From e5c9de9b6cf4f1e0b099706f5d1f4eaaa29b944a Mon Sep 17 00:00:00 2001 From: silicons <2003111+silicons@users.noreply.github.com> Date: Sat, 6 Jan 2024 11:27:26 -0800 Subject: [PATCH] various fixes (#6252) see commits fixes stuff in maintainer bug triage --------- Co-authored-by: silicons --- code/controllers/subsystem/input.dm | 9 +- code/controllers/subsystem/parallax.dm | 10 ++ code/controllers/subsystem/ping.dm | 3 + code/controllers/subsystem/throwing.dm | 6 + .../components/turfs/transition_border.dm | 42 ++++--- code/datums/recipe/stack_recipe.dm | 8 ++ code/game/atoms/movable/movement.dm | 3 +- code/game/dna/dna_modifier.dm | 41 +------ code/game/dna/genes/monkey.dm | 17 ++- .../changeling/powers/lesser_form.dm | 4 +- code/game/mecha/working/ripley.dm | 5 +- code/game/mecha/working/working.dm | 47 ------- code/game/objects/effects/spiders.dm | 8 +- code/game/objects/items.dm | 1 - code/game/objects/items/devices/PDA/PDA.dm | 4 +- .../objects/items/devices/chameleonproj.dm | 2 +- code/game/objects/items/devices/gps.dm | 2 +- .../objects/items/devices/radio/headset.dm | 4 +- .../game/objects/items/devices/radio/radio.dm | 2 +- code/game/objects/items/glassjar.dm | 6 +- code/game/objects/items/robot/robot_parts.dm | 4 +- code/game/objects/items/tools/weldingtool.dm | 2 +- .../game/objects/items/weapons/hydroponics.dm | 116 ------------------ code/game/objects/items/weapons/scrolls.dm | 2 +- code/game/objects/structures/bedsheet_bin.dm | 2 +- .../structures/crates_lockers/crates.dm | 2 + code/game/objects/structures/transit_tubes.dm | 38 ++---- code/game/objects/structures/watercloset.dm | 2 +- code/game/verbs/advanced_who.dm | 10 ++ code/game/verbs/character_directory.dm | 5 +- code/game/verbs/who.dm | 12 ++ code/modules/admin/admin_verbs.dm | 2 + .../modules/asset_cache/asset_cache_client.dm | 4 + code/modules/client/client_procs.dm | 46 ++++--- code/modules/client/data/client_data.dm | 6 +- code/modules/client/onboarding/_onboarding.dm | 10 +- .../client/onboarding/age_verification.dm | 4 + .../client/onboarding/security_checks.dm | 4 + code/modules/client/security.dm | 2 +- code/modules/client/verbs/ooc.dm | 3 + code/modules/mob/living/carbon/carbon.dm | 2 +- code/modules/mob/login.dm | 8 ++ code/modules/mob/logout.dm | 9 ++ code/modules/mob/new_player/new_player.dm | 4 +- code/modules/nano/nanoui.dm | 6 +- code/modules/organs/external/external.dm | 6 +- code/modules/sculpting/sculpting_block.dm | 2 +- code/modules/vore/eating/vore_vr.dm | 7 -- code/modules/vore/hook-defs_vr.dm | 2 - interface/interface.dm | 5 + 50 files changed, 213 insertions(+), 338 deletions(-) delete mode 100644 code/game/objects/items/weapons/hydroponics.dm 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"