Merge branch 'dynamicport'
This commit is contained in:
@@ -20,7 +20,7 @@
|
||||
var/list/mode_false_report_weight
|
||||
|
||||
var/motd
|
||||
// var/policy
|
||||
var/policy
|
||||
|
||||
var/static/regex/ic_filter_regex
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
CRASH("/datum/controller/configuration/Load() called more than once!")
|
||||
InitEntries()
|
||||
LoadModes()
|
||||
storyteller_cache = typecacheof(/datum/dynamic_storyteller, TRUE)
|
||||
if(fexists("[directory]/config.txt") && LoadEntries("config.txt") <= 1)
|
||||
var/list/legacy_configs = list("game_options.txt", "dbconfig.txt", "comms.txt")
|
||||
for(var/I in legacy_configs)
|
||||
@@ -52,7 +51,7 @@
|
||||
break
|
||||
loadmaplist(CONFIG_MAPS_FILE)
|
||||
LoadMOTD()
|
||||
// LoadPolicy()
|
||||
LoadPolicy()
|
||||
LoadChatFilter()
|
||||
|
||||
if (Master)
|
||||
@@ -266,7 +265,7 @@
|
||||
if(M.votable)
|
||||
votable_modes += M.config_tag
|
||||
qdel(M)
|
||||
votable_modes += "secret"
|
||||
votable_modes += "dynamic"
|
||||
|
||||
/datum/controller/configuration/proc/LoadMOTD()
|
||||
motd = file2text("[directory]/motd.txt")
|
||||
@@ -292,7 +291,7 @@ Example config:
|
||||
}
|
||||
|
||||
*/
|
||||
/*
|
||||
|
||||
/datum/controller/configuration/proc/LoadPolicy()
|
||||
policy = list()
|
||||
var/rawpolicy = file2text("[directory]/policy.json")
|
||||
@@ -303,7 +302,7 @@ Example config:
|
||||
DelayedMessageAdmins("JSON parsing failure for policy.json")
|
||||
else
|
||||
policy = parsed
|
||||
*/
|
||||
|
||||
/datum/controller/configuration/proc/loadmaplist(filename)
|
||||
log_config("Loading config file [filename]...")
|
||||
filename = "[directory]/[filename]"
|
||||
@@ -371,53 +370,7 @@ Example config:
|
||||
var/ct = initial(M.config_tag)
|
||||
if(ct && ct == mode_name)
|
||||
return new T
|
||||
return new /datum/game_mode/extended()
|
||||
|
||||
/// For dynamic.
|
||||
/datum/controller/configuration/proc/pick_storyteller(storyteller_name)
|
||||
for(var/T in storyteller_cache)
|
||||
var/datum/dynamic_storyteller/S = T
|
||||
var/name = initial(S.name)
|
||||
if(name && name == storyteller_name)
|
||||
return T
|
||||
return /datum/dynamic_storyteller/classic
|
||||
|
||||
/// Same with this
|
||||
/datum/controller/configuration/proc/get_runnable_storytellers()
|
||||
var/list/datum/dynamic_storyteller/runnable_storytellers = new
|
||||
var/list/probabilities = Get(/datum/config_entry/keyed_list/storyteller_weight)
|
||||
var/list/repeated_mode_adjust = Get(/datum/config_entry/number_list/repeated_mode_adjust)
|
||||
var/list/min_player_counts = Get(/datum/config_entry/keyed_list/storyteller_min_players)
|
||||
var/list/storyteller_min_chaos = Get(/datum/config_entry/keyed_list/storyteller_min_chaos)
|
||||
var/list/storyteller_max_chaos = Get(/datum/config_entry/keyed_list/storyteller_max_chaos)
|
||||
for(var/T in storyteller_cache)
|
||||
var/datum/dynamic_storyteller/S = T
|
||||
var/config_tag = initial(S.config_tag)
|
||||
if(!config_tag)
|
||||
continue
|
||||
var/probability = (config_tag in probabilities) ? probabilities[config_tag] : initial(S.weight)
|
||||
var/min_players = (config_tag in min_player_counts) ? min_player_counts[config_tag] : initial(S.min_players)
|
||||
if(probability <= 0)
|
||||
continue
|
||||
if(length(GLOB.player_list) < min_players)
|
||||
continue
|
||||
if(!Get(/datum/config_entry/flag/no_storyteller_threat_removal))
|
||||
var/min_chaos = (probabilities in storyteller_min_chaos) ? storyteller_min_chaos[config_tag] : initial(S.min_chaos)
|
||||
var/max_chaos = (probabilities in storyteller_max_chaos) ? storyteller_max_chaos[config_tag] : initial(S.max_chaos)
|
||||
if(SSpersistence.average_threat + 50 < min_chaos)
|
||||
continue
|
||||
if(SSpersistence.average_threat + 50 > max_chaos)
|
||||
continue
|
||||
if(SSpersistence.saved_storytellers.len == repeated_mode_adjust.len)
|
||||
var/name = initial(S.name)
|
||||
var/recent_round = min(SSpersistence.saved_storytellers.Find(name),3)
|
||||
var/adjustment = 0
|
||||
while(recent_round)
|
||||
adjustment += repeated_mode_adjust[recent_round]
|
||||
recent_round = SSpersistence.saved_modes.Find(name,recent_round+1,0)
|
||||
probability *= max(0,((100-adjustment)/100))
|
||||
runnable_storytellers[S] = probability
|
||||
return runnable_storytellers
|
||||
return new /datum/game_mode/dynamic
|
||||
|
||||
/datum/controller/configuration/proc/get_runnable_modes()
|
||||
var/list/datum/game_mode/runnable_modes = new
|
||||
|
||||
@@ -345,3 +345,5 @@
|
||||
|
||||
/datum/config_entry/flag/atmos_equalize_enabled
|
||||
default = FALSE
|
||||
|
||||
/datum/config_entry/flag/dynamic_config_enabled
|
||||
|
||||
@@ -30,11 +30,13 @@ SUBSYSTEM_DEF(job)
|
||||
var/datum/job/new_overflow = GetJob(new_overflow_role)
|
||||
var/cap = CONFIG_GET(number/overflow_cap)
|
||||
|
||||
new_overflow.allow_bureaucratic_error = FALSE
|
||||
new_overflow.spawn_positions = cap
|
||||
new_overflow.total_positions = cap
|
||||
|
||||
if(new_overflow_role != overflow_role)
|
||||
var/datum/job/old_overflow = GetJob(overflow_role)
|
||||
old_overflow.allow_bureaucratic_error = initial(old_overflow.allow_bureaucratic_error)
|
||||
old_overflow.spawn_positions = initial(old_overflow.spawn_positions)
|
||||
old_overflow.total_positions = initial(old_overflow.total_positions)
|
||||
overflow_role = new_overflow_role
|
||||
|
||||
@@ -5,24 +5,18 @@
|
||||
var/list/saved_modes = list(1,2,3)
|
||||
var/list/saved_chaos = list(5,5,5)
|
||||
var/list/saved_dynamic_rules = list(list(),list(),list())
|
||||
var/list/saved_storytellers = list("foo","bar","baz")
|
||||
var/average_threat = 50
|
||||
var/list/saved_maps
|
||||
|
||||
/datum/controller/subsystem/persistence/SaveServerPersistence()
|
||||
. = ..()
|
||||
CollectRoundtype()
|
||||
if(istype(SSticker.mode, /datum/game_mode/dynamic))
|
||||
var/datum/game_mode/dynamic/mode = SSticker.mode
|
||||
CollectStoryteller(mode)
|
||||
CollectRulesets(mode)
|
||||
RecordMaps()
|
||||
|
||||
/datum/controller/subsystem/persistence/LoadServerPersistence()
|
||||
. = ..()
|
||||
LoadRecentModes()
|
||||
LoadRecentChaos()
|
||||
LoadRecentStorytellers()
|
||||
LoadRecentRulesets()
|
||||
LoadRecentMaps()
|
||||
|
||||
@@ -45,30 +39,6 @@
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/CollectStoryteller(var/datum/game_mode/dynamic/mode)
|
||||
saved_storytellers.len = 3
|
||||
saved_storytellers[3] = saved_storytellers[2]
|
||||
saved_storytellers[2] = saved_storytellers[1]
|
||||
saved_storytellers[1] = mode.storyteller.name
|
||||
var/json_file = file("data/RecentStorytellers.json")
|
||||
var/list/file_data = list()
|
||||
file_data["data"] = saved_storytellers
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/CollectRulesets(var/datum/game_mode/dynamic/mode)
|
||||
saved_dynamic_rules[3] = saved_dynamic_rules[2]
|
||||
saved_dynamic_rules[2] = saved_dynamic_rules[1]
|
||||
saved_dynamic_rules[1] = list()
|
||||
for(var/r in mode.executed_rules)
|
||||
var/datum/dynamic_ruleset/rule = r
|
||||
saved_dynamic_rules[1] += rule.config_tag
|
||||
var/json_file = file("data/RecentRulesets.json")
|
||||
var/list/file_data = list()
|
||||
file_data["data"] = saved_dynamic_rules
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/RecordMaps()
|
||||
saved_maps = saved_maps?.len ? list("[SSmapping.config.map_name]") | saved_maps : list("[SSmapping.config.map_name]")
|
||||
var/json_file = file("data/RecentMaps.json")
|
||||
@@ -107,15 +77,6 @@
|
||||
return
|
||||
saved_dynamic_rules = json["data"]
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/LoadRecentStorytellers()
|
||||
var/json_file = file("data/RecentStorytellers.json")
|
||||
if(!fexists(json_file))
|
||||
return
|
||||
var/list/json = json_decode(file2text(json_file))
|
||||
if(!json)
|
||||
return
|
||||
saved_storytellers = json["data"]
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/LoadRecentMaps()
|
||||
var/json_file = file("data/RecentMaps.json")
|
||||
if(!fexists(json_file))
|
||||
|
||||
@@ -227,36 +227,14 @@ SUBSYSTEM_DEF(ticker)
|
||||
/datum/controller/subsystem/ticker/proc/setup()
|
||||
to_chat(world, "<span class='boldannounce'>Starting game...</span>")
|
||||
var/init_start = world.timeofday
|
||||
//Create and announce mode
|
||||
var/list/datum/game_mode/runnable_modes
|
||||
if(GLOB.master_mode == "random" || GLOB.master_mode == "secret")
|
||||
runnable_modes = config.get_runnable_modes()
|
||||
|
||||
if(GLOB.master_mode == "secret")
|
||||
hide_mode = 1
|
||||
if(GLOB.secret_force_mode != "secret")
|
||||
var/datum/game_mode/smode = config.pick_mode(GLOB.secret_force_mode)
|
||||
if(!smode.can_start())
|
||||
message_admins("<span class='notice'>Unable to force secret [GLOB.secret_force_mode]. [smode.required_players] players and [smode.required_enemies] eligible antagonists needed.</span>")
|
||||
else
|
||||
mode = smode
|
||||
|
||||
if(!mode)
|
||||
if(!runnable_modes.len)
|
||||
to_chat(world, "<B>Unable to choose playable game mode.</B> Reverting to pre-game lobby.")
|
||||
return 0
|
||||
mode = pickweight(runnable_modes)
|
||||
if(!mode) //too few roundtypes all run too recently
|
||||
mode = pick(runnable_modes)
|
||||
|
||||
else
|
||||
mode = config.pick_mode(GLOB.master_mode)
|
||||
if(!mode.can_start())
|
||||
to_chat(world, "<B>Unable to start [mode.name].</B> Not enough players, [mode.required_players] players and [mode.required_enemies] eligible antagonists needed. Reverting to pre-game lobby.")
|
||||
qdel(mode)
|
||||
mode = null
|
||||
SSjob.ResetOccupations()
|
||||
return 0
|
||||
GLOB.master_mode = "dynamic"
|
||||
mode = config.pick_mode(GLOB.master_mode)
|
||||
if(!mode.can_start())
|
||||
to_chat(world, "<B>Unable to start [mode.name].</B> Not enough players, [mode.required_players] players and [mode.required_enemies] eligible antagonists needed. Reverting to pre-game lobby.")
|
||||
qdel(mode)
|
||||
mode = null
|
||||
SSjob.ResetOccupations()
|
||||
return 0
|
||||
|
||||
CHECK_TICK
|
||||
//Configure mode and assign player to special mode stuff
|
||||
@@ -640,9 +618,9 @@ SUBSYSTEM_DEF(ticker)
|
||||
/datum/controller/subsystem/ticker/proc/load_mode()
|
||||
var/mode = trim(file2text("data/mode.txt"))
|
||||
if(mode)
|
||||
GLOB.master_mode = mode
|
||||
GLOB.master_mode = "dynamic"
|
||||
else
|
||||
GLOB.master_mode = "extended"
|
||||
GLOB.master_mode = GLOB.dynamic_forced_extended
|
||||
log_game("Saved mode is '[GLOB.master_mode]'")
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/save_mode(the_mode)
|
||||
|
||||
@@ -104,7 +104,6 @@ SUBSYSTEM_DEF(vote)
|
||||
return .
|
||||
|
||||
/datum/controller/subsystem/vote/proc/calculate_condorcet_votes(var/blackbox_text)
|
||||
// https://en.wikipedia.org/wiki/Schulze_method#Implementation
|
||||
if((mode == "gamemode" || mode == "dynamic" || mode == "roundtype") && CONFIG_GET(flag/must_be_readied_to_vote_gamemode))
|
||||
for(var/mob/dead/new_player/P in GLOB.player_list)
|
||||
if(P.ready != PLAYER_READY_TO_PLAY && voted[P.ckey])
|
||||
@@ -322,51 +321,17 @@ SUBSYSTEM_DEF(vote)
|
||||
var/restart = 0
|
||||
if(.)
|
||||
switch(mode)
|
||||
if("roundtype") //CIT CHANGE - adds the roundstart extended/secret vote
|
||||
if("roundtype") //CIT CHANGE - adds the roundstart extended/dynamic vote
|
||||
if(SSticker.current_state > GAME_STATE_PREGAME)//Don't change the mode if the round already started.
|
||||
return message_admins("A vote has tried to change the gamemode, but the game has already started. Aborting.")
|
||||
GLOB.master_mode = .
|
||||
SSticker.save_mode(.)
|
||||
GLOB.master_mode = "dynamic"
|
||||
if(. == "extended")
|
||||
GLOB.dynamic_forced_extended = TRUE
|
||||
message_admins("The gamemode has been voted for, and has been changed to: [GLOB.master_mode]")
|
||||
log_admin("Gamemode has been voted for and switched to: [GLOB.master_mode].")
|
||||
if(CONFIG_GET(flag/modetier_voting))
|
||||
reset()
|
||||
started_time = 0
|
||||
initiate_vote("mode tiers","server", votesystem=SCORE_VOTING, forced=TRUE, vote_time = 30 MINUTES)
|
||||
to_chat(world,"<b>The vote will end right as the round starts.</b>")
|
||||
return .
|
||||
if("restart")
|
||||
if(. == "Restart Round")
|
||||
restart = 1
|
||||
if("gamemode")
|
||||
if(GLOB.master_mode != .)
|
||||
SSticker.save_mode(.)
|
||||
if(SSticker.HasRoundStarted())
|
||||
restart = 1
|
||||
else
|
||||
GLOB.master_mode = .
|
||||
if("mode tiers")
|
||||
var/list/raw_score_numbers = list()
|
||||
for(var/score_name in scores)
|
||||
sorted_insert(raw_score_numbers,scores[score_name],/proc/cmp_numeric_asc)
|
||||
stored_modetier_results = scores.Copy()
|
||||
for(var/score_name in stored_modetier_results)
|
||||
if(stored_modetier_results[score_name] <= raw_score_numbers[CONFIG_GET(number/dropped_modes)])
|
||||
stored_modetier_results -= score_name
|
||||
stored_modetier_results += "traitor"
|
||||
if("dynamic")
|
||||
if(SSticker.current_state > GAME_STATE_PREGAME)//Don't change the mode if the round already started.
|
||||
return message_admins("A vote has tried to change the gamemode, but the game has already started. Aborting.")
|
||||
var/list/runnable_storytellers = config.get_runnable_storytellers()
|
||||
var/datum/dynamic_storyteller/picked
|
||||
for(var/T in runnable_storytellers)
|
||||
var/datum/dynamic_storyteller/S = T
|
||||
if(stored_gamemode_votes[initial(S.name)] == 1 && CHECK_BITFIELD(initial(S.flags), FORCE_IF_WON))
|
||||
picked = S
|
||||
runnable_storytellers[S] *= round(stored_gamemode_votes[initial(S.name)]*100000,1)
|
||||
if(!picked)
|
||||
picked = pickweight(runnable_storytellers, 0)
|
||||
GLOB.dynamic_storyteller_type = picked
|
||||
if("map")
|
||||
var/datum/map_config/VM = config.maplist[.]
|
||||
message_admins("The map has been voted for and will change to: [VM.map_name]")
|
||||
@@ -483,24 +448,7 @@ SUBSYSTEM_DEF(vote)
|
||||
if("transfer") // austation begin -- Crew autotranfer vote
|
||||
choices.Add("Initiate Crew Transfer","Continue Playing") // austation end
|
||||
if("roundtype") //CIT CHANGE - adds the roundstart secret/extended vote
|
||||
choices.Add("secret", "extended")
|
||||
if("mode tiers")
|
||||
var/list/modes_to_add = config.votable_modes
|
||||
var/list/probabilities = CONFIG_GET(keyed_list/probability)
|
||||
for(var/tag in modes_to_add)
|
||||
if(probabilities[tag] <= 0)
|
||||
modes_to_add -= tag
|
||||
modes_to_add -= "traitor" // makes it so that traitor is always available
|
||||
choices.Add(modes_to_add)
|
||||
if("dynamic")
|
||||
GLOB.master_mode = "dynamic"
|
||||
var/list/probabilities = CONFIG_GET(keyed_list/storyteller_weight)
|
||||
for(var/T in config.get_runnable_storytellers())
|
||||
var/datum/dynamic_storyteller/S = T
|
||||
var/probability = ((initial(S.config_tag) in probabilities) ? probabilities[initial(S.config_tag)] : initial(S.weight))
|
||||
if(probability > 0)
|
||||
choices.Add(initial(S.name))
|
||||
choice_descs.Add(initial(S.desc))
|
||||
choices.Add("dynamic", "extended")
|
||||
if("custom")
|
||||
question = stripped_input(usr,"What is the vote for?")
|
||||
if(!question)
|
||||
|
||||
Reference in New Issue
Block a user