From 9a0e94aaa2d6846a82287aa64f23208be4aa7dbf Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Sat, 4 Mar 2023 14:00:17 +0100 Subject: [PATCH] [MIRROR] Fixes hijacked shuttles not counting as escaped, cleans up associated code [MDB IGNORE] (#19652) * Fixes hijacked shuttles not counting as escaped, cleans up associated code (#73623) ## About The Pull Request Fixes #72240 So, in the past, `onCentCom` ran a check at the end that said "if we're on centcom z, in centcom area, or in shuttle that is endgame launched: return TRUE" Meanwhile its brother `onSyndieBase` did not need to run the same checks, because it was also on the centcom z-level. This meant that for the purposes of `considered_escaped`, `onCentCom` pretty much entirely eclipsed `onSyndieBase`, only mattering for, well, Nuke Ops So the fix was simple - add the check for "in shuttle that is engame launched" to `onSyndieBase`. I took this opportunity to do a quick audit of associated "escaped" and "alive" code. Did you know that hardcore random only checked that you were on centcom to award survival points? Instead of any other checks for escaped like stat? Also the ancient "romerol zombies can't be used as an easy way to greentext escape" was broken, because it checked the wrong species ID? Bonus performance optimization: `in area` -> `in area.get_contained_turfs()` ## Why It's Good For The Game Hijack does not turn around to become an L ## Changelog :cl: Melbert fix: Hijacked shuttles now count as "escaping alive" once agian fix: Hardcore random survival now actually checks that you've escaped alive, and not just made it to centcom fix: Intelligent zombies can now escape. fix: Infectious zombies now don't count as escaped as intended. /:cl: * Fixes hijacked shuttles not counting as escaped, cleans up associated code --------- Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> --- code/__DEFINES/shuttles.dm | 3 ++ code/__HELPERS/game.dm | 26 +++++++++--- code/__HELPERS/roundend.dm | 2 +- code/game/atoms.dm | 67 +++++++++++++++++++++---------- code/game/gamemodes/objective.dm | 13 +++++- code/modules/shuttle/emergency.dm | 5 +-- code/modules/shuttle/shuttle.dm | 3 +- 7 files changed, 85 insertions(+), 34 deletions(-) diff --git a/code/__DEFINES/shuttles.dm b/code/__DEFINES/shuttles.dm index 1d721ef3f1d..5380268e979 100644 --- a/code/__DEFINES/shuttles.dm +++ b/code/__DEFINES/shuttles.dm @@ -29,8 +29,11 @@ //Launching Shuttles to CentCom #define NOLAUNCH -1 #define UNLAUNCHED 0 +/// This shuttle launched to head to end game (or has arrived there), it will not update further #define ENDGAME_LAUNCHED 1 #define EARLY_LAUNCHED 2 +/// "Endgame transit" denotes shuttles which "fly into the sunset" when the round ends, such as the whiteship. +/// These shuttles leave when the main emergency shuttle does but don't dock anywhere (to save space), so this counts as "escaped". #define ENDGAME_TRANSIT 3 //positive value = cannot puchase diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index b473cffe9b6..288ab0f62b4 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -68,16 +68,30 @@ return player_mob return null -///Returns true if the mob that a player is controlling is alive +/** + * Checks if the passed mind has a mob that is "alive" + * + * * player_mind - who to check for alive status + * * enforce_human - if TRUE, the checks fails if the mind's mob is a silicon, brain, or infectious zombie. + * + * Returns TRUE if they're alive, FALSE otherwise + */ /proc/considered_alive(datum/mind/player_mind, enforce_human = TRUE) if(player_mind?.current) if(enforce_human) - var/mob/living/carbon/human/player_mob - if(ishuman(player_mind.current)) - player_mob = player_mind.current - return player_mind.current.stat != DEAD && !issilicon(player_mind.current) && !isbrain(player_mind.current) && (!player_mob || player_mob.dna.species.id != SPECIES_ZOMBIE) + var/mob/living/carbon/human/player_mob = player_mind.current + + if(player_mob.stat == DEAD) + return FALSE + if(issilicon(player_mob) || isbrain(player_mob)) + return FALSE + if(istype(player_mob) && (player_mob.dna?.species?.id == SPECIES_ZOMBIE_INFECTIOUS)) + return FALSE + return TRUE + else if(isliving(player_mind.current)) - return player_mind.current.stat != DEAD + return (player_mind.current.stat != DEAD) + return FALSE /** diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index e4f662d6a3a..ebb2d521935 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -197,7 +197,7 @@ if(!didthegamerwin) return FALSE player_client.give_award(/datum/award/score/hardcore_random, human_mob, round(human_mob.hardcore_survival_score * 2)) - else if(human_mob.onCentCom()) + else if(considered_escaped(human_mob)) player_client.give_award(/datum/award/score/hardcore_random, human_mob, round(human_mob.hardcore_survival_score)) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index e083c4aeea7..2f201285b23 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -409,42 +409,36 @@ return !density /** - * Is this atom currently located on centcom + * Is this atom currently located on centcom (or riding off into the sunset on a shuttle) * - * Specifically, is it on the z level and within the centcom areas - * - * You can also be in a shuttleshuttle during endgame transit + * Specifically, is it on the z level and within the centcom areas. + * You can also be in a shuttle during endgame transit. * * Used in gamemode to identify mobs who have escaped and for some other areas of the code * who don't want atoms where they shouldn't be + * + * Returns TRUE if this atom is on centcom or an escape shuttle, or FALSE if not */ /atom/proc/onCentCom() var/turf/current_turf = get_turf(src) if(!current_turf) return FALSE + // This doesn't necessarily check that we're at central command, + // but it checks for any shuttles which have finished are still in hyperspace + // (IE, stuff like the whiteship which fly off into the sunset and "escape") if(is_reserved_level(current_turf.z)) - for(var/obj/docking_port/mobile/mobile_docking_port as anything in SSshuttle.mobile_docking_ports) - if(mobile_docking_port.launch_status != ENDGAME_TRANSIT) - continue - for(var/area/shuttle/shuttle_area as anything in mobile_docking_port.shuttle_areas) - if(current_turf in shuttle_area) - return TRUE + return on_escaped_shuttle(ENDGAME_TRANSIT) - if(!is_centcom_level(current_turf.z))//if not, don't bother + // From here on we only concern ourselves with people actually on the centcom Z + if(!is_centcom_level(current_turf.z)) return FALSE - //Check for centcom itself if(istype(current_turf.loc, /area/centcom)) return TRUE - //Check for centcom shuttles - for(var/obj/docking_port/mobile/mobile_docking_port as anything in SSshuttle.mobile_docking_ports) - if(mobile_docking_port.launch_status == ENDGAME_LAUNCHED) - for(var/place as anything in mobile_docking_port.shuttle_areas) - var/area/shuttle/shuttle_area = place - if(current_turf in shuttle_area) - return TRUE + // Finally, check if we're on an escaped shuttle + return on_escaped_shuttle() /** * Is the atom in any of the syndicate areas @@ -452,18 +446,49 @@ * Either in the syndie base, or any of their shuttles * * Also used in gamemode code for win conditions + * + * Returns TRUE if this atom is on the syndicate recon base, any of its shuttles, or an escape shuttle, or FALSE if not */ /atom/proc/onSyndieBase() var/turf/current_turf = get_turf(src) if(!current_turf) return FALSE - if(!is_reserved_level(current_turf.z))//if not, don't bother + // Syndicate base is loaded in a reserved level. If not reserved, we don't care. + if(!is_reserved_level(current_turf.z)) return FALSE - if(istype(current_turf.loc, /area/shuttle/syndicate) || istype(current_turf.loc, /area/centcom/syndicate_mothership) || istype(current_turf.loc, /area/shuttle/assault_pod)) + var/static/list/syndie_typecache = typecacheof(list( + /area/centcom/syndicate_mothership, // syndicate base itself + /area/shuttle/assault_pod, // steel rain + /area/shuttle/syndicate, // infiltrator + )) + + if(is_type_in_typecache(current_turf.loc, syndie_typecache)) return TRUE + // Finally, check if we're on an escaped shuttle + return on_escaped_shuttle() + +/** + * Checks that we're on a shuttle that's escaped + * + * * check_for_launch_status - What launch status do we check for? Generally the two you want to check for are ENDGAME_LAUNCHED or ENDGAME_TRANSIT + * + * Returns TRUE if this atom is on a shuttle which is escaping or has escaped, or FALSE otherwise + */ +/atom/proc/on_escaped_shuttle(check_for_launch_status = ENDGAME_LAUNCHED) + var/turf/current_turf = get_turf(src) + if(!current_turf) + return FALSE + + for(var/obj/docking_port/mobile/mobile_docking_port as anything in SSshuttle.mobile_docking_ports) + if(mobile_docking_port.launch_status != check_for_launch_status) + continue + for(var/area/shuttle/shuttle_area as anything in mobile_docking_port.shuttle_areas) + if(current_turf in shuttle_area.get_contained_turfs()) + return TRUE + return FALSE /** diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 9b4867a948c..0686b622aea 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -67,22 +67,31 @@ GLOBAL_LIST_EMPTY(objectives) //SKYRAT EDIT ADDITION * Escaped mobs are used to check certain antag objectives / results. * * Escaped includes minds with alive, non-exiled mobs generally. + * + * Returns TRUE if they're a free person, or FALSE if they failed */ /proc/considered_escaped(datum/mind/escapee) if(!considered_alive(escapee)) return FALSE if(considered_exiled(escapee)) return FALSE + // "Into the sunset" force escaping for forced escape success if(escapee.force_escaped) return TRUE - if(SSticker.force_ending || GLOB.station_was_nuked) // Just let them win. + // Station destroying events (blob, cult, nukies)? Just let them win, even if there was no hope of escape + if(SSticker.force_ending || GLOB.station_was_nuked) return TRUE + // Escape hasn't happened yet if(SSshuttle.emergency.mode != SHUTTLE_ENDGAME) return FALSE var/area/current_area = get_area(escapee.current) - if(!current_area || istype(current_area, /area/shuttle/escape/brig)) // Fails if they are in the shuttle brig + // In custody (shuttle brig) does not count as escaping + if(!current_area || istype(current_area, /area/shuttle/escape/brig)) return FALSE var/turf/current_turf = get_turf(escapee.current) + if(!current_turf) + return FALSE + // Finally, if we made it to centcom (or the syndie base - got hijacked), we're home free return current_turf.onCentCom() || current_turf.onSyndieBase() /datum/objective/proc/check_completion() diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index 230e3a0ea58..4797a831715 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -535,9 +535,8 @@ if(time_left <= 0) //move each escape pod to its corresponding escape dock - for(var/A in SSshuttle.mobile_docking_ports) - var/obj/docking_port/mobile/M = A - M.on_emergency_dock() + for(var/obj/docking_port/mobile/port as anything in SSshuttle.mobile_docking_ports) + port.on_emergency_dock() // now move the actual emergency shuttle to centcom // unless the shuttle is "hijacked" diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index 5985efe8b06..bed4449c688 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -1162,7 +1162,8 @@ //Called when emergency shuttle docks at centcom /obj/docking_port/mobile/proc/on_emergency_dock() - //Mapping a new docking point for each ship mappers could potentially want docking with centcom would take up lots of space, just let them keep flying off into the sunset for their greentext + // Mapping a new docking point for each ship mappers could potentially want docking with centcom would take up lots of space, + // just let them keep flying off "into the sunset" for their greentext. if(launch_status == ENDGAME_LAUNCHED) launch_status = ENDGAME_TRANSIT