Dynamic current_players lists rework (#50013)

* current player lists

* Docs
This commit is contained in:
Rohesie
2020-03-21 17:05:13 +01:00
committed by GitHub
parent d82937ce33
commit 0cf8f7cd9d
18 changed files with 186 additions and 81 deletions
+6
View File
@@ -7,6 +7,12 @@
#define PLAYER_READY_TO_PLAY 1
#define PLAYER_READY_TO_OBSERVE 2
//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"
//movement intent defines for the m_intent var
#define MOVE_INTENT_WALK "walk"
#define MOVE_INTENT_RUN "run"
-41
View File
@@ -1,8 +1,3 @@
#define CURRENT_LIVING_PLAYERS 1
#define CURRENT_LIVING_ANTAGS 2
#define CURRENT_DEAD_PLAYERS 3
#define CURRENT_OBSERVERS 4
#define ONLY_RULESET 1
#define HIGHLANDER_RULESET 2
#define TRAITOR_RULESET 4
@@ -95,8 +90,6 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
var/list/current_rules = list()
/// List of executed rulesets.
var/list/executed_rules = list()
/// Associative list of current players, in order: living players, living antagonists, dead players and observers.
var/list/list/current_players = list(CURRENT_LIVING_PLAYERS, CURRENT_LIVING_ANTAGS, CURRENT_DEAD_PLAYERS, CURRENT_OBSERVERS)
/// When world.time is over this number the mode tries to inject a latejoin ruleset.
var/latejoin_injection_cooldown = 0
/// When world.time is over this number the mode tries to inject a midround ruleset.
@@ -105,8 +98,6 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
var/forced_injection = FALSE
/// Forced ruleset to be executed for the next latejoin.
var/datum/dynamic_ruleset/latejoin/forced_latejoin_rule = null
/// When current_players was updated last time.
var/pop_last_updated = 0
/// How many percent of the rounds are more peaceful.
var/peaceful_percentage = 50
/// If a highlander executed.
@@ -198,7 +189,6 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
. = "<b><i>Central Command Status Summary</i></b><hr>"
switch(round(threat_level))
if(0 to 19)
update_playercounts()
if(!current_players[CURRENT_LIVING_ANTAGS].len)
. += "<b>Peaceful Waypoint</b></center><BR>"
. += "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."
@@ -359,8 +349,6 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
return TRUE
/datum/game_mode/dynamic/post_setup(report)
update_playercounts()
for(var/datum/dynamic_ruleset/roundstart/rule in executed_rules)
rule.candidates.Cut() // The rule should not use candidates at this point as they all are null.
addtimer(CALLBACK(src, /datum/game_mode/dynamic/.proc/execute_roundstart_rule, rule), rule.delay)
@@ -564,7 +552,6 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
if(highlander_executed)
return FALSE
update_playercounts()
if ((forced || (new_rule.acceptable(current_players[CURRENT_LIVING_PLAYERS].len, threat_level) && new_rule.cost <= threat)))
new_rule.trim_candidates()
if (new_rule.ready(forced))
@@ -609,10 +596,6 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
return FALSE
/datum/game_mode/dynamic/process()
if (pop_last_updated < world.time - (60 SECONDS))
pop_last_updated = world.time
update_playercounts()
for (var/datum/dynamic_ruleset/rule in current_rules)
if(rule.rule_process() == RULESET_STOP_PROCESSING) // If rule_process() returns 1 (RULESET_STOP_PROCESSING), stop processing.
current_rules -= rule
@@ -633,7 +616,6 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
message_admins("DYNAMIC: Checking for midround injection.")
log_game("DYNAMIC: Checking for midround injection.")
update_playercounts()
if (get_injection_chance())
var/list/drafted_rules = list()
for (var/datum/dynamic_ruleset/midround/rule in midround_rules)
@@ -647,27 +629,6 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
if (drafted_rules.len > 0)
picking_midround_latejoin_rule(drafted_rules)
/// Updates current_players.
/datum/game_mode/dynamic/proc/update_playercounts()
current_players[CURRENT_LIVING_PLAYERS] = list()
current_players[CURRENT_LIVING_ANTAGS] = list()
current_players[CURRENT_DEAD_PLAYERS] = list()
current_players[CURRENT_OBSERVERS] = list()
for (var/mob/M in GLOB.player_list)
if (istype(M, /mob/dead/new_player))
continue
if (M.stat != DEAD)
current_players[CURRENT_LIVING_PLAYERS].Add(M)
if (M.mind && (M.mind.special_role || M.mind.antag_datums?.len > 0))
current_players[CURRENT_LIVING_ANTAGS].Add(M)
else
if (istype(M,/mob/dead/observer))
var/mob/dead/observer/O = M
if (O.started_as_observer) // Observers
current_players[CURRENT_OBSERVERS].Add(M)
continue
current_players[CURRENT_DEAD_PLAYERS].Add(M) // Players who actually died (and admins who ghosted, would be nice to avoid counting them somehow)
/// Gets the chance for latejoin and midround injection, the dry_run argument is only used for forced injection.
/datum/game_mode/dynamic/proc/get_injection_chance(dry_run = FALSE)
if(forced_injection)
@@ -724,8 +685,6 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
if(EMERGENCY_ESCAPED_OR_ENDGAMED) // No more rules after the shuttle has left
return
update_playercounts()
if (forced_latejoin_rule)
forced_latejoin_rule.candidates = list(newPlayer)
forced_latejoin_rule.trim_candidates()
+3
View File
@@ -51,6 +51,9 @@
var/gamemode_ready = FALSE //Is the gamemode all set up and ready to start checking for ending conditions.
var/setup_error //What stopepd setting up the mode.
/// 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, "<b>The gamemode is: <span class='[announce_span]'>[name]</span>!</b>")
+26 -10
View File
@@ -49,9 +49,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)
@@ -89,17 +95,23 @@ 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()
if(owner && owner.current)
if(!silent)
greet()
apply_innate_effects()
give_antag_moodies()
if(is_banned(owner.current) && replace_banned)
replace_banned_player()
else if(owner.current.client?.holder && (CONFIG_GET(flag/auto_deadmin_antagonists) || owner.current.client.prefs?.toggles & DEADMIN_ANTAGONIST))
owner.current.client.holder.auto_deadmin()
SHOULD_CALL_PARENT(TRUE)
if(!owner)
CRASH("[src] ran on_gain() without a mind")
if(!owner.current)
CRASH("[src] ran on_gain() on a mind without a mob")
if(!silent)
greet()
apply_innate_effects()
give_antag_moodies()
if(is_banned(owner.current) && replace_banned)
replace_banned_player()
else if(owner.current.client?.holder && (CONFIG_GET(flag/auto_deadmin_antagonists) || owner.current.client.prefs?.toggles & DEADMIN_ANTAGONIST))
owner.current.client.holder.auto_deadmin()
if(owner.current.stat != DEAD)
owner.current.add_to_current_living_antags()
/datum/antagonist/proc/is_banned(mob/M)
if(!M)
@@ -117,11 +129,15 @@ GLOBAL_LIST_EMPTY(antagonists)
owner.current.ghostize(0)
owner.current.key = C.key
///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)
if(!LAZYLEN(owner.antag_datums))
owner.current.remove_from_current_living_antags()
if(!silent && owner.current)
farewell()
var/datum/team/team = get_team()
@@ -22,13 +22,16 @@
return ashie_team
/datum/antagonist/ashwalker/on_body_transfer(mob/living/old_body, mob/living/new_body)
. = ..()
UnregisterSignal(old_body, COMSIG_MOB_EXAMINATE)
RegisterSignal(new_body, COMSIG_MOB_EXAMINATE, .proc/on_examinate)
/datum/antagonist/ashwalker/on_gain()
. = ..()
RegisterSignal(owner.current, COMSIG_MOB_EXAMINATE, .proc/on_examinate)
/datum/antagonist/ashwalker/on_removal()
. = ..()
UnregisterSignal(owner.current, COMSIG_MOB_EXAMINATE)
/datum/antagonist/ashwalker/proc/on_examinate(datum/source, atom/A)
+1 -1
View File
@@ -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()
+1 -1
View File
@@ -128,7 +128,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)
+4 -4
View File
@@ -63,8 +63,8 @@
var/fubar_brain = newbrain.suicided || brainmob.suiciding //brain is from a suicider
if(!fubar_brain && !(newbrain.organ_flags & ORGAN_FAILING)) // the brain organ hasn't been beaten to death, nor was from a suicider.
brainmob.set_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()
else if(!fubar_brain && newbrain.organ_flags & ORGAN_FAILING) // the brain is damaged, but not from a suicider
to_chat(user, "<span class='warning'>[src]'s indicator light turns yellow and its brain integrity alarm beeps softly. Perhaps you should check [newbrain] for damage.</span>")
playsound(src, "sound/machines/synth_no.ogg", 5, TRUE)
@@ -108,8 +108,8 @@
brainmob.set_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
log_game("[key_name(user)] has ejected the brain of [key_name(brainmob)] from an MMI at [AREACOORD(src)]")
brainmob = null //Set mmi brainmob var to null
+2 -2
View File
@@ -130,8 +130,8 @@ GLOBAL_VAR(posibrain_notify_cooldown)
to_chat(brainmob, welcome_message)
brainmob.mind.assigned_role = new_role
brainmob.set_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()
+2 -2
View File
@@ -59,9 +59,9 @@
deadchat_broadcast(" has died at <b>[get_area_name(T)]</b>.", "<b>[mind.name]</b>", follow_target = src, turf_target = T, message_type=DEADCHAT_DEATHRATTLE)
if(mind)
mind.store_memory("Time of death: [tod]", 0)
GLOB.alive_mob_list -= src
remove_from_alive_mob_list()
if(!gibbed && !was_dead_before)
GLOB.dead_mob_list += src
add_to_dead_mob_list()
set_drugginess(0)
set_disgust(0)
SetSleeping(0, 0)
+6 -6
View File
@@ -550,8 +550,8 @@
if(full_heal)
fully_heal(admin_revive = 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()
set_suicide(FALSE)
set_stat(UNCONSCIOUS) //the mob starts unconscious,
updatehealth() //then we check if the mob should wake up.
@@ -1371,11 +1371,11 @@
return FALSE
if("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()
. = ..()
switch(var_name)
if("knockdown")
+1 -1
View File
@@ -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)
@@ -163,8 +163,8 @@
if(mmi.brainmob)
if(mmi.brainmob.stat == DEAD)
mmi.brainmob.set_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
+1 -1
View File
@@ -22,7 +22,7 @@
* * send signal COMSIG_MOB_CLIENT_LOGIN
*/
/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]")
+2 -2
View File
@@ -2,13 +2,13 @@
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()
..()
if(loc)
loc.on_log(FALSE)
if(client)
for(var/foo in client.player_details.post_logout_callbacks)
var/datum/callback/CB = foo
+6 -8
View File
@@ -23,10 +23,9 @@
* Returns QDEL_HINT_HARDDEL (don't change this)
*/
/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
GLOB.mob_directory -= tag
remove_from_mob_list()
remove_from_dead_mob_list()
remove_from_alive_mob_list()
focus = null
for (var/alert in alerts)
clear_alert(alert, TRUE)
@@ -60,12 +59,11 @@
*/
/mob/Initialize()
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_MOB_CREATED, src)
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)
+119
View File
@@ -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
+1
View File
@@ -2074,6 +2074,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"