From 6cc4e35b4494b4928b533e3284d87c72282daabf Mon Sep 17 00:00:00 2001 From: keronshb Date: Sun, 19 Sep 2021 13:28:41 -0400 Subject: [PATCH] Mob lists --- code/__DEFINES/mobs.dm | 6 + code/game/gamemodes/dynamic/dynamic.dm | 19 +-- .../game/gamemodes/dynamic/dynamic_logging.dm | 8 +- .../dynamic/dynamic_rulesets_latejoin.dm | 4 +- .../dynamic/dynamic_rulesets_midround.dm | 14 +-- .../game/gamemodes/dynamic/ruleset_picking.dm | 2 +- code/game/gamemodes/game_mode.dm | 5 + code/modules/admin/admin.dm | 14 --- code/modules/admin/admin_verbs.dm | 7 +- .../antagonists/_common/antag_datum.dm | 15 ++- code/modules/mob/dead/dead.dm | 2 +- code/modules/mob/dead/observer/observer.dm | 2 +- code/modules/mob/living/brain/MMI.dm | 8 +- code/modules/mob/living/brain/posibrain.dm | 4 +- code/modules/mob/living/death.dm | 4 +- code/modules/mob/living/living.dm | 12 +- code/modules/mob/living/silicon/pai/death.dm | 2 +- .../modules/mob/living/silicon/robot/robot.dm | 4 +- code/modules/mob/login.dm | 2 +- code/modules/mob/logout.dm | 2 +- code/modules/mob/mob.dm | 14 +-- code/modules/mob/mob_lists.dm | 119 ++++++++++++++++++ tgstation.dme | 1 + 23 files changed, 200 insertions(+), 70 deletions(-) create mode 100644 code/modules/mob/mob_lists.dm diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 6a63ced634..bac40e3202 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -351,3 +351,9 @@ //Gremlins #define NPC_TAMPER_ACT_FORGET 1 //Don't try to tamper with this again #define NPC_TAMPER_ACT_NOMSG 2 //Don't produce a visible message + +//Game mode list indexes +#define CURRENT_LIVING_PLAYERS "living_players_list" +#define CURRENT_LIVING_ANTAGS "living_antags_list" +#define CURRENT_DEAD_PLAYERS "dead_players_list" +#define CURRENT_OBSERVERS "current_observers_list" diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index 1b03a1e3f7..17596c8668 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -17,7 +17,10 @@ GLOBAL_LIST_EMPTY(dynamic_forced_roundstart_ruleset) GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) /datum/game_mode/dynamic + name = "dynamic mode" config_tag = "dynamic" + announce_span = "danger" + announce_text = "Dynamic mode!" // This needs to be changed maybe // Threat logging vars /// The "threat cap", threat shouldn't normally go above this and is used in ruleset calculations var/threat_level = 0 @@ -252,7 +255,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) . = "Central Command Status Summary
" switch(round(shown_threat)) if(0 to 19) - if(!GLOB.current_living_antags.len) + if(!current_players[CURRENT_LIVING_ANTAGS].len) . += "Peaceful Waypoint
" . += "Your station orbits deep within controlled, core-sector systems and serves as a waypoint for routine traffic through Nanotrasen's trade empire. Due to the combination of high security, interstellar traffic, and low strategic value, it makes any direct threat of violence unlikely. Your primary enemies will be incompetence and bored crewmen: try to organize team-building events to keep staffers interested and productive." else @@ -560,7 +563,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) if(high_impact_ruleset_executed) return FALSE - var/population = GLOB.alive_player_list.len + var/population = current_players[CURRENT_LIVING_PLAYERS].len if((new_rule.acceptable(population, threat_level) && new_rule.cost <= mid_round_budget) || forced) new_rule.trim_candidates() if (new_rule.ready(forced)) @@ -612,7 +615,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) for (var/datum/dynamic_ruleset/midround/rule in midround_rules) if (!rule.weight) continue - if (rule.acceptable(GLOB.alive_player_list.len, threat_level) && mid_round_budget >= rule.cost) + if (rule.acceptable(current_players[CURRENT_LIVING_PLAYERS].len, threat_level) && mid_round_budget >= rule.cost) rule.trim_candidates() if (rule.ready()) drafted_rules[rule] = rule.get_weight() @@ -634,16 +637,16 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) forced_injection = dry_run return 100 var/chance = 0 - var/max_pop_per_antag = max(5,15 - round(threat_level/10) - round(GLOB.alive_player_list.len/5)) - if (!GLOB.current_living_antags.len) + var/max_pop_per_antag = max(5,15 - round(threat_level/10) - round(current_players[CURRENT_LIVING_PLAYERS].len/5)) + if (!current_players[CURRENT_LIVING_ANTAGS].len) chance += 50 // No antags at all? let's boost those odds! else - var/current_pop_per_antag = GLOB.alive_player_list.len / GLOB.current_living_antags.len + var/current_pop_per_antag = current_players[CURRENT_LIVING_PLAYERS].len / current_players[CURRENT_LIVING_ANTAGS].len if (current_pop_per_antag > max_pop_per_antag) chance += min(50, 25+10*(current_pop_per_antag-max_pop_per_antag)) else chance += 25-10*(max_pop_per_antag-current_pop_per_antag) - if (GLOB.dead_player_list.len > GLOB.alive_player_list.len) + if (current_players[CURRENT_DEAD_PLAYERS].len > current_players[CURRENT_LIVING_PLAYERS].len) chance -= 30 // More than half the crew died? ew, let's calm down on antags if (mid_round_budget > higher_injection_chance_minimum_threat) chance += higher_injection_chance @@ -707,7 +710,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) for (var/datum/dynamic_ruleset/latejoin/rule in latejoin_rules) if (!rule.weight) continue - if (rule.acceptable(GLOB.alive_player_list.len, threat_level) && mid_round_budget >= rule.cost) + if (rule.acceptable(current_players[CURRENT_LIVING_PLAYERS].len, threat_level) && mid_round_budget >= rule.cost) // No stacking : only one round-ender, unless threat level > stacking_limit. if (threat_level < GLOB.dynamic_stacking_limit && GLOB.dynamic_no_stacking) if(rule.flags & HIGH_IMPACT_RULESET && high_impact_ruleset_executed) diff --git a/code/game/gamemodes/dynamic/dynamic_logging.dm b/code/game/gamemodes/dynamic/dynamic_logging.dm index 7490894b52..095b28c4e5 100644 --- a/code/game/gamemodes/dynamic/dynamic_logging.dm +++ b/code/game/gamemodes/dynamic/dynamic_logging.dm @@ -89,11 +89,11 @@ new_snapshot.remaining_threat = mid_round_budget new_snapshot.time = world.time - new_snapshot.alive_players = GLOB.alive_player_list.len - new_snapshot.dead_players = GLOB.dead_player_list.len - new_snapshot.observers = GLOB.current_observers_list.len + new_snapshot.alive_players = current_players[CURRENT_LIVING_PLAYERS].len + new_snapshot.dead_players = current_players[CURRENT_DEAD_PLAYERS].len + new_snapshot.observers = current_players[CURRENT_OBSERVERS].len new_snapshot.total_players = new_snapshot.alive_players + new_snapshot.dead_players + new_snapshot.observers - new_snapshot.alive_antags = GLOB.current_living_antags.len + new_snapshot.alive_antags = current_players[CURRENT_LIVING_ANTAGS].len new_snapshot.ruleset_chosen = new /datum/dynamic_snapshot_ruleset(ruleset_chosen) LAZYADD(snapshots, new_snapshot) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm index 5b34f1e8e8..849ccadd6e 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm @@ -25,7 +25,7 @@ if (!forced) var/job_check = 0 if (enemy_roles.len > 0) - for (var/mob/M in GLOB.alive_player_list) + for (var/mob/M in mode.current_players[CURRENT_LIVING_PLAYERS]) if (M.stat == DEAD) continue // Dead players cannot count as opponents if (M.mind && (M.mind.assigned_role in enemy_roles) && (!(M in candidates) || (M.mind.assigned_role in restricted_roles))) @@ -96,7 +96,7 @@ if(!..()) return FALSE var/head_check = 0 - for(var/mob/player in GLOB.alive_player_list) + for(var/mob/player in mode.current_players[CURRENT_LIVING_PLAYERS]) if (player.mind.assigned_role in GLOB.command_positions) head_check++ return (head_check >= required_heads_of_staff) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index c016fad8d8..93a7e01463 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -29,10 +29,10 @@ var/required_applicants = 1 /datum/dynamic_ruleset/midround/trim_candidates() - living_players = trim_list(GLOB.alive_player_list) - living_antags = trim_list(GLOB.current_living_antags) - dead_players = trim_list(GLOB.dead_player_list) - list_observers = trim_list(GLOB.current_observers_list) + living_players = trim_list(mode.current_players[CURRENT_LIVING_PLAYERS]) + living_antags = trim_list(mode.current_players[CURRENT_LIVING_ANTAGS]) + dead_players = trim_list(mode.current_players[CURRENT_DEAD_PLAYERS]) + list_observers = trim_list(mode.current_players[CURRENT_OBSERVERS]) /datum/dynamic_ruleset/midround/proc/trim_list(list/L = list()) var/list/trimmed_list = L.Copy() @@ -75,7 +75,7 @@ if (!forced) var/job_check = 0 if (enemy_roles.len > 0) - for (var/mob/M in GLOB.alive_player_list) + for (var/mob/M in mode.current_players[CURRENT_LIVING_PLAYERS]) if (M.stat == DEAD || !M.client) continue // Dead/disconnected players cannot count as opponents if (M.mind && (M.mind.assigned_role in enemy_roles) && (!(M in candidates) || (M.mind.assigned_role in restricted_roles))) @@ -198,8 +198,8 @@ var/has_failure_chance = TRUE /datum/dynamic_ruleset/midround/autotraitor/acceptable(population = 0, threat = 0) - var/player_count = GLOB.alive_player_list.len - var/antag_count = GLOB.current_living_antags.len + var/player_count = mode.current_players[CURRENT_LIVING_PLAYERS].len + var/antag_count = mode.current_players[CURRENT_LIVING_ANTAGS].len var/max_traitors = round(player_count / 10) + 1 // adding traitors if the antag population is getting low diff --git a/code/game/gamemodes/dynamic/ruleset_picking.dm b/code/game/gamemodes/dynamic/ruleset_picking.dm index 678c4fdedc..7c87f1bc82 100644 --- a/code/game/gamemodes/dynamic/ruleset_picking.dm +++ b/code/game/gamemodes/dynamic/ruleset_picking.dm @@ -70,7 +70,7 @@ var/datum/dynamic_ruleset/rule = sent_rule spend_midround_budget(rule.cost) threat_log += "[worldtime2text()]: [rule.ruletype] [rule.name] spent [rule.cost]" - rule.pre_execute(GLOB.alive_player_list.len) + rule.pre_execute(current_players[CURRENT_LIVING_PLAYERS].len) if (rule.execute()) log_game("DYNAMIC: Injected a [rule.ruletype == "latejoin" ? "latejoin" : "midround"] ruleset [rule.name].") if(rule.flags & HIGH_IMPACT_RULESET) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 5ea99da479..617be706cb 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -52,6 +52,9 @@ var/setup_error //What stopepd setting up the mode. var/flipseclevel = FALSE //CIT CHANGE - adds a 10% chance for the alert level to be the opposite of what the gamemode is supposed to have + /// Associative list of current players, in order: living players, living antagonists, dead players and observers. + var/list/list/current_players = list(CURRENT_LIVING_PLAYERS = list(), CURRENT_LIVING_ANTAGS = list(), CURRENT_DEAD_PLAYERS = list(), CURRENT_OBSERVERS = list()) + /datum/game_mode/proc/announce() //Shows the gamemode's name and a fast description. to_chat(world, "The gamemode is: [name]!") to_chat(world, "[announce_text]") @@ -76,6 +79,8 @@ return 1 + + ///Attempts to select players for special roles the mode might have. /datum/game_mode/proc/pre_setup() return 1 diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 9c94ab5b12..d56e78c9fb 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -700,20 +700,6 @@ log_admin("[key_name(usr)] set the pre-game delay to [DisplayTimeText(newtime)].") SSblackbox.record_feedback("tally", "admin_verb", 1, "Delay Game Start") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/datum/admins/proc/toggledynamicvote() - set category = "Server" - set desc="Switches between secret/extended and dynamic voting" - set name="Toggle Dynamic Vote" - var/prev_dynamic_voting = CONFIG_GET(flag/dynamic_voting) - CONFIG_SET(flag/dynamic_voting,!prev_dynamic_voting) - if (!prev_dynamic_voting) - to_chat(world, "Vote is now between dynamic storytellers.") - else - to_chat(world, "Vote is now between extended and secret.") - log_admin("[key_name(usr)] [prev_dynamic_voting ? "disabled" : "enabled"] dynamic voting.") - message_admins("[key_name_admin(usr)] toggled dynamic voting.") - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Dynamic Voting", "[prev_dynamic_voting ? "Disabled" : "Enabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - /datum/admins/proc/unprison(mob/M in GLOB.mob_list) set category = "Admin" set name = "Unprison" diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index aa3e3f78d2..8d3e1c79ec 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -135,7 +135,6 @@ GLOBAL_PROTECT(admin_verbs_server) /client/proc/everyone_random, /datum/admins/proc/toggleAI, /datum/admins/proc/toggleMulticam, //CIT - /datum/admins/proc/toggledynamicvote, //CIT /client/proc/cmd_admin_delete, /*delete an instance/object/mob/etc*/ /client/proc/cmd_debug_del_all, /client/proc/toggle_random_events, @@ -190,11 +189,11 @@ GLOBAL_PROTECT(admin_verbs_debug) // /client/proc/validate_cards, // /client/proc/test_cardpack_distribution, // /client/proc/print_cards, - // #ifdef TESTING + #ifdef TESTING // /client/proc/check_missing_sprites, // /client/proc/export_dynamic_json, - // /client/proc/run_dynamic_simulations, - // #endif + /client/proc/run_dynamic_simulations, + #endif /datum/admins/proc/create_or_modify_area, /datum/admins/proc/fixcorruption, #ifdef EXTOOLS_REFERENCE_TRACKING diff --git a/code/modules/antagonists/_common/antag_datum.dm b/code/modules/antagonists/_common/antag_datum.dm index 4082a48e71..f232142902 100644 --- a/code/modules/antagonists/_common/antag_datum.dm +++ b/code/modules/antagonists/_common/antag_datum.dm @@ -55,9 +55,15 @@ GLOBAL_LIST_EMPTY(antagonists) /datum/antagonist/proc/specialization(datum/mind/new_owner) return src + ///Called by the transfer_to() mind proc after the mind (mind.current and new_character.mind) has moved but before the player (key and client) is transfered. /datum/antagonist/proc/on_body_transfer(mob/living/old_body, mob/living/new_body) + SHOULD_CALL_PARENT(TRUE) remove_innate_effects(old_body) + if(old_body.stat != DEAD && !LAZYLEN(old_body.mind?.antag_datums)) + old_body.remove_from_current_living_antags() apply_innate_effects(new_body) + if(new_body.stat != DEAD) + new_body.add_to_current_living_antags() //This handles the application of antag huds/special abilities /datum/antagonist/proc/apply_innate_effects(mob/living/mob_override) @@ -94,8 +100,9 @@ GLOBAL_LIST_EMPTY(antagonists) /datum/antagonist/proc/create_team(datum/team/team) return -//Proc called when the datum is given to a mind. + ///Called by the add_antag_datum() mind proc after the instanced datum is added to the mind's antag_datums list. /datum/antagonist/proc/on_gain() + SHOULD_CALL_PARENT(TRUE) set waitfor = FALSE if(!(owner?.current)) return @@ -113,6 +120,8 @@ GLOBAL_LIST_EMPTY(antagonists) if(istype(M)) M.name = "[name] Training" owner.current.AddComponent(/datum/component/activity) + if(owner.current.stat != DEAD) + owner.current.add_to_current_living_antags() SEND_SIGNAL(owner.current, COMSIG_MOB_ANTAG_ON_GAIN, src) /datum/antagonist/proc/is_banned(mob/M) @@ -131,13 +140,17 @@ GLOBAL_LIST_EMPTY(antagonists) owner.current.ghostize(0) C.transfer_ckey(owner.current, FALSE) +///Called by the remove_antag_datum() and remove_all_antag_datums() mind procs for the antag datum to handle its own removal and deletion. /datum/antagonist/proc/on_removal() + SHOULD_CALL_PARENT(TRUE) remove_innate_effects() clear_antag_moodies() if(owner) LAZYREMOVE(owner.antag_datums, src) for(var/A in skill_modifiers) owner.remove_skill_modifier(GET_SKILL_MOD_ID(A, type)) + if(!LAZYLEN(owner.antag_datums)) + owner.current.remove_from_current_living_antags() if(!silent && owner.current) farewell() var/datum/team/team = get_team() diff --git a/code/modules/mob/dead/dead.dm b/code/modules/mob/dead/dead.dm index 5647bc2305..ce767ae00d 100644 --- a/code/modules/mob/dead/dead.dm +++ b/code/modules/mob/dead/dead.dm @@ -13,7 +13,7 @@ INITIALIZE_IMMEDIATE(/mob/dead) stack_trace("Warning: [src]([type]) initialized multiple times!") flags_1 |= INITIALIZED_1 tag = "mob_[next_mob_id++]" - GLOB.mob_list += src + add_to_mob_list() prepare_huds() diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 1aa2863eda..0f30fe20fc 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -123,7 +123,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) animate(src, pixel_y = 2, time = 10, loop = -1) - GLOB.dead_mob_list += src + add_to_dead_mob_list() for(var/v in GLOB.active_alternate_appearances) if(!v) diff --git a/code/modules/mob/living/brain/MMI.dm b/code/modules/mob/living/brain/MMI.dm index 85c256f5b0..f38f326bc6 100644 --- a/code/modules/mob/living/brain/MMI.dm +++ b/code/modules/mob/living/brain/MMI.dm @@ -64,8 +64,8 @@ brainmob.container = src if(!(newbrain.organ_flags & ORGAN_FAILING)) // the brain organ hasn't been beaten to death. brainmob.stat = CONSCIOUS //we manually revive the brain mob - GLOB.dead_mob_list -= brainmob - GLOB.alive_mob_list += brainmob + brainmob.remove_from_dead_mob_list() + brainmob.add_to_alive_mob_list() brainmob.reset_perspective() brain = newbrain @@ -102,8 +102,8 @@ brainmob.stat = DEAD brainmob.emp_damage = 0 brainmob.reset_perspective() //so the brainmob follows the brain organ instead of the mmi. And to update our vision - GLOB.alive_mob_list -= brainmob //Get outta here - GLOB.dead_mob_list += brainmob + brainmob.remove_from_alive_mob_list() //Get outta here + brainmob.add_to_dead_mob_list() brain.brainmob = brainmob //Set the brain to use the brainmob brainmob = null //Set mmi brainmob var to null if(user) diff --git a/code/modules/mob/living/brain/posibrain.dm b/code/modules/mob/living/brain/posibrain.dm index 893d7c5103..e1eb09405a 100644 --- a/code/modules/mob/living/brain/posibrain.dm +++ b/code/modules/mob/living/brain/posibrain.dm @@ -159,8 +159,8 @@ GLOBAL_VAR(posibrain_notify_cooldown) to_chat(brainmob, welcome_message) brainmob.mind.assigned_role = new_role brainmob.stat = CONSCIOUS - GLOB.dead_mob_list -= brainmob - GLOB.alive_mob_list += brainmob + brainmob.remove_from_dead_mob_list() + brainmob.add_to_alive_mob_list() visible_message(new_mob_message) check_success() diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm index 2d529e976a..cbf0de51de 100644 --- a/code/modules/mob/living/death.dm +++ b/code/modules/mob/living/death.dm @@ -65,9 +65,9 @@ I.on_mob_death(src, gibbed) if(mind) mind.store_memory("Time of death: [tod]", 0) - GLOB.alive_mob_list -= src + remove_from_alive_mob_list() if(!gibbed) - GLOB.dead_mob_list += src + add_to_dead_mob_list() if(ckey) var/datum/preferences/P = GLOB.preferences_datums[ckey] if(P) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 5603801dce..be8241c063 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -589,8 +589,8 @@ if(full_heal) fully_heal(admin_revive) if(stat == DEAD && can_be_revived()) //in some cases you can't revive (e.g. no brain) - GLOB.dead_mob_list -= src - GLOB.alive_mob_list += src + remove_from_dead_mob_list() + add_to_alive_mob_list() suiciding = 0 stat = UNCONSCIOUS //the mob starts unconscious, if(!eye_blind) @@ -1289,11 +1289,11 @@ return FALSE if(NAMEOF(src, stat)) if((stat == DEAD) && (var_value < DEAD))//Bringing the dead back to life - GLOB.dead_mob_list -= src - GLOB.alive_mob_list += src + remove_from_dead_mob_list() + add_to_alive_mob_list() if((stat < DEAD) && (var_value == DEAD))//Kill he - GLOB.alive_mob_list -= src - GLOB.dead_mob_list += src + remove_from_alive_mob_list() + add_to_dead_mob_list() if(NAMEOF(src, health)) //this doesn't work. gotta use procs instead. return FALSE . = ..() diff --git a/code/modules/mob/living/silicon/pai/death.dm b/code/modules/mob/living/silicon/pai/death.dm index c60d84438c..c2bc49f9a8 100644 --- a/code/modules/mob/living/silicon/pai/death.dm +++ b/code/modules/mob/living/silicon/pai/death.dm @@ -7,6 +7,6 @@ clear_fullscreens() //New pAI's get a brand new mind to prevent meta stuff from their previous life. This new mind causes problems down the line if it's not deleted here. - GLOB.alive_mob_list -= src + remove_from_alive_mob_list() ghostize() qdel(src) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 9658247da3..3032011a1a 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -95,8 +95,8 @@ if(mmi.brainmob) if(mmi.brainmob.stat == DEAD) mmi.brainmob.stat = CONSCIOUS - GLOB.dead_mob_list -= mmi.brainmob - GLOB.alive_mob_list += mmi.brainmob + mmi.brainmob.remove_from_dead_mob_list() + mmi.brainmob.add_to_alive_mob_list() mind.transfer_to(mmi.brainmob) mmi.update_icon() else diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index 2ed0bfa9d2..8f74d3b45f 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -1,5 +1,5 @@ /mob/Login() - GLOB.player_list |= src + add_to_player_list() lastKnownIP = client.address computer_id = client.computer_id log_access("Mob Login: [key_name(src)] was assigned to a [type]") diff --git a/code/modules/mob/logout.dm b/code/modules/mob/logout.dm index 536eacca7d..2e2eeeb4fb 100644 --- a/code/modules/mob/logout.dm +++ b/code/modules/mob/logout.dm @@ -3,7 +3,7 @@ log_message("[key_name(src)] is no longer owning mob [src]([src.type])", LOG_OWNERSHIP) SStgui.on_logout(src) unset_machine() - GLOB.player_list -= src + remove_from_player_list() ..() diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 5ba4769f99..8a71bb72c4 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1,9 +1,8 @@ /mob/Destroy()//This makes sure that mobs with clients/keys are not just deleted from the game. - GLOB.mob_list -= src - GLOB.dead_mob_list -= src - GLOB.alive_mob_list -= src + remove_from_mob_list() + remove_from_dead_mob_list() + remove_from_alive_mob_list() GLOB.all_clockwork_mobs -= src - GLOB.mob_directory -= tag focus = null LAssailant = null movespeed_modification = null @@ -22,12 +21,11 @@ return QDEL_HINT_HARDDEL /mob/Initialize() - GLOB.mob_list += src - GLOB.mob_directory[tag] = src + add_to_mob_list() if(stat == DEAD) - GLOB.dead_mob_list += src + add_to_dead_mob_list() else - GLOB.alive_mob_list += src + add_to_alive_mob_list() set_focus(src) prepare_huds() for(var/v in GLOB.active_alternate_appearances) diff --git a/code/modules/mob/mob_lists.dm b/code/modules/mob/mob_lists.dm new file mode 100644 index 0000000000..14f519ec30 --- /dev/null +++ b/code/modules/mob/mob_lists.dm @@ -0,0 +1,119 @@ +///Adds the mob reference to the list and directory of all mobs. Called on Initialize(). +/mob/proc/add_to_mob_list() + GLOB.mob_list |= src + GLOB.mob_directory[tag] = src + +///Removes the mob reference from the list and directory of all mobs. Called on Destroy(). +/mob/proc/remove_from_mob_list() + GLOB.mob_list -= src + GLOB.mob_directory -= tag + +///Adds the mob reference to the list of all mobs alive. If mob is cliented, it adds it to the list of all living player-mobs. +/mob/proc/add_to_alive_mob_list() + GLOB.alive_mob_list |= src + if(client) + add_to_current_living_players() + +///Removes the mob reference from the list of all mobs alive. If mob is cliented, it removes it from the list of all living player-mobs. +/mob/proc/remove_from_alive_mob_list() + GLOB.alive_mob_list -= src + if(client) + remove_from_current_living_players() + + +///Adds the mob reference to the list of all the dead mobs. If mob is cliented, it adds it to the list of all dead player-mobs. +/mob/proc/add_to_dead_mob_list() + GLOB.dead_mob_list |= src + if(client) + add_to_current_dead_players() + +///Remvoes the mob reference from list of all the dead mobs. If mob is cliented, it adds it to the list of all dead player-mobs. +/mob/proc/remove_from_dead_mob_list() + GLOB.dead_mob_list -= src + if(client) + remove_from_current_dead_players() + + +///Adds the cliented mob reference to the list of all player-mobs, besides to either the of dead or alive player-mob lists, as appropriate. Called on Login(). +/mob/proc/add_to_player_list() + SHOULD_CALL_PARENT(TRUE) + GLOB.player_list |= src + if(!SSticker?.mode) + return + if(stat == DEAD) + add_to_current_dead_players() + else + add_to_current_living_players() + +///Removes the mob reference from the list of all player-mobs, besides from either the of dead or alive player-mob lists, as appropriate. Called on Logout(). +/mob/proc/remove_from_player_list() + SHOULD_CALL_PARENT(TRUE) + GLOB.player_list -= src + if(!SSticker?.mode) + return + if(stat == DEAD) + remove_from_current_dead_players() + else + remove_from_current_living_players() + + +///Adds the cliented mob reference to either the list of dead player-mobs or to the list of observers, depending on how they joined the game. +/mob/proc/add_to_current_dead_players() + if(!SSticker?.mode) + return + SSticker.mode.current_players[CURRENT_DEAD_PLAYERS] |= src + +/mob/dead/observer/add_to_current_dead_players() + if(!SSticker?.mode) + return + if(started_as_observer) + SSticker.mode.current_players[CURRENT_OBSERVERS] |= src + return + return ..() + +/mob/dead/new_player/add_to_current_dead_players() + return + +///Removes the mob reference from either the list of dead player-mobs or from the list of observers, depending on how they joined the game. +/mob/proc/remove_from_current_dead_players() + if(!SSticker?.mode) + return + SSticker.mode.current_players[CURRENT_DEAD_PLAYERS] -= src + +/mob/dead/observer/remove_from_current_dead_players() + if(!SSticker?.mode) + return + if(started_as_observer) + SSticker.mode.current_players[CURRENT_OBSERVERS] -= src + return + return ..() + + +///Adds the cliented mob reference to the list of living player-mobs. If the mob is an antag, it adds it to the list of living antag player-mobs. +/mob/proc/add_to_current_living_players() + if(!SSticker?.mode) + return + SSticker.mode.current_players[CURRENT_LIVING_PLAYERS] |= src + if(mind && (mind.special_role || length(mind.antag_datums))) + add_to_current_living_antags() + +///Removes the mob reference from the list of living player-mobs. If the mob is an antag, it removes it from the list of living antag player-mobs. +/mob/proc/remove_from_current_living_players() + if(!SSticker?.mode) + return + SSticker.mode.current_players[CURRENT_LIVING_PLAYERS] -= src + if(LAZYLEN(mind?.antag_datums)) + remove_from_current_living_antags() + + +///Adds the cliented mob reference to the list of living antag player-mobs. +/mob/proc/add_to_current_living_antags() + if(!SSticker?.mode) + return + SSticker.mode.current_players[CURRENT_LIVING_ANTAGS] |= src + +///Removes the mob reference from the list of living antag player-mobs. +/mob/proc/remove_from_current_living_antags() + if(!SSticker?.mode) + return + SSticker.mode.current_players[CURRENT_LIVING_ANTAGS] -= src diff --git a/tgstation.dme b/tgstation.dme index 83c6477050..e9526d1a00 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -2512,6 +2512,7 @@ #include "code\modules\mob\mob.dm" #include "code\modules\mob\mob_defines.dm" #include "code\modules\mob\mob_helpers.dm" +#include "code\modules\mob\mob_lists.dm" #include "code\modules\mob\mob_movement.dm" #include "code\modules\mob\mob_transformation_simple.dm" #include "code\modules\mob\say.dm"