diff --git a/code/__DEFINES/movespeed_modification.dm b/code/__DEFINES/movespeed_modification.dm
index ae2a753f1c6..6b8ef7bd567 100644
--- a/code/__DEFINES/movespeed_modification.dm
+++ b/code/__DEFINES/movespeed_modification.dm
@@ -1,12 +1,3 @@
-#define MOVESPEED_DATA_INDEX_PRIORITY 1
-#define MOVESPEED_DATA_INDEX_FLAGS 2
-#define MOVESPEED_DATA_INDEX_MULTIPLICATIVE_SLOWDOWN 3
-#define MOVESPEED_DATA_INDEX_MOVETYPE 4
-#define MOVESPEED_DATA_INDEX_BL_MOVETYPE 5
-#define MOVESPEED_DATA_INDEX_CONFLICT 6
-
-#define MOVESPEED_DATA_INDEX_MAX 6
-
//flags
#define IGNORE_NOSLOW (1 << 0)
@@ -15,67 +6,7 @@
#define MOVE_CONFLICT_JETPACK "JETPACK"
//ids
+#define MOVESPEED_ID_SANITY "sanity_component"
-#define MOVESPEED_ID_MOB_WALK_RUN_CONFIG_SPEED "MOB_WALK_RUN"
-#define MOVESPEED_ID_MOB_GRAB_STATE "MOB_GRAB_STATE"
-#define MOVESPEED_ID_MOB_EQUIPMENT "MOB_EQUIPMENT"
-#define MOVESPEED_ID_MOB_GRAVITY "MOB_GRAVITY"
-#define MOVESPEED_ID_CONFIG_SPEEDMOD "MOB_CONFIG_MODIFIER"
-
-#define MOVESPEED_ID_SLIME_REAGENTMOD "SLIME_REAGENT_MODIFIER"
-#define MOVESPEED_ID_SLIME_HEALTHMOD "SLIME_HEALTH_MODIFIER"
-#define MOVESPEED_ID_SLIME_TEMPMOD "SLIME_TEMPERATURE_MODIFIER"
-
-#define MOVESPEED_ID_SLIME_STATUS "SLIME_STATUS"
-
-#define MOVESPEED_ID_TARANTULA_WEB "TARANTULA_WEB"
-
-#define MOVESPEED_ID_LIVING_TURF_SPEEDMOD "LIVING_TURF_SPEEDMOD"
-#define MOVESPEED_ID_LIVING_LIMBLESS "LIVING_LIMBLESS"
-
-#define MOVESPEED_ID_CARBON_SOFTCRIT "CARBON_SOFTCRIT"
-#define MOVESPEED_ID_CARBON_OLDSPEED "CARBON_DEPRECATED_SPEED"
-#define MOVESPEED_ID_CARBON_CRAWLING "CARBON_CRAWLING"
-
-#define MOVESPEED_ID_DNA_VAULT "DNA_VAULT"
-
-#define MOVESPEED_ID_YELLOW_ORB "YELLOW_ORB"
-
-#define MOVESPEED_ID_TARFOOT "TARFOOT"
-
-#define MOVESPEED_ID_SEPIA "SEPIA"
-
-#define MOVESPEED_ID_MONKEY_REAGENT_SPEEDMOD "MONKEY_REAGENT_SPEEDMOD"
-#define MOVESPEED_ID_MONKEY_TEMPERATURE_SPEEDMOD "MONKEY_TEMPERATURE_SPEEDMOD"
-#define MOVESPEED_ID_MONKEY_HEALTH_SPEEDMOD "MONKEY_HEALTH_SPEEDMOD"
-
-#define MOVESPEED_ID_CHANGELING_MUSCLES "CHANGELING_MUSCLES"
-
-#define MOVESPEED_ID_SIMPLEMOB_VARSPEED "SIMPLEMOB_VARSPEED_MODIFIER"
-#define MOVESPEED_ID_ADMIN_VAREDIT "ADMIN_VAREDIT_MODIFIER"
-
-#define MOVESPEED_ID_PAI_SPACEWALK_SPEEDMOD "PAI_SPACEWALK_MODIFIER"
-
-#define MOVESPEED_ID_SANITY "MOOD_SANITY"
-
-#define MOVESPEED_ID_SPECIES "SPECIES_SPEED_MOD"
-#define MOVESPEED_ID_SNAIL_CRAWL "SNAIL_CRAWL_SPEED_MOD"
-
-#define MOVESPEED_ID_CYBER_THRUSTER "CYBER_IMPLANT_THRUSTER"
-#define MOVESPEED_ID_JETPACK "JETPACK"
-
-#define MOVESPEED_ID_SLAUGHTER "SLAUGHTER"
-#define MOVESPEED_ID_DIE_OF_FATE "DIE_OF_FATE"
-
-#define MOVESPEED_ID_SHOVE "SHOVE"
-#define MOVESPEED_ID_BULKY_DRAGGING "BULKY_DRAG"
-#define MOVESPEED_ID_HUMAN_CARRYING "HUMAN_CARRY"
-#define MOVESPEED_ID_SHRINK_RAY "SHRUNKEN_SPEED_MODIFIER"
-#define MOVESPEED_ID_PEPPER_SPRAY "PEPPER_SPRAYED"
-#define MOVESPEED_ID_FAT "FAT"
-#define MOVESPEED_ID_COLD "COLD"
-#define MOVESPEED_ID_HUNGRY "HUNGRY"
-#define MOVESPEED_ID_DAMAGE_SLOWDOWN "DAMAGE"
-#define MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING "FLYING"
-#define MOVESPEED_ID_LENTURI "LENTURI_SLOWDOWN"
-
+#define MOVESPEED_ID_MOB_GRAB_STATE "mob_grab_state"
+#define MOVESPEED_ID_MOB_WALK_RUN "mob_walk_run"
diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm
index 41eaba33c61..1ec0829c701 100644
--- a/code/controllers/configuration/entries/game_options.dm
+++ b/code/controllers/configuration/entries/game_options.dm
@@ -243,9 +243,19 @@
/datum/config_entry/number/movedelay/run_delay
integer = FALSE
+/datum/config_entry/number/movedelay/run_delay/ValidateAndSet()
+ . = ..()
+ var/datum/movespeed_modifier/config_walk_run/M = get_cached_movespeed_modifier(/datum/movespeed_modifier/config_walk_run/run)
+ M.sync()
+
/datum/config_entry/number/movedelay/walk_delay
integer = FALSE
+/datum/config_entry/number/movedelay/walk_delay/ValidateAndSet()
+ . = ..()
+ var/datum/movespeed_modifier/config_walk_run/M = get_cached_movespeed_modifier(/datum/movespeed_modifier/config_walk_run/walk)
+ M.sync()
+
/////////////////////////////////////////////////Outdated move delay
/datum/config_entry/number/outdated_movedelay
deprecated_by = /datum/config_entry/keyed_list/multiplicative_movespeed
diff --git a/code/datums/components/mood.dm b/code/datums/components/mood.dm
index afdc2821a95..c3e46d289e2 100644
--- a/code/datums/components/mood.dm
+++ b/code/datums/components/mood.dm
@@ -205,27 +205,27 @@
switch(sanity)
if(SANITY_INSANE to SANITY_CRAZY)
setInsanityEffect(MAJOR_INSANITY_PEN)
- master.add_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE, 100, override=TRUE, multiplicative_slowdown=1, movetypes=(~FLYING))
+ master.add_movespeed_modifier(/datum/movespeed_modifier/sanity/insane)
sanity_level = 6
if(SANITY_CRAZY to SANITY_UNSTABLE)
setInsanityEffect(MINOR_INSANITY_PEN)
- master.add_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE, 100, override=TRUE, multiplicative_slowdown=0.5, movetypes=(~FLYING))
+ master.add_movespeed_modifier(/datum/movespeed_modifier/sanity/crazy)
sanity_level = 5
if(SANITY_UNSTABLE to SANITY_DISTURBED)
setInsanityEffect(0)
- master.add_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE, 100, override=TRUE, multiplicative_slowdown=0.25, movetypes=(~FLYING))
+ master.add_movespeed_modifier(/datum/movespeed_modifier/sanity/disturbed)
sanity_level = 4
if(SANITY_DISTURBED to SANITY_NEUTRAL)
setInsanityEffect(0)
- master.remove_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE)
+ master.remove_movespeed_modifier(MOVESPEED_ID_SANITY)
sanity_level = 3
if(SANITY_NEUTRAL+1 to SANITY_GREAT+1) //shitty hack but +1 to prevent it from responding to super small differences
setInsanityEffect(0)
- master.remove_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE)
+ master.remove_movespeed_modifier(MOVESPEED_ID_SANITY)
sanity_level = 2
if(SANITY_GREAT+1 to INFINITY)
setInsanityEffect(0)
- master.remove_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE)
+ master.remove_movespeed_modifier(MOVESPEED_ID_SANITY)
sanity_level = 1
update_mood_icon()
diff --git a/code/datums/components/riding.dm b/code/datums/components/riding.dm
index 2bd1f1b938f..87af417a28c 100644
--- a/code/datums/components/riding.dm
+++ b/code/datums/components/riding.dm
@@ -224,13 +224,13 @@
/datum/component/riding/human/vehicle_mob_unbuckle(datum/source, mob/living/M, force = FALSE)
var/mob/living/carbon/human/H = parent
- H.remove_movespeed_modifier(MOVESPEED_ID_HUMAN_CARRYING)
+ H.remove_movespeed_modifier(/datum/movespeed_modifier/human_carry)
. = ..()
/datum/component/riding/human/vehicle_mob_buckle(datum/source, mob/living/M, force = FALSE)
. = ..()
var/mob/living/carbon/human/H = parent
- H.add_movespeed_modifier(MOVESPEED_ID_HUMAN_CARRYING, multiplicative_slowdown = HUMAN_CARRY_SLOWDOWN)
+ H.add_movespeed_modifier(/datum/movespeed_modifier/human_carry)
/datum/component/riding/human/proc/on_host_unarmed_melee(atom/target)
var/mob/living/carbon/human/H = parent
diff --git a/code/datums/components/shrink.dm b/code/datums/components/shrink.dm
index 48ab864c79d..3dfd131923a 100644
--- a/code/datums/components/shrink.dm
+++ b/code/datums/components/shrink.dm
@@ -14,7 +14,7 @@
parent_atom.opacity = 0
if(isliving(parent_atom))
var/mob/living/L = parent_atom
- L.add_movespeed_modifier(MOVESPEED_ID_SHRINK_RAY, update=TRUE, priority=100, multiplicative_slowdown=4, movetypes=GROUND)
+ L.add_movespeed_modifier(/datum/movespeed_modifier/shrink_ray)
if(iscarbon(L))
var/mob/living/carbon/C = L
C.unequip_everything()
@@ -27,7 +27,6 @@
"Everything grows bigger!")
QDEL_IN(src, shrink_time)
-
/datum/component/shrink/Destroy()
var/atom/parent_atom = parent
parent_atom.transform = parent_atom.transform.Scale(2,2)
@@ -35,7 +34,7 @@
parent_atom.opacity = oldopac
if(isliving(parent_atom))
var/mob/living/L = parent_atom
- L.remove_movespeed_modifier(MOVESPEED_ID_SHRINK_RAY)
+ L.remove_movespeed_modifier(/datum/movespeed_modifier/shrink_ray)
if(ishuman(L))
var/mob/living/carbon/human/H = L
H.physiology.damage_resistance += 100
diff --git a/code/datums/components/tackle.dm b/code/datums/components/tackle.dm
index 2719cf65a0a..9980a2fc96f 100644
--- a/code/datums/components/tackle.dm
+++ b/code/datums/components/tackle.dm
@@ -86,7 +86,7 @@
to_chat(user, "You're not ready to tackle!")
return
- if(user.has_movespeed_modifier(MOVESPEED_ID_SHOVE)) // can't tackle if you just got shoved
+ if(user.has_movespeed_modifier(/datum/movespeed_modifier/shove)) // can't tackle if you just got shoved
to_chat(user, "You're too off balance to tackle!")
return
@@ -167,8 +167,8 @@
to_chat(target, "[user] lands a weak tackle on you, briefly knocking you off-balance!")
user.Knockdown(30)
- if(ishuman(target) && !T.has_movespeed_modifier(MOVESPEED_ID_SHOVE))
- T.add_movespeed_modifier(MOVESPEED_ID_SHOVE, multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH) // maybe define a slightly more severe/longer slowdown for this
+ if(ishuman(target) && !T.has_movespeed_modifier(/datum/movespeed_modifier/shove))
+ T.add_movespeed_modifier(/datum/movespeed_modifier/shove) // maybe define a slightly more severe/longer slowdown for this
addtimer(CALLBACK(T, /mob/living/carbon/human/proc/clear_shove_slowdown), SHOVE_SLOWDOWN_LENGTH)
if(-1 to 0) // decent hit, both parties are about equally inconvenienced
diff --git a/code/datums/elements/snail_crawl.dm b/code/datums/elements/snail_crawl.dm
index 9352ab7beda..0e322c7c9d2 100644
--- a/code/datums/elements/snail_crawl.dm
+++ b/code/datums/elements/snail_crawl.dm
@@ -16,13 +16,13 @@
. = ..()
UnregisterSignal(target, COMSIG_MOVABLE_MOVED)
if(istype(target))
- target.remove_movespeed_modifier(MOVESPEED_ID_SNAIL_CRAWL)
+ target.remove_movespeed_modifier(/datum/movespeed_modifier/snail_crawl)
/datum/element/snailcrawl/proc/snail_crawl(mob/living/carbon/snail)
if(snail.resting && !snail.buckled && lubricate(snail))
- snail.add_movespeed_modifier(MOVESPEED_ID_SNAIL_CRAWL, update=TRUE, priority=100, multiplicative_slowdown=-7, movetypes=GROUND)
+ snail.add_movespeed_modifier(/datum/movespeed_modifier/snail_crawl)
else
- snail.remove_movespeed_modifier(MOVESPEED_ID_SNAIL_CRAWL)
+ snail.remove_movespeed_modifier(/datum/movespeed_modifier/snail_crawl)
/datum/element/snailcrawl/proc/lubricate(atom/movable/snail)
var/turf/open/OT = get_turf(snail)
diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm
index c2a6194cca6..1193ce213c2 100644
--- a/code/game/objects/effects/mines.dm
+++ b/code/game/objects/effects/mines.dm
@@ -177,7 +177,7 @@
if(!victim.client || !istype(victim))
return
to_chat(victim, "You feel fast!")
- victim.add_movespeed_modifier(MOVESPEED_ID_YELLOW_ORB, update=TRUE, priority=100, multiplicative_slowdown=-2, blacklisted_movetypes=(FLYING|FLOATING))
+ victim.add_movespeed_modifier(/datum/movespeed_modifier/yellow_orb)
sleep(duration)
- victim.remove_movespeed_modifier(MOVESPEED_ID_YELLOW_ORB)
+ victim.remove_movespeed_modifier(/datum/movespeed_modifier/yellow_orb)
to_chat(victim, "You slow down.")
diff --git a/code/game/objects/items/tanks/jetpack.dm b/code/game/objects/items/tanks/jetpack.dm
index 765274c93f8..ab3da28f220 100644
--- a/code/game/objects/items/tanks/jetpack.dm
+++ b/code/game/objects/items/tanks/jetpack.dm
@@ -1,275 +1,275 @@
-/obj/item/tank/jetpack
- name = "jetpack (empty)"
- desc = "A tank of compressed gas for use as propulsion in zero-gravity areas. Use with caution."
- icon_state = "jetpack"
- item_state = "jetpack"
- lefthand_file = 'icons/mob/inhands/equipment/jetpacks_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/equipment/jetpacks_righthand.dmi'
- w_class = WEIGHT_CLASS_BULKY
- distribute_pressure = ONE_ATMOSPHERE * O2STANDARD
- actions_types = list(/datum/action/item_action/set_internals, /datum/action/item_action/toggle_jetpack, /datum/action/item_action/jetpack_stabilization)
- var/gas_type = /datum/gas/oxygen
- var/on = FALSE
- var/stabilizers = FALSE
- var/full_speed = TRUE // If the jetpack will have a speedboost in space/nograv or not
- var/datum/effect_system/trail_follow/ion/ion_trail
-
-/obj/item/tank/jetpack/Initialize()
- . = ..()
- ion_trail = new
- ion_trail.auto_process = FALSE
- ion_trail.set_up(src)
-
-/obj/item/tank/jetpack/populate_gas()
- if(gas_type)
- air_contents.assert_gas(gas_type)
- air_contents.gases[gas_type][MOLES] = ((6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C))
-
-/obj/item/tank/jetpack/ui_action_click(mob/user, action)
- if(istype(action, /datum/action/item_action/toggle_jetpack))
- cycle(user)
- else if(istype(action, /datum/action/item_action/jetpack_stabilization))
- if(on)
- stabilizers = !stabilizers
- to_chat(user, "You turn the jetpack stabilization [stabilizers ? "on" : "off"].")
- else
- toggle_internals(user)
-
-
-/obj/item/tank/jetpack/proc/cycle(mob/user)
- if(user.incapacitated())
- return
-
- if(!on)
- turn_on(user)
- to_chat(user, "You turn the jetpack on.")
- else
- turn_off(user)
- to_chat(user, "You turn the jetpack off.")
- for(var/X in actions)
- var/datum/action/A = X
- A.UpdateButtonIcon()
-
-
-/obj/item/tank/jetpack/proc/turn_on(mob/user)
- if(!allow_thrust(0.01, user))
- return
- on = TRUE
- icon_state = "[initial(icon_state)]-on"
- ion_trail.start()
- RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/move_react)
- RegisterSignal(user, COMSIG_MOVABLE_PRE_MOVE, .proc/pre_move_react)
- if(full_speed)
- user.add_movespeed_modifier(MOVESPEED_ID_JETPACK, priority=100, multiplicative_slowdown=-0.5, movetypes=FLOATING, conflict=MOVE_CONFLICT_JETPACK)
-
-/obj/item/tank/jetpack/proc/turn_off(mob/user)
- on = FALSE
- stabilizers = FALSE
- icon_state = initial(icon_state)
- ion_trail.stop()
- UnregisterSignal(user, COMSIG_MOVABLE_MOVED)
- UnregisterSignal(user, COMSIG_MOVABLE_PRE_MOVE)
- user.remove_movespeed_modifier(MOVESPEED_ID_JETPACK)
-
-/obj/item/tank/jetpack/proc/move_react(mob/user)
- if(!on)//If jet dont work, it dont work
- return
- if(!user)//Don't allow jet self using
- return
- if(!isturf(user.loc))//You can't use jet in nowhere or from mecha/closet
- return
- if(!(user.is_flying() || user.is_floating()) || user.buckled)//You don't want use jet in gravity or while buckled.
- return
- if(user.pulledby)//You don't must use jet if someone pull you
- return
- if(user.throwing)//You don't must use jet if you thrown
- return
- if(length(user.client.keys_held & user.client.movement_keys))//You use jet when press keys. yes.
- allow_thrust(0.01, user)
-
-/obj/item/tank/jetpack/proc/pre_move_react(mob/user)
- ion_trail.oldposition = get_turf(src)
-
-/obj/item/tank/jetpack/proc/allow_thrust(num, mob/living/user)
- if((num < 0.005 || air_contents.total_moles() < num))
- turn_off(user)
- return
-
- var/datum/gas_mixture/removed = air_contents.remove(num)
- if(removed.total_moles() < 0.005)
- turn_off(user)
- return
-
- var/turf/T = get_turf(user)
- T.assume_air(removed)
- ion_trail.generate_effect()
-
- return TRUE
-
-/obj/item/tank/jetpack/suicide_act(mob/user)
- if (istype(user, /mob/living/carbon/human/))
- var/mob/living/carbon/human/H = user
- H.forcesay("WHAT THE FUCK IS CARBON DIOXIDE?")
- H.visible_message("[user] is suffocating [user.p_them()]self with [src]! It looks like [user.p_they()] didn't read what that jetpack says!")
- return (OXYLOSS)
- else
- ..()
-
-/obj/item/tank/jetpack/improvised
- name = "improvised jetpack"
- desc = "A jetpack made from two air tanks, a fire extinguisher and some atmospherics equipment. It doesn't look like it can hold much."
- icon_state = "jetpack-improvised"
- item_state = "jetpack-sec"
- volume = 20 //normal jetpacks have 70 volume
- gas_type = null //it starts empty
- full_speed = FALSE //moves at hardsuit jetpack speeds
-
-/obj/item/tank/jetpack/improvised/allow_thrust(num, mob/living/user)
- if(!on)
- return
- if((num < 0.005 || air_contents.total_moles() < num))
- turn_off(user)
- return
- if(rand(0,250) == 0)
- to_chat(user, "You feel your jetpack's engines cut out.")
- turn_off(user)
- return
-
- var/datum/gas_mixture/removed = air_contents.remove(num)
- if(removed.total_moles() < 0.005)
- turn_off(user)
- return
-
- var/turf/T = get_turf(user)
- T.assume_air(removed)
- ion_trail.generate_effect()
-
- return TRUE
-
-/obj/item/tank/jetpack/void
- name = "void jetpack (oxygen)"
- desc = "It works well in a void."
- icon_state = "jetpack-void"
- item_state = "jetpack-void"
-
-/obj/item/tank/jetpack/oxygen
- name = "jetpack (oxygen)"
- desc = "A tank of compressed oxygen for use as propulsion in zero-gravity areas. Use with caution."
- icon_state = "jetpack"
- item_state = "jetpack"
-
-/obj/item/tank/jetpack/oxygen/harness
- name = "jet harness (oxygen)"
- desc = "A lightweight tactical harness, used by those who don't want to be weighed down by traditional jetpacks."
- icon_state = "jetpack-mini"
- item_state = "jetpack-mini"
- volume = 40
- throw_range = 7
- w_class = WEIGHT_CLASS_NORMAL
-
-/obj/item/tank/jetpack/oxygen/captain
- name = "captain's jetpack"
- desc = "A compact, lightweight jetpack containing a high amount of compressed oxygen."
- icon_state = "jetpack-captain"
- item_state = "jetpack-captain"
- w_class = WEIGHT_CLASS_NORMAL
- volume = 90
- resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF //steal objective items are hard to destroy.
-
-/obj/item/tank/jetpack/oxygen/security
- name = "security jetpack (oxygen)"
- desc = "A tank of compressed oxygen for use as propulsion in zero-gravity areas by security forces."
- icon_state = "jetpack-sec"
- item_state = "jetpack-sec"
-
-
-
-/obj/item/tank/jetpack/carbondioxide
- name = "jetpack (carbon dioxide)"
- desc = "A tank of compressed carbon dioxide for use as propulsion in zero-gravity areas. Painted black to indicate that it should not be used as a source for internals."
- icon_state = "jetpack-black"
- item_state = "jetpack-black"
- distribute_pressure = 0
- gas_type = /datum/gas/carbon_dioxide
-
-
-/obj/item/tank/jetpack/suit
- name = "hardsuit jetpack upgrade"
- desc = "A modular, compact set of thrusters designed to integrate with a hardsuit. It is fueled by a tank inserted into the suit's storage compartment."
- icon_state = "jetpack-mining"
- item_state = "jetpack-black"
- w_class = WEIGHT_CLASS_NORMAL
- actions_types = list(/datum/action/item_action/toggle_jetpack, /datum/action/item_action/jetpack_stabilization)
- volume = 1
- slot_flags = null
- gas_type = null
- full_speed = FALSE
- var/datum/gas_mixture/temp_air_contents
- var/obj/item/tank/internals/tank = null
- var/mob/living/carbon/human/cur_user
-
-/obj/item/tank/jetpack/suit/Initialize()
- . = ..()
- STOP_PROCESSING(SSobj, src)
- temp_air_contents = air_contents
-
-/obj/item/tank/jetpack/suit/attack_self()
- return
-
-/obj/item/tank/jetpack/suit/cycle(mob/user)
- if(!istype(loc, /obj/item/clothing/suit/space/hardsuit))
- to_chat(user, "\The [src] must be connected to a hardsuit!")
- return
-
- var/mob/living/carbon/human/H = user
- if(!istype(H.s_store, /obj/item/tank/internals))
- to_chat(user, "You need a tank in your suit storage!")
- return
- ..()
-
-/obj/item/tank/jetpack/suit/turn_on(mob/user)
- if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc) || loc.loc != user)
- return
- var/mob/living/carbon/human/H = user
- tank = H.s_store
- air_contents = tank.air_contents
- START_PROCESSING(SSobj, src)
- cur_user = user
- ..()
-
-/obj/item/tank/jetpack/suit/turn_off(mob/user)
- tank = null
- air_contents = temp_air_contents
- STOP_PROCESSING(SSobj, src)
- cur_user = null
- ..()
-
-/obj/item/tank/jetpack/suit/process()
- if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc))
- turn_off(cur_user)
- return
- var/mob/living/carbon/human/H = loc.loc
- if(!tank || tank != H.s_store)
- turn_off(cur_user)
- return
- ..()
-
-
-//Return a jetpack that the mob can use
-//Back worn jetpacks, hardsuit internal packs, and so on.
-//Used in Process_Spacemove() and wherever you want to check for/get a jetpack
-
-/mob/proc/get_jetpack()
- return
-
-/mob/living/carbon/get_jetpack()
- var/obj/item/tank/jetpack/J = back
- if(istype(J))
- return J
-
-/mob/living/carbon/human/get_jetpack()
- var/obj/item/tank/jetpack/J = ..()
- if(!istype(J) && istype(wear_suit, /obj/item/clothing/suit/space/hardsuit))
- var/obj/item/clothing/suit/space/hardsuit/C = wear_suit
- J = C.jetpack
- return J
+/obj/item/tank/jetpack
+ name = "jetpack (empty)"
+ desc = "A tank of compressed gas for use as propulsion in zero-gravity areas. Use with caution."
+ icon_state = "jetpack"
+ item_state = "jetpack"
+ lefthand_file = 'icons/mob/inhands/equipment/jetpacks_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/equipment/jetpacks_righthand.dmi'
+ w_class = WEIGHT_CLASS_BULKY
+ distribute_pressure = ONE_ATMOSPHERE * O2STANDARD
+ actions_types = list(/datum/action/item_action/set_internals, /datum/action/item_action/toggle_jetpack, /datum/action/item_action/jetpack_stabilization)
+ var/gas_type = /datum/gas/oxygen
+ var/on = FALSE
+ var/stabilizers = FALSE
+ var/full_speed = TRUE // If the jetpack will have a speedboost in space/nograv or not
+ var/datum/effect_system/trail_follow/ion/ion_trail
+
+/obj/item/tank/jetpack/Initialize()
+ . = ..()
+ ion_trail = new
+ ion_trail.auto_process = FALSE
+ ion_trail.set_up(src)
+
+/obj/item/tank/jetpack/populate_gas()
+ if(gas_type)
+ air_contents.assert_gas(gas_type)
+ air_contents.gases[gas_type][MOLES] = ((6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C))
+
+/obj/item/tank/jetpack/ui_action_click(mob/user, action)
+ if(istype(action, /datum/action/item_action/toggle_jetpack))
+ cycle(user)
+ else if(istype(action, /datum/action/item_action/jetpack_stabilization))
+ if(on)
+ stabilizers = !stabilizers
+ to_chat(user, "You turn the jetpack stabilization [stabilizers ? "on" : "off"].")
+ else
+ toggle_internals(user)
+
+
+/obj/item/tank/jetpack/proc/cycle(mob/user)
+ if(user.incapacitated())
+ return
+
+ if(!on)
+ turn_on(user)
+ to_chat(user, "You turn the jetpack on.")
+ else
+ turn_off(user)
+ to_chat(user, "You turn the jetpack off.")
+ for(var/X in actions)
+ var/datum/action/A = X
+ A.UpdateButtonIcon()
+
+
+/obj/item/tank/jetpack/proc/turn_on(mob/user)
+ if(!allow_thrust(0.01, user))
+ return
+ on = TRUE
+ icon_state = "[initial(icon_state)]-on"
+ ion_trail.start()
+ RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/move_react)
+ RegisterSignal(user, COMSIG_MOVABLE_PRE_MOVE, .proc/pre_move_react)
+ if(full_speed)
+ user.add_movespeed_modifier(/datum/movespeed_modifier/jetpack/fullspeed)
+
+/obj/item/tank/jetpack/proc/turn_off(mob/user)
+ on = FALSE
+ stabilizers = FALSE
+ icon_state = initial(icon_state)
+ ion_trail.stop()
+ UnregisterSignal(user, COMSIG_MOVABLE_MOVED)
+ UnregisterSignal(user, COMSIG_MOVABLE_PRE_MOVE)
+ user.remove_movespeed_modifier(/datum/movespeed_modifier/jetpack/fullspeed)
+
+/obj/item/tank/jetpack/proc/move_react(mob/user)
+ if(!on)//If jet dont work, it dont work
+ return
+ if(!user)//Don't allow jet self using
+ return
+ if(!isturf(user.loc))//You can't use jet in nowhere or from mecha/closet
+ return
+ if(!(user.is_flying() || user.is_floating()) || user.buckled)//You don't want use jet in gravity or while buckled.
+ return
+ if(user.pulledby)//You don't must use jet if someone pull you
+ return
+ if(user.throwing)//You don't must use jet if you thrown
+ return
+ if(length(user.client.keys_held & user.client.movement_keys))//You use jet when press keys. yes.
+ allow_thrust(0.01, user)
+
+/obj/item/tank/jetpack/proc/pre_move_react(mob/user)
+ ion_trail.oldposition = get_turf(src)
+
+/obj/item/tank/jetpack/proc/allow_thrust(num, mob/living/user)
+ if((num < 0.005 || air_contents.total_moles() < num))
+ turn_off(user)
+ return
+
+ var/datum/gas_mixture/removed = air_contents.remove(num)
+ if(removed.total_moles() < 0.005)
+ turn_off(user)
+ return
+
+ var/turf/T = get_turf(user)
+ T.assume_air(removed)
+ ion_trail.generate_effect()
+
+ return TRUE
+
+/obj/item/tank/jetpack/suicide_act(mob/user)
+ if (istype(user, /mob/living/carbon/human/))
+ var/mob/living/carbon/human/H = user
+ H.forcesay("WHAT THE FUCK IS CARBON DIOXIDE?")
+ H.visible_message("[user] is suffocating [user.p_them()]self with [src]! It looks like [user.p_they()] didn't read what that jetpack says!")
+ return (OXYLOSS)
+ else
+ ..()
+
+/obj/item/tank/jetpack/improvised
+ name = "improvised jetpack"
+ desc = "A jetpack made from two air tanks, a fire extinguisher and some atmospherics equipment. It doesn't look like it can hold much."
+ icon_state = "jetpack-improvised"
+ item_state = "jetpack-sec"
+ volume = 20 //normal jetpacks have 70 volume
+ gas_type = null //it starts empty
+ full_speed = FALSE //moves at hardsuit jetpack speeds
+
+/obj/item/tank/jetpack/improvised/allow_thrust(num, mob/living/user)
+ if(!on)
+ return
+ if((num < 0.005 || air_contents.total_moles() < num))
+ turn_off(user)
+ return
+ if(rand(0,250) == 0)
+ to_chat(user, "You feel your jetpack's engines cut out.")
+ turn_off(user)
+ return
+
+ var/datum/gas_mixture/removed = air_contents.remove(num)
+ if(removed.total_moles() < 0.005)
+ turn_off(user)
+ return
+
+ var/turf/T = get_turf(user)
+ T.assume_air(removed)
+ ion_trail.generate_effect()
+
+ return TRUE
+
+/obj/item/tank/jetpack/void
+ name = "void jetpack (oxygen)"
+ desc = "It works well in a void."
+ icon_state = "jetpack-void"
+ item_state = "jetpack-void"
+
+/obj/item/tank/jetpack/oxygen
+ name = "jetpack (oxygen)"
+ desc = "A tank of compressed oxygen for use as propulsion in zero-gravity areas. Use with caution."
+ icon_state = "jetpack"
+ item_state = "jetpack"
+
+/obj/item/tank/jetpack/oxygen/harness
+ name = "jet harness (oxygen)"
+ desc = "A lightweight tactical harness, used by those who don't want to be weighed down by traditional jetpacks."
+ icon_state = "jetpack-mini"
+ item_state = "jetpack-mini"
+ volume = 40
+ throw_range = 7
+ w_class = WEIGHT_CLASS_NORMAL
+
+/obj/item/tank/jetpack/oxygen/captain
+ name = "captain's jetpack"
+ desc = "A compact, lightweight jetpack containing a high amount of compressed oxygen."
+ icon_state = "jetpack-captain"
+ item_state = "jetpack-captain"
+ w_class = WEIGHT_CLASS_NORMAL
+ volume = 90
+ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF //steal objective items are hard to destroy.
+
+/obj/item/tank/jetpack/oxygen/security
+ name = "security jetpack (oxygen)"
+ desc = "A tank of compressed oxygen for use as propulsion in zero-gravity areas by security forces."
+ icon_state = "jetpack-sec"
+ item_state = "jetpack-sec"
+
+
+
+/obj/item/tank/jetpack/carbondioxide
+ name = "jetpack (carbon dioxide)"
+ desc = "A tank of compressed carbon dioxide for use as propulsion in zero-gravity areas. Painted black to indicate that it should not be used as a source for internals."
+ icon_state = "jetpack-black"
+ item_state = "jetpack-black"
+ distribute_pressure = 0
+ gas_type = /datum/gas/carbon_dioxide
+
+
+/obj/item/tank/jetpack/suit
+ name = "hardsuit jetpack upgrade"
+ desc = "A modular, compact set of thrusters designed to integrate with a hardsuit. It is fueled by a tank inserted into the suit's storage compartment."
+ icon_state = "jetpack-mining"
+ item_state = "jetpack-black"
+ w_class = WEIGHT_CLASS_NORMAL
+ actions_types = list(/datum/action/item_action/toggle_jetpack, /datum/action/item_action/jetpack_stabilization)
+ volume = 1
+ slot_flags = null
+ gas_type = null
+ full_speed = FALSE
+ var/datum/gas_mixture/temp_air_contents
+ var/obj/item/tank/internals/tank = null
+ var/mob/living/carbon/human/cur_user
+
+/obj/item/tank/jetpack/suit/Initialize()
+ . = ..()
+ STOP_PROCESSING(SSobj, src)
+ temp_air_contents = air_contents
+
+/obj/item/tank/jetpack/suit/attack_self()
+ return
+
+/obj/item/tank/jetpack/suit/cycle(mob/user)
+ if(!istype(loc, /obj/item/clothing/suit/space/hardsuit))
+ to_chat(user, "\The [src] must be connected to a hardsuit!")
+ return
+
+ var/mob/living/carbon/human/H = user
+ if(!istype(H.s_store, /obj/item/tank/internals))
+ to_chat(user, "You need a tank in your suit storage!")
+ return
+ ..()
+
+/obj/item/tank/jetpack/suit/turn_on(mob/user)
+ if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc) || loc.loc != user)
+ return
+ var/mob/living/carbon/human/H = user
+ tank = H.s_store
+ air_contents = tank.air_contents
+ START_PROCESSING(SSobj, src)
+ cur_user = user
+ ..()
+
+/obj/item/tank/jetpack/suit/turn_off(mob/user)
+ tank = null
+ air_contents = temp_air_contents
+ STOP_PROCESSING(SSobj, src)
+ cur_user = null
+ ..()
+
+/obj/item/tank/jetpack/suit/process()
+ if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc))
+ turn_off(cur_user)
+ return
+ var/mob/living/carbon/human/H = loc.loc
+ if(!tank || tank != H.s_store)
+ turn_off(cur_user)
+ return
+ ..()
+
+
+//Return a jetpack that the mob can use
+//Back worn jetpacks, hardsuit internal packs, and so on.
+//Used in Process_Spacemove() and wherever you want to check for/get a jetpack
+
+/mob/proc/get_jetpack()
+ return
+
+/mob/living/carbon/get_jetpack()
+ var/obj/item/tank/jetpack/J = back
+ if(istype(J))
+ return J
+
+/mob/living/carbon/human/get_jetpack()
+ var/obj/item/tank/jetpack/J = ..()
+ if(!istype(J) && istype(wear_suit, /obj/item/clothing/suit/space/hardsuit))
+ var/obj/item/clothing/suit/space/hardsuit/C = wear_suit
+ J = C.jetpack
+ return J
diff --git a/code/modules/antagonists/changeling/powers/strained_muscles.dm b/code/modules/antagonists/changeling/powers/strained_muscles.dm
index 4432aa21fa0..8844c5844c3 100644
--- a/code/modules/antagonists/changeling/powers/strained_muscles.dm
+++ b/code/modules/antagonists/changeling/powers/strained_muscles.dm
@@ -18,7 +18,7 @@
if(active)
to_chat(user, "Our muscles tense and strengthen.")
else
- user.remove_movespeed_modifier(MOVESPEED_ID_CHANGELING_MUSCLES)
+ user.remove_movespeed_modifier(/datum/movespeed_modifier/strained_muscles)
to_chat(user, "Our muscles relax.")
if(stacks >= 10)
to_chat(user, "We collapse in exhaustion.")
@@ -31,12 +31,12 @@
/datum/action/changeling/strained_muscles/proc/muscle_loop(mob/living/carbon/user)
while(active)
- user.add_movespeed_modifier(MOVESPEED_ID_CHANGELING_MUSCLES, update=TRUE, priority=100, multiplicative_slowdown=-1, blacklisted_movetypes=(FLYING|FLOATING))
+ user.add_movespeed_modifier(/datum/movespeed_modifier/strained_muscles)
if(user.stat != CONSCIOUS || user.staminaloss >= 90)
active = !active
to_chat(user, "Our muscles relax without the energy to strengthen them.")
user.Paralyze(40)
- user.remove_movespeed_modifier(MOVESPEED_ID_CHANGELING_MUSCLES)
+ user.remove_movespeed_modifier(/datum/movespeed_modifier/strained_muscles)
break
stacks++
diff --git a/code/modules/antagonists/slaughter/slaughter.dm b/code/modules/antagonists/slaughter/slaughter.dm
index 1cd3053eb2f..42b08ae29c6 100644
--- a/code/modules/antagonists/slaughter/slaughter.dm
+++ b/code/modules/antagonists/slaughter/slaughter.dm
@@ -67,9 +67,8 @@
/mob/living/simple_animal/slaughter/phasein()
. = ..()
- add_movespeed_modifier(MOVESPEED_ID_SLAUGHTER, update=TRUE, priority=100, multiplicative_slowdown=-1)
- addtimer(CALLBACK(src, .proc/remove_movespeed_modifier, MOVESPEED_ID_SLAUGHTER, TRUE), 6 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE)
-
+ add_movespeed_modifier(/datum/movespeed_modifier/slaughter)
+ addtimer(CALLBACK(src, .proc/remove_movespeed_modifier, /datum/movespeed_modifier/slaughter), 6 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE)
//The loot from killing a slaughter demon - can be consumed to allow the user to blood crawl
/obj/item/organ/heart/demon
diff --git a/code/modules/awaymissions/mission_code/Academy.dm b/code/modules/awaymissions/mission_code/Academy.dm
index e69129b54dd..a5a8cf30b92 100644
--- a/code/modules/awaymissions/mission_code/Academy.dm
+++ b/code/modules/awaymissions/mission_code/Academy.dm
@@ -252,7 +252,7 @@
if(6)
//Cut speed
T.visible_message("[user] starts moving slower!")
- user.add_movespeed_modifier(MOVESPEED_ID_DIE_OF_FATE, update=TRUE, priority=100, multiplicative_slowdown=1)
+ user.add_movespeed_modifier(/datum/movespeed_modifier/die_of_fate)
if(7)
//Throw
T.visible_message("Unseen forces throw [user]!")
diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm
index ee6c2beea9d..590769797eb 100644
--- a/code/modules/clothing/shoes/_shoes.dm
+++ b/code/modules/clothing/shoes/_shoes.dm
@@ -225,8 +225,8 @@
to_chat(our_guy, "You trip on your shoelaces a bit[have_anything ? ", flinging what you were holding" : ""]!")
if(14 to 25) // 1.3ish% chance to stumble and be a bit off balance (like being disarmed)
to_chat(our_guy, "You stumble a bit on your untied shoelaces!")
- if(!our_guy.has_movespeed_modifier(MOVESPEED_ID_SHOVE))
- our_guy.add_movespeed_modifier(MOVESPEED_ID_SHOVE, multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH)
+ if(!our_guy.has_movespeed_modifier(/datum/movespeed_modifier/shove))
+ our_guy.add_movespeed_modifier(/datum/movespeed_modifier/shove)
addtimer(CALLBACK(our_guy, /mob/living/carbon/human/proc/clear_shove_slowdown), SHOVE_SLOWDOWN_LENGTH)
if(26 to 1000)
wiser = FALSE
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index abc6b269ba2..2755b9af05a 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -492,9 +492,9 @@
/mob/living/carbon/update_mobility()
. = ..()
if(!(mobility_flags & MOBILITY_STAND))
- add_movespeed_modifier(MOVESPEED_ID_CARBON_CRAWLING, TRUE, multiplicative_slowdown = CRAWLING_ADD_SLOWDOWN)
+ add_movespeed_modifier(/datum/movespeed_modifier/carbon_crawling)
else
- remove_movespeed_modifier(MOVESPEED_ID_CARBON_CRAWLING, TRUE)
+ remove_movespeed_modifier(/datum/movespeed_modifier/carbon_crawling)
//Updates the mob's health from bodyparts and mob damage variables
/mob/living/carbon/updatehealth()
@@ -517,9 +517,9 @@
med_hud_set_health()
if(stat == SOFT_CRIT)
- add_movespeed_modifier(MOVESPEED_ID_CARBON_SOFTCRIT, TRUE, multiplicative_slowdown = SOFTCRIT_ADD_SLOWDOWN)
+ add_movespeed_modifier(/datum/movespeed_modifier/carbon_softcrit)
else
- remove_movespeed_modifier(MOVESPEED_ID_CARBON_SOFTCRIT, TRUE)
+ remove_movespeed_modifier(/datum/movespeed_modifier/carbon_softcrit)
/mob/living/carbon/update_stamina()
var/stam = getStaminaLoss()
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 247ac153469..49a12ed2e3f 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1063,7 +1063,7 @@
return FALSE
/mob/living/carbon/human/proc/clear_shove_slowdown()
- remove_movespeed_modifier(MOVESPEED_ID_SHOVE)
+ remove_movespeed_modifier(/datum/movespeed_modifier/shove)
var/active_item = get_active_held_item()
if(is_type_in_typecache(active_item, GLOB.shove_disarming_types))
visible_message("[src.name] regains their grip on \the [active_item]!", "You regain your grip on \the [active_item]", null, COMBAT_MESSAGE_RANGE)
@@ -1076,17 +1076,16 @@
. = ..()
dna?.species.spec_updatehealth(src)
if(HAS_TRAIT(src, TRAIT_IGNOREDAMAGESLOWDOWN))
- remove_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN)
- remove_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING)
+ remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown)
+ remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying)
return
var/health_deficiency = max((maxHealth - health), staminaloss)
if(health_deficiency >= 40)
- add_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN, override = TRUE, multiplicative_slowdown = (health_deficiency / 75), blacklisted_movetypes = FLOATING|FLYING)
- add_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING, override = TRUE, multiplicative_slowdown = (health_deficiency / 25), movetypes = FLYING, blacklisted_movetypes = FLOATING)
+ add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown, TRUE, multiplicative_slowdown = health_deficiency / 75)
+ add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying, TRUE, multiplicative_slowdown = health_deficiency / 25)
else
- remove_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN)
- remove_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING)
-
+ remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown)
+ remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying)
/mob/living/carbon/human/washed(var/atom/washer)
. = ..()
@@ -1106,12 +1105,12 @@
if(gloves && !(HIDEGLOVES in obscured) && gloves.washed(washer))
SEND_SIGNAL(src, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
-/mob/living/carbon/human/adjust_nutrition(var/change) //Honestly FUCK the oldcoders for putting nutrition on /mob someone else can move it up because holy hell I'd have to fix SO many typechecks
+/mob/living/carbon/human/adjust_nutrition(change) //Honestly FUCK the oldcoders for putting nutrition on /mob someone else can move it up because holy hell I'd have to fix SO many typechecks
if(HAS_TRAIT(src, TRAIT_NOHUNGER))
return FALSE
return ..()
-/mob/living/carbon/human/set_nutrition(var/change) //Seriously fuck you oldcoders.
+/mob/living/carbon/human/set_nutrition(change) //Seriously fuck you oldcoders.
if(HAS_TRAIT(src, TRAIT_NOHUNGER))
return FALSE
return ..()
diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm
index 7f1c7c4c2fb..53872edc816 100644
--- a/code/modules/mob/living/carbon/human/human_movement.dm
+++ b/code/modules/mob/living/carbon/human/human_movement.dm
@@ -1,11 +1,13 @@
/mob/living/carbon/human/get_movespeed_modifiers()
var/list/considering = ..()
- . = considering
+ . = list()
if(HAS_TRAIT(src, TRAIT_IGNORESLOWDOWN))
- for(var/id in .)
- var/list/data = .[id]
- if(data[MOVESPEED_DATA_INDEX_FLAGS] & IGNORE_NOSLOW)
- .[id] = data
+ for(var/id in considering)
+ var/datum/movespeed_modifier/M = considering[id]
+ if(M.flags & IGNORE_NOSLOW)
+ .[id] = M
+ else
+ . = considering
/mob/living/carbon/human/slip(knockdown_amount, obj/O, lube, paralyze, forcedrop)
if(HAS_TRAIT(src, TRAIT_NOSLIPALL))
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index ebb5159b98a..5cec6a575b5 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -270,11 +270,10 @@ GLOBAL_LIST_EMPTY(roundstart_races)
fly = new
fly.Grant(C)
- C.add_movespeed_modifier(MOVESPEED_ID_SPECIES, TRUE, 100, override=TRUE, multiplicative_slowdown=speedmod, movetypes=(~FLYING))
+ C.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/species, multiplicative_slowdown=speedmod)
SEND_SIGNAL(C, COMSIG_SPECIES_GAIN, src, old_species)
-
/datum/species/proc/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load)
if(C.dna.species.exotic_bloodtype)
C.dna.blood_type = random_blood_type()
@@ -306,7 +305,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
C.dna.features["wings"] = "None"
C.update_body()
- C.remove_movespeed_modifier(MOVESPEED_ID_SPECIES)
+ C.remove_movespeed_modifier(/datum/movespeed_modifier/species)
SEND_SIGNAL(C, COMSIG_SPECIES_LOSS, src)
@@ -976,7 +975,6 @@ GLOBAL_LIST_EMPTY(roundstart_races)
////////
//LIFE//
////////
-
/datum/species/proc/handle_digestion(mob/living/carbon/human/H)
if(HAS_TRAIT(src, TRAIT_NOHUNGER))
return //hunger is for BABIES
@@ -986,14 +984,14 @@ GLOBAL_LIST_EMPTY(roundstart_races)
if(H.overeatduration < 100)
to_chat(H, "You feel fit again!")
REMOVE_TRAIT(H, TRAIT_FAT, OBESITY)
- H.remove_movespeed_modifier(MOVESPEED_ID_FAT)
+ H.remove_movespeed_modifier(/datum/movespeed_modifier/obesity)
H.update_inv_w_uniform()
H.update_inv_wear_suit()
else
if(H.overeatduration >= 100)
to_chat(H, "You suddenly feel blubbery!")
ADD_TRAIT(H, TRAIT_FAT, OBESITY)
- H.add_movespeed_modifier(MOVESPEED_ID_FAT, multiplicative_slowdown = 1.5)
+ H.add_movespeed_modifier(/datum/movespeed_modifier/obesity)
H.update_inv_w_uniform()
H.update_inv_wear_suit()
@@ -1048,13 +1046,13 @@ GLOBAL_LIST_EMPTY(roundstart_races)
if(!HAS_TRAIT(H, TRAIT_NOHUNGER))
var/hungry = (500 - H.nutrition) / 5 //So overeat would be 100 and default level would be 80
if(hungry >= 70)
- H.add_movespeed_modifier(MOVESPEED_ID_HUNGRY, override = TRUE, multiplicative_slowdown = (hungry / 50))
+ H.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/hunger, multiplicative_slowdown = (hungry / 50))
else if(isethereal(H))
var/datum/species/ethereal/E = H.dna.species
if(E.get_charge(H) <= ETHEREAL_CHARGE_NORMAL)
- H.add_movespeed_modifier(MOVESPEED_ID_HUNGRY, override = TRUE, multiplicative_slowdown = (1.5 * (1 - E.get_charge(H) / 100)))
+ H.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/hunger, multiplicative_slowdown = (1.5 * (1 - E.get_charge(H) / 100)))
else
- H.remove_movespeed_modifier(MOVESPEED_ID_HUNGRY)
+ H.remove_movespeed_modifier(/datum/movespeed_modifier/hunger)
switch(H.nutrition)
if(NUTRITION_LEVEL_FULL to INFINITY)
@@ -1337,8 +1335,8 @@ GLOBAL_LIST_EMPTY(roundstart_races)
var/knocked_item = FALSE
if(!is_type_in_typecache(target_held_item, GLOB.shove_disarming_types))
target_held_item = null
- if(!target.has_movespeed_modifier(MOVESPEED_ID_SHOVE))
- target.add_movespeed_modifier(MOVESPEED_ID_SHOVE, multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH)
+ if(!target.has_movespeed_modifier(/datum/movespeed_modifier/shove))
+ target.add_movespeed_modifier(/datum/movespeed_modifier/shove)
if(target_held_item)
target.visible_message("[target.name]'s grip on \the [target_held_item] loosens!",
"Your grip on \the [target_held_item] loosens!", null, COMBAT_MESSAGE_RANGE)
@@ -1592,8 +1590,8 @@ GLOBAL_LIST_EMPTY(roundstart_races)
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "cold")
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "hot", /datum/mood_event/hot)
- // Remove any slow down from the cold
- H.remove_movespeed_modifier(MOVESPEED_ID_COLD)
+ //Remove any slowdown from the cold.
+ H.remove_movespeed_modifier(/datum/movespeed_modifier/cold)
var/burn_damage = 0
var/firemodifier = H.fire_stacks / 50
@@ -1628,12 +1626,8 @@ GLOBAL_LIST_EMPTY(roundstart_races)
// clear any hot moods and apply cold mood
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "hot")
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "cold", /datum/mood_event/cold)
-
// Apply cold slow down
- H.add_movespeed_modifier(MOVESPEED_ID_COLD, override = TRUE, \
- multiplicative_slowdown = ((bodytemp_cold_damage_limit - H.bodytemperature) / COLD_SLOWDOWN_FACTOR), \
- blacklisted_movetypes = FLOATING)
-
+ H.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/cold, multiplicative_slowdown = ((bodytemp_cold_damage_limit - H.bodytemperature) / COLD_SLOWDOWN_FACTOR))
// Display alerts based on the amount of cold damage being taken
// Apply more damage based on how cold you are
switch(H.bodytemperature)
@@ -1650,7 +1644,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
// We are not to hot or cold, remove status and moods
else
H.clear_alert("temp")
- H.remove_movespeed_modifier(MOVESPEED_ID_COLD)
+ H.remove_movespeed_modifier(/datum/movespeed_modifier/cold)
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "cold")
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "hot")
diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm
index 9471fe92f2b..039c66e5d7e 100644
--- a/code/modules/mob/living/carbon/monkey/monkey.dm
+++ b/code/modules/mob/living/carbon/monkey/monkey.dm
@@ -61,14 +61,13 @@
/mob/living/carbon/monkey/on_reagent_change()
. = ..()
- remove_movespeed_modifier(MOVESPEED_ID_MONKEY_REAGENT_SPEEDMOD, TRUE)
var/amount
if(reagents.has_reagent(/datum/reagent/medicine/morphine))
amount = -1
if(reagents.has_reagent(/datum/reagent/consumable/nuka_cola))
amount = -1
if(amount)
- add_movespeed_modifier(MOVESPEED_ID_MONKEY_REAGENT_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = amount)
+ add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/monkey_reagent_speedmod, TRUE, amount)
/mob/living/carbon/monkey/updatehealth()
. = ..()
@@ -77,14 +76,14 @@
var/health_deficiency = (maxHealth - health)
if(health_deficiency >= 45)
slow += (health_deficiency / 25)
- add_movespeed_modifier(MOVESPEED_ID_MONKEY_HEALTH_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = slow)
+ add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/monkey_health_speedmod, TRUE, slow)
/mob/living/carbon/monkey/adjust_bodytemperature(amount, min_temp=0, max_temp=INFINITY, use_insulation=FALSE, use_steps=FALSE)
. = ..()
var/slow = 0
if (bodytemperature < 283.222)
slow += ((283.222 - bodytemperature) / 10) * 1.75
- add_movespeed_modifier(MOVESPEED_ID_MONKEY_TEMPERATURE_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = slow)
+ add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/monkey_temperature_speedmod, TRUE, slow)
/mob/living/carbon/monkey/Stat()
..()
@@ -96,8 +95,6 @@
if(changeling)
stat("Chemical Storage", "[changeling.chem_charges]/[changeling.chem_storage]")
stat("Absorbed DNA", changeling.absorbedcount)
- return
-
/mob/living/carbon/monkey/verb/removeinternal()
set name = "Remove Internals"
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 059716c37df..d479d1c6c95 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -1235,9 +1235,9 @@
if(!has_legs && has_arms < 2)
limbless_slowdown += 6 - (has_arms * 3)
if(limbless_slowdown)
- add_movespeed_modifier(MOVESPEED_ID_LIVING_LIMBLESS, update=TRUE, priority=100, override=TRUE, multiplicative_slowdown=limbless_slowdown, movetypes=GROUND)
+ add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/limbless, multiplicative_slowdown = limbless_slowdown)
else
- remove_movespeed_modifier(MOVESPEED_ID_LIVING_LIMBLESS, update=TRUE)
+ remove_movespeed_modifier(/datum/movespeed_modifier/limbless)
/mob/living/proc/fall(forced)
if(!(mobility_flags & MOBILITY_USE))
diff --git a/code/modules/mob/living/living_movement.dm b/code/modules/mob/living/living_movement.dm
index d2788647605..b92b2654f78 100644
--- a/code/modules/mob/living/living_movement.dm
+++ b/code/modules/mob/living/living_movement.dm
@@ -26,38 +26,31 @@
return ..()
/mob/living/proc/update_move_intent_slowdown()
- var/mod = 0
- if(m_intent == MOVE_INTENT_WALK)
- mod = CONFIG_GET(number/movedelay/walk_delay)
- else
- mod = CONFIG_GET(number/movedelay/run_delay)
- if(!isnum(mod))
- mod = 1
- add_movespeed_modifier(MOVESPEED_ID_MOB_WALK_RUN_CONFIG_SPEED, TRUE, 100, override = TRUE, multiplicative_slowdown = mod)
+ add_movespeed_modifier((m_intent == MOVE_INTENT_WALK)? /datum/movespeed_modifier/config_walk_run/walk : /datum/movespeed_modifier/config_walk_run/run)
/mob/living/proc/update_turf_movespeed(turf/open/T)
if(isopenturf(T))
- add_movespeed_modifier(MOVESPEED_ID_LIVING_TURF_SPEEDMOD, update=TRUE, priority=100, override=TRUE, multiplicative_slowdown=T.slowdown, movetypes=GROUND, blacklisted_movetypes=(FLYING|FLOATING))
+ add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/turf_slowdown, multiplicative_slowdown = T.slowdown)
else
- remove_movespeed_modifier(MOVESPEED_ID_LIVING_TURF_SPEEDMOD)
+ remove_movespeed_modifier(/datum/movespeed_modifier/turf_slowdown)
/mob/living/proc/update_pull_movespeed()
if(pulling)
if(isliving(pulling))
var/mob/living/L = pulling
if(!slowed_by_drag || (L.mobility_flags & MOBILITY_STAND) || L.buckled || grab_state >= GRAB_AGGRESSIVE)
- remove_movespeed_modifier(MOVESPEED_ID_BULKY_DRAGGING)
+ remove_movespeed_modifier(/datum/movespeed_modifier/bulky_drag)
return
- add_movespeed_modifier(MOVESPEED_ID_BULKY_DRAGGING, multiplicative_slowdown = PULL_PRONE_SLOWDOWN)
+ add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/bulky_drag, multiplicative_slowdown = PULL_PRONE_SLOWDOWN)
return
if(isobj(pulling))
var/obj/structure/S = pulling
if(!slowed_by_drag || !S.drag_slowdown)
- remove_movespeed_modifier(MOVESPEED_ID_BULKY_DRAGGING)
+ remove_movespeed_modifier(/datum/movespeed_modifier/bulky_drag)
return
- add_movespeed_modifier(MOVESPEED_ID_BULKY_DRAGGING, multiplicative_slowdown = S.drag_slowdown)
+ add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/bulky_drag, multiplicative_slowdown = S.drag_slowdown)
return
- remove_movespeed_modifier(MOVESPEED_ID_BULKY_DRAGGING)
+ remove_movespeed_modifier(/datum/movespeed_modifier/bulky_drag)
/mob/living/can_zFall(turf/T, levels)
return ..()
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
index b545c1acce4..e94431c4d3d 100644
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -255,9 +255,9 @@
/mob/living/silicon/pai/Process_Spacemove(movement_dir = 0)
. = ..()
if(!.)
- add_movespeed_modifier(MOVESPEED_ID_PAI_SPACEWALK_SPEEDMOD, TRUE, 100, multiplicative_slowdown = 2)
+ add_movespeed_modifier(/datum/movespeed_modifier/pai_spacewalk)
return TRUE
- remove_movespeed_modifier(MOVESPEED_ID_PAI_SPACEWALK_SPEEDMOD, TRUE)
+ remove_movespeed_modifier(/datum/movespeed_modifier/pai_spacewalk)
return TRUE
/mob/living/silicon/pai/examine(mob/user)
diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
index 085de510910..c22a22c979e 100644
--- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
+++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
@@ -209,10 +209,10 @@
. = ..()
if(slowed_by_webs)
if(!(locate(/obj/structure/spider/stickyweb) in loc))
- remove_movespeed_modifier(MOVESPEED_ID_TARANTULA_WEB)
+ remove_movespeed_modifier(/datum/movespeed_modifier/tarantula_web)
slowed_by_webs = FALSE
else if(locate(/obj/structure/spider/stickyweb) in loc)
- add_movespeed_modifier(MOVESPEED_ID_TARANTULA_WEB, priority=100, multiplicative_slowdown=3)
+ add_movespeed_modifier(/datum/movespeed_modifier/tarantula_web)
slowed_by_webs = TRUE
/mob/living/simple_animal/hostile/poison/giant_spider/ice //spiders dont usually like tempatures of 140 kelvin who knew
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 329af982d56..313b6738c53 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -388,8 +388,8 @@
/mob/living/simple_animal/proc/update_simplemob_varspeed()
if(speed == 0)
- remove_movespeed_modifier(MOVESPEED_ID_SIMPLEMOB_VARSPEED, TRUE)
- add_movespeed_modifier(MOVESPEED_ID_SIMPLEMOB_VARSPEED, TRUE, 100, multiplicative_slowdown = speed, override = TRUE)
+ remove_movespeed_modifier(/datum/movespeed_modifier/simplemob_varspeed)
+ add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/simplemob_varspeed, multiplicative_slowdown = speed)
/mob/living/simple_animal/Stat()
..()
diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm
index 0e469a4a937..996b82f6000 100644
--- a/code/modules/mob/living/simple_animal/slime/slime.dm
+++ b/code/modules/mob/living/simple_animal/slime/slime.dm
@@ -145,14 +145,14 @@
/mob/living/simple_animal/slime/on_reagent_change()
. = ..()
- remove_movespeed_modifier(MOVESPEED_ID_SLIME_REAGENTMOD, TRUE)
+ remove_movespeed_modifier(/datum/movespeed_modifier/slime_reagentmod)
var/amount = 0
if(reagents.has_reagent(/datum/reagent/medicine/morphine)) // morphine slows slimes down
amount = 2
if(reagents.has_reagent(/datum/reagent/consumable/frostoil)) // Frostoil also makes them move VEEERRYYYYY slow
amount = 5
if(amount)
- add_movespeed_modifier(MOVESPEED_ID_SLIME_REAGENTMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = amount)
+ add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/slime_reagentmod, multiplicative_slowdown = amount)
/mob/living/simple_animal/slime/updatehealth()
. = ..()
@@ -163,7 +163,7 @@
mod += (health_deficiency / 25)
if(health <= 0)
mod += 2
- add_movespeed_modifier(MOVESPEED_ID_SLIME_HEALTHMOD, TRUE, 100, multiplicative_slowdown = mod, override = TRUE)
+ add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/slime_healthmod, multiplicative_slowdown = mod)
update_health_hud()
/mob/living/simple_animal/slime/update_health_hud()
@@ -201,7 +201,7 @@
else if(bodytemperature < 283.222)
mod = ((283.222 - bodytemperature) / 10) * 1.75
if(mod)
- add_movespeed_modifier(MOVESPEED_ID_SLIME_TEMPMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = mod)
+ add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/slime_tempmod, multiplicative_slowdown = mod)
/mob/living/simple_animal/slime/ObjBump(obj/O)
if(!client && powerlevel > 0)
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index ca336b3ca7e..0101a376d5d 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -1233,17 +1233,22 @@
/// Updates the grab state of the mob and updates movespeed
/mob/setGrabState(newstate)
. = ..()
- if(grab_state == GRAB_PASSIVE)
- remove_movespeed_modifier(MOVESPEED_ID_MOB_GRAB_STATE, update=TRUE)
- else
- add_movespeed_modifier(MOVESPEED_ID_MOB_GRAB_STATE, update=TRUE, priority=100, override=TRUE, multiplicative_slowdown=grab_state*3, blacklisted_movetypes=FLOATING)
+ switch(grab_state)
+ if(GRAB_PASSIVE)
+ remove_movespeed_modifier(MOVESPEED_ID_MOB_GRAB_STATE)
+ if(GRAB_AGGRESSIVE)
+ add_movespeed_modifier(/datum/movespeed_modifier/grab_slowdown/aggressive)
+ if(GRAB_NECK)
+ add_movespeed_modifier(/datum/movespeed_modifier/grab_slowdown/neck)
+ if(GRAB_KILL)
+ add_movespeed_modifier(/datum/movespeed_modifier/grab_slowdown/kill)
/mob/proc/update_equipment_speed_mods()
var/speedies = equipped_speed_mods()
if(!speedies)
- remove_movespeed_modifier(MOVESPEED_ID_MOB_EQUIPMENT, update=TRUE)
+ remove_movespeed_modifier(/datum/movespeed_modifier/equipment_speedmod)
else
- add_movespeed_modifier(MOVESPEED_ID_MOB_EQUIPMENT, update=TRUE, priority=100, override=TRUE, multiplicative_slowdown=speedies, blacklisted_movetypes=FLOATING)
+ add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/equipment_speedmod, multiplicative_slowdown = speedies)
/// Gets the combined speed modification of all worn items
/// Except base mob type doesnt really wear items
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index 1f3f3760f64..31fd71f7b42 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -326,9 +326,9 @@
/mob/proc/update_gravity(has_gravity, override=FALSE)
var/speed_change = max(0, has_gravity - STANDARD_GRAVITY)
if(!speed_change)
- remove_movespeed_modifier(MOVESPEED_ID_MOB_GRAVITY, update=TRUE)
+ remove_movespeed_modifier(/datum/movespeed_modifier/gravity)
else
- add_movespeed_modifier(MOVESPEED_ID_MOB_GRAVITY, update=TRUE, priority=100, override=TRUE, multiplicative_slowdown=speed_change, blacklisted_movetypes=FLOATING)
+ add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/gravity, multiplicative_slowdown=speed_change)
//bodypart selection verbs - Cyberboss
//8:repeated presses toggles through head - eyes - mouth
diff --git a/code/modules/mob/mob_movespeed.dm b/code/modules/mob/mob_movespeed.dm
deleted file mode 100644
index 60af7098853..00000000000
--- a/code/modules/mob/mob_movespeed.dm
+++ /dev/null
@@ -1,166 +0,0 @@
-/*! How move speed for mobs works
-
-Move speed is now calculated by using a list of movespeed modifiers, which is a list itself (to avoid datum overhead)
-
-This gives us the ability to have multiple sources of movespeed, reliabily keep them applied and remove them when they should be
-
-THey can have unique sources and a bunch of extra fancy flags that control behaviour
-
-Previously trying to update move speed was a shot in the dark that usually meant mobs got stuck going faster or slower
-
-This list takes the following format
-
-```Current movespeed modification list format:
- list(
- id = list(
- priority,
- flags,
- legacy slowdown/speedup amount,
- movetype_flags
- )
- )
-```
-
-WHen update movespeed is called, the list of items is iterated, according to flags priority and a bunch of conditions
-this spits out a final calculated value which is used as a modifer to last_move + modifier for calculating when a mob
-can next move
-
-Key procs
-* [add_movespeed_modifier](mob.html#proc/add_movespeed_modifier)
-* [remove_movespeed_modifier](mob.html#proc/remove_movespeed_modifier)
-* [has_movespeed_modifier](mob.html#proc/has_movespeed_modifier)
-* [update_movespeed](mob.html#proc/update_movespeed)
-*/
-
-//ANY ADD/REMOVE DONE IN UPDATE_MOVESPEED MUST HAVE THE UPDATE ARGUMENT SET AS FALSE!
-
-///Add a move speed modifier to a mob
-/mob/proc/add_movespeed_modifier(id, update=TRUE, priority=0, flags=NONE, override=FALSE, multiplicative_slowdown=0, movetypes=ALL, blacklisted_movetypes=NONE, conflict=FALSE)
- var/list/temp = list(priority, flags, multiplicative_slowdown, movetypes, blacklisted_movetypes, conflict) //build the modification list
- var/resort = TRUE
- if(LAZYACCESS(movespeed_modification, id))
- var/list/existing_data = movespeed_modification[id]
- if(movespeed_modifier_identical_check(existing_data, temp))
- return FALSE
- if(!override)
- return FALSE
- if(priority == existing_data[MOVESPEED_DATA_INDEX_PRIORITY])
- resort = FALSE // We don't need to re-sort if we're replacing something already there and it's the same priority
- LAZYSET(movespeed_modification, id, temp)
- if(update)
- update_movespeed(resort)
- return TRUE
-
-///Remove a move speed modifier from a mob
-/mob/proc/remove_movespeed_modifier(id, update = TRUE)
- if(!LAZYACCESS(movespeed_modification, id))
- return FALSE
- LAZYREMOVE(movespeed_modification, id)
- UNSETEMPTY(movespeed_modification)
- if(update)
- update_movespeed(FALSE)
- return TRUE
-
-///Handles the special case of editing the movement var
-/mob/vv_edit_var(var_name, var_value)
- var/slowdown_edit = (var_name == NAMEOF(src, cached_multiplicative_slowdown))
- var/diff
- if(slowdown_edit && isnum(cached_multiplicative_slowdown) && isnum(var_value))
- remove_movespeed_modifier(MOVESPEED_ID_ADMIN_VAREDIT)
- diff = var_value - cached_multiplicative_slowdown
- . = ..()
- if(. && slowdown_edit && isnum(diff))
- add_movespeed_modifier(MOVESPEED_ID_ADMIN_VAREDIT, TRUE, 100, override = TRUE, multiplicative_slowdown = diff)
-
-///Is there a movespeed modifier for this mob
-/mob/proc/has_movespeed_modifier(id)
- return LAZYACCESS(movespeed_modification, id)
-
-///Set or update the global movespeed config on a mob
-/mob/proc/update_config_movespeed()
- add_movespeed_modifier(MOVESPEED_ID_CONFIG_SPEEDMOD, FALSE, 100, override = TRUE, multiplicative_slowdown = get_config_multiplicative_speed())
-
-///Get the global config movespeed of a mob by type
-/mob/proc/get_config_multiplicative_speed()
- if(!islist(GLOB.mob_config_movespeed_type_lookup) || !GLOB.mob_config_movespeed_type_lookup[type])
- return 0
- else
- return GLOB.mob_config_movespeed_type_lookup[type]
-
-///Go through the list of movespeed modifiers and calculate a final movespeed
-/mob/proc/update_movespeed(resort = TRUE)
- if(resort)
- sort_movespeed_modlist()
- . = 0
- var/list/conflict_tracker = list()
- for(var/id in get_movespeed_modifiers())
- var/list/data = movespeed_modification[id]
- if(!(data[MOVESPEED_DATA_INDEX_MOVETYPE] & movement_type)) // We don't affect any of these move types, skip
- continue
- if(data[MOVESPEED_DATA_INDEX_BL_MOVETYPE] & movement_type) // There's a movetype here that disables this modifier, skip
- continue
- var/conflict = data[MOVESPEED_DATA_INDEX_CONFLICT]
- var/amt = data[MOVESPEED_DATA_INDEX_MULTIPLICATIVE_SLOWDOWN]
- if(conflict)
- // Conflicting modifiers prioritize the larger slowdown or the larger speedup
- // We purposefuly don't handle mixing speedups and slowdowns on the same id
- if(abs(conflict_tracker[conflict]) < abs(amt))
- conflict_tracker[conflict] = amt
- else
- continue
- . += amt
- cached_multiplicative_slowdown = .
-
-///Get the move speed modifiers list of the mob
-/mob/proc/get_movespeed_modifiers()
- return movespeed_modification
-
-///Check if a movespeed modifier is identical to another
-/mob/proc/movespeed_modifier_identical_check(list/mod1, list/mod2)
- if(!islist(mod1) || !islist(mod2) || mod1.len < MOVESPEED_DATA_INDEX_MAX || mod2.len < MOVESPEED_DATA_INDEX_MAX)
- return FALSE
- for(var/i in 1 to MOVESPEED_DATA_INDEX_MAX)
- if(mod1[i] != mod2[i])
- return FALSE
- return TRUE
-
-///Calculate the total slowdown of all movespeed modifiers
-/mob/proc/total_multiplicative_slowdown()
- . = 0
- for(var/id in get_movespeed_modifiers())
- var/list/data = movespeed_modification[id]
- . += data[MOVESPEED_DATA_INDEX_MULTIPLICATIVE_SLOWDOWN]
-
-///Checks if a move speed modifier is valid and not missing any data
-/proc/movespeed_data_null_check(list/data) //Determines if a data list is not meaningful and should be discarded.
- . = TRUE
- if(data[MOVESPEED_DATA_INDEX_MULTIPLICATIVE_SLOWDOWN])
- . = FALSE
-
-/**
- * Sort the list of move speed modifiers
- *
- * Verifies it too. Sorts highest priority (first applied) to lowest priority (last applied)
- */
-/mob/proc/sort_movespeed_modlist()
- if(!movespeed_modification)
- return
- var/list/assembled = list()
- for(var/our_id in movespeed_modification)
- var/list/our_data = movespeed_modification[our_id]
- if(!islist(our_data) || (our_data.len < MOVESPEED_DATA_INDEX_PRIORITY) || movespeed_data_null_check(our_data))
- movespeed_modification -= our_id
- continue
- var/our_priority = our_data[MOVESPEED_DATA_INDEX_PRIORITY]
- var/resolved = FALSE
- for(var/their_id in assembled)
- var/list/their_data = assembled[their_id]
- if(their_data[MOVESPEED_DATA_INDEX_PRIORITY] < our_priority)
- assembled.Insert(assembled.Find(their_id), our_id)
- assembled[our_id] = our_data
- resolved = TRUE
- break
- if(!resolved)
- assembled[our_id] = our_data
- movespeed_modification = assembled
- UNSETEMPTY(movespeed_modification)
diff --git a/code/modules/movespeed/_movespeed_modifier.dm b/code/modules/movespeed/_movespeed_modifier.dm
new file mode 100644
index 00000000000..c6bab4dd712
--- /dev/null
+++ b/code/modules/movespeed/_movespeed_modifier.dm
@@ -0,0 +1,212 @@
+/*! Movespeed modification datums.
+
+ How move speed for mobs works
+
+Move speed is now calculated by using modifier datums which are added to mobs. Some of them (nonvariable ones) are globally cached, the variable ones are instanced and changed based on need.
+
+This gives us the ability to have multiple sources of movespeed, reliabily keep them applied and remove them when they should be
+
+THey can have unique sources and a bunch of extra fancy flags that control behaviour
+
+Previously trying to update move speed was a shot in the dark that usually meant mobs got stuck going faster or slower
+
+Movespeed modification list is a simple key = datum system. Key will be the datum's ID if it is overridden to not be null, or type if it is not.
+
+DO NOT override datum IDs unless you are going to have multiple types that must overwrite each other. It's more efficient to use types, ID functionality is only kept for cases where dynamic creation of modifiers need to be done.
+
+When update movespeed is called, the list of items is iterated, according to flags priority and a bunch of conditions
+this spits out a final calculated value which is used as a modifer to last_move + modifier for calculating when a mob
+can next move
+
+Key procs
+* [add_movespeed_modifier](mob.html#proc/add_movespeed_modifier)
+* [remove_movespeed_modifier](mob.html#proc/remove_movespeed_modifier)
+* [has_movespeed_modifier](mob.html#proc/has_movespeed_modifier)
+* [update_movespeed](mob.html#proc/update_movespeed)
+*/
+
+/datum/movespeed_modifier
+ /// Whether or not this is a variable modifier. Variable modifiers can NOT be ever auto-cached. ONLY CHECKED VIA INITIAL(), EFFECTIVELY READ ONLY (and for very good reason)
+ var/variable = FALSE
+
+ /// Unique ID. You can never have different modifications with the same ID. By default, this SHOULD NOT be set. Only set it for cases where you're dynamically making modifiers/need to have two types overwrite each other. If unset, uses path as ID.
+ var/id
+
+ /// Higher ones override lower priorities. This is NOT used for ID, ID must be unique, if it isn't unique the newer one overwrites automatically if overriding.
+ var/priority = 0
+ var/flags = NONE
+
+ /// Multiplicative slowdown
+ var/multiplicative_slowdown = 0
+
+ /// Movetypes this applies to
+ var/movetypes = ALL
+
+ /// Movetypes this never applies to
+ var/blacklisted_movetypes = NONE
+
+ /// Other modification datums this conflicts with.
+ var/conflicts_with
+
+GLOBAL_LIST_EMPTY(movespeed_modification_cache)
+
+/// Grabs a STATIC MODIFIER datum from cache. YOU MUST NEVER EDIT THESE DATUMS, OR IT WILL AFFECT ANYTHING ELSE USING IT TOO!
+/proc/get_cached_movespeed_modifier(modtype)
+ if(!ispath(modtype, /datum/movespeed_modifier))
+ CRASH("[modtype] is not a movespeed modification typepath.")
+ var/datum/movespeed_modifier/M = modtype
+ if(initial(M.variable))
+ CRASH("[modtype] is a variable modifier, and can never be cached.")
+ M = GLOB.movespeed_modification_cache[modtype]
+ if(!M)
+ M = GLOB.movespeed_modification_cache[modtype] = new modtype
+ return M
+
+///Add a move speed modifier to a mob. If a variable subtype is passed in as the first argument, it will make a new datum. If ID conflicts, it will overwrite the old ID.
+/mob/proc/add_movespeed_modifier(datum/movespeed_modifier/type_or_datum, update = TRUE)
+ if(ispath(type_or_datum))
+ if(!initial(type_or_datum.variable))
+ type_or_datum = get_cached_movespeed_modifier(type_or_datum)
+ else
+ type_or_datum = new type_or_datum
+ var/key = type_or_datum.id || type_or_datum.type //Our key will be ID if it's overridden, or if not, path.
+ var/datum/movespeed_modifier/existing = LAZYACCESS(movespeed_modification, key)
+ if(existing)
+ if(existing == type_or_datum) //same thing don't need to touch
+ return TRUE
+ remove_movespeed_modifier(existing, FALSE)
+ if(length(movespeed_modification))
+ BINARY_INSERT(key, movespeed_modification, datum/movespeed_modifier, type_or_datum, priority, COMPARE_VALUE)
+ LAZYSET(movespeed_modification, key, type_or_datum)
+ if(update)
+ update_movespeed()
+ return TRUE
+
+/// Remove a move speed modifier from a mob, whether static or variable.
+/mob/proc/remove_movespeed_modifier(datum/movespeed_modifier/type_id_datum, update = TRUE)
+ var/key
+ if(ispath(type_id_datum))
+ key = initial(type_id_datum.id) || type_id_datum //id if set, path if not.
+ else if(!istext(type_id_datum)) //if it isn't text it has to be a datum, as it isn't a type.
+ key = type_id_datum.id || type_id_datum.type
+ else //assume it's an id
+ key = type_id_datum
+ if(!LAZYACCESS(movespeed_modification, key))
+ return FALSE
+ LAZYREMOVE(movespeed_modification, key)
+ if(update)
+ update_movespeed(FALSE)
+ return TRUE
+
+/*! Used for variable slowdowns like hunger/health loss/etc, works somewhat like the old list-based modification adds. Returns the modifier datum if successful
+ How this SHOULD work is:
+ 1. Ensures type_id_datum one way or another refers to a /variable datum. This makes sure it can't be cached. This includes if it's already in the modification list.
+ 2. Instantiate a new datum if type_id_datum isn't already instantiated + in the list, using the type. Obviously, wouldn't work for ID only.
+ 3. Add the datum if necessary using the regular add proc
+ 4. If any of the rest of the args are not null (see: multiplicative slowdown), modify the datum
+ 5. Update if necessary
+*/
+/mob/proc/add_or_update_variable_movespeed_modifier(datum/movespeed_modifier/type_id_datum, update = TRUE, multiplicative_slowdown)
+ var/modified = FALSE
+ var/inject = FALSE
+ var/datum/movespeed_modifier/final
+ if(istext(type_id_datum))
+ final = LAZYACCESS(movespeed_modification, type_id_datum)
+ if(!final)
+ CRASH("Couldn't find existing modification when provided a text ID.")
+ else if(ispath(type_id_datum))
+ if(!initial(type_id_datum.variable))
+ CRASH("Not a variable modifier")
+ var/id = initial(type_id_datum.id)
+ final = LAZYACCESS(movespeed_modification, id || type_id_datum)
+ if(!final)
+ final = new type_id_datum
+ inject = TRUE
+ modified = TRUE
+ else
+ if(!initial(type_id_datum.variable))
+ CRASH("Not a variable modifier")
+ final = type_id_datum
+ if(!LAZYACCESS(movespeed_modification, final.id || final.type))
+ inject = TRUE
+ modified = TRUE
+ if(!isnull(multiplicative_slowdown))
+ final.multiplicative_slowdown = multiplicative_slowdown
+ modified = TRUE
+ if(inject)
+ add_movespeed_modifier(final, FALSE)
+ if(update && modified)
+ update_movespeed(TRUE)
+ return final
+
+/// Handles the special case of editing the movement var
+/mob/vv_edit_var(var_name, var_value)
+ var/slowdown_edit = (var_name == NAMEOF(src, cached_multiplicative_slowdown))
+ var/diff
+ if(slowdown_edit && isnum(cached_multiplicative_slowdown) && isnum(var_value))
+ remove_movespeed_modifier(/datum/movespeed_modifier/admin_varedit)
+ diff = var_value - cached_multiplicative_slowdown
+ . = ..()
+ if(. && slowdown_edit && isnum(diff))
+ add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/admin_varedit, multiplicative_slowdown = diff)
+
+///Is there a movespeed modifier for this mob
+/mob/proc/has_movespeed_modifier(datum/movespeed_modifier/datum_type_id)
+ var/key
+ if(ispath(datum_type_id))
+ key = initial(datum_type_id.id) || datum_type_id
+ else if(istext(datum_type_id))
+ key = datum_type_id
+ else
+ key = datum_type_id.id || datum_type_id.type
+ return LAZYACCESS(movespeed_modification, key)
+
+/// Set or update the global movespeed config on a mob
+/mob/proc/update_config_movespeed()
+ add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/mob_config_speedmod, multiplicative_slowdown = get_config_multiplicative_speed())
+
+/// Get the global config movespeed of a mob by type
+/mob/proc/get_config_multiplicative_speed()
+ if(!islist(GLOB.mob_config_movespeed_type_lookup) || !GLOB.mob_config_movespeed_type_lookup[type])
+ return 0
+ else
+ return GLOB.mob_config_movespeed_type_lookup[type]
+
+/// Go through the list of movespeed modifiers and calculate a final movespeed. ANY ADD/REMOVE DONE IN UPDATE_MOVESPEED MUST HAVE THE UPDATE ARGUMENT SET AS FALSE!
+/mob/proc/update_movespeed()
+ . = 0
+ var/list/conflict_tracker = list()
+ for(var/key in get_movespeed_modifiers())
+ var/datum/movespeed_modifier/M = movespeed_modification[key]
+ if(!(M.movetypes & movement_type)) // We don't affect any of these move types, skip
+ continue
+ if(M.blacklisted_movetypes & movement_type) // There's a movetype here that disables this modifier, skip
+ continue
+ var/conflict = M.conflicts_with
+ var/amt = M.multiplicative_slowdown
+ if(conflict)
+ // Conflicting modifiers prioritize the larger slowdown or the larger speedup
+ // We purposefuly don't handle mixing speedups and slowdowns on the same id
+ if(abs(conflict_tracker[conflict]) < abs(amt))
+ conflict_tracker[conflict] = amt
+ else
+ continue
+ . += amt
+ cached_multiplicative_slowdown = .
+
+/// Get the move speed modifiers list of the mob
+/mob/proc/get_movespeed_modifiers()
+ return movespeed_modification
+
+/// Calculate the total slowdown of all movespeed modifiers
+/mob/proc/total_multiplicative_slowdown()
+ . = 0
+ for(var/id in get_movespeed_modifiers())
+ var/datum/movespeed_modifier/M = movespeed_modification[id]
+ . += M.multiplicative_slowdown
+
+/// Checks if a move speed modifier is valid and not missing any data
+/proc/movespeed_data_null_check(datum/movespeed_modifier/M) //Determines if a data list is not meaningful and should be discarded.
+ . = TRUE
+ if(M.multiplicative_slowdown)
+ . = FALSE
diff --git a/code/modules/movespeed/modifiers/components.dm b/code/modules/movespeed/modifiers/components.dm
new file mode 100644
index 00000000000..a8f0db50181
--- /dev/null
+++ b/code/modules/movespeed/modifiers/components.dm
@@ -0,0 +1,20 @@
+/datum/movespeed_modifier/shrink_ray
+ movetypes = GROUND
+ multiplicative_slowdown = 4
+
+/datum/movespeed_modifier/snail_crawl
+ multiplicative_slowdown = -7
+ movetypes = GROUND
+
+/datum/movespeed_modifier/sanity
+ id = MOVESPEED_ID_SANITY
+ movetypes = (~FLYING)
+
+/datum/movespeed_modifier/sanity/insane
+ multiplicative_slowdown = 1
+
+/datum/movespeed_modifier/sanity/crazy
+ multiplicative_slowdown = 0.5
+
+/datum/movespeed_modifier/sanity/disturbed
+ multiplicative_slowdown = 0.25
diff --git a/code/modules/movespeed/modifiers/innate.dm b/code/modules/movespeed/modifiers/innate.dm
new file mode 100644
index 00000000000..ee4ed3a6ecf
--- /dev/null
+++ b/code/modules/movespeed/modifiers/innate.dm
@@ -0,0 +1,14 @@
+/datum/movespeed_modifier/strained_muscles
+ multiplicative_slowdown = -1
+ blacklisted_movetypes = (FLYING|FLOATING)
+
+/datum/movespeed_modifier/pai_spacewalk
+ multiplicative_slowdown = 2
+
+/datum/movespeed_modifier/species
+ movetypes = ~FLYING
+ variable = TRUE
+
+/datum/movespeed_modifier/dna_vault_speedup
+ blacklisted_movetypes = (FLYING|FLOATING)
+ multiplicative_slowdown = -0.4
diff --git a/code/modules/movespeed/modifiers/items.dm b/code/modules/movespeed/modifiers/items.dm
new file mode 100644
index 00000000000..e36c05dccee
--- /dev/null
+++ b/code/modules/movespeed/modifiers/items.dm
@@ -0,0 +1,12 @@
+/datum/movespeed_modifier/jetpack
+ conflicts_with = MOVE_CONFLICT_JETPACK
+ movetypes = FLOATING
+
+/datum/movespeed_modifier/jetpack/cybernetic
+ multiplicative_slowdown = -0.5
+
+/datum/movespeed_modifier/jetpack/fullspeed
+ multiplicative_slowdown = -0.5
+
+/datum/movespeed_modifier/die_of_fate
+ multiplicative_slowdown = 1
diff --git a/code/modules/movespeed/modifiers/misc.dm b/code/modules/movespeed/modifiers/misc.dm
new file mode 100644
index 00000000000..55c1aef5271
--- /dev/null
+++ b/code/modules/movespeed/modifiers/misc.dm
@@ -0,0 +1,6 @@
+/datum/movespeed_modifier/admin_varedit
+ variable = TRUE
+
+/datum/movespeed_modifier/yellow_orb
+ multiplicative_slowdown = -2
+ blacklisted_movetypes = (FLYING|FLOATING)
diff --git a/code/modules/movespeed/modifiers/mobs.dm b/code/modules/movespeed/modifiers/mobs.dm
new file mode 100644
index 00000000000..cc92c38533e
--- /dev/null
+++ b/code/modules/movespeed/modifiers/mobs.dm
@@ -0,0 +1,106 @@
+/datum/movespeed_modifier/obesity
+ multiplicative_slowdown = 1.5
+
+/datum/movespeed_modifier/monkey_reagent_speedmod
+ variable = TRUE
+
+/datum/movespeed_modifier/monkey_health_speedmod
+ variable = TRUE
+
+/datum/movespeed_modifier/monkey_temperature_speedmod
+ variable = TRUE
+
+/datum/movespeed_modifier/hunger
+ variable = TRUE
+
+/datum/movespeed_modifier/slaughter
+ multiplicative_slowdown = -1
+
+/datum/movespeed_modifier/damage_slowdown
+ blacklisted_movetypes = FLOATING|FLYING
+ variable = TRUE
+
+/datum/movespeed_modifier/damage_slowdown_flying
+ movetypes = FLOATING
+ variable = TRUE
+
+/datum/movespeed_modifier/equipment_speedmod
+ variable = TRUE
+ blacklisted_movetypes = FLOATING
+
+/datum/movespeed_modifier/grab_slowdown
+ id = MOVESPEED_ID_MOB_GRAB_STATE
+ blacklisted_movetypes = FLOATING
+
+/datum/movespeed_modifier/grab_slowdown/aggressive
+ multiplicative_slowdown = 3
+
+/datum/movespeed_modifier/grab_slowdown/neck
+ multiplicative_slowdown = 6
+
+/datum/movespeed_modifier/grab_slowdown/kill
+ multiplicative_slowdown = 9
+
+/datum/movespeed_modifier/slime_reagentmod
+ variable = TRUE
+
+/datum/movespeed_modifier/slime_healthmod
+ variable = TRUE
+
+/datum/movespeed_modifier/config_walk_run
+ multiplicative_slowdown = 1
+ id = MOVESPEED_ID_MOB_WALK_RUN
+
+/datum/movespeed_modifier/config_walk_run/proc/sync()
+
+/datum/movespeed_modifier/config_walk_run/walk/sync()
+ var/mod = CONFIG_GET(number/movedelay/walk_delay)
+ multiplicative_slowdown = isnum(mod)? mod : initial(multiplicative_slowdown)
+
+/datum/movespeed_modifier/config_walk_run/run/sync()
+ var/mod = CONFIG_GET(number/movedelay/run_delay)
+ multiplicative_slowdown = isnum(mod)? mod : initial(multiplicative_slowdown)
+
+/datum/movespeed_modifier/turf_slowdown
+ movetypes = GROUND
+ blacklisted_movetypes = (FLYING|FLOATING)
+ variable = TRUE
+
+/datum/movespeed_modifier/bulky_drag
+ variable = TRUE
+
+/datum/movespeed_modifier/cold
+ blacklisted_movetypes = FLOATING
+ variable = TRUE
+
+/datum/movespeed_modifier/shove
+ multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH
+
+/datum/movespeed_modifier/human_carry
+ multiplicative_slowdown = HUMAN_CARRY_SLOWDOWN
+
+/datum/movespeed_modifier/limbless
+ variable = TRUE
+ movetypes = GROUND
+
+/datum/movespeed_modifier/simplemob_varspeed
+ variable = TRUE
+
+/datum/movespeed_modifier/tarantula_web
+ multiplicative_slowdown = 3
+
+/datum/movespeed_modifier/gravity
+ blacklisted_movetypes = FLOATING
+ variable = TRUE
+
+/datum/movespeed_modifier/carbon_softcrit
+ multiplicative_slowdown = SOFTCRIT_ADD_SLOWDOWN
+
+/datum/movespeed_modifier/slime_tempmod
+ variable = TRUE
+
+/datum/movespeed_modifier/carbon_crawling
+ multiplicative_slowdown = CRAWLING_ADD_SLOWDOWN
+
+/datum/movespeed_modifier/mob_config_speedmod
+ variable = TRUE
diff --git a/code/modules/movespeed/modifiers/reagent.dm b/code/modules/movespeed/modifiers/reagent.dm
new file mode 100644
index 00000000000..f1a54f98de3
--- /dev/null
+++ b/code/modules/movespeed/modifiers/reagent.dm
@@ -0,0 +1,32 @@
+/datum/movespeed_modifier/reagent
+ blacklisted_movetypes = (FLYING|FLOATING)
+
+/datum/movespeed_modifier/reagent/stimulants
+ multiplicative_slowdown = -1
+
+/datum/movespeed_modifier/reagent/ephedrine
+ multiplicative_slowdown = -0.5
+
+/datum/movespeed_modifier/reagent/pepperspray
+ multiplicative_slowdown = 0.25
+
+/datum/movespeed_modifier/reagent/badstims
+ multiplicative_slowdown = -0.45
+
+/datum/movespeed_modifier/reagent/monkey_energy
+ multiplicative_slowdown = -0.35
+
+/datum/movespeed_modifier/reagent/changelinghaste
+ multiplicative_slowdown = -2
+
+/datum/movespeed_modifier/reagent/methamphetamine
+ multiplicative_slowdown = -0.65
+
+/datum/movespeed_modifier/reagent/nitryl
+ multiplicative_slowdown = -0.65
+
+/datum/movespeed_modifier/reagent/lenturi
+ multiplicative_slowdown = 1.5
+
+/datum/movespeed_modifier/reagent/nuka_cola
+ multiplicative_slowdown = -0.35
diff --git a/code/modules/movespeed/modifiers/status_effects.dm b/code/modules/movespeed/modifiers/status_effects.dm
new file mode 100644
index 00000000000..506a4672ef1
--- /dev/null
+++ b/code/modules/movespeed/modifiers/status_effects.dm
@@ -0,0 +1,17 @@
+/datum/movespeed_modifier/status_effect/bloodchill
+ multiplicative_slowdown = 3
+
+/datum/movespeed_modifier/status_effect/bonechill
+ multiplicative_slowdown = 3
+
+/datum/movespeed_modifier/status_effect/lightpink
+ multiplicative_slowdown = -0.5
+ blacklisted_movetypes = (FLYING|FLOATING)
+
+/datum/movespeed_modifier/status_effect/tarfoot
+ multiplicative_slowdown = 0.5
+ blacklisted_movetypes = (FLYING|FLOATING)
+
+/datum/movespeed_modifier/status_effect/sepia
+ variable = TRUE
+ blacklisted_movetypes = (FLYING|FLOATING)
diff --git a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm
index 59e49e9bf41..cb87676b534 100644
--- a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm
@@ -143,17 +143,19 @@
var/spammer = 0
/datum/reagent/medicine/C2/lenturi/on_mob_life(mob/living/carbon/M)
- M.adjustFireLoss(-3 * REM)
- M.adjustOrganLoss(ORGAN_SLOT_STOMACH, 0.4 * REM)
- ..()
- return TRUE
-/datum/reagent/medicine/C2/lenturi/on_mob_metabolize(mob/living/carbon/M)
- M.add_movespeed_modifier(MOVESPEED_ID_LENTURI, update=TRUE, priority=100, multiplicative_slowdown=1.50, blacklisted_movetypes=(FLYING|FLOATING))
- . = ..()
-/datum/reagent/medicine/C2/lenturi/on_mob_end_metabolize(mob/living/carbon/M)
- M.remove_movespeed_modifier(MOVESPEED_ID_LENTURI)
+ M.adjustFireLoss(-3 * REM)
+ M.adjustOrganLoss(ORGAN_SLOT_STOMACH, 0.4 * REM)
+ ..()
+ return TRUE
+
+/datum/reagent/medicine/C2/lenturi/on_mob_metabolize(mob/living/carbon/M)
+ M.add_movespeed_modifier(/datum/movespeed_modifier/reagent/lenturi)
+ return ..()
+
+/datum/reagent/medicine/C2/lenturi/on_mob_end_metabolize(mob/living/carbon/M)
+ M.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/lenturi)
+ return ..()
- . = ..()
/datum/reagent/medicine/C2/aiuri
name = "Aiuri"
description = "Used to treat burns. Does minor eye damage."
diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm
index a10fc254eab..57d57650883 100644
--- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm
@@ -376,10 +376,10 @@
/datum/reagent/consumable/nuka_cola/on_mob_metabolize(mob/living/L)
..()
- L.add_movespeed_modifier(type, update=TRUE, priority=100, multiplicative_slowdown=-0.35, blacklisted_movetypes=(FLYING|FLOATING))
+ L.add_movespeed_modifier(/datum/movespeed_modifier/reagent/nuka_cola)
/datum/reagent/consumable/nuka_cola/on_mob_end_metabolize(mob/living/L)
- L.remove_movespeed_modifier(type)
+ L.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/nuka_cola)
..()
/datum/reagent/consumable/nuka_cola/on_mob_life(mob/living/carbon/M)
@@ -565,17 +565,16 @@
/datum/reagent/consumable/monkey_energy/on_mob_metabolize(mob/living/L)
..()
if(ismonkey(L))
- L.add_movespeed_modifier(type, update=TRUE, priority=100, multiplicative_slowdown=-0.35, blacklisted_movetypes=(FLYING|FLOATING))
+ L.add_movespeed_modifier(/datum/movespeed_modifier/reagent/monkey_energy)
/datum/reagent/consumable/monkey_energy/on_mob_end_metabolize(mob/living/L)
- L.remove_movespeed_modifier(type)
+ L.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/monkey_energy)
..()
/datum/reagent/consumable/monkey_energy/overdose_process(mob/living/M)
if(prob(15))
M.say(pick_list_replacements(BOOMER_FILE, "boomer"), forced = /datum/reagent/consumable/monkey_energy)
..()
- return
/datum/reagent/consumable/ice
name = "Ice"
diff --git a/code/modules/reagents/chemistry/reagents/drug_reagents.dm b/code/modules/reagents/chemistry/reagents/drug_reagents.dm
index e20191c3358..5b21f771952 100644
--- a/code/modules/reagents/chemistry/reagents/drug_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/drug_reagents.dm
@@ -174,10 +174,10 @@
/datum/reagent/drug/methamphetamine/on_mob_metabolize(mob/living/L)
..()
- L.add_movespeed_modifier(type, update=TRUE, priority=100, multiplicative_slowdown=-0.65, blacklisted_movetypes=(FLYING|FLOATING))
+ L.add_movespeed_modifier(/datum/movespeed_modifier/reagent/methamphetamine)
/datum/reagent/drug/methamphetamine/on_mob_end_metabolize(mob/living/L)
- L.remove_movespeed_modifier(type)
+ L.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/methamphetamine)
..()
/datum/reagent/drug/methamphetamine/on_mob_life(mob/living/carbon/M)
diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm
index f6fa3d5d813..d4384cbf282 100755
--- a/code/modules/reagents/chemistry/reagents/food_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm
@@ -293,8 +293,8 @@
victim.blind_eyes(3) // 6 seconds
victim.confused = max(M.confused, 5) // 10 seconds
victim.Knockdown(3 SECONDS)
- victim.add_movespeed_modifier(MOVESPEED_ID_PEPPER_SPRAY, update=TRUE, priority=100, multiplicative_slowdown=0.25, blacklisted_movetypes=(FLYING|FLOATING))
- addtimer(CALLBACK(victim, /mob.proc/remove_movespeed_modifier, MOVESPEED_ID_PEPPER_SPRAY), 10 SECONDS)
+ victim.add_movespeed_modifier(/datum/movespeed_modifier/reagent/pepperspray)
+ addtimer(CALLBACK(victim, /mob.proc/remove_movespeed_modifier, /datum/movespeed_modifier/reagent/pepperspray), 10 SECONDS)
victim.update_damage_hud()
if(method == INGEST)
if(!holder.has_reagent(/datum/reagent/consumable/milk))
diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
index e4688c2bb9d..b28e6e97fcd 100644
--- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
@@ -437,11 +437,11 @@
/datum/reagent/medicine/ephedrine/on_mob_metabolize(mob/living/L)
..()
- L.add_movespeed_modifier(type, update=TRUE, priority=100, multiplicative_slowdown=-0.5, blacklisted_movetypes=(FLYING|FLOATING))
+ L.add_movespeed_modifier(/datum/movespeed_modifier/reagent/ephedrine)
ADD_TRAIT(L, TRAIT_STUNRESISTANCE, type)
/datum/reagent/medicine/ephedrine/on_mob_end_metabolize(mob/living/L)
- L.remove_movespeed_modifier(type)
+ L.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/ephedrine)
REMOVE_TRAIT(L, TRAIT_STUNRESISTANCE, type)
..()
@@ -811,11 +811,11 @@
/datum/reagent/medicine/stimulants/on_mob_metabolize(mob/living/L)
..()
- L.add_movespeed_modifier(type, update=TRUE, priority=100, multiplicative_slowdown=-1, blacklisted_movetypes=(FLYING|FLOATING))
+ L.add_movespeed_modifier(/datum/movespeed_modifier/reagent/stimulants)
ADD_TRAIT(L, TRAIT_STUNRESISTANCE, type)
/datum/reagent/medicine/stimulants/on_mob_end_metabolize(mob/living/L)
- L.remove_movespeed_modifier(type)
+ L.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/stimulants)
REMOVE_TRAIT(L, TRAIT_STUNRESISTANCE, type)
..()
@@ -1043,10 +1043,10 @@
/datum/reagent/medicine/changelinghaste/on_mob_metabolize(mob/living/L)
..()
- L.add_movespeed_modifier(type, update=TRUE, priority=100, multiplicative_slowdown=-2, blacklisted_movetypes=(FLYING|FLOATING))
+ L.add_movespeed_modifier(/datum/movespeed_modifier/reagent/changelinghaste)
/datum/reagent/medicine/changelinghaste/on_mob_end_metabolize(mob/living/L)
- L.remove_movespeed_modifier(type)
+ L.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/changelinghaste)
..()
/datum/reagent/medicine/changelinghaste/on_mob_life(mob/living/carbon/M)
@@ -1294,14 +1294,14 @@
..()
ADD_TRAIT(L, TRAIT_SLEEPIMMUNE, type)
ADD_TRAIT(L, TRAIT_STUNRESISTANCE, type)
- L.add_movespeed_modifier(type, update=TRUE, priority=100, multiplicative_slowdown=-0.45, blacklisted_movetypes=(FLYING|FLOATING))
+ L.add_movespeed_modifier(/datum/movespeed_modifier/reagent/badstims)
L.ignore_slowdown(type)
/datum/reagent/medicine/badstims/on_mob_end_metabolize(mob/living/L)
..()
REMOVE_TRAIT(L, TRAIT_SLEEPIMMUNE, type)
REMOVE_TRAIT(L, TRAIT_STUNRESISTANCE, type)
- L.remove_movespeed_modifier(type)
+ L.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/badstims)
L.unignore_slowdown(type)
L.Dizzy(0)
L.Jitter(0)
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index 4396bae93e6..e23346a4892 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -1245,10 +1245,10 @@
/datum/reagent/nitryl/on_mob_metabolize(mob/living/L)
..()
- L.add_movespeed_modifier(type, update=TRUE, priority=100, multiplicative_slowdown=-0.65, blacklisted_movetypes=(FLYING|FLOATING))
+ L.add_movespeed_modifier(/datum/movespeed_modifier/reagent/nitryl)
/datum/reagent/nitryl/on_mob_end_metabolize(mob/living/L)
- L.remove_movespeed_modifier(type)
+ L.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/nitryl)
..()
/////////////////////////Colorful Powder////////////////////////////
diff --git a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm
index 0344ec1fe9a..71ca68b2a0e 100644
--- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm
+++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm
@@ -185,7 +185,7 @@
alert_type = /obj/screen/alert/status_effect/bloodchill
/datum/status_effect/bloodchill/on_apply()
- owner.add_movespeed_modifier("bloodchilled", TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = 3)
+ owner.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/bloodchill)
return ..()
/datum/status_effect/bloodchill/tick()
@@ -193,7 +193,7 @@
owner.adjustFireLoss(2)
/datum/status_effect/bloodchill/on_remove()
- owner.remove_movespeed_modifier("bloodchilled")
+ owner.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/bloodchill)
/datum/status_effect/bonechill
id = "bonechill"
@@ -201,7 +201,7 @@
alert_type = /obj/screen/alert/status_effect/bonechill
/datum/status_effect/bonechill/on_apply()
- owner.add_movespeed_modifier("bonechilled", TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = 3)
+ owner.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/bonechill)
return ..()
/datum/status_effect/bonechill/tick()
@@ -211,8 +211,7 @@
owner.adjust_bodytemperature(-10)
/datum/status_effect/bonechill/on_remove()
- owner.remove_movespeed_modifier("bonechilled")
-
+ owner.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/bonechill)
/obj/screen/alert/status_effect/bonechill
name = "Bonechilled"
desc = "You feel a shiver down your spine after hearing the haunting noise of bone rattling. You'll move slower and get frostbite for a while!"
@@ -366,11 +365,11 @@ datum/status_effect/rebreathing/tick()
duration = 30
/datum/status_effect/tarfoot/on_apply()
- owner.add_movespeed_modifier(MOVESPEED_ID_TARFOOT, update=TRUE, priority=100, multiplicative_slowdown=0.5, blacklisted_movetypes=(FLYING|FLOATING))
+ owner.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/tarfoot)
return ..()
/datum/status_effect/tarfoot/on_remove()
- owner.remove_movespeed_modifier(MOVESPEED_ID_TARFOOT)
+ owner.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/tarfoot)
/datum/status_effect/spookcookie
id = "spookcookie"
@@ -684,15 +683,15 @@ datum/status_effect/stabilized/blue/on_remove()
/datum/status_effect/stabilized/sepia/tick()
if(prob(50) && mod > -1)
mod--
- owner.add_movespeed_modifier(MOVESPEED_ID_SEPIA, override = TRUE, update=TRUE, priority=100, multiplicative_slowdown=-0.5, blacklisted_movetypes=(FLYING|FLOATING))
+ owner.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/status_effect/sepia, multiplicative_slowdown = -0.5)
else if(mod < 1)
mod++
// yeah a value of 0 does nothing but replacing the trait in place is cheaper than removing and adding repeatedly
- owner.add_movespeed_modifier(MOVESPEED_ID_SEPIA, override = TRUE, update=TRUE, priority=100, multiplicative_slowdown=0, blacklisted_movetypes=(FLYING|FLOATING))
+ owner.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/status_effect/sepia, multiplicative_slowdown = 0)
return ..()
/datum/status_effect/stabilized/sepia/on_remove()
- owner.remove_movespeed_modifier(MOVESPEED_ID_SEPIA)
+ owner.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/sepia)
/datum/status_effect/stabilized/cerulean
id = "stabilizedcerulean"
@@ -900,7 +899,7 @@ datum/status_effect/stabilized/blue/on_remove()
colour = "light pink"
/datum/status_effect/stabilized/lightpink/on_apply()
- owner.add_movespeed_modifier(MOVESPEED_ID_SLIME_STATUS, update=TRUE, priority=100, multiplicative_slowdown=-0.5, blacklisted_movetypes=(FLYING|FLOATING))
+ owner.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/lightpink)
return ..()
/datum/status_effect/stabilized/lightpink/tick()
@@ -911,7 +910,7 @@ datum/status_effect/stabilized/blue/on_remove()
return ..()
/datum/status_effect/stabilized/lightpink/on_remove()
- owner.remove_movespeed_modifier(MOVESPEED_ID_SLIME_STATUS)
+ owner.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/lightpink)
/datum/status_effect/stabilized/adamantine
id = "stabilizedadamantine"
diff --git a/code/modules/station_goals/dna_vault.dm b/code/modules/station_goals/dna_vault.dm
index e040ea422a4..a66b07ec039 100644
--- a/code/modules/station_goals/dna_vault.dm
+++ b/code/modules/station_goals/dna_vault.dm
@@ -248,8 +248,6 @@
else
return ..()
-
-
/obj/machinery/dna_vault/proc/upgrade(mob/living/carbon/human/H,upgrade_type)
if(!(upgrade_type in power_lottery[H]))
return
@@ -279,7 +277,7 @@
ADD_TRAIT(H, TRAIT_PIERCEIMMUNE, "dna_vault")
if(VAULT_SPEED)
to_chat(H, "Your legs feel faster.")
- H.add_movespeed_modifier(MOVESPEED_ID_DNA_VAULT, update=TRUE, priority=100, multiplicative_slowdown=-0.4, blacklisted_movetypes=(FLYING|FLOATING))
+ H.add_movespeed_modifier(/datum/movespeed_modifier/dna_vault_speedup)
if(VAULT_QUICK)
to_chat(H, "Your arms move as fast as lightning.")
H.next_move_modifier = 0.5
diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/augments_chest.dm
index 0721824ec29..2baea55b151 100644
--- a/code/modules/surgery/organs/augments_chest.dm
+++ b/code/modules/surgery/organs/augments_chest.dm
@@ -153,15 +153,15 @@
on = TRUE
ion_trail.start()
RegisterSignal(owner, COMSIG_MOVABLE_MOVED, .proc/move_react)
+ owner.add_movespeed_modifier(/datum/movespeed_modifier/jetpack/cybernetic)
RegisterSignal(owner, COMSIG_MOVABLE_PRE_MOVE, .proc/pre_move_react)
- owner.add_movespeed_modifier(MOVESPEED_ID_CYBER_THRUSTER, priority=100, multiplicative_slowdown=-0.5, movetypes=FLOATING, conflict=MOVE_CONFLICT_JETPACK)
if(!silent)
to_chat(owner, "You turn your thrusters set on.")
else
ion_trail.stop()
UnregisterSignal(owner, COMSIG_MOVABLE_MOVED)
+ owner.remove_movespeed_modifier(/datum/movespeed_modifier/jetpack/cybernetic)
UnregisterSignal(owner, COMSIG_MOVABLE_PRE_MOVE)
- owner.remove_movespeed_modifier(MOVESPEED_ID_CYBER_THRUSTER)
if(!silent)
to_chat(owner, "You turn your thrusters set off.")
on = FALSE
diff --git a/tgstation.dme b/tgstation.dme
index b00e0e14596..cdf3a91ac2e 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -2072,7 +2072,6 @@
#include "code\modules\mob\mob_defines.dm"
#include "code\modules\mob\mob_helpers.dm"
#include "code\modules\mob\mob_movement.dm"
-#include "code\modules\mob\mob_movespeed.dm"
#include "code\modules\mob\mob_transformation_simple.dm"
#include "code\modules\mob\say.dm"
#include "code\modules\mob\status_procs.dm"
@@ -2432,6 +2431,14 @@
#include "code\modules\modular_computers\hardware\printer.dm"
#include "code\modules\modular_computers\hardware\recharger.dm"
#include "code\modules\modular_computers\NTNet\NTNRC\conversation.dm"
+#include "code\modules\movespeed\_movespeed_modifier.dm"
+#include "code\modules\movespeed\modifiers\components.dm"
+#include "code\modules\movespeed\modifiers\innate.dm"
+#include "code\modules\movespeed\modifiers\items.dm"
+#include "code\modules\movespeed\modifiers\misc.dm"
+#include "code\modules\movespeed\modifiers\mobs.dm"
+#include "code\modules\movespeed\modifiers\reagent.dm"
+#include "code\modules\movespeed\modifiers\status_effects.dm"
#include "code\modules\ninja\__ninjaDefines.dm"
#include "code\modules\ninja\energy_katana.dm"
#include "code\modules\ninja\ninja_event.dm"