diff --git a/code/controllers/subsystem/input.dm b/code/controllers/subsystem/input.dm
index f05c86e92d6..6f848ba04ce 100644
--- a/code/controllers/subsystem/input.dm
+++ b/code/controllers/subsystem/input.dm
@@ -104,15 +104,14 @@ SUBSYSTEM_DEF(input)
// Badmins just wanna have fun ♪
/datum/controller/subsystem/input/proc/refresh_client_macro_sets()
- var/list/clients = GLOB.clients
- for(var/i in 1 to clients.len)
- var/client/user = clients[i]
+ for(var/client/user as anything in GLOB.clients)
+ if(!user.initialized)
+ continue
user.set_macros()
user.update_movement_keys()
/datum/controller/subsystem/input/fire()
- var/list/clients = GLOB.clients // Let's sing the list cache song
- for(var/client/C as anything in clients)
+ for(var/client/C as anything in GLOB.clients)
if(!C.initialized)
continue
C.keyLoop()
diff --git a/code/controllers/subsystem/parallax.dm b/code/controllers/subsystem/parallax.dm
index fdf46539637..5c1b72de730 100644
--- a/code/controllers/subsystem/parallax.dm
+++ b/code/controllers/subsystem/parallax.dm
@@ -17,6 +17,7 @@ SUBSYSTEM_DEF(parallax)
while(length(currentrun))
var/client/processing_client = currentrun[currentrun.len]
currentrun.len--
+ // implicitly checks initialized
if (QDELETED(processing_client) || !processing_client.eye)
if (MC_TICK_CHECK)
return
@@ -28,6 +29,7 @@ SUBSYSTEM_DEF(parallax)
while(length(currentrun))
var/client/processing_client = currentrun[currentrun.len]
currentrun.len--
+ // implicitly checks initialized
if (QDELETED(processing_client) || !processing_client.eye)
if (MC_TICK_CHECK)
return
@@ -106,6 +108,8 @@ SUBSYSTEM_DEF(parallax)
*/
/datum/controller/subsystem/parallax/proc/update_clients_on_z(z)
for(var/client/C in GLOB.clients)
+ if(!C.initialized)
+ continue
if(C.mob.z == z)
C.parallax_holder?.Update(TRUE)
@@ -114,6 +118,8 @@ SUBSYSTEM_DEF(parallax)
*/
/datum/controller/subsystem/parallax/proc/reset_clients_on_z(z)
for(var/client/C in GLOB.clients)
+ if(!C.initialized)
+ continue
if(C.mob.z == z)
C.parallax_holder?.reset()
@@ -122,6 +128,8 @@ SUBSYSTEM_DEF(parallax)
*/
/datum/controller/subsystem/parallax/proc/update_z_vis_contents(z)
for(var/client/C in GLOB.clients)
+ if(!C.initialized)
+ continue
if(C.mob.z == z)
C.parallax_holder?.SyncVisContents()
@@ -130,6 +138,8 @@ SUBSYSTEM_DEF(parallax)
*/
/datum/controller/subsystem/parallax/proc/update_z_motion(z)
for(var/client/C in GLOB.clients)
+ if(!C.initialized)
+ continue
if(C.mob.z == z)
C.parallax_holder?.UpdateMotion()
diff --git a/code/controllers/subsystem/ping.dm b/code/controllers/subsystem/ping.dm
index d8b5ba01b9c..12ac61b1b41 100644
--- a/code/controllers/subsystem/ping.dm
+++ b/code/controllers/subsystem/ping.dm
@@ -27,6 +27,9 @@ SUBSYSTEM_DEF(ping)
var/client/client = currentrun[currentrun.len]
currentrun.len--
+ if(!client.initialized)
+ continue
+
if (client?.tgui_panel?.is_ready())
// Send a soft ping
client.tgui_panel.window.send_message("ping/soft", list(
diff --git a/code/controllers/subsystem/throwing.dm b/code/controllers/subsystem/throwing.dm
index 8f0bf69c6bc..7fa198c888e 100644
--- a/code/controllers/subsystem/throwing.dm
+++ b/code/controllers/subsystem/throwing.dm
@@ -35,6 +35,8 @@ SUBSYSTEM_DEF(throwing)
currentrun = null
+// todo: the landing stack kinda sucks ass and needs to be unit tested and rewritten
+
/datum/thrownthing
//! important stuff
/// thing we threw
@@ -350,6 +352,10 @@ SUBSYSTEM_DEF(throwing)
if(!impacted[target] && (target in get_turf(A)))
impact(target, TRUE)
+ // we got terminated already
+ if(finished)
+ return
+
// land
thrownthing._throw_finalize(A, src)
on_land?.InvokeAsync(A, src)
diff --git a/code/datums/components/turfs/transition_border.dm b/code/datums/components/turfs/transition_border.dm
index bf885a186a6..056b63042f3 100644
--- a/code/datums/components/turfs/transition_border.dm
+++ b/code/datums/components/turfs/transition_border.dm
@@ -54,25 +54,29 @@
STACK_TRACE("no z index?! deleting self.")
qdel(src)
return
- var/turf/target
- switch(dir)
- if(NORTH)
- target = locate(our_turf.x, 2, z_index)
- if(SOUTH)
- target = locate(our_turf.x, world.maxy - 1, z_index)
- if(EAST)
- target = locate(2, our_turf.y, z_index)
- if(WEST)
- target = locate(world.maxx - 1, our_turf.y, z_index)
- if(NORTHEAST)
- target = locate(2, 2, z_index)
- if(NORTHWEST)
- target = locate(world.maxx - 1, 2, z_index)
- if(SOUTHEAST)
- target = locate(2, world.maxy - 1, z_index)
- if(SOUTHWEST)
- target = locate(world.maxx - 1, world.maxy - 1, z_index)
- AM.locationTransitForceMove(target, recurse_levels = 2)
+ // todo: this is shit but we have to yield to prevent a Moved() before Moved()
+ spawn(0)
+ if(AM.loc != our_turf)
+ return
+ var/turf/target
+ switch(dir)
+ if(NORTH)
+ target = locate(our_turf.x, 2, z_index)
+ if(SOUTH)
+ target = locate(our_turf.x, world.maxy - 1, z_index)
+ if(EAST)
+ target = locate(2, our_turf.y, z_index)
+ if(WEST)
+ target = locate(world.maxx - 1, our_turf.y, z_index)
+ if(NORTHEAST)
+ target = locate(2, 2, z_index)
+ if(NORTHWEST)
+ target = locate(world.maxx - 1, 2, z_index)
+ if(SOUTHEAST)
+ target = locate(2, world.maxy - 1, z_index)
+ if(SOUTHWEST)
+ target = locate(world.maxx - 1, world.maxy - 1, z_index)
+ AM.locationTransitForceMove(target, recurse_levels = 2)
/datum/component/transition_border/proc/rebuild()
// reset first
diff --git a/code/datums/recipe/stack_recipe.dm b/code/datums/recipe/stack_recipe.dm
index 4d716d4e31e..581d427a31a 100644
--- a/code/datums/recipe/stack_recipe.dm
+++ b/code/datums/recipe/stack_recipe.dm
@@ -48,12 +48,17 @@
var/exclusitivity
/// max amount to allow crafting at once. null for 1 non stack, infinity stack
var/max_amount
+ /// we're a border object
+ var/on_border = FALSE
// todo: material constraints
/datum/stack_recipe/New()
if(ispath(result_type, /obj/item/stack))
result_is_stack = TRUE
+ var/atom/casted = result_type
+ on_border = !!(initial(casted.atom_flags) & ATOM_BORDER)
+
/**
* attepmt to craft
*
@@ -92,6 +97,9 @@
for(var/atom/movable/AM as anything in where)
if(AM == user)
continue
+ // border only collides with other border objs in the same dir
+ if((AM.atom_flags & ATOM_BORDER) && (!on_border || (AM.dir != use_dir)))
+ continue
if(AM.density)
if(!silent)
user.action_feedback(SPAN_WARNING("[AM] is in the way."))
diff --git a/code/game/atoms/movable/movement.dm b/code/game/atoms/movable/movement.dm
index 66574fc78b6..f12fb2c6a23 100644
--- a/code/game/atoms/movable/movement.dm
+++ b/code/game/atoms/movable/movement.dm
@@ -727,8 +727,7 @@
*/
/atom/movable/proc/on_changed_z_level(old_z, new_z)
SEND_SIGNAL(src, COMSIG_MOVABLE_Z_CHANGED, old_z, new_z)
- for(var/item in src) // Notify contents of Z-transition. This can be overridden IF we know the items contents do not care.
- var/atom/movable/AM = item
+ for(var/atom/movable/AM as anything in src) // Notify contents of Z-transition. This can be overridden IF we know the items contents do not care.
AM.on_changed_z_level(old_z, new_z)
//? Anchored
diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm
index 8fb8a5159b0..ff5617444f5 100644
--- a/code/game/dna/dna_modifier.dm
+++ b/code/game/dna/dna_modifier.dm
@@ -80,10 +80,10 @@
src.go_out()
for(var/obj/O in src)
if((!istype(O,/obj/item/reagent_containers)) && (!istype(O,/obj/item/circuitboard/clonescanner)) && (!istype(O,/obj/item/stock_parts)) && (!istype(O,/obj/item/stack/cable_coil)))
- O.loc = get_turf(src)//Ejects items that manage to get in there (exluding the components)
+ O.forceMove(get_turf(src))
if(!occupant)
for(var/mob/M in src)//Failsafe so you can get mobs out
- M.loc = get_turf(src)
+ M.forceMove(get_turf(src))
/**
*? Allows borgs to clone people without external assistance.
@@ -193,37 +193,6 @@
occupant = null
icon_state = "scanner_0"
-/obj/machinery/dna_scannernew/legacy_ex_act(severity)
- switch(severity)
- if(1.0)
- for(var/atom/movable/A as mob|obj in src)
- A.loc = src.loc
- legacy_ex_act(severity)
- //Foreach goto(35)
- //SN src = null
- qdel(src)
- return
- if(2.0)
- if (prob(50))
- for(var/atom/movable/A as mob|obj in src)
- A.loc = src.loc
- legacy_ex_act(severity)
- //Foreach goto(108)
- //SN src = null
- qdel(src)
- return
- if(3.0)
- if (prob(25))
- for(var/atom/movable/A as mob|obj in src)
- A.loc = src.loc
- legacy_ex_act(severity)
- //Foreach goto(181)
- //SN src = null
- qdel(src)
- return
- else
- return
-
/obj/machinery/computer/scan_consolenew
name = "DNA Modifier Access Console"
desc = "Scan DNA."
@@ -659,7 +628,7 @@
if(href_list["ejectBeaker"])
if(connected.beaker)
var/obj/item/reagent_containers/glass/B = connected.beaker
- B.loc = connected.loc
+ B.forceMove(connected.loc)
connected.beaker = null
return 1
@@ -684,7 +653,7 @@
if (bufferOption == "ejectDisk")
if (!src.disk)
return
- src.disk.loc = get_turf(src)
+ src.disk.forceMove(get_turf(src))
src.disk = null
return 1
@@ -805,7 +774,7 @@
I.buf = buf
waiting_for_user_input=0
if(success)
- I.loc = src.loc
+ I.forceMove(loc)
I.name += " ([buf.name])"
//src.temphtml = "Injector created."
src.injector_ready = 0
diff --git a/code/game/dna/genes/monkey.dm b/code/game/dna/genes/monkey.dm
index 22259914056..24bfde902bb 100644
--- a/code/game/dna/genes/monkey.dm
+++ b/code/game/dna/genes/monkey.dm
@@ -16,7 +16,7 @@
var/list/implants = list() //Try to preserve implants.
for(var/obj/item/implant/W in H)
implants += W
- W.loc = null
+ W.moveToNullspace()
if(!connected)
for(var/obj/item/W in (H.contents-implants))
@@ -55,14 +55,14 @@
for(var/obj/T in (M.contents-implants))
qdel(T)
- O.loc = M.loc
+ O.forceMove(M.loc)
if(M.mind)
M.mind.transfer(O) //transfer our mind to the cute little monkey
if (connected) //inside dna thing
var/obj/machinery/dna_scannernew/C = connected
- O.loc = C
+ O.forceMove(C)
C.occupant = O
connected = null
O.real_name = "monkey ([copytext(md5(M.real_name), 2, 6)])"
@@ -72,7 +72,7 @@
O.set_stat(M.stat)
O.a_intent = INTENT_HARM
for (var/obj/item/implant/I in implants)
- I.loc = O
+ I.forceMove(O)
I.implanted = O
// O.update_icon = 1 //queue a full icon update at next life() call
qdel(M)
@@ -87,7 +87,7 @@
var/list/implants = list() //Still preserving implants
for(var/obj/item/implant/W in Mo)
implants += W
- W.loc = null
+ W.moveToNullspace()
if(!connected)
for(var/obj/item/W in (Mo.contents-implants))
Mo.drop_from_inventory(W)
@@ -125,15 +125,14 @@
// for(var/obj/T in M)
// qdel(T)
-
- O.loc = M.loc
+ O.forceMove(M.loc)
if(M.mind)
M.mind.transfer(O) //transfer our mind to the human
if (connected) //inside dna thing
var/obj/machinery/dna_scannernew/C = connected
- O.loc = C
+ O.forceMove(C)
C.occupant = O
connected = null
@@ -156,7 +155,7 @@
O.adjustOxyLoss(M.getOxyLoss())
O.set_stat(M.stat)
for (var/obj/item/implant/I in implants)
- I.loc = O
+ I.forceMove(O)
I.implanted = O
// O.update_icon = 1 //queue a full icon update at next life() call
qdel(M)
diff --git a/code/game/gamemodes/changeling/powers/lesser_form.dm b/code/game/gamemodes/changeling/powers/lesser_form.dm
index cf301b6a33f..211f4c77087 100644
--- a/code/game/gamemodes/changeling/powers/lesser_form.dm
+++ b/code/game/gamemodes/changeling/powers/lesser_form.dm
@@ -92,7 +92,7 @@
for(var/obj/T in C)
qdel(T)
- O.loc = C.loc
+ O.forceMove(C.loc)
O.UpdateAppearance()
domutcheck(O, null)
@@ -102,7 +102,7 @@
O.adjustFireLoss(C.getFireLoss())
O.set_stat(C.stat)
for (var/obj/item/implant/I in implants)
- I.loc = O
+ I.forceMove(O)
I.implanted = O
C.mind.transfer(O)
diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm
index 826773e9c3a..785f0467351 100644
--- a/code/game/mecha/working/ripley.dm
+++ b/code/game/mecha/working/ripley.dm
@@ -29,10 +29,7 @@
/obj/mecha/working/ripley/Destroy()
for(var/atom/movable/A in src.cargo)
- A.loc = loc
- var/turf/T = loc
- if(istype(T))
- T.Entered(A)
+ A.forceMove(loc)
step_rand(A)
cargo.Cut()
..()
diff --git a/code/game/mecha/working/working.dm b/code/game/mecha/working/working.dm
index 51d9759c1f2..1313166d56a 100644
--- a/code/game/mecha/working/working.dm
+++ b/code/game/mecha/working/working.dm
@@ -12,52 +12,5 @@
if(isPlayerLevel(T.z))
new /obj/item/mecha_parts/mecha_tracking(src)
-/* This stuff has been generalized!
-/obj/mecha/working/Destroy()
- for(var/mob/M in src)
- if(M==src.occupant)
- continue
- M.loc = get_turf(src)
- M.loc.Entered(M)
- step_rand(M)
- for(var/atom/movable/A in src.cargo)
- A.loc = get_turf(src)
- var/turf/T = get_turf(A)
- if(T)
- T.Entered(A)
- step_rand(A)
- ..()
- return
-
-/obj/mecha/working/Topic(href, href_list)
- ..()
- if(href_list["drop_from_cargo"])
- var/obj/O = locate(href_list["drop_from_cargo"])
- if(O && O in src.cargo)
- src.occupant_message("You unload [O].")
- O.loc = get_turf(src)
- src.cargo -= O
- var/turf/T = get_turf(O)
- if(T)
- T.Entered(O)
- src.log_message("Unloaded [O]. Cargo compartment capacity: [cargo_capacity - src.cargo.len]")
- return
-
-/obj/mecha/working/Exit(atom/movable/O)
- if(O in cargo)
- return 0
- return ..()
-
-/obj/mecha/working/get_stats_part()
- var/output = ..()
- output += "Cargo Compartment Contents:
"
- if(src.cargo.len)
- for(var/obj/O in src.cargo)
- output += "
Unload : [O]
"
- else
- output += "Nothing"
- output += "
"
- return output
-*/
/obj/mecha/working/range_action(atom/target as obj|mob|turf)
return
diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm
index ef76cea4810..557cd497a54 100644
--- a/code/game/objects/effects/spiders.dm
+++ b/code/game/objects/effects/spiders.dm
@@ -152,7 +152,7 @@
// todo: remove this shit
if(QDELETED(src))
return
- loc = exit_vent
+ forceMove(exit_vent)
var/travel_time = round(get_dist(loc, exit_vent.loc) / 2)
spawn(travel_time)
// todo: remove this shit
@@ -160,7 +160,7 @@
return
if(!exit_vent || exit_vent.welded)
- loc = entry_vent
+ forceMove(entry_vent)
entry_vent = null
return
@@ -172,10 +172,10 @@
return
if(!exit_vent || exit_vent.welded)
- loc = entry_vent
+ forceMove(entry_vent)
entry_vent = null
return
- loc = exit_vent.loc
+ forceMove(exit_vent)
entry_vent = null
var/area/new_area = get_area(loc)
if(new_area)
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index eefe23344e4..90a3a83f51c 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -243,7 +243,6 @@
var/turf/T = src.loc
src.loc = null
-
src.loc = T
/// See inventory_sizes.dm for the defines.
diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm
index e643bfba9b5..fcf428d6f48 100644
--- a/code/game/objects/items/devices/PDA/PDA.dm
+++ b/code/game/objects/items/devices/PDA/PDA.dm
@@ -970,7 +970,7 @@ GLOBAL_LIST_EMPTY(PDAs)
if("2") // Eject pAI device
var/turf/T = get_turf_or_move(src.loc)
if(T)
- pai.loc = T
+ pai.forceMove(T)
pai = null
else
@@ -1084,7 +1084,7 @@ GLOBAL_LIST_EMPTY(PDAs)
M.put_in_hands(O)
to_chat(usr, "You remove \the [O] from \the [src].")
return
- O.loc = get_turf(src)
+ O.forceMove(get_turf(src))
else
to_chat(usr, "This PDA does not have a pen in it.")
diff --git a/code/game/objects/items/devices/chameleonproj.dm b/code/game/objects/items/devices/chameleonproj.dm
index 30783649623..cb25a423658 100644
--- a/code/game/objects/items/devices/chameleonproj.dm
+++ b/code/game/objects/items/devices/chameleonproj.dm
@@ -101,7 +101,7 @@
icon_state = new_iconstate
overlays = new_overlays
setDir(O.dir)
- M.loc = src
+ M.forceMove(src)
master = C
master.active_dummy = src
diff --git a/code/game/objects/items/devices/gps.dm b/code/game/objects/items/devices/gps.dm
index d9b81f39bcc..d3e3cf61ede 100644
--- a/code/game/objects/items/devices/gps.dm
+++ b/code/game/objects/items/devices/gps.dm
@@ -412,7 +412,7 @@
if(!tag_as)
return FALSE
var/turf/T = get_turf(src)
- add_waypoint(tag_as, text2num(params["x"]) || T.x, text2num(params["y"]) || T.y, params["level_id"] || SSmapping.level_id(T.z))
+ add_waypoint(tag_as, text2num(params["x"]) || T.x, text2num(params["y"]) || T.y, params["level_id"] || SSmapping.fluff_level_id(T.z))
return FALSE // add waypoint pushes data already
if("del_waypoint")
//* RAW LOCATE IN HREF WARNING: RECEIVING PROC WILL SANITY CHECK.
diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm
index 998675524ad..66aeb301562 100755
--- a/code/game/objects/items/devices/radio/headset.dm
+++ b/code/game/objects/items/devices/radio/headset.dm
@@ -378,7 +378,7 @@
if(keyslot1)
var/turf/T = get_turf(user)
if(T)
- keyslot1.loc = T
+ keyslot1.forceMove(T)
keyslot1 = null
@@ -386,7 +386,7 @@
if(keyslot2)
var/turf/T = get_turf(user)
if(T)
- keyslot2.loc = T
+ keyslot2.forceMove(T)
keyslot2 = null
recalculateChannels()
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index fb10a14016f..6c688e783aa 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -688,7 +688,7 @@ GLOBAL_DATUM_INIT(virtual_announcer_ai, /mob/living/silicon/ai/announcer, new(nu
if(keyslot)
var/turf/T = get_turf(user)
if(T)
- keyslot.loc = T
+ keyslot.forceMove(T)
keyslot = null
recalculateChannels()
diff --git a/code/game/objects/items/glassjar.dm b/code/game/objects/items/glassjar.dm
index 36453b49ad9..ac04f62cefb 100644
--- a/code/game/objects/items/glassjar.dm
+++ b/code/game/objects/items/glassjar.dm
@@ -48,21 +48,21 @@
switch(contains)
if(1)
for(var/obj/O in src)
- O.loc = user.loc
+ O.forceMove(user.loc)
to_chat(user, "You take money out of \the [src].")
contains = 0
update_icon()
return
if(2)
for(var/mob/M in src)
- M.loc = user.loc
+ M.forceMove(user.loc)
user.visible_message("[user] releases [M] from \the [src].", "You release [M] from \the [src].")
contains = 0
update_icon()
return
if(3)
for(var/obj/effect/spider/spiderling/S in src)
- S.loc = user.loc
+ S.forceMove(user.loc)
user.visible_message("[user] releases [S] from \the [src].", "You release [S] from \the [src].")
START_PROCESSING(SSobj, S) // They can grow after being let out though
contains = 0
diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm
index ef7c24a6407..ee5ea494540 100644
--- a/code/game/objects/items/robot/robot_parts.dm
+++ b/code/game/objects/items/robot/robot_parts.dm
@@ -211,8 +211,8 @@
O.add_language(L.name)
O.job = "Cyborg"
O.cell = chest.cell
- O.cell.loc = O
- W.loc = O//Should fix cybros run time erroring when blown up. It got deleted before, along with the frame.
+ O.cell.forceMove(O)
+ W.forceMove(O) //Should fix cybros run time erroring when blown up. It got deleted before, along with the frame.
// Since we "magically" installed a cell, we also have to update the correct component.
if(O.cell)
diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm
index ce0c3912d99..367b4c79bcb 100644
--- a/code/game/objects/items/tools/weldingtool.dm
+++ b/code/game/objects/items/tools/weldingtool.dm
@@ -157,7 +157,7 @@
//Returns the amount of fuel in the welder
/obj/item/weldingtool/proc/get_fuel()
- return reagents.get_reagent_amount("fuel")
+ return reagents.get_reagent_amount(/datum/reagent/fuel)
/obj/item/weldingtool/proc/get_max_fuel()
return max_fuel
diff --git a/code/game/objects/items/weapons/hydroponics.dm b/code/game/objects/items/weapons/hydroponics.dm
deleted file mode 100644
index 0ce4b552f41..00000000000
--- a/code/game/objects/items/weapons/hydroponics.dm
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * SeedBag
- */
-//uncomment when this is updated to match storage update
-/*
-/obj/item/seedbag
- icon = 'icons/obj/hydroponics_machines.dmi'
- icon_state = "seedbag"
- name = "Seed Bag"
- desc = "A small satchel made for organizing seeds."
- var/mode = 1; //0 = pick one at a time, 1 = pick all on tile
- var/capacity = 500; //the number of seeds it can carry.
- slot_flags = SLOT_BELT
- w_class = ITEMSIZE_TINY
- var/list/item_quants = list()
-
-/obj/item/seedbag/attack_self(mob/user)
- . = ..()
- if(.)
- return
- user.machine = src
- interact(user)
-
-/obj/item/seedbag/verb/toggle_mode()
- set name = "Switch Bagging Method"
- set category = "Object"
-
- mode = !mode
- switch (mode)
- if(1)
- to_chat(usr, "The bag now picks up all seeds in a tile at once.")
- if(0)
- to_chat(usr, "The bag now picks up one seed pouch at a time.")
-
-/obj/item/seeds/attackby(var/obj/item/O as obj, var/mob/user as mob)
- ..()
- if (istype(O, /obj/item/seedbag))
- var/obj/item/seedbag/S = O
- if (S.mode == 1)
- for (var/obj/item/seeds/G in locate(src.x,src.y,src.z))
- if (S.contents.len < S.capacity)
- S.contents += G;
- if(S.item_quants[G.name])
- S.item_quants[G.name]++
- else
- S.item_quants[G.name] = 1
- else
- to_chat(user, "The seed bag is full.")
- S.updateUsrDialog()
- return
- to_chat(user, "You pick up all the seeds.")
- else
- if (S.contents.len < S.capacity)
- S.contents += src;
- if(S.item_quants[name])
- S.item_quants[name]++
- else
- S.item_quants[name] = 1
- else
- to_chat(user, "The seed bag is full.")
- S.updateUsrDialog()
- return
-
-/obj/item/seedbag/interact(mob/user as mob)
-
- var/dat = "Select an item:
"
-
- if (contents.len == 0)
- dat += "No seeds loaded!"
- else
- for (var/O in item_quants)
- if(item_quants[O] > 0)
- var/N = item_quants[O]
- dat += "[capitalize(O)]:"
- dat += " [N] "
- dat += "Vend"
- dat += "
"
-
- dat += "
Unload All"
- dat += ""
- user << browse("Seedbag Supplies[dat]", "window=seedbag")
- onclose(user, "seedbag")
- return
-
-/obj/item/seedbag/Topic(href, href_list)
- if(..())
- return
-
- usr.machine = src
- if ( href_list["vend"] )
- var/N = href_list["vend"]
-
- if(item_quants[N] <= 0) // Sanity check, there are probably ways to press the button when it shouldn't be possible.
- return
-
- item_quants[N] -= 1
- for(var/obj/O in contents)
- if(O.name == N)
- O.loc = get_turf(src)
- usr.put_in_hands(O)
- break
-
- else if ( href_list["unload"] )
- item_quants.Cut()
- for(var/obj/O in contents )
- O.loc = get_turf(src)
-
- src.updateUsrDialog()
- return
-
-/obj/item/seedbag/updateUsrDialog()
- var/list/nearby = range(1, src)
- for(var/mob/M in nearby)
- if ((M.client && M.machine == src))
- src.attack_self(M)
-*/
diff --git a/code/game/objects/items/weapons/scrolls.dm b/code/game/objects/items/weapons/scrolls.dm
index 244c885ee6b..3e4238780e3 100644
--- a/code/game/objects/items/weapons/scrolls.dm
+++ b/code/game/objects/items/weapons/scrolls.dm
@@ -90,7 +90,7 @@
break
if(!success)
- user.loc = pick(L)
+ user.forceMove(pick(L))
smoke.start()
src.uses -= 1
diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm
index 3c4278b805b..ec2ae31c51d 100644
--- a/code/game/objects/structures/bedsheet_bin.dm
+++ b/code/game/objects/structures/bedsheet_bin.dm
@@ -32,7 +32,7 @@ LINEN BINS
add_fingerprint(user)
/obj/item/bedsheet/attackby(obj/item/I, mob/user)
- if(is_sharp(I))
+ if(is_sharp(I) || I.tool_check(TOOL_WIRECUTTER))
user.visible_message("\The [user] begins cutting up [src] with [I].", "You begin cutting up [src] with [I].")
if(do_after(user, 50))
to_chat(user, "You cut [src] into pieces!")
diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm
index 0bb46b31e65..4b6d3cafce3 100644
--- a/code/game/objects/structures/crates_lockers/crates.dm
+++ b/code/game/objects/structures/crates_lockers/crates.dm
@@ -77,6 +77,8 @@
return 1
/obj/structure/closet/crate/attackby(obj/item/W as obj, mob/user as mob)
+ if(user.a_intent == INTENT_HARM)
+ return ..()
if(opened)
if(isrobot(user))
return
diff --git a/code/game/objects/structures/transit_tubes.dm b/code/game/objects/structures/transit_tubes.dm
index b0fcc47e05f..c0a849a6e40 100644
--- a/code/game/objects/structures/transit_tubes.dm
+++ b/code/game/objects/structures/transit_tubes.dm
@@ -61,32 +61,8 @@
/obj/structure/transit_tube_pod/Destroy()
for(var/atom/movable/AM in contents)
- AM.loc = loc
-
- ..()
-
-
-
-// When destroyed by explosions, properly handle contents.
-/obj/structure/transit_tube_pod/legacy_ex_act(severity)
- switch(severity)
- if(1.0)
- for(var/atom/movable/AM in contents)
- AM.loc = loc
- LEGACY_EX_ACT(AM, severity + 1, null)
-
- qdel(src)
- return
- if(2.0)
- if(prob(50))
- for(var/atom/movable/AM in contents)
- AM.loc = loc
- LEGACY_EX_ACT(AM, severity + 1, null)
-
- qdel(src)
- return
- if(3.0)
- return
+ AM.forceMove(loc)
+ return ..()
/obj/structure/transit_tube_pod/Initialize(mapload)
. = ..()
@@ -117,7 +93,7 @@
to_chat(AM, "The tube's support pylons block your way.")
return ..()
else
- AM.loc = src.loc
+ AM.forceMove(loc)
to_chat(AM, "You slip under the tube.")
/obj/structure/transit_tube/station/Bumped(mob/AM as mob|obj)
@@ -127,7 +103,7 @@
to_chat(AM, "The pod is already occupied.")
return
else if(!pod.moving && (pod.dir in directions()))
- AM.loc = pod
+ AM.forceMove(pod)
return
@@ -334,7 +310,7 @@
last_delay = current_tube.enter_delay(src, next_dir)
sleep(last_delay)
setDir(next_dir)
- loc = next_loc // When moving from one tube to another, skip collision and such.
+ forceMove(next_loc) // When moving from one tube to another, skip collision and such.
density = current_tube.density
if(current_tube && current_tube.should_stop_pod(src, next_dir))
@@ -381,7 +357,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.forceMove(loc)
mob.client.Move(get_step(loc, direction), direction)
//if(moving && istype(loc, /turf/space))
@@ -394,7 +370,7 @@
if(!station.pod_moving)
if(direction == station.dir)
if(station.icon_state == "open")
- mob.loc = loc
+ mob.forceMove(loc)
mob.client.Move(get_step(loc, direction), direction)
else
diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm
index b1adaf1250e..9fd7adb195a 100644
--- a/code/game/objects/structures/watercloset.dm
+++ b/code/game/objects/structures/watercloset.dm
@@ -33,7 +33,7 @@
if(ishuman(user))
user.put_in_hands(I)
else
- I.loc = get_turf(src)
+ I.forceMove(get_turf(src))
to_chat(user, "You find \an [I] in the cistern.")
w_items -= I.w_class
return
diff --git a/code/game/verbs/advanced_who.dm b/code/game/verbs/advanced_who.dm
index d19d6ac5d86..a0359f7f56b 100644
--- a/code/game/verbs/advanced_who.dm
+++ b/code/game/verbs/advanced_who.dm
@@ -1,3 +1,5 @@
+// todo: combine with advanced who wtf is this shit
+// todo: /client/proc/who_query(client/asker, admin_rights, ...) be used for building the string?
/client/verb/who_advanced()
set name = "Advanced Who"
@@ -10,6 +12,10 @@
if(holder && (R_ADMIN & holder.rights || R_MOD & holder.rights))
for(var/client/C in GLOB.clients)
var/entry = "\t[C.key]"
+ if(!C.initialized)
+ entry += " - Uninitialized"
+ Lines += entry
+ continue
if(C.holder && C.holder.fakekey)
entry += " (as [C.holder.fakekey])"
entry += " - Playing as [C.mob.real_name]"
@@ -54,6 +60,10 @@
else
for(var/client/C in GLOB.clients)
var/entry = "\t"
+ if(!C.initialized)
+ entry += "[C.ckey] - Uninitialized"
+ Lines += entry
+ continue
if(C.holder && C.holder.fakekey)
entry += "[C.holder.fakekey]"
else
diff --git a/code/game/verbs/character_directory.dm b/code/game/verbs/character_directory.dm
index 1ee1d7e975d..8313016a25d 100644
--- a/code/game/verbs/character_directory.dm
+++ b/code/game/verbs/character_directory.dm
@@ -40,8 +40,11 @@ GLOBAL_DATUM(character_directory, /datum/character_directory)
var/list/directory_mobs = list()
for(var/client/C in GLOB.clients)
+ if(!C.initialized)
+ continue
+
// Allow opt-out.
- if(!C?.prefs?.show_in_directory)
+ if(!C.prefs.show_in_directory)
continue
// These are the three vars we're trying to find
diff --git a/code/game/verbs/who.dm b/code/game/verbs/who.dm
index ae584e95569..3a9f73e3bfc 100644
--- a/code/game/verbs/who.dm
+++ b/code/game/verbs/who.dm
@@ -1,3 +1,6 @@
+// todo: combine with advanced who wtf is this shit
+// todo: /client/proc/who_query(client/asker, admin_rights, ...) be used for building the string?
+
/client/verb/who()
set name = "Who"
set category = "OOC"
@@ -9,6 +12,10 @@
if(holder && (R_ADMIN & holder.rights || R_MOD & holder.rights))
for(var/client/C in GLOB.clients)
var/entry = "\t[C.key]"
+ if(!C.initialized)
+ entry += "[C.ckey] - Uninitialized"
+ Lines += entry
+ continue
if(C.holder && C.holder.fakekey)
entry += " (as [C.holder.fakekey])"
if(!C.initialized)
@@ -76,6 +83,9 @@
var/num_admins_online = 0
if(holder)
for(var/client/C in GLOB.admins)
+ if(!C.initialized)
+ continue
+
if(C.holder.fakekey && !((R_ADMIN|R_MOD) & holder.rights))
continue
@@ -101,6 +111,8 @@
else
for(var/client/C in GLOB.admins)
+ if(!C.initialized)
+ continue
if(C.holder.fakekey)
continue // hidden
msg += "\t[C] is a [C.holder.rank]"
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index ec56a4e3b71..be7e52115dd 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -1120,6 +1120,8 @@ var/list/admin_verbs_event_manager = list(
var/list/client/eligible = GLOB.clients.Copy()
for(var/i in eligible)
var/client/C = i
+ if(!C.initialized)
+ eligible -= C
if(!isliving(C.mob))
eligible -= C
for(var/role in GLOB.event_role_list)
diff --git a/code/modules/asset_cache/asset_cache_client.dm b/code/modules/asset_cache/asset_cache_client.dm
index 3cff8cb41f3..a30fcaf5dfe 100644
--- a/code/modules/asset_cache/asset_cache_client.dm
+++ b/code/modules/asset_cache/asset_cache_client.dm
@@ -1,4 +1,8 @@
+/client/proc/warn_if_no_asset_cache_browser()
+ if(!winexists(src, "asset_cache_browser")) // The client is using a custom skin, tell them.
+ to_chat(src, "Unable to access asset cache browser, if you are using a custom skin file, please allow DS to download the updated version, if you are not, then make a bug report. This is not a critical issue but can cause issues with resource downloading, as it is impossible to know when extra resources arrived to you.")
+
/// Process asset cache client topic calls for `"asset_cache_confirm_arrival=[INT]"`
/client/proc/asset_cache_confirm_arrival(job_id)
var/asset_cache_job = round(text2num(job_id))
diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm
index 9daabd9d104..30684835ef8 100644
--- a/code/modules/client/client_procs.dm
+++ b/code/modules/client/client_procs.dm
@@ -149,11 +149,18 @@
return 1
-
///////////
//CONNECT//
///////////
+/**
+ * Linter check, do not call.
+ */
+/proc/lint__check_client_new_doesnt_sleep()
+ SHOULD_NOT_SLEEP(TRUE)
+ var/client/C
+ C.New()
+
/client/New(TopicData)
//* pre-connect-ish
// set appadmin for profiling or it might not work (?) (this is old code we just assume it's here for a reason)
@@ -165,9 +172,12 @@
return null
// kick out guests
if(!config_legacy.guests_allowed && is_guest() && !is_localhost())
- alert(src,"This server doesn't allow guest accounts to play. Please go to http://www.byond.com/ and register for a key.","Guest","OK")
- del(src)
- return
+ security_kick(
+ message = "This server doesn't allow guest accounts to play. Please go to http://www.byond.com/ and register for a key.",
+ tell_user = TRUE,
+ immediate = TRUE,
+ )
+ return null
// pre-connect greeting
to_chat(src, "If the title screen is black, resources are still downloading. Please be patient until the title screen appears.")
// register in globals
@@ -195,11 +205,11 @@
//* Setup user interface
// todo: move top level menu here, for now it has to be under prefs.
// Instantiate statpanel
- statpanel_boot()
+ addtimer(CALLBACK(src, PROC_REF(statpanel_boot)), 0)
// Instantiate tgui panel
tgui_panel = new(src, "browseroutput")
// Instantiate cutscene system
- init_cutscene_system()
+ addtimer(CALLBACK(src, PROC_REF(init_cutscene_system)), 0)
//* Setup admin tooling
GLOB.ahelp_tickets.ClientLogin(src)
@@ -262,10 +272,7 @@
// start caching it immediately
INVOKE_ASYNC(SSipintel, TYPE_PROC_REF(/datum/controller/subsystem/ipintel, vpn_connection_check), address, ckey)
// run onboarding gauntlet
- if(!onboarding())
- if(!queued_security_kick)
- security_kick("Unknown error during client init. Contact staff on Discord.", TRUE)
- return FALSE
+ INVOKE_ASYNC(src, PROC_REF(onboarding))
//* Initialize Input
if(SSinput.initialized)
@@ -276,7 +283,7 @@
// initialize statbrowser
// (we don't, the JS does it for us. by signalling statpanel_ready().)
// Initialize tgui panel
- tgui_panel.initialize()
+ INVOKE_ASYNC(tgui_panel, TYPE_PROC_REF(/datum/tgui_panel, initialize))
// initialize cutscene browser
// (we don't, the JS does it for us.)
@@ -325,12 +332,13 @@
to_chat(src, "You have unread updates in the changelog.")
winset(src, "infowindow.changelog", "background-color=#eaeaea;font-style=bold")
if(config_legacy.aggressive_changelog)
- changelog()
+ changelog_async()
- if(!winexists(src, "asset_cache_browser")) // The client is using a custom skin, tell them.
- to_chat(src, "Unable to access asset cache browser, if you are using a custom skin file, please allow DS to download the updated version, if you are not, then make a bug report. This is not a critical issue but can cause issues with resource downloading, as it is impossible to know when extra resources arrived to you.")
+ // ensure asset cache is there
+ INVOKE_ASYNC(src, PROC_REF(warn_if_no_asset_cache_browser))
- hook_vr("client_new",list(src))
+ // todo: fuck you voreprefs
+ prefs_vr = new /datum/vore_preferences(src)
if(config_legacy.paranoia_logging)
if(isnum(player.player_age) && player.player_age == -1)
@@ -353,6 +361,14 @@
//DISCONNECT//
//////////////
+/**
+ * Linter check, do not call.
+ */
+/proc/lint__check_client_del_doesnt_sleep()
+ SHOULD_NOT_SLEEP(TRUE)
+ var/client/C
+ C.Del()
+
/client/Del()
if(!gc_destroyed)
Destroy() //Clean up signals and timers.
diff --git a/code/modules/client/data/client_data.dm b/code/modules/client/data/client_data.dm
index 280ead576af..8e1387b858f 100644
--- a/code/modules/client/data/client_data.dm
+++ b/code/modules/client/data/client_data.dm
@@ -21,9 +21,9 @@ GLOBAL_LIST_EMPTY(client_data)
var/key
/// absolutely, positively annihilated
var/ligma = FALSE
- /// byond account join date
+ /// byond account join date; null = not loaded
var/account_join
- /// byond account age
+ /// byond account age; null = not loaded
var/account_age
/// is guest
var/is_guest
@@ -47,7 +47,7 @@ GLOBAL_LIST_EMPTY(client_data)
is_guest = IsGuestKey(key)
- load_account_age()
+ INVOKE_ASYNC(src, PROC_REF(load_account_age))
var/list/the_cheese_touch = CONFIG_GET(keyed_list/shadowban)
var/client/C = GLOB.directory[src.ckey]
diff --git a/code/modules/client/onboarding/_onboarding.dm b/code/modules/client/onboarding/_onboarding.dm
index 5fa68709b1a..fac960325d8 100644
--- a/code/modules/client/onboarding/_onboarding.dm
+++ b/code/modules/client/onboarding/_onboarding.dm
@@ -4,10 +4,6 @@
* client should already be logged to DB at this point.
*/
/client/proc/onboarding()
- if(!security_checks())
- return FALSE
- if(!panic_bunker())
- return FALSE
- if(!age_verification())
- return FALSE
- return TRUE
+ security_checks()
+ panic_bunker()
+ age_verification()
diff --git a/code/modules/client/onboarding/age_verification.dm b/code/modules/client/onboarding/age_verification.dm
index b462ed39eda..22ed9ebc503 100644
--- a/code/modules/client/onboarding/age_verification.dm
+++ b/code/modules/client/onboarding/age_verification.dm
@@ -1,4 +1,8 @@
/client/proc/age_verification()
+ set waitfor = FALSE
+ age_verification_impl()
+
+/client/proc/age_verification_impl()
if(!SSdbcore.Connect())
return TRUE
if(!player.block_on_available(10 SECONDS))
diff --git a/code/modules/client/onboarding/security_checks.dm b/code/modules/client/onboarding/security_checks.dm
index fbf15c4e16c..dd2eaf50605 100644
--- a/code/modules/client/onboarding/security_checks.dm
+++ b/code/modules/client/onboarding/security_checks.dm
@@ -5,6 +5,10 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
))
/client/proc/security_checks()
+ set waitfor = FALSE
+ security_checks_impl()
+
+/client/proc/security_checks_impl()
if(byond_version < 513)
security_kick("BYOND 512 and prior clients are too outdated.", tell_user = TRUE)
return FALSE
diff --git a/code/modules/client/security.dm b/code/modules/client/security.dm
index b5506b80ed8..d29a1ee6898 100644
--- a/code/modules/client/security.dm
+++ b/code/modules/client/security.dm
@@ -31,7 +31,7 @@
* queues a security kick
* ensures the client's around for atleast delay or after current proc chain is over
*/
-/client/proc/queue_security_kick(delay)
+/client/proc/queue_security_kick(delay = 0)
var/left = isnull(queued_security_kick)? null : timeleft(queued_security_kick)
if(isnull(left) || left < delay)
deltimer(queued_security_kick)
diff --git a/code/modules/client/verbs/ooc.dm b/code/modules/client/verbs/ooc.dm
index 578b34a6c56..ee6a11fd801 100644
--- a/code/modules/client/verbs/ooc.dm
+++ b/code/modules/client/verbs/ooc.dm
@@ -127,6 +127,9 @@
ooc_style = "admin"
for(var/client/target in GLOB.clients)
+ if(!target.initialized)
+ continue
+
if(target.is_preference_enabled(/datum/client_preference/show_ooc))
if(target.is_key_ignored(key)) // If we're ignored by this person, then do nothing.
continue
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 0f4c3c6efdc..eb87ea70b47 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -32,7 +32,7 @@
for(var/mob/M in src)
if(M in src.stomach_contents)
src.stomach_contents.Remove(M)
- M.loc = src.loc
+ M.forceMove(loc)
for(var/mob/N in viewers(src, null))
if(N.client)
N.show_message("[M] bursts out of [src]!", 2)
diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm
index 1820d5514af..74191dc0a1a 100644
--- a/code/modules/mob/login.dm
+++ b/code/modules/mob/login.dm
@@ -1,3 +1,11 @@
+/**
+ * Linter check, do not call.
+ */
+/proc/lint__check_mob_login_doesnt_sleep()
+ SHOULD_NOT_SLEEP(TRUE)
+ var/mob/M
+ M.Login()
+
/**
* Run when a client is put in this mob or reconnets to byond and their client was on this mob
*
diff --git a/code/modules/mob/logout.dm b/code/modules/mob/logout.dm
index 8cebd172f60..4bd4d81517f 100644
--- a/code/modules/mob/logout.dm
+++ b/code/modules/mob/logout.dm
@@ -1,3 +1,12 @@
+
+/**
+ * Linter check, do not call.
+ */
+/proc/lint__check_mob_logout_doesnt_sleep()
+ SHOULD_NOT_SLEEP(TRUE)
+ var/mob/M
+ M.Logout()
+
/mob/Logout()
SHOULD_CALL_PARENT(TRUE)
SEND_SIGNAL(src, COMSIG_MOB_CLIENT_LOGOUT, client)
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index 107b16dd470..122742c1941 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -450,7 +450,7 @@
var/obj/structure/AIcore/deactivated/C = GLOB.empty_playable_ai_cores[1]
GLOB.empty_playable_ai_cores -= C
- character.loc = C.loc
+ character.forceMove(C.loc)
AnnounceCyborg(character, rank, "has been transferred to the empty core in \the [character.loc.loc]")
SSticker.mode.latespawn(character)
@@ -466,7 +466,7 @@
// Moving wheelchair if they have one
if(character.buckled && istype(character.buckled, /obj/structure/bed/chair/wheelchair))
- character.buckled.loc = character.loc
+ character.buckled.forceMove(character.loc)
character.buckled.setDir(character.dir)
SSticker.mode.latespawn(character)
diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm
index 628d66c0f4e..a505448584d 100644
--- a/code/modules/nano/nanoui.dm
+++ b/code/modules/nano/nanoui.dm
@@ -35,7 +35,7 @@
/// The layout key for this ui (this is used on the frontend, leave it as "default" unless you know what you're doing)
var/layout_key = "default"
/// Optional layout key for additional ui header content to include
- var/layout_header_key = "default_header"
+ // var/layout_header_key = "default_header"
/// This sets whether to re-render the ui layout with each update (default 0, turning on will break the map ui if it's in use)
var/auto_update_layout = FALSE
/// This sets whether to re-render the ui content with each update (default 1)
@@ -342,8 +342,8 @@
// before the UI opens, add the layout files based on the layout key
add_stylesheet("layout_[layout_key].css")
add_template("layout", "layout_[layout_key].tmpl")
- if (layout_header_key)
- add_template("layoutHeader", "layout_[layout_header_key].tmpl")
+ // if (layout_header_key)
+ // add_template("layoutHeader", "layout_[layout_header_key].tmpl")
var/head_content = ""
diff --git a/code/modules/organs/external/external.dm b/code/modules/organs/external/external.dm
index e09e6c6820d..9bb9452a31d 100644
--- a/code/modules/organs/external/external.dm
+++ b/code/modules/organs/external/external.dm
@@ -201,7 +201,7 @@
removable_objects |= I
if(removable_objects.len)
var/obj/item/I = pick(removable_objects)
- I.loc = get_turf(user) //just in case something was embedded that is not an item
+ I.forceMove(get_turf(user)) //just in case something was embedded that is not an item
if(istype(I))
user.put_in_hands(I)
user.visible_message("\The [user] rips \the [I] out of \the [src]!")
@@ -233,7 +233,7 @@
if(istype(W,/obj/item/surgical/hemostat))
if(contents.len)
var/obj/item/removing = pick(contents)
- removing.loc = get_turf(user.loc)
+ removing.forceMove(get_turf(user.loc))
user.put_in_hands(removing)
user.visible_message("[user] extracts [removing] from [src] with [W]!")
else
@@ -537,7 +537,7 @@
// remove embedded objects and drop them on the floor
for(var/obj/implanted_object in implants)
if(!istype(implanted_object,/obj/item/implant) && !istype(implanted_object,/obj/item/nif)) // We don't want to remove REAL implants. Just shrapnel etc.
- implanted_object.loc = get_turf(src)
+ implanted_object.forceMove(get_turf(src))
implants -= implanted_object
if(owner && !ignore_prosthetic_prefs)
diff --git a/code/modules/sculpting/sculpting_block.dm b/code/modules/sculpting/sculpting_block.dm
index c759b5e1001..7ebba835e71 100644
--- a/code/modules/sculpting/sculpting_block.dm
+++ b/code/modules/sculpting/sculpting_block.dm
@@ -165,7 +165,7 @@
otherwise_self = SPAN_NOTICE("You start slicing [src] apart."),
)
log_construction(e_args, src, "started deconstructing")
- if(!use_welder(I, e_args, flags, 7 SECONDS, 3))
+ if(!use_welder(I, e_args, flags, 7 SECONDS))
return TRUE
e_args.visible_feedback(
target = src,
diff --git a/code/modules/vore/eating/vore_vr.dm b/code/modules/vore/eating/vore_vr.dm
index 3554bb0eb9c..b9ec5048842 100644
--- a/code/modules/vore/eating/vore_vr.dm
+++ b/code/modules/vore/eating/vore_vr.dm
@@ -13,13 +13,6 @@
/client
var/datum/vore_preferences/prefs_vr
-/hook/client_new/proc/add_prefs_vr(client/C)
- C.prefs_vr = new/datum/vore_preferences(C)
- if(C.prefs_vr)
- return TRUE
-
- return FALSE
-
/datum/vore_preferences
//Actual preferences
var/digestable = FALSE
diff --git a/code/modules/vore/hook-defs_vr.dm b/code/modules/vore/hook-defs_vr.dm
index f5aa075a9b4..076e1747dc6 100644
--- a/code/modules/vore/hook-defs_vr.dm
+++ b/code/modules/vore/hook-defs_vr.dm
@@ -1,8 +1,6 @@
//The base hooks themselves
//New() hooks
-/hook/client_new
-
/hook/mob_new
/hook/living_new
diff --git a/interface/interface.dm b/interface/interface.dm
index 57b7e9b48ad..17c258a024b 100644
--- a/interface/interface.dm
+++ b/interface/interface.dm
@@ -89,6 +89,11 @@
to_chat(src, "The Github URL is not set in the server configuration.")
return
+/client/proc/changelog_async()
+ set waitfor = FALSE
+
+ changelog()
+
/client/verb/changelog()
set name = "Changelog"
set category = "OOC"