diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index 491aa22457e..65bc9c5d9c2 100644 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -10,7 +10,7 @@ active_power_usage = 40000 //40 kW var/efficiency = 40000 //will provide the modified power rate when upgraded var/obj/item/charging = null - var/list/allowed_devices = list(/obj/item/weapon/gun/energy, /obj/item/weapon/melee/baton, /obj/item/modular_computer, /obj/item/weapon/computer_hardware/battery_module, /obj/item/weapon/cell, /obj/item/device/suit_cooling_unit/emergency, /obj/item/device/flashlight, /obj/item/device/electronic_assembly, /obj/item/weapon/weldingtool/electric, /obj/item/ammo_magazine/smart, /obj/item/device/flash, /obj/item/device/defib_kit, /obj/item/ammo_casing/microbattery) //VOREStation Add - NSFW Batteries + var/list/allowed_devices = list(/obj/item/weapon/gun/energy, /obj/item/weapon/melee/baton, /obj/item/modular_computer, /obj/item/weapon/computer_hardware/battery_module, /obj/item/weapon/cell, /obj/item/device/suit_cooling_unit/emergency, /obj/item/device/flashlight, /obj/item/device/electronic_assembly, /obj/item/weapon/weldingtool/electric, /obj/item/ammo_magazine/smart, /obj/item/device/flash, /obj/item/device/defib_kit, /obj/item/ammo_casing/microbattery, /obj/item/device/paicard) //VOREStation Add - NSFW Batteries var/icon_state_charged = "recharger2" var/icon_state_charging = "recharger1" var/icon_state_idle = "recharger0" //also when unpowered @@ -68,9 +68,14 @@ if(EW.use_external_power) to_chat(user, "\The [EW] has no recharge port.") return - if(!G.get_cell() && !istype(G, /obj/item/ammo_casing/microbattery)) //VOREStation Edit: NSFW charging + if(!G.get_cell() && !istype(G, /obj/item/ammo_casing/microbattery) && !istype(G, /obj/item/device/paicard)) //VOREStation Edit: NSFW charging to_chat(user, "\The [G] does not have a battery installed.") return + if(istype(G, /obj/item/device/paicard)) + var/obj/item/device/paicard/ourcard = G + if(ourcard.panel_open) + to_chat(user, "\The [ourcard] won't fit in the recharger with its panel open.") + return user.drop_item() G.loc = src @@ -122,6 +127,24 @@ if(!charging) update_use_power(USE_POWER_IDLE) icon_state = icon_state_idle + //VOREStation Edit Start - pAI revival! + else if(istype(charging, /obj/item/device/paicard)) + var/obj/item/device/paicard/pcard = charging + if(pcard.is_damage_critical()) + pcard.forceMove(get_turf(src)) + charging = null + pcard.damage_random_component() + update_icon() + else if(pcard.pai.bruteloss) + pcard.pai.adjustBruteLoss(-1) + else if(pcard.pai.fireloss) + pcard.pai.adjustFireLoss(-1) + else + pcard.forceMove(get_turf(src)) + pcard.pai.full_restore() + charging = null + update_icon() + //VOREStation Edit End else var/obj/item/weapon/cell/C = charging.get_cell() if(istype(C)) diff --git a/code/game/objects/items/devices/paicard.dm b/code/game/objects/items/devices/paicard.dm index ae8b3903819..4fae67a9f9e 100644 --- a/code/game/objects/items/devices/paicard.dm +++ b/code/game/objects/items/devices/paicard.dm @@ -58,11 +58,21 @@ GLOBAL_LIST_BOILERPLATE(all_pai_cards, /obj/item/device/paicard) /obj/item/device/paicard/attack_ghost(mob/user as mob) if(pai != null) //Have a person in them already? return ..() - + var/time_till_respawn = user.time_till_respawn() + if(time_till_respawn == -1) // Special case, never allowed to respawn + to_chat(usr, "Respawning is not allowed!") + else if(time_till_respawn) // Nonzero time to respawn + to_chat(usr, "You can't do that yet! You died too recently. You need to wait another [round(time_till_respawn/10/60, 0.1)] minutes.") + return if(jobban_isbanned(usr, "pAI")) to_chat(usr,"You cannot join a pAI card when you are banned from playing as a pAI.") return + for(var/ourkey in paikeys) + if(ourkey == user.ckey) + to_chat(usr, "You can't just rejoin any old pAI card!!! Your card still exists.") + return + var/choice = tgui_alert(user, "You sure you want to inhabit this PAI, or submit yourself to being recruited?", "Confirmation", list("Inhabit", "Recruit", "Cancel")) if(choice == "Cancel") return ..() @@ -81,12 +91,14 @@ GLOBAL_LIST_BOILERPLATE(all_pai_cards, /obj/item/device/paicard) var/obj/item/device/paicard/typeb/card = new(location) var/mob/living/silicon/pai/new_pai = new(card) new_pai.key = user.key + paikeys |= new_pai.ckey card.setPersonality(new_pai) new_pai.SetName(actual_pai_name) else var/obj/item/device/paicard/card = new(location) var/mob/living/silicon/pai/new_pai = new(card) new_pai.key = user.key + paikeys |= new_pai.ckey card.setPersonality(new_pai) new_pai.SetName(actual_pai_name) @@ -95,6 +107,7 @@ GLOBAL_LIST_BOILERPLATE(all_pai_cards, /obj/item/device/paicard) var/obj/item/device/paicard/typeb/card = new(location) var/mob/living/silicon/pai/new_pai = new(card) new_pai.key = user.key + paikeys |= new_pai.ckey card.setPersonality(new_pai) if(!new_pai.savefile_load(new_pai)) var/pai_name = tgui_input_text(new_pai, "Choose your character's name", "Character Name") @@ -105,6 +118,7 @@ GLOBAL_LIST_BOILERPLATE(all_pai_cards, /obj/item/device/paicard) var/obj/item/device/paicard/card = new(location) var/mob/living/silicon/pai/new_pai = new(card) new_pai.key = user.key + paikeys |= new_pai.ckey card.setPersonality(new_pai) if(!new_pai.savefile_load(new_pai)) var/pai_name = tgui_input_text(new_pai, "Choose your character's name", "Character Name") @@ -513,6 +527,5 @@ GLOBAL_LIST_BOILERPLATE(all_pai_cards, /obj/item/device/paicard) return pick(/obj/item/device/paicard ,/obj/item/device/paicard/typeb) /obj/item/device/paicard/digest_act(var/atom/movable/item_storage = null) - if(!pai.digestable) - return - . = ..() + if(pai.digestable) + return ..() diff --git a/code/game/objects/items/devices/paicard_vr.dm b/code/game/objects/items/devices/paicard_vr.dm index a54a9fdf405..723218348ba 100644 --- a/code/game/objects/items/devices/paicard_vr.dm +++ b/code/game/objects/items/devices/paicard_vr.dm @@ -1,163 +1,346 @@ +#define PP_FUNCTIONAL 0 +#define PP_BROKEN 1 +#define PP_MISSING 2 + +var/global/list/paikeys = list() + /obj/item/device/paicard var/panel_open = FALSE - var/cell = TRUE //critical- power - var/processor = TRUE //critical- the thinky part - var/board = TRUE //critical- makes everything work - var/capacitor = TRUE //critical- power processing - var/projector = TRUE //non-critical- affects unfolding - var/emitter = TRUE //non-critical- affects unfolding - var/speech_synthesizer = TRUE //non-critical- affects speech - var/list/parts = list( - "cell", - "processor", - "board", - "capacitor", - "projector", - "emitter", - "speech synthesizer") + var/cell = PP_FUNCTIONAL //critical- power + var/processor = PP_FUNCTIONAL //critical- the thinky part + var/board = PP_FUNCTIONAL //critical- makes everything work + var/capacitor = PP_FUNCTIONAL //critical- power processing + var/projector = PP_FUNCTIONAL //non-critical- affects unfolding + var/emitter = PP_FUNCTIONAL //non-critical- affects unfolding + var/speech_synthesizer = PP_FUNCTIONAL //non-critical- affects speech /obj/item/device/paicard/attackby(var/obj/item/I as obj, mob/user as mob) if(istype(I,/obj/item/weapon/tool/screwdriver)) if(panel_open) panel_open = FALSE - user.visible_message("\The [user] secured \the [src]'s maintenance panel.") + user.visible_message("\The [user] secured \the [src]'s maintenance panel.") else panel_open = TRUE - user.visible_message("\The [user] opened \the [src]'s maintenance panel.") + user.visible_message("\The [user] opened \the [src]'s maintenance panel.") if(istype(I,/obj/item/device/robotanalyzer)) if(!panel_open) to_chat(user, "The panel isn't open. You will need to unscrew it to open it.") else - if(cell) + if(cell == PP_FUNCTIONAL) to_chat(user,"Power cell: functional") - else + else if(cell == PP_BROKEN) to_chat(user,"Power cell: damaged - CRITICAL") - if(processor) + else + to_chat(user,"Power cell: missing - CRITICAL") + + if(processor == PP_FUNCTIONAL) to_chat(user,"Processor: functional") - else + else if(processor == PP_BROKEN) to_chat(user,"Processor: damaged - CRITICAL") - if(board) + else + to_chat(user,"Processor: missing - CRITICAL") + + if(board == PP_FUNCTIONAL) to_chat(user,"Board: functional") - else + else if(board == PP_BROKEN) to_chat(user,"Board: damaged - CRITICAL") - if(capacitor) + else + to_chat(user,"Board: missing - CRITICAL") + + if(capacitor == PP_FUNCTIONAL) to_chat(user,"Capacitors: functional") - else + else if(capacitor == PP_BROKEN) to_chat(user,"Capacitors: damaged - CRITICAL") - if(projector) + else + to_chat(user,"Capacitors: missing - CRITICAL") + + if(projector == PP_FUNCTIONAL) to_chat(user,"Projectors: functional") - else + else if(projector == PP_BROKEN) to_chat(user,"Projectors: damaged") - if(emitter) + else + to_chat(user,"Projectors: missing") + + if(emitter == PP_FUNCTIONAL) to_chat(user,"Emitters: functional") - else + else if(emitter == PP_BROKEN) to_chat(user,"Emitters: damaged") - if(speech_synthesizer) - to_chat(user,"Speech Synthesizer: functional") else + to_chat(user,"Emitters: missing") + + if(speech_synthesizer == PP_FUNCTIONAL) + to_chat(user,"Speech Synthesizer: functional") + else if(speech_synthesizer == PP_BROKEN) to_chat(user,"Speech Synthesizer: damaged") + else + to_chat(user,"Speech Synthesizer: missing") + if(istype(I,/obj/item/device/multitool)) if(!panel_open) to_chat(user, "You can't do that in this state.") else + var/list/parts = list() + if(cell != PP_MISSING) + parts |= "cell" + if(processor != PP_MISSING) + parts |= "processor" + if(board != PP_MISSING) + parts |= "board" + if(capacitor != PP_MISSING) + parts |= "capacitor" + if(projector != PP_MISSING) + parts |= "projector" + if(emitter != PP_MISSING) + parts |= "emitter" + if(speech_synthesizer != PP_MISSING) + parts |= "speech synthesizer" + var/choice = tgui_input_list(user, "Which part would you like to check?", "Check part", parts) switch(choice) if("cell") - if(cell) + if(cell == PP_FUNCTIONAL) to_chat(user,"Power cell: functional") - else + else if(speech_synthesizer == PP_BROKEN) to_chat(user,"Power cell: damaged") + else + to_chat(user,"Power cell: missing") + if("processor") - if(processor) + if(processor == PP_FUNCTIONAL) to_chat(user,"Processor: functional") - else + else if(speech_synthesizer == PP_BROKEN) to_chat(user,"Processor: damaged") + else + to_chat(user,"Processor: missing") + if("board") - if(board) + if(board == PP_FUNCTIONAL) to_chat(user,"Board: functional") - else + else if(speech_synthesizer == PP_BROKEN) to_chat(user,"Board: damaged") + else + to_chat(user,"Board: missing") + if("capacitor") - if(capacitor) + if(capacitor == PP_FUNCTIONAL) to_chat(user,"Capacitors: functional") - else + else if(speech_synthesizer == PP_BROKEN) to_chat(user,"Capacitors: damaged") + else + to_chat(user,"Capacitors: missing") + if("projector") - if(projector) + if(projector == PP_FUNCTIONAL) to_chat(user,"Projectors: functional") - else + else if(speech_synthesizer == PP_BROKEN) to_chat(user,"Projectors: damaged") + else + to_chat(user,"Projectors: missing") + if("emitter") - if(emitter) + if(emitter == PP_FUNCTIONAL) to_chat(user,"Emitters: functional") - else + else if(speech_synthesizer == PP_BROKEN) to_chat(user,"Emitters: damaged") - if("speech synthesizer") - if(speech_synthesizer) - to_chat(user,"Speech Synthesizer: functional") else + to_chat(user,"Emitters: missing") + + if("speech synthesizer") + if(speech_synthesizer == PP_FUNCTIONAL) + to_chat(user,"Speech Synthesizer: functional") + else if(speech_synthesizer == PP_BROKEN) to_chat(user,"Speech Synthesizer: damaged") + else + to_chat(user,"Speech Synthesizer: missing") + + if(istype(I,/obj/item/paiparts/cell) && cell == PP_MISSING) + user.visible_message("\The [user] installs \the [I] into \the [src].","You install \the [I] into \the [src].") + cell = PP_FUNCTIONAL + user.drop_from_inventory(I) + qdel(I) + if(istype(I,/obj/item/paiparts/processor) && processor == PP_MISSING) + user.visible_message("\The [user] installs \the [I] into \the [src].","You install \the [I] into \the [src].") + processor = PP_FUNCTIONAL + user.drop_from_inventory(I) + qdel(I) + if(istype(I,/obj/item/paiparts/board) && board == PP_MISSING) + user.visible_message("\The [user] installs \the [I] into \the [src].","You install \the [I] into \the [src].") + board = PP_FUNCTIONAL + user.drop_from_inventory(I) + qdel(I) + if(istype(I,/obj/item/paiparts/capacitor) && capacitor == PP_MISSING) + user.visible_message("\The [user] installs \the [I] into \the [src].","You install \the [I] into \the [src].") + capacitor = PP_FUNCTIONAL + user.drop_from_inventory(I) + qdel(I) + if(istype(I,/obj/item/paiparts/projector) && projector == PP_MISSING) + user.visible_message("\The [user] installs \the [I] into \the [src].","You install \the [I] into \the [src].") + projector = PP_FUNCTIONAL + user.drop_from_inventory(I) + qdel(I) + if(istype(I,/obj/item/paiparts/emitter) && emitter == PP_MISSING) + user.visible_message("\The [user] installs \the [I] into \the [src].","You install \the [I] into \the [src].") + emitter = PP_FUNCTIONAL + user.drop_from_inventory(I) + qdel(I) + if(istype(I,/obj/item/paiparts/speech_synthesizer) && speech_synthesizer == PP_MISSING) + user.visible_message("\The [user] installs \the [I] into \the [src].","You install \the [I] into \the [src].") + speech_synthesizer = PP_FUNCTIONAL + user.drop_from_inventory(I) + qdel(I) /obj/item/device/paicard/attack_self(mob/user) if(!panel_open) access_screen(user) return + var/list/parts = list() + if(cell != PP_MISSING) + parts |= "cell" + if(processor != PP_MISSING) + parts |= "processor" + if(board != PP_MISSING) + parts |= "board" + if(capacitor != PP_MISSING) + parts |= "capacitor" + if(projector != PP_MISSING) + parts |= "projector" + if(emitter != PP_MISSING) + parts |= "emitter" + if(speech_synthesizer != PP_MISSING) + parts |= "speech synthesizer" + var/choice = tgui_input_list(user, "Which part would you like to remove?", "Remove part", parts) switch(choice) if("cell") - cell = FALSE - if(pai.stat != DEAD) - pai.death() + if(cell == PP_FUNCTIONAL) + new /obj/item/paiparts/capacitor(get_turf(user)) + else + new /obj/item/paiparts(get_turf(user)) + user.visible_message("\The [user] removes \the [choice] from \the [src].","You remove \the [choice] from \the [src].") + cell = PP_MISSING if("processor") - processor = FALSE - if(pai.stat != DEAD) - pai.death() + if(processor == PP_FUNCTIONAL) + new /obj/item/paiparts/capacitor(get_turf(user)) + else + new /obj/item/paiparts(get_turf(user)) + user.visible_message("\The [user] removes \the [choice] from \the [src].","You remove \the [choice] from \the [src].") + processor = PP_MISSING if("board") - board = FALSE - if(pai.stat != DEAD) - pai.death() + board = PP_MISSING + if(board == PP_FUNCTIONAL) + new /obj/item/paiparts/capacitor(get_turf(user)) + else + new /obj/item/paiparts(get_turf(user)) + user.visible_message("\The [user] removes \the [choice] from \the [src].","You remove \the [choice] from \the [src].") + if("capacitor") - capacitor = FALSE - if(pai.stat != DEAD) - pai.death() + if(capacitor == PP_FUNCTIONAL) + new /obj/item/paiparts/capacitor(get_turf(user)) + else + new /obj/item/paiparts(get_turf(user)) + user.visible_message("\The [user] removes \the [choice] from \the [src].","You remove \the [choice] from \the [src].") + capacitor = PP_MISSING if("projector") - projector = FALSE + if(projector == PP_FUNCTIONAL) + new /obj/item/paiparts/capacitor(get_turf(user)) + else + new /obj/item/paiparts(get_turf(user)) + user.visible_message("\The [user] removes \the [choice] from \the [src].","You remove \the [choice] from \the [src].") + projector = PP_MISSING if("emitter") - emitter = FALSE + if(emitter == PP_FUNCTIONAL) + new /obj/item/paiparts/capacitor(get_turf(user)) + else + new /obj/item/paiparts(get_turf(user)) + user.visible_message("\The [user] removes \the [choice] from \the [src].","You remove \the [choice] from \the [src].") + emitter = PP_MISSING if("speech synthesizer") - speech_synthesizer = FALSE - parts -= choice + if(speech_synthesizer == PP_FUNCTIONAL) + new /obj/item/paiparts/capacitor(get_turf(user)) + else + new /obj/item/paiparts(get_turf(user)) + user.visible_message("\The [user] removes \the [choice] from \the [src].","You remove \the [choice] from \the [src].") + speech_synthesizer = PP_MISSING /obj/item/device/paicard/proc/death_damage() - var/number = pick(1,4) + var/number = rand(1,4) while(number) - switch(pick(1,4)) + number -- + switch(rand(1,4)) if(1) - cell = FALSE + cell = PP_BROKEN if(2) - processor = FALSE + processor = PP_BROKEN if(3) - board = FALSE + board = PP_BROKEN if(4) - capacitor = FALSE + capacitor = PP_BROKEN + /obj/item/device/paicard/proc/damage_random_component(nonfatal = FALSE) + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(2, 1, src) + s.start() if(prob(80) || nonfatal) //Way more likely to be non-fatal part damage - switch(pick(1,3)) + switch(rand(1,3)) if(1) - projector = FALSE + projector = PP_BROKEN if(2) - emitter = FALSE + emitter = PP_BROKEN if(3) - speech_synthesizer = FALSE + speech_synthesizer = PP_BROKEN else - switch(pick(1,4)) + switch(rand(1,4)) if(1) - cell = FALSE + cell = PP_BROKEN if(2) - processor = FALSE + processor = PP_BROKEN if(3) - board = FALSE + board = PP_BROKEN if(4) - capacitor = FALSE + capacitor = PP_BROKEN + +/obj/item/device/paicard/proc/is_damage_critical() + if(cell != PP_FUNCTIONAL || processor != PP_FUNCTIONAL || board != PP_FUNCTIONAL || capacitor != PP_FUNCTIONAL) + return TRUE + return FALSE + +/obj/item/paiparts + name = "broken pAI component" + desc = "It's broken scrap from a pAI card!" + icon = 'icons/obj/paicard.dmi' + icon_state = "broken" +/obj/item/paiparts/Initialize() + . = ..() + pixel_x = rand(-10,10) + pixel_y = rand(-10,10) + +/obj/item/paiparts/cell + name = "pAI power cell" + desc = "It's very small and efficient! It powers the pAI!" + icon_state = "cell" +/obj/item/paiparts/processor + name = "pAI processor" + desc = "It's the brain of your computer friend!" + icon_state = "processor" +/obj/item/paiparts/board + name = "pAI board" + desc = "It's the thing all the other parts get attatched to!" + icon_state = "board" +/obj/item/paiparts/capacitor + name = "pAI capacitor" + desc = "It helps regulate power flow!" + icon_state = "capacitor" +/obj/item/paiparts/projector + name = "pAI projector" + desc = "It projects the pAI's form!" + icon_state = "projector" +/obj/item/paiparts/emitter + name = "pAI emitter" + desc = "It emits the fields to help the pAI get around!" + icon_state = "emitter" +/obj/item/paiparts/speech_synthesizer + name = "pAI speech synthesizer" + desc = "It's a little voice box!" + icon_state = "speech_synthesizer" diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 106bd0aef25..043e339c47c 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -983,6 +983,13 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp set name = "Blank pAI alert" set desc = "Flash an indicator light on available blank pAI devices for a smidgen of hope." + var/time_till_respawn = time_till_respawn() + if(time_till_respawn == -1) // Special case, never allowed to respawn + to_chat(usr, "Respawning is not allowed!") + else if(time_till_respawn) // Nonzero time to respawn + to_chat(usr, "You can't do that yet! You died too recently. You need to wait another [round(time_till_respawn/10/60, 0.1)] minutes.") + return + if(jobban_isbanned(usr, "pAI")) to_chat(usr,"You cannot alert pAI cards when you are banned from playing as a pAI.") return diff --git a/code/modules/mob/living/silicon/pai/death.dm b/code/modules/mob/living/silicon/pai/death.dm index 5a8efb1e193..6290b72f51c 100644 --- a/code/modules/mob/living/silicon/pai/death.dm +++ b/code/modules/mob/living/silicon/pai/death.dm @@ -1,10 +1,12 @@ //VOREStation Edit - Let's make it so that pAIs don't just always cease to be when they die! It would be cool if we could fix them. /mob/living/silicon/pai/death(gibbed,deathmessage="fizzles out and clatters to the floor...") +// set_respawn_timer() release_vore_contents() close_up(TRUE) if(card) card.cut_overlays() card.setEmotion(16) + card.damage_random_component() if(gibbed) qdel(card) diff --git a/code/modules/mob/living/silicon/pai/life.dm b/code/modules/mob/living/silicon/pai/life.dm index 2ad35532b04..6e7e8a42a10 100644 --- a/code/modules/mob/living/silicon/pai/life.dm +++ b/code/modules/mob/living/silicon/pai/life.dm @@ -13,14 +13,14 @@ if (src.stat == DEAD) return - if(!card.cell || !card.processor || !card.board || !card.capacitor) + if(card.cell != PP_FUNCTIONAL|| card.processor != PP_FUNCTIONAL || card.board != PP_FUNCTIONAL || card.capacitor != PP_FUNCTIONAL) death() - if(!card.projector && !card.emitter) + if(card.projector != PP_FUNCTIONAL && card.emitter != PP_FUNCTIONAL) if(loc != card) close_up() to_chat(src, "ERROR: System malfunction. Service required!") - else if(!card.projector || !card.emitter) + else if(card.projector != PP_FUNCTIONAL|| card.emitter != PP_FUNCTIONAL) if(prob(5)) close_up() to_chat(src, "ERROR: System malfunction. Service recommended!") @@ -36,6 +36,7 @@ handle_statuses() if(health <= 0) + card.death_damage() death(null,"fizzles out and clatters to the floor...") else if(health < maxHealth && istype(src.loc , /obj/item/device/paicard)) adjustBruteLoss(-0.5) diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 7d6f73eed7b..417a8d08a6e 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -251,6 +251,9 @@ if(src.loc != card) return + if(card.projector != PP_FUNCTIONAL && card.emitter != PP_FUNCTIONAL) + to_chat(src, "ERROR: System malfunction. Service required!") + if(world.time <= last_special) to_chat(src, "You can't unfold yet.") return @@ -531,6 +534,7 @@ return close_up() + paikeys -= ckey visible_message("[src] fades away from the screen, the pAI device goes silent.") card.removePersonality() clear_client() diff --git a/code/modules/mob/living/silicon/pai/pai_vr.dm b/code/modules/mob/living/silicon/pai/pai_vr.dm index a13f21eca6d..444dacd2923 100644 --- a/code/modules/mob/living/silicon/pai/pai_vr.dm +++ b/code/modules/mob/living/silicon/pai/pai_vr.dm @@ -76,14 +76,13 @@ /mob/living/silicon/pai/proc/full_restore() adjustBruteLoss(- bruteloss) adjustFireLoss(- fireloss) - spawn(10) - card.cut_overlays() + spawn(100) card.setEmotion(16) - update_icon() - spawn(50) + spawn(500) stat = CONSCIOUS canmove = TRUE card.setEmotion(15) + card.visible_message("\The [card] chimes.", runemessage = "chime") /mob/living/silicon/pai/proc/pai_nom(var/mob/living/T in oview(1)) set name = "pAI Nom" diff --git a/code/modules/mob/living/silicon/pai/recruit.dm b/code/modules/mob/living/silicon/pai/recruit.dm index a6365e45858..b7485fa7150 100644 --- a/code/modules/mob/living/silicon/pai/recruit.dm +++ b/code/modules/mob/living/silicon/pai/recruit.dm @@ -37,6 +37,7 @@ var/datum/paiController/paiController // Global handler for pAI candidates if(istype(card,/obj/item/device/paicard) && istype(candidate,/datum/paiCandidate)) var/mob/living/silicon/pai/pai = new(card) pai.key = candidate.key + paikeys |= pai.ckey card.setPersonality(pai) if(!candidate.name) pai.SetName(pick(ninja_names)) @@ -379,6 +380,16 @@ var/datum/paiController/paiController // Global handler for pAI candidates if(!C) return asked.Add(C.key) asked[C.key] = world.time + + var/mob/ourmob = C.mob + if(ourmob) + var/time_till_respawn = ourmob.time_till_respawn() + if(time_till_respawn == -1 || time_till_respawn) + return + for(var/ourkey in paikeys) + if(ourkey == ourmob.ckey) + return + var/response = tgui_alert(C, "[inquirer] is requesting a pAI personality. Would you like to play as a personal AI?", "pAI Request", list("Yes", "No", "Never for this round")) if(!C) return //handle logouts that happen whilst the alert is waiting for a response. if(response == "Yes") diff --git a/code/modules/mob/living/silicon/pai/say.dm b/code/modules/mob/living/silicon/pai/say.dm index 9223e16c5a6..b06a221859f 100644 --- a/code/modules/mob/living/silicon/pai/say.dm +++ b/code/modules/mob/living/silicon/pai/say.dm @@ -1,7 +1,7 @@ /mob/living/silicon/pai/say(var/message, var/datum/language/speaking = null, var/whispering = 0) if(silence_time) to_chat(src, "Communication circuits remain uninitialized.") - else if(!card.speech_synthesizer) + else if(card.speech_synthesizer != PP_FUNCTIONAL) to_chat(src, "Communication circuits damaged. Service required.") else ..() diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index f3683f6ca4b..dca1d5954fd 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -182,7 +182,7 @@ if(!ticker || ticker.current_state != GAME_STATE_PLAYING) to_chat(usr, "The round is either not ready, or has already finished...") return - + var/time_till_respawn = time_till_respawn() if(time_till_respawn == -1) // Special case, never allowed to respawn to_chat(usr, "Respawning is not allowed!") @@ -224,7 +224,7 @@ return 0 var/datum/species/S = GLOB.all_species[client.prefs.species] - + if(!(S.spawn_flags & SPECIES_CAN_JOIN)) tgui_alert_async(src,"Your current species, [client.prefs.species], is not available for play on the station.") return 0 @@ -367,7 +367,7 @@ popup.set_content(dat) popup.open() -/mob/new_player/proc/time_till_respawn() +/mob/proc/time_till_respawn() if(!ckey) return -1 // What? diff --git a/icons/obj/paicard.dmi b/icons/obj/paicard.dmi index 97fe95121ae..4403d47a3d5 100644 Binary files a/icons/obj/paicard.dmi and b/icons/obj/paicard.dmi differ