mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2026-08-24 05:36:57 +01:00
Merge remote-tracking branch 'polaris/master' into pixel_projectiles
This commit is contained in:
@@ -159,14 +159,14 @@
|
||||
if(burning)
|
||||
burning = FALSE
|
||||
update_icon()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
visible_message("<span class='notice'>\The [src] stops burning.</span>")
|
||||
|
||||
/obj/structure/bonfire/proc/ignite()
|
||||
if(!burning && get_fuel_amount())
|
||||
burning = TRUE
|
||||
update_icon()
|
||||
processing_objects += src
|
||||
START_PROCESSING(SSobj, src)
|
||||
visible_message("<span class='warning'>\The [src] starts burning!</span>")
|
||||
|
||||
/obj/structure/bonfire/proc/burn()
|
||||
@@ -342,14 +342,14 @@
|
||||
if(burning)
|
||||
burning = FALSE
|
||||
update_icon()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
visible_message("<span class='notice'>\The [src] stops burning.</span>")
|
||||
|
||||
/obj/structure/fireplace/proc/ignite()
|
||||
if(!burning && get_fuel_amount())
|
||||
burning = TRUE
|
||||
update_icon()
|
||||
processing_objects += src
|
||||
START_PROCESSING(SSobj, src)
|
||||
visible_message("<span class='warning'>\The [src] starts burning!</span>")
|
||||
|
||||
/obj/structure/fireplace/proc/burn()
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
var/maxhealth = 100
|
||||
anchored = 1.0
|
||||
|
||||
/obj/structure/catwalk/initialize()
|
||||
/obj/structure/catwalk/Initialize()
|
||||
. = ..()
|
||||
for(var/obj/structure/catwalk/O in range(1))
|
||||
O.update_icon()
|
||||
|
||||
@@ -9,22 +9,30 @@
|
||||
var/icon_closed = "closed"
|
||||
var/icon_opened = "open"
|
||||
var/opened = 0
|
||||
var/welded = 0
|
||||
var/sealed = 0
|
||||
var/seal_tool = /obj/item/weapon/weldingtool //Tool used to seal the closet, defaults to welder
|
||||
var/wall_mounted = 0 //never solid (You can always pass over it)
|
||||
var/health = 100
|
||||
|
||||
var/breakout = 0 //if someone is currently breaking out. mutex
|
||||
var/breakout_time = 2 //2 minutes by default
|
||||
var/breakout_sound = 'sound/effects/grillehit.ogg' //Sound that plays while breaking out
|
||||
|
||||
var/storage_capacity = 2 * MOB_MEDIUM //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/storage_cost = 40 //How much space this closet takes up if it's stuffed in another closet
|
||||
|
||||
var/open_sound = 'sound/machines/click.ogg'
|
||||
var/close_sound = 'sound/machines/click.ogg'
|
||||
|
||||
var/store_misc = 1
|
||||
var/store_items = 1
|
||||
var/store_mobs = 1
|
||||
var/store_misc = 1 //Chameleon item check
|
||||
var/store_items = 1 //Will the closet store items?
|
||||
var/store_mobs = 1 //Will the closet store mobs?
|
||||
var/max_closets = 0 //Number of other closets allowed on tile before it won't close.
|
||||
|
||||
var/list/starts_with
|
||||
|
||||
/obj/structure/closet/initialize()
|
||||
/obj/structure/closet/Initialize()
|
||||
. = ..()
|
||||
if(starts_with)
|
||||
create_objects_in_loc(src, starts_with)
|
||||
@@ -38,27 +46,27 @@
|
||||
// adjust locker size to hold all items with 5 units of free store room
|
||||
var/content_size = 0
|
||||
for(I in src.contents)
|
||||
content_size += Ceiling(I.w_class/2)
|
||||
content_size += CEILING(I.w_class/2, 1)
|
||||
if(content_size > storage_capacity-5)
|
||||
storage_capacity = content_size + 5
|
||||
|
||||
update_icon()
|
||||
|
||||
/obj/structure/closet/examine(mob/user)
|
||||
if(..(user, 1) && !opened)
|
||||
var/content_size = 0
|
||||
for(var/obj/item/I in src.contents)
|
||||
if(!I.anchored)
|
||||
content_size += Ceiling(I.w_class/2)
|
||||
content_size += CEILING(I.w_class/2, 1)
|
||||
if(!content_size)
|
||||
user << "It is empty."
|
||||
to_chat(user, "It is empty.")
|
||||
else if(storage_capacity > content_size*4)
|
||||
user << "It is barely filled."
|
||||
to_chat(user, "It is barely filled.")
|
||||
else if(storage_capacity > content_size*2)
|
||||
user << "It is less than half full."
|
||||
to_chat(user, "It is less than half full.")
|
||||
else if(storage_capacity > content_size)
|
||||
user << "There is still some free space."
|
||||
to_chat(user, "There is still some free space.")
|
||||
else
|
||||
user << "It is full."
|
||||
to_chat(user, "It is full.")
|
||||
|
||||
/obj/structure/closet/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if(wall_mounted)
|
||||
@@ -66,14 +74,18 @@
|
||||
return ..()
|
||||
|
||||
/obj/structure/closet/proc/can_open()
|
||||
if(src.welded)
|
||||
if(src.sealed)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/structure/closet/proc/can_close()
|
||||
var/closet_count = 0
|
||||
for(var/obj/structure/closet/closet in get_turf(src))
|
||||
if(closet != src)
|
||||
return 0
|
||||
if(!closet.anchored)
|
||||
closet_count ++
|
||||
if(closet_count > max_closets)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/structure/closet/proc/dump_contents()
|
||||
@@ -102,7 +114,7 @@
|
||||
src.icon_state = src.icon_opened
|
||||
src.opened = 1
|
||||
playsound(src.loc, open_sound, 15, 1, -3)
|
||||
density = 0
|
||||
density = !density
|
||||
return 1
|
||||
|
||||
/obj/structure/closet/proc/close()
|
||||
@@ -119,12 +131,14 @@
|
||||
stored_units += store_items(stored_units)
|
||||
if(store_mobs)
|
||||
stored_units += store_mobs(stored_units)
|
||||
if(max_closets)
|
||||
stored_units += store_closets(stored_units)
|
||||
|
||||
src.icon_state = src.icon_closed
|
||||
src.opened = 0
|
||||
|
||||
playsound(src.loc, close_sound, 15, 1, -3)
|
||||
density = 1
|
||||
density = !density
|
||||
return 1
|
||||
|
||||
//Cham Projector Exception
|
||||
@@ -140,7 +154,7 @@
|
||||
/obj/structure/closet/proc/store_items(var/stored_units)
|
||||
var/added_units = 0
|
||||
for(var/obj/item/I in src.loc)
|
||||
var/item_size = Ceiling(I.w_class / 2)
|
||||
var/item_size = CEILING(I.w_class / 2, 1)
|
||||
if(stored_units + added_units + item_size > storage_capacity)
|
||||
continue
|
||||
if(!I.anchored)
|
||||
@@ -162,9 +176,25 @@
|
||||
added_units += M.mob_size
|
||||
return added_units
|
||||
|
||||
/obj/structure/closet/proc/store_closets(var/stored_units)
|
||||
var/added_units = 0
|
||||
for(var/obj/structure/closet/C in src.loc)
|
||||
if(C == src) //Don't store ourself
|
||||
continue
|
||||
if(C.anchored) //Don't worry about anchored things on the same tile
|
||||
continue
|
||||
if(C.max_closets) //Prevents recursive storage
|
||||
continue
|
||||
if(stored_units + added_units + storage_cost > storage_capacity)
|
||||
break
|
||||
C.forceMove(src)
|
||||
added_units += storage_cost
|
||||
return added_units
|
||||
|
||||
|
||||
/obj/structure/closet/proc/toggle(mob/user as mob)
|
||||
if(!(src.opened ? src.close() : src.open()))
|
||||
user << "<span class='notice'>It won't budge!</span>"
|
||||
to_chat(user, "<span class='notice'>It won't budge!</span>")
|
||||
return
|
||||
update_icon()
|
||||
|
||||
@@ -222,7 +252,7 @@
|
||||
if(!WT.isOn())
|
||||
return
|
||||
else
|
||||
user << "<span class='notice'>You need more welding fuel to complete this task.</span>"
|
||||
to_chat(user, "<span class='notice'>You need more welding fuel to complete this task.</span>")
|
||||
return
|
||||
playsound(src, WT.usesound, 50)
|
||||
new /obj/item/stack/material/steel(src.loc)
|
||||
@@ -248,21 +278,25 @@
|
||||
W.forceMove(src.loc)
|
||||
else if(istype(W, /obj/item/weapon/packageWrap))
|
||||
return
|
||||
else if(istype(W, /obj/item/weapon/weldingtool))
|
||||
var/obj/item/weapon/weldingtool/WT = W
|
||||
if(!WT.remove_fuel(0,user))
|
||||
if(!WT.isOn())
|
||||
return
|
||||
else
|
||||
user << "<span class='notice'>You need more welding fuel to complete this task.</span>"
|
||||
return
|
||||
playsound(src, WT.usesound, 50)
|
||||
src.welded = !src.welded
|
||||
src.update_icon()
|
||||
for(var/mob/M in viewers(src))
|
||||
M.show_message("<span class='warning'>[src] has been [welded?"welded shut":"unwelded"] by [user.name].</span>", 3, "You hear welding.", 2)
|
||||
else if(seal_tool)
|
||||
if(istype(W, seal_tool))
|
||||
var/obj/item/weapon/S = W
|
||||
if(istype(S, /obj/item/weapon/weldingtool))
|
||||
var/obj/item/weapon/weldingtool/WT = S
|
||||
if(!WT.remove_fuel(0,user))
|
||||
if(!WT.isOn())
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You need more welding fuel to complete this task.</span>")
|
||||
return
|
||||
if(do_after(user, 20 * S.toolspeed))
|
||||
playsound(src, S.usesound, 50)
|
||||
src.sealed = !src.sealed
|
||||
src.update_icon()
|
||||
for(var/mob/M in viewers(src))
|
||||
M.show_message("<span class='warning'>[src] has been [sealed?"sealed":"unsealed"] by [user.name].</span>", 3)
|
||||
else if(W.is_wrench())
|
||||
if(welded)
|
||||
if(sealed)
|
||||
if(anchored)
|
||||
user.visible_message("\The [user] begins unsecuring \the [src] from the floor.", "You start unsecuring \the [src] from the floor.")
|
||||
else
|
||||
@@ -270,7 +304,7 @@
|
||||
playsound(src, W.usesound, 50)
|
||||
if(do_after(user, 20 * W.toolspeed))
|
||||
if(!src) return
|
||||
user << "<span class='notice'>You [anchored? "un" : ""]secured \the [src]!</span>"
|
||||
to_chat(user, "<span class='notice'>You [anchored? "un" : ""]secured \the [src]!</span>")
|
||||
anchored = !anchored
|
||||
else
|
||||
src.attack_hand(user)
|
||||
@@ -306,7 +340,7 @@
|
||||
return
|
||||
|
||||
if(!src.open())
|
||||
user << "<span class='notice'>It won't budge!</span>"
|
||||
to_chat(user, "<span class='notice'>It won't budge!</span>")
|
||||
|
||||
/obj/structure/closet/attack_hand(mob/user as mob)
|
||||
src.add_fingerprint(user)
|
||||
@@ -316,7 +350,7 @@
|
||||
/obj/structure/closet/attack_self_tk(mob/user as mob)
|
||||
src.add_fingerprint(user)
|
||||
if(!src.toggle())
|
||||
usr << "<span class='notice'>It won't budge!</span>"
|
||||
to_chat(usr, "<span class='notice'>It won't budge!</span>")
|
||||
|
||||
/obj/structure/closet/attack_ghost(mob/ghost)
|
||||
if(ghost.client && ghost.client.inquisitive_ghost)
|
||||
@@ -336,19 +370,19 @@
|
||||
src.add_fingerprint(usr)
|
||||
src.toggle(usr)
|
||||
else
|
||||
usr << "<span class='warning'>This mob type can't use this verb.</span>"
|
||||
to_chat(usr, "<span class='warning'>This mob type can't use this verb.</span>")
|
||||
|
||||
/obj/structure/closet/update_icon()//Putting the welded stuff in updateicon() so it's easy to overwrite for special cases (Fridges, cabinets, and whatnot)
|
||||
/obj/structure/closet/update_icon()//Putting the sealed stuff in updateicon() so it's easy to overwrite for special cases (Fridges, cabinets, and whatnot)
|
||||
overlays.Cut()
|
||||
if(!opened)
|
||||
icon_state = icon_closed
|
||||
if(welded)
|
||||
overlays += "welded"
|
||||
if(sealed)
|
||||
overlays += "sealed"
|
||||
else
|
||||
icon_state = icon_opened
|
||||
|
||||
/obj/structure/closet/attack_generic(var/mob/user, var/damage, var/attack_message = "destroys", var/wallbreaker)
|
||||
if(damage < 10 || !wallbreaker)
|
||||
/obj/structure/closet/attack_generic(var/mob/user, var/damage, var/attack_message = "destroys")
|
||||
if(damage < STRUCTURE_MIN_DAMAGE_THRESHOLD)
|
||||
return
|
||||
user.do_attack_animation(src)
|
||||
visible_message("<span class='danger'>[user] [attack_message] the [src]!</span>")
|
||||
@@ -359,20 +393,19 @@
|
||||
/obj/structure/closet/proc/req_breakout()
|
||||
if(opened)
|
||||
return 0 //Door's open... wait, why are you in it's contents then?
|
||||
if(!welded)
|
||||
return 0 //closed but not welded...
|
||||
if(!sealed)
|
||||
return 0 //closed but not sealed...
|
||||
return 1
|
||||
|
||||
/obj/structure/closet/proc/mob_breakout(var/mob/living/escapee)
|
||||
var/breakout_time = 2 //2 minutes by default
|
||||
|
||||
if(breakout || !req_breakout())
|
||||
return
|
||||
|
||||
escapee.setClickCooldown(100)
|
||||
|
||||
//okay, so the closet is either welded or locked... resist!!!
|
||||
escapee << "<span class='warning'>You lean on the back of \the [src] and start pushing the door open. (this will take about [breakout_time] minutes)</span>"
|
||||
//okay, so the closet is either sealed or locked... resist!!!
|
||||
to_chat(escapee, "<span class='warning'>You lean on the back of \the [src] and start pushing the door open. (this will take about [breakout_time] minutes)</span>")
|
||||
|
||||
visible_message("<span class='danger'>\The [src] begins to shake violently!</span>")
|
||||
|
||||
@@ -389,20 +422,20 @@
|
||||
breakout = 0
|
||||
return
|
||||
|
||||
playsound(src.loc, 'sound/effects/grillehit.ogg', 100, 1)
|
||||
playsound(src.loc, breakout_sound, 100, 1)
|
||||
animate_shake()
|
||||
add_fingerprint(escapee)
|
||||
|
||||
//Well then break it!
|
||||
breakout = 0
|
||||
escapee << "<span class='warning'>You successfully break out!</span>"
|
||||
to_chat(escapee, "<span class='warning'>You successfully break out!</span>")
|
||||
visible_message("<span class='danger'>\The [escapee] successfully broke out of \the [src]!</span>")
|
||||
playsound(src.loc, 'sound/effects/grillehit.ogg', 100, 1)
|
||||
playsound(src.loc, breakout_sound, 100, 1)
|
||||
break_open()
|
||||
animate_shake()
|
||||
|
||||
/obj/structure/closet/proc/break_open()
|
||||
welded = 0
|
||||
sealed = 0
|
||||
update_icon()
|
||||
//Do this to prevent contents from being opened into nullspace (read: bluespace)
|
||||
if(istype(loc, /obj/structure/bigDelivery))
|
||||
@@ -421,3 +454,9 @@
|
||||
|
||||
/obj/structure/closet/AllowDrop()
|
||||
return TRUE
|
||||
|
||||
/obj/structure/closet/return_air_for_internal_lifeform(var/mob/living/L)
|
||||
if(src.loc)
|
||||
if(istype(src.loc, /obj/structure/closet))
|
||||
return (loc.return_air_for_internal_lifeform(L))
|
||||
return return_air()
|
||||
|
||||
@@ -4,9 +4,161 @@
|
||||
icon_state = "coffin"
|
||||
icon_closed = "coffin"
|
||||
icon_opened = "coffin_open"
|
||||
seal_tool = /obj/item/weapon/tool/screwdriver
|
||||
breakout_sound = 'sound/weapons/tablehit1.ogg'
|
||||
|
||||
/obj/structure/closet/coffin/update_icon()
|
||||
if(!opened)
|
||||
icon_state = icon_closed
|
||||
else
|
||||
icon_state = icon_opened
|
||||
|
||||
/* Graves */
|
||||
/obj/structure/closet/grave
|
||||
name = "grave"
|
||||
desc = "Dirt."
|
||||
icon_state = "grave"
|
||||
icon_closed = "grave"
|
||||
icon_opened = "grave_open"
|
||||
seal_tool = null
|
||||
breakout_sound = 'sound/weapons/thudswoosh.ogg'
|
||||
anchored = 1
|
||||
max_closets = 1
|
||||
opened = 1
|
||||
|
||||
/obj/structure/closet/grave/attack_hand(mob/user as mob)
|
||||
if(opened)
|
||||
visible_message("<span class='notice'>[user] starts to climb into \the [src.name].</span>", \
|
||||
"<span class='notice'>You start to lower yourself into \the [src.name].</span>")
|
||||
if(do_after(user, 50))
|
||||
user.forceMove(src.loc)
|
||||
visible_message("<span class='notice'>[user] climbs into \the [src.name].</span>", \
|
||||
"<span class='notice'>You climb into \the [src.name].</span>")
|
||||
else
|
||||
visible_message("<span class='notice'>[user] decides not to climb into \the [src.name].</span>", \
|
||||
"<span class='notice'>You stop climbing into \the [src.name].</span>")
|
||||
return
|
||||
|
||||
/obj/structure/closet/grave/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if(opened && ismob(mover))
|
||||
var/mob/M = mover
|
||||
add_fingerprint(M)
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.m_intent == "walk")
|
||||
to_chat(H, "<span class='warning'>You stop at the edge of \the [src.name].</span>")
|
||||
return FALSE
|
||||
else
|
||||
to_chat(H, "<span class='warning'>You fall into \the [src.name]!</span>")
|
||||
fall_in(H)
|
||||
return TRUE
|
||||
if(isrobot(M))
|
||||
var/mob/living/silicon/robot/R = M
|
||||
if(R.a_intent == I_HELP)
|
||||
to_chat(R, "<span class='warning'>You stop at the edge of \the [src.name].</span>")
|
||||
return FALSE
|
||||
else
|
||||
to_chat(R, "<span class='warning'>You enter \the [src.name].</span>")
|
||||
return TRUE
|
||||
return TRUE //Everything else can move over the graves
|
||||
|
||||
/obj/structure/closet/grave/proc/fall_in(mob/living/L) //Only called on humans for now, but still
|
||||
L.Weaken(5)
|
||||
if(ishuman(L))
|
||||
var/mob/living/carbon/human/H = L
|
||||
var/limb_damage = rand(5,25)
|
||||
H.adjustBruteLoss(limb_damage)
|
||||
|
||||
/obj/structure/closet/grave/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(src.opened)
|
||||
if(istype(W, /obj/item/weapon/shovel))
|
||||
user.visible_message("<span class='notice'>[user] piles dirt into \the [src.name].</span>", \
|
||||
"<span class='notice'>You start to pile dirt into \the [src.name].</span>", \
|
||||
"<span class='notice'>You hear dirt being moved.</span>")
|
||||
if(do_after(user, 40 * W.toolspeed))
|
||||
user.visible_message("<span class='notice'>[user] pats down the dirt on top of \the [src.name].</span>", \
|
||||
"<span class='notice'>You finish filling in \the [src.name].</span>")
|
||||
close()
|
||||
return
|
||||
else
|
||||
user.visible_message("<span class='notice'>[user] stops filling in \the [src.name].</span>", \
|
||||
"<span class='notice'>You change your mind and stop filling in \the [src.name].</span>")
|
||||
return
|
||||
if(istype(W, /obj/item/weapon/grab))
|
||||
var/obj/item/weapon/grab/G = W
|
||||
src.MouseDrop_T(G.affecting, user) //act like they were dragged onto the closet
|
||||
return 0
|
||||
if(istype(W,/obj/item/tk_grab))
|
||||
return 0
|
||||
if(istype(W, /obj/item/weapon/storage/laundry_basket) && W.contents.len)
|
||||
var/obj/item/weapon/storage/laundry_basket/LB = W
|
||||
var/turf/T = get_turf(src)
|
||||
for(var/obj/item/I in LB.contents)
|
||||
LB.remove_from_storage(I, T)
|
||||
user.visible_message("<span class='notice'>[user] empties \the [LB] into \the [src].</span>", \
|
||||
"<span class='notice'>You empty \the [LB] into \the [src].</span>", \
|
||||
"<span class='notice'>You hear rustling of clothes.</span>")
|
||||
return
|
||||
if(isrobot(user))
|
||||
return
|
||||
if(W.loc != user) // This should stop mounted modules ending up outside the module.
|
||||
return
|
||||
usr.drop_item()
|
||||
if(W)
|
||||
W.forceMove(src.loc)
|
||||
else
|
||||
if(istype(W, /obj/item/weapon/shovel))
|
||||
if(user.a_intent == I_HURT) // Hurt intent means you're trying to kill someone, or just get rid of the grave
|
||||
user.visible_message("<span class='notice'>[user] begins to smoothe out the dirt of \the [src.name].</span>", \
|
||||
"<span class='notice'>You start to smoothe out the dirt of \the [src.name].</span>", \
|
||||
"<span class='notice'>You hear dirt being moved.</span>")
|
||||
if(do_after(user, 40 * W.toolspeed))
|
||||
user.visible_message("<span class='notice'>[user] finishes smoothing out \the [src.name].</span>", \
|
||||
"<span class='notice'>You finish smoothing out \the [src.name].</span>")
|
||||
if(LAZYLEN(contents))
|
||||
alpha = 40 // If we've got stuff inside, like maybe a person, just make it hard to see us
|
||||
else
|
||||
qdel(src) // Else, go away
|
||||
return
|
||||
else
|
||||
user.visible_message("<span class='notice'>[user] stops concealing \the [src.name].</span>", \
|
||||
"<span class='notice'>You stop concealing \the [src.name].</span>")
|
||||
return
|
||||
else
|
||||
user.visible_message("<span class='notice'>[user] begins to unearth \the [src.name].</span>", \
|
||||
"<span class='notice'>You start to unearth \the [src.name].</span>", \
|
||||
"<span class='notice'>You hear dirt being moved.</span>")
|
||||
if(do_after(user, 40 * W.toolspeed))
|
||||
user.visible_message("<span class='notice'>[user] reaches the bottom of \the [src.name].</span>", \
|
||||
"<span class='notice'>You finish digging out \the [src.name].</span>")
|
||||
break_open()
|
||||
return
|
||||
else
|
||||
user.visible_message("<span class='notice'>[user] stops digging out \the [src.name].</span>", \
|
||||
"<span class='notice'>You stop digging out \the [src.name].</span>")
|
||||
return
|
||||
return
|
||||
|
||||
/obj/structure/closet/grave/close()
|
||||
..()
|
||||
if(!opened)
|
||||
sealed = TRUE
|
||||
|
||||
/obj/structure/closet/grave/open()
|
||||
.=..()
|
||||
alpha = 255 // Needed because of grave hiding
|
||||
|
||||
/obj/structure/closet/grave/bullet_act(var/obj/item/projectile/P)
|
||||
return PROJECTILE_CONTINUE // It's a hole in the ground, doesn't usually stop or even care about bullets
|
||||
|
||||
/obj/structure/closet/grave/return_air_for_internal_lifeform(var/mob/living/L)
|
||||
var/gasid = "carbon_dioxide"
|
||||
if(ishuman(L))
|
||||
var/mob/living/carbon/human/H = L
|
||||
if(H.species && H.species.exhale_type)
|
||||
gasid = H.species.exhale_type
|
||||
var/datum/gas_mixture/grave_breath = new()
|
||||
var/datum/gas_mixture/above_air = return_air()
|
||||
grave_breath.adjust_gas(gasid, BREATH_MOLES)
|
||||
grave_breath.temperature = (above_air.temperature) - 30 //Underground
|
||||
return grave_breath
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
starts_with = list(/obj/item/weapon/material/twohanded/fireaxe)
|
||||
|
||||
/obj/structure/closet/fireaxecabinet/initialize()
|
||||
/obj/structure/closet/fireaxecabinet/Initialize()
|
||||
..()
|
||||
fireaxe = locate() in contents
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
/obj/item/clothing/gloves/fingerless,
|
||||
/obj/item/clothing/head/soft)
|
||||
|
||||
/obj/structure/closet/secure_closet/cargotech/initialize()
|
||||
/obj/structure/closet/secure_closet/cargotech/Initialize()
|
||||
if(prob(75))
|
||||
starts_with += /obj/item/weapon/storage/backpack
|
||||
else
|
||||
@@ -59,7 +59,7 @@
|
||||
/obj/item/clothing/suit/storage/hooded/wintercoat/cargo,
|
||||
/obj/item/clothing/shoes/boots/winter/supply)
|
||||
|
||||
/obj/structure/closet/secure_closet/quartermaster/initialize()
|
||||
/obj/structure/closet/secure_closet/quartermaster/Initialize()
|
||||
if(prob(75))
|
||||
starts_with += /obj/item/weapon/storage/backpack
|
||||
else
|
||||
@@ -93,7 +93,7 @@
|
||||
/obj/item/clothing/shoes/boots/winter/mining,
|
||||
/obj/item/stack/marker_beacon/thirty)
|
||||
|
||||
/obj/structure/closet/secure_closet/miner/initialize()
|
||||
/obj/structure/closet/secure_closet/miner/Initialize()
|
||||
if(prob(50))
|
||||
starts_with += /obj/item/weapon/storage/backpack/industrial
|
||||
else
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
/obj/item/clothing/shoes/boots/winter/engineering,
|
||||
/obj/item/weapon/tank/emergency/oxygen/engi)
|
||||
|
||||
/obj/structure/closet/secure_closet/engineering_chief/initialize()
|
||||
/obj/structure/closet/secure_closet/engineering_chief/Initialize()
|
||||
if(prob(50))
|
||||
starts_with += /obj/item/weapon/storage/backpack/industrial
|
||||
else
|
||||
@@ -98,7 +98,7 @@
|
||||
/obj/item/clothing/shoes/boots/winter/engineering,
|
||||
/obj/item/weapon/tank/emergency/oxygen/engi)
|
||||
|
||||
/obj/structure/closet/secure_closet/engineering_personal/initialize()
|
||||
/obj/structure/closet/secure_closet/engineering_personal/Initialize()
|
||||
if(prob(50))
|
||||
starts_with += /obj/item/weapon/storage/backpack/industrial
|
||||
else
|
||||
@@ -133,7 +133,7 @@
|
||||
/obj/item/clothing/shoes/boots/winter/atmos,
|
||||
/obj/item/weapon/tank/emergency/oxygen/engi)
|
||||
|
||||
/obj/structure/closet/secure_closet/atmos_personal/initialize()
|
||||
/obj/structure/closet/secure_closet/atmos_personal/Initialize()
|
||||
if(prob(50))
|
||||
starts_with += /obj/item/weapon/storage/backpack/industrial
|
||||
else
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
icon_opened = "base"
|
||||
req_one_access = list(access_armory)
|
||||
|
||||
/obj/structure/closet/secure_closet/guncabinet/initialize()
|
||||
/obj/structure/closet/secure_closet/guncabinet/Initialize()
|
||||
. = ..()
|
||||
update_icon()
|
||||
|
||||
@@ -43,8 +43,8 @@
|
||||
|
||||
overlays += icon(src.icon, "door")
|
||||
|
||||
if(welded)
|
||||
overlays += icon(src.icon,"welded")
|
||||
if(sealed)
|
||||
overlays += icon(src.icon,"sealed")
|
||||
|
||||
if(broken)
|
||||
overlays += icon(src.icon,"broken")
|
||||
|
||||
@@ -16,12 +16,12 @@
|
||||
/obj/item/clothing/head/greenbandana,
|
||||
/obj/item/weapon/material/minihoe,
|
||||
/obj/item/weapon/material/knife/machete/hatchet,
|
||||
/obj/item/weapon/tool/wirecutters/clippers,
|
||||
/obj/item/weapon/tool/wirecutters/clippers/trimmers,
|
||||
/obj/item/weapon/reagent_containers/spray/plantbgone,
|
||||
/obj/item/clothing/suit/storage/hooded/wintercoat/hydro,
|
||||
/obj/item/clothing/shoes/boots/winter/hydro)
|
||||
|
||||
/obj/structure/closet/secure_closet/hydroponics/initialize()
|
||||
/obj/structure/closet/secure_closet/hydroponics/Initialize()
|
||||
if(prob(50))
|
||||
starts_with += /obj/item/clothing/suit/storage/apron
|
||||
else
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
/obj/item/clothing/head/nursehat,
|
||||
/obj/item/weapon/storage/box/freezer = 3)
|
||||
|
||||
/obj/structure/closet/secure_closet/medical3/initialize()
|
||||
/obj/structure/closet/secure_closet/medical3/Initialize()
|
||||
if(prob(50))
|
||||
starts_with += /obj/item/weapon/storage/backpack/medic
|
||||
else
|
||||
@@ -169,7 +169,7 @@
|
||||
/obj/item/clothing/head/bio_hood/cmo,
|
||||
/obj/item/clothing/shoes/white)
|
||||
|
||||
/obj/structure/closet/secure_closet/CMO/initialize()
|
||||
/obj/structure/closet/secure_closet/CMO/Initialize()
|
||||
if(prob(50))
|
||||
starts_with += /obj/item/weapon/storage/backpack/medic
|
||||
else
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
starts_with = list(
|
||||
/obj/item/device/radio/headset)
|
||||
|
||||
/obj/structure/closet/secure_closet/personal/initialize()
|
||||
/obj/structure/closet/secure_closet/personal/Initialize()
|
||||
if(prob(50))
|
||||
starts_with += /obj/item/weapon/storage/backpack
|
||||
else
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
/obj/item/clothing/suit/storage/hooded/wintercoat/science,
|
||||
/obj/item/clothing/shoes/boots/winter/science)
|
||||
|
||||
/obj/structure/closet/secure_closet/scientist/initialize()
|
||||
/obj/structure/closet/secure_closet/scientist/Initialize()
|
||||
if(prob(50))
|
||||
starts_with += /obj/item/weapon/storage/backpack/dufflebag/sci
|
||||
else
|
||||
|
||||
@@ -46,23 +46,23 @@
|
||||
|
||||
/obj/structure/closet/secure_closet/proc/togglelock(mob/user as mob)
|
||||
if(src.opened)
|
||||
user << "<span class='notice'>Close the locker first.</span>"
|
||||
to_chat(user, "<span class='notice'>Close the locker first.</span>")
|
||||
return
|
||||
if(src.broken)
|
||||
user << "<span class='warning'>The locker appears to be broken.</span>"
|
||||
to_chat(user, "<span class='warning'>The locker appears to be broken.</span>")
|
||||
return
|
||||
if(user.loc == src)
|
||||
user << "<span class='notice'>You can't reach the lock from inside.</span>"
|
||||
to_chat(user, "<span class='notice'>You can't reach the lock from inside.</span>")
|
||||
return
|
||||
if(src.allowed(user))
|
||||
src.locked = !src.locked
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 15, 1, -3)
|
||||
for(var/mob/O in viewers(user, 3))
|
||||
if((O.client && !( O.blinded )))
|
||||
O << "<span class='notice'>The locker has been [locked ? null : "un"]locked by [user].</span>"
|
||||
to_chat(O, "<span class='notice'>The locker has been [locked ? null : "un"]locked by [user].</span>")
|
||||
update_icon()
|
||||
else
|
||||
user << "<span class='notice'>Access Denied</span>"
|
||||
to_chat(user, "<span class='notice'>Access Denied</span>")
|
||||
|
||||
/obj/structure/closet/secure_closet/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(src.opened)
|
||||
@@ -73,7 +73,7 @@
|
||||
if(src.large)
|
||||
src.MouseDrop_T(G.affecting, user) //act like they were dragged onto the closet
|
||||
else
|
||||
user << "<span class='notice'>The locker is too small to stuff [G.affecting] into!</span>"
|
||||
to_chat(user, "<span class='notice'>The locker is too small to stuff [G.affecting] into!</span>")
|
||||
if(isrobot(user))
|
||||
return
|
||||
if(W.loc != user) // This should stop mounted modules ending up outside the module.
|
||||
@@ -89,14 +89,14 @@
|
||||
playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1)
|
||||
playsound(src.loc, "sparks", 50, 1)
|
||||
else if(W.is_wrench())
|
||||
if(welded)
|
||||
if(sealed)
|
||||
if(anchored)
|
||||
user.visible_message("\The [user] begins unsecuring \the [src] from the floor.", "You start unsecuring \the [src] from the floor.")
|
||||
else
|
||||
user.visible_message("\The [user] begins securing \the [src] to the floor.", "You start securing \the [src] to the floor.")
|
||||
if(do_after(user, 20 * W.toolspeed))
|
||||
if(!src) return
|
||||
user << "<span class='notice'>You [anchored? "un" : ""]secured \the [src]!</span>"
|
||||
to_chat(user, "<span class='notice'>You [anchored? "un" : ""]secured \the [src]!</span>")
|
||||
anchored = !anchored
|
||||
return
|
||||
else if(istype(W,/obj/item/weapon/packageWrap) || istype(W,/obj/item/weapon/weldingtool))
|
||||
@@ -143,9 +143,9 @@
|
||||
src.add_fingerprint(usr)
|
||||
src.togglelock(usr)
|
||||
else
|
||||
usr << "<span class='warning'>This mob type can't use this verb.</span>"
|
||||
to_chat(usr, "<span class='warning'>This mob type can't use this verb.</span>")
|
||||
|
||||
/obj/structure/closet/secure_closet/update_icon()//Putting the welded stuff in updateicon() so it's easy to overwrite for special cases (Fridges, cabinets, and whatnot)
|
||||
/obj/structure/closet/secure_closet/update_icon()//Putting the sealed stuff in updateicon() so it's easy to overwrite for special cases (Fridges, cabinets, and whatnot)
|
||||
overlays.Cut()
|
||||
|
||||
if(!opened)
|
||||
@@ -155,8 +155,8 @@
|
||||
icon_state = icon_locked
|
||||
else
|
||||
icon_state = icon_closed
|
||||
if(welded)
|
||||
overlays += "welded"
|
||||
if(sealed)
|
||||
overlays += "sealed"
|
||||
else
|
||||
icon_state = icon_opened
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
/obj/item/device/flashlight/maglight,
|
||||
/obj/item/clothing/mask/gas/half)
|
||||
|
||||
/obj/structure/closet/secure_closet/hos/initialize()
|
||||
/obj/structure/closet/secure_closet/hos/Initialize()
|
||||
if(prob(50))
|
||||
starts_with += /obj/item/weapon/storage/backpack/security
|
||||
else
|
||||
@@ -168,7 +168,7 @@
|
||||
/obj/item/device/megaphone,
|
||||
/obj/item/clothing/mask/gas/half)
|
||||
|
||||
/obj/structure/closet/secure_closet/warden/initialize()
|
||||
/obj/structure/closet/secure_closet/warden/Initialize()
|
||||
if(prob(50))
|
||||
starts_with += /obj/item/weapon/storage/backpack/security
|
||||
else
|
||||
@@ -212,7 +212,7 @@
|
||||
/obj/item/clothing/shoes/boots/winter/security,
|
||||
/obj/item/device/flashlight/maglight)
|
||||
|
||||
/obj/structure/closet/secure_closet/security/initialize()
|
||||
/obj/structure/closet/secure_closet/security/Initialize()
|
||||
if(prob(50))
|
||||
starts_with += /obj/item/weapon/storage/backpack/security
|
||||
else
|
||||
@@ -221,22 +221,22 @@
|
||||
starts_with += /obj/item/weapon/storage/backpack/dufflebag/sec
|
||||
return ..()
|
||||
|
||||
/obj/structure/closet/secure_closet/security/cargo/initialize()
|
||||
/obj/structure/closet/secure_closet/security/cargo/Initialize()
|
||||
starts_with += /obj/item/clothing/accessory/armband/cargo
|
||||
starts_with += /obj/item/device/encryptionkey/headset_cargo
|
||||
return ..()
|
||||
|
||||
/obj/structure/closet/secure_closet/security/engine/initialize()
|
||||
/obj/structure/closet/secure_closet/security/engine/Initialize()
|
||||
starts_with += /obj/item/clothing/accessory/armband/engine
|
||||
starts_with += /obj/item/device/encryptionkey/headset_eng
|
||||
return ..()
|
||||
|
||||
/obj/structure/closet/secure_closet/security/science/initialize()
|
||||
/obj/structure/closet/secure_closet/security/science/Initialize()
|
||||
starts_with += /obj/item/clothing/accessory/armband/science
|
||||
starts_with += /obj/item/device/encryptionkey/headset_sci
|
||||
return ..()
|
||||
|
||||
/obj/structure/closet/secure_closet/security/med/initialize()
|
||||
/obj/structure/closet/secure_closet/security/med/Initialize()
|
||||
starts_with += /obj/item/clothing/accessory/armband/medblue
|
||||
starts_with += /obj/item/device/encryptionkey/headset_med
|
||||
return ..()
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
processing_objects.Add(src)
|
||||
START_PROCESSING(SSobj, src)
|
||||
..()
|
||||
|
||||
/obj/structure/closet/statue/process()
|
||||
@@ -55,7 +55,7 @@
|
||||
M.setOxyLoss(intialOxy)
|
||||
if (timer <= 0)
|
||||
dump_contents()
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/closet/statue/dump_contents()
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
/obj/structure/closet/syndicate/resources
|
||||
desc = "An old, dusty locker."
|
||||
|
||||
/obj/structure/closet/syndicate/resources/initialize()
|
||||
/obj/structure/closet/syndicate/resources/Initialize()
|
||||
. = ..()
|
||||
if(!contents.len)
|
||||
var/common_min = 30 //Minimum amount of minerals in the stack for common minerals
|
||||
@@ -103,7 +103,7 @@
|
||||
/obj/structure/closet/syndicate/resources/everything
|
||||
desc = "It's an emergency storage closet for repairs."
|
||||
|
||||
/obj/structure/closet/syndicate/resources/everything/initialize()
|
||||
/obj/structure/closet/syndicate/resources/everything/Initialize()
|
||||
var/list/resources = list(
|
||||
/obj/item/stack/material/steel,
|
||||
/obj/item/stack/material/glass,
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
icon_closed = "emergency"
|
||||
icon_opened = "emergencyopen"
|
||||
|
||||
/obj/structure/closet/emcloset/initialize()
|
||||
/obj/structure/closet/emcloset/Initialize()
|
||||
switch (pickweight(list("small" = 55, "aid" = 25, "tank" = 10, "both" = 10)))
|
||||
if ("small")
|
||||
starts_with = list(
|
||||
@@ -106,7 +106,7 @@
|
||||
icon_closed = "toolcloset"
|
||||
icon_opened = "toolclosetopen"
|
||||
|
||||
/obj/structure/closet/toolcloset/initialize()
|
||||
/obj/structure/closet/toolcloset/Initialize()
|
||||
starts_with = list()
|
||||
if(prob(40))
|
||||
starts_with += /obj/item/clothing/suit/storage/hazardvest
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
/obj/item/clothing/accessory/armband = 3,
|
||||
/obj/item/clothing/accessory/holster/waist = 3)
|
||||
|
||||
/obj/structure/closet/wardrobe/red/initialize()
|
||||
/obj/structure/closet/wardrobe/red/Initialize()
|
||||
if(prob(50))
|
||||
starts_with += /obj/item/weapon/storage/backpack/security
|
||||
else
|
||||
@@ -223,7 +223,7 @@
|
||||
/obj/item/weapon/storage/backpack/toxins,
|
||||
/obj/item/weapon/storage/backpack/satchel/tox)
|
||||
|
||||
/obj/structure/closet/wardrobe/science_white/initialize()
|
||||
/obj/structure/closet/wardrobe/science_white/Initialize()
|
||||
if(prob(50))
|
||||
starts_with += /obj/item/weapon/storage/backpack/dufflebag/sci
|
||||
else
|
||||
@@ -249,7 +249,7 @@
|
||||
/obj/item/weapon/storage/backpack/toxins,
|
||||
/obj/item/weapon/storage/backpack/satchel/tox)
|
||||
|
||||
/obj/structure/closet/wardrobe/robotics_black/initialize()
|
||||
/obj/structure/closet/wardrobe/robotics_black/Initialize()
|
||||
if(prob(50))
|
||||
starts_with += /obj/item/weapon/storage/backpack/dufflebag/sci
|
||||
else
|
||||
@@ -401,7 +401,7 @@
|
||||
/obj/item/clothing/gloves/black,
|
||||
/obj/item/clothing/under/pants/camo)
|
||||
|
||||
/obj/structure/closet/wardrobe/tactical/initialize()
|
||||
/obj/structure/closet/wardrobe/tactical/Initialize()
|
||||
if(prob(25))
|
||||
starts_with += /obj/item/weapon/storage/belt/security/tactical/bandolier
|
||||
else
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
density = 1
|
||||
var/list/starts_with
|
||||
|
||||
/obj/structure/largecrate/initialize()
|
||||
/obj/structure/largecrate/Initialize()
|
||||
. = ..()
|
||||
if(starts_with)
|
||||
create_objects_in_loc(src, starts_with)
|
||||
@@ -15,6 +15,7 @@
|
||||
if(I.density || I.anchored || I == src || !I.simulated)
|
||||
continue
|
||||
I.forceMove(src)
|
||||
update_icon()
|
||||
|
||||
/obj/structure/largecrate/attack_hand(mob/user as mob)
|
||||
to_chat(user, "<span class='notice'>You need a crowbar to pry this open!</span>")
|
||||
@@ -57,6 +58,29 @@
|
||||
ME.attach(H)
|
||||
..()
|
||||
|
||||
/obj/structure/largecrate/vehicle
|
||||
name = "vehicle crate"
|
||||
desc = "It comes in a box for the consumer's sake. ..How is this lighter?"
|
||||
icon_state = "vehiclecrate"
|
||||
|
||||
/obj/structure/largecrate/vehicle/Initialize()
|
||||
..()
|
||||
spawn(1)
|
||||
for(var/obj/O in contents)
|
||||
O.update_icon()
|
||||
|
||||
/obj/structure/largecrate/vehicle/bike
|
||||
name = "spacebike crate"
|
||||
starts_with = list(/obj/structure/vehiclecage/spacebike)
|
||||
|
||||
/obj/structure/largecrate/vehicle/quadbike
|
||||
name = "\improper ATV crate"
|
||||
starts_with = list(/obj/structure/vehiclecage/quadbike)
|
||||
|
||||
/obj/structure/largecrate/vehicle/quadtrailer
|
||||
name = "\improper ATV trailer crate"
|
||||
starts_with = list(/obj/structure/vehiclecage/quadtrailer)
|
||||
|
||||
/obj/structure/largecrate/animal
|
||||
icon_state = "mulecrate"
|
||||
|
||||
@@ -66,23 +90,23 @@
|
||||
|
||||
/obj/structure/largecrate/animal/corgi
|
||||
name = "corgi carrier"
|
||||
starts_with = list(/mob/living/simple_animal/corgi)
|
||||
starts_with = list(/mob/living/simple_mob/animal/passive/dog/corgi)
|
||||
|
||||
/obj/structure/largecrate/animal/cow
|
||||
name = "cow crate"
|
||||
starts_with = list(/mob/living/simple_animal/cow)
|
||||
starts_with = list(/mob/living/simple_mob/animal/passive/cow)
|
||||
|
||||
/obj/structure/largecrate/animal/goat
|
||||
name = "goat crate"
|
||||
starts_with = list(/mob/living/simple_animal/retaliate/goat)
|
||||
starts_with = list(/mob/living/simple_mob/animal/goat)
|
||||
|
||||
/obj/structure/largecrate/animal/cat
|
||||
name = "cat carrier"
|
||||
starts_with = list(/mob/living/simple_animal/cat)
|
||||
starts_with = list(/mob/living/simple_mob/animal/passive/cat)
|
||||
|
||||
/obj/structure/largecrate/animal/cat/bones
|
||||
starts_with = list(/mob/living/simple_animal/cat/fluff/bones)
|
||||
starts_with = list(/mob/living/simple_mob/animal/passive/cat/bones)
|
||||
|
||||
/obj/structure/largecrate/animal/chick
|
||||
name = "chicken crate"
|
||||
starts_with = list(/mob/living/simple_animal/chick = 5)
|
||||
starts_with = list(/mob/living/simple_mob/animal/passive/chick = 5)
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
/obj/structure/vehiclecage
|
||||
name = "vehicle cage"
|
||||
desc = "A large metal lattice that seems to exist solely to annoy consumers."
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "vehicle_cage"
|
||||
density = 1
|
||||
var/obj/vehicle/my_vehicle
|
||||
var/my_vehicle_type
|
||||
var/paint_color = "#666666"
|
||||
|
||||
/obj/structure/vehiclecage/examine(mob/user)
|
||||
..()
|
||||
if(my_vehicle)
|
||||
to_chat(user, "<span class='notice'>It seems to contain \the [my_vehicle].</span>")
|
||||
|
||||
/obj/structure/vehiclecage/Initialize()
|
||||
. = ..()
|
||||
if(my_vehicle_type)
|
||||
my_vehicle = new my_vehicle_type(src)
|
||||
for(var/obj/I in get_turf(src))
|
||||
if(I.density || I.anchored || I == src || !I.simulated || !istype(I, my_vehicle_type))
|
||||
continue
|
||||
load_vehicle(I)
|
||||
update_icon()
|
||||
|
||||
/obj/structure/vehiclecage/attack_hand(mob/user as mob)
|
||||
to_chat(user, "<span class='notice'>You need a wrench to take this apart!</span>")
|
||||
return
|
||||
|
||||
/obj/structure/vehiclecage/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T)
|
||||
to_chat(user, "<span class='notice'>You can't open this here!</span>")
|
||||
if(W.is_wrench() && do_after(user, 60 * W.toolspeed, src))
|
||||
playsound(loc, W.usesound, 50, 1)
|
||||
disassemble(W, user)
|
||||
user.visible_message("<span class='notice'>[user] begins loosening \the [src]'s bolts.</span>")
|
||||
if(W.is_wirecutter() && do_after(user, 70 * W.toolspeed, src))
|
||||
playsound(loc, W.usesound, 50, 1)
|
||||
disassemble(W, user)
|
||||
user.visible_message("<span class='notice'>[user] begins cutting \the [src]'s bolts.</span>")
|
||||
else
|
||||
return attack_hand(user)
|
||||
|
||||
/obj/structure/vehiclecage/update_icon()
|
||||
..()
|
||||
overlays.Cut()
|
||||
underlays.Cut()
|
||||
|
||||
var/image/framepaint = new(icon = 'icons/obj/storage.dmi', icon_state = "[initial(icon_state)]_a", layer = MOB_LAYER + 1.1)
|
||||
framepaint.plane = MOB_PLANE
|
||||
framepaint.color = paint_color
|
||||
overlays += framepaint
|
||||
|
||||
for(var/obj/vehicle/V in src.contents)
|
||||
var/image/showcase = new(V)
|
||||
showcase.layer = src.layer - 0.1
|
||||
underlays += showcase
|
||||
|
||||
/obj/structure/vehiclecage/MouseDrop_T(var/atom/movable/C, mob/user as mob)
|
||||
if(user && (user.buckled || user.stat || user.restrained() || !Adjacent(user) || !user.Adjacent(C)))
|
||||
return
|
||||
|
||||
var/obj/vehicle/V
|
||||
if(istype(C, /obj/vehicle))
|
||||
V = C
|
||||
if(!V)
|
||||
return
|
||||
|
||||
if(!my_vehicle)
|
||||
load_vehicle(V, user)
|
||||
|
||||
/obj/structure/vehiclecage/proc/load_vehicle(var/obj/vehicle/V, mob/user as mob)
|
||||
if(user)
|
||||
user.visible_message("<span class='notice'>[user] loads \the [V] into \the [src].</span>", \
|
||||
"<span class='notice'>You load \the [V] into \the [src].</span>", \
|
||||
"<span class='notice'>You hear creaking metal.</span>")
|
||||
|
||||
V.forceMove(src)
|
||||
|
||||
paint_color = V.paint_color
|
||||
|
||||
update_icon()
|
||||
|
||||
/obj/structure/vehiclecage/proc/disassemble(obj/item/weapon/W as obj, mob/user as mob)
|
||||
var/turf/T = get_turf(src)
|
||||
new /obj/item/stack/material/steel(src.loc, 5)
|
||||
|
||||
for(var/atom/movable/AM in contents)
|
||||
if(AM.simulated)
|
||||
AM.forceMove(T)
|
||||
|
||||
my_vehicle = null
|
||||
user.visible_message("<span class='notice'>[user] release \the [src].</span>", \
|
||||
"<span class='notice'>You finally release \the [src].</span>", \
|
||||
"<span class='notice'>You hear creaking metal.</span>")
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/vehiclecage/spacebike
|
||||
my_vehicle_type = /obj/vehicle/bike/random
|
||||
|
||||
/obj/structure/vehiclecage/quadbike
|
||||
my_vehicle_type = /obj/vehicle/train/engine/quadbike/random
|
||||
|
||||
/obj/structure/vehiclecage/quadtrailer
|
||||
my_vehicle_type = /obj/vehicle/train/trolley/trailer/random
|
||||
@@ -304,7 +304,7 @@
|
||||
light_power = 0.6
|
||||
light_color = "#FF6633"
|
||||
|
||||
/obj/structure/flora/sif/subterranean/initialize()
|
||||
/obj/structure/flora/sif/subterranean/Initialize()
|
||||
icon_state = "[initial(icon_state)][rand(1,2)]"
|
||||
. = ..()
|
||||
|
||||
@@ -313,6 +313,6 @@
|
||||
desc = "This is a mysterious looking plant. They kind of look like eyeballs. Creepy."
|
||||
icon_state = "eyeplant"
|
||||
|
||||
/obj/structure/flora/sif/eyes/initialize()
|
||||
/obj/structure/flora/sif/eyes/Initialize()
|
||||
icon_state = "[initial(icon_state)][rand(1,3)]"
|
||||
. = ..()
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
var/delay_to_self_open = 10 MINUTES // How long to wait for first attempt. Note that the timer by default starts when the pod is created.
|
||||
var/delay_to_try_again = 20 MINUTES // How long to wait if first attempt fails. Set to 0 to never try again.
|
||||
|
||||
/obj/structure/ghost_pod/automatic/initialize()
|
||||
/obj/structure/ghost_pod/automatic/Initialize()
|
||||
. = ..()
|
||||
spawn(delay_to_self_open)
|
||||
if(src)
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
/obj/structure/ghost_pod/manual/corgi/create_occupant(var/mob/M)
|
||||
lightning_strike(get_turf(src), cosmetic = TRUE)
|
||||
density = FALSE
|
||||
var/mob/living/simple_animal/corgi/R = new(get_turf(src))
|
||||
var/mob/living/simple_mob/animal/passive/dog/corgi/R = new(get_turf(src))
|
||||
if(M.mind)
|
||||
M.mind.transfer_to(R)
|
||||
to_chat(M, "<span class='notice'>You are a <b>Corgi</b>! Woof!</span>")
|
||||
@@ -47,4 +47,4 @@
|
||||
R.ghost_inhabit(M)
|
||||
visible_message("<span class='warning'>The blade shines brightly for a brief moment as [usr] pulls it out of the stone!</span>")
|
||||
log_and_message_admins("successfully acquired a cursed sword.")
|
||||
..()
|
||||
..()
|
||||
|
||||
@@ -25,12 +25,12 @@
|
||||
|
||||
/obj/structure/girder/Destroy()
|
||||
if(girder_material.products_need_process())
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
. = ..()
|
||||
|
||||
/obj/structure/girder/process()
|
||||
if(!radiate())
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return
|
||||
|
||||
/obj/structure/girder/proc/radiate()
|
||||
@@ -53,9 +53,9 @@
|
||||
if(applies_material_colour)
|
||||
color = girder_material.icon_colour
|
||||
if(girder_material.products_need_process()) //Am I radioactive or some other? Process me!
|
||||
processing_objects |= src
|
||||
else if(src in processing_objects) //If I happened to be radioactive or s.o. previously, and am not now, stop processing.
|
||||
processing_objects -= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
else if(is_processing) //If I happened to be radioactive or s.o. previously, and am not now, stop processing.
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/structure/girder/get_material()
|
||||
return girder_material
|
||||
@@ -83,8 +83,8 @@
|
||||
health = (displaced_health - round(current_damage / 4))
|
||||
cover = 25
|
||||
|
||||
/obj/structure/girder/attack_generic(var/mob/user, var/damage, var/attack_message = "smashes apart", var/wallbreaker)
|
||||
if(!damage || !wallbreaker)
|
||||
/obj/structure/girder/attack_generic(var/mob/user, var/damage, var/attack_message = "smashes apart")
|
||||
if(damage < STRUCTURE_MIN_DAMAGE_THRESHOLD)
|
||||
return 0
|
||||
user.do_attack_animation(src)
|
||||
visible_message("<span class='danger'>[user] [attack_message] the [src]!</span>")
|
||||
@@ -353,3 +353,54 @@
|
||||
to_chat(user, "<span class='notice'>You drill through the girder!</span>")
|
||||
new /obj/effect/decal/remains/human(get_turf(src))
|
||||
dismantle()
|
||||
|
||||
|
||||
/obj/structure/girder/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
|
||||
var/turf/simulated/T = get_turf(src)
|
||||
if(!istype(T) || T.density)
|
||||
return FALSE
|
||||
|
||||
switch(passed_mode)
|
||||
if(RCD_FLOORWALL)
|
||||
// Finishing a wall costs two sheets.
|
||||
var/cost = RCD_SHEETS_PER_MATTER_UNIT * 2
|
||||
// Rwalls cost three to finish.
|
||||
if(the_rcd.make_rwalls)
|
||||
cost += RCD_SHEETS_PER_MATTER_UNIT * 1
|
||||
return list(
|
||||
RCD_VALUE_MODE = RCD_FLOORWALL,
|
||||
RCD_VALUE_DELAY = 2 SECONDS,
|
||||
RCD_VALUE_COST = cost
|
||||
)
|
||||
if(RCD_DECONSTRUCT)
|
||||
return list(
|
||||
RCD_VALUE_MODE = RCD_DECONSTRUCT,
|
||||
RCD_VALUE_DELAY = 2 SECONDS,
|
||||
RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 5
|
||||
)
|
||||
return FALSE
|
||||
|
||||
/obj/structure/girder/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
|
||||
var/turf/simulated/T = get_turf(src)
|
||||
if(!istype(T) || T.density) // Should stop future bugs of people bringing girders to centcom and RCDing them, or somehow putting a girder on a durasteel wall and deconning it.
|
||||
return FALSE
|
||||
|
||||
switch(passed_mode)
|
||||
if(RCD_FLOORWALL)
|
||||
to_chat(user, span("notice", "You finish a wall."))
|
||||
// This is mostly the same as using on a floor. The girder's material is preserved, however.
|
||||
T.ChangeTurf(/turf/simulated/wall)
|
||||
var/turf/simulated/wall/new_T = get_turf(src) // Ref to the wall we just built.
|
||||
// Apparently set_material(...) for walls requires refs to the material singletons and not strings.
|
||||
// This is different from how other material objects with their own set_material(...) do it, but whatever.
|
||||
var/material/M = name_to_material[the_rcd.material_to_use]
|
||||
new_T.set_material(M, the_rcd.make_rwalls ? M : null, girder_material)
|
||||
new_T.add_hiddenprint(user)
|
||||
qdel(src)
|
||||
return TRUE
|
||||
|
||||
if(RCD_DECONSTRUCT)
|
||||
to_chat(user, span("notice", "You deconstruct \the [src]."))
|
||||
qdel(src)
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
src.set_dir(turn(src.dir, 90))
|
||||
return
|
||||
else
|
||||
if(istype(usr,/mob/living/simple_animal/mouse))
|
||||
if(ismouse(usr))
|
||||
return
|
||||
if(!usr || !isturf(usr.loc))
|
||||
return
|
||||
|
||||
@@ -93,10 +93,12 @@
|
||||
src.health -= damage*0.2
|
||||
spawn(0) healthcheck() //spawn to make sure we return properly if the grille is deleted
|
||||
|
||||
/obj/structure/grille/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
/obj/structure/grille/attackby(obj/item/W as obj, mob/user as mob)
|
||||
if(!istype(W))
|
||||
return
|
||||
if(W.is_wirecutter())
|
||||
if(istype(W, /obj/item/weapon/rcd)) // To stop us from hitting the grille when building windows, because grilles don't let parent handle it properly.
|
||||
return FALSE
|
||||
else if(W.is_wirecutter())
|
||||
if(!shock(user, 100))
|
||||
playsound(src, W.usesound, 100, 1)
|
||||
new /obj/item/stack/rods(get_turf(src), destroyed ? 1 : 2)
|
||||
@@ -109,7 +111,7 @@
|
||||
"<span class='notice'>You have [anchored ? "fastened the grille to" : "unfastened the grille from"] the floor.</span>")
|
||||
return
|
||||
|
||||
//window placing begin //TODO CONVERT PROPERLY TO MATERIAL DATUM
|
||||
//window placing begin //TODO CONVERT PROPERLY TO MATERIAL DATUM
|
||||
else if(istype(W,/obj/item/stack/material))
|
||||
var/obj/item/stack/material/ST = W
|
||||
if(!ST.material.created_window)
|
||||
@@ -252,3 +254,38 @@
|
||||
|
||||
/obj/structure/grille/broken/rustic
|
||||
icon_state = "grillerustic-b"
|
||||
|
||||
|
||||
/obj/structure/grille/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
|
||||
switch(passed_mode)
|
||||
if(RCD_WINDOWGRILLE)
|
||||
// A full tile window costs 4 glass sheets.
|
||||
return list(
|
||||
RCD_VALUE_MODE = RCD_WINDOWGRILLE,
|
||||
RCD_VALUE_DELAY = 2 SECONDS,
|
||||
RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 4
|
||||
)
|
||||
|
||||
if(RCD_DECONSTRUCT)
|
||||
return list(
|
||||
RCD_VALUE_MODE = RCD_DECONSTRUCT,
|
||||
RCD_VALUE_DELAY = 2 SECONDS,
|
||||
RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 2
|
||||
)
|
||||
return FALSE
|
||||
|
||||
/obj/structure/grille/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
|
||||
switch(passed_mode)
|
||||
if(RCD_DECONSTRUCT)
|
||||
to_chat(user, span("notice", "You deconstruct \the [src]."))
|
||||
qdel(src)
|
||||
return TRUE
|
||||
if(RCD_WINDOWGRILLE)
|
||||
if(locate(/obj/structure/window) in loc)
|
||||
return FALSE
|
||||
to_chat(user, span("notice", "You construct a window."))
|
||||
var/obj/structure/window/WD = new the_rcd.window_type(loc)
|
||||
WD.anchored = TRUE
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"plant-13"
|
||||
)
|
||||
|
||||
/obj/machinery/holoplant/initialize()
|
||||
/obj/machinery/holoplant/Initialize()
|
||||
. = ..()
|
||||
activate()
|
||||
|
||||
@@ -101,5 +101,5 @@
|
||||
|
||||
/obj/machinery/holoplant/shipped
|
||||
anchored = FALSE
|
||||
/obj/machinery/holoplant/shipped/initialize()
|
||||
/obj/machinery/holoplant/shipped/Initialize()
|
||||
. = ..()
|
||||
@@ -9,7 +9,7 @@
|
||||
plane = PLATING_PLANE
|
||||
// flags = CONDUCT
|
||||
|
||||
/obj/structure/lattice/initialize()
|
||||
/obj/structure/lattice/Initialize()
|
||||
. = ..()
|
||||
|
||||
if(!(istype(src.loc, /turf/space) || istype(src.loc, /turf/simulated/open) || istype(src.loc, /turf/simulated/mineral)))
|
||||
|
||||
@@ -115,7 +115,7 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh
|
||||
var/path = pick(rare_loot)
|
||||
return new path(src)
|
||||
|
||||
/obj/structure/loot_pile/initialize()
|
||||
/obj/structure/loot_pile/Initialize()
|
||||
if(icon_states_to_use && icon_states_to_use.len)
|
||||
icon_state = pick(icon_states_to_use)
|
||||
. = ..()
|
||||
@@ -574,6 +574,7 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh
|
||||
icon = 'icons/mecha/mecha.dmi'
|
||||
icon_state = "engineering_pod-broken"
|
||||
density = TRUE
|
||||
anchored = FALSE // In case a dead mecha-mob dies in a bad spot.
|
||||
|
||||
chance_uncommon = 20
|
||||
chance_rare = 10
|
||||
@@ -615,7 +616,7 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh
|
||||
/obj/structure/loot_pile/mecha/ripley
|
||||
name = "ripley wreckage"
|
||||
desc = "The ruins of some unfortunate ripley. Perhaps something is salvageable."
|
||||
icon_states_to_use = list("ripley-broken", "firefighter-broken", "ripley-broken-old")
|
||||
icon_state = "ripley-broken"
|
||||
|
||||
common_loot = list(
|
||||
/obj/random/tool,
|
||||
@@ -649,6 +650,12 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/energy/flamer/rigged
|
||||
)
|
||||
|
||||
/obj/structure/loot_pile/mecha/ripley/firefighter
|
||||
icon_state = "firefighter-broken"
|
||||
|
||||
/obj/structure/loot_pile/mecha/ripley/random_sprite
|
||||
icon_states_to_use = list("ripley-broken", "firefighter-broken", "ripley-broken-old")
|
||||
|
||||
//Death-Ripley, same common, but more combat-exosuit-based
|
||||
/obj/structure/loot_pile/mecha/deathripley
|
||||
name = "strange ripley wreckage"
|
||||
@@ -719,6 +726,14 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh
|
||||
/obj/item/mecha_parts/mecha_equipment/shocker
|
||||
)
|
||||
|
||||
/obj/structure/loot_pile/mecha/odysseus/murdysseus
|
||||
icon_state = "murdysseus-broken"
|
||||
|
||||
/obj/structure/loot_pile/mecha/hoverpod
|
||||
name = "hoverpod wreckage"
|
||||
desc = "The ruins of some unfortunate hoverpod. Perhaps something is salvageable."
|
||||
icon_state = "engineering_pod"
|
||||
|
||||
/obj/structure/loot_pile/mecha/gygax
|
||||
name = "gygax wreckage"
|
||||
desc = "The ruins of some unfortunate gygax. Perhaps something is salvageable."
|
||||
@@ -759,6 +774,18 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy
|
||||
)
|
||||
|
||||
/obj/structure/loot_pile/mecha/gygax/dark
|
||||
icon_state = "darkgygax-broken"
|
||||
|
||||
// Todo: Better loot.
|
||||
/obj/structure/loot_pile/mecha/gygax/dark/adv
|
||||
icon_state = "darkgygax_adv-broken"
|
||||
icon_scale = 1.5
|
||||
pixel_y = 8
|
||||
|
||||
/obj/structure/loot_pile/mecha/gygax/medgax
|
||||
icon_state = "medgax-broken"
|
||||
|
||||
/obj/structure/loot_pile/mecha/durand
|
||||
name = "durand wreckage"
|
||||
desc = "The ruins of some unfortunate durand. Perhaps something is salvageable."
|
||||
@@ -799,6 +826,22 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy
|
||||
)
|
||||
|
||||
/obj/structure/loot_pile/mecha/marauder
|
||||
name = "marauder wreckage"
|
||||
desc = "The ruins of some unfortunate marauder. Perhaps something is salvagable."
|
||||
icon_state = "marauder-broken"
|
||||
// Todo: Better loot.
|
||||
|
||||
/obj/structure/loot_pile/mecha/marauder/seraph
|
||||
name = "seraph wreckage"
|
||||
desc = "The ruins of some unfortunate seraph. Perhaps something is salvagable."
|
||||
icon_state = "seraph-broken"
|
||||
|
||||
/obj/structure/loot_pile/mecha/marauder/mauler
|
||||
name = "mauler wreckage"
|
||||
desc = "The ruins of some unfortunate mauler. Perhaps something is salvagable."
|
||||
icon_state = "mauler-broken"
|
||||
|
||||
/obj/structure/loot_pile/mecha/phazon
|
||||
name = "phazon wreckage"
|
||||
desc = "The ruins of some unfortunate phazon. Perhaps something is salvageable."
|
||||
|
||||
@@ -1,253 +1,110 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
|
||||
|
||||
#define MUSICIAN_HEARCHECK_MINDELAY 4
|
||||
#define INSTRUMENT_MAX_LINE_LENGTH 300
|
||||
#define INSTRUMENT_MAX_LINE_NUMBER 50
|
||||
|
||||
/datum/song
|
||||
var/name = "Untitled"
|
||||
var/list/lines = new()
|
||||
var/tempo = 5
|
||||
var/tempo = 5 // delay between notes
|
||||
|
||||
/obj/structure/device/piano
|
||||
name = "space minimoog"
|
||||
icon = 'icons/obj/musician.dmi'
|
||||
icon_state = "minimoog"
|
||||
anchored = 1
|
||||
density = 1
|
||||
var/datum/song/song
|
||||
var/playing = 0
|
||||
var/help = 0
|
||||
var/edit = 1
|
||||
var/repeat = 0
|
||||
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
|
||||
|
||||
/obj/structure/device/piano/New()
|
||||
if(prob(50))
|
||||
name = "space minimoog"
|
||||
desc = "This is a minimoog, like a space piano, but more spacey!"
|
||||
icon_state = "minimoog"
|
||||
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")
|
||||
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 hearers(15, source))
|
||||
if(!M.client || !(M.is_preference_enabled(/datum/client_preference/instrument_toggle)))
|
||||
continue
|
||||
LAZYSET(hearing_mobs, M, TRUE)
|
||||
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(!instrumentObj.Adjacent(user) || user.stat)
|
||||
return 1
|
||||
return !instrumentObj.anchored // add special cases to stop in subclasses
|
||||
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"
|
||||
return 1
|
||||
|
||||
/obj/structure/device/piano/verb/rotate()
|
||||
set name = "Rotate Piano"
|
||||
set category = "Object"
|
||||
set src in oview(1)
|
||||
|
||||
if(istype(usr,/mob/living/simple_animal/mouse))
|
||||
return
|
||||
else if(!usr || !isturf(usr.loc))
|
||||
return
|
||||
else if(usr.stat || usr.restrained())
|
||||
return
|
||||
else if (istype(usr,/mob/observer/ghost) && !config.ghost_interaction)
|
||||
return
|
||||
else
|
||||
src.set_dir(turn(src.dir, 90))
|
||||
return
|
||||
|
||||
/obj/structure/device/piano/proc/playnote(var/note as text)
|
||||
//world << "Note: [note]"
|
||||
var/soundfile
|
||||
/*BYOND loads resource files at compile time if they are ''. This means you can't really manipulate them dynamically.
|
||||
Tried doing it dynamically at first but its more trouble than its worth. Would have saved many lines tho.*/
|
||||
switch(note)
|
||||
if("Cn1") soundfile = 'sound/piano/Cn1.ogg'
|
||||
if("C#1") soundfile = 'sound/piano/C#1.ogg'
|
||||
if("Db1") soundfile = 'sound/piano/Db1.ogg'
|
||||
if("Dn1") soundfile = 'sound/piano/Dn1.ogg'
|
||||
if("D#1") soundfile = 'sound/piano/D#1.ogg'
|
||||
if("Eb1") soundfile = 'sound/piano/Eb1.ogg'
|
||||
if("En1") soundfile = 'sound/piano/En1.ogg'
|
||||
if("E#1") soundfile = 'sound/piano/E#1.ogg'
|
||||
if("Fb1") soundfile = 'sound/piano/Fb1.ogg'
|
||||
if("Fn1") soundfile = 'sound/piano/Fn1.ogg'
|
||||
if("F#1") soundfile = 'sound/piano/F#1.ogg'
|
||||
if("Gb1") soundfile = 'sound/piano/Gb1.ogg'
|
||||
if("Gn1") soundfile = 'sound/piano/Gn1.ogg'
|
||||
if("G#1") soundfile = 'sound/piano/G#1.ogg'
|
||||
if("Ab1") soundfile = 'sound/piano/Ab1.ogg'
|
||||
if("An1") soundfile = 'sound/piano/An1.ogg'
|
||||
if("A#1") soundfile = 'sound/piano/A#1.ogg'
|
||||
if("Bb1") soundfile = 'sound/piano/Bb1.ogg'
|
||||
if("Bn1") soundfile = 'sound/piano/Bn1.ogg'
|
||||
if("B#1") soundfile = 'sound/piano/B#1.ogg'
|
||||
if("Cb2") soundfile = 'sound/piano/Cb2.ogg'
|
||||
if("Cn2") soundfile = 'sound/piano/Cn2.ogg'
|
||||
if("C#2") soundfile = 'sound/piano/C#2.ogg'
|
||||
if("Db2") soundfile = 'sound/piano/Db2.ogg'
|
||||
if("Dn2") soundfile = 'sound/piano/Dn2.ogg'
|
||||
if("D#2") soundfile = 'sound/piano/D#2.ogg'
|
||||
if("Eb2") soundfile = 'sound/piano/Eb2.ogg'
|
||||
if("En2") soundfile = 'sound/piano/En2.ogg'
|
||||
if("E#2") soundfile = 'sound/piano/E#2.ogg'
|
||||
if("Fb2") soundfile = 'sound/piano/Fb2.ogg'
|
||||
if("Fn2") soundfile = 'sound/piano/Fn2.ogg'
|
||||
if("F#2") soundfile = 'sound/piano/F#2.ogg'
|
||||
if("Gb2") soundfile = 'sound/piano/Gb2.ogg'
|
||||
if("Gn2") soundfile = 'sound/piano/Gn2.ogg'
|
||||
if("G#2") soundfile = 'sound/piano/G#2.ogg'
|
||||
if("Ab2") soundfile = 'sound/piano/Ab2.ogg'
|
||||
if("An2") soundfile = 'sound/piano/An2.ogg'
|
||||
if("A#2") soundfile = 'sound/piano/A#2.ogg'
|
||||
if("Bb2") soundfile = 'sound/piano/Bb2.ogg'
|
||||
if("Bn2") soundfile = 'sound/piano/Bn2.ogg'
|
||||
if("B#2") soundfile = 'sound/piano/B#2.ogg'
|
||||
if("Cb3") soundfile = 'sound/piano/Cb3.ogg'
|
||||
if("Cn3") soundfile = 'sound/piano/Cn3.ogg'
|
||||
if("C#3") soundfile = 'sound/piano/C#3.ogg'
|
||||
if("Db3") soundfile = 'sound/piano/Db3.ogg'
|
||||
if("Dn3") soundfile = 'sound/piano/Dn3.ogg'
|
||||
if("D#3") soundfile = 'sound/piano/D#3.ogg'
|
||||
if("Eb3") soundfile = 'sound/piano/Eb3.ogg'
|
||||
if("En3") soundfile = 'sound/piano/En3.ogg'
|
||||
if("E#3") soundfile = 'sound/piano/E#3.ogg'
|
||||
if("Fb3") soundfile = 'sound/piano/Fb3.ogg'
|
||||
if("Fn3") soundfile = 'sound/piano/Fn3.ogg'
|
||||
if("F#3") soundfile = 'sound/piano/F#3.ogg'
|
||||
if("Gb3") soundfile = 'sound/piano/Gb3.ogg'
|
||||
if("Gn3") soundfile = 'sound/piano/Gn3.ogg'
|
||||
if("G#3") soundfile = 'sound/piano/G#3.ogg'
|
||||
if("Ab3") soundfile = 'sound/piano/Ab3.ogg'
|
||||
if("An3") soundfile = 'sound/piano/An3.ogg'
|
||||
if("A#3") soundfile = 'sound/piano/A#3.ogg'
|
||||
if("Bb3") soundfile = 'sound/piano/Bb3.ogg'
|
||||
if("Bn3") soundfile = 'sound/piano/Bn3.ogg'
|
||||
if("B#3") soundfile = 'sound/piano/B#3.ogg'
|
||||
if("Cb4") soundfile = 'sound/piano/Cb4.ogg'
|
||||
if("Cn4") soundfile = 'sound/piano/Cn4.ogg'
|
||||
if("C#4") soundfile = 'sound/piano/C#4.ogg'
|
||||
if("Db4") soundfile = 'sound/piano/Db4.ogg'
|
||||
if("Dn4") soundfile = 'sound/piano/Dn4.ogg'
|
||||
if("D#4") soundfile = 'sound/piano/D#4.ogg'
|
||||
if("Eb4") soundfile = 'sound/piano/Eb4.ogg'
|
||||
if("En4") soundfile = 'sound/piano/En4.ogg'
|
||||
if("E#4") soundfile = 'sound/piano/E#4.ogg'
|
||||
if("Fb4") soundfile = 'sound/piano/Fb4.ogg'
|
||||
if("Fn4") soundfile = 'sound/piano/Fn4.ogg'
|
||||
if("F#4") soundfile = 'sound/piano/F#4.ogg'
|
||||
if("Gb4") soundfile = 'sound/piano/Gb4.ogg'
|
||||
if("Gn4") soundfile = 'sound/piano/Gn4.ogg'
|
||||
if("G#4") soundfile = 'sound/piano/G#4.ogg'
|
||||
if("Ab4") soundfile = 'sound/piano/Ab4.ogg'
|
||||
if("An4") soundfile = 'sound/piano/An4.ogg'
|
||||
if("A#4") soundfile = 'sound/piano/A#4.ogg'
|
||||
if("Bb4") soundfile = 'sound/piano/Bb4.ogg'
|
||||
if("Bn4") soundfile = 'sound/piano/Bn4.ogg'
|
||||
if("B#4") soundfile = 'sound/piano/B#4.ogg'
|
||||
if("Cb5") soundfile = 'sound/piano/Cb5.ogg'
|
||||
if("Cn5") soundfile = 'sound/piano/Cn5.ogg'
|
||||
if("C#5") soundfile = 'sound/piano/C#5.ogg'
|
||||
if("Db5") soundfile = 'sound/piano/Db5.ogg'
|
||||
if("Dn5") soundfile = 'sound/piano/Dn5.ogg'
|
||||
if("D#5") soundfile = 'sound/piano/D#5.ogg'
|
||||
if("Eb5") soundfile = 'sound/piano/Eb5.ogg'
|
||||
if("En5") soundfile = 'sound/piano/En5.ogg'
|
||||
if("E#5") soundfile = 'sound/piano/E#5.ogg'
|
||||
if("Fb5") soundfile = 'sound/piano/Fb5.ogg'
|
||||
if("Fn5") soundfile = 'sound/piano/Fn5.ogg'
|
||||
if("F#5") soundfile = 'sound/piano/F#5.ogg'
|
||||
if("Gb5") soundfile = 'sound/piano/Gb5.ogg'
|
||||
if("Gn5") soundfile = 'sound/piano/Gn5.ogg'
|
||||
if("G#5") soundfile = 'sound/piano/G#5.ogg'
|
||||
if("Ab5") soundfile = 'sound/piano/Ab5.ogg'
|
||||
if("An5") soundfile = 'sound/piano/An5.ogg'
|
||||
if("A#5") soundfile = 'sound/piano/A#5.ogg'
|
||||
if("Bb5") soundfile = 'sound/piano/Bb5.ogg'
|
||||
if("Bn5") soundfile = 'sound/piano/Bn5.ogg'
|
||||
if("B#5") soundfile = 'sound/piano/B#5.ogg'
|
||||
if("Cb6") soundfile = 'sound/piano/Cb6.ogg'
|
||||
if("Cn6") soundfile = 'sound/piano/Cn6.ogg'
|
||||
if("C#6") soundfile = 'sound/piano/C#6.ogg'
|
||||
if("Db6") soundfile = 'sound/piano/Db6.ogg'
|
||||
if("Dn6") soundfile = 'sound/piano/Dn6.ogg'
|
||||
if("D#6") soundfile = 'sound/piano/D#6.ogg'
|
||||
if("Eb6") soundfile = 'sound/piano/Eb6.ogg'
|
||||
if("En6") soundfile = 'sound/piano/En6.ogg'
|
||||
if("E#6") soundfile = 'sound/piano/E#6.ogg'
|
||||
if("Fb6") soundfile = 'sound/piano/Fb6.ogg'
|
||||
if("Fn6") soundfile = 'sound/piano/Fn6.ogg'
|
||||
if("F#6") soundfile = 'sound/piano/F#6.ogg'
|
||||
if("Gb6") soundfile = 'sound/piano/Gb6.ogg'
|
||||
if("Gn6") soundfile = 'sound/piano/Gn6.ogg'
|
||||
if("G#6") soundfile = 'sound/piano/G#6.ogg'
|
||||
if("Ab6") soundfile = 'sound/piano/Ab6.ogg'
|
||||
if("An6") soundfile = 'sound/piano/An6.ogg'
|
||||
if("A#6") soundfile = 'sound/piano/A#6.ogg'
|
||||
if("Bb6") soundfile = 'sound/piano/Bb6.ogg'
|
||||
if("Bn6") soundfile = 'sound/piano/Bn6.ogg'
|
||||
if("B#6") soundfile = 'sound/piano/B#6.ogg'
|
||||
if("Cb7") soundfile = 'sound/piano/Cb7.ogg'
|
||||
if("Cn7") soundfile = 'sound/piano/Cn7.ogg'
|
||||
if("C#7") soundfile = 'sound/piano/C#7.ogg'
|
||||
if("Db7") soundfile = 'sound/piano/Db7.ogg'
|
||||
if("Dn7") soundfile = 'sound/piano/Dn7.ogg'
|
||||
if("D#7") soundfile = 'sound/piano/D#7.ogg'
|
||||
if("Eb7") soundfile = 'sound/piano/Eb7.ogg'
|
||||
if("En7") soundfile = 'sound/piano/En7.ogg'
|
||||
if("E#7") soundfile = 'sound/piano/E#7.ogg'
|
||||
if("Fb7") soundfile = 'sound/piano/Fb7.ogg'
|
||||
if("Fn7") soundfile = 'sound/piano/Fn7.ogg'
|
||||
if("F#7") soundfile = 'sound/piano/F#7.ogg'
|
||||
if("Gb7") soundfile = 'sound/piano/Gb7.ogg'
|
||||
if("Gn7") soundfile = 'sound/piano/Gn7.ogg'
|
||||
if("G#7") soundfile = 'sound/piano/G#7.ogg'
|
||||
if("Ab7") soundfile = 'sound/piano/Ab7.ogg'
|
||||
if("An7") soundfile = 'sound/piano/An7.ogg'
|
||||
if("A#7") soundfile = 'sound/piano/A#7.ogg'
|
||||
if("Bb7") soundfile = 'sound/piano/Bb7.ogg'
|
||||
if("Bn7") soundfile = 'sound/piano/Bn7.ogg'
|
||||
if("B#7") soundfile = 'sound/piano/B#7.ogg'
|
||||
if("Cb8") soundfile = 'sound/piano/Cb8.ogg'
|
||||
if("Cn8") soundfile = 'sound/piano/Cn8.ogg'
|
||||
if("C#8") soundfile = 'sound/piano/C#8.ogg'
|
||||
if("Db8") soundfile = 'sound/piano/Db8.ogg'
|
||||
if("Dn8") soundfile = 'sound/piano/Dn8.ogg'
|
||||
if("D#8") soundfile = 'sound/piano/D#8.ogg'
|
||||
if("Eb8") soundfile = 'sound/piano/Eb8.ogg'
|
||||
if("En8") soundfile = 'sound/piano/En8.ogg'
|
||||
if("E#8") soundfile = 'sound/piano/E#8.ogg'
|
||||
if("Fb8") soundfile = 'sound/piano/Fb8.ogg'
|
||||
if("Fn8") soundfile = 'sound/piano/Fn8.ogg'
|
||||
if("F#8") soundfile = 'sound/piano/F#8.ogg'
|
||||
if("Gb8") soundfile = 'sound/piano/Gb8.ogg'
|
||||
if("Gn8") soundfile = 'sound/piano/Gn8.ogg'
|
||||
if("G#8") soundfile = 'sound/piano/G#8.ogg'
|
||||
if("Ab8") soundfile = 'sound/piano/Ab8.ogg'
|
||||
if("An8") soundfile = 'sound/piano/An8.ogg'
|
||||
if("A#8") soundfile = 'sound/piano/A#8.ogg'
|
||||
if("Bb8") soundfile = 'sound/piano/Bb8.ogg'
|
||||
if("Bn8") soundfile = 'sound/piano/Bn8.ogg'
|
||||
if("B#8") soundfile = 'sound/piano/B#8.ogg'
|
||||
if("Cb9") soundfile = 'sound/piano/Cb9.ogg'
|
||||
if("Cn9") soundfile = 'sound/piano/Cn9.ogg'
|
||||
else return
|
||||
|
||||
//hearers(15, src) << sound(soundfile)
|
||||
var/turf/source = get_turf(src)
|
||||
for(var/mob/M in hearers(15, source))
|
||||
M.playsound_local(source, file(soundfile), 100, falloff = 5)
|
||||
|
||||
|
||||
/obj/structure/device/piano/proc/playsong()
|
||||
do
|
||||
/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_oct[i] = 3
|
||||
cur_acc[i] = "n"
|
||||
|
||||
for(var/line in song.lines)
|
||||
//world << line
|
||||
for(var/line in lines)
|
||||
for(var/beat in splittext(lowertext(line), ","))
|
||||
//world << "beat: [beat]"
|
||||
var/list/notes = splittext(beat, "/")
|
||||
for(var/note in splittext(notes[1], "-"))
|
||||
//world << "note: [note]"
|
||||
if(!playing || !anchored)//If the piano is playing, or is loose
|
||||
if(!playing || shouldStopPlaying(user))//If the instrument is playing, or special case
|
||||
playing = 0
|
||||
return
|
||||
if(lentext(note) == 0)
|
||||
continue
|
||||
//world << "Parse: [copytext(note,1,2)]"
|
||||
var/cur_note = text2ascii(note) - 96
|
||||
if(cur_note < 1 || cur_note > 7)
|
||||
continue
|
||||
@@ -259,49 +116,47 @@
|
||||
else if(ni == "s")
|
||||
cur_acc[cur_note] = "#" // so shift is never required
|
||||
else
|
||||
cur_oct[cur_note] = ni
|
||||
playnote(uppertext(copytext(note,1,2)) + cur_acc[cur_note] + cur_oct[cur_note])
|
||||
cur_oct[cur_note] = text2num(ni)
|
||||
playnote(cur_note, cur_acc[cur_note], cur_oct[cur_note])
|
||||
if(notes.len >= 2 && text2num(notes[2]))
|
||||
sleep(song.tempo / text2num(notes[2]))
|
||||
sleep(sanitize_tempo(tempo / text2num(notes[2])))
|
||||
else
|
||||
sleep(song.tempo)
|
||||
if(repeat > 0)
|
||||
repeat-- //Infinite loops are baaaad.
|
||||
while(repeat > 0)
|
||||
sleep(tempo)
|
||||
repeat--
|
||||
playing = 0
|
||||
updateUsrDialog()
|
||||
repeat = 0
|
||||
updateDialog(user)
|
||||
|
||||
/obj/structure/device/piano/attack_hand(var/mob/user as mob)
|
||||
if(!anchored)
|
||||
return
|
||||
|
||||
usr.machine = src
|
||||
var/dat = "<HEAD><TITLE>Piano</TITLE></HEAD><BODY>"
|
||||
|
||||
if(song)
|
||||
if(song.lines.len > 0 && !(playing))
|
||||
dat += "<A href='?src=\ref[src];play=1'>Play Song</A><BR><BR>"
|
||||
dat += "<A href='?src=\ref[src];repeat=1'>Repeat Song: [repeat] times.</A><BR><BR>"
|
||||
if(playing)
|
||||
dat += "<A href='?src=\ref[src];stop=1'>Stop Playing</A><BR>"
|
||||
dat += "Repeats left: [repeat].<BR><BR>"
|
||||
/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>
|
||||
Repeat Song:
|
||||
[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>"]
|
||||
[repeat] times
|
||||
[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>"]
|
||||
<BR>"}
|
||||
else
|
||||
dat += {"<SPAN CLASS='linkOn'>Play</SPAN> <A href='?src=\ref[src];stop=1'>Stop</A><BR>
|
||||
Repeats left: <B>[repeat]</B><BR>"}
|
||||
if(!edit)
|
||||
dat += "<A href='?src=\ref[src];edit=2'>Show Editor</A><BR><BR>"
|
||||
dat += "<BR><B><A href='?src=\ref[src];edit=2'>Show Editor</A></B><BR>"
|
||||
else
|
||||
dat += "<A href='?src=\ref[src];edit=1'>Hide Editor</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];newsong=1'>Start a New Song</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];import=1'>Import a Song</A><BR><BR>"
|
||||
if(song)
|
||||
var/calctempo = (10/song.tempo)*60
|
||||
dat += "Tempo : <A href='?src=\ref[src];tempo=10'>-</A><A href='?src=\ref[src];tempo=1'>-</A> [calctempo] BPM <A href='?src=\ref[src];tempo=-1'>+</A><A href='?src=\ref[src];tempo=-10'>+</A><BR><BR>"
|
||||
var/linecount = 0
|
||||
for(var/line in song.lines)
|
||||
linecount += 1
|
||||
dat += "Line [linecount]: [line] <A href='?src=\ref[src];deleteline=[linecount]'>Delete Line</A> <A href='?src=\ref[src];modifyline=[linecount]'>Modify Line</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];newline=1'>Add Line</A><BR><BR>"
|
||||
var/bpm = round(600 / tempo)
|
||||
dat += {"<H3>Editing</H3>
|
||||
<B><A href='?src=\ref[src];edit=1'>Hide Editor</A></B>
|
||||
<A href='?src=\ref[src];newsong=1'>Start a New Song</A>
|
||||
<A href='?src=\ref[src];import=1'>Import a Song</A><BR><BR>
|
||||
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 += "<A href='?src=\ref[src];help=1'>Hide Help</A><BR>"
|
||||
dat += {"
|
||||
dat += {"<B><A href='?src=\ref[src];help=1'>Hide Help</A></B><BR>
|
||||
Lines are a series of chords, separated by commas (,), each with notes seperated by hyphens (-).<br>
|
||||
Every note in a chord will play together, with chord timed by the tempo.<br>
|
||||
<br>
|
||||
@@ -313,120 +168,183 @@
|
||||
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,/2,G#/8,B/8,E3-E4/4</i>
|
||||
Combined, an example is: <i>E-E4/4,F#/2,G#/8,B/8,E3-E4/4</i>
|
||||
<br>
|
||||
Lines may be up to 50 characters.<br>
|
||||
A song may only contain up to 50 lines.<br>
|
||||
"}
|
||||
else
|
||||
dat += "<A href='?src=\ref[src];help=2'>Show Help</A><BR>"
|
||||
dat += "</BODY></HTML>"
|
||||
user << browse(dat, "window=piano;size=700x300")
|
||||
onclose(user, "piano")
|
||||
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()
|
||||
|
||||
/obj/structure/device/piano/Topic(href, href_list)
|
||||
/datum/song/Topic(href, href_list)
|
||||
if(!instrumentObj.Adjacent(usr) || usr.stat)
|
||||
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(lentext(t) >= INSTRUMENT_MAX_LINE_LENGTH*INSTRUMENT_MAX_LINE_NUMBER)
|
||||
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(lentext(t) > INSTRUMENT_MAX_LINE_LENGTH*INSTRUMENT_MAX_LINE_NUMBER)
|
||||
//split into lines
|
||||
spawn()
|
||||
lines = splittext(t, "\n")
|
||||
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 > INSTRUMENT_MAX_LINE_NUMBER)
|
||||
usr << "Too many lines!"
|
||||
lines.Cut(INSTRUMENT_MAX_LINE_NUMBER+1)
|
||||
var/linenum = 1
|
||||
for(var/l in lines)
|
||||
if(lentext(l) > INSTRUMENT_MAX_LINE_LENGTH)
|
||||
usr << "Line [linenum] too long!"
|
||||
lines.Remove(l)
|
||||
else
|
||||
linenum++
|
||||
updateDialog(usr) // make sure updates when complete
|
||||
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 = 1
|
||||
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 > INSTRUMENT_MAX_LINE_NUMBER)
|
||||
return
|
||||
if(lentext(newline) > INSTRUMENT_MAX_LINE_LENGTH)
|
||||
newline = copytext(newline, 1, INSTRUMENT_MAX_LINE_LENGTH)
|
||||
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(lentext(content) > INSTRUMENT_MAX_LINE_LENGTH)
|
||||
content = copytext(content, 1, INSTRUMENT_MAX_LINE_LENGTH)
|
||||
if(num > lines.len || num < 1)
|
||||
return
|
||||
lines[num] = content
|
||||
else if(href_list["stop"])
|
||||
playing = 0
|
||||
updateDialog(usr)
|
||||
return
|
||||
|
||||
if(!in_range(src, usr) || issilicon(usr) || !anchored || !usr.canmove || usr.restrained())
|
||||
usr << browse(null, "window=piano;size=700x300")
|
||||
onclose(usr, "piano")
|
||||
/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 1
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/obj/structure/device/piano
|
||||
name = "space piano"
|
||||
desc = "This is a space piano; just like a regular piano, but always in tune! Even if the musician isn't."
|
||||
icon = 'icons/obj/musician.dmi'
|
||||
icon_state = "piano"
|
||||
anchored = 1
|
||||
density = 1
|
||||
var/datum/song/song
|
||||
|
||||
/obj/structure/device/piano/minimoog
|
||||
name = "space minimoog"
|
||||
icon_state = "minimoog"
|
||||
desc = "This is a minimoog; just like a space piano, but more spacey!"
|
||||
|
||||
/obj/structure/device/piano/New()
|
||||
..()
|
||||
song = new("piano", src)
|
||||
|
||||
if(prob(50))
|
||||
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/device/piano/Destroy()
|
||||
qdel(song)
|
||||
song = null
|
||||
..()
|
||||
|
||||
/obj/structure/device/piano/verb/rotate()
|
||||
set name = "Rotate Piano"
|
||||
set category = "Object"
|
||||
set src in oview(1)
|
||||
|
||||
if(istype(usr,/mob/living/simple_mob/animal/passive/mouse))
|
||||
return
|
||||
else if(!usr || !isturf(usr.loc))
|
||||
return
|
||||
else if(usr.stat || usr.restrained())
|
||||
return
|
||||
else if (istype(usr,/mob/observer/ghost) && !config.ghost_interaction)
|
||||
return
|
||||
else
|
||||
src.set_dir(turn(src.dir, 90))
|
||||
return
|
||||
|
||||
if(href_list["newsong"])
|
||||
song = new()
|
||||
else if(song)
|
||||
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.
|
||||
var/tempnum = input("How many times do you want to repeat this piece? (max:10)") as num|null
|
||||
if(tempnum > 10)
|
||||
tempnum = 10
|
||||
if(tempnum < 0)
|
||||
tempnum = 0
|
||||
repeat = round(tempnum)
|
||||
/obj/structure/device/piano/attack_hand(mob/user)
|
||||
if(!user.IsAdvancedToolUser())
|
||||
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
|
||||
return 1
|
||||
interact(user)
|
||||
|
||||
else if(href_list["tempo"])
|
||||
song.tempo += round(text2num(href_list["tempo"]))
|
||||
if(song.tempo < 1)
|
||||
song.tempo = 1
|
||||
/obj/structure/device/piano/interact(mob/user)
|
||||
if(!user || !anchored)
|
||||
return
|
||||
|
||||
else if(href_list["play"])
|
||||
if(song)
|
||||
playing = 1
|
||||
spawn() playsong()
|
||||
|
||||
else if(href_list["newline"])
|
||||
var/newline = html_encode(input("Enter your line: ", "Piano") as text|null)
|
||||
if(!newline)
|
||||
return
|
||||
if(song.lines.len > 50)
|
||||
return
|
||||
if(lentext(newline) > 50)
|
||||
newline = copytext(newline, 1, 50)
|
||||
song.lines.Add(newline)
|
||||
|
||||
else if(href_list["deleteline"])
|
||||
var/num = round(text2num(href_list["deleteline"]))
|
||||
if(num > song.lines.len || num < 1)
|
||||
return
|
||||
song.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: ", "Piano", song.lines[num]) as text|null)
|
||||
if(!content)
|
||||
return
|
||||
if(lentext(content) > 50)
|
||||
content = copytext(content, 1, 50)
|
||||
if(num > song.lines.len || num < 1)
|
||||
return
|
||||
song.lines[num] = content
|
||||
|
||||
else if(href_list["stop"])
|
||||
playing = 0
|
||||
|
||||
else if(href_list["help"])
|
||||
help = text2num(href_list["help"]) - 1
|
||||
|
||||
else if(href_list["edit"])
|
||||
edit = text2num(href_list["edit"]) - 1
|
||||
|
||||
else if(href_list["import"])
|
||||
var/t = ""
|
||||
do
|
||||
t = html_encode(input(usr, "Please paste the entire song, formatted:", text("[]", src.name), t) as message)
|
||||
if (!in_range(src, usr))
|
||||
return
|
||||
|
||||
if(lentext(t) >= 3072)
|
||||
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(lentext(t) > 3072)
|
||||
|
||||
//split into lines
|
||||
spawn()
|
||||
var/list/lines = splittext(t, "\n")
|
||||
var/tempo = 5
|
||||
if(copytext(lines[1],1,6) == "BPM: ")
|
||||
tempo = 600 / text2num(copytext(lines[1],6))
|
||||
lines.Cut(1,2)
|
||||
if(lines.len > 50)
|
||||
usr << "Too many lines!"
|
||||
lines.Cut(51)
|
||||
var/linenum = 1
|
||||
for(var/l in lines)
|
||||
if(lentext(l) > 50)
|
||||
usr << "Line [linenum] too long!"
|
||||
lines.Remove(l)
|
||||
else
|
||||
linenum++
|
||||
song = new()
|
||||
song.lines = lines
|
||||
song.tempo = tempo
|
||||
updateUsrDialog()
|
||||
|
||||
add_fingerprint(usr)
|
||||
updateUsrDialog()
|
||||
return
|
||||
user.set_machine(src)
|
||||
song.interact(user)
|
||||
|
||||
/obj/structure/device/piano/attackby(obj/item/O as obj, mob/user as mob)
|
||||
if(O.is_wrench())
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/structure/noticeboard/initialize()
|
||||
/obj/structure/noticeboard/Initialize()
|
||||
for(var/obj/item/I in loc)
|
||||
if(notices > 4) break
|
||||
if(istype(I, /obj/item/weapon/paper))
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
explosion_resistance = 5
|
||||
var/list/mobs_can_pass = list(
|
||||
/mob/living/bot,
|
||||
/mob/living/simple_animal/slime,
|
||||
/mob/living/simple_animal/mouse,
|
||||
/mob/living/simple_mob/slime/xenobio,
|
||||
/mob/living/simple_mob/animal/passive/mouse,
|
||||
/mob/living/silicon/robot/drone
|
||||
)
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
var/static/list/possible_states = list("health", "spider", "slime", "emp", "species", "egg", "vent", "mindshock", "viral", "gland")
|
||||
var/static/list/possible_tech = list(TECH_MATERIAL, TECH_ENGINEERING, TECH_PHORON, TECH_POWER, TECH_BIO, TECH_COMBAT, TECH_MAGNET, TECH_DATA)
|
||||
|
||||
/obj/item/prop/alien/junk/initialize()
|
||||
/obj/item/prop/alien/junk/Initialize()
|
||||
. = ..()
|
||||
icon_state = pick(possible_states)
|
||||
var/list/techs = possible_tech.Copy()
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
interaction_message = "<span class='notice'>The prismatic turret seems to be able to rotate.</span>"
|
||||
|
||||
/obj/structure/prop/prism/initialize()
|
||||
/obj/structure/prop/prism/Initialize()
|
||||
if(degrees_from_north)
|
||||
animate(src, transform = turn(NORTH, degrees_from_north), time = 3)
|
||||
|
||||
@@ -196,7 +196,7 @@
|
||||
for(var/obj/structure/prop/prism/P in my_turrets)
|
||||
P.rotate_auto(new_bearing)
|
||||
|
||||
/obj/structure/prop/prismcontrol/initialize()
|
||||
/obj/structure/prop/prismcontrol/Initialize()
|
||||
..()
|
||||
if(my_turrets.len) //Preset controls.
|
||||
for(var/obj/structure/prop/prism/P in my_turrets)
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/obj/structure/prop/nest
|
||||
name = "diyaab den"
|
||||
desc = "A den of some creature."
|
||||
icon = 'icons/obj/structures.dmi'
|
||||
icon_state = "bonfire"
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
interaction_message = "<span class='warning'>You feel like you shouldn't be sticking your nose into a wild animal's den.</span>"
|
||||
|
||||
var/disturbance_spawn_chance = 20
|
||||
var/last_spawn
|
||||
var/spawn_delay = 150
|
||||
var/randomize_spawning = FALSE
|
||||
var/creature_types = list(/mob/living/simple_mob/animal/sif/diyaab)
|
||||
var/list/den_mobs
|
||||
var/den_faction //The faction of any spawned creatures.
|
||||
var/max_creatures = 3 //Maximum number of living creatures this nest can have at one time.
|
||||
|
||||
var/tally = 0 //The counter referenced against total_creature_max, or just to see how many mobs it has spawned.
|
||||
var/total_creature_max //If set, it can spawn this many creatures, total, ever.
|
||||
|
||||
/obj/structure/prop/nest/Initialize()
|
||||
..()
|
||||
den_mobs = list()
|
||||
START_PROCESSING(SSobj, src)
|
||||
last_spawn = world.time
|
||||
if(randomize_spawning) //Not the biggest shift in spawntime, but it's here.
|
||||
var/delayshift_clamp = spawn_delay / 10
|
||||
var/delayshift = rand(delayshift_clamp, -1 * delayshift_clamp)
|
||||
spawn_delay += delayshift
|
||||
|
||||
/obj/structure/prop/nest/Destroy()
|
||||
den_mobs = null
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
..()
|
||||
|
||||
/obj/structure/prop/nest/attack_hand(mob/living/user) // Used to tell the player that this isn't useful for anything.
|
||||
..()
|
||||
if(user && prob(disturbance_spawn_chance))
|
||||
spawn_creature(get_turf(src))
|
||||
|
||||
/obj/structure/prop/nest/process()
|
||||
update_creatures()
|
||||
if(world.time > last_spawn + spawn_delay)
|
||||
spawn_creature(get_turf(src))
|
||||
|
||||
/obj/structure/prop/nest/proc/spawn_creature(var/turf/spawnpoint)
|
||||
update_creatures() //Paranoia.
|
||||
if(total_creature_max && tally >= total_creature_max)
|
||||
return
|
||||
if(istype(spawnpoint) && den_mobs.len < max_creatures)
|
||||
last_spawn = world.time
|
||||
var/spawn_choice = pick(creature_types)
|
||||
var/mob/living/L = new spawn_choice(spawnpoint)
|
||||
if(den_faction)
|
||||
L.faction = den_faction
|
||||
visible_message("<span class='warning'>\The [L] crawls out of \the [src].</span>")
|
||||
den_mobs += L
|
||||
tally++
|
||||
|
||||
/obj/structure/prop/nest/proc/remove_creature(var/mob/target)
|
||||
den_mobs -= target
|
||||
|
||||
/obj/structure/prop/nest/proc/update_creatures()
|
||||
for(var/mob/living/L in den_mobs)
|
||||
if(L.stat == 2)
|
||||
remove_creature(L)
|
||||
@@ -31,7 +31,7 @@
|
||||
visible_message("<span class='cult'>\The [src] is completely unaffected by the blast.</span>")
|
||||
return
|
||||
|
||||
/obj/machinery/door/blast/puzzle/initialize()
|
||||
/obj/machinery/door/blast/puzzle/Initialize()
|
||||
. = ..()
|
||||
implicit_material = get_material_by_name("dungeonium")
|
||||
if(locks.len)
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
if(climbable)
|
||||
verbs += /obj/structure/proc/climb_on
|
||||
|
||||
/obj/structure/railing/initialize()
|
||||
/obj/structure/railing/Initialize()
|
||||
. = ..()
|
||||
if(src.anchored)
|
||||
update_icon(0)
|
||||
|
||||
@@ -30,7 +30,7 @@ FLOOR SAFES
|
||||
tumbler_2_open = rand(0, 72)
|
||||
|
||||
|
||||
/obj/structure/safe/initialize()
|
||||
/obj/structure/safe/Initialize()
|
||||
. = ..()
|
||||
for(var/obj/item/I in loc)
|
||||
if(space >= maxspace)
|
||||
@@ -175,7 +175,7 @@ obj/structure/safe/ex_act(severity)
|
||||
plane = TURF_PLANE
|
||||
layer = ABOVE_UTILITY
|
||||
|
||||
/obj/structure/safe/floor/initialize()
|
||||
/obj/structure/safe/floor/Initialize()
|
||||
. = ..()
|
||||
var/turf/T = loc
|
||||
if(istype(T) && !T.is_plating())
|
||||
|
||||
@@ -36,11 +36,11 @@
|
||||
else
|
||||
set_opacity(1)
|
||||
if(material.products_need_process())
|
||||
processing_objects |= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
update_nearby_tiles(need_rebuild=1)
|
||||
|
||||
/obj/structure/simple_door/Destroy()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
update_nearby_tiles()
|
||||
return ..()
|
||||
|
||||
@@ -206,6 +206,6 @@
|
||||
/obj/structure/simple_door/cult/TryToSwitchState(atom/user)
|
||||
if(isliving(user))
|
||||
var/mob/living/L = user
|
||||
if(!iscultist(L) && !istype(L, /mob/living/simple_animal/construct))
|
||||
if(!iscultist(L) && !istype(L, /mob/living/simple_mob/construct))
|
||||
return
|
||||
..()
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
src.set_dir(turn(src.dir, 90))
|
||||
return
|
||||
else
|
||||
if(istype(usr,/mob/living/simple_animal/mouse))
|
||||
if(istype(usr,/mob/living/simple_mob/animal/passive/mouse))
|
||||
return
|
||||
if(!usr || !isturf(usr.loc))
|
||||
return
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
var/shardtype = /obj/item/weapon/material/shard
|
||||
var/glasstype = null // Set this in subtypes. Null is assumed strange or otherwise impossible to dismantle, such as for shuttle glass.
|
||||
var/silicate = 0 // number of units of silicate
|
||||
var/fulltile = FALSE // Set to true on full-tile variants.
|
||||
|
||||
/obj/structure/window/examine(mob/user)
|
||||
. = ..(user)
|
||||
@@ -128,16 +129,10 @@
|
||||
/obj/structure/window/blob_act()
|
||||
take_damage(50)
|
||||
|
||||
//TODO: Make full windows a separate type of window.
|
||||
//Once a full window, it will always be a full window, so there's no point
|
||||
//having the same type for both.
|
||||
/obj/structure/window/proc/is_full_window()
|
||||
return (dir == SOUTHWEST || dir == SOUTHEAST || dir == NORTHWEST || dir == NORTHEAST)
|
||||
|
||||
/obj/structure/window/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if(istype(mover) && mover.checkpass(PASSGLASS))
|
||||
return TRUE
|
||||
if(is_full_window())
|
||||
if(is_fulltile())
|
||||
return FALSE //full tile window, you can't move into it!
|
||||
if((get_dir(loc, target) & dir) || (get_dir(mover, target) == turn(dir, 180)))
|
||||
return !density
|
||||
@@ -204,7 +199,7 @@
|
||||
user.setClickCooldown(user.get_attack_speed())
|
||||
if(!damage)
|
||||
return
|
||||
if(damage >= 10)
|
||||
if(damage >= STRUCTURE_MIN_DAMAGE_THRESHOLD)
|
||||
visible_message("<span class='danger'>[user] smashes into [src]!</span>")
|
||||
if(reinf)
|
||||
damage = damage / 2
|
||||
@@ -386,8 +381,6 @@
|
||||
anchored = 0
|
||||
state = 0
|
||||
update_verbs()
|
||||
if(is_fulltile())
|
||||
maxhealth *= 2
|
||||
|
||||
health = maxhealth
|
||||
|
||||
@@ -414,9 +407,7 @@
|
||||
|
||||
//checks if this window is full-tile one
|
||||
/obj/structure/window/proc/is_fulltile()
|
||||
if(dir & (dir - 1))
|
||||
return 1
|
||||
return 0
|
||||
return fulltile
|
||||
|
||||
//This proc is used to update the icons of nearby windows. It should not be confused with update_nearby_tiles(), which is an atmos proc!
|
||||
/obj/structure/window/proc/update_nearby_icons()
|
||||
@@ -456,7 +447,7 @@
|
||||
|
||||
// Damage overlays.
|
||||
var/ratio = health / maxhealth
|
||||
ratio = Ceiling(ratio * 4) * 25
|
||||
ratio = CEILING(ratio * 4, 1) * 25
|
||||
|
||||
if(ratio > 75)
|
||||
return
|
||||
@@ -482,6 +473,10 @@
|
||||
maxhealth = 12.0
|
||||
force_threshold = 3
|
||||
|
||||
/obj/structure/window/basic/full
|
||||
maxhealth = 24
|
||||
fulltile = TRUE
|
||||
|
||||
/obj/structure/window/phoronbasic
|
||||
name = "phoron window"
|
||||
desc = "A borosilicate alloy window. It seems to be quite strong."
|
||||
@@ -495,8 +490,8 @@
|
||||
force_threshold = 5
|
||||
|
||||
/obj/structure/window/phoronbasic/full
|
||||
dir = SOUTHWEST
|
||||
maxhealth = 80
|
||||
fulltile = TRUE
|
||||
|
||||
/obj/structure/window/phoronreinforced
|
||||
name = "reinforced borosilicate window"
|
||||
@@ -512,8 +507,8 @@
|
||||
force_threshold = 10
|
||||
|
||||
/obj/structure/window/phoronreinforced/full
|
||||
dir = SOUTHWEST
|
||||
maxhealth = 160
|
||||
fulltile = TRUE
|
||||
|
||||
/obj/structure/window/reinforced
|
||||
name = "reinforced window"
|
||||
@@ -528,9 +523,9 @@
|
||||
force_threshold = 6
|
||||
|
||||
/obj/structure/window/reinforced/full
|
||||
dir = SOUTHWEST
|
||||
icon_state = "fwindow"
|
||||
maxhealth = 80
|
||||
fulltile = TRUE
|
||||
|
||||
/obj/structure/window/reinforced/tinted
|
||||
name = "tinted window"
|
||||
@@ -565,9 +560,9 @@
|
||||
var/id
|
||||
|
||||
/obj/structure/window/reinforced/polarized/full
|
||||
dir = SOUTHWEST
|
||||
icon_state = "fwindow"
|
||||
maxhealth = 80
|
||||
fulltile = TRUE
|
||||
|
||||
/obj/structure/window/reinforced/polarized/attackby(obj/item/W as obj, mob/user as mob)
|
||||
if(istype(W, /obj/item/device/multitool) && !anchored) // Only allow programming if unanchored!
|
||||
@@ -645,3 +640,20 @@
|
||||
MT.update_icon()
|
||||
return TRUE
|
||||
. = ..()
|
||||
|
||||
/obj/structure/window/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
|
||||
switch(passed_mode)
|
||||
if(RCD_DECONSTRUCT)
|
||||
return list(
|
||||
RCD_VALUE_MODE = RCD_DECONSTRUCT,
|
||||
RCD_VALUE_DELAY = 5 SECONDS,
|
||||
RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 5
|
||||
)
|
||||
|
||||
/obj/structure/window/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
|
||||
switch(passed_mode)
|
||||
if(RCD_DECONSTRUCT)
|
||||
to_chat(user, span("notice", "You deconstruct \the [src]."))
|
||||
qdel(src)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
/obj/effect/wingrille_spawn/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
|
||||
return FALSE
|
||||
|
||||
/obj/effect/wingrille_spawn/initialize()
|
||||
/obj/effect/wingrille_spawn/Initialize()
|
||||
. = ..()
|
||||
if(!win_path)
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user