mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-06 15:02:29 +00:00
Reverts #47817 People are complaining about motion sickness and I don't know what the issue is.
167 lines
6.6 KiB
Plaintext
167 lines
6.6 KiB
Plaintext
/*! 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)
|