-
-
Notifications
You must be signed in to change notification settings - Fork 444
/
Copy pathquirks.dm
156 lines (126 loc) · 5.28 KB
/
quirks.dm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
//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