(ignore point 13)
This commit is contained in:
LorenLuke
2017-07-16 16:03:31 -07:00
parent b7df8d0b90
commit b7f5362276
7 changed files with 563 additions and 316 deletions

View File

@@ -133,9 +133,9 @@
var/assembly_type = /obj/item/device/assembly/signaler
//Note that the maximum amount of gas you can put in a 70L air tank at 1013.25 kPa and 519K is 16.44 mol.
var/phoron_amt = 10.96
var/oxygen_amt = 16.44
var/carbon_amt = 0.0
var/phoron_amt = 12
var/oxygen_amt = 18
var/carbon_amt = 0
/obj/effect/spawner/newbomb/timer
name = "TTV bomb - timer"
@@ -144,8 +144,8 @@
/obj/effect/spawner/newbomb/timer/syndicate
name = "TTV bomb - merc"
//High yield bombs. Yes, it is possible to make these with toxins
phoron_amt = 15.66
oxygen_amt = 24.66
phoron_amt = 18.5
oxygen_amt = 28.5
/obj/effect/spawner/newbomb/proximity
name = "TTV bomb - proximity"
@@ -170,15 +170,20 @@
PT.master = V
OT.master = V
PT.air_contents.temperature = PHORON_FLASHPOINT
PT.valve_welded = 1
PT.air_contents.gas["phoron"] = phoron_amt
PT.air_contents.gas["carbon_dioxide"] = carbon_amt
PT.air_contents.total_moles = phoron_amt + carbon_amt
PT.air_contents.temperature = PHORON_MINIMUM_BURN_TEMPERATURE+1
PT.air_contents.update_values()
OT.air_contents.temperature = PHORON_FLASHPOINT
OT.valve_welded = 1
OT.air_contents.gas["oxygen"] = oxygen_amt
OT.air_contents.total_moles = oxygen_amt
OT.air_contents.temperature = PHORON_MINIMUM_BURN_TEMPERATURE+1
OT.air_contents.update_values()
var/obj/item/device/assembly/S = new assembly_type(V)
@@ -190,3 +195,62 @@
V.update_icon()
qdel(src)
///////////////////////
//One Tank Bombs, WOOOOOOO! -Luke
///////////////////////
/obj/effect/spawner/onetankbomb
name = "Single-tank bomb"
icon = 'icons/mob/screen1.dmi'
icon_state = "x"
// var/assembly_type = /obj/item/device/assembly/signaler
//Note that the maximum amount of gas you can put in a 70L air tank at 1013.25 kPa and 519K is 16.44 mol.
var/phoron_amt = 0
var/oxygen_amt = 0
/obj/effect/spawner/onetankbomb/New(newloc) //just needs an assembly.
..(newloc)
var/type = pick(/obj/item/weapon/tank/phoron/onetankbomb, /obj/item/weapon/tank/oxygen/onetankbomb)
new type(src.loc)
qdel(src)
/obj/effect/spawner/onetankbomb/full
name = "Single-tank bomb"
icon = 'icons/mob/screen1.dmi'
icon_state = "x"
// var/assembly_type = /obj/item/device/assembly/signaler
//Note that the maximum amount of gas you can put in a 70L air tank at 1013.25 kPa and 519K is 16.44 mol.
/obj/effect/spawner/onetankbomb/full/New(newloc) //just needs an assembly.
..(newloc)
var/type = pick(/obj/item/weapon/tank/phoron/onetankbomb/full, /obj/item/weapon/tank/oxygen/onetankbomb/full)
new type(src.loc)
qdel(src)
/obj/effect/spawner/onetankbomb/frag
name = "Single-tank bomb"
icon = 'icons/mob/screen1.dmi'
icon_state = "x"
// var/assembly_type = /obj/item/device/assembly/signaler
//Note that the maximum amount of gas you can put in a 70L air tank at 1013.25 kPa and 519K is 16.44 mol.
/obj/effect/spawner/onetankbomb/full/New(newloc) //just needs an assembly.
..(newloc)
var/type = pick(/obj/item/weapon/tank/phoron/onetankbomb/full, /obj/item/weapon/tank/oxygen/onetankbomb/full)
new type(src.loc)
qdel(src)

View File

@@ -27,13 +27,17 @@
no_attack_log = 1
muzzle_type = null
/obj/item/projectile/bullet/pellet/fragment/strong
damage = 15
armor_penetration = 20
/obj/item/weapon/grenade/explosive
name = "fragmentation grenade"
desc = "A fragmentation grenade, optimized for harming personnel without causing massive structural damage."
icon_state = "frggrenade"
item_state = "grenade"
var/fragment_type = /obj/item/projectile/bullet/pellet/fragment
var/fragment_types = list(/obj/item/projectile/bullet/pellet/fragment, /obj/item/projectile/bullet/pellet/fragment, /obj/item/projectile/bullet/pellet/fragment, /obj/item/projectile/bullet/pellet/fragment/strong)
var/num_fragments = 63 //total number of fragments produced by the grenade
var/explosion_size = 2 //size of the center explosion
@@ -48,29 +52,49 @@
if(!O) return
if(explosion_size)
explosion(O, -1, -1, 2, round(explosion_size/2), 0)
on_explosion(O)
src.fragmentate(O, num_fragments, spread_range, fragment_types)
qdel(src)
var/list/target_turfs = getcircle(O, spread_range)
var/fragments_per_projectile = round(num_fragments/target_turfs.len)
for(var/turf/T in target_turfs)
var/obj/item/projectile/bullet/pellet/fragment/P = new (O)
/obj/proc/fragmentate(var/turf/T=get_turf(src), var/fragment_number = 30, var/spreading_range = 5, var/list/fragtypes=list(/obj/item/projectile/bullet/pellet/fragment/))
set waitfor = 0
var/list/target_turfs = getcircle(T, spreading_range)
var/fragments_per_projectile = round(fragment_number/target_turfs.len)
for(var/turf/O in target_turfs)
sleep(0)
var/fragment_type = pickweight(fragtypes)
var/obj/item/projectile/bullet/pellet/fragment/P = new fragment_type(T)
P.pellets = fragments_per_projectile
P.shot_from = src.name
P.launch(T)
//var/cone = new /obj/item/weapon/caution/cone (T)
//spawn(100) qdel(cone)
P.launch(O)
//Make sure to hit any mobs in the source turf
for(var/mob/living/M in O)
for(var/mob/living/M in T)
//lying on a frag grenade while the grenade is on the ground causes you to absorb most of the shrapnel.
//you will most likely be dead, but others nearby will be spared the fragments that hit you instead.
if(M.lying && isturf(src.loc))
P.attack_mob(M, 0, 0)
P.attack_mob(M, 0, 5)
else if(!M.lying && src.loc != get_turf(src)) //if it's not on the turf, it must be in the mob!
P.attack_mob(M, 0, 25) //you're holding a grenade, dude!
else
P.attack_mob(M, 0, 100) //otherwise, allow a decent amount of fragments to pass
qdel(src)
/obj/item/weapon/grenade/explosive/proc/on_explosion(var/turf/O)
if(explosion_size)
explosion(O, -1, -1, explosion_size, round(explosion_size/2), 0)
/obj/item/weapon/grenade/explosive/frag
name = "fragmentation grenade"
desc = "A military fragmentation grenade, designed to explode in a deadly shower of fragments."
icon_state = "frag"
loadable = null
fragment_types = list(/obj/item/projectile/bullet/pellet/fragment)
num_fragments = 200 //total number of fragments produced by the grenade
//The radius of the circle used to launch projectiles. Lower values mean less projectiles are used but if set too low gaps may appear in the spread pattern

View File

@@ -1,61 +0,0 @@
//Fragmentation grenade projectile
/obj/item/projectile/bullet/pellet/fragment
damage = 15
range_step = 2
base_spread = 0 //causes it to be treated as a shrapnel explosion instead of cone
spread_step = 20
silenced = 1 //embedding messages are still produced so it's kind of weird when enabled.
no_attack_log = 1
muzzle_type = null
/obj/item/weapon/grenade/frag
name = "fragmentation grenade"
desc = "A military fragmentation grenade, designed to explode in a deadly shower of fragments."
icon_state = "frag"
loadable = null
var/num_fragments = 200 //total number of fragments produced by the grenade
var/fragment_damage = 15
var/damage_step = 2 //projectiles lose a fragment each time they travel this distance. Can be a non-integer.
var/explosion_size = 2 //size of the center explosion
//The radius of the circle used to launch projectiles. Lower values mean less projectiles are used but if set too low gaps may appear in the spread pattern
var/spread_range = 7
/obj/item/weapon/grenade/frag/prime()
..()
var/turf/O = get_turf(src)
if(!O) return
if(explosion_size)
explosion(O, -1, round(explosion_size/2), explosion_size, round(explosion_size/2), 0)
var/list/target_turfs = getcircle(O, spread_range)
var/fragments_per_projectile = round(num_fragments/target_turfs.len)
for(var/turf/T in target_turfs)
var/obj/item/projectile/bullet/pellet/fragment/P = new (O)
P.damage = fragment_damage
P.pellets = fragments_per_projectile
P.range_step = damage_step
P.shot_from = src.name
P.launch(T)
//var/cone = new /obj/item/weapon/caution/cone (T)
//spawn(100) qdel(cone)
//Make sure to hit any mobs in the source turf
for(var/mob/living/M in O)
//lying on a frag grenade while the grenade is on the ground causes you to absorb most of the shrapnel.
//you will most likely be dead, but others nearby will be spared the fragments that hit you instead.
if(M.lying && isturf(src.loc))
P.attack_mob(M, 0, 0)
else
P.attack_mob(M, 0, 100) //otherwise, allow a decent amount of fragments to pass
qdel(src)

View File

@@ -16,26 +16,49 @@ var/list/global/tank_gauge_cache = list()
slot_flags = SLOT_BACK
w_class = ITEMSIZE_NORMAL
pressure_resistance = ONE_ATMOSPHERE*5
force = 5.0
throwforce = 10.0
throw_speed = 1
throw_range = 4
sprite_sheets = list(
"Teshari" = 'icons/mob/species/seromi/back.dmi'
)
var/datum/gas_mixture/air_contents = null
var/distribute_pressure = ONE_ATMOSPHERE
var/integrity = 3
var/integrity = 20
var/maxintegrity = 20
var/valve_welded = 0
var/obj/item/device/tankassemblyproxy/proxyassembly
var/volume = 70
var/manipulated_by = null //Used by _onclick/hud/screen_objects.dm internals to determine if someone has messed with our tank or not.
//If they have and we haven't scanned it with the PDA or gas analyzer then we might just breath whatever they put in it.
var/failure_temp = 173 //173 deg C Borate seal (yes it should be 153 F, but that's annoying)
var/leaking = 0
var/wired = 0
description_info = "These tanks are utilised to store any of the various types of gaseous substances. \
They can be attached to various portable atmospheric devices to be filled or emptied. <br>\
<br>\
Each tank is fitted with an emergency relief valve. This relief valve will open if the tank is pressurised to over ~3000kPa or heated to over 173<37>C. \
The valve itself will close after expending most or all of the contents into the air.<br>\
<br>\
Filling a tank such that experiences ~4000kPa of pressure will cause the tank to rupture, spilling out its contents and destroying the tank. \
Tanks filled over ~5000kPa will rupture rather violently, exploding with significant force."
description_antag = "Each tank may be incited to burn by attaching wires and an igniter assembly, though the igniter can only be used once and the mixture only burn if the igniter pushes a flammable gas mixture above the minimum burn temperature (126<32>C). \
Wired and assembled tanks may be disarmed with a set of wirecutters. Any exploding or rupturing tank will generate shrapnel, assuming their relief valves have been welded beforehand. Even if not, they can be incited to expel hot gas on ignition if pushed above 173<37>C. \
Relatively easy to make, the single tank bomb requries no tank transfer valve, and is still a fairly formidable weapon that can be manufactured from any tank."
/obj/item/weapon/tank/proc/init_proxy()
var/obj/item/device/tankassemblyproxy/proxy = new /obj/item/device/tankassemblyproxy(src)
proxy.tank = src
src.proxyassembly = proxy
/obj/item/weapon/tank/New()
..()
src.init_proxy()
src.air_contents = new /datum/gas_mixture()
src.air_contents.volume = volume //liters
src.air_contents.temperature = T20C
@@ -44,15 +67,17 @@ var/list/global/tank_gauge_cache = list()
return
/obj/item/weapon/tank/Destroy()
qdel_null(air_contents)
qdel(air_contents)
processing_objects.Remove(src)
qdel(src.proxyassembly)
if(istype(loc, /obj/item/device/transfer_valve))
var/obj/item/device/transfer_valve/TTV = loc
TTV.remove_tank(src)
qdel(TTV)
return ..()
. = ..()
/obj/item/weapon/tank/examine(mob/user)
. = ..(user, 0)
@@ -70,9 +95,17 @@ var/list/global/tank_gauge_cache = list()
descriptive = "lukewarm"
if(20 to 40)
descriptive = "room temperature"
else
if(-20 to 20)
descriptive = "cold"
user << "<span class='notice'>\The [src] feels [descriptive].</span>"
else
descriptive = "bitterly cold"
to_chat(user, "<span class='notice'>\The [src] feels [descriptive].</span>")
if(src.proxyassembly.assembly || wired)
to_chat(user, "<span class='warning'>It seems to have [wired? "some wires ": ""][wired && src.proxyassembly.assembly? "and ":""][src.proxyassembly.assembly ? "some sort of assembly ":""]attached to it.</span>")
if(src.valve_welded)
to_chat(user, "<span class='warning'>\The [src] emergency relief valve has been welded shut!</span>")
/obj/item/weapon/tank/attackby(obj/item/weapon/W as obj, mob/user as mob)
..()
@@ -87,15 +120,103 @@ var/list/global/tank_gauge_cache = list()
LB.blow(src)
src.add_fingerprint(user)
if(istype(W, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = W
if(C.use(1))
wired = 1
to_chat(user, "<span class='notice'>You attach the wires to the tank.</span>")
src.add_bomb_overlay()
if(istype(W, /obj/item/weapon/wirecutters))
if(wired && src.proxyassembly.assembly)
to_chat(user, "<span class='notice'>You carefully begin clipping the wires that attach to the tank.</span>")
if(do_after(user, 100,src))
wired = 0
src.overlays -= "bomb_assembly"
to_chat(user, "<span class='notice'>You cut the wire and remove the device.</span>")
var/obj/item/device/assembly_holder/assy = src.proxyassembly.assembly
if(assy.a_left && assy.a_right)
assy.dropInto(usr.loc)
assy.master = null
src.proxyassembly.assembly = null
else
if(!src.proxyassembly.assembly.a_left)
assy.a_right.dropInto(usr.loc)
assy.a_right.holder = null
assy.a_right = null
src.proxyassembly.assembly = null
qdel(assy)
src.overlays.Cut()
last_gauge_pressure = 0
update_gauge()
else
to_chat(user, "<span class='danger'>You slip and bump the igniter!</span>")
if(prob(85))
src.proxyassembly.receive_signal()
else if(wired)
if(do_after(user, 10, src))
to_chat(user, "<span class='notice'>You quickly clip the wire from the tank.</span>")
wired = 0
src.overlays -= "bomb_assembly"
else
to_chat(user, "<span class='notice'>There are no wires to cut!</span>")
if(istype(W, /obj/item/device/assembly_holder))
bomb_assemble(W,user)
if(wired)
to_chat(user, "<span class='notice'>You begin attaching the assembly to \the [src].</span>")
if(do_after(user, 50, src))
to_chat(user, "<span class='notice'>You finish attaching the assembly to \the [src].</span>")
bombers += "[key_name(user)] attached an assembly to a wired [src]. Temp: [src.air_contents.temperature-T0C]"
message_admins("[key_name_admin(user)] attached an assembly to a wired [src]. Temp: [src.air_contents.temperature-T0C]")
assemble_bomb(W,user)
else
to_chat(user, "<span class='notice'>You stop attaching the assembly.</span>")
else
to_chat(user, "<span class='notice'>You need to wire the device up first.</span>")
if(istype(W, /obj/item/weapon/weldingtool/))
var/obj/item/weapon/weldingtool/WT = W
if(WT.remove_fuel(1,user))
if(!valve_welded)
to_chat(user, "<span class='notice'>You begin welding the \the [src] emergency pressure relief valve.</span>")
if(do_after(user, 40,src))
to_chat(user, "<span class='notice'>You carefully weld \the [src] emergency pressure relief valve shut.</span><span class='warning'> \The [src] may now rupture under pressure!</span>")
src.valve_welded = 1
src.leaking = 0
else
bombers += "[key_name(user)] attempted to weld a [src]. [src.air_contents.temperature-T0C]"
message_admins("[key_name_admin(user)] attempted to weld a [src]. [src.air_contents.temperature-T0C]")
if(WT.welding)
to_chat(user, "<span class='danger'>You accidentally rake \the [W] across \the [src]!</span>")
maxintegrity -= rand(2,6)
integrity = min(integrity,maxintegrity)
src.air_contents.add_thermal_energy(rand(2000,50000))
WT.eyecheck(user)
else
to_chat(user, "<span class='notice'>The emergency pressure relief valve has already been welded.</span>")
add_fingerprint(user)
/obj/item/weapon/tank/attack_self(mob/user as mob)
add_fingerprint(user)
if (!(src.air_contents))
return
ui_interact(user)
// There's GOT to be a better way to do this
if (src.proxyassembly.assembly)
src.proxyassembly.assembly.attack_self(user)
/obj/item/weapon/tank/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/mob/living/carbon/location = null
@@ -117,7 +238,6 @@ var/list/global/tank_gauge_cache = list()
data["defaultReleasePressure"] = round(TANK_DEFAULT_RELEASE_PRESSURE)
data["maxReleasePressure"] = round(TANK_MAX_RELEASE_PRESSURE)
data["valveOpen"] = using_internal ? 1 : 0
data["maskConnected"] = 0
if(istype(location))
@@ -170,16 +290,21 @@ var/list/global/tank_gauge_cache = list()
src.distribute_pressure += cp
src.distribute_pressure = min(max(round(src.distribute_pressure), 0), TANK_MAX_RELEASE_PRESSURE)
if (href_list["stat"])
toggle_valve(usr)
src.add_fingerprint(usr)
return 1
/obj/item/weapon/tank/proc/toggle_valve(var/mob/user)
if(istype(loc,/mob/living/carbon))
var/mob/living/carbon/location = loc
if(location.internal == src)
location.internal = null
location.internals.icon_state = "internal0"
usr << "<span class='notice'>You close the tank release valve.</span>"
to_chat(user, "<span class='notice'>You close the tank release valve.</span>")
if (location.internals)
location.internals.icon_state = "internal0"
else
var/can_open_valve
if(location.wear_mask && (location.wear_mask.item_flags & AIRTIGHT))
can_open_valve = 1
@@ -190,14 +315,12 @@ var/list/global/tank_gauge_cache = list()
if(can_open_valve)
location.internal = src
usr << "<span class='notice'>You open \the [src] valve.</span>"
to_chat(user, "<span class='notice'>You open \the [src] valve.</span>")
if (location.internals)
location.internals.icon_state = "internal1"
else
usr << "<span class='warning'>You need something to connect to \the [src].</span>"
to_chat(user, "<span class='warning'>You need something to connect to \the [src].</span>")
src.add_fingerprint(usr)
return 1
/obj/item/weapon/tank/remove_air(amount)
@@ -231,6 +354,17 @@ var/list/global/tank_gauge_cache = list()
update_gauge()
check_status()
/obj/item/weapon/tank/proc/add_bomb_overlay()
if(src.wired)
src.overlays += "bomb_assembly"
if(src.proxyassembly.assembly)
var/icon/test = getFlatIcon(src.proxyassembly.assembly)
test.Shift(SOUTH,1)
test.Shift(WEST,3)
overlays += test
/obj/item/weapon/tank/proc/update_gauge()
var/gauge_pressure = 0
if(air_contents)
@@ -245,11 +379,17 @@ var/list/global/tank_gauge_cache = list()
last_gauge_pressure = gauge_pressure
overlays.Cut()
add_bomb_overlay()
var/indicator = "[gauge_icon][(gauge_pressure == -1) ? "overload" : gauge_pressure]"
if(!tank_gauge_cache[indicator])
tank_gauge_cache[indicator] = image(icon, indicator)
overlays += tank_gauge_cache[indicator]
/obj/item/weapon/tank/proc/check_status()
//Handle exploding, leaking, and rupturing of the tank
@@ -257,7 +397,10 @@ var/list/global/tank_gauge_cache = list()
return 0
var/pressure = air_contents.return_pressure()
if(pressure > TANK_FRAGMENT_PRESSURE)
if(integrity <= 7)
if(!istype(src.loc,/obj/item/device/transfer_valve))
message_admins("Explosive tank rupture! last key to touch the tank was [src.fingerprintslast].")
log_game("Explosive tank rupture! last key to touch the tank was [src.fingerprintslast].")
@@ -268,20 +411,47 @@ var/list/global/tank_gauge_cache = list()
air_contents.react()
pressure = air_contents.return_pressure()
var/range = (pressure-TANK_FRAGMENT_PRESSURE)/TANK_FRAGMENT_SCALE
var/strength = ((pressure-TANK_FRAGMENT_PRESSURE)/TANK_FRAGMENT_SCALE)
var/mult = ((src.air_contents.volume/140)**(1/2)) * (air_contents.total_moles**2/3)/((29*0.64) **2/3) //tanks appear to be experiencing a reduction on scale of about 0.64 total moles
//tanks appear to be experiencing a reduction on scale of about 0.64 total moles
var/turf/simulated/T = get_turf(src)
T.hotspot_expose(src.air_contents.temperature, 70, 1)
if(!T)
return
T.assume_air(air_contents)
explosion(
get_turf(loc),
round(min(BOMBCAP_DVSTN_RADIUS, range*0.25)),
round(min(BOMBCAP_HEAVY_RADIUS, range*0.50)),
round(min(BOMBCAP_LIGHT_RADIUS, range*1.00)),
round(min(BOMBCAP_FLASH_RADIUS, range*1.50)),
round(min(BOMBCAP_DVSTN_RADIUS, ((mult)*strength)*0.15)),
round(min(BOMBCAP_HEAVY_RADIUS, ((mult)*strength)*0.35)),
round(min(BOMBCAP_LIGHT_RADIUS, ((mult)*strength)*0.80)),
round(min(BOMBCAP_FLASH_RADIUS, ((mult)*strength)*1.20)),
)
var/num_fragments = round(rand(8,10) * sqrt(strength * mult))
src.fragmentate(T, num_fragments, rand(5) + 7, list(/obj/item/projectile/bullet/pellet/fragment/tank/small = 7,/obj/item/projectile/bullet/pellet/fragment/tank = 2,/obj/item/projectile/bullet/pellet/fragment/strong = 1))
if(istype(loc, /obj/item/device/transfer_valve))
var/obj/item/device/transfer_valve/TTV = loc
TTV.remove_tank(src)
qdel(TTV)
if(src)
qdel(src)
else
integrity -=7
else if(pressure > TANK_RUPTURE_PRESSURE)
#ifdef FIREDBG
log_debug("\blue[x],[y] tank is rupturing: [pressure] kPa, integrity [integrity]")
log_debug("<span class='warning'>[x],[y] tank is rupturing: [pressure] kPa, integrity [integrity]</span>")
#endif
if(integrity <= 0)
@@ -289,24 +459,231 @@ var/list/global/tank_gauge_cache = list()
if(!T)
return
T.assume_air(air_contents)
playsound(src.loc, 'sound/effects/spray.ogg', 10, 1, -3)
playsound(get_turf(src), 'sound/weapons/shotgun.ogg', 20, 1)
visible_message("\icon[src] <span class='danger'>\The [src] flies apart!</span>", "<span class='warning'>You hear a bang!</span>")
T.hotspot_expose(air_contents.temperature, 70, 1)
var/strength = 1+((pressure-TANK_LEAK_PRESSURE)/TANK_FRAGMENT_SCALE)
var/mult = (air_contents.total_moles**2/3)/((29*0.64) **2/3) //tanks appear to be experiencing a reduction on scale of about 0.64 total moles
var/num_fragments = round(rand(6,8) * sqrt(strength * mult)) //Less chunks, but bigger
src.fragmentate(T, num_fragments, 7, list(/obj/item/projectile/bullet/pellet/fragment/tank/small = 1,/obj/item/projectile/bullet/pellet/fragment/tank = 5,/obj/item/projectile/bullet/pellet/fragment/strong = 4))
if(istype(loc, /obj/item/device/transfer_valve))
var/obj/item/device/transfer_valve/TTV = loc
TTV.remove_tank(src)
qdel(src)
else
integrity--
integrity-= 5
else if(pressure > TANK_LEAK_PRESSURE)
#ifdef FIREDBG
log_debug("\blue[x],[y] tank is leaking: [pressure] kPa, integrity [integrity]")
#endif
if(integrity <= 0)
else if(pressure > TANK_LEAK_PRESSURE || air_contents.temperature - T0C > failure_temp)
if((integrity <= 19 || src.leaking) && !valve_welded)
var/turf/simulated/T = get_turf(src)
if(!T)
return
var/datum/gas_mixture/leaked_gas = air_contents.remove_ratio(0.25)
T.assume_air(leaked_gas)
else
integrity--
var/datum/gas_mixture/environment = loc.return_air()
var/env_pressure = environment.return_pressure()
var/tank_pressure = src.air_contents.return_pressure()
else if(integrity < 3)
var/release_ratio = Clamp(0.002, sqrt(max(tank_pressure-env_pressure,0)/tank_pressure),1)
var/datum/gas_mixture/leaked_gas = air_contents.remove_ratio(release_ratio)
//dynamic air release based on ambient pressure
T.assume_air(leaked_gas)
if(!leaking)
visible_message("\icon[src] <span class='warning'>\The [src] relief valve flips open with a hiss!</span>", "You hear hissing.")
playsound(src.loc, 'sound/effects/spray.ogg', 10, 1, -3)
leaking = 1
#ifdef FIREDBG
log_debug("<span class='warning'>[x],[y] tank is leaking: [pressure] kPa, integrity [integrity]</span>")
#endif
else
integrity-= 2
else
if(integrity < maxintegrity)
integrity++
if(leaking)
integrity++
if(integrity == maxintegrity)
leaking = 0
/////////////////////////////////
///Prewelded tanks
/////////////////////////////////
/obj/item/weapon/tank/phoron/welded
valve_welded = 1
/obj/item/weapon/tank/oxygen/welded
valve_welded = 1
/////////////////////////////////
///Onetankbombs (added as actual items)
/////////////////////////////////
/obj/item/weapon/tank/proc/onetankbomb(var/fill = 1)
var/phoron_amt = 4 + rand(4)
var/oxygen_amt = 6 + rand(8)
if(fill == 2)
phoron_amt = 10
oxygen_amt = 15
else if (!fill)
phoron_amt = 3
oxygen_amt = 4.5
src.air_contents.gas["phoron"] = phoron_amt
src.air_contents.gas["oxygen"] = oxygen_amt
src.air_contents.update_values()
src.valve_welded = 1
src.air_contents.temperature = PHORON_MINIMUM_BURN_TEMPERATURE-1
src.wired = 1
var/obj/item/device/assembly_holder/H = new(src)
src.proxyassembly.assembly = H
H.master = src.proxyassembly
H.update_icon()
src.overlays += "bomb_assembly"
/obj/item/weapon/tank/phoron/onetankbomb/New()
..()
src.onetankbomb()
/obj/item/weapon/tank/oxygen/onetankbomb/New()
..()
src.onetankbomb()
/obj/item/weapon/tank/phoron/onetankbomb/full/New()
..()
src.onetankbomb(2)
/obj/item/weapon/tank/oxygen/onetankbomb/full/New()
..()
src.onetankbomb(2)
/obj/item/weapon/tank/phoron/onetankbomb/small/New()
..()
src.onetankbomb(0)
/obj/item/weapon/tank/oxygen/onetankbomb/small/New()
..()
src.onetankbomb(1)
/////////////////////////////////
///Pulled from rewritten bomb.dm
/////////////////////////////////
/obj/item/device/tankassemblyproxy
name = "Tank assembly proxy"
desc = "Used as a stand in to trigger single tank assemblies... but you shouldn't see this."
var/obj/item/weapon/tank/tank = null
var/obj/item/device/assembly_holder/assembly = null
/obj/item/device/tankassemblyproxy/receive_signal() //This is mainly called by the sensor through sense() to the holder, and from the holder to here.
tank.ignite() //boom (or not boom if you made shijwtty mix)
/obj/item/weapon/tank/proc/assemble_bomb(W,user) //Bomb assembly proc. This turns assembly+tank into a bomb
var/obj/item/device/assembly_holder/S = W
var/mob/M = user
if(!S.secured) //Check if the assembly is secured
return
if(isigniter(S.a_left) == isigniter(S.a_right)) //Check if either part of the assembly has an igniter, but if both parts are igniters, then fuck it
return
M.drop_item() //Remove the assembly from your hands
M.remove_from_mob(src) //Remove the tank from your character,in case you were holding it
M.put_in_hands(src) //Equips the bomb if possible, or puts it on the floor.
src.proxyassembly.assembly = S //Tell the bomb about its assembly part
S.master = src.proxyassembly //Tell the assembly about its new owner
S.forceMove(src) //Move the assembly
src.update_icon()
src.add_bomb_overlay()
return
/obj/item/weapon/tank/proc/ignite() //This happens when a bomb is told to explode
var/obj/item/device/assembly_holder/assy = src.proxyassembly.assembly
var/ign = assy.a_right
var/obj/item/other = assy.a_left
if (isigniter(assy.a_left))
ign = assy.a_left
other = assy.a_right
other.dropInto(get_turf(src))
qdel(ign)
assy.master = null
src.proxyassembly.assembly = null
qdel(assy)
src.update_icon()
src.update_gauge()
air_contents.add_thermal_energy(15000)
/obj/item/device/tankassemblyproxy/update_icon()
if(assembly)
tank.update_icon()
tank.overlays += "bomb_assembly"
else
tank.update_icon()
tank.overlays -= "bomb_assembly"
/obj/item/device/tankassemblyproxy/HasProximity(atom/movable/AM as mob|obj)
if(src.assembly)
src.assembly.HasProximity(AM)
/obj/item/projectile/bullet/pellet/fragment/tank
name = "metal fragment"
damage = 9 //Big chunks flying off.
range_step = 2 //controls damage falloff with distance. projectiles lose a "pellet" each time they travel this distance. Can be a non-integer.
base_spread = 0 //causes it to be treated as a shrapnel explosion instead of cone
spread_step = 20
armor_penetration = 20
silenced = 1
no_attack_log = 1
muzzle_type = null
pellets = 3
/obj/item/projectile/bullet/pellet/fragment/tank/small
name = "small metal fragment"
damage = 6
armor_penetration = 5
pellets = 5
/obj/item/projectile/bullet/pellet/fragment/tank/big
name = "large metal fragment"
damage = 17
armor_penetration = 10
range_step = 5 //controls damage falloff with distance. projectiles lose a "pellet" each time they travel this distance. Can be a non-integer.
pellets = 1

View File

@@ -1,155 +0,0 @@
/obj/item/device/onetankbomb
name = "bomb"
icon = 'icons/obj/tank.dmi'
item_state = "assembly"
throwforce = 5
w_class = ITEMSIZE_NORMAL
throw_speed = 2
throw_range = 4
flags = CONDUCT | PROXMOVE
var/status = 0 //0 - not readied //1 - bomb finished with welder
var/obj/item/device/assembly_holder/bombassembly = null //The first part of the bomb is an assembly holder, holding an igniter+some device
var/obj/item/weapon/tank/bombtank = null //the second part of the bomb is a phoron tank
/obj/item/device/onetankbomb/examine(mob/user)
..(user)
user.examinate(bombtank)
/obj/item/device/onetankbomb/update_icon()
if(bombtank)
icon_state = bombtank.icon_state
if(bombassembly)
overlays += bombassembly.icon_state
overlays += bombassembly.overlays
overlays += "bomb_assembly"
/obj/item/device/onetankbomb/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/device/analyzer))
bombtank.attackby(W, user)
return
if(istype(W, /obj/item/weapon/wrench) && !status) //This is basically bomb assembly code inverted. apparently it works.
user << "<span class='notice'>You disassemble [src].</span>"
bombassembly.loc = user.loc
bombassembly.master = null
bombassembly = null
bombtank.loc = user.loc
bombtank.master = null
bombtank = null
qdel(src)
return
if((istype(W, /obj/item/weapon/weldingtool) && W:welding))
if(!status)
status = 1
bombers += "[key_name(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]"
message_admins("[key_name_admin(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]")
user << "<span class='notice'>A pressure hole has been bored to [bombtank] valve. \The [bombtank] can now be ignited.</span>"
else
status = 0
bombers += "[key_name(user)] unwelded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]"
user << "<span class='notice'>The hole has been closed.</span>"
add_fingerprint(user)
..()
/obj/item/device/onetankbomb/attack_self(mob/user as mob) //pressing the bomb accesses its assembly
bombassembly.attack_self(user, 1)
add_fingerprint(user)
return
/obj/item/device/onetankbomb/receive_signal() //This is mainly called by the sensor through sense() to the holder, and from the holder to here.
visible_message("\icon[src] *beep* *beep*", "*beep* *beep*")
sleep(10)
if(!src)
return
if(status)
bombtank.ignite() //if its not a dud, boom (or not boom if you made shitty mix) the ignite proc is below, in this file
else
bombtank.release()
/obj/item/device/onetankbomb/HasProximity(atom/movable/AM as mob|obj)
if(bombassembly)
bombassembly.HasProximity(AM)
// ---------- Procs below are for tanks that are used exclusively in 1-tank bombs ----------
/obj/item/weapon/tank/proc/bomb_assemble(W,user) //Bomb assembly proc. This turns assembly+tank into a bomb
var/obj/item/device/assembly_holder/S = W
var/mob/M = user
if(!S.secured) //Check if the assembly is secured
return
if(isigniter(S.a_left) == isigniter(S.a_right)) //Check if either part of the assembly has an igniter, but if both parts are igniters, then fuck it
return
var/obj/item/device/onetankbomb/R = new /obj/item/device/onetankbomb(loc)
M.drop_item() //Remove the assembly from your hands
M.remove_from_mob(src) //Remove the tank from your character,in case you were holding it
M.put_in_hands(R) //Equips the bomb if possible, or puts it on the floor.
R.bombassembly = S //Tell the bomb about its assembly part
S.master = R //Tell the assembly about its new owner
S.loc = R //Move the assembly out of the fucking way
R.bombtank = src //Same for tank
master = R
loc = R
R.update_icon()
return
/obj/item/weapon/tank/proc/ignite() //This happens when a bomb is told to explode
var/fuel_moles = air_contents.gas["phoron"] + air_contents.gas["oxygen"] / 6
var/strength = 1
var/turf/ground_zero = get_turf(loc)
loc = null
if(air_contents.temperature > (T0C + 400))
strength = (fuel_moles/15)
if(strength >=1)
explosion(ground_zero, round(strength,1), round(strength*2,1), round(strength*3,1), round(strength*4,1))
else if(strength >=0.5)
explosion(ground_zero, 0, 1, 2, 4)
else if(strength >=0.2)
explosion(ground_zero, -1, 0, 1, 2)
else
ground_zero.assume_air(air_contents)
ground_zero.hotspot_expose(1000, 125)
else if(air_contents.temperature > (T0C + 250))
strength = (fuel_moles/20)
if(strength >=1)
explosion(ground_zero, 0, round(strength,1), round(strength*2,1), round(strength*3,1))
else if (strength >=0.5)
explosion(ground_zero, -1, 0, 1, 2)
else
ground_zero.assume_air(air_contents)
ground_zero.hotspot_expose(1000, 125)
else if(air_contents.temperature > (T0C + 100))
strength = (fuel_moles/25)
if (strength >=1)
explosion(ground_zero, -1, 0, round(strength,1), round(strength*3,1))
else
ground_zero.assume_air(air_contents)
ground_zero.hotspot_expose(1000, 125)
else
ground_zero.assume_air(air_contents)
ground_zero.hotspot_expose(1000, 125)
if(master)
qdel(master)
qdel(src)
/obj/item/weapon/tank/proc/release() //This happens when the bomb is not welded. Tank contents are just spat out.
var/datum/gas_mixture/removed = air_contents.remove(air_contents.total_moles)
var/turf/simulated/T = get_turf(src)
if(!T)
return
T.assume_air(removed)

View File

@@ -86,8 +86,8 @@ var/global/list/datum/supply_drop_loot/supply_drop
/obj/item/ammo_magazine/m762/ap,
/obj/item/ammo_magazine/m762,
/obj/item/weapon/shield/energy,
/obj/item/weapon/grenade/frag,
/obj/item/weapon/grenade/frag,
/obj/item/weapon/grenade/explosive/frag,
/obj/item/weapon/grenade/explosive/frag,
/obj/item/weapon/grenade/smokebomb,
/obj/item/weapon/grenade/smokebomb,
/obj/item/weapon/grenade/flashbang,

View File

@@ -902,7 +902,6 @@
#include "code\game\objects\items\weapons\grenades\emgrenade.dm"
#include "code\game\objects\items\weapons\grenades\explosive.dm"
#include "code\game\objects\items\weapons\grenades\flashbang.dm"
#include "code\game\objects\items\weapons\grenades\fragmentation.dm"
#include "code\game\objects\items\weapons\grenades\grenade.dm"
#include "code\game\objects\items\weapons\grenades\smokebomb.dm"
#include "code\game\objects\items\weapons\grenades\spawnergrenade.dm"
@@ -1156,7 +1155,6 @@
#include "code\modules\alarm\motion_alarm.dm"
#include "code\modules\alarm\power_alarm.dm"
#include "code\modules\assembly\assembly.dm"
#include "code\modules\assembly\bomb.dm"
#include "code\modules\assembly\helpers.dm"
#include "code\modules\assembly\holder.dm"
#include "code\modules\assembly\igniter.dm"