From 0eac787dc0c863b73f58c186f9be87fd39c9c7aa Mon Sep 17 00:00:00 2001 From: TemporalOroboros Date: Sat, 19 Dec 2020 04:11:36 -0800 Subject: [PATCH] Buffs the Blastcannon (#55573) * Unhugboxes the blastcannon - Flips [/obj/item/gun/blastcannon/var/hugboxed] from [TRUE] to [FALSE] - Makes the blastcannon's maximum range scale with it's other explosive power - Documents some class level variables for the blastcannon --- .../projectiles/guns/misc/blastcannon.dm | 133 +++++++++--------- 1 file changed, 69 insertions(+), 64 deletions(-) diff --git a/code/modules/projectiles/guns/misc/blastcannon.dm b/code/modules/projectiles/guns/misc/blastcannon.dm index b6e4b88f6f8..31b4121b042 100644 --- a/code/modules/projectiles/guns/misc/blastcannon.dm +++ b/code/modules/projectiles/guns/misc/blastcannon.dm @@ -1,8 +1,12 @@ +/** + * A gun that consumes a TTV to shoot an projectile with equivalent power. + * + * It's basically an immovable rod launcher. + */ /obj/item/gun/blastcannon name = "pipe gun" desc = "A pipe welded onto a gun stock, with a mechanical trigger. The pipe has an opening near the top, and there seems to be a spring loaded wheel in the hole." icon_state = "empty_blastcannon" - var/icon_state_loaded = "loaded_blastcannon" inhand_icon_state = "blastcannon_empty" w_class = WEIGHT_CLASS_NORMAL force = 10 @@ -10,17 +14,26 @@ item_flags = NONE clumsy_check = FALSE randomspread = FALSE + /// The icon state used when this is loaded with a bomb. + var/icon_state_loaded = "loaded_blastcannon" - var/hugbox = TRUE - var/max_power = INFINITY + /// The TTV this contains that will be used to create the projectile + var/obj/item/transfer_valve/bomb + /// Additional volume added to the gasmixture used to calculate the bombs power. var/reaction_volume_mod = 0 - var/reaction_cycles = 3 //How many times gases react() before calculation. Very finnicky value, do not mess with without good reason. + /// Whether the gases are reacted once before calculating the range var/prereaction = TRUE + /// How many times gases react() before calculation. Very finnicky value, do not mess with without good reason. + var/reaction_cycles = 3 + /// The maximum power the blastcannon is capable of reaching + var/max_power = INFINITY + // For debugging/badminry + /// Whether you can fire this without a bomb. var/bombcheck = TRUE + /// The range this defaults to without a bomb for debugging and badminry var/debug_power = 0 - var/obj/item/transfer_valve/bomb /obj/item/gun/blastcannon/debug debug_power = 80 @@ -32,7 +45,8 @@ pin = new /obj/item/gun/blastcannon/Destroy() - QDEL_NULL(bomb) + if(bomb) + QDEL_NULL(bomb) return ..() /obj/item/gun/blastcannon/attack_self(mob/user) @@ -47,34 +61,35 @@ return ..() /obj/item/gun/blastcannon/update_icon_state() - if(bomb) - icon_state = icon_state_loaded - else - icon_state = initial(icon_state) + . = ..() + icon_state = bomb ? icon_state_loaded : initial(icon_state) -/obj/item/gun/blastcannon/attackby(obj/O, mob/user) - if(istype(O, /obj/item/transfer_valve)) - var/obj/item/transfer_valve/T = O - if(!T.tank_one || !T.tank_two) - to_chat(user, "What good would an incomplete bomb do?") - return FALSE - if(!user.transferItemToLoc(T, src)) - to_chat(user, "[T] seems to be stuck to your hand!") - return FALSE - user.visible_message("[user] attaches [T] to [src]!") - bomb = T - name = "blast cannon" - desc = "A makeshift device used to concentrate a bomb's blast energy to a narrow wave." - update_icon() - return TRUE - return ..() +/obj/item/gun/blastcannon/attackby(obj/item/transfer_valve/bomb_to_attach, mob/user) + if(!istype(bomb_to_attach)) + return ..() -//returns the third value of a bomb blast + if(!bomb_to_attach.tank_one || !bomb_to_attach.tank_two) + to_chat(user, "What good would an incomplete bomb do?") + return FALSE + if(!user.transferItemToLoc(bomb_to_attach, src)) + to_chat(user, "[bomb_to_attach] seems to be stuck to your hand!") + return FALSE + + user.visible_message("[user] attaches [bomb_to_attach] to [src]!") + bomb = bomb_to_attach + name = "blast cannon" + desc = "A makeshift device used to concentrate a bomb's blast energy to a narrow wave." + update_icon() + return TRUE + +/// Handles the bomb power calculations /obj/item/gun/blastcannon/proc/calculate_bomb() if(!istype(bomb) || !istype(bomb.tank_one) || !istype(bomb.tank_two)) return 0 + var/datum/gas_mixture/temp = new(max(reaction_volume_mod, 0)) bomb.merge_gases(temp) + if(prereaction) temp.react(src) var/prereaction_pressure = temp.return_pressure() @@ -82,19 +97,23 @@ return 0 for(var/i in 1 to reaction_cycles) temp.react(src) + var/pressure = temp.return_pressure() qdel(temp) if(pressure < TANK_FRAGMENT_PRESSURE) return 0 return ((pressure - TANK_FRAGMENT_PRESSURE) / TANK_FRAGMENT_SCALE) + /obj/item/gun/blastcannon/afterattack(atom/target, mob/user, flag, params) if((!bomb && bombcheck) || (!target) || (get_dist(get_turf(target), get_turf(user)) <= 2)) return ..() - var/power = bomb? calculate_bomb() : debug_power + + var/power = bomb ? calculate_bomb() : debug_power power = min(power, max_power) QDEL_NULL(bomb) update_icon() + var/heavy = power * 0.25 var/medium = power * 0.5 var/light = power @@ -105,12 +124,12 @@ message_admins("Blast wave fired from [ADMIN_VERBOSEJMP(starting)] at [ADMIN_VERBOSEJMP(targturf)] ([target.name]) by [ADMIN_LOOKUPFLW(user)] with power [heavy]/[medium]/[light].") log_game("Blast wave fired from [AREACOORD(starting)] at [AREACOORD(targturf)] ([target.name]) by [key_name(user)] with power [heavy]/[medium]/[light].") var/obj/projectile/blastwave/BW = new(loc, heavy, medium, light) - BW.hugbox = hugbox BW.preparePixelProjectile(target, get_turf(src), params, 0) BW.fire() name = initial(name) desc = initial(desc) +/// The projectile used by the blastcannon /obj/projectile/blastwave name = "blast wave" icon_state = "blastwave" @@ -118,52 +137,38 @@ nodamage = FALSE movement_type = FLYING projectile_phasing = ALL // just blows up the turfs lmao + /// The maximum distance this will inflict [EXPLODE_DEVASTATE] var/heavyr = 0 + /// The maximum distance this will inflict [EXPLODE_HEAVY] var/mediumr = 0 + /// The maximum distance this will inflict [EXPLODE_LIGHT] var/lightr = 0 - var/hugbox = TRUE - range = 150 -/obj/projectile/blastwave/Initialize(mapload, _h, _m, _l) - heavyr = _h - mediumr = _m - lightr = _l +/obj/projectile/blastwave/Initialize(mapload, _heavy, _medium, _light) + range = max(_heavy, _medium, _light, 0) + heavyr = _heavy + mediumr = _medium + lightr = _light return ..() /obj/projectile/blastwave/Range() - ..() - var/amount_destruction = EXPLODE_NONE - var/wallbreak_chance = 0 - if(heavyr) - amount_destruction = EXPLODE_DEVASTATE - wallbreak_chance = 99 - else if(mediumr) - amount_destruction = EXPLODE_HEAVY - wallbreak_chance = 66 - else if(lightr) - amount_destruction = EXPLODE_LIGHT - wallbreak_chance = 33 - if(amount_destruction) - if(hugbox) - loc.contents_explosion(EXPLODE_HEAVY, loc) - if(istype(loc, /turf/closed/wall)) - var/turf/closed/wall/W = loc - if(prob(wallbreak_chance)) - W.dismantle_wall(TRUE, TRUE) - else - switch(amount_destruction) - if(EXPLODE_DEVASTATE) - SSexplosions.highturf += loc - if(EXPLODE_HEAVY) - SSexplosions.medturf += loc - if(EXPLODE_LIGHT) - SSexplosions.lowturf += loc - else - qdel(src) + . = ..() + if(QDELETED(src)) + return heavyr = max(heavyr - 1, 0) mediumr = max(mediumr - 1, 0) lightr = max(lightr - 1, 0) + if(heavyr) + SSexplosions.highturf += loc + else if(mediumr) + SSexplosions.medturf += loc + else if(lightr) + SSexplosions.lowturf += loc + else + qdel(src) + return + /obj/projectile/blastwave/ex_act() return