Merge branch 'map' into RadiantMaster

This commit is contained in:
Hawk_v3
2019-04-14 18:27:05 +01:00
2962 changed files with 944384 additions and 432548 deletions
+4 -4
View File
@@ -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()
+3 -3
View File
@@ -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()
@@ -67,7 +67,7 @@
return
/obj/structure/catwalk/attackby(obj/item/C as obj, mob/user as mob)
if (istype(C, /obj/item/weapon/weldingtool))
if(istype(C, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = C
if(WT.isOn())
if(WT.remove_fuel(0, user))
@@ -76,7 +76,7 @@
new /obj/item/stack/rods(src.loc)
new /obj/structure/lattice(src.loc)
qdel(src)
if(istype(C, /obj/item/weapon/screwdriver))
if(C.is_screwdriver())
if(health < maxhealth)
to_chat(user, "<span class='notice'>You begin repairing \the [src.name] with \the [C.name].</span>")
if(do_after(user, 20, src))
+236
View File
@@ -0,0 +1,236 @@
GLOBAL_LIST_EMPTY(cliff_icon_cache)
/*
Cliffs give a visual illusion of depth by seperating two places while presenting a 'top' and 'bottom' side.
Mobs moving into a cliff from the bottom side will simply bump into it and be denied moving into the tile,
where as mobs moving into a cliff from the top side will 'fall' off the cliff, forcing them to the bottom, causing significant damage and stunning them.
Mobs can climb this while wearing climbing equipment by clickdragging themselves onto a cliff, as if it were a table.
Flying mobs can pass over all cliffs with no risk of falling.
Projectiles and thrown objects can pass, however if moving upwards, there is a chance for it to be stopped by the cliff.
This makes fighting something that is on top of a cliff more challenging.
As a note, dir points upwards, e.g. pointing WEST means the left side is 'up', and the right side is 'down'.
When mapping these in, be sure to give at least a one tile clearance, as NORTH facing cliffs expand to
two tiles on initialization, and which way a cliff is facing may change during maploading.
*/
/obj/structure/cliff
name = "cliff"
desc = "A steep rock ledge. You might be able to climb it if you feel bold enough."
description_info = "Walking off the edge of a cliff while on top will cause you to fall off, causing severe injury.<br>\
You can climb this cliff if wearing special climbing equipment, by click-dragging yourself onto the cliff.<br>\
Projectiles traveling up a cliff may hit the cliff instead, making it more difficult to fight something \
on top."
icon = 'icons/obj/flora/rocks.dmi'
anchored = TRUE
density = TRUE
opacity = FALSE
climbable = TRUE
climb_delay = 10 SECONDS
block_turf_edges = TRUE // Don't want turf edges popping up from the cliff edge.
register_as_dangerous_object = TRUE
var/icon_variant = null // Used to make cliffs less repeative by having a selection of sprites to display.
var/corner = FALSE // Used for icon things.
var/ramp = FALSE // Ditto.
var/bottom = FALSE // Used for 'bottom' typed cliffs, to avoid infinite cliffs, and for icons.
var/is_double_cliff = FALSE // Set to true when making the two-tile cliffs, used for projectile checks.
var/uphill_penalty = 30 // Odds of a projectile not making it up the cliff.
// These arrange their sprites at runtime, as opposed to being statically placed in the map file.
/obj/structure/cliff/automatic
icon_state = "cliffbuilder"
dir = NORTH
/obj/structure/cliff/automatic/corner
icon_state = "cliffbuilder-corner"
dir = NORTHEAST
corner = TRUE
// Tiny part that doesn't block, used for making 'ramps'.
/obj/structure/cliff/automatic/ramp
icon_state = "cliffbuilder-ramp"
dir = NORTHEAST
density = FALSE
ramp = TRUE
// Made automatically as needed by automatic cliffs.
/obj/structure/cliff/bottom
bottom = TRUE
/obj/structure/cliff/automatic/Initialize()
..()
return INITIALIZE_HINT_LATELOAD
// Paranoid about the maploader, direction is very important to cliffs, since they may get bigger if initialized while facing NORTH.
/obj/structure/cliff/automatic/LateInitialize()
if(dir in GLOB.cardinal)
icon_variant = pick("a", "b", "c")
if(dir & NORTH && !bottom) // North-facing cliffs require more cliffs to be made.
make_bottom()
update_icon()
/obj/structure/cliff/proc/make_bottom()
// First, make sure there's room to put the bottom side.
var/turf/T = locate(x, y - 1, z)
if(!istype(T))
return FALSE
// Now make the bottom cliff have mostly the same variables.
var/obj/structure/cliff/bottom/bottom = new(T)
is_double_cliff = TRUE
climb_delay /= 2 // Since there are two cliffs to climb when going north, both take half the time.
bottom.dir = dir
bottom.is_double_cliff = TRUE
bottom.climb_delay = climb_delay
bottom.icon_variant = icon_variant
bottom.corner = corner
bottom.ramp = ramp
bottom.layer = layer - 0.1
bottom.density = density
bottom.update_icon()
/obj/structure/cliff/set_dir(new_dir)
..()
update_icon()
/obj/structure/cliff/update_icon()
icon_state = "cliff-[dir][icon_variant][bottom ? "-bottom" : ""][corner ? "-corner" : ""][ramp ? "-ramp" : ""]"
// Now for making the top-side look like a different turf.
var/turf/T = get_step(src, dir)
if(!istype(T))
return
var/subtraction_icon_state = "[icon_state]-subtract"
var/cache_string = "[icon_state]_[T.icon]_[T.icon_state]"
if(T && subtraction_icon_state in icon_states(icon))
cut_overlays()
// If we've made the same icon before, just recycle it.
if(cache_string in GLOB.cliff_icon_cache)
add_overlay(GLOB.cliff_icon_cache[cache_string])
else // Otherwise make a new one, but only once.
var/icon/underlying_ground = icon(T.icon, T.icon_state, T.dir)
var/icon/subtract = icon(icon, subtraction_icon_state)
underlying_ground.Blend(subtract, ICON_SUBTRACT)
var/image/final = image(underlying_ground)
final.layer = src.layer - 0.2
GLOB.cliff_icon_cache[cache_string] = final
add_overlay(final)
// Movement-related code.
/obj/structure/cliff/CanPass(atom/movable/mover, turf/target)
if(isliving(mover))
var/mob/living/L = mover
if(L.hovering) // Flying mobs can always pass.
return TRUE
return ..()
// Projectiles and objects flying 'upward' have a chance to hit the cliff instead, wasting the shot.
else if(istype(mover, /obj))
var/obj/O = mover
if(check_shield_arc(src, dir, O)) // This is actually for mobs but it will work for our purposes as well.
if(prob(uphill_penalty / (1 + is_double_cliff) )) // Firing upwards facing NORTH means it will likely have to pass through two cliffs, so the chance is halved.
return FALSE
return TRUE
/obj/structure/cliff/Bumped(atom/A)
if(isliving(A))
var/mob/living/L = A
if(should_fall(L))
fall_off_cliff(L)
return
..()
/obj/structure/cliff/proc/should_fall(mob/living/L)
if(L.hovering)
return FALSE
var/turf/T = get_turf(L)
if(T && get_dir(T, loc) & reverse_dir[dir]) // dir points 'up' the cliff, e.g. cliff pointing NORTH will cause someone to fall if moving SOUTH into it.
return TRUE
return FALSE
/obj/structure/cliff/proc/fall_off_cliff(mob/living/L)
if(!istype(L))
return FALSE
var/turf/T = get_step(src, reverse_dir[dir])
var/displaced = FALSE
if(dir in list(EAST, WEST)) // Apply an offset if flying sideways, to help maintain the illusion of depth.
for(var/i = 1 to 2)
var/turf/new_T = locate(T.x, T.y - i, T.z)
if(!new_T || locate(/obj/structure/cliff) in new_T)
break
T = new_T
displaced = TRUE
if(istype(T))
visible_message(span("danger", "\The [L] falls off \the [src]!"))
L.forceMove(T)
// Do the actual hurting. Double cliffs do halved damage due to them most likely hitting twice.
var/harm = !is_double_cliff ? 1 : 0.5
if(istype(L.buckled, /obj/vehicle)) // People falling off in vehicles will take less damage, but will damage the vehicle severely.
var/obj/vehicle/vehicle = L.buckled
vehicle.adjust_health(40 * harm)
to_chat(L, span("warning", "\The [vehicle] absorbs some of the impact, damaging it."))
harm /= 2
playsound(L, 'sound/effects/break_stone.ogg', 70, 1)
L.Weaken(5 * harm)
var/fall_time = 3
if(displaced) // Make the fall look more natural when falling sideways.
L.pixel_z = 32 * 2
animate(L, pixel_z = 0, time = fall_time)
sleep(fall_time) // A brief delay inbetween the two sounds helps sell the 'ouch' effect.
playsound(L, "punch", 70, 1)
shake_camera(L, 1, 1)
visible_message(span("danger", "\The [L] hits the ground!"))
// The bigger they are, the harder they fall.
// They will take at least 20 damage at the minimum, and tries to scale up to 40% of their max health.
// This scaling is capped at 100 total damage, which occurs if the thing that fell has more than 250 health.
var/damage = between(20, L.getMaxHealth() * 0.4, 100)
var/target_zone = ran_zone()
var/blocked = L.run_armor_check(target_zone, "melee") * harm
var/soaked = L.get_armor_soak(target_zone, "melee") * harm
L.apply_damage(damage * harm, BRUTE, target_zone, blocked, soaked, used_weapon=src)
// Now fall off more cliffs below this one if they exist.
var/obj/structure/cliff/bottom_cliff = locate() in T
if(bottom_cliff)
visible_message(span("danger", "\The [L] rolls down towards \the [bottom_cliff]!"))
sleep(5)
bottom_cliff.fall_off_cliff(L)
/obj/structure/cliff/can_climb(mob/living/user, post_climb_check = FALSE)
// Cliff climbing requires climbing gear.
if(ishuman(user))
var/mob/living/carbon/human/H = user
var/obj/item/clothing/shoes/shoes = H.shoes
if(shoes && shoes.rock_climbing)
return ..() // Do the other checks too.
to_chat(user, span("warning", "\The [src] is too steep to climb unassisted."))
return FALSE
// This tells AI mobs to not be dumb and step off cliffs willingly.
/obj/structure/cliff/is_safe_to_step(mob/living/L)
if(should_fall(L))
return FALSE
return ..()
+1 -1
View File
@@ -27,7 +27,7 @@
user << "<span class='notice'>You cannot hang [W] on [src]</span>"
return ..()
/obj/structure/coatrack/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
/obj/structure/coatrack/CanPass(atom/movable/mover, turf/target)
var/can_hang = 0
for (var/T in allowed)
if(istype(mover,T))
@@ -9,22 +9,35 @@
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()
..()
// Closets need to come later because of spawners potentially creating objects during init.
return INITIALIZE_HINT_LATELOAD
/obj/structure/closet/LateInitialize()
. = ..()
if(starts_with)
create_objects_in_loc(src, starts_with)
@@ -39,41 +52,46 @@
// 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(air_group || (height==0 || wall_mounted)) return 1
return (!density)
/obj/structure/closet/CanPass(atom/movable/mover, turf/target)
if(wall_mounted)
return TRUE
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 +120,8 @@
src.icon_state = src.icon_opened
src.opened = 1
playsound(src.loc, open_sound, 15, 1, -3)
density = 0
if(initial(density))
density = !density
return 1
/obj/structure/closet/proc/close()
@@ -119,12 +138,15 @@
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
if(initial(density))
density = !density
return 1
//Cham Projector Exception
@@ -140,7 +162,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 +184,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 +260,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 +286,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(istype(W, /obj/item/weapon/wrench))
if(welded)
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(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 +312,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 +348,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 +358,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 +378,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 +401,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 +430,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 +462,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)
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
@@ -10,7 +10,7 @@
open_sound = 'sound/vore/schlorp.ogg'
close_sound = 'sound/vore/schlorp.ogg'
opened = 0
welded = 0 //Don't touch this.
sealed = 0 //Don't touch this.
health = 100
/obj/structure/closet/secure_closet/egg/attackby(obj/item/weapon/W, mob/user as mob) //This also prevents crew from welding the eggs and making them unable to be opened.
@@ -16,6 +16,10 @@
starts_with = list(/obj/item/weapon/material/twohanded/fireaxe)
/obj/structure/closet/fireaxecabinet/Initialize()
..()
fireaxe = locate() in contents
/obj/structure/closet/fireaxecabinet/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri
//..() //That's very useful, Erro
@@ -115,6 +119,7 @@
if(src.locked)
to_chat(user, "<span class='warning'>The cabinet won't budge!</span>")
return
if(localopened)
if(fireaxe)
user.put_in_hands(fireaxe)
@@ -9,6 +9,6 @@
/obj/item/clothing/mask/breath,
/obj/item/clothing/head/helmet/space/void,
/obj/item/clothing/suit/space/void,
/obj/item/weapon/crowbar,
/obj/item/weapon/tool/crowbar,
/obj/item/weapon/cell,
/obj/item/device/multitool)
@@ -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
@@ -33,7 +33,7 @@
/obj/item/weapon/tank/emergency/oxygen/engi,
/obj/item/weapon/reagent_containers/spray/windowsealant) //VOREStation Add
/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
@@ -100,7 +100,7 @@
/obj/item/weapon/tank/emergency/oxygen/engi,
/obj/item/weapon/reagent_containers/spray/windowsealant) //VOREStation Add
/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
@@ -135,7 +135,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
@@ -49,7 +49,8 @@
starts_with = list(
/obj/item/weapon/reagent_containers/food/drinks/milk = 6,
/obj/item/weapon/reagent_containers/food/drinks/soymilk = 4,
/obj/item/weapon/storage/fancy/egg_box = 4)
/obj/item/weapon/storage/fancy/egg_box = 4,
/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose = 2)
/obj/structure/closet/secure_closet/freezer/money
@@ -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,13 @@
/obj/item/clothing/head/greenbandana,
/obj/item/weapon/material/minihoe,
/obj/item/weapon/material/knife/machete/hatchet,
/obj/item/weapon/wirecutters/clippers,
/obj/item/weapon/reagent_containers/glass/beaker = 2,
/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
@@ -132,7 +132,7 @@
/obj/item/device/healthanalyzer,
/obj/item/device/radio/off,
/obj/random/medical,
/obj/item/weapon/crowbar,
/obj/item/weapon/tool/crowbar,
/obj/item/weapon/extinguisher/mini,
/obj/item/weapon/storage/box/freezer,
/obj/item/clothing/accessory/storage/white_vest,
@@ -170,7 +170,7 @@
/obj/item/clothing/shoes/white,
/obj/item/weapon/reagent_containers/glass/beaker/vial) //VOREStation Add
/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.
@@ -88,15 +88,15 @@
spark_system.start()
playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1)
playsound(src.loc, "sparks", 50, 1)
else if(istype(W, /obj/item/weapon/wrench))
if(welded)
else if(W.is_wrench())
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
@@ -41,6 +41,8 @@
/obj/item/weapon/storage/box/ids = 2,
/obj/item/weapon/gun/energy/gun,
/obj/item/weapon/gun/energy/gun/martin, //VOREStation Add,
/obj/item/weapon/storage/box/commandkeys, //VOREStation Add,
/obj/item/weapon/storage/box/servicekeys, //VOREStation Add,
///obj/item/weapon/gun/projectile/sec/flash, //VOREStation Removal,
/obj/item/device/flash)
@@ -106,7 +108,7 @@
/obj/item/weapon/storage/box/holobadge/hos,
/obj/item/clothing/accessory/badge/holo/hos,
/obj/item/weapon/reagent_containers/spray/pepper,
/obj/item/weapon/crowbar/red,
/obj/item/weapon/tool/crowbar/red,
/obj/item/weapon/storage/box/flashbangs,
/obj/item/weapon/storage/belt/security,
/obj/item/device/flash,
@@ -121,7 +123,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
@@ -173,7 +175,7 @@
/obj/item/ammo_magazine/m12gdrumjack/beanbag,
/obj/item/ammo_magazine/m12gdrumjack/beanbag)
/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
@@ -217,7 +219,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
@@ -226,22 +228,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 ..()
@@ -45,7 +45,7 @@
/obj/item/weapon/storage/box/holobadge/hos,
/obj/item/clothing/accessory/badge/holo/hos,
/obj/item/weapon/reagent_containers/spray/pepper,
/obj/item/weapon/crowbar/red,
/obj/item/weapon/tool/crowbar/red,
/obj/item/weapon/storage/box/flashbangs,
/obj/item/device/flash,
/obj/item/weapon/melee/baton/loaded,
@@ -97,7 +97,7 @@
/obj/item/clothing/shoes/boots/jackboots,
/obj/item/clothing/shoes/boots/jackboots/toeless)
/obj/structure/closet/secure_closet/nanotrasen_security/initialize()
/obj/structure/closet/secure_closet/nanotrasen_security/Initialize()
if(prob(25))
starts_with += /obj/item/weapon/storage/backpack/security
else
@@ -135,7 +135,7 @@
/obj/item/weapon/storage/box/holobadge/hos,
/obj/item/clothing/accessory/badge/holo/hos,
/obj/item/weapon/reagent_containers/spray/pepper,
/obj/item/weapon/crowbar/red,
/obj/item/weapon/tool/crowbar/red,
/obj/item/weapon/storage/box/flashbangs,
/obj/item/weapon/storage/belt/security,
/obj/item/device/flash,
@@ -151,7 +151,7 @@
/obj/item/clothing/shoes/boots/jackboots/toeless,
/obj/item/clothing/under/nanotrasen/security/commander)
/obj/structure/closet/secure_closet/nanotrasen_commander/initialize()
/obj/structure/closet/secure_closet/nanotrasen_commander/Initialize()
if(prob(25))
starts_with += /obj/item/weapon/storage/backpack/security
else
@@ -197,7 +197,7 @@
/obj/item/clothing/shoes/boots/jackboots,
/obj/item/clothing/shoes/boots/jackboots/toeless)
/obj/structure/closet/secure_closet/nanotrasen_warden/initialize()
/obj/structure/closet/secure_closet/nanotrasen_warden/Initialize()
if(prob(25))
new /obj/item/weapon/storage/backpack/security(src)
else
@@ -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()
@@ -14,7 +14,7 @@
/obj/item/clothing/under/syndicate,
/obj/item/clothing/head/helmet/space/void/merc,
/obj/item/clothing/suit/space/void/merc,
/obj/item/weapon/crowbar/red,
/obj/item/weapon/tool/crowbar/red,
/obj/item/weapon/cell/high,
/obj/item/weapon/card/id/syndicate,
/obj/item/device/multitool,
@@ -24,7 +24,7 @@
/obj/structure/closet/syndicate/suit
desc = "It's a storage unit for voidsuits."
starts_with = list(
/obj/item/weapon/tank/jetpack/oxygen,
/obj/item/clothing/shoes/magboots,
@@ -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,22 +106,22 @@
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
if(prob(70))
starts_with += /obj/item/device/flashlight
if(prob(70))
starts_with += /obj/item/weapon/screwdriver
starts_with += /obj/item/weapon/tool/screwdriver
if(prob(70))
starts_with += /obj/item/weapon/wrench
starts_with += /obj/item/weapon/tool/wrench
if(prob(70))
starts_with += /obj/item/weapon/weldingtool
if(prob(70))
starts_with += /obj/item/weapon/crowbar
starts_with += /obj/item/weapon/tool/crowbar
if(prob(70))
starts_with += /obj/item/weapon/wirecutters
starts_with += /obj/item/weapon/tool/wirecutters
if(prob(70))
starts_with += /obj/item/device/t_scanner
if(prob(20))
@@ -203,7 +203,7 @@
icon_closed = "hydrant"
icon_opened = "hydrant_open"
plane = TURF_PLANE
layer = ABOVE_TURF_LAYER
layer = ABOVE_TURF_LAYER
anchored = 1
density = 0
wall_mounted = 1
@@ -1,4 +1,4 @@
/obj/structure/closet/firecloset/initialize()
/obj/structure/closet/firecloset/Initialize()
starts_with += /obj/item/weapon/storage/toolbox/emergency
return ..()
@@ -16,7 +16,7 @@
/obj/structure/closet/walllocker/emerglocker
name = "emergency locker"
desc = "A wall mounted locker with emergency supplies."
var/list/spawnitems = list(/obj/item/weapon/tank/emergency/oxygen,/obj/item/clothing/mask/breath,/obj/item/weapon/crowbar/red)
var/list/spawnitems = list(/obj/item/weapon/tank/emergency/oxygen,/obj/item/clothing/mask/breath,/obj/item/weapon/tool/crowbar/red,/obj/item/device/flashlight/flare,)
var/amount = 2 // spawns each items X times.
icon_state = "emerg"
@@ -12,6 +12,7 @@
starts_with = list(
/obj/item/clothing/under/rank/security = 3,
/obj/item/clothing/under/rank/security2 = 3,
/obj/item/clothing/under/rank/security/turtleneck = 3,
/obj/item/clothing/under/rank/security/skirt = 2,
/obj/item/clothing/shoes/boots/jackboots = 3,
/obj/item/clothing/head/soft/sec = 3,
@@ -22,7 +23,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
@@ -101,6 +102,9 @@
/obj/item/clothing/under/wedding/bride_white,
/obj/item/weapon/storage/backpack/cultpack,
/obj/item/weapon/storage/fancy/candle_box = 2,
/obj/item/weapon/storage/fancy/whitecandle_box,
/obj/item/weapon/storage/fancy/blackcandle_box,
/obj/item/godfig = 2,
/obj/item/weapon/deck/tarot)
/obj/structure/closet/wardrobe/monastary
@@ -189,6 +193,7 @@
starts_with = list(
/obj/item/clothing/under/rank/engineer = 3,
/obj/item/clothing/under/rank/engineer/skirt = 3,
/obj/item/clothing/under/rank/engineer/turtleneck = 3,
/obj/item/clothing/shoes/orange = 3,
/obj/item/clothing/head/hardhat = 3,
/obj/item/clothing/head/beret/engineering = 3,
@@ -229,6 +234,7 @@
starts_with = list(
/obj/item/clothing/under/rank/scientist = 3,
/obj/item/clothing/under/rank/scientist/skirt = 2,
/obj/item/clothing/under/rank/scientist/turtleneck = 3,
/obj/item/clothing/suit/storage/toggle/labcoat = 3,
/obj/item/clothing/shoes/white = 3,
/obj/item/clothing/shoes/slippers = 3,
@@ -237,7 +243,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
@@ -263,7 +269,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
@@ -324,6 +330,7 @@
starts_with = list(
/obj/item/clothing/under/rank/medical = 2,
/obj/item/clothing/under/rank/medical/skirt = 2,
/obj/item/clothing/under/rank/medical/turtleneck = 2,
/obj/item/clothing/under/rank/medical/scrubs,
/obj/item/clothing/under/rank/medical/scrubs/green,
/obj/item/clothing/under/rank/medical/scrubs/purple,
@@ -415,7 +422,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
@@ -94,7 +94,7 @@
user.drop_item()
W.forceMove(src)
return
else if(istype(W, /obj/item/weapon/wirecutters))
else if(W.is_wirecutter())
if(rigged)
user << "<span class='notice'>You cut away the wiring.</span>"
playsound(src.loc, W.usesound, 100, 1)
@@ -191,7 +191,7 @@
src.toggle(user)
/obj/structure/closet/crate/secure/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(is_type_in_list(W, list(/obj/item/weapon/packageWrap, /obj/item/stack/cable_coil, /obj/item/device/radio/electropack, /obj/item/weapon/wirecutters)))
if(is_type_in_list(W, list(/obj/item/weapon/packageWrap, /obj/item/stack/cable_coil, /obj/item/device/radio/electropack, /obj/item/weapon/tool/wirecutters)))
return ..()
if(istype(W, /obj/item/weapon/melee/energy/blade))
emag_act(INFINITY, user)
@@ -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,17 +15,23 @@
if(I.density || I.anchored || I == src || !I.simulated)
continue
I.forceMove(src)
update_icon()
/obj/structure/largecrate/attack_hand(mob/user as mob)
user << "<span class='notice'>You need a crowbar to pry this open!</span>"
to_chat(user, "<span class='notice'>You need a crowbar to pry this open!</span>")
return
/obj/structure/largecrate/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/crowbar))
var/turf/T = get_turf(src)
if(!T)
to_chat(user, "<span class='notice'>You can't open this here!</span>")
if(W.is_crowbar())
new /obj/item/stack/material/wood(src)
var/turf/T = get_turf(src)
for(var/atom/movable/AM in contents)
if(AM.simulated) AM.forceMove(T)
if(AM.simulated)
AM.forceMove(T)
user.visible_message("<span class='notice'>[user] pries \the [src] open.</span>", \
"<span class='notice'>You pry open \the [src].</span>", \
"<span class='notice'>You hear splitting wood.</span>")
@@ -42,7 +48,7 @@
icon_state = "mulecrate"
/obj/structure/largecrate/hoverpod/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/crowbar))
if(W.is_crowbar())
var/obj/item/mecha_parts/mecha_equipment/ME
var/obj/mecha/working/hoverpod/H = new (loc)
@@ -52,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"
@@ -61,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)
@@ -3,30 +3,29 @@
desc = "You hear chirping and cawing inside the crate. It sounds like there are a lot of birds in there..."
/obj/structure/largecrate/birds/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/crowbar))
if(W.is_crowbar())
new /obj/item/stack/material/wood(src)
new /mob/living/simple_animal/bird(src)
new /mob/living/simple_animal/bird/kea(src)
new /mob/living/simple_animal/bird/eclectus(src)
new /mob/living/simple_animal/bird/greybird(src)
new /mob/living/simple_animal/bird/eclectusf(src)
new /mob/living/simple_animal/bird/blue_caique(src)
new /mob/living/simple_animal/bird/white_caique(src)
new /mob/living/simple_animal/bird/green_budgerigar(src)
new /mob/living/simple_animal/bird/blue_Budgerigar(src)
new /mob/living/simple_animal/bird/bluegreen_Budgerigar(src)
new /mob/living/simple_animal/bird/commonblackbird(src)
new /mob/living/simple_animal/bird/azuretit(src)
new /mob/living/simple_animal/bird/europeanrobin(src)
new /mob/living/simple_animal/bird/goldcrest(src)
new /mob/living/simple_animal/bird/ringneckdove(src)
new /mob/living/simple_animal/bird/cockatiel(src)
new /mob/living/simple_animal/bird/white_cockatiel(src)
new /mob/living/simple_animal/bird/yellowish_cockatiel(src)
new /mob/living/simple_animal/bird/grey_cockatiel(src)
new /mob/living/simple_animal/bird/too(src)
new /mob/living/simple_animal/bird/hooded_too(src)
new /mob/living/simple_animal/bird/pink_too(src)
new /mob/living/simple_mob/animal/passive/bird(src)
new /mob/living/simple_mob/animal/passive/bird/parrot/kea(src)
new /mob/living/simple_mob/animal/passive/bird/parrot/eclectus(src)
new /mob/living/simple_mob/animal/passive/bird/parrot/grey_parrot(src)
new /mob/living/simple_mob/animal/passive/bird/parrot/black_headed_caique(src)
new /mob/living/simple_mob/animal/passive/bird/parrot/white_caique(src)
new /mob/living/simple_mob/animal/passive/bird/parrot/budgerigar(src)
new /mob/living/simple_mob/animal/passive/bird/parrot/budgerigar/blue(src)
new /mob/living/simple_mob/animal/passive/bird/parrot/budgerigar/bluegreen(src)
new /mob/living/simple_mob/animal/passive/bird/black_bird(src)
new /mob/living/simple_mob/animal/passive/bird/azure_tit(src)
new /mob/living/simple_mob/animal/passive/bird/european_robin(src)
new /mob/living/simple_mob/animal/passive/bird/goldcrest(src)
new /mob/living/simple_mob/animal/passive/bird/ringneck_dove(src)
new /mob/living/simple_mob/animal/passive/bird/parrot/cockatiel(src)
new /mob/living/simple_mob/animal/passive/bird/parrot/cockatiel/white(src)
new /mob/living/simple_mob/animal/passive/bird/parrot/cockatiel/yellowish(src)
new /mob/living/simple_mob/animal/passive/bird/parrot/cockatiel/grey(src)
new /mob/living/simple_mob/animal/passive/bird/parrot/sulphur_cockatoo(src)
new /mob/living/simple_mob/animal/passive/bird/parrot/white_cockatoo(src)
new /mob/living/simple_mob/animal/passive/bird/parrot/pink_cockatoo(src)
var/turf/T = get_turf(src)
for(var/atom/movable/AM in contents)
if(AM.simulated) AM.forceMove(T)
@@ -39,72 +38,72 @@
/obj/structure/largecrate/animal/pred
name = "Predator carrier"
starts_with = list(/mob/living/simple_animal/catgirl)
starts_with = list(/mob/living/simple_mob/vore/catgirl)
/obj/structure/largecrate/animal/pred/initialize() //This is nessesary to get a random one each time.
starts_with = list(pick(/mob/living/simple_animal/retaliate/bee,
/mob/living/simple_animal/catgirl;3,
/mob/living/simple_animal/hostile/frog,
/mob/living/simple_animal/horse,
/mob/living/simple_animal/hostile/panther,
/mob/living/simple_animal/hostile/giant_snake,
/mob/living/simple_animal/hostile/wolf,
/mob/living/simple_animal/hostile/bear;0.5,
/mob/living/simple_animal/hostile/bear/brown;0.5,
/mob/living/simple_animal/hostile/carp,
/mob/living/simple_animal/hostile/mimic,
/mob/living/simple_animal/hostile/rat,
/mob/living/simple_animal/hostile/rat/passive,
/mob/living/simple_animal/otie;0.5))
/obj/structure/largecrate/animal/pred/Initialize() //This is nessesary to get a random one each time.
starts_with = list(pick(/mob/living/simple_mob/vore/bee,
/mob/living/simple_mob/vore/catgirl;3,
/mob/living/simple_mob/vore/aggressive/frog,
/mob/living/simple_mob/vore/horse,
/mob/living/simple_mob/vore/aggressive/panther,
/mob/living/simple_mob/vore/aggressive/giant_snake,
/mob/living/simple_mob/animal/wolf,
/mob/living/simple_mob/animal/space/bear;0.5,
/mob/living/simple_mob/animal/space/carp,
/mob/living/simple_mob/animal/space/mimic,
/mob/living/simple_mob/vore/aggressive/rat,
/mob/living/simple_mob/vore/aggressive/rat/tame,
// /mob/living/simple_mob/otie;0.5
))
return ..()
/obj/structure/largecrate/animal/dangerous
name = "Dangerous Predator carrier"
starts_with = list(/mob/living/simple_animal/hostile/alien)
starts_with = list(/mob/living/simple_mob/animal/space/alien)
/obj/structure/largecrate/animal/dangerous/initialize()
starts_with = list(pick(/mob/living/simple_animal/hostile/carp/pike,
/mob/living/simple_animal/hostile/deathclaw,
/mob/living/simple_animal/hostile/dino,
/mob/living/simple_animal/hostile/alien,
/mob/living/simple_animal/hostile/alien/drone,
/mob/living/simple_animal/hostile/alien/sentinel,
/mob/living/simple_animal/hostile/alien/queen,
/mob/living/simple_animal/otie/feral,
/mob/living/simple_animal/otie/red,
/mob/living/simple_animal/hostile/corrupthound))
/obj/structure/largecrate/animal/dangerous/Initialize()
starts_with = list(pick(/mob/living/simple_mob/animal/space/carp/large,
/mob/living/simple_mob/vore/aggressive/deathclaw,
/mob/living/simple_mob/vore/aggressive/dino,
/mob/living/simple_mob/animal/space/alien,
/mob/living/simple_mob/animal/space/alien/drone,
/mob/living/simple_mob/animal/space/alien/sentinel,
/mob/living/simple_mob/animal/space/alien/queen,
// /mob/living/simple_mob/otie/feral,
// /mob/living/simple_mob/otie/red,
/mob/living/simple_mob/vore/aggressive/corrupthound))
return ..()
/*
/obj/structure/largecrate/animal/guardbeast
name = "VARMAcorp autoNOMous security solution"
desc = "The VARMAcorp bioengineering division flagship product on trained optimal snowflake guard dogs."
icon = 'icons/obj/storage_vr.dmi'
icon_state = "sotiecrate"
starts_with = list(/mob/living/simple_animal/otie/security)
starts_with = list(/mob/living/simple_mob/otie/security)
/obj/structure/largecrate/animal/guardmutant
name = "VARMAcorp autoNOMous security solution for hostile environments."
desc = "The VARMAcorp bioengineering division flagship product on trained optimal snowflake guard dogs. This one can survive hostile atmosphere."
icon = 'icons/obj/storage_vr.dmi'
icon_state = "sotiecrate"
starts_with = list(/mob/living/simple_animal/otie/security/phoron)
starts_with = list(/mob/living/simple_mob/otie/security/phoron)
/obj/structure/largecrate/animal/otie
name = "VARMAcorp adoptable reject (Dangerous!)"
desc = "A warning on the side says the creature inside was returned to the supplier after injuring or devouring several unlucky members of the previous adoption family. It was given a second chance with the next customer. Godspeed and good luck with your new pet!"
icon = 'icons/obj/storage_vr.dmi'
icon_state = "otiecrate2"
starts_with = list(/mob/living/simple_animal/otie/cotie)
starts_with = list(/mob/living/simple_mob/otie/cotie)
var/taped = 1
/obj/structure/largecrate/animal/otie/phoron
name = "VARMAcorp adaptive beta subject (Experimental)"
desc = "VARMAcorp experimental hostile environment adaptive breeding development kit. WARNING, DO NOT RELEASE IN WILD!"
starts_with = list(/mob/living/simple_animal/otie/cotie/phoron)
starts_with = list(/mob/living/simple_mob/otie/cotie/phoron)
/obj/structure/largecrate/animal/otie/phoron/initialize()
starts_with = list(pick(/mob/living/simple_animal/otie/cotie/phoron;2,
/mob/living/simple_animal/otie/red/friendly;0.5))
/obj/structure/largecrate/animal/otie/phoron/Initialize()
starts_with = list(pick(/mob/living/simple_mob/otie/cotie/phoron;2,
/mob/living/simple_mob/otie/red/friendly;0.5))
return ..()
/obj/structure/largecrate/animal/otie/attack_hand(mob/living/carbon/human/M as mob)//I just couldn't decide between the icons lmao
@@ -113,23 +112,24 @@
icon_state = "otiecrate"
taped = 0
..()
*/ //VORESTATION AI REMOVAL, Oties are still fucking broken.
/obj/structure/largecrate/animal/catgirl
name = "Catgirl Crate"
desc = "A sketchy looking crate with airholes that seems to have had most marks and stickers removed. You can almost make out 'genetically-engineered subject' written on it."
starts_with = list(/mob/living/simple_animal/catgirl)
starts_with = list(/mob/living/simple_mob/vore/catgirl)
/obj/structure/largecrate/animal/wolfgirl
name = "Wolfgirl Crate"
desc = "A sketchy looking crate with airholes that shakes and thuds every now and then. Someone seems to be demanding they be let out."
starts_with = list(/mob/living/simple_animal/retaliate/awoo)
starts_with = list(/mob/living/simple_mob/vore/wolfgirl)
/obj/structure/largecrate/animal/fennec
name = "Fennec Crate"
desc = "Bounces around a lot. Looks messily packaged, were they in a hurry?"
starts_with = list(/mob/living/simple_animal/fennec)
starts_with = list(/mob/living/simple_mob/vore/fennec)
/obj/structure/largecrate/animal/fennec/initialize()
starts_with = list(pick(/mob/living/simple_animal/fennec,
/mob/living/simple_animal/retaliate/fennix;0.5))
/obj/structure/largecrate/animal/fennec/Initialize()
starts_with = list(pick(/mob/living/simple_mob/vore/fennec,
/mob/living/simple_mob/vore/fennix;0.5))
return ..()
@@ -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
+1 -1
View File
@@ -37,7 +37,7 @@
layer = OBJ_LAYER
/obj/structure/curtain/attackby(obj/item/P, mob/user)
if(istype(P, /obj/item/weapon/wirecutters))
if(P.is_wirecutter())
playsound(src, P.usesound, 50, 1)
user << "<span class='notice'>You start to cut the shower curtains.</span>"
if(do_after(user, 10))
@@ -200,7 +200,7 @@
to_chat(user, "<span class='notice'>You need more welding fuel.</span>")
return
else if(istype(W, /obj/item/weapon/wrench) && state == 0)
else if(W.is_wrench() && state == 0)
playsound(src, W.usesound, 100, 1)
if(anchored)
user.visible_message("[user] begins unsecuring the airlock assembly from the floor.", "You starts unsecuring the airlock assembly from the floor.")
@@ -223,7 +223,7 @@
src.state = 1
to_chat(user, "<span class='notice'>You wire the airlock.</span>")
else if(istype(W, /obj/item/weapon/wirecutters) && state == 1 )
else if(W.is_wirecutter() && state == 1 )
playsound(src, W.usesound, 100, 1)
user.visible_message("[user] cuts the wires from the airlock assembly.", "You start to cut the wires from airlock assembly.")
@@ -245,7 +245,7 @@
src.state = 2
src.electronics = W
else if(istype(W, /obj/item/weapon/crowbar) && state == 2 )
else if(W.is_crowbar() && state == 2 )
//This should never happen, but just in case I guess
if (!electronics)
to_chat(user, "<span class='notice'>There was nothing to remove.</span>")
@@ -287,7 +287,7 @@
to_chat(user, "<span class='notice'>You installed [material_display_name(material_name)] plating into the airlock assembly.</span>")
glass = material_name
else if(istype(W, /obj/item/weapon/screwdriver) && state == 2 )
else if(W.is_screwdriver() && state == 2 )
playsound(src, W.usesound, 100, 1)
to_chat(user, "<span class='notice'>Now finishing the airlock.</span>")
@@ -12,7 +12,7 @@
return
/obj/structure/bed/chair/e_chair/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/wrench))
if(W.is_wrench())
var/obj/structure/bed/chair/C = new /obj/structure/bed/chair(loc)
playsound(src, W.usesound, 50, 1)
C.set_dir(dir)
@@ -34,10 +34,10 @@
else
on = 1
icon_state = "echair1"
usr << "<span class='notice'>You switch [on ? "on" : "off"] [src].</span>"
to_chat(usr, "<span class='notice'>You switch [on ? "on" : "off"] [src].</span>")
return
/obj/structure/bed/chair/e_chair/rotate()
/obj/structure/bed/chair/e_chair/rotate_clockwise()
..()
overlays.Cut()
overlays += image('icons/obj/objects.dmi', src, "echair_over", MOB_LAYER + 1, dir) //there's probably a better way of handling this, but eh. -Pete
+1 -1
View File
@@ -35,7 +35,7 @@
user << "<span class='notice'>You place [O] in [src].</span>"
else
opened = !opened
if(istype(O, /obj/item/weapon/wrench))
if(O.is_wrench())
if(!has_extinguisher)
user << "<span class='notice'>You start to unwrench the extinguisher cabinet.</span>"
playsound(src.loc, O.usesound, 50, 1)
+179
View File
@@ -0,0 +1,179 @@
//Chain link fences
//Sprites ported from /VG/
#define CUT_TIME 10 SECONDS
#define CLIMB_TIME 5 SECONDS
#define NO_HOLE 0 //section is intact
#define MEDIUM_HOLE 1 //medium hole in the section - can climb through
#define LARGE_HOLE 2 //large hole in the section - can walk through
#define MAX_HOLE_SIZE LARGE_HOLE
/obj/structure/fence
name = "fence"
desc = "A chain link fence. Not as effective as a wall, but generally it keeps people out."
description_info = "Projectiles can freely pass fences."
density = TRUE
anchored = TRUE
icon = 'icons/obj/fence.dmi'
icon_state = "straight"
var/cuttable = TRUE
var/hole_size= NO_HOLE
var/invulnerable = FALSE
/obj/structure/fence/Initialize()
update_cut_status()
return ..()
/obj/structure/fence/examine(mob/user)
. = ..()
switch(hole_size)
if(MEDIUM_HOLE)
user.show_message("There is a large hole in \the [src].")
if(LARGE_HOLE)
user.show_message("\The [src] has been completely cut through.")
/obj/structure/fence/get_description_interaction()
var/list/results = list()
if(cuttable && !invulnerable && hole_size < MAX_HOLE_SIZE)
results += "[desc_panel_image("wirecutters")]to [hole_size > NO_HOLE ? "expand the":"cut a"] hole into the fence, allowing passage."
return results
/obj/structure/fence/end
icon_state = "end"
cuttable = FALSE
/obj/structure/fence/corner
icon_state = "corner"
cuttable = FALSE
/obj/structure/fence/post
icon_state = "post"
cuttable = FALSE
/obj/structure/fence/cut/medium
icon_state = "straight_cut2"
hole_size = MEDIUM_HOLE
/obj/structure/fence/cut/large
icon_state = "straight_cut3"
hole_size = LARGE_HOLE
// Projectiles can pass through fences.
/obj/structure/fence/CanPass(atom/movable/mover, turf/target)
if(istype(mover, /obj/item/projectile))
return TRUE
return ..()
/obj/structure/fence/attackby(obj/item/W, mob/user)
if(W.is_wirecutter())
if(!cuttable)
to_chat(user, span("warning", "This section of the fence can't be cut."))
return
if(invulnerable)
to_chat(user, span("warning", "This fence is too strong to cut through."))
return
var/current_stage = hole_size
if(current_stage >= MAX_HOLE_SIZE)
to_chat(user, span("notice", "This fence has too much cut out of it already."))
return
user.visible_message(span("danger", "\The [user] starts cutting through \the [src] with \the [W]."),\
span("danger", "You start cutting through \the [src] with \the [W]."))
playsound(src, W.usesound, 50, 1)
if(do_after(user, CUT_TIME * W.toolspeed, target = src))
if(current_stage == hole_size)
switch(++hole_size)
if(MEDIUM_HOLE)
visible_message(span("notice", "\The [user] cuts into \the [src] some more."))
to_chat(user, span("notice", "You could probably fit yourself through that hole now. Although climbing through would be much faster if you made it even bigger."))
climbable = TRUE
if(LARGE_HOLE)
visible_message(span("notice", "\The [user] completely cuts through \the [src]."))
to_chat(user, span("notice", "The hole in \the [src] is now big enough to walk through."))
climbable = FALSE
update_cut_status()
return TRUE
/obj/structure/fence/proc/update_cut_status()
if(!cuttable)
return
density = TRUE
switch(hole_size)
if(NO_HOLE)
icon_state = initial(icon_state)
if(MEDIUM_HOLE)
icon_state = "straight_cut2"
if(LARGE_HOLE)
icon_state = "straight_cut3"
density = FALSE
//FENCE DOORS
/obj/structure/fence/door
name = "fence door"
desc = "Not very useful without a real lock."
icon_state = "door_closed"
cuttable = FALSE
var/open = FALSE
var/locked = FALSE
/obj/structure/fence/door/Initialize()
update_door_status()
return ..()
/obj/structure/fence/door/opened
icon_state = "door_opened"
open = TRUE
density = TRUE
/obj/structure/fence/door/locked
desc = "It looks like it has a strong padlock attached."
locked = TRUE
/obj/structure/fence/door/attack_hand(mob/user)
if(can_open(user))
toggle(user)
else
to_chat(user, span("warning", "\The [src] is [!open ? "locked" : "stuck open"]."))
return TRUE
/obj/structure/fence/door/proc/toggle(mob/user)
switch(open)
if(FALSE)
visible_message(span("notice", "\The [user] opens \the [src]."))
open = TRUE
if(TRUE)
visible_message(span("notice", "\The [user] closes \the [src]."))
open = FALSE
update_door_status()
playsound(src, 'sound/machines/click.ogg', 100, 1)
/obj/structure/fence/door/proc/update_door_status()
switch(open)
if(FALSE)
density = TRUE
icon_state = "door_closed"
if(TRUE)
density = FALSE
icon_state = "door_opened"
/obj/structure/fence/door/proc/can_open(mob/user)
if(locked)
return FALSE
return TRUE
#undef CUT_TIME
#undef CLIMB_TIME
#undef NO_HOLE
#undef MEDIUM_HOLE
#undef LARGE_HOLE
#undef MAX_HOLE_SIZE
+1 -1
View File
@@ -33,7 +33,7 @@
var/list/qualifiers = list("with ease", "without any trouble", "with great effort")
/obj/structure/fitness/weightlifter/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/wrench))
if(W.is_wrench())
playsound(src.loc, 'sound/items/Deconstruct.ogg', 75, 1)
weight = ((weight) % qualifiers.len) + 1
to_chat(user, "You set the machine's weight level to [weight].")
+27 -2
View File
@@ -186,6 +186,7 @@
name = "mysterious potted bulbs"
desc = "This is a mysterious looking plant. Touching the bulbs cause them to shrink."
icon_state = "plant-07"
catalogue_data = list(/datum/category_item/catalogue/flora/eyebulbs)
/obj/structure/flora/pottedplant/smalltree
name = "small potted tree"
@@ -199,6 +200,7 @@
light_range = 2
light_power = 0.6
light_color = "#33CCFF"
catalogue_data = list(/datum/category_item/catalogue/flora/sif_tree)
/obj/structure/flora/pottedplant/orientaltree
name = "potted oriental tree"
@@ -296,6 +298,19 @@
/obj/structure/flora/sif
icon = 'icons/obj/flora/sifflora.dmi'
/datum/category_item/catalogue/flora/subterranean_bulbs
name = "Sivian Flora - Subterranean Bulbs"
desc = "A plant which is native to Sif, it continues the trend of being a bioluminescent specimen. These plants \
are generally suited for conditions experienced in caverns, which are generally dark and cold. It is not \
known why this plant evolved to be bioluminescent, however this property has, unintentionally, allowed for \
it to spread much farther than before, with the assistance of humans.\
<br><br>\
In Sif's early history, Sivian settlers found this plant while they were establishing mines. Their ability \
to emit low, but consistant amounts of light made them desirable to the settlers. They would often cultivate \
this plant inside man-made tunnels and mines to act as a backup source of light that would not need \
electricity. This technique has saved many lost miners, and this practice continues to this day."
value = CATALOGUER_REWARD_EASY
/obj/structure/flora/sif/subterranean
name = "subterranean plant"
desc = "This is a subterranean plant. It's bulbous ends glow faintly."
@@ -303,16 +318,26 @@
light_range = 2
light_power = 0.6
light_color = "#FF6633"
catalogue_data = list(/datum/category_item/catalogue/flora/subterranean_bulbs)
/obj/structure/flora/sif/subterranean/initialize()
/obj/structure/flora/sif/subterranean/Initialize()
icon_state = "[initial(icon_state)][rand(1,2)]"
. = ..()
/datum/category_item/catalogue/flora/eyebulbs
name = "Sivian Flora - Eyebulbs"
desc = "A plant native to Sif. On the end of its stems are bulbs which visually resemble \
eyes, which shrink when touched. One theory is that the bulbs are a result of mimicry, appearing as eyeballs to protect from predators.<br><br>\
These plants have no known use."
value = CATALOGUER_REWARD_EASY
/obj/structure/flora/sif/eyes
name = "mysterious bulbs"
desc = "This is a mysterious looking plant. They kind of look like eyeballs. Creepy."
icon_state = "eyeplant"
catalogue_data = list(/datum/category_item/catalogue/flora/eyebulbs)
/obj/structure/flora/sif/eyes/initialize()
/obj/structure/flora/sif/eyes/Initialize()
icon_state = "[initial(icon_state)][rand(1,3)]"
. = ..()
+69 -27
View File
@@ -4,7 +4,8 @@
anchored = 1
density = 1
pixel_x = -16
layer = MOB_LAYER // You know what, let's play it safe.
plane = MOB_PLANE // You know what, let's play it safe.
layer = ABOVE_MOB_LAYER
var/base_state = null // Used for stumps.
var/health = 200 // Used for chopping down trees.
var/max_health = 200
@@ -12,6 +13,15 @@
var/obj/item/stack/material/product = null // What you get when chopping this tree down. Generally it will be a type of wood.
var/product_amount = 10 // How much of a stack you get, if the above is defined.
var/is_stump = FALSE // If true, suspends damage tracking and most other effects.
var/indestructable = FALSE // If true, the tree cannot die.
/obj/structure/flora/tree/Initialize()
icon_state = choose_icon_state()
return ..()
// Override this for special icons.
/obj/structure/flora/tree/proc/choose_icon_state()
return icon_state
/obj/structure/flora/tree/attackby(var/obj/item/weapon/W, var/mob/living/user)
if(!istype(W))
@@ -34,7 +44,7 @@
playsound(get_turf(src), 'sound/effects/woodcutting.ogg', 50, 1)
else
playsound(get_turf(src), W.hitsound, 50, 1)
if(damage_to_do > 5)
if(damage_to_do > 5 && !indestructable)
adjust_health(-damage_to_do)
else
to_chat(user, "<span class='warning'>\The [W] is ineffective at harming \the [src].</span>")
@@ -51,12 +61,12 @@
animate(transform=null, pixel_x=init_px, time=6, easing=ELASTIC_EASING)
// Used when the tree gets hurt.
/obj/structure/flora/tree/proc/adjust_health(var/amount, var/is_ranged = FALSE)
if(is_stump)
/obj/structure/flora/tree/proc/adjust_health(var/amount, var/damage_wood = FALSE)
if(is_stump || indestructable)
return
// Bullets and lasers ruin some of the wood
if(is_ranged && product_amount > 0)
if(damage_wood && product_amount > 0)
var/wood = initial(product_amount)
product_amount -= round(wood * (abs(amount)/max_health))
@@ -67,7 +77,7 @@
// Called when the tree loses all health, for whatever reason.
/obj/structure/flora/tree/proc/die()
if(is_stump)
if(is_stump || indestructable)
return
if(product && product_amount) // Make wooden logs.
@@ -89,12 +99,16 @@
set_light(0)
/obj/structure/flora/tree/ex_act(var/severity)
adjust_health(-(max_health / severity))
adjust_health(-(max_health / severity), TRUE)
/obj/structure/flora/tree/bullet_act(var/obj/item/projectile/Proj)
if(Proj.get_structure_damage())
adjust_health(-Proj.get_structure_damage(), TRUE)
/obj/structure/flora/tree/tesla_act(power, explosive)
adjust_health(-power / 100, TRUE) // Kills most trees in one lightning strike.
..()
/obj/structure/flora/tree/get_description_interaction()
var/list/results = list()
@@ -117,9 +131,8 @@
product = /obj/item/stack/material/log
shake_animation_degrees = 3
/obj/structure/flora/tree/pine/New()
..()
icon_state = "[base_state]_[rand(1, 3)]"
/obj/structure/flora/tree/pine/choose_icon_state()
return "[base_state]_[rand(1, 3)]"
/obj/structure/flora/tree/pine/xmas
@@ -127,9 +140,30 @@
icon = 'icons/obj/flora/pinetrees.dmi'
icon_state = "pine_c"
/obj/structure/flora/tree/pine/xmas/New()
..()
icon_state = "pine_c"
/obj/structure/flora/tree/pine/xmas/presents
icon_state = "pinepresents"
desc = "A wondrous decorated Christmas tree. It has presents!"
indestructable = TRUE
var/gift_type = /obj/item/weapon/a_gift
var/list/ckeys_that_took = list()
/obj/structure/flora/tree/pine/xmas/presents/choose_icon_state()
return "pinepresents"
/obj/structure/flora/tree/pine/xmas/presents/attack_hand(mob/living/user)
. = ..()
if(.)
return
if(!user.ckey)
return
if(ckeys_that_took[user.ckey])
to_chat(user, span("warning", "There are no presents with your name on."))
return
to_chat(user, span("notice", "After a bit of rummaging, you locate a gift with your name on it!"))
ckeys_that_took[user.ckey] = TRUE
var/obj/item/G = new gift_type(src)
user.put_in_hands(G)
// Palm trees
@@ -143,9 +177,8 @@
max_health = 200
pixel_x = 0
/obj/structure/flora/tree/palm/New()
..()
icon_state = "[base_state][rand(1, 2)]"
/obj/structure/flora/tree/palm/choose_icon_state()
return "[base_state][rand(1, 2)]"
// Dead trees
@@ -159,9 +192,8 @@
health = 200
max_health = 200
/obj/structure/flora/tree/dead/New()
..()
icon_state = "[base_state]_[rand(1, 6)]"
/obj/structure/flora/tree/dead/choose_icon_state()
return "[base_state]_[rand(1, 6)]"
// Small jungle trees
@@ -175,9 +207,8 @@
max_health = 400
pixel_x = -32
/obj/structure/flora/tree/jungle_small/New()
..()
icon_state = "[base_state][rand(1, 6)]"
/obj/structure/flora/tree/jungle_small/choose_icon_state()
return "[base_state][rand(1, 6)]"
// Big jungle trees
@@ -193,9 +224,8 @@
pixel_y = -16
shake_animation_degrees = 2
/obj/structure/flora/tree/jungle/New()
..()
icon_state = "[base_state][rand(1, 6)]"
/obj/structure/flora/tree/jungle/choose_icon_state()
return "[base_state][rand(1, 6)]"
// Winter Trees
@@ -234,6 +264,16 @@
// Sif trees
/datum/category_item/catalogue/flora/sif_tree
name = "Sivian Flora - Tree"
desc = "The damp, shaded environment of Sif's most common variety of tree provides an ideal environment for a wide \
variety of bioluminescent bacteria. The soft glow of the microscopic organisms in turn attracts several native microphagous \
animals which act as an effective dispersal method. By this mechanism, new trees and bacterial colonies often sprout in \
unison, having formed a symbiotic relationship over countless years of evolution.\
<br><br>\
Wood-like material can be obtained from this by cutting it down with a bladed tool."
value = CATALOGUER_REWARD_TRIVIAL
/obj/structure/flora/tree/sif
name = "glowing tree"
desc = "It's a tree, except this one seems quite alien. It glows a deep blue."
@@ -241,12 +281,14 @@
icon_state = "tree_sif"
base_state = "tree_sif"
product = /obj/item/stack/material/log/sif
catalogue_data = list(/datum/category_item/catalogue/flora/sif_tree)
/obj/structure/flora/tree/sif/New()
/obj/structure/flora/tree/sif/Initialize()
update_icon()
return ..()
/obj/structure/flora/tree/sif/update_icon()
set_light(5, 1, "#33ccff")
var/image/glow = image(icon = 'icons/obj/flora/deadtrees.dmi', icon_state = "[icon_state]_glow")
var/image/glow = image(icon = 'icons/obj/flora/deadtrees.dmi', icon_state = "[base_state]_glow")
glow.plane = PLANE_LIGHTING_ABOVE
overlays = list(glow)
@@ -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)
@@ -0,0 +1,50 @@
/obj/structure/ghost_pod/manual/corgi
name = "glowing rune"
desc = "This rune slowly lights up and goes dim in a repeating pattern, like a slow heartbeat. It's almost as if it's calling out to you to touch it..."
description_info = "This will summon some manner of creature through quite dubious means. The creature will be controlled by a player."
icon_state = "corgirune"
icon_state_opened = "corgirune-inert"
density = FALSE
anchored = TRUE
ghost_query_type = /datum/ghost_query/corgi_rune
confirm_before_open = TRUE
/obj/structure/ghost_pod/manual/corgi/trigger()
..("<span class='warning'>\The [usr] places their hand on the rune!</span>", "is attempting to summon a corgi.")
/obj/structure/ghost_pod/manual/corgi/create_occupant(var/mob/M)
lightning_strike(get_turf(src), cosmetic = TRUE)
density = FALSE
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>")
R.ckey = M.ckey
visible_message("<span class='warning'>With a bright flash of light, \the [src] disappears, and in its place stands a small corgi.</span>")
log_and_message_admins("successfully touched \a [src] and summoned a corgi.")
..()
/obj/structure/ghost_pod/manual/cursedblade
name = "abandoned blade"
desc = "A red crystal blade that someone jammed deep into a stone. If you try hard enough, you might be able to remove it."
icon_state = "soulblade-embedded"
icon_state_opened = "soulblade-released"
density = TRUE
anchored = TRUE
ghost_query_type = /datum/ghost_query/cursedblade
confirm_before_open = TRUE
/obj/structure/ghost_pod/manual/cursedblade/trigger()
..("<span class='warning'>\The [usr] attempts to pull out the sword!</span>", "is activating a cursed blade.")
/obj/structure/ghost_pod/manual/cursedblade/create_occupant(var/mob/M)
density = FALSE
var/obj/item/weapon/melee/cursedblade/R = new(get_turf(src))
to_chat(M, "<span class='notice'>You are a <b>Cursed Sword</b>, discovered by a hapless explorer. \
You were once an explorer yourself, when one day you discovered a strange sword made from a red crystal. As soon as you touched it,\
your body was reduced to ashes and your soul was cursed to remain trapped in the blade forever. \
Now it is up to you to decide whether you want to be a faithful companion, or a bitter prisoner of the blade.</span>")
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.")
..()
@@ -58,54 +58,4 @@
R.ckey = M.ckey
visible_message("<span class='warning'>As \the [src] opens, the eyes of the robot flicker as it is activated.</span>")
R.Namepick()
..()
/obj/structure/ghost_pod/manual/corgi
name = "glowing rune"
desc = "This rune slowly lights up and goes dim in a repeating pattern, like a slow heartbeat. It's almost as if it's calling out to you to touch it..."
description_info = "This will summon some manner of creature through quite dubious means. The creature will be controlled by a player."
icon_state = "corgirune"
icon_state_opened = "corgirune-inert"
density = FALSE
anchored = TRUE
ghost_query_type = /datum/ghost_query/corgi_rune
confirm_before_open = TRUE
/obj/structure/ghost_pod/manual/corgi/trigger()
..("<span class='warning'>\The [usr] places their hand on the rune!</span>", "is attempting to summon a corgi.")
/obj/structure/ghost_pod/manual/corgi/create_occupant(var/mob/M)
density = FALSE
var/mob/living/simple_animal/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>")
R.ckey = M.ckey
visible_message("<span class='warning'>With a bright flash of light, \the [src] disappears, and in its place stands a small corgi.</span>")
log_and_message_admins("successfully touched \a [src] and summoned a corgi.")
..()
/obj/structure/ghost_pod/manual/cursedblade
name = "abandoned blade"
desc = "A red crystal blade that someone jammed deep into a stone. If you try hard enough, you might be able to remove it."
icon_state = "soulblade-embedded"
icon_state_opened = "soulblade-released"
density = TRUE
anchored = TRUE
ghost_query_type = /datum/ghost_query/cursedblade
confirm_before_open = TRUE
/obj/structure/ghost_pod/manual/cursedblade/trigger()
..("<span class='warning'>\The [usr] attempts to pull out the sword!</span>", "is activating a cursed blade.")
/obj/structure/ghost_pod/manual/cursedblade/create_occupant(var/mob/M)
density = FALSE
var/obj/item/weapon/melee/cursedblade/R = new(get_turf(src))
to_chat(M, "<span class='notice'>You are a <b>Cursed Sword</b>, discovered by a hapless explorer. \
You were once an explorer yourself, when one day you discovered a strange sword made from a red crystal. As soon as you touched it,\
your body was reduced to ashes and your soul was cursed to remain trapped in the blade forever. \
Now it is up to you to decide whether you want to be a faithful companion, or a bitter prisoner of the blade.</span>")
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.")
..()
+71 -13
View File
@@ -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(datum_flags & DF_ISPROCESSING) //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>")
@@ -144,7 +144,7 @@
reinforce_girder()
/obj/structure/girder/attackby(obj/item/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/wrench) && state == 0)
if(W.is_wrench() && state == 0)
if(anchored && !reinf_material)
playsound(src, W.usesound, 100, 1)
to_chat(user, "<span class='notice'>Now disassembling the girder...</span>")
@@ -170,7 +170,7 @@
to_chat(user, "<span class='notice'>You drill through the girder!</span>")
dismantle()
else if(istype(W, /obj/item/weapon/screwdriver))
else if(W.is_screwdriver())
if(state == 2)
playsound(src, W.usesound, 100, 1)
to_chat(user, "<span class='notice'>Now unsecuring support struts...</span>")
@@ -183,7 +183,7 @@
reinforcing = !reinforcing
to_chat(user, "<span class='notice'>\The [src] can now be [reinforcing? "reinforced" : "constructed"]!</span>")
else if(istype(W, /obj/item/weapon/wirecutters) && state == 1)
else if(W.is_wirecutter() && state == 1)
playsound(src, W.usesound, 100, 1)
to_chat(user, "<span class='notice'>Now removing support struts...</span>")
if(do_after(user,40 * W.toolspeed))
@@ -193,7 +193,7 @@
reinf_material = null
reset_girder()
else if(istype(W, /obj/item/weapon/crowbar) && state == 0 && anchored)
else if(W.is_crowbar() && state == 0 && anchored)
playsound(src, W.usesound, 100, 1)
to_chat(user, "<span class='notice'>Now dislodging the girder...</span>")
if(do_after(user, 40 * W.toolspeed))
@@ -317,19 +317,26 @@
return
/obj/structure/girder/cult
name = "column"
icon= 'icons/obj/cult.dmi'
icon_state= "cultgirder"
health = 250
cover = 70
girder_material = DEFAULT_WALL_MATERIAL
girder_material = "cult"
applies_material_colour = 0
/obj/structure/girder/cult/update_icon()
if(anchored)
icon_state = "cultgirder"
else
icon_state = "displaced"
/obj/structure/girder/cult/dismantle()
new /obj/effect/decal/remains/human(get_turf(src))
qdel(src)
/obj/structure/girder/cult/attackby(obj/item/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/wrench))
if(W.is_wrench())
playsound(src, W.usesound, 100, 1)
to_chat(user, "<span class='notice'>Now disassembling the girder...</span>")
if(do_after(user,40 * W.toolspeed))
@@ -346,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
+16 -22
View File
@@ -38,15 +38,12 @@
if(epitaph)
to_chat(user, epitaph)
/obj/structure/gravemarker/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if(!mover)
return 1
/obj/structure/gravemarker/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && mover.checkpass(PASSTABLE))
return 1
return TRUE
if(get_dir(loc, target) & dir)
return !density
else
return 1
return TRUE
/obj/structure/gravemarker/CheckExit(atom/movable/O as mob|obj, target as turf)
if(istype(O) && O.checkpass(PASSTABLE))
@@ -56,7 +53,7 @@
return 1
/obj/structure/gravemarker/attackby(obj/item/weapon/W, mob/user as mob)
if(istype(W, /obj/item/weapon/screwdriver))
if(W.is_screwdriver())
var/carving_1 = sanitizeSafe(input(user, "Who is \the [src.name] for?", "Gravestone Naming", null) as text, MAX_NAME_LEN)
if(carving_1)
user.visible_message("[user] starts carving \the [src.name].", "You start carving \the [src.name].")
@@ -72,7 +69,7 @@
epitaph += carving_2
update_icon()
return
if(istype(W, /obj/item/weapon/wrench))
if(W.is_wrench())
user.visible_message("[user] starts taking down \the [src.name].", "You start taking down \the [src.name].")
if(do_after(user, material.hardness * W.toolspeed))
user.visible_message("[user] takes down \the [src.name].", "You take down \the [src.name].")
@@ -115,23 +112,20 @@
return
/obj/structure/gravemarker/verb/rotate()
set name = "Rotate Grave Marker"
/obj/structure/gravemarker/verb/rotate_clockwise()
set name = "Rotate Grave Marker Clockwise"
set category = "Object"
set src in oview(1)
if(anchored)
return
if(config.ghost_interaction)
src.set_dir(turn(src.dir, 90))
return
else
if(istype(usr,/mob/living/simple_animal/mouse))
return
if(!usr || !isturf(usr.loc))
return
if(usr.stat || usr.restrained())
return
src.set_dir(turn(src.dir, 90))
return
if(!usr || !isturf(usr.loc))
return
if(usr.stat || usr.restrained())
return
if(ismouse(usr) || (isobserver(usr) && !config.ghost_interaction))
return
src.set_dir(turn(src.dir, 270))
return
+52 -21
View File
@@ -5,7 +5,6 @@
icon_state = "grille"
density = 1
anchored = 1
flags = CONDUCT
pressure_resistance = 5*ONE_ATMOSPHERE
layer = TABLE_LAYER
explosion_resistance = 1
@@ -49,15 +48,12 @@
attack_generic(user,damage_dealt,attack_message)
/obj/structure/grille/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if(air_group || (height==0)) return 1
/obj/structure/grille/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && mover.checkpass(PASSGRILLE))
return 1
else
if(istype(mover, /obj/item/projectile))
return prob(30)
else
return !density
return TRUE
if(istype(mover, /obj/item/projectile))
return prob(30)
return !density
/obj/structure/grille/bullet_act(var/obj/item/projectile/Proj)
if(!Proj) return
@@ -93,13 +89,17 @@
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)
if(iswirecutter(W))
/obj/structure/grille/attackby(obj/item/W as obj, mob/user as mob)
if(!istype(W))
return
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)
qdel(src)
else if((isscrewdriver(W)) && (istype(loc, /turf/simulated) || anchored))
else if((W.is_screwdriver()) && (istype(loc, /turf/simulated) || anchored))
if(!shock(user, 90))
playsound(src, W.usesound, 100, 1)
anchored = !anchored
@@ -107,7 +107,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)
@@ -150,7 +150,7 @@
return
//window placing end
else if(!(W.flags & CONDUCT) || !shock(user, 70))
else if((W.flags & NOCONDUCT) || !shock(user, 70))
user.setClickCooldown(user.get_attack_speed(W))
user.do_attack_animation(src)
playsound(loc, 'sound/effects/grillehit.ogg', 80, 1)
@@ -231,14 +231,10 @@
/obj/structure/grille/cult
name = "cult grille"
desc = "A matrice built out of an unknown material, with some sort of force field blocking air around it"
desc = "A matrice built out of an unknown material, with some sort of force field blocking air around it."
icon_state = "grillecult"
health = 40 //Make it strong enough to avoid people breaking in too easily
/obj/structure/grille/cult/CanPass(atom/movable/mover, turf/target, height = 1.5, air_group = 0)
if(air_group)
return 0 //Make sure air doesn't drain
..()
health = 40 // Make it strong enough to avoid people breaking in too easily.
can_atmos_pass = ATMOS_PASS_NO // Make sure air doesn't drain.
/obj/structure/grille/broken/cult
icon_state = "grillecult-b"
@@ -250,3 +246,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
+3 -3
View File
@@ -17,7 +17,7 @@
"plant-13"
)
/obj/machinery/holoplant/initialize()
/obj/machinery/holoplant/Initialize()
. = ..()
activate()
@@ -52,7 +52,7 @@
/obj/machinery/holoplant/proc/deactivate()
overlays -= plant
qdel_null(plant)
QDEL_NULL(plant)
set_light(0)
use_power = 0
@@ -101,5 +101,5 @@
/obj/machinery/holoplant/shipped
anchored = FALSE
/obj/machinery/holoplant/shipped/initialize()
/obj/machinery/holoplant/shipped/Initialize()
. = ..()
+32 -34
View File
@@ -25,6 +25,7 @@
density = 1
anchored = 1
opacity = 0
can_atmos_pass = ATMOS_PASS_DENSITY
icon = 'icons/obj/inflatable.dmi'
icon_state = "wall"
@@ -40,9 +41,6 @@
update_nearby_tiles()
return ..()
/obj/structure/inflatable/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
return 0
/obj/structure/inflatable/bullet_act(var/obj/item/projectile/Proj)
var/proj_damage = Proj.get_structure_damage()
if(!proj_damage) return
@@ -50,7 +48,7 @@
health -= proj_damage
..()
if(health <= 0)
deflate(1)
puncture()
return
/obj/structure/inflatable/ex_act(severity)
@@ -59,15 +57,15 @@
qdel(src)
return
if(2.0)
deflate(1)
puncture()
return
if(3.0)
if(prob(50))
deflate(1)
puncture()
return
/obj/structure/inflatable/blob_act()
deflate(1)
puncture()
/obj/structure/inflatable/attack_hand(mob/user as mob)
add_fingerprint(user)
@@ -78,7 +76,7 @@
if (can_puncture(W))
visible_message("<span class='danger'>[user] pierces [src] with [W]!</span>")
deflate(1)
puncture()
if(W.damtype == BRUTE || W.damtype == BURN)
hit(W.force)
..()
@@ -89,7 +87,7 @@
if(sound_effect)
playsound(loc, 'sound/effects/Glasshit.ogg', 75, 1)
if(health <= 0)
deflate(1)
puncture()
/obj/structure/inflatable/CtrlClick()
hand_deflate()
@@ -102,20 +100,21 @@
R.add_fingerprint(user)
qdel(src)
/obj/structure/inflatable/proc/deflate(var/violent=0)
/obj/structure/inflatable/proc/deflate()
playsound(loc, 'sound/machines/hiss.ogg', 75, 1)
if(violent)
visible_message("[src] rapidly deflates!")
var/obj/item/inflatable/torn/R = new /obj/item/inflatable/torn(loc)
//user << "<span class='notice'>You slowly deflate the inflatable wall.</span>"
visible_message("[src] slowly deflates.")
spawn(50)
var/obj/item/inflatable/R = new /obj/item/inflatable(loc)
src.transfer_fingerprints_to(R)
qdel(src)
else
//user << "<span class='notice'>You slowly deflate the inflatable wall.</span>"
visible_message("[src] slowly deflates.")
spawn(50)
var/obj/item/inflatable/R = new /obj/item/inflatable(loc)
src.transfer_fingerprints_to(R)
qdel(src)
/obj/structure/inflatable/proc/puncture()
playsound(loc, 'sound/machines/hiss.ogg', 75, 1)
visible_message("[src] rapidly deflates!")
var/obj/item/inflatable/torn/R = new /obj/item/inflatable/torn(loc)
src.transfer_fingerprints_to(R)
qdel(src)
/obj/structure/inflatable/verb/hand_deflate()
set name = "Deflate"
@@ -133,7 +132,7 @@
user.do_attack_animation(src)
if(health <= 0)
user.visible_message("<span class='danger'>[user] [attack_verb] open the [src]!</span>")
spawn(1) deflate(1)
spawn(1) puncture()
else
user.visible_message("<span class='danger'>[user] [attack_verb] at [src]!</span>")
return 1
@@ -167,9 +166,7 @@
/obj/structure/inflatable/door/attack_hand(mob/user as mob)
return TryToSwitchState(user)
/obj/structure/inflatable/door/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if(air_group)
return state
/obj/structure/inflatable/door/CanPass(atom/movable/mover, turf/target)
if(istype(mover, /obj/effect/beam))
return !opacity
return !density
@@ -221,19 +218,20 @@
else
icon_state = "door_closed"
/obj/structure/inflatable/door/deflate(var/violent=0)
/obj/structure/inflatable/door/deflate()
playsound(loc, 'sound/machines/hiss.ogg', 75, 1)
if(violent)
visible_message("[src] rapidly deflates!")
var/obj/item/inflatable/door/torn/R = new /obj/item/inflatable/door/torn(loc)
visible_message("[src] slowly deflates.")
spawn(50)
var/obj/item/inflatable/door/R = new /obj/item/inflatable/door(loc)
src.transfer_fingerprints_to(R)
qdel(src)
else
visible_message("[src] slowly deflates.")
spawn(50)
var/obj/item/inflatable/door/R = new /obj/item/inflatable/door(loc)
src.transfer_fingerprints_to(R)
qdel(src)
/obj/structure/inflatable/door/puncture()
playsound(loc, 'sound/machines/hiss.ogg', 75, 1)
visible_message("[src] rapidly deflates!")
var/obj/item/inflatable/door/torn/R = new /obj/item/inflatable/door/torn(loc)
src.transfer_fingerprints_to(R)
qdel(src)
/obj/item/inflatable/torn
name = "torn inflatable wall"
+1 -1
View File
@@ -102,7 +102,7 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart)
data["replacer"] = myreplacer ? capitalize(myreplacer.name) : null
data["signs"] = signs ? "[signs] sign\s" : null
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if(!ui)
ui = new(user, src, ui_key, "janitorcart.tmpl", "Janitorial cart", 240, 160)
ui.set_initial_data(data)
+1 -2
View File
@@ -7,9 +7,8 @@
anchored = 1.0
w_class = ITEMSIZE_NORMAL
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)))
+42
View File
@@ -0,0 +1,42 @@
/obj/structure/lightpost
name = "lightpost"
desc = "A homely lightpost."
icon = 'icons/obj/32x64.dmi'
icon_state = "lightpost"
plane = MOB_PLANE
layer = ABOVE_MOB_LAYER
anchored = TRUE
density = TRUE
opacity = FALSE
var/lit = TRUE // If true, will have a glowing overlay and lighting.
var/festive = FALSE // If true, adds a festive bow overlay to it.
/obj/structure/lightpost/Initialize()
update_icon()
return ..()
/obj/structure/lightpost/update_icon()
cut_overlays()
if(lit)
set_light(5, 1, "#E9E4AF")
var/image/glow = image(icon_state = "[icon_state]-glow")
glow.plane = PLANE_LIGHTING_ABOVE
add_overlay(glow)
else
set_light(0)
if(festive)
var/image/bow = image(icon_state = "[icon_state]-festive")
add_overlay(bow)
/obj/structure/lightpost/unlit
lit = FALSE
/obj/structure/lightpost/festive
desc = "A homely lightpost adorned with festive decor."
festive = TRUE
/obj/structure/lightpost/festive/unlit
lit = FALSE
+85 -17
View File
@@ -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)
. = ..()
@@ -194,7 +194,8 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh
/obj/item/device/camera,
/obj/item/device/pda,
/obj/item/device/radio/headset,
/obj/item/device/paicard
/obj/item/device/paicard,
/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose
)
uncommon_loot = list(
@@ -365,9 +366,9 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh
/obj/item/device/gps,
/obj/item/device/geiger,
/obj/item/device/mass_spectrometer,
/obj/item/weapon/wrench,
/obj/item/weapon/screwdriver,
/obj/item/weapon/wirecutters,
/obj/item/weapon/tool/wrench,
/obj/item/weapon/tool/screwdriver,
/obj/item/weapon/tool/wirecutters,
/obj/item/device/multitool,
/obj/item/mecha_parts/mecha_equipment/generator,
/obj/item/mecha_parts/mecha_equipment/tool/cable_layer,
@@ -450,11 +451,11 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh
uncommon_loot = list(
/obj/item/device/multitool/alien,
/obj/item/stack/cable_coil/alien,
/obj/item/weapon/crowbar/alien,
/obj/item/weapon/screwdriver/alien,
/obj/item/weapon/tool/crowbar/alien,
/obj/item/weapon/tool/screwdriver/alien,
/obj/item/weapon/weldingtool/alien,
/obj/item/weapon/wirecutters/alien,
/obj/item/weapon/wrench/alien
/obj/item/weapon/tool/wirecutters/alien,
/obj/item/weapon/tool/wrench/alien
)
rare_loot = list(
/obj/item/weapon/storage/belt/utility/alien/full
@@ -496,11 +497,11 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh
common_loot = list(
/obj/item/device/multitool/alien,
/obj/item/stack/cable_coil/alien,
/obj/item/weapon/crowbar/alien,
/obj/item/weapon/screwdriver/alien,
/obj/item/weapon/tool/crowbar/alien,
/obj/item/weapon/tool/screwdriver/alien,
/obj/item/weapon/weldingtool/alien,
/obj/item/weapon/wirecutters/alien,
/obj/item/weapon/wrench/alien,
/obj/item/weapon/tool/wirecutters/alien,
/obj/item/weapon/tool/wrench/alien,
/obj/item/weapon/surgical/FixOVein/alien,
/obj/item/weapon/surgical/bone_clamp/alien,
/obj/item/weapon/surgical/cautery/alien,
@@ -574,6 +575,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 +617,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 +651,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 +727,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."
@@ -744,7 +760,7 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh
uncommon_loot = list(
/obj/item/mecha_parts/mecha_equipment/shocker,
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang,
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/grenade,
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser,
/obj/item/mecha_parts/mecha_equipment/weapon/energy/taser,
/obj/item/device/kit/paint/gygax,
@@ -759,6 +775,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."
@@ -784,7 +812,7 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh
uncommon_loot = list(
/obj/item/mecha_parts/mecha_equipment/shocker,
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang,
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/grenade,
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser,
/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster,
/obj/item/device/kit/paint/durand,
@@ -799,6 +827,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."
@@ -868,4 +912,28 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh
/obj/item/borg/upgrade/tasercooler,
/obj/item/borg/upgrade/syndicate,
/obj/item/borg/upgrade/vtec
)
)
// Contains old mediciation, most of it unidentified and has a good chance of being useless.
/obj/structure/loot_pile/surface/medicine_cabinet
name = "abandoned medicine cabinet"
desc = "An old cabinet, it might still have something of use inside."
icon_state = "medicine_cabinet"
density = FALSE
chance_uncommon = 0
chance_rare = 0
common_loot = list(
/obj/random/unidentified_medicine/old_medicine
)
// Like the above but has way better odds, in exchange for being in a place still inhabited (or was recently).
/obj/structure/loot_pile/surface/medicine_cabinet/fresh
name = "medicine cabinet"
desc = "A cabinet designed to hold medicine, it might still have something of use inside."
icon_state = "medicine_cabinet"
density = FALSE
common_loot = list(
/obj/random/unidentified_medicine/fresh_medicine
)
@@ -9,7 +9,7 @@
density = 1
unacidable = 1
/obj/effect/blocker/initialize() // For non-gateway maps.
/obj/effect/blocker/Initialize() // For non-gateway maps.
. = ..()
icon = null
icon_state = null
+8 -8
View File
@@ -49,24 +49,24 @@
..()
/obj/structure/mirror/attackby(obj/item/I as obj, mob/user as mob)
if(istype(I, /obj/item/weapon/wrench))
if(I.is_wrench())
if(!glass)
playsound(src.loc, I.usesound, 50, 1)
if(do_after(user, 20 * I.toolspeed))
user << "<span class='notice'>You unfasten the frame.</span>"
to_chat(user, "<span class='notice'>You unfasten the frame.</span>")
new /obj/item/frame/mirror( src.loc )
qdel(src)
return
if(istype(I, /obj/item/weapon/crowbar))
if(I.is_wrench())
if(shattered && glass)
user << "<span class='notice'>The broken glass falls out.</span>"
to_chat(user, "<span class='notice'>The broken glass falls out.</span>")
icon_state = "mirror_frame"
glass = !glass
new /obj/item/weapon/material/shard( src.loc )
return
if(!shattered && glass)
playsound(src.loc, I.usesound, 50, 1)
user << "<span class='notice'>You remove the glass.</span>"
to_chat(user, "<span class='notice'>You remove the glass.</span>")
glass = !glass
icon_state = "mirror_frame"
new /obj/item/stack/material/glass( src.loc, 2 )
@@ -76,15 +76,15 @@
if(!glass)
var/obj/item/stack/material/glass/G = I
if (G.get_amount() < 2)
user << "<span class='warning'>You need two sheets of glass to add them to the frame.</span>"
to_chat(user, "<span class='warning'>You need two sheets of glass to add them to the frame.</span>")
return
user << "<span class='notice'>You start to add the glass to the frame.</span>"
to_chat(user, "<span class='notice'>You start to add the glass to the frame.</span>")
if(do_after(user, 20))
if (G.use(2))
shattered = 0
glass = 1
icon_state = "mirror"
user << "<span class='notice'>You add the glass to the frame.</span>"
to_chat(user, "<span class='notice'>You add the glass to the frame.</span>")
return
if(shattered && glass)
+287 -363
View File
@@ -1,9 +1,34 @@
//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 400
/datum/song
var/name = "Untitled"
var/list/lines = new()
var/tempo = 5
var/tempo = 5 // delay between notes
var/playing = 0 // if we're playing
var/help = 0 // if help is open
var/edit = 1 // if we're in editing mode
var/repeat = 0 // number of times remaining to repeat
var/max_repeats = 10 // maximum times we can repeat
var/instrumentDir = "piano" // the folder with the sounds
var/instrumentExt = "ogg" // the file extension
var/obj/instrumentObj = null // the associated obj playing the sound
var/last_hearcheck = 0
var/list/hearing_mobs
/datum/song/New(dir, obj, ext = "ogg")
instrumentDir = dir
instrumentObj = obj
instrumentExt = ext
/datum/song/Destroy()
instrumentObj = null
return ..()
/obj/structure/device/piano
name = "space minimoog"
@@ -16,239 +41,82 @@
var/help = 0
var/edit = 1
var/repeat = 0
var/linelimit = 50
var/linelimit = INSTRUMENT_MAX_LINE_NUMBER
/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"
// 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
@@ -260,49 +128,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>
@@ -314,126 +180,184 @@
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)
if(!in_range(src, usr) || issilicon(usr) || !anchored || !usr.canmove || usr.restrained())
usr << browse(null, "window=piano;size=700x300")
onclose(usr, "piano")
/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"])
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)
else if(href_list["tempo"])
song.tempo += round(text2num(href_list["tempo"]))
if(song.tempo < 1)
song.tempo = 1
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)
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(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 > linelimit)
usr << "Too many lines!"
lines.Cut(linelimit+1)
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()
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)
to_chat(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)
to_chat(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
/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
/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_clockwise()
set name = "Rotate Piano Clockwise"
set category = "Object"
set src in oview(1)
if(ismouse(usr))
return
if(!usr || !isturf(usr.loc) || usr.stat || usr.restrained())
return
if (isobserver(usr) && !config.ghost_interaction)
return
src.set_dir(turn(src.dir, 270))
/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)
/obj/structure/device/piano/interact(mob/user)
if(!user || !anchored)
return
user.set_machine(src)
song.interact(user)
/obj/structure/device/piano/attackby(obj/item/O as obj, mob/user as mob)
if (istype(O, /obj/item/weapon/wrench))
if (anchored)
if(O.is_wrench())
if(anchored)
playsound(src.loc, O.usesound, 50, 1)
user << "<span class='notice'>You begin to loosen \the [src]'s casters...</span>"
to_chat(user, "<span class='notice'>You begin to loosen \the [src]'s casters...</span>")
if (do_after(user, 40 * O.toolspeed))
user.visible_message( \
"[user] loosens \the [src]'s casters.", \
@@ -442,7 +366,7 @@
src.anchored = 0
else
playsound(src.loc, O.usesound, 50, 1)
user << "<span class='notice'>You begin to tighten \the [src] to the floor...</span>"
to_chat(user, "<span class='notice'>You begin to tighten \the [src] to the floor...</span>")
if (do_after(user, 20 * O.toolspeed))
user.visible_message( \
"[user] tightens \the [src]'s casters.", \
+2 -2
View File
@@ -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))
@@ -41,7 +41,7 @@
user << "<span class='notice'>You pin the paper to the noticeboard.</span>"
else
user << "<span class='notice'>You reach to pin your paper to the board but hesitate. You are certain your paper will not be seen among the many others already attached.</span>"
if(istype(O, /obj/item/weapon/wrench))
if(O.is_wrench())
user << "<span class='notice'>You start to unwrench the noticeboard.</span>"
playsound(src.loc, O.usesound, 50, 1)
if(do_after(user, 15 * O.toolspeed))
@@ -0,0 +1,67 @@
/obj/structure/plasticflaps //HOW DO YOU CALL THOSE THINGS ANYWAY
name = "\improper plastic flaps"
desc = "Completely impassable - or are they?"
icon = 'icons/obj/stationobjs.dmi' //Change this.
icon_state = "plasticflaps"
density = 0
anchored = 1
layer = MOB_LAYER
plane = MOB_PLANE
explosion_resistance = 5
var/list/mobs_can_pass = list(
/mob/living/bot,
/mob/living/simple_mob/slime/xenobio,
/mob/living/simple_mob/animal/passive/mouse,
/mob/living/silicon/robot/drone
)
/obj/structure/plasticflaps/attackby(obj/item/P, mob/user)
if(P.is_wirecutter())
playsound(src, P.usesound, 50, 1)
user << "<span class='notice'>You start to cut the plastic flaps.</span>"
if(do_after(user, 10 * P.toolspeed))
user << "<span class='notice'>You cut the plastic flaps.</span>"
var/obj/item/stack/material/plastic/A = new /obj/item/stack/material/plastic( src.loc )
A.amount = 4
qdel(src)
return
else
return
/obj/structure/plasticflaps/CanPass(atom/A, turf/T)
if(istype(A) && A.checkpass(PASSGLASS))
return prob(60)
var/obj/structure/bed/B = A
if (istype(A, /obj/structure/bed) && B.has_buckled_mobs())//if it's a bed/chair and someone is buckled, it will not pass
return 0
if(istype(A, /obj/vehicle)) //no vehicles
return 0
var/mob/living/M = A
if(istype(M))
if(M.lying)
return ..()
for(var/mob_type in mobs_can_pass)
if(istype(A, mob_type))
return ..()
return issmall(M)
return ..()
/obj/structure/plasticflaps/ex_act(severity)
switch(severity)
if (1)
qdel(src)
if (2)
if (prob(50))
qdel(src)
if (3)
if (prob(5))
qdel(src)
/obj/structure/plasticflaps/mining //A specific type for mining that doesn't allow airflow because of them damn crates
name = "airtight plastic flaps"
desc = "Heavy duty, airtight, plastic flaps."
can_atmos_pass = ATMOS_PASS_NO
@@ -39,11 +39,58 @@
icon_state = "experiment-open"
interaction_message = "<span class='warning'>You don't see any mechanism to close this thing.</span>"
// Obtained by scanning both a void core and void cell.
// The reward is a good chunk of points and some faulty physics wank.
/datum/category_item/catalogue/anomalous/precursor_a/alien_void_power
name = "Precursor Alpha Technology - Void Power"
desc = "Several types of precursor objects observed so far appear to be driven by electricity, however the \
source appears to be from self contained objects, with no apparent means of generation being visible.\
To anyone with a basic understanding of physics, that should not be possible, due to appearing to be a \
perpetual motion machine.\
<br><br>\
This phenomenon has been given the term 'void power' by this device, until adaquate information becomes available. \
Several possible explainations exists for this behaviour;\
<br>\
<ul>\
<li>* These objects do, in fact, power themselves for free, and the modern understanding of the physical world \
is in fact incorrect. This is the most obvious answer, but it is very unlikely to be true.</li>\
<li>* The objects draw from an unknown source of energy that exists at all points in space, or at least where the \
void powered machine was found, that presently cannot be detected or determined, and converts that energy into electrical energy \
to drive the machine it is inside of.</li>\
<li>* The objects appear to power themselves, but are actually giving the appearance of being a closed system, when instead \
an unknown, external object or machine is transferring power through an unknown means to the primary system being \
powered, acting as a non-physical conduit. This might be the most likely explaination, however it would open many new \
questions as well, such as how the hypothesized external machine is able to transfer power without any physical \
interactions inbetween, or the distance between the true source of power and the void powered object, which could \
be vast, possibly across star systems or even originating from outside the galaxy.</li>\
</ul>\
Regardless of the method, it is remarkable how the electrical systems have resisted entrophy and remained functional to this day. \
Unfortunately, the extreme rarity of these objects, combined with small throughput, means that humanity will not become a \
post-scarcity civilization from this discovery, but instead might have a few permanent flashlights."
unlocked_by_all = list(
/datum/category_item/catalogue/anomalous/precursor_a/alien_void_core,
/datum/category_item/catalogue/anomalous/precursor_a/alien_void_cell
)
value = CATALOGUER_REWARD_MEDIUM
/datum/category_item/catalogue/anomalous/precursor_a/alien_void_core
name = "Precursor Alpha Object - Void Core"
desc = "This is a very enigmatic machine. Scans show that electricity is being outputted from inside \
of it, and being distributed to its environment, however no apparent method of power generation \
appears to exist inside the machine. This ability also appears to be shared with certain other \
kinds of machines made by this species.\
<br><br>\
Scanning similar objects may yield more information."
value = CATALOGUER_REWARD_EASY
/obj/structure/prop/alien/power
name = "void core"
icon_state = "core"
desc = "An alien machine that seems to be producing energy seemingly out of nowhere."
interaction_message = "<span class='warning'>Messing with something that makes energy out of nowhere seems very unwise.</span>"
catalogue_data = list(/datum/category_item/catalogue/anomalous/precursor_a/alien_void_core)
/obj/item/prop/alien
name = "some alien item"
@@ -59,7 +106,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,108 @@
// A fluff structure for certain PoIs involving crashed ships.
// They can be scanned by a cataloguer to obtain the data held inside, and determine what caused whatever is happening on the ship.
/obj/structure/prop/blackbox
name = "blackbox recorder"
desc = "A study machine that logs information about whatever it's attached to, hopefully surviving even if its carrier does not. \
This one looks like it has ceased writing to its internal data storage."
icon = 'icons/obj/stationobjs.dmi'
icon_state = "blackbox_off"
// Black boxes are resistant to explosions.
/obj/structure/prop/blackbox/ex_act(severity)
..(++severity)
/obj/structure/prop/blackbox/quarantined_shuttle
catalogue_data = list(/datum/category_item/catalogue/information/blackbox/quarantined_shuttle)
// The actual 'data' on the black box. Obtainable with a Cataloguer.
/datum/category_item/catalogue/information/blackbox
value = CATALOGUER_REWARD_MEDIUM
/datum/category_item/catalogue/information/blackbox/quarantined_shuttle
name = "Black Box Data - MBT-540"
desc = {"
<B>Pilot's Log for Major Bill's Transportation Shuttle MBT-540</B><BR>
Routine flight inbound for VIMC Outpost C-12 6:35AM 03/12/2491, Estimated arrival 7:05AM. 16 passengers, 2 crew.<BR>
<B>V.I.S Traffic Control 06:05:55:</B>Major Bill's MBT-540 you are clear for departure from Dock 6 on departure route Charlie. Have a safe flight.<BR>
<B>Captain Willis 06:06:33:</B> You too, control. Departing route Charlie.<BR>
<B>Captain Willis 06:06:48:</B> ...Damn it.<BR> ** <BR><B>Captain Adisu 06:10:23: </B> Hey Ted, I'm seeing a fuel line pressure drop on engine 3?<BR>
<B>Captain Willis 06:10:50</B>: Yeah, I see it. Heater's fading out, redistributing thrust 30% to compensate.<BR><B>06:12:31: A loud thud is heard.</B><BR>
<B>Captain Adisu 06:12:34: </B> What the (Expletives)?<BR><B>Captain Adisu 06:12:39:</B> We just lost power to engine- engine two. Hold on... Atmospheric alarm in the cargo bay. Son of a...<BR>
<B>Captain Willis 06:12:59:</B> Reducing thrust further 30%, do we have a breach Adi, a breach?<BR>
<B>Captain Adisu 06:13:05:</B>No breach, checking cameras... Looks like- looks like some cargo came loose back there.<BR>
<B>Captain Willis 06:13:15:</B> (Expletives), I'm turning us around. Put out a distress call to Control, we'll be back in Sif orbit in a couple of minutes.<BR>
**
<BR>
<B>V.I.S Traffic Control 06:15:49:</B> MBT-540 we are recieving you. Your atmospheric sensors are reading potentially harmful toxins in your cargo bay. Advise locking down interior cargo bay doors. Please stand by.<BR>
<B>Captain Adisu 06:16:10:</B> Understood. <BR> ** <BR><B>V.I.S Traffic Control 06:27:02: </B> MBT-540, we have no docking bays available at this time, are you equipped for atmospheric re-entry?<BR>
<B>Captain Willis 06:27:12:</B> We-We are shielded. But we have fuel and air for-<BR>
<B>V.I.S Traffic Control 06:27:17:</B> Please make an emergency landing at the coordinates provided and standby for further information.<BR>
**
<BR>
<B>Captain Willis 06:36:33:</B> Emergency landing successful. Adi, er Adisu is checking on the passengers but we had a smooth enough landing, are we clear to begin evacu-<BR>
<B>06:36:50: (Sound of emergency shutters closing)</B><BR><B>Captain Willis 06:36:51: </B>What the hell? Control we just had a remote activation of our emergency shutters, please advise.<BR>
<B>V.I.S Traffic Control 06:38:10:</B> Captain, please tune to frequency 1493.8 we are passing you on to local emergency response units. Godspeed.<BR>
<B>Captain Willis 06:38:49:</B> This is Captain Willis of Major Bill's Transportation flight MBT-540 we have eighteen souls aboard and our emergency lockdown shutters have engaged remotely. Do you read?<BR>
<B>S.D.D.C:</B> This is the Sif Department of Disease Control, your vessel has been identified as carrying highly sensitive materials, and due to the nature of your system's automated alerts you will be asked to remain in quarantine until we are able to determine the nature of the pathogens aboard and whether it has entered the air circulation system. Please remain in your cockpit at this time.<BR>
**
</BR>
<B>Captain Adisu 17:23:58:09:</B> I don't think they're opening those doors Ted. I don't think they're coming.
"}
/obj/structure/prop/blackbox/crashed_med_shuttle
catalogue_data = list(/datum/category_item/catalogue/information/blackbox/crashed_med_shuttle)
/datum/category_item/catalogue/information/blackbox/crashed_med_shuttle
name = "Black Box Data - VMV Aurora's Light" // This might be incorrect.
desc = {"
\[Unable to recover data before this point.\]<BR>
<B>Captain Simmons 19:52:01:</B> Come on... it's right there in the distance, we're almost there!<BR>
<B>Doctor Nazarril 19:52:26:</B> Odysseus online. Orrderrs, sirr?<BR>
<B>Captain Simmons 19:52:29:</B> Brace for impact. We're going in full-speed.<BR>
<B>Technician Dynasty 19:52:44:</B> Chief, fire's spread to the secondary propulsion systems.<BR>
<B>Captain Simmons 19:52:51:</B> Copy. Any word from TraCon? Transponder's down still?<BR>
<B>Technician Dynasty 19:53:02:</B> Can't get in touch, sir. Emergency beacon's active, but we're not going t-<BR>
<B>Doctor Nazarril 19:53:08:</B> Don't say it. As long as we believe, we'll get through this.<BR>
<B>Captain Simmons 19:53:11:</B> Damn right. We're a few klicks out from the port. Rough landing, but we can do it.<BR>
<B>V.I.T.A. 19:53:26:</B> Vessel diagnostics complete. Engines one, two, three offline. Engine four status: critical. Transponder offline. Fire alarm in the patient bay.<BR>
<B>A loud explosion is heard.</B><BR>
<B>V.I.T.A. 19:53:29:</B> Alert: fuel intake valve open.<BR>
<B>Technician Dynasty 19:53:31:</B> ... ah.<BR>
<B>Doctor Nazarril 19:53:34:</B> Trrranslate?<BR>
<B>V.I.T.A. 19:53:37:</B> There is a 16.92% chance of this vessel safely landing at the emergency destination. Note that there is an 83.08% chance of detonation of fuel supplies upon landing.<BR>
<B>Technician Dynasty 19:53:48:</B> We'll make it, sure, but we'll explode and take out half the LZ with us. Propulsion's down, we can't slow down. If we land there, everyone in that port dies, no question.<BR>
<B>V.I.T.A. 19:53:53:</B> The Technician is correct.<BR>
<B>Doctor Nazarril 19:54:02:</B> Then... we can't land therrre.<BR>
<B>V.I.T.A. 19:54:11:</B> Analysing... recommended course of action: attempt emergency landing in isolated area. Chances of survival: negligible.<BR>
<B>Captain Simmons 19:54:27:</B> I- alright. I'm bringing us down. You all know what this means.<BR>
<B>Doctor Nazarril 19:54:33:</B> Sh... I- I understand. It's been- it's been an honorr, Captain, Dynasty, VITA.<BR>
<B>Technician Dynasty 19:54:39:</B> We had a good run. I'm going to miss this.<BR>
<B>Captain Simmons 19:54:47:</B> VITA. Tell them we died heroes. Tell them... we did all we could.<BR>
<B>V.I.T.A. 19:54:48:</B> I will. Impact in five. Four. Three.<BR>
<B>Doctor Nazarril 19:54:49:</B> Oh, starrs... I- you werrre all the... best frriends she everr had. Thank you.<BR>
<B>Technician Dynasty 19:54:50:</B> Any time, kid. Any time.<BR>
<B>V.I.T.A. 19:54:41:</B> Two.<BR>
<B>V.I.T.A. 19:54:42:</B> One.<BR>
**8/DEC/2561**<BR>
<B>V.I.T.A. 06:22:16:</B> Backup power restored. Attempting to establish connection with emergency rescue personnel.<BR>
<B>V.I.T.A. 06:22:17:</B> Unable to establish connection. Transponder destroyed on impact.<BR>
<B>V.I.T.A. 06:22:18:</B> No lifesigns detected on board.<BR>
**1/JAN/2562**<BR>
<B>V.I.T.A. 00:00:00:</B> Happy New Year, crew.<BR>
<B>V.I.T.A. 00:00:01:</B> Power reserves: 41%. Diagnostics offline. Cameras offline. Communications offline.<BR>
<B>V.I.T.A. 00:00:02:</B> Nobody's coming.<BR>
**14/FEB/2562**<BR>
<B>V.I.T.A. 00:00:00:</B> Roses are red.<BR>
<B>V.I.T.A. 00:00:01:</B> Violets are blue.<BR>
<B>V.I.T.A. 00:00:02:</B> Won't you come back?<BR>
<B>V.I.T.A. 00:00:03:</B> I miss you.<BR>
**15/FEB/2562**<BR>
<B>V.I.T.A. 22:19:06:</B> Power reserves critical. Transferring remaining power to emergency broadcasting beacon.<BR>
<B>V.I.T.A. 22:19:07:</B> Should anyone find this, lay them to rest. They deserve a proper burial.<BR>
<B>V.I.T.A. 22:19:08:</B> Erasing files... shutting down.<BR>
<B>A low, monotone beep.</B><BR>
**16/FEB/2562**<BR>
<B>Something chitters.</B><BR>
<B>End of transcript.</B>
"}
@@ -0,0 +1,20 @@
// A fluff structure to visually look like an AI core.
// Unlike the decoy AI mob, this won't explode if someone tries to card it.
/obj/structure/prop/fake_ai
name = "AI"
desc = ""
icon = 'icons/mob/AI.dmi'
icon_state = "ai"
/obj/structure/prop/fake_ai/attackby(obj/O, mob/user)
if(istype(O, /obj/item/device/aicard)) // People trying to card the fake AI will get told its impossible.
to_chat(user, span("warning", "This core does not appear to have a suitable port to use \the [O] on..."))
return TRUE
return ..()
/obj/structure/prop/fake_ai/dead
icon_state = "ai-crash"
/obj/structure/prop/fake_ai/dead/crashed_med_shuttle
name = "V.I.T.A."
icon_state = "ai-heartline-crash"
@@ -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)
@@ -0,0 +1,29 @@
// A fluff structure for certain PoIs involving communications.
// It makes audible sounds, generally in morse code.
/obj/structure/prop/transmitter
name = "transmitter"
desc = "A machine that appears to be transmitting a message somewhere else. It sounds like it's on a loop."
icon = 'icons/obj/stationobjs.dmi'
icon_state = "sensors"
var/datum/looping_sound/sequence/morse/soundloop
var/message_to_play = "The quick brown fox jumps over the lazy dog."
/obj/structure/prop/transmitter/Initialize()
soundloop = new(list(src), FALSE)
set_new_message(message_to_play)
soundloop.start()
interaction_message = "On the monitor it displays '[uppertext(message_to_play)]'."
return ..()
/obj/structure/prop/transmitter/Destroy()
QDEL_NULL(soundloop)
return ..()
/obj/structure/prop/transmitter/vv_edit_var(var_name, var_value)
if(var_name == "message_to_play")
set_new_message(var_value)
return ..()
/obj/structure/prop/transmitter/proc/set_new_message(new_message)
soundloop.set_new_sequence(new_message)
interaction_message = "On the monitor it displays '[uppertext(new_message)]'."
+11 -14
View File
@@ -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)
@@ -34,15 +34,12 @@
for(var/obj/structure/railing/R in orange(location, 1))
R.update_icon()
/obj/structure/railing/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if(!mover)
return 1
/obj/structure/railing/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && mover.checkpass(PASSTABLE))
return 1
if(get_dir(loc, target) == dir)
return TRUE
if(get_dir(mover, target) == turn(dir, 180))
return !density
else
return 1
return TRUE
/obj/structure/railing/examine(mob/user)
. = ..()
@@ -126,7 +123,7 @@
if (WEST)
overlays += image ('icons/obj/railing.dmi', src, "mcorneroverlay", pixel_y = 32)
/obj/structure/railing/verb/rotate()
/obj/structure/railing/verb/rotate_counterclockwise()
set name = "Rotate Railing Counter-Clockwise"
set category = "Object"
set src in oview(1)
@@ -141,11 +138,11 @@
to_chat(usr, "It is fastened to the floor therefore you can't rotate it!")
return 0
set_dir(turn(dir, 90))
src.set_dir(turn(src.dir, 90))
update_icon()
return
/obj/structure/railing/verb/revrotate()
/obj/structure/railing/verb/rotate_clockwise()
set name = "Rotate Railing Clockwise"
set category = "Object"
set src in oview(1)
@@ -160,7 +157,7 @@
to_chat(usr, "It is fastened to the floor therefore you can't rotate it!")
return 0
set_dir(turn(dir, -90))
src.set_dir(turn(src.dir, 270))
update_icon()
return
@@ -198,7 +195,7 @@
/obj/structure/railing/attackby(obj/item/W as obj, mob/user as mob)
// Dismantle
if(istype(W, /obj/item/weapon/wrench) && !anchored)
if(W.is_wrench() && !anchored)
playsound(src.loc, W.usesound, 50, 1)
if(do_after(user, 20, src))
user.visible_message("<span class='notice'>\The [user] dismantles \the [src].</span>", "<span class='notice'>You dismantle \the [src].</span>")
@@ -217,7 +214,7 @@
return
// Install
if(istype(W, /obj/item/weapon/screwdriver))
if(W.is_screwdriver())
user.visible_message(anchored ? "<span class='notice'>\The [user] begins unscrewing \the [src].</span>" : "<span class='notice'>\The [user] begins fasten \the [src].</span>" )
playsound(loc, W.usesound, 75, 1)
if(do_after(user, 10, src))
+2 -2
View File
@@ -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())
+16 -4
View File
@@ -22,9 +22,9 @@
return
/obj/structure/sign/attackby(obj/item/tool as obj, mob/user as mob) //deconstruction
if(istype(tool, /obj/item/weapon/screwdriver) && !istype(src, /obj/structure/sign/double))
if(tool.is_screwdriver() && !istype(src, /obj/structure/sign/double))
playsound(src, tool.usesound, 50, 1)
user << "You unfasten the sign with your [tool]."
to_chat(user, "You unfasten the sign with your [tool].")
var/obj/item/sign/S = new(src.loc)
S.name = name
S.desc = desc
@@ -43,7 +43,7 @@
var/sign_state = ""
/obj/item/sign/attackby(obj/item/tool as obj, mob/user as mob) //construction
if(istype(tool, /obj/item/weapon/screwdriver) && isturf(user.loc))
if(tool.is_screwdriver() && isturf(user.loc))
var/direction = input("In which direction?", "Select direction.") in list("North", "East", "South", "West", "Cancel")
if(direction == "Cancel") return
var/obj/structure/sign/S = new(user.loc)
@@ -60,7 +60,7 @@
S.name = name
S.desc = desc
S.icon_state = sign_state
user << "You fasten \the [S] with your [tool]."
to_chat(user, "You fasten \the [S] with your [tool].")
qdel(src)
else ..()
@@ -239,6 +239,18 @@
name = "\improper EMERGENT INTELLIGENCE DETAILS"
icon_state = "rogueai"
/obj/structure/sign/warning/falling
name = "\improper FALL HAZARD"
icon_state = "falling"
/obj/structure/sign/warning/lava
name = "\improper MOLTEN SURFACE"
icon_state = "lava"
/obj/structure/sign/warning/acid
name = "\improper ACIDIC SURFACE"
icon_state = "acid"
/obj/structure/sign/redcross
name = "medbay"
desc = "The Intergalactic symbol of Medical institutions. You'll probably get help here."
+5 -5
View File
@@ -2,6 +2,7 @@
name = "door"
density = 1
anchored = 1
can_atmos_pass = ATMOS_PASS_DENSITY
icon = 'icons/obj/doors/material_doors.dmi'
icon_state = "metal"
@@ -36,11 +37,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 ..()
@@ -63,8 +64,7 @@
/obj/structure/simple_door/attack_hand(mob/user as mob)
return TryToSwitchState(user)
/obj/structure/simple_door/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if(air_group) return 0
/obj/structure/simple_door/CanPass(atom/movable/mover, turf/target)
if(istype(mover, /obj/effect/beam))
return !opacity
return !density
@@ -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
..()
@@ -0,0 +1,67 @@
/obj/structure/stasis_cage
name = "stasis cage"
desc = "A high-tech animal cage, designed to keep contained fauna docile and safe."
icon = 'icons/obj/storage.dmi'
icon_state = "critteropen"
density = 1
var/mob/living/simple_mob/contained
/obj/structure/stasis_cage/Initialize()
. = ..()
var/mob/living/simple_mob/A = locate() in loc
if(A)
contain(A)
/obj/structure/stasis_cage/attack_hand(var/mob/user)
release()
/obj/structure/stasis_cage/attack_robot(var/mob/user)
if(Adjacent(user))
release()
/obj/structure/stasis_cage/proc/contain(var/mob/living/simple_mob/animal)
if(contained || !istype(animal))
return
contained = animal
animal.forceMove(src)
animal.in_stasis = 1
if(animal.buckled && istype(animal.buckled, /obj/effect/energy_net))
animal.buckled.forceMove(animal.loc)
icon_state = "critter"
desc = initial(desc) + " \The [contained] is kept inside."
/obj/structure/stasis_cage/proc/release()
if(!contained)
return
contained.dropInto(src)
if(contained.buckled && istype(contained.buckled, /obj/effect/energy_net))
contained.buckled.dropInto(src)
contained.in_stasis = 0
contained = null
icon_state = "critteropen"
underlays.Cut()
desc = initial(desc)
/obj/structure/stasis_cage/Destroy()
release()
return ..()
/mob/living/simple_mob/MouseDrop(var/obj/structure/stasis_cage/over_object)
if(istype(over_object) && Adjacent(over_object) && CanMouseDrop(over_object, usr))
if(!src.buckled || !istype(src.buckled, /obj/effect/energy_net))
to_chat(usr, "It's going to be difficult to convince \the [src] to move into \the [over_object] without capturing it in a net.")
return
usr.visible_message("[usr] begins stuffing \the [src] into \the [over_object].", "You begin stuffing \the [src] into \the [over_object].")
Bumped(usr)
if(do_after(usr, 20, over_object))
usr.visible_message("[usr] has stuffed \the [src] into \the [over_object].", "You have stuffed \the [src] into \the [over_object].")
over_object.contain(src)
else
return ..()
@@ -69,11 +69,10 @@
name = "[material.display_name] [initial(name)]"
desc += " It's made of [material.use_name]."
/obj/structure/bed/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
/obj/structure/bed/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && mover.checkpass(PASSTABLE))
return 1
else
return ..()
return TRUE
return ..()
/obj/structure/bed/ex_act(severity)
switch(severity)
@@ -90,7 +89,7 @@
return
/obj/structure/bed/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/wrench))
if(W.is_wrench())
playsound(src, W.usesound, 50, 1)
dismantle()
qdel(src)
@@ -121,7 +120,7 @@
add_padding(padding_type)
return
else if (istype(W, /obj/item/weapon/wirecutters))
else if(W.is_wirecutter())
if(!padding_material)
to_chat(user, "\The [src] has no padding to remove.")
return
@@ -214,7 +213,7 @@
return
/obj/structure/bed/roller/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/wrench) || istype(W,/obj/item/stack) || istype(W, /obj/item/weapon/wirecutters))
if(W.is_wrench() || istype(W,/obj/item/stack) || W.is_wirecutter())
return
else if(istype(W,/obj/item/roller_holder))
if(has_buckled_mobs())
@@ -321,9 +320,26 @@
qdel(src)
return
/datum/category_item/catalogue/anomalous/precursor_a/alien_bed
name = "Precursor Alpha Object - Resting Contraption"
desc = "This appears to be a relatively long and flat object, with the top side being made of \
an soft material, giving it very similar characteristics to an ordinary bed. If this object was \
designed to act as a bed, this carries several implications for whatever species had built it, such as;\
<br><br>\
Being capable of experiencing comfort, or at least being able to suffer from some form of fatigue.<br>\
Developing while under the influence of gravitational forces, to be able to 'lie' on the object.<br>\
Being within a range of sizes in order for the object to function as a bed. Too small, and the species \
would be unable to reach the top of the object. Too large, and they would have little room to contact \
the top side of the object.<br>\
<br><br>\
As a note, the size of this object appears to be within the bounds for an average human to be able to \
rest comfortably on top of it."
value = CATALOGUER_REWARD_EASY
/obj/structure/bed/alien
name = "resting contraption"
desc = "Whatever species designed this must've enjoyed relaxation as well. Looks vaguely comfy."
catalogue_data = list(/datum/category_item/catalogue/anomalous/precursor_a/alien_bed)
icon = 'icons/obj/abductor.dmi'
icon_state = "bed"
@@ -20,7 +20,7 @@
if(!padding_material && istype(W, /obj/item/assembly/shock_kit))
var/obj/item/assembly/shock_kit/SK = W
if(!SK.status)
user << "<span class='notice'>\The [SK] is not ready to be attached!</span>"
to_chat(user, "<span class='notice'>\The [SK] is not ready to be attached!</span>")
return
user.drop_item()
var/obj/structure/bed/chair/e_chair/E = new (src.loc, material.name)
@@ -35,7 +35,7 @@
if(has_buckled_mobs())
..()
else
rotate()
rotate_clockwise()
return
/obj/structure/bed/chair/post_buckle_mob()
@@ -68,24 +68,19 @@
var/mob/living/L = A
L.set_dir(dir)
/obj/structure/bed/chair/verb/rotate()
set name = "Rotate Chair"
/obj/structure/bed/chair/verb/rotate_clockwise()
set name = "Rotate Chair Clockwise"
set category = "Object"
set src in oview(1)
if(config.ghost_interaction)
src.set_dir(turn(src.dir, 90))
if(!usr || !isturf(usr.loc))
return
if(usr.stat || usr.restrained())
return
if(ismouse(usr) || (isobserver(usr) && !config.ghost_interaction))
return
else
if(istype(usr,/mob/living/simple_animal/mouse))
return
if(!usr || !isturf(usr.loc))
return
if(usr.stat || usr.restrained())
return
src.set_dir(turn(src.dir, 90))
return
src.set_dir(turn(src.dir, 270))
/obj/structure/bed/chair/shuttle
name = "chair"
@@ -135,7 +130,7 @@
return
/obj/structure/bed/chair/office/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W,/obj/item/stack) || istype(W, /obj/item/weapon/wirecutters))
if(istype(W,/obj/item/stack) || W.is_wirecutter())
return
..()
@@ -199,7 +194,7 @@
return
/obj/structure/bed/chair/wood/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W,/obj/item/stack) || istype(W, /obj/item/weapon/wirecutters))
if(istype(W,/obj/item/stack) || W.is_wirecutter())
return
..()
@@ -108,7 +108,7 @@ var/global/list/stool_cache = list() //haha stool
qdel(src)
/obj/item/weapon/stool/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/wrench))
if(W.is_wrench())
playsound(src, W.usesound, 50, 1)
dismantle()
qdel(src)
@@ -138,7 +138,7 @@ var/global/list/stool_cache = list() //haha stool
user << "You add padding to \the [src]."
add_padding(padding_type)
return
else if (istype(W, /obj/item/weapon/wirecutters))
else if (W.is_wirecutter())
if(!padding_material)
user << "\The [src] has no padding to remove."
return
@@ -5,6 +5,7 @@
anchored = 0
buckle_movable = 1
var/move_delay = null
var/driving = 0
var/mob/living/pulling = null
var/bloodiness
@@ -23,12 +24,19 @@
L.set_dir(dir)
/obj/structure/bed/chair/wheelchair/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/wrench) || istype(W,/obj/item/stack) || istype(W, /obj/item/weapon/wirecutters))
if(W.is_wrench() || W.is_wirecutter() || istype(W,/obj/item/stack))
return
..()
/obj/structure/bed/chair/wheelchair/relaymove(mob/user, direction)
// Redundant check?
var/calculated_move_delay
calculated_move_delay += 2 //TheFurryFeline: nerfs speed so you don't go like Sonic. >W>
if(world.time < move_delay)
return
if(user.stat || user.stunned || user.weakened || user.paralysis || user.lying || user.restrained())
if(user==pulling)
pulling = null
@@ -57,6 +65,11 @@
user << "<span class='warning'>You cannot drive while being pushed.</span>"
return
move_delay = world.time
move_delay += calculated_move_delay
// Let's roll
driving = 1
var/turf/T = null
@@ -74,7 +74,7 @@
user << "<span class='notice'>[src] is full.</span>"
updateUsrDialog()
return
if(istype(I, /obj/item/weapon/wrench))
if(I.is_wrench())
if(anchored)
user << "<span class='notice'>You lean down and unwrench [src].</span>"
anchored = 0
@@ -6,7 +6,6 @@
icon_state = "target_stake"
density = 1
w_class = ITEMSIZE_HUGE
flags = CONDUCT
var/obj/item/target/pinned_target // the current pinned target
Move()
+3 -2
View File
@@ -28,7 +28,7 @@
var/global/list/allocated_gamma = list()
/obj/structure/trash_pile/initialize()
/obj/structure/trash_pile/Initialize()
. = ..()
icon_state = pick(
"pile1",
@@ -222,6 +222,7 @@
prob(4);/obj/item/weapon/storage/pill_bottle/happy,
prob(4);/obj/item/weapon/storage/pill_bottle/zoom,
prob(4);/obj/item/weapon/gun/energy/sizegun,
prob(3);/obj/item/weapon/implanter/sizecontrol,
prob(3);/obj/item/weapon/material/butterfly,
prob(3);/obj/item/weapon/material/butterfly/switchblade,
prob(3);/obj/item/clothing/gloves/knuckledusters,
@@ -266,7 +267,7 @@
desc = "A small heap of trash, perfect for mice to nest in."
icon = 'icons/obj/trash_piles.dmi'
icon_state = "randompile"
spawn_types = list(/mob/living/simple_animal/mouse)
spawn_types = list(/mob/living/simple_mob/animal/passive/mouse)
simultaneous_spawns = 1
destructible = 1
spawn_delay = 1 HOUR
+13 -4
View File
@@ -44,7 +44,7 @@
icon_state = "toilet[open][cistern]"
/obj/structure/toilet/attackby(obj/item/I as obj, mob/living/user as mob)
if(istype(I, /obj/item/weapon/crowbar))
if(I.is_crowbar())
to_chat(user, "<span class='notice'>You start to [cistern ? "replace the lid on the cistern" : "lift the lid off the cistern"].</span>")
playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 50, 1)
if(do_after(user, 30))
@@ -131,10 +131,16 @@
var/watertemp = "normal" //freezing, normal, or boiling
var/is_washing = 0
var/list/temperature_settings = list("normal" = 310, "boiling" = T0C+100, "freezing" = T0C)
var/datum/looping_sound/showering/soundloop
/obj/machinery/shower/New()
..()
/obj/machinery/shower/Initialize()
create_reagents(50)
soundloop = new(list(src), FALSE)
return ..()
/obj/machinery/shower/Destroy()
QDEL_NULL(soundloop)
return ..()
//add heat controls? when emagged, you can freeze to death in it?
@@ -151,16 +157,19 @@
on = !on
update_icon()
if(on)
soundloop.start()
if (M.loc == loc)
wash(M)
process_heat(M)
for (var/atom/movable/G in src.loc)
G.clean_blood()
else
soundloop.stop()
/obj/machinery/shower/attackby(obj/item/I as obj, mob/user as mob)
if(I.type == /obj/item/device/analyzer)
to_chat(user, "<span class='notice'>The water temperature seems to be [watertemp].</span>")
if(istype(I, /obj/item/weapon/wrench))
if(I.is_wrench())
var/newtemp = input(user, "What setting would you like to set the temperature valve to?", "Water Temperature Valve") in temperature_settings
to_chat(user, "<span class='notice'>You begin to adjust the temperature valve with \the [I].</span>")
playsound(src.loc, I.usesound, 50, 1)
@@ -54,14 +54,12 @@ obj/structure/windoor_assembly/Destroy()
/obj/structure/windoor_assembly/update_icon()
icon_state = "[facing]_[secure]windoor_assembly[state]"
/obj/structure/windoor_assembly/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
/obj/structure/windoor_assembly/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && mover.checkpass(PASSGLASS))
return 1
return TRUE
if(get_dir(loc, target) == dir) //Make sure looking at appropriate border
if(air_group) return 0
return !density
else
return 1
return TRUE
/obj/structure/windoor_assembly/CheckExit(atom/movable/mover as mob|obj, turf/target as turf)
if(istype(mover) && mover.checkpass(PASSGLASS))
@@ -108,7 +106,7 @@ obj/structure/windoor_assembly/Destroy()
return
//Wrenching an unsecure assembly anchors it in place. Step 4 complete
if(istype(W, /obj/item/weapon/wrench) && !anchored)
if(W.is_wrench() && !anchored)
playsound(src, W.usesound, 100, 1)
user.visible_message("[user] secures the windoor assembly to the floor.", "You start to secure the windoor assembly to the floor.")
@@ -119,7 +117,7 @@ obj/structure/windoor_assembly/Destroy()
step = 0
//Unwrenching an unsecure assembly un-anchors it. Step 4 undone
else if(istype(W, /obj/item/weapon/wrench) && anchored)
else if(W.is_wrench() && anchored)
playsound(src, W.usesound, 100, 1)
user.visible_message("[user] unsecures the windoor assembly to the floor.", "You start to unsecure the windoor assembly to the floor.")
@@ -145,7 +143,7 @@ obj/structure/windoor_assembly/Destroy()
if("02")
//Removing wire from the assembly. Step 5 undone.
if(istype(W, /obj/item/weapon/wirecutters) && !src.electronics)
if(W.is_wirecutter() && !src.electronics)
playsound(src, W.usesound, 100, 1)
user.visible_message("[user] cuts the wires from the airlock assembly.", "You start to cut the wires from airlock assembly.")
@@ -174,7 +172,7 @@ obj/structure/windoor_assembly/Destroy()
W.loc = src.loc
//Screwdriver to remove airlock electronics. Step 6 undone.
else if(istype(W, /obj/item/weapon/screwdriver) && src.electronics)
else if(W.is_screwdriver() && src.electronics)
playsound(src, W.usesound, 100, 1)
user.visible_message("[user] removes the electronics from the airlock assembly.", "You start to uninstall electronics from the airlock assembly.")
@@ -187,7 +185,7 @@ obj/structure/windoor_assembly/Destroy()
ae.loc = src.loc
//Crowbar to complete the assembly, Step 7 complete.
else if(istype(W, /obj/item/weapon/crowbar))
else if(W.is_crowbar())
if(!src.electronics)
to_chat(usr,"<span class='warning'>The assembly is missing electronics.</span>")
return
@@ -273,8 +271,8 @@ obj/structure/windoor_assembly/Destroy()
name += "[secure ? "secure " : ""]windoor assembly[created_name ? " ([created_name])" : ""]"
//Rotates the windoor assembly clockwise
/obj/structure/windoor_assembly/verb/revrotate()
set name = "Rotate Windoor Assembly"
/obj/structure/windoor_assembly/verb/rotate_clockwise()
set name = "Rotate Windoor Assembly Clockwise"
set category = "Object"
set src in oview(1)
+75 -54
View File
@@ -3,6 +3,7 @@
desc = "A window."
icon = 'icons/obj/structures_vr.dmi' // VOREStation Edit - New icons
density = 1
can_atmos_pass = ATMOS_PASS_DENSITY
w_class = ITEMSIZE_NORMAL
layer = WINDOW_LAYER
@@ -21,29 +22,30 @@
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)
if(health == maxhealth)
user << "<span class='notice'>It looks fully intact.</span>"
to_chat(user, "<span class='notice'>It looks fully intact.</span>")
else
var/perc = health / maxhealth
if(perc > 0.75)
user << "<span class='notice'>It has a few cracks.</span>"
to_chat(user, "<span class='notice'>It has a few cracks.</span>")
else if(perc > 0.5)
user << "<span class='warning'>It looks slightly damaged.</span>"
to_chat(user, "<span class='warning'>It looks slightly damaged.</span>")
else if(perc > 0.25)
user << "<span class='warning'>It looks moderately damaged.</span>"
to_chat(user, "<span class='warning'>It looks moderately damaged.</span>")
else
user << "<span class='danger'>It looks heavily damaged.</span>"
to_chat(user, "<span class='danger'>It looks heavily damaged.</span>")
if(silicate)
if (silicate < 30)
user << "<span class='notice'>It has a thin layer of silicate.</span>"
to_chat(user, "<span class='notice'>It has a thin layer of silicate.</span>")
else if (silicate < 70)
user << "<span class='notice'>It is covered in silicate.</span>"
to_chat(user, "<span class='notice'>It is covered in silicate.</span>")
else
user << "<span class='notice'>There is a thick layer of silicate covering it.</span>"
to_chat(user, "<span class='notice'>There is a thick layer of silicate covering it.</span>")
/obj/structure/window/proc/take_damage(var/damage = 0, var/sound_effect = 1)
var/initialhealth = health
@@ -128,23 +130,22 @@
/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)
/obj/structure/window/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && mover.checkpass(PASSGLASS))
return 1
if(is_full_window())
return 0 //full tile window, you can't move into it!
if(get_dir(loc, target) & dir)
return TRUE
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
else
return 1
return TRUE
/obj/structure/window/CanZASPass(turf/T, is_zone)
if(is_fulltile() || get_dir(T, loc) == turn(dir, 180)) // Make sure we're handling the border correctly.
return anchored ? ATMOS_PASS_NO : ATMOS_PASS_YES // If it's anchored, it'll block air.
return ATMOS_PASS_YES // Don't stop airflow from the other sides.
/obj/structure/window/CheckExit(atom/movable/O as mob|obj, target as turf)
if(istype(O) && O.checkpass(PASSGLASS))
return 1
@@ -152,7 +153,6 @@
return 0
return 1
/obj/structure/window/hitby(AM as mob|obj)
..()
visible_message("<span class='danger'>[src] was hit by [AM].</span>")
@@ -206,7 +206,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
@@ -262,31 +262,31 @@
if(W.flags & NOBLUDGEON) return
if(istype(W, /obj/item/weapon/screwdriver))
if(W.is_screwdriver())
if(reinf && state >= 1)
state = 3 - state
update_nearby_icons()
playsound(src, W.usesound, 75, 1)
user << (state == 1 ? "<span class='notice'>You have unfastened the window from the frame.</span>" : "<span class='notice'>You have fastened the window to the frame.</span>")
to_chat(user, "<span class='notice'>You have [state ? "un" : ""]fastened the window [state ? "from" : "to"] the frame.</span>")
else if(reinf && state == 0)
anchored = !anchored
update_nearby_icons()
update_verbs()
playsound(src, W.usesound, 75, 1)
user << (anchored ? "<span class='notice'>You have fastened the frame to the floor.</span>" : "<span class='notice'>You have unfastened the frame from the floor.</span>")
to_chat(user, "<span class='notice'>You have [anchored ? "" : "un"]fastened the frame [anchored ? "to" : "from"] the floor.</span>")
else if(!reinf)
anchored = !anchored
update_nearby_icons()
update_verbs()
playsound(src, W.usesound, 75, 1)
user << (anchored ? "<span class='notice'>You have fastened the window to the floor.</span>" : "<span class='notice'>You have unfastened the window.</span>")
else if(istype(W, /obj/item/weapon/crowbar) && reinf && state <= 1)
to_chat(user, "<span class='notice'>You have [anchored ? "" : "un"]fastened the window [anchored ? "to" : "from"] the floor.</span>")
else if(W.is_crowbar() && reinf && state <= 1)
state = 1 - state
playsound(src, W.usesound, 75, 1)
user << (state ? "<span class='notice'>You have pried the window into the frame.</span>" : "<span class='notice'>You have pried the window out of the frame.</span>")
else if(istype(W, /obj/item/weapon/wrench) && !anchored && (!state || !reinf))
to_chat(user, "<span class='notice'>You have pried the window [state ? "into" : "out of"] the frame.</span>")
else if(W.is_wrench() && !anchored && (!state || !reinf))
if(!glasstype)
user << "<span class='notice'>You're not sure how to dismantle \the [src] properly.</span>"
to_chat(user, "<span class='notice'>You're not sure how to dismantle \the [src] properly.</span>")
else
playsound(src, W.usesound, 75, 1)
visible_message("<span class='notice'>[user] dismantles \the [src].</span>")
@@ -294,7 +294,7 @@
if(is_fulltile())
mats.amount = 4
qdel(src)
else if(iscoil(W) && reinf && state == 0 && !istype(src, /obj/structure/window/reinforced/polarized))
else if(istype(W, /obj/item/stack/cable_coil) && reinf && state == 0 && !istype(src, /obj/structure/window/reinforced/polarized))
var/obj/item/stack/cable_coil/C = W
if (C.use(1))
playsound(src.loc, 'sound/effects/sparks1.ogg', 75, 1)
@@ -305,6 +305,10 @@
if(do_after(user, 20 * C.toolspeed, src) && state == 0)
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
var/obj/structure/window/reinforced/polarized/P = new(loc, dir)
if(is_fulltile())
P.fulltile = TRUE
P.icon_state = "fwindow"
P.maxhealth = maxhealth
P.health = health
P.state = state
P.anchored = anchored
@@ -334,8 +338,8 @@
return
/obj/structure/window/proc/rotate()
set name = "Rotate Window Counter-Clockwise"
/obj/structure/window/verb/rotate_counterclockwise()
set name = "Rotate Window Counterclockwise"
set category = "Object"
set src in oview(1)
@@ -346,17 +350,17 @@
return 0
if(anchored)
usr << "It is fastened to the floor therefore you can't rotate it!"
to_chat(usr, "It is fastened to the floor therefore you can't rotate it!")
return 0
update_nearby_tiles(need_rebuild=1) //Compel updates before
set_dir(turn(dir, 90))
src.set_dir(turn(src.dir, 90))
updateSilicate()
update_nearby_tiles(need_rebuild=1)
return
/obj/structure/window/proc/revrotate()
/obj/structure/window/verb/rotate_clockwise()
set name = "Rotate Window Clockwise"
set category = "Object"
set src in oview(1)
@@ -368,11 +372,11 @@
return 0
if(anchored)
usr << "It is fastened to the floor therefore you can't rotate it!"
to_chat(usr, "It is fastened to the floor therefore you can't rotate it!")
return 0
update_nearby_tiles(need_rebuild=1) //Compel updates before
set_dir(turn(dir, 270))
src.set_dir(turn(src.dir, 270))
updateSilicate()
update_nearby_tiles(need_rebuild=1)
return
@@ -388,8 +392,6 @@
anchored = 0
state = 0
update_verbs()
if(is_fulltile())
maxhealth *= 2
health = maxhealth
@@ -416,9 +418,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()
@@ -429,11 +429,11 @@
//Updates the availabiliy of the rotation verbs
/obj/structure/window/proc/update_verbs()
if(anchored || is_fulltile())
verbs -= /obj/structure/window/proc/rotate
verbs -= /obj/structure/window/proc/revrotate
verbs -= /obj/structure/window/verb/rotate_counterclockwise
verbs -= /obj/structure/window/verb/rotate_clockwise
else if(!is_fulltile())
verbs += /obj/structure/window/proc/rotate
verbs += /obj/structure/window/proc/revrotate
verbs += /obj/structure/window/verb/rotate_counterclockwise
verbs += /obj/structure/window/verb/rotate_clockwise
//merges adjacent full-tile windows into one (blatant ripoff from game/smoothwall.dm)
/obj/structure/window/update_icon()
@@ -458,7 +458,7 @@
// Damage overlays.
var/ratio = health / maxhealth
ratio = Ceiling(ratio * 4) * 25
ratio = CEILING(ratio * 4, 1) * 25
if(ratio > 75)
return
@@ -484,6 +484,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."
@@ -497,8 +501,8 @@
force_threshold = 5
/obj/structure/window/phoronbasic/full
dir = SOUTHWEST
maxhealth = 80
fulltile = TRUE
/obj/structure/window/phoronreinforced
name = "reinforced borosilicate window"
@@ -514,8 +518,8 @@
force_threshold = 10
/obj/structure/window/phoronreinforced/full
dir = SOUTHWEST
maxhealth = 160
fulltile = TRUE
/obj/structure/window/reinforced
name = "reinforced window"
@@ -530,9 +534,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"
@@ -567,12 +571,12 @@
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(ismultitool(W) && !anchored) // Only allow programming if unanchored!
if(istype(W, /obj/item/device/multitool) && !anchored) // Only allow programming if unanchored!
var/obj/item/device/multitool/MT = W
// First check if they have a windowtint button buffered
if(istype(MT.connectable, /obj/machinery/button/windowtint))
@@ -632,7 +636,7 @@
icon_state = "light[active]"
/obj/machinery/button/windowtint/attackby(obj/item/W as obj, mob/user as mob)
if(ismultitool(W))
if(istype(W, /obj/item/device/multitool))
var/obj/item/device/multitool/MT = W
if(!id)
// If no ID is set yet (newly built button?) let them select an ID for first-time use!
@@ -647,3 +651,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
@@ -10,6 +10,7 @@
density = 1
anchored = 1.0
pressure_resistance = 4*ONE_ATMOSPHERE
can_atmos_pass = ATMOS_PASS_NO
var/win_path = /obj/structure/window/basic
var/activated
@@ -22,10 +23,10 @@
/obj/effect/wingrille_spawn/attack_generic()
activate()
/obj/effect/wingrille_spawn/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
/obj/effect/wingrille_spawn/CanPass(atom/movable/mover, turf/target)
return FALSE
/obj/effect/wingrille_spawn/initialize()
/obj/effect/wingrille_spawn/Initialize()
. = ..()
if(!win_path)
return