mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-10 17:52:36 +00:00
changes how grenades with custom primer are made (#44258)
* assemblies are shit fuck em * maybe press commit before making a pr * proxy stuff * morestuff * qol stuff * only 1 wire * revert that garbage that made me conflict * changes * wires
This commit is contained in:
@@ -450,3 +450,8 @@ GLOBAL_LIST_INIT(pda_styles, list(MONO, VT, ORBITRON, SHARE))
|
||||
|
||||
#define VOMIT_TOXIC 1
|
||||
#define VOMIT_PURPLE 2
|
||||
|
||||
//chem grenades defines
|
||||
#define EMPTY 1
|
||||
#define WIRED 2
|
||||
#define READY 3
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
/datum/wires/explosive
|
||||
var/duds_number = 2
|
||||
|
||||
/datum/wires/explosive/New(atom/holder)
|
||||
add_duds(2) // In this case duds actually explode.
|
||||
add_duds(duds_number) // In this case duds actually explode.
|
||||
..()
|
||||
|
||||
/datum/wires/explosive/on_pulse(index)
|
||||
@@ -11,6 +14,45 @@
|
||||
/datum/wires/explosive/proc/explode()
|
||||
return
|
||||
|
||||
/datum/wires/explosive/chem_grenade
|
||||
duds_number = 1
|
||||
holder_type = /obj/item/grenade/chem_grenade
|
||||
randomize = TRUE
|
||||
var/fingerprint
|
||||
|
||||
/datum/wires/explosive/chem_grenade/interactable(mob/user)
|
||||
var/obj/item/grenade/chem_grenade/G = holder
|
||||
if(G.stage == WIRED)
|
||||
return TRUE
|
||||
|
||||
/datum/wires/explosive/chem_grenade/attach_assembly(color, obj/item/assembly/S)
|
||||
if(istype(S,/obj/item/assembly/timer))
|
||||
var/obj/item/grenade/chem_grenade/G = holder
|
||||
var/obj/item/assembly/timer/T = S
|
||||
G.det_time = T.saved_time*10
|
||||
else if(istype(S,/obj/item/assembly/prox_sensor))
|
||||
var/obj/item/grenade/chem_grenade/G = holder
|
||||
G.landminemode = S
|
||||
S.proximity_monitor.wire = TRUE
|
||||
fingerprint = S.fingerprintslast
|
||||
return ..()
|
||||
|
||||
/datum/wires/explosive/chem_grenade/explode()
|
||||
var/obj/item/grenade/chem_grenade/G = holder
|
||||
var/obj/item/assembly/assembly = get_attached(get_wire(1))
|
||||
message_admins("\An [assembly] has pulsed a grenade, which was installed by [fingerprint].")
|
||||
log_game("\An [assembly] has pulsed a grenade, which was installed by [fingerprint].")
|
||||
G.prime()
|
||||
|
||||
/datum/wires/explosive/chem_grenade/detach_assembly(color)
|
||||
var/obj/item/assembly/S = get_attached(color)
|
||||
if(S && istype(S))
|
||||
assemblies -= color
|
||||
S.connected = null
|
||||
S.forceMove(holder.drop_location())
|
||||
var/obj/item/grenade/chem_grenade/G = holder
|
||||
G.landminemode = null
|
||||
return S
|
||||
|
||||
/datum/wires/explosive/c4
|
||||
holder_type = /obj/item/grenade/plastic/c4
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
var/list/checkers //list of /obj/effect/abstract/proximity_checkers
|
||||
var/current_range
|
||||
var/ignore_if_not_on_turf //don't check turfs in range if the host's loc isn't a turf
|
||||
var/wire = FALSE
|
||||
|
||||
/datum/proximity_monitor/New(atom/_host, range, _ignore_if_not_on_turf = TRUE)
|
||||
checkers = list()
|
||||
@@ -58,6 +59,8 @@
|
||||
var/atom/_host = host
|
||||
|
||||
var/atom/loc_to_use = ignore_if_not_on_turf ? _host.loc : get_turf(_host)
|
||||
if(wire && !isturf(loc_to_use)) //it makes assemblies attached on wires work
|
||||
loc_to_use = get_turf(loc_to_use)
|
||||
if(!isturf(loc_to_use)) //only check the host's loc
|
||||
if(range)
|
||||
var/obj/effect/abstract/proximity_checker/pc
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
#define EMPTY 1
|
||||
#define WIRED 2
|
||||
#define READY 3
|
||||
|
||||
/obj/item/grenade/chem_grenade
|
||||
name = "chemical grenade"
|
||||
desc = "A custom made grenade."
|
||||
@@ -14,20 +10,24 @@
|
||||
var/list/allowed_containers = list(/obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/glass/bottle)
|
||||
var/list/banned_containers = list(/obj/item/reagent_containers/glass/beaker/bluespace) //Containers to exclude from specific grenade subtypes
|
||||
var/affected_area = 3
|
||||
var/obj/item/assembly_holder/nadeassembly = null
|
||||
var/assemblyattacher
|
||||
var/ignition_temp = 10 // The amount of heat added to the reagents when this grenade goes off.
|
||||
var/threatscale = 1 // Used by advanced grenades to make them slightly more worthy.
|
||||
var/no_splash = FALSE //If the grenade deletes even if it has no reagents to splash with. Used for slime core reactions.
|
||||
var/casedesc = "This basic model accepts both beakers and bottles. It heats contents by 10°K upon ignition." // Appears when examining empty casings.
|
||||
var/obj/item/assembly/prox_sensor/landminemode = null
|
||||
|
||||
/obj/item/grenade/chem_grenade/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/empprotection, EMP_PROTECT_WIRES)
|
||||
|
||||
/obj/item/grenade/chem_grenade/Initialize()
|
||||
. = ..()
|
||||
create_reagents(1000)
|
||||
stage_change() // If no argument is set, it will change the stage to the current stage, useful for stock grenades that start READY.
|
||||
wires = new /datum/wires/explosive/chem_grenade(src)
|
||||
|
||||
/obj/item/grenade/chem_grenade/examine(mob/user)
|
||||
display_timer = (stage == READY && !nadeassembly) //show/hide the timer based on assembly state
|
||||
display_timer = (stage == READY) //show/hide the timer based on assembly state
|
||||
..()
|
||||
if(user.can_see_reagents())
|
||||
if(beakers.len)
|
||||
@@ -48,21 +48,11 @@
|
||||
|
||||
/obj/item/grenade/chem_grenade/attack_self(mob/user)
|
||||
if(stage == READY && !active)
|
||||
if(nadeassembly)
|
||||
nadeassembly.attack_self(user)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/grenade/chem_grenade/attackby(obj/item/I, mob/user, params)
|
||||
if(I.tool_behaviour == TOOL_MULTITOOL)
|
||||
if(stage == READY && !nadeassembly && !active)
|
||||
var/newtime = text2num(stripped_input(user, "Please enter a new detonation time", name))
|
||||
if (newtime != null && user.canUseTopic(src, BE_CLOSE))
|
||||
change_det_time(newtime)
|
||||
to_chat(user, "<span class='notice'>You modify the time delay. It's set for [DisplayTimeText(det_time)].</span>")
|
||||
if (round(newtime * 10) != det_time)
|
||||
to_chat(user, "<span class='warning'>The new value is out of bounds. The lowest possible time is 3 seconds and highest is 5 seconds. Instant detonations are also possible.</span>")
|
||||
return
|
||||
if((istype(I,/obj/item/assembly) || I.tool_behaviour == TOOL_MULTITOOL) && stage == WIRED)
|
||||
wires.interact(user)
|
||||
if(I.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
if(stage == WIRED)
|
||||
if(beakers.len)
|
||||
@@ -71,11 +61,14 @@
|
||||
I.play_tool_sound(src, 25)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to add at least one beaker before locking the [initial(name)] assembly!</span>")
|
||||
else if(stage == READY && !nadeassembly && !active)
|
||||
change_det_time()
|
||||
else if(stage == READY)
|
||||
det_time = det_time == 50 ? 30 : 50 //toggle between 30 and 50
|
||||
if(landminemode)
|
||||
landminemode.time = det_time * 0.1 //overwrites the proxy sensor activation timer
|
||||
|
||||
to_chat(user, "<span class='notice'>You modify the time delay. It's set for [DisplayTimeText(det_time)].</span>")
|
||||
else if(stage == EMPTY)
|
||||
to_chat(user, "<span class='warning'>You need to add an activation mechanism!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to add a wire!</span>")
|
||||
return
|
||||
else if(stage == WIRED && is_type_in_list(I, allowed_containers))
|
||||
. = TRUE //no afterattack
|
||||
@@ -96,21 +89,6 @@
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[I] is empty!</span>")
|
||||
|
||||
else if(stage == EMPTY && istype(I, /obj/item/assembly_holder))
|
||||
. = 1 // no afterattack
|
||||
var/obj/item/assembly_holder/A = I
|
||||
if(isigniter(A.a_left) == isigniter(A.a_right)) //Check if either part of the assembly has an igniter, but if both parts are igniters, then fuck it
|
||||
return
|
||||
if(!user.transferItemToLoc(I, src))
|
||||
return
|
||||
|
||||
nadeassembly = A
|
||||
A.master = src
|
||||
assemblyattacher = user.ckey
|
||||
|
||||
stage_change(WIRED)
|
||||
to_chat(user, "<span class='notice'>You add [A] to the [initial(name)] assembly.</span>")
|
||||
|
||||
else if(stage == EMPTY && istype(I, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/C = I
|
||||
if (C.use(1))
|
||||
@@ -135,12 +113,7 @@
|
||||
user.log_message("removed [O] ([reagent_list]) from [src]", LOG_GAME)
|
||||
beakers = list()
|
||||
to_chat(user, "<span class='notice'>You open the [initial(name)] assembly and remove the payload.</span>")
|
||||
return // First use of the wrench remove beakers, then use the wrench to remove the activation mechanism.
|
||||
if(nadeassembly)
|
||||
nadeassembly.forceMove(drop_location())
|
||||
nadeassembly.master = null
|
||||
nadeassembly = null
|
||||
else // If "nadeassembly = null && stage == WIRED", then it most have been cable_coil that was used.
|
||||
return
|
||||
new /obj/item/stack/cable_coil(get_turf(src),1)
|
||||
stage_change(EMPTY)
|
||||
to_chat(user, "<span class='notice'>You remove the activation mechanism from the [initial(name)] assembly.</span>")
|
||||
@@ -163,20 +136,6 @@
|
||||
desc = initial(desc)
|
||||
icon_state = "[initial(icon_state)]_locked"
|
||||
|
||||
|
||||
//assembly stuff
|
||||
/obj/item/grenade/chem_grenade/receive_signal()
|
||||
prime()
|
||||
|
||||
|
||||
/obj/item/grenade/chem_grenade/Crossed(atom/movable/AM)
|
||||
if(nadeassembly)
|
||||
nadeassembly.Crossed(AM)
|
||||
|
||||
/obj/item/grenade/chem_grenade/on_found(mob/finder)
|
||||
if(nadeassembly)
|
||||
nadeassembly.on_found(finder)
|
||||
|
||||
/obj/item/grenade/chem_grenade/log_grenade(mob/user, turf/T)
|
||||
var/reagent_string = ""
|
||||
var/beaker_number = 1
|
||||
@@ -184,8 +143,29 @@
|
||||
if(!exploded_beaker.reagents)
|
||||
continue
|
||||
reagent_string += " ([exploded_beaker.name] [beaker_number++] : " + pretty_string_from_reagent_list(exploded_beaker.reagents.reagent_list) + ");"
|
||||
if(landminemode)
|
||||
log_bomber(user, "activated a proxy", src, "containing:[reagent_string]")
|
||||
else
|
||||
log_bomber(user, "primed a", src, "containing:[reagent_string]")
|
||||
|
||||
/obj/item/grenade/chem_grenade/preprime(mob/user, delayoverride, msg = TRUE, volume = 60)
|
||||
var/turf/T = get_turf(src)
|
||||
log_grenade(user, T) //Inbuilt admin procs already handle null users
|
||||
if(user)
|
||||
add_fingerprint(user)
|
||||
if(msg)
|
||||
if(landminemode)
|
||||
to_chat(user, "<span class='warning'>You prime [src], activating its proximity sensor.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You prime [src]! [DisplayTimeText(det_time)]!</span>")
|
||||
playsound(src, 'sound/weapons/armbomb.ogg', volume, 1)
|
||||
icon_state = initial(icon_state) + "_active"
|
||||
if(landminemode)
|
||||
landminemode.activate()
|
||||
return
|
||||
active = TRUE
|
||||
addtimer(CALLBACK(src, .proc/prime), isnull(delayoverride)? det_time : delayoverride)
|
||||
|
||||
/obj/item/grenade/chem_grenade/prime()
|
||||
if(stage != READY)
|
||||
return
|
||||
@@ -205,13 +185,7 @@
|
||||
stage_change(EMPTY)
|
||||
active = FALSE
|
||||
return
|
||||
|
||||
if(nadeassembly)
|
||||
var/mob/M = get_mob_by_ckey(assemblyattacher)
|
||||
var/mob/last = get_mob_by_ckey(nadeassembly.fingerprintslast)
|
||||
message_admins("grenade primed by an assembly, attached by [ADMIN_LOOKUPFLW(M)] and last touched by [ADMIN_LOOKUPFLW(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [ADMIN_VERBOSEJMP(detonation_turf)]</a>.")
|
||||
log_game("grenade primed by an assembly, attached by [key_name(M)] and last touched by [key_name(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [AREACOORD(detonation_turf)]")
|
||||
|
||||
// logs from custom assemblies priming are handled by the wire component
|
||||
log_game("A grenade detonated at [AREACOORD(detonation_turf)]")
|
||||
|
||||
update_mob()
|
||||
@@ -306,7 +280,6 @@
|
||||
total_volume += RC.reagents.total_volume
|
||||
if(!total_volume)
|
||||
qdel(src)
|
||||
qdel(nadeassembly)
|
||||
return
|
||||
var/fraction = unit_spread/total_volume
|
||||
var/datum/reagents/reactants = new(unit_spread)
|
||||
@@ -316,19 +289,12 @@
|
||||
chem_splash(get_turf(src), affected_area, list(reactants), ignition_temp, threatscale)
|
||||
|
||||
var/turf/DT = get_turf(src)
|
||||
if(nadeassembly)
|
||||
var/mob/M = get_mob_by_ckey(assemblyattacher)
|
||||
var/mob/last = get_mob_by_ckey(nadeassembly.fingerprintslast)
|
||||
message_admins("grenade primed by an assembly at [AREACOORD(DT)], attached by [ADMIN_LOOKUPFLW(M)] and last touched by [ADMIN_LOOKUPFLW(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name])</a>.")
|
||||
log_game("grenade primed by an assembly at [AREACOORD(DT)], attached by [key_name(M)] and last touched by [key_name(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name])")
|
||||
else
|
||||
addtimer(CALLBACK(src, .proc/prime), det_time)
|
||||
log_game("A grenade detonated at [AREACOORD(DT)]")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
////// PREMADE GRENADES //////
|
||||
//////////////////////////////
|
||||
@@ -607,7 +573,3 @@
|
||||
|
||||
beakers += B1
|
||||
beakers += B2
|
||||
|
||||
#undef READY
|
||||
#undef WIRED
|
||||
#undef EMPTY
|
||||
|
||||
@@ -107,10 +107,6 @@
|
||||
if(stuffed || grenade)
|
||||
to_chat(user, "<span class='notice'>You pet [src]. D'awww.</span>")
|
||||
if(grenade && !grenade.active)
|
||||
if(istype(grenade, /obj/item/grenade/chem_grenade))
|
||||
var/obj/item/grenade/chem_grenade/G = grenade
|
||||
if(G.nadeassembly) //We're activated through different methods
|
||||
return
|
||||
log_game("[key_name(user)] activated a hidden grenade in [src].")
|
||||
grenade.preprime(user, msg = FALSE, volume = 10)
|
||||
else
|
||||
|
||||
@@ -34,25 +34,6 @@
|
||||
var/det_time = text2num(grenadedata["grenade-timer"])
|
||||
if (det_time)
|
||||
grenade.det_time = det_time
|
||||
if ("voice")
|
||||
var/voice_mode = text2num(grenadedata["grenade-voice-mode"])
|
||||
var/recording = grenadedata["grenade-voice-recording"]
|
||||
if (voice_mode && recording)
|
||||
var/obj/item/assembly/voice/voice_analyzer = new
|
||||
voice_analyzer.mode = voice_mode
|
||||
voice_analyzer.recorded = recording
|
||||
voice_analyzer.secured = FALSE // needs to be unsecured because assembly holder assembly toggles it
|
||||
grenade.nadeassembly = beaker_panel_prep_assembly(voice_analyzer, grenade)
|
||||
if ("signaler")
|
||||
var/frq = format_frequency(grenadedata["grenade-signaler-frq"])
|
||||
var/code = text2num(grenadedata["grenade-signaler-code"])
|
||||
if (frq && code)
|
||||
var/obj/item/assembly/signaler/signaler = new
|
||||
signaler.code = code
|
||||
signaler.frequency = frq
|
||||
signaler.secured = FALSE
|
||||
grenade.nadeassembly = beaker_panel_prep_assembly(signaler, grenade)
|
||||
|
||||
log_game("[key_name(usr)] spawned a [grenade] containing: [reagent_string]")
|
||||
|
||||
/datum/admins/proc/beaker_panel_prep_assembly(obj/item/assembly/towrap, grenade)
|
||||
@@ -284,29 +265,8 @@
|
||||
<label for="grenade-type">Grenade type: </label>
|
||||
<select id="grenade-type">
|
||||
<option value="normal">Normal</option>
|
||||
<option value="voice">Voice analyzer</option>
|
||||
<option value="signaler">Signaler</option>
|
||||
</select>
|
||||
<div class="grenade-data normal">
|
||||
<label for="grenade-timer">Timer: </label>
|
||||
<input id="grenade-timer" name="grenade-timer" value="30" />
|
||||
</div>
|
||||
<div class="grenade-data voice" style="display: none;">
|
||||
<label for="grenade-voice-mode">Mode</label>
|
||||
<select id="grenade-voice-mode" name="grenade-voice-mode">
|
||||
<option value="1">Inclusive</option>
|
||||
<option value="2">Exclusive</option>
|
||||
<option value="3">Recognizer</option>
|
||||
<option value="4">Voice sensor</option>
|
||||
</select>
|
||||
<label for="grenade-voice-recording">Name or phrase: </label>
|
||||
<input id="grenade-voice-recording" name="grenade-voice-recording" />
|
||||
</div>
|
||||
<div class="grenade-data signaler" style="display: none;">
|
||||
<label for="grenade-signaler-frq">Frequency: </label>
|
||||
<input id="grenade-signaler-frq" name="grenade-signaler-frq" />
|
||||
<label for="grenade-signaler-code">Code: </label>
|
||||
<input id="grenade-signaler-code" name="grenade-signaler-code" />
|
||||
</div>
|
||||
<br />
|
||||
<small>note: beakers recommended, other containers may have issues</small>
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
icon_state = "health"
|
||||
materials = list(MAT_METAL=800, MAT_GLASS=200)
|
||||
attachable = TRUE
|
||||
secured = FALSE
|
||||
|
||||
var/scanning = FALSE
|
||||
var/health_scan
|
||||
@@ -46,7 +45,6 @@
|
||||
var/atom/A = src
|
||||
if(connected && connected.holder)
|
||||
A = connected.holder
|
||||
|
||||
for(A, A && !ismob(A), A=A.loc);
|
||||
// like get_turf(), but for mobs.
|
||||
var/mob/living/M = A
|
||||
|
||||
Reference in New Issue
Block a user