Skip to content

Commit

Permalink
Antag selection weighting fixups (#3481)
Browse files Browse the repository at this point in the history
* Antag selection weighting fixups

* various misc storyteller code fixups

* improve antag cap logic

* fix most antags not being counted at all
  • Loading branch information
Absolucy authored Sep 27, 2024
1 parent 60617ac commit 3cc4b07
Show file tree
Hide file tree
Showing 35 changed files with 119 additions and 91 deletions.
8 changes: 7 additions & 1 deletion code/__DEFINES/antagonists.dm
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,13 @@ GLOBAL_LIST_INIT(human_invader_antagonists, list(
#define HUNTER_PACK_PSYKER "Psyker Shikaris"

// This flag disables certain checks that presume antagonist datums mean 'baddie'.
#define FLAG_FAKE_ANTAG (1 << 0)
#define FLAG_FAKE_ANTAG (1 << 0)
/// monkestation addition: Whether the antagonist can see exploitable info on people they examine.
#define FLAG_CAN_SEE_EXPOITABLE_INFO (1 << 1)
// monkestation addition: The storyteller will ignore this antag datum as counting against the antag cap.
#define FLAG_ANTAG_CAP_IGNORE (1 << 2)
// monkestation addition: The storyteller will count everyone on this antag's team as a singular antag instead.
#define FLAG_ANTAG_CAP_TEAM (1 << 3)

#define FREEDOM_IMPLANT_CHARGES 4

Expand Down
2 changes: 1 addition & 1 deletion code/controllers/master.dm
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ GLOBAL_REAL(Master, /datum/controller/master)
if(sleep_offline_after_initializations && CONFIG_GET(flag/resume_after_initializations))
world.sleep_offline = FALSE
initializations_finished_with_no_players_logged_in = initialized_tod < REALTIMEOFDAY - 10
SSgamemode.handle_picking_stroyteller() //monkestation edit
SSgamemode.handle_picking_storyteller() //monkestation edit

/**
* Initialize a given subsystem and handle the results.
Expand Down
2 changes: 1 addition & 1 deletion code/modules/antagonists/_common/antag_datum.dm
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ GLOBAL_LIST_EMPTY(antagonists)
/// The typepath for the outfit to show in the preview for the preferences menu.
var/preview_outfit
/// Flags for antags to turn on or off and check!
var/antag_flags = NONE
var/antag_flags = FLAG_CAN_SEE_EXPOITABLE_INFO // monkestation edit: allow antags to see exploitable info.
/// If true, this antagonist can assign themself a new objective
var/can_assign_self_objectives = FALSE
/// Default to fill in when entering a custom objective.
Expand Down
1 change: 1 addition & 0 deletions code/modules/antagonists/abductor/abductor.dm
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
show_in_antagpanel = FALSE //should only show subtypes
show_to_ghosts = TRUE
suicide_cry = "FOR THE MOTHERSHIP!!" // They can't even talk but y'know
antag_flags = parent_type::antag_flags | FLAG_ANTAG_CAP_TEAM // monkestation addition
var/datum/team/abductor_team/team
var/sub_role
var/outfit
Expand Down
1 change: 1 addition & 0 deletions code/modules/antagonists/blob/blob_minion.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
show_name_in_check_antagonists = TRUE
show_to_ghosts = TRUE
show_in_antagpanel = FALSE
antag_flags = FLAG_ANTAG_CAP_IGNORE // monkestation addition
/// The blob core that this minion is attached to
var/datum/weakref/overmind

Expand Down
1 change: 1 addition & 0 deletions code/modules/antagonists/brother/brother.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
ui_name = "AntagInfoBrother"
suicide_cry = "FOR MY BROTHER!!"
antag_moodlet = /datum/mood_event/focused
antag_flags = parent_type::antag_flags | FLAG_ANTAG_CAP_TEAM // monkestation addition
VAR_PRIVATE
datum/team/brother_team/team

Expand Down
1 change: 1 addition & 0 deletions code/modules/antagonists/changeling/fallen_changeling.dm
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
job_rank = ROLE_CHANGELING
antag_moodlet = /datum/mood_event/fallen_changeling
antag_hud_name = "changeling"
antag_flags = parent_type::antag_flags | FLAG_ANTAG_CAP_IGNORE // monkestation addition

/datum/mood_event/fallen_changeling
description = "My powers! Where are my powers?!"
Expand Down
1 change: 1 addition & 0 deletions code/modules/antagonists/heretic/heretic_monsters.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
antag_hud_name = "heretic_beast"
suicide_cry = "MY MASTER SMILES UPON ME!!"
show_in_antagpanel = FALSE
antag_flags = parent_type::antag_flags | FLAG_ANTAG_CAP_IGNORE // monkestation addition
/// Our master (a heretic)'s mind.
var/datum/mind/master

Expand Down
1 change: 1 addition & 0 deletions code/modules/antagonists/magic_servant/servant.dm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
show_in_roundend = FALSE
show_in_antagpanel = FALSE
show_name_in_check_antagonists = TRUE
antag_flags = parent_type::antag_flags | FLAG_ANTAG_CAP_IGNORE // monkestation addition

/datum/antagonist/magic_servant/proc/setup_master(mob/M)
var/datum/objective/O = new("Serve [M.real_name].")
Expand Down
1 change: 1 addition & 0 deletions code/modules/antagonists/pirate/pirate.dm
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
show_to_ghosts = TRUE
suicide_cry = "FOR ME MATEYS!!"
hijack_speed = 2 // That is without doubt the worst pirate I have ever seen.
antag_flags = parent_type::antag_flags | FLAG_ANTAG_CAP_TEAM // monkestation addition
var/datum/team/pirate/crew

/datum/antagonist/pirate/greet()
Expand Down
1 change: 1 addition & 0 deletions code/modules/antagonists/pyro_slime/pyro_slime.dm
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
show_in_antagpanel = FALSE
show_name_in_check_antagonists = TRUE
show_to_ghosts = TRUE
antag_flags = FLAG_ANTAG_CAP_IGNORE // monkestation addition

/datum/antagonist/pyro_slime/on_gain()
forge_objectives()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
name = "\improper Enemy of the Revolution"
show_in_antagpanel = FALSE
suicide_cry = "FOR NANOTRASEN, NOW AND FOREVER!!"
antag_flags = parent_type::antag_flags | FLAG_ANTAG_CAP_IGNORE // monkestation addition

/datum/antagonist/enemy_of_the_revolution/forge_objectives()
var/datum/objective/survive/survive = new
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
show_in_roundend = FALSE
count_against_dynamic_roll_chance = FALSE
ui_name = "AntagInfoSentient"
antag_flags = FLAG_ANTAG_CAP_IGNORE // monkestation addition

/datum/antagonist/sentient_creature/get_preview_icon()
var/icon/final_icon = icon('icons/mob/simple/pets.dmi', "corgi")
Expand Down
1 change: 1 addition & 0 deletions code/modules/antagonists/space_dragon/space_carp.dm
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
show_in_antagpanel = FALSE
show_name_in_check_antagonists = TRUE
show_to_ghosts = TRUE
antag_flags = FLAG_ANTAG_CAP_IGNORE // monkestation addition
/// The rift to protect
var/datum/weakref/rift

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
show_in_antagpanel = FALSE
show_name_in_check_antagonists = TRUE
show_to_ghosts = TRUE
antag_flags = FLAG_ANTAG_CAP_IGNORE // monkestation addition

/datum/antagonist/venus_human_trap/on_gain()
forge_objectives()
Expand Down
1 change: 1 addition & 0 deletions code/modules/antagonists/wishgranter/wishgranter.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
show_name_in_check_antagonists = TRUE
hijack_speed = 2 //You literally are here to do nothing else. Might as well be fast about it.
suicide_cry = "HAHAHAHAHA!!"
antag_flags = parent_type::antag_flags | FLAG_ANTAG_CAP_IGNORE // monkestation addition

/datum/antagonist/wishgranter/forge_objectives()
var/datum/objective/hijack/hijack = new
Expand Down
1 change: 1 addition & 0 deletions code/modules/antagonists/wizard/wizard.dm
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ GLOBAL_LIST_EMPTY(wizard_spellbook_purchases_by_key)
antag_hud_name = "apprentice"
show_in_roundend = FALSE
show_name_in_check_antagonists = TRUE
antag_flags = parent_type::antag_flags | FLAG_ANTAG_CAP_IGNORE // monkestation addition
/// The wizard team this wizard minion is part of.
var/datum/team/wizard/wiz_team

Expand Down
1 change: 1 addition & 0 deletions code/modules/antagonists/xeno/xeno.dm
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
return
captive_team = new
captive_team.progenitor = owner
antag_flags |= FLAG_ANTAG_CAP_IGNORE // monkestation edit: first captive xeno does not count against cap
else
if(!istype(new_team))
CRASH("Wrong xeno team type provided to create_team")
Expand Down
1 change: 1 addition & 0 deletions code/modules/bitrunning/antagonists/cyber_police.dm
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
show_to_ghosts = TRUE
suicide_cry = "ALT F4!"
ui_name = "AntagInfoCyberAuth"
antag_flags = FLAG_ANTAG_CAP_IGNORE // monkestation addition

/datum/antagonist/cyber_police/greet()
. = ..()
Expand Down
21 changes: 11 additions & 10 deletions code/modules/events/ghost_role/alien_infestation.dm
Original file line number Diff line number Diff line change
Expand Up @@ -87,25 +87,26 @@
if(temp_vent_parent.other_atmos_machines.len > 20)
vents += temp_vent

if(!vents.len)
if(!length(vents))
message_admins("An event attempted to spawn an alien but no suitable vents were found. Shutting down.")
return MAP_ERROR

for(var/i in 1 to antag_count)
if(!length(candidates))
break

var/client/mob_client = pick_n_take_weighted(weighted_candidates)
var/mob/candidate = mob_client.mob
if(candidate.client) //I hate this
candidate.client.prefs.reset_antag_rep()
var/selected_count = 0
while(length(weighted_candidates) && selected_count < antag_count)
var/client/candidate_ckey = pick_n_take_weighted(weighted_candidates)
var/client/candidate_client = GLOB.directory[candidate_ckey]
if(QDELETED(candidate_client) || QDELETED(candidate_client.mob))
continue
var/mob/candidate = candidate_client.mob
candidate_client.prefs?.reset_antag_rep()
if(!candidate.mind)
candidate.mind = new /datum/mind(candidate.key)

var/obj/vent = pick_n_take(vents)
var/mob/living/carbon/alien/larva/new_xeno = new(vent.loc)
new_xeno.key = candidate.key
new_xeno.ckey = candidate_ckey
new_xeno.move_into_vent(vent)
selected_count++

message_admins("[ADMIN_LOOKUPFLW(new_xeno)] has been made into an alien by an event.")
new_xeno.log_message("was spawned as an alien by an event.", LOG_GAME)
Expand Down
2 changes: 0 additions & 2 deletions monkestation/code/__DEFINES/antag_defines.dm

This file was deleted.

23 changes: 16 additions & 7 deletions monkestation/code/controllers/subsystem/job.dm
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,10 @@
mass_adjust_antag_rep(cliented_list, 1)

var/list/weighted_candidates = return_antag_rep_weight(candidates)

var/antag_selection_loops = SSgamemode.current_roundstart_event.get_antag_amount()
for(var/i in 1 to antag_selection_loops)
var/iter = 0
while(iter < antag_selection_loops)
iter++
if(antag_selection_loops >= 100)
log_storyteller("h_r_a failed, antag_selection_loops went over 100")
return FALSE
Expand All @@ -78,7 +79,11 @@
log_storyteller("h_r_a failed, below required candidates for selected roundstart event")
return FALSE
break
var/client/dead_client = pick_n_take_weighted(weighted_candidates)
var/candidate_ckey = pick_n_take_weighted(weighted_candidates)
var/client/dead_client = GLOB.directory[candidate_ckey]
if(QDELETED(dead_client))
antag_selection_loops++
continue
var/mob/dead/new_player/candidate = dead_client.mob
if(!candidate.mind || !istype(candidate))
antag_selection_loops++
Expand All @@ -105,12 +110,16 @@
continue
var/mob/dead/new_player/candidate
var/sanity = 0
while(!candidate && length(weighted_candidates) && !sanity >= 100)
while(QDELETED(candidate) && length(weighted_candidates) && sanity < 100)
sanity++
candidate = pick_n_take_weighted(weighted_candidates)
if(!candidate.mind || !istype(candidate))
var/candidate_ckey = pick_n_take_weighted(weighted_candidates)
var/client/candidate_client = GLOB.directory[candidate_ckey]
if(QDELETED(candidate_client))
continue
candidate = candidate_client.mob
if(!isnewplayer(candidate) || QDELING(candidate) || QDELETED(candidate.mind))
candidate = null
if(!candidate)
if(QDELETED(candidate))
if(length(SSgamemode.roundstart_antag_minds) < SSgamemode.current_roundstart_event.base_antags)
log_storyteller("h_r_a failed, removing unassigned antag player put us below current event minimum candidates and we were unable to find a replacement")
return FALSE
Expand Down
2 changes: 0 additions & 2 deletions monkestation/code/modules/antagonists/_common/antag_datum.dm
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
/datum/antagonist
/// Allows antags to check exploitable info
antag_flags = FLAG_CAN_SEE_EXPOITABLE_INFO
///The list of keys that are valid to see our antag hud/of huds we can see
var/list/hud_keys
/// If this antagonist should be removed from the crew manifest upon gain.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@

/datum/antagonist/clock_cultist/eminence
name = "Eminence"
antag_flags = parent_type::antag_flags | FLAG_ANTAG_CAP_IGNORE
give_slab = FALSE
antag_moodlet = null
communicate = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
antagpanel_category = "Evil Clones"
show_name_in_check_antagonists = TRUE
show_to_ghosts = TRUE
antag_flags = parent_type::antag_flags | FLAG_ANTAG_CAP_IGNORE

/datum/antagonist/evil_clone/greet()
. = ..()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
show_in_roundend = FALSE
job_rank = ROLE_BLOODSUCKER
antag_hud_name = "bloodsucker"
antag_flags = parent_type::antag_flags | FLAG_ANTAG_CAP_IGNORE

/obj/item/soulstone/bloodsucker
theme = THEME_WIZARD
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
silent = TRUE
ui_name = FALSE
hud_icon = 'monkestation/icons/bloodsuckers/bloodsucker_icons.dmi'
antag_flags = FLAG_ANTAG_CAP_IGNORE

///The revenge vassal that brought us into the fold.
var/datum/antagonist/vassal/revenge/revenge_vassal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
roundend_category = "vassals"
antagpanel_category = "Bloodsucker"
job_rank = ROLE_BLOODSUCKER
antag_flags = parent_type::antag_flags | FLAG_ANTAG_CAP_IGNORE
antag_hud_name = "vassal"
show_in_roundend = FALSE
hud_icon = 'monkestation/icons/bloodsuckers/bloodsucker_icons.dmi'
Expand Down
18 changes: 6 additions & 12 deletions monkestation/code/modules/storytellers/antag_rep/helper_procs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -37,27 +37,21 @@ GLOBAL_LIST_INIT(blessed_ckeys, list(
///give it a list of clients and the value aswell if it should be affected by multipliers and let er rip
/proc/mass_adjust_antag_rep(list/clients, value, mulitplier = TRUE)
for(var/client/listed_client as anything in clients)
if(!listed_client.prefs || !IS_CLIENT_OR_MOCK(listed_client))
if(!IS_CLIENT_OR_MOCK(listed_client) || QDELETED(listed_client) || QDELETED(listed_client.prefs))
continue
listed_client.prefs.adjust_antag_rep(value, mulitplier)

/proc/return_antag_rep_weight(list/candidates)
var/list/returning_list = list()
. = list()
for(var/anything in candidates)
var/client/client_source
if(ismob(anything))
var/mob/mob = anything
client_source = mob.client
if(IS_CLIENT_OR_MOCK(anything))
else if(IS_CLIENT_OR_MOCK(anything))
client_source = anything
if(!client_source)
if(QDELETED(client_source) || !client_source.ckey)
continue
.[client_source.ckey] = client_source.prefs?.antag_rep || 10

returning_list += client_source
var/return_value = 10
if(client_source.prefs?.antag_rep)
return_value = client_source.prefs.antag_rep
returning_list[client_source] = return_value

log_antag_rep("Returned Weighted List of [length(returning_list)]", list("before_weight" = candidates, "after_weight" = returning_list))
return returning_list
log_antag_rep("Returned Weighted List of [length(.)]", list("before_weight" = candidates, "after_weight" = .))
Original file line number Diff line number Diff line change
Expand Up @@ -240,9 +240,12 @@

var/list/weighted_candidates = return_antag_rep_weight(possible_candidates)

while(length(possible_candidates) && length(candidates) < antag_count) //both of these pick_n_take from possible_candidates so this should be fine
while(length(weighted_candidates) && length(candidates) < antag_count) //both of these pick_n_take from weighted_candidates so this should be fine
if(prompted_picking)
var/client/picked_client = pick_n_take_weighted(weighted_candidates)
var/picked_ckey = pick_n_take_weighted(weighted_candidates)
var/client/picked_client = GLOB.directory[picked_ckey]
if(QDELETED(picked_client))
continue
var/mob/picked_mob = picked_client.mob
log_storyteller("Prompted antag event mob: [picked_mob], special role: [picked_mob.mind?.special_role ? picked_mob.mind.special_role : "none"]")
if(picked_mob)
Expand All @@ -258,9 +261,10 @@
show_candidate_amount = FALSE,
)
else
if(!length(weighted_candidates))
break
var/client/picked_client = pick_n_take_weighted(weighted_candidates)
var/picked_ckey = pick_n_take_weighted(weighted_candidates)
var/client/picked_client = GLOB.directory[picked_ckey]
if(QDELETED(picked_client))
continue
var/mob/picked_mob = picked_client.mob
log_storyteller("Picked antag event mob: [picked_mob], special role: [picked_mob.mind?.special_role ? picked_mob.mind.special_role : "none"]")
candidates |= picked_mob
Expand Down Expand Up @@ -353,22 +357,21 @@
)

var/list/weighted_candidates = return_antag_rep_weight(candidates)
var/selected_count = 0
while(length(weighted_candidates) && selected_count < antag_count)
var/candidate_ckey = pick_n_take_weighted(weighted_candidates)
var/client/candidate_client = GLOB.directory[candidate_ckey]
if(QDELETED(candidate_client) || QDELETED(candidate_client.mob))
continue
var/mob/candidate = candidate_client.mob

for(var/i in 1 to antag_count)
if(!length(weighted_candidates))
break

var/client/mob_client = pick_n_take_weighted(weighted_candidates)
var/mob/candidate = mob_client.mob

if(candidate.client) //I hate this
candidate.client.prefs.reset_antag_rep()
candidate_client.prefs?.reset_antag_rep()

if(!candidate.mind)
candidate.mind = new /datum/mind(candidate.key)

var/mob/living/carbon/human/new_human = make_body(candidate)
new_human.mind.special_role = antag_flag
new_human.mind.restricted_roles = restricted_roles
setup_minds += new_human.mind
selected_count++
setup = TRUE
Loading

0 comments on commit 3cc4b07

Please sign in to comment.