mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-30 16:47:13 +01:00
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 🆑 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. /🆑
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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]"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user