Skip to content

Commit

Permalink
Adds Syndicate organizations (#24040)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>

* Implement steal items

* Apply suggestions from code review

Co-authored-by: DGamerL <[email protected]>
Co-authored-by: Luc <[email protected]>

* 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 <[email protected]>
Signed-off-by: datlo <[email protected]>

* add hunter notification, review stuff

* Update code/game/gamemodes/objective.dm

Co-authored-by: Ryan <[email protected]>
Signed-off-by: datlo <[email protected]>

* fix lists

* Updated captain's sabre typepath

Co-authored-by: Burzah <[email protected]>
Signed-off-by: SteelSlayer <[email protected]>

---------

Signed-off-by: datlo <[email protected]>
Signed-off-by: SteelSlayer <[email protected]>
Co-authored-by: DGamerL <[email protected]>
Co-authored-by: Luc <[email protected]>
Co-authored-by: Burzah <[email protected]>
Co-authored-by: Ryan <[email protected]>
Co-authored-by: SteelSlayer <[email protected]>
  • Loading branch information
6 people authored Sep 12, 2024
1 parent 2b90084 commit 20f47a7
Show file tree
Hide file tree
Showing 10 changed files with 293 additions and 29 deletions.
31 changes: 31 additions & 0 deletions code/__DEFINES/antag_defines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
5 changes: 4 additions & 1 deletion code/datums/mind.dm
Original file line number Diff line number Diff line change
Expand Up @@ -595,8 +595,11 @@
if(sections[i])
out.Add(sections[i])

out.Add("<b>Organization:</b> ")
for(var/datum/antagonist/D in antag_datums)
if(D.organization)
out.Add("[D.organization.name]")
out.Add(memory_edit_uplink())

out.Add("<b>Memory:</b>")
out.Add(memory)
out.Add("<a href='byond://?src=[UID()];memory_edit=1'>Edit memory</a><br>")
Expand Down
56 changes: 51 additions & 5 deletions code/game/gamemodes/objective.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand All @@ -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

Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -211,7 +254,6 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective)
return
return ..()


/datum/objective/mutiny
name = "Mutiny"
martyr_compatible = TRUE
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
5 changes: 3 additions & 2 deletions code/game/gamemodes/objective_holder.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
23 changes: 23 additions & 0 deletions code/game/gamemodes/objectives_subtypes.dm
Original file line number Diff line number Diff line change
@@ -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")
22 changes: 22 additions & 0 deletions code/modules/antagonists/_common/antag_datum.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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`.
*
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -352,6 +372,8 @@ GLOBAL_LIST_EMPTY(antagonists)
. = messages
if(owner && owner.current)
messages.Add("<span class='userdanger'>You are a [special_role]!</span>")
if(organization && organization.intro_desc)
messages.Add("<span class='boldnotice'>[organization.intro_desc]</span>")

/**
* 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!"
Expand Down
20 changes: 20 additions & 0 deletions code/modules/antagonists/antag_org/antag_org_datum.dm
Original file line number Diff line number Diff line change
@@ -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
89 changes: 89 additions & 0 deletions code/modules/antagonists/antag_org/antag_org_syndicate.dm
Original file line number Diff line number Diff line change
@@ -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
Loading

0 comments on commit 20f47a7

Please sign in to comment.