-
-
Notifications
You must be signed in to change notification settings - Fork 444
/
Copy pathoutfit.dm
executable file
·407 lines (358 loc) · 12.1 KB
/
outfit.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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
/**
* # Outfit datums
*
* This is a clean system of applying outfits to mobs, if you need to equip someone in a uniform
* this is the way to do it cleanly and properly.
*
* You can also specify an outfit datum on a job to have it auto equipped to the mob on join
*
* /mob/living/carbon/human/proc/equipOutfit(outfit) is the mob level proc to equip an outfit
* and you pass it the relevant datum outfit
*
* outfits can also be saved as json blobs downloadable by a client and then can be uploaded
* by that user to recreate the outfit, this is used by admins to allow for custom event outfits
* that can be restored at a later date
*/
/datum/outfit
///Name of the outfit (shows up in the equip admin verb)
var/name = "Naked"
/// Type path of item to go in uniform slot
var/uniform = null
/// Type path of item to go in suit slot
var/suit = null
/// Type path of item to go in back slot
var/back = null
/// Type path of item to go in belt slot
var/belt = null
/// Type path of item to go in gloves slot
var/gloves = null
/// Type path of item to go in shoes slot
var/shoes = null
/// Type path of item to go in head slot
var/head = null
/// Type path of item to go in mask slot
var/mask = null
/// Type path of item to go in neck slot
var/neck = null
/// Type path of item to go in ears slot
var/ears = null
/// Type path of item to go in the glasses slot
var/glasses = null
/// Type path of item to go in the idcard slot
var/id = null
/// Type path of item for left pocket slot
var/l_pocket = null
/// Type path of item for right pocket slot
var/r_pocket = null
/**
* Type path of item to go in suit storage slot
*
* (make sure it's valid for that suit)
*/
var/suit_store = null
///Type path of item to go in the right hand
var/r_hand = null
//Type path of item to go in left hand
var/l_hand = null
/// Should the toggle helmet proc be called on the helmet during equip
var/toggle_helmet = TRUE
///Should we preload some of this job's items?
var/preload = FALSE
///ID of the slot containing a gas tank
var/internals_slot = null
/**
* list of items that should go in the backpack of the user
*
* Format of this list should be: list(path=count,otherpath=count)
*/
var/list/backpack_contents = null
/// Internals box. Will be inserted at the start of backpack_contents
var/box
/**
* Any implants the mob should start implanted with
*
* Format of this list is (typepath, typepath, typepath)
*/
var/list/implants = null
/// Any clothing accessory item
var/accessory = null
/// Set to FALSE if your outfit requires runtime parameters
var/can_be_admin_equipped = TRUE
/**
* extra types for chameleon outfit changes, mostly guns
*
* Format of this list is (typepath, typepath, typepath)
*
* These are all added and returns in the list for get_chamelon_diguise_info proc
*/
var/list/chameleon_extras
/**
* Called at the start of the equip proc
*
* Override to change the value of the slots depending on client prefs, species and
* other such sources of change
*
* Extra Arguments
* * visualsOnly true if this is only for display (in the character setup screen)
*
* If visualsOnly is true, you can omit any work that doesn't visually appear on the character sprite
*/
/datum/outfit/proc/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
//to be overridden for customization depending on client prefs,species etc
return
/**
* Called after the equip proc has finished
*
* All items are on the mob at this point, use this proc to toggle internals
* fiddle with id bindings and accesses etc
*
* Extra Arguments
* * visualsOnly true if this is only for display (in the character setup screen)
*
* If visualsOnly is true, you can omit any work that doesn't visually appear on the character sprite
*/
/datum/outfit/proc/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
//to be overridden for toggling internals, id binding, access etc
return
/**
* Equips all defined types and paths to the mob passed in
*
* Extra Arguments
* * visualsOnly true if this is only for display (in the character setup screen)
*
* If visualsOnly is true, you can omit any work that doesn't visually appear on the character sprite
*/
/datum/outfit/proc/equip(mob/living/carbon/human/H, visualsOnly = FALSE)
pre_equip(H, visualsOnly)
//Start with uniform,suit,backpack for additional slots
if(uniform)
H.equip_to_slot_or_del(SSwardrobe.provide_type(uniform, H), ITEM_SLOT_ICLOTHING, TRUE)
if(suit)
H.equip_to_slot_or_del(SSwardrobe.provide_type(suit, H), ITEM_SLOT_OCLOTHING, TRUE)
if(back)
H.equip_to_slot_or_del(SSwardrobe.provide_type(back, H), ITEM_SLOT_BACK, TRUE)
if(belt)
H.equip_to_slot_or_del(SSwardrobe.provide_type(belt, H), ITEM_SLOT_BELT, TRUE)
if(gloves)
H.equip_to_slot_or_del(SSwardrobe.provide_type(gloves, H), ITEM_SLOT_GLOVES, TRUE)
if(shoes)
H.equip_to_slot_or_del(SSwardrobe.provide_type(shoes, H), ITEM_SLOT_FEET, TRUE)
if(head)
H.equip_to_slot_or_del(SSwardrobe.provide_type(head, H), ITEM_SLOT_HEAD, TRUE)
if(mask)
H.equip_to_slot_or_del(SSwardrobe.provide_type(mask, H), ITEM_SLOT_MASK, TRUE)
if(neck)
H.equip_to_slot_or_del(SSwardrobe.provide_type(neck, H), ITEM_SLOT_NECK, TRUE)
if(ears)
H.equip_to_slot_or_del(SSwardrobe.provide_type(ears, H), ITEM_SLOT_EARS, TRUE)
if(glasses)
H.equip_to_slot_or_del(SSwardrobe.provide_type(glasses, H), ITEM_SLOT_EYES, TRUE)
if(id)
H.equip_to_slot_or_del(SSwardrobe.provide_type(id, H), ITEM_SLOT_ID, TRUE)
if(suit_store)
H.equip_to_slot_or_del(SSwardrobe.provide_type(suit_store, H), ITEM_SLOT_SUITSTORE, TRUE)
if(accessory)
var/obj/item/clothing/under/U = H.w_uniform
if(U)
U.attach_accessory(SSwardrobe.provide_type(accessory, H))
else
WARNING("Unable to equip accessory [accessory] in outfit [name]. No uniform present!")
if(l_hand)
H.put_in_l_hand(SSwardrobe.provide_type(l_hand, H))
if(r_hand)
H.put_in_r_hand(SSwardrobe.provide_type(r_hand, H))
if(!visualsOnly) // Items in pockets or backpack don't show up on mob's icon.
if(l_pocket)
H.equip_to_slot_or_del(SSwardrobe.provide_type(l_pocket, H), ITEM_SLOT_LPOCKET, TRUE)
if(r_pocket)
H.equip_to_slot_or_del(SSwardrobe.provide_type(r_pocket, H), ITEM_SLOT_RPOCKET, TRUE)
if(box)
if(!backpack_contents)
backpack_contents = list()
backpack_contents.Insert(1, box)
backpack_contents[box] = 1
if(backpack_contents)
for(var/path in backpack_contents)
var/number = backpack_contents[path]
if(!isnum(number))//Default to 1
number = 1
for(var/i in 1 to number)
H.equip_to_slot_or_del(SSwardrobe.provide_type(path, H),ITEM_SLOT_BACKPACK, TRUE)
if(!H.head && toggle_helmet && istype(H.wear_suit, /obj/item/clothing/suit/space/hardsuit))
var/obj/item/clothing/suit/space/hardsuit/HS = H.wear_suit
HS.ToggleHelmet()
post_equip(H, visualsOnly)
if(!visualsOnly)
apply_fingerprints(H)
if(internals_slot)
H.open_internals(H.get_item_by_slot(internals_slot))
if(implants)
for(var/implant_type in implants)
var/obj/item/implant/I = SSwardrobe.provide_type(implant_type, H)
I.implant(H, null, TRUE)
H.update_body()
return TRUE
/**
* Apply a fingerprint from the passed in human to all items in the outfit
*
* Used for forensics setup when the mob is first equipped at roundstart
* essentially calls add_fingerprint to every defined item on the human
*
*/
/datum/outfit/proc/apply_fingerprints(mob/living/carbon/human/H)
if(!istype(H))
return
if(H.back)
H.back.add_fingerprint(H,1) //The 1 sets a flag to ignore gloves
for(var/obj/item/I in H.back.contents)
I.add_fingerprint(H,1)
if(H.wear_id)
H.wear_id.add_fingerprint(H,1)
if(H.w_uniform)
H.w_uniform.add_fingerprint(H,1)
if(H.wear_suit)
H.wear_suit.add_fingerprint(H,1)
if(H.wear_mask)
H.wear_mask.add_fingerprint(H,1)
if(H.wear_neck)
H.wear_neck.add_fingerprint(H,1)
if(H.head)
H.head.add_fingerprint(H,1)
if(H.shoes)
H.shoes.add_fingerprint(H,1)
if(H.gloves)
H.gloves.add_fingerprint(H,1)
if(H.ears)
H.ears.add_fingerprint(H,1)
if(H.glasses)
H.glasses.add_fingerprint(H,1)
if(H.belt)
H.belt.add_fingerprint(H,1)
for(var/obj/item/I in H.belt.contents)
I.add_fingerprint(H,1)
if(H.s_store)
H.s_store.add_fingerprint(H,1)
if(H.l_store)
H.l_store.add_fingerprint(H,1)
if(H.r_store)
H.r_store.add_fingerprint(H,1)
for(var/obj/item/I in H.held_items)
I.add_fingerprint(H,1)
return 1
/// Return a list of all the types that are required to disguise as this outfit type
/datum/outfit/proc/get_chameleon_disguise_info()
var/list/types = list(uniform, suit, back, belt, gloves, shoes, head, mask, neck, ears, glasses, id, l_pocket, r_pocket, suit_store, r_hand, l_hand)
types += chameleon_extras
listclearnulls(types)
return types
/// Return a list of types to pregenerate for later equipping
/// This should not be things that do unique stuff in Initialize(mapload) based off their location, since we'll be storing them for a while
/datum/outfit/proc/get_types_to_preload()
var/list/preload = list()
preload += id
preload += uniform
preload += suit
preload += suit_store
preload += back
//Load in backpack gear and shit
for(var/datum/type_to_load in backpack_contents)
for(var/i in 1 to backpack_contents[type_to_load])
preload += type_to_load
preload += belt
preload += ears
preload += glasses
preload += gloves
preload += head
preload += mask
preload += neck
preload += shoes
preload += l_pocket
preload += r_pocket
preload += l_hand
preload += r_hand
preload += accessory
preload += box
for(var/implant_type in implants)
preload += implant_type
return preload
/// Return a json list of this outfit
/datum/outfit/proc/get_json_data()
. = list()
.["outfit_type"] = type
.["name"] = name
.["uniform"] = uniform
.["suit"] = suit
.["toggle_helmet"] = toggle_helmet
.["back"] = back
.["belt"] = belt
.["gloves"] = gloves
.["shoes"] = shoes
.["head"] = head
.["mask"] = mask
.["neck"] = neck
.["ears"] = ears
.["glasses"] = glasses
.["id"] = id
.["l_pocket"] = l_pocket
.["r_pocket"] = r_pocket
.["suit_store"] = suit_store
.["r_hand"] = r_hand
.["l_hand"] = l_hand
.["internals_slot"] = internals_slot
.["backpack_contents"] = backpack_contents
.["box"] = box
.["implants"] = implants
.["accessory"] = accessory
/// Prompt the passed in mob client to download this outfit as a json blob
/datum/outfit/proc/save_to_file(mob/admin)
var/stored_data = get_json_data()
var/json = json_encode(stored_data)
//Kinda annoying but as far as i can tell you need to make actual file.
var/f = file("data/TempOutfitUpload")
fdel(f)
WRITE_FILE(f,json)
admin << ftp(f,"[name].json")
/// Create an outfit datum from a list of json data
/datum/outfit/proc/load_from(list/outfit_data)
//This could probably use more strict validation
name = outfit_data["name"]
uniform = text2path(outfit_data["uniform"])
suit = text2path(outfit_data["suit"])
toggle_helmet = outfit_data["toggle_helmet"]
back = text2path(outfit_data["back"])
belt = text2path(outfit_data["belt"])
gloves = text2path(outfit_data["gloves"])
shoes = text2path(outfit_data["shoes"])
head = text2path(outfit_data["head"])
mask = text2path(outfit_data["mask"])
neck = text2path(outfit_data["neck"])
ears = text2path(outfit_data["ears"])
glasses = text2path(outfit_data["glasses"])
id = text2path(outfit_data["id"])
l_pocket = text2path(outfit_data["l_pocket"])
r_pocket = text2path(outfit_data["r_pocket"])
suit_store = text2path(outfit_data["suit_store"])
r_hand = text2path(outfit_data["r_hand"])
l_hand = text2path(outfit_data["l_hand"])
internals_slot = outfit_data["internals_slot"]
var/list/backpack = outfit_data["backpack_contents"]
backpack_contents = list()
for(var/item in backpack)
var/itype = text2path(item)
if(itype)
backpack_contents[itype] = backpack[item]
box = text2path(outfit_data["box"])
var/list/impl = outfit_data["implants"]
implants = list()
for(var/I in impl)
var/imptype = text2path(I)
if(imptype)
implants += imptype
accessory = text2path(outfit_data["accessory"])
return TRUE
/datum/outfit/mulligan
name = "a Mulligan (Naked)"
/datum/outfit/mulligan/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
..()
var/mob/living/carbon/human/M = H
randomize_human(M)