move stuff

This commit is contained in:
kevinz000
2020-01-10 07:27:44 -08:00
parent bb95b2a870
commit 46451e23ea
11 changed files with 240 additions and 231 deletions
-5
View File
@@ -39,8 +39,3 @@
var/mob/living/carbon/human/H = L
H.physiology.damage_resistance += 100
..()
/datum/movespeed_modifier/shrink_ray
id = MOVESPEED_ID_SHRINK_RAY
movetypes = GROUNd
multiplicative_slowdown = 4
-5
View File
@@ -29,8 +29,3 @@
if(istype(OT))
OT.MakeSlippery(TURF_WET_LUBE, 20)
return TRUE
/datum/movespeed_modifier/snail_crawl
id = MOVESPEED_ID_SNAIL_CRAWL
multiplicative_slowdown = -7
movetypes = GROUnD
@@ -51,8 +51,3 @@
while(!active && stacks) //Damage stacks decrease fairly rapidly while not in sanic mode
stacks--
sleep(20)
/datum/movespeed_modifier/strained_muscles
id = MOVESPEED_ID_CHANGELING_MUSCLES
multiplicative_slowdown = -1
blacklisted_movetypes = (FLYING|FLOATING)
@@ -1,202 +1,202 @@
/*! 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!
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_modification(modtype)
if(!ispath(modtype, /datum/movespeed_modifier))
CRASH("[modtype] is not a movespeed modification type.")
var/datum/movespeed_modifier/M = GLOB.movespeed_modification_cache[modtype] || ((GLOB.movespeed_modification_cache[modtype] = new modtype))
return M
///Add a move speed modifier to a mob
/mob/proc/_REFACTORING_add_movespeed_modifier(datum/movespeed_modification/type_or_datum, update = TRUE, override = FALSE)
if(ispath(type_or_datum))
type_or_datum = get_cached_movespeed_modification(type_or_datum)
if(!istype(type_or_datum))
CRASH("Invalid modification datum")
var/oldpriority
var/datum/movespeed_modifier/existing = LAZYACCESS(movespeed_modification, type_or_datum.id)
if(existing)
if(existing == type_or_datum) //same thing don't need to touch
return TRUE
if(!override) //not overriding, do not overwrite same ID.
return FALSE
oldpriority = existing.priority
remove_movespeed_modifier(existing, FLASE)
LAZYSET(movespeed_modification, type_or_datum.id, type_or_datum)
var/resort = type_or_datum.priority == oldpriority
if(update)
update_movespeed(resort)
return TRUE
///Remove a move speed modifier from a mob
/mob/proc/_REFACTORING_remove_movespeed_modifier(datum/movespeed_modification/type_id_datum, update = TRUE)
if(ispath(type_id_datum))
type_id_datum = get_cached_movespeed_modification(type_id_datum)
if(istype(type_id_datum))
type_id_datum = type_id_datum.id
if(!LAZYACCESS(movespeed_modification, type_id_datum))
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(datum/movespeed_modifier/datum_type_id)
if(ispath(datum_type_id))
datum_type_id = get_cached_movespeed_modification(datum_type_id)
if(istype(datum_type_id))
datum_type_id = datum_type_id.id
return LAZYACCESS(movespeed_modification, datum_type_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
///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)
/**
* Movespeed modification datums.
*/
/datum/movespeed_modifier
/// Unique ID. You can never have different modifications with the same ID
var/id = "ERROR"
/// 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
/**
* Movespeed modification datums.
*/
/datum/movespeed_modifier
/// Unique ID. You can never have different modifications with the same ID
var/id = "ERROR"
/// 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
/*! 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!
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_modification(modtype)
if(!ispath(modtype, /datum/movespeed_modifier))
CRASH("[modtype] is not a movespeed modification type.")
var/datum/movespeed_modifier/M = GLOB.movespeed_modification_cache[modtype] || ((GLOB.movespeed_modification_cache[modtype] = new modtype))
return M
///Add a move speed modifier to a mob
/mob/proc/_REFACTORING_add_movespeed_modifier(datum/movespeed_modifier/type_or_datum, update = TRUE, override = FALSE)
if(ispath(type_or_datum))
type_or_datum = get_cached_movespeed_modification(type_or_datum)
if(!istype(type_or_datum))
CRASH("Invalid modification datum")
var/oldpriority
var/datum/movespeed_modifier/existing = LAZYACCESS(movespeed_modification, type_or_datum.id)
if(existing)
if(existing == type_or_datum) //same thing don't need to touch
return TRUE
if(!override) //not overriding, do not overwrite same ID.
return FALSE
oldpriority = existing.priority
remove_movespeed_modifier(existing, FLASE)
LAZYSET(movespeed_modification, type_or_datum.id, type_or_datum)
var/resort = type_or_datum.priority == oldpriority
if(update)
update_movespeed(resort)
return TRUE
///Remove a move speed modifier from a mob
/mob/proc/_REFACTORING_remove_movespeed_modifier(datum/movespeed_modifier/type_id_datum, update = TRUE)
if(ispath(type_id_datum))
type_id_datum = get_cached_movespeed_modification(type_id_datum)
if(istype(type_id_datum))
type_id_datum = type_id_datum.id
if(!LAZYACCESS(movespeed_modification, type_id_datum))
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(datum/movespeed_modifier/datum_type_id)
if(ispath(datum_type_id))
datum_type_id = get_cached_movespeed_modification(datum_type_id)
if(istype(datum_type_id))
datum_type_id = datum_type_id.id
return LAZYACCESS(movespeed_modification, datum_type_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
///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)
@@ -0,0 +1,9 @@
/datum/movespeed_modifier/shrink_ray
id = MOVESPEED_ID_SHRINK_RAY
movetypes = GROUND
multiplicative_slowdown = 4
/datum/movespeed_modifier/snail_crawl
id = MOVESPEED_ID_SNAIL_CRAWL
multiplicative_slowdown = -7
movetypes = GROUND
@@ -0,0 +1,4 @@
/datum/movespeed_modifier/strained_muscles
id = MOVESPEED_ID_CHANGELING_MUSCLES
multiplicative_slowdown = -1
blacklisted_movetypes = (FLYING|FLOATING)
@@ -0,0 +1,9 @@
/datum/movespeed_modifier/reagent/stimulants
id = "stimulants_reagent"
multiplicative_slowdown = -1
blacklisted_movetypes = (FLYING|FLOATING)
/datum/movespeed_modifier/reagent/ephedrine
id = "ephedrine_reagent"
multiplicative_slowdown = -0.5
blacklisted_movetypes = (FLYING|FLOATING)
@@ -0,0 +1,7 @@
/datum/movespeed_modifier/bloodchill
id = "bloodchilled"
multiplicative_slowdown = 3
/datum/movespeed_modifier/bonechill
id = "bonechilled"
multiplicative_slowdown = 3
@@ -422,11 +422,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._REFACTORING_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._REFACTORING_remove_movespeed_modifier(/datum/movespeed_modifier/reagent/ephedrine)
REMOVE_TRAIT(L, TRAIT_STUNRESISTANCE, type)
..()
@@ -806,11 +806,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._REFACTORING_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._REFACTORING_remove_movespeed_modifier(/datum/movespeed_modifier/reagent/stimulants)
REMOVE_TRAIT(L, TRAIT_STUNRESISTANCE, type)
..()
@@ -195,10 +195,6 @@
/datum/status_effect/bloodchill/on_remove()
owner._REFACTORING_remove_movespeed_modifier(/datum/movespeed_modifier/bloodchill)
/datum/movespeed_modifier/bloodchill
id = "bloodchilled"
multiplicative_slowdown = 3
/datum/status_effect/bonechill
id = "bonechill"
duration = 80
@@ -216,11 +212,6 @@
/datum/status_effect/bonechill/on_remove()
owner._REFACTORING_remove_movespeed_modifier(/datum/movespeed_modifier/bonechill)
/datum/movespeed_modifier/bonechill
id = "bonechilled"
multiplicative_slowdown = 3
/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!"
+5 -1
View File
@@ -2022,7 +2022,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"
@@ -2379,6 +2378,11 @@
#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\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"