Revert "PLASE"

This reverts commit 8af225e6e3.
This commit is contained in:
Fermi
2019-11-24 02:44:00 +00:00
parent 8af225e6e3
commit 00601a0c87
2145 changed files with 1387321 additions and 5257 deletions
+336
View File
@@ -0,0 +1,336 @@
/obj/structure/sign/barsign // All Signs are 64 by 64 pixels, though most of them are made to fit 64 x 32 and only take the two lowermost tiles.
name = "Bar Sign"
desc = "A bar sign with no writing on it."
icon = 'icons/obj/barsigns.dmi'
icon_state = "empty"
req_access = list(ACCESS_BAR)
max_integrity = 500
integrity_failure = 250
armor = list("melee" = 20, "bullet" = 20, "laser" = 20, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
buildable_sign = 0
var/list/barsigns=list()
var/panel_open = FALSE
/obj/structure/sign/barsign/Initialize()
. = ..()
//filling the barsigns list
for(var/bartype in subtypesof(/datum/barsign))
var/datum/barsign/signinfo = new bartype
if(!signinfo.hidden)
barsigns += signinfo
//randomly assigning a sign
set_sign(pick(barsigns))
/obj/structure/sign/barsign/proc/set_sign(datum/barsign/sign)
if(!istype(sign))
return
icon_state = sign.icon
name = sign.name
if(sign.desc)
desc = sign.desc
else
desc = "It displays \"[name]\"."
/obj/structure/sign/barsign/obj_break(damage_flag)
if(!broken && !(flags_1 & NODECONSTRUCT_1))
broken = TRUE
/obj/structure/sign/barsign/deconstruct(disassembled = TRUE)
new /obj/item/stack/sheet/metal (loc, 2)
new /obj/item/stack/cable_coil (loc, 2)
qdel(src)
/obj/structure/sign/barsign/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
if(BRUTE)
playsound(src.loc, 'sound/effects/glasshit.ogg', 75, 1)
if(BURN)
playsound(src.loc, 'sound/items/welder.ogg', 100, 1)
/obj/structure/sign/barsign/attack_ai(mob/user)
return attack_hand(user)
/obj/structure/sign/barsign/attack_hand(mob/user)
. = ..()
if(.)
return
if(!allowed(user))
to_chat(user, "<span class='info'>Access denied.</span>")
return
if (broken)
to_chat(user, "<span class ='danger'>The controls seem unresponsive.</span>")
return
pick_sign(user)
/obj/structure/sign/barsign/attackby(obj/item/I, mob/user)
if(istype(I, /obj/item/screwdriver))
if(!allowed(user))
to_chat(user, "<span class='info'>Access denied.</span>")
return
if(!panel_open)
to_chat(user, "<span class='notice'>You open the maintenance panel.</span>")
set_sign(new /datum/barsign/hiddensigns/signoff)
panel_open = TRUE
else
to_chat(user, "<span class='notice'>You close the maintenance panel.</span>")
if(!broken && !(obj_flags & EMAGGED))
set_sign(pick(barsigns))
else if(obj_flags & EMAGGED)
set_sign(new /datum/barsign/hiddensigns/syndibarsign)
else
set_sign(new /datum/barsign/hiddensigns/empbarsign)
panel_open = FALSE
else if(istype(I, /obj/item/stack/cable_coil) && panel_open)
var/obj/item/stack/cable_coil/C = I
if(obj_flags & EMAGGED) //Emagged, not broken by EMP
to_chat(user, "<span class='warning'>Sign has been damaged beyond repair!</span>")
return
else if(!broken)
to_chat(user, "<span class='warning'>This sign is functioning properly!</span>")
return
if(C.use(2))
to_chat(user, "<span class='notice'>You replace the burnt wiring.</span>")
broken = FALSE
else
to_chat(user, "<span class='warning'>You need at least two lengths of cable!</span>")
else
return ..()
/obj/structure/sign/barsign/emp_act(severity)
. = ..()
if(. & EMP_PROTECT_SELF)
return
set_sign(new /datum/barsign/hiddensigns/empbarsign)
broken = TRUE
/obj/structure/sign/barsign/emag_act(mob/user)
. = ..()
if(broken || (obj_flags & EMAGGED))
to_chat(user, "<span class='warning'>Nothing interesting happens!</span>")
return
obj_flags |= EMAGGED
to_chat(user, "<span class='notice'>You emag the barsign. Takeover in progress...</span>")
addtimer(CALLBACK(src, .proc/syndie_bar_good), 10 SECONDS)
return TRUE
/obj/structure/sign/barsign/proc/syndie_bar_good()
set_sign(new /datum/barsign/hiddensigns/syndibarsign)
req_access = list(ACCESS_SYNDICATE)
/obj/structure/sign/barsign/proc/pick_sign(mob/user)
var/picked_name = input(user, "Available Signage", "Bar Sign", name) as null|anything in barsigns
if(!picked_name)
return
set_sign(picked_name)
//Code below is to define useless variables for datums. It errors without these
/datum/barsign
var/name = "Name"
var/icon = "Icon"
var/desc = "desc"
var/hidden = FALSE
//Anything below this is where all the specific signs are. If people want to add more signs, add them below.
/datum/barsign/maltesefalcon
name = "Maltese Falcon"
icon = "maltesefalcon"
desc = "The Maltese Falcon, Space Bar and Grill."
/datum/barsign/thebark
name = "The Bark"
icon = "thebark"
desc = "Ian's bar of choice."
/datum/barsign/harmbaton
name = "The Harmbaton"
icon = "theharmbaton"
desc = "A great dining experience for both security members and assistants."
/datum/barsign/thesingulo
name = "The Singulo"
icon = "thesingulo"
desc = "Where people go that'd rather not be called by their name."
/datum/barsign/thedrunkcarp
name = "The Drunk Carp"
icon = "thedrunkcarp"
desc = "Don't drink and swim."
/datum/barsign/scotchservinwill
name = "Scotch Servin Willy's"
icon = "scotchservinwill"
desc = "Willy sure moved up in the world from clown to bartender."
/datum/barsign/officerbeersky
name = "Officer Beersky's"
icon = "officerbeersky"
desc = "Man eat a dong, these drinks are great."
/datum/barsign/thecavern
name = "The Cavern"
icon = "thecavern"
desc = "Fine drinks while listening to some fine tunes."
/datum/barsign/theouterspess
name = "The Outer Spess"
icon = "theouterspess"
desc = "This bar isn't actually located in outer space."
/datum/barsign/slipperyshots
name = "Slippery Shots"
icon = "slipperyshots"
desc = "Slippery slope to drunkeness with our shots!"
/datum/barsign/thegreytide
name = "The Grey Tide"
icon = "thegreytide"
desc = "Abandon your toolboxing ways and enjoy a lazy beer!"
/datum/barsign/honkednloaded
name = "Honked 'n' Loaded"
icon = "honkednloaded"
desc = "Honk."
/datum/barsign/thenest
name = "The Nest"
icon = "thenest"
desc = "A good place to retire for a drink after a long night of crime fighting."
/datum/barsign/thecoderbus
name = "The Coderbus"
icon = "thecoderbus"
desc = "A very controversial bar known for its wide variety of constantly-changing drinks."
/datum/barsign/theadminbus
name = "The Adminbus"
icon = "theadminbus"
desc = "An establishment visited mainly by space-judges. It isn't bombed nearly as much as court hearings."
/datum/barsign/oldcockinn
name = "The Old Cock Inn"
icon = "oldcockinn"
desc = "Something about this sign fills you with despair."
/datum/barsign/thewretchedhive
name = "The Wretched Hive"
icon = "thewretchedhive"
desc = "Legally obligated to instruct you to check your drinks for acid before consumption."
/datum/barsign/robustacafe
name = "The Robusta Cafe"
icon = "robustacafe"
desc = "Holder of the 'Most Lethal Barfights' record 5 years uncontested."
/datum/barsign/emergencyrumparty
name = "The Emergency Rum Party"
icon = "emergencyrumparty"
desc = "Recently relicensed after a long closure."
/datum/barsign/combocafe
name = "The Combo Cafe"
icon = "combocafe"
desc = "Renowned system-wide for their utterly uncreative drink combinations."
/datum/barsign/vladssaladbar
name = "Vlad's Salad Bar"
icon = "vladssaladbar"
desc = "Under new management. Vlad was always a bit too trigger happy with that shotgun."
/datum/barsign/theshaken
name = "The Shaken"
icon = "theshaken"
desc = "This establishment does not serve stirred drinks."
/datum/barsign/thealenath
name = "The Ale' Nath"
icon = "thealenath"
desc = "All right, buddy. I think you've had EI NATH. Time to get a cab."
/datum/barsign/thealohasnackbar
name = "The Aloha Snackbar"
icon = "alohasnackbar"
desc = "A tasteful, inoffensive tiki bar sign."
/datum/barsign/thenet
name = "The Net"
icon = "thenet"
desc = "You just seem to get caught up in it for hours."
/datum/barsign/maidcafe
name = "Maid Cafe"
icon = "maidcafe"
desc = "Welcome back, master!"
/datum/barsign/the_lightbulb
name = "The Lightbulb"
icon = "the_lightbulb"
desc = "A cafe popular among moths and moffs. Once shut down for a week after the bartender used mothballs to protect her spare uniforms."
/datum/barsign/cybersylph
name = "Cyber Sylph's"
icon = "cybersylph"
desc = "A cafe renowed for its out-of-boundaries futuristic insignia."
/datum/barsign/meow_mix
name = "Meow Mix"
icon = "meow_mix"
desc = "No, we don't serve catnip, officer!"
/datum/barsign/hiddensigns
hidden = TRUE
//Hidden signs list below this point
/datum/barsign/hiddensigns/empbarsign
name = "Haywire Barsign"
icon = "empbarsign"
desc = "Something has gone very wrong."
/datum/barsign/hiddensigns/syndibarsign
name = "Syndi Cat Takeover"
icon = "syndibarsign"
desc = "Syndicate or die."
/datum/barsign/hiddensigns/signoff
name = "Bar Sign"
icon = "empty"
desc = "This sign doesn't seem to be on."
@@ -0,0 +1,528 @@
/obj/structure/chair
name = "chair"
desc = "You sit in this. Either by will or force."
icon = 'icons/obj/chairs.dmi'
icon_state = "chair"
anchored = TRUE
can_buckle = 1
buckle_lying = 0 //you sit in a chair, not lay
resistance_flags = NONE
max_integrity = 250
integrity_failure = 25
var/buildstacktype = /obj/item/stack/sheet/metal
var/buildstackamount = 1
var/item_chair = /obj/item/chair // if null it can't be picked up
layer = OBJ_LAYER
/obj/structure/chair/examine(mob/user)
..()
to_chat(user, "<span class='notice'>It's held together by a couple of <b>bolts</b>.</span>")
if(!has_buckled_mobs())
to_chat(user, "<span class='notice'>Drag your sprite to sit in it.</span>")
/obj/structure/chair/Initialize()
. = ..()
if(!anchored) //why would you put these on the shuttle?
addtimer(CALLBACK(src, .proc/RemoveFromLatejoin), 0)
/obj/structure/chair/ComponentInitialize()
. = ..()
AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_CLOCKWISE, CALLBACK(src, .proc/can_user_rotate),CALLBACK(src, .proc/can_be_rotated),null)
/obj/structure/chair/proc/can_be_rotated(mob/user)
return TRUE
/obj/structure/chair/proc/can_user_rotate(mob/user)
var/mob/living/L = user
if(istype(L))
if(!user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return FALSE
else
return TRUE
else if(isobserver(user) && CONFIG_GET(flag/ghost_interaction))
return TRUE
return FALSE
/obj/structure/chair/Destroy()
RemoveFromLatejoin()
return ..()
/obj/structure/chair/proc/RemoveFromLatejoin()
SSjob.latejoin_trackers -= src //These may be here due to the arrivals shuttle
/obj/structure/chair/deconstruct()
// If we have materials, and don't have the NOCONSTRUCT flag
if(buildstacktype && (!(flags_1 & NODECONSTRUCT_1)))
new buildstacktype(loc,buildstackamount)
..()
/obj/structure/chair/attack_paw(mob/user)
return attack_hand(user)
/obj/structure/chair/narsie_act()
var/obj/structure/chair/wood/W = new/obj/structure/chair/wood(get_turf(src))
W.setDir(dir)
qdel(src)
/obj/structure/chair/ratvar_act()
var/obj/structure/chair/brass/B = new(get_turf(src))
B.setDir(dir)
qdel(src)
/obj/structure/chair/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/wrench) && !(flags_1&NODECONSTRUCT_1))
W.play_tool_sound(src)
deconstruct()
else if(istype(W, /obj/item/assembly/shock_kit))
if(!user.temporarilyRemoveItemFromInventory(W))
return
var/obj/item/assembly/shock_kit/SK = W
var/obj/structure/chair/e_chair/E = new /obj/structure/chair/e_chair(src.loc)
playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
E.setDir(dir)
E.part = SK
SK.forceMove(E)
SK.master = E
qdel(src)
else
return ..()
/obj/structure/chair/attack_tk(mob/user)
if(!anchored || has_buckled_mobs() || !isturf(user.loc))
..()
else
setDir(turn(dir,-90))
/obj/structure/chair/proc/handle_rotation(direction)
handle_layer()
if(has_buckled_mobs())
for(var/m in buckled_mobs)
var/mob/living/buckled_mob = m
buckled_mob.setDir(direction)
/obj/structure/chair/proc/handle_layer()
if(has_buckled_mobs() && dir == NORTH)
layer = ABOVE_MOB_LAYER
else
layer = OBJ_LAYER
/obj/structure/chair/post_buckle_mob(mob/living/M)
. = ..()
handle_layer()
/obj/structure/chair/post_unbuckle_mob()
. = ..()
handle_layer()
/obj/structure/chair/setDir(newdir)
..()
handle_rotation(newdir)
// Chair types
/obj/structure/chair/wood
icon_state = "wooden_chair"
name = "wooden chair"
desc = "Old is never too old to not be in fashion."
resistance_flags = FLAMMABLE
max_integrity = 70
buildstacktype = /obj/item/stack/sheet/mineral/wood
buildstackamount = 3
item_chair = /obj/item/chair/wood
/obj/structure/chair/wood/narsie_act()
return
/obj/structure/chair/wood/normal //Kept for map compatibility
/obj/structure/chair/wood/wings
icon_state = "wooden_chair_wings"
item_chair = /obj/item/chair/wood/wings
/obj/structure/chair/comfy
name = "comfy chair"
desc = "It looks comfy."
icon_state = "comfychair"
color = rgb(255,255,255)
resistance_flags = FLAMMABLE
max_integrity = 70
buildstackamount = 2
item_chair = null
var/mutable_appearance/armrest
/obj/structure/chair/comfy/Initialize()
armrest = GetArmrest()
armrest.layer = ABOVE_MOB_LAYER
return ..()
/obj/structure/chair/comfy/proc/GetArmrest()
return mutable_appearance('icons/obj/chairs.dmi', "comfychair_armrest")
/obj/structure/chair/comfy/Destroy()
QDEL_NULL(armrest)
return ..()
/obj/structure/chair/comfy/post_buckle_mob(mob/living/M)
. = ..()
update_armrest()
/obj/structure/chair/comfy/proc/update_armrest()
if(has_buckled_mobs())
add_overlay(armrest)
else
cut_overlay(armrest)
/obj/structure/chair/comfy/post_unbuckle_mob()
. = ..()
update_armrest()
/obj/structure/chair/comfy/brown
color = rgb(255,113,0)
/obj/structure/chair/comfy/beige
color = rgb(255,253,195)
/obj/structure/chair/comfy/teal
color = rgb(0,255,255)
/obj/structure/chair/comfy/black
color = rgb(167,164,153)
/obj/structure/chair/comfy/lime
color = rgb(255,251,0)
/obj/structure/chair/comfy/plywood
name = "plywood chair"
desc = "A relaxing plywood chair."
icon_state = "plywood_chair"
anchored = FALSE
buildstacktype = /obj/item/stack/sheet/mineral/wood
buildstackamount = 4
/obj/structure/chair/comfy/plywood/GetArmrest()
return mutable_appearance('icons/obj/chairs.dmi', "plywood_chair_armrest")
/obj/structure/chair/comfy/shuttle
name = "shuttle seat"
desc = "A comfortable, secure seat. It has a more sturdy looking buckling system, for smoother flights."
icon_state = "shuttle_chair"
/obj/structure/chair/comfy/shuttle/GetArmrest()
return mutable_appearance('icons/obj/chairs.dmi', "shuttle_chair_armrest")
/obj/structure/chair/office
anchored = FALSE
buildstackamount = 5
item_chair = null
/obj/structure/chair/office/Moved()
. = ..()
if(has_gravity())
playsound(src, 'sound/effects/roll.ogg', 100, 1)
/obj/structure/chair/office/light
icon_state = "officechair_white"
/obj/structure/chair/office/dark
icon_state = "officechair_dark"
//Stool
/obj/structure/chair/stool
name = "stool"
desc = "Apply butt."
icon_state = "stool"
can_buckle = 0
buildstackamount = 1
item_chair = /obj/item/chair/stool
/obj/structure/chair/stool/narsie_act()
return
/obj/structure/chair/MouseDrop(over_object, src_location, over_location)
. = ..()
if(over_object == usr && Adjacent(usr))
if(!item_chair || !usr.can_hold_items() || has_buckled_mobs() || src.flags_1 & NODECONSTRUCT_1)
return
if(!usr.canUseTopic(src, BE_CLOSE, ismonkey(usr)))
return
usr.visible_message("<span class='notice'>[usr] grabs \the [src.name].</span>", "<span class='notice'>You grab \the [src.name].</span>")
var/C = new item_chair(loc)
TransferComponents(C)
usr.put_in_hands(C)
qdel(src)
/obj/structure/chair/stool/bar
name = "bar stool"
desc = "It has some unsavory stains on it..."
icon_state = "bar"
item_chair = /obj/item/chair/stool/bar
/obj/item/chair
name = "chair"
desc = "Bar brawl essential."
icon = 'icons/obj/chairs.dmi'
icon_state = "chair_toppled"
item_state = "chair"
lefthand_file = 'icons/mob/inhands/misc/chairs_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/chairs_righthand.dmi'
w_class = WEIGHT_CLASS_HUGE
force = 8
throwforce = 10
throw_range = 3
hitsound = 'sound/items/trayhit1.ogg'
hit_reaction_chance = 50
materials = list(MAT_METAL = 2000)
var/break_chance = 5 //Likely hood of smashing the chair.
var/obj/structure/chair/origin_type = /obj/structure/chair
/obj/item/chair/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] begins hitting [user.p_them()]self with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
playsound(src,hitsound,50,1)
return BRUTELOSS
/obj/item/chair/narsie_act()
var/obj/item/chair/wood/W = new/obj/item/chair/wood(get_turf(src))
W.setDir(dir)
qdel(src)
/obj/item/chair/attack_self(mob/user)
plant(user)
/obj/item/chair/proc/plant(mob/user)
for(var/obj/A in get_turf(loc))
if(istype(A, /obj/structure/chair))
to_chat(user, "<span class='danger'>There is already a chair here.</span>")
return
if(A.density && !(A.flags_1 & ON_BORDER_1))
to_chat(user, "<span class='danger'>There is already something here.</span>")
return
user.visible_message("<span class='notice'>[user] rights \the [src.name].</span>", "<span class='notice'>You right \the [name].</span>")
var/obj/structure/chair/C = new origin_type(get_turf(loc))
TransferComponents(C)
C.setDir(dir)
qdel(src)
/obj/item/chair/proc/smash(mob/living/user)
var/stack_type = initial(origin_type.buildstacktype)
if(!stack_type)
return
var/remaining_mats = initial(origin_type.buildstackamount)
remaining_mats-- //Part of the chair was rendered completely unusable. It magically dissapears. Maybe make some dirt?
if(remaining_mats)
for(var/M=1 to remaining_mats)
new stack_type(get_turf(loc))
qdel(src)
/obj/item/chair/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(attack_type == UNARMED_ATTACK && prob(hit_reaction_chance))
owner.visible_message("<span class='danger'>[owner] fends off [attack_text] with [src]!</span>")
return 1
return 0
/obj/item/chair/afterattack(atom/target, mob/living/carbon/user, proximity)
. = ..()
if(!proximity)
return
if(prob(break_chance))
user.visible_message("<span class='danger'>[user] smashes \the [src] to pieces against \the [target]</span>")
if(iscarbon(target))
var/mob/living/carbon/C = target
if(C.health < C.maxHealth*0.5)
C.Knockdown(20)
smash(user)
/obj/item/chair/stool
name = "stool"
icon_state = "stool_toppled"
item_state = "stool"
origin_type = /obj/structure/chair/stool
break_chance = 0 //It's too sturdy.
/obj/item/chair/stool/bar
name = "bar stool"
icon_state = "bar_toppled"
item_state = "stool_bar"
origin_type = /obj/structure/chair/stool/bar
//////////////////////////
//Brass & Bronze stools!//
//////////////////////////
/obj/structure/chair/stool/bar/brass
name = "brass bar stool"
desc = "A brass bar stool with red silk for a pillow."
icon_state = "barbrass"
item_chair = /obj/item/chair/stool/bar/brass
buildstacktype = /obj/item/stack/tile/brass
buildstackamount = 1
/obj/structure/chair/stool/bar/bronze
name = "bronze bar stool"
desc = "A bronze bar stool with red silk for a pillow."
icon_state = "barbrass"
item_chair = /obj/item/chair/stool/bar/bronze
buildstacktype = /obj/item/stack/tile/bronze
buildstackamount = 1
/obj/structure/chair/stool/brass
name = "brass stool"
desc = "A brass stool with a silk top for comfort."
icon_state = "stoolbrass"
item_chair = /obj/item/chair/stool/brass
buildstacktype = /obj/item/stack/tile/brass
buildstackamount = 1
/obj/structure/chair/stool/bronze
name = "bronze stool"
desc = "A bronze stool with a silk top for comfort."
icon_state = "stoolbrass"
item_chair = /obj/item/chair/stool/bronze
buildstacktype = /obj/item/stack/tile/bronze
buildstackamount = 1
/obj/item/chair/stool/brass
name = "brass stool"
icon_state = "stoolbrass_toppled"
item_state = "stoolbrass"
origin_type = /obj/structure/chair/stool/brass
/obj/item/chair/stool/bar/brass
name = "brass bar stool"
icon_state = "barbrass_toppled"
item_state = "stoolbrass_bar"
origin_type = /obj/structure/chair/stool/bar/brass
/obj/item/chair/stool/bronze
name = "bronze stool"
icon_state = "stoolbrass_toppled"
item_state = "stoolbrass"
origin_type = /obj/structure/chair/stool/bronze
/obj/item/chair/stool/bar/bronze
name = "bronze bar stool"
icon_state = "barbrass_toppled"
item_state = "stoolbrass_bar"
origin_type = /obj/structure/chair/stool/bar/bronze
/////////////////////////////////
//End of Brass & Bronze stools!//
/////////////////////////////////
/obj/item/chair/stool/narsie_act()
return //sturdy enough to ignore a god
/obj/item/chair/wood
name = "wooden chair"
icon_state = "wooden_chair_toppled"
item_state = "woodenchair"
resistance_flags = FLAMMABLE
max_integrity = 70
hitsound = 'sound/weapons/genhit1.ogg'
origin_type = /obj/structure/chair/wood
materials = null
break_chance = 50
/obj/item/chair/wood/narsie_act()
return
/obj/item/chair/wood/wings
icon_state = "wooden_chair_wings_toppled"
origin_type = /obj/structure/chair/wood/wings
/obj/structure/chair/old
name = "strange chair"
desc = "You sit in this. Either by will or force. Looks REALLY uncomfortable."
icon_state = "chairold"
item_chair = null
/obj/structure/chair/brass
name = "brass chair"
desc = "A spinny chair made of brass. It looks uncomfortable."
icon_state = "brass_chair"
max_integrity = 150
buildstacktype = /obj/item/stack/tile/brass
buildstackamount = 1
item_chair = null
var/turns = 0
/obj/structure/chair/brass/Destroy()
STOP_PROCESSING(SSfastprocess, src)
. = ..()
/obj/structure/chair/brass/process()
setDir(turn(dir,-90))
playsound(src, 'sound/effects/servostep.ogg', 50, FALSE)
turns++
if(turns >= 8)
STOP_PROCESSING(SSfastprocess, src)
/obj/structure/chair/brass/ratvar_act()
return
/obj/structure/chair/brass/AltClick(mob/living/user)
turns = 0
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return
if(!(datum_flags & DF_ISPROCESSING))
user.visible_message("<span class='notice'>[user] spins [src] around, and Ratvarian technology keeps it spinning FOREVER.</span>", \
"<span class='notice'>Automated spinny chairs. The pinnacle of Ratvarian technology.</span>")
START_PROCESSING(SSfastprocess, src)
else
user.visible_message("<span class='notice'>[user] stops [src]'s uncontrollable spinning.</span>", \
"<span class='notice'>You grab [src] and stop its wild spinning.</span>")
STOP_PROCESSING(SSfastprocess, src)
/obj/structure/chair/bronze
name = "brass chair"
desc = "A spinny chair made of bronze. It has little cogs for wheels!"
anchored = FALSE
icon_state = "brass_chair"
buildstacktype = /obj/item/stack/tile/bronze
buildstackamount = 1
item_chair = null
/obj/structure/chair/bronze/Moved()
. = ..()
if(has_gravity())
playsound(src, 'sound/machines/clockcult/integration_cog_install.ogg', 50, TRUE)
/obj/structure/chair/sofa
name = "old ratty sofa"
icon_state = "sofamiddle"
icon = 'icons/obj/sofa.dmi'
buildstackamount = 1
var/mutable_appearance/armrest
/obj/structure/chair/sofa/Initialize()
armrest = mutable_appearance(icon, "[icon_state]_armrest")
return ..()
/obj/structure/chair/sofa/post_buckle_mob(mob/living/M)
. = ..()
update_armrest()
/obj/structure/chair/sofa/proc/update_armrest()
if(has_buckled_mobs())
add_overlay(armrest)
else
cut_overlay(armrest)
/obj/structure/chair/sofa/post_unbuckle_mob()
. = ..()
update_armrest()
/obj/structure/chair/sofa/left
icon_state = "sofaend_left"
/obj/structure/chair/sofa/right
icon_state = "sofaend_right"
/obj/structure/chair/sofa/corner
icon_state = "sofacorner"
/obj/structure/chair/sofa/corner/handle_layer() //only the armrest/back of this chair should cover the mob.
return
@@ -0,0 +1,399 @@
/*
CONTAINS:
BEDSHEETS
LINEN BINS
*/
/obj/item/bedsheet
name = "bedsheet"
desc = "A surprisingly soft linen bedsheet."
icon = 'icons/obj/bedsheets.dmi'
icon_state = "sheetwhite"
item_state = "bedsheet"
slot_flags = ITEM_SLOT_NECK
layer = MOB_LAYER
throwforce = 0
throw_speed = 1
throw_range = 2
w_class = WEIGHT_CLASS_TINY
item_color = "white"
resistance_flags = FLAMMABLE
dog_fashion = /datum/dog_fashion/head/ghost
var/list/dream_messages = list("white")
/obj/item/bedsheet/attack(mob/living/M, mob/user)
if(!attempt_initiate_surgery(src, M, user))
..()
/obj/item/bedsheet/attack_self(mob/user)
if(!user.CanReach(src)) //No telekenetic grabbing.
return
if(!user.dropItemToGround(src))
return
if(layer == initial(layer))
layer = ABOVE_MOB_LAYER
to_chat(user, "<span class='notice'>You cover yourself with [src].</span>")
else
layer = initial(layer)
to_chat(user, "<span class='notice'>You smooth [src] out beneath you.</span>")
add_fingerprint(user)
return
/obj/item/bedsheet/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/wirecutters) || I.get_sharpness())
var/obj/item/stack/sheet/cloth/C = new (get_turf(src), 3)
transfer_fingerprints_to(C)
C.add_fingerprint(user)
qdel(src)
to_chat(user, "<span class='notice'>You tear [src] up.</span>")
else
return ..()
/obj/item/bedsheet/blue
icon_state = "sheetblue"
item_color = "blue"
dream_messages = list("blue")
/obj/item/bedsheet/green
icon_state = "sheetgreen"
item_color = "green"
dream_messages = list("green")
/obj/item/bedsheet/grey
icon_state = "sheetgrey"
item_color = "grey"
dream_messages = list("grey")
/obj/item/bedsheet/orange
icon_state = "sheetorange"
item_color = "orange"
dream_messages = list("orange")
/obj/item/bedsheet/purple
icon_state = "sheetpurple"
item_color = "purple"
dream_messages = list("purple")
/obj/item/bedsheet/patriot
name = "patriotic bedsheet"
desc = "You've never felt more free than when sleeping on this."
icon_state = "sheetUSA"
item_color = "sheetUSA"
dream_messages = list("America", "freedom", "fireworks", "bald eagles")
/obj/item/bedsheet/rainbow
name = "rainbow bedsheet"
desc = "A multicolored blanket. It's actually several different sheets cut up and sewn together."
icon_state = "sheetrainbow"
item_color = "rainbow"
dream_messages = list("red", "orange", "yellow", "green", "blue", "purple", "a rainbow")
/obj/item/bedsheet/red
icon_state = "sheetred"
item_color = "red"
dream_messages = list("red")
/obj/item/bedsheet/yellow
icon_state = "sheetyellow"
item_color = "yellow"
dream_messages = list("yellow")
/obj/item/bedsheet/mime
name = "mime's blanket"
desc = "A very soothing striped blanket. All the noise just seems to fade out when you're under the covers in this."
icon_state = "sheetmime"
item_color = "mime"
dream_messages = list("silence", "gestures", "a pale face", "a gaping mouth", "the mime")
/obj/item/bedsheet/clown
name = "clown's blanket"
desc = "A rainbow blanket with a clown mask woven in. It smells faintly of bananas."
icon_state = "sheetclown"
item_color = "clown"
dream_messages = list("honk", "laughter", "a prank", "a joke", "a smiling face", "the clown")
/obj/item/bedsheet/captain
name = "captain's bedsheet"
desc = "It has a Nanotrasen symbol on it, and was woven with a revolutionary new kind of thread guaranteed to have 0.01% permeability for most non-chemical substances, popular among most modern captains."
icon_state = "sheetcaptain"
item_color = "captain"
dream_messages = list("authority", "a golden ID", "sunglasses", "a green disc", "an antique gun", "the captain")
/obj/item/bedsheet/rd
name = "research director's bedsheet"
desc = "It appears to have a beaker emblem, and is made out of fire-resistant material, although it probably won't protect you in the event of fires you're familiar with every day."
icon_state = "sheetrd"
item_color = "director"
dream_messages = list("authority", "a silvery ID", "a bomb", "a mech", "a facehugger", "maniacal laughter", "the research director")
// for Free Golems.
/obj/item/bedsheet/rd/royal_cape
name = "Royal Cape of the Liberator"
desc = "Majestic."
dream_messages = list("mining", "stone", "a golem", "freedom", "doing whatever")
/obj/item/bedsheet/medical
name = "medical blanket"
desc = "It's a sterilized* blanket commonly used in the Medbay. *Sterilization is voided if a virologist is present onboard the station."
icon_state = "sheetmedical"
item_color = "medical"
dream_messages = list("healing", "life", "surgery", "a doctor")
/obj/item/bedsheet/cmo
name = "chief medical officer's bedsheet"
desc = "It's a sterilized blanket that has a cross emblem. There's some cat fur on it, likely from Runtime."
icon_state = "sheetcmo"
item_color = "cmo"
dream_messages = list("authority", "a silvery ID", "healing", "life", "surgery", "a cat", "the chief medical officer")
/obj/item/bedsheet/hos
name = "head of security's bedsheet"
desc = "It is decorated with a shield emblem. While crime doesn't sleep, you do, but you are still THE LAW!"
icon_state = "sheethos"
item_color = "hosred"
dream_messages = list("authority", "a silvery ID", "handcuffs", "a baton", "a flashbang", "sunglasses", "the head of security")
/obj/item/bedsheet/hop
name = "head of personnel's bedsheet"
desc = "It is decorated with a key emblem. For those rare moments when you can rest and cuddle with Ian without someone screaming for you over the radio."
icon_state = "sheethop"
item_color = "hop"
dream_messages = list("authority", "a silvery ID", "obligation", "a computer", "an ID", "a corgi", "the head of personnel")
/obj/item/bedsheet/ce
name = "chief engineer's bedsheet"
desc = "It is decorated with a wrench emblem. It's highly reflective and stain resistant, so you don't need to worry about ruining it with oil."
icon_state = "sheetce"
item_color = "chief"
dream_messages = list("authority", "a silvery ID", "the engine", "power tools", "an APC", "a parrot", "the chief engineer")
/obj/item/bedsheet/qm
name = "quartermaster's bedsheet"
desc = "It is decorated with a crate emblem in silver lining. It's rather tough, and just the thing to lie on after a hard day of pushing paper."
icon_state = "sheetqm"
item_color = "qm"
dream_messages = list("a grey ID", "a shuttle", "a crate", "a sloth", "the quartermaster")
/obj/item/bedsheet/brown
icon_state = "sheetbrown"
item_color = "cargo"
dream_messages = list("brown")
/obj/item/bedsheet/black
icon_state = "sheetblack"
item_color = "black"
dream_messages = list("black")
/obj/item/bedsheet/centcom
name = "\improper CentCom bedsheet"
desc = "Woven with advanced nanothread for warmth as well as being very decorated, essential for all officials."
icon_state = "sheetcentcom"
item_color = "centcom"
dream_messages = list("a unique ID", "authority", "artillery", "an ending")
/obj/item/bedsheet/syndie
name = "syndicate bedsheet"
desc = "It has a syndicate emblem and it has an aura of evil."
icon_state = "sheetsyndie"
item_color = "syndie"
dream_messages = list("a green disc", "a red crystal", "a glowing blade", "a wire-covered ID")
/obj/item/bedsheet/cult
name = "cultist's bedsheet"
desc = "You might dream of Nar'Sie if you sleep with this. It seems rather tattered and glows of an eldritch presence."
icon_state = "sheetcult"
item_color = "cult"
dream_messages = list("a tome", "a floating red crystal", "a glowing sword", "a bloody symbol", "a massive humanoid figure")
/obj/item/bedsheet/wiz
name = "wizard's bedsheet"
desc = "A special fabric enchanted with magic so you can have an enchanted night. It even glows!"
icon_state = "sheetwiz"
item_color = "wiz"
dream_messages = list("a book", "an explosion", "lightning", "a staff", "a skeleton", "a robe", "magic")
/obj/item/bedsheet/nanotrasen
name = "nanotrasen bedsheet"
desc = "It has the Nanotrasen logo on it and has an aura of duty."
icon_state = "sheetNT"
item_color = "nanotrasen"
dream_messages = list("authority", "an ending")
/obj/item/bedsheet/ian
icon_state = "sheetian"
item_color = "ian"
dream_messages = list("a dog", "a corgi", "woof", "bark", "arf")
/obj/item/bedsheet/runtime
icon_state = "sheetruntime"
item_color = "runtime"
dream_messages = list("a kitty", "a cat", "meow", "purr", "nya~")
/obj/item/bedsheet/pirate
name = "pirate's bedsheet"
desc = "It has a Jolly Roger emblem on it and has a faint scent of grog."
icon_state = "sheetpirate"
item_color = "black"
dream_messages = list("doing whatever oneself wants", "cause a pirate is free", "being a pirate", "stealing", "landlubbers", "gold", "a buried treasure", "yarr", "avast", "a swashbuckler", "sailing the Seven Seas", "a parrot", "a monkey", "an island", "a talking skull")
/obj/item/bedsheet/gondola
name = "gondola bedsheet"
desc = "A precious bedsheet made from the hide of a rare and peculiar critter."
icon_state = "sheetgondola"
item_color = "cargo"
var/g_mouth
var/g_eyes
/obj/item/bedsheet/gondola/Initialize()
. = ..()
g_mouth = "sheetgondola_mouth[rand(1, 4)]"
g_eyes = "sheetgondola_eyes[rand(1, 4)]"
add_overlay(g_mouth)
add_overlay(g_eyes)
/obj/item/bedsheet/gondola/worn_overlays(isinhands = FALSE, icon_file)
. = ..()
if(!isinhands)
. += mutable_appearance(icon_file, g_mouth)
. += mutable_appearance(icon_file, g_eyes)
/obj/item/bedsheet/cosmos
name = "cosmic space bedsheet"
desc = "Made from the dreams of those who wonder at the stars."
icon_state = "sheetcosmos"
item_color = "cosmos"
dream_messages = list("the infinite cosmos", "Hans Zimmer music", "a flight through space", "the galaxy", "being fabulous", "shooting stars")
light_power = 2
light_range = 1.4
/obj/item/bedsheet/random
icon_state = "random_bedsheet"
item_color = "rainbow"
name = "random bedsheet"
desc = "If you're reading this description ingame, something has gone wrong! Honk!"
/obj/item/bedsheet/random/Initialize()
..()
var/type = pick(typesof(/obj/item/bedsheet) - /obj/item/bedsheet/random)
new type(loc)
return INITIALIZE_HINT_QDEL
/obj/structure/bedsheetbin
name = "linen bin"
desc = "It looks rather cosy."
icon = 'icons/obj/structures.dmi'
icon_state = "linenbin-full"
anchored = TRUE
resistance_flags = FLAMMABLE
max_integrity = 70
var/amount = 10
var/list/sheet_types = list(/obj/item/bedsheet)
var/static/allowed_sheets = list(/obj/item/bedsheet, /obj/item/reagent_containers/rag/towel)
var/list/sheets = list()
var/obj/item/hidden = null
/obj/structure/bedsheetbin/examine(mob/user)
..()
if(amount < 1)
to_chat(user, "There are no sheets in the bin.")
else if(amount == 1)
to_chat(user, "There is one sheet in the bin.")
else
to_chat(user, "There are [amount] sheets in the bin.")
/obj/structure/bedsheetbin/update_icon()
switch(amount)
if(0)
icon_state = "linenbin-empty"
if(1 to 5)
icon_state = "linenbin-half"
else
icon_state = "linenbin-full"
/obj/structure/bedsheetbin/fire_act(exposed_temperature, exposed_volume)
if(amount)
amount = 0
update_icon()
..()
/obj/structure/bedsheetbin/attackby(obj/item/I, mob/user, params)
if(is_type_in_list(I, allowed_sheets))
if(!user.transferItemToLoc(I, src))
to_chat(user, "<span class='warning'>\The [I] is stuck to your hand, you cannot place it into the bin!</span>")
return
sheets.Add(I)
amount++
to_chat(user, "<span class='notice'>You put [I] in [src].</span>")
update_icon()
else if(amount && !hidden && I.w_class < WEIGHT_CLASS_BULKY) //make sure there's sheets to hide it among, make sure nothing else is hidden in there.
if(!user.transferItemToLoc(I, src))
to_chat(user, "<span class='warning'>\The [I] is stuck to your hand, you cannot hide it among the sheets!</span>")
return
hidden = I
to_chat(user, "<span class='notice'>You hide [I] among the sheets.</span>")
/obj/structure/bedsheetbin/attack_paw(mob/user)
return attack_hand(user)
/obj/structure/bedsheetbin/attack_hand(mob/user)
. = ..()
if(.)
return
if(user.incapacitated())
return
if(amount >= 1)
amount--
var/obj/item/B
if(sheets.len > 0)
B = sheets[sheets.len]
sheets.Remove(B)
else
var/chosen = pick(sheet_types)
B = new chosen
B.forceMove(drop_location())
user.put_in_hands(B)
to_chat(user, "<span class='notice'>You take [B] out of [src].</span>")
update_icon()
if(hidden)
hidden.forceMove(drop_location())
to_chat(user, "<span class='notice'>[hidden] falls out of [B]!</span>")
hidden = null
add_fingerprint(user)
/obj/structure/bedsheetbin/attack_tk(mob/user)
if(amount >= 1)
amount--
var/obj/item/B
if(sheets.len > 0)
B = sheets[sheets.len]
sheets.Remove(B)
else
var/chosen = pick(sheet_types)
B = new chosen
B.forceMove(drop_location())
to_chat(user, "<span class='notice'>You telekinetically remove [B] from [src].</span>")
update_icon()
if(hidden)
hidden.forceMove(drop_location())
hidden = null
/obj/structure/bedsheetbin/towel
desc = "It looks rather cosy. This one is designed to hold towels."
sheet_types = list(/obj/item/reagent_containers/rag/towel)
/obj/structure/bedsheetbin/color
sheet_types = list(/obj/item/bedsheet, /obj/item/bedsheet/blue, /obj/item/bedsheet/green, /obj/item/bedsheet/orange, \
/obj/item/bedsheet/purple, /obj/item/bedsheet/red, /obj/item/bedsheet/yellow, /obj/item/bedsheet/brown, \
/obj/item/bedsheet/black)
@@ -0,0 +1,619 @@
/obj/structure/closet
name = "closet"
desc = "It's a basic storage unit."
icon = 'icons/obj/closet.dmi'
icon_state = "generic"
density = TRUE
var/icon_door = null
var/icon_door_override = FALSE //override to have open overlay use icon different to its base's
var/secure = FALSE //secure locker or not, also used if overriding a non-secure locker with a secure door overlay to add fancy lights
var/opened = FALSE
var/welded = FALSE
var/locked = FALSE
var/large = TRUE
var/wall_mounted = 0 //never solid (You can always pass over it)
max_integrity = 200
integrity_failure = 50
armor = list("melee" = 20, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 60)
var/breakout_time = 1200
var/message_cooldown
var/can_weld_shut = TRUE
var/horizontal = FALSE
var/allow_objects = FALSE
var/allow_dense = FALSE
var/dense_when_open = FALSE //if it's dense when open or not
var/max_mob_size = MOB_SIZE_HUMAN //Biggest mob_size accepted by the container
var/mob_storage_capacity = 3 // how many human sized mob/living can fit together inside a closet.
var/storage_capacity = 30 //This is so that someone can't pack hundreds of items in a locker/crate then open it in a populated area to crash clients.
var/cutting_tool = /obj/item/weldingtool
var/open_sound = 'sound/machines/click.ogg'
var/close_sound = 'sound/machines/click.ogg'
var/material_drop = /obj/item/stack/sheet/metal
var/material_drop_amount = 2
var/delivery_icon = "deliverycloset" //which icon to use when packagewrapped. null to be unwrappable.
var/anchorable = TRUE
var/icon_welded = "welded"
var/obj/item/electronics/airlock/lockerelectronics //Installed electronics
var/lock_in_use = FALSE //Someone is doing some stuff with the lock here, better not proceed further
var/eigen_teleport = FALSE //If the closet leads to Mr Tumnus.
var/obj/structure/closet/eigen_target //Where you go to.
/obj/structure/closet/Initialize(mapload)
. = ..()
update_icon()
PopulateContents()
if(mapload && !opened) // if closed, any item at the crate's loc is put in the contents
addtimer(CALLBACK(src, .proc/take_contents), 0)
if(secure)
lockerelectronics = new(src)
lockerelectronics.accesses = req_access
//USE THIS TO FILL IT, NOT INITIALIZE OR NEW
/obj/structure/closet/proc/PopulateContents()
return
/obj/structure/closet/Destroy()
dump_contents(override = FALSE)
return ..()
/obj/structure/closet/update_icon()
cut_overlays()
if(opened & icon_door_override)
add_overlay("[icon_door]_open")
layer = OBJ_LAYER
return
else if(opened)
add_overlay("[icon_state]_open")
return
if(icon_door)
add_overlay("[icon_door]_door")
else
layer = BELOW_OBJ_LAYER
add_overlay("[icon_state]_door")
if(welded)
add_overlay("welded")
if(!secure)
return
if(broken)
add_overlay("off")
add_overlay("sparking")
else if(locked)
add_overlay("locked")
else
add_overlay("unlocked")
/obj/structure/closet/examine(mob/user)
..()
if(welded)
to_chat(user, "<span class='notice'>It's <b>welded</b> shut.</span>")
if(anchored)
to_chat(user, "<span class='notice'>It is <b>bolted</b> to the ground.</span>")
if(opened)
to_chat(user, "<span class='notice'>The parts are <b>welded</b> together.</span>")
else if(secure && !opened)
else if(broken)
to_chat(user, "<span class='notice'>The lock is <b>screwed</b> in.</span>")
else if(secure)
to_chat(user, "<span class='notice'>Alt-click to [locked ? "unlock" : "lock"].</span>")
if(isliving(user))
var/mob/living/L = user
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)
if(wall_mounted)
return TRUE
return !density
/obj/structure/closet/proc/can_open(mob/living/user)
if(welded || locked)
return FALSE
var/turf/T = get_turf(src)
for(var/mob/living/L in T)
if(L.anchored || horizontal && L.mob_size > MOB_SIZE_TINY && L.density)
if(user)
to_chat(user, "<span class='danger'>There's something large on top of [src], preventing it from opening.</span>" )
return FALSE
return TRUE
/obj/structure/closet/proc/can_close(mob/living/user)
var/turf/T = get_turf(src)
for(var/obj/structure/closet/closet in T)
if(closet != src && !closet.wall_mounted)
return FALSE
for(var/mob/living/L in T)
if(L.anchored || horizontal && L.mob_size > MOB_SIZE_TINY && L.density)
if(user)
to_chat(user, "<span class='danger'>There's something too large in [src], preventing it from closing.</span>")
return FALSE
return TRUE
/obj/structure/closet/proc/can_lock(mob/living/user, var/check_access = TRUE) //set check_access to FALSE if you only need to check if a locker has a functional lock rather than access
if(!secure)
return FALSE
if(broken)
to_chat(user, "<span class='notice'>[src] is broken!</span>")
return FALSE
if(QDELETED(lockerelectronics) && !locked) //We want to be able to unlock it regardless of electronics, but only lockable with electronics
to_chat(user, "<span class='notice'>[src] is missing locker electronics!</span>")
return FALSE
if(!check_access)
return TRUE
if(allowed(user))
return TRUE
to_chat(user, "<span class='notice'>Access denied.</span>")
/obj/structure/closet/proc/togglelock(mob/living/user)
add_fingerprint(user)
if(eigen_target)
return
if(opened)
return
if(!can_lock(user))
return
locked = !locked
user.visible_message("<span class='notice'>[user] [locked ? null : "un"]locks [src].</span>",
"<span class='notice'>You [locked ? null : "un"]lock [src].</span>")
update_icon()
/obj/structure/closet/proc/dump_contents(var/override = TRUE) //Override is for not revealing the locker electronics when you open the locker, for example
var/atom/L = drop_location()
for(var/atom/movable/AM in src)
if(AM == lockerelectronics && override)
continue
AM.forceMove(L)
if(throwing) // you keep some momentum when getting out of a thrown closet
step(AM, dir)
if(throwing)
throwing.finalize(FALSE)
/obj/structure/closet/proc/take_contents()
var/atom/L = drop_location()
for(var/atom/movable/AM in L)
if(AM != src && insert(AM) == -1) // limit reached
break
/obj/structure/closet/proc/open(mob/living/user)
if(opened || !can_open(user))
return
playsound(loc, open_sound, 15, 1, -3)
opened = TRUE
if(!dense_when_open)
density = FALSE
climb_time *= 0.5 //it's faster to climb onto an open thing
dump_contents()
update_icon()
return 1
/obj/structure/closet/proc/insert(atom/movable/AM)
if(contents.len >= storage_capacity)
return -1
if(insertion_allowed(AM))
if(eigen_teleport) // For teleporting people with linked lockers.
do_teleport(AM, get_turf(eigen_target), 0)
if(eigen_target.opened == FALSE)
eigen_target.bust_open()
else
AM.forceMove(src)
return TRUE
else
return FALSE
/obj/structure/closet/proc/insertion_allowed(atom/movable/AM)
if(ismob(AM))
if(!isliving(AM)) //let's not put ghosts or camera mobs inside closets...
return FALSE
var/mob/living/L = AM
if(L.anchored || L.buckled || L.incorporeal_move || L.has_buckled_mobs())
return FALSE
if(L.mob_size > MOB_SIZE_TINY) // Tiny mobs are treated as items.
if(horizontal && L.density)
return FALSE
if(L.mob_size > max_mob_size)
return FALSE
var/mobs_stored = 0
for(var/mob/living/M in contents)
if(++mobs_stored >= mob_storage_capacity)
return FALSE
L.stop_pulling()
else if(istype(AM, /obj/structure/closet))
return FALSE
else if(istype(AM, /obj/effect))
return FALSE
else if(isobj(AM))
if((!allow_dense && AM.density) || AM.anchored || AM.has_buckled_mobs())
return FALSE
if(isitem(AM) && !HAS_TRAIT(AM, TRAIT_NODROP))
return TRUE
else if(!allow_objects && !istype(AM, /obj/effect/dummy/chameleon))
return FALSE
else
return FALSE
return TRUE
/obj/structure/closet/proc/close(mob/living/user)
if(!opened || !can_close(user))
return FALSE
take_contents()
playsound(loc, close_sound, 15, 1, -3)
climb_time = initial(climb_time)
opened = FALSE
density = TRUE
update_icon()
return TRUE
/obj/structure/closet/proc/toggle(mob/living/user)
if(opened)
return close(user)
else
return open(user)
/obj/structure/closet/proc/bust_open()
welded = FALSE //applies to all lockers
locked = FALSE //applies to critter crates and secure lockers only
broken = TRUE //applies to secure lockers only
open()
/obj/structure/closet/proc/handle_lock_addition(mob/user, obj/item/electronics/airlock/E)
add_fingerprint(user)
if(lock_in_use)
to_chat(user, "<span class='notice'>Wait for work on [src] to be done first!</span>")
return
if(secure)
to_chat(user, "<span class='notice'>This locker already has a lock!</span>")
return
if(broken)
to_chat(user, "<span class='notice'><b>Unscrew</b> the broken lock first!</span>")
return
if(!istype(E))
return
user.visible_message("<span class='notice'>[user] begins installing a lock on [src]...</span>","<span class='notice'>You begin installing a lock on [src]...</span>")
lock_in_use = TRUE
playsound(loc, 'sound/items/screwdriver.ogg', 50, 1)
if(!do_after(user, 60, target = src))
lock_in_use = FALSE
return
lock_in_use = FALSE
to_chat(user, "<span class='notice'>You finish the lock on [src]!</span>")
E.forceMove(src)
lockerelectronics = E
req_access = E.accesses
secure = TRUE
update_icon()
return TRUE
/obj/structure/closet/proc/handle_lock_removal(mob/user, obj/item/screwdriver/S)
if(lock_in_use)
to_chat(user, "<span class='notice'>Wait for work on [src] to be done first!</span>")
return
if(locked)
to_chat(user, "<span class='notice'>Unlock it first!</span>")
return
if(!secure)
to_chat(user, "<span class='notice'>[src] doesn't have a lock that you can remove!</span>")
return
if(!istype(S))
return
var/brokenword = broken ? "broken " : null
user.visible_message("<span class='notice'>[user] begins removing the [brokenword]lock on [src]...</span>","<span class='notice'>You begin removing the [brokenword]lock on [src]...</span>")
playsound(loc, S.usesound, 50, 1)
lock_in_use = TRUE
if(!do_after(user, 100 * S.toolspeed, target = src))
lock_in_use = FALSE
return
to_chat(user, "<span class='notice'>You remove the [brokenword]lock from [src]!</span>")
if(!QDELETED(lockerelectronics))
lockerelectronics.add_fingerprint(user)
lockerelectronics.forceMove(user.loc)
lockerelectronics = null
req_access = null
secure = FALSE
broken = FALSE
locked = FALSE
lock_in_use = FALSE
update_icon()
return TRUE
/obj/structure/closet/deconstruct(disassembled = TRUE)
if(ispath(material_drop) && material_drop_amount && !(flags_1 & NODECONSTRUCT_1))
new material_drop(loc, material_drop_amount)
qdel(src)
/obj/structure/closet/obj_break(damage_flag)
if(!broken && !(flags_1 & NODECONSTRUCT_1))
bust_open()
/obj/structure/closet/attackby(obj/item/W, mob/user, params)
if(user in src)
return
if(src.tool_interact(W,user))
return 1 // No afterattack
else
return ..()
/obj/structure/closet/proc/tool_interact(obj/item/W, mob/user)//returns TRUE if attackBy call shouldnt be continued (because tool was used/closet was of wrong type), FALSE if otherwise
. = TRUE
if(opened)
if(istype(W, cutting_tool))
if(istype(W, /obj/item/weldingtool))
if(!W.tool_start_check(user, amount=0))
return
to_chat(user, "<span class='notice'>You begin cutting \the [src] apart...</span>")
if(W.use_tool(src, user, 40, volume=50))
if(eigen_teleport)
to_chat(user, "<span class='notice'>The unstable nature of \the [src] makes it impossible to cut!</span>")
return
if(!opened)
return
user.visible_message("<span class='notice'>[user] slices apart \the [src].</span>",
"<span class='notice'>You cut \the [src] apart with \the [W].</span>",
"<span class='italics'>You hear welding.</span>")
deconstruct(TRUE)
return
else // for example cardboard box is cut with wirecutters
user.visible_message("<span class='notice'>[user] cut apart \the [src].</span>", \
"<span class='notice'>You cut \the [src] apart with \the [W].</span>")
deconstruct(TRUE)
return
if(user.transferItemToLoc(W, drop_location())) // so we put in unlit welder too
return TRUE
else if(istype(W, /obj/item/electronics/airlock))
handle_lock_addition(user, W)
else if(istype(W, /obj/item/screwdriver))
handle_lock_removal(user, W)
else if(istype(W, /obj/item/weldingtool) && can_weld_shut)
if(!W.tool_start_check(user, amount=0))
return
to_chat(user, "<span class='notice'>You begin [welded ? "unwelding":"welding"] \the [src]...</span>")
if(W.use_tool(src, user, 40, volume=50))
if(eigen_teleport)
to_chat(user, "<span class='notice'>The unstable nature of \the [src] makes it impossible to weld!</span>")
return
if(opened)
return
welded = !welded
after_weld(welded)
user.visible_message("<span class='notice'>[user] [welded ? "welds shut" : "unwelds"] \the [src].</span>",
"<span class='notice'>You [welded ? "weld" : "unwelded"] \the [src] with \the [W].</span>",
"<span class='italics'>You hear welding.</span>")
update_icon()
else if(istype(W, /obj/item/wrench) && anchorable)
if(isinspace() && !anchored)
return
setAnchored(!anchored)
W.play_tool_sound(src, 75)
user.visible_message("<span class='notice'>[user] [anchored ? "anchored" : "unanchored"] \the [src] [anchored ? "to" : "from"] the ground.</span>", \
"<span class='notice'>You [anchored ? "anchored" : "unanchored"] \the [src] [anchored ? "to" : "from"] the ground.</span>", \
"<span class='italics'>You hear a ratchet.</span>")
else if(user.a_intent != INTENT_HARM && !(W.item_flags & NOBLUDGEON))
if(W.GetID() || !toggle(user))
togglelock(user)
else
return FALSE
/obj/structure/closet/proc/after_weld(weld_state)
return
/obj/structure/closet/MouseDrop_T(atom/movable/O, mob/living/user)
if(!istype(O) || O.anchored || istype(O, /obj/screen))
return
if(!istype(user) || user.incapacitated() || user.lying)
return
if(!Adjacent(user) || !user.Adjacent(O))
return
if(user == O) //try to climb onto it
return ..()
if(!opened)
return
if(!isturf(O.loc))
return
var/actuallyismob = 0
if(isliving(O))
actuallyismob = 1
else if(!isitem(O))
return
var/turf/T = get_turf(src)
var/list/targets = list(O, src)
add_fingerprint(user)
user.visible_message("<span class='warning'>[user] [actuallyismob ? "tries to ":""]stuff [O] into [src].</span>", \
"<span class='warning'>You [actuallyismob ? "try to ":""]stuff [O] into [src].</span>", \
"<span class='italics'>You hear clanging.</span>")
if(actuallyismob)
if(do_after_mob(user, targets, 40))
user.visible_message("<span class='notice'>[user] stuffs [O] into [src].</span>", \
"<span class='notice'>You stuff [O] into [src].</span>", \
"<span class='italics'>You hear a loud metal bang.</span>")
var/mob/living/L = O
if(!issilicon(L))
L.Knockdown(40)
O.forceMove(T)
close()
else
O.forceMove(T)
return 1
/obj/structure/closet/relaymove(mob/user)
if(user.stat || !isturf(loc) || !isliving(user))
return
if(locked)
if(message_cooldown <= world.time)
message_cooldown = world.time + 50
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
return
container_resist(user)
/obj/structure/closet/attack_hand(mob/user)
. = ..()
if(.)
return
if(user.lying && get_dist(src, user) > 0)
return
if(!toggle(user))
togglelock(user)
/obj/structure/closet/attack_paw(mob/user)
return attack_hand(user)
/obj/structure/closet/attack_robot(mob/user)
if(user.Adjacent(src))
return attack_hand(user)
// tk grab then use on self
/obj/structure/closet/attack_self_tk(mob/user)
return attack_hand(user)
/obj/structure/closet/verb/verb_toggleopen()
set src in oview(1)
set category = "Object"
set name = "Toggle Open"
if(!usr.canmove || usr.stat || usr.restrained())
return
if(iscarbon(usr) || issilicon(usr) || isdrone(usr))
return attack_hand(usr)
else
to_chat(usr, "<span class='warning'>This mob type can't use this verb.</span>")
// Objects that try to exit a locker by stepping were doing so successfully,
// and due to an oversight in turf/Enter() were going through walls. That
// should be independently resolved, but this is also an interesting twist.
/obj/structure/closet/Exit(atom/movable/AM)
open()
if(AM.loc == src)
return 0
return 1
/obj/structure/closet/container_resist(mob/living/user)
if(opened)
return
if(ismovableatom(loc))
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
var/atom/movable/AM = loc
AM.relay_container_resist(user, src)
return
if(!welded && !locked)
open()
return
//okay, so the closet is either welded or locked... resist!!!
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
user.visible_message("<span class='warning'>[src] begins to shake violently!</span>", \
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(breakout_time)].)</span>", \
"<span class='italics'>You hear banging from [src].</span>")
if(do_after(user,(breakout_time), target = src))
if(!user || user.stat != CONSCIOUS || user.loc != src || opened || (!locked && !welded) )
return
//we check after a while whether there is a point of resisting anymore and whether the user is capable of resisting
user.visible_message("<span class='danger'>[user] successfully broke out of [src]!</span>",
"<span class='notice'>You successfully break out of [src]!</span>")
bust_open()
else
if(user.loc == src) //so we don't get the message if we resisted multiple times and succeeded.
to_chat(user, "<span class='warning'>You fail to break out of [src]!</span>")
/obj/structure/closet/AltClick(mob/user)
..()
if(!user.canUseTopic(src, be_close=TRUE) || !isturf(loc))
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
return
togglelock(user)
/obj/structure/closet/CtrlShiftClick(mob/living/user)
if(!HAS_TRAIT(user, TRAIT_SKITTISH))
return ..()
if(!user.canUseTopic(src) || !isturf(user.loc))
return
dive_into(user)
/obj/structure/closet/emag_act(mob/user)
. = ..()
if(!secure || broken)
return
user.visible_message("<span class='warning'>Sparks fly from [src]!</span>",
"<span class='warning'>You scramble [src]'s lock, breaking it open!</span>",
"<span class='italics'>You hear a faint electrical spark.</span>")
playsound(src, "sparks", 50, 1)
broken = TRUE
locked = FALSE
if(!QDELETED(lockerelectronics))
QDEL_NULL(lockerelectronics)
update_icon()
/obj/structure/closet/get_remote_view_fullscreens(mob/user)
if(user.stat == DEAD || !(user.sight & (SEEOBJS|SEEMOBS)))
user.overlay_fullscreen("remote_view", /obj/screen/fullscreen/impaired, 1)
/obj/structure/closet/emp_act(severity)
. = ..()
if(. & EMP_PROTECT_SELF)
return
if (!(. & EMP_PROTECT_CONTENTS))
for(var/obj/O in src)
O.emp_act(severity)
if(!secure || broken)
return ..()
if(prob(50 / severity))
locked = !locked
update_icon()
if(prob(20 / severity) && !opened)
if(!locked)
open()
else
req_access = list()
req_access += pick(get_all_accesses())
if(!QDELETED(lockerelectronics))
lockerelectronics.accesses = req_access
/obj/structure/closet/contents_explosion(severity, target)
for(var/atom/A in contents)
A.ex_act(severity, target)
CHECK_TICK
/obj/structure/closet/singularity_act()
dump_contents()
..()
/obj/structure/closet/AllowDrop()
return TRUE
/obj/structure/closet/return_temperature()
return
/obj/structure/closet/proc/dive_into(mob/living/user)
var/turf/T1 = get_turf(user)
var/turf/T2 = get_turf(src)
if(!opened)
if(locked)
togglelock(user, TRUE)
if(!open(user))
to_chat(user, "<span class='warning'>It won't budge!</span>")
return
step_towards(user, T2)
T1 = get_turf(user)
if(T1 == T2)
user.resting = TRUE //so people can jump into crates without slamming the lid on their head
if(!close(user))
to_chat(user, "<span class='warning'>You can't get [src] to close!</span>")
user.resting = FALSE
return
user.resting = FALSE
togglelock(user)
T1.visible_message("<span class='warning'>[user] dives into [src]!</span>")
/obj/structure/closet/canReachInto(atom/user, atom/target, list/next, view_only, obj/item/tool)
return ..() && opened
@@ -12,9 +12,6 @@
new /obj/item/clothing/under/shorts/blue(src)
new /obj/item/clothing/under/shorts/green(src)
new /obj/item/clothing/under/jabroni(src)
new /obj/item/clothing/under/polychromic/shortpants(src)
new /obj/item/clothing/under/polychromic/shortpants(src)
new /obj/item/clothing/under/polychromic/shortpants(src)
/obj/structure/closet/boxinggloves
@@ -352,7 +352,6 @@
icon_door = "black"
/obj/structure/closet/wardrobe/curator/PopulateContents()
new /obj/item/clothing/accessory/pocketprotector/full(src)
new /obj/item/clothing/head/fedora/curator(src)
new /obj/item/clothing/suit/curator(src)
new /obj/item/clothing/under/rank/curator/treasure_hunter(src)
@@ -11,7 +11,7 @@
new /obj/item/clothing/under/rank/cargo(src)
new /obj/item/clothing/under/rank/cargo/skirt(src)
new /obj/item/clothing/shoes/sneakers/brown(src)
new /obj/item/radio/headset/heads/qm(src)
new /obj/item/radio/headset/headset_cargo(src)
new /obj/item/clothing/suit/fire/firefighter(src)
new /obj/item/clothing/gloves/fingerless(src)
new /obj/item/megaphone/cargo(src)
@@ -23,4 +23,3 @@
new /obj/item/circuitboard/machine/techfab/department/cargo(src)
new /obj/item/storage/photo_album/QM(src)
new /obj/item/circuitboard/machine/ore_silo(src)
new /obj/item/clothing/suit/hooded/wintercoat/qm(src)
@@ -0,0 +1,103 @@
/obj/structure/closet/secure_closet/engineering_chief
name = "\proper chief engineer's locker"
req_access = list(ACCESS_CE)
icon_state = "ce"
/obj/structure/closet/secure_closet/engineering_chief/PopulateContents()
..()
new /obj/item/clothing/neck/cloak/ce(src)
new /obj/item/clothing/head/beret/ce(src)
new /obj/item/clothing/under/rank/chief_engineer(src)
new /obj/item/clothing/under/rank/chief_engineer/skirt(src)
new /obj/item/clothing/head/hardhat/white(src)
new /obj/item/clothing/head/hardhat/weldhat/white(src)
new /obj/item/clothing/gloves/color/yellow(src)
new /obj/item/clothing/shoes/sneakers/brown(src)
new /obj/item/tank/jetpack/suit(src)
new /obj/item/cartridge/ce(src)
new /obj/item/radio/headset/heads/ce(src)
new /obj/item/storage/toolbox/mechanical(src)
new /obj/item/clothing/suit/hazardvest(src)
new /obj/item/megaphone/command(src)
new /obj/item/areaeditor/blueprints(src)
new /obj/item/airlock_painter(src)
new /obj/item/holosign_creator/engineering(src)
new /obj/item/clothing/mask/gas(src)
new /obj/item/multitool(src)
new /obj/item/assembly/flash/handheld(src)
new /obj/item/clothing/glasses/meson/engine(src)
new /obj/item/door_remote/chief_engineer(src)
new /obj/item/pipe_dispenser(src)
new /obj/item/inducer(src)
new /obj/item/circuitboard/machine/techfab/department/engineering(src)
new /obj/item/extinguisher/advanced(src)
new /obj/item/storage/photo_album/CE(src)
new /obj/item/storage/lockbox/medal/engineering(src)
new /obj/item/construction/rcd/loaded/upgraded(src)
/obj/structure/closet/secure_closet/engineering_electrical
name = "electrical supplies locker"
req_access = list(ACCESS_ENGINE_EQUIP)
icon_state = "eng"
icon_door = "eng_elec"
/obj/structure/closet/secure_closet/engineering_electrical/PopulateContents()
..()
new /obj/item/clothing/gloves/color/yellow(src)
new /obj/item/clothing/gloves/color/yellow(src)
new /obj/item/inducer(src)
new /obj/item/inducer(src)
for(var/i in 1 to 3)
new /obj/item/storage/toolbox/electrical(src)
for(var/i in 1 to 3)
new /obj/item/electronics/apc(src)
for(var/i in 1 to 3)
new /obj/item/multitool(src)
/obj/structure/closet/secure_closet/engineering_welding
name = "welding supplies locker"
req_access = list(ACCESS_ENGINE_EQUIP)
icon_state = "eng"
icon_door = "eng_weld"
/obj/structure/closet/secure_closet/engineering_welding/PopulateContents()
..()
for(var/i in 1 to 3)
new /obj/item/clothing/head/welding(src)
for(var/i in 1 to 3)
new /obj/item/weldingtool(src)
/obj/structure/closet/secure_closet/engineering_personal
name = "engineer's locker"
req_access = list(ACCESS_ENGINE_EQUIP)
icon_state = "eng_secure"
/obj/structure/closet/secure_closet/engineering_personal/PopulateContents()
..()
new /obj/item/radio/headset/headset_eng(src)
new /obj/item/storage/toolbox/mechanical(src)
new /obj/item/tank/internals/emergency_oxygen/engi(src)
new /obj/item/holosign_creator/engineering(src)
new /obj/item/clothing/mask/gas(src)
new /obj/item/clothing/glasses/meson/engine(src)
new /obj/item/storage/box/emptysandbags(src)
/obj/structure/closet/secure_closet/atmospherics
name = "\proper atmospheric technician's locker"
req_access = list(ACCESS_ATMOSPHERICS)
icon_state = "atmos"
/obj/structure/closet/secure_closet/atmospherics/PopulateContents()
..()
new /obj/item/radio/headset/headset_eng(src)
new /obj/item/pipe_dispenser(src)
new /obj/item/storage/toolbox/mechanical(src)
new /obj/item/tank/internals/emergency_oxygen/engi(src)
new /obj/item/analyzer(src)
new /obj/item/holosign_creator/atmos(src)
new /obj/item/watertank/atmos(src)
new /obj/item/clothing/suit/fire/atmos(src)
new /obj/item/clothing/head/hardhat/atmos(src)
new /obj/item/clothing/glasses/meson/engine/tray(src)
new /obj/item/extinguisher/advanced(src)
@@ -0,0 +1,106 @@
/obj/structure/closet/secure_closet/freezer
icon_state = "freezer"
var/jones = FALSE
/obj/structure/closet/secure_closet/freezer/Destroy()
recursive_organ_check(src)
..()
/obj/structure/closet/secure_closet/freezer/Initialize()
..()
recursive_organ_check(src)
/obj/structure/closet/secure_closet/freezer/open(mob/living/user)
if(opened || !can_open(user)) //dupe check just so we don't let the organs decay when someone fails to open the locker
return FALSE
recursive_organ_check(src)
return ..()
/obj/structure/closet/secure_closet/freezer/close(mob/living/user)
if(..()) //if we actually closed the locker
recursive_organ_check(src)
/obj/structure/closet/secure_closet/freezer/ex_act()
if(!jones)
jones = TRUE
else
..()
/obj/structure/closet/secure_closet/freezer/kitchen
name = "kitchen Cabinet"
req_access = list(ACCESS_KITCHEN)
/obj/structure/closet/secure_closet/freezer/kitchen/PopulateContents()
..()
for(var/i = 0, i < 3, i++)
new /obj/item/reagent_containers/food/condiment/flour(src)
new /obj/item/reagent_containers/food/condiment/rice(src)
new /obj/item/reagent_containers/food/condiment/sugar(src)
/obj/structure/closet/secure_closet/freezer/kitchen/maintenance
name = "maintenance refrigerator"
desc = "This refrigerator looks quite dusty, is there anything edible still inside?"
req_access = list()
/obj/structure/closet/secure_closet/freezer/kitchen/maintenance/PopulateContents()
..()
for(var/i = 0, i < 5, i++)
new /obj/item/reagent_containers/food/condiment/milk(src)
for(var/i = 0, i < 5, i++)
new /obj/item/reagent_containers/food/condiment/soymilk(src)
for(var/i = 0, i < 2, i++)
new /obj/item/storage/fancy/egg_box(src)
/obj/structure/closet/secure_closet/freezer/kitchen/mining
req_access = list()
/obj/structure/closet/secure_closet/freezer/meat
name = "meat fridge"
/obj/structure/closet/secure_closet/freezer/meat/PopulateContents()
..()
for(var/i = 0, i < 4, i++)
new /obj/item/reagent_containers/food/snacks/meat/slab/monkey(src)
/obj/structure/closet/secure_closet/freezer/meat/open
req_access = null
locked = FALSE
/obj/structure/closet/secure_closet/freezer/fridge
name = "refrigerator"
/obj/structure/closet/secure_closet/freezer/fridge/PopulateContents()
..()
for(var/i = 0, i < 5, i++)
new /obj/item/reagent_containers/food/condiment/milk(src)
for(var/i = 0, i < 5, i++)
new /obj/item/reagent_containers/food/condiment/soymilk(src)
for(var/i = 0, i < 2, i++)
new /obj/item/storage/fancy/egg_box(src)
/obj/structure/closet/secure_closet/freezer/fridge/open
req_access = null
locked = FALSE
/obj/structure/closet/secure_closet/freezer/money
name = "freezer"
desc = "This contains cold hard cash."
req_access = list(ACCESS_VAULT)
/obj/structure/closet/secure_closet/freezer/money/PopulateContents()
..()
for(var/i = 0, i < 3, i++)
new /obj/item/stack/spacecash/c1000(src)
for(var/i = 0, i < 5, i++)
new /obj/item/stack/spacecash/c500(src)
for(var/i = 0, i < 6, i++)
new /obj/item/stack/spacecash/c200(src)
/obj/structure/closet/secure_closet/freezer/cream_pie
name = "cream pie closet"
desc = "Contains pies filled with cream and/or custard, you sickos."
req_access = list(ACCESS_THEATRE)
/obj/structure/closet/secure_closet/freezer/cream_pie/PopulateContents()
..()
new /obj/item/reagent_containers/food/snacks/pie/cream(src)
@@ -71,7 +71,7 @@
new /obj/item/storage/belt/medical(src)
new /obj/item/healthanalyzer/advanced(src)
new /obj/item/assembly/flash/handheld(src)
new /obj/item/storage/hypospraykit/cmo(src)
// new /obj/item/reagent_containers/hypospray/CMO(src) // CITADEL EDIT comments out the hypospray mk I. the MK II kit is modularized
new /obj/item/autosurgeon/cmo(src)
new /obj/item/door_remote/chief_medical_officer(src)
new /obj/item/clothing/neck/petcollar(src)
@@ -81,7 +81,6 @@
new /obj/item/circuitboard/machine/techfab/department/medical(src)
new /obj/item/storage/photo_album/CMO(src)
new /obj/item/storage/lockbox/medal/medical(src)
new /obj/item/clothing/suit/hooded/wintercoat/cmo(src)
/obj/structure/closet/secure_closet/animal
name = "animal control"
@@ -30,4 +30,3 @@
new /obj/item/door_remote/research_director(src)
new /obj/item/circuitboard/machine/techfab/department/science(src)
new /obj/item/storage/photo_album/RD(src)
new /obj/item/clothing/suit/hooded/wintercoat/rd(src)
@@ -61,7 +61,6 @@
new /obj/item/door_remote/civillian(src)
new /obj/item/circuitboard/machine/techfab/department/service(src)
new /obj/item/storage/photo_album/HoP(src)
new /obj/item/clothing/suit/hooded/wintercoat/hop(src)
/obj/structure/closet/secure_closet/hos
name = "\proper head of security's locker"
req_access = list(ACCESS_HOS)
@@ -95,7 +94,6 @@
new /obj/item/pinpointer/nuke(src)
new /obj/item/circuitboard/machine/techfab/department/security(src)
new /obj/item/storage/photo_album/HoS(src)
new /obj/item/clothing/suit/hooded/wintercoat/hos(src)
/obj/structure/closet/secure_closet/warden
name = "\proper warden's locker"
req_access = list(ACCESS_ARMORY)
@@ -0,0 +1,199 @@
/* Utility Closets
* Contains:
* Emergency Closet
* Fire Closet
* Tool Closet
* Radiation Closet
* Bombsuit Closet
* Hydrant
* First Aid
*/
/*
* Emergency Closet
*/
/obj/structure/closet/emcloset
name = "emergency closet"
desc = "It's a storage unit for emergency breath masks and O2 tanks."
icon_state = "emergency"
/obj/structure/closet/emcloset/anchored
anchored = TRUE
/obj/structure/closet/emcloset/PopulateContents()
..()
if (prob(40))
new /obj/item/storage/toolbox/emergency(src)
switch (pickweight(list("small" = 40, "aid" = 25, "tank" = 20, "both" = 10, "nothing" = 5)))
if ("small")
new /obj/item/tank/internals/emergency_oxygen(src)
new /obj/item/tank/internals/emergency_oxygen(src)
new /obj/item/clothing/mask/breath(src)
new /obj/item/clothing/mask/breath(src)
if ("aid")
new /obj/item/tank/internals/emergency_oxygen(src)
new /obj/item/storage/firstaid/o2(src)
new /obj/item/clothing/mask/breath(src)
if ("tank")
new /obj/item/tank/internals/air(src)
new /obj/item/clothing/mask/breath(src)
if ("both")
new /obj/item/tank/internals/emergency_oxygen(src)
new /obj/item/clothing/mask/breath(src)
if ("nothing")
// doot
return
/*
* Fire Closet
*/
/obj/structure/closet/firecloset
name = "fire-safety closet"
desc = "It's a storage unit for fire-fighting supplies."
icon_state = "fire"
/obj/structure/closet/firecloset/PopulateContents()
..()
if (prob(50))
new /obj/item/reagent_containers/hypospray/medipen/firelocker(src)
new /obj/item/clothing/suit/fire/firefighter(src)
new /obj/item/clothing/mask/gas(src)
new /obj/item/tank/internals/oxygen/red(src)
new /obj/item/extinguisher(src)
new /obj/item/clothing/head/hardhat/red(src)
/obj/structure/closet/firecloset/full/PopulateContents()
..()
if (prob(50))
new /obj/item/reagent_containers/hypospray/medipen/firelocker(src)
new /obj/item/clothing/suit/fire/firefighter(src)
new /obj/item/clothing/mask/gas(src)
new /obj/item/flashlight(src)
new /obj/item/tank/internals/oxygen/red(src)
new /obj/item/extinguisher(src)
new /obj/item/clothing/head/hardhat/red(src)
/*
* Tool Closet
*/
/obj/structure/closet/toolcloset
name = "tool closet"
desc = "It's a storage unit for tools."
icon_state = "eng"
icon_door = "eng_tool"
/obj/structure/closet/toolcloset/PopulateContents()
..()
if(prob(40))
new /obj/item/clothing/suit/hazardvest(src)
if(prob(70))
new /obj/item/flashlight(src)
if(prob(70))
new /obj/item/screwdriver(src)
if(prob(70))
new /obj/item/wrench(src)
if(prob(70))
new /obj/item/weldingtool(src)
if(prob(70))
new /obj/item/crowbar(src)
if(prob(70))
new /obj/item/wirecutters(src)
if(prob(70))
new /obj/item/t_scanner(src)
if(prob(20))
new /obj/item/storage/belt/utility(src)
if(prob(30))
new /obj/item/stack/cable_coil/random(src)
if(prob(30))
new /obj/item/stack/cable_coil/random(src)
if(prob(30))
new /obj/item/stack/cable_coil/random(src)
if(prob(20))
new /obj/item/multitool(src)
if(prob(5))
new /obj/item/clothing/gloves/color/yellow(src)
if(prob(40))
new /obj/item/clothing/head/hardhat(src)
/*
* Radiation Closet
*/
/obj/structure/closet/radiation
name = "radiation suit closet"
desc = "It's a storage unit for rad-protective suits."
icon_state = "eng"
icon_door = "eng_rad"
/obj/structure/closet/radiation/PopulateContents()
..()
if(prob(50))
new /obj/item/storage/firstaid/radbgone(src)
new /obj/item/geiger_counter(src)
new /obj/item/clothing/suit/radiation(src)
new /obj/item/clothing/head/radiation(src)
/*
* Bombsuit closet
*/
/obj/structure/closet/bombcloset
name = "\improper EOD closet"
desc = "It's a storage unit for explosion-protective suits."
icon_state = "bomb"
/obj/structure/closet/bombcloset/PopulateContents()
..()
if(prob(70))
new /obj/item/screwdriver(src)
if(prob(50))
new /obj/item/multitool(src)
if(prob(70))
new /obj/item/wirecutters(src)
new /obj/item/clothing/suit/bomb_suit(src)
new /obj/item/clothing/under/color/black(src)
new /obj/item/clothing/shoes/sneakers/black(src)
new /obj/item/clothing/head/bomb_hood(src)
/obj/structure/closet/bombcloset/security/PopulateContents()
..()
if(prob(90))
new /obj/item/screwdriver(src)
if(prob(70))
new /obj/item/multitool(src)
if(prob(90))
new /obj/item/wirecutters(src)
new /obj/item/clothing/suit/bomb_suit/security(src)
new /obj/item/clothing/under/rank/security(src)
new /obj/item/clothing/shoes/jackboots(src)
new /obj/item/clothing/head/bomb_hood/security(src)
/obj/structure/closet/bombcloset/white/PopulateContents()
..()
if(prob(50))
new /obj/item/screwdriver(src)
if(prob(20))
new /obj/item/multitool(src)
if(prob(50))
new /obj/item/wirecutters(src)
new /obj/item/clothing/suit/bomb_suit/white(src)
new /obj/item/clothing/under/color/black(src)
new /obj/item/clothing/shoes/sneakers/black(src)
new /obj/item/clothing/head/bomb_hood/white(src)
/*
* Ammunition
*/
/obj/structure/closet/ammunitionlocker
name = "ammunition locker"
/obj/structure/closet/ammunitionlocker/PopulateContents()
..()
for(var/i in 1 to 8)
new /obj/item/ammo_casing/shotgun/beanbag(src)
@@ -142,21 +142,28 @@
new /obj/item/clothing/suit/jacket(src)
if(prob(40))
new /obj/item/clothing/suit/jacket(src)
new /obj/item/clothing/under/polychromic/jumpsuit(src)
new /obj/item/clothing/under/polychromic/jumpsuit(src)
new /obj/item/clothing/under/polychromic/jumpsuit(src)
new /obj/item/clothing/under/polychromic/shirt(src)
new /obj/item/clothing/under/polychromic/shirt(src)
new /obj/item/clothing/under/polychromic/shirt(src)
new /obj/item/clothing/under/polychromic/kilt(src)
new /obj/item/clothing/under/polychromic/kilt(src)
new /obj/item/clothing/under/polychromic/kilt(src)
new /obj/item/clothing/under/polychromic/skirt(src)
new /obj/item/clothing/under/polychromic/skirt(src)
new /obj/item/clothing/under/polychromic/skirt(src)
new /obj/item/clothing/under/polychromic/shorts(src)
new /obj/item/clothing/under/polychromic/shorts(src)
new /obj/item/clothing/under/polychromic/shorts(src)
new /obj/item/clothing/under/color/white(src)
new /obj/item/clothing/under/skirt/color/white(src)
new /obj/item/clothing/under/color/blue(src)
new /obj/item/clothing/under/skirt/color/blue(src)
new /obj/item/clothing/under/color/yellow(src)
new /obj/item/clothing/under/skirt/color/yellow(src)
new /obj/item/clothing/under/color/green(src)
new /obj/item/clothing/under/skirt/color/green(src)
new /obj/item/clothing/under/color/orange(src)
new /obj/item/clothing/under/skirt/color/orange(src)
new /obj/item/clothing/under/color/pink(src)
new /obj/item/clothing/under/skirt/color/pink(src)
new /obj/item/clothing/under/color/red(src)
new /obj/item/clothing/under/skirt/color/red(src)
new /obj/item/clothing/under/color/darkblue(src)
new /obj/item/clothing/under/skirt/color/darkblue(src)
new /obj/item/clothing/under/color/teal(src)
new /obj/item/clothing/under/skirt/color/teal(src)
new /obj/item/clothing/under/color/lightpurple(src)
new /obj/item/clothing/under/skirt/color/lightpurple(src)
new /obj/item/clothing/under/color/green(src)
new /obj/item/clothing/under/skirt/color/green(src)
new /obj/item/clothing/mask/bandana/red(src)
new /obj/item/clothing/mask/bandana/red(src)
new /obj/item/clothing/mask/bandana/blue(src)
+349
View File
@@ -0,0 +1,349 @@
/*
* False Walls
*/
/obj/structure/falsewall
name = "wall"
desc = "A huge chunk of metal used to separate rooms."
anchored = TRUE
icon = 'icons/turf/walls/wall.dmi'
icon_state = "wall"
layer = CLOSED_TURF_LAYER
density = TRUE
opacity = 1
max_integrity = 100
canSmoothWith = list(
/turf/closed/wall,
/turf/closed/wall/r_wall,
/obj/structure/falsewall,
/obj/structure/falsewall/brass,
/obj/structure/falsewall/reinforced,
/turf/closed/wall/rust,
/turf/closed/wall/r_wall/rust,
/turf/closed/wall/clockwork)
smooth = SMOOTH_TRUE
can_be_unanchored = FALSE
CanAtmosPass = ATMOS_PASS_DENSITY
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
rad_insulation = RAD_MEDIUM_INSULATION
var/mineral = /obj/item/stack/sheet/metal
var/mineral_amount = 2
var/walltype = /turf/closed/wall
var/girder_type = /obj/structure/girder/displaced
var/opening = FALSE
/obj/structure/falsewall/Initialize()
. = ..()
air_update_turf(TRUE)
/obj/structure/falsewall/ratvar_act()
new /obj/structure/falsewall/brass(loc)
qdel(src)
/obj/structure/falsewall/attack_hand(mob/user)
if(opening)
return
. = ..()
if(.)
return
opening = TRUE
update_icon()
if(!density)
var/srcturf = get_turf(src)
for(var/mob/living/obstacle in srcturf) //Stop people from using this as a shield
opening = FALSE
return
addtimer(CALLBACK(src, /obj/structure/falsewall/proc/toggle_open), 5)
/obj/structure/falsewall/proc/toggle_open()
if(!QDELETED(src))
density = !density
set_opacity(density)
opening = FALSE
update_icon()
air_update_turf(TRUE)
/obj/structure/falsewall/update_icon()//Calling icon_update will refresh the smoothwalls if it's closed, otherwise it will make sure the icon is correct if it's open
if(opening)
if(density)
icon_state = "fwall_opening"
smooth = SMOOTH_FALSE
clear_smooth_overlays()
else
icon_state = "fwall_closing"
else
if(density)
icon_state = initial(icon_state)
smooth = SMOOTH_TRUE
queue_smooth(src)
else
icon_state = "fwall_open"
/obj/structure/falsewall/proc/ChangeToWall(delete = 1)
var/turf/T = get_turf(src)
T.PlaceOnTop(walltype)
if(delete)
qdel(src)
return T
/obj/structure/falsewall/attackby(obj/item/W, mob/user, params)
if(opening)
to_chat(user, "<span class='warning'>You must wait until the door has stopped moving!</span>")
return
if(istype(W, /obj/item/screwdriver))
if(density)
var/turf/T = get_turf(src)
if(T.density)
to_chat(user, "<span class='warning'>[src] is blocked!</span>")
return
if(!isfloorturf(T))
to_chat(user, "<span class='warning'>[src] bolts must be tightened on the floor!</span>")
return
user.visible_message("<span class='notice'>[user] tightens some bolts on the wall.</span>", "<span class='notice'>You tighten the bolts on the wall.</span>")
ChangeToWall()
else
to_chat(user, "<span class='warning'>You can't reach, close it first!</span>")
else if(istype(W, /obj/item/weldingtool) || istype(W, /obj/item/gun/energy/plasmacutter))
if(W.use_tool(src, user, 0, volume=50))
dismantle(user, TRUE)
else if(istype(W, /obj/item/pickaxe/drill/jackhammer))
W.play_tool_sound(src)
dismantle(user, TRUE)
else
return ..()
/obj/structure/falsewall/proc/dismantle(mob/user, disassembled=TRUE, obj/item/tool = null)
user.visible_message("[user] dismantles the false wall.", "<span class='notice'>You dismantle the false wall.</span>")
if(tool)
tool.play_tool_sound(src, 100)
else
playsound(src, 'sound/items/welder.ogg', 100, 1)
deconstruct(disassembled)
/obj/structure/falsewall/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
if(disassembled)
new girder_type(loc)
if(mineral_amount)
for(var/i in 1 to mineral_amount)
new mineral(loc)
qdel(src)
/obj/structure/falsewall/get_dumping_location(obj/item/storage/source,mob/user)
return null
/obj/structure/falsewall/examine_status(mob/user) //So you can't detect falsewalls by examine.
to_chat(user, "<span class='notice'>The outer plating is <b>welded</b> firmly in place.</span>")
return null
/*
* False R-Walls
*/
/obj/structure/falsewall/reinforced
name = "reinforced wall"
desc = "A huge chunk of reinforced metal used to separate rooms."
icon = 'icons/turf/walls/reinforced_wall.dmi'
icon_state = "r_wall"
walltype = /turf/closed/wall/r_wall
mineral = /obj/item/stack/sheet/plasteel
/obj/structure/falsewall/reinforced/examine_status(mob/user)
to_chat(user, "<span class='notice'>The outer <b>grille</b> is fully intact.</span>")
return null
/obj/structure/falsewall/reinforced/attackby(obj/item/tool, mob/user)
..()
if(istype(tool, /obj/item/wirecutters))
dismantle(user, TRUE, tool)
/*
* Uranium Falsewalls
*/
/obj/structure/falsewall/uranium
name = "uranium wall"
desc = "A wall with uranium plating. This is probably a bad idea."
icon = 'icons/turf/walls/uranium_wall.dmi'
icon_state = "uranium"
mineral = /obj/item/stack/sheet/mineral/uranium
walltype = /turf/closed/wall/mineral/uranium
var/active = null
var/last_event = 0
canSmoothWith = list(/obj/structure/falsewall/uranium, /turf/closed/wall/mineral/uranium)
/obj/structure/falsewall/uranium/attackby(obj/item/W, mob/user, params)
radiate()
return ..()
/obj/structure/falsewall/uranium/attack_hand(mob/user)
radiate()
. = ..()
/obj/structure/falsewall/uranium/proc/radiate()
if(!active)
if(world.time > last_event+15)
active = 1
radiation_pulse(src, 150)
for(var/turf/closed/wall/mineral/uranium/T in orange(1,src))
T.radiate()
last_event = world.time
active = null
return
return
/*
* Other misc falsewall types
*/
/obj/structure/falsewall/gold
name = "gold wall"
desc = "A wall with gold plating. Swag!"
icon = 'icons/turf/walls/gold_wall.dmi'
icon_state = "gold"
mineral = /obj/item/stack/sheet/mineral/gold
walltype = /turf/closed/wall/mineral/gold
canSmoothWith = list(/obj/structure/falsewall/gold, /turf/closed/wall/mineral/gold)
/obj/structure/falsewall/silver
name = "silver wall"
desc = "A wall with silver plating. Shiny."
icon = 'icons/turf/walls/silver_wall.dmi'
icon_state = "silver"
mineral = /obj/item/stack/sheet/mineral/silver
walltype = /turf/closed/wall/mineral/silver
canSmoothWith = list(/obj/structure/falsewall/silver, /turf/closed/wall/mineral/silver)
/obj/structure/falsewall/diamond
name = "diamond wall"
desc = "A wall with diamond plating. You monster."
icon = 'icons/turf/walls/diamond_wall.dmi'
icon_state = "diamond"
mineral = /obj/item/stack/sheet/mineral/diamond
walltype = /turf/closed/wall/mineral/diamond
canSmoothWith = list(/obj/structure/falsewall/diamond, /turf/closed/wall/mineral/diamond)
max_integrity = 800
/obj/structure/falsewall/plasma
name = "plasma wall"
desc = "A wall with plasma plating. This is definitely a bad idea."
icon = 'icons/turf/walls/plasma_wall.dmi'
icon_state = "plasma"
mineral = /obj/item/stack/sheet/mineral/plasma
walltype = /turf/closed/wall/mineral/plasma
canSmoothWith = list(/obj/structure/falsewall/plasma, /turf/closed/wall/mineral/plasma)
/obj/structure/falsewall/plasma/attackby(obj/item/W, mob/user, params)
if(W.get_temperature() > 300)
var/turf/T = get_turf(src)
message_admins("Plasma falsewall ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_VERBOSEJMP(T)]")
log_game("Plasma falsewall ignited by [key_name(user)] in [AREACOORD(T)]")
burnbabyburn()
else
return ..()
/obj/structure/falsewall/plasma/proc/burnbabyburn(user)
playsound(src, 'sound/items/welder.ogg', 100, 1)
atmos_spawn_air("plasma=400;TEMP=1000")
new /obj/structure/girder/displaced(loc)
qdel(src)
/obj/structure/falsewall/plasma/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300)
burnbabyburn()
/obj/structure/falsewall/bananium
name = "bananium wall"
desc = "A wall with bananium plating. Honk!"
icon = 'icons/turf/walls/bananium_wall.dmi'
icon_state = "bananium"
mineral = /obj/item/stack/sheet/mineral/bananium
walltype = /turf/closed/wall/mineral/bananium
canSmoothWith = list(/obj/structure/falsewall/bananium, /turf/closed/wall/mineral/bananium)
/obj/structure/falsewall/sandstone
name = "sandstone wall"
desc = "A wall with sandstone plating. Rough."
icon = 'icons/turf/walls/sandstone_wall.dmi'
icon_state = "sandstone"
mineral = /obj/item/stack/sheet/mineral/sandstone
walltype = /turf/closed/wall/mineral/sandstone
canSmoothWith = list(/obj/structure/falsewall/sandstone, /turf/closed/wall/mineral/sandstone)
/obj/structure/falsewall/wood
name = "wooden wall"
desc = "A wall with wooden plating. Stiff."
icon = 'icons/turf/walls/wood_wall.dmi'
icon_state = "wood"
mineral = /obj/item/stack/sheet/mineral/wood
walltype = /turf/closed/wall/mineral/wood
canSmoothWith = list(/obj/structure/falsewall/wood, /turf/closed/wall/mineral/wood)
/obj/structure/falsewall/iron
name = "rough metal wall"
desc = "A wall with rough metal plating."
icon = 'icons/turf/walls/iron_wall.dmi'
icon_state = "iron"
mineral = /obj/item/stack/rods
mineral_amount = 5
walltype = /turf/closed/wall/mineral/iron
canSmoothWith = list(/obj/structure/falsewall/iron, /turf/closed/wall/mineral/iron)
/obj/structure/falsewall/abductor
name = "alien wall"
desc = "A wall with alien alloy plating."
icon = 'icons/turf/walls/abductor_wall.dmi'
icon_state = "abductor"
mineral = /obj/item/stack/sheet/mineral/abductor
walltype = /turf/closed/wall/mineral/abductor
canSmoothWith = list(/obj/structure/falsewall/abductor, /turf/closed/wall/mineral/abductor)
/obj/structure/falsewall/titanium
name = "wall"
desc = "A light-weight titanium wall used in shuttles."
icon = 'icons/turf/walls/shuttle_wall.dmi'
icon_state = "shuttle"
mineral = /obj/item/stack/sheet/mineral/titanium
walltype = /turf/closed/wall/mineral/titanium
smooth = SMOOTH_MORE
canSmoothWith = list(/turf/closed/wall/mineral/titanium, /obj/machinery/door/airlock/shuttle, /obj/machinery/door/airlock, /obj/structure/window/shuttle, /obj/structure/shuttle/engine/heater)
/obj/structure/falsewall/plastitanium
name = "wall"
desc = "An evil wall of plasma and titanium."
icon = 'icons/turf/walls/plastitanium_wall.dmi'
icon_state = "shuttle"
mineral = /obj/item/stack/sheet/mineral/plastitanium
walltype = /turf/closed/wall/mineral/plastitanium
smooth = SMOOTH_MORE
canSmoothWith = list(/turf/closed/wall/mineral/plastitanium, /obj/machinery/door/airlock/shuttle, /obj/machinery/door/airlock, /obj/structure/window/shuttle, /obj/structure/shuttle/engine/heater)
/obj/structure/falsewall/brass
name = "clockwork wall"
desc = "A huge chunk of warm metal. The clanging of machinery emanates from within."
icon = 'icons/turf/walls/clockwork_wall.dmi'
icon_state = "clockwork_wall"
resistance_flags = FIRE_PROOF | ACID_PROOF
mineral_amount = 1
canSmoothWith = list(/obj/effect/clockwork/overlay/wall, /obj/structure/falsewall/brass)
girder_type = /obj/structure/destructible/clockwork/wall_gear/displaced
walltype = /turf/closed/wall/clockwork
mineral = /obj/item/stack/tile/brass
/obj/structure/falsewall/brass/New(loc)
..()
var/turf/T = get_turf(src)
new /obj/effect/temp_visual/ratvar/wall/false(T)
new /obj/effect/temp_visual/ratvar/beam/falsewall(T)
change_construction_value(4)
/obj/structure/falsewall/brass/Destroy()
change_construction_value(-4)
return ..()
/obj/structure/falsewall/brass/ratvar_act()
if(GLOB.ratvar_awakens)
obj_integrity = max_integrity
+427
View File
@@ -0,0 +1,427 @@
/obj/structure/flora
resistance_flags = FLAMMABLE
max_integrity = 150
anchored = TRUE
//trees
/obj/structure/flora/tree
name = "tree"
desc = "A large tree."
density = TRUE
pixel_x = -16
layer = FLY_LAYER
var/log_amount = 10
/obj/structure/flora/tree/attackby(obj/item/W, mob/user, params)
if(log_amount && (!(flags_1 & NODECONSTRUCT_1)))
if(W.sharpness && W.force > 0)
if(W.hitsound)
playsound(get_turf(src), W.hitsound, 100, 0, 0)
user.visible_message("<span class='notice'>[user] begins to cut down [src] with [W].</span>","<span class='notice'>You begin to cut down [src] with [W].</span>", "You hear the sound of sawing.")
if(do_after(user, 1000/W.force, target = src)) //5 seconds with 20 force, 8 seconds with a hatchet, 20 seconds with a shard.
user.visible_message("<span class='notice'>[user] fells [src] with the [W].</span>","<span class='notice'>You fell [src] with the [W].</span>", "You hear the sound of a tree falling.")
playsound(get_turf(src), 'sound/effects/meteorimpact.ogg', 100 , 0, 0)
for(var/i=1 to log_amount)
new /obj/item/grown/log/tree(get_turf(src))
var/obj/structure/flora/stump/S = new(loc)
S.name = "[name] stump"
qdel(src)
else
return ..()
/obj/structure/flora/stump
name = "stump"
desc = "This represents our promise to the crew, and the station itself, to cut down as many trees as possible." //running naked through the trees
icon = 'icons/obj/flora/pinetrees.dmi'
icon_state = "tree_stump"
density = FALSE
pixel_x = -16
/obj/structure/flora/tree/pine
name = "pine tree"
desc = "A coniferous pine tree."
icon = 'icons/obj/flora/pinetrees.dmi'
icon_state = "pine_1"
var/list/icon_states = list("pine_1", "pine_2", "pine_3")
/obj/structure/flora/tree/pine/Initialize()
. = ..()
if(islist(icon_states && icon_states.len))
icon_state = pick(icon_states)
/obj/structure/flora/tree/pine/xmas
name = "xmas tree"
desc = "A wondrous decorated Christmas tree."
icon_state = "pine_c"
icon_states = null
/obj/structure/flora/tree/pine/xmas/presents
icon_state = "pinepresents"
desc = "A wondrous decorated Christmas tree. It has presents!"
var/gift_type = /obj/item/a_gift/anything
var/list/ckeys_that_took = list()
/obj/structure/flora/tree/pine/xmas/presents/attack_hand(mob/living/user)
. = ..()
if(.)
return
if(!user.ckey)
return
if(ckeys_that_took[user.ckey])
to_chat(user, "<span class='warning'>There are no presents with your name on.</span>")
return
to_chat(user, "<span class='warning'>After a bit of rummaging, you locate a gift with your name on it!</span>")
ckeys_that_took[user.ckey] = TRUE
var/obj/item/G = new gift_type(src)
user.put_in_hands(G)
/obj/structure/flora/tree/dead
icon = 'icons/obj/flora/deadtrees.dmi'
desc = "A dead tree. How it died, you know not."
icon_state = "tree_1"
/obj/structure/flora/tree/palm
icon = 'icons/misc/beach2.dmi'
desc = "A tree straight from the tropics."
icon_state = "palm1"
/obj/structure/flora/tree/palm/Initialize()
. = ..()
icon_state = pick("palm1","palm2")
pixel_x = 0
/obj/structure/festivus
name = "festivus pole"
icon = 'icons/obj/flora/pinetrees.dmi'
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)]"
. = ..()
/obj/structure/flora/tree/jungle
name = "tree"
icon_state = "tree"
desc = "It's seriously hampering your view of the jungle."
icon = 'icons/obj/flora/jungletrees.dmi'
pixel_x = -48
pixel_y = -20
/obj/structure/flora/tree/jungle/Initialize()
icon_state = "[icon_state][rand(1, 6)]"
. = ..()
/obj/structure/flora/tree/jungle/small
pixel_y = 0
pixel_x = -32
icon = 'icons/obj/flora/jungletreesmall.dmi'
//grass
/obj/structure/flora/grass
name = "grass"
desc = "A patch of overgrown grass."
icon = 'icons/obj/flora/snowflora.dmi'
gender = PLURAL //"this is grass" not "this is a grass"
/obj/structure/flora/grass/brown
icon_state = "snowgrass1bb"
/obj/structure/flora/grass/brown/Initialize()
icon_state = "snowgrass[rand(1, 3)]bb"
. = ..()
/obj/structure/flora/grass/green
icon_state = "snowgrass1gb"
/obj/structure/flora/grass/green/Initialize()
icon_state = "snowgrass[rand(1, 3)]gb"
. = ..()
/obj/structure/flora/grass/both
icon_state = "snowgrassall1"
/obj/structure/flora/grass/both/Initialize()
icon_state = "snowgrassall[rand(1, 3)]"
. = ..()
//bushes
/obj/structure/flora/bush
name = "bush"
desc = "Some type of shrub."
icon = 'icons/obj/flora/snowflora.dmi'
icon_state = "snowbush1"
anchored = TRUE
/obj/structure/flora/bush/Initialize()
icon_state = "snowbush[rand(1, 6)]"
. = ..()
//newbushes
/obj/structure/flora/ausbushes
name = "bush"
desc = "Some kind of plant."
icon = 'icons/obj/flora/ausflora.dmi'
icon_state = "firstbush_1"
/obj/structure/flora/ausbushes/Initialize()
if(icon_state == "firstbush_1")
icon_state = "firstbush_[rand(1, 4)]"
. = ..()
/obj/structure/flora/ausbushes/reedbush
icon_state = "reedbush_1"
/obj/structure/flora/ausbushes/reedbush/Initialize()
icon_state = "reedbush_[rand(1, 4)]"
. = ..()
/obj/structure/flora/ausbushes/leafybush
icon_state = "leafybush_1"
/obj/structure/flora/ausbushes/leafybush/Initialize()
icon_state = "leafybush_[rand(1, 3)]"
. = ..()
/obj/structure/flora/ausbushes/palebush
icon_state = "palebush_1"
/obj/structure/flora/ausbushes/palebush/Initialize()
icon_state = "palebush_[rand(1, 4)]"
. = ..()
/obj/structure/flora/ausbushes/stalkybush
icon_state = "stalkybush_1"
/obj/structure/flora/ausbushes/stalkybush/Initialize()
icon_state = "stalkybush_[rand(1, 3)]"
. = ..()
/obj/structure/flora/ausbushes/grassybush
icon_state = "grassybush_1"
/obj/structure/flora/ausbushes/grassybush/Initialize()
icon_state = "grassybush_[rand(1, 4)]"
. = ..()
/obj/structure/flora/ausbushes/fernybush
icon_state = "fernybush_1"
/obj/structure/flora/ausbushes/fernybush/Initialize()
icon_state = "fernybush_[rand(1, 3)]"
. = ..()
/obj/structure/flora/ausbushes/sunnybush
icon_state = "sunnybush_1"
/obj/structure/flora/ausbushes/sunnybush/Initialize()
icon_state = "sunnybush_[rand(1, 3)]"
. = ..()
/obj/structure/flora/ausbushes/genericbush
icon_state = "genericbush_1"
/obj/structure/flora/ausbushes/genericbush/Initialize()
icon_state = "genericbush_[rand(1, 4)]"
. = ..()
/obj/structure/flora/ausbushes/pointybush
icon_state = "pointybush_1"
/obj/structure/flora/ausbushes/pointybush/Initialize()
icon_state = "pointybush_[rand(1, 4)]"
. = ..()
/obj/structure/flora/ausbushes/lavendergrass
icon_state = "lavendergrass_1"
/obj/structure/flora/ausbushes/lavendergrass/Initialize()
icon_state = "lavendergrass_[rand(1, 4)]"
. = ..()
/obj/structure/flora/ausbushes/ywflowers
icon_state = "ywflowers_1"
/obj/structure/flora/ausbushes/ywflowers/Initialize()
icon_state = "ywflowers_[rand(1, 3)]"
. = ..()
/obj/structure/flora/ausbushes/brflowers
icon_state = "brflowers_1"
/obj/structure/flora/ausbushes/brflowers/Initialize()
icon_state = "brflowers_[rand(1, 3)]"
. = ..()
/obj/structure/flora/ausbushes/ppflowers
icon_state = "ppflowers_1"
/obj/structure/flora/ausbushes/ppflowers/Initialize()
icon_state = "ppflowers_[rand(1, 3)]"
. = ..()
/obj/structure/flora/ausbushes/sparsegrass
icon_state = "sparsegrass_1"
/obj/structure/flora/ausbushes/sparsegrass/Initialize()
icon_state = "sparsegrass_[rand(1, 3)]"
. = ..()
/obj/structure/flora/ausbushes/fullgrass
icon_state = "fullgrass_1"
/obj/structure/flora/ausbushes/fullgrass/Initialize()
icon_state = "fullgrass_[rand(1, 3)]"
. = ..()
/obj/item/twohanded/required/kirbyplants
name = "potted plant"
icon = 'icons/obj/flora/plants.dmi'
icon_state = "plant-01"
desc = "A little bit of nature contained in a pot."
layer = ABOVE_MOB_LAYER
w_class = WEIGHT_CLASS_HUGE
force = 10
throwforce = 13
throw_speed = 2
throw_range = 4
/obj/item/twohanded/required/kirbyplants/Initialize()
. = ..()
AddComponent(/datum/component/tactical)
/obj/item/twohanded/required/kirbyplants/random
icon = 'icons/obj/flora/_flora.dmi'
icon_state = "random_plant"
var/list/static/states
/obj/item/twohanded/required/kirbyplants/random/Initialize()
. = ..()
icon = 'icons/obj/flora/plants.dmi'
if(!states)
generate_states()
icon_state = pick(states)
/obj/item/twohanded/required/kirbyplants/random/proc/generate_states()
states = list()
for(var/i in 1 to 25)
var/number
if(i < 10)
number = "0[i]"
else
number = "[i]"
states += "plant-[number]"
states += "applebush"
/obj/item/twohanded/required/kirbyplants/dead
name = "RD's potted plant"
desc = "A gift from the botanical staff, presented after the RD's reassignment. There's a tag on it that says \"Y'all come back now, y'hear?\"\nIt doesn't look very healthy..."
icon_state = "plant-25"
/obj/item/twohanded/required/kirbyplants/photosynthetic
name = "photosynthetic potted plant"
desc = "A bioluminescent plant."
icon_state = "plant-09"
light_color = "#2cb2e8"
light_range = 3
//a rock is flora according to where the icon file is
//and now these defines
/obj/structure/flora/rock
icon_state = "basalt"
desc = "A volcanic rock. Pioneers used to ride these babies for miles."
icon = 'icons/obj/flora/rocks.dmi'
resistance_flags = FIRE_PROOF
density = TRUE
/obj/structure/flora/rock/Initialize()
. = ..()
icon_state = "[icon_state][rand(1,3)]"
/obj/structure/flora/rock/pile
icon_state = "lavarocks"
desc = "A pile of rocks."
//Jungle grass
/obj/structure/flora/grass/jungle
name = "jungle grass"
desc = "Thick alien flora."
icon = 'icons/obj/flora/jungleflora.dmi'
icon_state = "grassa"
/obj/structure/flora/grass/jungle/Initialize()
icon_state = "[icon_state][rand(1, 5)]"
. = ..()
/obj/structure/flora/grass/jungle/b
icon_state = "grassb"
//Jungle rocks
/obj/structure/flora/rock/jungle
icon_state = "pile of rocks"
desc = "A pile of rocks."
icon_state = "rock"
icon = 'icons/obj/flora/jungleflora.dmi'
density = FALSE
/obj/structure/flora/rock/jungle/Initialize()
. = ..()
icon_state = "[initial(icon_state)][rand(1,5)]"
//Jungle bushes
/obj/structure/flora/junglebush
name = "bush"
desc = "A wild plant that is found in jungles."
icon = 'icons/obj/flora/jungleflora.dmi'
icon_state = "busha"
/obj/structure/flora/junglebush/Initialize()
icon_state = "[icon_state][rand(1, 3)]"
. = ..()
/obj/structure/flora/junglebush/b
icon_state = "bushb"
/obj/structure/flora/junglebush/c
icon_state = "bushc"
/obj/structure/flora/junglebush/large
icon_state = "bush"
icon = 'icons/obj/flora/largejungleflora.dmi'
pixel_x = -16
pixel_y = -12
layer = ABOVE_ALL_MOB_LAYER
/obj/structure/flora/rock/pile/largejungle
name = "rocks"
icon_state = "rocks"
icon = 'icons/obj/flora/largejungleflora.dmi'
density = FALSE
pixel_x = -16
pixel_y = -16
/obj/structure/flora/rock/pile/largejungle/Initialize()
. = ..()
icon_state = "[initial(icon_state)][rand(1,3)]"
+240
View File
@@ -0,0 +1,240 @@
//Fluff structures serve no purpose and exist only for enriching the environment. They can be destroyed with a wrench.
/obj/structure/fluff
name = "fluff structure"
desc = "Fluffier than a sheep. This shouldn't exist."
icon = 'icons/obj/stationobjs.dmi'
icon_state = "minibar"
anchored = TRUE
density = FALSE
opacity = 0
var/deconstructible = TRUE
/obj/structure/fluff/attackby(obj/item/I, mob/living/user, params)
if(istype(I, /obj/item/wrench) && deconstructible)
user.visible_message("<span class='notice'>[user] starts disassembling [src]...</span>", "<span class='notice'>You start disassembling [src]...</span>")
I.play_tool_sound(src)
if(I.use_tool(src, user, 50))
user.visible_message("<span class='notice'>[user] disassembles [src]!</span>", "<span class='notice'>You break down [src] into scrap metal.</span>")
playsound(user, 'sound/items/deconstruct.ogg', 50, 1)
new/obj/item/stack/sheet/metal(drop_location())
qdel(src)
return
..()
/obj/structure/fluff/empty_terrarium //Empty terrariums are created when a preserved terrarium in a lavaland seed vault is activated.
name = "empty terrarium"
desc = "An ancient machine that seems to be used for storing plant matter. Its hatch is ajar."
icon = 'icons/obj/lavaland/spawners.dmi'
icon_state = "terrarium_open"
density = TRUE
/obj/structure/fluff/empty_sleeper //Empty sleepers are created by a good few ghost roles in lavaland.
name = "empty sleeper"
desc = "An open sleeper. It looks as though it would be awaiting another patient, were it not broken."
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper-open"
/obj/structure/fluff/empty_sleeper/nanotrasen
name = "broken hypersleep chamber"
desc = "A Nanotrasen hypersleep chamber - this one appears broken. \
There are exposed bolts for easy disassembly using a wrench."
icon_state = "sleeper-o"
/obj/structure/fluff/empty_sleeper/syndicate
icon_state = "sleeper_s-open"
/obj/structure/fluff/empty_cryostasis_sleeper //Empty cryostasis sleepers are created when a malfunctioning cryostasis sleeper in a lavaland shelter is activated
name = "empty cryostasis sleeper"
desc = "Although comfortable, this sleeper won't function as anything but a bed ever again."
icon = 'icons/obj/lavaland/spawners.dmi'
icon_state = "cryostasis_sleeper_open"
/obj/structure/fluff/broken_flooring
name = "broken tiling"
desc = "A segment of broken flooring."
icon = 'icons/obj/brokentiling.dmi'
icon_state = "corner"
/obj/structure/fluff/drake_statue //Ash drake status spawn on either side of the necropolis gate in lavaland.
name = "drake statue"
desc = "A towering basalt sculpture of a proud and regal drake. Its eyes are six glowing gemstones."
icon = 'icons/effects/64x64.dmi'
icon_state = "drake_statue"
pixel_x = -16
density = TRUE
deconstructible = FALSE
layer = EDGED_TURF_LAYER
/obj/structure/fluff/drake_statue/falling //A variety of statue in disrepair; parts are broken off and a gemstone is missing
desc = "A towering basalt sculpture of a drake. Cracks run down its surface and parts of it have fallen off."
icon_state = "drake_statue_falling"
/obj/structure/fluff/lightpost
name = "lightpost"
desc = "A homely lightpost adorned with festive decor."
icon = 'icons/obj/2x2.dmi'
icon_state = "lightpost"
deconstructible = FALSE
layer = EDGED_TURF_LAYER
/obj/structure/fluff/bus
name = "bus"
desc = "GO TO SCHOOL. READ A BOOK."
icon = 'icons/obj/bus.dmi'
density = TRUE
anchored = TRUE
deconstructible = FALSE
/obj/structure/fluff/bus/dense
name = "bus"
icon_state = "backwall"
/obj/structure/fluff/bus/passable
name = "bus"
icon_state = "frontwalltop"
density = FALSE
layer = ABOVE_ALL_MOB_LAYER //except for the stairs tile, which should be set to OBJ_LAYER aka 3.
/obj/structure/fluff/bus/passable/seat
name = "seat"
desc = "Buckle up! ...What do you mean, there's no seatbelts?!"
icon_state = "backseat"
pixel_y = 17
layer = OBJ_LAYER
/obj/structure/fluff/bus/passable/seat/driver
name = "driver's seat"
desc = "Space Jesus is my copilot."
icon_state = "driverseat"
/obj/structure/fluff/bus/passable/seat/driver/attack_hand(mob/user)
playsound(src, 'sound/items/carhorn.ogg', 50, 1)
. = ..()
/obj/structure/fluff/paper
name = "dense lining of papers"
desc = "A lining of paper scattered across the bottom of a wall."
icon = 'icons/obj/fluff.dmi'
icon_state = "paper"
deconstructible = FALSE
/obj/structure/fluff/paper/corner
icon_state = "papercorner"
/obj/structure/fluff/paper/stack
name = "dense stack of papers"
desc = "A stack of various papers, childish scribbles scattered across each page."
icon_state = "paperstack"
/obj/structure/fluff/divine
name = "Miracle"
icon = 'icons/obj/hand_of_god_structures.dmi'
anchored = TRUE
density = TRUE
/obj/structure/fluff/divine/nexus
name = "nexus"
desc = "It anchors a deity to this world. It radiates an unusual aura. It looks well protected from explosive shock."
icon_state = "nexus"
/obj/structure/fluff/divine/conduit
name = "conduit"
desc = "It allows a deity to extend their reach. Their powers are just as potent near a conduit as a nexus."
icon_state = "conduit"
/obj/structure/fluff/divine/convertaltar
name = "conversion altar"
desc = "An altar dedicated to a deity."
icon_state = "convertaltar"
density = FALSE
can_buckle = 1
/obj/structure/fluff/divine/powerpylon
name = "power pylon"
desc = "A pylon which increases the deity's rate it can influence the world."
icon_state = "powerpylon"
can_buckle = 1
/obj/structure/fluff/divine/defensepylon
name = "defense pylon"
desc = "A pylon which is blessed to withstand many blows, and fire strong bolts at nonbelievers. A god can toggle it."
icon_state = "defensepylon"
/obj/structure/fluff/divine/shrine
name = "shrine"
desc = "A shrine dedicated to a deity."
icon_state = "shrine"
/obj/structure/fluff/fokoff_sign
name = "crude sign"
desc = "A crudely-made sign with the words 'fok of' written in some sort of red paint."
icon = 'icons/obj/fluff.dmi'
icon_state = "fokof"
/obj/structure/fluff/snowlegion
name = "snowlegion"
desc = "Looks like that weird kid with the tiger plushie has been round here again."
icon = 'icons/obj/fluff.dmi'
icon_state = "snowlegion"
anchored = TRUE
deconstructible = FALSE
/obj/structure/fluff/big_chain
name = "giant chain"
desc = "A towering link of chains leading up to the ceiling."
icon = 'icons/effects/32x96.dmi'
icon_state = "chain"
layer = ABOVE_OBJ_LAYER
anchored = TRUE
density = TRUE
deconstructible = FALSE
/obj/structure/fluff/railing
name = "railing"
desc = "Basic railing meant to protect idiots like you from falling."
icon = 'icons/obj/fluff.dmi'
icon_state = "railing"
density = TRUE
anchored = TRUE
deconstructible = FALSE
/obj/structure/fluff/railing/corner
icon_state = "railing_corner"
density = FALSE
/obj/structure/fluff/beach_towel
name = "beach towel"
desc = "A towel decorated in various beach-themed designs."
icon = 'icons/obj/fluff.dmi'
icon_state = "railing"
density = FALSE
anchored = TRUE
deconstructible = FALSE
/obj/structure/fluff/beach_umbrella
name = "beach umbrella"
desc = "A fancy umbrella designed to keep the sun off beach-goers."
icon = 'icons/obj/fluff.dmi'
icon_state = "brella"
density = FALSE
anchored = TRUE
deconstructible = FALSE
/obj/structure/fluff/beach_umbrella/security
icon_state = "hos_brella"
/obj/structure/fluff/beach_umbrella/science
icon_state = "rd_brella"
/obj/structure/fluff/beach_umbrella/engine
icon_state = "ce_brella"
/obj/structure/fluff/beach_umbrella/cap
icon_state = "cap_brella"
/obj/structure/fluff/beach_umbrella/syndi
icon_state = "syndi_brella"
@@ -0,0 +1,593 @@
//Objects that spawn ghosts in as a certain role when they click on it, i.e. away mission bartenders.
//Preserved terrarium/seed vault: Spawns in seed vault structures in lavaland. Ghosts become plantpeople and are advised to begin growing plants in the room near them.
/obj/effect/mob_spawn/human/seed_vault
name = "preserved terrarium"
desc = "An ancient machine that seems to be used for storing plant matter. The glass is obstructed by a mat of vines."
mob_name = "a lifebringer"
job_description = "Lifebringer"
icon = 'icons/obj/lavaland/spawners.dmi'
icon_state = "terrarium"
density = TRUE
roundstart = FALSE
death = FALSE
mob_species = /datum/species/pod
flavour_text = "<span class='big bold'>You are a sentient ecosystem,</span><b> an example of the mastery over life that your creators possessed. Your masters, benevolent as they were, created uncounted \
seed vaults and spread them across the universe to every planet they could chart. You are in one such seed vault. Your goal is to cultivate and spread life wherever it will go while waiting \
for contact from your creators. Estimated time of last contact: Deployment, 5x10^3 millennia ago.</b>"
assignedrole = "Lifebringer"
/obj/effect/mob_spawn/human/seed_vault/special(mob/living/new_spawn)
var/plant_name = pick("Tomato", "Potato", "Broccoli", "Carrot", "Ambrosia", "Pumpkin", "Ivy", "Kudzu", "Banana", "Moss", "Flower", "Bloom", "Root", "Bark", "Glowshroom", "Petal", "Leaf", \
"Venus", "Sprout","Cocoa", "Strawberry", "Citrus", "Oak", "Cactus", "Pepper", "Juniper")
new_spawn.real_name = plant_name
if(ishuman(new_spawn))
var/mob/living/carbon/human/H = new_spawn
H.underwear = "Nude" //You're a plant, partner
H.update_body()
/obj/effect/mob_spawn/human/seed_vault/Destroy()
new/obj/structure/fluff/empty_terrarium(get_turf(src))
return ..()
//Ash walker eggs: Spawns in ash walker dens in lavaland. Ghosts become unbreathing lizards that worship the Necropolis and are advised to retrieve corpses to create more ash walkers.
/obj/effect/mob_spawn/human/ash_walker
name = "ash walker egg"
desc = "A man-sized yellow egg, spawned from some unfathomable creature. A humanoid silhouette lurks within."
mob_name = "an ash walker"
job_description = "Ashwalker"
icon = 'icons/mob/lavaland/lavaland_monsters.dmi'
icon_state = "large_egg"
mob_species = /datum/species/lizard/ashwalker
outfit = /datum/outfit/ashwalker
roundstart = FALSE
death = FALSE
anchored = FALSE
density = FALSE
flavour_text = "<span class='big bold'>You are an ash walker.</span><b> Your tribe worships <span class='danger'>the Necropolis</span>. The wastes are sacred ground, its monsters a blessed bounty. You would never leave its beautiful expanse. \
You have seen lights in the distance... they foreshadow the arrival of outsiders that seek to tear apart the Necropolis and its domain. Fresh sacrifices for your nest.</b>"
assignedrole = "Ash Walker"
/obj/effect/mob_spawn/human/ash_walker/special(mob/living/new_spawn)
new_spawn.real_name = random_unique_lizard_name(gender)
to_chat(new_spawn, "<b>Drag the corpses of men and beasts to your nest. It will absorb them to create more of your kind. Glory to the Necropolis!</b>")
new_spawn.grant_language(/datum/language/draconic)
var/datum/language_holder/holder = new_spawn.get_language_holder()
holder.selected_default_language = /datum/language/draconic
if(ishuman(new_spawn))
var/mob/living/carbon/human/H = new_spawn
H.underwear = "Nude"
H.update_body()
/obj/effect/mob_spawn/human/ash_walker/Initialize(mapload)
. = ..()
var/area/A = get_area(src)
if(A)
notify_ghosts("An ash walker egg is ready to hatch in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_ASHWALKER, ignore_dnr_observers = TRUE)
/datum/outfit/ashwalker
name ="Ashwalker"
head = /obj/item/clothing/head/helmet/gladiator
uniform = /obj/item/clothing/under/gladiator/ash_walker
//Timeless prisons: Spawns in Wish Granter prisons in lavaland. Ghosts become age-old users of the Wish Granter and are advised to seek repentance for their past.
/obj/effect/mob_spawn/human/exile
name = "timeless prison"
desc = "Although this stasis pod looks medicinal, it seems as though it's meant to preserve something for a very long time."
mob_name = "a penitent exile"
job_description = "Exiled Prisoner"
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
roundstart = FALSE
death = FALSE
mob_species = /datum/species/shadow
flavour_text = "<span class='big bold'>You are cursed.</span><b> Years ago, you sacrificed the lives of your trusted friends and the humanity of yourself to reach the Wish Granter. Though you \
did so, it has come at a cost: your very body rejects the light, dooming you to wander endlessly in this horrible wasteland.</b>"
assignedrole = "Exile"
/obj/effect/mob_spawn/human/exile/Destroy()
new/obj/structure/fluff/empty_sleeper(get_turf(src))
return ..()
/obj/effect/mob_spawn/human/exile/special(mob/living/new_spawn)
new_spawn.real_name = "Wish Granter's Victim ([rand(1,999)])"
var/wish = rand(1,4)
switch(wish)
if(1)
to_chat(new_spawn, "<b>You wished to kill, and kill you did. You've lost track of how many, but the spark of excitement that murder once held has winked out. You feel only regret.</b>")
if(2)
to_chat(new_spawn, "<b>You wished for unending wealth, but no amount of money was worth this existence. Maybe charity might redeem your soul?</b>")
if(3)
to_chat(new_spawn, "<b>You wished for power. Little good it did you, cast out of the light. You are the [gender == MALE ? "king" : "queen"] of a hell that holds no subjects. You feel only remorse.</b>")
if(4)
to_chat(new_spawn, "<b>You wished for immortality, even as your friends lay dying behind you. No matter how many times you cast yourself into the lava, you awaken in this room again within a few days. There is no escape.</b>")
//Golem shells: Spawns in Free Golem ships in lavaland. Ghosts become mineral golems and are advised to spread personal freedom.
/obj/effect/mob_spawn/human/golem
name = "inert free golem shell"
desc = "A humanoid shape, empty, lifeless, and full of potential."
mob_name = "a free golem"
job_description = "Free Golem"
icon = 'icons/obj/wizard.dmi'
icon_state = "construct"
mob_species = /datum/species/golem
roundstart = FALSE
death = FALSE
anchored = FALSE
density = FALSE
var/has_owner = FALSE
var/can_transfer = TRUE //if golems can switch bodies to this new shell
var/mob/living/owner = null //golem's owner if it has one
flavour_text = "<span class='big bold'>You are a Free Golem.</span><b> Your family worships <span class='danger'>The Liberator</span>. In his infinite and divine wisdom, he set your clan free to \
travel the stars with a single declaration: \"Yeah go do whatever.\" Though you are bound to the one who created you, it is customary in your society to repeat those same words to newborn \
golems, so that no golem may ever be forced to serve again.</b>"
/obj/effect/mob_spawn/human/golem/Initialize(mapload, datum/species/golem/species = null, mob/creator = null)
if(species) //spawners list uses object name to register so this goes before ..()
name += " ([initial(species.prefix)])"
mob_species = species
. = ..()
var/area/A = get_area(src)
if(!mapload && A)
notify_ghosts("\A [initial(species.prefix)] golem shell has been completed in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_GOLEM, ignore_dnr_observers = TRUE)
if(has_owner && creator)
flavour_text = "<span class='big bold'>You are a Golem.</span><b> You move slowly, but are highly resistant to heat and cold as well as blunt trauma. You are unable to wear clothes, but can still use most tools. \
Serve [creator], and assist [creator.p_them()] in completing [creator.p_their()] goals at any cost.</b>"
owner = creator
/obj/effect/mob_spawn/human/golem/special(mob/living/new_spawn, name)
var/datum/species/golem/X = mob_species
to_chat(new_spawn, "[initial(X.info_text)]")
if(!owner)
to_chat(new_spawn, "Build golem shells in the autolathe, and feed refined mineral sheets to the shells to bring them to life! You are generally a peaceful group unless provoked.")
else
new_spawn.mind.store_memory("<b>Serve [owner.real_name], your creator.</b>")
new_spawn.mind.enslave_mind_to_creator(owner)
log_game("[key_name(new_spawn)] possessed a golem shell enslaved to [key_name(owner)].")
log_admin("[key_name(new_spawn)] possessed a golem shell enslaved to [key_name(owner)].")
if(ishuman(new_spawn))
var/mob/living/carbon/human/H = new_spawn
H.set_cloned_appearance()
if(!name)
if(has_owner)
H.real_name = "[initial(X.prefix)] Golem ([rand(1,999)])"
else
H.real_name = H.dna.species.random_name()
else
H.real_name = name
if(has_owner)
new_spawn.mind.assigned_role = "Servant Golem"
else
new_spawn.mind.assigned_role = "Free Golem"
/obj/effect/mob_spawn/human/golem/attack_hand(mob/user)
. = ..()
if(.)
return
if(isgolem(user) && can_transfer)
var/transfer_choice = alert("Transfer your soul to [src]? (Warning, your old body will die!)",,"Yes","No")
if(transfer_choice != "Yes")
return
if(QDELETED(src) || uses <= 0)
return
log_game("[key_name(user)] golem-swapped into [src]")
user.visible_message("<span class='notice'>A faint light leaves [user], moving to [src] and animating it!</span>","<span class='notice'>You leave your old body behind, and transfer into [src]!</span>")
show_flavour = FALSE
create(ckey = user.ckey,name = user.real_name)
user.death()
return
/obj/effect/mob_spawn/human/golem/servant
has_owner = TRUE
name = "inert servant golem shell"
job_description = "Servant Golem"
/obj/effect/mob_spawn/human/golem/adamantine
name = "dust-caked free golem shell"
desc = "A humanoid shape, empty, lifeless, and full of potential."
mob_name = "a free golem"
can_transfer = FALSE
mob_species = /datum/species/golem/adamantine
//Malfunctioning cryostasis sleepers: Spawns in makeshift shelters in lavaland. Ghosts become hermits with knowledge of how they got to where they are now.
/obj/effect/mob_spawn/human/hermit
name = "malfunctioning cryostasis sleeper"
desc = "A humming sleeper with a silhouetted occupant inside. Its stasis function is broken and it's likely being used as a bed."
mob_name = "a stranded hermit"
job_description = "Lavaland Hermit"
icon = 'icons/obj/lavaland/spawners.dmi'
icon_state = "cryostasis_sleeper"
roundstart = FALSE
death = FALSE
random = TRUE
mob_species = /datum/species/human
flavour_text = "<span class='big bold'>You've been stranded in this godless prison of a planet for longer than you can remember.</span><b> Each day you barely scrape by, and between the terrible \
conditions of your makeshift shelter, the hostile creatures, and the ash drakes swooping down from the cloudless skies, all you can wish for is the feel of soft grass between your toes and \
the fresh air of Earth. These thoughts are dispelled by yet another recollection of how you got here... "
assignedrole = "Hermit"
/obj/effect/mob_spawn/human/hermit/Initialize(mapload)
. = ..()
var/arrpee = rand(1,4)
switch(arrpee)
if(1)
flavour_text += "you were a [pick("arms dealer", "shipwright", "docking manager")]'s assistant on a small trading station several sectors from here. Raiders attacked, and there was \
only one pod left when you got to the escape bay. You took it and launched it alone, and the crowd of terrified faces crowding at the airlock door as your pod's engines burst to \
life and sent you to this hell are forever branded into your memory.</b>"
outfit.uniform = /obj/item/clothing/under/assistantformal
outfit.shoes = /obj/item/clothing/shoes/sneakers/black
outfit.back = /obj/item/storage/backpack
if(2)
flavour_text += "you're an exile from the Tiger Cooperative. Their technological fanaticism drove you to question the power and beliefs of the Exolitics, and they saw you as a \
heretic and subjected you to hours of horrible torture. You were hours away from execution when a high-ranking friend of yours in the Cooperative managed to secure you a pod, \
scrambled its destination's coordinates, and launched it. You awoke from stasis when you landed and have been surviving - barely - ever since.</b>"
outfit.uniform = /obj/item/clothing/under/rank/prisoner
outfit.shoes = /obj/item/clothing/shoes/sneakers/orange
outfit.back = /obj/item/storage/backpack
if(3)
flavour_text += "you were a doctor on one of Nanotrasen's space stations, but you left behind that damn corporation's tyranny and everything it stood for. From a metaphorical hell \
to a literal one, you find yourself nonetheless missing the recycled air and warm floors of what you left behind... but you'd still rather be here than there.</b>"
outfit.uniform = /obj/item/clothing/under/rank/medical
outfit.suit = /obj/item/clothing/suit/toggle/labcoat
outfit.back = /obj/item/storage/backpack/medic
outfit.shoes = /obj/item/clothing/shoes/sneakers/black
if(4)
flavour_text += "you were always joked about by your friends for \"not playing with a full deck\", as they so <i>kindly</i> put it. It seems that they were right when you, on a tour \
at one of Nanotrasen's state-of-the-art research facilities, were in one of the escape pods alone and saw the red button. It was big and shiny, and it caught your eye. You pressed \
it, and after a terrifying and fast ride for days, you landed here. You've had time to wisen up since then, and you think that your old friends wouldn't be laughing now.</b>"
outfit.uniform = /obj/item/clothing/under/color/grey/glorf
outfit.shoes = /obj/item/clothing/shoes/sneakers/black
outfit.back = /obj/item/storage/backpack
/obj/effect/mob_spawn/human/hermit/Destroy()
new/obj/structure/fluff/empty_cryostasis_sleeper(get_turf(src))
return ..()
//Broken rejuvenation pod: Spawns in animal hospitals in lavaland. Ghosts become disoriented interns and are advised to search for help.
/obj/effect/mob_spawn/human/doctor/alive/lavaland
name = "broken rejuvenation pod"
desc = "A small sleeper typically used to instantly restore minor wounds. This one seems broken, and its occupant is comatose."
job_description = "Lavaland Veterinarian"
mob_name = "a translocated vet"
flavour_text = "<span class='big bold'>What...?</span><b> Where are you? Where are the others? This is still the animal hospital - you should know, you've been an intern here for weeks - but \
everyone's gone. One of the cats scratched you just a few minutes ago. That's why you were in the pod - to heal the scratch. The scabs are still fresh; you see them right now. So where is \
everyone? Where did they go? What happened to the hospital? And is that <i>smoke</i> you smell? You need to find someone else. Maybe they can tell you what happened.</b>"
assignedrole = "Translocated Vet"
/obj/effect/mob_spawn/human/doctor/alive/lavaland/Destroy()
var/obj/structure/fluff/empty_sleeper/S = new(drop_location())
S.setDir(dir)
return ..()
//Prisoner containment sleeper: Spawns in crashed prison ships in lavaland. Ghosts become escaped prisoners and are advised to find a way out of the mess they've gotten themselves into.
/obj/effect/mob_spawn/human/prisoner_transport
name = "prisoner containment sleeper"
desc = "A sleeper designed to put its occupant into a deep coma, unbreakable until the sleeper turns off. This one's glass is cracked and you can see a pale, sleeping face staring out."
mob_name = "an escaped prisoner"
job_description = "Escaped Prisoner"
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper_s"
outfit = /datum/outfit/lavalandprisoner
roundstart = FALSE
death = FALSE
flavour_text = "<b>Good. It seems as though your ship crashed. <span class='big bold'>You're a prisoner,</span> sentenced to hard work in one of Nanotrasen's labor camps, but it seems as \
though fate has other plans for you. You remember that you were convicted of "
assignedrole = "Escaped Prisoner"
/obj/effect/mob_spawn/human/prisoner_transport/special(mob/living/L)
L.real_name = "NTP #LL-0[rand(111,999)]" //Nanotrasen Prisoner #Lavaland-(numbers)
L.name = L.real_name
/obj/effect/mob_spawn/human/prisoner_transport/Initialize(mapload)
. = ..()
var/list/crimes = list("murder", "larceny", "embezzlement", "unionization", "dereliction of duty", "kidnapping", "gross incompetence", "grand theft", "collaboration with the Syndicate", \
"worship of a forbidden deity", "interspecies relations", "mutiny")
flavour_text += "[pick(crimes)]. but regardless of that, it seems like your crime doesn't matter now. You don't know where you are, but you know that it's out to kill you, and you're not going \
to lose this opportunity. Find a way to get out of this mess and back to where you rightfully belong - your [pick("house", "apartment", "spaceship", "station")]</b>."
/datum/outfit/lavalandprisoner
name = "Lavaland Prisoner"
uniform = /obj/item/clothing/under/rank/prisoner
mask = /obj/item/clothing/mask/breath
shoes = /obj/item/clothing/shoes/sneakers/orange
r_pocket = /obj/item/tank/internals/emergency_oxygen
/obj/effect/mob_spawn/human/prisoner_transport/Destroy()
new/obj/structure/fluff/empty_sleeper/syndicate(get_turf(src))
return ..()
//Space Hotel Staff
/obj/effect/mob_spawn/human/hotel_staff //not free antag u little shits
name = "staff sleeper"
desc = "A sleeper designed for long-term stasis between guest visits."
mob_name = "hotel staff member"
job_description = "Hotel Staff"
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper_s"
objectives = "Cater to visiting guests with your fellow staff. Do not leave your assigned hotel and always remember: The customer is always right!"
death = FALSE
roundstart = FALSE
random = TRUE
outfit = /datum/outfit/hotelstaff
flavour_text = "<span class='big bold'>You are a staff member of a top-of-the-line space hotel!</span><b> Cater to guests and <font size=6><b>DON'T</b></font> leave the hotel, lest the manager fire you for\
dereliction of duty!</b>"
assignedrole = "Hotel Staff"
/datum/outfit/hotelstaff
name = "Hotel Staff"
uniform = /obj/item/clothing/under/assistantformal
shoes = /obj/item/clothing/shoes/laceup
r_pocket = /obj/item/radio/off
back = /obj/item/storage/backpack
implants = list(/obj/item/implant/mindshield)
/obj/effect/mob_spawn/human/hotel_staff/security
name = "hotel security sleeper"
mob_name = "hotel security member"
job_description = "Hotel Security"
outfit = /datum/outfit/hotelstaff/security
flavour_text = "<span class='big bold'>You are a peacekeeper</span><b> assigned to this hotel to protect the interests of the company while keeping the peace between \
guests and the staff. Do <font size=6>NOT</font> leave the hotel, as that is grounds for contract termination.</b>"
objectives = "Do not leave your assigned hotel. Try and keep the peace between staff and guests, non-lethal force heavily advised if possible."
/datum/outfit/hotelstaff/security
name = "Hotel Secuirty"
uniform = /obj/item/clothing/under/rank/security/blueshirt
shoes = /obj/item/clothing/shoes/jackboots
suit = /obj/item/clothing/suit/armor/vest/blueshirt
head = /obj/item/clothing/head/helmet/blueshirt
back = /obj/item/storage/backpack/security
belt = /obj/item/storage/belt/security/full
/obj/effect/mob_spawn/human/hotel_staff/Destroy()
new/obj/structure/fluff/empty_sleeper/syndicate(get_turf(src))
..()
/obj/effect/mob_spawn/human/demonic_friend
name = "Essence of friendship"
desc = "Oh boy! Oh boy! A friend!"
mob_name = "Demonic friend"
job_description = "Demonic Friend"
icon = 'icons/obj/cardboard_cutout.dmi'
icon_state = "cutout_basic"
outfit = /datum/outfit/demonic_friend
death = FALSE
roundstart = FALSE
random = TRUE
id_job = "SuperFriend"
id_access = "assistant"
var/obj/effect/proc_holder/spell/targeted/summon_friend/spell
var/datum/mind/owner
assignedrole = "SuperFriend"
/obj/effect/mob_spawn/human/demonic_friend/Initialize(mapload, datum/mind/owner_mind, obj/effect/proc_holder/spell/targeted/summon_friend/summoning_spell)
. = ..()
owner = owner_mind
flavour_text = "<span class='big bold'>You have been given a reprieve from your eternity of torment, to be [owner.name]'s friend for [owner.p_their()] short mortal coil.</span><b> Be aware that if you do not live up to [owner.name]'s expectations, they can send you back to hell with a single thought. [owner.name]'s death will also return you to hell.</b>"
var/area/A = get_area(src)
if(!mapload && A)
notify_ghosts("\A friendship shell has been completed in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_dnr_observers = TRUE)
objectives = "Be [owner.name]'s friend, and keep [owner.name] alive, so you don't get sent back to hell."
spell = summoning_spell
/obj/effect/mob_spawn/human/demonic_friend/special(mob/living/L)
if(!QDELETED(owner.current) && owner.current.stat != DEAD)
L.real_name = "[owner.name]'s best friend"
L.name = L.real_name
soullink(/datum/soullink/oneway, owner.current, L)
spell.friend = L
spell.charge_counter = spell.charge_max
L.mind.hasSoul = FALSE
var/mob/living/carbon/human/H = L
var/obj/item/worn = H.wear_id
var/obj/item/card/id/id = worn.GetID()
id.registered_name = L.real_name
id.update_label()
else
to_chat(L, "<span class='userdanger'>Your owner is already dead! You will soon perish.</span>")
addtimer(CALLBACK(L, /mob.proc/dust, 150)) //Give em a few seconds as a mercy.
/datum/outfit/demonic_friend
name = "Demonic Friend"
uniform = /obj/item/clothing/under/assistantformal
shoes = /obj/item/clothing/shoes/laceup
r_pocket = /obj/item/radio/off
back = /obj/item/storage/backpack
implants = list(/obj/item/implant/mindshield) //No revolutionaries, he's MY friend.
id = /obj/item/card/id
/obj/effect/mob_spawn/human/syndicate
name = "Syndicate Operative"
roundstart = FALSE
death = FALSE
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper_s"
outfit = /datum/outfit/syndicate_empty
assignedrole = "Space Syndicate" //I know this is really dumb, but Syndicate operative is nuke ops
/datum/outfit/syndicate_empty
name = "Syndicate Operative Empty"
uniform = /obj/item/clothing/under/syndicate
shoes = /obj/item/clothing/shoes/combat
gloves = /obj/item/clothing/gloves/combat
ears = /obj/item/radio/headset/syndicate/alt
back = /obj/item/storage/backpack
implants = list(/obj/item/implant/weapons_auth)
id = /obj/item/card/id/syndicate
/datum/outfit/syndicate_empty/post_equip(mob/living/carbon/human/H)
H.faction |= ROLE_SYNDICATE
/obj/effect/mob_spawn/human/syndicate/battlecruiser
name = "Syndicate Battlecruiser Ship Operative"
flavour_text = "<span class='big bold'>You are a crewmember aboard the syndicate flagship: the SBC Starfury.</span><span class='big'> <span class='danger'><b>Your job is to follow your captain's orders, maintain the ship, and keep the engine running.</b></span> If you are not familiar with how the supermatter engine functions: <b>do not attempt to start it.</b><br>\
<br>\
<span class='danger'><b>The armory is not a candy store, and your role is not to assault the station directly, leave that work to the assault operatives.</b></span></font>"
outfit = /datum/outfit/syndicate_empty/SBC
/datum/outfit/syndicate_empty/SBC
name = "Syndicate Battlecruiser Ship Operative"
l_pocket = /obj/item/gun/ballistic/automatic/pistol
r_pocket = /obj/item/kitchen/knife/combat/survival
belt = /obj/item/storage/belt/military/assault
/obj/effect/mob_spawn/human/syndicate/battlecruiser/assault
name = "Syndicate Battlecruiser Assault Operative"
flavour_text = "<span class='big bold'>You are an assault operative aboard the syndicate flagship: the SBC Starfury.</span><span class='big'> <span class='danger'><b>Your job is to follow your captain's orders, keep intruders out of the ship, and assault Space Station 13.</b></span> There is an armory, multiple assault ships, and beam cannons to attack the station with.<br>\
<br>\
<span class='danger'><b>Work as a team with your fellow operatives and work out a plan of attack. If you are overwhelmed, escape back to your ship!</b></span></span>"
outfit = /datum/outfit/syndicate_empty/SBC/assault
/datum/outfit/syndicate_empty/SBC/assault
name = "Syndicate Battlecruiser Assault Operative"
uniform = /obj/item/clothing/under/syndicate/combat
l_pocket = /obj/item/ammo_box/magazine/m10mm
r_pocket = /obj/item/kitchen/knife/combat/survival
belt = /obj/item/storage/belt/military
suit = /obj/item/clothing/suit/armor/vest
suit_store = /obj/item/gun/ballistic/automatic/pistol
back = /obj/item/storage/backpack/security
mask = /obj/item/clothing/mask/gas/syndicate
/obj/effect/mob_spawn/human/syndicate/battlecruiser/captain
name = "Syndicate Battlecruiser Captain"
flavour_text = "<span class='big bold'>You are the captain aboard the syndicate flagship: the SBC Starfury.</span><span class='big'> <span class='danger'><b>Your job is to oversee your crew, defend the ship, and destroy Space Station 13.</b></span> The ship has an armory, multiple ships, beam cannons, and multiple crewmembers to accomplish this goal.<br>\
<br>\
<span class='danger'><b>As the captain, this whole operation falls on your shoulders.</b></span> You do not need to nuke the station, causing sufficient damage and preventing your ship from being destroyed will be enough.</span>"
outfit = /datum/outfit/syndicate_empty/SBC/assault/captain
id_access_list = list(150,151)
/datum/outfit/syndicate_empty/SBC/assault/captain
name = "Syndicate Battlecruiser Captain"
l_pocket = /obj/item/melee/transforming/energy/sword/saber/red
r_pocket = /obj/item/melee/classic_baton/telescopic
suit = /obj/item/clothing/suit/armor/vest/capcarapace/syndicate
suit_store = /obj/item/gun/ballistic/revolver/mateba
back = /obj/item/storage/backpack/satchel/leather
head = /obj/item/clothing/head/HoS/syndicate
mask = /obj/item/clothing/mask/cigarette/cigar/havana
glasses = /obj/item/clothing/glasses/thermal/eyepatch
//Ancient cryogenic sleepers. Players become NT crewmen from a hundred year old space station, now on the verge of collapse.
/obj/effect/mob_spawn/human/oldsec
name = "old cryogenics pod"
desc = "A humming cryo pod. You can barely recognise a security uniform underneath the built up ice. The machine is attempting to wake up its occupant."
mob_name = "a security officer"
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
roundstart = FALSE
death = FALSE
random = TRUE
mob_species = /datum/species/human
flavour_text = "<span class='big bold'>You are a security officer working for Nanotrasen,</span><b> stationed onboard a state of the art research station. You vaguely recall rushing into a \
cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \
your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod. \
Work as a team with your fellow survivors and do not abandon them.</b>"
uniform = /obj/item/clothing/under/rank/security
shoes = /obj/item/clothing/shoes/jackboots
id = /obj/item/card/id/away/old/sec
r_pocket = /obj/item/restraints/handcuffs
l_pocket = /obj/item/assembly/flash/handheld
job_description = "Oldstation Crew"
assignedrole = "Ancient Crew"
/obj/effect/mob_spawn/human/oldsec/Destroy()
new/obj/structure/showcase/machinery/oldpod/used(drop_location())
return ..()
/obj/effect/mob_spawn/human/oldeng
name = "old cryogenics pod"
desc = "A humming cryo pod. You can barely recognise an engineering uniform underneath the built up ice. The machine is attempting to wake up its occupant."
mob_name = "an engineer"
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
job_description = "Oldstation Crew"
roundstart = FALSE
death = FALSE
random = TRUE
mob_species = /datum/species/human
flavour_text = "<span class='big bold'>You are an engineer working for Nanotrasen,</span><b> stationed onboard a state of the art research station. You vaguely recall rushing into a \
cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \
your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod. \
Work as a team with your fellow survivors and do not abandon them.</b>"
uniform = /obj/item/clothing/under/rank/engineer
shoes = /obj/item/clothing/shoes/workboots
id = /obj/item/card/id/away/old/eng
gloves = /obj/item/clothing/gloves/color/fyellow/old
l_pocket = /obj/item/tank/internals/emergency_oxygen
assignedrole = "Ancient Crew"
/obj/effect/mob_spawn/human/oldeng/Destroy()
new/obj/structure/showcase/machinery/oldpod/used(drop_location())
return ..()
/obj/effect/mob_spawn/human/oldsci
name = "old cryogenics pod"
desc = "A humming cryo pod. You can barely recognise a science uniform underneath the built up ice. The machine is attempting to wake up its occupant."
mob_name = "a scientist"
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
roundstart = FALSE
death = FALSE
random = TRUE
mob_species = /datum/species/human
flavour_text = "<span class='big bold'>You are a scientist working for Nanotrasen,</span><b> stationed onboard a state of the art research station. You vaguely recall rushing into a \
cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \
your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod. \
Work as a team with your fellow survivors and do not abandon them.</b>"
uniform = /obj/item/clothing/under/rank/scientist
shoes = /obj/item/clothing/shoes/laceup
id = /obj/item/card/id/away/old/sci
l_pocket = /obj/item/stack/medical/bruise_pack
assignedrole = "Ancient Crew"
job_description = "Oldstation Crew"
/obj/effect/mob_spawn/human/oldsci/Destroy()
new/obj/structure/showcase/machinery/oldpod/used(drop_location())
return ..()
/obj/effect/mob_spawn/human/pirate
name = "space pirate sleeper"
desc = "A cryo sleeper smelling faintly of rum."
job_description = "Space Pirate"
random = TRUE
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
mob_name = "a space pirate"
mob_species = /datum/species/skeleton/space
outfit = /datum/outfit/pirate/space
roundstart = FALSE
death = FALSE
anchored = TRUE
density = FALSE
show_flavour = FALSE //Flavour only exists for spawners menu
flavour_text = "<span class='big bold'>You are a space pirate.</span><b> The station refused to pay for your protection, protect the ship, siphon the credits from the station and raid it for even more loot.</b>"
assignedrole = "Space Pirate"
var/rank = "Mate"
/obj/effect/mob_spawn/human/pirate/special(mob/living/new_spawn)
new_spawn.fully_replace_character_name(new_spawn.real_name,generate_pirate_name())
new_spawn.mind.add_antag_datum(/datum/antagonist/pirate)
/obj/effect/mob_spawn/human/pirate/proc/generate_pirate_name()
var/beggings = strings(PIRATE_NAMES_FILE, "beginnings")
var/endings = strings(PIRATE_NAMES_FILE, "endings")
return "[rank] [pick(beggings)][pick(endings)]"
/obj/effect/mob_spawn/human/pirate/Destroy()
new/obj/structure/showcase/machinery/oldpod/used(drop_location())
return ..()
/obj/effect/mob_spawn/human/pirate/captain
rank = "Captain"
outfit = /datum/outfit/pirate/space/captain
/obj/effect/mob_spawn/human/pirate/gunner
rank = "Gunner"
+454
View File
@@ -0,0 +1,454 @@
/obj/structure/girder
name = "girder"
icon_state = "girder"
desc = "A large structural assembly made out of metal; It requires a layer of metal before it can be considered a wall."
anchored = TRUE
density = TRUE
var/state = GIRDER_NORMAL
var/girderpasschance = 20 // percentage chance that a projectile passes through the girder.
var/can_displace = TRUE //If the girder can be moved around by wrenching it
max_integrity = 200
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
rad_insulation = RAD_VERY_LIGHT_INSULATION
/obj/structure/girder/examine(mob/user)
. = ..()
switch(state)
if(GIRDER_REINF)
to_chat(user, "<span class='notice'>The support struts are <b>screwed</b> in place.</span>")
if(GIRDER_REINF_STRUTS)
to_chat(user, "<span class='notice'>The support struts are <i>unscrewed</i> and the inner <b>grille</b> is intact.</span>")
if(GIRDER_NORMAL)
if(can_displace)
to_chat(user, "<span class='notice'>The bolts are <b>wrenched</b> in place.</span>")
if(GIRDER_DISPLACED)
to_chat(user, "<span class='notice'>The bolts are <i>loosened</i>, but the <b>screws</b> are holding [src] together.</span>")
if(GIRDER_DISASSEMBLED)
to_chat(user, "<span class='notice'>[src] is disassembled! You probably shouldn't be able to see this examine message.</span>")
/obj/structure/girder/attackby(obj/item/W, mob/user, params)
add_fingerprint(user)
if(istype(W, /obj/item/gun/energy/plasmacutter))
to_chat(user, "<span class='notice'>You start slicing apart the girder...</span>")
if(W.use_tool(src, user, 40, volume=100))
to_chat(user, "<span class='notice'>You slice apart the girder.</span>")
var/obj/item/stack/sheet/metal/M = new (loc, 2)
M.add_fingerprint(user)
qdel(src)
else if(istype(W, /obj/item/pickaxe/drill/jackhammer))
to_chat(user, "<span class='notice'>You smash through the girder!</span>")
new /obj/item/stack/sheet/metal(get_turf(src))
W.play_tool_sound(src)
qdel(src)
else if(istype(W, /obj/item/stack))
if(iswallturf(loc))
to_chat(user, "<span class='warning'>There is already a wall present!</span>")
return
if(!isfloorturf(src.loc))
to_chat(user, "<span class='warning'>A floor must be present to build a false wall!</span>")
return
if (locate(/obj/structure/falsewall) in src.loc.contents)
to_chat(user, "<span class='warning'>There is already a false wall present!</span>")
return
if(istype(W, /obj/item/stack/rods))
var/obj/item/stack/rods/S = W
if(state == GIRDER_DISPLACED)
if(S.get_amount() < 2)
to_chat(user, "<span class='warning'>You need at least two rods to create a false wall!</span>")
return
to_chat(user, "<span class='notice'>You start building a reinforced false wall...</span>")
if(do_after(user, 20, target = src))
if(S.get_amount() < 2)
return
S.use(2)
to_chat(user, "<span class='notice'>You create a false wall. Push on it to open or close the passage.</span>")
var/obj/structure/falsewall/iron/FW = new (loc)
transfer_fingerprints_to(FW)
qdel(src)
else
if(S.get_amount() < 5)
to_chat(user, "<span class='warning'>You need at least five rods to add plating!</span>")
return
to_chat(user, "<span class='notice'>You start adding plating...</span>")
if(do_after(user, 40, target = src))
if(S.get_amount() < 5)
return
S.use(5)
to_chat(user, "<span class='notice'>You add the plating.</span>")
var/turf/T = get_turf(src)
T.PlaceOnTop(/turf/closed/wall/mineral/iron)
transfer_fingerprints_to(T)
qdel(src)
return
if(!istype(W, /obj/item/stack/sheet))
return
var/obj/item/stack/sheet/S = W
if(istype(S, /obj/item/stack/sheet/metal))
if(state == GIRDER_DISPLACED)
if(S.get_amount() < 2)
to_chat(user, "<span class='warning'>You need two sheets of metal to create a false wall!</span>")
return
to_chat(user, "<span class='notice'>You start building a false wall...</span>")
if(do_after(user, 20, target = src))
if(S.get_amount() < 2)
return
S.use(2)
to_chat(user, "<span class='notice'>You create a false wall. Push on it to open or close the passage.</span>")
var/obj/structure/falsewall/F = new (loc)
transfer_fingerprints_to(F)
qdel(src)
else
if(S.get_amount() < 2)
to_chat(user, "<span class='warning'>You need two sheets of metal to finish a wall!</span>")
return
to_chat(user, "<span class='notice'>You start adding plating...</span>")
if (do_after(user, 40, target = src))
if(S.get_amount() < 2)
return
S.use(2)
to_chat(user, "<span class='notice'>You add the plating.</span>")
var/turf/T = get_turf(src)
T.PlaceOnTop(/turf/closed/wall)
transfer_fingerprints_to(T)
qdel(src)
return
if(istype(S, /obj/item/stack/sheet/plasteel))
if(state == GIRDER_DISPLACED)
if(S.get_amount() < 2)
to_chat(user, "<span class='warning'>You need at least two sheets to create a false wall!</span>")
return
to_chat(user, "<span class='notice'>You start building a reinforced false wall...</span>")
if(do_after(user, 20, target = src))
if(S.get_amount() < 2)
return
S.use(2)
to_chat(user, "<span class='notice'>You create a reinforced false wall. Push on it to open or close the passage.</span>")
var/obj/structure/falsewall/reinforced/FW = new (loc)
transfer_fingerprints_to(FW)
qdel(src)
else
if(state == GIRDER_REINF)
if(S.get_amount() < 1)
return
to_chat(user, "<span class='notice'>You start finalizing the reinforced wall...</span>")
if(do_after(user, 50, target = src))
if(S.get_amount() < 1)
return
S.use(1)
to_chat(user, "<span class='notice'>You fully reinforce the wall.</span>")
var/turf/T = get_turf(src)
T.PlaceOnTop(/turf/closed/wall/r_wall)
transfer_fingerprints_to(T)
qdel(src)
return
else
if(S.get_amount() < 1)
return
to_chat(user, "<span class='notice'>You start reinforcing the girder...</span>")
if(do_after(user, 60, target = src))
if(S.get_amount() < 1)
return
S.use(1)
to_chat(user, "<span class='notice'>You reinforce the girder.</span>")
var/obj/structure/girder/reinforced/R = new (loc)
transfer_fingerprints_to(R)
qdel(src)
return
if(S.sheettype && S.sheettype != "runed")
var/M = S.sheettype
if(state == GIRDER_DISPLACED)
if(S.get_amount() < 2)
to_chat(user, "<span class='warning'>You need at least two sheets to create a false wall!</span>")
return
if(do_after(user, 20, target = src))
if(S.get_amount() < 2)
return
S.use(2)
to_chat(user, "<span class='notice'>You create a false wall. Push on it to open or close the passage.</span>")
var/F = text2path("/obj/structure/falsewall/[M]")
var/obj/structure/FW = new F (loc)
transfer_fingerprints_to(FW)
qdel(src)
else
if(S.get_amount() < 2)
to_chat(user, "<span class='warning'>You need at least two sheets to add plating!</span>")
return
to_chat(user, "<span class='notice'>You start adding plating...</span>")
if (do_after(user, 40, target = src))
if(S.get_amount() < 2)
return
S.use(2)
to_chat(user, "<span class='notice'>You add the plating.</span>")
var/turf/T = get_turf(src)
T.PlaceOnTop(text2path("/turf/closed/wall/mineral/[M]"))
transfer_fingerprints_to(T)
qdel(src)
return
add_hiddenprint(user)
else if(istype(W, /obj/item/pipe))
var/obj/item/pipe/P = W
if (P.pipe_type in list(0, 1, 5)) //simple pipes, simple bends, and simple manifolds.
if(!user.transferItemToLoc(P, drop_location()))
return
to_chat(user, "<span class='notice'>You fit the pipe into \the [src].</span>")
else
return ..()
// Screwdriver behavior for girders
/obj/structure/girder/screwdriver_act(mob/user, obj/item/tool)
if(..())
return TRUE
. = FALSE
if(state == GIRDER_DISPLACED)
user.visible_message("<span class='warning'>[user] disassembles the girder.</span>",
"<span class='notice'>You start to disassemble the girder...</span>",
"You hear clanking and banging noises.")
if(tool.use_tool(src, user, 40, volume=100))
if(state != GIRDER_DISPLACED)
return
state = GIRDER_DISASSEMBLED
to_chat(user, "<span class='notice'>You disassemble the girder.</span>")
var/obj/item/stack/sheet/metal/M = new (loc, 2)
M.add_fingerprint(user)
qdel(src)
return TRUE
else if(state == GIRDER_REINF)
to_chat(user, "<span class='notice'>You start unsecuring support struts...</span>")
if(tool.use_tool(src, user, 40, volume=100))
if(state != GIRDER_REINF)
return
to_chat(user, "<span class='notice'>You unsecure the support struts.</span>")
state = GIRDER_REINF_STRUTS
return TRUE
else if(state == GIRDER_REINF_STRUTS)
to_chat(user, "<span class='notice'>You start securing support struts...</span>")
if(tool.use_tool(src, user, 40, volume=100))
if(state != GIRDER_REINF_STRUTS)
return
to_chat(user, "<span class='notice'>You secure the support struts.</span>")
state = GIRDER_REINF
return TRUE
// Wirecutter behavior for girders
/obj/structure/girder/wirecutter_act(mob/user, obj/item/tool)
. = FALSE
if(state == GIRDER_REINF_STRUTS)
to_chat(user, "<span class='notice'>You start removing the inner grille...</span>")
if(tool.use_tool(src, user, 40, volume=100))
to_chat(user, "<span class='notice'>You remove the inner grille.</span>")
new /obj/item/stack/sheet/plasteel(get_turf(src))
var/obj/structure/girder/G = new (loc)
transfer_fingerprints_to(G)
qdel(src)
return TRUE
/obj/structure/girder/wrench_act(mob/user, obj/item/tool)
. = FALSE
if(state == GIRDER_DISPLACED)
if(!isfloorturf(loc))
to_chat(user, "<span class='warning'>A floor must be present to secure the girder!</span>")
to_chat(user, "<span class='notice'>You start securing the girder...</span>")
if(tool.use_tool(src, user, 40, volume=100))
to_chat(user, "<span class='notice'>You secure the girder.</span>")
var/obj/structure/girder/G = new (loc)
transfer_fingerprints_to(G)
qdel(src)
return TRUE
else if(state == GIRDER_NORMAL && can_displace)
to_chat(user, "<span class='notice'>You start unsecuring the girder...</span>")
if(tool.use_tool(src, user, 40, volume=100))
to_chat(user, "<span class='notice'>You unsecure the girder.</span>")
var/obj/structure/girder/displaced/D = new (loc)
transfer_fingerprints_to(D)
qdel(src)
return TRUE
/obj/structure/girder/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && (mover.pass_flags & PASSGRILLE))
return prob(girderpasschance)
else
if(istype(mover, /obj/item/projectile))
return prob(girderpasschance)
else
return 0
/obj/structure/girder/CanAStarPass(ID, dir, caller)
. = !density
if(ismovableatom(caller))
var/atom/movable/mover = caller
. = . || (mover.pass_flags & PASSGRILLE)
/obj/structure/girder/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
var/remains = pick(/obj/item/stack/rods, /obj/item/stack/sheet/metal)
new remains(loc)
qdel(src)
/obj/structure/girder/ratvar_act()
if(anchored)
new /obj/structure/destructible/clockwork/wall_gear(loc)
else
new /obj/structure/destructible/clockwork/wall_gear/displaced(loc)
qdel(src)
/obj/structure/girder/narsie_act()
new /obj/structure/girder/cult(loc)
qdel(src)
/obj/structure/girder/displaced
name = "displaced girder"
icon_state = "displaced"
anchored = FALSE
state = GIRDER_DISPLACED
girderpasschance = 25
max_integrity = 120
/obj/structure/girder/reinforced
name = "reinforced girder"
icon_state = "reinforced"
state = GIRDER_REINF
girderpasschance = 0
max_integrity = 350
//////////////////////////////////////////// cult girder //////////////////////////////////////////////
/obj/structure/girder/cult
name = "runed girder"
desc = "Framework made of a strange and shockingly cold metal. It doesn't seem to have any bolts."
icon = 'icons/obj/cult.dmi'
icon_state= "cultgirder"
can_displace = FALSE
/obj/structure/girder/cult/attackby(obj/item/W, mob/user, params)
add_fingerprint(user)
if(istype(W, /obj/item/melee/cultblade/dagger) && iscultist(user)) //Cultists can demolish cult girders instantly with their tomes
user.visible_message("<span class='warning'>[user] strikes [src] with [W]!</span>", "<span class='notice'>You demolish [src].</span>")
new /obj/item/stack/sheet/runed_metal(drop_location(), 1)
qdel(src)
else if(istype(W, /obj/item/weldingtool) || istype(W, /obj/item/gun/energy/plasmacutter))
if(!W.tool_start_check(user, amount=0))
return
to_chat(user, "<span class='notice'>You start slicing apart the girder...</span>")
if(W.use_tool(src, user, 40, volume=50))
to_chat(user, "<span class='notice'>You slice apart the girder.</span>")
var/obj/item/stack/sheet/runed_metal/R = new(drop_location(), 1)
transfer_fingerprints_to(R)
qdel(src)
else if(istype(W, /obj/item/pickaxe/drill/jackhammer))
to_chat(user, "<span class='notice'>Your jackhammer smashes through the girder!</span>")
var/obj/item/stack/sheet/runed_metal/R = new(drop_location(), 2)
transfer_fingerprints_to(R)
W.play_tool_sound(src)
qdel(src)
else if(istype(W, /obj/item/stack/sheet/runed_metal))
var/obj/item/stack/sheet/runed_metal/R = W
if(R.get_amount() < 1)
to_chat(user, "<span class='warning'>You need at least one sheet of runed metal to construct a runed wall!</span>")
return 0
user.visible_message("<span class='notice'>[user] begins laying runed metal on [src]...</span>", "<span class='notice'>You begin constructing a runed wall...</span>")
if(do_after(user, 50, target = src))
if(R.get_amount() < 1)
return
user.visible_message("<span class='notice'>[user] plates [src] with runed metal.</span>", "<span class='notice'>You construct a runed wall.</span>")
R.use(1)
var/turf/T = get_turf(src)
T.PlaceOnTop(/turf/closed/wall/mineral/cult)
qdel(src)
else
return ..()
/obj/structure/girder/cult/narsie_act()
return
/obj/structure/girder/cult/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
new /obj/item/stack/sheet/runed_metal(drop_location(), 1)
qdel(src)
/obj/structure/girder/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
switch(the_rcd.mode)
if(RCD_FLOORWALL)
return list("mode" = RCD_FLOORWALL, "delay" = 20, "cost" = 8)
if(RCD_DECONSTRUCT)
return list("mode" = RCD_DECONSTRUCT, "delay" = 20, "cost" = 13)
return FALSE
/obj/structure/girder/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode)
var/turf/T = get_turf(src)
switch(passed_mode)
if(RCD_FLOORWALL)
to_chat(user, "<span class='notice'>You finish a wall.</span>")
T.PlaceOnTop(/turf/closed/wall)
qdel(src)
return TRUE
if(RCD_DECONSTRUCT)
to_chat(user, "<span class='notice'>You deconstruct the girder.</span>")
qdel(src)
return TRUE
return FALSE
/obj/structure/girder/bronze
name = "wall gear"
desc = "A girder made out of sturdy bronze, made to resemble a gear."
icon = 'icons/obj/clockwork_objects.dmi'
icon_state = "wall_gear"
can_displace = FALSE
/obj/structure/girder/bronze/attackby(obj/item/W, mob/living/user, params)
add_fingerprint(user)
if(istype(W, /obj/item/weldingtool) || istype(W, /obj/item/gun/energy/plasmacutter))
if(!W.tool_start_check(user, amount = 0))
return
to_chat(user, "<span class='notice'>You start slicing apart [src]...</span>")
if(W.use_tool(src, user, 40, volume=50))
to_chat(user, "<span class='notice'>You slice apart [src].</span>")
var/obj/item/stack/tile/bronze/B = new(drop_location(), 2)
transfer_fingerprints_to(B)
qdel(src)
else if(istype(W, /obj/item/pickaxe/drill/jackhammer))
to_chat(user, "<span class='notice'>Your jackhammer smashes through the girder!</span>")
var/obj/item/stack/tile/bronze/B = new(drop_location(), 2)
transfer_fingerprints_to(B)
W.play_tool_sound(src)
qdel(src)
else if(istype(W, /obj/item/stack/tile/bronze))
var/obj/item/stack/tile/bronze/B = W
if(B.get_amount() < 2)
to_chat(user, "<span class='warning'>You need at least two bronze sheets to build a bronze wall!</span>")
return 0
user.visible_message("<span class='notice'>[user] begins plating [src] with bronze...</span>", "<span class='notice'>You begin constructing a bronze wall...</span>")
if(do_after(user, 50, target = src))
if(B.get_amount() < 2)
return
user.visible_message("<span class='notice'>[user] plates [src] with bronze!</span>", "<span class='notice'>You construct a bronze wall.</span>")
B.use(2)
var/turf/T = get_turf(src)
T.PlaceOnTop(/turf/closed/wall/mineral/bronze)
qdel(src)
else
return ..()
+5 -4
View File
@@ -9,13 +9,11 @@
armor = list("melee" = 0, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 20)
var/obj/item/holosign_creator/projector
/obj/structure/holosign/Initialize(mapload, source_projector)
. = ..()
/obj/structure/holosign/New(loc, source_projector)
if(source_projector)
projector = source_projector
projector.signs += src
alpha = 0
SSvis_overlays.add_vis_overlay(src, icon, icon_state, ABOVE_MOB_LAYER, plane, dir, add_appearance_flags = RESET_ALPHA) //you see mobs under it, but you hit them like they are above it
..()
/obj/structure/holosign/Destroy()
if(projector)
@@ -73,8 +71,10 @@
desc = "A holographic barrier resembling a firelock. Though it does not prevent solid objects from passing through, gas is kept out."
icon_state = "holo_firelock"
density = FALSE
layer = ABOVE_MOB_LAYER
anchored = TRUE
CanAtmosPass = ATMOS_PASS_NO
layer = ABOVE_MOB_LAYER
alpha = 150
/obj/structure/holosign/barrier/atmos/Initialize()
@@ -100,6 +100,7 @@
desc = "A holobarrier that uses biometrics to detect human viruses. Denies passing to personnel with easily-detected, malicious viruses. Good for quarantines."
icon_state = "holo_medical"
alpha = 125 //lazy :)
layer = ABOVE_MOB_LAYER
var/force_allaccess = FALSE
var/buzzcd = 0
+151
View File
@@ -0,0 +1,151 @@
/obj/structure/lattice
name = "lattice"
desc = "A lightweight support lattice. These hold our station together."
icon = 'icons/obj/smooth_structures/lattice.dmi'
icon_state = "lattice"
density = FALSE
anchored = TRUE
armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 50)
max_integrity = 50
layer = LATTICE_LAYER //under pipes
plane = FLOOR_PLANE
var/number_of_rods = 1
canSmoothWith = list(/obj/structure/lattice,
/turf/open/floor,
/turf/closed/wall,
/obj/structure/falsewall)
smooth = SMOOTH_MORE
// flags = CONDUCT_1
/obj/structure/lattice/examine(mob/user)
..()
deconstruction_hints(user)
/obj/structure/lattice/proc/deconstruction_hints(mob/user)
to_chat(user, "<span class='notice'>The rods look like they could be <b>cut</b>. There's space for more <i>rods</i> or a <i>tile</i>.</span>")
/obj/structure/lattice/Initialize(mapload)
. = ..()
for(var/obj/structure/lattice/LAT in loc)
if(LAT != src)
QDEL_IN(LAT, 0)
/obj/structure/lattice/blob_act(obj/structure/blob/B)
return
/obj/structure/lattice/ratvar_act()
new /obj/structure/lattice/clockwork(loc)
/obj/structure/lattice/attackby(obj/item/C, mob/user, params)
if(resistance_flags & INDESTRUCTIBLE)
return
if(istype(C, /obj/item/wirecutters))
to_chat(user, "<span class='notice'>Slicing [name] joints ...</span>")
deconstruct()
else
var/turf/T = get_turf(src)
return T.attackby(C, user) //hand this off to the turf instead (for building plating, catwalks, etc)
/obj/structure/lattice/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
new /obj/item/stack/rods(get_turf(src), number_of_rods)
qdel(src)
/obj/structure/lattice/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
if(the_rcd.mode == RCD_FLOORWALL)
return list("mode" = RCD_FLOORWALL, "delay" = 0, "cost" = 2)
/obj/structure/lattice/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode)
if(passed_mode == RCD_FLOORWALL)
to_chat(user, "<span class='notice'>You build a floor.</span>")
var/turf/T = src.loc
if(isspaceturf(T))
T.PlaceOnTop(/turf/open/floor/plating)
qdel(src)
return TRUE
return FALSE
/obj/structure/lattice/singularity_pull(S, current_size)
if(current_size >= STAGE_FOUR)
deconstruct()
/obj/structure/lattice/clockwork
name = "cog lattice"
desc = "A lightweight support lattice. These hold the Justicar's station together."
icon = 'icons/obj/smooth_structures/lattice_clockwork.dmi'
/obj/structure/lattice/clockwork/Initialize(mapload)
canSmoothWith += /turf/open/indestructible/clock_spawn_room //list overrides are a terrible thing
. = ..()
ratvar_act()
if(is_reebe(z))
resistance_flags |= INDESTRUCTIBLE
/obj/structure/lattice/clockwork/ratvar_act()
if(ISODD(x+y))
icon = 'icons/obj/smooth_structures/lattice_clockwork_large.dmi'
pixel_x = -9
pixel_y = -9
else
icon = 'icons/obj/smooth_structures/lattice_clockwork.dmi'
pixel_x = 0
pixel_y = 0
return TRUE
/obj/structure/lattice/catwalk
name = "catwalk"
desc = "A catwalk for easier EVA maneuvering and cable placement."
icon = 'icons/obj/smooth_structures/catwalk.dmi'
icon_state = "catwalk"
number_of_rods = 2
smooth = SMOOTH_TRUE
canSmoothWith = null
obj_flags = CAN_BE_HIT | BLOCK_Z_FALL
/obj/structure/lattice/catwalk/deconstruction_hints(mob/user)
to_chat(user, "<span class='notice'>The supporting rods look like they could be <b>cut</b>.</span>")
/obj/structure/lattice/catwalk/ratvar_act()
new /obj/structure/lattice/catwalk/clockwork(loc)
/obj/structure/lattice/catwalk/Move()
var/turf/T = loc
for(var/obj/structure/cable/C in T)
C.deconstruct()
..()
/obj/structure/lattice/catwalk/deconstruct()
var/turf/T = loc
for(var/obj/structure/cable/C in T)
C.deconstruct()
..()
/obj/structure/lattice/catwalk/clockwork
name = "clockwork catwalk"
icon = 'icons/obj/smooth_structures/catwalk_clockwork.dmi'
canSmoothWith = list(/obj/structure/lattice,
/turf/open/floor,
/turf/open/indestructible/clock_spawn_room,
/turf/closed/wall,
/obj/structure/falsewall)
smooth = SMOOTH_MORE
/obj/structure/lattice/catwalk/clockwork/Initialize(mapload)
. = ..()
ratvar_act()
if(!mapload)
new /obj/effect/temp_visual/ratvar/floor/catwalk(loc)
new /obj/effect/temp_visual/ratvar/beam/catwalk(loc)
if(is_reebe(z))
resistance_flags |= INDESTRUCTIBLE
/obj/structure/lattice/catwalk/clockwork/ratvar_act()
if(ISODD(x+y))
icon = 'icons/obj/smooth_structures/catwalk_clockwork_large.dmi'
pixel_x = -9
pixel_y = -9
else
icon = 'icons/obj/smooth_structures/catwalk_clockwork.dmi'
pixel_x = 0
pixel_y = 0
return TRUE
@@ -0,0 +1,258 @@
//NOT using the existing /obj/machinery/door type, since that has some complications on its own, mainly based on its
//machineryness
/obj/structure/mineral_door
name = "metal door"
density = TRUE
anchored = TRUE
opacity = TRUE
layer = CLOSED_DOOR_LAYER
icon = 'icons/obj/doors/mineral_doors.dmi'
icon_state = "metal"
var/initial_state
var/state = 0 //closed, 1 == open
var/isSwitchingStates = 0
var/close_delay = -1 //-1 if does not auto close.
max_integrity = 200
armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 50, "acid" = 50)
var/sheetType = /obj/item/stack/sheet/metal
var/sheetAmount = 7
var/openSound = 'sound/effects/stonedoor_openclose.ogg'
var/closeSound = 'sound/effects/stonedoor_openclose.ogg'
CanAtmosPass = ATMOS_PASS_DENSITY
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
rad_insulation = RAD_MEDIUM_INSULATION
/obj/structure/mineral_door/Initialize()
. = ..()
initial_state = icon_state
air_update_turf(TRUE)
/obj/structure/mineral_door/Move()
var/turf/T = loc
. = ..()
move_update_air(T)
/obj/structure/mineral_door/Bumped(atom/movable/AM)
..()
if(!state)
return TryToSwitchState(AM)
/obj/structure/mineral_door/attack_ai(mob/user) //those aren't machinery, they're just big fucking slabs of a mineral
if(isAI(user)) //so the AI can't open it
return
else if(iscyborg(user)) //but cyborgs can
if(get_dist(user,src) <= 1) //not remotely though
return TryToSwitchState(user)
/obj/structure/mineral_door/attack_paw(mob/user)
return attack_hand(user)
/obj/structure/mineral_door/attack_hand(mob/user)
. = ..()
if(.)
return
return TryToSwitchState(user)
/obj/structure/mineral_door/CanPass(atom/movable/mover, turf/target)
if(istype(mover, /obj/effect/beam))
return !opacity
return !density
/obj/structure/mineral_door/proc/TryToSwitchState(atom/user)
if(isSwitchingStates)
return
if(isliving(user))
var/mob/living/M = user
if(world.time - M.last_bumped <= 60)
return //NOTE do we really need that?
if(M.client)
if(iscarbon(M))
var/mob/living/carbon/C = M
if(!C.handcuffed)
SwitchState()
else
SwitchState()
else if(ismecha(user))
SwitchState()
/obj/structure/mineral_door/proc/SwitchState()
if(state)
Close()
else
Open()
/obj/structure/mineral_door/proc/Open()
isSwitchingStates = 1
playsound(src, openSound, 100, 1)
set_opacity(FALSE)
flick("[initial_state]opening",src)
sleep(10)
density = FALSE
layer = OPEN_DOOR_LAYER
state = 1
air_update_turf(1)
update_icon()
isSwitchingStates = 0
if(close_delay != -1)
addtimer(CALLBACK(src, .proc/Close), close_delay)
/obj/structure/mineral_door/proc/Close()
if(isSwitchingStates || state != 1)
return
var/turf/T = get_turf(src)
for(var/mob/living/L in T)
return
isSwitchingStates = 1
playsound(loc, closeSound, 100, 1)
flick("[initial_state]closing",src)
sleep(10)
density = TRUE
set_opacity(TRUE)
state = 0
layer = initial(layer)
air_update_turf(1)
update_icon()
isSwitchingStates = 0
/obj/structure/mineral_door/update_icon()
if(state)
icon_state = "[initial_state]open"
else
icon_state = initial_state
/obj/structure/mineral_door/attackby(obj/item/I, mob/user, params)
if(I.tool_behaviour == TOOL_MINING)
to_chat(user, "<span class='notice'>You start digging the [name]...</span>")
if(I.use_tool(src, user, 40, volume=50))
to_chat(user, "<span class='notice'>You finish digging.</span>")
deconstruct(TRUE)
else if(user.a_intent != INTENT_HARM)
return attack_hand(user)
else
return ..()
/obj/structure/mineral_door/deconstruct(disassembled = TRUE)
var/turf/T = get_turf(src)
if(disassembled)
new sheetType(T, sheetAmount)
else
new sheetType(T, max(sheetAmount - 2, 1))
qdel(src)
/obj/structure/mineral_door/iron
name = "iron door"
max_integrity = 300
/obj/structure/mineral_door/silver
name = "silver door"
icon_state = "silver"
sheetType = /obj/item/stack/sheet/mineral/silver
max_integrity = 300
rad_insulation = RAD_HEAVY_INSULATION
/obj/structure/mineral_door/gold
name = "gold door"
icon_state = "gold"
sheetType = /obj/item/stack/sheet/mineral/gold
rad_insulation = RAD_HEAVY_INSULATION
/obj/structure/mineral_door/uranium
name = "uranium door"
icon_state = "uranium"
sheetType = /obj/item/stack/sheet/mineral/uranium
max_integrity = 300
light_range = 2
/obj/structure/mineral_door/uranium/ComponentInitialize()
return
/obj/structure/mineral_door/sandstone
name = "sandstone door"
icon_state = "sandstone"
sheetType = /obj/item/stack/sheet/mineral/sandstone
max_integrity = 100
/obj/structure/mineral_door/transparent
opacity = FALSE
rad_insulation = RAD_VERY_LIGHT_INSULATION
/obj/structure/mineral_door/transparent/Close()
..()
set_opacity(FALSE)
/obj/structure/mineral_door/transparent/plasma
name = "plasma door"
icon_state = "plasma"
sheetType = /obj/item/stack/sheet/mineral/plasma
/obj/structure/mineral_door/transparent/plasma/ComponentInitialize()
return
/obj/structure/mineral_door/transparent/plasma/attackby(obj/item/W, mob/user, params)
if(W.get_temperature())
var/turf/T = get_turf(src)
message_admins("Plasma mineral door ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_VERBOSEJMP(T)]")
log_game("Plasma mineral door ignited by [key_name(user)] in [AREACOORD(T)]")
TemperatureAct()
else
return ..()
/obj/structure/mineral_door/transparent/plasma/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300)
TemperatureAct()
/obj/structure/mineral_door/transparent/plasma/proc/TemperatureAct()
atmos_spawn_air("plasma=500;TEMP=1000")
deconstruct(FALSE)
/obj/structure/mineral_door/transparent/diamond
name = "diamond door"
icon_state = "diamond"
sheetType = /obj/item/stack/sheet/mineral/diamond
max_integrity = 1000
rad_insulation = RAD_EXTREME_INSULATION
/obj/structure/mineral_door/wood
name = "wood door"
icon_state = "wood"
openSound = 'sound/effects/doorcreaky.ogg'
closeSound = 'sound/effects/doorcreaky.ogg'
sheetType = /obj/item/stack/sheet/mineral/wood
resistance_flags = FLAMMABLE
max_integrity = 200
rad_insulation = RAD_VERY_LIGHT_INSULATION
/obj/structure/mineral_door/woodrustic
name = "rustic wood door"
icon_state = "woodrustic"
openSound = 'sound/effects/doorcreaky.ogg'
closeSound = 'sound/effects/doorcreaky.ogg'
sheetType = /obj/item/stack/sheet/mineral/wood
sheetAmount = 10
max_integrity = 200
rad_insulation = RAD_VERY_LIGHT_INSULATION
/obj/structure/mineral_door/paperframe
name = "paper frame door"
icon_state = "paperframe"
openSound = 'sound/effects/doorcreaky.ogg'
closeSound = 'sound/effects/doorcreaky.ogg'
sheetType = /obj/item/stack/sheet/paperframes
sheetAmount = 3
resistance_flags = FLAMMABLE
max_integrity = 20
/obj/structure/mineral_door/paperframe/Initialize()
. = ..()
queue_smooth_neighbors(src)
/obj/structure/mineral_door/paperframe/ComponentInitialize()
return
/obj/structure/mineral_door/paperframe/Destroy()
queue_smooth_neighbors(src)
return ..()
+385
View File
@@ -0,0 +1,385 @@
/* Morgue stuff
* Contains:
* Morgue
* Morgue tray
* Crematorium
* Creamatorium
* Crematorium tray
* Crematorium button
*/
/*
* Bodycontainer
* Parent class for morgue and crematorium
* For overriding only
*/
GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants and other ghosties.
/obj/structure/bodycontainer
icon = 'icons/obj/stationobjs.dmi'
icon_state = "morgue1"
density = TRUE
anchored = TRUE
max_integrity = 400
var/obj/structure/tray/connected = null
var/locked = FALSE
dir = SOUTH
var/message_cooldown
var/breakout_time = 600
/obj/structure/bodycontainer/Initialize()
. = ..()
GLOB.bodycontainers += src
recursive_organ_check(src)
/obj/structure/bodycontainer/Destroy()
GLOB.bodycontainers -= src
open()
if(connected)
qdel(connected)
connected = null
return ..()
/obj/structure/bodycontainer/on_log(login)
..()
update_icon()
/obj/structure/bodycontainer/update_icon()
return
/obj/structure/bodycontainer/relaymove(mob/user)
if(user.stat || !isturf(loc))
return
if(locked)
if(message_cooldown <= world.time)
message_cooldown = world.time + 50
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
return
open()
/obj/structure/bodycontainer/attack_paw(mob/user)
return attack_hand(user)
/obj/structure/bodycontainer/attack_hand(mob/user)
. = ..()
if(.)
return
if(locked)
to_chat(user, "<span class='danger'>It's locked.</span>")
return
if(!connected)
to_chat(user, "That doesn't appear to have a tray.")
return
if(connected.loc == src)
open()
else
close()
add_fingerprint(user)
/obj/structure/bodycontainer/attack_robot(mob/user)
if(!user.Adjacent(src))
return
return attack_hand(user)
/obj/structure/bodycontainer/attackby(obj/P, mob/user, params)
add_fingerprint(user)
if(istype(P, /obj/item/pen))
if(!user.is_literate())
to_chat(user, "<span class='notice'>You scribble illegibly on the side of [src]!</span>")
return
var/t = stripped_input(user, "What would you like the label to be?", text("[]", name), null)
if (user.get_active_held_item() != P)
return
if(!user.canUseTopic(src, BE_CLOSE))
return
if (t)
name = text("[]- '[]'", initial(name), t)
else
name = initial(name)
else
return ..()
/obj/structure/bodycontainer/deconstruct(disassembled = TRUE)
new /obj/item/stack/sheet/metal (loc, 5)
recursive_organ_check(src)
qdel(src)
/obj/structure/bodycontainer/container_resist(mob/living/user)
if(!locked)
open()
return
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
user.visible_message(null, \
"<span class='notice'>You lean on the back of [src] and start pushing the tray open... (this will take about [DisplayTimeText(breakout_time)].)</span>", \
"<span class='italics'>You hear a metallic creaking from [src].</span>")
if(do_after(user,(breakout_time), target = src))
if(!user || user.stat != CONSCIOUS || user.loc != src )
return
user.visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>", \
"<span class='notice'>You successfully break out of [src]!</span>")
open()
/obj/structure/bodycontainer/proc/open()
recursive_organ_check(src)
playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
playsound(src, 'sound/effects/roll.ogg', 5, 1)
var/turf/T = get_step(src, dir)
connected.setDir(dir)
for(var/atom/movable/AM in src)
AM.forceMove(T)
update_icon()
/obj/structure/bodycontainer/proc/close()
playsound(src, 'sound/effects/roll.ogg', 5, 1)
playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
for(var/atom/movable/AM in connected.loc)
if(!AM.anchored || AM == connected)
if(ismob(AM) && !isliving(AM))
continue
AM.forceMove(src)
recursive_organ_check(src)
update_icon()
/obj/structure/bodycontainer/get_remote_view_fullscreens(mob/user)
if(user.stat == DEAD || !(user.sight & (SEEOBJS|SEEMOBS)))
user.overlay_fullscreen("remote_view", /obj/screen/fullscreen/impaired, 2)
/*
* Morgue
*/
/obj/structure/bodycontainer/morgue
name = "morgue"
desc = "Used to keep bodies in until someone fetches them. Now includes a high-tech alert system."
icon_state = "morgue1"
dir = EAST
var/beeper = TRUE
var/beep_cooldown = 50
var/next_beep = 0
/obj/structure/bodycontainer/morgue/New()
connected = new/obj/structure/tray/m_tray(src)
connected.connected = src
..()
/obj/structure/bodycontainer/morgue/examine(mob/user)
..()
to_chat(user, "<span class='notice'>The speaker is [beeper ? "enabled" : "disabled"]. Alt-click to toggle it.</span>")
/obj/structure/bodycontainer/morgue/AltClick(mob/user)
..()
if(!user.canUseTopic(src, !issilicon(user)))
return
beeper = !beeper
to_chat(user, "<span class='notice'>You turn the speaker function [beeper ? "on" : "off"].</span>")
/obj/structure/bodycontainer/morgue/update_icon()
if (!connected || connected.loc != src) // Open or tray is gone.
icon_state = "morgue0"
else
if(contents.len == 1) // Empty
icon_state = "morgue1"
else
icon_state = "morgue2" // Dead, brainded mob.
var/list/compiled = recursive_mob_check(src, 0, 0) // Search for mobs in all contents.
if(!length(compiled)) // No mobs?
icon_state = "morgue3"
return
for(var/mob/living/M in compiled)
var/mob/living/mob_occupant = get_mob_or_brainmob(M)
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)
playsound(src, 'sound/weapons/smg_empty_alarm.ogg', 50, 0) //Clone them you blind fucks
next_beep = world.time + beep_cooldown
break
/obj/item/paper/guides/jobs/medical/morgue
name = "morgue memo"
info = "<font size='2'>Since this station's medbay never seems to fail to be staffed by the mindless monkeys meant for genetics experiments, I'm leaving a reminder here for anyone handling the pile of cadavers the quacks are sure to leave.</font><BR><BR><font size='4'><font color=red>Red lights mean there's a plain ol' dead body inside.</font><BR><BR><font color=orange>Yellow lights mean there's non-body objects inside.</font><BR><font size='2'>Probably stuff pried off a corpse someone grabbed, or if you're lucky it's stashed booze.</font><BR><BR><font color=green>Green lights mean the morgue system detects the body may be able to be cloned.</font></font><BR><font size='2'>I don't know how that works, but keep it away from the kitchen and go yell at the geneticists.</font><BR><BR>- CentCom medical inspector"
/*
* Crematorium
*/
GLOBAL_LIST_EMPTY(crematoriums)
/obj/structure/bodycontainer/crematorium
name = "crematorium"
desc = "A human incinerator. Works well on barbecue nights."
icon_state = "crema1"
dir = SOUTH
var/id = 1
/obj/structure/bodycontainer/crematorium/attack_robot(mob/user) //Borgs can't use crematoriums without help
to_chat(user, "<span class='warning'>[src] is locked against you.</span>")
return
/obj/structure/bodycontainer/crematorium/Destroy()
GLOB.crematoriums.Remove(src)
return ..()
/obj/structure/bodycontainer/crematorium/New()
connected = new/obj/structure/tray/c_tray(src)
connected.connected = src
GLOB.crematoriums.Add(src)
..()
/obj/structure/bodycontainer/crematorium/update_icon()
if(!connected || connected.loc != src)
icon_state = "crema0"
else
if(src.contents.len > 1)
src.icon_state = "crema2"
else
src.icon_state = "crema1"
if(locked)
src.icon_state = "crema_active"
return
/obj/structure/bodycontainer/crematorium/proc/cremate(mob/user)
if(locked)
return //don't let you cremate something twice or w/e
// Make sure we don't delete the actual morgue and its tray
var/list/conts = GetAllContents() - src - connected
if(!conts.len)
audible_message("<span class='italics'>You hear a hollow crackle.</span>")
return
else
audible_message("<span class='italics'>You hear a roar as the crematorium activates.</span>")
locked = TRUE
update_icon()
for(var/mob/living/M in conts)
if (M.stat != DEAD)
M.emote("scream")
if(user)
log_combat(user, M, "cremated")
else
M.log_message("was cremated", LOG_ATTACK)
M.death(1)
if(M) //some animals get automatically deleted on death.
M.ghostize()
qdel(M)
for(var/obj/O in conts) //conts defined above, ignores crematorium and tray
qdel(O)
if(!locate(/obj/effect/decal/cleanable/ash) in get_step(src, dir))//prevent pile-up
new/obj/effect/decal/cleanable/ash/crematorium(src)
sleep(30)
if(!QDELETED(src))
locked = FALSE
update_icon()
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1) //you horrible people
/obj/structure/bodycontainer/crematorium/creamatorium
name = "creamatorium"
desc = "A human incinerator. Works well during ice cream socials."
/obj/structure/bodycontainer/crematorium/creamatorium/cremate(mob/user)
var/list/icecreams = new()
for(var/mob/living/i_scream in GetAllContents())
var/obj/item/reagent_containers/food/snacks/icecream/IC = new()
IC.set_cone_type("waffle")
IC.add_mob_flavor(i_scream)
icecreams += IC
. = ..()
for(var/obj/IC in icecreams)
IC.forceMove(src)
/*
* Generic Tray
* Parent class for morguetray and crematoriumtray
* For overriding only
*/
/obj/structure/tray
icon = 'icons/obj/stationobjs.dmi'
density = TRUE
layer = TRAY_LAYER
var/obj/structure/bodycontainer/connected = null
anchored = TRUE
pass_flags = LETPASSTHROW
max_integrity = 350
/obj/structure/tray/Destroy()
if(connected)
connected.connected = null
connected.update_icon()
connected = null
return ..()
/obj/structure/tray/deconstruct(disassembled = TRUE)
new /obj/item/stack/sheet/metal (loc, 2)
qdel(src)
/obj/structure/tray/attack_paw(mob/user)
return attack_hand(user)
/obj/structure/tray/attack_hand(mob/user)
. = ..()
if(.)
return
if (src.connected)
connected.close()
add_fingerprint(user)
else
to_chat(user, "<span class='warning'>That's not connected to anything!</span>")
/obj/structure/tray/MouseDrop_T(atom/movable/O as mob|obj, mob/user)
if(!ismovableatom(O) || O.anchored || !Adjacent(user) || !user.Adjacent(O) || O.loc == user)
return
if(!ismob(O))
if(!istype(O, /obj/structure/closet/body_bag))
return
else
var/mob/M = O
if(M.buckled)
return
if(!ismob(user) || user.lying || user.incapacitated())
return
O.forceMove(src.loc)
if (user != O)
visible_message("<span class='warning'>[user] stuffs [O] into [src].</span>")
return
/*
* Crematorium tray
*/
/obj/structure/tray/c_tray
name = "crematorium tray"
desc = "Apply body before burning."
icon_state = "cremat"
/*
* Morgue tray
*/
/obj/structure/tray/m_tray
name = "morgue tray"
desc = "Apply corpse before closing."
icon_state = "morguet"
/obj/structure/tray/m_tray/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && (mover.pass_flags & PASSTABLE))
return 1
if(locate(/obj/structure/table) in get_turf(mover))
return 1
else
return 0
/obj/structure/tray/m_tray/CanAStarPass(ID, dir, caller)
. = !density
if(ismovableatom(caller))
var/atom/movable/mover = caller
. = . || (mover.pass_flags & PASSTABLE)
+381
View File
@@ -0,0 +1,381 @@
#define MUSICIAN_HEARCHECK_MINDELAY 4
#define MUSIC_MAXLINES 600
#define MUSIC_MAXLINECHARS 50
/datum/song
var/name = "Untitled"
var/list/lines = new()
var/tempo = 5 // delay between notes
var/playing = 0 // if we're playing
var/help = 0 // if help is open
var/edit = 1 // if we're in editing mode
var/repeat = 0 // number of times remaining to repeat
var/max_repeats = 10 // maximum times we can repeat
var/instrumentDir = "piano" // the folder with the sounds
var/instrumentExt = "ogg" // the file extension
var/obj/instrumentObj = null // the associated obj playing the sound
var/last_hearcheck = 0
var/list/hearing_mobs
/datum/song/New(dir, obj, ext = "ogg")
tempo = sanitize_tempo(tempo)
instrumentDir = dir
instrumentObj = obj
instrumentExt = ext
/datum/song/Destroy()
instrumentObj = null
return ..()
// note is a number from 1-7 for A-G
// acc is either "b", "n", or "#"
// oct is 1-8 (or 9 for C)
/datum/song/proc/playnote(note, acc as text, oct)
// handle accidental -> B<>C of E<>F
if(acc == "b" && (note == 3 || note == 6)) // C or F
if(note == 3)
oct--
note--
acc = "n"
else if(acc == "#" && (note == 2 || note == 5)) // B or E
if(note == 2)
oct++
note++
acc = "n"
else if(acc == "#" && (note == 7)) //G#
note = 1
acc = "b"
else if(acc == "#") // mass convert all sharps to flats, octave jump already handled
acc = "b"
note++
// check octave, C is allowed to go to 9
if(oct < 1 || (note == 3 ? oct > 9 : oct > 8))
return
// now generate name
var/soundfile = "sound/instruments/[instrumentDir]/[ascii2text(note+64)][acc][oct].[instrumentExt]"
soundfile = file(soundfile)
// make sure the note exists
if(!fexists(soundfile))
return
// and play
var/turf/source = get_turf(instrumentObj)
if((world.time - MUSICIAN_HEARCHECK_MINDELAY) > last_hearcheck)
LAZYCLEARLIST(hearing_mobs)
for(var/mob/M in get_hearers_in_view(15, source))
if(!M.client || !(M.client.prefs.toggles & SOUND_INSTRUMENTS))
continue
LAZYADD(hearing_mobs, M)
last_hearcheck = world.time
var/sound/music_played = sound(soundfile)
for(var/i in hearing_mobs)
var/mob/M = i
M.playsound_local(source, null, 100, falloff = 5, S = music_played)
/datum/song/proc/updateDialog(mob/user)
instrumentObj.updateDialog() // assumes it's an object in world, override if otherwise
/datum/song/proc/shouldStopPlaying(mob/user)
if(instrumentObj)
if(!user.canUseTopic(instrumentObj))
return TRUE
return !instrumentObj.anchored // add special cases to stop in subclasses
else
return TRUE
/datum/song/proc/playsong(mob/user)
while(repeat >= 0)
var/cur_oct[7]
var/cur_acc[7]
for(var/i = 1 to 7)
cur_oct[i] = 3
cur_acc[i] = "n"
for(var/line in lines)
for(var/beat in splittext(lowertext(line), ","))
var/list/notes = splittext(beat, "/")
for(var/note in splittext(notes[1], "-"))
if(!playing || shouldStopPlaying(user))//If the instrument is playing, or special case
playing = FALSE
hearing_mobs = null
return
if(!length(note))
continue
var/cur_note = text2ascii(note) - 96
if(cur_note < 1 || cur_note > 7)
continue
for(var/i=2 to length(note))
var/ni = copytext(note,i,i+1)
if(!text2num(ni))
if(ni == "#" || ni == "b" || ni == "n")
cur_acc[cur_note] = ni
else if(ni == "s")
cur_acc[cur_note] = "#" // so shift is never required
else
cur_oct[cur_note] = text2num(ni)
if(user.dizziness > 0 && prob(user.dizziness / 2))
cur_note = CLAMP(cur_note + rand(round(-user.dizziness / 10), round(user.dizziness / 10)), 1, 7)
if(user.dizziness > 0 && prob(user.dizziness / 5))
if(prob(30))
cur_acc[cur_note] = "#"
else if(prob(42))
cur_acc[cur_note] = "b"
else if(prob(75))
cur_acc[cur_note] = "n"
playnote(cur_note, cur_acc[cur_note], cur_oct[cur_note])
if(notes.len >= 2 && text2num(notes[2]))
sleep(sanitize_tempo(tempo / text2num(notes[2])))
else
sleep(tempo)
repeat--
hearing_mobs = null
playing = FALSE
repeat = 0
updateDialog(user)
/datum/song/proc/interact(mob/user)
var/dat = ""
if(lines.len > 0)
dat += "<H3>Playback</H3>"
if(!playing)
dat += "<A href='?src=[REF(src)];play=1'>Play</A> <SPAN CLASS='linkOn'>Stop</SPAN><BR><BR>"
dat += "Repeat Song: "
dat += repeat > 0 ? "<A href='?src=[REF(src)];repeat=-10'>-</A><A href='?src=[REF(src)];repeat=-1'>-</A>" : "<SPAN CLASS='linkOff'>-</SPAN><SPAN CLASS='linkOff'>-</SPAN>"
dat += " [repeat] times "
dat += repeat < max_repeats ? "<A href='?src=[REF(src)];repeat=1'>+</A><A href='?src=[REF(src)];repeat=10'>+</A>" : "<SPAN CLASS='linkOff'>+</SPAN><SPAN CLASS='linkOff'>+</SPAN>"
dat += "<BR>"
else
dat += "<SPAN CLASS='linkOn'>Play</SPAN> <A href='?src=[REF(src)];stop=1'>Stop</A><BR>"
dat += "Repeats left: <B>[repeat]</B><BR>"
if(!edit)
dat += "<BR><B><A href='?src=[REF(src)];edit=2'>Show Editor</A></B><BR>"
else
dat += "<H3>Editing</H3>"
dat += "<B><A href='?src=[REF(src)];edit=1'>Hide Editor</A></B>"
dat += " <A href='?src=[REF(src)];newsong=1'>Start a New Song</A>"
dat += " <A href='?src=[REF(src)];import=1'>Import a Song</A><BR><BR>"
var/bpm = round(600 / tempo)
dat += "Tempo: <A href='?src=[REF(src)];tempo=[world.tick_lag]'>-</A> [bpm] BPM <A href='?src=[REF(src)];tempo=-[world.tick_lag]'>+</A><BR><BR>"
var/linecount = 0
for(var/line in lines)
linecount += 1
dat += "Line [linecount]: <A href='?src=[REF(src)];modifyline=[linecount]'>Edit</A> <A href='?src=[REF(src)];deleteline=[linecount]'>X</A> [line]<BR>"
dat += "<A href='?src=[REF(src)];newline=1'>Add Line</A><BR><BR>"
if(help)
dat += "<B><A href='?src=[REF(src)];help=1'>Hide Help</A></B><BR>"
dat += {"
Lines are a series of chords, separated by commas (,), each with notes separated by hyphens (-).<br>
Every note in a chord will play together, with chord timed by the tempo.<br>
<br>
Notes are played by the names of the note, and optionally, the accidental, and/or the octave number.<br>
By default, every note is natural and in octave 3. Defining otherwise is remembered for each note.<br>
Example: <i>C,D,E,F,G,A,B</i> will play a C major scale.<br>
After a note has an accidental placed, it will be remembered: <i>C,C4,C,C3</i> is <i>C3,C4,C4,C3</i><br>
Chords can be played simply by seperating each note with a hyphon: <i>A-C#,Cn-E,E-G#,Gn-B</i><br>
A pause may be denoted by an empty chord: <i>C,E,,C,G</i><br>
To make a chord be a different time, end it with /x, where the chord length will be length<br>
defined by tempo / x: <i>C,G/2,E/4</i><br>
Combined, an example is: <i>E-E4/4,F#/2,G#/8,B/8,E3-E4/4</i>
<br>
Lines may be up to [MUSIC_MAXLINECHARS] characters.<br>
A song may only contain up to [MUSIC_MAXLINES] lines.<br>
"}
else
dat += "<B><A href='?src=[REF(src)];help=2'>Show Help</A></B><BR>"
var/datum/browser/popup = new(user, "instrument", instrumentObj.name, 700, 500)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(instrumentObj.icon, instrumentObj.icon_state))
popup.open()
/datum/song/proc/ParseSong(text)
set waitfor = FALSE
//split into lines
lines = splittext(text, "\n")
if(lines.len)
if(copytext(lines[1],1,6) == "BPM: ")
tempo = sanitize_tempo(600 / text2num(copytext(lines[1],6)))
lines.Cut(1,2)
else
tempo = sanitize_tempo(5) // default 120 BPM
if(lines.len > MUSIC_MAXLINES)
to_chat(usr, "Too many lines!")
lines.Cut(MUSIC_MAXLINES + 1)
var/linenum = 1
for(var/l in lines)
if(length(l) > MUSIC_MAXLINECHARS)
to_chat(usr, "Line [linenum] too long!")
lines.Remove(l)
else
linenum++
updateDialog(usr) // make sure updates when complete
/datum/song/Topic(href, href_list)
if(!usr.canUseTopic(instrumentObj))
usr << browse(null, "window=instrument")
usr.unset_machine()
return
instrumentObj.add_fingerprint(usr)
if(href_list["newsong"])
lines = new()
tempo = sanitize_tempo(5) // default 120 BPM
name = ""
else if(href_list["import"])
var/t = ""
do
t = html_encode(input(usr, "Please paste the entire song, formatted:", text("[]", name), t) as message)
if(!in_range(instrumentObj, usr))
return
if(length(t) >= MUSIC_MAXLINES * MUSIC_MAXLINECHARS)
var/cont = input(usr, "Your message is too long! Would you like to continue editing it?", "", "yes") in list("yes", "no")
if(cont == "no")
break
while(length(t) > MUSIC_MAXLINES * MUSIC_MAXLINECHARS)
ParseSong(t)
else if(href_list["help"])
help = text2num(href_list["help"]) - 1
else if(href_list["edit"])
edit = text2num(href_list["edit"]) - 1
if(href_list["repeat"]) //Changing this from a toggle to a number of repeats to avoid infinite loops.
if(playing)
return //So that people cant keep adding to repeat. If the do it intentionally, it could result in the server crashing.
repeat += round(text2num(href_list["repeat"]))
if(repeat < 0)
repeat = 0
if(repeat > max_repeats)
repeat = max_repeats
else if(href_list["tempo"])
tempo = sanitize_tempo(tempo + text2num(href_list["tempo"]))
else if(href_list["play"])
playing = TRUE
spawn()
playsong(usr)
else if(href_list["newline"])
var/newline = html_encode(input("Enter your line: ", instrumentObj.name) as text|null)
if(!newline || !in_range(instrumentObj, usr))
return
if(lines.len > MUSIC_MAXLINES)
return
if(length(newline) > MUSIC_MAXLINECHARS)
newline = copytext(newline, 1, MUSIC_MAXLINECHARS)
lines.Add(newline)
else if(href_list["deleteline"])
var/num = round(text2num(href_list["deleteline"]))
if(num > lines.len || num < 1)
return
lines.Cut(num, num+1)
else if(href_list["modifyline"])
var/num = round(text2num(href_list["modifyline"]),1)
var/content = html_encode(input("Enter your line: ", instrumentObj.name, lines[num]) as text|null)
if(!content || !in_range(instrumentObj, usr))
return
if(length(content) > MUSIC_MAXLINECHARS)
content = copytext(content, 1, MUSIC_MAXLINECHARS)
if(num > lines.len || num < 1)
return
lines[num] = content
else if(href_list["stop"])
playing = FALSE
hearing_mobs = null
updateDialog(usr)
return
/datum/song/proc/sanitize_tempo(new_tempo)
new_tempo = abs(new_tempo)
return max(round(new_tempo, world.tick_lag), world.tick_lag)
// subclass for handheld instruments, like violin
/datum/song/handheld
/datum/song/handheld/updateDialog(mob/user)
instrumentObj.interact(user)
/datum/song/handheld/shouldStopPlaying()
if(instrumentObj)
return !isliving(instrumentObj.loc)
else
return TRUE
//////////////////////////////////////////////////////////////////////////
/obj/structure/piano
name = "space minimoog"
icon = 'icons/obj/musician.dmi'
icon_state = "minimoog"
anchored = TRUE
density = TRUE
var/datum/song/song
/obj/structure/piano/unanchored
anchored = FALSE
/obj/structure/piano/New()
..()
song = new("piano", src)
if(prob(50) && icon_state == initial(icon_state))
name = "space minimoog"
desc = "This is a minimoog, like a space piano, but more spacey!"
icon_state = "minimoog"
else
name = "space piano"
desc = "This is a space piano, like a regular piano, but always in tune! Even if the musician isn't."
icon_state = "piano"
/obj/structure/piano/Destroy()
qdel(song)
song = null
return ..()
/obj/structure/piano/Initialize(mapload)
. = ..()
if(mapload)
song.tempo = song.sanitize_tempo(song.tempo) // tick_lag isn't set when the map is loaded
/obj/structure/piano/attack_hand(mob/user)
. = ..()
if(.)
return
interact(user)
/obj/structure/piano/attack_paw(mob/user)
return attack_hand(user)
/obj/structure/piano/interact(mob/user)
ui_interact(user)
/obj/structure/piano/ui_interact(mob/user)
if(!user || !anchored)
return
if(!user.IsAdvancedToolUser())
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
return 1
user.set_machine(src)
song.interact(user)
/obj/structure/piano/wrench_act(mob/living/user, obj/item/I)
default_unfasten_wrench(user, I, 40)
return TRUE
+1 -5
View File
@@ -6,16 +6,12 @@
armor = list("melee" = 100, "bullet" = 80, "laser" = 80, "energy" = 100, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 50, "acid" = 50)
density = FALSE
anchored = TRUE
layer = ABOVE_MOB_LAYER
CanAtmosPass = ATMOS_PASS_NO
/obj/structure/plasticflaps/opaque
opacity = TRUE
/obj/structure/plasticflaps/Initialize()
. = ..()
alpha = 0
SSvis_overlays.add_vis_overlay(src, icon, icon_state, ABOVE_MOB_LAYER, plane, dir, add_appearance_flags = RESET_ALPHA) //you see mobs under it, but you hit them like they are above it
/obj/structure/plasticflaps/examine(mob/user)
. = ..()
if(anchored)
+263
View File
@@ -0,0 +1,263 @@
/obj/structure/reflector
name = "reflector base"
icon = 'icons/obj/structures.dmi'
icon_state = "reflector_map"
desc = "A base for reflector assemblies."
anchored = FALSE
density = FALSE
var/deflector_icon_state
var/image/deflector_overlay
var/finished = FALSE
var/admin = FALSE //Can't be rotated or deconstructed
var/can_rotate = TRUE
var/framebuildstacktype = /obj/item/stack/sheet/metal
var/framebuildstackamount = 5
var/buildstacktype = /obj/item/stack/sheet/metal
var/buildstackamount = 0
var/list/allowed_projectile_typecache = list(/obj/item/projectile/beam)
var/rotation_angle = -1
/obj/structure/reflector/Initialize()
. = ..()
icon_state = "reflector_base"
allowed_projectile_typecache = typecacheof(allowed_projectile_typecache)
if(deflector_icon_state)
deflector_overlay = image(icon, deflector_icon_state)
add_overlay(deflector_overlay)
if(rotation_angle == -1)
setAngle(dir2angle(dir))
else
setAngle(rotation_angle)
if(admin)
can_rotate = FALSE
/obj/structure/reflector/examine(mob/user)
..()
if(finished)
to_chat(user, "It is set to [rotation_angle] degrees, and the rotation is [can_rotate ? "unlocked" : "locked"].")
if(!admin)
if(can_rotate)
to_chat(user, "<span class='notice'>Alt-click to adjust its direction.</span>")
else
to_chat(user, "<span class='notice'>Use screwdriver to unlock the rotation.</span>")
/obj/structure/reflector/proc/setAngle(new_angle)
if(can_rotate)
rotation_angle = new_angle
if(deflector_overlay)
cut_overlay(deflector_overlay)
deflector_overlay.transform = turn(matrix(), new_angle)
add_overlay(deflector_overlay)
/obj/structure/reflector/setDir(new_dir)
return ..(NORTH)
/obj/structure/reflector/proc/dir_map_to_angle(dir)
return 0
/obj/structure/reflector/bullet_act(obj/item/projectile/P)
var/pdir = P.dir
var/pangle = P.Angle
var/ploc = get_turf(P)
if(!finished || !allowed_projectile_typecache[P.type] || !(P.dir in GLOB.cardinals))
return ..()
if(auto_reflect(P, pdir, ploc, pangle) != -1)
return ..()
return -1
/obj/structure/reflector/proc/auto_reflect(obj/item/projectile/P, pdir, turf/ploc, pangle)
P.ignore_source_check = TRUE
P.range = P.decayedRange
P.decayedRange = max(P.decayedRange--, 0)
return -1
/obj/structure/reflector/attackby(obj/item/W, mob/user, params)
if(admin)
return
if(istype(W, /obj/item/screwdriver))
can_rotate = !can_rotate
to_chat(user, "<span class='notice'>You [can_rotate ? "unlock" : "lock"] [src]'s rotation.</span>")
W.play_tool_sound(src)
return
if(istype(W, /obj/item/wrench))
if(anchored)
to_chat(user, "<span class='warning'>Unweld [src] from the floor first!</span>")
return
user.visible_message("[user] starts to dismantle [src].", "<span class='notice'>You start to dismantle [src]...</span>")
if(W.use_tool(src, user, 80, volume=50))
to_chat(user, "<span class='notice'>You dismantle [src].</span>")
new framebuildstacktype(drop_location(), framebuildstackamount)
if(buildstackamount)
new buildstacktype(drop_location(), buildstackamount)
qdel(src)
else if(istype(W, /obj/item/weldingtool))
if(obj_integrity < max_integrity)
if(!W.tool_start_check(user, amount=0))
return
user.visible_message("[user] starts to repair [src].",
"<span class='notice'>You begin repairing [src]...</span>",
"<span class='italics'>You hear welding.</span>")
if(W.use_tool(src, user, 40, volume=40))
obj_integrity = max_integrity
user.visible_message("[user] has repaired [src].", \
"<span class='notice'>You finish repairing [src].</span>")
else if(!anchored)
if(!W.tool_start_check(user, amount=0))
return
user.visible_message("[user] starts to weld [src] to the floor.",
"<span class='notice'>You start to weld [src] to the floor...</span>",
"<span class='italics'>You hear welding.</span>")
if (W.use_tool(src, user, 20, volume=50))
setAnchored(TRUE)
to_chat(user, "<span class='notice'>You weld [src] to the floor.</span>")
else
if(!W.tool_start_check(user, amount=0))
return
user.visible_message("[user] starts to cut [src] free from the floor.",
"<span class='notice'>You start to cut [src] free from the floor...</span>",
"<span class='italics'>You hear welding.</span>")
if (W.use_tool(src, user, 20, volume=50))
setAnchored(FALSE)
to_chat(user, "<span class='notice'>You cut [src] free from the floor.</span>")
//Finishing the frame
else if(istype(W, /obj/item/stack/sheet))
if(finished)
return
var/obj/item/stack/sheet/S = W
if(istype(S, /obj/item/stack/sheet/glass))
if(S.use(5))
new /obj/structure/reflector/single(drop_location())
qdel(src)
else
to_chat(user, "<span class='warning'>You need five sheets of glass to create a reflector!</span>")
return
if(istype(S, /obj/item/stack/sheet/rglass))
if(S.use(10))
new /obj/structure/reflector/double(drop_location())
qdel(src)
else
to_chat(user, "<span class='warning'>You need ten sheets of reinforced glass to create a double reflector!</span>")
return
if(istype(S, /obj/item/stack/sheet/mineral/diamond))
if(S.use(1))
new /obj/structure/reflector/box(drop_location())
qdel(src)
else
return ..()
/obj/structure/reflector/proc/rotate(mob/user)
if (!can_rotate || admin)
to_chat(user, "<span class='warning'>The rotation is locked!</span>")
return FALSE
var/new_angle = input(user, "Input a new angle for primary reflection face.", "Reflector Angle", rotation_angle) as null|num
if(!user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return
if(!isnull(new_angle))
setAngle(SIMPLIFY_DEGREES(new_angle))
return TRUE
/obj/structure/reflector/AltClick(mob/user)
if(!user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return
else if(finished)
rotate(user)
//TYPES OF REFLECTORS, SINGLE, DOUBLE, BOX
//SINGLE
/obj/structure/reflector/single
name = "reflector"
deflector_icon_state = "reflector"
desc = "An angled mirror for reflecting laser beams."
density = TRUE
finished = TRUE
buildstacktype = /obj/item/stack/sheet/glass
buildstackamount = 5
/obj/structure/reflector/single/anchored
anchored = TRUE
/obj/structure/reflector/single/mapping
admin = TRUE
anchored = TRUE
/obj/structure/reflector/single/auto_reflect(obj/item/projectile/P, pdir, turf/ploc, pangle)
var/incidence = GET_ANGLE_OF_INCIDENCE(rotation_angle, (P.Angle + 180))
if(abs(incidence) > 90 && abs(incidence) < 270)
return FALSE
var/new_angle = SIMPLIFY_DEGREES(rotation_angle + incidence)
P.setAngle(new_angle)
return ..()
//DOUBLE
/obj/structure/reflector/double
name = "double sided reflector"
deflector_icon_state = "reflector_double"
desc = "A double sided angled mirror for reflecting laser beams."
density = TRUE
finished = TRUE
buildstacktype = /obj/item/stack/sheet/rglass
buildstackamount = 10
/obj/structure/reflector/double/anchored
anchored = TRUE
/obj/structure/reflector/double/mapping
admin = TRUE
anchored = TRUE
/obj/structure/reflector/double/auto_reflect(obj/item/projectile/P, pdir, turf/ploc, pangle)
var/incidence = GET_ANGLE_OF_INCIDENCE(rotation_angle, (P.Angle + 180))
var/new_angle = SIMPLIFY_DEGREES(rotation_angle + incidence)
P.setAngle(new_angle)
return ..()
//BOX
/obj/structure/reflector/box
name = "reflector box"
deflector_icon_state = "reflector_box"
desc = "A box with an internal set of mirrors that reflects all laser beams in a single direction."
density = TRUE
finished = TRUE
buildstacktype = /obj/item/stack/sheet/mineral/diamond
buildstackamount = 1
/obj/structure/reflector/box/anchored
anchored = TRUE
/obj/structure/reflector/box/mapping
admin = TRUE
anchored = TRUE
/obj/structure/reflector/box/auto_reflect(obj/item/projectile/P)
P.setAngle(rotation_angle)
return ..()
/obj/structure/reflector/ex_act()
if(admin)
return
else
return ..()
/obj/structure/reflector/dir_map_to_angle(dir)
return dir2angle(dir)
/obj/structure/reflector/singularity_act()
if(admin)
return
else
return ..()
@@ -0,0 +1,57 @@
//map and direction signs
/obj/structure/sign/map
name = "station map"
desc = "A framed picture of the station."
max_integrity = 500
/obj/structure/sign/map/left
icon_state = "map-left"
/obj/structure/sign/map/right
icon_state = "map-right"
/obj/structure/sign/directions/science
name = "science department"
desc = "A direction sign, pointing out which way the Science department is."
icon_state = "direction_sci"
/obj/structure/sign/directions/engineering
name = "engineering department"
desc = "A direction sign, pointing out which way the Engineering department is."
icon_state = "direction_eng"
/obj/structure/sign/directions/security
name = "security department"
desc = "A direction sign, pointing out which way the Security department is."
icon_state = "direction_sec"
/obj/structure/sign/directions/medical
name = "medical bay"
desc = "A direction sign, pointing out which way the Medical Bay is."
icon_state = "direction_med"
/obj/structure/sign/directions/evac
name = "escape arm"
desc = "A direction sign, pointing out which way the escape shuttle dock is."
icon_state = "direction_evac"
/obj/structure/sign/directions/supply
name = "cargo bay"
desc = "A direction sign, pointing out which way the Cargo Bay is."
icon_state = "direction_supply"
/obj/structure/sign/directions/command
name = "command department"
desc = "A direction sign, pointing out which way the Command department is."
icon_state = "direction_bridge"
/obj/structure/sign/directions/bar
name = "bar"
desc = "A direction sign, pointing out which way the Bar is."
icon_state = "direction_bar"
/obj/structure/sign/directions/cafe
name = "cafe"
desc = "A direction sign, pointing out which way the Cafe is."
icon_state = "direction_cafe"
+283
View File
@@ -0,0 +1,283 @@
/obj/structure/statue
name = "statue"
desc = "Placeholder. Yell at Firecage if you SOMEHOW see this."
icon = 'icons/obj/statue.dmi'
icon_state = ""
density = TRUE
anchored = FALSE
max_integrity = 100
var/oreAmount = 5
var/material_drop_type = /obj/item/stack/sheet/metal
CanAtmosPass = ATMOS_PASS_DENSITY
/obj/structure/statue/attackby(obj/item/W, mob/living/user, params)
add_fingerprint(user)
user.changeNext_move(CLICK_CD_MELEE)
if(!(flags_1 & NODECONSTRUCT_1))
if(default_unfasten_wrench(user, W))
return
if(istype(W, /obj/item/weldingtool) || istype(W, /obj/item/gun/energy/plasmacutter))
if(!W.tool_start_check(user, amount=0))
return FALSE
user.visible_message("[user] is slicing apart the [name].", \
"<span class='notice'>You are slicing apart the [name]...</span>")
if(W.use_tool(src, user, 40, volume=50))
user.visible_message("[user] slices apart the [name].", \
"<span class='notice'>You slice apart the [name]!</span>")
deconstruct(TRUE)
return
return ..()
/obj/structure/statue/attack_hand(mob/living/user)
. = ..()
if(.)
return
user.changeNext_move(CLICK_CD_MELEE)
add_fingerprint(user)
user.visible_message("[user] rubs some dust off from the [name]'s surface.", \
"<span class='notice'>You rub some dust off from the [name]'s surface.</span>")
/obj/structure/statue/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
if(material_drop_type)
var/drop_amt = oreAmount
if(!disassembled)
drop_amt -= 2
if(drop_amt > 0)
new material_drop_type(get_turf(src), drop_amt)
qdel(src)
//////////////////////////////////////STATUES/////////////////////////////////////////////////////////////
////////////////////////uranium///////////////////////////////////
/obj/structure/statue/uranium
max_integrity = 300
light_range = 2
material_drop_type = /obj/item/stack/sheet/mineral/uranium
var/last_event = 0
var/active = null
/obj/structure/statue/uranium/nuke
name = "statue of a nuclear fission explosive"
desc = "This is a grand statue of a Nuclear Explosive. It has a sickening green colour."
icon_state = "nuke"
/obj/structure/statue/uranium/eng
name = "Statue of an engineer"
desc = "This statue has a sickening green colour."
icon_state = "eng"
/obj/structure/statue/uranium/attackby(obj/item/W, mob/user, params)
radiate()
return ..()
/obj/structure/statue/uranium/Bumped(atom/movable/AM)
radiate()
..()
/obj/structure/statue/uranium/attack_hand(mob/user)
radiate()
. = ..()
/obj/structure/statue/uranium/attack_paw(mob/user)
radiate()
. = ..()
/obj/structure/statue/uranium/proc/radiate()
if(!active)
if(world.time > last_event+15)
active = 1
radiation_pulse(src, 30)
last_event = world.time
active = null
return
return
////////////////////////////plasma///////////////////////////////////////////////////////////////////////
/obj/structure/statue/plasma
max_integrity = 200
material_drop_type = /obj/item/stack/sheet/mineral/plasma
desc = "This statue is suitably made from plasma."
/obj/structure/statue/plasma/scientist
name = "statue of a scientist"
icon_state = "sci"
/obj/structure/statue/plasma/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300)
PlasmaBurn(exposed_temperature)
/obj/structure/statue/plasma/bullet_act(obj/item/projectile/Proj)
var/burn = FALSE
if(!(Proj.nodamage) && Proj.damage_type == BURN && !QDELETED(src))
burn = TRUE
if(burn)
var/turf/T = get_turf(src)
if(Proj.firer)
message_admins("Plasma statue ignited by [ADMIN_LOOKUPFLW(Proj.firer)] in [ADMIN_VERBOSEJMP(T)]")
log_game("Plasma statue ignited by [key_name(Proj.firer)] in [AREACOORD(T)]")
else
message_admins("Plasma statue ignited by [Proj]. No known firer, in [ADMIN_VERBOSEJMP(T)]")
log_game("Plasma statue ignited by [Proj] in [AREACOORD(T)]. No known firer.")
PlasmaBurn(2500)
..()
/obj/structure/statue/plasma/attackby(obj/item/W, mob/user, params)
if(W.get_temperature() > 300 && !QDELETED(src))//If the temperature of the object is over 300, then ignite
var/turf/T = get_turf(src)
message_admins("Plasma statue ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_VERBOSEJMP(T)]")
log_game("Plasma statue ignited by [key_name(user)] in [AREACOORD(T)]")
ignite(W.get_temperature())
else
return ..()
/obj/structure/statue/plasma/proc/PlasmaBurn(exposed_temperature)
if(QDELETED(src))
return
atmos_spawn_air("plasma=[oreAmount*10];TEMP=[exposed_temperature]")
deconstruct(FALSE)
/obj/structure/statue/plasma/proc/ignite(exposed_temperature)
if(exposed_temperature > 300)
PlasmaBurn(exposed_temperature)
//////////////////////gold///////////////////////////////////////
/obj/structure/statue/gold
max_integrity = 300
material_drop_type = /obj/item/stack/sheet/mineral/gold
desc = "This is a highly valuable statue made from gold."
/obj/structure/statue/gold/hos
name = "statue of the head of security"
icon_state = "hos"
/obj/structure/statue/gold/hop
name = "statue of the head of personnel"
icon_state = "hop"
/obj/structure/statue/gold/cmo
name = "statue of the chief medical officer"
icon_state = "cmo"
/obj/structure/statue/gold/ce
name = "statue of the chief engineer"
icon_state = "ce"
/obj/structure/statue/gold/rd
name = "statue of the research director"
icon_state = "rd"
//////////////////////////silver///////////////////////////////////////
/obj/structure/statue/silver
max_integrity = 300
material_drop_type = /obj/item/stack/sheet/mineral/silver
desc = "This is a valuable statue made from silver."
/obj/structure/statue/silver/md
name = "statue of a medical officer"
icon_state = "md"
/obj/structure/statue/silver/janitor
name = "statue of a janitor"
icon_state = "jani"
/obj/structure/statue/silver/sec
name = "statue of a security officer"
icon_state = "sec"
/obj/structure/statue/silver/secborg
name = "statue of a security cyborg"
icon_state = "secborg"
/obj/structure/statue/silver/medborg
name = "statue of a medical cyborg"
icon_state = "medborg"
/////////////////////////diamond/////////////////////////////////////////
/obj/structure/statue/diamond
max_integrity = 1000
material_drop_type = /obj/item/stack/sheet/mineral/diamond
desc = "This is a very expensive diamond statue."
/obj/structure/statue/diamond/captain
name = "statue of THE captain."
icon_state = "cap"
/obj/structure/statue/diamond/ai1
name = "statue of the AI hologram."
icon_state = "ai1"
/obj/structure/statue/diamond/ai2
name = "statue of the AI core."
icon_state = "ai2"
////////////////////////bananium///////////////////////////////////////
/obj/structure/statue/bananium
max_integrity = 300
material_drop_type = /obj/item/stack/sheet/mineral/bananium
desc = "A bananium statue with a small engraving:'HOOOOOOONK'."
var/spam_flag = 0
/obj/structure/statue/bananium/clown
name = "statue of a clown"
icon_state = "clown"
/obj/structure/statue/bananium/Bumped(atom/movable/AM)
honk()
..()
/obj/structure/statue/bananium/attackby(obj/item/W, mob/user, params)
honk()
return ..()
/obj/structure/statue/bananium/attack_hand(mob/user)
honk()
. = ..()
/obj/structure/statue/bananium/attack_paw(mob/user)
honk()
..()
/obj/structure/statue/bananium/proc/honk()
if(!spam_flag)
spam_flag = 1
playsound(src.loc, 'sound/items/bikehorn.ogg', 50, 1)
spawn(20)
spam_flag = 0
/////////////////////sandstone/////////////////////////////////////////
/obj/structure/statue/sandstone
max_integrity = 50
material_drop_type = /obj/item/stack/sheet/mineral/sandstone
/obj/structure/statue/sandstone/assistant
name = "statue of an assistant"
desc = "A cheap statue of sandstone for a greyshirt."
icon_state = "assist"
/obj/structure/statue/sandstone/venus //call me when we add marble i guess
name = "statue of a pure maiden"
desc = "An ancient marble statue. The subject is depicted with a floor-length braid and is wielding a toolbox. By Jove, it's easily the most gorgeous depiction of a woman you've ever seen. The artist must truly be a master of his craft. Shame about the broken arm, though."
icon = 'icons/obj/statuelarge.dmi'
icon_state = "venus"
/////////////////////snow/////////////////////////////////////////
/obj/structure/statue/snow
max_integrity = 50
material_drop_type = /obj/item/stack/sheet/mineral/snow
/obj/structure/statue/snow/snowman
name = "snowman"
desc = "Several lumps of snow put together to form a snowman."
icon_state = "snowman"
@@ -0,0 +1,184 @@
/obj/structure/transit_tube_pod
icon = 'icons/obj/atmospherics/pipes/transit_tube.dmi'
icon_state = "pod"
animate_movement = FORWARD_STEPS
anchored = TRUE
density = TRUE
var/moving = 0
var/datum/gas_mixture/air_contents = new()
/obj/structure/transit_tube_pod/Initialize()
. = ..()
air_contents.gases[/datum/gas/oxygen] = MOLES_O2STANDARD
air_contents.gases[/datum/gas/nitrogen] = MOLES_N2STANDARD
air_contents.temperature = T20C
/obj/structure/transit_tube_pod/Destroy()
empty_pod()
return ..()
/obj/structure/transit_tube_pod/update_icon()
if(contents.len)
icon_state = "pod_occupied"
else
icon_state = "pod"
/obj/structure/transit_tube_pod/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/crowbar))
if(!moving)
I.play_tool_sound(src)
if(contents.len)
user.visible_message("[user] empties \the [src].", "<span class='notice'>You empty \the [src].</span>")
empty_pod()
else
deconstruct(TRUE, user)
else
return ..()
/obj/structure/transit_tube_pod/deconstruct(disassembled = TRUE, mob/user)
if(!(flags_1 & NODECONSTRUCT_1))
var/atom/location = get_turf(src)
if(user)
location = user.loc
add_fingerprint(user)
user.visible_message("[user] removes [src].", "<span class='notice'>You remove [src].</span>")
var/obj/structure/c_transit_tube_pod/R = new/obj/structure/c_transit_tube_pod(location)
transfer_fingerprints_to(R)
R.setDir(dir)
empty_pod(location)
qdel(src)
/obj/structure/transit_tube_pod/ex_act(severity, target)
..()
if(!QDELETED(src))
empty_pod()
/obj/structure/transit_tube_pod/contents_explosion(severity, target)
for(var/atom/movable/AM in contents)
AM.ex_act(severity, target)
/obj/structure/transit_tube_pod/singularity_pull(S, current_size)
..()
if(current_size >= STAGE_FIVE)
deconstruct(FALSE)
/obj/structure/transit_tube_pod/container_resist(mob/living/user)
if(!user.incapacitated())
empty_pod()
return
if(!moving)
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
to_chat(user, "<span class='notice'>You start trying to escape from the pod...</span>")
if(do_after(user, 600, target = src))
to_chat(user, "<span class='notice'>You manage to open the pod.</span>")
empty_pod()
/obj/structure/transit_tube_pod/proc/empty_pod(atom/location)
if(!location)
location = get_turf(src)
for(var/atom/movable/M in contents)
M.forceMove(location)
update_icon()
/obj/structure/transit_tube_pod/Process_Spacemove()
if(moving) //No drifting while moving in the tubes
return 1
else
return ..()
/obj/structure/transit_tube_pod/proc/follow_tube()
set waitfor = 0
if(moving)
return
moving = 1
var/obj/structure/transit_tube/current_tube = null
var/next_dir
var/next_loc
var/last_delay = 0
var/exit_delay
for(var/obj/structure/transit_tube/tube in loc)
if(tube.has_exit(dir))
current_tube = tube
break
while(current_tube)
next_dir = current_tube.get_exit(dir)
if(!next_dir)
break
exit_delay = current_tube.exit_delay(src, dir)
last_delay += exit_delay
sleep(exit_delay)
next_loc = get_step(loc, next_dir)
current_tube = null
for(var/obj/structure/transit_tube/tube in next_loc)
if(tube.has_entrance(next_dir))
current_tube = tube
break
if(current_tube == null)
setDir(next_dir)
Move(get_step(loc, dir), dir) // Allow collisions when leaving the tubes.
break
last_delay = current_tube.enter_delay(src, next_dir)
sleep(last_delay)
setDir(next_dir)
forceMove(next_loc) // When moving from one tube to another, skip collision and such.
density = current_tube.density
if(current_tube && current_tube.should_stop_pod(src, next_dir))
current_tube.pod_stopped(src, dir)
break
density = TRUE
moving = 0
var/obj/structure/transit_tube/TT = locate(/obj/structure/transit_tube) in loc
if(!TT || (!(dir in TT.tube_dirs) && !(turn(dir,180) in TT.tube_dirs))) //landed on a turf without transit tube or not in our direction
deconstruct(FALSE) //we automatically deconstruct the pod
/obj/structure/transit_tube_pod/return_air()
return air_contents
/obj/structure/transit_tube_pod/assume_air(datum/gas_mixture/giver)
return air_contents.merge(giver)
/obj/structure/transit_tube_pod/remove_air(amount)
return air_contents.remove(amount)
/obj/structure/transit_tube_pod/relaymove(mob/mob, direction)
if(istype(mob) && mob.client)
if(!moving)
for(var/obj/structure/transit_tube/station/station in loc)
if(!station.pod_moving)
if(direction == turn(station.boarding_dir,180))
if(station.open_status == STATION_TUBE_OPEN)
mob.forceMove(loc)
update_icon()
else
station.open_animation()
else if(direction in station.tube_dirs)
setDir(direction)
station.launch_pod()
return
for(var/obj/structure/transit_tube/TT in loc)
if(dir in TT.tube_dirs)
if(TT.has_exit(direction))
setDir(direction)
return
/obj/structure/transit_tube_pod/return_temperature()
return air_contents.temperature
+141
View File
@@ -0,0 +1,141 @@
/obj/structure/trap
name = "IT'S A TRAP"
desc = "Stepping on me is a guaranteed bad day."
icon = 'icons/obj/hand_of_god_structures.dmi'
icon_state = "trap"
density = FALSE
anchored = TRUE
alpha = 30 //initially quite hidden when not "recharging"
var/last_trigger = 0
var/time_between_triggers = 600 //takes a minute to recharge
var/charges = INFINITY
var/list/static/ignore_typecache
var/list/mob/immune_minds = list()
var/datum/effect_system/spark_spread/spark_system
/obj/structure/trap/Initialize(mapload)
. = ..()
spark_system = new
spark_system.set_up(4,1,src)
spark_system.attach(src)
if(!ignore_typecache)
ignore_typecache = typecacheof(list(
/obj/effect,
/mob/dead))
/obj/structure/trap/Destroy()
qdel(spark_system)
spark_system = null
. = ..()
/obj/structure/trap/examine(mob/user)
. = ..()
if(!isliving(user))
return
if(user.mind && user.mind in immune_minds)
return
if(get_dist(user, src) <= 1)
to_chat(user, "<span class='notice'>You reveal [src]!</span>")
flare()
/obj/structure/trap/proc/flare()
// Makes the trap visible, and starts the cooldown until it's
// able to be triggered again.
visible_message("<span class='warning'>[src] flares brightly!</span>")
spark_system.start()
alpha = 200
last_trigger = world.time
charges--
if(charges <= 0)
animate(src, alpha = 0, time = 10)
QDEL_IN(src, 10)
else
animate(src, alpha = initial(alpha), time = time_between_triggers)
/obj/structure/trap/Crossed(atom/movable/AM)
if(last_trigger + time_between_triggers > world.time)
return
// Don't want the traps triggered by sparks, ghosts or projectiles.
if(is_type_in_typecache(AM, ignore_typecache))
return
if(ismob(AM))
var/mob/M = AM
if(M.mind in immune_minds)
return
if(M.anti_magic_check())
flare()
if(charges <= 0)
return
flare()
if(isliving(AM))
trap_effect(AM)
/obj/structure/trap/proc/trap_effect(mob/living/L)
return
/obj/structure/trap/stun
name = "shock trap"
desc = "A trap that will shock and render you immobile. You'd better avoid it."
icon_state = "trap-shock"
/obj/structure/trap/stun/trap_effect(mob/living/L)
L.electrocute_act(30, src, safety=1) // electrocute act does a message.
L.Knockdown(100)
/obj/structure/trap/fire
name = "flame trap"
desc = "A trap that will set you ablaze. You'd better avoid it."
icon_state = "trap-fire"
/obj/structure/trap/fire/trap_effect(mob/living/L)
to_chat(L, "<span class='danger'><B>Spontaneous combustion!</B></span>")
L.Knockdown(20)
/obj/structure/trap/fire/flare()
..()
new /obj/effect/hotspot(get_turf(src))
/obj/structure/trap/chill
name = "frost trap"
desc = "A trap that will chill you to the bone. You'd better avoid it."
icon_state = "trap-frost"
/obj/structure/trap/chill/trap_effect(mob/living/L)
to_chat(L, "<span class='danger'><B>You're frozen solid!</B></span>")
L.Knockdown(20)
L.adjust_bodytemperature(-300)
L.apply_status_effect(/datum/status_effect/freon)
/obj/structure/trap/damage
name = "earth trap"
desc = "A trap that will summon a small earthquake, just for you. You'd better avoid it."
icon_state = "trap-earth"
/obj/structure/trap/damage/trap_effect(mob/living/L)
to_chat(L, "<span class='danger'><B>The ground quakes beneath your feet!</B></span>")
L.Knockdown(100)
L.adjustBruteLoss(35)
/obj/structure/trap/damage/flare()
..()
var/obj/structure/flora/rock/giant_rock = new(get_turf(src))
QDEL_IN(giant_rock, 200)
/obj/structure/trap/ward
name = "divine ward"
desc = "A divine barrier, It looks like you could destroy it with enough effort, or wait for it to dissipate..."
icon_state = "ward"
density = TRUE
time_between_triggers = 1200 //Exists for 2 minutes
/obj/structure/trap/ward/New()
..()
QDEL_IN(src, time_between_triggers)
+685
View File
@@ -0,0 +1,685 @@
/obj/structure/toilet
name = "toilet"
desc = "The HT-451, a torque rotation-based, waste disposal unit for small matter. This one seems remarkably clean."
icon = 'icons/obj/watercloset.dmi'
icon_state = "toilet00"
density = FALSE
anchored = TRUE
var/open = FALSE //if the lid is up
var/cistern = 0 //if the cistern bit is open
var/w_items = 0 //the combined w_class of all the items in the cistern
var/mob/living/swirlie = null //the mob being given a swirlie
/obj/structure/toilet/Initialize()
. = ..()
open = round(rand(0, 1))
update_icon()
/obj/structure/toilet/attack_hand(mob/living/user)
. = ..()
if(.)
return
if(swirlie)
user.changeNext_move(CLICK_CD_MELEE)
playsound(src.loc, "swing_hit", 25, 1)
swirlie.visible_message("<span class='danger'>[user] slams the toilet seat onto [swirlie]'s head!</span>", "<span class='userdanger'>[user] slams the toilet seat onto your head!</span>", "<span class='italics'>You hear reverberating porcelain.</span>")
swirlie.adjustBruteLoss(5)
else if(user.pulling && user.a_intent == INTENT_GRAB && isliving(user.pulling))
user.changeNext_move(CLICK_CD_MELEE)
var/mob/living/GM = user.pulling
if(user.grab_state >= GRAB_AGGRESSIVE)
if(GM.loc != get_turf(src))
to_chat(user, "<span class='warning'>[GM] needs to be on [src]!</span>")
return
if(!swirlie)
if(open)
GM.visible_message("<span class='danger'>[user] starts to give [GM] a swirlie!</span>", "<span class='userdanger'>[user] starts to give you a swirlie...</span>")
swirlie = GM
if(do_after(user, 30, 0, target = src))
GM.visible_message("<span class='danger'>[user] gives [GM] a swirlie!</span>", "<span class='userdanger'>[user] gives you a swirlie!</span>", "<span class='italics'>You hear a toilet flushing.</span>")
if(iscarbon(GM))
var/mob/living/carbon/C = GM
if(!C.internal)
C.adjustOxyLoss(5)
else
GM.adjustOxyLoss(5)
swirlie = null
else
playsound(src.loc, 'sound/effects/bang.ogg', 25, 1)
GM.visible_message("<span class='danger'>[user] slams [GM.name] into [src]!</span>", "<span class='userdanger'>[user] slams you into [src]!</span>")
GM.adjustBruteLoss(5)
else
to_chat(user, "<span class='warning'>You need a tighter grip!</span>")
else if(cistern && !open && user.CanReach(src))
if(!contents.len)
to_chat(user, "<span class='notice'>The cistern is empty.</span>")
else
var/obj/item/I = pick(contents)
if(ishuman(user))
user.put_in_hands(I)
else
I.forceMove(drop_location())
to_chat(user, "<span class='notice'>You find [I] in the cistern.</span>")
w_items -= I.w_class
else
open = !open
update_icon()
/obj/structure/toilet/update_icon()
icon_state = "toilet[open][cistern]"
/obj/structure/toilet/attackby(obj/item/I, mob/living/user, params)
if(istype(I, /obj/item/crowbar))
to_chat(user, "<span class='notice'>You start to [cistern ? "replace the lid on the cistern" : "lift the lid off the cistern"]...</span>")
playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 50, 1)
if(I.use_tool(src, user, 30))
user.visible_message("[user] [cistern ? "replaces the lid on the cistern" : "lifts the lid off the cistern"]!", "<span class='notice'>You [cistern ? "replace the lid on the cistern" : "lift the lid off the cistern"]!</span>", "<span class='italics'>You hear grinding porcelain.</span>")
cistern = !cistern
update_icon()
else if(cistern)
if(user.a_intent != INTENT_HARM)
if(I.w_class > WEIGHT_CLASS_NORMAL)
to_chat(user, "<span class='warning'>[I] does not fit!</span>")
return
if(w_items + I.w_class > WEIGHT_CLASS_HUGE)
to_chat(user, "<span class='warning'>The cistern is full!</span>")
return
if(!user.transferItemToLoc(I, src))
to_chat(user, "<span class='warning'>\The [I] is stuck to your hand, you cannot put it in the cistern!</span>")
return
w_items += I.w_class
to_chat(user, "<span class='notice'>You carefully place [I] into the cistern.</span>")
else if(istype(I, /obj/item/reagent_containers))
if (!open)
return
var/obj/item/reagent_containers/RG = I
RG.reagents.add_reagent("water", min(RG.volume - RG.reagents.total_volume, RG.amount_per_transfer_from_this))
to_chat(user, "<span class='notice'>You fill [RG] from [src]. Gross.</span>")
else
return ..()
/obj/structure/toilet/secret
var/obj/item/secret
var/secret_type = null
/obj/structure/toilet/secret/Initialize(mapload)
. = ..()
if (secret_type)
secret = new secret_type(src)
secret.desc += " It's a secret!"
w_items += secret.w_class
contents += secret
/obj/structure/urinal
name = "urinal"
desc = "The HU-452, an experimental urinal. Comes complete with experimental urinal cake."
icon = 'icons/obj/watercloset.dmi'
icon_state = "urinal"
density = FALSE
anchored = TRUE
var/exposed = 0 // can you currently put an item inside
var/obj/item/hiddenitem = null // what's in the urinal
/obj/structure/urinal/New()
..()
hiddenitem = new /obj/item/reagent_containers/food/urinalcake
/obj/structure/urinal/attack_hand(mob/user)
. = ..()
if(.)
return
if(user.pulling && user.a_intent == INTENT_GRAB && isliving(user.pulling))
var/mob/living/GM = user.pulling
if(user.grab_state >= GRAB_AGGRESSIVE)
if(GM.loc != get_turf(src))
to_chat(user, "<span class='notice'>[GM.name] needs to be on [src].</span>")
return
user.changeNext_move(CLICK_CD_MELEE)
user.visible_message("<span class='danger'>[user] slams [GM] into [src]!</span>", "<span class='danger'>You slam [GM] into [src]!</span>")
GM.adjustBruteLoss(8)
else
to_chat(user, "<span class='warning'>You need a tighter grip!</span>")
else if(exposed)
if(!hiddenitem)
to_chat(user, "<span class='notice'>There is nothing in the drain holder.</span>")
else
if(ishuman(user))
user.put_in_hands(hiddenitem)
else
hiddenitem.forceMove(get_turf(src))
to_chat(user, "<span class='notice'>You fish [hiddenitem] out of the drain enclosure.</span>")
hiddenitem = null
else
..()
/obj/structure/urinal/attackby(obj/item/I, mob/living/user, params)
if(exposed)
if (hiddenitem)
to_chat(user, "<span class='warning'>There is already something in the drain enclosure.</span>")
return
if(I.w_class > 1)
to_chat(user, "<span class='warning'>[I] is too large for the drain enclosure.</span>")
return
if(!user.transferItemToLoc(I, src))
to_chat(user, "<span class='warning'>\[I] is stuck to your hand, you cannot put it in the drain enclosure!</span>")
return
hiddenitem = I
to_chat(user, "<span class='notice'>You place [I] into the drain enclosure.</span>")
else
return ..()
/obj/structure/urinal/screwdriver_act(mob/living/user, obj/item/I)
if(..())
return TRUE
to_chat(user, "<span class='notice'>You start to [exposed ? "screw the cap back into place" : "unscrew the cap to the drain protector"]...</span>")
playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 50, 1)
if(I.use_tool(src, user, 20))
user.visible_message("[user] [exposed ? "screws the cap back into place" : "unscrew the cap to the drain protector"]!",
"<span class='notice'>You [exposed ? "screw the cap back into place" : "unscrew the cap on the drain"]!</span>",
"<span class='italics'>You hear metal and squishing noises.</span>")
exposed = !exposed
return TRUE
/obj/item/reagent_containers/food/urinalcake
name = "urinal cake"
desc = "The noble urinal cake, protecting the station's pipes from the station's pee. Do not eat."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "urinalcake"
w_class = WEIGHT_CLASS_TINY
list_reagents = list("chlorine" = 3, "ammonia" = 1)
/obj/item/reagent_containers/food/urinalcake/attack_self(mob/living/user)
user.visible_message("<span class='notice'>[user] squishes [src]!</span>", "<span class='notice'>You squish [src].</span>", "<i>You hear a squish.</i>")
icon_state = "urinalcake_squish"
addtimer(VARSET_CALLBACK(src, icon_state, "urinalcake"), 8)
/obj/machinery/shower
name = "shower"
desc = "The HS-451. Installed in the 2550s by the Nanotrasen Hygiene Division."
icon = 'icons/obj/watercloset.dmi'
icon_state = "shower"
density = FALSE
use_power = NO_POWER_USE
var/on = FALSE
var/obj/effect/mist/mymist = null
var/ismist = 0 //needs a var so we can make it linger~
var/watertemp = "normal" //freezing, normal, or boiling
var/datum/looping_sound/showering/soundloop
/obj/machinery/shower/Initialize()
. = ..()
soundloop = new(list(src), FALSE)
/obj/machinery/shower/Destroy()
QDEL_NULL(soundloop)
return ..()
/obj/effect/mist
name = "mist"
icon = 'icons/obj/watercloset.dmi'
icon_state = "mist"
layer = FLY_LAYER
anchored = TRUE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
/obj/machinery/shower/interact(mob/M)
on = !on
update_icon()
add_fingerprint(M)
if(on)
START_PROCESSING(SSmachines, src)
soundloop.start()
wash_turf()
for(var/atom/movable/G in loc)
SEND_SIGNAL(G, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
if(isliving(G))
var/mob/living/L = G
wash_mob(L)
else if(isobj(G)) // Skip the light objects
wash_obj(G)
else
soundloop.stop()
if(isopenturf(loc))
var/turf/open/tile = loc
tile.MakeSlippery(TURF_WET_WATER, min_wet_time = 5 SECONDS, wet_time_to_add = 1 SECONDS)
/obj/machinery/shower/attackby(obj/item/I, mob/user, params)
if(I.type == /obj/item/analyzer)
to_chat(user, "<span class='notice'>The water temperature seems to be [watertemp].</span>")
else
return ..()
/obj/machinery/shower/wrench_act(mob/living/user, obj/item/I)
to_chat(user, "<span class='notice'>You begin to adjust the temperature valve with \the [I]...</span>")
if(I.use_tool(src, user, 50))
switch(watertemp)
if("normal")
watertemp = "freezing"
if("freezing")
watertemp = "boiling"
if("boiling")
watertemp = "normal"
user.visible_message("<span class='notice'>[user] adjusts the shower with \the [I].</span>", "<span class='notice'>You adjust the shower with \the [I] to [watertemp] temperature.</span>")
log_game("[key_name(user)] has wrenched a shower to [watertemp] at ([x],[y],[z])")
add_hiddenprint(user)
return TRUE
/obj/machinery/shower/update_icon() //this is terribly unreadable, but basically it makes the shower mist up
cut_overlays() //once it's been on for a while, in addition to handling the water overlay.
if(mymist)
qdel(mymist)
if(on)
add_overlay(mutable_appearance('icons/obj/watercloset.dmi', "water", ABOVE_MOB_LAYER))
if(watertemp == "freezing")
return
if(!ismist)
spawn(50)
if(src && on)
ismist = 1
mymist = new /obj/effect/mist(loc)
else
ismist = 1
mymist = new /obj/effect/mist(loc)
else if(ismist)
ismist = 1
mymist = new /obj/effect/mist(loc)
spawn(250)
if(!on && mymist)
qdel(mymist)
ismist = 0
/obj/machinery/shower/Crossed(atom/movable/AM)
..()
if(on)
if(isliving(AM))
var/mob/living/L = AM
if(wash_mob(L)) //it's a carbon mob.
var/mob/living/carbon/C = L
C.slip(80,null,NO_SLIP_WHEN_WALKING)
else if(isobj(AM))
wash_obj(AM)
/obj/machinery/shower/proc/wash_obj(obj/O)
. = SEND_SIGNAL(O, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
. = O.clean_blood()
O.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
if(isitem(O))
var/obj/item/I = O
I.acid_level = 0
I.extinguish()
/obj/machinery/shower/proc/wash_turf()
if(isturf(loc))
var/turf/tile = loc
tile.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
tile.clean_blood()
SEND_SIGNAL(tile, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
for(var/obj/effect/E in tile)
if(is_cleanable(E))
qdel(E)
/obj/machinery/shower/proc/wash_mob(mob/living/L)
SEND_SIGNAL(L, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
L.wash_cream()
L.ExtinguishMob()
L.adjust_fire_stacks(-20) //Douse ourselves with water to avoid fire more easily
L.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "shower", /datum/mood_event/nice_shower)
if(iscarbon(L))
var/mob/living/carbon/M = L
. = TRUE
check_heat(M)
for(var/obj/item/I in M.held_items)
wash_obj(I)
if(M.back)
if(wash_obj(M.back))
M.update_inv_back(0)
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/washgloves = TRUE
var/washshoes = TRUE
var/washmask = TRUE
var/washears = TRUE
var/washglasses = TRUE
if(H.wear_suit)
washgloves = !(H.wear_suit.flags_inv & HIDEGLOVES)
washshoes = !(H.wear_suit.flags_inv & HIDESHOES)
if(H.head)
washmask = !(H.head.flags_inv & HIDEMASK)
washglasses = !(H.head.flags_inv & HIDEEYES)
washears = !(H.head.flags_inv & HIDEEARS)
if(H.wear_mask)
if (washears)
washears = !(H.wear_mask.flags_inv & HIDEEARS)
if (washglasses)
washglasses = !(H.wear_mask.flags_inv & HIDEEYES)
if(H.head && wash_obj(H.head))
H.update_inv_head()
if(H.wear_suit && wash_obj(H.wear_suit))
H.update_inv_wear_suit()
else if(H.w_uniform && wash_obj(H.w_uniform))
H.update_inv_w_uniform()
if(washgloves)
H.clean_blood()
SEND_SIGNAL(H, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
if(H.shoes && washshoes && wash_obj(H.shoes))
H.update_inv_shoes()
if(H.wear_mask && washmask && wash_obj(H.wear_mask))
H.update_inv_wear_mask()
else
H.lip_style = null
H.update_body()
if(H.glasses && washglasses && wash_obj(H.glasses))
H.update_inv_glasses()
if(H.ears && washears && wash_obj(H.ears))
H.update_inv_ears()
if(H.belt && wash_obj(H.belt))
H.update_inv_belt()
else
if(M.wear_mask && wash_obj(M.wear_mask))
M.update_inv_wear_mask(0)
M.clean_blood()
SEND_SIGNAL(M, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
else
L.clean_blood()
SEND_SIGNAL(L, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
/obj/machinery/shower/proc/contamination_cleanse(atom/movable/thing)
var/datum/component/radioactive/healthy_green_glow = thing.GetComponent(/datum/component/radioactive)
if(!healthy_green_glow || QDELETED(healthy_green_glow))
return
var/strength = healthy_green_glow.strength
if(strength <= RAD_BACKGROUND_RADIATION)
qdel(healthy_green_glow)
return
healthy_green_glow.strength = max(strength-1, 0)
/obj/machinery/shower/process()
if(on)
wash_turf()
for(var/atom/movable/AM in loc)
if(isliving(AM))
wash_mob(AM)
else if(isobj(AM))
wash_obj(AM)
contamination_cleanse(AM)
else
return PROCESS_KILL
/obj/machinery/shower/deconstruct(disassembled = TRUE)
new /obj/item/stack/sheet/metal (loc, 3)
qdel(src)
/obj/machinery/shower/proc/check_heat(mob/living/carbon/C)
if(watertemp == "freezing")
C.adjust_bodytemperature(-80, 80)
to_chat(C, "<span class='warning'>The water is freezing!</span>")
else if(watertemp == "boiling")
C.adjust_bodytemperature(35, 0, 500)
C.adjustFireLoss(5)
to_chat(C, "<span class='danger'>The water is searing!</span>")
/obj/item/bikehorn/rubberducky
name = "rubber ducky"
desc = "Rubber ducky you're so fine, you make bathtime lots of fuuun. Rubber ducky I'm awfully fooooond of yooooouuuu~" //thanks doohl
icon = 'icons/obj/watercloset.dmi'
icon_state = "rubberducky"
item_state = "rubberducky"
/obj/structure/sink
name = "sink"
icon = 'icons/obj/watercloset.dmi'
icon_state = "sink"
desc = "A sink used for washing one's hands and face."
anchored = TRUE
var/busy = FALSE //Something's being washed at the moment
var/dispensedreagent = "water" // for whenever plumbing happens
/obj/structure/sink/attack_hand(mob/living/user)
. = ..()
if(.)
return
if(!user || !istype(user))
return
if(!iscarbon(user))
return
if(!Adjacent(user))
return
if(busy)
to_chat(user, "<span class='notice'>Someone's already washing here.</span>")
return
var/selected_area = parse_zone(user.zone_selected)
var/washing_face = 0
if(selected_area in list(BODY_ZONE_HEAD, BODY_ZONE_PRECISE_MOUTH, BODY_ZONE_PRECISE_EYES))
washing_face = 1
user.visible_message("<span class='notice'>[user] starts washing [user.p_their()] [washing_face ? "face" : "hands"]...</span>", \
"<span class='notice'>You start washing your [washing_face ? "face" : "hands"]...</span>")
busy = TRUE
if(!do_after(user, 40, target = src))
busy = FALSE
return
busy = FALSE
user.visible_message("<span class='notice'>[user] washes [user.p_their()] [washing_face ? "face" : "hands"] using [src].</span>", \
"<span class='notice'>You wash your [washing_face ? "face" : "hands"] using [src].</span>")
if(washing_face)
if(ishuman(user))
var/mob/living/carbon/human/H = user
H.lip_style = null //Washes off lipstick
H.lip_color = initial(H.lip_color)
H.wash_cream()
H.regenerate_icons()
user.drowsyness = max(user.drowsyness - rand(2,3), 0) //Washing your face wakes you up if you're falling asleep
else
SEND_SIGNAL(user, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
user.clean_blood()
/obj/structure/sink/attackby(obj/item/O, mob/living/user, params)
if(busy)
to_chat(user, "<span class='warning'>Someone's already washing here!</span>")
return
if(istype(O, /obj/item/reagent_containers))
var/obj/item/reagent_containers/RG = O
if(RG.is_refillable())
if(!RG.reagents.holder_full())
RG.reagents.add_reagent(dispensedreagent, min(RG.volume - RG.reagents.total_volume, RG.amount_per_transfer_from_this))
to_chat(user, "<span class='notice'>You fill [RG] from [src].</span>")
return TRUE
to_chat(user, "<span class='notice'>\The [RG] is full.</span>")
return FALSE
if(istype(O, /obj/item/melee/baton))
var/obj/item/melee/baton/B = O
if(B.cell)
if(B.cell.charge > 0 && B.status == 1)
flick("baton_active", src)
var/stunforce = B.stunforce
user.Knockdown(stunforce)
user.stuttering = stunforce/20
B.deductcharge(B.hitcost)
user.visible_message("<span class='warning'>[user] shocks [user.p_them()]self while attempting to wash the active [B.name]!</span>", \
"<span class='userdanger'>You unwisely attempt to wash [B] while it's still on.</span>")
playsound(src, "sparks", 50, 1)
return
if(istype(O, /obj/item/mop))
O.reagents.add_reagent("[dispensedreagent]", 5)
to_chat(user, "<span class='notice'>You wet [O] in [src].</span>")
playsound(loc, 'sound/effects/slosh.ogg', 25, 1)
return
if(istype(O, /obj/item/stack/medical/gauze))
var/obj/item/stack/medical/gauze/G = O
new /obj/item/reagent_containers/rag(src.loc)
to_chat(user, "<span class='notice'>You tear off a strip of gauze and make a rag.</span>")
G.use(1)
return
if(!istype(O))
return
if(O.item_flags & ABSTRACT) //Abstract items like grabs won't wash. No-drop items will though because it's still technically an item in your hand.
return
if(user.a_intent != INTENT_HARM)
to_chat(user, "<span class='notice'>You start washing [O]...</span>")
busy = TRUE
if(!do_after(user, 40, target = src))
busy = FALSE
return 1
busy = FALSE
SEND_SIGNAL(O, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
O.clean_blood()
O.acid_level = 0
create_reagents(5)
reagents.add_reagent(dispensedreagent, 5)
reagents.reaction(O, TOUCH)
user.visible_message("<span class='notice'>[user] washes [O] using [src].</span>", \
"<span class='notice'>You wash [O] using [src].</span>")
return 1
else
return ..()
/obj/structure/sink/deconstruct(disassembled = TRUE)
new /obj/item/stack/sheet/metal (loc, 3)
qdel(src)
/obj/structure/sink/kitchen
name = "kitchen sink"
icon_state = "sink_alt"
/obj/structure/sink/puddle //splishy splashy ^_^
name = "puddle"
desc = "A puddle used for washing one's hands and face."
icon_state = "puddle"
resistance_flags = UNACIDABLE
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/structure/sink/puddle/attack_hand(mob/M)
icon_state = "puddle-splash"
. = ..()
icon_state = "puddle"
/obj/structure/sink/puddle/attackby(obj/item/O, mob/user, params)
icon_state = "puddle-splash"
. = ..()
icon_state = "puddle"
/obj/structure/sink/puddle/deconstruct(disassembled = TRUE)
qdel(src)
//Shower Curtains//
//Defines used are pre-existing in layers.dm//
/obj/structure/curtain
name = "curtain"
desc = "Contains less than 1% mercury."
icon = 'icons/obj/watercloset.dmi'
icon_state = "open"
color = "#ACD1E9" //Default color, didn't bother hardcoding other colors, mappers can and should easily change it.
alpha = 200 //Mappers can also just set this to 255 if they want curtains that can't be seen through
layer = SIGN_LAYER
anchored = TRUE
opacity = 0
density = FALSE
var/open = TRUE
/obj/structure/curtain/proc/toggle()
open = !open
update_icon()
/obj/structure/curtain/update_icon()
if(!open)
icon_state = "closed"
layer = WALL_OBJ_LAYER
density = TRUE
open = FALSE
else
icon_state = "open"
layer = SIGN_LAYER
density = FALSE
open = TRUE
/obj/structure/curtain/attackby(obj/item/W, mob/user)
if (istype(W, /obj/item/toy/crayon))
color = input(user,"","Choose Color",color) as color
else
return ..()
/obj/structure/curtain/wrench_act(mob/living/user, obj/item/I)
default_unfasten_wrench(user, I, 50)
return TRUE
/obj/structure/curtain/wirecutter_act(mob/living/user, obj/item/I)
if(anchored)
return TRUE
user.visible_message("<span class='warning'>[user] cuts apart [src].</span>",
"<span class='notice'>You start to cut apart [src].</span>", "You hear cutting.")
if(I.use_tool(src, user, 50, volume=100) && !anchored)
to_chat(user, "<span class='notice'>You cut apart [src].</span>")
deconstruct()
return TRUE
/obj/structure/curtain/attack_hand(mob/user)
. = ..()
if(.)
return
playsound(loc, 'sound/effects/curtain.ogg', 50, 1)
toggle()
/obj/structure/curtain/deconstruct(disassembled = TRUE)
new /obj/item/stack/sheet/cloth (loc, 2)
new /obj/item/stack/sheet/plastic (loc, 2)
new /obj/item/stack/rods (loc, 1)
qdel(src)
/obj/structure/curtain/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
if(BRUTE)
if(damage_amount)
playsound(src.loc, 'sound/weapons/slash.ogg', 80, 1)
else
playsound(loc, 'sound/weapons/tap.ogg', 50, 1)
if(BURN)
playsound(loc, 'sound/items/welder.ogg', 80, 1)
+749
View File
@@ -0,0 +1,749 @@
/obj/structure/window
name = "window"
desc = "A window."
icon_state = "window"
density = TRUE
layer = ABOVE_OBJ_LAYER //Just above doors
pressure_resistance = 4*ONE_ATMOSPHERE
anchored = TRUE //initially is 0 for tile smoothing
flags_1 = ON_BORDER_1
max_integrity = 25
var/ini_dir = null
var/state = WINDOW_OUT_OF_FRAME
var/reinf = FALSE
var/heat_resistance = 800
var/decon_speed = 30
var/wtype = "glass"
var/fulltile = FALSE
var/glass_type = /obj/item/stack/sheet/glass
var/glass_amount = 1
var/mutable_appearance/crack_overlay
can_be_unanchored = TRUE
resistance_flags = ACID_PROOF
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100)
CanAtmosPass = ATMOS_PASS_PROC
var/real_explosion_block //ignore this, just use explosion_block
var/breaksound = "shatter"
var/hitsound = 'sound/effects/Glasshit.ogg'
rad_insulation = RAD_VERY_LIGHT_INSULATION
rad_flags = RAD_PROTECT_CONTENTS
/obj/structure/window/examine(mob/user)
..()
if(reinf)
if(anchored && state == WINDOW_SCREWED_TO_FRAME)
to_chat(user, "<span class='notice'>The window is <b>screwed</b> to the frame.</span>")
else if(anchored && state == WINDOW_IN_FRAME)
to_chat(user, "<span class='notice'>The window is <i>unscrewed</i> but <b>pried</b> into the frame.</span>")
else if(anchored && state == WINDOW_OUT_OF_FRAME)
to_chat(user, "<span class='notice'>The window is out of the frame, but could be <i>pried</i> in. It is <b>screwed</b> to the floor.</span>")
else if(!anchored)
to_chat(user, "<span class='notice'>The window is <i>unscrewed</i> from the floor, and could be deconstructed by <b>wrenching</b>.</span>")
else
if(anchored)
to_chat(user, "<span class='notice'>The window is <b>screwed</b> to the floor.</span>")
else
to_chat(user, "<span class='notice'>The window is <i>unscrewed</i> from the floor, and could be deconstructed by <b>wrenching</b>.</span>")
/obj/structure/window/Initialize(mapload, direct)
. = ..()
if(direct)
setDir(direct)
if(reinf && anchored)
state = WINDOW_SCREWED_TO_FRAME
ini_dir = dir
air_update_turf(1)
if(fulltile)
setDir()
//windows only block while reinforced and fulltile, so we'll use the proc
real_explosion_block = explosion_block
explosion_block = EXPLOSION_BLOCK_PROC
/obj/structure/window/ComponentInitialize()
. = ..()
AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS ,null,CALLBACK(src, .proc/can_be_rotated),CALLBACK(src,.proc/after_rotation))
/obj/structure/window/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
switch(the_rcd.mode)
if(RCD_DECONSTRUCT)
return list("mode" = RCD_DECONSTRUCT, "delay" = 20, "cost" = 5)
return FALSE
/obj/structure/window/rcd_act(mob/user, var/obj/item/construction/rcd/the_rcd)
switch(the_rcd.mode)
if(RCD_DECONSTRUCT)
to_chat(user, "<span class='notice'>You deconstruct the window.</span>")
qdel(src)
return TRUE
return FALSE
/obj/structure/window/narsie_act()
add_atom_colour(NARSIE_WINDOW_COLOUR, FIXED_COLOUR_PRIORITY)
/obj/structure/window/ratvar_act()
if(!fulltile)
new/obj/structure/window/reinforced/clockwork(get_turf(src), dir)
else
new/obj/structure/window/reinforced/clockwork/fulltile(get_turf(src))
qdel(src)
/obj/structure/window/singularity_pull(S, current_size)
..()
if(current_size >= STAGE_FIVE)
deconstruct(FALSE)
/obj/structure/window/setDir(direct)
if(!fulltile)
..()
else
..(FULLTILE_WINDOW_DIR)
/obj/structure/window/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && (mover.pass_flags & PASSGLASS))
return 1
if(dir == FULLTILE_WINDOW_DIR)
return 0 //full tile window, you can't move into it!
if(get_dir(loc, target) == dir)
return !density
if(istype(mover, /obj/structure/window))
var/obj/structure/window/W = mover
if(!valid_window_location(loc, W.ini_dir))
return FALSE
else if(istype(mover, /obj/structure/windoor_assembly))
var/obj/structure/windoor_assembly/W = mover
if(!valid_window_location(loc, W.ini_dir))
return FALSE
else if(istype(mover, /obj/machinery/door/window) && !valid_window_location(loc, mover.dir))
return FALSE
return 1
/obj/structure/window/CheckExit(atom/movable/O, turf/target)
if(istype(O) && (O.pass_flags & PASSGLASS))
return 1
if(get_dir(O.loc, target) == dir)
return 0
return 1
/obj/structure/window/attack_tk(mob/user)
user.changeNext_move(CLICK_CD_MELEE)
user.visible_message("<span class='notice'>Something knocks on [src].</span>")
add_fingerprint(user)
playsound(src, 'sound/effects/Glassknock.ogg', 50, 1)
/obj/structure/window/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
if(!can_be_reached(user))
return 1
. = ..()
/obj/structure/window/attack_hand(mob/user)
. = ..()
if(.)
return
if(!can_be_reached(user))
return
user.changeNext_move(CLICK_CD_MELEE)
user.visible_message("[user] knocks on [src].")
add_fingerprint(user)
playsound(src, 'sound/effects/Glassknock.ogg', 50, 1)
/obj/structure/window/attack_paw(mob/user)
return attack_hand(user)
/obj/structure/window/attack_generic(mob/user, damage_amount = 0, damage_type = BRUTE, damage_flag = 0, sound_effect = 1) //used by attack_alien, attack_animal, and attack_slime
if(!can_be_reached(user))
return
..()
/obj/structure/window/attackby(obj/item/I, mob/living/user, params)
if(!can_be_reached(user))
return 1 //skip the afterattack
add_fingerprint(user)
if(istype(I, /obj/item/weldingtool) && user.a_intent == INTENT_HELP)
if(obj_integrity < max_integrity)
if(!I.tool_start_check(user, amount=0))
return
to_chat(user, "<span class='notice'>You begin repairing [src]...</span>")
if(I.use_tool(src, user, 40, volume=50))
obj_integrity = max_integrity
update_nearby_icons()
to_chat(user, "<span class='notice'>You repair [src].</span>")
else
to_chat(user, "<span class='warning'>[src] is already in good condition!</span>")
return
if(!(flags_1&NODECONSTRUCT_1))
if(istype(I, /obj/item/screwdriver))
I.play_tool_sound(src, 75)
if(reinf)
if(state == WINDOW_SCREWED_TO_FRAME || state == WINDOW_IN_FRAME)
to_chat(user, "<span class='notice'>You begin to [state == WINDOW_SCREWED_TO_FRAME ? "unscrew the window from":"screw the window to"] the frame...</span>")
if(I.use_tool(src, user, decon_speed, extra_checks = CALLBACK(src, .proc/check_state_and_anchored, state, anchored)))
state = (state == WINDOW_IN_FRAME ? WINDOW_SCREWED_TO_FRAME : WINDOW_IN_FRAME)
to_chat(user, "<span class='notice'>You [state == WINDOW_IN_FRAME ? "unfasten the window from":"fasten the window to"] the frame.</span>")
else if(state == WINDOW_OUT_OF_FRAME)
to_chat(user, "<span class='notice'>You begin to [anchored ? "unscrew the frame from":"screw the frame to"] the floor...</span>")
if(I.use_tool(src, user, decon_speed, extra_checks = CALLBACK(src, .proc/check_state_and_anchored, state, anchored)))
setAnchored(!anchored)
to_chat(user, "<span class='notice'>You [anchored ? "fasten the frame to":"unfasten the frame from"] the floor.</span>")
else //if we're not reinforced, we don't need to check or update state
to_chat(user, "<span class='notice'>You begin to [anchored ? "unscrew the window from":"screw the window to"] the floor...</span>")
if(I.use_tool(src, user, decon_speed, extra_checks = CALLBACK(src, .proc/check_anchored, anchored)))
setAnchored(!anchored)
to_chat(user, "<span class='notice'>You [anchored ? "fasten the window to":"unfasten the window from"] the floor.</span>")
return
else if (istype(I, /obj/item/crowbar) && reinf && (state == WINDOW_OUT_OF_FRAME || state == WINDOW_IN_FRAME))
to_chat(user, "<span class='notice'>You begin to lever the window [state == WINDOW_OUT_OF_FRAME ? "into":"out of"] the frame...</span>")
I.play_tool_sound(src, 75)
if(I.use_tool(src, user, decon_speed, extra_checks = CALLBACK(src, .proc/check_state_and_anchored, state, anchored)))
state = (state == WINDOW_OUT_OF_FRAME ? WINDOW_IN_FRAME : WINDOW_OUT_OF_FRAME)
to_chat(user, "<span class='notice'>You pry the window [state == WINDOW_IN_FRAME ? "into":"out of"] the frame.</span>")
return
else if(istype(I, /obj/item/wrench) && !anchored)
I.play_tool_sound(src, 75)
to_chat(user, "<span class='notice'> You begin to disassemble [src]...</span>")
if(I.use_tool(src, user, decon_speed, extra_checks = CALLBACK(src, .proc/check_state_and_anchored, state, anchored)))
var/obj/item/stack/sheet/G = new glass_type(user.loc, glass_amount)
G.add_fingerprint(user)
playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
to_chat(user, "<span class='notice'>You successfully disassemble [src].</span>")
qdel(src)
return
return ..()
/obj/structure/window/setAnchored(anchorvalue)
..()
air_update_turf(TRUE)
update_nearby_icons()
/obj/structure/window/proc/check_state(checked_state)
if(state == checked_state)
return TRUE
/obj/structure/window/proc/check_anchored(checked_anchored)
if(anchored == checked_anchored)
return TRUE
/obj/structure/window/proc/check_state_and_anchored(checked_state, checked_anchored)
return check_state(checked_state) && check_anchored(checked_anchored)
/obj/structure/window/mech_melee_attack(obj/mecha/M)
if(!can_be_reached())
return
..()
/obj/structure/window/proc/can_be_reached(mob/user)
if(!fulltile)
if(get_dir(user,src) & dir)
for(var/obj/O in loc)
if(!O.CanPass(user, user.loc, 1))
return 0
return 1
/obj/structure/window/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1)
. = ..()
if(.) //received damage
update_nearby_icons()
/obj/structure/window/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
if(BRUTE)
if(damage_amount)
playsound(src, hitsound, 75, 1)
else
playsound(src, 'sound/weapons/tap.ogg', 50, 1)
if(BURN)
playsound(src, 'sound/items/Welder.ogg', 100, 1)
/obj/structure/window/deconstruct(disassembled = TRUE)
if(QDELETED(src))
return
if(!disassembled)
playsound(src, breaksound, 70, 1)
if(!(flags_1 & NODECONSTRUCT_1))
for(var/obj/item/shard/debris in spawnDebris(drop_location()))
transfer_fingerprints_to(debris) // transfer fingerprints to shards only
qdel(src)
update_nearby_icons()
/obj/structure/window/proc/spawnDebris(location)
. = list()
. += new /obj/item/shard(location)
. += new /obj/effect/decal/cleanable/glass(location)
if (reinf)
. += new /obj/item/stack/rods(location, (fulltile ? 2 : 1))
if (fulltile)
. += new /obj/item/shard(location)
/obj/structure/window/proc/can_be_rotated(mob/user,rotation_type)
if(anchored)
to_chat(user, "<span class='warning'>[src] cannot be rotated while it is fastened to the floor!</span>")
return FALSE
var/target_dir = turn(dir, rotation_type == ROTATION_CLOCKWISE ? -90 : 90)
if(!valid_window_location(loc, target_dir))
to_chat(user, "<span class='warning'>[src] cannot be rotated in that direction!</span>")
return FALSE
return TRUE
/obj/structure/window/proc/after_rotation(mob/user,rotation_type)
air_update_turf(1)
ini_dir = dir
add_fingerprint(user)
/obj/structure/window/Destroy()
density = FALSE
air_update_turf(1)
update_nearby_icons()
return ..()
/obj/structure/window/Move()
var/turf/T = loc
. = ..()
setDir(ini_dir)
move_update_air(T)
/obj/structure/window/CanAtmosPass(turf/T)
if(!anchored || !density)
return TRUE
return !(FULLTILE_WINDOW_DIR == dir || dir == get_dir(loc, T))
//This proc is used to update the icons of nearby windows.
/obj/structure/window/proc/update_nearby_icons()
update_icon()
if(smooth)
queue_smooth_neighbors(src)
//merges adjacent full-tile windows into one
/obj/structure/window/update_icon()
if(!QDELETED(src))
if(!fulltile)
return
var/ratio = obj_integrity / max_integrity
ratio = CEILING(ratio*4, 1) * 25
if(smooth)
queue_smooth(src)
cut_overlay(crack_overlay)
if(ratio > 75)
return
crack_overlay = mutable_appearance('icons/obj/structures.dmi', "damage[ratio]", -(layer+0.1))
add_overlay(crack_overlay)
/obj/structure/window/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > (T0C + heat_resistance))
take_damage(round(exposed_volume / 100), BURN, 0, 0)
..()
/obj/structure/window/get_dumping_location(obj/item/storage/source,mob/user)
return null
/obj/structure/window/CanAStarPass(ID, to_dir)
if(!density)
return 1
if((dir == FULLTILE_WINDOW_DIR) || (dir == to_dir))
return 0
return 1
/obj/structure/window/GetExplosionBlock()
return reinf && fulltile ? real_explosion_block : 0
/obj/structure/window/spawner/east
dir = EAST
/obj/structure/window/spawner/west
dir = WEST
/obj/structure/window/spawner/north
dir = NORTH
/obj/structure/window/unanchored
anchored = FALSE
/obj/structure/window/reinforced
name = "reinforced window"
desc = "A window that is reinforced with metal rods."
icon_state = "rwindow"
reinf = TRUE
heat_resistance = 1600
armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 25, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 100)
max_integrity = 50
explosion_block = 1
glass_type = /obj/item/stack/sheet/rglass
rad_insulation = RAD_HEAVY_INSULATION
/obj/structure/window/reinforced/spawner/east
dir = EAST
/obj/structure/window/reinforced/spawner/west
dir = WEST
/obj/structure/window/reinforced/spawner/north
dir = NORTH
/obj/structure/window/reinforced/unanchored
anchored = FALSE
/obj/structure/window/plasma
name = "plasma window"
desc = "A window made out of a plasma-silicate alloy. It looks insanely tough to break and burn through."
icon_state = "plasmawindow"
reinf = FALSE
heat_resistance = 25000
armor = list("melee" = 75, "bullet" = 5, "laser" = 0, "energy" = 0, "bomb" = 45, "bio" = 100, "rad" = 100, "fire" = 99, "acid" = 100)
max_integrity = 150
explosion_block = 1
glass_type = /obj/item/stack/sheet/plasmaglass
rad_insulation = RAD_NO_INSULATION
/obj/structure/window/plasma/spawnDebris(location)
. = list()
. += new /obj/item/shard/plasma(location)
. += new /obj/effect/decal/cleanable/glass/plasma(location)
if (reinf)
. += new /obj/item/stack/rods(location, (fulltile ? 2 : 1))
if (fulltile)
. += new /obj/item/shard/plasma(location)
/obj/structure/window/plasma/spawner/east
dir = EAST
/obj/structure/window/plasma/spawner/west
dir = WEST
/obj/structure/window/plasma/spawner/north
dir = NORTH
/obj/structure/window/plasma/unanchored
anchored = FALSE
/obj/structure/window/plasma/reinforced
name = "reinforced plasma window"
desc = "A window made out of a plasma-silicate alloy and a rod matrix. It looks hopelessly tough to break and is most likely nigh fireproof."
icon_state = "plasmarwindow"
reinf = TRUE
heat_resistance = 50000
armor = list("melee" = 85, "bullet" = 20, "laser" = 0, "energy" = 0, "bomb" = 60, "bio" = 100, "rad" = 100, "fire" = 99, "acid" = 100)
max_integrity = 500
explosion_block = 2
glass_type = /obj/item/stack/sheet/plasmarglass
/obj/structure/window/plasma/reinforced/spawner/east
dir = EAST
/obj/structure/window/plasma/reinforced/spawner/west
dir = WEST
/obj/structure/window/plasma/reinforced/spawner/north
dir = NORTH
/obj/structure/window/plasma/reinforced/unanchored
anchored = FALSE
/obj/structure/window/reinforced/tinted
name = "tinted window"
icon_state = "twindow"
opacity = 1
/obj/structure/window/reinforced/tinted/frosted
name = "frosted window"
icon_state = "fwindow"
/* Full Tile Windows (more obj_integrity) */
/obj/structure/window/fulltile
icon = 'icons/obj/smooth_structures/window.dmi'
icon_state = "window"
dir = FULLTILE_WINDOW_DIR
max_integrity = 50
fulltile = TRUE
flags_1 = PREVENT_CLICK_UNDER_1
smooth = SMOOTH_TRUE
canSmoothWith = list(/obj/structure/window/fulltile, /obj/structure/window/reinforced/fulltile, /obj/structure/window/reinforced/tinted/fulltile, /obj/structure/window/plasma/fulltile, /obj/structure/window/plasma/reinforced/fulltile)
glass_amount = 2
/obj/structure/window/fulltile/unanchored
anchored = FALSE
/obj/structure/window/plasma/fulltile
icon = 'icons/obj/smooth_structures/plasma_window.dmi'
icon_state = "plasmawindow"
dir = FULLTILE_WINDOW_DIR
max_integrity = 300
fulltile = TRUE
flags_1 = PREVENT_CLICK_UNDER_1
smooth = SMOOTH_TRUE
canSmoothWith = list(/obj/structure/window/fulltile, /obj/structure/window/reinforced/fulltile, /obj/structure/window/reinforced/tinted/fulltile, /obj/structure/window/plasma/fulltile, /obj/structure/window/plasma/reinforced/fulltile)
glass_amount = 2
/obj/structure/window/plasma/fulltile/unanchored
anchored = FALSE
/obj/structure/window/plasma/reinforced/fulltile
icon = 'icons/obj/smooth_structures/rplasma_window.dmi'
icon_state = "rplasmawindow"
dir = FULLTILE_WINDOW_DIR
max_integrity = 1000
fulltile = TRUE
flags_1 = PREVENT_CLICK_UNDER_1
smooth = SMOOTH_TRUE
glass_amount = 2
/obj/structure/window/plasma/reinforced/fulltile/unanchored
anchored = FALSE
/obj/structure/window/reinforced/fulltile
icon = 'icons/obj/smooth_structures/reinforced_window.dmi'
icon_state = "r_window"
dir = FULLTILE_WINDOW_DIR
max_integrity = 100
fulltile = TRUE
flags_1 = PREVENT_CLICK_UNDER_1
smooth = SMOOTH_TRUE
canSmoothWith = list(/obj/structure/window/fulltile, /obj/structure/window/reinforced/fulltile, /obj/structure/window/reinforced/tinted/fulltile, /obj/structure/window/plasma/fulltile, /obj/structure/window/plasma/reinforced/fulltile)
level = 3
glass_amount = 2
/obj/structure/window/reinforced/fulltile/unanchored
anchored = FALSE
/obj/structure/window/reinforced/tinted/fulltile
icon = 'icons/obj/smooth_structures/tinted_window.dmi'
icon_state = "tinted_window"
dir = FULLTILE_WINDOW_DIR
fulltile = TRUE
flags_1 = PREVENT_CLICK_UNDER_1
smooth = SMOOTH_TRUE
canSmoothWith = list(/obj/structure/window/fulltile, /obj/structure/window/reinforced/fulltile, /obj/structure/window/reinforced/tinted/fulltile, /obj/structure/window/plasma/fulltile, /obj/structure/window/plasma/reinforced/fulltile)
level = 3
glass_amount = 2
/obj/structure/window/reinforced/fulltile/ice
icon = 'icons/obj/smooth_structures/rice_window.dmi'
icon_state = "ice_window"
max_integrity = 150
canSmoothWith = list(/obj/structure/window/fulltile, /obj/structure/window/reinforced/fulltile, /obj/structure/window/reinforced/tinted/fulltile, /obj/structure/window/plasma/fulltile, /obj/structure/window/plasma/reinforced/fulltile)
level = 3
glass_amount = 2
/obj/structure/window/shuttle
name = "shuttle window"
desc = "A reinforced, air-locked pod window."
icon = 'icons/obj/smooth_structures/shuttle_window.dmi'
icon_state = "shuttle_window"
dir = FULLTILE_WINDOW_DIR
max_integrity = 100
wtype = "shuttle"
fulltile = TRUE
flags_1 = PREVENT_CLICK_UNDER_1
reinf = TRUE
heat_resistance = 1600
armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 100)
smooth = SMOOTH_TRUE
canSmoothWith = null
explosion_block = 3
level = 3
glass_type = /obj/item/stack/sheet/titaniumglass
glass_amount = 2
/obj/structure/window/shuttle/narsie_act()
add_atom_colour("#3C3434", FIXED_COLOUR_PRIORITY)
/obj/structure/window/shuttle/tinted
opacity = TRUE
/obj/structure/window/shuttle/unanchored
anchored = FALSE
/obj/structure/window/plastitanium
name = "plastitanium window"
desc = "An evil looking window of plasma and titanium."
icon = 'icons/obj/smooth_structures/plastitanium_window.dmi'
icon_state = "plastitanium_window"
dir = FULLTILE_WINDOW_DIR
max_integrity = 100
wtype = "shuttle"
fulltile = TRUE
flags_1 = PREVENT_CLICK_UNDER_1
reinf = TRUE
heat_resistance = 1600
armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 100)
smooth = SMOOTH_TRUE
canSmoothWith = null
explosion_block = 3
level = 3
glass_type = /obj/item/stack/sheet/plastitaniumglass
glass_amount = 2
/obj/structure/window/plastitanium/unanchored
anchored = FALSE
/obj/structure/window/reinforced/clockwork
name = "brass window"
desc = "A paper-thin pane of translucent yet reinforced brass."
icon = 'icons/obj/smooth_structures/clockwork_window.dmi'
icon_state = "clockwork_window_single"
resistance_flags = FIRE_PROOF | ACID_PROOF
max_integrity = 80
armor = list("melee" = 60, "bullet" = 25, "laser" = 0, "energy" = 0, "bomb" = 25, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 100)
explosion_block = 2 //fancy AND hard to destroy. the most useful combination.
decon_speed = 40
glass_type = /obj/item/stack/tile/brass
glass_amount = 1
reinf = FALSE
var/made_glow = FALSE
/obj/structure/window/reinforced/clockwork/Initialize(mapload, direct)
. = ..()
change_construction_value(fulltile ? 2 : 1)
/obj/structure/window/reinforced/clockwork/spawnDebris(location)
. = list()
var/gearcount = fulltile ? 4 : 2
for(var/i in 1 to gearcount)
. += new /obj/item/clockwork/alloy_shards/medium/gear_bit(location)
/obj/structure/window/reinforced/clockwork/setDir(direct)
if(!made_glow)
var/obj/effect/E = new /obj/effect/temp_visual/ratvar/window/single(get_turf(src))
E.setDir(direct)
made_glow = TRUE
..()
/obj/structure/window/reinforced/clockwork/Destroy()
change_construction_value(fulltile ? -2 : -1)
return ..()
/obj/structure/window/reinforced/clockwork/ratvar_act()
if(GLOB.ratvar_awakens)
obj_integrity = max_integrity
update_icon()
/obj/structure/window/reinforced/clockwork/narsie_act()
take_damage(rand(25, 75), BRUTE)
if(!QDELETED(src))
var/previouscolor = color
color = "#960000"
animate(src, color = previouscolor, time = 8)
addtimer(CALLBACK(src, /atom/proc/update_atom_colour), 8)
/obj/structure/window/reinforced/clockwork/unanchored
anchored = FALSE
/obj/structure/window/reinforced/clockwork/fulltile
icon_state = "clockwork_window"
smooth = SMOOTH_TRUE
canSmoothWith = null
fulltile = TRUE
flags_1 = PREVENT_CLICK_UNDER_1
dir = FULLTILE_WINDOW_DIR
max_integrity = 120
level = 3
glass_amount = 2
/obj/structure/window/reinforced/clockwork/spawnDebris(location)
. = list()
for(var/i in 1 to 4)
. += new /obj/item/clockwork/alloy_shards/medium/gear_bit(location)
/obj/structure/window/reinforced/clockwork/Initialize(mapload, direct)
made_glow = TRUE
new /obj/effect/temp_visual/ratvar/window(get_turf(src))
return ..()
/obj/structure/window/reinforced/clockwork/fulltile/unanchored
anchored = FALSE
/obj/structure/window/paperframe
name = "paper frame"
desc = "A fragile separator made of thin wood and paper."
icon = 'icons/obj/smooth_structures/paperframes.dmi'
icon_state = "frame"
dir = FULLTILE_WINDOW_DIR
opacity = TRUE
max_integrity = 15
fulltile = TRUE
flags_1 = PREVENT_CLICK_UNDER_1
smooth = SMOOTH_TRUE
canSmoothWith = list(/obj/structure/window/paperframe, /obj/structure/mineral_door/paperframe)
glass_amount = 2
glass_type = /obj/item/stack/sheet/paperframes
heat_resistance = 233
decon_speed = 10
CanAtmosPass = ATMOS_PASS_YES
resistance_flags = FLAMMABLE
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
breaksound = 'sound/items/poster_ripped.ogg'
hitsound = 'sound/weapons/slashmiss.ogg'
var/static/mutable_appearance/torn = mutable_appearance('icons/obj/smooth_structures/paperframes.dmi',icon_state = "torn", layer = ABOVE_OBJ_LAYER - 0.1)
var/static/mutable_appearance/paper = mutable_appearance('icons/obj/smooth_structures/paperframes.dmi',icon_state = "paper", layer = ABOVE_OBJ_LAYER - 0.1)
/obj/structure/window/paperframe/Initialize()
. = ..()
update_icon()
/obj/structure/window/paperframe/spawnDebris(location)
. = list(new /obj/item/stack/sheet/mineral/wood(location))
for (var/i in 1 to rand(1,4))
. += new /obj/item/paper/natural(location)
/obj/structure/window/paperframe/attack_hand(mob/user)
. = ..()
if(.)
return
add_fingerprint(user)
if(user.a_intent != INTENT_HARM)
user.changeNext_move(CLICK_CD_MELEE)
user.visible_message("[user] knocks on [src].")
playsound(src, "pageturn", 50, 1)
else
take_damage(4,BRUTE,"melee", 0)
playsound(src, hitsound, 50, 1)
if(!QDELETED(src))
user.visible_message("<span class='danger'>[user] tears a hole in [src].</span>")
update_icon()
/obj/structure/window/paperframe/update_icon()
if(obj_integrity < max_integrity)
cut_overlay(paper)
add_overlay(torn)
set_opacity(FALSE)
else
cut_overlay(torn)
add_overlay(paper)
set_opacity(TRUE)
queue_smooth(src)
/obj/structure/window/paperframe/attackby(obj/item/W, mob/user)
if(W.get_temperature())
fire_act(W.get_temperature())
return
if(user.a_intent == INTENT_HARM)
return ..()
if(istype(W, /obj/item/paper) && obj_integrity < max_integrity)
user.visible_message("[user] starts to patch the holes in \the [src].")
if(do_after(user, 20, target = src))
obj_integrity = min(obj_integrity+4,max_integrity)
qdel(W)
user.visible_message("[user] patches some of the holes in \the [src].")
if(obj_integrity == max_integrity)
update_icon()
return
..()
update_icon()