mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-06-22 06:35:12 +01:00
f58b8511f0
## About The Pull Request This PR refactors ``effect_system``s to be a bit easier to use by getting rid of ``set_up``, allowing ``attach()`` to be chained into ``start()`` and refactoring most direct system usages in our code to use helper procs. ``set_up`` was unnecessary and only existed to allow ``New``'s behavior to be fully overriden, which is not required if we split sparks/lightning/steam into a new ``/datum/effect_system/basic`` subtype which houses the effect spreading behavior. This allows us to roll all logic from ``set_up`` into ``New`` and cut down on code complexity. Chaining setup as ``system.attach(src).start()`` also helps a bit in case no helper method exists I've added ``do_chem_smoke`` and ``do_foam`` helpers, which respectively allow chemical smoke or foam to be spawned easily without having to manually create effect datums and reagent holders. Also turns out we've had some nonfunctional effect systems which either never set themselves up, or never started, so I fixed those while I was at it (mostly by moving them to aforementioned helper procs) ## Why It's Good For The Game Cleaner code, makes it significantly easier for users to work with. Also most of our effect system usage was copypasta which was passing booleans as numbers, while perfectly fine helper procs existed in our code. ## Changelog 🆑 refactor: Refactored sparks, foam, smoke, and other miscellaneous effect systems. refactor: Vapes now have consistent rigging with cigs using the new system. fix: Fixed some effects never working. /🆑
244 lines
7.3 KiB
Plaintext
244 lines
7.3 KiB
Plaintext
/obj/structure/trap
|
|
name = "IT'S A TRAP"
|
|
desc = "Stepping on me is a guaranteed bad day."
|
|
icon = 'icons/obj/service/hand_of_god_structures.dmi'
|
|
icon_state = "trap"
|
|
density = FALSE
|
|
anchored = TRUE
|
|
alpha = 30 //initially quite hidden when not "recharging"
|
|
var/flare_message = span_warning("the trap flares brightly!")
|
|
var/last_trigger = 0
|
|
var/time_between_triggers = 1 MINUTES
|
|
var/charges = INFINITY
|
|
var/antimagic_flags = MAGIC_RESISTANCE
|
|
|
|
var/static/list/ignore_typecache
|
|
var/list/mob/immune_minds = list()
|
|
|
|
var/sparks = TRUE
|
|
var/datum/effect_system/basic/spark_spread/spark_system
|
|
|
|
/obj/structure/trap/Initialize(mapload)
|
|
. = ..()
|
|
flare_message = span_warning("[src] flares brightly!")
|
|
spark_system = new(src, 4, TRUE)
|
|
|
|
var/static/list/loc_connections = list(
|
|
COMSIG_ATOM_ENTERED = PROC_REF(on_entered)
|
|
)
|
|
AddElement(/datum/element/connect_loc, loc_connections)
|
|
|
|
if(isnull(ignore_typecache))
|
|
ignore_typecache = typecacheof(list(
|
|
/obj/effect,
|
|
/mob/dead,
|
|
))
|
|
|
|
/obj/structure/trap/Destroy()
|
|
QDEL_NULL(spark_system)
|
|
return ..()
|
|
|
|
/obj/structure/trap/examine(mob/user)
|
|
. = ..()
|
|
if(!isliving(user))
|
|
return
|
|
if(user.mind && (user.mind in immune_minds))
|
|
return
|
|
if(get_dist(user, src) <= 1)
|
|
. += span_notice("You reveal [src]!")
|
|
flare()
|
|
|
|
/obj/structure/trap/proc/flare()
|
|
// Makes the trap visible, and starts the cooldown until it's
|
|
// able to be triggered again.
|
|
visible_message(flare_message)
|
|
if(sparks)
|
|
spark_system.start()
|
|
alpha = 200
|
|
last_trigger = world.time
|
|
charges--
|
|
if(charges <= 0)
|
|
animate(src, alpha = 0, time = 1 SECONDS)
|
|
QDEL_IN(src, 1 SECONDS)
|
|
else
|
|
animate(src, alpha = initial(alpha), time = time_between_triggers)
|
|
|
|
/obj/structure/trap/proc/on_entered(datum/source, atom/movable/victim)
|
|
SIGNAL_HANDLER
|
|
if(last_trigger + time_between_triggers > world.time)
|
|
return
|
|
// Don't want the traps triggered by sparks, ghosts or projectiles.
|
|
if(is_type_in_typecache(victim, ignore_typecache))
|
|
return
|
|
if(ismob(victim))
|
|
var/mob/mob_victim = victim
|
|
if(mob_victim.mind in immune_minds)
|
|
return
|
|
if(mob_victim.can_block_magic(antimagic_flags))
|
|
flare()
|
|
return
|
|
if(charges <= 0)
|
|
return
|
|
flare()
|
|
if(isliving(victim))
|
|
trap_effect(victim)
|
|
|
|
/obj/structure/trap/proc/trap_effect(mob/living/victim)
|
|
return
|
|
|
|
/obj/structure/trap/stun
|
|
name = "shock trap"
|
|
desc = "A trap that will shock and render you immobile. You'd better avoid it."
|
|
icon_state = "trap-shock"
|
|
var/stun_time = 10 SECONDS
|
|
|
|
/obj/structure/trap/stun/trap_effect(mob/living/victim)
|
|
victim.electrocute_act(30, src, flags = SHOCK_NOGLOVES) // electrocute act does a message.
|
|
victim.Paralyze(stun_time)
|
|
|
|
/obj/structure/trap/stun/hunter
|
|
name = "bounty trap"
|
|
desc = "A trap that only goes off when a fugitive steps on it, announcing the location and stunning the target. You'd better avoid it."
|
|
icon = 'icons/obj/weapons/restraints.dmi'
|
|
icon_state = "bounty_trap_on"
|
|
stun_time = 20 SECONDS
|
|
sparks = FALSE //the item version gives them off to prevent runtimes (see Destroy())
|
|
antimagic_flags = NONE
|
|
var/obj/item/bountytrap/stored_item
|
|
var/caught = FALSE
|
|
|
|
/obj/structure/trap/stun/hunter/Initialize(mapload)
|
|
. = ..()
|
|
time_between_triggers = 1 SECONDS
|
|
flare_message = span_warning("[src] snaps shut!")
|
|
|
|
/obj/structure/trap/stun/hunter/Destroy()
|
|
if(!QDELETED(stored_item))
|
|
qdel(stored_item)
|
|
stored_item = null
|
|
return ..()
|
|
|
|
/obj/structure/trap/stun/hunter/on_entered(datum/source, atom/movable/victim)
|
|
if(isliving(victim))
|
|
var/mob/living/living_victim = victim
|
|
if(!living_victim.mind?.has_antag_datum(/datum/antagonist/fugitive))
|
|
return
|
|
caught = TRUE
|
|
. = ..()
|
|
|
|
/obj/structure/trap/stun/hunter/flare()
|
|
..()
|
|
var/turf/our_turf = get_turf(src)
|
|
if(!our_turf)
|
|
return
|
|
stored_item.forceMove(get_turf(src))
|
|
forceMove(stored_item)
|
|
if(caught)
|
|
stored_item.announce_fugitive()
|
|
caught = FALSE
|
|
|
|
/obj/item/bountytrap
|
|
name = "bounty trap"
|
|
desc = "A trap that only goes off when a fugitive steps on it, announcing the location and stunning the target. It's currently inactive."
|
|
icon = 'icons/obj/weapons/restraints.dmi'
|
|
icon_state = "bounty_trap_off"
|
|
var/obj/structure/trap/stun/hunter/stored_trap
|
|
var/obj/item/radio/radio
|
|
var/datum/effect_system/basic/spark_spread/spark_system
|
|
|
|
/obj/item/bountytrap/Initialize(mapload)
|
|
. = ..()
|
|
radio = new(src)
|
|
radio.subspace_transmission = TRUE
|
|
radio.canhear_range = 0
|
|
radio.recalculateChannels()
|
|
spark_system = new(src, 4, TRUE)
|
|
spark_system.attach(src)
|
|
name = "[name] #[rand(1, 999)]"
|
|
stored_trap = new(src)
|
|
stored_trap.name = name
|
|
stored_trap.stored_item = src
|
|
|
|
/obj/item/bountytrap/proc/announce_fugitive()
|
|
spark_system.start()
|
|
playsound(src, 'sound/machines/ding.ogg', 50, TRUE)
|
|
radio.talk_into(src, "Fugitive has triggered this trap in the [get_area_name(src)]!", RADIO_CHANNEL_COMMON)
|
|
|
|
/obj/item/bountytrap/attack_self(mob/living/user)
|
|
var/turf/target_turf = get_turf(src)
|
|
if(!user || !user.transferItemToLoc(src, target_turf))//visibly unequips
|
|
return
|
|
to_chat(user, span_notice("You set up [src]. Examine while close to disarm it."))
|
|
stored_trap.forceMove(target_turf)//moves trap to ground
|
|
forceMove(stored_trap)//moves item into trap
|
|
|
|
/obj/item/bountytrap/Destroy()
|
|
if(!QDELETED(stored_trap))
|
|
qdel(stored_trap)
|
|
stored_trap = null
|
|
QDEL_NULL(radio)
|
|
QDEL_NULL(spark_system)
|
|
. = ..()
|
|
|
|
/obj/structure/trap/fire
|
|
name = "flame trap"
|
|
desc = "A trap that will set you ablaze. You'd better avoid it."
|
|
icon_state = "trap-fire"
|
|
|
|
/obj/structure/trap/fire/trap_effect(mob/living/victim)
|
|
to_chat(victim, span_danger("<B>Spontaneous combustion!</B>"))
|
|
victim.Paralyze(2 SECONDS)
|
|
new /obj/effect/hotspot(get_turf(src))
|
|
|
|
/obj/structure/trap/chill
|
|
name = "frost trap"
|
|
desc = "A trap that will chill you to the bone. You'd better avoid it."
|
|
icon_state = "trap-frost"
|
|
|
|
/obj/structure/trap/chill/trap_effect(mob/living/victim)
|
|
if(HAS_TRAIT(victim, TRAIT_RESISTCOLD))
|
|
return
|
|
to_chat(victim, span_bolddanger("You're frozen solid!"))
|
|
victim.Paralyze(2 SECONDS)
|
|
victim.adjust_bodytemperature(-300)
|
|
victim.apply_status_effect(/datum/status_effect/freon)
|
|
|
|
|
|
/obj/structure/trap/damage
|
|
name = "earth trap"
|
|
desc = "A trap that will summon a small earthquake, just for you. You'd better avoid it."
|
|
icon_state = "trap-earth"
|
|
|
|
|
|
/obj/structure/trap/damage/trap_effect(mob/living/victim)
|
|
to_chat(victim, span_bolddanger("The ground quakes beneath your feet!"))
|
|
victim.Paralyze(10 SECONDS)
|
|
victim.adjust_brute_loss(35)
|
|
var/obj/structure/flora/rock/style_random/giant_rock = new(get_turf(src))
|
|
QDEL_IN(giant_rock, 20 SECONDS)
|
|
|
|
|
|
/obj/structure/trap/ward
|
|
name = "divine ward"
|
|
desc = "A divine barrier, It looks like you could destroy it with enough effort, or wait for it to dissipate..."
|
|
icon_state = "ward"
|
|
density = TRUE
|
|
time_between_triggers = 2 MINUTES
|
|
|
|
/obj/structure/trap/ward/Initialize(mapload)
|
|
. = ..()
|
|
QDEL_IN(src, time_between_triggers)
|
|
|
|
/obj/structure/trap/cult
|
|
name = "unholy trap"
|
|
desc = "A trap that rings with unholy energy. You think you hear... chittering?"
|
|
icon_state = "trap-cult"
|
|
|
|
/obj/structure/trap/cult/trap_effect(mob/living/victim)
|
|
to_chat(victim, span_bolddanger("With a crack, the hostile constructs come out of hiding, stunning you!"))
|
|
victim.electrocute_act(10, src, flags = SHOCK_NOGLOVES) // electrocute act does a message.
|
|
victim.Paralyze(2 SECONDS)
|
|
new /mob/living/basic/construct/proteon/hostile(loc)
|
|
new /mob/living/basic/construct/proteon/hostile(loc)
|
|
QDEL_IN(src, 3 SECONDS)
|