mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-18 21:15:21 +00:00
## About The Pull Request - "Long shift" can now be earned from sub 10 minute rounds rather than sub 5 minute rounds - Admin restarts no longer give out "Long shift" ## Why It's Good For The Game I do not think this achievement can *possibly* be earned right now. Like at all. Nuke Ops and cult are the only antags that can possibly do it and it's incredibly infeasible (requiring that they nuke the station or summon Nar'sie in just 3 minutes!) So I bumped up the timer to 10 minutes. This means that ops can get it if they nuke the station in 8 minutes, cult can get it if they REALLY speedrun, and revs can get it if they beeline the heads. I checked the DB for stats on this achievement and it's only been earned in 3 rounds across the last year - `208780` (admin restart due to a bug) `192892` (admin restart due to a bug?) `186192` (admin restart). So I also prevented admin forcing the round to end. (I don't know if it catches admin reboots directly I'll have to check that.) ## Changelog 🆑 Melbert balance: The "Long Shift" achievement is now feasibly obtainable, and admins can no longer trigger it unknowingly /🆑
229 lines
9.0 KiB
Plaintext
229 lines
9.0 KiB
Plaintext
|
|
|
|
/*
|
|
* GAMEMODES (by Rastaf0)
|
|
*
|
|
* In the new mode system all special roles are fully supported.
|
|
* You can have proper wizards/traitors/changelings/cultists during any mode.
|
|
* Only two things really depends on gamemode:
|
|
* 1. Starting roles, equipment and preparations
|
|
* 2. Conditions of finishing the round.
|
|
*
|
|
*/
|
|
|
|
|
|
/datum/game_mode
|
|
|
|
///Attempts to select players for special roles the mode might have.
|
|
/datum/game_mode/proc/pre_setup()
|
|
return TRUE
|
|
|
|
///Everyone should now be on the station and have their normal gear. This is the place to give the special roles extra things
|
|
/datum/game_mode/proc/post_setup(report) //Gamemodes can override the intercept report. Passing TRUE as the argument will force a report.
|
|
if(!report)
|
|
report = !CONFIG_GET(flag/no_intercept_report)
|
|
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(display_roundstart_logout_report)), ROUNDSTART_LOGOUT_REPORT_TIME)
|
|
|
|
if(CONFIG_GET(flag/reopen_roundstart_suicide_roles))
|
|
var/delay = CONFIG_GET(number/reopen_roundstart_suicide_roles_delay)
|
|
if(delay)
|
|
delay = (delay SECONDS)
|
|
else
|
|
delay = (4 MINUTES) //default to 4 minutes if the delay isn't defined.
|
|
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(reopen_roundstart_suicide_roles)), delay)
|
|
|
|
if(SSdbcore.Connect())
|
|
var/list/to_set = list()
|
|
var/arguments = list()
|
|
if(SSticker.mode)
|
|
to_set += "game_mode = :game_mode"
|
|
arguments["game_mode"] = SSticker.mode
|
|
if(GLOB.revdata.originmastercommit)
|
|
to_set += "commit_hash = :commit_hash"
|
|
arguments["commit_hash"] = GLOB.revdata.originmastercommit
|
|
if(to_set.len)
|
|
arguments["round_id"] = GLOB.round_id
|
|
var/datum/db_query/query_round_game_mode = SSdbcore.NewQuery(
|
|
"UPDATE [format_table_name("round")] SET [to_set.Join(", ")] WHERE id = :round_id",
|
|
arguments
|
|
)
|
|
query_round_game_mode.Execute()
|
|
qdel(query_round_game_mode)
|
|
return TRUE
|
|
|
|
|
|
///Handles late-join antag assignments
|
|
/datum/game_mode/proc/make_antag_chance(mob/living/carbon/human/character)
|
|
return
|
|
|
|
/// Checks if the round should be ending, called every ticker tick
|
|
/datum/game_mode/proc/check_finished()
|
|
if(!SSticker.setup_done)
|
|
return FALSE
|
|
if(SSshuttle.emergency && (SSshuttle.emergency.mode == SHUTTLE_ENDGAME))
|
|
return TRUE
|
|
if(GLOB.station_was_nuked)
|
|
return TRUE
|
|
if(GLOB.revolutionary_win)
|
|
return TRUE
|
|
return FALSE
|
|
|
|
/*
|
|
* Generate a list of station goals available to purchase to report to the crew.
|
|
*
|
|
* Returns a formatted string all station goals that are available to the station.
|
|
*/
|
|
/datum/game_mode/proc/generate_station_goal_report()
|
|
if(!GLOB.station_goals.len)
|
|
return
|
|
. = "<hr><b>Special Orders for [station_name()]:</b><BR>"
|
|
var/list/goal_reports = list()
|
|
for(var/datum/station_goal/station_goal as anything in GLOB.station_goals)
|
|
station_goal.on_report()
|
|
goal_reports += station_goal.get_report()
|
|
|
|
. += goal_reports.Join("<hr>")
|
|
return
|
|
|
|
/*
|
|
* Generate a list of active station traits to report to the crew.
|
|
*
|
|
* Returns a formatted string of all station traits (that are shown) affecting the station.
|
|
*/
|
|
/datum/game_mode/proc/generate_station_trait_report()
|
|
var/trait_list_string = ""
|
|
for(var/datum/station_trait/station_trait as anything in SSstation.station_traits)
|
|
if(!station_trait.show_in_report)
|
|
continue
|
|
trait_list_string += "[station_trait.get_report()]<BR>"
|
|
if(trait_list_string != "")
|
|
return "<hr><b>Identified shift divergencies:</b><BR>" + trait_list_string
|
|
return
|
|
|
|
/datum/game_mode/proc/generate_report_footnote()
|
|
var/footnote_pile = ""
|
|
|
|
for(var/datum/command_footnote/footnote in SScommunications.command_report_footnotes)
|
|
footnote_pile += "[footnote.message]<BR>"
|
|
footnote_pile += "<i>[footnote.signature]</i><BR>"
|
|
footnote_pile += "<BR>"
|
|
|
|
return "<hr><b>Additional Notes: </b><BR><BR>" + footnote_pile
|
|
|
|
/proc/reopen_roundstart_suicide_roles()
|
|
var/include_command = CONFIG_GET(flag/reopen_roundstart_suicide_roles_command_positions)
|
|
var/list/reopened_jobs = list()
|
|
|
|
for(var/mob/living/quitter in GLOB.suicided_mob_list)
|
|
var/datum/job/job = SSjob.GetJob(quitter.job)
|
|
if(!job || !(job.job_flags & JOB_REOPEN_ON_ROUNDSTART_LOSS))
|
|
continue
|
|
if(!include_command && job.departments_bitflags & DEPARTMENT_BITFLAG_COMMAND)
|
|
continue
|
|
job.current_positions = max(job.current_positions - 1, 0)
|
|
reopened_jobs += quitter.job
|
|
|
|
if(CONFIG_GET(flag/reopen_roundstart_suicide_roles_command_report))
|
|
if(reopened_jobs.len)
|
|
var/reopened_job_report_positions
|
|
for(var/dead_dudes_job in reopened_jobs)
|
|
reopened_job_report_positions = "[reopened_job_report_positions ? "[reopened_job_report_positions]\n":""][dead_dudes_job]"
|
|
|
|
var/suicide_command_report = "<font size = 3><b>Central Command Human Resources Board</b><br>\
|
|
Notice of Personnel Change</font><hr>\
|
|
To personnel management staff aboard [station_name()]:<br><br>\
|
|
Our medical staff have detected a series of anomalies in the vital sensors \
|
|
of some of the staff aboard your station.<br><br>\
|
|
Further investigation into the situation on our end resulted in us discovering \
|
|
a series of rather... unforturnate decisions that were made on the part of said staff.<br><br>\
|
|
As such, we have taken the liberty to automatically reopen employment opportunities for the positions of the crew members \
|
|
who have decided not to partake in our research. We will be forwarding their cases to our employment review board \
|
|
to determine their eligibility for continued service with the company (and of course the \
|
|
continued storage of cloning records within the central medical backup server.)<br><br>\
|
|
<i>The following positions have been reopened on our behalf:<br><br>\
|
|
[reopened_job_report_positions]</i>"
|
|
|
|
print_command_report(suicide_command_report, "Central Command Personnel Update")
|
|
|
|
//////////////////////////
|
|
//Reports player logouts//
|
|
//////////////////////////
|
|
/proc/display_roundstart_logout_report()
|
|
var/list/msg = list("[span_boldnotice("Roundstart logout report")]\n\n")
|
|
for(var/i in GLOB.mob_living_list)
|
|
var/mob/living/L = i
|
|
var/mob/living/carbon/C = L
|
|
if (istype(C) && !C.last_mind)
|
|
continue // never had a client
|
|
|
|
if(L.ckey && !GLOB.directory[L.ckey])
|
|
msg += "<b>[L.name]</b> ([L.key]), the [L.job] (<font color='#ffcc00'><b>Disconnected</b></font>)\n"
|
|
|
|
|
|
if(L.ckey && L.client)
|
|
var/failed = FALSE
|
|
if(L.client.inactivity >= ROUNDSTART_LOGOUT_AFK_THRESHOLD) //Connected, but inactive (alt+tabbed or something)
|
|
msg += "<b>[L.name]</b> ([L.key]), the [L.job] (<font color='#ffcc00'><b>Connected, Inactive</b></font>)\n"
|
|
failed = TRUE //AFK client
|
|
if(!failed && L.stat)
|
|
if(HAS_TRAIT(L, TRAIT_SUICIDED)) //Suicider
|
|
msg += "<b>[L.name]</b> ([L.key]), the [L.job] ([span_boldannounce("Suicide")])\n"
|
|
failed = TRUE //Disconnected client
|
|
if(!failed && (L.stat == UNCONSCIOUS || L.stat == HARD_CRIT))
|
|
msg += "<b>[L.name]</b> ([L.key]), the [L.job] (Dying)\n"
|
|
failed = TRUE //Unconscious
|
|
if(!failed && L.stat == DEAD)
|
|
msg += "<b>[L.name]</b> ([L.key]), the [L.job] (Dead)\n"
|
|
failed = TRUE //Dead
|
|
|
|
continue //Happy connected client
|
|
for(var/mob/dead/observer/D in GLOB.dead_mob_list)
|
|
if(D.mind && D.mind.current == L)
|
|
if(L.stat == DEAD)
|
|
if(HAS_TRAIT(L, TRAIT_SUICIDED)) //Suicider
|
|
msg += "<b>[L.name]</b> ([ckey(D.mind.key)]), the [L.job] ([span_boldannounce("Suicide")])\n"
|
|
continue //Disconnected client
|
|
else
|
|
msg += "<b>[L.name]</b> ([ckey(D.mind.key)]), the [L.job] (Dead)\n"
|
|
continue //Dead mob, ghost abandoned
|
|
else
|
|
if(D.can_reenter_corpse)
|
|
continue //Adminghost, or cult/wizard ghost
|
|
else
|
|
msg += "<b>[L.name]</b> ([ckey(D.mind.key)]), the [L.job] ([span_boldannounce("Ghosted")])\n"
|
|
continue //Ghosted while alive
|
|
|
|
var/concatenated_message = msg.Join()
|
|
log_admin(concatenated_message)
|
|
to_chat(GLOB.admins, concatenated_message)
|
|
|
|
/datum/game_mode/proc/generate_station_goals(greenshift)
|
|
var/goal_budget = greenshift ? INFINITY : CONFIG_GET(number/station_goal_budget)
|
|
var/list/possible = subtypesof(/datum/station_goal)
|
|
if(SSmapping.is_planetary())
|
|
for(var/datum/station_goal/goal in possible)
|
|
if(goal.requires_space)
|
|
///Removes all goals that require space if space is not present
|
|
possible -= goal
|
|
var/goal_weights = 0
|
|
while(possible.len && goal_weights < goal_budget)
|
|
var/datum/station_goal/picked = pick_n_take(possible)
|
|
goal_weights += initial(picked.weight)
|
|
GLOB.station_goals += new picked
|
|
|
|
//Set result and news report here
|
|
/datum/game_mode/proc/set_round_result()
|
|
SSticker.mode_result = "undefined"
|
|
// Something nuked the station - it wasn't nuke ops (they set their own via their rulset)
|
|
if(GLOB.station_was_nuked)
|
|
SSticker.news_report = STATION_NUKED
|
|
if(SSsupermatter_cascade.cascade_initiated)
|
|
SSticker.news_report = SUPERMATTER_CASCADE
|
|
// Only show this one if we have nothing better to show
|
|
if(EMERGENCY_ESCAPED_OR_ENDGAMED && !SSticker.news_report)
|
|
SSticker.news_report = SSshuttle.emergency?.is_hijacked() ? SHUTTLE_HIJACK : STATION_EVACUATED
|
|
|
|
/// Mode specific admin panel.
|
|
/datum/game_mode/proc/admin_panel()
|
|
return
|