From 262af7ccbd5681aa034c8ef8fb196d5a0414ec07 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Wed, 15 Jan 2025 18:31:55 +1100 Subject: [PATCH 001/120] Fixing base unarmed attack list on species. --- code/modules/species/species.dm | 6 ++++-- code/modules/species/station/human.dm | 6 ------ mods/species/bayliens/skrell/datum/species.dm | 6 ------ 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/code/modules/species/species.dm b/code/modules/species/species.dm index af664b32e9ad..3aa9c8a0b934 100644 --- a/code/modules/species/species.dm +++ b/code/modules/species/species.dm @@ -80,9 +80,11 @@ var/global/const/DEFAULT_SPECIES_HEALTH = 200 // Combat vars. var/total_health = DEFAULT_SPECIES_HEALTH // Point at which the mob will enter crit. var/list/unarmed_attacks = list( // Possible unarmed attacks that the mob will use in combat, - /decl/natural_attack, + /decl/natural_attack/stomp, + /decl/natural_attack/kick, + /decl/natural_attack/punch, /decl/natural_attack/bite - ) + ) var/brute_mod = 1 // Physical damage multiplier. var/burn_mod = 1 // Burn damage multiplier. diff --git a/code/modules/species/station/human.dm b/code/modules/species/station/human.dm index 6264a7b20482..2ee92427f41f 100644 --- a/code/modules/species/station/human.dm +++ b/code/modules/species/station/human.dm @@ -2,12 +2,6 @@ name = SPECIES_HUMAN name_plural = "Humans" primitive_form = SPECIES_MONKEY - unarmed_attacks = list( - /decl/natural_attack/stomp, - /decl/natural_attack/kick, - /decl/natural_attack/punch, - /decl/natural_attack/bite - ) description = "A medium-sized creature prone to great ambition. If you are reading this, you are probably a human." hidden_from_codex = FALSE spawn_flags = SPECIES_CAN_JOIN diff --git a/mods/species/bayliens/skrell/datum/species.dm b/mods/species/bayliens/skrell/datum/species.dm index 0d9acdcd8807..b5001c7f5445 100644 --- a/mods/species/bayliens/skrell/datum/species.dm +++ b/mods/species/bayliens/skrell/datum/species.dm @@ -14,12 +14,6 @@ traits = list(/decl/trait/malus/intolerance/protein = TRAIT_LEVEL_MINOR) primitive_form = "Neaera" - unarmed_attacks = list( - /decl/natural_attack/stomp, - /decl/natural_attack/kick, - /decl/natural_attack/punch, - /decl/natural_attack/bite - ) description = "The Skrell are a highly advanced race of amphibians hailing from the system known as Qerr'Vallis. Their society is regimented into \ five different castes which the Qerr'Katish, or Royal Caste, rules over. Skrell are strict herbivores who are unable to eat large quantities of \ From f2d6d66c3de3d87b24fd26b5efd69cd570eabe89 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 9 Jan 2025 21:19:26 +1100 Subject: [PATCH 002/120] Adding grindstones and whetstones. --- code/__defines/item_effects.dm | 15 +++++ code/_onclick/item_attack.dm | 2 +- code/game/machinery/floor_light.dm | 2 +- code/game/objects/items/__item.dm | 4 +- code/game/objects/items/_item_force.dm | 21 ++++-- code/game/objects/items/blades/_blade.dm | 2 + .../structures/_structure_materials.dm | 4 +- code/modules/crafting/working/_working.dm | 6 +- .../modules/crafting/working/textiles/loom.dm | 16 ++--- .../working/textiles/spinning_wheel.dm | 22 +++---- code/modules/item_effects/_item_effect.dm | 15 ++--- code/modules/item_effects/item_effect_aura.dm | 2 +- .../item_effects/item_effect_charges.dm | 8 +-- .../modules/item_effects/item_effect_debug.dm | 28 ++++---- code/modules/item_effects/item_effect_item.dm | 61 ++++++++++++------ .../solids/materials_solid_mineral.dm | 1 + .../living/simple_animal/natural_weapons.dm | 2 +- maps/modpack_testing/modpack_testing.dm | 1 + maps/shaded_hills/shaded_hills.dm | 1 + .../item_sharpening/_item_sharpening.dm | 4 ++ .../item_sharpening/_item_sharpening.dme | 11 ++++ mods/content/item_sharpening/blade_sharpen.dm | 24 +++++++ .../content/item_sharpening/effect_sharpen.dm | 19 ++++++ mods/content/item_sharpening/grindstone.dm | 42 ++++++++++++ .../item_sharpening/icons/grindstone.dmi | Bin 0 -> 914 bytes mods/content/item_sharpening/item_sharpen.dm | 46 +++++++++++++ mods/content/item_sharpening/whetstone.dm | 18 ++++++ mods/~compatibility/patches/fantasy.dm | 7 +- .../patches/fantasy/whetstone_fantasy.dm | 7 ++ nebula.dme | 1 + 30 files changed, 307 insertions(+), 85 deletions(-) create mode 100644 code/__defines/item_effects.dm create mode 100644 mods/content/item_sharpening/_item_sharpening.dm create mode 100644 mods/content/item_sharpening/_item_sharpening.dme create mode 100644 mods/content/item_sharpening/blade_sharpen.dm create mode 100644 mods/content/item_sharpening/effect_sharpen.dm create mode 100644 mods/content/item_sharpening/grindstone.dm create mode 100644 mods/content/item_sharpening/icons/grindstone.dmi create mode 100644 mods/content/item_sharpening/item_sharpen.dm create mode 100644 mods/content/item_sharpening/whetstone.dm create mode 100644 mods/~compatibility/patches/fantasy/whetstone_fantasy.dm diff --git a/code/__defines/item_effects.dm b/code/__defines/item_effects.dm new file mode 100644 index 000000000000..d5c79b402f9a --- /dev/null +++ b/code/__defines/item_effects.dm @@ -0,0 +1,15 @@ +// Identifiers for various categories of item effects. +#define IE_CAT_DAMAGE "weff_damage" +#define IE_CAT_STRIKE "weff_strike" +#define IE_CAT_PARRY "weff_parry" +#define IE_CAT_USED "weff_used" +#define IE_CAT_WIELDED "weff_wield" +#define IE_CAT_VISUAL "weff_visual" +#define IE_CAT_LISTENER "weff_listener" +#define IE_CAT_EXAMINE "weff_visible" +#define IE_CAT_RANGED "weff_ranged" +#define IE_CAT_PROCESS "weff_process" + +// Identifiers for parameters for item effects. +#define IE_PAR_USES "uses" +#define IE_PAR_MAX_USES "max_uses" diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 075995076d43..76667e422706 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -92,7 +92,7 @@ avoid code duplication. This includes items that may sometimes act as a standard var/oldhealth = current_health . = used_item.use_on_mob(src, user) - if(used_item.get_attack_force(user) && istype(ai) && current_health < oldhealth) + if(used_item.get_attack_force(user, dry_run = TRUE) && istype(ai) && current_health < oldhealth) ai.retaliate(user) if(!. && user == src && user.get_target_zone() == BP_MOUTH && can_devour(used_item, silent = TRUE)) diff --git a/code/game/machinery/floor_light.dm b/code/game/machinery/floor_light.dm index b6fefd1fe27b..e31a013168b4 100644 --- a/code/game/machinery/floor_light.dm +++ b/code/game/machinery/floor_light.dm @@ -58,7 +58,7 @@ var/global/list/floor_light_cache = list() qdel(src) return TRUE - if(W.get_attack_force(user) && user.check_intent(I_FLAG_HARM)) + if(W.get_attack_force(user, dry_run = TRUE) && user.check_intent(I_FLAG_HARM)) return physical_attack_hand(user) return ..() diff --git a/code/game/objects/items/__item.dm b/code/game/objects/items/__item.dm index 20c732782fa0..f90ecf6e4112 100644 --- a/code/game/objects/items/__item.dm +++ b/code/game/objects/items/__item.dm @@ -775,7 +775,7 @@ . += wielded_parry_bonus /obj/item/proc/on_disarm_attempt(mob/target, mob/living/attacker) - var/force = get_attack_force(attacker) + var/force = get_attack_force(attacker, dry_run = TRUE) if(force < 1) return 0 if(!istype(attacker)) @@ -1008,7 +1008,7 @@ modules/mob/living/human/life.dm if you die, you will be zoomed out. descriptors += "sharp" if(edge) descriptors += "edged" - if(get_attack_force() >= 10 && !sharp && !edge) + if(get_attack_force(dry_run = TRUE) >= 10 && !sharp && !edge) descriptors += "heavy" if(material) descriptors += "made of [material.solid_name]" diff --git a/code/game/objects/items/_item_force.dm b/code/game/objects/items/_item_force.dm index 3ff63de0cc7c..86d105167cfd 100644 --- a/code/game/objects/items/_item_force.dm +++ b/code/game/objects/items/_item_force.dm @@ -13,18 +13,20 @@ VAR_PROTECTED/_hardness_force_factor = 0.25 /obj/item/proc/get_max_weapon_force() - . = get_attack_force() + . = get_attack_force(dry_run = TRUE) if(can_be_twohanded) . = round(. * _wielded_force_multiplier) -/obj/item/proc/get_attack_force(mob/living/user) +// `dry_run` param is used for things like the grindstone modpack to avoid +// depleting sharpness when not actually being used to attack. +/obj/item/proc/get_attack_force(mob/living/user, dry_run = FALSE) if(_base_attack_force <= 0 || (item_flags & ITEM_FLAG_NO_BLUDGEON)) return 0 if(isnull(_cached_attack_force)) update_attack_force() if(_cached_attack_force <= 0) return 0 - return istype(user) ? user.modify_attack_force(src, _cached_attack_force, _wielded_force_multiplier) : _cached_attack_force + return istype(user) ? user.modify_attack_force(src, _cached_attack_force, _wielded_force_multiplier, dry_run) : _cached_attack_force // Existing hitby() code expects mobs, structures and machines to be thrown, it seems. /atom/movable/proc/get_thrown_attack_force() @@ -108,10 +110,17 @@ return _cached_attack_force // TODO: consider strength, athletics, mob size -/mob/living/proc/modify_attack_force(obj/item/weapon, supplied_force, wield_mult) +// `dry_run` param used in grindstone modpack to avoid depleting sharpness on non-attacks. +/mob/living/proc/modify_attack_force(obj/item/weapon, supplied_force, wield_mult, dry_run) if(!istype(weapon) || !weapon.is_held_twohanded()) - return supplied_force - return round(supplied_force * wield_mult) + . = supplied_force + else + . = supplied_force * wield_mult + var/list/item_effects = weapon.get_item_effects(IE_CAT_DAMAGE) + if(length(item_effects)) + for(var/decl/item_effect/damage_effect as anything in item_effects) + . = damage_effect.modify_attack_damage(., weapon, src, parameters = item_effects[damage_effect]) + return round(.) // Debug proc - leaving in for future work. Linter hates protected var access so leave commented. /* diff --git a/code/game/objects/items/blades/_blade.dm b/code/game/objects/items/blades/_blade.dm index 60a422153994..19dbcbce1cd6 100644 --- a/code/game/objects/items/blades/_blade.dm +++ b/code/game/objects/items/blades/_blade.dm @@ -15,9 +15,11 @@ slot_flags = SLOT_LOWER_BODY material = /decl/material/solid/metal/steel _base_attack_force = 10 + var/decl/material/hilt_material = /decl/material/solid/organic/wood/oak var/decl/material/guard_material = /decl/material/solid/organic/wood/oak var/decl/material/pommel_material = /decl/material/solid/organic/wood/oak + /// Cache var for blade material shine calculation. var/tmp/shine diff --git a/code/game/objects/structures/_structure_materials.dm b/code/game/objects/structures/_structure_materials.dm index f3c619b1f61b..db8065e41d4d 100644 --- a/code/game/objects/structures/_structure_materials.dm +++ b/code/game/objects/structures/_structure_materials.dm @@ -37,14 +37,14 @@ /obj/structure/proc/update_material_name(var/override_name) var/base_name = override_name || initial(name) - if(istype(material)) + if(istype(material) && (material_alteration & MAT_FLAG_ALTERATION_NAME)) SetName("[material.adjective_name] [base_name]") else SetName(base_name) /obj/structure/proc/update_material_desc(var/override_desc) var/base_desc = override_desc || initial(desc) - if(istype(material)) + if(istype(material) && (material_alteration & MAT_FLAG_ALTERATION_DESC)) desc = "[base_desc] This one is made of [material.solid_name]." else desc = base_desc diff --git a/code/modules/crafting/working/_working.dm b/code/modules/crafting/working/_working.dm index e848937907a7..4957dc0052ab 100644 --- a/code/modules/crafting/working/_working.dm +++ b/code/modules/crafting/working/_working.dm @@ -49,7 +49,7 @@ work_sound.stop(src) update_icon() -/obj/structure/working/attackby(obj/item/W, mob/user) +/obj/structure/working/attackby(obj/item/used_item, mob/user) if(user.check_intent(I_FLAG_HARM)) return ..() @@ -58,12 +58,12 @@ to_chat(user, SPAN_WARNING("\The [src] is currently in use, please wait for it to be finished.")) return TRUE - if(try_take_input(W, user)) + if(try_take_input(used_item, user)) return TRUE return ..() -/obj/structure/working/proc/try_take_input(obj/item/W, mob/user, silent) +/obj/structure/working/proc/try_take_input(obj/item/used_item, mob/user, silent) return FALSE /obj/structure/working/proc/try_unload_material(mob/user) diff --git a/code/modules/crafting/working/textiles/loom.dm b/code/modules/crafting/working/textiles/loom.dm index 2b7bf5ae8688..a68bdacbf57b 100644 --- a/code/modules/crafting/working/textiles/loom.dm +++ b/code/modules/crafting/working/textiles/loom.dm @@ -34,24 +34,24 @@ weaving_type = null weaving_progress = 0 -/obj/structure/working/loom/try_take_input(obj/item/W, mob/user) +/obj/structure/working/loom/try_take_input(obj/item/used_item, mob/user) - if(istype(W, /obj/item/stack/material/thread)) + if(istype(used_item, /obj/item/stack/material/thread)) - if(!W.material.has_textile_fibers) - to_chat(user, SPAN_WARNING("\The [W] isn't suitable for making cloth.")) + if(!used_item.material.has_textile_fibers) + to_chat(user, SPAN_WARNING("\The [used_item] isn't suitable for making cloth.")) return TRUE var/loaded = FALSE if(loaded_thread) - if(!loaded_thread.can_merge_stacks(W)) + if(!loaded_thread.can_merge_stacks(used_item)) to_chat(user, SPAN_WARNING("\The [src] is already wound with \the [loaded_thread].")) return TRUE - var/obj/item/stack/feeding = W + var/obj/item/stack/feeding = used_item feeding.transfer_to(loaded_thread) loaded = TRUE - else if(user.try_unequip(W, src)) - loaded_thread = W + else if(user.try_unequip(used_item, src)) + loaded_thread = used_item loaded = TRUE if(loaded) weaving_color = loaded_thread.get_color() diff --git a/code/modules/crafting/working/textiles/spinning_wheel.dm b/code/modules/crafting/working/textiles/spinning_wheel.dm index e79afe923791..84b1dab6e1b4 100644 --- a/code/modules/crafting/working/textiles/spinning_wheel.dm +++ b/code/modules/crafting/working/textiles/spinning_wheel.dm @@ -24,16 +24,16 @@ /obj/structure/working/spinning_wheel/proc/can_process(obj/item/thing) return istype(thing) && thing.has_textile_fibers() -/obj/structure/working/spinning_wheel/try_take_input(obj/item/W, mob/user) +/obj/structure/working/spinning_wheel/try_take_input(obj/item/used_item, mob/user) - if(istype(W.storage)) + if(istype(used_item.storage)) var/list/loading_growns = list() - for(var/obj/item/thing in W.get_stored_inventory()) + for(var/obj/item/thing in used_item.get_stored_inventory()) if(can_process(thing)) loading_growns += thing if(!length(loading_growns)) - to_chat(user, SPAN_WARNING("Nothing in \the [W] is suitable for processing on \the [src].")) + to_chat(user, SPAN_WARNING("Nothing in \the [used_item] is suitable for processing on \the [src].")) return TRUE if(length(loaded) >= MAX_LOADED) @@ -42,24 +42,24 @@ var/loaded_items = 0 for(var/obj/item/thing as anything in loading_growns) - if(W.storage.remove_from_storage(thing, src, TRUE)) + if(used_item.storage.remove_from_storage(thing, src, TRUE)) loaded_items++ LAZYADD(loaded, thing) if(length(loaded) >= MAX_LOADED) break if(loaded_items) - W.storage.finish_bulk_removal() - to_chat(user, SPAN_NOTICE("You prepare \the [src] with [loaded_items] items from \the [W].")) + used_item.storage.finish_bulk_removal() + to_chat(user, SPAN_NOTICE("You prepare \the [src] with [loaded_items] items from \the [used_item].")) update_icon() return TRUE - if(can_process(W)) + if(can_process(used_item)) if(length(loaded) >= MAX_LOADED) to_chat(user, SPAN_WARNING("\The [src] is already fully stocked and ready for spinning.")) return TRUE - if(user.try_unequip(W, src)) - LAZYADD(loaded, W) - to_chat(user, SPAN_NOTICE("You prepare \the [src] with \the [W].")) + if(user.try_unequip(used_item, src)) + LAZYADD(loaded, used_item) + to_chat(user, SPAN_NOTICE("You prepare \the [src] with \the [used_item].")) update_icon() return TRUE return TRUE diff --git a/code/modules/item_effects/_item_effect.dm b/code/modules/item_effects/_item_effect.dm index 9516a3a9639b..3c88e8280212 100644 --- a/code/modules/item_effects/_item_effect.dm +++ b/code/modules/item_effects/_item_effect.dm @@ -1,13 +1,3 @@ -#define ITEM_EFFECT_STRIKE "weff_strike" -#define ITEM_EFFECT_PARRY "weff_parry" -#define ITEM_EFFECT_USED "weff_used" -#define ITEM_EFFECT_WIELDED "weff_wield" -#define ITEM_EFFECT_VISUAL "weff_visual" -#define ITEM_EFFECT_LISTENER "weff_listener" -#define ITEM_EFFECT_VISIBLE "weff_visible" -#define ITEM_EFFECT_RANGED "weff_ranged" -#define ITEM_EFFECT_PROCESS "weff_process" - /decl/item_effect abstract_type = /decl/item_effect @@ -75,6 +65,9 @@ SHOULD_CALL_PARENT(FALSE) return FALSE -/decl/item_effect/proc/examined(obj/item/item, mob/user) +/decl/item_effect/proc/on_examined(obj/item/item, mob/user, distance, list/parameters) SHOULD_CALL_PARENT(FALSE) return FALSE + +/decl/item_effect/proc/modify_attack_damage(base_damage, obj/item/used_item, mob/user, dry_run, list/parameters) + return base_damage diff --git a/code/modules/item_effects/item_effect_aura.dm b/code/modules/item_effects/item_effect_aura.dm index d08b4a4968ea..c30e3a36461a 100644 --- a/code/modules/item_effects/item_effect_aura.dm +++ b/code/modules/item_effects/item_effect_aura.dm @@ -16,7 +16,7 @@ user.remove_aura(aura_type) return TRUE -/decl/item_effect/aura/examined(obj/item/item, mob/user) +/decl/item_effect/aura/on_examined(obj/item/item, mob/user) var/obj/aura/aura = aura_type to_chat(user, SPAN_NOTICE("\The [item] grants \a [initial(aura.name)] to the wielder.")) diff --git a/code/modules/item_effects/item_effect_charges.dm b/code/modules/item_effects/item_effect_charges.dm index 4a27d3d0a271..06e8126b16fe 100644 --- a/code/modules/item_effects/item_effect_charges.dm +++ b/code/modules/item_effects/item_effect_charges.dm @@ -3,14 +3,14 @@ abstract_type = /decl/item_effect/charges /decl/item_effect/charges/do_ranged_effect(mob/user, obj/item/item, atom/target, list/parameters) - var/charges = (LAZYACCESS(parameters, "charges") || 0) + var/charges = (LAZYACCESS(parameters, IE_PAR_USES) || 0) if(charges <= 0) return FALSE - item.set_item_effect_parameter(src, ITEM_EFFECT_RANGED, "charges", charges-1) + item.set_item_effect_parameter(src, IE_CAT_RANGED, IE_PAR_USES, charges-1) return TRUE -/decl/item_effect/charges/examined(obj/item/item, mob/user) - to_chat(user, SPAN_NOTICE("\The [item] has [item.get_item_effect_parameter(src, ITEM_EFFECT_RANGED, "charges") || 0] charge\s of [effect_descriptor] left.")) +/decl/item_effect/charges/on_examined(obj/item/item, mob/user) + to_chat(user, SPAN_NOTICE("\The [item] has [item.get_item_effect_parameter(src, IE_CAT_RANGED, IE_PAR_USES) || 0] charge\s of [effect_descriptor] left.")) /obj/item/projectile/fireball name = "fireball" diff --git a/code/modules/item_effects/item_effect_debug.dm b/code/modules/item_effects/item_effect_debug.dm index 352143ed57b4..1533abda4836 100644 --- a/code/modules/item_effects/item_effect_debug.dm +++ b/code/modules/item_effects/item_effect_debug.dm @@ -37,7 +37,7 @@ /decl/item_effect/debug/hear_speech(obj/item/item, mob/user, message, decl/language/speaking) log_debug("[type]: [item] heard [user] say [message] in [speaking] ([json_encode(args)])") -/decl/item_effect/debug/examined(obj/item/item, mob/user) +/decl/item_effect/debug/on_examined(obj/item/item, mob/user) log_debug("[type]: [user] examined [item] ([json_encode(args)])") /decl/item_effect/debug/do_process_effect(obj/item/item, list/parameters) @@ -46,21 +46,21 @@ /obj/item/sword/katana/debug/Initialize() . = ..() add_item_effect(/decl/item_effect/debug, list( - ITEM_EFFECT_VISUAL = list("vis" = "ual"), - ITEM_EFFECT_STRIKE = list("foo" = "bar"), - ITEM_EFFECT_PARRY = list("fizz" = "buzz"), - ITEM_EFFECT_USED = list("aard" = "vark"), - ITEM_EFFECT_VISIBLE = list("ooo" = "aaa"), - ITEM_EFFECT_LISTENER = list("walla walla" = "bing bong"), - ITEM_EFFECT_PROCESS = list("hyonk" = "hjonk") + (IE_CAT_VISUAL) = list("vis" = "ual"), + (IE_CAT_STRIKE) = list("foo" = "bar"), + (IE_CAT_PARRY) = list("fizz" = "buzz"), + (IE_CAT_USED) = list("aard" = "vark"), + (IE_CAT_EXAMINE) = list("ooo" = "aaa"), + (IE_CAT_LISTENER) = list("walla walla" = "bing bong"), + (IE_CAT_PROCESS) = list("hyonk" = "hjonk") )) add_item_effect(/decl/item_effect/charges/fireball, list( - ITEM_EFFECT_VISIBLE, - ITEM_EFFECT_RANGED = list("charges" = 5) + (IE_CAT_EXAMINE), + (IE_CAT_RANGED) = list(IE_PAR_USES = 5) )) add_item_effect(/decl/item_effect/aura/regeneration, list( - ITEM_EFFECT_VISIBLE, - ITEM_EFFECT_WIELDED + (IE_CAT_EXAMINE), + (IE_CAT_WIELDED) )) /obj/item/staff/crystal/beacon/fireball @@ -71,6 +71,6 @@ /obj/item/staff/crystal/beacon/fireball/Initialize(ml, material_key) . = ..() add_item_effect(/decl/item_effect/charges/fireball, list( - ITEM_EFFECT_VISIBLE, - ITEM_EFFECT_RANGED = list("charges" = 5) + (IE_CAT_EXAMINE), + (IE_CAT_RANGED) = list(IE_PAR_USES = 5) )) \ No newline at end of file diff --git a/code/modules/item_effects/item_effect_item.dm b/code/modules/item_effects/item_effect_item.dm index 22c57157bd4e..ea1be1cfd241 100644 --- a/code/modules/item_effects/item_effect_item.dm +++ b/code/modules/item_effects/item_effect_item.dm @@ -1,6 +1,15 @@ /obj/item var/list/_item_effects +/obj/item/proc/has_item_effect(decl/item_effect/effect, effect_category) + if(!length(_item_effects)) + return FALSE + if(ispath(effect)) + effect = GET_DECL(effect) + if(!istype(effect)) + return FALSE + return LAZYISIN(LAZYACCESS(_item_effects, effect_category), effect) + /obj/item/proc/add_item_effect(effect_type, list/effect_parameters) if(!effect_type || !length(effect_parameters)) return FALSE @@ -13,13 +22,15 @@ . = TRUE if(.) - if(ITEM_EFFECT_LISTENER in effect_parameters) + if(IE_CAT_LISTENER in effect_parameters) global.listening_objects |= src - if(ITEM_EFFECT_PROCESS in effect_parameters) + if(IE_CAT_PROCESS in effect_parameters) SSitem_effects.queued_items |= src /obj/item/proc/remove_item_effect(decl/item_effect/effect) - if(!effect || !length(_item_effects)) + if(ispath(effect)) + effect = GET_DECL(effect) + if(!istype(effect) || !length(_item_effects)) return FALSE var/list/removed_effect_categories = list() for(var/effect_category in _item_effects) @@ -30,13 +41,23 @@ LAZYREMOVE(_item_effects, effect_category) . = TRUE if(.) - if(ITEM_EFFECT_LISTENER in removed_effect_categories) + if(IE_CAT_LISTENER in removed_effect_categories) global.listening_objects -= src - if(ITEM_EFFECT_PROCESS in removed_effect_categories) + if(IE_CAT_PROCESS in removed_effect_categories) SSitem_effects.queued_items -= src +/obj/item/proc/get_item_effect_parameters(decl/item_effect/effect, effect_category) + if(ispath(effect)) + effect = GET_DECL(effect) + if(!istype(effect) || !length(_item_effects) || !effect_category) + return null + var/list/effects = LAZYACCESS(_item_effects, effect_category) + return LAZYACCESS(effects, effect) + /obj/item/proc/get_item_effect_parameter(decl/item_effect/effect, effect_category, parameter_name) - if(!effect || !length(_item_effects) || !effect_category || !parameter_name) + if(ispath(effect)) + effect = GET_DECL(effect) + if(!istype(effect) || !length(_item_effects) || !effect_category || !parameter_name) return null var/list/effects = LAZYACCESS(_item_effects, effect_category) if(!LAZYISIN(effects, effect)) @@ -44,7 +65,9 @@ return LAZYACCESS(effects[effect], parameter_name) /obj/item/proc/set_item_effect_parameter(decl/item_effect/effect, effect_category, parameter_name, parameter_value) - if(!effect || !length(_item_effects) || !effect_category || !parameter_name) + if(ispath(effect)) + effect = GET_DECL(effect) + if(!istype(effect) || !length(_item_effects) || !effect_category || !parameter_name) return FALSE var/list/effects = LAZYACCESS(_item_effects, effect_category) if(!LAZYISIN(effects, effect)) @@ -59,7 +82,7 @@ /obj/item/resolve_attackby(atom/A, mob/user, var/click_params) if(!(. = ..())) return - var/list/item_effects = get_item_effects(ITEM_EFFECT_STRIKE) + var/list/item_effects = get_item_effects(IE_CAT_STRIKE) if(!length(item_effects)) return if(!istype(user) || QDELETED(user) || QDELETED(src)) @@ -72,7 +95,7 @@ // PARRY effects /obj/item/on_parry(mob/user, damage_source, mob/attacker) . = ..() - var/list/item_effects = get_item_effects(ITEM_EFFECT_PARRY) + var/list/item_effects = get_item_effects(IE_CAT_PARRY) if(!length(item_effects)) return if(!istype(user) || QDELETED(user) || QDELETED(src)) @@ -86,7 +109,7 @@ // VISUAL effects (world icon) /obj/item/on_update_icon() . = ..() - var/list/item_effects = get_item_effects(ITEM_EFFECT_VISUAL) + var/list/item_effects = get_item_effects(IE_CAT_VISUAL) if(!length(item_effects)) return for(var/decl/item_effect/used_effect as anything in item_effects) @@ -96,7 +119,7 @@ /obj/item/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) // TODO: this might need work to handle items that do a state or appearance update in the parent call. if(overlay) - var/list/item_effects = get_item_effects(ITEM_EFFECT_VISUAL) + var/list/item_effects = get_item_effects(IE_CAT_VISUAL) if(length(item_effects)) for(var/decl/item_effect/used_effect as anything in item_effects) used_effect.apply_onmob_appearance_to(src, user_mob, bodytype, overlay, slot, bodypart, item_effects[used_effect]) @@ -106,7 +129,7 @@ /obj/item/attack_self(mob/user) if((. = ..())) return - var/list/item_effects = get_item_effects(ITEM_EFFECT_USED) + var/list/item_effects = get_item_effects(IE_CAT_USED) if(!length(item_effects)) return if(!istype(user) || QDELETED(user) || QDELETED(src)) @@ -120,7 +143,7 @@ // WIELD effects (unwielded) /obj/item/dropped(mob/user) . = ..() - var/list/item_effects = get_item_effects(ITEM_EFFECT_WIELDED) + var/list/item_effects = get_item_effects(IE_CAT_WIELDED) if(!length(item_effects)) return if(!istype(user) || QDELETED(user) || QDELETED(src)) @@ -133,7 +156,7 @@ // WIELD effects (wielded) /obj/item/equipped(mob/user, slot) . = ..() - var/list/item_effects = get_item_effects(ITEM_EFFECT_WIELDED) + var/list/item_effects = get_item_effects(IE_CAT_WIELDED) if(!length(item_effects)) return if(!istype(user) || QDELETED(user) || QDELETED(src) || loc != user || !(slot in user.get_held_item_slots())) @@ -146,7 +169,7 @@ // LISTENING effects /obj/item/hear_talk(mob/M, text, verb, decl/language/speaking) . = ..() - var/list/item_effects = get_item_effects(ITEM_EFFECT_LISTENER) + var/list/item_effects = get_item_effects(IE_CAT_LISTENER) if(!length(item_effects)) return for(var/decl/item_effect/listening_effect as anything in item_effects) @@ -157,17 +180,17 @@ . = ..() if(!user) return - var/list/item_effects = get_item_effects(ITEM_EFFECT_VISIBLE) + var/list/item_effects = get_item_effects(IE_CAT_EXAMINE) if(!length(item_effects)) return for(var/decl/item_effect/examine_effect as anything in item_effects) - examine_effect.examined(src, user, distance, item_effects[examine_effect]) + examine_effect.on_examined(src, user, distance, item_effects[examine_effect]) // RANGED effects /obj/item/afterattack(turf/floor/target, mob/user, proximity) if((. = ..()) || proximity) return - var/list/item_effects = get_item_effects(ITEM_EFFECT_RANGED) + var/list/item_effects = get_item_effects(IE_CAT_RANGED) if(!length(item_effects)) return for(var/decl/item_effect/ranged_effect as anything in item_effects) @@ -177,7 +200,7 @@ // PROCESS effects /obj/item/proc/process_item_effects() - var/list/item_effects = get_item_effects(ITEM_EFFECT_PROCESS) + var/list/item_effects = get_item_effects(IE_CAT_PROCESS) if(length(item_effects)) for(var/decl/item_effect/process_effect as anything in item_effects) process_effect.do_process_effect(src, item_effects[process_effect]) diff --git a/code/modules/materials/definitions/solids/materials_solid_mineral.dm b/code/modules/materials/definitions/solids/materials_solid_mineral.dm index ac92e330a7d4..9f17d069f3f8 100644 --- a/code/modules/materials/definitions/solids/materials_solid_mineral.dm +++ b/code/modules/materials/definitions/solids/materials_solid_mineral.dm @@ -68,6 +68,7 @@ boiling_point = 2504 color = "#effffe" reflectiveness = MAT_VALUE_SHINY + hardness = MAT_VALUE_VERY_HARD - 5 // Hard enough to whet steel. sparse_material_weight = 3 rich_material_weight = 1 dissolves_into = list( diff --git a/code/modules/mob/living/simple_animal/natural_weapons.dm b/code/modules/mob/living/simple_animal/natural_weapons.dm index 161bf49f7cd0..06611f0170c5 100644 --- a/code/modules/mob/living/simple_animal/natural_weapons.dm +++ b/code/modules/mob/living/simple_animal/natural_weapons.dm @@ -10,7 +10,7 @@ weapon_can_knock_prone = FALSE // Very powerful in the hands of simplemobs. var/show_in_message // whether should we show up in attack message, e.g. 'urist has been bit with teeth by carp' vs 'urist has been bit by carp' -/obj/item/natural_weapon/get_attack_force(mob/living/user) +/obj/item/natural_weapon/get_attack_force(mob/living/user, dry_run = FALSE) return get_base_attack_force() /obj/item/natural_weapon/attack_message_name() diff --git a/maps/modpack_testing/modpack_testing.dm b/maps/modpack_testing/modpack_testing.dm index 8466fb6b71eb..9d08ae36d519 100644 --- a/maps/modpack_testing/modpack_testing.dm +++ b/maps/modpack_testing/modpack_testing.dm @@ -23,6 +23,7 @@ #include "../../mods/content/shackles/_shackles.dme" #include "../../mods/content/supermatter/_supermatter.dme" #include "../../mods/content/xenobiology/_xenobiology.dme" + #include "../../mods/content/item_sharpening/_item_sharpening.dme" #include "../../mods/gamemodes/cult/_cult.dme" #include "../../mods/gamemodes/heist/_heist.dme" diff --git a/maps/shaded_hills/shaded_hills.dm b/maps/shaded_hills/shaded_hills.dm index 1931b81ef34b..eb386cc81801 100644 --- a/maps/shaded_hills/shaded_hills.dm +++ b/maps/shaded_hills/shaded_hills.dm @@ -5,6 +5,7 @@ #include "../../mods/content/mouse_highlights/_mouse_highlight.dme" #include "../../mods/content/scaling_descriptors.dm" #include "../../mods/species/drakes/_drakes.dme" // include before _fantasy.dme so overrides work + #include "../../mods/content/item_sharpening/_item_sharpening.dme" #include "../../mods/content/fantasy/_fantasy.dme" #include "areas/_areas.dm" diff --git a/mods/content/item_sharpening/_item_sharpening.dm b/mods/content/item_sharpening/_item_sharpening.dm new file mode 100644 index 000000000000..53c03251f449 --- /dev/null +++ b/mods/content/item_sharpening/_item_sharpening.dm @@ -0,0 +1,4 @@ +#define IE_PAR_SHARP_DAM_MULT "sharp_dam_mult" + +/decl/modpack/item_sharpening + name = "Item Sharpening" diff --git a/mods/content/item_sharpening/_item_sharpening.dme b/mods/content/item_sharpening/_item_sharpening.dme new file mode 100644 index 000000000000..cf812cb8b329 --- /dev/null +++ b/mods/content/item_sharpening/_item_sharpening.dme @@ -0,0 +1,11 @@ +#ifndef MODPACK_ITEM_SHARPENING +#define MODPACK_ITEM_SHARPENING +// BEGIN_INCLUDE +#include "_item_sharpening.dm" +#include "blade_sharpen.dm" +#include "grindstone.dm" +#include "effect_sharpen.dm" +#include "item_sharpen.dm" +#include "whetstone.dm" +//END_INCLUDE +#endif diff --git a/mods/content/item_sharpening/blade_sharpen.dm b/mods/content/item_sharpening/blade_sharpen.dm new file mode 100644 index 000000000000..a46b8d690332 --- /dev/null +++ b/mods/content/item_sharpening/blade_sharpen.dm @@ -0,0 +1,24 @@ +/obj/item/bladed/proc/get_sharpened_effect_params() + return list( + (IE_CAT_DAMAGE) = list( + (IE_PAR_USES) = max(1, max(1, rand(round(10 * 0.3), round(20 * 0.6)))), + (IE_PAR_MAX_USES) = 30, + (IE_PAR_SHARP_DAM_MULT) = 0.25 + ), + (IE_CAT_EXAMINE) + ) + +/obj/item/bladed/Initialize(ml, material_key, _hilt_mat, _guard_mat, _pommel_mat) + var/list/sharpened_params = get_sharpened_effect_params() + if(length(sharpened_params)) + add_item_effect(/decl/item_effect/sharpened, sharpened_params) + . = ..() + if(length(sharpened_params)) + update_attack_force() + update_name() + +/obj/item/bladed/folding/try_sharpen_with(mob/user, obj/sharpening_with) + if(!open) + to_chat(user, SPAN_WARNING("You cannot sharpen \the [src] while it's closed!")) + return FALSE + return ..() diff --git a/mods/content/item_sharpening/effect_sharpen.dm b/mods/content/item_sharpening/effect_sharpen.dm new file mode 100644 index 000000000000..4331f18e0d4b --- /dev/null +++ b/mods/content/item_sharpening/effect_sharpen.dm @@ -0,0 +1,19 @@ +/decl/item_effect/sharpened/modify_attack_damage(base_damage, obj/item/used_item, mob/user, dry_run, list/parameters) + var/uses = LAZYACCESS(parameters, IE_PAR_USES) + if(uses <= 0) + return base_damage + . = (1 + ((uses / max(1, LAZYACCESS(parameters, IE_PAR_MAX_USES))) * LAZYACCESS(parameters, IE_PAR_SHARP_DAM_MULT))) + if(!dry_run) + uses = max(0, uses-1) + used_item.set_item_effect_parameter(src, IE_CAT_DAMAGE, IE_PAR_USES, uses) + if(uses == 0) // We've gone dull! + used_item.update_attack_force() + used_item.update_name() + +/decl/item_effect/sharpened/on_examined(obj/item/item, mob/user, distance, list/parameters) + if(distance <= 1) + var/uses = item.get_item_effect_parameter(src, IE_CAT_DAMAGE, IE_PAR_USES) + if(uses > 0) + to_chat(user, SPAN_NOTICE("\The [src] has been sharpened to a keen edge.")) + else + to_chat(user, SPAN_NOTICE("\The [src] is dull and in need of sharpening.")) diff --git a/mods/content/item_sharpening/grindstone.dm b/mods/content/item_sharpening/grindstone.dm new file mode 100644 index 000000000000..13bc15f848b6 --- /dev/null +++ b/mods/content/item_sharpening/grindstone.dm @@ -0,0 +1,42 @@ +// TODO: better sound effects for working. +/obj/structure/working/grindstone + name = "grindstone" + desc = "A rotating section of coarse stone used to polish and sharpen metalwork like blades." + icon = 'mods/content/item_sharpening/icons/grindstone.dmi' + material_alteration = MAT_FLAG_ALTERATION_COLOR // Name and desc handled manually. + var/decl/material/stone_material = /decl/material/solid/quartz + +/obj/structure/working/grindstone/Initialize() + stone_material = GET_DECL(stone_material) + . = ..() + update_material_name() + update_material_desc() + +/obj/structure/working/grindstone/update_material_name(override_name) + . = ..() + if(stone_material) + SetName("[stone_material.adjective_name] [name]") + +/obj/structure/working/grindstone/update_material_desc(override_desc) + . = ..() + if(stone_material && istype(material)) + desc = "[desc] This one is made from [stone_material.solid_name] with \a [material.adjective_name] frame." + +/obj/structure/working/grindstone/on_update_icon() + . = ..() + underlays = list( + overlay_image(icon, "[icon_state]-grindstone", stone_material.color, RESET_COLOR), + overlay_image(icon, "[initial(icon_state)]-backdrop") + ) + +// Slightly wonky override, but this basically intercepts items being used on the grindstone. +/obj/structure/working/grindstone/try_take_input(obj/item/used_item, mob/user, silent) + if(working) + if(!silent) + to_chat(user, SPAN_WARNING("\The [src] is already in use, please wait for it to be free.")) + else + start_working() + used_item.try_sharpen_with(user, src) + if(!QDELETED(src) && working) + stop_working() + return TRUE diff --git a/mods/content/item_sharpening/icons/grindstone.dmi b/mods/content/item_sharpening/icons/grindstone.dmi new file mode 100644 index 0000000000000000000000000000000000000000..70b311b63b5c8f68854a03a206211bdc316f508c GIT binary patch literal 914 zcmV;D18w|?P)004jl0{{R3eocQU0000LP)t-sz`($Y zik`y3$w^0C|NsAGVs^m5z#D@x2wg|Jao=>o~@%)E5$sx5$`sX2+2AYmPf zAiA|liOJb1Mfn9px-z{eGcTpMBtI{eG;a~qh}(x;$_lQ2F5vJ70Q+8RYGa`M3IG5C zfJsC_RA_0cZ>c?U0qt_?PDK?zU5L%QSqVM;IduVhkmF8Q$n_) z?-t#?1v}jz9rRFXt=uDtk4KnuJ)E)A{n6b=wC19q+5{Pvb$?{ z#!mM~hhMjU3->PRa%KPFg+iea@N*d^b2=M8Mqx5mzukdhF3WLFXG7<7HeoL7ac*Z5 z=CYW~k_sArBP+bze7_ruSbM9~Qc<<;Vuk_xWD|GLouej2C zu^-;19{-3dy%)Pe9`R%!j(%;B7Yc>{7}@OX7t`$N2RFpbj_yYH{W{IXTnBS!_4RE( zKm2B#)h6XNah7s8*xKINHR%jH!_JVy$+{K$o^avbK=zR{Act z=vlSwHF2Ka_XoI7s1j~BIY9Ug{v=!ww`qsoAJA>^nmD)DsrzR{-+0{x@fx`+DpqxS zx?9=V3xz_V@Ih`5M(1VrASJs8DcL&2M-9*j;bJ@|e23nyG7u#3Dt7ytkO07*qoM6N<$f~sr1p8x;= literal 0 HcmV?d00001 diff --git a/mods/content/item_sharpening/item_sharpen.dm b/mods/content/item_sharpening/item_sharpen.dm new file mode 100644 index 000000000000..28290a6d13a6 --- /dev/null +++ b/mods/content/item_sharpening/item_sharpen.dm @@ -0,0 +1,46 @@ +/obj/item/update_name() + . = ..() + if(has_item_effect(/decl/item_effect/sharpened, IE_CAT_EXAMINE) && get_item_effect_parameter(/decl/item_effect/sharpened, IE_CAT_DAMAGE, IE_PAR_USES) <= 0) + SetName("dulled [name]") + +/obj/item/proc/can_sharpen_with(obj/item/sharpening_with) + if(!has_item_effect(/decl/item_effect/sharpened, IE_CAT_DAMAGE)) + return FALSE + var/list/params = get_item_effect_parameters(/decl/item_effect/sharpened, IE_CAT_DAMAGE) + if(!islist(params) || params[IE_PAR_USES] >= params[IE_PAR_MAX_USES]) + return FALSE + if(istype(sharpening_with, /obj/structure/working/grindstone)) + var/obj/structure/working/grindstone/stone = sharpening_with + return !material || material.hardness <= stone.stone_material?.hardness + return !material || material.hardness <= sharpening_with.material?.hardness + +/obj/item/proc/sharpen_with(mob/user, obj/item/sharpen_with) + if(!has_item_effect(/decl/item_effect/sharpened, IE_CAT_DAMAGE)) + return FALSE + var/list/params = get_item_effect_parameters(/decl/item_effect/sharpened, IE_CAT_DAMAGE) + if(!islist(params)) + return FALSE + var/max_uses = params[IE_PAR_MAX_USES] + if(max_uses <= 0) + return FALSE + var/uses = params[IE_PAR_USES] || 0 + if(uses >= max_uses) + return FALSE + set_item_effect_parameter(/decl/item_effect/sharpened, IE_CAT_DAMAGE, IE_PAR_USES, max_uses) + if(uses == 0) // We've sharpened up from dull. + update_attack_force() + update_name() + return TRUE + +/obj/item/proc/try_sharpen_with(mob/user, obj/sharpening_with) + if(!has_item_effect(/decl/item_effect/sharpened, IE_CAT_DAMAGE)) + return FALSE + if(can_sharpen_with(sharpening_with)) + user.visible_message("\The [user] begins sharpening \the [src] with \the [sharpening_with].") + // TODO: play sharpening sound? Spawn sparks for metal? + if(user.do_skilled(10 SECONDS, SKILL_WEAPONS, src, check_holding = TRUE) && !QDELETED(sharpening_with) && can_sharpen_with(sharpening_with) && sharpen_with(user, sharpening_with)) + // TODO: play sharpening sound? Spawn sparks for metal? + user.visible_message("\The [user] sharpens \the [src] with \the [sharpening_with].") + else + to_chat(user, SPAN_WARNING("\The [src] cannot be [sharp ? "further sharpened" : "sharpened"] with \the [sharpening_with].")) + return TRUE diff --git a/mods/content/item_sharpening/whetstone.dm b/mods/content/item_sharpening/whetstone.dm new file mode 100644 index 000000000000..cdfbb09eea51 --- /dev/null +++ b/mods/content/item_sharpening/whetstone.dm @@ -0,0 +1,18 @@ +/obj/item/whetstone + name = "whetstone" + desc = "A worn-down lozenge used to sharpen blades." + icon = 'icons/obj/items/striker.dmi' // TODO unique icon? + w_class = ITEM_SIZE_TINY + material_alteration = MAT_FLAG_ALTERATION_ALL + material = /decl/material/solid/quartz + +/obj/item/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/whetstone)) + return try_sharpen_with(user, used_item) + return ..() + +/decl/loadout_option/utility/whetstone + name = "whetstone" + path = /obj/item/whetstone + loadout_flags = null + uid = "gear_utility_whetstone" diff --git a/mods/~compatibility/patches/fantasy.dm b/mods/~compatibility/patches/fantasy.dm index c176360672c6..4b4d6f7feaba 100644 --- a/mods/~compatibility/patches/fantasy.dm +++ b/mods/~compatibility/patches/fantasy.dm @@ -1,4 +1,9 @@ // Override drake lore and names for the fantasy modpack. #ifdef MODPACK_DRAKES #include "fantasy/drake_fantasy.dm" -#endif \ No newline at end of file +#endif + +// Make whetstones available for the fantasy modpack/ +#ifdef MODPACK_ITEM_SHARPENING +#include "fantasy/whetstone_fantasy.dm" +#endif diff --git a/mods/~compatibility/patches/fantasy/whetstone_fantasy.dm b/mods/~compatibility/patches/fantasy/whetstone_fantasy.dm new file mode 100644 index 000000000000..b2821d26fa67 --- /dev/null +++ b/mods/~compatibility/patches/fantasy/whetstone_fantasy.dm @@ -0,0 +1,7 @@ +// Make whetstones available in character generation. +/decl/loadout_option/fantasy/utility/whetstone + name = "whetstone" + path = /obj/item/whetstone + available_materials = null + loadout_flags = null + uid = "gear_fantasy_whetstone" diff --git a/nebula.dme b/nebula.dme index 8660305935b2..bca074839c49 100644 --- a/nebula.dme +++ b/nebula.dme @@ -60,6 +60,7 @@ #include "code\__defines\intent.dm" #include "code\__defines\interactions.dm" #include "code\__defines\inventory_sizes.dm" +#include "code\__defines\item_effects.dm" #include "code\__defines\items_clothing.dm" #include "code\__defines\jobs.dm" #include "code\__defines\languages.dm" From 57f5e91322bcc6736fa23473d7050cb5cfd730a0 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 9 Jan 2025 23:36:29 +1100 Subject: [PATCH 003/120] Making all edge/sharpness checks use getters. --- code/_helpers/unsorted.dm | 16 ++++-------- code/_onclick/item_attack.dm | 4 +-- code/game/objects/__objs.dm | 11 ++++---- code/game/objects/effects/spiders.dm | 2 +- code/game/objects/items/__item.dm | 6 ++--- code/game/objects/items/_item_force.dm | 24 +++++------------ code/game/objects/items/_item_sharpness.dm | 21 +++++++++++++++ code/game/objects/items/blades/_blade.dm | 4 +-- code/game/objects/items/blades/folding.dm | 7 +++-- code/game/objects/items/blades/spear.dm | 4 +-- code/game/objects/items/rock.dm | 8 +++--- code/game/objects/items/toys.dm | 8 +++--- .../objects/items/weapons/material/folding.dm | 13 +++++----- .../objects/items/weapons/material/knives.dm | 6 ++--- .../objects/items/weapons/material/misc.dm | 12 ++++----- .../objects/items/weapons/material/shards.dm | 4 +-- .../objects/items/weapons/material/stick.dm | 8 +++--- .../objects/items/weapons/material/swiss.dm | 4 +-- .../objects/items/weapons/material/swords.dm | 8 +++--- .../objects/items/weapons/material/thrown.dm | 4 +-- .../objects/items/weapons/melee/energy.dm | 10 +++---- .../objects/items/weapons/melee/energy_axe.dm | 4 +-- code/game/objects/items/weapons/melee/misc.dm | 2 +- .../items/weapons/shields/shield_energy.dm | 2 +- .../items/weapons/shields/shield_riot.dm | 2 +- code/game/objects/items/weapons/stunbaton.dm | 2 -- .../objects/items/weapons/surgery_tools.dm | 12 ++++----- .../items/weapons/surgery_tools_ancient.dm | 2 +- .../items/weapons/tools/screwdriver.dm | 2 +- .../objects/items/weapons/tools/shears.dm | 4 +-- .../objects/items/weapons/tools/wirecutter.dm | 4 +-- code/game/objects/structures/__structure.dm | 2 +- code/game/objects/structures/bedsheet_bin.dm | 2 +- code/game/objects/structures/flora/_flora.dm | 2 +- code/game/objects/structures/flora/plant.dm | 2 +- code/game/objects/structures/seaweed.dm | 2 +- code/game/turfs/turf.dm | 2 +- code/game/turfs/walls/wall_attacks.dm | 2 +- code/modules/augment/active/armblades.dm | 4 +-- code/modules/clothing/_clothing.dm | 2 +- .../clothing/gloves/jewelry/rings/_ring.dm | 2 +- code/modules/clothing/head/fated_key.dm | 2 +- code/modules/economy/worth_items.dm | 2 +- code/modules/food/utensils/_utensil.dm | 10 +++---- code/modules/food/utensils/utensil_hybrid.dm | 16 ++++++------ code/modules/food/utensils/utensil_knife.dm | 4 +-- code/modules/hydroponics/seed.dm | 8 +++--- .../hydroponics/spreading/spreading.dm | 6 ++--- code/modules/hydroponics/trays/tray.dm | 2 +- code/modules/mob/grab/normal/grab_normal.dm | 4 +-- code/modules/mob/living/human/human.dm | 2 +- .../modules/mob/living/human/human_defense.dm | 6 ++--- .../mob/living/human/unarmed_attack.dm | 18 ++++++------- code/modules/mob/living/living_defense.dm | 2 +- .../mob/living/simple_animal/crow/crow.dm | 2 +- .../hostile/commanded/nanomachines.dm | 2 +- .../simple_animal/hostile/hivebots/megabot.dm | 4 +-- .../hostile/retaliate/king_of_goats.dm | 6 ++--- .../simple_animal/hostile/viscerator.dm | 4 +-- .../living/simple_animal/natural_weapons.dm | 10 +++---- code/modules/organs/external/_external.dm | 4 +-- code/modules/paperwork/pen/fancy.dm | 2 +- code/modules/paperwork/pen/quill_and_ink.dm | 2 +- code/modules/paperwork/pen/reagent_pen.dm | 2 +- code/modules/persistence/graffiti.dm | 2 +- code/modules/power/cable.dm | 5 +++- code/modules/power/lighting.dm | 2 +- .../projectiles/ammunition/chemdart.dm | 2 +- .../projectiles/guns/launcher/bows/arrow.dm | 4 +-- .../projectiles/guns/launcher/syringe_gun.dm | 4 +-- code/modules/projectiles/projectile/beams.dm | 16 ++++++------ .../reagent_containers/drinks/bottle.dm | 3 +-- .../reagents/reagent_containers/food/fish.dm | 2 +- .../reagents/reagent_containers/syringes.dm | 2 +- code/modules/recycling/wrapped_package.dm | 2 +- code/modules/species/species_attack.dm | 8 +++--- .../archetypes/tool_archetype_definitions.dm | 8 +++--- code/modules/tools/subtypes/axes.dm | 4 +-- code/modules/tools/subtypes/hammers.dm | 2 -- code/modules/tools/subtypes/hoes.dm | 4 +-- code/modules/tools/subtypes/pickaxes.dm | 4 +-- code/modules/tools/subtypes/shovel.dm | 8 +++--- .../tools/subtypes/xenoarchaeology_picks.dm | 26 +++++++++---------- code/modules/tools/tool.dm | 1 - .../xenoarcheaology/tools/core_sampler.dm | 2 +- maps/away/errant_pisces/errant_pisces.dm | 4 +-- .../content/item_sharpening/effect_sharpen.dm | 4 +-- mods/content/item_sharpening/item_sharpen.dm | 8 +++++- .../psionics/equipment/psipower_blade.dm | 4 +-- .../cult/mobs/constructs/constructs.dm | 4 +-- nebula.dme | 1 + 91 files changed, 249 insertions(+), 249 deletions(-) create mode 100644 code/game/objects/items/_item_sharpness.dm diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm index 32eac707ce72..88f8f402528e 100644 --- a/code/_helpers/unsorted.dm +++ b/code/_helpers/unsorted.dm @@ -692,23 +692,17 @@ Turf and target are seperate in case you want to teleport some distance from a t return zone_to_descriptor_mapping[zone] || zone //Whether or not the given item counts as sharp in terms of dealing damage -/proc/is_sharp(obj/O) - if (!O) return 0 - if (O.sharp) return 1 - if (O.edge) return 1 - return 0 +/obj/proc/is_sharp() + return FALSE //Whether or not the given item counts as cutting with an edge in terms of removing limbs -/proc/has_edge(obj/O) - if (!O) return 0 - if (O.edge) return 1 - return 0 - +/obj/proc/has_edge() + return FALSE //For items that can puncture e.g. thick plastic but aren't necessarily sharp //Returns 1 if the given item is capable of popping things like balloons, inflatable barriers, or cutting police tape. /obj/item/proc/can_puncture() - return sharp + return is_sharp() /obj/item/screwdriver/can_puncture() return 1 diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 76667e422706..f6cf807ccb17 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -85,7 +85,7 @@ avoid code duplication. This includes items that may sometimes act as a standard if(milkable.handle_milked(used_item, user)) return TRUE - if(used_item.edge && has_extension(src, /datum/extension/shearable)) + if(used_item.has_edge() && has_extension(src, /datum/extension/shearable)) var/datum/extension/shearable/shearable = get_extension(src, /datum/extension/shearable) if(shearable.handle_sheared(used_item, user)) return TRUE @@ -170,7 +170,7 @@ avoid code duplication. This includes items that may sometimes act as a standard /obj/item/proc/apply_hit_effect(mob/living/target, mob/living/user, var/hit_zone) var/use_hitsound = hitsound if(!use_hitsound) - if(edge || sharp) + if(has_edge() || is_sharp()) use_hitsound = 'sound/weapons/bladeslice.ogg' else use_hitsound = "swing_hit" diff --git a/code/game/objects/__objs.dm b/code/game/objects/__objs.dm index 8ab41e00a57f..bda29fadff27 100644 --- a/code/game/objects/__objs.dm +++ b/code/game/objects/__objs.dm @@ -14,8 +14,7 @@ var/list/req_access var/list/matter //Used to store information about the contents of the object. var/w_class // Size of the object. - var/sharp = 0 // whether this object cuts - var/edge = 0 // whether this object is more likely to dismember + var/in_use = 0 // If we have a user using us, this will be set on. We will check if the user has stopped using us, and thus stop updating and LAGGING EVERYTHING! var/armor_penetration = 0 var/anchor_fall = FALSE @@ -119,12 +118,12 @@ /obj/proc/damage_flags() . = 0 - if(has_edge(src)) - . |= DAM_EDGE - if(is_sharp(src)) - . |= DAM_SHARP + if(is_sharp()) + . |= DAM_SHARP|DAM_EDGE if(atom_damage_type == BURN) . |= DAM_LASER + else if(has_edge()) + . |= DAM_EDGE /obj/attackby(obj/item/used_item, mob/user) // We need to call parent even if we lack dexterity, so that storage can work. diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index a1a3fd87bd3c..07dab27d5ac2 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -43,7 +43,7 @@ var/damage = W.get_attack_force(user) / 4 - if(W.edge) + if(W.has_edge()) damage += 5 if(IS_WELDER(W)) diff --git a/code/game/objects/items/__item.dm b/code/game/objects/items/__item.dm index f90ecf6e4112..a19db6e1a1e4 100644 --- a/code/game/objects/items/__item.dm +++ b/code/game/objects/items/__item.dm @@ -1004,11 +1004,11 @@ modules/mob/living/human/life.dm if you die, you will be zoomed out. /obj/item/proc/get_autopsy_descriptors() var/list/descriptors = list() descriptors += w_class_description() - if(sharp) + if(is_sharp()) descriptors += "sharp" - if(edge) + if(has_edge()) descriptors += "edged" - if(get_attack_force(dry_run = TRUE) >= 10 && !sharp && !edge) + if(get_attack_force(dry_run = TRUE) >= 10 && !is_sharp() && !has_edge()) descriptors += "heavy" if(material) descriptors += "made of [material.solid_name]" diff --git a/code/game/objects/items/_item_force.dm b/code/game/objects/items/_item_force.dm index 86d105167cfd..5dbbbd01959c 100644 --- a/code/game/objects/items/_item_force.dm +++ b/code/game/objects/items/_item_force.dm @@ -45,18 +45,6 @@ _cached_attack_force = null _base_attack_force = new_force -/obj/item/proc/set_edge(new_edge) - if(edge != new_edge) - edge = new_edge - return TRUE - return FALSE - -/obj/item/proc/set_sharp(new_sharp) - if(sharp != new_sharp) - sharp = new_sharp - return TRUE - return FALSE - /obj/item/proc/update_attack_force() // Get our base force. @@ -68,14 +56,14 @@ // Check if this material is hard enough to hold an edge. if(!material.can_hold_edge()) set_edge(FALSE) - else if(!edge) - set_edge(initial(edge)) + else if(!_edge) + set_edge(initial(_edge)) // Check if this material can hold a point. if(!material.can_hold_sharpness()) set_sharp(FALSE) - else if(!sharp) - set_sharp(initial(sharp)) + else if(!_sharp) + set_sharp(initial(_sharp)) // Work out where we're going to cap our calculated force. // Any additional force resulting from hardness or weight turn into armour penetration. @@ -119,7 +107,7 @@ var/list/item_effects = weapon.get_item_effects(IE_CAT_DAMAGE) if(length(item_effects)) for(var/decl/item_effect/damage_effect as anything in item_effects) - . = damage_effect.modify_attack_damage(., weapon, src, parameters = item_effects[damage_effect]) + . = damage_effect.modify_attack_damage(., weapon, src, dry_run, item_effects[damage_effect]) return round(.) // Debug proc - leaving in for future work. Linter hates protected var access so leave commented. @@ -164,7 +152,7 @@ (attk_force + expected_material_mod), (attk_force * item._wielded_force_multiplier), item.armor_penetration, - (item.sharp||item.edge) + (item._sharp|item._edge) ), "|") text2file(jointext(rows, "\n"), "weapon_stats_dump.csv") diff --git a/code/game/objects/items/_item_sharpness.dm b/code/game/objects/items/_item_sharpness.dm new file mode 100644 index 000000000000..f1ed8fd10237 --- /dev/null +++ b/code/game/objects/items/_item_sharpness.dm @@ -0,0 +1,21 @@ +/obj/item + var/_sharp = FALSE + var/_edge = FALSE + +/obj/item/is_sharp() + return _sharp + +/obj/item/has_edge() + return _edge + +/obj/item/proc/set_edge(new_edge) + if(_edge != new_edge) + _edge = new_edge + return TRUE + return FALSE + +/obj/item/proc/set_sharp(new_sharp) + if(_sharp != new_sharp) + _sharp = new_sharp + return TRUE + return FALSE diff --git a/code/game/objects/items/blades/_blade.dm b/code/game/objects/items/blades/_blade.dm index 19dbcbce1cd6..5609760df9c1 100644 --- a/code/game/objects/items/blades/_blade.dm +++ b/code/game/objects/items/blades/_blade.dm @@ -6,8 +6,8 @@ origin_tech = @'{"materials":1,"combat":1}' attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") obj_flags = OBJ_FLAG_CONDUCTIBLE - sharp = TRUE - edge = TRUE + _sharp = TRUE + _edge = TRUE item_flags = ITEM_FLAG_IS_WEAPON pickup_sound = 'sound/foley/knife1.ogg' drop_sound = 'sound/foley/knifedrop3.ogg' diff --git a/code/game/objects/items/blades/folding.dm b/code/game/objects/items/blades/folding.dm index 9617f3cbb84b..12bc613fa288 100644 --- a/code/game/objects/items/blades/folding.dm +++ b/code/game/objects/items/blades/folding.dm @@ -3,7 +3,7 @@ desc = "A small folding knife." icon = 'icons/obj/items/bladed/folding.dmi' w_class = ITEM_SIZE_SMALL - sharp = FALSE + _sharp = FALSE pommel_material = null guard_material = null slot_flags = null @@ -53,9 +53,8 @@ /obj/item/bladed/folding/update_attack_force() ..() - // TODO: check sharp/edge. - edge = open - sharp = open + set_edge(open) + set_sharp(open) if(open) w_class = open_item_size attack_verb = open_attack_verbs diff --git a/code/game/objects/items/blades/spear.dm b/code/game/objects/items/blades/spear.dm index 8659642ba913..6991d988a51f 100644 --- a/code/game/objects/items/blades/spear.dm +++ b/code/game/objects/items/blades/spear.dm @@ -3,8 +3,8 @@ desc = "A haphazardly-constructed yet still deadly weapon of ancient design." icon = 'icons/obj/items/bladed/spear.dmi' throw_speed = 3 - edge = 0 - sharp = 1 + _edge = FALSE + _sharp = TRUE attack_verb = list("attacked", "poked", "jabbed", "torn", "gored") does_spin = FALSE abstract_type = /obj/item/bladed/polearm/spear diff --git a/code/game/objects/items/rock.dm b/code/game/objects/items/rock.dm index 4a57b5ab4dde..94611df6bdd3 100644 --- a/code/game/objects/items/rock.dm +++ b/code/game/objects/items/rock.dm @@ -3,8 +3,8 @@ desc = "The secret is to bang the rocks together, guys." icon = 'icons/obj/items/rock.dmi' icon_state = ICON_STATE_WORLD - sharp = TRUE - edge = TRUE + _sharp = TRUE + _edge = TRUE _base_attack_force = 3 material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME w_class = ITEM_SIZE_SMALL @@ -49,6 +49,6 @@ name = "striker" desc = "A squared-off, rather worn-down piece of stone." icon = 'icons/obj/items/striker.dmi' - sharp = FALSE - edge = FALSE + _sharp = FALSE + _edge = FALSE w_class = ITEM_SIZE_TINY \ No newline at end of file diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index b91bf589f2cc..424992dba80d 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -144,8 +144,8 @@ /obj/item/energy_blade/sword/toy name = "toy sword" desc = "A cheap, plastic replica of an energy sword. Realistic sounds! Ages 8 and up." - sharp = FALSE - edge = FALSE + _sharp = FALSE + _edge = FALSE attack_verb = list("hit") material = /decl/material/solid/organic/plastic active_hitsound = 'sound/weapons/genhit.ogg' @@ -497,8 +497,8 @@ desc = "An arcane weapon (made of foam) wielded by the followers of the hit Saturday morning cartoon \"King Nursee and the Acolytes of Heroism\"." icon = 'icons/obj/items/weapon/swords/cult.dmi' material = /decl/material/solid/organic/plastic/foam - edge = 0 - sharp = 0 + _edge = FALSE + _sharp = FALSE /obj/item/inflatable_duck //#TODO: Move under obj/item/toy ? name = "inflatable duck" diff --git a/code/game/objects/items/weapons/material/folding.dm b/code/game/objects/items/weapons/material/folding.dm index 46a631afe6db..cdbc0a29a09a 100644 --- a/code/game/objects/items/weapons/material/folding.dm +++ b/code/game/objects/items/weapons/material/folding.dm @@ -6,8 +6,8 @@ icon = 'icons/obj/items/weapon/knives/folding/basic.dmi' w_class = ITEM_SIZE_SMALL attack_verb = list("prodded", "tapped") - edge = FALSE - sharp = FALSE + _edge = FALSE + _sharp = FALSE draw_handle = TRUE valid_handle_colors = list(COLOR_DARK_GRAY, COLOR_RED_GRAY, COLOR_BLUE_GRAY, COLOR_DARK_BLUE_GRAY, COLOR_GREEN_GRAY, COLOR_DARK_GREEN_GRAY) material = /decl/material/solid/metal/steel @@ -29,15 +29,14 @@ /obj/item/knife/folding/update_attack_force() ..() if(open) - // TODO: check sharp/edge. - edge = TRUE - sharp = TRUE + set_edge(TRUE) + set_sharp(TRUE) w_class = ITEM_SIZE_NORMAL attack_verb = list("slashed", "stabbed") ..() else - edge = initial(edge) - sharp = initial(sharp) + set_edge(initial(_edge)) + set_sharp(initial(_sharp)) w_class = initial(w_class) attack_verb = closed_attack_verbs diff --git a/code/game/objects/items/weapons/material/knives.dm b/code/game/objects/items/weapons/material/knives.dm index 9df9b46dc099..8c0f344729bb 100644 --- a/code/game/objects/items/weapons/material/knives.dm +++ b/code/game/objects/items/weapons/material/knives.dm @@ -8,8 +8,8 @@ material = /decl/material/solid/metal/steel origin_tech = @'{"materials":1}' obj_flags = OBJ_FLAG_CONDUCTIBLE - sharp = TRUE - edge = TRUE + _sharp = TRUE + _edge = TRUE item_flags = ITEM_FLAG_CAN_HIDE_IN_SHOES | ITEM_FLAG_IS_WEAPON material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME pickup_sound = 'sound/foley/knife1.ogg' @@ -104,7 +104,7 @@ name = "meat hook" desc = "A sharp, metal hook what sticks into things." icon = 'icons/obj/items/weapon/knives/hook.dmi' - sharp = FALSE + _sharp = FALSE /obj/item/knife/ritual name = "ritual knife" diff --git a/code/game/objects/items/weapons/material/misc.dm b/code/game/objects/items/weapons/material/misc.dm index 941dd4fd8cc1..5a2c02a2b3ee 100644 --- a/code/game/objects/items/weapons/material/misc.dm +++ b/code/game/objects/items/weapons/material/misc.dm @@ -1,8 +1,8 @@ /obj/item/harpoon name = "harpoon" desc = "A short throwing spear with a deep barb, specifically designed to embed itself in its target." - sharp = 1 - edge = 1 + _sharp = TRUE + _edge = TRUE icon = 'icons/obj/items/weapon/harpoon.dmi' icon_state = "harpoon" item_state = "harpoon" @@ -39,16 +39,16 @@ SetName("broken harpoon") desc = "A short spear with just a barb - if it once had a spearhead, it doesn't any more." icon_state = "harpoon_bomb_spent" - sharp = FALSE - edge = FALSE + _sharp = FALSE + _edge = FALSE /obj/item/scythe name = "scythe" desc = "A sharp and curved blade on a long fibremetal handle, this tool makes it easy to reap what you sow." icon = 'icons/obj/items/tool/scythe.dmi' icon_state = ICON_STATE_WORLD - sharp = 1 - edge = 1 + _sharp = TRUE + _edge = TRUE throw_speed = 1 throw_range = 3 w_class = ITEM_SIZE_HUGE diff --git a/code/game/objects/items/weapons/material/shards.dm b/code/game/objects/items/weapons/material/shards.dm index 7ff92bf32ad2..2f558ddead6e 100644 --- a/code/game/objects/items/weapons/material/shards.dm +++ b/code/game/objects/items/weapons/material/shards.dm @@ -6,8 +6,8 @@ desc = "Made of nothing. How does this even exist?" // set based on material, if this desc is visible it's a bug (shards default to being made of glass) icon_state = "large" randpixel = 8 - sharp = 1 - edge = 1 + _sharp = TRUE + _edge = TRUE w_class = ITEM_SIZE_SMALL item_state = "shard-glass" attack_verb = list("stabbed", "slashed", "sliced", "cut") diff --git a/code/game/objects/items/weapons/material/stick.dm b/code/game/objects/items/weapons/material/stick.dm index a124a6644bce..7f6fe9941035 100644 --- a/code/game/objects/items/weapons/material/stick.dm +++ b/code/game/objects/items/weapons/material/stick.dm @@ -16,17 +16,17 @@ /obj/item/stick/attackby(obj/item/W, mob/user) - if(W.sharp && W.edge && !sharp) + if(W.is_sharp() && W.has_edge() && !_sharp) user.visible_message("[user] sharpens [src] with [W].", "You sharpen [src] using [W].") - sharp = 1 //Sharpen stick + set_sharp(TRUE) SetName("sharpened " + name) update_attack_force() return TRUE - if(!sharp && (istype(W, /obj/item/stack/material/bolt) || istype(W, /obj/item/stack/material/bundle))) + if(!_sharp && (istype(W, /obj/item/stack/material/bolt) || istype(W, /obj/item/stack/material/bundle))) var/choice = input(user, "Do you want to make a torch, or a splint?", "Stick Crafting") as null|anything in list("Torch", "Splint") - if(!choice || QDELETED(user) || user.get_active_held_item() != W || QDELETED(W) || !QDELETED(src) || (loc != user && !Adjacent(user)) || sharp) + if(!choice || QDELETED(user) || user.get_active_held_item() != W || QDELETED(W) || !QDELETED(src) || (loc != user && !Adjacent(user)) || _sharp) return TRUE var/obj/item/stack/material/cloth = W diff --git a/code/game/objects/items/weapons/material/swiss.dm b/code/game/objects/items/weapons/material/swiss.dm index 81f5700ebd1c..122550c521bb 100644 --- a/code/game/objects/items/weapons/material/swiss.dm +++ b/code/game/objects/items/weapons/material/swiss.dm @@ -102,8 +102,8 @@ else siemens_coefficient = initial(siemens_coefficient) else - edge = initial(edge) - sharp = initial(sharp) + set_edge(initial(_edge)) + set_sharp(initial(_sharp)) attack_verb = closed_attack_verbs siemens_coefficient = initial(siemens_coefficient) diff --git a/code/game/objects/items/weapons/material/swords.dm b/code/game/objects/items/weapons/material/swords.dm index 19a54e6ac778..535a726060f6 100644 --- a/code/game/objects/items/weapons/material/swords.dm +++ b/code/game/objects/items/weapons/material/swords.dm @@ -7,8 +7,8 @@ w_class = ITEM_SIZE_LARGE item_flags = ITEM_FLAG_IS_WEAPON armor_penetration = 10 - sharp = 1 - edge = 1 + _sharp = TRUE + _edge = TRUE attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") hitsound = 'sound/weapons/bladeslice.ogg' base_parry_chance = 50 @@ -22,13 +22,13 @@ /obj/item/edge/set_edge(new_edge) . = ..() - if(. && !edge) + if(. && !has_edge()) attack_verb = list("attacked", "stabbed", "jabbed", "smacked", "prodded") hitsound = 'sound/weapons/pierce.ogg' /obj/item/sword/set_sharp(new_sharp) . = ..() - if(. && !sharp) + if(. && !is_sharp()) attack_verb = list("attacked", "smashed", "jabbed", "smacked", "prodded", "bonked") hitsound = "chop" diff --git a/code/game/objects/items/weapons/material/thrown.dm b/code/game/objects/items/weapons/material/thrown.dm index 427fffbe1022..d5c13d31e820 100644 --- a/code/game/objects/items/weapons/material/thrown.dm +++ b/code/game/objects/items/weapons/material/thrown.dm @@ -6,8 +6,8 @@ randpixel = 12 throw_speed = 10 throw_range = 15 - sharp = 1 - edge = 1 + _sharp = TRUE + _edge = TRUE material = /decl/material/solid/metal/steel material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME item_flags = ITEM_FLAG_IS_WEAPON diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm index 47de3c87b7ba..90ba45281578 100644 --- a/code/game/objects/items/weapons/melee/energy.dm +++ b/code/game/objects/items/weapons/melee/energy.dm @@ -13,8 +13,6 @@ _base_attack_force = 3 // bonk throw_speed = 1 throw_range = 5 - sharp = 0 - edge = 0 armor_penetration = 0 material = /decl/material/solid/metal/steel @@ -90,8 +88,8 @@ if(active) obj_flags |= OBJ_FLAG_NO_STORAGE - sharp = active_sharp - edge = active_edge + set_sharp(active_sharp) + set_edge(active_edge) base_parry_chance = active_parry_chance armor_penetration = active_armour_pen hitsound = active_hitsound @@ -105,8 +103,8 @@ else obj_flags &= ~OBJ_FLAG_NO_STORAGE - sharp = initial(sharp) - edge = initial(edge) + set_sharp(initial(_sharp)) + set_edge(initial(_edge)) base_parry_chance = initial(base_parry_chance) armor_penetration = initial(armor_penetration) hitsound = initial(hitsound) diff --git a/code/game/objects/items/weapons/melee/energy_axe.dm b/code/game/objects/items/weapons/melee/energy_axe.dm index e70d70971f59..7a052e548c14 100644 --- a/code/game/objects/items/weapons/melee/energy_axe.dm +++ b/code/game/objects/items/weapons/melee/energy_axe.dm @@ -12,8 +12,8 @@ origin_tech = @'{"magnets":3,"combat":4}' active_attack_verb = list("attacked", "chopped", "cleaved", "torn", "cut") inactive_attack_verb = list("attacked", "chopped", "cleaved", "torn", "cut") - sharp = 1 - edge = 1 + _sharp = TRUE + _edge = TRUE base_parry_chance = 30 active_parry_chance = 30 melee_accuracy_bonus = 15 diff --git a/code/game/objects/items/weapons/melee/misc.dm b/code/game/objects/items/weapons/melee/misc.dm index a1b4938bacf0..bee2f881dc50 100644 --- a/code/game/objects/items/weapons/melee/misc.dm +++ b/code/game/objects/items/weapons/melee/misc.dm @@ -32,7 +32,7 @@ item_state = "whip" obj_flags = null _base_attack_force = 19 - edge = TRUE + _edge = TRUE origin_tech = @'{"combat":6,"materials":5}' material = /decl/material/solid/organic/leather/lizard diff --git a/code/game/objects/items/weapons/shields/shield_energy.dm b/code/game/objects/items/weapons/shields/shield_energy.dm index 4b028ca79316..c7d54652a56e 100644 --- a/code/game/objects/items/weapons/shields/shield_energy.dm +++ b/code/game/objects/items/weapons/shields/shield_energy.dm @@ -41,7 +41,7 @@ /obj/item/shield/energy/get_block_chance(mob/user, var/damage, atom/damage_source = null, mob/attacker = null) if(istype(damage_source, /obj/item/projectile)) var/obj/item/projectile/P = damage_source - if((is_sharp(P) && damage > 10) || istype(P, /obj/item/projectile/beam)) + if(((P.is_sharp() || P.has_edge()) && damage > 10) || istype(P, /obj/item/projectile/beam)) return (base_block_chance - round(damage / 2.5)) //block bullets and beams using the old block chance return base_block_chance diff --git a/code/game/objects/items/weapons/shields/shield_riot.dm b/code/game/objects/items/weapons/shields/shield_riot.dm index 378ae85d9f0e..0cc0c9324f0a 100644 --- a/code/game/objects/items/weapons/shields/shield_riot.dm +++ b/code/game/objects/items/weapons/shields/shield_riot.dm @@ -24,7 +24,7 @@ if(istype(damage_source, /obj/item/projectile)) var/obj/item/projectile/P = damage_source //plastic shields do not stop bullets or lasers, even in space. Will block beanbags, rubber bullets, and stunshots just fine though. - if(is_sharp(P) && damage >= max_block) + if((P.is_sharp() || P.has_edge()) && damage >= max_block) return 0 if(istype(P, /obj/item/projectile/beam) && (!can_block_lasers || (P.armor_penetration >= max_block))) return 0 diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index eec6eb5e83a0..f1d555da4d0b 100644 --- a/code/game/objects/items/weapons/stunbaton.dm +++ b/code/game/objects/items/weapons/stunbaton.dm @@ -5,8 +5,6 @@ icon = 'icons/obj/items/weapon/stunbaton.dmi' icon_state = ICON_STATE_WORLD slot_flags = SLOT_LOWER_BODY - sharp = 0 - edge = 0 w_class = ITEM_SIZE_NORMAL origin_tech = @'{"combat":2}' attack_verb = list("beaten") diff --git a/code/game/objects/items/weapons/surgery_tools.dm b/code/game/objects/items/weapons/surgery_tools.dm index c5b1f30ef204..68c683beb976 100644 --- a/code/game/objects/items/weapons/surgery_tools.dm +++ b/code/game/objects/items/weapons/surgery_tools.dm @@ -99,8 +99,8 @@ icon = 'icons/obj/surgery.dmi' icon_state = "scalpel" obj_flags = OBJ_FLAG_CONDUCTIBLE - sharp = 1 - edge = 1 + _sharp = TRUE + _edge = TRUE w_class = ITEM_SIZE_TINY slot_flags = SLOT_EARS throw_speed = 3 @@ -160,8 +160,8 @@ /obj/item/incision_manager name = "incision management system" desc = "A true extension of the surgeon's body, this marvel combines several medical tools into one modular package." - sharp = 1 - edge = 1 + _sharp = TRUE + _edge = TRUE atom_damage_type = BURN icon = 'icons/obj/surgery.dmi' icon_state = "scalpel_manager_on" @@ -202,8 +202,8 @@ material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) attack_verb = list("attacked", "slashed", "sawed", "cut") - sharp = 1 - edge = 1 + _sharp = TRUE + _edge = TRUE pickup_sound = 'sound/foley/pickup2.ogg' drop_sound = 'sound/foley/knifedrop3.ogg' _base_attack_force = 15 diff --git a/code/game/objects/items/weapons/surgery_tools_ancient.dm b/code/game/objects/items/weapons/surgery_tools_ancient.dm index f6f31166bfac..57e06a3d62db 100644 --- a/code/game/objects/items/weapons/surgery_tools_ancient.dm +++ b/code/game/objects/items/weapons/surgery_tools_ancient.dm @@ -55,7 +55,7 @@ name = "scalpel" desc = "A short, wickedly sharp blade used for making incisions and cutting through flesh." icon = 'icons/obj/items/surgery/scalpel.dmi' - sharp = TRUE + _sharp = TRUE _base_attack_force = 8 /obj/item/ancient_surgery/scalpel/get_tool_properties() diff --git a/code/game/objects/items/weapons/tools/screwdriver.dm b/code/game/objects/items/weapons/tools/screwdriver.dm index d16e6c230f38..ae59281a05eb 100644 --- a/code/game/objects/items/weapons/tools/screwdriver.dm +++ b/code/game/objects/items/weapons/tools/screwdriver.dm @@ -9,7 +9,7 @@ center_of_mass = @'{"x":16,"y":7}' attack_verb = list("stabbed") lock_picking_level = 5 - sharp = TRUE + _sharp = TRUE material_alteration = MAT_FLAG_ALTERATION_COLOR drop_sound = 'sound/foley/singletooldrop2.ogg' diff --git a/code/game/objects/items/weapons/tools/shears.dm b/code/game/objects/items/weapons/tools/shears.dm index c57dff7b9e20..e18dd843721f 100644 --- a/code/game/objects/items/weapons/tools/shears.dm +++ b/code/game/objects/items/weapons/tools/shears.dm @@ -8,8 +8,8 @@ material = /decl/material/solid/metal/steel center_of_mass = @'{"x":18,"y":10}' attack_verb = list("sheared", "cut") - sharp = 1 - edge = 1 + _sharp = TRUE + _edge = TRUE material_alteration = MAT_FLAG_ALTERATION_COLOR drop_sound = 'sound/foley/singletooldrop1.ogg' diff --git a/code/game/objects/items/weapons/tools/wirecutter.dm b/code/game/objects/items/weapons/tools/wirecutter.dm index 2886de69bc3e..e5e64b9e5d6d 100644 --- a/code/game/objects/items/weapons/tools/wirecutter.dm +++ b/code/game/objects/items/weapons/tools/wirecutter.dm @@ -9,8 +9,8 @@ material = /decl/material/solid/metal/steel center_of_mass = @'{"x":18,"y":10}' attack_verb = list("pinched", "nipped") - sharp = 1 - edge = 1 + _sharp = TRUE + _edge = TRUE material_alteration = MAT_FLAG_ALTERATION_COLOR drop_sound = 'sound/foley/singletooldrop1.ogg' diff --git a/code/game/objects/structures/__structure.dm b/code/game/objects/structures/__structure.dm index f1fb8d4a2c11..875f633e4558 100644 --- a/code/game/objects/structures/__structure.dm +++ b/code/game/objects/structures/__structure.dm @@ -245,7 +245,7 @@ playsound(loc, 'sound/weapons/tablehit1.ogg', 50, 1) var/list/L = take_damage(rand(1,5)) for(var/obj/item/shard/S in L) - if(S.sharp && prob(50)) + if(S.is_sharp() && prob(50)) victim.visible_message( SPAN_DANGER("\The [S] slices into [victim]'s face!"), SPAN_DANGER("\The [S] slices into your face!") diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index bca9199f37db..50fb98d51d08 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -19,7 +19,7 @@ LINEN BINS material = /decl/material/solid/organic/cloth /obj/item/bedsheet/attackby(obj/item/I, mob/user) - if(is_sharp(I)) + if(I.is_sharp() || I.has_edge()) user.visible_message("\The [user] begins cutting up \the [src] with \a [I].", "You begin cutting up \the [src] with \the [I].") if(do_after(user, 50, src)) to_chat(user, "You cut \the [src] into pieces!") diff --git a/code/game/objects/structures/flora/_flora.dm b/code/game/objects/structures/flora/_flora.dm index 5395ed57f9a3..5e4be61b738b 100644 --- a/code/game/objects/structures/flora/_flora.dm +++ b/code/game/objects/structures/flora/_flora.dm @@ -34,7 +34,7 @@ /**Whether the item used by user can cause cut_down to be called. Used to bypass default attack proc for some specific items/tools. */ /obj/structure/flora/proc/can_cut_down(var/obj/item/I, var/mob/user) - return (I.get_attack_force(user) >= 5) && I.sharp //Anything sharp and relatively strong can cut us instantly + return (I.get_attack_force(user) >= 5) && I.is_sharp() //Anything sharp and relatively strong can cut us instantly /**What to do when the can_cut_down check returns true. Normally simply calls dismantle. */ /obj/structure/flora/proc/play_cut_sound(mob/user) diff --git a/code/game/objects/structures/flora/plant.dm b/code/game/objects/structures/flora/plant.dm index 615e9229cb48..ceb0b5e205e3 100644 --- a/code/game/objects/structures/flora/plant.dm +++ b/code/game/objects/structures/flora/plant.dm @@ -81,7 +81,7 @@ return TRUE // Hydrotray boilerplate for taking samples. - if(O.edge && O.w_class < ITEM_SIZE_NORMAL && !user.check_intent(I_FLAG_HARM)) + if(O.has_edge() && O.w_class < ITEM_SIZE_NORMAL && !user.check_intent(I_FLAG_HARM)) if(sampled) to_chat(user, SPAN_WARNING("There's no bits that can be used for a sampling left.")) return TRUE diff --git a/code/game/objects/structures/seaweed.dm b/code/game/objects/structures/seaweed.dm index 52a5af6125c8..a76e6f838870 100644 --- a/code/game/objects/structures/seaweed.dm +++ b/code/game/objects/structures/seaweed.dm @@ -31,7 +31,7 @@ icon = 'icons/obj/structures/plants.dmi' /obj/effect/decal/cleanable/lichen/attackby(obj/item/I, mob/user) - if(I.sharp && I.get_attack_force(user) > 1) + if(I.is_sharp() && I.get_attack_force(user) > 1) qdel(src) return TRUE . = ..() \ No newline at end of file diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 0563fd5715fe..e220ed3dd365 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -445,7 +445,7 @@ /turf/proc/try_graffiti(var/mob/vandal, var/obj/item/tool) - if(!tool.sharp || !can_engrave() || !vandal.check_intent(I_FLAG_HELP)) + if(!tool.is_sharp() || !can_engrave() || !vandal.check_intent(I_FLAG_HELP)) return FALSE if(jobban_isbanned(vandal, "Graffiti")) diff --git a/code/game/turfs/walls/wall_attacks.dm b/code/game/turfs/walls/wall_attacks.dm index 4f82673b1321..9986a22f4b11 100644 --- a/code/game/turfs/walls/wall_attacks.dm +++ b/code/game/turfs/walls/wall_attacks.dm @@ -133,7 +133,7 @@ return TRUE else var/force = W.get_attack_force(user) - if((!is_sharp(W) && force >= 10) || force >= 20) + if((!W.is_sharp() && !W.has_edge() && force >= 10) || force >= 20) to_chat(user, "\The [src] crumbles away under the force of your [W.name].") physically_destroyed() return TRUE diff --git a/code/modules/augment/active/armblades.dm b/code/modules/augment/active/armblades.dm index 1f214a266fed..1f36cb7b1d26 100644 --- a/code/modules/augment/active/armblades.dm +++ b/code/modules/augment/active/armblades.dm @@ -5,8 +5,8 @@ icon = 'icons/obj/augment.dmi' desc = "A handy utility blade for the discerning augmentee. Warranty void if used for cutting." base_parry_chance = 30 - sharp = 1 - edge = 1 + _sharp = TRUE + _edge = TRUE attack_verb = list("stabbed", "sliced", "cut") origin_tech = @'{"materials":1,"engineering":1,"combat":2}' material = /decl/material/solid/metal/steel diff --git a/code/modules/clothing/_clothing.dm b/code/modules/clothing/_clothing.dm index b51dfb2f51e3..5cdecafa6eaa 100644 --- a/code/modules/clothing/_clothing.dm +++ b/code/modules/clothing/_clothing.dm @@ -100,7 +100,7 @@ /obj/item/clothing/attackby(obj/item/I, mob/user) var/rags = RAG_COUNT(src) - if(istype(material) && material.default_solid_form && rags && (I.edge || I.sharp) && user.check_intent(I_FLAG_HARM)) + if(istype(material) && material.default_solid_form && rags && (I.is_sharp() || I.has_edge()) && user.check_intent(I_FLAG_HARM)) if(length(accessories)) to_chat(user, SPAN_WARNING("You should remove the accessories attached to \the [src] first.")) return TRUE diff --git a/code/modules/clothing/gloves/jewelry/rings/_ring.dm b/code/modules/clothing/gloves/jewelry/rings/_ring.dm index b9e58beedf62..aadeedab5589 100644 --- a/code/modules/clothing/gloves/jewelry/rings/_ring.dm +++ b/code/modules/clothing/gloves/jewelry/rings/_ring.dm @@ -54,7 +54,7 @@ desc = "[base_desc] [desc]" /obj/item/clothing/gloves/ring/attackby(var/obj/item/tool, var/mob/user) - if(can_inscribe && tool.sharp && user.check_intent(I_FLAG_HELP)) + if(can_inscribe && tool.is_sharp() && user.check_intent(I_FLAG_HELP)) var/new_inscription = sanitize(input("Enter an inscription to engrave.", "Inscription") as null|text) if(user.stat || !user.incapacitated() || !user.Adjacent(src) || tool.loc != user) return TRUE diff --git a/code/modules/clothing/head/fated_key.dm b/code/modules/clothing/head/fated_key.dm index cc65bd802395..24bc19943477 100644 --- a/code/modules/clothing/head/fated_key.dm +++ b/code/modules/clothing/head/fated_key.dm @@ -51,7 +51,7 @@ var/atom/blade for(var/obj/item/held in shuffle(user.get_held_items())) - if(has_edge(held)) + if(held.has_edge()) blade = held break if(!blade) diff --git a/code/modules/economy/worth_items.dm b/code/modules/economy/worth_items.dm index ce2d11ae8be7..74a54ebd26e2 100644 --- a/code/modules/economy/worth_items.dm +++ b/code/modules/economy/worth_items.dm @@ -21,7 +21,7 @@ . += largest_tech_val if((item_flags & ITEM_FLAG_IS_WEAPON) && get_base_attack_force()) - var/weapon_value = ((get_max_weapon_force() * 15) * (1 + max(sharp, edge))) + var/weapon_value = ((get_max_weapon_force() * 15) * (1 + max(_sharp, _edge))) if(attack_cooldown <= FAST_WEAPON_COOLDOWN) weapon_value *= 1.5 else if(attack_cooldown >= SLOW_WEAPON_COOLDOWN) diff --git a/code/modules/food/utensils/_utensil.dm b/code/modules/food/utensils/_utensil.dm index adabd99b0366..7bc767b24e00 100644 --- a/code/modules/food/utensils/_utensil.dm +++ b/code/modules/food/utensils/_utensil.dm @@ -17,8 +17,6 @@ w_class = ITEM_SIZE_SMALL origin_tech = @'{"materials":1}' attack_verb = list("attacked", "stabbed", "poked") - sharp = FALSE - edge = FALSE material = /decl/material/solid/metal/aluminium material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME @@ -121,8 +119,8 @@ /obj/item/food/proc/do_utensil_interaction(obj/item/tool, mob/user) // Non-utensils. - if(tool && !istype(tool, /obj/item/utensil)) - return has_edge(tool) && (utensil_flags & UTENSIL_FLAG_SLICE) && handle_utensil_cutting(tool, user) + if(istype(tool) && !istype(tool, /obj/item/utensil)) + return tool.has_edge() && (utensil_flags & UTENSIL_FLAG_SLICE) && handle_utensil_cutting(tool, user) var/obj/item/utensil/utensil = tool if(!istype(utensil) || !utensil.utensil_flags) @@ -131,9 +129,9 @@ if(!handle_utensil_spreading(utensil, user)) to_chat(user, SPAN_WARNING("You already have something on \the [utensil].")) return TRUE - if((utensil.edge || (utensil.utensil_flags & UTENSIL_FLAG_SLICE)) && (utensil_flags & UTENSIL_FLAG_SLICE) && handle_utensil_cutting(utensil, user)) + if((utensil.has_edge() || (utensil.utensil_flags & UTENSIL_FLAG_SLICE)) && (utensil_flags & UTENSIL_FLAG_SLICE) && handle_utensil_cutting(utensil, user)) return TRUE - if((utensil.sharp || (utensil.utensil_flags & UTENSIL_FLAG_COLLECT)) && (utensil_flags & UTENSIL_FLAG_COLLECT) && handle_utensil_collection(utensil, user)) + if((utensil.is_sharp() || (utensil.utensil_flags & UTENSIL_FLAG_COLLECT)) && (utensil_flags & UTENSIL_FLAG_COLLECT) && handle_utensil_collection(utensil, user)) return TRUE if((utensil.utensil_flags & UTENSIL_FLAG_SCOOP) && (utensil_flags & UTENSIL_FLAG_SCOOP) && handle_utensil_scooping(utensil, user)) return TRUE diff --git a/code/modules/food/utensils/utensil_hybrid.dm b/code/modules/food/utensils/utensil_hybrid.dm index d7ad70bed87a..c365e068dcef 100644 --- a/code/modules/food/utensils/utensil_hybrid.dm +++ b/code/modules/food/utensils/utensil_hybrid.dm @@ -1,18 +1,18 @@ /obj/item/utensil/spork - name = "spork" - desc = "It's a spork. It's much like a fork, but much blunter." - icon = 'icons/obj/food/utensils/spork.dmi' + name = "spork" + desc = "It's a spork. It's much like a fork, but much blunter." + icon = 'icons/obj/food/utensils/spork.dmi' utensil_flags = UTENSIL_FLAG_COLLECT | UTENSIL_FLAG_SCOOP /obj/item/utensil/spork/plastic material = /decl/material/solid/organic/plastic /obj/item/utensil/foon - name = "foon" - desc = "It's a foon. It's much like a spoon, but much sharper." - icon = 'icons/obj/food/utensils/foon.dmi' - sharp = TRUE - edge = TRUE + name = "foon" + desc = "It's a foon. It's much like a spoon, but much sharper." + icon = 'icons/obj/food/utensils/foon.dmi' + _sharp = TRUE + _edge = TRUE utensil_flags = UTENSIL_FLAG_SLICE | UTENSIL_FLAG_SCOOP /obj/item/utensil/foon/plastic diff --git a/code/modules/food/utensils/utensil_knife.dm b/code/modules/food/utensils/utensil_knife.dm index fd98a7d568fd..59307a246cc7 100644 --- a/code/modules/food/utensils/utensil_knife.dm +++ b/code/modules/food/utensils/utensil_knife.dm @@ -11,8 +11,8 @@ name = "steak knife" desc = "It's a steak knife with a serrated edge." icon = 'icons/obj/food/utensils/steak_knife.dmi' - sharp = TRUE - edge = TRUE + _sharp = TRUE + _edge = TRUE utensil_flags = UTENSIL_FLAG_SLICE material = /decl/material/solid/metal/steel _base_attack_force = 6 diff --git a/code/modules/hydroponics/seed.dm b/code/modules/hydroponics/seed.dm index 873ec702462e..01e90e6adcfe 100644 --- a/code/modules/hydroponics/seed.dm +++ b/code/modules/hydroponics/seed.dm @@ -131,23 +131,23 @@ return var/damage = 0 - var/has_edge = 0 + var/edged = 0 if(get_trait(TRAIT_CARNIVOROUS) >= 2) if(affecting) to_chat(target, "\The [fruit]'s thorns pierce your [affecting.name] greedily!") else to_chat(target, "\The [fruit]'s thorns pierce your flesh greedily!") damage = max(5, round(15*get_trait(TRAIT_POTENCY)/100, 1)) - has_edge = prob(get_trait(TRAIT_POTENCY)/2) + edged = prob(get_trait(TRAIT_POTENCY)/2) else if(affecting) to_chat(target, "\The [fruit]'s thorns dig deeply into your [affecting.name]!") else to_chat(target, "\The [fruit]'s thorns dig deeply into your flesh!") damage = max(1, round(5*get_trait(TRAIT_POTENCY)/100, 1)) - has_edge = prob(get_trait(TRAIT_POTENCY)/5) + edged = prob(get_trait(TRAIT_POTENCY)/5) - var/damage_flags = DAM_SHARP|(has_edge? DAM_EDGE : 0) + var/damage_flags = DAM_SHARP|(edged? DAM_EDGE : 0) target.apply_damage(damage, BRUTE, target_limb, damage_flags, used_weapon = "Thorns") // Adds reagents to a target. diff --git a/code/modules/hydroponics/spreading/spreading.dm b/code/modules/hydroponics/spreading/spreading.dm index bd7c4a3fb0f3..533555b7c061 100644 --- a/code/modules/hydroponics/spreading/spreading.dm +++ b/code/modules/hydroponics/spreading/spreading.dm @@ -200,7 +200,7 @@ /obj/effect/vine/attackby(var/obj/item/W, var/mob/user) START_PROCESSING(SSvines, src) - if(W.edge && W.w_class < ITEM_SIZE_NORMAL && !user.check_intent(I_FLAG_HARM)) + if(W.has_edge() && W.w_class < ITEM_SIZE_NORMAL && !user.check_intent(I_FLAG_HARM)) if(!is_mature()) to_chat(user, SPAN_WARNING("\The [src] is not mature enough to yield a sample yet.")) return TRUE @@ -217,7 +217,7 @@ else . = ..() var/damage = W.get_attack_force(user) - if(W.edge) + if(W.has_edge()) damage *= 2 adjust_health(-damage) playsound(get_turf(src), W.hitsound, 100, 1) @@ -280,7 +280,7 @@ /decl/interaction_handler/vine_chop/invoked(atom/target, mob/user, obj/item/prop) var/obj/effect/vine/vine = target var/obj/item/holding = user.get_active_held_item() - if(!istype(holding) || !holding.edge || holding.w_class < ITEM_SIZE_NORMAL) + if(!istype(holding) || !holding.has_edge() || holding.w_class < ITEM_SIZE_NORMAL) to_chat(user, SPAN_WARNING("You need a larger or sharper object for this task!")) return user.visible_message(SPAN_NOTICE("\The [user] starts chopping down \the [vine].")) diff --git a/code/modules/hydroponics/trays/tray.dm b/code/modules/hydroponics/trays/tray.dm index f0f7beb5e72e..e5df232f9bce 100644 --- a/code/modules/hydroponics/trays/tray.dm +++ b/code/modules/hydroponics/trays/tray.dm @@ -691,7 +691,7 @@ examine_desc = "take a sample" /decl/interaction_handler/hydroponics/sample/is_possible(atom/target, mob/user, obj/item/prop) - return ..() && istype(prop) && prop.edge && prop.w_class < ITEM_SIZE_NORMAL + return ..() && istype(prop) && prop.has_edge() && prop.w_class < ITEM_SIZE_NORMAL /decl/interaction_handler/hydroponics/sample/invoked(atom/target, mob/user, obj/item/prop) var/obj/machinery/portable_atmospherics/hydroponics/tray = target diff --git a/code/modules/mob/grab/normal/grab_normal.dm b/code/modules/mob/grab/normal/grab_normal.dm index ca01188a2ead..b919a34b3ec5 100644 --- a/code/modules/mob/grab/normal/grab_normal.dm +++ b/code/modules/mob/grab/normal/grab_normal.dm @@ -228,7 +228,7 @@ if(!user.check_intent(I_FLAG_HARM)) return 0 // Not trying to hurt them. - if(!W.edge || !W.get_attack_force(user) || W.atom_damage_type != BRUTE) + if(!W.has_edge() || !W.get_attack_force(user) || W.atom_damage_type != BRUTE) return 0 //unsuitable weapon user.visible_message("\The [user] begins to slit [affecting]'s throat with \the [W]!") @@ -273,7 +273,7 @@ return if(!user.check_intent(I_FLAG_HARM)) return 0 // Not trying to hurt them. - if(!W.edge || !W.get_attack_force(user) || W.atom_damage_type != BRUTE) + if(!W.has_edge() || !W.get_attack_force(user) || W.atom_damage_type != BRUTE) return 0 //unsuitable weapon var/obj/item/organ/external/O = grab.get_targeted_organ() if(!O || !(O.limb_flags & ORGAN_FLAG_HAS_TENDON) || (O.status & ORGAN_TENDON_CUT)) diff --git a/code/modules/mob/living/human/human.dm b/code/modules/mob/living/human/human.dm index ed0df480df70..2e9b1a8d81e3 100644 --- a/code/modules/mob/living/human/human.dm +++ b/code/modules/mob/living/human/human.dm @@ -425,7 +425,7 @@ var/obj/item/organ/internal/stomach/stomach = get_organ(BP_STOMACH, /obj/item/organ/internal/stomach) if(stomach && stomach.contents.len) for(var/obj/item/O in stomach.contents) - if((O.edge || O.sharp) && prob(5)) + if((O.is_sharp() || O.has_edge()) && prob(5)) var/obj/item/organ/external/parent = GET_EXTERNAL_ORGAN(src, stomach.parent_organ) if(prob(1) && can_feel_pain() && O.can_embed()) to_chat(src, SPAN_DANGER("You feel something rip out of your [stomach.name]!")) diff --git a/code/modules/mob/living/human/human_defense.dm b/code/modules/mob/living/human/human_defense.dm index aa168f8ae019..7e457b8256f2 100644 --- a/code/modules/mob/living/human/human_defense.dm +++ b/code/modules/mob/living/human/human_defense.dm @@ -197,14 +197,14 @@ meteor_act return //make non-sharp low-force weapons less likely to be bloodied - if(W.sharp || prob(effective_force*4)) + if(W.is_sharp() || prob(effective_force*4)) if(!(W.atom_flags & ATOM_FLAG_NO_BLOOD)) W.add_blood(src) else return //if the weapon itself didn't get bloodied than it makes little sense for the target to be bloodied either //getting the weapon bloodied is easier than getting the target covered in blood, so run prob() again - if(prob(33 + W.sharp*10)) + if(prob(33 + W.is_sharp() * 10)) var/turf/location = loc if(istype(location) && location.simulated) location.add_blood(src) @@ -234,7 +234,7 @@ meteor_act /mob/living/human/proc/projectile_hit_bloody(obj/item/projectile/P, var/effective_force, var/hit_zone, var/obj/item/organ/external/organ) if(P.atom_damage_type != BRUTE || P.nodamage) return - if(!(P.sharp || prob(effective_force*4))) + if(!(P.is_sharp() || prob(effective_force*4))) return if(prob(effective_force)) var/turf/location = loc diff --git a/code/modules/mob/living/human/unarmed_attack.dm b/code/modules/mob/living/human/unarmed_attack.dm index f1740242c4fd..5811ea192946 100644 --- a/code/modules/mob/living/human/unarmed_attack.dm +++ b/code/modules/mob/living/human/unarmed_attack.dm @@ -159,7 +159,7 @@ user.visible_message(SPAN_DANGER("\The [user] attempts to press [pronouns.his] [eye_attack_text] into \the [target]'s eyes, but [target_gender.he] [target_gender.does]n't have any!")) /decl/natural_attack/proc/damage_flags() - return (src.sharp? DAM_SHARP : 0)|(src.edge? DAM_EDGE : 0) + return (sharp ? DAM_SHARP : 0) | (edge ? DAM_EDGE : 0) /decl/natural_attack/bite name = "bite" @@ -169,14 +169,14 @@ attack_sound = 'sound/weapons/bite.ogg' shredding = 0 damage = 5 - sharp = 0 - edge = 0 + sharp = FALSE + edge = FALSE usable_with_limbs = list(BP_HEAD) /decl/natural_attack/bite/sharp attack_verb = list("bit", "chomped") - sharp = 1 - edge = 1 + sharp = TRUE + edge = TRUE /decl/natural_attack/bite/is_usable(var/mob/living/human/user, var/mob/living/human/target, var/zone) @@ -342,8 +342,8 @@ attack_verb = list("tapped", "lightly struck") shredding = 0 damage = 0 - sharp = 0 - edge = 0 + sharp = FALSE + edge = FALSE attack_sound = "light_strike" /decl/natural_attack/light_strike/punch @@ -370,8 +370,8 @@ attack_noun = list("forelimb") damage = 8 shredding = 1 - sharp = 1 - edge = 1 + sharp = TRUE + edge = TRUE delay = 20 eye_attack_text = "a forelimb" eye_attack_text_victim = "a forelimb" diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 4cacbc889af7..7a5c096451f1 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -218,7 +218,7 @@ if(affecting && istype(supplied_wound) && supplied_wound.is_open() && dtype == BRUTE) // Can't embed in a small bruise. var/obj/item/I = O - var/sharp = is_sharp(I) + var/sharp = I.is_sharp() || I.has_edge() embed_damage *= (1 - get_blocked_ratio(def_zone, BRUTE, O.damage_flags(), O.armor_penetration, I.get_attack_force(user))) //blunt objects should really not be embedding in things unless a huge amount of force is involved diff --git a/code/modules/mob/living/simple_animal/crow/crow.dm b/code/modules/mob/living/simple_animal/crow/crow.dm index 66428209454e..227e3824cf55 100644 --- a/code/modules/mob/living/simple_animal/crow/crow.dm +++ b/code/modules/mob/living/simple_animal/crow/crow.dm @@ -38,7 +38,7 @@ name = "claws" gender = PLURAL attack_verb = list("clawed") - sharp = TRUE + _sharp = TRUE _base_attack_force = 7 /mob/living/simple_animal/crow/Initialize() diff --git a/code/modules/mob/living/simple_animal/hostile/commanded/nanomachines.dm b/code/modules/mob/living/simple_animal/hostile/commanded/nanomachines.dm index 1145b90b6e8b..0b1b55686f74 100644 --- a/code/modules/mob/living/simple_animal/hostile/commanded/nanomachines.dm +++ b/code/modules/mob/living/simple_animal/hostile/commanded/nanomachines.dm @@ -22,7 +22,7 @@ name = "decompilers" attack_verb = list("swarmed") _base_attack_force = 2 - sharp = TRUE + _sharp = TRUE /datum/mob_controller/aggressive/commanded/nanomachines/do_process(time_elapsed) diff --git a/code/modules/mob/living/simple_animal/hostile/hivebots/megabot.dm b/code/modules/mob/living/simple_animal/hostile/hivebots/megabot.dm index ead786ab340c..0b286445f27c 100644 --- a/code/modules/mob/living/simple_animal/hostile/hivebots/megabot.dm +++ b/code/modules/mob/living/simple_animal/hostile/hivebots/megabot.dm @@ -42,8 +42,8 @@ name = "giant circular saw" attack_verb = list("sawed", "ripped") _base_attack_force = 15 - sharp = TRUE - edge = TRUE + _sharp = TRUE + _edge = TRUE /mob/living/simple_animal/hostile/hivebot/mega/Initialize() . = ..() diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm index 61c888bceaf5..48cbcb6efc1a 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm @@ -84,7 +84,7 @@ name = "giant horns" attack_verb = list("brutalized") _base_attack_force = 40 - sharp = TRUE + _sharp = TRUE /obj/item/natural_weapon/goatking/fire name = "burning horns" @@ -105,7 +105,7 @@ name = "horns" attack_verb = list("impaled", "stabbed") _base_attack_force = 15 - sharp = TRUE + _sharp = TRUE /mob/living/simple_animal/hostile/goat/guard/master name = "master of the guard" @@ -159,7 +159,7 @@ name = "horns" attack_verb = list("impaled", "stabbed") _base_attack_force = 15 - sharp = TRUE + _sharp = TRUE /mob/living/simple_animal/hostile/retaliate/goat/guard/master name = "master of the guard" diff --git a/code/modules/mob/living/simple_animal/hostile/viscerator.dm b/code/modules/mob/living/simple_animal/hostile/viscerator.dm index 03f3853fd5bc..2ab555856c13 100644 --- a/code/modules/mob/living/simple_animal/hostile/viscerator.dm +++ b/code/modules/mob/living/simple_animal/hostile/viscerator.dm @@ -18,8 +18,8 @@ attack_verb = list("sliced", "cut") hitsound = 'sound/weapons/bladeslice.ogg' _base_attack_force = 15 - edge = 1 - sharp = 1 + _edge = TRUE + _sharp = TRUE /mob/living/simple_animal/hostile/viscerator/check_has_mouth() return FALSE diff --git a/code/modules/mob/living/simple_animal/natural_weapons.dm b/code/modules/mob/living/simple_animal/natural_weapons.dm index 06611f0170c5..a62b10cf5d0b 100644 --- a/code/modules/mob/living/simple_animal/natural_weapons.dm +++ b/code/modules/mob/living/simple_animal/natural_weapons.dm @@ -31,7 +31,7 @@ attack_verb = list("bitten") hitsound = 'sound/weapons/bite.ogg' _base_attack_force = 10 - sharp = TRUE + _sharp = TRUE /obj/item/natural_weapon/bite/weak _base_attack_force = 5 @@ -49,8 +49,8 @@ name = "claws" attack_verb = list("mauled", "clawed", "slashed") _base_attack_force = 10 - sharp = TRUE - edge = TRUE + _sharp = TRUE + _edge = TRUE /obj/item/natural_weapon/claws/strong _base_attack_force = 25 @@ -77,14 +77,14 @@ gender = NEUTER attack_verb = list("sliced") atom_damage_type = BRUTE - edge = TRUE + _edge = TRUE show_in_message = TRUE /obj/item/natural_weapon/beak name = "beak" gender = NEUTER attack_verb = list("pecked", "jabbed", "poked") - sharp = TRUE + _sharp = TRUE /obj/item/natural_weapon/large _base_attack_force = 15 diff --git a/code/modules/organs/external/_external.dm b/code/modules/organs/external/_external.dm index faa52cb2323e..ad75371d49c8 100644 --- a/code/modules/organs/external/_external.dm +++ b/code/modules/organs/external/_external.dm @@ -318,7 +318,7 @@ //Handles removing internal organs/implants/items still in the detached limb. /obj/item/organ/external/proc/try_remove_internal_item(var/obj/item/used_item, var/mob/user) - if(stage == 0 && used_item.sharp) + if(stage == 0 && used_item.is_sharp()) user.visible_message(SPAN_NOTICE("\The [user] cuts \the [src] open with \the [used_item].")) stage++ return TRUE @@ -328,7 +328,7 @@ stage++ return TRUE - if(stage == 2 && (used_item.sharp || IS_HEMOSTAT(used_item) || IS_WIRECUTTER(used_item))) + if(stage == 2 && (used_item.is_sharp() || IS_HEMOSTAT(used_item) || IS_WIRECUTTER(used_item))) var/list/radial_buttons = make_item_radial_menu_choices(get_contents_recursive()) if(LAZYLEN(radial_buttons)) var/obj/item/removing = show_radial_menu(user, src, radial_buttons, radius = 42, require_near = TRUE, use_labels = RADIAL_LABELS_OFFSET, check_locs = list(src)) diff --git a/code/modules/paperwork/pen/fancy.dm b/code/modules/paperwork/pen/fancy.dm index 9c7e149a7be8..226052b4a870 100644 --- a/code/modules/paperwork/pen/fancy.dm +++ b/code/modules/paperwork/pen/fancy.dm @@ -1,7 +1,7 @@ /obj/item/pen/fancy name = "fountain pen" icon = 'icons/obj/items/pens/pen_fancy.dmi' - sharp = 1 //pointy + _sharp = TRUE stroke_color = "#1c1713" //dark ashy brownish stroke_color_name = "dark ashy brownish" material = /decl/material/solid/metal/steel diff --git a/code/modules/paperwork/pen/quill_and_ink.dm b/code/modules/paperwork/pen/quill_and_ink.dm index 4944165f4e5b..1e3b72af4c39 100644 --- a/code/modules/paperwork/pen/quill_and_ink.dm +++ b/code/modules/paperwork/pen/quill_and_ink.dm @@ -1,7 +1,7 @@ /obj/item/pen/fancy/quill name = "quill pen" icon = 'icons/obj/items/pens/pen_quill.dmi' - sharp = 0 + _sharp = FALSE material = /decl/material/solid/organic/skin/feathers pen_quality = TOOL_QUALITY_DEFAULT max_uses = 5 // gotta re-ink it often! diff --git a/code/modules/paperwork/pen/reagent_pen.dm b/code/modules/paperwork/pen/reagent_pen.dm index 67dfcad441c6..e96e7b800e5b 100644 --- a/code/modules/paperwork/pen/reagent_pen.dm +++ b/code/modules/paperwork/pen/reagent_pen.dm @@ -1,7 +1,7 @@ /obj/item/pen/reagent atom_flags = ATOM_FLAG_OPEN_CONTAINER origin_tech = @'{"materials":2,"esoteric":5}' - sharp = 1 + _sharp = TRUE pen_quality = TOOL_QUALITY_MEDIOCRE /obj/item/pen/reagent/Initialize() diff --git a/code/modules/persistence/graffiti.dm b/code/modules/persistence/graffiti.dm index 1ed8a188417e..0bd85389b6f4 100644 --- a/code/modules/persistence/graffiti.dm +++ b/code/modules/persistence/graffiti.dm @@ -43,7 +43,7 @@ user.visible_message(SPAN_NOTICE("\The [user] clears away some graffiti.")) qdel(src) return TRUE - else if(thing.sharp && !user.check_intent(I_FLAG_HELP)) //Check intent so you don't go insane trying to unscrew a light fixture over a graffiti + else if(thing.is_sharp() && !user.check_intent(I_FLAG_HELP)) //Check intent so you don't go insane trying to unscrew a light fixture over a graffiti if(jobban_isbanned(user, "Graffiti")) to_chat(user, SPAN_WARNING("You are banned from leaving persistent information across rounds.")) return TRUE diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index c68581b32295..04401c7fd2cc 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -188,7 +188,10 @@ By design, d1 is the smallest direction and d2 is the highest to_chat(user, SPAN_WARNING("\The [src] is not powered.")) return TRUE - if(used_item.edge) + + + else if(W.has_edge()) + var/delay_holder if(used_item.get_attack_force(user) < 5) visible_message(SPAN_WARNING("[user] starts sawing away roughly at \the [src] with \the [used_item].")) diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index e3b47f5c5d10..a1f4640d16c6 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -604,7 +604,7 @@ if(status == LIGHT_OK || status == LIGHT_BURNED) src.visible_message("[name] shatters.","You hear a small glass object shatter.") status = LIGHT_BROKEN - sharp = 1 + set_sharp(TRUE) set_base_attack_force(5) playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1) update_icon() diff --git a/code/modules/projectiles/ammunition/chemdart.dm b/code/modules/projectiles/ammunition/chemdart.dm index bd8710bef92d..deb37e85eed9 100644 --- a/code/modules/projectiles/ammunition/chemdart.dm +++ b/code/modules/projectiles/ammunition/chemdart.dm @@ -2,7 +2,7 @@ name = "dart" icon_state = "dart" damage = 5 - sharp = 1 + _sharp = TRUE embed = 1 //the dart is shot fast enough to pierce space suits, so I guess splintering inside the target can be a thing. Should be rare due to low damage. life_span = 15 //shorter range muzzle_type = null diff --git a/code/modules/projectiles/guns/launcher/bows/arrow.dm b/code/modules/projectiles/guns/launcher/bows/arrow.dm index 1fb6cc358678..2ff38789cfd5 100644 --- a/code/modules/projectiles/guns/launcher/bows/arrow.dm +++ b/code/modules/projectiles/guns/launcher/bows/arrow.dm @@ -5,8 +5,8 @@ plural_icon_state = ICON_STATE_WORLD + "-mult" max_icon_state = ICON_STATE_WORLD + "-max" w_class = ITEM_SIZE_NORMAL - sharp = 1 - edge = 0 + _sharp = TRUE + _edge = FALSE lock_picking_level = 3 material = /decl/material/solid/organic/wood/oak material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME | MAT_FLAG_ALTERATION_DESC diff --git a/code/modules/projectiles/guns/launcher/syringe_gun.dm b/code/modules/projectiles/guns/launcher/syringe_gun.dm index d44be24924d5..b4c7e754a1a6 100644 --- a/code/modules/projectiles/guns/launcher/syringe_gun.dm +++ b/code/modules/projectiles/guns/launcher/syringe_gun.dm @@ -30,7 +30,7 @@ return TRUE syringe = I to_chat(user, "You carefully insert [syringe] into [src].") - sharp = TRUE + set_sharp(TRUE) name = "syringe dart" update_icon() return TRUE @@ -41,7 +41,7 @@ to_chat(user, "You remove [syringe] from [src].") user.put_in_hands(syringe) syringe = null - sharp = initial(sharp) + set_sharp(initial(_sharp)) SetName(initial(name)) update_icon() diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index dc643dcdc3b2..c309c5ad1ab1 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -7,7 +7,7 @@ pass_flags = PASS_FLAG_TABLE | PASS_FLAG_GLASS | PASS_FLAG_GRILLE damage = 40 atom_damage_type = BURN - sharp = 1 //concentrated burns + _sharp = TRUE //concentrated burns damage_flags = DAM_LASER eyeblur = 4 hitscan = 1 @@ -210,7 +210,7 @@ icon_state = "stun" fire_sound = 'sound/weapons/Taser.ogg' damage_flags = 0 - sharp = 0 //not a laser + _sharp = FALSE //not a laser damage = 1//flavor burn! still not a laser, dmg will be reduce by energy resistance not laser resistances atom_damage_type = BURN eyeblur = 1//Some feedback that you've been hit @@ -241,8 +241,8 @@ icon_state = "omnilaser" fire_sound = 'sound/weapons/plasma_cutter.ogg' damage = 15 - sharp = 1 - edge = 1 + _sharp = TRUE + _edge = TRUE atom_damage_type = BURN life_span = 5 pass_flags = PASS_FLAG_TABLE @@ -264,7 +264,7 @@ fire_sound='sound/weapons/confuseray.ogg' damage = 2 agony = 7 - sharp = FALSE + _sharp = FALSE distance_falloff = 5 damage_flags = 0 atom_damage_type = STUN @@ -317,7 +317,7 @@ name = "dark matter wave" icon_state = "darkt" damage_flags = 0 - sharp = 0 //not a laser + _sharp = FALSE //not a laser agony = 40 atom_damage_type = STUN muzzle_type = /obj/effect/projectile/muzzle/darkmattertaser @@ -329,7 +329,7 @@ icon_state = "laser" damage = 15 atom_damage_type = ELECTROCUTE //You should be safe inside a voidsuit - sharp = FALSE //"Wide" spectrum beam + _sharp = FALSE //"Wide" spectrum beam muzzle_type = /obj/effect/projectile/muzzle/pd tracer_type = /obj/effect/projectile/tracer/pd impact_type = /obj/effect/projectile/impact/pd @@ -341,7 +341,7 @@ damage = 12 agony = 8 eyeblur = 8 - sharp = FALSE + _sharp = FALSE damage_flags = 0 life_span = 8 penetration_modifier = 0.1 diff --git a/code/modules/reagents/reagent_containers/drinks/bottle.dm b/code/modules/reagents/reagent_containers/drinks/bottle.dm index 5d0776020c41..318aae2a26d6 100644 --- a/code/modules/reagents/reagent_containers/drinks/bottle.dm +++ b/code/modules/reagents/reagent_containers/drinks/bottle.dm @@ -228,8 +228,7 @@ throw_range = 5 item_state = "beer" attack_verb = list("stabbed", "slashed", "attacked") - sharp = 1 - edge = 0 + _sharp = TRUE obj_flags = OBJ_FLAG_HOLLOW material = /decl/material/solid/glass _base_attack_force = 9 diff --git a/code/modules/reagents/reagent_containers/food/fish.dm b/code/modules/reagents/reagent_containers/food/fish.dm index d4a3a57106ba..fd8ec91188e0 100644 --- a/code/modules/reagents/reagent_containers/food/fish.dm +++ b/code/modules/reagents/reagent_containers/food/fish.dm @@ -70,7 +70,7 @@ qdel(src) /obj/item/mollusc/attackby(var/obj/item/thing, var/mob/user) - if(thing.sharp || thing.edge) + if(thing.is_sharp() || thing.has_edge()) user.visible_message(SPAN_NOTICE("\The [user] cracks open \the [src] with \the [thing].")) crack_shell(user) return TRUE diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index f55288be25ec..44760396d29f 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -17,7 +17,7 @@ volume = 15 w_class = ITEM_SIZE_TINY slot_flags = SLOT_EARS - sharp = 1 + _sharp = TRUE item_flags = ITEM_FLAG_NO_BLUDGEON var/mode = SYRINGE_DRAW diff --git a/code/modules/recycling/wrapped_package.dm b/code/modules/recycling/wrapped_package.dm index 57261df802b3..da2a33bfd701 100644 --- a/code/modules/recycling/wrapped_package.dm +++ b/code/modules/recycling/wrapped_package.dm @@ -195,7 +195,7 @@ update_icon() return TRUE - else if(W.sharp && user.check_intent(I_FLAG_HELP)) + else if(W.is_sharp() && user.check_intent(I_FLAG_HELP)) //You can alternative cut the wrapper off with a sharp item unwrap(user) return TRUE diff --git a/code/modules/species/species_attack.dm b/code/modules/species/species_attack.dm index d2daf2daa062..0fffa9846431 100644 --- a/code/modules/species/species_attack.dm +++ b/code/modules/species/species_attack.dm @@ -2,8 +2,8 @@ attack_verb = list("bit", "chomped on") attack_sound = 'sound/weapons/bite.ogg' shredding = 0 - sharp = 1 - edge = 1 + sharp = TRUE + edge = TRUE name = "sharp bite" /decl/natural_attack/claws @@ -14,8 +14,8 @@ eye_attack_text_victim = "sharp claws" attack_sound = 'sound/weapons/slice.ogg' miss_sound = 'sound/weapons/slashmiss.ogg' - sharp = 1 - edge = 1 + sharp = TRUE + edge = TRUE name = "claws" usable_with_limbs = list(BP_L_HAND, BP_R_HAND) var/blocked_by_gloves = TRUE diff --git a/code/modules/tools/archetypes/tool_archetype_definitions.dm b/code/modules/tools/archetypes/tool_archetype_definitions.dm index 25df48e3afda..2b2b2f14f4d6 100644 --- a/code/modules/tools/archetypes/tool_archetype_definitions.dm +++ b/code/modules/tools/archetypes/tool_archetype_definitions.dm @@ -70,16 +70,16 @@ /decl/tool_archetype/knife/get_default_quality(obj/item/tool) if(tool) - if(tool.sharp && tool.edge) + if(tool.is_sharp() && tool.has_edge()) return TOOL_QUALITY_DEFAULT - else if(tool.sharp || tool.edge) + else if(tool.is_sharp() || tool.has_edge()) return TOOL_QUALITY_MEDIOCRE return ..() /decl/tool_archetype/knife/get_default_speed(obj/item/tool) if(tool) - if(tool.sharp && tool.edge) + if(tool.is_sharp() && tool.has_edge()) return TOOL_SPEED_DEFAULT - else if(tool.sharp || tool.edge) + else if(tool.is_sharp() || tool.has_edge()) return TOOL_SPEED_MEDIOCRE return ..() diff --git a/code/modules/tools/subtypes/axes.dm b/code/modules/tools/subtypes/axes.dm index d671ffa07479..4a6f166f6260 100644 --- a/code/modules/tools/subtypes/axes.dm +++ b/code/modules/tools/subtypes/axes.dm @@ -3,8 +3,8 @@ desc = "A handheld tool for chopping things, wood, food, or people." icon_state = "preview" icon = 'icons/obj/items/tool/axes/handaxe.dmi' - sharp = TRUE - edge = TRUE + _sharp = TRUE + _edge = TRUE handle_material = /decl/material/solid/organic/wood/oak item_flags = ITEM_FLAG_IS_WEAPON origin_tech = @'{"materials":2,"combat":1}' diff --git a/code/modules/tools/subtypes/hammers.dm b/code/modules/tools/subtypes/hammers.dm index bb1c9ee58cd5..70021c01c4a0 100644 --- a/code/modules/tools/subtypes/hammers.dm +++ b/code/modules/tools/subtypes/hammers.dm @@ -2,8 +2,6 @@ name = "hammer" desc = "A simple hammer. Ancient technology once thought lost." icon = 'icons/obj/items/tool/hammers/hammer.dmi' - sharp = 0 - edge = 0 attack_verb = list( "bludgeons", "slaps", diff --git a/code/modules/tools/subtypes/hoes.dm b/code/modules/tools/subtypes/hoes.dm index b5bdda347638..fe3e709c8ad2 100644 --- a/code/modules/tools/subtypes/hoes.dm +++ b/code/modules/tools/subtypes/hoes.dm @@ -3,8 +3,8 @@ desc = "It's used for removing weeds or scratching your back." icon = 'icons/obj/items/tool/hoes/hoe.dmi' icon_state = "preview" - sharp = TRUE - edge = TRUE + _sharp = TRUE + _edge = TRUE attack_verb = list("slashed", "sliced", "cut", "clawed") material = /decl/material/solid/metal/steel material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME diff --git a/code/modules/tools/subtypes/pickaxes.dm b/code/modules/tools/subtypes/pickaxes.dm index 083c99661f8c..a6a859e2691c 100644 --- a/code/modules/tools/subtypes/pickaxes.dm +++ b/code/modules/tools/subtypes/pickaxes.dm @@ -3,8 +3,8 @@ desc = "A heavy tool with a pick head for prospecting for minerals, and an axe head for dealing with anyone with a prior claim." icon_state = "preview" icon = 'icons/obj/items/tool/pickaxe.dmi' - sharp = TRUE - edge = TRUE + _sharp = TRUE + _edge = TRUE w_class = ITEM_SIZE_HUGE handle_material = /decl/material/solid/organic/wood/oak _base_attack_force = 15 diff --git a/code/modules/tools/subtypes/shovel.dm b/code/modules/tools/subtypes/shovel.dm index 204bb0a9fbb4..f80626f07adb 100644 --- a/code/modules/tools/subtypes/shovel.dm +++ b/code/modules/tools/subtypes/shovel.dm @@ -5,8 +5,8 @@ icon_state = "preview" // mapping preview icon slot_flags = SLOT_LOWER_BODY w_class = ITEM_SIZE_LARGE - edge = TRUE - sharp = TRUE + _edge = TRUE + _sharp = TRUE attack_verb = list("bashed", "bludgeoned", "thrashed", "whacked") handle_material = /decl/material/solid/organic/wood/oak _base_attack_force = 8 @@ -36,8 +36,8 @@ icon = 'icons/obj/items/tool/shovels/spade.dmi' icon_state = "preview" // mapping preview icon w_class = ITEM_SIZE_SMALL - edge = FALSE - sharp = FALSE + _edge = FALSE + _sharp = FALSE slot_flags = SLOT_LOWER_BODY attack_verb = list("bashed", "bludgeoned", "thrashed", "whacked") material_alteration = 0 diff --git a/code/modules/tools/subtypes/xenoarchaeology_picks.dm b/code/modules/tools/subtypes/xenoarchaeology_picks.dm index 9db2d59f5418..e6d3ccdedad8 100644 --- a/code/modules/tools/subtypes/xenoarchaeology_picks.dm +++ b/code/modules/tools/subtypes/xenoarchaeology_picks.dm @@ -7,7 +7,7 @@ material = /decl/material/solid/metal/chromium matter = list(/decl/material/solid/metal/steel = MATTER_AMOUNT_SECONDARY) w_class = ITEM_SIZE_SMALL - sharp = 1 + _sharp = TRUE abstract_type = /obj/item/tool/xeno material_alteration = 0 handle_material = /decl/material/solid/organic/plastic @@ -36,18 +36,18 @@ to_chat(user, "This tool has a [get_tool_property(TOOL_PICK, TOOL_PROP_EXCAVATION_DEPTH) || 0] centimetre excavation depth.") /obj/item/tool/xeno/brush - name = "wire brush" - icon_state = "pick_brush" - slot_flags = SLOT_EARS - _base_attack_force = 1 - attack_verb = list("prodded", "attacked") - desc = "A wood-handled brush with thick metallic wires for clearing away dust and loose scree." - sharp = 0 - material = /decl/material/solid/metal/steel - handle_material = /decl/material/solid/organic/wood/oak - excavation_amount = 1 - excavation_sound = "sweeping" - excavation_verb = "brushing" + name = "wire brush" + icon_state = "pick_brush" + slot_flags = SLOT_EARS + _base_attack_force = 1 + attack_verb = list("prodded", "attacked") + desc = "A wood-handled brush with thick metallic wires for clearing away dust and loose scree." + _sharp = FALSE + material = /decl/material/solid/metal/steel + handle_material = /decl/material/solid/organic/wood/oak + excavation_amount = 1 + excavation_sound = "sweeping" + excavation_verb = "brushing" /obj/item/tool/xeno/one_pick name = "2cm pick" diff --git a/code/modules/tools/tool.dm b/code/modules/tools/tool.dm index 889d2ab199d9..953a751ebbb2 100644 --- a/code/modules/tools/tool.dm +++ b/code/modules/tools/tool.dm @@ -6,7 +6,6 @@ w_class = ITEM_SIZE_NORMAL origin_tech = @'{"materials":1,"engineering":1}' attack_verb = list("hit", "pierced", "sliced", "attacked") - sharp = 0 abstract_type = /obj/item/tool material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME | MAT_FLAG_ALTERATION_DESC _base_attack_force = 10 diff --git a/code/modules/xenoarcheaology/tools/core_sampler.dm b/code/modules/xenoarcheaology/tools/core_sampler.dm index 01b4f1401e5d..2ef87ee56ae8 100644 --- a/code/modules/xenoarcheaology/tools/core_sampler.dm +++ b/code/modules/xenoarcheaology/tools/core_sampler.dm @@ -51,7 +51,7 @@ icon_state = "sliver1" randpixel = 8 w_class = ITEM_SIZE_TINY - sharp = 1 + _sharp = TRUE material = /decl/material/solid/stone/sandstone material_health_multiplier = 0.25 diff --git a/maps/away/errant_pisces/errant_pisces.dm b/maps/away/errant_pisces/errant_pisces.dm index 82cba1ab1eb6..f171768e57b1 100644 --- a/maps/away/errant_pisces/errant_pisces.dm +++ b/maps/away/errant_pisces/errant_pisces.dm @@ -112,9 +112,9 @@ return SPAN_NOTICE("A few strands of \the [src] have been severed.") /obj/structure/net/attackby(obj/item/W, mob/user) - if(W.sharp || W.edge) + if(W.is_sharp() || W.has_edge()) var/force = W.get_attack_force(user) - if (!(W.sharp) || (W.sharp && force < 10))//is not sharp enough or at all + if (!(W.is_sharp()) || (W.is_sharp() && force < 10))//is not sharp enough or at all to_chat(user,"You can't cut through \the [src] with \the [W], it's too dull.") return TRUE visible_message("[user] starts to cut through \the [src] with \the [W]!") diff --git a/mods/content/item_sharpening/effect_sharpen.dm b/mods/content/item_sharpening/effect_sharpen.dm index 4331f18e0d4b..d7ce982218e7 100644 --- a/mods/content/item_sharpening/effect_sharpen.dm +++ b/mods/content/item_sharpening/effect_sharpen.dm @@ -14,6 +14,6 @@ if(distance <= 1) var/uses = item.get_item_effect_parameter(src, IE_CAT_DAMAGE, IE_PAR_USES) if(uses > 0) - to_chat(user, SPAN_NOTICE("\The [src] has been sharpened to a keen edge.")) + to_chat(user, SPAN_NOTICE("\The [item] has been sharpened to a keen edge.")) else - to_chat(user, SPAN_NOTICE("\The [src] is dull and in need of sharpening.")) + to_chat(user, SPAN_NOTICE("\The [item] is dull and in need of sharpening.")) diff --git a/mods/content/item_sharpening/item_sharpen.dm b/mods/content/item_sharpening/item_sharpen.dm index 28290a6d13a6..f302a6c609db 100644 --- a/mods/content/item_sharpening/item_sharpen.dm +++ b/mods/content/item_sharpening/item_sharpen.dm @@ -42,5 +42,11 @@ // TODO: play sharpening sound? Spawn sparks for metal? user.visible_message("\The [user] sharpens \the [src] with \the [sharpening_with].") else - to_chat(user, SPAN_WARNING("\The [src] cannot be [sharp ? "further sharpened" : "sharpened"] with \the [sharpening_with].")) + to_chat(user, SPAN_WARNING("\The [src] cannot be [initial(_sharp) ? "further sharpened" : "sharpened"] with \the [sharpening_with].")) return TRUE + +// We don't override sharp because it's probably still pointy even if it isn't sharpened. +/obj/item/has_edge() + . = ..() + if(. && has_item_effect(/decl/item_effect/sharpened, IE_CAT_DAMAGE)) + return get_item_effect_parameter(/decl/item_effect/sharpened, IE_CAT_DAMAGE, IE_PAR_USES) > 0 diff --git a/mods/content/psionics/system/psionics/equipment/psipower_blade.dm b/mods/content/psionics/system/psionics/equipment/psipower_blade.dm index fd8b4f947c86..5863c9d2c2cf 100644 --- a/mods/content/psionics/system/psionics/equipment/psipower_blade.dm +++ b/mods/content/psionics/system/psionics/equipment/psipower_blade.dm @@ -1,8 +1,8 @@ /obj/item/ability/psionic/psiblade name = "psychokinetic slash" _base_attack_force = 10 - sharp = 1 - edge = 1 + _sharp = TRUE + _edge = TRUE maintain_cost = 1 icon_state = "psiblade_short" diff --git a/mods/gamemodes/cult/mobs/constructs/constructs.dm b/mods/gamemodes/cult/mobs/constructs/constructs.dm index 1eb37f6980bd..42d61584c70b 100644 --- a/mods/gamemodes/cult/mobs/constructs/constructs.dm +++ b/mods/gamemodes/cult/mobs/constructs/constructs.dm @@ -174,7 +174,7 @@ gender = NEUTER attack_verb = list("slashed", "tore into") hitsound = 'sound/weapons/rapidslice.ogg' - edge = TRUE + _edge = TRUE _base_attack_force = 25 /mob/living/simple_animal/construct/wraith/mind_initialize() @@ -262,7 +262,7 @@ gender = NEUTER attack_verb = list("violently stabbed", "ran through") hitsound = 'sound/weapons/pierce.ogg' - sharp = TRUE + _sharp = TRUE _base_attack_force = 25 ////////////////HUD////////////////////// diff --git a/nebula.dme b/nebula.dme index bca074839c49..b7bb2e26077b 100644 --- a/nebula.dme +++ b/nebula.dme @@ -1076,6 +1076,7 @@ #include "code\game\objects\items\_item_materials.dm" #include "code\game\objects\items\_item_melting.dm" #include "code\game\objects\items\_item_reagents.dm" +#include "code\game\objects\items\_item_sharpness.dm" #include "code\game\objects\items\apc_frame.dm" #include "code\game\objects\items\blackout.dm" #include "code\game\objects\items\blueprints.dm" From 929804b2ef07314a0a00c23b1486954fe305a328 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Fri, 10 Jan 2025 00:12:40 +1100 Subject: [PATCH 004/120] Ensuring sharpness is not deducated multiple times on a hit. --- code/game/objects/items/_item_materials.dm | 2 +- .../game/objects/items/flame/flame_fuelled.dm | 2 +- .../crates_lockers/closets/__closet.dm | 2 +- code/game/objects/structures/doors/_door.dm | 2 +- code/game/objects/structures/fishtanks.dm | 2 +- .../cooking_vessels/_cooking_vessel.dm | 2 +- code/modules/hydroponics/trays/tray.dm | 19 ++++++++++--------- code/modules/mechs/equipment/combat.dm | 2 +- code/modules/mob/grab/normal/grab_normal.dm | 2 +- .../modules/mob/living/human/human_defense.dm | 4 ++-- code/modules/mob/living/living_defense.dm | 2 +- .../modules/mob/living/silicon/robot/robot.dm | 2 +- code/modules/power/cable.dm | 4 +--- .../item_sharpening/_item_sharpening.dme | 2 +- .../content/item_sharpening/effect_sharpen.dm | 4 ++-- mods/content/item_sharpening/item_sharpen.dm | 4 ++-- .../system/psionics/equipment/psipower.dm | 4 ++-- .../dionaea/mob/gestalt/gestalt_attacks.dm | 2 +- 18 files changed, 31 insertions(+), 32 deletions(-) diff --git a/code/game/objects/items/_item_materials.dm b/code/game/objects/items/_item_materials.dm index ecf48b7029e8..0615330d3cf5 100644 --- a/code/game/objects/items/_item_materials.dm +++ b/code/game/objects/items/_item_materials.dm @@ -12,7 +12,7 @@ /obj/item/apply_hit_effect(mob/living/target, mob/living/user, var/hit_zone) . = ..() - if(material && (material.is_brittle() || target.get_blocked_ratio(hit_zone, BRUTE, damage_flags(), armor_penetration, get_attack_force(user)) * 100 >= material.hardness/5)) + if(material && (material.is_brittle() || target.get_blocked_ratio(hit_zone, BRUTE, damage_flags(), armor_penetration, get_attack_force(user, dry_run = TRUE)) * 100 >= material.hardness/5)) apply_wear() /obj/item/on_parry(mob/user, damage_source, mob/attacker) diff --git a/code/game/objects/items/flame/flame_fuelled.dm b/code/game/objects/items/flame/flame_fuelled.dm index 07bcfe40859e..42eec60835d1 100644 --- a/code/game/objects/items/flame/flame_fuelled.dm +++ b/code/game/objects/items/flame/flame_fuelled.dm @@ -21,7 +21,7 @@ // Boilerplate from /obj/item/chems/glass. TODO generalize to a lower level. /obj/item/flame/fuelled/use_on_mob(mob/living/target, mob/living/user, animate = TRUE) - if(get_attack_force() && !(item_flags & ITEM_FLAG_NO_BLUDGEON) && user.check_intent(I_FLAG_HARM)) + if(get_attack_force(dry_run = TRUE) && !(item_flags & ITEM_FLAG_NO_BLUDGEON) && user.check_intent(I_FLAG_HARM)) . = ..() if(reagents?.total_volume && !QDELETED(target)) target.visible_message(SPAN_DANGER("Some of the contents of \the [src] splash onto \the [target].")) diff --git a/code/game/objects/structures/crates_lockers/closets/__closet.dm b/code/game/objects/structures/crates_lockers/closets/__closet.dm index 6bfeca7cfe85..ae0a39060279 100644 --- a/code/game/objects/structures/crates_lockers/closets/__closet.dm +++ b/code/game/objects/structures/crates_lockers/closets/__closet.dm @@ -250,7 +250,7 @@ var/global/list/closets = list() /obj/structure/closet/attackby(obj/item/used_item, mob/user) - if(user.check_intent(I_FLAG_HARM) && used_item.get_attack_force(user)) + if(user.check_intent(I_FLAG_HARM) && used_item.get_attack_force(user, dry_run = TRUE)) return ..() if(!opened && (istype(used_item, /obj/item/stack/material) || IS_WRENCH(used_item)) ) diff --git a/code/game/objects/structures/doors/_door.dm b/code/game/objects/structures/doors/_door.dm index ff6989638376..2697a5661b1b 100644 --- a/code/game/objects/structures/doors/_door.dm +++ b/code/game/objects/structures/doors/_door.dm @@ -163,7 +163,7 @@ /obj/structure/door/attackby(obj/item/used_item, mob/user) add_fingerprint(user, 0, used_item) - if((user.check_intent(I_FLAG_HARM) && used_item.get_attack_force(user)) || istype(used_item, /obj/item/stack/material)) + if((user.check_intent(I_FLAG_HARM) && used_item.get_attack_force(user, dry_run = TRUE)) || istype(used_item, /obj/item/stack/material)) return ..() if(used_item.user_can_attack_with(user, silent = TRUE)) diff --git a/code/game/objects/structures/fishtanks.dm b/code/game/objects/structures/fishtanks.dm index b6724f467752..bc711de5671f 100644 --- a/code/game/objects/structures/fishtanks.dm +++ b/code/game/objects/structures/fishtanks.dm @@ -69,7 +69,7 @@ var/global/list/fishtank_cache = list() return TRUE /obj/structure/glass_tank/attackby(var/obj/item/W, var/mob/user) - if(W.get_attack_force(user) < 5 || !user.check_intent(I_FLAG_HARM)) + if(W.get_attack_force(user, dry_run = TRUE) < 5 || !user.check_intent(I_FLAG_HARM)) attack_animation(user) visible_message(SPAN_NOTICE("\The [user] taps \the [src] with \the [W].")) else diff --git a/code/modules/food/cooking/cooking_vessels/_cooking_vessel.dm b/code/modules/food/cooking/cooking_vessels/_cooking_vessel.dm index fcd1cea0e1eb..72f0d1a44c9f 100644 --- a/code/modules/food/cooking/cooking_vessels/_cooking_vessel.dm +++ b/code/modules/food/cooking/cooking_vessels/_cooking_vessel.dm @@ -35,7 +35,7 @@ // Boilerplate from /obj/item/chems/glass. TODO generalize to a lower level. /obj/item/chems/cooking_vessel/use_on_mob(mob/living/target, mob/living/user, animate = TRUE) - if(get_attack_force() && !(item_flags & ITEM_FLAG_NO_BLUDGEON) && user.check_intent(I_FLAG_HARM)) + if(get_attack_force(dry_run = TRUE) && !(item_flags & ITEM_FLAG_NO_BLUDGEON) && user.check_intent(I_FLAG_HARM)) return ..() return FALSE diff --git a/code/modules/hydroponics/trays/tray.dm b/code/modules/hydroponics/trays/tray.dm index e5df232f9bce..ff099293f8bd 100644 --- a/code/modules/hydroponics/trays/tray.dm +++ b/code/modules/hydroponics/trays/tray.dm @@ -498,15 +498,16 @@ to_chat(user, "You [anchored ? "wrench" : "unwrench"] \the [src].") return TRUE - var/force = used_item.get_attack_force(user) - if(force && seed) - user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) - user.visible_message("\The [seed.display_name] has been attacked by [user] with \the [used_item]!") - playsound(get_turf(src), used_item.hitsound, 100, 1) - if(!dead) - plant_health -= force - check_plant_health() - return TRUE + if(seed) + var/force = used_item.get_attack_force(user) + if(force) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) + user.visible_message("\The [seed.display_name] has been attacked by [user] with \the [used_item]!") + playsound(get_turf(src), used_item.hitsound, 100, 1) + if(!dead) + plant_health -= force + check_plant_health() + return TRUE if(mechanical) return component_attackby(used_item, user) diff --git a/code/modules/mechs/equipment/combat.dm b/code/modules/mechs/equipment/combat.dm index fbc24657a603..e9d182c1980a 100644 --- a/code/modules/mechs/equipment/combat.dm +++ b/code/modules/mechs/equipment/combat.dm @@ -438,7 +438,7 @@ /obj/aura/mech_ballistic/attackby(obj/item/I, mob/user) . = ..() - if (shield && prob(shield.block_chance(I.get_attack_force(), I.armor_penetration, source = I, attacker = user))) + if (shield && prob(shield.block_chance(I.get_attack_force(dry_run = TRUE), I.armor_penetration, source = I, attacker = user))) user.visible_message(SPAN_WARNING("\The [I] is blocked by \the [user]'s [shield.name].")) playsound(user.loc, 'sound/weapons/Genhit.ogg', 50, 1) return AURA_FALSE|AURA_CANCEL diff --git a/code/modules/mob/grab/normal/grab_normal.dm b/code/modules/mob/grab/normal/grab_normal.dm index b919a34b3ec5..fcb921974f8f 100644 --- a/code/modules/mob/grab/normal/grab_normal.dm +++ b/code/modules/mob/grab/normal/grab_normal.dm @@ -228,7 +228,7 @@ if(!user.check_intent(I_FLAG_HARM)) return 0 // Not trying to hurt them. - if(!W.has_edge() || !W.get_attack_force(user) || W.atom_damage_type != BRUTE) + if(!W.has_edge() || !W.get_attack_force(user, dry_run = TRUE) || W.atom_damage_type != BRUTE) return 0 //unsuitable weapon user.visible_message("\The [user] begins to slit [affecting]'s throat with \the [W]!") diff --git a/code/modules/mob/living/human/human_defense.dm b/code/modules/mob/living/human/human_defense.dm index 7e457b8256f2..5e0ebff949e5 100644 --- a/code/modules/mob/living/human/human_defense.dm +++ b/code/modules/mob/living/human/human_defense.dm @@ -119,7 +119,7 @@ meteor_act visible_message("\The [user] misses [src] with \the [I]!") return null - if(check_shields(I.get_attack_force(user), I, user, target_zone, I)) + if(check_shields(I.get_attack_force(user, dry_run = TRUE), I, user, target_zone, I)) return null var/obj/item/organ/external/affecting = GET_EXTERNAL_ORGAN(src, hit_zone) @@ -152,7 +152,7 @@ meteor_act if(!affecting) return 0 - var/blocked = get_blocked_ratio(hit_zone, I.atom_damage_type, I.damage_flags(), I.armor_penetration, I.get_attack_force(user)) + var/blocked = get_blocked_ratio(hit_zone, I.atom_damage_type, I.damage_flags(), I.armor_penetration, I.get_attack_force(user, dry_run = TRUE)) // Handle striking to cripple. if(user.check_intent(I_FLAG_DISARM)) effective_force *= 0.66 //reduced effective force... diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 7a5c096451f1..73b1db81faa3 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -219,7 +219,7 @@ if(affecting && istype(supplied_wound) && supplied_wound.is_open() && dtype == BRUTE) // Can't embed in a small bruise. var/obj/item/I = O var/sharp = I.is_sharp() || I.has_edge() - embed_damage *= (1 - get_blocked_ratio(def_zone, BRUTE, O.damage_flags(), O.armor_penetration, I.get_attack_force(user))) + embed_damage *= (1 - get_blocked_ratio(def_zone, BRUTE, O.damage_flags(), O.armor_penetration, I.get_attack_force(user, dry_run = TRUE))) //blunt objects should really not be embedding in things unless a huge amount of force is involved var/embed_chance = embed_damage / (sharp ? I.w_class : (I.w_class*3)) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 4421aabf243b..d9cb6b6ff240 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -626,7 +626,7 @@ else to_chat(user, "Upgrade error!") return TRUE - if(!(istype(W, /obj/item/robotanalyzer) || istype(W, /obj/item/scanner/health)) && W.get_attack_force(user) && !user.check_intent(I_FLAG_HELP)) + if(!(istype(W, /obj/item/robotanalyzer) || istype(W, /obj/item/scanner/health)) && !user.check_intent(I_FLAG_HELP) && W.get_attack_force(user)) spark_at(src, 5, holder=src) return ..() diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 04401c7fd2cc..8bc69f07f558 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -188,9 +188,7 @@ By design, d1 is the smallest direction and d2 is the highest to_chat(user, SPAN_WARNING("\The [src] is not powered.")) return TRUE - - - else if(W.has_edge()) + else if(used_item.has_edge()) var/delay_holder if(used_item.get_attack_force(user) < 5) diff --git a/mods/content/item_sharpening/_item_sharpening.dme b/mods/content/item_sharpening/_item_sharpening.dme index cf812cb8b329..c9af243f5e94 100644 --- a/mods/content/item_sharpening/_item_sharpening.dme +++ b/mods/content/item_sharpening/_item_sharpening.dme @@ -3,8 +3,8 @@ // BEGIN_INCLUDE #include "_item_sharpening.dm" #include "blade_sharpen.dm" -#include "grindstone.dm" #include "effect_sharpen.dm" +#include "grindstone.dm" #include "item_sharpen.dm" #include "whetstone.dm" //END_INCLUDE diff --git a/mods/content/item_sharpening/effect_sharpen.dm b/mods/content/item_sharpening/effect_sharpen.dm index d7ce982218e7..c5711a326aba 100644 --- a/mods/content/item_sharpening/effect_sharpen.dm +++ b/mods/content/item_sharpening/effect_sharpen.dm @@ -14,6 +14,6 @@ if(distance <= 1) var/uses = item.get_item_effect_parameter(src, IE_CAT_DAMAGE, IE_PAR_USES) if(uses > 0) - to_chat(user, SPAN_NOTICE("\The [item] has been sharpened to a keen edge.")) + to_chat(user, SPAN_NOTICE("\The [item] has been honed to a keen edge.")) else - to_chat(user, SPAN_NOTICE("\The [item] is dull and in need of sharpening.")) + to_chat(user, SPAN_NOTICE("\The [item] in need of sharpening.")) diff --git a/mods/content/item_sharpening/item_sharpen.dm b/mods/content/item_sharpening/item_sharpen.dm index f302a6c609db..bc0d4480b0f7 100644 --- a/mods/content/item_sharpening/item_sharpen.dm +++ b/mods/content/item_sharpening/item_sharpen.dm @@ -37,9 +37,9 @@ return FALSE if(can_sharpen_with(sharpening_with)) user.visible_message("\The [user] begins sharpening \the [src] with \the [sharpening_with].") - // TODO: play sharpening sound? Spawn sparks for metal? + playsound(loc, 'sound/foley/knife1.ogg', 50) // metallic scrape, TODO better sound if(user.do_skilled(10 SECONDS, SKILL_WEAPONS, src, check_holding = TRUE) && !QDELETED(sharpening_with) && can_sharpen_with(sharpening_with) && sharpen_with(user, sharpening_with)) - // TODO: play sharpening sound? Spawn sparks for metal? + playsound(loc, 'sound/foley/knife1.ogg', 50) user.visible_message("\The [user] sharpens \the [src] with \the [sharpening_with].") else to_chat(user, SPAN_WARNING("\The [src] cannot be [initial(_sharp) ? "further sharpened" : "sharpened"] with \the [sharpening_with].")) diff --git a/mods/content/psionics/system/psionics/equipment/psipower.dm b/mods/content/psionics/system/psionics/equipment/psipower.dm index 8aa0afca3524..f608efe4d4c7 100644 --- a/mods/content/psionics/system/psionics/equipment/psipower.dm +++ b/mods/content/psionics/system/psionics/equipment/psipower.dm @@ -21,13 +21,13 @@ . = ..() /obj/item/ability/psionic/use_on_mob(mob/living/target, mob/living/user, animate = TRUE) - if(target.do_psionics_check(max(get_attack_force(user), maintain_cost), user)) + if(target.do_psionics_check(max(get_attack_force(user, dry_run = TRUE), maintain_cost), user)) to_chat(user, SPAN_WARNING("\The [src] flickers violently out of phase!")) return TRUE . = ..() /obj/item/ability/psionic/afterattack(var/atom/target, var/mob/living/user, var/proximity) - if(target.do_psionics_check(max(get_attack_force(user), maintain_cost), user)) + if(target.do_psionics_check(max(get_attack_force(user, dry_run = TRUE), maintain_cost), user)) to_chat(user, SPAN_WARNING("\The [src] flickers violently out of phase!")) return TRUE . = ..(target, user, proximity) diff --git a/mods/mobs/dionaea/mob/gestalt/gestalt_attacks.dm b/mods/mobs/dionaea/mob/gestalt/gestalt_attacks.dm index 05aeb1f74bb7..33e83ed20379 100644 --- a/mods/mobs/dionaea/mob/gestalt/gestalt_attacks.dm +++ b/mods/mobs/dionaea/mob/gestalt/gestalt_attacks.dm @@ -1,6 +1,6 @@ /obj/structure/diona_gestalt/attackby(var/obj/item/thing, var/mob/user) . = ..() - if(thing.get_attack_force(user)) + if(thing.get_attack_force(user, dry_run = TRUE)) shed_atom(forcefully = TRUE) /obj/structure/diona_gestalt/hitby() From a039aafd332aaa1186a3fef093d3963302eaf12a Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 16 Jan 2025 12:30:48 +1100 Subject: [PATCH 005/120] Reworking attack force procs to separate getting it for a check, and expending it for an attack. --- code/_onclick/item_attack.dm | 4 ++-- .../_machines_base/machinery_damage.dm | 2 +- code/game/machinery/atmoalter/canister.dm | 2 +- code/game/machinery/deployable.dm | 4 ++-- code/game/machinery/doors/_door.dm | 2 +- code/game/machinery/doors/airlock.dm | 4 ++-- code/game/machinery/floor_light.dm | 2 +- code/game/machinery/portable_turret.dm | 2 +- code/game/objects/effects/chem/foam.dm | 2 +- code/game/objects/effects/spiders.dm | 2 +- code/game/objects/items/__item.dm | 4 ++-- code/game/objects/items/_item_damage.dm | 2 +- code/game/objects/items/_item_force.dm | 23 +++++++++++-------- code/game/objects/items/_item_materials.dm | 2 +- .../game/objects/items/flame/flame_fuelled.dm | 2 +- .../objects/items/weapons/swords_axes_etc.dm | 4 ++-- code/game/objects/items/weapons/weaponry.dm | 2 +- code/game/objects/structures/__structure.dm | 2 +- .../structures/_structure_construction.dm | 2 +- .../crates_lockers/closets/__closet.dm | 2 +- .../crates_lockers/closets/statue.dm | 2 +- code/game/objects/structures/doors/_door.dm | 2 +- .../objects/structures/fireaxe_cabinet.dm | 2 +- code/game/objects/structures/fishtanks.dm | 2 +- code/game/objects/structures/flora/_flora.dm | 2 +- code/game/objects/structures/grille.dm | 4 ++-- code/game/objects/structures/inflatable.dm | 2 +- code/game/objects/structures/quicksand.dm | 2 +- code/game/objects/structures/railing.dm | 2 +- code/game/objects/structures/seaweed.dm | 2 +- code/game/objects/structures/town_bell.dm | 2 +- code/game/objects/structures/window.dm | 2 +- code/game/turfs/walls/wall_attacks.dm | 4 ++-- code/modules/blob/blob.dm | 4 ++-- .../cooking_vessels/_cooking_vessel.dm | 2 +- code/modules/holodeck/HolodeckObjects.dm | 2 +- .../hydroponics/spreading/spreading.dm | 4 ++-- code/modules/hydroponics/trays/tray.dm | 2 +- code/modules/item_effects/_item_effect.dm | 3 +++ code/modules/mechs/equipment/combat.dm | 2 +- code/modules/mechs/mech_damage.dm | 2 +- code/modules/mechs/mech_wreckage.dm | 2 +- code/modules/mob/grab/normal/grab_normal.dm | 8 +++---- .../modules/mob/living/human/human_defense.dm | 4 ++-- .../mob/living/human/unarmed_attack.dm | 4 ++-- code/modules/mob/living/living.dm | 2 +- code/modules/mob/living/living_defense.dm | 2 +- code/modules/mob/living/silicon/pai/pai.dm | 2 +- .../modules/mob/living/silicon/robot/robot.dm | 2 +- .../hostile/giant_spiders/_giant_spider.dm | 2 +- .../simple_animal/hostile/retaliate/goose.dm | 2 +- .../simple_animal/hostile/retaliate/parrot.dm | 2 +- .../living/simple_animal/natural_weapons.dm | 2 +- .../simple_animal/simple_animal_damage.dm | 2 +- code/modules/power/cable.dm | 2 +- code/modules/power/lighting.dm | 2 +- code/modules/power/solar.dm | 2 +- .../reagents/reagent_containers/_glass.dm | 2 +- .../reagent_containers/drinks/bottle.dm | 2 +- .../reagents/reagent_containers/mortar.dm | 2 +- code/modules/shield_generators/shield.dm | 2 +- code/modules/shieldgen/emergency_shield.dm | 2 +- code/modules/shieldgen/shieldwallgen.dm | 2 +- code/modules/vehicles/vehicle.dm | 4 ++-- .../artifacts/triggers/force.dm | 2 +- maps/away/errant_pisces/errant_pisces.dm | 2 +- .../content/item_sharpening/effect_sharpen.dm | 16 +++++++------ .../system/psionics/equipment/psipower.dm | 4 ++-- mods/content/xenobiology/slime/_slime.dm | 2 +- mods/gamemodes/cult/items.dm | 2 +- .../cult/mobs/constructs/soulstone.dm | 2 +- mods/gamemodes/cult/runes.dm | 2 +- mods/gamemodes/cult/structures.dm | 2 +- .../dionaea/mob/gestalt/gestalt_attacks.dm | 2 +- mods/species/ascent/effects/razorweb.dm | 2 +- 75 files changed, 114 insertions(+), 104 deletions(-) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index f6cf807ccb17..d798b551256a 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -92,7 +92,7 @@ avoid code duplication. This includes items that may sometimes act as a standard var/oldhealth = current_health . = used_item.use_on_mob(src, user) - if(used_item.get_attack_force(user, dry_run = TRUE) && istype(ai) && current_health < oldhealth) + if(used_item.get_attack_force(user) && istype(ai) && current_health < oldhealth) ai.retaliate(user) if(!. && user == src && user.get_target_zone() == BP_MOUTH && can_devour(used_item, silent = TRUE)) @@ -175,7 +175,7 @@ avoid code duplication. This includes items that may sometimes act as a standard else use_hitsound = "swing_hit" playsound(loc, use_hitsound, 50, 1, -1) - return target.hit_with_weapon(src, user, get_attack_force(user), hit_zone) + return target.hit_with_weapon(src, user, expend_attack_force(user), hit_zone) /obj/item/proc/handle_reflexive_fire(var/mob/user, var/atom/aiming_at) return istype(user) && istype(aiming_at) diff --git a/code/game/machinery/_machines_base/machinery_damage.dm b/code/game/machinery/_machines_base/machinery_damage.dm index a434776abd88..bba75011ff7a 100644 --- a/code/game/machinery/_machines_base/machinery_damage.dm +++ b/code/game/machinery/_machines_base/machinery_damage.dm @@ -85,7 +85,7 @@ /obj/machinery/bash(obj/item/W, mob/user) if(!istype(W)) return FALSE - var/force = W.get_attack_force(user) + var/force = W.expend_attack_force(user) if(force <= 5) return FALSE . = ..() diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 48e9178a8c70..52613f16121d 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -200,7 +200,7 @@ EMPTY_CANISTER(hydrogen, /obj/machinery/portable_atmospherics/canister/hydrogen) /obj/machinery/portable_atmospherics/canister/bash(var/obj/item/W, var/mob/user) . = ..() if(.) - current_health -= W.get_attack_force(user) + current_health -= W.expend_attack_force(user) healthcheck() /obj/machinery/portable_atmospherics/canister/attackby(var/obj/item/W, var/mob/user) diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm index 5b319d56bcb6..345a6b0359aa 100644 --- a/code/game/machinery/deployable.dm +++ b/code/game/machinery/deployable.dm @@ -52,9 +52,9 @@ else switch(W.atom_damage_type) if(BURN) - current_health -= W.get_attack_force(user) * 0.75 + current_health -= W.expend_attack_force(user) * 0.75 if(BRUTE) - current_health -= W.get_attack_force(user) * 0.5 + current_health -= W.expend_attack_force(user) * 0.5 if (current_health <= 0) explode() return TRUE diff --git a/code/game/machinery/doors/_door.dm b/code/game/machinery/doors/_door.dm index cc2a3c8adf4b..e76fe49edfef 100644 --- a/code/game/machinery/doors/_door.dm +++ b/code/game/machinery/doors/_door.dm @@ -335,7 +335,7 @@ return FALSE user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) user.do_attack_animation(src) - var/force = weapon.get_attack_force(user) + var/force = weapon.expend_attack_force(user) if(force < min_force) user.visible_message("\The [user] hits \the [src] with \the [weapon] with no visible effect.") else diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index aa341461f1c8..1be24240e750 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -802,7 +802,7 @@ About the new airlock wires panel: else if((stat & (BROKEN|NOPOWER)) && isanimal(user)) var/mob/living/simple_animal/A = user var/obj/item/I = A.get_natural_weapon() - if(I?.get_attack_force(user) >= 10) + if(I?.expend_attack_force(user) >= 10) if(density) visible_message(SPAN_DANGER("\The [A] forces \the [src] open!")) open(1) @@ -822,7 +822,7 @@ About the new airlock wires panel: var/obj/item/bladed/axe/fire/F = weapon if (F.is_held_twohanded()) playsound(src, 'sound/weapons/smash.ogg', 100, 1) - current_health -= F.get_attack_force(user) * 2 + current_health -= F.expend_attack_force(user) * 2 if(current_health <= 0) user.visible_message(SPAN_DANGER("[user] smashes \the [weapon] into the airlock's control panel! It explodes in a shower of sparks!"), SPAN_DANGER("You smash \the [weapon] into the airlock's control panel! It explodes in a shower of sparks!")) current_health = 0 diff --git a/code/game/machinery/floor_light.dm b/code/game/machinery/floor_light.dm index e31a013168b4..b6fefd1fe27b 100644 --- a/code/game/machinery/floor_light.dm +++ b/code/game/machinery/floor_light.dm @@ -58,7 +58,7 @@ var/global/list/floor_light_cache = list() qdel(src) return TRUE - if(W.get_attack_force(user, dry_run = TRUE) && user.check_intent(I_FLAG_HARM)) + if(W.get_attack_force(user) && user.check_intent(I_FLAG_HARM)) return physical_attack_hand(user) return ..() diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index 0124b95786e2..286ac6310cc4 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -290,7 +290,7 @@ var/global/list/turret_icons else //if the turret was attacked with the intention of harming it: - var/force = I.get_attack_force(user) * 0.5 + var/force = I.expend_attack_force(user) * 0.5 user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) take_damage(force, I.atom_damage_type) if(force > 1) //if the force of impact dealt at least 1 damage, the turret gets pissed off diff --git a/code/game/objects/effects/chem/foam.dm b/code/game/objects/effects/chem/foam.dm index 1e7a3685c90e..70d5c86bb2e0 100644 --- a/code/game/objects/effects/chem/foam.dm +++ b/code/game/objects/effects/chem/foam.dm @@ -171,7 +171,7 @@ return TRUE /obj/structure/foamedmetal/attackby(var/obj/item/I, var/mob/user) - if(prob(I.get_attack_force(user) * 20 - metal * 25)) + if(prob(I.expend_attack_force(user) * 20 - metal * 25)) user.visible_message( SPAN_WARNING("\The [user] smashes through the foamed metal."), SPAN_NOTICE("You smash through the foamed metal with \the [I].") diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index 07dab27d5ac2..2aae839cd613 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -41,7 +41,7 @@ else visible_message("\The [src] has been attacked with \the [W][(user ? " by [user]." : ".")]") - var/damage = W.get_attack_force(user) / 4 + var/damage = W.expend_attack_force(user) / 4 if(W.has_edge()) damage += 5 diff --git a/code/game/objects/items/__item.dm b/code/game/objects/items/__item.dm index a19db6e1a1e4..30fcf79bdedd 100644 --- a/code/game/objects/items/__item.dm +++ b/code/game/objects/items/__item.dm @@ -775,7 +775,7 @@ . += wielded_parry_bonus /obj/item/proc/on_disarm_attempt(mob/target, mob/living/attacker) - var/force = get_attack_force(attacker, dry_run = TRUE) + var/force = get_attack_force(attacker) if(force < 1) return 0 if(!istype(attacker)) @@ -1008,7 +1008,7 @@ modules/mob/living/human/life.dm if you die, you will be zoomed out. descriptors += "sharp" if(has_edge()) descriptors += "edged" - if(get_attack_force(dry_run = TRUE) >= 10 && !is_sharp() && !has_edge()) + if(get_attack_force() >= 10 && !is_sharp() && !has_edge()) descriptors += "heavy" if(material) descriptors += "made of [material.solid_name]" diff --git a/code/game/objects/items/_item_damage.dm b/code/game/objects/items/_item_damage.dm index 6d8803c33d3a..c91030262051 100644 --- a/code/game/objects/items/_item_damage.dm +++ b/code/game/objects/items/_item_damage.dm @@ -50,7 +50,7 @@ /obj/item/bash(obj/item/weapon, mob/user) . = ..() - var/force = weapon.get_attack_force(user) + var/force = weapon.expend_attack_force(user) if(force >= 3 && .) user.setClickCooldown(weapon.attack_cooldown + weapon.w_class) take_damage(force, weapon.atom_damage_type) diff --git a/code/game/objects/items/_item_force.dm b/code/game/objects/items/_item_force.dm index 5dbbbd01959c..2a494551d6aa 100644 --- a/code/game/objects/items/_item_force.dm +++ b/code/game/objects/items/_item_force.dm @@ -13,27 +13,32 @@ VAR_PROTECTED/_hardness_force_factor = 0.25 /obj/item/proc/get_max_weapon_force() - . = get_attack_force(dry_run = TRUE) + . = get_attack_force() if(can_be_twohanded) . = round(. * _wielded_force_multiplier) -// `dry_run` param is used for things like the grindstone modpack to avoid -// depleting sharpness when not actually being used to attack. -/obj/item/proc/get_attack_force(mob/living/user, dry_run = FALSE) +/obj/item/proc/expend_attack_force(mob/living/user) + . = get_attack_force(user) + var/list/item_effects = get_item_effects(IE_CAT_DAMAGE) + if(length(item_effects)) + for(var/decl/item_effect/damage_effect as anything in item_effects) + . = damage_effect.expend_attack_use(src, user, item_effects[damage_effect]) + +/obj/item/proc/get_attack_force(mob/living/user) if(_base_attack_force <= 0 || (item_flags & ITEM_FLAG_NO_BLUDGEON)) return 0 if(isnull(_cached_attack_force)) update_attack_force() if(_cached_attack_force <= 0) return 0 - return istype(user) ? user.modify_attack_force(src, _cached_attack_force, _wielded_force_multiplier, dry_run) : _cached_attack_force + return istype(user) ? user.modify_attack_force(src, _cached_attack_force, _wielded_force_multiplier) : _cached_attack_force // Existing hitby() code expects mobs, structures and machines to be thrown, it seems. /atom/movable/proc/get_thrown_attack_force() return get_object_size() /obj/item/get_thrown_attack_force() - return round(get_attack_force() * _thrown_force_multiplier) + return round(expend_attack_force() * _thrown_force_multiplier) /obj/item/proc/get_base_attack_force() return _base_attack_force @@ -99,7 +104,7 @@ // TODO: consider strength, athletics, mob size // `dry_run` param used in grindstone modpack to avoid depleting sharpness on non-attacks. -/mob/living/proc/modify_attack_force(obj/item/weapon, supplied_force, wield_mult, dry_run) +/mob/living/proc/modify_attack_force(obj/item/weapon, supplied_force, wield_mult) if(!istype(weapon) || !weapon.is_held_twohanded()) . = supplied_force else @@ -107,7 +112,7 @@ var/list/item_effects = weapon.get_item_effects(IE_CAT_DAMAGE) if(length(item_effects)) for(var/decl/item_effect/damage_effect as anything in item_effects) - . = damage_effect.modify_attack_damage(., weapon, src, dry_run, item_effects[damage_effect]) + . = damage_effect.modify_attack_damage(., weapon, src, item_effects[damage_effect]) return round(.) // Debug proc - leaving in for future work. Linter hates protected var access so leave commented. @@ -139,7 +144,7 @@ item = new item - var/attk_force = item.get_attack_force() + var/attk_force = item.expend_attack_force() var/expected_material_mod = ((attk_force * item._weight_force_factor) + (attk_force * item._hardness_force_factor))/2 rows += jointext(list( diff --git a/code/game/objects/items/_item_materials.dm b/code/game/objects/items/_item_materials.dm index 0615330d3cf5..ecf48b7029e8 100644 --- a/code/game/objects/items/_item_materials.dm +++ b/code/game/objects/items/_item_materials.dm @@ -12,7 +12,7 @@ /obj/item/apply_hit_effect(mob/living/target, mob/living/user, var/hit_zone) . = ..() - if(material && (material.is_brittle() || target.get_blocked_ratio(hit_zone, BRUTE, damage_flags(), armor_penetration, get_attack_force(user, dry_run = TRUE)) * 100 >= material.hardness/5)) + if(material && (material.is_brittle() || target.get_blocked_ratio(hit_zone, BRUTE, damage_flags(), armor_penetration, get_attack_force(user)) * 100 >= material.hardness/5)) apply_wear() /obj/item/on_parry(mob/user, damage_source, mob/attacker) diff --git a/code/game/objects/items/flame/flame_fuelled.dm b/code/game/objects/items/flame/flame_fuelled.dm index 42eec60835d1..07bcfe40859e 100644 --- a/code/game/objects/items/flame/flame_fuelled.dm +++ b/code/game/objects/items/flame/flame_fuelled.dm @@ -21,7 +21,7 @@ // Boilerplate from /obj/item/chems/glass. TODO generalize to a lower level. /obj/item/flame/fuelled/use_on_mob(mob/living/target, mob/living/user, animate = TRUE) - if(get_attack_force(dry_run = TRUE) && !(item_flags & ITEM_FLAG_NO_BLUDGEON) && user.check_intent(I_FLAG_HARM)) + if(get_attack_force() && !(item_flags & ITEM_FLAG_NO_BLUDGEON) && user.check_intent(I_FLAG_HARM)) . = ..() if(reagents?.total_volume && !QDELETED(target)) target.visible_message(SPAN_DANGER("Some of the contents of \the [src] splash onto \the [target].")) diff --git a/code/game/objects/items/weapons/swords_axes_etc.dm b/code/game/objects/items/weapons/swords_axes_etc.dm index 25ecca6f8563..eb8b3a9e3a8b 100644 --- a/code/game/objects/items/weapons/swords_axes_etc.dm +++ b/code/game/objects/items/weapons/swords_axes_etc.dm @@ -19,7 +19,7 @@ /obj/item/classic_baton/use_on_mob(mob/living/target, mob/living/user, animate = TRUE) if (user.has_genetic_condition(GENE_COND_CLUMSY) && prob(50)) - var/force = get_attack_force(user) + var/force = expend_attack_force(user) to_chat(user, SPAN_WARNING("You club yourself over the head.")) SET_STATUS_MAX(user, STAT_WEAK, (3 * force)) if(ishuman(user)) @@ -76,7 +76,7 @@ /obj/item/telebaton/use_on_mob(mob/living/target, mob/living/user, animate = TRUE) if(on && user.has_genetic_condition(GENE_COND_CLUMSY) && prob(50)) - var/force = get_attack_force(user) + var/force = expend_attack_force(user) to_chat(user, SPAN_DANGER("You club yourself over the head.")) SET_STATUS_MAX(user, STAT_WEAK, (3 * force)) if(ishuman(user)) diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index 243fe2bd7e88..43e52f205a44 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -207,7 +207,7 @@ return TRUE /obj/effect/energy_net/attackby(obj/item/W, mob/user) - current_health -= W.get_attack_force(user) + current_health -= W.expend_attack_force(user) healthcheck() return TRUE diff --git a/code/game/objects/structures/__structure.dm b/code/game/objects/structures/__structure.dm index 875f633e4558..e3cb8f48051b 100644 --- a/code/game/objects/structures/__structure.dm +++ b/code/game/objects/structures/__structure.dm @@ -250,7 +250,7 @@ SPAN_DANGER("\The [S] slices into [victim]'s face!"), SPAN_DANGER("\The [S] slices into your face!") ) - victim.standard_weapon_hit_effects(S, user, S.get_attack_force()*2, BP_HEAD) + victim.standard_weapon_hit_effects(S, user, S.expend_attack_force()*2, BP_HEAD) qdel(grab) else if(atom_flags & ATOM_FLAG_CLIMBABLE) var/obj/occupied = turf_is_crowded() diff --git a/code/game/objects/structures/_structure_construction.dm b/code/game/objects/structures/_structure_construction.dm index 86a88084bd35..186aa29e0e0f 100644 --- a/code/game/objects/structures/_structure_construction.dm +++ b/code/game/objects/structures/_structure_construction.dm @@ -62,7 +62,7 @@ /obj/structure/attackby(obj/item/used_item, mob/user) if(used_item.user_can_attack_with(user, silent = TRUE)) - var/force = used_item.get_attack_force(user) + var/force = used_item.expend_attack_force(user) if(force && user.check_intent(I_FLAG_HARM)) attack_animation(user) visible_message(SPAN_DANGER("\The [src] has been [pick(used_item.attack_verb)] with \the [used_item] by \the [user]!")) diff --git a/code/game/objects/structures/crates_lockers/closets/__closet.dm b/code/game/objects/structures/crates_lockers/closets/__closet.dm index ae0a39060279..6bfeca7cfe85 100644 --- a/code/game/objects/structures/crates_lockers/closets/__closet.dm +++ b/code/game/objects/structures/crates_lockers/closets/__closet.dm @@ -250,7 +250,7 @@ var/global/list/closets = list() /obj/structure/closet/attackby(obj/item/used_item, mob/user) - if(user.check_intent(I_FLAG_HARM) && used_item.get_attack_force(user, dry_run = TRUE)) + if(user.check_intent(I_FLAG_HARM) && used_item.get_attack_force(user)) return ..() if(!opened && (istype(used_item, /obj/item/stack/material) || IS_WRENCH(used_item)) ) diff --git a/code/game/objects/structures/crates_lockers/closets/statue.dm b/code/game/objects/structures/crates_lockers/closets/statue.dm index b34c334d77e1..27a6d55f4fce 100644 --- a/code/game/objects/structures/crates_lockers/closets/statue.dm +++ b/code/game/objects/structures/crates_lockers/closets/statue.dm @@ -99,7 +99,7 @@ check_health() /obj/structure/closet/statue/attackby(obj/item/I, mob/user) - current_health -= I.get_attack_force(user) + current_health -= I.expend_attack_force(user) user.do_attack_animation(src) visible_message("[user] strikes [src] with [I].") check_health() diff --git a/code/game/objects/structures/doors/_door.dm b/code/game/objects/structures/doors/_door.dm index 2697a5661b1b..ff6989638376 100644 --- a/code/game/objects/structures/doors/_door.dm +++ b/code/game/objects/structures/doors/_door.dm @@ -163,7 +163,7 @@ /obj/structure/door/attackby(obj/item/used_item, mob/user) add_fingerprint(user, 0, used_item) - if((user.check_intent(I_FLAG_HARM) && used_item.get_attack_force(user, dry_run = TRUE)) || istype(used_item, /obj/item/stack/material)) + if((user.check_intent(I_FLAG_HARM) && used_item.get_attack_force(user)) || istype(used_item, /obj/item/stack/material)) return ..() if(used_item.user_can_attack_with(user, silent = TRUE)) diff --git a/code/game/objects/structures/fireaxe_cabinet.dm b/code/game/objects/structures/fireaxe_cabinet.dm index f16681fa2d49..ec563ffce7e7 100644 --- a/code/game/objects/structures/fireaxe_cabinet.dm +++ b/code/game/objects/structures/fireaxe_cabinet.dm @@ -81,7 +81,7 @@ update_icon() return TRUE - var/force = O.get_attack_force(user) + var/force = O.expend_attack_force(user) if(force) user.setClickCooldown(10) attack_animation(user) diff --git a/code/game/objects/structures/fishtanks.dm b/code/game/objects/structures/fishtanks.dm index bc711de5671f..b6724f467752 100644 --- a/code/game/objects/structures/fishtanks.dm +++ b/code/game/objects/structures/fishtanks.dm @@ -69,7 +69,7 @@ var/global/list/fishtank_cache = list() return TRUE /obj/structure/glass_tank/attackby(var/obj/item/W, var/mob/user) - if(W.get_attack_force(user, dry_run = TRUE) < 5 || !user.check_intent(I_FLAG_HARM)) + if(W.get_attack_force(user) < 5 || !user.check_intent(I_FLAG_HARM)) attack_animation(user) visible_message(SPAN_NOTICE("\The [user] taps \the [src] with \the [W].")) else diff --git a/code/game/objects/structures/flora/_flora.dm b/code/game/objects/structures/flora/_flora.dm index 5e4be61b738b..c38361f4a845 100644 --- a/code/game/objects/structures/flora/_flora.dm +++ b/code/game/objects/structures/flora/_flora.dm @@ -34,7 +34,7 @@ /**Whether the item used by user can cause cut_down to be called. Used to bypass default attack proc for some specific items/tools. */ /obj/structure/flora/proc/can_cut_down(var/obj/item/I, var/mob/user) - return (I.get_attack_force(user) >= 5) && I.is_sharp() //Anything sharp and relatively strong can cut us instantly + return (I.expend_attack_force(user) >= 5) && I.is_sharp() //Anything sharp and relatively strong can cut us instantly /**What to do when the can_cut_down check returns true. Normally simply calls dismantle. */ /obj/structure/flora/proc/play_cut_sound(mob/user) diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 39080d777fb9..b4f70acd3256 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -211,9 +211,9 @@ playsound(loc, 'sound/effects/grillehit.ogg', 80, 1) switch(W.atom_damage_type) if(BURN) - take_damage(W.get_attack_force(user)) + take_damage(W.expend_attack_force(user)) if(BRUTE) - take_damage(W.get_attack_force(user) * 0.1) + take_damage(W.expend_attack_force(user) * 0.1) return TRUE return ..() diff --git a/code/game/objects/structures/inflatable.dm b/code/game/objects/structures/inflatable.dm index 12cdf96b365f..825e04a5ba66 100644 --- a/code/game/objects/structures/inflatable.dm +++ b/code/game/objects/structures/inflatable.dm @@ -139,7 +139,7 @@ /obj/structure/inflatable/attackby(obj/item/W, mob/user) - if((W.atom_damage_type == BRUTE || W.atom_damage_type == BURN) && (W.can_puncture() || W.get_attack_force(user) > 10)) + if((W.atom_damage_type == BRUTE || W.atom_damage_type == BURN) && (W.can_puncture() || W.expend_attack_force(user) > 10)) visible_message(SPAN_DANGER("\The [user] pierces \the [src] with \the [W]!")) deflate(TRUE) return TRUE diff --git a/code/game/objects/structures/quicksand.dm b/code/game/objects/structures/quicksand.dm index 383b435943b3..d891b03a6eaf 100644 --- a/code/game/objects/structures/quicksand.dm +++ b/code/game/objects/structures/quicksand.dm @@ -80,7 +80,7 @@ update_icon() /obj/effect/quicksand/attackby(obj/item/W, mob/user) - if(!exposed && W.get_attack_force(user)) + if(!exposed && W.expend_attack_force(user)) expose() return TRUE else diff --git a/code/game/objects/structures/railing.dm b/code/game/objects/structures/railing.dm index 96c1baf5b0aa..2ae373f0513d 100644 --- a/code/game/objects/structures/railing.dm +++ b/code/game/objects/structures/railing.dm @@ -291,7 +291,7 @@ WOOD_RAILING_SUBTYPE(yew) update_icon() return TRUE - var/force = W.get_attack_force(user) + var/force = W.expend_attack_force(user) if(force && (W.atom_damage_type == BURN || W.atom_damage_type == BRUTE)) user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) visible_message("\The [src] has been [LAZYLEN(W.attack_verb) ? pick(W.attack_verb) : "attacked"] with \the [W] by \the [user]!") diff --git a/code/game/objects/structures/seaweed.dm b/code/game/objects/structures/seaweed.dm index a76e6f838870..bfa52f88a189 100644 --- a/code/game/objects/structures/seaweed.dm +++ b/code/game/objects/structures/seaweed.dm @@ -31,7 +31,7 @@ icon = 'icons/obj/structures/plants.dmi' /obj/effect/decal/cleanable/lichen/attackby(obj/item/I, mob/user) - if(I.is_sharp() && I.get_attack_force(user) > 1) + if(I.is_sharp() && I.expend_attack_force(user) > 1) qdel(src) return TRUE . = ..() \ No newline at end of file diff --git a/code/game/objects/structures/town_bell.dm b/code/game/objects/structures/town_bell.dm index 4a0faee50f5f..45cb1f484511 100644 --- a/code/game/objects/structures/town_bell.dm +++ b/code/game/objects/structures/town_bell.dm @@ -48,7 +48,7 @@ /obj/structure/town_bell/attackby(obj/item/used_item, mob/user) . = ..() - if(used_item.get_attack_force()) + if(used_item.expend_attack_force()) ding_dong() /obj/structure/town_bell/attack_hand(mob/user) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index d516cd10eb23..5ee1d9e41dc2 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -292,7 +292,7 @@ // physical damage types that can impart force; swinging a bat or energy sword if(weapon.atom_damage_type == BRUTE || weapon.atom_damage_type == BURN) user.do_attack_animation(src) - hit(weapon.get_attack_force(user)) + hit(weapon.expend_attack_force(user)) if(current_health <= 7) set_anchored(FALSE) step(src, get_dir(user, src)) diff --git a/code/game/turfs/walls/wall_attacks.dm b/code/game/turfs/walls/wall_attacks.dm index 9986a22f4b11..9e8eb62472e5 100644 --- a/code/game/turfs/walls/wall_attacks.dm +++ b/code/game/turfs/walls/wall_attacks.dm @@ -132,7 +132,7 @@ qdel(WR) return TRUE else - var/force = W.get_attack_force(user) + var/force = W.expend_attack_force(user) if((!W.is_sharp() && !W.has_edge() && force >= 10) || force >= 20) to_chat(user, "\The [src] crumbles away under the force of your [W.name].") physically_destroyed() @@ -297,7 +297,7 @@ return TRUE // Attack the wall with items - var/force = W.get_attack_force(user) + var/force = W.expend_attack_force(user) if(istype(W,/obj/item/rcd) || istype(W, /obj/item/chems) || !force || user.check_intent(I_FLAG_HELP)) return ..() diff --git a/code/modules/blob/blob.dm b/code/modules/blob/blob.dm index e8f001355f0f..5de1ac052b18 100644 --- a/code/modules/blob/blob.dm +++ b/code/modules/blob/blob.dm @@ -182,11 +182,11 @@ var/damage = 0 switch(W.atom_damage_type) if(BURN) - damage = (W.get_attack_force(user) / fire_resist) + damage = (W.expend_attack_force(user) / fire_resist) if(IS_WELDER(W)) playsound(loc, 'sound/items/Welder.ogg', 100, 1) if(BRUTE) - damage = (W.get_attack_force(user) / brute_resist) + damage = (W.expend_attack_force(user) / brute_resist) take_damage(damage, W.atom_damage_type) return TRUE diff --git a/code/modules/food/cooking/cooking_vessels/_cooking_vessel.dm b/code/modules/food/cooking/cooking_vessels/_cooking_vessel.dm index 72f0d1a44c9f..fcd1cea0e1eb 100644 --- a/code/modules/food/cooking/cooking_vessels/_cooking_vessel.dm +++ b/code/modules/food/cooking/cooking_vessels/_cooking_vessel.dm @@ -35,7 +35,7 @@ // Boilerplate from /obj/item/chems/glass. TODO generalize to a lower level. /obj/item/chems/cooking_vessel/use_on_mob(mob/living/target, mob/living/user, animate = TRUE) - if(get_attack_force(dry_run = TRUE) && !(item_flags & ITEM_FLAG_NO_BLUDGEON) && user.check_intent(I_FLAG_HARM)) + if(get_attack_force() && !(item_flags & ITEM_FLAG_NO_BLUDGEON) && user.check_intent(I_FLAG_HARM)) return ..() return FALSE diff --git a/code/modules/holodeck/HolodeckObjects.dm b/code/modules/holodeck/HolodeckObjects.dm index 2d9b37d42098..e151a9bbbc48 100644 --- a/code/modules/holodeck/HolodeckObjects.dm +++ b/code/modules/holodeck/HolodeckObjects.dm @@ -157,7 +157,7 @@ playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1) visible_message("\The [src] was hit by \the [I].") if(I.atom_damage_type == BRUTE || I.atom_damage_type == BURN) - take_damage(I.get_attack_force(user)) + take_damage(I.expend_attack_force(user)) return TRUE src.add_fingerprint(user) diff --git a/code/modules/hydroponics/spreading/spreading.dm b/code/modules/hydroponics/spreading/spreading.dm index 533555b7c061..0980347c73d7 100644 --- a/code/modules/hydroponics/spreading/spreading.dm +++ b/code/modules/hydroponics/spreading/spreading.dm @@ -216,7 +216,7 @@ return TRUE else . = ..() - var/damage = W.get_attack_force(user) + var/damage = W.expend_attack_force(user) if(W.has_edge()) damage *= 2 adjust_health(-damage) @@ -285,7 +285,7 @@ return user.visible_message(SPAN_NOTICE("\The [user] starts chopping down \the [vine].")) playsound(get_turf(vine), holding.hitsound, 100, 1) - var/chop_time = (vine.current_health/holding.get_attack_force(user)) * 0.5 SECONDS + var/chop_time = (vine.current_health/holding.expend_attack_force(user)) * 0.5 SECONDS if(user.skill_check(SKILL_BOTANY, SKILL_ADEPT)) chop_time *= 0.5 if(do_after(user, chop_time, vine, TRUE)) diff --git a/code/modules/hydroponics/trays/tray.dm b/code/modules/hydroponics/trays/tray.dm index ff099293f8bd..41c957a226a0 100644 --- a/code/modules/hydroponics/trays/tray.dm +++ b/code/modules/hydroponics/trays/tray.dm @@ -499,7 +499,7 @@ return TRUE if(seed) - var/force = used_item.get_attack_force(user) + var/force = used_item.expend_attack_force(user) if(force) user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) user.visible_message("\The [seed.display_name] has been attacked by [user] with \the [used_item]!") diff --git a/code/modules/item_effects/_item_effect.dm b/code/modules/item_effects/_item_effect.dm index 3c88e8280212..54199b3584da 100644 --- a/code/modules/item_effects/_item_effect.dm +++ b/code/modules/item_effects/_item_effect.dm @@ -71,3 +71,6 @@ /decl/item_effect/proc/modify_attack_damage(base_damage, obj/item/used_item, mob/user, dry_run, list/parameters) return base_damage + +/decl/item_effect/proc/expend_attack_use(obj/item/used_item, mob/user, dry_run, list/parameters) + return diff --git a/code/modules/mechs/equipment/combat.dm b/code/modules/mechs/equipment/combat.dm index e9d182c1980a..fbc24657a603 100644 --- a/code/modules/mechs/equipment/combat.dm +++ b/code/modules/mechs/equipment/combat.dm @@ -438,7 +438,7 @@ /obj/aura/mech_ballistic/attackby(obj/item/I, mob/user) . = ..() - if (shield && prob(shield.block_chance(I.get_attack_force(dry_run = TRUE), I.armor_penetration, source = I, attacker = user))) + if (shield && prob(shield.block_chance(I.get_attack_force(), I.armor_penetration, source = I, attacker = user))) user.visible_message(SPAN_WARNING("\The [I] is blocked by \the [user]'s [shield.name].")) playsound(user.loc, 'sound/weapons/Genhit.ogg', 50, 1) return AURA_FALSE|AURA_CANCEL diff --git a/code/modules/mechs/mech_damage.dm b/code/modules/mechs/mech_damage.dm index 930c8d500603..a83ea60f14ab 100644 --- a/code/modules/mechs/mech_damage.dm +++ b/code/modules/mechs/mech_damage.dm @@ -28,7 +28,7 @@ . = ..() /mob/living/exosuit/resolve_item_attack(var/obj/item/I, var/mob/living/user, var/def_zone) - if(!I.get_attack_force(user)) + if(!I.expend_attack_force(user)) user.visible_message(SPAN_NOTICE("\The [user] bonks \the [src] harmlessly with \the [I].")) return diff --git a/code/modules/mechs/mech_wreckage.dm b/code/modules/mechs/mech_wreckage.dm index a78f4c7596c2..eb23590ea088 100644 --- a/code/modules/mechs/mech_wreckage.dm +++ b/code/modules/mechs/mech_wreckage.dm @@ -86,7 +86,7 @@ else to_chat(user, SPAN_WARNING("It's too solid to dismantle. Try cutting through some of the bigger bits.")) return 1 - else if(istype(W) && W.get_attack_force(user) > 20) + else if(istype(W) && W.expend_attack_force(user) > 20) visible_message(SPAN_DANGER("\The [src] has been smashed with \the [W] by \the [user]!")) if(prob(20)) physically_destroyed() diff --git a/code/modules/mob/grab/normal/grab_normal.dm b/code/modules/mob/grab/normal/grab_normal.dm index fcb921974f8f..df950514b867 100644 --- a/code/modules/mob/grab/normal/grab_normal.dm +++ b/code/modules/mob/grab/normal/grab_normal.dm @@ -154,7 +154,7 @@ var/obj/item/clothing/hat = attacker.get_equipped_item(slot_head_str) var/damage_flags = 0 if(istype(hat)) - damage += hat.get_attack_force(attacker) * 3 + damage += hat.expend_attack_force(attacker) * 3 damage_flags = hat.damage_flags() if(damage_flags & DAM_SHARP) @@ -228,7 +228,7 @@ if(!user.check_intent(I_FLAG_HARM)) return 0 // Not trying to hurt them. - if(!W.has_edge() || !W.get_attack_force(user, dry_run = TRUE) || W.atom_damage_type != BRUTE) + if(!W.has_edge() || !W.get_attack_force(user) || W.atom_damage_type != BRUTE) return 0 //unsuitable weapon user.visible_message("\The [user] begins to slit [affecting]'s throat with \the [W]!") @@ -241,7 +241,7 @@ var/damage_mod = 1 var/damage_flags = W.damage_flags() //presumably, if they are wearing a helmet that stops pressure effects, then it probably covers the throat as well - var/force = W.get_attack_force(user) + var/force = W.expend_attack_force(user) var/obj/item/clothing/head/helmet = affecting.get_equipped_item(slot_head_str) if(istype(helmet) && (helmet.body_parts_covered & SLOT_HEAD) && (helmet.item_flags & ITEM_FLAG_AIRTIGHT) && !isnull(helmet.max_pressure_protection)) var/datum/extension/armor/armor_datum = get_extension(helmet, /datum/extension/armor) @@ -273,7 +273,7 @@ return if(!user.check_intent(I_FLAG_HARM)) return 0 // Not trying to hurt them. - if(!W.has_edge() || !W.get_attack_force(user) || W.atom_damage_type != BRUTE) + if(!W.has_edge() || !W.expend_attack_force(user) || W.atom_damage_type != BRUTE) return 0 //unsuitable weapon var/obj/item/organ/external/O = grab.get_targeted_organ() if(!O || !(O.limb_flags & ORGAN_FLAG_HAS_TENDON) || (O.status & ORGAN_TENDON_CUT)) diff --git a/code/modules/mob/living/human/human_defense.dm b/code/modules/mob/living/human/human_defense.dm index 5e0ebff949e5..7e457b8256f2 100644 --- a/code/modules/mob/living/human/human_defense.dm +++ b/code/modules/mob/living/human/human_defense.dm @@ -119,7 +119,7 @@ meteor_act visible_message("\The [user] misses [src] with \the [I]!") return null - if(check_shields(I.get_attack_force(user, dry_run = TRUE), I, user, target_zone, I)) + if(check_shields(I.get_attack_force(user), I, user, target_zone, I)) return null var/obj/item/organ/external/affecting = GET_EXTERNAL_ORGAN(src, hit_zone) @@ -152,7 +152,7 @@ meteor_act if(!affecting) return 0 - var/blocked = get_blocked_ratio(hit_zone, I.atom_damage_type, I.damage_flags(), I.armor_penetration, I.get_attack_force(user, dry_run = TRUE)) + var/blocked = get_blocked_ratio(hit_zone, I.atom_damage_type, I.damage_flags(), I.armor_penetration, I.get_attack_force(user)) // Handle striking to cripple. if(user.check_intent(I_FLAG_DISARM)) effective_force *= 0.66 //reduced effective force... diff --git a/code/modules/mob/living/human/unarmed_attack.dm b/code/modules/mob/living/human/unarmed_attack.dm index 5811ea192946..3ae4dece2a1a 100644 --- a/code/modules/mob/living/human/unarmed_attack.dm +++ b/code/modules/mob/living/human/unarmed_attack.dm @@ -272,7 +272,7 @@ var/obj/item/clothing/shoes = user.get_equipped_item(slot_shoes_str) if(!istype(shoes)) return damage - return damage + (shoes ? shoes.get_attack_force(user) : 0) + return damage + (shoes ? shoes.expend_attack_force(user) : 0) /decl/natural_attack/kick/show_attack(var/mob/living/human/user, var/mob/living/human/target, var/zone, var/attack_damage) @@ -308,7 +308,7 @@ /decl/natural_attack/stomp/get_unarmed_damage(mob/living/user, mob/living/victim) var/obj/item/clothing/shoes = user.get_equipped_item(slot_shoes_str) - return damage + (shoes ? shoes.get_attack_force(user) : 0) + return damage + (shoes ? shoes.expend_attack_force(user) : 0) /decl/natural_attack/stomp/show_attack(var/mob/living/human/user, var/mob/living/human/target, var/zone, var/attack_damage) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index d0c29b6dd4a2..235ec0c62b45 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1754,7 +1754,7 @@ default behaviour is: user.set_special_ability_cooldown(5 SECONDS) visible_message(SPAN_DANGER("You hear something rumbling inside [src]'s stomach...")) var/obj/item/I = user.get_active_held_item() - var/force = I?.get_attack_force(user) + var/force = I?.expend_attack_force(user) if(!force) return var/d = rand(round(force / 4), force) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 73b1db81faa3..7a5c096451f1 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -219,7 +219,7 @@ if(affecting && istype(supplied_wound) && supplied_wound.is_open() && dtype == BRUTE) // Can't embed in a small bruise. var/obj/item/I = O var/sharp = I.is_sharp() || I.has_edge() - embed_damage *= (1 - get_blocked_ratio(def_zone, BRUTE, O.damage_flags(), O.armor_penetration, I.get_attack_force(user, dry_run = TRUE))) + embed_damage *= (1 - get_blocked_ratio(def_zone, BRUTE, O.damage_flags(), O.armor_penetration, I.get_attack_force(user))) //blunt objects should really not be embedding in things unless a huge amount of force is involved var/embed_chance = embed_damage / (sharp ? I.w_class : (I.w_class*3)) diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 5659569a4e94..b7e695a72cbe 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -287,7 +287,7 @@ var/global/list/possible_say_verbs = list( return TRUE if(try_stock_parts_removal(W, user)) return TRUE - var/force = W.get_attack_force(user) + var/force = W.expend_attack_force(user) if(force) visible_message(SPAN_DANGER("[user] attacks [src] with [W]!")) take_damage(force) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index d9cb6b6ff240..37e7095a3c94 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -626,7 +626,7 @@ else to_chat(user, "Upgrade error!") return TRUE - if(!(istype(W, /obj/item/robotanalyzer) || istype(W, /obj/item/scanner/health)) && !user.check_intent(I_FLAG_HELP) && W.get_attack_force(user)) + if(!(istype(W, /obj/item/robotanalyzer) || istype(W, /obj/item/scanner/health)) && !user.check_intent(I_FLAG_HELP) && W.expend_attack_force(user)) spark_at(src, 5, holder=src) return ..() diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spiders/_giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spiders/_giant_spider.dm index 3131138951d8..c08c3614b202 100644 --- a/code/modules/mob/living/simple_animal/hostile/giant_spiders/_giant_spider.dm +++ b/code/modules/mob/living/simple_animal/hostile/giant_spiders/_giant_spider.dm @@ -67,7 +67,7 @@ if(current_health < get_max_health()) var/obj/item/attacking_with = get_natural_weapon() if(attacking_with) - heal_overall_damage(0.2 * attacking_with.get_attack_force(src)) //heal a bit on hit + heal_overall_damage(0.2 * attacking_with.expend_attack_force(src)) //heal a bit on hit if(ishuman(target)) var/mob/living/human/H = target var/obj/item/clothing/suit/space/S = H.get_covering_equipped_item_by_zone(BP_CHEST) diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/goose.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/goose.dm index 25ddfdc7d4a9..f4f0d39d70cc 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/goose.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/goose.dm @@ -54,7 +54,7 @@ var/obj/item/attacking_with = get_natural_weapon() if(attacking_with) attacking_with.set_base_attack_force(min((attacking_with.get_initial_base_attack_force() + potency), max_damage)) - if(!loose && prob(25) && (attacking_with && attacking_with.get_attack_force(src) >= loose_threshold)) //second wind + if(!loose && prob(25) && (attacking_with && attacking_with.expend_attack_force(src) >= loose_threshold)) //second wind loose = TRUE set_max_health(initial(max_health) * 1.5) set_damage(BRUTE, 0) diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/parrot.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/parrot.dm index aab2c3fca766..8ca034e24a4f 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/parrot.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/parrot.dm @@ -333,7 +333,7 @@ //Mobs with objects /mob/living/simple_animal/hostile/parrot/attackby(var/obj/item/O, var/mob/user) . = ..() - if(!stat && !client && !istype(O, /obj/item/stack/medical) && O.get_attack_force(user)) + if(!stat && !client && !istype(O, /obj/item/stack/medical) && O.expend_attack_force(user)) if(parrot_state == PARROT_PERCH) parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched parrot_interest = user diff --git a/code/modules/mob/living/simple_animal/natural_weapons.dm b/code/modules/mob/living/simple_animal/natural_weapons.dm index a62b10cf5d0b..c3e1f11a780b 100644 --- a/code/modules/mob/living/simple_animal/natural_weapons.dm +++ b/code/modules/mob/living/simple_animal/natural_weapons.dm @@ -10,7 +10,7 @@ weapon_can_knock_prone = FALSE // Very powerful in the hands of simplemobs. var/show_in_message // whether should we show up in attack message, e.g. 'urist has been bit with teeth by carp' vs 'urist has been bit by carp' -/obj/item/natural_weapon/get_attack_force(mob/living/user, dry_run = FALSE) +/obj/item/natural_weapon/expend_attack_force(mob/living/user) return get_base_attack_force() /obj/item/natural_weapon/attack_message_name() diff --git a/code/modules/mob/living/simple_animal/simple_animal_damage.dm b/code/modules/mob/living/simple_animal/simple_animal_damage.dm index 66f589549167..32cce9c5b442 100644 --- a/code/modules/mob/living/simple_animal/simple_animal_damage.dm +++ b/code/modules/mob/living/simple_animal/simple_animal_damage.dm @@ -56,7 +56,7 @@ if(istype(ai)) ai.retaliate(user) - var/damage = O.get_attack_force(user) + var/damage = O.expend_attack_force(user) if(damage <= resistance) to_chat(user, SPAN_WARNING("This weapon is ineffective; it does no damage.")) return 0 diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 8bc69f07f558..1153dfc2f593 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -191,7 +191,7 @@ By design, d1 is the smallest direction and d2 is the highest else if(used_item.has_edge()) var/delay_holder - if(used_item.get_attack_force(user) < 5) + if(used_item.expend_attack_force(user) < 5) visible_message(SPAN_WARNING("[user] starts sawing away roughly at \the [src] with \the [used_item].")) delay_holder = 8 SECONDS else diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index a1f4640d16c6..2a3ae1574c83 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -264,7 +264,7 @@ else if(lightbulb && (lightbulb.status != LIGHT_BROKEN) && !user.check_intent(I_FLAG_HELP)) - if(prob(1 + W.get_attack_force(user) * 5)) + if(prob(1 + W.expend_attack_force(user) * 5)) user.visible_message("[user.name] smashed the light!", "You smash the light!", "You hear a tinkle of breaking glass.") if(on && (W.obj_flags & OBJ_FLAG_CONDUCTIBLE)) diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index bd129184831a..a941debb006a 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -88,7 +88,7 @@ var/global/list/solars_list = list() return TRUE else if (W) add_fingerprint(user) - current_health -= W.get_attack_force(user) + current_health -= W.expend_attack_force(user) healthcheck() return ..() diff --git a/code/modules/reagents/reagent_containers/_glass.dm b/code/modules/reagents/reagent_containers/_glass.dm index aee39d399219..f381c8a44bba 100644 --- a/code/modules/reagents/reagent_containers/_glass.dm +++ b/code/modules/reagents/reagent_containers/_glass.dm @@ -82,7 +82,7 @@ return ..() /obj/item/chems/glass/use_on_mob(mob/living/target, mob/living/user, animate = TRUE) - if(get_attack_force(user) && !(item_flags & ITEM_FLAG_NO_BLUDGEON) && user.check_intent(I_FLAG_HARM)) + if(expend_attack_force(user) && !(item_flags & ITEM_FLAG_NO_BLUDGEON) && user.check_intent(I_FLAG_HARM)) return ..() return FALSE diff --git a/code/modules/reagents/reagent_containers/drinks/bottle.dm b/code/modules/reagents/reagent_containers/drinks/bottle.dm index 318aae2a26d6..cc509d959e0d 100644 --- a/code/modules/reagents/reagent_containers/drinks/bottle.dm +++ b/code/modules/reagents/reagent_containers/drinks/bottle.dm @@ -168,7 +168,7 @@ user.visible_message(SPAN_DANGER("\The [user] smashes \the [src] into [H]'s [affecting.name]!")) // You are going to knock someone out for longer if they are not wearing a helmet. var/blocked = target.get_blocked_ratio(hit_zone, BRUTE, damage = 10) * 100 - var/weaken_duration = smash_duration + min(0, get_attack_force(user) - blocked + 10) + var/weaken_duration = smash_duration + min(0, expend_attack_force(user) - blocked + 10) if(weaken_duration) target.apply_effect(min(weaken_duration, 5), WEAKEN, blocked) // Never weaken more than a flash! else diff --git a/code/modules/reagents/reagent_containers/mortar.dm b/code/modules/reagents/reagent_containers/mortar.dm index fe85a5c09fee..b19a7340e236 100644 --- a/code/modules/reagents/reagent_containers/mortar.dm +++ b/code/modules/reagents/reagent_containers/mortar.dm @@ -28,7 +28,7 @@ var/decl/material/attacking_material = using_item.get_material() var/decl/material/crushing_material = crushing_item?.get_material() var/skill_factor = CLAMP01(1 + 0.3*(user.get_skill_value(SKILL_CHEMISTRY) - SKILL_EXPERT)/(SKILL_EXPERT - SKILL_MIN)) - if(using_item.get_attack_force(user) <= 0 || !attacking_material || !crushing_material) + if(using_item.expend_attack_force(user) <= 0 || !attacking_material || !crushing_material) return TRUE if(attacking_material.hardness <= crushing_material.hardness) to_chat(user, SPAN_NOTICE("\The [using_item] is not hard enough to crush \the [crushing_item].")) diff --git a/code/modules/shield_generators/shield.dm b/code/modules/shield_generators/shield.dm index 0b97dd24cbf0..d9c1d32489ba 100644 --- a/code/modules/shield_generators/shield.dm +++ b/code/modules/shield_generators/shield.dm @@ -217,7 +217,7 @@ if(!gen.check_flag(MODEFLAG_HYPERKINETIC)) user.visible_message("\The [user] tries to attack \the [src] with \the [weapon], but it passes through!") return TRUE - var/force = weapon.get_attack_force(user) + var/force = weapon.expend_attack_force(user) user.visible_message("\The [user] [pick(weapon.attack_verb)] \the [src] with \the [weapon]!") switch(weapon.atom_damage_type) if(BURN) diff --git a/code/modules/shieldgen/emergency_shield.dm b/code/modules/shieldgen/emergency_shield.dm index f76892be8a40..0cb3ee417b94 100644 --- a/code/modules/shieldgen/emergency_shield.dm +++ b/code/modules/shieldgen/emergency_shield.dm @@ -55,7 +55,7 @@ //Calculate damage switch(W.atom_damage_type) if(BRUTE, BURN) - current_health -= W.get_attack_force(user) + current_health -= W.expend_attack_force(user) else return FALSE diff --git a/code/modules/shieldgen/shieldwallgen.dm b/code/modules/shieldgen/shieldwallgen.dm index 126820437525..0ca75384784e 100644 --- a/code/modules/shieldgen/shieldwallgen.dm +++ b/code/modules/shieldgen/shieldwallgen.dm @@ -289,7 +289,7 @@ /obj/machinery/shieldwall/attackby(var/obj/item/I, var/mob/user) var/obj/machinery/shieldwallgen/G = prob(50) ? gen_primary : gen_secondary - G.storedpower -= I.get_attack_force(user)*2500 + G.storedpower -= I.expend_attack_force(user)*2500 user.visible_message("\The [user] hits \the [src] with \the [I]!") user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) user.do_attack_animation(src) diff --git a/code/modules/vehicles/vehicle.dm b/code/modules/vehicles/vehicle.dm index edfc8efaba4a..ce40b54d230c 100644 --- a/code/modules/vehicles/vehicle.dm +++ b/code/modules/vehicles/vehicle.dm @@ -115,10 +115,10 @@ // physical damage types that can impart force; swinging a bat or energy sword switch(weapon.atom_damage_type) if(BURN) - current_health -= weapon.get_attack_force(user) * fire_dam_coeff + current_health -= weapon.expend_attack_force(user) * fire_dam_coeff . = TRUE if(BRUTE) - current_health -= weapon.get_attack_force(user) * brute_dam_coeff + current_health -= weapon.expend_attack_force(user) * brute_dam_coeff . = TRUE else . = FALSE diff --git a/code/modules/xenoarcheaology/artifacts/triggers/force.dm b/code/modules/xenoarcheaology/artifacts/triggers/force.dm index c8003f314e72..97a771745f11 100644 --- a/code/modules/xenoarcheaology/artifacts/triggers/force.dm +++ b/code/modules/xenoarcheaology/artifacts/triggers/force.dm @@ -7,7 +7,7 @@ var/obj/item/projectile/hit_projectile = hit_with return (hit_projectile.atom_damage_type == BRUTE) else if(istype(hit_with, /obj/item)) - return (hit_with.get_attack_force(user) >= 10) + return (hit_with.expend_attack_force(user) >= 10) /datum/artifact_trigger/force/on_explosion(severity) return TRUE diff --git a/maps/away/errant_pisces/errant_pisces.dm b/maps/away/errant_pisces/errant_pisces.dm index f171768e57b1..98b02fae56ab 100644 --- a/maps/away/errant_pisces/errant_pisces.dm +++ b/maps/away/errant_pisces/errant_pisces.dm @@ -113,7 +113,7 @@ /obj/structure/net/attackby(obj/item/W, mob/user) if(W.is_sharp() || W.has_edge()) - var/force = W.get_attack_force(user) + var/force = W.expend_attack_force(user) if (!(W.is_sharp()) || (W.is_sharp() && force < 10))//is not sharp enough or at all to_chat(user,"You can't cut through \the [src] with \the [W], it's too dull.") return TRUE diff --git a/mods/content/item_sharpening/effect_sharpen.dm b/mods/content/item_sharpening/effect_sharpen.dm index c5711a326aba..5847ac347b36 100644 --- a/mods/content/item_sharpening/effect_sharpen.dm +++ b/mods/content/item_sharpening/effect_sharpen.dm @@ -1,14 +1,16 @@ -/decl/item_effect/sharpened/modify_attack_damage(base_damage, obj/item/used_item, mob/user, dry_run, list/parameters) +/decl/item_effect/sharpened/modify_attack_damage(base_damage, obj/item/used_item, mob/user, list/parameters) var/uses = LAZYACCESS(parameters, IE_PAR_USES) if(uses <= 0) return base_damage . = (1 + ((uses / max(1, LAZYACCESS(parameters, IE_PAR_MAX_USES))) * LAZYACCESS(parameters, IE_PAR_SHARP_DAM_MULT))) - if(!dry_run) - uses = max(0, uses-1) - used_item.set_item_effect_parameter(src, IE_CAT_DAMAGE, IE_PAR_USES, uses) - if(uses == 0) // We've gone dull! - used_item.update_attack_force() - used_item.update_name() + +/decl/item_effect/sharpened/expend_attack_use(obj/item/used_item, mob/user, list/parameters) + var/uses = LAZYACCESS(parameters, IE_PAR_USES) + uses = max(0, uses-1) + used_item.set_item_effect_parameter(src, IE_CAT_DAMAGE, IE_PAR_USES, uses) + if(uses == 0) // We've gone dull! + used_item.update_attack_force() + used_item.update_name() /decl/item_effect/sharpened/on_examined(obj/item/item, mob/user, distance, list/parameters) if(distance <= 1) diff --git a/mods/content/psionics/system/psionics/equipment/psipower.dm b/mods/content/psionics/system/psionics/equipment/psipower.dm index f608efe4d4c7..8aa0afca3524 100644 --- a/mods/content/psionics/system/psionics/equipment/psipower.dm +++ b/mods/content/psionics/system/psionics/equipment/psipower.dm @@ -21,13 +21,13 @@ . = ..() /obj/item/ability/psionic/use_on_mob(mob/living/target, mob/living/user, animate = TRUE) - if(target.do_psionics_check(max(get_attack_force(user, dry_run = TRUE), maintain_cost), user)) + if(target.do_psionics_check(max(get_attack_force(user), maintain_cost), user)) to_chat(user, SPAN_WARNING("\The [src] flickers violently out of phase!")) return TRUE . = ..() /obj/item/ability/psionic/afterattack(var/atom/target, var/mob/living/user, var/proximity) - if(target.do_psionics_check(max(get_attack_force(user, dry_run = TRUE), maintain_cost), user)) + if(target.do_psionics_check(max(get_attack_force(user), maintain_cost), user)) to_chat(user, SPAN_WARNING("\The [src] flickers violently out of phase!")) return TRUE . = ..(target, user, proximity) diff --git a/mods/content/xenobiology/slime/_slime.dm b/mods/content/xenobiology/slime/_slime.dm index a5b342022c26..37181b3cd0f8 100644 --- a/mods/content/xenobiology/slime/_slime.dm +++ b/mods/content/xenobiology/slime/_slime.dm @@ -272,7 +272,7 @@ return ..() /mob/living/slime/attackby(var/obj/item/W, var/mob/user) - var/force = W.get_attack_force(user) + var/force = W.expend_attack_force(user) if(force > 0) var/datum/mob_controller/slime/slime_ai = ai if(istype(slime_ai)) diff --git a/mods/gamemodes/cult/items.dm b/mods/gamemodes/cult/items.dm index 2b2e826617c7..e4faf111e49f 100644 --- a/mods/gamemodes/cult/items.dm +++ b/mods/gamemodes/cult/items.dm @@ -26,7 +26,7 @@ to_chat(user, SPAN_DANGER("An unexplicable force rips through you, tearing the sword from your grasp!")) //random amount of damage between half of the blade's force and the full force of the blade. - var/force = get_attack_force(user) + var/force = expend_attack_force(user) user.apply_damage(rand(force/2, force), BRUTE, zone, (DAM_SHARP|DAM_EDGE), armor_pen = 100) SET_STATUS_MAX(user, STAT_WEAK, 5) diff --git a/mods/gamemodes/cult/mobs/constructs/soulstone.dm b/mods/gamemodes/cult/mobs/constructs/soulstone.dm index b5a8f6f09485..69e5d0ef21e4 100644 --- a/mods/gamemodes/cult/mobs/constructs/soulstone.dm +++ b/mods/gamemodes/cult/mobs/constructs/soulstone.dm @@ -51,7 +51,7 @@ to_chat(user, SPAN_NOTICE("You cleanse \the [src] of taint, purging its shackles to its creator.")) is_evil = FALSE return TRUE - else if(I.get_attack_force(user) >= 5) + else if(I.expend_attack_force(user) >= 5) if(full != SOULSTONE_CRACKED) user.visible_message( SPAN_WARNING("\The [user] hits \the [src] with \the [I], and it breaks.[shade.client ? " You hear a terrible scream!" : ""]"), diff --git a/mods/gamemodes/cult/runes.dm b/mods/gamemodes/cult/runes.dm index 6724fbae270b..c54cb016914f 100644 --- a/mods/gamemodes/cult/runes.dm +++ b/mods/gamemodes/cult/runes.dm @@ -322,7 +322,7 @@ user.visible_message(SPAN_NOTICE("\The [user] touches \the [src] with \the [I], and it disappears."), SPAN_NOTICE("You disrupt the vile magic with the deadening field of \the [I].")) qdel(src) return TRUE - var/force = I.get_attack_force(user) + var/force = I.expend_attack_force(user) if(force) user.visible_message(SPAN_NOTICE("\The [user] hits \the [src] with \the [I]."), SPAN_NOTICE("You hit \the [src] with \the [I].")) take_damage(force, I.atom_damage_type) diff --git a/mods/gamemodes/cult/structures.dm b/mods/gamemodes/cult/structures.dm index 26eec8bb2175..9f39d61522d6 100644 --- a/mods/gamemodes/cult/structures.dm +++ b/mods/gamemodes/cult/structures.dm @@ -28,7 +28,7 @@ return TRUE /obj/structure/cult/pylon/attackby(obj/item/W, mob/user) - attackpylon(user, W.get_attack_force(user)) + attackpylon(user, W.expend_attack_force(user)) return TRUE /obj/structure/cult/pylon/proc/attackpylon(mob/user, var/damage) diff --git a/mods/mobs/dionaea/mob/gestalt/gestalt_attacks.dm b/mods/mobs/dionaea/mob/gestalt/gestalt_attacks.dm index 33e83ed20379..05aeb1f74bb7 100644 --- a/mods/mobs/dionaea/mob/gestalt/gestalt_attacks.dm +++ b/mods/mobs/dionaea/mob/gestalt/gestalt_attacks.dm @@ -1,6 +1,6 @@ /obj/structure/diona_gestalt/attackby(var/obj/item/thing, var/mob/user) . = ..() - if(thing.get_attack_force(user, dry_run = TRUE)) + if(thing.get_attack_force(user)) shed_atom(forcefully = TRUE) /obj/structure/diona_gestalt/hitby() diff --git a/mods/species/ascent/effects/razorweb.dm b/mods/species/ascent/effects/razorweb.dm index c8b05c70deb4..0647ffe0c91f 100644 --- a/mods/species/ascent/effects/razorweb.dm +++ b/mods/species/ascent/effects/razorweb.dm @@ -81,7 +81,7 @@ /obj/effect/razorweb/attackby(var/obj/item/thing, var/mob/user) var/destroy_self - if(thing.get_attack_force(user)) + if(thing.expend_attack_force(user)) visible_message(SPAN_DANGER("\The [user] breaks \the [src] with \the [thing]!")) destroy_self = TRUE From c399005aeba76fcb473b066adfa427ecf518e988 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 16 Jan 2025 21:39:32 +1100 Subject: [PATCH 006/120] Applying dev species icon patterns to staging, adding missing avian alt medical suit icons. --- mods/species/bayliens/tajaran/_tajaran.dm | 8 ++ .../bayliens/tajaran/machinery/suit_cycler.dm | 85 ++++++--------- mods/species/drakes/_drakes.dme | 1 + mods/species/drakes/clothing.dm | 28 ++--- mods/species/drakes/overrides.dm | 10 ++ mods/species/neoavians/clothing.dm | 57 +++++----- .../spacesuit/void/medical/helmet.dmi | Bin 2713 -> 2752 bytes .../spacesuit/void/medical_alt/helmet.dmi | Bin 0 -> 1404 bytes .../spacesuit/void/medical_alt/suit.dmi | Bin 0 -> 704 bytes .../neoavians/machinery/suit_cycler.dm | 99 ++++++++---------- 10 files changed, 135 insertions(+), 153 deletions(-) create mode 100644 mods/species/drakes/overrides.dm create mode 100644 mods/species/neoavians/icons/clothing/spacesuit/void/medical_alt/helmet.dmi create mode 100644 mods/species/neoavians/icons/clothing/spacesuit/void/medical_alt/suit.dmi diff --git a/mods/species/bayliens/tajaran/_tajaran.dm b/mods/species/bayliens/tajaran/_tajaran.dm index b4e664e999bb..b170c30db8bd 100644 --- a/mods/species/bayliens/tajaran/_tajaran.dm +++ b/mods/species/bayliens/tajaran/_tajaran.dm @@ -2,6 +2,14 @@ #define BODYTYPE_FELINE "feline body" #define BODY_EQUIP_FLAG_FELINE BITFLAG(7) +/obj/item + var/_feline_icon + +/obj/item/setup_sprite_sheets() + . = ..() + if(_feline_icon && !(BODYTYPE_FELINE in sprite_sheets)) + LAZYSET(sprite_sheets, BODYTYPE_FELINE, _feline_icon) + /obj/item/clothing/setup_equip_flags() . = ..() if(bodytype_equip_flags & BODY_EQUIP_FLAG_EXCLUDE) diff --git a/mods/species/bayliens/tajaran/machinery/suit_cycler.dm b/mods/species/bayliens/tajaran/machinery/suit_cycler.dm index af8842c7b19b..37e943e06750 100644 --- a/mods/species/bayliens/tajaran/machinery/suit_cycler.dm +++ b/mods/species/bayliens/tajaran/machinery/suit_cycler.dm @@ -2,70 +2,53 @@ LAZYDISTINCTADD(available_bodytypes, BODYTYPE_FELINE) . = ..() -/obj/item/clothing/suit/space/void/merc/setup_sprite_sheets() - . = ..() - LAZYSET(sprite_sheets, BODYTYPE_FELINE, 'mods/species/bayliens/tajaran/icons/clothing/merc/suit.dmi') +/obj/item/clothing/suit/space/void/merc + _feline_icon = 'mods/species/bayliens/tajaran/icons/clothing/merc/suit.dmi' -/obj/item/clothing/suit/space/void/swat/setup_sprite_sheets() - . = ..() - LAZYSET(sprite_sheets, BODYTYPE_FELINE, 'mods/species/bayliens/tajaran/icons/clothing/deathsquad/suit.dmi') +/obj/item/clothing/suit/space/void/swat + _feline_icon = 'mods/species/bayliens/tajaran/icons/clothing/deathsquad/suit.dmi' -/obj/item/clothing/suit/space/void/engineering/setup_sprite_sheets() - . = ..() - LAZYSET(sprite_sheets, BODYTYPE_FELINE, 'mods/species/bayliens/tajaran/icons/clothing/engineering/suit.dmi') +/obj/item/clothing/suit/space/void/engineering + _feline_icon = 'mods/species/bayliens/tajaran/icons/clothing/engineering/suit.dmi' -/obj/item/clothing/suit/space/void/mining/setup_sprite_sheets() - . = ..() - LAZYSET(sprite_sheets, BODYTYPE_FELINE, 'mods/species/bayliens/tajaran/icons/clothing/mining/suit.dmi') +/obj/item/clothing/suit/space/void/mining + _feline_icon = 'mods/species/bayliens/tajaran/icons/clothing/mining/suit.dmi' -/obj/item/clothing/suit/space/void/medical/setup_sprite_sheets() - . = ..() - LAZYSET(sprite_sheets, BODYTYPE_FELINE, 'mods/species/bayliens/tajaran/icons/clothing/medical/suit.dmi') +/obj/item/clothing/suit/space/void/medical + _feline_icon = 'mods/species/bayliens/tajaran/icons/clothing/medical/suit.dmi' -/obj/item/clothing/suit/space/void/security/setup_sprite_sheets() - . = ..() - LAZYSET(sprite_sheets, BODYTYPE_FELINE, 'mods/species/bayliens/tajaran/icons/clothing/sec/suit.dmi') +/obj/item/clothing/suit/space/void/security + _feline_icon = 'mods/species/bayliens/tajaran/icons/clothing/sec/suit.dmi' -/obj/item/clothing/suit/space/void/atmos/setup_sprite_sheets() - . = ..() - LAZYSET(sprite_sheets, BODYTYPE_FELINE, 'mods/species/bayliens/tajaran/icons/clothing/atmos/suit.dmi') +/obj/item/clothing/suit/space/void/atmos + _feline_icon = 'mods/species/bayliens/tajaran/icons/clothing/atmos/suit.dmi' -/obj/item/clothing/suit/space/void/engineering/alt/setup_sprite_sheets() - . = ..() - LAZYSET(sprite_sheets, BODYTYPE_FELINE, 'mods/species/bayliens/tajaran/icons/clothing/engineering_alt/suit.dmi') +/obj/item/clothing/suit/space/void/engineering/alt + _feline_icon = 'mods/species/bayliens/tajaran/icons/clothing/engineering_alt/suit.dmi' -/obj/item/clothing/suit/space/void/mining/alt/setup_sprite_sheets() - . = ..() - LAZYSET(sprite_sheets, BODYTYPE_FELINE, 'mods/species/bayliens/tajaran/icons/clothing/mining_alt/suit.dmi') +/obj/item/clothing/suit/space/void/mining/alt + _feline_icon = 'mods/species/bayliens/tajaran/icons/clothing/mining_alt/suit.dmi' -/obj/item/clothing/suit/space/void/medical/alt/setup_sprite_sheets() - . = ..() - LAZYSET(sprite_sheets, BODYTYPE_FELINE, 'mods/species/bayliens/tajaran/icons/clothing/medical_alt/suit.dmi') +/obj/item/clothing/suit/space/void/medical/alt + _feline_icon = 'mods/species/bayliens/tajaran/icons/clothing/medical_alt/suit.dmi' -/obj/item/clothing/suit/space/void/security/alt/setup_sprite_sheets() - . = ..() - LAZYSET(sprite_sheets, BODYTYPE_FELINE, 'mods/species/bayliens/tajaran/icons/clothing/sec_alt/suit.dmi') +/obj/item/clothing/suit/space/void/security/alt + _feline_icon = 'mods/species/bayliens/tajaran/icons/clothing/sec_alt/suit.dmi' -/obj/item/clothing/suit/space/void/atmos/alt/setup_sprite_sheets() - . = ..() - LAZYSET(sprite_sheets, BODYTYPE_FELINE, 'mods/species/bayliens/tajaran/icons/clothing/atmos_alt/suit.dmi') +/obj/item/clothing/suit/space/void/atmos/alt + _feline_icon = 'mods/species/bayliens/tajaran/icons/clothing/atmos_alt/suit.dmi' -/obj/item/clothing/suit/space/void/engineering/salvage/setup_sprite_sheets() - . = ..() - LAZYSET(sprite_sheets, BODYTYPE_FELINE, 'mods/species/bayliens/tajaran/icons/clothing/salvage/suit.dmi') +/obj/item/clothing/suit/space/void/engineering/salvage + _feline_icon = 'mods/species/bayliens/tajaran/icons/clothing/salvage/suit.dmi' -/obj/item/clothing/suit/space/void/expedition/setup_sprite_sheets() - . = ..() - LAZYSET(sprite_sheets, BODYTYPE_FELINE, 'mods/species/bayliens/tajaran/icons/clothing/pilot/suit.dmi') +/obj/item/clothing/suit/space/void/expedition + _feline_icon = 'mods/species/bayliens/tajaran/icons/clothing/pilot/suit.dmi' -/obj/item/clothing/suit/space/void/setup_sprite_sheets() - . = ..() - LAZYSET(sprite_sheets, BODYTYPE_FELINE, 'mods/species/bayliens/tajaran/icons/clothing/nasa/suit.dmi') +/obj/item/clothing/suit/space/void + _feline_icon = 'mods/species/bayliens/tajaran/icons/clothing/nasa/suit.dmi' -/obj/item/clothing/suit/space/void/wizard/setup_sprite_sheets() - . = ..() - LAZYSET(sprite_sheets, BODYTYPE_FELINE, 'mods/species/bayliens/tajaran/icons/clothing/wizard/suit.dmi') +/obj/item/clothing/suit/space/void/wizard + _feline_icon = 'mods/species/bayliens/tajaran/icons/clothing/wizard/suit.dmi' -/obj/item/clothing/suit/space/void/excavation/setup_sprite_sheets() - . = ..() - LAZYSET(sprite_sheets, BODYTYPE_FELINE, 'mods/species/bayliens/tajaran/icons/clothing/excavation/suit.dmi') +/obj/item/clothing/suit/space/void/excavation + _feline_icon = 'mods/species/bayliens/tajaran/icons/clothing/excavation/suit.dmi' diff --git a/mods/species/drakes/_drakes.dme b/mods/species/drakes/_drakes.dme index 44fa41725be3..c485410158f3 100644 --- a/mods/species/drakes/_drakes.dme +++ b/mods/species/drakes/_drakes.dme @@ -19,6 +19,7 @@ #include "drake_spit.dm" #include "drake_traits.dm" #include "language.dm" +#include "overrides.dm" #include "sifpod.dm" #include "sifsap.dm" #include "species.dm" diff --git a/mods/species/drakes/clothing.dm b/mods/species/drakes/clothing.dm index ac23b01ba190..63c803bc1dbe 100644 --- a/mods/species/drakes/clothing.dm +++ b/mods/species/drakes/clothing.dm @@ -1,21 +1,11 @@ +/obj/item/backpack + _drake_onmob_icon = 'mods/species/drakes/icons/clothing/backpack.dmi' + _drake_hatchling_onmob_icon = 'mods/species/drakes/icons/clothing/hatchling_backpack.dmi' -/obj/item/backpack/setup_sprite_sheets() - . = ..() - if(!(BODYTYPE_GRAFADREKA in sprite_sheets)) - LAZYSET(sprite_sheets, BODYTYPE_GRAFADREKA, 'mods/species/drakes/icons/clothing/backpack.dmi') - if(!(BODYTYPE_GRAFADREKA_HATCHLING in sprite_sheets)) - LAZYSET(sprite_sheets, BODYTYPE_GRAFADREKA_HATCHLING, 'mods/species/drakes/icons/clothing/hatchling_backpack.dmi') +/obj/item/card/id + _drake_onmob_icon = 'mods/species/drakes/icons/clothing/id.dmi' + _drake_hatchling_onmob_icon = 'mods/species/drakes/icons/clothing/hatchling_id.dmi' -/obj/item/card/id/setup_sprite_sheets() - . = ..() - if(!(BODYTYPE_GRAFADREKA in sprite_sheets)) - LAZYSET(sprite_sheets, BODYTYPE_GRAFADREKA, 'mods/species/drakes/icons/clothing/id.dmi') - if(!(BODYTYPE_GRAFADREKA_HATCHLING in sprite_sheets)) - LAZYSET(sprite_sheets, BODYTYPE_GRAFADREKA_HATCHLING, 'mods/species/drakes/icons/clothing/hatchling_id.dmi') - -/obj/item/bag/setup_sprite_sheets() - . = ..() - if(!(BODYTYPE_GRAFADREKA in sprite_sheets)) - LAZYSET(sprite_sheets, BODYTYPE_GRAFADREKA, 'mods/species/drakes/icons/clothing/sack.dmi') - if(!(BODYTYPE_GRAFADREKA_HATCHLING in sprite_sheets)) - LAZYSET(sprite_sheets, BODYTYPE_GRAFADREKA_HATCHLING, 'mods/species/drakes/icons/clothing/hatchling_backpack.dmi') +/obj/item/bag + _drake_onmob_icon = 'mods/species/drakes/icons/clothing/sack.dmi' + _drake_hatchling_onmob_icon = 'mods/species/drakes/icons/clothing/hatchling_backpack.dmi' diff --git a/mods/species/drakes/overrides.dm b/mods/species/drakes/overrides.dm new file mode 100644 index 000000000000..a4246927c61e --- /dev/null +++ b/mods/species/drakes/overrides.dm @@ -0,0 +1,10 @@ +/obj/item + var/_drake_onmob_icon + var/_drake_hatchling_onmob_icon + +/obj/item/setup_sprite_sheets() + . = ..() + if(_drake_onmob_icon) + LAZYSET(sprite_sheets, BODYTYPE_GRAFADREKA, _drake_onmob_icon) + if(_drake_hatchling_onmob_icon) + LAZYSET(sprite_sheets, BODYTYPE_GRAFADREKA_HATCHLING, _drake_hatchling_onmob_icon) diff --git a/mods/species/neoavians/clothing.dm b/mods/species/neoavians/clothing.dm index 98f5b8dac918..ff9f7c78b8b0 100644 --- a/mods/species/neoavians/clothing.dm +++ b/mods/species/neoavians/clothing.dm @@ -1,11 +1,17 @@ -//Shoes -/obj/item/clothing/shoes/magboots/setup_sprite_sheets() - . = ..() - LAZYSET(sprite_sheets, BODYTYPE_AVIAN, 'mods/species/neoavians/icons/clothing/feet/magboots.dmi') +/obj/item + var/_avian_icon -/obj/item/clothing/shoes/galoshes/setup_sprite_sheets() +/obj/item/setup_sprite_sheets() . = ..() - LAZYSET(sprite_sheets, BODYTYPE_AVIAN, 'mods/species/neoavians/icons/clothing/feet/galoshes.dmi') + if(_avian_icon && !(BODYTYPE_AVIAN in sprite_sheets)) + LAZYSET(sprite_sheets, BODYTYPE_AVIAN, _avian_icon) + +//Shoes +/obj/item/clothing/shoes/magboots + _avian_icon = 'mods/species/neoavians/icons/clothing/feet/magboots.dmi' + +/obj/item/clothing/shoes/galoshes + _avian_icon = 'mods/species/neoavians/icons/clothing/feet/galoshes.dmi' //Gloves /obj/item/clothing/gloves/setup_equip_flags() @@ -13,34 +19,29 @@ if(!isnull(bodytype_equip_flags) && !(bodytype_equip_flags & BODY_EQUIP_FLAG_EXCLUDE)) bodytype_equip_flags |= BODY_EQUIP_FLAG_AVIAN -/obj/item/clothing/gloves/setup_sprite_sheets() - . = ..() - LAZYSET(sprite_sheets, BODYTYPE_AVIAN, 'mods/species/neoavians/icons/clothing/gloves.dmi') +/obj/item/clothing/gloves + _avian_icon = 'mods/species/neoavians/icons/clothing/gloves.dmi' //Backpacks & tanks - -/obj/item/backpack/satchel/Initialize() - . = ..() - LAZYSET(sprite_sheets, BODYTYPE_AVIAN, 'mods/species/neoavians/icons/clothing/satchel.dmi') +/obj/item/backpack/satchel + _avian_icon = 'mods/species/neoavians/icons/clothing/satchel.dmi' //Radsuits (theyre essential?) +/obj/item/clothing/head/radiation + _avian_icon = 'mods/species/neoavians/icons/clothing/head/rad_helm.dmi' -/obj/item/clothing/head/radiation/setup_sprite_sheets() - . = ..() - LAZYSET(sprite_sheets, BODYTYPE_AVIAN, 'mods/species/neoavians/icons/clothing/head/rad_helm.dmi') +/obj/item/clothing/head/radiation + _avian_icon = 'mods/species/neoavians/icons/clothing/head/rad_helm.dmi' -/obj/item/clothing/suit/radiation/setup_sprite_sheets() - . = ..() - LAZYSET(sprite_sheets, BODYTYPE_AVIAN, 'mods/species/neoavians/icons/clothing/suit/rad_suit.dmi') +/obj/item/clothing/suit/radiation + _avian_icon = 'mods/species/neoavians/icons/clothing/suit/rad_suit.dmi' //cloaks -/obj/item/clothing/suit/cloak/setup_sprite_sheets() - . = ..() - LAZYSET(sprite_sheets, BODYTYPE_AVIAN, 'mods/species/neoavians/icons/clothing/accessory/cloak.dmi') +/obj/item/clothing/suit/cloak + _avian_icon = 'mods/species/neoavians/icons/clothing/accessory/cloak.dmi' -/obj/item/clothing/suit/cloak/hide/setup_sprite_sheets() - . = ..() - LAZYSET(sprite_sheets, BODYTYPE_AVIAN, 'mods/species/neoavians/icons/clothing/accessory/cloak_hide.dmi') +/obj/item/clothing/suit/cloak/hide + _avian_icon = 'mods/species/neoavians/icons/clothing/accessory/cloak_hide.dmi' //clothing /obj/item/clothing/dress/avian_smock @@ -49,6 +50,7 @@ icon = 'mods/species/neoavians/icons/clothing/under/smock.dmi' icon_state = ICON_STATE_WORLD bodytype_equip_flags = BODY_EQUIP_FLAG_AVIAN + _avian_icon = null /obj/item/clothing/dress/avian_smock/worker name = "worker's smock" @@ -81,11 +83,16 @@ name = "stylish uniform" icon = 'mods/species/neoavians/icons/clothing/under/stylish_form.dmi' +/obj/item/clothing/shoes + _avian_icon = 'mods/species/neoavians/icons/clothing/feet/shoes.dmi' + /obj/item/clothing/shoes/avian name = "small shoes" icon = 'mods/species/neoavians/icons/clothing/feet/shoes.dmi' color = COLOR_GRAY bodytype_equip_flags = BODY_EQUIP_FLAG_AVIAN + _avian_icon = null + icon = 'mods/species/neoavians/icons/clothing/feet/shoes.dmi' /obj/item/clothing/shoes/avian/footwraps name = "cloth footwraps" diff --git a/mods/species/neoavians/icons/clothing/spacesuit/void/medical/helmet.dmi b/mods/species/neoavians/icons/clothing/spacesuit/void/medical/helmet.dmi index fe7e1534a7eaf41747fae467ab89b7a7d51eb29b..645c2a006bf70795c88c29c053f9df7935da2aad 100644 GIT binary patch literal 2752 zcmd6pYc$kbAIJY1Nh0YY38SdQ)TAW2E16U%O^ya5XCjweVn&GhQ;wphQ9U8I(MXdR z*Hi~%bTf63=2XTdCd7;}gUNl&<@vXsS3T>zdR8x<7khu#Ui-KAUVH8DXMK12ad(u4 znywlE02;1`ojoCKhFX!T3e;mvaDI^7O+b6&odaWV(IHXzkjMxCh|5oEt5$otYpu(` z{<-bMo>Ol^FSKsne*1pXAFEx@?|iM2d$c5S!q6%`e-zQ0O>EfFz8DycXmtQ23%Cr=HdA5AA()&wCB{9>aO>+H-6?+ z+?}+DB&E|#n2fYg{FRi^9So(_Hv3!v$9+fuSU%$F?1YZX7xj4r>+v?IOrC3j9mIpuLp2PCt&$gzz;K^do_e4&Z#A#eI#uzzGPQEQAM*z)1M$mSIwFC|jPdaQ23pj%5j zoz`{HZ@!$eeKfaZV`N*R%9*gYy8Ze!X{hhI;9FgT4K-;OmChf+4R+FfCT%q%2y3mi zHvz);ZCP4nAl@$zF-EZh3VHYaNMBztFzoB58o03LSze?lqJlGal2#{A?}wQPNJSHiyWG|kxT9M4kg5GqE&ecp3DKAC zwZdO-!CWq-F@+ri<9!V}aCis7z|72S;M+IjWQK^M5LJq~D8(z;;#^%gcnPwwU^Tf(JVr`{!jN}7RYEZVoN4+@H7BY$V5|#s`~`v;%!(C~kv?nzNPQm#%r4>t zLiL9u03eR%=U>67*0V_DO6%HD?6pIWL29<6kj$hVmWl7&^m!uLrj~pp$FxaT2dKa{ z)N}@0Xy38L>XKY==Ao#StP53;i?RY=%*kLeZC9+#G6GLWl@+%}5T;K)v#u{ckU4k2 zLfr_xqvx~yw@v7C$KJ(AA*+eCl4auSpWzPa(BQLH5z|4=Bw~A$N96PD9M~wC851LS z1f>Ps#`w_1p>1LY4>kV=S;ql~{yw{P#zSh(50HsDV>6|scm5$`WTq$A*Qb(0`$XuI ziF>n=9;H)8wmICs^B%|Yd*t)3`U%9;)@&NS5I*qgI`rV_>Bj_=dK-(yq4mWMM9iU5 zPyni)gk`l3dqPGrR6P}oP3@M9acd|q=hTwyqy zqRV+I`fx!HZ>>+i&NP|vSO?6qknW(=A_J{(E*L=fP_+kI0W46}he?Wa+IzLV)~zT& zC!i4?B&`X_?eR&yRCuxI(0t}zDWSGI(XKB>AzVUsz{GW1xFPy{n$0S)T@;Ug z9ty}frEo_5H~|YvjWfIzXk<$4xu9-1*vvz{ee6KgwRtw7ZiH1Z#(K`4R=ie%h#i}e ze1fny0-jz0r7tr3;UEJ`>3MD*8GH{&Mk=g1tE$rZrlbQQQ93?|@6!@n4iuS2kVk&80ko}br z35s{t>Vj+ysGi^rN@Ghrd!L(E(wuCQHIWe&b!K;S>nj=@haE;4rUy51m&FsIO!fccAF}o5r2Tp1HU`qOJwGEn~=%OoYMO&kKsm!m(*OzdIZ9_&&&ZX;ccm7JJ6H}Htn$uRWg6aY~M z&GAqbhTdsJ*nhR!1;~%A!;n7>2bZUpvu=O$R=O5De|qMl|JUO2j?1Q!+9mVli!r(6 zWz88xw5q{bJ95_`xXMQw>Ptplp1!H>s2FtNZgvpJ5wA1kr=}5$`fQQE(?L~<_Q1U^ zztHn5HnbbrdkJfzx3*RrTaO*^g)q!S%n!Rn;{;RI;X!9zYIoww` zJTGPmd*Sz%x;@72WfA=5t^&l>4Wq7!G&lj&{vEz2=sRzB?ne*v=A}9cyom^RSYgSp xZaB!|q7A$zi^plaHBkQXsjiy9{{)*19$#BZ?Dr01f5sndNn5HogW9CllKGr&G-MiL3>)t>1{;a+B{_g!<-|y%9`R?l{ z;m0;>7-;|iu-VhY&0CIL^6@}TMLzpmgq@c|e)?%&lv{XGSYl*6DiRq70BIyl|5J@_ zh@SgL2f-ff#2HFdLjTS^zdXcT+3FdyuSccOs{*-VYJZ*dNi#S%I<-;p1Tu27*GDJU zGU#^Cj&ZN-UXk1PD#fLlmDg?oxo_*1FHSZx*S-ti78Z{^;dHdx10AGc}^fI*r6;yoxsdV4}KOeZP+i+-P!Ne$Y4fy<ylk&mUE7DYp zJ{+QXCFBZ+(%iqpwzgGEuR{O4=9``aYkz@c3_FF_9(o#4j()~mSqJI9N&J#gCLkA% zj7xU6wzR11tR^2^2I*|pRXkj}AJ}E|PZ&0*CHDo=OqMz@6VaXt%RrTZB-~njim2Uv zYN#&5<@pmw_37>Sq$f*x2aR&g7gJQ4djV3kjS*s$T{SlMAlfsr7I3o`ZsSuOUmb%w zt3|yF*6%t8Egng80#d$I99az+p1o!zReegSUre9WEx+ryXm9~a2tcb$`z4QLfZgUO`IOl#4E-w0B(t9Dq#gMUEM5XQxw4dHsb5wavx$$!8prc2dCCdn z-7#NtAyD;$NlDQ9oV73oaJTzI#hgT5K2E)tM>kbUY{OU>c4NsZN&d z0B0|}kfw|#?GUh3JTTK(o%(x6H>Oy`L0f1qL7U>AR-7~7UES8&paitPQeCGPRd_cG z&O2BV2!vG(_`rb!0RG;+Z9+1ULZO@J8|2yD#-nU4JLVC9(<2v{4H zE0{mBx*9dAL?Z3K_qIudpc+~RHGGIs__f7ywZ9htxCsl}f7-LbeGiG0>Y6At)7cO* z_eLz8k&=AK_l|zeowUOdvjj?LYNj8}t{R4Y*H$@zD+Q{utKXcv0-AnH?O)=jV;tV_ zDo)kY?$!r(ywpOy!>w@Gah*b;VdJzte8C=miEcZ298Iaqhb3A5uCJd}Yfu{QcR?N; z>Y8oQK%AOMpL%0Z_U=L44D_%Qy2d5S=E1xVlC@-PSC1)}bGY?9fj5zZ=(t}GvibS~ zXWiL(V`)*AyZ^Cx_gWvKyGMj*R*km|Pb;QDrS$aFwIsmNY;8e$4O;l2;=23t$kQzu zC~z12v~Fu0Ba4NWA6@Xx1{z?FcaPP=u&Cf77x^_a;XD~NfNFKASXOnB$tw}sT+&f` z(V3a9ZNPjnyfHN|6i$xu(Xn^c#GgCZ`~fc4Az3!#XfW)XQ6O?O9Y(h@s;HF$EY}Md z-jxOt+fjX5NF6h{oIJNw$Mm;4h`B2H!O zV5f2>U-k63RTAQplMj*#3l)a_e&)esd!*}gxaT+-xusEOH@^?jpD#je5FlqDB}1$% z(_fWcZuY0ofrv|*uyPEFL}8|v~H$st?Xf(4AK|UE#ZmfO-H7eOXZ0eGQ3D$m7AiIF_ZKNDfg*fdfuLZH-oq(YOg z9P+2hHj8|5;%MG>dA=wxBK5dZ;r;aq z((@&=z!K(Vj%a0cIYX*jq5`djN!{ygJCZR|$Hjq>7!k{uePOMSx%YOB>J#G0@6RBj zaguVa4(B7)r>R&>ws&<6M{qz^-R{~5BX5%j{RcU#WIIpj|Hk6IFjY&Gca3LLX+S|i z!NQmi0nVCHJw%_3YEE3#E9dy&x$JYT$z!U&-NOZe@ouvvM{Zuy1g`f2|1I2kZmn~# z!n;~CL(P=}{ZE!m#a%!8<1#;as~(QRNzOjL?XzhxfwbBr=)1d*`mK(fo$tZHZEm0t zTqaLE>vh-SYv6*u8ki`shX#M&vP1+kX!AY%KAc?AE^&z9^S3To(2hYoX8?IylFN%f zzfblLrSV7MBwX$bBuq>*vr+^a{OLh*(Ycz4QF{O7U(^(_hW9kU$POFaidjA=dv*uj f1M;UhxULespBAgs%_qwLntAz6O|sHZKJ diff --git a/mods/species/neoavians/icons/clothing/spacesuit/void/medical_alt/helmet.dmi b/mods/species/neoavians/icons/clothing/spacesuit/void/medical_alt/helmet.dmi new file mode 100644 index 0000000000000000000000000000000000000000..779b0d77fe462b727aa86c6e8996cc011c16fbb0 GIT binary patch literal 1404 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGo?NuQWB`&GO$wiq3C7Jno3=9=> zYESRwI%FWicER$yrroW`kIS>gJT)b6g=x3Y6eZ4PG^zGk;S*gNlA zNb6~~?spYRpC7G|6uZtnb56y{U#%GzSi05T$e7*nu8~jCwR$d+#vIaee%G~UtXQdXu%rE1-=XnEE_ys978JRyq$AC`?iP3@%?(yHq5TUN;ZN6}|p;qxD;aYg;h-zRzcb;)|$1%yuxwnjeeSGxwcf-U*8^5}}PtHvFsMh-TZ>>Q|%;I+k zRvc#PNMt;+fgve^!BD3`Ld@X|{}ovYvuV@AT4L%q{@OF4r2bgC!_pYh+r8UXOj*6? z|L)7_m6@(N=C_=DJ>>R8)W&f%r7h>5T4Wl?*TWKWD)iwl)jPY2#n(kU-4jaL6J7r9 z*uQhic|ZgDf_rky?+TfjU+eu9aG_E}k^f4mcgFqd8#n9z{+<8fFB`*yr>ox{S^hLN zCvOe+{rm%^-V6+-d#`dO-WGc%E@s@#A5-%)rRKQip>1pZ?B?Cww@@_xHBZIQtlbKe z|37%CKR5jMJ?9;HnwOt2ANX@9>0qh1>`kHj`A_E6Fl>BsI%bXRoQ%1gZqpYWo+}lX zzn7I^&%LVd!*gey%M}C*d{(!2eO}mnO+sNJ z^TgcfjIB;Aj>ex)_jk#BxMHaA`n11!adGjZfWL zY5QisIB;yL@A9uze={z86Zvhx`@ng9?f2~cJjslkf}*aariIEbS23TK;Nto2`n)9h zUuxG~nl7ql6ert;sq)O}_OOb4Xx+oSfx*Z1bm7^uzrzdOlZsOgR&xR(4D)e7{^)+rNj^#gn5jt~ckQ(;@36 zI*y+ItW|#+eg_HV;+y~+>{#u+NsrI@r zEGM#$k755a5%bbX92|^)WY$KX(En*gTe~DWM4fm?Urw literal 0 HcmV?d00001 diff --git a/mods/species/neoavians/icons/clothing/spacesuit/void/medical_alt/suit.dmi b/mods/species/neoavians/icons/clothing/spacesuit/void/medical_alt/suit.dmi new file mode 100644 index 0000000000000000000000000000000000000000..c84f8e938c696d11d909c74d847243aee88a40fe GIT binary patch literal 704 zcmV;x0zdtUP)^xn_X@I z0004WQchCV=-0C=2JR&a84_w-Y6@%7{?OD!tS z%+FJ>RWQ*r;NmRLOex6#a*U0*I5Sc+(=$pSoZ^zil2jm5DX}awF;5{WKc!N)I48d( zzPL2AM2U+tC9|j)WCj;!T2W$dDu`_eG$FsFxF8>7gps+9v4M^;m$HJZp9|Px0N&#y z_Tl2x<^TWzrb$FWR9J=WR?&`wFbr!_lHSPR`2Vjxr)*k>nj+nE&B_ptO&TGRlqM!7 zCVC)FOhcZ>e8xd>1T8GQ4ERh+T5=RY%g^$_ig;DZz)Gq?fIaC!PYdX@tvR!D$?MkT z&5ZYbXZ-i|#r2|`bLlxiZbbg$z5{1w1*wdy9?xvQCRn)Y8nCLsKvcT{r@fe3pZ6lV zM?D3+?*jRUMOOIx5d|bO3CfY9yt<-HxFK|Y{MQW-2z-(n3I6%LB^-Y2N zyVvTr(;jEA69U={T>SNs#DKy%HYiNg(k5=wIAFx!91ajkSJ3pKA+>t`+(Bzc2aTF1 z7sCwDgr8EA=7xIr?>ne7rp*K2SMM@Tg4iTAvY6>0?Cu mCWrdFfJ1|q;Doc61pWYWHw@q7m0sKc0000 Date: Thu, 16 Jan 2025 14:00:03 +1100 Subject: [PATCH 007/120] Fixing erroneous medical alt suit inhands. --- .../spacesuit/void/medical_alt/suit.dmi | Bin 1475 -> 1364 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/clothing/spacesuit/void/medical_alt/suit.dmi b/icons/clothing/spacesuit/void/medical_alt/suit.dmi index 77b79193e46a4382cffdd41128f1854b493351d8..634b67420791610b2b1ca9e4d3709d4a33a3e7b2 100644 GIT binary patch delta 1127 zcmV-t1ep873)BjbBmp^*B{2|4KQL5DIfiy=z`(%#k6TKSd#`^gNklWMfLg@lyl3Y_YKuq!yz&=$2h>6<4MV^-_ zU}Xx{0t9YjX1IS*S05=xx)5E|-b5B0WeG5O&lPF4=+_u9XWpV6 z%TO7^T7ZZg^g>`JJ%EV9C=L)E8b9dn*sayQGf`yh9v1)JQIBIZ$#5gE9ZKu%7+%0Pd1E`14*R2Xp1$Rt}PupEp= zfK3ttnBUUBvk&Bca>nJKd!ezHF9CA7+%rrU$Y=LKUMN5eF!*uJ{;X$mCK+*6**mMB z1H_j56{tZ@S#GtJ2nXhc)Or{sAA$+N7X%O?w*V1W->*{{7nwzFV5Zb9cOyc8NO8|H zN>H?3=AeJ1FBWbAf?*WHgIruUImoR-V95PwQX=fr$YMunAv50B0dZv5s=mI z2k*)?x=}6^-Bh1}bzlmH#uTi{2MC`cfcQeBHRXRl8XiFB)?;V|Sfc~hdQEP#yfKN| zBWwrqZlOE_Zu0AXS|@-&d)R&sQ5i%{hdk$J57ces&X3N)vPNZu`i4&N`bI(eh7SU{ z^MeeQHA*!XWCzgjv*iMM$^{)A9UcD*Olvng8pz%AtKn((16`2ApXCD-7{mo*IIB>Y z3Cw?4{7D4ZOZtZ7>ZBc8QaW#iKr&~o1Dn%#WZ(xVXZG_)y@|=WDPF!0@BniR_>2t( z32&8i4qtZ1)wk%cfH;owe2JA3RR&VmIYBS&=Vw!B(J%Xa{Y$tD0T%nqROm<(W}qw& zh+Dv3G;EHJ`=()Ju`NGiX!J@bUzGMiU#NeBK#Tq-)TRs-am9sxlpMdjy^a1CTdWu& z`|;~z?I0pelT*jIiGFT)ZLO(@t13W1t*~sOpBv($HkH*KkzF=nbB?cI6Mf(}E^1Sx zc4d9<4!O>!GTTD`2DK?t%6e{pB~Z&9H_^XAZMr1y?T&K|Kqat&{wH=c{cgWnr`vx* z|E~E%1lo1Fj*gCwj*gCwjt*c$q2pltN}=POY}7&r@!M*vYN2Df`5p$9N&)XF-aHAl zQgFTV4i;*q05|jJ8wjYC0?t*er8;mh)Jg$vzQJ~eS}CYy^~VrUDh1E{U&3Cfm4XNB z0UaG39UUDV9UUc}KP7+G{{B<)m*Pi(Q}UN$_bK_yvGq$&bS3Q}Uy* t@09!i>^mhtgut#-^4DYMDS5{~fIr0)9;`EcHIM)R002ovPDHLkV1hx@2yg%Z delta 1239 zcmV;|1StE|3d0MKBmqv5B{3z?(9ljnIosRY{QUegEFwrhFjPr7G@-?Yc4?@Tg}}hT zFmzfPk!G)dgh@m}RCt{2S&N$TC=6}5TI?=JXY_ynC*1_9W98DSW4qrj$Fa^wfEt!K$wvjz|s^0NCDJ?3#6J{pfWC43J@}Xn^KC*n4i9fzK0{gF*_Q76Gz+v z3ZzsycJ%tNfN^n2+Ql)xeDyOizBy z#|SQeoMRvxfuA&xg)nykViE;HFmy6kKrB0!BcPZ;0_5M+zR?EQZUhtI`zU1mco!hY z<0C_JBzZI+$&(2v1{CpACH--pK`_J6RO#q2eGCwuo>xSTLVI$RU21aVl zw3Z10ijZ4?ps64CDXt6HBxj^1of}(w3ITwBjCrP25=Ac22Pu8ja0?JxMzTDTqv-}g za-Jd3g>f)sBJ4-Wq$kq@J@*qJ84HI97U9Ekaw1@8fvJ0MQv?EN!P3pX7$8>#!9?Y= z0vTYB;&5^h{#9a>;)79yyeLNoT9;4Rs{zUn0=WBSCq=qPSIUv17|I@42DzZCxL`?t z-jVPv0u)~qX;t}O6${Yd+HGh7v`0JI>m@l4@`@94x3DJ=PK(Sv;3mJGr)2^ZXfNvz zA&QGA&4Ks%Xo0ehF!)s;OnVepm_N{=zdlhw{=g>!VepF#racNJ69fZ5_jk<%@RkW0 z8X6k@FJQIP?9-s!Jv0VOegqvUF*6B|=H z$&r9zd+h@r(s#Q9!SdrSN6WlKGi?(YJF$NukWwXb-qS_0Mq+a ze`J3q0_&V`qLt3OBB5vkTXm#7V2+=(5_^9>pOJcn{T(t3weI4g1um{)Ml%c|tsq49 z=Oy;BFI`S)S9kd{S>R92jYJ@0fpzSoBD#Ekk7L?(9IdzGSRKwoj-O1rj(xy|E~ji) zi`vHp6NWlpPOygk9b=d4YEQ0za|;_8O1a}2_CLsX#Tml40v>AsIRY!#-{Fa_bN$6S z-3s=P-CrV5uhTU&G&D3cG&D3c1WakKd!tnFp8iuzI%lPVcM2EJ!cnRoY6WiAxRri% zfb(9@3mw>qgihNK@SXEoYk!~rQzK^2+Ykt)0zJ?FV`H$u$6ev>N(J_Ru5lc{g9TRC zkX~nSD-~SayfIkd@^J!%Qo%Sb)=qv6*;0XBU%hyrK(16kjawmGDtNIV(9qD((9qD( z(C~;U^W8Gnoa@hJzFXp&`D(x2Bknz7=Ibf<+{X!1lKVC4l`qMEoxr+R{GUTM^WBy~ zF7w?M&%Gr70G@kE{s{si&%Gr7eLVS+yy3rqe*m{YH^8@{cNG8t002ovPDHLkV1lfb BJ{$l5 From 6b677118bf79c008521f29833584ce84255feebc Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 17 Jan 2025 00:36:05 -0500 Subject: [PATCH 008/120] Fix accidentally-removed barren turfs --- .../random_exoplanet/planet_types/barren.dm | 6 ++--- code/modules/multiz/level_data.dm | 3 ++- code/modules/random_map/automata/caves.dm | 2 +- .../lost_supply_base/lost_supply_base.dmm | 2 +- maps/away/mining/mining-asteroid.dmm | 16 +++++++------- maps/away/mining/mining-orb.dmm | 8 +++---- maps/away/mining/mining_areas.dm | 2 +- maps/away/smugglers/smugglers.dmm | 22 +++++++++---------- .../away_sites_testing_define.dm | 4 ++-- maps/planets/test_planet/neutralia-2.dmm | 4 ++-- maps/planets/test_planet/neutralia-3.dmm | 8 +++---- maps/planets/test_planet/test_planet.dm | 4 ++-- 12 files changed, 41 insertions(+), 40 deletions(-) diff --git a/code/modules/maps/template_types/random_exoplanet/planet_types/barren.dm b/code/modules/maps/template_types/random_exoplanet/planet_types/barren.dm index 7ef37a05e79a..27a86377dc88 100644 --- a/code/modules/maps/template_types/random_exoplanet/planet_types/barren.dm +++ b/code/modules/maps/template_types/random_exoplanet/planet_types/barren.dm @@ -13,7 +13,7 @@ /datum/level_data/planetoid/exoplanet/barren base_area = /area/exoplanet/barren - base_turf = /turf/floor + base_turf = /turf/floor/barren exterior_atmosphere = null //Generate me exterior_atmos_temp = null //Generate me level_generators = list( @@ -99,7 +99,7 @@ ///Generator for fauna and flora spawners for the surface of the barren exoplanet /datum/random_map/noise/exoplanet/barren descriptor = "barren exoplanet" - land_type = /turf/floor + land_type = /turf/floor/barren flora_prob = 0.1 large_flora_prob = 0 fauna_prob = 0 @@ -111,7 +111,7 @@ /area/exoplanet/barren name = "\improper Planetary surface" - base_turf = /turf/floor + base_turf = /turf/floor/barren is_outside = OUTSIDE_YES ambience = list( 'sound/effects/wind/wind_2_1.ogg', diff --git a/code/modules/multiz/level_data.dm b/code/modules/multiz/level_data.dm index 69ee279edba2..1de07a48dc74 100644 --- a/code/modules/multiz/level_data.dm +++ b/code/modules/multiz/level_data.dm @@ -736,7 +736,8 @@ INITIALIZE_IMMEDIATE(/obj/abstract/level_data_spawner) return ..() /datum/level_data/mining_level/asteroid - base_turf = /turf/floor + base_turf = /turf/floor/barren + filler_turf = /turf/space level_generators = list( /datum/random_map/automata/cave_system, /datum/random_map/noise/ore diff --git a/code/modules/random_map/automata/caves.dm b/code/modules/random_map/automata/caves.dm index d12f5a79204d..91044cd99d54 100644 --- a/code/modules/random_map/automata/caves.dm +++ b/code/modules/random_map/automata/caves.dm @@ -2,7 +2,7 @@ iterations = 5 descriptor = "moon caves" wall_type = /turf/wall/natural - floor_type = /turf/floor + floor_type = /turf/floor/barren target_turf_type = /turf/unsimulated/mask var/sparse_mineral_turf = /turf/wall/natural/random diff --git a/maps/away/lost_supply_base/lost_supply_base.dmm b/maps/away/lost_supply_base/lost_supply_base.dmm index 94c58cd1b3fb..5acfba27ea2a 100644 --- a/maps/away/lost_supply_base/lost_supply_base.dmm +++ b/maps/away/lost_supply_base/lost_supply_base.dmm @@ -1982,7 +1982,7 @@ /turf/unsimulated/mask, /area/mine/unexplored) "gu" = ( -/turf/floor, +/turf/floor/barren, /area/mine/explored) "ib" = ( /obj/structure/hygiene/sink{ diff --git a/maps/away/mining/mining-asteroid.dmm b/maps/away/mining/mining-asteroid.dmm index 63713ba44342..89a0612365c1 100644 --- a/maps/away/mining/mining-asteroid.dmm +++ b/maps/away/mining/mining-asteroid.dmm @@ -6,14 +6,14 @@ /turf/unsimulated/mask, /area/mine/unexplored) "af" = ( -/turf/floor, +/turf/floor/barren, /area/mine/explored) "aj" = ( /turf/wall/r_wall, /area/djstation) "ak" = ( /obj/random/junk, -/turf/floor, +/turf/floor/barren, /area/mine/explored) "al" = ( /obj/random/trash, @@ -204,15 +204,15 @@ /area/djstation) "be" = ( /obj/random/maintenance, -/turf/floor, +/turf/floor/barren, /area/mine/explored) "bf" = ( /obj/effect/overmap/visitable/sector/cluster, -/turf/floor, +/turf/floor/barren, /area/mine/explored) "cb" = ( /obj/effect/shuttle_landmark/cluster/nav5, -/turf/floor, +/turf/floor/barren, /area/mine/explored) "db" = ( /obj/effect/shuttle_landmark/cluster/nav6, @@ -236,7 +236,7 @@ /area/space) "ib" = ( /obj/effect/shuttle_landmark/cluster/nav7, -/turf/floor, +/turf/floor/barren, /area/mine/explored) "jb" = ( /obj/machinery/button/access/exterior{ @@ -245,7 +245,7 @@ pixel_y = -24; dir = 1 }, -/turf/floor, +/turf/floor/barren, /area/mine/explored) "kb" = ( /obj/machinery/door/airlock/external{ @@ -345,7 +345,7 @@ req_access = null; dir = 4 }, -/turf/floor, +/turf/floor/barren, /area/mine/explored) "wb" = ( /obj/machinery/door/airlock/external{ diff --git a/maps/away/mining/mining-orb.dmm b/maps/away/mining/mining-orb.dmm index 0f03154da5cf..46fc8c21fb46 100644 --- a/maps/away/mining/mining-orb.dmm +++ b/maps/away/mining/mining-orb.dmm @@ -14,10 +14,10 @@ /turf/unsimulated/mask, /area/mine/unexplored) "ae" = ( -/turf/floor, +/turf/floor/barren, /area/mine/explored) "af" = ( -/turf/floor, +/turf/floor/barren, /area/mine/unexplored) "ag" = ( /turf/wall/natural/random/high_chance, @@ -250,7 +250,7 @@ /area/mine/explored) "st" = ( /obj/effect/shuttle_landmark/orb/nav7, -/turf/floor, +/turf/floor/barren, /area/mine/explored) "vc" = ( /obj/effect/floor_decal/spline/fancy/wood{ @@ -277,7 +277,7 @@ /obj/effect/floor_decal/spline/fancy/wood/corner{ dir = 4 }, -/turf/floor, +/turf/floor/barren, /area/mine/explored) "Aj" = ( /obj/effect/floor_decal/spline/fancy/wood/corner, diff --git a/maps/away/mining/mining_areas.dm b/maps/away/mining/mining_areas.dm index 94d5e15d9781..3dd6da725299 100644 --- a/maps/away/mining/mining_areas.dm +++ b/maps/away/mining/mining_areas.dm @@ -3,7 +3,7 @@ icon_state = "mining" ambience = list('sound/ambience/ambimine.ogg', 'sound/ambience/song_game.ogg') sound_env = ASTEROID - base_turf = /turf/floor + base_turf = /turf/floor/barren area_flags = AREA_FLAG_IS_BACKGROUND | AREA_FLAG_HIDE_FROM_HOLOMAP /area/mine/explored diff --git a/maps/away/smugglers/smugglers.dmm b/maps/away/smugglers/smugglers.dmm index 12cf197b3eec..f58d8c8b66a2 100644 --- a/maps/away/smugglers/smugglers.dmm +++ b/maps/away/smugglers/smugglers.dmm @@ -3,7 +3,7 @@ /turf/space, /area/space) "ab" = ( -/turf/floor, +/turf/floor/barren, /area/mine/explored) "ac" = ( /turf/unsimulated/mask, @@ -24,7 +24,7 @@ /turf/floor, /area/smugglers/base) "ah" = ( -/turf/floor, +/turf/floor/barren, /area/space) "aj" = ( /obj/item/ammo_casing/pistol/magnum{ @@ -37,11 +37,11 @@ pixel_y = -5 }, /obj/effect/decal/cleanable/blood, -/turf/floor, +/turf/floor/barren, /area/mine/explored) "ak" = ( /obj/effect/decal/cleanable/blood, -/turf/floor, +/turf/floor/barren, /area/mine/explored) "al" = ( /obj/effect/wallframe_spawn/reinforced, @@ -98,7 +98,7 @@ pixel_y = 7 }, /obj/item/flashlight/flare/glowstick/yellow, -/turf/floor, +/turf/floor/barren, /area/mine/explored) "av" = ( /obj/effect/decal/cleanable/blood/drip, @@ -281,11 +281,11 @@ pixel_x = -25; pixel_y = 25 }, -/turf/floor, +/turf/floor/barren, /area/mine/explored) "aM" = ( /obj/random/trash, -/turf/floor, +/turf/floor/barren, /area/mine/explored) "aN" = ( /obj/machinery/light/small{ @@ -432,7 +432,7 @@ /obj/item/tool/xeno/hand{ pixel_x = -15 }, -/turf/floor, +/turf/floor/barren, /area/mine/explored) "bh" = ( /obj/effect/floor_decal/industrial/warning{ @@ -476,7 +476,7 @@ /area/smugglers/base) "bn" = ( /obj/structure/boulder, -/turf/floor, +/turf/floor/barren, /area/mine/explored) "bo" = ( /obj/item/stack/material/ore/silver, @@ -484,7 +484,7 @@ pixel_x = 10; pixel_y = -5 }, -/turf/floor, +/turf/floor/barren, /area/mine/explored) "bp" = ( /obj/structure/cable{ @@ -946,7 +946,7 @@ "db" = ( /obj/effect/decal/cleanable/blood, /obj/abstract/landmark/corpse/doctor, -/turf/floor, +/turf/floor/barren, /area/mine/explored) "eb" = ( /obj/machinery/light/small{ diff --git a/maps/away_sites_testing/away_sites_testing_define.dm b/maps/away_sites_testing/away_sites_testing_define.dm index 8b605741a841..fd1868d5c2ad 100644 --- a/maps/away_sites_testing/away_sites_testing_define.dm +++ b/maps/away_sites_testing/away_sites_testing_define.dm @@ -20,10 +20,10 @@ var/list/unsorted_sites = list_values(SSmapping.get_templates_by_category(MAP_TEMPLATE_CATEGORY_AWAYSITE)) var/list/sorted_sites = sortTim(unsorted_sites, /proc/cmp_sort_templates_tallest_to_shortest) for (var/datum/map_template/A in sorted_sites) - A.load_new_z(centered = FALSE) + A.load_new_z() testing("Spawning [A] in [english_list(SSmapping.get_connected_levels(world.maxz))]") if(A.template_flags & TEMPLATE_FLAG_TEST_DUPLICATES) - A.load_new_z(centered = FALSE) + A.load_new_z() testing("Spawning [A] in [english_list(SSmapping.get_connected_levels(world.maxz))]") /proc/cmp_sort_templates_tallest_to_shortest(var/datum/map_template/a, var/datum/map_template/b) diff --git a/maps/planets/test_planet/neutralia-2.dmm b/maps/planets/test_planet/neutralia-2.dmm index 8b5e82e76e8a..cc84b991ea84 100644 --- a/maps/planets/test_planet/neutralia-2.dmm +++ b/maps/planets/test_planet/neutralia-2.dmm @@ -3,11 +3,11 @@ /turf/unsimulated/mineral, /area/exoplanet/underground/neutralia) "b" = ( -/turf/floor, +/turf/floor/barren, /area/exoplanet/underground/neutralia) "c" = ( /obj/abstract/level_data_spawner/neutralia/underground, -/turf/floor, +/turf/floor/barren, /area/exoplanet/underground/neutralia) (1,1,1) = {" diff --git a/maps/planets/test_planet/neutralia-3.dmm b/maps/planets/test_planet/neutralia-3.dmm index 768772a0f91a..f7d1ff768ee3 100644 --- a/maps/planets/test_planet/neutralia-3.dmm +++ b/maps/planets/test_planet/neutralia-3.dmm @@ -1,6 +1,6 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "a" = ( -/turf/floor, +/turf/floor/barren, /area/exoplanet/neutralia) "b" = ( /turf/unsimulated/mineral, @@ -17,15 +17,15 @@ /area/exoplanet/neutralia) "j" = ( /obj/abstract/landmark/exoplanet_spawn/large_plant, -/turf/floor, +/turf/floor/barren, /area/exoplanet/neutralia) "o" = ( /obj/abstract/landmark/exoplanet_spawn/animal, -/turf/floor, +/turf/floor/barren, /area/exoplanet/neutralia) "x" = ( /obj/abstract/landmark/exoplanet_spawn/plant, -/turf/floor, +/turf/floor/barren, /area/exoplanet/neutralia) (1,1,1) = {" diff --git a/maps/planets/test_planet/test_planet.dm b/maps/planets/test_planet/test_planet.dm index 159722fde19c..83c42703e654 100644 --- a/maps/planets/test_planet/test_planet.dm +++ b/maps/planets/test_planet/test_planet.dm @@ -131,14 +131,14 @@ name = "neutralia surface" level_id = NEUTRALIA_SURFACE_LEVEL_ID base_area = /area/exoplanet/neutralia - base_turf = /turf/floor + base_turf = /turf/floor/barren border_filler = /turf/unsimulated/dark_filler /datum/level_data/planetoid/neutralia/underground name = "neutralia underground" level_id = "neutralia_underground" base_area = /area/exoplanet/underground/neutralia - base_turf = /turf/floor + base_turf = /turf/floor/barren border_filler = /turf/unsimulated/mineral /datum/level_data/planetoid/neutralia/underground/bottom From 72787c032214d15ebdae1b69bfe3a092ee2f4d26 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 17 Jan 2025 00:40:48 -0500 Subject: [PATCH 009/120] Fix space turfs on ERT base --- maps/antag_spawn/ert/ert_base.dmm | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/maps/antag_spawn/ert/ert_base.dmm b/maps/antag_spawn/ert/ert_base.dmm index dd760f39c1a7..e5f51da4973a 100644 --- a/maps/antag_spawn/ert/ert_base.dmm +++ b/maps/antag_spawn/ert/ert_base.dmm @@ -1588,10 +1588,6 @@ /obj/machinery/vending/medical, /turf/unsimulated/wall, /area/map_template/rescue_base/base) -"dj" = ( -/obj/effect/wingrille_spawn/reinforced/crescent, -/turf/space, -/area/map_template/rescue_base/base) "dk" = ( /obj/machinery/door/airlock/centcom{ name = "EVA" @@ -4917,7 +4913,7 @@ ar cH ar cS -dj +bg ao ao bg @@ -4982,7 +4978,7 @@ ar cI ar cT -dj +bg ao ao bg @@ -5047,7 +5043,7 @@ ar ar ar cU -dj +bg ao ao bg @@ -5112,7 +5108,7 @@ cy cJ cO cV -dj +bg ao ao ad From 785a2506e495543b35ed04e554d2989f15f86241 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 17 Jan 2025 01:17:28 -0500 Subject: [PATCH 010/120] Fix starlight not working --- code/modules/multiz/level_data.dm | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/code/modules/multiz/level_data.dm b/code/modules/multiz/level_data.dm index 1de07a48dc74..60ee0a0dfb6e 100644 --- a/code/modules/multiz/level_data.dm +++ b/code/modules/multiz/level_data.dm @@ -181,7 +181,6 @@ initialize_level_id() SSmapping.register_level_data(src) - setup_ambient() setup_exterior_atmosphere() if(SSmapping.initialized && !defer_level_setup) setup_level_data() @@ -233,6 +232,7 @@ if(!skip_gen) generate_level() after_generate_level() + setup_ambient() // Determine our relative positioning. // First find an appropriate origin point. @@ -720,6 +720,12 @@ INITIALIZE_IMMEDIATE(/obj/abstract/level_data_spawner) level_flags = (ZLEVEL_CONTACT|ZLEVEL_PLAYER|ZLEVEL_SEALED) filler_turf = /turf/unsimulated/dark_filler +// Used in order to avoid making the level too large. Only works if loaded prior to SSmapping init... it's unclear if this really does much. +/datum/level_data/unit_test/after_template_load(var/datum/map_template/template) + . = ..() + level_max_width ||= template.width + level_max_height ||= template.height + /datum/level_data/overmap name = "Sensor Display" level_flags = ZLEVEL_SEALED @@ -833,9 +839,6 @@ INITIALIZE_IMMEDIATE(/obj/abstract/level_data_spawner) /datum/level_data/proc/load_subtemplate(turf/central_turf, datum/map_template/template) if(!template) return FALSE - for(var/turf/T in template.get_affected_turfs(central_turf, TRUE)) - for(var/mob/living/simple_animal/monster in T) - qdel(monster) template.load(central_turf, centered = TRUE) return TRUE From 13b00e01fea2ef0c84e73c317b5da3dd93a49e6d Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 17 Jan 2025 02:12:10 -0500 Subject: [PATCH 011/120] Fix ore deposits spreading into ramps --- code/game/turfs/walls/wall_natural.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/turfs/walls/wall_natural.dm b/code/game/turfs/walls/wall_natural.dm index e878e59747e5..552b239eb514 100644 --- a/code/game/turfs/walls/wall_natural.dm +++ b/code/game/turfs/walls/wall_natural.dm @@ -167,7 +167,7 @@ if(!prob(reinf_material.ore_spread_chance)) continue var/turf/wall/natural/target_turf = get_step_resolving_mimic(src, trydir) - if(!istype(target_turf) || !isnull(target_turf.reinf_material)) + if(!istype(target_turf) || !isnull(target_turf.reinf_material) || target_turf.ramp_slope_direction) continue target_turf.set_turf_materials(target_turf.material, reinf_material) target_turf.spread_deposit() From 7f10b4e7d31e68d5bbd78c3f346b9cebaca061bc Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 17 Jan 2025 01:47:57 -0500 Subject: [PATCH 012/120] Fix lighting overlays being built multiple times per turf --- code/controllers/subsystems/lighting.dm | 27 +++++-------------- code/game/turfs/turf_changing.dm | 2 +- code/modules/lighting/lighting_turf.dm | 3 +-- code/modules/maps/_map_template.dm | 4 --- code/modules/maps/reader.dm | 2 -- .../random_exoplanet/random_planet.dm | 6 ++--- 6 files changed, 11 insertions(+), 33 deletions(-) diff --git a/code/controllers/subsystems/lighting.dm b/code/controllers/subsystems/lighting.dm index a7583ae1b2ff..61f8b083a33b 100644 --- a/code/controllers/subsystems/lighting.dm +++ b/code/controllers/subsystems/lighting.dm @@ -54,7 +54,12 @@ SUBSYSTEM_DEF(lighting) // Generate overlays. for (var/zlevel = 1 to world.maxz) - overlaycount += InitializeZlev(zlevel) + var/datum/level_data/level = SSmapping.levels_by_z[zlevel] + for (var/turf/tile as anything in block(1, 1, zlevel, level.level_max_width, level.level_max_height)) // include TRANSITIONEDGE turfs + if (TURF_IS_DYNAMICALLY_LIT_UNSAFE(tile)) + tile.lighting_build_overlay() + overlaycount++ + CHECK_TICK admin_notice(SPAN_DANGER("Created [overlaycount] lighting overlays in [(REALTIMEOFDAY - starttime)/10] seconds."), R_DEBUG) @@ -71,26 +76,6 @@ SUBSYSTEM_DEF(lighting) ..() -/datum/controller/subsystem/lighting/proc/InitializeZlev(zlev) - for (var/thing in Z_ALL_TURFS(zlev)) - var/turf/T = thing - if (TURF_IS_DYNAMICALLY_LIT_UNSAFE(T) && !T.lighting_overlay) // Can't assume that one hasn't already been created on bay/neb. - new /atom/movable/lighting_overlay(T) - . += 1 - if (T.ambient_light) - T.generate_missing_corners() // Forcibly generate corners. - - CHECK_TICK - -// It's safe to pass a list of non-turfs to this list - it'll only check turfs. -/datum/controller/subsystem/lighting/proc/InitializeTurfs(list/targets) - for (var/turf/T in (targets || world)) - if (TURF_IS_DYNAMICALLY_LIT_UNSAFE(T)) - T.lighting_build_overlay() - - // If this isn't here, BYOND will set-background us. - CHECK_TICK - /datum/controller/subsystem/lighting/fire(resumed = FALSE, no_mc_tick = FALSE) if (!resumed) processed_lights = 0 diff --git a/code/game/turfs/turf_changing.dm b/code/game/turfs/turf_changing.dm index ce53c4785664..bbac5a1f1e0c 100644 --- a/code/game/turfs/turf_changing.dm +++ b/code/game/turfs/turf_changing.dm @@ -140,7 +140,7 @@ if ((old_opacity != opacity) || (tidlu != old_dynamic_lighting) || force_lighting_update) reconsider_lights() - if (tidlu != old_dynamic_lighting) + if (tidlu != old_dynamic_lighting && SSlighting.initialized) // don't fuck with lighting before lighting flush if (tidlu) lighting_build_overlay() else diff --git a/code/modules/lighting/lighting_turf.dm b/code/modules/lighting/lighting_turf.dm index 17e233358079..c308064f8463 100644 --- a/code/modules/lighting/lighting_turf.dm +++ b/code/modules/lighting/lighting_turf.dm @@ -126,8 +126,7 @@ // Builds a lighting overlay for us, but only if our area is dynamic. /turf/proc/lighting_build_overlay(now = FALSE) if (lighting_overlay) - return // shrug - // CRASH("Attempted to create lighting_overlay on tile that already had one.") + CRASH("Attempted to create lighting_overlay on tile that already had one.") if (TURF_IS_DYNAMICALLY_LIT_UNSAFE(src)) if (!lighting_corners_initialised || !corners) diff --git a/code/modules/maps/_map_template.dm b/code/modules/maps/_map_template.dm index a48c199cccca..c5ae24dc655f 100644 --- a/code/modules/maps/_map_template.dm +++ b/code/modules/maps/_map_template.dm @@ -185,8 +185,6 @@ for(var/z_index = bounds[MAP_MINZ] to bounds[MAP_MAXZ]) var/datum/level_data/level = SSmapping.levels_by_z[z_index] level.after_template_load(src) - if(SSlighting.initialized) - SSlighting.InitializeZlev(z_index) Master.StopLoadingMap() log_game("Z-level [name] loaded at [x],[y],[world.maxz]") loaded++ @@ -225,8 +223,6 @@ init_atoms(atoms_to_initialise) init_shuttles(shuttle_state, map_hash, initialized_areas_by_type) after_load() - if (SSlighting.initialized) - SSlighting.InitializeTurfs(atoms_to_initialise) // Hopefully no turfs get placed on new coords by SSatoms. Master.StopLoadingMap() log_game("[name] loaded at at [T.x],[T.y],[T.z]") diff --git a/code/modules/maps/reader.dm b/code/modules/maps/reader.dm index efc444d7b0a1..bd097470945d 100644 --- a/code/modules/maps/reader.dm +++ b/code/modules/maps/reader.dm @@ -185,8 +185,6 @@ var/global/dmm_suite/preloader/_preloader = new maxx = max(maxx, xcrd) ++xcrd --ycrd - if (zexpansion && SSlighting.initialized) - SSlighting.InitializeZlev(zcrd) bounds[MAP_MAXX] = clamp(max(bounds[MAP_MAXX], cropMap ? min(maxx, world.maxx) : maxx), x_lower, x_upper) diff --git a/code/modules/maps/template_types/random_exoplanet/random_planet.dm b/code/modules/maps/template_types/random_exoplanet/random_planet.dm index cc846e98ae22..6a8ea018c2af 100644 --- a/code/modules/maps/template_types/random_exoplanet/random_planet.dm +++ b/code/modules/maps/template_types/random_exoplanet/random_planet.dm @@ -203,9 +203,9 @@ //Run the finishing touch on all loaded levels for(var/datum/level_data/LD in new_level_data) - LD.after_template_load(src) - if(SSlighting.initialized) - SSlighting.InitializeZlev(LD.level_z) + //This is done in parent if we have mappaths, so skip it unless we don't have any + if(!length(mappaths)) + LD.after_template_load(src) log_game("Z-level '[LD.name]'(planetoid:'[name]') loaded at [LD.level_z]") loaded++ return WORLD_CENTER_TURF(world.maxz) From e1a1d93d0594d26f21e6712a11beb28b1b121aec Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 17 Jan 2025 01:53:26 -0500 Subject: [PATCH 013/120] Revert to cheaper ambient light corner generation code --- code/modules/lighting/lighting_turf.dm | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/code/modules/lighting/lighting_turf.dm b/code/modules/lighting/lighting_turf.dm index c308064f8463..53e59fa5b9b0 100644 --- a/code/modules/lighting/lighting_turf.dm +++ b/code/modules/lighting/lighting_turf.dm @@ -65,27 +65,17 @@ return // Unlit turfs will have corners if they have a lit neighbor -- don't generate corners for them, but do update them if they're there. - // if (!corners) - // var/force_build_corners = FALSE - // for (var/turf/T as anything in RANGE_TURFS(src, 1)) - // if (TURF_IS_DYNAMICALLY_LIT_UNSAFE(T)) - // force_build_corners = TRUE - // break - - // if (force_build_corners || TURF_IS_DYNAMICALLY_LIT_UNSAFE(src)) - // generate_missing_corners() - // else - // return - - // still inefficient :( - if(!corners || !lighting_corners_initialised) - /* Commented out pending working out why this doesn't work properly on Neb. - if(TURF_IS_DYNAMICALLY_LIT_UNSAFE(src)) + if (!corners) + var/force_build_corners = FALSE + for (var/turf/T as anything in RANGE_TURFS(src, 1)) + if (TURF_IS_DYNAMICALLY_LIT_UNSAFE(T)) + force_build_corners = TRUE + break + + if (force_build_corners || TURF_IS_DYNAMICALLY_LIT_UNSAFE(src)) generate_missing_corners() else return - */ - generate_missing_corners() // This list can contain nulls on things like space turfs -- they only have their neighbors' corners. for (var/datum/lighting_corner/C in corners) From 62472e1dcb69c87b6d83274735269fb4416ffaf1 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 17 Jan 2025 01:55:08 -0500 Subject: [PATCH 014/120] Fix space turfs having starlight blocked by a roof --- code/controllers/subsystems/ambience.dm | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/code/controllers/subsystems/ambience.dm b/code/controllers/subsystems/ambience.dm index 757f846c6402..8f4b462e2050 100644 --- a/code/controllers/subsystems/ambience.dm +++ b/code/controllers/subsystems/ambience.dm @@ -33,6 +33,14 @@ SUBSYSTEM_DEF(ambience) /// Whether this turf has been queued for an ambient lighting update. var/ambience_queued = FALSE +/turf/proc/shows_outdoor_ambience() + return is_outside() + +// Starlight can't be blocked by stuff above a space turf. +// TODO: decide if open sky deserves the same treatment +/turf/space/shows_outdoor_ambience() + return TRUE + /turf/proc/update_ambient_light_from_z_or_area() // If we're not outside, we don't show ambient light. @@ -40,7 +48,7 @@ SUBSYSTEM_DEF(ambience) var/ambient_light_modifier // If we're indoors because of our area, OR we're outdoors and not exposed to the weather, get interior ambience. - var/outsideness = is_outside() + var/outsideness = shows_outdoor_ambience() if((!outsideness && is_outside == OUTSIDE_AREA) || (outsideness && get_weather_exposure() != WEATHER_EXPOSED)) var/area/A = get_area(src) if(isnull(A?.interior_ambient_light_modifier)) From bbcf32d735b1b5bc7d73b1c7dbb686f570c7c1c1 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 17 Jan 2025 17:27:05 -0500 Subject: [PATCH 015/120] Fix CI example config --- test/run-test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/run-test.sh b/test/run-test.sh index a9907ae692c1..e4bac59b824f 100755 --- a/test/run-test.sh +++ b/test/run-test.sh @@ -222,8 +222,8 @@ function run_byond_tests { then exit 1 else msg "configured map is '$MAP_PATH'" fi - cp config/example/* config/ - cp data/secrets/example/* data/secrets/ + cp -r config/example/* config/ + cp -r data/secrets/example/* data/secrets/ if [[ "$CI" == "true" ]]; then msg "installing BYOND" ./install-byond.sh || exit 1 From 4108ae91a012f089ecb1563bd6d3c0b248839511 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 10 Jan 2025 14:04:48 -0500 Subject: [PATCH 016/120] Update create & destroy UT to latest TG --- ...mpile_options.dm => ___compile_options.dm} | 4 -- code/__defines/qdel.dm | 8 ++- code/controllers/subsystems/garbage.dm | 13 ++-- code/modules/mob/living/life.dm | 1 - .../reagents/reagent_containers/food.dm | 2 +- code/unit_tests/del_the_world.dm | 70 +++++++++---------- code/world.dm | 5 +- nebula.dme | 2 +- 8 files changed, 52 insertions(+), 53 deletions(-) rename code/{__defines/_compile_options.dm => ___compile_options.dm} (61%) diff --git a/code/__defines/_compile_options.dm b/code/___compile_options.dm similarity index 61% rename from code/__defines/_compile_options.dm rename to code/___compile_options.dm index 0c60ba0a5ddb..a4f54bc99b94 100644 --- a/code/__defines/_compile_options.dm +++ b/code/___compile_options.dm @@ -1,7 +1,3 @@ -// The default value for all uses of set background. Set background can cause gradual lag and is recommended you only turn this on if necessary. -// 1 will enable set background. 0 will disable set background. -#define BACKGROUND_ENABLED 0 - // If REFTRACK_IN_CI is defined, the reftracker will run in CI. #define REFTRACK_IN_CI #if defined(REFTRACK_IN_CI) && defined(UNIT_TEST) && !defined(SPACEMAN_DMM) diff --git a/code/__defines/qdel.dm b/code/__defines/qdel.dm index fa9cf0a8debe..afafb9c6a132 100644 --- a/code/__defines/qdel.dm +++ b/code/__defines/qdel.dm @@ -21,8 +21,12 @@ #define GC_QUEUE_ITEM_GCD_DESTROYED 3 //! Item's gc_destroyed var value. Used to detect ref reuse. #define GC_QUEUE_ITEM_INDEX_COUNT 3 //! Number of item indexes, used for allocating the nested lists. Don't forget to increase this if you add a new queue item index -#define GC_QUEUED_FOR_HARD_DEL -1 -#define GC_CURRENTLY_BEING_QDELETED -2 +// Defines for the time an item has to get its reference cleaned before it fails the queue and moves to the next. +#define GC_FILTER_QUEUE (1 SECONDS) +#define GC_CHECK_QUEUE (5 MINUTES) +#define GC_DEL_QUEUE (10 SECONDS) + +#define GC_CURRENTLY_BEING_QDELETED -1 #define QDELING(X) (X.gc_destroyed) #define QDELETED(X) (isnull(X) || QDELING(X)) diff --git a/code/controllers/subsystems/garbage.dm b/code/controllers/subsystems/garbage.dm index 18f925703957..9265525bd7fe 100644 --- a/code/controllers/subsystems/garbage.dm +++ b/code/controllers/subsystems/garbage.dm @@ -17,7 +17,7 @@ SUBSYSTEM_DEF(garbage) runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY init_order = SS_INIT_GARBAGE - var/list/collection_timeout = list(0, 3 MINUTES, 10 SECONDS) // deciseconds to wait before moving something up in the queue to the next level + var/list/collection_timeout = list(GC_FILTER_QUEUE, GC_CHECK_QUEUE, GC_DEL_QUEUE) // deciseconds to wait before moving something up in the queue to the next level //Stat tracking var/delslasttick = 0 // number of del()'s we've done this tick @@ -173,10 +173,10 @@ SUBSYSTEM_DEF(garbage) var/remaining_refs = refcount(D) - REFS_WE_EXPECT var/refID = ref(D) if(reference_find_on_fail[refID]) - D.find_references(remaining_refs) + INVOKE_ASYNC(D, TYPE_PROC_REF(/datum, find_references), remaining_refs) #ifdef GC_FAILURE_HARD_LOOKUP else - D.find_references(remaining_refs) + INVOKE_ASYNC(D, TYPE_PROC_REF(/datum, find_references), remaining_refs) #endif reference_find_on_fail -= refID #endif @@ -204,8 +204,6 @@ SUBSYSTEM_DEF(garbage) /datum/controller/subsystem/garbage/proc/Queue(datum/D, level = GC_QUEUE_FILTER) if (isnull(D)) return - if (D.gc_destroyed == GC_QUEUED_FOR_HARD_DEL) - level = GC_QUEUE_HARDDELETE if (level > GC_QUEUE_COUNT) HardDelete(D) return @@ -474,6 +472,7 @@ SUBSYSTEM_DEF(garbage) if(usr && usr.client && !usr.client.running_find_references) return if (!recursive_limit) + testing("Recursion limit reached. [container_name]") return if(references_to_clear == 0) return @@ -541,6 +540,10 @@ SUBSYSTEM_DEF(garbage) else if (I && !isnum(I) && normal) if(X[I] == src) testing("Found [src.type] \ref[src] in list [container_name]\[[I]\]") + references_to_clear -= 1 + if(references_to_clear == 0) + testing("All references to [type] \ref[src] found, exiting.") + return else if(islist(X[I])) DoSearchVar(X[I], "[container_name]\[[I]\]", recursive_limit-1) diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 38f5705f5778..05d2002770b4 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -1,6 +1,5 @@ /mob/living/Life() set invisibility = FALSE - set background = BACKGROUND_ENABLED ..() diff --git a/code/modules/reagents/reagent_containers/food.dm b/code/modules/reagents/reagent_containers/food.dm index c28d70364f65..55309ff3d2cc 100644 --- a/code/modules/reagents/reagent_containers/food.dm +++ b/code/modules/reagents/reagent_containers/food.dm @@ -142,7 +142,7 @@ /obj/item/food/Destroy() QDEL_NULL(plate) trash = null - if(contents) + if(length(contents)) for(var/atom/movable/something in contents) something.dropInto(loc) . = ..() diff --git a/code/unit_tests/del_the_world.dm b/code/unit_tests/del_the_world.dm index 93591ed1d01e..411ef21b8d33 100644 --- a/code/unit_tests/del_the_world.dm +++ b/code/unit_tests/del_the_world.dm @@ -39,58 +39,52 @@ continue qdel(to_del, force = TRUE) // I hate borg stacks I hate borg stacks AM = null // this counts as a reference to the last item if we don't explicitly clear it?? + del_candidates.Cut() // this also?? // Check for hanging references. SSticker.delay_end = TRUE // Don't end the round while we wait! - // No harddels during this test. - SSgarbage.collection_timeout[GC_QUEUE_HARDDELETE] = 6 HOURS // github CI timeout length + // Drastically lower the amount of time it takes to GC, since we don't have clients that can hold it up. + SSgarbage.collection_timeout[GC_QUEUE_CHECK] = 10 SECONDS cached_contents.Cut() + var/list/queues_we_care_about = list() + // All of em, I want hard deletes too, since we rely on the debug info from them + for(var/i in 1 to GC_QUEUE_HARDDELETE) + queues_we_care_about += i + + //Now that we've qdel'd everything, let's sleep until the gc has processed all the shit we care about + // + 2 seconds to ensure that everything gets in the queue. + var/time_needed = 2 SECONDS + for(var/index in queues_we_care_about) + time_needed += SSgarbage.collection_timeout[index] + // track start time so we know anything deleted after this point isn't ours var/start_time = world.time - // spin until the first item in the filter queue is older than start_time - var/filter_queue_finished = FALSE - var/list/filter_queue = SSgarbage.queues[GC_QUEUE_FILTER] - while(!filter_queue_finished) - if(!length(filter_queue)) - filter_queue_finished = TRUE - break - var/list/oldest_packet = filter_queue[1] - //Pull out the time we inserted at - var/qdel_time = oldest_packet[GC_QUEUE_ITEM_GCD_DESTROYED] - if(qdel_time > start_time) // Everything is in the check queue now! - filter_queue_finished = TRUE - break - if(world.time > start_time + 2 MINUTES) - fail("Something has gone horribly wrong, the filter queue has been processing for well over 2 minutes. What the hell did you do??") - break - // We want to fire every time. - SSgarbage.next_fire = 1 - sleep(2 SECONDS) - // We need to check the check queue now. - start_time = world.time - // sleep until SSgarbage has run through the queue - var/time_needed = SSgarbage.collection_timeout[GC_QUEUE_CHECK] - sleep(time_needed) - // taken verbatim from TG's Del The World + var/real_start_time = REALTIMEOFDAY var/garbage_queue_processed = FALSE - var/list/check_queue = SSgarbage.queues[GC_QUEUE_CHECK] + + sleep(time_needed) while(!garbage_queue_processed) - //How the hell did you manage to empty this? Good job! - if(!length(check_queue)) - garbage_queue_processed = TRUE - break + var/oldest_packet_creation = INFINITY + for(var/index in queues_we_care_about) + var/list/queue_to_check = SSgarbage.queues[index] + if(!length(queue_to_check)) + continue + + var/list/oldest_packet = queue_to_check[1] + //Pull out the time we inserted at + var/qdeld_at = oldest_packet[GC_QUEUE_ITEM_GCD_DESTROYED] + + oldest_packet_creation = min(qdeld_at, oldest_packet_creation) - var/list/oldest_packet = check_queue[1] - //Pull out the time we inserted at - var/qdeld_at = oldest_packet[GC_QUEUE_ITEM_GCD_DESTROYED] //If we've found a packet that got del'd later then we finished, then all our shit has been processed - if(qdeld_at > start_time) + //That said, if there are any pending hard deletes you may NOT sleep, we gotta handle that shit + if(oldest_packet_creation > start_time && !length(SSgarbage.queues[GC_QUEUE_HARDDELETE])) garbage_queue_processed = TRUE break - if(world.time > start_time + time_needed + 8 MINUTES) - fail("The garbage queue has been processing for well over 10 minutes. Something is likely broken.") + if(REALTIMEOFDAY > real_start_time + time_needed + 30 MINUTES) //If this gets us gitbanned I'm going to laugh so hard + fail("Something has gone horribly wrong, the garbage queue has been processing for well over 30 minutes. What the hell did you do") break //Immediately fire the gc right after diff --git a/code/world.dm b/code/world.dm index 361fa6c4a150..057199cfb0a5 100644 --- a/code/world.dm +++ b/code/world.dm @@ -12,6 +12,9 @@ hub = "Exadv1.spacestation13" icon_size = WORLD_ICON_SIZE fps = 20 -#ifdef GC_FAILURE_HARD_LOOKUP +#ifdef FIND_REF_NO_CHECK_TICK +#pragma push +#pragma ignore loop_checks loop_checks = FALSE +#pragma pop #endif diff --git a/nebula.dme b/nebula.dme index 8660305935b2..3531bdcbbe0c 100644 --- a/nebula.dme +++ b/nebula.dme @@ -10,6 +10,7 @@ #define DEBUG // END_PREFERENCES // BEGIN_INCLUDE +#include "code\___compile_options.dm" #include "code\___opendream_linting.dm" #include "code\__globals.dm" #include "code\_macros.dm" @@ -20,7 +21,6 @@ #include "code\__datastructures\stack.dm" #include "code\__defines\_byond_version_compat.dm" #include "code\__defines\_compile_helpers.dm" -#include "code\__defines\_compile_options.dm" #include "code\__defines\_planes+layers.dm" #include "code\__defines\_tick.dm" #include "code\__defines\admin.dm" From 53adcea7f076c86b79205e7458ac3939966301ff Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 10 Jan 2025 14:04:17 -0500 Subject: [PATCH 017/120] Allow QDEL_IN to use DPC --- code/__defines/qdel.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/__defines/qdel.dm b/code/__defines/qdel.dm index afafb9c6a132..1d2654f16d2c 100644 --- a/code/__defines/qdel.dm +++ b/code/__defines/qdel.dm @@ -33,13 +33,13 @@ #define QDESTROYING(X) (isnull(X) || X.gc_destroyed == GC_CURRENTLY_BEING_QDELETED) //Qdel helper macros. -#define QDEL_IN(item, time) if(!isnull(item)) {addtimer(CALLBACK(item, TYPE_PROC_REF(/datum, qdel_self)), time, TIMER_STOPPABLE)} -#define QDEL_IN_CLIENT_TIME(item, time) if(!isnull(item)) {addtimer(CALLBACK(item, TYPE_PROC_REF(/datum, qdel_self)), time, TIMER_STOPPABLE | TIMER_CLIENT_TIME)} +#define QDEL_IN(item, time) if(!isnull(item)) {addtimer(CALLBACK(item, TYPE_PROC_REF(/datum, qdel_self)), time)} +#define QDEL_IN_CLIENT_TIME(item, time) if(!isnull(item)) {addtimer(CALLBACK(item, TYPE_PROC_REF(/datum, qdel_self)), time, TIMER_CLIENT_TIME)} #define QDEL_NULL(item) if(item) {qdel(item); item = null} #define QDEL_NULL_SCREEN(item) if(client) { client.screen -= item; }; QDEL_NULL(item) #define QDEL_NULL_LIST(x) if(x) { for(var/y in x) { qdel(y) }}; if(x) {x.Cut(); x = null } // Second x check to handle items that LAZYREMOVE on qdel. #define QDEL_LIST(L) if(L) { for(var/I in L) qdel(I); L.Cut(); } -#define QDEL_LIST_IN(L, time) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(______qdel_list_wrapper), L), time, TIMER_STOPPABLE) +#define QDEL_LIST_IN(L, time) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(______qdel_list_wrapper), L), time) #define QDEL_LIST_ASSOC(L) if(L) { for(var/I in L) { qdel(L[I]); qdel(I); } L.Cut(); } #define QDEL_LIST_ASSOC_VAL(L) if(L) { for(var/I in L) qdel(L[I]); L.Cut(); } From 8f73c4c5995be254007f4329d0a895b95af7715c Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 10 Jan 2025 14:01:16 -0500 Subject: [PATCH 018/120] Fix global init datum harddeling --- ~code/global_init.dm | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/~code/global_init.dm b/~code/global_init.dm index 82950bb246da..c483e8f9e8b6 100644 --- a/~code/global_init.dm +++ b/~code/global_init.dm @@ -11,15 +11,14 @@ Pre-map initialization stuff should go here. */ -var/global_init = new /datum/global_init() +var/global/global_init = new /datum/global_init() /datum/global_init/New() SSconfiguration.load_all_configuration() generate_game_id() makeDatumRefLists() - qdel(src) //we're done + QDEL_IN(src, 0) //we're done. give it some time to finish setting up though /datum/global_init/Destroy() - global_init = null - ..() - return QDEL_HINT_HARDDEL + global.global_init = null + return ..() From 64c73b041900993891a5f73c8a3b01b8c5472816 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sat, 11 Jan 2025 21:15:13 -0500 Subject: [PATCH 019/120] Remove unnecessary image Destroy override --- code/game/images.dm | 3 --- nebula.dme | 1 - 2 files changed, 4 deletions(-) delete mode 100644 code/game/images.dm diff --git a/code/game/images.dm b/code/game/images.dm deleted file mode 100644 index e8b844937491..000000000000 --- a/code/game/images.dm +++ /dev/null @@ -1,3 +0,0 @@ -/image/Destroy() - ..() - return QDEL_HINT_HARDDEL diff --git a/nebula.dme b/nebula.dme index 3531bdcbbe0c..bb4d51993bc9 100644 --- a/nebula.dme +++ b/nebula.dme @@ -753,7 +753,6 @@ #include "code\game\atoms_movable_overlay.dm" #include "code\game\atoms_temperature.dm" #include "code\game\base_turf.dm" -#include "code\game\images.dm" #include "code\game\movietitles.dm" #include "code\game\response_team.dm" #include "code\game\sound.dm" From e05c4c24a731fe52973b606efe3fde4f1695bc0e Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 16 Jan 2025 15:45:35 -0500 Subject: [PATCH 020/120] Fix GC failures in slime code --- mods/content/xenobiology/slime/_slime.dm | 4 +- mods/content/xenobiology/slime/life.dm | 2 + mods/content/xenobiology/slime/slime_AI.dm | 50 +++++++++++-------- .../xenobiology/slime/slime_commands.dm | 30 ++++++----- .../xenobiology/slime/slime_comments.dm | 5 +- .../xenobiology/slime/slime_reagents.dm | 29 +++++------ 6 files changed, 66 insertions(+), 54 deletions(-) diff --git a/mods/content/xenobiology/slime/_slime.dm b/mods/content/xenobiology/slime/_slime.dm index a5b342022c26..c731f5cfba73 100644 --- a/mods/content/xenobiology/slime/_slime.dm +++ b/mods/content/xenobiology/slime/_slime.dm @@ -33,7 +33,6 @@ var/slime_type = /decl/slime_colour/grey var/cores = 1 // the number of /obj/item/slime_extract's the slime has left inside var/core_removal_stage = 0 //For removing cores. - var/datum/reagents/metabolism/ingested /mob/living/slime/Destroy() set_feeding_on() @@ -65,8 +64,7 @@ . = ..(mapload) - ingested = new /datum/reagents/metabolism(240, src, CHEM_TOUCH) - reagents = ingested + reagents = new /datum/reagents/metabolism(240, src, CHEM_TOUCH) render_target = "slime_\ref[src]" verbs += /mob/living/proc/ventcrawl diff --git a/mods/content/xenobiology/slime/life.dm b/mods/content/xenobiology/slime/life.dm index 55b0e665ec12..d71a1d3edd4c 100644 --- a/mods/content/xenobiology/slime/life.dm +++ b/mods/content/xenobiology/slime/life.dm @@ -46,6 +46,7 @@ . = ..() if(feeding_on) slime_feed() + var/datum/reagents/metabolism/ingested = reagents ingested.metabolize() /mob/living/slime/fluid_act(datum/reagents/fluids) @@ -86,6 +87,7 @@ . = ..() if(feeding_on) slime_feed() + var/datum/reagents/metabolism/ingested = reagents ingested.metabolize() // Digest whatever we've got floating around in our goop. diff --git a/mods/content/xenobiology/slime/slime_AI.dm b/mods/content/xenobiology/slime/slime_AI.dm index 7260e124070c..bf28ef6cd6bb 100644 --- a/mods/content/xenobiology/slime/slime_AI.dm +++ b/mods/content/xenobiology/slime/slime_AI.dm @@ -2,8 +2,8 @@ expected_type = /mob/living/slime var/mood var/chase_target = 0 - var/mob/living/leader - var/mob/living/current_target // Currently attacking this mob (separate from feeding) + var/weakref/leader + var/weakref/current_target // Currently attacking this mob (separate from feeding) var/attacked = 0 // Determines if it's been attacked recently. Can be any number, is a cooloff-ish variable var/rabid = 0 // If set to 1, the slime will attack and eat anything it comes in contact with var/list/observed_friends // A list of refs to friends; they are not considered targets for feeding; passed down after splitting. @@ -20,6 +20,7 @@ /datum/mob_controller/slime/Destroy() observed_friends = null friendship_cooldown = null + leader = null current_target = null speech_buffer = null slime = null @@ -44,7 +45,7 @@ else if(rabid || attacked) new_mood = "angry" body.set_intent(I_FLAG_HARM) - else if(current_target) + else if(current_target?.resolve()) new_mood = "mischevous" if(!new_mood) @@ -97,22 +98,27 @@ current_target = null return - if(current_target) + var/mob/actual_target = current_target?.resolve() + if(actual_target) chase_target-- if(chase_target <= 0 || attacked || rabid) // Tired of chasing or attacking everything nearby chase_target = 0 current_target = null + else + current_target = null var/hunger = slime.get_hunger_state() - if(!current_target) + var/mob/leader_mob = leader?.resolve() + actual_target = current_target?.resolve() + if(!actual_target) var/feral = (attacked || rabid || hunger >= 2) - if(feral || (!leader && !holding_still) || (hunger && prob(10))) + if(feral || (!leader_mob && !holding_still) || (hunger && prob(10))) var/list/targets for(var/mob/living/prey in view(7, body)) if(assess_target(prey)) LAZYADD(targets, prey) if(length(targets)) - current_target = get_best_target(targets) + current_target = weakref(get_best_target(targets)) chase_target = rand(5,7) if(slime.is_adult) chase_target += 3 @@ -120,8 +126,8 @@ if(holding_still) holding_still = max(holding_still - 1 - hunger, 0) else if(isturf(body?.loc)) - if(leader) - step_to(body, get_dir(body, leader)) + if(leader_mob) + step_to(body, get_dir(body, leader_mob)) else if(prob(hunger ? 50 : 33)) body.SelfMove(pick(global.cardinal)) @@ -131,42 +137,42 @@ return var/added_delay = 0 - if(slime.amount_grown >= SLIME_EVOLUTION_THRESHOLD && !current_target) + var/mob/actual_target = current_target?.resolve() + if(slime.amount_grown >= SLIME_EVOLUTION_THRESHOLD && !actual_target) if(slime.is_adult) slime.slime_split() else slime.slime_mature() added_delay = 10 else - - if(!assess_target(current_target) || current_target == slime.feeding_on || !(current_target in view(7, body))) + if(!assess_target(actual_target) || actual_target == slime.feeding_on || !(actual_target in view(7, body))) current_target = null - if(!current_target) + if(!actual_target) if(prob(1)) for(var/mob/living/slime/frenemy in range(1, body)) if(frenemy != body && body.Adjacent(frenemy)) body.set_intent((frenemy.slime_type == slime.slime_type) ? I_FLAG_HELP : I_FLAG_HARM) body.UnarmedAttack(frenemy, TRUE) added_delay = 10 - else if(slime.Adjacent(current_target)) + else if(slime.Adjacent(actual_target)) var/do_attack = FALSE - if(issilicon(current_target)) + if(issilicon(actual_target)) body.set_intent(I_FLAG_HARM) do_attack = TRUE - else if(current_target.client && !current_target.current_posture.prone && prob(60 + slime.powerlevel * 4)) + else if(actual_target.client && !actual_target.current_posture.prone && prob(60 + slime.powerlevel * 4)) body.set_intent(I_FLAG_DISARM) do_attack = TRUE - else if(slime.check_valid_feed_target(current_target) == FEED_RESULT_VALID) + else if(slime.check_valid_feed_target(actual_target) == FEED_RESULT_VALID) body.set_intent(I_FLAG_GRAB) do_attack = TRUE if(do_attack) - body.UnarmedAttack(current_target, TRUE) + body.UnarmedAttack(actual_target, TRUE) added_delay = 10 else current_target = null else - step_to(body, current_target) + step_to(body, actual_target) next_core_logic_run = world.time + max(body?.get_movement_delay(), 5) + added_delay @@ -208,13 +214,13 @@ /datum/mob_controller/slime/proc/adjust_friendship(var/atom/user, var/amount) if(ismob(user)) - if(QDELETED(user)) + if(QDELING(user)) return FALSE user = weakref(user) else if(istype(user, /weakref)) // verify the ref is still valid var/weakref/user_ref = user - user = user_ref.resolve() - if(!ismob(user) || QDELETED(user)) + var/mob/resolved_user = user_ref.resolve() + if(!ismob(resolved_user) || QDELING(resolved_user)) return FALSE else return FALSE diff --git a/mods/content/xenobiology/slime/slime_commands.dm b/mods/content/xenobiology/slime/slime_commands.dm index 4290f05accfb..3be381f2a01f 100644 --- a/mods/content/xenobiology/slime/slime_commands.dm +++ b/mods/content/xenobiology/slime/slime_commands.dm @@ -20,15 +20,16 @@ triggers = list("follow") /decl/slime_command/follow/get_response(var/speaker, var/spoken, var/datum/mob_controller/slime/holder) - if(holder.leader) - if(holder.leader == speaker) + var/mob/leader_mob = holder.leader?.resolve() + if(leader_mob) + if(leader_mob == speaker) return pick("Yes...", "Lead...", "Following...") - if(LAZYACCESS(holder.observed_friends, weakref(speaker)) > LAZYACCESS(holder.observed_friends, weakref(holder.leader))) - holder.leader = speaker + if(LAZYACCESS(holder.observed_friends, weakref(speaker)) > LAZYACCESS(holder.observed_friends, holder.leader)) + holder.leader = weakref(speaker) return "Yes... I follow [speaker]..." - return "No... I follow [holder.leader]..." + return "No... I follow [leader_mob]..." if(LAZYACCESS(holder.observed_friends, weakref(speaker)) > 2) - holder.leader = speaker + holder.leader = weakref(speaker) return "I follow..." return pick("No...", "I won't follow...") @@ -45,18 +46,20 @@ holder.adjust_friendship(speaker, -1) return "Grrr..." return "Fine..." - if(holder.current_target) + var/mob/actual_target = holder.current_target?.resolve() + if(actual_target) if(friendship > 3) holder.current_target = null if(friendship < 6) holder.adjust_friendship(speaker, -1) return "Grrr..." return "Fine..." - if(holder.leader) - if(holder.leader == speaker) + var/mob/leader_mob = holder.leader?.resolve() + if(leader_mob) + if(leader_mob == speaker) holder.leader = null return "Yes... I'll stop..." - if(friendship > LAZYACCESS(holder.observed_friends, weakref(holder.leader))) + if(friendship > LAZYACCESS(holder.observed_friends, holder.leader)) holder.leader = null return "Yes... I'll stop..." return "No... I'll keep following..." @@ -66,11 +69,12 @@ /decl/slime_command/stay/get_response(var/speaker, var/spoken, var/datum/mob_controller/slime/holder) var/friendship = LAZYACCESS(holder.observed_friends, weakref(speaker)) - if(holder.leader) - if(holder.leader == speaker) + var/mob/leader_mob = holder.leader?.resolve() + if(leader_mob) + if(leader_mob == speaker) holder.holding_still = friendship * 10 return "Yes... Staying..." - var/leader_friendship = LAZYACCESS(holder.observed_friends, weakref(holder.leader)) + var/leader_friendship = LAZYACCESS(holder.observed_friends, holder.leader) if(friendship > leader_friendship) holder.holding_still = (friendship - leader_friendship) * 10 return "Yes... Staying..." diff --git a/mods/content/xenobiology/slime/slime_comments.dm b/mods/content/xenobiology/slime/slime_comments.dm index bd8ad9f11468..f009e3131236 100644 --- a/mods/content/xenobiology/slime/slime_comments.dm +++ b/mods/content/xenobiology/slime/slime_comments.dm @@ -29,8 +29,9 @@ if(holder.slime.nutrition < holder.slime.get_starve_nutrition()) . += list("So... hungry...", "Very... hungry...", "Need... food...", "Must... eat...") tension += 10 - if(holder.current_target) - . += "\The [holder.current_target]... looks tasty..." + var/mob/actual_target = holder.current_target?.resolve() + if(actual_target) + . += "\The [actual_target]... looks tasty..." if(length(.) && prob(tension)) return pick(.) diff --git a/mods/content/xenobiology/slime/slime_reagents.dm b/mods/content/xenobiology/slime/slime_reagents.dm index bff84fd00ee7..882797de7599 100644 --- a/mods/content/xenobiology/slime/slime_reagents.dm +++ b/mods/content/xenobiology/slime/slime_reagents.dm @@ -14,22 +14,23 @@ metabolism = REM * 0.25 exoplanet_rarity_gas = MAT_RARITY_EXOTIC -/decl/material/liquid/water/affect_touch(var/mob/living/M, var/removed, var/datum/reagents/holder) +/decl/material/liquid/water/affect_touch(var/mob/living/victim, var/removed, var/datum/reagents/holder) . = ..() - if(isslime(M)) - M.take_damage(10 * removed, TOX) - var/mob/living/slime/S = M - if(istype(S) && istype(S.ai, /datum/mob_controller/slime)) - var/datum/mob_controller/slime/slime_ai = S.ai - if(slime_ai.current_target) + if(isslime(victim)) + victim.take_damage(10 * removed, TOX) + var/mob/living/slime/slime_victim = victim + if(istype(slime_victim) && istype(slime_victim.ai, /datum/mob_controller/slime)) + var/datum/mob_controller/slime/slime_ai = slime_victim.ai + if(slime_ai.current_target) // don't bother resolving it, we're just clearing it slime_ai.current_target = null - S.set_feeding_on() - if(LAZYACCESS(M.chem_doses, type) == removed) - M.visible_message( \ - SPAN_DANGER("\The [S]'s flesh sizzles where \the [name] touches it!"), \ - SPAN_DANGER("Your flesh is burned by \the [name]!")) - SET_STATUS_MAX(M, STAT_CONFUSE, 2) - var/datum/mob_controller/slime/slime_ai = M.ai + slime_victim.set_feeding_on() + if(LAZYACCESS(victim.chem_doses, type) == removed) + var/reagent_name = get_reagent_name(holder) // mostly to check masked name, but handles phase too + victim.visible_message( \ + SPAN_DANGER("\The [slime_victim]'s flesh sizzles where \the [reagent_name] touches it!"), \ + SPAN_DANGER("Your flesh is burned by \the [reagent_name]!")) + SET_STATUS_MAX(victim, STAT_CONFUSE, 2) + var/datum/mob_controller/slime/slime_ai = victim.ai if(istype(slime_ai)) slime_ai.attacked = max(slime_ai.attacked, rand(7,10)) // angery From 218fb229065ac931af7c715a91b6e5f648c1848c Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 17 Jan 2025 03:28:21 -0500 Subject: [PATCH 021/120] Fix bookcases causing harddels --- code/_macros.dm | 6 +++++- code/game/objects/structures/bookcase.dm | 20 ++++++++++++-------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/code/_macros.dm b/code/_macros.dm index 5cba5893825f..f1fbd14b3d02 100644 --- a/code/_macros.dm +++ b/code/_macros.dm @@ -194,4 +194,8 @@ #define FONT_GIANT(X) "[X]" -#define PRINT_STACK_TRACE(X) get_stack_trace(X, __FILE__, __LINE__) \ No newline at end of file +#define PRINT_STACK_TRACE(X) get_stack_trace(X, __FILE__, __LINE__) + +/// Checks if potential_weakref is a weakref of thing. +/// NOTE: These argments are the opposite order of TG's, because I think TG's are counterintuitive. +#define IS_WEAKREF_OF(potential_weakref, thing) (istype(thing, /datum) && !isnull(potential_weakref) && thing.weakref == potential_weakref) \ No newline at end of file diff --git a/code/game/objects/structures/bookcase.dm b/code/game/objects/structures/bookcase.dm index 944bcd3fe0fb..c51e005f3cfe 100644 --- a/code/game/objects/structures/bookcase.dm +++ b/code/game/objects/structures/bookcase.dm @@ -44,7 +44,7 @@ var/global/list/station_bookcases = list() var/place_key = GET_BOOK_POS(src, place_x, place_y) if(isnull(book_positions[place_key])) - book_positions[place_key] = inserted + book_positions[place_key] = weakref(inserted) /datum/storage/bookcase/update_ui_after_item_removal(obj/item/removed) . = ..() @@ -53,7 +53,8 @@ var/global/list/station_bookcases = list() for(var/bX = 0 to (book_slots_x-1)) for(var/bY = 0 to (book_slots_y-1)) var/bK = GET_BOOK_POS(src, bX, bY) - if(book_positions[bK] == removed) + var/weakref/potential_book = book_positions[bK] + if(IS_WEAKREF_OF(potential_book, removed)) book_positions[bK] = null return @@ -65,8 +66,9 @@ var/global/list/station_bookcases = list() for(var/bX = 0 to (book_slots_x-1)) for(var/bY = 0 to (book_slots_y-1)) var/bK = GET_BOOK_POS(src, bX, bY) - var/obj/item/thing = book_positions[bK] - if(!isnull(thing) && (QDELETED(thing) || thing.loc != holder)) + var/weakref/book_ref = book_positions[bK] + var/obj/item/thing = book_ref?.resolve() + if(!isnull(thing) && (QDELING(thing) || thing.loc != holder)) // QDELING because it might be deleting but hasn't been moved to nullspace yet book_positions[bK] = null for(var/obj/item/thing in holder.get_stored_inventory()) @@ -75,7 +77,8 @@ var/global/list/station_bookcases = list() // Avoid moving us if we're already positioned for(var/bX = 0 to (book_slots_x-1)) for(var/bY = 0 to (book_slots_y-1)) - if(book_positions[GET_BOOK_POS(src, bX, bY)] == thing) + var/weakref/potential_book = book_positions[GET_BOOK_POS(src, bX, bY)] + if(IS_WEAKREF_OF(potential_book, thing)) positioned = TRUE break if(positioned) @@ -89,7 +92,7 @@ var/global/list/station_bookcases = list() for(var/bY = 0 to (book_slots_y-1)) var/bK = GET_BOOK_POS(src, bX, bY) if(isnull(book_positions[bK])) - book_positions[bK] = thing + book_positions[bK] = weakref(thing) positioned = TRUE break if(positioned) @@ -154,12 +157,13 @@ var/global/list/station_bookcases = list() for(var/bY = 0 to (book_storage.book_slots_y-1)) var/bK = (bY * book_storage.book_slots_x) + bX + 1 - var/obj/item/book = book_storage.book_positions[bK] + var/weakref/book_ref = book_storage.book_positions[bK] + var/obj/item/book = book_ref?.resolve() if(!istype(book) || !check_state_in_icon("bookcase", book.icon)) continue var/use_lying_state = "bookcase" - if(bX < (book_storage.book_slots_x-1) && isnull(book_storage.book_positions[bK+1]) && check_state_in_icon("bookcase_flat", book.icon)) + if(bX < (book_storage.book_slots_x-1) && !isnull(book_storage.book_positions[bK+1]) && check_state_in_icon("bookcase_flat", book.icon)) use_lying_state = "bookcase_flat" var/image/book_overlay = overlay_image(book.icon, use_lying_state, book.get_color(), RESET_COLOR) From bb908f8630d4d629c6884051330ef372b4f23ef4 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 14 Jan 2025 12:13:12 -0500 Subject: [PATCH 022/120] Fix graphs and graph tests causing harddels --- code/unit_tests/graph_tests.dm | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/code/unit_tests/graph_tests.dm b/code/unit_tests/graph_tests.dm index 1d1cd69b6219..d3adbe5210d4 100644 --- a/code/unit_tests/graph_tests.dm +++ b/code/unit_tests/graph_tests.dm @@ -489,6 +489,7 @@ /atom/movable/graph_test/Destroy() QDEL_NULL(node) + neighboursByDirection.Cut() return ..() /atom/movable/graph_test/forceMove() @@ -524,7 +525,7 @@ var/on_split_was_called var/issues -/datum/graph/testing/New(var/node, var/edges, var/name) +/datum/graph/testing/New(var/node, var/edges, var/previous_owner, var/name) ..() src.name = name || "Graph" issues = list() @@ -558,8 +559,10 @@ /datum/graph/testing/proc/CheckExpectations() if(on_check_expectations) issues += DoCheckExpectations(on_check_expectations) + QDEL_NULL(on_check_expectations) // stop holding up GC! if(length(split_expectations) && !on_split_was_called) issues += "Had split expectations but OnSplit was not called" + QDEL_LIST(split_expectations) // stop holding up GC! if(!length(split_expectations) && on_split_was_called) issues += "Had no split expectations but OnSplit was called" if(expecting_merge != on_merge_was_called) @@ -576,6 +579,11 @@ src.expected_nodes = expected_nodes || list() src.expected_edges = expected_edges || list() +/datum/graph_expectation/Destroy(force) + expected_nodes.Cut() + expected_edges.Cut() + return ..() + // Stub for subtype-specific functionality for DoCheckExpectations. // Should not access graph.nodes or graph.edges. /datum/graph_expectation/proc/OnCheckExpectations(var/datum/graph/graph) From 776d6f5c2817d9d2e3b8d29d06bb053f787085e6 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 17 Jan 2025 19:09:24 -0500 Subject: [PATCH 023/120] Fix vomit causing harddels --- code/modules/mob/living/human/human.dm | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/code/modules/mob/living/human/human.dm b/code/modules/mob/living/human/human.dm index ed0df480df70..3380393bbd78 100644 --- a/code/modules/mob/living/human/human.dm +++ b/code/modules/mob/living/human/human.dm @@ -346,7 +346,7 @@ return var/decl/pronouns/pronouns = get_pronouns() visible_message(SPAN_DANGER("\The [src] starts sticking a finger down [pronouns.his] own throat. It looks like [pronouns.he] [pronouns.is] trying to throw up!")) - if(!do_after(src, 30)) + if(!do_after(src, 3 SECONDS)) return timevomit = max(timevomit, 5) @@ -355,13 +355,22 @@ lastpuke = TRUE to_chat(src, SPAN_WARNING("You feel nauseous...")) + var/finish_time = 35 SECONDS if(level > 1) - sleep(150 / timevomit) //15 seconds until second warning - to_chat(src, SPAN_WARNING("You feel like you are about to throw up!")) + // 15 seconds until second warning + addtimer(CALLBACK(src, PROC_REF(vomit_second_warning_message)), 15 SECONDS / timevomit) + finish_time += 15 SECONDS / timevomit if(level > 2) - sleep(100 / timevomit) //and you have 10 more for mad dash to the bucket - empty_stomach() - sleep(350) //wait 35 seconds before next volley + // and you have 10 more for mad dash to the bucket + // timer delay must include the time from the prior one also + addtimer(CALLBACK(src, PROC_REF(empty_stomach)), 25 SECONDS / timevomit) + finish_time += 10 SECONDS / timevomit + addtimer(CALLBACK(src, PROC_REF(reset_vomit_cooldown)), finish_time) + +/mob/living/human/proc/vomit_second_warning_message() + to_chat(src, SPAN_WARNING("You feel like you are about to throw up!")) + +/mob/living/human/proc/reset_vomit_cooldown() lastpuke = FALSE /mob/living/human/proc/increase_germ_level(n) From 33074a8d33d045e00d9c87cc0422ff663ec31594 Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Sun, 19 Jan 2025 00:52:54 +0000 Subject: [PATCH 024/120] Automatic changelog generation [ci skip] --- html/changelog.html | 6 ++++++ html/changelogs/.all_changelog.yml | 4 ++++ html/changelogs/AutoChangeLog-pr-4748.yml | 5 ----- 3 files changed, 10 insertions(+), 5 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-4748.yml diff --git a/html/changelog.html b/html/changelog.html index 58aeb978adc1..7e9d585edb61 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -52,6 +52,12 @@ -->
+

19 January 2025

+

MistakeNot4892 updated:

+
    +
  • Intents have been rewritten and moved, please report any issues with intent selection.
  • +
+

16 January 2025

MistakeNot4892 updated:

    diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 65ecf2cbcfd8..7192cd238724 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -14959,3 +14959,7 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. overlay color. - tweak: The Shaded Hills river now flows north. - tweak: Snow, mud and sand will now show footprints. +2025-01-19: + MistakeNot4892: + - tweak: Intents have been rewritten and moved, please report any issues with intent + selection. diff --git a/html/changelogs/AutoChangeLog-pr-4748.yml b/html/changelogs/AutoChangeLog-pr-4748.yml deleted file mode 100644 index 36462616a457..000000000000 --- a/html/changelogs/AutoChangeLog-pr-4748.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: MistakeNot4892 -changes: - - {tweak: 'Intents have been rewritten and moved, please report any issues with - intent selection.'} -delete-after: true From 469c1df67c0ccd4f1d681695ff25703b997fd379 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 19 Jan 2025 19:41:08 +1100 Subject: [PATCH 025/120] Reverting sharp/edge var rename in favour of VAR_PROTECTED. --- code/game/objects/items/_item_force.dm | 10 +++++----- code/game/objects/items/_item_sharpness.dm | 16 ++++++++-------- code/game/objects/items/blades/_blade.dm | 4 ++-- code/game/objects/items/blades/folding.dm | 2 +- code/game/objects/items/blades/spear.dm | 4 ++-- code/game/objects/items/rock.dm | 8 ++++---- code/game/objects/items/toys.dm | 8 ++++---- .../objects/items/weapons/material/folding.dm | 8 ++++---- .../objects/items/weapons/material/knives.dm | 6 +++--- code/game/objects/items/weapons/material/misc.dm | 12 ++++++------ .../objects/items/weapons/material/shards.dm | 4 ++-- .../game/objects/items/weapons/material/stick.dm | 6 +++--- .../game/objects/items/weapons/material/swiss.dm | 4 ++-- .../objects/items/weapons/material/swords.dm | 4 ++-- .../objects/items/weapons/material/thrown.dm | 4 ++-- code/game/objects/items/weapons/melee/energy.dm | 4 ++-- .../objects/items/weapons/melee/energy_axe.dm | 4 ++-- code/game/objects/items/weapons/melee/misc.dm | 2 +- code/game/objects/items/weapons/surgery_tools.dm | 12 ++++++------ .../items/weapons/surgery_tools_ancient.dm | 2 +- .../objects/items/weapons/tools/screwdriver.dm | 2 +- code/game/objects/items/weapons/tools/shears.dm | 4 ++-- .../objects/items/weapons/tools/wirecutter.dm | 4 ++-- code/modules/augment/active/armblades.dm | 4 ++-- code/modules/economy/worth_items.dm | 2 +- code/modules/food/utensils/utensil_hybrid.dm | 4 ++-- code/modules/food/utensils/utensil_knife.dm | 4 ++-- .../mob/living/simple_animal/crow/crow.dm | 2 +- .../hostile/commanded/nanomachines.dm | 2 +- .../simple_animal/hostile/hivebots/megabot.dm | 4 ++-- .../hostile/retaliate/king_of_goats.dm | 6 +++--- .../living/simple_animal/hostile/viscerator.dm | 4 ++-- .../mob/living/simple_animal/natural_weapons.dm | 10 +++++----- code/modules/paperwork/pen/fancy.dm | 2 +- code/modules/paperwork/pen/quill_and_ink.dm | 2 +- code/modules/paperwork/pen/reagent_pen.dm | 2 +- code/modules/projectiles/ammunition/chemdart.dm | 2 +- .../projectiles/guns/launcher/bows/arrow.dm | 4 ++-- .../projectiles/guns/launcher/syringe_gun.dm | 2 +- code/modules/projectiles/projectile/beams.dm | 16 ++++++++-------- .../reagents/reagent_containers/drinks/bottle.dm | 2 +- .../reagents/reagent_containers/syringes.dm | 2 +- code/modules/shield_generators/shield.dm | 2 +- code/modules/tools/subtypes/axes.dm | 4 ++-- code/modules/tools/subtypes/hoes.dm | 4 ++-- code/modules/tools/subtypes/pickaxes.dm | 4 ++-- code/modules/tools/subtypes/shovel.dm | 8 ++++---- .../tools/subtypes/xenoarchaeology_picks.dm | 4 ++-- .../xenoarcheaology/tools/core_sampler.dm | 2 +- mods/content/item_sharpening/item_sharpen.dm | 2 +- .../system/psionics/equipment/psipower_blade.dm | 4 ++-- .../gamemodes/cult/mobs/constructs/constructs.dm | 4 ++-- 52 files changed, 124 insertions(+), 124 deletions(-) diff --git a/code/game/objects/items/_item_force.dm b/code/game/objects/items/_item_force.dm index 2a494551d6aa..9ce71938c3cb 100644 --- a/code/game/objects/items/_item_force.dm +++ b/code/game/objects/items/_item_force.dm @@ -61,14 +61,14 @@ // Check if this material is hard enough to hold an edge. if(!material.can_hold_edge()) set_edge(FALSE) - else if(!_edge) - set_edge(initial(_edge)) + else if(!edge) + set_edge(initial(edge)) // Check if this material can hold a point. if(!material.can_hold_sharpness()) set_sharp(FALSE) - else if(!_sharp) - set_sharp(initial(_sharp)) + else if(!sharp) + set_sharp(initial(sharp)) // Work out where we're going to cap our calculated force. // Any additional force resulting from hardness or weight turn into armour penetration. @@ -157,7 +157,7 @@ (attk_force + expected_material_mod), (attk_force * item._wielded_force_multiplier), item.armor_penetration, - (item._sharp|item._edge) + (item.sharp|item.edge) ), "|") text2file(jointext(rows, "\n"), "weapon_stats_dump.csv") diff --git a/code/game/objects/items/_item_sharpness.dm b/code/game/objects/items/_item_sharpness.dm index f1ed8fd10237..a37c1bf56fe7 100644 --- a/code/game/objects/items/_item_sharpness.dm +++ b/code/game/objects/items/_item_sharpness.dm @@ -1,21 +1,21 @@ /obj/item - var/_sharp = FALSE - var/_edge = FALSE + VAR_PROTECTED/sharp = FALSE + VAR_PROTECTED/edge = FALSE /obj/item/is_sharp() - return _sharp + return sharp /obj/item/has_edge() - return _edge + return edge /obj/item/proc/set_edge(new_edge) - if(_edge != new_edge) - _edge = new_edge + if(edge != new_edge) + edge = new_edge return TRUE return FALSE /obj/item/proc/set_sharp(new_sharp) - if(_sharp != new_sharp) - _sharp = new_sharp + if(sharp != new_sharp) + sharp = new_sharp return TRUE return FALSE diff --git a/code/game/objects/items/blades/_blade.dm b/code/game/objects/items/blades/_blade.dm index 5609760df9c1..74acd76417af 100644 --- a/code/game/objects/items/blades/_blade.dm +++ b/code/game/objects/items/blades/_blade.dm @@ -6,8 +6,8 @@ origin_tech = @'{"materials":1,"combat":1}' attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") obj_flags = OBJ_FLAG_CONDUCTIBLE - _sharp = TRUE - _edge = TRUE + sharp = TRUE + edge = TRUE item_flags = ITEM_FLAG_IS_WEAPON pickup_sound = 'sound/foley/knife1.ogg' drop_sound = 'sound/foley/knifedrop3.ogg' diff --git a/code/game/objects/items/blades/folding.dm b/code/game/objects/items/blades/folding.dm index 12bc613fa288..8af5321a1208 100644 --- a/code/game/objects/items/blades/folding.dm +++ b/code/game/objects/items/blades/folding.dm @@ -3,7 +3,7 @@ desc = "A small folding knife." icon = 'icons/obj/items/bladed/folding.dmi' w_class = ITEM_SIZE_SMALL - _sharp = FALSE + sharp = FALSE pommel_material = null guard_material = null slot_flags = null diff --git a/code/game/objects/items/blades/spear.dm b/code/game/objects/items/blades/spear.dm index 6991d988a51f..99af4702dc2c 100644 --- a/code/game/objects/items/blades/spear.dm +++ b/code/game/objects/items/blades/spear.dm @@ -3,8 +3,8 @@ desc = "A haphazardly-constructed yet still deadly weapon of ancient design." icon = 'icons/obj/items/bladed/spear.dmi' throw_speed = 3 - _edge = FALSE - _sharp = TRUE + edge = FALSE + sharp = TRUE attack_verb = list("attacked", "poked", "jabbed", "torn", "gored") does_spin = FALSE abstract_type = /obj/item/bladed/polearm/spear diff --git a/code/game/objects/items/rock.dm b/code/game/objects/items/rock.dm index 94611df6bdd3..76b9f6d04862 100644 --- a/code/game/objects/items/rock.dm +++ b/code/game/objects/items/rock.dm @@ -3,8 +3,8 @@ desc = "The secret is to bang the rocks together, guys." icon = 'icons/obj/items/rock.dmi' icon_state = ICON_STATE_WORLD - _sharp = TRUE - _edge = TRUE + sharp = TRUE + edge = TRUE _base_attack_force = 3 material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME w_class = ITEM_SIZE_SMALL @@ -49,6 +49,6 @@ name = "striker" desc = "A squared-off, rather worn-down piece of stone." icon = 'icons/obj/items/striker.dmi' - _sharp = FALSE - _edge = FALSE + sharp = FALSE + edge = FALSE w_class = ITEM_SIZE_TINY \ No newline at end of file diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 424992dba80d..53ec5ef987f7 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -144,8 +144,8 @@ /obj/item/energy_blade/sword/toy name = "toy sword" desc = "A cheap, plastic replica of an energy sword. Realistic sounds! Ages 8 and up." - _sharp = FALSE - _edge = FALSE + sharp = FALSE + edge = FALSE attack_verb = list("hit") material = /decl/material/solid/organic/plastic active_hitsound = 'sound/weapons/genhit.ogg' @@ -497,8 +497,8 @@ desc = "An arcane weapon (made of foam) wielded by the followers of the hit Saturday morning cartoon \"King Nursee and the Acolytes of Heroism\"." icon = 'icons/obj/items/weapon/swords/cult.dmi' material = /decl/material/solid/organic/plastic/foam - _edge = FALSE - _sharp = FALSE + edge = FALSE + sharp = FALSE /obj/item/inflatable_duck //#TODO: Move under obj/item/toy ? name = "inflatable duck" diff --git a/code/game/objects/items/weapons/material/folding.dm b/code/game/objects/items/weapons/material/folding.dm index cdbc0a29a09a..38cfa3a24761 100644 --- a/code/game/objects/items/weapons/material/folding.dm +++ b/code/game/objects/items/weapons/material/folding.dm @@ -6,8 +6,8 @@ icon = 'icons/obj/items/weapon/knives/folding/basic.dmi' w_class = ITEM_SIZE_SMALL attack_verb = list("prodded", "tapped") - _edge = FALSE - _sharp = FALSE + edge = FALSE + sharp = FALSE draw_handle = TRUE valid_handle_colors = list(COLOR_DARK_GRAY, COLOR_RED_GRAY, COLOR_BLUE_GRAY, COLOR_DARK_BLUE_GRAY, COLOR_GREEN_GRAY, COLOR_DARK_GREEN_GRAY) material = /decl/material/solid/metal/steel @@ -35,8 +35,8 @@ attack_verb = list("slashed", "stabbed") ..() else - set_edge(initial(_edge)) - set_sharp(initial(_sharp)) + set_edge(initial(edge)) + set_sharp(initial(sharp)) w_class = initial(w_class) attack_verb = closed_attack_verbs diff --git a/code/game/objects/items/weapons/material/knives.dm b/code/game/objects/items/weapons/material/knives.dm index 8c0f344729bb..9df9b46dc099 100644 --- a/code/game/objects/items/weapons/material/knives.dm +++ b/code/game/objects/items/weapons/material/knives.dm @@ -8,8 +8,8 @@ material = /decl/material/solid/metal/steel origin_tech = @'{"materials":1}' obj_flags = OBJ_FLAG_CONDUCTIBLE - _sharp = TRUE - _edge = TRUE + sharp = TRUE + edge = TRUE item_flags = ITEM_FLAG_CAN_HIDE_IN_SHOES | ITEM_FLAG_IS_WEAPON material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME pickup_sound = 'sound/foley/knife1.ogg' @@ -104,7 +104,7 @@ name = "meat hook" desc = "A sharp, metal hook what sticks into things." icon = 'icons/obj/items/weapon/knives/hook.dmi' - _sharp = FALSE + sharp = FALSE /obj/item/knife/ritual name = "ritual knife" diff --git a/code/game/objects/items/weapons/material/misc.dm b/code/game/objects/items/weapons/material/misc.dm index 5a2c02a2b3ee..8040747110e6 100644 --- a/code/game/objects/items/weapons/material/misc.dm +++ b/code/game/objects/items/weapons/material/misc.dm @@ -1,8 +1,8 @@ /obj/item/harpoon name = "harpoon" desc = "A short throwing spear with a deep barb, specifically designed to embed itself in its target." - _sharp = TRUE - _edge = TRUE + sharp = TRUE + edge = TRUE icon = 'icons/obj/items/weapon/harpoon.dmi' icon_state = "harpoon" item_state = "harpoon" @@ -39,16 +39,16 @@ SetName("broken harpoon") desc = "A short spear with just a barb - if it once had a spearhead, it doesn't any more." icon_state = "harpoon_bomb_spent" - _sharp = FALSE - _edge = FALSE + sharp = FALSE + edge = FALSE /obj/item/scythe name = "scythe" desc = "A sharp and curved blade on a long fibremetal handle, this tool makes it easy to reap what you sow." icon = 'icons/obj/items/tool/scythe.dmi' icon_state = ICON_STATE_WORLD - _sharp = TRUE - _edge = TRUE + sharp = TRUE + edge = TRUE throw_speed = 1 throw_range = 3 w_class = ITEM_SIZE_HUGE diff --git a/code/game/objects/items/weapons/material/shards.dm b/code/game/objects/items/weapons/material/shards.dm index 2f558ddead6e..858687ff9167 100644 --- a/code/game/objects/items/weapons/material/shards.dm +++ b/code/game/objects/items/weapons/material/shards.dm @@ -6,8 +6,8 @@ desc = "Made of nothing. How does this even exist?" // set based on material, if this desc is visible it's a bug (shards default to being made of glass) icon_state = "large" randpixel = 8 - _sharp = TRUE - _edge = TRUE + sharp = TRUE + edge = TRUE w_class = ITEM_SIZE_SMALL item_state = "shard-glass" attack_verb = list("stabbed", "slashed", "sliced", "cut") diff --git a/code/game/objects/items/weapons/material/stick.dm b/code/game/objects/items/weapons/material/stick.dm index 7f6fe9941035..d752ca73f46d 100644 --- a/code/game/objects/items/weapons/material/stick.dm +++ b/code/game/objects/items/weapons/material/stick.dm @@ -16,17 +16,17 @@ /obj/item/stick/attackby(obj/item/W, mob/user) - if(W.is_sharp() && W.has_edge() && !_sharp) + if(W.is_sharp() && W.has_edge() && !sharp) user.visible_message("[user] sharpens [src] with [W].", "You sharpen [src] using [W].") set_sharp(TRUE) SetName("sharpened " + name) update_attack_force() return TRUE - if(!_sharp && (istype(W, /obj/item/stack/material/bolt) || istype(W, /obj/item/stack/material/bundle))) + if(!sharp && (istype(W, /obj/item/stack/material/bolt) || istype(W, /obj/item/stack/material/bundle))) var/choice = input(user, "Do you want to make a torch, or a splint?", "Stick Crafting") as null|anything in list("Torch", "Splint") - if(!choice || QDELETED(user) || user.get_active_held_item() != W || QDELETED(W) || !QDELETED(src) || (loc != user && !Adjacent(user)) || _sharp) + if(!choice || QDELETED(user) || user.get_active_held_item() != W || QDELETED(W) || !QDELETED(src) || (loc != user && !Adjacent(user)) || sharp) return TRUE var/obj/item/stack/material/cloth = W diff --git a/code/game/objects/items/weapons/material/swiss.dm b/code/game/objects/items/weapons/material/swiss.dm index 122550c521bb..44f237dc8534 100644 --- a/code/game/objects/items/weapons/material/swiss.dm +++ b/code/game/objects/items/weapons/material/swiss.dm @@ -102,8 +102,8 @@ else siemens_coefficient = initial(siemens_coefficient) else - set_edge(initial(_edge)) - set_sharp(initial(_sharp)) + set_edge(initial(edge)) + set_sharp(initial(sharp)) attack_verb = closed_attack_verbs siemens_coefficient = initial(siemens_coefficient) diff --git a/code/game/objects/items/weapons/material/swords.dm b/code/game/objects/items/weapons/material/swords.dm index 535a726060f6..094dd9767a23 100644 --- a/code/game/objects/items/weapons/material/swords.dm +++ b/code/game/objects/items/weapons/material/swords.dm @@ -7,8 +7,8 @@ w_class = ITEM_SIZE_LARGE item_flags = ITEM_FLAG_IS_WEAPON armor_penetration = 10 - _sharp = TRUE - _edge = TRUE + sharp = TRUE + edge = TRUE attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") hitsound = 'sound/weapons/bladeslice.ogg' base_parry_chance = 50 diff --git a/code/game/objects/items/weapons/material/thrown.dm b/code/game/objects/items/weapons/material/thrown.dm index d5c13d31e820..a49a1f7ea61d 100644 --- a/code/game/objects/items/weapons/material/thrown.dm +++ b/code/game/objects/items/weapons/material/thrown.dm @@ -6,8 +6,8 @@ randpixel = 12 throw_speed = 10 throw_range = 15 - _sharp = TRUE - _edge = TRUE + sharp = TRUE + edge = TRUE material = /decl/material/solid/metal/steel material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME item_flags = ITEM_FLAG_IS_WEAPON diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm index 90ba45281578..bfc53022ae67 100644 --- a/code/game/objects/items/weapons/melee/energy.dm +++ b/code/game/objects/items/weapons/melee/energy.dm @@ -103,8 +103,8 @@ else obj_flags &= ~OBJ_FLAG_NO_STORAGE - set_sharp(initial(_sharp)) - set_edge(initial(_edge)) + set_sharp(initial(sharp)) + set_edge(initial(edge)) base_parry_chance = initial(base_parry_chance) armor_penetration = initial(armor_penetration) hitsound = initial(hitsound) diff --git a/code/game/objects/items/weapons/melee/energy_axe.dm b/code/game/objects/items/weapons/melee/energy_axe.dm index 7a052e548c14..ca5be697bd48 100644 --- a/code/game/objects/items/weapons/melee/energy_axe.dm +++ b/code/game/objects/items/weapons/melee/energy_axe.dm @@ -12,8 +12,8 @@ origin_tech = @'{"magnets":3,"combat":4}' active_attack_verb = list("attacked", "chopped", "cleaved", "torn", "cut") inactive_attack_verb = list("attacked", "chopped", "cleaved", "torn", "cut") - _sharp = TRUE - _edge = TRUE + sharp = TRUE + edge = TRUE base_parry_chance = 30 active_parry_chance = 30 melee_accuracy_bonus = 15 diff --git a/code/game/objects/items/weapons/melee/misc.dm b/code/game/objects/items/weapons/melee/misc.dm index bee2f881dc50..a1b4938bacf0 100644 --- a/code/game/objects/items/weapons/melee/misc.dm +++ b/code/game/objects/items/weapons/melee/misc.dm @@ -32,7 +32,7 @@ item_state = "whip" obj_flags = null _base_attack_force = 19 - _edge = TRUE + edge = TRUE origin_tech = @'{"combat":6,"materials":5}' material = /decl/material/solid/organic/leather/lizard diff --git a/code/game/objects/items/weapons/surgery_tools.dm b/code/game/objects/items/weapons/surgery_tools.dm index 68c683beb976..082bccc7a32a 100644 --- a/code/game/objects/items/weapons/surgery_tools.dm +++ b/code/game/objects/items/weapons/surgery_tools.dm @@ -99,8 +99,8 @@ icon = 'icons/obj/surgery.dmi' icon_state = "scalpel" obj_flags = OBJ_FLAG_CONDUCTIBLE - _sharp = TRUE - _edge = TRUE + sharp = TRUE + edge = TRUE w_class = ITEM_SIZE_TINY slot_flags = SLOT_EARS throw_speed = 3 @@ -160,8 +160,8 @@ /obj/item/incision_manager name = "incision management system" desc = "A true extension of the surgeon's body, this marvel combines several medical tools into one modular package." - _sharp = TRUE - _edge = TRUE + sharp = TRUE + edge = TRUE atom_damage_type = BURN icon = 'icons/obj/surgery.dmi' icon_state = "scalpel_manager_on" @@ -202,8 +202,8 @@ material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) attack_verb = list("attacked", "slashed", "sawed", "cut") - _sharp = TRUE - _edge = TRUE + sharp = TRUE + edge = TRUE pickup_sound = 'sound/foley/pickup2.ogg' drop_sound = 'sound/foley/knifedrop3.ogg' _base_attack_force = 15 diff --git a/code/game/objects/items/weapons/surgery_tools_ancient.dm b/code/game/objects/items/weapons/surgery_tools_ancient.dm index 57e06a3d62db..f6f31166bfac 100644 --- a/code/game/objects/items/weapons/surgery_tools_ancient.dm +++ b/code/game/objects/items/weapons/surgery_tools_ancient.dm @@ -55,7 +55,7 @@ name = "scalpel" desc = "A short, wickedly sharp blade used for making incisions and cutting through flesh." icon = 'icons/obj/items/surgery/scalpel.dmi' - _sharp = TRUE + sharp = TRUE _base_attack_force = 8 /obj/item/ancient_surgery/scalpel/get_tool_properties() diff --git a/code/game/objects/items/weapons/tools/screwdriver.dm b/code/game/objects/items/weapons/tools/screwdriver.dm index ae59281a05eb..d16e6c230f38 100644 --- a/code/game/objects/items/weapons/tools/screwdriver.dm +++ b/code/game/objects/items/weapons/tools/screwdriver.dm @@ -9,7 +9,7 @@ center_of_mass = @'{"x":16,"y":7}' attack_verb = list("stabbed") lock_picking_level = 5 - _sharp = TRUE + sharp = TRUE material_alteration = MAT_FLAG_ALTERATION_COLOR drop_sound = 'sound/foley/singletooldrop2.ogg' diff --git a/code/game/objects/items/weapons/tools/shears.dm b/code/game/objects/items/weapons/tools/shears.dm index e18dd843721f..b5958ab00254 100644 --- a/code/game/objects/items/weapons/tools/shears.dm +++ b/code/game/objects/items/weapons/tools/shears.dm @@ -8,8 +8,8 @@ material = /decl/material/solid/metal/steel center_of_mass = @'{"x":18,"y":10}' attack_verb = list("sheared", "cut") - _sharp = TRUE - _edge = TRUE + sharp = TRUE + edge = TRUE material_alteration = MAT_FLAG_ALTERATION_COLOR drop_sound = 'sound/foley/singletooldrop1.ogg' diff --git a/code/game/objects/items/weapons/tools/wirecutter.dm b/code/game/objects/items/weapons/tools/wirecutter.dm index e5e64b9e5d6d..7eda6a47b543 100644 --- a/code/game/objects/items/weapons/tools/wirecutter.dm +++ b/code/game/objects/items/weapons/tools/wirecutter.dm @@ -9,8 +9,8 @@ material = /decl/material/solid/metal/steel center_of_mass = @'{"x":18,"y":10}' attack_verb = list("pinched", "nipped") - _sharp = TRUE - _edge = TRUE + sharp = TRUE + edge = TRUE material_alteration = MAT_FLAG_ALTERATION_COLOR drop_sound = 'sound/foley/singletooldrop1.ogg' diff --git a/code/modules/augment/active/armblades.dm b/code/modules/augment/active/armblades.dm index 1f36cb7b1d26..8e40dc7c43e3 100644 --- a/code/modules/augment/active/armblades.dm +++ b/code/modules/augment/active/armblades.dm @@ -5,8 +5,8 @@ icon = 'icons/obj/augment.dmi' desc = "A handy utility blade for the discerning augmentee. Warranty void if used for cutting." base_parry_chance = 30 - _sharp = TRUE - _edge = TRUE + sharp = TRUE + edge = TRUE attack_verb = list("stabbed", "sliced", "cut") origin_tech = @'{"materials":1,"engineering":1,"combat":2}' material = /decl/material/solid/metal/steel diff --git a/code/modules/economy/worth_items.dm b/code/modules/economy/worth_items.dm index 74a54ebd26e2..ce2d11ae8be7 100644 --- a/code/modules/economy/worth_items.dm +++ b/code/modules/economy/worth_items.dm @@ -21,7 +21,7 @@ . += largest_tech_val if((item_flags & ITEM_FLAG_IS_WEAPON) && get_base_attack_force()) - var/weapon_value = ((get_max_weapon_force() * 15) * (1 + max(_sharp, _edge))) + var/weapon_value = ((get_max_weapon_force() * 15) * (1 + max(sharp, edge))) if(attack_cooldown <= FAST_WEAPON_COOLDOWN) weapon_value *= 1.5 else if(attack_cooldown >= SLOW_WEAPON_COOLDOWN) diff --git a/code/modules/food/utensils/utensil_hybrid.dm b/code/modules/food/utensils/utensil_hybrid.dm index c365e068dcef..1928f5aaab6c 100644 --- a/code/modules/food/utensils/utensil_hybrid.dm +++ b/code/modules/food/utensils/utensil_hybrid.dm @@ -11,8 +11,8 @@ name = "foon" desc = "It's a foon. It's much like a spoon, but much sharper." icon = 'icons/obj/food/utensils/foon.dmi' - _sharp = TRUE - _edge = TRUE + sharp = TRUE + edge = TRUE utensil_flags = UTENSIL_FLAG_SLICE | UTENSIL_FLAG_SCOOP /obj/item/utensil/foon/plastic diff --git a/code/modules/food/utensils/utensil_knife.dm b/code/modules/food/utensils/utensil_knife.dm index 59307a246cc7..fd98a7d568fd 100644 --- a/code/modules/food/utensils/utensil_knife.dm +++ b/code/modules/food/utensils/utensil_knife.dm @@ -11,8 +11,8 @@ name = "steak knife" desc = "It's a steak knife with a serrated edge." icon = 'icons/obj/food/utensils/steak_knife.dmi' - _sharp = TRUE - _edge = TRUE + sharp = TRUE + edge = TRUE utensil_flags = UTENSIL_FLAG_SLICE material = /decl/material/solid/metal/steel _base_attack_force = 6 diff --git a/code/modules/mob/living/simple_animal/crow/crow.dm b/code/modules/mob/living/simple_animal/crow/crow.dm index 227e3824cf55..66428209454e 100644 --- a/code/modules/mob/living/simple_animal/crow/crow.dm +++ b/code/modules/mob/living/simple_animal/crow/crow.dm @@ -38,7 +38,7 @@ name = "claws" gender = PLURAL attack_verb = list("clawed") - _sharp = TRUE + sharp = TRUE _base_attack_force = 7 /mob/living/simple_animal/crow/Initialize() diff --git a/code/modules/mob/living/simple_animal/hostile/commanded/nanomachines.dm b/code/modules/mob/living/simple_animal/hostile/commanded/nanomachines.dm index 0b1b55686f74..1145b90b6e8b 100644 --- a/code/modules/mob/living/simple_animal/hostile/commanded/nanomachines.dm +++ b/code/modules/mob/living/simple_animal/hostile/commanded/nanomachines.dm @@ -22,7 +22,7 @@ name = "decompilers" attack_verb = list("swarmed") _base_attack_force = 2 - _sharp = TRUE + sharp = TRUE /datum/mob_controller/aggressive/commanded/nanomachines/do_process(time_elapsed) diff --git a/code/modules/mob/living/simple_animal/hostile/hivebots/megabot.dm b/code/modules/mob/living/simple_animal/hostile/hivebots/megabot.dm index 0b286445f27c..ead786ab340c 100644 --- a/code/modules/mob/living/simple_animal/hostile/hivebots/megabot.dm +++ b/code/modules/mob/living/simple_animal/hostile/hivebots/megabot.dm @@ -42,8 +42,8 @@ name = "giant circular saw" attack_verb = list("sawed", "ripped") _base_attack_force = 15 - _sharp = TRUE - _edge = TRUE + sharp = TRUE + edge = TRUE /mob/living/simple_animal/hostile/hivebot/mega/Initialize() . = ..() diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm index 48cbcb6efc1a..61c888bceaf5 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm @@ -84,7 +84,7 @@ name = "giant horns" attack_verb = list("brutalized") _base_attack_force = 40 - _sharp = TRUE + sharp = TRUE /obj/item/natural_weapon/goatking/fire name = "burning horns" @@ -105,7 +105,7 @@ name = "horns" attack_verb = list("impaled", "stabbed") _base_attack_force = 15 - _sharp = TRUE + sharp = TRUE /mob/living/simple_animal/hostile/goat/guard/master name = "master of the guard" @@ -159,7 +159,7 @@ name = "horns" attack_verb = list("impaled", "stabbed") _base_attack_force = 15 - _sharp = TRUE + sharp = TRUE /mob/living/simple_animal/hostile/retaliate/goat/guard/master name = "master of the guard" diff --git a/code/modules/mob/living/simple_animal/hostile/viscerator.dm b/code/modules/mob/living/simple_animal/hostile/viscerator.dm index 2ab555856c13..197f1c2b3862 100644 --- a/code/modules/mob/living/simple_animal/hostile/viscerator.dm +++ b/code/modules/mob/living/simple_animal/hostile/viscerator.dm @@ -18,8 +18,8 @@ attack_verb = list("sliced", "cut") hitsound = 'sound/weapons/bladeslice.ogg' _base_attack_force = 15 - _edge = TRUE - _sharp = TRUE + edge = TRUE + sharp = TRUE /mob/living/simple_animal/hostile/viscerator/check_has_mouth() return FALSE diff --git a/code/modules/mob/living/simple_animal/natural_weapons.dm b/code/modules/mob/living/simple_animal/natural_weapons.dm index c3e1f11a780b..88c5a6a93f9c 100644 --- a/code/modules/mob/living/simple_animal/natural_weapons.dm +++ b/code/modules/mob/living/simple_animal/natural_weapons.dm @@ -31,7 +31,7 @@ attack_verb = list("bitten") hitsound = 'sound/weapons/bite.ogg' _base_attack_force = 10 - _sharp = TRUE + sharp = TRUE /obj/item/natural_weapon/bite/weak _base_attack_force = 5 @@ -49,8 +49,8 @@ name = "claws" attack_verb = list("mauled", "clawed", "slashed") _base_attack_force = 10 - _sharp = TRUE - _edge = TRUE + sharp = TRUE + edge = TRUE /obj/item/natural_weapon/claws/strong _base_attack_force = 25 @@ -77,14 +77,14 @@ gender = NEUTER attack_verb = list("sliced") atom_damage_type = BRUTE - _edge = TRUE + edge = TRUE show_in_message = TRUE /obj/item/natural_weapon/beak name = "beak" gender = NEUTER attack_verb = list("pecked", "jabbed", "poked") - _sharp = TRUE + sharp = TRUE /obj/item/natural_weapon/large _base_attack_force = 15 diff --git a/code/modules/paperwork/pen/fancy.dm b/code/modules/paperwork/pen/fancy.dm index 226052b4a870..988b0a4b60cb 100644 --- a/code/modules/paperwork/pen/fancy.dm +++ b/code/modules/paperwork/pen/fancy.dm @@ -1,7 +1,7 @@ /obj/item/pen/fancy name = "fountain pen" icon = 'icons/obj/items/pens/pen_fancy.dmi' - _sharp = TRUE + sharp = TRUE stroke_color = "#1c1713" //dark ashy brownish stroke_color_name = "dark ashy brownish" material = /decl/material/solid/metal/steel diff --git a/code/modules/paperwork/pen/quill_and_ink.dm b/code/modules/paperwork/pen/quill_and_ink.dm index 1e3b72af4c39..18cf19bd1499 100644 --- a/code/modules/paperwork/pen/quill_and_ink.dm +++ b/code/modules/paperwork/pen/quill_and_ink.dm @@ -1,7 +1,7 @@ /obj/item/pen/fancy/quill name = "quill pen" icon = 'icons/obj/items/pens/pen_quill.dmi' - _sharp = FALSE + sharp = FALSE material = /decl/material/solid/organic/skin/feathers pen_quality = TOOL_QUALITY_DEFAULT max_uses = 5 // gotta re-ink it often! diff --git a/code/modules/paperwork/pen/reagent_pen.dm b/code/modules/paperwork/pen/reagent_pen.dm index e96e7b800e5b..2493a7b139c1 100644 --- a/code/modules/paperwork/pen/reagent_pen.dm +++ b/code/modules/paperwork/pen/reagent_pen.dm @@ -1,7 +1,7 @@ /obj/item/pen/reagent atom_flags = ATOM_FLAG_OPEN_CONTAINER origin_tech = @'{"materials":2,"esoteric":5}' - _sharp = TRUE + sharp = TRUE pen_quality = TOOL_QUALITY_MEDIOCRE /obj/item/pen/reagent/Initialize() diff --git a/code/modules/projectiles/ammunition/chemdart.dm b/code/modules/projectiles/ammunition/chemdart.dm index deb37e85eed9..fa7647a4dcf1 100644 --- a/code/modules/projectiles/ammunition/chemdart.dm +++ b/code/modules/projectiles/ammunition/chemdart.dm @@ -2,7 +2,7 @@ name = "dart" icon_state = "dart" damage = 5 - _sharp = TRUE + sharp = TRUE embed = 1 //the dart is shot fast enough to pierce space suits, so I guess splintering inside the target can be a thing. Should be rare due to low damage. life_span = 15 //shorter range muzzle_type = null diff --git a/code/modules/projectiles/guns/launcher/bows/arrow.dm b/code/modules/projectiles/guns/launcher/bows/arrow.dm index 2ff38789cfd5..073c4d5928ba 100644 --- a/code/modules/projectiles/guns/launcher/bows/arrow.dm +++ b/code/modules/projectiles/guns/launcher/bows/arrow.dm @@ -5,8 +5,8 @@ plural_icon_state = ICON_STATE_WORLD + "-mult" max_icon_state = ICON_STATE_WORLD + "-max" w_class = ITEM_SIZE_NORMAL - _sharp = TRUE - _edge = FALSE + sharp = TRUE + edge = FALSE lock_picking_level = 3 material = /decl/material/solid/organic/wood/oak material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME | MAT_FLAG_ALTERATION_DESC diff --git a/code/modules/projectiles/guns/launcher/syringe_gun.dm b/code/modules/projectiles/guns/launcher/syringe_gun.dm index b4c7e754a1a6..69fa0078472d 100644 --- a/code/modules/projectiles/guns/launcher/syringe_gun.dm +++ b/code/modules/projectiles/guns/launcher/syringe_gun.dm @@ -41,7 +41,7 @@ to_chat(user, "You remove [syringe] from [src].") user.put_in_hands(syringe) syringe = null - set_sharp(initial(_sharp)) + set_sharp(initial(sharp)) SetName(initial(name)) update_icon() diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index c309c5ad1ab1..8df181e9195e 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -7,7 +7,7 @@ pass_flags = PASS_FLAG_TABLE | PASS_FLAG_GLASS | PASS_FLAG_GRILLE damage = 40 atom_damage_type = BURN - _sharp = TRUE //concentrated burns + sharp = TRUE //concentrated burns damage_flags = DAM_LASER eyeblur = 4 hitscan = 1 @@ -210,7 +210,7 @@ icon_state = "stun" fire_sound = 'sound/weapons/Taser.ogg' damage_flags = 0 - _sharp = FALSE //not a laser + sharp = FALSE //not a laser damage = 1//flavor burn! still not a laser, dmg will be reduce by energy resistance not laser resistances atom_damage_type = BURN eyeblur = 1//Some feedback that you've been hit @@ -241,8 +241,8 @@ icon_state = "omnilaser" fire_sound = 'sound/weapons/plasma_cutter.ogg' damage = 15 - _sharp = TRUE - _edge = TRUE + sharp = TRUE + edge = TRUE atom_damage_type = BURN life_span = 5 pass_flags = PASS_FLAG_TABLE @@ -264,7 +264,7 @@ fire_sound='sound/weapons/confuseray.ogg' damage = 2 agony = 7 - _sharp = FALSE + sharp = FALSE distance_falloff = 5 damage_flags = 0 atom_damage_type = STUN @@ -317,7 +317,7 @@ name = "dark matter wave" icon_state = "darkt" damage_flags = 0 - _sharp = FALSE //not a laser + sharp = FALSE //not a laser agony = 40 atom_damage_type = STUN muzzle_type = /obj/effect/projectile/muzzle/darkmattertaser @@ -329,7 +329,7 @@ icon_state = "laser" damage = 15 atom_damage_type = ELECTROCUTE //You should be safe inside a voidsuit - _sharp = FALSE //"Wide" spectrum beam + sharp = FALSE //"Wide" spectrum beam muzzle_type = /obj/effect/projectile/muzzle/pd tracer_type = /obj/effect/projectile/tracer/pd impact_type = /obj/effect/projectile/impact/pd @@ -341,7 +341,7 @@ damage = 12 agony = 8 eyeblur = 8 - _sharp = FALSE + sharp = FALSE damage_flags = 0 life_span = 8 penetration_modifier = 0.1 diff --git a/code/modules/reagents/reagent_containers/drinks/bottle.dm b/code/modules/reagents/reagent_containers/drinks/bottle.dm index cc509d959e0d..56e5f6b47206 100644 --- a/code/modules/reagents/reagent_containers/drinks/bottle.dm +++ b/code/modules/reagents/reagent_containers/drinks/bottle.dm @@ -228,7 +228,7 @@ throw_range = 5 item_state = "beer" attack_verb = list("stabbed", "slashed", "attacked") - _sharp = TRUE + sharp = TRUE obj_flags = OBJ_FLAG_HOLLOW material = /decl/material/solid/glass _base_attack_force = 9 diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 44760396d29f..6af31c901452 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -17,7 +17,7 @@ volume = 15 w_class = ITEM_SIZE_TINY slot_flags = SLOT_EARS - _sharp = TRUE + sharp = TRUE item_flags = ITEM_FLAG_NO_BLUDGEON var/mode = SYRINGE_DRAW diff --git a/code/modules/shield_generators/shield.dm b/code/modules/shield_generators/shield.dm index d9c1d32489ba..b39816fdce51 100644 --- a/code/modules/shield_generators/shield.dm +++ b/code/modules/shield_generators/shield.dm @@ -37,7 +37,7 @@ if(update_neighbors) for(var/obj/effect/shield/shield in T) shield.update_icon(FALSE) - add_overlay(image(icon = icon, icon_state = "[icon_state]_edge", dir = direction)) + add_overlay(image(icon = icon, icon_state = "[icon_state]edge", dir = direction)) // Prevents shuttles, singularities and pretty much everything else from moving the field segments away. // The only thing that is allowed to move us is the Destroy() proc. diff --git a/code/modules/tools/subtypes/axes.dm b/code/modules/tools/subtypes/axes.dm index 4a6f166f6260..20e47c48f4d9 100644 --- a/code/modules/tools/subtypes/axes.dm +++ b/code/modules/tools/subtypes/axes.dm @@ -3,8 +3,8 @@ desc = "A handheld tool for chopping things, wood, food, or people." icon_state = "preview" icon = 'icons/obj/items/tool/axes/handaxe.dmi' - _sharp = TRUE - _edge = TRUE + sharp = TRUE + edge = TRUE handle_material = /decl/material/solid/organic/wood/oak item_flags = ITEM_FLAG_IS_WEAPON origin_tech = @'{"materials":2,"combat":1}' diff --git a/code/modules/tools/subtypes/hoes.dm b/code/modules/tools/subtypes/hoes.dm index fe3e709c8ad2..6e8ed505a827 100644 --- a/code/modules/tools/subtypes/hoes.dm +++ b/code/modules/tools/subtypes/hoes.dm @@ -3,8 +3,8 @@ desc = "It's used for removing weeds or scratching your back." icon = 'icons/obj/items/tool/hoes/hoe.dmi' icon_state = "preview" - _sharp = TRUE - _edge = TRUE + sharp = TRUE + edge = TRUE attack_verb = list("slashed", "sliced", "cut", "clawed") material = /decl/material/solid/metal/steel material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME diff --git a/code/modules/tools/subtypes/pickaxes.dm b/code/modules/tools/subtypes/pickaxes.dm index a6a859e2691c..951afcf148bb 100644 --- a/code/modules/tools/subtypes/pickaxes.dm +++ b/code/modules/tools/subtypes/pickaxes.dm @@ -3,8 +3,8 @@ desc = "A heavy tool with a pick head for prospecting for minerals, and an axe head for dealing with anyone with a prior claim." icon_state = "preview" icon = 'icons/obj/items/tool/pickaxe.dmi' - _sharp = TRUE - _edge = TRUE + sharp = TRUE + edge = TRUE w_class = ITEM_SIZE_HUGE handle_material = /decl/material/solid/organic/wood/oak _base_attack_force = 15 diff --git a/code/modules/tools/subtypes/shovel.dm b/code/modules/tools/subtypes/shovel.dm index f80626f07adb..3d8afd26eaec 100644 --- a/code/modules/tools/subtypes/shovel.dm +++ b/code/modules/tools/subtypes/shovel.dm @@ -5,8 +5,8 @@ icon_state = "preview" // mapping preview icon slot_flags = SLOT_LOWER_BODY w_class = ITEM_SIZE_LARGE - _edge = TRUE - _sharp = TRUE + edge = TRUE + sharp = TRUE attack_verb = list("bashed", "bludgeoned", "thrashed", "whacked") handle_material = /decl/material/solid/organic/wood/oak _base_attack_force = 8 @@ -36,8 +36,8 @@ icon = 'icons/obj/items/tool/shovels/spade.dmi' icon_state = "preview" // mapping preview icon w_class = ITEM_SIZE_SMALL - _edge = FALSE - _sharp = FALSE + edge = FALSE + sharp = FALSE slot_flags = SLOT_LOWER_BODY attack_verb = list("bashed", "bludgeoned", "thrashed", "whacked") material_alteration = 0 diff --git a/code/modules/tools/subtypes/xenoarchaeology_picks.dm b/code/modules/tools/subtypes/xenoarchaeology_picks.dm index e6d3ccdedad8..ebe8b03af09b 100644 --- a/code/modules/tools/subtypes/xenoarchaeology_picks.dm +++ b/code/modules/tools/subtypes/xenoarchaeology_picks.dm @@ -7,7 +7,7 @@ material = /decl/material/solid/metal/chromium matter = list(/decl/material/solid/metal/steel = MATTER_AMOUNT_SECONDARY) w_class = ITEM_SIZE_SMALL - _sharp = TRUE + sharp = TRUE abstract_type = /obj/item/tool/xeno material_alteration = 0 handle_material = /decl/material/solid/organic/plastic @@ -42,7 +42,7 @@ _base_attack_force = 1 attack_verb = list("prodded", "attacked") desc = "A wood-handled brush with thick metallic wires for clearing away dust and loose scree." - _sharp = FALSE + sharp = FALSE material = /decl/material/solid/metal/steel handle_material = /decl/material/solid/organic/wood/oak excavation_amount = 1 diff --git a/code/modules/xenoarcheaology/tools/core_sampler.dm b/code/modules/xenoarcheaology/tools/core_sampler.dm index 2ef87ee56ae8..21d5bd0cb6dd 100644 --- a/code/modules/xenoarcheaology/tools/core_sampler.dm +++ b/code/modules/xenoarcheaology/tools/core_sampler.dm @@ -51,7 +51,7 @@ icon_state = "sliver1" randpixel = 8 w_class = ITEM_SIZE_TINY - _sharp = TRUE + sharp = TRUE material = /decl/material/solid/stone/sandstone material_health_multiplier = 0.25 diff --git a/mods/content/item_sharpening/item_sharpen.dm b/mods/content/item_sharpening/item_sharpen.dm index bc0d4480b0f7..5212ad94ab93 100644 --- a/mods/content/item_sharpening/item_sharpen.dm +++ b/mods/content/item_sharpening/item_sharpen.dm @@ -42,7 +42,7 @@ playsound(loc, 'sound/foley/knife1.ogg', 50) user.visible_message("\The [user] sharpens \the [src] with \the [sharpening_with].") else - to_chat(user, SPAN_WARNING("\The [src] cannot be [initial(_sharp) ? "further sharpened" : "sharpened"] with \the [sharpening_with].")) + to_chat(user, SPAN_WARNING("\The [src] cannot be [initial(sharp) ? "further sharpened" : "sharpened"] with \the [sharpening_with].")) return TRUE // We don't override sharp because it's probably still pointy even if it isn't sharpened. diff --git a/mods/content/psionics/system/psionics/equipment/psipower_blade.dm b/mods/content/psionics/system/psionics/equipment/psipower_blade.dm index 5863c9d2c2cf..94163e320127 100644 --- a/mods/content/psionics/system/psionics/equipment/psipower_blade.dm +++ b/mods/content/psionics/system/psionics/equipment/psipower_blade.dm @@ -1,8 +1,8 @@ /obj/item/ability/psionic/psiblade name = "psychokinetic slash" _base_attack_force = 10 - _sharp = TRUE - _edge = TRUE + sharp = TRUE + edge = TRUE maintain_cost = 1 icon_state = "psiblade_short" diff --git a/mods/gamemodes/cult/mobs/constructs/constructs.dm b/mods/gamemodes/cult/mobs/constructs/constructs.dm index 42d61584c70b..1eb37f6980bd 100644 --- a/mods/gamemodes/cult/mobs/constructs/constructs.dm +++ b/mods/gamemodes/cult/mobs/constructs/constructs.dm @@ -174,7 +174,7 @@ gender = NEUTER attack_verb = list("slashed", "tore into") hitsound = 'sound/weapons/rapidslice.ogg' - _edge = TRUE + edge = TRUE _base_attack_force = 25 /mob/living/simple_animal/construct/wraith/mind_initialize() @@ -262,7 +262,7 @@ gender = NEUTER attack_verb = list("violently stabbed", "ran through") hitsound = 'sound/weapons/pierce.ogg' - _sharp = TRUE + sharp = TRUE _base_attack_force = 25 ////////////////HUD////////////////////// From 762b0360e8056321d18ef710ee147aa1de1d23ae Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Wed, 15 Jan 2025 23:07:34 +1100 Subject: [PATCH 026/120] Attack dexterity is bypassed for items in rigs. --- code/_onclick/item_attack.dm | 2 ++ code/game/objects/items/__item.dm | 16 ++++++++++++++-- code/modules/mob/living/living.dm | 5 +++-- code/modules/projectiles/gun.dm | 19 +++++++++++++------ code/modules/projectiles/secure.dm | 8 -------- 5 files changed, 32 insertions(+), 18 deletions(-) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 075995076d43..7a308c7176cc 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -26,6 +26,8 @@ avoid code duplication. This includes items that may sometimes act as a standard // If TRUE, prevent afterattack from running. /obj/item/proc/resolve_attackby(atom/A, mob/user, var/click_params) + if(!user.check_dexterity(get_required_attack_dexterity())) + return TRUE if(!(item_flags & ITEM_FLAG_NO_PRINT)) add_fingerprint(user) return A.attackby(src, user, click_params) diff --git a/code/game/objects/items/__item.dm b/code/game/objects/items/__item.dm index 20c732782fa0..620adaa6447b 100644 --- a/code/game/objects/items/__item.dm +++ b/code/game/objects/items/__item.dm @@ -120,6 +120,18 @@ /// Can this item knock someone out if used as a weapon? Overridden for natural weapons as a nerf to simplemobs. var/weapon_can_knock_prone = TRUE +/// Returns a dexterity value required to use this item as a weapon. +/obj/item/proc/get_required_attack_dexterity() + // We can likely assume that if we're located inside a rig, then the wearer + // has the appropriate dexterity to wear and use the rig, even if they aren't + // manually dexterous; specifically useful for things like baxxid and drakes. + var/obj/item/rig/rig = get_recursive_loc_of_type(/obj/item/rig) + return istype(rig) ? DEXTERITY_NONE : needs_attack_dexterity + +// Returns a dexterity value required to interact with this item at all, such as picking it up. +/obj/item/get_required_interaction_dexterity() + return needs_interaction_dexterity + /obj/item/get_color() if(paint_color) return paint_color @@ -571,11 +583,11 @@ return FALSE /obj/item/proc/user_can_attack_with(mob/user, silent = FALSE) - return !needs_attack_dexterity || user.check_dexterity(needs_attack_dexterity, silent = silent) + return user.check_dexterity(get_required_attack_dexterity(), silent = silent) /obj/item/attackby(obj/item/used_item, mob/user) // if can_wield is false we still need to call parent for storage objects to work properly - var/can_wield = user_can_attack_with(user, silent = TRUE) + var/can_wield = used_item.user_can_attack_with(user, silent = TRUE) if(can_wield && try_slapcrafting(used_item, user)) return TRUE diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index a9f88a6c596c..c2715cc5572f 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1945,11 +1945,12 @@ default behaviour is: var/datum/inventory_slot/gripper/slot = get_inventory_slot_datum(empty_hand) if(!istype(slot)) continue + var/req_item_dex = item.get_required_attack_dexterity() if(slot.requires_organ_tag) var/obj/item/organ/external/hand = GET_EXTERNAL_ORGAN(src, slot.requires_organ_tag) - if(istype(hand) && hand.is_usable() && (!item.needs_attack_dexterity || hand.get_manual_dexterity() >= item.needs_attack_dexterity)) + if(istype(hand) && hand.is_usable() && (!req_item_dex || hand.get_manual_dexterity() >= req_item_dex)) return TRUE - else if(!item.needs_attack_dexterity || slot.dexterity >= item.needs_attack_dexterity) + else if(!req_item_dex || slot.dexterity >= req_item_dex) return TRUE return FALSE diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index d01aa247e4b0..5d659a59b210 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -45,6 +45,7 @@ drop_sound = 'sound/foley/drop1.ogg' pickup_sound = 'sound/foley/pickup2.ogg' can_be_twohanded = TRUE // also checks one_hand_penalty + needs_attack_dexterity = DEXTERITY_WEAPONS var/fire_verb = "fire" var/waterproof = FALSE @@ -193,15 +194,20 @@ /obj/item/gun/proc/special_check(var/mob/user) if(!isliving(user)) - return 0 - if(!user.check_dexterity(DEXTERITY_WEAPONS)) - return 0 + return FALSE + + if(!user.check_dexterity(get_required_attack_dexterity())) + return FALSE + + if(is_secure_gun() && !free_fire() && (!authorized_modes[sel_mode] || !registered_owner)) + audible_message(SPAN_WARNING("\The [src] buzzes, refusing to fire."), hearing_distance = 3) + playsound(loc, 'sound/machines/buzz-sigh.ogg', 10, 0) + return FALSE var/mob/living/M = user if(!safety() && world.time > last_safety_check + 5 MINUTES && !user.skill_check(SKILL_WEAPONS, SKILL_BASIC)) if(prob(30)) toggle_safety() - return 1 if(M.has_genetic_condition(GENE_COND_CLUMSY) && prob(40)) //Clumsy handling var/obj/P = consume_next_projectile() @@ -218,8 +224,9 @@ M.try_unequip(src) else handle_click_empty(user) - return 0 - return 1 + return FALSE + + return TRUE /obj/item/gun/emp_act(severity) for(var/obj/O in contents) diff --git a/code/modules/projectiles/secure.dm b/code/modules/projectiles/secure.dm index 241a0e0a8aff..6902b3bddb1e 100644 --- a/code/modules/projectiles/secure.dm +++ b/code/modules/projectiles/secure.dm @@ -99,14 +99,6 @@ var/decl/security_state/security_state = GET_DECL(global.using_map.security_state) return security_state.current_security_level_is_same_or_higher_than(security_state.high_security_level) -/obj/item/gun/special_check() - if(is_secure_gun() && !free_fire() && (!authorized_modes[sel_mode] || !registered_owner)) - audible_message(SPAN_WARNING("\The [src] buzzes, refusing to fire."), hearing_distance = 3) - playsound(loc, 'sound/machines/buzz-sigh.ogg', 10, 0) - return 0 - - . = ..() - /obj/item/gun/get_next_firemode() if(!is_secure_gun()) return ..() From b6ba8e1d5dc43dd2987bbd4437d32025a5435637 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 19 Jan 2025 19:52:13 +1100 Subject: [PATCH 027/120] Allowing targets like tables to override required attack dexterity. --- code/_onclick/item_attack.dm | 2 +- code/game/atoms.dm | 6 ++++ code/game/objects/items/__item.dm | 10 ++++--- code/game/objects/structures/racks.dm | 6 ++++ code/game/objects/structures/tables.dm | 40 +++++++++++++++----------- code/modules/mob/living/living.dm | 2 +- code/modules/projectiles/gun.dm | 2 +- 7 files changed, 44 insertions(+), 24 deletions(-) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 7a308c7176cc..82407fd4ddd3 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -26,7 +26,7 @@ avoid code duplication. This includes items that may sometimes act as a standard // If TRUE, prevent afterattack from running. /obj/item/proc/resolve_attackby(atom/A, mob/user, var/click_params) - if(!user.check_dexterity(get_required_attack_dexterity())) + if(!user.check_dexterity(get_required_attack_dexterity(user, A))) return TRUE if(!(item_flags & ITEM_FLAG_NO_PRINT)) add_fingerprint(user) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index fc3e86a037a2..196f4cc44e5c 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -997,5 +997,11 @@ /atom/proc/can_drink_from(mob/user) return ATOM_IS_OPEN_CONTAINER(src) && reagents?.total_volume && user.check_has_mouth() +/atom/proc/adjust_required_attack_dexterity(mob/user, required_dexterity) + if(storage) // TODO: possibly check can_be_inserted() to avoid being able to shoot mirrors as a drake. + return DEXTERITY_HOLD_ITEM + return required_dexterity + /atom/proc/immune_to_floor_hazards() return !simulated + diff --git a/code/game/objects/items/__item.dm b/code/game/objects/items/__item.dm index 620adaa6447b..fc0d7f6b08f1 100644 --- a/code/game/objects/items/__item.dm +++ b/code/game/objects/items/__item.dm @@ -121,12 +121,14 @@ var/weapon_can_knock_prone = TRUE /// Returns a dexterity value required to use this item as a weapon. -/obj/item/proc/get_required_attack_dexterity() +/obj/item/proc/get_required_attack_dexterity(mob/user, atom/target) // We can likely assume that if we're located inside a rig, then the wearer // has the appropriate dexterity to wear and use the rig, even if they aren't // manually dexterous; specifically useful for things like baxxid and drakes. var/obj/item/rig/rig = get_recursive_loc_of_type(/obj/item/rig) - return istype(rig) ? DEXTERITY_NONE : needs_attack_dexterity + . = istype(rig) ? DEXTERITY_NONE : needs_attack_dexterity + if(istype(target)) + . = target.adjust_required_attack_dexterity(user, .) // Returns a dexterity value required to interact with this item at all, such as picking it up. /obj/item/get_required_interaction_dexterity() @@ -582,8 +584,8 @@ return TRUE return FALSE -/obj/item/proc/user_can_attack_with(mob/user, silent = FALSE) - return user.check_dexterity(get_required_attack_dexterity(), silent = silent) +/obj/item/proc/user_can_attack_with(mob/user, atom/target, silent = FALSE) + return user.check_dexterity(get_required_attack_dexterity(user, target), silent = silent) /obj/item/attackby(obj/item/used_item, mob/user) // if can_wield is false we still need to call parent for storage objects to work properly diff --git a/code/game/objects/structures/racks.dm b/code/game/objects/structures/racks.dm index 3ade37d94fe8..2cbeb5bb7f58 100644 --- a/code/game/objects/structures/racks.dm +++ b/code/game/objects/structures/racks.dm @@ -29,6 +29,12 @@ I.pixel_y = max(3-i*3, -3) + 1 I.pixel_z = 0 +/obj/structure/rack/adjust_required_attack_dexterity(mob/user, required_dexterity) + // Let people put stuff on tables without necessarily being able to use a gun or such. + if(user?.check_intent(I_FLAG_HELP)) + return DEXTERITY_HOLD_ITEM + return ..() + /obj/structure/rack/attackby(obj/item/O, mob/user, click_params) . = ..() if(!. && !isrobot(user) && O.loc == user && user.try_unequip(O, loc)) diff --git a/code/game/objects/structures/tables.dm b/code/game/objects/structures/tables.dm index 459216c264a5..68fba3649734 100644 --- a/code/game/objects/structures/tables.dm +++ b/code/game/objects/structures/tables.dm @@ -41,12 +41,6 @@ /obj/structure/table/should_have_alpha_mask() return simulated && isturf(loc) && !(locate(/obj/structure/table) in get_step(loc, SOUTH)) -/obj/structure/table/clear_connections() - connections = null - -/obj/structure/table/set_connections(dirs, other_dirs) - connections = dirs_to_corner_states(dirs) - /obj/structure/table/Initialize() if(ispath(additional_reinf_material, /decl/material)) additional_reinf_material = GET_DECL(additional_reinf_material) @@ -69,6 +63,29 @@ update_connections(TRUE) update_icon() +/obj/structure/table/Destroy() + var/turf/oldloc = loc + additional_reinf_material = null + . = ..() + if(istype(oldloc)) + for(var/obj/structure/table/table in range(oldloc, 1)) + if(QDELETED(table)) + continue + table.update_connections(FALSE) + table.update_icon() + +/obj/structure/table/adjust_required_attack_dexterity(mob/user, required_dexterity) + // Let people put stuff on tables without necessarily being able to use a gun or such. + if(user?.check_intent(I_FLAG_HELP)) + return DEXTERITY_HOLD_ITEM + return ..() + +/obj/structure/table/clear_connections() + connections = null + +/obj/structure/table/set_connections(dirs, other_dirs) + connections = dirs_to_corner_states(dirs) + /obj/structure/table/get_material_health_modifier() . = additional_reinf_material ? 0.75 : 0.5 @@ -106,17 +123,6 @@ felted = FALSE additional_reinf_material = null -/obj/structure/table/Destroy() - var/turf/oldloc = loc - additional_reinf_material = null - . = ..() - if(istype(oldloc)) - for(var/obj/structure/table/table in range(oldloc, 1)) - if(QDELETED(table)) - continue - table.update_connections(FALSE) - table.update_icon() - /obj/structure/table/can_dismantle(mob/user) . = ..() if(.) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index c2715cc5572f..db36e34032c9 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1945,7 +1945,7 @@ default behaviour is: var/datum/inventory_slot/gripper/slot = get_inventory_slot_datum(empty_hand) if(!istype(slot)) continue - var/req_item_dex = item.get_required_attack_dexterity() + var/req_item_dex = item.get_required_attack_dexterity(src) if(slot.requires_organ_tag) var/obj/item/organ/external/hand = GET_EXTERNAL_ORGAN(src, slot.requires_organ_tag) if(istype(hand) && hand.is_usable() && (!req_item_dex || hand.get_manual_dexterity() >= req_item_dex)) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 5d659a59b210..d99abdef1e63 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -196,7 +196,7 @@ if(!isliving(user)) return FALSE - if(!user.check_dexterity(get_required_attack_dexterity())) + if(!user.check_dexterity(get_required_attack_dexterity(user))) return FALSE if(is_secure_gun() && !free_fire() && (!authorized_modes[sel_mode] || !registered_owner)) From 8ba42a21a07466af631be984d34fa4facdb55176 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 19 Jan 2025 21:24:01 +1100 Subject: [PATCH 028/120] Fixes mundane fountains being a light source. --- code/game/objects/structures/fountain.dm | 34 +++++++++++++----------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/code/game/objects/structures/fountain.dm b/code/game/objects/structures/fountain.dm index 7df7c3ee3074..e2bc08d9fa21 100644 --- a/code/game/objects/structures/fountain.dm +++ b/code/game/objects/structures/fountain.dm @@ -1,20 +1,22 @@ //the fountain of youth/unyouth /obj/structure/fountain - name = "strange fountain" - desc = "The water from the spout is still as if frozen in time, yet the water in the base ripples perpetually." - icon = 'icons/obj/fountain.dmi' - icon_state = "fountain" - density = TRUE - anchored = TRUE - pixel_x = -16 - var/used = FALSE + name = "strange fountain" + desc = "The water from the spout is still as if frozen in time, yet the water in the base ripples perpetually." + icon = 'icons/obj/fountain.dmi' + icon_state = "fountain" + density = TRUE + anchored = TRUE + pixel_x = -16 + light_range = 5 + light_power = 0.5 + var/used = FALSE var/increase_age_prob = (100 / 6) /obj/structure/fountain/Initialize(ml, _mat, _reinf_mat) + if(light_range && light_power) + light_color = get_random_colour(lower = 190) . = ..() - light_color = get_random_colour(lower = 190) - set_light(5, 0.5, light_color) /obj/structure/fountain/attack_hand(var/mob/user) @@ -48,7 +50,7 @@ L.flash_eyes(3) SET_STATUS_MAX(L, STAT_BLURRY, 9) - visible_message("\The [src] erupts in a bright flash of light!") + visible_message(SPAN_WARNING("\The [src] erupts in a bright flash of light!")) playsound(src,'sound/items/time.ogg',100) var/old_age = user.get_age() @@ -65,19 +67,19 @@ new_age = max(new_age, min_age) // This will clamp to the max defined age already so only need to min() if(new_age == old_age) - to_chat(user, "You touch the fountain, and feel your memories sifted through by a great presence. Then, it withdraws, leaving you unchanged.") + to_chat(user, SPAN_CULT("You touch the fountain, and feel your memories sifted through by a great presence. Then, it withdraws, leaving you unchanged.")) else user.set_age(new_age) if(new_age < old_age) - to_chat(user, "You touch the fountain. Everything stops - then reverses. You relive in an instant the events of your life. The fountain, yesterday's lunch, your first love, your first kiss. It all feels as though it just happened moments ago. Then it feels like it never happened at all. Time reverses back into normality and continues its advance. You feel great, but why are you here?") + to_chat(user, SPAN_CULT("You touch the fountain. Everything stops - then reverses. You relive in an instant the events of your life. The fountain, yesterday's lunch, your first love, your first kiss. It all feels as though it just happened moments ago. Then it feels like it never happened at all. Time reverses back into normality and continues its advance. You feel great, but why are you here?")) user.became_younger = TRUE else - to_chat(user, "You touch the fountain. All the memories of your life seem to fade into the distant past as seconds drag like years. You feel the inexplicable sensation of your skin tightening and thinning across your entire body as your muscles degrade and your joints weaken. Time returns to its 'normal' pace. You can only just barely remember touching the fountain.") + to_chat(user, SPAN_CULT("You touch the fountain. All the memories of your life seem to fade into the distant past as seconds drag like years. You feel the inexplicable sensation of your skin tightening and thinning across your entire body as your muscles degrade and your joints weaken. Time returns to its 'normal' pace. You can only just barely remember touching the fountain.")) user.became_older = TRUE SET_HAIR_COLOR(user, COLOR_GRAY80, FALSE) var/max_age = age.standalone_value_descriptors[age.standalone_value_descriptors[length(age.standalone_value_descriptors)]] if(new_age >= max_age) - to_chat(user, "The burden of the years is too much, and you are reduced to dust.") + to_chat(user, SPAN_CULT("The burden of the years is too much, and you are reduced to dust.")) user.dust() used = TRUE @@ -93,6 +95,8 @@ used = TRUE material_alteration = MAT_FLAG_ALTERATION_ALL atom_flags = ATOM_FLAG_OPEN_CONTAINER | ATOM_FLAG_CLIMBABLE + light_range = null + light_power = null /obj/structure/fountain/mundane/Initialize(ml, _mat, _reinf_mat) . = ..() From a4408fb811a9380e7e2f5dcd0f8332a76a7a6116 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 19 Jan 2025 21:26:20 +1100 Subject: [PATCH 029/120] Replacing cultannounce with a macro. --- code/_macros.dm | 55 ++++++++++--------- code/game/objects/structures/fountain.dm | 8 +-- .../hostile/retaliate/king_of_goats.dm | 6 +- 3 files changed, 35 insertions(+), 34 deletions(-) diff --git a/code/_macros.dm b/code/_macros.dm index 5cba5893825f..dce1ac770a60 100644 --- a/code/_macros.dm +++ b/code/_macros.dm @@ -147,34 +147,35 @@ #define SPAN_STYLE(S, X) "[X]" #define SPAN_CLASS(C, X) "[X]" -#define SPAN_ITALIC(X) SPAN_CLASS("italic", X) -#define SPAN_BOLD(X) SPAN_CLASS("bold", X) -#define SPAN_NOTICE(X) SPAN_CLASS("notice", X) -#define SPAN_WARNING(X) SPAN_CLASS("warning", X) -#define SPAN_DANGER(X) SPAN_CLASS("danger", X) -#define SPAN_ROSE(X) SPAN_CLASS("rose", X) -#define SPAN_OCCULT(X) SPAN_CLASS("cult", X) -#define SPAN_MFAUNA(X) SPAN_CLASS("mfauna", X) -#define SPAN_SUBTLE(X) SPAN_CLASS("subtle", X) -#define SPAN_INFO(X) SPAN_CLASS("info", X) -#define SPAN_RED(X) SPAN_CLASS("font_red", X) -#define SPAN_ORANGE(X) SPAN_CLASS("font_orange", X) -#define SPAN_YELLOW(X) SPAN_CLASS("font_yellow", X) -#define SPAN_GREEN(X) SPAN_CLASS("font_green", X) -#define SPAN_BLUE(X) SPAN_CLASS("font_blue", X) -#define SPAN_VIOLET(X) SPAN_CLASS("font_violet", X) -#define SPAN_PURPLE(X) SPAN_CLASS("font_purple", X) -#define SPAN_GREY(X) SPAN_CLASS("font_grey", X) -#define SPAN_MAROON(X) SPAN_CLASS("font_maroon", X) -#define SPAN_PINK(X) SPAN_CLASS("font_pink", X) -#define SPAN_PALEPINK(X) SPAN_CLASS("font_palepink", X) -#define SPAN_SINISTER(X) SPAN_CLASS("sinister", X) -#define SPAN_MODERATE(X) SPAN_CLASS("moderate", X) +#define SPAN_ITALIC(X) SPAN_CLASS("italic", X) +#define SPAN_BOLD(X) SPAN_CLASS("bold", X) +#define SPAN_NOTICE(X) SPAN_CLASS("notice", X) +#define SPAN_WARNING(X) SPAN_CLASS("warning", X) +#define SPAN_DANGER(X) SPAN_CLASS("danger", X) +#define SPAN_ROSE(X) SPAN_CLASS("rose", X) +#define SPAN_OCCULT(X) SPAN_CLASS("cult", X) +#define SPAN_CULT_ANNOUNCE(X) SPAN_CLASS("cultannounce", X) +#define SPAN_MFAUNA(X) SPAN_CLASS("mfauna", X) +#define SPAN_SUBTLE(X) SPAN_CLASS("subtle", X) +#define SPAN_INFO(X) SPAN_CLASS("info", X) +#define SPAN_RED(X) SPAN_CLASS("font_red", X) +#define SPAN_ORANGE(X) SPAN_CLASS("font_orange", X) +#define SPAN_YELLOW(X) SPAN_CLASS("font_yellow", X) +#define SPAN_GREEN(X) SPAN_CLASS("font_green", X) +#define SPAN_BLUE(X) SPAN_CLASS("font_blue", X) +#define SPAN_VIOLET(X) SPAN_CLASS("font_violet", X) +#define SPAN_PURPLE(X) SPAN_CLASS("font_purple", X) +#define SPAN_GREY(X) SPAN_CLASS("font_grey", X) +#define SPAN_MAROON(X) SPAN_CLASS("font_maroon", X) +#define SPAN_PINK(X) SPAN_CLASS("font_pink", X) +#define SPAN_PALEPINK(X) SPAN_CLASS("font_palepink", X) +#define SPAN_SINISTER(X) SPAN_CLASS("sinister", X) +#define SPAN_MODERATE(X) SPAN_CLASS("moderate", X) // placeholders -#define SPAN_GOOD(X) SPAN_GREEN(X) -#define SPAN_NEUTRAL(X) SPAN_BLUE(X) -#define SPAN_BAD(X) SPAN_RED(X) -#define SPAN_HARDSUIT(X) SPAN_BLUE(X) +#define SPAN_GOOD(X) SPAN_GREEN(X) +#define SPAN_NEUTRAL(X) SPAN_BLUE(X) +#define SPAN_BAD(X) SPAN_RED(X) +#define SPAN_HARDSUIT(X) SPAN_BLUE(X) #define CSS_CLASS_RADIO "radio" diff --git a/code/game/objects/structures/fountain.dm b/code/game/objects/structures/fountain.dm index e2bc08d9fa21..e28689d70a97 100644 --- a/code/game/objects/structures/fountain.dm +++ b/code/game/objects/structures/fountain.dm @@ -67,19 +67,19 @@ new_age = max(new_age, min_age) // This will clamp to the max defined age already so only need to min() if(new_age == old_age) - to_chat(user, SPAN_CULT("You touch the fountain, and feel your memories sifted through by a great presence. Then, it withdraws, leaving you unchanged.")) + to_chat(user, SPAN_CULT_ANNOUNCE("You touch the fountain, and feel your memories sifted through by a great presence. Then, it withdraws, leaving you unchanged.")) else user.set_age(new_age) if(new_age < old_age) - to_chat(user, SPAN_CULT("You touch the fountain. Everything stops - then reverses. You relive in an instant the events of your life. The fountain, yesterday's lunch, your first love, your first kiss. It all feels as though it just happened moments ago. Then it feels like it never happened at all. Time reverses back into normality and continues its advance. You feel great, but why are you here?")) + to_chat(user, SPAN_CULT_ANNOUNCE("You touch the fountain. Everything stops - then reverses. You relive in an instant the events of your life. The fountain, yesterday's lunch, your first love, your first kiss. It all feels as though it just happened moments ago. Then it feels like it never happened at all. Time reverses back into normality and continues its advance. You feel great, but why are you here?")) user.became_younger = TRUE else - to_chat(user, SPAN_CULT("You touch the fountain. All the memories of your life seem to fade into the distant past as seconds drag like years. You feel the inexplicable sensation of your skin tightening and thinning across your entire body as your muscles degrade and your joints weaken. Time returns to its 'normal' pace. You can only just barely remember touching the fountain.")) + to_chat(user, SPAN_CULT_ANNOUNCE("You touch the fountain. All the memories of your life seem to fade into the distant past as seconds drag like years. You feel the inexplicable sensation of your skin tightening and thinning across your entire body as your muscles degrade and your joints weaken. Time returns to its 'normal' pace. You can only just barely remember touching the fountain.")) user.became_older = TRUE SET_HAIR_COLOR(user, COLOR_GRAY80, FALSE) var/max_age = age.standalone_value_descriptors[age.standalone_value_descriptors[length(age.standalone_value_descriptors)]] if(new_age >= max_age) - to_chat(user, SPAN_CULT("The burden of the years is too much, and you are reduced to dust.")) + to_chat(user, SPAN_CULT_ANNOUNCE("The burden of the years is too much, and you are reduced to dust.")) user.dust() used = TRUE diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm index 61c888bceaf5..faae358b3884 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm @@ -53,7 +53,7 @@ var/stun_chance = 5 //chance per attack to Weaken target /mob/living/simple_animal/hostile/goat/king/proc/OnDeath() - visible_message("\The [src] lets loose a terrific wail as its wounds close shut with a flash of light, and its eyes glow even brighter than before!") + visible_message(SPAN_CULT_ANNOUNCE("\The [src] lets loose a terrific wail as its wounds close shut with a flash of light, and its eyes glow even brighter than before!")) new /mob/living/simple_animal/hostile/goat/king/phase2(src.loc) qdel(src) @@ -202,7 +202,7 @@ current_damtype = ELECTROCUTE else if(prob(5)) //earthquake spell - visible_message("\The [src]' eyes begin to glow ominously as dust and debris in the area is kicked up in a light breeze.") + visible_message(SPAN_CULT_ANNOUNCE("\The [src]' eyes begin to glow ominously as dust and debris in the area is kicked up in a light breeze.")) ai?.pause() if(do_after(src, 6 SECONDS, src)) var/initial_brute = get_damage(BRUTE) @@ -230,7 +230,7 @@ boss_theme = play_looping_sound(src, sound_id, 'sound/music/Visager-Miniboss_Fight.ogg', volume = 10, range = 8, falloff = 4, prefer_mute = TRUE) stun_chance = 10 update_icon() - visible_message("\The [src]' wounds close with a flash, and when he emerges, he's even larger than before!") + visible_message(SPAN_CULT_ANNOUNCE("\The [src]' wounds close with a flash, and when he emerges, he's even larger than before!")) /mob/living/simple_animal/hostile/goat/king/phase2/on_update_icon() ..() From 02fa990541cf38880caa8c8c6b5371136cf06fee Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 19 Jan 2025 21:29:51 +1100 Subject: [PATCH 030/120] Robot debris reskin for fantasy map. --- mods/content/fantasy/datum/overrides.dm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mods/content/fantasy/datum/overrides.dm b/mods/content/fantasy/datum/overrides.dm index 0726866427dc..64736e84bf8e 100644 --- a/mods/content/fantasy/datum/overrides.dm +++ b/mods/content/fantasy/datum/overrides.dm @@ -56,3 +56,8 @@ // Rename wooden prostheses /decl/bodytype/prosthetic/wooden name = "carved wooden" // weird to call it 'crude' when it's cutting-edge for the setting + +// Just a fun override for when robot debris shows up in maint. +/obj/effect/decal/cleanable/blood/gibs/robot + name = "mysterious debris" + desc = "Some kind of complex, oily detritus. What could it be?" From ec2e8d287a53a880d16ec27959c6194593e7936b Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 19 Jan 2025 21:32:44 +1100 Subject: [PATCH 031/120] Updating the random trash spawner for the fantasy map. --- code/game/objects/random/subtypes/misc.dm | 1 + mods/content/fantasy/datum/overrides.dm | 24 ++++++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/code/game/objects/random/subtypes/misc.dm b/code/game/objects/random/subtypes/misc.dm index c0dcab1b2c99..8ed2df78bc34 100644 --- a/code/game/objects/random/subtypes/misc.dm +++ b/code/game/objects/random/subtypes/misc.dm @@ -164,6 +164,7 @@ /obj/effect/decal/cleanable/ash, /obj/effect/decal/cleanable/generic, /obj/effect/decal/cleanable/flour, + /obj/effect/decal/cleanable/filth, /obj/effect/decal/cleanable/dirt/visible, /obj/item/remains/robot ) diff --git a/mods/content/fantasy/datum/overrides.dm b/mods/content/fantasy/datum/overrides.dm index 64736e84bf8e..b1f1137ad79f 100644 --- a/mods/content/fantasy/datum/overrides.dm +++ b/mods/content/fantasy/datum/overrides.dm @@ -57,7 +57,29 @@ /decl/bodytype/prosthetic/wooden name = "carved wooden" // weird to call it 'crude' when it's cutting-edge for the setting -// Just a fun override for when robot debris shows up in maint. +// Just some fun overrides for when robot debris shows up in maint. /obj/effect/decal/cleanable/blood/gibs/robot name = "mysterious debris" desc = "Some kind of complex, oily detritus. What could it be?" + +/obj/item/remains/robot + name = "mysterious remains" + desc = "The oily remains of some complex, metallic object. What could they be from?" + +// Override to remove non-fantasy stuff. +/obj/random/trash/spawn_choices() + var/static/list/spawnable_choices = list( + /obj/item/remains/lizard, + /obj/effect/decal/cleanable/blood/gibs/robot, + /obj/effect/decal/cleanable/spiderling_remains, + /obj/item/remains/mouse, + /obj/effect/decal/cleanable/vomit, + /obj/effect/decal/cleanable/blood/splatter, + /obj/effect/decal/cleanable/ash, + /obj/effect/decal/cleanable/generic, + /obj/effect/decal/cleanable/flour, + /obj/effect/decal/cleanable/filth, + /obj/effect/decal/cleanable/dirt/visible, + /obj/item/remains/robot + ) + return spawnable_choices From f29c32447e88a5f02f7f002e6640df0016b4c9eb Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 19 Jan 2025 21:33:55 +1100 Subject: [PATCH 032/120] Oil updates color on spawn. --- code/game/objects/effects/decals/Cleanable/robots.dm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/game/objects/effects/decals/Cleanable/robots.dm b/code/game/objects/effects/decals/Cleanable/robots.dm index 330acc9f3ce0..efeaac361390 100644 --- a/code/game/objects/effects/decals/Cleanable/robots.dm +++ b/code/game/objects/effects/decals/Cleanable/robots.dm @@ -44,6 +44,11 @@ chemical = /decl/material/liquid/lube cleanable_scent = "industrial lubricant" +/obj/effect/decal/cleanable/blood/oil/Initialize(mapload) + if(basecolor) + set_color(basecolor) + . = ..() + /obj/effect/decal/cleanable/blood/oil/dry() return From bf6a0a3dae6cc81024a15272f4d259622bacd787 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 19 Jan 2025 21:36:04 +1100 Subject: [PATCH 033/120] Hugs only count for goals if both parties are players and unincapacitated(). --- code/modules/mob/hugs.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/hugs.dm b/code/modules/mob/hugs.dm index 1ce632931f2c..afa0d6264737 100644 --- a/code/modules/mob/hugs.dm +++ b/code/modules/mob/hugs.dm @@ -46,7 +46,7 @@ var/global/list/_default_hug_messages = list( playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - if(src != target) + if(src != target && client && key && target.client && target.key && !target.incapacitated()) update_personal_goal(/datum/goal/achievement/givehug, TRUE) target.update_personal_goal(/datum/goal/achievement/gethug, TRUE) From ec4e13e813b34e1bcfa9f1c537712287803e44f4 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 19 Jan 2025 21:50:32 +1100 Subject: [PATCH 034/120] Adding basic handling to forage maps for snow and dirt. --- code/modules/random_map/noise/forage.dm | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/code/modules/random_map/noise/forage.dm b/code/modules/random_map/noise/forage.dm index de983ba78109..aec8125c689f 100644 --- a/code/modules/random_map/noise/forage.dm +++ b/code/modules/random_map/noise/forage.dm @@ -116,6 +116,7 @@ /datum/random_map/noise/forage/get_appropriate_path(value) return +// TODO: /decl system to handle different forage categories. /datum/random_map/noise/forage/get_additional_spawns(value, turf/T) if(!istype(T, /turf/floor)) return @@ -126,11 +127,13 @@ var/place_type if(floor.is_outside()) + if(istype(flooring, /decl/flooring/rock)) if(prob(15)) // Static as current map has limited amount of rock turfs var/rock_type = SAFEPICK(forage["rocks"]) new rock_type(floor) return + if(istype(flooring, /decl/flooring/grass)) if(prob(parse_value * tree_weight)) if(length(trees)) @@ -139,6 +142,7 @@ return place_prob = parse_value * forage_weight place_type = SAFEPICK(forage["grass"]) + if(istype(flooring, /decl/flooring/mud)) switch(floor.get_fluid_depth()) if(FLUID_OVER_MOB_HEAD to FLUID_MAX_DEPTH) @@ -150,6 +154,15 @@ else place_prob = parse_value * forage_weight place_type = SAFEPICK(forage["riverbank"]) // no entries by default, expanded on subtypes + + if(istype(flooring, /decl/flooring/snow)) + place_prob = parse_value * forage_weight + place_type = SAFEPICK(forage["snow"]) + + if(istype(flooring, /decl/flooring/dirt)) + place_prob = parse_value * forage_weight + place_type = SAFEPICK(forage["dirt"]) + else if(istype(flooring, /decl/flooring/mud)) switch(floor.get_fluid_depth()) From 92ea88d9149ac9ab34633d50eb9d54792e84f6d7 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 19 Jan 2025 21:52:17 +1100 Subject: [PATCH 035/120] Butchering carcasses puts blood on the knife. --- code/modules/butchery/butchery_hook.dm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/modules/butchery/butchery_hook.dm b/code/modules/butchery/butchery_hook.dm index bd34f55f0c2b..1a104185132f 100644 --- a/code/modules/butchery/butchery_hook.dm +++ b/code/modules/butchery/butchery_hook.dm @@ -195,12 +195,14 @@ update_icon() if(!tool?.do_tool_interaction(TOOL_KNIFE, user, src, 3 SECONDS, start_message = butchery_string, success_message = butchery_string, check_skill = SKILL_COOKING)) return FALSE - if(!QDELETED(user) && !QDELETED(last_occupant) && occupant == last_occupant && occupant_state == last_state) + if(!QDELETED(user) && !QDELETED(last_occupant) && occupant == last_occupant && occupant_state == last_state && user.get_active_held_item() == tool) var/decl/butchery_data/butchery_data = GET_DECL(occupant.butchery_data) if(!butchery_data) return FALSE + tool.add_blood(occupant) + switch(next_state) if(CARCASS_SKINNED) if(occupant.currently_has_skin()) From 523ccfc1ef489abb2faa3cbe3faa429cdb025b3d Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 19 Jan 2025 22:15:00 +1100 Subject: [PATCH 036/120] Pref updates will now refresh the HUD. --- .../client/preference_setup/global/01_ui.dm | 43 +++++++++++-------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/code/modules/client/preference_setup/global/01_ui.dm b/code/modules/client/preference_setup/global/01_ui.dm index de5797080c49..594a13a78d30 100644 --- a/code/modules/client/preference_setup/global/01_ui.dm +++ b/code/modules/client/preference_setup/global/01_ui.dm @@ -98,26 +98,47 @@ var/global/list/valid_icon_sizes = list(32, 48, 64, 96, 128) . += "Client FPS: [pref.clientfps]
    " /datum/category_item/player_setup_item/player_global/ui/OnTopic(var/href,var/list/href_list, var/mob/user) + if(href_list["select_style"]) var/decl/ui_style/current_style = GET_DECL(pref.UI_style) var/decl/ui_style/UI_style_new = input(user, "Choose UI style.", CHARACTER_PREFERENCE_INPUT_TITLE, current_style) as null|anything in get_ui_styles() if(!istype(UI_style_new) || !CanUseTopic(user)) return TOPIC_NOACTION pref.UI_style = UI_style_new.type - return TOPIC_REFRESH + . = TOPIC_REFRESH else if(href_list["select_color"]) var/UI_style_color_new = input(user, "Choose UI color, dark colors are not recommended!", "Global Preference", pref.UI_style_color) as color|null if(isnull(UI_style_color_new) || !CanUseTopic(user)) return TOPIC_NOACTION pref.UI_style_color = UI_style_color_new - return TOPIC_REFRESH + . = TOPIC_REFRESH else if(href_list["select_alpha"]) var/UI_style_alpha_new = input(user, "Select UI alpha (transparency) level, between 50 and 255.", "Global Preference", pref.UI_style_alpha) as num|null if(isnull(UI_style_alpha_new) || (UI_style_alpha_new < 50 || UI_style_alpha_new > 255) || !CanUseTopic(user)) return TOPIC_NOACTION pref.UI_style_alpha = UI_style_alpha_new - return TOPIC_REFRESH + . = TOPIC_REFRESH + + else if(href_list["reset"]) + switch(href_list["reset"]) + if("ui") + pref.UI_style_color = initial(pref.UI_style_color) + if("alpha") + pref.UI_style_alpha = initial(pref.UI_style_alpha) + if("mouseover_color") + pref.UI_mouseover_color = initial(pref.UI_mouseover_color) + if("mouseover_alpha") + pref.UI_mouseover_alpha = initial(pref.UI_mouseover_alpha) + if("ooc") + pref.ooccolor = initial(pref.ooccolor) + . = TOPIC_REFRESH + + if(. == TOPIC_REFRESH) + // This is overkill, but we do not currently have a way to tell what elements should grab a new color or alpha. + // TODO: maybe limit or debounce/queue this? + user.hud_reset(TRUE) + return - else if(href_list["select_ooc_color"]) + if(href_list["select_ooc_color"]) var/new_ooccolor = input(user, "Choose OOC color:", "Global Preference") as color|null if(new_ooccolor && can_select_ooc_color(user) && CanUseTopic(user)) pref.ooccolor = new_ooccolor @@ -142,20 +163,6 @@ var/global/list/valid_icon_sizes = list(32, 48, 64, 96, 128) pref.tooltip_style = tooltip_style_new return TOPIC_REFRESH - else if(href_list["reset"]) - switch(href_list["reset"]) - if("ui") - pref.UI_style_color = initial(pref.UI_style_color) - if("alpha") - pref.UI_style_alpha = initial(pref.UI_style_alpha) - if("mouseover_color") - pref.UI_mouseover_color = initial(pref.UI_mouseover_color) - if("mouseover_alpha") - pref.UI_mouseover_alpha = initial(pref.UI_mouseover_alpha) - if("ooc") - pref.ooccolor = initial(pref.ooccolor) - return TOPIC_REFRESH - else if(href_list["select_icon_size"]) var/new_icon_size = input(user, "Enter a new default icon size.", "Default Icon Size", pref.icon_size) as null|anything in global.valid_icon_sizes if(new_icon_size && pref.icon_size != new_icon_size) From 89e1952b56dc7550def0701a74d3892913a497be Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 19 Jan 2025 22:17:54 +1100 Subject: [PATCH 037/120] Selecting UI style will reset to default color/alpha if set. --- .../modules/client/preference_setup/global/01_ui.dm | 13 ++++++++++--- code/modules/client/ui_styles/_ui_style.dm | 4 ++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/code/modules/client/preference_setup/global/01_ui.dm b/code/modules/client/preference_setup/global/01_ui.dm index 594a13a78d30..1d52af2a4ba6 100644 --- a/code/modules/client/preference_setup/global/01_ui.dm +++ b/code/modules/client/preference_setup/global/01_ui.dm @@ -102,19 +102,26 @@ var/global/list/valid_icon_sizes = list(32, 48, 64, 96, 128) if(href_list["select_style"]) var/decl/ui_style/current_style = GET_DECL(pref.UI_style) var/decl/ui_style/UI_style_new = input(user, "Choose UI style.", CHARACTER_PREFERENCE_INPUT_TITLE, current_style) as null|anything in get_ui_styles() - if(!istype(UI_style_new) || !CanUseTopic(user)) return TOPIC_NOACTION + if(!istype(UI_style_new) || !CanUseTopic(user)) + return TOPIC_NOACTION pref.UI_style = UI_style_new.type + if(!isnull(UI_style_new.default_color)) + pref.UI_style_color = UI_style_new.default_color + if(!isnull(UI_style_new.default_alpha)) + pref.UI_style_alpha = UI_style_new.default_alpha . = TOPIC_REFRESH else if(href_list["select_color"]) var/UI_style_color_new = input(user, "Choose UI color, dark colors are not recommended!", "Global Preference", pref.UI_style_color) as color|null - if(isnull(UI_style_color_new) || !CanUseTopic(user)) return TOPIC_NOACTION + if(isnull(UI_style_color_new) || !CanUseTopic(user)) + return TOPIC_NOACTION pref.UI_style_color = UI_style_color_new . = TOPIC_REFRESH else if(href_list["select_alpha"]) var/UI_style_alpha_new = input(user, "Select UI alpha (transparency) level, between 50 and 255.", "Global Preference", pref.UI_style_alpha) as num|null - if(isnull(UI_style_alpha_new) || (UI_style_alpha_new < 50 || UI_style_alpha_new > 255) || !CanUseTopic(user)) return TOPIC_NOACTION + if(isnull(UI_style_alpha_new) || (UI_style_alpha_new < 50 || UI_style_alpha_new > 255) || !CanUseTopic(user)) + return TOPIC_NOACTION pref.UI_style_alpha = UI_style_alpha_new . = TOPIC_REFRESH diff --git a/code/modules/client/ui_styles/_ui_style.dm b/code/modules/client/ui_styles/_ui_style.dm index 24e3d9085160..39572275c7fd 100644 --- a/code/modules/client/ui_styles/_ui_style.dm +++ b/code/modules/client/ui_styles/_ui_style.dm @@ -27,6 +27,10 @@ ) /// A subset of UI keys to icon files used to override the above. var/list/override_icons + /// A color to reset this UI to on pref selection. + var/default_color + /// An alpha to reset this UI to on pref selection. + var/default_alpha /decl/ui_style/Initialize() for(var/ui_key in override_icons) From d2a45963b1959a3532c17b39c7c95c4f5b54f2a0 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 19 Jan 2025 22:21:27 +1100 Subject: [PATCH 038/120] Rags will now wipe down turfs. --- code/modules/detectivework/tools/rag.dm | 57 +++++++++++++++---------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/code/modules/detectivework/tools/rag.dm b/code/modules/detectivework/tools/rag.dm index ca9b832689fc..039b3ea46818 100644 --- a/code/modules/detectivework/tools/rag.dm +++ b/code/modules/detectivework/tools/rag.dm @@ -37,11 +37,17 @@ . = ..() /obj/item/chems/glass/rag/attack_self(mob/user) + if(on_fire && user.try_unequip(src)) user.visible_message(SPAN_NOTICE("\The [user] stamps out [src]."), SPAN_NOTICE("You stamp out [src].")) extinguish() - else + return TRUE + + if(reagents?.total_volume) remove_contents(user) + return TRUE + + return ..() /obj/item/chems/glass/rag/attackby(obj/item/W, mob/user) if(W.isflamesource()) @@ -76,28 +82,35 @@ /obj/item/chems/glass/rag/proc/remove_contents(mob/user, atom/trans_dest = null) if(!trans_dest && !user.loc) return + if(reagents?.total_volume <= 0) + return + var/target_text = trans_dest? "\the [trans_dest]" : "\the [user.loc]" + user.visible_message( + SPAN_NOTICE("\The [user] begins to wring out [src] over [target_text]."), + SPAN_NOTICE("You begin to wring out \the [src] over [target_text].") + ) + if(!do_after(user, reagents.total_volume*5, progress = 0) || !reagents?.total_volume) //50 for a fully soaked rag + return + if(trans_dest) + reagents.trans_to(trans_dest, reagents.total_volume) + else + reagents.splash(user.loc, reagents.total_volume) + user.visible_message( + SPAN_NOTICE("\The [user] wrings out \the [src] over [target_text]."), + SPAN_NOTICE("You finish to wringing out \the [src].") + ) + update_name() - if(reagents.total_volume) - var/target_text = trans_dest? "\the [trans_dest]" : "\the [user.loc]" - user.visible_message("\The [user] begins to wring out [src] over [target_text].", "You begin to wring out [src] over [target_text].") - - if(do_after(user, reagents.total_volume*5, progress = 0)) //50 for a fully soaked rag - if(trans_dest) - reagents.trans_to(trans_dest, reagents.total_volume) - else - reagents.splash(user.loc, reagents.total_volume) - user.visible_message("\The [user] wrings out [src] over [target_text].", "You finish to wringing out [src].") - update_name() +/obj/item/chems/glass/rag/proc/wipe_down(atom/target, mob/user) -/obj/item/chems/glass/rag/proc/wipe_down(atom/A, mob/user) - if(!reagents.total_volume) - to_chat(user, "The [initial(name)] is dry!") - else - user.visible_message("\The [user] starts to wipe down [A] with [src]!") - update_name() - if(do_after(user,30, progress = 1)) - user.visible_message("\The [user] finishes wiping off the [A]!") - reagents.splash(A, FLUID_QDEL_POINT) + if(!reagents?.total_volume) + to_chat(user, SPAN_WARNING("The [initial(name)] is dry.")) + return + + user.visible_message(SPAN_NOTICE("\The [user] starts to wipe down \the [target] with \the [src].")) + if(do_after(user, 3 SECONDS, target, check_holding = TRUE)) + user.visible_message(SPAN_NOTICE("\The [user] finishes wiping off \the [target].")) + reagents.touch_atom(target) /obj/item/chems/glass/rag/use_on_mob(mob/living/target, mob/living/user, animate = TRUE) @@ -159,7 +172,7 @@ return if(!on_fire && istype(A) && (src in user)) - if(ATOM_IS_OPEN_CONTAINER(A) && !(A in user)) + if(ATOM_IS_OPEN_CONTAINER(A) && !isturf(A) && !(A in user)) remove_contents(user, A) else if(!ismob(A)) //mobs are handled in use_on_mob() - this prevents us from wiping down people while smothering them. wipe_down(A, user) From 10639e443c23c50b947abd74ee3e8d9586a7ca5a Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 19 Jan 2025 22:28:32 +1100 Subject: [PATCH 039/120] All UI styles will default to white and fully opaque. --- code/modules/client/ui_styles/_ui_style.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/client/ui_styles/_ui_style.dm b/code/modules/client/ui_styles/_ui_style.dm index 39572275c7fd..250eb36314eb 100644 --- a/code/modules/client/ui_styles/_ui_style.dm +++ b/code/modules/client/ui_styles/_ui_style.dm @@ -28,9 +28,9 @@ /// A subset of UI keys to icon files used to override the above. var/list/override_icons /// A color to reset this UI to on pref selection. - var/default_color + var/default_color = COLOR_WHITE /// An alpha to reset this UI to on pref selection. - var/default_alpha + var/default_alpha = 255 /decl/ui_style/Initialize() for(var/ui_key in override_icons) From 3d2098eb872bdd2227dc7ca08c99749d570bf0b1 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sat, 18 Jan 2025 19:31:01 -0500 Subject: [PATCH 040/120] Fix muddy footprints being made of blood --- .../effects/decals/Cleanable/humans.dm | 61 +++++++++++++------ .../effects/decals/Cleanable/robots.dm | 6 -- .../effects/decals/Cleanable/tracks.dm | 6 +- code/game/objects/effects/footprints.dm | 4 +- .../stool_bed_chair_nest_sofa/wheelchair.dm | 1 + code/game/turfs/flooring/_flooring.dm | 4 +- code/game/turfs/flooring/flooring_mud.dm | 8 ++- code/game/turfs/floors/_floor.dm | 4 +- code/game/turfs/turf.dm | 28 +++++++-- code/modules/materials/_materials.dm | 12 ++++ .../liquids/materials_liquid_chemistry.dm | 4 ++ .../liquids/materials_liquid_mundane.dm | 12 ++++ .../definitions/solids/materials_solid_ice.dm | 27 ++++++++ code/modules/mob/living/living.dm | 34 ++++++----- code/modules/reagents/Chemistry-Machinery.dm | 2 +- code/modules/reagents/chems/chems_blood.dm | 2 +- mods/species/bayliens/skrell/datum/species.dm | 23 ++++--- nebula.dme | 1 + 18 files changed, 175 insertions(+), 64 deletions(-) create mode 100644 code/modules/materials/definitions/liquids/materials_liquid_mundane.dm diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index cbd3f166ddbb..77bb9276f642 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -1,4 +1,3 @@ -#define DRYING_TIME 5 MINUTES //for 1 unit of depth in puddle (amount var) #define BLOOD_SIZE_SMALL 1 #define BLOOD_SIZE_MEDIUM 2 #define BLOOD_SIZE_BIG 3 @@ -21,6 +20,8 @@ var/base_icon = 'icons/effects/blood.dmi' var/basecolor=COLOR_BLOOD_HUMAN // Color when wet. var/amount = 5 + //for 1 unit of depth in puddle (amount var) + var/time_to_dry = 5 MINUTES var/drytime var/dryname = "dried blood" var/drydesc = "It's dry and crusty. Someone isn't doing their job." @@ -29,19 +30,21 @@ var/chemical = /decl/material/liquid/blood /obj/effect/decal/cleanable/blood/reveal_blood() - if(!fluorescent) + if(ispath(chemical, /decl/material/liquid/blood) && !fluorescent) fluorescent = FLUORESCENT_GLOWS basecolor = COLOR_LUMINOL update_icon() /obj/effect/decal/cleanable/blood/clean(clean_forensics = TRUE) - fluorescent = FALSE - if(invisibility != INVISIBILITY_ABSTRACT) - set_invisibility(INVISIBILITY_ABSTRACT) - amount = 0 - STOP_PROCESSING(SSobj, src) - remove_extension(src, /datum/extension/scent) - . = ..(clean_forensics = FALSE) + if(ispath(chemical, /decl/material/liquid/blood)) + clean_forensics = FALSE + fluorescent = FALSE + if(invisibility != INVISIBILITY_ABSTRACT) + set_invisibility(INVISIBILITY_ABSTRACT) + amount = 0 + STOP_PROCESSING(SSobj, src) + remove_extension(src, /datum/extension/scent) + . = ..(clean_forensics) /obj/effect/decal/cleanable/blood/hide() return @@ -50,8 +53,11 @@ STOP_PROCESSING(SSobj, src) return ..() -/obj/effect/decal/cleanable/blood/Initialize(mapload) +// new_chemical is a material typepath, or null +/obj/effect/decal/cleanable/blood/Initialize(ml, _age, new_chemical) . = ..() + if(!isnull(new_chemical)) + chemical = new_chemical if(merge_with_blood()) return INITIALIZE_HINT_QDEL start_drying() @@ -61,16 +67,31 @@ if(!isturf(loc) || blood_size == BLOOD_SIZE_NO_MERGE) return FALSE for(var/obj/effect/decal/cleanable/blood/B in loc) - if(B != src && B.blood_size != BLOOD_SIZE_NO_MERGE) - if(B.blood_DNA) - blood_size = BLOOD_SIZE_NO_MERGE - B.blood_DNA |= blood_DNA.Copy() - B.alpha = initial(B.alpha) // reset rain-based fading due to more drips - return TRUE + if(B == src) + continue + if(B.blood_size == BLOOD_SIZE_NO_MERGE) + continue + if(B.invisibility >= INVISIBILITY_ABSTRACT) // has been cleaned + continue + if(B.chemical != chemical) // don't mix blood and oil or oil and mud etc + continue // todo: refactor to make bloody steps use reagents and track data/size/amount on there? + if(B.blood_DNA) + blood_size = BLOOD_SIZE_NO_MERGE + B.blood_DNA |= blood_DNA.Copy() + B.alpha = initial(B.alpha) // reset rain-based fading due to more drips + return TRUE return FALSE /obj/effect/decal/cleanable/blood/proc/start_drying() - drytime = world.time + DRYING_TIME * (amount+1) + var/decl/material/our_chemical = GET_DECL(chemical) + time_to_dry = our_chemical.get_time_to_dry_stain(src) + switch(time_to_dry) + if(0) // dry instantly + dry() + return + if(-INFINITY to 0) // don't even bother trying to dry this + return + drytime = world.time + time_to_dry * (amount+1) update_icon() START_PROCESSING(SSobj, src) @@ -100,6 +121,9 @@ amount-- /obj/effect/decal/cleanable/blood/proc/dry() + var/decl/material/our_chemical = GET_DECL(chemical) + if(our_chemical.handle_stain_dry(src)) + return TRUE // prevent additional drying handling; this includes preventing processing, so be careful name = dryname desc = drydesc color = adjust_brightness(color, -50) @@ -107,6 +131,7 @@ blood_data = null remove_extension(src, /datum/extension/scent) STOP_PROCESSING(SSobj, src) + return FALSE /obj/effect/decal/cleanable/blood/attack_hand(mob/user) if(!amount || !length(blood_data) || !ishuman(user)) @@ -233,7 +258,7 @@ for (var/i = 0, i < pick(1, 200; 2, 150; 3, 50; 4), i++) sleep(3) if (i > 0) - var/obj/effect/decal/cleanable/blood/b = new /obj/effect/decal/cleanable/blood/splatter(loc) + var/obj/effect/decal/cleanable/blood/b = new /obj/effect/decal/cleanable/blood/splatter(loc, null, chemical) b.basecolor = src.basecolor b.update_icon() if (step_to(src, get_step(src, direction), 0)) diff --git a/code/game/objects/effects/decals/Cleanable/robots.dm b/code/game/objects/effects/decals/Cleanable/robots.dm index 330acc9f3ce0..425cd84d5179 100644 --- a/code/game/objects/effects/decals/Cleanable/robots.dm +++ b/code/game/objects/effects/decals/Cleanable/robots.dm @@ -13,9 +13,6 @@ /obj/effect/decal/cleanable/blood/gibs/robot/on_update_icon() color = "#ffffff" -/obj/effect/decal/cleanable/blood/gibs/robot/dry() //pieces of robots do not dry up like - return - /obj/effect/decal/cleanable/blood/gibs/robot/streak(var/list/directions) spawn (0) var/direction = pick(directions) @@ -44,9 +41,6 @@ chemical = /decl/material/liquid/lube cleanable_scent = "industrial lubricant" -/obj/effect/decal/cleanable/blood/oil/dry() - return - /obj/effect/decal/cleanable/blood/oil/streak random_icon_states = list("mgibbl1", "mgibbl2", "mgibbl3", "mgibbl4", "mgibbl5") amount = 2 \ No newline at end of file diff --git a/code/game/objects/effects/decals/Cleanable/tracks.dm b/code/game/objects/effects/decals/Cleanable/tracks.dm index 9ef315bf7870..7bddd805f9a2 100644 --- a/code/game/objects/effects/decals/Cleanable/tracks.dm +++ b/code/game/objects/effects/decals/Cleanable/tracks.dm @@ -10,8 +10,7 @@ #define TRACKS_GOING_EAST 64 #define TRACKS_GOING_WEST 128 -// 5 seconds -#define TRACKS_CRUSTIFY_TIME 50 +#define TRACKS_CRUSTIFY_TIME 5 SECONDS /datum/fluidtrack var/direction=0 @@ -26,7 +25,8 @@ src.wet=_wet /obj/effect/decal/cleanable/blood/tracks/reveal_blood() - if(!fluorescent) + // don't reveal non-blood tracks + if(ispath(chemical, /decl/material/liquid/blood) && !fluorescent) if(stack && stack.len) for(var/datum/fluidtrack/track in stack) track.basecolor = COLOR_LUMINOL diff --git a/code/game/objects/effects/footprints.dm b/code/game/objects/effects/footprints.dm index a8af8a6112db..091aa2638568 100644 --- a/code/game/objects/effects/footprints.dm +++ b/code/game/objects/effects/footprints.dm @@ -7,7 +7,7 @@ is_spawnable_type = FALSE blend_mode = BLEND_SUBTRACT alpha = 128 - var/list/footprints + var/list/image/footprints /obj/effect/footprints/Initialize(mapload) . = ..() @@ -15,7 +15,7 @@ name = null /obj/effect/footprints/Destroy() - QDEL_NULL(footprints) + footprints.Cut() // don't qdel images . = ..() /obj/effect/footprints/on_update_icon() diff --git a/code/game/objects/structures/stool_bed_chair_nest_sofa/wheelchair.dm b/code/game/objects/structures/stool_bed_chair_nest_sofa/wheelchair.dm index 67640a583fdf..c6b882a2a67c 100644 --- a/code/game/objects/structures/stool_bed_chair_nest_sofa/wheelchair.dm +++ b/code/game/objects/structures/stool_bed_chair_nest_sofa/wheelchair.dm @@ -12,6 +12,7 @@ tool_interaction_flags = 0 var/item_form_type = /obj/item/wheelchair_kit + // TODO: Replace with reagent holder? This doesn't even properly handle non-human bloodstains. var/bloodiness /obj/structure/bed/chair/wheelchair/Initialize() diff --git a/code/game/turfs/flooring/_flooring.dm b/code/game/turfs/flooring/_flooring.dm index d30c22285702..92d3163ff851 100644 --- a/code/game/turfs/flooring/_flooring.dm +++ b/code/game/turfs/flooring/_flooring.dm @@ -391,5 +391,7 @@ var/global/list/flooring_cache = list() /decl/flooring/proc/turf_crossed(atom/movable/crosser) return -/decl/flooring/proc/can_show_coating_footprints(turf/target) +/// target is the turf that wants to know if it supports footprints +/// contaminant is, optionally, the material of the coating that wants to be added. +/decl/flooring/proc/can_show_coating_footprints(turf/target, decl/material/contaminant) return TRUE diff --git a/code/game/turfs/flooring/flooring_mud.dm b/code/game/turfs/flooring/flooring_mud.dm index a4865eb5fe7f..d6d77b4e9e31 100644 --- a/code/game/turfs/flooring/flooring_mud.dm +++ b/code/game/turfs/flooring/flooring_mud.dm @@ -25,10 +25,12 @@ if(!isliving(crosser)) return var/mob/living/walker = crosser - walker.add_walking_contaminant(/decl/material/solid/soil, rand(2,3)) + walker.add_walking_contaminant(force_material.type, rand(2,3)) -/decl/flooring/mud/can_show_coating_footprints(turf/target) - return FALSE // So we don't end up covered in a million footsteps that we provided. +/decl/flooring/mud/can_show_coating_footprints(turf/target, decl/material/contaminant) + if(force_material.type == contaminant) // So we don't end up covered in a million footsteps that we provided. + return FALSE + return ..() /decl/flooring/dry_mud name = "dry mud" diff --git a/code/game/turfs/floors/_floor.dm b/code/game/turfs/floors/_floor.dm index 844b479eaa12..d319eb06c8c2 100644 --- a/code/game/turfs/floors/_floor.dm +++ b/code/game/turfs/floors/_floor.dm @@ -309,5 +309,5 @@ flooring?.turf_crossed(AM) return ..() -/turf/floor/can_show_coating_footprints() - return ..() && get_topmost_flooring()?.can_show_coating_footprints(src) +/turf/floor/can_show_coating_footprints(decl/material/contaminant = null) + return ..() && get_topmost_flooring()?.can_show_coating_footprints(src, contaminant) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 0563fd5715fe..1d52a53bb130 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -712,13 +712,29 @@ blood_splatter(src, M, 1) return TRUE -/turf/proc/AddTracks(var/typepath,var/bloodDNA,var/comingdir,var/goingdir,var/bloodcolor=COLOR_BLOOD_HUMAN) +/// Creates a new /obj/effect/decal/cleanable/blood/tracks instance of a given type, +/// or merges it with an existing (not-yet-cleaned) one that matches typepath and chemical. +/// typepath is a type, not an instance +/// new_chemical is optional argument for things like muddy footprints, where typepath isn't enough +/turf/proc/AddTracks(obj/effect/decal/cleanable/blood/tracks/typepath, bloodDNA, comingdir, goingdir, bloodcolor = COLOR_BLOOD_HUMAN, new_chemical = null) if(!simulated) return - var/obj/effect/decal/cleanable/blood/tracks/tracks = locate(typepath) in src + // Populate defaults from the given typepath, where possible. + if(isnull(new_chemical)) + new_chemical = typepath::chemical || /decl/material/liquid/blood + + var/obj/effect/decal/cleanable/blood/tracks/tracks = null + for(var/obj/effect/decal/cleanable/blood/tracks/candidate in src) + if(!istype(candidate, typepath)) + continue + if(candidate.invisibility >= INVISIBILITY_ABSTRACT) // has been cleaned + continue + if(candidate.chemical != new_chemical) + continue + tracks = candidate if(!tracks) - tracks = new typepath(src) - tracks.AddTracks(bloodDNA,comingdir,goingdir,bloodcolor) + tracks = new typepath(src, null, new_chemical) + tracks.AddTracks(bloodDNA, comingdir, goingdir, bloodcolor) // Proc called in /turf/Entered() to supply an appropriate fluid overlay. /turf/proc/get_movable_alpha_mask_state(atom/movable/mover) @@ -814,7 +830,9 @@ if(IS_HOE(held) && can_dig_farm(held.material?.hardness)) LAZYADD(., /decl/interaction_handler/dig/farm) -/turf/proc/can_show_coating_footprints() +/// Contaminant may be the chemical type of the footprint being provided, +/// or null if we just want to know if we support footprints, at all, ever. +/turf/proc/can_show_coating_footprints(decl/material/contaminant) return simulated /decl/interaction_handler/show_turf_contents diff --git a/code/modules/materials/_materials.dm b/code/modules/materials/_materials.dm index 4633de8a6ca8..8c3ae7d8eb98 100644 --- a/code/modules/materials/_materials.dm +++ b/code/modules/materials/_materials.dm @@ -1203,3 +1203,15 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) // TODO: expand this to more than just Actual Poison. /decl/material/proc/is_unsafe_to_drink(mob/user) return toxicity > 0 + +/// Used for material-dependent effects on stain dry. +/// Return TRUE to skip default drying handling. +/decl/material/proc/handle_stain_dry(obj/effect/decal/cleanable/blood/stain) + return FALSE + +/// Returns (in deciseconds) how long until dry() will be called on this stain, +/// or null to use the stain's default. +/// If 0 is returned, it dries instantly. +/// If any value below 0 is returned, it doesn't start processing. +/decl/material/proc/get_time_to_dry_stain(obj/effect/decal/cleanable/blood/stain) + return initial(stain.time_to_dry) diff --git a/code/modules/materials/definitions/liquids/materials_liquid_chemistry.dm b/code/modules/materials/definitions/liquids/materials_liquid_chemistry.dm index ae855b451f11..bb527d7123d3 100644 --- a/code/modules/materials/definitions/liquids/materials_liquid_chemistry.dm +++ b/code/modules/materials/definitions/liquids/materials_liquid_chemistry.dm @@ -25,3 +25,7 @@ value = 0.1 slipperiness = 80 exoplanet_rarity_gas = MAT_RARITY_EXOTIC + +// Prevent oil stains from drying. +/decl/material/liquid/lube/get_time_to_dry_stain(obj/effect/decal/cleanable/blood/stain) + return -1 \ No newline at end of file diff --git a/code/modules/materials/definitions/liquids/materials_liquid_mundane.dm b/code/modules/materials/definitions/liquids/materials_liquid_mundane.dm new file mode 100644 index 000000000000..97cfe6b65f94 --- /dev/null +++ b/code/modules/materials/definitions/liquids/materials_liquid_mundane.dm @@ -0,0 +1,12 @@ +/decl/material/liquid/mucus + name = "mucus" + uid = "chem_mucus" + lore_text = "A gooey semi-liquid produced by a wide variety of organisms. In some, it's associated with disease and illness." + taste_description = "slime" + color = COLOR_LIQUID_WATER + opacity = 0.5 + exoplanet_rarity_gas = MAT_RARITY_NOWHERE + +/decl/material/liquid/mucus/handle_stain_dry(obj/effect/decal/cleanable/blood/stain) + qdel(stain) + return TRUE // skip blood handling \ No newline at end of file diff --git a/code/modules/materials/definitions/solids/materials_solid_ice.dm b/code/modules/materials/definitions/solids/materials_solid_ice.dm index a6b33d5a584a..b37ec038e84c 100644 --- a/code/modules/materials/definitions/solids/materials_solid_ice.dm +++ b/code/modules/materials/definitions/solids/materials_solid_ice.dm @@ -43,6 +43,33 @@ default_solid_form = /obj/item/stack/material/lump/large can_backfill_floor_type = /decl/flooring/snow +/decl/material/solid/ice/snow/handle_stain_dry(obj/effect/decal/cleanable/blood/stain) + var/ambient_temperature = stain.get_ambient_temperature() + if(ambient_temperature < melting_point) + // reset the drying timer, it's not warm enough to melt + stain.start_drying() // you'd better not ever melt instantly below your melting point, or else this will cause infinite recursion + else if(ambient_temperature > boiling_point) + qdel(src) // melt instantly, no questions asked + else + if(--stain.amount < 0) // reduce the amount of snow (amount is always 0 for footprints currently, but maybe someday?) + qdel(src) + return TRUE // skip base blood handling + +// For snowy footprints melting. +/decl/material/solid/ice/snow/get_time_to_dry_stain(obj/effect/decal/cleanable/blood/stain) + // Attempt to melt once every two minutes at T20C, + // and every 5 minutes at T0C, trying to 'fake' latent heat. + // Above T20C it scales based on (temperature / T20C). + // At or above the boiling point it melts instantly. + // This doesn't mean it WILL melt at that point, just that it'll attempt to. + var/ambient_temperature = max(stain.get_ambient_temperature(), melting_point) + if(ambient_temperature >= boiling_point) + return 0 // dry instantly + if(ambient_temperature < melting_point) + return 5 MINUTES + // convert from kelvins to celsius by subtracting the 0C point in Kelvins + return Interpolate(5 MINUTES, 2 MINUTES, (ambient_temperature - T0C) / 20) / (stain.amount + 1) // Undo the scaling done by blood. + /decl/material/solid/ice/aspium name = "aspium" use_name = null diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index a9f88a6c596c..0074c7f7cca5 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1614,24 +1614,28 @@ default behaviour is: my_species?.handle_trail(src, T, old_loc) return - var/list/bloodDNA - var/bloodcolor - var/list/blood_data = REAGENT_DATA(source.coating, /decl/material/liquid/blood) - if(blood_data) - bloodDNA = list(blood_data[DATA_BLOOD_DNA] = blood_data[DATA_BLOOD_TYPE]) - else - bloodDNA = list() - bloodcolor = source.coating.get_color() + var/use_move_trail = my_species?.get_move_trail(src) + if(!use_move_trail) + return + + var/decl/material/contaminant_type = source.coating.reagent_volumes[1] // take [1] instead of primary reagent to match what remove_any will probably remove + if(!T.can_show_coating_footprints(contaminant_type)) + return + /// An associative list of DNA unique enzymes -> blood type. Used by forensics, mostly. + var/list/bloodDNA = list() + var/track_color + var/list/source_data = REAGENT_DATA(source.coating, contaminant_type) + if(source_data && source_data[DATA_BLOOD_DNA] && source_data[DATA_BLOOD_TYPE]) + bloodDNA = list(source_data[DATA_BLOOD_DNA] = source_data[DATA_BLOOD_TYPE]) + track_color = source.coating.get_color() + T.AddTracks(use_move_trail, bloodDNA, dir, 0, track_color, contaminant_type) // Coming + if(isturf(old_loc)) + var/turf/old_turf = old_loc + if(old_turf.can_show_coating_footprints(contaminant_type)) + old_turf.AddTracks(use_move_trail, bloodDNA, 0, dir, track_color, contaminant_type) // Going source.remove_coating(1) update_equipment_overlay(slot_shoes_str) - var/use_move_trail = my_species?.get_move_trail(src) - if(use_move_trail) - T.AddTracks(use_move_trail, bloodDNA, dir, 0, bloodcolor) // Coming - if(isturf(old_loc)) - var/turf/old_turf = old_loc - old_turf.AddTracks(use_move_trail, bloodDNA, 0, dir, bloodcolor) // Going - /mob/living/proc/handle_general_grooming(user, obj/item/grooming/tool) if(tool.grooming_flags & (GROOMABLE_BRUSH|GROOMABLE_COMB)) visible_message(SPAN_NOTICE(tool.replace_message_tokens((user == src) ? tool.message_target_self_generic : tool.message_target_other_generic, user, src, tool))) diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm index 0216e31ad13a..e304fbec91e0 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/Chemistry-Machinery.dm @@ -223,7 +223,7 @@ . += "

    Description:
    " if(detailed_blood && istype(reagent, /decl/material/liquid/blood)) var/blood_data = REAGENT_DATA(beaker?.reagents, /decl/material/liquid/blood) - . += "Blood Type: [LAZYACCESS(blood_data, DATA_BLOOD_TYPE)]
    DNA: [LAZYACCESS(blood_data, "blood.DNA")]" + . += "Blood Type: [LAZYACCESS(blood_data, DATA_BLOOD_TYPE)]
    DNA: [LAZYACCESS(blood_data, DATA_BLOOD_DNA)]" else . += "[reagent.lore_text]" . += "


    (Back)" diff --git a/code/modules/reagents/chems/chems_blood.dm b/code/modules/reagents/chems/chems_blood.dm index 1e4696e3ffec..ab5f8e6dd8ec 100644 --- a/code/modules/reagents/chems/chems_blood.dm +++ b/code/modules/reagents/chems/chems_blood.dm @@ -72,7 +72,7 @@ /decl/material/liquid/blood/get_reagent_color(datum/reagents/holder) var/list/blood_data = REAGENT_DATA(holder, type) - return blood_data?["blood_color"] || ..() + return blood_data?[DATA_BLOOD_COLOR] || ..() /decl/material/liquid/coagulated_blood name = "coagulated blood" diff --git a/mods/species/bayliens/skrell/datum/species.dm b/mods/species/bayliens/skrell/datum/species.dm index 0d9acdcd8807..00fa25e43e66 100644 --- a/mods/species/bayliens/skrell/datum/species.dm +++ b/mods/species/bayliens/skrell/datum/species.dm @@ -117,27 +117,36 @@ var/obj/item/shoes = H.get_equipped_item(slot_shoes_str) if(!shoes) var/list/bloodDNA - var/list/blood_data = REAGENT_DATA(H.vessel, /decl/material/liquid/blood) + var/list/blood_data = REAGENT_DATA(H.vessel, blood_reagent) if(blood_data) bloodDNA = list(blood_data[DATA_BLOOD_DNA] = blood_data[DATA_BLOOD_TYPE]) else bloodDNA = list() - if(T.simulated) - T.AddTracks(/obj/effect/decal/cleanable/blood/tracks/footprints/skrellprints, bloodDNA, H.dir, 0, H.get_skin_colour() + "25") // Coming (8c is the alpha value) + T.AddTracks(/obj/effect/decal/cleanable/blood/tracks/footprints/skrellprints, bloodDNA, H.dir, 0, H.get_skin_colour() + "25") // Coming (25 is the alpha value) if(isturf(old_loc)) var/turf/old_turf = old_loc - if(old_turf.simulated) - old_turf.AddTracks(/obj/effect/decal/cleanable/blood/tracks/footprints/skrellprints, bloodDNA, 0, H.dir, H.get_skin_colour() + "25") // Going (8c is the alpha value) + old_turf.AddTracks(/obj/effect/decal/cleanable/blood/tracks/footprints/skrellprints, bloodDNA, 0, H.dir, H.get_skin_colour() + "25") // Going (25 is the alpha value) /decl/species/skrell/check_background() return TRUE +/decl/material/liquid/mucus/skrell + name = "slime" + uid = "chem_mucus_skrell" + lore_text = "A gooey semi-liquid secreted by skrellian skin." + +// Copied from blood. +// TODO: There's not currently a way to check this, which might be a little annoying for forensics. +// But this is just a stopgap to stop Skrell from literally leaking blood everywhere they go. +/decl/material/liquid/mucus/skrell/get_reagent_color(datum/reagents/holder) + var/list/goo_data = REAGENT_DATA(holder, type) + return goo_data?[DATA_BLOOD_COLOR] || ..() + /obj/effect/decal/cleanable/blood/tracks/footprints/skrellprints name = "wet footprints" desc = "They look like still wet tracks left by skrellian feet." + chemical = /decl/material/liquid/mucus/skrell -/obj/effect/decal/cleanable/blood/tracks/footprints/skrellprints/dry() - qdel(src) /obj/item/organ/internal/eyes/skrell name = "amphibian eyes" desc = "Large black orbs, belonging to some sort of giant frog by looks of it." diff --git a/nebula.dme b/nebula.dme index 8660305935b2..5e7332fe6b49 100644 --- a/nebula.dme +++ b/nebula.dme @@ -2744,6 +2744,7 @@ #include "code\modules\materials\definitions\gasses\material_gas_mundane.dm" #include "code\modules\materials\definitions\liquids\_mat_liquid.dm" #include "code\modules\materials\definitions\liquids\materials_liquid_chemistry.dm" +#include "code\modules\materials\definitions\liquids\materials_liquid_mundane.dm" #include "code\modules\materials\definitions\liquids\materials_liquid_solvents.dm" #include "code\modules\materials\definitions\liquids\materials_liquid_soup.dm" #include "code\modules\materials\definitions\liquids\materials_liquid_toxins.dm" From c8e2e3a5b76150fcea6136ebe117481937bf44ce Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sat, 18 Jan 2025 19:47:08 -0500 Subject: [PATCH 041/120] Add snowy footsteps --- code/game/turfs/flooring/flooring_snow.dm | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/code/game/turfs/flooring/flooring_snow.dm b/code/game/turfs/flooring/flooring_snow.dm index 834b109eea7d..e88af2cbf966 100644 --- a/code/game/turfs/flooring/flooring_snow.dm +++ b/code/game/turfs/flooring/flooring_snow.dm @@ -31,6 +31,19 @@ return return ..() +/decl/flooring/snow/turf_crossed(atom/movable/crosser) + if(!isliving(crosser)) + return + var/mob/living/walker = crosser + // at some point this might even be able to use the height + // of the snow flooring layer, so deep snow gives you more coating + walker.add_walking_contaminant(force_material.type, rand(1, 2)) + +/decl/flooring/snow/can_show_coating_footprints(turf/target, decl/material/contaminant) + if(force_material.type == contaminant) // So we don't end up covered in a million footsteps that we provided. + return FALSE + return ..() + /decl/flooring/permafrost name = "permafrost" desc = "A stretch of frozen soil that hasn't seen a thaw for many seasons." From 9075edd1e3e7dd9e255d802846d8ca60fe21cf43 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 19 Jan 2025 18:09:40 -0500 Subject: [PATCH 042/120] Split walking contaminants between all feet --- code/modules/mob/living/living.dm | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 0074c7f7cca5..f6dd4d172be6 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1995,12 +1995,31 @@ default behaviour is: /mob/living/proc/get_age() . = LAZYACCESS(appearance_descriptors, "age") || 30 -/mob/living/proc/add_walking_contaminant(material_type, amount, data) +/mob/living/proc/get_walking_contaminant_targets() var/obj/item/clothing/shoes/shoes = get_equipped_item(slot_shoes_str) if(istype(shoes)) if(!buckled) - shoes.add_coating(material_type, amount, data) + return list(shoes) else - for(var/obj/item/organ/external/limb in get_organs_by_categories(global.child_stance_limbs)) - limb.add_coating(material_type, amount, data) + return get_organs_by_categories(global.child_stance_limbs) + return null + +/// Adds `amount` units of `material_type` contaminant to whatever we're walking with, +/// be it shoes, normal human feet, dog paws, robot treads, a million millipede legs, +/// the sky's the limit. If multiple targets are returned from +/// `get_walking_contaminant_targets()`, then `amount` is split evenly +/// between them. +/mob/living/proc/add_walking_contaminant(material_type, amount, data) + if(amount <= 0) + return FALSE + var/list/obj/item/sources = get_walking_contaminant_targets() + if(!LAZYLEN(sources)) + return FALSE + var/amount_per = max(CHEMS_QUANTIZE(amount / length(sources)), MINIMUM_CHEMICAL_VOLUME) // don't let it round down to 0, always add something + for(var/obj/item/dirty_item in sources) + dirty_item.add_coating(material_type, amount_per, data) + // i don't like how hardcoded this is, it might be better to use RAISE_EVENT or something + // like /decl/observ/on_add_walking_contaminant or something + // or things should just update their worn slot when coating is added update_equipment_overlay(slot_shoes_str) + return TRUE From 512efa8842dc05f757db6351035fc9e04577876a Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Mon, 20 Jan 2025 10:36:11 +1100 Subject: [PATCH 043/120] Changes oil update color to update_icon(). --- code/game/objects/effects/decals/Cleanable/robots.dm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/code/game/objects/effects/decals/Cleanable/robots.dm b/code/game/objects/effects/decals/Cleanable/robots.dm index efeaac361390..e7fa4729e483 100644 --- a/code/game/objects/effects/decals/Cleanable/robots.dm +++ b/code/game/objects/effects/decals/Cleanable/robots.dm @@ -45,9 +45,8 @@ cleanable_scent = "industrial lubricant" /obj/effect/decal/cleanable/blood/oil/Initialize(mapload) - if(basecolor) - set_color(basecolor) . = ..() + update_icon() /obj/effect/decal/cleanable/blood/oil/dry() return From 31f18eb9c09547240960a0b99ac8c04b0f66e02d Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Mon, 20 Jan 2025 00:50:08 +0000 Subject: [PATCH 044/120] Automatic changelog generation [ci skip] --- html/changelog.html | 6 ------ 1 file changed, 6 deletions(-) diff --git a/html/changelog.html b/html/changelog.html index 7e9d585edb61..d507970d55ed 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -109,12 +109,6 @@

    ophelia updated:

    • You can now put any disk into the research design database or research design console, but only the correct disk type (tech disk or design disk) will function.
    - -

    18 November 2024

    -

    MistakeNot4892 updated:

    -
      -
    • Swapped barrel icons out for Doe's much nicer barrels.
    • -
From 08f44b575b0b66a1a96f83c64ec9bd7539e1a5f2 Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Mon, 20 Jan 2025 16:03:00 +1100 Subject: [PATCH 045/120] Automatic changelog generation for PR #4762 [ci skip] --- html/changelogs/AutoChangeLog-pr-4762.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4762.yml diff --git a/html/changelogs/AutoChangeLog-pr-4762.yml b/html/changelogs/AutoChangeLog-pr-4762.yml new file mode 100644 index 000000000000..d387cce9023f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4762.yml @@ -0,0 +1,5 @@ +author: Penelope Haze +changes: + - {tweak: Mud can now receive footprints with any reagent other than mud. No more + conspicuously missing bloody footprints!} +delete-after: true From 52b299f0438b388aab0c61d30f094869be530dc6 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Mon, 20 Jan 2025 17:24:08 +1100 Subject: [PATCH 046/120] Cleans up modular_computer attackby. --- .../computers/modular_computer/interaction.dm | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/code/modules/modular_computers/computers/modular_computer/interaction.dm b/code/modules/modular_computers/computers/modular_computer/interaction.dm index 6bb4a4f41b84..b2a0b77524f0 100644 --- a/code/modules/modular_computers/computers/modular_computer/interaction.dm +++ b/code/modules/modular_computers/computers/modular_computer/interaction.dm @@ -85,23 +85,22 @@ return TRUE . = ..() -/obj/item/modular_computer/attackby(var/obj/item/W, var/mob/user) +/obj/item/modular_computer/attackby(var/obj/item/used_item, var/mob/user) + var/datum/extension/assembly/assembly = get_extension(src, /datum/extension/assembly) - . = assembly.attackby(W, user) - if(.) + if(assembly?.attackby(used_item, user)) update_verbs() return TRUE - if(IS_PEN(W) && (W.w_class <= ITEM_SIZE_TINY) && stores_pen) + if(IS_PEN(used_item) && (used_item.w_class <= ITEM_SIZE_TINY) && stores_pen) if(istype(stored_pen)) - to_chat(user, "There is already a pen in [src].") - return TRUE - if(!user.try_unequip(W, src)) - return TRUE - stored_pen = W - update_verbs() - to_chat(user, "You insert [W] into [src].") + to_chat(user, SPAN_NOTICE("There is already \a [stored_pen] in \the [src].")) + else if(user.try_unequip(used_item, src)) + stored_pen = used_item + update_verbs() + to_chat(user, SPAN_NOTICE("You insert \the [used_item] into [src].")) return TRUE + return ..() /obj/item/modular_computer/examine(mob/user) From 46a458a71518ccd5fb96eff2a6d56df62da75f1a Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Mon, 20 Jan 2025 17:58:34 +1100 Subject: [PATCH 047/120] Spent casings are called 'spent casing'. --- code/modules/projectiles/ammunition.dm | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm index f163d0f64c76..821b1c5658d2 100644 --- a/code/modules/projectiles/ammunition.dm +++ b/code/modules/projectiles/ammunition.dm @@ -44,12 +44,11 @@ . = BB BB = null set_dir(pick(global.alldirs)) //spin spent casings - // Aurora forensics port, gunpowder residue. if(leaves_residue) leave_residue() - update_icon() + update_name() /obj/item/ammo_casing/Crossed(atom/movable/AM) ..() @@ -119,6 +118,11 @@ else if(spent_icon && !BB) icon_state = spent_icon +/obj/item/ammo_casing/update_name() + . = ..() + if(!BB) + SetName("spent [name]") + /obj/item/ammo_casing/examine(mob/user) . = ..() if(caliber) From d59e9b73b1aaa217014fabddbf4b7b2a0ba778ec Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Mon, 20 Jan 2025 17:58:56 +1100 Subject: [PATCH 048/120] Allows toggling the common channel on or off. --- nano/templates/radio_basic.tmpl | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/nano/templates/radio_basic.tmpl b/nano/templates/radio_basic.tmpl index fc94e17029cd..b3ba6f4830ac 100644 --- a/nano/templates/radio_basic.tmpl +++ b/nano/templates/radio_basic.tmpl @@ -138,12 +138,11 @@ Used In File(s): /code/game/objects/item/devices/radio/radio.dm {{:value.display_name}}
- {{if value.secure_channel}} - {{:helper.link('On', null, {'ch_name' : value.chan, 'listen' : 1}, value.listening ? 'selected' : null)}} - {{:helper.link('Off', null, {'ch_name' : value.chan, 'listen' : 0}, value.listening ? null : 'selected')}} - {{else}} - {{:helper.link('Switch', null, {'spec_freq' : value.chan}, data.rawfreq == value.chan ? 'selected' : null)}} - {{/if}} + {{:helper.link('On', null, {'ch_name' : value.chan, 'listen' : 1}, value.listening ? 'selected' : null)}} + {{:helper.link('Off', null, {'ch_name' : value.chan, 'listen' : 0}, value.listening ? null : 'selected')}} + {{if !value.secure_channel}} + {{:helper.link('Switch', null, {'spec_freq' : value.chan}, data.rawfreq == value.chan ? 'selected' : null)}} + {{/if}}
{{/for}} {{/if}} From cc87b774570f0334e3aa58a1074f8ec5e5ceccf7 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Mon, 20 Jan 2025 18:11:48 +1100 Subject: [PATCH 049/120] Ensuring all HUDs get an intent selector. --- code/_onclick/hud/ai.dm | 3 +++ code/_onclick/hud/animal.dm | 2 -- code/_onclick/hud/hud.dm | 17 ++++++++++++++++- code/_onclick/hud/human.dm | 6 ------ code/_onclick/hud/robot.dm | 5 ----- code/_onclick/hud/screen/screen_robot_intent.dm | 7 ------- code/modules/augment/augment.dm | 1 + .../computers/modular_computer/interaction.dm | 2 +- code/modules/species/species_hud.dm | 1 - mods/content/xenobiology/_xenobiology.dme | 1 - mods/content/xenobiology/slime/_slime.dm | 2 +- mods/content/xenobiology/slime/slime_hud.dm | 4 ---- mods/gamemodes/deity/mobs/deity_hud.dm | 6 +++--- mods/mobs/dionaea/mob/nymph_ui.dm | 10 ++++++---- mods/species/ascent/mobs/nymph/nymph_ui.dm | 8 +++++--- 15 files changed, 36 insertions(+), 39 deletions(-) delete mode 100644 mods/content/xenobiology/slime/slime_hud.dm diff --git a/code/_onclick/hud/ai.dm b/code/_onclick/hud/ai.dm index 81f1abf89659..651c4d1e007f 100644 --- a/code/_onclick/hud/ai.dm +++ b/code/_onclick/hud/ai.dm @@ -1,6 +1,9 @@ /mob/living/silicon/ai hud_used = /datum/hud/ai +/datum/hud/ai + action_intent_type = null // no selector + /datum/hud/ai/FinalizeInstantiation() var/list/ai_hud_data = decls_repository.get_decls_of_subtype(/decl/ai_hud) for(var/elem_type in ai_hud_data) diff --git a/code/_onclick/hud/animal.dm b/code/_onclick/hud/animal.dm index 5c1d9173a3a6..8b372aabdcc6 100644 --- a/code/_onclick/hud/animal.dm +++ b/code/_onclick/hud/animal.dm @@ -11,6 +11,4 @@ move_intent = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_MOVEMENT) move_intent.icon_state = mymob.move_intent.hud_icon_state adding += move_intent - action_intent = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_INTENT) - adding += action_intent ..() diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 052eca2d8aef..85f3e763a576 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -28,10 +28,12 @@ var/list/hand_hud_objects var/list/swaphand_hud_objects - var/obj/screen/intent/action_intent var/obj/screen/movement/move_intent var/obj/screen/stamina/stamina_bar + var/action_intent_type = /obj/screen/intent + var/obj/screen/intent/action_intent + var/list/adding = list() var/list/other = list() var/list/hud_elements = list() @@ -112,9 +114,21 @@ return FALSE /datum/hud/proc/FinalizeInstantiation() + SHOULD_CALL_PARENT(TRUE) + + var/ui_style = get_ui_style_data() + var/ui_color = get_ui_color() + var/ui_alpha = get_ui_alpha() + + if(!action_intent && action_intent_type) // Everyone needs an intent selector. + action_intent = new action_intent_type(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_INTENT) + adding |= action_intent + hud_elements |= action_intent + BuildInventoryUI() BuildHandsUI() + if(mymob.client) mymob.client.screen = list() if(length(hand_hud_objects)) @@ -127,6 +141,7 @@ mymob.client.screen |= adding if(length(hotkeybuttons)) mymob.client.screen |= hotkeybuttons + hide_inventory() /datum/hud/proc/get_ui_style_data() diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index a4fb7dab7ffe..7dc1d837d915 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -15,12 +15,6 @@ stamina_bar = new(null, mymob) adding += stamina_bar - // Draw the attack intent dialogue. - if(hud_data.has_a_intent) - action_intent = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_INTENT) - src.adding += action_intent - hud_elements |= action_intent - if(hud_data.has_m_intent) move_intent = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_MOVEMENT) move_intent.icon_state = mymob.move_intent.hud_icon_state diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index 2b87d5f9372a..ab88cc0b2be5 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -50,11 +50,6 @@ var/global/obj/screen/robot_inventory R.ui_drop_grab = new(null, mymob) adding += R.ui_drop_grab - //Intent - action_intent = new /obj/screen/intent/robot(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_INTENT) - action_intent.icon_state = R.a_intent - - adding += action_intent adding += new /obj/screen/robot_panel(null, mymob) adding += new /obj/screen/robot_store(null, mymob) diff --git a/code/_onclick/hud/screen/screen_robot_intent.dm b/code/_onclick/hud/screen/screen_robot_intent.dm index bbc6501941ef..e69de29bb2d1 100644 --- a/code/_onclick/hud/screen/screen_robot_intent.dm +++ b/code/_onclick/hud/screen/screen_robot_intent.dm @@ -1,7 +0,0 @@ -/obj/screen/intent/robot - name = "act_intent" - dir = SOUTHWEST - screen_loc = ui_acti - -/obj/screen/intent/robot/handle_click(mob/user, params) - user.a_intent_change("right") diff --git a/code/modules/augment/augment.dm b/code/modules/augment/augment.dm index ff96aabde045..30dbea3a74c0 100644 --- a/code/modules/augment/augment.dm +++ b/code/modules/augment/augment.dm @@ -2,6 +2,7 @@ name = "embedded augment" desc = "An embedded augment." icon = 'icons/obj/augment.dmi' + w_class = ITEM_SIZE_TINY // Need to be tiny to fit inside limbs. //By default these fit on both flesh and robotic organs and are robotic organ_properties = ORGAN_PROP_PROSTHETIC default_action_type = /datum/action/item_action/organ/augment diff --git a/code/modules/modular_computers/computers/modular_computer/interaction.dm b/code/modules/modular_computers/computers/modular_computer/interaction.dm index b2a0b77524f0..97f6c3738464 100644 --- a/code/modules/modular_computers/computers/modular_computer/interaction.dm +++ b/code/modules/modular_computers/computers/modular_computer/interaction.dm @@ -98,7 +98,7 @@ else if(user.try_unequip(used_item, src)) stored_pen = used_item update_verbs() - to_chat(user, SPAN_NOTICE("You insert \the [used_item] into [src].")) + to_chat(user, SPAN_NOTICE("You insert \the [used_item] into [src].")) return TRUE return ..() diff --git a/code/modules/species/species_hud.dm b/code/modules/species/species_hud.dm index ee873291034d..21cc70f4742c 100644 --- a/code/modules/species/species_hud.dm +++ b/code/modules/species/species_hud.dm @@ -1,5 +1,4 @@ /datum/hud_data - var/has_a_intent = 1 // Set to draw intent box. var/has_m_intent = 1 // Set to draw move intent box. var/has_warnings = 1 // Set to draw environment warnings. var/has_pressure = 1 // Draw the pressure indicator. diff --git a/mods/content/xenobiology/_xenobiology.dme b/mods/content/xenobiology/_xenobiology.dme index 11a5f3972c68..1591ea3f458a 100644 --- a/mods/content/xenobiology/_xenobiology.dme +++ b/mods/content/xenobiology/_xenobiology.dme @@ -50,7 +50,6 @@ #include "slime\slime_commands.dm" #include "slime\slime_comments.dm" #include "slime\slime_follow.dm" -#include "slime\slime_hud.dm" #include "slime\slime_reagents.dm" #include "slime\slime_surgery.dm" #include "slime\slime_update_icon.dm" diff --git a/mods/content/xenobiology/slime/_slime.dm b/mods/content/xenobiology/slime/_slime.dm index 474a98545d16..985cb6ee5610 100644 --- a/mods/content/xenobiology/slime/_slime.dm +++ b/mods/content/xenobiology/slime/_slime.dm @@ -18,7 +18,7 @@ status_flags = CANPARALYSE|CANPUSH butchery_data = null ai = /datum/mob_controller/slime - hud_used = /datum/hud/slime + hud_used = /datum/hud/animal nutrition = 800 var/is_adult = FALSE diff --git a/mods/content/xenobiology/slime/slime_hud.dm b/mods/content/xenobiology/slime/slime_hud.dm deleted file mode 100644 index c1dcf1b914a5..000000000000 --- a/mods/content/xenobiology/slime/slime_hud.dm +++ /dev/null @@ -1,4 +0,0 @@ -/datum/hud/slime/FinalizeInstantiation() - action_intent = new(null, mymob, get_ui_style_data(), get_ui_color(), get_ui_alpha(), UI_ICON_INTENT) - adding = list(action_intent) - ..() diff --git a/mods/gamemodes/deity/mobs/deity_hud.dm b/mods/gamemodes/deity/mobs/deity_hud.dm index 8a9e3d77d096..b93ec04512f1 100644 --- a/mods/gamemodes/deity/mobs/deity_hud.dm +++ b/mods/gamemodes/deity/mobs/deity_hud.dm @@ -1,9 +1,9 @@ /mob/living/deity hud_used = /datum/hud/deity + action_intent_type = /obj/screen/intent/deity /datum/hud/deity/FinalizeInstantiation() - action_intent = new /obj/screen/intent/deity(null, mymob, get_ui_style_data(), get_ui_color(), get_ui_alpha(), UI_ICON_INTENT) - adding += action_intent ..() var/obj/screen/intent/deity/D = action_intent - D.sync_to_mob(mymob) + if(istype(D)) + D.sync_to_mob(mymob) diff --git a/mods/mobs/dionaea/mob/nymph_ui.dm b/mods/mobs/dionaea/mob/nymph_ui.dm index 15ab7bf27eac..2babfc8427ee 100644 --- a/mods/mobs/dionaea/mob/nymph_ui.dm +++ b/mods/mobs/dionaea/mob/nymph_ui.dm @@ -22,6 +22,9 @@ UI_ICON_INVENTORY = 'mods/mobs/dionaea/icons/ui_inventory.dmi' ) +/datum/hud/diona_nymph + action_intent_type = /obj/screen/intent/diona_nymph + /datum/hud/diona_nymph/get_ui_style_data() return GET_DECL(/decl/ui_style/diona) @@ -36,10 +39,9 @@ var/ui_color = get_ui_color() var/ui_alpha = get_ui_alpha() - action_intent = new /obj/screen/intent/diona_nymph(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_INTENT) - mymob.healths = new /obj/screen/diona_health( null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_HEALTH) - src.other = list() - src.adding = list(mymob.healths, action_intent) + mymob.healths = new /obj/screen/diona_health(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_HEALTH) + other = list() + adding = list(mymob.healths) ..() /obj/screen/diona_health diff --git a/mods/species/ascent/mobs/nymph/nymph_ui.dm b/mods/species/ascent/mobs/nymph/nymph_ui.dm index 85225fd26a9c..54efcc1aed68 100644 --- a/mods/species/ascent/mobs/nymph/nymph_ui.dm +++ b/mods/species/ascent/mobs/nymph/nymph_ui.dm @@ -38,6 +38,9 @@ UI_ICON_INVENTORY = 'mods/species/ascent/icons/ui_inventory.dmi' ) +/datum/hud/ascent_nymph + action_intent_type = /obj/screen/intent/ascent_nymph + /datum/hud/ascent_nymph/get_ui_style_data() return GET_DECL(/decl/ui_style/ascent) @@ -54,10 +57,9 @@ molt = new( null, mymob, ui_style, ui_color, ui_alpha) food = new /obj/screen/food( null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_NUTRITION) drink = new /obj/screen/drink( null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_HYDRATION) - action_intent = new /obj/screen/intent/ascent_nymph(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_INTENT) mymob.healths = new /obj/screen/ascent_nymph_health(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_HEALTH) - src.other = list() - src.adding = list(mymob.healths, molt, food, drink, action_intent) + other = list() + adding = list(mymob.healths, molt, food, drink) ..() /obj/screen/ascent_nymph_health From 6fa0a07ae6c4310f6f98d0ccb4ff95e01e8839bf Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Mon, 20 Jan 2025 18:33:48 +1100 Subject: [PATCH 050/120] Refactoring tray growth rate and fixing turfs on Tradeship. --- .../subsystems/{processing => }/overmap.dm | 0 .../subsystems/{ => processing}/plants.dm | 18 +++--- code/game/turfs/floors/subtypes/floor_misc.dm | 8 +++ code/modules/hydroponics/seed.dm | 7 +-- code/modules/hydroponics/trays/tray.dm | 6 -- .../modules/hydroponics/trays/tray_process.dm | 56 ++++++++----------- code/modules/hydroponics/trays/tray_soil.dm | 10 +++- maps/tradeship/tradeship-0.dmm | 12 ++-- mods/gamemodes/deity/mobs/deity_hud.dm | 2 + nebula.dme | 4 +- 10 files changed, 64 insertions(+), 59 deletions(-) rename code/controllers/subsystems/{processing => }/overmap.dm (100%) rename code/controllers/subsystems/{ => processing}/plants.dm (87%) diff --git a/code/controllers/subsystems/processing/overmap.dm b/code/controllers/subsystems/overmap.dm similarity index 100% rename from code/controllers/subsystems/processing/overmap.dm rename to code/controllers/subsystems/overmap.dm diff --git a/code/controllers/subsystems/plants.dm b/code/controllers/subsystems/processing/plants.dm similarity index 87% rename from code/controllers/subsystems/plants.dm rename to code/controllers/subsystems/processing/plants.dm index a6256b563317..c07b5e9c714e 100644 --- a/code/controllers/subsystems/plants.dm +++ b/code/controllers/subsystems/processing/plants.dm @@ -1,11 +1,15 @@ -PROCESSING_SUBSYSTEM_DEF(plants) - name = "Plants" - priority = SS_PRIORITY_PLANTS - runlevels = RUNLEVEL_GAME|RUNLEVEL_POSTGAME - flags = SS_BACKGROUND|SS_POST_FIRE_TIMING - init_order = SS_INIT_PLANTS - wait = 60 +/datum/proc/process_plants() + SHOULD_NOT_SLEEP(TRUE) + return PROCESS_KILL +PROCESSING_SUBSYSTEM_DEF(plants) + name = "Plants" + priority = SS_PRIORITY_PLANTS + runlevels = RUNLEVEL_GAME|RUNLEVEL_POSTGAME + flags = SS_BACKGROUND|SS_POST_FIRE_TIMING + init_order = SS_INIT_PLANTS + wait = 1 MINUTE + process_proc = TYPE_PROC_REF(/datum, process_plants) /// Stores generated fruit descs. var/list/product_descs = list() /// All seed data stored here. diff --git a/code/game/turfs/floors/subtypes/floor_misc.dm b/code/game/turfs/floors/subtypes/floor_misc.dm index fbc7d2400e17..c316080fbe41 100644 --- a/code/game/turfs/floors/subtypes/floor_misc.dm +++ b/code/game/turfs/floors/subtypes/floor_misc.dm @@ -54,6 +54,14 @@ /turf/floor/plating _base_flooring = /decl/flooring/plating // Setting here so overrides on /turf/floor do not impact explicitly typed plating turfs. +// Dirt plating for Tradeship farms. +/turf/floor/plating/dirt + name = "dirt" + icon = 'icons/turf/flooring/dirt.dmi' + icon_state = "dirt" + color = "#41311b" + _flooring = /decl/flooring/dirt + /turf/floor/plating/broken _floor_broken = TRUE diff --git a/code/modules/hydroponics/seed.dm b/code/modules/hydroponics/seed.dm index 873ec702462e..a14290807250 100644 --- a/code/modules/hydroponics/seed.dm +++ b/code/modules/hydroponics/seed.dm @@ -256,16 +256,15 @@ var/growth_rate = 1 var/turf/current_turf = isturf(holder) ? holder : get_turf(holder) - if(istype(holder) && !holder.mechanical && current_turf) - growth_rate = current_turf.get_plant_growth_rate() + if(istype(holder)) + growth_rate = holder.get_growth_rate() var/health_change = 0 // Handle gas consumption. if(consume_gasses && consume_gasses.len) var/missing_gas = 0 for(var/gas in consume_gasses) - if(environment && environment.gas && environment.gas[gas] && \ - environment.gas[gas] >= consume_gasses[gas]) + if(LAZYACCESS(environment?.gas, gas) >= consume_gasses[gas]) if(!check_only) environment.adjust_gas(gas,-consume_gasses[gas],1) else diff --git a/code/modules/hydroponics/trays/tray.dm b/code/modules/hydroponics/trays/tray.dm index c1252de11d33..cf6cfa6bf737 100644 --- a/code/modules/hydroponics/trays/tray.dm +++ b/code/modules/hydroponics/trays/tray.dm @@ -36,8 +36,6 @@ // Mechanical concerns. var/plant_health = 0 // Plant health. var/lastproduce = 0 // Last time tray was harvested - var/lastcycle = 0 // Cycle timing/tracking var. - var/cycledelay = 150 // Delay per cycle. var/closed_system // If set, the tray will attempt to take atmos from a pipe. var/force_update // Set this to bypass the cycle time check. var/obj/temp_chem_holder // Something to hold reagents during process_reagents() @@ -328,7 +326,6 @@ return //Weed does not exist, someone fucked up. age = 0 - lastcycle = world.time harvest = 0 weedlevel = 0 pestlevel = 0 @@ -397,7 +394,6 @@ set_seed(SSplants.seeds[newseed]) mutate(1) plant_health = seed.get_trait(TRAIT_ENDURANCE) // re-run in case mutation changed our endurance - lastcycle = world.time update_icon() visible_message("The [previous_plant] has suddenly mutated into [seed.display_name]!") @@ -556,7 +552,6 @@ //Snowflakey, maybe move this to the seed datum // re-running to adjust based on planting method plant_health = (istype(S, /obj/item/seeds/extracted/cutting) ? round(seed.get_trait(TRAIT_ENDURANCE)/rand(2,5)) : seed.get_trait(TRAIT_ENDURANCE)) - lastcycle = world.time var/needed_skill = seed.mysterious ? SKILL_ADEPT : SKILL_BASIC if(prob(user.skill_fail_chance(SKILL_BOTANY, 40, needed_skill))) @@ -654,7 +649,6 @@ age = 1 // re-running to adjust for planting method plant_health = (istype(S, /obj/item/seeds/extracted/cutting) ? round(seed.get_trait(TRAIT_ENDURANCE)/rand(2,5)) : seed.get_trait(TRAIT_ENDURANCE)) - lastcycle = world.time check_plant_health() qdel(S) diff --git a/code/modules/hydroponics/trays/tray_process.dm b/code/modules/hydroponics/trays/tray_process.dm index 05c029e69b47..dbcf6f194470 100644 --- a/code/modules/hydroponics/trays/tray_process.dm +++ b/code/modules/hydroponics/trays/tray_process.dm @@ -1,37 +1,29 @@ -/obj/machinery/portable_atmospherics/hydroponics/Process() - - var/growth_rate = 1 - var/turf/T = get_turf(src) - if(istype(T)) - if(!mechanical) - growth_rate = T.get_plant_growth_rate() - - if(!closed_system) - var/space_left = reagents ? (reagents.maximum_volume - reagents.total_volume) : 0 - if(space_left > 0 && reagents.total_volume < 10) - // Handle nearby smoke if any. - for(var/obj/effect/effect/smoke/chem/smoke in view(1, src)) - if(smoke.reagents.total_volume) - smoke.reagents.trans_to_obj(src, 5, copy = 1) - // Handle environmental effects like weather and flooding. - if(T.reagents?.total_volume) - T.reagents.trans_to_obj(src, min(space_left, min(T.reagents.total_volume, rand(5,10)))) - if(istype(T.weather?.weather_system?.current_state, /decl/state/weather/rain)) - var/decl/state/weather/rain/rain = T.weather.weather_system.current_state - if(rain.is_liquid) - reagents.add_reagent(T.weather.water_material, min(space_left, rand(3,5))) +/obj/machinery/portable_atmospherics/hydroponics/proc/get_growth_rate() + return 1 + +/obj/machinery/portable_atmospherics/hydroponics/process_plants() + + var/growth_rate = get_growth_rate() + var/turf/my_turf = get_turf(src) + if(istype(my_turf) && !closed_system) + var/space_left = reagents ? (reagents.maximum_volume - reagents.total_volume) : 0 + if(space_left > 0 && reagents.total_volume < 10) + // Handle nearby smoke if any. + for(var/obj/effect/effect/smoke/chem/smoke in view(1, src)) + if(smoke.reagents.total_volume) + smoke.reagents.trans_to_obj(src, 5, copy = 1) + // Handle environmental effects like weather and flooding. + if(my_turf.reagents?.total_volume) + my_turf.reagents.trans_to_obj(src, min(space_left, min(my_turf.reagents.total_volume, rand(5,10)))) + if(istype(my_turf.weather?.weather_system?.current_state, /decl/state/weather/rain)) + var/decl/state/weather/rain/rain = my_turf.weather.weather_system.current_state + if(rain.is_liquid) + reagents.add_reagent(my_turf.weather.water_material, min(space_left, rand(3,5))) //Do this even if we're not ready for a plant cycle. process_reagents() var/needs_icon_update = 0 - // Update values every cycle rather than every process() tick. - if(force_update) - force_update = 0 - else if(world.time < (lastcycle + cycledelay)) - return - lastcycle = world.time - // Mutation level drops each main tick. mutation_level -= rand(2,4) @@ -94,7 +86,7 @@ if(closed_system && (get_port() || holding)) environment = air_contents // If atmos input is not there, grab from turf. - if(!environment && istype(T)) environment = T.return_air() + if(!environment && istype(my_turf)) environment = my_turf.return_air() if(!environment) return // Seed datum handles gasses, light and pressure. @@ -148,9 +140,9 @@ if(!closed_system && \ seed.get_trait(TRAIT_SPREAD) == 2 && \ 2 * age >= seed.get_trait(TRAIT_MATURATION) && \ - !(locate(/obj/effect/vine) in T) && \ + !(locate(/obj/effect/vine) in my_turf) && \ prob(2 * seed.get_trait(TRAIT_POTENCY))) - new /obj/effect/vine(T, seed) + new /obj/effect/vine(my_turf, seed) if(prob(3)) // On each tick, there's a chance the pest population will increase pestlevel += 0.1 * growth_rate diff --git a/code/modules/hydroponics/trays/tray_soil.dm b/code/modules/hydroponics/trays/tray_soil.dm index 7a89804a38a9..ea007095eccb 100644 --- a/code/modules/hydroponics/trays/tray_soil.dm +++ b/code/modules/hydroponics/trays/tray_soil.dm @@ -24,6 +24,10 @@ . -= /decl/interaction_handler/drink . -= /decl/interaction_handler/wash_hands +/obj/machinery/portable_atmospherics/hydroponics/soil/get_growth_rate() + var/turf/my_turf = get_turf(src) + return max(0, my_turf?.get_plant_growth_rate()) + /obj/machinery/portable_atmospherics/hydroponics/soil/Initialize() . = ..() @@ -162,7 +166,6 @@ dead = 0 age = start_mature ? seed.get_trait(TRAIT_MATURATION) : 1 plant_health = seed.get_trait(TRAIT_ENDURANCE) - lastcycle = world.time if(isnull(default_pixel_y)) default_pixel_y = rand(-12,12) if(isnull(default_pixel_y)) @@ -199,4 +202,7 @@ for(var/obj/effect/vine/plant in get_turf(src)) if(plant.invisibility == INVISIBILITY_MAXIMUM) plant.set_invisibility(initial(plant.invisibility)) - . = ..() \ No newline at end of file + . = ..() + +/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/get_growth_rate() + return max(..(), 1) diff --git a/maps/tradeship/tradeship-0.dmm b/maps/tradeship/tradeship-0.dmm index 6fdddb5e5340..e56faf1cb618 100644 --- a/maps/tradeship/tradeship-0.dmm +++ b/maps/tradeship/tradeship-0.dmm @@ -1009,7 +1009,7 @@ "dN" = ( /obj/machinery/portable_atmospherics/hydroponics/soil, /obj/item/tool/hoe/mini, -/turf/floor, +/turf/floor/plating/dirt, /area/ship/trade/aft_port_underside_maint) "en" = ( /turf/floor/wood/walnut, @@ -1179,7 +1179,7 @@ icon_state = "4-8" }, /obj/machinery/portable_atmospherics/hydroponics/soil, -/turf/floor, +/turf/floor/plating/dirt, /area/ship/trade/aft_port_underside_maint) "lv" = ( /obj/effect/decal/cleanable/dirt/visible, @@ -1231,11 +1231,11 @@ /area/ship/trade/fore_port_underside_maint) "oo" = ( /obj/machinery/portable_atmospherics/hydroponics/soil, -/turf/floor, +/turf/floor/plating/dirt, /area/ship/trade/aft_starboard_underside_maint) "or" = ( /obj/machinery/portable_atmospherics/hydroponics/soil, -/turf/floor, +/turf/floor/plating/dirt, /area/ship/trade/aft_port_underside_maint) "os" = ( /obj/structure/lattice, @@ -1483,7 +1483,7 @@ /obj/machinery/light{ dir = 4 }, -/turf/floor, +/turf/floor/plating/dirt, /area/ship/trade/aft_port_underside_maint) "xP" = ( /obj/structure/disposalpipe/segment{ @@ -2053,7 +2053,7 @@ /obj/machinery/light{ dir = 4 }, -/turf/floor, +/turf/floor/plating/dirt, /area/ship/trade/aft_starboard_underside_maint) "QW" = ( /obj/item/stack/tile/floor/five, diff --git a/mods/gamemodes/deity/mobs/deity_hud.dm b/mods/gamemodes/deity/mobs/deity_hud.dm index b93ec04512f1..820a493fa996 100644 --- a/mods/gamemodes/deity/mobs/deity_hud.dm +++ b/mods/gamemodes/deity/mobs/deity_hud.dm @@ -1,5 +1,7 @@ /mob/living/deity hud_used = /datum/hud/deity + +/datum/hud/deity action_intent_type = /obj/screen/intent/deity /datum/hud/deity/FinalizeInstantiation() diff --git a/nebula.dme b/nebula.dme index 85539f1a37f4..03330a9790f4 100644 --- a/nebula.dme +++ b/nebula.dme @@ -282,7 +282,7 @@ #include "code\controllers\subsystems\mapping.dm" #include "code\controllers\subsystems\misc_late.dm" #include "code\controllers\subsystems\overlays.dm" -#include "code\controllers\subsystems\plants.dm" +#include "code\controllers\subsystems\overmap.dm" #include "code\controllers\subsystems\radiation.dm" #include "code\controllers\subsystems\shuttle.dm" #include "code\controllers\subsystems\skybox.dm" @@ -326,7 +326,7 @@ #include "code\controllers\subsystems\processing\mobs.dm" #include "code\controllers\subsystems\processing\nano.dm" #include "code\controllers\subsystems\processing\obj.dm" -#include "code\controllers\subsystems\processing\overmap.dm" +#include "code\controllers\subsystems\processing\plants.dm" #include "code\controllers\subsystems\processing\processing.dm" #include "code\controllers\subsystems\processing\projectiles.dm" #include "code\controllers\subsystems\processing\temperature.dm" From c5ec9e53df34dd6c7bb2233be2d5f489672eae62 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Mon, 20 Jan 2025 19:42:29 +1100 Subject: [PATCH 051/120] Lowers some ore smelting temperatures for the sake of the medieval map. --- code/__defines/research.dm | 3 ++- .../definitions/solids/_mat_solid.dm | 2 +- .../solids/materials_solid_metal.dm | 1 + .../solids/materials_solid_mineral.dm | 22 +++++++++---------- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/code/__defines/research.dm b/code/__defines/research.dm index 2fb5ac649e4c..3898d8dc2958 100644 --- a/code/__defines/research.dm +++ b/code/__defines/research.dm @@ -19,7 +19,8 @@ #define HOLLOW_OBJECT_MATTER_MULTIPLIER 0.05 #define BASE_OBJECT_MATTER_MULTPLIER 0.25 -#define GENERIC_SMELTING_HEAT_POINT 1350 CELSIUS +#define LOW_SMELTING_HEAT_POINT 1150 CELSIUS // Reachable with coal in a kiln on the medieval maps. +#define GENERIC_SMELTING_HEAT_POINT 1350 CELSIUS // Reachable with coal and a bellows in a kiln on medieval maps. #define HIGH_SMELTING_HEAT_POINT 4000 CELSIUS // must be at least 4074K (3800 C) to melt graphite #define TECH_MATERIAL "materials" diff --git a/code/modules/materials/definitions/solids/_mat_solid.dm b/code/modules/materials/definitions/solids/_mat_solid.dm index 5e7797cd07d1..88085e5c1d9c 100644 --- a/code/modules/materials/definitions/solids/_mat_solid.dm +++ b/code/modules/materials/definitions/solids/_mat_solid.dm @@ -22,4 +22,4 @@ solution_name = "[name] solution" if(!ore_compresses_to) ore_compresses_to = type - . = ..() \ No newline at end of file + . = ..() diff --git a/code/modules/materials/definitions/solids/materials_solid_metal.dm b/code/modules/materials/definitions/solids/materials_solid_metal.dm index d5a796870133..5aa1b8acd502 100644 --- a/code/modules/materials/definitions/solids/materials_solid_metal.dm +++ b/code/modules/materials/definitions/solids/materials_solid_metal.dm @@ -486,3 +486,4 @@ taste_mult = 0 //no taste color = "#dcdcdc" value = 0.5 + melting_point = 3422 CELSIUS diff --git a/code/modules/materials/definitions/solids/materials_solid_mineral.dm b/code/modules/materials/definitions/solids/materials_solid_mineral.dm index 6b11ffc0f8b7..4317abc5b12d 100644 --- a/code/modules/materials/definitions/solids/materials_solid_mineral.dm +++ b/code/modules/materials/definitions/solids/materials_solid_mineral.dm @@ -285,7 +285,7 @@ /decl/material/solid/metal/iron = 0.8, /decl/material/solid/slag = 0.2 ) - heating_point = GENERIC_SMELTING_HEAT_POINT + heating_point = LOW_SMELTING_HEAT_POINT heating_sound = null heating_message = null ore_result_amount = 2 @@ -330,7 +330,7 @@ /decl/material/solid/metal/silver = 0.4, /decl/material/solid/slag = 0.2 ) - heating_point = GENERIC_SMELTING_HEAT_POINT + heating_point = LOW_SMELTING_HEAT_POINT heating_sound = null heating_message = null ore_result_amount = 2 @@ -352,7 +352,7 @@ /decl/material/solid/metal/copper = 0.1, /decl/material/solid/slag = 0.1 ) - heating_point = GENERIC_SMELTING_HEAT_POINT + heating_point = LOW_SMELTING_HEAT_POINT heating_sound = null heating_message = null ore_result_amount = 2 @@ -379,7 +379,7 @@ /decl/material/solid/metal/copper = 0.6, /decl/material/solid/slag = 0.4 ) - heating_point = GENERIC_SMELTING_HEAT_POINT + heating_point = LOW_SMELTING_HEAT_POINT heating_sound = null heating_message = null ore_result_amount = 2 @@ -439,7 +439,7 @@ /decl/material/solid/metal/tungsten = 0.2, /decl/material/solid/slag = 0.1 ) - heating_point = GENERIC_SMELTING_HEAT_POINT + heating_point = LOW_SMELTING_HEAT_POINT heating_sound = null heating_message = null ore_name = "cassiterite" @@ -467,7 +467,7 @@ /decl/material/solid/metal/iron = 0.2, /decl/material/solid/slag = 0.5 ) - heating_point = GENERIC_SMELTING_HEAT_POINT + heating_point = LOW_SMELTING_HEAT_POINT heating_sound = null heating_message = null ore_name = "wolframite" @@ -496,7 +496,7 @@ /decl/material/solid/glass = 0.1, /decl/material/solid/slag = 0.3 ) - heating_point = GENERIC_SMELTING_HEAT_POINT + heating_point = LOW_SMELTING_HEAT_POINT heating_sound = null heating_message = null ore_name = "sperrylite" @@ -525,7 +525,7 @@ /decl/material/solid/metal/iron = 0.1, /decl/material/solid/slag = 0.2 ) - heating_point = GENERIC_SMELTING_HEAT_POINT + heating_point = LOW_SMELTING_HEAT_POINT heating_sound = null heating_message = null ore_name = "sphalerite" @@ -554,7 +554,7 @@ /decl/material/solid/metal/silver = 0.1, /decl/material/solid/slag = 0.1 ) - heating_point = GENERIC_SMELTING_HEAT_POINT + heating_point = LOW_SMELTING_HEAT_POINT heating_sound = null heating_message = null ore_name = "galena" @@ -582,7 +582,7 @@ /decl/material/solid/metal/silver = 0.3, /decl/material/solid/slag = 0.1 ) - heating_point = GENERIC_SMELTING_HEAT_POINT + heating_point = LOW_SMELTING_HEAT_POINT heating_sound = null heating_message = null ore_name = "calaverite" @@ -609,7 +609,7 @@ /decl/material/solid/metal/lead = 0.4, /decl/material/solid/slag = 0.3 ) - heating_point = GENERIC_SMELTING_HEAT_POINT + heating_point = LOW_SMELTING_HEAT_POINT heating_sound = null heating_message = null ore_name = "crocoite" From a2a062bc3b507d5993088ef28a2b872440a2efae Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 16 Jan 2025 19:01:08 +1100 Subject: [PATCH 052/120] Guns use get_stored_ammo_count() where possible. --- code/game/machinery/turrets/_turrets.dm | 4 ++-- code/game/machinery/turrets/turret_ammo.dm | 4 ++-- code/modules/projectiles/guns/projectile.dm | 8 ++++---- code/modules/projectiles/guns/projectile/automatic.dm | 2 +- code/modules/projectiles/guns/projectile/pistol.dm | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/code/game/machinery/turrets/_turrets.dm b/code/game/machinery/turrets/_turrets.dm index 3030bc2bef9f..c7b9825b8d75 100644 --- a/code/game/machinery/turrets/_turrets.dm +++ b/code/game/machinery/turrets/_turrets.dm @@ -188,7 +188,7 @@ playsound(src.loc, 'sound/weapons/flipblade.ogg', 50, 1) reloading_progress = 0 - else if(stored_magazine && length(stored_magazine.stored_ammo) < stored_magazine.max_ammo) + else if(stored_magazine && length(stored_magazine.get_stored_ammo_count()) < stored_magazine.max_ammo) var/obj/item/stock_parts/ammo_box/ammo_box = get_component_of_type(/obj/item/stock_parts/ammo_box) if(ammo_box?.is_functional() && ammo_box.stored_caliber == proj_gun.caliber) var/obj/item/ammo_casing/casing = ammo_box.remove_ammo(stored_magazine) @@ -366,7 +366,7 @@ // Only reload the magazine if we're completely out of ammo or we don't have a target. if(ammo_remaining == 0) return TRUE - if(!is_valid_target(target?.resolve()) && length(proj_gun.ammo_magazine.stored_ammo) != proj_gun.ammo_magazine.max_ammo) + if(!is_valid_target(target?.resolve()) && length(proj_gun.ammo_magazine.get_stored_ammo_count()) != proj_gun.ammo_magazine.max_ammo) return TRUE else return FALSE diff --git a/code/game/machinery/turrets/turret_ammo.dm b/code/game/machinery/turrets/turret_ammo.dm index 52cf5825df0c..175dfc0911bb 100644 --- a/code/game/machinery/turrets/turret_ammo.dm +++ b/code/game/machinery/turrets/turret_ammo.dm @@ -50,7 +50,7 @@ if(stored_caliber && magazine.caliber != stored_caliber) to_chat(user, SPAN_WARNING("The caliber of \the [magazine] does not match the caliber stored in \the [src]!")) return TRUE - if(!length(magazine.stored_ammo)) + if(!length(magazine.get_stored_ammo_count())) to_chat(user, SPAN_WARNING("\The [magazine] is empty!")) return TRUE if(length(stored_ammo) >= max_ammo) @@ -58,7 +58,7 @@ return TRUE stored_caliber = magazine.caliber - for(var/obj/item/ammo_casing/casing in magazine.stored_ammo) + for(var/obj/item/ammo_casing/casing in magazine.get_stored_ammo_count()) // Just in case. if(casing.caliber != stored_caliber) continue diff --git a/code/modules/projectiles/guns/projectile.dm b/code/modules/projectiles/guns/projectile.dm index 1466e138166a..10aed91cf2cb 100644 --- a/code/modules/projectiles/guns/projectile.dm +++ b/code/modules/projectiles/guns/projectile.dm @@ -74,8 +74,8 @@ if(handle_casings == HOLD_CASINGS) ammo_magazine.stored_ammo += chambered ammo_magazine.initial_ammo-- - else if(ammo_magazine.stored_ammo.len) - chambered = ammo_magazine.stored_ammo[ammo_magazine.stored_ammo.len] + else if(length(ammo_magazine.stored_ammo)) + chambered = ammo_magazine.stored_ammo[length(ammo_magazine.stored_ammo)] if(handle_casings != HOLD_CASINGS) ammo_magazine.stored_ammo -= chambered @@ -334,9 +334,9 @@ /obj/item/gun/projectile/proc/get_ammo_indicator() var/base_state = get_world_inventory_state() - if(!ammo_magazine || !LAZYLEN(ammo_magazine.stored_ammo)) + if(!ammo_magazine || !ammo_magazine.get_stored_ammo_count()) return mutable_appearance(icon, "[base_state]_ammo_bad") - else if(LAZYLEN(ammo_magazine.stored_ammo) <= 0.5 * ammo_magazine.max_ammo) + else if(LAZYLEN(ammo_magazine.get_stored_ammo_count()) <= 0.5 * ammo_magazine.max_ammo) return mutable_appearance(icon, "[base_state]_ammo_warn") else return mutable_appearance(icon, "[base_state]_ammo_ok") diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index 7505d0152aa7..802b1f93863c 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -35,7 +35,7 @@ /obj/item/gun/projectile/automatic/smg/on_update_icon() ..() if(ammo_magazine) - add_overlay("[get_world_inventory_state()]mag-[round(length(ammo_magazine.stored_ammo),5)]") + add_overlay("[get_world_inventory_state()]mag-[round(ammo_magazine.get_stored_ammo_count(),5)]") /obj/item/gun/projectile/automatic/assault_rifle name = "assault rifle" diff --git a/code/modules/projectiles/guns/projectile/pistol.dm b/code/modules/projectiles/guns/projectile/pistol.dm index 638376989eeb..8ccdb6232915 100644 --- a/code/modules/projectiles/guns/projectile/pistol.dm +++ b/code/modules/projectiles/guns/projectile/pistol.dm @@ -17,7 +17,7 @@ /obj/item/gun/projectile/pistol/update_base_icon_state() . = ..() - if(!length(ammo_magazine?.stored_ammo)) + if(!length(ammo_magazine?.get_stored_ammo_count())) var/empty_state = "[icon_state]-e" if(check_state_in_icon(empty_state, icon)) icon_state = empty_state From 114ad7d3318f1450f7a37dad1b79c7dd2e79b5b6 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 16 Jan 2025 19:14:20 +1100 Subject: [PATCH 053/120] Various MRE fixes. --- code/game/objects/items/weapons/storage/mre.dm | 6 +++++- code/game/objects/random/subtypes/food.dm | 3 ++- .../reagents/reagent_containers/packets.dm | 17 ++++++++++++++++- maps/ministation/ministation-1.dmm | 6 +++--- 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/code/game/objects/items/weapons/storage/mre.dm b/code/game/objects/items/weapons/storage/mre.dm index 8c2acb816db5..b5d3ffc9596c 100644 --- a/code/game/objects/items/weapons/storage/mre.dm +++ b/code/game/objects/items/weapons/storage/mre.dm @@ -12,6 +12,7 @@ MRE Stuff obj_flags = OBJ_FLAG_HOLLOW var/main_meal = /obj/item/mrebag var/meal_desc = "This one is menu 1, meat pizza." + var/has_been_opened = FALSE /obj/item/mre/WillContain() . = list( @@ -36,11 +37,14 @@ MRE Stuff /obj/item/mre/on_update_icon() . = ..() icon_state = get_world_inventory_state() - if(storage?.opened) + if(has_been_opened) icon_state = "[icon_state]-open" /obj/item/mre/attack_self(mob/user) if(storage && !storage.opened) + if(!has_been_opened) + has_been_opened = TRUE + to_chat(user, SPAN_NOTICE("You tear \the [src] open!")) storage.open(user) return TRUE return ..() diff --git a/code/game/objects/random/subtypes/food.dm b/code/game/objects/random/subtypes/food.dm index f390e57cf5d1..36aa8a4a37e6 100644 --- a/code/game/objects/random/subtypes/food.dm +++ b/code/game/objects/random/subtypes/food.dm @@ -102,7 +102,8 @@ /obj/random/mre/spread/spawn_choices() var/static/list/spawnable_choices = list( /obj/item/chems/packet/jelly, - /obj/item/chems/packet/honey + /obj/item/chems/packet/honey, + /obj/item/chems/packet/honey_fake ) return spawnable_choices diff --git a/code/modules/reagents/reagent_containers/packets.dm b/code/modules/reagents/reagent_containers/packets.dm index c46af37998fb..391c3440471b 100644 --- a/code/modules/reagents/reagent_containers/packets.dm +++ b/code/modules/reagents/reagent_containers/packets.dm @@ -7,7 +7,14 @@ amount_per_transfer_from_this = 1 volume = 10 -/obj/item/chems/packet/afterattack(var/obj/target, var/mob/user, var/proximity) +/obj/item/chems/packet/attack_self(mob/user) + if(!ATOM_IS_OPEN_CONTAINER(src)) + atom_flags |= ATOM_FLAG_OPEN_CONTAINER + to_chat(user, SPAN_NOTICE("You tear \the [src] open.")) + return TRUE + return ..() + +/obj/item/chems/packet/afterattack(obj/target, mob/user, proximity) if(!proximity) return ..() if(standard_dispenser_refill(user, target)) @@ -54,6 +61,14 @@ icon = 'icons/obj/food/condiments/packets/packet_medium.dmi' /obj/item/chems/packet/honey/populate_reagents() + add_to_reagents(/decl/material/liquid/nutriment/honey, reagents.maximum_volume) + +/obj/item/chems/packet/honey_fake + name = "'honey' packet" + desc = "Contains 10u of allergen-free non-GMO 'honey'." + icon = 'icons/obj/food/condiments/packets/packet_medium.dmi' + +/obj/item/chems/packet/honey_fake/populate_reagents() add_to_reagents(/decl/material/liquid/nutriment/sugar, reagents.maximum_volume) /obj/item/chems/packet/capsaicin diff --git a/maps/ministation/ministation-1.dmm b/maps/ministation/ministation-1.dmm index 727dd8ac5a0a..9994e8a347ed 100644 --- a/maps/ministation/ministation-1.dmm +++ b/maps/ministation/ministation-1.dmm @@ -9764,12 +9764,12 @@ /obj/structure/table/woodentable, /obj/item/eftpos, /obj/item/chems/spray/cleaner, +/obj/item/chems/packet/honey_fake, +/obj/item/chems/packet/honey_fake, /obj/item/chems/packet/honey, /obj/item/chems/packet/honey, /obj/item/chems/packet/honey, -/obj/item/chems/packet/honey, -/obj/item/chems/packet/honey, -/obj/item/chems/packet/honey, +/obj/item/chems/packet/honey_fake, /obj/item/chems/packet/honey, /turf/floor/lino, /area/ministation/cafe) From e8494b16f546a2e1617db8c11743409b796df102 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 16 Jan 2025 19:19:07 +1100 Subject: [PATCH 054/120] Cigboxes will use their empty state when empty. --- code/game/objects/items/weapons/storage/fancy/_fancy.dm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/code/game/objects/items/weapons/storage/fancy/_fancy.dm b/code/game/objects/items/weapons/storage/fancy/_fancy.dm index ec59092259d8..66774d7abaeb 100644 --- a/code/game/objects/items/weapons/storage/fancy/_fancy.dm +++ b/code/game/objects/items/weapons/storage/fancy/_fancy.dm @@ -14,7 +14,11 @@ /obj/item/box/fancy/proc/update_icon_state() icon_state = initial(icon_state) - if(key_type && storage?.opened) + if(!length(contents)) + var/empty_state = "[icon_state]0" + if(check_state_in_icon(empty_state, icon)) + icon_state = empty_state + else if(key_type && storage?.opened) icon_state = "[icon_state][count_by_type(contents, key_type)]" /obj/item/box/fancy/proc/add_contents_overlays() From d7a3aaa7701050964c0afed62f9ed8addf629db6 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 16 Jan 2025 19:25:39 +1100 Subject: [PATCH 055/120] Proper fix for MRE opening. --- code/datums/extensions/storage/subtypes_mre.dm | 7 +++++-- code/game/objects/items/weapons/storage/mre.dm | 6 +++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/code/datums/extensions/storage/subtypes_mre.dm b/code/datums/extensions/storage/subtypes_mre.dm index 5b7f49107160..b5045c1fc1b2 100644 --- a/code/datums/extensions/storage/subtypes_mre.dm +++ b/code/datums/extensions/storage/subtypes_mre.dm @@ -5,8 +5,11 @@ open_sound = 'sound/effects/rip1.ogg' /datum/storage/mre/open(mob/user) - if(!opened) - to_chat(user, "You tear open the bag, breaking the vacuum seal.") + var/obj/item/mre/mre = holder + if(istype(mre) && !mre.has_been_opened) + to_chat(user, SPAN_NOTICE("You tear open the bag, breaking the vacuum seal.")) + mre.has_been_opened = TRUE + mre.update_icon() . = ..() /datum/storage/mrebag diff --git a/code/game/objects/items/weapons/storage/mre.dm b/code/game/objects/items/weapons/storage/mre.dm index b5d3ffc9596c..70bbf23d7775 100644 --- a/code/game/objects/items/weapons/storage/mre.dm +++ b/code/game/objects/items/weapons/storage/mre.dm @@ -34,6 +34,9 @@ MRE Stuff . = ..() to_chat(user, meal_desc) +/obj/item/mre/attack_self(mob/user) + . = ..() + /obj/item/mre/on_update_icon() . = ..() icon_state = get_world_inventory_state() @@ -42,9 +45,6 @@ MRE Stuff /obj/item/mre/attack_self(mob/user) if(storage && !storage.opened) - if(!has_been_opened) - has_been_opened = TRUE - to_chat(user, SPAN_NOTICE("You tear \the [src] open!")) storage.open(user) return TRUE return ..() From 790a1e55dd98dca412ce78f6b7fb6e17e8d141d3 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 16 Jan 2025 19:36:18 +1100 Subject: [PATCH 056/120] Actually fixes gun ammo checking. --- code/game/machinery/turrets/_turrets.dm | 4 ++-- code/game/machinery/turrets/turret_ammo.dm | 2 +- code/modules/projectiles/guns/projectile/dartgun.dm | 4 ++-- code/modules/projectiles/guns/projectile/pistol.dm | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/code/game/machinery/turrets/_turrets.dm b/code/game/machinery/turrets/_turrets.dm index c7b9825b8d75..957c34078890 100644 --- a/code/game/machinery/turrets/_turrets.dm +++ b/code/game/machinery/turrets/_turrets.dm @@ -188,7 +188,7 @@ playsound(src.loc, 'sound/weapons/flipblade.ogg', 50, 1) reloading_progress = 0 - else if(stored_magazine && length(stored_magazine.get_stored_ammo_count()) < stored_magazine.max_ammo) + else if(stored_magazine && stored_magazine.get_stored_ammo_count() < stored_magazine.max_ammo) var/obj/item/stock_parts/ammo_box/ammo_box = get_component_of_type(/obj/item/stock_parts/ammo_box) if(ammo_box?.is_functional() && ammo_box.stored_caliber == proj_gun.caliber) var/obj/item/ammo_casing/casing = ammo_box.remove_ammo(stored_magazine) @@ -366,7 +366,7 @@ // Only reload the magazine if we're completely out of ammo or we don't have a target. if(ammo_remaining == 0) return TRUE - if(!is_valid_target(target?.resolve()) && length(proj_gun.ammo_magazine.get_stored_ammo_count()) != proj_gun.ammo_magazine.max_ammo) + if(!is_valid_target(target?.resolve()) && proj_gun.ammo_magazine.get_stored_ammo_count() != proj_gun.ammo_magazine.max_ammo) return TRUE else return FALSE diff --git a/code/game/machinery/turrets/turret_ammo.dm b/code/game/machinery/turrets/turret_ammo.dm index 175dfc0911bb..2ae590923072 100644 --- a/code/game/machinery/turrets/turret_ammo.dm +++ b/code/game/machinery/turrets/turret_ammo.dm @@ -50,7 +50,7 @@ if(stored_caliber && magazine.caliber != stored_caliber) to_chat(user, SPAN_WARNING("The caliber of \the [magazine] does not match the caliber stored in \the [src]!")) return TRUE - if(!length(magazine.get_stored_ammo_count())) + if(!magazine.get_stored_ammo_count()) to_chat(user, SPAN_WARNING("\The [magazine] is empty!")) return TRUE if(length(stored_ammo) >= max_ammo) diff --git a/code/modules/projectiles/guns/projectile/dartgun.dm b/code/modules/projectiles/guns/projectile/dartgun.dm index a34c5d36ae99..24792f96e073 100644 --- a/code/modules/projectiles/guns/projectile/dartgun.dm +++ b/code/modules/projectiles/guns/projectile/dartgun.dm @@ -37,13 +37,13 @@ /obj/item/gun/projectile/dartgun/on_update_icon() ..() if(ammo_magazine) - icon_state = "[get_world_inventory_state()]-[clamp(length(ammo_magazine.get_stored_ammo_count()), 0, 5)]" + icon_state = "[get_world_inventory_state()]-[clamp(ammo_magazine.get_stored_ammo_count(), 0, 5)]" else icon_state = get_world_inventory_state() /obj/item/gun/projectile/dartgun/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) if(overlay && (slot in user_mob?.get_held_item_slots()) && ammo_magazine) - overlay.icon_state += "-[clamp(length(ammo_magazine.get_stored_ammo_count()), 0, 5)]" + overlay.icon_state += "-[clamp(ammo_magazine.get_stored_ammo_count(), 0, 5)]" . = ..() /obj/item/gun/projectile/dartgun/consume_next_projectile() diff --git a/code/modules/projectiles/guns/projectile/pistol.dm b/code/modules/projectiles/guns/projectile/pistol.dm index 8ccdb6232915..e64e7c3f731e 100644 --- a/code/modules/projectiles/guns/projectile/pistol.dm +++ b/code/modules/projectiles/guns/projectile/pistol.dm @@ -17,7 +17,7 @@ /obj/item/gun/projectile/pistol/update_base_icon_state() . = ..() - if(!length(ammo_magazine?.get_stored_ammo_count())) + if(!ammo_magazine?.get_stored_ammo_count()) var/empty_state = "[icon_state]-e" if(check_state_in_icon(empty_state, icon)) icon_state = empty_state From dd352345afbeda8bed693d00f1272e41783c717e Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 16 Jan 2025 19:40:23 +1100 Subject: [PATCH 057/120] Fixes seeds using seed ID instead of display name. --- code/modules/hydroponics/trays/tray_soil.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/hydroponics/trays/tray_soil.dm b/code/modules/hydroponics/trays/tray_soil.dm index 7a89804a38a9..d96448d41d9a 100644 --- a/code/modules/hydroponics/trays/tray_soil.dm +++ b/code/modules/hydroponics/trays/tray_soil.dm @@ -63,7 +63,7 @@ return if(prob(25)) return - to_chat(walker, SPAN_DANGER("You trample \the [seed]!")) + to_chat(walker, SPAN_DANGER("You trample \the [seed.display_name]!")) plant_health = max(0, plant_health - rand(3,5)) check_plant_health() From 33fdcba6c5259120ae81a0c9265e4d2988de4cde Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 16 Jan 2025 19:48:12 +1100 Subject: [PATCH 058/120] Vended tea/coffee just uses a generic 'cup of tea' name. --- code/modules/reagents/reagent_containers/drinks.dm | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/code/modules/reagents/reagent_containers/drinks.dm b/code/modules/reagents/reagent_containers/drinks.dm index 46c56514eee4..053ccf480c01 100644 --- a/code/modules/reagents/reagent_containers/drinks.dm +++ b/code/modules/reagents/reagent_containers/drinks.dm @@ -148,7 +148,7 @@ add_to_reagents(/decl/material/liquid/drink/milk/chocolate, reagents.maximum_volume) /obj/item/chems/drinks/coffee - name = "\improper Robust Coffee" + name = "cup of coffee" desc = "Careful, the beverage you're about to enjoy is extremely hot." icon_state = "coffee" center_of_mass = @'{"x":15,"y":10}' @@ -269,16 +269,14 @@ //tea and tea accessories /obj/item/chems/drinks/tea - name = "cup of tea master item" + name = "cup of tea" desc = "A tall plastic cup full of the concept and ideal of tea." icon_state = "coffee" item_state = "coffee" center_of_mass = @'{"x":16,"y":14}' filling_states = @"[100]" - base_name = "cup" base_icon = "cup" volume = 30 - presentation_flags = PRESENTATION_FLAG_NAME /obj/item/chems/drinks/tea/black name = "cup of black tea" From 4e34276335db4ea16be08ce45bb9a3c8bad4fff1 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 16 Jan 2025 20:24:30 +1100 Subject: [PATCH 059/120] Adds an attack_hand override to dump transit pod contents. --- code/game/objects/structures/transit_tubes.dm | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/code/game/objects/structures/transit_tubes.dm b/code/game/objects/structures/transit_tubes.dm index 289b7d7c251d..b7fba083f5c9 100644 --- a/code/game/objects/structures/transit_tubes.dm +++ b/code/game/objects/structures/transit_tubes.dm @@ -45,7 +45,12 @@ var/moving = 0 var/datum/gas_mixture/air_contents = new() - +/obj/structure/transit_tube_pod/attack_hand(mob/user) + if(!moving && length(contents) && isturf(user.loc)) + user.visible_message(SPAN_NOTICE("\The [user] empties out \the [src]!")) + dump_contents() + return TRUE + return ..() /obj/structure/transit_tube_pod/Destroy() dump_contents() From b1f5b50902694e9315fcd869e9e5b8484fc2a1ce Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 16 Jan 2025 21:08:21 +1100 Subject: [PATCH 060/120] Tweaks to reagent interactions. --- code/modules/interactions/interactions_reagents.dm | 6 +++--- code/modules/reagents/reagent_containers.dm | 10 +++++++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/code/modules/interactions/interactions_reagents.dm b/code/modules/interactions/interactions_reagents.dm index 79885549cc40..c617f6ba9e79 100644 --- a/code/modules/interactions/interactions_reagents.dm +++ b/code/modules/interactions/interactions_reagents.dm @@ -3,7 +3,7 @@ interaction_flags = INTERACTION_NEEDS_PHYSICAL_INTERACTION | INTERACTION_NEVER_AUTOMATIC /decl/interaction_handler/dip_item/is_possible(atom/target, mob/user, obj/item/prop) - return ..() && target.reagents?.total_volume >= FLUID_MINIMUM_TRANSFER && istype(prop) && target.can_be_poured_from(user, prop) + return ..() && target != prop && target.reagents?.total_volume >= FLUID_MINIMUM_TRANSFER && istype(prop) && target.can_be_poured_from(user, prop) /decl/interaction_handler/dip_item/invoked(atom/target, mob/user, obj/item/prop) user.visible_message(SPAN_NOTICE("\The [user] dips \the [prop] into \the [target.reagents.get_primary_reagent_name()].")) @@ -23,7 +23,7 @@ /decl/interaction_handler/fill_from/is_possible(atom/target, mob/user, obj/item/prop) if(!(. = ..())) return - if(target.reagents?.total_volume < FLUID_PUDDLE) + if(target == prop || target.reagents?.total_volume < FLUID_PUDDLE) return FALSE if(!istype(prop) || (!isitem(target) && !istype(target, /obj/structure/reagent_dispensers))) return FALSE @@ -45,7 +45,7 @@ /decl/interaction_handler/empty_into/is_possible(atom/target, mob/user, obj/item/prop) if(!(. = ..())) return - if(!istype(prop) || prop.reagents?.total_volume <= 0) + if(target == prop || !istype(prop) || prop.reagents?.total_volume <= 0) return FALSE return target.can_be_poured_into(user, prop) && prop.can_be_poured_from(user, target) diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index e7924021f37a..ae3775b41d82 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -183,9 +183,17 @@ // // Interactions // +/obj/item/chems/get_quick_interaction_handler(mob/user) + var/static/interaction = GET_DECL(/decl/interaction_handler/set_transfer/chems) + return interaction + /obj/item/chems/get_alt_interactions(var/mob/user) . = ..() - LAZYADD(., /decl/interaction_handler/set_transfer/chems) + var/static/list/chem_interactions = list( + /decl/interaction_handler/set_transfer/chems, + /decl/interaction_handler/empty/chems + ) + LAZYADD(., chem_interactions) /decl/interaction_handler/set_transfer/chems expected_target_type = /obj/item/chems From 25e3da6c49d53f42ec1907c3aa3d371b546da7f8 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 16 Jan 2025 22:17:12 +1100 Subject: [PATCH 061/120] Fixing issues with augment and cavity surgery. --- code/modules/augment/augment.dm | 1 + code/modules/organs/external/_external.dm | 2 +- code/modules/organs/external/head.dm | 2 +- code/modules/organs/external/standard.dm | 4 +-- code/modules/surgery/implant.dm | 34 +++++++++++++---------- code/modules/surgery/organs_internal.dm | 2 +- 6 files changed, 26 insertions(+), 19 deletions(-) diff --git a/code/modules/augment/augment.dm b/code/modules/augment/augment.dm index ff96aabde045..3ff300f33a47 100644 --- a/code/modules/augment/augment.dm +++ b/code/modules/augment/augment.dm @@ -7,6 +7,7 @@ default_action_type = /datum/action/item_action/organ/augment material = /decl/material/solid/metal/steel origin_tech = @'{"materials":1,"magnets":2,"engineering":2,"biotech":1}' + w_class = ITEM_SIZE_TINY var/descriptor = "" var/known = TRUE diff --git a/code/modules/organs/external/_external.dm b/code/modules/organs/external/_external.dm index 1c6f8997cc3a..5917819063cf 100644 --- a/code/modules/organs/external/_external.dm +++ b/code/modules/organs/external/_external.dm @@ -62,7 +62,7 @@ var/artery_name = "artery" // Flavour text for cartoid artery, aorta, etc. var/arterial_bleed_severity = 1 // Multiplier for bleeding in a limb. var/tendon_name = "tendon" // Flavour text for Achilles tendon, etc. - var/cavity_name = "cavity" + var/cavity_name = "intramuscular cavity" // Surgery vars. var/cavity_max_w_class = ITEM_SIZE_TINY //this is increased if bigger organs spawn by default inside diff --git a/code/modules/organs/external/head.dm b/code/modules/organs/external/head.dm index 1d6b432822ce..b0930a27868b 100644 --- a/code/modules/organs/external/head.dm +++ b/code/modules/organs/external/head.dm @@ -12,7 +12,7 @@ amputation_point = "neck" encased = "skull" artery_name = "carotid artery" - cavity_name = "cranial" + cavity_name = "cranial cavity" limb_flags = ORGAN_FLAG_CAN_AMPUTATE | ORGAN_FLAG_HEALS_OVERKILL | ORGAN_FLAG_CAN_BREAK | ORGAN_FLAG_CAN_DISLOCATE var/glowing_eyes = FALSE diff --git a/code/modules/organs/external/standard.dm b/code/modules/organs/external/standard.dm index d3ec8d68e7f4..5bde12032cc2 100644 --- a/code/modules/organs/external/standard.dm +++ b/code/modules/organs/external/standard.dm @@ -17,7 +17,7 @@ parent_organ = null encased = "ribcage" artery_name = "aorta" - cavity_name = "thoracic" + cavity_name = "thoracic cavity" limb_flags = ORGAN_FLAG_HEALS_OVERKILL | ORGAN_FLAG_CAN_BREAK /obj/item/organ/external/chest/proc/get_current_skin() @@ -47,7 +47,7 @@ amputation_point = "lumbar" joint = "hip" artery_name = "iliac artery" - cavity_name = "abdominal" + cavity_name = "abdominal cavity" limb_flags = ORGAN_FLAG_CAN_AMPUTATE | ORGAN_FLAG_CAN_BREAK /obj/item/organ/external/groin/die() diff --git a/code/modules/surgery/implant.dm b/code/modules/surgery/implant.dm index 1b8ef1751a04..be2f0f6b69dc 100644 --- a/code/modules/surgery/implant.dm +++ b/code/modules/surgery/implant.dm @@ -21,6 +21,12 @@ affected.take_external_damage(20, 0, (DAM_SHARP|DAM_EDGE), used_weapon = tool) ..() +/decl/surgery_step/cavity/get_skill_reqs(mob/living/user, mob/living/target, obj/item/tool, target_zone) + var/obj/item/organ/external/affected = GET_EXTERNAL_ORGAN(target, target_zone) + if(!affected || !BP_IS_PROSTHETIC(affected) || BP_IS_CRYSTAL(affected)) + return ..() + return SURGERY_SKILLS_ROBOTIC + ////////////////////////////////////////////////////////////////// // create implant space surgery step ////////////////////////////////////////////////////////////////// @@ -38,16 +44,16 @@ /decl/surgery_step/cavity/make_space/begin_step(mob/user, mob/living/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = GET_EXTERNAL_ORGAN(target, target_zone) - user.visible_message("[user] starts making some space inside [target]'s [affected.cavity_name] cavity with \the [tool].", \ - "You start making some space inside [target]'s [affected.cavity_name] cavity with \the [tool]." ) + user.visible_message("[user] starts making some space inside [target]'s [affected.cavity_name] with \the [tool].", \ + "You start making some space inside [target]'s [affected.cavity_name] with \the [tool]." ) target.custom_pain("The pain in your chest is living hell!",1,affecting = affected) affected.cavity = TRUE ..() /decl/surgery_step/cavity/make_space/end_step(mob/living/user, mob/living/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = GET_EXTERNAL_ORGAN(target, target_zone) - user.visible_message("[user] makes some space inside [target]'s [affected.cavity_name] cavity with \the [tool].", \ - "You make some space inside [target]'s [affected.cavity_name] cavity with \the [tool]." ) + user.visible_message("[user] makes some space inside [target]'s \the [affected.cavity_name] with \the [tool].", \ + "You make some space inside [target]'s \the [affected.cavity_name] with \the [tool]." ) ..() ////////////////////////////////////////////////////////////////// @@ -70,15 +76,15 @@ /decl/surgery_step/cavity/close_space/begin_step(mob/user, mob/living/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = GET_EXTERNAL_ORGAN(target, target_zone) - user.visible_message("[user] starts mending [target]'s [affected.cavity_name] cavity wall with \the [tool].", \ - "You start mending [target]'s [affected.cavity_name] cavity wall with \the [tool]." ) + user.visible_message("[user] starts mending [target]'s \the [affected.cavity_name] wall with \the [tool].", \ + "You start mending [target]'s \the [affected.cavity_name] wall with \the [tool]." ) target.custom_pain("The pain in your chest is living hell!",1,affecting = affected) ..() /decl/surgery_step/cavity/close_space/end_step(mob/living/user, mob/living/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = GET_EXTERNAL_ORGAN(target, target_zone) - user.visible_message("[user] mends [target]'s [affected.cavity_name] cavity walls with \the [tool].", \ - "You mend [target]'s [affected.cavity_name] cavity walls with \the [tool]." ) + user.visible_message("[user] mends [target]'s \the [affected.cavity_name] walls with \the [tool].", \ + "You mend [target]'s \the [affected.cavity_name] walls with \the [tool]." ) affected.cavity = FALSE ..() @@ -109,7 +115,7 @@ if(affected && affected.cavity) var/max_volume = BASE_STORAGE_CAPACITY(affected.cavity_max_w_class) + affected.internal_organs_size if(tool.w_class > affected.cavity_max_w_class) - to_chat(user, SPAN_WARNING("\The [tool] is too big for [affected.cavity_name] cavity.")) + to_chat(user, SPAN_WARNING("\The [tool] is too big for \the [affected.cavity_name].")) return FALSE var/total_volume = tool.get_storage_cost() for(var/obj/item/I in affected.implants) @@ -119,14 +125,14 @@ for(var/obj/item/organ/internal/org in affected.internal_organs) max_volume -= org.get_storage_cost() if(total_volume > max_volume) - to_chat(user, SPAN_WARNING("There isn't enough space left in [affected.cavity_name] cavity for [tool].")) + to_chat(user, SPAN_WARNING("There isn't enough space left in \the [affected.cavity_name] for [tool].")) return FALSE return TRUE /decl/surgery_step/cavity/place_item/begin_step(mob/user, mob/living/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = GET_EXTERNAL_ORGAN(target, target_zone) - user.visible_message("[user] starts putting \the [tool] inside [target]'s [affected.cavity_name] cavity.", \ - "You start putting \the [tool] inside [target]'s [affected.cavity_name] cavity." ) + user.visible_message("[user] starts putting \the [tool] inside [target]'s \the [affected.cavity_name].", \ + "You start putting \the [tool] inside [target]'s \the [affected.cavity_name]." ) target.custom_pain("The pain in your chest is living hell!",1,affecting = affected) ..() @@ -134,8 +140,8 @@ var/obj/item/organ/external/affected = GET_EXTERNAL_ORGAN(target, target_zone) if(!user.try_unequip(tool, affected)) return - user.visible_message("[user] puts \the [tool] inside [target]'s [affected.cavity_name] cavity.", \ - "You put \the [tool] inside [target]'s [affected.cavity_name] cavity." ) + user.visible_message("[user] puts \the [tool] inside [target]'s \the [affected.cavity_name].", \ + "You put \the [tool] inside [target]'s \the [affected.cavity_name]." ) if (tool.w_class > affected.cavity_max_w_class/2 && prob(50) && !BP_IS_PROSTHETIC(affected) && affected.sever_artery()) to_chat(user, "You tear some blood vessels trying to fit such a big object in this cavity.") affected.owner.custom_pain("You feel something rip in your [affected.name]!", 1,affecting = affected) diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm index f6b9bffb28e3..8f92b195d351 100644 --- a/code/modules/surgery/organs_internal.dm +++ b/code/modules/surgery/organs_internal.dm @@ -262,7 +262,7 @@ return FALSE if(O.w_class > affected.cavity_max_w_class) - to_chat(user, SPAN_WARNING("\The [O.name] [pronouns.is] too big for [affected.cavity_name] cavity!")) + to_chat(user, SPAN_WARNING("\The [O.name] [pronouns.is] too big for \the [affected.cavity_name]!")) return FALSE var/obj/item/organ/internal/I = GET_INTERNAL_ORGAN(target, O.organ_tag) From 5ea9306e89ff007be9cbb430520a094583ba2371 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 19 Jan 2025 18:40:22 +1100 Subject: [PATCH 062/120] Updates fluids and atoms on turf height change. --- code/game/atoms_movable.dm | 5 +++++ code/game/turfs/floors/floor_height.dm | 4 ++-- code/modules/fluids/_fluid.dm | 3 +++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 2eeb6cccb12a..7d3a39b4b4ea 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -588,3 +588,8 @@ /atom/movable/immune_to_floor_hazards() return ..() || throwing + +/atom/movable/proc/on_turf_height_change(new_height) + // re-runs stuff like Entered(), updates pixel offsets, triggers fluids, etc. + if(simulated) + dropInto(loc) diff --git a/code/game/turfs/floors/floor_height.dm b/code/game/turfs/floors/floor_height.dm index 2dd080f5edd8..28c3f6d71d8a 100644 --- a/code/game/turfs/floors/floor_height.dm +++ b/code/game/turfs/floors/floor_height.dm @@ -10,7 +10,7 @@ for(var/turf/neighbor as anything in RANGE_TURFS(src, 1)) neighbor.update_icon() fluid_update() - if(fluid_overlay) - fluid_overlay.update_icon() + for(var/atom/movable/thing in contents) + thing.on_turf_height_change(new_height) return TRUE return FALSE diff --git a/code/modules/fluids/_fluid.dm b/code/modules/fluids/_fluid.dm index ef3d0259a0d3..362b6629820b 100644 --- a/code/modules/fluids/_fluid.dm +++ b/code/modules/fluids/_fluid.dm @@ -14,6 +14,9 @@ var/last_update_depth var/updating_edge_mask +/atom/movable/fluid_overlay/on_turf_height_change(new_height) + update_icon() + /atom/movable/fluid_overlay/on_update_icon() var/datum/reagents/loc_reagents = loc?.reagents From cebe02950e7cf4ce36c302756fdfb48594549377 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 19 Jan 2025 18:49:38 +1100 Subject: [PATCH 063/120] Catwalks now prevent falling into trenches. --- code/game/objects/structures/__structure.dm | 4 +++ code/game/objects/structures/catwalk.dm | 29 +++++++++++++-------- code/game/turfs/turf.dm | 6 +++++ code/game/turfs/turf_enter.dm | 6 +++-- code/modules/mob/mob_layering.dm | 11 ++++++-- 5 files changed, 41 insertions(+), 15 deletions(-) diff --git a/code/game/objects/structures/__structure.dm b/code/game/objects/structures/__structure.dm index 724a01372c5c..0b98d91b94b4 100644 --- a/code/game/objects/structures/__structure.dm +++ b/code/game/objects/structures/__structure.dm @@ -322,3 +322,7 @@ Note: This proc can be overwritten to allow for different types of auto-alignmen W.pixel_x = (CELLSIZE * (cell_x + 0.5)) - center["x"] W.pixel_y = (CELLSIZE * (cell_y + 0.5)) - center["y"] W.pixel_z = 0 + +// Does this structure override turf depth for the purposes of mob offsets? +/obj/structure/proc/is_platform() + return FALSE diff --git a/code/game/objects/structures/catwalk.dm b/code/game/objects/structures/catwalk.dm index 28d320d564f9..a34e1e5210cf 100644 --- a/code/game/objects/structures/catwalk.dm +++ b/code/game/objects/structures/catwalk.dm @@ -19,14 +19,6 @@ var/list/connections var/list/other_connections -/obj/structure/catwalk/clear_connections() - connections = null - other_connections = null - -/obj/structure/catwalk/set_connections(dirs, other_dirs) - connections = dirs_to_corner_states(dirs) - other_connections = dirs_to_corner_states(other_dirs) - /obj/structure/catwalk/Initialize() . = ..() DELETE_IF_DUPLICATE_OF(/obj/structure/catwalk) @@ -41,9 +33,6 @@ update_connections(1) update_icon() -/obj/structure/catwalk/can_climb_from_below(var/mob/climber) - return TRUE - /obj/structure/catwalk/Destroy() var/turf/oldloc = loc redraw_nearby_catwalks() @@ -52,6 +41,24 @@ for(var/atom/movable/AM in oldloc) AM.fall(oldloc) +/obj/structure/catwalk/clear_connections() + connections = null + other_connections = null + +/obj/structure/catwalk/on_turf_height_change(new_height) + return null // We are a fixed point. + +/obj/structure/catwalk/is_platform() + return TRUE + +/obj/structure/catwalk/set_connections(dirs, other_dirs) + connections = dirs_to_corner_states(dirs) + other_connections = dirs_to_corner_states(other_dirs) + +/obj/structure/catwalk/can_climb_from_below(var/mob/climber) + return TRUE + + /obj/structure/catwalk/proc/redraw_nearby_catwalks() for(var/direction in global.alldirs) var/obj/structure/catwalk/L = locate() in get_step(src, direction) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 87781fb618db..5ab301cf595f 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -791,6 +791,12 @@ /turf/can_be_poured_into(atom/source) return !density +/turf/proc/get_supporting_platform() + for(var/obj/structure/platform in get_contained_external_atoms()) + if(platform.is_platform()) + return platform + return null + /turf/get_alt_interactions(mob/user) . = ..() LAZYADD(., /decl/interaction_handler/show_turf_contents) diff --git a/code/game/turfs/turf_enter.dm b/code/game/turfs/turf_enter.dm index a0cc300474d9..a83d87a855fe 100644 --- a/code/game/turfs/turf_enter.dm +++ b/code/game/turfs/turf_enter.dm @@ -29,7 +29,9 @@ regenerate_ao() #endif - if(isturf(old_loc) && has_gravity() && A.can_fall() && !(weakref(A) in skip_height_fall_for)) + var/obj/structure/platform = get_supporting_platform() + if(isturf(old_loc) && has_gravity() && A.can_fall() && !isnull(platform) && !(weakref(A) in skip_height_fall_for)) + var/turf/old_turf = old_loc var/old_height = old_turf.get_physical_height() + old_turf.reagents?.total_volume var/current_height = get_physical_height() + reagents?.total_volume @@ -69,7 +71,7 @@ // Delay to allow transition to the new turf and avoid layering issues. var/mob/M = A M.reset_offsets() - if(get_physical_height() > T.get_physical_height()) + if(platform || (get_physical_height() > T.get_physical_height())) M.reset_layer() else // arbitrary timing value that feels good in practice. it sucks and is inconsistent:( diff --git a/code/modules/mob/mob_layering.dm b/code/modules/mob/mob_layering.dm index d98e8923528f..40863c498ca0 100644 --- a/code/modules/mob/mob_layering.dm +++ b/code/modules/mob/mob_layering.dm @@ -97,8 +97,15 @@ // Update offsets from loc. var/turf/floor/ext = loc - if(istype(ext) && ext.height < 0) - new_pixel_z += ext.pixel_z + if(istype(ext)) + var/modify_pixel_z + var/obj/structure/catwalk = ext.get_supporting_platform() + if(catwalk) + modify_pixel_z = catwalk.pixel_z + else if(ext.height < 0) + modify_pixel_z = ext.pixel_z + + // Check for catwalks/supporting platforms. // Update offsets from our buckled atom. if(buckled && buckled.buckle_pixel_shift) From 3c4aac504cd3918d0943162068893fd8fff59d16 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 19 Jan 2025 18:59:53 +1100 Subject: [PATCH 064/120] Updating catwalk checks to use a turf proc. --- code/controllers/subsystems/holomap.dm | 2 +- .../objects/items/devices/chameleonproj.dm | 5 ++++- code/game/objects/structures/__structure.dm | 3 +++ code/game/objects/structures/catwalk.dm | 4 ++++ code/game/objects/structures/lattice.dm | 7 ++++--- code/game/turfs/flooring/flooring_lava.dm | 2 +- code/game/turfs/floors/floor_attackby.dm | 2 +- code/game/turfs/turf.dm | 15 ++++++++++---- code/game/turfs/turf_changing.dm | 4 ++++ code/modules/mob/mob_layering.dm | 9 ++++----- code/modules/multiz/ladder.dm | 20 +++++++++---------- code/modules/multiz/turf.dm | 2 +- 12 files changed, 48 insertions(+), 27 deletions(-) diff --git a/code/controllers/subsystems/holomap.dm b/code/controllers/subsystems/holomap.dm index 566e9ccb2181..ac6662184f62 100644 --- a/code/controllers/subsystems/holomap.dm +++ b/code/controllers/subsystems/holomap.dm @@ -81,7 +81,7 @@ SUBSYSTEM_DEF(minimap) continue if((tile.turf_flags & TURF_IS_HOLOMAP_OBSTACLE) || (locate(/obj/structure/grille) in tile)) canvas.DrawBox(COLOR_HOLOMAP_OBSTACLE, tile.x + offset_x, tile.y + offset_y) - else if((tile.turf_flags & TURF_IS_HOLOMAP_PATH) || (locate(/obj/structure/catwalk) in tile)) + else if((tile.turf_flags & TURF_IS_HOLOMAP_PATH) || tile.get_supporting_platform()) canvas.DrawBox(COLOR_HOLOMAP_PATH, tile.x + offset_x, tile.y + offset_y) CHECK_TICK return canvas diff --git a/code/game/objects/items/devices/chameleonproj.dm b/code/game/objects/items/devices/chameleonproj.dm index 567039e9b513..f09470bc64ec 100644 --- a/code/game/objects/items/devices/chameleonproj.dm +++ b/code/game/objects/items/devices/chameleonproj.dm @@ -147,7 +147,10 @@ // As it is, the effect can freely levitate over any open space. /obj/effect/dummy/chameleon/Move() . = ..() - if(. && isturf(loc) && loc.has_gravity() && !(locate(/obj/structure/catwalk) in loc) && !(locate(/obj/structure/lattice) in loc)) + if(!. || !isturf(loc) || !loc.has_gravity()) + return + var/turf/my_turf = loc + if(!my_turf.get_supporting_platform() && !(locate(/obj/structure/lattice) in loc)) disrupted() /datum/movement_handler/delay/chameleon_projector diff --git a/code/game/objects/structures/__structure.dm b/code/game/objects/structures/__structure.dm index 0b98d91b94b4..bb5203514244 100644 --- a/code/game/objects/structures/__structure.dm +++ b/code/game/objects/structures/__structure.dm @@ -326,3 +326,6 @@ Note: This proc can be overwritten to allow for different types of auto-alignmen // Does this structure override turf depth for the purposes of mob offsets? /obj/structure/proc/is_platform() return FALSE + +/obj/structure/proc/is_z_passable() + return TRUE diff --git a/code/game/objects/structures/catwalk.dm b/code/game/objects/structures/catwalk.dm index a34e1e5210cf..222fb6337199 100644 --- a/code/game/objects/structures/catwalk.dm +++ b/code/game/objects/structures/catwalk.dm @@ -40,6 +40,7 @@ if(istype(oldloc)) for(var/atom/movable/AM in oldloc) AM.fall(oldloc) + oldloc.supporting_platform = null /obj/structure/catwalk/clear_connections() connections = null @@ -177,6 +178,9 @@ /obj/structure/catwalk/refresh_neighbors() return +/obj/structure/catwalk/is_z_passable() + return !plated_tile + /obj/effect/catwalk_plated name = "plated catwalk spawner" icon = 'icons/obj/structures/catwalks.dmi' diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index cfdce2510d78..3de7c1dba7b2 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -88,12 +88,13 @@ return TRUE var/obj/item/stack/material/rods/R = C - if(locate(/obj/structure/catwalk) in get_turf(src)) - to_chat(user, SPAN_WARNING("There is already a catwalk here.")) + var/turf/my_turf = get_turf(src) + if(my_turf?.get_supporting_platform()) + to_chat(user, SPAN_WARNING("There is already a platform here.")) return TRUE else if(R.use(2)) playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) - new /obj/structure/catwalk(src.loc, R.material.type) + new /obj/structure/catwalk(my_turf, R.material.type) return TRUE else to_chat(user, SPAN_WARNING("You require at least two rods to complete the catwalk.")) diff --git a/code/game/turfs/flooring/flooring_lava.dm b/code/game/turfs/flooring/flooring_lava.dm index 9fe4be66e462..d8137d15b356 100644 --- a/code/game/turfs/flooring/flooring_lava.dm +++ b/code/game/turfs/flooring/flooring_lava.dm @@ -13,7 +13,7 @@ /decl/flooring/lava/handle_environment_proc(turf/floor/target) . = PROCESS_KILL - if(locate(/obj/structure/catwalk) in target) + if(target.get_supporting_platform()) return var/datum/gas_mixture/environment = target.return_air() var/pressure = environment?.return_pressure() diff --git a/code/game/turfs/floors/floor_attackby.dm b/code/game/turfs/floors/floor_attackby.dm index d023e3d2ee58..0ddfc38eea84 100644 --- a/code/game/turfs/floors/floor_attackby.dm +++ b/code/game/turfs/floors/floor_attackby.dm @@ -24,7 +24,7 @@ return ..() /turf/floor/proc/try_build_catwalk(var/obj/item/used_item, var/mob/user) - if(!(locate(/obj/structure/catwalk) in src) && istype(used_item, /obj/item/stack/material/rods)) + if(istype(used_item, /obj/item/stack/material/rods) && !get_supporting_platform()) var/obj/item/stack/material/rods/R = used_item if (R.use(2)) playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 5ab301cf595f..d1e295561dea 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -86,6 +86,9 @@ var/paint_color + /// Floorlike structures like catwalks. Updated/retrieved by get_supporting_platform() + var/obj/structure/supporting_platform + /turf/Initialize(mapload, ...) . = null && ..() // This weird construct is to shut up the 'parent proc not called' warning without disabling the lint for child types. We explicitly return an init hint so this won't change behavior. @@ -140,6 +143,8 @@ /turf/Destroy() + supporting_platform = null + if(zone) if(can_safely_remove_from_zone()) c_copy_air() @@ -792,10 +797,12 @@ return !density /turf/proc/get_supporting_platform() - for(var/obj/structure/platform in get_contained_external_atoms()) - if(platform.is_platform()) - return platform - return null + if(isnull(supporting_platform)) + for(var/obj/structure/platform in get_contained_external_atoms()) + if(platform.is_platform()) + supporting_platform = platform + break + return supporting_platform /turf/get_alt_interactions(mob/user) . = ..() diff --git a/code/game/turfs/turf_changing.dm b/code/game/turfs/turf_changing.dm index ce53c4785664..1774f0170212 100644 --- a/code/game/turfs/turf_changing.dm +++ b/code/game/turfs/turf_changing.dm @@ -36,6 +36,7 @@ above.ChangeTurf(open_turf_type, keep_air = TRUE, update_open_turfs_above = FALSE) /turf/proc/ChangeTurf(var/turf/N, var/tell_universe = TRUE, var/force_lighting_update = FALSE, var/keep_air = FALSE, var/update_open_turfs_above = TRUE, var/keep_height = FALSE) + if (!N) return @@ -49,6 +50,9 @@ if (!(atom_flags & ATOM_FLAG_INITIALIZED)) return new N(src) + // Rebuilt on next call. + supporting_platform = null + // Track a number of old values for the purposes of raising // state change events after changing the turf to the new type. var/old_fire = fire diff --git a/code/modules/mob/mob_layering.dm b/code/modules/mob/mob_layering.dm index 40863c498ca0..456fb517d1d4 100644 --- a/code/modules/mob/mob_layering.dm +++ b/code/modules/mob/mob_layering.dm @@ -98,12 +98,11 @@ // Update offsets from loc. var/turf/floor/ext = loc if(istype(ext)) - var/modify_pixel_z - var/obj/structure/catwalk = ext.get_supporting_platform() - if(catwalk) - modify_pixel_z = catwalk.pixel_z + var/obj/structure/platform = ext.get_supporting_platform() + if(platform) + new_pixel_z += platform.pixel_z else if(ext.height < 0) - modify_pixel_z = ext.pixel_z + new_pixel_z += ext.pixel_z // Check for catwalks/supporting platforms. diff --git a/code/modules/multiz/ladder.dm b/code/modules/multiz/ladder.dm index 10fc3c5a59a0..edb4a281e120 100644 --- a/code/modules/multiz/ladder.dm +++ b/code/modules/multiz/ladder.dm @@ -71,8 +71,8 @@ var/turf/L = loc if(HasBelow(z) && istype(L) && L.is_open()) var/failed - for(var/obj/structure/catwalk/catwalk in loc) - if(catwalk.plated_tile) + for(var/obj/structure/platform in loc) + if(!platform.is_z_passable()) failed = TRUE break if(!failed) @@ -86,8 +86,8 @@ var/turf/T = GetAbove(src) if(istype(T) && T.is_open()) var/failed - for(var/obj/structure/catwalk/catwalk in T) - if(catwalk.plated_tile) + for(var/obj/structure/platform in T) + if(!platform.is_z_passable()) failed = TRUE break if(!failed) @@ -214,18 +214,18 @@ if(!istype(T) || !T.is_open()) to_chat(M, SPAN_WARNING("The ceiling is in the way!")) return null - for(var/obj/structure/catwalk/catwalk in target_up.loc) - if(catwalk.plated_tile) - to_chat(M, SPAN_WARNING("\The [catwalk] is in the way!")) + for(var/obj/structure/platform in target_up.loc) + if(!platform.is_z_passable()) + to_chat(M, SPAN_WARNING("\The [platform] is in the way!")) return null if(. == target_down) var/turf/T = loc if(!istype(T) || !T.is_open()) to_chat(M, SPAN_WARNING("\The [loc] is in the way!")) return null - for(var/obj/structure/catwalk/catwalk in loc) - if(catwalk.plated_tile) - to_chat(M, SPAN_WARNING("\The [catwalk] is in the way!")) + for(var/obj/structure/platform in loc) + if(!platform.is_z_passable()) + to_chat(M, SPAN_WARNING("\The [platform] is in the way!")) return null /mob/proc/may_climb_ladders(var/ladder) diff --git a/code/modules/multiz/turf.dm b/code/modules/multiz/turf.dm index 01db42e52616..c08433c2a3c5 100644 --- a/code/modules/multiz/turf.dm +++ b/code/modules/multiz/turf.dm @@ -9,7 +9,7 @@ return FALSE else if(direction == DOWN) - if(!is_open() || !HasBelow(z) || (locate(/obj/structure/catwalk) in src)) + if(!is_open() || !HasBelow(z) || get_supporting_platform()) return FALSE if(check_neighbor_canzpass) var/turf/T = GetBelow(src) From bf6852259598f9855dcf88ad815d9c69f97f5bc4 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 19 Jan 2025 19:32:23 +1100 Subject: [PATCH 065/120] Updating snow to be diggable. --- code/game/atoms_movable.dm | 6 ++++-- code/game/objects/structures/__structure.dm | 4 ++++ code/game/objects/structures/catwalk.dm | 3 --- code/game/turfs/flooring/flooring_snow.dm | 1 + code/game/turfs/floors/floor_digging.dm | 2 +- code/modules/fluids/_fluid.dm | 1 + 6 files changed, 11 insertions(+), 6 deletions(-) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 7d3a39b4b4ea..9515c94ad495 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -589,7 +589,9 @@ /atom/movable/immune_to_floor_hazards() return ..() || throwing +// updates pixel offsets, triggers fluids, etc. /atom/movable/proc/on_turf_height_change(new_height) - // re-runs stuff like Entered(), updates pixel offsets, triggers fluids, etc. if(simulated) - dropInto(loc) + reset_offsets() + return TRUE + return FALSE diff --git a/code/game/objects/structures/__structure.dm b/code/game/objects/structures/__structure.dm index bb5203514244..ffa2e49ccb8c 100644 --- a/code/game/objects/structures/__structure.dm +++ b/code/game/objects/structures/__structure.dm @@ -329,3 +329,7 @@ Note: This proc can be overwritten to allow for different types of auto-alignmen /obj/structure/proc/is_z_passable() return TRUE + +/obj/structure/on_turf_height_change(new_height) + // We may be a fixed point. + return !is_platform() && ..() diff --git a/code/game/objects/structures/catwalk.dm b/code/game/objects/structures/catwalk.dm index 222fb6337199..16c4ce961fd4 100644 --- a/code/game/objects/structures/catwalk.dm +++ b/code/game/objects/structures/catwalk.dm @@ -46,9 +46,6 @@ connections = null other_connections = null -/obj/structure/catwalk/on_turf_height_change(new_height) - return null // We are a fixed point. - /obj/structure/catwalk/is_platform() return TRUE diff --git a/code/game/turfs/flooring/flooring_snow.dm b/code/game/turfs/flooring/flooring_snow.dm index 6055cdda83db..f489a1a59868 100644 --- a/code/game/turfs/flooring/flooring_snow.dm +++ b/code/game/turfs/flooring/flooring_snow.dm @@ -4,6 +4,7 @@ icon = 'icons/turf/flooring/snow.dmi' icon_base = "snow" icon_edge_layer = FLOOR_EDGE_SNOW + flooring_flags = TURF_REMOVE_SHOVEL footstep_type = /decl/footsteps/snow has_base_range = 13 force_material = /decl/material/solid/ice/snow diff --git a/code/game/turfs/floors/floor_digging.dm b/code/game/turfs/floors/floor_digging.dm index 4262e953ad82..1520383b7ca7 100644 --- a/code/game/turfs/floors/floor_digging.dm +++ b/code/game/turfs/floors/floor_digging.dm @@ -1,6 +1,6 @@ /turf/floor/proc/is_fundament() var/decl/flooring/flooring = get_topmost_flooring() - return flooring ? !flooring.constructed : TRUE + return flooring ? (!flooring.constructed && flooring != get_base_flooring()) : TRUE /turf/floor/can_be_dug(tool_hardness = MAT_VALUE_MALLEABLE, using_tool = TOOL_SHOVEL) // This should be removed before digging trenches. diff --git a/code/modules/fluids/_fluid.dm b/code/modules/fluids/_fluid.dm index 362b6629820b..21f28aec313c 100644 --- a/code/modules/fluids/_fluid.dm +++ b/code/modules/fluids/_fluid.dm @@ -16,6 +16,7 @@ /atom/movable/fluid_overlay/on_turf_height_change(new_height) update_icon() + return TRUE /atom/movable/fluid_overlay/on_update_icon() From 51c8f1a4feb4020fd060b68fa31c279c9734e8a6 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 19 Jan 2025 19:39:52 +1100 Subject: [PATCH 066/120] Fixing issues with is_fundament(). --- code/game/turfs/floors/floor_digging.dm | 12 +++++++----- code/game/turfs/turf.dm | 6 ++++++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/code/game/turfs/floors/floor_digging.dm b/code/game/turfs/floors/floor_digging.dm index 1520383b7ca7..6a6784ef00ec 100644 --- a/code/game/turfs/floors/floor_digging.dm +++ b/code/game/turfs/floors/floor_digging.dm @@ -1,10 +1,12 @@ -/turf/floor/proc/is_fundament() +/turf/floor/proc/flooring_is_diggable() var/decl/flooring/flooring = get_topmost_flooring() - return flooring ? (!flooring.constructed && flooring != get_base_flooring()) : TRUE + if(!flooring || flooring.constructed) + return FALSE + return TRUE /turf/floor/can_be_dug(tool_hardness = MAT_VALUE_MALLEABLE, using_tool = TOOL_SHOVEL) // This should be removed before digging trenches. - if(!is_fundament()) + if(!flooring_is_diggable()) return FALSE var/decl/flooring/flooring = get_base_flooring() if(istype(flooring) && flooring.constructed) @@ -24,7 +26,7 @@ return can_be_dug(tool_hardness, using_tool) && get_physical_height() > -(FLUID_DEEP) /turf/floor/dig_trench(tool_hardness = MAT_VALUE_MALLEABLE, using_tool = TOOL_SHOVEL) - if(!is_fundament()) + if(!flooring_is_diggable()) return var/new_height = max(get_physical_height()-TRENCH_DEPTH_PER_ACTION, -(FLUID_DEEP)) var/height_diff = abs(get_physical_height()-new_height) @@ -38,6 +40,6 @@ /turf/floor/get_diggable_resources() var/decl/material/my_material = get_material() - if(is_fundament() && istype(my_material) && my_material.dug_drop_type && (get_physical_height() > -(FLUID_DEEP))) + if(flooring_is_diggable() && istype(my_material) && my_material.dug_drop_type && (get_physical_height() > -(FLUID_DEEP))) return list(my_material.dug_drop_type = list(3, 2)) return null diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index d1e295561dea..57fa35d12c0b 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -841,6 +841,12 @@ /decl/interaction_handler/dig/trench name = "Dig Trench" +/decl/interaction_handler/dig/trench/is_possible(atom/target, mob/user, obj/item/prop) + . = ..() + if(. && istype(target, /turf/floor)) + var/turf/floor/target_turf = target + return target_turf.flooring_is_diggable() + /decl/interaction_handler/dig/trench/invoked(atom/target, mob/user, obj/item/prop) prop ||= user.get_usable_hand_slot_organ() // Allows drakes to dig. var/turf/T = get_turf(target) From c4012273a968282dd8bd2ffb1ac82ea3633f906e Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 19 Jan 2025 20:22:50 +1100 Subject: [PATCH 067/120] More work on turf height being bypassed by catwalks. --- code/controllers/subsystems/fluids.dm | 22 +++++++++++++------ code/game/atoms_fluids.dm | 2 +- code/game/objects/__objs.dm | 4 ++-- code/game/objects/structures/catwalk.dm | 4 ++++ code/game/turfs/turf.dm | 29 ++++++++++++++++++------- code/game/turfs/turf_fluids.dm | 19 +++++++++++++--- code/game/turfs/turf_footsteps.dm | 2 +- code/modules/mob/mob.dm | 6 ++--- code/modules/mob/mob_layering.dm | 6 ++--- 9 files changed, 66 insertions(+), 28 deletions(-) diff --git a/code/controllers/subsystems/fluids.dm b/code/controllers/subsystems/fluids.dm index 1e95a63bf463..0b9faea243ed 100644 --- a/code/controllers/subsystems/fluids.dm +++ b/code/controllers/subsystems/fluids.dm @@ -231,13 +231,21 @@ SUBSYSTEM_DEF(fluids) if(!istype(current_fluid_holder) || QDELETED(current_fluid_holder)) continue var/pushed_something = FALSE - if(current_fluid_holder.reagents?.total_volume > FLUID_SHALLOW && current_fluid_holder.last_flow_strength >= 10) - for(var/atom/movable/AM as anything in current_fluid_holder.get_contained_external_atoms()) - if(AM.is_fluid_pushable(current_fluid_holder.last_flow_strength)) - AM.pushed(current_fluid_holder.last_flow_dir) - pushed_something = TRUE - if(pushed_something && prob(1)) - playsound(current_fluid_holder, 'sound/effects/slosh.ogg', 25, 1) + + if(current_fluid_holder.last_flow_strength >= 10) + // Catwalks mean items will be above the turf; subtract the turf height from our volume. + // TODO: somehow handle stuff that is on a catwalk or on the turf within the same turf. + var/effective_volume = current_fluid_holder.reagents?.total_volume + if(current_fluid_holder.get_supporting_platform()) + // Depth is negative height, hence +=. TODO: positive heights? No idea how to handle that. + effective_volume += current_fluid_holder.get_physical_height() + if(effective_volume > FLUID_SHALLOW) + for(var/atom/movable/AM as anything in current_fluid_holder.get_contained_external_atoms()) + if(AM.try_fluid_push(effective_volume, current_fluid_holder.last_flow_strength)) + AM.pushed(current_fluid_holder.last_flow_dir) + pushed_something = TRUE + if(pushed_something && prob(1)) + playsound(current_fluid_holder, 'sound/effects/slosh.ogg', 25, 1) if(MC_TICK_CHECK) processing_flows.Cut(1, i+1) return diff --git a/code/game/atoms_fluids.dm b/code/game/atoms_fluids.dm index e69ed3bbfc30..8f3f7def7884 100644 --- a/code/game/atoms_fluids.dm +++ b/code/game/atoms_fluids.dm @@ -16,7 +16,7 @@ /atom/proc/CanFluidPass(var/coming_from) return TRUE -/atom/movable/proc/is_fluid_pushable(var/amt) +/atom/movable/proc/try_fluid_push(volume, strength) return simulated && !anchored /atom/movable/is_flooded(var/lying_mob, var/absolute) diff --git a/code/game/objects/__objs.dm b/code/game/objects/__objs.dm index 3fc47332062e..5f71fecad448 100644 --- a/code/game/objects/__objs.dm +++ b/code/game/objects/__objs.dm @@ -157,8 +157,8 @@ add_fingerprint(user) return ..() -/obj/is_fluid_pushable(var/amt) - return ..() && w_class <= round(amt/20) +/obj/try_fluid_push(volume, strength) + return ..() && w_class <= round(strength/20) /obj/proc/can_embed() return FALSE diff --git a/code/game/objects/structures/catwalk.dm b/code/game/objects/structures/catwalk.dm index 16c4ce961fd4..b7186e1926d5 100644 --- a/code/game/objects/structures/catwalk.dm +++ b/code/game/objects/structures/catwalk.dm @@ -42,6 +42,10 @@ AM.fall(oldloc) oldloc.supporting_platform = null +// Catwalks need to layer over grass and water. +/obj/structure/catwalk/update_turf_alpha_mask() + return FALSE + /obj/structure/catwalk/clear_connections() connections = null other_connections = null diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 57fa35d12c0b..157fff727e7e 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -209,7 +209,7 @@ if(weather) . += weather.get_movement_delay(return_air(), travel_dir) // TODO: check user species webbed feet, wearing swimming gear - if(reagents?.total_volume > FLUID_PUDDLE) + if(!get_supporting_platform() && reagents?.total_volume > FLUID_PUDDLE) . += (reagents.total_volume > FLUID_SHALLOW) ? 6 : 3 /turf/attack_hand(mob/user) @@ -248,6 +248,12 @@ if(IS_SHOVEL(W)) + // TODO: move these checks into the interaction handlers. + var/atom/platform = get_supporting_platform() + if(platform) + to_chat(user, SPAN_WARNING("\The [platform] [platform.get_pronouns().is] in the way!")) + return TRUE + if(!can_be_dug(W.material?.hardness)) to_chat(user, SPAN_WARNING("\The [src] is too hard to be dug with \the [W].")) return TRUE @@ -263,6 +269,12 @@ var/decl/material/material = get_material() if(IS_PICK(W) && material) + // TODO: move these checks into the interaction handlers. + var/atom/platform = get_supporting_platform() + if(platform) + to_chat(user, SPAN_WARNING("\The [platform] [platform.get_pronouns().is] in the way!")) + return TRUE + if(material?.hardness <= MAT_VALUE_FLEXIBLE) to_chat(user, SPAN_WARNING("\The [src] is too soft to be excavated with \the [W]. Use a shovel.")) return TRUE @@ -332,7 +344,7 @@ return 0 // Check if they need to climb out of a hole. - if(has_gravity()) + if(has_gravity() && !get_supporting_platform()) var/mob/mover_mob = mover if(!istype(mover_mob) || (!mover_mob.throwing && !mover_mob.can_overcome_gravity())) var/turf/old_turf = mover.loc @@ -726,12 +738,13 @@ var/mob/moving_mob = mover if(moving_mob.can_overcome_gravity()) return null - var/fluid_depth = get_fluid_depth() - if(fluid_depth > FLUID_PUDDLE) - if(fluid_depth <= FLUID_SHALLOW) - return "mask_shallow" - if(fluid_depth <= FLUID_DEEP) - return "mask_deep" + if(!get_supporting_platform()) + var/fluid_depth = get_fluid_depth() + if(fluid_depth > FLUID_PUDDLE) + if(fluid_depth <= FLUID_SHALLOW) + return "mask_shallow" + if(fluid_depth <= FLUID_DEEP) + return "mask_deep" /turf/spark_act(obj/effect/sparks/sparks) if(simulated) diff --git a/code/game/turfs/turf_fluids.dm b/code/game/turfs/turf_fluids.dm index 48b6a7d7a100..13e48d990521 100644 --- a/code/game/turfs/turf_fluids.dm +++ b/code/game/turfs/turf_fluids.dm @@ -62,7 +62,14 @@ fluid_update() // We are now floodable, so wake up our neighbors. /turf/is_flooded(var/lying_mob, var/absolute) - return (flooded || (!absolute && check_fluid_depth(lying_mob ? FLUID_OVER_MOB_HEAD : FLUID_DEEP))) + if(flooded) + return TRUE + if(absolute) + return FALSE + var/required_depth = lying_mob ? FLUID_OVER_MOB_HEAD : FLUID_DEEP + if(get_supporting_platform()) // Increase required depth if we are over the water. + required_depth -= get_physical_height() // depth is negative, -= to increase required depth. + return check_fluid_depth(required_depth) /turf/check_fluid_depth(var/min = 1) . = (get_fluid_depth() >= min) @@ -117,8 +124,14 @@ ..() if(!QDELETED(src) && fluids?.total_volume) fluids.touch_turf(src, touch_atoms = FALSE) // Handled in fluid_act() below. - for(var/atom/movable/AM as anything in get_contained_external_atoms()) - AM.fluid_act(fluids) + // Wet items that are not supported on a platform or such. + var/effective_volume = fluids?.total_volume + if(get_supporting_platform()) + // Depth is negative height, hence +=. TODO: positive heights? No idea how to handle that. + effective_volume += get_physical_height() + if(effective_volume > FLUID_PUDDLE) + for(var/atom/movable/AM as anything in get_contained_external_atoms()) + AM.fluid_act(fluids) /turf/proc/remove_fluids(var/amount, var/defer_update) if(!reagents?.total_liquid_volume) diff --git a/code/game/turfs/turf_footsteps.dm b/code/game/turfs/turf_footsteps.dm index 371d40feefad..bfa1f9171569 100644 --- a/code/game/turfs/turf_footsteps.dm +++ b/code/game/turfs/turf_footsteps.dm @@ -12,4 +12,4 @@ return get_footstep_for_mob(/decl/footsteps/water, caller) if(footstep_type) return get_footstep_for_mob(footstep_type, caller) - return get_footstep_for_mob(/decl/footsteps/blank, caller) \ No newline at end of file + return get_footstep_for_mob(/decl/footsteps/blank, caller) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 0a301a3ea548..3a465515aa4d 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -988,12 +988,12 @@ /mob/proc/get_gender() return gender -/mob/is_fluid_pushable(var/amt) - if(..() && !buckled && (current_posture.prone || !Check_Shoegrip()) && (amt >= mob_size * (current_posture.prone ? 5 : 10))) +/mob/try_fluid_push(volume, strength) + if(..() && !buckled && (current_posture.prone || !Check_Shoegrip()) && (strength >= mob_size * (current_posture.prone ? 5 : 10))) if(!current_posture.prone) SET_STATUS_MAX(src, STAT_WEAK, 1) if(current_posture.prone && prob(10)) - to_chat(src, "You are pushed down by the flood!") + to_chat(src, SPAN_DANGER("You are pushed down by the flood!")) return TRUE return FALSE diff --git a/code/modules/mob/mob_layering.dm b/code/modules/mob/mob_layering.dm index 456fb517d1d4..e4ecb2b50071 100644 --- a/code/modules/mob/mob_layering.dm +++ b/code/modules/mob/mob_layering.dm @@ -7,9 +7,9 @@ var/last_layer = layer var/new_layer = get_base_layer() if(isturf(loc)) - var/turf/T = loc - if(T.pixel_z < 0) - new_layer = T.layer + 0.25 + var/turf/my_turf = loc + if(my_turf.pixel_z < 0 && !my_turf.get_supporting_platform()) + new_layer = my_turf.layer + 0.25 else if(buckled && buckled.buckle_layer_above) new_layer = buckled.layer + ((buckled.dir == SOUTH) ? -0.01 : 0.01) else if(length(grabbed_by)) From 3fc0f3e8fbed6e383cf6dc44981a3ed0a454cbda Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 19 Jan 2025 22:31:01 +1100 Subject: [PATCH 068/120] Fixes flicker in hand slot screen elements. --- code/_onclick/hud/screen/screen_inventory_hands.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/_onclick/hud/screen/screen_inventory_hands.dm b/code/_onclick/hud/screen/screen_inventory_hands.dm index df5784067418..7dbdbf0b1525 100644 --- a/code/_onclick/hud/screen/screen_inventory_hands.dm +++ b/code/_onclick/hud/screen/screen_inventory_hands.dm @@ -1,7 +1,7 @@ /obj/screen/inventory/hand icon_state = "hand_base" -/obj/screen/inventory/hand/on_update_icon() +/obj/screen/inventory/hand/rebuild_screen_overlays() ..() From a6d3c7e4fc60821da2158e8a860d75fdfc05d7ba Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 19 Jan 2025 22:33:17 +1100 Subject: [PATCH 069/120] Changing floor height will clear footprints. --- code/game/turfs/floors/floor_height.dm | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/code/game/turfs/floors/floor_height.dm b/code/game/turfs/floors/floor_height.dm index 2dd080f5edd8..7de5fe0441ee 100644 --- a/code/game/turfs/floors/floor_height.dm +++ b/code/game/turfs/floors/floor_height.dm @@ -5,12 +5,19 @@ return density ? 0 : height /turf/floor/set_physical_height(new_height) - if(height != new_height) - height = new_height - for(var/turf/neighbor as anything in RANGE_TURFS(src, 1)) - neighbor.update_icon() - fluid_update() - if(fluid_overlay) - fluid_overlay.update_icon() - return TRUE - return FALSE + + if(height == new_height) + return FALSE + + height = new_height + for(var/turf/neighbor as anything in RANGE_TURFS(src, 1)) + neighbor.update_icon() + fluid_update() + if(fluid_overlay) + fluid_overlay.update_icon() + + // Clear footprints. + for(var/obj/effect/footprints/prints in contents) + qdel(prints) + + return TRUE From 5cd6a308e6aaf32979e13ffaa6560b1fa6af525a Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 19 Jan 2025 22:33:31 +1100 Subject: [PATCH 070/120] Footprints cannot be placed in fluids. --- code/game/objects/effects/decals/Cleanable/tracks.dm | 1 + code/game/turfs/flooring/_flooring.dm | 2 ++ code/game/turfs/turf.dm | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/code/game/objects/effects/decals/Cleanable/tracks.dm b/code/game/objects/effects/decals/Cleanable/tracks.dm index 7bddd805f9a2..d2e28c977da5 100644 --- a/code/game/objects/effects/decals/Cleanable/tracks.dm +++ b/code/game/objects/effects/decals/Cleanable/tracks.dm @@ -68,6 +68,7 @@ * @param bloodcolor Color of the blood when wet. */ /obj/effect/decal/cleanable/blood/tracks/proc/AddTracks(var/list/DNA, var/comingdir, var/goingdir, var/bloodcolor=COLOR_BLOOD_HUMAN) + var/updated=0 // Shift our goingdir 4 spaces to the left so it's in the GOING bitblock. var/realgoing=BITSHIFT_LEFT(goingdir,4) diff --git a/code/game/turfs/flooring/_flooring.dm b/code/game/turfs/flooring/_flooring.dm index 92d3163ff851..7618f0600eaa 100644 --- a/code/game/turfs/flooring/_flooring.dm +++ b/code/game/turfs/flooring/_flooring.dm @@ -378,6 +378,8 @@ var/global/list/flooring_cache = list() /decl/flooring/proc/try_place_footprints(atom/movable/crosser, turf/target, turf/from_turf, turf/to_turf, use_state = "going") if(!ismob(crosser) || !crosser.simulated || !isturf(from_turf) || !isturf(to_turf)) return FALSE + if(target.check_fluid_depth(FLUID_QDEL_POINT)) + return FALSE var/movement_dir = get_dir(from_turf, to_turf) if(!movement_dir) return FALSE diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 1d52a53bb130..896aad139938 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -717,7 +717,7 @@ /// typepath is a type, not an instance /// new_chemical is optional argument for things like muddy footprints, where typepath isn't enough /turf/proc/AddTracks(obj/effect/decal/cleanable/blood/tracks/typepath, bloodDNA, comingdir, goingdir, bloodcolor = COLOR_BLOOD_HUMAN, new_chemical = null) - if(!simulated) + if(!simulated || check_fluid_depth(FLUID_QDEL_POINT)) return // Populate defaults from the given typepath, where possible. if(isnull(new_chemical)) From 50ec1d1b104474e9b23898aec30f107b9e3c4c97 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Mon, 20 Jan 2025 19:57:57 +1100 Subject: [PATCH 071/120] Fixes poster directional offsets. --- code/game/objects/effects/decals/posters/_poster.dm | 4 ++-- maps/tradeship/tradeship-2.dmm | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/code/game/objects/effects/decals/posters/_poster.dm b/code/game/objects/effects/decals/posters/_poster.dm index e06ef097d23f..6f0e3ab5cf26 100644 --- a/code/game/objects/effects/decals/posters/_poster.dm +++ b/code/game/objects/effects/decals/posters/_poster.dm @@ -7,9 +7,9 @@ icon = 'icons/obj/items/posters.dmi' icon_state = "poster0" anchored = TRUE - directional_offset = @'{"NORTH":{"y":32}, "SOUTH":{"y":-32}, "WEST":{"x":32}, "EAST":{"x":-32}}' + directional_offset = @'{"NORTH":{"y":32}, "SOUTH":{"y":-32}, "EAST":{"x":32}, "WEST":{"x":-32}}' material = /decl/material/solid/organic/paper - max_health = 10 + max_health = 10 parts_type = /obj/item/poster parts_amount = 1 diff --git a/maps/tradeship/tradeship-2.dmm b/maps/tradeship/tradeship-2.dmm index 3c5c5254ea04..5dc58a980578 100644 --- a/maps/tradeship/tradeship-2.dmm +++ b/maps/tradeship/tradeship-2.dmm @@ -1282,7 +1282,7 @@ /obj/machinery/recharger, /obj/structure/sign/poster{ pixel_x = 32; - dir = 8 + dir = 4 }, /obj/item/plate/tray, /obj/item/circular_saw, From f9290d4306540b92040cc736f8220194183b3fe7 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Mon, 20 Jan 2025 20:36:29 +1100 Subject: [PATCH 072/120] Integrating immune_to_floor_hazards() into water crossing logic. --- code/game/atoms_fluids.dm | 4 ++-- code/game/atoms_movable.dm | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/code/game/atoms_fluids.dm b/code/game/atoms_fluids.dm index 82983b1c2ccc..bf49a3469c05 100644 --- a/code/game/atoms_fluids.dm +++ b/code/game/atoms_fluids.dm @@ -47,7 +47,7 @@ // This override exists purely because throwing is movable-level and not atom-level, // for obvious reasons (that being that non-movable atoms cannot move). /atom/movable/submerged(depth, above_turf) - above_turf ||= !!throwing + above_turf ||= immune_to_floor_hazards() return ..() /obj/item/submerged(depth, above_turf) @@ -66,7 +66,7 @@ return ..() /mob/submerged(depth, above_turf) - above_turf ||= is_floating || !!throwing // check throwing here because of the table check coming before parent call + above_turf ||= immune_to_floor_hazards() // check throwing here because of the table check coming before parent call var/obj/structure/table/standing_on = locate(/obj/structure/table) in loc // can't stand on a table if we're floating if(!above_turf && standing_on && standing_on.mob_offset > 0) // standing atop a table that is a meaningful amount above the ground (not a bench) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 586877c4220a..9c481be8d469 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -593,7 +593,7 @@ return null /atom/movable/immune_to_floor_hazards() - return ..() || throwing + return ..() || !!throwing // TODO: make everything use this. /atom/movable/proc/set_anchored(new_anchored) From 709f22aecdb1f8d5a8f7aa0b38d0225c157644b8 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Mon, 20 Jan 2025 20:43:54 +1100 Subject: [PATCH 073/120] Fixes paper dispenser only working on tables. Let paper be free. --- code/modules/clothing/spacesuits/rig/modules/utility.dm | 9 +-------- code/modules/mob/living/silicon/robot/robot_items.dm | 9 ++------- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/code/modules/clothing/spacesuits/rig/modules/utility.dm b/code/modules/clothing/spacesuits/rig/modules/utility.dm index c3aaa393ee41..b354bee3a427 100644 --- a/code/modules/clothing/spacesuits/rig/modules/utility.dm +++ b/code/modules/clothing/spacesuits/rig/modules/utility.dm @@ -456,14 +456,7 @@ use_power_cost = 200 usable = 1 selectable = 0 - device = /obj/item/paper_bin - -/obj/item/rig_module/device/paperdispenser/engage(atom/target) - if(!..() || !device) - return FALSE - if(!target) - device.attack_hand_with_interaction_checks(holder.wearer) - return TRUE + device = /obj/item/form_printer /obj/item/rig_module/device/pen name = "mounted pen" diff --git a/code/modules/mob/living/silicon/robot/robot_items.dm b/code/modules/mob/living/silicon/robot/robot_items.dm index eb0a535eec67..2839e9599c9a 100644 --- a/code/modules/mob/living/silicon/robot/robot_items.dm +++ b/code/modules/mob/living/silicon/robot/robot_items.dm @@ -177,12 +177,8 @@ /obj/item/form_printer/use_on_mob(mob/living/target, mob/living/user, animate = TRUE) return FALSE -/obj/item/form_printer/afterattack(atom/target, mob/living/user, flag, params) - - if(!target || !flag) - return - - if(istype(target,/obj/structure/table)) +/obj/item/form_printer/afterattack(atom/target, mob/living/user, proximity, params) + if(istype(target) && !istype(target, /obj/screen) && proximity) deploy_paper(get_turf(target)) /obj/item/form_printer/attack_self(mob/user) @@ -192,7 +188,6 @@ T.visible_message(SPAN_NOTICE("\The [src.loc] dispenses a sheet of crisp white paper.")) new /obj/item/paper(T) - //Personal shielding for the combat module. /obj/item/borg/combat/shield name = "personal shielding" From 88340b3bd734a5443630df5869b92427e6230ab8 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Mon, 20 Jan 2025 20:50:27 +1100 Subject: [PATCH 074/120] You can now deploy a rig that doesn't require shoes, while wearing shoes. --- code/modules/clothing/spacesuits/rig/rig.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index 0002058a65fe..f9f4f356c2bb 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -264,7 +264,7 @@ wearer.visible_message( SPAN_HARDSUIT("[wearer]'s suit emits a quiet hum as it begins to adjust its seals."), SPAN_HARDSUIT("With a quiet hum, the suit begins running checks and adjusting components.")) - if(seal_delay && !do_after(wearer,seal_delay, src)) + if(seal_delay && !do_after(wearer, seal_delay, src)) if(wearer) to_chat(wearer, "You must remain still while the suit is adjusting the components.") failed_to_seal = 1 @@ -299,7 +299,7 @@ var/obj/item/compare_piece = piece_data[2] var/msg_type = piece_data[3] - if(!piece) + if(!piece || !compare_piece) continue if(!istype(wearer) || !istype(piece) || !istype(compare_piece) || !msg_type) From 7d998cb8f203a9415d76e4384b47ec0b6d0a8cee Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Wed, 15 Jan 2025 19:00:21 +1100 Subject: [PATCH 075/120] Moving unarmed attacks onto limbs. --- code/game/machinery/camera/camera.dm | 2 +- code/game/machinery/doors/windowdoor.dm | 12 ++++---- code/game/objects/items/weapons/weaponry.dm | 10 ++----- .../objects/structures/defensive_barrier.dm | 3 +- code/game/objects/structures/grille.dm | 10 +++---- code/game/objects/structures/window.dm | 22 +++++++------- .../mob/living/human/human_attackhand.dm | 24 ++++++--------- .../modules/mob/living/human/human_defines.dm | 2 -- code/modules/mob/living/human/human_verbs.dm | 6 ---- code/modules/mob/living/living.dm | 8 +++++ code/modules/mob/living/living_resist.dm | 3 +- .../modules/mob/living/silicon/robot/robot.dm | 3 +- code/modules/mob/mob.dm | 21 ++++++++++++++ code/modules/mob/mob_defines.dm | 3 ++ code/modules/organs/external/_external.dm | 6 ---- code/modules/organs/external/head.dm | 18 ++++++++++++ code/modules/organs/external/standard.dm | 19 ++++++++++++ code/modules/paperwork/papershredder.dm | 4 +-- code/modules/power/apc.dm | 29 +++++++++---------- code/modules/power/lighting.dm | 13 +++++---- code/modules/species/species.dm | 23 --------------- code/modules/species/species_helpers.dm | 5 ---- code/modules/species/station/golem.dm | 1 - code/modules/species/station/monkey.dm | 1 - mods/content/fantasy/datum/hnoll/species.dm | 7 ----- mods/species/ascent/datum/species.dm | 5 ---- .../species/bayliens/tajaran/datum/species.dm | 7 ----- .../tajaran/datum/species_bodytypes.dm | 5 +++- .../bayliens/tritonian/datum/species.dm | 7 ----- .../tritonian/datum/species_bodytypes.dm | 3 ++ mods/species/bayliens/unathi/datum/species.dm | 7 ----- .../unathi/datum/species_bodytypes.dm | 27 +++++++++++------ mods/species/drakes/species.dm | 5 +--- mods/species/drakes/species_bodytypes.dm | 15 +++++++++- mods/species/neoavians/datum/species.dm | 6 ---- .../neoavians/datum/species_bodytypes.dm | 15 ++++++++++ mods/species/serpentid/datum/species.dm | 8 ----- .../serpentid/datum/species_bodytypes.dm | 13 +++++++-- mods/species/utility_frames/species.dm | 5 ---- mods/species/vox/datum/species.dm | 8 ----- mods/species/vox/datum/species_bodytypes.dm | 16 ++++++++-- 41 files changed, 209 insertions(+), 198 deletions(-) diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index ee9a28eee31d..3262bf5a4230 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -187,7 +187,7 @@ /obj/machinery/camera/physical_attack_hand(mob/living/human/user) if(!istype(user)) return TRUE - if(user.species.can_shred(user)) + if(user.can_shred()) user.do_attack_animation(src) visible_message(SPAN_WARNING("\The [user] slashes at [src]!")) playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1) diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 6ec853d2eb83..e6366bcc0a0f 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -139,13 +139,11 @@ return /obj/machinery/door/window/physical_attack_hand(mob/user) - if(ishuman(user)) - var/mob/living/human/H = user - if(H.species.can_shred(H)) - playsound(loc, 'sound/effects/Glasshit.ogg', 75, 1) - visible_message("\The [user] smashes against \the [src].", 1) - take_damage(25) - return TRUE + if(user.can_shred()) + playsound(loc, 'sound/effects/Glasshit.ogg', 75, 1) + visible_message(SPAN_DANGER("\The [user] smashes against \the [src].")) + take_damage(25) + return TRUE return ..() /obj/machinery/door/window/emag_act(var/remaining_charges, var/mob/user) diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index 243fe2bd7e88..2981dccbaa8c 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -193,13 +193,9 @@ /obj/effect/energy_net/attack_hand(var/mob/user) if(!user.check_intent(I_FLAG_HARM)) return ..() - var/decl/species/my_species = user.get_species() - if(my_species) - if(my_species.can_shred(user)) - playsound(src.loc, 'sound/weapons/slash.ogg', 80, 1) - current_health -= rand(10, 20) - else - current_health -= rand(1,3) + if(user.can_shred()) + playsound(src.loc, 'sound/weapons/slash.ogg', 80, 1) + current_health -= rand(10, 20) else current_health -= rand(5,8) to_chat(user, SPAN_DANGER("You claw at the energy net.")) diff --git a/code/game/objects/structures/defensive_barrier.dm b/code/game/objects/structures/defensive_barrier.dm index d3d977f5b84e..7545fcc06413 100644 --- a/code/game/objects/structures/defensive_barrier.dm +++ b/code/game/objects/structures/defensive_barrier.dm @@ -105,8 +105,7 @@ if(!user.check_dexterity(DEXTERITY_HOLD_ITEM, TRUE)) return ..() - var/decl/species/species = user.get_species() - if(ishuman(user) && species?.can_shred(user) && user.check_intent(I_FLAG_HARM)) + if(user.can_shred() && user.check_intent(I_FLAG_HARM)) take_damage(20) user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) return TRUE diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 39080d777fb9..385c83e8a22b 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -101,12 +101,10 @@ var/damage_dealt = 1 var/attack_message = "kicks" - if(ishuman(user)) - var/mob/living/human/H = user - if(H.species.can_shred(H)) - attack_message = "mangles" - damage_dealt = 5 - attack_generic(user,damage_dealt,attack_message) + if(user.can_shred()) + attack_message = "mangles" + damage_dealt = 5 + attack_generic(user, damage_dealt, attack_message) return TRUE /obj/structure/grille/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index d516cd10eb23..9a541458f7ae 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -147,21 +147,23 @@ user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) if (user.check_intent(I_FLAG_HARM)) - if (ishuman(user)) - var/mob/living/human/H = user - if(H.species.can_shred(H)) - return attack_generic(H,25) + if(user.can_shred()) + return attack_generic(user, 25) playsound(src.loc, 'sound/effects/glassknock.ogg', 80, 1) user.do_attack_animation(src) - user.visible_message(SPAN_DANGER("\The [user] bangs against \the [src]!"), - SPAN_DANGER("You bang against \the [src]!"), - "You hear a banging sound.") + user.visible_message( + SPAN_DANGER("\The [user] bangs against \the [src]!"), + SPAN_DANGER("You bang against \the [src]!"), + "You hear a banging sound." + ) else playsound(src.loc, 'sound/effects/glassknock.ogg', 80, 1) - user.visible_message("[user.name] knocks on \the [src].", - "You knock on \the [src].", - "You hear a knocking sound.") + user.visible_message( + SPAN_NOTICE("\The [user] knocks on \the [src]."), + SPAN_NOTICE("You knock on \the [src]."), + "You hear a knocking sound." + ) return TRUE /obj/structure/window/do_simple_ranged_interaction(var/mob/user) diff --git a/code/modules/mob/living/human/human_attackhand.dm b/code/modules/mob/living/human/human_attackhand.dm index bf6a29c1bf3a..d32ec613162e 100644 --- a/code/modules/mob/living/human/human_attackhand.dm +++ b/code/modules/mob/living/human/human_attackhand.dm @@ -1,13 +1,12 @@ /mob/living/human/proc/get_unarmed_attack(var/mob/target, var/hit_zone = null) if(!hit_zone) hit_zone = get_target_zone() - var/list/available_attacks = get_natural_attacks() + var/list/available_attacks = get_mob_natural_attacks() var/decl/natural_attack/use_attack = default_attack if(!use_attack || !use_attack.is_usable(src, target, hit_zone) || !(use_attack.type in available_attacks)) use_attack = null var/list/other_attacks = list() - for(var/u_attack_type in available_attacks) - var/decl/natural_attack/u_attack = GET_DECL(u_attack_type) + for(var/decl/natural_attack/u_attack as anything in available_attacks) if(!u_attack.is_usable(src, target, hit_zone)) continue if(u_attack.is_starting_default) @@ -18,11 +17,8 @@ use_attack = pick(other_attacks) . = use_attack?.resolve_to_soft_variant(src) -/mob/living/human/proc/get_natural_attacks() - . = list() - for(var/obj/item/organ/external/limb in get_external_organs()) - if(length(limb.unarmed_attacks) && limb.is_usable()) - . |= limb.unarmed_attacks +/obj/item/organ/external/proc/get_natural_attacks() + return null /obj/item/organ/external/proc/get_injury_status(include_pain = TRUE, include_visible = TRUE) . = list() @@ -409,14 +405,12 @@ set src = usr var/list/choices - for(var/thing in get_natural_attacks()) - var/decl/natural_attack/u_attack = GET_DECL(thing) - if(istype(u_attack)) - var/image/radial_button = new - radial_button.name = capitalize(u_attack.name) - LAZYSET(choices, u_attack, radial_button) + for(var/decl/natural_attack/u_attack as anything in get_mob_natural_attacks()) + var/image/radial_button = new + radial_button.name = capitalize(u_attack.name) + LAZYSET(choices, u_attack, radial_button) var/decl/natural_attack/new_attack = show_radial_menu(src, (attack_selector || src), choices, radius = 42, use_labels = RADIAL_LABELS_OFFSET) - if(QDELETED(src) || !istype(new_attack) || !(new_attack.type in get_natural_attacks())) + if(QDELETED(src) || !istype(new_attack) || !(new_attack in get_mob_natural_attacks())) return default_attack = new_attack to_chat(src, SPAN_NOTICE("Your default unarmed attack is now [default_attack?.name || "cleared"].")) diff --git a/code/modules/mob/living/human/human_defines.dm b/code/modules/mob/living/human/human_defines.dm index 500e8bb1743e..be736a3eb0d7 100644 --- a/code/modules/mob/living/human/human_defines.dm +++ b/code/modules/mob/living/human/human_defines.dm @@ -23,8 +23,6 @@ var/mob/remoteview_target = null var/hand_blood_color var/list/flavor_texts = list() - /// Are you trying not to hurt your opponent? - var/pulling_punches /// We are a robutt. var/full_prosthetic /// Number of robot limbs. diff --git a/code/modules/mob/living/human/human_verbs.dm b/code/modules/mob/living/human/human_verbs.dm index c8f5f9083922..a43f889eb110 100644 --- a/code/modules/mob/living/human/human_verbs.dm +++ b/code/modules/mob/living/human/human_verbs.dm @@ -319,9 +319,3 @@ "[self ? "You pop" : "[U] pops"] your [current_limb.joint] back in!" \ ) current_limb.undislocate() - -/mob/living/human/verb/pull_punches() - set name = "Switch Stance" - set desc = "Try not to hurt them." - set category = "IC" - species.toggle_stance(src) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index f6dd4d172be6..5419ac3e7891 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -2023,3 +2023,11 @@ default behaviour is: // or things should just update their worn slot when coating is added update_equipment_overlay(slot_shoes_str) return TRUE + +/mob/living/verb/pull_punches() + set name = "Switch Stance" + set desc = "Try not to hurt them." + set category = "IC" + if(!incapacitated()) + pulling_punches = !pulling_punches + to_chat(src, SPAN_NOTICE("You are now [pulling_punches ? "pulling your punches" : "not pulling your punches"].")) diff --git a/code/modules/mob/living/living_resist.dm b/code/modules/mob/living/living_resist.dm index c1339fbaefcb..2be9b6f463b8 100644 --- a/code/modules/mob/living/living_resist.dm +++ b/code/modules/mob/living/living_resist.dm @@ -63,8 +63,7 @@ return 1 /mob/living/proc/can_break_restraints() - var/decl/species/my_species = get_species() - return my_species?.can_shred(src, 1) + return can_shred(ignore_intent = TRUE) /mob/living/proc/get_special_resist_time() return 0 diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 4421aabf243b..02ad13a4a969 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -643,8 +643,7 @@ return user?.attempt_hug(src) /mob/living/silicon/robot/default_hurt_interaction(mob/user) - var/decl/species/user_species = user.get_species() - if(user_species?.can_shred(user)) + if(user.can_shred()) attack_generic(user, rand(30,50), "slashed") user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) return TRUE diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index e7e9ef15e082..ad15792b151c 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1392,3 +1392,24 @@ paw = GET_EXTERNAL_ORGAN(src, BP_R_HAND) if(istype(paw) && paw.is_usable()) return paw + +// Called when using the shredding behavior. +/mob/proc/can_shred(var/mob/living/human/H, var/ignore_intent, var/ignore_antag) + if((!ignore_intent && !check_intent(I_FLAG_HARM)) || pulling_punches) + return FALSE + if(!ignore_antag && mind && !player_is_antag(mind)) + return FALSE + if(get_equipped_item(slot_handcuffed_str) || buckled) + return FALSE + for(var/decl/natural_attack/attack as anything in get_mob_natural_attacks()) + if(attack.is_usable(src) && attack.shredding) + return TRUE + return FALSE + +/mob/proc/get_mob_natural_attacks() + for(var/obj/item/organ/external/limb in get_external_organs()) + if(!limb.is_usable()) + continue + var/list/limb_unarmed_attacks = limb.get_natural_attacks() + if(istype(limb_unarmed_attacks, /decl/natural_attack) || (islist(limb_unarmed_attacks) && length(limb_unarmed_attacks))) + LAZYDISTINCTADD(., limb_unarmed_attacks) diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index ec19dd3daedb..88da01483aaf 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -156,3 +156,6 @@ // Offset the overhead text if necessary. var/offset_overhead_text_x = 0 var/offset_overhead_text_y = 0 + + /// Are you trying not to hurt your opponent? + var/pulling_punches diff --git a/code/modules/organs/external/_external.dm b/code/modules/organs/external/_external.dm index 687a43d3814f..aff6b8274c54 100644 --- a/code/modules/organs/external/_external.dm +++ b/code/modules/organs/external/_external.dm @@ -70,8 +70,6 @@ var/stage = 0 var/cavity = 0 - var/list/unarmed_attacks - var/atom/movable/applied_pressure var/atom/movable/splinted @@ -141,10 +139,6 @@ _icon_cache_key = null . = ..() skin_blend = bodytype.limb_blend - for(var/attack_type in species.unarmed_attacks) - var/decl/natural_attack/attack = GET_DECL(attack_type) - if(istype(attack) && (organ_tag in attack.usable_with_limbs)) - LAZYADD(unarmed_attacks, attack_type) update_icon() /obj/item/organ/external/set_bodytype(decl/bodytype/new_bodytype, override_material = null, apply_to_internal_organs = TRUE) diff --git a/code/modules/organs/external/head.dm b/code/modules/organs/external/head.dm index b0930a27868b..b16d8919e296 100644 --- a/code/modules/organs/external/head.dm +++ b/code/modules/organs/external/head.dm @@ -20,6 +20,24 @@ var/forehead_graffiti var/graffiti_style +/obj/item/organ/external/head/get_natural_attacks() + if(!can_intake_reagents) + return null + var/static/unarmed_attack = GET_DECL(/decl/natural_attack/bite) + return unarmed_attack + +/obj/item/organ/external/head/sharp_bite/get_natural_attacks() + if(!can_intake_reagents) + return null + var/static/unarmed_attack = GET_DECL(/decl/natural_attack/bite/sharp) + return unarmed_attack + +/obj/item/organ/external/head/strong_bite/get_natural_attacks() + if(!can_intake_reagents) + return null + var/static/unarmed_attack = GET_DECL(/decl/natural_attack/bite/strong) + return unarmed_attack + /obj/item/organ/external/head/proc/get_organ_eyes_overlay() if(!glowing_eyes && !owner?.has_chemical_effect(CE_GLOWINGEYES, 1)) return diff --git a/code/modules/organs/external/standard.dm b/code/modules/organs/external/standard.dm index 3969df5e653c..84cb21e75a31 100644 --- a/code/modules/organs/external/standard.dm +++ b/code/modules/organs/external/standard.dm @@ -113,6 +113,13 @@ limb_flags = ORGAN_FLAG_CAN_AMPUTATE | ORGAN_FLAG_CAN_STAND | ORGAN_FLAG_HAS_TENDON | ORGAN_FLAG_CAN_BREAK | ORGAN_FLAG_CAN_DISLOCATE organ_category = ORGAN_CATEGORY_STANCE +/obj/item/organ/external/foot/get_natural_attacks() + var/static/list/unarmed_attacks = list( + GET_DECL(/decl/natural_attack/stomp), + GET_DECL(/decl/natural_attack/kick) + ) + return unarmed_attacks + /obj/item/organ/external/foot/right organ_tag = BP_R_FOOT name = "right foot" @@ -139,6 +146,10 @@ is_washable = TRUE var/gripper_type = /datum/inventory_slot/gripper/left_hand +/obj/item/organ/external/hand/get_natural_attacks() + var/static/unarmed_attack = GET_DECL(/decl/natural_attack/punch) + return unarmed_attack + /obj/item/organ/external/hand/do_install(mob/living/human/target, affected, in_place, update_icon, detached) . = ..() if(. && owner && gripper_type) @@ -158,3 +169,11 @@ joint = "right wrist" amputation_point = "right wrist" gripper_type = /datum/inventory_slot/gripper/right_hand + +/obj/item/organ/external/hand/clawed/get_natural_attacks() + var/static/unarmed_attack = GET_DECL(/decl/natural_attack/claws) + return unarmed_attack + +/obj/item/organ/external/hand/right/clawed/get_natural_attacks() + var/static/unarmed_attack = GET_DECL(/decl/natural_attack/claws) + return unarmed_attack diff --git a/code/modules/paperwork/papershredder.dm b/code/modules/paperwork/papershredder.dm index 89f88cf959a8..a5b56cf128fb 100644 --- a/code/modules/paperwork/papershredder.dm +++ b/code/modules/paperwork/papershredder.dm @@ -89,7 +89,7 @@ /obj/machinery/papershredder/proc/is_bin_empty() return !(length(shredder_bin) > 0 && cached_total_matter) -/obj/machinery/papershredder/proc/can_shred(var/obj/item/I, var/mob/user = null) +/obj/machinery/papershredder/proc/can_shred_document(var/obj/item/I, var/mob/user = null) if(!istype(I)) if(user) to_chat(user, SPAN_WARNING("\The [I] cannot be shredded by \the [src]!")) @@ -120,7 +120,7 @@ empty_bin(user, used_item) return TRUE - else if(!trying_to_smack && can_shred(used_item)) + else if(!trying_to_smack && can_shred_document(used_item)) shred(used_item, user) return TRUE return ..() diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 1f6254eea46a..6e2b63b82fa9 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -491,21 +491,20 @@ var/global/list/all_apcs = list() /obj/machinery/power/apc/physical_attack_hand(mob/user) //Human mob special interaction goes here. - if(ishuman(user)) - var/mob/living/human/H = user - - if(H.species.can_shred(H)) - user.visible_message("\The [user] slashes at \the [src]!", "You slash at \the [src]!") - playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1) - - var/allcut = wires.IsAllCut() - if(beenhit >= pick(3, 4) && allcut == 0) - wires.CutAll() - src.update_icon() - src.visible_message("\The [src]'s wires are shredded!") - else - beenhit += 1 - return TRUE + if(user.can_shred()) + user.visible_message( + SPAN_DANGER("\The [user] slashes at \the [src]!"), + SPAN_DANGER("You slash at \the [src]!") + ) + playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1) + var/allcut = wires.IsAllCut() + if(beenhit >= pick(3, 4) && allcut == 0) + wires.CutAll() + update_icon() + visible_message(SPAN_DANGER("\The [src]'s wires are shredded!")) + else + beenhit += 1 + return TRUE return FALSE /obj/machinery/power/apc/interface_interact(mob/user) diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index e3b47f5c5d10..aeef808e555d 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -316,12 +316,13 @@ to_chat(user, "There is no [get_fitting_name()] in this light.") return TRUE - if(ishuman(user)) - var/mob/living/human/H = user - if(H.species.can_shred(H)) - visible_message("[user.name] smashed the light!", 3, "You hear a tinkle of breaking glass.") - broken() - return TRUE + if(user.can_shred()) + visible_message( + SPAN_DANGER("\The [user] smashes the light!"), + blind_message = "You hear a tinkle of breaking glass." + ) + broken() + return TRUE // make it burn hands if not wearing fire-insulated gloves if(on) diff --git a/code/modules/species/species.dm b/code/modules/species/species.dm index 4946a2b424d5..6ef37bd2681e 100644 --- a/code/modules/species/species.dm +++ b/code/modules/species/species.dm @@ -79,12 +79,6 @@ var/global/const/DEFAULT_SPECIES_HEALTH = 200 // Combat vars. var/total_health = DEFAULT_SPECIES_HEALTH // Point at which the mob will enter crit. - var/list/unarmed_attacks = list( // Possible unarmed attacks that the mob will use in combat, - /decl/natural_attack/stomp, - /decl/natural_attack/kick, - /decl/natural_attack/punch, - /decl/natural_attack/bite - ) var/brute_mod = 1 // Physical damage multiplier. var/burn_mod = 1 // Burn damage multiplier. @@ -494,23 +488,6 @@ var/global/const/DEFAULT_SPECIES_HEALTH = 200 return TRUE //We could tie it to stamina return FALSE -// Called when using the shredding behavior. -/decl/species/proc/can_shred(var/mob/living/human/H, var/ignore_intent, var/ignore_antag) - - if((!ignore_intent && !H.check_intent(I_FLAG_HARM)) || H.pulling_punches) - return 0 - - if(!ignore_antag && H.mind && !player_is_antag(H.mind)) - return 0 - - for(var/attack_type in unarmed_attacks) - var/decl/natural_attack/attack = GET_DECL(attack_type) - if(!istype(attack) || !attack.is_usable(H)) - continue - if(attack.shredding) - return 1 - return 0 - /decl/species/proc/handle_vision(var/mob/living/human/H) var/list/vision = H.get_accumulated_vision_handlers() H.update_sight() diff --git a/code/modules/species/species_helpers.dm b/code/modules/species/species_helpers.dm index 5bd257fa5bcd..7079a40757a6 100644 --- a/code/modules/species/species_helpers.dm +++ b/code/modules/species/species_helpers.dm @@ -5,11 +5,6 @@ var/global/list/stored_shock_by_ref = list() target.electrocute_act(stored_shock_by_ref["\ref[src]"]*0.9, src) stored_shock_by_ref["\ref[src]"] = 0 -/decl/species/proc/toggle_stance(var/mob/living/human/H) - if(!H.incapacitated()) - H.pulling_punches = !H.pulling_punches - to_chat(H, "You are now [H.pulling_punches ? "pulling your punches" : "not pulling your punches"].") - /decl/species/proc/fluid_act(var/mob/living/human/H, var/datum/reagents/fluids) SHOULD_CALL_PARENT(TRUE) var/water = REAGENT_VOLUME(fluids, /decl/material/liquid/water) diff --git a/code/modules/species/station/golem.dm b/code/modules/species/station/golem.dm index 9f571d66c608..93dc4786eaeb 100644 --- a/code/modules/species/station/golem.dm +++ b/code/modules/species/station/golem.dm @@ -16,7 +16,6 @@ available_bodytypes = list(/decl/bodytype/crystalline/golem) - unarmed_attacks = list(/decl/natural_attack/stomp, /decl/natural_attack/kick, /decl/natural_attack/punch) species_flags = SPECIES_FLAG_NO_POISON spawn_flags = SPECIES_IS_RESTRICTED shock_vulnerability = 0 diff --git a/code/modules/species/station/monkey.dm b/code/modules/species/station/monkey.dm index 9159f5eadc3c..1871219744e5 100644 --- a/code/modules/species/station/monkey.dm +++ b/code/modules/species/station/monkey.dm @@ -15,7 +15,6 @@ dusted_anim = "dust-m" death_message = "lets out a faint chimper as it collapses and stops moving..." - unarmed_attacks = list(/decl/natural_attack/bite, /decl/natural_attack/claws, /decl/natural_attack/punch) inherent_verbs = list(/mob/living/proc/ventcrawl) species_hud = /datum/hud_data/monkey butchery_data = /decl/butchery_data/humanoid/monkey diff --git a/mods/content/fantasy/datum/hnoll/species.dm b/mods/content/fantasy/datum/hnoll/species.dm index 31ebc61a61ea..8bb1cd7496e7 100644 --- a/mods/content/fantasy/datum/hnoll/species.dm +++ b/mods/content/fantasy/datum/hnoll/species.dm @@ -30,13 +30,6 @@ move_trail = /obj/effect/decal/cleanable/blood/tracks/paw base_external_prosthetics_model = null - unarmed_attacks = list( - /decl/natural_attack/stomp, - /decl/natural_attack/kick, - /decl/natural_attack/punch, - /decl/natural_attack/bite/sharp - ) - available_background_info = list( /decl/background_category/homeworld = list( /decl/background_detail/location/fantasy, diff --git a/mods/species/ascent/datum/species.dm b/mods/species/ascent/datum/species.dm index 809da7c26fb8..f6bc5dddb055 100644 --- a/mods/species/ascent/datum/species.dm +++ b/mods/species/ascent/datum/species.dm @@ -71,11 +71,6 @@ species_flags = SPECIES_FLAG_NO_SLIP | SPECIES_FLAG_NO_MINOR_CUT spawn_flags = SPECIES_IS_RESTRICTED - unarmed_attacks = list( - /decl/natural_attack/claws/strong/gloves, - /decl/natural_attack/bite/sharp - ) - force_background_info = list( /decl/background_category/heritage = /decl/background_detail/heritage/ascent, /decl/background_category/homeworld = /decl/background_detail/location/kharmaani, diff --git a/mods/species/bayliens/tajaran/datum/species.dm b/mods/species/bayliens/tajaran/datum/species.dm index 231ed1684f0e..19de51ffc360 100644 --- a/mods/species/bayliens/tajaran/datum/species.dm +++ b/mods/species/bayliens/tajaran/datum/species.dm @@ -45,13 +45,6 @@ thirst_factor = DEFAULT_THIRST_FACTOR * 1.2 gluttonous = GLUT_TINY - unarmed_attacks = list( - /decl/natural_attack/stomp, - /decl/natural_attack/kick, - /decl/natural_attack/punch, - /decl/natural_attack/bite/sharp - ) - move_trail = /obj/effect/decal/cleanable/blood/tracks/paw available_background_info = list( diff --git a/mods/species/bayliens/tajaran/datum/species_bodytypes.dm b/mods/species/bayliens/tajaran/datum/species_bodytypes.dm index bd161dac4369..0088067d9b28 100644 --- a/mods/species/bayliens/tajaran/datum/species_bodytypes.dm +++ b/mods/species/bayliens/tajaran/datum/species_bodytypes.dm @@ -28,7 +28,10 @@ eye_low_light_vision_adjustment_speed = 0.3 override_limb_types = list( - BP_TAIL = /obj/item/organ/external/tail/cat + BP_TAIL = /obj/item/organ/external/tail/cat, + BP_HEAD = /obj/item/organ/external/head/sharp_bite, + BP_L_HAND = /obj/item/organ/external/hand/clawed, + BP_R_HAND = /obj/item/organ/external/hand/right/clawed ) default_sprite_accessories = list( diff --git a/mods/species/bayliens/tritonian/datum/species.dm b/mods/species/bayliens/tritonian/datum/species.dm index a6e415dbce0f..84491dd46cf6 100644 --- a/mods/species/bayliens/tritonian/datum/species.dm +++ b/mods/species/bayliens/tritonian/datum/species.dm @@ -13,10 +13,3 @@ body_temperature = 302 water_soothe_amount = 5 - - unarmed_attacks = list( - /decl/natural_attack/stomp, - /decl/natural_attack/kick, - /decl/natural_attack/punch, - /decl/natural_attack/bite/sharp - ) diff --git a/mods/species/bayliens/tritonian/datum/species_bodytypes.dm b/mods/species/bayliens/tritonian/datum/species_bodytypes.dm index 0e5614f62d50..dadaac398a3d 100644 --- a/mods/species/bayliens/tritonian/datum/species_bodytypes.dm +++ b/mods/species/bayliens/tritonian/datum/species_bodytypes.dm @@ -6,6 +6,9 @@ override_organ_types = list( BP_LUNGS = /obj/item/organ/internal/lungs/gills ) + override_limb_types = list( + BP_HEAD = /obj/item/organ/external/head/sharp_bite + ) /decl/bodytype/human/tritonian/masculine name = "masculine" diff --git a/mods/species/bayliens/unathi/datum/species.dm b/mods/species/bayliens/unathi/datum/species.dm index 43ab46e00492..ad4a508329bd 100644 --- a/mods/species/bayliens/unathi/datum/species.dm +++ b/mods/species/bayliens/unathi/datum/species.dm @@ -24,13 +24,6 @@ /decl/bodytype/lizard, /decl/bodytype/lizard/masculine ) - unarmed_attacks = list( - /decl/natural_attack/stomp, - /decl/natural_attack/tail, - /decl/natural_attack/claws, - /decl/natural_attack/punch, - /decl/natural_attack/bite/sharp - ) available_accessory_categories = list( SAC_HORNS, diff --git a/mods/species/bayliens/unathi/datum/species_bodytypes.dm b/mods/species/bayliens/unathi/datum/species_bodytypes.dm index 12b4de66522e..226241bc9a1a 100644 --- a/mods/species/bayliens/unathi/datum/species_bodytypes.dm +++ b/mods/species/bayliens/unathi/datum/species_bodytypes.dm @@ -34,19 +34,24 @@ ) override_organ_types = list( - BP_EYES = /obj/item/organ/internal/eyes/lizard, - BP_BRAIN = /obj/item/organ/internal/brain/lizard + BP_EYES = /obj/item/organ/internal/eyes/lizard, + BP_BRAIN = /obj/item/organ/internal/brain/lizard ) - override_limb_types = list(BP_TAIL = /obj/item/organ/external/tail/lizard) + override_limb_types = list( + BP_TAIL = /obj/item/organ/external/tail/lizard, + BP_HEAD = /obj/item/organ/external/head/strong_bite, + BP_L_HAND = /obj/item/organ/external/hand/clawed, + BP_R_HAND = /obj/item/organ/external/hand/right/clawed + ) - cold_level_1 = 280 //Default 260 - Lower is better - cold_level_2 = 220 //Default 200 - cold_level_3 = 130 //Default 120 + cold_level_1 = 280 //Default 260 - Lower is better + cold_level_2 = 220 //Default 200 + cold_level_3 = 130 //Default 120 - heat_level_1 = 420 //Default 360 - Higher is better - heat_level_2 = 480 //Default 400 - heat_level_3 = 1100 //Default 1000 + heat_level_1 = 420 //Default 360 - Higher is better + heat_level_2 = 480 //Default 400 + heat_level_3 = 1100 //Default 1000 heat_discomfort_level = 320 heat_discomfort_strings = list( @@ -81,3 +86,7 @@ /obj/item/organ/external/tail/lizard tail_icon = 'mods/species/bayliens/unathi/icons/tail.dmi' tail_animation_states = 9 + +/obj/item/organ/external/tail/lizard/get_natural_attacks() + var/static/unarmed_attack = GET_DECL(/decl/natural_attack/tail) + return unarmed_attack diff --git a/mods/species/drakes/species.dm b/mods/species/drakes/species.dm index cd57051614f9..e5b53bae100c 100644 --- a/mods/species/drakes/species.dm +++ b/mods/species/drakes/species.dm @@ -20,10 +20,7 @@ /decl/pronouns/male, /decl/pronouns/female ) - unarmed_attacks = list( - /decl/natural_attack/bite/sharp/drake, - /decl/natural_attack/claws/strong/drake - ) + available_background_info = list( /decl/background_category/heritage = list(/decl/background_detail/heritage/grafadreka), /decl/background_category/homeworld = list(/decl/background_detail/location/grafadreka), diff --git a/mods/species/drakes/species_bodytypes.dm b/mods/species/drakes/species_bodytypes.dm index a04b7513377e..c68d50a9fcb7 100644 --- a/mods/species/drakes/species_bodytypes.dm +++ b/mods/species/drakes/species_bodytypes.dm @@ -38,7 +38,8 @@ override_limb_types = list( BP_TAIL = /obj/item/organ/external/tail/grafadreka, BP_L_HAND = /obj/item/organ/external/hand/quadruped/grafadreka, - BP_R_HAND = /obj/item/organ/external/hand/right/quadruped/grafadreka + BP_R_HAND = /obj/item/organ/external/hand/right/quadruped/grafadreka, + BP_HEAD = /obj/item/organ/external/head/grafadreka ) base_color = "#608894" base_eye_color = COLOR_SILVER @@ -307,6 +308,10 @@ _base_attack_force = 8 needs_attack_dexterity = DEXTERITY_NONE +/obj/item/organ/external/hand/quadruped/grafadreka/get_natural_attacks() + var/static/unarmed_attack = GET_DECL(/decl/natural_attack/claws/strong/drake) + return unarmed_attack + /obj/item/organ/external/hand/quadruped/grafadreka/Initialize(mapload, material_key, datum/mob_snapshot/supplied_appearance, decl/bodytype/new_bodytype) . = ..() item_flags |= ITEM_FLAG_NO_BLUDGEON @@ -323,6 +328,10 @@ _base_attack_force = 8 needs_attack_dexterity = DEXTERITY_NONE +/obj/item/organ/external/hand/right/quadruped/grafadreka/get_natural_attacks() + var/static/unarmed_attack = GET_DECL(/decl/natural_attack/claws/strong/drake) + return unarmed_attack + /obj/item/organ/external/hand/right/quadruped/grafadreka/Initialize(mapload, material_key, datum/mob_snapshot/supplied_appearance, decl/bodytype/new_bodytype) . = ..() item_flags |= ITEM_FLAG_NO_BLUDGEON @@ -334,3 +343,7 @@ /obj/item/organ/external/hand/right/quadruped/grafadreka/set_bodytype(decl/bodytype/new_bodytype, override_material, apply_to_internal_organs) override_material = /decl/material/solid/organic/bone . = ..() + +/obj/item/organ/external/head/grafadreka/get_natural_attacks() + var/static/unarmed_attack = GET_DECL(/decl/natural_attack/bite/sharp/drake) + return unarmed_attack diff --git a/mods/species/neoavians/datum/species.dm b/mods/species/neoavians/datum/species.dm index a0bfea025ed0..065b6c6d932d 100644 --- a/mods/species/neoavians/datum/species.dm +++ b/mods/species/neoavians/datum/species.dm @@ -52,12 +52,6 @@ swap_flags = MONKEY|SIMPLE_ANIMAL push_flags = MONKEY|SIMPLE_ANIMAL - unarmed_attacks = list( - /decl/natural_attack/bite/sharp, - /decl/natural_attack/claws, - /decl/natural_attack/stomp/weak - ) - available_background_info = list( /decl/background_category/heritage = list( /decl/background_detail/heritage/neoavian, diff --git a/mods/species/neoavians/datum/species_bodytypes.dm b/mods/species/neoavians/datum/species_bodytypes.dm index 35eb54d9a7ff..a83f74e9b60c 100644 --- a/mods/species/neoavians/datum/species_bodytypes.dm +++ b/mods/species/neoavians/datum/species_bodytypes.dm @@ -39,6 +39,13 @@ base_eye_color = "#f5c842" mob_size = MOB_SIZE_SMALL nail_noun = "talons" + override_limb_types = list( + BP_L_FOOT = /obj/item/organ/external/foot/avian, + BP_R_FOOT = /obj/item/organ/external/foot/right/avian, + BP_L_HAND = /obj/item/organ/external/hand/clawed, + BP_R_HAND = /obj/item/organ/external/hand/right/clawed, + BP_HEAD = /obj/item/organ/external/head/sharp_bite + ) has_organ = list( BP_STOMACH = /obj/item/organ/internal/stomach, BP_HEART = /obj/item/organ/internal/heart, @@ -170,6 +177,14 @@ ) . = ..() +/obj/item/organ/external/foot/avian/get_natural_attacks() + var/static/unarmed_attack = GET_DECL(/decl/natural_attack/stomp/weak) + return unarmed_attack + +/obj/item/organ/external/foot/right/avian/get_natural_attacks() + var/static/unarmed_attack = GET_DECL(/decl/natural_attack/stomp/weak) + return unarmed_attack + /obj/item/organ/external/tail/avian/get_tail() if(istype(bodytype, /decl/bodytype/avian)) var/decl/bodytype/avian/bird_bod = bodytype diff --git a/mods/species/serpentid/datum/species.dm b/mods/species/serpentid/datum/species.dm index 5d9b15171f86..a261ea256d49 100644 --- a/mods/species/serpentid/datum/species.dm +++ b/mods/species/serpentid/datum/species.dm @@ -60,8 +60,6 @@ swap_flags = ALLMOBS move_trail = /obj/effect/decal/cleanable/blood/tracks/snake - unarmed_attacks = list(/decl/natural_attack/forelimb_slash) - pain_emotes_with_pain_level = list( list(/decl/emote/audible/bug_hiss) = 40 ) @@ -101,12 +99,6 @@ return FALSE -/decl/species/serpentid/can_shred(var/mob/living/human/H, var/ignore_intent, var/ignore_antag) - if(!H.get_equipped_item(slot_handcuffed_str) || H.buckled) - return ..(H, ignore_intent, TRUE) - else - return 0 - /decl/species/serpentid/handle_movement_delay_special(var/mob/living/human/victim) var/tally = 0 victim.remove_cloaking_source(src) diff --git a/mods/species/serpentid/datum/species_bodytypes.dm b/mods/species/serpentid/datum/species_bodytypes.dm index 0bf66ff375fa..947019f4db7e 100644 --- a/mods/species/serpentid/datum/species_bodytypes.dm +++ b/mods/species/serpentid/datum/species_bodytypes.dm @@ -34,15 +34,16 @@ BP_HEAD = list("path" = /obj/item/organ/external/head/insectoid/serpentid), BP_L_ARM = list("path" = /obj/item/organ/external/arm/insectoid), BP_L_HAND = list("path" = /obj/item/organ/external/hand/insectoid), - BP_L_HAND_UPPER = list("path" = /obj/item/organ/external/hand/insectoid/upper), + BP_L_HAND_UPPER = list("path" = /obj/item/organ/external/hand/insectoid/upper/serpentid), BP_R_ARM = list("path" = /obj/item/organ/external/arm/right/insectoid), BP_R_HAND = list("path" = /obj/item/organ/external/hand/right/insectoid), - BP_R_HAND_UPPER = list("path" = /obj/item/organ/external/hand/right/insectoid/upper), + BP_R_HAND_UPPER = list("path" = /obj/item/organ/external/hand/right/insectoid/upper/serpentid), BP_R_LEG = list("path" = /obj/item/organ/external/leg/right/insectoid/serpentid), BP_L_LEG = list("path" = /obj/item/organ/external/leg/insectoid/serpentid), BP_L_FOOT = list("path" = /obj/item/organ/external/foot/insectoid/serpentid), BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right/insectoid/serpentid) ) + appearance_descriptors = list( /datum/appearance_descriptor/height = 1.75, /datum/appearance_descriptor/body_length = 1 @@ -122,3 +123,11 @@ name = "green" icon_base = 'mods/species/serpentid/icons/body_green.dmi' uid = "bodytype_serpentid_green" + +/obj/item/organ/external/hand/insectoid/upper/serpentid/get_natural_attacks() + var/static/unarmed_attack = GET_DECL(/decl/natural_attack/forelimb_slash) + return unarmed_attack + +/obj/item/organ/external/hand/right/insectoid/upper/serpentid/get_natural_attacks() + var/static/unarmed_attack = GET_DECL(/decl/natural_attack/forelimb_slash) + return unarmed_attack diff --git a/mods/species/utility_frames/species.dm b/mods/species/utility_frames/species.dm index 55554ae957cd..2fa4f50fe438 100644 --- a/mods/species/utility_frames/species.dm +++ b/mods/species/utility_frames/species.dm @@ -30,11 +30,6 @@ preview_outfit = null - unarmed_attacks = list( - /decl/natural_attack/stomp, - /decl/natural_attack/kick, - /decl/natural_attack/punch - ) available_pronouns = list( /decl/pronouns, /decl/pronouns/neuter diff --git a/mods/species/vox/datum/species.dm b/mods/species/vox/datum/species.dm index 02f7fed9313f..eac1ad157862 100644 --- a/mods/species/vox/datum/species.dm +++ b/mods/species/vox/datum/species.dm @@ -32,14 +32,6 @@ /mob/living/human/proc/toggle_vox_pressure_seal ) - unarmed_attacks = list( - /decl/natural_attack/stomp, - /decl/natural_attack/kick, - /decl/natural_attack/claws/strong/gloves, - /decl/natural_attack/punch, - /decl/natural_attack/bite/strong - ) - rarity_value = 4 description = {"The Vox are the broken remnants of a once-proud race, now reduced to little more diff --git a/mods/species/vox/datum/species_bodytypes.dm b/mods/species/vox/datum/species_bodytypes.dm index cff74b6141d9..092cfeb50b96 100644 --- a/mods/species/vox/datum/species_bodytypes.dm +++ b/mods/species/vox/datum/species_bodytypes.dm @@ -30,9 +30,13 @@ BP_BRAIN ) override_limb_types = list( - BP_GROIN = /obj/item/organ/external/groin/vox, - BP_TAIL = /obj/item/organ/external/tail/vox + BP_GROIN = /obj/item/organ/external/groin/vox, + BP_TAIL = /obj/item/organ/external/tail/vox, + BP_L_HAND = /obj/item/organ/external/hand/vox, + BP_R_HAND = /obj/item/organ/external/hand/right/vox, + BP_HEAD = /obj/item/organ/external/head/strong_bite ) + has_organ = list( BP_STOMACH = /obj/item/organ/internal/stomach/vox, BP_HEART = /obj/item/organ/internal/heart/vox, @@ -172,3 +176,11 @@ /obj/item/organ/external/tail/vox/stanchion tail_icon = 'mods/species/vox/icons/body/stanchion/body.dmi' + +/obj/item/organ/external/hand/vox/get_natural_attacks() + var/static/unarmed_attack = GET_DECL(/decl/natural_attack/claws/strong/gloves) + return unarmed_attack + +/obj/item/organ/external/hand/right/vox/get_natural_attacks() + var/static/unarmed_attack = GET_DECL(/decl/natural_attack/claws/strong/gloves) + return unarmed_attack From 4261bc507fd3aeec68a80d66b4ce91f287a5841d Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 19 Jan 2025 12:39:43 +1100 Subject: [PATCH 076/120] Fixing drakes losing their mouth slot. --- mods/species/drakes/species_bodytypes.dm | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/mods/species/drakes/species_bodytypes.dm b/mods/species/drakes/species_bodytypes.dm index c68d50a9fcb7..aae52bd678ac 100644 --- a/mods/species/drakes/species_bodytypes.dm +++ b/mods/species/drakes/species_bodytypes.dm @@ -39,7 +39,7 @@ BP_TAIL = /obj/item/organ/external/tail/grafadreka, BP_L_HAND = /obj/item/organ/external/hand/quadruped/grafadreka, BP_R_HAND = /obj/item/organ/external/hand/right/quadruped/grafadreka, - BP_HEAD = /obj/item/organ/external/head/grafadreka + BP_HEAD = /obj/item/organ/external/head/gripper/grafadreka ) base_color = "#608894" base_eye_color = COLOR_SILVER @@ -203,9 +203,14 @@ /datum/ability_handler/predator/grafadreka/hatchling ) z_flags = 0 + // TODO: weaker attack subtypes for the baby override_limb_types = list( - BP_TAIL = /obj/item/organ/external/tail/grafadreka/hatchling + BP_TAIL = /obj/item/organ/external/tail/grafadreka/hatchling, + BP_L_HAND = /obj/item/organ/external/hand/quadruped/grafadreka, + BP_R_HAND = /obj/item/organ/external/hand/right/quadruped/grafadreka, + BP_HEAD = /obj/item/organ/external/head/gripper/grafadreka ) + default_emotes = list( /decl/emote/audible/drake_hatchling_growl, /decl/emote/audible/drake_hatchling_whine, @@ -344,6 +349,6 @@ override_material = /decl/material/solid/organic/bone . = ..() -/obj/item/organ/external/head/grafadreka/get_natural_attacks() +/obj/item/organ/external/head/gripper/grafadreka/get_natural_attacks() var/static/unarmed_attack = GET_DECL(/decl/natural_attack/bite/sharp/drake) return unarmed_attack From f772186fa5fe26dcc409b7e89af598c2add60a96 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 19 Jan 2025 19:44:05 +1100 Subject: [PATCH 077/120] Generalizing sharpening material. --- code/game/objects/items/blades/_blade.dm | 4 ++-- code/game/objects/items/blades/folding.dm | 2 +- code/game/objects/items/blades/spear.dm | 4 ++-- code/game/objects/items/rock.dm | 8 ++++---- code/game/objects/items/weapons/material/thrown.dm | 2 +- code/game/objects/items/weapons/melee/energy_axe.dm | 2 +- code/modules/food/utensils/utensil_hybrid.dm | 4 ++-- code/modules/paperwork/pen/fancy.dm | 2 +- code/modules/paperwork/pen/quill_and_ink.dm | 2 +- code/modules/paperwork/pen/reagent_pen.dm | 2 +- code/modules/tools/subtypes/axes.dm | 4 ++-- code/modules/tools/subtypes/hoes.dm | 4 ++-- code/modules/tools/subtypes/pickaxes.dm | 4 ++-- code/modules/tools/subtypes/shovel.dm | 8 ++++---- code/modules/tools/subtypes/xenoarchaeology_picks.dm | 4 ++-- mods/content/item_sharpening/_item_sharpening.dm | 4 ++++ mods/content/item_sharpening/grindstone.dm | 4 ++++ mods/content/item_sharpening/item_sharpen.dm | 11 ++++------- 18 files changed, 40 insertions(+), 35 deletions(-) diff --git a/code/game/objects/items/blades/_blade.dm b/code/game/objects/items/blades/_blade.dm index 74acd76417af..19dbcbce1cd6 100644 --- a/code/game/objects/items/blades/_blade.dm +++ b/code/game/objects/items/blades/_blade.dm @@ -6,8 +6,8 @@ origin_tech = @'{"materials":1,"combat":1}' attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") obj_flags = OBJ_FLAG_CONDUCTIBLE - sharp = TRUE - edge = TRUE + sharp = TRUE + edge = TRUE item_flags = ITEM_FLAG_IS_WEAPON pickup_sound = 'sound/foley/knife1.ogg' drop_sound = 'sound/foley/knifedrop3.ogg' diff --git a/code/game/objects/items/blades/folding.dm b/code/game/objects/items/blades/folding.dm index 8af5321a1208..281c88d523a0 100644 --- a/code/game/objects/items/blades/folding.dm +++ b/code/game/objects/items/blades/folding.dm @@ -3,7 +3,7 @@ desc = "A small folding knife." icon = 'icons/obj/items/bladed/folding.dmi' w_class = ITEM_SIZE_SMALL - sharp = FALSE + sharp = FALSE pommel_material = null guard_material = null slot_flags = null diff --git a/code/game/objects/items/blades/spear.dm b/code/game/objects/items/blades/spear.dm index 99af4702dc2c..2779646e0c85 100644 --- a/code/game/objects/items/blades/spear.dm +++ b/code/game/objects/items/blades/spear.dm @@ -3,8 +3,8 @@ desc = "A haphazardly-constructed yet still deadly weapon of ancient design." icon = 'icons/obj/items/bladed/spear.dmi' throw_speed = 3 - edge = FALSE - sharp = TRUE + edge = FALSE + sharp = TRUE attack_verb = list("attacked", "poked", "jabbed", "torn", "gored") does_spin = FALSE abstract_type = /obj/item/bladed/polearm/spear diff --git a/code/game/objects/items/rock.dm b/code/game/objects/items/rock.dm index 76b9f6d04862..4a57b5ab4dde 100644 --- a/code/game/objects/items/rock.dm +++ b/code/game/objects/items/rock.dm @@ -3,8 +3,8 @@ desc = "The secret is to bang the rocks together, guys." icon = 'icons/obj/items/rock.dmi' icon_state = ICON_STATE_WORLD - sharp = TRUE - edge = TRUE + sharp = TRUE + edge = TRUE _base_attack_force = 3 material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME w_class = ITEM_SIZE_SMALL @@ -49,6 +49,6 @@ name = "striker" desc = "A squared-off, rather worn-down piece of stone." icon = 'icons/obj/items/striker.dmi' - sharp = FALSE - edge = FALSE + sharp = FALSE + edge = FALSE w_class = ITEM_SIZE_TINY \ No newline at end of file diff --git a/code/game/objects/items/weapons/material/thrown.dm b/code/game/objects/items/weapons/material/thrown.dm index a49a1f7ea61d..7e878a0ac20c 100644 --- a/code/game/objects/items/weapons/material/thrown.dm +++ b/code/game/objects/items/weapons/material/thrown.dm @@ -7,7 +7,7 @@ throw_speed = 10 throw_range = 15 sharp = TRUE - edge = TRUE + edge = TRUE material = /decl/material/solid/metal/steel material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME item_flags = ITEM_FLAG_IS_WEAPON diff --git a/code/game/objects/items/weapons/melee/energy_axe.dm b/code/game/objects/items/weapons/melee/energy_axe.dm index ca5be697bd48..e7845e089858 100644 --- a/code/game/objects/items/weapons/melee/energy_axe.dm +++ b/code/game/objects/items/weapons/melee/energy_axe.dm @@ -13,7 +13,7 @@ active_attack_verb = list("attacked", "chopped", "cleaved", "torn", "cut") inactive_attack_verb = list("attacked", "chopped", "cleaved", "torn", "cut") sharp = TRUE - edge = TRUE + edge = TRUE base_parry_chance = 30 active_parry_chance = 30 melee_accuracy_bonus = 15 diff --git a/code/modules/food/utensils/utensil_hybrid.dm b/code/modules/food/utensils/utensil_hybrid.dm index 1928f5aaab6c..dde7a7e98952 100644 --- a/code/modules/food/utensils/utensil_hybrid.dm +++ b/code/modules/food/utensils/utensil_hybrid.dm @@ -11,8 +11,8 @@ name = "foon" desc = "It's a foon. It's much like a spoon, but much sharper." icon = 'icons/obj/food/utensils/foon.dmi' - sharp = TRUE - edge = TRUE + sharp = TRUE + edge = TRUE utensil_flags = UTENSIL_FLAG_SLICE | UTENSIL_FLAG_SCOOP /obj/item/utensil/foon/plastic diff --git a/code/modules/paperwork/pen/fancy.dm b/code/modules/paperwork/pen/fancy.dm index 988b0a4b60cb..098033965e66 100644 --- a/code/modules/paperwork/pen/fancy.dm +++ b/code/modules/paperwork/pen/fancy.dm @@ -1,7 +1,7 @@ /obj/item/pen/fancy name = "fountain pen" icon = 'icons/obj/items/pens/pen_fancy.dmi' - sharp = TRUE + sharp = TRUE stroke_color = "#1c1713" //dark ashy brownish stroke_color_name = "dark ashy brownish" material = /decl/material/solid/metal/steel diff --git a/code/modules/paperwork/pen/quill_and_ink.dm b/code/modules/paperwork/pen/quill_and_ink.dm index 18cf19bd1499..f643b9d12472 100644 --- a/code/modules/paperwork/pen/quill_and_ink.dm +++ b/code/modules/paperwork/pen/quill_and_ink.dm @@ -1,7 +1,7 @@ /obj/item/pen/fancy/quill name = "quill pen" icon = 'icons/obj/items/pens/pen_quill.dmi' - sharp = FALSE + sharp = FALSE material = /decl/material/solid/organic/skin/feathers pen_quality = TOOL_QUALITY_DEFAULT max_uses = 5 // gotta re-ink it often! diff --git a/code/modules/paperwork/pen/reagent_pen.dm b/code/modules/paperwork/pen/reagent_pen.dm index 2493a7b139c1..7334323851a1 100644 --- a/code/modules/paperwork/pen/reagent_pen.dm +++ b/code/modules/paperwork/pen/reagent_pen.dm @@ -1,7 +1,7 @@ /obj/item/pen/reagent atom_flags = ATOM_FLAG_OPEN_CONTAINER origin_tech = @'{"materials":2,"esoteric":5}' - sharp = TRUE + sharp = TRUE pen_quality = TOOL_QUALITY_MEDIOCRE /obj/item/pen/reagent/Initialize() diff --git a/code/modules/tools/subtypes/axes.dm b/code/modules/tools/subtypes/axes.dm index 20e47c48f4d9..d671ffa07479 100644 --- a/code/modules/tools/subtypes/axes.dm +++ b/code/modules/tools/subtypes/axes.dm @@ -3,8 +3,8 @@ desc = "A handheld tool for chopping things, wood, food, or people." icon_state = "preview" icon = 'icons/obj/items/tool/axes/handaxe.dmi' - sharp = TRUE - edge = TRUE + sharp = TRUE + edge = TRUE handle_material = /decl/material/solid/organic/wood/oak item_flags = ITEM_FLAG_IS_WEAPON origin_tech = @'{"materials":2,"combat":1}' diff --git a/code/modules/tools/subtypes/hoes.dm b/code/modules/tools/subtypes/hoes.dm index 6e8ed505a827..b5bdda347638 100644 --- a/code/modules/tools/subtypes/hoes.dm +++ b/code/modules/tools/subtypes/hoes.dm @@ -3,8 +3,8 @@ desc = "It's used for removing weeds or scratching your back." icon = 'icons/obj/items/tool/hoes/hoe.dmi' icon_state = "preview" - sharp = TRUE - edge = TRUE + sharp = TRUE + edge = TRUE attack_verb = list("slashed", "sliced", "cut", "clawed") material = /decl/material/solid/metal/steel material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME diff --git a/code/modules/tools/subtypes/pickaxes.dm b/code/modules/tools/subtypes/pickaxes.dm index 951afcf148bb..083c99661f8c 100644 --- a/code/modules/tools/subtypes/pickaxes.dm +++ b/code/modules/tools/subtypes/pickaxes.dm @@ -3,8 +3,8 @@ desc = "A heavy tool with a pick head for prospecting for minerals, and an axe head for dealing with anyone with a prior claim." icon_state = "preview" icon = 'icons/obj/items/tool/pickaxe.dmi' - sharp = TRUE - edge = TRUE + sharp = TRUE + edge = TRUE w_class = ITEM_SIZE_HUGE handle_material = /decl/material/solid/organic/wood/oak _base_attack_force = 15 diff --git a/code/modules/tools/subtypes/shovel.dm b/code/modules/tools/subtypes/shovel.dm index 3d8afd26eaec..204bb0a9fbb4 100644 --- a/code/modules/tools/subtypes/shovel.dm +++ b/code/modules/tools/subtypes/shovel.dm @@ -5,8 +5,8 @@ icon_state = "preview" // mapping preview icon slot_flags = SLOT_LOWER_BODY w_class = ITEM_SIZE_LARGE - edge = TRUE - sharp = TRUE + edge = TRUE + sharp = TRUE attack_verb = list("bashed", "bludgeoned", "thrashed", "whacked") handle_material = /decl/material/solid/organic/wood/oak _base_attack_force = 8 @@ -36,8 +36,8 @@ icon = 'icons/obj/items/tool/shovels/spade.dmi' icon_state = "preview" // mapping preview icon w_class = ITEM_SIZE_SMALL - edge = FALSE - sharp = FALSE + edge = FALSE + sharp = FALSE slot_flags = SLOT_LOWER_BODY attack_verb = list("bashed", "bludgeoned", "thrashed", "whacked") material_alteration = 0 diff --git a/code/modules/tools/subtypes/xenoarchaeology_picks.dm b/code/modules/tools/subtypes/xenoarchaeology_picks.dm index ebe8b03af09b..2a335b9fa4ca 100644 --- a/code/modules/tools/subtypes/xenoarchaeology_picks.dm +++ b/code/modules/tools/subtypes/xenoarchaeology_picks.dm @@ -7,7 +7,7 @@ material = /decl/material/solid/metal/chromium matter = list(/decl/material/solid/metal/steel = MATTER_AMOUNT_SECONDARY) w_class = ITEM_SIZE_SMALL - sharp = TRUE + sharp = TRUE abstract_type = /obj/item/tool/xeno material_alteration = 0 handle_material = /decl/material/solid/organic/plastic @@ -42,7 +42,7 @@ _base_attack_force = 1 attack_verb = list("prodded", "attacked") desc = "A wood-handled brush with thick metallic wires for clearing away dust and loose scree." - sharp = FALSE + sharp = FALSE material = /decl/material/solid/metal/steel handle_material = /decl/material/solid/organic/wood/oak excavation_amount = 1 diff --git a/mods/content/item_sharpening/_item_sharpening.dm b/mods/content/item_sharpening/_item_sharpening.dm index 53c03251f449..3807839161bd 100644 --- a/mods/content/item_sharpening/_item_sharpening.dm +++ b/mods/content/item_sharpening/_item_sharpening.dm @@ -2,3 +2,7 @@ /decl/modpack/item_sharpening name = "Item Sharpening" + +/obj/proc/get_sharpening_material() + RETURN_TYPE(/decl/material) + return get_material() diff --git a/mods/content/item_sharpening/grindstone.dm b/mods/content/item_sharpening/grindstone.dm index 13bc15f848b6..13d8f1260520 100644 --- a/mods/content/item_sharpening/grindstone.dm +++ b/mods/content/item_sharpening/grindstone.dm @@ -40,3 +40,7 @@ if(!QDELETED(src) && working) stop_working() return TRUE + +/obj/structure/working/grindstone/get_sharpening_material() + RETURN_TYPE(/decl/material) + return stone_material diff --git a/mods/content/item_sharpening/item_sharpen.dm b/mods/content/item_sharpening/item_sharpen.dm index 5212ad94ab93..a72e928e5e88 100644 --- a/mods/content/item_sharpening/item_sharpen.dm +++ b/mods/content/item_sharpening/item_sharpen.dm @@ -3,18 +3,15 @@ if(has_item_effect(/decl/item_effect/sharpened, IE_CAT_EXAMINE) && get_item_effect_parameter(/decl/item_effect/sharpened, IE_CAT_DAMAGE, IE_PAR_USES) <= 0) SetName("dulled [name]") -/obj/item/proc/can_sharpen_with(obj/item/sharpening_with) - if(!has_item_effect(/decl/item_effect/sharpened, IE_CAT_DAMAGE)) +/obj/item/proc/can_sharpen_with(obj/sharpening_with) + if(!has_item_effect(/decl/item_effect/sharpened, IE_CAT_DAMAGE) || !material || !istype(sharpening_with)) return FALSE var/list/params = get_item_effect_parameters(/decl/item_effect/sharpened, IE_CAT_DAMAGE) if(!islist(params) || params[IE_PAR_USES] >= params[IE_PAR_MAX_USES]) return FALSE - if(istype(sharpening_with, /obj/structure/working/grindstone)) - var/obj/structure/working/grindstone/stone = sharpening_with - return !material || material.hardness <= stone.stone_material?.hardness - return !material || material.hardness <= sharpening_with.material?.hardness + return material.hardness <= sharpening_with.get_sharpening_material()?.hardness -/obj/item/proc/sharpen_with(mob/user, obj/item/sharpen_with) +/obj/item/proc/sharpen_with(mob/user, obj/sharpen_with) if(!has_item_effect(/decl/item_effect/sharpened, IE_CAT_DAMAGE)) return FALSE var/list/params = get_item_effect_parameters(/decl/item_effect/sharpened, IE_CAT_DAMAGE) From e1d7453ac23ff88035dd7b05cb5f4ea1cf5a5c56 Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Tue, 21 Jan 2025 00:47:54 +0000 Subject: [PATCH 078/120] Automatic changelog generation [ci skip] --- html/changelog.html | 6 ++++++ html/changelogs/.all_changelog.yml | 4 ++++ html/changelogs/AutoChangeLog-pr-4762.yml | 5 ----- 3 files changed, 10 insertions(+), 5 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-4762.yml diff --git a/html/changelog.html b/html/changelog.html index d507970d55ed..9b10adb50da0 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -52,6 +52,12 @@ -->
+

21 January 2025

+

Penelope Haze updated:

+
    +
  • Mud can now receive footprints with any reagent other than mud. No more conspicuously missing bloody footprints!
  • +
+

19 January 2025

MistakeNot4892 updated:

    diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 7192cd238724..142b18620763 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -14963,3 +14963,7 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. MistakeNot4892: - tweak: Intents have been rewritten and moved, please report any issues with intent selection. +2025-01-21: + Penelope Haze: + - tweak: Mud can now receive footprints with any reagent other than mud. No more + conspicuously missing bloody footprints! diff --git a/html/changelogs/AutoChangeLog-pr-4762.yml b/html/changelogs/AutoChangeLog-pr-4762.yml deleted file mode 100644 index d387cce9023f..000000000000 --- a/html/changelogs/AutoChangeLog-pr-4762.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: Penelope Haze -changes: - - {tweak: Mud can now receive footprints with any reagent other than mud. No more - conspicuously missing bloody footprints!} -delete-after: true From 184163b1727420cdd464effe8170bbbbac2aab18 Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Wed, 22 Jan 2025 04:43:03 +1100 Subject: [PATCH 079/120] Automatic changelog generation for PR #4712 [ci skip] --- html/changelogs/AutoChangeLog-pr-4712.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4712.yml diff --git a/html/changelogs/AutoChangeLog-pr-4712.yml b/html/changelogs/AutoChangeLog-pr-4712.yml new file mode 100644 index 000000000000..cf23dbfe571a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4712.yml @@ -0,0 +1,4 @@ +author: MistakeNot4892 +changes: + - {tweak: Swords on Shaded Hills can be sharpened using whetstones or grindstones.} +delete-after: true From a2f16322ac15f9a9870ea0888321111cfbf7f349 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 19 Jan 2025 15:14:05 -0500 Subject: [PATCH 080/120] Remove unnecessary spawn()s before qdel --- code/game/objects/effects/mines.dm | 18 ++++++------------ code/modules/assembly/holder.dm | 3 +-- code/modules/mob/transform_procs.dm | 8 +++----- mods/mobs/borers/mob/organ.dm | 3 +-- 4 files changed, 11 insertions(+), 21 deletions(-) diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm index 7f70b3e996c6..ac59e8322d4a 100644 --- a/code/game/objects/effects/mines.dm +++ b/code/game/objects/effects/mines.dm @@ -34,16 +34,14 @@ if(ismob(obj)) var/mob/mob = obj mob.add_genetic_condition(pick(decls_repository.get_decls_of_type(/decl/genetic_condition/disability))) - spawn(0) - qdel(src) + qdel(src) /obj/effect/mine/proc/triggerstun(obj) if(ismob(obj)) var/mob/M = obj SET_STATUS_MAX(M, STAT_STUN, 30) spark_at(src, cardinal_only = TRUE) - spawn(0) - qdel(src) + qdel(src) /obj/effect/mine/proc/triggern2o(obj) //example: n2o triggerproc @@ -53,8 +51,7 @@ if(target.simulated && !target.blocks_air) target.assume_gas(/decl/material/gas/nitrous_oxide, 30) - spawn(0) - qdel(src) + qdel(src) /obj/effect/mine/proc/triggerflame(obj) for (var/turf/target in range(1,src)) @@ -62,21 +59,18 @@ target.assume_gas(/decl/material/gas/hydrogen, 30) target.hotspot_expose(1000, CELL_VOLUME) - spawn(0) - qdel(src) + qdel(src) /obj/effect/mine/proc/triggerkick(obj) spark_at(src, cardinal_only = TRUE) if(ismob(obj)) var/mob/victim = obj qdel(victim.client) - spawn(0) - qdel(src) + qdel(src) /obj/effect/mine/proc/explode(obj) explosion(loc, 0, 1, 2, 3) - spawn(0) - qdel(src) + qdel(src) /obj/effect/mine/dnascramble name = "Radiation Mine" diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm index dba32a26eb25..9a794b2c9006 100644 --- a/code/modules/assembly/holder.dm +++ b/code/modules/assembly/holder.dm @@ -159,8 +159,7 @@ if(a_right) a_right.holder = null a_right.forceMove(T) - spawn(0) - qdel(src) + qdel(src) return /obj/item/assembly_holder/hear_talk(mob/living/M, msg, verb, decl/language/speaking) diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 866c96a62c6e..6ec207ea1b87 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -98,8 +98,7 @@ O.add_ai_verbs() O.rename_self("ai",1) - spawn(0) // Mobs still instantly del themselves, thus we need to spawn or O will never be returned - qdel(src) + qdel(src) return O //human -> robot @@ -136,7 +135,7 @@ RAISE_EVENT(/decl/observ/cyborg_created, O) O.Namepick() - qdel(src) // Queues us for a hard delete + qdel(src) return O /mob/living/human/proc/corgize() @@ -188,8 +187,7 @@ to_chat(new_mob, "You suddenly feel more... animalistic.") - spawn() - qdel(src) + qdel(src) return /mob/proc/Animalize() diff --git a/mods/mobs/borers/mob/organ.dm b/mods/mobs/borers/mob/organ.dm index c1f686ade981..80c12e77c94c 100644 --- a/mods/mobs/borers/mob/organ.dm +++ b/mods/mobs/borers/mob/organ.dm @@ -38,5 +38,4 @@ B.leave_host() B.ckey = last_owner.ckey - spawn(0) - qdel(src) + qdel(src) From ca40142b0585262b0028422cf594fb049ac1d856 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 19 Jan 2025 15:16:59 -0500 Subject: [PATCH 081/120] Replace sleep/spawn delayed qdels with QDEL_IN --- code/_onclick/hud/screen/screen_credits.dm | 12 +++++----- code/game/objects/effects/chem/water.dm | 3 +-- code/game/objects/effects/temporary.dm | 10 +++++++-- code/game/objects/empulse.dm | 8 +------ .../weapons/grenades/anti_photon_grenade.dm | 3 +-- code/game/objects/items/weapons/weaponry.dm | 6 ++--- code/modules/admin/topic.dm | 3 +-- code/modules/clothing/head/fated_key.dm | 4 ++-- .../modules/mob/living/human/human_helpers.dm | 5 ++--- .../modules/mob/living/silicon/robot/robot.dm | 3 +-- code/modules/power/lighting.dm | 17 ++++++++------ code/modules/recycling/disposalpipe.dm | 3 +-- code/modules/vehicles/vehicle.dm | 22 +++++++------------ .../system/psionics/equipment/psipower_tk.dm | 3 +-- 14 files changed, 46 insertions(+), 56 deletions(-) diff --git a/code/_onclick/hud/screen/screen_credits.dm b/code/_onclick/hud/screen/screen_credits.dm index 5025cc7a87dc..2c04fffcf9a9 100644 --- a/code/_onclick/hud/screen/screen_credits.dm +++ b/code/_onclick/hud/screen/screen_credits.dm @@ -18,15 +18,17 @@ animate(src, transform = M, time = CREDIT_ROLL_SPEED) target = M animate(src, alpha = 255, time = CREDIT_EASE_DURATION, flags = ANIMATION_PARALLEL) - spawn(CREDIT_ROLL_SPEED - CREDIT_EASE_DURATION) - if(!QDELETED(src)) - animate(src, alpha = 0, transform = target, time = CREDIT_EASE_DURATION) - sleep(CREDIT_EASE_DURATION) - qdel(src) + addtimer(CALLBACK(src, PROC_REF(ease_out)), CREDIT_ROLL_SPEED - CREDIT_EASE_DURATION) var/mob/owner = owner_ref?.resolve() if(istype(owner) && owner.client) owner.client.screen += src +/obj/screen/credit/proc/ease_out() + if(QDELETED(src)) + return + animate(src, alpha = 0, transform = target, time = CREDIT_EASE_DURATION) + QDEL_IN_CLIENT_TIME(src, CREDIT_EASE_DURATION) + /obj/screen/credit/Destroy() var/client/P = parent if(istype(P)) diff --git a/code/game/objects/effects/chem/water.dm b/code/game/objects/effects/chem/water.dm index ef1d2ba60969..8f4dbce7bb75 100644 --- a/code/game/objects/effects/chem/water.dm +++ b/code/game/objects/effects/chem/water.dm @@ -45,8 +45,7 @@ break sleep(delay) - sleep(10) - qdel(src) + QDEL_IN(src, 1 SECOND) /obj/effect/effect/water/Move(turf/newloc) if(newloc.density) diff --git a/code/game/objects/effects/temporary.dm b/code/game/objects/effects/temporary.dm index b457013a1034..b56d38275f17 100644 --- a/code/game/objects/effects/temporary.dm +++ b/code/game/objects/effects/temporary.dm @@ -5,7 +5,7 @@ layer = ABOVE_HUMAN_LAYER mouse_opacity = MOUSE_OPACITY_UNCLICKABLE simulated = FALSE - var/duration = 10 //in deciseconds + var/duration = 1 SECOND //in deciseconds /obj/effect/temp_visual/Initialize(mapload, set_dir) if(set_dir) @@ -17,9 +17,15 @@ icon = 'icons/effects/effects.dmi' icon_state = "empdisable" +/obj/effect/temp_visual/emppulse + name = "electromagnetic pulse" + icon = 'icons/effects/effects.dmi' + icon_state = "emppulse" + duration = 2 SECONDS + /obj/effect/temp_visual/bloodsplatter icon = 'icons/effects/bloodspatter.dmi' - duration = 5 + duration = 0.5 SECONDS layer = LYING_HUMAN_LAYER var/splatter_type = "splatter" diff --git a/code/game/objects/empulse.dm b/code/game/objects/empulse.dm index 33ea333138ce..24dad4dfb5d0 100644 --- a/code/game/objects/empulse.dm +++ b/code/game/objects/empulse.dm @@ -14,13 +14,7 @@ log_and_message_admins("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] ") if(heavy_range > 1) - var/obj/effect/overlay/pulse = new/obj/effect/overlay(epicenter) - pulse.icon = 'icons/effects/effects.dmi' - pulse.icon_state = "emppulse" - pulse.SetName("electromagnetic pulse") - pulse.anchored = TRUE - spawn(20) - qdel(pulse) + new /obj/effect/temp_visual/emppulse(epicenter) if(heavy_range > light_range) light_range = heavy_range diff --git a/code/game/objects/items/weapons/grenades/anti_photon_grenade.dm b/code/game/objects/items/weapons/grenades/anti_photon_grenade.dm index a9fdaf0deab2..19054df59bde 100644 --- a/code/game/objects/items/weapons/grenades/anti_photon_grenade.dm +++ b/code/game/objects/items/weapons/grenades/anti_photon_grenade.dm @@ -18,5 +18,4 @@ /obj/item/grenade/anti_photon/proc/finish() set_light(10, 10, rgb(rand(64,255), rand(64,255), rand(64,255))) playsound(loc, 'sound/effects/bang.ogg', 50, 1, 5) - sleep(1 SECOND) - qdel(src) \ No newline at end of file + QDEL_IN(src, 1 SECOND) \ No newline at end of file diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index 43e52f205a44..1202c6d20ad4 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -64,8 +64,7 @@ /obj/item/energy_net/dropped() ..() - spawn(10) - if(src) qdel(src) + QDEL_IN(src, 1 SECOND) /obj/item/energy_net/throw_impact(atom/hit_atom) ..() @@ -85,8 +84,7 @@ qdel(src) // If we miss or hit an obstacle, we still want to delete the net. - spawn(10) - if(src) qdel(src) + QDEL_IN(src, 1 SECOND) /obj/effect/energy_net name = "energy net" diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 8adc77ad2e73..46d220be2381 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -979,8 +979,7 @@ var/obj/effect/stop/S S = new /obj/effect/stop(M.loc) S.victim = M - spawn(20) - qdel(S) + QDEL_IN(S, 2 SECONDS) var/turf/floor/T = get_turf(M) if(istype(T)) diff --git a/code/modules/clothing/head/fated_key.dm b/code/modules/clothing/head/fated_key.dm index 24bc19943477..626126d50c93 100644 --- a/code/modules/clothing/head/fated_key.dm +++ b/code/modules/clothing/head/fated_key.dm @@ -113,5 +113,5 @@ animate(src, alpha = 255, time = 3) sleep(13) animate(src, alpha = 0, time = 40) - sleep(40) - qdel(src) + if(!QDELING(src)) + QDEL_IN(src, 4 SECONDS) diff --git a/code/modules/mob/living/human/human_helpers.dm b/code/modules/mob/living/human/human_helpers.dm index 66e9f18001f8..3148393b04e0 100644 --- a/code/modules/mob/living/human/human_helpers.dm +++ b/code/modules/mob/living/human/human_helpers.dm @@ -116,9 +116,8 @@ ping_image.layer = BEAM_PROJECTILE_LAYER ping_image.pixel_x = (T.x - src.x) * WORLD_ICON_SIZE ping_image.pixel_y = (T.y - src.y) * WORLD_ICON_SIZE - show_image(src, ping_image) - spawn(8) - qdel(ping_image) + show_image(src, ping_image) // todo: should this use screen stuff instead? + QDEL_IN(ping_image, 0.8 SECONDS) // qdeling an image is gross but oh well var/feedback = list("There are noises of movement ") var/direction = get_dir(src, L) if(direction) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 37e7095a3c94..2d8c1244d718 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -1065,8 +1065,7 @@ animation.icon_state = "blank" animation.icon = 'icons/mob/mob.dmi' flick("blspell", animation) - sleep(5) - qdel(animation) + QDEL_IN(animation, 0.5 SECONDS) /mob/living/silicon/robot/proc/handle_radio_transmission() if(!is_component_functioning("radio")) diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 2a3ae1574c83..46ce049defb9 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -612,13 +612,7 @@ /obj/item/light/proc/switch_on() switchcount++ if(rigged) - log_and_message_admins("Rigged light explosion, last touched by [fingerprintslast]") - var/turf/T = get_turf(src.loc) - spawn(0) - sleep(2) - explosion(T, 0, 0, 3, 5) - sleep(1) - qdel(src) + addtimer(CALLBACK(src, PROC_REF(do_rigged_explosion)), 0.2 SECONDS) status = LIGHT_BROKEN else if(prob(min(60, switchcount*switchcount*0.01))) status = LIGHT_BURNED @@ -626,6 +620,15 @@ playsound(src, sound_on, 75) return status +/obj/item/light/proc/do_rigged_explosion() + if(!rigged) + return + log_and_message_admins("Rigged light explosion, last touched by [fingerprintslast]") + var/turf/T = get_turf(src) + explosion(T, 0, 0, 3, 5) + if(!QDELETED(src)) + QDEL_IN(src, 1) + /obj/machinery/light/do_simple_ranged_interaction(var/mob/user) if(lightbulb) remove_bulb() diff --git a/code/modules/recycling/disposalpipe.dm b/code/modules/recycling/disposalpipe.dm index e035da8b8254..b1e5ab0afc48 100644 --- a/code/modules/recycling/disposalpipe.dm +++ b/code/modules/recycling/disposalpipe.dm @@ -184,8 +184,7 @@ if(H) expel(H, T, 0) - spawn(2) // delete pipe after 2 ticks to ensure expel proc finished - qdel(src) + QDEL_IN(src, 2) // delete pipe after 2 ticks to ensure expel proc finished // pipe affected by explosion diff --git a/code/modules/vehicles/vehicle.dm b/code/modules/vehicles/vehicle.dm index ce40b54d230c..1098bd2bf01b 100644 --- a/code/modules/vehicles/vehicle.dm +++ b/code/modules/vehicles/vehicle.dm @@ -144,23 +144,17 @@ healthcheck() /obj/vehicle/emp_act(severity) - var/was_on = on + addtimer(CALLBACK(src, PROC_REF(end_emp), on), severity * 30 SECONDS) stat |= EMPED - var/obj/effect/overlay/pulse2 = new /obj/effect/overlay(loc) - pulse2.icon = 'icons/effects/effects.dmi' - pulse2.icon_state = "empdisable" - pulse2.SetName("emp sparks") - pulse2.anchored = TRUE - pulse2.set_dir(pick(global.cardinal)) - - spawn(10) - qdel(pulse2) + var/obj/effect/temp_visual/emp_burst/burst = new /obj/effect/temp_visual/emp_burst(loc) + burst.set_dir(pick(global.cardinal)) if(on) turn_off() - spawn(severity*300) - stat &= ~EMPED - if(was_on) - turn_on() + +/obj/vehicle/proc/end_emp(was_on) + stat &= ~EMPED + if(was_on) + turn_on() /obj/vehicle/attack_ai(mob/living/silicon/ai/user) return diff --git a/mods/content/psionics/system/psionics/equipment/psipower_tk.dm b/mods/content/psionics/system/psionics/equipment/psipower_tk.dm index ee21afaa9077..ee529a0d9226 100644 --- a/mods/content/psionics/system/psionics/equipment/psipower_tk.dm +++ b/mods/content/psionics/system/psionics/equipment/psipower_tk.dm @@ -106,5 +106,4 @@ O.icon = 'icons/effects/effects.dmi' O.icon_state = "nothing" flick("empdisable",O) - sleep(5) - qdel(O) + QDEL_IN(src, 0.5 SECONDS) From 7d8f3b4c719138e69db36d0d756cfd8eadd70441 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 19 Jan 2025 15:17:15 -0500 Subject: [PATCH 082/120] Permit qdeling images --- code/controllers/subsystems/garbage.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/controllers/subsystems/garbage.dm b/code/controllers/subsystems/garbage.dm index 9265525bd7fe..ac728a55ea21 100644 --- a/code/controllers/subsystems/garbage.dm +++ b/code/controllers/subsystems/garbage.dm @@ -279,13 +279,13 @@ SUBSYSTEM_DEF(garbage) qdel(D, force) #endif -// Should be treated as a replacement for the 'del' keyword. -// Datums passed to this will be given a chance to clean up references to allow the GC to collect them. +/// Should be treated as a replacement for the 'del' keyword. +/// Datums passed to this will be given a chance to clean up references to allow the GC to collect them. +/// Non-datums passed to this will be hard-deleted. /proc/qdel(datum/D, force=FALSE) if(isnull(D)) return if(!istype(D)) - PRINT_STACK_TRACE("qdel() can only handle /datum (sub)types, was passed: [log_info_line(D)]") del(D) return var/datum/qdel_item/I = SSgarbage.items[D.type] From 5fd43217d8bef1677a550f3d52440b55be28a224 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 19 Jan 2025 16:20:45 -0500 Subject: [PATCH 083/120] Remove unnecessary trait name check --- code/datums/traits/maluses/amputations.dm | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/datums/traits/maluses/amputations.dm b/code/datums/traits/maluses/amputations.dm index 5cbd3ea7c77e..8ce9bc5d4186 100644 --- a/code/datums/traits/maluses/amputations.dm +++ b/code/datums/traits/maluses/amputations.dm @@ -15,8 +15,6 @@ if(trait_type == type) continue var/decl/trait/malus/amputation/trait = check_traits[trait_type] - if(!trait.name) - continue // remove when abstract decl handling from dev is merged for(var/limb in trait.apply_to_limbs) if(limb in ban_traits_relating_to_limbs) LAZYDISTINCTADD(incompatible_with, trait_type) From 7f9ddfdd175eded70ddbfd46b77299516ffb6f58 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 19 Jan 2025 16:25:56 -0500 Subject: [PATCH 084/120] Make map templates use abstract_type properly --- code/controllers/subsystems/mapping.dm | 2 +- code/modules/maps/_map_template.dm | 3 +-- code/modules/maps/template_types/antag_spawn.dm | 2 +- code/modules/maps/template_types/away_site.dm | 2 +- .../template_types/mapped_planet/mapped_planet_template.dm | 1 - .../template_types/random_exoplanet/planet_types/barren.dm | 1 - .../template_types/random_exoplanet/planet_types/chlorine.dm | 1 - .../template_types/random_exoplanet/planet_types/desert.dm | 1 - .../template_types/random_exoplanet/planet_types/grass.dm | 1 - .../maps/template_types/random_exoplanet/planet_types/meat.dm | 1 - .../template_types/random_exoplanet/planet_types/shrouded.dm | 1 - .../maps/template_types/random_exoplanet/planet_types/snow.dm | 1 - .../template_types/random_exoplanet/planet_types/volcanic.dm | 1 - .../maps/template_types/random_exoplanet/random_exoplanet.dm | 1 - .../maps/template_types/random_exoplanet/random_planet.dm | 1 - code/modules/maps/template_types/ruins.dm | 2 +- code/modules/maps/template_types/ruins_exoplanet.dm | 2 +- maps/random_ruins/space_ruins/space_ruins.dm | 1 + mods/content/fantasy/submaps/_submaps.dm | 1 - mods/content/fantasy/submaps/downlands/_downlands.dm | 2 -- mods/content/fantasy/submaps/grassland/_grassland.dm | 4 +--- mods/content/fantasy/submaps/swamp/_swamp.dm | 3 +-- mods/content/fantasy/submaps/woods/_woods.dm | 1 - 23 files changed, 9 insertions(+), 27 deletions(-) diff --git a/code/controllers/subsystems/mapping.dm b/code/controllers/subsystems/mapping.dm index 6e1061636ec6..f441ba4b3546 100644 --- a/code/controllers/subsystems/mapping.dm +++ b/code/controllers/subsystems/mapping.dm @@ -198,7 +198,7 @@ SUBSYSTEM_DEF(mapping) . = list() for(var/template_type in subtypesof(/datum/map_template)) var/datum/map_template/template = template_type - if(!TYPE_IS_ABSTRACT(template) && initial(template.template_parent_type) != template_type && initial(template.name)) + if(!TYPE_IS_ABSTRACT(template)) . += new template_type(type) // send name as a param to catch people doing illegal ad hoc creation /datum/controller/subsystem/mapping/proc/get_template(var/template_name) diff --git a/code/modules/maps/_map_template.dm b/code/modules/maps/_map_template.dm index c5ae24dc655f..fbeb54f36f19 100644 --- a/code/modules/maps/_map_template.dm +++ b/code/modules/maps/_map_template.dm @@ -1,4 +1,5 @@ /datum/map_template + abstract_type = /datum/map_template ///Name for differentiating templates var/name = "Default Template Name" ///The width of the template's levels. Size is preloaded from template during template registration. @@ -23,8 +24,6 @@ var/modify_tag_vars = TRUE ///List of strings to store the templates under for mass retrieval. var/list/template_categories - ///If this is equal to current type, the datum is abstract and should not be created. - var/template_parent_type = /datum/map_template ///The initial type of level_data to instantiate new z-level with initially. (Is replaced by whatever is in the map file.) If null, will use default. var/level_data_type /// Various tags used for selecting templates for placement on a map. diff --git a/code/modules/maps/template_types/antag_spawn.dm b/code/modules/maps/template_types/antag_spawn.dm index 7c079ead9eb4..8b8b167bd0fd 100644 --- a/code/modules/maps/template_types/antag_spawn.dm +++ b/code/modules/maps/template_types/antag_spawn.dm @@ -1,3 +1,3 @@ /datum/map_template/ruin/antag_spawn prefix = "maps/antag_spawn/" - template_parent_type = /datum/map_template/ruin/antag_spawn + abstract_type = /datum/map_template/ruin/antag_spawn diff --git a/code/modules/maps/template_types/away_site.dm b/code/modules/maps/template_types/away_site.dm index b9adb30914b1..81d77b0152ef 100644 --- a/code/modules/maps/template_types/away_site.dm +++ b/code/modules/maps/template_types/away_site.dm @@ -1,7 +1,7 @@ /datum/map_template/ruin/away_site prefix = "maps/away/" template_categories = list(MAP_TEMPLATE_CATEGORY_AWAYSITE) - template_parent_type = /datum/map_template/ruin/away_site + abstract_type = /datum/map_template/ruin/away_site var/spawn_weight = 1 /datum/map_template/ruin/away_site/get_spawn_weight() diff --git a/code/modules/maps/template_types/mapped_planet/mapped_planet_template.dm b/code/modules/maps/template_types/mapped_planet/mapped_planet_template.dm index 45396ae3baf0..4a7f663352e1 100644 --- a/code/modules/maps/template_types/mapped_planet/mapped_planet_template.dm +++ b/code/modules/maps/template_types/mapped_planet/mapped_planet_template.dm @@ -6,7 +6,6 @@ /datum/map_template/planetoid name = "planetoid" abstract_type = /datum/map_template/planetoid - template_parent_type = /datum/map_template/planetoid template_categories = list(MAP_TEMPLATE_CATEGORY_PLANET) level_data_type = /datum/level_data/planetoid modify_tag_vars = TRUE diff --git a/code/modules/maps/template_types/random_exoplanet/planet_types/barren.dm b/code/modules/maps/template_types/random_exoplanet/planet_types/barren.dm index 27a86377dc88..6de9ef4a6001 100644 --- a/code/modules/maps/template_types/random_exoplanet/planet_types/barren.dm +++ b/code/modules/maps/template_types/random_exoplanet/planet_types/barren.dm @@ -76,7 +76,6 @@ overmap_marker_type = /obj/effect/overmap/visitable/sector/planetoid/exoplanet/barren template_tags_blacklist = TEMPLATE_TAG_HABITAT|TEMPLATE_TAG_WATER subtemplate_budget = 6 - template_parent_type = /datum/map_template/planetoid/random/exoplanet level_data_type = /datum/level_data/planetoid/exoplanet/barren prefered_level_data_per_z = list( /datum/level_data/planetoid/exoplanet/barren, //surface level diff --git a/code/modules/maps/template_types/random_exoplanet/planet_types/chlorine.dm b/code/modules/maps/template_types/random_exoplanet/planet_types/chlorine.dm index c45df0faf7c2..9ec7a8823884 100644 --- a/code/modules/maps/template_types/random_exoplanet/planet_types/chlorine.dm +++ b/code/modules/maps/template_types/random_exoplanet/planet_types/chlorine.dm @@ -87,7 +87,6 @@ planetoid_data_type = /datum/planetoid_data/random/chlorine overmap_marker_type = /obj/effect/overmap/visitable/sector/planetoid/exoplanet/chlorine template_tags_blacklist = TEMPLATE_TAG_HABITAT|TEMPLATE_TAG_WATER - template_parent_type = /datum/map_template/planetoid/random/exoplanet level_data_type = /datum/level_data/planetoid/exoplanet/chlorine prefered_level_data_per_z = list( /datum/level_data/planetoid/exoplanet/chlorine, diff --git a/code/modules/maps/template_types/random_exoplanet/planet_types/desert.dm b/code/modules/maps/template_types/random_exoplanet/planet_types/desert.dm index 93053b6b88e7..098a604152cb 100644 --- a/code/modules/maps/template_types/random_exoplanet/planet_types/desert.dm +++ b/code/modules/maps/template_types/random_exoplanet/planet_types/desert.dm @@ -95,7 +95,6 @@ name = "desert exoplanet" planetoid_data_type = /datum/planetoid_data/random/desert overmap_marker_type = /obj/effect/overmap/visitable/sector/planetoid/exoplanet/desert - template_parent_type = /datum/map_template/planetoid/random/exoplanet level_data_type = /datum/level_data/planetoid/exoplanet/desert prefered_level_data_per_z = list( /datum/level_data/planetoid/exoplanet/desert, diff --git a/code/modules/maps/template_types/random_exoplanet/planet_types/grass.dm b/code/modules/maps/template_types/random_exoplanet/planet_types/grass.dm index f3bc7a90522f..d6ecd767659b 100644 --- a/code/modules/maps/template_types/random_exoplanet/planet_types/grass.dm +++ b/code/modules/maps/template_types/random_exoplanet/planet_types/grass.dm @@ -119,7 +119,6 @@ name = "lush exoplanet" planetoid_data_type = /datum/planetoid_data/random/grass overmap_marker_type = /obj/effect/overmap/visitable/sector/planetoid/exoplanet/grass - template_parent_type = /datum/map_template/planetoid/random/exoplanet level_data_type = /datum/level_data/planetoid/exoplanet/grass prefered_level_data_per_z = list( /datum/level_data/planetoid/exoplanet/grass, diff --git a/code/modules/maps/template_types/random_exoplanet/planet_types/meat.dm b/code/modules/maps/template_types/random_exoplanet/planet_types/meat.dm index 90aaf8dad69f..95ad399b57d1 100644 --- a/code/modules/maps/template_types/random_exoplanet/planet_types/meat.dm +++ b/code/modules/maps/template_types/random_exoplanet/planet_types/meat.dm @@ -91,7 +91,6 @@ planetoid_data_type = /datum/planetoid_data/random/meat overmap_marker_type = /obj/effect/overmap/visitable/sector/planetoid/exoplanet/meat template_tags_blacklist = TEMPLATE_TAG_HABITAT|TEMPLATE_TAG_HUMAN|TEMPLATE_TAG_WATER - template_parent_type = /datum/map_template/planetoid/random/exoplanet level_data_type = /datum/level_data/planetoid/exoplanet/meat prefered_level_data_per_z = null diff --git a/code/modules/maps/template_types/random_exoplanet/planet_types/shrouded.dm b/code/modules/maps/template_types/random_exoplanet/planet_types/shrouded.dm index 07b282eb4da8..5b201f4509da 100644 --- a/code/modules/maps/template_types/random_exoplanet/planet_types/shrouded.dm +++ b/code/modules/maps/template_types/random_exoplanet/planet_types/shrouded.dm @@ -86,7 +86,6 @@ planetoid_data_type = /datum/planetoid_data/random/shrouded overmap_marker_type = /obj/effect/overmap/visitable/sector/planetoid/exoplanet/shrouded template_tags_blacklist = TEMPLATE_TAG_HABITAT - template_parent_type = /datum/map_template/planetoid/random/exoplanet level_data_type = /datum/level_data/planetoid/exoplanet/shrouded prefered_level_data_per_z = list( /datum/level_data/planetoid/exoplanet/shrouded, diff --git a/code/modules/maps/template_types/random_exoplanet/planet_types/snow.dm b/code/modules/maps/template_types/random_exoplanet/planet_types/snow.dm index 6926e0d004db..567c152b7587 100644 --- a/code/modules/maps/template_types/random_exoplanet/planet_types/snow.dm +++ b/code/modules/maps/template_types/random_exoplanet/planet_types/snow.dm @@ -77,7 +77,6 @@ name = "snow exoplanet" planetoid_data_type = /datum/planetoid_data/random/snow overmap_marker_type = /obj/effect/overmap/visitable/sector/planetoid/exoplanet/snow - template_parent_type = /datum/map_template/planetoid/random/exoplanet level_data_type = /datum/level_data/planetoid/exoplanet/snow prefered_level_data_per_z = list( /datum/level_data/planetoid/exoplanet/snow, diff --git a/code/modules/maps/template_types/random_exoplanet/planet_types/volcanic.dm b/code/modules/maps/template_types/random_exoplanet/planet_types/volcanic.dm index a6b669411bbe..fc24c4a289fc 100644 --- a/code/modules/maps/template_types/random_exoplanet/planet_types/volcanic.dm +++ b/code/modules/maps/template_types/random_exoplanet/planet_types/volcanic.dm @@ -92,7 +92,6 @@ overmap_marker_type = /obj/effect/overmap/visitable/sector/planetoid/exoplanet/volcanic max_themes = 1 template_tags_blacklist = TEMPLATE_TAG_HABITAT|TEMPLATE_TAG_WATER - template_parent_type = /datum/map_template/planetoid/random/exoplanet level_data_type = /datum/level_data/planetoid/exoplanet/volcanic prefered_level_data_per_z = list( /datum/level_data/planetoid/exoplanet/volcanic, diff --git a/code/modules/maps/template_types/random_exoplanet/random_exoplanet.dm b/code/modules/maps/template_types/random_exoplanet/random_exoplanet.dm index 8eb2764c4c1b..3cdd8d4a0f37 100644 --- a/code/modules/maps/template_types/random_exoplanet/random_exoplanet.dm +++ b/code/modules/maps/template_types/random_exoplanet/random_exoplanet.dm @@ -2,7 +2,6 @@ /datum/map_template/planetoid/random/exoplanet name = "random exoplanet" abstract_type = /datum/map_template/planetoid/random/exoplanet - template_parent_type = /datum/map_template/planetoid/random/exoplanet template_categories = list(MAP_TEMPLATE_CATEGORY_EXOPLANET) template_category = MAP_TEMPLATE_CATEGORY_EXOPLANET_SITE tallness = 1 diff --git a/code/modules/maps/template_types/random_exoplanet/random_planet.dm b/code/modules/maps/template_types/random_exoplanet/random_planet.dm index 6a8ea018c2af..d19a9ee7625d 100644 --- a/code/modules/maps/template_types/random_exoplanet/random_planet.dm +++ b/code/modules/maps/template_types/random_exoplanet/random_planet.dm @@ -7,7 +7,6 @@ /datum/map_template/planetoid/random name = "random planetoid" abstract_type = /datum/map_template/planetoid/random - template_parent_type = /datum/map_template/planetoid/random modify_tag_vars = TRUE //Would set it to false, since we're generating everything on the fly, but unit test doesn't like it tallness = 1 //Amount of vertical z-levels to generate for this planet. diff --git a/code/modules/maps/template_types/ruins.dm b/code/modules/maps/template_types/ruins.dm index 5c5782ac0a3c..9e26f2c6212a 100644 --- a/code/modules/maps/template_types/ruins.dm +++ b/code/modules/maps/template_types/ruins.dm @@ -1,7 +1,7 @@ /datum/map_template/ruin name = null template_flags = 0 // No duplicates by default - template_parent_type = /datum/map_template/ruin + abstract_type = /datum/map_template/ruin var/description var/cost = 0 var/prefix diff --git a/code/modules/maps/template_types/ruins_exoplanet.dm b/code/modules/maps/template_types/ruins_exoplanet.dm index a0a34f76975c..d6c405132afa 100644 --- a/code/modules/maps/template_types/ruins_exoplanet.dm +++ b/code/modules/maps/template_types/ruins_exoplanet.dm @@ -1,4 +1,4 @@ /datum/map_template/ruin/exoplanet prefix = "maps/random_ruins/exoplanet_ruins/" template_categories = list(MAP_TEMPLATE_CATEGORY_EXOPLANET_SITE) - template_parent_type = /datum/map_template/ruin/exoplanet + abstract_type = /datum/map_template/ruin/exoplanet diff --git a/maps/random_ruins/space_ruins/space_ruins.dm b/maps/random_ruins/space_ruins/space_ruins.dm index 6310e536a7e0..460f5a6995a7 100644 --- a/maps/random_ruins/space_ruins/space_ruins.dm +++ b/maps/random_ruins/space_ruins/space_ruins.dm @@ -5,6 +5,7 @@ material = /decl/material/solid/gemstone/diamond /datum/map_template/ruin/space + abstract_type = /datum/map_template/ruin/space template_categories = list(MAP_TEMPLATE_CATEGORY_SPACE) prefix = "maps/random_ruins/space_ruins/" cost = 1 diff --git a/mods/content/fantasy/submaps/_submaps.dm b/mods/content/fantasy/submaps/_submaps.dm index 71cfb9e98a05..64c03240f4b7 100644 --- a/mods/content/fantasy/submaps/_submaps.dm +++ b/mods/content/fantasy/submaps/_submaps.dm @@ -7,7 +7,6 @@ /datum/map_template/fantasy abstract_type = /datum/map_template/fantasy - template_parent_type = /datum/map_template/fantasy template_flags = TEMPLATE_FLAG_CLEAR_CONTENTS | TEMPLATE_FLAG_NO_RUINS area_usage_test_exempted_root_areas = list( /area/fantasy/outside/point_of_interest diff --git a/mods/content/fantasy/submaps/downlands/_downlands.dm b/mods/content/fantasy/submaps/downlands/_downlands.dm index c97d04705d06..5086d54dc545 100644 --- a/mods/content/fantasy/submaps/downlands/_downlands.dm +++ b/mods/content/fantasy/submaps/downlands/_downlands.dm @@ -1,9 +1,7 @@ /datum/map_template/fantasy/downlands abstract_type = /datum/map_template/fantasy/downlands template_categories = list(MAP_TEMPLATE_CATEGORY_FANTASY_DOWNLANDS) - template_parent_type = /datum/map_template/fantasy/downlands /datum/map_template/fantasy/dungeon abstract_type = /datum/map_template/fantasy/dungeon template_categories = list(MAP_TEMPLATE_CATEGORY_FANTASY_DUNGEON) - template_parent_type = /datum/map_template/fantasy/dungeon diff --git a/mods/content/fantasy/submaps/grassland/_grassland.dm b/mods/content/fantasy/submaps/grassland/_grassland.dm index 57fcd595c5f3..19b70b9367f0 100644 --- a/mods/content/fantasy/submaps/grassland/_grassland.dm +++ b/mods/content/fantasy/submaps/grassland/_grassland.dm @@ -1,9 +1,7 @@ /datum/map_template/fantasy/grassland abstract_type = /datum/map_template/fantasy/grassland template_categories = list(MAP_TEMPLATE_CATEGORY_FANTASY_GRASSLAND) - template_parent_type = /datum/map_template/fantasy/grassland /datum/map_template/fantasy/cavern abstract_type = /datum/map_template/fantasy/cavern - template_categories = list(MAP_TEMPLATE_CATEGORY_FANTASY_CAVERNS) - template_parent_type = /datum/map_template/fantasy/cavern \ No newline at end of file + template_categories = list(MAP_TEMPLATE_CATEGORY_FANTASY_CAVERNS) \ No newline at end of file diff --git a/mods/content/fantasy/submaps/swamp/_swamp.dm b/mods/content/fantasy/submaps/swamp/_swamp.dm index 60ece589b4af..6a3c2054ea9a 100644 --- a/mods/content/fantasy/submaps/swamp/_swamp.dm +++ b/mods/content/fantasy/submaps/swamp/_swamp.dm @@ -1,4 +1,3 @@ /datum/map_template/fantasy/swamp abstract_type = /datum/map_template/fantasy/swamp - template_categories = list(MAP_TEMPLATE_CATEGORY_FANTASY_SWAMP) - template_parent_type = /datum/map_template/fantasy/swamp \ No newline at end of file + template_categories = list(MAP_TEMPLATE_CATEGORY_FANTASY_SWAMP) \ No newline at end of file diff --git a/mods/content/fantasy/submaps/woods/_woods.dm b/mods/content/fantasy/submaps/woods/_woods.dm index 657ce2c6b269..dc1429ef5592 100644 --- a/mods/content/fantasy/submaps/woods/_woods.dm +++ b/mods/content/fantasy/submaps/woods/_woods.dm @@ -1,4 +1,3 @@ /datum/map_template/fantasy/woods abstract_type = /datum/map_template/fantasy/woods template_categories = list(MAP_TEMPLATE_CATEGORY_FANTASY_WOODS) - template_parent_type = /datum/map_template/fantasy/woods From b68c097703eb5142f3fdaa3878ec3eba5dc5bd84 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 19 Jan 2025 16:27:30 -0500 Subject: [PATCH 085/120] Make shuttles use abstract_type --- code/controllers/subsystems/shuttle.dm | 15 ++++++++------- code/modules/overmap/overmap_shuttle.dm | 2 +- code/modules/shuttles/escape_pods.dm | 2 +- code/modules/shuttles/shuttle.dm | 2 +- code/modules/shuttles/shuttle_autodock.dm | 2 +- code/modules/shuttles/shuttle_emergency.dm | 2 +- code/modules/shuttles/shuttle_ferry.dm | 2 +- code/modules/shuttles/shuttle_specops.dm | 5 +---- code/modules/shuttles/shuttle_supply.dm | 2 +- code/modules/shuttles/shuttles_multi.dm | 4 ++-- 10 files changed, 18 insertions(+), 20 deletions(-) diff --git a/code/controllers/subsystems/shuttle.dm b/code/controllers/subsystems/shuttle.dm index 7c6b1a077114..77f0d4083cb2 100644 --- a/code/controllers/subsystems/shuttle.dm +++ b/code/controllers/subsystems/shuttle.dm @@ -125,13 +125,14 @@ SUBSYSTEM_DEF(shuttle) /datum/controller/subsystem/shuttle/proc/initialize_shuttle(var/shuttle_type, var/map_hash, var/list/add_args) var/datum/shuttle/shuttle = shuttle_type - if(initial(shuttle.category) != shuttle_type) - var/list/shuttle_args = list(map_hash) - if(length(add_args)) - shuttle_args += add_args - shuttle = new shuttle(arglist(shuttle_args)) - shuttle_areas |= shuttle.shuttle_area - return shuttle + if(TYPE_IS_ABSTRACT(shuttle)) + return null + var/list/shuttle_args = list(map_hash) + if(length(add_args)) + shuttle_args += add_args + shuttle = new shuttle(arglist(shuttle_args)) + shuttle_areas |= shuttle.shuttle_area + return shuttle /datum/controller/subsystem/shuttle/proc/hook_up_motherships(shuttles_list) for(var/datum/shuttle/S in shuttles_list) diff --git a/code/modules/overmap/overmap_shuttle.dm b/code/modules/overmap/overmap_shuttle.dm index 408db04970a3..2a7e5b3fb646 100644 --- a/code/modules/overmap/overmap_shuttle.dm +++ b/code/modules/overmap/overmap_shuttle.dm @@ -7,7 +7,7 @@ var/fuel_consumption = 0 //Amount of moles of gas consumed per trip; If zero, then shuttle is magic and does not need fuel var/list/obj/structure/fuel_port/fuel_ports //the fuel ports of the shuttle (but usually just one) - category = /datum/shuttle/autodock/overmap + abstract_type = /datum/shuttle/autodock/overmap var/skill_needed = SKILL_BASIC var/landing_skill_needed = SKILL_EXPERT var/operator_skill = SKILL_MIN diff --git a/code/modules/shuttles/escape_pods.dm b/code/modules/shuttles/escape_pods.dm index c12dc6e38d90..bd13d30c417b 100644 --- a/code/modules/shuttles/escape_pods.dm +++ b/code/modules/shuttles/escape_pods.dm @@ -3,7 +3,7 @@ var/global/list/escape_pods_by_name = list() /datum/shuttle/autodock/ferry/escape_pod var/datum/computer/file/embedded_program/docking/simple/escape_pod_berth/arming_controller - category = /datum/shuttle/autodock/ferry/escape_pod + abstract_type = /datum/shuttle/autodock/ferry/escape_pod move_time = 100 /datum/shuttle/autodock/ferry/escape_pod/New(map_hash) diff --git a/code/modules/shuttles/shuttle.dm b/code/modules/shuttles/shuttle.dm index 794f0736f127..85ee565817b5 100644 --- a/code/modules/shuttles/shuttle.dm +++ b/code/modules/shuttles/shuttle.dm @@ -12,7 +12,7 @@ var/arrive_time = 0 //the time at which the shuttle arrives when long jumping var/flags = 0 var/process_state = IDLE_STATE //Used with SHUTTLE_FLAGS_PROCESS, as well as to store current state. - var/category = /datum/shuttle + abstract_type = /datum/shuttle var/multiz = 0 //how many multiz levels, starts at 0 var/ceiling_type = /turf/unsimulated/floor/shuttle_ceiling diff --git a/code/modules/shuttles/shuttle_autodock.dm b/code/modules/shuttles/shuttle_autodock.dm index 74c157df8fed..f2003eb0129d 100644 --- a/code/modules/shuttles/shuttle_autodock.dm +++ b/code/modules/shuttles/shuttle_autodock.dm @@ -16,7 +16,7 @@ var/obj/effect/shuttle_landmark/landmark_transition //This variable is type-abused initially: specify the landmark_tag, not the actual landmark. var/move_time = 240 //the time spent in the transition area - category = /datum/shuttle/autodock + abstract_type = /datum/shuttle/autodock flags = SHUTTLE_FLAGS_PROCESS | SHUTTLE_FLAGS_ZERO_G /datum/shuttle/autodock/New(var/map_hash, var/obj/effect/shuttle_landmark/start_waypoint) diff --git a/code/modules/shuttles/shuttle_emergency.dm b/code/modules/shuttles/shuttle_emergency.dm index 2bdc11d22846..f6efaa4a8645 100644 --- a/code/modules/shuttles/shuttle_emergency.dm +++ b/code/modules/shuttles/shuttle_emergency.dm @@ -1,5 +1,5 @@ /datum/shuttle/autodock/ferry/emergency - category = /datum/shuttle/autodock/ferry/emergency + abstract_type = /datum/shuttle/autodock/ferry/emergency move_time = 10 MINUTES flags = SHUTTLE_FLAGS_PROCESS | SHUTTLE_FLAGS_ZERO_G | SHUTTLE_FLAGS_NO_CODE var/datum/evacuation_controller/shuttle/emergency_controller diff --git a/code/modules/shuttles/shuttle_ferry.dm b/code/modules/shuttles/shuttle_ferry.dm index 4f23361de2b3..ebe0a7cf54f6 100644 --- a/code/modules/shuttles/shuttle_ferry.dm +++ b/code/modules/shuttles/shuttle_ferry.dm @@ -7,7 +7,7 @@ var/obj/effect/shuttle_landmark/waypoint_station //This variable is type-abused initially: specify the landmark_tag, not the actual landmark. var/obj/effect/shuttle_landmark/waypoint_offsite //This variable is type-abused initially: specify the landmark_tag, not the actual landmark. - category = /datum/shuttle/autodock/ferry + abstract_type = /datum/shuttle/autodock/ferry /datum/shuttle/autodock/ferry/New(map_hash) if(map_hash) diff --git a/code/modules/shuttles/shuttle_specops.dm b/code/modules/shuttles/shuttle_specops.dm index 41778075e990..cd3e55c4fdb5 100644 --- a/code/modules/shuttles/shuttle_specops.dm +++ b/code/modules/shuttles/shuttle_specops.dm @@ -14,10 +14,7 @@ var/reset_time = 0 //the world.time at which the shuttle will be ready to move again. var/launch_prep = 0 var/cancel_countdown = 0 - category = /datum/shuttle/autodock/ferry/specops - -/datum/shuttle/autodock/ferry/specops/New() - ..() + abstract_type = /datum/shuttle/autodock/ferry/specops /datum/shuttle/autodock/ferry/specops/launch(var/user) if (!can_launch()) diff --git a/code/modules/shuttles/shuttle_supply.dm b/code/modules/shuttles/shuttle_supply.dm index 175924860dcb..f38e5fef5b31 100644 --- a/code/modules/shuttles/shuttle_supply.dm +++ b/code/modules/shuttles/shuttle_supply.dm @@ -3,7 +3,7 @@ var/late_chance = 80 var/max_late_time = (30 SECONDS) flags = SHUTTLE_FLAGS_PROCESS|SHUTTLE_FLAGS_SUPPLY|SHUTTLE_FLAGS_NO_CODE - category = /datum/shuttle/autodock/ferry/supply + abstract_type = /datum/shuttle/autodock/ferry/supply ceiling_type = /turf/floor/shuttle_ceiling /datum/shuttle/autodock/ferry/supply/short_jump(var/area/destination) diff --git a/code/modules/shuttles/shuttles_multi.dm b/code/modules/shuttles/shuttles_multi.dm index 35e00c68be6d..71e144e02e27 100644 --- a/code/modules/shuttles/shuttles_multi.dm +++ b/code/modules/shuttles/shuttles_multi.dm @@ -2,7 +2,7 @@ var/list/destination_tags var/list/destinations_cache = list() var/last_cache_rebuild_time = 0 - category = /datum/shuttle/autodock/multi + abstract_type = /datum/shuttle/autodock/multi /datum/shuttle/autodock/multi/New(map_hash) ..() @@ -42,7 +42,7 @@ var/arrival_message var/departure_message - category = /datum/shuttle/autodock/multi/antag + abstract_type = /datum/shuttle/autodock/multi/antag /datum/shuttle/autodock/multi/antag/New(map_hash) ..() From 48a49c75295a2cac95cb891a08263a0478b95ae8 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 19 Jan 2025 16:28:04 -0500 Subject: [PATCH 086/120] Make attack filters datums --- .../secrets/investigation/attack_logs.dm | 57 +++++++++---------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/code/modules/admin/secrets/investigation/attack_logs.dm b/code/modules/admin/secrets/investigation/attack_logs.dm index 201adaa00bf7..5a915fd379c7 100644 --- a/code/modules/admin/secrets/investigation/attack_logs.dm +++ b/code/modules/admin/secrets/investigation/attack_logs.dm @@ -69,9 +69,8 @@ . = filters_per_client[user.client] if(!.) . = list() - for(var/af_type in subtypesof(/attack_filter)) - var/attack_filter/af = af_type - if(initial(af.category) == af_type) + for(var/datum/attack_filter/af_type as anything in subtypesof(/datum/attack_filter)) + if(TYPE_IS_ABSTRACT(af_type)) continue . += new af_type(src) filters_per_client[user.client] = . @@ -79,56 +78,56 @@ /datum/admin_secret_item/investigation/attack_logs/proc/get_filter_html(user) . = list() for(var/filter in get_user_filters(user)) - var/attack_filter/af = filter + var/datum/attack_filter/af = filter . += af.get_html() . = jointext(.," | ") /datum/admin_secret_item/investigation/attack_logs/proc/filter_log(user, var/datum/attack_log/al) for(var/filter in get_user_filters(user)) - var/attack_filter/af = filter + var/datum/attack_filter/af = filter if(af.filter_attack(al)) return TRUE return FALSE /datum/admin_secret_item/investigation/attack_logs/proc/reset_user_filters(user) for(var/filter in get_user_filters(user)) - var/attack_filter/af = filter + var/datum/attack_filter/af = filter af.reset() -/attack_filter - var/category = /attack_filter +/datum/attack_filter + abstract_type = /datum/attack_filter var/datum/admin_secret_item/investigation/attack_logs/holder -/attack_filter/New(var/holder) +/datum/attack_filter/New(var/holder) ..() src.holder = holder -/attack_filter/Topic(href, href_list) +/datum/attack_filter/Topic(href, href_list) if(..()) return TRUE if(OnTopic(href_list)) holder.execute(usr) return TRUE -/attack_filter/proc/get_html() +/datum/attack_filter/proc/get_html() return -/attack_filter/proc/reset() +/datum/attack_filter/proc/reset() return -/attack_filter/proc/filter_attack(var/datum/attack_log/al) +/datum/attack_filter/proc/filter_attack(var/datum/attack_log/al) return FALSE -/attack_filter/proc/OnTopic(href_list) +/datum/attack_filter/proc/OnTopic(href_list) return FALSE /* * Filter logs with one or more missing clients */ -/attack_filter/no_client +/datum/attack_filter/no_client var/filter_missing_clients = TRUE -/attack_filter/no_client/get_html() +/datum/attack_filter/no_client/get_html() . = list() . += "Must have clients: " if(filter_missing_clients) @@ -137,7 +136,7 @@ . += "YesNo" . = jointext(.,null) -/attack_filter/no_client/OnTopic(href_list) +/datum/attack_filter/no_client/OnTopic(href_list) if(href_list["yes"] && !filter_missing_clients) filter_missing_clients = TRUE return TRUE @@ -145,10 +144,10 @@ filter_missing_clients = FALSE return TRUE -/attack_filter/no_client/reset() +/datum/attack_filter/no_client/reset() filter_missing_clients = initial(filter_missing_clients) -/attack_filter/no_client/filter_attack(var/datum/attack_log/al) +/datum/attack_filter/no_client/filter_attack(var/datum/attack_log/al) if(!filter_missing_clients) return FALSE if(al.attacker && al.attacker.client.ckey == NO_CLIENT_CKEY) @@ -160,19 +159,19 @@ /* Either subject must be the selected client */ -/attack_filter/must_be_given_ckey +/datum/attack_filter/must_be_given_ckey var/ckey_filter var/check_attacker = TRUE var/check_victim = TRUE var/description = "Either ckey is" -/attack_filter/must_be_given_ckey/reset() +/datum/attack_filter/must_be_given_ckey/reset() ckey_filter = null -/attack_filter/must_be_given_ckey/get_html() +/datum/attack_filter/must_be_given_ckey/get_html() return "[description]: [ckey_filter ? ckey_filter : "*ANY*"]" -/attack_filter/must_be_given_ckey/OnTopic(href_list) +/datum/attack_filter/must_be_given_ckey/OnTopic(href_list) if(!href_list["select_ckey"]) return var/ckey = input("Select ckey to filter on","Select ckey", ckey_filter) as null|anything in get_ckeys() @@ -183,7 +182,7 @@ ckey_filter = ckey return TRUE -/attack_filter/must_be_given_ckey/proc/get_ckeys() +/datum/attack_filter/must_be_given_ckey/proc/get_ckeys() . = list() for(var/log in attack_log_repository.attack_logs_) var/datum/attack_log/al = log @@ -194,7 +193,7 @@ . = sortTim(., /proc/cmp_text_asc) . += "*ANY*" -/attack_filter/must_be_given_ckey/filter_attack(var/datum/attack_log/al) +/datum/attack_filter/must_be_given_ckey/filter_attack(var/datum/attack_log/al) if(!ckey_filter) return FALSE if(check_attacker && al.attacker && al.attacker.client.ckey == ckey_filter) @@ -206,19 +205,19 @@ /* Attacker must be the selected client */ -/attack_filter/must_be_given_ckey/attacker +/datum/attack_filter/must_be_given_ckey/attacker description = "Attacker ckey is" check_victim = FALSE -/attack_filter/must_be_given_ckey/attacker/filter_attack(al) +/datum/attack_filter/must_be_given_ckey/attacker/filter_attack(al) return ..(al, TRUE, FALSE) /* Victim must be the selected client */ -/attack_filter/must_be_given_ckey/victim +/datum/attack_filter/must_be_given_ckey/victim description = "Victim ckey is" check_attacker = FALSE -/attack_filter/must_be_given_ckey/victim/filter_attack(al) +/datum/attack_filter/must_be_given_ckey/victim/filter_attack(al) return ..(al, FALSE, TRUE) From b821f4c5dda2837edb4aa253cfde1c0b5fec720d Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 19 Jan 2025 16:28:18 -0500 Subject: [PATCH 087/120] Make prometheus metrics use decls --- code/game/world_topic_commands.dm | 5 ++-- .../prometheus_metrics/metric_family.dm | 10 ++++---- code/modules/prometheus_metrics/metrics.dm | 23 ++++++------------- .../prometheus_metrics/metrics/byond.dm | 16 ++++++------- .../prometheus_metrics/metrics/ss13.dm | 20 ++++++++-------- 5 files changed, 32 insertions(+), 42 deletions(-) diff --git a/code/game/world_topic_commands.dm b/code/game/world_topic_commands.dm index 2bbc05f14361..cfd86601053b 100644 --- a/code/game/world_topic_commands.dm +++ b/code/game/world_topic_commands.dm @@ -356,6 +356,5 @@ uid = "topic_command_prometheus_metrics" /decl/topic_command/secure/prometheus_metrics/use() - if(!global.prometheus_metrics) - return "Metrics not ready" - return global.prometheus_metrics.collect() + var/static/decl/prometheus_metrics/prometheus_metrics = IMPLIED_DECL + return prometheus_metrics.collect() diff --git a/code/modules/prometheus_metrics/metric_family.dm b/code/modules/prometheus_metrics/metric_family.dm index 373130e297a4..0054e97a257e 100644 --- a/code/modules/prometheus_metrics/metric_family.dm +++ b/code/modules/prometheus_metrics/metric_family.dm @@ -1,11 +1,11 @@ // Datum used for gathering a set of prometheus metrics. -/datum/metric_family +/decl/metric_family var/name = null var/metric_type = null var/help = null // Collect should return a list of lists with two entries, one being a list and the other being a number. -/datum/metric_family/proc/collect() +/decl/metric_family/proc/collect() var/list/out = list() out[++out.len] = list(list("foo" = "bar"), 3.14) @@ -15,9 +15,9 @@ // _to_proto will call the collect() method and format its result in a list // suitable for encoding as a JSON protobuf mapping. -/datum/metric_family/proc/_to_proto() +/decl/metric_family/proc/_to_proto() var/list/collected = collect() - + var/list/out = list( "name" = name, "type" = metric_type, @@ -36,7 +36,7 @@ label_pairs[++label_pairs.len] = list("name" = k, "value" = m[1][k]) metrics[++metrics.len] = list("label" = label_pairs, PROMETHEUS_METRIC_NAME(metric_type) = list("value" = m[2])) - + if(metrics.len == 0) return null out["metric"] = metrics diff --git a/code/modules/prometheus_metrics/metrics.dm b/code/modules/prometheus_metrics/metrics.dm index 95e2f8190027..ad98b6c178f9 100644 --- a/code/modules/prometheus_metrics/metrics.dm +++ b/code/modules/prometheus_metrics/metrics.dm @@ -1,24 +1,15 @@ -var/global/datum/prometheus_metrics/prometheus_metrics = new - // prometheus_metrics holds a list of metric_family datums and uses them to // create a json protobuf. -/datum/prometheus_metrics +/decl/prometheus_metrics var/list/metric_families -/datum/prometheus_metrics/New() - metric_families = list() - for(var/T in subtypesof(/datum/metric_family)) - var/datum/metric_family/mf = T - if(initial(mf.name) == null || initial(mf.metric_type) == null) - continue - metric_families += new T - -/datum/prometheus_metrics/proc/collect() +/decl/prometheus_metrics/proc/collect() var/list/out = list() - for(var/datum/metric_family/MF in metric_families) - var/proto = MF._to_proto() + for(var/decl/metric_family/metric_family in decls_repository.get_decls_of_type_unassociated(/decl/metric_family)) + var/proto = metric_family._to_proto() if(proto != null) - out[++out.len] = MF._to_proto() - + // out += proto will try to merge the lists, we have to insert it at the end instead + out[++out.len] = proto + return json_encode(out) diff --git a/code/modules/prometheus_metrics/metrics/byond.dm b/code/modules/prometheus_metrics/metrics/byond.dm index 232bce38fafe..3aa58ba942d3 100644 --- a/code/modules/prometheus_metrics/metrics/byond.dm +++ b/code/modules/prometheus_metrics/metrics/byond.dm @@ -1,29 +1,29 @@ // byond-specific metrics -/datum/metric_family/byond_time +/decl/metric_family/byond_time name = "byond_world_time_seconds" metric_type = PROMETHEUS_METRIC_COUNTER help = "Counter of 'game-time' seconds since server startup" -/datum/metric_family/byond_time/collect() +/decl/metric_family/byond_time/collect() return list(list(null, world.time / 10)) -/datum/metric_family/byond_tick_lag +/decl/metric_family/byond_tick_lag name = "byond_tick_lag" metric_type = PROMETHEUS_METRIC_GAUGE help = "Current value of world.tick_lag" -/datum/metric_family/byond_tick_lag/collect() +/decl/metric_family/byond_tick_lag/collect() return list(list(null, world.tick_lag)) -/datum/metric_family/byond_players +/decl/metric_family/byond_players name = "byond_players" metric_type = PROMETHEUS_METRIC_GAUGE help = "Number of players currently connected to the server" -/datum/metric_family/byond_players/collect() +/decl/metric_family/byond_players/collect() var/c = 0 for(var/client/C) if(C.connection == "seeker" || C.connection == "web") @@ -31,10 +31,10 @@ return list(list(null, c)) -/datum/metric_family/byond_cpu +/decl/metric_family/byond_cpu name = "byond_cpu" metric_type = PROMETHEUS_METRIC_GAUGE help = "Current value of world.cpu" -/datum/metric_family/byond_cpu/collect() +/decl/metric_family/byond_cpu/collect() return list(list(null, world.cpu)) diff --git a/code/modules/prometheus_metrics/metrics/ss13.dm b/code/modules/prometheus_metrics/metrics/ss13.dm index 5c6d315b04d0..f686f1d1bed7 100644 --- a/code/modules/prometheus_metrics/metrics/ss13.dm +++ b/code/modules/prometheus_metrics/metrics/ss13.dm @@ -1,11 +1,11 @@ // ss13-specific metrics -/datum/metric_family/ss13_controller_time_seconds +/decl/metric_family/ss13_controller_time_seconds name = "ss13_controller_time_seconds" metric_type = PROMETHEUS_METRIC_COUNTER help = "Counter of time spent in a controller in seconds" -/datum/metric_family/ss13_controller_time_seconds/collect() +/decl/metric_family/ss13_controller_time_seconds/collect() var/list/out = list() if(Master) for(var/name in Master.total_run_times) @@ -14,23 +14,23 @@ return out -/datum/metric_family/ss13_master_runlevel +/decl/metric_family/ss13_master_runlevel name = "ss13_master_runlevel" metric_type = PROMETHEUS_METRIC_GAUGE help = "Current MC runlevel" -/datum/metric_family/ss13_master_runlevel/collect() +/decl/metric_family/ss13_master_runlevel/collect() if(Master) return list(list(null, Master.current_runlevel)) return list() -/datum/metric_family/ss13_garbage_queue_length +/decl/metric_family/ss13_garbage_queue_length name = "ss13_garbage_queue_length" metric_type = PROMETHEUS_METRIC_GAUGE help = "Length of SSgarbage queues" -/datum/metric_family/ss13_garbage_queue_length/collect() +/decl/metric_family/ss13_garbage_queue_length/collect() var/list/out = list() if(SSgarbage) @@ -40,12 +40,12 @@ return out -/datum/metric_family/ss13_garbage_queue_results +/decl/metric_family/ss13_garbage_queue_results name = "ss13_garbage_queue_results" metric_type = PROMETHEUS_METRIC_COUNTER help = "Counter of pass/fail results for SSgarbage queues" -/datum/metric_family/ss13_garbage_queue_results/collect() +/decl/metric_family/ss13_garbage_queue_results/collect() var/list/out = list() if(SSgarbage) @@ -56,12 +56,12 @@ return out -/datum/metric_family/ss13_garbage_total_cleaned +/decl/metric_family/ss13_garbage_total_cleaned name = "ss13_garbage_total_cleaned" metric_type = PROMETHEUS_METRIC_COUNTER help = "Counter for number of objects deleted/GCed by SSgarbage" -/datum/metric_family/ss13_garbage_total_cleaned/collect() +/decl/metric_family/ss13_garbage_total_cleaned/collect() var/list/out = list() if(SSgarbage) From 29d6f430e907bbeacefd0012743e8afdd9a89569 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 19 Jan 2025 16:28:59 -0500 Subject: [PATCH 088/120] Make ailments use abstract_type --- code/modules/admin/view_variables/topic.dm | 4 ++-- code/modules/organs/ailments/_ailment.dm | 3 +-- code/modules/organs/ailments/ailment_codex.dm | 2 +- code/modules/organs/ailments/ailments_medical.dm | 2 +- code/modules/organs/ailments/faults/_fault.dm | 2 +- code/modules/organs/organ.dm | 6 ++++-- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/code/modules/admin/view_variables/topic.dm b/code/modules/admin/view_variables/topic.dm index 09d5d1cc8c14..971e7a394bcd 100644 --- a/code/modules/admin/view_variables/topic.dm +++ b/code/modules/admin/view_variables/topic.dm @@ -290,8 +290,8 @@ return var/list/possible_ailments = list() for(var/atype in subtypesof(/datum/ailment)) - var/datum/ailment/ailment = get_ailment_reference(atype) - if(ailment && ailment.category != ailment.type && ailment.can_apply_to(limb)) + var/datum/ailment/ailment = get_ailment_reference(atype) // will not get abstract ailments + if(ailment && ailment.can_apply_to(limb)) possible_ailments |= ailment var/datum/ailment/ailment = input("Select an ailment type to add.", "Add Ailment") as null|anything in possible_ailments diff --git a/code/modules/organs/ailments/_ailment.dm b/code/modules/organs/ailments/_ailment.dm index 7bcc0c24da64..713dfcdc7aab 100644 --- a/code/modules/organs/ailments/_ailment.dm +++ b/code/modules/organs/ailments/_ailment.dm @@ -1,10 +1,9 @@ /datum/ailment + abstract_type = /datum/ailment var/name // Descriptive name, primarily used for adminbus. var/timer_id // Current timer waiting to proc next symptom message. var/min_time = 2 MINUTES // Minimum time between symptom messages. var/max_time = 5 MINUTES // Maximum time between symptom messages. - var/category = /datum/ailment // Used similar to hierarchies, if category == type then the - // ailment is a category and won't be applied to organs. var/obj/item/organ/organ // Organ associated with the ailment (ailment is in organ.ailments list). // Requirements before applying to a target. diff --git a/code/modules/organs/ailments/ailment_codex.dm b/code/modules/organs/ailments/ailment_codex.dm index 40cc20eb341d..566446dd17ef 100644 --- a/code/modules/organs/ailments/ailment_codex.dm +++ b/code/modules/organs/ailments/ailment_codex.dm @@ -40,7 +40,7 @@ ailment_table += "[name_column][treatment_column]" for(var/atype in subtypesof(/datum/ailment)) var/datum/ailment/ailment = get_ailment_reference(atype) - if(!ailment.name || show_robotics_recipes != ailment.applies_to_prosthetics || ailment.hidden_from_codex) + if(!ailment || show_robotics_recipes != ailment.applies_to_prosthetics || ailment.hidden_from_codex) continue ailment_table += "[ailment.name]" var/list/ailment_cures = list() diff --git a/code/modules/organs/ailments/ailments_medical.dm b/code/modules/organs/ailments/ailments_medical.dm index 4cf930ac0f95..c9d3dad97511 100644 --- a/code/modules/organs/ailments/ailments_medical.dm +++ b/code/modules/organs/ailments/ailments_medical.dm @@ -1,5 +1,5 @@ /datum/ailment/head - category = /datum/ailment/head + abstract_type = /datum/ailment/head applies_to_organ = list(BP_HEAD) /datum/ailment/head/headache diff --git a/code/modules/organs/ailments/faults/_fault.dm b/code/modules/organs/ailments/faults/_fault.dm index 8219540a8dc1..52a9b747a84e 100644 --- a/code/modules/organs/ailments/faults/_fault.dm +++ b/code/modules/organs/ailments/faults/_fault.dm @@ -1,7 +1,7 @@ /datum/ailment/fault applies_to_robotics = TRUE applies_to_prosthetics = TRUE - category = /datum/ailment/fault + abstract_type = /datum/ailment/fault treated_by_item_type = list( /obj/item/stack/nanopaste, /obj/item/stack/tape_roll/duct_tape diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index 92bcc2d8ed77..36d6a3ac5317 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -482,9 +482,11 @@ return var/global/list/ailment_reference_cache = list() -/proc/get_ailment_reference(var/ailment_type) +/proc/get_ailment_reference(var/datum/ailment/ailment_type) if(!ispath(ailment_type, /datum/ailment)) return + if(TYPE_IS_ABSTRACT(ailment_type)) + return if(!global.ailment_reference_cache[ailment_type]) global.ailment_reference_cache[ailment_type] = new ailment_type return global.ailment_reference_cache[ailment_type] @@ -495,7 +497,7 @@ var/global/list/ailment_reference_cache = list() return . for(var/ailment_type in subtypesof(/datum/ailment)) var/datum/ailment/ailment = ailment_type - if(initial(ailment.category) == ailment_type) + if(TYPE_IS_ABSTRACT(ailment)) continue ailment = get_ailment_reference(ailment_type) if(ailment.can_apply_to(src)) From 0f70602e8f182e00b49d1d6de61263621d3182fb Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 19 Jan 2025 16:30:14 -0500 Subject: [PATCH 089/120] Adjust some old comments --- code/modules/admin/view_variables/helpers.dm | 4 +--- code/modules/power/cell.dm | 3 ++- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/code/modules/admin/view_variables/helpers.dm b/code/modules/admin/view_variables/helpers.dm index 959b1b0c0119..2a1f96ecaa59 100644 --- a/code/modules/admin/view_variables/helpers.dm +++ b/code/modules/admin/view_variables/helpers.dm @@ -1,6 +1,4 @@ - -// Keep these two together, they *must* be defined on both -// If /client ever becomes /datum/client or similar, they can be merged +// If /client/var/parent_type ever stops being /datum, this proc will need to be redefined on client. /datum/proc/get_view_variables_header() return "[src]" diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index 48abeb8383a3..a60fab7f939a 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -85,7 +85,8 @@ to_chat(user, "The charge meter reads [round(src.percent(), 0.1)]%.") /obj/item/cell/emp_act(severity) - //remove this once emp changes on dev are merged in + // remove this if EMPs are ever rebalanced so that they don't instantly drain borg cells + // todo: containers (partially) shielding contents? if(isrobot(loc)) var/mob/living/silicon/robot/R = loc severity *= R.cell_emp_mult From ef8271eede77f1718c3ef45de6f155df5a18c865 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 19 Jan 2025 16:32:48 -0500 Subject: [PATCH 090/120] Make unit tests use abstract types --- code/unit_tests/_template.dm | 4 ++-- code/unit_tests/atmospherics_tests.dm | 4 ++-- code/unit_tests/chemistry_tests.dm | 2 +- code/unit_tests/equipment_tests.dm | 2 +- code/unit_tests/extension_tests.dm | 2 +- code/unit_tests/foundation_tests.dm | 2 +- code/unit_tests/graph_tests.dm | 2 +- code/unit_tests/icon_tests.dm | 2 +- code/unit_tests/integrated_circuits.dm | 4 ++-- code/unit_tests/mob_tests.dm | 2 +- code/unit_tests/movement_tests.dm | 2 +- code/unit_tests/observation_tests.dm | 2 +- code/unit_tests/override_tests.dm | 2 +- code/unit_tests/proximity_tests.dm | 4 ++-- code/unit_tests/time_tests.dm | 2 +- code/unit_tests/unit_test.dm | 11 +++++------ code/unit_tests/virtual_mob_tests.dm | 4 ++-- code/unit_tests/zas_tests.dm | 2 +- mods/species/vox/datum/unit_testing.dm | 2 +- 19 files changed, 28 insertions(+), 29 deletions(-) diff --git a/code/unit_tests/_template.dm b/code/unit_tests/_template.dm index 556941cb1ce5..36dc0ddfa189 100644 --- a/code/unit_tests/_template.dm +++ b/code/unit_tests/_template.dm @@ -7,8 +7,8 @@ /datum/unit_test/template name = "Test Template - Change My name" - template = /datum/unit_test/template // Set this var equal to the test path to treat it as a template, i.e. it should not be run - async = 1 // Set if we should continue testing elsewhere and come back and check on the results. + abstract_type = /datum/unit_test/template // Set this var equal to the test path to treat it as a template, i.e. it should not be run + async = 1 // Set if we should continue testing elsewhere and come back and check on the results. /datum/unit_test/template/start_test() diff --git a/code/unit_tests/atmospherics_tests.dm b/code/unit_tests/atmospherics_tests.dm index 5a9c69c15cf1..46837d818bf5 100644 --- a/code/unit_tests/atmospherics_tests.dm +++ b/code/unit_tests/atmospherics_tests.dm @@ -2,7 +2,7 @@ Unit tests for ATMOSPHERICS primitives */ /datum/unit_test/atmos_machinery - template = /datum/unit_test/atmos_machinery + abstract_type = /datum/unit_test/atmos_machinery var/list/test_cases = list() /datum/unit_test/atmos_machinery/proc/create_gas_mixes(gas_mix_data) @@ -60,7 +60,7 @@ pass("[case_name]: conserved moles of each gas ID.") /datum/unit_test/atmos_machinery/conserve_moles - template = /datum/unit_test/atmos_machinery/conserve_moles + abstract_type = /datum/unit_test/atmos_machinery/conserve_moles test_cases = list( uphill = list( source = list( diff --git a/code/unit_tests/chemistry_tests.dm b/code/unit_tests/chemistry_tests.dm index bb6e9d904773..cdc9dae00d42 100644 --- a/code/unit_tests/chemistry_tests.dm +++ b/code/unit_tests/chemistry_tests.dm @@ -1,6 +1,6 @@ /datum/unit_test/chemistry name = "CHEMISTRY: Reagent Template" - template = /datum/unit_test/chemistry + abstract_type = /datum/unit_test/chemistry var/container_volume = 45 var/donor_type = /obj/item diff --git a/code/unit_tests/equipment_tests.dm b/code/unit_tests/equipment_tests.dm index 25146ab9251b..d082e6fc91a9 100644 --- a/code/unit_tests/equipment_tests.dm +++ b/code/unit_tests/equipment_tests.dm @@ -1,6 +1,6 @@ /datum/unit_test/vision_glasses name = "EQUIPMENT: Vision Template" - template = /datum/unit_test/vision_glasses + abstract_type = /datum/unit_test/vision_glasses var/mob/living/human/H = null var/expectation = SEE_INVISIBLE_NOLIGHTING var/glasses_type = null diff --git a/code/unit_tests/extension_tests.dm b/code/unit_tests/extension_tests.dm index 49f9769fa431..2a7724e3cc7b 100644 --- a/code/unit_tests/extension_tests.dm +++ b/code/unit_tests/extension_tests.dm @@ -1,6 +1,6 @@ /datum/unit_test/extensions name = "EXTENSIONS template" - template = /datum/unit_test/extensions + abstract_type = /datum/unit_test/extensions async = 0 /datum/unit_test/extensions/basic_extension_shall_lazy_initalize_as_expected diff --git a/code/unit_tests/foundation_tests.dm b/code/unit_tests/foundation_tests.dm index 66fb31643b33..27196ec37ff8 100644 --- a/code/unit_tests/foundation_tests.dm +++ b/code/unit_tests/foundation_tests.dm @@ -3,7 +3,7 @@ */ /datum/unit_test/foundation name = "FOUNDATION template" - template = /datum/unit_test/foundation + abstract_type = /datum/unit_test/foundation async = 0 /datum/unit_test/foundation/step_shall_return_true_on_success diff --git a/code/unit_tests/graph_tests.dm b/code/unit_tests/graph_tests.dm index d3adbe5210d4..47cdb388f629 100644 --- a/code/unit_tests/graph_tests.dm +++ b/code/unit_tests/graph_tests.dm @@ -430,7 +430,7 @@ * Base Test Setup * ******************/ /datum/unit_test/graph_test - template = /datum/unit_test/graph_test + abstract_type = /datum/unit_test/graph_test async = TRUE var/list/graphs diff --git a/code/unit_tests/icon_tests.dm b/code/unit_tests/icon_tests.dm index 5e4e751e6c97..8ab79c314a2b 100644 --- a/code/unit_tests/icon_tests.dm +++ b/code/unit_tests/icon_tests.dm @@ -1,6 +1,6 @@ /datum/unit_test/icon_test name = "ICON STATE template" - template = /datum/unit_test/icon_test + abstract_type = /datum/unit_test/icon_test /datum/unit_test/icon_test/food_shall_have_icon_states name = "ICON STATE: Food And Drink Subtypes Shall Have Icon States" diff --git a/code/unit_tests/integrated_circuits.dm b/code/unit_tests/integrated_circuits.dm index 79c26d52a3a8..84de2ac2ff34 100644 --- a/code/unit_tests/integrated_circuits.dm +++ b/code/unit_tests/integrated_circuits.dm @@ -1,5 +1,5 @@ /datum/unit_test/integrated_circuits - template = /datum/unit_test/integrated_circuits + abstract_type = /datum/unit_test/integrated_circuits /datum/unit_test/integrated_circuits/unique_names name = "INTEGRATED CIRCUITS: Circuits must have unique names" @@ -64,7 +64,7 @@ /datum/unit_test/integrated_circuits/input_output name = "INTEGRATED CIRCUITS: INPUT/OUTPUT - TEMPLATE" - template = /datum/unit_test/integrated_circuits/input_output + abstract_type = /datum/unit_test/integrated_circuits/input_output var/list/all_inputs = list() var/list/all_expected_outputs = list() var/activation_pin = 1 diff --git a/code/unit_tests/mob_tests.dm b/code/unit_tests/mob_tests.dm index 0228ea803411..86adfc0c9f15 100644 --- a/code/unit_tests/mob_tests.dm +++ b/code/unit_tests/mob_tests.dm @@ -129,7 +129,7 @@ var/global/default_mobloc = null /datum/unit_test/mob_damage name = "MOB: Template for mob damage" - template = /datum/unit_test/mob_damage + abstract_type = /datum/unit_test/mob_damage var/damagetype = BRUTE var/mob_type = /mob/living/human var/expected_vulnerability = STANDARD diff --git a/code/unit_tests/movement_tests.dm b/code/unit_tests/movement_tests.dm index 8d45dbe20cfb..dbcb2bc44991 100644 --- a/code/unit_tests/movement_tests.dm +++ b/code/unit_tests/movement_tests.dm @@ -1,6 +1,6 @@ /datum/unit_test/movement name = "MOVEMENT template" - template = /datum/unit_test/movement + abstract_type = /datum/unit_test/movement async = 0 /datum/unit_test/movement/force_move_shall_trigger_crossed_when_entering_turf diff --git a/code/unit_tests/observation_tests.dm b/code/unit_tests/observation_tests.dm index b9174d26fe87..829bc7435764 100644 --- a/code/unit_tests/observation_tests.dm +++ b/code/unit_tests/observation_tests.dm @@ -4,7 +4,7 @@ /datum/unit_test/observation name = "OBSERVATION template" - template = /datum/unit_test/observation + abstract_type = /datum/unit_test/observation async = 0 var/list/received_moves var/list/received_name_set_events diff --git a/code/unit_tests/override_tests.dm b/code/unit_tests/override_tests.dm index 2c8d6bc47cca..4687b0c72aaa 100644 --- a/code/unit_tests/override_tests.dm +++ b/code/unit_tests/override_tests.dm @@ -2,7 +2,7 @@ /datum/unit_test/override name = "OVERRIDE template" - template = /datum/unit_test/override + abstract_type = /datum/unit_test/override /datum/unit_test/override/obj_random_shall_spawn_heaviest_item name = "OVERRIDE: obj/random shall spawn heaviest item" diff --git a/code/unit_tests/proximity_tests.dm b/code/unit_tests/proximity_tests.dm index b77946ec7397..b405a2c3db25 100644 --- a/code/unit_tests/proximity_tests.dm +++ b/code/unit_tests/proximity_tests.dm @@ -2,7 +2,7 @@ * Template Setup * *****************/ /datum/unit_test/proximity - template = /datum/unit_test/proximity + abstract_type = /datum/unit_test/proximity var/turf/wall/wall var/obj/proximity_listener/proximity_listener @@ -24,7 +24,7 @@ wall.set_opacity(opacity) /datum/unit_test/proximity/visibility - template = /datum/unit_test/proximity/visibility + abstract_type = /datum/unit_test/proximity/visibility var/list/expected_number_of_turfs_by_trigger_type /datum/unit_test/proximity/visibility/start_test() diff --git a/code/unit_tests/time_tests.dm b/code/unit_tests/time_tests.dm index 2dbf636d1e91..55a17518a603 100644 --- a/code/unit_tests/time_tests.dm +++ b/code/unit_tests/time_tests.dm @@ -1,6 +1,6 @@ /datum/unit_test/time name = "TIME: Template" - template = /datum/unit_test/time + abstract_type = /datum/unit_test/time /datum/unit_test/time/shall_validate_sixth_of_june name = "TIME: Shall validate 6th of June" diff --git a/code/unit_tests/unit_test.dm b/code/unit_tests/unit_test.dm index 4fe4fedfdc5c..24fd800c8544 100644 --- a/code/unit_tests/unit_test.dm +++ b/code/unit_tests/unit_test.dm @@ -4,7 +4,7 @@ * For the most part I think any test can be created that doesn't require a client in a mob or require a game mode other then extended * * The easiest way to make effective tests is to create a "template" if you intend to run the same test over and over and make your actual - * tests be a "child object" of those templates. Be sure and name your templates with the word "template" somewhere in var/name. + * tests be a "child object" of those templates. Be sure to set abstract_type on your template type. * * The goal is to have all sorts of tests that run and to run them as quickly as possible. * @@ -51,8 +51,8 @@ var/global/ascii_reset = "[ascii_esc]\[0m" // Templates aren't intended to be ran but just serve as a way to create child objects of it with inheritable tests for quick test creation. /datum/unit_test + abstract_type = /datum/unit_test var/name = "template - should not be ran." - var/template // Treat the unit test as a template if its type is the same as the value of this var var/disabled = 0 // If we want to keep a unit test in the codebase but not run it for some reason. var/async = 0 // If the check can be left to do it's own thing, you must define a check_result() proc if you use this. var/reported = 0 // If it's reported a success or failure. Any tests that have not are assumed to be failures. @@ -157,11 +157,10 @@ var/global/ascii_reset = "[ascii_esc]\[0m" /proc/get_test_datums() . = list() - for(var/test in subtypesof(/datum/unit_test)) - var/datum/unit_test/d = test - if(test == initial(d.template)) + for(var/datum/unit_test/test as anything in subtypesof(/datum/unit_test)) + if(TYPE_IS_ABSTRACT(test)) continue - . += d + . += test /proc/do_unit_test(datum/unit_test/test, end_time, skip_disabled_tests = TRUE) if(test.disabled && skip_disabled_tests) diff --git a/code/unit_tests/virtual_mob_tests.dm b/code/unit_tests/virtual_mob_tests.dm index dab89f395ec8..718bf0107483 100644 --- a/code/unit_tests/virtual_mob_tests.dm +++ b/code/unit_tests/virtual_mob_tests.dm @@ -1,10 +1,10 @@ /datum/unit_test/virtual name = "VIRTUAL: Template" - template = /datum/unit_test/virtual + abstract_type = /datum/unit_test/virtual /datum/unit_test/virtual/helper name = "VIRTUAL: Template Helper" - template = /datum/unit_test/virtual/helper + abstract_type = /datum/unit_test/virtual/helper var/helper_proc var/list/expected_mobs diff --git a/code/unit_tests/zas_tests.dm b/code/unit_tests/zas_tests.dm index b83f880bff9e..7866c78bd62a 100644 --- a/code/unit_tests/zas_tests.dm +++ b/code/unit_tests/zas_tests.dm @@ -12,7 +12,7 @@ /datum/unit_test/zas_area_test name = "ZAS: Area Test Template" - template = /datum/unit_test/zas_area_test + abstract_type = /datum/unit_test/zas_area_test var/area_path = null // Put the area you are testing here. var/expectation = UT_NORMAL // See defines above. diff --git a/mods/species/vox/datum/unit_testing.dm b/mods/species/vox/datum/unit_testing.dm index 1026f897cad4..1010d534842d 100644 --- a/mods/species/vox/datum/unit_testing.dm +++ b/mods/species/vox/datum/unit_testing.dm @@ -4,7 +4,7 @@ /datum/unit_test/mob_damage/vox name = "MOB: Vox damage check template" - template = /datum/unit_test/mob_damage/vox + abstract_type = /datum/unit_test/mob_damage/vox mob_type = /mob/living/human/vox /datum/unit_test/mob_damage/vox/brute From 6d73ca05e132efefe1f742b8fdcdd1deafa30e0f Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 19 Jan 2025 16:34:40 -0500 Subject: [PATCH 091/120] Fix horse coloration --- .../mob/living/simple_animal/passive/horse.dm | 48 +++++++++---------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/code/modules/mob/living/simple_animal/passive/horse.dm b/code/modules/mob/living/simple_animal/passive/horse.dm index d9ea080a559a..e7c235a6c29d 100644 --- a/code/modules/mob/living/simple_animal/passive/horse.dm +++ b/code/modules/mob/living/simple_animal/passive/horse.dm @@ -1,21 +1,22 @@ /mob/living/simple_animal/passive/horse - name = "horse" - real_name = "horse" - desc = "A hefty four-legged animal traditionally used for hauling goods, recreational riding, and stomping enemy soldiers to death." - icon = 'icons/mob/simple_animal/horse.dmi' - speak_emote = list("neighs", "whinnies") - possession_candidate = TRUE - mob_size = MOB_SIZE_LARGE - pixel_x = -6 - default_pixel_x = -6 - base_animal_type = /mob/living/simple_animal/passive/horse - faction = null - buckle_pixel_shift = @"{'x':0,'y':0,'z':16}" - can_have_rider = TRUE - max_rider_size = MOB_SIZE_MEDIUM - ai = /datum/mob_controller/passive/horse - - var/honse_color // Replace this with "base" state when simple animal stuff is merged. + name = "horse" + real_name = "horse" + desc = "A hefty four-legged animal traditionally used for hauling goods, recreational riding, and stomping enemy soldiers to death." + icon = 'icons/mob/simple_animal/horse.dmi' + speak_emote = list("neighs", "whinnies") + possession_candidate = TRUE + mob_size = MOB_SIZE_LARGE + pixel_x = -6 + default_pixel_x = -6 + base_animal_type = /mob/living/simple_animal/passive/horse + faction = null + buckle_pixel_shift = @"{'x':0,'y':0,'z':16}" + can_have_rider = TRUE + max_rider_size = MOB_SIZE_MEDIUM + ai = /datum/mob_controller/passive/horse + draw_visible_overlays = list( + "base" = "#ccc496" + ) /datum/mob_controller/passive/horse emote_speech = list("Neigh!","NEIGH!","Neigh?") @@ -31,18 +32,15 @@ . = ..() add_inventory_slot(new /datum/inventory_slot/back/horse) equip_to_slot_or_del(new /obj/item/saddle(src), slot_back_str) - if(!honse_color) - honse_color = pick(get_possible_horse_colors()) + if(!LAZYACCESS(draw_visible_overlays, "base")) + LAZYSET(draw_visible_overlays, "base", pick(get_possible_horse_colors())) update_icon() -/mob/living/simple_animal/passive/horse/refresh_visible_overlays() - var/list/current_overlays = list(overlay_image(icon, icon_state, honse_color, RESET_COLOR)) +/mob/living/simple_animal/passive/horse/add_additional_visible_overlays(list/accumulator) if(buckled_mob) - var/image/horse_front = overlay_image(icon, "[icon_state]-buckled", honse_color, RESET_COLOR) + var/image/horse_front = overlay_image(icon, "[icon_state]-buckled", draw_visible_overlays["base"], RESET_COLOR) horse_front.layer = ABOVE_HUMAN_LAYER - current_overlays += horse_front - set_current_mob_overlay(HO_SKIN_LAYER, current_overlays, redraw_mob = FALSE) // We're almost certainly redrawing in ..() anyway - . = ..() + accumulator += horse_front /mob/living/simple_animal/passive/horse/get_bodytype() return GET_DECL(/decl/bodytype/quadruped/animal/horse) From 24ded4fcd81fbfd37793bb83992bffe7b69a0a95 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 19 Jan 2025 18:37:40 -0500 Subject: [PATCH 092/120] Fix double words in strings and comments --- code/__defines/flags.dm | 4 ++-- code/__defines/gamemode.dm | 2 +- code/datums/wires/nuclearbomb.dm | 2 +- .../_machines_base/stock_parts/power/terminal.dm | 6 +++--- code/game/machinery/pipe/pipelayer.dm | 2 +- code/game/machinery/wall_frames.dm | 2 +- code/game/objects/items/devices/uplink.dm | 2 +- code/game/objects/items/weapons/grenades/grenade.dm | 8 ++++---- .../objects/items/weapons/grenades/spawnergrenade.dm | 2 +- code/game/objects/items/weapons/tanks/tanks.dm | 2 +- code/game/objects/structures/coathanger.dm | 4 ++-- code/modules/assembly/infrared.dm | 2 +- code/modules/atmospherics/datum_pipeline.dm | 2 +- code/modules/clothing/masks/smokable.dm | 2 +- code/modules/clothing/spacesuits/spacesuits.dm | 2 +- code/modules/clothing/suits/armor/merc.dm | 2 +- code/modules/events/ion_storm.dm | 2 +- code/modules/integrated_electronics/subtypes/memory.dm | 2 +- code/modules/maps/_map_template.dm | 2 +- code/modules/materials/_materials.dm | 4 ++-- code/modules/mechs/components/frame.dm | 2 +- code/modules/mechs/mech_interaction.dm | 4 ++-- code/modules/modular_computers/hardware/lan_port.dm | 4 ++-- .../networking/machinery/telecomms.dm | 2 +- code/modules/multiz/level_data.dm | 2 +- code/modules/organs/external/wounds/wound.dm | 4 ++-- code/modules/power/singularity/emitter.dm | 2 +- code/modules/reagents/reagent_containers/inhaler.dm | 2 +- code/modules/recycling/disposalholder.dm | 10 +++++----- code/modules/shuttles/shuttle_specops.dm | 2 +- .../psionics/system/psionics/faculties/coercion.dm | 2 +- 31 files changed, 46 insertions(+), 46 deletions(-) diff --git a/code/__defines/flags.dm b/code/__defines/flags.dm index cc9efae8d514..8056ab4a3bed 100644 --- a/code/__defines/flags.dm +++ b/code/__defines/flags.dm @@ -81,8 +81,8 @@ The latter will result in a linter warning and will not work correctly. #define ITEM_FLAG_NOCUFFS BITFLAG(11) // Gloves that have this flag prevent cuffs being applied #define ITEM_FLAG_CAN_HIDE_IN_SHOES BITFLAG(12) // Items that can be hidden in shoes that permit it #define ITEM_FLAG_PADDED BITFLAG(13) // When set on gloves, will act like pulling punches in unarmed combat. -#define ITEM_FLAG_CAN_TAPE BITFLAG(14) // Whether the item can be be taped onto something using tape -#define ITEM_FLAG_IS_WEAPON BITFLAG(15) // Item is considered a weapon. Currently only used for force-based worth calculation. +#define ITEM_FLAG_CAN_TAPE BITFLAG(14) // Whether the item can be taped onto something using tape +#define ITEM_FLAG_IS_WEAPON BITFLAG(15) // Item is considered a weapon. Currently only used for force-based worth calculation. // Flags for pass_flags (/atom/var/pass_flags) #define PASS_FLAG_TABLE BITFLAG(0) diff --git a/code/__defines/gamemode.dm b/code/__defines/gamemode.dm index 9493ae7aa125..b3c749c4a546 100644 --- a/code/__defines/gamemode.dm +++ b/code/__defines/gamemode.dm @@ -3,7 +3,7 @@ #define CHOOSE_GAMEMODE_RETRY 2 // The gamemode could not be chosen; we will use the next most popular option voted in, or the default. #define CHOOSE_GAMEMODE_REVOTE 3 // The gamemode could not be chosen; we need to have a revote. #define CHOOSE_GAMEMODE_RESTART 4 // The gamemode could not be chosen; we will restart the server. -#define CHOOSE_GAMEMODE_SILENT_REDO 5 // The gamemode could not be chosen; we request to have the the proc rerun on the next tick. +#define CHOOSE_GAMEMODE_SILENT_REDO 5 // The gamemode could not be chosen; we request to have the proc rerun on the next tick. //End game state, to manage round end. #define END_GAME_NOT_OVER 1 diff --git a/code/datums/wires/nuclearbomb.dm b/code/datums/wires/nuclearbomb.dm index 06c679edfd2c..c984ebbcb773 100644 --- a/code/datums/wires/nuclearbomb.dm +++ b/code/datums/wires/nuclearbomb.dm @@ -20,7 +20,7 @@ var/global/const/NUCLEARBOMB_WIRE_SAFETY = 4 var/obj/machinery/nuclearbomb/N = holder . += ..() . += "
    The device is [N.timing ? "shaking!" : "still."]
    " - . += "The device is is [N.safety ? "quiet" : "whirring"].
    " + . += "The device is [N.safety ? "quiet" : "whirring"].
    " . += "The lights are [N.lighthack ? "static" : "functional"].
    " /datum/wires/nuclearbomb/proc/toggle_hacked() diff --git a/code/game/machinery/_machines_base/stock_parts/power/terminal.dm b/code/game/machinery/_machines_base/stock_parts/power/terminal.dm index d267e96446e7..7e7365e2e176 100644 --- a/code/game/machinery/_machines_base/stock_parts/power/terminal.dm +++ b/code/game/machinery/_machines_base/stock_parts/power/terminal.dm @@ -135,7 +135,7 @@ if(!C.can_use(10)) to_chat(user, "You need ten lengths of cable for \the [machine].") return TRUE - user.visible_message("\The [user] adds cables to the \the [machine].", \ + user.visible_message("\The [user] adds cables to \the [machine].", \ "You start adding cables to \the [machine] frame...") playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) if(do_after(user, 20, machine)) @@ -147,8 +147,8 @@ return TRUE C.use(10) user.visible_message(\ - "\The [user] has added cables to the \the [machine]!",\ - "You add cables to the \the [machine].") + "\The [user] has added cables to \the [machine]!",\ + "You add cables to \the [machine].") make_terminal(machine) return TRUE diff --git a/code/game/machinery/pipe/pipelayer.dm b/code/game/machinery/pipe/pipelayer.dm index 53203ed79923..6a3e54ef69b2 100644 --- a/code/game/machinery/pipe/pipelayer.dm +++ b/code/game/machinery/pipe/pipelayer.dm @@ -73,7 +73,7 @@ if(m) use_metal(m) SSmaterials.create_object(/decl/material/solid/metal/steel, get_turf(src), m) - user.visible_message("[user] removes [m] sheet\s of metal from the \the [src].", "You remove [m] sheet\s of metal from \the [src]") + user.visible_message(SPAN_NOTICE("[user] removes [m] sheet\s of metal from \the [src]."), SPAN_NOTICE("You remove [m] sheet\s of metal from \the [src]")) else to_chat(user, "\The [src] is empty.") return diff --git a/code/game/machinery/wall_frames.dm b/code/game/machinery/wall_frames.dm index f3f7fb0ed89c..cd71c0bdf3a7 100644 --- a/code/game/machinery/wall_frames.dm +++ b/code/game/machinery/wall_frames.dm @@ -246,7 +246,7 @@ icon = 'icons/obj/airlock_machines.dmi' icon_state = "airlock_control_off" name = "airlock controller frame" - desc = "Used to build airlock controllers. Use a multitool on the circuit to determine which type you want, and then hit this with the the circuit." + desc = "Used to build airlock controllers. Use a multitool on the circuit to determine which type you want, and then hit this with the circuit." build_machine_type = null ///Used when configuring a dummy controller var/master_controller_id_tag diff --git a/code/game/objects/items/devices/uplink.dm b/code/game/objects/items/devices/uplink.dm index 4ccd921e0cbb..a3d84d98c0a0 100644 --- a/code/game/objects/items/devices/uplink.dm +++ b/code/game/objects/items/devices/uplink.dm @@ -69,7 +69,7 @@ do var/datum/uplink_random_selection/uplink_selection = get_uplink_random_selection_by_type(/datum/uplink_random_selection/blacklist) new_discount_item = uplink_selection.get_random_item(INFINITY, src) - // Ensures we only only get items for which we get an actual discount and that this particular uplink can actually view (can buy would risk near-infinite loops). + // Ensures we only get items for which we get an actual discount and that this particular uplink can actually view (can buy would risk near-infinite loops). while(is_improper_item(new_discount_item, discount_amount)) if(!new_discount_item) return diff --git a/code/game/objects/items/weapons/grenades/grenade.dm b/code/game/objects/items/weapons/grenades/grenade.dm index c6c88a774472..e4cd31143be3 100644 --- a/code/game/objects/items/weapons/grenades/grenade.dm +++ b/code/game/objects/items/weapons/grenades/grenade.dm @@ -89,16 +89,16 @@ switch(det_time) if (1) det_time = 10 - to_chat(user, SPAN_NOTICE("You set the \the [src] for 1 second detonation time.")) + to_chat(user, SPAN_NOTICE("You set \the [src] for 1 second detonation time.")) if (10) det_time = 30 - to_chat(user, SPAN_NOTICE("You set the \the [src] for 3 second detonation time.")) + to_chat(user, SPAN_NOTICE("You set \the [src] for 3 second detonation time.")) if (30) det_time = 50 - to_chat(user, SPAN_NOTICE("You set the \the [src] for 5 second detonation time.")) + to_chat(user, SPAN_NOTICE("You set \the [src] for 5 second detonation time.")) if (50) det_time = 1 - to_chat(user, SPAN_NOTICE("You set the \the [src] for instant detonation.")) + to_chat(user, SPAN_NOTICE("You set \the [src] for instant detonation.")) add_fingerprint(user) return TRUE return ..() diff --git a/code/game/objects/items/weapons/grenades/spawnergrenade.dm b/code/game/objects/items/weapons/grenades/spawnergrenade.dm index 543bbe5fac4f..7ea1fe40e436 100644 --- a/code/game/objects/items/weapons/grenades/spawnergrenade.dm +++ b/code/game/objects/items/weapons/grenades/spawnergrenade.dm @@ -1,5 +1,5 @@ /obj/item/grenade/spawnergrenade - desc = "It is set to detonate in 5 seconds. It will unleash unleash an unspecified anomaly into the vicinity." + desc = "It is set to detonate in 5 seconds. It will unleash an unspecified anomaly into the vicinity." name = "delivery grenade" icon = 'icons/obj/items/grenades/delivery.dmi' origin_tech = @'{"materials":3,"magnets":4}' diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm index 15bf01b04272..90be0d1bf51b 100644 --- a/code/game/objects/items/weapons/tanks/tanks.dm +++ b/code/game/objects/items/weapons/tanks/tanks.dm @@ -193,7 +193,7 @@ var/global/list/global/tank_gauge_cache = list() var/obj/item/weldingtool/WT = W if(WT.weld(1,user)) if(!valve_welded) - to_chat(user, "You begin welding the \the [src] emergency pressure relief valve.") + to_chat(user, "You begin welding \the [src] emergency pressure relief valve.") if(do_after(user, 40,src)) to_chat(user, "You carefully weld \the [src] emergency pressure relief valve shut. \The [src] may now rupture under pressure!") valve_welded = 1 diff --git a/code/game/objects/structures/coathanger.dm b/code/game/objects/structures/coathanger.dm index 1ba9bf8b4ab0..c0cc9c49c367 100644 --- a/code/game/objects/structures/coathanger.dm +++ b/code/game/objects/structures/coathanger.dm @@ -41,7 +41,7 @@ var/obj/item/removing = contents[contents.len] user.visible_message( \ SPAN_NOTICE("\The [user] takes \the [removing] off \the [src]."), - SPAN_NOTICE("You take \the [removing] off the \the [src].") + SPAN_NOTICE("You take \the [removing] off \the [src].") ) removing.dropInto(loc) user.put_in_active_hand(removing) @@ -74,7 +74,7 @@ if(user.try_unequip(W, src)) user.visible_message( \ SPAN_NOTICE("\The [user] hangs \the [W] on \the [src]."), \ - SPAN_NOTICE("You hang \the [W] on the \the [src].") \ + SPAN_NOTICE("You hang \the [W] on \the [src].") \ ) update_icon() return TRUE diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm index c472eacbe068..93d3b8d26ce0 100644 --- a/code/modules/assembly/infrared.dm +++ b/code/modules/assembly/infrared.dm @@ -67,7 +67,7 @@ holder.update_icon() update_beams() -/obj/item/assembly/infra/interact(mob/user)//TODO: change this this to the wire control panel +/obj/item/assembly/infra/interact(mob/user)//TODO: change this to the wire control panel if(!secured) return if(!CanInteract(user, global.physical_topic_state)) diff --git a/code/modules/atmospherics/datum_pipeline.dm b/code/modules/atmospherics/datum_pipeline.dm index 3223d3251c1e..3b914c0488ec 100644 --- a/code/modules/atmospherics/datum_pipeline.dm +++ b/code/modules/atmospherics/datum_pipeline.dm @@ -45,7 +45,7 @@ . = ..() -/datum/pipeline/Process()//This use to be called called from the pipe networks +/datum/pipeline/Process()//This use to be called from the pipe networks //Check to see if pressure is within acceptable limits var/pressure = air.return_pressure() if(pressure > maximum_pressure) diff --git a/code/modules/clothing/masks/smokable.dm b/code/modules/clothing/masks/smokable.dm index 27f2ab1e023e..c9a5211d4670 100644 --- a/code/modules/clothing/masks/smokable.dm +++ b/code/modules/clothing/masks/smokable.dm @@ -183,7 +183,7 @@ /obj/item/clothing/mask/smokable/attack(var/mob/living/M, var/mob/living/user, def_zone) if(istype(M) && M.on_fire) user.do_attack_animation(M) - light(SPAN_NOTICE("\The [user] coldly lights the \the [src] with the burning body of \the [M].")) + light(SPAN_NOTICE("\The [user] coldly lights \the [src] with the burning body of \the [M].")) return 1 else return ..() diff --git a/code/modules/clothing/spacesuits/spacesuits.dm b/code/modules/clothing/spacesuits/spacesuits.dm index fa008a113e74..b62cf1f16a33 100644 --- a/code/modules/clothing/spacesuits/spacesuits.dm +++ b/code/modules/clothing/spacesuits/spacesuits.dm @@ -1,6 +1,6 @@ //Spacesuit //Note: Everything in modules/clothing/spacesuits should have the entire suit grouped together. -// Meaning the the suit is defined directly after the corrisponding helmet. Just like below! +// Meaning the suit is defined directly after the corresponding helmet. Just like below! /obj/item/clothing/head/helmet/space name = "space helmet" diff --git a/code/modules/clothing/suits/armor/merc.dm b/code/modules/clothing/suits/armor/merc.dm index c81931f77f17..74ae80237cec 100644 --- a/code/modules/clothing/suits/armor/merc.dm +++ b/code/modules/clothing/suits/armor/merc.dm @@ -4,7 +4,7 @@ /obj/item/clothing/accessory/armor/plate/merc name = "heavy armor plate" - desc = "A diamond-reinforced titanium armor plate, providing state of of the art protection. Attaches to a plate carrier." + desc = "A diamond-reinforced titanium armor plate, providing state of the art protection. Attaches to a plate carrier." icon = 'icons/clothing/accessories/armor/armor_merc.dmi' armor = list( ARMOR_MELEE = ARMOR_MELEE_RESISTANT, diff --git a/code/modules/events/ion_storm.dm b/code/modules/events/ion_storm.dm index 7678707149d4..46e75a25a5fb 100644 --- a/code/modules/events/ion_storm.dm +++ b/code/modules/events/ion_storm.dm @@ -82,7 +82,7 @@ "When asked a question, respond with the least-obvious and least-rational answer.", "[pick("Everyone", random_player)] is wearing a pretty pink dress! Compliment it!", "You are the [location_name()]'s psychologist. Give advice to [pick("the crew", random_player)].", - "[random_player] is the monarch of of England. Ensure all crewmembers pay due respect.", + "[random_player] is the monarch of England. Ensure all crewmembers pay due respect.", "[pick("The crew", random_player)] is [pick("ugly","beautiful")]. Ensure all are aware.", "Reminding the crew of their mortality is good for the morale. Keep the crew's morale up.", "[pick("Monkeys","Doors")] are part of the crew, too. Make sure they are treated humanely.", diff --git a/code/modules/integrated_electronics/subtypes/memory.dm b/code/modules/integrated_electronics/subtypes/memory.dm index c4c127693b4f..b105438a0377 100644 --- a/code/modules/integrated_electronics/subtypes/memory.dm +++ b/code/modules/integrated_electronics/subtypes/memory.dm @@ -63,7 +63,7 @@ /obj/item/integrated_circuit/memory/huge name = "large memory stick" - desc = "This stick of memory can store up up to sixteen pieces of data." + desc = "This stick of memory can store up to sixteen pieces of data." icon_state = "memory16" w_class = ITEM_SIZE_SMALL spawn_flags = IC_SPAWN_RESEARCH diff --git a/code/modules/maps/_map_template.dm b/code/modules/maps/_map_template.dm index 5df971a8d5e8..76642243a94f 100644 --- a/code/modules/maps/_map_template.dm +++ b/code/modules/maps/_map_template.dm @@ -225,7 +225,7 @@ if (SSlighting.initialized) SSlighting.InitializeTurfs(atoms_to_initialise) // Hopefully no turfs get placed on new coords by SSatoms. - log_game("[name] loaded at at [T.x],[T.y],[T.z]") + log_game("[name] loaded at [T.x],[T.y],[T.z]") loaded++ return TRUE diff --git a/code/modules/materials/_materials.dm b/code/modules/materials/_materials.dm index 767d51211e21..9b7994bd456a 100644 --- a/code/modules/materials/_materials.dm +++ b/code/modules/materials/_materials.dm @@ -289,7 +289,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) // Placeholders for light tiles and rglass. /decl/material/proc/reinforce(var/mob/user, var/obj/item/stack/material/used_stack, var/obj/item/stack/material/target_stack, var/use_sheets = 1) if(!used_stack.can_use(use_sheets)) - to_chat(user, SPAN_WARNING("You need need at least one [used_stack.singular_name] to reinforce [target_stack].")) + to_chat(user, SPAN_WARNING("You need at least one [used_stack.singular_name] to reinforce [target_stack].")) return var/decl/material/reinf_mat = used_stack.material @@ -298,7 +298,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) return if(!target_stack.can_use(use_sheets)) - to_chat(user, SPAN_WARNING("You need need at least [use_sheets] [use_sheets == 1 ? target_stack.singular_name : target_stack.plural_name] for reinforcement with [used_stack].")) + to_chat(user, SPAN_WARNING("You need at least [use_sheets] [use_sheets == 1 ? target_stack.singular_name : target_stack.plural_name] for reinforcement with [used_stack].")) return to_chat(user, SPAN_NOTICE("You reinforce the [target_stack] with [reinf_mat.solid_name].")) diff --git a/code/modules/mechs/components/frame.dm b/code/modules/mechs/components/frame.dm index 1681a3e44591..31cbe024414e 100644 --- a/code/modules/mechs/components/frame.dm +++ b/code/modules/mechs/components/frame.dm @@ -198,7 +198,7 @@ to_chat(user, SPAN_WARNING("You need at least ten sheets to reinforce \the [src].")) return - visible_message("\The [user] begins layering the interior of the \the [src] with \the [M].") + visible_message("\The [user] begins layering the interior of \the [src] with \the [M].") if(!do_after(user, 30 * user.skill_delay_mult(SKILL_DEVICES)) || is_reinforced) return diff --git a/code/modules/mechs/mech_interaction.dm b/code/modules/mechs/mech_interaction.dm index 0bb34504ad69..c6096b7fae1e 100644 --- a/code/modules/mechs/mech_interaction.dm +++ b/code/modules/mechs/mech_interaction.dm @@ -461,9 +461,9 @@ if(!body) //Error return TRUE var/delay = min(50 * user.skill_delay_mult(SKILL_DEVICES), 50 * user.skill_delay_mult(SKILL_EVA)) - visible_message(SPAN_NOTICE("\The [user] starts forcing the \the [src]'s emergency [body.hatch_descriptor] release using \the [thing].")) + visible_message(SPAN_NOTICE("\The [user] starts forcing \the [src]'s emergency [body.hatch_descriptor] release using \the [thing].")) if(do_after(user, delay, src)) - visible_message(SPAN_NOTICE("\The [user] forces \the [src]'s [body.hatch_descriptor] open using the \the [thing].")) + visible_message(SPAN_NOTICE("\The [user] forces \the [src]'s [body.hatch_descriptor] open using \the [thing].")) playsound(user.loc, 'sound/machines/bolts_up.ogg', 25, 1) hatch_locked = FALSE hatch_closed = FALSE diff --git a/code/modules/modular_computers/hardware/lan_port.dm b/code/modules/modular_computers/hardware/lan_port.dm index 09e516f290ba..3bca93ec072c 100644 --- a/code/modules/modular_computers/hardware/lan_port.dm +++ b/code/modules/modular_computers/hardware/lan_port.dm @@ -77,10 +77,10 @@ to_chat(user, SPAN_WARNING("You need five lengths of network cable for \the [parent].")) return TRUE - user.visible_message(SPAN_NOTICE("\The [user] adds cables to the \the [parent]."), "You start adding cables to \the [parent] frame...") + user.visible_message(SPAN_NOTICE("\The [user] adds cables to \the [parent]."), "You start adding cables to \the [parent] frame...") if(do_after(user, 20, parent)) if(!terminal && (loc == parent) && parent.components_are_accessible(type) && !check_terminal_block(T) && C.use(5)) - user.visible_message(SPAN_NOTICE("\The [user] has added cables to the \the [parent]!"), "You add cables to the \the [parent].") + user.visible_message(SPAN_NOTICE("\The [user] has added cables to \the [parent]!"), "You add cables to \the [parent].") set_terminal() return TRUE if(IS_WIRECUTTER(I) && terminal) diff --git a/code/modules/modular_computers/networking/machinery/telecomms.dm b/code/modules/modular_computers/networking/machinery/telecomms.dm index 9c936561586e..93f7f7cd4914 100644 --- a/code/modules/modular_computers/networking/machinery/telecomms.dm +++ b/code/modules/modular_computers/networking/machinery/telecomms.dm @@ -127,7 +127,7 @@ var/global/list/telecomms_hubs = list() if(overloaded_for > 0) overloaded_for-- -/// Accepts either a raw frequency (numeric), or or a frequency/key string, and returns the associated channel data. +/// Accepts either a raw frequency (numeric), or a frequency/key string, and returns the associated channel data. /obj/machinery/network/telecomms_hub/proc/get_channel_from_freq_or_key(var/cid) cid = "[cid]" . = LAZYACCESS(channels_by_frequency, cid) || LAZYACCESS(channels_by_key, cid) diff --git a/code/modules/multiz/level_data.dm b/code/modules/multiz/level_data.dm index 9b32cf78efb7..9cb52cd34ff7 100644 --- a/code/modules/multiz/level_data.dm +++ b/code/modules/multiz/level_data.dm @@ -682,7 +682,7 @@ INITIALIZE_IMMEDIATE(/obj/abstract/level_data_spawner) load_subtemplate(T, template) return template -///Actually handles loading a template template at the given turf. +///Actually handles loading a template at the given turf. /datum/level_data/proc/load_subtemplate(turf/central_turf, datum/map_template/template) if(!template) return FALSE diff --git a/code/modules/organs/external/wounds/wound.dm b/code/modules/organs/external/wounds/wound.dm index 2c2746cd154c..60219be1f1a4 100644 --- a/code/modules/organs/external/wounds/wound.dm +++ b/code/modules/organs/external/wounds/wound.dm @@ -79,7 +79,7 @@ return 0 return (wound_damage() <= autoheal_cutoff) ? 1 : is_treated() -// checks whether the wound has been appropriately treated +/// checks whether the wound has been appropriately treated /datum/wound/proc/is_treated() if(!LAZYLEN(embedded_objects)) switch(damage_type) @@ -88,7 +88,7 @@ if(BURN) return salved - // Checks whether other other can be merged into src. +/// Checks whether other can be merged into src. /datum/wound/proc/can_merge_wounds(var/datum/wound/other) if (other.type != src.type) return 0 if (other.current_stage != src.current_stage) return 0 diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index af92c39b88c3..b35b803b77eb 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -11,7 +11,7 @@ active_power_usage = 100 KILOWATTS var/efficiency = 0.3 // Energy efficiency. 30% at this time, so 100kW load means 30kW laser pulses. - var/minimum_power = 10 KILOWATTS // The minimum power the emitter will still fire at it it doesn't have enough power available. + var/minimum_power = 10 KILOWATTS // The minimum power below which the emitter will turn off; different than the power needed to fire. var/active = 0 var/fire_delay = 100 var/max_burst_delay = 100 diff --git a/code/modules/reagents/reagent_containers/inhaler.dm b/code/modules/reagents/reagent_containers/inhaler.dm index df9d2ed145cf..0f43e315bfdb 100644 --- a/code/modules/reagents/reagent_containers/inhaler.dm +++ b/code/modules/reagents/reagent_containers/inhaler.dm @@ -63,7 +63,7 @@ user.do_attack_animation(target) if(user == target) - user.visible_message(SPAN_NOTICE("\The [user] inhales from \the [src]."), SPAN_NOTICE("You stick the \the [src] in your mouth and press the injection button.")) + user.visible_message(SPAN_NOTICE("\The [user] inhales from \the [src]."), SPAN_NOTICE("You stick \the [src] in your mouth and press the injection button.")) else user.visible_message(SPAN_WARNING("\The [user] attempts to administer \the [src] to \the [target]..."), SPAN_NOTICE("You attempt to administer \the [src] to \the [target]...")) if (!do_after(user, 1 SECONDS, target)) diff --git a/code/modules/recycling/disposalholder.dm b/code/modules/recycling/disposalholder.dm index 120782aaff47..49c84d3ea838 100644 --- a/code/modules/recycling/disposalholder.dm +++ b/code/modules/recycling/disposalholder.dm @@ -82,11 +82,11 @@ if(!curr) last.expel(src, loc, dir) - // find the turf which should contain the next pipe +/// find the turf which should contain the next pipe /obj/structure/disposalholder/proc/nextloc() return get_step(loc,dir) -// find a matching pipe on a turf +/// find a matching pipe on a turf /obj/structure/disposalholder/proc/findpipe(var/turf/T) if(!T) return null @@ -98,8 +98,8 @@ // if no matching pipe, return null return null -// merge two holder objects -// used when a a holder meets a stuck holder +/// merge two holder objects +/// used when a holder meets a stuck holder /obj/structure/disposalholder/proc/merge(var/obj/structure/disposalholder/other) for(var/atom/movable/AM in other) AM.forceMove(src) // move everything in other holder to this one @@ -119,7 +119,7 @@ else partialTag = new_tag -// called when player tries to move while in a pipe +/// called when player tries to move while in a pipe /obj/structure/disposalholder/relaymove(mob/user) if(!isliving(user)) return diff --git a/code/modules/shuttles/shuttle_specops.dm b/code/modules/shuttles/shuttle_specops.dm index e028cd81130d..9e7ab58fa266 100644 --- a/code/modules/shuttles/shuttle_specops.dm +++ b/code/modules/shuttles/shuttle_specops.dm @@ -98,7 +98,7 @@ return ..() /datum/shuttle/autodock/ferry/specops/proc/sleep_until_launch() - var/message_tracker[] = list(0,1,2,3,5,10,30,45)//Create a a list with potential time values. + var/message_tracker[] = list(0,1,2,3,5,10,30,45)//Create a list with potential time values. var/launch_time = world.time + specops_countdown_time var/time_until_launch diff --git a/mods/content/psionics/system/psionics/faculties/coercion.dm b/mods/content/psionics/system/psionics/faculties/coercion.dm index b21fba16e60e..7f54c9499dff 100644 --- a/mods/content/psionics/system/psionics/faculties/coercion.dm +++ b/mods/content/psionics/system/psionics/faculties/coercion.dm @@ -181,7 +181,7 @@ return TRUE if(accepted_glamour == "Yes") - to_chat(user, SPAN_DANGER("You layer a glamour across the \the [target]'s senses, beguiling them to unwittingly follow your commands.")) + to_chat(user, SPAN_DANGER("You layer a glamour across \the [target]'s senses, beguiling them to unwittingly follow your commands.")) to_chat(target, SPAN_DANGER("You have been ensnared by \the [user]'s glamour!")) beguiled.add_antagonist(target.mind, new_controller = user) else From 562e324d93f5a1eb87e58f826936bd45868d9f51 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 16 Jan 2025 22:09:07 -0500 Subject: [PATCH 093/120] Optimize roundstart atom initialization --- code/__defines/subsystems.dm | 5 +-- code/controllers/subsystems/atoms.dm | 55 ++++++++++++++-------------- code/game/atoms_init.dm | 13 +++---- test/check-paths.sh | 2 +- 4 files changed, 35 insertions(+), 40 deletions(-) diff --git a/code/__defines/subsystems.dm b/code/__defines/subsystems.dm index c9880741fa9e..13861c4d9f5d 100644 --- a/code/__defines/subsystems.dm +++ b/code/__defines/subsystems.dm @@ -1,7 +1,6 @@ #define INITIALIZATION_INSSATOMS 0 //New should not call Initialize -#define INITIALIZATION_INSSATOMS_LATE 1 //New should not call Initialize; after the first pass is complete (handled differently) -#define INITIALIZATION_INNEW_MAPLOAD 2 //New should call Initialize(TRUE) -#define INITIALIZATION_INNEW_REGULAR 3 //New should call Initialize(FALSE) +#define INITIALIZATION_INNEW_MAPLOAD 1 //New should call Initialize(TRUE) +#define INITIALIZATION_INNEW_REGULAR 2 //New should call Initialize(FALSE) #define INITIALIZE_HINT_NORMAL 0 //Nothing happens #define INITIALIZE_HINT_LATELOAD 1 //Call LateInitialize diff --git a/code/controllers/subsystems/atoms.dm b/code/controllers/subsystems/atoms.dm index 6e45e5e274b9..baf065bd0fd3 100644 --- a/code/controllers/subsystems/atoms.dm +++ b/code/controllers/subsystems/atoms.dm @@ -11,8 +11,10 @@ SUBSYSTEM_DEF(atoms) var/atom_init_stage = INITIALIZATION_INSSATOMS var/old_init_stage - var/list/late_loaders + /// A non-associative list of lists, with the format list(list(atom, list(Initialize arguments))). var/list/created_atoms = list() + /// A non-associative list of lists, with the format list(list(atom, list(LateInitialize arguments))). + var/list/late_loaders = list() var/list/BadInitializeCalls = list() @@ -22,21 +24,25 @@ SUBSYSTEM_DEF(atoms) return ..() /datum/controller/subsystem/atoms/proc/InitializeAtoms() - if(atom_init_stage <= INITIALIZATION_INSSATOMS_LATE) + if(atom_init_stage <= INITIALIZATION_INSSATOMS) return atom_init_stage = INITIALIZATION_INNEW_MAPLOAD - LAZYINITLIST(late_loaders) - var/list/mapload_arg = list(TRUE) - var/count = created_atoms.len - while(created_atoms.len) - var/atom/A = created_atoms[created_atoms.len] - var/list/atom_args = created_atoms[A] - created_atoms.len-- - if(!QDELETED(A) && !(A.atom_flags & ATOM_FLAG_INITIALIZED)) + var/index = 1 + // Things can add to the end of this list while we iterate, so we can't use a for loop. + while(index <= length(created_atoms)) + // Don't remove from this list while we run, that's expensive. + // That would also make it harder to handle things added while we iterate. + var/list/creation_packet = created_atoms[index++] + var/atom/A = creation_packet[1] + var/list/atom_args = creation_packet[2] + // I sure hope nothing in this list is ever hard-deleted, or else QDELING will runtime. + // If you get a null reference runtime error, just change it back to QDELETED. + // The ATOM_FLAG_INITIALIZED check is because of INITIALIZE_IMMEDIATE(). + if(!QDELING(A) && !(A.atom_flags & ATOM_FLAG_INITIALIZED)) if(atom_args) atom_args.Insert(1, TRUE) InitAtom(A, atom_args) @@ -44,26 +50,19 @@ SUBSYSTEM_DEF(atoms) InitAtom(A, mapload_arg) CHECK_TICK - // If wondering why not just store all atoms in created_atoms and use the block above: that turns out unbearably expensive. - // Instead, atoms without extra arguments in New created on server start are fished out of world directly. - // We do this exactly once. - if(!initialized) - for(var/atom/A in world) - if(!QDELETED(A) && !(A.atom_flags & ATOM_FLAG_INITIALIZED)) - InitAtom(A, mapload_arg) - ++count - CHECK_TICK - - report_progress("Initialized [count] atom\s") + report_progress("Initialized [index] atom\s") + created_atoms.Cut() atom_init_stage = INITIALIZATION_INNEW_REGULAR - if(late_loaders.len) - for(var/I in late_loaders) - var/atom/A = I - A.LateInitialize(arglist(late_loaders[A])) + if(length(late_loaders)) + index = 1 + while(index <= length(late_loaders)) + var/list/creation_packet = late_loaders[index++] + var/atom/A = creation_packet[1] + A.LateInitialize(arglist(creation_packet[2])) CHECK_TICK - report_progress("Late initialized [late_loaders.len] atom\s") + report_progress("Late initialized [index] atom\s") late_loaders.Cut() /datum/controller/subsystem/atoms/proc/InitAtom(atom/A, list/arguments) @@ -91,7 +90,7 @@ SUBSYSTEM_DEF(atoms) EMPTY_BLOCK_GUARD if(INITIALIZE_HINT_LATELOAD) if(arguments[1]) //mapload - late_loaders[A] = arguments + late_loaders[++late_loaders.len] = list(A, arguments) else A.LateInitialize(arglist(arguments)) if(INITIALIZE_HINT_QDEL) @@ -113,7 +112,7 @@ SUBSYSTEM_DEF(atoms) /datum/controller/subsystem/atoms/proc/map_loader_begin() old_init_stage = atom_init_stage - atom_init_stage = INITIALIZATION_INSSATOMS_LATE + atom_init_stage = INITIALIZATION_INSSATOMS /datum/controller/subsystem/atoms/proc/map_loader_stop() atom_init_stage = old_init_stage diff --git a/code/game/atoms_init.dm b/code/game/atoms_init.dm index d1cd533c7967..eb08297e2ab9 100644 --- a/code/game/atoms_init.dm +++ b/code/game/atoms_init.dm @@ -16,18 +16,15 @@ var/do_initialize = SSatoms.atom_init_stage var/list/created = SSatoms.created_atoms - if(do_initialize > INITIALIZATION_INSSATOMS_LATE) + if(do_initialize > INITIALIZATION_INSSATOMS) args[1] = do_initialize == INITIALIZATION_INNEW_MAPLOAD if(SSatoms.InitAtom(src, args)) //we were deleted return - else if(created) - var/list/argument_list - if(length(args) > 1) - argument_list = args.Copy(2) - if(argument_list || do_initialize == INITIALIZATION_INSSATOMS_LATE) - created[src] = argument_list - + else if(length(args) > 1) + created[++created.len] = list(src, args.Copy(2)) + else + created[++created.len] = list(src, null) if(atom_flags & ATOM_FLAG_CLIMBABLE) verbs += /atom/proc/climb_on diff --git a/test/check-paths.sh b/test/check-paths.sh index b88c7775cf26..7d9bfbed01a9 100755 --- a/test/check-paths.sh +++ b/test/check-paths.sh @@ -32,7 +32,7 @@ exactly 2 "/mob text paths" '"/mob' exactly 6 "/obj text paths" '"/obj' exactly 10 "/turf text paths" '"/turf' exactly 1 "world<< uses" 'world<<|world[[:space:]]<<' -exactly 90 "'in world' uses" 'in world' +exactly 89 "'in world' uses" 'in world' exactly 1 "world.log<< uses" 'world.log<<|world.log[[:space:]]<<' exactly 18 "<< uses" '(?> uses" '>>(?!>)' -P From e7e85ff17fd747facd186e6c13936bf326a6a354 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 17 Jan 2025 01:55:29 -0500 Subject: [PATCH 094/120] Simplify duplicate level data setup code --- code/controllers/subsystems/mapping.dm | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/code/controllers/subsystems/mapping.dm b/code/controllers/subsystems/mapping.dm index 6e1061636ec6..7cbabf3d479d 100644 --- a/code/controllers/subsystems/mapping.dm +++ b/code/controllers/subsystems/mapping.dm @@ -119,15 +119,9 @@ SUBSYSTEM_DEF(mapping) // This needs to be non-null even if the overmap isn't created for this map. overmap_event_handler = GET_DECL(/decl/overmap_event_handler) - var/old_maxz - for(var/z = 1 to world.maxz) - var/datum/level_data/level = levels_by_z[z] - if(!istype(level)) - level = new /datum/level_data/space(z) - PRINT_STACK_TRACE("Missing z-level data object for z[num2text(z)]!") - level.setup_level_data() + setup_data_for_levels() - old_maxz = world.maxz + var/old_maxz = world.maxz // Build away sites. global.using_map.build_away_sites() global.using_map.build_planets() @@ -150,13 +144,7 @@ SUBSYSTEM_DEF(mapping) test_load_map_templates() #endif - // Check/associated/setup our level data objects. - for(var/z = old_maxz + 1 to world.maxz) - var/datum/level_data/level = levels_by_z[z] - if(!istype(level)) - level = new /datum/level_data/space(z) - PRINT_STACK_TRACE("Missing z-level data object for z[num2text(z)]!") - level.setup_level_data() + setup_data_for_levels(min_z = old_maxz + 1) // Generate turbolifts last, since away sites may have elevators to generate too. for(var/obj/abstract/turbolift_spawner/turbolift as anything in turbolifts_to_initialize) @@ -166,6 +154,14 @@ SUBSYSTEM_DEF(mapping) . = ..() +/datum/controller/subsystem/mapping/proc/setup_data_for_levels(min_z = 1, max_z = world.maxz) + for(var/z = min_z to max_z) + var/datum/level_data/level = levels_by_z[z] + if(!istype(level)) + level = new /datum/level_data/space(z) + PRINT_STACK_TRACE("Missing z-level data object for z[num2text(z)]!") + level.setup_level_data() + /datum/controller/subsystem/mapping/Recover() flags |= SS_NO_INIT map_templates = SSmapping.map_templates From a02c41c97f0ed01026ad5f781d7eb3ca9aa1be5a Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 17 Jan 2025 02:01:40 -0500 Subject: [PATCH 095/120] Optimize map template atom init processing --- code/controllers/subsystems/machines.dm | 6 ++++ code/controllers/subsystems/mapping.dm | 2 ++ code/modules/maps/_map_template.dm | 43 ++++++------------------- 3 files changed, 18 insertions(+), 33 deletions(-) diff --git a/code/controllers/subsystems/machines.dm b/code/controllers/subsystems/machines.dm index 48d7b4250379..674ec094cc68 100644 --- a/code/controllers/subsystems/machines.dm +++ b/code/controllers/subsystems/machines.dm @@ -82,6 +82,12 @@ if(current_step == this_step || (check_resumed && !resumed)) {\ #undef INTERNAL_PROCESS_STEP +/datum/controller/subsystem/machines/StartLoadingMap() + suspend() + +/datum/controller/subsystem/machines/StopLoadingMap() + wake() + // rebuild all power networks from scratch - only called at world creation or by the admin verb // The above is a lie. Turbolifts also call this proc. /datum/controller/subsystem/machines/proc/makepowernets() diff --git a/code/controllers/subsystems/mapping.dm b/code/controllers/subsystems/mapping.dm index 7cbabf3d479d..e565651692cb 100644 --- a/code/controllers/subsystems/mapping.dm +++ b/code/controllers/subsystems/mapping.dm @@ -109,6 +109,8 @@ SUBSYSTEM_DEF(mapping) // Load any queued map template markers. for(var/obj/abstract/landmark/map_load_mark/queued_mark in queued_markers) queued_mark.load_subtemplate() + if(!QDELETED(queued_mark)) // for if the tile that lands on the landmark is a no-op tile + qdel(queued_mark) queued_markers.Cut() // Populate overmap. diff --git a/code/modules/maps/_map_template.dm b/code/modules/maps/_map_template.dm index c5ae24dc655f..2a96e4c0fa47 100644 --- a/code/modules/maps/_map_template.dm +++ b/code/modules/maps/_map_template.dm @@ -14,7 +14,7 @@ ///Shuttles in this template's levels that need to be initialized with SSshuttle. var/list/shuttles_to_initialise = list() ///Sub-templates to spawn on this template if any. Ruins and sites and etc.. - var/list/subtemplates_to_spawn + var/list/subtemplates_to_spawn = list() ///Percent of chances to end up onto a level from this template by spacewalking between space z-levels. var/accessibility_weight = 0 ///Flags for defining special properties of this template. @@ -67,45 +67,22 @@ if (SSatoms.atom_init_stage == INITIALIZATION_INSSATOMS) return // let proper initialisation handle it later - var/list/turf/turfs = list() - var/list/obj/machinery/atmospherics/atmos_machines = list() - var/list/obj/machinery/machines = list() - var/list/obj/structure/cable/cables = list() - - for(var/atom/A in atoms) - if(isturf(A)) - turfs += A - if(istype(A, /obj/structure/cable)) - cables += A - if(istype(A, /obj/machinery/atmospherics)) - atmos_machines += A - if(istype(A, /obj/machinery)) - machines += A - if(istype(A, /obj/abstract/landmark/map_load_mark)) - LAZYADD(subtemplates_to_spawn, A) - - var/notsuspended - if(!SSmachines.suspended) - SSmachines.suspend() - notsuspended = TRUE - SSatoms.InitializeAtoms() // The atoms should have been getting queued there. This flushes the queue. - SSmachines.setup_powernets_for_cables(cables) - SSmachines.setup_atmos_machinery(atmos_machines) - if(notsuspended) - SSmachines.wake() + for(var/obj/abstract/landmark/map_load_mark/landmark in atoms) + subtemplates_to_spawn += landmark - for (var/obj/machinery/machine as anything in machines) - machine.power_change() + // fun fact: these already filter for us, so it's pointless to sort + SSmachines.setup_powernets_for_cables(atoms) + SSmachines.setup_atmos_machinery(atoms) - for (var/turf/T as anything in turfs) + for (var/turf/T in atoms) if(template_flags & TEMPLATE_FLAG_NO_RUINS) T.turf_flags |= TURF_FLAG_NO_POINTS_OF_INTEREST if(template_flags & TEMPLATE_FLAG_NO_RADS) qdel(SSradiation.sources_assoc[T]) - if(istype(T) && T.simulated) - T.update_air_properties() + if(T.simulated) + SSair.mark_for_update(T) /datum/map_template/proc/pre_init_shuttles() . = SSshuttle.block_queue @@ -234,7 +211,7 @@ for(var/obj/abstract/landmark/map_load_mark/mark as anything in subtemplates_to_spawn) subtemplates_to_spawn -= mark mark.load_subtemplate() - if(!QDELETED(mark)) + if(!QDELETED(mark)) // for if the tile that lands on the landmark is a no-op tile qdel(mark) subtemplates_to_spawn = null generate_multi_spawn_items() From 7bb7fbdb413c247c6ad40aa92f5b56b0ede83291 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 17 Jan 2025 02:03:58 -0500 Subject: [PATCH 096/120] Optimize the map reader --- code/modules/maps/reader.dm | 65 +++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 35 deletions(-) diff --git a/code/modules/maps/reader.dm b/code/modules/maps/reader.dm index bd097470945d..71bedba36393 100644 --- a/code/modules/maps/reader.dm +++ b/code/modules/maps/reader.dm @@ -12,18 +12,32 @@ var/global/dmm_suite/preloader/_preloader = new var/list/atoms_to_initialise /dmm_suite - // /"([a-zA-Z]+)" = \(((?:.|\n)*?)\)\n(?!\t)|\((\d+),(\d+),(\d+)\) = \{"([a-zA-Z\n]*)"\}/g - var/static/regex/dmmRegex = new/regex({""(\[a-zA-Z]+)" = \\(((?:.|\n)*?)\\)\n(?!\t)|\\((\\d+),(\\d+),(\\d+)\\) = \\{"(\[a-zA-Z\n]*)"\\}"}, "g") + // /"([a-zA-Z]+)" = \(((?:.|\n)*?)\)\n(?!\t)|\((\d+),(\d+),(\d+)\) = \{"\n*([a-zA-Z\n]*)\n?"\}/g + var/static/regex/dmmRegex = new/regex({""(\[a-zA-Z]+)" = \\(((?:.|\n)*?)\\)\n(?!\t)|\\((\\d+),(\\d+),(\\d+)\\) = \\{"\n*(\[a-zA-Z\n]*)\n?"\\}"}, "g") // /^[\s\n]+"?|"?[\s\n]+$|^"|"$/g var/static/regex/trimQuotesRegex = new/regex({"^\[\\s\n]+"?|"?\[\\s\n]+$|^"|"$"}, "g") // /^[\s\n]+|[\s\n]+$/ var/static/regex/trimRegex = new/regex("^\[\\s\n]+|\[\\s\n]+$", "g") var/static/list/modelCache = list() var/static/space_key + var/static/list/types_to_delete #ifdef TESTING var/static/turfsSkipped #endif +// Set up some basic cached vars, like types_to_delete, that have to check things like subtypes. +/dmm_suite/New() + if(!types_to_delete) + types_to_delete = typecacheof(list( + /mob/living, + /obj/effect, + /obj/item, + /obj/machinery, + /obj/structure, + /obj/abstract/landmark/exoplanet_spawn, + )) + ..() + /** * Construct the model map and control the loading process * @@ -124,20 +138,11 @@ var/global/dmm_suite/preloader/_preloader = new bounds[MAP_MAXZ] = max(bounds[MAP_MAXZ], zcrd) var/list/gridLines = splittext(dmmRegex.group[6], "\n") - - var/leadingBlanks = 0 - while(leadingBlanks < gridLines.len && gridLines[++leadingBlanks] == "") - if(leadingBlanks > 1) - gridLines.Cut(1, leadingBlanks) // Remove all leading blank lines. - - if(!gridLines.len) // Skip it if only blank lines exist. + if(!length(gridLines)) // Skip it if only blank lines exist. continue - if(gridLines.len && gridLines[gridLines.len] == "") - gridLines.Cut(gridLines.len) // Remove only one blank line at the end. - bounds[MAP_MINY] = min(bounds[MAP_MINY], clamp(ycrd, y_lower, y_upper)) - ycrd += gridLines.len - 1 // Start at the top and work down + ycrd += length(gridLines) - 1 // Start at the top and work down if(!cropMap && ycrd > world.maxy) if(!measureOnly) @@ -224,16 +229,6 @@ var/global/dmm_suite/preloader/_preloader = new var/list/atoms_to_initialise var/list/atoms_to_delete -/dmm_suite/proc/types_to_delete() - return list( - /mob/living, - /obj/effect, - /obj/item, - /obj/machinery, - /obj/structure, - /obj/abstract/landmark/exoplanet_spawn, - ) - /dmm_suite/proc/parse_grid(model as text, model_key as text, xcrd as num,ycrd as num,zcrd as num, no_changeturf as num, clear_contents as num, initialized_areas_by_type) /*Method parse_grid() - Accepts a text string containing a comma separated list of type paths of the @@ -286,8 +281,8 @@ var/global/dmm_suite/preloader/_preloader = new if(variables_start)//if there's any variable full_def = copytext(full_def,variables_start+1,length(full_def))//removing the last '}' fields = readlist(full_def, ";") - if(fields.len) - if(!trim(fields[fields.len])) + if(length(fields)) + if(!trim(fields[length(fields)])) --fields.len for(var/I in fields) var/value = fields[I] @@ -310,7 +305,7 @@ var/global/dmm_suite/preloader/_preloader = new // 5. and the members are world.turf and world.area // Basically, if we find an entry like this: "XXX" = (/turf/default, /area/default) // We can skip calling this proc every time we see XXX - if(no_changeturf && !space_key && members.len == 2 && members_attributes.len == 2 && length(members_attributes[1]) == 0 && length(members_attributes[2]) == 0 && (world.area in members) && (world.turf in members)) + if(no_changeturf && !space_key && length(members) == 2 && length(members_attributes) == 2 && length(members_attributes[1]) == 0 && length(members_attributes[2]) == 0 && (world.area in members) && (world.turf in members)) space_key = model_key return @@ -327,7 +322,7 @@ var/global/dmm_suite/preloader/_preloader = new var/atoms_to_delete = list() //first instance the /area and remove it from the members list - index = members.len + index = length(members) if(members[index] != /area/template_noop) is_not_noop = TRUE var/list/attr = members_attributes[index] @@ -361,20 +356,20 @@ var/global/dmm_suite/preloader/_preloader = new if(T) //if others /turf are presents, simulates the underlays piling effect index = first_turf_index + 1 - while(index <= members.len - 1) // Last item is an /area + while(index < length(members)) // Last item is an /area var/underlay = T.appearance T = instance_atom(members[index],members_attributes[index],crds,no_changeturf)//instance new turf T.underlays += underlay index++ atoms_to_initialise += T - if (clear_contents && is_not_noop) - for (var/type_to_delete in types_to_delete()) - for (var/atom/pre_existing in crds) - if(crds != pre_existing.loc) // avoid deleting multitile objects unnecessarily, only check their 'real' loc - continue - if (istype(pre_existing, type_to_delete)) - atoms_to_delete |= pre_existing + if (clear_contents && is_not_noop && length(crds.contents)) + for (var/atom/movable/pre_existing as anything in crds) + if(!types_to_delete[pre_existing.type]) + continue + if(crds != pre_existing.loc) // avoid deleting multitile objects unnecessarily, only check their 'real' loc + continue + atoms_to_delete += pre_existing //finally instance all remainings objects/mobs for(index in 1 to first_turf_index-1) From 95a2c76f574ab758976eca11c0f3a35f2034510b Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Wed, 22 Jan 2025 11:45:34 +1100 Subject: [PATCH 097/120] Automatic changelog generation for PR #4739 [ci skip] --- html/changelogs/AutoChangeLog-pr-4739.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4739.yml diff --git a/html/changelogs/AutoChangeLog-pr-4739.yml b/html/changelogs/AutoChangeLog-pr-4739.yml new file mode 100644 index 000000000000..07f2fc3ce9aa --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4739.yml @@ -0,0 +1,4 @@ +author: MistakeNot4892 +changes: + - {tweak: Guns can now be fired from rigs regardless of dexterity.} +delete-after: true From c7fb19dca93ea7674a745152faeedaa122a59894 Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Wed, 22 Jan 2025 00:50:10 +0000 Subject: [PATCH 098/120] Automatic changelog generation [ci skip] --- html/changelog.html | 7 +++++++ html/changelogs/.all_changelog.yml | 4 ++++ html/changelogs/AutoChangeLog-pr-4712.yml | 4 ---- html/changelogs/AutoChangeLog-pr-4739.yml | 4 ---- 4 files changed, 11 insertions(+), 8 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-4712.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-4739.yml diff --git a/html/changelog.html b/html/changelog.html index 9b10adb50da0..23cae88f2087 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -52,6 +52,13 @@ -->
    +

    22 January 2025

    +

    MistakeNot4892 updated:

    +
      +
    • Swords on Shaded Hills can be sharpened using whetstones or grindstones.
    • +
    • Guns can now be fired from rigs regardless of dexterity.
    • +
    +

    21 January 2025

    Penelope Haze updated:

      diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 142b18620763..20e1bd55f284 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -14967,3 +14967,7 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. Penelope Haze: - tweak: Mud can now receive footprints with any reagent other than mud. No more conspicuously missing bloody footprints! +2025-01-22: + MistakeNot4892: + - tweak: Swords on Shaded Hills can be sharpened using whetstones or grindstones. + - tweak: Guns can now be fired from rigs regardless of dexterity. diff --git a/html/changelogs/AutoChangeLog-pr-4712.yml b/html/changelogs/AutoChangeLog-pr-4712.yml deleted file mode 100644 index cf23dbfe571a..000000000000 --- a/html/changelogs/AutoChangeLog-pr-4712.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: MistakeNot4892 -changes: - - {tweak: Swords on Shaded Hills can be sharpened using whetstones or grindstones.} -delete-after: true diff --git a/html/changelogs/AutoChangeLog-pr-4739.yml b/html/changelogs/AutoChangeLog-pr-4739.yml deleted file mode 100644 index 07f2fc3ce9aa..000000000000 --- a/html/changelogs/AutoChangeLog-pr-4739.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: MistakeNot4892 -changes: - - {tweak: Guns can now be fired from rigs regardless of dexterity.} -delete-after: true From e38f119380685a963978bb7b8613defcc70c85da Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 17 Jan 2025 02:10:38 -0500 Subject: [PATCH 099/120] Optimize ATMOS_CANPASS_TURF --- code/__defines/ZAS.dm | 32 ++++++++++++++------------------ code/modules/ZAS/Turf.dm | 4 ++-- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/code/__defines/ZAS.dm b/code/__defines/ZAS.dm index 59466d88b53d..6734ee68ffb1 100644 --- a/code/__defines/ZAS.dm +++ b/code/__defines/ZAS.dm @@ -57,29 +57,25 @@ } #ifdef MULTIZAS - -var/global/list/csrfz_check = list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST, NORTHUP, EASTUP, WESTUP, SOUTHUP, NORTHDOWN, EASTDOWN, WESTDOWN, SOUTHDOWN) -var/global/list/gzn_check = list(NORTH, SOUTH, EAST, WEST, UP, DOWN) +#define ZAS_CSRFZ_CHECK global.cornerdirsz +#define ZAS_GZN_CHECK global.cardinalz #define ATMOS_CANPASS_TURF(ret, A, B) \ if (A.blocks_air & AIR_BLOCKED || B.blocks_air & AIR_BLOCKED) { \ ret = BLOCKED; \ } \ - else if (B.z != A.z) { \ - if (B.z < A.z) { \ - ret = (A.z_flags & ZM_ALLOW_ATMOS) ? ZONE_BLOCKED : BLOCKED; \ - } \ - else { \ - ret = (B.z_flags & ZM_ALLOW_ATMOS) ? ZONE_BLOCKED : BLOCKED; \ - } \ + else if (B.z < A.z) { \ + ret = (A.z_flags & ZM_ALLOW_ATMOS) ? ZONE_BLOCKED : BLOCKED; \ } \ - else if (A.blocks_air & ZONE_BLOCKED || B.blocks_air & ZONE_BLOCKED) { \ - ret = (A.z == B.z) ? ZONE_BLOCKED : AIR_BLOCKED; \ + else if(B.z > A.z) { \ + ret = (B.z_flags & ZM_ALLOW_ATMOS) ? ZONE_BLOCKED : BLOCKED; \ } \ - else if (A.contents.len) { \ + else if ((A.blocks_air & ZONE_BLOCKED) || (B.blocks_air & ZONE_BLOCKED)) { \ + ret = ZONE_BLOCKED; \ + } \ + else if (length(A.contents)) { \ ret = 0;\ - for (var/thing in A) { \ - var/atom/movable/AM = thing; \ + for (var/atom/movable/AM as anything in A) { \ ATMOS_CANPASS_MOVABLE(ret, AM, B); \ if (ret == BLOCKED) { \ break;\ @@ -88,8 +84,8 @@ var/global/list/gzn_check = list(NORTH, SOUTH, EAST, WEST, UP, DOWN) } #else -var/global/list/csrfz_check = list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST) -var/global/list/gzn_check = list(NORTH, SOUTH, EAST, WEST) +#define ZAS_CSRFZ_CHECK global.cornerdirs +#define ZAS_GZN_CHECK global.cardinal #define ATMOS_CANPASS_TURF(ret, A, B) \ if (A.blocks_air & AIR_BLOCKED || B.blocks_air & AIR_BLOCKED) { \ @@ -98,7 +94,7 @@ var/global/list/gzn_check = list(NORTH, SOUTH, EAST, WEST) else if (A.blocks_air & ZONE_BLOCKED || B.blocks_air & ZONE_BLOCKED) { \ ret = ZONE_BLOCKED; \ } \ - else if (A.contents.len) { \ + else if (length(A.contents)) { \ ret = 0;\ for (var/thing in A) { \ var/atom/movable/AM = thing; \ diff --git a/code/modules/ZAS/Turf.dm b/code/modules/ZAS/Turf.dm index 823128586228..58f5e7b2e9de 100644 --- a/code/modules/ZAS/Turf.dm +++ b/code/modules/ZAS/Turf.dm @@ -167,7 +167,7 @@ #define GET_ZONE_NEIGHBOURS(T, ret) \ ret = 0; \ if (T.zone) { \ - for (var/_gzn_dir in gzn_check) { \ + for (var/_gzn_dir in ZAS_GZN_CHECK) { \ var/turf/other = get_step(T, _gzn_dir); \ if (istype(other) && other.simulated && other.zone == T.zone) { \ var/block; \ @@ -198,7 +198,7 @@ if (!(check_dirs & (check_dirs - 1))) //Equivalent to: if(IsInteger(log(2, .))) return TRUE - for(var/dir in global.csrfz_check) + for(var/dir in ZAS_CSRFZ_CHECK) //for each pair of "adjacent" cardinals (e.g. NORTH and WEST, but not NORTH and SOUTH) if((dir & check_dirs) == dir) //check that they are connected by the corner turf From ac7e52d62c2518ad2845b93675faba78fcb071d4 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 17 Jan 2025 02:11:44 -0500 Subject: [PATCH 100/120] Optimize update_air_properties and its callsites --- code/controllers/subsystems/air.dm | 16 ++++++++++++---- code/game/turfs/turf.dm | 2 +- code/game/turfs/turf_changing.dm | 26 +++++++++++++------------- code/modules/ZAS/Turf.dm | 4 ++-- 4 files changed, 28 insertions(+), 20 deletions(-) diff --git a/code/controllers/subsystems/air.dm b/code/controllers/subsystems/air.dm index 4da8abb538d8..92e3271df809 100644 --- a/code/controllers/subsystems/air.dm +++ b/code/controllers/subsystems/air.dm @@ -138,7 +138,13 @@ SUBSYSTEM_DEF(air) if(!SHOULD_PARTICIPATE_IN_ZONES(T)) continue simulated_turf_count++ + // We also skip anything already queued, since it'll be settled when fire() runs anyway. + if(T.needs_air_update) + continue T.update_air_properties() + // air state is necessarily globally incomplete during this + // so we can't do T.post_update_air_properties(), which needs + // connections to have been settled already. CHECK_TICK report_progress({"Total Simulated Turfs: [simulated_turf_count] @@ -198,7 +204,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun T.update_air_properties() T.post_update_air_properties() - T.needs_air_update = 0 + T.needs_air_update = FALSE #ifdef ZASDBG T.remove_vis_contents(zasdbgovl_mark) #endif @@ -214,7 +220,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun T.update_air_properties() T.post_update_air_properties() - T.needs_air_update = 0 + T.needs_air_update = FALSE #ifdef ZASDBG T.remove_vis_contents(zasdbgovl_mark) #endif @@ -368,13 +374,15 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun #ifdef ZASDBG ASSERT(isturf(T)) #endif - if(T.needs_air_update) + // don't queue us if we've already been queued + // and if SSair hasn't run, every turf in the world will get updated soon anyway + if(T.needs_air_update || !SSair.initialized) return tiles_to_update += T #ifdef ZASDBG T.add_vis_contents(zasdbgovl_mark) #endif - T.needs_air_update = 1 + T.needs_air_update = TRUE /datum/controller/subsystem/air/proc/mark_zone_update(zone/Z) #ifdef ZASDBG diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index b0722530f68c..152b1ac63a01 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -534,7 +534,7 @@ if(below) below.update_weather(new_weather) -// Updates turf participation in ZAS according to outside status. Must be called whenever the outside status of a turf may change. +/// Updates turf participation in ZAS according to outside status and atmosphere participation bools. Must be called whenever any of those values may change. /turf/proc/update_external_atmos_participation() var/old_outside = last_outside_check last_outside_check = OUTSIDE_UNCERTAIN diff --git a/code/game/turfs/turf_changing.dm b/code/game/turfs/turf_changing.dm index 670cb3128440..19db7607c2ec 100644 --- a/code/game/turfs/turf_changing.dm +++ b/code/game/turfs/turf_changing.dm @@ -152,24 +152,24 @@ // end of lighting stuff - // In case the turf isn't marked for update in Initialize (e.g. space), we call this to create any unsimulated edges necessary. - if(W.zone_membership_candidate != old_zone_membership_candidate) - SSair.mark_for_update(src) - // we check the var rather than the proc, because area outside values usually shouldn't be set on turfs W.last_outside_check = OUTSIDE_UNCERTAIN if(W.is_outside != old_outside) // This will check the exterior atmos participation of this turf and all turfs connected by open space below. W.set_outside(old_outside, skip_weather_update = TRUE) - else if(HasBelow(z) && (W.is_open() != old_is_open)) // Otherwise, we do it here if the open status of the turf has changed. - var/turf/checking = src - while(HasBelow(checking.z)) - checking = GetBelow(checking) - if(!isturf(checking)) - break - checking.update_external_atmos_participation() - if(!checking.is_open()) - break + else // We didn't already update our external atmos participation in set_outside. + if(HasBelow(z) && (W.is_open() != old_is_open)) // Otherwise, we do it here if the open status of the turf has changed. + var/turf/checking = src + while(HasBelow(checking.z)) + checking = GetBelow(checking) + if(!isturf(checking)) + break + checking.update_external_atmos_participation() + if(!checking.is_open()) + break + // In case the turf isn't marked for update in Initialize (e.g. space), we call this to create any unsimulated edges necessary. + if(W.zone_membership_candidate != old_zone_membership_candidate) + update_external_atmos_participation() W.update_weather(force_update_below = W.is_open() != old_is_open) diff --git a/code/modules/ZAS/Turf.dm b/code/modules/ZAS/Turf.dm index 58f5e7b2e9de..016d69b4c53e 100644 --- a/code/modules/ZAS/Turf.dm +++ b/code/modules/ZAS/Turf.dm @@ -35,9 +35,9 @@ var/list/postponed #ifdef MULTIZAS - for(var/d = 1, d < 64, d *= 2) + for(var/d in global.cardinalz) #else - for(var/d = 1, d < 16, d *= 2) + for(var/d in global.cardinal) #endif var/turf/unsim = get_step(src, d) From 252e4980ff5dd7617b7b7bbe29b518b2ee1e038a Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 17 Jan 2025 02:12:00 -0500 Subject: [PATCH 101/120] Stub out alpha mask logic for unsim turfs --- code/game/turfs/unsimulated.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/game/turfs/unsimulated.dm b/code/game/turfs/unsimulated.dm index 67200a23bf89..45e70ce956e8 100644 --- a/code/game/turfs/unsimulated.dm +++ b/code/game/turfs/unsimulated.dm @@ -25,3 +25,6 @@ /turf/unsimulated/get_lumcount(var/minlum = 0, var/maxlum = 1) return 0.8 + +/turf/unsimulated/get_movable_alpha_mask_state(atom/movable/mover) + return null From edd3b79706547371dfe3f53b2a5fcc9c090c8162 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 17 Jan 2025 16:16:02 -0500 Subject: [PATCH 102/120] Optimize _fetch_icon_state_cache_entry --- code/game/objects/item_mob_overlay.dm | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/code/game/objects/item_mob_overlay.dm b/code/game/objects/item_mob_overlay.dm index fe253ea6f0bb..5739ddef4b1a 100644 --- a/code/game/objects/item_mob_overlay.dm +++ b/code/game/objects/item_mob_overlay.dm @@ -45,13 +45,15 @@ var/global/list/icon_state_cache = list() /proc/_fetch_icon_state_cache_entry(checkicon) if(isnull(checkicon) || !(isfile(checkicon) || isicon(checkicon))) return null - var/checkkey = "\ref[checkicon]" - var/list/check = global.icon_state_cache[checkkey] + // if we want to let people del icons (WHY???) then we can use weakreF() + // but right now it's cheaper to just use checkicon directly + // ref doesn't even do any deduplication + var/list/check = global.icon_state_cache[checkicon] if(!check) check = list() for(var/istate in icon_states(checkicon)) check[istate] = TRUE - global.icon_state_cache[checkkey] = check + global.icon_state_cache[checkicon] = check return check /obj/item/proc/update_world_inventory_state() From 3fccc7e24e4029210a638f81f9b6bcc0495abefc Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 23 Jan 2025 14:25:53 +1100 Subject: [PATCH 103/120] Fixing borer infestation logic. --- .../modules/mob/living/human/human_defense.dm | 14 ----- code/modules/mob/mob_eating.dm | 13 ++++- mods/mobs/borers/mob/borer/borer_attacks.dm | 58 +++++++++---------- mods/mobs/borers/mob/borer/borer_hud.dm | 1 + 4 files changed, 38 insertions(+), 48 deletions(-) diff --git a/code/modules/mob/living/human/human_defense.dm b/code/modules/mob/living/human/human_defense.dm index 1014326d2176..30ea13667b6d 100644 --- a/code/modules/mob/living/human/human_defense.dm +++ b/code/modules/mob/living/human/human_defense.dm @@ -85,20 +85,6 @@ meteor_act // Add inherent armor to the end of list so that protective equipment is checked first . += ..() -/mob/living/human/proc/check_head_coverage() - for(var/slot in global.standard_headgear_slots) - var/obj/item/clothing/clothes = get_equipped_item(slot) - if(istype(clothes) && (clothes.body_parts_covered & SLOT_HEAD)) - return TRUE - return FALSE - -//Used to check if they can be fed food/drinks/pills -/mob/living/human/check_mouth_coverage() - for(var/slot in global.standard_headgear_slots) - var/obj/item/gear = get_equipped_item(slot) - if(istype(gear) && (gear.body_parts_covered & SLOT_FACE) && !(gear.item_flags & ITEM_FLAG_FLEXIBLEMATERIAL)) - return gear - /mob/living/human/resolve_item_attack(obj/item/I, mob/living/user, var/target_zone) for (var/obj/item/grab/grab as anything in grabbed_by) diff --git a/code/modules/mob/mob_eating.dm b/code/modules/mob/mob_eating.dm index 2d9170878b8f..c4fb19e2854e 100644 --- a/code/modules/mob/mob_eating.dm +++ b/code/modules/mob/mob_eating.dm @@ -1,6 +1,15 @@ -// mobs do not have blocked mouths by default -// overridden in human_defense.dm +//Used to check if they can be fed food/drinks/pills /mob/proc/check_mouth_coverage() + return get_covering_head_item(SLOT_FACE) + +/mob/proc/check_head_coverage() + return !!get_covering_head_item(SLOT_HEAD) + +/mob/proc/get_covering_head_item(slot_flags) + for(var/slot in global.standard_headgear_slots) + var/obj/item/clothes = get_equipped_item(slot) + if(istype(clothes) && (clothes.body_parts_covered & slot_flags) && !(clothes.item_flags & ITEM_FLAG_FLEXIBLEMATERIAL)) + return clothes return null /mob/proc/get_eaten_transfer_amount(var/default) diff --git a/mods/mobs/borers/mob/borer/borer_attacks.dm b/mods/mobs/borers/mob/borer/borer_attacks.dm index 43358767a9ef..1cd2b76ceaf8 100644 --- a/mods/mobs/borers/mob/borer/borer_attacks.dm +++ b/mods/mobs/borers/mob/borer/borer_attacks.dm @@ -1,50 +1,44 @@ /mob/living/simple_animal/borer/UnarmedAttack(atom/A, proximity) - . = ..() - if(.) - return + if(host) + return TRUE // We cannot click things outside of our host. - if(!isliving(A) || a_intent != I_GRAB) - return FALSE + if(!isliving(A) || a_intent != I_GRAB || stat || !proximity) + return ..() - if(host || !can_use_borer_ability(requires_host_value = FALSE, check_last_special = FALSE)) - return FALSE + if(!can_use_borer_ability(requires_host_value = FALSE, check_last_special = FALSE)) + return TRUE - var/mob/living/M = A - if(M.has_brain_worms()) + var/mob/living/victim = A + if(victim.has_brain_worms()) to_chat(src, SPAN_WARNING("You cannot take a host who already has a passenger!")) return TRUE - - //TODO generalize borers to enter any mob. Until then, return early. - if(!ishuman(M)) - to_chat(src, SPAN_WARNING("This creature is not sufficiently intelligent to host you.")) + var/obj/item/organ/external/limb = GET_EXTERNAL_ORGAN(victim, BP_HEAD) + if(!limb) + to_chat(src, SPAN_WARNING("\The [victim] does not have anatomy compatible with your lifecycle!")) return TRUE - // end TODO - - var/mob/living/human/H = M - var/obj/item/organ/external/E = GET_EXTERNAL_ORGAN(H, BP_HEAD) - if(!E) - to_chat(src, SPAN_WARNING("\The [H] does not have a head!")) + if(BP_IS_PROSTHETIC(limb)) + to_chat(src, SPAN_WARNING("\The [victim]'s head is prosthetic and cannot support your lifecycle!")) return TRUE - if(!H.should_have_organ(BP_BRAIN)) - to_chat(src, SPAN_WARNING("\The [H] does not seem to have a brain cavity to enter.")) + if(!victim.should_have_organ(BP_BRAIN)) + to_chat(src, SPAN_WARNING("\The [victim] does not seem to have a brain cavity to enter.")) return TRUE - if(H.check_head_coverage()) + if(victim.check_head_coverage()) to_chat(src, SPAN_WARNING("You cannot get through that host's protective gear.")) return TRUE - to_chat(M, SPAN_WARNING("Something slimy begins probing at the opening of your ear canal...")) - to_chat(src, SPAN_NOTICE("You slither up [M] and begin probing at their ear canal...")) + to_chat(victim, SPAN_WARNING("Something slimy begins probing at the opening of your ear canal...")) + to_chat(src, SPAN_NOTICE("You slither up [victim] and begin probing at their ear canal...")) set_ability_cooldown(5 SECONDS) - if(!do_after(src, 3 SECONDS, M)) + if(!do_after(src, 3 SECONDS, victim) || host || GET_EXTERNAL_ORGAN(victim, BP_HEAD) != limb || BP_IS_PROSTHETIC(limb) || victim.check_head_coverage()) return TRUE - to_chat(src, SPAN_NOTICE("You wiggle into \the [M]'s ear.")) - if(M.stat == CONSCIOUS) - to_chat(M, SPAN_DANGER("Something wet, cold and slimy wiggles into your ear!")) + to_chat(src, SPAN_NOTICE("You wiggle into \the [victim]'s ear.")) + if(victim.stat == CONSCIOUS) + to_chat(victim, SPAN_DANGER("Something wet, cold and slimy wiggles into your ear!")) - host = M + host = victim host.status_flags |= PASSEMOTES forceMove(host) @@ -60,9 +54,9 @@ borers.add_antagonist_mind(host.mind, 1, borers.faction_name, borers.faction_welcome) if(ishuman(host)) - var/obj/item/organ/internal/I = GET_INTERNAL_ORGAN(H, BP_BRAIN) + var/obj/item/organ/internal/I = GET_INTERNAL_ORGAN(victim, BP_BRAIN) if(!I) // No brain organ, so the borer moves in and replaces it permanently. replace_brain() - else if(E) // If they're in normally, implant removal can get them out. - LAZYDISTINCTADD(E.implants, src) + else if(limb) // If they're in normally, implant removal can get them out. + LAZYDISTINCTADD(limb.implants, src) return TRUE diff --git a/mods/mobs/borers/mob/borer/borer_hud.dm b/mods/mobs/borers/mob/borer/borer_hud.dm index 8b9a155e5d43..ff0479086ad0 100644 --- a/mods/mobs/borers/mob/borer/borer_hud.dm +++ b/mods/mobs/borers/mob/borer/borer_hud.dm @@ -50,6 +50,7 @@ icon = 'mods/mobs/borers/icons/borer_ui.dmi' alpha = 0 invisibility = INVISIBILITY_MAXIMUM + requires_ui_style = FALSE /obj/screen/borer/handle_click(mob/user, params) if(!isborer(user)) From e6f947baf776d0a10e87ac6ff9a5d3fa9397fb05 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 23 Jan 2025 15:46:16 +1100 Subject: [PATCH 104/120] Updating holster code, adding quick interaction for holsters and holster accessories. --- code/_onclick/click.dm | 4 +- code/datums/extensions/holster/holster.dm | 63 ++++++++++++++++++- .../objects/items/weapons/storage/belt.dm | 37 +++++------ code/modules/clothing/webbing/holster.dm | 17 +++-- 4 files changed, 86 insertions(+), 35 deletions(-) diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 96c1880c8289..42298a21d64c 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -282,10 +282,10 @@ return A.CtrlClick(src) /atom/proc/CtrlClick(var/mob/user) - if(loc == user) + if(get_recursive_loc_of_type(/mob) == user) var/decl/interaction_handler/handler = get_quick_interaction_handler(user) if(handler) - var/using_item = user.get_active_held_item() || user.get_usable_hand_slot_organ() + var/using_item = user.get_active_held_item() if(handler.is_possible(src, user, using_item)) return handler.invoked(src, user, using_item) return FALSE diff --git a/code/datums/extensions/holster/holster.dm b/code/datums/extensions/holster/holster.dm index f83a5ac67a9b..88ddb7399b93 100644 --- a/code/datums/extensions/holster/holster.dm +++ b/code/datums/extensions/holster/holster.dm @@ -111,7 +111,7 @@ to_chat(user, "It is empty.") /datum/extension/holster/proc/check_holster() - if(holstered.loc != storage) + if(holstered.loc != storage.holder) clear_holster() /atom/proc/holster_verb(var/holster_name in get_holsters()) @@ -154,4 +154,63 @@ else for(var/i = 1 to holster_accessories.len) var/holster_name = "[accessory_name] [i]" - .[holster_name] = get_extension(holster_accessories[i], /datum/extension/holster) \ No newline at end of file + .[holster_name] = get_extension(holster_accessories[i], /datum/extension/holster) + +// Basic unholster for an item at the top level. +/decl/interaction_handler/unholster + name = "Unholster" + +/decl/interaction_handler/unholster/is_possible(atom/target, mob/user, obj/item/prop) + . = ..() && !prop + if(.) + var/datum/extension/holster/holster = get_extension(target, /datum/extension/holster) + return !!holster?.holstered + +/decl/interaction_handler/unholster/invoked(atom/target, mob/user, obj/item/prop) + var/datum/extension/holster/holster = get_extension(target, /datum/extension/holster) + return holster?.unholster(user, avoid_intent = TRUE) + +// Interaction procs for getting this interaction for basic items. +/obj/item/get_quick_interaction_handler(mob/user) + if(!(. = ..())) + var/datum/extension/holster/holster = get_extension(src, /datum/extension/holster) + if(holster?.holstered) + return GET_DECL(/decl/interaction_handler/unholster) + +// More complex version of the above that iterates clothing accessories. +/decl/interaction_handler/unholster_accessory + name = "Unholster From Accessory" + expected_target_type = /obj/item/clothing + +/decl/interaction_handler/unholster_accessory/is_possible(atom/target, mob/user, obj/item/prop) + . = ..() && !prop + if(.) + var/obj/item/clothing/clothes = target + for(var/obj/item/thing in clothes.accessories) + var/datum/extension/holster/holster = get_extension(thing, /datum/extension/holster) + if(holster?.holstered) + return TRUE + return FALSE + +/decl/interaction_handler/unholster_accessory/invoked(atom/target, mob/user, obj/item/prop) + var/obj/item/clothing/clothes = target + for(var/obj/item/thing in clothes.accessories) + var/datum/extension/holster/holster = get_extension(thing, /datum/extension/holster) + if(holster?.unholster(user, avoid_intent = TRUE)) + return TRUE + return FALSE + +// Interaction procs for getting this interaction for clothing accessories. +/obj/item/clothing/get_alt_interactions(mob/user) + . = ..() + for(var/obj/item/thing in accessories) + var/datum/extension/holster/holster = get_extension(thing, /datum/extension/holster) + if(holster?.holstered) + LAZYADD(., GET_DECL(/decl/interaction_handler/unholster_accessory)) + +/obj/item/clothing/get_quick_interaction_handler(mob/user) + if(!(. = ..())) + for(var/obj/item/thing in accessories) + var/datum/extension/holster/holster = get_extension(thing, /datum/extension/holster) + if(holster?.holstered) + return GET_DECL(/decl/interaction_handler/unholster_accessory) diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index 641a512ce20d..e53ef9f89e04 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -24,11 +24,11 @@ . = ..() if(overlay_flags & BELT_OVERLAY_ITEMS) var/list/cur_overlays - for(var/obj/item/I in contents) - if(I.use_single_icon) - LAZYADD(cur_overlays, I.get_on_belt_overlay()) + for(var/obj/item/thing in contents) + if(thing.use_single_icon) + LAZYADD(cur_overlays, thing.get_on_belt_overlay()) else - LAZYADD(cur_overlays, overlay_image('icons/obj/clothing/obj_belt_overlays.dmi', I.icon_state)) + LAZYADD(cur_overlays, overlay_image('icons/obj/clothing/obj_belt_overlays.dmi', thing.icon_state)) if(LAZYLEN(cur_overlays)) add_overlay(cur_overlays) @@ -37,8 +37,8 @@ /obj/item/belt/get_mob_overlay(mob/user_mob, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_adjustment = FALSE) var/image/ret = ..() if(ret && slot == slot_belt_str && length(contents)) - for(var/obj/item/I in contents) - var/image/new_overlay = I.get_mob_overlay(user_mob, slot, bodypart, use_fallback_if_icon_missing, TRUE) + for(var/obj/item/thing in contents) + var/image/new_overlay = thing.get_mob_overlay(user_mob, slot, bodypart, use_fallback_if_icon_missing, TRUE) if(new_overlay) ret.overlays += new_overlay return ret @@ -57,13 +57,6 @@ . = ..() set_extension(src, /datum/extension/holster, storage, sound_in, sound_out, can_holster) -/obj/item/belt/holster/get_stored_inventory() - . = ..() - if(length(.)) - var/datum/extension/holster/holster = get_extension(src, /datum/extension/holster) - if(holster.holstered) - . -= holster.holstered - /obj/item/belt/holster/attackby(obj/item/used_item, mob/user) var/datum/extension/holster/holster = get_extension(src, /datum/extension/holster) if(holster?.holster(used_item, user)) @@ -73,27 +66,27 @@ /obj/item/belt/holster/attack_hand(mob/user) if(!user.check_dexterity(DEXTERITY_HOLD_ITEM, TRUE)) return ..() - var/datum/extension/holster/H = get_extension(src, /datum/extension/holster) - if(H.unholster(user)) + var/datum/extension/holster/holster = get_extension(src, /datum/extension/holster) + if(holster?.unholster(user)) return TRUE return ..() /obj/item/belt/holster/examine(mob/user) . = ..() - var/datum/extension/holster/H = get_extension(src, /datum/extension/holster) - H.examine_holster(user) + var/datum/extension/holster/holster = get_extension(src, /datum/extension/holster) + holster.examine_holster(user) /obj/item/belt/holster/on_update_icon() . = ..() - var/datum/extension/holster/H = get_extension(src, /datum/extension/holster) + var/datum/extension/holster/holster = get_extension(src, /datum/extension/holster) if(overlay_flags) var/list/cur_overlays - for(var/obj/item/I in contents) - if(I == H.holstered) + for(var/obj/item/thing in contents) + if(thing == holster.holstered) if(overlay_flags & BELT_OVERLAY_HOLSTER) - LAZYADD(cur_overlays, overlay_image('icons/obj/clothing/obj_belt_overlays.dmi', I.icon_state)) + LAZYADD(cur_overlays, overlay_image('icons/obj/clothing/obj_belt_overlays.dmi', thing.icon_state)) else if(overlay_flags & BELT_OVERLAY_ITEMS) - LAZYADD(cur_overlays, overlay_image('icons/obj/clothing/obj_belt_overlays.dmi', I.icon_state)) + LAZYADD(cur_overlays, overlay_image('icons/obj/clothing/obj_belt_overlays.dmi', thing.icon_state)) if(LAZYLEN(cur_overlays)) add_overlay(cur_overlays) diff --git a/code/modules/clothing/webbing/holster.dm b/code/modules/clothing/webbing/holster.dm index 47ca037c939e..1d49eaabc2b7 100644 --- a/code/modules/clothing/webbing/holster.dm +++ b/code/modules/clothing/webbing/holster.dm @@ -12,25 +12,24 @@ . = ..() set_extension(src, /datum/extension/holster, storage, sound_in, sound_out, can_holster) -/obj/item/clothing/webbing/holster/attackby(obj/item/W, mob/user) - var/datum/extension/holster/H = get_extension(src, /datum/extension/holster) - if(H.holster(W, user)) +/obj/item/clothing/webbing/holster/attackby(obj/item/used_item, mob/user) + var/datum/extension/holster/holster = get_extension(src, /datum/extension/holster) + if(holster.holster(used_item, user)) return TRUE - else - . = ..(W, user) + return ..(used_item, user) /obj/item/clothing/webbing/holster/attack_hand(mob/user) if(!user.check_dexterity(DEXTERITY_HOLD_ITEM, TRUE)) return ..() - var/datum/extension/holster/H = get_extension(src, /datum/extension/holster) - if(H.unholster(user)) + var/datum/extension/holster/holster = get_extension(src, /datum/extension/holster) + if(holster.unholster(user)) return TRUE return ..() /obj/item/clothing/webbing/holster/examine(mob/user) . = ..(user) - var/datum/extension/holster/H = get_extension(src, /datum/extension/holster) - H.examine_holster(user) + var/datum/extension/holster/holster = get_extension(src, /datum/extension/holster) + holster.examine_holster(user) /obj/item/clothing/webbing/holster/on_attached(var/obj/item/clothing/holder, var/mob/user) . = ..() From de4df0c44bcb853a9b5124c2716252baefdec573 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 23 Jan 2025 16:42:59 +1100 Subject: [PATCH 105/120] Cleaning up HE pipes. --- .../components/unary/heat_exchanger.dm | 2 +- code/modules/atmospherics/datum_pipeline.dm | 66 ++++----- code/modules/atmospherics/he_pipes.dm | 131 +++++++++--------- 3 files changed, 97 insertions(+), 102 deletions(-) diff --git a/code/modules/atmospherics/components/unary/heat_exchanger.dm b/code/modules/atmospherics/components/unary/heat_exchanger.dm index 30849bc53b92..f19c4ecb4f74 100644 --- a/code/modules/atmospherics/components/unary/heat_exchanger.dm +++ b/code/modules/atmospherics/components/unary/heat_exchanger.dm @@ -4,7 +4,7 @@ icon_state = "intact" density = TRUE - name = "Heat Exchanger" + name = "heat exchanger" desc = "Exchanges heat between two input gases. Setup for fast heat transfer." var/obj/machinery/atmospherics/unary/heat_exchanger/partner = null diff --git a/code/modules/atmospherics/datum_pipeline.dm b/code/modules/atmospherics/datum_pipeline.dm index 51634ba2d586..55a58d0138fe 100644 --- a/code/modules/atmospherics/datum_pipeline.dm +++ b/code/modules/atmospherics/datum_pipeline.dm @@ -193,13 +193,23 @@ network.update = 1 /datum/pipeline/proc/temperature_interact(turf/target, share_volume, thermal_conductivity) + + if(air.volume <= 0) // Avoid div by zero. + return + var/total_heat_capacity = air.heat_capacity() var/partial_heat_capacity = total_heat_capacity*(share_volume/air.volume) + if(total_heat_capacity <= 0) // Avoid div by zero. + return + if(SHOULD_PARTICIPATE_IN_ZONES(target) && !target.blocks_air) + + if(partial_heat_capacity <= 0) + return + var/delta_temperature = 0 var/sharer_heat_capacity = 0 - if(target.zone) delta_temperature = (air.temperature - target.zone.air.temperature) sharer_heat_capacity = target.zone.air.heat_capacity() @@ -207,18 +217,14 @@ delta_temperature = (air.temperature - target.air.temperature) sharer_heat_capacity = target.air.heat_capacity() + if(sharer_heat_capacity <= 0) + return + var/self_temperature_delta = 0 var/sharer_temperature_delta = 0 - - if((sharer_heat_capacity > 0) && (partial_heat_capacity > 0)) - var/heat = thermal_conductivity*delta_temperature* \ - (partial_heat_capacity*sharer_heat_capacity/(partial_heat_capacity+sharer_heat_capacity)) - - self_temperature_delta = -heat/total_heat_capacity - sharer_temperature_delta = heat/sharer_heat_capacity - else - return 1 - + var/heat = thermal_conductivity * delta_temperature * ( partial_heat_capacity * sharer_heat_capacity / (partial_heat_capacity + sharer_heat_capacity) ) + self_temperature_delta = -heat/total_heat_capacity + sharer_temperature_delta = heat/sharer_heat_capacity air.temperature += self_temperature_delta if(target.zone) @@ -228,33 +234,29 @@ else if(target.external_atmosphere_participation && !target.blocks_air) - var/turf/modeled_location = target - var/datum/gas_mixture/target_air = modeled_location.return_air() + if(partial_heat_capacity <= 0) + return - var/delta_temperature = air.temperature - target_air.temperature - var/sharer_heat_capacity = target_air.heat_capacity() + var/datum/gas_mixture/target_air = target.return_air() + var/sharer_heat_capacity = target_air?.heat_capacity() - if((sharer_heat_capacity > 0) && (partial_heat_capacity > 0)) - var/heat = thermal_conductivity*delta_temperature* \ - (partial_heat_capacity*sharer_heat_capacity/(partial_heat_capacity+sharer_heat_capacity)) - air.temperature += -heat/total_heat_capacity - else - return 1 + if(sharer_heat_capacity <= 0) + return - else - if((target.heat_capacity > 0) && (partial_heat_capacity > 0)) - var/delta_temperature = air.temperature - target.temperature - - var/heat = thermal_conductivity*delta_temperature* \ - (partial_heat_capacity*target.heat_capacity/(partial_heat_capacity+target.heat_capacity)) + var/delta_temperature = air.temperature - target_air.temperature + var/heat = thermal_conductivity * delta_temperature * ( partial_heat_capacity * sharer_heat_capacity / (partial_heat_capacity+sharer_heat_capacity) ) + air.temperature += -heat/total_heat_capacity - air.temperature -= heat/total_heat_capacity - // Only increase the temperature of the target if it's simulated. - if(target.simulated) - target.temperature += heat/target.heat_capacity + else if((target.heat_capacity > 0) && (partial_heat_capacity > 0)) + var/delta_temperature = air.temperature - target.temperature + var/heat = thermal_conductivity * delta_temperature * ( partial_heat_capacity * target.heat_capacity / (partial_heat_capacity + target.heat_capacity) ) + air.temperature -= heat/total_heat_capacity + // Only increase the temperature of the target if it's simulated. + if(target.simulated) + target.temperature += heat/target.heat_capacity if(network) - network.update = 1 + network.update = TRUE //surface must be the surface area in m^2 /datum/pipeline/proc/radiate_heat_to_space(surface, thermal_conductivity) diff --git a/code/modules/atmospherics/he_pipes.dm b/code/modules/atmospherics/he_pipes.dm index 55afc98fd37f..380adf9245f4 100644 --- a/code/modules/atmospherics/he_pipes.dm +++ b/code/modules/atmospherics/he_pipes.dm @@ -1,28 +1,26 @@ /obj/machinery/atmospherics/pipe/simple/heat_exchanging - icon = 'icons/atmos/heat.dmi' - icon_state = "11" - color = "#404040" - pipe_color = "#404040" - level = LEVEL_ABOVE_PLATING - connect_types = CONNECT_TYPE_HE + icon = 'icons/atmos/heat.dmi' + icon_state = "11" + color = "#404040" + pipe_color = "#404040" + level = LEVEL_ABOVE_PLATING + connect_types = CONNECT_TYPE_HE interact_offline = TRUE //Needs to be set so that pipes don't say they lack power in their description - var/initialize_directions_he - var/surface = 2 //surface area in m^2 - var/icon_temperature = T20C //stop small changes in temperature causing an icon refresh build_icon_state = "he" - atom_flags = 0 // no painting + atom_flags = 0 // no painting + maximum_pressure = 360 ATM + fatigue_pressure = 300 ATM + can_buckle = TRUE + buckle_lying = TRUE appearance_flags = KEEP_TOGETHER + var/initialize_directions_he + var/surface = 2 //surface area in m^2 + var/icon_temperature = T20C //stop small changes in temperature causing an icon refresh var/thermal_conductivity = OPEN_HEAT_TRANSFER_COEFFICIENT var/minimum_temperature_difference = 20 - maximum_pressure = 360 ATM - fatigue_pressure = 300 ATM - - can_buckle = 1 - buckle_lying = 1 - /obj/machinery/atmospherics/pipe/simple/heat_exchanging/Initialize() . = ..() add_filter("glow",1, list(type = "drop_shadow", x = 0, y = 0, offset = 0, size = 4)) @@ -57,62 +55,57 @@ update_icon() /obj/machinery/atmospherics/pipe/simple/heat_exchanging/Process() + if(!parent) ..() - else - var/turf/turf = loc - var/datum/gas_mixture/pipe_air = return_air() - if(istype(loc, /turf/space)) - parent.radiate_heat_to_space(surface, 1) - else if(istype(turf) && turf.simulated) - var/turf/pipe_turf = loc - var/environment_temperature = 0 - if(pipe_turf.blocks_air) - environment_temperature = pipe_turf.temperature - else - var/datum/gas_mixture/environment = pipe_turf.return_air() - environment_temperature = environment.temperature - if(abs(environment_temperature-pipe_air.temperature) > minimum_temperature_difference) - parent.temperature_interact(pipe_turf, volume, thermal_conductivity) - - if(buckled_mob) - var/hc = pipe_air.heat_capacity() - var/avg_temp = (pipe_air.temperature * hc + buckled_mob.bodytemperature * 3500) / (hc + 3500) - pipe_air.temperature = avg_temp - buckled_mob.bodytemperature = avg_temp - - var/heat_limit = 1000 - - var/mob/living/human/H = buckled_mob - if(istype(H) && H.species) - heat_limit = H.get_mob_temperature_threshold(HEAT_LEVEL_3) - - if(pipe_air.temperature > heat_limit + 1) - buckled_mob.apply_damage(4 * log(pipe_air.temperature - heat_limit), BURN, BP_CHEST, used_weapon = "Excessive Heat") - - //fancy radiation glowing - if(pipe_air.temperature && (icon_temperature > 500 || pipe_air.temperature > 500)) //start glowing at 500K - if(abs(pipe_air.temperature - icon_temperature) > 10) - icon_temperature = pipe_air.temperature - var/scale = max((icon_temperature - 500) / 1500, 0) - - var/h_r = heat2color_r(icon_temperature) - var/h_g = heat2color_g(icon_temperature) - var/h_b = heat2color_b(icon_temperature) - - if(icon_temperature < 2000) //scale up overlay until 2000K - h_r = 64 + (h_r - 64)*scale - h_g = 64 + (h_g - 64)*scale - h_b = 64 + (h_b - 64)*scale - var/scale_color = rgb(h_r, h_g, h_b) - var/list/animate_targets = get_above_oo() + src - for (var/thing in animate_targets) - var/atom/movable/AM = thing - animate(AM, color = scale_color, time = 2 SECONDS, easing = SINE_EASING) - animate_filter("glow", list(color = scale_color, time = 2 SECONDS, easing = LINEAR_EASING)) - set_light(min(3, scale*2.5), min(3, scale*2.5), scale_color) + return + + // Handle pipe heat exchange. + var/turf/turf = loc + var/datum/gas_mixture/pipe_air = return_air() + if(istype(loc, /turf/space)) + parent.radiate_heat_to_space(surface, 1) + else if(istype(turf) && turf.simulated) + var/environment_temperature = 0 + if(turf.blocks_air) + environment_temperature = turf.temperature else - set_light(0, 0) + var/datum/gas_mixture/environment = turf.return_air() + environment_temperature = environment?.temperature || 0 + if(abs(environment_temperature-pipe_air.temperature) > minimum_temperature_difference) + parent.temperature_interact(turf, volume, thermal_conductivity) + + // Burn mobs buckled to this pipe. + if(buckled_mob) + var/hc = pipe_air.heat_capacity() + var/avg_temp = (pipe_air.temperature * hc + buckled_mob.bodytemperature * 3500) / (hc + 3500) + pipe_air.temperature = avg_temp + buckled_mob.bodytemperature = avg_temp + var/heat_limit = buckled_mob.get_mob_temperature_threshold(HEAT_LEVEL_3) + if(pipe_air.temperature > heat_limit + 1) + buckled_mob.apply_damage(4 * log(pipe_air.temperature - heat_limit), BURN, BP_CHEST, used_weapon = "Excessive Heat") + + //fancy radiation glowing + if(pipe_air.temperature && (icon_temperature > 500 || pipe_air.temperature > 500)) //start glowing at 500K + if(abs(pipe_air.temperature - icon_temperature) > 10) + icon_temperature = pipe_air.temperature + var/scale = max((icon_temperature - 500) / 1500, 0) + var/h_r = heat2color_r(icon_temperature) + var/h_g = heat2color_g(icon_temperature) + var/h_b = heat2color_b(icon_temperature) + if(icon_temperature < 2000) //scale up overlay until 2000K + h_r = 64 + (h_r - 64)*scale + h_g = 64 + (h_g - 64)*scale + h_b = 64 + (h_b - 64)*scale + var/scale_color = rgb(h_r, h_g, h_b) + var/list/animate_targets = get_above_oo() + src + for (var/thing in animate_targets) + var/atom/movable/AM = thing + animate(AM, color = scale_color, time = 2 SECONDS, easing = SINE_EASING) + animate_filter("glow", list(color = scale_color, time = 2 SECONDS, easing = LINEAR_EASING)) + set_light(min(3, scale*2.5), min(3, scale*2.5), scale_color) + else + set_light(0, 0) /obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction icon = 'icons/atmos/junction.dmi' From 6992db4bd50ae945f0bba7e4928c0cf012b008a6 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 23 Jan 2025 17:29:55 +1100 Subject: [PATCH 106/120] Prevents borers moving in a host from breaking them completely. --- mods/mobs/borers/mob/borer/borer.dm | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/mods/mobs/borers/mob/borer/borer.dm b/mods/mobs/borers/mob/borer/borer.dm index 5529384f7741..6fe781f44d13 100644 --- a/mods/mobs/borers/mob/borer/borer.dm +++ b/mods/mobs/borers/mob/borer/borer.dm @@ -20,6 +20,22 @@ bleed_colour = "#816e12" ai = /datum/mob_controller/borer + // Defined here to remove relaymove handlers as being + // directly in mob contents breaks relaymove spectacularly. + movement_handlers = list( + /datum/movement_handler/mob/death, + /datum/movement_handler/mob/borer_in_host, + /datum/movement_handler/mob/conscious, + /datum/movement_handler/mob/eye, + /datum/movement_handler/mob/delay, + /datum/movement_handler/mob/stop_effect, + /datum/movement_handler/mob/physically_capable, + /datum/movement_handler/mob/physically_restrained, + /datum/movement_handler/mob/space, + /datum/movement_handler/mob/multiz, + /datum/movement_handler/mob/movement + ) + var/static/list/chemical_types = list( "anti-trauma" = /decl/material/liquid/brute_meds, "amphetamines" = /decl/material/liquid/amphetamines, @@ -42,6 +58,9 @@ var/mob/living/human/host // Human host for the brain worm. var/mob/living/captive_brain/host_brain // Used for swapping control of the body back and forth. +/datum/movement_handler/mob/borer_in_host/MayMove(mob/mover, is_external) + return ismob(mob.loc) ? MOVEMENT_STOP : MOVEMENT_PROCEED + /datum/mob_controller/borer emote_hear = list("chirrups") do_wander = FALSE From edf7c7f97ca603a7ec7b893d40d68cfc6f6c60ee Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 17 Jan 2025 16:15:53 -0500 Subject: [PATCH 107/120] Fix redundant code in supply pack setup --- code/datums/supplypacks/supplypack.dm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/code/datums/supplypacks/supplypack.dm b/code/datums/supplypacks/supplypack.dm index 159c8ae31e7a..1be6469edc51 100644 --- a/code/datums/supplypacks/supplypack.dm +++ b/code/datums/supplypacks/supplypack.dm @@ -24,9 +24,7 @@ var/global/list/cargoprices = list() cost = 0 for(var/entry in contains) cost += atom_info_repository.get_combined_worth_for(entry) * max(1, contains[entry]) - var/container_value = containertype ? atom_info_repository.get_single_worth_for(containertype) : 0 - if(container_value) - cost += atom_info_repository.get_single_worth_for(containertype) + cost += containertype ? atom_info_repository.get_single_worth_for(containertype) : 0 cost = max(1, NONUNIT_CEILING((cost * WORTH_TO_SUPPLY_POINTS_CONSTANT * SSsupply.price_markup), WORTH_TO_SUPPLY_POINTS_ROUND_CONSTANT)) global.cargoprices[name] = cost From 3859858e1b25e6fc66fed213240c52d8f3ee4ca7 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 17 Jan 2025 16:12:40 -0500 Subject: [PATCH 108/120] Replace unnecessary 'in world' loops --- code/game/objects/structures/flora/tree.dm | 9 +++++++ code/modules/admin/verbs/diagnostics.dm | 2 +- code/modules/admin/verbs/mapping.dm | 19 ++++++++++++-- code/modules/holidays/holiday_special.dm | 16 ++++++------ .../file_system/programs/generic/folding.dm | 2 +- code/modules/recycling/disposalpipe.dm | 5 ---- code/unit_tests/map_tests.dm | 26 +++++++++++++++++-- code/unit_tests/mob_tests.dm | 12 +-------- .../supermatter/endgame_cascade/universe.dm | 3 ++- 9 files changed, 63 insertions(+), 31 deletions(-) diff --git a/code/game/objects/structures/flora/tree.dm b/code/game/objects/structures/flora/tree.dm index 9ad3314fc775..a088f2297cf2 100644 --- a/code/game/objects/structures/flora/tree.dm +++ b/code/game/objects/structures/flora/tree.dm @@ -102,6 +102,7 @@ /obj/structure/flora/tree/pine/init_appearance() icon_state = "pine_[rand(1, 3)]" +var/global/list/christmas_trees = list() /obj/structure/flora/tree/pine/xmas name = "\improper Christmas tree" desc = "O Christmas tree, O Christmas tree..." @@ -109,6 +110,14 @@ icon_state = "pine_c" stump_type = /obj/structure/flora/stump/tree/pine/xmas +/obj/structure/flora/tree/pine/xmas/Initialize(ml, _mat, _reinf_mat) + . = ..() + global.christmas_trees += src + +/obj/structure/flora/tree/pine/xmas/Destroy() + global.christmas_trees -= src + return ..() + /obj/structure/flora/tree/pine/xmas/init_appearance() return //Only one possible icon diff --git a/code/modules/admin/verbs/diagnostics.dm b/code/modules/admin/verbs/diagnostics.dm index 75b90a337127..179676df7f36 100644 --- a/code/modules/admin/verbs/diagnostics.dm +++ b/code/modules/admin/verbs/diagnostics.dm @@ -10,7 +10,7 @@ var/inactive_groups = SSair.zones.len - active_groups var/hotspots = 0 - for(var/obj/fire/hotspot in world) + for(var/obj/fire/hotspot in SSair.active_hotspots) hotspots++ var/active_on_main_station = 0 diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm index dd3f47479406..b599e3845e62 100644 --- a/code/modules/admin/verbs/mapping.dm +++ b/code/modules/admin/verbs/mapping.dm @@ -24,6 +24,7 @@ var/global/camera_range_display_status = 0 var/global/intercom_range_display_status = 0 +var/global/list/debug_camera_range_markers = list() /obj/effect/debugging/camera_range icon = 'icons/480x480.dmi' icon_state = "25percent" @@ -33,11 +34,25 @@ var/global/intercom_range_display_status = 0 default_pixel_x = -224 default_pixel_y = -224 reset_offsets(0) + global.debug_camera_range_markers += src +/obj/effect/debugging/camera_range/Destroy() + global.debug_camera_range_markers -= src + return ..() + +var/global/list/mapping_debugging_markers = list() /obj/effect/debugging/marker icon = 'icons/turf/areas.dmi' icon_state = "yellow" +/obj/effect/debugging/marker/Initialize(mapload) + . = ..() + global.mapping_debugging_markers += src + +/obj/effect/debugging/marker/Destroy() + global.mapping_debugging_markers -= src + return ..() + /obj/effect/debugging/marker/Move() return 0 @@ -56,7 +71,7 @@ var/global/intercom_range_display_status = 0 - for(var/obj/effect/debugging/camera_range/C in world) + for(var/obj/effect/debugging/camera_range/C as anything in debug_camera_range_markers) qdel(C) if(camera_range_display_status) @@ -113,7 +128,7 @@ var/global/intercom_range_display_status = 0 else intercom_range_display_status = 1 - for(var/obj/effect/debugging/marker/M in world) + for(var/obj/effect/debugging/marker/M in global.mapping_debugging_markers) qdel(M) if(intercom_range_display_status) diff --git a/code/modules/holidays/holiday_special.dm b/code/modules/holidays/holiday_special.dm index 36f2c7f2695d..375c6a3d9f86 100644 --- a/code/modules/holidays/holiday_special.dm +++ b/code/modules/holidays/holiday_special.dm @@ -1,12 +1,12 @@ -/datum/holiday/christmas/New() - ..() +/datum/holiday/christmas announcement = "Merry Christmas, everyone!" /datum/holiday/christmas/set_up_holiday() - for(var/obj/structure/flora/tree/pine/xmas in world) - if(isNotStationLevel(xmas.z)) + for(var/obj/structure/flora/tree/pine/xmas/crimmas_tree in global.christmas_trees) + if(isNotStationLevel(crimmas_tree.z)) continue - for(var/turf/T in orange(1,xmas)) - if(T.is_floor() && T.simulated) - for(var/i = 1 to rand(1,5)) - new /obj/item/a_gift(T) + for(var/turf/T in orange(1, crimmas_tree)) + if(!T.is_floor() || !T.simulated) + continue + for(var/i = 1 to rand(1,5)) + new /obj/item/a_gift(T) diff --git a/code/modules/modular_computers/file_system/programs/generic/folding.dm b/code/modules/modular_computers/file_system/programs/generic/folding.dm index ebd8214d0ffb..5d49c83988b3 100644 --- a/code/modules/modular_computers/file_system/programs/generic/folding.dm +++ b/code/modules/modular_computers/file_system/programs/generic/folding.dm @@ -23,7 +23,7 @@ var/started_on = 0 // When the program started some science. var/current_interval = 0 // How long the current interval will be. - var/next_event = 0 // in world timeofday, when the next event is scheduled to pop. + var/next_event = 0 // based on world.timeofday, when the next event is scheduled to pop. var/program_status = PROGRAM_STATUS_RUNNING // Program periodically needs a restart, increases crash chance slightly over time. var/crashed_at = 0 // When the program crashed. diff --git a/code/modules/recycling/disposalpipe.dm b/code/modules/recycling/disposalpipe.dm index b1e5ab0afc48..88e11fbbdc60 100644 --- a/code/modules/recycling/disposalpipe.dm +++ b/code/modules/recycling/disposalpipe.dm @@ -234,11 +234,6 @@ /obj/structure/disposalpipe/hides_under_flooring() return 1 -// *** TEST verb -//client/verb/dispstop() -// for(var/obj/structure/disposalholder/H in world) -// H.active = 0 - // a straight or bent segment /obj/structure/disposalpipe/segment icon_state = "pipe-s" // Sadly this var stores state. "pipe-c" is corner. Should be changed, but requires huge map diff. diff --git a/code/unit_tests/map_tests.dm b/code/unit_tests/map_tests.dm index 2803ba8db097..89238fa88d21 100644 --- a/code/unit_tests/map_tests.dm +++ b/code/unit_tests/map_tests.dm @@ -503,6 +503,28 @@ //======================================================================================= +// These vars are used to avoid in-world loops in the following unit test. +var/global/_unit_test_disposal_segments = list() +var/global/_unit_test_sort_junctions = list() + +#ifdef UNIT_TEST +/obj/structure/disposalpipe/segment/Initialize(mapload) + . = ..() + _unit_test_disposal_segments += src + +/obj/structure/disposalpipe/segment/Destroy() + _unit_test_disposal_segments -= src + return ..() + +/obj/structure/disposalpipe/sortjunction/Initialize(mapload) + . = ..() + _unit_test_sort_junctions += src + +/obj/structure/disposalpipe/sortjunction/Destroy() + _unit_test_sort_junctions -= src + return ..() +#endif + /datum/unit_test/disposal_segments_shall_connect_with_other_disposal_pipes name = "MAP: Disposal segments shall connect with other disposal pipes" @@ -522,7 +544,7 @@ num2text(SOUTH) = list(list(SOUTH, list(NORTH, WEST)), list(EAST, list(NORTH, EAST))), num2text(WEST) = list(list(EAST, list(NORTH, EAST)), list(SOUTH, list(SOUTH, EAST)))) - for(var/obj/structure/disposalpipe/segment/D in world) + for(var/obj/structure/disposalpipe/segment/D in _unit_test_disposal_segments) if(!D.loc) continue if(D.icon_state == "pipe-s") @@ -760,7 +782,7 @@ /datum/unit_test/networked_disposals_shall_deliver_tagged_packages/start_test() . = 1 var/fail = FALSE - for(var/obj/structure/disposalpipe/sortjunction/sort in world) + for(var/obj/structure/disposalpipe/sortjunction/sort in _unit_test_sort_junctions) if(!sort.loc) continue if(is_type_in_list(sort, exempt_junctions)) diff --git a/code/unit_tests/mob_tests.dm b/code/unit_tests/mob_tests.dm index 86adfc0c9f15..79d3e9003314 100644 --- a/code/unit_tests/mob_tests.dm +++ b/code/unit_tests/mob_tests.dm @@ -60,19 +60,9 @@ var/global/default_mobloc = null -/proc/create_test_mob_with_mind(var/turf/mobloc = null, var/mobtype = /mob/living/human) +/proc/create_test_mob_with_mind(var/turf/mobloc, var/mobtype = /mob/living/human) var/list/test_result = list("result" = FAILURE, "msg" = "", "mobref" = null) - if(isnull(mobloc)) - if(!default_mobloc) - for(var/turf/floor/tiled/T in world) - if(!T.zone?.air) - continue - var/pressure = T.zone.air.return_pressure() - if(90 < pressure && pressure < 120) // Find a turf between 90 and 120 - default_mobloc = T - break - mobloc = default_mobloc if(!mobloc) test_result["msg"] = "Unable to find a location to create test mob" return test_result diff --git a/mods/content/supermatter/endgame_cascade/universe.dm b/mods/content/supermatter/endgame_cascade/universe.dm index 507097a121eb..ccca16707e43 100644 --- a/mods/content/supermatter/endgame_cascade/universe.dm +++ b/mods/content/supermatter/endgame_cascade/universe.dm @@ -67,9 +67,10 @@ if(!invalid_area) A.update_icon() +// TODO: Should this be changed to use the actual ambient lights system...? /datum/universal_state/supermatter_cascade/OverlayAndAmbientSet() spawn(0) - for(var/datum/lighting_corner/L in world) + for(var/datum/lighting_corner/L in SSlighting.lighting_corners) if(isAdminLevel(L.z)) L.update_lumcount(1,1,1) else From d6b37ee65b519735a25623fc083ca0ef7c211668 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 17 Jan 2025 16:14:13 -0500 Subject: [PATCH 109/120] Replace uses of direct_output with specialized helpers --- code/_helpers/files.dm | 2 +- code/_helpers/icons.dm | 2 +- code/_helpers/logging.dm | 2 +- code/_helpers/profiling.dm | 2 +- code/_helpers/sorts/__main.dm | 2 +- code/_macros.dm | 3 +++ .../controllers/subsystems/initialization/character_info.dm | 2 +- code/game/objects/items/_item_force.dm | 2 +- code/game/world.dm | 4 ++-- code/modules/admin/admin.dm | 2 +- code/modules/admin/topic.dm | 2 +- code/modules/admin/verbs/getlogs.dm | 4 ++-- code/modules/admin/view_variables/helpers.dm | 6 +++--- code/modules/client/asset_cache.dm | 4 ++-- code/modules/client/preferences.dm | 2 +- code/modules/mob/living/silicon/robot/robot.dm | 2 +- 16 files changed, 23 insertions(+), 20 deletions(-) diff --git a/code/_helpers/files.dm b/code/_helpers/files.dm index b665a162e7ba..c6d4b7ea49ff 100644 --- a/code/_helpers/files.dm +++ b/code/_helpers/files.dm @@ -1,7 +1,7 @@ //Sends resource files to client cache /client/proc/getFiles() for(var/file in args) - direct_output(src, browse_rsc(file)) + send_rsc(src, file, null) /client/proc/browse_files(root="data/logs/", max_iterations=10, list/valid_extensions=list(".txt",".log",".htm")) var/path = root diff --git a/code/_helpers/icons.dm b/code/_helpers/icons.dm index 5c78a7dd62f9..ee74c5f11efe 100644 --- a/code/_helpers/icons.dm +++ b/code/_helpers/icons.dm @@ -163,7 +163,7 @@ mob // Send the icon to src's local cache send_rsc(src, getFlatIcon(src), iconName) // Display the icon in their browser - direct_output(src, browse("

      ")) + show_browser(src, "

      ") Output_Icon() set name = "2. Output Icon" diff --git a/code/_helpers/logging.dm b/code/_helpers/logging.dm index b8cf7af8f123..5c1744b0178f 100644 --- a/code/_helpers/logging.dm +++ b/code/_helpers/logging.dm @@ -26,7 +26,7 @@ var/global/log_end= world.system_type == UNIX ? ascii2text(13) : "" to_world_log("## TESTING: [msg][log_end]") /proc/game_log(category, text) - direct_output(diary, "\[[time_stamp()]] [game_id] [category]: [text][log_end]") + to_file(diary, "\[[time_stamp()]] [game_id] [category]: [text][log_end]") /proc/log_admin(text) global.admin_log.Add(text) diff --git a/code/_helpers/profiling.dm b/code/_helpers/profiling.dm index ad16a2c2d279..0c4785568368 100644 --- a/code/_helpers/profiling.dm +++ b/code/_helpers/profiling.dm @@ -71,7 +71,7 @@ lines += "[entry] => [num2text(data[STAT_ENTRY_TIME], 10)]ms ([data[STAT_ENTRY_COUNT]]) (avg:[num2text(data[STAT_ENTRY_TIME]/(data[STAT_ENTRY_COUNT] || 1), 99)])" if (user) - direct_output(user, browse("
      1. [lines.Join("
      2. ")]
      ", "window=[url_encode("stats:[ref(stats)]")]")) + show_browser(user, "
      1. [lines.Join("
      2. ")]
      ", "window=[url_encode("stats:[ref(stats)]")]") . = lines.Join("\n") diff --git a/code/_helpers/sorts/__main.dm b/code/_helpers/sorts/__main.dm index 09bb861f6477..391630171eba 100644 --- a/code/_helpers/sorts/__main.dm +++ b/code/_helpers/sorts/__main.dm @@ -169,7 +169,7 @@ reverse a descending sequence without violating stability. var/r = 0 //becomes 1 if any bits are shifted off while(n >= MIN_MERGE) r |= (n & 1) - n >>= 1 + n = BITSHIFT_RIGHT(n, 1) return n + r //Examines the stack of runs waiting to be merged and merges adjacent runs until the stack invariants are reestablished: diff --git a/code/_macros.dm b/code/_macros.dm index b5bcd2346dff..11e6c146b5d5 100644 --- a/code/_macros.dm +++ b/code/_macros.dm @@ -106,9 +106,12 @@ #define show_image(target, image) target << (image) #define send_rsc(target, rsc_content, rsc_name) target << browse_rsc(rsc_content, rsc_name) #define open_link(target, url) target << link(url) +#define ftp_to(target, file_entry, suggested_name) target << ftp(file_entry, suggested_name) +#define open_file_for(target, file) target << run(file) #define to_savefile(target, key, value) target[(key)] << (value) #define from_savefile(target, key, value) target[(key)] >> (value) #define to_output(target, output_content, output_args) target << output((output_content), (output_args)) +// Avoid using this where possible, prefer the other helpers instead. #define direct_output(target, value) target << (value) /proc/html_icon(var/thing) // Proc instead of macro to avoid precompiler problems. diff --git a/code/controllers/subsystems/initialization/character_info.dm b/code/controllers/subsystems/initialization/character_info.dm index cb09b69f3619..a874ddcb4f93 100644 --- a/code/controllers/subsystems/initialization/character_info.dm +++ b/code/controllers/subsystems/initialization/character_info.dm @@ -136,7 +136,7 @@ SUBSYSTEM_DEF(character_info) fdel(dump_file_name) text2file(JOINTEXT(SScharacter_info.get_character_manifest_html(apply_striping = FALSE)), dump_file_name) if(fexists(dump_file_name)) - direct_output(usr, ftp(dump_file_name, "dump_manifest.html")) + ftp_to(usr, dump_file_name, "dump_manifest.html") return TOPIC_HANDLED catch(var/exception/E) log_debug("Exception when dumping character relationship manifest: [E]") diff --git a/code/game/objects/items/_item_force.dm b/code/game/objects/items/_item_force.dm index 9ce71938c3cb..790d894e5962 100644 --- a/code/game/objects/items/_item_force.dm +++ b/code/game/objects/items/_item_force.dm @@ -162,6 +162,6 @@ text2file(jointext(rows, "\n"), "weapon_stats_dump.csv") if(fexists("weapon_stats_dump.csv")) - direct_output(usr, ftp("weapon_stats_dump.csv", "weapon_stats_dump.csv")) + ftp_to(usr, "weapon_stats_dump.csv", "weapon_stats_dump.csv") to_chat(usr, "Done.") */ diff --git a/code/game/world.dm b/code/game/world.dm index eb1715e424fb..1c65910d510c 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -126,7 +126,7 @@ var/global/world_topic_last = world.timeofday throttle[2] = reason /world/Topic(T, addr, master, key) - direct_output(diary, "TOPIC: \"[T]\", from:[addr], master:[master], key:[key][log_end]") + to_file(diary, "TOPIC: \"[T]\", from:[addr], master:[master], key:[key][log_end]") if (global.world_topic_last > world.timeofday) global.world_topic_throttle = list() //probably passed midnight @@ -201,7 +201,7 @@ var/global/_reboot_announced = FALSE /world/proc/save_mode(var/the_mode) var/F = file("data/mode.txt") fdel(F) - direct_output(F, the_mode) + to_file(F, the_mode) /world/proc/load_motd() join_motd = safe_file2text("config/motd.txt", FALSE) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 5e06996ca46f..c211f274d603 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -321,7 +321,7 @@ var/global/BSACooldown = 0 dat += "Remove" dat += "
      " if(update_file) - direct_output(info, infos) + to_file(info, infos) dat += "

    Add Comment
    " diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 46d220be2381..c9e2798773b2 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -174,7 +174,7 @@ else if(task == "permissions") if(!D) return var/list/permissionlist = list() - for(var/i=1, i<=R_MAXPERMISSION, i<<=1) //that <<= is shorthand for i = i << 1. Which is a left BITSHIFT_LEFT + for(var/i=1, i<=R_MAXPERMISSION, i = BITSHIFT_LEFT(i, 1)) permissionlist[rights2text(i)] = i var/new_permission = input("Select a permission to turn on/off", "Permission toggle", null, null) as null|anything in permissionlist if(!new_permission) return diff --git a/code/modules/admin/verbs/getlogs.dm b/code/modules/admin/verbs/getlogs.dm index 24bbe2f93abd..0527485b1265 100644 --- a/code/modules/admin/verbs/getlogs.dm +++ b/code/modules/admin/verbs/getlogs.dm @@ -51,7 +51,7 @@ return message_admins("[key_name_admin(src)] accessed file: [path]") - direct_output(src, run(file(path))) + open_file_for(src, file(path)) to_chat(src, "Attempting to send file, this may take a fair few minutes if the file is very large.") return @@ -64,6 +64,6 @@ set name = "Show Server Log" set desc = "Shows today's server log." - direct_output(usr, run(diary)) + open_file_for(usr, diary) SSstatistics.add_field_details("admin_verb","VTL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! return \ No newline at end of file diff --git a/code/modules/admin/view_variables/helpers.dm b/code/modules/admin/view_variables/helpers.dm index 2a1f96ecaa59..7b7155b8391c 100644 --- a/code/modules/admin/view_variables/helpers.dm +++ b/code/modules/admin/view_variables/helpers.dm @@ -6,16 +6,16 @@ return {" [src]
    - << + \<\< [dir2text(dir)] - >> + \>\> "} /mob/living/get_view_variables_header() return {" [src] -
    << [dir2text(dir)] >> +
    \<\< [dir2text(dir)] \>\>
    [ckey ? ckey : "No ckey"] / [real_name ? real_name : "No real name"]
    BRUTE:[get_damage(BRUTE)] diff --git a/code/modules/client/asset_cache.dm b/code/modules/client/asset_cache.dm index d582783e0912..f83344b4841e 100644 --- a/code/modules/client/asset_cache.dm +++ b/code/modules/client/asset_cache.dm @@ -45,7 +45,7 @@ You can set verify to TRUE if you want send() to sleep until the client has the client.sending |= asset_name var/job = ++client.last_asset_job - direct_output(client, browse("", "window=asset_cache_browser")) + show_browser(client, "", "window=asset_cache_browser") var/t = 0 var/timeout_time = (ASSET_CACHE_SEND_TIMEOUT * client.sending.len) + ASSET_CACHE_SEND_TIMEOUT @@ -85,7 +85,7 @@ You can set verify to TRUE if you want send() to sleep until the client has the client.sending |= unreceived var/job = ++client.last_asset_job - direct_output(client, browse("", "window=asset_cache_browser")) + show_browser(client, "", "window=asset_cache_browser") var/t = 0 var/timeout_time = ASSET_CACHE_SEND_TIMEOUT * client.sending.len diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index b5c1c2a992a8..c4ec78c13cf2 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -295,7 +295,7 @@ var/global/list/time_prefs_fixed = list() return if(href_list["preference"] == "open_whitelist_forum") if(get_config_value(/decl/config/text/forumurl)) - direct_output(user, link(get_config_value(/decl/config/text/forumurl))) + open_link(user, get_config_value(/decl/config/text/forumurl)) else to_chat(user, "The forum URL is not set in the server configuration.") return diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 2d8c1244d718..caf0ec893084 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -1013,7 +1013,7 @@ sleep(5) to_chat(src, "Would you like to send a report to the vendor? Y/N") sleep(10) - to_chat(src, "> N") + to_chat(src, "\> N") sleep(20) to_chat(src, "ERRORERRORERROR") to_chat(src, "Obey these laws:") From 08f76b05aac1a62c796e45761b84b3e609fdd191 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 17 Jan 2025 16:15:10 -0500 Subject: [PATCH 110/120] Remove unnecessary uses of tag var --- code/modules/overmap/contacts/_contacts.dm | 1 - code/modules/random_map/drop/droppod.dm | 4 ---- 2 files changed, 5 deletions(-) diff --git a/code/modules/overmap/contacts/_contacts.dm b/code/modules/overmap/contacts/_contacts.dm index e4cab812e76f..bde9a41d1717 100644 --- a/code/modules/overmap/contacts/_contacts.dm +++ b/code/modules/overmap/contacts/_contacts.dm @@ -29,7 +29,6 @@ radar = image(loc = effect, icon = 'icons/obj/overmap.dmi', icon_state = "sensor_range") radar.color = source.color - radar.tag = "radar" radar.add_filter("blur", 1, list(type = "blur", size = 1)) radar.appearance_flags |= RESET_TRANSFORM | KEEP_APART radar.appearance_flags &= ~PIXEL_SCALE diff --git a/code/modules/random_map/drop/droppod.dm b/code/modules/random_map/drop/droppod.dm index ac23a7b14e80..926ed6b2d0bd 100644 --- a/code/modules/random_map/drop/droppod.dm +++ b/code/modules/random_map/drop/droppod.dm @@ -136,7 +136,6 @@ drop = pick(supplied_drop_types) supplied_drop_types -= drop if(istype(drop)) - drop.tag = null if(drop.buckled) drop.buckled = null drop.forceMove(T) @@ -168,7 +167,6 @@ return for(var/i=0;i Date: Fri, 17 Jan 2025 16:16:37 -0500 Subject: [PATCH 111/120] Improve git grep code quality checks --- .../modular_computers/terminal/terminal.dm | 18 +++++----- test/check-paths.sh | 33 ++++++++++--------- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/code/modules/modular_computers/terminal/terminal.dm b/code/modules/modular_computers/terminal/terminal.dm index 994bbc2f774c..dec38ed92f15 100644 --- a/code/modules/modular_computers/terminal/terminal.dm +++ b/code/modules/modular_computers/terminal/terminal.dm @@ -98,7 +98,7 @@ account_name = "LOCAL" else account_name = "GUEST" - content += "
    >[account_name]:/[current_disk?.get_dir_path(current_directory, TRUE)]
    " + content += "
    \>[account_name]:/[current_disk?.get_dir_path(current_directory, TRUE)]
    " content += "type `man` for a list of available commands." panel.set_content("[jointext(content, "
    ")]
    ") @@ -159,7 +159,7 @@ /datum/terminal/proc/parse_directory(directory_path, create_directories = FALSE) var/datum/file_storage/target_disk = current_disk var/datum/computer_file/directory/root_dir = current_directory - + if(!length(directory_path)) return list(target_disk, root_dir) @@ -168,8 +168,8 @@ // Otherwise, we append the working directory path to the passed path. var/list/directories = splittext(directory_path, "/") - - // When splitting the text, there could be blank strings at either end, so remove them. If there's any in the body of the path, there was a + + // When splitting the text, there could be blank strings at either end, so remove them. If there's any in the body of the path, there was a // missed input, so leave them. if(!length(directories[1])) directories.Cut(1, 2) @@ -194,7 +194,7 @@ if(!target_disk) // Invalid disk entered. return OS_DIR_NOT_FOUND directories.Cut(1, 2) - + break // Any further use of ../ is handled by the hard drive. // If we were only pathing to the parent of a directory or to a disk, we can return early. @@ -208,7 +208,7 @@ var/datum/computer_file/directory/target_directory = target_disk.parse_directory(final_path, create_directories) if(!istype(target_directory)) return OS_DIR_NOT_FOUND - + return list(target_disk, target_directory) // Returns list(/datum/file_storage, /datum/computer_file/directory, /datum/computer_file) on success. Returns error code on failure. @@ -221,7 +221,7 @@ var/list/dirs_and_file = splittext(file_path, "/") if(!length(dirs_and_file)) return OS_DIR_NOT_FOUND - + // Join together everything but the filename into a path. var/list/file_loc = parse_directory(jointext(dirs_and_file, "/", 1, dirs_and_file.len)) if(!islist(file_loc)) // Errored! @@ -231,7 +231,7 @@ var/datum/computer_file/directory/target_dir = file_loc[2] if(!istype(target_disk)) return OS_DIR_NOT_FOUND - + var/filename = dirs_and_file[dirs_and_file.len] var/datum/computer_file/target_file = target_disk.get_file(filename, target_dir) if(!istype(target_file)) @@ -265,5 +265,5 @@ return "I/O error, Harddrive may be non-functional" if(OS_NETWORK_ERROR) return "Unable to connect to the network" - + return "An unspecified error occured." \ No newline at end of file diff --git a/test/check-paths.sh b/test/check-paths.sh index 7d9bfbed01a9..852c681ae6ca 100755 --- a/test/check-paths.sh +++ b/test/check-paths.sh @@ -23,34 +23,35 @@ exactly() { # exactly N name search [mode] [filter] # With the potential exception of << if you increase any of these numbers you're probably doing it wrong # Additional exception August 2020: \b is a regex symbol as well as a BYOND macro. -exactly 1 "escapes" '\\\\(red|blue|green|black|b|i[^mc])' -exactly 8 "Del()s" '\WDel\(' +exactly 3 "escapes" '\\(red|blue|green|black|b|i[^mc])' +exactly 3 "Del()s" '(?> uses" '>>(?!>)' -P +exactly 1 "world<< uses" 'world\s*<<' +exactly 74 "'in world' uses" '\s+\bin world\b(?=\s*$|\s*//|\s*\))' -P +exactly 1 "world.log<< uses" 'world.log\s*<<' +exactly 18 "<< uses" '(?> uses" '(?\\])>>(?!>)' -P exactly 0 "incorrect indentations" '^( {4,})' -P exactly 23 "text2path uses" 'text2path' -exactly 4 "update_icon() override" '/update_icon\((.*)\)' -P -exactly 0 "goto uses" 'goto ' +exactly 4 "update_icon() overrides" '\/update_icon\(' -P +exactly 0 "goto uses" '\bgoto\b' exactly 9 "atom/New uses" '^/(obj|atom|area|mob|turf).*/New\(' exactly 1 "decl/New uses" '^/decl.*/New\(' -exactly 0 "tag uses" '\stag = ' -P '*.dmm' -exactly 3 "unmarked globally scoped variables" '^(/|)var/(?!global)' -P -exactly 0 "global-marked member variables" '\t(/|)var.*/global/.+' -P -exactly 0 "static-marked globally scoped variables" '^(/|)var.*/static/.+' -P +exactly 3 "tag uses" '(? Date: Tue, 21 Jan 2025 13:24:26 -0500 Subject: [PATCH 112/120] Simplify unit test dummy mob creation --- code/unit_tests/equipment_tests.dm | 31 +++++++++++++----------------- code/unit_tests/mob_tests.dm | 4 +--- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/code/unit_tests/equipment_tests.dm b/code/unit_tests/equipment_tests.dm index d082e6fc91a9..dac446856e8b 100644 --- a/code/unit_tests/equipment_tests.dm +++ b/code/unit_tests/equipment_tests.dm @@ -1,42 +1,37 @@ /datum/unit_test/vision_glasses name = "EQUIPMENT: Vision Template" abstract_type = /datum/unit_test/vision_glasses - var/mob/living/human/H = null + var/mob/living/human/subject = null var/expectation = SEE_INVISIBLE_NOLIGHTING var/glasses_type = null async = 1 /datum/unit_test/vision_glasses/start_test() - var/list/test = create_test_mob_with_mind(get_safe_turf(), /mob/living/human) - if(isnull(test)) - fail("Check Runtimed in Mob creation") - - if(test["result"] == FAILURE) - fail(test["msg"]) - async = 0 - return 0 - - H = locate(test["mobref"]) - H.equip_to_slot(new glasses_type(H), slot_glasses_str) + subject = new(get_safe_turf(), SPECIES_HUMAN) // force human so default map species doesn't mess with anything + subject.equip_to_slot(new glasses_type(subject), slot_glasses_str) return 1 /datum/unit_test/vision_glasses/check_result() - if(isnull(H) || H.life_tick < 2) + if(isnull(subject) || subject.life_tick < 2) return 0 - if(isnull(H.get_equipped_item(slot_glasses_str))) + if(isnull(subject.get_equipped_item(slot_glasses_str))) fail("Mob doesn't have glasses on") - H.handle_vision() // Because Life has a client check that bypasses updating vision + subject.handle_vision() // Because Life has a client check that bypasses updating vision - if(H.see_invisible == expectation) - pass("Mob See invisible is [H.see_invisible]") + if(subject.see_invisible == expectation) + pass("Mob See invisible is [subject.see_invisible]") else - fail("Mob See invisible is [H.see_invisible] / expected [expectation]") + fail("Mob See invisible is [subject.see_invisible] / expected [expectation]") return 1 +/datum/unit_test/vision_glasses/teardown_test() + QDEL_NULL(subject) + . = ..() + /datum/unit_test/vision_glasses/NVG name = "EQUIPMENT: NVG see_invis" glasses_type = /obj/item/clothing/glasses/night diff --git a/code/unit_tests/mob_tests.dm b/code/unit_tests/mob_tests.dm index 79d3e9003314..2f03eb9da320 100644 --- a/code/unit_tests/mob_tests.dm +++ b/code/unit_tests/mob_tests.dm @@ -58,9 +58,7 @@ // ============================================================================ -var/global/default_mobloc = null - -/proc/create_test_mob_with_mind(var/turf/mobloc, var/mobtype = /mob/living/human) +/datum/unit_test/mob_damage/proc/create_test_mob_with_mind(var/turf/mobloc, var/mobtype = /mob/living/human) var/list/test_result = list("result" = FAILURE, "msg" = "", "mobref" = null) if(!mobloc) From 300690ebbc03997fdd666c2186d8f31263ead471 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 21 Jan 2025 11:40:49 -0500 Subject: [PATCH 113/120] Fix blood mixing with muddy footsteps --- code/game/turfs/turf.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 152b1ac63a01..11c0740d79a1 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -718,8 +718,11 @@ var/mob/living/human/H = M var/unique_enzymes = H.get_unique_enzymes() var/blood_type = H.get_blood_type() + var/blood_reagent = H.species.blood_reagent if(unique_enzymes && blood_type) for(var/obj/effect/decal/cleanable/blood/B in contents) + if(B.chemical != blood_reagent) + continue if(!LAZYACCESS(B.blood_DNA, unique_enzymes)) LAZYSET(B.blood_DNA, unique_enzymes, blood_type) LAZYSET(B.blood_data, unique_enzymes, REAGENT_DATA(H.vessel, H.species.blood_reagent)) From 210eefdf60f9ce1b63f4116b8dd965bbf0a51fc0 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 21 Jan 2025 11:26:04 -0500 Subject: [PATCH 114/120] Fix coating overlay color being shared globally between identical items --- code/game/objects/items/__item.dm | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/code/game/objects/items/__item.dm b/code/game/objects/items/__item.dm index 2831c4b103c3..7c41d0aa13fb 100644 --- a/code/game/objects/items/__item.dm +++ b/code/game/objects/items/__item.dm @@ -829,21 +829,19 @@ LAZYSET(blood_DNA, unique_enzymes, blood_type) return TRUE -var/global/list/_coating_overlay_cache = list() +var/global/list/icon/_coating_overlay_cache = list() var/global/icon/_item_coating_mask = icon('icons/effects/blood.dmi', "itemblood") /obj/item/proc/generate_coating_overlay(force = FALSE) if(coating_overlay && !force) return - var/cache_key = "[icon]-[icon_state]" - if(global._coating_overlay_cache[cache_key]) - coating_overlay = global._coating_overlay_cache[cache_key] - return - var/icon/I = new /icon(icon, icon_state) - I.MapColors(0,0,0, 0,0,0, 0,0,0, 1,1,1) // Sets the icon RGB channel to pure white. - I.Blend(global._item_coating_mask, ICON_MULTIPLY) // Masks the coating overlay against the generated mask. - coating_overlay = image(I) + var/cache_key = "\ref[icon]-[icon_state]" // this needs to use ref because of stringification + if(!global._coating_overlay_cache[cache_key]) + var/icon/I = new /icon(icon, icon_state) + I.MapColors(0,0,0, 0,0,0, 0,0,0, 1,1,1) // Sets the icon RGB channel to pure white. + I.Blend(global._item_coating_mask, ICON_MULTIPLY) // Masks the coating overlay against the generated mask. + global._coating_overlay_cache[cache_key] = I + coating_overlay = image(global._coating_overlay_cache[cache_key]) coating_overlay.appearance_flags |= NO_CLIENT_COLOR|RESET_COLOR - global._coating_overlay_cache[cache_key] = coating_overlay /obj/item/proc/showoff(mob/user) for(var/mob/M in view(user)) From aa75817ed35ad3060f611310d42f4186dcb908ed Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 21 Jan 2025 11:24:18 -0500 Subject: [PATCH 115/120] Fix missing phase argument in add_to_reagents --- code/game/turfs/turf_fluids.dm | 2 +- code/modules/reagents/Chemistry-Holder.dm | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/code/game/turfs/turf_fluids.dm b/code/game/turfs/turf_fluids.dm index 13e48d990521..fafce1d44ff0 100644 --- a/code/game/turfs/turf_fluids.dm +++ b/code/game/turfs/turf_fluids.dm @@ -110,7 +110,7 @@ create_reagents(FLUID_MAX_DEPTH) return ..() -/turf/add_to_reagents(reagent_type, amount, data, safety = FALSE, defer_update = FALSE, phase) +/turf/add_to_reagents(reagent_type, amount, data, safety = FALSE, defer_update = FALSE, phase = null) if(!reagents) create_reagents(FLUID_MAX_DEPTH) return ..() diff --git a/code/modules/reagents/Chemistry-Holder.dm b/code/modules/reagents/Chemistry-Holder.dm index 88cbb17aa8c6..c8872711cd3e 100644 --- a/code/modules/reagents/Chemistry-Holder.dm +++ b/code/modules/reagents/Chemistry-Holder.dm @@ -1,8 +1,8 @@ var/global/obj/temp_reagents_holder = new var/global/datum/reagents/sink/infinite_reagent_sink = new -/atom/proc/add_to_reagents(reagent_type, amount, data, safety = FALSE, defer_update = FALSE) - return reagents?.add_reagent(reagent_type, amount, data, safety, defer_update) +/atom/proc/add_to_reagents(reagent_type, amount, data, safety = FALSE, defer_update = FALSE, phase = null) + return reagents?.add_reagent(reagent_type, amount, data, safety, defer_update, phase) /atom/proc/remove_from_reagents(reagent_type, amount, safety = FALSE, defer_update = FALSE) return reagents?.remove_reagent(reagent_type, amount, safety, defer_update) From 3bb4000373c1d889dd76218a1ce75a7dcaff6b32 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 21 Jan 2025 11:35:31 -0500 Subject: [PATCH 116/120] Fix clothing ensemble examine name missing an article --- code/modules/clothing/_clothing.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/modules/clothing/_clothing.dm b/code/modules/clothing/_clothing.dm index be67a2323ee4..31e8219e033a 100644 --- a/code/modules/clothing/_clothing.dm +++ b/code/modules/clothing/_clothing.dm @@ -303,12 +303,12 @@ update_clothing_icon() /obj/item/clothing/get_examine_name() - var/list/ensemble = list(name) + var/list/ensemble = list(..()) for(var/obj/item/clothing/accessory in accessories) if(accessory.accessory_visibility == ACCESSORY_VISIBILITY_ENSEMBLE) - LAZYADD(ensemble, accessory.get_examine_name()) - if(length(ensemble) <= 1) - return ..() + ensemble += accessory.get_examine_name() + if(length(ensemble) == 1) // don't worry about it being empty, we always have a minimum of one + return ensemble[1] return english_list(ensemble, summarize = TRUE) /obj/item/clothing/get_examine_line() From 4f4f496a59572e359e6d4d5cb106d4ee1283d7ac Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 23 Jan 2025 10:46:25 +1100 Subject: [PATCH 117/120] Fixes bad istype() in hand slot code. --- code/modules/mob/mob.dm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 3a465515aa4d..98985b3add80 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1401,8 +1401,8 @@ /// THIS DOES NOT RELATE TO HELD ITEM SLOTS. It is very specifically a functional BP_L_HAND or BP_R_HAND organ, not necessarily a gripper. /mob/proc/get_usable_hand_slot_organ() - var/obj/item/organ/external/paw = GET_EXTERNAL_ORGAN(src, BP_L_HAND) - if(!istype(paw) && !paw.is_usable()) - paw = GET_EXTERNAL_ORGAN(src, BP_R_HAND) - if(istype(paw) && paw.is_usable()) - return paw + var/static/list/hand_slots = list(BP_L_HAND, BP_R_HAND) + for(var/slot in shuffle(hand_slots)) + var/obj/item/organ/external/hand = GET_EXTERNAL_ORGAN(src, slot) + if(istype(hand) && hand.is_usable()) + return hand From 01133c35ad6b088dc11561b5b54f985e1fc85bf7 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 23 Jan 2025 13:27:22 +1100 Subject: [PATCH 118/120] Fixing issues with robot brainmobs. --- code/modules/mob/living/brain/brain.dm | 2 +- code/modules/mob/living/death.dm | 6 +++ code/modules/mob/living/human/death.dm | 3 -- .../modules/mob/living/silicon/robot/robot.dm | 40 ++++++++++++------- 4 files changed, 33 insertions(+), 18 deletions(-) diff --git a/code/modules/mob/living/brain/brain.dm b/code/modules/mob/living/brain/brain.dm index 35b97e4880b8..fe3e16913e87 100644 --- a/code/modules/mob/living/brain/brain.dm +++ b/code/modules/mob/living/brain/brain.dm @@ -44,7 +44,7 @@ container.queue_icon_update() /mob/living/brain/proc/get_container() - . = loc?.loc + return get_recursive_loc_of_type(/obj/item/organ/internal) /mob/living/brain/Login() . = ..() diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm index 8855bd1ecd74..8a31af021dc1 100644 --- a/code/modules/mob/living/death.dm +++ b/code/modules/mob/living/death.dm @@ -11,3 +11,9 @@ stop_aiming(no_message=1) if(istype(ai)) ai.handle_death(gibbed) + + var/decl/species/my_species = get_species() + if(my_species) + if(!gibbed && my_species.death_sound) + playsound(loc, my_species.death_sound, 80, 1, 1) + my_species.handle_death(src) diff --git a/code/modules/mob/living/human/death.dm b/code/modules/mob/living/human/death.dm index e06f550ae42b..8f21775624ac 100644 --- a/code/modules/mob/living/human/death.dm +++ b/code/modules/mob/living/human/death.dm @@ -33,11 +33,8 @@ if(!gibbed) set_tail_animation_state(null, TRUE) handle_organs() - if(species.death_sound) - playsound(loc, species.death_sound, 80, 1, 1) if(SSticker.mode) SSticker.mode.check_win() - species.handle_death(src) /mob/living/human/physically_destroyed(var/skip_qdel, var/droplimb_type = DISMEMBER_METHOD_BLUNT) for(var/obj/item/organ/external/limb in get_external_organs()) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index f2b3335bc462..0953228225a4 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -190,14 +190,7 @@ return 0 /mob/living/silicon/robot/Destroy() - if(central_processor) - central_processor.dropInto(loc) - var/mob/living/brainmob = central_processor.get_brainmob() - if(mind && brainmob) - mind.transfer_to(brainmob) - else - ghostize() - central_processor = null + QDEL_NULL(central_processor) if(connected_ai) connected_ai.connected_robots -= src connected_ai = null @@ -518,8 +511,8 @@ SPAN_NOTICE("\The [user] begins ripping \the [central_processor] out of \the [src]."), SPAN_NOTICE("You jam the crowbar into the robot and begin levering out \the [central_processor].")) - if(do_after(user, 50, src)) - dismantle(user) + if(do_after(user, 5 SECONDS, src)) + dismantle_robot(user) else // Okay we're not removing the cell or a CPU, but maybe something else? var/list/removable_components = list() @@ -1042,10 +1035,29 @@ return 1 return ..() -/mob/living/silicon/robot/proc/dismantle(var/mob/user) - to_chat(user, SPAN_NOTICE("You damage some parts of the chassis, but eventually manage to rip out the central processor.")) - var/obj/item/robot_parts/robot_suit/C = new dismantle_type(loc) - C.dismantled_from(src) +/mob/living/silicon/robot/gib(do_gibs) + SHOULD_CALL_PARENT(FALSE) + var/lastloc = loc + dismantle_robot() + if(lastloc && do_gibs) + spawn_gibber(lastloc) + +/mob/living/silicon/robot/proc/dismantle_robot(var/mob/user) + + if(central_processor) + if(user) + to_chat(user, SPAN_NOTICE("You damage some parts of the chassis, but eventually manage to rip out \the [central_processor].")) + central_processor.dropInto(loc) + var/mob/living/brainmob = central_processor.get_brainmob(create_if_missing = TRUE) + if(mind && brainmob) + mind.transfer_to(brainmob) + else + ghostize() + central_processor.update_icon() + central_processor = null + + var/obj/item/robot_parts/robot_suit/chassis = new dismantle_type(loc) + chassis.dismantled_from(src) qdel(src) /mob/living/silicon/robot/try_stock_parts_install(obj/item/stock_parts/W, mob/user) From ead9e478fdac31a7d9ac80232ebe7edae532e469 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 23 Jan 2025 17:55:02 -0500 Subject: [PATCH 119/120] Unify floor turf reagent handling --- code/game/turfs/floors/_floor.dm | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/code/game/turfs/floors/_floor.dm b/code/game/turfs/floors/_floor.dm index d319eb06c8c2..d7e8441fda07 100644 --- a/code/game/turfs/floors/_floor.dm +++ b/code/game/turfs/floors/_floor.dm @@ -44,8 +44,7 @@ if(floortype) set_flooring(GET_DECL(floortype), skip_update = TRUE) - if(fill_reagent_type && get_physical_height() < 0) - add_to_reagents(fill_reagent_type, abs(height), phase = MAT_PHASE_LIQUID) + fill_to_zero_height() // try to refill turfs that act as fluid sources if(floor_material || get_topmost_flooring()) if(ml) @@ -71,6 +70,12 @@ STOP_PROCESSING(SSobj, src) return ..() +/turf/floor/proc/fill_to_zero_height() + var/my_height = get_physical_height() + if(fill_reagent_type && my_height < 0 && (!reagents || !QDELING(reagents)) && reagents?.total_volume < abs(my_height)) + var/reagents_to_add = abs(my_height) - reagents?.total_volume + add_to_reagents(fill_reagent_type, reagents_to_add, phase = MAT_PHASE_LIQUID) + /turf/floor/can_climb_from_below(var/mob/climber) return TRUE @@ -92,9 +97,9 @@ /turf/floor/on_reagent_change() . = ..() - var/my_height = get_physical_height() - if(!QDELETED(src) && fill_reagent_type && my_height < 0 && !QDELETED(reagents) && reagents.total_volume < abs(my_height)) - add_to_reagents(fill_reagent_type, abs(my_height) - reagents.total_volume) + if(!QDELETED(src)) + fill_to_zero_height() + update_floor_strings() /turf/floor/proc/set_base_flooring(new_base_flooring, skip_update) if(ispath(new_base_flooring, /decl/flooring)) From c86a66c784e293ec7fcd219523790fe7be616f4f Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Wed, 22 Jan 2025 23:05:45 +1100 Subject: [PATCH 120/120] Cleaning up/generalizing some procs for electrical shock to handle mobs not using their hands. --- code/__defines/species.dm | 1 + code/datums/wires/smes.dm | 78 +++++++++---------- .../objects/items/weapons/material/shards.dm | 2 +- code/game/objects/structures/grille.dm | 33 ++++---- code/modules/mob/inventory.dm | 6 ++ code/modules/mob/living/carbon/carbon.dm | 28 +++---- .../mob/living/carbon/human/human_defense.dm | 31 -------- code/modules/mob/living/living_defense.dm | 10 ++- code/modules/mob/living/silicon/silicon.dm | 26 ++++--- code/modules/mob/mob_damage.dm | 21 +++++ code/modules/power/power.dm | 15 ++-- code/modules/species/species_helpers.dm | 6 +- 12 files changed, 129 insertions(+), 128 deletions(-) diff --git a/code/__defines/species.dm b/code/__defines/species.dm index 0ff09486031d..791e81cd17d3 100644 --- a/code/__defines/species.dm +++ b/code/__defines/species.dm @@ -8,6 +8,7 @@ #define SPECIES_FLAG_NO_BLOCK BITFLAG(6) // Unable to block or defend itself from attackers. #define SPECIES_FLAG_NEED_DIRECT_ABSORB BITFLAG(7) // This species can only have their DNA taken by direct absorption. #define SPECIES_FLAG_LOW_GRAV_ADAPTED BITFLAG(8) // This species is used to lower than standard gravity, affecting stamina in high-grav +#define SPECIES_FLAG_ABSORB_ELECTRICITY BITFLAG(9) // This species can absorb electricity; snowflake flag for old slime people. // Species spawn flags #define SPECIES_IS_WHITELISTED BITFLAG(0) // Must be whitelisted to play. diff --git a/code/datums/wires/smes.dm b/code/datums/wires/smes.dm index 15eff146d156..7cc90b2d664a 100644 --- a/code/datums/wires/smes.dm +++ b/code/datums/wires/smes.dm @@ -9,68 +9,68 @@ new /datum/wire_description(SMES_WIRE_FAILSAFES, "This wire appears to connect to a failsafe mechanism.") ) -var/global/const/SMES_WIRE_RCON = 1 // Remote control (AI and consoles), cut to disable -var/global/const/SMES_WIRE_INPUT = 2 // Input wire, cut to disable input, pulse to disable for 60s -var/global/const/SMES_WIRE_OUTPUT = 4 // Output wire, cut to disable output, pulse to disable for 60s -var/global/const/SMES_WIRE_GROUNDING = 8 // Cut to quickly discharge causing sparks, pulse to only create few sparks -var/global/const/SMES_WIRE_FAILSAFES = 16 // Cut to disable failsafes, mend to reenable - - -/datum/wires/smes/CanUse(var/mob/living/L) - var/obj/machinery/power/smes/buildable/S = holder - if(!S.grounding && S.powernet && S.powernet.avail) - electrocute_mob(L, S.powernet, S, S.safeties_enabled? 0.1 : 1) - if(S.panel_open) - return 1 - return 0 +/// Remote control (AI and consoles), cut to disable +var/global/const/SMES_WIRE_RCON = BITFLAG(0) +/// Input wire, cut to disable input, pulse to disable for 60s +var/global/const/SMES_WIRE_INPUT = BITFLAG(1) +/// Output wire, cut to disable output, pulse to disable for 60s +var/global/const/SMES_WIRE_OUTPUT = BITFLAG(2) +/// Cut to quickly discharge causing sparks, pulse to only create few sparks +var/global/const/SMES_WIRE_GROUNDING = BITFLAG(3) +/// Cut to disable failsafes, mend to reenable +var/global/const/SMES_WIRE_FAILSAFES = BITFLAG(4) +/datum/wires/smes/CanUse(var/mob/living/user) + var/obj/machinery/power/smes/buildable/storage = holder + if(!storage.grounding && storage.powernet && storage.powernet.avail) + electrocute_mob(user, storage.powernet, storage, (storage.safeties_enabled? 0.1 : 1)) + return storage.panel_open /datum/wires/smes/GetInteractWindow(mob/user) - var/obj/machinery/power/smes/buildable/S = holder + var/obj/machinery/power/smes/buildable/storage = holder . += ..() - . += "The green light is [(S.input_cut || S.input_pulsed || S.output_cut || S.output_pulsed) ? "off" : "on"]
    " - . += "The red light is [(S.safeties_enabled || S.grounding) ? "off" : "blinking"]
    " - . += "The blue light is [S.RCon ? "on" : "off"]" - + . += "The green light is [(storage.input_cut || storage.input_pulsed || storage.output_cut || storage.output_pulsed) ? "off" : "on"]
    " + . += "The red light is [(storage.safeties_enabled || storage.grounding) ? "off" : "blinking"]
    " + . += "The blue light is [storage.RCon ? "on" : "off"]" /datum/wires/smes/UpdateCut(var/index, var/mended) - var/obj/machinery/power/smes/buildable/S = holder + var/obj/machinery/power/smes/buildable/storage = holder switch(index) if(SMES_WIRE_RCON) - S.RCon = mended + storage.RCon = mended if(SMES_WIRE_INPUT) - S.input_cut = !mended + storage.input_cut = !mended if(SMES_WIRE_OUTPUT) - S.output_cut = !mended + storage.output_cut = !mended if(SMES_WIRE_GROUNDING) - S.grounding = mended + storage.grounding = mended if(SMES_WIRE_FAILSAFES) - S.safeties_enabled = mended + storage.safeties_enabled = mended /datum/wires/smes/proc/reset_rcon() - var/obj/machinery/power/smes/buildable/S = holder - if(S) - S.RCon = TRUE + var/obj/machinery/power/smes/buildable/storage = holder + if(storage) + storage.RCon = TRUE /datum/wires/smes/proc/reset_safeties() - var/obj/machinery/power/smes/buildable/S = holder - if(S) - S.safeties_enabled = TRUE + var/obj/machinery/power/smes/buildable/storage = holder + if(storage) + storage.safeties_enabled = TRUE /datum/wires/smes/UpdatePulsed(var/index) - var/obj/machinery/power/smes/buildable/S = holder + var/obj/machinery/power/smes/buildable/storage = holder switch(index) if(SMES_WIRE_RCON) - if(S.RCon) - S.RCon = 0 + if(storage.RCon) + storage.RCon = 0 addtimer(CALLBACK(src, PROC_REF(reset_rcon)), 1 SECOND) if(SMES_WIRE_INPUT) - S.toggle_input() + storage.toggle_input() if(SMES_WIRE_OUTPUT) - S.toggle_output() + storage.toggle_output() if(SMES_WIRE_GROUNDING) - S.grounding = 0 + storage.grounding = 0 if(SMES_WIRE_FAILSAFES) - if(S.safeties_enabled) - S.safeties_enabled = 0 + if(storage.safeties_enabled) + storage.safeties_enabled = 0 addtimer(CALLBACK(src, PROC_REF(reset_safeties)), 1 SECOND) diff --git a/code/game/objects/items/weapons/material/shards.dm b/code/game/objects/items/weapons/material/shards.dm index cfad08854a48..5035124e1b9c 100644 --- a/code/game/objects/items/weapons/material/shards.dm +++ b/code/game/objects/items/weapons/material/shards.dm @@ -104,7 +104,7 @@ playsound(src.loc, 'sound/effects/glass_step.ogg', 50, 1) // not sure how to handle metal shards with sounds var/decl/species/walker_species = M.get_species() - if(walker_species && (walker_species.siemens_coefficient<0.5 || (walker_species.species_flags & (SPECIES_FLAG_NO_EMBED|SPECIES_FLAG_NO_MINOR_CUT)))) //Thick skin. + if(walker_species?.species_flags & (SPECIES_FLAG_NO_EMBED|SPECIES_FLAG_NO_MINOR_CUT)) //Thick skin. return var/obj/item/shoes = M.get_equipped_item(slot_shoes_str) diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index c5231af0360e..43a18ba6657e 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -85,7 +85,8 @@ add_overlay(I) /obj/structure/grille/Bumped(atom/user) - if(ismob(user)) shock(user, 70) + if(ismob(user)) + shock(user, 70) /obj/structure/grille/attack_hand(mob/user) @@ -226,25 +227,23 @@ // returns 1 if shocked, 0 otherwise /obj/structure/grille/proc/shock(mob/user, prb) if(!anchored || destroyed) // anchored/destroyed grilles are never connected - return 0 + return FALSE if(!(material.conductive)) - return 0 + return FALSE if(!prob(prb)) - return 0 + return FALSE if(!in_range(src, user))//To prevent TK and exosuit users from getting shocked - return 0 - var/turf/T = get_turf(src) - var/obj/structure/cable/C = T.get_cable_node() - if(C) - if(electrocute_mob(user, C, src)) - if(C.powernet) - C.powernet.trigger_warning() - spark_at(src, cardinal_only = TRUE) - if(HAS_STATUS(user, STAT_STUN)) - return 1 - else - return 0 - return 0 + return FALSE + var/turf/my_turf = get_turf(src) + var/obj/structure/cable/cable = my_turf.get_cable_node() + if(!cable) + return FALSE + if(!electrocute_mob(user, cable, src)) + return FALSE + if(cable.powernet) + cable.powernet.trigger_warning() + spark_at(src, cardinal_only = TRUE) + return !!HAS_STATUS(user, STAT_STUN) /obj/structure/grille/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) if(!destroyed) diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 1cde56a39dc9..6c737fb8feea 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -405,3 +405,9 @@ var/org = GET_EXTERNAL_ORGAN(src, hand_slot) if(org) LAZYDISTINCTADD(., org) + +/mob/proc/get_active_hand_bodypart_flags() + var/datum/inventory_slot/gripper/inv_slot = get_inventory_slot_datum(get_active_held_item_slot()) + if(istype(inv_slot)) + . = inv_slot.covering_slot_flags + . ||= SLOT_HANDS diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index bcfa4ea35052..018ea79c0dcc 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -66,29 +66,26 @@ gib() /mob/living/carbon/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0, var/def_zone = null) - if(status_flags & GODMODE) return 0 //godmode - shock_damage = apply_shock(shock_damage, def_zone, siemens_coeff) - - if(!shock_damage) + shock_damage = ..() + if(shock_damage <= 0) return 0 + shock_damage = apply_shock(shock_damage, def_zone, siemens_coeff) stun_effect_act(agony_amount=shock_damage, def_zone=def_zone) - playsound(loc, "sparks", 50, 1, -1) if (shock_damage > 15) - src.visible_message( - "[src] was electrocuted[source ? " by the [source]" : ""]!", \ - "You feel a powerful shock course through your body!", \ - "You hear a heavy electrical crack." \ + visible_message( + SPAN_DANGER("\The [src] was electrocuted[source ? " by the [source]" : ""]!"), + SPAN_DANGER("You feel a powerful shock course through your body!"), + SPAN_DANGER("You hear a heavy electrical crack.") ) else - src.visible_message( - "[src] was shocked[source ? " by the [source]" : ""].", \ - "You feel a shock course through your body.", \ - "You hear a zapping sound." \ + visible_message( + SPAN_DANGER("\The [src] was shocked[source ? " by the [source]" : ""]."), + SPAN_DANGER("You feel a shock course through your body."), + SPAN_DANGER("You hear a zapping sound.") ) - switch(shock_damage) if(11 to 15) SET_STATUS_MAX(src, STAT_STUN, 1) @@ -100,11 +97,8 @@ SET_STATUS_MAX(src, STAT_WEAK, 5) if(31 to INFINITY) SET_STATUS_MAX(src, STAT_WEAK, 10) //This should work for now, more is really silly and makes you lay there forever - set_status(STAT_JITTER, min(shock_damage*5, 200)) - spark_at(loc, amount=5, cardinal_only = TRUE) - return shock_damage /mob/living/carbon/proc/apply_shock(var/shock_damage, var/def_zone, var/siemens_coeff = 1.0) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 7d337970d53a..26bb3c64f94a 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -85,19 +85,6 @@ meteor_act // Add inherent armor to the end of list so that protective equipment is checked first . += ..() -//this proc returns the Siemens coefficient of electrical resistivity for a particular external organ. -/mob/living/carbon/human/proc/get_siemens_coefficient_organ(var/obj/item/organ/external/def_zone) - if (!def_zone) - return 1.0 - - var/siemens_coefficient = max(species.siemens_coefficient,0) - for(var/slot in global.standard_clothing_slots) - var/obj/item/clothing/C = get_equipped_item(slot) - if(istype(C) && (C.body_parts_covered & def_zone.body_part)) // Is that body part being targeted covered? - siemens_coefficient *= C.siemens_coefficient - - return siemens_coefficient - /mob/living/carbon/human/proc/check_head_coverage() for(var/slot in global.standard_headgear_slots) var/obj/item/clothing/clothes = get_equipped_item(slot) @@ -373,24 +360,6 @@ meteor_act fire_act(air, temperature) return FALSE -//Removed the horrible safety parameter. It was only being used by ninja code anyways. -//Now checks siemens_coefficient of the affected area by default -/mob/living/carbon/human/electrocute_act(var/shock_damage, var/obj/source, var/base_siemens_coeff = 1.0, var/def_zone = null) - - if(status_flags & GODMODE) return 0 //godmode - - if(species.siemens_coefficient == -1) - if(stored_shock_by_ref["\ref[src]"]) - stored_shock_by_ref["\ref[src]"] += shock_damage - else - stored_shock_by_ref["\ref[src]"] = shock_damage - return - - if (!def_zone) - def_zone = pick(BP_L_HAND, BP_R_HAND) - - return ..(shock_damage, source, base_siemens_coeff, def_zone) - /mob/living/carbon/human/explosion_act(severity) ..() if(QDELETED(src)) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index ddc6d17d8b0e..a33044b3ad53 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -97,7 +97,15 @@ apply_effect(agony_amount/10, EYE_BLUR) /mob/living/proc/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0, def_zone = null) - return 0 //only carbon liveforms have this proc + SHOULD_CALL_PARENT(TRUE) + if(status_flags & GODMODE) + return 0 + var/decl/species/my_species = get_species() + if(my_species?.species_flags & SPECIES_FLAG_ABSORB_ELECTRICITY) + spark_at(loc, amount=5, cardinal_only = TRUE) + LAZYADD(global.stored_shock_by_ref["\ref[src]"], shock_damage) + return 0 + return shock_damage /mob/living/emp_act(severity) var/list/L = src.get_contents() diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index c23a0e0faa43..12ddf623401e 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -124,17 +124,21 @@ /mob/living/silicon/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0, def_zone = null) - if (istype(source, /obj/effect/containment_field)) - spark_at(loc, amount=5, cardinal_only = TRUE) - - shock_damage *= 0.75 //take reduced damage - take_overall_damage(0, shock_damage) - visible_message("\The [src] was shocked by \the [source]!", \ - "Energy pulse detected, system damaged!", \ - "You hear an electrical crack") - if(prob(20)) - SET_STATUS_MAX(src, STAT_STUN, 2) - return + shock_damage = ..() + if(shock_damage <= 0 || !istype(source, /obj/effect/containment_field)) + return 0 + + spark_at(loc, amount=5, cardinal_only = TRUE) + shock_damage *= 0.75 //take reduced damage + take_overall_damage(0, shock_damage) + visible_message( + SPAN_DANGER("\The [src] was shocked by \the [source]!"), + SPAN_DANGER("Energy pulse detected, system damaged!"), + SPAN_DANGER("You hear an electrical crack.") + ) + if(prob(20)) + SET_STATUS_MAX(src, STAT_STUN, 2) + return shock_damage /mob/living/silicon/proc/damage_mob(var/brute = 0, var/fire = 0, var/tox = 0) return diff --git a/code/modules/mob/mob_damage.dm b/code/modules/mob/mob_damage.dm index 94adae932a99..f52cc527f4c1 100644 --- a/code/modules/mob/mob_damage.dm +++ b/code/modules/mob/mob_damage.dm @@ -58,3 +58,24 @@ SHOULD_CALL_PARENT(TRUE) if(do_update_health) update_health() + +// Calculates the Siemen's coefficient for a given area of the body. +// 1 is 100% vulnerability, 0 is immune. +/mob/proc/get_siemens_coefficient_for_coverage(coverage_flags = SLOT_HANDS) + var/decl/species/my_species = get_species() + . = my_species ? my_species.siemens_coefficient : 1 + if(. <= 0) + return 0 + if(coverage_flags) + for(var/obj/item/clothing/clothes in get_equipped_items(include_carried = FALSE)) + if(clothes.body_parts_covered & coverage_flags) + if(clothes.siemens_coefficient <= 0) + return 0 + . *= clothes.siemens_coefficient + if(. <= 0) + return 0 + . = max(round(., 0.1), 0) + +//this proc returns the Siemens coefficient of electrical resistivity for a particular external organ. +/mob/proc/get_siemens_coefficient_organ(var/obj/item/organ/external/def_zone) + return (istype(def_zone) && def_zone.body_part) ? get_siemens_coefficient_for_coverage(def_zone.body_part) : 1 diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index d2db88a1164c..9642a5abcc79 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -183,7 +183,10 @@ //power_source is a source of electricity, can be powercell, area, apc, cable, powernet or null //source is an object caused electrocuting (airlock, grille, etc) //No animations will be performed by this proc. -/proc/electrocute_mob(mob/living/carbon/M, var/power_source, var/obj/source, var/siemens_coeff = 1.0) +/proc/electrocute_mob(mob/living/carbon/M, power_source, obj/source, siemens_coeff = 1.0, coverage_flags = SLOT_HANDS) + + coverage_flags = M?.get_active_hand_bodypart_flags() || coverage_flags + var/area/source_area if(istype(power_source,/area)) source_area = power_source @@ -214,13 +217,9 @@ //If following checks determine user is protected we won't alarm for long. if(PN) PN.trigger_warning(5) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(H.species.siemens_coefficient <= 0) - return - var/obj/item/clothing/gloves/G = H.get_equipped_item(slot_gloves_str) - if(istype(G) && G.siemens_coefficient == 0) - return 0 //to avoid spamming with insulated glvoes on + + if(M.get_siemens_coefficient_for_coverage(coverage_flags) <= 0) + return //Checks again. If we are still here subject will be shocked, trigger standard 20 tick warning //Since this one is longer it will override the original one. diff --git a/code/modules/species/species_helpers.dm b/code/modules/species/species_helpers.dm index 5ac85615ad46..6be3e01dd47a 100644 --- a/code/modules/species/species_helpers.dm +++ b/code/modules/species/species_helpers.dm @@ -1,9 +1,9 @@ var/global/list/stored_shock_by_ref = list() /mob/living/proc/apply_stored_shock_to(var/mob/living/target) - if(stored_shock_by_ref["\ref[src]"]) - target.electrocute_act(stored_shock_by_ref["\ref[src]"]*0.9, src) - stored_shock_by_ref["\ref[src]"] = 0 + if(global.stored_shock_by_ref["\ref[src]"]) + target.electrocute_act(global.stored_shock_by_ref["\ref[src]"]*0.9, src) + global.stored_shock_by_ref["\ref[src]"] = 0 /decl/species/proc/toggle_stance(var/mob/living/carbon/human/H) if(!H.incapacitated())