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:
Tlaltecuhtli
2019-06-11 18:28:35 +02:00
committed by moo
parent 7f5a4962a4
commit 4a247210fd
7 changed files with 95 additions and 129 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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>

View File

@@ -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