From 166dcdeb2685bb8b7c783b57f1ff1e8a8d863eb7 Mon Sep 17 00:00:00 2001 From: Zephyr <12817816+ZephyrTFA@users.noreply.github.com> Date: Sat, 9 Apr 2022 20:58:07 -0400 Subject: [PATCH] [NO GBP] Resolves Golems not being allowed in the areas they created (#66000) Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com> --- code/__DEFINES/dcs/signals/signals_global.dm | 3 ++ code/__HELPERS/areas.dm | 1 + code/datums/components/hazard_area.dm | 43 ++++++++++++++++++- .../mob_spawn/ghost_roles/golem_roles.dm | 3 +- 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/code/__DEFINES/dcs/signals/signals_global.dm b/code/__DEFINES/dcs/signals/signals_global.dm index 0a771e756dc..28d8454e0de 100644 --- a/code/__DEFINES/dcs/signals/signals_global.dm +++ b/code/__DEFINES/dcs/signals/signals_global.dm @@ -6,6 +6,9 @@ // These are signals which can be listened to by any component on any parent // start global signals with "!", this used to be necessary but now it's just a formatting choice + +/// called after a successful area creation by a mob: (area/created_area, area/old_area, mob/creator) +#define COMSIG_AREA_CREATED "!mob_created_area" ///from base of datum/controller/subsystem/mapping/proc/add_new_zlevel(): (list/args) #define COMSIG_GLOB_NEW_Z "!new_z" /// sent after world.maxx and/or world.maxy are expanded: (has_exapnded_world_maxx, has_expanded_world_maxy) diff --git a/code/__HELPERS/areas.dm b/code/__HELPERS/areas.dm index e7876df8ae7..cc99089e29d 100644 --- a/code/__HELPERS/areas.dm +++ b/code/__HELPERS/areas.dm @@ -99,6 +99,7 @@ GLOBAL_LIST_INIT(typecache_powerfailure_safe_areas, typecacheof(/area/engineerin var/obj/machinery/door/firedoor/FD = door FD.CalculateAffectingAreas() + SEND_GLOBAL_SIGNAL(COMSIG_AREA_CREATED, newA, oldA, creator) to_chat(creator, span_notice("You have created a new area, named [newA.name]. It is now weather proof, and constructing an APC will allow it to be powered.")) return TRUE diff --git a/code/datums/components/hazard_area.dm b/code/datums/components/hazard_area.dm index 544024d35b5..1e0423ac956 100644 --- a/code/datums/components/hazard_area.dm +++ b/code/datums/components/hazard_area.dm @@ -9,6 +9,8 @@ var/list/area_blacklist /// The whitelist of areas that the parent is allowed to be in. If set this overrides the blacklist var/list/area_whitelist + /// A list of areas that have been created and are considered to not be hazardous + var/list/area_created /// A variable storing the typepath of the last checked area to prevent any further logic running if it has not changed VAR_PRIVATE/last_parent_area @@ -21,6 +23,7 @@ return COMPONENT_INCOMPATIBLE src.area_blacklist = area_blacklist src.area_whitelist = area_whitelist + area_created = new /datum/component/hazard_area/RegisterWithParent() var/mob/parent_mob = parent @@ -28,12 +31,18 @@ RegisterSignal(parent_mob, COMSIG_ENTER_AREA, .proc/handle_parent_area_change) RegisterSignal(parent_mob, COMSIG_LADDER_TRAVEL, .proc/reject_ladder_movement) RegisterSignal(parent_mob, COMSIG_VEHICLE_RIDDEN, .proc/reject_vehicle) + RegisterSignal(SSdcs, COMSIG_AREA_CREATED, .proc/on_area_creation) /datum/component/hazard_area/UnregisterFromParent() var/mob/parent_mob = parent UnregisterSignal(parent_mob, list(COMSIG_ENTER_AREA, COMSIG_LADDER_TRAVEL, COMSIG_VEHICLE_RIDDEN)) + UnregisterSignal(SSdcs, COMSIG_AREA_CREATED) parent_mob.lose_area_sensitivity(type) +/datum/component/hazard_area/Destroy(force, silent) + . = ..() + area_created = null + /** * This signal handler checks the area the target ladder is in and if hazardous prevents them from using it */ @@ -54,8 +63,9 @@ return vehicle.balloon_alert(parent, "you slip and fall off!") - var/mob/living/parent_living = parent - parent_living.Stun(0.5 SECONDS) + if(isliving(parent)) // We don't know for certain if we are a mob/living subtype + var/mob/living/parent_living = parent + parent_living.Stun(0.5 SECONDS) return EJECT_FROM_VEHICLE /** @@ -65,12 +75,41 @@ * * checking - This should be the typepath of the area being checked, but there is a conversion handler if you pass in a reference instead */ /datum/component/hazard_area/proc/check_area_hazardous(area/checking) + if(LAZYFIND(area_created, checking)) + return FALSE if(!ispath(checking)) checking = checking.type if(area_whitelist) return !(checking in area_whitelist) return checking in area_blacklist +/** + * This signal handler does a few house cleaning tasks when a new area is created. + * If the created area already exists in the blacklist or whitelist it simply returns, + * however if it isn't we check for an overwritten area and if non-hazardous setup the area to + * allow the parent. + * If there isnt an overwritten area it assumes it to be non-hazardous, abuse it and you will weep -ZephyrTFA + */ +/datum/component/hazard_area/proc/on_area_creation(datum/source, area/created, area/overwritten, mob/creator) + SIGNAL_HANDLER + + if(created.type in area_whitelist) + return // in whitelist, probably expanded an already whitelisted area + + if(created.type in area_blacklist) + return // in blacklist, expanding a blacklisted area doesnt magically give you permission to enter + + if(overwritten) + if(check_area_hazardous(overwritten.type)) + return // Overwrote a hazardous area, still hazardous fool + area_created -= overwritten // While its not guaranteed to be in the area_created list it's a good idea to ensure we dont have handing refs + area_created += created // Congrats, you are now allowed in this area + return + + // No overwritten area, which means its a brand new area, for now we are going to be nice and assume its non-hazardous + // If people abuse this in the future to put rooms right next to the station add an is_station_level check + area_created += created + /** * This proc handles the status effect applied to the parent, most noteably applying or removing it as required */ diff --git a/code/modules/mob_spawn/ghost_roles/golem_roles.dm b/code/modules/mob_spawn/ghost_roles/golem_roles.dm index 8b50bca5ad4..8c6eca9e6a1 100644 --- a/code/modules/mob_spawn/ghost_roles/golem_roles.dm +++ b/code/modules/mob_spawn/ghost_roles/golem_roles.dm @@ -52,7 +52,6 @@ if (policy) to_chat(new_spawn, policy) to_chat(new_spawn, "Build golem shells in the autolathe, and feed refined mineral sheets to the shells to bring them to life! You are generally a peaceful group unless provoked.") - try_keep_home(new_spawn) else new_spawn.mind.enslave_mind_to_creator(owner) @@ -70,7 +69,7 @@ new_spawn.mind.set_assigned_role(SSjob.GetJobType(/datum/job/free_golem)) /obj/effect/mob_spawn/ghost_role/human/golem/proc/try_keep_home(mob/new_spawn) - var/static/list/allowed_areas = typecacheof(list(/area/icemoon, /area/lavaland, /area/ruin)) + var/static/list/allowed_areas = typecacheof(list(/area/icemoon, /area/lavaland, /area/ruin)) + typecacheof(/area/survivalpod) ADD_TRAIT(new_spawn, TRAIT_FORBID_MINING_SHUTTLE_CONSOLE_OUTSIDE_STATION, INNATE_TRAIT) new_spawn.AddComponent(/datum/component/hazard_area, area_whitelist = allowed_areas)