Skip to content

Commit

Permalink
random storytellers
Browse files Browse the repository at this point in the history
  • Loading branch information
wraith-54321 committed Dec 16, 2023
1 parent 7821ea6 commit caa70ad
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 24 deletions.
3 changes: 1 addition & 2 deletions code/controllers/master.dm
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
if(sleep_offline_after_initializations && CONFIG_GET(flag/resume_after_initializations))
world.sleep_offline = FALSE
initializations_finished_with_no_players_logged_in = initialized_tod < REALTIMEOFDAY - 10
/// run votes
SSvote.initiate_vote(/datum/vote/storyteller, "pick round storyteller", forced = TRUE) // idk where else to run this lol
SSgamemode.handle_picking_stroyteller() //monkestation edit

/**
* Initialize a given subsystem and handle the results.
Expand Down
2 changes: 1 addition & 1 deletion code/controllers/subsystem/statpanel.dm
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ SUBSYSTEM_DEF(statpanels)
global_data = list(
"Map: [SSmapping.config?.map_name || "Loading..."]",
cached ? "Next Map: [cached.map_name]" : null,
"Storyteller: [SSgamemode.storyteller ? SSgamemode.storyteller.name : "N/A"]", //monkestation addition
"Storyteller: [!SSgamemode.secret_storyteller && SSgamemode.storyteller ? SSgamemode.storyteller.name : "Secret"]", //monkestation addition
"Round ID: [GLOB.round_id ? GLOB.round_id : "NULL"]",
"Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]",
"Round Time: [ROUND_TIME()]",
Expand Down
53 changes: 37 additions & 16 deletions monkestation/code/modules/storytellers/gamemode_subsystem.dm
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#define INIT_ORDER_GAMEMODE 70
///how many storytellers can be voted for along with always_votable ones
#define DEFAULT_STORYTELLER_VOTE_OPTIONS 4
///amount of players we can have before no longer running votes for storyteller
#define MAX_POP_FOR_STORYTELLER_VOTE 25

SUBSYSTEM_DEF(gamemode)
name = "Gamemode"
Expand All @@ -13,8 +15,8 @@ SUBSYSTEM_DEF(gamemode)
var/list/event_tracks = EVENT_TRACKS
/// Our storyteller. They progresses our trackboards and picks out events
var/datum/storyteller/storyteller
/// Result of the storyteller vote. Defaults to the guide.
var/voted_storyteller = /datum/storyteller/guide
/// Result of the storyteller vote/pick. Defaults to the guide.
var/selected_storyteller = /datum/storyteller/guide
/// List of all the storytellers. Populated at init. Associative from type
var/list/storytellers = list()
/// Next process for our storyteller. The wait time is STORYTELLER_WAIT_TIME
Expand Down Expand Up @@ -141,7 +143,10 @@ SUBSYSTEM_DEF(gamemode)
var/sec_crew = 0
var/med_crew = 0

var/wizardmode = FALSE
/// Is storyteller secret or not
var/secret_storyteller = FALSE

var/wizardmode = FALSE //refactor this into just being a unique storyteller

var/datum/round_event_control/current_roundstart_event
var/list/last_round_events = list()
Expand Down Expand Up @@ -777,21 +782,21 @@ SUBSYSTEM_DEF(gamemode)
point_thresholds[EVENT_TRACK_ROLESET] = CONFIG_GET(number/roleset_point_threshold)
point_thresholds[EVENT_TRACK_OBJECTIVES] = CONFIG_GET(number/objectives_point_threshold)

/datum/controller/subsystem/gamemode/proc/handle_picking_stroyteller()
if(length(GLOB.clients) > MAX_POP_FOR_STORYTELLER_VOTE)
secret_storyteller = TRUE
selected_storyteller = pick_weight(get_valid_storytellers())
return
SSvote.initiate_vote(/datum/vote/storyteller, "pick round storyteller", forced = TRUE)

/datum/controller/subsystem/gamemode/proc/storyteller_vote_choices()
var/client_amount = length(GLOB.clients)
var/list/final_choices = list()
var/list/pick_from = list()
for(var/storyteller_type in storytellers)
var/datum/storyteller/storyboy = storytellers[storyteller_type]
if(!storyboy.votable)
continue
if((storyboy.population_min && storyboy.population_min > client_amount) || (storyboy.population_max && storyboy.population_max < client_amount))
continue

for(var/datum/storyteller/storyboy in get_valid_storytellers())
if(storyboy.always_votable)
final_choices[storyboy.name] = 0
else
pick_from[storyboy.name] = storyboy.weight
pick_from[storyboy.name] = storyboy.weight //might be able to refactor this to be slightly better due to get_valid_storytellers returning a weighted list

var/added_storytellers = 0
while(added_storytellers < DEFAULT_STORYTELLER_VOTE_OPTIONS && length(pick_from))
Expand All @@ -813,19 +818,34 @@ SUBSYSTEM_DEF(gamemode)
for(var/storyteller_type in storytellers)
var/datum/storyteller/storyboy = storytellers[storyteller_type]
if(storyboy.name == winner_name)
voted_storyteller = storyteller_type
selected_storyteller = storyteller_type
break

//return a weighted list of all storytellers that are currently valid to roll
/datum/controller/subsystem/gamemode/proc/get_valid_storytellers()
var/client_amount = length(GLOB.clients)
var/list/valid_storytellers = list()
for(var/storyteller_type in storytellers)
var/datum/storyteller/storyboy = storytellers[storyteller_type]
if(storyboy.restricted || (storyboy.population_min && storyboy.population_min > client_amount) || (storyboy.population_max && storyboy.population_max < client_amount))
continue

valid_storytellers[storyboy] = storyboy.weight
return valid_storytellers

/datum/controller/subsystem/gamemode/proc/init_storyteller()
set_storyteller(voted_storyteller)
set_storyteller(selected_storyteller)

/datum/controller/subsystem/gamemode/proc/set_storyteller(passed_type)
if(!storytellers[passed_type])
message_admins("Attempted to set an invalid storyteller type: [passed_type].")
CRASH("Attempted to set an invalid storyteller type: [passed_type].")
storyteller = storytellers[passed_type]
to_chat(world, span_notice("<b>Storyteller is [storyteller.name]!</b>"))
to_chat(world, span_notice("[storyteller.welcome_text]"))
if(!secret_storyteller)
send_to_playing_players(span_notice("<b>Storyteller is [storyteller.name]!</b>"))
send_to_playing_players(span_notice("[storyteller.welcome_text]"))
else
send_to_observers(span_notice("<b>Storyteller is [storyteller.name]!</b>")) //observers still get to know

/// Panel containing information, variables and controls about the gamemode and scheduled event
/datum/controller/subsystem/gamemode/proc/admin_panel(mob/user)
Expand Down Expand Up @@ -1173,3 +1193,4 @@ SUBSYSTEM_DEF(gamemode)
listed.occurrences++

#undef DEFAULT_STORYTELLER_VOTE_OPTIONS
#undef MAX_POP_FOR_STORYTELLER_VOTE
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@
/// Whether the storyteller has the distributions disabled. Important for ghost storytellers
var/disable_distribution = FALSE

/// Whether people can vote for the storyteller
var/votable = TRUE
/// Whether a storyteller is pickable/can be voted for
var/restricted = FALSE
/// If defined, will need a minimum of population to be votable
var/population_min
/// If defined, it will not be votable if exceeding the population
Expand All @@ -56,7 +56,7 @@
var/ignores_roundstart = FALSE
///is a storyteller always able to be voted for(also does not count for the amount of storytellers to pick from)
var/always_votable = FALSE
///weight this has of showing up in the vote if not always_votable
///weight this has of being picked for random storyteller/showing up in the vote if not always_votable
var/weight = 0

/datum/storyteller/process(delta_time)
Expand Down Expand Up @@ -181,4 +181,5 @@
/datum/storyteller/guide
name = "The Guide"
desc = "The Guide will provide a balanced and varied experience. Consider this the default experience."
weight = 8
always_votable = TRUE
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@
)
tag_multipliers = list(TAG_COMMUNAL = 1.1, TAG_SPOOKY = 1.2)
guarantees_roundstart_roleset = FALSE
votable = FALSE //admins can still use this if they want the crew to really suffer, for that reason im going all in
restricted = FALSE //admins can still use this if they want the crew to really suffer, for that reason im going all in
roundstart_prob = 75
ignores_roundstart = TRUE
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
disable_distribution = TRUE
population_max = 25
welcome_text = "The station feels invisible to outside influence."
weight = 4 //extra likely if its an option
weight = 3
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@
tag_multipliers = list(TAG_COMBAT = 0.6, TAG_DESTRUCTIVE = 0.7)
always_votable = TRUE //good for low pop
welcome_text = "The day is going slowly."
weight = 1 //close to greenshift so its very low weight

0 comments on commit caa70ad

Please sign in to comment.