mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2025-12-10 01:49:19 +00:00
246 lines
10 KiB
Plaintext
246 lines
10 KiB
Plaintext
//////////////////////////////////////////////
|
|
// //
|
|
// LATEJOIN RULESETS //
|
|
// //
|
|
//////////////////////////////////////////////
|
|
|
|
/datum/dynamic_ruleset/latejoin/trim_candidates()
|
|
for(var/mob/P in candidates)
|
|
if (!P.client || !P.mind || !P.mind.assigned_role) // Are they connected?
|
|
candidates.Remove(P)
|
|
continue
|
|
if(!mode.check_age(P.client, minimum_required_age))
|
|
candidates.Remove(P)
|
|
continue
|
|
if(antag_flag_override)
|
|
if(!(antag_flag_override in P.client.prefs.be_special) || jobban_isbanned(P.ckey, list(antag_flag_override)))
|
|
candidates.Remove(P)
|
|
continue
|
|
else
|
|
if(!(antag_flag in P.client.prefs.be_special) || jobban_isbanned(P.ckey, list(antag_flag, ROLE_SYNDICATE)))
|
|
candidates.Remove(P)
|
|
continue
|
|
if (P.mind.assigned_role in restricted_roles) // Does their job allow for it?
|
|
candidates.Remove(P)
|
|
continue
|
|
if ((exclusive_roles.len > 0) && !(P.mind.assigned_role in exclusive_roles)) // Is the rule exclusive to their job?
|
|
candidates.Remove(P)
|
|
continue
|
|
|
|
/datum/dynamic_ruleset/latejoin/ready(forced = 0)
|
|
if (!forced)
|
|
var/job_check = 0
|
|
if (enemy_roles.len > 0)
|
|
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 && (M.mind.assigned_role in enemy_roles) && (!(M in candidates) || (M.mind.assigned_role in restricted_roles)))
|
|
job_check++ // Checking for "enemies" (such as sec officers). To be counters, they must either not be candidates to that rule, or have a job that restricts them from it
|
|
var/threat = round(mode.threat_level/10)
|
|
if (job_check < required_enemies[threat])
|
|
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough enemy roles")
|
|
return FALSE
|
|
return ..()
|
|
|
|
/datum/dynamic_ruleset/latejoin/execute()
|
|
var/mob/M = pick(candidates)
|
|
assigned += M.mind
|
|
M.mind.special_role = antag_flag
|
|
M.mind.add_antag_datum(antag_datum)
|
|
log_admin("[M.name] was made into a [name] by dynamic.")
|
|
message_admins("[M.name] was made into a [name] by dynamic.")
|
|
return TRUE
|
|
|
|
//////////////////////////////////////////////
|
|
// //
|
|
// SYNDICATE TRAITORS //
|
|
// //
|
|
//////////////////////////////////////////////
|
|
|
|
/datum/dynamic_ruleset/latejoin/infiltrator
|
|
name = "Syndicate Infiltrator"
|
|
config_tag = "latejoin_traitor"
|
|
antag_datum = /datum/antagonist/traitor
|
|
antag_flag = ROLE_TRAITOR
|
|
restricted_roles = list("AI", "Cyborg")
|
|
protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
|
|
required_candidates = 1
|
|
weight = 7
|
|
cost = 5
|
|
requirements = list(40,30,20,15,15,15,15,15,15,15)
|
|
high_population_requirement = 15
|
|
repeatable = TRUE
|
|
flags = TRAITOR_RULESET
|
|
property_weights = list("story_potential" = 2, "trust" = -1, "extended" = 1)
|
|
always_max_weight = TRUE
|
|
|
|
//////////////////////////////////////////////
|
|
// //
|
|
// REVOLUTIONARY PROVOCATEUR //
|
|
// //
|
|
//////////////////////////////////////////////
|
|
|
|
/datum/dynamic_ruleset/latejoin/provocateur
|
|
name = "Provocateur"
|
|
persistent = TRUE
|
|
config_tag = "latejoin_revolution"
|
|
antag_datum = /datum/antagonist/rev/head
|
|
antag_flag = ROLE_REV_HEAD
|
|
antag_flag_override = ROLE_REV
|
|
restricted_roles = list("AI", "Cyborg", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
|
|
enemy_roles = list("AI", "Cyborg", "Security Officer","Detective","Head of Security", "Captain", "Warden")
|
|
required_enemies = list(4,4,3,3,3,3,3,2,2,1)
|
|
required_candidates = 1
|
|
weight = 2
|
|
delay = 1 MINUTES // Prevents rule start while head is offstation.
|
|
cost = 20
|
|
requirements = list(101,101,70,40,40,40,40,40,40,40)
|
|
high_population_requirement = 40
|
|
flags = HIGHLANDER_RULESET
|
|
property_weights = list("trust" = -2, "chaos" = 2, "extended" = -2, "valid" = 2, "conversion" = 1)
|
|
var/required_heads_of_staff = 3
|
|
var/finished = FALSE
|
|
var/datum/team/revolution/revolution
|
|
|
|
/datum/dynamic_ruleset/latejoin/provocateur/ready(forced=FALSE)
|
|
if (forced)
|
|
required_heads_of_staff = 1
|
|
if(!..())
|
|
return FALSE
|
|
var/head_check = 0
|
|
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)
|
|
|
|
/datum/dynamic_ruleset/latejoin/provocateur/execute()
|
|
var/mob/M = pick(candidates) // This should contain a single player, but in case.
|
|
if(check_eligible(M.mind)) // Didnt die/run off z-level/get implanted since leaving shuttle.
|
|
assigned += M.mind
|
|
M.mind.special_role = antag_flag
|
|
revolution = new()
|
|
var/datum/antagonist/rev/head/new_head = new()
|
|
new_head.give_flash = TRUE
|
|
new_head.give_hud = TRUE
|
|
new_head.remove_clumsy = TRUE
|
|
new_head = M.mind.add_antag_datum(new_head, revolution)
|
|
revolution.update_objectives()
|
|
revolution.update_heads()
|
|
SSshuttle.registerHostileEnvironment(src)
|
|
log_admin("[M.name] was made into a revolutionary by dynamic.")
|
|
message_admins("[M.name] was made into a revolutionary by dynamic.")
|
|
return TRUE
|
|
else
|
|
log_game("DYNAMIC: [ruletype] [name] discarded [M.name] from head revolutionary due to ineligibility.")
|
|
log_game("DYNAMIC: [ruletype] [name] failed to get any eligible headrevs. Refunding [cost] threat.")
|
|
return FALSE
|
|
|
|
/datum/dynamic_ruleset/latejoin/provocateur/rule_process()
|
|
if(check_rev_victory())
|
|
finished = REVOLUTION_VICTORY
|
|
return RULESET_STOP_PROCESSING
|
|
else if (check_heads_victory())
|
|
finished = STATION_VICTORY
|
|
SSshuttle.clearHostileEnvironment(src)
|
|
priority_announce("It appears the mutiny has been quelled. Please return yourself and your colleagues to work. \
|
|
We have remotely blacklisted the head revolutionaries from your cloning software to prevent accidental cloning.", null, "attention", null, "Central Command Loyalty Monitoring Division")
|
|
for(var/datum/mind/M in revolution.members) // Remove antag datums and prevent headrev cloning then restarting rebellions.
|
|
if(M.has_antag_datum(/datum/antagonist/rev/head))
|
|
var/datum/antagonist/rev/head/R = M.has_antag_datum(/datum/antagonist/rev/head)
|
|
R.remove_revolutionary(FALSE, "gamemode")
|
|
var/mob/living/carbon/C = M.current
|
|
if(C.stat == DEAD)
|
|
C.makeUncloneable()
|
|
if(M.has_antag_datum(/datum/antagonist/rev))
|
|
var/datum/antagonist/rev/R = M.has_antag_datum(/datum/antagonist/rev)
|
|
R.remove_revolutionary(FALSE, "gamemode")
|
|
return RULESET_STOP_PROCESSING
|
|
|
|
/// Checks for revhead loss conditions and other antag datums.
|
|
/datum/dynamic_ruleset/latejoin/provocateur/proc/check_eligible(var/datum/mind/M)
|
|
var/turf/T = get_turf(M.current)
|
|
if(!considered_afk(M) && considered_alive(M) && is_station_level(T.z) && !M.antag_datums?.len && !HAS_TRAIT(M, TRAIT_MINDSHIELD))
|
|
return TRUE
|
|
return FALSE
|
|
|
|
/datum/dynamic_ruleset/latejoin/provocateur/check_finished()
|
|
if(finished == REVOLUTION_VICTORY)
|
|
return TRUE
|
|
else
|
|
return ..()
|
|
|
|
/datum/dynamic_ruleset/latejoin/provocateur/proc/check_rev_victory()
|
|
for(var/datum/objective/mutiny/objective in revolution.objectives)
|
|
if(!(objective.check_completion()))
|
|
return FALSE
|
|
return TRUE
|
|
|
|
/datum/dynamic_ruleset/latejoin/provocateur/proc/check_heads_victory()
|
|
for(var/datum/mind/rev_mind in revolution.head_revolutionaries())
|
|
var/turf/T = get_turf(rev_mind.current)
|
|
if(!considered_afk(rev_mind) && considered_alive(rev_mind) && is_station_level(T.z))
|
|
if(ishuman(rev_mind.current) || ismonkey(rev_mind.current))
|
|
return FALSE
|
|
return TRUE
|
|
|
|
/datum/dynamic_ruleset/latejoin/provocateur/round_result()
|
|
if(finished == REVOLUTION_VICTORY)
|
|
SSticker.mode_result = "win - heads killed"
|
|
SSticker.news_report = REVS_WIN
|
|
else if(finished == STATION_VICTORY)
|
|
SSticker.mode_result = "loss - rev heads killed"
|
|
SSticker.news_report = REVS_LOSE
|
|
|
|
//////////////////////////////////////////////
|
|
// //
|
|
// BLOODSUCKERS //
|
|
// //
|
|
//////////////////////////////////////////////
|
|
|
|
/datum/dynamic_ruleset/latejoin/bloodsucker
|
|
name = "Bloodsucker Infiltrator"
|
|
config_tag = "latejoin_bloodsucker"
|
|
antag_datum = ANTAG_DATUM_BLOODSUCKER
|
|
antag_flag = ROLE_TRAITOR
|
|
restricted_roles = list("AI", "Cyborg")
|
|
protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
|
|
required_candidates = 1
|
|
weight = 3
|
|
cost = 10
|
|
property_weights = list("story_potential" = 2, "extended" = 2, "trust" = -2, "valid" = 1)
|
|
requirements = list(70,65,60,55,50,45,40,35,30,30)
|
|
high_population_requirement = 30
|
|
repeatable = TRUE
|
|
|
|
/datum/dynamic_ruleset/latejoin/bloodsucker/execute()
|
|
var/mob/M = pick(candidates)
|
|
assigned += M.mind
|
|
M.mind.special_role = antag_flag
|
|
if(mode.make_bloodsucker(M.mind))
|
|
mode.bloodsuckers += M
|
|
log_admin("[M.name] was made into a bloodsucker by dynamic.")
|
|
message_admins("[M.name] was made into a bloodsucker by dynamic.")
|
|
return TRUE
|
|
|
|
//////////////////////////////////////////////
|
|
// //
|
|
// COLLECTOR //
|
|
// //
|
|
//////////////////////////////////////////////
|
|
|
|
/datum/dynamic_ruleset/latejoin/collector
|
|
name = "Contraband Collector"
|
|
config_tag = "latejoin_collector"
|
|
antag_datum = /datum/antagonist/collector
|
|
antag_flag = ROLE_MINOR_ANTAG
|
|
restricted_roles = list("AI", "Cyborg")
|
|
protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
|
|
required_candidates = 1
|
|
weight = 5
|
|
cost = 1
|
|
requirements = list(10,10,10,10,10,10,10,10,10,10)
|
|
high_population_requirement = 10
|
|
repeatable = TRUE
|
|
flags = TRAITOR_RULESET
|
|
property_weights = list("story_potential" = 2, "trust" = -1, "extended" = 2)
|