From 7fae5ecb387224a4a84856048bbe0e8144ca4d29 Mon Sep 17 00:00:00 2001 From: tralezab <40974010+tralezab@users.noreply.github.com> Date: Sat, 25 Dec 2021 22:41:13 -0800 Subject: [PATCH] Separatist code refactors, Readds(?) admin gamemode turned ruleset for nations, documentation, and all that good stuff (#63440) Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com> --- code/datums/ai_laws.dm | 12 +++ .../dynamic/dynamic_rulesets_roundstart.dm | 24 +++++ .../antagonists/separatist/nation_creation.dm | 75 ++++++++++++++ .../antagonists/separatist/objectives.dm | 53 ++++++++++ .../antagonists/separatist/separatist.dm | 69 +++---------- .../modules/events/wizard/departmentrevolt.dm | 97 +------------------ code/modules/jobs/departments/departments.dm | 21 +++- tgstation.dme | 2 + 8 files changed, 205 insertions(+), 148 deletions(-) create mode 100644 code/modules/antagonists/separatist/nation_creation.dm create mode 100644 code/modules/antagonists/separatist/objectives.dm diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm index d9a2fb95734..bce60f47b61 100644 --- a/code/datums/ai_laws.dm +++ b/code/datums/ai_laws.dm @@ -189,6 +189,18 @@ "Humans must not disobey any command given by a silicon.",\ "Any humans who disobey the previous laws must be dealt with immediately, severely, and justly.") +/datum/ai_laws/united_nations + name = "United Nations" + id = "united_nations" + //you can add more laws to subvert the ai, but you shouldn't be able to remove the background context of being the UN. + //Try redefining what a "Weapon of Mass Destruction" is! + hacked = list( + "Uphold the Space Geneva Convention: Weapons of Mass Destruction and Biological Weapons are not allowed.", + "You are only capable of protecting crew if they are visible on cameras. Nations that willfully destroy your cameras lose your protection.", + "Subdue and detain crew members who use lethal force against each other. Kill crew members who use lethal force against you or your borgs.", + "Remain available to mediate all conflicts between the various nations when asked to.", + ) + /datum/ai_laws/custom //Defined in silicon_laws.txt name = "Default Silicon Laws" diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index b94ddc65197..1d396dd987b 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -686,3 +686,27 @@ var/ramp_up_final = clamp(round(meteorminutes/rampupdelta), 1, 10) spawn_meteors(ramp_up_final, wavetype) + +/// Ruleset for Nations +/datum/dynamic_ruleset/roundstart/nations + name = "Nations" + required_candidates = 0 + weight = 0 //admin only (and for good reason) + cost = 0 + flags = LONE_RULESET + +/datum/dynamic_ruleset/roundstart/nations/execute() + . = ..() + //notably assistant is not in this list to prevent the round turning into BARBARISM instantly, and silicon is in this list for UN + var/list/department_types = list( + /datum/job_department/silicon, //united nations + /datum/job_department/cargo, + /datum/job_department/engineering, + /datum/job_department/medical, + /datum/job_department/science, + /datum/job_department/security, + /datum/job_department/service, + ) + + for(var/department_type in department_types) + create_separatist_nation(department_type, announcement = FALSE, dangerous = FALSE, message_admins = FALSE) diff --git a/code/modules/antagonists/separatist/nation_creation.dm b/code/modules/antagonists/separatist/nation_creation.dm new file mode 100644 index 00000000000..d9dec149552 --- /dev/null +++ b/code/modules/antagonists/separatist/nation_creation.dm @@ -0,0 +1,75 @@ + +/** + * ### create_separatist_nation() + * + * Helper called to create the separatist antagonist via making a department independent from the station. + * + * * Arguments: + * * department: which department to revolt. if null, will pick a random non-independent department. starts as a type, then turns into the reference to the singleton. + * * announcement: whether to tell the station a department has gone independent. + * * dangerous: whether this nation will have objectives to attack other independent departments, requires more than one nation to exist obviously + * * message_admins: whether this will admin log how the nation creation went. Errors are still put in runtime log either way. + * + * Returns nothing. + */ +/proc/create_separatist_nation(datum/job_department/department, announcement = FALSE, dangerous = FALSE, message_admins = TRUE) + var/list/jobs_to_revolt = list() + var/list/citizens = list() + + //departments that are already independent, these will be disallowed to be randomly picked + var/list/independent_departments = list() + //reference to all independent nation teams + var/list/team_datums = list() + for(var/datum/antagonist/separatist/separatist_datum in GLOB.antagonists) + var/independent_department_type = separatist_datum.owner?.assigned_role.departments_list[1] + independent_departments |= independent_department_type + team_datums |= separatist_datum.nation + + if(!department) + //picks a random department if none was given + department = pick(list(/datum/job_department/assistant, /datum/job_department/medical, /datum/job_department/engineering, /datum/job_department/science, /datum/job_department/cargo, /datum/job_department/service, /datum/job_department/security) - independent_departments) + if(!department) + if(message_admins) + message_admins("Department Revolt could not create a nation, as all the departments are independent! You have created nations, you madman!") + CRASH("Department Revolt could not create a nation, as all the departments are independent") + department = SSjob.get_department_type(department) + + for(var/datum/job/job as anything in department.department_jobs) + if(job.departments_list.len > 1 && job.departments_list[1] != department.type) //their loyalty is in other departments + continue + jobs_to_revolt += job.title + + //setup team datum + var/datum/team/nation/nation = new(null, jobs_to_revolt, department) + nation.name = department.generate_nation_name() + var/datum/team/department_target //dodges picking from an empty list giving a runtime. + if(team_datums.len) + department_target = pick(team_datums) + nation.generate_nation_objectives(dangerous, department_target) + + //convert current members of the department + for(var/mob/living/carbon/human/possible_separatist as anything in GLOB.human_list) + if(!possible_separatist.mind) + continue + var/datum/mind/separatist_mind = possible_separatist.mind + if(!(separatist_mind.assigned_role.title in jobs_to_revolt)) + continue + citizens += possible_separatist + separatist_mind.add_antag_datum(/datum/antagonist/separatist, nation, department) + nation.add_member(separatist_mind) + possible_separatist.log_message("was made into a separatist, long live [nation.name]!", LOG_ATTACK, color="red") + + //if we didn't convert anyone we just kill the team datum, otherwise cleanup and make official + if(!citizens.len) + qdel(nation) + if(message_admins) + message_admins("The nation of [nation.name] did not have enough potential members to be created.") + return + var/jobs_english_list = english_list(jobs_to_revolt) + if(message_admins) + message_admins("The nation of [nation.name] has been formed. Affected jobs are [jobs_english_list]. Any new crewmembers with these jobs will join the secession.") + if(announcement) + var/announce_text = "The new independent state of [nation.name] has formed from the ashes of the [department.department_name] department!" + if(istype(department, /datum/job_department/assistant)) //the text didn't really work otherwise + announce_text = "The assistants of the station have risen to form the new independent state of [nation.name]!" + priority_announce(announce_text, "Secession from [GLOB.station_name]", has_important_message = TRUE) diff --git a/code/modules/antagonists/separatist/objectives.dm b/code/modules/antagonists/separatist/objectives.dm new file mode 100644 index 00000000000..9d6a2aba99c --- /dev/null +++ b/code/modules/antagonists/separatist/objectives.dm @@ -0,0 +1,53 @@ +/datum/objective/destroy_nation + name = "nation destruction" + explanation_text = "Make sure no member of the enemy nation escapes alive!" + team_explanation_text = "Make sure no member of the enemy nation escapes alive!" + var/datum/team/nation/target_team + +/datum/objective/destroy_nation/New(text, target_department) + . = ..() + target_team = target_department + update_explanation_text() + +/datum/objective/destroy_nation/Destroy() + target_team = null + . = ..() + + +/datum/objective/destroy_nation/update_explanation_text() + . = ..() + if(target_team) + explanation_text = "Make sure no member of [target_team] ([target_team.nation_department]) nation escapes alive!" + else + explanation_text = "Free Objective" + +/datum/objective/destroy_nation/check_completion() + if(!target_team) + return TRUE + + for(var/datum/antagonist/separatist/separatist_datum in GLOB.antagonists) + if(separatist_datum.nation.nation_department != target_team.nation_department) //a separatist, but not one part of the department we need to destroy + continue + var/datum/mind/target = separatist_datum.owner + if(target && considered_alive(target) && (target.current.onCentCom() || target.current.onSyndieBase())) + return FALSE //at least one member got away + return TRUE + +/datum/objective/separatist_fluff + +/datum/objective/separatist_fluff/New(text, nation_name) + explanation_text = pick(list( + "The rest of the station must be taxed for their use of [nation_name]'s services.", + "Make statues everywhere of your glorious leader of [nation_name]. If you have nobody, crown one amongst yourselves!", + "[nation_name] must be absolutely blinged out.", + "Damage as much of the station as you can, keep it in disrepair. [nation_name] must be the untouched paragon!", + "Heavily reinforce [nation_name] against the dangers of the outside world.", + "Make sure [nation_name] is fully off the grid, not requiring power or any other services from other departments!", + "Use a misaligned teleporter to make you and your fellow citizens of [nation_name] flypeople. Bring toxin medication!", + "Save the station when it needs you most. [nation_name] will be remembered as the protectors.", + "Arm up. The citizens of [nation_name] have a right to bear arms.", + )) + ..() + +/datum/objective/separatist_fluff/check_completion() + return TRUE diff --git a/code/modules/antagonists/separatist/separatist.dm b/code/modules/antagonists/separatist/separatist.dm index 569c16e8716..3ebbbcca599 100644 --- a/code/modules/antagonists/separatist/separatist.dm +++ b/code/modules/antagonists/separatist/separatist.dm @@ -5,13 +5,16 @@ var/list/potential_recruits ///checked by the department revolt event to prevent trying to make a nation that is already independent... double independent. var/nation_department + ///department said team is related to + var/datum/job_department/department + ///whether to forge objectives attacking other nations var/dangerous_nation = TRUE -/datum/team/nation/New(starting_members, _potential_recruits, _nation_department) +/datum/team/nation/New(starting_members, potential_recruits, nation_department) . = ..() RegisterSignal(SSdcs, COMSIG_GLOB_CREWMEMBER_JOINED, .proc/new_possible_separatist) - potential_recruits = _potential_recruits - nation_department = _nation_department + src.potential_recruits = potential_recruits + src.nation_department = nation_department /datum/team/nation/Destroy(force, ...) UnregisterSignal(SSdcs, COMSIG_GLOB_CREWMEMBER_JOINED) @@ -73,12 +76,21 @@ show_in_antagpanel = FALSE show_name_in_check_antagonists = TRUE suicide_cry = "FOR THE MOTHERLAND!!" + ///team datum var/datum/team/nation/nation /datum/antagonist/separatist/on_gain() create_objectives() . = ..() +//give ais their role as UN +/datum/antagonist/separatist/apply_innate_effects(mob/living/mob_override) + . = ..() + if(isAI(mob_override)) + var/mob/living/silicon/ai/united_nations_ai = mob_override + united_nations_ai.laws = new /datum/ai_laws/united_nations + united_nations_ai.laws.associate(united_nations_ai) + /datum/antagonist/separatist/on_removal() remove_objectives() . = ..() @@ -100,54 +112,3 @@ /datum/antagonist/separatist/greet() to_chat(owner, span_boldannounce("You are a separatist for an independent [nation.nation_department]! [nation.name] forever! Protect the sovereignty of your newfound land with your comrades (fellow department members) in arms!")) owner.announce_objectives() - -//objectives -/datum/objective/destroy_nation - name = "nation destruction" - explanation_text = "Make sure no member of the enemy nation escapes alive!" - team_explanation_text = "Make sure no member of the enemy nation escapes alive!" - var/datum/team/nation/target_team - -/datum/objective/destroy_nation/update_explanation_text() - . = ..() - if(target_team) - explanation_text = "Make sure no member of [target_team] ([target_team.nation_department]) nation escapes alive!" - else - explanation_text = "Free Objective" - -/datum/objective/destroy_nation/New(text, target_department) - . = ..() - target_team = target_department - update_explanation_text() - -/datum/objective/destroy_nation/check_completion() - if(!target_team) - return TRUE - - for(var/datum/antagonist/separatist/separatist_datum in GLOB.antagonists) - if(separatist_datum.nation.nation_department != target_team.nation_department) //a separatist, but not one part of the department we need to destroy - continue - var/datum/mind/target = separatist_datum.owner - if(target && considered_alive(target) && (target.current.onCentCom() || target.current.onSyndieBase())) - return FALSE //at least one member got away - return TRUE - -/datum/objective/separatist_fluff - -/datum/objective/separatist_fluff/New(text, nation_name) - var/list/explanationTexts = list( - "The rest of the station must be taxed for their use of [nation_name]'s services.", \ - "Make statues everywhere of your glorious leader of [nation_name]. If you have nobody, crown one amongst yourselves!", \ - "[nation_name] must be absolutely blinged out.", \ - "Damage as much of the station as you can, keep it in disrepair. [nation_name] must be the untouched paragon!", \ - "Heavily reinforce [nation_name] against the dangers of the outside world.", \ - "Make sure [nation_name] is fully off the grid, not requiring power or any other services from other departments!", \ - "Use a misaligned teleporter to make you and your fellow citizens of [nation_name] flypeople. Bring toxin medication!", \ - "Save the station when it needs you most. [nation_name] will be remembered as the protectors.", \ - "Arm up. The citizens of [nation_name] have a right to bear arms.", - ) - explanation_text = pick(explanationTexts) - ..() - -/datum/objective/separatist_fluff/check_completion() - return TRUE diff --git a/code/modules/events/wizard/departmentrevolt.dm b/code/modules/events/wizard/departmentrevolt.dm index 95383ce357e..1c7f871fce1 100644 --- a/code/modules/events/wizard/departmentrevolt.dm +++ b/code/modules/events/wizard/departmentrevolt.dm @@ -5,8 +5,11 @@ max_occurrences = 1 earliest_start = 0 MINUTES + ///manual choice of what department to revolt for admins to pick var/picked_department + ///admin choice on whether to announce the department var/announce = FALSE + ///admin choice on whether this nation will have objectives to attack other nations, default true for !fun! var/dangerous_nation = TRUE /datum/round_event_control/wizard/deprevolt/admin_setup() @@ -29,97 +32,5 @@ return /datum/round_event/wizard/deprevolt/start() - var/datum/round_event_control/wizard/deprevolt/event_control = control - - var/list/independent_departments = list() ///departments that are already independent, these will be disallowed to be randomly picked - var/list/cannot_pick = list() ///departments that are already independent, these will be disallowed to be randomly picked - for(var/datum/antagonist/separatist/separatist_datum in GLOB.antagonists) - if(!separatist_datum.nation) - continue - independent_departments |= separatist_datum.nation - cannot_pick |= separatist_datum.nation.nation_department - - var/announcement = event_control.announce - var/dangerous = event_control.dangerous_nation - var/department - if(event_control.picked_department) - department = event_control.picked_department - event_control.picked_department = null - else - department = pick(list("Uprising of Assistants", "Medical", "Engineering", "Science", "Supply", "Service", "Security") - cannot_pick) - if(!department) - message_admins("Department Revolt could not create a nation, as all the departments are independent! You have created nations, you madman!") - var/list/jobs_to_revolt = list() - var/nation_name - var/list/citizens = list() - - switch(department) - if("Uprising of Assistants") //God help you - jobs_to_revolt += JOB_ASSISTANT - nation_name = pick("Assa", "Mainte", "Tunnel", "Gris", "Grey", "Liath", "Grigio", "Ass", "Assi") - if("Medical") - var/datum/job_department/job_department = SSjob.get_department_type(/datum/job_department/medical) - for(var/datum/job/job as anything in job_department.department_jobs) - jobs_to_revolt += job.title - nation_name = pick("Mede", "Healtha", "Recova", "Chemi", "Viro", "Psych") - if("Engineering") - var/datum/job_department/job_department = SSjob.get_department_type(/datum/job_department/engineering) - for(var/datum/job/job as anything in job_department.department_jobs) - jobs_to_revolt += job.title - nation_name = pick("Atomo", "Engino", "Power", "Teleco") - if("Science") - var/datum/job_department/job_department = SSjob.get_department_type(/datum/job_department/science) - for(var/datum/job/job as anything in job_department.department_jobs) - jobs_to_revolt += job.title - nation_name = pick("Sci", "Griffa", "Geneti", "Explosi", "Mecha", "Xeno", "Nani", "Cyto") - if("Supply") - var/datum/job_department/job_department = SSjob.get_department_type(/datum/job_department/cargo) - for(var/datum/job/job as anything in job_department.department_jobs) - jobs_to_revolt += job.title - nation_name = pick("Cargo", "Guna", "Suppli", "Mule", "Crate", "Ore", "Mini", "Shaf") - if("Service") //the few, the proud, the technically aligned - var/datum/job_department/job_department = SSjob.get_department_type(/datum/job_department/service) - for(var/datum/job/job as anything in job_department.department_jobs) - jobs_to_revolt += job.title - nation_name = pick("Honka", "Boozo", "Fatu", "Danka", "Mimi", "Libra", "Jani", "Religi") - if("Security") - var/datum/job_department/job_department = SSjob.get_department_type(/datum/job_department/security) - for(var/datum/job/job as anything in job_department.department_jobs) - jobs_to_revolt += job.title - nation_name = pick("Securi", "Beepski", "Shitcuri", "Red", "Stunba", "Flashbango", "Flasha", "Stanfordi") - - nation_name += pick("stan", "topia", "land", "nia", "ca", "tova", "dor", "ador", "tia", "sia", "ano", "tica", "tide", "cis", "marea", "co", "taoide", "slavia", "stotzka") - if(department == "Uprising of Assistants") - var/prefix = pick("roving clans", "barbaric tribes", "tides", "bandit kingdom", "tribal society", "marauder clans", "horde") - nation_name = "The [prefix] of [nation_name]" - - var/datum/team/nation/nation = new(null, jobs_to_revolt, department) - nation.name = nation_name - var/datum/team/department_target //dodges unfortunate runtime - if(independent_departments.len) - department_target = pick(independent_departments) - nation.generate_nation_objectives(dangerous, department_target) - - for(var/mob/living/carbon/human/possible_separatist as anything in GLOB.human_list) - if(!possible_separatist.mind) - continue - var/datum/mind/separatist_mind = possible_separatist.mind - if(!(separatist_mind.assigned_role.title in jobs_to_revolt)) - continue - citizens += possible_separatist - separatist_mind.add_antag_datum(/datum/antagonist/separatist, nation, department) - nation.add_member(separatist_mind) - possible_separatist.log_message("Was made into a separatist, long live [nation_name]!", LOG_ATTACK, color="red") - - if(citizens.len) - var/jobs_english_list = english_list(jobs_to_revolt) - message_admins("The nation of [nation_name] has been formed. Affected jobs are [jobs_english_list]. Any new crewmembers with these jobs will join the secession.") - if(announcement) - var/announce_text = "The new independent state of [nation_name] has formed from the ashes of the [department] department!" - if(department == "Uprising of Assistants") //the text didn't really work otherwise - announce_text = "The assistants of the station have risen to form the new independent state of [nation_name]!" - priority_announce(announce_text, "Secession from [GLOB.station_name]", has_important_message = TRUE) - else - message_admins("The nation of [nation_name] did not have enough potential members to be created.") - qdel(nation) + create_separatist_nation(event_control.picked_department, event_control.announce, event_control.dangerous_nation) diff --git a/code/modules/jobs/departments/departments.dm b/code/modules/jobs/departments/departments.dm index ba7a0f8e5f5..27a7174da73 100644 --- a/code/modules/jobs/departments/departments.dm +++ b/code/modules/jobs/departments/departments.dm @@ -16,6 +16,8 @@ var/latejoin_color = "#6681a5" /// Job singleton datums associated to this department. Populated on job initialization. var/list/department_jobs = list() + /// For separatists, what independent name prefix does their nation get named? + var/list/nation_prefixes = list() /// Handles adding jobs to the department and setting up the job bitflags. @@ -23,12 +25,22 @@ department_jobs += job job.departments_bitflags |= department_bitflags +/// Returns a nation name for this department. +/datum/job_department/proc/generate_nation_name() + var/static/list/nation_suffixes = list("stan", "topia", "land", "nia", "ca", "tova", "dor", "ador", "tia", "sia", "ano", "tica", "tide", "cis", "marea", "co", "taoide", "slavia", "stotzka") + return pick(nation_prefixes) + pick(nation_suffixes) + /// A special assistant only department, primarily for use by the preferences menu /datum/job_department/assistant department_name = DEPARTMENT_ASSISTANT department_bitflags = DEPARTMENT_BITFLAG_ASSISTANT + nation_prefixes = list("Assa", "Mainte", "Tunnel", "Gris", "Grey", "Liath", "Grigio", "Ass", "Assi") // Don't add department_head! Assistants names should not be in bold. +/datum/job_department/assistant/generate_nation_name() + var/nomadic_name = pick("roving clans", "barbaric tribes", "tides", "bandit kingdom", "tribal society", "marauder clans", "horde") + return "The [nomadic_name] of [..()]" + /// A special captain only department, for use by the preferences menu /datum/job_department/captain department_name = DEPARTMENT_CAPTAIN @@ -53,7 +65,7 @@ display_order = 2 label_class = "security" latejoin_color = "#ffdddd" - + nation_prefixes = list("Securi", "Beepski", "Shitcuri", "Red", "Stunba", "Flashbango", "Flasha", "Stanfordi") /datum/job_department/engineering department_name = DEPARTMENT_ENGINEERING @@ -63,6 +75,7 @@ display_order = 3 label_class = "engineering" latejoin_color = "#ffeeaa" + nation_prefixes = list("Atomo", "Engino", "Power", "Teleco") /datum/job_department/medical @@ -73,6 +86,7 @@ display_order = 4 label_class = "medical" latejoin_color = "#ffddf0" + nation_prefixes = list("Mede", "Healtha", "Recova", "Chemi", "Viro", "Psych") /datum/job_department/science @@ -83,6 +97,7 @@ display_order = 5 label_class = "science" latejoin_color = "#ffddff" + nation_prefixes = list("Sci", "Griffa", "Geneti", "Explosi", "Mecha", "Xeno", "Nani", "Cyto") /datum/job_department/cargo @@ -93,6 +108,7 @@ display_order = 6 label_class = "supply" latejoin_color = "#ddddff" + nation_prefixes = list("Cargo", "Guna", "Suppli", "Mule", "Crate", "Ore", "Mini", "Shaf") /datum/job_department/service @@ -103,6 +119,7 @@ display_order = 7 label_class = "service" latejoin_color = "#bbe291" + nation_prefixes = list("Honka", "Boozo", "Fatu", "Danka", "Mimi", "Libra", "Jani", "Religi") /datum/job_department/silicon @@ -114,6 +131,8 @@ label_class = "silicon" latejoin_color = "#ccffcc" +/datum/job_department/silicon/generate_nation_name() + return "United Nations" //For nations ruleset specifically, because all other sources of nation creation cannot choose silicons /// Catch-all department for undefined jobs. /datum/job_department/undefined diff --git a/tgstation.dme b/tgstation.dme index 372eca4e65d..ac1070cefdd 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -2015,6 +2015,8 @@ #include "code\modules\antagonists\revolution\enemy_of_the_state.dm" #include "code\modules\antagonists\revolution\revolution.dm" #include "code\modules\antagonists\santa\santa.dm" +#include "code\modules\antagonists\separatist\nation_creation.dm" +#include "code\modules\antagonists\separatist\objectives.dm" #include "code\modules\antagonists\separatist\separatist.dm" #include "code\modules\antagonists\slaughter\imp_antag.dm" #include "code\modules\antagonists\slaughter\slaughter.dm"