From 561c2179f8279c8f9a220131e66b240a0f1727e0 Mon Sep 17 00:00:00 2001
From: kevinz000 <2003111+kevinz000@users.noreply.github.com>
Date: Thu, 21 Jun 2018 16:38:29 -0700
Subject: [PATCH 1/2] Fixes and adds blast cannons to traitor science uplink
items (#38093)
rscadd: Blast cannons have been fixed and are now available for purchase by traitorous scientists for a low low price of 14TC.
rscadd: Blast cannons take the explosive power of a TTV bomb and ejects a linear projectile that will apply what the bomb would do to a certain tile at that distance to that tile. However, this will not cause breaches, or gib mobs, unless the gods (admins) so will it.
experimental: Blast cannons do not respect maxcap. (Unless the admins so will it.)
---
.../objects/items/devices/transfer_valve.dm | 17 ++++--
code/game/objects/items/tanks/tanks.dm | 1 -
.../projectiles/guns/misc/blastcannon.dm | 52 +++++++++++++++----
code/modules/uplink/uplink_items.dm | 10 ++++
4 files changed, 66 insertions(+), 14 deletions(-)
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, \