mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-09 16:05:07 +00:00
Cleans up chem grenade code, fixes prox sensors not working in grenades (#89891)
## About The Pull Request Closes #89886 Closes #89887 Closes #89888 ## Changelog 🆑 fix: You can no longer insert infinite amounts of slime cores into advanced chem grenades fix: Non-beaker containers in grenades work once more fix: Proximity sensors in grenade finally work after like, 4 years. code: Cleaned up chemical grenade code /🆑
This commit is contained in:
@@ -42,23 +42,30 @@
|
||||
return
|
||||
. = ..()
|
||||
|
||||
/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/assembly/prox_sensor/sensor = S
|
||||
var/obj/item/grenade/chem_grenade/grenade = holder
|
||||
/datum/wires/explosive/chem_grenade/attach_assembly(color, obj/item/assembly/assembly)
|
||||
fingerprint = assembly.fingerprintslast
|
||||
var/obj/item/grenade/chem_grenade/grenade = holder
|
||||
if(!assembly.secured)
|
||||
assembly.toggle_secure()
|
||||
|
||||
if(istype(assembly, /obj/item/assembly/timer))
|
||||
var/obj/item/assembly/timer/timer = assembly
|
||||
grenade.det_time = timer.saved_time SECONDS
|
||||
return ..()
|
||||
|
||||
if(istype(assembly, /obj/item/assembly/prox_sensor))
|
||||
var/obj/item/assembly/prox_sensor/sensor = assembly
|
||||
grenade.landminemode = sensor
|
||||
sensor.proximity_monitor.set_ignore_if_not_on_turf(FALSE)
|
||||
else if(istype(S,/obj/item/assembly/health))
|
||||
var/obj/item/assembly/health/sensor = S
|
||||
if(!sensor.secured)
|
||||
sensor.toggle_secure()
|
||||
if(!sensor.scanning)
|
||||
sensor.toggle_scan()
|
||||
fingerprint = S.fingerprintslast
|
||||
sensor.time = grenade.det_time * 0.1
|
||||
return ..()
|
||||
|
||||
if(!istype(assembly, /obj/item/assembly/health))
|
||||
return ..()
|
||||
|
||||
var/obj/item/assembly/health/sensor = assembly
|
||||
if(!sensor.scanning)
|
||||
sensor.toggle_scan()
|
||||
return ..()
|
||||
|
||||
/datum/wires/explosive/chem_grenade/explode()
|
||||
@@ -71,8 +78,7 @@
|
||||
if(!grenade.dud_flags)
|
||||
message_admins(message)
|
||||
log_game(message)
|
||||
var/mob/M = get_mob_by_ckey(fingerprint)
|
||||
grenade.log_grenade(M) //Used in arm_grenade() too but this one conveys where the mob who triggered the bomb is
|
||||
grenade.log_grenade(get_mob_by_ckey(fingerprint)) //Used in arm_grenade() too but this one conveys where the mob who triggered the bomb is
|
||||
if(grenade.landminemode)
|
||||
grenade.detonate() ///already armed
|
||||
else
|
||||
@@ -80,22 +86,24 @@
|
||||
|
||||
|
||||
/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.holder = null
|
||||
S.forceMove(holder.drop_location())
|
||||
var/obj/item/grenade/chem_grenade/G = holder
|
||||
G.landminemode = null
|
||||
return S
|
||||
var/obj/item/assembly/assembly = get_attached(color)
|
||||
if(!istype(assembly))
|
||||
return
|
||||
|
||||
var/obj/item/grenade/chem_grenade/grenade = holder
|
||||
assemblies -= color
|
||||
assembly.connected = null
|
||||
assembly.holder = null
|
||||
assembly.forceMove(holder.drop_location())
|
||||
grenade.landminemode = null
|
||||
return assembly
|
||||
|
||||
/datum/wires/explosive/c4 // Also includes X4
|
||||
holder_type = /obj/item/grenade/c4
|
||||
|
||||
/datum/wires/explosive/c4/explode()
|
||||
var/obj/item/grenade/c4/P = holder
|
||||
P.detonate()
|
||||
var/obj/item/grenade/c4/bomb = holder
|
||||
bomb.detonate()
|
||||
|
||||
/datum/wires/explosive/pizza
|
||||
holder_type = /obj/item/pizzabox
|
||||
@@ -110,37 +118,38 @@
|
||||
/datum/wires/explosive/pizza/interactable(mob/user)
|
||||
if(!..())
|
||||
return FALSE
|
||||
var/obj/item/pizzabox/P = holder
|
||||
if(P.open && P.bomb)
|
||||
var/obj/item/pizzabox/pizza_bomb = holder
|
||||
if(pizza_bomb.open && pizza_bomb.bomb)
|
||||
return TRUE
|
||||
|
||||
/datum/wires/explosive/pizza/get_status()
|
||||
var/obj/item/pizzabox/P = holder
|
||||
var/obj/item/pizzabox/pizza_bomb = holder
|
||||
var/list/status = list()
|
||||
status += "The red light is [P.bomb_active ? "on" : "off"]."
|
||||
status += "The green light is [P.bomb_defused ? "on": "off"]."
|
||||
status += "The red light is [pizza_bomb.bomb_active ? "on" : "off"]."
|
||||
status += "The green light is [pizza_bomb.bomb_defused ? "on": "off"]."
|
||||
return status
|
||||
|
||||
/datum/wires/explosive/pizza/on_pulse(wire)
|
||||
var/obj/item/pizzabox/P = holder
|
||||
switch(wire)
|
||||
if(WIRE_DISARM) // Pulse to toggle
|
||||
P.bomb_defused = !P.bomb_defused
|
||||
else // Boom
|
||||
explode()
|
||||
var/obj/item/pizzabox/pizza_bomb = holder
|
||||
if(wire == WIRE_DISARM) // Pulse to toggle
|
||||
pizza_bomb.bomb_defused = !pizza_bomb.bomb_defused
|
||||
else // Boom
|
||||
explode()
|
||||
|
||||
/datum/wires/explosive/pizza/on_cut(wire, mend, source)
|
||||
var/obj/item/pizzabox/P = holder
|
||||
switch(wire)
|
||||
if(WIRE_DISARM) // Disarm and untrap the box.
|
||||
if(!mend)
|
||||
P.bomb_defused = TRUE
|
||||
else
|
||||
if(!mend && !P.bomb_defused)
|
||||
if (!isnull(source))
|
||||
log_combat(source, holder, "cut the detonation wire for")
|
||||
explode()
|
||||
if (mend)
|
||||
return
|
||||
|
||||
var/obj/item/pizzabox/pizza_bomb = holder
|
||||
if(wire == WIRE_DISARM) // Disarm and untrap the box.
|
||||
pizza_bomb.bomb_defused = TRUE
|
||||
return
|
||||
|
||||
if(!pizza_bomb.bomb_defused)
|
||||
if (!isnull(source))
|
||||
log_combat(source, holder, "cut the detonation wire for")
|
||||
explode()
|
||||
|
||||
/datum/wires/explosive/pizza/explode()
|
||||
var/obj/item/pizzabox/P = holder
|
||||
P.bomb.detonate()
|
||||
var/obj/item/pizzabox/pizza_bomb = holder
|
||||
pizza_bomb.bomb.detonate()
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
/// Which stage of construction this grenade is currently at.
|
||||
var/stage = GRENADE_EMPTY
|
||||
/// The set of reagent containers that have been added to this grenade casing.
|
||||
var/list/obj/item/reagent_containers/cup/beakers = list()
|
||||
var/list/obj/item/beakers = list()
|
||||
/// The types of reagent containers that can be added to this grenade casing.
|
||||
var/list/allowed_containers = list(/obj/item/reagent_containers/cup/beaker, /obj/item/reagent_containers/cup/bottle)
|
||||
/// The types of reagent containers that can't be added to this grenade casing.
|
||||
@@ -24,15 +24,15 @@
|
||||
var/threatscale = 1
|
||||
/// The description when examining empty casings.
|
||||
var/casedesc = "This basic model accepts both beakers and bottles. It heats contents by 10 K upon ignition."
|
||||
/// Whether or not the grenade is currently acting as a landmine. Currently broken and not my current project.
|
||||
/// Whether or not the grenade is currently acting as a landmine.
|
||||
var/obj/item/assembly/prox_sensor/landminemode = null
|
||||
|
||||
/obj/item/grenade/chem_grenade/Initialize(mapload)
|
||||
. = ..()
|
||||
AddElement(/datum/element/empprotection, EMP_PROTECT_WIRES)
|
||||
create_reagents(casing_holder_volume)
|
||||
stage_change() // If no argument is set, it will change the stage to the current stage, useful for stock grenades that start READY.
|
||||
set_wires(new /datum/wires/explosive/chem_grenade(src))
|
||||
update_appearance()
|
||||
|
||||
/obj/item/grenade/chem_grenade/Destroy(force)
|
||||
QDEL_NULL(landminemode)
|
||||
@@ -48,162 +48,186 @@
|
||||
/obj/item/grenade/chem_grenade/examine(mob/user)
|
||||
display_timer = (stage == GRENADE_READY) //show/hide the timer based on assembly state
|
||||
. = ..()
|
||||
if(user.can_see_reagents())
|
||||
if(beakers.len)
|
||||
. += span_notice("You scan the grenade and detect the following reagents:")
|
||||
for(var/obj/item/reagent_containers/cup/glass_beaker in beakers)
|
||||
for(var/datum/reagent/reagent in glass_beaker.reagents.reagent_list)
|
||||
. += span_notice("[reagent.volume] units of [reagent.name] in \the [glass_beaker].")
|
||||
if(beakers.len == 1)
|
||||
. += span_notice("You detect no second beaker in the grenade.")
|
||||
else
|
||||
. += span_notice("You scan the grenade, but detect nothing.")
|
||||
else if(stage != GRENADE_READY && beakers.len)
|
||||
if(beakers.len == 2 && beakers[1].name == beakers[2].name)
|
||||
if (!user.can_see_reagents())
|
||||
if (stage == GRENADE_READY || !(length(beakers)))
|
||||
return
|
||||
if (length(beakers) == 2 && beakers[1].name == beakers[2].name)
|
||||
. += span_notice("You see two [beakers[1].name]s inside the grenade.")
|
||||
else
|
||||
for(var/obj/item/reagent_containers/cup/glass_beaker in beakers)
|
||||
. += span_notice("You see a [glass_beaker.name] inside the grenade.")
|
||||
return
|
||||
|
||||
for (var/obj/item/beaker as anything in beakers)
|
||||
. += span_notice("You see a [beaker.name] inside the grenade.")
|
||||
|
||||
if (!length(beakers))
|
||||
. += span_notice("You scan the grenade, but detect nothing.")
|
||||
return
|
||||
|
||||
. += span_notice("You scan the grenade and detect the following reagents:")
|
||||
|
||||
for (var/obj/item/beaker as anything in beakers)
|
||||
for (var/datum/reagent/reagent in beaker.reagents.reagent_list)
|
||||
. += span_notice("[reagent.volume] units of [reagent.name] in \the [beaker].")
|
||||
|
||||
if (length(beakers) == 1)
|
||||
. += span_notice("You detect no second beaker in the grenade.")
|
||||
|
||||
/obj/item/grenade/chem_grenade/update_name(updates)
|
||||
switch(stage)
|
||||
if(GRENADE_EMPTY)
|
||||
switch (stage)
|
||||
if (GRENADE_EMPTY)
|
||||
name = "[initial(name)] casing"
|
||||
if(GRENADE_WIRED)
|
||||
if (GRENADE_WIRED)
|
||||
name = "unsecured [initial(name)]"
|
||||
if(GRENADE_READY)
|
||||
if (GRENADE_READY)
|
||||
name = initial(name)
|
||||
return ..()
|
||||
|
||||
/obj/item/grenade/chem_grenade/update_desc(updates)
|
||||
switch(stage)
|
||||
if(GRENADE_EMPTY)
|
||||
switch (stage)
|
||||
if (GRENADE_EMPTY)
|
||||
desc = "A do it yourself [initial(name)]! [initial(casedesc)]"
|
||||
if(GRENADE_WIRED)
|
||||
if (GRENADE_WIRED)
|
||||
desc = "An unsecured [initial(name)] assembly."
|
||||
if(GRENADE_READY)
|
||||
if (GRENADE_READY)
|
||||
desc = initial(desc)
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/grenade/chem_grenade/update_icon_state()
|
||||
if(active)
|
||||
if (active)
|
||||
icon_state = "[base_icon_state]_active"
|
||||
return ..()
|
||||
|
||||
switch(stage)
|
||||
if(GRENADE_EMPTY)
|
||||
switch (stage)
|
||||
if (GRENADE_EMPTY)
|
||||
icon_state = base_icon_state
|
||||
if(GRENADE_WIRED)
|
||||
if (GRENADE_WIRED)
|
||||
icon_state = "[base_icon_state]_ass"
|
||||
if(GRENADE_READY)
|
||||
if (GRENADE_READY)
|
||||
icon_state = "[base_icon_state]_locked"
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/grenade/chem_grenade/attack_self(mob/user)
|
||||
if(stage == GRENADE_READY && !active)
|
||||
..()
|
||||
if(stage == GRENADE_WIRED)
|
||||
if (stage == GRENADE_READY && !active)
|
||||
return ..()
|
||||
|
||||
if (stage == GRENADE_WIRED)
|
||||
wires.interact(user)
|
||||
|
||||
/obj/item/grenade/chem_grenade/screwdriver_act(mob/living/user, obj/item/tool)
|
||||
. = TRUE
|
||||
if(dud_flags & GRENADE_USED)
|
||||
if (dud_flags & GRENADE_USED)
|
||||
balloon_alert(user, "resetting trigger...")
|
||||
if (do_after(user, 2 SECONDS, src))
|
||||
balloon_alert(user, "trigger reset")
|
||||
dud_flags &= ~GRENADE_USED
|
||||
return
|
||||
if (!do_after(user, 2 SECONDS, src))
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
|
||||
if(stage == GRENADE_WIRED)
|
||||
if(beakers.len)
|
||||
balloon_alert(user, "trigger reset")
|
||||
dud_flags &= ~GRENADE_USED
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
if (stage == GRENADE_WIRED)
|
||||
if (length(beakers))
|
||||
stage_change(GRENADE_READY)
|
||||
to_chat(user, span_notice("You lock the [initial(name)] assembly."))
|
||||
tool.play_tool_sound(src, 25)
|
||||
else if(landminemode)
|
||||
landminemode.timing = FALSE
|
||||
if(!landminemode.secured)
|
||||
landminemode.toggle_secure()
|
||||
landminemode.toggle_scan(FALSE)
|
||||
to_chat(user, span_notice("You disarm \the [landminemode]."))
|
||||
tool.play_tool_sound(src, 25)
|
||||
else
|
||||
to_chat(user, span_warning("You need to add at least one beaker before locking the [initial(name)] assembly!"))
|
||||
else if(stage == GRENADE_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
|
||||
tool.play_tool_sound(src, 25)
|
||||
to_chat(user, span_notice("You modify the time delay. It's set for [DisplayTimeText(det_time)]."))
|
||||
else
|
||||
to_chat(user, span_warning("You need to add a wire!"))
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
if (!landminemode || !(landminemode.scanning || landminemode.timing))
|
||||
to_chat(user, span_warning("You need to add at least one beaker before locking the [initial(name)] assembly!"))
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
|
||||
landminemode.timing = FALSE
|
||||
landminemode.toggle_scan(FALSE)
|
||||
to_chat(user, span_notice("You disarm \the [landminemode]."))
|
||||
tool.play_tool_sound(src, 25)
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
if (stage != GRENADE_READY)
|
||||
to_chat(user, span_warning("You need to add a wire!"))
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
|
||||
det_time = det_time == 5 SECONDS ? 3 SECONDS : 5 SECONDS
|
||||
if (landminemode)
|
||||
landminemode.time = det_time * 0.1 //overwrites the proxy sensor activation timer
|
||||
|
||||
tool.play_tool_sound(src, 25)
|
||||
to_chat(user, span_notice("You modify the time delay. It's set for [DisplayTimeText(det_time)]."))
|
||||
return TRUE
|
||||
|
||||
/obj/item/grenade/chem_grenade/wirecutter_act(mob/living/user, obj/item/tool)
|
||||
if(stage == GRENADE_READY && !active)
|
||||
tool.play_tool_sound(src)
|
||||
stage_change(GRENADE_WIRED)
|
||||
to_chat(user, span_notice("You unlock the [initial(name)] assembly."))
|
||||
return TRUE
|
||||
if (stage != GRENADE_READY || active)
|
||||
return NONE
|
||||
|
||||
tool.play_tool_sound(src)
|
||||
stage_change(GRENADE_WIRED)
|
||||
to_chat(user, span_notice("You unlock the [initial(name)] assembly."))
|
||||
return TRUE
|
||||
|
||||
/obj/item/grenade/chem_grenade/wrench_act(mob/living/user, obj/item/tool)
|
||||
if(stage != GRENADE_WIRED)
|
||||
return FALSE
|
||||
if(beakers.len)
|
||||
for(var/obj/beaker in beakers)
|
||||
beaker.forceMove(drop_location())
|
||||
if(!beaker.reagents)
|
||||
continue
|
||||
var/reagent_list = pretty_string_from_reagent_list(beaker.reagents.reagent_list)
|
||||
user.log_message("removed [beaker] ([reagent_list]) from [src]", LOG_GAME)
|
||||
beakers = list()
|
||||
to_chat(user, span_notice("You open the [initial(name)] assembly and remove the payload."))
|
||||
return
|
||||
tool.play_tool_sound(src)
|
||||
wires.detach_assembly(wires.get_wire(1))
|
||||
new /obj/item/stack/cable_coil(get_turf(src), 1)
|
||||
stage_change(GRENADE_EMPTY)
|
||||
to_chat(user, span_notice("You remove the activation mechanism from the [initial(name)] assembly."))
|
||||
if (stage != GRENADE_WIRED)
|
||||
return NONE
|
||||
|
||||
/obj/item/grenade/chem_grenade/attackby(obj/item/item, mob/user, params)
|
||||
if(isassembly(item) && stage == GRENADE_WIRED)
|
||||
if (!length(beakers))
|
||||
tool.play_tool_sound(src)
|
||||
wires.detach_assembly(wires.get_wire(1))
|
||||
new /obj/item/stack/cable_coil(get_turf(src), 1)
|
||||
stage_change(GRENADE_EMPTY)
|
||||
to_chat(user, span_notice("You remove the activation mechanism from the [initial(name)] assembly."))
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
to_chat(user, span_notice("You open the [initial(name)] assembly and remove the payload."))
|
||||
for(var/obj/item/beaker as anything in beakers)
|
||||
beaker.forceMove(drop_location())
|
||||
if(!beaker.reagents)
|
||||
continue
|
||||
var/reagent_list = pretty_string_from_reagent_list(beaker.reagents.reagent_list)
|
||||
user.log_message("removed [beaker] ([reagent_list]) from [src]", LOG_GAME)
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
/obj/item/grenade/chem_grenade/item_interaction(mob/living/user, obj/item/item, list/modifiers)
|
||||
if (isassembly(item) && stage == GRENADE_WIRED)
|
||||
wires.interact(user)
|
||||
else if(stage == GRENADE_WIRED && is_type_in_list(item, allowed_containers))
|
||||
. = TRUE //no afterattack
|
||||
if(is_type_in_list(item, banned_containers))
|
||||
to_chat(user, span_warning("[src] is too small to fit [item]!")) // this one hits home huh anon?
|
||||
return
|
||||
if(beakers.len == 2)
|
||||
to_chat(user, span_warning("[src] can not hold more containers!"))
|
||||
return
|
||||
else
|
||||
if(item.reagents.total_volume)
|
||||
if(!user.transferItemToLoc(item, src))
|
||||
return
|
||||
to_chat(user, span_notice("You add [item] to the [initial(name)] assembly."))
|
||||
beakers += item
|
||||
var/reagent_list = pretty_string_from_reagent_list(item.reagents.reagent_list)
|
||||
user.log_message("inserted [item] ([reagent_list]) into [src]", LOG_GAME)
|
||||
else
|
||||
to_chat(user, span_warning("[item] is empty!"))
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
else if(stage == GRENADE_EMPTY && istype(item, /obj/item/stack/cable_coil))
|
||||
if (stage == GRENADE_EMPTY && istype(item, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/coil = item
|
||||
if (coil.use(1))
|
||||
det_time = 50 // In case the cable_coil was removed and readded.
|
||||
stage_change(GRENADE_WIRED)
|
||||
to_chat(user, span_notice("You rig the [initial(name)] assembly."))
|
||||
else
|
||||
if (!coil.use(1))
|
||||
to_chat(user, span_warning("You need one length of coil to wire the assembly!"))
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
|
||||
/obj/item/grenade/chem_grenade/proc/stage_change(N)
|
||||
if(N)
|
||||
stage = N
|
||||
det_time = 5 SECONDS // In case the cable_coil was removed and readded.
|
||||
stage_change(GRENADE_WIRED)
|
||||
to_chat(user, span_notice("You rig the [initial(name)] assembly."))
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
if (stage != GRENADE_WIRED)
|
||||
return NONE
|
||||
|
||||
if (!is_type_in_list(item, allowed_containers))
|
||||
return NONE
|
||||
|
||||
if(is_type_in_list(item, banned_containers))
|
||||
to_chat(user, span_warning("[src] is too small to fit [item]!")) // this one hits home huh anon?
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
|
||||
if (length(beakers) == 2)
|
||||
to_chat(user, span_warning("[src] can not hold more containers!"))
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
|
||||
if(!user.transferItemToLoc(item, src))
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
|
||||
to_chat(user, span_notice("You add [item] to the [initial(name)] assembly."))
|
||||
beakers += item
|
||||
var/reagent_list = pretty_string_from_reagent_list(item.reagents.reagent_list)
|
||||
user.log_message("inserted [item] ([reagent_list]) into [src]", LOG_GAME)
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
/obj/item/grenade/chem_grenade/Exited(atom/movable/gone, direction)
|
||||
. = ..()
|
||||
beakers -= gone
|
||||
|
||||
/obj/item/grenade/chem_grenade/proc/stage_change(new_stage)
|
||||
stage = new_stage
|
||||
update_appearance()
|
||||
|
||||
/obj/item/grenade/chem_grenade/on_found(mob/finder)
|
||||
@@ -213,10 +237,10 @@
|
||||
/obj/item/grenade/chem_grenade/log_grenade(mob/user)
|
||||
var/reagent_string = ""
|
||||
var/beaker_number = 1
|
||||
for(var/obj/exploded_beaker in beakers)
|
||||
if(!exploded_beaker.reagents)
|
||||
continue
|
||||
reagent_string += " ([exploded_beaker.name] [beaker_number++] : " + pretty_string_from_reagent_list(exploded_beaker.reagents.reagent_list) + ");"
|
||||
for(var/obj/item/exploded_beaker as anything in beakers)
|
||||
if (exploded_beaker.reagents)
|
||||
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]", message_admins = !dud_flags)
|
||||
else
|
||||
@@ -224,10 +248,10 @@
|
||||
|
||||
/obj/item/grenade/chem_grenade/arm_grenade(mob/user, delayoverride, msg = TRUE, volume = 60)
|
||||
log_grenade(user) //Inbuilt admin procs already handle null users
|
||||
if(user)
|
||||
if (user)
|
||||
add_fingerprint(user)
|
||||
if(msg)
|
||||
if(landminemode)
|
||||
if (msg)
|
||||
if (landminemode)
|
||||
to_chat(user, span_warning("You prime [src], activating its proximity sensor."))
|
||||
else
|
||||
to_chat(user, span_warning("You prime [src]! [DisplayTimeText(det_time)]!"))
|
||||
@@ -235,10 +259,11 @@
|
||||
active = TRUE
|
||||
update_icon_state()
|
||||
playsound(src, grenade_arm_sound, volume, grenade_sound_vary)
|
||||
if(landminemode)
|
||||
if (landminemode)
|
||||
landminemode.toggle_scan(FALSE) // Ensures that if it was turned on before for some reason, it doesn't get turned off
|
||||
landminemode.activate()
|
||||
return
|
||||
addtimer(CALLBACK(src, PROC_REF(detonate)), isnull(delayoverride)? det_time : delayoverride)
|
||||
else
|
||||
addtimer(CALLBACK(src, PROC_REF(detonate)), isnull(delayoverride)? det_time : delayoverride)
|
||||
|
||||
/obj/item/grenade/chem_grenade/detonate(mob/living/lanced_by)
|
||||
if(stage != GRENADE_READY)
|
||||
@@ -249,8 +274,8 @@
|
||||
return
|
||||
|
||||
var/list/datum/reagents/reactants = list()
|
||||
for(var/obj/item/reagent_containers/cup/glass_beaker in beakers)
|
||||
reactants += glass_beaker.reagents
|
||||
for(var/obj/item/beaker as anything in beakers)
|
||||
reactants += beaker.reagents
|
||||
|
||||
var/turf/detonation_turf = get_turf(src)
|
||||
if (chem_splash(detonation_turf, reagents, affected_area, reactants, ignition_temp, threatscale))
|
||||
@@ -260,7 +285,6 @@
|
||||
active = FALSE
|
||||
update_appearance()
|
||||
|
||||
|
||||
//Large chem grenades accept slime cores and use the appropriately.
|
||||
/obj/item/grenade/chem_grenade/large
|
||||
name = "large grenade"
|
||||
@@ -268,7 +292,7 @@
|
||||
casedesc = "This casing affects a larger area than the basic model and can fit exotic containers, including slime cores and bluespace beakers. Heats contents by 25 K upon ignition."
|
||||
icon_state = "large_grenade"
|
||||
base_icon_state = "large_grenade"
|
||||
allowed_containers = list(/obj/item/reagent_containers/cup, /obj/item/reagent_containers/condiment, /obj/item/reagent_containers/cup/glass)
|
||||
allowed_containers = list(/obj/item/reagent_containers/cup, /obj/item/reagent_containers/condiment, /obj/item/reagent_containers/cup/glass, /obj/item/slime_extract)
|
||||
banned_containers = list()
|
||||
affected_area = 5
|
||||
ignition_temp = 25 // Large grenades are slightly more effective at setting off heat-sensitive mixtures than smaller grenades.
|
||||
@@ -280,7 +304,6 @@
|
||||
update_appearance()
|
||||
return FALSE
|
||||
|
||||
|
||||
var/extract_total_volume = 0
|
||||
var/extract_maximum_volume = 0
|
||||
var/list/extracts = list()
|
||||
@@ -292,18 +315,18 @@
|
||||
if(!thing.reagents)
|
||||
continue
|
||||
|
||||
if(istype(thing, /obj/item/slime_extract))
|
||||
var/obj/item/slime_extract/extract = thing
|
||||
if(!extract.extract_uses)
|
||||
continue
|
||||
|
||||
extract_total_volume += extract.reagents.total_volume
|
||||
extract_maximum_volume += extract.reagents.maximum_volume
|
||||
extracts += extract
|
||||
else
|
||||
if(!istype(thing, /obj/item/slime_extract))
|
||||
beaker_total_volume += thing.reagents.total_volume
|
||||
other_containers += thing
|
||||
continue
|
||||
|
||||
var/obj/item/slime_extract/extract = thing
|
||||
if(!extract.extract_uses)
|
||||
continue
|
||||
|
||||
extract_total_volume += extract.reagents.total_volume
|
||||
extract_maximum_volume += extract.reagents.maximum_volume
|
||||
extracts += extract
|
||||
|
||||
var/available_extract_volume = extract_maximum_volume - extract_total_volume
|
||||
if(beaker_total_volume <= 0 || available_extract_volume <= 0)
|
||||
@@ -325,18 +348,6 @@
|
||||
|
||||
return ..()
|
||||
|
||||
//I tried to just put it in the allowed_containers list but
|
||||
//if you do that it must have reagents. If you're going to
|
||||
//make a special case you might as well do it explicitly. -Sayu
|
||||
/obj/item/grenade/chem_grenade/large/attackby(obj/item/item, mob/user, params)
|
||||
if(!istype(item, /obj/item/slime_extract) || stage != GRENADE_WIRED)
|
||||
return ..()
|
||||
|
||||
if(!user.transferItemToLoc(item, src))
|
||||
return
|
||||
to_chat(user, span_notice("You add [item] to the [initial(name)] assembly."))
|
||||
beakers += item
|
||||
|
||||
/obj/item/grenade/chem_grenade/cryo // Intended for rare cryogenic mixes. Cools the area moderately upon detonation.
|
||||
name = "cryo grenade"
|
||||
desc = "A custom made cryogenic grenade. Rapidly cools contents upon ignition."
|
||||
@@ -364,13 +375,15 @@
|
||||
|
||||
/obj/item/grenade/chem_grenade/adv_release/multitool_act(mob/living/user, obj/item/tool)
|
||||
if (active)
|
||||
return
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
|
||||
var/newspread = tgui_input_number(user, "Please enter a new spread amount", "Grenade Spread", 5, 100, 5)
|
||||
if(!newspread || QDELETED(user) || QDELETED(src) || !usr.can_perform_action(src, FORBID_TELEKINESIS_REACH))
|
||||
return
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
|
||||
unit_spread = newspread
|
||||
to_chat(user, span_notice("You set the time release to [unit_spread] units per detonation."))
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/item/grenade/chem_grenade/adv_release/detonate(mob/living/lanced_by)
|
||||
if(stage != GRENADE_READY || dud_flags)
|
||||
@@ -381,10 +394,12 @@
|
||||
var/total_volume = 0
|
||||
for(var/obj/item/reagent_containers/reagent_container in beakers)
|
||||
total_volume += reagent_container.reagents.total_volume
|
||||
|
||||
if(!total_volume)
|
||||
active = FALSE
|
||||
update_appearance()
|
||||
return
|
||||
|
||||
var/fraction = unit_spread/total_volume
|
||||
var/datum/reagents/reactants = new(unit_spread)
|
||||
reactants.my_atom = src
|
||||
@@ -395,18 +410,13 @@
|
||||
threatscale,
|
||||
no_react = TRUE
|
||||
)
|
||||
chem_splash(get_turf(src), reagents, affected_area, list(reactants), ignition_temp, threatscale)
|
||||
|
||||
var/turf/detonated_turf = get_turf(src)
|
||||
chem_splash(detonated_turf, reagents, affected_area, list(reactants), ignition_temp, threatscale)
|
||||
addtimer(CALLBACK(src, PROC_REF(detonate)), det_time)
|
||||
log_game("A grenade detonated at [AREACOORD(detonated_turf)]")
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
////// PREMADE GRENADES //////
|
||||
//////////////////////////////
|
||||
// Premade grenades
|
||||
|
||||
/obj/item/grenade/chem_grenade/metalfoam
|
||||
name = "metal foam grenade"
|
||||
|
||||
Reference in New Issue
Block a user