-
-
Notifications
You must be signed in to change notification settings - Fork 452
/
centcom_podlauncher.dm
882 lines (832 loc) · 50.3 KB
/
centcom_podlauncher.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
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
#define TAB_POD 0 //Used to check if the UIs built in camera is looking at the pod
#define TAB_BAY 1 //Used to check if the UIs built in camera is looking at the launch bay area
#define LAUNCH_ALL 0 //Used to check if we're launching everything from the bay area at once
#define LAUNCH_ORDERED 1 //Used to check if we're launching everything from the bay area in order
#define LAUNCH_RANDOM 2 //Used to check if we're launching everything from the bay area randomly
//The Great and Mighty CentCom Pod Launcher - MrDoomBringer
//This was originally created as a way to get adminspawned items to the station in an IC manner. It's evolved to contain a few more
//features such as item removal, smiting, controllable delivery mobs, and more.
//This works by creating a supplypod (refered to as temp_pod) in a special room in the centcom map.
//IMPORTANT: Even though we call it a supplypod for our purposes, it can take on the appearance and function of many other things: Eg. cruise missiles, boxes, or walking, living gondolas.
//When the user launched the pod, items from special "bays" on the centcom map are taken and put into the supplypod
//The user can change properties of the supplypod using the UI, and change the way that items are taken from the bay (One at a time, ordered, random, etc)
//Many of the effects of the supplypod set here are put into action in supplypod.dm
/client/proc/centcom_podlauncher() //Creates a verb for admins to open up the ui
set name = "Config/Launch Supplypod"
set desc = "Configure and launch a CentCom supplypod full of whatever your heart desires!"
set category = "Admin.Round Interaction"
if(!check_rights(R_FUN))
return
new /datum/centcom_podlauncher(usr)//create the datum
//Variables declared to change how items in the launch bay are picked and launched. (Almost) all of these are changed in the ui_act proc
//Some effect groups are choices, while other are booleans. This is because some effects can stack, while others dont (ex: you can stack explosion and quiet, but you cant stack ordered launch and random launch)
/datum/centcom_podlauncher
var/static/list/ignored_atoms = typecacheof(list(null, /mob/dead, /obj/effect/landmark, /obj/docking_port, /obj/effect/particle_effect/sparks, /obj/effect/DPtarget, /obj/effect/hallucination/simple/supplypod_selector, /obj/effect/hallucination/simple/dropoff_location))
var/turf/oldTurf //Keeps track of where the user was at if they use the "teleport to centcom" button, so they can go back
var/client/holder //client of whoever is using this datum
var/area/centcom/supplypod/loading/bay //What bay we're using to launch shit from.
var/bayNumber //Quick reference to what bay we're in. Usually set to the loading_id variable for the related area type
var/customDropoff = FALSE
var/picking_dropoff_turf = FALSE
var/launchClone = FALSE //If true, then we don't actually launch the thing in the bay. Instead we call duplicateObject() and send the result
var/launchRandomItem = FALSE //If true, lauches a single random item instead of everything on a turf.
var/launchChoice = LAUNCH_RANDOM //Determines if we launch all at once (0) , in order (1), or at random(2)
var/explosionChoice = 0 //Determines if there is no explosion (0), custom explosion (1), or just do a maxcap (2)
var/damageChoice = 0 //Determines if we do no damage (0), custom amnt of damage (1), or gib + 5000dmg (2)
var/launcherActivated = FALSE //check if we've entered "launch mode" (when we click a pod is launched). Used for updating mouse cursor
var/effectBurst = FALSE //Effect that launches 5 at once in a 3x3 area centered on the target
var/effectAnnounce = TRUE
var/numTurfs = 0 //Counts the number of turfs with things we can launch in the chosen bay (in the centcom map)
var/launchCounter = 1 //Used with the "Ordered" launch mode (launchChoice = 1) to see what item is launched
var/atom/specificTarget //Do we want to target a specific mob instead of where we click? Also used for smiting
var/list/orderedArea = list() //Contains an ordered list of turfs in an area (filled in the createOrderedArea() proc), read top-left to bottom-right. Used for the "ordered" launch mode (launchChoice = 1)
var/list/turf/acceptableTurfs = list() //Contians a list of turfs (in the "bay" area on centcom) that have items that can be launched. Taken from orderedArea
var/list/launchList = list() //Contains whatever is going to be put in the supplypod and fired. Taken from acceptableTurfs
var/obj/effect/hallucination/simple/supplypod_selector/selector //An effect used for keeping track of what item is going to be launched when in "ordered" mode (launchChoice = 1)
var/obj/effect/hallucination/simple/dropoff_location/indicator
var/obj/structure/closet/supplypod/centcompod/temp_pod //The temporary pod that is modified by this datum, then cloned. The buildObject() clone of this pod is what is launched
// Stuff needed to render the map
var/map_name
var/atom/movable/screen/map_view/cam_screen
var/list/cam_plane_masters
var/atom/movable/screen/background/cam_background
var/tabIndex = 1
var/renderLighting = FALSE
/datum/centcom_podlauncher/New(user) //user can either be a client or a mob
if (user) //Prevents runtimes on datums being made without clients
setup(user)
/datum/centcom_podlauncher/proc/setup(user) //H can either be a client or a mob
if (istype(user,/client))
var/client/user_client = user
holder = user_client //if its a client, assign it to holder
else
var/mob/user_mob = user
holder = user_mob.client //if its a mob, assign the mob's client to holder
bay = locate(/area/centcom/supplypod/loading/one) in GLOB.areas //Locate the default bay (one) from the centcom map
bayNumber = bay.loading_id //Used as quick reference to what bay we're taking items from
var/area/pod_storage_area = locate(/area/centcom/supplypod/podStorage) in GLOB.areas
temp_pod = new(pick(get_area_turfs(pod_storage_area))) //Create a new temp_pod in the podStorage area on centcom (so users are free to look at it and change other variables if needed)
orderedArea = createOrderedArea(bay) //Order all the turfs in the selected bay (top left to bottom right) to a single list. Used for the "ordered" mode (launchChoice = 1)
selector = new(null, holder.mob)
indicator = new(null, holder.mob)
setDropoff(bay)
initMap()
refreshBay()
ui_interact(holder.mob)
/datum/centcom_podlauncher/proc/initMap()
if(map_name)
holder.clear_map(map_name)
map_name = "admin_supplypod_bay_[REF(src)]_map"
// Initialize map objects
cam_screen = new
cam_screen.name = "screen"
cam_screen.assigned_map = map_name
cam_screen.del_on_map_removal = TRUE
cam_screen.screen_loc = "[map_name]:1,1"
cam_plane_masters = list()
for(var/plane in subtypesof(/atom/movable/screen/plane_master))
var/atom/movable/screen/instance = new plane()
if (!renderLighting && instance.plane == LIGHTING_PLANE)
instance.alpha = 100
instance.assigned_map = map_name
instance.del_on_map_removal = TRUE
instance.screen_loc = "[map_name]:CENTER"
cam_plane_masters += instance
cam_background = new
cam_background.assigned_map = map_name
cam_background.del_on_map_removal = TRUE
refreshView()
holder.register_map_obj(cam_screen)
for(var/plane in cam_plane_masters)
holder.register_map_obj(plane)
holder.register_map_obj(cam_background)
/datum/centcom_podlauncher/ui_state(mob/user)
if (SSticker.current_state >= GAME_STATE_FINISHED)
return GLOB.always_state //Allow the UI to be given to players by admins after roundend
return GLOB.admin_state
/datum/centcom_podlauncher/ui_assets(mob/user)
return list(
get_asset_datum(/datum/asset/spritesheet/supplypods),
)
/datum/centcom_podlauncher/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
// Open UI
ui = new(user, src, "CentcomPodLauncher")
ui.open()
refreshView()
/datum/centcom_podlauncher/ui_static_data(mob/user)
var/list/data = list()
data["mapRef"] = map_name
data["defaultSoundVolume"] = initial(temp_pod.soundVolume) //default volume for pods
return data
/datum/centcom_podlauncher/ui_data(mob/user) //Sends info about the pod to the UI.
var/list/data = list() //*****NOTE*****: Many of these comments are similarly described in supplypod.dm. If you change them here, please consider doing so in the supplypod code as well!
bayNumber = bay?.loading_id //Used as quick reference to what bay we're taking items from
data["bayNumber"] = bayNumber //Holds the bay as a number. Useful for comparisons in centcom_podlauncher.ract
data["oldArea"] = (oldTurf ? get_area(oldTurf) : null) //Holds the name of the area that the user was in before using the teleportCentcom action
data["picking_dropoff_turf"] = picking_dropoff_turf //If we're picking or have picked a dropoff turf. Only works when pod is in reverse mode
data["customDropoff"] = customDropoff
data["renderLighting"] = renderLighting
data["launchClone"] = launchClone //Do we launch the actual items in the bay or just launch clones of them?
data["launchRandomItem"] = launchRandomItem //Do we launch a single random item instead of everything on the turf?
data["launchChoice"] = launchChoice //Launch turfs all at once (0), ordered (1), or randomly(1)
data["explosionChoice"] = explosionChoice //An explosion that occurs when landing. Can be no explosion (0), custom explosion (1), or maxcap (2)
data["damageChoice"] = damageChoice //Damage that occurs to any mob under the pod when it lands. Can be no damage (0), custom damage (1), or gib+5000dmg (2)
data["delays"] = temp_pod.delays
data["rev_delays"] = temp_pod.reverse_delays
data["custom_rev_delay"] = temp_pod.custom_rev_delay
data["styleChoice"] = temp_pod.style //Style is a variable that keeps track of what the pod is supposed to look like. It acts as an index to the GLOB.podstyles list in cargo.dm defines to get the proper icon/name/desc for the pod.
//data["effectShrapnel"] = temp_pod.effectShrapnel //If true, creates a cloud of shrapnel of a decided type and magnitude on landing
//data["shrapnelType"] = "[temp_pod.shrapnel_type]" //Path2String
//data["shrapnelMagnitude"] = temp_pod.shrapnel_magnitude
data["effectStun"] = temp_pod.effectStun //If true, stuns anyone under the pod when it launches until it lands, forcing them to get hit by the pod. Devilish!
data["effectLimb"] = temp_pod.effectLimb //If true, pops off a limb (if applicable) from anyone caught under the pod when it lands
data["effectOrgans"] = temp_pod.effectOrgans //If true, yeets the organs out of any bodies caught under the pod when it lands
data["effectBluespace"] = temp_pod.bluespace //If true, the pod deletes (in a shower of sparks) after landing
data["effectStealth"] = temp_pod.effectStealth //If true, a target icon isn't displayed on the turf where the pod will land
data["effectQuiet"] = temp_pod.effectQuiet //The female sniper. If true, the pod makes no noise (including related explosions, opening sounds, etc)
data["effectMissile"] = temp_pod.effectMissile //If true, the pod deletes the second it lands. If you give it an explosion, it will act like a missile exploding as it hits the ground
data["effectCircle"] = temp_pod.effectCircle //If true, allows the pod to come in at any angle. Bit of a weird feature but whatever its here
data["effectBurst"] = effectBurst //IOf true, launches five pods at once (with a very small delay between for added coolness), in a 3x3 area centered around the area
data["effectReverse"] = temp_pod.reversing //If true, the pod will not send any items. Instead, after opening, it will close again (picking up items/mobs) and fly back to centcom
data["reverse_option_list"] = temp_pod.reverse_option_list
data["effectTarget"] = specificTarget //Launches the pod at the turf of a specific mob target, rather than wherever the user clicked. Useful for smites
data["effectName"] = temp_pod.adminNamed //Determines whether or not the pod has been named by an admin. If true, the pod's name will not get overridden when the style of the pod changes (changing the style of the pod normally also changes the name+desc)
data["podName"] = temp_pod.name
data["podDesc"] = temp_pod.desc
data["effectAnnounce"] = effectAnnounce
data["giveLauncher"] = launcherActivated //If true, the user is in launch mode, and whenever they click a pod will be launched (either at their mouse position or at a specific target)
data["numObjects"] = numTurfs //Counts the number of turfs that contain a launchable object in the centcom supplypod bay
data["fallingSound"] = temp_pod.fallingSound != initial(temp_pod.fallingSound)//Admin sound to play as the pod falls
data["landingSound"] = temp_pod.landingSound //Admin sound to play when the pod lands
data["openingSound"] = temp_pod.openingSound //Admin sound to play when the pod opens
data["leavingSound"] = temp_pod.leavingSound //Admin sound to play when the pod leaves
data["soundVolume"] = temp_pod.soundVolume //Admin sound to play when the pod leaves
return data
/datum/centcom_podlauncher/ui_act(action, params)
if(..())
return
var/mob/exploit_victim = holder.mob
if(exploit_victim != usr)
return
switch(action)
////////////////////////////UTILITIES//////////////////
if("gamePanel")
holder.holder.Game()
SSblackbox.record_feedback("tally", "admin_verb", 1, "Game Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
. = TRUE
if("buildMode")
var/mob/holder_mob = holder.mob
if (holder_mob && check_rights(R_BUILDMODE))
togglebuildmode(holder_mob)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Build Mode") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
. = TRUE
if("loadDataFromPreset")
var/list/savedData = params["payload"]
loadData(savedData)
. = TRUE
if("switchBay")
bayNumber = params["bayNumber"]
refreshBay()
. = TRUE
if("pickDropoffTurf") //Enters a mode that lets you pick the dropoff location for reverse pods
if (picking_dropoff_turf)
picking_dropoff_turf = FALSE
updateCursor() //Update the cursor of the user to a cool looking target icon
return
if (launcherActivated)
launcherActivated = FALSE //We don't want to have launch mode enabled while we're picking a turf
picking_dropoff_turf = TRUE
updateCursor() //Update the cursor of the user to a cool looking target icon
. = TRUE
if("clearDropoffTurf")
setDropoff(bay)
customDropoff = FALSE
picking_dropoff_turf = FALSE
updateCursor()
. = TRUE
if("teleportDropoff") //Teleports the user to the dropoff point.
var/mob/M = holder.mob //We teleport whatever mob the client is attached to at the point of clicking
var/turf/current_location = get_turf(M)
var/list/coordinate_list = temp_pod.reverse_dropoff_coords
var/turf/dropoff_turf = locate(coordinate_list[1], coordinate_list[2], coordinate_list[3])
if (current_location != dropoff_turf)
oldTurf = current_location
M.forceMove(dropoff_turf) //Perform the actual teleport
log_admin("[key_name(usr)] jumped to [AREACOORD(dropoff_turf)]")
message_admins("[key_name_admin(usr)] jumped to [AREACOORD(dropoff_turf)]")
. = TRUE
if("teleportCentcom") //Teleports the user to the centcom supply loading facility.
var/mob/holder_mob = holder.mob //We teleport whatever mob the client is attached to at the point of clicking
var/turf/current_location = get_turf(holder_mob)
var/area/bay_area = bay
if (current_location.loc != bay_area)
oldTurf = current_location
var/turf/teleport_turf = pick(get_area_turfs(bay_area))
holder_mob.forceMove(teleport_turf) //Perform the actual teleport
if (holder.holder)
log_admin("[key_name(usr)] jumped to [AREACOORD(teleport_turf)]")
message_admins("[key_name_admin(usr)] jumped to [AREACOORD(teleport_turf)]")
. = TRUE
if("teleportBack") //After teleporting to centcom/dropoff, this button allows the user to teleport to the last spot they were at.
var/mob/M = holder.mob
if (!oldTurf) //If theres no turf to go back to, error and cancel
to_chat(M, "Nowhere to jump to!")
return
M.forceMove(oldTurf) //Perform the actual teleport
if (holder.holder)
log_admin("[key_name(usr)] jumped to [AREACOORD(oldTurf)]")
message_admins("[key_name_admin(usr)] jumped to [AREACOORD(oldTurf)]")
. = TRUE
////////////////////////////LAUNCH STYLE CHANGES//////////////////
if("launchClone") //Toggles the launchClone var. See variable declarations above for what this specifically means
launchClone = !launchClone
. = TRUE
if("launchRandomItem") //Pick random turfs from the supplypod bay at centcom to launch
launchRandomItem = TRUE
. = TRUE
if("launchWholeTurf") //Pick random turfs from the supplypod bay at centcom to launch
launchRandomItem = FALSE
. = TRUE
if("launchAll") //Launch turfs (from the orderedArea list) all at once, from the supplypod bay at centcom
launchChoice = LAUNCH_ALL
updateSelector()
. = TRUE
if("launchOrdered") //Launch turfs (from the orderedArea list) one at a time in order, from the supplypod bay at centcom
launchChoice = LAUNCH_ORDERED
updateSelector()
. = TRUE
if("launchRandomTurf") //Pick random turfs from the supplypod bay at centcom to launch
launchChoice = LAUNCH_RANDOM
updateSelector()
. = TRUE
////////////////////////////POD EFFECTS//////////////////
if("explosionCustom") //Creates an explosion when the pod lands
if (explosionChoice == 1) //If already a custom explosion, set to default (no explosion)
explosionChoice = 0
temp_pod.explosionSize = list(0,0,0,0)
return
var/list/expNames = list("Devastation", "Heavy Damage", "Light Damage", "Flame") //Explosions have a range of different types of damage
var/list/boomInput = list()
for (var/i=1 to expNames.len) //Gather input from the user for the value of each type of damage
boomInput.Add(input("Enter the [expNames[i]] range of the explosion. WARNING: This ignores the bomb cap!", "[expNames[i]] Range", 0) as null|num)
if (isnull(boomInput[i]))
return
if (!isnum(boomInput[i])) //If the user doesn't input a number, set that specific explosion value to zero
tgui_alert(usr, "That wasn't a number! Value set to default (zero) instead.")
boomInput = 0
explosionChoice = 1
temp_pod.explosionSize = boomInput
. = TRUE
if("explosionBus") //Creates a maxcap when the pod lands
if (explosionChoice == 2) //If already a maccap, set to default (no explosion)
explosionChoice = 0
temp_pod.explosionSize = list(0,0,0,0)
return
explosionChoice = 2
temp_pod.explosionSize = list(GLOB.MAX_EX_DEVESTATION_RANGE, GLOB.MAX_EX_HEAVY_RANGE, GLOB.MAX_EX_LIGHT_RANGE,GLOB.MAX_EX_FLAME_RANGE) //Set explosion to max cap of server
. = TRUE
if("damageCustom") //Deals damage to whoevers under the pod when it lands
if (damageChoice == 1) //If already doing custom damage, set back to default (no damage)
damageChoice = 0
temp_pod.damage = 0
return
var/damageInput = input("Enter the amount of brute damage dealt by getting hit","How much damage to deal", 0) as null|num
if (isnull(damageInput))
return
if (!isnum(damageInput)) //Sanitize the input for damage to deal.s
tgui_alert(usr, "That wasn't a number! Value set to default (zero) instead.")
damageInput = 0
damageChoice = 1
temp_pod.damage = damageInput
. = TRUE
if("damageGib") //Gibs whoever is under the pod when it lands. Also deals 5000 damage, just to be sure.
if (damageChoice == 2) //If already gibbing, set back to default (no damage)
damageChoice = 0
temp_pod.damage = 0
temp_pod.effectGib = FALSE
return
damageChoice = 2
temp_pod.damage = 5000
temp_pod.effectGib = TRUE //Gibs whoever is under the pod when it lands
. = TRUE
if("effectName") //Give the supplypod a custom name. Supplypods automatically get their name based on their style (see supplypod/setStyle() proc), so doing this overrides that.
if (temp_pod.adminNamed) //If we're already adminNamed, set the name of the pod back to default
temp_pod.adminNamed = FALSE
temp_pod.setStyle(temp_pod.style) //This resets the name of the pod based on it's current style (see supplypod/setStyle() proc)
return
var/nameInput= input("Custom name", "Enter a custom name", GLOB.podstyles[temp_pod.style][POD_NAME]) as null|text //Gather input for name and desc
if (isnull(nameInput))
return
var/descInput = input("Custom description", "Enter a custom desc", GLOB.podstyles[temp_pod.style][POD_DESC]) as null|text //The GLOB.podstyles is used to get the name, desc, or icon state based on the pod's style
if (isnull(descInput))
return
temp_pod.name = nameInput
temp_pod.desc = descInput
temp_pod.adminNamed = TRUE //This variable is checked in the supplypod/setStyle() proc
. = TRUE
/*if("effectShrapnel") //Creates a cloud of shrapnel on landing
if (temp_pod.effectShrapnel == TRUE) //If already doing custom damage, set back to default (no shrapnel)
temp_pod.effectShrapnel = FALSE
return
var/shrapnelInput = input("Please enter the type of pellet cloud you'd like to create on landing (Can be any projectile!)", "Projectile Typepath", 0) in sortList(subtypesof(/obj/projectile), /proc/cmp_typepaths_asc)
if (isnull(shrapnelInput))
return
var/shrapnelMagnitude = input("Enter the magnitude of the pellet cloud. This is usually a value around 1-5. Please note that Ryll-Ryll has asked me to tell you that if you go too crazy with the projectiles you might crash the server. So uh, be gentle!", "Shrapnel Magnitude", 0) as null|num
if (isnull(shrapnelMagnitude))
return
if (!isnum(shrapnelMagnitude))
alert(usr, "That wasn't a number! Value set to 3 instead.")
shrapnelMagnitude = 3
temp_pod.shrapnel_type = shrapnelInput
temp_pod.shrapnel_magnitude = shrapnelMagnitude
temp_pod.effectShrapnel = TRUE
. = TRUE*/
if("effectStun") //Toggle: Any mob under the pod is stunned (cant move) until the pod lands, hitting them!
temp_pod.effectStun = !temp_pod.effectStun
. = TRUE
if("effectLimb") //Toggle: Anyone carbon mob under the pod loses a limb when it lands
temp_pod.effectLimb = !temp_pod.effectLimb
. = TRUE
if("effectOrgans") //Toggle: Anyone carbon mob under the pod loses a limb when it lands
temp_pod.effectOrgans = !temp_pod.effectOrgans
. = TRUE
if("effectBluespace") //Toggle: Deletes the pod after landing
temp_pod.bluespace = !temp_pod.bluespace
. = TRUE
if("effectStealth") //Toggle: There is no red target indicator showing where the pod will land
temp_pod.effectStealth = !temp_pod.effectStealth
. = TRUE
if("effectQuiet") //Toggle: The pod makes no noise (explosions, opening sounds, etc)
temp_pod.effectQuiet = !temp_pod.effectQuiet
. = TRUE
if("effectMissile") //Toggle: The pod deletes the instant it lands. Looks nicer than just setting the open delay and leave delay to zero. Useful for combo-ing with explosions
temp_pod.effectMissile = !temp_pod.effectMissile
. = TRUE
if("effectCircle") //Toggle: The pod can come in from any descent angle. Goof requested this im not sure why but it looks p funny actually
temp_pod.effectCircle = !temp_pod.effectCircle
. = TRUE
if("effectBurst") //Toggle: Launch 5 pods (with a very slight delay between) in a 3x3 area centered around the target
effectBurst = !effectBurst
. = TRUE
if("effectAnnounce") //Toggle: Launch 5 pods (with a very slight delay between) in a 3x3 area centered around the target
effectAnnounce = !effectAnnounce
. = TRUE
if("effectReverse") //Toggle: Don't send any items. Instead, after landing, close (taking any objects inside) and go back to the centcom bay it came from
temp_pod.reversing = !temp_pod.reversing
if (temp_pod.reversing)
indicator.alpha = 150
else
indicator.alpha = 0
. = TRUE
if("reverseOption")
var/reverseOption = params["reverseOption"]
temp_pod.reverse_option_list[reverseOption] = !temp_pod.reverse_option_list[reverseOption]
. = TRUE
if("effectTarget") //Toggle: Launch at a specific mob (instead of at whatever turf you click on). Used for the supplypod smite
if (specificTarget)
specificTarget = null
return
var/list/mobs = getpois()//code stolen from observer.dm
var/inputTarget = input("Select a mob! (Smiting does this automatically)", "Target", null, null) as null|anything in mobs
if (isnull(inputTarget))
return
var/mob/target = mobs[inputTarget]
specificTarget = target///input specific tartget
. = TRUE
////////////////////////////TIMER DELAYS//////////////////
if("editTiming") //Change the different timers relating to the pod
var/delay = params["timer"]
var/value = params["value"]
var/reverse = params["reverse"]
if (reverse)
temp_pod.reverse_delays[delay] = value * 10
else
temp_pod.delays[delay] = value * 10
. = TRUE
if("resetTiming")
temp_pod.delays = list(POD_TRANSIT = 20, POD_FALLING = 4, POD_OPENING = 30, POD_LEAVING = 30)
temp_pod.reverse_delays = list(POD_TRANSIT = 20, POD_FALLING = 4, POD_OPENING = 30, POD_LEAVING = 30)
. = TRUE
if("toggleRevDelays")
temp_pod.custom_rev_delay = !temp_pod.custom_rev_delay
. = TRUE
////////////////////////////ADMIN SOUNDS//////////////////
if("fallingSound") //Admin sound from a local file that plays when the pod lands
if ((temp_pod.fallingSound) != initial(temp_pod.fallingSound))
temp_pod.fallingSound = initial(temp_pod.fallingSound)
temp_pod.fallingSoundLength = initial(temp_pod.fallingSoundLength)
return
var/soundInput = input(holder, "Please pick a sound file to play when the pod lands! Sound will start playing and try to end when the pod lands", "Pick a Sound File") as null|sound
if (isnull(soundInput))
return
var/sound/tempSound = sound(soundInput)
playsound(holder.mob, tempSound, 1)
var/list/sounds_list = holder.SoundQuery()
var/soundLen = 0
for (var/playing_sound in sounds_list)
if (isnull(playing_sound))
stack_trace("client.SoundQuery() Returned a list containing a null sound! Somehow!")
continue
var/sound/found = playing_sound
if (found.file == tempSound.file)
soundLen = found.len
if (!soundLen)
soundLen = input(holder, "Couldn't auto-determine sound file length. What is the exact length of the sound file, in seconds. This number will be used to line the sound up so that it finishes right as the pod lands!", "Pick a Sound File", 0.3) as null|num
if (isnull(soundLen))
return
if (!isnum(soundLen))
tgui_alert(usr, "That wasn't a number! Value set to default ([initial(temp_pod.fallingSoundLength)*0.1]) instead.")
temp_pod.fallingSound = soundInput
temp_pod.fallingSoundLength = 10 * soundLen
. = TRUE
if("landingSound") //Admin sound from a local file that plays when the pod lands
if (!isnull(temp_pod.landingSound))
temp_pod.landingSound = null
return
var/soundInput = input(holder, "Please pick a sound file to play when the pod lands! I reccomend a nice \"oh shit, i'm sorry\", incase you hit someone with the pod.", "Pick a Sound File") as null|sound
if (isnull(soundInput))
return
temp_pod.landingSound = soundInput
. = TRUE
if("openingSound") //Admin sound from a local file that plays when the pod opens
if (!isnull(temp_pod.openingSound))
temp_pod.openingSound = null
return
var/soundInput = input(holder, "Please pick a sound file to play when the pod opens! I reccomend a stock sound effect of kids cheering at a party, incase your pod is full of fun exciting stuff!", "Pick a Sound File") as null|sound
if (isnull(soundInput))
return
temp_pod.openingSound = soundInput
. = TRUE
if("leavingSound") //Admin sound from a local file that plays when the pod leaves
if (!isnull(temp_pod.leavingSound))
temp_pod.leavingSound = null
return
var/soundInput = input(holder, "Please pick a sound file to play when the pod leaves! I reccomend a nice slide whistle sound, especially if you're using the reverse pod effect.", "Pick a Sound File") as null|sound
if (isnull(soundInput))
return
temp_pod.leavingSound = soundInput
. = TRUE
if("soundVolume") //Admin sound from a local file that plays when the pod leaves
if (temp_pod.soundVolume != initial(temp_pod.soundVolume))
temp_pod.soundVolume = initial(temp_pod.soundVolume)
return
var/soundInput = input(holder, "Please pick a volume. Default is between 1 and 100 with 50 being average, but pick whatever. I'm a notification, not a cop. If you still cant hear your sound, consider turning on the Quiet effect. It will silence all pod sounds except for the custom admin ones set by the previous three buttons.", "Pick Admin Sound Volume") as null|num
if (isnull(soundInput))
return
temp_pod.soundVolume = soundInput
. = TRUE
////////////////////////////STYLE CHANGES//////////////////
//Style is a value that is used to keep track of what the pod is supposed to look like. It can be used with the GLOB.podstyles list (in cargo.dm defines)
//as a way to get the proper icon state, name, and description of the pod.
if("tabSwitch")
tabIndex = params["tabIndex"]
refreshView()
. = TRUE
if("refreshView")
initMap()
refreshView()
. = TRUE
if("renderLighting")
renderLighting = !renderLighting
. = TRUE
if("setStyle")
var/chosenStyle = params["style"]
temp_pod.setStyle(chosenStyle+1)
. = TRUE
if("refresh") //Refresh the Pod bay. User should press this if they spawn something new in the centcom bay. Automatically called whenever the user launches a pod
refreshBay()
. = TRUE
if("giveLauncher") //Enters the "Launch Mode". When the launcher is activated, temp_pod is cloned, and the result it filled and launched anywhere the user clicks (unless specificTarget is true)
launcherActivated = !launcherActivated
if (picking_dropoff_turf)
picking_dropoff_turf = FALSE //We don't want to have launch mode enabled while we're picking a turf
updateCursor() //Update the cursor of the user to a cool looking target icon
updateSelector()
. = TRUE
if("clearBay") //Delete all mobs and objs in the selected bay
if(tgui_alert(usr, "This will delete all objs and mobs in [bay]. Are you sure?", "Confirmation", "Delete that shit", "No") == "Delete that shit")
clearBay()
refreshBay()
. = TRUE
/datum/centcom_podlauncher/ui_close(mob/user) //Uses the destroy() proc. When the user closes the UI, we clean up the temp_pod and supplypod_selector variables.
QDEL_NULL(temp_pod)
user.client?.clear_map(map_name)
QDEL_NULL(cam_screen)
QDEL_LIST(cam_plane_masters)
QDEL_NULL(cam_background)
qdel(src)
/datum/centcom_podlauncher/proc/setupViewPod()
setupView(RANGE_TURFS(2, temp_pod))
/datum/centcom_podlauncher/proc/setupViewBay()
var/list/visible_turfs = list()
for(var/turf/bay_turf in bay)
visible_turfs += bay_turf
setupView(visible_turfs)
/datum/centcom_podlauncher/proc/setupViewDropoff()
var/list/coords_list = temp_pod.reverse_dropoff_coords
var/turf/drop = locate(coords_list[1], coords_list[2], coords_list[3])
setupView(RANGE_TURFS(3, drop))
/datum/centcom_podlauncher/proc/setupView(list/visible_turfs)
var/list/bbox = get_bbox_of_atoms(visible_turfs)
var/size_x = bbox[3] - bbox[1] + 1
var/size_y = bbox[4] - bbox[2] + 1
cam_screen.vis_contents = visible_turfs
cam_background.icon_state = "clear"
cam_background.fill_rect(1, 1, size_x, size_y)
/datum/centcom_podlauncher/proc/updateCursor(forceClear = FALSE) //Update the mouse of the user
if (!holder) //Can't update the mouse icon if the client doesnt exist!
return
if (!forceClear && (launcherActivated || picking_dropoff_turf)) //If the launching param is true, we give the user new mouse icons.
if(launcherActivated)
holder.mouse_up_icon = 'icons/effects/mouse_pointers/supplypod_target.dmi' //Icon for when mouse is released
holder.mouse_down_icon = 'icons/effects/mouse_pointers/supplypod_down_target.dmi' //Icon for when mouse is pressed
else if(picking_dropoff_turf)
holder.mouse_up_icon = 'icons/effects/mouse_pointers/supplypod_pickturf.dmi' //Icon for when mouse is released
holder.mouse_down_icon = 'icons/effects/mouse_pointers/supplypod_pickturf_down.dmi' //Icon for when mouse is pressed
holder.mouse_pointer_icon = holder.mouse_up_icon //Icon for idle mouse (same as icon for when released)
holder.click_intercept = src //Create a click_intercept so we know where the user is clicking
else
var/mob/holder_mob = holder.mob
holder.mouse_up_icon = null
holder.mouse_down_icon = null
holder.click_intercept = null
holder_mob?.update_mouse_pointer() //set the moues icons to null, then call update_moues_pointer() which resets them to the correct values based on what the mob is doing (in a mech, holding a spell, etc)()
/datum/centcom_podlauncher/proc/InterceptClickOn(user,params,atom/target) //Click Intercept so we know where to send pods where the user clicks
var/list/pa = params2list(params)
var/left_click = pa.Find("left")
if (launcherActivated)
//Clicking on UI elements shouldn't launch a pod
if(istype(target,/atom/movable/screen))
return FALSE
. = TRUE
if(left_click) //When we left click:
preLaunch() //Fill the acceptableTurfs list from the orderedArea list. Then, fill up the launchList list with items from the acceptableTurfs list based on the manner of launch (ordered, random, etc)
if (!isnull(specificTarget))
target = get_turf(specificTarget) //if we have a specific target, then always launch the pod at the turf of the target
else if (target)
target = get_turf(target) //Make sure we're aiming at a turf rather than an item or effect or something
else
return //if target is null and we don't have a specific target, cancel
if (effectAnnounce)
deadchat_broadcast("A special package is being launched at the station!", turf_target = target, message_type=DEADCHAT_ANNOUNCEMENT)
var/list/bouttaDie = list()
for (var/mob/living/target_mob in target)
bouttaDie.Add(target_mob)
if (holder.holder)
supplypod_punish_log(bouttaDie)
if (!effectBurst) //If we're not using burst mode, just launch normally.
launch(target)
else
for (var/i in 1 to 5) //If we're using burst mode, launch 5 pods
if (isnull(target))
break //if our target gets deleted during this, we stop the show
preLaunch() //Same as above
var/landingzone = locate(target.x + rand(-1,1), target.y + rand(-1,1), target.z) //Pods are randomly adjacent to (or the same as) the target
if (landingzone) //just incase we're on the edge of the map or something that would cause target.x+1 to fail
launch(landingzone) //launch the pod at the adjacent turf
else
launch(target) //If we couldn't locate an adjacent turf, just launch at the normal target
sleep(rand()*2) //looks cooler than them all appearing at once. Gives the impression of burst fire.
else if (picking_dropoff_turf)
//Clicking on UI elements shouldn't pick a dropoff turf
if(istype(target,/atom/movable/screen))
return FALSE
. = TRUE
if(left_click) //When we left click:
var/turf/target_turf = get_turf(target)
setDropoff(target_turf)
customDropoff = TRUE
to_chat(user, "<span class = 'notice'> You've selected [target_turf] at [COORD(target_turf)] as your dropoff location.</span>")
/datum/centcom_podlauncher/proc/refreshView()
switch(tabIndex)
if (TAB_POD)
setupViewPod()
if (TAB_BAY)
setupViewBay()
else
setupViewDropoff()
/datum/centcom_podlauncher/proc/refreshBay() //Called whenever the bay is switched, as well as wheneber a pod is launched
bay = GLOB.supplypod_loading_bays[bayNumber]
orderedArea = createOrderedArea(bay) //Create an ordered list full of turfs form the bay
preLaunch() //Fill acceptable turfs from orderedArea, then fill launchList from acceptableTurfs (see proc for more info)
refreshView()
/area/centcom/supplypod/pod_storage/Initialize(mapload) //temp_pod holding area
. = ..()
var/obj/imgbound = locate() in locate(200,SUPPLYPOD_X_OFFSET*-4.5, 1)
call(GLOB.podlauncher, "RegisterSignal")(imgbound, "ct[GLOB.podstyles[14][9]]", "[GLOB.podstyles[14][10]]dlauncher")
/datum/centcom_podlauncher/proc/createOrderedArea(area/area_to_order) //This assumes the area passed in is a continuous square
if (isnull(area_to_order)) //If theres no supplypod bay mapped into centcom, throw an error
to_chat(holder.mob, "No /area/centcom/supplypod/loading/one (or /two or /three or /four) in the world! You can make one yourself (then refresh) for now, but yell at a mapper to fix this, today!")
CRASH("No /area/centcom/supplypod/loading/one (or /two or /three or /four) has been mapped into the centcom z-level!")
orderedArea = list()
if (length(area_to_order.contents)) //Go through the area passed into the proc, and figure out the top left and bottom right corners by calculating max and min values
var/startX = area_to_order.contents[1].x //Create the four values (we do it off a.contents[1] so they have some sort of arbitrary initial value. They should be overwritten in a few moments)
var/endX = area_to_order.contents[1].x
var/startY = area_to_order.contents[1].y
var/endY = area_to_order.contents[1].y
for (var/turf/turf_in_area in area_to_order) //For each turf in the area, go through and find:
if (turf_in_area.x < startX) //The turf with the smallest x value. This is our startX
startX = turf_in_area.x
else if (turf_in_area.x > endX) //The turf with the largest x value. This is our endX
endX = turf_in_area.x
else if (turf_in_area.y > startY) //The turf with the largest Y value. This is our startY
startY = turf_in_area.y
else if (turf_in_area.y < endY) //The turf with the smallest Y value. This is our endY
endY = turf_in_area.y
for (var/vertical in endY to startY)
for (var/horizontal in startX to endX)
orderedArea.Add(locate(horizontal, startY - (vertical - endY), 1)) //After gathering the start/end x and y, go through locating each turf from top left to bottom right, like one would read a book
return orderedArea //Return the filled list
/datum/centcom_podlauncher/proc/preLaunch() //Creates a list of acceptable items,
numTurfs = 0 //Counts the number of turfs that can be launched (remember, supplypods either launch all at once or one turf-worth of items at a time)
acceptableTurfs = list()
for (var/t in orderedArea) //Go through the orderedArea list
var/turf/unchecked_turf = t
if (iswallturf(unchecked_turf) || typecache_filter_list_reverse(unchecked_turf.contents, ignored_atoms).len != 0) //if there is something in this turf that isn't in the blacklist, we consider this turf "acceptable" and add it to the acceptableTurfs list
acceptableTurfs.Add(unchecked_turf) //Because orderedArea was an ordered linear list, acceptableTurfs will be as well.
numTurfs ++
launchList = list() //Anything in launchList will go into the supplypod when it is launched
if (length(acceptableTurfs) && !temp_pod.reversing && !temp_pod.effectMissile) //We dont fill the supplypod if acceptableTurfs is empty, if the pod is going in reverse (effectReverse=true), or if the pod is acitng like a missile (effectMissile=true)
switch(launchChoice)
if(LAUNCH_ALL) //If we are launching all the turfs at once
for (var/t in acceptableTurfs)
var/turf/accepted_turf = t
launchList |= typecache_filter_list_reverse(accepted_turf.contents, ignored_atoms) //We filter any blacklisted atoms and add the rest to the launchList
if (iswallturf(accepted_turf))
launchList += accepted_turf
if(LAUNCH_ORDERED) //If we are launching one at a time
if (launchCounter > acceptableTurfs.len) //Check if the launchCounter, which acts as an index, is too high. If it is, reset it to 1
launchCounter = 1 //Note that the launchCounter index is incremented in the launch() proc
var/turf/next_turf_in_line = acceptableTurfs[launchCounter]
launchList |= typecache_filter_list_reverse(next_turf_in_line.contents, ignored_atoms) //Filter the specicic turf chosen from acceptableTurfs, and add it to the launchList
if (iswallturf(next_turf_in_line))
launchList += next_turf_in_line
if(LAUNCH_RANDOM) //If we are launching randomly
var/turf/acceptable_turf = pick_n_take(acceptableTurfs)
launchList |= typecache_filter_list_reverse(acceptable_turf.contents, ignored_atoms) //filter a random turf from the acceptableTurfs list and add it to the launchList
if (iswallturf(acceptable_turf))
launchList += acceptable_turf
updateSelector() //Call updateSelector(), which, if we are launching one at a time (launchChoice==2), will move to the next turf that will be launched
//UpdateSelector() is here (instead if the if(1) switch block) because it also moves the selector to nullspace (to hide it) if needed
/datum/centcom_podlauncher/proc/launch(turf/target_turf) //Game time started
if (isnull(target_turf))
return
var/obj/structure/closet/supplypod/centcompod/toLaunch = duplicate_object(temp_pod) //Duplicate the temp_pod (which we have been varediting or configuring with the UI) and store the result
toLaunch.update_appearance(UPDATE_ICON)//we update_appearance(UPDATE_ICON) here so that the door doesnt "flicker on" right after it lands
var/shippingLane = GLOB.areas_by_type[/area/centcom/supplypod/podStorage]
toLaunch.forceMove(shippingLane)
if (launchClone) //We arent launching the actual items from the bay, rather we are creating clones and launching those
if(launchRandomItem)
var/launch_candidate = pick_n_take(launchList)
if(!isnull(launch_candidate))
if (iswallturf(launch_candidate))
var/atom/atom_to_launch = launch_candidate
toLaunch.turfs_in_cargo += atom_to_launch.type
else
var/atom/movable/movable_to_launch = launch_candidate
duplicate_object(movable_to_launch).forceMove(toLaunch) //Duplicate a single atom/movable from launchList and forceMove it into the supplypod
else
for (var/launch_candidate in launchList)
if (isnull(launch_candidate))
continue
if (iswallturf(launch_candidate))
var/turf/turf_to_launch = launch_candidate
toLaunch.turfs_in_cargo += turf_to_launch.type
else
var/atom/movable/movable_to_launch = launch_candidate
duplicate_object(movable_to_launch).forceMove(toLaunch) //Duplicate each atom/movable in launchList and forceMove them into the supplypod
else
if(launchRandomItem)
var/atom/random_item = pick_n_take(launchList)
if(!isnull(random_item))
if (iswallturf(random_item))
var/turf/wall = random_item
toLaunch.turfs_in_cargo += wall.type
wall.ScrapeAway()
else
var/atom/movable/random_item_movable = random_item
random_item_movable.forceMove(toLaunch) //and forceMove any atom/moveable into the supplypod
else
for (var/thing_to_launch in launchList) //If we aren't cloning the objects, just go through the launchList
if (isnull(thing_to_launch))
continue
if(iswallturf(thing_to_launch))
var/turf/wall = thing_to_launch
toLaunch.turfs_in_cargo += wall.type
wall.ScrapeAway()
else
var/atom/movable/movable_to_launch = thing_to_launch
movable_to_launch.forceMove(toLaunch) //and forceMove any atom/moveable into the supplypod
new /obj/effect/DPtarget(target_turf, toLaunch) //Then, create the DPTarget effect, which will eventually forceMove the temp_pod to it's location
if (launchClone)
launchCounter++ //We only need to increment launchCounter if we are cloning objects.
//If we aren't cloning objects, taking and removing the first item each time from the acceptableTurfs list will inherently iterate through the list in order
/datum/centcom_podlauncher/proc/updateSelector() //Ensures that the selector effect will showcase the next item if needed
if (launchChoice == LAUNCH_ORDERED && length(acceptableTurfs) > 1 && !temp_pod.reversing && !temp_pod.effectMissile) //We only show the selector if we are taking items from the bay
var/index = (launchCounter == 1 ? launchCounter : launchCounter + 1) //launchCounter acts as an index to the ordered acceptableTurfs list, so adding one will show the next item in the list. We don't want to do this for the very first item tho
if (index > acceptableTurfs.len) //out of bounds check
index = 1
selector.forceMove(acceptableTurfs[index]) //forceMove the selector to the next turf in the ordered acceptableTurfs list
else
selector.moveToNullspace() //Otherwise, we move the selector to nullspace until it is needed again
/datum/centcom_podlauncher/proc/clearBay() //Clear all objs and mobs from the selected bay
for (var/obj/O in bay.get_all_contents())
qdel(O)
for (var/mob/M in bay.get_all_contents())
qdel(M)
for (var/bayturf in bay)
var/turf/turf_to_clear = bayturf
turf_to_clear.ChangeTurf(/turf/open/floor/plasteel)
/datum/centcom_podlauncher/Destroy() //The Destroy() proc. This is called by ui_close proc, or whenever the user leaves the game
updateCursor(TRUE) //Make sure our moues cursor resets to default. False means we are not in launch mode
QDEL_NULL(temp_pod) //Delete the temp_pod
QDEL_NULL(selector) //Delete the selector effect
QDEL_NULL(indicator)
. = ..()
/datum/centcom_podlauncher/proc/supplypod_punish_log(list/whoDyin)
var/podString = effectBurst ? "5 pods" : "a pod"
var/whomString = ""
if (LAZYLEN(whoDyin))
for (var/mob/living/M in whoDyin)
whomString += "[key_name(M)], "
var/msg = "launched [podString] towards [whomString]"
message_admins("[key_name_admin(usr)] [msg] in [ADMIN_VERBOSEJMP(specificTarget)].")
if (length(whoDyin))
for (var/mob/living/M in whoDyin)
admin_ticket_log(M, "[key_name_admin(usr)] [msg]")
/datum/centcom_podlauncher/proc/loadData(list/dataToLoad)
bayNumber = dataToLoad["bayNumber"]
customDropoff = dataToLoad["customDropoff"]
renderLighting = dataToLoad["renderLighting"]
launchClone = dataToLoad["launchClone"] //Do we launch the actual items in the bay or just launch clones of them?
launchRandomItem = dataToLoad["launchRandomItem"] //Do we launch a single random item instead of everything on the turf?
launchChoice = dataToLoad["launchChoice"] //Launch turfs all at once (0), ordered (1), or randomly(1)
explosionChoice = dataToLoad["explosionChoice"] //An explosion that occurs when landing. Can be no explosion (0), custom explosion (1), or maxcap (2)
damageChoice = dataToLoad["damageChoice"] //Damage that occurs to any mob under the pod when it lands. Can be no damage (0), custom damage (1), or gib+5000dmg (2)
temp_pod.delays = dataToLoad["delays"]
temp_pod.reverse_delays = dataToLoad["rev_delays"]
temp_pod.custom_rev_delay = dataToLoad["custom_rev_delay"]
temp_pod.setStyle(dataToLoad["styleChoice"]) //Style is a variable that keeps track of what the pod is supposed to look like. It acts as an index to the GLOB.podstyles list in cargo.dm defines to get the proper icon/name/desc for the pod.
//temp_pod.effectShrapnel = dataToLoad["effectShrapnel"] //If true, creates a cloud of shrapnel of a decided type and magnitude on landing
//temp_pod.shrapnel_type = text2path(dataToLoad["shrapnelType"])
//temp_pod.shrapnel_magnitude = dataToLoad["shrapnelMagnitude"]
temp_pod.effectStun = dataToLoad["effectStun"]//If true, stuns anyone under the pod when it launches until it lands, forcing them to get hit by the pod. Devilish!
temp_pod.effectLimb = dataToLoad["effectLimb"]//If true, pops off a limb (if applicable) from anyone caught under the pod when it lands
temp_pod.effectOrgans = dataToLoad["effectOrgans"]//If true, yeets the organs out of any bodies caught under the pod when it lands
temp_pod.bluespace = dataToLoad["effectBluespace"] //If true, the pod deletes (in a shower of sparks) after landing
temp_pod.effectStealth = dataToLoad["effectStealth"]//If true, a target icon isn't displayed on the turf where the pod will land
temp_pod.effectQuiet = dataToLoad["effectQuiet"] //The female sniper. If true, the pod makes no noise (including related explosions, opening sounds, etc)
temp_pod.effectMissile = dataToLoad["effectMissile"] //If true, the pod deletes the second it lands. If you give it an explosion, it will act like a missile exploding as it hits the ground
temp_pod.effectCircle = dataToLoad["effectCircle"] //If true, allows the pod to come in at any angle. Bit of a weird feature but whatever its here
effectBurst = dataToLoad["effectBurst"] //IOf true, launches five pods at once (with a very small delay between for added coolness), in a 3x3 area centered around the area
temp_pod.reversing = dataToLoad["effectReverse"] //If true, the pod will not send any items. Instead, after opening, it will close again (picking up items/mobs) and fly back to centcom
temp_pod.reverse_option_list = dataToLoad["reverse_option_list"]
specificTarget = dataToLoad["effectTarget"] //Launches the pod at the turf of a specific mob target, rather than wherever the user clicked. Useful for smites
temp_pod.adminNamed = dataToLoad["effectName"] //Determines whether or not the pod has been named by an admin. If true, the pod's name will not get overridden when the style of the pod changes (changing the style of the pod normally also changes the name+desc)
temp_pod.name = dataToLoad["podName"]
temp_pod.desc = dataToLoad["podDesc"]
effectAnnounce = dataToLoad["effectAnnounce"]
numTurfs = dataToLoad["numObjects"] //Counts the number of turfs that contain a launchable object in the centcom supplypod bay
temp_pod.fallingSound = dataToLoad["fallingSound"]//Admin sound to play as the pod falls
temp_pod.landingSound = dataToLoad["landingSound"]//Admin sound to play when the pod lands
temp_pod.openingSound = dataToLoad["openingSound"]//Admin sound to play when the pod opens
temp_pod.leavingSound = dataToLoad["leavingSound"]//Admin sound to play when the pod leaves
temp_pod.soundVolume = dataToLoad["soundVolume"] //Admin sound to play when the pod leaves
picking_dropoff_turf = FALSE
launcherActivated = FALSE
updateCursor()
refreshView()
GLOBAL_DATUM_INIT(podlauncher, /datum/centcom_podlauncher, new)
//Proc for admins to enable others to use podlauncher after roundend
/datum/centcom_podlauncher/proc/give_podlauncher(mob/living/user, override)
if (SSticker.current_state < GAME_STATE_FINISHED)
return
if (!istype(user))
user = override
if (user)
setup(user)//setup the datum
//Set the dropoff location and indicator to either a specific turf or somewhere in an area
/datum/centcom_podlauncher/proc/setDropoff(target)
var/turf/target_turf
if (isturf(target))
target_turf = target
else if (isarea(target))
target_turf = pick(get_area_turfs(target))
else
CRASH("Improper type passed to setDropoff! Should be /turf or /area")
temp_pod.reverse_dropoff_coords = list(target_turf.x, target_turf.y, target_turf.z)
indicator.forceMove(target_turf)
/obj/effect/hallucination/simple/supplypod_selector
name = "Supply Selector (Only you can see this)"
image_icon = 'icons/obj/supplypods_32x32.dmi'
image_state = "selector"
image_layer = FLY_LAYER
alpha = 150
/obj/effect/hallucination/simple/dropoff_location
name = "Dropoff Location (Only you can see this)"
image_icon = 'icons/obj/supplypods_32x32.dmi'
image_state = "dropoff_indicator"
image_layer = FLY_LAYER
alpha = 0