Refactors faction lists to use getters and setters and be cached (#94490)

This commit is contained in:
Bloop
2026-01-19 04:12:35 +01:00
committed by GitHub
parent 8a8e9f7c88
commit 68153c2333
158 changed files with 757 additions and 393 deletions
@@ -53,7 +53,7 @@
visible_message(span_warning("The corpse of [target.name] suddenly rises!"))
var/mob/living/basic/blob_minion/zombie/blombie = change_mob_type(zombie_type, loc, new_name = initial(zombie_type.name))
blombie.pass_flags |= PASSBLOB //No way to pass the blob_borne info through change_mob_type() to Initilize(), so we just circumvent it here.
blombie.faction |= faction //inherit the spore's faction in case it was spawned with a different one (eg gold core)
APPLY_FACTION_AND_ALLIES_FROM(blombie, src) //inherit the spore's faction in case it was spawned with a different one (eg gold core)
blombie.set_name()
if (istype(blombie)) // In case of badmin
blombie.consume_corpse(target)
+9 -2
View File
@@ -102,6 +102,10 @@ GLOBAL_LIST_INIT(command_strings, list(
)
///name of the UI we will attempt to open
var/bot_ui = "SimpleBot"
// The faction of the bot before it inherited the pai's faction
var/list/original_faction
// The allies of the bot before it inherited the pai's faction
var/list/original_allies
/// If true we will offer this
COOLDOWN_DECLARE(offer_ghosts_cooldown)
@@ -706,7 +710,9 @@ GLOBAL_LIST_INIT(command_strings, list(
paicard.pai.mind.transfer_to(src)
to_chat(src, span_notice("You sense your form change as you are uploaded into [src]."))
name = paicard.pai.name
faction = user.faction.Copy()
original_faction = get_faction()
original_allies = allies
SET_FACTION_AND_ALLIES_FROM(src, user)
log_combat(user, paicard.pai, "uploaded to [initial(src.name)],")
return TRUE
@@ -737,7 +743,8 @@ GLOBAL_LIST_INIT(command_strings, list(
to_chat(paicard.pai, span_notice("You feel your control fade as [paicard] ejects from [initial(name)]."))
paicard = null
name = initial(name)
faction = initial(faction)
set_faction(original_faction)
set_allies(original_allies)
remove_all_languages(source = LANGUAGE_PAI)
get_selected_language()
@@ -185,7 +185,7 @@
continue
if(!HAS_TRAIT(human_target, TRAIT_CLEANBOT_WHISPERER))
continue
if((living_pawn.faction.Find(REF(human_target))))
if(living_pawn.has_ally(REF(human_target)))
continue
return human_target
return null
+1 -1
View File
@@ -109,7 +109,7 @@
/datum/action/cooldown/mob_cooldown/exenterate/proc/slash_em(atom/caster)
for(var/mob/living/victim in range(ability_range, caster))
if(faction_check(victim.faction, immune_factions) && victim.IsReachableBy(owner))
if(victim.has_faction(immune_factions) && victim.IsReachableBy(owner))
continue
to_chat(caster, span_warning("You slice [victim]!"))
to_chat(victim, span_warning("You are cut by [caster]'s blades!"))
@@ -53,7 +53,7 @@
/mob/living/basic/vatbeast/tamed(mob/living/tamer, obj/item/food)
buckle_lying = 0
AddElement(/datum/element/ridable, /datum/component/riding/creature/vatbeast)
faction = list(FACTION_NEUTRAL)
set_faction(list(FACTION_NEUTRAL))
/mob/living/basic/vatbeast/proc/add_cell_sample()
AddElement(/datum/element/swabable, CELL_LINE_TABLE_VATBEAST, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
@@ -37,7 +37,7 @@
/mob/living/basic/cow/moonicorn/tamed(mob/living/tamer, atom/food)
. = ..()
///stop killing my FRIENDS
faction |= tamer.faction
APPLY_FACTION_AND_ALLIES_FROM(src, tamer)
/datum/ai_controller/basic_controller/cow/moonicorn
blackboard = list(
@@ -15,7 +15,6 @@
mob_biotypes = MOB_SPECIAL
sentience_type = SENTIENCE_HUMANOID
hud_type = /datum/hud/guardian
faction = list()
speed = 0
status_flags = CANPUSH
maxHealth = INFINITY // The spirit itself is invincible and passes damage to its host
@@ -225,8 +224,9 @@
if (mind)
mind.enslave_mind_to_creator(to_who)
else //mindless guardian, manually give them factions
faction += summoner.faction
summoner.faction += "[REF(src)]"
add_faction(summoner.get_faction())
add_ally(summoner.allies)
summoner.add_ally(src)
remove_all_languages(LANGUAGE_MASTER)
copy_languages(to_who, LANGUAGE_MASTER) // make sure holoparasites speak same language as master
RegisterSignal(to_who, COMSIG_QDELETING, PROC_REF(on_summoner_deletion))
@@ -251,8 +251,8 @@
unleash()
UnregisterSignal(summoner, list(COMSIG_QDELETING, COMSIG_LIVING_ON_WABBAJACKED, COMSIG_LIVING_SHAPESHIFTED, COMSIG_LIVING_UNSHAPESHIFTED))
if (different_person)
summoner.faction -= "[REF(src)]"
faction -= summoner.faction
summoner.remove_ally(src)
remove_faction(summoner.get_faction())
mind?.remove_all_antag_datums()
if (!length(summoner.get_all_linked_holoparasites() - src))
for (var/action_type in control_actions)
@@ -83,5 +83,5 @@
. = ..()
if(isnull(.))
return
faction = new_friend.faction.Copy()
SET_FACTION_AND_ALLIES_FROM(src, new_friend)
visible_message(span_notice("[src] lowers [src.p_their()] snout at [new_friend]'s offering and begins to wag [src.p_their()] tail."))
@@ -50,9 +50,11 @@
try_replicate()
/// Full setup for illusion mobs to lessen code duplication in the individual files.
/mob/living/basic/illusion/proc/full_setup(mob/living/original, mob/living/target_mob = null, list/faction = null, life = 5 SECONDS, hp = 100, damage = 0, replicate = 0)
/mob/living/basic/illusion/proc/full_setup(mob/living/original, mob/living/target_mob = null, list/faction_override = null, life = 5 SECONDS, hp = 100, damage = 0, replicate = 0)
mock_as(original, life, hp, damage, replicate)
set_faction(faction)
SET_FACTION_AND_ALLIES_FROM(src, original)
if(faction_override)
set_faction(faction_override)
set_target(target_mob)
/// Gives the illusion a target to focus on in whatever behavior it wants to engage as.
@@ -61,12 +63,6 @@
return
ai_controller.set_blackboard_key(target_key, target_mob)
/// Sets the faction of the illusion
/mob/living/basic/illusion/proc/set_faction(list/new_faction)
if(!new_faction) // can be list with no length or null
return
faction = new_faction.Copy()
/// Does the actual work of setting up the illusion's appearance and some other functionality.
/mob/living/basic/illusion/proc/mock_as(mob/living/original, life, hp, damage, replicate)
if(QDELETED(original))
@@ -83,7 +79,7 @@
melee_damage_upper = damage
multiply_chance = replicate
faction -= FACTION_NEUTRAL
remove_faction(FACTION_NEUTRAL)
transform = initial(transform)
pixel_x = base_pixel_x
pixel_y = base_pixel_y
@@ -104,7 +100,7 @@
new_clone.full_setup(
parent_mob,
target_mob = ai_controller.blackboard[target_key],
faction = faction,
faction_override = faction,
life = 8 SECONDS,
hp = health / 2,
damage = melee_damage_upper,
@@ -247,4 +247,4 @@
/datum/action/cooldown/spell/conjure/limit_summons/create_suicide_toads/post_summon(atom/summoned_object, atom/cast_on)
. = ..()
var/mob/living/summoned_toad = summoned_object
summoned_toad.faction = owner.faction ///so they dont attack the leaper or the wizard master
SET_FACTION_AND_ALLIES_FROM(summoned_toad, owner) // so they dont attack the leaper or the wizard master
@@ -16,7 +16,7 @@
return ..()
var/mob/living/living_target = target
if(FACTION_JUNGLE in living_target.faction)
if(living_target.has_faction(FACTION_JUNGLE))
return BULLET_ACT_BLOCK
return ..()
@@ -159,7 +159,7 @@
. = ..()
if(isnull(.))
return
faction = new_friend.faction.Copy()
SET_FACTION_AND_ALLIES_FROM(src, new_friend)
/mob/living/basic/mining/goliath/RangedAttack(atom/atom_target, modifiers)
tentacles?.Trigger(target = atom_target)
@@ -42,7 +42,7 @@
for(var/mob/living/potential_friend in oview(9, living_pawn))
if(!isashwalker(potential_friend))
continue
if((living_pawn.faction.Find(REF(potential_friend))))
if(living_pawn.has_ally(REF(potential_friend)))
continue
living_pawn.befriend(potential_friend)
to_chat(potential_friend, span_nicegreen("[living_pawn] looks at you with endearing eyes!"))
@@ -59,7 +59,7 @@
/// Spawns a worm on the specified turf
/mob/living/basic/mining/hivelord/proc/complete_spawn(turf/spawn_turf)
var/mob/living/brood = new death_spawn_type(spawn_turf)
brood.faction = faction
SET_FACTION_AND_ALLIES_FROM(brood, src)
brood.ai_controller?.set_blackboard_key(ai_controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET])
brood.dir = get_dir(src, spawn_turf)
@@ -79,7 +79,7 @@
/// Actually create a mob
/datum/action/cooldown/mob_cooldown/hivelord_spawn/proc/complete_spawn(turf/spawn_turf, target)
var/mob/living/brood = new spawn_type(spawn_turf)
brood.faction = owner.faction
SET_FACTION_AND_ALLIES_FROM(brood, owner)
brood.ai_controller?.set_blackboard_key(ai_target_key, target)
brood.dir = get_dir(owner, spawn_turf)
@@ -85,7 +85,7 @@
var/spawn_type = get_legion_type(target)
var/mob/living/basic/mining/legion/new_legion = new spawn_type(loc)
new_legion.consume(target)
new_legion.faction = faction.Copy()
new_legion.set_faction(get_faction())
qdel(src)
/// Returns the kind of legion we make out of the target
@@ -99,9 +99,9 @@
/// Sets someone as our creator, mostly so you can't use skulls to heal yourself
/mob/living/basic/mining/legion_brood/proc/assign_creator(mob/living/creator, copy_full_faction = TRUE)
if (copy_full_faction)
faction = creator.faction.Copy()
set_faction(creator.get_faction())
else
faction |= REF(creator)
add_ally(creator)
created_by = WEAKREF(creator)
ai_controller?.set_blackboard_key(BB_LEGION_BROOD_CREATOR, creator)
RegisterSignal(creator, COMSIG_QDELETING, PROC_REF(creator_destroyed))
@@ -97,8 +97,8 @@
. = ..()
if(isnull(.))
return
faction |= new_friend.faction
faction -= FACTION_MINING
APPLY_FACTION_AND_ALLIES_FROM(src, new_friend)
remove_faction(FACTION_MINING)
/mob/living/basic/mining/lobstrosity/mind_initialize()
. = ..()
@@ -58,6 +58,6 @@
/mob/living/basic/mining/proc/check_ashwalker_peace_violation(datum/source, mob/living/carbon/human/possible_ashwalker)
SIGNAL_HANDLER
if(!isashwalker(possible_ashwalker) || !(FACTION_ASHWALKER in faction))
if(!isashwalker(possible_ashwalker) || !has_faction(FACTION_ASHWALKER))
return
faction.Remove(FACTION_ASHWALKER)
remove_faction(FACTION_ASHWALKER)
@@ -31,7 +31,7 @@ GLOBAL_LIST_INIT(mook_commands, list(
///check for faction if not a ash walker, otherwise just attack
/datum/targeting_strategy/basic/mook/faction_check(datum/ai_controller/controller, mob/living/living_mob, mob/living/the_target)
if(FACTION_ASHWALKER in living_mob.faction)
if(living_mob.has_faction(FACTION_ASHWALKER))
return FALSE
return ..()
@@ -116,7 +116,7 @@
if(isgroundlessturf(my_turf))
return FALSE
var/obj/effect/mine/minebot/my_mine = new(my_turf)
my_mine.ignore_list = owner.faction.Copy()
my_mine.ignore_list = owner.get_faction()
playsound(my_turf, 'sound/items/weapons/armbomb.ogg', 20)
StartCooldown()
return TRUE
@@ -183,6 +183,6 @@
if(!isliving(on_who))
return ..()
var/mob/living/stepped_mob = on_who
if(FACTION_NEUTRAL in stepped_mob.faction)
if(stepped_mob.has_faction(FACTION_NEUTRAL))
return FALSE
return ..()
@@ -74,7 +74,7 @@
controller.queue_behavior(/datum/ai_behavior/find_and_set, BB_DRONE_DEFEND, /mob/living/basic/node_drone)
return
var/mob/living/living_pawn = controller.pawn
if(!living_pawn.faction.Find(REF(target)))
if(!living_pawn.has_ally(target))
controller.queue_behavior(/datum/ai_behavior/befriend_target, BB_DRONE_DEFEND)
return
if(target.health < (target.maxHealth * 0.75) && controller.blackboard[BB_MINEBOT_REPAIR_DRONE])
@@ -51,13 +51,13 @@
else
. += span_notice("It looks like it has already made its delivery.")
/mob/living/basic/pet/gondola/gondolapod/setOpened()
/mob/living/basic/pet/gondola/gondolapod/set_opened()
opened = TRUE
layer = initial(layer)
update_appearance()
addtimer(CALLBACK(src, TYPE_PROC_REF(/atom/, setClosed)), 5 SECONDS)
addtimer(CALLBACK(src, TYPE_PROC_REF(/atom/, set_closed)), 5 SECONDS)
/mob/living/basic/pet/gondola/gondolapod/setClosed()
/mob/living/basic/pet/gondola/gondolapod/set_closed()
opened = FALSE
layer = LOW_MOB_LAYER
update_appearance()
@@ -57,7 +57,7 @@
return potential_victim
if(!ishuman(potential_victim))
continue
if(living_pawn.faction.Find(REF(potential_victim)))
if(living_pawn.has_ally(potential_victim))
continue //dont steal from friends
if(holding_valuable(controller, potential_victim))
controller.set_blackboard_key(BB_ALWAYS_IGNORE_FACTION, TRUE)
@@ -51,7 +51,7 @@
/datum/ai_behavior/find_and_set/friendly_cultist/search_tactic(datum/ai_controller/controller, locate_path, search_range = SEARCH_TACTIC_DEFAULT_RANGE)
var/mob/living/living_pawn = controller.pawn
for(var/mob/living/carbon/possible_cultist in oview(search_range, controller.pawn))
if(IS_CULTIST(possible_cultist) && !(living_pawn.faction.Find(REF(possible_cultist))))
if(IS_CULTIST(possible_cultist) && !(living_pawn.has_ally(possible_cultist)))
return possible_cultist
return null
@@ -112,7 +112,7 @@
var/list/created_slimes = list(src)
var/list/slime_friends = list()
for(var/faction_member in faction)
for(var/faction_member in get_faction())
var/mob/living/possible_friend = locate(faction_member) in GLOB.mob_living_list
if(QDELETED(possible_friend))
continue
@@ -29,12 +29,12 @@
// Check if the slime can drain the target
/datum/ai_behavior/find_hunt_target/find_slime_food/valid_dinner(mob/living/basic/slime/hunter, mob/living/dinner, radius, datum/ai_controller/controller, seconds_per_tick)
var/static/list/slime_faction
if(isnull(slime_faction)) // This might look silly but by having this list pointer precached we can take advantage of the faster inline macro for this hot proc.
slime_faction = string_list(list(FACTION_SLIME))
if(REF(dinner) in hunter.faction) //Don't eat our friends...
return FALSE
var/static/list/slime_faction = list(FACTION_SLIME)
if(faction_check(slime_faction, dinner.faction)) //Don't try to eat slimy things, no matter how hungry we are. Anyone else can be betrayed.
// Macro here to squeeze as much speed as possible because this code gets exponentially HOT if people are doing a lot of xenobio.
if(FAST_FACTION_CHECK(slime_faction, dinner.get_faction(), hunter.allies, dinner.allies, FALSE)) // Don't try to eat our friends, or slimy things, no matter how hungry we are. Anyone else can be betrayed.
return FALSE
if(!hunter.can_feed_on(dinner, check_adjacent = FALSE)) //Are they tasty to slimes?
@@ -17,7 +17,7 @@
balloon_alert(src, "not hungry!")
return FALSE
if(check_friendship && (REF(meal) in faction))
if(check_friendship && has_faction(REF(meal)))
return FALSE
if(check_adjacent && (!Adjacent(meal) || !isturf(loc)))
@@ -33,7 +33,6 @@
unsuitable_cold_damage = 4
unsuitable_heat_damage = 4
combat_mode = TRUE
faction = list() // No allies but yourself
pass_flags = PASSTABLE
unique_name = TRUE
lighting_cutoff_red = 22
@@ -119,4 +119,4 @@
/mob/living/basic/eyeball/tamed(mob/living/tamer, atom/food)
spin(spintime = 2 SECONDS, speed = 1)
//become passive to the humens
faction |= tamer.faction
APPLY_FACTION_AND_ALLIES_FROM(src, tamer)
@@ -67,7 +67,7 @@
/mob/living/basic/lightgeist/melee_attack(atom/target, list/modifiers, ignore_cooldown = FALSE)
. = ..()
if (. && isliving(target))
faction |= REF(target) // Anyone we heal will treat us as a friend
add_ally(target) // Anyone we heal will treat us as a friend
/mob/living/basic/lightgeist/ghost()
. = ..()
@@ -21,7 +21,6 @@
response_help_simple = "pet"
response_disarm_continuous = "gently pushes"
response_disarm_simple = "gently push"
faction = list()
ai_controller = /datum/ai_controller/basic_controller/meteor_heart
habitable_atmos = null
minimum_survivable_temperature = 0
@@ -175,9 +175,9 @@
/datum/reagent/rat_spit/overdose_start(mob/living/affected_mob, metabolization_ratio)
. = ..()
var/mob/living/carbon/victim = affected_mob
if (istype(victim) && !(FACTION_RAT in victim.faction))
if (istype(victim) && !victim.has_faction(FACTION_RAT))
to_chat(victim, span_userdanger("With this last sip, you feel your body convulsing horribly from the contents you've ingested. As you contemplate your actions, you sense an awakened kinship with rat-kind and their newly risen leader!"))
victim.faction |= FACTION_RAT
victim.add_faction(FACTION_RAT)
victim.vomit(VOMIT_CATEGORY_DEFAULT)
metabolization_rate = 10 * REAGENTS_METABOLISM
@@ -152,7 +152,7 @@
var/mob/living/basic/spider/giant/grown = change_mob_type(grow_as, get_turf(src), initial(grow_as.name))
ADD_TRAIT(grown, TRAIT_WAS_EVOLVED, REF(src))
grown.faction = faction.Copy()
SET_FACTION_AND_ALLIES_FROM(grown, src)
grown.directive = directive
grown.set_name()
grown.set_brute_loss(get_brute_loss())
@@ -55,7 +55,7 @@
/datum/action/cooldown/mob_cooldown/lay_eggs/proc/lay_egg()
var/obj/effect/mob_spawn/ghost_role/spider/new_eggs = new egg_type(get_turf(owner))
new_eggs.faction = owner.faction
SET_FACTION_AND_ALLIES_FROM(new_eggs, owner)
var/datum/action/cooldown/mob_cooldown/set_spider_directive/spider_directive = locate() in owner.actions
if (spider_directive)
new_eggs.directive = spider_directive.current_directive
@@ -81,7 +81,7 @@
/mob/living/basic/mouse/proc/make_tameable()
if (tame)
faction |= FACTION_NEUTRAL
add_faction(FACTION_NEUTRAL)
else
var/static/list/food_types = list(/obj/item/food/cheese)
AddComponent(/datum/component/tameable, food_types = food_types, tame_chance = 100)
@@ -196,7 +196,7 @@
/// Called when a mouse is hand-fed some cheese, it will stop being afraid of humans
/mob/living/basic/mouse/tamed(mob/living/tamer, obj/item/food/cheese/cheese)
new /obj/effect/temp_visual/heart(loc)
faction |= FACTION_NEUTRAL
add_faction(FACTION_NEUTRAL)
tame = TRUE
try_consume_cheese(cheese)
ai_controller.CancelActions() // Interrupt any current fleeing