Merge remote-tracking branch 'upstream/master' into IPC-buffs

This commit is contained in:
SteelSlayer
2020-07-03 14:34:22 -05:00
1262 changed files with 117522 additions and 259381 deletions
-1
View File
@@ -141,7 +141,6 @@
return ..()
/obj/structure/alien/weeds/proc/Life()
set background = BACKGROUND_ENABLED
var/turf/U = get_turf(src)
if(istype(U, /turf/space))
@@ -12,6 +12,8 @@
var/opened = FALSE
var/welded = FALSE
var/locked = FALSE
var/large = TRUE
var/can_be_emaged = FALSE
var/wall_mounted = 0 //never solid (You can always pass over it)
var/lastbang
var/sound = 'sound/machines/click.ogg'
@@ -143,84 +145,21 @@
/obj/structure/closet/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/rcs) && !opened)
if(user in contents) //to prevent self-teleporting.
return
var/obj/item/rcs/E = W
if(E.rcell && (E.rcell.charge >= E.chargecost))
if(!is_level_reachable(z))
to_chat(user, "<span class='warning'>The rapid-crate-sender can't locate any telepads!</span>")
return
if(E.mode == 0)
if(!E.teleporting)
var/list/L = list()
var/list/areaindex = list()
for(var/obj/machinery/telepad_cargo/R in world)
if(R.stage == 0)
var/turf/T = get_turf(R)
var/tmpname = T.loc.name
if(areaindex[tmpname])
tmpname = "[tmpname] ([++areaindex[tmpname]])"
else
areaindex[tmpname] = 1
L[tmpname] = R
var/desc = input("Please select a telepad.", "RCS") in L
E.pad = L[desc]
if(!Adjacent(user))
to_chat(user, "<span class='notice'>Unable to teleport, too far from crate.</span>")
return
playsound(E.loc, E.usesound, 50, 1)
to_chat(user, "<span class='notice'>Teleporting [name]...</span>")
E.teleporting = 1
if(!do_after(user, 50 * E.toolspeed, target = src))
E.teleporting = 0
return
E.teleporting = 0
if(user in contents)
to_chat(user, "<span class='warning'>Error: User located in container--aborting for safety.</span>")
playsound(E.loc, 'sound/machines/buzz-sigh.ogg', 50, 1)
return
if(!(E.rcell && E.rcell.use(E.chargecost)))
to_chat(user, "<span class='notice'>Unable to teleport, insufficient charge.</span>")
return
do_sparks(5, 1, src)
do_teleport(src, E.pad, 0)
to_chat(user, "<span class='notice'>Teleport successful. [round(E.rcell.charge/E.chargecost)] charge\s left.</span>")
return
else
E.rand_x = rand(50,200)
E.rand_y = rand(50,200)
var/L = locate(E.rand_x, E.rand_y, 6)
if(!Adjacent(user))
to_chat(user, "<span class='notice'>Unable to teleport, too far from crate.</span>")
return
playsound(E.loc, E.usesound, 50, 1)
to_chat(user, "<span class='notice'>Teleporting [name]...</span>")
E.teleporting = 1
if(!do_after(user, 50, E.toolspeed, target = src))
E.teleporting = 0
return
E.teleporting = 0
if(user in contents)
to_chat(user, "<span class='warning'>Error: User located in container--aborting for safety.</span>")
playsound(E.loc, 'sound/machines/buzz-sigh.ogg', 50, 1)
return
if(!(E.rcell && E.rcell.use(E.chargecost)))
to_chat(user, "<span class='notice'>Unable to teleport, insufficient charge.</span>")
return
do_sparks(5, 1, src)
do_teleport(src, L)
to_chat(user, "<span class='notice'>Teleport successful. [round(E.rcell.charge/E.chargecost)] charge\s left.</span>")
return
else
to_chat(user, "<span class='warning'>Out of charges.</span>")
return
E.try_send_container(user, src)
return
if(opened)
if(istype(W, /obj/item/grab))
MouseDrop_T(W:affecting, user) //act like they were dragged onto the closet
if(istype(W,/obj/item/tk_grab))
var/obj/item/grab/G = W
if(large)
MouseDrop_T(G.affecting, user) //act like they were dragged onto the closet
else
to_chat(user, "<span class='notice'>[src] is too small to stuff [G.affecting] into!</span>")
if(istype(W, /obj/item/tk_grab))
return FALSE
if(user.a_intent != INTENT_HELP) // Stops you from putting your baton in the closet on accident
return
if(isrobot(user))
return
if(!user.drop_item()) //couldn't drop the item
@@ -228,13 +167,20 @@
return
if(W)
W.forceMove(loc)
return TRUE // It's resolved. No afterattack needed. Stops you from emagging lockers when putting in an emag
else if(can_be_emaged && (istype(W, /obj/item/card/emag) || istype(W, /obj/item/melee/energy/blade) && !broken))
emag_act(user)
else if(istype(W, /obj/item/stack/packageWrap))
return
else if(user.a_intent != INTENT_HARM)
attack_hand(user)
closed_item_click(user)
else
return ..()
// What happens when the closet is attacked by a random item not on harm mode
/obj/structure/closet/proc/closed_item_click(mob/user)
attack_hand(user)
/obj/structure/closet/welder_act(mob/user, obj/item/I)
. = TRUE
if(!opened && user.loc == src)
@@ -115,6 +115,8 @@
new /obj/item/clothing/shoes/black(src)
new /obj/item/clothing/glasses/sunglasses/big(src)
new /obj/item/clothing/glasses/sunglasses/big(src)
new /obj/item/clothing/accessory/lawyers_badge(src)
new /obj/item/clothing/accessory/lawyers_badge(src)
//Paramedic
@@ -54,36 +54,33 @@
new /obj/item/storage/backpack/satchel/withwallet( src )
new /obj/item/radio/headset( src )
/obj/structure/closet/secure_closet/personal/attackby(obj/item/W as obj, mob/user as mob, params)
if(src.opened)
if(istype(W, /obj/item/grab))
src.MouseDrop_T(W:affecting, user) //act like they were dragged onto the closet
user.drop_item()
if(W) W.forceMove(loc)
else if(istype(W, /obj/item/card/id))
if(src.broken)
to_chat(user, "<span class='warning'>It appears to be broken.</span>")
return
var/obj/item/card/id/I = W
if(!I || !I.registered_name) return
if(src == user.loc)
to_chat(user, "<span class='notice'>You can't reach the lock from inside.</span>")
else if(src.allowed(user) || !src.registered_name || (istype(I) && (src.registered_name == I.registered_name)))
//they can open all lockers, or nobody owns this, or they own this locker
src.locked = !( src.locked )
if(src.locked)
src.icon_state = src.icon_locked
else
src.icon_state = src.icon_closed
registered_name = null
desc = initial(desc)
if(!src.registered_name && src.locked)
src.registered_name = I.registered_name
src.desc = "Owned by [I.registered_name]."
else
to_chat(user, "<span class='warning'>Access Denied</span>")
else if((istype(W, /obj/item/card/emag) || istype(W, /obj/item/melee/energy/blade)) && !broken)
emag_act(user)
else
/obj/structure/closet/secure_closet/personal/attackby(obj/item/W, mob/user, params)
if(opened || !istype(W, /obj/item/card/id))
return ..()
if(broken)
to_chat(user, "<span class='warning'>It appears to be broken.</span>")
return
var/obj/item/card/id/I = W
if(!I || !I.registered_name)
return
if(src == user.loc)
to_chat(user, "<span class='notice'>You can't reach the lock from inside.</span>")
else if(allowed(user) || !registered_name || (istype(I) && (registered_name == I.registered_name)))
//they can open all lockers, or nobody owns this, or they own this locker
locked = !locked
if(locked)
icon_state = icon_locked
else
icon_state = icon_closed
registered_name = null
desc = initial(desc)
if(!registered_name && locked)
registered_name = I.registered_name
desc = "Owned by [I.registered_name]."
else
to_chat(user, "<span class='warning'>Access Denied</span>")
@@ -7,10 +7,10 @@
opened = 0
locked = 1
broken = 0
can_be_emaged = TRUE
max_integrity = 250
armor = list("melee" = 30, "bullet" = 50, "laser" = 50, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80)
damage_deflection = 20
var/large = 1
icon_closed = "secure"
var/icon_locked = "secure1"
icon_opened = "secureopen"
@@ -66,31 +66,8 @@
else
to_chat(user, "<span class='notice'>Access Denied</span>")
/obj/structure/closet/secure_closet/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/rcs))
return ..()
if(opened)
if(istype(W, /obj/item/grab))
if(large)
MouseDrop_T(W:affecting, user) //act like they were dragged onto the closet
else
to_chat(user, "<span class='notice'>The locker is too small to stuff [W:affecting] into!</span>")
if(isrobot(user))
return
if(!user.drop_item()) //couldn't drop the item
to_chat(user, "<span class='notice'>\The [W] is stuck to your hand, you cannot put it in \the [src]!</span>")
return
if(W)
W.forceMove(loc)
else if((istype(W, /obj/item/card/emag)||istype(W, /obj/item/melee/energy/blade)) && !broken)
emag_act(user)
else if(istype(W,/obj/item/stack/packageWrap) || istype(W,/obj/item/weldingtool))
return ..(W, user)
else if(user.a_intent != INTENT_HARM)
togglelock(user)
else
return ..()
/obj/structure/closet/secure_closet/closed_item_click(mob/user)
togglelock(user)
/obj/structure/closet/secure_closet/emag_act(mob/user)
if(!broken)
@@ -426,7 +426,7 @@
icon_off = "wall-lockeroff"
//too small to put a man in
large = 0
large = FALSE
/obj/structure/closet/secure_closet/wall/update_icon()
if(broken)
@@ -466,3 +466,4 @@
new /obj/item/gavelhammer(src)
new /obj/item/clothing/head/justice_wig(src)
new /obj/item/clothing/accessory/medal/legal(src)
new /obj/item/clothing/accessory/lawyers_badge(src)
@@ -19,7 +19,7 @@
L.buckled = 0
L.anchored = 0
L.forceMove(src)
L.disabilities += MUTE
L.mutations |= MUTE
max_integrity = L.health + 100 //stoning damaged mobs will result in easier to shatter statues
intialTox = L.getToxLoss()
intialFire = L.getFireLoss()
@@ -69,7 +69,7 @@
for(var/mob/living/M in src)
M.forceMove(loc)
M.disabilities -= MUTE
M.mutations -= MUTE
M.take_overall_damage((M.health - obj_integrity - 100),0) //any new damage the statue incurred is transfered to the mob
..()
@@ -79,111 +79,42 @@
return TRUE
/obj/structure/closet/crate/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/rcs) && !src.opened)
var/obj/item/rcs/E = W
if(E.rcell && (E.rcell.charge >= E.chargecost))
if(!is_level_reachable(src.z)) // This is inconsistent with the closet sending code
to_chat(user, "<span class='warning'>The rapid-crate-sender can't locate any telepads!</span>")
return
if(E.mode == 0)
if(!E.teleporting)
var/list/L = list()
var/list/areaindex = list()
for(var/obj/machinery/telepad_cargo/R in world)
if(R.stage == 0)
var/turf/T = get_turf(R)
var/tmpname = T.loc.name
if(areaindex[tmpname])
tmpname = "[tmpname] ([++areaindex[tmpname]])"
else
areaindex[tmpname] = 1
L[tmpname] = R
var/desc = input("Please select a telepad.", "RCS") in L
E.pad = L[desc]
if(!Adjacent(user))
to_chat(user, "<span class='notice'>Unable to teleport, too far from crate.</span>")
return
playsound(E.loc, E.usesound, 50, 1)
to_chat(user, "<span class='notice'>Teleporting [src.name]...</span>")
E.teleporting = TRUE
if(!do_after(user, 50 * E.toolspeed, target = src))
E.teleporting = 0
return
E.teleporting = 0
if(!(E.rcell && E.rcell.use(E.chargecost)))
to_chat(user, "<span class='notice'>Unable to teleport, insufficient charge.</span>")
return
do_sparks(5, 1, src)
do_teleport(src, E.pad, 0)
to_chat(user, "<span class='notice'>Teleport successful. [round(E.rcell.charge/E.chargecost)] charge\s left.</span>")
return
else
E.rand_x = rand(50,200)
E.rand_y = rand(50,200)
var/L = locate(E.rand_x, E.rand_y, 6)
if(!Adjacent(user))
to_chat(user, "<span class='notice'>Unable to teleport, too far from crate.</span>")
return
playsound(E.loc, E.usesound, 50, 1)
to_chat(user, "<span class='notice'>Teleporting [src.name]...</span>")
E.teleporting = TRUE
if(!do_after(user, 50 * E.toolspeed, target = src))
E.teleporting = FALSE
return
E.teleporting = 0
if(!(E.rcell && E.rcell.use(E.chargecost)))
to_chat(user, "<span class='notice'>Unable to teleport, insufficient charge.</span>")
return
do_sparks(5, 1, src)
do_teleport(src, L)
to_chat(user, "<span class='notice'>Teleport successful. [round(E.rcell.charge/E.chargecost)] charge\s left.</span>")
return
else
to_chat(user, "<span class='warning'>Out of charges.</span>")
return
if(opened)
if(isrobot(user))
return
if(!user.drop_item()) //couldn't drop the item
to_chat(user, "<span class='notice'>\The [W] is stuck to your hand, you cannot put it in \the [src]!</span>")
return
if(W)
W.forceMove(loc)
else if(istype(W, /obj/item/stack/packageWrap))
if(!opened && try_rig(W, user))
return
else if(istype(W, /obj/item/stack/cable_coil))
return ..()
/obj/structure/closet/crate/proc/try_rig(obj/item/W, mob/user)
if(istype(W, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = W
if(rigged)
to_chat(user, "<span class='notice'>[src] is already rigged!</span>")
return
return TRUE
if(C.use(15))
to_chat(user, "<span class='notice'>You rig [src].</span>")
rigged = TRUE
else
to_chat(user, "<span class='warning'>You need atleast 15 wires to rig [src]!</span>")
return
else if(istype(W, /obj/item/radio/electropack))
return TRUE
if(istype(W, /obj/item/radio/electropack))
if(rigged)
if(!user.drop_item())
to_chat(user, "<span class='warning'>[W] seems to be stuck to your hand!</span>")
return TRUE
to_chat(user, "<span class='notice'>You attach [W] to [src].</span>")
user.drop_item()
W.forceMove(src)
return
else if(istype(W, /obj/item/wirecutters))
if(rigged)
to_chat(user, "<span class='notice'>You cut away the wiring.</span>")
playsound(loc, W.usesound, 100, 1)
rigged = FALSE
return
else if(user.a_intent != INTENT_HARM)
attack_hand(user)
else
return ..()
return TRUE
/obj/structure/closet/singularity_act()
dump_contents()
..()
/obj/structure/closet/crate/wirecutter_act(mob/living/user, obj/item/I)
if(opened)
return
if(!rigged)
return
if(I.use_tool(src, user))
to_chat(user, "<span class='notice'>You cut away the wiring.</span>")
playsound(loc, I.usesound, 100, 1)
rigged = FALSE
return TRUE
/obj/structure/closet/crate/welder_act()
return
@@ -229,9 +160,10 @@
max_integrity = 500
armor = list("melee" = 30, "bullet" = 50, "laser" = 50, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80)
damage_deflection = 25
var/tamperproof = 0
broken = 0
locked = 1
var/tamperproof = FALSE
broken = FALSE
locked = TRUE
can_be_emaged = TRUE
/obj/structure/closet/crate/secure/update_icon()
..()
@@ -306,17 +238,8 @@
else
src.toggle(user)
/obj/structure/closet/crate/secure/attackby(obj/item/W, mob/user, params)
if(is_type_in_list(W, list(/obj/item/stack/packageWrap, /obj/item/stack/cable_coil, /obj/item/radio/electropack, /obj/item/wirecutters,/obj/item/rcs)))
return ..()
if((istype(W, /obj/item/card/emag) || istype(W, /obj/item/melee/energy/blade)))
emag_act(user)
return
if(!opened)
src.togglelock(user)
return
return ..()
/obj/structure/closet/crate/secure/closed_item_click(mob/user)
togglelock(user)
/obj/structure/closet/crate/secure/emag_act(mob/user)
if(locked)
+2 -2
View File
@@ -46,7 +46,7 @@
/obj/structure/curtain/screwdriver_act(mob/user, obj/item/I)
. = TRUE
if(!I.tool_start_check(user, 0))
if(!I.tool_start_check(src, user, 0))
return
if(anchored)
user.visible_message("<span class='warning'>[user] unscrews [src] from the floor.</span>", "<span class='notice'>You start to unscrew [src] from the floor...</span>", "You hear rustling noises.")
@@ -65,7 +65,7 @@
if(anchored)
return
. = TRUE
if(!I.tool_start_check(user, 0))
if(!I.tool_start_check(src, user, 0))
return
WIRECUTTER_ATTEMPT_DISMANTLE_MESSAGE
if(I.use_tool(src, user, 50, volume = I.tool_volume))
@@ -1,23 +0,0 @@
/obj/structure/decor/machinery/telecomms/processor
name = "Processor Unit"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "processor"
desc = "This machine is used to process large quantities of information."
/obj/structure/decor/machinery/telecomms/hub
name = "Telecommunication Hub"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "hub"
desc = "A mighty piece of hardware used to send/receive massive amounts of data."
/obj/structure/decor/machinery/telecomms/server
name = "Telecommunication Server"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "comm_server"
desc = "A machine used to store data and network statistics."
/obj/structure/decor/machinery/telecomms/relay
name = "Telecommunication Relay"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "relay"
desc = "A mighty piece of hardware used to send massive amounts of data far away."
+1 -1
View File
@@ -56,7 +56,7 @@
/obj/structure/dresser/crowbar_act(mob/user, obj/item/I)
. = TRUE
if(!I.tool_start_check(user, 0))
if(!I.tool_start_check(src, user, 0))
return
TOOL_ATTEMPT_DISMANTLE_MESSAGE
if(I.use_tool(src, user, 50, volume = I.tool_volume))
+5 -6
View File
@@ -17,11 +17,11 @@
var/opened = 0
var/material_drop = /obj/item/stack/sheet/metal
/obj/structure/extinguisher_cabinet/New(turf/loc, ndir = null)
/obj/structure/extinguisher_cabinet/New(turf/loc, direction = null)
..()
if(ndir)
pixel_x = (ndir & EAST|WEST) ? (ndir == EAST ? 28 : -28) : 0
pixel_y = (ndir & NORTH|SOUTH)? (ndir == WEST ? 28 : -28) : 0
if(direction)
setDir(direction)
set_pixel_offsets_from_dir(28, -28, 30, -30)
switch(extinguishertype)
if(NO_EXTINGUISHER)
return
@@ -165,9 +165,8 @@
else
icon_state = "extinguisher_empty"
/obj/structure/extinguisher_cabinet/empty/New(turf/loc, ndir = null)
/obj/structure/extinguisher_cabinet/empty
extinguishertype = NO_EXTINGUISHER
..()
#undef NO_EXTINGUISHER
#undef NORMAL_EXTINGUISHER
+1 -1
View File
@@ -374,7 +374,7 @@
/obj/structure/girder/CanAStarPass(ID, dir, caller)
. = !density
if(ismovableatom(caller))
if(ismovable(caller))
var/atom/movable/mover = caller
. = . || mover.checkpass(PASSGRILLE)
+1 -1
View File
@@ -111,7 +111,7 @@
/obj/structure/grille/CanAStarPass(ID, dir, caller)
. = !density
if(ismovableatom(caller))
if(ismovable(caller))
var/atom/movable/mover = caller
. = . || mover.checkpass(PASSGRILLE)
@@ -130,16 +130,18 @@
release_mob(M)
/obj/structure/kitchenspike/proc/release_mob(mob/living/M)
var/matrix/m180 = matrix(M.transform)
m180.Turn(180)
animate(M, transform = m180, time = 3)
M.pixel_y = M.get_standard_pixel_y_offset(180)
M.adjustBruteLoss(30)
src.visible_message(text("<span class='danger'>[M] falls free of [src]!</span>"))
unbuckle_mob(M, force = TRUE)
M.emote("scream")
M.AdjustWeakened(10)
/obj/structure/kitchenspike/post_unbuckle_mob(mob/living/M)
M.pixel_y = M.get_standard_pixel_y_offset(0)
var/matrix/m180 = matrix(M.transform)
m180.Turn(180)
animate(M, transform = m180, time = 3)
/obj/structure/kitchenspike/Destroy()
if(has_buckled_mobs())
for(var/mob/living/L in buckled_mobs)
+3 -1
View File
@@ -131,7 +131,7 @@
AC.ui_interact(user)
if("Voice")
var/voice_choice = input(user, "Perhaps...", "Voice effects") as null|anything in list("Comic Sans", "Wingdings", "Swedish", "Chav")
var/voice_choice = input(user, "Perhaps...", "Voice effects") as null|anything in list("Comic Sans", "Wingdings", "Swedish", "Chav", "Mute")
var/voice_mutation
switch(voice_choice)
if("Comic Sans")
@@ -142,6 +142,8 @@
voice_mutation = GLOB.swedeblock
if("Chav")
voice_mutation = GLOB.chavblock
if("Mute")
voice_mutation = GLOB.muteblock
if(voice_mutation)
if(H.dna.GetSEState(voice_mutation))
H.dna.SetSEState(voice_mutation, FALSE)
+1 -1
View File
@@ -232,7 +232,7 @@
/obj/structure/tray/m_tray/CanAStarPass(ID, dir, caller)
. = !density
if(ismovableatom(caller))
if(ismovable(caller))
var/atom/movable/mover = caller
. = . || mover.checkpass(PASSTABLE)
+3 -2
View File
@@ -246,7 +246,7 @@ GLOBAL_LIST_EMPTY(safes)
var/ticks = text2num(href_list["turnright"])
for(var/i = 1 to ticks)
dial = Wrap(dial - 1, 0, 100)
dial = WRAP(dial - 1, 0, 100)
var/invalid_turn = current_tumbler_index % 2 == 0 || current_tumbler_index > number_of_tumblers
if(invalid_turn) // The moment you turn the wrong way or go too far, the tumblers reset
@@ -274,7 +274,7 @@ GLOBAL_LIST_EMPTY(safes)
var/ticks = text2num(href_list["turnleft"])
for(var/i = 1 to ticks)
dial = Wrap(dial + 1, 0, 100)
dial = WRAP(dial + 1, 0, 100)
var/invalid_turn = current_tumbler_index % 2 != 0 || current_tumbler_index > number_of_tumblers
if(invalid_turn) // The moment you turn the wrong way or go too far, the tumblers reset
@@ -373,6 +373,7 @@ GLOBAL_LIST_EMPTY(safes)
info = "<div style='text-align:center;'><img src='ntlogo.png'><center><h3>Safe Codes</h3></center>"
/obj/item/paper/safe_code/Initialize(mapload)
..()
return INITIALIZE_HINT_LATELOAD
/obj/item/paper/safe_code/LateInitialize(mapload)
+4 -4
View File
@@ -128,7 +128,7 @@
/obj/structure/table/CanAStarPass(ID, dir, caller)
. = !density
if(ismovableatom(caller))
if(ismovable(caller))
var/atom/movable/mover = caller
. = . || mover.checkpass(PASSTABLE)
@@ -224,8 +224,8 @@
if(!click_params || !click_params["icon-x"] || !click_params["icon-y"])
return
//Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf)
I.pixel_x = Clamp(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2)
I.pixel_y = Clamp(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2)
I.pixel_x = clamp(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2)
I.pixel_y = clamp(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2)
item_placed(I)
else
return ..()
@@ -666,7 +666,7 @@
/obj/structure/rack/CanAStarPass(ID, dir, caller)
. = !density
if(ismovableatom(caller))
if(ismovable(caller))
var/atom/movable/mover = caller
. = . || mover.checkpass(PASSTABLE)
+86 -61
View File
@@ -1,3 +1,5 @@
#define MAX_TANK_STORAGE 10
/obj/structure/dispenser
name = "tank storage unit"
desc = "A simple yet bulky storage device for gas tanks. Has room for up to ten oxygen tanks, and ten plasma tanks."
@@ -5,29 +7,51 @@
icon_state = "dispenser"
density = 1
anchored = 1.0
var/oxygentanks = 10
var/plasmatanks = 10
var/list/oxytanks = list() //sorry for the similar var names
var/list/platanks = list()
var/starting_oxygen_tanks = MAX_TANK_STORAGE // The starting amount of oxygen tanks the dispenser gets when it's spawned
var/starting_plasma_tanks = MAX_TANK_STORAGE // Starting amount of plasma tanks
var/list/stored_oxygen_tanks = list() // List of currently stored oxygen tanks
var/list/stored_plasma_tanks = list() // And plasma tanks
/obj/structure/dispenser/oxygen
plasmatanks = 0
starting_plasma_tanks = 0
/obj/structure/dispenser/plasma
oxygentanks = 0
starting_oxygen_tanks = 0
/obj/structure/dispenser/New()
..()
initialize_tanks()
update_icon()
/obj/structure/dispenser/Destroy()
QDEL_LIST(stored_plasma_tanks)
QDEL_LIST(stored_oxygen_tanks)
return ..()
/obj/structure/dispenser/proc/initialize_tanks()
for(var/I in 1 to starting_plasma_tanks)
var/obj/item/tank/plasma/P = new(src)
stored_plasma_tanks.Add(P)
for(var/I in 1 to starting_oxygen_tanks)
var/obj/item/tank/oxygen/O = new(src)
stored_oxygen_tanks.Add(O)
/obj/structure/dispenser/update_icon()
overlays.Cut()
switch(oxygentanks)
if(1 to 3) overlays += "oxygen-[oxygentanks]"
if(4 to INFINITY) overlays += "oxygen-4"
switch(plasmatanks)
if(1 to 4) overlays += "plasma-[plasmatanks]"
if(5 to INFINITY) overlays += "plasma-5"
cut_overlays()
var/oxy_tank_amount = LAZYLEN(stored_oxygen_tanks)
switch(oxy_tank_amount)
if(1 to 3)
overlays += "oxygen-[oxy_tank_amount]"
if(4 to INFINITY)
overlays += "oxygen-4"
var/pla_tank_amount = LAZYLEN(stored_plasma_tanks)
switch(pla_tank_amount)
if(1 to 4)
overlays += "plasma-[pla_tank_amount]"
if(5 to INFINITY)
overlays += "plasma-5"
/obj/structure/dispenser/attack_hand(mob/user)
if(..())
@@ -38,7 +62,7 @@
/obj/structure/dispenser/attack_ghost(mob/user)
ui_interact(user)
/obj/structure/dispenser/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = GLOB.default_state)
/obj/structure/dispenser/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, master_ui = null, datum/topic_state/state = GLOB.default_state)
user.set_machine(src)
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
@@ -47,35 +71,19 @@
/obj/structure/dispenser/ui_data(user)
var/list/data = list()
data["o_tanks"] = oxygentanks
data["p_tanks"] = plasmatanks
data["o_tanks"] = LAZYLEN(stored_oxygen_tanks)
data["p_tanks"] = LAZYLEN(stored_plasma_tanks)
return data
/obj/structure/dispenser/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/tank/oxygen) || istype(I, /obj/item/tank/air) || istype(I, /obj/item/tank/anesthetic))
if(oxygentanks < 10)
user.drop_item()
I.forceMove(src)
oxytanks.Add(I)
oxygentanks++
update_icon()
to_chat(user, "<span class='notice'>You put [I] in [src].</span>")
else
to_chat(user, "<span class='notice'>[src] is full.</span>")
SSnanoui.update_uis(src)
try_insert_tank(user, stored_oxygen_tanks, I)
return
if(istype(I, /obj/item/tank/plasma))
if(plasmatanks < 10)
user.drop_item()
I.forceMove(src)
platanks.Add(I)
plasmatanks++
update_icon()
to_chat(user, "<span class='notice'>You put [I] in [src].</span>")
else
to_chat(user, "<span class='notice'>[src] is full.</span>")
SSnanoui.update_uis(src)
try_insert_tank(user, stored_plasma_tanks, I)
return
if(istype(I, /obj/item/wrench))
if(anchored)
to_chat(user, "<span class='notice'>You lean down and unwrench [src].</span>")
@@ -88,40 +96,55 @@
/obj/structure/dispenser/Topic(href, href_list)
if(..())
return 1
return TRUE
if(Adjacent(usr))
usr.set_machine(src)
// The oxygen tank button
if(href_list["oxygen"])
if(oxygentanks > 0)
var/obj/item/tank/oxygen/O
if(oxytanks.len == oxygentanks)
O = oxytanks[1]
oxytanks.Remove(O)
else
O = new /obj/item/tank/oxygen(loc)
O.loc = loc
to_chat(usr, "<span class='notice'>You take [O] out of [src].</span>")
oxygentanks--
update_icon()
try_remove_tank(usr, stored_oxygen_tanks)
// The plasma tank button
if(href_list["plasma"])
if(plasmatanks > 0)
var/obj/item/tank/plasma/P
if(platanks.len == plasmatanks)
P = platanks[1]
platanks.Remove(P)
else
P = new /obj/item/tank/plasma(loc)
P.loc = loc
to_chat(usr, "<span class='notice'>You take [P] out of [src].</span>")
plasmatanks--
update_icon()
try_remove_tank(usr, stored_plasma_tanks)
add_fingerprint(usr)
updateUsrDialog()
SSnanoui.update_uis(src)
SSnanoui.try_update_ui(usr, src)
else
SSnanoui.close_user_uis(usr,src)
return 1
return TRUE
/// Called when the user clicks on the oxygen or plasma tank UI buttons, and tries to withdraw a tank.
/obj/structure/dispenser/proc/try_remove_tank(mob/living/user, list/tank_list)
if(!LAZYLEN(tank_list))
return // There are no tanks left to withdraw.
var/obj/item/tank/T = tank_list[1]
tank_list.Remove(T)
if(!user.put_in_hands(T))
T.forceMove(loc) // If the user's hands are full, place it on the tile of the dispenser.
to_chat(user, "<span class='notice'>You take [T] out of [src].</span>")
update_icon()
/// Called when the user clicks on the dispenser with a tank. Tries to insert the tank into the dispenser, and updates the UI if successful.
/obj/structure/dispenser/proc/try_insert_tank(mob/living/user, list/tank_list, obj/item/tank/T)
if(LAZYLEN(tank_list) >= MAX_TANK_STORAGE)
to_chat(user, "<span class='warning'>[src] is full.</span>")
return
if(!user.drop_item()) // Antidrop check
to_chat(user, "<span class='warning'>[T] is stuck to your hand!</span>")
return
T.forceMove(src)
tank_list.Add(T)
update_icon()
to_chat(user, "<span class='notice'>You put [T] in [src].</span>")
SSnanoui.try_update_ui(user, src)
/obj/structure/tank_dispenser/deconstruct(disassembled = TRUE)
if(!(flags & NODECONSTRUCT))
@@ -130,3 +153,5 @@
I.forceMove(loc)
new /obj/item/stack/sheet/metal(loc, 2)
qdel(src)
#undef MAX_TANK_STORAGE
@@ -144,9 +144,7 @@
if(istype(mob, /mob) && mob.client)
// If the pod is not in a tube at all, you can get out at any time.
if(!(locate(/obj/structure/transit_tube) in loc))
mob.loc = loc
mob.client.Move(get_step(loc, direction), direction)
mob.reset_perspective(null)
mob.forceMove(loc)
//if(moving && istype(loc, /turf/space))
// Todo: If you get out of a moving pod in space, you should move as well.
@@ -158,9 +156,7 @@
if(!station.pod_moving)
if(direction == station.dir)
if(station.icon_state == "open")
mob.loc = loc
mob.client.Move(get_step(loc, direction), direction)
mob.reset_perspective(null)
mob.forceMove(loc)
else
station.open_animation()
+1 -69
View File
@@ -403,75 +403,7 @@
L.ExtinguishMob()
L.adjust_fire_stacks(-20) //Douse ourselves with water to avoid fire more easily
to_chat(L, "<span class='warning'>You've been drenched in water!</span>")
if(iscarbon(O))
var/mob/living/carbon/M = O
if(M.r_hand)
M.r_hand.clean_blood()
if(M.l_hand)
M.l_hand.clean_blood()
if(M.back)
if(M.back.clean_blood())
M.update_inv_back(0)
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/washgloves = 1
var/washshoes = 1
var/washmask = 1
var/washears = 1
var/washglasses = 1
if(H.wear_suit)
washgloves = !(H.wear_suit.flags_inv & HIDEGLOVES)
washshoes = !(H.wear_suit.flags_inv & HIDESHOES)
if(H.head)
washmask = !(H.head.flags_inv & HIDEMASK)
washglasses = !(H.head.flags_inv & HIDEEYES)
washears = !(H.head.flags_inv & HIDEEARS)
if(H.wear_mask)
if(washears)
washears = !(H.wear_mask.flags_inv & HIDEEARS)
if(washglasses)
washglasses = !(H.wear_mask.flags_inv & HIDEEYES)
if(H.head)
if(H.head.clean_blood())
H.update_inv_head(0,0)
if(H.wear_suit)
if(H.wear_suit.clean_blood())
H.update_inv_wear_suit(0,0)
else if(H.w_uniform)
if(H.w_uniform.clean_blood())
H.update_inv_w_uniform(0,0)
if(H.gloves && washgloves)
if(H.gloves.clean_blood())
H.update_inv_gloves(0,0)
if(H.shoes && washshoes)
if(H.shoes.clean_blood())
H.update_inv_shoes(0,0)
if(H.wear_mask && washmask)
if(H.wear_mask.clean_blood())
H.update_inv_wear_mask(0)
if(H.glasses && washglasses)
if(H.glasses.clean_blood())
H.update_inv_glasses(0)
if(H.l_ear && washears)
if(H.l_ear.clean_blood())
H.update_inv_ears(0)
if(H.r_ear && washears)
if(H.r_ear.clean_blood())
H.update_inv_ears(0)
if(H.belt)
if(H.belt.clean_blood())
H.update_inv_belt(0)
else
if(M.wear_mask) //if the mob is not human, it cleans the mask without asking for bitflags
if(M.wear_mask.clean_blood())
M.update_inv_wear_mask(0)
else
O.clean_blood()
L.clean_blood()
if(isturf(loc))
var/turf/tile = loc