diff --git a/code/__DEFINES/dcs/signals/signals_bitrunning.dm b/code/__DEFINES/dcs/signals/signals_bitrunning.dm index 957e61ae303..e2731a05b34 100644 --- a/code/__DEFINES/dcs/signals/signals_bitrunning.dm +++ b/code/__DEFINES/dcs/signals/signals_bitrunning.dm @@ -32,3 +32,6 @@ /// from /obj/machinery/quantum_server/scrub_vdom() #define COMSIG_BITRUNNER_DOMAIN_SCRUBBED "bitrunner_domain_scrubbed" + +/// from /obj/machinery/netpod/open_machine() +#define COMSIG_BITRUNNER_NETPOD_OPENED "bitrunner_netpod_opened" diff --git a/code/modules/bitrunning/components/avatar_connection.dm b/code/modules/bitrunning/components/avatar_connection.dm index 24f42d8f3e5..8aa37645b4f 100644 --- a/code/modules/bitrunning/components/avatar_connection.dm +++ b/code/modules/bitrunning/components/avatar_connection.dm @@ -35,6 +35,7 @@ avatar.key = old_body.key ADD_TRAIT(old_body, TRAIT_MIND_TEMPORARILY_GONE, REF(src)) + RegisterSignals(old_body, list(COMSIG_LIVING_DEATH, COMSIG_MOVABLE_MOVED, COMSIG_LIVING_STATUS_UNCONSCIOUS), PROC_REF(on_sever_connection)) RegisterSignal(pod, COMSIG_BITRUNNER_CROWBAR_ALERT, PROC_REF(on_netpod_crowbar)) RegisterSignal(pod, COMSIG_BITRUNNER_NETPOD_INTEGRITY, PROC_REF(on_netpod_damaged)) RegisterSignal(pod, COMSIG_BITRUNNER_SEVER_AVATAR, PROC_REF(on_sever_connection)) diff --git a/code/modules/bitrunning/components/netpod_healing.dm b/code/modules/bitrunning/components/netpod_healing.dm index d5fae561236..98fdb5ba021 100644 --- a/code/modules/bitrunning/components/netpod_healing.dm +++ b/code/modules/bitrunning/components/netpod_healing.dm @@ -1,36 +1,18 @@ -/datum/component/netpod_healing - /// Brute damage to heal over a second - var/brute_heal = 0 - /// Burn damage to heal over a second - var/burn_heal = 0 - /// Toxin damage to heal over a second - var/toxin_heal = 0 - /// Amount of cloning damage to heal over a second - var/clone_heal = 0 - /// Amount of blood to heal over a second - var/blood_heal = 0 +#define BASE_HEAL 4 -/datum/component/netpod_healing/Initialize( - brute_heal = 0, - burn_heal = 0, - toxin_heal = 0, - clone_heal = 0, - blood_heal = 0, -) - var/mob/living/carbon/player = parent - if (!iscarbon(player)) +/datum/component/netpod_healing + +/datum/component/netpod_healing/Initialize(obj/machinery/netpod/pod) + if (!iscarbon(parent)) return COMPONENT_INCOMPATIBLE + RegisterSignal(pod, COMSIG_BITRUNNER_NETPOD_OPENED, PROC_REF(on_opened)) + + var/mob/living/carbon/player = parent player.apply_status_effect(/datum/status_effect/embryonic, STASIS_NETPOD_EFFECT) START_PROCESSING(SSmachines, src) - src.brute_heal = brute_heal - src.burn_heal = burn_heal - src.toxin_heal = toxin_heal - src.clone_heal = clone_heal - src.blood_heal = blood_heal - /datum/component/netpod_healing/Destroy(force, silent) STOP_PROCESSING(SSmachines, src) @@ -46,17 +28,23 @@ return var/need_mob_update = FALSE - need_mob_update += owner.adjustBruteLoss(-brute_heal * seconds_per_tick, updating_health = FALSE) - need_mob_update += owner.adjustFireLoss(-burn_heal * seconds_per_tick, updating_health = FALSE) - need_mob_update += owner.adjustToxLoss(-toxin_heal * seconds_per_tick, updating_health = FALSE, forced = TRUE) - need_mob_update += owner.adjustCloneLoss(-clone_heal * seconds_per_tick, updating_health = FALSE) + need_mob_update += owner.adjustBruteLoss(-BASE_HEAL * seconds_per_tick, updating_health = FALSE) + need_mob_update += owner.adjustFireLoss(-BASE_HEAL * seconds_per_tick, updating_health = FALSE) + need_mob_update += owner.adjustToxLoss(-BASE_HEAL * seconds_per_tick, updating_health = FALSE, forced = TRUE) + need_mob_update += owner.adjustCloneLoss(-BASE_HEAL * seconds_per_tick, updating_health = FALSE) if(owner.blood_volume < BLOOD_VOLUME_NORMAL) - owner.blood_volume += blood_heal * seconds_per_tick + owner.blood_volume += BASE_HEAL * seconds_per_tick if(need_mob_update) owner.updatehealth() +/// Deletes itself when the machine was opened +/datum/component/netpod_healing/proc/on_opened() + SIGNAL_HANDLER + + qdel(src) + /datum/status_effect/embryonic id = "embryonic" alert_type = /atom/movable/screen/alert/status_effect/embryonic @@ -72,3 +60,5 @@ name = "Embryonic Stasis" icon_state = "netpod_stasis" desc = "You feel like you're in a dream." + +#undef BASE_HEAL diff --git a/code/modules/bitrunning/objects/netpod.dm b/code/modules/bitrunning/objects/netpod.dm index a1630c27f16..cda63af2d91 100644 --- a/code/modules/bitrunning/objects/netpod.dm +++ b/code/modules/bitrunning/objects/netpod.dm @@ -35,15 +35,10 @@ disconnect_damage = BASE_DISCONNECT_DAMAGE find_server() - RegisterSignals(src, list( - COMSIG_QDELETING, - COMSIG_MACHINERY_BROKEN, - COMSIG_MACHINERY_POWER_LOST, - ), - PROC_REF(on_broken), - ) RegisterSignal(src, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) - RegisterSignal(src, COMSIG_ATOM_TAKE_DAMAGE, PROC_REF(on_take_damage)) + RegisterSignal(src, COMSIG_ATOM_TAKE_DAMAGE, PROC_REF(on_damage_taken)) + RegisterSignal(src, COMSIG_MACHINERY_POWER_LOST, PROC_REF(on_power_loss)) + RegisterSignals(src, list(COMSIG_QDELETING, COMSIG_MACHINERY_BROKEN),PROC_REF(on_broken)) register_context() update_appearance() @@ -89,7 +84,7 @@ if(!iscarbon(player)) return - if((HAS_TRAIT(player, TRAIT_UI_BLOCKED) && !player.resting) || !Adjacent(player) || !player.Adjacent(target) || !ISADVANCEDTOOLUSER(player) || !is_operational) + if((HAS_TRAIT(player, TRAIT_UI_BLOCKED) && !player.resting) || !Adjacent(player) || !ISADVANCEDTOOLUSER(player) || !is_operational) return close_machine(target) @@ -142,9 +137,10 @@ open_machine() /obj/machinery/netpod/open_machine(drop = TRUE, density_to_set = FALSE) - unprotect_and_signal() playsound(src, 'sound/machines/tramopen.ogg', 60, TRUE, frequency = 65000) flick("[base_icon_state]_opening", src) + SEND_SIGNAL(src, COMSIG_BITRUNNER_NETPOD_OPENED) + update_use_power(IDLE_POWER_USE) return ..() @@ -156,10 +152,6 @@ flick("[base_icon_state]_closing", src) ..() - if(!iscarbon(occupant)) - open_machine() - return - enter_matrix() /obj/machinery/netpod/default_pry_open(obj/item/crowbar, mob/living/pryer) @@ -184,6 +176,7 @@ if(do_after(pryer, 15 SECONDS, src)) if(!state_open) + SEND_SIGNAL(src, COMSIG_BITRUNNER_SEVER_AVATAR) open_machine() return TRUE @@ -232,17 +225,22 @@ if(isnull(our_target) || !our_observer.orbit(our_target)) return ..() +/// Puts the occupant in netpod stasis, basically short-circuiting environmental conditions +/obj/machinery/netpod/proc/add_healing(mob/living/target) + if(target != occupant) + return + + target.AddComponent(/datum/component/netpod_healing, pod = src) + target.playsound_local(src, 'sound/effects/submerge.ogg', 20, vary = TRUE) + target.extinguish_mob() + update_use_power(ACTIVE_POWER_USE) + /// Disconnects the occupant after a certain time so they aren't just hibernating in netpod stasis. A balance change /obj/machinery/netpod/proc/auto_disconnect() if(isnull(occupant) || state_open || connected) return - if(!iscarbon(occupant)) - open_machine() - return - - var/mob/living/carbon/player = occupant - + var/mob/player = occupant player.playsound_local(src, 'sound/effects/splash.ogg', 60, TRUE) to_chat(player, span_notice("The machine disconnects itself and begins to drain.")) open_machine() @@ -252,7 +250,7 @@ connected = FALSE var/mob/living/mob_occupant = occupant - if(isnull(occupant) || !isliving(occupant) || mob_occupant.stat == DEAD) + if(isnull(occupant) || mob_occupant.stat == DEAD) open_machine() return @@ -261,6 +259,10 @@ mob_occupant.set_temp_blindness(1 SECONDS) mob_occupant.Paralyze(2 SECONDS) + if(!is_operational) + open_machine() + return + var/heal_time = 1 if(mob_occupant.health < mob_occupant.maxHealth) heal_time = (mob_occupant.stat + 2) * 5 @@ -299,9 +301,8 @@ return var/mob/living/carbon/current_avatar = avatar_ref?.resolve() - var/obj/structure/hololadder/wayout if(isnull(current_avatar) || current_avatar.stat != CONSCIOUS) // We need a viable avatar - wayout = server.generate_hololadder() + var/obj/structure/hololadder/wayout = server.generate_hololadder() if(isnull(wayout)) balloon_alert(neo, "out of bandwidth!") return @@ -310,7 +311,7 @@ server.stock_gear(current_avatar, neo, generated_domain) neo.set_static_vision(3 SECONDS) - protect_occupant(occupant) + add_healing(occupant) if(!do_after(neo, 2 SECONDS, src)) return @@ -372,20 +373,33 @@ /obj/machinery/netpod/proc/on_broken(datum/source) SIGNAL_HANDLER - if(!state_open) - open_machine() + if(isnull(occupant) || !connected) + return - if(occupant) - unprotect_and_signal() + SEND_SIGNAL(src, COMSIG_BITRUNNER_SEVER_AVATAR) + +/// Checks the integrity, alerts occupants +/obj/machinery/netpod/proc/on_damage_taken(datum/source, damage_amount) + SIGNAL_HANDLER + + if(isnull(occupant) || !connected) + return + + var/total = max_integrity - damage_amount + var/integrity = (atom_integrity / total) * 100 + if(integrity > 50) + return + + SEND_SIGNAL(src, COMSIG_BITRUNNER_NETPOD_INTEGRITY) /// Puts points on the current occupant's card account /obj/machinery/netpod/proc/on_domain_complete(datum/source, atom/movable/crate, reward_points) SIGNAL_HANDLER - if(isnull(occupant) || !connected || !iscarbon(occupant)) + if(isnull(occupant) || !connected) return - var/mob/living/carbon/player = occupant + var/mob/living/player = occupant var/datum/bank_account/account = player.get_bank_account() if(isnull(account)) @@ -393,6 +407,16 @@ account.bitrunning_points += reward_points * 100 +/// The domain has been fully purged, so we should double check our avatar is deleted +/obj/machinery/netpod/proc/on_domain_scrubbed(datum/source) + SIGNAL_HANDLER + + var/mob/avatar = avatar_ref?.resolve() + if(isnull(avatar)) + return + + QDEL_NULL(avatar) + /// User inspects the machine /obj/machinery/netpod/proc/on_examine(datum/source, mob/examiner, list/examine_text) SIGNAL_HANDLER @@ -408,15 +432,19 @@ examine_text += span_notice("It is currently occupied by [occupant].") examine_text += span_notice("It can be pried open with a crowbar, but its safety mechanisms will alert the occupant.") -/// The domain has been fully purged, so we should double check our avatar is deleted -/obj/machinery/netpod/proc/on_domain_scrubbed(datum/source) +/// Boots out anyone in the machine && opens it +/obj/machinery/netpod/proc/on_power_loss(datum/source) SIGNAL_HANDLER - var/mob/living/current_avatar = avatar_ref?.resolve() - if(isnull(current_avatar)) + if(state_open) return - QDEL_NULL(current_avatar) + if(isnull(occupant) || !connected) + connected = FALSE + open_machine() + return + + SEND_SIGNAL(src, COMSIG_BITRUNNER_SEVER_AVATAR) /// When the server is upgraded, drops brain damage a little /obj/machinery/netpod/proc/on_server_upgraded(datum/source, servo_rating) @@ -424,50 +452,6 @@ disconnect_damage = BASE_DISCONNECT_DAMAGE * (1 - servo_rating) -/// Checks the integrity, alerts occupants -/obj/machinery/netpod/proc/on_take_damage(datum/source, damage_amount) - SIGNAL_HANDLER - - if(isnull(occupant)) - return - - var/total = max_integrity - damage_amount - var/integrity = (atom_integrity / total) * 100 - if(integrity > 50) - return - - SEND_SIGNAL(src, COMSIG_BITRUNNER_NETPOD_INTEGRITY) - -/// Puts the occupant in netpod stasis, basically short-circuiting environmental conditions -/obj/machinery/netpod/proc/protect_occupant(mob/living/target) - if(target != occupant) - return - - target.AddComponent(/datum/component/netpod_healing, \ - brute_heal = 4, \ - burn_heal = 4, \ - toxin_heal = 4, \ - clone_heal = 4, \ - blood_heal = 4, \ - ) - - target.playsound_local(src, 'sound/effects/submerge.ogg', 20, TRUE) - target.extinguish_mob() - update_use_power(ACTIVE_POWER_USE) - -/// On unbuckle or break, make sure the occupant ref is null -/obj/machinery/netpod/proc/unprotect_and_signal() - unprotect_occupant(occupant) - SEND_SIGNAL(src, COMSIG_BITRUNNER_SEVER_AVATAR) - -/// Removes the occupant from netpod stasis -/obj/machinery/netpod/proc/unprotect_occupant(mob/living/target) - var/datum/component/netpod_healing/healing_eff = target?.GetComponent(/datum/component/netpod_healing) - if(healing_eff) - qdel(healing_eff) - - update_use_power(IDLE_POWER_USE) - /// Resolves a path to an outfit. /obj/machinery/netpod/proc/resolve_outfit(text) var/path = text2path(text) diff --git a/code/modules/bitrunning/server/obj_generation.dm b/code/modules/bitrunning/server/obj_generation.dm index f42d3ec3c3a..6fd22040242 100644 --- a/code/modules/bitrunning/server/obj_generation.dm +++ b/code/modules/bitrunning/server/obj_generation.dm @@ -85,7 +85,8 @@ if(domain_forbids_spells) import_ban += "imported_abilities" disk_ban += "powers" - if(import_ban) + + if(length(import_ban)) to_chat(neo, span_warning("This domain forbids the use of [english_list(import_ban)], your disk [english_list(disk_ban)] will not be granted!")) var/failed = FALSE