Increases performance significantly by turning garbage collection into a define

This commit is contained in:
deathride58
2019-04-14 11:33:28 -04:00
parent 2c9deab42e
commit 41375d9737
22 changed files with 5081 additions and 5090 deletions

View File

@@ -239,6 +239,8 @@
//HELPERS //HELPERS
#define THERMAL_ENERGY(gas) (gas.temperature * gas.heat_capacity()) #define THERMAL_ENERGY(gas) (gas.temperature * gas.heat_capacity())
#define QUANTIZE(variable) (round(variable,0.0000001))/*I feel the need to document what happens here. Basically this is used to catch most rounding errors, however it's previous value made it so that
once gases got hot enough, most procedures wouldnt occur due to the fact that the mole counts would get rounded away. Thus, we lowered it a few orders of magnititude */
//prefer this to gas_mixture/total_moles in performance critical areas //prefer this to gas_mixture/total_moles in performance critical areas
#define TOTAL_MOLES(cached_gases, out_var)\ #define TOTAL_MOLES(cached_gases, out_var)\
@@ -247,6 +249,14 @@
out_var += cached_gases[total_moles_id];\ out_var += cached_gases[total_moles_id];\
} }
//Unomos - So for whatever reason, garbage collection actually drastically decreases the cost of atmos later in the round. Turning this into a define yields massively improved performance.
#define GAS_GARBAGE_COLLECT(GASGASGAS)\
var/list/CACHE_GAS = GASGASGAS;\
for(var/id in CACHE_GAS){\
if(QUANTIZE(CACHE_GAS[id]) <= 0)\
CACHE_GAS -= id;\
}
#define ARCHIVE_TEMPERATURE(gas) gas.temperature_archived = gas.temperature #define ARCHIVE_TEMPERATURE(gas) gas.temperature_archived = gas.temperature
GLOBAL_LIST_INIT(pipe_paint_colors, list( GLOBAL_LIST_INIT(pipe_paint_colors, list(

View File

@@ -1,347 +1,347 @@
// Foam // Foam
// Similar to smoke, but slower and mobs absorb its reagent through their exposed skin. // Similar to smoke, but slower and mobs absorb its reagent through their exposed skin.
#define ALUMINUM_FOAM 1 #define ALUMINUM_FOAM 1
#define IRON_FOAM 2 #define IRON_FOAM 2
#define RESIN_FOAM 3 #define RESIN_FOAM 3
/obj/effect/particle_effect/foam /obj/effect/particle_effect/foam
name = "foam" name = "foam"
icon_state = "foam" icon_state = "foam"
opacity = 0 opacity = 0
anchored = TRUE anchored = TRUE
density = FALSE density = FALSE
layer = EDGED_TURF_LAYER layer = EDGED_TURF_LAYER
mouse_opacity = MOUSE_OPACITY_TRANSPARENT mouse_opacity = MOUSE_OPACITY_TRANSPARENT
var/amount = 3 var/amount = 3
animate_movement = 0 animate_movement = 0
var/metal = 0 var/metal = 0
var/lifetime = 40 var/lifetime = 40
var/reagent_divisor = 7 var/reagent_divisor = 7
var/static/list/blacklisted_turfs = typecacheof(list( var/static/list/blacklisted_turfs = typecacheof(list(
/turf/open/space/transit, /turf/open/space/transit,
/turf/open/chasm, /turf/open/chasm,
/turf/open/lava)) /turf/open/lava))
/obj/effect/particle_effect/foam/firefighting /obj/effect/particle_effect/foam/firefighting
name = "firefighting foam" name = "firefighting foam"
lifetime = 20 //doesn't last as long as normal foam lifetime = 20 //doesn't last as long as normal foam
amount = 0 //no spread amount = 0 //no spread
var/absorbed_plasma = 0 var/absorbed_plasma = 0
/obj/effect/particle_effect/foam/firefighting/MakeSlippery() /obj/effect/particle_effect/foam/firefighting/MakeSlippery()
return return
/obj/effect/particle_effect/foam/firefighting/process() /obj/effect/particle_effect/foam/firefighting/process()
..() ..()
var/turf/open/T = get_turf(src) var/turf/open/T = get_turf(src)
var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T) var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T)
if(hotspot && istype(T) && T.air) if(hotspot && istype(T) && T.air)
qdel(hotspot) qdel(hotspot)
var/datum/gas_mixture/G = T.air var/datum/gas_mixture/G = T.air
var/plas_amt = min(30,G.gases[/datum/gas/plasma]) //Absorb some plasma var/plas_amt = min(30,G.gases[/datum/gas/plasma]) //Absorb some plasma
G.gases[/datum/gas/plasma] -= plas_amt G.gases[/datum/gas/plasma] -= plas_amt
absorbed_plasma += plas_amt absorbed_plasma += plas_amt
if(G.temperature > T20C) if(G.temperature > T20C)
G.temperature = max(G.temperature/2,T20C) G.temperature = max(G.temperature/2,T20C)
G.garbage_collect() GAS_GARBAGE_COLLECT(G.gases)
T.air_update_turf() T.air_update_turf()
/obj/effect/particle_effect/foam/firefighting/kill_foam() /obj/effect/particle_effect/foam/firefighting/kill_foam()
STOP_PROCESSING(SSfastprocess, src) STOP_PROCESSING(SSfastprocess, src)
if(absorbed_plasma) if(absorbed_plasma)
var/obj/effect/decal/cleanable/plasma/P = (locate(/obj/effect/decal/cleanable/plasma) in get_turf(src)) var/obj/effect/decal/cleanable/plasma/P = (locate(/obj/effect/decal/cleanable/plasma) in get_turf(src))
if(!P) if(!P)
P = new(loc) P = new(loc)
P.reagents.add_reagent("stable_plasma", absorbed_plasma) P.reagents.add_reagent("stable_plasma", absorbed_plasma)
flick("[icon_state]-disolve", src) flick("[icon_state]-disolve", src)
QDEL_IN(src, 5) QDEL_IN(src, 5)
/obj/effect/particle_effect/foam/firefighting/foam_mob(mob/living/L) /obj/effect/particle_effect/foam/firefighting/foam_mob(mob/living/L)
if(!istype(L)) if(!istype(L))
return return
L.adjust_fire_stacks(-2) L.adjust_fire_stacks(-2)
L.ExtinguishMob() L.ExtinguishMob()
/obj/effect/particle_effect/foam/firefighting/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) /obj/effect/particle_effect/foam/firefighting/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
return return
/obj/effect/particle_effect/foam/metal /obj/effect/particle_effect/foam/metal
name = "aluminium foam" name = "aluminium foam"
metal = ALUMINUM_FOAM metal = ALUMINUM_FOAM
icon_state = "mfoam" icon_state = "mfoam"
/obj/effect/particle_effect/foam/metal/MakeSlippery() /obj/effect/particle_effect/foam/metal/MakeSlippery()
return return
/obj/effect/particle_effect/foam/metal/smart /obj/effect/particle_effect/foam/metal/smart
name = "smart foam" name = "smart foam"
/obj/effect/particle_effect/foam/metal/iron /obj/effect/particle_effect/foam/metal/iron
name = "iron foam" name = "iron foam"
metal = IRON_FOAM metal = IRON_FOAM
/obj/effect/particle_effect/foam/metal/resin /obj/effect/particle_effect/foam/metal/resin
name = "resin foam" name = "resin foam"
metal = RESIN_FOAM metal = RESIN_FOAM
/obj/effect/particle_effect/foam/long_life /obj/effect/particle_effect/foam/long_life
lifetime = 150 lifetime = 150
/obj/effect/particle_effect/foam/Initialize() /obj/effect/particle_effect/foam/Initialize()
. = ..() . = ..()
MakeSlippery() MakeSlippery()
create_reagents(1000) //limited by the size of the reagent holder anyway. create_reagents(1000) //limited by the size of the reagent holder anyway.
START_PROCESSING(SSfastprocess, src) START_PROCESSING(SSfastprocess, src)
playsound(src, 'sound/effects/bubbles2.ogg', 80, 1, -3) playsound(src, 'sound/effects/bubbles2.ogg', 80, 1, -3)
/obj/effect/particle_effect/foam/proc/MakeSlippery() /obj/effect/particle_effect/foam/proc/MakeSlippery()
AddComponent(/datum/component/slippery, 100) AddComponent(/datum/component/slippery, 100)
/obj/effect/particle_effect/foam/Destroy() /obj/effect/particle_effect/foam/Destroy()
STOP_PROCESSING(SSfastprocess, src) STOP_PROCESSING(SSfastprocess, src)
return ..() return ..()
/obj/effect/particle_effect/foam/proc/kill_foam() /obj/effect/particle_effect/foam/proc/kill_foam()
STOP_PROCESSING(SSfastprocess, src) STOP_PROCESSING(SSfastprocess, src)
switch(metal) switch(metal)
if(ALUMINUM_FOAM) if(ALUMINUM_FOAM)
new /obj/structure/foamedmetal(get_turf(src)) new /obj/structure/foamedmetal(get_turf(src))
if(IRON_FOAM) if(IRON_FOAM)
new /obj/structure/foamedmetal/iron(get_turf(src)) new /obj/structure/foamedmetal/iron(get_turf(src))
if(RESIN_FOAM) if(RESIN_FOAM)
new /obj/structure/foamedmetal/resin(get_turf(src)) new /obj/structure/foamedmetal/resin(get_turf(src))
flick("[icon_state]-disolve", src) flick("[icon_state]-disolve", src)
QDEL_IN(src, 5) QDEL_IN(src, 5)
/obj/effect/particle_effect/foam/smart/kill_foam() //Smart foam adheres to area borders for walls /obj/effect/particle_effect/foam/smart/kill_foam() //Smart foam adheres to area borders for walls
STOP_PROCESSING(SSfastprocess, src) STOP_PROCESSING(SSfastprocess, src)
if(metal) if(metal)
var/turf/T = get_turf(src) var/turf/T = get_turf(src)
if(isspaceturf(T)) //Block up any exposed space if(isspaceturf(T)) //Block up any exposed space
T.PlaceOnTop(/turf/open/floor/plating/foam) T.PlaceOnTop(/turf/open/floor/plating/foam)
for(var/direction in GLOB.cardinals) for(var/direction in GLOB.cardinals)
var/turf/cardinal_turf = get_step(T, direction) var/turf/cardinal_turf = get_step(T, direction)
if(get_area(cardinal_turf) != get_area(T)) //We're at an area boundary, so let's block off this turf! if(get_area(cardinal_turf) != get_area(T)) //We're at an area boundary, so let's block off this turf!
new/obj/structure/foamedmetal(T) new/obj/structure/foamedmetal(T)
break break
flick("[icon_state]-disolve", src) flick("[icon_state]-disolve", src)
QDEL_IN(src, 5) QDEL_IN(src, 5)
/obj/effect/particle_effect/foam/process() /obj/effect/particle_effect/foam/process()
lifetime-- lifetime--
if(lifetime < 1) if(lifetime < 1)
kill_foam() kill_foam()
return return
var/fraction = 1/initial(reagent_divisor) var/fraction = 1/initial(reagent_divisor)
for(var/obj/O in range(0,src)) for(var/obj/O in range(0,src))
if(O.type == src.type) if(O.type == src.type)
continue continue
if(isturf(O.loc)) if(isturf(O.loc))
var/turf/T = O.loc var/turf/T = O.loc
if(T.intact && O.level == 1) //hidden under the floor if(T.intact && O.level == 1) //hidden under the floor
continue continue
if(lifetime % reagent_divisor) if(lifetime % reagent_divisor)
reagents.reaction(O, VAPOR, fraction) reagents.reaction(O, VAPOR, fraction)
var/hit = 0 var/hit = 0
for(var/mob/living/L in range(0,src)) for(var/mob/living/L in range(0,src))
hit += foam_mob(L) hit += foam_mob(L)
if(hit) if(hit)
lifetime++ //this is so the decrease from mobs hit and the natural decrease don't cumulate. lifetime++ //this is so the decrease from mobs hit and the natural decrease don't cumulate.
var/T = get_turf(src) var/T = get_turf(src)
if(lifetime % reagent_divisor) if(lifetime % reagent_divisor)
reagents.reaction(T, VAPOR, fraction) reagents.reaction(T, VAPOR, fraction)
if(--amount < 0) if(--amount < 0)
return return
spread_foam() spread_foam()
/obj/effect/particle_effect/foam/proc/foam_mob(mob/living/L) /obj/effect/particle_effect/foam/proc/foam_mob(mob/living/L)
if(lifetime<1) if(lifetime<1)
return 0 return 0
if(!istype(L)) if(!istype(L))
return 0 return 0
var/fraction = 1/initial(reagent_divisor) var/fraction = 1/initial(reagent_divisor)
if(lifetime % reagent_divisor) if(lifetime % reagent_divisor)
reagents.reaction(L, VAPOR, fraction) reagents.reaction(L, VAPOR, fraction)
lifetime-- lifetime--
return 1 return 1
/obj/effect/particle_effect/foam/proc/spread_foam() /obj/effect/particle_effect/foam/proc/spread_foam()
var/turf/t_loc = get_turf(src) var/turf/t_loc = get_turf(src)
for(var/turf/T in t_loc.GetAtmosAdjacentTurfs()) for(var/turf/T in t_loc.GetAtmosAdjacentTurfs())
var/obj/effect/particle_effect/foam/foundfoam = locate() in T //Don't spread foam where there's already foam! var/obj/effect/particle_effect/foam/foundfoam = locate() in T //Don't spread foam where there's already foam!
if(foundfoam) if(foundfoam)
continue continue
if(is_type_in_typecache(T, blacklisted_turfs)) if(is_type_in_typecache(T, blacklisted_turfs))
continue continue
for(var/mob/living/L in T) for(var/mob/living/L in T)
foam_mob(L) foam_mob(L)
var/obj/effect/particle_effect/foam/F = new src.type(T) var/obj/effect/particle_effect/foam/F = new src.type(T)
F.amount = amount F.amount = amount
reagents.copy_to(F, (reagents.total_volume)) reagents.copy_to(F, (reagents.total_volume))
F.add_atom_colour(color, FIXED_COLOUR_PRIORITY) F.add_atom_colour(color, FIXED_COLOUR_PRIORITY)
F.metal = metal F.metal = metal
/obj/effect/particle_effect/foam/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) /obj/effect/particle_effect/foam/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(prob(max(0, exposed_temperature - 475))) //foam dissolves when heated if(prob(max(0, exposed_temperature - 475))) //foam dissolves when heated
kill_foam() kill_foam()
/obj/effect/particle_effect/foam/metal/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) /obj/effect/particle_effect/foam/metal/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
return return
/////////////////////////////////////////////// ///////////////////////////////////////////////
//FOAM EFFECT DATUM //FOAM EFFECT DATUM
/datum/effect_system/foam_spread /datum/effect_system/foam_spread
var/amount = 10 // the size of the foam spread. var/amount = 10 // the size of the foam spread.
var/obj/chemholder var/obj/chemholder
effect_type = /obj/effect/particle_effect/foam effect_type = /obj/effect/particle_effect/foam
var/metal = 0 var/metal = 0
/datum/effect_system/foam_spread/metal /datum/effect_system/foam_spread/metal
effect_type = /obj/effect/particle_effect/foam/metal effect_type = /obj/effect/particle_effect/foam/metal
/datum/effect_system/foam_spread/metal/smart /datum/effect_system/foam_spread/metal/smart
effect_type = /obj/effect/particle_effect/foam/smart effect_type = /obj/effect/particle_effect/foam/smart
/datum/effect_system/foam_spread/long /datum/effect_system/foam_spread/long
effect_type = /obj/effect/particle_effect/foam/long_life effect_type = /obj/effect/particle_effect/foam/long_life
/datum/effect_system/foam_spread/New() /datum/effect_system/foam_spread/New()
..() ..()
chemholder = new /obj() chemholder = new /obj()
var/datum/reagents/R = new/datum/reagents(1000) var/datum/reagents/R = new/datum/reagents(1000)
chemholder.reagents = R chemholder.reagents = R
R.my_atom = chemholder R.my_atom = chemholder
/datum/effect_system/foam_spread/Destroy() /datum/effect_system/foam_spread/Destroy()
qdel(chemholder) qdel(chemholder)
chemholder = null chemholder = null
return ..() return ..()
/datum/effect_system/foam_spread/set_up(amt=5, loca, datum/reagents/carry = null) /datum/effect_system/foam_spread/set_up(amt=5, loca, datum/reagents/carry = null)
if(isturf(loca)) if(isturf(loca))
location = loca location = loca
else else
location = get_turf(loca) location = get_turf(loca)
amount = round(sqrt(amt / 2), 1) amount = round(sqrt(amt / 2), 1)
carry.copy_to(chemholder, carry.total_volume) carry.copy_to(chemholder, carry.total_volume)
/datum/effect_system/foam_spread/metal/set_up(amt=5, loca, datum/reagents/carry = null, metaltype) /datum/effect_system/foam_spread/metal/set_up(amt=5, loca, datum/reagents/carry = null, metaltype)
..() ..()
metal = metaltype metal = metaltype
/datum/effect_system/foam_spread/start() /datum/effect_system/foam_spread/start()
var/obj/effect/particle_effect/foam/F = new effect_type(location) var/obj/effect/particle_effect/foam/F = new effect_type(location)
var/foamcolor = mix_color_from_reagents(chemholder.reagents.reagent_list) var/foamcolor = mix_color_from_reagents(chemholder.reagents.reagent_list)
chemholder.reagents.copy_to(F, chemholder.reagents.total_volume/amount) chemholder.reagents.copy_to(F, chemholder.reagents.total_volume/amount)
F.add_atom_colour(foamcolor, FIXED_COLOUR_PRIORITY) F.add_atom_colour(foamcolor, FIXED_COLOUR_PRIORITY)
F.amount = amount F.amount = amount
F.metal = metal F.metal = metal
////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////
// FOAM STRUCTURE. Formed by metal foams. Dense and opaque, but easy to break // FOAM STRUCTURE. Formed by metal foams. Dense and opaque, but easy to break
/obj/structure/foamedmetal /obj/structure/foamedmetal
icon = 'icons/effects/effects.dmi' icon = 'icons/effects/effects.dmi'
icon_state = "metalfoam" icon_state = "metalfoam"
density = TRUE density = TRUE
opacity = 1 // changed in New() opacity = 1 // changed in New()
anchored = TRUE anchored = TRUE
layer = EDGED_TURF_LAYER layer = EDGED_TURF_LAYER
resistance_flags = FIRE_PROOF | ACID_PROOF resistance_flags = FIRE_PROOF | ACID_PROOF
name = "foamed metal" name = "foamed metal"
desc = "A lightweight foamed metal wall." desc = "A lightweight foamed metal wall."
gender = PLURAL gender = PLURAL
max_integrity = 20 max_integrity = 20
CanAtmosPass = ATMOS_PASS_DENSITY CanAtmosPass = ATMOS_PASS_DENSITY
/obj/structure/foamedmetal/Initialize() /obj/structure/foamedmetal/Initialize()
. = ..() . = ..()
air_update_turf(1) air_update_turf(1)
/obj/structure/foamedmetal/Move() /obj/structure/foamedmetal/Move()
var/turf/T = loc var/turf/T = loc
. = ..() . = ..()
move_update_air(T) move_update_air(T)
/obj/structure/foamedmetal/attack_paw(mob/user) /obj/structure/foamedmetal/attack_paw(mob/user)
return attack_hand(user) return attack_hand(user)
/obj/structure/foamedmetal/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) /obj/structure/foamedmetal/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1) playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1)
/obj/structure/foamedmetal/attack_hand(mob/user) /obj/structure/foamedmetal/attack_hand(mob/user)
. = ..() . = ..()
if(.) if(.)
return return
user.changeNext_move(CLICK_CD_MELEE) user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src, ATTACK_EFFECT_PUNCH) user.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
to_chat(user, "<span class='warning'>You hit [src] but bounce off it!</span>") to_chat(user, "<span class='warning'>You hit [src] but bounce off it!</span>")
playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1) playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1)
/obj/structure/foamedmetal/CanPass(atom/movable/mover, turf/target) /obj/structure/foamedmetal/CanPass(atom/movable/mover, turf/target)
return !density return !density
/obj/structure/foamedmetal/iron /obj/structure/foamedmetal/iron
max_integrity = 50 max_integrity = 50
icon_state = "ironfoam" icon_state = "ironfoam"
//Atmos Backpack Resin, transparent, prevents atmos and filters the air //Atmos Backpack Resin, transparent, prevents atmos and filters the air
/obj/structure/foamedmetal/resin /obj/structure/foamedmetal/resin
name = "\improper ATMOS Resin" name = "\improper ATMOS Resin"
desc = "A lightweight, transparent resin used to suffocate fires, scrub the air of toxins, and restore the air to a safe temperature." desc = "A lightweight, transparent resin used to suffocate fires, scrub the air of toxins, and restore the air to a safe temperature."
opacity = FALSE opacity = FALSE
icon_state = "atmos_resin" icon_state = "atmos_resin"
alpha = 120 alpha = 120
max_integrity = 10 max_integrity = 10
/obj/structure/foamedmetal/resin/Initialize() /obj/structure/foamedmetal/resin/Initialize()
. = ..() . = ..()
if(isopenturf(loc)) if(isopenturf(loc))
var/turf/open/O = loc var/turf/open/O = loc
O.ClearWet() O.ClearWet()
if(O.air) if(O.air)
var/datum/gas_mixture/G = O.air var/datum/gas_mixture/G = O.air
G.temperature = 293.15 G.temperature = 293.15
for(var/obj/effect/hotspot/H in O) for(var/obj/effect/hotspot/H in O)
qdel(H) qdel(H)
var/list/G_gases = G.gases var/list/G_gases = G.gases
for(var/I in G_gases) for(var/I in G_gases)
if(I == /datum/gas/oxygen || I == /datum/gas/nitrogen) if(I == /datum/gas/oxygen || I == /datum/gas/nitrogen)
continue continue
G_gases[I] = 0 G_gases[I] = 0
G.garbage_collect() GAS_GARBAGE_COLLECT(G.gases)
O.air_update_turf() O.air_update_turf()
for(var/obj/machinery/atmospherics/components/unary/U in O) for(var/obj/machinery/atmospherics/components/unary/U in O)
if(!U.welded) if(!U.welded)
U.welded = TRUE U.welded = TRUE
U.update_icon() U.update_icon()
U.visible_message("<span class='danger'>[U] sealed shut!</span>") U.visible_message("<span class='danger'>[U] sealed shut!</span>")
for(var/mob/living/L in O) for(var/mob/living/L in O)
L.ExtinguishMob() L.ExtinguishMob()
for(var/obj/item/Item in O) for(var/obj/item/Item in O)
Item.extinguish() Item.extinguish()
/obj/structure/foamedmetal/resin/CanPass(atom/movable/mover, turf/target) /obj/structure/foamedmetal/resin/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && (mover.pass_flags & PASSGLASS)) if(istype(mover) && (mover.pass_flags & PASSGLASS))
return TRUE return TRUE
. = ..() . = ..()
#undef ALUMINUM_FOAM #undef ALUMINUM_FOAM
#undef IRON_FOAM #undef IRON_FOAM
#undef RESIN_FOAM #undef RESIN_FOAM

View File

@@ -1,328 +1,328 @@
///////////////////////////////////////////// /////////////////////////////////////////////
//// SMOKE SYSTEMS //// SMOKE SYSTEMS
///////////////////////////////////////////// /////////////////////////////////////////////
/obj/effect/particle_effect/smoke /obj/effect/particle_effect/smoke
name = "smoke" name = "smoke"
icon = 'icons/effects/96x96.dmi' icon = 'icons/effects/96x96.dmi'
icon_state = "smoke" icon_state = "smoke"
pixel_x = -32 pixel_x = -32
pixel_y = -32 pixel_y = -32
opacity = 0 opacity = 0
layer = FLY_LAYER layer = FLY_LAYER
anchored = TRUE anchored = TRUE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT mouse_opacity = MOUSE_OPACITY_TRANSPARENT
animate_movement = 0 animate_movement = 0
var/amount = 4 var/amount = 4
var/lifetime = 5 var/lifetime = 5
var/opaque = 1 //whether the smoke can block the view when in enough amount var/opaque = 1 //whether the smoke can block the view when in enough amount
/obj/effect/particle_effect/smoke/proc/fade_out(frames = 16) /obj/effect/particle_effect/smoke/proc/fade_out(frames = 16)
if(alpha == 0) //Handle already transparent case if(alpha == 0) //Handle already transparent case
return return
if(frames == 0) if(frames == 0)
frames = 1 //We will just assume that by 0 frames, the coder meant "during one frame". frames = 1 //We will just assume that by 0 frames, the coder meant "during one frame".
var/step = alpha / frames var/step = alpha / frames
for(var/i = 0, i < frames, i++) for(var/i = 0, i < frames, i++)
alpha -= step alpha -= step
if(alpha < 160) if(alpha < 160)
set_opacity(0) //if we were blocking view, we aren't now because we're fading out set_opacity(0) //if we were blocking view, we aren't now because we're fading out
stoplag() stoplag()
/obj/effect/particle_effect/smoke/Initialize() /obj/effect/particle_effect/smoke/Initialize()
. = ..() . = ..()
create_reagents(500) create_reagents(500)
START_PROCESSING(SSobj, src) START_PROCESSING(SSobj, src)
/obj/effect/particle_effect/smoke/Destroy() /obj/effect/particle_effect/smoke/Destroy()
STOP_PROCESSING(SSobj, src) STOP_PROCESSING(SSobj, src)
return ..() return ..()
/obj/effect/particle_effect/smoke/proc/kill_smoke() /obj/effect/particle_effect/smoke/proc/kill_smoke()
STOP_PROCESSING(SSobj, src) STOP_PROCESSING(SSobj, src)
INVOKE_ASYNC(src, .proc/fade_out) INVOKE_ASYNC(src, .proc/fade_out)
QDEL_IN(src, 10) QDEL_IN(src, 10)
/obj/effect/particle_effect/smoke/process() /obj/effect/particle_effect/smoke/process()
lifetime-- lifetime--
if(lifetime < 1) if(lifetime < 1)
kill_smoke() kill_smoke()
return 0 return 0
for(var/mob/living/L in range(0,src)) for(var/mob/living/L in range(0,src))
smoke_mob(L) smoke_mob(L)
return 1 return 1
/obj/effect/particle_effect/smoke/proc/smoke_mob(mob/living/carbon/C) /obj/effect/particle_effect/smoke/proc/smoke_mob(mob/living/carbon/C)
if(!istype(C)) if(!istype(C))
return 0 return 0
if(lifetime<1) if(lifetime<1)
return 0 return 0
if(C.internal != null || C.has_smoke_protection()) if(C.internal != null || C.has_smoke_protection())
return 0 return 0
if(C.smoke_delay) if(C.smoke_delay)
return 0 return 0
C.smoke_delay++ C.smoke_delay++
addtimer(CALLBACK(src, .proc/remove_smoke_delay, C), 10) addtimer(CALLBACK(src, .proc/remove_smoke_delay, C), 10)
return 1 return 1
/obj/effect/particle_effect/smoke/proc/remove_smoke_delay(mob/living/carbon/C) /obj/effect/particle_effect/smoke/proc/remove_smoke_delay(mob/living/carbon/C)
if(C) if(C)
C.smoke_delay = 0 C.smoke_delay = 0
/obj/effect/particle_effect/smoke/proc/spread_smoke() /obj/effect/particle_effect/smoke/proc/spread_smoke()
var/turf/t_loc = get_turf(src) var/turf/t_loc = get_turf(src)
if(!t_loc) if(!t_loc)
return return
var/list/newsmokes = list() var/list/newsmokes = list()
for(var/turf/T in t_loc.GetAtmosAdjacentTurfs()) for(var/turf/T in t_loc.GetAtmosAdjacentTurfs())
var/obj/effect/particle_effect/smoke/foundsmoke = locate() in T //Don't spread smoke where there's already smoke! var/obj/effect/particle_effect/smoke/foundsmoke = locate() in T //Don't spread smoke where there's already smoke!
if(foundsmoke) if(foundsmoke)
continue continue
for(var/mob/living/L in T) for(var/mob/living/L in T)
smoke_mob(L) smoke_mob(L)
var/obj/effect/particle_effect/smoke/S = new type(T) var/obj/effect/particle_effect/smoke/S = new type(T)
reagents.copy_to(S, reagents.total_volume) reagents.copy_to(S, reagents.total_volume)
S.setDir(pick(GLOB.cardinals)) S.setDir(pick(GLOB.cardinals))
S.amount = amount-1 S.amount = amount-1
S.add_atom_colour(color, FIXED_COLOUR_PRIORITY) S.add_atom_colour(color, FIXED_COLOUR_PRIORITY)
S.lifetime = lifetime S.lifetime = lifetime
if(S.amount>0) if(S.amount>0)
if(opaque) if(opaque)
S.set_opacity(TRUE) S.set_opacity(TRUE)
newsmokes.Add(S) newsmokes.Add(S)
if(newsmokes.len) if(newsmokes.len)
spawn(1) //the smoke spreads rapidly but not instantly spawn(1) //the smoke spreads rapidly but not instantly
for(var/obj/effect/particle_effect/smoke/SM in newsmokes) for(var/obj/effect/particle_effect/smoke/SM in newsmokes)
SM.spread_smoke() SM.spread_smoke()
/datum/effect_system/smoke_spread /datum/effect_system/smoke_spread
var/amount = 10 var/amount = 10
effect_type = /obj/effect/particle_effect/smoke effect_type = /obj/effect/particle_effect/smoke
/datum/effect_system/smoke_spread/set_up(radius = 5, loca) /datum/effect_system/smoke_spread/set_up(radius = 5, loca)
if(isturf(loca)) if(isturf(loca))
location = loca location = loca
else else
location = get_turf(loca) location = get_turf(loca)
amount = radius amount = radius
/datum/effect_system/smoke_spread/start() /datum/effect_system/smoke_spread/start()
if(holder) if(holder)
location = get_turf(holder) location = get_turf(holder)
var/obj/effect/particle_effect/smoke/S = new effect_type(location) var/obj/effect/particle_effect/smoke/S = new effect_type(location)
S.amount = amount S.amount = amount
if(S.amount) if(S.amount)
S.spread_smoke() S.spread_smoke()
///////////////////////////////////////////// /////////////////////////////////////////////
// Bad smoke // Bad smoke
///////////////////////////////////////////// /////////////////////////////////////////////
/obj/effect/particle_effect/smoke/bad /obj/effect/particle_effect/smoke/bad
lifetime = 8 lifetime = 8
/obj/effect/particle_effect/smoke/bad/smoke_mob(mob/living/carbon/M) /obj/effect/particle_effect/smoke/bad/smoke_mob(mob/living/carbon/M)
if(..()) if(..())
M.drop_all_held_items() M.drop_all_held_items()
M.adjustOxyLoss(1) M.adjustOxyLoss(1)
M.emote("cough") M.emote("cough")
return 1 return 1
/obj/effect/particle_effect/smoke/bad/CanPass(atom/movable/mover, turf/target) /obj/effect/particle_effect/smoke/bad/CanPass(atom/movable/mover, turf/target)
if(istype(mover, /obj/item/projectile/beam)) if(istype(mover, /obj/item/projectile/beam))
var/obj/item/projectile/beam/B = mover var/obj/item/projectile/beam/B = mover
B.damage = (B.damage/2) B.damage = (B.damage/2)
return 1 return 1
/datum/effect_system/smoke_spread/bad /datum/effect_system/smoke_spread/bad
effect_type = /obj/effect/particle_effect/smoke/bad effect_type = /obj/effect/particle_effect/smoke/bad
///////////////////////////////////////////// /////////////////////////////////////////////
// Nanofrost smoke // Nanofrost smoke
///////////////////////////////////////////// /////////////////////////////////////////////
/obj/effect/particle_effect/smoke/freezing /obj/effect/particle_effect/smoke/freezing
name = "nanofrost smoke" name = "nanofrost smoke"
color = "#B2FFFF" color = "#B2FFFF"
opaque = 0 opaque = 0
/datum/effect_system/smoke_spread/freezing /datum/effect_system/smoke_spread/freezing
effect_type = /obj/effect/particle_effect/smoke/freezing effect_type = /obj/effect/particle_effect/smoke/freezing
var/blast = 0 var/blast = 0
var/temperature = 2 var/temperature = 2
var/weldvents = TRUE var/weldvents = TRUE
var/distcheck = TRUE var/distcheck = TRUE
/datum/effect_system/smoke_spread/freezing/proc/Chilled(atom/A) /datum/effect_system/smoke_spread/freezing/proc/Chilled(atom/A)
if(isopenturf(A)) if(isopenturf(A))
var/turf/open/T = A var/turf/open/T = A
if(T.air) if(T.air)
var/datum/gas_mixture/G = T.air var/datum/gas_mixture/G = T.air
if(!distcheck || get_dist(T, location) < blast) // Otherwise we'll get silliness like people using Nanofrost to kill people through walls with cold air if(!distcheck || get_dist(T, location) < blast) // Otherwise we'll get silliness like people using Nanofrost to kill people through walls with cold air
G.temperature = temperature G.temperature = temperature
T.air_update_turf() T.air_update_turf()
for(var/obj/effect/hotspot/H in T) for(var/obj/effect/hotspot/H in T)
qdel(H) qdel(H)
var/list/G_gases = G.gases var/list/G_gases = G.gases
if(G_gases[/datum/gas/plasma]) if(G_gases[/datum/gas/plasma])
G_gases[/datum/gas/nitrogen] += (G_gases[/datum/gas/plasma]) G_gases[/datum/gas/nitrogen] += (G_gases[/datum/gas/plasma])
G_gases[/datum/gas/plasma] = 0 G_gases[/datum/gas/plasma] = 0
G.garbage_collect() GAS_GARBAGE_COLLECT(G.gases)
if (weldvents) if (weldvents)
for(var/obj/machinery/atmospherics/components/unary/U in T) for(var/obj/machinery/atmospherics/components/unary/U in T)
if(!isnull(U.welded) && !U.welded) //must be an unwelded vent pump or vent scrubber. if(!isnull(U.welded) && !U.welded) //must be an unwelded vent pump or vent scrubber.
U.welded = TRUE U.welded = TRUE
U.update_icon() U.update_icon()
U.visible_message("<span class='danger'>[U] was frozen shut!</span>") U.visible_message("<span class='danger'>[U] was frozen shut!</span>")
for(var/mob/living/L in T) for(var/mob/living/L in T)
L.ExtinguishMob() L.ExtinguishMob()
for(var/obj/item/Item in T) for(var/obj/item/Item in T)
Item.extinguish() Item.extinguish()
/datum/effect_system/smoke_spread/freezing/set_up(radius = 5, loca, blast_radius = 0) /datum/effect_system/smoke_spread/freezing/set_up(radius = 5, loca, blast_radius = 0)
..() ..()
blast = blast_radius blast = blast_radius
/datum/effect_system/smoke_spread/freezing/start() /datum/effect_system/smoke_spread/freezing/start()
if(blast) if(blast)
for(var/turf/T in RANGE_TURFS(blast, location)) for(var/turf/T in RANGE_TURFS(blast, location))
Chilled(T) Chilled(T)
..() ..()
/datum/effect_system/smoke_spread/freezing/decon /datum/effect_system/smoke_spread/freezing/decon
temperature = 293.15 temperature = 293.15
distcheck = FALSE distcheck = FALSE
weldvents = FALSE weldvents = FALSE
///////////////////////////////////////////// /////////////////////////////////////////////
// Sleep smoke // Sleep smoke
///////////////////////////////////////////// /////////////////////////////////////////////
/obj/effect/particle_effect/smoke/sleeping /obj/effect/particle_effect/smoke/sleeping
color = "#9C3636" color = "#9C3636"
lifetime = 10 lifetime = 10
/obj/effect/particle_effect/smoke/sleeping/smoke_mob(mob/living/carbon/M) /obj/effect/particle_effect/smoke/sleeping/smoke_mob(mob/living/carbon/M)
if(..()) if(..())
M.Sleeping(200) M.Sleeping(200)
M.emote("cough") M.emote("cough")
return 1 return 1
/datum/effect_system/smoke_spread/sleeping /datum/effect_system/smoke_spread/sleeping
effect_type = /obj/effect/particle_effect/smoke/sleeping effect_type = /obj/effect/particle_effect/smoke/sleeping
///////////////////////////////////////////// /////////////////////////////////////////////
// Chem smoke // Chem smoke
///////////////////////////////////////////// /////////////////////////////////////////////
/obj/effect/particle_effect/smoke/chem /obj/effect/particle_effect/smoke/chem
lifetime = 10 lifetime = 10
/obj/effect/particle_effect/smoke/chem/process() /obj/effect/particle_effect/smoke/chem/process()
if(..()) if(..())
var/turf/T = get_turf(src) var/turf/T = get_turf(src)
var/fraction = 1/initial(lifetime) var/fraction = 1/initial(lifetime)
for(var/atom/movable/AM in T) for(var/atom/movable/AM in T)
if(AM.type == src.type) if(AM.type == src.type)
continue continue
if(T.intact && AM.level == 1) //hidden under the floor if(T.intact && AM.level == 1) //hidden under the floor
continue continue
reagents.reaction(AM, TOUCH, fraction) reagents.reaction(AM, TOUCH, fraction)
reagents.reaction(T, TOUCH, fraction) reagents.reaction(T, TOUCH, fraction)
return 1 return 1
/obj/effect/particle_effect/smoke/chem/smoke_mob(mob/living/carbon/M) /obj/effect/particle_effect/smoke/chem/smoke_mob(mob/living/carbon/M)
if(lifetime<1) if(lifetime<1)
return 0 return 0
if(!istype(M)) if(!istype(M))
return 0 return 0
var/mob/living/carbon/C = M var/mob/living/carbon/C = M
if(C.internal != null || C.has_smoke_protection()) if(C.internal != null || C.has_smoke_protection())
return 0 return 0
var/fraction = 1/initial(lifetime) var/fraction = 1/initial(lifetime)
reagents.copy_to(C, fraction*reagents.total_volume) reagents.copy_to(C, fraction*reagents.total_volume)
reagents.reaction(M, INGEST, fraction) reagents.reaction(M, INGEST, fraction)
return 1 return 1
/datum/effect_system/smoke_spread/chem /datum/effect_system/smoke_spread/chem
var/obj/chemholder var/obj/chemholder
effect_type = /obj/effect/particle_effect/smoke/chem effect_type = /obj/effect/particle_effect/smoke/chem
/datum/effect_system/smoke_spread/chem/New() /datum/effect_system/smoke_spread/chem/New()
..() ..()
chemholder = new /obj() chemholder = new /obj()
var/datum/reagents/R = new/datum/reagents(500) var/datum/reagents/R = new/datum/reagents(500)
chemholder.reagents = R chemholder.reagents = R
R.my_atom = chemholder R.my_atom = chemholder
/datum/effect_system/smoke_spread/chem/Destroy() /datum/effect_system/smoke_spread/chem/Destroy()
qdel(chemholder) qdel(chemholder)
chemholder = null chemholder = null
return ..() return ..()
/datum/effect_system/smoke_spread/chem/set_up(datum/reagents/carry = null, radius = 1, loca, silent = FALSE) /datum/effect_system/smoke_spread/chem/set_up(datum/reagents/carry = null, radius = 1, loca, silent = FALSE)
if(isturf(loca)) if(isturf(loca))
location = loca location = loca
else else
location = get_turf(loca) location = get_turf(loca)
amount = radius amount = radius
carry.copy_to(chemholder, carry.total_volume) carry.copy_to(chemholder, carry.total_volume)
if(!silent) if(!silent)
var/contained = "" var/contained = ""
for(var/reagent in carry.reagent_list) for(var/reagent in carry.reagent_list)
contained += " [reagent] " contained += " [reagent] "
if(contained) if(contained)
contained = "\[[contained]\]" contained = "\[[contained]\]"
var/where = "[AREACOORD(location)]" var/where = "[AREACOORD(location)]"
if(carry.my_atom.fingerprintslast) if(carry.my_atom.fingerprintslast)
var/mob/M = get_mob_by_key(carry.my_atom.fingerprintslast) var/mob/M = get_mob_by_key(carry.my_atom.fingerprintslast)
var/more = "" var/more = ""
if(M) if(M)
more = "[ADMIN_LOOKUPFLW(M)] " more = "[ADMIN_LOOKUPFLW(M)] "
message_admins("Smoke: ([ADMIN_VERBOSEJMP(location)])[contained]. Key: [more ? more : carry.my_atom.fingerprintslast].") message_admins("Smoke: ([ADMIN_VERBOSEJMP(location)])[contained]. Key: [more ? more : carry.my_atom.fingerprintslast].")
log_game("A chemical smoke reaction has taken place in ([where])[contained]. Last touched by [carry.my_atom.fingerprintslast].") log_game("A chemical smoke reaction has taken place in ([where])[contained]. Last touched by [carry.my_atom.fingerprintslast].")
else else
message_admins("Smoke: ([ADMIN_VERBOSEJMP(location)])[contained]. No associated key.") message_admins("Smoke: ([ADMIN_VERBOSEJMP(location)])[contained]. No associated key.")
log_game("A chemical smoke reaction has taken place in ([where])[contained]. No associated key.") log_game("A chemical smoke reaction has taken place in ([where])[contained]. No associated key.")
/datum/effect_system/smoke_spread/chem/start() /datum/effect_system/smoke_spread/chem/start()
var/mixcolor = mix_color_from_reagents(chemholder.reagents.reagent_list) var/mixcolor = mix_color_from_reagents(chemholder.reagents.reagent_list)
if(holder) if(holder)
location = get_turf(holder) location = get_turf(holder)
var/obj/effect/particle_effect/smoke/chem/S = new effect_type(location) var/obj/effect/particle_effect/smoke/chem/S = new effect_type(location)
if(chemholder.reagents.total_volume > 1) // can't split 1 very well if(chemholder.reagents.total_volume > 1) // can't split 1 very well
chemholder.reagents.copy_to(S, chemholder.reagents.total_volume) chemholder.reagents.copy_to(S, chemholder.reagents.total_volume)
if(mixcolor) if(mixcolor)
S.add_atom_colour(mixcolor, FIXED_COLOUR_PRIORITY) // give the smoke color, if it has any to begin with S.add_atom_colour(mixcolor, FIXED_COLOUR_PRIORITY) // give the smoke color, if it has any to begin with
S.amount = amount S.amount = amount
if(S.amount) if(S.amount)
S.spread_smoke() //calling process right now so the smoke immediately attacks mobs. S.spread_smoke() //calling process right now so the smoke immediately attacks mobs.
///////////////////////////////////////////// /////////////////////////////////////////////
// Transparent smoke // Transparent smoke
///////////////////////////////////////////// /////////////////////////////////////////////
//Same as the base type, but the smoke produced is not opaque //Same as the base type, but the smoke produced is not opaque
/datum/effect_system/smoke_spread/transparent /datum/effect_system/smoke_spread/transparent
effect_type = /obj/effect/particle_effect/smoke/transparent effect_type = /obj/effect/particle_effect/smoke/transparent
/obj/effect/particle_effect/smoke/transparent /obj/effect/particle_effect/smoke/transparent
opaque = FALSE opaque = FALSE

View File

@@ -444,7 +444,7 @@ SLIME SCANNER
else else
to_chat(user, "<span class='info'>Plasma: [round(plasma_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/plasma], 0.01)] mol)</span>") to_chat(user, "<span class='info'>Plasma: [round(plasma_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/plasma], 0.01)] mol)</span>")
environment.garbage_collect() GAS_GARBAGE_COLLECT(environment.gases)
for(var/id in env_gases) for(var/id in env_gases)
if(id in GLOB.hardcoded_gases) if(id in GLOB.hardcoded_gases)

View File

@@ -1,296 +1,296 @@
/turf/open /turf/open
plane = FLOOR_PLANE plane = FLOOR_PLANE
var/slowdown = 0 //negative for faster, positive for slower var/slowdown = 0 //negative for faster, positive for slower
var/postdig_icon_change = FALSE var/postdig_icon_change = FALSE
var/postdig_icon var/postdig_icon
var/wet var/wet
var/footstep = null var/footstep = null
/turf/open/ComponentInitialize() /turf/open/ComponentInitialize()
. = ..() . = ..()
if(wet) if(wet)
AddComponent(/datum/component/wet_floor, wet, INFINITY, 0, INFINITY, TRUE) AddComponent(/datum/component/wet_floor, wet, INFINITY, 0, INFINITY, TRUE)
/turf/open/MouseDrop_T(atom/dropping, mob/user) /turf/open/MouseDrop_T(atom/dropping, mob/user)
. = ..() . = ..()
if(dropping == user && isliving(user)) if(dropping == user && isliving(user))
var/mob/living/L = user var/mob/living/L = user
if(L.resting && do_after(L, max(10, L.getStaminaLoss()*0.5), 0, src)) if(L.resting && do_after(L, max(10, L.getStaminaLoss()*0.5), 0, src))
if(Adjacent(L, src)) if(Adjacent(L, src))
step(L, get_dir(L, src)) step(L, get_dir(L, src))
playsound(L, "rustle", 25, 1) playsound(L, "rustle", 25, 1)
/turf/open/indestructible /turf/open/indestructible
name = "floor" name = "floor"
icon = 'icons/turf/floors.dmi' icon = 'icons/turf/floors.dmi'
icon_state = "floor" icon_state = "floor"
footstep = FOOTSTEP_FLOOR footstep = FOOTSTEP_FLOOR
tiled_dirt = TRUE tiled_dirt = TRUE
/turf/open/indestructible/Melt() /turf/open/indestructible/Melt()
to_be_destroyed = FALSE to_be_destroyed = FALSE
return src return src
/turf/open/indestructible/singularity_act() /turf/open/indestructible/singularity_act()
return return
/turf/open/indestructible/TerraformTurf(path, defer_change = FALSE, ignore_air = FALSE) /turf/open/indestructible/TerraformTurf(path, defer_change = FALSE, ignore_air = FALSE)
return return
/turf/open/indestructible/sound /turf/open/indestructible/sound
name = "squeaky floor" name = "squeaky floor"
footstep = null footstep = null
var/sound var/sound
/turf/open/indestructible/sound/Entered(var/mob/AM) /turf/open/indestructible/sound/Entered(var/mob/AM)
..() ..()
if(istype(AM)) if(istype(AM))
playsound(src,sound,50,1) playsound(src,sound,50,1)
/turf/open/indestructible/cobble/side /turf/open/indestructible/cobble/side
icon_state = "cobble_side" icon_state = "cobble_side"
/turf/open/indestructible/cobble/corner /turf/open/indestructible/cobble/corner
icon_state = "cobble_corner" icon_state = "cobble_corner"
/turf/open/indestructible/cobble /turf/open/indestructible/cobble
name = "cobblestone path" name = "cobblestone path"
desc = "A simple but beautiful path made of various sized stones." desc = "A simple but beautiful path made of various sized stones."
icon = 'icons/turf/floors.dmi' icon = 'icons/turf/floors.dmi'
icon_state = "cobble" icon_state = "cobble"
baseturfs = /turf/open/indestructible/cobble baseturfs = /turf/open/indestructible/cobble
tiled_dirt = FALSE tiled_dirt = FALSE
/turf/open/indestructible/necropolis /turf/open/indestructible/necropolis
name = "necropolis floor" name = "necropolis floor"
desc = "It's regarding you suspiciously." desc = "It's regarding you suspiciously."
icon = 'icons/turf/floors.dmi' icon = 'icons/turf/floors.dmi'
icon_state = "necro1" icon_state = "necro1"
baseturfs = /turf/open/indestructible/necropolis baseturfs = /turf/open/indestructible/necropolis
initial_gas_mix = LAVALAND_DEFAULT_ATMOS initial_gas_mix = LAVALAND_DEFAULT_ATMOS
footstep = FOOTSTEP_LAVA footstep = FOOTSTEP_LAVA
tiled_dirt = FALSE tiled_dirt = FALSE
/turf/open/indestructible/necropolis/Initialize() /turf/open/indestructible/necropolis/Initialize()
. = ..() . = ..()
if(prob(12)) if(prob(12))
icon_state = "necro[rand(2,3)]" icon_state = "necro[rand(2,3)]"
/turf/open/indestructible/necropolis/air /turf/open/indestructible/necropolis/air
initial_gas_mix = "o2=22;n2=82;TEMP=293.15" initial_gas_mix = "o2=22;n2=82;TEMP=293.15"
/turf/open/indestructible/boss //you put stone tiles on this and use it as a base /turf/open/indestructible/boss //you put stone tiles on this and use it as a base
name = "necropolis floor" name = "necropolis floor"
icon = 'icons/turf/boss_floors.dmi' icon = 'icons/turf/boss_floors.dmi'
icon_state = "boss" icon_state = "boss"
baseturfs = /turf/open/indestructible/boss baseturfs = /turf/open/indestructible/boss
initial_gas_mix = LAVALAND_DEFAULT_ATMOS initial_gas_mix = LAVALAND_DEFAULT_ATMOS
/turf/open/indestructible/boss/air /turf/open/indestructible/boss/air
initial_gas_mix = "o2=22;n2=82;TEMP=293.15" initial_gas_mix = "o2=22;n2=82;TEMP=293.15"
/turf/open/indestructible/hierophant /turf/open/indestructible/hierophant
icon = 'icons/turf/floors/hierophant_floor.dmi' icon = 'icons/turf/floors/hierophant_floor.dmi'
initial_gas_mix = LAVALAND_DEFAULT_ATMOS initial_gas_mix = LAVALAND_DEFAULT_ATMOS
baseturfs = /turf/open/indestructible/hierophant baseturfs = /turf/open/indestructible/hierophant
smooth = SMOOTH_TRUE smooth = SMOOTH_TRUE
tiled_dirt = FALSE tiled_dirt = FALSE
/turf/open/indestructible/hierophant/two /turf/open/indestructible/hierophant/two
/turf/open/indestructible/hierophant/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) /turf/open/indestructible/hierophant/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
return FALSE return FALSE
/turf/open/indestructible/paper /turf/open/indestructible/paper
name = "notebook floor" name = "notebook floor"
desc = "A floor made of invulnerable notebook paper." desc = "A floor made of invulnerable notebook paper."
icon_state = "paperfloor" icon_state = "paperfloor"
footstep = null footstep = null
tiled_dirt = FALSE tiled_dirt = FALSE
/turf/open/indestructible/binary /turf/open/indestructible/binary
name = "tear in the fabric of reality" name = "tear in the fabric of reality"
CanAtmosPass = ATMOS_PASS_NO CanAtmosPass = ATMOS_PASS_NO
baseturfs = /turf/open/indestructible/binary baseturfs = /turf/open/indestructible/binary
icon_state = "binary" icon_state = "binary"
footstep = null footstep = null
/turf/open/indestructible/airblock /turf/open/indestructible/airblock
icon_state = "bluespace" icon_state = "bluespace"
CanAtmosPass = ATMOS_PASS_NO CanAtmosPass = ATMOS_PASS_NO
baseturfs = /turf/open/indestructible/airblock baseturfs = /turf/open/indestructible/airblock
/turf/open/indestructible/clock_spawn_room /turf/open/indestructible/clock_spawn_room
name = "cogmetal floor" name = "cogmetal floor"
desc = "Brass plating that gently radiates heat. For some reason, it reminds you of blood." desc = "Brass plating that gently radiates heat. For some reason, it reminds you of blood."
icon_state = "reebe" icon_state = "reebe"
baseturfs = /turf/open/indestructible/clock_spawn_room baseturfs = /turf/open/indestructible/clock_spawn_room
footstep = FOOTSTEP_PLATING footstep = FOOTSTEP_PLATING
/turf/open/indestructible/clock_spawn_room/Entered() /turf/open/indestructible/clock_spawn_room/Entered()
..() ..()
START_PROCESSING(SSfastprocess, src) START_PROCESSING(SSfastprocess, src)
/turf/open/indestructible/clock_spawn_room/Destroy() /turf/open/indestructible/clock_spawn_room/Destroy()
STOP_PROCESSING(SSfastprocess, src) STOP_PROCESSING(SSfastprocess, src)
. = ..() . = ..()
/turf/open/indestructible/clock_spawn_room/process() /turf/open/indestructible/clock_spawn_room/process()
if(!port_servants()) if(!port_servants())
STOP_PROCESSING(SSfastprocess, src) STOP_PROCESSING(SSfastprocess, src)
/turf/open/indestructible/clock_spawn_room/proc/port_servants() /turf/open/indestructible/clock_spawn_room/proc/port_servants()
. = FALSE . = FALSE
for(var/mob/living/L in src) for(var/mob/living/L in src)
if(is_servant_of_ratvar(L) && L.stat != DEAD) if(is_servant_of_ratvar(L) && L.stat != DEAD)
. = TRUE . = TRUE
L.forceMove(get_turf(pick(GLOB.servant_spawns))) L.forceMove(get_turf(pick(GLOB.servant_spawns)))
visible_message("<span class='warning'>[L] vanishes in a flash of red!</span>") visible_message("<span class='warning'>[L] vanishes in a flash of red!</span>")
L.visible_message("<span class='warning'>[L] appears in a flash of red!</span>", \ L.visible_message("<span class='warning'>[L] appears in a flash of red!</span>", \
"<span class='bold cult'>sas'so c'arta forbici</span><br><span class='danger'>You're yanked away from [src]!</span>") "<span class='bold cult'>sas'so c'arta forbici</span><br><span class='danger'>You're yanked away from [src]!</span>")
playsound(src, 'sound/magic/enter_blood.ogg', 50, TRUE) playsound(src, 'sound/magic/enter_blood.ogg', 50, TRUE)
playsound(L, 'sound/magic/exit_blood.ogg', 50, TRUE) playsound(L, 'sound/magic/exit_blood.ogg', 50, TRUE)
flash_color(L, flash_color = "#C80000", flash_time = 10) flash_color(L, flash_color = "#C80000", flash_time = 10)
/turf/open/Initalize_Atmos(times_fired) /turf/open/Initalize_Atmos(times_fired)
excited = 0 excited = 0
update_visuals() update_visuals()
current_cycle = times_fired current_cycle = times_fired
//cache some vars //cache some vars
var/list/atmos_adjacent_turfs = src.atmos_adjacent_turfs var/list/atmos_adjacent_turfs = src.atmos_adjacent_turfs
for(var/direction in GLOB.cardinals) for(var/direction in GLOB.cardinals)
var/turf/open/enemy_tile = get_step(src, direction) var/turf/open/enemy_tile = get_step(src, direction)
if(!istype(enemy_tile)) if(!istype(enemy_tile))
if (atmos_adjacent_turfs) if (atmos_adjacent_turfs)
atmos_adjacent_turfs -= enemy_tile atmos_adjacent_turfs -= enemy_tile
continue continue
var/datum/gas_mixture/enemy_air = enemy_tile.return_air() var/datum/gas_mixture/enemy_air = enemy_tile.return_air()
//only check this turf, if it didn't check us when it was initalized //only check this turf, if it didn't check us when it was initalized
if(enemy_tile.current_cycle < times_fired) if(enemy_tile.current_cycle < times_fired)
if(CANATMOSPASS(src, enemy_tile)) if(CANATMOSPASS(src, enemy_tile))
LAZYINITLIST(atmos_adjacent_turfs) LAZYINITLIST(atmos_adjacent_turfs)
LAZYINITLIST(enemy_tile.atmos_adjacent_turfs) LAZYINITLIST(enemy_tile.atmos_adjacent_turfs)
atmos_adjacent_turfs[enemy_tile] = TRUE atmos_adjacent_turfs[enemy_tile] = TRUE
enemy_tile.atmos_adjacent_turfs[src] = TRUE enemy_tile.atmos_adjacent_turfs[src] = TRUE
else else
if (atmos_adjacent_turfs) if (atmos_adjacent_turfs)
atmos_adjacent_turfs -= enemy_tile atmos_adjacent_turfs -= enemy_tile
if (enemy_tile.atmos_adjacent_turfs) if (enemy_tile.atmos_adjacent_turfs)
enemy_tile.atmos_adjacent_turfs -= src enemy_tile.atmos_adjacent_turfs -= src
UNSETEMPTY(enemy_tile.atmos_adjacent_turfs) UNSETEMPTY(enemy_tile.atmos_adjacent_turfs)
continue continue
else else
if (!atmos_adjacent_turfs || !atmos_adjacent_turfs[enemy_tile]) if (!atmos_adjacent_turfs || !atmos_adjacent_turfs[enemy_tile])
continue continue
if(!excited && air.compare(enemy_air)) if(!excited && air.compare(enemy_air))
//testing("Active turf found. Return value of compare(): [is_active]") //testing("Active turf found. Return value of compare(): [is_active]")
excited = TRUE excited = TRUE
SSair.active_turfs |= src SSair.active_turfs |= src
UNSETEMPTY(atmos_adjacent_turfs) UNSETEMPTY(atmos_adjacent_turfs)
if (atmos_adjacent_turfs) if (atmos_adjacent_turfs)
src.atmos_adjacent_turfs = atmos_adjacent_turfs src.atmos_adjacent_turfs = atmos_adjacent_turfs
/turf/open/proc/GetHeatCapacity() /turf/open/proc/GetHeatCapacity()
. = air.heat_capacity() . = air.heat_capacity()
/turf/open/proc/GetTemperature() /turf/open/proc/GetTemperature()
. = air.temperature . = air.temperature
/turf/open/proc/TakeTemperature(temp) /turf/open/proc/TakeTemperature(temp)
air.temperature += temp air.temperature += temp
air_update_turf() air_update_turf()
/turf/open/proc/freon_gas_act() /turf/open/proc/freon_gas_act()
for(var/obj/I in contents) for(var/obj/I in contents)
if(I.resistance_flags & FREEZE_PROOF) if(I.resistance_flags & FREEZE_PROOF)
return return
if(!(I.obj_flags & FROZEN)) if(!(I.obj_flags & FROZEN))
I.make_frozen_visual() I.make_frozen_visual()
for(var/mob/living/L in contents) for(var/mob/living/L in contents)
if(L.bodytemperature <= 50) if(L.bodytemperature <= 50)
L.apply_status_effect(/datum/status_effect/freon) L.apply_status_effect(/datum/status_effect/freon)
MakeSlippery(TURF_WET_PERMAFROST, 50) MakeSlippery(TURF_WET_PERMAFROST, 50)
return 1 return 1
/turf/open/proc/water_vapor_gas_act() /turf/open/proc/water_vapor_gas_act()
MakeSlippery(TURF_WET_WATER, min_wet_time = 100, wet_time_to_add = 50) MakeSlippery(TURF_WET_WATER, min_wet_time = 100, wet_time_to_add = 50)
for(var/mob/living/simple_animal/slime/M in src) for(var/mob/living/simple_animal/slime/M in src)
M.apply_water() M.apply_water()
SEND_SIGNAL(src, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK) SEND_SIGNAL(src, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
for(var/obj/effect/O in src) for(var/obj/effect/O in src)
if(is_cleanable(O)) if(is_cleanable(O))
qdel(O) qdel(O)
return TRUE return TRUE
/turf/open/handle_slip(mob/living/carbon/C, knockdown_amount, obj/O, lube) /turf/open/handle_slip(mob/living/carbon/C, knockdown_amount, obj/O, lube)
if(C.movement_type & FLYING) if(C.movement_type & FLYING)
return 0 return 0
if(has_gravity(src)) if(has_gravity(src))
var/obj/buckled_obj var/obj/buckled_obj
if(C.buckled) if(C.buckled)
buckled_obj = C.buckled buckled_obj = C.buckled
if(!(lube&GALOSHES_DONT_HELP)) //can't slip while buckled unless it's lube. if(!(lube&GALOSHES_DONT_HELP)) //can't slip while buckled unless it's lube.
return 0 return 0
else else
if(C.lying || !(C.status_flags & CANKNOCKDOWN)) // can't slip unbuckled mob if they're lying or can't fall. if(C.lying || !(C.status_flags & CANKNOCKDOWN)) // can't slip unbuckled mob if they're lying or can't fall.
return 0 return 0
if(C.m_intent == MOVE_INTENT_WALK && (lube&NO_SLIP_WHEN_WALKING)) if(C.m_intent == MOVE_INTENT_WALK && (lube&NO_SLIP_WHEN_WALKING))
return 0 return 0
if(ishuman(C) && (lube&NO_SLIP_WHEN_WALKING)) if(ishuman(C) && (lube&NO_SLIP_WHEN_WALKING))
var/mob/living/carbon/human/H = C var/mob/living/carbon/human/H = C
if(!H.sprinting && H.getStaminaLoss() >= 20) if(!H.sprinting && H.getStaminaLoss() >= 20)
return 0 return 0
if(!(lube&SLIDE_ICE)) if(!(lube&SLIDE_ICE))
to_chat(C, "<span class='notice'>You slipped[ O ? " on the [O.name]" : ""]!</span>") to_chat(C, "<span class='notice'>You slipped[ O ? " on the [O.name]" : ""]!</span>")
playsound(C.loc, 'sound/misc/slip.ogg', 50, 1, -3) playsound(C.loc, 'sound/misc/slip.ogg', 50, 1, -3)
SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "slipped", /datum/mood_event/slipped) SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "slipped", /datum/mood_event/slipped)
for(var/obj/item/I in C.held_items) for(var/obj/item/I in C.held_items)
C.accident(I) C.accident(I)
var/olddir = C.dir var/olddir = C.dir
if(!(lube & SLIDE_ICE)) if(!(lube & SLIDE_ICE))
C.Knockdown(knockdown_amount) C.Knockdown(knockdown_amount)
C.stop_pulling() C.stop_pulling()
else else
C.Stun(20) C.Stun(20)
if(buckled_obj) if(buckled_obj)
buckled_obj.unbuckle_mob(C) buckled_obj.unbuckle_mob(C)
lube |= SLIDE_ICE lube |= SLIDE_ICE
if(lube&SLIDE) if(lube&SLIDE)
new /datum/forced_movement(C, get_ranged_target_turf(C, olddir, 4), 1, FALSE, CALLBACK(C, /mob/living/carbon/.proc/spin, 1, 1)) new /datum/forced_movement(C, get_ranged_target_turf(C, olddir, 4), 1, FALSE, CALLBACK(C, /mob/living/carbon/.proc/spin, 1, 1))
else if(lube&SLIDE_ICE) else if(lube&SLIDE_ICE)
new /datum/forced_movement(C, get_ranged_target_turf(C, olddir, 1), 1, FALSE) //spinning would be bad for ice, fucks up the next dir new /datum/forced_movement(C, get_ranged_target_turf(C, olddir, 1), 1, FALSE) //spinning would be bad for ice, fucks up the next dir
return 1 return 1
/turf/open/proc/MakeSlippery(wet_setting = TURF_WET_WATER, min_wet_time = 0, wet_time_to_add = 0, max_wet_time = MAXIMUM_WET_TIME, permanent) /turf/open/proc/MakeSlippery(wet_setting = TURF_WET_WATER, min_wet_time = 0, wet_time_to_add = 0, max_wet_time = MAXIMUM_WET_TIME, permanent)
AddComponent(/datum/component/wet_floor, wet_setting, min_wet_time, wet_time_to_add, max_wet_time, permanent) AddComponent(/datum/component/wet_floor, wet_setting, min_wet_time, wet_time_to_add, max_wet_time, permanent)
/turf/open/proc/MakeDry(wet_setting = TURF_WET_WATER, immediate = FALSE, amount = INFINITY) /turf/open/proc/MakeDry(wet_setting = TURF_WET_WATER, immediate = FALSE, amount = INFINITY)
SEND_SIGNAL(src, COMSIG_TURF_MAKE_DRY, wet_setting, immediate, amount) SEND_SIGNAL(src, COMSIG_TURF_MAKE_DRY, wet_setting, immediate, amount)
/turf/open/get_dumping_location() /turf/open/get_dumping_location()
return src return src
/turf/open/proc/ClearWet()//Nuclear option of immediately removing slipperyness from the tile instead of the natural drying over time /turf/open/proc/ClearWet()//Nuclear option of immediately removing slipperyness from the tile instead of the natural drying over time
qdel(GetComponent(/datum/component/wet_floor)) qdel(GetComponent(/datum/component/wet_floor))
/turf/open/rad_act(pulse_strength) /turf/open/rad_act(pulse_strength)
. = ..() . = ..()
if (air.gases[/datum/gas/carbon_dioxide] && air.gases[/datum/gas/oxygen]) if (air.gases[/datum/gas/carbon_dioxide] && air.gases[/datum/gas/oxygen])
pulse_strength = min(pulse_strength,air.gases[/datum/gas/carbon_dioxide]*1000,air.gases[/datum/gas/oxygen]*2000) //Ensures matter is conserved properly pulse_strength = min(pulse_strength,air.gases[/datum/gas/carbon_dioxide]*1000,air.gases[/datum/gas/oxygen]*2000) //Ensures matter is conserved properly
air.gases[/datum/gas/carbon_dioxide]=max(air.gases[/datum/gas/carbon_dioxide]-(pulse_strength/1000),0) air.gases[/datum/gas/carbon_dioxide]=max(air.gases[/datum/gas/carbon_dioxide]-(pulse_strength/1000),0)
air.gases[/datum/gas/oxygen]=max(air.gases[/datum/gas/oxygen]-(pulse_strength/2000),0) air.gases[/datum/gas/oxygen]=max(air.gases[/datum/gas/oxygen]-(pulse_strength/2000),0)
air.gases[/datum/gas/pluoxium]+=(pulse_strength/4000) air.gases[/datum/gas/pluoxium]+=(pulse_strength/4000)
air.garbage_collect() GAS_GARBAGE_COLLECT(air.gases)

View File

@@ -1,202 +1,202 @@
/obj/item/onetankbomb /obj/item/onetankbomb
name = "bomb" name = "bomb"
icon = 'icons/obj/tank.dmi' icon = 'icons/obj/tank.dmi'
item_state = "assembly" item_state = "assembly"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
throwforce = 5 throwforce = 5
w_class = WEIGHT_CLASS_NORMAL w_class = WEIGHT_CLASS_NORMAL
throw_speed = 2 throw_speed = 2
throw_range = 4 throw_range = 4
flags_1 = CONDUCT_1 flags_1 = CONDUCT_1
var/status = FALSE //0 - not readied //1 - bomb finished with welder var/status = FALSE //0 - not readied //1 - bomb finished with welder
var/obj/item/assembly_holder/bombassembly = null //The first part of the bomb is an assembly holder, holding an igniter+some device var/obj/item/assembly_holder/bombassembly = null //The first part of the bomb is an assembly holder, holding an igniter+some device
var/obj/item/tank/bombtank = null //the second part of the bomb is a plasma tank var/obj/item/tank/bombtank = null //the second part of the bomb is a plasma tank
/obj/item/onetankbomb/IsSpecialAssembly() /obj/item/onetankbomb/IsSpecialAssembly()
return TRUE return TRUE
/obj/item/onetankbomb/examine(mob/user) /obj/item/onetankbomb/examine(mob/user)
bombtank.examine(user) bombtank.examine(user)
/obj/item/onetankbomb/update_icon() /obj/item/onetankbomb/update_icon()
cut_overlays() cut_overlays()
if(bombtank) if(bombtank)
icon = bombtank.icon icon = bombtank.icon
icon_state = bombtank.icon_state icon_state = bombtank.icon_state
if(bombassembly) if(bombassembly)
add_overlay(bombassembly.icon_state) add_overlay(bombassembly.icon_state)
copy_overlays(bombassembly) copy_overlays(bombassembly)
add_overlay("bomb_assembly") add_overlay("bomb_assembly")
/obj/item/onetankbomb/wrench_act(mob/living/user, obj/item/I) /obj/item/onetankbomb/wrench_act(mob/living/user, obj/item/I)
to_chat(user, "<span class='notice'>You disassemble [src]!</span>") to_chat(user, "<span class='notice'>You disassemble [src]!</span>")
if(bombassembly) if(bombassembly)
bombassembly.forceMove(drop_location()) bombassembly.forceMove(drop_location())
bombassembly.master = null bombassembly.master = null
bombassembly = null bombassembly = null
if(bombtank) if(bombtank)
bombtank.forceMove(drop_location()) bombtank.forceMove(drop_location())
bombtank.master = null bombtank.master = null
bombtank = null bombtank = null
qdel(src) qdel(src)
return TRUE return TRUE
/obj/item/onetankbomb/welder_act(mob/living/user, obj/item/I) /obj/item/onetankbomb/welder_act(mob/living/user, obj/item/I)
. = FALSE . = FALSE
if(status) if(status)
to_chat(user, "<span class='notice'>[bombtank] already has a pressure hole!</span>") to_chat(user, "<span class='notice'>[bombtank] already has a pressure hole!</span>")
return return
if(!I.tool_start_check(user, amount=0)) if(!I.tool_start_check(user, amount=0))
return return
if(I.use_tool(src, user, 0, volume=40)) if(I.use_tool(src, user, 0, volume=40))
status = TRUE status = TRUE
GLOB.bombers += "[key_name(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]" GLOB.bombers += "[key_name(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]"
message_admins("[ADMIN_LOOKUPFLW(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]") message_admins("[ADMIN_LOOKUPFLW(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]")
to_chat(user, "<span class='notice'>A pressure hole has been bored to [bombtank] valve. \The [bombtank] can now be ignited.</span>") to_chat(user, "<span class='notice'>A pressure hole has been bored to [bombtank] valve. \The [bombtank] can now be ignited.</span>")
add_fingerprint(user) add_fingerprint(user)
return TRUE return TRUE
/obj/item/onetankbomb/analyzer_act(mob/living/user, obj/item/I) /obj/item/onetankbomb/analyzer_act(mob/living/user, obj/item/I)
bombtank.analyzer_act(user, I) bombtank.analyzer_act(user, I)
/obj/item/onetankbomb/attack_self(mob/user) //pressing the bomb accesses its assembly /obj/item/onetankbomb/attack_self(mob/user) //pressing the bomb accesses its assembly
bombassembly.attack_self(user, TRUE) bombassembly.attack_self(user, TRUE)
add_fingerprint(user) add_fingerprint(user)
return return
/obj/item/onetankbomb/receive_signal() //This is mainly called by the sensor through sense() to the holder, and from the holder to here. /obj/item/onetankbomb/receive_signal() //This is mainly called by the sensor through sense() to the holder, and from the holder to here.
audible_message("[icon2html(src, hearers(src))] *beep* *beep* *beep*") audible_message("[icon2html(src, hearers(src))] *beep* *beep* *beep*")
playsound(src, 'sound/machines/triple_beep.ogg', ASSEMBLY_BEEP_VOLUME, TRUE) playsound(src, 'sound/machines/triple_beep.ogg', ASSEMBLY_BEEP_VOLUME, TRUE)
sleep(10) sleep(10)
if(QDELETED(src)) if(QDELETED(src))
return return
if(status) 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 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 else
bombtank.release() bombtank.release()
//Assembly / attached device memes //Assembly / attached device memes
/obj/item/onetankbomb/Crossed(atom/movable/AM as mob|obj) //for mousetraps /obj/item/onetankbomb/Crossed(atom/movable/AM as mob|obj) //for mousetraps
. = ..() . = ..()
if(bombassembly) if(bombassembly)
bombassembly.Crossed(AM) bombassembly.Crossed(AM)
/obj/item/onetankbomb/on_found(mob/finder) //for mousetraps /obj/item/onetankbomb/on_found(mob/finder) //for mousetraps
if(bombassembly) if(bombassembly)
bombassembly.on_found(finder) bombassembly.on_found(finder)
/obj/item/onetankbomb/attack_hand() //also for mousetraps /obj/item/onetankbomb/attack_hand() //also for mousetraps
. = ..() . = ..()
if(.) if(.)
return return
if(bombassembly) if(bombassembly)
bombassembly.attack_hand() bombassembly.attack_hand()
/obj/item/onetankbomb/Move() /obj/item/onetankbomb/Move()
. = ..() . = ..()
if(bombassembly) if(bombassembly)
bombassembly.setDir(dir) bombassembly.setDir(dir)
bombassembly.Move() bombassembly.Move()
/obj/item/onetankbomb/dropped() /obj/item/onetankbomb/dropped()
. = ..() . = ..()
if(bombassembly) if(bombassembly)
bombassembly.dropped() bombassembly.dropped()
// ---------- Procs below are for tanks that are used exclusively in 1-tank bombs ---------- // ---------- Procs below are for tanks that are used exclusively in 1-tank bombs ----------
//Bomb assembly proc. This turns assembly+tank into a bomb //Bomb assembly proc. This turns assembly+tank into a bomb
/obj/item/tank/proc/bomb_assemble(obj/item/assembly_holder/assembly, mob/living/user) /obj/item/tank/proc/bomb_assemble(obj/item/assembly_holder/assembly, mob/living/user)
//Check if either part of the assembly has an igniter, but if both parts are igniters, then fuck it //Check if either part of the assembly has an igniter, but if both parts are igniters, then fuck it
if(isigniter(assembly.a_left) == isigniter(assembly.a_right)) if(isigniter(assembly.a_left) == isigniter(assembly.a_right))
return return
if((src in user.get_equipped_items(TRUE)) && !user.canUnEquip(src)) if((src in user.get_equipped_items(TRUE)) && !user.canUnEquip(src))
to_chat(user, "<span class='warning'>[src] is stuck to you!</span>") to_chat(user, "<span class='warning'>[src] is stuck to you!</span>")
return return
if(!user.canUnEquip(assembly)) if(!user.canUnEquip(assembly))
to_chat(user, "<span class='warning'>[assembly] is stuck to your hand!</span>") to_chat(user, "<span class='warning'>[assembly] is stuck to your hand!</span>")
return return
var/obj/item/onetankbomb/bomb = new var/obj/item/onetankbomb/bomb = new
user.transferItemToLoc(src, bomb) user.transferItemToLoc(src, bomb)
user.transferItemToLoc(assembly, bomb) user.transferItemToLoc(assembly, bomb)
bomb.bombassembly = assembly //Tell the bomb about its assembly part bomb.bombassembly = assembly //Tell the bomb about its assembly part
assembly.master = bomb //Tell the assembly about its new owner assembly.master = bomb //Tell the assembly about its new owner
bomb.bombtank = src //Same for tank bomb.bombtank = src //Same for tank
master = bomb master = bomb
forceMove(bomb) forceMove(bomb)
bomb.update_icon() bomb.update_icon()
user.put_in_hands(bomb) //Equips the bomb if possible, or puts it on the floor. user.put_in_hands(bomb) //Equips the bomb if possible, or puts it on the floor.
to_chat(user, "<span class='notice'>You attach [assembly] to [src].</span>") to_chat(user, "<span class='notice'>You attach [assembly] to [src].</span>")
return return
/obj/item/tank/proc/ignite() //This happens when a bomb is told to explode /obj/item/tank/proc/ignite() //This happens when a bomb is told to explode
var/fuel_moles = air_contents.gases[/datum/gas/plasma] + air_contents.gases[/datum/gas/oxygen]/6 var/fuel_moles = air_contents.gases[/datum/gas/plasma] + air_contents.gases[/datum/gas/oxygen]/6
air_contents.garbage_collect() GAS_GARBAGE_COLLECT(air_contents.gases)
var/datum/gas_mixture/bomb_mixture = air_contents.copy() var/datum/gas_mixture/bomb_mixture = air_contents.copy()
var/strength = 1 var/strength = 1
var/turf/ground_zero = get_turf(loc) var/turf/ground_zero = get_turf(loc)
if(master) if(master)
qdel(master) qdel(master)
qdel(src) qdel(src)
if(bomb_mixture.temperature > (T0C + 400)) if(bomb_mixture.temperature > (T0C + 400))
strength = (fuel_moles/15) strength = (fuel_moles/15)
if(strength >=1) if(strength >=1)
explosion(ground_zero, round(strength,1), round(strength*2,1), round(strength*3,1), round(strength*4,1)) explosion(ground_zero, round(strength,1), round(strength*2,1), round(strength*3,1), round(strength*4,1))
else if(strength >=0.5) else if(strength >=0.5)
explosion(ground_zero, 0, 1, 2, 4) explosion(ground_zero, 0, 1, 2, 4)
else if(strength >=0.2) else if(strength >=0.2)
explosion(ground_zero, -1, 0, 1, 2) explosion(ground_zero, -1, 0, 1, 2)
else else
ground_zero.assume_air(bomb_mixture) ground_zero.assume_air(bomb_mixture)
ground_zero.hotspot_expose(1000, 125) ground_zero.hotspot_expose(1000, 125)
else if(bomb_mixture.temperature > (T0C + 250)) else if(bomb_mixture.temperature > (T0C + 250))
strength = (fuel_moles/20) strength = (fuel_moles/20)
if(strength >=1) if(strength >=1)
explosion(ground_zero, 0, round(strength,1), round(strength*2,1), round(strength*3,1)) explosion(ground_zero, 0, round(strength,1), round(strength*2,1), round(strength*3,1))
else if (strength >=0.5) else if (strength >=0.5)
explosion(ground_zero, -1, 0, 1, 2) explosion(ground_zero, -1, 0, 1, 2)
else else
ground_zero.assume_air(bomb_mixture) ground_zero.assume_air(bomb_mixture)
ground_zero.hotspot_expose(1000, 125) ground_zero.hotspot_expose(1000, 125)
else if(bomb_mixture.temperature > (T0C + 100)) else if(bomb_mixture.temperature > (T0C + 100))
strength = (fuel_moles/25) strength = (fuel_moles/25)
if (strength >=1) if (strength >=1)
explosion(ground_zero, -1, 0, round(strength,1), round(strength*3,1)) explosion(ground_zero, -1, 0, round(strength,1), round(strength*3,1))
else else
ground_zero.assume_air(bomb_mixture) ground_zero.assume_air(bomb_mixture)
ground_zero.hotspot_expose(1000, 125) ground_zero.hotspot_expose(1000, 125)
else else
ground_zero.assume_air(bomb_mixture) ground_zero.assume_air(bomb_mixture)
ground_zero.hotspot_expose(1000, 125) ground_zero.hotspot_expose(1000, 125)
ground_zero.air_update_turf() ground_zero.air_update_turf()
/obj/item/tank/proc/release() //This happens when the bomb is not welded. Tank contents are just spat out. /obj/item/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/datum/gas_mixture/removed = air_contents.remove(air_contents.total_moles())
var/turf/T = get_turf(src) var/turf/T = get_turf(src)
if(!T) if(!T)
return return
T.assume_air(removed) T.assume_air(removed)
air_update_turf() air_update_turf()

View File

@@ -5,8 +5,6 @@ What are the archived variables for?
*/ */
#define MINIMUM_HEAT_CAPACITY 0.0003 #define MINIMUM_HEAT_CAPACITY 0.0003
#define MINIMUM_MOLE_COUNT 0.01 #define MINIMUM_MOLE_COUNT 0.01
#define QUANTIZE(variable) (round(variable,0.0000001))/*I feel the need to document what happens here. Basically this is used to catch most rounding errors, however it's previous value made it so that
once gases got hot enough, most procedures wouldnt occur due to the fact that the mole counts would get rounded away. Thus, we lowered it a few orders of magnititude */
GLOBAL_LIST_INIT(meta_gas_info, meta_gas_list()) //see ATMOSPHERICS/gas_types.dm GLOBAL_LIST_INIT(meta_gas_info, meta_gas_list()) //see ATMOSPHERICS/gas_types.dm
/datum/gas_mixture /datum/gas_mixture
var/list/gases = list() var/list/gases = list()
@@ -22,23 +20,6 @@ GLOBAL_LIST_INIT(meta_gas_info, meta_gas_list()) //see ATMOSPHERICS/gas_types.dm
if (!isnull(volume)) if (!isnull(volume))
src.volume = volume src.volume = volume
//listmos procs
//use the macros in performance intensive areas. for their definitions, refer to code/__DEFINES/atmospherics.dm
//UNOMOS - whoever originally wrote this is a sadist that just wants to see byond suffer.
//garbage_collect() - removes any gas list which is empty.
//If called with a list as an argument, only removes gas lists with IDs from that list.
//Must be used after subtracting from a gas. Must be used after assert_gas()
//if assert_gas() was called only to read from the gas.
//By removing empty gases, processing speed is increased.
//UNOMOS - i have no idea exactly what the fuck or how the fuck it's the case, but removing this proc can and will completely nullify all of the performance gain from removing add_gas and assert_gas. so uh, dont remove it i guess. Why this shit isn't a define is beyond me.
/datum/gas_mixture/proc/garbage_collect(list/tocheck)
var/list/cached_gases = gases
for(var/id in (tocheck || cached_gases))
if(QUANTIZE(cached_gases[id]) <= 0)
cached_gases -= id
//PV = nRT //PV = nRT
/datum/gas_mixture/proc/heat_capacity() //joules per kelvin /datum/gas_mixture/proc/heat_capacity() //joules per kelvin
@@ -152,7 +133,7 @@ GLOBAL_LIST_INIT(meta_gas_info, meta_gas_list()) //see ATMOSPHERICS/gas_types.dm
for(var/id in cached_gases) for(var/id in cached_gases)
removed_gases[id] = QUANTIZE((cached_gases[id] / sum) * amount) removed_gases[id] = QUANTIZE((cached_gases[id] / sum) * amount)
cached_gases[id] -= removed_gases[id] cached_gases[id] -= removed_gases[id]
garbage_collect() GAS_GARBAGE_COLLECT(gases)
return removed return removed
@@ -170,7 +151,7 @@ GLOBAL_LIST_INIT(meta_gas_info, meta_gas_list()) //see ATMOSPHERICS/gas_types.dm
removed_gases[id] = QUANTIZE(cached_gases[id] * ratio) removed_gases[id] = QUANTIZE(cached_gases[id] * ratio)
cached_gases[id] -= removed_gases[id] cached_gases[id] -= removed_gases[id]
garbage_collect() GAS_GARBAGE_COLLECT(gases)
return removed return removed
@@ -282,11 +263,8 @@ GLOBAL_LIST_INIT(meta_gas_info, meta_gas_list()) //see ATMOSPHERICS/gas_types.dm
if(abs(new_sharer_heat_capacity/old_sharer_heat_capacity - 1) < 0.1) // <10% change in sharer heat capacity if(abs(new_sharer_heat_capacity/old_sharer_heat_capacity - 1) < 0.1) // <10% change in sharer heat capacity
temperature_share(sharer, OPEN_HEAT_TRANSFER_COEFFICIENT) temperature_share(sharer, OPEN_HEAT_TRANSFER_COEFFICIENT)
if(length(cached_gases ^ sharer_gases)) //if all gases were present in both mixtures, we know that no gases are 0
garbage_collect(cached_gases - sharer_gases) //any gases the sharer had, we are guaranteed to have. gases that it didn't have we are not.
sharer.garbage_collect(sharer_gases - cached_gases) //the reverse is equally true
if (initial(sharer.gc_share)) if (initial(sharer.gc_share))
sharer.garbage_collect() GAS_GARBAGE_COLLECT(sharer.gases)
if(temperature_delta > MINIMUM_TEMPERATURE_TO_MOVE || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE) if(temperature_delta > MINIMUM_TEMPERATURE_TO_MOVE || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE)
var/our_moles var/our_moles
TOTAL_MOLES(cached_gases,our_moles) TOTAL_MOLES(cached_gases,our_moles)
@@ -391,7 +369,7 @@ GLOBAL_LIST_INIT(meta_gas_info, meta_gas_list()) //see ATMOSPHERICS/gas_types.dm
if (. & STOP_REACTIONS) if (. & STOP_REACTIONS)
break break
if(.) if(.)
garbage_collect() GAS_GARBAGE_COLLECT(gases)
if(temperature < TCMB) //just for safety if(temperature < TCMB) //just for safety
temperature = TCMB temperature = TCMB

View File

@@ -7,9 +7,6 @@
/datum/gas_mixture/immutable/New() /datum/gas_mixture/immutable/New()
..() ..()
garbage_collect()
/datum/gas_mixture/immutable/garbage_collect()
temperature = initial_temperature temperature = initial_temperature
temperature_archived = initial_temperature temperature_archived = initial_temperature
gases.Cut() gases.Cut()
@@ -19,7 +16,9 @@
/datum/gas_mixture/immutable/share(datum/gas_mixture/sharer, atmos_adjacent_turfs = 4) /datum/gas_mixture/immutable/share(datum/gas_mixture/sharer, atmos_adjacent_turfs = 4)
. = ..(sharer, 0) . = ..(sharer, 0)
garbage_collect() temperature = initial_temperature
temperature_archived = initial_temperature
gases.Cut()
/datum/gas_mixture/immutable/react() /datum/gas_mixture/immutable/react()
return 0 //we're immutable. return 0 //we're immutable.
@@ -59,9 +58,13 @@
/datum/gas_mixture/immutable/cloner /datum/gas_mixture/immutable/cloner
initial_temperature = T20C initial_temperature = T20C
/datum/gas_mixture/immutable/cloner/garbage_collect() /datum/gas_mixture/immutable/cloner/New()
..() ..()
gases[/datum/gas/nitrogen] = MOLES_O2STANDARD + MOLES_N2STANDARD gases[/datum/gas/nitrogen] = MOLES_O2STANDARD + MOLES_N2STANDARD
/datum/gas_mixture/immutable/share(datum/gas_mixture/sharer, atmos_adjacent_turfs = 4)
. = ..(sharer, 0)
gases[/datum/gas/nitrogen] = MOLES_O2STANDARD + MOLES_N2STANDARD
/datum/gas_mixture/immutable/cloner/heat_capacity() /datum/gas_mixture/immutable/cloner/heat_capacity()
return (MOLES_O2STANDARD + MOLES_N2STANDARD)*20 //specific heat of nitrogen is 20 return (MOLES_O2STANDARD + MOLES_N2STANDARD)*20 //specific heat of nitrogen is 20

File diff suppressed because it is too large Load Diff

View File

@@ -1,237 +1,237 @@
/obj/machinery/atmospherics/components/trinary/filter /obj/machinery/atmospherics/components/trinary/filter
name = "gas filter" name = "gas filter"
icon_state = "filter_off" icon_state = "filter_off"
desc = "Very useful for filtering gasses." desc = "Very useful for filtering gasses."
density = FALSE density = FALSE
can_unwrench = TRUE can_unwrench = TRUE
var/target_pressure = ONE_ATMOSPHERE var/target_pressure = ONE_ATMOSPHERE
var/filter_type = null var/filter_type = null
var/frequency = 0 var/frequency = 0
var/datum/radio_frequency/radio_connection var/datum/radio_frequency/radio_connection
construction_type = /obj/item/pipe/trinary/flippable construction_type = /obj/item/pipe/trinary/flippable
pipe_state = "filter" pipe_state = "filter"
/obj/machinery/atmospherics/components/trinary/filter/layer1 /obj/machinery/atmospherics/components/trinary/filter/layer1
piping_layer = PIPING_LAYER_MIN piping_layer = PIPING_LAYER_MIN
pixel_x = -PIPING_LAYER_P_X pixel_x = -PIPING_LAYER_P_X
pixel_y = -PIPING_LAYER_P_Y pixel_y = -PIPING_LAYER_P_Y
/obj/machinery/atmospherics/components/trinary/filter/layer3 /obj/machinery/atmospherics/components/trinary/filter/layer3
piping_layer = PIPING_LAYER_MAX piping_layer = PIPING_LAYER_MAX
pixel_x = PIPING_LAYER_P_X pixel_x = PIPING_LAYER_P_X
pixel_y = PIPING_LAYER_P_Y pixel_y = PIPING_LAYER_P_Y
/obj/machinery/atmospherics/components/trinary/filter/flipped /obj/machinery/atmospherics/components/trinary/filter/flipped
icon_state = "filter_off_f" icon_state = "filter_off_f"
flipped = TRUE flipped = TRUE
/obj/machinery/atmospherics/components/trinary/filter/flipped/layer1 /obj/machinery/atmospherics/components/trinary/filter/flipped/layer1
piping_layer = PIPING_LAYER_MIN piping_layer = PIPING_LAYER_MIN
pixel_x = -PIPING_LAYER_P_X pixel_x = -PIPING_LAYER_P_X
pixel_y = -PIPING_LAYER_P_Y pixel_y = -PIPING_LAYER_P_Y
/obj/machinery/atmospherics/components/trinary/filter/flipped/layer3 /obj/machinery/atmospherics/components/trinary/filter/flipped/layer3
piping_layer = PIPING_LAYER_MAX piping_layer = PIPING_LAYER_MAX
pixel_x = PIPING_LAYER_P_X pixel_x = PIPING_LAYER_P_X
pixel_y = PIPING_LAYER_P_Y pixel_y = PIPING_LAYER_P_Y
// These two filter types have critical_machine flagged to on and thus causes the area they are in to be exempt from the Grid Check event. // These two filter types have critical_machine flagged to on and thus causes the area they are in to be exempt from the Grid Check event.
/obj/machinery/atmospherics/components/trinary/filter/critical /obj/machinery/atmospherics/components/trinary/filter/critical
critical_machine = TRUE critical_machine = TRUE
/obj/machinery/atmospherics/components/trinary/filter/flipped/critical /obj/machinery/atmospherics/components/trinary/filter/flipped/critical
critical_machine = TRUE critical_machine = TRUE
/obj/machinery/atmospherics/components/trinary/filter/proc/set_frequency(new_frequency) /obj/machinery/atmospherics/components/trinary/filter/proc/set_frequency(new_frequency)
SSradio.remove_object(src, frequency) SSradio.remove_object(src, frequency)
frequency = new_frequency frequency = new_frequency
if(frequency) if(frequency)
radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA) radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA)
/obj/machinery/atmospherics/components/trinary/filter/Destroy() /obj/machinery/atmospherics/components/trinary/filter/Destroy()
SSradio.remove_object(src,frequency) SSradio.remove_object(src,frequency)
return ..() return ..()
/obj/machinery/atmospherics/components/trinary/filter/atmos //Used for atmos waste loops /obj/machinery/atmospherics/components/trinary/filter/atmos //Used for atmos waste loops
on = TRUE on = TRUE
icon_state = "filter_on" icon_state = "filter_on"
/obj/machinery/atmospherics/components/trinary/filter/atmos/n2 /obj/machinery/atmospherics/components/trinary/filter/atmos/n2
name = "nitrogen filter" name = "nitrogen filter"
filter_type = "n2" filter_type = "n2"
/obj/machinery/atmospherics/components/trinary/filter/atmos/o2 /obj/machinery/atmospherics/components/trinary/filter/atmos/o2
name = "oxygen filter" name = "oxygen filter"
filter_type = "o2" filter_type = "o2"
/obj/machinery/atmospherics/components/trinary/filter/atmos/co2 /obj/machinery/atmospherics/components/trinary/filter/atmos/co2
name = "carbon dioxide filter" name = "carbon dioxide filter"
filter_type = "co2" filter_type = "co2"
/obj/machinery/atmospherics/components/trinary/filter/atmos/n2o /obj/machinery/atmospherics/components/trinary/filter/atmos/n2o
name = "nitrous oxide filter" name = "nitrous oxide filter"
filter_type = "n2o" filter_type = "n2o"
/obj/machinery/atmospherics/components/trinary/filter/atmos/plasma /obj/machinery/atmospherics/components/trinary/filter/atmos/plasma
name = "plasma filter" name = "plasma filter"
filter_type = "plasma" filter_type = "plasma"
/obj/machinery/atmospherics/components/trinary/filter/atmos/flipped //This feels wrong, I know /obj/machinery/atmospherics/components/trinary/filter/atmos/flipped //This feels wrong, I know
icon_state = "filter_on_f" icon_state = "filter_on_f"
flipped = TRUE flipped = TRUE
/obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/n2 /obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/n2
name = "nitrogen filter" name = "nitrogen filter"
filter_type = "n2" filter_type = "n2"
/obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/o2 /obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/o2
name = "oxygen filter" name = "oxygen filter"
filter_type = "o2" filter_type = "o2"
/obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/co2 /obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/co2
name = "carbon dioxide filter" name = "carbon dioxide filter"
filter_type = "co2" filter_type = "co2"
/obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/n2o /obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/n2o
name = "nitrous oxide filter" name = "nitrous oxide filter"
filter_type = "n2o" filter_type = "n2o"
/obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/plasma /obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/plasma
name = "plasma filter" name = "plasma filter"
filter_type = "plasma" filter_type = "plasma"
/obj/machinery/atmospherics/components/trinary/filter/update_icon() /obj/machinery/atmospherics/components/trinary/filter/update_icon()
cut_overlays() cut_overlays()
for(var/direction in GLOB.cardinals) for(var/direction in GLOB.cardinals)
if(direction & initialize_directions) if(direction & initialize_directions)
var/obj/machinery/atmospherics/node = findConnecting(direction) var/obj/machinery/atmospherics/node = findConnecting(direction)
if(node) if(node)
add_overlay(getpipeimage('icons/obj/atmospherics/components/trinary_devices.dmi', "cap", direction, node.pipe_color)) add_overlay(getpipeimage('icons/obj/atmospherics/components/trinary_devices.dmi', "cap", direction, node.pipe_color))
continue continue
add_overlay(getpipeimage('icons/obj/atmospherics/components/trinary_devices.dmi', "cap", direction)) add_overlay(getpipeimage('icons/obj/atmospherics/components/trinary_devices.dmi', "cap", direction))
..() ..()
/obj/machinery/atmospherics/components/trinary/filter/update_icon_nopipes() /obj/machinery/atmospherics/components/trinary/filter/update_icon_nopipes()
if(on && nodes[1] && nodes[2] && nodes[3] && is_operational()) if(on && nodes[1] && nodes[2] && nodes[3] && is_operational())
icon_state = "filter_on[flipped?"_f":""]" icon_state = "filter_on[flipped?"_f":""]"
return return
icon_state = "filter_off[flipped?"_f":""]" icon_state = "filter_off[flipped?"_f":""]"
/obj/machinery/atmospherics/components/trinary/filter/power_change() /obj/machinery/atmospherics/components/trinary/filter/power_change()
var/old_stat = stat var/old_stat = stat
..() ..()
if(stat != old_stat) if(stat != old_stat)
update_icon() update_icon()
/obj/machinery/atmospherics/components/trinary/filter/process_atmos() /obj/machinery/atmospherics/components/trinary/filter/process_atmos()
..() ..()
if(!on || !(nodes[1] && nodes[2] && nodes[3]) || !is_operational()) if(!on || !(nodes[1] && nodes[2] && nodes[3]) || !is_operational())
return return
var/datum/gas_mixture/air1 = airs[1] var/datum/gas_mixture/air1 = airs[1]
var/datum/gas_mixture/air2 = airs[2] var/datum/gas_mixture/air2 = airs[2]
var/datum/gas_mixture/air3 = airs[3] var/datum/gas_mixture/air3 = airs[3]
var/output_starting_pressure = air3.return_pressure() var/output_starting_pressure = air3.return_pressure()
if(output_starting_pressure >= target_pressure) if(output_starting_pressure >= target_pressure)
//No need to transfer if target is already full! //No need to transfer if target is already full!
return return
//Calculate necessary moles to transfer using PV=nRT //Calculate necessary moles to transfer using PV=nRT
var/pressure_delta = target_pressure - output_starting_pressure var/pressure_delta = target_pressure - output_starting_pressure
var/transfer_moles var/transfer_moles
if(air1.temperature > 0) if(air1.temperature > 0)
transfer_moles = pressure_delta*air3.volume/(air1.temperature * R_IDEAL_GAS_EQUATION) transfer_moles = pressure_delta*air3.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
//Actually transfer the gas //Actually transfer the gas
if(transfer_moles > 0) if(transfer_moles > 0)
var/datum/gas_mixture/removed = air1.remove(transfer_moles) var/datum/gas_mixture/removed = air1.remove(transfer_moles)
if(!removed) if(!removed)
return return
var/filtering = TRUE var/filtering = TRUE
if(!ispath(filter_type)) if(!ispath(filter_type))
if(filter_type) if(filter_type)
filter_type = gas_id2path(filter_type) //support for mappers so they don't need to type out paths filter_type = gas_id2path(filter_type) //support for mappers so they don't need to type out paths
else else
filtering = FALSE filtering = FALSE
if(filtering && removed.gases[filter_type]) if(filtering && removed.gases[filter_type])
var/datum/gas_mixture/filtered_out = new var/datum/gas_mixture/filtered_out = new
filtered_out.temperature = removed.temperature filtered_out.temperature = removed.temperature
filtered_out.gases[filter_type] = removed.gases[filter_type] filtered_out.gases[filter_type] = removed.gases[filter_type]
removed.gases[filter_type] = 0 removed.gases[filter_type] = 0
removed.garbage_collect() GAS_GARBAGE_COLLECT(removed.gases)
var/datum/gas_mixture/target = (air2.return_pressure() < target_pressure ? air2 : air1) //if there's no room for the filtered gas; just leave it in air1 var/datum/gas_mixture/target = (air2.return_pressure() < target_pressure ? air2 : air1) //if there's no room for the filtered gas; just leave it in air1
target.merge(filtered_out) target.merge(filtered_out)
air3.merge(removed) air3.merge(removed)
update_parents() update_parents()
/obj/machinery/atmospherics/components/trinary/filter/atmosinit() /obj/machinery/atmospherics/components/trinary/filter/atmosinit()
set_frequency(frequency) set_frequency(frequency)
return ..() return ..()
/obj/machinery/atmospherics/components/trinary/filter/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ /obj/machinery/atmospherics/components/trinary/filter/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui) if(!ui)
ui = new(user, src, ui_key, "atmos_filter", name, 475, 195, master_ui, state) ui = new(user, src, ui_key, "atmos_filter", name, 475, 195, master_ui, state)
ui.open() ui.open()
/obj/machinery/atmospherics/components/trinary/filter/ui_data() /obj/machinery/atmospherics/components/trinary/filter/ui_data()
var/data = list() var/data = list()
data["on"] = on data["on"] = on
data["pressure"] = round(target_pressure) data["pressure"] = round(target_pressure)
data["max_pressure"] = round(MAX_OUTPUT_PRESSURE) data["max_pressure"] = round(MAX_OUTPUT_PRESSURE)
data["filter_types"] = list() data["filter_types"] = list()
data["filter_types"] += list(list("name" = "Nothing", "path" = "", "selected" = !filter_type)) data["filter_types"] += list(list("name" = "Nothing", "path" = "", "selected" = !filter_type))
for(var/path in GLOB.meta_gas_info) for(var/path in GLOB.meta_gas_info)
var/list/gas = GLOB.meta_gas_info[path] var/list/gas = GLOB.meta_gas_info[path]
data["filter_types"] += list(list("name" = gas[META_GAS_NAME], "id" = gas[META_GAS_ID], "selected" = (path == gas_id2path(filter_type)))) data["filter_types"] += list(list("name" = gas[META_GAS_NAME], "id" = gas[META_GAS_ID], "selected" = (path == gas_id2path(filter_type))))
return data return data
/obj/machinery/atmospherics/components/trinary/filter/ui_act(action, params) /obj/machinery/atmospherics/components/trinary/filter/ui_act(action, params)
if(..()) if(..())
return return
switch(action) switch(action)
if("power") if("power")
on = !on on = !on
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", INVESTIGATE_ATMOS) investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", INVESTIGATE_ATMOS)
. = TRUE . = TRUE
if("pressure") if("pressure")
var/pressure = params["pressure"] var/pressure = params["pressure"]
if(pressure == "max") if(pressure == "max")
pressure = MAX_OUTPUT_PRESSURE pressure = MAX_OUTPUT_PRESSURE
. = TRUE . = TRUE
else if(pressure == "input") else if(pressure == "input")
pressure = input("New output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", name, target_pressure) as num|null pressure = input("New output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", name, target_pressure) as num|null
if(!isnull(pressure) && !..()) if(!isnull(pressure) && !..())
. = TRUE . = TRUE
else if(text2num(pressure) != null) else if(text2num(pressure) != null)
pressure = text2num(pressure) pressure = text2num(pressure)
. = TRUE . = TRUE
if(.) if(.)
target_pressure = CLAMP(pressure, 0, MAX_OUTPUT_PRESSURE) target_pressure = CLAMP(pressure, 0, MAX_OUTPUT_PRESSURE)
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", INVESTIGATE_ATMOS) investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", INVESTIGATE_ATMOS)
if("filter") if("filter")
filter_type = null filter_type = null
var/filter_name = "nothing" var/filter_name = "nothing"
var/gas = gas_id2path(params["mode"]) var/gas = gas_id2path(params["mode"])
if(gas in GLOB.meta_gas_info) if(gas in GLOB.meta_gas_info)
filter_type = gas filter_type = gas
filter_name = GLOB.meta_gas_info[gas][META_GAS_NAME] filter_name = GLOB.meta_gas_info[gas][META_GAS_NAME]
investigate_log("was set to filter [filter_name] by [key_name(usr)]", INVESTIGATE_ATMOS) investigate_log("was set to filter [filter_name] by [key_name(usr)]", INVESTIGATE_ATMOS)
. = TRUE . = TRUE
update_icon() update_icon()
/obj/machinery/atmospherics/components/trinary/filter/can_unwrench(mob/user) /obj/machinery/atmospherics/components/trinary/filter/can_unwrench(mob/user)
. = ..() . = ..()
if(. && on && is_operational()) if(. && on && is_operational())
to_chat(user, "<span class='warning'>You cannot unwrench [src], turn it off first!</span>") to_chat(user, "<span class='warning'>You cannot unwrench [src], turn it off first!</span>")
return FALSE return FALSE

View File

@@ -184,7 +184,7 @@
beaker.reagents.trans_to(occupant, 1, efficiency * 0.25) // Transfer reagents. beaker.reagents.trans_to(occupant, 1, efficiency * 0.25) // Transfer reagents.
beaker.reagents.reaction(occupant, VAPOR) beaker.reagents.reaction(occupant, VAPOR)
air1.gases[/datum/gas/oxygen] -= max(0,air1.gases[/datum/gas/oxygen] - 2 / efficiency) //Let's use gas for this air1.gases[/datum/gas/oxygen] -= max(0,air1.gases[/datum/gas/oxygen] - 2 / efficiency) //Let's use gas for this
air1.garbage_collect() GAS_GARBAGE_COLLECT(air1.gases)
if(++reagent_transfer >= 10 * efficiency) // Throttle reagent transfer (higher efficiency will transfer the same amount but consume less from the beaker). if(++reagent_transfer >= 10 * efficiency) // Throttle reagent transfer (higher efficiency will transfer the same amount but consume less from the beaker).
reagent_transfer = 0 reagent_transfer = 0
@@ -221,7 +221,7 @@
mob_occupant.adjust_bodytemperature(heat / heat_capacity, TCMB) mob_occupant.adjust_bodytemperature(heat / heat_capacity, TCMB)
air1.gases[/datum/gas/oxygen] = max(0,air1.gases[/datum/gas/oxygen] - 0.5 / efficiency) // Magically consume gas? Why not, we run on cryo magic. air1.gases[/datum/gas/oxygen] = max(0,air1.gases[/datum/gas/oxygen] - 0.5 / efficiency) // Magically consume gas? Why not, we run on cryo magic.
air1.garbage_collect() GAS_GARBAGE_COLLECT(air1.gases)
/obj/machinery/atmospherics/components/unary/cryo_cell/power_change() /obj/machinery/atmospherics/components/unary/cryo_cell/power_change()
..() ..()

View File

@@ -1,329 +1,329 @@
#define SIPHONING 0 #define SIPHONING 0
#define SCRUBBING 1 #define SCRUBBING 1
/obj/machinery/atmospherics/components/unary/vent_scrubber /obj/machinery/atmospherics/components/unary/vent_scrubber
name = "air scrubber" name = "air scrubber"
desc = "Has a valve and pump attached to it." desc = "Has a valve and pump attached to it."
icon_state = "scrub_map" icon_state = "scrub_map"
use_power = IDLE_POWER_USE use_power = IDLE_POWER_USE
idle_power_usage = 10 idle_power_usage = 10
active_power_usage = 60 active_power_usage = 60
can_unwrench = TRUE can_unwrench = TRUE
welded = FALSE welded = FALSE
level = 1 level = 1
layer = GAS_SCRUBBER_LAYER layer = GAS_SCRUBBER_LAYER
var/id_tag = null var/id_tag = null
var/scrubbing = SCRUBBING //0 = siphoning, 1 = scrubbing var/scrubbing = SCRUBBING //0 = siphoning, 1 = scrubbing
var/filter_types = list(/datum/gas/carbon_dioxide) var/filter_types = list(/datum/gas/carbon_dioxide)
var/volume_rate = 200 var/volume_rate = 200
var/widenet = 0 //is this scrubber acting on the 3x3 area around it. var/widenet = 0 //is this scrubber acting on the 3x3 area around it.
var/list/turf/adjacent_turfs = list() var/list/turf/adjacent_turfs = list()
var/frequency = FREQ_ATMOS_CONTROL var/frequency = FREQ_ATMOS_CONTROL
var/datum/radio_frequency/radio_connection var/datum/radio_frequency/radio_connection
var/radio_filter_out var/radio_filter_out
var/radio_filter_in var/radio_filter_in
pipe_state = "scrubber" pipe_state = "scrubber"
/obj/machinery/atmospherics/components/unary/vent_scrubber/layer1 /obj/machinery/atmospherics/components/unary/vent_scrubber/layer1
piping_layer = PIPING_LAYER_MIN piping_layer = PIPING_LAYER_MIN
pixel_x = -PIPING_LAYER_P_X pixel_x = -PIPING_LAYER_P_X
pixel_y = -PIPING_LAYER_P_Y pixel_y = -PIPING_LAYER_P_Y
/obj/machinery/atmospherics/components/unary/vent_scrubber/layer3 /obj/machinery/atmospherics/components/unary/vent_scrubber/layer3
piping_layer = PIPING_LAYER_MAX piping_layer = PIPING_LAYER_MAX
pixel_x = PIPING_LAYER_P_X pixel_x = PIPING_LAYER_P_X
pixel_y = PIPING_LAYER_P_Y pixel_y = PIPING_LAYER_P_Y
/obj/machinery/atmospherics/components/unary/vent_scrubber/New() /obj/machinery/atmospherics/components/unary/vent_scrubber/New()
..() ..()
if(!id_tag) if(!id_tag)
id_tag = assign_uid_vents() id_tag = assign_uid_vents()
for(var/f in filter_types) for(var/f in filter_types)
if(istext(f)) if(istext(f))
filter_types -= f filter_types -= f
filter_types += gas_id2path(f) filter_types += gas_id2path(f)
/obj/machinery/atmospherics/components/unary/vent_scrubber/on /obj/machinery/atmospherics/components/unary/vent_scrubber/on
on = TRUE on = TRUE
icon_state = "scrub_map_on" icon_state = "scrub_map_on"
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer1 /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer1
piping_layer = PIPING_LAYER_MIN piping_layer = PIPING_LAYER_MIN
pixel_x = -PIPING_LAYER_P_X pixel_x = -PIPING_LAYER_P_X
pixel_y = -PIPING_LAYER_P_Y pixel_y = -PIPING_LAYER_P_Y
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3 /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3
piping_layer = PIPING_LAYER_MAX piping_layer = PIPING_LAYER_MAX
pixel_x = PIPING_LAYER_P_X pixel_x = PIPING_LAYER_P_X
pixel_y = PIPING_LAYER_P_Y pixel_y = PIPING_LAYER_P_Y
/obj/machinery/atmospherics/components/unary/vent_scrubber/Destroy() /obj/machinery/atmospherics/components/unary/vent_scrubber/Destroy()
var/area/A = get_area(src) var/area/A = get_area(src)
if (A) if (A)
A.air_scrub_names -= id_tag A.air_scrub_names -= id_tag
A.air_scrub_info -= id_tag A.air_scrub_info -= id_tag
SSradio.remove_object(src,frequency) SSradio.remove_object(src,frequency)
radio_connection = null radio_connection = null
adjacent_turfs.Cut() adjacent_turfs.Cut()
return ..() return ..()
/obj/machinery/atmospherics/components/unary/vent_scrubber/auto_use_power() /obj/machinery/atmospherics/components/unary/vent_scrubber/auto_use_power()
if(!on || welded || !is_operational() || !powered(power_channel)) if(!on || welded || !is_operational() || !powered(power_channel))
return FALSE return FALSE
var/amount = idle_power_usage var/amount = idle_power_usage
if(scrubbing & SCRUBBING) if(scrubbing & SCRUBBING)
amount += idle_power_usage * length(filter_types) amount += idle_power_usage * length(filter_types)
else //scrubbing == SIPHONING else //scrubbing == SIPHONING
amount = active_power_usage amount = active_power_usage
if(widenet) if(widenet)
amount += amount * (adjacent_turfs.len * (adjacent_turfs.len / 2)) amount += amount * (adjacent_turfs.len * (adjacent_turfs.len / 2))
use_power(amount, power_channel) use_power(amount, power_channel)
return TRUE return TRUE
/obj/machinery/atmospherics/components/unary/vent_scrubber/update_icon_nopipes() /obj/machinery/atmospherics/components/unary/vent_scrubber/update_icon_nopipes()
cut_overlays() cut_overlays()
if(showpipe) if(showpipe)
add_overlay(getpipeimage(icon, "scrub_cap", initialize_directions)) add_overlay(getpipeimage(icon, "scrub_cap", initialize_directions))
if(welded) if(welded)
icon_state = "scrub_welded" icon_state = "scrub_welded"
return return
if(!nodes[1] || !on || !is_operational()) if(!nodes[1] || !on || !is_operational())
icon_state = "scrub_off" icon_state = "scrub_off"
return return
if(scrubbing & SCRUBBING) if(scrubbing & SCRUBBING)
if(widenet) if(widenet)
icon_state = "scrub_wide" icon_state = "scrub_wide"
else else
icon_state = "scrub_on" icon_state = "scrub_on"
else //scrubbing == SIPHONING else //scrubbing == SIPHONING
icon_state = "scrub_purge" icon_state = "scrub_purge"
/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/set_frequency(new_frequency) /obj/machinery/atmospherics/components/unary/vent_scrubber/proc/set_frequency(new_frequency)
SSradio.remove_object(src, frequency) SSradio.remove_object(src, frequency)
frequency = new_frequency frequency = new_frequency
radio_connection = SSradio.add_object(src, frequency, radio_filter_in) radio_connection = SSradio.add_object(src, frequency, radio_filter_in)
/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/broadcast_status() /obj/machinery/atmospherics/components/unary/vent_scrubber/proc/broadcast_status()
if(!radio_connection) if(!radio_connection)
return FALSE return FALSE
var/list/f_types = list() var/list/f_types = list()
for(var/path in GLOB.meta_gas_info) for(var/path in GLOB.meta_gas_info)
var/list/gas = GLOB.meta_gas_info[path] var/list/gas = GLOB.meta_gas_info[path]
f_types += list(list("gas_id" = gas[META_GAS_ID], "gas_name" = gas[META_GAS_NAME], "enabled" = (path in filter_types))) f_types += list(list("gas_id" = gas[META_GAS_ID], "gas_name" = gas[META_GAS_NAME], "enabled" = (path in filter_types)))
var/datum/signal/signal = new(list( var/datum/signal/signal = new(list(
"tag" = id_tag, "tag" = id_tag,
"frequency" = frequency, "frequency" = frequency,
"device" = "VS", "device" = "VS",
"timestamp" = world.time, "timestamp" = world.time,
"power" = on, "power" = on,
"scrubbing" = scrubbing, "scrubbing" = scrubbing,
"widenet" = widenet, "widenet" = widenet,
"filter_types" = f_types, "filter_types" = f_types,
"sigtype" = "status" "sigtype" = "status"
)) ))
var/area/A = get_area(src) var/area/A = get_area(src)
if(!A.air_scrub_names[id_tag]) if(!A.air_scrub_names[id_tag])
name = "\improper [A.name] air scrubber #[A.air_scrub_names.len + 1]" name = "\improper [A.name] air scrubber #[A.air_scrub_names.len + 1]"
A.air_scrub_names[id_tag] = name A.air_scrub_names[id_tag] = name
A.air_scrub_info[id_tag] = signal.data A.air_scrub_info[id_tag] = signal.data
radio_connection.post_signal(src, signal, radio_filter_out) radio_connection.post_signal(src, signal, radio_filter_out)
return TRUE return TRUE
/obj/machinery/atmospherics/components/unary/vent_scrubber/atmosinit() /obj/machinery/atmospherics/components/unary/vent_scrubber/atmosinit()
radio_filter_in = frequency==initial(frequency)?(RADIO_FROM_AIRALARM):null radio_filter_in = frequency==initial(frequency)?(RADIO_FROM_AIRALARM):null
radio_filter_out = frequency==initial(frequency)?(RADIO_TO_AIRALARM):null radio_filter_out = frequency==initial(frequency)?(RADIO_TO_AIRALARM):null
if(frequency) if(frequency)
set_frequency(frequency) set_frequency(frequency)
broadcast_status() broadcast_status()
check_turfs() check_turfs()
..() ..()
/obj/machinery/atmospherics/components/unary/vent_scrubber/process_atmos() /obj/machinery/atmospherics/components/unary/vent_scrubber/process_atmos()
..() ..()
if(welded || !is_operational()) if(welded || !is_operational())
return FALSE return FALSE
if(!nodes[1] || !on) if(!nodes[1] || !on)
on = FALSE on = FALSE
return FALSE return FALSE
scrub(loc) scrub(loc)
if(widenet) if(widenet)
for(var/turf/tile in adjacent_turfs) for(var/turf/tile in adjacent_turfs)
scrub(tile) scrub(tile)
return TRUE return TRUE
/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/scrub(var/turf/tile) /obj/machinery/atmospherics/components/unary/vent_scrubber/proc/scrub(var/turf/tile)
if(!istype(tile)) if(!istype(tile))
return FALSE return FALSE
var/datum/gas_mixture/environment = tile.return_air() var/datum/gas_mixture/environment = tile.return_air()
var/datum/gas_mixture/air_contents = airs[1] var/datum/gas_mixture/air_contents = airs[1]
var/list/env_gases = environment.gases var/list/env_gases = environment.gases
if(air_contents.return_pressure() >= 50*ONE_ATMOSPHERE) if(air_contents.return_pressure() >= 50*ONE_ATMOSPHERE)
return FALSE return FALSE
if(scrubbing & SCRUBBING) if(scrubbing & SCRUBBING)
if(length(env_gases & filter_types)) if(length(env_gases & filter_types))
var/transfer_moles = min(1, volume_rate/environment.volume)*environment.total_moles() var/transfer_moles = min(1, volume_rate/environment.volume)*environment.total_moles()
//Take a gas sample //Take a gas sample
var/datum/gas_mixture/removed = tile.remove_air(transfer_moles) var/datum/gas_mixture/removed = tile.remove_air(transfer_moles)
//Nothing left to remove from the tile //Nothing left to remove from the tile
if(isnull(removed)) if(isnull(removed))
return FALSE return FALSE
var/list/removed_gases = removed.gases var/list/removed_gases = removed.gases
//Filter it //Filter it
var/datum/gas_mixture/filtered_out = new var/datum/gas_mixture/filtered_out = new
var/list/filtered_gases = filtered_out.gases var/list/filtered_gases = filtered_out.gases
filtered_out.temperature = removed.temperature filtered_out.temperature = removed.temperature
for(var/gas in filter_types & removed_gases) for(var/gas in filter_types & removed_gases)
filtered_gases[gas] = removed_gases[gas] filtered_gases[gas] = removed_gases[gas]
removed_gases[gas] = 0 removed_gases[gas] = 0
removed.garbage_collect() GAS_GARBAGE_COLLECT(removed.gases)
//Remix the resulting gases //Remix the resulting gases
air_contents.merge(filtered_out) air_contents.merge(filtered_out)
tile.assume_air(removed) tile.assume_air(removed)
tile.air_update_turf() tile.air_update_turf()
else //Just siphoning all air else //Just siphoning all air
var/transfer_moles = environment.total_moles()*(volume_rate/environment.volume) var/transfer_moles = environment.total_moles()*(volume_rate/environment.volume)
var/datum/gas_mixture/removed = tile.remove_air(transfer_moles) var/datum/gas_mixture/removed = tile.remove_air(transfer_moles)
air_contents.merge(removed) air_contents.merge(removed)
tile.air_update_turf() tile.air_update_turf()
update_parents() update_parents()
return TRUE return TRUE
//There is no easy way for an object to be notified of changes to atmos can pass flags //There is no easy way for an object to be notified of changes to atmos can pass flags
// So we check every machinery process (2 seconds) // So we check every machinery process (2 seconds)
/obj/machinery/atmospherics/components/unary/vent_scrubber/process() /obj/machinery/atmospherics/components/unary/vent_scrubber/process()
if(widenet) if(widenet)
check_turfs() check_turfs()
//we populate a list of turfs with nonatmos-blocked cardinal turfs AND //we populate a list of turfs with nonatmos-blocked cardinal turfs AND
// diagonal turfs that can share atmos with *both* of the cardinal turfs // diagonal turfs that can share atmos with *both* of the cardinal turfs
/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/check_turfs() /obj/machinery/atmospherics/components/unary/vent_scrubber/proc/check_turfs()
adjacent_turfs.Cut() adjacent_turfs.Cut()
var/turf/T = get_turf(src) var/turf/T = get_turf(src)
if(istype(T)) if(istype(T))
adjacent_turfs = T.GetAtmosAdjacentTurfs(alldir = 1) adjacent_turfs = T.GetAtmosAdjacentTurfs(alldir = 1)
/obj/machinery/atmospherics/components/unary/vent_scrubber/receive_signal(datum/signal/signal) /obj/machinery/atmospherics/components/unary/vent_scrubber/receive_signal(datum/signal/signal)
if(!is_operational() || !signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command")) if(!is_operational() || !signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command"))
return 0 return 0
var/mob/signal_sender = signal.data["user"] var/mob/signal_sender = signal.data["user"]
if("power" in signal.data) if("power" in signal.data)
on = text2num(signal.data["power"]) on = text2num(signal.data["power"])
if("power_toggle" in signal.data) if("power_toggle" in signal.data)
on = !on on = !on
if("widenet" in signal.data) if("widenet" in signal.data)
widenet = text2num(signal.data["widenet"]) widenet = text2num(signal.data["widenet"])
if("toggle_widenet" in signal.data) if("toggle_widenet" in signal.data)
widenet = !widenet widenet = !widenet
var/old_scrubbing = scrubbing var/old_scrubbing = scrubbing
if("scrubbing" in signal.data) if("scrubbing" in signal.data)
scrubbing = text2num(signal.data["scrubbing"]) scrubbing = text2num(signal.data["scrubbing"])
if("toggle_scrubbing" in signal.data) if("toggle_scrubbing" in signal.data)
scrubbing = !scrubbing scrubbing = !scrubbing
if(scrubbing != old_scrubbing) if(scrubbing != old_scrubbing)
investigate_log(" was toggled to [scrubbing ? "scrubbing" : "siphon"] mode by [key_name(signal_sender)]",INVESTIGATE_ATMOS) investigate_log(" was toggled to [scrubbing ? "scrubbing" : "siphon"] mode by [key_name(signal_sender)]",INVESTIGATE_ATMOS)
if("toggle_filter" in signal.data) if("toggle_filter" in signal.data)
filter_types ^= gas_id2path(signal.data["toggle_filter"]) filter_types ^= gas_id2path(signal.data["toggle_filter"])
if("set_filters" in signal.data) if("set_filters" in signal.data)
filter_types = list() filter_types = list()
for(var/gas in signal.data["set_filters"]) for(var/gas in signal.data["set_filters"])
filter_types += gas_id2path(gas) filter_types += gas_id2path(gas)
if("init" in signal.data) if("init" in signal.data)
name = signal.data["init"] name = signal.data["init"]
return return
if("status" in signal.data) if("status" in signal.data)
broadcast_status() broadcast_status()
return //do not update_icon return //do not update_icon
broadcast_status() broadcast_status()
update_icon() update_icon()
return return
/obj/machinery/atmospherics/components/unary/vent_scrubber/power_change() /obj/machinery/atmospherics/components/unary/vent_scrubber/power_change()
..() ..()
update_icon_nopipes() update_icon_nopipes()
/obj/machinery/atmospherics/components/unary/vent_scrubber/welder_act(mob/living/user, obj/item/I) /obj/machinery/atmospherics/components/unary/vent_scrubber/welder_act(mob/living/user, obj/item/I)
if(!I.tool_start_check(user, amount=0)) if(!I.tool_start_check(user, amount=0))
return TRUE return TRUE
to_chat(user, "<span class='notice'>Now welding the scrubber.</span>") to_chat(user, "<span class='notice'>Now welding the scrubber.</span>")
if(I.use_tool(src, user, 20, volume=50)) if(I.use_tool(src, user, 20, volume=50))
if(!welded) if(!welded)
user.visible_message("[user] welds the scrubber shut.","You weld the scrubber shut.", "You hear welding.") user.visible_message("[user] welds the scrubber shut.","You weld the scrubber shut.", "You hear welding.")
welded = TRUE welded = TRUE
else else
user.visible_message("[user] unwelds the scrubber.", "You unweld the scrubber.", "You hear welding.") user.visible_message("[user] unwelds the scrubber.", "You unweld the scrubber.", "You hear welding.")
welded = FALSE welded = FALSE
update_icon() update_icon()
pipe_vision_img = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir) pipe_vision_img = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir)
pipe_vision_img.plane = ABOVE_HUD_PLANE pipe_vision_img.plane = ABOVE_HUD_PLANE
return TRUE return TRUE
/obj/machinery/atmospherics/components/unary/vent_scrubber/can_unwrench(mob/user) /obj/machinery/atmospherics/components/unary/vent_scrubber/can_unwrench(mob/user)
. = ..() . = ..()
if(. && on && is_operational()) if(. && on && is_operational())
to_chat(user, "<span class='warning'>You cannot unwrench [src], turn it off first!</span>") to_chat(user, "<span class='warning'>You cannot unwrench [src], turn it off first!</span>")
return FALSE return FALSE
/obj/machinery/atmospherics/components/unary/vent_scrubber/examine(mob/user) /obj/machinery/atmospherics/components/unary/vent_scrubber/examine(mob/user)
..() ..()
if(welded) if(welded)
to_chat(user, "It seems welded shut.") to_chat(user, "It seems welded shut.")
/obj/machinery/atmospherics/components/unary/vent_scrubber/can_crawl_through() /obj/machinery/atmospherics/components/unary/vent_scrubber/can_crawl_through()
return !welded return !welded
/obj/machinery/atmospherics/components/unary/vent_scrubber/attack_alien(mob/user) /obj/machinery/atmospherics/components/unary/vent_scrubber/attack_alien(mob/user)
if(!welded || !(do_after(user, 20, target = src))) if(!welded || !(do_after(user, 20, target = src)))
return return
user.visible_message("[user] furiously claws at [src]!", "You manage to clear away the stuff blocking the scrubber.", "You hear loud scraping noises.") user.visible_message("[user] furiously claws at [src]!", "You manage to clear away the stuff blocking the scrubber.", "You hear loud scraping noises.")
welded = FALSE welded = FALSE
update_icon() update_icon()
pipe_vision_img = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir) pipe_vision_img = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir)
pipe_vision_img.plane = ABOVE_HUD_PLANE pipe_vision_img.plane = ABOVE_HUD_PLANE
playsound(loc, 'sound/weapons/bladeslice.ogg', 100, 1) playsound(loc, 'sound/weapons/bladeslice.ogg', 100, 1)
#undef SIPHONING #undef SIPHONING
#undef SCRUBBING #undef SCRUBBING

View File

@@ -1,145 +1,145 @@
/obj/machinery/portable_atmospherics/scrubber /obj/machinery/portable_atmospherics/scrubber
name = "portable air scrubber" name = "portable air scrubber"
icon_state = "pscrubber:0" icon_state = "pscrubber:0"
density = TRUE density = TRUE
var/on = FALSE var/on = FALSE
var/volume_rate = 1000 var/volume_rate = 1000
volume = 1000 volume = 1000
var/list/scrubbing = list(/datum/gas/plasma, /datum/gas/carbon_dioxide, /datum/gas/nitrous_oxide, /datum/gas/bz, /datum/gas/nitryl, /datum/gas/tritium, /datum/gas/hypernoblium, /datum/gas/water_vapor) var/list/scrubbing = list(/datum/gas/plasma, /datum/gas/carbon_dioxide, /datum/gas/nitrous_oxide, /datum/gas/bz, /datum/gas/nitryl, /datum/gas/tritium, /datum/gas/hypernoblium, /datum/gas/water_vapor)
/obj/machinery/portable_atmospherics/scrubber/Destroy() /obj/machinery/portable_atmospherics/scrubber/Destroy()
var/turf/T = get_turf(src) var/turf/T = get_turf(src)
T.assume_air(air_contents) T.assume_air(air_contents)
air_update_turf() air_update_turf()
return ..() return ..()
/obj/machinery/portable_atmospherics/scrubber/update_icon() /obj/machinery/portable_atmospherics/scrubber/update_icon()
icon_state = "pscrubber:[on]" icon_state = "pscrubber:[on]"
cut_overlays() cut_overlays()
if(holding) if(holding)
add_overlay("scrubber-open") add_overlay("scrubber-open")
if(connected_port) if(connected_port)
add_overlay("scrubber-connector") add_overlay("scrubber-connector")
/obj/machinery/portable_atmospherics/scrubber/process_atmos() /obj/machinery/portable_atmospherics/scrubber/process_atmos()
..() ..()
if(!on) if(!on)
return return
if(holding) if(holding)
scrub(holding.air_contents) scrub(holding.air_contents)
else else
var/turf/T = get_turf(src) var/turf/T = get_turf(src)
scrub(T.return_air()) scrub(T.return_air())
/obj/machinery/portable_atmospherics/scrubber/proc/scrub(var/datum/gas_mixture/mixture) /obj/machinery/portable_atmospherics/scrubber/proc/scrub(var/datum/gas_mixture/mixture)
var/transfer_moles = min(1, volume_rate / mixture.volume) * mixture.total_moles() var/transfer_moles = min(1, volume_rate / mixture.volume) * mixture.total_moles()
var/datum/gas_mixture/filtering = mixture.remove(transfer_moles) // Remove part of the mixture to filter. var/datum/gas_mixture/filtering = mixture.remove(transfer_moles) // Remove part of the mixture to filter.
var/datum/gas_mixture/filtered = new var/datum/gas_mixture/filtered = new
if(!filtering) if(!filtering)
return return
filtered.temperature = filtering.temperature filtered.temperature = filtering.temperature
for(var/gas in filtering.gases & scrubbing) for(var/gas in filtering.gases & scrubbing)
filtered.gases[gas] = filtering.gases[gas] // Shuffle the "bad" gasses to the filtered mixture. filtered.gases[gas] = filtering.gases[gas] // Shuffle the "bad" gasses to the filtered mixture.
filtering.gases[gas] = 0 filtering.gases[gas] = 0
filtering.garbage_collect() // Now that the gasses are set to 0, clean up the mixture. GAS_GARBAGE_COLLECT(filtering.gases)
air_contents.merge(filtered) // Store filtered out gasses. air_contents.merge(filtered) // Store filtered out gasses.
mixture.merge(filtering) // Returned the cleaned gas. mixture.merge(filtering) // Returned the cleaned gas.
if(!holding) if(!holding)
air_update_turf() air_update_turf()
/obj/machinery/portable_atmospherics/scrubber/emp_act(severity) /obj/machinery/portable_atmospherics/scrubber/emp_act(severity)
. = ..() . = ..()
if(. & EMP_PROTECT_SELF) if(. & EMP_PROTECT_SELF)
return return
if(is_operational()) if(is_operational())
if(prob(50 / severity)) if(prob(50 / severity))
on = !on on = !on
update_icon() update_icon()
/obj/machinery/portable_atmospherics/scrubber/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ /obj/machinery/portable_atmospherics/scrubber/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state) datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui) if(!ui)
ui = new(user, src, ui_key, "portable_scrubber", name, 420, 435, master_ui, state) ui = new(user, src, ui_key, "portable_scrubber", name, 420, 435, master_ui, state)
ui.open() ui.open()
/obj/machinery/portable_atmospherics/scrubber/ui_data() /obj/machinery/portable_atmospherics/scrubber/ui_data()
var/data = list() var/data = list()
data["on"] = on data["on"] = on
data["connected"] = connected_port ? 1 : 0 data["connected"] = connected_port ? 1 : 0
data["pressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0) data["pressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0)
data["id_tag"] = -1 //must be defined in order to reuse code between portable and vent scrubbers data["id_tag"] = -1 //must be defined in order to reuse code between portable and vent scrubbers
data["filter_types"] = list() data["filter_types"] = list()
for(var/path in GLOB.meta_gas_info) for(var/path in GLOB.meta_gas_info)
var/list/gas = GLOB.meta_gas_info[path] var/list/gas = GLOB.meta_gas_info[path]
data["filter_types"] += list(list("gas_id" = gas[META_GAS_ID], "gas_name" = gas[META_GAS_NAME], "enabled" = (path in scrubbing))) data["filter_types"] += list(list("gas_id" = gas[META_GAS_ID], "gas_name" = gas[META_GAS_NAME], "enabled" = (path in scrubbing)))
if(holding) if(holding)
data["holding"] = list() data["holding"] = list()
data["holding"]["name"] = holding.name data["holding"]["name"] = holding.name
data["holding"]["pressure"] = round(holding.air_contents.return_pressure()) data["holding"]["pressure"] = round(holding.air_contents.return_pressure())
return data return data
/obj/machinery/portable_atmospherics/scrubber/ui_act(action, params) /obj/machinery/portable_atmospherics/scrubber/ui_act(action, params)
if(..()) if(..())
return return
switch(action) switch(action)
if("power") if("power")
on = !on on = !on
. = TRUE . = TRUE
if("eject") if("eject")
if(holding) if(holding)
holding.forceMove(drop_location()) holding.forceMove(drop_location())
holding = null holding = null
. = TRUE . = TRUE
if("toggle_filter") if("toggle_filter")
scrubbing ^= gas_id2path(params["val"]) scrubbing ^= gas_id2path(params["val"])
. = TRUE . = TRUE
update_icon() update_icon()
/obj/machinery/portable_atmospherics/scrubber/huge /obj/machinery/portable_atmospherics/scrubber/huge
name = "huge air scrubber" name = "huge air scrubber"
icon_state = "scrubber:0" icon_state = "scrubber:0"
anchored = TRUE anchored = TRUE
active_power_usage = 500 active_power_usage = 500
idle_power_usage = 10 idle_power_usage = 10
volume_rate = 1500 volume_rate = 1500
volume = 50000 volume = 50000
var/movable = FALSE var/movable = FALSE
/obj/machinery/portable_atmospherics/scrubber/huge/movable /obj/machinery/portable_atmospherics/scrubber/huge/movable
movable = TRUE movable = TRUE
/obj/machinery/portable_atmospherics/scrubber/huge/update_icon() /obj/machinery/portable_atmospherics/scrubber/huge/update_icon()
icon_state = "scrubber:[on]" icon_state = "scrubber:[on]"
/obj/machinery/portable_atmospherics/scrubber/huge/process_atmos() /obj/machinery/portable_atmospherics/scrubber/huge/process_atmos()
if((!anchored && !movable) || !is_operational()) if((!anchored && !movable) || !is_operational())
on = FALSE on = FALSE
update_icon() update_icon()
use_power = on ? ACTIVE_POWER_USE : IDLE_POWER_USE use_power = on ? ACTIVE_POWER_USE : IDLE_POWER_USE
if(!on) if(!on)
return return
..() ..()
if(!holding) if(!holding)
var/turf/T = get_turf(src) var/turf/T = get_turf(src)
for(var/turf/AT in T.GetAtmosAdjacentTurfs(alldir = TRUE)) for(var/turf/AT in T.GetAtmosAdjacentTurfs(alldir = TRUE))
scrub(AT.return_air()) scrub(AT.return_air())
/obj/machinery/portable_atmospherics/scrubber/huge/attackby(obj/item/W, mob/user) /obj/machinery/portable_atmospherics/scrubber/huge/attackby(obj/item/W, mob/user)
if(default_unfasten_wrench(user, W)) if(default_unfasten_wrench(user, W))
if(!movable) if(!movable)
on = FALSE on = FALSE
else else
return ..() return ..()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -31,7 +31,7 @@
breath_gases[/datum/gas/plasma] -= toxins_used breath_gases[/datum/gas/plasma] -= toxins_used
breath_gases[/datum/gas/oxygen] += toxins_used breath_gases[/datum/gas/oxygen] += toxins_used
breath.garbage_collect() GAS_GARBAGE_COLLECT(breath.gases)
//BREATH TEMPERATURE //BREATH TEMPERATURE
handle_breath_temperature(breath) handle_breath_temperature(breath)

View File

@@ -291,7 +291,7 @@
breath.garbage_collect() GAS_GARBAGE_COLLECT(breath.gases)
//BREATH TEMPERATURE //BREATH TEMPERATURE
handle_breath_temperature(breath) handle_breath_temperature(breath)

File diff suppressed because it is too large Load Diff

View File

@@ -46,7 +46,7 @@
var/gasdrained = min(powerproduction_drain*drainratio,loaded_tank.air_contents.gases[/datum/gas/plasma]) var/gasdrained = min(powerproduction_drain*drainratio,loaded_tank.air_contents.gases[/datum/gas/plasma])
loaded_tank.air_contents.gases[/datum/gas/plasma] -= gasdrained loaded_tank.air_contents.gases[/datum/gas/plasma] -= gasdrained
loaded_tank.air_contents.gases[/datum/gas/tritium] += gasdrained loaded_tank.air_contents.gases[/datum/gas/tritium] += gasdrained
loaded_tank.air_contents.garbage_collect() GAS_GARBAGE_COLLECT(loaded_tank.air_contents.gases)
var/power_produced = RAD_COLLECTOR_OUTPUT var/power_produced = RAD_COLLECTOR_OUTPUT
add_avail(power_produced) add_avail(power_produced)
@@ -60,7 +60,7 @@
loaded_tank.air_contents.gases[/datum/gas/tritium] -= gasdrained loaded_tank.air_contents.gases[/datum/gas/tritium] -= gasdrained
loaded_tank.air_contents.gases[/datum/gas/oxygen] -= gasdrained loaded_tank.air_contents.gases[/datum/gas/oxygen] -= gasdrained
loaded_tank.air_contents.gases[/datum/gas/carbon_dioxide] += gasdrained*2 loaded_tank.air_contents.gases[/datum/gas/carbon_dioxide] += gasdrained*2
loaded_tank.air_contents.garbage_collect() GAS_GARBAGE_COLLECT(loaded_tank.air_contents.gases)
var/bitcoins_mined = RAD_COLLECTOR_OUTPUT var/bitcoins_mined = RAD_COLLECTOR_OUTPUT
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, bitcoins_mined*RAD_COLLECTOR_MINING_CONVERSION_RATE) SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, bitcoins_mined*RAD_COLLECTOR_MINING_CONVERSION_RATE)
stored_power-=bitcoins_mined stored_power-=bitcoins_mined

View File

@@ -103,7 +103,7 @@ Chilling extracts:
if(istype(G)) if(istype(G))
G.gases[/datum/gas/plasma] = 0 G.gases[/datum/gas/plasma] = 0
filtered = TRUE filtered = TRUE
G.garbage_collect() GAS_GARBAGE_COLLECT(G.gases)
T.air_update_turf() T.air_update_turf()
if(filtered) if(filtered)
user.visible_message("<span class='notice'>Cracks spread throughout [src], and some air is sucked in!</span>") user.visible_message("<span class='notice'>Cracks spread throughout [src], and some air is sucked in!</span>")

View File

@@ -339,7 +339,7 @@
SEND_SIGNAL(owner, COMSIG_CLEAR_MOOD_EVENT, "smell") SEND_SIGNAL(owner, COMSIG_CLEAR_MOOD_EVENT, "smell")
handle_breath_temperature(breath, H) handle_breath_temperature(breath, H)
breath.garbage_collect() GAS_GARBAGE_COLLECT(breath.gases)
return TRUE return TRUE

View File

@@ -1,389 +1,389 @@
/* /*
DOG BORG EQUIPMENT HERE DOG BORG EQUIPMENT HERE
SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm ! SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
*/ */
/obj/item/dogborg/jaws /obj/item/dogborg/jaws
name = "Dogborg jaws" name = "Dogborg jaws"
desc = "The jaws of the debug errors oh god." desc = "The jaws of the debug errors oh god."
icon = 'icons/mob/dogborg.dmi' icon = 'icons/mob/dogborg.dmi'
flags_1 = CONDUCT_1 flags_1 = CONDUCT_1
force = 1 force = 1
throwforce = 0 throwforce = 0
w_class = 3 w_class = 3
hitsound = 'sound/weapons/bite.ogg' hitsound = 'sound/weapons/bite.ogg'
sharpness = IS_SHARP sharpness = IS_SHARP
/obj/item/dogborg/jaws/big /obj/item/dogborg/jaws/big
name = "combat jaws" name = "combat jaws"
desc = "The jaws of the law. Very sharp." desc = "The jaws of the law. Very sharp."
icon_state = "jaws" icon_state = "jaws"
force = 12 force = 12
attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced") attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced")
/obj/item/dogborg/jaws/small /obj/item/dogborg/jaws/small
name = "puppy jaws" name = "puppy jaws"
desc = "Rubberized teeth designed to protect accidental harm. Sharp enough for specialized tasks however." desc = "Rubberized teeth designed to protect accidental harm. Sharp enough for specialized tasks however."
icon_state = "smalljaws" icon_state = "smalljaws"
force = 6 force = 6
attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed") attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed")
var/status = 0 var/status = 0
/obj/item/dogborg/jaws/attack(atom/A, mob/living/silicon/robot/user) /obj/item/dogborg/jaws/attack(atom/A, mob/living/silicon/robot/user)
..() ..()
user.do_attack_animation(A, ATTACK_EFFECT_BITE) user.do_attack_animation(A, ATTACK_EFFECT_BITE)
log_combat(user, A, "bit") log_combat(user, A, "bit")
/obj/item/dogborg/jaws/small/attack_self(mob/user) /obj/item/dogborg/jaws/small/attack_self(mob/user)
var/mob/living/silicon/robot.R = user var/mob/living/silicon/robot.R = user
if(R.cell && R.cell.charge > 100) if(R.cell && R.cell.charge > 100)
if(R.emagged && status == 0) if(R.emagged && status == 0)
name = "combat jaws" name = "combat jaws"
icon_state = "jaws" icon_state = "jaws"
desc = "The jaws of the law." desc = "The jaws of the law."
force = 12 force = 12
attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced") attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced")
status = 1 status = 1
to_chat(user, "<span class='notice'>Your jaws are now [status ? "Combat" : "Pup'd"].</span>") to_chat(user, "<span class='notice'>Your jaws are now [status ? "Combat" : "Pup'd"].</span>")
else else
name = "puppy jaws" name = "puppy jaws"
icon_state = "smalljaws" icon_state = "smalljaws"
desc = "The jaws of a small dog." desc = "The jaws of a small dog."
force = 5 force = 5
attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed") attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed")
status = 0 status = 0
if(R.emagged) if(R.emagged)
to_chat(user, "<span class='notice'>Your jaws are now [status ? "Combat" : "Pup'd"].</span>") to_chat(user, "<span class='notice'>Your jaws are now [status ? "Combat" : "Pup'd"].</span>")
update_icon() update_icon()
//Boop //Boop
/obj/item/analyzer/nose /obj/item/analyzer/nose
name = "boop module" name = "boop module"
icon = 'icons/mob/dogborg.dmi' icon = 'icons/mob/dogborg.dmi'
icon_state = "nose" icon_state = "nose"
desc = "The BOOP module" desc = "The BOOP module"
flags_1 = CONDUCT_1 flags_1 = CONDUCT_1
force = 0 force = 0
throwforce = 0 throwforce = 0
attack_verb = list("nuzzles", "pushes", "boops") attack_verb = list("nuzzles", "pushes", "boops")
w_class = 1 w_class = 1
/obj/item/analyzer/nose/attack_self(mob/user) /obj/item/analyzer/nose/attack_self(mob/user)
user.visible_message("[user] sniffs around the air.", "<span class='warning'>You sniff the air for gas traces.</span>") user.visible_message("[user] sniffs around the air.", "<span class='warning'>You sniff the air for gas traces.</span>")
var/turf/location = user.loc var/turf/location = user.loc
if(!istype(location)) if(!istype(location))
return return
var/datum/gas_mixture/environment = location.return_air() var/datum/gas_mixture/environment = location.return_air()
var/pressure = environment.return_pressure() var/pressure = environment.return_pressure()
var/total_moles = environment.total_moles() var/total_moles = environment.total_moles()
to_chat(user, "<span class='info'><B>Results:</B></span>") to_chat(user, "<span class='info'><B>Results:</B></span>")
if(abs(pressure - ONE_ATMOSPHERE) < 10) if(abs(pressure - ONE_ATMOSPHERE) < 10)
to_chat(user, "<span class='info'>Pressure: [round(pressure,0.1)] kPa</span>") to_chat(user, "<span class='info'>Pressure: [round(pressure,0.1)] kPa</span>")
else else
to_chat(user, "<span class='alert'>Pressure: [round(pressure,0.1)] kPa</span>") to_chat(user, "<span class='alert'>Pressure: [round(pressure,0.1)] kPa</span>")
if(total_moles) if(total_moles)
var/list/env_gases = environment.gases var/list/env_gases = environment.gases
var/o2_concentration = env_gases[/datum/gas/oxygen]/total_moles var/o2_concentration = env_gases[/datum/gas/oxygen]/total_moles
var/n2_concentration = env_gases[/datum/gas/nitrogen]/total_moles var/n2_concentration = env_gases[/datum/gas/nitrogen]/total_moles
var/co2_concentration = env_gases[/datum/gas/carbon_dioxide]/total_moles var/co2_concentration = env_gases[/datum/gas/carbon_dioxide]/total_moles
var/plasma_concentration = env_gases[/datum/gas/plasma]/total_moles var/plasma_concentration = env_gases[/datum/gas/plasma]/total_moles
environment.garbage_collect() GAS_GARBAGE_COLLECT(environment.gases)
if(abs(n2_concentration - N2STANDARD) < 20) if(abs(n2_concentration - N2STANDARD) < 20)
to_chat(user, "<span class='info'>Nitrogen: [round(n2_concentration*100, 0.01)] %</span>") to_chat(user, "<span class='info'>Nitrogen: [round(n2_concentration*100, 0.01)] %</span>")
else else
to_chat(user, "<span class='alert'>Nitrogen: [round(n2_concentration*100, 0.01)] %</span>") to_chat(user, "<span class='alert'>Nitrogen: [round(n2_concentration*100, 0.01)] %</span>")
if(abs(o2_concentration - O2STANDARD) < 2) if(abs(o2_concentration - O2STANDARD) < 2)
to_chat(user, "<span class='info'>Oxygen: [round(o2_concentration*100, 0.01)] %</span>") to_chat(user, "<span class='info'>Oxygen: [round(o2_concentration*100, 0.01)] %</span>")
else else
to_chat(user, "<span class='alert'>Oxygen: [round(o2_concentration*100, 0.01)] %</span>") to_chat(user, "<span class='alert'>Oxygen: [round(o2_concentration*100, 0.01)] %</span>")
if(co2_concentration > 0.01) if(co2_concentration > 0.01)
to_chat(user, "<span class='alert'>CO2: [round(co2_concentration*100, 0.01)] %</span>") to_chat(user, "<span class='alert'>CO2: [round(co2_concentration*100, 0.01)] %</span>")
else else
to_chat(user, "<span class='info'>CO2: [round(co2_concentration*100, 0.01)] %</span>") to_chat(user, "<span class='info'>CO2: [round(co2_concentration*100, 0.01)] %</span>")
if(plasma_concentration > 0.005) if(plasma_concentration > 0.005)
to_chat(user, "<span class='alert'>Plasma: [round(plasma_concentration*100, 0.01)] %</span>") to_chat(user, "<span class='alert'>Plasma: [round(plasma_concentration*100, 0.01)] %</span>")
else else
to_chat(user, "<span class='info'>Plasma: [round(plasma_concentration*100, 0.01)] %</span>") to_chat(user, "<span class='info'>Plasma: [round(plasma_concentration*100, 0.01)] %</span>")
for(var/id in env_gases) for(var/id in env_gases)
if(id in GLOB.hardcoded_gases) if(id in GLOB.hardcoded_gases)
continue continue
var/gas_concentration = env_gases[id]/total_moles var/gas_concentration = env_gases[id]/total_moles
to_chat(user, "<span class='alert'>[GLOB.meta_gas_info[id][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] %</span>") to_chat(user, "<span class='alert'>[GLOB.meta_gas_info[id][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] %</span>")
to_chat(user, "<span class='info'>Temperature: [round(environment.temperature-T0C)] &deg;C</span>") to_chat(user, "<span class='info'>Temperature: [round(environment.temperature-T0C)] &deg;C</span>")
/obj/item/analyzer/nose/AltClick(mob/user) //Barometer output for measuring when the next storm happens /obj/item/analyzer/nose/AltClick(mob/user) //Barometer output for measuring when the next storm happens
. = ..() . = ..()
/obj/item/analyzer/nose/afterattack(atom/target, mob/user, proximity) /obj/item/analyzer/nose/afterattack(atom/target, mob/user, proximity)
. = ..() . = ..()
if(!proximity) if(!proximity)
return return
do_attack_animation(target, null, src) do_attack_animation(target, null, src)
user.visible_message("<span class='notice'>[user] [pick(attack_verb)] \the [target.name] with their nose!</span>") user.visible_message("<span class='notice'>[user] [pick(attack_verb)] \the [target.name] with their nose!</span>")
//Delivery //Delivery
/obj/item/storage/bag/borgdelivery /obj/item/storage/bag/borgdelivery
name = "fetching storage" name = "fetching storage"
desc = "Fetch the thing!" desc = "Fetch the thing!"
icon = 'icons/mob/dogborg.dmi' icon = 'icons/mob/dogborg.dmi'
icon_state = "dbag" icon_state = "dbag"
w_class = WEIGHT_CLASS_BULKY w_class = WEIGHT_CLASS_BULKY
/obj/item/storage/bag/borgdelivery/ComponentInitialize() /obj/item/storage/bag/borgdelivery/ComponentInitialize()
. = ..() . = ..()
GET_COMPONENT(STR, /datum/component/storage) GET_COMPONENT(STR, /datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_BULKY STR.max_w_class = WEIGHT_CLASS_BULKY
STR.max_combined_w_class = 5 STR.max_combined_w_class = 5
STR.max_items = 1 STR.max_items = 1
STR.cant_hold = typecacheof(list(/obj/item/disk/nuclear, /obj/item/radio/intercom)) STR.cant_hold = typecacheof(list(/obj/item/disk/nuclear, /obj/item/radio/intercom))
//Tongue stuff //Tongue stuff
/obj/item/soap/tongue /obj/item/soap/tongue
name = "synthetic tongue" name = "synthetic tongue"
desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face." desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face."
icon = 'icons/mob/dogborg.dmi' icon = 'icons/mob/dogborg.dmi'
icon_state = "synthtongue" icon_state = "synthtongue"
hitsound = 'sound/effects/attackblob.ogg' hitsound = 'sound/effects/attackblob.ogg'
cleanspeed = 80 cleanspeed = 80
var/status = 0 var/status = 0
/obj/item/soap/tongue/scrubpup /obj/item/soap/tongue/scrubpup
cleanspeed = 25 //slightly faster than a mop. cleanspeed = 25 //slightly faster than a mop.
/obj/item/soap/tongue/New() /obj/item/soap/tongue/New()
..() ..()
item_flags |= NOBLUDGEON //No more attack messages item_flags |= NOBLUDGEON //No more attack messages
/obj/item/soap/tongue/attack_self(mob/user) /obj/item/soap/tongue/attack_self(mob/user)
var/mob/living/silicon/robot.R = user var/mob/living/silicon/robot.R = user
if(R.cell && R.cell.charge > 100) if(R.cell && R.cell.charge > 100)
if(R.emagged && status == 0) if(R.emagged && status == 0)
status = !status status = !status
name = "energized tongue" name = "energized tongue"
desc = "Your tongue is energized for dangerously maximum efficency." desc = "Your tongue is energized for dangerously maximum efficency."
icon_state = "syndietongue" icon_state = "syndietongue"
to_chat(user, "<span class='notice'>Your tongue is now [status ? "Energized" : "Normal"].</span>") to_chat(user, "<span class='notice'>Your tongue is now [status ? "Energized" : "Normal"].</span>")
cleanspeed = 10 //(nerf'd)tator soap stat cleanspeed = 10 //(nerf'd)tator soap stat
else else
status = 0 status = 0
name = "synthetic tongue" name = "synthetic tongue"
desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face." desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face."
icon_state = "synthtongue" icon_state = "synthtongue"
cleanspeed = initial(cleanspeed) cleanspeed = initial(cleanspeed)
if(R.emagged) if(R.emagged)
to_chat(user, "<span class='notice'>Your tongue is now [status ? "Energized" : "Normal"].</span>") to_chat(user, "<span class='notice'>Your tongue is now [status ? "Energized" : "Normal"].</span>")
update_icon() update_icon()
/obj/item/soap/tongue/afterattack(atom/target, mob/user, proximity) /obj/item/soap/tongue/afterattack(atom/target, mob/user, proximity)
var/mob/living/silicon/robot.R = user var/mob/living/silicon/robot.R = user
if(!proximity || !check_allowed_items(target)) if(!proximity || !check_allowed_items(target))
return return
if(R.client && (target in R.client.screen)) if(R.client && (target in R.client.screen))
to_chat(R, "<span class='warning'>You need to take that [target.name] off before cleaning it!</span>") to_chat(R, "<span class='warning'>You need to take that [target.name] off before cleaning it!</span>")
else if(is_cleanable(target)) else if(is_cleanable(target))
R.visible_message("[R] begins to lick off \the [target.name].", "<span class='warning'>You begin to lick off \the [target.name]...</span>") R.visible_message("[R] begins to lick off \the [target.name].", "<span class='warning'>You begin to lick off \the [target.name]...</span>")
if(do_after(R, src.cleanspeed, target = target)) if(do_after(R, src.cleanspeed, target = target))
if(!in_range(src, target)) //Proximity is probably old news by now, do a new check. if(!in_range(src, target)) //Proximity is probably old news by now, do a new check.
return //If they moved away, you can't eat them. return //If they moved away, you can't eat them.
to_chat(R, "<span class='notice'>You finish licking off \the [target.name].</span>") to_chat(R, "<span class='notice'>You finish licking off \the [target.name].</span>")
qdel(target) qdel(target)
R.cell.give(50) R.cell.give(50)
else if(isobj(target)) //hoo boy. danger zone man else if(isobj(target)) //hoo boy. danger zone man
if(istype(target,/obj/item/trash)) if(istype(target,/obj/item/trash))
R.visible_message("[R] nibbles away at \the [target.name].", "<span class='warning'>You begin to nibble away at \the [target.name]...</span>") R.visible_message("[R] nibbles away at \the [target.name].", "<span class='warning'>You begin to nibble away at \the [target.name]...</span>")
if(!do_after(R, src.cleanspeed, target = target)) if(!do_after(R, src.cleanspeed, target = target))
return //If they moved away, you can't eat them. return //If they moved away, you can't eat them.
to_chat(R, "<span class='notice'>You finish off \the [target.name].</span>") to_chat(R, "<span class='notice'>You finish off \the [target.name].</span>")
qdel(target) qdel(target)
R.cell.give(250) R.cell.give(250)
return return
if(istype(target,/obj/item/stock_parts/cell)) if(istype(target,/obj/item/stock_parts/cell))
R.visible_message("[R] begins cramming \the [target.name] down its throat.", "<span class='warning'>You begin cramming \the [target.name] down your throat...</span>") R.visible_message("[R] begins cramming \the [target.name] down its throat.", "<span class='warning'>You begin cramming \the [target.name] down your throat...</span>")
if(!do_after(R, 50, target = target)) if(!do_after(R, 50, target = target))
return //If they moved away, you can't eat them. return //If they moved away, you can't eat them.
to_chat(R, "<span class='notice'>You finish off \the [target.name].</span>") to_chat(R, "<span class='notice'>You finish off \the [target.name].</span>")
var/obj/item/stock_parts/cell.C = target var/obj/item/stock_parts/cell.C = target
R.cell.charge = R.cell.charge + (C.charge / 3) //Instant full cell upgrades op idgaf R.cell.charge = R.cell.charge + (C.charge / 3) //Instant full cell upgrades op idgaf
qdel(target) qdel(target)
return return
var/obj/item/I = target //HAHA FUCK IT, NOT LIKE WE ALREADY HAVE A SHITTON OF WAYS TO REMOVE SHIT var/obj/item/I = target //HAHA FUCK IT, NOT LIKE WE ALREADY HAVE A SHITTON OF WAYS TO REMOVE SHIT
if(!I.anchored && R.emagged) if(!I.anchored && R.emagged)
R.visible_message("[R] begins chewing up \the [target.name]. Looks like it's trying to loophole around its diet restriction!", "<span class='warning'>You begin chewing up \the [target.name]...</span>") R.visible_message("[R] begins chewing up \the [target.name]. Looks like it's trying to loophole around its diet restriction!", "<span class='warning'>You begin chewing up \the [target.name]...</span>")
if(!do_after(R, 100, target = I)) //Nerf dat time yo if(!do_after(R, 100, target = I)) //Nerf dat time yo
return //If they moved away, you can't eat them. return //If they moved away, you can't eat them.
visible_message("<span class='warning'>[R] chews up \the [target.name] and cleans off the debris!</span>") visible_message("<span class='warning'>[R] chews up \the [target.name] and cleans off the debris!</span>")
to_chat(R, "<span class='notice'>You finish off \the [target.name].</span>") to_chat(R, "<span class='notice'>You finish off \the [target.name].</span>")
qdel(I) qdel(I)
R.cell.give(500) R.cell.give(500)
return return
R.visible_message("[R] begins to lick \the [target.name] clean...", "<span class='notice'>You begin to lick \the [target.name] clean...</span>") R.visible_message("[R] begins to lick \the [target.name] clean...", "<span class='notice'>You begin to lick \the [target.name] clean...</span>")
else if(ishuman(target)) else if(ishuman(target))
var/mob/living/L = target var/mob/living/L = target
if(status == 0 && check_zone(R.zone_selected) == "head") if(status == 0 && check_zone(R.zone_selected) == "head")
R.visible_message("<span class='warning'>\the [R] affectionally licks \the [L]'s face!</span>", "<span class='notice'>You affectionally lick \the [L]'s face!</span>") R.visible_message("<span class='warning'>\the [R] affectionally licks \the [L]'s face!</span>", "<span class='notice'>You affectionally lick \the [L]'s face!</span>")
playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1) playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
if(istype(L) && L.fire_stacks > 0) if(istype(L) && L.fire_stacks > 0)
L.adjust_fire_stacks(-10) L.adjust_fire_stacks(-10)
return return
else if(status == 0) else if(status == 0)
R.visible_message("<span class='warning'>\the [R] affectionally licks \the [L]!</span>", "<span class='notice'>You affectionally lick \the [L]!</span>") R.visible_message("<span class='warning'>\the [R] affectionally licks \the [L]!</span>", "<span class='notice'>You affectionally lick \the [L]!</span>")
playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1) playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
if(istype(L) && L.fire_stacks > 0) if(istype(L) && L.fire_stacks > 0)
L.adjust_fire_stacks(-10) L.adjust_fire_stacks(-10)
return return
else else
if(R.cell.charge <= 800) if(R.cell.charge <= 800)
to_chat(R, "Insufficent Power!") to_chat(R, "Insufficent Power!")
return return
L.Stun(4) // normal stunbaton is force 7 gimme a break good sir! L.Stun(4) // normal stunbaton is force 7 gimme a break good sir!
L.Knockdown(80) L.Knockdown(80)
L.apply_effect(EFFECT_STUTTER, 4) L.apply_effect(EFFECT_STUTTER, 4)
L.visible_message("<span class='danger'>[R] has shocked [L] with its tongue!</span>", \ L.visible_message("<span class='danger'>[R] has shocked [L] with its tongue!</span>", \
"<span class='userdanger'>[R] has shocked you with its tongue!</span>") "<span class='userdanger'>[R] has shocked you with its tongue!</span>")
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1) playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
R.cell.use(666) R.cell.use(666)
log_combat(R, L, "tongue stunned") log_combat(R, L, "tongue stunned")
else if(istype(target, /obj/structure/window)) else if(istype(target, /obj/structure/window))
R.visible_message("[R] begins to lick \the [target.name] clean...", "<span class='notice'>You begin to lick \the [target.name] clean...</span>") R.visible_message("[R] begins to lick \the [target.name] clean...", "<span class='notice'>You begin to lick \the [target.name] clean...</span>")
if(do_after(user, src.cleanspeed, target = target)) if(do_after(user, src.cleanspeed, target = target))
to_chat(user, "<span class='notice'>You clean \the [target.name].</span>") to_chat(user, "<span class='notice'>You clean \the [target.name].</span>")
target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY) target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
target.set_opacity(initial(target.opacity)) target.set_opacity(initial(target.opacity))
else else
R.visible_message("[R] begins to lick \the [target.name] clean...", "<span class='notice'>You begin to lick \the [target.name] clean...</span>") R.visible_message("[R] begins to lick \the [target.name] clean...", "<span class='notice'>You begin to lick \the [target.name] clean...</span>")
if(do_after(user, src.cleanspeed, target = target)) if(do_after(user, src.cleanspeed, target = target))
to_chat(user, "<span class='notice'>You clean \the [target.name].</span>") to_chat(user, "<span class='notice'>You clean \the [target.name].</span>")
var/obj/effect/decal/cleanable/C = locate() in target var/obj/effect/decal/cleanable/C = locate() in target
qdel(C) qdel(C)
target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY) target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
SEND_SIGNAL(target, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM) SEND_SIGNAL(target, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM)
target.wash_cream() target.wash_cream()
return return
//Dogfood //Dogfood
/obj/item/trash/rkibble /obj/item/trash/rkibble
name = "robo kibble" name = "robo kibble"
desc = "A novelty bowl of assorted mech fabricator byproducts. Mockingly feed this to the sec-dog to help it recharge." desc = "A novelty bowl of assorted mech fabricator byproducts. Mockingly feed this to the sec-dog to help it recharge."
icon = 'icons/mob/dogborg.dmi' icon = 'icons/mob/dogborg.dmi'
icon_state= "kibble" icon_state= "kibble"
//Defibs //Defibs
/obj/item/twohanded/shockpaddles/cyborg/hound /obj/item/twohanded/shockpaddles/cyborg/hound
name = "Paws of Life" name = "Paws of Life"
desc = "MediHound specific shock paws." desc = "MediHound specific shock paws."
icon = 'icons/mob/dogborg.dmi' icon = 'icons/mob/dogborg.dmi'
icon_state = "defibpaddles0" icon_state = "defibpaddles0"
item_state = "defibpaddles0" item_state = "defibpaddles0"
// Pounce stuff for K-9 // Pounce stuff for K-9
/obj/item/dogborg/pounce /obj/item/dogborg/pounce
name = "pounce" name = "pounce"
icon = 'icons/mob/dogborg.dmi' icon = 'icons/mob/dogborg.dmi'
icon_state = "pounce" icon_state = "pounce"
desc = "Leap at your target to momentarily stun them." desc = "Leap at your target to momentarily stun them."
force = 0 force = 0
throwforce = 0 throwforce = 0
/obj/item/dogborg/pounce/New() /obj/item/dogborg/pounce/New()
..() ..()
item_flags |= NOBLUDGEON item_flags |= NOBLUDGEON
/mob/living/silicon/robot /mob/living/silicon/robot
var/leaping = 0 var/leaping = 0
var/pounce_cooldown = 0 var/pounce_cooldown = 0
var/pounce_cooldown_time = 50 //Nearly doubled, u happy? var/pounce_cooldown_time = 50 //Nearly doubled, u happy?
var/pounce_spoolup = 3 var/pounce_spoolup = 3
var/leap_at var/leap_at
var/disabler var/disabler
var/laser var/laser
var/sleeper_g var/sleeper_g
var/sleeper_r var/sleeper_r
var/sleeper_nv var/sleeper_nv
#define MAX_K9_LEAP_DIST 4 //because something's definitely borked the pounce functioning from a distance. #define MAX_K9_LEAP_DIST 4 //because something's definitely borked the pounce functioning from a distance.
/obj/item/dogborg/pounce/afterattack(atom/A, mob/user) /obj/item/dogborg/pounce/afterattack(atom/A, mob/user)
var/mob/living/silicon/robot/R = user var/mob/living/silicon/robot/R = user
if(R && !R.pounce_cooldown) if(R && !R.pounce_cooldown)
R.pounce_cooldown = !R.pounce_cooldown R.pounce_cooldown = !R.pounce_cooldown
to_chat(R, "<span class ='warning'>Your targeting systems lock on to [A]...</span>") to_chat(R, "<span class ='warning'>Your targeting systems lock on to [A]...</span>")
addtimer(CALLBACK(R, /mob/living/silicon/robot.proc/leap_at, A), R.pounce_spoolup) addtimer(CALLBACK(R, /mob/living/silicon/robot.proc/leap_at, A), R.pounce_spoolup)
spawn(R.pounce_cooldown_time) spawn(R.pounce_cooldown_time)
R.pounce_cooldown = !R.pounce_cooldown R.pounce_cooldown = !R.pounce_cooldown
else if(R && R.pounce_cooldown) else if(R && R.pounce_cooldown)
to_chat(R, "<span class='danger'>Your leg actuators are still recharging!</span>") to_chat(R, "<span class='danger'>Your leg actuators are still recharging!</span>")
/mob/living/silicon/robot/proc/leap_at(atom/A) /mob/living/silicon/robot/proc/leap_at(atom/A)
if(leaping || stat || buckled || lying) if(leaping || stat || buckled || lying)
return return
if(!has_gravity(src) || !has_gravity(A)) if(!has_gravity(src) || !has_gravity(A))
to_chat(src,"<span class='danger'>It is unsafe to leap without gravity!</span>") to_chat(src,"<span class='danger'>It is unsafe to leap without gravity!</span>")
//It's also extremely buggy visually, so it's balance+bugfix //It's also extremely buggy visually, so it's balance+bugfix
return return
if(cell.charge <= 500) if(cell.charge <= 500)
to_chat(src,"<span class='danger'>Insufficent reserves for jump actuators!</span>") to_chat(src,"<span class='danger'>Insufficent reserves for jump actuators!</span>")
return return
else else
leaping = 1 leaping = 1
weather_immunities += "lava" weather_immunities += "lava"
pixel_y = 10 pixel_y = 10
update_icons() update_icons()
throw_at(A, MAX_K9_LEAP_DIST, 1, spin=0, diagonals_first = 1) throw_at(A, MAX_K9_LEAP_DIST, 1, spin=0, diagonals_first = 1)
cell.use(500) //Doubled the energy consumption cell.use(500) //Doubled the energy consumption
weather_immunities -= "lava" weather_immunities -= "lava"
/mob/living/silicon/robot/throw_impact(atom/A) /mob/living/silicon/robot/throw_impact(atom/A)
if(!leaping) if(!leaping)
return ..() return ..()
if(A) if(A)
if(isliving(A)) if(isliving(A))
var/mob/living/L = A var/mob/living/L = A
var/blocked = 0 var/blocked = 0
if(ishuman(A)) if(ishuman(A))
var/mob/living/carbon/human/H = A var/mob/living/carbon/human/H = A
if(H.check_shields(0, "the [name]", src, attack_type = LEAP_ATTACK)) if(H.check_shields(0, "the [name]", src, attack_type = LEAP_ATTACK))
blocked = 1 blocked = 1
if(!blocked) if(!blocked)
L.visible_message("<span class ='danger'>[src] pounces on [L]!</span>", "<span class ='userdanger'>[src] pounces on you!</span>") L.visible_message("<span class ='danger'>[src] pounces on [L]!</span>", "<span class ='userdanger'>[src] pounces on you!</span>")
L.Knockdown(iscarbon(L) ? 450 : 45) // Temporary. If someone could rework how dogborg pounces work to accomodate for combat changes, that'd be nice. L.Knockdown(iscarbon(L) ? 450 : 45) // Temporary. If someone could rework how dogborg pounces work to accomodate for combat changes, that'd be nice.
playsound(src, 'sound/weapons/Egloves.ogg', 50, 1) playsound(src, 'sound/weapons/Egloves.ogg', 50, 1)
sleep(2)//Runtime prevention (infinite bump() calls on hulks) sleep(2)//Runtime prevention (infinite bump() calls on hulks)
step_towards(src,L) step_towards(src,L)
log_combat(src, L, "borg pounced") log_combat(src, L, "borg pounced")
else else
Knockdown(45, 1, 1) Knockdown(45, 1, 1)
pounce_cooldown = !pounce_cooldown pounce_cooldown = !pounce_cooldown
spawn(pounce_cooldown_time) //3s by default spawn(pounce_cooldown_time) //3s by default
pounce_cooldown = !pounce_cooldown pounce_cooldown = !pounce_cooldown
else if(A.density && !A.CanPass(src)) else if(A.density && !A.CanPass(src))
visible_message("<span class ='danger'>[src] smashes into [A]!</span>", "<span class ='userdanger'>You smash into [A]!</span>") visible_message("<span class ='danger'>[src] smashes into [A]!</span>", "<span class ='userdanger'>You smash into [A]!</span>")
playsound(src, 'sound/items/trayhit1.ogg', 50, 1) playsound(src, 'sound/items/trayhit1.ogg', 50, 1)
Knockdown(45, 1, 1) Knockdown(45, 1, 1)
if(leaping) if(leaping)
leaping = 0 leaping = 0
pixel_y = initial(pixel_y) pixel_y = initial(pixel_y)
update_icons() update_icons()
update_canmove() update_canmove()