diff --git a/code/datums/wires/_wires.dm b/code/datums/wires/_wires.dm
index 745e719112c..db3503a2f95 100644
--- a/code/datums/wires/_wires.dm
+++ b/code/datums/wires/_wires.dm
@@ -184,13 +184,14 @@
assemblies[color] = S
S.forceMove(holder)
S.connected = src
+ S.on_attach() // Notify assembly that it is attached
return S
/datum/wires/proc/detach_assembly(color)
var/obj/item/assembly/S = get_attached(color)
if(S && istype(S))
assemblies -= color
- S.connected = null
+ S.on_detach() // Notify the assembly. This should remove the reference to our holder
S.forceMove(holder.drop_location())
return S
diff --git a/code/game/communications.dm b/code/game/communications.dm
index e4517f4f644..ba8c29ed250 100644
--- a/code/game/communications.dm
+++ b/code/game/communications.dm
@@ -180,11 +180,13 @@ GLOBAL_LIST_INIT(reverseradiochannels, list(
if (!filter)
filter = "_default"
+ var/datum/weakref/new_listener = WEAKREF(device)
+ if(isnull(new_listener))
+ return stack_trace("null, non-datum, or qdeleted device")
var/list/devices_line = devices[filter]
if(!devices_line)
devices[filter] = devices_line = list()
- devices_line += WEAKREF(device)
-
+ devices_line += new_listener
/datum/radio_frequency/proc/remove_listener(obj/device)
for(var/devices_filter in devices)
@@ -195,7 +197,6 @@ GLOBAL_LIST_INIT(reverseradiochannels, list(
if(!devices_line.len)
devices -= devices_filter
-
/obj/proc/receive_signal(datum/signal/signal)
return
diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm
index a188b07f764..8d5477aafb9 100644
--- a/code/game/objects/items/devices/transfer_valve.dm
+++ b/code/game/objects/items/devices/transfer_valve.dm
@@ -65,8 +65,8 @@
return
attached_device = A
to_chat(user, span_notice("You attach the [item] to the valve controls and secure it."))
- A.on_attach()
A.holder = src
+ A.on_attach()
A.toggle_secure() //this calls update_icon(), which calls update_icon() on the holder (i.e. the bomb).
log_bomber(user, "attached a [item.name] to a ttv -", src, null, FALSE)
attacher = user
diff --git a/code/modules/assembly/assembly.dm b/code/modules/assembly/assembly.dm
index c8a529a8d51..0b9becc8c86 100644
--- a/code/modules/assembly/assembly.dm
+++ b/code/modules/assembly/assembly.dm
@@ -39,17 +39,30 @@
/obj/item/assembly/get_part_rating()
return 1
+/**
+ * on_attach: Called when attached to a holder, wiring datum, or other special assembly
+ *
+ * Will also be called if the assembly holder is attached to a plasma (internals) tank or welding fuel (dispenser) tank.
+ */
/obj/item/assembly/proc/on_attach()
+ if(!holder && connected)
+ holder = connected.holder
-//Call this when detaching it from a device. handles any special functions that need to be updated ex post facto
+/**
+ * on_detach: Called when removed from an assembly holder or wiring datum
+ */
/obj/item/assembly/proc/on_detach()
+ if(connected)
+ connected = null
if(!holder)
return FALSE
forceMove(holder.drop_location())
holder = null
return TRUE
-//Called when the holder is moved
+/**
+ * holder_movement: Called when the assembly's holder detects movement
+ */
/obj/item/assembly/proc/holder_movement()
if(!holder)
return FALSE
@@ -94,6 +107,15 @@
update_appearance()
return secured
+// This is overwritten so that clumsy people can set off mousetraps even when in a holder.
+// We are not going deeper than that however (won't set off if in a tank bomb or anything with wires)
+// That would need to be added to all parent objects, or a signal created, whatever.
+// Anyway this return check prevents you from picking up every assembly inside the holder at once.
+/obj/item/assembly/attack_hand(mob/living/user, list/modifiers)
+ if(holder || connected)
+ return
+ . = ..()
+
/obj/item/assembly/attackby(obj/item/W, mob/user, params)
if(isassembly(W))
var/obj/item/assembly/A = W
@@ -135,9 +157,12 @@
return ui_interact(user)
/obj/item/assembly/ui_host(mob/user)
- if(holder)
- return holder
- return src
+ // In order, return:
+ // - The conencted wiring datum's owner, or
+ // - The thing your assembly holder is attached to, or
+ // - the assembly holder itself, or
+ // - us
+ return connected?.holder || holder?.master || holder || src
/obj/item/assembly/ui_state(mob/user)
return GLOB.hands_state
diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm
index 9ef44fc61ae..887f8e973b9 100644
--- a/code/modules/assembly/bomb.dm
+++ b/code/modules/assembly/bomb.dm
@@ -136,6 +136,7 @@
bomb.bombassembly = assembly //Tell the bomb about its assembly part
assembly.master = bomb //Tell the assembly about its new owner
+ assembly.on_attach()
bomb.bombtank = src //Same for tank
master = bomb
diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm
index fb551a44e41..004315f7c21 100644
--- a/code/modules/assembly/holder.dm
+++ b/code/modules/assembly/holder.dm
@@ -28,7 +28,6 @@
/obj/item/assembly_holder/IsAssemblyHolder()
return TRUE
-
/obj/item/assembly_holder/proc/assemble(obj/item/assembly/A, obj/item/assembly/A2, mob/user)
attach(A,user)
attach(A2,user)
@@ -36,6 +35,17 @@
update_appearance()
SSblackbox.record_feedback("tally", "assembly_made", 1, "[initial(A.name)]-[initial(A2.name)]")
+/**
+ * on_attach: Pass on_attach message to child assemblies
+ *
+ */
+/obj/item/assembly_holder/proc/on_attach()
+ var/obj/item/newloc = loc
+ if(!newloc.IsSpecialAssembly() && !newloc.IsAssemblyHolder())
+ return
+ for(var/obj/item/assembly/assembly in assemblies)
+ assembly.on_attach()
+
/**
* Adds an assembly to the assembly holder
*
@@ -104,7 +114,7 @@
if(.)
return
for(var/obj/item/assembly/assembly as anything in assemblies)
- assembly.attack_hand()
+ assembly.attack_hand(user, modifiers) // Note override in assembly.dm to prevent side effects here
/obj/item/assembly_holder/attackby(obj/item/weapon, mob/user, params)
if(isassembly(weapon))
@@ -151,7 +161,7 @@
return FALSE
if(normal && LAZYLEN(assemblies) >= 2)
for(var/obj/item/assembly/assembly as anything in assemblies)
- if(LAZYACCESS(assemblies, assembly) != device)
+ if(assembly != device)
assembly.pulsed(FALSE)
if(master)
master.receive_signal()
diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm
index 580b17ab374..9c0b3e081e8 100644
--- a/code/modules/assembly/mousetrap.dm
+++ b/code/modules/assembly/mousetrap.dm
@@ -8,18 +8,72 @@
var/armed = FALSE
drop_sound = 'sound/items/handling/component_drop.ogg'
pickup_sound = 'sound/items/handling/component_pickup.ogg'
+ var/obj/item/host = null
+ var/turf/host_turf = null
- ///if we are attached to an assembly holder, we attach a connect_loc element to ourselves that listens to this from the holder
- var/static/list/holder_connections = list(
- COMSIG_ATOM_ENTERED = .proc/on_entered,
- )
+/**
+ * update_host: automatically setup host and host_turf
+ *
+ * Arguments:
+ * * force: Re-register signals even if the host or loc is unchanged
+ */
+/obj/item/assembly/mousetrap/proc/update_host(force = FALSE)
+ var/obj/item/newhost
+ // Pick the first valid object in this list:
+ // Wiring datum's owner
+ // assembly holder's attached object
+ // assembly holder itself
+ // us
+ newhost = connected?.holder || holder?.master || holder || src
+
+ // ok look
+ // previously this wasn't working and thus no concern, but I made mousetraps work with wires
+ // specifically in step-on-the-mousetrap mode, ie, when you enter its turf
+ // and as a consequence, you can put a mousetrap in door wires and it will be set off
+ // the first time someone walks through a door (enters the door's loc)
+ // that's an interesting mechanic (bolt open a door for example) but it's not appropriate for a mousetrap
+ // similarly if used on say an apc's wires it would go into effect when someone walked by it. Not appropriate.
+ // other assemblies could be made to do something similar instead.
+ // mousetrap assemblies will still receive on-found notifications when you open a wiring panel
+ // and (whether reasonable or not) mousetraps that do this do still trigger wires
+ // the point is for now step-on-mousetrap mode should only work on items
+ // maybe it should never have been an assembly in the first place.
+
+ // tl;dr only trigger step-on mode if the host is an item
+ if(!istype(newhost,/obj/item))
+ if(host)
+ UnregisterSignal(host,COMSIG_MOVABLE_MOVED)
+ host = src
+ if(isturf(host_turf))
+ UnregisterSignal(host_turf,COMSIG_ATOM_ENTERED)
+ host_turf = null
+ return
+
+ // If host changed
+ if((newhost != host) || force)
+ if(host)
+ UnregisterSignal(host,COMSIG_MOVABLE_MOVED)
+ host = newhost
+ RegisterSignal(host,COMSIG_MOVABLE_MOVED,.proc/holder_movement)
+
+ // If host moved
+ if((host_turf != host.loc) || force)
+ if(isturf(host_turf))
+ UnregisterSignal(host_turf,COMSIG_ATOM_ENTERED)
+ host_turf = null
+ if(isturf(host.loc))
+ host_turf = host.loc
+ RegisterSignal(host_turf,COMSIG_ATOM_ENTERED,.proc/on_entered)
+ else
+ host_turf = null
+
+/obj/item/assembly/mousetrap/holder_movement()
+ . = ..()
+ update_host()
/obj/item/assembly/mousetrap/Initialize(mapload)
. = ..()
- var/static/list/loc_connections = list(
- COMSIG_ATOM_ENTERED = .proc/on_entered,
- )
- AddElement(/datum/element/connect_loc, loc_connections)
+ update_host(force = TRUE)
/obj/item/assembly/mousetrap/examine(mob/user)
. = ..()
@@ -47,22 +101,22 @@
/obj/item/assembly/mousetrap/on_attach()
. = ..()
- AddComponent(/datum/component/connect_loc_behalf, holder, holder_connections)
+ update_host()
/obj/item/assembly/mousetrap/on_detach()
. = ..()
- qdel(GetComponent(/datum/component/connect_loc_behalf))
+ update_host()
/obj/item/assembly/mousetrap/proc/triggered(mob/target, type = "feet")
if(!armed)
return
+ armed = FALSE // moved to the top because you could trigger it more than once under some circumstances
+ update_appearance()
var/obj/item/bodypart/affecting = null
if(ishuman(target))
var/mob/living/carbon/human/H = target
if(HAS_TRAIT(H, TRAIT_PIERCEIMMUNE))
playsound(src, 'sound/effects/snap.ogg', 50, TRUE)
- armed = FALSE
- update_appearance()
pulse(FALSE)
return FALSE
switch(type)
@@ -89,22 +143,32 @@
else if(isregalrat(target))
visible_message(span_boldannounce("Skreeeee!")) //He's simply too large to be affected by a tiny mouse trap.
playsound(src, 'sound/effects/snap.ogg', 50, TRUE)
- armed = FALSE
- update_appearance()
pulse(FALSE)
+/**
+ * clumsy_check: Sets off the mousetrap if handled by a clown (with some probability)
+ *
+ * Arguments:
+ * * user: The mob handling the trap
+ */
+/obj/item/assembly/mousetrap/proc/clumsy_check(mob/living/carbon/human/user)
+ if(!armed)
+ return FALSE
+ if((HAS_TRAIT(user, TRAIT_DUMB) || HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50))
+ var/which_hand = BODY_ZONE_PRECISE_L_HAND
+ if(!(user.active_hand_index % 2))
+ which_hand = BODY_ZONE_PRECISE_R_HAND
+ triggered(user, which_hand)
+ user.visible_message(span_warning("[user] accidentally sets off [src], breaking their fingers."), \
+ span_warning("You accidentally trigger [src]!"))
+ return TRUE
+ return FALSE
/obj/item/assembly/mousetrap/attack_self(mob/living/carbon/human/user)
if(!armed)
to_chat(user, span_notice("You arm [src]."))
else
- if((HAS_TRAIT(user, TRAIT_DUMB) || HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50))
- var/which_hand = BODY_ZONE_PRECISE_L_HAND
- if(!(user.active_hand_index % 2))
- which_hand = BODY_ZONE_PRECISE_R_HAND
- triggered(user, which_hand)
- user.visible_message(span_warning("[user] accidentally sets off [src], breaking their fingers."), \
- span_warning("You accidentally trigger [src]!"))
+ if(clumsy_check(user))
return
to_chat(user, span_notice("You disarm [src]."))
armed = !armed
@@ -112,17 +176,10 @@
playsound(src, 'sound/weapons/handcuffs.ogg', 30, TRUE, -3)
-//ATTACK HAND IGNORING PARENT RETURN VALUE
+// Clumsy check only
/obj/item/assembly/mousetrap/attack_hand(mob/living/carbon/human/user, list/modifiers)
- if(armed)
- if((HAS_TRAIT(user, TRAIT_DUMB) || HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50))
- var/which_hand = BODY_ZONE_PRECISE_L_HAND
- if(!(user.active_hand_index % 2))
- which_hand = BODY_ZONE_PRECISE_R_HAND
- triggered(user, which_hand)
- user.visible_message(span_warning("[user] accidentally sets off [src], breaking their fingers."), \
- span_warning("You accidentally trigger [src]!"))
- return
+ if(clumsy_check(user))
+ return
return ..()
@@ -164,6 +221,15 @@
triggered(null)
+/obj/item/assembly/mousetrap/Destroy()
+ if(host)
+ UnregisterSignal(host,COMSIG_MOVABLE_MOVED)
+ host = null
+ if(isturf(host_turf))
+ UnregisterSignal(host_turf,COMSIG_ATOM_ENTERED)
+ host_turf = null
+ return ..()
+
/obj/item/assembly/mousetrap/armed
icon_state = "mousetraparmed"
armed = TRUE
diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm
index c1c4cecaffd..210cc4ec0e3 100644
--- a/code/modules/assembly/proximity.dm
+++ b/code/modules/assembly/proximity.dm
@@ -37,12 +37,35 @@
update_appearance()
return TRUE
+/obj/item/assembly/prox_sensor/dropped()
+ . = ..()
+ // Pick the first valid object in this list:
+ // Wiring datum's owner
+ // assembly holder's attached object
+ // assembly holder itself
+ // us
+ proximity_monitor.set_host(connected?.holder || holder?.master || holder || src, src)
+
+/obj/item/assembly/prox_sensor/on_attach()
+ . = ..()
+ // Pick the first valid object in this list:
+ // Wiring datum's owner
+ // assembly holder's attached object
+ // assembly holder itself
+ // us
+ proximity_monitor.set_host(connected?.holder || holder?.master || holder || src, src)
+
/obj/item/assembly/prox_sensor/on_detach()
. = ..()
if(!.)
return
else
- proximity_monitor.set_host(src, src)
+ // Pick the first valid object in this list:
+ // Wiring datum's owner
+ // assembly holder's attached object
+ // assembly holder itself
+ // us
+ proximity_monitor.set_host(connected?.holder || holder?.master || holder || src, src)
/obj/item/assembly/prox_sensor/toggle_secure()
secured = !secured
diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm
index d2312056c2e..d47c6f8fb88 100644
--- a/code/modules/assembly/timer.dm
+++ b/code/modules/assembly/timer.dm
@@ -54,12 +54,11 @@
return secured
/obj/item/assembly/timer/proc/timer_end()
- if(!secured || next_activate > world.time)
- return FALSE
- pulse(FALSE)
- audible_message("[icon2html(src, hearers(src))] *beep* *beep* *beep*", null, hearing_range)
- for(var/mob/hearing_mob in get_hearers_in_view(hearing_range, src))
- hearing_mob.playsound_local(get_turf(src), 'sound/machines/triple_beep.ogg', ASSEMBLY_BEEP_VOLUME, TRUE)
+ if(secured && next_activate <= world.time)
+ pulse(FALSE)
+ audible_message(span_infoplain("[icon2html(src, hearers(src))] *beep* *beep* *beep*"), null, hearing_range)
+ for(var/mob/hearing_mob in get_hearers_in_view(hearing_range, src))
+ hearing_mob.playsound_local(get_turf(src), 'sound/machines/triple_beep.ogg', ASSEMBLY_BEEP_VOLUME, TRUE)
if(loop)
timing = TRUE
update_appearance()
diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm
index 623e6783504..a22c18aaf86 100644
--- a/code/modules/reagents/reagent_dispenser.dm
+++ b/code/modules/reagents/reagent_dispenser.dm
@@ -7,20 +7,44 @@
anchored = FALSE
pressure_resistance = 2*ONE_ATMOSPHERE
max_integrity = 300
- ///In units, how much the dispenser can hold
+ /// In units, how much the dispenser can hold
var/tank_volume = 1000
- ///The ID of the reagent that the dispenser uses
+ /// The ID of the reagent that the dispenser uses
var/reagent_id = /datum/reagent/water
- ///Can you turn this into a plumbing tank?
+ /// Can you turn this into a plumbing tank?
var/can_be_tanked = TRUE
- ///Is this source self-replenishing?
+ /// Is this source self-replenishing?
var/refilling = FALSE
- ///Can this dispenser be opened using a wrench?
+ /// Can this dispenser be opened using a wrench?
var/openable = FALSE
- ///Is this dispenser slowly leaking its reagent?
+ /// Is this dispenser slowly leaking its reagent?
var/leaking = FALSE
- ///How much reagent to leak
+ /// How much reagent to leak
var/amount_to_leak = 10
+ /// An assembly attached to the tank - if this dispenser accepts_rig
+ var/obj/item/assembly_holder/rig = null
+ /// Whether this dispenser can be rigged with an assembly (and blown up with an igniter)
+ var/accepts_rig = FALSE
+ //overlay of attached assemblies
+ var/mutable_appearance/assembliesoverlay
+ /// The person who attached an assembly to this dispenser, for bomb logging purposes
+ var/last_rigger = ""
+
+// This check is necessary for assemblies to automatically detect that we are compatible
+/obj/structure/reagent_dispensers/IsSpecialAssembly()
+ return accepts_rig
+
+/obj/structure/reagent_dispensers/Destroy()
+ QDEL_NULL(rig)
+ return ..()
+
+/**
+ * rig_boom: Wrapper to log when a reagent_dispenser is set off by an assembly
+ *
+ */
+/obj/structure/reagent_dispensers/proc/rig_boom()
+ log_bomber(last_rigger, "rigged [src] exploded", src)
+ boom()
/obj/structure/reagent_dispensers/Initialize(mapload)
. = ..()
@@ -37,6 +61,12 @@
. += span_notice("Its tap looks like it could be wrenched open.")
else
. += span_warning("Its tap is wrenched open!")
+ if(accepts_rig && get_dist(user, src) <= 2)
+ if(rig)
+ . += span_warning("There is some kind of device rigged to the tank!")
+ else
+ . += span_notice("It looks like you could rig a device to the tank.")
+
/obj/structure/reagent_dispensers/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
. = ..()
@@ -47,6 +77,30 @@
/obj/structure/reagent_dispensers/attackby(obj/item/W, mob/user, params)
if(W.is_refillable())
return FALSE //so we can refill them via their afterattack.
+ if(istype(W, /obj/item/assembly_holder) && accepts_rig)
+ if(rig)
+ user.balloon_alert("another device is in the way!")
+ return ..()
+ var/obj/item/assembly_holder/holder = W
+ if(!(locate(/obj/item/assembly/igniter) in holder.assemblies))
+ return ..()
+
+ user.balloon_alert_to_viewers("attaching rig...")
+ add_fingerprint(user)
+ if(!do_after(user, 2 SECONDS, target = src) || !user.transferItemToLoc(holder, src))
+ return
+ rig = holder
+ holder.master = src
+ holder.on_attach()
+ assembliesoverlay = holder
+ assembliesoverlay.pixel_x += 6
+ assembliesoverlay.pixel_y += 1
+ add_overlay(assembliesoverlay)
+ RegisterSignal(src, COMSIG_IGNITER_ACTIVATE, .proc/rig_boom)
+ log_bomber(user, "attached [holder.name] to ", src)
+ last_rigger = user
+ user.balloon_alert_to_viewers("attached rig")
+ return
if(istype(W, /obj/item/stack/sheet/iron) && can_be_tanked)
var/obj/item/stack/sheet/iron/metal_stack = W
@@ -62,15 +116,75 @@
return ..()
+/obj/structure/reagent_dispensers/Exited(atom/movable/gone, direction)
+ . = ..()
+ if(gone == rig)
+ rig = null
+
+/obj/structure/reagent_dispensers/attack_hand(mob/user, list/modifiers)
+ . = ..()
+ if(. || !rig)
+ return
+ // mousetrap rigs only make sense if you can set them off, can't step on them
+ // If you see a mousetrap-rigged fuel tank, just leave it alone
+ rig.on_found()
+ if(QDELETED(src))
+ return
+ user.balloon_alert_to_viewers("detaching rig...")
+ if(!do_after(user, 2 SECONDS, target = src))
+ return
+ user.balloon_alert_to_viewers("detached rig")
+ user.log_message("detached [rig] from [src].", LOG_GAME)
+ if(!user.put_in_hands(rig))
+ rig.forceMove(get_turf(user))
+ rig = null
+ last_rigger = null
+ cut_overlays(assembliesoverlay)
+ UnregisterSignal(src, COMSIG_IGNITER_ACTIVATE)
+
/obj/structure/reagent_dispensers/Initialize(mapload)
create_reagents(tank_volume, DRAINABLE | AMOUNT_VISIBLE)
if(reagent_id)
reagents.add_reagent(reagent_id, tank_volume)
. = ..()
+/**
+ * boom: Detonate a reagent dispenser.
+ *
+ * This is most dangerous for fuel tanks, which will explosion().
+ * Other dispensers will scatter their contents within range.
+ */
/obj/structure/reagent_dispensers/proc/boom()
- visible_message(span_danger("\The [src] ruptures!"))
- chem_splash(loc, null, 5, list(reagents))
+ var/datum/reagent/fuel/volatiles = reagents.has_reagent(/datum/reagent/fuel)
+ var/fuel_amt = 0
+ if(istype(volatiles) && volatiles.volume >= 25)
+ fuel_amt = volatiles.volume
+ reagents.del_reagent(/datum/reagent/fuel) // not actually used for the explosion
+ if(reagents.total_volume)
+ if(!fuel_amt)
+ visible_message(span_danger("\The [src] ruptures!"))
+ // Leave it up to future terrorists to figure out the best way to mix reagents with fuel for a useful boom here
+ chem_splash(loc, null, 2 + (reagents.total_volume + fuel_amt) / 1000, list(reagents), extra_heat=(fuel_amt / 50),adminlog=(fuel_amt<25))
+
+ if(fuel_amt) // with that done, actually explode
+ visible_message(span_danger("\The [src] explodes!"))
+ // old code for reference:
+ // standard fuel tank = 1000 units = heavy_impact_range = 1, light_impact_range = 5, flame_range = 5
+ // big fuel tank = 5000 units = devastation_range = 1, heavy_impact_range = 2, light_impact_range = 7, flame_range = 12
+ // It did not account for how much fuel was actually in the tank at all, just the size of the tank.
+ // I encourage others to better scale these numbers in the future.
+ // As it stands this is a minor nerf in exchange for an easy bombing technique working that has been broken for a while.
+ switch(volatiles.volume)
+ if(25 to 150)
+ explosion(src, light_impact_range = 1, flame_range = 2)
+ if(150 to 300)
+ explosion(src, light_impact_range = 2, flame_range = 3)
+ if(300 to 750)
+ explosion(src, heavy_impact_range = 1, light_impact_range = 3, flame_range = 5)
+ if(750 to 1500)
+ explosion(src, heavy_impact_range = 1, light_impact_range = 4, flame_range = 6)
+ if(1500 to INFINITY)
+ explosion(src, devastation_range = 1, heavy_impact_range = 2, light_impact_range = 6, flame_range = 8)
qdel(src)
/obj/structure/reagent_dispensers/deconstruct(disassembled = TRUE)
@@ -127,14 +241,7 @@
icon_state = "fuel"
reagent_id = /datum/reagent/fuel
openable = TRUE
- //an assembly attached to the tank
- var/obj/item/assembly_holder/rig = null
- //whether it accepts assemblies or not
- var/accepts_rig = TRUE
- //overlay of attached assemblies
- var/mutable_appearance/assembliesoverlay
- /// The last person to rig this fuel tank - Stored with the object. Only the last person matters for investigation
- var/last_rigger = ""
+ accepts_rig = TRUE
/obj/structure/reagent_dispensers/fueltank/Initialize(mapload)
. = ..()
@@ -142,49 +249,6 @@
if(SSevents.holidays?[APRIL_FOOLS])
icon_state = "fuel_fools"
-/obj/structure/reagent_dispensers/fueltank/Destroy()
- QDEL_NULL(rig)
- return ..()
-
-/obj/structure/reagent_dispensers/fueltank/Exited(atom/movable/gone, direction)
- . = ..()
- if(gone == rig)
- rig = null
-
-/obj/structure/reagent_dispensers/fueltank/examine(mob/user)
- . = ..()
- if(get_dist(user, src) <= 2)
- if(rig)
- . += span_warning("There is some kind of device rigged to the tank!")
- else
- . += span_notice("It looks like you could rig a device to the tank.")
-
-/obj/structure/reagent_dispensers/fueltank/attack_hand(mob/user, list/modifiers)
- . = ..()
- if(.)
- return
- if(!rig)
- return
- user.balloon_alert_to_viewers("detaching rig...")
- if(!do_after(user, 2 SECONDS, target = src))
- return
- user.balloon_alert_to_viewers("detached rig")
- user.log_message("detached [rig] from [src].", LOG_GAME)
- if(!user.put_in_hands(rig))
- rig.forceMove(get_turf(user))
- rig = null
- last_rigger = null
- cut_overlays(assembliesoverlay)
- UnregisterSignal(src, COMSIG_IGNITER_ACTIVATE)
-
-/obj/structure/reagent_dispensers/fueltank/boom()
- explosion(src, heavy_impact_range = 1, light_impact_range = 5, flame_range = 5)
- qdel(src)
-
-/obj/structure/reagent_dispensers/fueltank/proc/rig_boom()
- log_bomber(last_rigger, "rigged fuel tank exploded", src)
- boom()
-
/obj/structure/reagent_dispensers/fueltank/blob_act(obj/structure/blob/B)
boom()
@@ -225,27 +289,7 @@
log_bomber(user, "detonated a", src, "via welding tool")
boom()
return
- if(istype(I, /obj/item/assembly_holder) && accepts_rig)
- if(rig)
- user.balloon_alert("another device is in the way!")
- return ..()
- user.balloon_alert_to_viewers("attaching rig...")
- if(!do_after(user, 2 SECONDS, target = src))
- return
- user.balloon_alert_to_viewers("attached rig")
- var/obj/item/assembly_holder/holder = I
- if(locate(/obj/item/assembly/igniter) in holder.assemblies)
- rig = holder
- if(!user.transferItemToLoc(holder, src))
- return
- log_bomber(user, "rigged [name] with [holder.name] for explosion", src)
- last_rigger = user
- assembliesoverlay = holder
- assembliesoverlay.pixel_x += 6
- assembliesoverlay.pixel_y += 1
- add_overlay(assembliesoverlay)
- RegisterSignal(src, COMSIG_IGNITER_ACTIVATE, .proc/rig_boom)
- return
+
return ..()
/obj/structure/reagent_dispensers/fueltank/large
@@ -254,10 +298,6 @@
icon_state = "fuel_high"
tank_volume = 5000
-/obj/structure/reagent_dispensers/fueltank/large/boom()
- explosion(src, devastation_range = 1, heavy_impact_range = 2, light_impact_range = 7, flame_range = 12)
- qdel(src)
-
/// Wall mounted dispeners, like pepper spray or virus food. Not a normal tank, and shouldn't be able to be turned into a plumbed stationary one.
/obj/structure/reagent_dispensers/wall
anchored = TRUE
@@ -388,3 +428,4 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/reagent_dispensers/wall/virusfood, 30
icon_state = "fuel_stationary"
desc = "A stationary, plumbed, fuel tank."
reagent_id = /datum/reagent/fuel
+ accepts_rig = TRUE