mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2026-08-27 23:29:10 +01:00
Merge branch 'map' into RadiantMaster
This commit is contained in:
@@ -159,14 +159,14 @@
|
||||
if(burning)
|
||||
burning = FALSE
|
||||
update_icon()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
visible_message("<span class='notice'>\The [src] stops burning.</span>")
|
||||
|
||||
/obj/structure/bonfire/proc/ignite()
|
||||
if(!burning && get_fuel_amount())
|
||||
burning = TRUE
|
||||
update_icon()
|
||||
processing_objects += src
|
||||
START_PROCESSING(SSobj, src)
|
||||
visible_message("<span class='warning'>\The [src] starts burning!</span>")
|
||||
|
||||
/obj/structure/bonfire/proc/burn()
|
||||
@@ -342,14 +342,14 @@
|
||||
if(burning)
|
||||
burning = FALSE
|
||||
update_icon()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
visible_message("<span class='notice'>\The [src] stops burning.</span>")
|
||||
|
||||
/obj/structure/fireplace/proc/ignite()
|
||||
if(!burning && get_fuel_amount())
|
||||
burning = TRUE
|
||||
update_icon()
|
||||
processing_objects += src
|
||||
START_PROCESSING(SSobj, src)
|
||||
visible_message("<span class='warning'>\The [src] starts burning!</span>")
|
||||
|
||||
/obj/structure/fireplace/proc/burn()
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
var/maxhealth = 100
|
||||
anchored = 1.0
|
||||
|
||||
/obj/structure/catwalk/initialize()
|
||||
/obj/structure/catwalk/Initialize()
|
||||
. = ..()
|
||||
for(var/obj/structure/catwalk/O in range(1))
|
||||
O.update_icon()
|
||||
@@ -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))
|
||||
|
||||
@@ -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 ..()
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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].")
|
||||
|
||||
@@ -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)]"
|
||||
. = ..()
|
||||
|
||||
@@ -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.")
|
||||
..()
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
. = ..()
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)))
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.", \
|
||||
|
||||
@@ -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)]'."
|
||||
@@ -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))
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user