Skip to content

Commit

Permalink
Antag optin (#1891)
Browse files Browse the repository at this point in the history
* PLEASE

* remove the remnants of the fallen state

* we should improve this somewhat

* Apply suggestions from code review

* Apply suggestions from code review

* Update code/modules/jobs/job_types/_job.dm

* Update code/datums/brain_damage/creepy_trauma.dm

* me when

* Typo

* Skyrat defines->nova defines

* Revert "Skyrat defines->nova defines"

This reverts commit 46f5fd5ab97edd58aac59d0fdbdcd48bebc54f95.

* Update tgstation.dme

* Revert "Update tgstation.dme"

This reverts commit 1f5bc9672bba5b28e7d08c47eac695222ee36d67.

* Update tgstation.dme

* Update tgstation.dme

* fix config

* awarfgh

* this should work?

* ill finish this later

* okay

* arggh

* well, at least it can be lazy

* agshj

* lil fixy

* config

* tis is a g ood  change

* guess who forgot to push a commit

* Apply suggestions from code review



* lets just safeguard

* move maroon to rr

* Trigger CI

* awagga

* 2nd debug code

* lets fix compile

* respect the be antag switch

* i need to push this shit already

* ok

---------

Co-authored-by: nikothedude <[email protected]>
Co-authored-by: Bloop <[email protected]>
Co-authored-by: Iajret <[email protected]>
  • Loading branch information
4 people authored Mar 1, 2024
1 parent 09859ae commit 6f3fbc0
Show file tree
Hide file tree
Showing 23 changed files with 589 additions and 17 deletions.
45 changes: 45 additions & 0 deletions code/__DEFINES/~nova_defines/antag_optin_defines.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//defines for antag opt in objective checking
//objectives check for all players with a value equal or greater than the 'threat' level of an objective then pick from that list
//command + sec roles are always opted in regardless of opt in status

/// For temporary or otherwise 'inconvenient' objectives like kidnapping or theft
#define OPT_IN_YES_TEMP 1
/// Cool with being killed or otherwise occupied but not removed from the round
#define OPT_IN_YES_KILL 2
/// Fine with being round removed.
#define OPT_IN_YES_ROUND_REMOVE 3

#define OPT_IN_YES_TEMP_STRING "Yes - Temporary/Inconvenience"
#define OPT_IN_YES_KILL_STRING "Yes - Kill"
#define OPT_IN_YES_ROUND_REMOVE_STRING "Yes - Round Remove"
#define OPT_IN_NOT_TARGET_STRING "No"

/// Assoc list of stringified opt_in_## define to the front-end string to show users as a representation of the setting.
GLOBAL_LIST_INIT(antag_opt_in_strings, list(
"0" = OPT_IN_NOT_TARGET_STRING,
"1" = OPT_IN_YES_TEMP_STRING,
"2" = OPT_IN_YES_KILL_STRING,
"3" = OPT_IN_YES_ROUND_REMOVE_STRING,
))

/// Assoc list of stringified opt_in_## define to the color associated with it.
GLOBAL_LIST_INIT(antag_opt_in_colors, list(
OPT_IN_NOT_TARGET_STRING = COLOR_GRAY,
OPT_IN_YES_TEMP_STRING = COLOR_EMERALD,
OPT_IN_YES_KILL_STRING = COLOR_ORANGE,
OPT_IN_YES_ROUND_REMOVE_STRING = COLOR_RED
))

/// Prefers not to be a target. Will still be a potential target if playing sec or command.
#define OPT_IN_NOT_TARGET 0

/// The minimum opt-in level for people playing sec.
#define SECURITY_OPT_IN_LEVEL OPT_IN_YES_KILL
/// The minimum opt-in level for people playing command.
#define COMMAND_OPT_IN_LEVEL OPT_IN_YES_KILL

/// The default opt in level for preferences and mindless mobs.
#define OPT_IN_DEFAULT_LEVEL OPT_IN_NOT_TARGET

/// If the player has any non-ghost role antags enabled, they are forced to use a minimum of this.
#define OPT_IN_ANTAG_ENABLED_LEVEL OPT_IN_YES_TEMP
Original file line number Diff line number Diff line change
Expand Up @@ -942,12 +942,16 @@
/datum/dynamic_ruleset/midround/from_ghosts/paradox_clone/proc/find_original()
var/list/possible_targets = list()

var/opt_in_disabled = CONFIG_GET(flag/disable_antag_opt_in_preferences) // NOVA EDIT ADDITION - ANTAG OPT-IN
for(var/mob/living/carbon/human/player in GLOB.player_list)
if(!player.client || !player.mind || player.stat)
continue
if(!(player.mind.assigned_role.job_flags & JOB_CREW_MEMBER))
continue
possible_targets += player
// NOVA EDIT ADDITION START - Players in the interlink can't be obsession targets + Antag Optin
if (!opt_in_disabled && player.mind?.get_effective_opt_in_level() < OPT_IN_YES_ROUND_REMOVE)
continue
// NOVA EDIT ADDITION END

if(possible_targets.len)
return pick(possible_targets)
Expand Down
7 changes: 5 additions & 2 deletions code/datums/brain_damage/creepy_trauma.dm
Original file line number Diff line number Diff line change
Expand Up @@ -131,15 +131,18 @@
var/list/special_pool = list() //The special list, for quirk-based
var/chosen_victim //The obsession target

var/opt_in_disabled = CONFIG_GET(flag/disable_antag_opt_in_preferences) // NOVA EDIT ADDITION - ANTAG OPT-IN
for(var/mob/player as anything in GLOB.player_list)//prevents crew members falling in love with nuke ops they never met, and other annoying hijinks
if(!player.client || !player.mind || isnewplayer(player) || player.stat == DEAD || isbrain(player) || player == owner)
continue
if(!(player.mind.assigned_role.job_flags & JOB_CREW_MEMBER))
continue
// NOVA EDIT ADDITION START - Players in the interlink can't be obsession targets
// NOVA EDIT ADDITION START - Players in the interlink can't be obsession targets + Antag Optin
if(SSticker.IsRoundInProgress() && istype(get_area(player), /area/centcom/interlink))
continue
// NOVA EDIT END
if (!opt_in_disabled && player.mind?.get_effective_opt_in_level() < OPT_IN_YES_KILL)
continue
// NOVA EDIT ADDITION END
viable_minds += player.mind
for(var/datum/mind/possible_target as anything in viable_minds)
if(possible_target != owner && ishuman(possible_target.current))
Expand Down
15 changes: 14 additions & 1 deletion code/game/gamemodes/objective.dm
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ GLOBAL_LIST_EMPTY(objectives) //NOVA EDIT ADDITION
var/datum/mind/O = I
if(O.late_joiner)
try_target_late_joiners = TRUE
var/opt_in_disabled = CONFIG_GET(flag/disable_antag_opt_in_preferences) // NOVA EDIT ADDITION - ANTAG OPT-IN
for(var/datum/mind/possible_target in get_crewmember_minds())
if(possible_target in owners)
continue
Expand All @@ -166,6 +167,10 @@ GLOBAL_LIST_EMPTY(objectives) //NOVA EDIT ADDITION
continue
if(!is_valid_target(possible_target))
continue
// NOVA EDIT ADDITION START - Antag Opt In
if (!opt_in_disabled && !opt_in_valid(possible_target))
continue
// NOVA EDIT ADDITION END
possible_targets += possible_target
if(try_target_late_joiners)
var/list/all_possible_targets = possible_targets.Copy()
Expand Down Expand Up @@ -871,7 +876,15 @@ GLOBAL_LIST_EMPTY(possible_items)
/datum/objective/destroy/find_target(dupe_search_range, list/blacklist)
var/list/possible_targets = active_ais(TRUE)
possible_targets -= blacklist
var/mob/living/silicon/ai/target_ai = pick(possible_targets)
//var/mob/living/silicon/ai/target_ai = pick(possible_targets) // NOVA EDIT REMOVAL - Uses the below loop
// NOVA EDIT ADDITION BEGIN - ANTAG OPTIN
var/mob/living/silicon/ai/target_ai
var/opt_in_disabled = CONFIG_GET(flag/disable_antag_opt_in_preferences) // NOVA EDIT ADDITION - ANTAG OPT-IN
for (var/mob/living/silicon/ai/possible_target as anything in shuffle(possible_targets))
if (!opt_in_disabled && !opt_in_valid(possible_target))
continue
target_ai = possible_target
// NOVA EDIT ADDITION END
target = target_ai.mind
update_explanation_text()
return target
Expand Down
9 changes: 7 additions & 2 deletions code/modules/antagonists/cult/cult_objectives.dm
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,24 @@
return
var/datum/team/cult/cult = team
var/list/target_candidates = list()
var/opt_in_disabled = CONFIG_GET(flag/disable_antag_opt_in_preferences) // NOVA EDIT ADDITION - ANTAG OPT-IN
for(var/mob/living/carbon/human/player in GLOB.player_list)
// NOVA EDIT ADDITION START - Players in the interlink can't be obsession targets
// NOVA EDIT ADDITION START - Players in the interlink can't be obsession targets + Antag Optin
if(SSticker.IsRoundInProgress() && istype(get_area(player), /area/centcom/interlink))
continue
if (!opt_in_disabled && !opt_in_valid(player))
continue
// NOVA EDIT END
if(player.mind && !player.mind.has_antag_datum(/datum/antagonist/cult) && !is_convertable_to_cult(player) && player.stat != DEAD)
target_candidates += player.mind
if(target_candidates.len == 0)
message_admins("Cult Sacrifice: Could not find unconvertible target, checking for convertible target.")
for(var/mob/living/carbon/human/player in GLOB.player_list)
// NOVA EDIT ADDITION START - Players in the interlink can't be obsession targets
// NOVA EDIT ADDITION START - Players in the interlink can't be obsession targets + Antag Optin
if(SSticker.IsRoundInProgress() && istype(get_area(player), /area/centcom/interlink))
continue
if (!opt_in_disabled && !opt_in_valid(player))
continue
// NOVA EDIT END
if(player.mind && !player.mind.has_antag_datum(/datum/antagonist/cult) && player.stat != DEAD)
target_candidates += player.mind
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@
continue
if(possible_target.current.stat == DEAD)
continue
// NOVA EDIT ADDITION BEGIN - Antag opt-in (Only security and command can be targetted)
if (!possible_target.assigned_role?.heretic_sac_target)
continue
// NOVA EDIT ADDITION END

valid_targets += possible_target

Expand Down Expand Up @@ -142,12 +146,14 @@
valid_targets -= sec_mind
break

/* NOVA EDIT REMOVAL -- Antag Opt In (Only sec and command may be targetted)
// Third target, someone in their department.
for(var/datum/mind/department_mind as anything in shuffle(valid_targets))
if(department_mind.assigned_role?.departments_bitflags & user.mind.assigned_role?.departments_bitflags)
final_targets += department_mind
valid_targets -= department_mind
break
*/ // NOVA EDIT REMOVAL END

// Now grab completely random targets until we'll full
var/target_sanity = 0
Expand Down
9 changes: 9 additions & 0 deletions code/modules/jobs/job_types/_job.dm
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,15 @@
info += span_boldnotice("As this station was initially staffed with a \
[CONFIG_GET(flag/jobs_have_minimal_access) ? "full crew, only your job's necessities" : "skeleton crew, additional access may"] \
have been added to your ID card.")
//NOVA EDIT ADDITION BEGIN - ANTAG OPT IN
if (!CONFIG_GET(flag/disable_antag_opt_in_preferences))
if (isnum(minimum_opt_in_level) && minimum_opt_in_level > OPT_IN_NOT_TARGET)
info += span_bolddanger("This job forces a minimum opt-in setting of [GLOB.antag_opt_in_strings["[minimum_opt_in_level]"]].")
if (heretic_sac_target)
info += span_bolddanger("This job can be sacrificed by heretics.")
if (contractable)
info += span_bolddanger("This job can be targeted by contractors.")
//NOVA EDIT ADDITION END
//NOVA EDIT ADDITION START - ALTERNATIVE_JOB_TITLES
if(alt_title != title)
info += span_warning("Remember that alternate titles are purely for flavor and roleplay.")
Expand Down
6 changes: 6 additions & 0 deletions code/modules/mob/living/carbon/human/examine.dm
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,12 @@
if(erp_status_pref && !CONFIG_GET(flag/disable_erp_preferences))
. += span_notice("ERP STATUS: [erp_status_pref]")

if (!CONFIG_GET(flag/disable_antag_opt_in_preferences))
var/opt_in_status = mind?.get_effective_opt_in_level()
if (!isnull(opt_in_status))
var/stringified_optin = GLOB.antag_opt_in_strings["[opt_in_status]"]
. += span_notice("Antag Opt-in Status: <b><font color='[GLOB.antag_opt_in_colors[stringified_optin]]'>[stringified_optin]</font></b>")

//Temporary flavor text addition:
if(temporary_flavor_text)
if(length_char(temporary_flavor_text) < TEMPORARY_FLAVOR_PREVIEW_LIMIT)
Expand Down
3 changes: 3 additions & 0 deletions config/nova/config_nova.txt
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,6 @@ VETERAN_LEGACY_SYSTEM

## How much time arrivals shuttle should stay at station after its engines recharged before returning to interlink. In deciseconds. 150 - 15 seconds. 0 - disables autoreturn.
ARRIVALS_WAIT 150

## Uncomment to completely disable the opt-in system, which is a system that forces objectives to only roll on individuals who consent to it.
#DISABLE_ANTAG_OPT_IN_PREFERENCES
41 changes: 31 additions & 10 deletions modular_nova/master_files/code/modules/mob/living/examine_tgui.dm
Original file line number Diff line number Diff line change
Expand Up @@ -54,19 +54,30 @@
var/custom_species_lore
var/obscured
var/ooc_notes = ""
var/ideal_antag_optin_status
var/current_antag_optin_status
var/headshot = ""

// Handle OOC notes first
if(preferences && preferences.read_preference(/datum/preference/toggle/master_erp_preferences))
var/e_prefs = preferences.read_preference(/datum/preference/choiced/erp_status)
var/e_prefs_nc = preferences.read_preference(/datum/preference/choiced/erp_status_nc)
var/e_prefs_v = preferences.read_preference(/datum/preference/choiced/erp_status_v)
var/e_prefs_mechanical = preferences.read_preference(/datum/preference/choiced/erp_status_mechanics)
ooc_notes += "ERP: [e_prefs]\n"
ooc_notes += "Non-Con: [e_prefs_nc]\n"
ooc_notes += "Vore: [e_prefs_v]\n"
ooc_notes += "ERP Mechanics: [e_prefs_mechanical]\n"
ooc_notes += "\n"
if(preferences)
if(preferences.read_preference(/datum/preference/toggle/master_erp_preferences))
var/e_prefs = preferences.read_preference(/datum/preference/choiced/erp_status)
var/e_prefs_nc = preferences.read_preference(/datum/preference/choiced/erp_status_nc)
var/e_prefs_v = preferences.read_preference(/datum/preference/choiced/erp_status_v)
var/e_prefs_mechanical = preferences.read_preference(/datum/preference/choiced/erp_status_mechanics)
ooc_notes += "ERP: [e_prefs]\n"
ooc_notes += "Non-Con: [e_prefs_nc]\n"
ooc_notes += "Vore: [e_prefs_v]\n"
ooc_notes += "ERP Mechanics: [e_prefs_mechanical]\n"
ooc_notes += "\n"

if(!CONFIG_GET(flag/disable_antag_opt_in_preferences))
var/antag_prefs = holder.mind?.ideal_opt_in_level
var/effective_opt_in_level = holder.mind?.get_effective_opt_in_level()
if(isnull(antag_prefs))
antag_prefs = preferences.read_preference(/datum/preference/choiced/antag_opt_in_status)
current_antag_optin_status = GLOB.antag_opt_in_strings[num2text(effective_opt_in_level)]
ideal_antag_optin_status = GLOB.antag_opt_in_strings[num2text(antag_prefs)]

// Now we handle silicon and/or human, order doesn't really matter
// If other variants of mob/living need to be handled at some point, put them here
Expand Down Expand Up @@ -97,4 +108,14 @@
data["custom_species"] = custom_species
data["custom_species_lore"] = custom_species_lore
data["headshot"] = headshot

data["ideal_antag_optin_status"] = ideal_antag_optin_status
data["current_antag_optin_status"] = current_antag_optin_status
return data

/datum/examine_panel/ui_static_data(mob/user)
var/list/data = list()

data["opt_in_colors"] = GLOB.antag_opt_in_colors

return data
2 changes: 2 additions & 0 deletions modular_nova/modules/antag_opt_in/code/antag_optin_config.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/datum/config_entry/flag/disable_antag_opt_in_preferences
default = FALSE
33 changes: 33 additions & 0 deletions modular_nova/modules/antag_opt_in/code/antag_optin_preferences.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/datum/preference/choiced/antag_opt_in_status
category = PREFERENCE_CATEGORY_NON_CONTEXTUAL
savefile_identifier = PREFERENCE_CHARACTER
savefile_key = "antag_opt_in_status_pref"

/datum/preference/choiced/antag_opt_in_status/init_possible_values()
return list(OPT_IN_YES_TEMP, OPT_IN_YES_KILL, OPT_IN_YES_ROUND_REMOVE, OPT_IN_NOT_TARGET)

/datum/preference/choiced/antag_opt_in_status/create_default_value()
return OPT_IN_DEFAULT_LEVEL

/datum/preference/choiced/antag_opt_in_status/is_accessible(datum/preferences/preferences)
if (!..(preferences))
return FALSE

return !(CONFIG_GET(flag/disable_antag_opt_in_preferences))

/datum/preference/choiced/antag_opt_in_status/deserialize(input, datum/preferences/preferences)
if(CONFIG_GET(flag/disable_antag_opt_in_preferences))
return OPT_IN_DEFAULT_LEVEL

return ..()

/datum/preference/choiced/antag_opt_in_status/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences)
return FALSE

/datum/preference/choiced/antag_opt_in_status/compile_constant_data()
var/list/data = ..()

// An assoc list of values to display names so we don't show players numbers in their settings!
data[CHOICED_PREFERENCE_DISPLAY_NAMES] = GLOB.antag_opt_in_strings

return data
72 changes: 72 additions & 0 deletions modular_nova/modules/antag_opt_in/code/job.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/datum/job
/// The minimum antag opt-in any holder of this job must use. If null, will defer to the mind's opt in level.
var/minimum_opt_in_level
/// Can this job be targetted as a heretic sacrifice target?
var/heretic_sac_target
/// Is this job targetable by contractors?
var/contractable

/// Updates [minimum_opt_in_level] [heretic_sac_target] and [contractable].
/datum/job/proc/update_opt_in_vars()
if(CONFIG_GET(flag/disable_antag_opt_in_preferences))
return

if(isnull(minimum_opt_in_level))
minimum_opt_in_level = get_initial_opt_in_level()
if(isnull(heretic_sac_target))
heretic_sac_target = initialize_heretic_target_status()
if(isnull(contractable))
contractable = initialize_contractable_status()

update_opt_in_desc_suffix()

/// Returns this job's initial opt in level, taking into account departmental bitflags.
/datum/job/proc/get_initial_opt_in_level()
if (departments_bitflags & (DEPARTMENT_BITFLAG_SECURITY))
return SECURITY_OPT_IN_LEVEL
if (departments_bitflags & (DEPARTMENT_BITFLAG_COMMAND))
return COMMAND_OPT_IN_LEVEL

/// Determines if this job should be sacrificable by heretics.
/datum/job/proc/initialize_heretic_target_status()
if (departments_bitflags & (DEPARTMENT_BITFLAG_SECURITY | DEPARTMENT_BITFLAG_COMMAND))
return TRUE

return FALSE

/// Determines if this job should be targetable by contractors.
/datum/job/proc/initialize_contractable_status()
if (departments_bitflags & (DEPARTMENT_BITFLAG_SECURITY | DEPARTMENT_BITFLAG_COMMAND))
return TRUE

return FALSE

/// Generates and sets a suffix appended to our description detailing our opt-in variables.
/datum/job/proc/update_opt_in_desc_suffix()
var/list/suffixes = list()

if (minimum_opt_in_level)
suffixes += " Forces a minimum of [GLOB.antag_opt_in_strings["[minimum_opt_in_level]"]] antag opt-in."
if (contractable)
suffixes += " Targetable by contractors."
if (heretic_sac_target)
suffixes += " Targetable by heretics."
if (length(suffixes))
var/suffix = jointext(suffixes, "")
set_opt_in_desc_suffix(suffix)

/// Setter for [new_suffix]. Resets desc then appends the new suffix.
/datum/job/proc/set_opt_in_desc_suffix(new_suffix)
description = initial(description)

if (new_suffix)
description += new_suffix

/datum/controller/subsystem/job/SetupOccupations()
. = ..()

if(CONFIG_GET(flag/disable_antag_opt_in_preferences))
return

for(var/datum/job/job as anything in all_occupations)
job.update_opt_in_vars()
Loading

0 comments on commit 6f3fbc0

Please sign in to comment.