mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-06-05 22:31:04 +01:00
a6f49ed542
## About The Pull Request Firstly, this var was on `/mob`, even though only `/mob/living` and `/mob/dead` could have ever used it, so who knows how much needless memory it was consuming on stuff such as `oranges_ear` that would never ever ever use something like this. Edit: okay instead of memory it just polluted variable edit windows for all /mob when it didn't need to. I like having a slim VV window Secondly, it's a technical improvement over the previous system as we are able to "track" where a suicide originates from, and how we can track that from mob-to-mob-to-mob. Previously, the boolean `suiciding` would only inform us if they had ever been connected to a mob that had ever committed suicide, but now we are able to precisely determine which mob gave them the trait that they must now apparently bear until the round restarts. ## Why It's Good For The Game Less memory usage, more indepth ability to track suicides in case you really need that dexterity. Currently no implemented code could benefit from using it, but it would be pretty neat if someone could figure out a way to have someone be guilt-tripped whenever they look into a mirror and seeing the reflection of their past life? This PR won't actually help you code that and it'll probably require a bit more work, but it's a possibility of some cool interactions you can do when you have this information available to you.  ## Changelog 🆑 refactor: Some aspects of how we track suicides from your living mob to your observer have changed- please do let us know if anything has broken via a GitHub Issue Report. /🆑 There's probably some technical improvements that can be made in some parts of the code I reworked to accommodate this change, do let me know if you spot any easy ones (or fuckups). a lot of excess comes from the fact that any step in the TRAIT framework trusts that you are passing in a valid datum (or subtype) so that's a thing
227 lines
8.9 KiB
Plaintext
227 lines
8.9 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
|
|
|
|
/datum/game_mode/proc/check_finished(force_ending) //to be called by SSticker
|
|
if(!SSticker.setup_done)
|
|
return FALSE
|
|
if(SSshuttle.emergency && (SSshuttle.emergency.mode == SHUTTLE_ENDGAME))
|
|
return TRUE
|
|
if(GLOB.station_was_nuked)
|
|
return TRUE
|
|
if(force_ending)
|
|
return TRUE
|
|
|
|
/*
|
|
* 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
|