From b7383bc503947bee07805dd7c073b0ab7ddc72da Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Wed, 26 Mar 2025 17:55:32 +0100 Subject: [PATCH] Refactors MODsuit slowdown calculations (#90116) ## About The Pull Request MODsuits now calculate their slowdown by querying modules by sending a signal on themselves instead of having modules try and keep up with control unit's speed updates (which broke in a fabulous fashion after MODsuits were allowed to deploy by piece) Also added a separate trait to prevent objects from being speed potion-ed to combat stabilized red crossbreed issues, and removed a duplicate list helper (40 lines down in the same file lol) Closes #89979 Closes #90036 ## Changelog :cl: fix: MODsuits should now be affected by stabilized red crossbreeds fix: MODsuit slowdowns should no longer behave weirdly with ash accretion/magboots/armor booster modules. refactor: Refactored MODsuit slowdown calculations to be query-based instead of modules directly modifying part speed values. /:cl: --- code/__DEFINES/dcs/signals/signals_mod.dm | 2 ++ code/__DEFINES/traits/declarations.dm | 3 +++ code/__HELPERS/_lists.dm | 7 ----- code/_globalvars/traits/_traits.dm | 1 + code/controllers/subsystem/bitrunning.dm | 4 +-- .../bitrunning/server/obj_generation.dm | 2 +- code/modules/mafia/controller.dm | 2 +- code/modules/mafia/controller_ui.dm | 2 +- code/modules/mod/mod_clothes.dm | 18 ++++++++++--- code/modules/mod/mod_control.dm | 22 ++++++++++++---- code/modules/mod/mod_theme.dm | 8 +++--- code/modules/mod/modules/modules_antag.dm | 26 ++++++++++--------- .../mod/modules/modules_engineering.dm | 17 +++++++++--- code/modules/mod/modules/modules_supply.dm | 23 ++++++++-------- .../research/xenobiology/xenobiology.dm | 2 +- 15 files changed, 87 insertions(+), 52 deletions(-) diff --git a/code/__DEFINES/dcs/signals/signals_mod.dm b/code/__DEFINES/dcs/signals/signals_mod.dm index 70c434adae3..6cc6832beb6 100644 --- a/code/__DEFINES/dcs/signals/signals_mod.dm +++ b/code/__DEFINES/dcs/signals/signals_mod.dm @@ -48,3 +48,5 @@ #define COMSIG_MODULE_GENERATE_WORN_OVERLAY "mod_module_generate_worn_overlay" /// Called when the MOD control unit fetches its visor icon #define COMSIG_MOD_GET_VISOR_OVERLAY "mod_get_visor_overlay" +/// Called when the MOD control unit updates its parts speed +#define COMSIG_MOD_UPDATE_SPEED "mod_update_speed" diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index 8fadf09aaab..c0340db854b 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -1469,4 +1469,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai ///trait given to mobs that are easy to tame through mounting #define TRAIT_MOB_EASY_TO_MOUNT "easy_to_mount" +/// Prevents items from being speed potion-ed, but allows their speed to be altered in other ways +#define TRAIT_NO_SPEED_POTION "no_speed_potion" + // END TRAIT DEFINES diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm index 8b47d6756f5..4cb7a4e34ac 100644 --- a/code/__HELPERS/_lists.dm +++ b/code/__HELPERS/_lists.dm @@ -958,13 +958,6 @@ UNTYPED_LIST_ADD(keys, key) return keys -///Gets the total amount of everything in the associative list. -/proc/assoc_value_sum(list/input) - var/keys = 0 - for(var/key in input) - keys += input[key] - return keys - ///compare two lists, returns TRUE if they are the same /proc/compare_list(list/l,list/d) if(!islist(l) || !islist(d)) diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 8362fdd8308..5f2fc6407c0 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -626,6 +626,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_NEEDS_TWO_HANDS" = TRAIT_NEEDS_TWO_HANDS, "TRAIT_NO_BARCODES" = TRAIT_NO_BARCODES, "TRAIT_NO_STORAGE_INSERT" = TRAIT_NO_STORAGE_INSERT, + "TRAIT_NO_SPEED_POTION" = TRAIT_NO_SPEED_POTION, "TRAIT_NO_TELEPORT" = TRAIT_NO_TELEPORT, "TRAIT_NO_SIDE_KICK" = TRAIT_NO_SIDE_KICK, "TRAIT_NODROP" = TRAIT_NODROP, diff --git a/code/controllers/subsystem/bitrunning.dm b/code/controllers/subsystem/bitrunning.dm index 63c2561f0f4..5e6a1c6bd34 100644 --- a/code/controllers/subsystem/bitrunning.dm +++ b/code/controllers/subsystem/bitrunning.dm @@ -31,7 +31,7 @@ SUBSYSTEM_DEF(bitrunning) "difficulty" = domain.difficulty, "id" = domain.key, "is_modular" = domain.is_modular, - "has_secondary_objectives" = assoc_value_sum(domain.secondary_loot) ? TRUE : FALSE, + "has_secondary_objectives" = counterlist_sum(domain.secondary_loot) ? TRUE : FALSE, "name" = can_view ? domain.name : REDACTED, "reward" = can_view_reward ? domain.reward_points : REDACTED, )) @@ -42,7 +42,7 @@ SUBSYSTEM_DEF(bitrunning) var/datum/lazy_template/virtual_domain/domain = completed_domain var/choice - if(assoc_value_sum(domain.secondary_loot)) + if(counterlist_sum(domain.secondary_loot)) choice = pick_weight(domain.secondary_loot) domain.secondary_loot[choice] -= 1 else diff --git a/code/modules/bitrunning/server/obj_generation.dm b/code/modules/bitrunning/server/obj_generation.dm index cd2f39738d6..30f7b2c47e6 100644 --- a/code/modules/bitrunning/server/obj_generation.dm +++ b/code/modules/bitrunning/server/obj_generation.dm @@ -21,7 +21,7 @@ if(!length(possible_turfs)) // Out of turfs to place a curiosity return FALSE - if(generated_domain.secondary_loot_generated >= assoc_value_sum(generated_domain.secondary_loot)) // Out of curiosities to place + if(generated_domain.secondary_loot_generated >= counterlist_sum(generated_domain.secondary_loot)) // Out of curiosities to place return FALSE shuffle_inplace(possible_turfs) diff --git a/code/modules/mafia/controller.dm b/code/modules/mafia/controller.dm index d4edbb37f41..957f7f2bc42 100644 --- a/code/modules/mafia/controller.dm +++ b/code/modules/mafia/controller.dm @@ -710,7 +710,7 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment()) var/req_players = MAFIA_MAX_PLAYER_COUNT var/list/setup = custom_setup if(length(setup)) - req_players = assoc_value_sum(setup) + req_players = counterlist_sum(setup) var/list/filtered_keys_and_pdas = filter_players(req_players) diff --git a/code/modules/mafia/controller_ui.dm b/code/modules/mafia/controller_ui.dm index f45ea3a80aa..83857f66837 100644 --- a/code/modules/mafia/controller_ui.dm +++ b/code/modules/mafia/controller_ui.dm @@ -123,7 +123,7 @@ var/done = FALSE while(!done) - to_chat(usr, "You have a total player count of [assoc_value_sum(debug_setup)] in this setup.") + to_chat(usr, "You have a total player count of [counterlist_sum(debug_setup)] in this setup.") var/chosen_role_name = tgui_input_list(usr, "Select a role!", "Custom Setup Creation", rolelist_dict) if(!chosen_role_name) return diff --git a/code/modules/mod/mod_clothes.dm b/code/modules/mod/mod_clothes.dm index 8c4e5481b14..28428a8fe13 100644 --- a/code/modules/mod/mod_clothes.dm +++ b/code/modules/mod/mod_clothes.dm @@ -9,11 +9,11 @@ body_parts_covered = HEAD heat_protection = HEAD cold_protection = HEAD - item_flags = IMMUTABLE_SLOW // Even without a hat stabilizer, hats can be worn - however, they'll fall off very easily /obj/item/clothing/head/mod/Initialize(mapload) . = ..() + ADD_TRAIT(src, TRAIT_NO_SPEED_POTION, INNATE_TRAIT) AddComponent(/datum/component/hat_stabilizer, loose_hat = TRUE) /obj/item/clothing/suit/mod @@ -33,9 +33,12 @@ body_parts_covered = CHEST|GROIN heat_protection = CHEST|GROIN cold_protection = CHEST|GROIN - item_flags = IMMUTABLE_SLOW drop_sound = null +/obj/item/clothing/suit/mod/Initialize(mapload) + . = ..() + ADD_TRAIT(src, TRAIT_NO_SPEED_POTION, INNATE_TRAIT) + /obj/item/clothing/gloves/mod name = "MOD gauntlets" desc = "A pair of gauntlets for a MODsuit." @@ -47,11 +50,14 @@ body_parts_covered = HANDS|ARMS heat_protection = HANDS|ARMS cold_protection = HANDS|ARMS - item_flags = IMMUTABLE_SLOW equip_sound = null pickup_sound = null drop_sound = null +/obj/item/clothing/gloves/mod/Initialize(mapload) + . = ..() + ADD_TRAIT(src, TRAIT_NO_SPEED_POTION, INNATE_TRAIT) + /obj/item/clothing/shoes/mod name = "MOD boots" desc = "A pair of boots for a MODsuit." @@ -63,6 +69,10 @@ body_parts_covered = FEET|LEGS heat_protection = FEET|LEGS cold_protection = FEET|LEGS - item_flags = IGNORE_DIGITIGRADE | IMMUTABLE_SLOW + item_flags = IGNORE_DIGITIGRADE fastening_type = SHOES_SLIPON equip_sound = null + +/obj/item/clothing/shoes/mod/Initialize(mapload) + . = ..() + ADD_TRAIT(src, TRAIT_NO_SPEED_POTION, INNATE_TRAIT) diff --git a/code/modules/mod/mod_control.dm b/code/modules/mod/mod_control.dm index dbb2d5d0777..d662df70f9b 100644 --- a/code/modules/mod/mod_control.dm +++ b/code/modules/mod/mod_control.dm @@ -684,9 +684,19 @@ wearer.update_spacesuit_hud_icon(state_to_use || "0") /obj/item/mod/control/proc/update_speed() - for(var/obj/item/part as anything in get_parts(all = TRUE)) - part.slowdown = slowdown_deployed / length(mod_parts) - var/datum/mod_part/part_datum = get_part_datum(part) + var/total_slowdown = 0 + var/prevent_slowdown = HAS_TRAIT(src, TRAIT_SPEED_POTIONED) + if (!prevent_slowdown) + total_slowdown += slowdown_deployed + + var/list/module_slowdowns = list() + SEND_SIGNAL(src, COMSIG_MOD_UPDATE_SPEED, module_slowdowns, prevent_slowdown) + for (var/module_slow in module_slowdowns) + total_slowdown += module_slow + + for(var/datum/mod_part/part_datum as anything in get_part_datums(all = TRUE)) + var/obj/item/part = part_datum.part_item + part.slowdown = total_slowdown / length(mod_parts) if (!part_datum.sealed) part.slowdown = max(part.slowdown, 0) wearer?.update_equipment_speed_mods() @@ -747,15 +757,17 @@ /obj/item/mod/control/proc/on_potion(atom/movable/source, obj/item/slimepotion/speed/speed_potion, mob/living/user) SIGNAL_HANDLER - if(slowdown_deployed <= 0) + if(HAS_TRAIT(src, TRAIT_SPEED_POTIONED)) to_chat(user, span_warning("[src] has already been coated with red, that's as fast as it'll go!")) return SPEED_POTION_STOP + if(active) to_chat(user, span_warning("It's too dangerous to smear [speed_potion] on [src] while it's active!")) return SPEED_POTION_STOP + to_chat(user, span_notice("You slather the red gunk over [src], making it faster.")) set_mod_color(color_transition_filter(COLOR_RED)) - slowdown_deployed = 0 + ADD_TRAIT(src, TRAIT_SPEED_POTIONED, SLIME_POTION_TRAIT) update_speed() qdel(speed_potion) return SPEED_POTION_STOP diff --git a/code/modules/mod/mod_theme.dm b/code/modules/mod/mod_theme.dm index 9c2ada9899e..7ac3aeda0cc 100644 --- a/code/modules/mod/mod_theme.dm +++ b/code/modules/mod/mod_theme.dm @@ -119,6 +119,7 @@ part_datum.part_item = mod_part mod.mod_parts["[mod_part.slot_flags]"] = part_datum parts += mod_part + for(var/obj/item/part as anything in parts) part.name = "[name] [part.name]" part.desc = "[part.desc] [desc]" @@ -130,6 +131,7 @@ part.max_heat_protection_temperature = max_heat_protection_temperature part.min_cold_protection_temperature = min_cold_protection_temperature part.siemens_coefficient = siemens_coefficient + set_skin(mod, skin || default_skin) /datum/mod_theme/proc/set_skin(obj/item/mod/control/mod, skin) @@ -1156,7 +1158,7 @@ complexity_max = DEFAULT_MAX_COMPLEXITY + 3 max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT siemens_coefficient = 0 - slowdown_deployed = 0.5 + slowdown_deployed = 0 ui_theme = "syndicate" resistance_flags = FIRE_PROOF inbuilt_modules = list(/obj/item/mod/module/armor_booster) @@ -1263,7 +1265,7 @@ max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT complexity_max = DEFAULT_MAX_COMPLEXITY + 3 siemens_coefficient = 0 - slowdown_deployed = 0.5 + slowdown_deployed = 0 ui_theme = "syndicate" inbuilt_modules = list(/obj/item/mod/module/armor_booster) allowed_suit_storage = list( @@ -1696,7 +1698,7 @@ max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT complexity_max = DEFAULT_MAX_COMPLEXITY + 3 siemens_coefficient = 0 - slowdown_deployed = 0.5 + slowdown_deployed = 0 ui_theme = "ntos_terminal" inbuilt_modules = list(/obj/item/mod/module/armor_booster) allowed_suit_storage = list( diff --git a/code/modules/mod/modules/modules_antag.dm b/code/modules/mod/modules/modules_antag.dm index 2c39d3ebdbd..9dce0940b3f 100644 --- a/code/modules/mod/modules/modules_antag.dm +++ b/code/modules/mod/modules/modules_antag.dm @@ -18,17 +18,15 @@ mask_worn_overlay = TRUE /// Whether or not this module removes pressure protection. var/remove_pressure_protection = TRUE - /// Speed added to the control unit. - var/speed_added = 0.5 - /// Speed that we actually added. - var/actual_speed_added = 0 + /// Slowdown added to the control unit while this module is disabled + var/space_slowdown = 0.5 /// Armor values added to the suit parts. var/datum/armor/armor_mod = /datum/armor/mod_module_armor_boost /// List of parts of the suit that are spaceproofed, for giving them back the pressure protection. var/list/spaceproofed = list() /obj/item/mod/module/armor_booster/no_speedbost - speed_added = 0 + space_slowdown = 0 /datum/armor/mod_module_armor_boost melee = 25 @@ -37,36 +35,37 @@ energy = 15 /obj/item/mod/module/armor_booster/on_part_activation() + RegisterSignal(mod, COMSIG_MOD_UPDATE_SPEED, PROC_REF(on_update_speed)) var/obj/item/clothing/head_cover = mod.get_part_from_slot(ITEM_SLOT_HEAD) || mod.get_part_from_slot(ITEM_SLOT_MASK) || mod.get_part_from_slot(ITEM_SLOT_EYES) if(istype(head_cover)) head_cover.flash_protect = FLASH_PROTECTION_WELDER + mod.update_speed() /obj/item/mod/module/armor_booster/on_part_deactivation(deleting = FALSE) if(deleting) return + UnregisterSignal(mod, COMSIG_MOD_UPDATE_SPEED) var/obj/item/clothing/head_cover = mod.get_part_from_slot(ITEM_SLOT_HEAD) || mod.get_part_from_slot(ITEM_SLOT_MASK) || mod.get_part_from_slot(ITEM_SLOT_EYES) if(istype(head_cover)) head_cover.flash_protect = initial(head_cover.flash_protect) + mod.update_speed() /obj/item/mod/module/armor_booster/on_activation() playsound(src, 'sound/vehicles/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) balloon_alert(mod.wearer, "armor boosted, EVA lost") - actual_speed_added = max(0, min(mod.slowdown_deployed, speed_added)) var/datum/mod_part/head_cover = mod.get_part_datum_from_slot(ITEM_SLOT_HEAD) || mod.get_part_datum_from_slot(ITEM_SLOT_MASK) || mod.get_part_datum_from_slot(ITEM_SLOT_EYES) if(head_cover) RegisterSignal(mod, COMSIG_MOD_PART_SEALED, PROC_REF(seal_helmet)) seal_helmet(mod, head_cover) - var/list/mod_parts = mod.get_parts(all = TRUE) for(var/obj/item/part as anything in mod.get_parts(all = TRUE)) part.set_armor(part.get_armor().add_other_armor(armor_mod)) - part.slowdown -= speed_added / length(mod_parts) if(!remove_pressure_protection || !isclothing(part)) continue var/obj/item/clothing/clothing_part = part if(clothing_part.clothing_flags & STOPSPRESSUREDAMAGE) clothing_part.clothing_flags &= ~STOPSPRESSUREDAMAGE spaceproofed[clothing_part] = TRUE - mod.wearer.update_equipment_speed_mods() + mod.update_speed() /obj/item/mod/module/armor_booster/on_deactivation(display_message = TRUE, deleting = FALSE) if(!deleting) @@ -76,18 +75,21 @@ if(head_cover) UnregisterSignal(mod, COMSIG_MOD_PART_SEALED) REMOVE_TRAIT(mod.wearer, TRAIT_HEAD_INJURY_BLOCKED, REF(src)) - var/list/mod_parts = mod.get_parts(all = TRUE) for(var/obj/item/part as anything in mod.get_parts(all = TRUE)) part.set_armor(part.get_armor().subtract_other_armor(armor_mod)) - part.slowdown += speed_added / length(mod_parts) if(!remove_pressure_protection || !isclothing(part)) continue var/obj/item/clothing/clothing_part = part if(spaceproofed[clothing_part]) clothing_part.clothing_flags |= STOPSPRESSUREDAMAGE - mod.wearer.update_equipment_speed_mods() + mod.update_speed() spaceproofed = list() +/obj/item/mod/module/armor_booster/proc/on_update_speed(datum/source, list/module_slowdowns, prevent_slowdown) + SIGNAL_HANDLER + if (!active) + module_slowdowns += space_slowdown + /obj/item/mod/module/armor_booster/generate_worn_overlay(mutable_appearance/standing) overlay_state_inactive = "[initial(overlay_state_inactive)]-[mod.skin]" overlay_state_active = "[initial(overlay_state_active)]-[mod.skin]" diff --git a/code/modules/mod/modules/modules_engineering.dm b/code/modules/mod/modules/modules_engineering.dm index af22a60d383..9af2ea0bc5a 100644 --- a/code/modules/mod/modules/modules_engineering.dm +++ b/code/modules/mod/modules/modules_engineering.dm @@ -61,15 +61,24 @@ /// A list of traits to add to the wearer when we're active (see: Magboots) var/list/active_traits = list(TRAIT_NO_SLIP_WATER, TRAIT_NO_SLIP_ICE, TRAIT_NO_SLIP_SLIDE, TRAIT_NEGATES_GRAVITY) +/obj/item/mod/module/magboot/on_install() + RegisterSignal(mod, COMSIG_MOD_UPDATE_SPEED, PROC_REF(on_update_speed)) + +/obj/item/mod/module/magboot/on_uninstall(deleting) + UnregisterSignal(mod, COMSIG_MOD_UPDATE_SPEED) + /obj/item/mod/module/magboot/on_activation() mod.wearer.add_traits(active_traits, REF(src)) - mod.slowdown += slowdown_active - mod.wearer.update_equipment_speed_mods() + mod.update_speed() /obj/item/mod/module/magboot/on_deactivation(display_message = TRUE, deleting = FALSE) mod.wearer.remove_traits(active_traits, REF(src)) - mod.slowdown -= slowdown_active - mod.wearer.update_equipment_speed_mods() + mod.update_speed() + +/obj/item/mod/module/magboot/proc/on_update_speed(datum/source, list/module_slowdowns, prevent_slowdown) + SIGNAL_HANDLER + if (!prevent_slowdown && active) + module_slowdowns += slowdown_active /obj/item/mod/module/magboot/advanced name = "MOD advanced magnetic stability module" diff --git a/code/modules/mod/modules/modules_supply.dm b/code/modules/mod/modules/modules_supply.dm index 97346262e56..bef88f0eb8e 100644 --- a/code/modules/mod/modules/modules_supply.dm +++ b/code/modules/mod/modules/modules_supply.dm @@ -369,9 +369,7 @@ /// Armor values per tile. var/datum/armor/armor_mod = /datum/armor/mod_ash_accretion /// Speed added when you're fully covered in ash. - var/speed_added = 0.5 - /// Speed that we actually added. - var/actual_speed_added = 0 + var/speed_added = -0.5 /// Turfs that let us accrete ash. var/static/list/accretion_turfs /// Turfs that let us keep ash. @@ -409,24 +407,30 @@ /obj/item/mod/module/ash_accretion/on_part_activation() mod.wearer.add_traits(list(TRAIT_ASHSTORM_IMMUNE, TRAIT_SNOWSTORM_IMMUNE), REF(src)) RegisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED, PROC_REF(on_move)) + RegisterSignal(mod, COMSIG_MOD_UPDATE_SPEED, PROC_REF(on_update_speed)) /obj/item/mod/module/ash_accretion/on_part_deactivation(deleting = FALSE) mod.wearer.remove_traits(list(TRAIT_ASHSTORM_IMMUNE, TRAIT_SNOWSTORM_IMMUNE), REF(src)) UnregisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED) + UnregisterSignal(mod, COMSIG_MOD_UPDATE_SPEED) if(!traveled_tiles) return var/datum/armor/to_remove = get_armor_by_type(armor_mod) for(var/obj/item/part as anything in mod.get_parts(all = TRUE)) part.set_armor(part.get_armor().subtract_other_armor(to_remove.generate_new_with_multipliers(list(ARMOR_ALL = traveled_tiles)))) if(traveled_tiles == max_traveled_tiles) - mod.slowdown += speed_added - mod.wearer.update_equipment_speed_mods() + mod.update_speed() traveled_tiles = 0 /obj/item/mod/module/ash_accretion/generate_worn_overlay(mutable_appearance/standing) overlay_state_inactive = "[initial(overlay_state_inactive)]-[mod.skin]" return ..() +/obj/item/mod/module/ash_accretion/proc/on_update_speed(datum/source, list/module_slowdowns, prevent_slowdown) + SIGNAL_HANDLER + if (traveled_tiles == max_traveled_tiles) + module_slowdowns += speed_added + /obj/item/mod/module/ash_accretion/proc/on_move(atom/source, atom/oldloc, dir, forced) if(!isturf(mod.wearer.loc)) //dont lose ash from going in a locker return @@ -443,18 +447,15 @@ mod.wearer.color = list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,3) //make them super light animate(mod.wearer, 1 SECONDS, color = null, flags = ANIMATION_PARALLEL) playsound(src, 'sound/effects/sparks/sparks1.ogg', 100, TRUE) - actual_speed_added = max(0, min(mod.slowdown_deployed, speed_added)) - mod.slowdown -= actual_speed_added - mod.wearer.update_equipment_speed_mods() + mod.update_speed() else if(is_type_in_typecache(mod.wearer.loc, keep_turfs)) return else if(traveled_tiles <= 0) return - if(traveled_tiles == max_traveled_tiles) - mod.slowdown += actual_speed_added - mod.wearer.update_equipment_speed_mods() traveled_tiles-- + if(traveled_tiles == max_traveled_tiles - 1) // Just lost our speed buff + mod.update_speed() for(var/obj/item/part as anything in mod.get_parts(all = TRUE)) part.set_armor(part.get_armor().subtract_other_armor(armor_mod)) if(traveled_tiles <= 0) diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index 71e8f04b4b5..d6bcb8cff2d 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -912,7 +912,7 @@ return ITEM_INTERACT_SUCCESS if(isitem(interacting_with)) var/obj/item/apply_to = interacting_with - if(apply_to.slowdown <= 0 || (apply_to.item_flags & IMMUTABLE_SLOW)) + if(apply_to.slowdown <= 0 || (apply_to.item_flags & IMMUTABLE_SLOW) || HAS_TRAIT(apply_to, TRAIT_NO_SPEED_POTION)) if(interacting_with.atom_storage) return NONE // lets us put the potion in the bag to_chat(user, span_warning("[apply_to] can't be made any faster!"))