diff --git a/code/__DEFINES/movespeed_modification.dm b/code/__DEFINES/movespeed_modification.dm
new file mode 100644
index 00000000000..d3585aab97e
--- /dev/null
+++ b/code/__DEFINES/movespeed_modification.dm
@@ -0,0 +1,31 @@
+#define MOVESPEED_DATA_INDEX_PRIORITY 1
+#define MOVESPEED_DATA_INDEX_FLAGS 2
+#define MOVESPEED_DATA_INDEX_MULTIPLICATIVE_SLOWDOWN 3
+
+#define MOVESPEED_DATA_INDEX_MAX 3
+
+//flags
+#define IGNORE_NOSLOW (1 << 0)
+
+//ids
+
+#define MOVESPEED_ID_MOB_WALK_RUN_CONFIG_SPEED "MOB_WALK_RUN"
+#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_LIVING_TURF_SPEEDMOD "LIVING_TURF_SPEEDMOD"
+
+#define MOVESPEED_ID_CARBON_SOFTCRIT "CARBON_SOFTCRIT"
+#define MOVESPEED_ID_CARBON_OLDSPEED "CARBON_DEPRECATED_SPEED"
+
+#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_SIMPLEMOB_VARSPEED "SIMPLEMOB_VARSPEED_MODIFIER"
+#define MOVESPEED_ID_ADMIN_VAREDIT "ADMIN_VAREDIT_MODIFIER"
+
+#define MOVESPEED_ID_PAI_SPACEWALK_SPEEDMOD "PAI_SPACEWALK_MODIFIER"
\ No newline at end of file
diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm
index fd94293ff69..3e1c2b778d7 100644
--- a/code/__HELPERS/roundend.dm
+++ b/code/__HELPERS/roundend.dm
@@ -194,7 +194,7 @@
send2irc("Server", "Round just ended.")
- if(length(CONFIG_GET(keyed_string_list/cross_server)))
+ if(length(CONFIG_GET(keyed_list/cross_server)))
send_news_report()
CHECK_TICK
diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm
index 1010aa7676d..9cea3d1a71d 100644
--- a/code/_globalvars/lists/mobs.dm
+++ b/code/_globalvars/lists/mobs.dm
@@ -34,3 +34,23 @@ GLOBAL_LIST_EMPTY(all_languages)
GLOBAL_LIST_EMPTY(sentient_disease_instances)
GLOBAL_LIST_EMPTY(latejoin_ai_cores)
+
+GLOBAL_LIST_EMPTY(mob_config_movespeed_type_lookup)
+
+/proc/update_config_movespeed_type_lookup(update_mobs = TRUE)
+ var/list/mob_types = list()
+ var/list/entry_value = CONFIG_GET(keyed_list/multiplicative_movespeed)
+ for(var/path in entry_value)
+ var/value = entry_value[path]
+ if(!value)
+ continue
+ for(var/subpath in typesof(path))
+ mob_types[subpath] = value
+ GLOB.mob_config_movespeed_type_lookup = mob_types
+ if(update_mobs)
+ update_mob_config_movespeeds()
+
+/proc/update_mob_config_movespeeds()
+ for(var/i in GLOB.mob_list)
+ var/mob/M = i
+ M.update_config_movespeed()
diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm
index dca035f90f0..9d65cddda43 100644
--- a/code/_onclick/hud/screen_objects.dm
+++ b/code/_onclick/hud/screen_objects.dm
@@ -310,17 +310,21 @@
/obj/screen/mov_intent/Click()
toggle(usr)
+/obj/screen/mov_intent/update_icon(mob/user)
+ if(!user && hud)
+ user = hud.mymob
+ if(!user)
+ return
+ switch(user.m_intent)
+ if(MOVE_INTENT_WALK)
+ icon_state = "walking"
+ if(MOVE_INTENT_RUN)
+ icon_state = "running"
+
/obj/screen/mov_intent/proc/toggle(mob/user)
if(isobserver(user))
return
- switch(user.m_intent)
- if("run")
- user.m_intent = MOVE_INTENT_WALK
- icon_state = "walking"
- if("walk")
- user.m_intent = MOVE_INTENT_RUN
- icon_state = "running"
- user.update_icons()
+ user.toggle_move_intent(user)
/obj/screen/pull
name = "stop pulling"
diff --git a/code/controllers/configuration/config_entry.dm b/code/controllers/configuration/config_entry.dm
index c683f55c59d..5314cf19b91 100644
--- a/code/controllers/configuration/config_entry.dm
+++ b/code/controllers/configuration/config_entry.dm
@@ -1,6 +1,9 @@
-#define LIST_MODE_NUM 0
-#define LIST_MODE_TEXT 1
-#define LIST_MODE_FLAG 2
+#define VALUE_MODE_NUM 0
+#define VALUE_MODE_TEXT 1
+#define VALUE_MODE_FLAG 2
+
+#define KEY_MODE_TEXT 0
+#define KEY_MODE_TYPE 1
/datum/config_entry
var/name //read-only, this is determined by the last portion of the derived entry type
@@ -58,32 +61,6 @@
VASProcCallGuard(str_val)
CRASH("Invalid config entry type!")
-/datum/config_entry/proc/ValidateKeyedList(str_val, list_mode, splitter)
- str_val = trim(str_val)
- var/key_pos = findtext(str_val, splitter)
- var/key_name = null
- var/key_value = null
-
- if(key_pos || list_mode == LIST_MODE_FLAG)
- key_name = lowertext(copytext(str_val, 1, key_pos))
- key_value = copytext(str_val, key_pos + 1)
- var/temp
- var/continue_check
- switch(list_mode)
- if(LIST_MODE_FLAG)
- temp = TRUE
- continue_check = TRUE
- if(LIST_MODE_NUM)
- temp = text2num(key_value)
- continue_check = !isnull(temp)
- if(LIST_MODE_TEXT)
- temp = key_value
- continue_check = temp
- if(continue_check && ValidateListEntry(key_name, temp))
- config_entry_value[key_name] = temp
- return TRUE
- return FALSE
-
/datum/config_entry/proc/ValidateListEntry(key_name, key_value)
return TRUE
@@ -156,44 +133,58 @@
config_entry_value = new_list
return TRUE
-/datum/config_entry/keyed_flag_list
- abstract_type = /datum/config_entry/keyed_flag_list
- config_entry_value = list()
- dupes_allowed = TRUE
-
-/datum/config_entry/keyed_flag_list/ValidateAndSet(str_val)
- if(!VASProcCallGuard(str_val))
- return FALSE
- return ValidateKeyedList(str_val, LIST_MODE_FLAG, " ")
-
-/datum/config_entry/keyed_number_list
- abstract_type = /datum/config_entry/keyed_number_list
+/datum/config_entry/keyed_list
+ abstract_type = /datum/config_entry/keyed_list
config_entry_value = list()
dupes_allowed = TRUE
+ var/key_mode
+ var/value_mode
var/splitter = " "
-/datum/config_entry/keyed_number_list/vv_edit_var(var_name, var_value)
- return var_name != "splitter" && ..()
+/datum/config_entry/keyed_list/New()
+ . = ..()
+ if(isnull(key_mode) || isnull(value_mode))
+ CRASH("Keyed list of type [type] created with null key or value mode!")
-/datum/config_entry/keyed_number_list/ValidateAndSet(str_val)
+/datum/config_entry/keyed_list/ValidateAndSet(str_val)
if(!VASProcCallGuard(str_val))
return FALSE
- return ValidateKeyedList(str_val, LIST_MODE_NUM, splitter)
-/datum/config_entry/keyed_string_list
- abstract_type = /datum/config_entry/keyed_string_list
- config_entry_value = list()
- dupes_allowed = TRUE
- var/splitter = " "
+ str_val = trim(str_val)
+ var/key_pos = findtext(str_val, splitter)
+ var/key_name = null
+ var/key_value = null
-/datum/config_entry/keyed_string_list/vv_edit_var(var_name, var_value)
+ if(key_pos || value_mode == VALUE_MODE_FLAG)
+ key_name = lowertext(copytext(str_val, 1, key_pos))
+ key_value = copytext(str_val, key_pos + 1)
+ var/new_key
+ var/new_value
+ var/continue_check_value
+ var/continue_check_key
+ switch(key_mode)
+ if(KEY_MODE_TEXT)
+ new_key = key_name
+ continue_check_key = new_key
+ if(KEY_MODE_TYPE)
+ new_key = key_name
+ if(!ispath(new_key))
+ new_key = text2path(new_key)
+ continue_check_key = ispath(new_key)
+ switch(value_mode)
+ if(VALUE_MODE_FLAG)
+ new_value = TRUE
+ continue_check_value = TRUE
+ if(VALUE_MODE_NUM)
+ new_value = text2num(key_value)
+ continue_check_value = !isnull(new_value)
+ if(VALUE_MODE_TEXT)
+ new_value = key_value
+ continue_check_value = new_value
+ if(continue_check_value && continue_check_key && ValidateListEntry(new_key, new_value))
+ config_entry_value[new_key] = new_value
+ return TRUE
+ return FALSE
+
+/datum/config_entry/keyed_list/vv_edit_var(var_name, var_value)
return var_name != "splitter" && ..()
-
-/datum/config_entry/keyed_string_list/ValidateAndSet(str_val)
- if(!VASProcCallGuard(str_val))
- return FALSE
- return ValidateKeyedList(str_val, LIST_MODE_TEXT, splitter)
-
-#undef LIST_MODE_NUM
-#undef LIST_MODE_TEXT
-#undef LIST_MODE_FLAG
diff --git a/code/controllers/configuration/configuration.dm b/code/controllers/configuration/configuration.dm
index 60904ab5efa..2b1790c7f8c 100644
--- a/code/controllers/configuration/configuration.dm
+++ b/code/controllers/configuration/configuration.dm
@@ -89,7 +89,7 @@
L = trim(L)
if(!L)
continue
-
+
var/firstchar = copytext(L, 1, 2)
if(firstchar == "#")
continue
@@ -110,7 +110,7 @@
if(!entry)
continue
-
+
if(entry == "$include")
if(!value)
log_config("Warning: Invalid $include directive: [value]")
@@ -118,7 +118,7 @@
LoadEntries(value, stack)
++.
continue
-
+
var/datum/config_entry/E = _entries[entry]
if(!E)
log_config("Unknown setting in configuration: '[entry]'")
@@ -140,19 +140,19 @@
E = new_ver
else
warning("[new_ver.type] is deprecated but gave no proper return for DeprecationUpdate()")
-
+
var/validated = E.ValidateAndSet(value)
if(!validated)
log_config("Failed to validate setting \"[value]\" for [entry]")
- else
+ else
if(E.modified && !E.dupes_allowed)
log_config("Duplicate setting for [entry] ([value], [E.resident_file]) detected! Using latest.")
E.resident_file = filename
-
+
if(validated)
E.modified = TRUE
-
+
++.
/datum/controller/configuration/can_vv_get(var_name)
@@ -200,7 +200,7 @@
mode_reports = list()
mode_false_report_weight = list()
votable_modes = list()
- var/list/probabilities = Get(/datum/config_entry/keyed_number_list/probability)
+ var/list/probabilities = Get(/datum/config_entry/keyed_list/probability)
for(var/T in gamemode_cache)
// I wish I didn't have to instance the game modes in order to look up
// their information, but it is the only way (at least that I know of).
@@ -296,9 +296,9 @@
/datum/controller/configuration/proc/get_runnable_modes()
var/list/datum/game_mode/runnable_modes = new
- var/list/probabilities = Get(/datum/config_entry/keyed_number_list/probability)
- var/list/min_pop = Get(/datum/config_entry/keyed_number_list/min_pop)
- var/list/max_pop = Get(/datum/config_entry/keyed_number_list/max_pop)
+ var/list/probabilities = Get(/datum/config_entry/keyed_list/probability)
+ var/list/min_pop = Get(/datum/config_entry/keyed_list/min_pop)
+ var/list/max_pop = Get(/datum/config_entry/keyed_list/max_pop)
var/list/repeated_mode_adjust = Get(/datum/config_entry/number_list/repeated_mode_adjust)
for(var/T in gamemode_cache)
var/datum/game_mode/M = new T()
@@ -326,9 +326,9 @@
/datum/controller/configuration/proc/get_runnable_midround_modes(crew)
var/list/datum/game_mode/runnable_modes = new
- var/list/probabilities = Get(/datum/config_entry/keyed_number_list/probability)
- var/list/min_pop = Get(/datum/config_entry/keyed_number_list/min_pop)
- var/list/max_pop = Get(/datum/config_entry/keyed_number_list/max_pop)
+ var/list/probabilities = Get(/datum/config_entry/keyed_list/probability)
+ var/list/min_pop = Get(/datum/config_entry/keyed_list/min_pop)
+ var/list/max_pop = Get(/datum/config_entry/keyed_list/max_pop)
for(var/T in (gamemode_cache - SSticker.mode.type))
var/datum/game_mode/M = new T()
if(!(M.config_tag in modes))
diff --git a/code/controllers/configuration/entries/comms.dm b/code/controllers/configuration/entries/comms.dm
index 576e73faaa4..a1de1c962e9 100644
--- a/code/controllers/configuration/entries/comms.dm
+++ b/code/controllers/configuration/entries/comms.dm
@@ -4,10 +4,12 @@
/datum/config_entry/string/comms_key/ValidateAndSet(str_val)
return str_val != "default_pwd" && length(str_val) > 6 && ..()
-/datum/config_entry/keyed_string_list/cross_server
+/datum/config_entry/keyed_list/cross_server
+ key_mode = KEY_MODE_TEXT
+ value_mode = VALUE_MODE_TEXT
protection = CONFIG_ENTRY_LOCKED
-/datum/config_entry/keyed_string_list/cross_server/ValidateAndSet(str_val)
+/datum/config_entry/keyed_list/cross_server/ValidateAndSet(str_val)
. = ..()
if(.)
var/list/newv = list()
@@ -15,7 +17,7 @@
newv[replacetext(I, "+", " ")] = config_entry_value[I]
config_entry_value = newv
-/datum/config_entry/keyed_string_list/cross_server/ValidateListEntry(key_name, key_value)
+/datum/config_entry/keyed_list/cross_server/ValidateListEntry(key_name, key_value)
return key_value != "byond:\\address:port" && ..()
/datum/config_entry/string/cross_comms_name
diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm
index 1339d8cae49..9a1457e0e19 100644
--- a/code/controllers/configuration/entries/game_options.dm
+++ b/code/controllers/configuration/entries/game_options.dm
@@ -1,31 +1,43 @@
/datum/config_entry/number_list/repeated_mode_adjust
-/datum/config_entry/keyed_number_list/probability
+/datum/config_entry/keyed_list/probability
+ key_mode = KEY_MODE_TEXT
+ value_mode = VALUE_MODE_NUM
-/datum/config_entry/keyed_number_list/probability/ValidateListEntry(key_name)
+/datum/config_entry/keyed_list/probability/ValidateListEntry(key_name)
return key_name in config.modes
-/datum/config_entry/keyed_number_list/max_pop
+/datum/config_entry/keyed_list/max_pop
+ key_mode = KEY_MODE_TEXT
+ value_mode = VALUE_MODE_NUM
-/datum/config_entry/keyed_number_list/max_pop/ValidateListEntry(key_name)
+/datum/config_entry/keyed_list/max_pop/ValidateListEntry(key_name)
return key_name in config.modes
-/datum/config_entry/keyed_number_list/min_pop
+/datum/config_entry/keyed_list/min_pop
+ key_mode = KEY_MODE_TEXT
+ value_mode = VALUE_MODE_NUM
-/datum/config_entry/keyed_number_list/min_pop/ValidateListEntry(key_name, key_value)
+/datum/config_entry/keyed_list/min_pop/ValidateListEntry(key_name, key_value)
return key_name in config.modes
-/datum/config_entry/keyed_flag_list/continuous // which roundtypes continue if all antagonists die
+/datum/config_entry/keyed_list/continuous // which roundtypes continue if all antagonists die
+ key_mode = KEY_MODE_TEXT
+ value_mode = VALUE_MODE_FLAG
-/datum/config_entry/keyed_flag_list/continuous/ValidateListEntry(key_name, key_value)
+/datum/config_entry/keyed_list/continuous/ValidateListEntry(key_name, key_value)
return key_name in config.modes
-/datum/config_entry/keyed_flag_list/midround_antag // which roundtypes use the midround antagonist system
+/datum/config_entry/keyed_list/midround_antag // which roundtypes use the midround antagonist system
+ key_mode = KEY_MODE_TEXT
+ value_mode = VALUE_MODE_FLAG
-/datum/config_entry/keyed_flag_list/midround_antag/ValidateListEntry(key_name, key_value)
+/datum/config_entry/keyed_list/midround_antag/ValidateListEntry(key_name, key_value)
return key_name in config.modes
-/datum/config_entry/keyed_string_list/policy
+/datum/config_entry/keyed_list/policy
+ key_mode = KEY_MODE_TEXT
+ value_mode = VALUE_MODE_TEXT
/datum/config_entry/number/damage_multiplier
config_entry_value = 1
@@ -124,7 +136,9 @@
/datum/config_entry/flag/show_game_type_odds //if set this allows players to see the odds of each roundtype on the get revision screen
-/datum/config_entry/keyed_flag_list/roundstart_races //races you can play as from the get go.
+/datum/config_entry/keyed_list/roundstart_races //races you can play as from the get go.
+ key_mode = KEY_MODE_TEXT
+ value_mode = VALUE_MODE_FLAG
/datum/config_entry/flag/join_with_mutant_humans //players can pick mutant bodyparts for humans before joining the game
@@ -174,28 +188,67 @@
/datum/config_entry/flag/emojis
-/datum/config_entry/number/run_delay //Used for modifying movement speed for mobs.
- var/static/value_cache = 0
+/datum/config_entry/keyed_list/multiplicative_movespeed
+ key_mode = KEY_MODE_TYPE
+ value_mode = VALUE_MODE_NUM
+ config_entry_value = list( //DEFAULTS
+ /mob/living/simple_animal = 1,
+ /mob/living/silicon/pai = 1,
+ /mob/living/carbon/alien/humanoid/hunter = -1,
+ /mob/living/carbon/alien/humanoid/royal/praetorian = 1,
+ /mob/living/carbon/alien/humanoid/royal/queen = 3
+ )
-/datum/config_entry/number/run_delay/ValidateAndSet()
+/datum/config_entry/keyed_list/multiplicative_movespeed/ValidateAndSet()
. = ..()
if(.)
- value_cache = config_entry_value
+ update_config_movespeed_type_lookup(TRUE)
-/datum/config_entry/number/walk_delay
- var/static/value_cache = 0
+/datum/config_entry/keyed_list/multiplicative_movespeed/vv_edit_var(var_name, var_value)
+ . = ..()
+ if(. && (var_name == NAMEOF(src, config_entry_value)))
+ update_config_movespeed_type_lookup(TRUE)
-/datum/config_entry/number/walk_delay/ValidateAndSet()
+/datum/config_entry/number/movedelay //Used for modifying movement speed for mobs.
+ abstract_type = /datum/config_entry/number/movedelay
+
+/datum/config_entry/number/movedelay/ValidateAndSet()
. = ..()
if(.)
- value_cache = config_entry_value
+ update_mob_config_movespeeds()
-/datum/config_entry/number/human_delay //Mob specific modifiers. NOTE: These will affect different mob types in different ways
-/datum/config_entry/number/robot_delay
-/datum/config_entry/number/monkey_delay
-/datum/config_entry/number/alien_delay
-/datum/config_entry/number/slime_delay
-/datum/config_entry/number/animal_delay
+/datum/config_entry/number/movedelay/vv_edit_var(var_name, var_value)
+ . = ..()
+ if(. && (var_name == NAMEOF(src, config_entry_value)))
+ update_mob_config_movespeeds()
+
+/datum/config_entry/number/movedelay/run_delay
+
+/datum/config_entry/number/movedelay/walk_delay
+
+/////////////////////////////////////////////////Outdated move delay
+/datum/config_entry/number/outdated_movedelay
+ deprecated_by = /datum/config_entry/keyed_list/multiplicative_movespeed
+ abstract_type = /datum/config_entry/number/outdated_movedelay
+
+ var/movedelay_type
+
+/datum/config_entry/number/outdated_movedelay/DeprecationUpdate(value)
+ return "[movedelay_type] [value]"
+
+/datum/config_entry/number/outdated_movedelay/human_delay
+ movedelay_type = /mob/living/carbon/human
+/datum/config_entry/number/outdated_movedelay/robot_delay
+ movedelay_type = /mob/living/silicon/robot
+/datum/config_entry/number/outdated_movedelay/monkey_delay
+ movedelay_type = /mob/living/carbon/monkey
+/datum/config_entry/number/outdated_movedelay/alien_delay
+ movedelay_type = /mob/living/carbon/alien
+/datum/config_entry/number/outdated_movedelay/slime_delay
+ movedelay_type = /mob/living/simple_animal/slime
+/datum/config_entry/number/outdated_movedelay/animal_delay
+ movedelay_type = /mob/living/simple_animal
+/////////////////////////////////////////////////
/datum/config_entry/flag/roundstart_away //Will random away mission be loaded.
@@ -219,9 +272,13 @@
config_entry_value = 12
min_val = 0
-/datum/config_entry/keyed_flag_list/random_laws
+/datum/config_entry/keyed_list/random_laws
+ key_mode = KEY_MODE_TEXT
+ value_mode = VALUE_MODE_FLAG
-/datum/config_entry/keyed_number_list/law_weight
+/datum/config_entry/keyed_list/law_weight
+ key_mode = KEY_MODE_TEXT
+ value_mode = VALUE_MODE_NUM
splitter = ","
/datum/config_entry/number/overflow_cap
@@ -286,7 +343,9 @@
/datum/config_entry/flag/shift_time_realtime
-/datum/config_entry/keyed_number_list/antag_rep
+/datum/config_entry/keyed_list/antag_rep
+ key_mode = KEY_MODE_TEXT
+ value_mode = VALUE_MODE_NUM
/datum/config_entry/number/monkeycap
config_entry_value = 64
diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm
index 00075128263..74b670b644b 100644
--- a/code/datums/ai_laws.dm
+++ b/code/datums/ai_laws.dm
@@ -218,7 +218,7 @@
/* General ai_law functions */
/datum/ai_laws/proc/set_laws_config()
- var/list/law_ids = CONFIG_GET(keyed_flag_list/random_laws)
+ var/list/law_ids = CONFIG_GET(keyed_list/random_laws)
switch(CONFIG_GET(number/default_laws))
if(0)
add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.")
@@ -247,7 +247,7 @@
/datum/ai_laws/proc/pick_weighted_lawset()
var/datum/ai_laws/lawtype
- var/list/law_weights = CONFIG_GET(keyed_number_list/law_weight)
+ var/list/law_weights = CONFIG_GET(keyed_list/law_weight)
while(!lawtype && law_weights.len)
var/possible_id = pickweightAllowZero(law_weights)
lawtype = lawid_to_type(possible_id)
diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm
index de360a3361b..1e780d7f604 100644
--- a/code/datums/datumvars.dm
+++ b/code/datums/datumvars.dm
@@ -9,6 +9,7 @@
return FALSE
vars[var_name] = var_value
datum_flags |= DF_VAR_EDITED
+ return TRUE
/datum/proc/vv_get_var(var_name)
switch(var_name)
diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm
index c0fb034f1f1..7542a4be722 100644
--- a/code/datums/helper_datums/getrev.dm
+++ b/code/datums/helper_datums/getrev.dm
@@ -72,17 +72,17 @@
to_chat(src, "Protect Assistant Role From Traitor: [CONFIG_GET(flag/protect_assistant_from_antagonist)]")
to_chat(src, "Enforce Human Authority: [CONFIG_GET(flag/enforce_human_authority)]")
to_chat(src, "Allow Latejoin Antagonists: [CONFIG_GET(flag/allow_latejoin_antagonists)]")
- to_chat(src, "Enforce Continuous Rounds: [length(CONFIG_GET(keyed_flag_list/continuous))] of [config.modes.len] roundtypes")
- to_chat(src, "Allow Midround Antagonists: [length(CONFIG_GET(keyed_flag_list/midround_antag))] of [config.modes.len] roundtypes")
+ to_chat(src, "Enforce Continuous Rounds: [length(CONFIG_GET(keyed_list/continuous))] of [config.modes.len] roundtypes")
+ to_chat(src, "Allow Midround Antagonists: [length(CONFIG_GET(keyed_list/midround_antag))] of [config.modes.len] roundtypes")
if(CONFIG_GET(flag/show_game_type_odds))
- var/list/probabilities = CONFIG_GET(keyed_number_list/probability)
+ var/list/probabilities = CONFIG_GET(keyed_list/probability)
if(SSticker.IsRoundInProgress())
var/prob_sum = 0
var/current_odds_differ = FALSE
var/list/probs = list()
var/list/modes = config.gamemode_cache
- var/list/min_pop = CONFIG_GET(keyed_number_list/min_pop)
- var/list/max_pop = CONFIG_GET(keyed_number_list/max_pop)
+ var/list/min_pop = CONFIG_GET(keyed_list/min_pop)
+ var/list/max_pop = CONFIG_GET(keyed_list/max_pop)
for(var/mode in modes)
var/datum/game_mode/M = mode
var/ctag = initial(M.config_tag)
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 2bd7bfb00aa..c3027e0d7e3 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -1,6 +1,7 @@
/atom/movable
layer = OBJ_LAYER
var/last_move = null
+ var/last_move_time = 0
var/anchored = FALSE
var/datum/thrownthing/throwing = null
var/throw_speed = 2 //How many tiles to move per ds when being thrown. Float values are fully supported
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 7c20a31c77f..2a853f92881 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -176,7 +176,7 @@
round_converted = 0
return
//somewhere between 1 and 3 minutes from now
- if(!CONFIG_GET(keyed_flag_list/midround_antag)[SSticker.mode.config_tag])
+ if(!CONFIG_GET(keyed_list/midround_antag)[SSticker.mode.config_tag])
round_converted = 0
return 1
for(var/mob/living/carbon/human/H in antag_candidates)
@@ -204,8 +204,8 @@
return TRUE
if(station_was_nuked)
return TRUE
- var/list/continuous = CONFIG_GET(keyed_flag_list/continuous)
- var/list/midround_antag = CONFIG_GET(keyed_flag_list/midround_antag)
+ var/list/continuous = CONFIG_GET(keyed_list/continuous)
+ var/list/midround_antag = CONFIG_GET(keyed_list/midround_antag)
if(!round_converted && (!continuous[config_tag] || (continuous[config_tag] && midround_antag[config_tag]))) //Non-continuous or continous with replacement antags
if(!continuous_sanity_checked) //make sure we have antags to be checking in the first place
for(var/mob/Player in GLOB.mob_list)
diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm
index e7ea46f5730..087bf20b36f 100644
--- a/code/game/gamemodes/revolution/revolution.dm
+++ b/code/game/gamemodes/revolution/revolution.dm
@@ -133,7 +133,7 @@
//Checks if the round is over//
///////////////////////////////
/datum/game_mode/revolution/check_finished()
- if(CONFIG_GET(keyed_flag_list/continuous)["revolution"])
+ if(CONFIG_GET(keyed_list/continuous)["revolution"])
if(finished)
SSshuttle.clearHostileEnvironment(src)
return ..()
diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm
index 66b2031ffb9..fa1d586ff62 100755
--- a/code/game/machinery/computer/communications.dm
+++ b/code/game/machinery/computer/communications.dm
@@ -474,7 +474,7 @@
if (authenticated==2)
dat += "
Captain Functions"
dat += "
\[ Make a Captain's Announcement \]"
- var/cross_servers_count = length(CONFIG_GET(keyed_string_list/cross_server))
+ var/cross_servers_count = length(CONFIG_GET(keyed_list/cross_server))
if(cross_servers_count)
dat += "
\[ Send a message to [cross_servers_count == 1 ? "an " : ""]allied station[cross_servers_count > 1 ? "s" : ""] \]"
if(SSmapping.config.allow_custom_shuttles)
diff --git a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm
index a22ea805ea7..4726707996a 100644
--- a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm
+++ b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm
@@ -22,7 +22,7 @@
return
move_delay = TRUE
if(step(src, direction))
- addtimer(CALLBACK(src, .proc/ResetMoveDelay), CONFIG_GET(number/walk_delay) * move_speed_multiplier)
+ addtimer(CALLBACK(src, .proc/ResetMoveDelay), CONFIG_GET(number/movedelay/walk_delay) * move_speed_multiplier)
else
ResetMoveDelay()
diff --git a/code/modules/admin/check_antagonists.dm b/code/modules/admin/check_antagonists.dm
index 9adc5837050..30fa664f42a 100644
--- a/code/modules/admin/check_antagonists.dm
+++ b/code/modules/admin/check_antagonists.dm
@@ -154,12 +154,12 @@
else
dat += "ETA: [(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]
"
dat += "Continuous Round Status
"
- dat += "[CONFIG_GET(keyed_flag_list/continuous)[SSticker.mode.config_tag] ? "Continue if antagonists die" : "End on antagonist death"]"
- if(CONFIG_GET(keyed_flag_list/continuous)[SSticker.mode.config_tag])
- dat += ", [CONFIG_GET(keyed_flag_list/midround_antag)[SSticker.mode.config_tag] ? "creating replacement antagonists" : "not creating new antagonists"]
"
+ dat += "[CONFIG_GET(keyed_list/continuous)[SSticker.mode.config_tag] ? "Continue if antagonists die" : "End on antagonist death"]"
+ if(CONFIG_GET(keyed_list/continuous)[SSticker.mode.config_tag])
+ dat += ", [CONFIG_GET(keyed_list/midround_antag)[SSticker.mode.config_tag] ? "creating replacement antagonists" : "not creating new antagonists"]
"
else
dat += "
"
- if(CONFIG_GET(keyed_flag_list/midround_antag)[SSticker.mode.config_tag])
+ if(CONFIG_GET(keyed_list/midround_antag)[SSticker.mode.config_tag])
dat += "Time limit: [CONFIG_GET(number/midround_antag_time_check)] minutes into round
"
dat += "Living crew limit: [CONFIG_GET(number/midround_antag_life_check) * 100]% of crew alive
"
dat += "If limits past: [SSticker.mode.round_ends_with_antag_death ? "End The Round" : "Continue As Extended"]
"
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index ff830a2d70b..b0dd821afaa 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -339,7 +339,7 @@
else if(href_list["toggle_continuous"])
if(!check_rights(R_ADMIN))
return
- var/list/continuous = CONFIG_GET(keyed_flag_list/continuous)
+ var/list/continuous = CONFIG_GET(keyed_list/continuous)
if(!continuous[SSticker.mode.config_tag])
continuous[SSticker.mode.config_tag] = TRUE
else
@@ -352,7 +352,7 @@
if(!check_rights(R_ADMIN))
return
- var/list/midround_antag = CONFIG_GET(keyed_flag_list/midround_antag)
+ var/list/midround_antag = CONFIG_GET(keyed_list/midround_antag)
if(!midround_antag[SSticker.mode.config_tag])
midround_antag[SSticker.mode.config_tag] = TRUE
else
diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm
index d49cb921f66..a71e0edc982 100644
--- a/code/modules/admin/verbs/adminhelp.dm
+++ b/code/modules/admin/verbs/adminhelp.dm
@@ -588,7 +588,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
message["key"] = comms_key
message += type
- var/list/servers = CONFIG_GET(keyed_string_list/cross_server)
+ var/list/servers = CONFIG_GET(keyed_list/cross_server)
for(var/I in servers)
world.Export("[servers[I]]?[list2params(message)]")
diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm
index 30e61dba1c7..2dec6f86541 100644
--- a/code/modules/client/client_defines.dm
+++ b/code/modules/client/client_defines.dm
@@ -20,8 +20,8 @@
//OTHER//
/////////
var/datum/preferences/prefs = null
- var/move_delay = 1
-
+ var/last_turn = 0
+ var/move_delay = 0
var/area = null
///////////////
diff --git a/code/modules/jobs/job_types/job.dm b/code/modules/jobs/job_types/job.dm
index 2f4daed2798..58bd24d2b63 100644
--- a/code/modules/jobs/job_types/job.dm
+++ b/code/modules/jobs/job_types/job.dm
@@ -69,7 +69,7 @@
return TRUE
/datum/job/proc/GetAntagRep()
- . = CONFIG_GET(keyed_number_list/antag_rep)[lowertext(title)]
+ . = CONFIG_GET(keyed_list/antag_rep)[lowertext(title)]
if(. == null)
return antag_rep
diff --git a/code/modules/mob/dead/dead.dm b/code/modules/mob/dead/dead.dm
index c492905995f..30b185d3eec 100644
--- a/code/modules/mob/dead/dead.dm
+++ b/code/modules/mob/dead/dead.dm
@@ -14,7 +14,7 @@ INITIALIZE_IMMEDIATE(/mob/dead)
prepare_huds()
- if(length(CONFIG_GET(keyed_string_list/cross_server)))
+ if(length(CONFIG_GET(keyed_list/cross_server)))
verbs += /mob/dead/proc/server_hop
set_focus(src)
return INITIALIZE_HINT_NORMAL
@@ -59,7 +59,7 @@ INITIALIZE_IMMEDIATE(/mob/dead)
set desc= "Jump to the other server"
if(notransform)
return
- var/list/csa = CONFIG_GET(keyed_string_list/cross_server)
+ var/list/csa = CONFIG_GET(keyed_list/cross_server)
var/pick
switch(csa.len)
if(0)
diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm
index 3df3447fa50..d3ed8a6541a 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm
@@ -5,21 +5,16 @@
health = 125
icon_state = "aliend"
-
/mob/living/carbon/alien/humanoid/drone/Initialize()
AddAbility(new/obj/effect/proc_holder/alien/evolve(null))
. = ..()
-
/mob/living/carbon/alien/humanoid/drone/create_internal_organs()
internal_organs += new /obj/item/organ/alien/plasmavessel/large
internal_organs += new /obj/item/organ/alien/resinspinner
internal_organs += new /obj/item/organ/alien/acid
..()
-/mob/living/carbon/alien/humanoid/drone/movement_delay()
- . = ..()
-
/obj/effect/proc_holder/alien/evolve
name = "Evolve to Praetorian"
desc = "Praetorian"
diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm
index 3e82641544d..fe682b5c99d 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm
@@ -10,11 +10,6 @@
internal_organs += new /obj/item/organ/alien/plasmavessel/small
..()
-/mob/living/carbon/alien/humanoid/hunter/movement_delay()
- . = -1 //hunters are sanic
- . += ..() //but they still need to slow down on stun
-
-
//Hunter verbs
/mob/living/carbon/alien/humanoid/hunter/proc/toggle_leap(message = 1)
@@ -26,7 +21,6 @@
else
return
-
/mob/living/carbon/alien/humanoid/hunter/ClickOn(atom/A, params)
face_atom(A)
if(leap_on_click)
@@ -34,7 +28,6 @@
else
..()
-
#define MAX_ALIEN_LEAP_DIST 7
/mob/living/carbon/alien/humanoid/hunter/proc/leap_at(atom/A)
diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/praetorian.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/praetorian.dm
index fe61c2a8ffb..4ec57808380 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/caste/praetorian.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/caste/praetorian.dm
@@ -5,12 +5,8 @@
health = 250
icon_state = "alienp"
-
-
/mob/living/carbon/alien/humanoid/royal/praetorian/Initialize()
-
real_name = name
-
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/repulse/xeno(src))
AddAbility(new /obj/effect/proc_holder/alien/royal/praetorian/evolve())
. = ..()
@@ -22,11 +18,6 @@
internal_organs += new /obj/item/organ/alien/neurotoxin
..()
-
-/mob/living/carbon/alien/humanoid/royal/praetorian/movement_delay()
- . = ..()
- . += 1
-
/obj/effect/proc_holder/alien/royal/praetorian/evolve
name = "Evolve"
desc = "Produce an internal egg sac capable of spawning children. Only one queen can exist at a time."
diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm
index 4a7914a22dc..97486e6a9d5 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm
@@ -5,7 +5,6 @@
health = 150
icon_state = "aliens"
-
/mob/living/carbon/alien/humanoid/sentinel/Initialize()
AddAbility(new /obj/effect/proc_holder/alien/sneak)
. = ..()
@@ -15,7 +14,3 @@
internal_organs += new /obj/item/organ/alien/acid
internal_organs += new /obj/item/organ/alien/neurotoxin
..()
-
-
-/mob/living/carbon/alien/humanoid/sentinel/movement_delay()
- . = ..()
diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
index f673f7e14c6..8403d533c41 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
@@ -26,16 +26,8 @@
AddAbility(new/obj/effect/proc_holder/alien/regurgitate(null))
. = ..()
-/mob/living/carbon/alien/humanoid/movement_delay()
- . = ..()
- var/static/config_alien_delay
- if(isnull(config_alien_delay))
- config_alien_delay = CONFIG_GET(number/alien_delay)
- . += move_delay_add + config_alien_delay + sneaking //move_delay_add is used to slow aliens with stun
-
/mob/living/carbon/alien/humanoid/restrained(ignore_grab)
- . = handcuffed
-
+ return handcuffed
/mob/living/carbon/alien/humanoid/show_inv(mob/user)
user.set_machine(src)
diff --git a/code/modules/mob/living/carbon/alien/humanoid/queen.dm b/code/modules/mob/living/carbon/alien/humanoid/queen.dm
index 9c61e8aa2db..79eed6b82b1 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/queen.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/queen.dm
@@ -40,7 +40,7 @@
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/repulse/xeno(src))
AddAbility(new/obj/effect/proc_holder/alien/royal/queen/promote())
smallsprite.Grant(src)
- ..()
+ return ..()
/mob/living/carbon/alien/humanoid/royal/queen/create_internal_organs()
internal_organs += new /obj/item/organ/alien/plasmavessel/large/queen
@@ -50,10 +50,6 @@
internal_organs += new /obj/item/organ/alien/eggsac
..()
-/mob/living/carbon/alien/humanoid/royal/queen/movement_delay()
- . = ..()
- . += 3
-
//Queen verbs
/obj/effect/proc_holder/alien/lay_egg
name = "Lay Egg"
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index b655b44e517..e25f68a5eaa 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -515,6 +515,10 @@
if(((maxHealth - total_burn) < HEALTH_THRESHOLD_DEAD) && stat == DEAD )
become_husk("burn")
med_hud_set_health()
+ if(stat == SOFT_CRIT)
+ add_movespeed_modifier(MOVESPEED_ID_CARBON_SOFTCRIT, TRUE, multiplicative_slowdown = SOFTCRIT_ADD_SLOWDOWN)
+ else
+ remove_movespeed_modifier(MOVESPEED_ID_CARBON_SOFTCRIT, TRUE)
/mob/living/carbon/update_sight()
if(!client)
diff --git a/code/modules/mob/living/carbon/carbon_movement.dm b/code/modules/mob/living/carbon/carbon_movement.dm
index e5444d32977..ca664ebb1e4 100644
--- a/code/modules/mob/living/carbon/carbon_movement.dm
+++ b/code/modules/mob/living/carbon/carbon_movement.dm
@@ -10,9 +10,6 @@
if(legcuffed)
. += legcuffed.slowdown
- if(stat == SOFT_CRIT)
- . += SOFTCRIT_ADD_SLOWDOWN
-
/mob/living/carbon/slip(knockdown_amount, obj/O, lube)
if(movement_type & FLYING)
return 0
diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm
index 5bfbb76e467..41fb4bf6777 100644
--- a/code/modules/mob/living/carbon/human/human_movement.dm
+++ b/code/modules/mob/living/carbon/human/human_movement.dm
@@ -1,9 +1,16 @@
+/mob/living/carbon/human/get_movespeed_modifiers()
+ var/list/considering = ..()
+ . = considering
+ if(has_trait(TRAIT_IGNORESLOWDOWN))
+ for(var/id in .)
+ var/list/data = .[id]
+ if(data[MOVESPEED_DATA_INDEX_FLAGS] & IGNORE_NOSLOW)
+ .[id] = data
+
/mob/living/carbon/human/movement_delay()
- . = 0
- var/static/config_human_delay
- if(isnull(config_human_delay))
- config_human_delay = CONFIG_GET(number/human_delay)
- . += ..() + config_human_delay + dna.species.movement_delay(src)
+ . = ..()
+ if(dna && dna.species)
+ . += dna.species.movement_delay(src)
/mob/living/carbon/human/slip(knockdown_amount, obj/O, lube)
if(has_trait(TRAIT_NOSLIPALL))
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 2f08f22db11..364866396e3 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -94,7 +94,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
GLOB.roundstart_races += "human"
/datum/species/proc/check_roundstart_eligible()
- if(id in (CONFIG_GET(keyed_flag_list/roundstart_races)))
+ if(id in (CONFIG_GET(keyed_list/roundstart_races)))
return TRUE
return FALSE
diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm
index 3261813160e..23ba71d81bb 100644
--- a/code/modules/mob/living/carbon/monkey/monkey.dm
+++ b/code/modules/mob/living/carbon/monkey/monkey.dm
@@ -16,8 +16,6 @@
/obj/item/bodypart/r_arm/monkey, /obj/item/bodypart/r_leg/monkey, /obj/item/bodypart/l_leg/monkey)
hud_type = /datum/hud/monkey
-
-
/mob/living/carbon/monkey/Initialize(mapload, cubespawned=FALSE, mob/spawner)
verbs += /mob/living/proc/mob_sleep
verbs += /mob/living/proc/lay_down
@@ -28,7 +26,6 @@
//initialize limbs
create_bodyparts()
-
create_internal_organs()
. = ..()
@@ -60,26 +57,31 @@
internal_organs += new /obj/item/organ/stomach
..()
-/mob/living/carbon/monkey/movement_delay()
- if(reagents)
- if(reagents.has_reagent("morphine"))
- return -1
-
- if(reagents.has_reagent("nuka_cola"))
- return -1
-
+/mob/living/carbon/monkey/on_reagent_change()
. = ..()
+ remove_movespeed_modifier(MOVESPEED_ID_MONKEY_REAGENT_SPEEDMOD, TRUE)
+ var/amount
+ if(reagents.has_reagent("morphine"))
+ amount = -1
+ if(reagents.has_reagent("nuka_cola"))
+ amount = -1
+ if(amount)
+ add_movespeed_modifier(MOVESPEED_ID_MONKEY_REAGENT_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = amount)
+
+/mob/living/carbon/monkey/updatehealth()
+ . = ..()
+ var/slow = 0
var/health_deficiency = (100 - health)
if(health_deficiency >= 45)
- . += (health_deficiency / 25)
+ slow += (health_deficiency / 25)
+ add_movespeed_modifier(MOVESPEED_ID_MONKEY_HEALTH_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = slow)
+/mob/living/carbon/monkey/adjust_bodytemperature(amount)
+ . = ..()
+ var/slow = 0
if (bodytemperature < 283.222)
- . += (283.222 - bodytemperature) / 10 * 1.75
-
- var/static/config_monkey_delay
- if(isnull(config_monkey_delay))
- config_monkey_delay = CONFIG_GET(number/monkey_delay)
- . += config_monkey_delay
+ slow += (283.222 - bodytemperature) / 10 * 1.75
+ add_movespeed_modifier(MOVESPEED_ID_MONKEY_TEMPERATURE_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = amount)
/mob/living/carbon/monkey/Stat()
..()
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 66f0a048173..0d08fdfb1a2 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -492,27 +492,6 @@
if(lying && !buckled && prob(getBruteLoss()*200/maxHealth))
makeTrail(newloc, T, old_direction)
-/mob/living/movement_delay(ignorewalk = 0)
- . = 0
- if(isopenturf(loc) && !is_flying())
- var/turf/open/T = loc
- . += T.slowdown
- var/static/datum/config_entry/number/run_delay/config_run_delay
- var/static/datum/config_entry/number/walk_delay/config_walk_delay
- if(isnull(config_run_delay))
- config_run_delay = CONFIG_GET(number/run_delay)
- config_walk_delay = CONFIG_GET(number/walk_delay)
- if(ignorewalk)
- . += config_run_delay.value_cache
- else
- switch(m_intent)
- if(MOVE_INTENT_RUN)
- if(drowsyness > 0)
- . += 6
- . += config_run_delay.value_cache
- if(MOVE_INTENT_WALK)
- . += config_walk_delay.value_cache
-
/mob/living/proc/makeTrail(turf/target_turf, turf/start, direction)
if(!has_gravity())
return
diff --git a/code/modules/mob/living/living_movement.dm b/code/modules/mob/living/living_movement.dm
new file mode 100644
index 00000000000..16c3aa6050b
--- /dev/null
+++ b/code/modules/mob/living/living_movement.dm
@@ -0,0 +1,27 @@
+/mob/living/Moved()
+ . = ..()
+ update_turf_movespeed(loc)
+
+/mob/living/toggle_move_intent()
+ . = ..()
+ update_move_intent_slowdown()
+
+/mob/living/update_config_movespeed()
+ update_move_intent_slowdown()
+ 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)
+
+/mob/living/proc/update_turf_movespeed(turf/open/T)
+ if(isopenturf(T) && !is_flying())
+ add_movespeed_modifier(MOVESPEED_ID_LIVING_TURF_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = T.slowdown)
+ else
+ remove_movespeed_modifier(MOVESPEED_ID_LIVING_TURF_SPEEDMOD)
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
index 5a4f01a53ca..896d8674bec 100644
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -75,13 +75,7 @@
var/overload_maxhealth = 0
canmove = FALSE
var/silent = FALSE
- var/hit_slowdown = 0
var/brightness_power = 5
- var/slowdown = 0
-
-/mob/living/silicon/pai/movement_delay()
- . = ..()
- . += slowdown
/mob/living/silicon/pai/can_unbuckle()
return FALSE
@@ -266,9 +260,9 @@
/mob/living/silicon/pai/Process_Spacemove(movement_dir = 0)
. = ..()
if(!.)
- slowdown = 2
+ add_movespeed_modifier(MOVESPEED_ID_PAI_SPACEWALK_SPEEDMOD, TRUE, 100, multiplicative_slowdown = 2)
return TRUE
- slowdown = initial(slowdown)
+ remove_movespeed_modifier(MOVESPEED_ID_PAI_SPACEWALK_SPEEDMOD, TRUE)
return TRUE
/mob/living/silicon/pai/examine(mob/user)
@@ -293,7 +287,5 @@
health = maxHealth - getBruteLoss() - getFireLoss()
update_stat()
-
/mob/living/silicon/pai/process()
emitterhealth = CLAMP((emitterhealth + emitterregen), -50, emittermaxhealth)
- hit_slowdown = CLAMP((hit_slowdown - 1), 0, 100)
diff --git a/code/modules/mob/living/silicon/pai/pai_defense.dm b/code/modules/mob/living/silicon/pai/pai_defense.dm
index 417a24cd68d..f20ccbc7309 100644
--- a/code/modules/mob/living/silicon/pai/pai_defense.dm
+++ b/code/modules/mob/living/silicon/pai/pai_defense.dm
@@ -64,7 +64,6 @@
if(emitterhealth < 0)
fold_in(force = TRUE)
to_chat(src, "The impact degrades your holochassis!")
- hit_slowdown += amount
return amount
/mob/living/silicon/pai/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE)
diff --git a/code/modules/mob/living/silicon/pai/pai_shell.dm b/code/modules/mob/living/silicon/pai/pai_shell.dm
index 85f7fe6afcd..99484f395ea 100644
--- a/code/modules/mob/living/silicon/pai/pai_shell.dm
+++ b/code/modules/mob/living/silicon/pai/pai_shell.dm
@@ -103,10 +103,6 @@
set_light(0)
to_chat(src, "You disable your integrated light.")
-/mob/living/silicon/pai/movement_delay()
- . = ..()
- . += 1 //A bit slower than humans, so they're easier to smash
-
/mob/living/silicon/pai/mob_pickup(mob/living/L)
var/obj/item/clothing/head/mob_holder/holder = new(get_turf(src), src, chassis, item_head_icon, item_lh_icon, item_rh_icon)
if(!L.put_in_hands(holder))
diff --git a/code/modules/mob/living/silicon/robot/robot_movement.dm b/code/modules/mob/living/silicon/robot/robot_movement.dm
index a1f0dbf4be6..12ec521ac23 100644
--- a/code/modules/mob/living/silicon/robot/robot_movement.dm
+++ b/code/modules/mob/living/silicon/robot/robot_movement.dm
@@ -3,13 +3,6 @@
return 1
return ..()
-/mob/living/silicon/robot/movement_delay()
- . = ..()
- var/static/config_robot_delay
- if(isnull(config_robot_delay))
- config_robot_delay = CONFIG_GET(number/robot_delay)
- . += speed + config_robot_delay
-
/mob/living/silicon/robot/mob_negates_gravity()
return magpulse
diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm
index 2affa548c5c..ca4b5defcd6 100644
--- a/code/modules/mob/living/simple_animal/parrot.dm
+++ b/code/modules/mob/living/simple_animal/parrot.dm
@@ -394,6 +394,9 @@
if(!isturf(src.loc) || !canmove || buckled)
return //If it can't move, dont let it move. (The buckled check probably isn't necessary thanks to canmove)
+ if(client && stat == CONSCIOUS && parrot_state != icon_living)
+ icon_state = icon_living
+ //Because the most appropriate place to set icon_state is movement_delay(), clearly
//-----SLEEPING
if(parrot_state == PARROT_PERCH)
@@ -604,12 +607,6 @@
* Procs
*/
-/mob/living/simple_animal/parrot/movement_delay()
- if(client && stat == CONSCIOUS && parrot_state != icon_living)
- icon_state = icon_living
- //Because the most appropriate place to set icon_state is movement_delay(), clearly
- return ..()
-
/mob/living/simple_animal/parrot/proc/isStuck()
//Check to see if the parrot is stuck due to things like windows or doors or windowdoors
if(parrot_lastmove)
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index f267a2af12d..708707c62e2 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -101,6 +101,7 @@
real_name = name
if(!loc)
stack_trace("Simple animal being instantiated in nullspace")
+ update_simplemob_varspeed()
/mob/living/simple_animal/Destroy()
GLOB.simple_animals[AIStatus] -= src
@@ -278,14 +279,14 @@
act = "me"
..(act, m_type, message)
+/mob/living/simple_animal/proc/set_varspeed(var_value)
+ speed = var_value
+ update_simplemob_varspeed()
-
-/mob/living/simple_animal/movement_delay()
- var/static/config_animal_delay
- if(isnull(config_animal_delay))
- config_animal_delay = CONFIG_GET(number/animal_delay)
- . += config_animal_delay
- return ..() + speed + config_animal_delay
+/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)
/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 134a7bde441..034ccc4c399 100644
--- a/code/modules/mob/living/simple_animal/slime/slime.dm
+++ b/code/modules/mob/living/simple_animal/slime/slime.dm
@@ -134,33 +134,37 @@
icon_state = icon_dead
..()
-/mob/living/simple_animal/slime/movement_delay()
- if(bodytemperature >= 330.23) // 135 F or 57.08 C
- return -1 // slimes become supercharged at high temperatures
-
+/mob/living/simple_animal/slime/on_reagent_change()
. = ..()
+ remove_movespeed_modifier(MOVESPEED_ID_SLIME_REAGENTMOD, TRUE)
+ var/amount = 0
+ if(reagents.has_reagent("morphine")) // morphine slows slimes down
+ amount = 2
+ if(reagents.has_reagent("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)
+/mob/living/simple_animal/slime/updatehealth()
+ . = ..()
+ remove_movespeed_modifier(MOVESPEED_ID_SLIME_HEALTHMOD, FALSE)
var/health_deficiency = (100 - health)
+ var/mod = 0
if(health_deficiency >= 45)
- . += (health_deficiency / 25)
+ mod += (health_deficiency / 25)
+ if(health <= 0)
+ mod += 2
+ add_movespeed_modifier(MOVESPEED_ID_SLIME_HEALTHMOD, TRUE, 100, multiplicative_slowdown = mod)
- if(bodytemperature < 183.222)
- . += (283.222 - bodytemperature) / 10 * 1.75
-
- if(reagents)
- if(reagents.has_reagent("morphine")) // morphine slows slimes down
- . *= 2
-
- if(reagents.has_reagent("frostoil")) // Frostoil also makes them move VEEERRYYYYY slow
- . *= 5
-
- if(health <= 0) // if damaged, the slime moves twice as slow
- . *= 2
-
- var/static/config_slime_delay
- if(isnull(config_slime_delay))
- config_slime_delay = CONFIG_GET(number/slime_delay)
- . += config_slime_delay
+/mob/living/simple_animal/slime/adjust_bodytemperature()
+ . = ..()
+ var/mod = 0
+ if(bodytemperature >= 330.23) // 135 F or 57.08 C
+ mod = -1 // slimes become supercharged at high temperatures
+ else if(bodytemperature < 183.222)
+ mod = (283.222 - bodytemperature) / 10 * 1.75
+ if(mod)
+ add_movespeed_modifier(MOVESPEED_ID_SLIME_TEMPMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = mod)
/mob/living/simple_animal/slime/ObjBump(obj/O)
if(!client && powerlevel > 0)
diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm
index 3af0a79762e..be98d1bfabd 100644
--- a/code/modules/mob/living/status_procs.dm
+++ b/code/modules/mob/living/status_procs.dm
@@ -143,9 +143,14 @@
/mob/living/proc/add_trait(trait, source)
if(!status_traits[trait])
status_traits[trait] = list(source)
+ on_add_trait(trait, source)
else
status_traits[trait] |= list(source)
+/mob/living/proc/on_add_trait(trait, source)
+ if(trait == TRAIT_IGNORESLOWDOWN)
+ update_movespeed(FALSE)
+
/mob/living/proc/add_quirk(quirk, spawn_effects) //separate proc due to the way these ones are handled
if(has_trait(quirk))
return
@@ -156,7 +161,6 @@
return TRUE
/mob/living/proc/remove_trait(trait, list/sources, force)
-
if(!status_traits[trait])
return
@@ -165,6 +169,7 @@
if(!sources) // No defined source cures the trait entirely.
status_traits -= trait
+ on_remove_trait(trait, sources, force)
return
if(!islist(sources))
@@ -179,6 +184,11 @@
if(!LAZYLEN(status_traits[trait]))
status_traits -= trait
+ on_remove_trait(trait, sources, force)
+
+/mob/living/proc/on_remove_trait(trait, list/sources, force)
+ if(trait == TRAIT_IGNORESLOWDOWN)
+ update_movespeed(FALSE)
/mob/living/proc/remove_quirk(quirk)
var/datum/quirk/T = roundstart_quirks[quirk]
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index a285b5de424..3d55ff43172 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -35,6 +35,8 @@
AA.onNewMob(src)
nutrition = rand(NUTRITION_LEVEL_START_MIN, NUTRITION_LEVEL_START_MAX)
. = ..()
+ update_config_movespeed()
+ update_movespeed(TRUE)
/mob/GenerateTag()
tag = "mob_[next_mob_id++]"
@@ -173,9 +175,6 @@
for(var/mob/M in get_hearers_in_view(range, src))
M.show_message( message, 2, deaf_message, 1)
-/mob/proc/movement_delay() //update /living/movement_delay() if you change this
- return 0
-
/mob/proc/Life()
set waitfor = FALSE
@@ -317,17 +316,17 @@
set category = "Object"
if(!src || !isturf(src.loc) || !(A in view(src.loc)))
- return 0
+ return FALSE
if(istype(A, /obj/effect/temp_visual/point))
- return 0
+ return FALSE
var/tile = get_turf(A)
if (!tile)
- return 0
+ return FALSE
new /obj/effect/temp_visual/point(A,invisibility)
- return 1
+ return TRUE
/mob/proc/can_resist()
return FALSE //overridden in living.dm
@@ -599,59 +598,61 @@
if(S.chemical_cost >=0 && S.can_be_used_by(src))
statpanel("[S.panel]",((S.chemical_cost > 0) ? "[S.chemical_cost]" : ""),S)
+#define MOB_FACE_DIRECTION_DELAY 1
+
// facing verbs
/mob/proc/canface()
if(!canmove)
- return 0
- if(world.time < client.move_delay)
- return 0
- if(stat==2)
- return 0
+ return FALSE
+ if(world.time < client.last_turn)
+ return FALSE
+ if(stat == DEAD || stat == UNCONSCIOUS)
+ return FALSE
if(anchored)
- return 0
+ return FALSE
if(notransform)
- return 0
+ return FALSE
if(restrained())
- return 0
- return 1
+ return FALSE
+ return TRUE
/mob/proc/fall(forced)
drop_all_held_items()
/mob/verb/eastface()
- set hidden = 1
+ set hidden = TRUE
if(!canface())
- return 0
+ return FALSE
setDir(EAST)
- client.move_delay += movement_delay()
- return 1
+ client.last_turn = world.time + MOB_FACE_DIRECTION_DELAY
+ return TRUE
/mob/verb/westface()
- set hidden = 1
+ set hidden = TRUE
if(!canface())
- return 0
+ return FALSE
setDir(WEST)
- client.move_delay += movement_delay()
- return 1
+ client.last_turn = world.time + MOB_FACE_DIRECTION_DELAY
+ return TRUE
/mob/verb/northface()
- set hidden = 1
+ set hidden = TRUE
if(!canface())
- return 0
+ return FALSE
setDir(NORTH)
- client.move_delay += movement_delay()
- return 1
+ client.last_turn = world.time + MOB_FACE_DIRECTION_DELAY
+ return TRUE
/mob/verb/southface()
- set hidden = 1
+ set hidden = TRUE
if(!canface())
- return 0
+ return FALSE
setDir(SOUTH)
- client.move_delay += movement_delay()
- return 1
+ client.last_turn = world.time + MOB_FACE_DIRECTION_DELAY
+ return TRUE
/mob/proc/IsAdvancedToolUser()//This might need a rename but it should replace the can this mob use things check
- return 0
+ return FALSE
/mob/proc/swap_hand()
return
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 3dff46ec84a..0dbb8f59517 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -14,8 +14,7 @@
var/list/datum/action/chameleon_item_actions
var/static/next_mob_id = 0
- var/stat = 0 //Whether a mob is alive or dead. TODO: Move this to living - Nodrak
-
+ var/stat = CONSCIOUS //Whether a mob is alive or dead. TODO: Move this to living - Nodrak
/*A bunch of this stuff really needs to go under their own defines instead of being globally attached to mob.
A variable should only be globally attached to turfs/objects/whatever, when it is in fact needed as such.
@@ -40,6 +39,11 @@
var/lying_prev = 0
var/canmove = 1
+ //MOVEMENT SPEED
+ var/list/movespeed_modification //Lazy list, see mob_movespeed.dm
+ var/cached_multiplicative_slowdown
+ /////////////////
+
var/name_archive //For admin things like possession
var/bodytemperature = BODYTEMP_NORMAL //310.15K / 98.6F
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index 291ae1e4258..85318be931c 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -10,6 +10,10 @@
return TRUE
return (!mover.density || !density || lying)
+//DO NOT USE THIS UNLESS YOU ABSOLUTELY HAVE TO. THIS IS BEING PHASED OUT FOR THE MOVESPEED MODIFICATION SYSTEM.
+//See mob_movespeed.dm
+/mob/proc/movement_delay() //update /living/movement_delay() if you change this
+ return cached_multiplicative_slowdown
/client/verb/drop_item()
set hidden = 1
@@ -26,7 +30,6 @@
mob.control_object.setDir(direct)
else
mob.control_object.forceMove(get_step(mob.control_object,direct))
- return
#define MOVEMENT_DELAY_BUFFER 0.75
#define MOVEMENT_DELAY_BUFFER_DELTA 1.25
@@ -38,7 +41,7 @@
next_move_dir_add = 0
next_move_dir_sub = 0
var/old_move_delay = move_delay
- move_delay = world.time+world.tick_lag //this is here because Move() can now be called mutiple times per tick
+ move_delay = world.time + world.tick_lag //this is here because Move() can now be called mutiple times per tick
if(!mob || !mob.loc)
return FALSE
if(!n || !direct)
@@ -357,9 +360,13 @@
set hidden = TRUE
set instant = TRUE
if(mob)
- mob.toggle_move_intent()
+ mob.toggle_move_intent(usr)
-/mob/proc/toggle_move_intent()
+/mob/proc/toggle_move_intent(mob/user)
+ if(m_intent == MOVE_INTENT_RUN)
+ m_intent = MOVE_INTENT_WALK
+ else
+ m_intent = MOVE_INTENT_RUN
if(hud_used && hud_used.static_inventory)
for(var/obj/screen/mov_intent/selector in hud_used.static_inventory)
- selector.toggle(src)
+ selector.update_icon(src)
diff --git a/code/modules/mob/mob_movespeed.dm b/code/modules/mob/mob_movespeed.dm
new file mode 100644
index 00000000000..9014592be25
--- /dev/null
+++ b/code/modules/mob/mob_movespeed.dm
@@ -0,0 +1,106 @@
+
+/*Current movespeed modification list format: list(id = list(
+ priority,
+ legacy slowdown/speedup amount,
+ ))
+*/
+
+//ANY ADD/REMOVE DONE IN UPDATE_MOVESPEED MUST HAVE THE UPDATE ARGUMENT SET AS FALSE!
+/mob/proc/add_movespeed_modifier(id, update = TRUE, priority = 0, flags = NONE, override = FALSE, multiplicative_slowdown = 0)
+ var/list/temp = list(priority, flags, multiplicative_slowdown) //build the modification list
+ if(LAZYACCESS(movespeed_modification, id))
+ if(movespeed_modifier_identical_check(movespeed_modification[id], temp))
+ return FALSE
+ if(!override)
+ return FALSE
+ else
+ remove_movespeed_modifier(id, update)
+ LAZYSET(movespeed_modification, id, list(priority, flags, multiplicative_slowdown))
+ if(update)
+ update_movespeed(TRUE)
+ return TRUE
+
+/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
+
+/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)
+
+/mob/proc/has_movespeed_modifier(id)
+ return LAZYACCESS(movespeed_modification, id)
+
+/mob/proc/update_config_movespeed()
+ add_movespeed_modifier(MOVESPEED_ID_CONFIG_SPEEDMOD, FALSE, 100, override = TRUE, multiplicative_slowdown = get_config_multiplicative_speed())
+
+/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]
+
+/mob/proc/update_movespeed(resort = TRUE)
+ if(resort)
+ sort_movespeed_modlist()
+ . = 0
+ for(var/id in get_movespeed_modifiers())
+ var/list/data = movespeed_modification[id]
+ . += data[MOVESPEED_DATA_INDEX_MULTIPLICATIVE_SLOWDOWN]
+ cached_multiplicative_slowdown = .
+
+/mob/proc/get_movespeed_modifiers()
+ return movespeed_modification
+
+/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
+
+/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]
+
+/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
+
+/mob/proc/sort_movespeed_modlist() //Verifies it too. Sorts highest priority (first applied) to lowest priority (last applied)
+ 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)
\ No newline at end of file
diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm
index 1d430aaafc7..b14d14d9060 100644
--- a/code/modules/projectiles/projectile/magic.dm
+++ b/code/modules/projectiles/projectile/magic.dm
@@ -244,7 +244,7 @@
to_chat(new_mob, "Your form morphs into that of a [randomize].")
- var/poly_msg = CONFIG_GET(keyed_string_list/policy)["polymorph"]
+ var/poly_msg = CONFIG_GET(keyed_list/policy)["polymorph"]
if(poly_msg)
to_chat(new_mob, poly_msg)
diff --git a/config/game_options.txt b/config/game_options.txt
index 2387c0dfef4..e6b805e0ba7 100644
--- a/config/game_options.txt
+++ b/config/game_options.txt
@@ -37,13 +37,16 @@ EMOJIS
RUN_DELAY 1
WALK_DELAY 4
-## The variables below affect the movement of specific mob types.
-HUMAN_DELAY 0
-ROBOT_DELAY 0
-MONKEY_DELAY 0
-ALIEN_DELAY 0
-SLIME_DELAY 0
-ANIMAL_DELAY 1
+## The variables below affect the movement of specific mob types. THIS AFFECTS ALL SUBTYPES OF THE TYPE YOU CHOOSE!
+## Entries completely override all subtypes. Later entries have precedence over earlier entries.
+## This means if you put /mob 0 on the last entry, it will null out all changes, while if you put /mob as the first entry and
+## /mob/living/carbon/human on the last entry, the last entry will override the first.
+##MULTIPLICATIVE_MOVESPEED /mob/living/carbon/human 0
+##MULTIPLICATIVE_MOVESPEED /mob/living/silicon/robot 0
+##MULTIPLICATIVE_MOVESPEED /mob/living/carbon/monkey 0
+##MULTIPLICATIVE_MOVESPEED /mob/living/carbon/alien 0
+##MULTIPLICATIVE_MOVESPEED /mob/living/simple_animal/slime 0
+MULTIPLICATIVE_MOVESPEED /mob/living/simple_animal 1
## NAMES ###
diff --git a/tgstation.dme b/tgstation.dme
index 9c98d54cbb0..2d3b0851ad7 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -62,6 +62,7 @@
#include "code\__DEFINES\misc.dm"
#include "code\__DEFINES\mobs.dm"
#include "code\__DEFINES\monkeys.dm"
+#include "code\__DEFINES\movespeed_modification.dm"
#include "code\__DEFINES\networks.dm"
#include "code\__DEFINES\obj_flags.dm"
#include "code\__DEFINES\pinpointers.dm"
@@ -1791,6 +1792,7 @@
#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"
@@ -1819,6 +1821,7 @@
#include "code\modules\mob\living\living.dm"
#include "code\modules\mob\living\living_defense.dm"
#include "code\modules\mob\living\living_defines.dm"
+#include "code\modules\mob\living\living_movement.dm"
#include "code\modules\mob\living\login.dm"
#include "code\modules\mob\living\logout.dm"
#include "code\modules\mob\living\say.dm"