Merge remote-tracking branch 'origin/master' into perlin-genny
This commit is contained in:
@@ -1,92 +0,0 @@
|
||||
/* BALLS - GLORIOUS BALLS
|
||||
//
|
||||
// Includes:-
|
||||
// 1) Tennis balls, lines 10 - 92
|
||||
//
|
||||
//
|
||||
//
|
||||
*/
|
||||
|
||||
/obj/item/toy/tennis
|
||||
name = "tennis ball"
|
||||
desc = "A classical tennis ball. It appears to have faint bite marks scattered all over its surface."
|
||||
icon = 'modular_citadel/icons/obj/balls.dmi'
|
||||
icon_state = "tennis_classic"
|
||||
lefthand_file = 'modular_citadel/icons/mob/inhands/balls_left.dmi'
|
||||
righthand_file = 'modular_citadel/icons/mob/inhands/balls_right.dmi'
|
||||
item_state = "tennis_classic"
|
||||
mob_overlay_icon = 'modular_citadel/icons/mob/mouthball.dmi'
|
||||
slot_flags = ITEM_SLOT_HEAD | ITEM_SLOT_NECK | ITEM_SLOT_EARS //Fluff item, put it wherever you want!
|
||||
throw_range = 14
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
|
||||
/obj/item/toy/tennis/alt_pre_attack(atom/A, mob/living/user, params) //checks if it can do right click memes
|
||||
altafterattack(A, user, TRUE, params)
|
||||
return TRUE
|
||||
|
||||
/obj/item/toy/tennis/altafterattack(atom/target, mob/living/carbon/user, proximity_flag, click_parameters) //does right click memes
|
||||
if(istype(user))
|
||||
user.visible_message("<span class='notice'>[user] waggles [src] at [target].</span>", "<span class='notice'>You waggle [src] at [target].</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/item/toy/tennis/rainbow
|
||||
name = "pseudo-euclidean interdimensional tennis sphere"
|
||||
desc = "A tennis ball from another plane of existance. Really groovy."
|
||||
icon_state = "tennis_rainbow"
|
||||
item_state = "tennis_rainbow"
|
||||
actions_types = list(/datum/action/item_action/squeeze) //Giving the masses easy access to unilimted honks would be annoying
|
||||
|
||||
/obj/item/toy/tennis/rainbow/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/squeak)
|
||||
|
||||
/obj/item/toy/tennis/rainbow/izzy //izzyinbox's donator item
|
||||
name = "Katlin's Ball"
|
||||
desc = "A tennis ball that's seen a good bit of love, being covered in a few black and white hairs and slobber."
|
||||
icon_state = "tennis_izzy"
|
||||
item_state = "tennis_izzy"
|
||||
|
||||
/obj/item/toy/tennis/red //da red wuns go fasta
|
||||
name = "red tennis ball"
|
||||
desc = "A red tennis ball. It goes three times faster!"
|
||||
icon_state = "tennis_red"
|
||||
item_state = "tennis_red"
|
||||
throw_speed = 9
|
||||
|
||||
/obj/item/toy/tennis/yellow //because yellow is hot I guess
|
||||
name = "yellow tennis ball"
|
||||
desc = "A yellow tennis ball. It seems to have a flame-retardant coating."
|
||||
icon_state = "tennis_yellow"
|
||||
item_state = "tennis_yellow"
|
||||
resistance_flags = FIRE_PROOF
|
||||
|
||||
/obj/item/toy/tennis/green //pestilence
|
||||
name = "green tennis ball"
|
||||
desc = "A green tennis ball. It seems to have an impermeable coating."
|
||||
icon_state = "tennis_green"
|
||||
item_state = "tennis_green"
|
||||
permeability_coefficient = 0.9
|
||||
|
||||
/obj/item/toy/tennis/cyan //electric
|
||||
name = "cyan tennis ball"
|
||||
desc = "A cyan tennis ball. It seems to have odd electrical properties."
|
||||
icon_state = "tennis_cyan"
|
||||
item_state = "tennis_cyan"
|
||||
siemens_coefficient = 0.9
|
||||
|
||||
/obj/item/toy/tennis/blue //reliability
|
||||
name = "blue tennis ball"
|
||||
desc = "A blue tennis ball. It seems ever so slightly more robust than normal."
|
||||
icon_state = "tennis_blue"
|
||||
item_state = "tennis_blue"
|
||||
max_integrity = 300
|
||||
|
||||
/obj/item/toy/tennis/purple //because purple dyes have high pH and would neutralize acids I guess
|
||||
name = "purple tennis ball"
|
||||
desc = "A purple tennis ball. It seems to have an acid-resistant coating."
|
||||
icon_state = "tennis_purple"
|
||||
item_state = "tennis_purple"
|
||||
resistance_flags = ACID_PROOF
|
||||
|
||||
/datum/action/item_action/squeeze
|
||||
name = "Squeak!"
|
||||
@@ -549,6 +549,7 @@
|
||||
contraband = TRUE
|
||||
obj_flags |= EMAGGED
|
||||
to_chat(user, "<span class='notice'>You adjust [src]'s routing and receiver spectrum, unlocking special supplies and contraband.</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/item/circuitboard/computer/cargo/configure_machine(obj/machinery/computer/cargo/machine)
|
||||
if(!istype(machine))
|
||||
@@ -565,10 +566,12 @@
|
||||
build_path = /obj/machinery/computer/cargo/express
|
||||
|
||||
/obj/item/circuitboard/computer/cargo/express/emag_act(mob/living/user)
|
||||
. = ..()
|
||||
if(!(obj_flags & EMAGGED))
|
||||
contraband = TRUE
|
||||
obj_flags |= EMAGGED
|
||||
to_chat(user, "<span class='notice'>You change the routing protocols, allowing the Drop Pod to land anywhere on the station.</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/item/circuitboard/computer/cargo/express/multitool_act(mob/living/user)
|
||||
if (!(obj_flags & EMAGGED))
|
||||
|
||||
@@ -472,7 +472,7 @@
|
||||
build_path = /obj/machinery/holopad
|
||||
secure = FALSE
|
||||
else
|
||||
build_path = /obj/machinery/holopad //secure
|
||||
build_path = /obj/machinery/holopad/secure //secure
|
||||
secure = TRUE
|
||||
to_chat(user, "<span class='notice'>You [secure? "en" : "dis"]able the security on the [src]</span>")
|
||||
. = ..()
|
||||
@@ -609,6 +609,7 @@
|
||||
/obj/machinery/vending/cigarette = "ShadyCigs Deluxe",
|
||||
/obj/machinery/vending/games = "\improper Good Clean Fun",
|
||||
/obj/machinery/vending/kink = "KinkMate",
|
||||
/obj/machinery/vending/barkbox = "Bark Box",
|
||||
/obj/machinery/vending/autodrobe = "AutoDrobe",
|
||||
/obj/machinery/vending/wardrobe/sec_wardrobe = "SecDrobe",
|
||||
/obj/machinery/vending/wardrobe/det_wardrobe = "DetDrobe",
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
/* Balls, Bones, and Bountiful Fun
|
||||
//
|
||||
// Includes:-
|
||||
// 1) Fluff Content, lines 12 - 131
|
||||
//
|
||||
// 1) Tennis balls, lines 39 - 99
|
||||
// 2) Chew bones, lines 101 - 138
|
||||
// 3) Frisbee, lines 140 - 166
|
||||
*/
|
||||
|
||||
/obj/item/toy/fluff
|
||||
name = "Fluff Item"
|
||||
desc = "You shouldn't be seeing this."
|
||||
icon = 'icons/obj/barkbox_fluff.dmi'
|
||||
icon_state = "poly_tennis"
|
||||
item_state = "poly_tennis"
|
||||
lefthand_file = 'icons/mob/inhands/fluff_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/fluff_righthand.dmi'
|
||||
mob_overlay_icon = 'icons/mob/mouthfluff.dmi'
|
||||
slot_flags = ITEM_SLOT_HEAD | ITEM_SLOT_NECK | ITEM_SLOT_EARS
|
||||
var/poly_states = 0
|
||||
var/poly_colors = list()
|
||||
|
||||
/obj/item/toy/fluff/alt_pre_attack(atom/A, mob/living/user, params) //checks if it can do right click memes
|
||||
altafterattack(A, user, TRUE, params)
|
||||
return TRUE
|
||||
|
||||
/obj/item/toy/fluff/altafterattack(atom/target, mob/living/carbon/user, proximity_flag, click_parameters) //does right click memes
|
||||
if(istype(user))
|
||||
user.visible_message("<span class='notice'>[user] waggles [src] at [target].</span>", "<span class='notice'>You waggle [src] at [target].</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/item/toy/fluff/ComponentInitialize()
|
||||
. = ..()
|
||||
if(!poly_states)
|
||||
return
|
||||
AddElement(/datum/element/polychromic, poly_colors, poly_states, _flags = POLYCHROMIC_ACTION)
|
||||
|
||||
/obj/item/toy/fluff/tennis_poly
|
||||
name = "polychromic tennis ball"
|
||||
desc = "A polychromic tennis ball. There's a half torn tag read: WARNIN-, surely it means nothing. Right?"
|
||||
throw_range = 14
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
poly_states = 2
|
||||
poly_colors = list("#CCFF00", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/tennis_poly/red
|
||||
poly_colors = list("#FF4C00", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/tennis_poly/yellow
|
||||
poly_colors = list("#FFCC00", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/tennis_poly/green
|
||||
poly_colors = list("#99FF00", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/tennis_poly/cyan
|
||||
poly_colors = list("#00FFB2", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/tennis_poly/blue
|
||||
poly_colors = list("#007FFF", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/tennis_poly/purple
|
||||
poly_colors = list("#CC00FF", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/tennis_poly/tri
|
||||
name = "tricolor-polychromic tennis ball"
|
||||
desc = "A tricolor-polychromic tennis ball. Triple the shocking!"
|
||||
icon_state = "tripoly_tennis"
|
||||
item_state = "tripoly_tennis"
|
||||
poly_states = 3
|
||||
poly_colors = list("#FFFFFF", "#FFFFFF", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/tennis_poly/tri/squeak
|
||||
name = "tricolor-polychromic tennis sphere"
|
||||
desc = "A tricolor-polychromic tennis ball. This one seems to emit a squeak when squeezed."
|
||||
actions_types = list(/datum/action/item_action/squeeze)
|
||||
|
||||
/obj/item/toy/fluff/tennis_poly/tri/squeak/izzy //izzyinbox's donator item
|
||||
name = "Katlin's Ball"
|
||||
desc = "A tennis ball that's seen a good bit of love, being covered in a few black and white hairs and slobber."
|
||||
poly_colors = list("#8FED56", "#51cfde", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/tennis_poly/tri/squeak/rainbow
|
||||
name = "pseudo-euclidean interdimensional tennis sphere"
|
||||
desc = "A tennis ball from another plane of existance. Really groovy."
|
||||
icon_state = "tennis_rainbow"
|
||||
item_state = "tennis_rainbow"
|
||||
poly_states = 0
|
||||
actions_types = list(/datum/action/item_action/squeeze)
|
||||
|
||||
/obj/item/toy/fluff/tennis_poly/tri/squeak/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/squeak)
|
||||
|
||||
/obj/item/toy/fluff/bone_poly
|
||||
name = "polychromic bone"
|
||||
desc = "A polychromic chew bone. Nothing like a good bone to chew on."
|
||||
icon_state = "poly_bone"
|
||||
item_state = "poly_bone"
|
||||
throw_range = 7
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
poly_states = 1
|
||||
poly_colors = list("#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/bone_poly/red
|
||||
poly_colors = list("#FF4C00")
|
||||
|
||||
/obj/item/toy/fluff/bone_poly/yellow
|
||||
poly_colors = list("#FFCC00")
|
||||
|
||||
/obj/item/toy/fluff/bone_poly/green
|
||||
poly_colors = list("#99FF00")
|
||||
|
||||
/obj/item/toy/fluff/bone_poly/cyan
|
||||
poly_colors = list("#00FFB2")
|
||||
|
||||
/obj/item/toy/fluff/bone_poly/blue
|
||||
poly_colors = list("#007FFF")
|
||||
|
||||
/obj/item/toy/fluff/bone_poly/purple
|
||||
poly_colors = list("#CC00FF")
|
||||
|
||||
/obj/item/toy/fluff/bone_poly/squeak
|
||||
name = "polychromic bone"
|
||||
desc = "A polychromic chew bone. Makes a small squeak when squeezed."
|
||||
|
||||
/obj/item/toy/fluff/bone_poly/squeak/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/squeak)
|
||||
|
||||
/datum/action/item_action/squeeze
|
||||
name = "Squeak!"
|
||||
|
||||
/obj/item/toy/fluff/frisbee_poly
|
||||
name = "polychromic frisbee"
|
||||
desc = "A polychromic frisbee. Warning: May induce shock."
|
||||
icon_state = "poly_frisbee"
|
||||
item_state = "poly_frisbee"
|
||||
throw_range = 14
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
poly_states = 2
|
||||
poly_colors = list("#CCFF00", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/frisbee_poly/red
|
||||
poly_colors = list("#FF4C00", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/frisbee_poly/yellow
|
||||
poly_colors = list("#FFCC00", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/frisbee_poly/green
|
||||
poly_colors = list("#99FF00", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/frisbee_poly/cyan
|
||||
poly_colors = list("#00FFB2", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/frisbee_poly/blue
|
||||
poly_colors = list("#007FFF", "#FFFFFF")
|
||||
|
||||
/obj/item/toy/fluff/frisbee_poly/purple
|
||||
poly_colors = list("#CC00FF", "#FFFFFF")
|
||||
@@ -459,8 +459,8 @@
|
||||
|
||||
/obj/item/stack/AltClick(mob/living/user)
|
||||
. = ..()
|
||||
if(isturf(loc)) // to prevent people that are alt clicking a tile to see its content from getting undesidered pop ups
|
||||
return
|
||||
// if(isturf(loc)) // to prevent people that are alt clicking a tile to see its content from getting undesidered pop ups
|
||||
// return
|
||||
if(is_cyborg || !user.canUseTopic(src, BE_CLOSE, TRUE, FALSE) || zero_amount()) //, !iscyborg(user)
|
||||
return
|
||||
//get amount from user
|
||||
|
||||
@@ -435,6 +435,20 @@
|
||||
STR.max_items = 6
|
||||
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/nugget))
|
||||
|
||||
/obj/item/storage/fancy/treat_box
|
||||
name = "treat box"
|
||||
desc = "A cardboard box used for holding dog treats."
|
||||
icon = 'icons/obj/food/containers.dmi'
|
||||
icon_state = "treatbox"
|
||||
icon_type = "treat"
|
||||
spawn_type = /obj/item/reagent_containers/food/snacks/dogtreat
|
||||
|
||||
/obj/item/storage/fancy/treat_box/ComponentInitialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 6
|
||||
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/dogtreat))
|
||||
|
||||
/obj/item/storage/fancy/cracker_pack
|
||||
name = "cracker pack"
|
||||
desc = "A pack of delicious crackers. Keep away from parrots!"
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
var/datum/effect_system/trail_follow/ion/ion_trail
|
||||
|
||||
/obj/item/tank/jetpack/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
ion_trail = new
|
||||
ion_trail.set_up(src)
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
return TRUE
|
||||
|
||||
/obj/item/tank/jetpack/suicide_act(mob/user)
|
||||
if (istype(user, /mob/living/carbon/human/))
|
||||
if (ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.forcesay("WHAT THE FUCK IS CARBON DIOXIDE?")
|
||||
H.visible_message("<span class='suicide'>[user] is suffocating [user.p_them()]self with [src]! It looks like [user.p_they()] didn't read what that jetpack says!</span>")
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
icon = 'icons/obj/closet.dmi'
|
||||
icon_state = "generic"
|
||||
density = TRUE
|
||||
max_integrity = 200
|
||||
integrity_failure = 0.25
|
||||
armor = list("melee" = 20, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 60)
|
||||
|
||||
var/icon_door = null
|
||||
var/icon_door_override = FALSE //override to have open overlay use icon different to its base's
|
||||
var/secure = FALSE //secure locker or not, also used if overriding a non-secure locker with a secure door overlay to add fancy lights
|
||||
@@ -12,9 +16,6 @@
|
||||
var/locked = FALSE
|
||||
var/large = TRUE
|
||||
var/wall_mounted = 0 //never solid (You can always pass over it)
|
||||
max_integrity = 200
|
||||
integrity_failure = 0.25
|
||||
armor = list("melee" = 20, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 60)
|
||||
var/breakout_time = 1200
|
||||
var/message_cooldown
|
||||
var/can_weld_shut = TRUE
|
||||
@@ -40,12 +41,12 @@
|
||||
var/should_populate_contents = TRUE
|
||||
|
||||
/obj/structure/closet/Initialize(mapload)
|
||||
if(mapload && !opened) // if closed, any item at the crate's loc is put in the contents
|
||||
addtimer(CALLBACK(src, .proc/take_contents), 0)
|
||||
. = ..()
|
||||
update_icon()
|
||||
if(should_populate_contents)
|
||||
PopulateContents()
|
||||
if(mapload && !opened) // if closed, any item at the crate's loc is put in the contents
|
||||
addtimer(CALLBACK(src, .proc/take_contents), 0)
|
||||
if(secure)
|
||||
lockerelectronics = new(src)
|
||||
lockerelectronics.accesses = req_access
|
||||
@@ -60,10 +61,10 @@
|
||||
|
||||
/obj/structure/closet/update_icon()
|
||||
. = ..()
|
||||
if(!opened)
|
||||
layer = OBJ_LAYER
|
||||
else
|
||||
layer = BELOW_OBJ_LAYER
|
||||
if(istype(src, /obj/structure/closet/supplypod))
|
||||
return
|
||||
|
||||
layer = opened ? BELOW_OBJ_LAYER : OBJ_LAYER
|
||||
|
||||
/obj/structure/closet/update_overlays()
|
||||
. = ..()
|
||||
@@ -71,61 +72,57 @@
|
||||
|
||||
/obj/structure/closet/proc/closet_update_overlays(list/new_overlays)
|
||||
. = new_overlays
|
||||
if(!opened)
|
||||
if(icon_door)
|
||||
. += "[icon_door]_door"
|
||||
else
|
||||
. += "[icon_state]_door"
|
||||
if(welded)
|
||||
. += "welded"
|
||||
if(!secure)
|
||||
return
|
||||
if(broken)
|
||||
. += "off"
|
||||
. += "sparking"
|
||||
else if(locked)
|
||||
. += "locked"
|
||||
else
|
||||
. += "unlocked"
|
||||
else
|
||||
if(icon_door_override)
|
||||
. += "[icon_door]_open"
|
||||
else
|
||||
. += "[icon_state]_open"
|
||||
if(opened)
|
||||
. += "[icon_door_override ? icon_door : icon_state]_open"
|
||||
return
|
||||
|
||||
. += "[icon_door || icon_state]_door"
|
||||
if(welded)
|
||||
. += icon_welded
|
||||
|
||||
if(!secure)
|
||||
return
|
||||
if(broken)
|
||||
. += "off"
|
||||
. += "sparking"
|
||||
//Overlay is similar enough for both that we can use the same mask for both
|
||||
SSvis_overlays.add_vis_overlay(src, icon, "locked", EMISSIVE_LAYER, EMISSIVE_PLANE, dir, alpha)
|
||||
. += locked ? "locked" : "unlocked"
|
||||
|
||||
|
||||
/obj/structure/closet/examine(mob/user)
|
||||
. = ..()
|
||||
if(welded)
|
||||
. += "<span class='notice'>It's <b>welded</b> shut.</span>"
|
||||
. += "<span class='notice'>It's welded shut.</span>"
|
||||
if(anchored)
|
||||
. += "<span class='notice'>It is <b>bolted</b> to the ground.</span>"
|
||||
if(opened)
|
||||
. += "<span class='notice'>The parts are <b>welded</b> together.</span>"
|
||||
else if(secure && !opened)
|
||||
. += "<span class='notice'>Alt-click to [locked ? "unlock" : "lock"].</span>"
|
||||
else if(broken)
|
||||
. += "<span class='notice'>The lock is <b>screwed</b> in.</span>"
|
||||
else if(secure)
|
||||
. += "<span class='notice'>Alt-click to [locked ? "unlock" : "lock"].</span>"
|
||||
if(isliving(user))
|
||||
var/mob/living/L = user
|
||||
if(HAS_TRAIT(L, TRAIT_SKITTISH))
|
||||
. += "<span class='notice'>Ctrl-Shift-click [src] to jump inside.</span>"
|
||||
|
||||
if(isobserver(user))
|
||||
. += "<span class='info'>It contains: [english_list(contents)].</span>"
|
||||
investigate_log("had its contents examined by [user] as a ghost.", INVESTIGATE_GHOST)
|
||||
|
||||
if(HAS_TRAIT(user, TRAIT_SKITTISH))
|
||||
. += "<span class='notice'>If you bump into [p_them()] while running, you will jump inside.</span>"
|
||||
|
||||
/obj/structure/closet/CanPass(atom/movable/mover, turf/target)
|
||||
if(wall_mounted)
|
||||
return TRUE
|
||||
return !density
|
||||
|
||||
/obj/structure/closet/proc/can_open(mob/living/user)
|
||||
/obj/structure/closet/proc/can_open(mob/living/user, force = FALSE)
|
||||
if(force)
|
||||
return TRUE
|
||||
if(welded || locked)
|
||||
return FALSE
|
||||
var/turf/T = get_turf(src)
|
||||
for(var/mob/living/L in T)
|
||||
if(L.move_resist >= MOVE_FORCE_VERY_STRONG || (horizontal && L.mob_size > MOB_SIZE_TINY && L.density))
|
||||
if(L.anchored || L.move_resist >= MOVE_FORCE_VERY_STRONG || (horizontal && L.mob_size > MOB_SIZE_TINY && L.density))
|
||||
if(user)
|
||||
to_chat(user, "<span class='danger'>There's something large on top of [src], preventing it from opening.</span>" )
|
||||
return FALSE
|
||||
@@ -137,44 +134,16 @@
|
||||
if(closet != src && !closet.wall_mounted)
|
||||
return FALSE
|
||||
for(var/mob/living/L in T)
|
||||
if(L.move_resist >= MOVE_FORCE_VERY_STRONG || horizontal && L.mob_size > MOB_SIZE_TINY && L.density)
|
||||
if(L.anchored || L.move_resist >= MOVE_FORCE_VERY_STRONG || (horizontal && L.mob_size > MOB_SIZE_TINY && L.density))
|
||||
if(user)
|
||||
to_chat(user, "<span class='danger'>There's something too large in [src], preventing it from closing.</span>")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/structure/closet/proc/can_lock(mob/living/user, var/check_access = TRUE) //set check_access to FALSE if you only need to check if a locker has a functional lock rather than access
|
||||
if(!secure)
|
||||
return FALSE
|
||||
if(broken)
|
||||
to_chat(user, "<span class='notice'>[src] is broken!</span>")
|
||||
return FALSE
|
||||
if(QDELETED(lockerelectronics) && !locked) //We want to be able to unlock it regardless of electronics, but only lockable with electronics
|
||||
to_chat(user, "<span class='notice'>[src] is missing locker electronics!</span>")
|
||||
return FALSE
|
||||
if(!check_access)
|
||||
return TRUE
|
||||
if(allowed(user))
|
||||
return TRUE
|
||||
to_chat(user, "<span class='notice'>Access denied.</span>")
|
||||
|
||||
/obj/structure/closet/proc/togglelock(mob/living/user)
|
||||
add_fingerprint(user)
|
||||
if(eigen_target)
|
||||
return
|
||||
if(opened)
|
||||
return
|
||||
if(!can_lock(user))
|
||||
return
|
||||
locked = !locked
|
||||
user.visible_message("<span class='notice'>[user] [locked ? null : "un"]locks [src].</span>",
|
||||
"<span class='notice'>You [locked ? null : "un"]lock [src].</span>")
|
||||
update_icon()
|
||||
|
||||
/obj/structure/closet/proc/dump_contents(var/override = TRUE) //Override is for not revealing the locker electronics when you open the locker, for example
|
||||
/obj/structure/closet/proc/dump_contents(override = TRUE) //Override is for not revealing the locker electronics when you open the locker, for example
|
||||
var/atom/L = drop_location()
|
||||
for(var/atom/movable/AM in src)
|
||||
if(AM == lockerelectronics && override)
|
||||
if(AM == lockerelectronics && override) // this stops the electronics from being dumped out? huh
|
||||
continue
|
||||
AM.forceMove(L)
|
||||
if(throwing) // you keep some momentum when getting out of a thrown closet
|
||||
@@ -187,18 +156,30 @@
|
||||
for(var/atom/movable/AM in L)
|
||||
if(AM != src && insert(AM) == -1) // limit reached
|
||||
break
|
||||
// for(var/i in reverseRange(L.GetAllContents()))
|
||||
// var/atom/movable/thing = i
|
||||
// SEND_SIGNAL(thing, COMSIG_TRY_STORAGE_HIDE_ALL)
|
||||
|
||||
/obj/structure/closet/proc/open(mob/living/user)
|
||||
if(opened || !can_open(user))
|
||||
/obj/structure/closet/proc/open(mob/living/user, force = FALSE)
|
||||
if(!can_open(user, force))
|
||||
return
|
||||
playsound(loc, open_sound, 15, 1, -3)
|
||||
if(opened)
|
||||
return
|
||||
welded = FALSE
|
||||
locked = FALSE // if you manage to open it, then its not welded/locked, hello?!
|
||||
playsound(loc, open_sound, 15, TRUE, -3)
|
||||
opened = TRUE
|
||||
if(!dense_when_open)
|
||||
density = FALSE
|
||||
climb_time *= 0.5 //it's faster to climb onto an open thing
|
||||
dump_contents()
|
||||
update_icon()
|
||||
return 1
|
||||
after_open(user, force)
|
||||
return TRUE
|
||||
|
||||
///Proc to override for effects after opening a door
|
||||
/obj/structure/closet/proc/after_open(mob/living/user, force = FALSE)
|
||||
return
|
||||
|
||||
/obj/structure/closet/proc/insert(atom/movable/AM)
|
||||
if(contents.len >= storage_capacity)
|
||||
@@ -208,19 +189,19 @@
|
||||
do_teleport(AM, get_turf(eigen_target), 0)
|
||||
if(eigen_target.opened == FALSE)
|
||||
eigen_target.bust_open()
|
||||
else
|
||||
AM.forceMove(src)
|
||||
return TRUE
|
||||
|
||||
AM.forceMove(src)
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
|
||||
|
||||
/obj/structure/closet/proc/insertion_allowed(atom/movable/AM)
|
||||
if(ismob(AM))
|
||||
if(!isliving(AM)) //let's not put ghosts or camera mobs inside closets...
|
||||
return FALSE
|
||||
var/mob/living/L = AM
|
||||
if(L.move_resist >= MOVE_FORCE_VERY_STRONG || L.buckled || L.incorporeal_move || L.has_buckled_mobs())
|
||||
if(L.anchored || L.move_resist >= MOVE_FORCE_VERY_STRONG || L.buckled || L.incorporeal_move || L.has_buckled_mobs())
|
||||
return FALSE
|
||||
if(L.mob_size > MOB_SIZE_TINY) // Tiny mobs are treated as items.
|
||||
if(horizontal && L.density)
|
||||
@@ -236,13 +217,13 @@
|
||||
else if(istype(AM, /obj/structure/closet))
|
||||
return FALSE
|
||||
|
||||
else if(istype(AM, /obj/effect))
|
||||
else if(iseffect(AM)) // todo: move to atom/movable
|
||||
return FALSE
|
||||
|
||||
else if(isobj(AM))
|
||||
if((!allow_dense && AM.density) || AM.anchored || AM.has_buckled_mobs())
|
||||
return FALSE
|
||||
if(isitem(AM) && !HAS_TRAIT(AM, TRAIT_NODROP))
|
||||
else if(isitem(AM) && !HAS_TRAIT(AM, TRAIT_NODROP))
|
||||
return TRUE
|
||||
else if(!allow_objects && !istype(AM, /obj/effect/dummy/chameleon))
|
||||
return FALSE
|
||||
@@ -255,25 +236,356 @@
|
||||
if(!opened || !can_close(user))
|
||||
return FALSE
|
||||
take_contents()
|
||||
playsound(loc, close_sound, 15, 1, -3)
|
||||
climb_time = initial(climb_time)
|
||||
playsound(loc, close_sound, 15, TRUE, -3)
|
||||
opened = FALSE
|
||||
density = TRUE
|
||||
update_icon()
|
||||
after_close(user)
|
||||
return TRUE
|
||||
|
||||
///Proc to override for effects after closing a door
|
||||
/obj/structure/closet/proc/after_close(mob/living/user)
|
||||
return
|
||||
|
||||
|
||||
/obj/structure/closet/proc/toggle(mob/living/user)
|
||||
if(opened)
|
||||
return close(user)
|
||||
else
|
||||
return open(user)
|
||||
|
||||
|
||||
/obj/structure/closet/deconstruct(disassembled = TRUE)
|
||||
if(ispath(material_drop) && material_drop_amount && !(flags_1 & NODECONSTRUCT_1))
|
||||
new material_drop(loc, material_drop_amount)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/closet/obj_break(damage_flag)
|
||||
if(!broken && !(flags_1 & NODECONSTRUCT_1))
|
||||
bust_open()
|
||||
|
||||
/obj/structure/closet/attackby(obj/item/W, mob/user, params)
|
||||
if(user in src)
|
||||
return
|
||||
if(src.tool_interact(W,user))
|
||||
return 1 // No afterattack
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/closet/proc/tool_interact(obj/item/W, mob/living/user)//returns TRUE if attackBy call shouldn't be continued (because tool was used/closet was of wrong type), FALSE if otherwise
|
||||
. = TRUE
|
||||
if(opened)
|
||||
if(istype(W, /obj/item/weldingtool))
|
||||
if(W.tool_behaviour == TOOL_WELDER)
|
||||
// eigen check
|
||||
if(eigen_teleport)
|
||||
to_chat(user, "<span class='notice'>The unstable nature of \the [src] makes it impossible to deconstruct!</span>")
|
||||
return
|
||||
|
||||
if(!W.tool_start_check(user, amount=0))
|
||||
return
|
||||
|
||||
to_chat(user, "<span class='notice'>You begin cutting \the [src] apart...</span>")
|
||||
if(W.use_tool(src, user, 40, volume=50))
|
||||
if(!opened)
|
||||
return
|
||||
user.visible_message("<span class='notice'>[user] slices apart \the [src].</span>",
|
||||
"<span class='notice'>You cut \the [src] apart with \the [W].</span>",
|
||||
"<span class='hear'>You hear welding.</span>")
|
||||
deconstruct(TRUE)
|
||||
return
|
||||
else // for example cardboard box is cut with wirecutters
|
||||
user.visible_message("<span class='notice'>[user] cut apart \the [src].</span>", \
|
||||
"<span class='notice'>You cut \the [src] apart with \the [W].</span>")
|
||||
deconstruct(TRUE)
|
||||
return
|
||||
if(user.transferItemToLoc(W, drop_location())) // so we put in unlit welder too
|
||||
return
|
||||
else if(W.tool_behaviour == TOOL_WELDER && can_weld_shut)
|
||||
// eigen check
|
||||
if(eigen_teleport)
|
||||
to_chat(user, "<span class='notice'>The unstable nature of \the [src] makes it impossible to deconstruct!</span>")
|
||||
return
|
||||
if(!W.tool_start_check(user, amount=0))
|
||||
return
|
||||
|
||||
to_chat(user, "<span class='notice'>You begin [welded ? "unwelding":"welding"] \the [src]...</span>")
|
||||
if(W.use_tool(src, user, 40, volume=50))
|
||||
if(opened)
|
||||
return
|
||||
welded = !welded
|
||||
after_weld(welded)
|
||||
user.visible_message("<span class='notice'>[user] [welded ? "welds shut" : "unwelded"] \the [src].</span>",
|
||||
"<span class='notice'>You [welded ? "weld" : "unwelded"] \the [src] with \the [W].</span>",
|
||||
"<span class='hear'>You hear welding.</span>")
|
||||
log_game("[key_name(user)] [welded ? "welded":"unwelded"] closet [src] with [W] at [AREACOORD(src)]")
|
||||
update_icon()
|
||||
else if(W.tool_behaviour == TOOL_WRENCH && anchorable)
|
||||
if(isinspace() && !anchored)
|
||||
return
|
||||
set_anchored(!anchored)
|
||||
W.play_tool_sound(src, 75)
|
||||
user.visible_message("<span class='notice'>[user] [anchored ? "anchored" : "unanchored"] \the [src] [anchored ? "to" : "from"] the ground.</span>", \
|
||||
"<span class='notice'>You [anchored ? "anchored" : "unanchored"] \the [src] [anchored ? "to" : "from"] the ground.</span>", \
|
||||
"<span class='hear'>You hear a ratchet.</span>")
|
||||
else if(user.a_intent != INTENT_HARM && !(W.item_flags & NOBLUDGEON))
|
||||
var/item_is_id = W.GetID()
|
||||
if(!item_is_id)
|
||||
return FALSE
|
||||
if(item_is_id || !toggle(user))
|
||||
togglelock(user)
|
||||
// cit addons
|
||||
else if(istype(W, /obj/item/electronics/airlock))
|
||||
handle_lock_addition(user, W)
|
||||
else if(W.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
handle_lock_removal(user, W)
|
||||
|
||||
else
|
||||
return FALSE
|
||||
|
||||
/obj/structure/closet/proc/after_weld(weld_state)
|
||||
return
|
||||
|
||||
/obj/structure/closet/MouseDrop_T(atom/movable/O, mob/living/user)
|
||||
if(!istype(O) || O.anchored || istype(O, /obj/screen))
|
||||
return
|
||||
if(!istype(user) || user.incapacitated() || user.lying)
|
||||
return
|
||||
if(!Adjacent(user) || !user.Adjacent(O))
|
||||
return
|
||||
if(user == O) //try to climb onto it
|
||||
return ..()
|
||||
if(!opened)
|
||||
return
|
||||
if(!isturf(O.loc))
|
||||
return
|
||||
|
||||
var/actuallyismob = 0
|
||||
if(isliving(O))
|
||||
actuallyismob = 1
|
||||
else if(!isitem(O))
|
||||
return
|
||||
var/turf/T = get_turf(src)
|
||||
var/list/targets = list(O, src)
|
||||
add_fingerprint(user)
|
||||
user.visible_message("<span class='warning'>[user] [actuallyismob ? "tries to ":""]stuff [O] into [src].</span>", \
|
||||
"<span class='warning'>You [actuallyismob ? "try to ":""]stuff [O] into [src].</span>", \
|
||||
"<span class='hear'>You hear clanging.</span>")
|
||||
if(actuallyismob)
|
||||
if(do_after_mob(user, targets, 40))
|
||||
user.visible_message("<span class='notice'>[user] stuffs [O] into [src].</span>", \
|
||||
"<span class='notice'>You stuff [O] into [src].</span>", \
|
||||
"<span class='hear'>You hear a loud metal bang.</span>")
|
||||
var/mob/living/L = O
|
||||
if(!issilicon(L))
|
||||
L.DefaultCombatKnockdown(40)
|
||||
if(istype(src, /obj/structure/closet/supplypod/extractionpod))
|
||||
O.forceMove(src)
|
||||
else
|
||||
O.forceMove(T)
|
||||
close()
|
||||
else
|
||||
O.forceMove(T)
|
||||
return 1
|
||||
|
||||
/obj/structure/closet/relaymove(mob/living/user, direction)
|
||||
if(user.stat || !isturf(loc))
|
||||
return
|
||||
if(locked)
|
||||
if(message_cooldown <= world.time)
|
||||
message_cooldown = world.time + 50
|
||||
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
|
||||
return
|
||||
container_resist(user)
|
||||
|
||||
/obj/structure/closet/on_attack_hand(mob/user)
|
||||
if(user.lying && get_dist(src, user) > 0)
|
||||
return
|
||||
|
||||
if(!toggle(user))
|
||||
togglelock(user)
|
||||
|
||||
|
||||
/obj/structure/closet/attack_paw(mob/user)
|
||||
return attack_hand(user)
|
||||
|
||||
/obj/structure/closet/attack_robot(mob/user)
|
||||
if(user.Adjacent(src))
|
||||
return attack_hand(user)
|
||||
|
||||
// tk grab then use on self
|
||||
/obj/structure/closet/attack_self_tk(mob/user)
|
||||
return attack_hand(user)
|
||||
|
||||
/obj/structure/closet/verb/verb_toggleopen()
|
||||
set src in view(1)
|
||||
set category = "Object"
|
||||
set name = "Toggle Open"
|
||||
|
||||
if(!usr.canUseTopic(src, BE_CLOSE) || !isturf(loc))
|
||||
return
|
||||
|
||||
if(iscarbon(usr) || issilicon(usr) || isdrone(usr))
|
||||
return toggle(usr)
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>This mob type can't use this verb.</span>")
|
||||
|
||||
// Objects that try to exit a locker by stepping were doing so successfully,
|
||||
// and due to an oversight in turf/Enter() were going through walls. That
|
||||
// should be independently resolved, but this is also an interesting twist.
|
||||
/obj/structure/closet/Exit(atom/movable/AM)
|
||||
open()
|
||||
if(AM.loc == src)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/structure/closet/container_resist(mob/living/user)
|
||||
if(opened)
|
||||
return
|
||||
if(ismovable(loc))
|
||||
// user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
// user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
var/atom/movable/AM = loc
|
||||
AM.relay_container_resist(user, src)
|
||||
return
|
||||
if(!welded && !locked)
|
||||
open()
|
||||
return
|
||||
|
||||
//okay, so the closet is either welded or locked... resist!!!
|
||||
// user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
// user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
user.visible_message("<span class='warning'>[src] begins to shake violently!</span>", \
|
||||
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(breakout_time)].)</span>", \
|
||||
"<span class='hear'>You hear banging from [src].</span>")
|
||||
if(do_after(user,(breakout_time), target = src, required_mobility_flags = MOBILITY_RESIST))
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src || opened || (!locked && !welded) )
|
||||
return
|
||||
//we check after a while whether there is a point of resisting anymore and whether the user is capable of resisting
|
||||
user.visible_message("<span class='danger'>[user] successfully broke out of [src]!</span>",
|
||||
"<span class='notice'>You successfully break out of [src]!</span>")
|
||||
bust_open()
|
||||
else
|
||||
if(user.loc == src) //so we don't get the message if we resisted multiple times and succeeded.
|
||||
to_chat(user, "<span class='warning'>You fail to break out of [src]!</span>")
|
||||
|
||||
/obj/structure/closet/proc/bust_open()
|
||||
welded = FALSE //applies to all lockers
|
||||
locked = FALSE //applies to critter crates and secure lockers only
|
||||
broken = TRUE //applies to secure lockers only
|
||||
open()
|
||||
|
||||
/obj/structure/closet/AltClick(mob/user)
|
||||
..()
|
||||
if(!user.canUseTopic(src, BE_CLOSE) || !isturf(loc))
|
||||
return
|
||||
if(opened || !secure)
|
||||
return
|
||||
else
|
||||
togglelock(user)
|
||||
|
||||
/obj/structure/closet/proc/togglelock(mob/living/user, silent)
|
||||
if(secure && !broken)
|
||||
if(allowed(user))
|
||||
if(iscarbon(user))
|
||||
add_fingerprint(user)
|
||||
locked = !locked
|
||||
user.visible_message("<span class='notice'>[user] [locked ? null : "un"]locks [src].</span>",
|
||||
"<span class='notice'>You [locked ? null : "un"]lock [src].</span>")
|
||||
update_icon()
|
||||
else if(!silent)
|
||||
to_chat(user, "<span class='alert'>Access Denied.</span>")
|
||||
else if(secure && broken)
|
||||
to_chat(user, "<span class='warning'>\The [src] is broken!</span>")
|
||||
|
||||
/obj/structure/closet/CtrlShiftClick(mob/living/user)
|
||||
if(!HAS_TRAIT(user, TRAIT_SKITTISH))
|
||||
return ..()
|
||||
if(!user.canUseTopic(src) || !isturf(user.loc) || !user.Adjacent(src) || !user.CanReach(src))
|
||||
return
|
||||
dive_into(user)
|
||||
|
||||
/obj/structure/closet/emag_act(mob/user)
|
||||
. = ..()
|
||||
if(!secure || broken)
|
||||
return
|
||||
if(user)
|
||||
user.visible_message("<span class='warning'>Sparks fly from [src]!</span>",
|
||||
"<span class='warning'>You scramble [src]'s lock, breaking it open!</span>",
|
||||
"<span class='hear'>You hear a faint electrical spark.</span>")
|
||||
playsound(src, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
|
||||
broken = TRUE
|
||||
locked = FALSE
|
||||
if(!QDELETED(lockerelectronics))
|
||||
QDEL_NULL(lockerelectronics)
|
||||
update_icon()
|
||||
|
||||
/obj/structure/closet/get_remote_view_fullscreens(mob/user)
|
||||
if(user.stat == DEAD || !(user.sight & (SEEOBJS|SEEMOBS)))
|
||||
user.overlay_fullscreen("remote_view", /obj/screen/fullscreen/impaired, 1)
|
||||
|
||||
/obj/structure/closet/emp_act(severity)
|
||||
. = ..()
|
||||
if(. & EMP_PROTECT_SELF)
|
||||
return
|
||||
if (!(. & EMP_PROTECT_CONTENTS))
|
||||
for(var/obj/O in src)
|
||||
O.emp_act(severity)
|
||||
if(secure && !broken && !(. & EMP_PROTECT_SELF))
|
||||
if(prob(50 / severity))
|
||||
locked = !locked
|
||||
update_icon()
|
||||
if(prob(20 / severity) && !opened)
|
||||
if(!locked)
|
||||
open()
|
||||
else
|
||||
req_access = list()
|
||||
req_access += pick(get_all_accesses())
|
||||
if(!QDELETED(lockerelectronics))
|
||||
lockerelectronics.accesses = req_access
|
||||
|
||||
/obj/structure/closet/contents_explosion(severity, target)
|
||||
for(var/atom/A in contents)
|
||||
A.ex_act(severity, target)
|
||||
CHECK_TICK
|
||||
|
||||
/obj/structure/closet/singularity_act()
|
||||
dump_contents()
|
||||
..()
|
||||
|
||||
/obj/structure/closet/AllowDrop()
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/structure/closet/return_temperature()
|
||||
return
|
||||
|
||||
/obj/structure/closet/proc/dive_into(mob/living/user)
|
||||
var/turf/T1 = get_turf(user)
|
||||
var/turf/T2 = get_turf(src)
|
||||
if(!opened)
|
||||
if(locked)
|
||||
togglelock(user, TRUE)
|
||||
if(!open(user))
|
||||
to_chat(user, "<span class='warning'>It won't budge!</span>")
|
||||
return
|
||||
step_towards(user, T2)
|
||||
T1 = get_turf(user)
|
||||
if(T1 == T2)
|
||||
user.set_resting(TRUE, TRUE)
|
||||
if(!close(user))
|
||||
to_chat(user, "<span class='warning'>You can't get [src] to close!</span>")
|
||||
user.set_resting(FALSE, TRUE)
|
||||
return
|
||||
user.set_resting(FALSE, TRUE)
|
||||
togglelock(user)
|
||||
T1.visible_message("<span class='warning'>[user] dives into [src]!</span>")
|
||||
|
||||
/obj/structure/closet/canReachInto(atom/user, atom/target, list/next, view_only, obj/item/tool)
|
||||
return (user in src)
|
||||
|
||||
/// cit specific ///
|
||||
|
||||
/obj/structure/closet/proc/handle_lock_addition(mob/user, obj/item/electronics/airlock/E)
|
||||
add_fingerprint(user)
|
||||
if(lock_in_use)
|
||||
@@ -336,294 +648,17 @@
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/structure/closet/deconstruct(disassembled = TRUE)
|
||||
if(ispath(material_drop) && material_drop_amount && !(flags_1 & NODECONSTRUCT_1))
|
||||
new material_drop(loc, material_drop_amount)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/closet/obj_break(damage_flag)
|
||||
if(!broken && !(flags_1 & NODECONSTRUCT_1))
|
||||
bust_open()
|
||||
|
||||
/obj/structure/closet/attackby(obj/item/W, mob/user, params)
|
||||
if(user in src)
|
||||
return
|
||||
if(src.tool_interact(W,user))
|
||||
return 1 // No afterattack
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/closet/proc/tool_interact(obj/item/W, mob/user)//returns TRUE if attackBy call shouldnt be continued (because tool was used/closet was of wrong type), FALSE if otherwise
|
||||
. = TRUE
|
||||
if(opened)
|
||||
if(istype(W, cutting_tool))
|
||||
var/welder = FALSE
|
||||
if(W.tool_behaviour == TOOL_WELDER)
|
||||
if(!W.tool_start_check(user, amount=0))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You begin [welder ? "slicing" : "deconstructing"] \the [src] apart...</span>")
|
||||
welder = TRUE
|
||||
if(W.use_tool(src, user, 40, volume=50))
|
||||
if(eigen_teleport)
|
||||
to_chat(user, "<span class='notice'>The unstable nature of \the [src] makes it impossible to [welder ? "slice" : "deconstruct"]!</span>")
|
||||
return
|
||||
if(!opened)
|
||||
return
|
||||
user.visible_message("<span class='notice'>[user] [welder ? "slice" : "deconstruct"]s apart \the [src].</span>",
|
||||
"<span class='notice'>You [welder ? "slice" : "deconstruct"] \the [src] apart with \the [W].</span>",
|
||||
"<span class='italics'>You hear [welder ? "welding" : "rustling of screws and metal"].</span>")
|
||||
deconstruct(TRUE)
|
||||
return
|
||||
if(user.a_intent != INTENT_HARM && user.transferItemToLoc(W, drop_location())) // so we put in unlit welder too
|
||||
return TRUE
|
||||
else if(istype(W, /obj/item/electronics/airlock))
|
||||
handle_lock_addition(user, W)
|
||||
else if(W.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
handle_lock_removal(user, W)
|
||||
else if(W.tool_behaviour == TOOL_WELDER && can_weld_shut)
|
||||
if(!W.tool_start_check(user, amount=0))
|
||||
return
|
||||
|
||||
to_chat(user, "<span class='notice'>You begin [welded ? "unwelding":"welding"] \the [src]...</span>")
|
||||
if(W.use_tool(src, user, 40, volume=50))
|
||||
if(eigen_teleport)
|
||||
to_chat(user, "<span class='notice'>The unstable nature of \the [src] makes it impossible to weld!</span>")
|
||||
return
|
||||
if(opened)
|
||||
return
|
||||
welded = !welded
|
||||
after_weld(welded)
|
||||
user.visible_message("<span class='notice'>[user] [welded ? "welds shut" : "unwelds"] \the [src].</span>",
|
||||
"<span class='notice'>You [welded ? "weld" : "unwelded"] \the [src] with \the [W].</span>",
|
||||
"<span class='italics'>You hear welding.</span>")
|
||||
update_icon()
|
||||
else if(W.tool_behaviour == TOOL_WRENCH && anchorable)
|
||||
if(isinspace() && !anchored)
|
||||
return
|
||||
setAnchored(!anchored)
|
||||
W.play_tool_sound(src, 75)
|
||||
user.visible_message("<span class='notice'>[user] [anchored ? "anchored" : "unanchored"] \the [src] [anchored ? "to" : "from"] the ground.</span>", \
|
||||
"<span class='notice'>You [anchored ? "anchored" : "unanchored"] \the [src] [anchored ? "to" : "from"] the ground.</span>", \
|
||||
"<span class='italics'>You hear a ratchet.</span>")
|
||||
else if(user.a_intent != INTENT_HARM && !(W.item_flags & NOBLUDGEON))
|
||||
if(W.GetID() || !toggle(user))
|
||||
togglelock(user)
|
||||
else
|
||||
/obj/structure/closet/proc/can_lock(mob/living/user, var/check_access = TRUE) //set check_access to FALSE if you only need to check if a locker has a functional lock rather than access
|
||||
if(!secure)
|
||||
return FALSE
|
||||
|
||||
/obj/structure/closet/proc/after_weld(weld_state)
|
||||
return
|
||||
|
||||
/obj/structure/closet/MouseDrop_T(atom/movable/O, mob/living/user)
|
||||
if(!istype(O) || O.anchored || istype(O, /obj/screen))
|
||||
return
|
||||
if(!istype(user) || user.incapacitated() || user.lying)
|
||||
return
|
||||
if(!Adjacent(user) || !user.Adjacent(O))
|
||||
return
|
||||
if(user == O) //try to climb onto it
|
||||
return ..()
|
||||
if(!opened)
|
||||
return
|
||||
if(!isturf(O.loc))
|
||||
return
|
||||
|
||||
var/actuallyismob = 0
|
||||
if(isliving(O))
|
||||
actuallyismob = 1
|
||||
else if(!isitem(O))
|
||||
return
|
||||
var/turf/T = get_turf(src)
|
||||
var/list/targets = list(O, src)
|
||||
add_fingerprint(user)
|
||||
user.visible_message("<span class='warning'>[user] [actuallyismob ? "tries to ":""]stuff [O] into [src].</span>", \
|
||||
"<span class='warning'>You [actuallyismob ? "try to ":""]stuff [O] into [src].</span>", \
|
||||
"<span class='italics'>You hear clanging.</span>")
|
||||
if(actuallyismob)
|
||||
if(do_after_mob(user, targets, 40))
|
||||
user.visible_message("<span class='notice'>[user] stuffs [O] into [src].</span>", \
|
||||
"<span class='notice'>You stuff [O] into [src].</span>", \
|
||||
"<span class='italics'>You hear a loud metal bang.</span>")
|
||||
var/mob/living/L = O
|
||||
if(!issilicon(L))
|
||||
L.DefaultCombatKnockdown(40)
|
||||
if(istype(src, /obj/structure/closet/supplypod/extractionpod))
|
||||
O.forceMove(src)
|
||||
else
|
||||
O.forceMove(T)
|
||||
close()
|
||||
else
|
||||
O.forceMove(T)
|
||||
return 1
|
||||
|
||||
/obj/structure/closet/relaymove(mob/user)
|
||||
if(user.stat || !isturf(loc) || !isliving(user))
|
||||
return
|
||||
if(locked || welded)
|
||||
if(message_cooldown <= world.time)
|
||||
message_cooldown = world.time + 50
|
||||
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
|
||||
return
|
||||
container_resist(user)
|
||||
|
||||
/obj/structure/closet/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(user.lying && get_dist(src, user) > 0)
|
||||
return
|
||||
|
||||
if(!toggle(user))
|
||||
togglelock(user)
|
||||
|
||||
/obj/structure/closet/attack_paw(mob/user)
|
||||
return attack_hand(user)
|
||||
|
||||
/obj/structure/closet/attack_robot(mob/user)
|
||||
if(user.Adjacent(src))
|
||||
return attack_hand(user)
|
||||
|
||||
// tk grab then use on self
|
||||
/obj/structure/closet/attack_self_tk(mob/user)
|
||||
return attack_hand(user)
|
||||
|
||||
/obj/structure/closet/verb/verb_toggleopen()
|
||||
set src in oview(1)
|
||||
set category = "Object"
|
||||
set name = "Toggle Open"
|
||||
|
||||
var/mob/living/L = usr
|
||||
if(!istype(L) || !CHECK_MOBILITY(L, MOBILITY_USE))
|
||||
if(broken)
|
||||
to_chat(user, "<span class='notice'>[src] is broken!</span>")
|
||||
return FALSE
|
||||
|
||||
if(iscarbon(usr) || issilicon(usr) || isdrone(usr))
|
||||
return attack_hand(usr)
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>This mob type can't use this verb.</span>")
|
||||
|
||||
// Objects that try to exit a locker by stepping were doing so successfully,
|
||||
// and due to an oversight in turf/Enter() were going through walls. That
|
||||
// should be independently resolved, but this is also an interesting twist.
|
||||
/obj/structure/closet/Exit(atom/movable/AM)
|
||||
open()
|
||||
if(AM.loc == src)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/structure/closet/container_resist(mob/living/user)
|
||||
if(opened)
|
||||
return
|
||||
if(ismovable(loc))
|
||||
var/atom/movable/AM = loc
|
||||
AM.relay_container_resist(user, src)
|
||||
return
|
||||
if(!welded && !locked)
|
||||
open()
|
||||
return
|
||||
|
||||
//okay, so the closet is either welded or locked... resist!!!
|
||||
user.visible_message("<span class='warning'>[src] begins to shake violently!</span>", \
|
||||
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(breakout_time)].)</span>", \
|
||||
"<span class='italics'>You hear banging from [src].</span>")
|
||||
if(do_after(user,(breakout_time), target = src, required_mobility_flags = MOBILITY_RESIST))
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src || opened || (!locked && !welded) )
|
||||
return
|
||||
//we check after a while whether there is a point of resisting anymore and whether the user is capable of resisting
|
||||
user.visible_message("<span class='danger'>[user] successfully broke out of [src]!</span>",
|
||||
"<span class='notice'>You successfully break out of [src]!</span>")
|
||||
bust_open()
|
||||
else
|
||||
if(user.loc == src) //so we don't get the message if we resisted multiple times and succeeded.
|
||||
to_chat(user, "<span class='warning'>You fail to break out of [src]!</span>")
|
||||
|
||||
/obj/structure/closet/AltClick(mob/user)
|
||||
. = ..()
|
||||
if(!user.canUseTopic(src, be_close=TRUE) || !isturf(loc))
|
||||
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
|
||||
if(QDELETED(lockerelectronics) && !locked) //We want to be able to unlock it regardless of electronics, but only lockable with electronics
|
||||
to_chat(user, "<span class='notice'>[src] is missing locker electronics!</span>")
|
||||
return FALSE
|
||||
if(!check_access)
|
||||
return TRUE
|
||||
togglelock(user)
|
||||
return TRUE
|
||||
|
||||
/obj/structure/closet/CtrlShiftClick(mob/living/user)
|
||||
if(!HAS_TRAIT(user, TRAIT_SKITTISH))
|
||||
return ..()
|
||||
if(!user.canUseTopic(src) || !isturf(user.loc) || !user.Adjacent(src) || !user.CanReach(src))
|
||||
return
|
||||
dive_into(user)
|
||||
|
||||
/obj/structure/closet/emag_act(mob/user)
|
||||
. = ..()
|
||||
if(!secure || broken)
|
||||
return
|
||||
user.visible_message("<span class='warning'>Sparks fly from [src]!</span>",
|
||||
"<span class='warning'>You scramble [src]'s lock, breaking it open!</span>",
|
||||
"<span class='italics'>You hear a faint electrical spark.</span>")
|
||||
playsound(src, "sparks", 50, 1)
|
||||
broken = TRUE
|
||||
locked = FALSE
|
||||
if(!QDELETED(lockerelectronics))
|
||||
QDEL_NULL(lockerelectronics)
|
||||
update_icon()
|
||||
|
||||
/obj/structure/closet/get_remote_view_fullscreens(mob/user)
|
||||
if(user.stat == DEAD || !(user.sight & (SEEOBJS|SEEMOBS)))
|
||||
user.overlay_fullscreen("remote_view", /obj/screen/fullscreen/impaired, 1)
|
||||
|
||||
/obj/structure/closet/emp_act(severity)
|
||||
. = ..()
|
||||
if(. & EMP_PROTECT_SELF)
|
||||
return
|
||||
if (!(. & EMP_PROTECT_CONTENTS))
|
||||
for(var/obj/O in src)
|
||||
O.emp_act(severity)
|
||||
if(!secure || broken)
|
||||
return ..()
|
||||
if(prob(severity/2))
|
||||
locked = !locked
|
||||
update_icon()
|
||||
if(prob(severity/5) && !opened)
|
||||
if(!locked)
|
||||
open()
|
||||
else
|
||||
req_access = list()
|
||||
req_access += pick(get_all_accesses())
|
||||
if(!QDELETED(lockerelectronics))
|
||||
lockerelectronics.accesses = req_access
|
||||
|
||||
/obj/structure/closet/contents_explosion(severity, target)
|
||||
for(var/atom/A in contents)
|
||||
A.ex_act(severity, target)
|
||||
CHECK_TICK
|
||||
|
||||
/obj/structure/closet/singularity_act()
|
||||
dump_contents()
|
||||
..()
|
||||
|
||||
/obj/structure/closet/AllowDrop()
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/structure/closet/return_temperature()
|
||||
return
|
||||
|
||||
/obj/structure/closet/proc/dive_into(mob/living/user)
|
||||
var/turf/T1 = get_turf(user)
|
||||
var/turf/T2 = get_turf(src)
|
||||
if(!opened)
|
||||
if(locked)
|
||||
togglelock(user, TRUE)
|
||||
if(!open(user))
|
||||
to_chat(user, "<span class='warning'>It won't budge!</span>")
|
||||
return
|
||||
step_towards(user, T2)
|
||||
T1 = get_turf(user)
|
||||
if(T1 == T2)
|
||||
user.set_resting(TRUE, TRUE)
|
||||
if(!close(user))
|
||||
to_chat(user, "<span class='warning'>You can't get [src] to close!</span>")
|
||||
user.set_resting(FALSE, TRUE)
|
||||
return
|
||||
user.set_resting(FALSE, TRUE)
|
||||
togglelock(user)
|
||||
T1.visible_message("<span class='warning'>[user] dives into [src]!</span>")
|
||||
|
||||
/obj/structure/closet/canReachInto(atom/user, atom/target, list/next, view_only, obj/item/tool)
|
||||
return (user in src)
|
||||
if(allowed(user))
|
||||
return TRUE
|
||||
to_chat(user, "<span class='notice'>Access denied.</span>")
|
||||
|
||||
@@ -17,10 +17,13 @@
|
||||
material_drop_amount = 5
|
||||
var/obj/item/paper/fluff/jobs/cargo/manifest/manifest
|
||||
|
||||
/obj/structure/closet/crate/New()
|
||||
..()
|
||||
/obj/structure/closet/crate/Initialize()
|
||||
. = ..()
|
||||
if(icon_state == "[initial(icon_state)]open")
|
||||
opened = TRUE
|
||||
// AddElement(/datum/element/climbable, climb_time = crate_climb_time * 0.5, climb_stun = 0)
|
||||
// else
|
||||
// AddElement(/datum/element/climbable, climb_time = crate_climb_time, climb_stun = 0)
|
||||
update_icon()
|
||||
|
||||
/obj/structure/closet/crate/CanPass(atom/movable/mover, turf/target)
|
||||
@@ -46,21 +49,16 @@
|
||||
if(manifest)
|
||||
tear_manifest(user)
|
||||
|
||||
/obj/structure/closet/crate/tool_interact(obj/item/W, mob/user)
|
||||
if(W.tool_behaviour == TOOL_WIRECUTTER && manifest)
|
||||
tear_manifest(user)
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/obj/structure/closet/crate/open(mob/living/user)
|
||||
/obj/structure/closet/crate/open(mob/living/user, force = FALSE)
|
||||
. = ..()
|
||||
if(. && manifest)
|
||||
to_chat(user, "<span class='notice'>The manifest is torn off [src].</span>")
|
||||
playsound(src, 'sound/items/poster_ripped.ogg', 75, 1)
|
||||
playsound(src, 'sound/items/poster_ripped.ogg', 75, TRUE)
|
||||
manifest.forceMove(get_turf(src))
|
||||
manifest = null
|
||||
update_icon()
|
||||
|
||||
// cit specific
|
||||
/obj/structure/closet/crate/handle_lock_addition()
|
||||
return
|
||||
|
||||
@@ -69,7 +67,7 @@
|
||||
|
||||
/obj/structure/closet/crate/proc/tear_manifest(mob/user)
|
||||
to_chat(user, "<span class='notice'>You tear the manifest off of [src].</span>")
|
||||
playsound(src, 'sound/items/poster_ripped.ogg', 75, 1)
|
||||
playsound(src, 'sound/items/poster_ripped.ogg', 75, TRUE)
|
||||
|
||||
manifest.forceMove(loc)
|
||||
if(ishuman(user))
|
||||
|
||||
@@ -80,16 +80,25 @@
|
||||
name = "private crate"
|
||||
desc = "A crate cover designed to only open for who purchased its contents."
|
||||
icon_state = "privatecrate"
|
||||
///Account of the person buying the crate if private purchasing.
|
||||
var/datum/bank_account/buyer_account
|
||||
///Department of the person buying the crate if buying via the NIRN app.
|
||||
var/datum/bank_account/department/department_account
|
||||
///Is the secure crate opened or closed?
|
||||
var/privacy_lock = TRUE
|
||||
///Is the crate being bought by a person, or a budget card?
|
||||
var/department_purchase = FALSE
|
||||
|
||||
/obj/structure/closet/crate/secure/owned/examine(mob/user)
|
||||
. = ..()
|
||||
to_chat(user, "<span class='notice'>It's locked with a privacy lock, and can only be unlocked by the buyer's ID.</span>")
|
||||
. += "<span class='notice'>It's locked with a privacy lock, and can only be unlocked by the buyer's ID.</span>"
|
||||
|
||||
/obj/structure/closet/crate/secure/owned/Initialize(mapload, datum/bank_account/_buyer_account)
|
||||
. = ..()
|
||||
buyer_account = _buyer_account
|
||||
if(istype(buyer_account, /datum/bank_account/department))
|
||||
department_purchase = TRUE
|
||||
department_account = buyer_account
|
||||
|
||||
/obj/structure/closet/crate/secure/owned/togglelock(mob/living/user, silent)
|
||||
if(privacy_lock)
|
||||
@@ -97,7 +106,7 @@
|
||||
var/obj/item/card/id/id_card = user.get_idcard(TRUE)
|
||||
if(id_card)
|
||||
if(id_card.registered_account)
|
||||
if(id_card.registered_account == buyer_account)
|
||||
if(id_card.registered_account == buyer_account || (department_purchase && (id_card.registered_account?.account_job?.paycheck_department) == (department_account.department_id)))
|
||||
if(iscarbon(user))
|
||||
add_fingerprint(user)
|
||||
locked = !locked
|
||||
|
||||
@@ -676,7 +676,6 @@
|
||||
ADD_TRAIT(new_spawn, TRAIT_SIXTHSENSE, GHOSTROLE_TRAIT)
|
||||
ADD_TRAIT(new_spawn, TRAIT_EXEMPT_HEALTH_EVENTS, GHOSTROLE_TRAIT)
|
||||
ADD_TRAIT(new_spawn, TRAIT_NO_MIDROUND_ANTAG, GHOSTROLE_TRAIT) //The mob can't be made into a random antag, they are still eligible for ghost roles popups.
|
||||
ADD_TRAIT(new_spawn, TRAIT_PACIFISM, GHOSTROLE_TRAIT)
|
||||
to_chat(new_spawn,"<span class='boldwarning'>Ghosting is free!</span>")
|
||||
var/datum/action/toggle_dead_chat_mob/D = new(new_spawn)
|
||||
D.Grant(new_spawn)
|
||||
|
||||
Reference in New Issue
Block a user