-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds Chemical flamethrowers (#25091)
* Initial work * Good enough to open a PR out of draft * Make these use the vars on the flamethrower * Moar fixes * Undefines define * Update code/game/objects/items/weapons/chemical_flamethrower.dm Co-authored-by: GDN <[email protected]> * Update code/game/objects/items/weapons/chemical_flamethrower.dm Co-authored-by: GDN <[email protected]> * Update code/game/objects/items/weapons/chemical_flamethrower.dm Co-authored-by: GDN <[email protected]> * Update code/game/objects/items/weapons/chemical_flamethrower.dm Co-authored-by: GDN <[email protected]> * Update code/game/objects/items/weapons/chemical_flamethrower.dm Co-authored-by: GDN <[email protected]> * This won't compile * GDN review * Fixes CI * Fixes CI even more * 5 ammo per tile now * Heavily nerfs adding multiple fires * Adds phlogiston as a burnable reagent * Fixes the fire name * Placeholder sprite + ammo use fix * Now in cargo partially * Apply suggestions from code review Co-authored-by: Henri215 <[email protected]> Signed-off-by: DGamerL <[email protected]> * Update code/game/objects/items/weapons/chemical_flamethrower/chemical_flamethrower.dm Co-authored-by: GDN <[email protected]> Signed-off-by: DGamerL <[email protected]> * Update code/game/objects/items/weapons/chemical_flamethrower/fire_effect.dm Co-authored-by: GDN <[email protected]> Signed-off-by: DGamerL <[email protected]> * Update code/game/objects/items/weapons/chemical_flamethrower/fire_effect.dm Co-authored-by: GDN <[email protected]> Signed-off-by: DGamerL <[email protected]> * Lewc Review * Adds nuclear variant * Adds the chem flamethrower to the nukie uplink, alongside ammo * More fire armor tweaks * GDN review * Update code/modules/reagents/chemistry/reagents/pyrotechnic.dm Co-authored-by: 1080pCat <[email protected]> Signed-off-by: DGamerL <[email protected]> * Update code/game/objects/items/weapons/chemical_flamethrower/chemical_flamethrower.dm Co-authored-by: 1080pCat <[email protected]> Signed-off-by: DGamerL <[email protected]> * Apply suggestions from code review Co-authored-by: 1080pCat <[email protected]> Signed-off-by: DGamerL <[email protected]> * Update code/game/objects/items/weapons/chemical_flamethrower/chemical_flamethrower.dm Co-authored-by: Luc <[email protected]> Signed-off-by: DGamerL <[email protected]> * Update code/game/objects/items/weapons/chemical_flamethrower/fire_effect.dm Co-authored-by: Luc <[email protected]> Signed-off-by: DGamerL <[email protected]> * TEMPORARY PUSH * Adds inhands * Update code/game/objects/items/weapons/chemical_flamethrower/chemical_flamethrower.dm Co-authored-by: Luc <[email protected]> Signed-off-by: DGamerL <[email protected]> * Update code/game/objects/items/weapons/chemical_flamethrower/chemical_flamethrower.dm Co-authored-by: Luc <[email protected]> Signed-off-by: DGamerL <[email protected]> * Fixes inhands * Makes air hot again * Lewc review * Audible messages and canister refilling * Update code/game/objects/items/weapons/chemical_flamethrower/chemical_flamethrower.dm Co-authored-by: Burzah <[email protected]> Signed-off-by: DGamerL <[email protected]> --------- Signed-off-by: DGamerL <[email protected]> Co-authored-by: GDN <[email protected]> Co-authored-by: Henri215 <[email protected]> Co-authored-by: 1080pCat <[email protected]> Co-authored-by: Luc <[email protected]> Co-authored-by: Burzah <[email protected]>
- Loading branch information
1 parent
6ae5bfe
commit e3c7311
Showing
21 changed files
with
523 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
288 changes: 288 additions & 0 deletions
288
code/game/objects/items/weapons/chemical_flamethrower/chemical_flamethrower.dm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,288 @@ | ||
/obj/item/chemical_flamethrower | ||
name = "chemical flamethrower" | ||
desc = "I love the smell of napalm in the morning." | ||
icon = 'icons/obj/chemical_flamethrower.dmi' | ||
icon_state = "chem_flame" | ||
lefthand_file = 'icons/mob/inhands/flamethrower_lefthand.dmi' | ||
righthand_file = 'icons/mob/inhands/flamethrower_righthand.dmi' | ||
flags = CONDUCT | ||
force = 5 | ||
throwforce = 10 | ||
throw_speed = 1 | ||
throw_range = 5 | ||
w_class = WEIGHT_CLASS_NORMAL | ||
slot_flags = SLOT_FLAG_BACK | ||
materials = list(MAT_METAL = 5000) | ||
resistance_flags = FIRE_PROOF | ||
origin_tech = "combat=1;plasmatech=2;engineering=2" | ||
|
||
/// How many canisters fit in our flamethrower? | ||
var/max_canisters = 1 | ||
/// All our loaded canisters in a list | ||
var/list/canisters = list() | ||
/// Is this a type of flamethrower that starts loaded? | ||
var/should_start_with_canisters = FALSE | ||
|
||
/// The burn temperature of our currently stored chemical in the canister | ||
var/canister_burn_temp = T0C + 300 | ||
/// The burn duration of our currently stored chemical in the canister | ||
var/canister_burn_duration = 10 SECONDS | ||
/// How many firestacks will our reagent apply | ||
var/canister_fire_applications = 1 | ||
/// Is this a syndicate flamethrower | ||
var/syndicate = FALSE | ||
|
||
/obj/item/chemical_flamethrower/Initialize(mapload) | ||
. = ..() | ||
if(should_start_with_canisters && !length(canisters)) | ||
canisters += new /obj/item/chemical_canister | ||
update_canister_stats() | ||
update_icon_state() | ||
|
||
/obj/item/chemical_flamethrower/Destroy() | ||
QDEL_LIST_CONTENTS(canisters) | ||
return ..() | ||
|
||
/obj/item/chemical_flamethrower/update_icon_state() | ||
icon_state = "chem_flame[max_canisters == 2 ? "_2" : ""][syndicate ? "_s" : ""]" | ||
item_state = icon_state | ||
|
||
/obj/item/chemical_flamethrower/update_overlays() | ||
. = ..() | ||
var/iterator = 1 | ||
for(var/obj/item/chemical_canister as anything in canisters) | ||
. += mutable_appearance('icons/obj/chemical_flamethrower.dmi', "[chemical_canister.icon_state]_[iterator]") | ||
iterator++ | ||
|
||
/obj/item/chemical_flamethrower/attack_self(mob/user) | ||
. = ..() | ||
if(length(canisters)) | ||
unequip_canisters(user) | ||
|
||
/obj/item/chemical_flamethrower/proc/unequip_canisters(mob/user) | ||
if(!length(canisters)) | ||
return | ||
|
||
var/obj/item/chemical_canister/canister_to_remove = canisters[length(canisters)] | ||
canister_to_remove.forceMove(get_turf(src)) | ||
user.put_in_hands(canister_to_remove) | ||
canisters -= canister_to_remove | ||
update_icon(UPDATE_OVERLAYS) | ||
|
||
/obj/item/chemical_flamethrower/attackby(obj/item/I, mob/user, params) | ||
. = ..() | ||
if(!istype(I, /obj/item/chemical_canister)) | ||
to_chat(user, "<span class='notice'>You can't fit [I] in there!</span>") | ||
return | ||
if(length(canisters) >= max_canisters) | ||
to_chat(user, "<span class='notice'>[src] is already full!</span>") | ||
return | ||
|
||
if(!user.unEquip(I)) | ||
return | ||
|
||
to_chat(user, "<span class='notice'>You put [I] into [src].</span>") | ||
canisters += I | ||
I.forceMove(src) | ||
update_canister_stats() | ||
|
||
/obj/item/chemical_flamethrower/proc/update_canister_stats() | ||
if(!length(canisters)) | ||
canister_burn_temp = null | ||
canister_burn_duration = null | ||
canister_fire_applications = null | ||
return | ||
|
||
var/burn_temp | ||
var/burn_duration | ||
var/fire_applications | ||
var/how_many_canisters = length(canisters) | ||
|
||
for(var/obj/item/chemical_canister/canister as anything in canisters) | ||
if(!canister.ammo) | ||
continue | ||
burn_temp += canister.chem_burn_temp | ||
burn_duration += canister.chem_burn_duration | ||
fire_applications += canister.fire_applications | ||
|
||
canister_burn_temp = round(burn_temp / how_many_canisters, 1) | ||
canister_burn_duration = round(burn_duration / how_many_canisters, 1) | ||
canister_fire_applications = round(fire_applications / how_many_canisters, 1) | ||
update_icon(UPDATE_OVERLAYS) | ||
|
||
/obj/item/chemical_flamethrower/afterattack(atom/target, mob/user, flag) | ||
. = ..() | ||
if(flag || !user) | ||
return | ||
|
||
if(user.mind?.martial_art?.no_guns) | ||
to_chat(user, "<span class='warning'>[user.mind.martial_art.no_guns_message]</span>") | ||
return | ||
|
||
if(HAS_TRAIT(user, TRAIT_CHUNKYFINGERS)) | ||
to_chat(user, "<span class='warning'>Your meaty finger is far too large for the trigger guard!</span>") | ||
return | ||
|
||
if(user.get_active_hand() == src) // Make sure our user is still holding us | ||
var/turf/target_turf = get_turf(target) | ||
if(target_turf) | ||
var/turf_list = get_line(user, target_turf) | ||
add_attack_logs(user, target, "Chemical Flamethrowered at [target.x], [target.y], [target.z]") | ||
INVOKE_ASYNC(src, PROC_REF(flame_turf), turf_list, user) | ||
|
||
/obj/item/chemical_flamethrower/proc/flame_turf(list/turflist = list(), mob/user) | ||
if(!length(turflist)) | ||
return | ||
|
||
var/turf/previousturf = get_turf(src) | ||
for(var/turf/simulated/T in turflist) | ||
if(iswallturf(T)) // No going through walls | ||
break | ||
if(!use_ammo(3)) | ||
to_chat(user, "<span class='warning'>You hear a click!</span>") | ||
playsound(user, 'sound/weapons/empty.ogg', 100, TRUE) | ||
break // Whoops! No ammo! | ||
|
||
if(T == previousturf) | ||
continue // So we don't burn the tile we be standin on | ||
|
||
var/found_obstruction = FALSE | ||
for(var/obj/thing in T) | ||
if(thing.density && !istype(thing, /obj/structure/table)) | ||
found_obstruction = TRUE | ||
break | ||
if(found_obstruction) | ||
break | ||
|
||
make_flame(T) | ||
update_canister_stats() // In case we ran out of some fuel this fire | ||
sleep(1) | ||
previousturf = T | ||
|
||
/obj/item/chemical_flamethrower/proc/make_flame(turf/spawn_turf) | ||
new /obj/effect/fire(spawn_turf, canister_burn_temp, (canister_burn_duration + rand(1, 3) SECONDS), canister_fire_applications) // For that spicy randomness (and to save your ears from all fires extinguishing at the same time) | ||
|
||
/* | ||
* Uses `amount` ammo from the flamethrower. | ||
* Returns `TRUE` if ammo could be consumed, returns `FALSE` if it failed somehow | ||
* It will use up ammo if it failed. | ||
*/ | ||
/obj/item/chemical_flamethrower/proc/use_ammo(amount) | ||
var/total_ammo | ||
for(var/obj/item/chemical_canister/canister as anything in canisters) | ||
total_ammo += canister.ammo | ||
if(total_ammo - amount < 0) | ||
return FALSE | ||
|
||
var/length = length(canisters) | ||
var/difference = amount | ||
for(var/i in 0 to length) | ||
var/obj/item/chemical_canister/canister = canisters[length - i] | ||
if(canister.ammo - difference <= 0) | ||
difference -= canister.ammo | ||
canister.ammo = 0 | ||
else | ||
canister.ammo -= difference | ||
difference = 0 | ||
|
||
if(!difference) | ||
break | ||
|
||
return !difference | ||
|
||
/obj/item/chemical_flamethrower/extended | ||
name = "extended capacity chemical flamethrower" | ||
desc = "A flamethrower that accepts two chemical canisters to create lasting fires." | ||
max_canisters = 2 | ||
|
||
/obj/item/chemical_flamethrower/extended/nuclear | ||
name = "\improper Syndicate extended capacity chemical flamethrower" | ||
desc = "A flamethrower that accepts two chemical canisters to create lasting fires. As black as the ash of your enemies." | ||
syndicate = TRUE | ||
|
||
/obj/item/chemical_flamethrower/extended/nuclear/Initialize(mapload) | ||
. = ..() | ||
for(var/i in 1 to max_canisters) | ||
canisters += new /obj/item/chemical_canister/extended/nuclear | ||
update_canister_stats() | ||
|
||
/obj/item/chemical_canister | ||
name = "chemical canister" | ||
desc = "A simple canister of fuel. Does not accept any pyrotechnics except for welding fuel." | ||
icon = 'icons/obj/chemical_flamethrower.dmi' | ||
icon_state = "normal" | ||
container_type = OPENCONTAINER | ||
/// How much ammo do we have? Empty at 0. | ||
var/ammo = 100 | ||
/// Which reagent IDs do we accept | ||
var/list/accepted_chemicals = list("fuel") | ||
/// The burn temperature of our currently stored chemical | ||
var/chem_burn_temp = T0C + 300 | ||
/// The burn duration of our currently stored chemical | ||
var/chem_burn_duration = 10 SECONDS | ||
/// How many firestacks will our reagent apply | ||
var/fire_applications = 1 | ||
/// The currently stored reagent ID | ||
var/current_reagent_id | ||
/// How many units of the reagent do we need to have it's effects kick in? | ||
var/required_volume = 10 | ||
/// Do we have a locked in reagent type? | ||
var/has_filled_reagent = FALSE | ||
/// Are we silent on the first change of reagents? | ||
var/first_time_silent = FALSE // The reason for this is so we can have canisters that spawn with reagents but don't announce it on `Initialize()` | ||
|
||
/obj/item/chemical_canister/Initialize(mapload) | ||
. = ..() | ||
create_reagents(50) | ||
|
||
/obj/item/chemical_canister/on_reagent_change() | ||
if(has_filled_reagent && ammo != 0) | ||
audible_message("<span class='notice'>[src]'s speaker beeps: no new chemicals are accepted!</span>") | ||
return | ||
|
||
if(!reagents.get_master_reagent_id() || !(reagents.get_master_reagent_id() in accepted_chemicals)) | ||
reagents.clear_reagents() | ||
audible_message("<span class='notice'>[src]'s speaker beeps: the most present chemical isn't accepted!</span>") | ||
return | ||
|
||
current_reagent_id = reagents.get_master_reagent_id() | ||
reagents.isolate_reagent(current_reagent_id) | ||
var/has_enough_reagents = reagents.total_volume >= required_volume | ||
|
||
if(!first_time_silent) | ||
audible_message("<span class='notice'>[src]'s speaker beeps: \ | ||
All reagents are removed except for [current_reagent_id]. \ | ||
The reservoir has [reagents.total_volume] out of [required_volume] units. \ | ||
Reagent effects are [has_enough_reagents ? "in effect" : "not active"].</span>") | ||
first_time_silent = FALSE | ||
|
||
if(has_enough_reagents) | ||
var/datum/reagent/reagent_to_burn = reagents.reagent_list[1] | ||
chem_burn_duration = reagent_to_burn.burn_duration | ||
chem_burn_temp = reagent_to_burn.burn_temperature | ||
fire_applications = reagent_to_burn.fire_stack_applications | ||
ammo = initial(ammo) | ||
has_filled_reagent = TRUE | ||
|
||
/obj/item/chemical_canister/extended | ||
name = "extended capacity chemical canister" | ||
desc = "An extended version of the original design. Does not accept any pyrotechnics except for welding fuel." | ||
icon_state = "extended" | ||
ammo = 200 | ||
required_volume = 20 // Bigger canister? More reagents needed. | ||
|
||
/obj/item/chemical_canister/extended/nuclear | ||
icon_state = "pyro" | ||
accepted_chemicals = list("napalm") | ||
first_time_silent = TRUE | ||
|
||
/obj/item/chemical_canister/extended/nuclear/Initialize(mapload) | ||
..() | ||
reagents.add_reagent("napalm", 30) // Overload it with napalm! | ||
|
||
/obj/item/chemical_canister/pyrotechnics | ||
name = "extended capacity chemical canister" | ||
desc = "A specialized canister designed to accept certain pyrotechnics." | ||
icon_state = "pyro" | ||
ammo = 150 | ||
accepted_chemicals = list("phlogiston", "phlogiston_dust", "napalm", "fuel", "thermite", "clf3", "plasma") |
Oops, something went wrong.