<commit_before>#define EXTRA_RULESET_PENALTY 20	// Changes how likely a gamemode is to scale based on how many other roundstart rulesets are waiting to be rolled.
#define POP_SCALING_PENALTY 50		// Discourages scaling up rulesets if ratio of antags to crew is high.

#define REVOLUTION_VICTORY 1
#define STATION_VICTORY 2

/datum/dynamic_ruleset
	/// For admin logging and round end screen.
	var/name = ""
	/// For admin logging and round end screen, do not change this unless making a new rule type.
	var/ruletype = ""
	/// For config purposes, similar to config_tag for secret game modes.
	var/config_tag = null
	/// If set to TRUE, the rule won't be discarded after being executed, and dynamic will call rule_process() every time it ticks.
	var/persistent = FALSE
	/// If set to TRUE, dynamic mode will be able to draft this ruleset again later on. (doesn't apply for roundstart rules)
	var/repeatable = FALSE
	/// If set higher than 0 decreases weight by itself causing the ruleset to appear less often the more it is repeated.
	var/repeatable_weight_decrease = 2
	/// List of players that are being drafted for this rule
	var/list/mob/candidates = list()
	/// List of players that were selected for this rule
	var/list/datum/mind/assigned = list()
	/// Preferences flag such as ROLE_WIZARD that need to be turned on for players to be antag
	var/antag_flag = null
	/// The antagonist datum that is assigned to the mobs mind on ruleset execution.
	var/datum/antagonist/antag_datum = null
	/// The required minimum account age for this ruleset.
	var/minimum_required_age = 7
	/// If set, and config flag protect_roles_from_antagonist is false, then the rule will not pick players from these roles.
	var/list/protected_roles = list()
	/// If set, rule will deny candidates from those roles always.
	var/list/restricted_roles = list()
	/// If set, rule will only accept candidates from those roles, IMPORTANT: DOES NOT WORK ON ROUNDSTART RULESETS.
	var/list/exclusive_roles = list()
	/// If set, there needs to be a certain amount of players doing those roles (among the players who won't be drafted) for the rule to be drafted IMPORTANT: DOES NOT WORK ON ROUNDSTART RULESETS.
	var/list/enemy_roles = list()
	/// If enemy_roles was set, this is the amount of enemy job workers needed per threat_level range (0-10,10-20,etc) IMPORTANT: DOES NOT WORK ON ROUNDSTART RULESETS.
	var/required_enemies = list(1,1,0,0,0,0,0,0,0,0)
	/// The rule needs this many candidates (post-trimming) to be executed (example: Cult needs 4 players at round start)
	var/required_candidates = 0
	/// 1 -> 9, probability for this rule to be picked against other rules
	var/weight = 5
	/// Threat cost for this rule, this is decreased from the mode's threat when the rule is executed.
	var/cost = 0
	/// Cost per level the rule scales up.
	var/scaling_cost = 0
	/// How many times a rule has scaled up upon getting picked.
	var/scaled_times = 0
	/// Used for the roundend report
	var/total_cost = 0
	/// A flag that determines how the ruleset is handled
	/// HIGHLANDER_RULESET are rulesets can end the round.
	/// TRAITOR_RULESET and MINOR_RULESET can't end the round and have no difference right now.
	var/flags = 0
	/// Pop range per requirement. If zero defaults to mode's pop_per_requirement.
	var/pop_per_requirement = 0
	/// Requirements are the threat level requirements per pop range.
	/// With the default values, The rule will never get drafted below 10 threat level (aka: "peaceful extended"), and it requires a higher threat level at lower pops.
	var/list/requirements = list(40,30,20,10,10,10,10,10,10,10)
	/// An alternative, static requirement used instead when pop is over mode's high_pop_limit.
	var/high_population_requirement = 10
	/// Reference to the mode, use this instead of SSticker.mode.
	var/datum/game_mode/dynamic/mode = null
	/// If a role is to be considered another for the purpose of banning.
	var/antag_flag_override = null
	/// If a ruleset type which is in this list has been executed, then the ruleset will not be executed.
	var/list/blocking_rules = list()
	/// The minimum amount of players required for the rule to be considered.
	var/minimum_players = 0
	/// The maximum amount of players required for the rule to be considered.
	/// Anything below zero or exactly zero is ignored.
	var/maximum_players = 0
	/// Calculated during acceptable(), used in scaling and team sizes.
	var/indice_pop = 0
	/// Population scaling. Used by team antags and scaling for solo antags.
	var/list/antag_cap = list()
	/// Base probability used in scaling. The higher it is, the more likely to scale. Kept as a var to allow for config editing._SendSignal(sigtype, list/arguments)
	var/base_prob = 60
	/// Delay for when execute will get called from the time of post_setup (roundstart) or process (midround/latejoin).
	/// Make sure your ruleset works with execute being called during the game when using this, and that the clean_up proc reverts it properly in case of faliure.
	var/delay = 0
	/// Whether or not recent-round weight values are taken into account for this ruleset.
	/// Weight reduction uses the same values as secret's recent-round mode weight reduction.
	var/always_max_weight = FALSE

/datum/dynamic_ruleset/New()
	..()
	if(CONFIG_GET(flag/protect_roles_from_antagonist))
		restricted_roles += protected_roles
	if(CONFIG_GET(flag/protect_assistant_from_antagonist))
		restricted_roles += "Assistant"
	var/weights = CONFIG_GET(keyed_list/dynamic_weight)
	var/costs = CONFIG_GET(keyed_list/dynamic_cost)
	var/requirementses = CONFIG_GET(keyed_list/dynamic_requirements) // can't damn well use requirements
	var/high_population_requirements = CONFIG_GET(keyed_list/dynamic_high_population_requirement)
	var/list/repeated_mode_adjust = CONFIG_GET(number_list/repeated_mode_adjust)
	if(config_tag in weights)
		var/weight_mult = 1
		if(!always_max_weight && SSpersistence.saved_dynamic_rules.len == 3 && repeated_mode_adjust.len == 3)
			var/saved_dynamic_rules = SSpersistence.saved_dynamic_rules.len
			for(var/i in 1 to 3)
				if(config_tag in saved_dynamic_rules[i])
					weight_mult -= (repeated_mode_adjust[i]/100)
		weight = weights[config_tag] * weight_mult
	if(config_tag in costs)<commit_msg>and THIS is why you always double check your code<commit_after>#define EXTRA_RULESET_PENALTY 20	// Changes how likely a gamemode is to scale based on how many other roundstart rulesets are waiting to be rolled.
#define POP_SCALING_PENALTY 50		// Discourages scaling up rulesets if ratio of antags to crew is high.

#define REVOLUTION_VICTORY 1
#define STATION_VICTORY 2

/datum/dynamic_ruleset
	/// For admin logging and round end screen.
	var/name = ""
	/// For admin logging and round end screen, do not change this unless making a new rule type.
	var/ruletype = ""
	/// For config purposes, similar to config_tag for secret game modes.
	var/config_tag = null
	/// If set to TRUE, the rule won't be discarded after being executed, and dynamic will call rule_process() every time it ticks.
	var/persistent = FALSE
	/// If set to TRUE, dynamic mode will be able to draft this ruleset again later on. (doesn't apply for roundstart rules)
	var/repeatable = FALSE
	/// If set higher than 0 decreases weight by itself causing the ruleset to appear less often the more it is repeated.
	var/repeatable_weight_decrease = 2
	/// List of players that are being drafted for this rule
	var/list/mob/candidates = list()
	/// List of players that were selected for this rule
	var/list/datum/mind/assigned = list()
	/// Preferences flag such as ROLE_WIZARD that need to be turned on for players to be antag
	var/antag_flag = null
	/// The antagonist datum that is assigned to the mobs mind on ruleset execution.
	var/datum/antagonist/antag_datum = null
	/// The required minimum account age for this ruleset.
	var/minimum_required_age = 7
	/// If set, and config flag protect_roles_from_antagonist is false, then the rule will not pick players from these roles.
	var/list/protected_roles = list()
	/// If set, rule will deny candidates from those roles always.
	var/list/restricted_roles = list()
	/// If set, rule will only accept candidates from those roles, IMPORTANT: DOES NOT WORK ON ROUNDSTART RULESETS.
	var/list/exclusive_roles = list()
	/// If set, there needs to be a certain amount of players doing those roles (among the players who won't be drafted) for the rule to be drafted IMPORTANT: DOES NOT WORK ON ROUNDSTART RULESETS.
	var/list/enemy_roles = list()
	/// If enemy_roles was set, this is the amount of enemy job workers needed per threat_level range (0-10,10-20,etc) IMPORTANT: DOES NOT WORK ON ROUNDSTART RULESETS.
	var/required_enemies = list(1,1,0,0,0,0,0,0,0,0)
	/// The rule needs this many candidates (post-trimming) to be executed (example: Cult needs 4 players at round start)
	var/required_candidates = 0
	/// 1 -> 9, probability for this rule to be picked against other rules
	var/weight = 5
	/// Threat cost for this rule, this is decreased from the mode's threat when the rule is executed.
	var/cost = 0
	/// Cost per level the rule scales up.
	var/scaling_cost = 0
	/// How many times a rule has scaled up upon getting picked.
	var/scaled_times = 0
	/// Used for the roundend report
	var/total_cost = 0
	/// A flag that determines how the ruleset is handled
	/// HIGHLANDER_RULESET are rulesets can end the round.
	/// TRAITOR_RULESET and MINOR_RULESET can't end the round and have no difference right now.
	var/flags = 0
	/// Pop range per requirement. If zero defaults to mode's pop_per_requirement.
	var/pop_per_requirement = 0
	/// Requirements are the threat level requirements per pop range.
	/// With the default values, The rule will never get drafted below 10 threat level (aka: "peaceful extended"), and it requires a higher threat level at lower pops.
	var/list/requirements = list(40,30,20,10,10,10,10,10,10,10)
	/// An alternative, static requirement used instead when pop is over mode's high_pop_limit.
	var/high_population_requirement = 10
	/// Reference to the mode, use this instead of SSticker.mode.
	var/datum/game_mode/dynamic/mode = null
	/// If a role is to be considered another for the purpose of banning.
	var/antag_flag_override = null
	/// If a ruleset type which is in this list has been executed, then the ruleset will not be executed.
	var/list/blocking_rules = list()
	/// The minimum amount of players required for the rule to be considered.
	var/minimum_players = 0
	/// The maximum amount of players required for the rule to be considered.
	/// Anything below zero or exactly zero is ignored.
	var/maximum_players = 0
	/// Calculated during acceptable(), used in scaling and team sizes.
	var/indice_pop = 0
	/// Population scaling. Used by team antags and scaling for solo antags.
	var/list/antag_cap = list()
	/// Base probability used in scaling. The higher it is, the more likely to scale. Kept as a var to allow for config editing._SendSignal(sigtype, list/arguments)
	var/base_prob = 60
	/// Delay for when execute will get called from the time of post_setup (roundstart) or process (midround/latejoin).
	/// Make sure your ruleset works with execute being called during the game when using this, and that the clean_up proc reverts it properly in case of faliure.
	var/delay = 0
	/// Whether or not recent-round weight values are taken into account for this ruleset.
	/// Weight reduction uses the same values as secret's recent-round mode weight reduction.
	var/always_max_weight = FALSE

/datum/dynamic_ruleset/New()
	..()
	if(CONFIG_GET(flag/protect_roles_from_antagonist))
		restricted_roles += protected_roles
	if(CONFIG_GET(flag/protect_assistant_from_antagonist))
		restricted_roles += "Assistant"
	var/weights = CONFIG_GET(keyed_list/dynamic_weight)
	var/costs = CONFIG_GET(keyed_list/dynamic_cost)
	var/requirementses = CONFIG_GET(keyed_list/dynamic_requirements) // can't damn well use requirements
	var/high_population_requirements = CONFIG_GET(keyed_list/dynamic_high_population_requirement)
	var/list/repeated_mode_adjust = CONFIG_GET(number_list/repeated_mode_adjust)
	if(config_tag in weights)
		var/weight_mult = 1
		if(!always_max_weight && SSpersistence.saved_dynamic_rules.len == 3 && repeated_mode_adjust.len == 3)
			var/saved_dynamic_rules = SSpersistence.saved_dynamic_rules
			for(var/i in 1 to 3)
				if(config_tag in saved_dynamic_rules[i])
					weight_mult -= (repeated_mode_adjust[i]/100)
		weight = weights[config_tag] * weight_mult
	if(config_tag in costs)
{'fraction_non_alphanumeric': 0.07684278143568331, 'fraction_numerical': 0.012044323109041272, 'mean_word_length': 3.9839935974389755, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 2, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '246045', 'n_tokens_mistral': 3946, 'n_tokens_neox': 3710, 'n_words': 1534}