mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-18 18:44:48 +01:00
Cult is now part of dynamic (#28236)
* Adds cult to dynamic * declare result * more dynamic stuff * config * comment * tweaks * numbers changes
This commit is contained in:
@@ -80,5 +80,7 @@
|
||||
#define DYNAMIC_RULESET_BANNED "<b>Banned</b>"
|
||||
|
||||
#define RULESET_FAILURE_BUDGET "Not enough budget"
|
||||
#define RULESET_FAILURE_ANTAG_BUDGET "Not enough antag budget"
|
||||
#define RULESET_FAILURE_NO_PLAYERS "No drafted players"
|
||||
#define RULESET_FAILURE_MUTUAL_RULESET "No banned mutual rulesets"
|
||||
#define RULESET_FAILURE_CHANGELING_SECONDARY_RULESET "Needs a secondary ruleset in rotation"
|
||||
|
||||
@@ -42,7 +42,10 @@
|
||||
/// If true, the species blacklist is now a species whitelist
|
||||
var/banned_species_only = FALSE
|
||||
|
||||
// var/list/banned_mutual_rulesets = list() // UNIMPLEMENTED: could be used to prevent nukies rolling while theres cultists, or wizards, etc
|
||||
/// Rulesets that cannot be rolled while this ruleset is active. Used to prevent traitors from rolling while theres cultists, etc.
|
||||
var/list/banned_mutual_rulesets = list(
|
||||
/datum/ruleset/team/cult,
|
||||
)
|
||||
|
||||
/* This stuff changes, all stuff above is static */
|
||||
/// How many antagonists to spawn
|
||||
@@ -56,11 +59,17 @@
|
||||
stack_trace("[src] ([type]) was destroyed.")
|
||||
return ..()
|
||||
|
||||
/datum/ruleset/proc/ruleset_possible(ruleset_budget, rulesets)
|
||||
/datum/ruleset/proc/ruleset_possible(ruleset_budget, rulesets, antag_budget)
|
||||
if(ruleset_budget < ruleset_cost)
|
||||
return RULESET_FAILURE_BUDGET
|
||||
if(antag_budget < antag_cost)
|
||||
return RULESET_FAILURE_ANTAG_BUDGET
|
||||
if(!length(SSticker.mode.get_players_for_role(antagonist_type::job_rank))) // this specifically needs to be job_rank not special_rank
|
||||
return RULESET_FAILURE_NO_PLAYERS
|
||||
if(length(banned_mutual_rulesets) && length(rulesets))
|
||||
for(var/datum/ruleset/ruleset in rulesets)
|
||||
if(ruleset.type in banned_mutual_rulesets)
|
||||
return RULESET_FAILURE_MUTUAL_RULESET
|
||||
|
||||
/datum/ruleset/proc/antagonist_possible(budget)
|
||||
return budget >= antag_cost
|
||||
@@ -148,8 +157,8 @@
|
||||
|
||||
/datum/ruleset/proc/latespawn(datum/game_mode/dynamic/dynamic)
|
||||
// latespawning is only used by traitors at this point, so we're just going to be naive and allocate all budget when this proc is called.
|
||||
var/late_antag_amount = floor(dynamic.budget_overflow / antag_cost)
|
||||
dynamic.budget_overflow -= (late_antag_amount * antag_cost)
|
||||
var/late_antag_amount = floor(dynamic.antag_budget / antag_cost)
|
||||
dynamic.antag_budget -= (late_antag_amount * antag_cost)
|
||||
|
||||
var/list/datum/mind/possible_antags = get_latejoin_players()
|
||||
for(var/i in 1 to late_antag_amount)
|
||||
@@ -158,6 +167,13 @@
|
||||
|
||||
log_dynamic("Latespawned [late_antag_amount] [name]s.")
|
||||
|
||||
/datum/ruleset/proc/automatic_deduct(budget)
|
||||
. = antag_cost * antag_amount
|
||||
log_dynamic("Automatic deduction: +[antag_amount] [name]\s. Remaining budget: [budget - .].")
|
||||
|
||||
/datum/ruleset/proc/declare_completion()
|
||||
return
|
||||
|
||||
/datum/ruleset/traitor
|
||||
name = "Traitor"
|
||||
ruleset_weight = 11
|
||||
@@ -205,6 +221,7 @@
|
||||
|
||||
// This is the fucking worst, but its required to not change functionality with mindflayers. Cannot be rolled normally, this is applied by other methods.
|
||||
/datum/ruleset/implied
|
||||
name = "BASE IMPLIED RULESET"
|
||||
// These 3 variables should never change
|
||||
ruleset_cost = 0
|
||||
ruleset_weight = 0
|
||||
@@ -234,3 +251,56 @@
|
||||
implier.antag_amount -= 1
|
||||
antag_amount += 1
|
||||
was_triggered = TRUE
|
||||
|
||||
/datum/ruleset/team
|
||||
name = "BASE TEAM RULESET"
|
||||
ruleset_weight = 0
|
||||
/// Whether there should only be one of this kind of team. This could be used for blood-brothers if false.
|
||||
var/unique_team = TRUE
|
||||
/// How many players on a team.
|
||||
var/team_size = 1
|
||||
/// Team datum to create.
|
||||
var/datum/team/team_type
|
||||
|
||||
/datum/ruleset/team/roundstart_post_setup(datum/game_mode/dynamic)
|
||||
if(unique_team)
|
||||
new team_type(pre_antags)
|
||||
return
|
||||
stack_trace("Undefined behavior for dynamic non-unique teams!")
|
||||
|
||||
/datum/ruleset/team/automatic_deduct(budget)
|
||||
antag_amount = team_size
|
||||
. = ..()
|
||||
|
||||
/datum/ruleset/team/antagonist_possible(budget)
|
||||
if(unique_team) // we're given our size at the start, no more please!
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/ruleset/team/cult
|
||||
name = "Cultist"
|
||||
ruleset_cost = 1
|
||||
ruleset_weight = 3
|
||||
// antag_weight doesnt matter, since we've already allocated our budget for 4 cultists only
|
||||
antag_cost = 30
|
||||
antagonist_type = /datum/antagonist/cultist
|
||||
banned_mutual_rulesets = list(
|
||||
/datum/ruleset/traitor,
|
||||
/datum/ruleset/vampire,
|
||||
/datum/ruleset/changeling
|
||||
)
|
||||
banned_jobs = list("Cyborg", "AI", "Chaplain", "Head of Personnel")
|
||||
|
||||
team_size = 4
|
||||
team_type = /datum/team/cult
|
||||
|
||||
/datum/ruleset/team/cult/declare_completion()
|
||||
if(SSticker.mode.cult_team.cult_status == NARSIE_HAS_RISEN)
|
||||
SSticker.mode_result = "cult win - cult win"
|
||||
to_chat(world, "<span class='danger'><FONT size=3>The cult wins! It has succeeded in summoning [GET_CULT_DATA(entity_name, "their god")]!</FONT></span>")
|
||||
else if(SSticker.mode.cult_team.cult_status == NARSIE_HAS_FALLEN)
|
||||
SSticker.mode_result = "cult draw - narsie died, nobody wins"
|
||||
to_chat(world, "<span class='danger'><FONT size = 3>Nobody wins! [GET_CULT_DATA(entity_name, "the cult god")] was summoned, but banished!</FONT></span>")
|
||||
else
|
||||
SSticker.mode_result = "cult loss - staff stopped the cult"
|
||||
to_chat(world, "<span class='warning'><FONT size = 3>The staff managed to stop the cult!</FONT></span>")
|
||||
|
||||
@@ -10,7 +10,7 @@ GLOBAL_LIST_EMPTY(dynamic_forced_rulesets)
|
||||
var/list/datum/ruleset/implied_rulesets = list()
|
||||
|
||||
/// How much budget is left after roundstart antagonists roll
|
||||
var/budget_overflow = 0
|
||||
var/antag_budget = 0
|
||||
|
||||
/// Log for what happens in a dynamic round
|
||||
var/list/dynamic_log = list()
|
||||
@@ -27,7 +27,8 @@ GLOBAL_LIST_EMPTY(dynamic_forced_rulesets)
|
||||
to_chat(world, "<b>Possible Rulesets:</b> [english_list(possible_rulesets)]")
|
||||
|
||||
/datum/game_mode/dynamic/proc/allocate_ruleset_budget()
|
||||
var/ruleset_budget = text2num(GLOB.dynamic_forced_rulesets["budget"] || pickweight(list("0" = 3, "1" = 5, "2" = 12, "3" = 3))) // more likely to or 2
|
||||
var/ruleset_budget = text2num(GLOB.dynamic_forced_rulesets["budget"] || pickweight(list("0" = 3, "1" = 8, "2" = 12, "3" = 3)))
|
||||
antag_budget = num_players()
|
||||
log_dynamic("Allocated gamemode budget: [ruleset_budget]")
|
||||
var/list/possible_rulesets = list()
|
||||
for(var/datum/ruleset/ruleset as anything in subtypesof(/datum/ruleset))
|
||||
@@ -68,9 +69,9 @@ GLOBAL_LIST_EMPTY(dynamic_forced_rulesets)
|
||||
if(!ruleset)
|
||||
return
|
||||
if(!force)
|
||||
var/failure_reason = ruleset.ruleset_possible(ruleset_budget, rulesets)
|
||||
var/failure_reason = ruleset.ruleset_possible(ruleset_budget, rulesets, antag_budget)
|
||||
if(failure_reason)
|
||||
log_dynamic("Failed [ruleset.name] ruleset: [failure_reason]")
|
||||
log_dynamic("Failed [ruleset.name] ruleset: [failure_reason].")
|
||||
return
|
||||
log_dynamic("Rolled ruleset: [ruleset.name]")
|
||||
rulesets[ruleset] = ruleset.antag_weight
|
||||
@@ -89,33 +90,30 @@ GLOBAL_LIST_EMPTY(dynamic_forced_rulesets)
|
||||
if(!length(rulesets))
|
||||
log_dynamic("No rulesets in play.")
|
||||
return
|
||||
var/budget = num_players()
|
||||
log_dynamic("Allocated antagonist budget: [budget].")
|
||||
log_dynamic("Allocated antagonist budget: [antag_budget].")
|
||||
|
||||
for(var/datum/ruleset/ruleset in rulesets)
|
||||
ruleset.antag_amount = 1
|
||||
budget -= ruleset.antag_cost
|
||||
log_dynamic("Automatic deduction: +1 [ruleset.name]. Remaining budget: [budget].")
|
||||
antag_budget -= ruleset.automatic_deduct(antag_budget)
|
||||
|
||||
log_dynamic("Rulesets in play: [english_list((rulesets + implied_rulesets))]")
|
||||
|
||||
apply_antag_budget(budget)
|
||||
apply_antag_budget()
|
||||
|
||||
/datum/game_mode/dynamic/proc/apply_antag_budget(budget) // todo, can be called later in the game to apply more budget. That also means there has to be shit done for latejoins.
|
||||
/datum/game_mode/dynamic/proc/apply_antag_budget() // todo, can be called later in the game to apply more budget. That also means there has to be shit done for latejoins.
|
||||
var/list/temp_rulesets = rulesets.Copy()
|
||||
while(budget >= 0)
|
||||
while(antag_budget >= 0)
|
||||
var/datum/ruleset/ruleset = pickweight(temp_rulesets)
|
||||
if(!ruleset)
|
||||
log_dynamic("No rulesets remaining. Remaining budget: [budget].")
|
||||
budget_overflow = budget
|
||||
log_dynamic("No rulesets remaining. Remaining budget: [antag_budget].")
|
||||
return
|
||||
if(!ruleset.antagonist_possible(budget))
|
||||
if(!ruleset.antagonist_possible(antag_budget))
|
||||
log_dynamic("Rolled [ruleset.name]: failed, removing [ruleset.name] ruleset.")
|
||||
temp_rulesets -= ruleset
|
||||
continue
|
||||
ruleset.antag_amount++
|
||||
budget -= ruleset.antag_cost
|
||||
log_dynamic("Rolled [ruleset.name]: success, +1 [ruleset.name]. Remaining budget: [budget].")
|
||||
antag_budget -= ruleset.antag_cost
|
||||
log_dynamic("Rolled [ruleset.name]: success, +1 [ruleset.name]. Remaining budget: [antag_budget].")
|
||||
log_dynamic("No more antagonist budget remaining.")
|
||||
|
||||
/datum/game_mode/dynamic/pre_setup()
|
||||
@@ -128,10 +126,10 @@ GLOBAL_LIST_EMPTY(dynamic_forced_rulesets)
|
||||
|
||||
for(var/datum/ruleset/ruleset in (rulesets + implied_rulesets)) // rulesets first, then implied rulesets
|
||||
log_dynamic("Applying [ruleset.antag_amount] [ruleset.name]\s.")
|
||||
budget_overflow += ruleset.roundstart_pre_setup()
|
||||
antag_budget += ruleset.roundstart_pre_setup()
|
||||
|
||||
log_dynamic("Budget overflow: [budget_overflow].")
|
||||
// for the future, maybe try readding antagonists with apply_antag_budget(budget_overflow)
|
||||
log_dynamic("Budget overflow: [antag_budget].")
|
||||
// for the future, maybe try readding antagonists with apply_antag_budget(antag_budget)
|
||||
log_dynamic("Finished dynamic setup in [stop_watch(watch)]s.")
|
||||
return TRUE
|
||||
|
||||
@@ -147,19 +145,19 @@ GLOBAL_LIST_EMPTY(dynamic_forced_rulesets)
|
||||
|
||||
/datum/game_mode/dynamic/latespawn(mob)
|
||||
. = ..()
|
||||
budget_overflow++
|
||||
antag_budget++
|
||||
|
||||
/datum/game_mode/dynamic/on_mob_cryo(mob/sleepy_mob, obj/machinery/cryopod/cryopod)
|
||||
var/turf/T = get_turf(cryopod)
|
||||
if(!T || is_admin_level(T.z))
|
||||
return
|
||||
budget_overflow--
|
||||
antag_budget--
|
||||
if(!sleepy_mob.mind || !length(sleepy_mob.mind.antag_datums))
|
||||
return
|
||||
for(var/datum/antagonist/antag in sleepy_mob.mind.antag_datums)
|
||||
for(var/datum/ruleset/possible_ruleset as anything in subtypesof(/datum/ruleset))
|
||||
if(istype(antag, possible_ruleset.antagonist_type))
|
||||
budget_overflow += possible_ruleset.antag_cost
|
||||
antag_budget += possible_ruleset.antag_cost
|
||||
log_dynamic("[possible_ruleset] cryo. +[possible_ruleset.antag_cost] budget.")
|
||||
|
||||
/datum/game_mode/dynamic/get_webhook_name()
|
||||
@@ -169,6 +167,11 @@ GLOBAL_LIST_EMPTY(dynamic_forced_rulesets)
|
||||
implied_and_used += implied
|
||||
return "[name] ([english_list(rulesets + implied_and_used, nothing_text = "Extended")])"
|
||||
|
||||
/datum/game_mode/dynamic/declare_completion()
|
||||
for(var/datum/ruleset/ruleset in rulesets)
|
||||
ruleset.declare_completion()
|
||||
. = ..()
|
||||
|
||||
/proc/log_dynamic(text)
|
||||
log_game("Dynamic: [text]")
|
||||
var/datum/game_mode/dynamic/dynamic = SSticker.mode
|
||||
|
||||
@@ -1056,7 +1056,7 @@
|
||||
if(GLOB.master_mode != "dynamic" && !(GLOB.master_mode == "secret" && GLOB.secret_force_mode == "dynamic"))
|
||||
return alert(usr, "The game mode has to be dynamic!", null, null, null, null)
|
||||
var/dat = {"<!DOCTYPE html><b>Possible Rulesets:</b><hr>"}
|
||||
var/list/rulesets = subtypesof(/datum/ruleset) - typesof(/datum/ruleset/implied)
|
||||
var/list/rulesets = subtypesof(/datum/ruleset) - typesof(/datum/ruleset/implied) - /datum/ruleset/team
|
||||
dat += {"Budget: <a href='byond://?src=[UID()];f_dynamic2=budget'>[isnull(GLOB.dynamic_forced_rulesets["budget"]) ? "Random" : GLOB.dynamic_forced_rulesets["budget"]]</a><hr>"}
|
||||
for(var/datum/ruleset/ruleset as anything in rulesets)
|
||||
dat += {"[ruleset.name]: <a href='byond://?src=[UID()];f_dynamic2=[ruleset.type]'>[GLOB.dynamic_forced_rulesets[ruleset] || DYNAMIC_RULESET_NORMAL]</a><br>"}
|
||||
|
||||
@@ -261,7 +261,7 @@ antag_account_age_restrictions = false
|
||||
gamemode_probabilities = [
|
||||
{ gamemode = "abduction", probability = 0 },
|
||||
{ gamemode = "changeling", probability = 0 },
|
||||
{ gamemode = "cult", probability = 3 },
|
||||
{ gamemode = "cult", probability = 0 },
|
||||
{ gamemode = "extend-a-traitormongous", probability = 2 }, # Autotraitor
|
||||
{ gamemode = "extended", probability = 0 },
|
||||
{ gamemode = "nuclear", probability = 2 },
|
||||
|
||||
Reference in New Issue
Block a user