diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index 0ef20dea19..fca7f9bc6d 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -160,11 +160,22 @@ if(sensor.on && sensor.visible) add_overlay("proxy_beam") -/obj/item/transfer_valve/proc/merge_gases() - tank_two.air_contents.volume += tank_one.air_contents.volume +/obj/item/transfer_valve/proc/merge_gases(datum/gas_mixture/target, change_volume = TRUE) + var/target_self = FALSE + if(!target || (target == tank_one.air_contents)) + target = tank_two.air_contents + if(target == tank_two.air_contents) + target_self = TRUE + if(change_volume) + if(!target_self) + target.volume += tank_two.volume + target.volume += tank_one.air_contents.volume var/datum/gas_mixture/temp temp = tank_one.air_contents.remove_ratio(1) - tank_two.air_contents.merge(temp) + target.merge(temp) + if(!target_self) + temp = tank_two.air_contents.remove_ratio(1) + target.merge(temp) /obj/item/transfer_valve/proc/split_gases() if (!valve_open || !tank_one || !tank_two) diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm index 447a83422b..74aea29768 100644 --- a/code/game/objects/items/tanks/tanks.dm +++ b/code/game/objects/items/tanks/tanks.dm @@ -226,7 +226,6 @@ air_contents.react() check_status() - /obj/item/tank/proc/check_status() //Handle exploding, leaking, and rupturing of the tank diff --git a/code/modules/projectiles/guns/misc/blastcannon.dm b/code/modules/projectiles/guns/misc/blastcannon.dm index e7b628653f..df1f9fdfbd 100644 --- a/code/modules/projectiles/guns/misc/blastcannon.dm +++ b/code/modules/projectiles/guns/misc/blastcannon.dm @@ -11,8 +11,21 @@ clumsy_check = FALSE randomspread = FALSE + var/hugbox = TRUE + var/max_power = INFINITY + 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. + var/prereaction = TRUE + + var/bombcheck = TRUE + var/debug_power = 0 + var/obj/item/transfer_valve/bomb +/obj/item/gun/blastcannon/debug + debug_power = 80 + bombcheck = FALSE + /obj/item/gun/blastcannon/Initialize() . = ..() if(!pin) @@ -56,27 +69,33 @@ return TRUE return ..() +//returns the third value of a bomb blast /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(60) //directional buff. - temp.merge(bomb.tank_one.air_contents.remove_ratio(1)) - temp.merge(bomb.tank_two.air_contents.remove_ratio(2)) - for(var/i in 1 to 6) + 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() + if(prereaction_pressure < TANK_FRAGMENT_PRESSURE) + 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_SCALE) + return ((pressure - TANK_FRAGMENT_PRESSURE) / TANK_FRAGMENT_SCALE) /obj/item/gun/blastcannon/afterattack(atom/target, mob/user, flag, params) - if((!bomb) || (!target) || (get_dist(get_turf(target), get_turf(user)) <= 2)) + if((!bomb && bombcheck) || (!target) || (get_dist(get_turf(target), get_turf(user)) <= 2)) return ..() - var/power = calculate_bomb() + var/power = bomb? calculate_bomb() : debug_power + power = min(power, max_power) QDEL_NULL(bomb) update_icon() - var/heavy = power * 0.2 + var/heavy = power * 0.25 var/medium = power * 0.5 var/light = power user.visible_message("[user] opens [bomb] on [user.p_their()] [name] and fires a blast wave at [target]!","You open [bomb] on your [name] and fire a blast wave at [target]!") @@ -87,7 +106,8 @@ message_admins(log_str) log_game(log_str) var/obj/item/projectile/blastwave/BW = new(loc, heavy, medium, light) - BW.preparePixelProjectile(target, get_turf(target), user, params, 0) + BW.hugbox = hugbox + BW.preparePixelProjectile(target, get_turf(src), params, 0) BW.fire() /obj/item/projectile/blastwave @@ -99,6 +119,7 @@ var/heavyr = 0 var/mediumr = 0 var/lightr = 0 + var/hugbox = TRUE range = 150 /obj/item/projectile/blastwave/Initialize(mapload, _h, _m, _l) @@ -110,14 +131,25 @@ /obj/item/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) - loc.ex_act(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 + loc.ex_act(amount_destruction) else qdel(src) diff --git a/code/modules/uplink/uplink_items.dm b/code/modules/uplink/uplink_items.dm index 89197a7f07..619e2c8193 100644 --- a/code/modules/uplink/uplink_items.dm +++ b/code/modules/uplink/uplink_items.dm @@ -1412,6 +1412,16 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) limited_stock = 2 //you can't use more than two! restricted_roles = list("Shaft Miner") +/datum/uplink_item/role_restricted/blastcannon + name = "Blast Cannon" + desc = "A highly specialized weapon, the Blast Cannon is actually relatively simple. It contains an attachment for a tank transfer valve mounted to an angled pipe specially constructed \ + withstand extreme pressure and temperatures, and has a mechanical trigger for triggering the transfer valve. Essentially, it turns the explosive force of a bomb into a narrow-angle \ + blast wave \"projectile\". Aspiring scientists may find this highly useful, as forcing the pressure shockwave into a narrow angle seems to be able to bypass whatever quirk of physics \ + disallows explosive ranges above a certain distance, allowing for the device to use the theoretical yield of a transfer valve bomb, instead of the factual yield." + item = /obj/item/gun/blastcannon + cost = 14 //High cost because of the potential for extreme damage in the hands of a skilled scientist. + restricted_roles = list("Research Director", "Scientist") + /datum/uplink_item/device_tools/clown_bomb name = "Clown Bomb" desc = "The Clown bomb is a hilarious device capable of massive pranks. It has an adjustable timer, \