Files
Yogstation/code/controllers/subsystem/processing/quirks.dm
Rune Knight b76e8c45ec New Station Trait: Cybernetic Revolution + Body Purist Quirk (#21882)
* first half of port

* no mail goodies

* no more errors in vsc, but errors in build

* debugging and setting implants

* quirk blacklist

* discounts and markups

* station must load first and THEN research

* round up

* quirk works now

* signals

* runover

* and thats it

* it is illegal to be too different :\

* ya meson eyes for janitor just sucks ass, so get a worse organ (heart)

* whoops double discount

* alphabetical

* zzz

* why extra tab

* no need for extra linebreak

* zzz2

* comment: makes it clear that body purist prevents effect :)
2024-04-27 20:43:41 -05:00

157 lines
5.3 KiB
Plaintext

//Used to process and handle roundstart quirks
// - Quirk strings are used for faster checking in code
// - Quirk datums are stored and hold different effects, as well as being a vector for applying trait string
PROCESSING_SUBSYSTEM_DEF(quirks)
name = "Quirks"
init_order = INIT_ORDER_QUIRKS
flags = SS_BACKGROUND
wait = 1 SECONDS
runlevels = RUNLEVEL_GAME
var/list/quirks = list() //Assoc. list of all roundstart quirk datum types; "name" = /path/
var/list/quirk_points = list() //Assoc. list of quirk names and their "point cost"; positive numbers are good traits, and negative ones are bad
var/list/quirk_objects = list() //A list of all quirk objects in the game, since some may process
var/static/list/quirk_blacklist = list( //A list a list of quirks that can not be used with each other. Format: list(quirk1,quirk2),list(quirk3,quirk4)
list("Blind","Nearsighted"),
list("Jolly","Depression","Apathetic","Hypersensitive"),
list("Ageusia","Vegetarian","Deviant Tastes"),
list("Ananas Affinity","Ananas Aversion"),
list("Alcohol Tolerance","Light Drinker"),
list("Prosthetic Limb (Left Arm)","Prosthetic Limb", "Body Purist"),
list("Prosthetic Limb (Right Arm)","Prosthetic Limb", "Body Purist"),
list("Prosthetic Limb (Left Leg)","Prosthetic Limb", "Body Purist"),
list("Prosthetic Limb (Right Leg)","Prosthetic Limb", "Body Purist"),
list("Prosthetic Limb (Left Leg)","Paraplegic", "Body Purist"),
list("Prosthetic Limb (Right Leg)","Paraplegic", "Body Purist"),
list("Prosthetic Limb", "Paraplegic"),
list("Prosthetic Limb", "Body Purist"),
list("Cybernetic Organ (Lungs)", "Body Purist"),
list("Cybernetic Organ (Heart)", "Body Purist"),
list("Cybernetic Organ (Liver)", "Body Purist"),
list("Upgraded Cybernetic Organ", "Body Purist")
)
/datum/controller/subsystem/processing/quirks/Initialize(timeofday)
if(!quirks.len)
SetupQuirks()
return SS_INIT_SUCCESS
//basically a lazily loaded list of quirks, never access .quirks directly.
/datum/controller/subsystem/processing/quirks/proc/get_quirks()
if(!quirks.len)
SetupQuirks()
return quirks
/datum/controller/subsystem/processing/quirks/proc/SetupQuirks()
// Sort by Positive, Negative, Neutral; and then by name
var/list/quirk_list = sortList(subtypesof(/datum/quirk), /proc/cmp_quirk_asc)
for(var/V in quirk_list)
var/datum/quirk/T = V
quirks[initial(T.name)] = T
quirk_points[initial(T.name)] = initial(T.value)
/datum/controller/subsystem/processing/quirks/proc/AssignQuirks(mob/living/user, client/cli, spawn_effects)
if(!checkquirks(user,cli)) return// Yogs -- part of Adding Mood as Preference
if(user.job)
for(var/V in cli.prefs.all_quirks)
var/datum/quirk/Q = quirks[V]
if(Q)
Q = new Q (no_init = TRUE)
if(user.job in Q.job_blacklist)
to_chat(cli, span_danger("One or more of your quirks is incompatible with your job so all have been removed."))
return
qdel(Q)//clean up afterwards
var/badquirk = FALSE
for(var/V in cli.prefs.all_quirks)
var/datum/quirk/Q = quirks[V]
if(Q)
user.add_quirk(Q, spawn_effects)
else
stack_trace("Invalid quirk \"[V]\" in client [cli.ckey] preferences")
cli.prefs.all_quirks -= V
badquirk = TRUE
if(badquirk)
cli.prefs.save_character()
/// Takes a list of quirk names and returns a new list of quirks that would
/// be valid.
/// If no changes need to be made, will return the same list.
/// Expects all quirk names to be unique, but makes no other expectations.
/datum/controller/subsystem/processing/quirks/proc/filter_invalid_quirks(list/quirks, client_or_prefs)
var/list/new_quirks = list()
var/list/positive_quirks = list()
var/balance = 0
var/datum/preferences/prefs = client_or_prefs
if (istype(client_or_prefs, /client))
var/client/client = client_or_prefs
prefs = client.prefs
// If moods are globally enabled, or this guy does indeed have his mood pref set to Enabled
var/ismoody = (!CONFIG_GET(flag/disable_human_mood) || (prefs.read_preference(/datum/preference/toggle/mood_enabled)))
var/list/all_quirks = get_quirks() //forces a load of the quirks if they aren't setup already
for (var/quirk_name in quirks)
var/datum/quirk/quirk = all_quirks[quirk_name]
if (isnull(quirk))
continue
if (initial(quirk.mood_quirk) && !ismoody)
continue
// Returns error string, FALSE if quirk is okay to have
var/datum/quirk/quirk_obj = new quirk(no_init = TRUE)
if (quirk_obj?.check_quirk(prefs))
continue
qdel(quirk_obj)
var/blacklisted = FALSE
for (var/list/blacklist as anything in quirk_blacklist)
if (!(quirk in blacklist))
continue
for (var/other_quirk in blacklist)
if (other_quirk in new_quirks)
blacklisted = TRUE
break
if (blacklisted)
break
if (blacklisted)
continue
var/value = initial(quirk.value)
if (value > 0)
if (positive_quirks.len == MAX_QUIRKS)
continue
positive_quirks[quirk_name] = value
balance += value
new_quirks += quirk_name
if (balance > 0)
var/balance_left_to_remove = balance
for (var/positive_quirk in positive_quirks)
var/value = positive_quirks[positive_quirk]
balance_left_to_remove -= value
new_quirks -= positive_quirk
if (balance_left_to_remove <= 0)
break
// It is guaranteed that if no quirks are invalid, you can simply check through `==`
if (new_quirks.len == quirks.len)
return quirks
return new_quirks