Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Traitor Backstories #9126

Merged
merged 29 commits into from
Feb 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
b8280f1
Basic backstories
itsmeow May 30, 2023
4b9d5d3
Snapshot
itsmeow May 31, 2023
20f9683
Progress
itsmeow May 31, 2023
fc1b8ce
The UI and faction update
itsmeow May 31, 2023
148833d
More progress
itsmeow Jun 1, 2023
64276ea
UI code cleanup
itsmeow Jun 2, 2023
a8aea9d
Fix NotFoundError (What the fuck)
itsmeow Jun 2, 2023
bc7f404
Code reorganization + gimmick config
itsmeow Jun 2, 2023
08e3249
Fix list scrollability flow
itsmeow Jun 2, 2023
5e91e6d
Cleanup
itsmeow Jun 2, 2023
2336d9c
Actually integrate it with the game
itsmeow Jun 3, 2023
ace25da
Roundend report stuff
itsmeow Jun 3, 2023
feffbef
Backstory view phase - now testmergeable
itsmeow Jun 3, 2023
85e1183
Improve roundend report and recommendations
itsmeow Jun 3, 2023
30e8bf7
Fix forced factions after selection
itsmeow Jun 4, 2023
b9a7879
Start rewriting obj briefings
itsmeow Jun 5, 2023
cd62324
FInish
itsmeow Jun 23, 2023
a2a0478
Merge remote-tracking branch 'origin/master' into objectives-backstory
itsmeow Jan 5, 2024
faf1917
Cleanup and integrate with antag tips
itsmeow Jan 5, 2024
92a8e4c
Remove objective backstories for now and call it a day.
itsmeow Jan 5, 2024
51df9ee
More cleanup
itsmeow Jan 5, 2024
f10ff3e
More direct murderbone logic
itsmeow Jan 5, 2024
e2e288b
Add logging and Traitor Panel for backstory
itsmeow Jan 6, 2024
08f35c4
Remove KILL text from Sadist
itsmeow Jan 6, 2024
b55ee05
Reorganize, make it required, remove the auto-timeout.
itsmeow Jan 6, 2024
fd307d1
Fixes soft-tracked objectives being non martyr-compatible, does the m…
itsmeow Jan 6, 2024
8bdcaae
Add SSblackbox for selections
itsmeow Jan 7, 2024
05e8bf5
Highlight no codewords
itsmeow Jan 7, 2024
4886814
Fix codewords always being given
itsmeow Jan 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 8 additions & 0 deletions beestation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@
#include "code\__DEFINES\timed_action.dm"
#include "code\__DEFINES\tools.dm"
#include "code\__DEFINES\toys.dm"
#include "code\__DEFINES\traitor.dm"
#include "code\__DEFINES\traits.dm"
#include "code\__DEFINES\turfs.dm"
#include "code\__DEFINES\typeids.dm"
Expand Down Expand Up @@ -314,6 +315,7 @@
#include "code\_globalvars\lists\names.dm"
#include "code\_globalvars\lists\objects.dm"
#include "code\_globalvars\lists\poll_ignore.dm"
#include "code\_globalvars\lists\traitor.dm"
#include "code\_globalvars\lists\typecache.dm"
#include "code\_globalvars\lists\wiremod.dm"
#include "code\_js\byjax.dm"
Expand Down Expand Up @@ -2099,7 +2101,13 @@
#include "code\modules\antagonists\swarmer\swarmer_event.dm"
#include "code\modules\antagonists\traitor\datum_traitor.dm"
#include "code\modules\antagonists\traitor\syndicate_contract.dm"
#include "code\modules\antagonists\traitor\traitor_ai.dm"
#include "code\modules\antagonists\traitor\traitor_objectives.dm"
#include "code\modules\antagonists\traitor\traitor_spawner.dm"
#include "code\modules\antagonists\traitor\backstory\traitor_backstories.dm"
#include "code\modules\antagonists\traitor\backstory\traitor_backstory_ui.dm"
#include "code\modules\antagonists\traitor\backstory\traitor_datum_backstory.dm"
#include "code\modules\antagonists\traitor\backstory\traitor_factions.dm"
#include "code\modules\antagonists\traitor\equipment\contractor.dm"
#include "code\modules\antagonists\traitor\equipment\Malf_Modules.dm"
#include "code\modules\antagonists\traitor\IAA\internal_affairs.dm"
Expand Down
5 changes: 4 additions & 1 deletion code/__DEFINES/devices.dm
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@

#define THEME_SYNDICATE "syndicate"

#define THEME_NEUTRAL "neutral"

/// Map of theme name -> theme ID
GLOBAL_LIST_INIT(ntos_device_themes_default, list(
"NtOS Default" = THEME_NTOS,
Expand All @@ -69,7 +71,8 @@ GLOBAL_LIST_INIT(ntos_device_themes_default, list(
))

GLOBAL_LIST_INIT(ntos_device_themes_emagged, list(
"Syndix" = THEME_SYNDICATE
"Syndix" = THEME_SYNDICATE,
"Neutral" = THEME_NEUTRAL,
) + GLOB.ntos_device_themes_default)

/// Reverse map of GLOB.ntos_device_themes_emagged
Expand Down
22 changes: 22 additions & 0 deletions code/__DEFINES/traitor.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#define TRAITOR_FACTION_BLACK_MARKET "black_market"
#define TRAITOR_FACTION_SYNDICATE "syndicate"
#define TRAITOR_FACTION_INDEPENDENT "independent"

/// If this backstory involves being forced into the job
#define TRAITOR_MOTIVATION_FORCED "Forced Into It"
/// If this backstory does not involve being forced into the job
#define TRAITOR_MOTIVATION_NOT_FORCED "Not Forced Into It"
/// If this backstory is motivated by money or personal gain
#define TRAITOR_MOTIVATION_MONEY "Money"
/// If this backstory is politically motivated, wanting to "change the world".
#define TRAITOR_MOTIVATION_POLITICAL "Political"
/// If this backstory is motivated through the power of love (your family, friends, etc)
#define TRAITOR_MOTIVATION_LOVE "Love"
/// If this backstory is motivated by your reputation, or by knowledge (blackmail)
#define TRAITOR_MOTIVATION_REPUTATION "Reputation"
/// If this backstory is motivated by the threat of death or personal harm
#define TRAITOR_MOTIVATION_DEATH_THREAT "Death Threat"
/// If this backstory is motivated by their faction or presence in an organization
#define TRAITOR_MOTIVATION_AUTHORITY "Authority"
/// If this backstory is motivated by themselves or the activity
#define TRAITOR_MOTIVATION_FUN "Fun"
34 changes: 34 additions & 0 deletions code/_globalvars/lists/traitor.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/// Associative list of /datum/traitor_backstory path strings to datums
GLOBAL_LIST_INIT(traitor_backstories, generate_traitor_backstories())
/// Associative list of /datum/traitor_faction keys to datums
GLOBAL_LIST_INIT(traitor_factions_to_datum, generate_traitor_factions())
GLOBAL_LIST_INIT(traitor_factions, assoc_to_keys(GLOB.traitor_factions_to_datum))

/proc/generate_traitor_backstories()
var/list/result = list()
for(var/datum/traitor_backstory/path as anything in subtypesof(/datum/traitor_backstory))
if(isnull(initial(path.name)))
continue
result["[path]"] = new path()
return result

/proc/generate_traitor_factions()
var/list/result = list()
for(var/datum/traitor_faction/path as anything in subtypesof(/datum/traitor_faction))
var/key = initial(path.key)
if(!istext(key))
continue
result[key] = new path()
return result

GLOBAL_LIST_INIT(traitor_motivations, list(
TRAITOR_MOTIVATION_FORCED,
TRAITOR_MOTIVATION_NOT_FORCED,
TRAITOR_MOTIVATION_MONEY,
TRAITOR_MOTIVATION_POLITICAL,
TRAITOR_MOTIVATION_LOVE,
TRAITOR_MOTIVATION_REPUTATION,
TRAITOR_MOTIVATION_DEATH_THREAT,
TRAITOR_MOTIVATION_AUTHORITY,
TRAITOR_MOTIVATION_FUN,
))
12 changes: 6 additions & 6 deletions code/datums/mind.dm
Original file line number Diff line number Diff line change
Expand Up @@ -363,11 +363,11 @@
U.setup_unlock_code()
if(!silent)
if(uplink_loc == R)
U.unlock_text = "[employer] has cunningly disguised a Syndicate Uplink as your [R.name]. Simply speak [U.unlock_code] into the :d channel to unlock its hidden features."
U.unlock_text = "[employer] [employer == "You" ? "have" : "has"] cunningly disguised a Syndicate Uplink as your [R.name]. Simply speak [U.unlock_code] into the :d channel to unlock its hidden features."
else if(uplink_loc == PDA)
U.unlock_text = "[employer] has cunningly disguised a Syndicate Uplink as your [PDA.name]. Simply enter the code \"[U.unlock_code]\" into the ring tone selection to unlock its hidden features."
U.unlock_text = "[employer] [employer == "You" ? "have" : "has"] cunningly disguised a Syndicate Uplink as your [PDA.name]. Simply enter the code \"[U.unlock_code]\" into the ring tone selection to unlock its hidden features."
else if(uplink_loc == P)
U.unlock_text = "[employer] has cunningly disguised a Syndicate Uplink as your [P.name]. Simply twist the top of the pen [english_list(U.unlock_code)] from its starting position to unlock its hidden features."
U.unlock_text = "[employer] [employer == "You" ? "have" : "has"] cunningly disguised a Syndicate Uplink as your [P.name]. Simply twist the top of the pen [english_list(U.unlock_code)] from its starting position to unlock its hidden features."
to_chat(traitor_mob, "<span class='boldnotice'>[U.unlock_text]</span>")

if(uplink_owner)
Expand All @@ -379,7 +379,7 @@
I.implant(traitor_mob, null, silent = TRUE)
var/datum/component/uplink/U = I.GetComponent(/datum/component/uplink)
if(!silent)
U.unlock_text = "[employer] has cunningly implanted you with a Syndicate Uplink (although uplink implants cost valuable TC, so you will have slightly less). Simply trigger the uplink to access it."
U.unlock_text = "[employer] [employer == "You" ? "have" : "has"] cunningly implanted [employer == "You" ? "yourself" : "you"] with a Syndicate Uplink (although uplink implants cost valuable TC, so you will have slightly less). Simply trigger the uplink to access it."
to_chat(traitor_mob, "<span class='boldnotice'>[U.unlock_text]</span>")
return I

Expand Down Expand Up @@ -673,8 +673,8 @@
add_antag_datum(/datum/antagonist/traitor)

/datum/mind/proc/make_Contractor_Support()
if(!(has_antag_datum(/datum/antagonist/traitor/contractor_support)))
add_antag_datum(/datum/antagonist/traitor/contractor_support)
if(!(has_antag_datum(/datum/antagonist/contractor_support)))
add_antag_datum(/datum/antagonist/contractor_support)

/datum/mind/proc/make_Changeling()
var/datum/antagonist/changeling/C = has_antag_datum(/datum/antagonist/changeling)
Expand Down
30 changes: 21 additions & 9 deletions code/game/gamemodes/objectives/_objective.dm
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
GLOBAL_LIST(admin_objective_list) //Prefilled admin assignable objective list

/datum/objective
var/datum/mind/owner //The primary owner of the objective. !!SOMEWHAT DEPRECATED!! Prefer using 'team' for new code.
var/datum/team/team //An alternative to 'owner': a team. Use this when writing new code.
var/name = "generic objective" //Name for admin prompts
var/explanation_text = "Nothing" //What that person is supposed to do.
var/team_explanation_text //For when there are multiple owners.
var/datum/mind/target = null //If they are focused on a particular person.
var/target_amount = 0 //If they are focused on a particular number. Steal objectives have their own counter.
var/completed = 0 //currently only used for custom objectives.
var/martyr_compatible = 0 //If the objective is compatible with martyr objective, i.e. if you can still do it while dead.
/// The primary owner of the objective. !!SOMEWHAT DEPRECATED!! Prefer using 'team' for new code.
var/datum/mind/owner
/// An alternative to 'owner': a team. Use this when writing new code.
var/datum/team/team
/// Name of the objective for admin prompts
var/name = "generic objective"
/// What that person is supposed to do.
var/explanation_text = "Nothing"
/// For when there are multiple owners.
var/team_explanation_text
/// If they are focused on a particular person.
var/datum/mind/target = null
/// If they are focused on a particular number. Steal objectives have their own counter.
var/target_amount = 0
/// If the objective is to be marked as completed, regardless of any conditions. Currently only used for custom objectives.
var/completed = FALSE
/// If the objective is compatible with martyr objective, i.e. if you can still do it while dead.
var/martyr_compatible = TRUE
/// Whether the objective should show up as optional in the roundend screen
var/optional = FALSE
/// Used to check if obj owner can buy murderbone stuff
var/murderbone_flag = FALSE

/datum/objective/New(var/text)
Expand Down
1 change: 0 additions & 1 deletion code/game/gamemodes/objectives/basic/assassinate.dm
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/datum/objective/assassinate
name = "assasinate"
var/target_role_type=FALSE
martyr_compatible = 1

/datum/objective/assassinate/find_target_by_role(role, role_type=FALSE,invert=FALSE)
if(!invert)
Expand Down
1 change: 1 addition & 0 deletions code/game/gamemodes/objectives/basic/debrain.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/datum/objective/debrain
name = "debrain"
martyr_compatible = FALSE
var/target_role_type=0

/datum/objective/debrain/find_target_by_role(role, role_type=FALSE,invert=FALSE)
Expand Down
1 change: 0 additions & 1 deletion code/game/gamemodes/objectives/basic/destroy_ai.dm
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

/datum/objective/destroy
name = "destroy AI"
martyr_compatible = 1

/datum/objective/destroy/find_target(list/dupe_search_range, list/blacklist)
var/list/possible_targets = list()
Expand Down
1 change: 1 addition & 0 deletions code/game/gamemodes/objectives/basic/download.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/datum/objective/download
name = "download"
martyr_compatible = FALSE
var/amount = 0

/datum/objective/download/proc/gen_amount_goal()
Expand Down
1 change: 0 additions & 1 deletion code/game/gamemodes/objectives/basic/maroon.dm
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/datum/objective/maroon
name = "maroon"
var/target_role_type=FALSE
martyr_compatible = 1

/datum/objective/maroon/find_target_by_role(role, role_type=FALSE,invert=FALSE)
if(!invert)
Expand Down
1 change: 0 additions & 1 deletion code/game/gamemodes/objectives/basic/mutiny.dm
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/datum/objective/mutiny
name = "mutiny"
var/target_role_type=FALSE
martyr_compatible = 1

/datum/objective/mutiny/find_target_by_role(role, role_type=FALSE,invert=FALSE)
if(!invert)
Expand Down
1 change: 0 additions & 1 deletion code/game/gamemodes/objectives/basic/protect.dm
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/datum/objective/protect//The opposite of killing a dude.
name = "protect"
martyr_compatible = 1
var/target_role_type = FALSE
var/human_check = TRUE

Expand Down
1 change: 0 additions & 1 deletion code/game/gamemodes/objectives/basic/silicon/block.dm
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/datum/objective/block
name = "no organics on shuttle"
explanation_text = "Do not allow any organic lifeforms to escape on the shuttle alive."
martyr_compatible = 1

/datum/objective/block/check_completion()
if(SSshuttle.emergency.mode != SHUTTLE_ENDGAME)
Expand Down
1 change: 0 additions & 1 deletion code/game/gamemodes/objectives/basic/silicon/purge.dm
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/datum/objective/purge
name = "no mutants on shuttle"
explanation_text = "Ensure no mutant humanoid species are present aboard the escape shuttle."
martyr_compatible = 1

/datum/objective/purge/check_completion()
if(SSshuttle.emergency.mode != SHUTTLE_ENDGAME)
Expand Down
2 changes: 1 addition & 1 deletion code/game/gamemodes/objectives/basic/silicon/robot_army.dm
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/datum/objective/robot_army
name = "robot army"
explanation_text = "Have at least eight active cyborgs synced to you."
martyr_compatible = 0
martyr_compatible = FALSE
var/counter = 0

/datum/objective/robot_army/check_completion()
Expand Down
4 changes: 2 additions & 2 deletions code/game/gamemodes/objectives/basic/steal.dm
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
GLOBAL_LIST_EMPTY(possible_items)
/datum/objective/steal
name = "steal"
martyr_compatible = FALSE
var/datum/objective_item/targetinfo = null //Save the chosen item datum so we can access it later.
var/obj/item/steal_target = null //Needed for custom objectives (they're just items, not datums).
martyr_compatible = 0

/datum/objective/steal/get_target()
return steal_target
Expand Down Expand Up @@ -113,7 +113,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)

/datum/objective/steal/exchange
name = "exchange"
martyr_compatible = 0
martyr_compatible = FALSE

/datum/objective/steal/exchange/admin_edit(mob/admin)
return
Expand Down
1 change: 1 addition & 0 deletions code/game/gamemodes/objectives/basic/steal_five.dm
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/datum/objective/steal_five_of_type
name = "steal five of"
explanation_text = "Steal at least five items!"
martyr_compatible = FALSE
var/list/wanted_items = list()
var/stolen_count = 0
var/thing_name = "item"
Expand Down
1 change: 0 additions & 1 deletion code/game/gamemodes/objectives/finale/nuclear.dm
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/datum/objective/nuclear
name = "nuclear"
explanation_text = "Destroy the station with a nuclear device."
martyr_compatible = 1
murderbone_flag = TRUE

/datum/objective/nuclear/check_completion()
Expand Down
2 changes: 1 addition & 1 deletion code/modules/admin/antag_panel.dm
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ GLOBAL_VAR(antag_prototypes)
alert("This mind doesn't have a mob, or is deleted! For some reason!", "Edit Memory")
return

var/out = "<B>[name]</B>[(current && (current.real_name!=name))?" (as [current.real_name])":""]<br>"
var/out = "[TOOLTIP_CSS_SETUP]<B>[name]</B>[(current && (current.real_name!=name))?" (as [current.real_name])":""]<br>"
out += "Mind currently owned by key: [key] [active?"(synced)":"(not synced)"]<br>"
out += "Assigned role: [assigned_role]. <a href='?src=[REF(src)];role_edit=1'>Edit</a><br>"
out += "Faction and special role: <b><font color='red'>[special_role]</font></b><br>"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@
for(var/datum/antagonist/summoner_antag in holder.owner.antag_datums)
if(istype(summoner_antag, /datum/antagonist/traitor))
var/datum/antagonist/traitor/summoner_traitor = summoner_antag
if(summoner_traitor.should_give_codewords)
if(summoner_traitor.has_codewords)
LAZYSET(extra_info, "Code Phrases", jointext(GLOB.syndicate_code_phrase, ", "))
extra_info["Code Responses"] = jointext(GLOB.syndicate_code_response, ", ")
var/datum/team/summoner_team = summoner_antag.get_team()
Expand Down
2 changes: 1 addition & 1 deletion code/modules/antagonists/traitor/IAA/internal_affairs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@
special_role = TRAITOR_AGENT_ROLE
syndicate = TRUE
log_game("[owner.key] has been designated an External Affairs Agent")
forge_single_objective()
forge_single_human_objective()

/datum/antagonist/traitor/internal_affairs/forge_traitor_objectives()
forge_iaa_objectives()
Expand Down