Adds configs for hijack population minimums (#31206)

* add config for hijack pop lock

* woopsie daisy

* doth this please you, your lintliness?

* nerd emoji

* address DGL's most beauteous code review
This commit is contained in:
Pooble
2025-12-29 13:49:45 +00:00
committed by GitHub
parent 00eb823fe6
commit 8e79d6c089
10 changed files with 88 additions and 6 deletions
+18
View File
@@ -384,6 +384,24 @@
return active_players
/// Get living players who are playing in the round (no ghosts)
/proc/get_living_players_count()
var/count = 0
for(var/mob/living/carbon/human/player in GLOB.human_list)
if(player.mind && player.stat != DEAD && player.client)
count++
return count
/// Same as above but only count Sec
/datum/antagonist/traitor/proc/get_living_security_players_count()
var/count = 0
for(var/mob/living/carbon/human/player in GLOB.human_list)
if(!player.mind || player.stat == DEAD || !player.client)
continue
if(player.mind.assigned_role in GLOB.active_security_positions)
count++
return count
/proc/mobs_in_area(area/the_area, client_needed=0, moblist=GLOB.mob_list)
var/list/mobs_found[0]
for(var/mob/M in moblist)
+2
View File
@@ -6,5 +6,7 @@ GLOBAL_DATUM(start_state, /datum/station_state) // Used in round-end report. Don
GLOBAL_VAR(custom_event_msg)
GLOBAL_VAR(roundstart_ready_players) // Number of players who were readied up at roundstart
/// We want anomalous_particulate_tracker to exist only once and be accessible from anywhere.
GLOBAL_DATUM_INIT(anomaly_smash_track, /datum/anomalous_particulate_tracker, new)
@@ -22,6 +22,12 @@
var/enable_gamemode_player_limit = TRUE
/// Should we generate random station traits at game start?
var/add_random_station_traits = TRUE
/// Minimum readied up players required for roundstart hijack objectives
var/min_players_hijack_roundstart = 30
/// Minimum alive crew required for midround hijack objectives
var/min_players_hijack_midround = 20
/// Minimum living security required for midround hijack objectives
var/min_security_hijack_midround = 2
// Dynamically setup a list of all gamemodes
/datum/configuration_section/gamemode_configuration/New()
@@ -57,6 +63,10 @@
CONFIG_LOAD_NUM(traitor_objectives_amount, data["traitor_objective_amount"])
CONFIG_LOAD_NUM(min_players_hijack_roundstart, data["min_players_hijack_roundstart"])
CONFIG_LOAD_NUM(min_players_hijack_midround, data["min_players_hijack_midround"])
CONFIG_LOAD_NUM(min_security_hijack_midround, data["min_security_hijack_midround"])
// Load gamemode probabilities
if(islist(data["gamemode_probabilities"]))
for(var/list/assocset in data["gamemode_probabilities"])
+7
View File
@@ -276,6 +276,13 @@ SUBSYSTEM_DEF(ticker)
// Behold, a rough way of figuring out what takes 10 years
var/watch = start_watch()
// Count ready players before we spawn them for hijack objective requirements
GLOB.roundstart_ready_players = 0
for(var/mob/new_player/player in GLOB.new_player_mobs)
if(player.ready && player.client)
GLOB.roundstart_ready_players++
create_characters() // Create player characters and transfer clients
log_debug("Creating characters took [stop_watch(watch)]s")
@@ -200,6 +200,7 @@
if(ishuman(antag.current))
traitor_datum.delayed_objectives = TRUE
traitor_datum.addtimer(CALLBACK(traitor_datum, TYPE_PROC_REF(/datum/antagonist/traitor, reveal_delayed_objectives)), latespawn_time, TIMER_DELETE_ME)
traitor_datum.is_roundstart = TRUE
antag.add_antag_datum(traitor_datum)
SSblackbox.record_feedback("nested tally", "dynamic_selections", 1, list("roundstart", "[antagonist_type]"))
+1
View File
@@ -58,6 +58,7 @@
traitor_datum.delayed_objectives = TRUE
traitor_datum.addtimer(CALLBACK(traitor_datum, TYPE_PROC_REF(/datum/antagonist/traitor, reveal_delayed_objectives)), random_time, TIMER_DELETE_ME)
traitor_datum.is_roundstart = TRUE
traitor.add_antag_datum(traitor_datum)
/datum/game_mode/traitor/traitors_to_add()
+1
View File
@@ -123,6 +123,7 @@
traitor_datum.delayed_objectives = TRUE
traitor_datum.addtimer(CALLBACK(traitor_datum, TYPE_PROC_REF(/datum/antagonist/traitor, reveal_delayed_objectives)), random_time, TIMER_DELETE_ME)
traitor_datum.is_roundstart = TRUE
traitor.add_antag_datum(traitor_datum)
..()
@@ -405,6 +405,12 @@ GLOBAL_LIST_EMPTY(antagonists)
/datum/antagonist/proc/finalize_antag()
return
/**
* Check if this antag can be assigned hijack.
*/
/datum/antagonist/proc/can_assign_hijack_objective()
return FALSE
/**
* Create and assign a full set of randomized, basic human traitor objectives.
* can_hijack - If you want the 5% chance for the antagonist to be able to roll hijack, only true for traitors
@@ -412,11 +418,13 @@ GLOBAL_LIST_EMPTY(antagonists)
/datum/antagonist/proc/forge_basic_objectives(can_hijack = FALSE, number_of_objectives = GLOB.configuration.gamemode.traitor_objectives_amount)
// Hijack objective.
if(can_hijack && prob(5) && !(locate(/datum/objective/hijack) in owner.get_all_objectives()))
if(prob(50)) // 50% chance you have to detonate the nuke instead
add_antag_objective(/datum/objective/nuke)
return
add_antag_objective(/datum/objective/hijack)
return // Hijack should be their only objective (normally), so return.
// Check if hijack is allowed based on player count and number of sec
if(can_assign_hijack_objective())
if(prob(50)) // 50% chance you have to detonate the nuke instead
add_antag_objective(/datum/objective/nuke)
return
add_antag_objective(/datum/objective/hijack)
return // Hijack should be their only objective (normally), so return.
// Will give normal steal/kill/etc. type objectives.
for(var/i in 1 to number_of_objectives)
@@ -21,6 +21,8 @@ RESTRICT_TYPE(/datum/antagonist/traitor)
/// Have we / are we sending a backstab message at this time. If we are, do not send another.
var/sending_backstab = FALSE
/// Whether this traitor was assigned during round start
var/is_roundstart = FALSE
/datum/antagonist/traitor/on_gain()
// Create this in case the traitor wants to mindslaves someone.
@@ -90,7 +92,14 @@ RESTRICT_TYPE(/datum/antagonist/traitor)
/datum/antagonist/traitor/select_organization()
if(is_ai(owner.current))
return
var/chaos = pickweight(list(ORG_CHAOS_HUNTER = ORG_PROB_HUNTER, ORG_CHAOS_MILD = ORG_PROB_MILD, ORG_CHAOS_AVERAGE = ORG_PROB_AVERAGE, ORG_CHAOS_HIJACK = ORG_PROB_HIJACK))
var/list/chaos_weights = list(
ORG_CHAOS_HUNTER = ORG_PROB_HUNTER,
ORG_CHAOS_MILD = ORG_PROB_MILD,
ORG_CHAOS_AVERAGE = ORG_PROB_AVERAGE
)
if(can_assign_hijack_objective())
chaos_weights[ORG_CHAOS_HIJACK] = ORG_PROB_HIJACK
var/chaos = pickweight(chaos_weights)
for(var/org_type in shuffle(subtypesof(/datum/antag_org/syndicate)))
var/datum/antag_org/org = org_type
if(initial(org.chaos_level) == chaos)
@@ -344,3 +353,21 @@ RESTRICT_TYPE(/datum/antagonist/traitor)
var/list/messages = owner.prepare_announce_objectives()
to_chat(owner.current, chat_box_red(messages.Join("<br>")))
SEND_SOUND(owner.current, sound('sound/ambience/alarm4.ogg'))
/// Helper functions for hijack pop checks
/datum/antagonist/traitor/can_assign_hijack_objective()
var/total_players
if(is_roundstart)
total_players = GLOB.roundstart_ready_players
if(total_players < GLOB.configuration.gamemode.min_players_hijack_roundstart)
return FALSE
return TRUE
total_players = get_living_players_count()
if(total_players < GLOB.configuration.gamemode.min_players_hijack_midround)
return FALSE
var/security_count = get_living_security_players_count()
if(security_count < GLOB.configuration.gamemode.min_security_hijack_midround)
return FALSE
return TRUE
+7
View File
@@ -285,6 +285,13 @@ enable_gamemode_player_limit = true
# Enable to generate zero or more random station traits on game start.
add_random_station_traits = false
# Minimum readied up players required for roundstart hijack objectives
min_players_hijack_roundstart = 30
# Minimum alive crew required for midround hijack objectives
min_players_hijack_midround = 20
# Minimum security required for midround hijack objectives
min_security_hijack_midround = 2
################################################################
[general_configuration]