Merge remote-tracking branch 'origin/master' into perlin-genny

This commit is contained in:
LetterN
2021-03-24 21:55:47 +08:00
99 changed files with 103500 additions and 102174 deletions
-92
View File
@@ -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",
+160
View File
@@ -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")
+2 -2
View File
@@ -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
+14
View File
@@ -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!"
+2 -2
View File
@@ -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)