[MIRROR] Flamethrower TGUI + Tweaks (#10479)

Co-authored-by: Cameron Lennox <killer65311@gmail.com>
Co-authored-by: Willburd <7099514+Willburd@users.noreply.github.com>
Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
CHOMPStation2StaffMirrorBot
2025-03-21 00:08:55 +01:00
committed by GitHub
co-authored by Cameron Lennox Willburd Kashargul
parent e7ed84355b
commit 98519f0f45
5 changed files with 211 additions and 118 deletions
+121 -98
View File
@@ -1,3 +1,6 @@
#define THROWER_MIN 50
#define THROWER_MAX 1000
/obj/item/flamethrower
name = "flamethrower"
desc = "You are a firestarter!"
@@ -15,15 +18,27 @@
w_class = ITEMSIZE_NORMAL
origin_tech = list(TECH_COMBAT = 1, TECH_PHORON = 1)
matter = list(MAT_STEEL = 500)
var/status = 0
var/throw_amount = 100
var/lit = 0 //on or off
var/operating = 0//cooldown
var/status = FALSE
var/throw_amount = THROWER_MIN
var/lit = FALSE //on or off
var/operating = FALSE //cooldown
var/turf/previousturf = null
var/obj/item/weldingtool/weldtool = null
var/obj/item/assembly/igniter/igniter = null
var/obj/item/tank/phoron/ptank = null
var/volume_per_max_burn = 20 // gets divided by the intended burn ratio
/obj/item/flamethrower/Initialize(mapload)
weldtool = new /obj/item/weldingtool(src)
weldtool.status = 0 // for disassembly
update_icon()
. = ..()
/obj/item/flamethrower/full/Initialize(mapload)
igniter = new /obj/item/assembly/igniter(src)
igniter.secured = 0 // for disassembly
. = ..()
status = TRUE
/obj/item/flamethrower/Destroy()
QDEL_NULL(weldtool)
@@ -44,7 +59,6 @@
location.hotspot_expose(700, 2)
return
/obj/item/flamethrower/update_icon()
cut_overlays()
if(igniter)
@@ -59,26 +73,55 @@
return
/obj/item/flamethrower/afterattack(atom/target, mob/user, proximity)
if(!proximity) return
// Make sure our user is still holding us
if(!lit || operating)
return
if(user && user.get_active_hand() == src)
var/turf/target_turf = get_turf(target)
if(target_turf)
var/turflist = getline(user, target_turf)
flame_turf(turflist)
if(user.a_intent == I_HELP && user.client?.prefs?.read_preference(/datum/preference/toggle/safefiring))
to_chat(user, span_warning("You refrain from firing \the [src] as your intent is set to help."))
return
if(check_fuel())
// spawn projectile
var/obj/item/projectile/P = new /obj/item/projectile/bullet/dragon/flamethrower(get_turf(src))
P.submunition_spread_max = 90 + round(80*thrower_spew_percent())
P.submunition_spread_min = 5 + round(50*thrower_spew_percent())
P.submunitions = list(/obj/item/projectile/bullet/incendiary/dragonflame/flamethrower = 1 + round(thrower_spew_percent()*2))
P.launch_projectile( target, BP_TORSO, user)
// suck out fuel and burn it
var/datum/gas_mixture/used_gas = ptank.air_contents.remove_ratio(volume_per_max_burn * thrower_spew_percent() / ptank.air_contents.volume)
qdel(used_gas)
if(!check_fuel())
lit = FALSE
update_icon()
else
to_chat(user, span_notice("There is not enough pressure in [src]'s tank!"))
lit = FALSE
update_icon()
// prevent spam
operating = TRUE
addtimer(VARSET_CALLBACK(src, operating, FALSE), 15)
return
/obj/item/flamethrower/proc/thrower_spew_percent()
return throw_amount / THROWER_MAX
/obj/item/flamethrower/proc/check_fuel()
return ptank != null && ptank.air_contents.total_moles > 5 // minimum fuel usage is five moles, for EXTREMELY hot mix or super low pressure
/obj/item/flamethrower/attackby(obj/item/W as obj, mob/user as mob)
if(user.stat || user.restrained() || user.lying) return
if(user.stat || user.restrained() || user.lying)
return
if(W.has_tool_quality(TOOL_WRENCH) && !status)//Taking this apart
var/turf/T = get_turf(src)
if(weldtool)
weldtool.loc = T
weldtool.forceMove(T)
weldtool = null
if(igniter)
igniter.loc = T
igniter.forceMove(T)
igniter = null
if(ptank)
ptank.loc = T
ptank.forceMove(T)
ptank = null
new /obj/item/stack/rods(T)
qdel(src)
@@ -95,7 +138,7 @@
if(I.secured) return
if(igniter) return
user.drop_item()
I.loc = src
I.forceMove(src)
igniter = I
update_icon()
return
@@ -106,99 +149,79 @@
return
user.drop_item()
ptank = W
W.loc = src
W.forceMove(src)
update_icon()
return
..()
return
/obj/item/flamethrower/attack_self(mob/user as mob)
if(user.stat || user.restrained() || user.lying) return
user.set_machine(src)
if(!ptank)
to_chat(user, span_notice("Attach a phoron tank first!"))
if(user.stat || user.restrained() || user.lying)
return
var/dat = text("<htmk><TT><B>Flamethrower (<A href='byond://?src=\ref[src];light=1'>[lit ? "<font color='red'>Lit</font>" : "Unlit"]</a>)</B><BR>\n Tank Pressure: [ptank.air_contents.return_pressure()]<BR>\nAmount to throw: <A href='byond://?src=\ref[src];amount=-100'>-</A> <A href='byond://?src=\ref[src];amount=-10'>-</A> <A href='byond://?src=\ref[src];amount=-1'>-</A> [throw_amount] <A href='byond://?src=\ref[src];amount=1'>+</A> <A href='byond://?src=\ref[src];amount=10'>+</A> <A href='byond://?src=\ref[src];amount=100'>+</A><BR>\n<A href='byond://?src=\ref[src];remove=1'>Remove phorontank</A> - <A href='byond://?src=\ref[src];close=1'>Close</A></TT></html>")
user << browse(dat, "window=flamethrower;size=600x300")
onclose(user, "flamethrower")
return
tgui_interact(user)
/obj/item/flamethrower/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "Flamethrower", name)
ui.open()
/obj/item/flamethrower/Topic(href,href_list[])
if(href_list["close"])
usr.unset_machine()
usr << browse(null, "window=flamethrower")
return
if(usr.stat || usr.restrained() || usr.lying) return
usr.set_machine(src)
if(href_list["light"])
if(!ptank) return
if(ptank.air_contents.gas[GAS_PHORON] < 1) return
if(!status) return
lit = !lit
if(lit)
START_PROCESSING(SSobj, src)
if(href_list["amount"])
throw_amount = throw_amount + text2num(href_list["amount"])
throw_amount = max(50, min(5000, throw_amount))
if(href_list["remove"])
if(!ptank) return
usr.put_in_hands(ptank)
ptank = null
lit = 0
usr.unset_machine()
usr << browse(null, "window=flamethrower")
for(var/mob/M in viewers(1, loc))
if((M.client && M.machine == src))
attack_self(M)
update_icon()
return
/obj/item/flamethrower/tgui_data(mob/user)
var/list/dat = list()
dat["lit"] = lit
dat["constructed"] = status
dat["throw_amount"] = throw_amount
// Tank
dat["has_tank"] = !isnull(ptank)
dat["throw_min"] = THROWER_MIN
dat["throw_max"] = THROWER_MAX
dat["fuel_kpa"] = check_fuel() ? ptank.air_contents.return_pressure() : 0
return dat
/obj/item/flamethrower/tgui_act(action, params, datum/tgui/ui)
if(usr.stat || usr.restrained() || usr.lying)
return FALSE
if(..())
return FALSE
//Called from turf.dm turf/dblclick
/obj/item/flamethrower/proc/flame_turf(turflist)
if(!lit || operating) return
operating = 1
for(var/turf/T in turflist)
if(T.density || istype(T, /turf/space))
break
if(!previousturf && length(turflist)>1)
previousturf = get_turf(src)
continue //so we don't burn the tile we be standin on
if(previousturf && LinkBlocked(previousturf, T))
break
ignite_turf(T)
sleep(1)
previousturf = null
operating = 0
for(var/mob/M in viewers(1, loc))
if((M.client && M.machine == src))
attack_self(M)
return
switch(action)
if("light")
if(!check_fuel() || ptank.air_contents.gas[GAS_PHORON] < 1 || !status)
return FALSE
lit = !lit
if(lit)
START_PROCESSING(SSobj, src)
playsound(src, 'sound/items/welderactivate.ogg', 50, 1)
else
playsound(src, 'sound/items/welderdeactivate.ogg', 50, 1)
update_icon()
return TRUE
if("amount")
throw_amount = text2num(params["amount"])
throw_amount = clamp(throw_amount,THROWER_MIN,THROWER_MAX)
return TRUE
if("remove")
if(!ptank)
return FALSE
usr.put_in_hands(ptank)
ptank = null
lit = 0
update_icon()
return TRUE
// Projectile
/obj/item/projectile/bullet/dragon/flamethrower
name = "flames"
icon_state = "fireball2"
submunitions = list(/obj/item/projectile/bullet/incendiary/dragonflame/flamethrower = 2)
damage = 0
hitsound_wall = null
/obj/item/flamethrower/proc/ignite_turf(turf/target)
//TODO: DEFERRED Consider checking to make sure tank pressure is high enough before doing this...
//Transfer 5% of current tank air contents to turf
var/datum/gas_mixture/air_transfer = ptank.air_contents.remove_ratio(0.02*(throw_amount/100))
//air_transfer.toxins = air_transfer.toxins * 5 // This is me not comprehending the air system. I realize this is mischievious and I could probably make it work without fucking it up like this, but there you have it. -- TLE
new/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel(target,air_transfer.gas[GAS_PHORON],get_dir(loc,target))
air_transfer.gas[GAS_PHORON] = 0
target.assume_air(air_transfer)
//Burn it based on transfered gas
//target.hotspot_expose(part4.air_contents.temperature*2,300)
target.hotspot_expose((ptank.air_contents.temperature*2) + 380,500) // -- More of my "how do I shot fire?" dickery. -- TLE
//location.hotspot_expose(1000,500,1)
return
/obj/item/projectile/bullet/incendiary/dragonflame/flamethrower
name = "flames"
icon_state = "fireball2"
damage = 2
hitsound_wall = null
/obj/item/flamethrower/full/New(var/loc)
..()
weldtool = new /obj/item/weldingtool(src)
weldtool.status = 0
igniter = new /obj/item/assembly/igniter(src)
igniter.secured = 0
status = 1
update_icon()
return
#undef THROWER_MIN
#undef THROWER_MAX
@@ -85,11 +85,13 @@
if (istype(W, /obj/item/flamethrower))
var/obj/item/flamethrower/F = W
if ((!F.status)||(F.ptank)) return
src.master = F
if ((!F.status)||(F.ptank))
return
master = F
F.ptank = src
user.remove_from_mob(src)
src.loc = F
forceMove(F)
F.update_icon()
return
/obj/item/tank/vox //Can't be a child of phoron or the gas amount gets screwey.
@@ -111,32 +111,19 @@
to_chat(user, span_notice("You secure the welder."))
else
to_chat(user, span_notice("The welder can now be attached and modified."))
src.add_fingerprint(user)
add_fingerprint(user)
return
if((!status) && (istype(W,/obj/item/stack/rods)))
var/obj/item/stack/rods/R = W
R.use(1)
var/obj/item/flamethrower/F = new/obj/item/flamethrower(user.loc)
src.loc = F
var/obj/item/flamethrower/F = new/obj/item/flamethrower(get_turf(user))
user.drop_from_inventory(src,F)
F.weldtool = src
if (user.client)
user.client.screen -= src
if (user.r_hand == src)
user.remove_from_mob(src)
else
user.remove_from_mob(src)
src.master = F
src.layer = initial(src.layer)
user.remove_from_mob(src)
if (user.client)
user.client.screen -= src
src.loc = F
src.add_fingerprint(user)
add_fingerprint(user)
return
..()
return
/obj/item/weldingtool/process()
if(welding)