Skip to content
This repository was archived by the owner on May 22, 2025. It is now read-only.

Commit 59a2d13

Browse files
Flamethrower rework part 3: the pre-sequel (#21437)
* Update flamethrower.dm * runtimes * COLD FIRE!!!!!
1 parent 4aafdc1 commit 59a2d13

File tree

1 file changed

+56
-53
lines changed

1 file changed

+56
-53
lines changed

code/game/objects/items/flamethrower.dm

Lines changed: 56 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
/// How many joules of energy from reactions required to cause 1 damage
2+
#define JOULES_PER_DAMAGE 100000
3+
14
/obj/item/flamethrower
25
name = "flamethrower"
36
desc = "You are a firestarter!"
@@ -54,7 +57,7 @@
5457
if(M.is_holding(src))
5558
location = M.loc
5659
if(isturf(location)) //start a fire if possible
57-
igniter.flamethrower_process(location)
60+
open_flame(igniter.heat)
5861

5962

6063
/obj/item/flamethrower/update_overlays()
@@ -199,33 +202,21 @@
199202
if(!istype(target))
200203
return FALSE
201204

202-
var/ratio_removed = 1
203-
if(!release_all)
204-
ratio_removed = min(ptank.distribute_pressure, ptank.air_contents.return_pressure()) / ptank.air_contents.return_pressure()
205+
var/ratio_removed = min(ptank.distribute_pressure, ptank.air_contents.return_pressure()) / ptank.air_contents.return_pressure()
206+
205207
var/datum/gas_mixture/fuel_mix = ptank.air_contents.remove_ratio(ratio_removed)
208+
var/datum/gas_mixture/turf_mix = target.return_air()
209+
210+
fuel_mix.merge(turf_mix.copy()) // copy air from the turf to do reactions with
211+
fuel_mix.set_temperature(igniter.heat) // heat the contents
212+
213+
var/old_thermal_energy = fuel_mix.thermal_energy()
214+
for(var/i in 1 to 10) // react a bunch of times on the target turf
215+
if(!fuel_mix.react(target))
216+
break // break the loop if it stops reacting
206217

207-
// Return of the stimball flamethrower, wear radiation protection when using this or you're just as likely to die as your target
208-
if(fuel_mix.get_moles(GAS_PLASMA) >= NITRO_BALL_MOLES_REQUIRED && fuel_mix.get_moles(GAS_NITRIUM) >= NITRO_BALL_MOLES_REQUIRED && fuel_mix.get_moles(GAS_PLUOXIUM) >= NITRO_BALL_MOLES_REQUIRED)
209-
var/balls_shot = round(min(fuel_mix.get_moles(GAS_NITRIUM), fuel_mix.get_moles(GAS_PLUOXIUM), NITRO_BALL_MAX_REACT_RATE / NITRO_BALL_MOLES_REQUIRED))
210-
var/angular_increment = 360/balls_shot
211-
var/random_starting_angle = rand(0,360)
212-
for(var/i in 1 to balls_shot)
213-
target.fire_nuclear_particle((i*angular_increment+random_starting_angle))
214-
fuel_mix.adjust_moles(GAS_PLASMA, -balls_shot * NITRO_BALL_MOLES_REQUIRED) // No free extra damage for you, conservation of mass go brrrrr
215-
216-
// Funny rad flamethrower go brrr
217-
if(fuel_mix.get_moles(GAS_TRITIUM)) // Tritium fires cause a bit of radiation
218-
radiation_pulse(target, min(fuel_mix.get_moles(GAS_TRITIUM), fuel_mix.get_moles(GAS_O2)/2) * FIRE_HYDROGEN_ENERGY_RELEASED / TRITIUM_BURN_RADIOACTIVITY_FACTOR)
219-
220-
// 8 damage at 0.5 mole transfer or ~17 kPa release pressure
221-
// 16 damage at 1 mole transfer or ~35 kPa release pressure
222-
var/damage = fuel_mix.get_moles(GAS_PLASMA) * 16
223-
// harder to achieve than plasma
224-
damage += fuel_mix.get_moles(GAS_TRITIUM) * 24 // Lower damage than hydrogen, causes minor radiation
225-
damage += fuel_mix.get_moles(GAS_H2) * 32
226-
// Maximum damage restricted by the available oxygen, with a hard cap at 16
227-
var/datum/gas_mixture/turf_air = target.return_air()
228-
damage = min(damage, turf_air.get_moles(GAS_O2) + fuel_mix.get_moles(GAS_O2), max_damage) // capped by combined oxygen in the fuel mix and enviroment
218+
// damage is based on the positive or negative energy of the reaction, with a cap
219+
var/damage = min(abs(fuel_mix.thermal_energy() - old_thermal_energy) / JOULES_PER_DAMAGE, max_damage)
229220

230221
// If there's not enough fuel and/or oxygen to do more than 1 damage, shut itself off
231222
if(damage < 1)
@@ -251,22 +242,40 @@
251242
for(var/turf/T in turflist)
252243
if(T == previousturf)
253244
continue //so we don't burn the tile we be standin on
254-
for(var/obj/structure/blob/B in T)
245+
var/cached_damage = 0
246+
247+
for(var/obj/structure/blob/blob in T)
255248
// This is run before atmos checks because blob can be atmos blocking but we still want to hit them
256249
// See /proc/default_ignite
257-
var/damage = process_fuel(T)
258-
if(!damage)
259-
break // Out of gas, stop running pointlessly
260-
B.take_damage(damage * 2, BURN, FIRE) // strong against blobs
250+
if(!cached_damage)
251+
cached_damage = process_fuel(T)
252+
if(!lit)
253+
break // stopped running, don't continue
254+
if(QDELETED(blob))
255+
continue
256+
blob.take_damage(cached_damage * 2, BURN, FIRE) // strong against blobs
257+
258+
for(var/obj/structure/spacevine/vine in T)
259+
// This is run before atmos checks because vines can be on top of a window or some other atmos-blocking structure
260+
if(!cached_damage)
261+
cached_damage = process_fuel(T)
262+
if(!lit)
263+
break // stopped running, don't continue
264+
if(QDELETED(vine))
265+
continue
266+
vine.take_damage(cached_damage * 3, BURN, FIRE, TRUE) // very strong against vines
267+
261268
var/list/turfs_sharing_with_prev = previousturf.GetAtmosAdjacentTurfs(alldir=1)
262269
if(!(T in turfs_sharing_with_prev))
263270
break // Hit something that blocks atmos
264-
if(igniter)
265-
if(!igniter.ignite_turf(src,T))
266-
break // Out of gas, stop running pointlessly
267-
else
268-
if(!default_ignite(T))
269-
break // Out of gas, stop running pointlessly
271+
272+
if(!cached_damage)
273+
cached_damage = process_fuel(T)
274+
if(!lit)
275+
break // stopped running, don't continue
276+
if(!burn_atoms_on_turf(T, cached_damage))
277+
break // Out of gas, stop running pointlessly
278+
270279
if(!sound_played) // play the sound once if we successfully ignite at least one thing
271280
sound_played = TRUE
272281
playsound(loc, pick(flame_sounds), 50, TRUE)
@@ -281,10 +290,9 @@
281290
// /obj/structure/blob/normal
282291

283292
// Return value tells the parent whether to continue calculating the line
284-
/obj/item/flamethrower/proc/default_ignite(turf/target, release_all = FALSE)
285-
// do the fuel stuff
286-
var/damage = process_fuel(target, release_all)
287-
if(!damage)
293+
/obj/item/flamethrower/proc/burn_atoms_on_turf(turf/target, damage)
294+
// no damage? don't continue
295+
if(damage <= 0)
288296
return FALSE
289297

290298
//Burn it
@@ -333,24 +341,17 @@
333341
var/obj/projectile/P = hitby
334342
if(damage && attack_type == PROJECTILE_ATTACK && P.damage_type != STAMINA && prob(5))
335343
owner.visible_message(span_danger("\The [attack_text] hits the fueltank on [owner]'s [name], rupturing it! What a shot!"))
336-
var/target_turf = get_turf(owner)
337-
igniter.ignite_turf(src,target_turf, release_all = TRUE)
338-
qdel(ptank)
339-
return 1 //It hit the flamethrower, not them
340-
341-
342-
/obj/item/assembly/igniter/proc/flamethrower_process(turf/open/location)
343-
location.hotspot_expose(700,2)
344-
345-
/obj/item/assembly/igniter/proc/ignite_turf(obj/item/flamethrower/F, turf/open/location, release_all = FALSE)
346-
return F.default_ignite(location, release_all)
344+
var/turf/target_turf = get_turf(owner)
345+
burn_atoms_on_turf(target_turf, process_fuel(target_turf))
346+
return TRUE //It hit the flamethrower, not them
347+
return ..()
347348

348349
///////////////////// Flamethrower as an energy weapon /////////////////////
349350
// Currently used exclusively in /obj/item/gun/energy/printer/flamethrower
350351
/obj/item/ammo_casing/energy/flamethrower
351352
projectile_type = /obj/projectile/bullet/incendiary/flamethrower
352353
select_name = "fire"
353-
fire_sound = null
354+
fire_sound = 'sound/weapons/flamethrower1.ogg'
354355
firing_effect_type = null
355356
e_cost = 50
356357

@@ -361,3 +362,5 @@
361362
sharpness = SHARP_NONE
362363
range = 6
363364
penetration_flags = PENETRATE_OBJECTS | PENETRATE_MOBS
365+
366+
#undef JOULES_PER_DAMAGE

0 commit comments

Comments
 (0)