forked from Squishy6094/character-select-coop
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathz-api.lua
More file actions
1314 lines (1205 loc) · 57.3 KB
/
Copy pathz-api.lua
File metadata and controls
1314 lines (1205 loc) · 57.3 KB
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
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
if incompatibleClient then return 0 end
---@class CharacterTable
---@field public name string
---@field public saveName string
---@field public description table
---@field public credit string
---@field public color Color
---@field public model ModelExtendedId|integer
---@field public baseChar CharacterType
---@field public lifeIcon TextureInfo
---@field public camScale integer
local TYPE_INTEGER = "number"
local TYPE_STRING = "string"
local TYPE_TABLE = "table"
local TYPE_TEX_INFO = "userdata"
local TYPE_FUNCTION = "function"
-------------------------
-- Character Functions --
-------------------------
---@header
---@forcedoc Character_Functions
---@description A function that adds a Character to the Character Table
---@added 1
---@param name string? `"Custom Model"`
---@param description string|table? `{"string"}`
---@param credit string? `"You!"`, Credit the creators
---@param color Color|string? `{r, g, b}`
---@param modelInfo ModelExtendedId|integer? Use `smlua_model_util_get_id`
---@param baseChar CharacterType? Character Type, such as `CT_MARIO`
---@param lifeIcon TextureInfo|string? Use get_texture_info
---@param camScale integer? Zooms the camera based on a multiplier (Default `1`)
---@return integer --The index of the character in the character table
local function character_add(name, description, credit, color, modelInfo, baseChar, lifeIcon, camScale)
name = type(name) == TYPE_STRING and name or "Untitled"
credit = type(credit) == TYPE_STRING and credit or "Unknown"
if type(description) == TYPE_TABLE then
local table = description
description = ""
for i = 1, #table do
description = description .. table[i] .. (i ~= #table and " " or "")
end
end
if color ~= nil and type(color) == TYPE_STRING then
color = {r = tonumber(color:sub(1,2), 16), g = tonumber(color:sub(3,4), 16), b = tonumber(color:sub(5,6), 16) }
end
if lifeIcon and type(lifeIcon) == TYPE_STRING then
lifeIcon = lifeIcon:sub(1,1)
end
local addedModel = (modelInfo and modelInfo ~= E_MODEL_ERROR_MODEL) and modelInfo or E_MODEL_ERROR_MODEL
local charNum = #characterTable + 1
if name and type(name) == TYPE_STRING and not _G["CT_"..name:upper():gsub(" ", "_")] then
local charNum = charNum ---@type CharacterType
define_valid_global("CT_"..name:upper():gsub(" ", "_"), charNum)
end
table.insert(characterTable, {
saveName = type(name) == TYPE_STRING and string_space_to_underscore(name.."_"..credit) or "Untitled",
nickname = type(name) == TYPE_STRING and name or "Untitled",
currAlt = 1,
hasMoveset = false,
locked = LOCKED_NEVER,
category = "All",
ogNum = charNum,
playtime = 0,
autoDialog = true,
replaceModels = {
model = {},
bhv = {},
},
replaceTextures = {},
menuInst = nil,
[1] = {
name = name,
description = type(description) == TYPE_STRING and description or "No description has been provided",
credit = credit,
color = type(color) == TYPE_TABLE and color or {r = 255, g = 255, b = 255},
model = addedModel,
ogModel = addedModel,
baseChar = baseChar and baseChar or CT_MARIO,
lifeIcon = (type(lifeIcon) == TYPE_TABLE or type(lifeIcon) == TYPE_TEX_INFO or type(lifeIcon) == TYPE_STRING) and lifeIcon or "?",
starIcon = gTextures.star,
camScale = type(camScale) == TYPE_INTEGER and camScale or 1,
healthMeter = nil,
},
})
characterMovesets[charNum] = {}
characterDialog[charNum] = {}
return charNum
end
---@description A function that adds a Costume to an Existing Character, all inputs mimic character_edit
---@added 1.11
---@param charNum integer The number/table position of the Character you want to add a costume to
---@param name string? `"Custom Model"`
---@param description table|string? `{"string"}`
---@param credit string? `"You!"`, Credit the creators
---@param color Color|string? `{r, g, b}`
---@param modelInfo ModelExtendedId|integer? Use `smlua_model_util_get_id`
---@param baseChar CharacterType? Character Type, such as `CT_MARIO`
---@param lifeIcon TextureInfo|string? Use get_texture_info
---@param camScale integer? Zooms the camera based on a multiplier (Default `1`)
---@return integer? --The index of the costume in the character's table
local function character_add_costume(charNum, name, description, credit, color, modelInfo, baseChar, lifeIcon, camScale)
if not tonumber(charNum) or charNum > #characterTable or charNum < 0 then return end
if description ~= nil and type(description) == TYPE_TABLE then
local table = description
description = ""
for i = 1, #table do
description = description .. table[i] .. (i ~= #table and " " or "")
end
end
if color ~= nil and type(color) == TYPE_STRING then
color = {r = tonumber(color:sub(1,2), 16), g = tonumber(color:sub(3,4), 16), b = tonumber(color:sub(5,6), 16) }
end
if lifeIcon and type(lifeIcon) == TYPE_STRING then
lifeIcon = lifeIcon:sub(1,1)
end
local tableCache = characterTable[charNum][1]
local addedModel = (modelInfo and modelInfo ~= E_MODEL_ERROR_MODEL) and modelInfo or tableCache.model
table.insert(characterTable[charNum], {
name = type(name) == TYPE_STRING and name or tableCache.name,
description = type(description) == TYPE_STRING and description or tableCache.description,
credit = type(credit) == TYPE_STRING and credit or tableCache.credit,
color = type(color) == TYPE_TABLE and color or tableCache.color,
model = addedModel,
ogModel = addedModel,
baseChar = type(baseChar) == TYPE_INTEGER and baseChar or tableCache.baseChar,
lifeIcon = (type(lifeIcon) == TYPE_TABLE or type(lifeIcon) == TYPE_TEX_INFO or type(lifeIcon) == TYPE_STRING) and lifeIcon or tableCache.lifeIcon,
starIcon = tableCache.starIcon, -- Done to prevent it getting lost in the sauce
camScale = type(camScale) == TYPE_INTEGER and camScale or tableCache.camScale,
healthMeter = tableCache.healthMeter,
})
return #characterTable[charNum]
end
---@description A function that Edits an existing Costume
---@added 1.11
---@param charNum integer The number/table position of the Character you want to edit the costume of
---@param charAlt integer The number/table position of the Costume you want to edit, this can be found by making a variable equal
---@param name string? `"Custom Model"`
---@param description table|string? `{"string"}`
---@param credit string? `"You!"`, Credit the creators
---@param color Color|string? `{r, g, b}`
---@param modelInfo ModelExtendedId|integer? Use `smlua_model_util_get_id`
---@param baseChar CharacterType? Character Type, such as `CT_MARIO`
---@param lifeIcon TextureInfo|string? Use get_texture_info
---@param camScale integer? Zooms the camera based on a multiplier (Default `1`)
local function character_edit_costume(charNum, charAlt, name, description, credit, color, modelInfo, baseChar, lifeIcon, camScale)
if tonumber(charNum) == nil or charNum > #characterTable or charNum < 0 then return end
if description ~= nil and type(description) == TYPE_TABLE then
local table = description
description = ""
for i = 1, #table do
description = description .. table[i] .. (i ~= #table and " " or "")
end
end
if color ~= nil and type(color) == TYPE_STRING then
color = {r = tonumber(color:sub(1,2), 16), g = tonumber(color:sub(3,4), 16), b = tonumber(color:sub(5,6), 16) }
end
if lifeIcon and type(lifeIcon) == TYPE_STRING then
lifeIcon = lifeIcon:sub(1,1)
end
local tableCache = characterTable[charNum][charAlt]
characterTable[charNum][charAlt] = characterTable[charNum][charAlt] and {
name = type(name) == TYPE_STRING and name or tableCache.name,
description = type(description) == TYPE_STRING and description or tableCache.description,
credit = type(credit) == TYPE_STRING and credit or tableCache.credit,
color = type(color) == TYPE_TABLE and color or tableCache.color,
model = (modelInfo and modelInfo ~= E_MODEL_ERROR_MODEL) and modelInfo or tableCache.model,
ogModel = tableCache.ogModel,
baseChar = type(baseChar) == TYPE_INTEGER and baseChar or tableCache.baseChar,
lifeIcon = (type(lifeIcon) == TYPE_TABLE or type(lifeIcon) == TYPE_TEX_INFO or type(lifeIcon) == TYPE_STRING) and lifeIcon or tableCache.lifeIcon,
starIcon = tableCache.starIcon, -- Done to prevent it getting lost in the sauce
camScale = type(camScale) == TYPE_INTEGER and camScale or tableCache.camScale,
healthMeter = tableCache.healthMeter,
} or nil
if modelInfo and characterColorPresets[modelInfo] and tableCache.model and characterColorPresets[tableCache.model] and #characterColorPresets[modelInfo] == #characterColorPresets[tableCache.model] then
characterColorPresets[modelInfo].currPalette = characterColorPresets[tableCache.model].currPalette
end
end
---@description A function that Edits an Existing Character
---@added 1
---@param charNum integer The number/table position of the Character you want to edit
---@param name string? `"Custom Model"`
---@param description table|string? `{"string"}`
---@param credit string? `"You!"`, Credit the creators
---@param color Color|string? `{r, g, b}`
---@param modelInfo ModelExtendedId|integer? Use `smlua_model_util_get_id`
---@param baseChar CharacterType? Character Type, such as `CT_MARIO`
---@param lifeIcon TextureInfo|string? Use get_texture_info
---@param camScale integer? Zooms the camera based on a multiplier (Default `1`)
local function character_edit(charNum, name, description, credit, color, modelInfo, baseChar, lifeIcon, camScale)
character_edit_costume(charNum, characterTable[charNum] and characterTable[charNum].currAlt or 1, name, description, credit, color, modelInfo, baseChar, lifeIcon, camScale)
end
---@description A function to set a Character's Nickname, used for Dialog Replacement
---@added 1.16
---@param charNum integer The number/table position of the Character you want to nickname
---@param nickname string The Character's new nickname
---@param autoSetDialog boolean? Wheather dialog is automatically set (Defaults to `true`)
local function character_set_nickname(charNum, nickname, autoSetDialog)
if autoSetDialog == nil then autoSetDialog = true end
if characterTable[charNum] == nil or type(nickname) == TYPE_STRING then
characterTable[charNum].nickname = nickname
characterTable[charNum].autoDialog = autoSetDialog
end
end
---@description A function to get a Character's Nickname, used for Dialog Replacement
---@added 1.16
---@param charNum integer The number/table position of the Character you want to get the nickname of
local function character_get_nickname(charNum)
return characterTable[charNum] ~= nil and characterTable[charNum].nickname
end
---@description A function that adds a voice table to a character
---@added 1.5
---@param modelInfo ModelExtendedId|integer Model Information Received from smlua_model_util_get_id
---@param clips table A Table with your Character's Sound File Names
---@note In order for sound files to function, please run config_character_sounds in your pack
---@note
---@note Table Example:
---@note ```lua
---@note local VOICETABLE_CHAR = {
---@note [CHAR_SOUND_ATTACKED] = 'NES-Hit.ogg',
---@note [CHAR_SOUND_DOH] = 'NES-Bump.ogg',
---@note [CHAR_SOUND_DROWNING] = 'NES-Die.ogg',
---@note [CHAR_SOUND_DYING] = 'NES-Die.ogg',
---@note [CHAR_SOUND_GROUND_POUND_WAH] = 'NES-Squish.ogg',
---@note [CHAR_SOUND_HAHA] = 'NES-1up.ogg',
---@note [CHAR_SOUND_HAHA_2] = 'NES-1up.ogg',
---@note [CHAR_SOUND_HERE_WE_GO] = 'NES-Flagpole.ogg',
---@note [CHAR_SOUND_HOOHOO] = 'NES-Jump.ogg',
---@note [CHAR_SOUND_MAMA_MIA] = 'NES-Warp.ogg',
---@note [CHAR_SOUND_OKEY_DOKEY] = 'NES-1up.ogg',
---@note [CHAR_SOUND_ON_FIRE] = 'NES-Enemy_Fire.ogg',
---@note [CHAR_SOUND_OOOF] = 'NES-Hit.ogg',
---@note [CHAR_SOUND_OOOF2] = 'NES-Hit.ogg',
---@note [CHAR_SOUND_PUNCH_HOO] = 'NES-Kick.ogg',
---@note [CHAR_SOUND_PUNCH_WAH] = 'NES-Thwomp.ogg',
---@note [CHAR_SOUND_PUNCH_YAH] = 'NES-Thwomp.ogg',
---@note [CHAR_SOUND_SO_LONGA_BOWSER] = 'NES-Bowser_Die.ogg',
---@note [CHAR_SOUND_TWIRL_BOUNCE] = 'NES-Item.ogg',
---@note [CHAR_SOUND_WAAAOOOW] = 'NES-Vine.ogg',
---@note [CHAR_SOUND_WAH2] = 'NES-Kick.ogg',
---@note [CHAR_SOUND_WHOA] = 'NES-Item.ogg',
---@note [CHAR_SOUND_YAHOO] = 'NES-Jump.ogg',
---@note [CHAR_SOUND_YAHOO_WAHA_YIPPEE] = 'NES-Jump.ogg',
---@note [CHAR_SOUND_YAH_WAH_HOO] = 'NES-Big_Jump.ogg',
---@note [CHAR_SOUND_YAWNING] = 'NES-Pause.ogg',
---@note }
---@note ```
local function character_add_voice(modelInfo, clips)
--hook_event(HOOK_ON_MODS_LOADED, function ()
local voiceTable = {}
-- Check nil table for vanilla voices
if clips == nil then return end
-- Check empty table for no sound
if clips == nil then return NO_SOUND end
-- Load samples that haven't been loaded
for voice, sound in pairs(clips) do
if sound then
if type(sound) == TYPE_STRING then
local load = audio_sample_load(sound)
if load ~= nil then
voiceTable[voice] = load
end
elseif sound._pointer ~= nil then
voiceTable[voice] = sound
elseif type(sound) == TYPE_TABLE then
-- load RNG/Table Samples
voiceTable[voice] = {}
for i, subsound in pairs(sound) do
if type(subsound) == TYPE_STRING then
local load = audio_sample_load(subsound)
if load ~= nil then
voiceTable[voice][i] = load
end
elseif subsound._pointer ~= nil then
voiceTable[voice][i] = subsound
end
end
end
end
end
characterVoices[modelInfo] = voiceTable
--end)
end
hook_event(HOOK_ON_MODS_LOADED, character_add_voice)
---@description A function that gets the current character's voice table
---@added 1.5
---@param model integer|MarioState Can use Model and/or MarioState
function character_get_voice(model)
local model = (type(model) == TYPE_INTEGER) and model or gCSPlayers[model.playerIndex].modelId
return characterVoices[model]
end
---@description A function that adds a caps table to a character
---@added 1.6
---@param modelInfo ModelExtendedId|integer Model Information Received from smlua_model_util_get_id
---@param caps table Cap
---@note ```lua
---@note local CAPTABLE_CHAR = {
---@note normal = smlua_model_util_get_id("custom_model_cap_normal_geo"),
---@note wing = smlua_model_util_get_id("custom_model_cap_wing_geo"),
---@note metal = smlua_model_util_get_id("custom_model_cap_metal_geo"),
---@note metalWing = smlua_model_util_get_id("custom_model_cap_wing_geo")
---@note }
---@note ```
local function character_add_caps(modelInfo, caps)
characterCaps[modelInfo] = type(caps) == TYPE_TABLE and caps or nil
end
---@description A function that gets a model's cap table
---@added 1.13
---@param modelInfo ModelExtendedId|integer? Model Information Received from smlua_model_util_get_id
local function character_get_caps(modelInfo)
if modelInfo == nil then modelInfo = characterTable[currChar][characterTable[currChar].currAlt].model end
return characterCaps[modelInfo]
end
---@description A function that adds health meter textures to a costume
---@added 1.12
---@param charNum integer The number/table position of the Character you want to add a meter to
---@param charAlt integer The number/table position of the Costume you want to add a meter to
---@param healthMeter table|function? A Table with your Character's Health Textures (Table Shown in character_add_health_meter) or Rendering Function
local function character_add_costume_health_meter(charNum, charAlt, healthMeter)
if type(charNum) ~= TYPE_INTEGER or charNum == nil then return end
if type(charAlt) ~= TYPE_INTEGER or charAlt == nil then return end
if healthMeter == nil then
return
elseif type(healthMeter) == TYPE_FUNCTION then
characterTable[charNum][charAlt].healthMeter = healthMeter
elseif type(healthMeter) == TYPE_TABLE then
characterTable[charNum][charAlt].healthMeter = {
label = {
left = is_texture_valid(healthMeter.label.left) and healthMeter.label.left or defaultMeterInfo.label.left,
right = is_texture_valid(healthMeter.label.right) and healthMeter.label.right or defaultMeterInfo.label.right,
},
pie = {
is_texture_valid(healthMeter.pie[1]) and healthMeter.pie[1] or defaultMeterInfo.pie[1],
is_texture_valid(healthMeter.pie[2]) and healthMeter.pie[2] or defaultMeterInfo.pie[2],
is_texture_valid(healthMeter.pie[3]) and healthMeter.pie[3] or defaultMeterInfo.pie[3],
is_texture_valid(healthMeter.pie[4]) and healthMeter.pie[4] or defaultMeterInfo.pie[4],
is_texture_valid(healthMeter.pie[5]) and healthMeter.pie[5] or defaultMeterInfo.pie[5],
is_texture_valid(healthMeter.pie[6]) and healthMeter.pie[6] or defaultMeterInfo.pie[6],
is_texture_valid(healthMeter.pie[7]) and healthMeter.pie[7] or defaultMeterInfo.pie[7],
is_texture_valid(healthMeter.pie[8]) and healthMeter.pie[8] or defaultMeterInfo.pie[8],
}
}
end
end
---@description A function that adds health meter textures to a character
---@added 1.9
---@param charNum integer The number/table position of the Character you want to add a meter to
---@param healthMeter table|function? A Table with your Character's Health Textures (Table Shown Below) or Rendering Function
---@note ```lua
---@note local HEALTH_METER_CHAR = {
---@note label = {
---@note left = get_texture_info("char_hp_pie_left"),
---@note right = get_texture_info("char_hp_pie_right"),
---@note },
---@note pie = {
---@note [1] = get_texture_info("char_hp_pie_1"),
---@note [2] = get_texture_info("char_hp_pie_2"),
---@note [3] = get_texture_info("char_hp_pie_3"),
---@note [4] = get_texture_info("char_hp_pie_4"),
---@note [5] = get_texture_info("char_hp_pie_5"),
---@note [6] = get_texture_info("char_hp_pie_6"),
---@note [7] = get_texture_info("char_hp_pie_7"),
---@note [8] = get_texture_info("char_hp_pie_8"),
---@note }
---@note }
---@note
---@note -- or --
---@note
---@note local function char_meter_render(localIndex, health, prevX, prevY, prevScaleX, prevScaleY, x, y, scaleX, scaleY)
---@note local squares = health >> 8
---@note for i = 1, squares do
---@note djui_hud_render_rect(x + (i * 17), y, 16, 16)
---@note end
---@note end
---@note ```
local function character_add_health_meter(charNum, healthMeter)
character_add_costume_health_meter(charNum, 1, healthMeter)
end
---@description A function that adds course textures to a costume in the Star Select
---@added 1.12
---@param charNum integer The number/table position of the Character you want to add a course textures to
---@param charAlt integer The number/table position of the Costume you want to add a course textures to
---@param courseTexture table? A Table with your Character's Health Textures (Table Shown in character_add_course)
local function character_add_costume_course_texture(charNum, charAlt, courseTexture)
if type(charNum) ~= TYPE_INTEGER or charNum == nil then return end
if type(charAlt) ~= TYPE_INTEGER or charAlt == nil then return end
characterTable[charNum][charAlt].courseTexture = type(courseTexture) == TYPE_TABLE and courseTexture or nil
end
---@description A function that adds course textures to a character in the Star Select
---@added 1.12
---@param charNum integer The number/table position of the Character you want to add a course textures to
---@param courseTexture table? A Table with your Character's Health Textures (Table Shown Below)
---@note ```lua
---@note local COURSE_CHAR = {
---@note top = get_texture_info("char_course_top"),
---@note bottom = get_texture_info("char_course_bottom"),
---@note }
---@note ```
local function character_add_course_texture(charNum, courseTexture)
character_add_costume_course_texture(charNum, 1, courseTexture)
end
---@description A function that replaces a behaviors model with your own
---@added 1.16.2
---@param charNum integer Player Model ID
---@param bhvId BehaviorId|ModelExtendedId|integer Behavior ID of the type of objects you want to replace
---@param replaceModel ModelExtendedId|integer|function? Model ID
---@param isModel boolean? Makes `bhvId` act as a `ModelExtendedId` input, replacing objects based on it's model rather then it's behavior
local function character_add_model_replacement(charNum, bhvId, replaceModel, isModel)
if isModel then
characterTable[charNum].replaceModels.model[bhvId] = replaceModel
else
characterTable[charNum].replaceModels.bhv[bhvId] = replaceModel
end
end
---@description A function that replaces a texture with your own
---@added 1.16.2
---@param charNum integer Player Model ID
---@param textureName string Behavior ID of the type of objects you want to replace
---@param overrideTexInfo TextureInfo|function Model ID
local function character_add_texture_replacement(charNum, textureName, overrideTexInfo)
table.insert(texturesModified, textureName)
characterTable[charNum].replaceTextures[textureName] = overrideTexInfo
end
---@description A function that adds a celebration star model to a character
---@added 1.7
---@param modelInfo ModelExtendedId|integer Player Model ID
---@param starModel ModelExtendedId|integer Custom Star Model ID
---@param starIcon TextureInfo? Custom Star Texture
local function character_add_celebration_star(modelInfo, starModel, starIcon)
local charNum, charAlt = character_get_number_from_model(modelInfo)
character_add_model_replacement(charNum, E_MODEL_STAR, starModel, true)
character_add_texture_replacement(charNum, "texture_hud_char_star", starIcon)
characterTable[charNum][charAlt].starIcon = type(starIcon) == TYPE_TABLE and starIcon or gTextures.star
end
---@description A function that adds a peach model to a character for the opening letter and ending cutscene.Can also change peach's letter for the character
---@added 1.16
---@param modelInfo ModelExtendedId|integer Model Information Received from smlua_model_util_get_id()
---@param peachmodelstart ModelExtendedId? Model Information Received from smlua_model_util_get_id() the model used for peach in the opening if left blank will use default peach model
---@param peachmodelend ModelExtendedId? Model Information Received from smlua_model_util_get_id() the model used for peach in the ending if left blank will use default peach model
---@param peachletterleft TextureInfo? left side of the texture to replace peach's letter texture in the intro
---@param peachletterright TextureInfo? right side of the texture to replace peach's letter texture in the intro
---@param peachlettersig TextureInfo? texture to replace peach's letter texture in the intro
local function character_add_peach_custom(modelInfo, peachmodelstart, peachmodelend, peachletterleft, peachletterright, peachlettersig)
if modelInfo == nil then return end
local charNum = character_get_number_from_model(modelInfo) ---@type integer
character_add_model_replacement(charNum, id_bhvBeginningPeach, function(o)
if peachmodelstart ~= nil then
return peachmodelstart
else
return obj_get_model_id_extended(o)
end
end)
character_add_model_replacement(charNum, id_bhvEndPeach, peachmodelend)
if (peachletterleft ~= nil) and (peachletterright ~= nil) and (peachlettersig ~= nil) then
character_add_texture_replacement(charNum, "castle_grounds_seg7_texture_0700C9E8", peachletterleft)
character_add_texture_replacement(charNum, "castle_grounds_seg7_texture_0700D9E8", peachletterright)
character_add_texture_replacement(charNum, "castle_grounds_seg7_us_texture_0700EAE8", peachlettersig)
end
end
---@description A function that sets the toad models during the ending cutscene
---@added 1.16
---@param modelInfo ModelExtendedId|integer Model Information Received from smlua_model_util_get_id()
---@param toadModelRight ModelExtendedId Model Information Received from smlua_model_util_get_id(), the model used for the right toad in the ending if left blank said toad will use the default npc toad model
---@param toadModelLeft ModelExtendedId Model Information Received from smlua_model_util_get_id(), the model used for the left toad in the ending if left blank said toad will use the default npc toad model
local function character_add_ending_toad_model(modelInfo, toadModelRight, toadModelLeft)
if modelInfo == nil then return end
local settingRightToad = false
local charNum = character_get_number_from_model(modelInfo) ---@type integer
character_add_model_replacement(charNum, id_bhvEndToad, function (o)
if (obj_has_model_extended(o,toadModelRight) == 0) and (obj_has_model_extended(o,toadModelLeft) == 0) then --if the model was already changed
settingRightToad = not settingRightToad
if settingRightToad then
return toadModelRight
end
return toadModelLeft
else --the ending toads model was already changed
return obj_get_model_id_extended(o)
end
end)
end
---@description A function that adds a palette preset to a character
---@added 1.8
---@param modelInfo ModelExtendedId|integer
---@param paletteTable table
---@param paletteName string?
---@note ```lua
---@note local PALETTE_CHAR = {
---@note [PANTS] = {r = 0x00, g = 0x00, b = 0xff},
---@note [SHIRT] = {r = 0xff, g = 0x00, b = 0x00},
---@note [GLOVES] = {r = 0xff, g = 0xff, b = 0xff},
---@note [SHOES] = {r = 0x72, g = 0x1c, b = 0x0e},
---@note [HAIR] = {r = 0x73, g = 0x06, b = 0x00},
---@note [SKIN] = {r = 0xfe, g = 0xc1, b = 0x79},
---@note [CAP] = {r = 0xff, g = 0x00, b = 0x00},
---@note }
---@note ```
---@note Strings can also be used rather than RGB tables, ex. `[PANTS] = "0000ff"`
local function character_add_palette_preset(modelInfo, paletteTable, paletteName)
if paletteName == nil then
if characterColorPresets[modelInfo] == nil then
paletteName = "Default"
else
paletteName = "Alt " .. tostring(#characterColorPresets[modelInfo])
end
end
local paletteTableOut = {
name = paletteName,
}
local defaultColors = characterColorPresets[E_MODEL_MARIO]
for i = 0, 7 do
local color = paletteTable[i]
paletteTableOut[i] = {r = 0, g = 0, b = 0}
if type(color) == TYPE_STRING then
paletteTableOut[i].r = tonumber(color:sub(1,2), 16) and tonumber(color:sub(1,2), 16) or defaultColors[i].r
paletteTableOut[i].g = tonumber(color:sub(3,4), 16) and tonumber(color:sub(3,4), 16) or defaultColors[i].g
paletteTableOut[i].b = tonumber(color:sub(5,6), 16) and tonumber(color:sub(5,6), 16) or defaultColors[i].b
end
if type(color) == TYPE_TABLE then
paletteTableOut[i].r = (type(color) == TYPE_TABLE and color.r) and color.r or defaultColors[i].r
paletteTableOut[i].g = (type(color) == TYPE_TABLE and color.g) and color.g or defaultColors[i].g
paletteTableOut[i].b = (type(color) == TYPE_TABLE and color.b) and color.b or defaultColors[i].b
end
end
if characterColorPresets[modelInfo] == nil then
characterColorPresets[modelInfo] = {
currPalette = 1,
}
end
table.insert(characterColorPresets[modelInfo], paletteTableOut)
end
---@description A function that adds animations to a model
---@added 1.10
---@param modelInfo ModelExtendedId|integer
---@param animTable? table
---@param eyeTable? table
---@param handTable? table
local function character_add_animations(modelInfo, animTable, eyeTable, handTable)
characterAnims[modelInfo] = {
anims = type(animTable) == TYPE_TABLE and animTable or nil,
eyes = type(eyeTable) == TYPE_TABLE and eyeTable or nil,
hands = type(handTable) == TYPE_TABLE and handTable or nil,
}
end
---@description A function that gets any animation table from a model
---@added 1.10
---@param modelInfo ModelExtendedId|integer
local function character_get_animations(modelInfo)
return characterAnims[modelInfo]
end
---@description A function that gets a character's full Character Select Table
---@added 1
---@param tablePos integer?
---@param charAlt integer?
---@return CharacterTable
local function character_get_current_table(tablePos, charAlt)
tablePos = tablePos and tablePos or currChar
charAlt = charAlt and charAlt or 1
return characterTable[tablePos][charAlt]
end
---@description A function that gets Character Select's Entire Character Table
---@added 1.11.1
---@return table
local function character_get_full_table()
return characterTable
end
---@description A function that gets the current character's table position in CS
---@added 1
---@param localIndex integer? The local player index you want to get the character number from, Default is `0`
---@return integer?
local function character_get_current_number(localIndex)
if not startup_init_stall() then return end
if localIndex == nil or localIndex == 0 then
return currChar
else
for i = 0, #characterTable do
if characterTable[i].saveName == gCSPlayers[localIndex].saveName then
return i
end
end
return nil
end
end
---@description A function that gets the current costumes's table position in CS
---@added 1.12
---@param localIndex integer?
---@return integer?
local function character_get_current_costume(localIndex)
if localIndex == nil or localIndex == 0 then
return characterTable[currChar].currAlt
else
for i = 0, #characterTable do
if characterTable[i].saveName == gCSPlayers[localIndex].saveName then
return characterTable[i].currAlt
end
end
return nil
end
end
---@description A function that sets the current character based only table position with an optional second argument for setting a specific costume
---@added 1.9
---@param charNum integer The number/table position of the Character you want the local player to become
---@param charAlt integer? The number/table position of a costume in the corresponding character's costume table to switch to. If nil will use the 1st costume
local function character_set_current_number(charNum, charAlt)
if type(charNum) ~= TYPE_INTEGER or characterTable[charNum] == nil then return end
if charAlt == nil then charAlt = 1 end
charAlt = math.clamp(charAlt, 1, #characterTable[charNum])
force_set_character(charNum, charAlt)
charBeingSet = true
end
---@description A function that gets the current character's palette data
---@added 1.12
---@return table?
local function character_get_current_palette()
local model = characterTable[currChar][characterTable[currChar].currAlt].model
return characterColorPresets[model] ~= nil and characterColorPresets[model][gCSPlayers[0].presetPalette] or nil
end
---@description A function that gets the current character's palette number
---@added 1.12
---@param localIndex integer?
---@return integer?
local function character_get_current_palette_number(localIndex)
if localIndex == nil then localIndex = 0 end
return gCSPlayers[localIndex].presetPalette
end
---@description A function that searches for a character's table posision based on name
---@added 1
---@param name string
---@return integer?
function character_get_number_from_string(name)
if type(name) ~= TYPE_STRING then return nil end
for i = 0, #characterTable do
for a = 1, #characterTable[i] do
if characterTable[i][a].name == name or characterTable[i][a].name == string_space_to_underscore(name) then
return i
end
end
end
return nil
end
---@description A function that searches for a character's table posision based on model
---@added 1.16
---@param model integer|ModelExtendedId
---@return integer, integer
function character_get_number_from_model(model)
if type(model) ~= TYPE_INTEGER then return nil end
for i = 0, #characterTable do
for a = 1, #characterTable[i] do
if characterTable[i][a].model == model or characterTable[i][a].ogModel == model then
return i, a
end
end
end
end
-- Located in n-hud.lua
---@description A function that gets a persons life icon texture / string based off of local index
---@added 1.7
---@param localIndex integer
---@return TextureInfo|string
---@note This assumes multiple characters will not have the same model, Icons can only be seen by users who have the character avalible to them. This function can return nil. if this is the case, render `djui_hud_print_text("?", x, y, 1)`
---@forcedoc character_get_life_icon
---@description A function that renders a persons life icon texture / string based off of local index
---@added 1.11
---@param localIndex integer
---@param x integer
---@param y integer
---@param scale integer
---@forcedoc character_render_life_icon
---@description A function that acts as character_render_life_icon with support for interpolation
---@added 1.13
---@param localIndex integer
---@param prevX integer
---@param prevY integer
---@param prevScale integer
---@param x integer
---@param y integer
---@param scale integer
---@forcedoc character_render_life_icon_interpolated
---@description A function that gets a persons star icon texture / string based off of local index
---@added 1.8
---@param localIndex integer
---@return TextureInfo
---@note This assumes multiple characters will not have the same model, Icons can only be seen by users who have the character avalible to them
---@forcedoc character_get_star_icon
---@description A function that renders a persons star icon texture / string based off of local index
---@added 1.11
---@param localIndex integer
---@param x integer
---@param y integer
---@param scale integer
---@forcedoc character_render_star_icon
---@description A function that acts as character_render_star_icon with support for interpolation
---@added 1.13
---@param localIndex integer
---@param prevX integer
---@param prevY integer
---@param prevScale integer
---@param x integer
---@param y integer
---@param scale integer
---@forcedoc character_render_star_icon_interpolated
---@description A function that gets a persons health meter texture table (example of which is at character_add_health_meter)
---@added 1.12
---@param localIndex integer
---@return table
---@note This assumes multiple characters will not have the same model, Meters can only be seen by users who have the character avalible to them
---@forcedoc character_get_health_meter
---@description A function that renders a persons health meter texture table
---@added 1.12
---@param localIndex integer
---@param health integer
---@param x integer
---@param y integer
---@param scaleX integer
---@param scaleY integer
---@forcedoc character_render_health_meter
---@description A function that renders a persons health meter texture table, with interpolation
---@added 1.16
---@param localIndex integer
---@param health integer
---@param prevX integer
---@param prevY integer
---@param prevScaleX integer
---@param prevScaleY integer
---@param x integer
---@param y integer
---@param scaleX integer
---@param scaleY integer
---@forcedoc character_render_health_meter_interpolated
---@description A function that locks a character under an unlock condition
---@added 1.10
---@param charNum integer? The number of the Character you want to Lock
---@param unlockCondition function|boolean? The condition for if the character stays locked
---@param notify boolean? Toggles whether Character Select should notify the user when the character is unlocked
local function character_set_locked(charNum, unlockCondition, notify)
if charNum == nil or charNum > #characterTable or charNum < 0 then return end
if unlockCondition == nil then unlockCondition = false end
if notify == nil then notify = true end
characterTable[charNum].locked = run_func_or_get_var(unlockCondition) and LOCKED_FALSE or LOCKED_TRUE
if currChar == charNum then
force_set_character()
end
characterUnlock[charNum] = {
check = unlockCondition,
notif = notify,
}
end
---@description A function that sets a character under a specific category
---@added 1.14
---@param charNum integer The number of the Character you want to set the category for
---@param categoryName string The Category Name (Will create a new category if category does not exist)
---@param forceIcon boolean? Forces the icon to be used as a category icon
local function character_set_category(charNum, categoryName, forceIcon)
if not charNum then return end
if not categoryName then return end
categoryName = string_underscore_to_space(categoryName)
local foundCategory = nil
for i = 1, #characterCategories do
if characterCategories[i].name == categoryName then
foundCategory = characterCategories[i]
end
end
if not foundCategory then
table.insert(characterCategories, {name = categoryName, icon1 = nil, icon2 = nil})
foundCategory = characterCategories[#characterCategories]
end
if forceIcon then
if not foundCategory.icon1 then
foundCategory.icon1 = charNum
elseif not foundCategory.icon2 then
foundCategory.icon2 = charNum
end
end
characterTable[charNum].category = characterTable[charNum].category .. "_" .. categoryName
end
---@description A function that replaces dialog if you are playing as a specific character
---@added 1.16
---@param charNum integer The number of the Character you want to replace dislog for
---@param dialogId integer|DialogId The ID of the dialog you want to replace
---@param unused integer Unused Dialog Variable
---@param linesPerBox integer Lines of text that appear in a single dialog
---@param leftOffset integer Dialog Box Posistion relitive to the left side of the screen
---@param width integer Verticle Position on screen (Dispite Variable Name)
---@param text string Dialog to be replaced with
local function character_replace_dialog(charNum, dialogId, unused, linesPerBox, leftOffset, width, text)
if modded == nil then modded = true end
characterDialog[charNum][dialogId] = {
unused = unused,
linesPerBox = linesPerBox,
leftOffset = leftOffset,
width = width,
text = text,
}
end
---@header
---@forcedoc Menu_Functions
---@description (Deprecated) A function that sets the big "Character Select" texture in the Character Select Menu
---@added 1.7
---@param texture TextureInfo?
---@forcedoc header_set_texture
---@description A function that returns the version string
---@added 1
---@return string --`"v1.2.3"`
local function version_get()
return MOD_VERSION_STRING
end
---@description A function that returns the version in table format
---@added 1.11
---@return table
---@note Returns the following table (Will differ based on version)
---@note ```lua
---@note {
---@note api = 1,
---@note major = 2,
---@note minor = 3,
---@note indev = true
---@note }
---@note ```
local function version_get_full()
return {
api = MOD_VERSION_API,
major = MOD_VERSION_MAJOR,
minor = MOD_VERSION_MINOR,
indev = MOD_VERSION_INDEV
}
end
---@description A function that checks is the Character Select Menu is currently open
---@added 1
---@return boolean
local function is_menu_open()
return menuAndTransition
end
---@description A function that forces they Character Select Menu state
---@added 1.8
---@param bool boolean? Sets if the menu is open
local function set_menu_open(bool)
if bool == nil then bool = true end
menu = bool
end
---@description A function that gets Character Select's current Menu color
---@added 1.8
---@return table
local function get_menu_color()
return menuColor
end
---------------------------
-- HUD Element Functions --
---------------------------
---@header
---@forcedoc HUD_Element_Functions
---@description Hides the specified custom hud element
---@added 1.5
---@param hudElement HUDDisplayFlag
---@forcedoc hud_hide_element
---@description Shows the specified custom hud element
---@added 1.5
---@param hudElement HUDDisplayFlag
---@forcedoc hud_show_element
---@description Gets the specified custom hud element's state
---@added 1.5
---@param hudElement HUDDisplayFlag
---@return boolean
---@forcedoc hud_get_element
---@description A function that checks if the options menu is open inside of the CS menu
---@added 1
---@return boolean
local function is_options_open()
return options ~= nil
end
---@description A function that adds credits to the CS Options' Credits section
---@added 1.10
---@param modName string The Name of your Character Select Mod
---@param creditee string The person you want to Credit
---@param credit string What the Person helped with
---@overload fun(modName: string, credits: string[][])
local function credit_add(modName, creditee, credit)
local credits
for i = 2, #creditTable do
if modName == creditTable[i].packName then
credits = creditTable[i]
end
end
if not credits then
credits = { packName = modName }
table.insert(creditTable, credits)
end
if type(creditee) == "table" then
for _, credit in ipairs(creditee) do
table.insert(credits, { creditee = credit[1], credit = credit[2] })
end
else table.insert(credits, { creditee = creditee, credit = credit }) end
end
---@description A function that sets if palettes are restricted (Default `false` unless a mod with the incompatible `gamemode` is on)
---@added 1.8
---@param bool boolean
local function restrict_palettes(bool)
if not network_is_server() then return end
if bool == nil then bool = true end
gGlobalSyncTable.charSelectRestrictPalettes = bool and 2 or 0
end
---@description A function that sets if movesets are restricted (Default `false`)
---@added 1.10
---@param bool boolean
local function restrict_movesets(bool)
if not network_is_server() then return end
if bool == nil then bool = true end
gGlobalSyncTable.charSelectRestrictMovesets = bool and 2 or optionTable[optionTableRef.restrictMovesets].toggle
end
---@description A function that checks if palettes are restricted
---@added 1.15
---@return boolean
local function are_palettes_restricted()
return gGlobalSyncTable.charSelectRestrictPalettes > 0
end
---@description A function that checks if movesets are restricted
---@added 1.15
---@return boolean
local function are_movesets_restricted()
return gGlobalSyncTable.charSelectRestrictMovesets > 0
end
---@description A table that contains the local mario's controller before Character Select's menu cancels them
---@added 1
local controller = {
buttonDown = 0,
buttonPressed = 0,