Hazardous Area Component | Free Golem Soft-Restriction (#65720)

Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
This commit is contained in:
Zephyr
2022-03-28 17:49:50 -04:00
committed by GitHub
parent 7b5619f29f
commit a00df2ed76
10 changed files with 159 additions and 0 deletions
@@ -0,0 +1,3 @@
/// Called on a mob attempting to use a ladder to go in either direction. (entrance_ladder, exit_ladder, going_up)
#define COMSIG_LADDER_TRAVEL "ladder-travel"
#define LADDER_TRAVEL_BLOCK (1<<0)
@@ -0,0 +1,4 @@
/// Called on a mob when they start riding a vehicle (obj/vehicle)
#define COMSIG_VEHICLE_RIDDEN "vehicle-ridden"
/// Return this to signal that the mob should be removed from the vehicle
#define EJECT_FROM_VEHICLE (1<<0)
+130
View File
@@ -0,0 +1,130 @@
/**
* This is a relatively simple component that attempts to deter the parent of the component away
* from a specific area or areas. By default it simply applies a penalty where all movement is
* four times slower than usual and any action that would affect your 'next move' has a penalty
* multiplier of 4 attached.
*/
/datum/component/hazard_area
/// The blacklist of areas that the parent will be penalized for entering
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 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
/datum/component/hazard_area/Initialize(area_blacklist, area_whitelist)
. = ..()
if(!ismob(parent))
return COMPONENT_INCOMPATIBLE
if(!islist(area_blacklist) && !islist(area_whitelist))
stack_trace("[type] - neither area_blacklist nor area_whitelist were provided.")
return COMPONENT_INCOMPATIBLE
src.area_blacklist = area_blacklist
src.area_whitelist = area_whitelist
/datum/component/hazard_area/RegisterWithParent()
var/mob/parent_mob = parent
parent_mob.become_area_sensitive(type)
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)
/datum/component/hazard_area/UnregisterFromParent()
var/mob/parent_mob = parent
UnregisterSignal(parent_mob, list(COMSIG_ENTER_AREA, COMSIG_LADDER_TRAVEL, COMSIG_VEHICLE_RIDDEN))
parent_mob.lose_area_sensitivity(type)
/**
* This signal handler checks the area the target ladder is in and if hazardous prevents them from using it
*/
/datum/component/hazard_area/proc/reject_ladder_movement(mob/source, obj/entrance_ladder, exit_ladder, going_up)
SIGNAL_HANDLER
if(check_area_hazardous(get_area(exit_ladder)))
entrance_ladder.balloon_alert(parent, "the path is too dangerous for you!")
return LADDER_TRAVEL_BLOCK
/**
* A simple signal handler that informs the parent they cannot ride a vehicle and ejects them
*/
/datum/component/hazard_area/proc/reject_vehicle(mob/source, obj/vehicle/vehicle)
SIGNAL_HANDLER
if(!check_area_hazardous(last_parent_area))
return
vehicle.balloon_alert(parent, "you slip and fall off!")
var/mob/living/parent_living = parent
parent_living.Stun(0.5 SECONDS)
return EJECT_FROM_VEHICLE
/**
* Checks if the area being checked is considered hazardous
* The whitelist is checked first if it exists, otherwise it checks if it is in the blacklist
*
* * 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(!ispath(checking))
checking = checking.type
if(area_whitelist)
return !(checking in area_whitelist)
return checking in area_blacklist
/**
* This proc handles the status effect applied to the parent, most noteably applying or removing it as required
*/
/datum/component/hazard_area/proc/update_parent_status_effect()
if(QDELETED(parent))
return
var/mob/living/parent_living = parent
var/datum/status_effect/hazard_area/effect = parent_living.has_status_effect(/datum/status_effect/hazard_area)
var/should_have_status_effect = check_area_hazardous(last_parent_area)
if(should_have_status_effect && !effect) // Should have the status - and doesnt
parent_living.apply_status_effect(/datum/status_effect/hazard_area)
if(parent_living.buckled)
parent_living.buckled.balloon_alert(parent, "you fall off!")
parent_living.buckled.unbuckle_mob(parent_living, force=TRUE)
return
if(!should_have_status_effect && effect) // Shouldn't have the status - and does
parent_living.remove_status_effect(/datum/status_effect/hazard_area)
/**
* This signal should be called whenever our parent moves.
*/
/datum/component/hazard_area/proc/handle_parent_area_change(mob/source, area/new_area)
SIGNAL_HANDLER
if(new_area.type == last_parent_area)
return
last_parent_area = new_area.type
INVOKE_ASYNC(src, .proc/update_parent_status_effect)
/// The dedicated status effect for the hazard_area component - use with caution and know what it does!
/datum/status_effect/hazard_area
id = "hazard_area"
examine_text = "SUBJECTPRONOUN appears to be largely immobilized through unknown means."
status_type = STATUS_EFFECT_UNIQUE
alert_type = /atom/movable/screen/alert/status_effect/hazard_area
/datum/status_effect/hazard_area/nextmove_modifier()
return 4
/datum/status_effect/hazard_area/on_apply()
. = ..()
owner.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/hazard_area, update=TRUE)
owner.add_actionspeed_modifier(/datum/actionspeed_modifier/status_effect/hazard_area, update=TRUE)
/datum/status_effect/hazard_area/on_remove()
. = ..()
owner.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/hazard_area, update=TRUE)
owner.remove_actionspeed_modifier(/datum/actionspeed_modifier/status_effect/hazard_area, update=TRUE)
/atom/movable/screen/alert/status_effect/hazard_area
name = "Hazardous Area"
desc = "The area you are currently within is incredibly hazardous to you. Check your surroudings and vacate as soon as possible."
icon_state = "hazard_area"
+4
View File
@@ -71,6 +71,10 @@
qdel(src)
/obj/structure/ladder/proc/travel(going_up, mob/user, is_ghost, obj/structure/ladder/ladder)
var/response = SEND_SIGNAL(user, COMSIG_LADDER_TRAVEL, src, ladder, going_up)
if(response & LADDER_TRAVEL_BLOCK)
return
if(!is_ghost)
ladder.add_fingerprint(user)
if(!do_after(user, travel_time, target = src))
@@ -6,3 +6,6 @@
/datum/actionspeed_modifier/nooartrium
multiplicative_slowdown = 0.5
/datum/actionspeed_modifier/status_effect/hazard_area
multiplicative_slowdown = 4
@@ -52,6 +52,10 @@
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.")
var/static/list/allowed_areas
if(!allowed_areas)
allowed_areas = typecacheof(list(/area/icemoon, /area/lavaland, /area/ruin))
new_spawn.AddComponent(/datum/component/hazard_area, area_whitelist=allowed_areas)
else
new_spawn.mind.enslave_mind_to_creator(owner)
log_game("[key_name(new_spawn)] possessed a golem shell enslaved to [key_name(owner)].")
@@ -16,3 +16,6 @@
variable = TRUE
blacklisted_movetypes = (FLYING|FLOATING)
/datum/movespeed_modifier/status_effect/hazard_area
multiplicative_slowdown = 4
+5
View File
@@ -58,6 +58,11 @@
/obj/vehicle/ridden/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE)
if(!force && occupant_amount() >= max_occupants)
return FALSE
var/response = SEND_SIGNAL(M, COMSIG_VEHICLE_RIDDEN, src)
if(response & EJECT_FROM_VEHICLE)
return FALSE
return ..()
/obj/vehicle/ridden/zap_act(power, zap_flags)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 116 KiB

+3
View File
@@ -212,6 +212,7 @@
#include "code\__DEFINES\dcs\signals\signals_heretic.dm"
#include "code\__DEFINES\dcs\signals\signals_hydroponic.dm"
#include "code\__DEFINES\dcs\signals\signals_janitor.dm"
#include "code\__DEFINES\dcs\signals\signals_ladder.dm"
#include "code\__DEFINES\dcs\signals\signals_light_eater.dm"
#include "code\__DEFINES\dcs\signals\signals_medical.dm"
#include "code\__DEFINES\dcs\signals\signals_mind.dm"
@@ -240,6 +241,7 @@
#include "code\__DEFINES\dcs\signals\signals_transform.dm"
#include "code\__DEFINES\dcs\signals\signals_turf.dm"
#include "code\__DEFINES\dcs\signals\signals_twohand.dm"
#include "code\__DEFINES\dcs\signals\signals_vehicle.dm"
#include "code\__DEFINES\dcs\signals\signals_wash.dm"
#include "code\__DEFINES\dcs\signals\signals_xeno_control.dm"
#include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_attack.dm"
@@ -714,6 +716,7 @@
#include "code\datums\components\gps.dm"
#include "code\datums\components\grillable.dm"
#include "code\datums\components\gunpoint.dm"
#include "code\datums\components\hazard_area.dm"
#include "code\datums\components\heirloom.dm"
#include "code\datums\components\holderloving.dm"
#include "code\datums\components\igniter.dm"