This commit is contained in:
Ghommie
2019-06-24 16:48:15 +02:00
637 changed files with 17918 additions and 12263 deletions
@@ -72,7 +72,7 @@
..()
if(ishuman(O))
var/mob/living/carbon/human/H = O
if(H.shoes && blood_state && bloodiness && !H.has_trait(TRAIT_LIGHT_STEP))
if(H.shoes && blood_state && bloodiness && !HAS_TRAIT(H, TRAIT_LIGHT_STEP))
var/obj/item/clothing/shoes/S = H.shoes
var/add_blood = 0
if(bloodiness >= BLOOD_GAIN_PER_STEP)
@@ -60,7 +60,7 @@
/obj/effect/decal/cleanable/blood/gibs/Crossed(mob/living/L)
if(istype(L) && has_gravity(loc))
playsound(loc, 'sound/effects/gib_step.ogg', L.has_trait(TRAIT_LIGHT_STEP) ? 20 : 50, 1)
playsound(loc, 'sound/effects/gib_step.ogg', HAS_TRAIT(L, TRAIT_LIGHT_STEP) ? 20 : 50, 1)
. = ..()
/obj/effect/decal/cleanable/blood/gibs/proc/streak(list/directions)
@@ -1,347 +1,347 @@
// Foam
// Similar to smoke, but slower and mobs absorb its reagent through their exposed skin.
#define ALUMINUM_FOAM 1
#define IRON_FOAM 2
#define RESIN_FOAM 3
/obj/effect/particle_effect/foam
name = "foam"
icon_state = "foam"
opacity = 0
anchored = TRUE
density = FALSE
layer = EDGED_TURF_LAYER
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
var/amount = 3
animate_movement = 0
var/metal = 0
var/lifetime = 40
var/reagent_divisor = 7
var/static/list/blacklisted_turfs = typecacheof(list(
/turf/open/space/transit,
/turf/open/chasm,
/turf/open/lava))
/obj/effect/particle_effect/foam/firefighting
name = "firefighting foam"
lifetime = 20 //doesn't last as long as normal foam
amount = 0 //no spread
var/absorbed_plasma = 0
/obj/effect/particle_effect/foam/firefighting/MakeSlippery()
return
/obj/effect/particle_effect/foam/firefighting/process()
..()
var/turf/open/T = get_turf(src)
var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T)
if(hotspot && istype(T) && T.air)
qdel(hotspot)
var/datum/gas_mixture/G = T.air
var/plas_amt = min(30,G.gases[/datum/gas/plasma][MOLES]) //Absorb some plasma
G.gases[/datum/gas/plasma][MOLES] -= plas_amt
absorbed_plasma += plas_amt
if(G.temperature > T20C)
G.temperature = max(G.temperature/2,T20C)
G.garbage_collect()
T.air_update_turf()
/obj/effect/particle_effect/foam/firefighting/kill_foam()
STOP_PROCESSING(SSfastprocess, src)
if(absorbed_plasma)
var/obj/effect/decal/cleanable/plasma/P = (locate(/obj/effect/decal/cleanable/plasma) in get_turf(src))
if(!P)
P = new(loc)
P.reagents.add_reagent("stable_plasma", absorbed_plasma)
flick("[icon_state]-disolve", src)
QDEL_IN(src, 5)
/obj/effect/particle_effect/foam/firefighting/foam_mob(mob/living/L)
if(!istype(L))
return
L.adjust_fire_stacks(-2)
L.ExtinguishMob()
/obj/effect/particle_effect/foam/firefighting/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
return
/obj/effect/particle_effect/foam/metal
name = "aluminium foam"
metal = ALUMINUM_FOAM
icon_state = "mfoam"
/obj/effect/particle_effect/foam/metal/MakeSlippery()
return
/obj/effect/particle_effect/foam/metal/smart
name = "smart foam"
/obj/effect/particle_effect/foam/metal/iron
name = "iron foam"
metal = IRON_FOAM
/obj/effect/particle_effect/foam/metal/resin
name = "resin foam"
metal = RESIN_FOAM
/obj/effect/particle_effect/foam/long_life
lifetime = 150
/obj/effect/particle_effect/foam/Initialize()
. = ..()
MakeSlippery()
create_reagents(1000) //limited by the size of the reagent holder anyway.
START_PROCESSING(SSfastprocess, src)
playsound(src, 'sound/effects/bubbles2.ogg', 80, 1, -3)
/obj/effect/particle_effect/foam/proc/MakeSlippery()
AddComponent(/datum/component/slippery, 100)
/obj/effect/particle_effect/foam/Destroy()
STOP_PROCESSING(SSfastprocess, src)
return ..()
/obj/effect/particle_effect/foam/proc/kill_foam()
STOP_PROCESSING(SSfastprocess, src)
switch(metal)
if(ALUMINUM_FOAM)
new /obj/structure/foamedmetal(get_turf(src))
if(IRON_FOAM)
new /obj/structure/foamedmetal/iron(get_turf(src))
if(RESIN_FOAM)
new /obj/structure/foamedmetal/resin(get_turf(src))
flick("[icon_state]-disolve", src)
QDEL_IN(src, 5)
/obj/effect/particle_effect/foam/smart/kill_foam() //Smart foam adheres to area borders for walls
STOP_PROCESSING(SSfastprocess, src)
if(metal)
var/turf/T = get_turf(src)
if(isspaceturf(T)) //Block up any exposed space
T.PlaceOnTop(/turf/open/floor/plating/foam)
for(var/direction in GLOB.cardinals)
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!
new/obj/structure/foamedmetal(T)
break
flick("[icon_state]-disolve", src)
QDEL_IN(src, 5)
/obj/effect/particle_effect/foam/process()
lifetime--
if(lifetime < 1)
kill_foam()
return
var/fraction = 1/initial(reagent_divisor)
for(var/obj/O in range(0,src))
if(O.type == src.type)
continue
if(isturf(O.loc))
var/turf/T = O.loc
if(T.intact && O.level == 1) //hidden under the floor
continue
if(lifetime % reagent_divisor)
reagents.reaction(O, VAPOR, fraction)
var/hit = 0
for(var/mob/living/L in range(0,src))
hit += foam_mob(L)
if(hit)
lifetime++ //this is so the decrease from mobs hit and the natural decrease don't cumulate.
var/T = get_turf(src)
if(lifetime % reagent_divisor)
reagents.reaction(T, VAPOR, fraction)
if(--amount < 0)
return
spread_foam()
/obj/effect/particle_effect/foam/proc/foam_mob(mob/living/L)
if(lifetime<1)
return 0
if(!istype(L))
return 0
var/fraction = 1/initial(reagent_divisor)
if(lifetime % reagent_divisor)
reagents.reaction(L, VAPOR, fraction)
lifetime--
return 1
/obj/effect/particle_effect/foam/proc/spread_foam()
var/turf/t_loc = get_turf(src)
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!
if(foundfoam)
continue
if(is_type_in_typecache(T, blacklisted_turfs))
continue
for(var/mob/living/L in T)
foam_mob(L)
var/obj/effect/particle_effect/foam/F = new src.type(T)
F.amount = amount
reagents.copy_to(F, (reagents.total_volume))
F.add_atom_colour(color, FIXED_COLOUR_PRIORITY)
F.metal = metal
/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
kill_foam()
/obj/effect/particle_effect/foam/metal/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
return
///////////////////////////////////////////////
//FOAM EFFECT DATUM
/datum/effect_system/foam_spread
var/amount = 10 // the size of the foam spread.
var/obj/chemholder
effect_type = /obj/effect/particle_effect/foam
var/metal = 0
/datum/effect_system/foam_spread/metal
effect_type = /obj/effect/particle_effect/foam/metal
/datum/effect_system/foam_spread/metal/smart
effect_type = /obj/effect/particle_effect/foam/smart
/datum/effect_system/foam_spread/long
effect_type = /obj/effect/particle_effect/foam/long_life
/datum/effect_system/foam_spread/New()
..()
chemholder = new /obj()
var/datum/reagents/R = new/datum/reagents(1000)
chemholder.reagents = R
R.my_atom = chemholder
/datum/effect_system/foam_spread/Destroy()
qdel(chemholder)
chemholder = null
return ..()
/datum/effect_system/foam_spread/set_up(amt=5, loca, datum/reagents/carry = null)
if(isturf(loca))
location = loca
else
location = get_turf(loca)
amount = round(sqrt(amt / 2), 1)
carry.copy_to(chemholder, carry.total_volume)
/datum/effect_system/foam_spread/metal/set_up(amt=5, loca, datum/reagents/carry = null, metaltype)
..()
metal = metaltype
/datum/effect_system/foam_spread/start()
var/obj/effect/particle_effect/foam/F = new effect_type(location)
var/foamcolor = mix_color_from_reagents(chemholder.reagents.reagent_list)
chemholder.reagents.copy_to(F, chemholder.reagents.total_volume/amount)
F.add_atom_colour(foamcolor, FIXED_COLOUR_PRIORITY)
F.amount = amount
F.metal = metal
//////////////////////////////////////////////////////////
// FOAM STRUCTURE. Formed by metal foams. Dense and opaque, but easy to break
/obj/structure/foamedmetal
icon = 'icons/effects/effects.dmi'
icon_state = "metalfoam"
density = TRUE
opacity = 1 // changed in New()
anchored = TRUE
layer = EDGED_TURF_LAYER
resistance_flags = FIRE_PROOF | ACID_PROOF
name = "foamed metal"
desc = "A lightweight foamed metal wall."
gender = PLURAL
max_integrity = 20
CanAtmosPass = ATMOS_PASS_DENSITY
/obj/structure/foamedmetal/Initialize()
. = ..()
air_update_turf(1)
/obj/structure/foamedmetal/Move()
var/turf/T = loc
. = ..()
move_update_air(T)
/obj/structure/foamedmetal/attack_paw(mob/user)
return attack_hand(user)
/obj/structure/foamedmetal/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1)
/obj/structure/foamedmetal/attack_hand(mob/user)
. = ..()
if(.)
return
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
to_chat(user, "<span class='warning'>You hit [src] but bounce off it!</span>")
playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1)
/obj/structure/foamedmetal/CanPass(atom/movable/mover, turf/target)
return !density
/obj/structure/foamedmetal/iron
max_integrity = 50
icon_state = "ironfoam"
//Atmos Backpack Resin, transparent, prevents atmos and filters the air
/obj/structure/foamedmetal/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."
opacity = FALSE
icon_state = "atmos_resin"
alpha = 120
max_integrity = 10
/obj/structure/foamedmetal/resin/Initialize()
. = ..()
if(isopenturf(loc))
var/turf/open/O = loc
O.ClearWet()
if(O.air)
var/datum/gas_mixture/G = O.air
G.temperature = 293.15
for(var/obj/effect/hotspot/H in O)
qdel(H)
var/list/G_gases = G.gases
for(var/I in G_gases)
if(I == /datum/gas/oxygen || I == /datum/gas/nitrogen)
continue
G_gases[I][MOLES] = 0
G.garbage_collect()
O.air_update_turf()
for(var/obj/machinery/atmospherics/components/unary/U in O)
if(!U.welded)
U.welded = TRUE
U.update_icon()
U.visible_message("<span class='danger'>[U] sealed shut!</span>")
for(var/mob/living/L in O)
L.ExtinguishMob()
for(var/obj/item/Item in O)
Item.extinguish()
/obj/structure/foamedmetal/resin/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && (mover.pass_flags & PASSGLASS))
return TRUE
. = ..()
#undef ALUMINUM_FOAM
#undef IRON_FOAM
#undef RESIN_FOAM
// Foam
// Similar to smoke, but slower and mobs absorb its reagent through their exposed skin.
#define ALUMINUM_FOAM 1
#define IRON_FOAM 2
#define RESIN_FOAM 3
/obj/effect/particle_effect/foam
name = "foam"
icon_state = "foam"
opacity = 0
anchored = TRUE
density = FALSE
layer = EDGED_TURF_LAYER
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
var/amount = 3
animate_movement = 0
var/metal = 0
var/lifetime = 40
var/reagent_divisor = 7
var/static/list/blacklisted_turfs = typecacheof(list(
/turf/open/space/transit,
/turf/open/chasm,
/turf/open/lava))
/obj/effect/particle_effect/foam/firefighting
name = "firefighting foam"
lifetime = 20 //doesn't last as long as normal foam
amount = 0 //no spread
var/absorbed_plasma = 0
/obj/effect/particle_effect/foam/firefighting/MakeSlippery()
return
/obj/effect/particle_effect/foam/firefighting/process()
..()
var/turf/open/T = get_turf(src)
var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T)
if(hotspot && istype(T) && T.air)
qdel(hotspot)
var/datum/gas_mixture/G = T.air
var/plas_amt = min(30,G.gases[/datum/gas/plasma]) //Absorb some plasma
G.gases[/datum/gas/plasma] -= plas_amt
absorbed_plasma += plas_amt
if(G.temperature > T20C)
G.temperature = max(G.temperature/2,T20C)
GAS_GARBAGE_COLLECT(G.gases)
T.air_update_turf()
/obj/effect/particle_effect/foam/firefighting/kill_foam()
STOP_PROCESSING(SSfastprocess, src)
if(absorbed_plasma)
var/obj/effect/decal/cleanable/plasma/P = (locate(/obj/effect/decal/cleanable/plasma) in get_turf(src))
if(!P)
P = new(loc)
P.reagents.add_reagent("stable_plasma", absorbed_plasma)
flick("[icon_state]-disolve", src)
QDEL_IN(src, 5)
/obj/effect/particle_effect/foam/firefighting/foam_mob(mob/living/L)
if(!istype(L))
return
L.adjust_fire_stacks(-2)
L.ExtinguishMob()
/obj/effect/particle_effect/foam/firefighting/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
return
/obj/effect/particle_effect/foam/metal
name = "aluminium foam"
metal = ALUMINUM_FOAM
icon_state = "mfoam"
/obj/effect/particle_effect/foam/metal/MakeSlippery()
return
/obj/effect/particle_effect/foam/metal/smart
name = "smart foam"
/obj/effect/particle_effect/foam/metal/iron
name = "iron foam"
metal = IRON_FOAM
/obj/effect/particle_effect/foam/metal/resin
name = "resin foam"
metal = RESIN_FOAM
/obj/effect/particle_effect/foam/long_life
lifetime = 150
/obj/effect/particle_effect/foam/Initialize()
. = ..()
MakeSlippery()
create_reagents(1000) //limited by the size of the reagent holder anyway.
START_PROCESSING(SSfastprocess, src)
playsound(src, 'sound/effects/bubbles2.ogg', 80, 1, -3)
/obj/effect/particle_effect/foam/proc/MakeSlippery()
AddComponent(/datum/component/slippery, 100)
/obj/effect/particle_effect/foam/Destroy()
STOP_PROCESSING(SSfastprocess, src)
return ..()
/obj/effect/particle_effect/foam/proc/kill_foam()
STOP_PROCESSING(SSfastprocess, src)
switch(metal)
if(ALUMINUM_FOAM)
new /obj/structure/foamedmetal(get_turf(src))
if(IRON_FOAM)
new /obj/structure/foamedmetal/iron(get_turf(src))
if(RESIN_FOAM)
new /obj/structure/foamedmetal/resin(get_turf(src))
flick("[icon_state]-disolve", src)
QDEL_IN(src, 5)
/obj/effect/particle_effect/foam/smart/kill_foam() //Smart foam adheres to area borders for walls
STOP_PROCESSING(SSfastprocess, src)
if(metal)
var/turf/T = get_turf(src)
if(isspaceturf(T)) //Block up any exposed space
T.PlaceOnTop(/turf/open/floor/plating/foam)
for(var/direction in GLOB.cardinals)
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!
new/obj/structure/foamedmetal(T)
break
flick("[icon_state]-disolve", src)
QDEL_IN(src, 5)
/obj/effect/particle_effect/foam/process()
lifetime--
if(lifetime < 1)
kill_foam()
return
var/fraction = 1/initial(reagent_divisor)
for(var/obj/O in range(0,src))
if(O.type == src.type)
continue
if(isturf(O.loc))
var/turf/T = O.loc
if(T.intact && O.level == 1) //hidden under the floor
continue
if(lifetime % reagent_divisor)
reagents.reaction(O, VAPOR, fraction)
var/hit = 0
for(var/mob/living/L in range(0,src))
hit += foam_mob(L)
if(hit)
lifetime++ //this is so the decrease from mobs hit and the natural decrease don't cumulate.
var/T = get_turf(src)
if(lifetime % reagent_divisor)
reagents.reaction(T, VAPOR, fraction)
if(--amount < 0)
return
spread_foam()
/obj/effect/particle_effect/foam/proc/foam_mob(mob/living/L)
if(lifetime<1)
return 0
if(!istype(L))
return 0
var/fraction = 1/initial(reagent_divisor)
if(lifetime % reagent_divisor)
reagents.reaction(L, VAPOR, fraction)
lifetime--
return 1
/obj/effect/particle_effect/foam/proc/spread_foam()
var/turf/t_loc = get_turf(src)
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!
if(foundfoam)
continue
if(is_type_in_typecache(T, blacklisted_turfs))
continue
for(var/mob/living/L in T)
foam_mob(L)
var/obj/effect/particle_effect/foam/F = new src.type(T)
F.amount = amount
reagents.copy_to(F, (reagents.total_volume))
F.add_atom_colour(color, FIXED_COLOUR_PRIORITY)
F.metal = metal
/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
kill_foam()
/obj/effect/particle_effect/foam/metal/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
return
///////////////////////////////////////////////
//FOAM EFFECT DATUM
/datum/effect_system/foam_spread
var/amount = 10 // the size of the foam spread.
var/obj/chemholder
effect_type = /obj/effect/particle_effect/foam
var/metal = 0
/datum/effect_system/foam_spread/metal
effect_type = /obj/effect/particle_effect/foam/metal
/datum/effect_system/foam_spread/metal/smart
effect_type = /obj/effect/particle_effect/foam/smart
/datum/effect_system/foam_spread/long
effect_type = /obj/effect/particle_effect/foam/long_life
/datum/effect_system/foam_spread/New()
..()
chemholder = new /obj()
var/datum/reagents/R = new/datum/reagents(1000)
chemholder.reagents = R
R.my_atom = chemholder
/datum/effect_system/foam_spread/Destroy()
qdel(chemholder)
chemholder = null
return ..()
/datum/effect_system/foam_spread/set_up(amt=5, loca, datum/reagents/carry = null)
if(isturf(loca))
location = loca
else
location = get_turf(loca)
amount = round(sqrt(amt / 2), 1)
carry.copy_to(chemholder, carry.total_volume)
/datum/effect_system/foam_spread/metal/set_up(amt=5, loca, datum/reagents/carry = null, metaltype)
..()
metal = metaltype
/datum/effect_system/foam_spread/start()
var/obj/effect/particle_effect/foam/F = new effect_type(location)
var/foamcolor = mix_color_from_reagents(chemholder.reagents.reagent_list)
chemholder.reagents.copy_to(F, chemholder.reagents.total_volume/amount)
F.add_atom_colour(foamcolor, FIXED_COLOUR_PRIORITY)
F.amount = amount
F.metal = metal
//////////////////////////////////////////////////////////
// FOAM STRUCTURE. Formed by metal foams. Dense and opaque, but easy to break
/obj/structure/foamedmetal
icon = 'icons/effects/effects.dmi'
icon_state = "metalfoam"
density = TRUE
opacity = 1 // changed in New()
anchored = TRUE
layer = EDGED_TURF_LAYER
resistance_flags = FIRE_PROOF | ACID_PROOF
name = "foamed metal"
desc = "A lightweight foamed metal wall."
gender = PLURAL
max_integrity = 20
CanAtmosPass = ATMOS_PASS_DENSITY
/obj/structure/foamedmetal/Initialize()
. = ..()
air_update_turf(1)
/obj/structure/foamedmetal/Move()
var/turf/T = loc
. = ..()
move_update_air(T)
/obj/structure/foamedmetal/attack_paw(mob/user)
return attack_hand(user)
/obj/structure/foamedmetal/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1)
/obj/structure/foamedmetal/attack_hand(mob/user)
. = ..()
if(.)
return
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
to_chat(user, "<span class='warning'>You hit [src] but bounce off it!</span>")
playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1)
/obj/structure/foamedmetal/CanPass(atom/movable/mover, turf/target)
return !density
/obj/structure/foamedmetal/iron
max_integrity = 50
icon_state = "ironfoam"
//Atmos Backpack Resin, transparent, prevents atmos and filters the air
/obj/structure/foamedmetal/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."
opacity = FALSE
icon_state = "atmos_resin"
alpha = 120
max_integrity = 10
/obj/structure/foamedmetal/resin/Initialize()
. = ..()
if(isopenturf(loc))
var/turf/open/O = loc
O.ClearWet()
if(O.air)
var/datum/gas_mixture/G = O.air
G.temperature = 293.15
for(var/obj/effect/hotspot/H in O)
qdel(H)
var/list/G_gases = G.gases
for(var/I in G_gases)
if(I == /datum/gas/oxygen || I == /datum/gas/nitrogen)
continue
G_gases[I] = 0
GAS_GARBAGE_COLLECT(G.gases)
O.air_update_turf()
for(var/obj/machinery/atmospherics/components/unary/U in O)
if(!U.welded)
U.welded = TRUE
U.update_icon()
U.visible_message("<span class='danger'>[U] sealed shut!</span>")
for(var/mob/living/L in O)
L.ExtinguishMob()
for(var/obj/item/Item in O)
Item.extinguish()
/obj/structure/foamedmetal/resin/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && (mover.pass_flags & PASSGLASS))
return TRUE
. = ..()
#undef ALUMINUM_FOAM
#undef IRON_FOAM
#undef RESIN_FOAM
@@ -1,329 +1,328 @@
/////////////////////////////////////////////
//// SMOKE SYSTEMS
/////////////////////////////////////////////
/obj/effect/particle_effect/smoke
name = "smoke"
icon = 'icons/effects/96x96.dmi'
icon_state = "smoke"
pixel_x = -32
pixel_y = -32
opacity = 0
layer = FLY_LAYER
anchored = TRUE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
animate_movement = 0
var/amount = 4
var/lifetime = 5
var/opaque = 1 //whether the smoke can block the view when in enough amount
/obj/effect/particle_effect/smoke/proc/fade_out(frames = 16)
if(alpha == 0) //Handle already transparent case
return
if(frames == 0)
frames = 1 //We will just assume that by 0 frames, the coder meant "during one frame".
var/step = alpha / frames
for(var/i = 0, i < frames, i++)
alpha -= step
if(alpha < 160)
set_opacity(0) //if we were blocking view, we aren't now because we're fading out
stoplag()
/obj/effect/particle_effect/smoke/Initialize()
. = ..()
create_reagents(500)
START_PROCESSING(SSobj, src)
/obj/effect/particle_effect/smoke/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/effect/particle_effect/smoke/proc/kill_smoke()
STOP_PROCESSING(SSobj, src)
INVOKE_ASYNC(src, .proc/fade_out)
QDEL_IN(src, 10)
/obj/effect/particle_effect/smoke/process()
lifetime--
if(lifetime < 1)
kill_smoke()
return 0
for(var/mob/living/L in range(0,src))
smoke_mob(L)
return 1
/obj/effect/particle_effect/smoke/proc/smoke_mob(mob/living/carbon/C)
if(!istype(C))
return 0
if(lifetime<1)
return 0
if(C.internal != null || C.has_smoke_protection())
return 0
if(C.smoke_delay)
return 0
C.smoke_delay++
addtimer(CALLBACK(src, .proc/remove_smoke_delay, C), 10)
return 1
/obj/effect/particle_effect/smoke/proc/remove_smoke_delay(mob/living/carbon/C)
if(C)
C.smoke_delay = 0
/obj/effect/particle_effect/smoke/proc/spread_smoke()
var/turf/t_loc = get_turf(src)
if(!t_loc)
return
var/list/newsmokes = list()
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!
if(foundsmoke)
continue
for(var/mob/living/L in T)
smoke_mob(L)
var/obj/effect/particle_effect/smoke/S = new type(T)
reagents.copy_to(S, reagents.total_volume)
S.setDir(pick(GLOB.cardinals))
S.amount = amount-1
S.add_atom_colour(color, FIXED_COLOUR_PRIORITY)
S.lifetime = lifetime
if(S.amount>0)
if(opaque)
S.set_opacity(TRUE)
newsmokes.Add(S)
if(newsmokes.len)
spawn(1) //the smoke spreads rapidly but not instantly
for(var/obj/effect/particle_effect/smoke/SM in newsmokes)
SM.spread_smoke()
/datum/effect_system/smoke_spread
var/amount = 10
effect_type = /obj/effect/particle_effect/smoke
/datum/effect_system/smoke_spread/set_up(radius = 5, loca)
if(isturf(loca))
location = loca
else
location = get_turf(loca)
amount = radius
/datum/effect_system/smoke_spread/start()
if(holder)
location = get_turf(holder)
var/obj/effect/particle_effect/smoke/S = new effect_type(location)
S.amount = amount
if(S.amount)
S.spread_smoke()
/////////////////////////////////////////////
// Bad smoke
/////////////////////////////////////////////
/obj/effect/particle_effect/smoke/bad
lifetime = 8
/obj/effect/particle_effect/smoke/bad/smoke_mob(mob/living/carbon/M)
if(..())
M.drop_all_held_items()
M.adjustOxyLoss(1)
M.emote("cough")
return 1
/obj/effect/particle_effect/smoke/bad/CanPass(atom/movable/mover, turf/target)
if(istype(mover, /obj/item/projectile/beam))
var/obj/item/projectile/beam/B = mover
B.damage = (B.damage/2)
return 1
/datum/effect_system/smoke_spread/bad
effect_type = /obj/effect/particle_effect/smoke/bad
/////////////////////////////////////////////
// Nanofrost smoke
/////////////////////////////////////////////
/obj/effect/particle_effect/smoke/freezing
name = "nanofrost smoke"
color = "#B2FFFF"
opaque = 0
/datum/effect_system/smoke_spread/freezing
effect_type = /obj/effect/particle_effect/smoke/freezing
var/blast = 0
var/temperature = 2
var/weldvents = TRUE
var/distcheck = TRUE
/datum/effect_system/smoke_spread/freezing/proc/Chilled(atom/A)
if(isopenturf(A))
var/turf/open/T = A
if(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
G.temperature = temperature
T.air_update_turf()
for(var/obj/effect/hotspot/H in T)
qdel(H)
var/list/G_gases = G.gases
if(G_gases[/datum/gas/plasma])
G.assert_gas(/datum/gas/nitrogen)
G_gases[/datum/gas/nitrogen][MOLES] += (G_gases[/datum/gas/plasma][MOLES])
G_gases[/datum/gas/plasma][MOLES] = 0
G.garbage_collect()
if (weldvents)
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.
U.welded = TRUE
U.update_icon()
U.visible_message("<span class='danger'>[U] was frozen shut!</span>")
for(var/mob/living/L in T)
L.ExtinguishMob()
for(var/obj/item/Item in T)
Item.extinguish()
/datum/effect_system/smoke_spread/freezing/set_up(radius = 5, loca, blast_radius = 0)
..()
blast = blast_radius
/datum/effect_system/smoke_spread/freezing/start()
if(blast)
for(var/turf/T in RANGE_TURFS(blast, location))
Chilled(T)
..()
/datum/effect_system/smoke_spread/freezing/decon
temperature = 293.15
distcheck = FALSE
weldvents = FALSE
/////////////////////////////////////////////
// Sleep smoke
/////////////////////////////////////////////
/obj/effect/particle_effect/smoke/sleeping
color = "#9C3636"
lifetime = 10
/obj/effect/particle_effect/smoke/sleeping/smoke_mob(mob/living/carbon/M)
if(..())
M.Sleeping(200)
M.emote("cough")
return 1
/datum/effect_system/smoke_spread/sleeping
effect_type = /obj/effect/particle_effect/smoke/sleeping
/////////////////////////////////////////////
// Chem smoke
/////////////////////////////////////////////
/obj/effect/particle_effect/smoke/chem
lifetime = 10
/obj/effect/particle_effect/smoke/chem/process()
if(..())
var/turf/T = get_turf(src)
var/fraction = 1/initial(lifetime)
for(var/atom/movable/AM in T)
if(AM.type == src.type)
continue
if(T.intact && AM.level == 1) //hidden under the floor
continue
reagents.reaction(AM, TOUCH, fraction)
reagents.reaction(T, TOUCH, fraction)
return 1
/obj/effect/particle_effect/smoke/chem/smoke_mob(mob/living/carbon/M)
if(lifetime<1)
return 0
if(!istype(M))
return 0
var/mob/living/carbon/C = M
if(C.internal != null || C.has_smoke_protection())
return 0
var/fraction = 1/initial(lifetime)
reagents.copy_to(C, fraction*reagents.total_volume)
reagents.reaction(M, INGEST, fraction)
return 1
/datum/effect_system/smoke_spread/chem
var/obj/chemholder
effect_type = /obj/effect/particle_effect/smoke/chem
/datum/effect_system/smoke_spread/chem/New()
..()
chemholder = new /obj()
var/datum/reagents/R = new/datum/reagents(500)
chemholder.reagents = R
R.my_atom = chemholder
/datum/effect_system/smoke_spread/chem/Destroy()
qdel(chemholder)
chemholder = null
return ..()
/datum/effect_system/smoke_spread/chem/set_up(datum/reagents/carry = null, radius = 1, loca, silent = FALSE)
if(isturf(loca))
location = loca
else
location = get_turf(loca)
amount = radius
carry.copy_to(chemholder, carry.total_volume)
if(!silent)
var/contained = ""
for(var/reagent in carry.reagent_list)
contained += " [reagent] "
if(contained)
contained = "\[[contained]\]"
var/where = "[AREACOORD(location)]"
if(carry.my_atom.fingerprintslast)
var/mob/M = get_mob_by_key(carry.my_atom.fingerprintslast)
var/more = ""
if(M)
more = "[ADMIN_LOOKUPFLW(M)] "
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].")
else
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.")
/datum/effect_system/smoke_spread/chem/start()
var/mixcolor = mix_color_from_reagents(chemholder.reagents.reagent_list)
if(holder)
location = get_turf(holder)
var/obj/effect/particle_effect/smoke/chem/S = new effect_type(location)
if(chemholder.reagents.total_volume > 1) // can't split 1 very well
chemholder.reagents.copy_to(S, chemholder.reagents.total_volume)
if(mixcolor)
S.add_atom_colour(mixcolor, FIXED_COLOUR_PRIORITY) // give the smoke color, if it has any to begin with
S.amount = amount
if(S.amount)
S.spread_smoke() //calling process right now so the smoke immediately attacks mobs.
/////////////////////////////////////////////
// Transparent smoke
/////////////////////////////////////////////
//Same as the base type, but the smoke produced is not opaque
/datum/effect_system/smoke_spread/transparent
effect_type = /obj/effect/particle_effect/smoke/transparent
/obj/effect/particle_effect/smoke/transparent
opaque = FALSE
/////////////////////////////////////////////
//// SMOKE SYSTEMS
/////////////////////////////////////////////
/obj/effect/particle_effect/smoke
name = "smoke"
icon = 'icons/effects/96x96.dmi'
icon_state = "smoke"
pixel_x = -32
pixel_y = -32
opacity = 0
layer = FLY_LAYER
anchored = TRUE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
animate_movement = 0
var/amount = 4
var/lifetime = 5
var/opaque = 1 //whether the smoke can block the view when in enough amount
/obj/effect/particle_effect/smoke/proc/fade_out(frames = 16)
if(alpha == 0) //Handle already transparent case
return
if(frames == 0)
frames = 1 //We will just assume that by 0 frames, the coder meant "during one frame".
var/step = alpha / frames
for(var/i = 0, i < frames, i++)
alpha -= step
if(alpha < 160)
set_opacity(0) //if we were blocking view, we aren't now because we're fading out
stoplag()
/obj/effect/particle_effect/smoke/Initialize()
. = ..()
create_reagents(500)
START_PROCESSING(SSobj, src)
/obj/effect/particle_effect/smoke/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/effect/particle_effect/smoke/proc/kill_smoke()
STOP_PROCESSING(SSobj, src)
INVOKE_ASYNC(src, .proc/fade_out)
QDEL_IN(src, 10)
/obj/effect/particle_effect/smoke/process()
lifetime--
if(lifetime < 1)
kill_smoke()
return 0
for(var/mob/living/L in range(0,src))
smoke_mob(L)
return 1
/obj/effect/particle_effect/smoke/proc/smoke_mob(mob/living/carbon/C)
if(!istype(C))
return 0
if(lifetime<1)
return 0
if(C.internal != null || C.has_smoke_protection())
return 0
if(C.smoke_delay)
return 0
C.smoke_delay++
addtimer(CALLBACK(src, .proc/remove_smoke_delay, C), 10)
return 1
/obj/effect/particle_effect/smoke/proc/remove_smoke_delay(mob/living/carbon/C)
if(C)
C.smoke_delay = 0
/obj/effect/particle_effect/smoke/proc/spread_smoke()
var/turf/t_loc = get_turf(src)
if(!t_loc)
return
var/list/newsmokes = list()
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!
if(foundsmoke)
continue
for(var/mob/living/L in T)
smoke_mob(L)
var/obj/effect/particle_effect/smoke/S = new type(T)
reagents.copy_to(S, reagents.total_volume)
S.setDir(pick(GLOB.cardinals))
S.amount = amount-1
S.add_atom_colour(color, FIXED_COLOUR_PRIORITY)
S.lifetime = lifetime
if(S.amount>0)
if(opaque)
S.set_opacity(TRUE)
newsmokes.Add(S)
if(newsmokes.len)
spawn(1) //the smoke spreads rapidly but not instantly
for(var/obj/effect/particle_effect/smoke/SM in newsmokes)
SM.spread_smoke()
/datum/effect_system/smoke_spread
var/amount = 10
effect_type = /obj/effect/particle_effect/smoke
/datum/effect_system/smoke_spread/set_up(radius = 5, loca)
if(isturf(loca))
location = loca
else
location = get_turf(loca)
amount = radius
/datum/effect_system/smoke_spread/start()
if(holder)
location = get_turf(holder)
var/obj/effect/particle_effect/smoke/S = new effect_type(location)
S.amount = amount
if(S.amount)
S.spread_smoke()
/////////////////////////////////////////////
// Bad smoke
/////////////////////////////////////////////
/obj/effect/particle_effect/smoke/bad
lifetime = 8
/obj/effect/particle_effect/smoke/bad/smoke_mob(mob/living/carbon/M)
if(..())
M.drop_all_held_items()
M.adjustOxyLoss(1)
M.emote("cough")
return 1
/obj/effect/particle_effect/smoke/bad/CanPass(atom/movable/mover, turf/target)
if(istype(mover, /obj/item/projectile/beam))
var/obj/item/projectile/beam/B = mover
B.damage = (B.damage/2)
return 1
/datum/effect_system/smoke_spread/bad
effect_type = /obj/effect/particle_effect/smoke/bad
/////////////////////////////////////////////
// Nanofrost smoke
/////////////////////////////////////////////
/obj/effect/particle_effect/smoke/freezing
name = "nanofrost smoke"
color = "#B2FFFF"
opaque = 0
/datum/effect_system/smoke_spread/freezing
effect_type = /obj/effect/particle_effect/smoke/freezing
var/blast = 0
var/temperature = 2
var/weldvents = TRUE
var/distcheck = TRUE
/datum/effect_system/smoke_spread/freezing/proc/Chilled(atom/A)
if(isopenturf(A))
var/turf/open/T = A
if(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
G.temperature = temperature
T.air_update_turf()
for(var/obj/effect/hotspot/H in T)
qdel(H)
var/list/G_gases = G.gases
if(G_gases[/datum/gas/plasma])
G_gases[/datum/gas/nitrogen] += (G_gases[/datum/gas/plasma])
G_gases[/datum/gas/plasma] = 0
GAS_GARBAGE_COLLECT(G.gases)
if (weldvents)
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.
U.welded = TRUE
U.update_icon()
U.visible_message("<span class='danger'>[U] was frozen shut!</span>")
for(var/mob/living/L in T)
L.ExtinguishMob()
for(var/obj/item/Item in T)
Item.extinguish()
/datum/effect_system/smoke_spread/freezing/set_up(radius = 5, loca, blast_radius = 0)
..()
blast = blast_radius
/datum/effect_system/smoke_spread/freezing/start()
if(blast)
for(var/turf/T in RANGE_TURFS(blast, location))
Chilled(T)
..()
/datum/effect_system/smoke_spread/freezing/decon
temperature = 293.15
distcheck = FALSE
weldvents = FALSE
/////////////////////////////////////////////
// Sleep smoke
/////////////////////////////////////////////
/obj/effect/particle_effect/smoke/sleeping
color = "#9C3636"
lifetime = 10
/obj/effect/particle_effect/smoke/sleeping/smoke_mob(mob/living/carbon/M)
if(..())
M.Sleeping(200)
M.emote("cough")
return 1
/datum/effect_system/smoke_spread/sleeping
effect_type = /obj/effect/particle_effect/smoke/sleeping
/////////////////////////////////////////////
// Chem smoke
/////////////////////////////////////////////
/obj/effect/particle_effect/smoke/chem
lifetime = 10
/obj/effect/particle_effect/smoke/chem/process()
if(..())
var/turf/T = get_turf(src)
var/fraction = 1/initial(lifetime)
for(var/atom/movable/AM in T)
if(AM.type == src.type)
continue
if(T.intact && AM.level == 1) //hidden under the floor
continue
reagents.reaction(AM, TOUCH, fraction)
reagents.reaction(T, TOUCH, fraction)
return 1
/obj/effect/particle_effect/smoke/chem/smoke_mob(mob/living/carbon/M)
if(lifetime<1)
return 0
if(!istype(M))
return 0
var/mob/living/carbon/C = M
if(C.internal != null || C.has_smoke_protection())
return 0
var/fraction = 1/initial(lifetime)
reagents.copy_to(C, fraction*reagents.total_volume)
reagents.reaction(M, INGEST, fraction)
return 1
/datum/effect_system/smoke_spread/chem
var/obj/chemholder
effect_type = /obj/effect/particle_effect/smoke/chem
/datum/effect_system/smoke_spread/chem/New()
..()
chemholder = new /obj()
var/datum/reagents/R = new/datum/reagents(500)
chemholder.reagents = R
R.my_atom = chemholder
/datum/effect_system/smoke_spread/chem/Destroy()
qdel(chemholder)
chemholder = null
return ..()
/datum/effect_system/smoke_spread/chem/set_up(datum/reagents/carry = null, radius = 1, loca, silent = FALSE)
if(isturf(loca))
location = loca
else
location = get_turf(loca)
amount = radius
carry.copy_to(chemholder, carry.total_volume)
if(!silent)
var/contained = ""
for(var/reagent in carry.reagent_list)
contained += " [reagent] "
if(contained)
contained = "\[[contained]\]"
var/where = "[AREACOORD(location)]"
if(carry.my_atom.fingerprintslast)
var/mob/M = get_mob_by_key(carry.my_atom.fingerprintslast)
var/more = ""
if(M)
more = "[ADMIN_LOOKUPFLW(M)] "
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].")
else
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.")
/datum/effect_system/smoke_spread/chem/start()
var/mixcolor = mix_color_from_reagents(chemholder.reagents.reagent_list)
if(holder)
location = get_turf(holder)
var/obj/effect/particle_effect/smoke/chem/S = new effect_type(location)
if(chemholder.reagents.total_volume > 1) // can't split 1 very well
chemholder.reagents.copy_to(S, chemholder.reagents.total_volume)
if(mixcolor)
S.add_atom_colour(mixcolor, FIXED_COLOUR_PRIORITY) // give the smoke color, if it has any to begin with
S.amount = amount
if(S.amount)
S.spread_smoke() //calling process right now so the smoke immediately attacks mobs.
/////////////////////////////////////////////
// Transparent smoke
/////////////////////////////////////////////
//Same as the base type, but the smoke produced is not opaque
/datum/effect_system/smoke_spread/transparent
effect_type = /obj/effect/particle_effect/smoke/transparent
/obj/effect/particle_effect/smoke/transparent
opaque = FALSE
+2 -2
View File
@@ -170,7 +170,7 @@
if(!victim.client || !istype(victim))
return
to_chat(victim, "<span class='notice'>You feel fast!</span>")
victim.add_trait(TRAIT_GOTTAGOREALLYFAST, "yellow_orb")
ADD_TRAIT(victim, TRAIT_GOTTAGOREALLYFAST, "yellow_orb")
sleep(duration)
victim.remove_trait(TRAIT_GOTTAGOREALLYFAST, "yellow_orb")
REMOVE_TRAIT(victim, TRAIT_GOTTAGOREALLYFAST, "yellow_orb")
to_chat(victim, "<span class='notice'>You slow down.</span>")
@@ -1,6 +1,6 @@
#define CELSIUS_TO_KELVIN(T_K) ((T_K) + T0C)
#define OPTIMAL_TEMP_K_PLA_BURN_SCALE(PRESSURE_P,PRESSURE_O,TEMP_O) (((PRESSURE_P) * GLOB.meta_gas_info[/datum/gas/plasma][META_GAS_SPECIFIC_HEAT]) / (((PRESSURE_P) * GLOB.meta_gas_info[/datum/gas/plasma][META_GAS_SPECIFIC_HEAT] + (PRESSURE_O) * GLOB.meta_gas_info[/datum/gas/oxygen][META_GAS_SPECIFIC_HEAT]) / PLASMA_UPPER_TEMPERATURE - (PRESSURE_O) * GLOB.meta_gas_info[/datum/gas/oxygen][META_GAS_SPECIFIC_HEAT] / CELSIUS_TO_KELVIN(TEMP_O)))
#define OPTIMAL_TEMP_K_PLA_BURN_SCALE(PRESSURE_P,PRESSURE_O,TEMP_O) (((PRESSURE_P) * GLOB.meta_gas_specific_heats[/datum/gas/plasma]) / (((PRESSURE_P) * GLOB.meta_gas_specific_heats[/datum/gas/plasma] + (PRESSURE_O) * GLOB.meta_gas_specific_heats[/datum/gas/oxygen]) / PLASMA_UPPER_TEMPERATURE - (PRESSURE_O) * GLOB.meta_gas_specific_heats[/datum/gas/oxygen] / CELSIUS_TO_KELVIN(TEMP_O)))
#define OPTIMAL_TEMP_K_PLA_BURN_RATIO(PRESSURE_P,PRESSURE_O,TEMP_O) (CELSIUS_TO_KELVIN(TEMP_O) * PLASMA_OXYGEN_FULLBURN * (PRESSURE_P) / (PRESSURE_O))
/obj/effect/spawner/newbomb
@@ -19,12 +19,10 @@
var/obj/item/tank/internals/plasma/PT = new(V)
var/obj/item/tank/internals/oxygen/OT = new(V)
PT.air_contents.assert_gas(/datum/gas/plasma)
PT.air_contents.gases[/datum/gas/plasma][MOLES] = pressure_p*PT.volume/(R_IDEAL_GAS_EQUATION*CELSIUS_TO_KELVIN(temp_p))
PT.air_contents.gases[/datum/gas/plasma] = pressure_p*PT.volume/(R_IDEAL_GAS_EQUATION*CELSIUS_TO_KELVIN(temp_p))
PT.air_contents.temperature = CELSIUS_TO_KELVIN(temp_p)
OT.air_contents.assert_gas(/datum/gas/oxygen)
OT.air_contents.gases[/datum/gas/oxygen][MOLES] = pressure_o*OT.volume/(R_IDEAL_GAS_EQUATION*CELSIUS_TO_KELVIN(temp_o))
OT.air_contents.gases[/datum/gas/oxygen] = pressure_o*OT.volume/(R_IDEAL_GAS_EQUATION*CELSIUS_TO_KELVIN(temp_o))
OT.air_contents.temperature = CELSIUS_TO_KELVIN(temp_o)
V.tank_one = PT
+5 -4
View File
@@ -109,6 +109,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
var/list/grind_results //A reagent list containing the reagents this item produces when ground up in a grinder - this can be an empty list to allow for reagent transferring only
var/list/juice_results //A reagent list containing blah blah... but when JUICED in a grinder!
/obj/item/Initialize()
materials = typelist("materials", materials)
@@ -256,7 +257,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
can_handle_hot = TRUE
else if(C.gloves && (C.gloves.max_heat_protection_temperature > 360))
can_handle_hot = TRUE
else if(C.has_trait(TRAIT_RESISTHEAT) || C.has_trait(TRAIT_RESISTHEATHANDS))
else if(HAS_TRAIT(C, TRAIT_RESISTHEAT) || HAS_TRAIT(C, TRAIT_RESISTHEATHANDS))
can_handle_hot = TRUE
if(can_handle_hot)
@@ -449,10 +450,10 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
return 0
/obj/item/proc/eyestab(mob/living/carbon/M, mob/living/carbon/user)
if(user.has_trait(TRAIT_PACIFISM))
if(HAS_TRAIT(user, TRAIT_PACIFISM))
to_chat(user, "<span class='warning'>You don't want to harm [M]!</span>")
return
if(user.has_trait(TRAIT_CLUMSY) && prob(50))
if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
M = user
var/is_human_victim = 0
var/obj/item/bodypart/affecting = M.get_bodypart(BODY_ZONE_HEAD)
@@ -523,7 +524,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
M.adjust_blurriness(15)
if(M.stat != DEAD)
to_chat(M, "<span class='danger'>Your eyes start to bleed profusely!</span>")
if(!(M.has_trait(TRAIT_BLIND) || M.has_trait(TRAIT_NEARSIGHT)))
if(!(HAS_TRAIT(M, TRAIT_BLIND) || HAS_TRAIT(M, TRAIT_NEARSIGHT)))
to_chat(M, "<span class='danger'>You become nearsighted!</span>")
M.become_nearsighted(EYE_DAMAGE)
if(prob(50))
+131 -40
View File
@@ -161,13 +161,18 @@ RLD
user.visible_message("<span class='suicide'>[user] sets the RCD to 'Wall' and points it down [user.p_their()] throat! It looks like [user.p_theyre()] trying to commit suicide..</span>")
return (BRUTELOSS)
/obj/item/construction/rcd/verb/toggle_window_type()
set name = "Toggle Window Type"
/obj/item/construction/rcd/verb/toggle_window_type_verb()
set name = "RCD : Toggle Window Type"
set category = "Object"
set src in usr // What does this do?
set src in view(1)
if(!usr.canUseTopic(src, BE_CLOSE))
return
toggle_window_type(usr)
/obj/item/construction/rcd/proc/toggle_window_type(mob/user)
var/window_type_name
if (window_type == /obj/structure/window/fulltile)
window_type = /obj/structure/window/reinforced/fulltile
window_type_name = "reinforced glass"
@@ -175,17 +180,14 @@ RLD
window_type = /obj/structure/window/fulltile
window_type_name = "glass"
to_chat(usr, "<span class='notice'>You change \the [src]'s window mode to [window_type_name].</span>")
to_chat(user, "<span class='notice'>You change \the [src]'s window mode to [window_type_name].</span>")
/obj/item/construction/rcd/verb/change_airlock_access()
set name = "Change Airlock Access"
set category = "Object"
set src in usr
/obj/item/construction/rcd/verb/change_airlock_access(mob/user)
if (!ishuman(usr) && !usr.has_unlimited_silicon_privilege)
return ..(usr)
if (!ishuman(user) && !user.has_unlimited_silicon_privilege)
return
var/t1 = text("")
var/t1 = ""
if(use_one_access)
@@ -216,24 +218,23 @@ RLD
t1 += "<p><a href='?src=[REF(src)];close=1'>Close</a></p>\n"
var/datum/browser/popup = new(usr, "airlock_electronics", "Access Control", 900, 500)
var/datum/browser/popup = new(user, "rcd_access", "Access Control", 900, 500)
popup.set_content(t1)
popup.set_title_image(usr.browse_rsc_icon(src.icon, src.icon_state))
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
popup.open()
onclose(usr, "airlock")
onclose(user, "rcd_access")
/obj/item/construction/rcd/Topic(href, href_list)
..()
if (usr.stat || usr.restrained())
return
if (href_list["close"])
usr << browse(null, "window=airlock")
usr << browse(null, "window=rcd_access")
return
if (href_list["access"])
toggle_access(href_list["access"])
change_airlock_access()
change_airlock_access(usr)
/obj/item/construction/rcd/proc/toggle_access(acc)
if (acc == "all")
@@ -253,16 +254,77 @@ RLD
if (!conf_access.len)
conf_access = null
/obj/item/construction/rcd/verb/change_airlock_setting()
set name = "Change Airlock Setting"
set category = "Object"
set src in usr
/obj/item/construction/rcd/proc/get_airlock_image(airlock_type)
var/obj/machinery/door/airlock/proto = airlock_type
var/ic = initial(proto.icon)
var/mutable_appearance/MA = mutable_appearance(ic, "closed")
if(!initial(proto.glass))
MA.overlays += "fill_closed"
//Not scaling these down to button size because they look horrible then, instead just bumping up radius.
return MA
var/airlockcat = input(usr, "Select whether the airlock is solid or glass.") in list("Solid", "Glass")
/obj/item/construction/rcd/proc/check_menu(mob/living/user)
if(!istype(user))
return FALSE
if(user.incapacitated() || !user.Adjacent(src))
return FALSE
return TRUE
/obj/item/construction/rcd/proc/change_airlock_setting(mob/user)
if(!user)
return
var/list/solid_or_glass_choices = list(
"Solid" = get_airlock_image(/obj/machinery/door/airlock),
"Glass" = get_airlock_image(/obj/machinery/door/airlock/glass)
)
var/list/solid_choices = list(
"Standard" = get_airlock_image(/obj/machinery/door/airlock),
"Public" = get_airlock_image(/obj/machinery/door/airlock/public),
"Engineering" = get_airlock_image(/obj/machinery/door/airlock/engineering),
"Atmospherics" = get_airlock_image(/obj/machinery/door/airlock/atmos),
"Security" = get_airlock_image(/obj/machinery/door/airlock/security),
"Command" = get_airlock_image(/obj/machinery/door/airlock/command),
"Medical" = get_airlock_image(/obj/machinery/door/airlock/medical),
"Research" = get_airlock_image(/obj/machinery/door/airlock/research),
"Freezer" = get_airlock_image(/obj/machinery/door/airlock/freezer),
"Science" = get_airlock_image(/obj/machinery/door/airlock/science),
"Virology" = get_airlock_image(/obj/machinery/door/airlock/virology),
"Mining" = get_airlock_image(/obj/machinery/door/airlock/mining),
"Maintenance" = get_airlock_image(/obj/machinery/door/airlock/maintenance),
"External" = get_airlock_image(/obj/machinery/door/airlock/external),
"External Maintenance" = get_airlock_image(/obj/machinery/door/airlock/maintenance/external),
"Airtight Hatch" = get_airlock_image(/obj/machinery/door/airlock/hatch),
"Maintenance Hatch" = get_airlock_image(/obj/machinery/door/airlock/maintenance_hatch)
)
var/list/glass_choices = list(
"Standard" = get_airlock_image(/obj/machinery/door/airlock/glass),
"Public" = get_airlock_image(/obj/machinery/door/airlock/public/glass),
"Engineering" = get_airlock_image(/obj/machinery/door/airlock/engineering/glass),
"Atmospherics" = get_airlock_image(/obj/machinery/door/airlock/atmos/glass),
"Security" = get_airlock_image(/obj/machinery/door/airlock/security/glass),
"Command" = get_airlock_image(/obj/machinery/door/airlock/command/glass),
"Medical" = get_airlock_image(/obj/machinery/door/airlock/medical/glass),
"Research" = get_airlock_image(/obj/machinery/door/airlock/research/glass),
"Science" = get_airlock_image(/obj/machinery/door/airlock/science/glass),
"Virology" = get_airlock_image(/obj/machinery/door/airlock/virology/glass),
"Mining" = get_airlock_image(/obj/machinery/door/airlock/mining/glass),
"Maintenance" = get_airlock_image(/obj/machinery/door/airlock/maintenance/glass),
"External" = get_airlock_image(/obj/machinery/door/airlock/external/glass),
"External Maintenance" = get_airlock_image(/obj/machinery/door/airlock/maintenance/external/glass)
)
var/airlockcat = show_radial_menu(user, src, solid_or_glass_choices, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE)
if(!check_menu(user))
return
switch(airlockcat)
if("Solid")
if(advanced_airlock_setting == 1)
var/airlockpaint = input(usr, "Select the type of the airlock.") in list("Standard", "Public", "Engineering", "Atmospherics", "Security", "Command", "Medical", "Research", "Freezer", "Science", "Virology", "Mining", "Maintenance", "External", "External Maintenance", "Airtight Hatch", "Maintenance Hatch")
var/airlockpaint = show_radial_menu(user, src, solid_choices, radius = 42, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE)
if(!check_menu(user))
return
switch(airlockpaint)
if("Standard")
airlock_type = /obj/machinery/door/airlock
@@ -305,7 +367,9 @@ RLD
if("Glass")
if(advanced_airlock_setting == 1)
var/airlockpaint = input(usr, "Select the type of the airlock.") in list("Standard", "Public", "Engineering", "Atmospherics", "Security", "Command", "Medical", "Research", "Science", "Virology", "Mining", "Maintenance", "External", "External Maintenance")
var/airlockpaint = show_radial_menu(user, src , glass_choices, radius = 42, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE)
if(!check_menu(user))
return
switch(airlockpaint)
if("Standard")
airlock_type = /obj/machinery/door/airlock/glass
@@ -356,8 +420,8 @@ RLD
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
return TRUE
/obj/item/construction/rcd/New()
..()
/obj/item/construction/rcd/Initialize()
. = ..()
GLOB.rcd_list += src
/obj/item/construction/rcd/Destroy()
@@ -366,19 +430,46 @@ RLD
/obj/item/construction/rcd/attack_self(mob/user)
..()
switch(mode)
if(1)
mode = 2
to_chat(user, "<span class='notice'>You change RCD's mode to 'Airlock'.</span>")
if(2)
mode = 3
to_chat(user, "<span class='notice'>You change RCD's mode to 'Deconstruct'.</span>")
if(3)
mode = 4
to_chat(user, "<span class='notice'>You change RCD's mode to 'Grilles & Windows'.</span>")
if(4)
mode = 1
to_chat(user, "<span class='notice'>You change RCD's mode to 'Floor & Walls'.</span>")
var/list/choices = list(
"Airlock" = image(icon = 'icons/mob/radial.dmi', icon_state = "airlock"),
"Deconstruct" = image(icon= 'icons/mob/radial.dmi', icon_state = "delete"),
"Grilles & Windows" = image(icon = 'icons/mob/radial.dmi', icon_state = "grillewindow"),
"Floors & Walls" = image(icon = 'icons/mob/radial.dmi', icon_state = "wallfloor")
)
if(mode == RCD_AIRLOCK)
choices += list(
"Change Access" = image(icon = 'icons/mob/radial.dmi', icon_state = "access"),
"Change Airlock Type" = image(icon = 'icons/mob/radial.dmi', icon_state = "airlocktype")
)
else if(mode == RCD_WINDOWGRILLE)
choices += list(
"Change Window Type" = image(icon = 'icons/mob/radial.dmi', icon_state = "windowtype")
)
var/choice = show_radial_menu(user,src,choices, custom_check = CALLBACK(src,.proc/check_menu,user))
if(!check_menu(user))
return
switch(choice)
if("Floors & Walls")
mode = RCD_FLOORWALL
if("Airlock")
mode = RCD_AIRLOCK
if("Deconstruct")
mode = RCD_DECONSTRUCT
if("Grilles & Windows")
mode = RCD_WINDOWGRILLE
if("Change Access")
change_airlock_access(user)
return
if("Change Airlock Type")
change_airlock_setting(user)
return
if("Change Window Type")
toggle_window_type(user)
return
else
return
playsound(src, 'sound/effects/pop.ogg', 50, 0)
to_chat(user, "<span class='notice'>You change RCD's mode to '[choice]'.</span>")
/obj/item/construction/rcd/proc/target_check(atom/A, mob/user) // only returns true for stuff the device can actually work with
if((isturf(A) && A.density && mode==RCD_DECONSTRUCT) || (isturf(A) && !A.density) || (istype(A, /obj/machinery/door/airlock) && mode==RCD_DECONSTRUCT) || istype(A, /obj/structure/grille) || (istype(A, /obj/structure/window) && mode==RCD_DECONSTRUCT) || istype(A, /obj/structure/girder))
+123 -12
View File
@@ -14,13 +14,14 @@
w_class = WEIGHT_CLASS_NORMAL
var/max_amount = 90
var/active = FALSE
actions_types = list(/datum/action/item_action/rcl)
actions_types = list(/datum/action/item_action/rcl_col,/datum/action/item_action/rcl_gui)
var/list/colors = list("red", "yellow", "green", "blue", "pink", "orange", "cyan", "white")
var/current_color_index = 1
var/ghetto = FALSE
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
var/datum/component/mobhook
var/datum/radial_menu/persistent/wiring_gui_menu
/obj/item/twohanded/rcl/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/stack/cable_coil))
@@ -85,7 +86,8 @@
/obj/item/twohanded/rcl/Destroy()
QDEL_NULL(loaded)
last = null
setActive(FALSE, null) // setactive(FALSE) removes mobhook
QDEL_NULL(mobhook)
QDEL_NULL(wiring_gui_menu)
return ..()
/obj/item/twohanded/rcl/update_icon()
@@ -115,20 +117,28 @@
if(loaded)
QDEL_NULL(loaded)
loaded = null
QDEL_NULL(wiring_gui_menu)
unwield(user)
setActive(wielded, user)
active = wielded
return TRUE
return FALSE
/obj/item/twohanded/rcl/pickup(mob/user)
..()
getMobhook(user)
/obj/item/twohanded/rcl/dropped(mob/wearer)
..()
if(mobhook)
setActive(FALSE, mobhook.parent)
active = FALSE
QDEL_NULL(mobhook)
last = null
/obj/item/twohanded/rcl/attack_self(mob/user)
..()
setActive(wielded, user)
active = wielded
if(!active)
last = null
else if(!last)
@@ -137,17 +147,24 @@
last = C
break
/obj/item/twohanded/rcl/proc/setActive(toggle, mob/user)
active = toggle
if (active && user)
if (mobhook && mobhook.parent != user)
obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
if(to_hook)
if(mobhook && mobhook.parent != to_hook)
QDEL_NULL(mobhook)
if (!mobhook)
mobhook = user.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/trigger)))
mobhook = to_hook.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/trigger)))
else
QDEL_NULL(mobhook)
/obj/item/twohanded/rcl/proc/trigger(mob/user)
if(active)
layCable(user)
if(wiring_gui_menu) //update the wire options as you move
wiringGuiUpdate(user)
//previous contents of trigger(), lays cable each time the player moves
/obj/item/twohanded/rcl/proc/layCable(mob/user)
if(!isturf(user.loc))
return
if(is_empty(user, 0))
@@ -156,7 +173,7 @@
if(prob(2) && ghetto) //Give ghetto RCLs a 2% chance to jam, requiring it to be reactviated manually.
to_chat(user, "<span class='warning'>[src]'s wires jam!</span>")
setActive(FALSE, user)
active = FALSE
return
else
if(last)
@@ -179,6 +196,91 @@
is_empty(user) //If we've run out, display message
update_icon()
//searches the current tile for a stub cable of the same colour
/obj/item/twohanded/rcl/proc/findLinkingCable(mob/user)
var/turf/T
if(!isturf(user.loc))
return
T = get_turf(user)
if(T.intact || !T.can_have_cabling())
return
for(var/obj/structure/cable/C in T)
if(!C)
continue
if(C.cable_color != GLOB.cable_colors[colors[current_color_index]])
continue
if(C.d1 == 0)
return C
break
return
/obj/item/twohanded/rcl/proc/wiringGuiGenerateChoices(mob/user)
var/fromdir = 0
var/obj/structure/cable/linkingCable = findLinkingCable(user)
if(linkingCable)
fromdir = linkingCable.d2
var/list/wiredirs = list("1","5","4","6","2","10","8","9")
for(var/icondir in wiredirs)
var/dirnum = text2num(icondir)
var/cablesuffix = "[min(fromdir,dirnum)]-[max(fromdir,dirnum)]"
if(fromdir == dirnum) //cables can't loop back on themselves
cablesuffix = "invalid"
var/image/img = image(icon = 'icons/mob/radial.dmi', icon_state = "cable_[cablesuffix]")
img.color = GLOB.cable_colors[colors[current_color_index]]
wiredirs[icondir] = img
return wiredirs
/obj/item/twohanded/rcl/proc/showWiringGui(mob/user)
var/list/choices = wiringGuiGenerateChoices(user)
wiring_gui_menu = show_radial_menu_persistent(user, src , choices, select_proc = CALLBACK(src, .proc/wiringGuiReact, user), radius = 42)
/obj/item/twohanded/rcl/proc/wiringGuiUpdate(mob/user)
if(!wiring_gui_menu)
return
wiring_gui_menu.entry_animation = FALSE //stop the open anim from playing each time we update
var/list/choices = wiringGuiGenerateChoices(user)
wiring_gui_menu.change_choices(choices,FALSE)
//Callback used to respond to interactions with the wiring menu
/obj/item/twohanded/rcl/proc/wiringGuiReact(mob/living/user,choice)
if(!choice) //close on a null choice (the center button)
QDEL_NULL(wiring_gui_menu)
return
choice = text2num(choice)
if(!isturf(user.loc))
return
if(is_empty(user, 0))
to_chat(user, "<span class='warning'>\The [src] is empty!</span>")
return
var/turf/T = get_turf(user)
if(T.intact || !T.can_have_cabling())
return
loaded.item_color = colors[current_color_index]
var/obj/structure/cable/linkingCable = findLinkingCable(user)
if(linkingCable)
if(choice != linkingCable.d2)
loaded.cable_join(linkingCable, user, FALSE, choice)
last = null
else
last = loaded.place_turf(get_turf(src), user, choice)
is_empty(user) //If we've run out, display message
wiringGuiUpdate(user)
/obj/item/twohanded/rcl/pre_loaded/Initialize() //Comes preloaded with cable, for testing stuff
. = ..()
@@ -192,12 +294,21 @@
update_icon()
/obj/item/twohanded/rcl/ui_action_click(mob/user, action)
if(istype(action, /datum/action/item_action/rcl))
if(istype(action, /datum/action/item_action/rcl_col))
current_color_index++;
if (current_color_index > colors.len)
current_color_index = 1
var/cwname = colors[current_color_index]
to_chat(user, "Color changed to [cwname]!")
if(loaded)
loaded.item_color= colors[current_color_index]
if(wiring_gui_menu)
wiringGuiUpdate(user)
else if(istype(action, /datum/action/item_action/rcl_gui))
if(wiring_gui_menu) //The menu is already open, close it
QDEL_NULL(wiring_gui_menu)
else //open the menu
showWiringGui(user)
/obj/item/twohanded/rcl/ghetto
actions_types = list()
+1 -1
View File
@@ -331,7 +331,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
//make sure what we're clicking is valid for the current category
var/static/list/make_pipe_whitelist
if(!make_pipe_whitelist)
make_pipe_whitelist = typecacheof(list(/obj/structure/lattice, /obj/structure/girder, /obj/item/pipe))
make_pipe_whitelist = typecacheof(list(/obj/structure/lattice, /obj/structure/girder, /obj/item/pipe, /obj/structure/window, /obj/structure/grille))
var/can_make_pipe = (isturf(A) || is_type_in_typecache(A, make_pipe_whitelist))
. = FALSE
+5 -7
View File
@@ -59,7 +59,7 @@
/obj/item/areaeditor/blueprints/attack_self(mob/user)
. = ..()
if(!legend)
var/area/A = get_area()
var/area/A = get_area(user)
if(get_area_type() == AREA_STATION)
. += "<p>According to \the [src], you are now in <b>\"[html_encode(A.name)]\"</b>.</p>"
. += "<p><a href='?src=[REF(src)];edit_area=1'>Change area name</a></p>"
@@ -140,12 +140,10 @@
legend = FALSE
/obj/item/areaeditor/proc/get_area()
var/turf/T = get_turf(usr)
var/area/A = T.loc
return A
/obj/item/areaeditor/proc/get_area_type(area/A = get_area())
/obj/item/areaeditor/proc/get_area_type(area/A)
if(!A)
A = get_area(usr)
if(A.outdoors)
return AREA_SPACE
var/list/SPECIALS = list(
@@ -183,7 +181,7 @@
return ""
/obj/item/areaeditor/proc/edit_area()
var/area/A = get_area()
var/area/A = get_area(usr)
var/prevname = "[A.name]"
var/str = stripped_input(usr,"New area name:", "Area Creation", "", MAX_NAME_LEN)
if(!str || !length(str) || str==prevname) //cancel
+2 -2
View File
@@ -16,7 +16,7 @@
/obj/item/organ/body_egg/Insert(var/mob/living/carbon/M, special = 0)
..()
owner.add_trait(TRAIT_XENO_HOST, TRAIT_GENERIC)
ADD_TRAIT(owner, TRAIT_XENO_HOST, TRAIT_GENERIC)
START_PROCESSING(SSobj, src)
owner.med_hud_set_status()
INVOKE_ASYNC(src, .proc/AddInfectionImages, owner)
@@ -24,7 +24,7 @@
/obj/item/organ/body_egg/Remove(var/mob/living/carbon/M, special = 0)
STOP_PROCESSING(SSobj, src)
if(owner)
owner.remove_trait(TRAIT_XENO_HOST, TRAIT_GENERIC)
REMOVE_TRAIT(owner, TRAIT_XENO_HOST, TRAIT_GENERIC)
owner.med_hud_set_status()
INVOKE_ASYNC(src, .proc/RemoveInfectionImages, owner)
..()
+2 -3
View File
@@ -248,9 +248,8 @@
/obj/effect/chrono_field/return_air() //we always have nominal air and temperature
var/datum/gas_mixture/GM = new
GM.add_gases(/datum/gas/oxygen, /datum/gas/nitrogen)
GM.gases[/datum/gas/oxygen][MOLES] = MOLES_O2STANDARD
GM.gases[/datum/gas/nitrogen][MOLES] = MOLES_N2STANDARD
GM.gases[/datum/gas/oxygen] = MOLES_O2STANDARD
GM.gases[/datum/gas/nitrogen] = MOLES_N2STANDARD
GM.temperature = T20C
return GM
+6 -10
View File
@@ -102,7 +102,6 @@ CIGARETTE PACKETS ARE IN FANCY.DM
icon_state = "cigoff"
throw_speed = 0.5
item_state = "cigoff"
container_type = INJECTABLE
w_class = WEIGHT_CLASS_TINY
body_parts_covered = null
grind_results = list()
@@ -123,8 +122,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
/obj/item/clothing/mask/cigarette/Initialize()
. = ..()
create_reagents(chem_volume)
reagents.set_reacting(FALSE) // so it doesn't react until you light it
create_reagents(chem_volume, INJECTABLE | NO_REACT) // so it doesn't react until you light it
if(list_reagents)
reagents.add_reagent_list(list_reagents)
if(starts_lit)
@@ -184,7 +182,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
qdel(src)
return
// allowing reagents to react after being lit
reagents.set_reacting(TRUE)
DISABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT)
reagents.handle_reactions()
icon_state = icon_on
item_state = icon_on
@@ -325,7 +323,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
list_reagents = list("space_drugs" = 15, "lipolicide" = 35)
/obj/item/clothing/mask/cigarette/rollie/mindbreaker
list_reagents = list("mindbreaker" = 35, "lipolicide" = 15)
list_reagents = list("mindbreaker" = 35, "lipolicide" = 15)
/obj/item/cigbutt/roach
name = "roach"
@@ -720,8 +718,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
/obj/item/clothing/mask/vape/Initialize(mapload, param_color)
. = ..()
create_reagents(chem_volume)
reagents.set_reacting(FALSE) // so it doesn't react until you light it
DISABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT)
reagents.add_reagent("nicotine", 50)
if(!icon_state)
if(!param_color)
@@ -790,13 +787,12 @@ CIGARETTE PACKETS ARE IN FANCY.DM
if(reagents.total_volume > 0)
to_chat(user, "<span class='notice'>You empty [src] of all reagents.</span>")
reagents.clear_reagents()
return
/obj/item/clothing/mask/vape/equipped(mob/user, slot)
if(slot == SLOT_WEAR_MASK)
if(!screw)
to_chat(user, "<span class='notice'>You start puffing on the vape.</span>")
reagents.set_reacting(TRUE)
DISABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT)
START_PROCESSING(SSobj, src)
else //it will not start if the vape is opened.
to_chat(user, "<span class='warning'>You need to close the cap first!</span>")
@@ -804,7 +800,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
/obj/item/clothing/mask/vape/dropped(mob/user)
var/mob/living/carbon/C = user
if(C.get_item_by_slot(SLOT_WEAR_MASK) == src)
reagents.set_reacting(FALSE)
ENABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT)
STOP_PROCESSING(SSobj, src)
/obj/item/clothing/mask/vape/proc/hand_reagents()//had to rename to avoid duplicate error
+1 -1
View File
@@ -254,7 +254,7 @@
cost = 0
if(ishuman(user))
var/mob/living/carbon/human/H = user
if (H.has_trait(TRAIT_TAGGER))
if (HAS_TRAIT(H, TRAIT_TAGGER))
cost *= 0.5
var/charges_used = use_charges(user, cost)
if(!charges_used)
+2 -2
View File
@@ -444,7 +444,7 @@
/obj/item/twohanded/shockpaddles/proc/can_defib(mob/living/carbon/H)
var/obj/item/organ/brain/BR = H.getorgan(/obj/item/organ/brain)
return (!H.suiciding && !(H.has_trait(TRAIT_NOCLONE)) && !H.hellbound && ((world.time - H.timeofdeath) < tlimit) && (H.getBruteLoss() < 180) && (H.getFireLoss() < 180) && H.getorgan(/obj/item/organ/heart) && BR && !BR.damaged_brain)
return (!H.suiciding && !(HAS_TRAIT(H, TRAIT_NOCLONE)) && !H.hellbound && ((world.time - H.timeofdeath) < tlimit) && (H.getBruteLoss() < 180) && (H.getFireLoss() < 180) && H.getorgan(/obj/item/organ/heart) && BR && !BR.damaged_brain)
/obj/item/twohanded/shockpaddles/proc/shock_touching(dmg, mob/H)
if(req_defib)
@@ -585,7 +585,7 @@
shock_touching(30, H)
var/failed
if (H.suiciding || (H.has_trait(TRAIT_NOCLONE)))
if (H.suiciding || (HAS_TRAIT(H, TRAIT_NOCLONE)))
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Recovery of patient impossible. Further attempts futile.</span>"
else if (H.hellbound)
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's soul appears to be on another plane of existence. Further attempts futile.</span>"
+11 -7
View File
@@ -221,12 +221,16 @@ GLOBAL_LIST_EMPTY(PDAs)
overlay.icon_state = "[current_overlays[PDA_OVERLAY_PAI]][pai.pai ? "" : "_off"]"
add_overlay(new /mutable_appearance(overlay))
/obj/item/pda/MouseDrop(obj/over_object, src_location, over_location)
/obj/item/pda/MouseDrop(mob/over, src_location, over_location)
var/mob/M = usr
if((!istype(over_object, /obj/screen)) && usr.canUseTopic(src))
if((M == over) && usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return attack_self(M)
return ..()
/obj/item/pda/attack_self_tk(mob/user)
to_chat(user, "<span class='warning'>The PDA's capacitive touch screen doesn't seem to respond!</span>")
return
/obj/item/pda/interact(mob/user)
if(!user.IsAdvancedToolUser())
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
@@ -408,9 +412,9 @@ GLOBAL_LIST_EMPTY(PDAs)
if (total_moles)
for(var/id in env_gases)
var/gas_level = env_gases[id][MOLES]/total_moles
var/gas_level = env_gases[id]/total_moles
if(gas_level > 0)
dat += "[env_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_level*100, 0.01)]%<br>"
dat += "[GLOB.meta_gas_names[id]]: [round(gas_level*100, 0.01)]%<br>"
dat += "Temperature: [round(environment.temperature-T0C)]&deg;C<br>"
dat += "<br>"
@@ -432,7 +436,7 @@ GLOBAL_LIST_EMPTY(PDAs)
var/mob/living/U = usr
//Looking for master was kind of pointless since PDAs don't appear to have one.
if(usr.canUseTopic(src) && !href_list["close"])
if(usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK) && !href_list["close"])
add_fingerprint(U)
U.set_machine(src)
@@ -686,7 +690,7 @@ GLOBAL_LIST_EMPTY(PDAs)
/obj/item/pda/proc/remove_id()
if(issilicon(usr) || !usr.canUseTopic(src, BE_CLOSE))
if(issilicon(usr) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
if (id)
@@ -851,7 +855,7 @@ GLOBAL_LIST_EMPTY(PDAs)
/obj/item/pda/proc/remove_pen()
if(issilicon(usr) || !usr.canUseTopic(src, BE_CLOSE))
if(issilicon(usr) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
if(inserted_item)
@@ -0,0 +1,127 @@
/obj/item/compressionkit
name = "bluespace compression kit"
desc = "An illegally modified BSRPED, capable of reducing the size of most items."
icon = 'icons/obj/tools.dmi'
icon_state = "compression_c"
item_state = "RPED"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
w_class = WEIGHT_CLASS_NORMAL
var/charges = 5
// var/damage_multiplier = 0.2 Not in use yet.
var/mode = 0
/obj/item/compressionkit/examine(mob/user)
..()
to_chat(user, "<span class='notice'>It has [charges] charges left. Recharge with bluespace crystals.</span>")
to_chat(user, "<span class='notice'>Use in-hand to swap toggle compress/expand mode (expand mode not yet implemented).</span>")
/obj/item/compressionkit/attack_self(mob/user)
if(mode == 0)
mode = 1
icon_state = "compression_e"
to_chat(user, "<span class='notice'>You switch the compressor to expand mode. This isn't implemented yet, so right now it wont do anything different!</span>")
return
if(mode == 1)
mode = 0
icon_state = "compression_c"
to_chat(user, "<span class='notice'>You switch the compressor to compress mode. Usage will now reduce the size of objects.</span>")
return
else
mode = 0
icon_state = "compression_c"
to_chat(user, "<span class='notice'>Some coder cocked up or an admin broke your compressor. It's been set back to compress mode..</span>")
/obj/item/compressionkit/proc/sparks()
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(5, 1, get_turf(src))
s.start()
/obj/item/compressionkit/suicide_act(mob/living/carbon/M)
M.visible_message("<span class='suicide'>[M] is sticking their head in [src] and turning it on! [M.p_theyre(TRUE)] going to compress their own skull!</span>")
var/obj/item/bodypart/head = M.get_bodypart("head")
if(!head)
return
var/turf/T = get_turf(M)
var/list/organs = M.getorganszone("head") + M.getorganszone("eyes") + M.getorganszone("mouth")
for(var/internal_organ in organs)
var/obj/item/organ/I = internal_organ
I.Remove(M)
I.forceMove(T)
head.drop_limb()
qdel(head)
new M.gib_type(T,1,M.get_static_viruses())
M.add_splatter_floor(T)
playsound(M, 'sound/weapons/flash.ogg', 50, 1)
playsound(M, 'sound/effects/splat.ogg', 50, 1)
return OXYLOSS
/obj/item/compressionkit/afterattack(atom/target, mob/user, proximity)
. = ..()
if(!proximity || !target)
return
else
if(charges == 0)
playsound(get_turf(src), 'sound/machines/buzz-two.ogg', 50, 1)
to_chat(user, "<span class='notice'>The bluespace compression kit is out of charges! Recharge it with bluespace crystals.</span>")
return
if(istype(target, /obj/item))
var/obj/item/O = target
if(O.w_class == 1)
playsound(get_turf(src), 'sound/machines/buzz-two.ogg', 50, 1)
to_chat(user, "<span class='notice'>[target] cannot be compressed smaller!.</span>")
return
if(O.GetComponent(/datum/component/storage))
to_chat(user, "<span class='notice'>You feel like compressing an item that stores other items would be counterproductive.</span>")
return
if(O.w_class > 1)
playsound(get_turf(src), 'sound/weapons/flash.ogg', 50, 1)
user.visible_message("<span class='warning'>[user] is compressing [O] with their bluespace compression kit!</span>")
if(do_mob(user, O, 40) && charges > 0 && O.w_class > 1)
playsound(get_turf(src), 'sound/weapons/emitter2.ogg', 50, 1)
sparks()
flash_lighting_fx(3, 3, LIGHT_COLOR_CYAN)
O.w_class -= 1
// O.force_mult -= damage_multiplier
charges -= 1
to_chat(user, "<span class='notice'>You successfully compress [target]! The compressor now has [charges] charges.</span>")
else
to_chat(user, "<span class='notice'>Anomalous error. Summon a coder.</span>")
if(istype(target, /mob/living))
var/mob/living/victim = target
if(istype(victim, /mob/living/carbon/human))
if(user.zone_selected == "groin") // pp smol. There's probably a smarter way to do this but im retarded. If you have a simpler method let me know.
var/list/organs = victim.getorganszone("groin")
for(var/internal_organ in organs)
if(istype(internal_organ, /obj/item/organ/genital/penis))
var/obj/item/organ/genital/penis/O = internal_organ
playsound(get_turf(src), 'sound/weapons/flash.ogg', 50, 1)
victim.visible_message("<span class='warning'>[user] is preparing to shrink [victim]\'s [O.name] with their bluespace compression kit!</span>")
if(do_mob(user, victim, 40) && charges > 0 && O.length > 0)
victim.visible_message("<span class='warning'>[user] has shrunk [victim]\'s [O.name]!</span>")
playsound(get_turf(src), 'sound/weapons/emitter2.ogg', 50, 1)
sparks()
flash_lighting_fx(3, 3, LIGHT_COLOR_CYAN)
charges -= 1
O.length -= 5
if(O.length < 1)
victim.visible_message("<span class='warning'>[user]\'s [O.name] vanishes!</span>")
qdel(O) // no pp for you
else
O.update_size()
O.update_appearance()
/obj/item/compressionkit/attackby(obj/item/I, mob/user, params)
..()
if(istype(I, /obj/item/stack/ore/bluespace_crystal))
var/obj/item/stack/ore/bluespace_crystal/B = I
charges += 2
to_chat(user, "<span class='notice'>You insert [I] into [src]. It now has [charges] charges.</span>")
if(B.amount > 1)
B.amount -= 1
else
qdel(I)
+17 -5
View File
@@ -13,7 +13,8 @@
actions_types = list(/datum/action/item_action/toggle_light)
var/on = FALSE
var/brightness_on = 4 //range of light when on
var/flashlight_power = 1 //strength of the light when on
var/flashlight_power = 0.8 //strength of the light when on
light_color = "#FFCC66"
/obj/item/flashlight/Initialize()
. = ..()
@@ -52,7 +53,7 @@
add_fingerprint(user)
if(istype(M) && on && user.zone_selected in list(BODY_ZONE_PRECISE_EYES, BODY_ZONE_PRECISE_MOUTH))
if((user.has_trait(TRAIT_CLUMSY) || user.has_trait(TRAIT_DUMB)) && prob(50)) //too dumb to use flashlight properly
if((HAS_TRAIT(user, TRAIT_CLUMSY) || HAS_TRAIT(user, TRAIT_DUMB)) && prob(50)) //too dumb to use flashlight properly
return ..() //just hit them in the head
if(!user.IsAdvancedToolUser())
@@ -63,7 +64,7 @@
to_chat(user, "<span class='warning'>[M] doesn't have a head!</span>")
return
if(flashlight_power < 1)
if(flashlight_power < 0.3)
to_chat(user, "<span class='warning'>\The [src] isn't bright enough to see anything!</span> ")
return
@@ -86,7 +87,7 @@
else
user.visible_message("<span class='warning'>[user] directs [src] to [M]'s eyes.</span>", \
"<span class='danger'>You direct [src] to [M]'s eyes.</span>")
if(M.stat == DEAD || (M.has_trait(TRAIT_BLIND)) || !M.flash_act(visual = 1)) //mob is dead or fully blind
if(M.stat == DEAD || (HAS_TRAIT(M, TRAIT_BLIND)) || !M.flash_act(visual = 1)) //mob is dead or fully blind
to_chat(user, "<span class='warning'>[M]'s pupils don't react to the light!</span>")
else if(M.dna && M.dna.check_mutation(XRAY)) //mob has X-ray vision
to_chat(user, "<span class='danger'>[M]'s pupils give an eerie glow!</span>")
@@ -168,6 +169,8 @@
item_state = ""
flags_1 = CONDUCT_1
brightness_on = 2
light_color = "#FFDDCC"
flashlight_power = 0.3
var/holo_cooldown = 0
/obj/item/flashlight/pen/afterattack(atom/target, mob/user, proximity_flag)
@@ -204,6 +207,8 @@
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
force = 9 // Not as good as a stun baton.
brightness_on = 5 // A little better than the standard flashlight.
light_color = "#CDDDFF"
flashlight_power = 0.9
hitsound = 'sound/weapons/genhit1.ogg'
// the desk lamps are a bit special
@@ -216,6 +221,7 @@
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
force = 10
brightness_on = 5
light_color = "#FFDDBB"
w_class = WEIGHT_CLASS_BULKY
flags_1 = CONDUCT_1
materials = list()
@@ -252,6 +258,7 @@
desc = "A red Nanotrasen issued flare. There are instructions on the side, it reads 'pull cord, make light'."
w_class = WEIGHT_CLASS_SMALL
brightness_on = 7 // Pretty bright.
light_color = "#FA421A"
icon_state = "flare"
item_state = "flare"
actions_types = list()
@@ -325,6 +332,7 @@
desc = "A torch fashioned from some leaves and a log."
w_class = WEIGHT_CLASS_BULKY
brightness_on = 4
light_color = "#FAA44B"
icon_state = "torch"
item_state = "torch"
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
@@ -341,6 +349,8 @@
righthand_file = 'icons/mob/inhands/equipment/mining_righthand.dmi'
desc = "A mining lantern."
brightness_on = 6 // luminosity when on
light_color = "#FFAA44"
flashlight_power = 0.75
/obj/item/flashlight/slime
@@ -354,6 +364,8 @@
slot_flags = ITEM_SLOT_BELT
materials = list()
brightness_on = 6 //luminosity when on
light_color = "#FFEEAA"
flashlight_power = 0.6
/obj/item/flashlight/emp
var/emp_max_charges = 4
@@ -517,6 +529,7 @@
icon_state = null
light_color = null
brightness_on = 0
flashlight_power = 1
light_range = 0
light_power = 10
alpha = 0
@@ -538,7 +551,6 @@
name = "eyelight"
desc = "This shouldn't exist outside of someone's head, how are you seeing this?"
brightness_on = 15
flashlight_power = 1
flags_1 = CONDUCT_1
item_flags = DROPDEL
actions_types = list()
+32
View File
@@ -0,0 +1,32 @@
/obj/item/syndie_glue
name = "bottle of super glue"
desc = "A black market brand of high strength adhesive, rarely sold to the public. Do not ingest."
icon = 'icons/obj/tools.dmi'
icon_state = "glue"
w_class = WEIGHT_CLASS_SMALL
var/uses = 1
/obj/item/syndie_glue/suicide_act(mob/living/carbon/M)
return //todo
/obj/item/syndie_glue/afterattack(atom/target, mob/user, proximity)
. = ..()
if(!proximity || !target)
return
else
if(uses == 0)
to_chat(user, "<span class='warning'>The bottle of glue is empty!</span>")
return
if(istype(target, /obj/item))
var/obj/item/I = target
if(I.item_flags & NODROP)
to_chat(user, "<span class='warning'>[I] is already sticky!</span>")
return
uses -= 1
I.item_flags |= NODROP
I.desc += " It looks sticky."
to_chat(user, "<span class='notice'>You smear the [I] with glue, making it incredibly sticky!</span>")
if(uses == 0)
icon_state = "glue_used"
name = "empty bottle of super glue"
return
@@ -54,7 +54,7 @@
/obj/item/instrument/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/musicaltuner))
var/mob/living/carbon/human/H = user
if (H.has_trait(TRAIT_MUSICIAN))
if (HAS_TRAIT(H, TRAIT_MUSICIAN))
if (!tune_time)
H.visible_message("[H] tunes the [src] to perfection!", "<span class='notice'>You tune the [src] to perfection!</span>")
tune_time = 300
@@ -69,7 +69,7 @@
if (!user.IsAdvancedToolUser())
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
return
if(user.has_trait(TRAIT_NOGUNS))
if(HAS_TRAIT(user, TRAIT_NOGUNS))
to_chat(user, "<span class='warning'>Your fingers can't press the button!</span>")
return
if(ishuman(user))
+24 -25
View File
@@ -95,7 +95,7 @@ SLIME SCANNER
/obj/item/healthanalyzer/attack(mob/living/M, mob/living/carbon/human/user)
// Clumsiness/brain damage check
if ((user.has_trait(TRAIT_CLUMSY) || user.has_trait(TRAIT_DUMB)) && prob(50))
if ((HAS_TRAIT(user, TRAIT_CLUMSY) || HAS_TRAIT(user, TRAIT_DUMB)) && prob(50))
to_chat(user, "<span class='notice'>You stupidly try to analyze the floor's vitals!</span>")
user.visible_message("<span class='warning'>[user] has analyzed the floor's vitals!</span>")
var/msg = "<span class='info'>*---------*\nAnalyzing results for The floor:\n\tOverall status: <b>Healthy</b>\n"
@@ -127,7 +127,7 @@ SLIME SCANNER
var/brute_loss = M.getBruteLoss()
var/mob_status = (M.stat == DEAD ? "<span class='alert'><b>Deceased</b></span>" : "<b>[round(M.health/M.maxHealth,0.01)*100] % healthy</b>")
if(M.has_trait(TRAIT_FAKEDEATH) && !advanced)
if(HAS_TRAIT(M, TRAIT_FAKEDEATH) && !advanced)
mob_status = "<span class='alert'><b>Deceased</b></span>"
oxy_loss = max(rand(1, 40), oxy_loss, (300 - (tox_loss + fire_loss + brute_loss))) // Random oxygen loss
@@ -199,10 +199,10 @@ SLIME SCANNER
msg += "\t<span class='info'><b>==EAR STATUS==</b></span>\n"
if(istype(ears))
var/healthy = TRUE
if(C.has_trait(TRAIT_DEAF, GENETIC_MUTATION))
if(HAS_TRAIT_FROM(C, TRAIT_DEAF, GENETIC_MUTATION))
healthy = FALSE
msg += "\t<span class='alert'>Subject is genetically deaf.</span>\n"
else if(C.has_trait(TRAIT_DEAF))
else if(HAS_TRAIT(C, TRAIT_DEAF))
healthy = FALSE
msg += "\t<span class='alert'>Subject is deaf.</span>\n"
else
@@ -220,10 +220,10 @@ SLIME SCANNER
msg += "\t<span class='info'><b>==EYE STATUS==</b></span>\n"
if(istype(eyes))
var/healthy = TRUE
if(C.has_trait(TRAIT_BLIND))
if(HAS_TRAIT(C, TRAIT_BLIND))
msg += "\t<span class='alert'>Subject is blind.</span>\n"
healthy = FALSE
if(C.has_trait(TRAIT_NEARSIGHT))
if(HAS_TRAIT(C, TRAIT_NEARSIGHT))
msg += "\t<span class='alert'>Subject is nearsighted.</span>\n"
healthy = FALSE
if(eyes.eye_damage > 30)
@@ -290,7 +290,7 @@ SLIME SCANNER
msg += "<span class='info'>Body temperature: [round(M.bodytemperature-T0C,0.1)] &deg;C ([round(M.bodytemperature*1.8-459.67,0.1)] &deg;F)</span>\n"
// Time of death
if(M.tod && (M.stat == DEAD || ((M.has_trait(TRAIT_FAKEDEATH)) && !advanced)))
if(M.tod && (M.stat == DEAD || ((HAS_TRAIT(M, TRAIT_FAKEDEATH)) && !advanced)))
msg += "<span class='info'>Time of Death:</span> [M.tod]\n"
var/tdelta = round(world.time - M.timeofdeath)
if(tdelta < (DEFIB_TIME_LIMIT * 10))
@@ -428,39 +428,38 @@ SLIME SCANNER
if(total_moles)
var/list/env_gases = environment.gases
environment.assert_gases(arglist(GLOB.hardcoded_gases))
var/o2_concentration = env_gases[/datum/gas/oxygen][MOLES]/total_moles
var/n2_concentration = env_gases[/datum/gas/nitrogen][MOLES]/total_moles
var/co2_concentration = env_gases[/datum/gas/carbon_dioxide][MOLES]/total_moles
var/plasma_concentration = env_gases[/datum/gas/plasma][MOLES]/total_moles
var/o2_concentration = env_gases[/datum/gas/oxygen]/total_moles
var/n2_concentration = env_gases[/datum/gas/nitrogen]/total_moles
var/co2_concentration = env_gases[/datum/gas/carbon_dioxide]/total_moles
var/plasma_concentration = env_gases[/datum/gas/plasma]/total_moles
if(abs(n2_concentration - N2STANDARD) < 20)
to_chat(user, "<span class='info'>Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/nitrogen][MOLES], 0.01)] mol)</span>")
to_chat(user, "<span class='info'>Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/nitrogen], 0.01)] mol)</span>")
else
to_chat(user, "<span class='alert'>Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/nitrogen][MOLES], 0.01)] mol)</span>")
to_chat(user, "<span class='alert'>Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/nitrogen], 0.01)] mol)</span>")
if(abs(o2_concentration - O2STANDARD) < 2)
to_chat(user, "<span class='info'>Oxygen: [round(o2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/oxygen][MOLES], 0.01)] mol)</span>")
to_chat(user, "<span class='info'>Oxygen: [round(o2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/oxygen], 0.01)] mol)</span>")
else
to_chat(user, "<span class='alert'>Oxygen: [round(o2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/oxygen][MOLES], 0.01)] mol)</span>")
to_chat(user, "<span class='alert'>Oxygen: [round(o2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/oxygen], 0.01)] mol)</span>")
if(co2_concentration > 0.01)
to_chat(user, "<span class='alert'>CO2: [round(co2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/carbon_dioxide][MOLES], 0.01)] mol)</span>")
to_chat(user, "<span class='alert'>CO2: [round(co2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/carbon_dioxide], 0.01)] mol)</span>")
else
to_chat(user, "<span class='info'>CO2: [round(co2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/carbon_dioxide][MOLES], 0.01)] mol)</span>")
to_chat(user, "<span class='info'>CO2: [round(co2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/carbon_dioxide], 0.01)] mol)</span>")
if(plasma_concentration > 0.005)
to_chat(user, "<span class='alert'>Plasma: [round(plasma_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/plasma][MOLES], 0.01)] mol)</span>")
to_chat(user, "<span class='alert'>Plasma: [round(plasma_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/plasma], 0.01)] mol)</span>")
else
to_chat(user, "<span class='info'>Plasma: [round(plasma_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/plasma][MOLES], 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)
if(id in GLOB.hardcoded_gases)
continue
var/gas_concentration = env_gases[id][MOLES]/total_moles
to_chat(user, "<span class='alert'>[env_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] % ([round(env_gases[id][MOLES], 0.01)] mol)</span>")
var/gas_concentration = env_gases[id]/total_moles
to_chat(user, "<span class='alert'>[GLOB.meta_gas_names[id]]: [round(gas_concentration*100, 0.01)] % ([round(env_gases[id], 0.01)] mol)</span>")
to_chat(user, "<span class='info'>Temperature: [round(environment.temperature-T0C, 0.01)] &deg;C ([round(environment.temperature, 0.01)] K)</span>")
/obj/item/analyzer/AltClick(mob/user) //Barometer output for measuring when the next storm happens
@@ -550,8 +549,8 @@ SLIME SCANNER
var/list/cached_gases = air_contents.gases
for(var/id in cached_gases)
var/gas_concentration = cached_gases[id][MOLES]/total_moles
to_chat(user, "<span class='notice'>[cached_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] % ([round(cached_gases[id][MOLES], 0.01)] mol)</span>")
var/gas_concentration = cached_gases[id]/total_moles
to_chat(user, "<span class='notice'>[GLOB.meta_gas_names[id]]: [round(gas_concentration*100, 0.01)] % ([round(cached_gases[id], 0.01)] mol)</span>")
to_chat(user, "<span class='notice'>Temperature: [round(temperature - T0C,0.01)] &deg;C ([round(temperature, 0.01)] K)</span>")
else
+2 -2
View File
@@ -31,7 +31,7 @@
/obj/item/dnainjector/proc/inject(mob/living/carbon/M, mob/user)
prepare()
if(M.has_dna() && !M.has_trait(TRAIT_RADIMMUNE) && !M.has_trait(TRAIT_NOCLONE))
if(M.has_dna() && !HAS_TRAIT(M, TRAIT_RADIMMUNE) && !HAS_TRAIT(M, TRAIT_NOCLONE))
M.radiation += rand(20/(damage_coeff ** 2),50/(damage_coeff ** 2))
var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]"
for(var/datum/mutation/human/HM in remove_mutations)
@@ -313,7 +313,7 @@
to_chat(user, "<span class='notice'>You can't modify [M]'s DNA while [M.p_theyre()] dead.</span>")
return FALSE
if(M.has_dna() && !(M.has_trait(TRAIT_NOCLONE)))
if(M.has_dna() && !(HAS_TRAIT(M, TRAIT_NOCLONE)))
M.radiation += rand(20/(damage_coeff ** 2),50/(damage_coeff ** 2))
var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]"
var/endtime = world.time+duration
+3 -4
View File
@@ -15,7 +15,6 @@
attack_verb = list("slammed", "whacked", "bashed", "thunked", "battered", "bludgeoned", "thrashed")
dog_fashion = /datum/dog_fashion/back
resistance_flags = FIRE_PROOF
container_type = AMOUNT_VISIBLE
var/max_water = 50
var/last_use = 1
var/chem = "water"
@@ -56,7 +55,7 @@
/obj/item/extinguisher/Initialize()
. = ..()
create_reagents(max_water)
create_reagents(max_water, AMOUNT_VISIBLE)
reagents.add_reagent(chem, max_water)
@@ -111,7 +110,7 @@
to_chat(user, "The safety is [safety ? "on" : "off"].")
if(reagents.total_volume)
to_chat(user, "<span class='notice'>Alt-click to empty it.</span>")
to_chat(user, "<span class='notice'>You can loose its <b>screws</b> to empty it.</span>")
/obj/item/extinguisher/proc/AttemptRefill(atom/target, mob/user)
if(istype(target, tanktype) && target.Adjacent(user))
@@ -245,7 +244,7 @@
var/turf/open/theturf = T
theturf.MakeSlippery(TURF_WET_WATER, min_wet_time = 10 SECONDS, wet_time_to_add = 5 SECONDS)
user.visible_message("[user] empties out \the [src] onto the floor using the release valve.", "<span class='info'>You quietly empty out \the [src] using its release valve.</span>")
user.visible_message("[user] empties out \the [src] onto the floor using the release valve.", "<span class='info'>You quietly empty out \the [src] by loosing the release valve's screws.</span>")
//firebot assembly
/obj/item/extinguisher/attackby(obj/O, mob/user, params)
+1 -1
View File
@@ -205,7 +205,7 @@
//Transfer 5% of current tank air contents to turf
var/datum/gas_mixture/air_transfer = ptank.air_contents.remove_ratio(release_amount)
if(air_transfer.gases[/datum/gas/plasma])
air_transfer.gases[/datum/gas/plasma][MOLES] *= 5
air_transfer.gases[/datum/gas/plasma] *= 5
target.assume_air(air_transfer)
//Burn it based on transfered gas
target.hotspot_expose((ptank.air_contents.temperature*2) + 380,500)
+27
View File
@@ -87,6 +87,33 @@
active = FALSE
UpdateButtonIcon()
/obj/item/book/granter/action/origami
granted_action = /datum/action/innate/origami
name = "The Art of Origami"
desc = "A meticulously in-depth manual explaining the art of paper folding."
icon_state = "origamibook"
actionname = "origami"
oneuse = TRUE
remarks = list("Dead-stick stability...", "Symmetry seems to play a rather large factor...", "Accounting for crosswinds... really?", "Drag coefficients of various paper types...", "Thrust to weight ratios?", "Positive dihedral angle?", "Center of gravity forward of the center of lift...")
/datum/action/innate/origami
name = "Origami Folding"
desc = "Toggles your ability to fold and catch robust paper airplanes."
button_icon_state = "origami_off"
check_flags = NONE
/datum/action/innate/origami/Activate()
to_chat(owner, "<span class='notice'>You will now fold origami planes.</span>")
button_icon_state = "origami_on"
active = TRUE
UpdateButtonIcon()
/datum/action/innate/origami/Deactivate()
to_chat(owner, "<span class='notice'>You will no longer fold origami planes.</span>")
button_icon_state = "origami_off"
active = FALSE
UpdateButtonIcon()
///SPELLS///
/obj/item/book/granter/spell
+1 -1
View File
@@ -33,7 +33,7 @@
qdel(src)
/obj/item/grenade/proc/clown_check(mob/living/carbon/human/user)
var/clumsy = user.has_trait(TRAIT_CLUMSY)
var/clumsy = HAS_TRAIT(user, TRAIT_CLUMSY)
if(clumsy && (clumsy_check == GRENADE_CLUMSY_FUMBLE))
if(prob(50))
to_chat(user, "<span class='warning'>Huh? How does this thing work?</span>")
+1 -1
View File
@@ -44,7 +44,7 @@
if(!istype(C))
return
if(iscarbon(user) && (user.has_trait(TRAIT_CLUMSY) && prob(50)))
if(iscarbon(user) && (HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50)))
to_chat(user, "<span class='warning'>Uh... how do those things work?!</span>")
apply_cuffs(user,user)
return
+5 -1
View File
@@ -546,6 +546,9 @@
/obj/item/nullrod/pride_hammer
icon_state = "pride"
item_state = "pride"
lefthand_file = 'icons/mob/inhands/weapons/hammers_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/hammers_righthand.dmi'
name = "Pride-struck Hammer"
desc = "It resonates an aura of Pride."
force = 16
@@ -553,7 +556,7 @@
w_class = 4
slot_flags = ITEM_SLOT_BACK
attack_verb = list("attacked", "smashed", "crushed", "splattered", "cracked")
hitsound = 'sound/weapons/blade1.ogg'
hitsound = 'sound/weapons/resonator_blast.ogg'
/obj/item/nullrod/pride_hammer/afterattack(atom/A as mob|obj|turf|area, mob/user, proximity)
. = ..()
@@ -573,6 +576,7 @@
lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi'
slot_flags = ITEM_SLOT_BELT
reach = 2
attack_verb = list("whipped", "lashed")
hitsound = 'sound/weapons/chainhit.ogg'
@@ -2,7 +2,6 @@
name = "chem implant"
desc = "Injects things."
icon_state = "reagents"
container_type = OPENCONTAINER
activated = FALSE
/obj/item/implant/chem/get_data()
@@ -23,7 +22,7 @@
/obj/item/implant/chem/Initialize()
. = ..()
create_reagents(50)
create_reagents(50, OPENCONTAINER)
GLOB.tracked_chem_implants += src
/obj/item/implant/chem/Destroy()
@@ -20,7 +20,7 @@
/obj/item/implant/mindshield/implant(mob/living/target, mob/user, silent = FALSE)
if(..())
if(!target.mind)
target.add_trait(TRAIT_MINDSHIELD, "implant")
ADD_TRAIT(target, TRAIT_MINDSHIELD, "implant")
target.sec_hud_set_implants()
return TRUE
@@ -49,7 +49,7 @@
to_chat(target, "<span class='warning'>You feel something interfering with your mental conditioning, but you resist it!</span>")
else
to_chat(target, "<span class='notice'>You feel a sense of peace and security. You are now protected from brainwashing.</span>")
target.add_trait(TRAIT_MINDSHIELD, "implant")
ADD_TRAIT(target, TRAIT_MINDSHIELD, "implant")
target.sec_hud_set_implants()
return TRUE
return FALSE
@@ -58,7 +58,7 @@
if(..())
if(isliving(target))
var/mob/living/L = target
L.remove_trait(TRAIT_MINDSHIELD, "implant")
REMOVE_TRAIT(L, TRAIT_MINDSHIELD, "implant")
L.sec_hud_set_implants()
if(target.stat != DEAD && !silent)
to_chat(target, "<span class='boldnotice'>Your mind suddenly feels terribly vulnerable. You are no longer safe from brainwashing.</span>")
@@ -33,24 +33,8 @@
/obj/item/implant/adrenalin/activate()
. = ..()
uses--
imp_in.do_adrenaline(150, TRUE, 0, 0, TRUE, list("inaprovaline" = 3, "synaptizine" = 10, "regen_jelly" = 10, "stimulants" = 10), "<span class='boldnotice'>You feel a sudden surge of energy!</span>")
to_chat(imp_in, "<span class='notice'>You feel a sudden surge of energy!</span>")
imp_in.SetSleeping(0)
imp_in.SetStun(0)
imp_in.SetKnockdown(0)
imp_in.SetUnconscious(0)
imp_in.adjustStaminaLoss(-150)
imp_in.stuttering = 0
imp_in.updatehealth()
imp_in.update_stamina()
imp_in.resting = 0
imp_in.lying = 0
imp_in.update_canmove()
imp_in.reagents.add_reagent("inaprovaline", 3) //let's give another chance to dumb fucks who forget to breathe
imp_in.reagents.add_reagent("synaptizine", 10)
imp_in.reagents.add_reagent("omnizine", 10)
imp_in.reagents.add_reagent("stimulants", 10)
if(!uses)
qdel(src)
@@ -185,7 +185,7 @@
objective = stripped_input(usr,"What order do you want to imprint on [C]?","Enter the order","",120)
message_admins("[ADMIN_LOOKUPFLW(user)] set brainwash machine objective to '[objective]'.")
log_game("[key_name(user)] set brainwash machine objective to '[objective]'.")
if(C.has_trait(TRAIT_MINDSHIELD))
if(HAS_TRAIT(C, TRAIT_MINDSHIELD))
return FALSE
brainwash(C, objective)
message_admins("[ADMIN_LOOKUPFLW(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.")
+5 -5
View File
@@ -37,7 +37,7 @@
</ol>
<p>
It really is that easy! Good luck!
</body>
</html>
"}
@@ -344,14 +344,14 @@
author = "Sir John Rose"
title = "Barman Recipes: Mixing Drinks and Changing Lives"
page_link = "Guide_to_food_and_drinks"
/obj/item/book/manual/wiki/robotics_cyborgs
name = "Robotics for Dummies"
icon_state = "borgbook"
author = "XISC"
title = "Robotics for Dummies"
page_link = "Guide_to_robotics"
/obj/item/book/manual/wiki/research_and_development
name = "Research and Development 101"
icon_state = "rdbook"
@@ -401,7 +401,7 @@
author = "the City-state of Atmosia"
title = "Lexica Atmosia"
page_link = "Guide_to_Atmospherics"
/obj/item/book/manual/wiki/medicine
name = "Medical Space Compendium, Volume 638"
icon_state = "book8"
@@ -441,7 +441,7 @@
H.dropItemToGround(W)
if(prob(50))
step(W, pick(GLOB.alldirs))
H.add_trait(TRAIT_DISFIGURED, TRAIT_GENERIC)
ADD_TRAIT(H, TRAIT_DISFIGURED, TRAIT_GENERIC)
H.bleed_rate = 5
H.gib_animation()
sleep(3)
+2 -1
View File
@@ -20,6 +20,7 @@
slot_flags = ITEM_SLOT_BELT
force = 14
throwforce = 10
reach = 2
w_class = WEIGHT_CLASS_NORMAL
attack_verb = list("flogged", "whipped", "lashed", "disciplined")
hitsound = 'sound/weapons/chainhit.ogg'
@@ -156,7 +157,7 @@
return //CIT CHANGE - ditto
add_fingerprint(user)
if((user.has_trait(TRAIT_CLUMSY)) && prob(50))
if((HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50))
to_chat(user, "<span class ='danger'>You club yourself over the head.</span>")
user.Knockdown(60 * force)
if(ishuman(user))
@@ -82,6 +82,6 @@
to_chat(user, "<span class='notice'>[src] [active ? "is now active":"can now be concealed"].</span>")
/obj/item/melee/transforming/proc/clumsy_transform_effect(mob/living/user)
if(clumsy_check && user.has_trait(TRAIT_CLUMSY) && prob(50))
if(clumsy_check && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
to_chat(user, "<span class='warning'>You accidentally cut yourself with [src], like a doofus!</span>")
user.take_bodypart_damage(5,5)
+42 -5
View File
@@ -591,16 +591,42 @@
desc = "An adorable stuffed toy that resembles a slime. It is practically just a hacky sack."
icon_state = "plushie_slime"
item_state = "plushie_slime"
attack_verb = list("blorbled", "slimed", "absorbed")
attack_verb = list("blorbled", "slimed", "absorbed", "glomped")
squeak_override = list('sound/effects/blobattack.ogg' = 1)
gender = FEMALE //given all the jokes and drawings, I'm not sure the xenobiologists would make a slimeboy
/obj/item/toy/plush/slimeplushie/annie
desc = "An adorable stuffed toy that resembles a slimey crewmember."
icon_state = "annie"
item_state = "annie"
/obj/item/toy/plush/slimeplushie/paxton
desc = "An adorable stuffed toy that resembles a slimey crewmember."
icon_state = "paxton"
item_state = "paxton"
attack_verb = list("CQC'd", "jabroni'd", "powergamed", "robusted", "cakehatted")
gender = MALE
/obj/item/toy/plush/awakenedplushie
name = "awakened plushie"
desc = "An ancient plushie that has grown enlightened to the true nature of reality."
icon_state = "plushie_awake"
item_state = "plushie_awake"
/obj/item/toy/plush/awakenedplushie/ComponentInitialize()
. = ..()
AddComponent(/datum/component/edit_complainer)
/obj/item/toy/plush/beeplushie
name = "bee plushie"
desc = "A cute toy that resembles an even cuter bee."
icon_state = "plushie_h"
item_state = "plushie_h"
attack_verb = list("stung")
gender = FEMALE
squeak_override = list('modular_citadel/sound/voice/scream_moth.ogg' = 1)
/obj/item/toy/plush/mothplushie
name = "insect plushie"
desc = "An adorable stuffed toy that resembles some kind of insect"
@@ -741,6 +767,10 @@
icon_state = "pavel"
item_state = "pavel"
/obj/item/toy/plush/mammal/mason
icon_state = "mason"
item_state = "mason"
/obj/item/toy/plush/mammal/oten
icon_state = "oten"
item_state = "oten"
@@ -749,6 +779,10 @@
icon_state = "ray"
item_state = "ray"
/obj/item/toy/plush/mammal/redtail
icon_state = "redtail"
item_state = "redtail"
/obj/item/toy/plush/mammal/dawud
icon_state = "dawud"
item_state = "dawud"
@@ -840,6 +874,13 @@
icon_state = "flynn"
item_state = "flynn"
/obj/item/toy/plush/mammal/dog/fritz
icon_state = "fritz"
item_state = "fritz"
attack_verb = list("barked", "boofed", "shotgun'd")
obj_flags = UNIQUE_RENAME
unique_reskin = list("Goodboye" = "fritz", "Badboye" = "fritz_bad")
/obj/item/toy/plush/catgirl
name = "feline plushie"
desc = "An adorable stuffed toy that resembles a feline."
@@ -877,7 +918,3 @@
item_state = "fermis"
attack_verb = list("cuddled", "petpatted", "wigglepurred")
squeak_override = list('modular_citadel/sound/voice/merowr.ogg' = 1)
/obj/item/toy/plush/awakenedplushie/ComponentInitialize()
. = ..()
AddComponent(/datum/component/edit_complainer)
+1 -1
View File
@@ -150,7 +150,7 @@
if(tank && !tank.air_contents.remove(gasPerThrow * pressureSetting))
to_chat(user, "<span class='warning'>\The [src] lets out a weak hiss and doesn't react!</span>")
return
if(user.has_trait(TRAIT_CLUMSY) && prob(75) && clumsyCheck && iscarbon(user))
if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(75) && clumsyCheck && iscarbon(user))
var/mob/living/carbon/C = user
C.visible_message("<span class='warning'>[C] loses [C.p_their()] grip on [src], causing it to go off!</span>", "<span class='userdanger'>[src] slips out of your hands and goes off!</span>")
C.dropItemToGround(src, TRUE)
+1 -1
View File
@@ -187,7 +187,7 @@
inspiration_available = FALSE
/obj/item/banner/command/check_inspiration(mob/living/carbon/human/H)
return H.has_trait(TRAIT_MINDSHIELD) //Command is stalwart but rewards their allies.
return HAS_TRAIT(H, TRAIT_MINDSHIELD) //Command is stalwart but rewards their allies.
/datum/crafting_recipe/command_banner
name = "Command Banner"
+12 -2
View File
@@ -20,7 +20,6 @@
attack_verb = list("shoved", "bashed")
var/cooldown = 0 //shield bash cooldown. based on world.time
/obj/item/shield/riot/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/melee/baton))
if(cooldown < world.time - 25)
@@ -91,7 +90,7 @@
return (active)
/obj/item/shield/energy/attack_self(mob/living/carbon/human/user)
if(clumsy_check && user.has_trait(TRAIT_CLUMSY) && prob(50))
if(clumsy_check && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
to_chat(user, "<span class='warning'>You beat yourself in the head with [src].</span>")
user.take_bodypart_damage(5)
active = !active
@@ -166,3 +165,14 @@
block_chance = 25
force = 5
throwforce = 7
/obj/item/shield/riot/tower
name = "tower shield"
desc = "A massive shield that can block a lot of attacks, can take a lot of abuse before braking."
armor = list("melee" = 95, "bullet" = 95, "laser" = 75, "energy" = 60, "bomb" = 90, "bio" = 90, "rad" = 0, "fire" = 90, "acid" = 10) //Armor for the item, dosnt transfer to user
item_state = "metal"
block_chance = 75 //1/4 shots will hit*
force = 10
slowdown = 2
throwforce = 15 //Massive pice of metal
w_class = WEIGHT_CLASS_HUGE
@@ -281,12 +281,12 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list(
var/hit_hand = ((user.active_hand_index % 2 == 0) ? "r_" : "l_") + "arm"
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(!H.gloves && !H.has_trait(TRAIT_PIERCEIMMUNE)) // golems, etc
if(!H.gloves && !HAS_TRAIT(H, TRAIT_PIERCEIMMUNE)) // golems, etc
to_chat(H, "<span class='warning'>[src] cuts into your hand!</span>")
H.apply_damage(force*0.5, BRUTE, hit_hand)
else if(ismonkey(user))
var/mob/living/carbon/monkey/M = user
if(!M.has_trait(TRAIT_PIERCEIMMUNE))
if(!HAS_TRAIT(M, TRAIT_PIERCEIMMUNE))
to_chat(M, "<span class='warning'>[src] cuts into your hand!</span>")
M.apply_damage(force*0.5, BRUTE, hit_hand)
@@ -312,7 +312,7 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list(
/obj/item/shard/Crossed(mob/living/L)
if(istype(L) && has_gravity(loc))
if(L.has_trait(TRAIT_LIGHT_STEP))
if(HAS_TRAIT(L, TRAIT_LIGHT_STEP))
playsound(loc, 'sound/effects/glass_step.ogg', 30, 1)
else
playsound(loc, 'sound/effects/glass_step.ogg', 50, 1)
@@ -282,9 +282,14 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \
*/
GLOBAL_LIST_INIT(cardboard_recipes, list ( \
new/datum/stack_recipe("box", /obj/item/storage/box), \
new/datum/stack_recipe("sec box", /obj/item/storage/box/seclooking), \
new/datum/stack_recipe("light tubes", /obj/item/storage/box/lights/tubes), \
new/datum/stack_recipe("light bulbs", /obj/item/storage/box/lights/bulbs), \
new/datum/stack_recipe("mouse traps", /obj/item/storage/box/mousetraps), \
new/datum/stack_recipe("pizza box", /obj/item/pizzabox), \
new/datum/stack_recipe("power cell", /obj/item/storage/box/cells), \
new/datum/stack_recipe("02", /obj/item/storage/box/otwo), \
null, \
new/datum/stack_recipe("lethal ammo box", /obj/item/storage/box/lethalshot), \
new/datum/stack_recipe("rubber shot ammo box", /obj/item/storage/box/rubbershot), \
new/datum/stack_recipe("bean bag ammo box", /obj/item/storage/box/beanbag), \
@@ -292,13 +297,23 @@ GLOBAL_LIST_INIT(cardboard_recipes, list ( \
new/datum/stack_recipe("stun slug ammo box", /obj/item/storage/box/stunslug), \
new/datum/stack_recipe("tech shell ammo box", /obj/item/storage/box/techsslug), \
new/datum/stack_recipe("incendiary ammo box", /obj/item/storage/box/fireshot), \
new/datum/stack_recipe("firing pins", /obj/item/storage/box/firingpins), \
new/datum/stack_recipe("loose ammo", /obj/item/storage/box/ammoshells), \
null, \
new/datum/stack_recipe("cardborg suit", /obj/item/clothing/suit/cardborg, 3), \
new/datum/stack_recipe("cardborg helmet", /obj/item/clothing/head/cardborg), \
new/datum/stack_recipe("pizza box", /obj/item/pizzabox), \
new/datum/stack_recipe("folder", /obj/item/folder), \
new/datum/stack_recipe("large box", /obj/structure/closet/cardboard, 4), \
new/datum/stack_recipe("cardboard cutout", /obj/item/cardboard_cutout, 5), \
))
null, \
new/datum/stack_recipe("colored brown", /obj/item/storage/box/brown), \
new/datum/stack_recipe("colored green", /obj/item/storage/box/green), \
new/datum/stack_recipe("colored red", /obj/item/storage/box/blue), \
new/datum/stack_recipe("colored blue", /obj/item/storage/box/red), \
new/datum/stack_recipe("colored yellow", /obj/item/storage/box/yellow), \
new/datum/stack_recipe("colored pink", /obj/item/storage/box/pink), \
new/datum/stack_recipe("colored purple", /obj/item/storage/box/purple), \
))
/obj/item/stack/sheet/cardboard //BubbleWrap //it's cardboard you fuck
name = "cardboard"
@@ -394,8 +409,10 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \
new/datum/stack_recipe("brass pinion airlock - windowed", /obj/machinery/door/airlock/clockwork/brass, 5, time = 50, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("brass windoor", /obj/machinery/door/window/clockwork, 2, time = 30, on_floor = TRUE, window_checks = TRUE), \
null,
new/datum/stack_recipe("directional brass window", /obj/structure/window/reinforced/clockwork/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \
new/datum/stack_recipe("fulltile brass window", /obj/structure/window/reinforced/clockwork/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \
new/datum/stack_recipe("brass reflector", /obj/structure/destructible/clockwork/reflector, 10, time = 100, one_per_turf = TRUE, on_floor = TRUE, window_checks = TRUE), \
null,
new/datum/stack_recipe("brass window - directional", /obj/structure/window/reinforced/clockwork/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \
new/datum/stack_recipe("brass window - fulltile", /obj/structure/window/reinforced/clockwork/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \
new/datum/stack_recipe("brass chair", /obj/structure/chair/brass, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("brass table frame", /obj/structure/table_frame/brass, 1, time = 5, one_per_turf = TRUE, on_floor = TRUE), \
null,
+29 -1
View File
@@ -28,7 +28,6 @@
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.max_items = 21
/*
* Backpack Types
*/
@@ -244,6 +243,18 @@
icon_state = "satchel-explorer"
item_state = "securitypack"
/obj/item/storage/backpack/satchel/bone
name = "bone satchel"
desc = "A bone satchel fashend with watcher wings and large bones from goliath. Can be worn on the belt."
icon = 'icons/obj/mining.dmi'
icon_state = "goliath_saddle"
slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_BELT
/obj/item/storage/backpack/satchel/bone/ComponentInitialize()
. = ..()
GET_COMPONENT(STR, /datum/component/storage)
STR.max_combined_w_class = 10
/obj/item/storage/backpack/satchel/cap
name = "captain's satchel"
desc = "An exclusive satchel for Nanotrasen officers."
@@ -447,6 +458,8 @@
new /obj/item/clothing/suit/straight_jacket(src)
new /obj/item/clothing/mask/muzzle(src)
new /obj/item/mmi/syndie(src)
new /obj/item/implantcase(src)
new /obj/item/implanter(src)
/obj/item/storage/backpack/duffelbag/syndie/surgery_adv
name = "advanced surgery duffel bag"
@@ -464,6 +477,8 @@
new /obj/item/clothing/suit/straight_jacket(src)
new /obj/item/clothing/mask/muzzle(src)
new /obj/item/mmi/syndie(src)
new /obj/item/implantcase(src)
new /obj/item/implanter(src)
/obj/item/storage/backpack/duffelbag/syndie/ammo
name = "ammunition duffel bag"
@@ -574,3 +589,16 @@
new /obj/item/clothing/mask/gas/clown_hat(src)
new /obj/item/bikehorn(src)
new /obj/item/implanter/sad_trombone(src)
obj/item/storage/backpack/duffelbag/syndie/shredderbundle
desc = "A large duffel bag containing two CX Shredders, some magazines, an elite hardsuit, and a chest rig."
/obj/item/storage/backpack/duffelbag/syndie/shredderbundle/PopulateContents()
new /obj/item/ammo_box/magazine/flechette/shredder(src)
new /obj/item/ammo_box/magazine/flechette/shredder(src)
new /obj/item/ammo_box/magazine/flechette/shredder(src)
new /obj/item/ammo_box/magazine/flechette/shredder(src)
new /obj/item/gun/ballistic/automatic/flechette/shredder(src)
new /obj/item/gun/ballistic/automatic/flechette/shredder(src)
new /obj/item/storage/belt/military(src)
new /obj/item/clothing/suit/space/hardsuit/syndi/elite(src)
+19
View File
@@ -541,6 +541,25 @@
/obj/item/ammo_casing/shotgun
))
/obj/item/storage/belt/medolier
name = "medolier"
desc = "A medical bandolier for holding smartdarts."
icon_state = "medolier"
item_state = "medolier"
/obj/item/storage/belt/medolier/ComponentInitialize()
. = ..()
GET_COMPONENT(STR, /datum/component/storage)
STR.max_items = 15
STR.display_numerical_stacking = FALSE
STR.can_hold = typecacheof(list(
/obj/item/reagent_containers/syringe/dart
))
/obj/item/storage/belt/medolier/full/PopulateContents()
for(var/i in 1 to 16)
new /obj/item/reagent_containers/syringe/dart/(src)
/obj/item/storage/belt/holster
name = "shoulder holster"
desc = "A holster to carry a handgun and ammo. WARNING: Badasses only."
+1 -1
View File
@@ -109,7 +109,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
return
if (user.has_trait(TRAIT_CLUMSY) && prob(50))
if (HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
to_chat(user, "<span class='danger'>[src] slips out of your hand and hits your head.</span>")
user.take_bodypart_damage(10)
user.Unconscious(400)
+75 -11
View File
@@ -15,9 +15,10 @@
* Handcuff, mousetrap, and pillbottle boxes,
* Snap-pops and matchboxes,
* Replacement light boxes,
* Shotgun Ammo boxes,
* Ammo types,
* Action Figure Boxes,
* Various paper bags.
* Various paper bags,
* Colored boxes
*
* For syndicate call-ins see uplink_kits.dm
*/
@@ -75,7 +76,6 @@
return 0
return ..()
//Disk boxes
/obj/item/storage/box/disks
name = "diskette box"
@@ -142,6 +142,29 @@
..() // we want the regular stuff too
new /obj/item/radio/off(src)
/obj/item/storage/box/seclooking
icon_state = "secbox"
illustration = null
/obj/item/storage/box/cells
name = "box of powercells"
desc = "Contains powercells."
illustration = "power_cell"
/obj/item/storage/box/ammoshells
name = "box of loose ammo"
desc = "Contains loose ammo."
illustration = "loose_ammo"
/obj/item/storage/box/otwo
name = "box of o2 supplies"
desc = "Contains o2 supplies."
illustration = "02"
/obj/item/storage/box/otwo/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/tank/internals/emergency_oxygen/engi(src)
/obj/item/storage/box/gloves
name = "box of latex gloves"
desc = "Contains sterile latex gloves."
@@ -463,7 +486,7 @@
/obj/item/storage/box/firingpins
name = "box of standard firing pins"
desc = "A box full of standard firing pins, to allow newly-developed firearms to operate."
illustration = "id"
illustration = "firing_pins"
/obj/item/storage/box/firingpins/PopulateContents()
for(var/i in 1 to 5)
@@ -472,7 +495,7 @@
/obj/item/storage/box/lasertagpins
name = "box of laser tag firing pins"
desc = "A box full of laser tag firing pins, to allow newly-developed firearms to require wearing brightly coloured plastic armor before being able to be used."
illustration = "id"
illustration = "firing_pins"
/obj/item/storage/box/lasertagpins/PopulateContents()
for(var/i in 1 to 3)
@@ -699,7 +722,7 @@
new /obj/item/ammo_casing/shotgun/rubbershot(src)
/obj/item/storage/box/lethalshot
name = "box of lethal shotgun shots"
name = "box of buckshot (Lethal)"
desc = "A box full of lethal shots, designed for riot shotguns."
icon_state = "lethalshot_box"
illustration = null
@@ -726,7 +749,7 @@
/obj/item/storage/box/lethalslugs/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/projectile/bullet/shotgun_slug(src)
new /obj/item/ammo_casing/shotgun(src)
/obj/item/storage/box/stunslug
name = "box of stun slugs"
@@ -736,7 +759,7 @@
/obj/item/storage/box/stunslug/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/projectile/bullet/shotgun_stunslug(src)
new /obj/item/ammo_casing/shotgun/stunslug(src)
/obj/item/storage/box/techsslug
name = "box of tech shotgun shells"
@@ -750,11 +773,11 @@
/obj/item/storage/box/fireshot
name = "box of incendiary ammo"
desc = "A box full of tech incendiary ammo."
desc = "A box full of incendiary ammo."
icon_state = "fireshot_box"
illustration = null
/obj/item/storage/box/techsslug/PopulateContents()
/obj/item/storage/box/fireshot/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/ammo_casing/shotgun/incendiary(src)
@@ -768,6 +791,19 @@
var/randomFigure = pick(subtypesof(/obj/item/toy/figure))
new randomFigure(src)
/obj/item/storage/box/mechfigures
name = "box of mech figures"
desc = "The latest set of collectable mech figures."
icon_state = "box"
/obj/item/storage/box/mechfigures/PopulateContents()
for(var/i in 1 to 4)
var/randomFigure = pick(subtypesof(/obj/item/toy/prize/))
new randomFigure(src)
#define NODESIGN "None"
#define NANOTRASEN "NanotrasenStandard"
#define SYNDI "SyndiSnacks"
@@ -1003,7 +1039,6 @@
for(var/i in 1 to 7)
new /obj/item/reagent_containers/pill/patch/silver_sulf(src)
/obj/item/storage/box/fountainpens
name = "box of fountain pens"
@@ -1062,3 +1097,32 @@
new /obj/item/stock_parts/matter_bin/bluespace(src)
new /obj/item/stock_parts/matter_bin/bluespace(src)
new /obj/item/stock_parts/matter_bin/bluespace(src)
//Colored boxes.
/obj/item/storage/box/green
icon_state = "box_green"
illustration = null
/obj/item/storage/box/blue
icon_state = "box_blue"
illustration = null
/obj/item/storage/box/purple
icon_state = "box_purple"
illustration = null
/obj/item/storage/box/red
icon_state = "box_red"
illustration = null
/obj/item/storage/box/yellow
icon_state = "box_yellow"
illustration = null
/obj/item/storage/box/brown
icon_state = "box_brown"
illustration = null
/obj/item/storage/box/pink
icon_state = "box_pink"
illustration = null
+28 -2
View File
@@ -38,9 +38,10 @@
/obj/item/storage/briefcase/lawyer
folder_path = /obj/item/folder/blue
/obj/item/storage/briefcase/lawyer/family
/obj/item/storage/briefcase/lawyer/family
name = "battered briefcase"
desc = "An old briefcase, this one has seen better days in its time. It's clear they don't make them nowadays as good as they used to. The corners are modified with metal trim adding in weight!"
desc = "An old briefcase, this one has seen better days in its time. It's clear they don't make them nowadays as good as they used to. Comes with an added belt clip!"
slot_flags = ITEM_SLOT_BELT
/obj/item/storage/briefcase/lawyer/family/PopulateContents()
new /obj/item/stamp/law(src)
@@ -79,3 +80,28 @@
new /obj/item/ammo_box/magazine/sniper_rounds/soporific(src)
new /obj/item/suppressor/specialoffer(src)
/obj/item/storage/briefcase/modularbundle
desc = "It's label reads genuine hardened Captain leather, but suspiciously has no other tags or branding."
force = 10
/obj/item/storage/briefcase/modularbundle/PopulateContents()
new /obj/item/gun/ballistic/automatic/pistol/modular(src)
new /obj/item/suppressor(src)
new /obj/item/ammo_box/magazine/m10mm(src)
new /obj/item/ammo_box/magazine/m10mm/soporific(src)
new /obj/item/ammo_box/c10mm/soporific(src)
new /obj/item/clothing/under/lawyer/blacksuit(src)
new /obj/item/clothing/accessory/waistcoat(src)
new /obj/item/clothing/suit/toggle/lawyer/black/syndie(src)
/obj/item/storage/briefcase/medical
name = "medical briefcase"
icon_state = "medbriefcase"
desc = "A white with a blue cross brieface, this is ment to hold medical gear that would not be able to normally fit in a bag."
/obj/item/storage/briefcase/medical/PopulateContents()
new /obj/item/clothing/neck/stethoscope(src)
new /obj/item/healthanalyzer(src)
..() //In case of paperwork
@@ -320,3 +320,46 @@
/obj/item/storage/pill_bottle/penis_enlargement/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/reagent_containers/pill/penis_enlargement(src)
/////////////
//Organ Box//
/////////////
/obj/item/storage/belt/organbox
name = "Organ Storge"
desc = "A compact box that helps hold massive amounts of implants, organs, and some tools. Has a belt clip for easy carrying"
w_class = WEIGHT_CLASS_BULKY
icon = 'icons/obj/mysterybox.dmi'
icon_state = "organbox_open"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
throw_speed = 1
throw_range = 1
/obj/item/storage/belt/organbox/ComponentInitialize()
. = ..()
GET_COMPONENT(STR, /datum/component/storage)
STR.max_items = 16
STR.max_w_class = WEIGHT_CLASS_BULKY
STR.max_combined_w_class = 20
STR.can_hold = typecacheof(list(
/obj/item/storage/pill_bottle,
/obj/item/reagent_containers/hypospray,
/obj/item/healthanalyzer,
/obj/item/reagent_containers/syringe,
/obj/item/clothing/glasses/hud/health,
/obj/item/hemostat,
/obj/item/scalpel,
/obj/item/retractor,
/obj/item/cautery,
/obj/item/surgical_drapes,
/obj/item/autosurgeon,
/obj/item/organ,
/obj/item/implant,
/obj/item/implantpad,
/obj/item/implantcase,
/obj/item/implanter,
/obj/item/circuitboard/computer/operating,
/obj/item/stack/sheet/mineral/silver,
/obj/item/organ_storage
))
@@ -183,6 +183,22 @@
slab_type = /obj/item/clockwork/slab/debug
fabricator_type = /obj/item/clockwork/replica_fabricator/scarab/debug
/obj/item/storage/toolbox/durasteel
name = "durasteel toolbox"
desc = "A toolbox made out of durasteel. Probably packs a massive punch."
total_mass = 5
icon_state = "blue"
item_state = "toolbox_blue"
w_class = WEIGHT_CLASS_HUGE //heyo no bohing this!
force = 18 //spear damage
/obj/item/storage/toolbox/durasteel/afterattack(atom/A, mob/user, proximity)
. = ..()
if(proximity && isobj(A) && !isitem(A))
var/obj/O = A
//50 total object damage but split up for stuff like damage deflection.
O.take_damage(22)
O.take_damage(10)
/obj/item/storage/toolbox/artistic
name = "artistic toolbox"
+33 -19
View File
@@ -2,7 +2,7 @@
/obj/item/storage/box/syndicate/PopulateContents()
switch (pickweight(list("bloodyspai" = 3, "stealth" = 2, "bond" = 2, "screwed" = 2, "sabotage" = 3, "guns" = 2, "murder" = 2, "implant" = 1, "hacker" = 3, "darklord" = 1, "sniper" = 1, "metaops" = 1, "ninja" = 1)))
if("bloodyspai") // 27 tc now this is more right
if("bloodyspai") // 30 tc now this is more right
new /obj/item/clothing/under/chameleon(src) // 2 tc since it's not the full set
new /obj/item/clothing/mask/chameleon(src) // Goes with above
new /obj/item/card/id/syndicate(src) // 2 tc
@@ -11,7 +11,7 @@
new /obj/item/multitool/ai_detect(src) // 1 tc
new /obj/item/encryptionkey/syndicate(src) // 2 tc
new /obj/item/reagent_containers/syringe/mulligan(src) // 4 tc
new /obj/item/switchblade(src) //I'll count this as 2 tc
new /obj/item/switchblade(src) //I'll count this as 5 tc
new /obj/item/storage/fancy/cigarettes/cigpack_syndicate (src) // 2 tc this shit heals
new /obj/item/flashlight/emp(src) // 2 tc
new /obj/item/chameleon(src) // 7 tc
@@ -25,13 +25,13 @@
new /obj/item/clothing/glasses/thermal/syndi(src)
if("bond") // 29 tc
new /obj/item/gun/ballistic/automatic/pistol(src)
new /obj/item/suppressor(src)
new /obj/item/gun/ballistic/automatic/pistol/suppressed(src)
new /obj/item/ammo_box/magazine/m10mm(src)
new /obj/item/ammo_box/magazine/m10mm(src)
new /obj/item/clothing/under/chameleon(src)
new /obj/item/card/id/syndicate(src)
new /obj/item/reagent_containers/syringe/stimulants(src)
new /obj/item/clothing/neck/tie/red(src)
if("screwed") // 29 tc
new /obj/item/sbeacondrop/bomb(src)
@@ -41,7 +41,7 @@
new /obj/item/clothing/head/helmet/space/syndicate/black/red(src)
new /obj/item/encryptionkey/syndicate(src)
if("guns") // 28 tc now
if("guns") // 30 tc now
new /obj/item/gun/ballistic/revolver(src)
new /obj/item/ammo_box/a357(src)
new /obj/item/ammo_box/a357(src)
@@ -50,39 +50,53 @@
new /obj/item/clothing/gloves/color/latex/nitrile(src)
new /obj/item/clothing/mask/gas/clown_hat(src)
new /obj/item/clothing/under/suit_jacket/really_black(src)
new /obj/item/screwdriver/power(src) //2 tc item
if("murder") // 28 tc now
if("murder") // 35 tc now
new /obj/item/melee/transforming/energy/sword/saber(src)
new /obj/item/clothing/glasses/thermal/syndi(src)
new /obj/item/card/emag(src)
new /obj/item/clothing/shoes/chameleon/noslip(src)
new /obj/item/encryptionkey/syndicate(src)
new /obj/item/grenade/syndieminibomb(src)
new /obj/item/clothing/glasses/phantomthief/syndicate(src)
new /obj/item/reagent_containers/syringe/stimulants(src)
if("implant") // 55+ tc holy shit what the fuck this is a lottery disguised as fun boxes isn't it?
if("implant") // 67+ tc holy shit what the fuck this is a lottery disguised as fun boxes isn't it?
new /obj/item/implanter/freedom(src)
new /obj/item/implanter/uplink/precharged(src)
new /obj/item/implanter/emp(src)
new /obj/item/implanter/adrenalin(src)
new /obj/item/implanter/explosive(src)
new /obj/item/implanter/storage(src)
new /obj/item/implanter/radio/syndicate(src)
new /obj/item/implanter/stealth(src)
if("hacker") // 26 tc
if("hacker") // 30 tc
new /obj/item/aiModule/syndicate(src)
new /obj/item/card/emag(src)
new /obj/item/encryptionkey/binary(src)
new /obj/item/aiModule/toyAI(src)
new /obj/item/multitool/ai_detect(src)
new /obj/item/flashlight/emp(src)
new /obj/item/emagrecharge(src)
if("lordsingulo") // 24 tc
new /obj/item/sbeacondrop(src)
new /obj/item/clothing/suit/space/syndicate/black/red(src)
new /obj/item/clothing/head/helmet/space/syndicate/black/red(src)
new /obj/item/card/emag(src)
if("lordsingulo") // "36" tc aka 23 tc
new /obj/item/sbeacondrop(src) // 14 kinda useless
new /obj/item/clothing/suit/space/syndicate/black/red(src) //2
new /obj/item/clothing/head/helmet/space/syndicate/black/red(src) //2
new /obj/item/card/emag(src) //6
new /obj/item/emagrecharge(src) //2
new /obj/item/storage/toolbox/syndicate(src) //1
new /obj/item/card/id/syndicate(src) //2
new /obj/item/flashlight/emp(src) //2
new /obj/item/jammer(src) //5
if("sabotage") // 26 tc now
if("sabotage") // ~28 tc now
new /obj/item/grenade/plastic/c4 (src)
new /obj/item/grenade/plastic/c4 (src)
new /obj/item/grenade/plastic/x4 (src)
new /obj/item/grenade/plastic/x4 (src)
new /obj/item/doorCharge(src)
new /obj/item/doorCharge(src)
new /obj/item/camera_bug(src)
@@ -117,15 +131,15 @@
new /obj/item/grenade/plastic/c4 (src) // 1 tc
new /obj/item/card/emag(src) // 6 tc
if("ninja") // 33 tc worth
new /obj/item/katana(src) // Unique , hard to tell how much tc this is worth. 8 tc?
if("ninja") // 40~ tc worth
new /obj/item/katana(src) // Unique , basicly a better esword. 10 tc?
new /obj/item/implanter/adrenalin(src) // 8 tc
new /obj/item/throwing_star(src) // ~5 tc for all 6
new /obj/item/throwing_star(src)
new /obj/item/throwing_star(src)
new /obj/item/throwing_star(src)
new /obj/item/throwing_star(src)
new /obj/item/throwing_star(src)
new /obj/item/implanter/emp(src)
new /obj/item/grenade/smokebomb(src)
new /obj/item/grenade/smokebomb(src)
new /obj/item/storage/belt/chameleon(src) // Unique but worth at least 2 tc
new /obj/item/card/id/syndicate(src) // 2 tc
new /obj/item/chameleon(src) // 7 tc
+48 -30
View File
@@ -22,7 +22,10 @@
var/preload_cell_type //if not empty the baton starts with this type of cell
/obj/item/melee/baton/get_cell()
return cell
. = cell
if(iscyborg(loc))
var/mob/living/silicon/robot/R = loc
. = R.get_cell()
/obj/item/melee/baton/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is putting the live [name] in [user.p_their()] mouth! It looks like [user.p_theyre()] trying to commit suicide!</span>")
@@ -46,14 +49,18 @@
/obj/item/melee/baton/loaded //this one starts with a cell pre-installed.
preload_cell_type = /obj/item/stock_parts/cell/high
/obj/item/melee/baton/proc/deductcharge(chrgdeductamt, chargecheck = TRUE)
if(!cell)
/obj/item/melee/baton/proc/deductcharge(chrgdeductamt, chargecheck = TRUE, explode = TRUE)
var/obj/item/stock_parts/cell/copper_top = get_cell()
if(!copper_top)
switch_status(FALSE, TRUE)
return FALSE
//Note this value returned is significant, as it will determine
//if a stun is applied or not
. = cell.use(chrgdeductamt)
if(status && (!. || (chargecheck && cell.charge < hitcost * STUNBATON_CHARGE_LENIENCY)))
copper_top.use(min(chrgdeductamt, copper_top.charge), explode)
if(QDELETED(src))
return FALSE
if(status && (!copper_top || !copper_top.charge || (chargecheck && copper_top.charge < (hitcost * STUNBATON_CHARGE_LENIENCY))))
//we're below minimum, turn off
switch_status(FALSE)
@@ -69,7 +76,7 @@
update_icon()
/obj/item/melee/baton/process()
deductcharge(hitcost * 0.004, FALSE)
deductcharge(hitcost * 0.004, FALSE, FALSE)
/obj/item/melee/baton/update_icon()
if(status)
@@ -80,9 +87,10 @@
icon_state = "[initial(name)]"
/obj/item/melee/baton/examine(mob/user)
..()
if(cell)
to_chat(user, "<span class='notice'>\The [src] is [round(cell.percent())]% charged.</span>")
. = ..()
var/obj/item/stock_parts/cell/copper_top = get_cell()
if(copper_top)
to_chat(user, "<span class='notice'>\The [src] is [round(copper_top.percent())]% charged.</span>")
else
to_chat(user, "<span class='warning'>\The [src] does not have a power source installed.</span>")
@@ -92,7 +100,7 @@
if(cell)
to_chat(user, "<span class='notice'>[src] already has a cell.</span>")
else
if(C.maxcharge < hitcost * STUNBATON_CHARGE_LENIENCY)
if(C.maxcharge < (hitcost * STUNBATON_CHARGE_LENIENCY))
to_chat(user, "<span class='notice'>[src] requires a higher capacity cell.</span>")
return
if(!user.transferItemToLoc(W, src))
@@ -112,19 +120,20 @@
return ..()
/obj/item/melee/baton/attack_self(mob/user)
if(cell && cell.charge > hitcost * STUNBATON_CHARGE_LENIENCY)
switch_status(!status)
to_chat(user, "<span class='notice'>[src] is now [status ? "on" : "off"].</span>")
else
var/obj/item/stock_parts/cell/copper_top = get_cell()
if(!copper_top || copper_top.charge < (hitcost * STUNBATON_CHARGE_LENIENCY))
switch_status(FALSE, TRUE)
if(!cell)
if(!copper_top)
to_chat(user, "<span class='warning'>[src] does not have a power source!</span>")
else
to_chat(user, "<span class='warning'>[src] is out of charge.</span>")
else
switch_status(!status)
to_chat(user, "<span class='notice'>[src] is now [status ? "on" : "off"].</span>")
add_fingerprint(user)
/obj/item/melee/baton/attack(mob/M, mob/living/carbon/human/user)
if(status && user.has_trait(TRAIT_CLUMSY) && prob(50))
if(status && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
clowning_around(user)
return
@@ -164,16 +173,21 @@
playsound(L, 'sound/weapons/genhit.ogg', 50, 1)
return FALSE
var/stunpwr = stunforce
if(iscyborg(loc))
var/mob/living/silicon/robot/R = loc
if(!istype(R) || !R.cell || !R.cell.use(hitcost))
var/obj/item/stock_parts/cell/our_cell = get_cell()
if(!our_cell)
switch_status(FALSE)
return FALSE
var/stuncharge = our_cell.charge
deductcharge(hitcost, FALSE)
if(QDELETED(src) || QDELETED(our_cell)) //it was rigged
return FALSE
if(stuncharge < hitcost)
if(stuncharge < (hitcost * STUNBATON_CHARGE_LENIENCY))
L.visible_message("<span class='warning'>[user] has prodded [L] with [src]. Luckily it was out of charge.</span>", \
"<span class='warning'>[user] has prodded you with [src]. Luckily it was out of charge.</span>")
return FALSE
else
var/stuncharge = cell.charge
if(!deductcharge(hitcost, FALSE))
stunpwr *= round(stuncharge/hitcost)
if(stunpwr < stunforce * STUNBATON_CHARGE_LENIENCY)
return FALSE
stunpwr *= round(stuncharge/hitcost, 0.1)
L.Knockdown(stunpwr)
L.adjustStaminaLoss(stunpwr*0.1, affected_zone = (istype(user) ? user.zone_selected : BODY_ZONE_CHEST))//CIT CHANGE - makes stunbatons deal extra staminaloss. Todo: make this also deal pain when pain gets implemented.
@@ -198,14 +212,17 @@
/obj/item/melee/baton/proc/clowning_around(mob/living/user)
user.visible_message("<span class='danger'>[user] accidentally hits [user.p_them()]self with [src]!</span>", \
"<span class='userdanger'>You accidentally hit yourself with [src]!</span>")
SEND_SIGNAL(user, COMSIG_LIVING_MINOR_SHOCK)
user.Knockdown(stunforce*3)
playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
deductcharge(hitcost)
/obj/item/melee/baton/emp_act(severity)
. = ..()
if (!(. & EMP_PROTECT_SELF))
switch_status(FALSE)
deductcharge(1000 / severity)
if(!iscyborg(loc))
deductcharge(1000 / severity, TRUE, FALSE)
//Makeshift stun baton. Replacement for stun gloves.
/obj/item/melee/baton/cattleprod
@@ -222,14 +239,15 @@
hitcost = 2000
throw_hit_chance = 10
slot_flags = ITEM_SLOT_BACK
var/obj/item/assembly/igniter/sparkler = 0
var/obj/item/assembly/igniter/sparkler
/obj/item/melee/baton/cattleprod/Initialize()
. = ..()
sparkler = new (src)
sparkler.activate_cooldown = 5
/obj/item/melee/baton/cattleprod/baton_stun()
if(sparkler.activate())
..()
sparkler?.activate()
. = ..()
#undef STUNBATON_CHARGE_LENIENCY
#undef STUNBATON_CHARGE_LENIENCY
+239 -238
View File
@@ -1,238 +1,239 @@
/obj/item/tank/jetpack
name = "jetpack (empty)"
desc = "A tank of compressed gas for use as propulsion in zero-gravity areas. Use with caution."
icon_state = "jetpack"
item_state = "jetpack"
lefthand_file = 'icons/mob/inhands/equipment/jetpacks_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/jetpacks_righthand.dmi'
w_class = WEIGHT_CLASS_BULKY
distribute_pressure = ONE_ATMOSPHERE * O2STANDARD
actions_types = list(/datum/action/item_action/set_internals, /datum/action/item_action/toggle_jetpack, /datum/action/item_action/jetpack_stabilization)
var/gas_type = /datum/gas/oxygen
var/on = FALSE
var/stabilizers = FALSE
var/full_speed = TRUE // If the jetpack will have a speedboost in space/nograv or not
var/datum/effect_system/trail_follow/ion/ion_trail
/obj/item/tank/jetpack/New()
..()
if(gas_type)
air_contents.assert_gas(gas_type)
air_contents.gases[gas_type][MOLES] = (6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C)
ion_trail = new
ion_trail.set_up(src)
/obj/item/tank/jetpack/ui_action_click(mob/user, action)
if(istype(action, /datum/action/item_action/toggle_jetpack))
cycle(user)
else if(istype(action, /datum/action/item_action/jetpack_stabilization))
if(on)
stabilizers = !stabilizers
to_chat(user, "<span class='notice'>You turn the jetpack stabilization [stabilizers ? "on" : "off"].</span>")
else
toggle_internals(user)
/obj/item/tank/jetpack/proc/cycle(mob/user)
if(user.incapacitated())
return
if(!on)
turn_on()
to_chat(user, "<span class='notice'>You turn the jetpack on.</span>")
else
turn_off()
to_chat(user, "<span class='notice'>You turn the jetpack off.</span>")
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
/obj/item/tank/jetpack/proc/turn_on()
on = TRUE
icon_state = "[initial(icon_state)]-on"
ion_trail.start()
/obj/item/tank/jetpack/proc/turn_off()
on = FALSE
stabilizers = FALSE
icon_state = initial(icon_state)
ion_trail.stop()
/obj/item/tank/jetpack/proc/allow_thrust(num, mob/living/user)
if(!on)
return
if((num < 0.005 || air_contents.total_moles() < num))
turn_off()
return
var/datum/gas_mixture/removed = air_contents.remove(num)
if(removed.total_moles() < 0.005)
turn_off()
return
var/turf/T = get_turf(user)
T.assume_air(removed)
return 1
/obj/item/tank/jetpack/suicide_act(mob/user)
if (istype(user, /mob/living/carbon/human/))
var/mob/living/carbon/human/H = user
H.forcesay("WHAT THE FUCK IS CARBON DIOXIDE?")
H.visible_message("<span class='suicide'>[user] is suffocating [user.p_them()]self with [src]! It looks like [user.p_they()] didn't read what that jetpack says!</span>")
return (OXYLOSS)
else
..()
/obj/item/tank/jetpack/improvised
name = "improvised jetpack"
desc = "A jetpack made from two air tanks, a fire extinguisher and some atmospherics equipment. It doesn't look like it can hold much."
icon_state = "jetpack-improvised"
item_state = "jetpack-sec"
volume = 30 //normal jetpacks have 70 volume
gas_type = null //it starts empty
full_speed = FALSE //moves at hardsuit jetpack speeds
/obj/item/tank/jetpack/improvised/allow_thrust(num, mob/living/user)
if(!on)
return
if((num < 0.005 || air_contents.total_moles() < num))
turn_off()
return
if(rand(0,250) == 0)
to_chat(user, "<span class='notice'>You feel your jetpack's engines cut out.</span>")
turn_off()
return
var/datum/gas_mixture/removed = air_contents.remove(num)
if(removed.total_moles() < 0.005)
turn_off()
return
var/turf/T = get_turf(user)
T.assume_air(removed)
return 1
/obj/item/tank/jetpack/void
name = "void jetpack (oxygen)"
desc = "It works well in a void."
volume = 60
icon_state = "jetpack-void"
item_state = "jetpack-void"
full_speed = FALSE //Old pre-hardsuit tech
/obj/item/tank/jetpack/oxygen
name = "jetpack (oxygen)"
desc = "A tank of compressed oxygen for use as propulsion in zero-gravity areas. Use with caution."
icon_state = "jetpack"
item_state = "jetpack"
/obj/item/tank/jetpack/oxygen/harness
name = "jet harness (oxygen)"
desc = "A lightweight tactical harness, used by those who don't want to be weighed down by traditional jetpacks."
icon_state = "jetpack-mini"
item_state = "jetpack-mini"
volume = 50
throw_range = 7
w_class = WEIGHT_CLASS_NORMAL
/obj/item/tank/jetpack/oxygen/captain
name = "\improper Captain's jetpack"
desc = "A compact, lightweight jetpack containing a high amount of compressed oxygen."
icon_state = "jetpack-captain"
item_state = "jetpack-captain"
w_class = WEIGHT_CLASS_NORMAL
volume = 90
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF //steal objective items are hard to destroy.
/obj/item/tank/jetpack/oxygen/security
name = "security jetpack (oxygen)"
desc = "A tank of compressed oxygen for use as propulsion in zero-gravity areas by security forces."
icon_state = "jetpack-sec"
item_state = "jetpack-sec"
/obj/item/tank/jetpack/carbondioxide
name = "jetpack (carbon dioxide)"
desc = "A tank of compressed carbon dioxide for use as propulsion in zero-gravity areas. Painted black to indicate that it should not be used as a source for internals."
icon_state = "jetpack-black"
item_state = "jetpack-black"
distribute_pressure = 0
gas_type = /datum/gas/carbon_dioxide
/obj/item/tank/jetpack/suit
name = "hardsuit jetpack upgrade"
desc = "A modular, compact set of thrusters designed to integrate with a hardsuit. It is fueled by a tank inserted into the suit's storage compartment."
icon_state = "jetpack-mining"
item_state = "jetpack-black"
w_class = WEIGHT_CLASS_NORMAL
actions_types = list(/datum/action/item_action/toggle_jetpack, /datum/action/item_action/jetpack_stabilization)
volume = 1
slot_flags = null
gas_type = null
full_speed = FALSE
var/datum/gas_mixture/temp_air_contents
var/obj/item/tank/internals/tank = null
/obj/item/tank/jetpack/suit/New()
..()
STOP_PROCESSING(SSobj, src)
temp_air_contents = air_contents
/obj/item/tank/jetpack/suit/attack_self()
return
/obj/item/tank/jetpack/suit/cycle(mob/user)
if(!istype(loc, /obj/item/clothing/suit/space/hardsuit))
to_chat(user, "<span class='warning'>\The [src] must be connected to a hardsuit!</span>")
return
var/mob/living/carbon/human/H = user
if(!istype(H.s_store, /obj/item/tank/internals))
to_chat(user, "<span class='warning'>You need a tank in your suit storage!</span>")
return
..()
/obj/item/tank/jetpack/suit/turn_on()
if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc))
return
var/mob/living/carbon/human/H = loc.loc
tank = H.s_store
air_contents = tank.air_contents
START_PROCESSING(SSobj, src)
..()
/obj/item/tank/jetpack/suit/turn_off()
tank = null
air_contents = temp_air_contents
STOP_PROCESSING(SSobj, src)
..()
/obj/item/tank/jetpack/suit/process()
if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc))
turn_off()
return
var/mob/living/carbon/human/H = loc.loc
if(!tank || tank != H.s_store)
turn_off()
return
..()
//Return a jetpack that the mob can use
//Back worn jetpacks, hardsuit internal packs, and so on.
//Used in Process_Spacemove() and wherever you want to check for/get a jetpack
/mob/proc/get_jetpack()
return
/mob/living/carbon/get_jetpack()
var/obj/item/tank/jetpack/J = back
if(istype(J))
return J
/mob/living/carbon/human/get_jetpack()
var/obj/item/tank/jetpack/J = ..()
if(!istype(J) && istype(wear_suit, /obj/item/clothing/suit/space/hardsuit))
var/obj/item/clothing/suit/space/hardsuit/C = wear_suit
J = C.jetpack
return J
/obj/item/tank/jetpack
name = "jetpack (empty)"
desc = "A tank of compressed gas for use as propulsion in zero-gravity areas. Use with caution."
icon_state = "jetpack"
item_state = "jetpack"
lefthand_file = 'icons/mob/inhands/equipment/jetpacks_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/jetpacks_righthand.dmi'
w_class = WEIGHT_CLASS_BULKY
distribute_pressure = ONE_ATMOSPHERE * O2STANDARD
actions_types = list(/datum/action/item_action/set_internals, /datum/action/item_action/toggle_jetpack, /datum/action/item_action/jetpack_stabilization)
var/gas_type = /datum/gas/oxygen
var/on = FALSE
var/stabilizers = FALSE
var/full_speed = TRUE // If the jetpack will have a speedboost in space/nograv or not
var/datum/effect_system/trail_follow/ion/ion_trail
/obj/item/tank/jetpack/New()
..()
if(gas_type)
air_contents.gases[gas_type] = (6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C)
ion_trail = new
ion_trail.set_up(src)
/obj/item/tank/jetpack/ui_action_click(mob/user, action)
if(istype(action, /datum/action/item_action/toggle_jetpack))
cycle(user)
else if(istype(action, /datum/action/item_action/jetpack_stabilization))
if(on)
stabilizers = !stabilizers
to_chat(user, "<span class='notice'>You turn the jetpack stabilization [stabilizers ? "on" : "off"].</span>")
else
toggle_internals(user)
/obj/item/tank/jetpack/proc/cycle(mob/user)
if(user.incapacitated())
return
if(!on)
turn_on()
to_chat(user, "<span class='notice'>You turn the jetpack on.</span>")
else
turn_off()
to_chat(user, "<span class='notice'>You turn the jetpack off.</span>")
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
/obj/item/tank/jetpack/proc/turn_on()
on = TRUE
icon_state = "[initial(icon_state)]-on"
ion_trail.start()
/obj/item/tank/jetpack/proc/turn_off()
on = FALSE
stabilizers = FALSE
icon_state = initial(icon_state)
ion_trail.stop()
/obj/item/tank/jetpack/proc/allow_thrust(num, mob/living/user)
if(!on)
return
if((num < 0.005 || air_contents.total_moles() < num))
turn_off()
return
var/datum/gas_mixture/removed = air_contents.remove(num)
if(removed.total_moles() < 0.005)
turn_off()
return
var/turf/T = get_turf(user)
T.assume_air(removed)
return 1
/obj/item/tank/jetpack/suicide_act(mob/user)
if (istype(user, /mob/living/carbon/human/))
var/mob/living/carbon/human/H = user
H.forcesay("WHAT THE FUCK IS CARBON DIOXIDE?")
H.visible_message("<span class='suicide'>[user] is suffocating [user.p_them()]self with [src]! It looks like [user.p_they()] didn't read what that jetpack says!</span>")
return (OXYLOSS)
else
..()
/obj/item/tank/jetpack/improvised
name = "improvised jetpack"
desc = "A jetpack made from two air tanks, a fire extinguisher and some atmospherics equipment. It doesn't look like it can hold much."
icon_state = "jetpack-improvised"
item_state = "jetpack-sec"
volume = 30 //normal jetpacks have 70 volume
gas_type = null //it starts empty
full_speed = FALSE //moves at hardsuit jetpack speeds
/obj/item/tank/jetpack/improvised/allow_thrust(num, mob/living/user)
if(!on)
return
if((num < 0.005 || air_contents.total_moles() < num))
turn_off()
return
if(rand(0,250) == 0)
to_chat(user, "<span class='notice'>You feel your jetpack's engines cut out.</span>")
turn_off()
return
var/datum/gas_mixture/removed = air_contents.remove(num)
if(removed.total_moles() < 0.005)
turn_off()
return
var/turf/T = get_turf(user)
T.assume_air(removed)
return 1
/obj/item/tank/jetpack/void
name = "void jetpack (oxygen)"
desc = "It works well in a void."
volume = 60
icon_state = "jetpack-void"
item_state = "jetpack-void"
full_speed = FALSE //Old pre-hardsuit tech
/obj/item/tank/jetpack/oxygen
name = "jetpack (oxygen)"
desc = "A tank of compressed oxygen for use as propulsion in zero-gravity areas. Use with caution."
icon_state = "jetpack"
item_state = "jetpack"
/obj/item/tank/jetpack/oxygen/harness
name = "jet harness (oxygen)"
desc = "A lightweight tactical harness, used by those who don't want to be weighed down by traditional jetpacks."
icon_state = "jetpack-mini"
item_state = "jetpack-mini"
volume = 50
throw_range = 7
w_class = WEIGHT_CLASS_NORMAL
/obj/item/tank/jetpack/oxygen/captain
name = "\improper Captain's jetpack"
desc = "A compact, lightweight jetpack containing a high amount of compressed oxygen."
icon_state = "jetpack-captain"
item_state = "jetpack-captain"
w_class = WEIGHT_CLASS_NORMAL
volume = 90
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF //steal objective items are hard to destroy.
/obj/item/tank/jetpack/oxygen/security
name = "security jetpack (oxygen)"
desc = "A tank of compressed oxygen for use as propulsion in zero-gravity areas by security forces."
icon_state = "jetpack-sec"
item_state = "jetpack-sec"
full_speed = FALSE
/obj/item/tank/jetpack/carbondioxide
name = "jetpack (carbon dioxide)"
desc = "A tank of compressed carbon dioxide for use as propulsion in zero-gravity areas. Painted black to indicate that it should not be used as a source for internals."
icon_state = "jetpack-black"
item_state = "jetpack-black"
distribute_pressure = 0
gas_type = /datum/gas/carbon_dioxide
/obj/item/tank/jetpack/suit
name = "hardsuit jetpack upgrade"
desc = "A modular, compact set of thrusters designed to integrate with a hardsuit. It is fueled by a tank inserted into the suit's storage compartment."
icon_state = "jetpack-mining"
item_state = "jetpack-black"
w_class = WEIGHT_CLASS_NORMAL
actions_types = list(/datum/action/item_action/toggle_jetpack, /datum/action/item_action/jetpack_stabilization)
volume = 1
slot_flags = null
gas_type = null
full_speed = FALSE
var/datum/gas_mixture/temp_air_contents
var/obj/item/tank/internals/tank = null
/obj/item/tank/jetpack/suit/New()
..()
STOP_PROCESSING(SSobj, src)
temp_air_contents = air_contents
/obj/item/tank/jetpack/suit/attack_self()
return
/obj/item/tank/jetpack/suit/cycle(mob/user)
if(!istype(loc, /obj/item/clothing/suit/space/hardsuit))
to_chat(user, "<span class='warning'>\The [src] must be connected to a hardsuit!</span>")
return
var/mob/living/carbon/human/H = user
if(!istype(H.s_store, /obj/item/tank/internals))
to_chat(user, "<span class='warning'>You need a tank in your suit storage!</span>")
return
..()
/obj/item/tank/jetpack/suit/turn_on()
if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc))
return
var/mob/living/carbon/human/H = loc.loc
tank = H.s_store
air_contents = tank.air_contents
START_PROCESSING(SSobj, src)
..()
/obj/item/tank/jetpack/suit/turn_off()
tank = null
air_contents = temp_air_contents
STOP_PROCESSING(SSobj, src)
..()
/obj/item/tank/jetpack/suit/process()
if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc))
turn_off()
return
var/mob/living/carbon/human/H = loc.loc
if(!tank || tank != H.s_store)
turn_off()
return
..()
//Return a jetpack that the mob can use
//Back worn jetpacks, hardsuit internal packs, and so on.
//Used in Process_Spacemove() and wherever you want to check for/get a jetpack
/mob/proc/get_jetpack()
return
/mob/living/carbon/get_jetpack()
var/obj/item/tank/jetpack/J = back
if(istype(J))
return J
/mob/living/carbon/human/get_jetpack()
var/obj/item/tank/jetpack/J = ..()
if(!istype(J) && istype(wear_suit, /obj/item/clothing/suit/space/hardsuit))
var/obj/item/clothing/suit/space/hardsuit/C = wear_suit
J = C.jetpack
return J
+11 -17
View File
@@ -21,8 +21,7 @@
/obj/item/tank/internals/oxygen/New()
..()
air_contents.assert_gas(/datum/gas/oxygen)
air_contents.gases[/datum/gas/oxygen][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
air_contents.gases[/datum/gas/oxygen] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
return
@@ -49,9 +48,8 @@
/obj/item/tank/internals/anesthetic/New()
..()
air_contents.assert_gases(/datum/gas/oxygen, /datum/gas/nitrous_oxide)
air_contents.gases[/datum/gas/oxygen][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD
air_contents.gases[/datum/gas/nitrous_oxide][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD
air_contents.gases[/datum/gas/oxygen] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD
air_contents.gases[/datum/gas/nitrous_oxide] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD
return
/*
@@ -67,9 +65,8 @@
/obj/item/tank/internals/air/New()
..()
air_contents.assert_gases(/datum/gas/oxygen, /datum/gas/nitrogen)
air_contents.gases[/datum/gas/oxygen][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD
air_contents.gases[/datum/gas/nitrogen][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD
air_contents.gases[/datum/gas/oxygen] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD
air_contents.gases[/datum/gas/nitrogen] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD
return
@@ -87,8 +84,7 @@
/obj/item/tank/internals/plasma/New()
..()
air_contents.assert_gas(/datum/gas/plasma)
air_contents.gases[/datum/gas/plasma][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
air_contents.gases[/datum/gas/plasma] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
return
/obj/item/tank/internals/plasma/attackby(obj/item/W, mob/user, params)
@@ -106,7 +102,7 @@
/obj/item/tank/internals/plasma/full/New()
..() // Plasma asserted in parent
air_contents.gases[/datum/gas/plasma][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
air_contents.gases[/datum/gas/plasma] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
return
@@ -124,13 +120,12 @@
/obj/item/tank/internals/plasmaman/New()
..()
air_contents.assert_gas(/datum/gas/plasma)
air_contents.gases[/datum/gas/plasma][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
air_contents.gases[/datum/gas/plasma] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
return
/obj/item/tank/internals/plasmaman/full/New()
..() // Plasma asserted in parent
air_contents.gases[/datum/gas/plasma][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
air_contents.gases[/datum/gas/plasma] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
return
@@ -144,7 +139,7 @@
/obj/item/tank/internals/plasmaman/belt/full/New()
..() // Plasma asserted in parent
air_contents.gases[/datum/gas/plasma][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
air_contents.gases[/datum/gas/plasma] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
return
@@ -166,8 +161,7 @@
/obj/item/tank/internals/emergency_oxygen/New()
..()
air_contents.assert_gas(/datum/gas/oxygen)
air_contents.gases[/datum/gas/oxygen][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
air_contents.gases[/datum/gas/oxygen] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
return
/obj/item/tank/internals/emergency_oxygen/engi
+1 -1
View File
@@ -128,7 +128,7 @@
H.dropItemToGround(W)
if(prob(50))
step(W, pick(GLOB.alldirs))
H.add_trait(TRAIT_DISFIGURED, TRAIT_GENERIC)
ADD_TRAIT(H, TRAIT_DISFIGURED, TRAIT_GENERIC)
H.bleed_rate = 5
H.gib_animation()
sleep(3)
+2 -3
View File
@@ -18,7 +18,7 @@
/obj/item/watertank/Initialize()
. = ..()
create_reagents(volume)
create_reagents(volume, OPENCONTAINER)
noz = make_noz()
/obj/item/watertank/ui_action_click(mob/user)
@@ -113,7 +113,6 @@
possible_transfer_amounts = list(25,50,100)
volume = 500
item_flags = NOBLUDGEON | ABSTRACT // don't put in storage
container_type = OPENCONTAINER
slot_flags = 0
var/obj/item/watertank/tank
@@ -335,7 +334,7 @@
var/usage_ratio = 5 //5 unit added per 1 removed
var/injection_amount = 1
amount_per_transfer_from_this = 5
container_type = OPENCONTAINER
reagent_flags = OPENCONTAINER
spillable = FALSE
possible_transfer_amounts = list(5,10,15)
+2 -3
View File
@@ -10,15 +10,14 @@
. = ..()
if(!. || !istype(M) || M.anchored)
return
else
SEND_SIGNAL(M, COMSIG_LIVING_MINOR_SHOCK)
do_teleport(M, get_turf(M), 15)
do_teleport(M, get_turf(M), 15)
/obj/item/melee/baton/cattleprod/teleprod/clowning_around(mob/living/user)
user.visible_message("<span class='danger'>[user] accidentally hits [user.p_them()]self with [src]!</span>", \
"<span class='userdanger'>You accidentally hit yourself with [src]!</span>")
SEND_SIGNAL(user, COMSIG_LIVING_MINOR_SHOCK)
user.Knockdown(stunforce*3)
playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
if(do_teleport(user, get_turf(user), 50))
deductcharge(hitcost)
else
+2 -2
View File
@@ -266,10 +266,10 @@
status = !status
if(status)
to_chat(user, "<span class='notice'>You resecure [src] and close the fuel tank.</span>")
container_type = NONE
DISABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER)
else
to_chat(user, "<span class='notice'>[src] can now be attached, modified, and refuelled.</span>")
container_type = OPENCONTAINER
ENABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER)
add_fingerprint(user)
/obj/item/weldingtool/proc/flamethrower_rods(obj/item/I, mob/user)
+1 -1
View File
@@ -350,7 +350,7 @@
unwield()
return
..()
if(user.has_trait(TRAIT_CLUMSY) && (wielded) && prob(40))
if(HAS_TRAIT(user, TRAIT_CLUMSY) && (wielded) && prob(40))
impale(user)
return
if((wielded) && prob(50))
+2 -2
View File
@@ -115,10 +115,10 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
/obj/item/claymore/highlander/pickup(mob/living/user)
to_chat(user, "<span class='notice'>The power of Scotland protects you! You are shielded from all stuns and knockdowns.</span>")
user.add_stun_absorption("highlander", INFINITY, 1, " is protected by the power of Scotland!", "The power of Scotland absorbs the stun!", " is protected by the power of Scotland!")
user.add_trait(TRAIT_IGNORESLOWDOWN, HIGHLANDER)
user.ignore_slowdown(HIGHLANDER)
/obj/item/claymore/highlander/dropped(mob/living/user)
user.remove_trait(TRAIT_IGNORESLOWDOWN, HIGHLANDER)
user.unignore_slowdown(HIGHLANDER)
if(!QDELETED(src))
qdel(src) //If this ever happens, it's because you lost an arm
+1 -1
View File
@@ -71,7 +71,7 @@
adjusted_climb_time *= 2
if(isalien(user))
adjusted_climb_time *= 0.25 //aliens are terrifyingly fast
if(user.has_trait(TRAIT_FREERUNNING)) //do you have any idea how fast I am???
if(HAS_TRAIT(user, TRAIT_FREERUNNING)) //do you have any idea how fast I am???
adjusted_climb_time *= 0.8
structureclimber = user
if(do_mob(user, user, adjusted_climb_time))
@@ -86,7 +86,7 @@
to_chat(user, "<span class='notice'>Alt-click to [locked ? "unlock" : "lock"].</span>")
if(isliving(user))
var/mob/living/L = user
if(L.has_trait(TRAIT_SKITTISH))
if(HAS_TRAIT(L, TRAIT_SKITTISH))
to_chat(user, "<span class='notice'>Ctrl-Shift-click [src] to jump inside.</span>")
/obj/structure/closet/CanPass(atom/movable/mover, turf/target)
@@ -416,7 +416,7 @@
togglelock(user)
/obj/structure/closet/CtrlShiftClick(mob/living/user)
if(!user.has_trait(TRAIT_SKITTISH))
if(!HAS_TRAIT(user, TRAIT_SKITTISH))
return ..()
if(!user.canUseTopic(src) || !isturf(user.loc))
return
@@ -106,6 +106,7 @@
new /obj/item/radio/headset/headset_sec(src)
new /obj/item/clothing/suit/armor/vest/warden(src)
new /obj/item/clothing/head/warden(src)
new /obj/item/clothing/head/warden/drill(src)
new /obj/item/clothing/head/beret/sec/navywarden(src)
new /obj/item/clothing/suit/armor/vest/warden/alt(src)
new /obj/item/clothing/under/rank/warden/navyblue(src)
+6
View File
@@ -101,6 +101,12 @@
icon_state = "festivus_pole"
desc = "During last year's Feats of Strength the Research Director was able to suplex this passing immobile rod into a planter."
/obj/structure/festivus/anchored
name = "suplexed rod"
desc = "A true feat of strength, almost as good as last year."
icon_state = "anchored_rod"
anchored = TRUE
/obj/structure/flora/tree/dead/Initialize()
icon_state = "tree_[rand(1, 6)]"
. = ..()
+1 -2
View File
@@ -5,7 +5,6 @@
icon_state = "cart"
anchored = FALSE
density = TRUE
container_type = OPENCONTAINER
//copypaste sorry
var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite
var/obj/item/storage/bag/trash/mybag = null
@@ -18,7 +17,7 @@
/obj/structure/janitorialcart/Initialize()
. = ..()
create_reagents(100)
create_reagents(100, OPENCONTAINER)
/obj/structure/janitorialcart/proc/wet_mop(obj/item/mop, mob/user)
if(reagents.total_volume < 1)
+10 -12
View File
@@ -24,15 +24,13 @@
if(ishuman(user))
var/mob/living/carbon/human/H = user
var/userloc = H.loc
//see code/modules/mob/dead/new_player/preferences.dm at approx line 545 for comments!
//this is largely copypasted from there.
//handle facial hair (if necessary)
if(H.gender == MALE)
var/new_style = input(user, "Select a facial hair style", "Grooming") as null|anything in GLOB.facial_hair_styles_list
if(userloc != H.loc)
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return //no tele-grooming
if(new_style)
H.facial_hair_style = new_style
@@ -41,7 +39,7 @@
//handle normal hair
var/new_style = input(user, "Select a hair style", "Grooming") as null|anything in GLOB.hair_styles_list
if(userloc != H.loc)
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return //no tele-grooming
if(new_style)
H.hair_style = new_style
@@ -90,9 +88,9 @@
/obj/structure/mirror/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
if(BRUTE)
playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
playsound(src, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
if(BURN)
playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
playsound(src, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
/obj/structure/mirror/magic
@@ -131,7 +129,7 @@
var/choice = input(user, "Something to change?", "Magical Grooming") as null|anything in list("name", "race", "gender", "hair", "eyes")
if(!Adjacent(user))
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
switch(choice)
@@ -140,7 +138,7 @@
if(!newname)
return
if(!Adjacent(user))
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
H.real_name = newname
H.name = newname
@@ -156,7 +154,7 @@
if(!newrace)
return
if(!Adjacent(user))
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
H.set_species(newrace, icon_update=0)
@@ -186,7 +184,7 @@
if("gender")
if(!(H.gender in list("male", "female"))) //blame the patriarchy
return
if(!Adjacent(user))
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
if(H.gender == "male")
if(alert(H, "Become a Witch?", "Confirmation", "Yes", "No") == "Yes")
@@ -207,7 +205,7 @@
if("hair")
var/hairchoice = alert(H, "Hair style or hair color?", "Change Hair", "Style", "Color")
if(!Adjacent(user))
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
if(hairchoice == "Style") //So you just want to use a mirror then?
..()
@@ -225,7 +223,7 @@
if(BODY_ZONE_PRECISE_EYES)
var/new_eye_color = input(H, "Choose your eye color", "Eye Color","#"+H.eye_color) as color|null
if(!Adjacent(user))
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
if(new_eye_color)
H.eye_color = sanitize_hexcolor(new_eye_color)
+1 -2
View File
@@ -4,13 +4,12 @@
icon = 'icons/obj/janitor.dmi'
icon_state = "mopbucket"
density = TRUE
container_type = OPENCONTAINER
var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite
/obj/structure/mopbucket/Initialize()
. = ..()
create_reagents(100)
create_reagents(100, OPENCONTAINER)
/obj/structure/mopbucket/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/mop))
+1 -1
View File
@@ -182,7 +182,7 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an
for(var/mob/living/M in compiled)
var/mob/living/mob_occupant = get_mob_or_brainmob(M)
if(mob_occupant.client && !mob_occupant.suiciding && !(mob_occupant.has_trait(TRAIT_NOCLONE)) && !mob_occupant.hellbound)
if(mob_occupant.client && !mob_occupant.suiciding && !(HAS_TRAIT(mob_occupant, TRAIT_NOCLONE)) && !mob_occupant.hellbound)
icon_state = "morgue4" // Cloneable
if(mob_occupant.stat == DEAD && beeper)
if(world.time > next_beep)
@@ -17,7 +17,7 @@
L.buckled.unbuckle_mob(L,force=1)
L.visible_message("<span class='warning'>[L]'s skin rapidly turns to marble!</span>", "<span class='userdanger'>Your body freezes up! Can't... move... can't... think...</span>")
L.forceMove(src)
L.add_trait(TRAIT_MUTE, STATUE_MUTE)
ADD_TRAIT(L, TRAIT_MUTE, STATUE_MUTE)
L.faction += "mimic" //Stops mimics from instaqdeling people in statues
L.status_flags |= GODMODE
obj_integrity = L.health + 100 //stoning damaged mobs will result in easier to shatter statues
@@ -59,7 +59,7 @@
if(petrified_mob)
petrified_mob.status_flags &= ~GODMODE
petrified_mob.forceMove(loc)
petrified_mob.remove_trait(TRAIT_MUTE, STATUE_MUTE)
REMOVE_TRAIT(petrified_mob, TRAIT_MUTE, STATUE_MUTE)
petrified_mob.take_overall_damage((petrified_mob.health - obj_integrity + 100)) //any new damage the statue incurred is transfered to the mob
petrified_mob.faction -= "mimic"
petrified_mob = null
@@ -152,8 +152,8 @@
pod_moving = 0
if(!QDELETED(pod))
var/datum/gas_mixture/floor_mixture = loc.return_air()
floor_mixture.archive()
pod.air_contents.archive()
ARCHIVE_TEMPERATURE(floor_mixture)
ARCHIVE_TEMPERATURE(pod.air_contents)
pod.air_contents.share(floor_mixture, 1) //mix the pod's gas mixture with the tile it's on
air_update_turf()
@@ -11,9 +11,8 @@
/obj/structure/transit_tube_pod/Initialize()
. = ..()
air_contents.add_gases(/datum/gas/oxygen, /datum/gas/nitrogen)
air_contents.gases[/datum/gas/oxygen][MOLES] = MOLES_O2STANDARD
air_contents.gases[/datum/gas/nitrogen][MOLES] = MOLES_N2STANDARD
air_contents.gases[/datum/gas/oxygen] = MOLES_O2STANDARD
air_contents.gases[/datum/gas/nitrogen] = MOLES_N2STANDARD
air_contents.temperature = T20C