mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-17 11:05:16 +01:00
Mirror 72339 & 71284 (#18645)
* Renews a bunch of old roundend new reports that got lost. Plus, some roundend report QoL for cult and revs. (#71284) A few roundend reports got lost from moving to dynamic and other prs. This PRs re-allows them to occur. Namely: "Wizard Killed" (lost in dynamic), "Blob nuked" (lost in dynamic), "Cult escaped" (lost in cult rework), and "Nuke Ops Victory" (station destroyed via nuke) (lost from, what I can see, an oversight / accidental swap of report values). Additionally, small roundend report QOL for cult: Removes antag datums from spirit realm ghosts after being dusted, so they do not show up on the report. And in reverse, heads of staff who were dusted / destroyed in revolution rounds are now also shown in roundend reports. Some of these reports are dead, which is is a shame because I think they're cool and fun. 🆑 Melbert qol: Successfully fending off a blob now has a cross station news report again. More pressing reports will take priority over it, though. qol: Successfully killing a wizard (and all of their apprentices) now has a cross station news report again. qol: If more than half of a cultist team manages to escape on the shuttle (rather than summoning Nar'sie), they will send a unique cross station news report. This is still a loss, by the way. Summon Nar'sie! qol: Nuclear Operatives successfully nuking the station now has its unique cross station news report again, and no longer uses the generic "The station was nuked" report. qol: Nuking the station to stop a blob infection now has a unique cross station news report again. Good luck convincing admins to allow this. qol: Cult ghosts from "Spirit Realm" no longer persist on the cult's team after being desummoned, meaning they will not show up on roundend report. qol: Heads of staff will now always show up on revolution roundend report - even if their body was fully destroyed. /🆑 * Adds support for Rulesets having intrinsic template requirements (#72339) Title Ensures that we load templates for a ruleset before we attempt to place or cache characters for that ruleset Also makes wizard and abductor async load their template to improve (apparent) loading times for them This is the only thing left that I can think of that would cause antags like nukies and abductors to spawn in wrong This should not be player facing Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com> Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Co-authored-by: Zephyr <12817816+ZephyrTFA@users.noreply.github.com> Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
This commit is contained in:
@@ -11,8 +11,6 @@
|
||||
#define STATION_EVACUATED 5
|
||||
/// The blob has reached critical mass and overtaken the station
|
||||
#define BLOB_WIN 8
|
||||
/// The station's nuke was detonated destroying the blob
|
||||
#define BLOB_NUKE 9
|
||||
/// The blob was destroyed by the crew
|
||||
#define BLOB_DESTROYED 10
|
||||
/// The cult managed to escape alive on the shuttle
|
||||
|
||||
@@ -958,42 +958,39 @@ SUBSYSTEM_DEF(job)
|
||||
living_mob.forceMove(toLaunch)
|
||||
new /obj/effect/pod_landingzone(spawn_turf, toLaunch)
|
||||
|
||||
///////////////////////////////////
|
||||
//Keeps track of all living heads//
|
||||
///////////////////////////////////
|
||||
/// Returns a list of minds of all heads of staff who are alive
|
||||
/datum/controller/subsystem/job/proc/get_living_heads()
|
||||
. = list()
|
||||
for(var/mob/living/carbon/human/player as anything in GLOB.human_list)
|
||||
if(player.stat != DEAD && (player.mind?.assigned_role.departments_bitflags & DEPARTMENT_BITFLAG_COMMAND))
|
||||
. += player.mind
|
||||
for(var/datum/mind/head as anything in get_crewmember_minds())
|
||||
if(!(head.assigned_role.departments_bitflags & DEPARTMENT_BITFLAG_COMMAND))
|
||||
continue
|
||||
if(isnull(head.current) || head.current.stat == DEAD)
|
||||
continue
|
||||
. += head
|
||||
|
||||
|
||||
////////////////////////////
|
||||
//Keeps track of all heads//
|
||||
////////////////////////////
|
||||
/// Returns a list of minds of all heads of staff
|
||||
/datum/controller/subsystem/job/proc/get_all_heads()
|
||||
. = list()
|
||||
for(var/mob/living/carbon/human/player as anything in GLOB.human_list)
|
||||
if(player.mind?.assigned_role.departments_bitflags & DEPARTMENT_BITFLAG_COMMAND)
|
||||
. += player.mind
|
||||
for(var/datum/mind/head as anything in get_crewmember_minds())
|
||||
if(head.assigned_role.departments_bitflags & DEPARTMENT_BITFLAG_COMMAND)
|
||||
. += head
|
||||
|
||||
//////////////////////////////////////////////
|
||||
//Keeps track of all living security members//
|
||||
//////////////////////////////////////////////
|
||||
/// Returns a list of minds of all security members who are alive
|
||||
/datum/controller/subsystem/job/proc/get_living_sec()
|
||||
. = list()
|
||||
for(var/mob/living/carbon/human/player as anything in GLOB.human_list)
|
||||
if(player.stat != DEAD && (player.mind?.assigned_role.departments_bitflags & DEPARTMENT_BITFLAG_SECURITY))
|
||||
. += player.mind
|
||||
for(var/datum/mind/sec as anything in get_crewmember_minds())
|
||||
if(!(sec.assigned_role.departments_bitflags & DEPARTMENT_BITFLAG_SECURITY))
|
||||
continue
|
||||
if(isnull(sec.current) || sec.current.stat == DEAD)
|
||||
continue
|
||||
. += sec
|
||||
|
||||
////////////////////////////////////////
|
||||
//Keeps track of all security members//
|
||||
////////////////////////////////////////
|
||||
/// Returns a list of minds of all security members
|
||||
/datum/controller/subsystem/job/proc/get_all_sec()
|
||||
. = list()
|
||||
for(var/mob/living/carbon/human/player as anything in GLOB.human_list)
|
||||
if(player.mind?.assigned_role.departments_bitflags & DEPARTMENT_BITFLAG_SECURITY)
|
||||
. += player.mind
|
||||
for(var/datum/mind/sec as anything in get_crewmember_minds())
|
||||
if(sec.assigned_role.departments_bitflags & DEPARTMENT_BITFLAG_SECURITY)
|
||||
. += sec
|
||||
|
||||
/datum/controller/subsystem/job/proc/JobDebug(message)
|
||||
log_job_debug(message)
|
||||
|
||||
@@ -861,6 +861,17 @@ GLOBAL_LIST_EMPTY(the_station_areas)
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/lazy_load_template(template_key, force = FALSE)
|
||||
RETURN_TYPE(/datum/turf_reservation)
|
||||
var/static/lazy_loading = FALSE
|
||||
UNTIL(!lazy_loading)
|
||||
|
||||
lazy_loading = TRUE
|
||||
. = _lazy_load_template(template_key, force)
|
||||
lazy_loading = FALSE
|
||||
return .
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/_lazy_load_template(template_key, force = FALSE)
|
||||
PRIVATE_PROC(TRUE)
|
||||
|
||||
if(LAZYACCESS(loaded_lazy_templates, template_key) && !force)
|
||||
var/datum/lazy_template/template = GLOB.lazy_templates[template_key]
|
||||
return template.reservations[1]
|
||||
@@ -869,7 +880,6 @@ GLOBAL_LIST_EMPTY(the_station_areas)
|
||||
var/datum/lazy_template/target = GLOB.lazy_templates[template_key]
|
||||
if(!target)
|
||||
CRASH("Attempted to lazy load a template key that does not exist: '[template_key]'")
|
||||
|
||||
return target.lazy_load()
|
||||
|
||||
/proc/generate_lighting_appearance_by_z(z_level)
|
||||
|
||||
@@ -48,6 +48,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
var/queue_delay = 0
|
||||
var/list/queued_players = list() //used for join queues when the server exceeds the hard population cap
|
||||
|
||||
/// What is going to be reported to other stations at end of round?
|
||||
var/news_report
|
||||
|
||||
|
||||
@@ -582,47 +583,96 @@ SUBSYSTEM_DEF(ticker)
|
||||
/datum/controller/subsystem/ticker/proc/send_news_report()
|
||||
var/news_message
|
||||
var/news_source = "Nanotrasen News Network"
|
||||
var/decoded_station_name = html_decode("[CONFIG_GET(string/cross_comms_name)]([station_name()])") //decode station_name to avoid minor_announce double encode //SKYRAT EDIT CHANGE
|
||||
var/decoded_station_name = html_decode(CONFIG_GET(string/cross_comms_name)) //decode station_name to avoid minor_announce double encode // SKYRAT EDIT: CROSS COMMS CONFIG
|
||||
|
||||
switch(news_report)
|
||||
// The nuke was detonated on the syndicate recon outpost
|
||||
if(NUKE_SYNDICATE_BASE)
|
||||
news_message = "In a daring raid, the heroic crew of [decoded_station_name] detonated a nuclear device in the heart of a terrorist base."
|
||||
news_message = "In a daring raid, the heroic crew of [decoded_station_name] \
|
||||
detonated a nuclear device in the heart of a terrorist base."
|
||||
// The station was destroyed by nuke ops
|
||||
if(STATION_DESTROYED_NUKE)
|
||||
news_message = "We would like to reassure all employees that the reports of a Syndicate backed nuclear attack on [decoded_station_name] are, in fact, a hoax. Have a secure day!"
|
||||
news_message = "We would like to reassure all employees that the reports of a Syndicate \
|
||||
backed nuclear attack on [decoded_station_name] are, in fact, a hoax. Have a secure day!"
|
||||
// The station was evacuated (normal result)
|
||||
if(STATION_EVACUATED)
|
||||
// Had an emergency reason supplied to pass along
|
||||
if(emergency_reason)
|
||||
news_message = "[decoded_station_name] has been evacuated after transmitting the following distress beacon:\n\n[html_decode(emergency_reason)]"
|
||||
news_message = "[decoded_station_name] has been evacuated after transmitting \
|
||||
the following distress beacon:\n\n[html_decode(emergency_reason)]"
|
||||
else
|
||||
news_message = "The crew of [decoded_station_name] has been evacuated amid unconfirmed reports of enemy activity."
|
||||
news_message = "The crew of [decoded_station_name] has been \
|
||||
evacuated amid unconfirmed reports of enemy activity."
|
||||
// A blob won
|
||||
if(BLOB_WIN)
|
||||
news_message = "[decoded_station_name] was overcome by an unknown biological outbreak, killing all crew on board. Don't let it happen to you! Remember, a clean work station is a safe work station."
|
||||
if(BLOB_NUKE)
|
||||
news_message = "[decoded_station_name] is currently undergoing decontanimation after a controlled burst of radiation was used to remove a biological ooze. All employees were safely evacuated prior, and are enjoying a relaxing vacation."
|
||||
news_message = "[decoded_station_name] was overcome by an unknown biological outbreak, killing \
|
||||
all crew on board. Don't let it happen to you! Remember, a clean work station is a safe work station."
|
||||
// A blob was destroyed
|
||||
if(BLOB_DESTROYED)
|
||||
news_message = "[decoded_station_name] is currently undergoing decontamination procedures after the destruction of a biological hazard. As a reminder, any crew members experiencing cramps or bloating should report immediately to security for incineration."
|
||||
news_message = "[decoded_station_name] is currently undergoing decontamination procedures \
|
||||
after the destruction of a biological hazard. As a reminder, any crew members experiencing \
|
||||
cramps or bloating should report immediately to security for incineration."
|
||||
// A certain percentage of all cultists managed to escape at the end of round
|
||||
if(CULT_ESCAPE)
|
||||
news_message = "Security Alert: A group of religious fanatics have escaped from [decoded_station_name]."
|
||||
// Cult was completely or almost completely wiped out
|
||||
if(CULT_FAILURE)
|
||||
news_message = "Following the dismantling of a restricted cult aboard [decoded_station_name], we would like to remind all employees that worship outside of the Chapel is strictly prohibited, and cause for termination."
|
||||
news_message = "Following the dismantling of a restricted cult aboard [decoded_station_name], \
|
||||
we would like to remind all employees that worship outside of the Chapel is strictly prohibited, \
|
||||
and cause for termination."
|
||||
// Cult summoned Nar'sie
|
||||
if(CULT_SUMMON)
|
||||
news_message = "Company officials would like to clarify that [decoded_station_name] was scheduled to be decommissioned following meteor damage earlier this year. Earlier reports of an unknowable eldritch horror were made in error."
|
||||
news_message = "Company officials would like to clarify that [decoded_station_name] was scheduled \
|
||||
to be decommissioned following meteor damage earlier this year. Earlier reports of an \
|
||||
unknowable eldritch horror were made in error."
|
||||
// Nuke detonated, but missed the station entirely
|
||||
if(NUKE_MISS)
|
||||
news_message = "The Syndicate have bungled a terrorist attack [decoded_station_name], detonating a nuclear weapon in empty space nearby."
|
||||
news_message = "The Syndicate have bungled a terrorist attack [decoded_station_name], \
|
||||
detonating a nuclear weapon in empty space nearby."
|
||||
// All nuke ops got killed
|
||||
if(OPERATIVES_KILLED)
|
||||
news_message = "Repairs to [decoded_station_name] are underway after an elite Syndicate death squad was wiped out by the crew."
|
||||
news_message = "Repairs to [decoded_station_name] are underway after an elite \
|
||||
Syndicate death squad was wiped out by the crew."
|
||||
// Nuke ops results inconclusive - Crew escaped without the disk, or nukies were left alive, or something
|
||||
if(OPERATIVE_SKIRMISH)
|
||||
news_message = "A skirmish between security forces and Syndicate agents aboard [decoded_station_name] ended with both sides bloodied but intact."
|
||||
news_message = "A skirmish between security forces and Syndicate agents aboard [decoded_station_name] \
|
||||
ended with both sides bloodied but intact."
|
||||
// Revolution victory
|
||||
if(REVS_WIN)
|
||||
news_message = "Company officials have reassured investors that despite a union led revolt aboard [decoded_station_name] there will be no wage increases for workers."
|
||||
news_message = "Company officials have reassured investors that despite a union led revolt \
|
||||
aboard [decoded_station_name] there will be no wage increases for workers."
|
||||
// Revolution defeat
|
||||
if(REVS_LOSE)
|
||||
news_message = "[decoded_station_name] quickly put down a misguided attempt at mutiny. Remember, unionizing is illegal!"
|
||||
news_message = "[decoded_station_name] quickly put down a misguided attempt at mutiny. \
|
||||
Remember, unionizing is illegal!"
|
||||
// All wizards (plus apprentices) have been killed
|
||||
if(WIZARD_KILLED)
|
||||
news_message = "Tensions have flared with the Space Wizard Federation following the death of one of their members aboard [decoded_station_name]."
|
||||
news_message = "Tensions have flared with the Space Wizard Federation following the death \
|
||||
of one of their members aboard [decoded_station_name]."
|
||||
// The station was nuked generically
|
||||
if(STATION_NUKED)
|
||||
news_message = "[decoded_station_name] activated its self-destruct device for unknown reasons. Attempts to clone the Captain for arrest and execution are underway."
|
||||
// There was a blob on board, guess it was nuked to stop it
|
||||
if(length(GLOB.overminds))
|
||||
for(var/mob/camera/blob/overmind as anything in GLOB.overminds)
|
||||
if(overmind.max_count < overmind.announcement_size)
|
||||
continue
|
||||
|
||||
news_message = "[decoded_station_name] is currently undergoing decontanimation after a controlled \
|
||||
burst of radiation was used to remove a biological ooze. All employees were safely evacuated prior, \
|
||||
and are enjoying a relaxing vacation."
|
||||
break
|
||||
// A self destruct or something else
|
||||
else
|
||||
news_message = "[decoded_station_name] activated its self-destruct device for unknown reasons. \
|
||||
Attempts to clone the Captain for arrest and execution are underway."
|
||||
// The emergency escape shuttle was hijacked
|
||||
if(SHUTTLE_HIJACK)
|
||||
news_message = "During routine evacuation procedures, the emergency shuttle of [decoded_station_name] had its navigation protocols corrupted and went off course, but was recovered shortly after."
|
||||
news_message = "During routine evacuation procedures, the emergency shuttle of [decoded_station_name] \
|
||||
had its navigation protocols corrupted and went off course, but was recovered shortly after."
|
||||
// A supermatter cascade triggered
|
||||
if(SUPERMATTER_CASCADE)
|
||||
news_message = "Officials are advising nearby colonies about a newly declared exclusion zone in the sector surrounding [decoded_station_name]."
|
||||
news_message = "Officials are advising nearby colonies about a newly declared exclusion zone in \
|
||||
the sector surrounding [decoded_station_name]."
|
||||
|
||||
//SKYRAT EDIT - START
|
||||
if(SSblackbox.first_death)
|
||||
|
||||
@@ -73,7 +73,8 @@
|
||||
var/has_ever_been_ai = FALSE
|
||||
var/last_death = 0
|
||||
|
||||
/// Set by Into The Sunset command of the shuttle manipulator
|
||||
/// Set by Into The Sunset command of the shuttle manipulator.
|
||||
/// If TRUE, the mob will always be considered "escaped" if they are alive and not exiled.
|
||||
var/force_escaped = FALSE
|
||||
|
||||
var/list/learned_recipes //List of learned recipe TYPES.
|
||||
|
||||
@@ -290,7 +290,11 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
|
||||
// If it got to this part, just pick one high impact ruleset if it exists
|
||||
for(var/datum/dynamic_ruleset/rule in executed_rules)
|
||||
if(rule.flags & HIGH_IMPACT_RULESET)
|
||||
return rule.round_result()
|
||||
rule.round_result()
|
||||
// One was set, so we're done here
|
||||
if(SSticker.news_report)
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/game_mode/dynamic/proc/send_intercept()
|
||||
@@ -503,6 +507,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
|
||||
rule.acceptable(roundstart_pop_ready, threat_level) // Assigns some vars in the modes, running it here for consistency
|
||||
rule.candidates = candidates.Copy()
|
||||
rule.trim_candidates()
|
||||
rule.load_templates()
|
||||
if (rule.ready(roundstart_pop_ready, TRUE))
|
||||
var/cost = rule.cost
|
||||
var/scaled_times = 0
|
||||
@@ -523,6 +528,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
|
||||
if (rule.acceptable(roundstart_pop_ready, threat_level) && round_start_budget >= rule.cost) // If we got the population and threat required
|
||||
rule.candidates = candidates.Copy()
|
||||
rule.trim_candidates()
|
||||
rule.load_templates()
|
||||
if (rule.ready(roundstart_pop_ready) && rule.candidates.len > 0)
|
||||
drafted_rules[rule] = rule.weight
|
||||
|
||||
@@ -630,6 +636,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
|
||||
var/population = GLOB.alive_player_list.len
|
||||
if((new_rule.acceptable(population, threat_level) && (ignore_cost || new_rule.cost <= mid_round_budget)) || forced)
|
||||
new_rule.trim_candidates()
|
||||
new_rule.load_templates()
|
||||
if (new_rule.ready(forced))
|
||||
if (!ignore_cost)
|
||||
spend_midround_budget(new_rule.cost, threat_log, "[worldtime2text()]: Forced rule [new_rule.name]")
|
||||
@@ -682,6 +689,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
|
||||
if (forced_latejoin_rule)
|
||||
forced_latejoin_rule.candidates = list(newPlayer)
|
||||
forced_latejoin_rule.trim_candidates()
|
||||
forced_latejoin_rule.load_templates()
|
||||
log_dynamic("Forcing ruleset [forced_latejoin_rule]")
|
||||
if (forced_latejoin_rule.ready(TRUE))
|
||||
if (!forced_latejoin_rule.repeatable)
|
||||
@@ -704,6 +712,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
|
||||
|
||||
rule.candidates = list(newPlayer)
|
||||
rule.trim_candidates()
|
||||
rule.load_templates()
|
||||
if (rule.ready())
|
||||
drafted_rules[rule] = rule.get_weight()
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
continue
|
||||
|
||||
ruleset.trim_candidates()
|
||||
ruleset.load_templates()
|
||||
if (!ruleset.ready())
|
||||
log_game("DYNAMIC: FAIL: [ruleset] is not ready()")
|
||||
continue
|
||||
|
||||
@@ -85,6 +85,9 @@
|
||||
/// If written as a linear equation, will be in the form of `list("denominator" = denominator, "offset" = offset).
|
||||
var/antag_cap = 0
|
||||
|
||||
/// A list, or null, of templates that the ruleset depends on to function correctly
|
||||
var/list/ruleset_lazy_templates
|
||||
|
||||
/datum/dynamic_ruleset/New()
|
||||
// Rulesets can be instantiated more than once, such as when an admin clicks
|
||||
// "Execute Midround Ruleset". Thus, it would be wrong to perform any
|
||||
@@ -173,6 +176,11 @@
|
||||
/datum/dynamic_ruleset/proc/ready(forced = 0)
|
||||
return check_candidates()
|
||||
|
||||
/// This should always be called before ready is, to ensure that the ruleset can locate map/template based landmarks as needed
|
||||
/datum/dynamic_ruleset/proc/load_templates()
|
||||
for(var/template in ruleset_lazy_templates)
|
||||
SSmapping.lazy_load_template(template)
|
||||
|
||||
/// Runs from gamemode process() if ruleset fails to start, like delayed rulesets not getting valid candidates.
|
||||
/// This one only handles refunding the threat, override in ruleset to clean up the rest.
|
||||
/datum/dynamic_ruleset/proc/clean_up()
|
||||
|
||||
@@ -347,12 +347,12 @@
|
||||
cost = 10
|
||||
requirements = REQUIREMENTS_VERY_HIGH_THREAT_NEEDED
|
||||
flags = HIGH_IMPACT_RULESET
|
||||
ruleset_lazy_templates = list(LAZY_TEMPLATE_KEY_WIZARDDEN)
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/wizard/ready(forced = FALSE)
|
||||
SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_WIZARDDEN)
|
||||
if (!check_candidates())
|
||||
if(!check_candidates())
|
||||
return FALSE
|
||||
if(GLOB.wizardstart.len == 0)
|
||||
if(!length(GLOB.wizardstart))
|
||||
log_admin("Cannot accept Wizard ruleset. Couldn't find any wizard spawn points.")
|
||||
message_admins("Cannot accept Wizard ruleset. Couldn't find any wizard spawn points.")
|
||||
return FALSE
|
||||
|
||||
@@ -273,16 +273,30 @@
|
||||
weight = 2
|
||||
cost = 20
|
||||
requirements = list(90,90,90,80,60,40,30,20,10,10)
|
||||
var/list/roundstart_wizards = list()
|
||||
ruleset_lazy_templates = list(LAZY_TEMPLATE_KEY_WIZARDDEN)
|
||||
|
||||
/datum/dynamic_ruleset/roundstart/wizard/acceptable(population=0, threat=0)
|
||||
SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_WIZARDDEN)
|
||||
if(GLOB.wizardstart.len == 0)
|
||||
/datum/dynamic_ruleset/roundstart/wizard/ready(forced = FALSE)
|
||||
if(!check_candidates())
|
||||
return FALSE
|
||||
if(!length(GLOB.wizardstart))
|
||||
log_admin("Cannot accept Wizard ruleset. Couldn't find any wizard spawn points.")
|
||||
message_admins("Cannot accept Wizard ruleset. Couldn't find any wizard spawn points.")
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/dynamic_ruleset/roundstart/wizard/round_result()
|
||||
for(var/datum/antagonist/wizard/wiz in GLOB.antagonists)
|
||||
var/mob/living/real_wiz = wiz.owner?.current
|
||||
if(isnull(real_wiz))
|
||||
continue
|
||||
|
||||
var/turf/wiz_location = get_turf(real_wiz)
|
||||
// If this wiz is alive AND not in an away level, then we know not all wizards are dead and can leave entirely
|
||||
if(considered_alive(wiz.owner) && wiz_location && !is_away_level(wiz_location.z))
|
||||
return
|
||||
|
||||
SSticker.news_report = WIZARD_KILLED
|
||||
|
||||
/datum/dynamic_ruleset/roundstart/wizard/pre_execute()
|
||||
. = ..()
|
||||
if(GLOB.wizardstart.len == 0)
|
||||
@@ -361,13 +375,25 @@
|
||||
return TRUE
|
||||
|
||||
/datum/dynamic_ruleset/roundstart/bloodcult/round_result()
|
||||
..()
|
||||
if(main_cult.check_cult_victory())
|
||||
SSticker.mode_result = "win - cult win"
|
||||
SSticker.news_report = CULT_SUMMON
|
||||
else
|
||||
SSticker.mode_result = "loss - staff stopped the cult"
|
||||
SSticker.news_report = CULT_FAILURE
|
||||
return
|
||||
|
||||
SSticker.mode_result = "loss - staff stopped the cult"
|
||||
|
||||
if(main_cult.size_at_maximum == 0)
|
||||
CRASH("Cult team existed with a size_at_maximum of 0 at round end!")
|
||||
|
||||
// If more than a certain ratio of our cultists have escaped, give the "cult escape" resport.
|
||||
// Otherwise, give the "cult failure" report.
|
||||
var/ratio_to_be_considered_escaped = 0.5
|
||||
var/escaped_cultists = 0
|
||||
for(var/datum/mind/escapee as anything in main_cult.members)
|
||||
if(considered_escaped(escapee))
|
||||
escaped_cultists++
|
||||
|
||||
SSticker.news_report = (escaped_cultists / main_cult.size_at_maximum) >= ratio_to_be_considered_escaped ? CULT_ESCAPE : CULT_FAILURE
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// //
|
||||
@@ -391,6 +417,7 @@
|
||||
requirements = list(90,90,90,80,60,40,30,20,10,10)
|
||||
flags = HIGH_IMPACT_RULESET
|
||||
antag_cap = list("denominator" = 18, "offset" = 1)
|
||||
ruleset_lazy_templates = list(LAZY_TEMPLATE_KEY_NUKIEBASE)
|
||||
var/required_role = ROLE_NUCLEAR_OPERATIVE
|
||||
var/datum/team/nuclear/nuke_team
|
||||
|
||||
@@ -432,10 +459,10 @@
|
||||
SSticker.news_report = NUKE_SYNDICATE_BASE
|
||||
if(NUKE_RESULT_NUKE_WIN)
|
||||
SSticker.mode_result = "win - syndicate nuke"
|
||||
SSticker.news_report = STATION_NUKED
|
||||
SSticker.news_report = STATION_DESTROYED_NUKE
|
||||
if(NUKE_RESULT_NOSURVIVORS)
|
||||
SSticker.mode_result = "halfwin - syndicate nuke - did not evacuate in time"
|
||||
SSticker.news_report = STATION_NUKED
|
||||
SSticker.news_report = STATION_DESTROYED_NUKE
|
||||
if(NUKE_RESULT_WRONG_STATION)
|
||||
SSticker.mode_result = "halfwin - blew wrong station"
|
||||
SSticker.news_report = NUKE_MISS
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
|
||||
ruleset.trim_candidates()
|
||||
|
||||
ruleset.load_templates()
|
||||
if (!ruleset.ready())
|
||||
continue
|
||||
|
||||
|
||||
@@ -212,14 +212,14 @@
|
||||
//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_DESTROYED_NUKE
|
||||
if(EMERGENCY_ESCAPED_OR_ENDGAMED)
|
||||
SSticker.news_report = STATION_EVACUATED
|
||||
if(SSshuttle.emergency.is_hijacked())
|
||||
SSticker.news_report = SHUTTLE_HIJACK
|
||||
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()
|
||||
|
||||
@@ -61,21 +61,28 @@ GLOBAL_LIST_EMPTY(objectives) //SKYRAT EDIT ADDITION
|
||||
|
||||
update_explanation_text()
|
||||
|
||||
/datum/objective/proc/considered_escaped(datum/mind/M)
|
||||
if(!considered_alive(M))
|
||||
/**
|
||||
* Checks if the passed mind is considered "escaped".
|
||||
*
|
||||
* Escaped mobs are used to check certain antag objectives / results.
|
||||
*
|
||||
* Escaped includes minds with alive, non-exiled mobs generally.
|
||||
*/
|
||||
/proc/considered_escaped(datum/mind/escapee)
|
||||
if(!considered_alive(escapee))
|
||||
return FALSE
|
||||
if(considered_exiled(M))
|
||||
if(considered_exiled(escapee))
|
||||
return FALSE
|
||||
if(M.force_escaped)
|
||||
if(escapee.force_escaped)
|
||||
return TRUE
|
||||
if(SSticker.force_ending || GLOB.station_was_nuked) // Just let them win.
|
||||
return TRUE
|
||||
if(SSshuttle.emergency.mode != SHUTTLE_ENDGAME)
|
||||
return FALSE
|
||||
var/area/current_area = get_area(M.current)
|
||||
var/area/current_area = get_area(escapee.current)
|
||||
if(!current_area || istype(current_area, /area/shuttle/escape/brig)) // Fails if they are in the shuttle brig
|
||||
return FALSE
|
||||
var/turf/current_turf = get_turf(M.current)
|
||||
var/turf/current_turf = get_turf(escapee.current)
|
||||
return current_turf.onCentCom() || current_turf.onSyndieBase()
|
||||
|
||||
/datum/objective/proc/check_completion()
|
||||
|
||||
@@ -115,4 +115,3 @@ GLOBAL_LIST_EMPTY(antagonist_teams)
|
||||
///Custom names for individuals in a team
|
||||
/datum/team/proc/antag_listing_name()
|
||||
return name
|
||||
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
/// Type path for the associated job datum.
|
||||
var/role_job = /datum/job/abductor_agent
|
||||
|
||||
/datum/antagonist/abductor/New()
|
||||
// lets get the loading started now, but don't block waiting for it
|
||||
INVOKE_ASYNC(SSmapping, TYPE_PROC_REF(/datum/controller/subsystem/mapping, lazy_load_template), LAZY_TEMPLATE_KEY_ABDUCTOR_SHIPS)
|
||||
return ..()
|
||||
|
||||
/datum/antagonist/abductor/get_preview_icon()
|
||||
var/mob/living/carbon/human/dummy/consistent/scientist = new
|
||||
var/mob/living/carbon/human/dummy/consistent/agent = new
|
||||
@@ -99,6 +104,8 @@
|
||||
H.real_name = "[team.name] [sub_role]"
|
||||
H.equipOutfit(outfit)
|
||||
|
||||
// We require that the template be loaded here, so call it in a blocking manner, if its already done loading, this won't block
|
||||
SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_ABDUCTOR_SHIPS)
|
||||
//Teleport to ship
|
||||
for(var/obj/effect/landmark/abductor/LM in GLOB.landmarks_list)
|
||||
if(istype(LM, landmark_type) && LM.team_number == team.team_number)
|
||||
@@ -116,7 +123,6 @@
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/abductor/admin_add(datum/mind/new_owner,mob/admin)
|
||||
SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_ABDUCTOR_SHIPS)
|
||||
var/list/current_teams = list()
|
||||
for(var/datum/team/abductor_team/T in GLOB.antagonist_teams)
|
||||
current_teams[T.name] = T
|
||||
|
||||
@@ -135,6 +135,8 @@ GLOBAL_LIST_EMPTY(blob_nodes)
|
||||
if(autoplace_max_time && world.time >= autoplace_max_time)
|
||||
place_blob_core(BLOB_RANDOM_PLACEMENT)
|
||||
else
|
||||
// If we get here, it means yes: the blob is kill
|
||||
SSticker.news_report = BLOB_DESTROYED
|
||||
qdel(src)
|
||||
else if(!victory_in_progress && (blobs_legit.len >= blobwincount))
|
||||
victory_in_progress = TRUE
|
||||
|
||||
@@ -271,6 +271,8 @@
|
||||
|
||||
///Has narsie been summoned yet?
|
||||
var/narsie_summoned = FALSE
|
||||
///How large were we at max size.
|
||||
var/size_at_maximum = 0
|
||||
|
||||
/datum/team/cult/proc/check_size()
|
||||
if(cult_ascendent)
|
||||
@@ -305,6 +307,13 @@
|
||||
cult_ascendent = TRUE
|
||||
log_game("The blood cult has ascended with [cultplayers] players.")
|
||||
|
||||
/datum/team/cult/add_member(datum/mind/new_member)
|
||||
. = ..()
|
||||
// A little hacky, but this checks that cult ghosts don't contribute to the size at maximum value.
|
||||
if(is_unassigned_job(new_member.assigned_role))
|
||||
return
|
||||
size_at_maximum++
|
||||
|
||||
/datum/team/cult/proc/make_image(datum/objective/sacrifice/sac_objective)
|
||||
var/datum/job/job_of_sacrifice = sac_objective.target.assigned_role
|
||||
var/datum/preferences/prefs_of_sacrifice = sac_objective.target.current.client.prefs
|
||||
|
||||
@@ -869,7 +869,8 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
to_chat(user, span_cultitalic("Your blood begins flowing into [src]. You must remain in place and conscious to maintain the forms of those summoned. This will hurt you slowly but surely..."))
|
||||
var/obj/structure/emergency_shield/cult/weak/N = new(T)
|
||||
new_human.key = ghost_to_spawn.key
|
||||
new_human.mind?.add_antag_datum(/datum/antagonist/cult)
|
||||
var/datum/antagonist/cult/created_cultist = new_human.mind?.add_antag_datum(/datum/antagonist/cult)
|
||||
created_cultist?.silent = TRUE
|
||||
to_chat(new_human, span_cultitalic("<b>You are a servant of the Geometer. You have been made semi-corporeal by the cult of Nar'Sie, and you are to serve them at all costs.</b>"))
|
||||
|
||||
while(!QDELETED(src) && !QDELETED(user) && !QDELETED(new_human) && (user in T))
|
||||
@@ -885,7 +886,9 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
span_cultlarge("Your link to the world fades. Your form breaks apart."))
|
||||
for(var/obj/I in new_human)
|
||||
new_human.dropItemToGround(I, TRUE)
|
||||
new_human.mind?.remove_antag_datum(/datum/antagonist/cult)
|
||||
new_human.dust()
|
||||
|
||||
else if(choice == "Ascend as a Dark Spirit")
|
||||
affecting = user
|
||||
affecting.add_atom_colour(RUNE_COLOR_DARKRED, ADMIN_COLOUR_PRIORITY)
|
||||
|
||||
@@ -25,6 +25,11 @@
|
||||
/// The amount of limited discounts that the team get
|
||||
var/discount_limited_amount = 10
|
||||
|
||||
/datum/antagonist/nukeop/New()
|
||||
if(send_to_spawnpoint) // lets get the loading started now, but don't block waiting for it
|
||||
INVOKE_ASYNC(SSmapping, TYPE_PROC_REF(/datum/controller/subsystem/mapping, lazy_load_template), LAZY_TEMPLATE_KEY_NUKIEBASE)
|
||||
return ..()
|
||||
|
||||
/datum/antagonist/nukeop/proc/equip_op()
|
||||
if(!ishuman(owner.current))
|
||||
return
|
||||
@@ -118,6 +123,9 @@
|
||||
objectives |= nuke_team.objectives
|
||||
|
||||
/datum/antagonist/nukeop/proc/move_to_spawnpoint()
|
||||
// Ensure that the nukiebase is loaded, and wait for it if required
|
||||
SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_NUKIEBASE)
|
||||
|
||||
var/team_number = 1
|
||||
if(nuke_team)
|
||||
team_number = nuke_team.members.Find(owner)
|
||||
@@ -127,7 +135,6 @@
|
||||
owner.current.forceMove(pick(GLOB.nukeop_leader_start))
|
||||
|
||||
/datum/antagonist/nukeop/create_team(datum/team/nuclear/new_team)
|
||||
SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_NUKIEBASE)
|
||||
if(!new_team)
|
||||
if(!always_new_team)
|
||||
for(var/datum/antagonist/nukeop/N in GLOB.antagonists)
|
||||
|
||||
@@ -28,7 +28,9 @@
|
||||
/datum/outfit/syndicate/post_equip(mob/living/carbon/human/nukie, visualsOnly = FALSE)
|
||||
if(visualsOnly)
|
||||
return
|
||||
SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_NUKIEBASE)
|
||||
|
||||
// We don't require the nukiebase be loaded to function, but lets go ahead and kick off loading just in case
|
||||
INVOKE_ASYNC(SSmapping, TYPE_PROC_REF(/datum/controller/subsystem/mapping, lazy_load_template), LAZY_TEMPLATE_KEY_NUKIEBASE)
|
||||
var/obj/item/radio/radio = nukie.ears
|
||||
radio.set_frequency(FREQ_SYNDICATE)
|
||||
radio.freqlock = RADIO_FREQENCY_LOCKED
|
||||
|
||||
@@ -626,7 +626,7 @@
|
||||
|
||||
var/heads_report = "<b>Heads of Staff</b><br>"
|
||||
heads_report += "<table cellspacing=5>"
|
||||
for(var/datum/mind/N in SSjob.get_living_heads())
|
||||
for(var/datum/mind/N as anything in SSjob.get_living_heads())
|
||||
var/mob/M = N.current
|
||||
if(M)
|
||||
heads_report += "<tr><td><a href='?_src_=holder;[HrefToken()];adminplayeropts=[REF(M)]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
|
||||
@@ -21,6 +21,11 @@ GLOBAL_LIST_EMPTY(wizard_spellbook_purchases_by_key)
|
||||
var/wiz_age = WIZARD_AGE_MIN /* Wizards by nature cannot be too young. */
|
||||
show_to_ghosts = TRUE
|
||||
|
||||
/datum/antagonist/wizard/New()
|
||||
if(move_to_lair) // kick off loading of your lair, if you want to be moved to it
|
||||
INVOKE_ASYNC(SSmapping, TYPE_PROC_REF(/datum/controller/subsystem/mapping, lazy_load_template), LAZY_TEMPLATE_KEY_WIZARDDEN)
|
||||
return ..()
|
||||
|
||||
/datum/antagonist/wizard_minion
|
||||
name = "Wizard Minion"
|
||||
antagpanel_category = "Wizard"
|
||||
@@ -92,7 +97,9 @@ GLOBAL_LIST_EMPTY(wizard_spellbook_purchases_by_key)
|
||||
wiz_team.master_wizard = src
|
||||
|
||||
/datum/antagonist/wizard/proc/send_to_lair()
|
||||
// And now we ensure that its loaded
|
||||
SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_WIZARDDEN)
|
||||
|
||||
if(!owner)
|
||||
CRASH("Antag datum with no owner.")
|
||||
if(!owner.current)
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
/datum/job/nuclear_operative
|
||||
title = ROLE_NUCLEAR_OPERATIVE
|
||||
|
||||
|
||||
/datum/job/nuclear_operative/get_roundstart_spawn_point()
|
||||
SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_NUKIEBASE)
|
||||
return pick(GLOB.nukeop_start)
|
||||
|
||||
/datum/job/nuclear_operative/get_latejoin_spawn_point()
|
||||
SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_NUKIEBASE)
|
||||
return pick(GLOB.nukeop_start)
|
||||
|
||||
@@ -3,9 +3,7 @@
|
||||
faction = ROLE_WIZARD
|
||||
|
||||
/datum/job/space_wizard/get_roundstart_spawn_point()
|
||||
SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_WIZARDDEN)
|
||||
return pick(GLOB.wizardstart)
|
||||
|
||||
/datum/job/space_wizard/get_latejoin_spawn_point()
|
||||
SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_WIZARDDEN)
|
||||
return pick(GLOB.wizardstart)
|
||||
|
||||
@@ -181,8 +181,9 @@
|
||||
|
||||
/obj/machinery/computer/emergency_shuttle/proc/increase_hijack_stage()
|
||||
var/obj/docking_port/mobile/emergency/shuttle = SSshuttle.emergency
|
||||
// Begin loading this early, otherwise we get an awkward 30 second delay on the
|
||||
SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_NUKIEBASE)
|
||||
// Begin loading this early, prevents a delay when the shuttle goes to land
|
||||
INVOKE_ASYNC(SSmapping, TYPE_PROC_REF(/datum/controller/subsystem/mapping, lazy_load_template), LAZY_TEMPLATE_KEY_NUKIEBASE)
|
||||
|
||||
shuttle.hijack_status++
|
||||
if(hijack_announce)
|
||||
announce_hijack_stage()
|
||||
@@ -542,6 +543,7 @@
|
||||
// unless the shuttle is "hijacked"
|
||||
var/destination_dock = "emergency_away"
|
||||
if(is_hijacked() || elimination_hijack())
|
||||
// just double check
|
||||
SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_NUKIEBASE)
|
||||
destination_dock = "emergency_syndicate"
|
||||
minor_announce("Corruption detected in \
|
||||
|
||||
Reference in New Issue
Block a user