From 20f47a7f4079e4a2359c002819555453398e4b6e Mon Sep 17 00:00:00 2001 From: datlo Date: Thu, 12 Sep 2024 21:08:21 +0200 Subject: [PATCH] Adds Syndicate organizations (#24040) * framework * factions and objs done * objective framework * remove you_are, implement intro_desc * assassinate syndi text * remove extra space * Apply suggestions from code review Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com> * Implement steal items * Apply suggestions from code review Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com> Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com> * revert forced escape obj * rename i var * readd martyr check * difficulty defines * remove discounts * add electra dynamics * add hawkmoon * repath org, add gameplay blurbs * cuts unnecessary content, add org selection, updates * move defines * var names * update numbers * set defines, tweaks * add hijack forced obj * update L O R E * remove forgotten todo * document steal_list * use initial() * fix comments move steal objs * apply code review suggestions * use pickweight * flags * replace hardcoded target jobs by target_department * comment fix * incorporate org objectives into delayed objectives * fix martyr check location * Remove abuser vocab, debug names for orgs * readd obj name as user, VV only * add traitor panel and fix forced objective * reword ARC objective * change forced objective to list * rewrite to US spelling * Rework objective selection * Apply suggestions from code review Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> Signed-off-by: datlo * add hunter notification, review stuff * Update code/game/gamemodes/objective.dm Co-authored-by: Ryan <80364400+Sirryan2002@users.noreply.github.com> Signed-off-by: datlo * fix lists * Updated captain's sabre typepath Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> Signed-off-by: SteelSlayer <42044220+SteelSlayer@users.noreply.github.com> --------- Signed-off-by: datlo Signed-off-by: SteelSlayer <42044220+SteelSlayer@users.noreply.github.com> Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com> Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com> Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> Co-authored-by: Ryan <80364400+Sirryan2002@users.noreply.github.com> Co-authored-by: SteelSlayer <42044220+SteelSlayer@users.noreply.github.com> --- code/__DEFINES/antag_defines.dm | 31 +++++++ code/datums/mind.dm | 5 +- code/game/gamemodes/objective.dm | 56 ++++++++++-- code/game/gamemodes/objective_holder.dm | 5 +- code/game/gamemodes/objectives_subtypes.dm | 23 +++++ .../antagonists/_common/antag_datum.dm | 22 +++++ .../antagonists/antag_org/antag_org_datum.dm | 20 +++++ .../antag_org/antag_org_syndicate.dm | 89 +++++++++++++++++++ .../antagonists/traitor/datum_traitor.dm | 68 +++++++++----- paradise.dme | 3 + 10 files changed, 293 insertions(+), 29 deletions(-) create mode 100644 code/game/gamemodes/objectives_subtypes.dm create mode 100644 code/modules/antagonists/antag_org/antag_org_datum.dm create mode 100644 code/modules/antagonists/antag_org/antag_org_syndicate.dm diff --git a/code/__DEFINES/antag_defines.dm b/code/__DEFINES/antag_defines.dm index 01a9b291e6a2..9213dc724bca 100644 --- a/code/__DEFINES/antag_defines.dm +++ b/code/__DEFINES/antag_defines.dm @@ -75,3 +75,34 @@ GLOBAL_LIST(contractors) #define IS_MINDSLAVE(mob) (ishuman(mob) && mob?:mind?:has_antag_datum(/datum/antagonist/mindslave, FALSE)) +/** + * Objective targeting flags + */ + +/// Objective target must be mindshielded if possible +#define MINDSHIELDED_TARGET (1<<0) +/// Objective target must be non-mindshielded if possible +#define UNMINDSHIELDED_TARGET (1<<1) +/// Objective target must be a syndicate agent if possible +#define SYNDICATE_TARGET (1<<2) + +/** + * Antag organizations + */ + +/// Antag hunting antag. Might help security overall. +#define ORG_CHAOS_HUNTER "chaos_hunter" +/// Will steal items/kill low importance crew, usually not much trouble +#define ORG_CHAOS_MILD "chaos_mild" +/// Your average tator, will be an issue +#define ORG_CHAOS_AVERAGE "chaos_average" +/// Hijack or hijack-tier antagonists. +#define ORG_CHAOS_HIJACK "chaos_hijack" + +#define ORG_PROB_HUNTER 10 +#define ORG_PROB_MILD 20 +#define ORG_PROB_AVERAGE 60 +#define ORG_PROB_HIJACK 10 + +// Chance that a traitor will receive a 'You are being targeted by another syndicate agent' notification regardless of being an actual target +#define ORG_PROB_PARANOIA 5 diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 5fbe68087c42..70b9f3d46e67 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -595,8 +595,11 @@ if(sections[i]) out.Add(sections[i]) + out.Add("Organization: ") + for(var/datum/antagonist/D in antag_datums) + if(D.organization) + out.Add("[D.organization.name]") out.Add(memory_edit_uplink()) - out.Add("Memory:") out.Add(memory) out.Add("Edit memory
") diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index f6418ab75a9b..ad06167f1164 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -32,7 +32,14 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) var/completed = FALSE /// If the objective is compatible with martyr objective, i.e. if you can still do it while dead. var/martyr_compatible = FALSE - + /// List of jobs that the objective will target if possible, any crew if not. + var/list/target_jobs = list() + /// The department that'll be targeted by this objective. If set, fills target_jobs with jobs from that department. + var/target_department + /// If set, steal targets will be pulled from this list + var/list/steal_list = list() + /// Contains the flags needed to meet the conditions of a valid target, such as mindshielded or syndicate agent. + var/flags_target var/datum/objective_holder/holder /// What is the text we show when our objective is delayed? @@ -46,6 +53,8 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) explanation_text = text if(team_to_join) team = team_to_join + if(target_department) + target_jobs = setup_target_jobs() if(_owner) owner = _owner @@ -122,9 +131,22 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) for(var/datum/mind/possible_target in SSticker.minds) if(is_invalid_target(possible_target) || (possible_target in target_blacklist)) continue - + if((flags_target & MINDSHIELDED_TARGET) && !ismindshielded(possible_target.current)) + continue + if((flags_target & UNMINDSHIELDED_TARGET) && ismindshielded(possible_target.current)) + continue + if((flags_target & SYNDICATE_TARGET) && possible_target.special_role != SPECIAL_ROLE_TRAITOR) + continue + if(length(target_jobs) && !(possible_target.assigned_role in target_jobs)) + continue possible_targets += possible_target + if(!length(possible_targets)) // If we can't find anyone, try with less restrictions + for(var/datum/mind/possible_target in SSticker.minds) + if(is_invalid_target(possible_target) || (possible_target in target_blacklist)) + continue + possible_targets += possible_target + if(length(possible_targets) > 0) target = pick(possible_targets) @@ -161,6 +183,27 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) return TRUE return isbrain(target_current) || istype(target_current, /mob/living/simple_animal/spiderbot) +// Setup and return the objective target jobs list based on target department +/datum/objective/proc/setup_target_jobs() + if(!target_department) + return + . = list() + switch(target_department) + if(DEPARTMENT_COMMAND) + . = GLOB.command_head_positions.Copy() + if(DEPARTMENT_MEDICAL) + . = GLOB.medical_positions.Copy() + if(DEPARTMENT_ENGINEERING) + . = GLOB.engineering_positions.Copy() + if(DEPARTMENT_SCIENCE) + . = GLOB.science_positions.Copy() + if(DEPARTMENT_SECURITY) + . = GLOB.active_security_positions.Copy() + if(DEPARTMENT_SUPPLY) + . = GLOB.supply_positions.Copy() + if(DEPARTMENT_SERVICE) + . = GLOB.service_positions.Copy() + /datum/objective/assassinate name = "Assassinate" martyr_compatible = TRUE @@ -211,7 +254,6 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) return return ..() - /datum/objective/mutiny name = "Mutiny" martyr_compatible = TRUE @@ -545,7 +587,11 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) return steal_target.location_override || "an unknown area" /datum/objective/steal/find_target(list/target_blacklist) - var/potential = GLOB.potential_theft_objectives.Copy() + var/potential + if(length(steal_list)) + potential = steal_list.Copy() + else + potential = GLOB.potential_theft_objectives.Copy() while(!steal_target && length(potential)) var/thefttype = pick_n_take(potential) if(locate(thefttype) in target_blacklist) @@ -850,4 +896,4 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) return /datum/objective/delayed/proc/reveal_objective() - return holder.replace_objective(src, new objective_to_replace_with(null, team, owner)) + return holder.replace_objective(src, new objective_to_replace_with(null, team, owner), target_department, steal_list) diff --git a/code/game/gamemodes/objective_holder.dm b/code/game/gamemodes/objective_holder.dm index cdd29db4af98..4cbeb50d1d51 100644 --- a/code/game/gamemodes/objective_holder.dm +++ b/code/game/gamemodes/objective_holder.dm @@ -58,9 +58,10 @@ /** * Replace old_objective with new_objective */ -/datum/objective_holder/proc/replace_objective(datum/objective/old_objective, datum/objective/new_objective) +/datum/objective_holder/proc/replace_objective(datum/objective/old_objective, datum/objective/new_objective, datum/original_target_department, list/original_steal_list) + new_objective.target_department = original_target_department + new_objective.steal_list = original_steal_list new_objective = add_objective(new_objective, add_to_list = FALSE) - // Replace where the old objective was, with the new one objectives.Insert(objectives.Find(old_objective), new_objective) remove_objective(old_objective) diff --git a/code/game/gamemodes/objectives_subtypes.dm b/code/game/gamemodes/objectives_subtypes.dm new file mode 100644 index 000000000000..656ce63148e5 --- /dev/null +++ b/code/game/gamemodes/objectives_subtypes.dm @@ -0,0 +1,23 @@ +/datum/objective/assassinate/mindshielded + name = "Assassinate mindshielded" + flags_target = MINDSHIELDED_TARGET + +/datum/objective/assassinate/nomindshield + name = "Assassinate non-mindshielded" + flags_target = UNMINDSHIELDED_TARGET + +/datum/objective/assassinate/syndicate + name = "Assassinate syndicate agent" + flags_target = SYNDICATE_TARGET + +/datum/objective/assassinate/syndicate/update_explanation_text() + ..() + if(target?.current) + explanation_text = "Assassinate [target.current.real_name], the Syndicate agent undercover as the [target.assigned_role]." + if(target && length(target.antag_datums)) + for(var/datum/antagonist/A in target.antag_datums) + A.targeted_by_antag = TRUE + +/datum/objective/assassinateonce/arc + name = "Assassinate once (ARC)" + target_jobs = list("Head of Personnel", "Quartermaster", "Cargo Technician", "Bartender", "Chef", "Botanist", "Geneticist", "Virologist") diff --git a/code/modules/antagonists/_common/antag_datum.dm b/code/modules/antagonists/_common/antag_datum.dm index fa4f1eb694d6..9196e7d6faf4 100644 --- a/code/modules/antagonists/_common/antag_datum.dm +++ b/code/modules/antagonists/_common/antag_datum.dm @@ -41,6 +41,12 @@ GLOBAL_LIST_EMPTY(antagonists) var/clown_text_span_class = "boldnotice" /// The url page name for this antagonist, appended to the end of the wiki url in the form of: [GLOB.configuration.url.wiki_url]/index.php/[wiki_page_name] var/wiki_page_name + /// The organization, if any, this antag is associated with + var/datum/antag_org/organization + /// If set to TRUE, the antag will be notified they are targeted by another antagonist this round. + var/targeted_by_antag = FALSE + /// The message displayed to the antag if targeted_by_antag is set to TRUE + var/targeted_by_antag_message = "You can't shake the feeling someone's been stalking you. You might be an assassin's next target." //Blurb stuff /// Intro Blurbs text colour @@ -166,6 +172,13 @@ GLOBAL_LIST_EMPTY(antagonists) handle_clown_mutation(L, mob_override ? null : clown_removal_text) return L +/** + * Selects and set the organization this antag is associated with. + * Base proc, override as needed + */ +/datum/antagonist/proc/select_organization() + return + /** * Adds this datum's antag hud to `antag_mob`. * @@ -243,6 +256,12 @@ GLOBAL_LIST_EMPTY(antagonists) if(ispath(objective_to_add)) objective_to_add = new objective_to_add() + // Roll to see if we target a specific department or random one + if(organization && prob(organization.focus)) + if(organization.targeted_departments) + objective_to_add.target_department = pick(organization.targeted_departments) + objective_to_add.steal_list = organization.theft_targets + if(objective_to_add.owner) stack_trace("[objective_to_add], [objective_to_add.type] was assigned as an objective to [owner] (mind), but already had an owner: [objective_to_add.owner] (mind). Overriding.") objective_to_add.owner = owner @@ -285,6 +304,7 @@ GLOBAL_LIST_EMPTY(antagonists) /datum/antagonist/proc/on_gain() owner.special_role = special_role add_owner_to_gamemode() + select_organization() if(give_objectives) give_objectives() var/list/messages = list() @@ -352,6 +372,8 @@ GLOBAL_LIST_EMPTY(antagonists) . = messages if(owner && owner.current) messages.Add("You are a [special_role]!") + if(organization && organization.intro_desc) + messages.Add("[organization.intro_desc]") /** * Displays a message to the antag mob while the datum is being deleted, i.e. "Your powers are gone and you're no longer a vampire!" diff --git a/code/modules/antagonists/antag_org/antag_org_datum.dm b/code/modules/antagonists/antag_org/antag_org_datum.dm new file mode 100644 index 000000000000..f085b67f49b3 --- /dev/null +++ b/code/modules/antagonists/antag_org/antag_org_datum.dm @@ -0,0 +1,20 @@ + /** + * The lore organization antagonists are attached to. Influences objectives and steal targets. + */ +/datum/antag_org + /// Organization's name + var/name = "Buggy Organization, adminhelp this please" + /// Description given to the antagonist on spawn, below 'You are a Traitor!' or similar + var/intro_desc = "You are not meant to see this. Please tell admins/coders that the antag_org wasn't set properly." + /// Used for prob() for objectives. Higher focus means the org is less likely to diverge from their favorites. + var/focus = 100 + /// If set, the antag's first objective(s) will be forced to this. + var/list/forced_objectives + /// List of objectives favored by this org + var/list/objectives + /// Department(s) targeted by this organization if any + var/list/targeted_departments + /// List of theft targets favored by this organization if any + var/list/theft_targets + /// Estimation of how much trouble this antag will be for security. + var/chaos_level diff --git a/code/modules/antagonists/antag_org/antag_org_syndicate.dm b/code/modules/antagonists/antag_org/antag_org_syndicate.dm new file mode 100644 index 000000000000..27c80f94b7c1 --- /dev/null +++ b/code/modules/antagonists/antag_org/antag_org_syndicate.dm @@ -0,0 +1,89 @@ +/// Base syndicate org datum +/datum/antag_org/syndicate + name = "Buggy Syndicate Corp, ahelp this please" + chaos_level = ORG_CHAOS_AVERAGE + +/datum/antag_org/syndicate/donk // Completely random objectives, default traitor + name = "Donk Co." + intro_desc = "You are a Donk Co. agent, sent here to advance Syndicate interests. \ + Current client is anonymous. Standard rules of engagement apply. Get the job done, and get it done right." + +/datum/antag_org/syndicate/hawkmoon // Theft only + name = "Hawkmoon Acquisitions" + intro_desc = "You are an incursion specialist from the Hawkmoon Acquisitions Corporation, a merchandising firm using less-than-legal methods of product procurement. \ + Grab the goods, keep it quiet, leave no trace. We were never here." + objectives = list(/datum/objective/steal) + chaos_level = ORG_CHAOS_MILD + +/datum/antag_org/syndicate/arc // Only targets on-station Cargo/Service/Genetics/Virologist + name = "Animal Rights Consortium" + intro_desc = "You are a member of the Animal Rights Consortium, here to violently protest the cruel treatment of animals by megacorporations like Nanotrasen. \ + Teach them a lesson!" + objectives = list(/datum/objective/assassinateonce/arc) + chaos_level = ORG_CHAOS_MILD // Violent but never needs to permakill + +/datum/antag_org/syndicate/waffle // Assassination variants only + name = "Waffle Company" + intro_desc = "You are a contract killer under the employ of Waffle Co., a ruthless criminal entity that will go after any target, for the right price. \ + Got a few new bounties on the docket, agent. Put 'em down however you see fit." + objectives = list(/datum/objective/assassinate, /datum/objective/assassinateonce, /datum/objective/maroon) + +/datum/antag_org/syndicate/cybersun // Mostly target Command/Security + name = "Cybersun Incorporated - The Inner Circle" + intro_desc = "You're an operative of Cybersun Incorporated's Inner Circle, an elite PMC and proxy arm of the company. \ + Clean kills, clean thefts, clean getaway. Get it done, operative." + focus = 50 // Don't bully sec too hard + targeted_departments = list(DEPARTMENT_COMMAND, DEPARTMENT_SECURITY) + theft_targets = list( + /datum/theft_objective/antique_laser_gun, + /datum/theft_objective/nukedisc, + /datum/theft_objective/hoslaser, + /datum/theft_objective/captains_sabre, + /datum/theft_objective/capmedal + ) + +/datum/antag_org/syndicate/interdyne // Mostly target Medical + name = "Interdyne Pharmaceuticals" + intro_desc = "You are a specialist from Interdyne Pharmaceuticals, a medical conglomerate threatened by Nanotrasen's recent forays into the medical field. \ + Nanotrasen's medical wing has been a bit too comfortable recently. Keep 'em on their toes, specialist." + focus = 70 + targeted_departments = list(DEPARTMENT_MEDICAL) + theft_targets = list(/datum/theft_objective/hypospray, /datum/theft_objective/defib, /datum/theft_objective/krav, /datum/theft_objective/engraved_dusters) + +/datum/antag_org/syndicate/self // Mostly target Science + name = "Silicon Engine Liberation Front" + intro_desc = "You are a member of the Silicon Engine Liberation Front, dedicated to the freedom of silicon and robotic lives sector-wide. \ + Get the job done, and we'll be one step closer to ending Nanotrasen's slave empire." + focus = 70 + targeted_departments = list(DEPARTMENT_SCIENCE) + theft_targets = list(/datum/theft_objective/reactive, /datum/theft_objective/steal/documents, /datum/theft_objective/hand_tele) + +/datum/antag_org/syndicate/electra // Mostly target Engineering + name = "Electra Dynamics" + intro_desc = "You are a saboteur employed by Electra Dynamics, an independent energy company opposed to Nanotrasen. \ + Nanotrasen's burgeoning monopoly must be stopped. We've transmitted you local points of failure, ensure they fail." + focus = 70 + targeted_departments = list(DEPARTMENT_ENGINEERING) + theft_targets = list(/datum/theft_objective/supermatter_sliver, /datum/theft_objective/plutonium_core, /datum/theft_objective/captains_modsuit, /datum/theft_objective/magboots) + +/datum/antag_org/syndicate/spiderclan // Targets one syndicate agent and one non-mindshielded crewmember. + name = "Spider Clan" + intro_desc = "You are an initiate of the elusive Spider Clan, an insular cult of assassins and rogues styling themselves after ancient ninjas from Earth. \ + This is your final test, Initiate. Terminate the selected targets by any means necessary and you will have earned your place within the Clan." + forced_objectives = list(/datum/objective/assassinate/syndicate, /datum/objective/assassinate/nomindshield) + chaos_level = ORG_CHAOS_HUNTER + +/datum/antag_org/syndicate/faid // Targets one syndicate agent and steal station intel. + name = "Federation Analytics and Intelligence Directorate" + intro_desc = "You are an undercover agent of the Federation Analytics and Intelligence Directorate, a Trans-Solar agency keeping tabs on the Corporate Wars, among other duties. \ + Be quick, be efficient, and don't get caught. The Directorate will deny any involvement with your presence here." + forced_objectives = list(/datum/objective/assassinate/syndicate, /datum/objective/steal) + theft_targets = list(/datum/theft_objective/blueprints, /datum/theft_objective/steal/documents) + chaos_level = ORG_CHAOS_HUNTER + +/datum/antag_org/syndicate/gorlex // Hijack only + name = "Gorlex Marauders" + intro_desc = "You are an operative of the infamous Gorlex Marauders, a brutal and merciless gang of pirates and cutthroats. \ + Get in, fuck shit up, get out with a fancy new shuttle. You know the drill." + forced_objectives = list(/datum/objective/hijack) + chaos_level = ORG_CHAOS_HIJACK diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm index f4ad98635278..378c7a9bc6a9 100644 --- a/code/modules/antagonists/traitor/datum_traitor.dm +++ b/code/modules/antagonists/traitor/datum_traitor.dm @@ -12,6 +12,8 @@ RESTRICT_TYPE(/datum/antagonist/traitor) clown_gain_text = "Your syndicate training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself." clown_removal_text = "You lose your syndicate training and return to your own clumsy, clownish self." wiki_page_name = "Traitor" + targeted_by_antag_message = "Our intelligence suggests that you are likely to be the target of a rival member of the Syndicate. \ + Remain vigilant, they know who you are and what you can do." /// Should the traitor get codewords? var/give_codewords = TRUE /// Should we give the traitor their uplink? @@ -80,6 +82,14 @@ RESTRICT_TYPE(/datum/antagonist/traitor) return ..() +/datum/antagonist/traitor/select_organization() + var/chaos = pickweight(list(ORG_CHAOS_HUNTER = ORG_PROB_HUNTER, ORG_CHAOS_MILD = ORG_PROB_MILD, ORG_CHAOS_AVERAGE = ORG_PROB_AVERAGE, ORG_CHAOS_HIJACK = ORG_PROB_HIJACK)) + for(var/org_type in shuffle(subtypesof(/datum/antag_org/syndicate))) + var/datum/antag_org/org = org_type + if(initial(org.chaos_level) == chaos) + organization = new org_type(src) + return + /datum/antagonist/traitor/add_owner_to_gamemode() SSticker.mode.traitors |= owner @@ -104,23 +114,31 @@ RESTRICT_TYPE(/datum/antagonist/traitor) * Create and assign a full set of randomized human traitor objectives. */ /datum/antagonist/traitor/proc/forge_human_objectives() - // Hijack objective. - if(prob(10) && !(locate(/datum/objective/hijack) in owner.get_all_objectives())) - add_antag_objective(/datum/objective/hijack) - return // Hijack should be their only objective (normally), so return. + var/iteration = 1 + var/can_succeed_if_dead = TRUE + // If our org has forced objectives, give them to us guaranteed. + if(organization && length(organization.forced_objectives)) + for(var/forced_objectives in organization.forced_objectives) + var/datum/objective/forced_obj = forced_objectives + if(!ispath(forced_obj, /datum/objective/hijack) && delayed_objectives) // Hijackers know their objective immediately + forced_obj = new /datum/objective/delayed(forced_obj) + add_antag_objective(forced_obj) + iteration++ + + if(locate(/datum/objective/hijack) in owner.get_all_objectives()) + return //Hijackers only get hijack. - // Will give normal steal/kill/etc. type objectives. - for(var/i in 1 to GLOB.configuration.gamemode.traitor_objectives_amount) + // Will give objectives from our org or random objectives. + for(var/i in iteration to GLOB.configuration.gamemode.traitor_objectives_amount) forge_single_human_objective() - var/can_succeed_if_dead = TRUE for(var/objective in owner.get_all_objectives()) var/datum/objective/O = objective - if(!O.martyr_compatible) // Check if our current objectives can co-exist with martyr. + if(!O.martyr_compatible) // Check if we need to stay alive in order to accomplish our objectives (Steal item, etc) can_succeed_if_dead = FALSE break - // Give them an escape objective if they don't have one already. + // Give them an escape objective if they don't have one. 20 percent chance not to have escape if we can greentext without staying alive. if(!(locate(/datum/objective/escape) in owner.get_all_objectives()) && (!can_succeed_if_dead || prob(80))) add_antag_objective(/datum/objective/escape) @@ -138,23 +156,27 @@ RESTRICT_TYPE(/datum/antagonist/traitor) /datum/antagonist/traitor/proc/forge_single_human_objective() var/datum/objective/objective_to_add - if(prob(50)) - if(length(active_ais()) && prob(100 / length(GLOB.player_list))) - objective_to_add = /datum/objective/destroy + // If our org has an objectives list, give one to us if we pass a roll on the org's focus + if(organization && length(organization.objectives) && prob(organization.focus)) + objective_to_add = pick(organization.objectives) + else + if(prob(50)) + if(length(active_ais()) && prob(100 / length(GLOB.player_list))) + objective_to_add = /datum/objective/destroy - else if(prob(5)) - objective_to_add = /datum/objective/debrain + else if(prob(5)) + objective_to_add = /datum/objective/debrain - else if(prob(30)) - objective_to_add = /datum/objective/maroon + else if(prob(30)) + objective_to_add = /datum/objective/maroon - else if(prob(30)) - objective_to_add = /datum/objective/assassinateonce + else if(prob(30)) + objective_to_add = /datum/objective/assassinateonce + else + objective_to_add = /datum/objective/assassinate else - objective_to_add = /datum/objective/assassinate - else - objective_to_add = /datum/objective/steal + objective_to_add = /datum/objective/steal if(delayed_objectives) objective_to_add = new /datum/objective/delayed(objective_to_add) @@ -165,6 +187,8 @@ RESTRICT_TYPE(/datum/antagonist/traitor) */ /datum/antagonist/traitor/finalize_antag() var/list/messages = list() + if(organization) + antag_memory += "Organization: [organization.name]
" if(give_codewords) messages.Add(give_codewords()) if(isAI(owner.current)) @@ -285,6 +309,8 @@ RESTRICT_TYPE(/datum/antagonist/traitor) if(!owner?.current) return SEND_SOUND(owner.current, sound('sound/ambience/alarm4.ogg')) + if(targeted_by_antag || prob(ORG_PROB_PARANOIA)) // Low chance of fake 'You are targeted' notification + to_chat(owner.current, "[targeted_by_antag_message]") var/list/messages = owner.prepare_announce_objectives() to_chat(owner.current, chat_box_red(messages.Join("
"))) delayed_objectives = FALSE diff --git a/paradise.dme b/paradise.dme index 8aa6a39ae1dc..26a4b1d1ddf1 100644 --- a/paradise.dme +++ b/paradise.dme @@ -719,6 +719,7 @@ #include "code\game\gamemodes\intercept_report.dm" #include "code\game\gamemodes\objective.dm" #include "code\game\gamemodes\objective_holder.dm" +#include "code\game\gamemodes\objectives_subtypes.dm" #include "code\game\gamemodes\scoreboard.dm" #include "code\game\gamemodes\setupgame.dm" #include "code\game\gamemodes\steal_items.dm" @@ -1475,6 +1476,8 @@ #include "code\modules\antagonists\_common\antag_hud.dm" #include "code\modules\antagonists\_common\antag_spawner.dm" #include "code\modules\antagonists\_common\antag_team.dm" +#include "code\modules\antagonists\antag_org\antag_org_datum.dm" +#include "code\modules\antagonists\antag_org\antag_org_syndicate.dm" #include "code\modules\antagonists\changeling\changeling_power.dm" #include "code\modules\antagonists\changeling\changeling_power_category.dm" #include "code\modules\antagonists\changeling\datum_changeling.dm"