Skip to content

Commit

Permalink
Adds an option to generate typecaches as zebras, a TG mirror (#1720)
Browse files Browse the repository at this point in the history
* Adds an option to generate typecaches as zebras. (#63710)

About The Pull Request

Adds an argument to typecache generation that allows specifying the whether to include/exclude types in the input list.
Also adds another argument to specify whether to remove falsey values after the typecache is generated.
Why It's Good For The Game

Might make zaps slightly faster???
Honestly I just thought it would be a good way to condense some whitelist/blacklist typecache sets.

* whoop

* dont ya just love accidentally deleting stuff?

* CALM DOWN SIR, FOR GODS SAKES

---------

Co-authored-by: TemporalOroboros <[email protected]>
  • Loading branch information
Gboster-0 and TemporalOroboros authored Dec 13, 2023
1 parent 61e0f56 commit 6309831
Show file tree
Hide file tree
Showing 43 changed files with 554 additions and 347 deletions.
165 changes: 133 additions & 32 deletions code/__HELPERS/_lists.dm
Original file line number Diff line number Diff line change
Expand Up @@ -90,16 +90,49 @@

return "[output][and_text][input[index]]"

//Checks for specific types in a list
/proc/is_type_in_list(atom/A, list/L)
if(!LAZYLEN(L) || !A)
/**
* Checks for specific types in a list.
*
* If using zebra mode the list should be an assoc list with truthy/falsey values.
* The check short circuits so earlier entries in the input list will take priority.
* Ergo, subtypes should come before parent types.
* Notice that this is the opposite priority of [/proc/typecacheof].
*
* Arguments:
* - [type_to_check][/datum]: An instance to check.
* - [list_to_check][/list]: A list of typepaths to check the type_to_check against.
* - zebra: Whether to use the value of the mathing type in the list instead of just returning true when a match is found.
*/
/proc/is_type_in_list(datum/type_to_check, list/list_to_check, zebra = FALSE)
if(!LAZYLEN(list_to_check) || !type_to_check)
return FALSE
for(var/type in list_to_check)
if(istype(type_to_check, type))
return !zebra || list_to_check[type] // Subtypes must come first in zebra lists.
return FALSE

/**
* Checks for specific paths in a list.
*
* If using zebra mode the list should be an assoc list with truthy/falsey values.
* The check short circuits so earlier entries in the input list will take priority.
* Ergo, subpaths should come before parent paths.
* Notice that this is the opposite priority of [/proc/typecacheof].
*
* Arguments:
* - path_to_check: A typepath to check.
* - [list_to_check][/list]: A list of typepaths to check the path_to_check against.
* - zebra: Whether to use the value of the mathing path in the list instead of just returning true when a match is found.
*/
/proc/is_path_in_list(path_to_check, list/list_to_check, zebra = FALSE)
if(!LAZYLEN(list_to_check) || !path_to_check)
return FALSE
for(var/type in L)
if(istype(A, type))
return TRUE
for(var/path in list_to_check)
if(ispath(path_to_check, path))
return !zebra || list_to_check[path]
return FALSE

//Checks for specific types in specifically structured (Assoc "type" = TRUE) lists ('typecaches')
///Checks for specific types in specifically structured (Assoc "type" = TRUE|FALSE) lists ('typecaches')
#define is_type_in_typecache(A, L) (A && length(L) && L[(ispath(A) ? A : A:type)])

//returns a new list with only atoms that are in typecache L
Expand All @@ -126,33 +159,101 @@
if(typecache_include[A.type] && !typecache_exclude[A.type])
. += A

//Like typesof() or subtypesof(), but returns a typecache instead of a list
/proc/typecacheof(path, ignore_root_path, only_root_path = FALSE)
/**
* Like typesof() or subtypesof(), but returns a typecache instead of a list.
*
* Arguments:
* - path: A typepath or list of typepaths.
* - only_root_path: Whether the typecache should be specifically of the passed types.
* - ignore_root_path: Whether to ignore the root path when caching subtypes.
*/
/proc/typecacheof(path, only_root_path = FALSE, ignore_root_path = FALSE)
if(isnull(path))
return

if(ispath(path))
var/list/types = list()
. = list()
if(only_root_path)
types = list(path)
else
types = ignore_root_path ? subtypesof(path) : typesof(path)
var/list/L = list()
for(var/T in types)
L[T] = TRUE
return L
else if(islist(path))
var/list/pathlist = path
var/list/L = list()
if(ignore_root_path)
for(var/P in pathlist)
for(var/T in subtypesof(P))
L[T] = TRUE
else
for(var/P in pathlist)
if(only_root_path)
L[P] = TRUE
else
for(var/T in typesof(P))
L[T] = TRUE
return L
.[path] = TRUE
return

for(var/subtype in (ignore_root_path ? subtypesof(path) : typesof(path)))
.[subtype] = TRUE
return

if(!islist(path))
CRASH("Tried to create a typecache of [path] which is neither a typepath nor a list.")

. = list()
var/list/pathlist = path
if(only_root_path)
for(var/current_path in pathlist)
.[current_path] = TRUE
else if(ignore_root_path)
for(var/current_path in pathlist)
for(var/subtype in subtypesof(current_path))
.[subtype] = TRUE
else
for(var/current_path in pathlist)
for(var/subpath in typesof(current_path))
.[subpath] = TRUE

/**
* Like typesof() or subtypesof(), but returns a typecache instead of a list.
* This time it also uses the associated values given by the input list for the values of the subtypes.
*
* Latter values from the input list override earlier values.
* Thus subtypes should come _after_ parent types in the input list.
* Notice that this is the opposite priority of [/proc/is_type_in_list] and [/proc/is_path_in_list].
*
* Arguments:
* - path: A typepath or list of typepaths with associated values.
* - single_value: The assoc value used if only a single path is passed as the first variable.
* - only_root_path: Whether the typecache should be specifically of the passed types.
* - ignore_root_path: Whether to ignore the root path when caching subtypes.
* - clear_nulls: Whether to remove keys with null assoc values from the typecache after generating it.
*/
/proc/zebra_typecacheof(path, single_value = TRUE, only_root_path = FALSE, ignore_root_path = FALSE, clear_nulls = FALSE)
if(isnull(path))
return

if(ispath(path))
if (isnull(single_value))
return

. = list()
if(only_root_path)
.[path] = single_value
return

for(var/subtype in (ignore_root_path ? subtypesof(path) : typesof(path)))
.[subtype] = single_value
return

if(!islist(path))
CRASH("Tried to create a typecache of [path] which is neither a typepath nor a list.")

. = list()
var/list/pathlist = path
if(only_root_path)
for(var/current_path in pathlist)
.[current_path] = pathlist[current_path]
else if(ignore_root_path)
for(var/current_path in pathlist)
for(var/subtype in subtypesof(current_path))
.[subtype] = pathlist[current_path]
else
for(var/current_path in pathlist)
for(var/subpath in typesof(current_path))
.[subpath] = pathlist[current_path]

if(!clear_nulls)
return

for(var/cached_path in .)
if (isnull(.[cached_path]))
. -= cached_path


//Removes any null entries from the list
//Returns TRUE if the list had nulls, FALSE otherwise
Expand Down
6 changes: 4 additions & 2 deletions code/datums/components/chasm.dm
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@
/obj/effect/light_emitter/tendril,
/obj/effect/collapse,
/obj/effect/particle_effect/ion_trails,
/obj/effect/dummy/phased_mob
))
/obj/effect/dummy/phased_mob,
/obj/effect/mapping_helpers,
/obj/effect/wisp,
))

/datum/component/chasm/Initialize(turf/target)
RegisterSignal(parent, list(COMSIG_MOVABLE_CROSSED, COMSIG_ATOM_ENTERED), .proc/Entered)
Expand Down
44 changes: 21 additions & 23 deletions code/datums/components/fantasy/suffixes.dm
Original file line number Diff line number Diff line change
Expand Up @@ -56,19 +56,18 @@
var/static/list/possible_mobtypes
if(!possible_mobtypes)
// The base list of allowed mob/species types
possible_mobtypes = typecacheof(list(
/mob/living/simple_animal,
/mob/living/carbon,
/datum/species,
))
possible_mobtypes = zebra_typecacheof(list(
/mob/living/simple_animal = TRUE,
/mob/living/carbon = TRUE,
/datum/species = TRUE,
// Some types to remove them and their subtypes
/mob/living/carbon/human/species = FALSE,
))
// Some particular types to disallow if they're too broad/abstract
// Not in the above typecache generator because it includes subtypes and this doesn't.
possible_mobtypes -= list(
/mob/living/simple_animal/hostile,
)
// Some types to remove them and their subtypes
possible_mobtypes -= typecacheof(list(
/mob/living/carbon/human/species,
))
)

var/mob/picked_mobtype = pick(possible_mobtypes)
// This works even with the species picks since we're only accessing the name
Expand All @@ -88,22 +87,21 @@
var/static/list/possible_mobtypes
if(!possible_mobtypes)
// The base list of allowed mob/species types
possible_mobtypes = typecacheof(list(
/mob/living/simple_animal,
/mob/living/carbon,
/datum/species,
))
possible_mobtypes = zebra_typecacheof(list(
/mob/living/simple_animal = TRUE,
/mob/living/carbon = TRUE,
/datum/species = TRUE,
// Some types to remove them and their subtypes
/mob/living/carbon/human/species = FALSE,
/mob/living/simple_animal/hostile/syndicate/mecha_pilot = FALSE,
/mob/living/simple_animal/hostile/asteroid/elite = FALSE,
/mob/living/simple_animal/hostile/megafauna = FALSE,
))
// Some particular types to disallow if they're too broad/abstract
// Not in the above typecache generator because it includes subtypes and this doesn't.
possible_mobtypes -= list(
/mob/living/simple_animal/hostile,
)
// Some types to remove them and their subtypes
possible_mobtypes -= typecacheof(list(
/mob/living/carbon/human/species,
/mob/living/simple_animal/hostile/syndicate/mecha_pilot,
/mob/living/simple_animal/hostile/asteroid/elite,
/mob/living/simple_animal/hostile/megafauna,
))
)

var/mob/picked_mobtype = pick(possible_mobtypes)
// This works even with the species picks since we're only accessing the name
Expand Down
9 changes: 6 additions & 3 deletions code/datums/components/storage/concrete/pockets.dm
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@
/datum/component/storage/concrete/pockets/small/fedora/Initialize()
. = ..()
var/static/list/exception_cache = typecacheof(list(
/obj/item/katana, /obj/item/toy/katana, /obj/item/nullrod/claymore/katana,
/obj/item/energy_katana, /obj/item/gun/ballistic/automatic/tommygun
))
/obj/item/katana,
/obj/item/toy/katana,
/obj/item/nullrod/claymore/katana,
/obj/item/energy_katana,
/obj/item/gun/ballistic/automatic/tommygun,
))
exception_hold = exception_cache

/datum/component/storage/concrete/pockets/small/fedora/detective
Expand Down
18 changes: 9 additions & 9 deletions code/datums/components/thermite.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@
/turf/open/lava,
/turf/open/space,
/turf/open/water,
/turf/open/chasm)
)

/turf/open/chasm,
))
///List of turfs that are immune to thermite
var/static/list/immunelist = typecacheof(list(
/turf/closed/wall/mineral/diamond,
/turf/closed/indestructible,
/turf/open/indestructible)
)

var/static/list/resistlist = typecacheof(
/turf/closed/wall/r_wall
)
/turf/open/indestructible,
))
///List of turfs that take extra thermite to burn through
var/static/list/resistlist = typecacheof(list(
/turf/closed/wall/r_wall,
))

/datum/component/thermite/Initialize(_amount)
if(!istype(parent, /turf) || blacklist[parent.type])
Expand Down
18 changes: 8 additions & 10 deletions code/datums/emotes.dm
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,14 @@
var/cooldown = 0.8 SECONDS

/datum/emote/New()
if (ispath(mob_type_allowed_typecache))
switch (mob_type_allowed_typecache)
if (/mob)
mob_type_allowed_typecache = GLOB.typecache_mob
if (/mob/living)
mob_type_allowed_typecache = GLOB.typecache_living
else
mob_type_allowed_typecache = typecacheof(mob_type_allowed_typecache)
else
mob_type_allowed_typecache = typecacheof(mob_type_allowed_typecache)
switch(mob_type_allowed_typecache)
if(/mob)
mob_type_allowed_typecache = GLOB.typecache_mob
if(/mob/living)
mob_type_allowed_typecache = GLOB.typecache_living
else
mob_type_allowed_typecache = typecacheof(mob_type_allowed_typecache)

mob_type_blacklist_typecache = typecacheof(mob_type_blacklist_typecache)
mob_type_ignore_stat_typecache = typecacheof(mob_type_ignore_stat_typecache)

Expand Down
15 changes: 7 additions & 8 deletions code/datums/helper_datums/teleport.dm
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,13 @@
// forced: whether or not to ignore no_teleport
/proc/do_teleport(atom/movable/teleatom, atom/destination, precision=null, forceMove = TRUE, datum/effect_system/effectin=null, datum/effect_system/effectout=null, asoundin=null, asoundout=null, no_effects=FALSE, channel=TELEPORT_CHANNEL_BLUESPACE, forced = FALSE)
// teleporting most effects just deletes them
var/static/list/delete_atoms = typecacheof(list(
/obj/effect,
)) - typecacheof(list(
/obj/effect/dummy/chameleon,
/obj/effect/wisp,
/obj/effect/mob_spawn,
/obj/effect/immovablerod,
))
var/static/list/delete_atoms = zebra_typecacheof(list(
/obj/effect = TRUE,
/obj/effect/dummy/chameleon = FALSE,
/obj/effect/wisp = FALSE,
/obj/effect/mob_spawn = FALSE,
/obj/effect/immovablerod = FALSE,
))
if(delete_atoms[teleatom.type])
qdel(teleatom)
return FALSE
Expand Down
2 changes: 1 addition & 1 deletion code/datums/mutations/holy_mutation/honorbound.dm
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@
/obj/projectile/beam,
/obj/projectile/bullet,
/obj/projectile/magic,
))
))
if(!is_type_in_typecache(proj, guilty_projectiles))
return
if((proj.damage_type == STAMINA))
Expand Down
3 changes: 2 additions & 1 deletion code/game/machinery/gulag_teleporter.dm
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ The console is located at computer/gulag_teleporter.dm
/obj/item/clothing/gloves/color/plasmaman,
/obj/item/tank/internals,
/obj/item/clothing/mask/breath,
/obj/item/clothing/mask/gas))
/obj/item/clothing/mask/gas,
))

/obj/machinery/gulag_teleporter/Initialize()
. = ..()
Expand Down
12 changes: 8 additions & 4 deletions code/game/machinery/iv_drip.dm
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@
var/mob/living/carbon/attached
var/mode = IV_INJECTING
var/dripfeed = FALSE
///Internal beaker
var/obj/item/reagent_containers/beaker
var/static/list/drip_containers = typecacheof(list(/obj/item/reagent_containers/blood,
/obj/item/reagent_containers/food,
/obj/item/reagent_containers/glass,
/obj/item/reagent_containers/chem_pack))
///Typecache of containers we accept
var/static/list/drip_containers = typecacheof(list(
/obj/item/reagent_containers/blood,
/obj/item/reagent_containers/food,
/obj/item/reagent_containers/glass,
/obj/item/reagent_containers/chem_pack,
))

/obj/machinery/iv_drip/Initialize(mapload)
. = ..()
Expand Down
Loading

0 comments on commit 6309831

Please sign in to comment.