mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-06-22 06:35:12 +01:00
dbadf01a35
## About The Pull Request This PR sort-of brings back old IEDs, albeit much more freeform compared to their previous iteration. Using #94861's ``spark_act`` interactions they can now be made by filling up a soda can with a variety of chemicals (welding fuel being the easiest to obtain), dunking in a piece of wire, taping it up (optional, required if using welding fuel or plasma) and lighting it on fire with a lighter or welding tool (anything that's hot enough works, really) They have a random delay of 2-4 seconds, and can be disarmed by snipping the fuse with wirecutters in time before they detonate (or don't, depending on the mixture) There's also a new, more "professional" improvised chemical explosive in the form of beakerbombs. These can be assembled by putting a lid on a beaker (alt-click, prevents the beaker from spilling its contents when thrown) and attaching an assembly with an igniter or a condenser to it. <img width="150" height="90" alt="dreamseeker_2OKpZeN7ay" src="https://github.com/user-attachments/assets/599e75ea-9653-4db9-a915-b2ca6307635f" /> When triggered, igniters will heat the reagents up by a bit while condensers will cool them down. However, you can also attach and wire up a power cell, which will cause it to dump all of its power into the beaker when the igniter fires off, triggering ``spark_act`` interactions potentially causing a larger explosion. <img width="534" height="447" alt="dreamseeker_k9Uzf18Eoa" src="https://github.com/user-attachments/assets/4cfed5b4-3875-4522-9bfa-5f6a3c8e0864" /> Decently sized boom from The Contraption. Plasma and welding fuel's potency inside of beakerbombs/soda cans is significantly reduced compared to other riggable objects (strengthdiv is 3 times higher) as they're very easy to obtain and would make for very powerful explosives, considering their very strong strengthdiv as most rigging interactions use very little fuel/plasma to cause a large explosion, which was carried over to the new system. (Don't worry, this still leaves them at sensible values with welding fuel being about as strong as old IEDs on average) Closes #94990 via having plasma's electrical power modifier have a decline past a certain point based on its volume ## Why It's Good For The Game #81529 didn't justify IED removal whatsoever and I think with new mechanics these can be used as easier (but weaker) to make improvised bombs, being much less clunky to make and use than pipebombs. Beakerbombs are essentially a somewhat weaker (even with metamat beakers, you're still 20u short of a normal large beaker grenade at 200u) form of grenades, but have access to new interactions involving charged up explosions, which could make for some variety among chemists' weaponry. ## Changelog 🆑 add: Added back IEDs made by attaching some wire and tape to a soda can filled with fuel, plasma, or any other explosive of your choice. They need to be lit on fire with a lighter or a welding tool. add: You can now attach a lid to beakers with alt-click, preventing them from being spilled when thrown. add: Added beakerbombs, made by attaching an assembly (with optional power cell and wiring) to a lidded beaker. balance: Rigged explosions now create flames. balance: Plasma explosions now limit their explosion potency past a certain point based on their volume /🆑
184 lines
5.7 KiB
Plaintext
184 lines
5.7 KiB
Plaintext
/obj/item/assembly_holder
|
|
name = "Assembly"
|
|
icon = 'icons/obj/devices/new_assemblies.dmi'
|
|
icon_state = "assembly_holder"
|
|
inhand_icon_state = "assembly"
|
|
lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi'
|
|
righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi'
|
|
obj_flags = CONDUCTS_ELECTRICITY
|
|
throwforce = 5
|
|
w_class = WEIGHT_CLASS_SMALL
|
|
throw_speed = 2
|
|
throw_range = 7
|
|
/// used to store the list of assemblies making up our assembly holder
|
|
var/list/obj/item/assembly/assemblies
|
|
|
|
/obj/item/assembly_holder/Initialize(mapload)
|
|
. = ..()
|
|
AddElement(/datum/element/simple_rotation)
|
|
|
|
/obj/item/assembly_holder/Destroy()
|
|
QDEL_LAZYLIST(assemblies)
|
|
return ..()
|
|
|
|
/obj/item/assembly_holder/Exited(atom/movable/gone, direction)
|
|
. = ..()
|
|
LAZYREMOVE(assemblies, gone)
|
|
|
|
/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)
|
|
name = "[A.name]-[A2.name] assembly"
|
|
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()
|
|
|
|
/obj/item/assembly_holder/proc/try_add_assembly(obj/item/assembly/attached_assembly, mob/user)
|
|
if(attached_assembly.secured)
|
|
balloon_alert(user, "not attachable!")
|
|
return FALSE
|
|
|
|
if(LAZYLEN(assemblies) >= HOLDER_MAX_ASSEMBLIES)
|
|
balloon_alert(user, "too many assemblies!")
|
|
return FALSE
|
|
|
|
if(attached_assembly.assembly_flags & ASSEMBLY_NO_DUPLICATES)
|
|
if(locate(attached_assembly.type) in assemblies)
|
|
balloon_alert(user, "can't attach another of that!")
|
|
return FALSE
|
|
|
|
add_assembly(attached_assembly, user)
|
|
balloon_alert(user, "part attached")
|
|
return TRUE
|
|
|
|
/**
|
|
* Adds an assembly to the assembly holder
|
|
*
|
|
* This proc is used to add an assembly to the assembly holder, update the appearance, and the name of it.
|
|
* Arguments:
|
|
* * attached_assembly - assembly we are adding to the assembly holder
|
|
* * user - user we pass into attach()
|
|
*/
|
|
/obj/item/assembly_holder/proc/add_assembly(obj/item/assembly/attached_assembly, mob/user)
|
|
attach(attached_assembly, user)
|
|
name = ""
|
|
for(var/obj/item/assembly/assembly as anything in assemblies)
|
|
name += "[assembly.name]-"
|
|
name = splicetext(name, length(name), length(name) + 1, "")
|
|
name += " assembly"
|
|
update_appearance()
|
|
|
|
/obj/item/assembly_holder/proc/attach(obj/item/assembly/A, mob/user)
|
|
if(!A.remove_item_from_storage(src, user))
|
|
if(user)
|
|
user.transferItemToLoc(A, src)
|
|
else
|
|
A.forceMove(src)
|
|
A.holder = src
|
|
A.toggle_secure()
|
|
LAZYADD(assemblies, A)
|
|
A.holder_movement()
|
|
A.on_attach()
|
|
|
|
/obj/item/assembly_holder/update_appearance(updates=ALL)
|
|
. = ..()
|
|
master?.update_appearance(updates)
|
|
|
|
/obj/item/assembly_holder/update_overlays()
|
|
. = ..()
|
|
for(var/i in 1 to LAZYLEN(assemblies))
|
|
if(IS_LEFT_INDEX(i))
|
|
var/obj/item/assembly/assembly = assemblies[i]
|
|
. += mutable_appearance(assembly.icon, "[assembly.icon_state]_left")
|
|
for(var/left_overlay in assembly.attached_overlays)
|
|
. += "[left_overlay]_l"
|
|
if(IS_RIGHT_INDEX(i))
|
|
var/obj/item/assembly/assembly = assemblies[i]
|
|
var/mutable_appearance/right = mutable_appearance(assembly.icon, "[assembly.icon_state]_left")
|
|
right.transform = matrix(-1, 0, 0, 0, 1, 0)
|
|
for(var/right_overlay in assembly.attached_overlays)
|
|
right.add_overlay("[right_overlay]_l")
|
|
. += right
|
|
|
|
/obj/item/assembly_holder/on_found(mob/finder)
|
|
for(var/obj/item/assembly/assembly as anything in assemblies)
|
|
assembly.on_found(finder)
|
|
|
|
/obj/item/assembly_holder/setDir()
|
|
. = ..()
|
|
for(var/obj/item/assembly/assembly as anything in assemblies)
|
|
assembly.holder_movement()
|
|
|
|
/obj/item/assembly_holder/dropped(mob/user)
|
|
. = ..()
|
|
for(var/obj/item/assembly/assembly as anything in assemblies)
|
|
assembly.dropped(user)
|
|
|
|
/obj/item/assembly_holder/attack_hand(mob/living/user, list/modifiers)//Perhapse this should be a holder_pickup proc instead, can add if needbe I guess
|
|
. = ..()
|
|
if(.)
|
|
return
|
|
for(var/obj/item/assembly/assembly as anything in assemblies)
|
|
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, list/modifiers, list/attack_modifiers)
|
|
if(isassembly(weapon))
|
|
try_add_assembly(weapon, user)
|
|
return
|
|
|
|
return ..()
|
|
|
|
|
|
/obj/item/assembly_holder/screwdriver_act(mob/user, obj/item/tool)
|
|
loc.balloon_alert(user, "disassembled")
|
|
|
|
deconstruct(TRUE)
|
|
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
/obj/item/assembly_holder/atom_deconstruct(disassembled)
|
|
for(var/obj/item/assembly/assembly as anything in assemblies)
|
|
assembly.on_detach()
|
|
LAZYREMOVE(assemblies, assembly)
|
|
|
|
/obj/item/assembly_holder/attack_self(mob/user)
|
|
src.add_fingerprint(user)
|
|
if(LAZYLEN(assemblies) == 1)
|
|
balloon_alert(user, "part missing!")
|
|
return
|
|
|
|
for(var/obj/item/assembly/assembly as anything in assemblies)
|
|
assembly.attack_self(user)
|
|
|
|
/**
|
|
* this proc is used to process the activation of the assembly holder
|
|
*
|
|
* This proc is usually called by signalers, timers, or anything that can trigger and
|
|
* send a pulse to the assembly holder, which then calls this proc that actually activates the assemblies
|
|
* Arguments:
|
|
* * /obj/device - the device we sent the pulse from which called this proc
|
|
*/
|
|
/obj/item/assembly_holder/proc/process_activation(obj/device)
|
|
if(!device)
|
|
return FALSE
|
|
if(LAZYLEN(assemblies) >= 2)
|
|
for(var/obj/item/assembly/assembly as anything in assemblies)
|
|
if(assembly != device)
|
|
assembly.pulsed()
|
|
if(master)
|
|
master.receive_signal()
|
|
return TRUE
|