Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MIRROR] Fixes infinite loop in bitrunning #242

Merged
merged 1 commit into from
Oct 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions code/__DEFINES/dcs/signals/signals_bitrunning.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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"
1 change: 1 addition & 0 deletions code/modules/bitrunning/components/avatar_connection.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
52 changes: 21 additions & 31 deletions code/modules/bitrunning/components/netpod_healing.dm
Original file line number Diff line number Diff line change
@@ -1,36 +1,18 @@
#define BASE_HEAL 4

/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

/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/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)

Expand All @@ -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
Expand All @@ -65,3 +53,5 @@
name = "Embryonic Stasis"
icon_state = "netpod_stasis"
desc = "You feel like you're in a dream."

#undef BASE_HEAL
142 changes: 63 additions & 79 deletions code/modules/bitrunning/objects/netpod.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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 ..()

Expand All @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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()
Expand All @@ -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

Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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

Expand Down Expand Up @@ -372,27 +373,50 @@
/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))
return

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
Expand All @@ -408,66 +432,26 @@
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

if(isnull(occupant) || !connected)
connected = FALSE
open_machine()
return

QDEL_NULL(current_avatar)
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)
SIGNAL_HANDLER

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)
Expand Down
3 changes: 2 additions & 1 deletion code/modules/bitrunning/server/obj_generation.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading