From aed3013410a511c4a384bbb7f0cdb9990c25136e Mon Sep 17 00:00:00 2001 From: silicons <2003111+silicons@users.noreply.github.com> Date: Fri, 10 Jan 2025 11:34:32 -0500 Subject: [PATCH] bugfix / tweaks (#6959) --- citadel.dme | 14 ++- code/__DEFINES/mapping/multiz.dm | 22 +++- code/__HELPERS/lists/associations.dm | 1 + code/controllers/repository/flooring.dm | 12 +- code/datums/components/_component.dm | 9 +- .../components/mobs/mob_feign_impairment.dm | 62 +++++++++++ .../mobs/mob_self_horizontal_inversion.dm | 6 + .../mobs/mob_self_vertical_inversion.dm | 40 +++++++ .../nanotrasen/nanotrasen-supply/costumes.dm | 4 +- .../game/objects/items-inventory-rendering.dm | 2 +- code/game/objects/items/gifts.dm | 1 - .../melee/types/transforming/energy/saber.dm | 1 + code/game/objects/items/stacks/rods.dm | 3 +- code/game/objects/items/stacks/stack.dm | 41 +++++-- .../objects/items/stacks/tiles/tile_types.dm | 12 +- code/game/objects/random/maintenance.dm | 2 +- code/game/objects/structures/loot_piles.dm | 2 +- code/game/objects/structures/trash_pile.dm | 2 +- code/game/objects/systems/storage/storage.dm | 12 +- code/game/rendering/legacy/radial.dm | 4 + code/game/rendering/mob.dm | 2 + .../simulated/floor/floor-construction.dm | 21 +++- .../game/turfs/simulated/flooring/flooring.dm | 12 ++ .../simulated/flooring/flooring_types.dm | 3 - code/modules/artwork/crayon_decal_meta.dm | 10 +- code/modules/artwork/items/crayon.dm | 2 + code/modules/clothing/accessories/halo.dm | 4 +- code/modules/clothing/clothing.dm | 27 +++-- code/modules/clothing/under/_under.dm | 4 +- code/modules/clothing/under/gear_harness.dm | 25 +++++ code/modules/clothing/under/miscellaneous.dm | 6 - code/modules/frames/frame_step.dm | 10 +- code/modules/frames/types/fire_alarm.dm | 2 +- code/modules/loadout/loadout_xeno.dm | 2 +- code/modules/materials/material_sheets.dm | 2 +- code/modules/materials/material_synth.dm | 6 + code/modules/mining/tools/vertibore.dm | 2 +- code/modules/mob/animations.dm | 11 +- .../mob/living/carbon/human/examine.dm | 7 +- .../mob/living/carbon/human/human-defense.dm | 2 +- .../mob/living/carbon/human/update_icons.dm | 2 +- code/modules/mob/living/living.dm | 2 +- code/modules/mob/living/say.dm | 4 +- code/modules/mob/mob-status_procs.dm | 36 ++++++ code/modules/mob/mob.dm | 5 + code/modules/mob/verbs/feign_impairment.dm | 105 ++++++++++++++++++ .../mob/verbs/horizontal_invert_self.dm | 1 + .../modules/mob/verbs/vertical_invert_self.dm | 24 ++++ code/modules/multiz/atom-z_fall.dm | 29 +++++ .../multiz/{atoms.dm => atom-z_move.dm} | 2 +- code/modules/multiz/core.dm | 2 +- code/modules/multiz/falling.dm | 15 --- code/modules/multiz/movement.dm | 36 +++--- code/modules/multiz/turf-multiz_misc.dm | 52 +++++++++ code/modules/multiz/turf-z_fall.dm | 38 +++++++ .../multiz/{turf.dm => turf-z_move.dm} | 100 ++--------------- code/modules/power/cable.dm | 45 ++++---- .../preferences/preferences_toggle_procs.dm | 50 --------- .../micro/mecha_construction_paths_vr.dm | 2 - maps/templates/archive/tradeship.dmm | 2 +- 60 files changed, 677 insertions(+), 287 deletions(-) create mode 100644 code/datums/components/mobs/mob_feign_impairment.dm create mode 100644 code/datums/components/mobs/mob_self_vertical_inversion.dm create mode 100644 code/modules/clothing/under/gear_harness.dm create mode 100644 code/modules/mob/mob-status_procs.dm create mode 100644 code/modules/mob/verbs/feign_impairment.dm create mode 100644 code/modules/mob/verbs/vertical_invert_self.dm create mode 100644 code/modules/multiz/atom-z_fall.dm rename code/modules/multiz/{atoms.dm => atom-z_move.dm} (92%) delete mode 100644 code/modules/multiz/falling.dm create mode 100644 code/modules/multiz/turf-multiz_misc.dm create mode 100644 code/modules/multiz/turf-z_fall.dm rename code/modules/multiz/{turf.dm => turf-z_move.dm} (52%) diff --git a/citadel.dme b/citadel.dme index c1999fd4477..674277a855b 100644 --- a/citadel.dme +++ b/citadel.dme @@ -811,7 +811,9 @@ #include "code\datums\components\items\passive_parry.dm" #include "code\datums\components\items\wielding.dm" #include "code\datums\components\mobs\block_frame.dm" +#include "code\datums\components\mobs\mob_feign_impairment.dm" #include "code\datums\components\mobs\mob_self_horizontal_inversion.dm" +#include "code\datums\components\mobs\mob_self_vertical_inversion.dm" #include "code\datums\components\mobs\parry_frame.dm" #include "code\datums\components\movable\aquarium.dm" #include "code\datums\components\movable\spatial_grid.dm" @@ -2668,6 +2670,7 @@ #include "code\modules\clothing\suits\aliens\vox.dm" #include "code\modules\clothing\under\_under.dm" #include "code\modules\clothing\under\color.dm" +#include "code\modules\clothing\under\gear_harness.dm" #include "code\modules\clothing\under\imperial_vr.dm" #include "code\modules\clothing\under\misc.dm" #include "code\modules\clothing\under\miscellaneous.dm" @@ -3615,6 +3618,7 @@ #include "code\modules\mob\mob-keybind-triggers.dm" #include "code\modules\mob\mob-login.dm" #include "code\modules\mob\mob-logout.dm" +#include "code\modules\mob\mob-status_procs.dm" #include "code\modules\mob\mob.dm" #include "code\modules\mob\mob_defines.dm" #include "code\modules\mob\mob_helpers.dm" @@ -4146,7 +4150,9 @@ #include "code\modules\mob\observer\dead\orbit.dm" #include "code\modules\mob\observer\dead\perspective.dm" #include "code\modules\mob\observer\dead\say.dm" +#include "code\modules\mob\verbs\feign_impairment.dm" #include "code\modules\mob\verbs\horizontal_invert_self.dm" +#include "code\modules\mob\verbs\vertical_invert_self.dm" #include "code\modules\modular_computers\laptop_vendor.dm" #include "code\modules\modular_computers\computers\modular_computer\core.dm" #include "code\modules\modular_computers\computers\modular_computer\damage.dm" @@ -4211,12 +4217,14 @@ #include "code\modules\movespeed\movespeed_modifier.dm" #include "code\modules\movespeed\modifiers\misc.dm" #include "code\modules\movespeed\modifiers\mob.dm" -#include "code\modules\multiz\atoms.dm" +#include "code\modules\multiz\atom-z_fall.dm" +#include "code\modules\multiz\atom-z_move.dm" #include "code\modules\multiz\basic_legacy.dm" #include "code\modules\multiz\core.dm" -#include "code\modules\multiz\falling.dm" #include "code\modules\multiz\movement.dm" -#include "code\modules\multiz\turf.dm" +#include "code\modules\multiz\turf-multiz_misc.dm" +#include "code\modules\multiz\turf-z_fall.dm" +#include "code\modules\multiz\turf-z_move.dm" #include "code\modules\multiz\structures\hoist.dm" #include "code\modules\multiz\structures\ladder.dm" #include "code\modules\multiz\structures\pipes.dm" diff --git a/code/__DEFINES/mapping/multiz.dm b/code/__DEFINES/mapping/multiz.dm index b43bdd839d7..51636b09d27 100644 --- a/code/__DEFINES/mapping/multiz.dm +++ b/code/__DEFINES/mapping/multiz.dm @@ -1,4 +1,8 @@ -// fall_flags +//* This file is explicitly licensed under the MIT license. *// +//* Copyright (c) 2025 Citadel Station Developers *// + +//* fall_Flags *// + /// Falling should ignore anchored status #define FALL_IGNORE_ANCHORED (1<<0) /// this fall shouldn't incur any sort of self-damage for hitting the ground @@ -20,17 +24,25 @@ #define FALL_FLAGS_STOP (FALL_BLOCKED | FALL_RECOVERED | FALL_TERMINATED) /// there's a level above +/// * This works as long as SSmapping has its rebuild proc called after a load; given this is enforced +/// by SSmapping most of the time, this is usually fine. #define Z_HAS_ABOVE(z) (!isnull(SSmapping.cached_level_up[z])) /// there's a level below +/// * This works as long as SSmapping has its rebuild proc called after a load; given this is enforced +/// by SSmapping most of the time, this is usually fine. #define Z_HAS_BELOW(z) (!isnull(SSmapping.cached_level_down[z])) /// get turf below this turf, if any -/// we are at the mercy of zmimic when we do this. do not use in critical maploader code. +/// * this is a guesstimation +/// * we are at the mercy of zmimic when we do this. do not use in critical maploader code. #define TURF_BELOW_ISH(T) (T.below || T.below()) /// get turf above this turf, if any -/// we are at the mercy of zmimic when we do this. do not use in critical maploader code. +/// * this is a guesstimation +/// * we are at the mercy of zmimic when we do this. do not use in critical maploader code. #define TURF_ABOVE_ISH(T) (T.above || T.above()) -/// we should use get virtual step due to our x/y being border -/// we do not get step this, so use it on something **on** game world. (aka turf or on turf). +/// Checks if we're right next to the map transition border. +/// * Only valid for something on a turf. +/// +/// todo: support multi-tile objects #define AT_MAP_BORDER(A) (A.x == 2 || A.y == 2 || A.x == world.maxx - 1 || A.y == world.maxy - 1) diff --git a/code/__HELPERS/lists/associations.dm b/code/__HELPERS/lists/associations.dm index 7e2610cb0ba..243906b6dba 100644 --- a/code/__HELPERS/lists/associations.dm +++ b/code/__HELPERS/lists/associations.dm @@ -32,6 +32,7 @@ flat_list[flat_list[i]] = TRUE return flat_list +//! WARNING: this no longer works; byond will NEVER de-assoc a list for json_encode purposes even if this is called! /proc/assoc_list_strip_value_inplace(list/input) for(var/i in 1 to length(input)) input[input[i]] = null diff --git a/code/controllers/repository/flooring.dm b/code/controllers/repository/flooring.dm index 8b7bd2ba2e3..ed8190c1253 100644 --- a/code/controllers/repository/flooring.dm +++ b/code/controllers/repository/flooring.dm @@ -20,17 +20,21 @@ REPOSITORY_DEF(flooring) if(!.) return if(ispath(instance.build_type, /obj/item/stack)) - LAZYADD(build_item_lookup[instance.build_type], instance) + if(build_item_lookup?[instance.build_type]) + stack_trace("attempted to load [instance.id], but build type [instance.build_type] collides with [build_item_lookup?[instance.build_type]:id]. suppressing [instance.id]'s build_type.") + LAZYSET(build_item_lookup, instance.build_type, instance) else if(ispath(instance.build_type, /datum/prototype/material)) var/datum/prototype/material/casted_material = instance.build_type - LAZYADD(build_material_lookup[initial(casted_material.id)], instance) + if(build_material_lookup?[casted_material.id]) + stack_trace("attempted to load [instance.id], but material [casted_material.id] collides with [build_material_lookup?[casted_material.id]:id]. suppressing [instance.id]'s build_type.") + LAZYSET(build_material_lookup, initial(casted_material.id), instance) /datum/controller/repository/flooring/unload(datum/prototype/flooring/instance) . = ..() if(!.) return if(ispath(instance.build_type, /obj/item/stack)) - LAZYREMOVE(build_item_lookup[instance.build_type], instance) + LAZYREMOVE(build_item_lookup, instance.build_type) else if(ispath(instance.build_type, /datum/prototype/material)) var/datum/prototype/material/casted_material = instance.build_type - LAZYREMOVE(build_material_lookup[initial(casted_material.id)], instance) + LAZYREMOVE(build_material_lookup, initial(casted_material.id)) diff --git a/code/datums/components/_component.dm b/code/datums/components/_component.dm index e9fb0a5caa0..ec9b3e6a4a3 100644 --- a/code/datums/components/_component.dm +++ b/code/datums/components/_component.dm @@ -345,11 +345,10 @@ for(var/datum/listening_datum as anything in queued_calls) . |= call(listening_datum, queued_calls[listening_datum])(arglist(arguments)) -// The type arg is casted so initial works, you shouldn't be passing a real instance into this /** - * Return any component assigned to this datum of the given type + * Return any component assigned to this datum of the given registered component type * - * If it has a registered type, that'll be used instead! + * * `registered_type` must be set on the component for this to work. * * Arguments: * * datum/component/c_type The type of the component you want to get a reference to. It will be overridden with the type of its [registered_type] if it's set. @@ -360,7 +359,9 @@ return . && (length(.) ? .[1] : .) /** - * Get all components of a given type that are attached to this datum + * Get all components of a given registered component type that are attached to this datum + * + * * `registered_type` must be set on the component for this to work. * * Arguments: * * c_type The component type path diff --git a/code/datums/components/mobs/mob_feign_impairment.dm b/code/datums/components/mobs/mob_feign_impairment.dm new file mode 100644 index 00000000000..0c9d897dad0 --- /dev/null +++ b/code/datums/components/mobs/mob_feign_impairment.dm @@ -0,0 +1,62 @@ +//* This file is explicitly licensed under the MIT license. *// +//* Copyright (c) 2025 Citadel Station Developers *// + +// todo: datumize impairments; the way this works right now is pretty stupid +// it's because we're using different components since i was too +// lazy to do a single tracking component + +/** + * Component added to a mob by the mob themselves to feign an impairment + */ +/datum/component/mob_feign_impairment + var/power + var/feign_impairment_type + +/datum/component/mob_feign_impairment/Initialize(power) + if(!ismob(parent)) + return COMPONENT_INCOMPATIBLE + . = ..() + if(. == COMPONENT_INCOMPATIBLE) + return + src.power = power + +/datum/component/mob_feign_impairment/RegisterWithParent() + . = ..() + // todo: on update stat + RegisterSignal(parent, COMSIG_MOB_ON_UPDATE_MOBILITY, PROC_REF(recheck_stat)) + var/mob/mob_parent = parent + LAZYSET(mob_parent.impairments_feigned, feign_impairment_type, src) + +/datum/component/mob_feign_impairment/UnregisterFromParent() + . = ..() + // todo: on update stat + UnregisterSignal(parent, COMSIG_MOB_ON_UPDATE_MOBILITY) + var/mob/mob_parent = parent + LAZYREMOVE(mob_parent.impairments_feigned, feign_impairment_type) + +/datum/component/mob_feign_impairment/proc/recheck_stat(mob/source) + SIGNAL_HANDLER + if(IS_CONSCIOUS(source)) + return + qdel(src) + +/datum/component/mob_feign_impairment/slurring + // this must be set + registered_type = /datum/component/mob_feign_impairment/slurring + feign_impairment_type = /datum/feign_impairment/slurring + +/datum/component/mob_feign_impairment/stutter + // this must be set + registered_type = /datum/component/mob_feign_impairment/stutter + feign_impairment_type = /datum/feign_impairment/stutter + +/datum/component/mob_feign_impairment/jitter + // this must be set + registered_type = /datum/component/mob_feign_impairment/jitter + feign_impairment_type = /datum/feign_impairment/jitter + +/datum/component/mob_feign_impairment/jitter/RegisterWithParent() + . = ..() + // shitcode but whatever + var/mob/mob_parent = parent + mob_parent.make_jittery(0) diff --git a/code/datums/components/mobs/mob_self_horizontal_inversion.dm b/code/datums/components/mobs/mob_self_horizontal_inversion.dm index 79df9ca7c29..fc85738cf3e 100644 --- a/code/datums/components/mobs/mob_self_horizontal_inversion.dm +++ b/code/datums/components/mobs/mob_self_horizontal_inversion.dm @@ -15,6 +15,7 @@ /datum/component/mob_self_horizontal_inversion/RegisterWithParent() . = ..() RegisterSignal(parent, COMSIG_MOVABLE_BASE_TRANSFORM, PROC_REF(alter_base_transform)) + RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(on_move)) var/mob/target = parent var/matrix/to_apply = target.transform to_apply.Scale(-1, 1) @@ -23,6 +24,7 @@ /datum/component/mob_self_horizontal_inversion/UnregisterFromParent() . = ..() UnregisterSignal(parent, COMSIG_MOVABLE_BASE_TRANSFORM) + UnregisterSignal(parent, COMSIG_MOVABLE_MOVED) var/mob/target = parent var/matrix/to_apply = target.transform to_apply.Scale(-1, 1) @@ -31,3 +33,7 @@ /datum/component/mob_self_horizontal_inversion/proc/alter_base_transform(datum/source, matrix/applying) SIGNAL_HANDLER applying.Scale(-1, 1) + +/datum/component/mob_self_horizontal_inversion/proc/on_move(datum/source) + SIGNAL_HANDLER + qdel(src) diff --git a/code/datums/components/mobs/mob_self_vertical_inversion.dm b/code/datums/components/mobs/mob_self_vertical_inversion.dm new file mode 100644 index 00000000000..8bdec05ff5f --- /dev/null +++ b/code/datums/components/mobs/mob_self_vertical_inversion.dm @@ -0,0 +1,40 @@ +//* This file is explicitly licensed under the MIT license. *// +//* Copyright (c) 2024 Citadel Station Developers *// + +/** + * Component added to a mob by the mob themselves to invert themselves vertically. + */ +/datum/component/mob_self_vertical_inversion + registered_type = /datum/component/mob_self_vertical_inversion + +/datum/component/mob_self_vertical_inversion/Initialize() + if(!ismob(parent)) + return COMPONENT_INCOMPATIBLE + return ..() + +/datum/component/mob_self_vertical_inversion/RegisterWithParent() + . = ..() + // todo: allow it if they're being moved by an external source; MOB_SLEFMOVE? + RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(on_move)) + RegisterSignal(parent, COMSIG_MOVABLE_BASE_TRANSFORM, PROC_REF(alter_base_transform)) + var/mob/target = parent + var/matrix/to_apply = target.transform + to_apply.Scale(1, -1) + target.set_transform(to_apply) + +/datum/component/mob_self_vertical_inversion/UnregisterFromParent() + . = ..() + UnregisterSignal(parent, COMSIG_MOVABLE_BASE_TRANSFORM) + UnregisterSignal(parent, COMSIG_MOVABLE_MOVED) + var/mob/target = parent + var/matrix/to_apply = target.transform + to_apply.Scale(1, -1) + target.set_transform(to_apply) + +/datum/component/mob_self_vertical_inversion/proc/alter_base_transform(datum/source, matrix/applying) + SIGNAL_HANDLER + applying.Scale(1, -1) + +/datum/component/mob_self_vertical_inversion/proc/on_move(datum/source) + SIGNAL_HANDLER + qdel(src) diff --git a/code/game/content/factions/corporations/nanotrasen/nanotrasen-supply/costumes.dm b/code/game/content/factions/corporations/nanotrasen/nanotrasen-supply/costumes.dm index 782a2e66f39..25ab2126413 100644 --- a/code/game/content/factions/corporations/nanotrasen/nanotrasen-supply/costumes.dm +++ b/code/game/content/factions/corporations/nanotrasen/nanotrasen-supply/costumes.dm @@ -187,7 +187,7 @@ /obj/item/clothing/under/permit, /obj/item/clothing/under/vox/vox_casual, /obj/item/clothing/under/vox/vox_robes, - /obj/item/clothing/under/harness, + /obj/item/clothing/under/gear_harness, /obj/item/clothing/under/skirt/loincloth, /obj/item/clothing/gloves/vox, ) @@ -345,7 +345,7 @@ /obj/item/clothing/suit/storage/toggle/leather_jacket/nanotrasen/sleeveless, /obj/item/clothing/under/pants/chaps, /obj/item/clothing/under/pants/chaps/black, - /obj/item/clothing/under/harness, + /obj/item/clothing/under/gear_harness, /obj/item/clothing/shoes/laceup/brown, /obj/item/clothing/shoes/boots/jungle, /obj/item/clothing/shoes/boots/jackboots, diff --git a/code/game/objects/items-inventory-rendering.dm b/code/game/objects/items-inventory-rendering.dm index d28e70515cc..a0e8fc2d44f 100644 --- a/code/game/objects/items-inventory-rendering.dm +++ b/code/game/objects/items-inventory-rendering.dm @@ -472,7 +472,7 @@ var/mob/living/carbon/human/H = ishuman(M)? M : null var/datum/inventory_slot/slot_meta if(isnull(slot_or_id)) - slot_or_id = worn_slot + slot_or_id = inv_slot_or_index if(isnum(slot_or_id)) slot_meta = resolve_inventory_slot((slot_or_id % 2)? /datum/inventory_slot/abstract/hand/left : /datum/inventory_slot/abstract/hand/right) else diff --git a/code/game/objects/items/gifts.dm b/code/game/objects/items/gifts.dm index 2c762e45b57..af41f9f6049 100644 --- a/code/game/objects/items/gifts.dm +++ b/code/game/objects/items/gifts.dm @@ -77,7 +77,6 @@ GLOBAL_LIST_EMPTY(possible_gifts) return gift_type - /obj/item/a_gift/anything name = "christmas gift" desc = "It could be anything!" diff --git a/code/game/objects/items/melee/types/transforming/energy/saber.dm b/code/game/objects/items/melee/types/transforming/energy/saber.dm index 48e1eb49140..60f6d1a5fad 100644 --- a/code/game/objects/items/melee/types/transforming/energy/saber.dm +++ b/code/game/objects/items/melee/types/transforming/energy/saber.dm @@ -83,6 +83,7 @@ armor_penetration = 35 colorable = TRUE attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + worn_render_flags = WORN_RENDER_SLOT_NO_RENDER | WORN_RENDER_INHAND_ONE_FOR_ALL passive_parry = /datum/passive_parry{ parry_chance_default = 60; diff --git a/code/game/objects/items/stacks/rods.dm b/code/game/objects/items/stacks/rods.dm index 13af5cc22f9..b36e4520505 100644 --- a/code/game/objects/items/stacks/rods.dm +++ b/code/game/objects/items/stacks/rods.dm @@ -64,5 +64,6 @@ gender = NEUTER uses_charge = 1 charge_costs = list(500) - stacktype = /obj/item/stack/rods + stack_type = /obj/item/stack/rods + stacktype_legacy = /obj/item/stack/rods no_variants = TRUE diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 4d4b4b51135..6aa51a10242 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -36,16 +36,19 @@ origin_tech = list(TECH_MATERIAL = 1) icon = 'icons/obj/stacks.dmi' item_flags = ITEM_CAREFUL_BLUDGEON | ITEM_ENCUMBERS_WHILE_HELD + + /// Always create this type when splitting, instead of our own type. + var/split_type + /// The type we actually are. This is what is used when things try to consume an amount of us. + /// * null = this current type + var/stack_type + var/singular_name var/amount = 1 /// See stack recipes initialisation, param "max_res_amount" must be equal to this max_amount. var/max_amount = 50 /// Determines whether different stack types can merge. - var/stacktype - /// enforce a certain type when splitting; useful if you have an infinite stack you don't want to be split into another one - var/split_type - /// Used when directly applied to a turf. - var/build_type = null + var/stacktype_legacy var/uses_charge = 0 var/list/charge_costs = null var/list/datum/matter_synth/synths = null @@ -70,8 +73,8 @@ explicit_recipes = typelist(NAMEOF(src, explicit_recipes), generate_explicit_recipes()) if(new_amount != null) amount = new_amount - if(!stacktype) - stacktype = type + if(!stacktype_legacy) + stacktype_legacy = type . = ..() if(merge) for(var/obj/item/stack/S in loc) @@ -189,7 +192,7 @@ return FALSE if((strict_color_stacking || other.strict_color_stacking) && (color != other.color)) return FALSE - return other.stacktype == stacktype + return other.stacktype_legacy == stacktype_legacy /obj/item/stack/proc/use(used) if (!can_use(used)) @@ -424,3 +427,25 @@ return FALSE update_icon() return TRUE + +//* Types *// + +/** + * Get our 'use as type'. + */ +/obj/item/stack/proc/get_use_as_type() + return stack_type || type + +/** + * We can be used as a specific stack type. + */ +/obj/item/stack/proc/can_use_as_type(path) + return stack_type == path || type == path + +/** + * Can merge into a type + * + * todo: use this instead of raw stacktype_legacy checks + */ +/obj/item/stack/proc/can_merge_into_type(path) + CRASH("Not implemented.") diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm index 3f0955fd54b..b0b1e5db320 100644 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ b/code/game/objects/items/stacks/tiles/tile_types.dm @@ -87,8 +87,8 @@ desc = "A device that makes wood floor tiles." uses_charge = 1 charge_costs = list(250) - stacktype = /obj/item/stack/tile/wood - build_type = /obj/item/stack/tile/wood + stack_type = /obj/item/stack/tile/wood + stacktype_legacy = /obj/item/stack/tile/wood /* * Carpets @@ -298,8 +298,8 @@ materials_base = null uses_charge = 1 charge_costs = list(250) - stacktype = /obj/item/stack/tile/floor - build_type = /obj/item/stack/tile/floor + stack_type = /obj/item/stack/tile/floor + stacktype_legacy = /obj/item/stack/tile/floor /obj/item/stack/tile/floor/sandstone name = "sandstone tile" @@ -353,8 +353,8 @@ desc = "A device that makes roofing tiles." uses_charge = 1 charge_costs = list(250) - stacktype = /obj/item/stack/tile/roofing - build_type = /obj/item/stack/tile/roofing + stack_type = /obj/item/stack/tile/roofing + stacktype_legacy = /obj/item/stack/tile/roofing /obj/item/stack/tile/roofing/wood name = "wood roofing" diff --git a/code/game/objects/random/maintenance.dm b/code/game/objects/random/maintenance.dm index a2613ba2563..244aa5293f5 100644 --- a/code/game/objects/random/maintenance.dm +++ b/code/game/objects/random/maintenance.dm @@ -97,7 +97,7 @@ something, make sure it's not in one of the other lists.*/ prob(4);/obj/item/clothing/under/color/grey, prob(2);/obj/item/clothing/under/syndicate/tacticool, prob(2);/obj/item/clothing/under/pants/camo, - prob(1);/obj/item/clothing/under/harness, + prob(1);/obj/item/clothing/under/gear_harness, prob(1);/obj/item/clothing/under/tactical, prob(3);/obj/item/clothing/accessory/storage/webbing, prob(3);/obj/item/camera_assembly, diff --git a/code/game/objects/structures/loot_piles.dm b/code/game/objects/structures/loot_piles.dm index bde9d888de8..981c8140a1f 100644 --- a/code/game/objects/structures/loot_piles.dm +++ b/code/game/objects/structures/loot_piles.dm @@ -192,7 +192,7 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh /obj/item/clothing/under/color/grey, /obj/item/clothing/under/syndicate/tacticool, /obj/item/clothing/under/pants/camo, - /obj/item/clothing/under/harness, + /obj/item/clothing/under/gear_harness, /obj/item/clothing/accessory/storage/webbing, /obj/item/spacecash/c1, /obj/item/spacecash/c10, diff --git a/code/game/objects/structures/trash_pile.dm b/code/game/objects/structures/trash_pile.dm index 7532fc01b19..eab27406c2c 100644 --- a/code/game/objects/structures/trash_pile.dm +++ b/code/game/objects/structures/trash_pile.dm @@ -202,7 +202,7 @@ prob(1);/obj/item/clothing/shoes/syndigaloshes, prob(1);/obj/item/clothing/suit/bio_suit/general, prob(1);/obj/item/clothing/suit/space/emergency, - prob(1);/obj/item/clothing/under/harness, + prob(1);/obj/item/clothing/under/gear_harness, prob(1);/obj/item/clothing/under/tactical, prob(1);/obj/item/clothing/suit/armor/material/makeshift, prob(1);/obj/item/flashlight/glowstick/orange, diff --git a/code/game/objects/systems/storage/storage.dm b/code/game/objects/systems/storage/storage.dm index 32f9799907d..204b0f90876 100644 --- a/code/game/objects/systems/storage/storage.dm +++ b/code/game/objects/systems/storage/storage.dm @@ -284,7 +284,6 @@ return action_mode_switch = new(src) action_mode_switch.button_additional_only = TRUE - action_mode_switch.button_additional_overlay = parent /datum/object_system/storage/proc/grant_buttons(mob/wearer) ensure_buttons() @@ -1145,6 +1144,17 @@ /datum/action/storage_gather_mode name = "Switch Gather Mode" +/datum/action/storage_gather_mode/pre_render_hook() + if(istype(target, /datum/object_system/storage)) + var/datum/object_system/storage/storage_datum = target + var/obj/storage_target = storage_datum.parent + var/image/generated = new + generated.appearance = storage_target + generated.layer = FLOAT_LAYER + generated.plane = FLOAT_PLANE + button_additional_overlay = generated + return ..() + //? Hooks /obj/proc/object_storage_opened(mob/user) diff --git a/code/game/rendering/legacy/radial.dm b/code/game/rendering/legacy/radial.dm index 0cb587ad865..6d37d8f09e0 100644 --- a/code/game/rendering/legacy/radial.dm +++ b/code/game/rendering/legacy/radial.dm @@ -252,6 +252,10 @@ GLOBAL_LIST_EMPTY(radial_menus) //! perform fixup I.plane = FLOAT_PLANE I.layer = FLOAT_LAYER + I.maptext = MAPTEXT(I.maptext) + I.maptext_width = 64 + I.maptext_height = 32 + I.maptext_y = 32 //! end choices_icons[id] = I else diff --git a/code/game/rendering/mob.dm b/code/game/rendering/mob.dm index bfcd07a224d..b49319562e2 100644 --- a/code/game/rendering/mob.dm +++ b/code/game/rendering/mob.dm @@ -24,6 +24,8 @@ client.global_planes.apply(client) client.update_clickcatcher() client.using_perspective?.reload(client, TRUE) + client.actor_huds.reassert_onto_owner() + client.action_drawer.reassert_screen() INVOKE_ASYNC(client, TYPE_PROC_REF(/client, init_viewport_blocking)) reload_fullscreen() hud_used?.reorganize_alerts() diff --git a/code/game/turfs/simulated/floor/floor-construction.dm b/code/game/turfs/simulated/floor/floor-construction.dm index 319c589de13..d0a37d37eac 100644 --- a/code/game/turfs/simulated/floor/floor-construction.dm +++ b/code/game/turfs/simulated/floor/floor-construction.dm @@ -22,12 +22,17 @@ using_stack = with_mat_stack else var/obj/item/stack/with_stack = with_item - possible = RSflooring.build_item_lookup[with_stack.type] + possible = RSflooring.build_item_lookup[with_stack.get_use_as_type()] has_amount = with_stack.amount using_stack = with_stack - if(!length(possible)) + if(!possible) return FALSE - var/datum/prototype/flooring/trying_to_make + var/datum/prototype/flooring/trying_to_make = possible + if(force_flooring && !(trying_to_make.id == force_flooring || trying_to_make.type == force_flooring)) + return FALSE + // todo: multiple possible floorings are disabled for UI/UX reasons. put the selector on the stack + // with client-local-state sometime, and re-enable it. + /* if(force_flooring) for(var/datum/prototype/flooring/potential as anything in possible) if(potential.type == force_flooring || potential.id == force_flooring) @@ -42,16 +47,24 @@ else var/list/built_choices = list() var/list/pick_choices = list() + var/matrix/three_fourths_size = matrix() + three_fourths_size.Scale(3 / 4, 3 / 4) for(var/datum/prototype/flooring/potential as anything in possible) built_choices[potential.name] = potential var/image/preview = image(potential.icon, potential.icon_base) + preview.transform = three_fourths_size preview.maptext = MAPTEXT_CENTER(potential.name) preview.maptext_width = 64 - pick_choices[potential.name] = preview + var/use_name = potential.name + var/notch = 1 + while(pick_choices[use_name]) + use_name = "[potential.name] ([notch++])" + pick_choices[use_name] = preview var/choice_name = show_radial_menu(e_args.initiator, src, pick_choices) trying_to_make = built_choices[choice_name] if(!trying_to_make) return FALSE + */ if(trying_to_make.build_cost > has_amount) e_args.chat_feedback(SPAN_WARNING("You require at least [trying_to_make.build_cost] [with_item.name] to lay down those [trying_to_make.descriptor]")) return FALSE diff --git a/code/game/turfs/simulated/flooring/flooring.dm b/code/game/turfs/simulated/flooring/flooring.dm index 2e846cbf714..b8e70f205cf 100644 --- a/code/game/turfs/simulated/flooring/flooring.dm +++ b/code/game/turfs/simulated/flooring/flooring.dm @@ -71,6 +71,11 @@ /// /// * Supports /obj/item/stack /// * Supports /datum/material + /// + /// todo: as of right now, only a single floor can ever be allowed to be built in this way + /// for a given stack or material id. + /// at some point, we need to investigate having multiple possibilities + /// todo: remove 'subtype build_type suppression' from New() var/build_type /// Amount of material needed to build. var/build_cost = 1 @@ -162,6 +167,13 @@ dismantle_tool = dismantle_tool ? list(dismantle_tool) : list() if(!islist(destroy_tool)) destroy_tool = destroy_tool ? list(destroy_tool) : list() + // subtype build suppression + // erase our build_type if our parent type defaults to it + // this way only the first declaration on the tree of a certain build type applies + if(ispath(parent_type, /datum/prototype/flooring)) + var/datum/prototype/flooring/parent = parent_type + if(initial(parent.build_type) == build_type) + build_type = null /datum/prototype/flooring/proc/get_flooring_overlay(cache_key, base_state, icon_dir = 0, layer = FLOOR_DECAL_LAYER) if(!flooring_cache[cache_key]) diff --git a/code/game/turfs/simulated/flooring/flooring_types.dm b/code/game/turfs/simulated/flooring/flooring_types.dm index 5fa2358958e..e92d3e9be39 100644 --- a/code/game/turfs/simulated/flooring/flooring_types.dm +++ b/code/game/turfs/simulated/flooring/flooring_types.dm @@ -250,7 +250,6 @@ icon_base = "asteroidfloor" has_damage_range = null flooring_flags = TURF_REMOVE_CROWBAR - build_type = /obj/item/stack/tile/floor/steel /datum/prototype/flooring/tiling/white name = "floor" @@ -276,12 +275,10 @@ /datum/prototype/flooring/tiling/hydro name = "floor" icon_base = "hydrofloor" - build_type = /obj/item/stack/tile/floor/steel /datum/prototype/flooring/tiling/neutral name = "floor" icon_base = "neutral" - build_type = /obj/item/stack/tile/floor/steel /datum/prototype/flooring/tiling/freezer name = "floor" diff --git a/code/modules/artwork/crayon_decal_meta.dm b/code/modules/artwork/crayon_decal_meta.dm index fc1051634f7..3b9227a8eb1 100644 --- a/code/modules/artwork/crayon_decal_meta.dm +++ b/code/modules/artwork/crayon_decal_meta.dm @@ -74,11 +74,17 @@ GLOBAL_LIST_EMPTY(crayon_data_lookup_by_string_icon_path) var/centering_pixel_y /datum/crayon_decal_meta/proc/tgui_crayon_data() + //! uh oh! byond alert! !// + //! associative lists are contagious and we really need a flat list or tgui crashes! !// + //! manually flatten it. !// + var/list/i_really_dislike_byond = list() + for(var/key in states) + i_really_dislike_byond += key + return list( "name" = name, - "states" = states, + "states" = i_really_dislike_byond, "width" = width, "height" = height, "id" = id, ) - diff --git a/code/modules/artwork/items/crayon.dm b/code/modules/artwork/items/crayon.dm index 30acd4e54bc..9cc2db19343 100644 --- a/code/modules/artwork/items/crayon.dm +++ b/code/modules/artwork/items/crayon.dm @@ -10,6 +10,7 @@ pen_color = "#FF0000" //RGB clickable = FALSE + // todo: reorganize vars /// color name var/crayon_color_name = "red" /// what we show as; e.g. 'crayon', 'marker' @@ -35,6 +36,7 @@ /// can eat var/crayon_edible = TRUE + // todo: per user this so you can't see what someone else was about to do lmao /// currently picked datapack string path var/current_graffiti_icon_string_path /// currently picked datapack icon state diff --git a/code/modules/clothing/accessories/halo.dm b/code/modules/clothing/accessories/halo.dm index de07cf47854..6ea632337d7 100644 --- a/code/modules/clothing/accessories/halo.dm +++ b/code/modules/clothing/accessories/halo.dm @@ -16,12 +16,12 @@ generate_styles() AddElement(/datum/element/clothing/dynamic_recolor) -/obj/item/clothing/accessory/halo_projector/available_styles(mob/user) +/obj/item/clothing/accessory/halo_projector/style_repick_query(mob/user) . = ..() for(var/halo_name in global_halo_styles) .[halo_name] = global_halo_styles[halo_name] -/obj/item/clothing/accessory/halo_projector/set_style(style, mob/user) +/obj/item/clothing/accessory/halo_projector/style_repick_set(style, mob/user) . = ..() if(.) return diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 8d2de2bcc9d..e76f2ed187b 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -231,25 +231,29 @@ else icon = initial(icon) -//? styles +//* Style Repicking *// /** * returns available styles as name = state or image or mutable_appearance */ -/obj/item/clothing/proc/available_styles(mob/user) +/obj/item/clothing/proc/style_repick_query(mob/user) + SHOULD_NOT_SLEEP(TRUE) . = list() /** * sets us to a specific style + * + * * do not update_icon() or update_worn_icon() in here, we do that automatically. */ -/obj/item/clothing/proc/set_style(style, mob/user) +/obj/item/clothing/proc/style_repick_set(style, mob/user) + SHOULD_NOT_SLEEP(TRUE) return FALSE /** * prompts a user to pick style */ -/obj/item/clothing/proc/pick_style(mob/user) - var/list/available = available_styles(user) +/obj/item/clothing/proc/style_repick_open(mob/user) + var/list/available = style_repick_query(user) var/list/assembled = list() for(var/name in available) var/using = available[name] @@ -272,9 +276,16 @@ var/choice = show_radial_menu(user, loc == user ? user : src, assembled, radius = 48) if(isnull(choice)) return - set_style(choice, user) + if(!style_repick_set(choice, user)) + return + // todo: logging API + to_chat(user, SPAN_NOTICE("You set [src]'s style to [choice].")) + log_game("[key_name(user)] set [src]'s style to [choice]") + update_icon() + update_worn_icon() -/obj/item/clothing/verb/pick_style_verb() +// todo: context menu this instead +/obj/item/clothing/verb/style_repick_verb() set name = "Set Worn Style" set category = VERB_CATEGORY_IC set desc = "Wear this piece of clothing in a different style." @@ -284,4 +295,4 @@ usr.action_feedback(SPAN_WARNING("You can't do that right now!"), src) return - pick_style(usr) + style_repick_open(usr) diff --git a/code/modules/clothing/under/_under.dm b/code/modules/clothing/under/_under.dm index f7ce6de2bdf..1110856226e 100644 --- a/code/modules/clothing/under/_under.dm +++ b/code/modules/clothing/under/_under.dm @@ -96,7 +96,7 @@ //? Styles -/obj/item/clothing/under/available_styles(mob/user) +/obj/item/clothing/under/style_repick_query(mob/user) . = list() var/old_roll = worn_rolled_down var/old_sleeves = worn_rolled_sleeves @@ -114,7 +114,7 @@ worn_rolled_down = old_roll worn_rolled_sleeves = old_sleeves -/obj/item/clothing/under/set_style(style, mob/user) +/obj/item/clothing/under/style_repick_set(style, mob/user) . = ..() if(.) return diff --git a/code/modules/clothing/under/gear_harness.dm b/code/modules/clothing/under/gear_harness.dm new file mode 100644 index 00000000000..1b47733b5d5 --- /dev/null +++ b/code/modules/clothing/under/gear_harness.dm @@ -0,0 +1,25 @@ +/obj/item/clothing/under/gear_harness + name = "gear harness" + desc = "How... minimalist." + icon_state = "gear_harness" + body_cover_flags = NONE + +/obj/item/clothing/under/gear_harness/style_repick_query(mob/user) + . = ..() + var/image/normal_image = image(icon, "gear_harness") + normal_image.maptext = "normal" + .["normal"] = normal_image + var/image/invisible_image = image('icons/system/blank_32x32.dmi', "") + invisible_image.maptext = "invisible" + .["invisible"] = invisible_image + +/obj/item/clothing/under/gear_harness/style_repick_set(style, mob/user) + switch(style) + if("normal") + worn_render_flags = initial(worn_render_flags) + return TRUE + if("invisible") + worn_render_flags |= WORN_RENDER_SLOT_NO_RENDER + return TRUE + else + return FALSE diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 88fc5e8f779..ab14cd390f5 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -724,12 +724,6 @@ icon_state = "cuttop_red" item_state_slots = list(SLOT_ID_RIGHT_HAND = "red", SLOT_ID_LEFT_HAND = "red") -/obj/item/clothing/under/harness - name = "gear harness" - desc = "How... minimalist." - icon_state = "gear_harness" - body_cover_flags = 0 - /obj/item/clothing/under/dress/white name = "white wedding dress" desc = "A fancy white dress with a blue underdress." diff --git a/code/modules/frames/frame_step.dm b/code/modules/frames/frame_step.dm index 0c3c6c35119..5b40f8dc3cb 100644 --- a/code/modules/frames/frame_step.dm +++ b/code/modules/frames/frame_step.dm @@ -30,6 +30,11 @@ var/request_type /// ergo: stack type, item type, tool function, etc. what this is depends on [step_type] /// limited autodetection is allowed. + /// + /// allowed: + /// * /datum/prototype/material path + /// * /obj/item/stack path + /// * /obj/item path var/request /// * stacks: amount /// * items: amount; if 0, we just apply the item to it @@ -157,11 +162,12 @@ /datum/frame_step/proc/valid_interaction(datum/event_args/actor/actor, obj/item/using_tool, datum/frame2/frame_datum, obj/structure/frame2/frame) switch(request_type) if(FRAME_REQUEST_TYPE_INTERACT) - return TRUE + return isnull(using_tool) if(FRAME_REQUEST_TYPE_ITEM) return using_tool?.type == request if(FRAME_REQUEST_TYPE_STACK) - return using_tool?.type == request + var/obj/item/stack/using_stack = using_tool + return using_stack.can_use_as_type(request) if(FRAME_REQUEST_TYPE_PROC) return FALSE // override this proc if(FRAME_REQUEST_TYPE_TOOL) diff --git a/code/modules/frames/types/fire_alarm.dm b/code/modules/frames/types/fire_alarm.dm index 03f5797e8e8..c35f319481f 100644 --- a/code/modules/frames/types/fire_alarm.dm +++ b/code/modules/frames/types/fire_alarm.dm @@ -46,7 +46,7 @@ AUTO_FRAME_DATUM(/datum/frame2/fire_alarm, fire_alarm, 'icons/machinery/fire_ala steps = list( /datum/frame_step{ request = /obj/item/stack/cable_coil; - name = "unsecure circuit"; + name = "wire circuit"; request_amount = 1; stage = "wired"; direction = TOOL_DIRECTION_FORWARDS; diff --git a/code/modules/loadout/loadout_xeno.dm b/code/modules/loadout/loadout_xeno.dm index 3e961c1bb9d..94105322a1b 100644 --- a/code/modules/loadout/loadout_xeno.dm +++ b/code/modules/loadout/loadout_xeno.dm @@ -1044,4 +1044,4 @@ /datum/loadout_entry/xeno/uniform name = "Generic - Gear Harness" - path = /obj/item/clothing/under/harness + path = /obj/item/clothing/under/gear_harness diff --git a/code/modules/materials/material_sheets.dm b/code/modules/materials/material_sheets.dm index 8fea3c15a16..2684f9c1c40 100644 --- a/code/modules/materials/material_sheets.dm +++ b/code/modules/materials/material_sheets.dm @@ -51,7 +51,7 @@ pixel_x = rand(0,4)-4 pixel_y = rand(0,4)-4 - stacktype = src.material.stack_type + stacktype_legacy = src.material.stack_type if(islist(src.material.stack_origin_tech)) origin_tech = src.material.stack_origin_tech.Copy() diff --git a/code/modules/materials/material_synth.dm b/code/modules/materials/material_synth.dm index ad5b16c35ec..8acd60ee9c2 100644 --- a/code/modules/materials/material_synth.dm +++ b/code/modules/materials/material_synth.dm @@ -15,25 +15,31 @@ /obj/item/stack/material/cyborg/plastic icon_state = "sheet-plastic" + stack_type = /obj/item/stack/material/plastic material = /datum/prototype/material/plastic /obj/item/stack/material/cyborg/steel icon_state = "sheet-metal" + stack_type = /obj/item/stack/material/steel material = /datum/prototype/material/steel /obj/item/stack/material/cyborg/plasteel icon_state = "sheet-plasteel" + stack_type = /obj/item/stack/material/plasteel material = /datum/prototype/material/plasteel /obj/item/stack/material/cyborg/wood icon_state = "sheet-wood" + stack_type = /obj/item/stack/material/wood material = /datum/prototype/material/wood_plank /obj/item/stack/material/cyborg/glass icon_state = "sheet-glass" + stack_type = /obj/item/stack/material/glass material = /datum/prototype/material/glass /obj/item/stack/material/cyborg/glass/reinforced icon_state = "sheet-rglass" + stack_type = /obj/item/stack/material/glass/reinforced material = /datum/prototype/material/glass/reinforced charge_costs = list(500, 1000) diff --git a/code/modules/mining/tools/vertibore.dm b/code/modules/mining/tools/vertibore.dm index eb2319b9171..692b1ed1d89 100644 --- a/code/modules/mining/tools/vertibore.dm +++ b/code/modules/mining/tools/vertibore.dm @@ -27,7 +27,7 @@ if(cell) to_chat(user, "\The [src] already has \a [cell] installed.") return - if(!user.attempt_insert_item_for_installation(cell, src)) + if(!user.attempt_insert_item_for_installation(thing, src)) return cell = thing playsound(loc, 'sound/machines/click.ogg', 10, 1) diff --git a/code/modules/mob/animations.dm b/code/modules/mob/animations.dm index 24ea11d5c45..e9facbae81f 100644 --- a/code/modules/mob/animations.dm +++ b/code/modules/mob/animations.dm @@ -46,18 +46,21 @@ note dizziness decrements automatically in the mob's Life() proc. jitteriness = min(1000, jitteriness + amount) // store what will be new value // clamped to max 1000 - if(jitteriness > 100 && !is_jittery) + + var/effective_jitteriness = get_effective_impairment_power_jitter() + if(effective_jitteriness > 100 && !is_jittery) spawn(0) jittery_process() - /mob/proc/jittery_process() if(IS_DEAD(src))//Dead people dont twitch around return is_jittery = 1 - while(jitteriness > 100) - var/amplitude = min(4, jitteriness / 100) + var/effective_jitteriness = get_effective_impairment_power_jitter() + while(effective_jitteriness > 100) + effective_jitteriness = get_effective_impairment_power_jitter() + var/amplitude = min(4, effective_jitteriness / 100) pixel_x = get_managed_pixel_x() + rand(-amplitude, amplitude) pixel_y = get_managed_pixel_y() + rand(-amplitude/3, amplitude/3) diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 8d423b44b08..9a5244888f5 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -273,11 +273,12 @@ //Jitters if(is_jittery) - if(jitteriness >= 300) + var/effective_jitteriness = get_effective_impairment_power_jitter() + if(effective_jitteriness >= 300) . += SPAN_DANGER("[T.He] [T.is] convulsing violently!") - else if(jitteriness >= 200) + else if(effective_jitteriness >= 200) . += SPAN_WARNING("[T.He] [T.is] extremely jittery.") - else if(jitteriness >= 100) + else if(effective_jitteriness >= 100) . += SPAN_WARNING("[T.He] [T.is] twitching ever so slightly.") //splints diff --git a/code/modules/mob/living/carbon/human/human-defense.dm b/code/modules/mob/living/carbon/human/human-defense.dm index dd8ec528930..20dcc1ab071 100644 --- a/code/modules/mob/living/carbon/human/human-defense.dm +++ b/code/modules/mob/living/carbon/human/human-defense.dm @@ -33,7 +33,7 @@ /mob/living/carbon/human/slip_act(slip_class, source, hard_strength, soft_strength, suppressed) var/footcoverage_check = length(inventory.query_coverage(FEET)) - var/obj/item/shoes = inventory.get_slot(/datum/inventory_slot/inventory/shoes) + var/obj/item/shoes = inventory.get_slot_single(/datum/inventory_slot/inventory/shoes) if(((species.species_flags & NO_SLIP) && !footcoverage_check) || (shoes && (shoes.clothing_flags & NOSLIP))) //Footwear negates a species' natural traction. return 0 return ..() diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 251cfc5f004..d5e89635d87 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -66,7 +66,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) /mob/living/carbon/human/apply_transform(matrix/to_apply) var/anim_time = CHECK_MOBILITY(src, MOBILITY_CAN_STAND)? 3 : 1 - animate(src, transform = to_apply, time = anim_time, flags = ANIMATION_PARALLEL) + animate(src, transform = to_apply, time = anim_time, flags = ANIMATION_PARALLEL | ANIMATION_LINEAR_TRANSFORM) update_icon_special() //May contain transform-altering things update_ssd_overlay() diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 62cc2e737e8..069d93070ef 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -605,7 +605,7 @@ default behaviour is: return applying /mob/living/apply_transform(matrix/to_apply) - animate(src, transform = to_apply, time = 1 SECONDS) + animate(src, transform = to_apply, time = 1 SECONDS, flags = ANIMATION_LINEAR_TRANSFORM | ANIMATION_PARALLEL) update_ssd_overlay() // This handles setting the client's color variable, which makes everything look a specific color. diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 16d78b94b22..71ebc1b8723 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -109,11 +109,11 @@ var/list/channel_to_radio_key = new verb = pick("yells","roars","hollers") whispering = 0 . = 1 - if(slurring) + if(get_effective_impairment_power_slurring()) message = slur(message) verb = pick("slobbers","slurs") . = 1 - if(stuttering) + if(get_effective_impairment_power_stutter()) message = stutter(message) verb = pick("stammers","stutters") . = 1 diff --git a/code/modules/mob/mob-status_procs.dm b/code/modules/mob/mob-status_procs.dm new file mode 100644 index 00000000000..83935e06c82 --- /dev/null +++ b/code/modules/mob/mob-status_procs.dm @@ -0,0 +1,36 @@ +//* This file is explicitly licensed under the MIT license. *// +//* Copyright (c) 2025 Citadel Station Developers *// + +//* Impairments *// + +// hey! listen +// if you're thinking about find-replacing checks for the var with this +// well fucking don't +// +// the reason this is separate from main vars for these things +// is because people keep abusing vars to implement features that have a +// ton of unintended side effects +// +// these should only be used for the actual effects; it is **not** +// allowed to use for any other effects like xenochimera feral, +// traumatic shock, etc + +// todo: /datum/mob_impairment ? + +/mob/proc/get_effective_impairment_power_slurring() + . = slurring + var/datum/component/mob_feign_impairment/slurring/feigned = GetComponent(/datum/component/mob_feign_impairment/slurring) + if(feigned) + . = max(., feigned.power) + +/mob/proc/get_effective_impairment_power_jitter() + . = jitteriness + var/datum/component/mob_feign_impairment/jitter/feigned = GetComponent(/datum/component/mob_feign_impairment/jitter) + if(feigned) + . = max(., feigned.power) + +/mob/proc/get_effective_impairment_power_stutter() + . = stuttering + var/datum/component/mob_feign_impairment/stutter/feigned = GetComponent(/datum/component/mob_feign_impairment/stutter) + if(feigned) + . = max(., feigned.power) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 9e30f2992a7..c2021320c78 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1,3 +1,8 @@ +/mob + //* Impairments *// + /// active feign_impairment types + /// * lazy list + var/list/impairments_feigned /** * Intialize a mob diff --git a/code/modules/mob/verbs/feign_impairment.dm b/code/modules/mob/verbs/feign_impairment.dm new file mode 100644 index 00000000000..dd7a3ab8ff4 --- /dev/null +++ b/code/modules/mob/verbs/feign_impairment.dm @@ -0,0 +1,105 @@ +//* This file is explicitly licensed under the MIT license. *// +//* Copyright (c) 2025 Citadel Station Developers *// + +GLOBAL_LIST_INIT(feign_impairment_types, init_feign_impairment_types()) + +/proc/init_feign_impairment_types() + . = list() + var/list/component_collision_check = list() + for(var/datum/feign_impairment/path as anything in subtypesof(/datum/feign_impairment)) + if(initial(path.abstract_type) == path) + continue + var/datum/feign_impairment/instance = new path + if(component_collision_check[instance.component_type]) + stack_trace("collision between [component_collision_check[instance.component_type]:type] and [instance.type] on component type [instance.component_type]") + continue + component_collision_check[instance.component_type] = instance + .[path] = instance + +// todo: this is better than the old, but still a dumpster fire. impairments +// need to be datums so we can have a single tracking system +// and a single /datum/component/mob_feign_impairment +// to track everything, instead of this crap. + +/datum/feign_impairment + abstract_type = /datum/feign_impairment + var/name + var/adjective + var/component_type + var/power_min = 0 + var/power_max = 0 + +/datum/feign_impairment/slurring + name = "Slurring" + adjective = "slurring" + component_type = /datum/component/mob_feign_impairment/slurring + power_min = 10 + power_max = 500 + +/datum/feign_impairment/stutter + name = "Stuttering" + adjective = "stuttering" + component_type = /datum/component/mob_feign_impairment/stutter + power_min = 10 + power_max = 500 + +/datum/feign_impairment/jitter + name = "Jittering" + adjective = "jittering" + component_type = /datum/component/mob_feign_impairment/jitter + power_min = 10 + power_max = 2000 + +// todo: DECLARE_MOB_VERB +/mob/verb/feign_impairment() + set name = "Feign Impairment" + set category = VERB_CATEGORY_IC + set desc = "Pretend like you're slurring, stuttering, jittering, and more." + + var/list/name_to_type = list() + for(var/datum/feign_impairment/path as anything in subtypesof(/datum/feign_impairment)) + if(initial(path.abstract_type) == path) + continue + var/is_active = impairments_feigned?[path] + name_to_type["[initial(path.name)] (Currently: [is_active ? "Active" : "Inactive"])"] = path + + var/choice = tgui_input_list(src, "Choose an impairment to toggle.", "Feign Impairment", name_to_type) + if(!choice) + return + + var/path = name_to_type[choice] + var/new_active = !impairments_feigned?[path] + var/datum/feign_impairment/impairment = GLOB.feign_impairment_types[path] + + var/power + + if(new_active) + if(GetComponent(impairment.component_type)) + to_chat(src, SPAN_WARNING("You are already pretending to be [impairment.adjective].")) + return + power = tgui_input_number( + src, + "What power? ([impairment.power_min] - [impairment.power_max])", + "Feign Impairment", + impairment.power_min, + impairment.power_max, + impairment.power_min, + round_value = TRUE, + ) + else + if(!GetComponent(impairment.component_type)) + return + + // todo: better logging + log_game("[key_name(src)] toggled [impairment] to [new_active ?"on, with power [power]" : "off"]") + + if(new_active) + AddComponent(impairment.component_type, power) + else + qdel(GetComponent(impairment.component_type)) + + to_chat(src, SPAN_NOTICE("You are now [new_active ? "pretending" : "no longer pretending"] to be [impairment.adjective]. This will be automatically reset should you lose consciousness.")) + +/mob/proc/clear_feign_impairment() + QDEL_LIST_ASSOC_VAL(impairments_feigned) + impairments_feigned = null diff --git a/code/modules/mob/verbs/horizontal_invert_self.dm b/code/modules/mob/verbs/horizontal_invert_self.dm index 09adab8dbc5..57b55fd188f 100644 --- a/code/modules/mob/verbs/horizontal_invert_self.dm +++ b/code/modules/mob/verbs/horizontal_invert_self.dm @@ -1,6 +1,7 @@ //* This file is explicitly licensed under the MIT license. *// //* Copyright (c) 2024 Citadel Station Developers *// +// todo: DECLARE_MOB_VERB /mob/verb/horizontal_invert_self() set name = "Invert Yourself (Horizontal)" set desc = "Mirror your sprite across the N-S axis." diff --git a/code/modules/mob/verbs/vertical_invert_self.dm b/code/modules/mob/verbs/vertical_invert_self.dm new file mode 100644 index 00000000000..9b179d98fe0 --- /dev/null +++ b/code/modules/mob/verbs/vertical_invert_self.dm @@ -0,0 +1,24 @@ +//* This file is explicitly licensed under the MIT license. *// +//* Copyright (c) 2025 Citadel Station Developers *// + +// todo: DECLARE_MOB_VERB +/mob/verb/vertical_invert_self() + set name = "Invert Yourself (Vertical)" + set desc = "Mirror your sprite across the N-S axis." + set category = VERB_CATEGORY_IC + + // todo: remote control? mobs that don't allow it? + + if(TIMER_COOLDOWN_CHECK(src, CD_INDEX_MOB_VERB_INVERT_SELF)) + // todo: don't usr lol + to_chat(usr, SPAN_WARNING("You can't do that yet!")) + return + TIMER_COOLDOWN_START(src, CD_INDEX_MOB_VERB_INVERT_SELF, 0.5 SECONDS) + + log_game("[key_name(usr)] invoked vertical_invert_self on [key_name(src)].") + + var/datum/component/mob_self_vertical_inversion/inversion = GetComponent(/datum/component/mob_self_vertical_inversion) + if(inversion) + qdel(inversion) + else + AddComponent(/datum/component/mob_self_vertical_inversion) diff --git a/code/modules/multiz/atom-z_fall.dm b/code/modules/multiz/atom-z_fall.dm new file mode 100644 index 00000000000..6f06a7b9eb4 --- /dev/null +++ b/code/modules/multiz/atom-z_fall.dm @@ -0,0 +1,29 @@ +//* This file is explicitly licensed under the MIT license. *// +//* Copyright (c) 2025 Citadel Station Developers *// + +/** + * Stops a thing from falling through this + * + * * If said thing is asking while falling, the first thing to return this will be what gets on_z_impacted'd. + * + * @params + * * victim - thing trying to fall through us + * * levels - levels fallen so far, preventing a fall in the first place has this at 0, breaking a falling object from z2 to z1's floor would be 1, etc. + * * fall_flags - see __DEFINES/mapping/multiz.dm + */ +/atom/proc/prevent_z_fall(atom/movable/victim, levels = 0, fall_flags) + return fall_flags + +/** + * Called when a thing falls onto us. + * + * * Only called if something is falling; if we prevent the fall in the first place, this never gets called + * + * @params + * * victim - thing trying to fall through us + * * levels - levels fallen so far, preventing a fall in the first place has this at 0, breaking a falling object from z2 to z1's floor would be 1, etc. + * * fall_flags - see __DEFINES/mapping/multiz.dm + * * direct_hit - we're the thing actually landed on. + */ +/atom/proc/on_z_impacted(atom/movable/victim, levels, fall_flags, direct_hit) + return fall_flags diff --git a/code/modules/multiz/atoms.dm b/code/modules/multiz/atom-z_move.dm similarity index 92% rename from code/modules/multiz/atoms.dm rename to code/modules/multiz/atom-z_move.dm index 5abbda59d9a..bfafd6552c3 100644 --- a/code/modules/multiz/atoms.dm +++ b/code/modules/multiz/atom-z_move.dm @@ -1,5 +1,5 @@ //* This file is explicitly licensed under the MIT license. *// -//* Copyright (c) 2023 Citadel Station developers. *// +//* Copyright (c) 2025 Citadel Station Developers *// /** * returns if an atom can enter our tile from a multiz move diff --git a/code/modules/multiz/core.dm b/code/modules/multiz/core.dm index 5d16359cd4b..fd8ce02a737 100644 --- a/code/modules/multiz/core.dm +++ b/code/modules/multiz/core.dm @@ -1,5 +1,5 @@ //* This file is explicitly licensed under the MIT license. *// -//* Copyright (c) 2023 Citadel Station developers. *// +//* Copyright (c) 2025 Citadel Station Developers *// /** * This is the basic get multiz step. diff --git a/code/modules/multiz/falling.dm b/code/modules/multiz/falling.dm deleted file mode 100644 index 7e671e085d1..00000000000 --- a/code/modules/multiz/falling.dm +++ /dev/null @@ -1,15 +0,0 @@ -//* This file is explicitly licensed under the MIT license. *// -//* Copyright (c) 2023 Citadel Station developers. *// - -/** - * Stops a thing from falling through this - * - * If said thing is asking while falling, the first thing to return this will be what gets ZImpact'd. - * - * @params - * - victim - thing trying to fall through us - * - levels - levels fallen so far, preventing a fall in the first place has this at 0, breaking a falling object from z2 to z1's floor would be 1, etc. - * - fall_flags - see __DEFINES/mapping/multiz.dm - */ -/atom/proc/prevent_z_fall(atom/movable/victim, levels = 0, fall_flags) - return fall_flags diff --git a/code/modules/multiz/movement.dm b/code/modules/multiz/movement.dm index 907f3d5a410..85479fe8b69 100644 --- a/code/modules/multiz/movement.dm +++ b/code/modules/multiz/movement.dm @@ -309,18 +309,12 @@ var/obj/structure/stairs/stairs = locate() in landing if(!stairs) // Now lets move there! - // todo: this should not use Move - if(!Move(landing)) + if(!forceMove(landing)) return 1 var/atom/A = find_fall_target(oldloc, landing) if(special_fall_handle(A) || !A || !A.check_z_impact(src)) return - var/mob/drop_mob = locate(/mob, landing) - if(drop_mob && !(drop_mob == src) && ismob(drop_mob) && isliving(drop_mob)) //Shitload of checks. This is because the game finds various ways to screw me over. - var/mob/living/drop_living = drop_mob - if(drop_living.dropped_onto(src)) - return fall_impact(A) else locationTransitForceMove(landing) @@ -343,6 +337,8 @@ // First hit objects in the turf! for(var/atom/movable/A in landing) + if(A.atom_flags & (ATOM_NONWORLD | ATOM_ABSTRACT)) + continue if(A != src && A.CheckFall(src)) return A @@ -360,7 +356,7 @@ // CheckFall landing.fall_impact(src) //! ## THE FALLING PROCS ### - +// todo: rework falling :/ /** * Called on everything that falling_atom might hit. @@ -375,6 +371,8 @@ * If you are hit: how is it handled. * Return TRUE if the generic fall_impact should be called. * Return FALSE if you handled it yourself or if there's no effect from hitting you. + * + * todo: this is a legacy proc */ /atom/proc/check_z_impact(atom/movable/falling_atom) return TRUE @@ -386,16 +384,19 @@ * damage_max is the largest amount of damage a thing (currently only mobs and mechs) will take from falling. * If silent is True, the proc won't play sound or give a message. * If planetary is True, it's harder to stop the fall damage. + * + * todo: rework everything lmao */ /atom/movable/proc/fall_impact(atom/hit_atom, damage_min = 0, damage_max = 10, silent = FALSE, planetary = FALSE) if(!silent) visible_message("\The [src] falls from above and slams into \the [hit_atom]!", "You hear something slam into \the [hit_atom].") for(var/atom/movable/A in src.contents) + if(A.atom_flags & (ATOM_NONWORLD | ATOM_ABSTRACT)) + continue A.fall_impact(hit_atom, damage_min, damage_max, silent = TRUE) for(var/mob/M in buckled_mobs) M.fall_impact(hit_atom, damage_min, damage_max, silent, planetary) - /// Take damage from falling and hitting the ground. /mob/living/fall_impact(atom/hit_atom, damage_min = 0, damage_max = 5, silent = FALSE, planetary = FALSE) var/turf/landing = get_turf(hit_atom) @@ -419,15 +420,15 @@ if(!silent) if(planetary) visible_message( - SPAN_USERDANGER("\A [src] falls out of the sky and crashes into \the [landing]!"), - SPAN_USERDANGER("You fall out of the sky and crash into \the [landing]!"), + SPAN_USERDANGER("\A [src] falls out of the sky and crashes into [landing]!"), + SPAN_USERDANGER("You fall out of the sky and crash into [landing]!"), SPAN_HEAR("You hear something slam into \the [landing]."), ) var/turf/T = get_turf(landing) explosion(T, 0, 1, 2) else visible_message( - SPAN_WARNING("\The [src] falls from above and slams into \the [landing]!"), + SPAN_WARNING("\The [src] falls from above and slams into [landing]!"), SPAN_DANGER("You fall off and hit \the [landing]!"), SPAN_HEAR("You hear something slam into \the [landing]."), ) @@ -437,7 +438,7 @@ // Hits 10 times, because apparently targeting individual limbs lets certain species survive the fall from atmosphere for(var/i = 1 to 10) adjustBruteLoss(rand(damage_min, damage_max)) - afflict_paralyze(20 * 4) + afflict_paralyze(8 SECONDS) update_health() /mob/living/carbon/human/fall_impact(atom/hit_atom, damage_min, damage_max, silent, planetary) @@ -563,12 +564,9 @@ var/turf/simulated/floor/ground = hit_atom ground.break_tile() - +// todo: rewrite this entire file /mob/CheckFall(atom/movable/falling_atom) return falling_atom.fall_impact(src) -//! I didn't feel like removing @silicons' check in handle_fall(). @Zandario -/mob/living/proc/dropped_onto(atom/hit_atom) - if(!isliving(hit_atom)) - return FALSE - return TRUE +/mob/observer/CheckFall(atom/movable/falling_atom) + return FALSE diff --git a/code/modules/multiz/turf-multiz_misc.dm b/code/modules/multiz/turf-multiz_misc.dm new file mode 100644 index 00000000000..6cfecc5af46 --- /dev/null +++ b/code/modules/multiz/turf-multiz_misc.dm @@ -0,0 +1,52 @@ +//* This file is explicitly licensed under the MIT license. *// +//* Copyright (c) 2025 Citadel Station Developers *// + +// todo: redo +/turf/CheckFall(atom/movable/falling_atom) + if(!(mz_flags & MZ_OPEN_DOWN)) + return TRUE // impact! + return ..() + +//* lookups + +/turf/proc/above() + RETURN_TYPE(/turf) + return locate(x, y, SSmapping.cached_level_up[z]) + +/turf/proc/below() + RETURN_TYPE(/turf) + return locate(x, y, SSmapping.cached_level_down[z]) + +/** + * This is the basic get multiz step. + * It will not look across lateral transitions, only up/down. + */ +/turf/proc/vertical_step(dir) + RETURN_TYPE(/turf) + if((dir & (UP|DOWN)) == 0) + return get_step(src, dir) + else if(dir & UP) + return get_step(locate(x, y, SSmapping.cached_level_up[z]), dir & ~(UP)) + else if(dir & DOWN) + return get_step(locate(x, y, SSmapping.cached_level_down[z]), dir & ~(DOWN)) + CRASH("how did we get here?") + +/** + * Basic multiz get dir + * Will not look across lateral transitions, only directly up/down. + */ +/turf/proc/vertical_dir(turf/other) + if(other.z == z) + return get_dir(src, other) + else if(other.z == SSmapping.cached_level_up[z]) + return get_dir(src, other) | UP + else if(other.z == SSmapping.cached_level_down[z]) + return get_dir(src, other) | DOWN + +/** + * This is the full get multiz step. + * It will look across lateral transitions and other struct magic. + */ +/turf/proc/virtual_step(dir) + RETURN_TYPE(/turf) + return SSmapping.get_virtual_step(src, dir) diff --git a/code/modules/multiz/turf-z_fall.dm b/code/modules/multiz/turf-z_fall.dm new file mode 100644 index 00000000000..6e501a85323 --- /dev/null +++ b/code/modules/multiz/turf-z_fall.dm @@ -0,0 +1,38 @@ +//* This file is explicitly licensed under the MIT license. *// +//* Copyright (c) 2025 Citadel Station Developers *// + +/** + * simple boolean check to see if something's physically blocked from leaving us via up/down + * + * @params + * - mover - atom that needs to move + * - dir - are they going UP abov eus or DOWN below us? + */ +/turf/proc/z_exit_check(atom/movable/mover, dir) + // we assume dir is up/down because why wouldn't it be + var/turf/dest + if(dir == UP) + dest = above() + return dest && !z_pass_out_obstruction(mover, UP, dest) && !dest.z_pass_in_obstruction(mover, DOWN, src) + else if(dir == DOWN) + dest = below() + return dest && !z_pass_out_obstruction(mover, DOWN, dest) && !dest.z_pass_in_obstruction(mover, UP, src) + CRASH("Non-vertical direction '[dir]' passed in.") + +/** + * checks what is going to block something from falling through us + */ +/turf/proc/z_fall_obstruction(atom/movable/mover, levels, fall_flags) + for(var/atom/movable/AM as anything in contents) + if(AM.prevent_z_fall(mover, levels, fall_flags)) + return AM + +/** + * simple boolean check to see if something's physically blocked from falling through us + * + * * checked in addition to z_exit_check. + */ +/turf/proc/z_fall_check(atom/movable/mover, levels, fall_flags) + if(!(mz_flags & MZ_OPEN_DOWN)) + return FALSE + return isnull(z_fall_obstruction(mover, levels, fall_flags)) diff --git a/code/modules/multiz/turf.dm b/code/modules/multiz/turf-z_move.dm similarity index 52% rename from code/modules/multiz/turf.dm rename to code/modules/multiz/turf-z_move.dm index e35652e4e2b..239c2f06357 100644 --- a/code/modules/multiz/turf.dm +++ b/code/modules/multiz/turf-z_move.dm @@ -1,5 +1,11 @@ //* This file is explicitly licensed under the MIT license. *// -//* Copyright (c) 2023 Citadel Station developers. *// +//* Copyright (c) 2025 Citadel Station Developers *// + +/turf/z_pass_in(atom/movable/AM, dir, turf/old_loc) + return isnull(z_pass_in_obstruction(AM, dir, old_loc)) + +/turf/z_pass_out(atom/movable/AM, dir, turf/new_loc) + return isnull(z_pass_out_obstruction(AM, dir, new_loc)) /** * WARNING: This proc is unique. Read the doc here, especially the return value. @@ -65,94 +71,4 @@ else if(dir == DOWN) dest = below() return dest && (z_pass_out_obstruction(mover, DOWN, dest) || dest.z_pass_in_obstruction(mover, UP, src)) - CRASH("What?") - -/** - * simple boolean check to see if something's physically blocked from leaving us via up/down - * - * @params - * - mover - atom that needs to move - * - dir - are they going UP abov eus or DOWN below us? - */ -/turf/proc/z_exit_check(atom/movable/mover, dir) - // we assume dir is up/down because why wouldn't it be - var/turf/dest - if(dir == UP) - dest = above() - return dest && !z_pass_out_obstruction(mover, UP, dest) && !dest.z_pass_in_obstruction(mover, DOWN, src) - else if(dir == DOWN) - dest = below() - return dest && !z_pass_out_obstruction(mover, DOWN, dest) && !dest.z_pass_in_obstruction(mover, UP, src) - CRASH("What?") - -/** - * checks what is going to block something from falling through us - */ -/turf/proc/z_fall_obstruction(atom/movable/mover, levels, fall_flags) - for(var/atom/movable/AM as anything in contents) - if(AM.prevent_z_fall(mover, levels, fall_flags)) - return AM - -/** - * simple boolean check to see if something's physically blocked from falling through us - */ -/turf/proc/z_fall_check(atom/movable/mover, levels, fall_flags) - if(!(mz_flags & MZ_OPEN_DOWN)) - return FALSE - return isnull(z_fall_obstruction(mover, levels, fall_flags)) - -/turf/z_pass_in(atom/movable/AM, dir, turf/old_loc) - return isnull(z_pass_in_obstruction(AM, dir, old_loc)) - -/turf/z_pass_out(atom/movable/AM, dir, turf/new_loc) - return isnull(z_pass_out_obstruction(AM, dir, new_loc)) - -// todo: redo -/turf/CheckFall(atom/movable/falling_atom) - if(!(mz_flags & MZ_OPEN_DOWN)) - return TRUE // impact! - return ..() - -//* lookups - -/turf/proc/above() - RETURN_TYPE(/turf) - return locate(x, y, SSmapping.cached_level_up[z]) - -/turf/proc/below() - RETURN_TYPE(/turf) - return locate(x, y, SSmapping.cached_level_down[z]) - -/** - * This is the basic get multiz step. - * It will not look across lateral transitions, only up/down. - */ -/turf/proc/vertical_step(dir) - RETURN_TYPE(/turf) - if((dir & (UP|DOWN)) == 0) - return get_step(src, dir) - else if(dir & UP) - return get_step(locate(x, y, SSmapping.cached_level_up[z]), dir & ~(UP)) - else if(dir & DOWN) - return get_step(locate(x, y, SSmapping.cached_level_down[z]), dir & ~(DOWN)) - CRASH("how did we get here?") - -/** - * Basic multiz get dir - * Will not look across lateral transitions, only directly up/down. - */ -/turf/proc/vertical_dir(turf/other) - if(other.z == z) - return get_dir(src, other) - else if(other.z == SSmapping.cached_level_up[z]) - return get_dir(src, other) | UP - else if(other.z == SSmapping.cached_level_down[z]) - return get_dir(src, other) | DOWN - -/** - * This is the full get multiz step. - * It will look across lateral transitions and other struct magic. - */ -/turf/proc/virtual_step(dir) - RETURN_TYPE(/turf) - return SSmapping.get_virtual_step(src, dir) + CRASH("Non-vertical direction '[dir]' passed in.") diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 0a6fd8c9ffc..ba987430fd4 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -542,9 +542,10 @@ GLOBAL_LIST_INIT(possible_cable_coil_colours, list( slot_flags = SLOT_BELT item_state = "coil" attack_verb = list("whipped", "lashed", "disciplined", "flogged") - stacktype = /obj/item/stack/cable_coil + stacktype_legacy = /obj/item/stack/cable_coil drop_sound = 'sound/items/drop/accessory.ogg' pickup_sound = 'sound/items/pickup/accessory.ogg' + stack_type = /obj/item/stack/cable_coil /obj/item/stack/cable_coil/cyborg name = "cable coil synthesizer" @@ -856,85 +857,85 @@ GLOBAL_LIST_INIT(possible_cable_coil_colours, list( update_wclass() /obj/item/stack/cable_coil/yellow - stacktype = /obj/item/stack/cable_coil + stacktype_legacy = /obj/item/stack/cable_coil color = COLOR_YELLOW /obj/item/stack/cable_coil/blue - stacktype = /obj/item/stack/cable_coil + stacktype_legacy = /obj/item/stack/cable_coil color = COLOR_BLUE /obj/item/stack/cable_coil/green - stacktype = /obj/item/stack/cable_coil + stacktype_legacy = /obj/item/stack/cable_coil color = COLOR_LIME /obj/item/stack/cable_coil/pink - stacktype = /obj/item/stack/cable_coil + stacktype_legacy = /obj/item/stack/cable_coil color = COLOR_PINK /obj/item/stack/cable_coil/orange - stacktype = /obj/item/stack/cable_coil + stacktype_legacy = /obj/item/stack/cable_coil color = COLOR_ORANGE /obj/item/stack/cable_coil/cyan - stacktype = /obj/item/stack/cable_coil + stacktype_legacy = /obj/item/stack/cable_coil color = COLOR_CYAN /obj/item/stack/cable_coil/white - stacktype = /obj/item/stack/cable_coil + stacktype_legacy = /obj/item/stack/cable_coil color = COLOR_WHITE /obj/item/stack/cable_coil/silver - stacktype = /obj/item/stack/cable_coil + stacktype_legacy = /obj/item/stack/cable_coil color = COLOR_SILVER /obj/item/stack/cable_coil/gray - stacktype = /obj/item/stack/cable_coil + stacktype_legacy = /obj/item/stack/cable_coil color = COLOR_GRAY /obj/item/stack/cable_coil/black - stacktype = /obj/item/stack/cable_coil + stacktype_legacy = /obj/item/stack/cable_coil color = COLOR_BLACK /obj/item/stack/cable_coil/maroon - stacktype = /obj/item/stack/cable_coil + stacktype_legacy = /obj/item/stack/cable_coil color = COLOR_MAROON /obj/item/stack/cable_coil/olive - stacktype = /obj/item/stack/cable_coil + stacktype_legacy = /obj/item/stack/cable_coil color = COLOR_OLIVE /obj/item/stack/cable_coil/lime - stacktype = /obj/item/stack/cable_coil + stacktype_legacy = /obj/item/stack/cable_coil color = COLOR_LIME /obj/item/stack/cable_coil/teal - stacktype = /obj/item/stack/cable_coil + stacktype_legacy = /obj/item/stack/cable_coil color = COLOR_TEAL /obj/item/stack/cable_coil/navy - stacktype = /obj/item/stack/cable_coil + stacktype_legacy = /obj/item/stack/cable_coil color = COLOR_NAVY /obj/item/stack/cable_coil/purple - stacktype = /obj/item/stack/cable_coil + stacktype_legacy = /obj/item/stack/cable_coil color = COLOR_PURPLE /obj/item/stack/cable_coil/beige - stacktype = /obj/item/stack/cable_coil + stacktype_legacy = /obj/item/stack/cable_coil color = COLOR_BEIGE /obj/item/stack/cable_coil/brown - stacktype = /obj/item/stack/cable_coil + stacktype_legacy = /obj/item/stack/cable_coil color = COLOR_BROWN /obj/item/stack/cable_coil/random/Initialize(mapload, new_amount, merge) . = ..() - stacktype = /obj/item/stack/cable_coil + stacktype_legacy = /obj/item/stack/cable_coil color = pick(COLOR_RED, COLOR_BLUE, COLOR_LIME, COLOR_WHITE, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN, COLOR_SILVER, COLOR_GRAY, COLOR_BLACK, COLOR_MAROON, COLOR_OLIVE, COLOR_LIME, COLOR_TEAL, COLOR_NAVY, COLOR_PURPLE, COLOR_BEIGE, COLOR_BROWN) /obj/item/stack/cable_coil/random_belt/Initialize(mapload, new_amount, merge) . = ..() - stacktype = /obj/item/stack/cable_coil + stacktype_legacy = /obj/item/stack/cable_coil color = pick(COLOR_RED, COLOR_YELLOW, COLOR_ORANGE) amount = 30 @@ -972,7 +973,7 @@ GLOBAL_LIST_INIT(possible_cable_coil_colours, list( materials_base = list(MAT_STEEL = 50, MAT_GLASS = 20) slot_flags = SLOT_BELT attack_verb = list("whipped", "lashed", "disciplined", "flogged") - stacktype = null + stacktype_legacy = null split_type = /obj/item/stack/cable_coil tool_speed = 0.25 diff --git a/code/modules/preferences/preferences_toggle_procs.dm b/code/modules/preferences/preferences_toggle_procs.dm index 3337c1d9dd0..185314f2924 100644 --- a/code/modules/preferences/preferences_toggle_procs.dm +++ b/code/modules/preferences/preferences_toggle_procs.dm @@ -12,53 +12,3 @@ else src.painmsg = 1 to_chat(src,"You will [ (painmsg) ? "now" : "no longer"] see your own pain messages.") - -/mob/living/carbon/human/verb/acting() - set name = "Feign Impairment" - set category = VERB_CATEGORY_IC - set desc = "Allows user to manually enable drunkenness, stutter, jitter, etc." - set src = usr - - if(!IS_CONSCIOUS(src)) - to_chat(src, "You need to be conscious to do that") - return - - var/list/choices = list("Drunkenness", "Stuttering", "Jittering") - if(src.slurring >= 10 || src.stuttering >= 10 || src.jitteriness >= 100) - var/disable = alert(src, "Stop performing impairment? (Do NOT abuse this)", "Impairments", "Yes", "No") - if(disable == "Yes") - acting_expiry() - return - - var/impairment = input(src, "Select an impairment to perform:", "Impairments") as null|anything in choices - if(!impairment) - return - var/duration = input(src,"Choose a duration to perform [impairment]. (1 - 60 seconds)","Duration in seconds",25) as num|null - if(!isnum(duration)) - return - if(duration > 60 && !check_rights(R_EVENT, 0)) // admins can do as they please - to_chat(src, "Please choose a duration in seconds between 1 to 60.") - return - if(duration >= 1000) // unreachable code for anyone but admins who have set the number very high, logging for my sanity - message_admins("[src] has set their [impairment] to [duration] via Feign Impairment.") - if(duration >= 2000) - to_chat(src, "Please choose a duration less than 2000.") - return - if(impairment == "Drunkenness") - slurring = duration - if(impairment == "Stuttering") - stuttering = duration - if(impairment == "Jittering") - make_jittery(duration + 100) - - if(duration) - addtimer(CALLBACK(src, PROC_REF(acting_expiry)), duration SECONDS) - var/aduration = duration SECONDS / 10 - to_chat(src,"You will now performatively act as if you were experiencing [impairment] for [aduration] seconds. (Do NOT abuse this)") - feedback_add_details("admin_verb","actimpaired") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/mob/living/carbon/human/proc/acting_expiry() - to_chat(src,"You are no longer acting impaired.") // tick down from 1 to allow the effects to end 'naturally' - slurring = 1 - stuttering = 1 - jitteriness = 1 diff --git a/code/modules/vehicles/sealed/mecha/subtypes/micro/mecha_construction_paths_vr.dm b/code/modules/vehicles/sealed/mecha/subtypes/micro/mecha_construction_paths_vr.dm index 36d682829ff..36606784333 100644 --- a/code/modules/vehicles/sealed/mecha/subtypes/micro/mecha_construction_paths_vr.dm +++ b/code/modules/vehicles/sealed/mecha/subtypes/micro/mecha_construction_paths_vr.dm @@ -306,8 +306,6 @@ const_holder.cut_overlays() spawn() qdel(src) - return - /datum/construction/reversible/mecha/gopher result = "/obj/vehicle/sealed/mecha/micro/utility/gopher" diff --git a/maps/templates/archive/tradeship.dmm b/maps/templates/archive/tradeship.dmm index ed1a4ce9f4c..dcad551d9a7 100644 --- a/maps/templates/archive/tradeship.dmm +++ b/maps/templates/archive/tradeship.dmm @@ -1537,7 +1537,7 @@ /obj/item/clothing/under/cheongsam, /obj/item/clothing/under/hosformalmale, /obj/item/clothing/under/hosformalfem, -/obj/item/clothing/under/harness, +/obj/item/clothing/under/gear_harness, /obj/item/clothing/under/gladiator, /obj/item/clothing/under/ert, /obj/item/clothing/under/schoolgirl,