Repository navigation
Expand file tree
/
Copy pathAdminTools.lua
More file actions
1212 lines (1103 loc) · 47.7 KB
/
Copy pathAdminTools.lua
File metadata and controls
1212 lines (1103 loc) · 47.7 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
--=========================================================================
-- Admin Tools - quick GM command panel for WOTLK 3.3.5a (TrinityCore / SPP)
--
-- Commands are sent as chat text starting with "." exactly as if you typed
-- them. On TrinityCore the server intercepts these before they are spoken,
-- so nothing is broadcast as long as the account has GM access and the
-- command is valid. If a command is rejected it will appear in /say.
--
-- Slash: /admin (or /adt) - toggles the window
-- /admin <command> - runs a single command (leading "." optional)
--
-- Tweaking: every button is just { "Label", ".command" }. Edit the tables
-- below to add/remove/reorder buttons, or use the Custom tab in-game.
--=========================================================================
local ADDON = ...
local floor, ceil = math.floor, math.ceil
-- Largest normal (non-profession) bag in WotLK 3.3.5a = 22 slots.
-- Glacial Bag, itemID 41600. Alternate 22-slotter: Gigantique Bag 34845.
local MAX_BAG_ID = 41600
---------------------------------------------------------------------------
-- Core: run a command
---------------------------------------------------------------------------
local function RunCmd(cmd)
if type(cmd) ~= "string" then return end
cmd = strtrim(cmd)
if cmd == "" then return end
if cmd:sub(1, 1) ~= "." then cmd = "." .. cmd end
if #cmd > 255 then cmd = cmd:sub(1, 255) end
-- Silent execution via editbox prevents rejected GM commands from leaking to public /say
local eb = ChatEdit_GetActiveWindow and ChatEdit_GetActiveWindow() or ChatFrame1EditBox
if eb then
local oldText = eb:GetText()
eb:SetText(cmd)
ChatEdit_SendText(eb, 0)
eb:SetText(oldText or "")
else
SendChatMessage(cmd, "SAY")
end
if not AdminToolsDB or AdminToolsDB.echo ~= false then
DEFAULT_CHAT_FRAME:AddMessage("|cFFFFD700[Project Jaina Admin]|r " .. cmd)
end
end
local function ConfirmCmd(cmd)
local d = StaticPopup_Show("ADMINTOOLS_CONFIRM", cmd)
if d then d.data = cmd end
end
StaticPopupDialogs["ADMINTOOLS_CONFIRM"] = {
text = "Run this command?\n\n|cffffd100%s|r",
button1 = YES, button2 = NO,
OnAccept = function(self, data) RunCmd(data) end,
timeout = 0, whileDead = true, hideOnEscape = true, preferredIndex = 3,
}
StaticPopupDialogs["ADMINTOOLS_ENEMYCITY"] = {
text = "That is a |cffff2020%s|r capital.\nEnemy guards will attack you on arrival.\n\nTeleport anyway?",
button1 = YES, button2 = NO,
OnAccept = function(self, data) RunCmd(data) end,
timeout = 0, whileDead = true, hideOnEscape = true, preferredIndex = 3,
}
---------------------------------------------------------------------------
-- Widget helpers
---------------------------------------------------------------------------
local BTN_W, BTN_H, PAD = 122, 22, 6
local function MakeButton(parent, text, w, action)
local b = CreateFrame("Button", nil, parent, "UIPanelButtonTemplate")
b:SetSize(w or BTN_W, BTN_H)
b:SetText(text)
b:SetScript("OnClick", function()
if type(action) == "function" then action() else RunCmd(action) end
end)
return b
end
local function MakeEdit(parent, w)
local e = CreateFrame("EditBox", nil, parent, "InputBoxTemplate")
e:SetSize(w or 160, 20)
e:SetAutoFocus(false)
e:SetScript("OnEscapePressed", e.ClearFocus)
e:SetScript("OnEnterPressed", e.ClearFocus)
return e
end
local function MakeLabel(parent, text, template)
local fs = parent:CreateFontString(nil, "ARTWORK", template or "GameFontNormalSmall")
fs:SetText(text)
return fs
end
-- lay out a list of {label, cmd} buttons in a grid (default 3-wide); returns next Y
local function FlowButtons(page, defs, startY, customCols, customW)
local cols = customCols or 3
local w = customW or BTN_W
for i, d in ipairs(defs) do
local col = (i - 1) % cols
local row = floor((i - 1) / cols)
local b = MakeButton(page, d[1], w, d[2])
b:SetPoint("TOPLEFT", page, "TOPLEFT", 4 + col * (w + PAD), startY - row * (BTN_H + PAD))
end
return startY - ceil(#defs / cols) * (BTN_H + PAD) - PAD
end
-- label + one editbox + Go button; builder(text) -> command string
local function FormRow(page, y, labelText, builder, width)
local lbl = MakeLabel(page, labelText)
lbl:SetPoint("TOPLEFT", page, "TOPLEFT", 6, y - 5)
local e = MakeEdit(page, width or 170)
e:SetPoint("TOPLEFT", page, "TOPLEFT", 122, y)
local function fire()
local t = strtrim(e:GetText() or "")
if t ~= "" then RunCmd(builder(t)) end
end
local go = MakeButton(page, "Go", 40, fire)
go:SetPoint("LEFT", e, "RIGHT", 6, 0)
e:SetScript("OnEnterPressed", function(self) fire(); self:ClearFocus() end)
return y - 26, e
end
-- label + two editboxes + Go button; builder(a, b) -> command string
local function FormRow2(page, y, labelText, builder)
local lbl = MakeLabel(page, labelText)
lbl:SetPoint("TOPLEFT", page, "TOPLEFT", 6, y - 5)
local e1 = MakeEdit(page, 90)
e1:SetPoint("TOPLEFT", page, "TOPLEFT", 122, y)
local e2 = MakeEdit(page, 60)
e2:SetPoint("LEFT", e1, "RIGHT", 6, 0)
local function fire()
local a = strtrim(e1:GetText() or "")
local b = strtrim(e2:GetText() or "")
if a ~= "" then RunCmd(builder(a, b)) end
end
local go = MakeButton(page, "Go", 40, fire)
go:SetPoint("LEFT", e2, "RIGHT", 6, 0)
e1:SetScript("OnEnterPressed", function() fire() end)
e2:SetScript("OnEnterPressed", function(self) fire(); self:ClearFocus() end)
return y - 26
end
-- teleport button that warns before dropping you in an enemy capital
local function MakeTeleButton(parent, label, teleName, cityFaction)
return MakeButton(parent, label, BTN_W, function()
local pf = UnitFactionGroup("player")
if cityFaction and cityFaction ~= "Neutral" and pf and cityFaction ~= pf then
local d = StaticPopup_Show("ADMINTOOLS_ENEMYCITY", cityFaction)
if d then d.data = ".tele " .. teleName end
else
RunCmd(".tele " .. teleName)
end
end)
end
-- header + grid of {label, teleName, faction} buttons; returns next Y
local function TeleSection(page, y, header, list)
local h = MakeLabel(page, header, "GameFontNormal")
h:SetPoint("TOPLEFT", page, "TOPLEFT", 6, y)
y = y - 16
local cols = 3
for i, e in ipairs(list) do
local col = (i - 1) % cols
local row = floor((i - 1) / cols)
local b = MakeTeleButton(page, e[1], e[2], e[3])
b:SetPoint("TOPLEFT", page, "TOPLEFT", 4 + col * (BTN_W + PAD), y - row * (BTN_H + PAD))
end
return y - ceil(#list / cols) * (BTN_H + PAD) - PAD - 2
end
---------------------------------------------------------------------------
-- Main frame
---------------------------------------------------------------------------
local f = CreateFrame("Frame", "AdminToolsFrame", UIParent)
f:SetSize(670, 520)
f:SetPoint("CENTER")
f:SetBackdrop({
bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
tile = true, tileSize = 32, edgeSize = 32,
insets = { left = 11, right = 12, top = 12, bottom = 11 },
})
f:SetToplevel(true)
f:SetClampedToScreen(true)
f:SetMovable(true)
f:EnableMouse(true)
f:RegisterForDrag("LeftButton")
f:SetScript("OnDragStart", f.StartMoving)
f:SetScript("OnDragStop", function(self)
self:StopMovingOrSizing()
local p, _, rp, x, y = self:GetPoint()
if AdminToolsDB then AdminToolsDB.pos = { p, rp, x, y } end
end)
f:SetScript("OnMouseDown", function(self) self:Raise() end)
f:Hide()
tinsert(UISpecialFrames, "AdminToolsFrame") -- ESC closes
local title = MakeLabel(f, "|cFFFFD700Project Jaina|r |cFF00FFCCAdmin Tools|r |cFFFFFFFFv3.0 (Supreme GM Edition)|r", "GameFontHighlightLarge")
title:SetPoint("TOP", 0, -14)
local close = CreateFrame("Button", nil, f, "UIPanelCloseButton")
close:SetPoint("TOPRIGHT", -8, -8)
-- bottom command bar (always visible). Strata bumped to HIGH so dense tab
-- content (e.g. Tele/Travel) can never visually overlap the typed text.
local cmdLabel = MakeLabel(f, "Comando:")
cmdLabel:SetPoint("BOTTOMLEFT", 20, 18)
local cmdBox = CreateFrame("EditBox", nil, f, "InputBoxTemplate")
cmdBox:SetSize(440, 20)
cmdBox:SetPoint("LEFT", cmdLabel, "RIGHT", 8, 0)
cmdBox:SetAutoFocus(false)
cmdBox:SetFrameStrata("HIGH")
cmdBox:SetScript("OnEscapePressed", cmdBox.ClearFocus)
cmdBox:SetScript("OnEnterPressed", function(self)
RunCmd(self:GetText()); self:SetText(""); self:ClearFocus()
end)
local runBtn = MakeButton(f, "Ejecutar", 66, function()
RunCmd(cmdBox:GetText()); cmdBox:SetText("")
end)
runBtn:SetPoint("LEFT", cmdBox, "RIGHT", 8, 0)
runBtn:SetFrameStrata("HIGH")
---------------------------------------------------------------------------
-- Tabs / pages
---------------------------------------------------------------------------
local TABS = { "Tele", "Travel", "Mundo", "God", "Armería", "Char", "Party", "Bots", "Summon", "Server", "Custom" }
local pages, tabButtons = {}, {}
local function ShowPage(name)
for n, p in pairs(pages) do
if n == name then p:Show() else p:Hide() end
end
for n, b in pairs(tabButtons) do
if n == name then b:LockHighlight() else b:UnlockHighlight() end
end
if AdminToolsDB then AdminToolsDB.tab = name end
end
for i, name in ipairs(TABS) do
local b = CreateFrame("Button", nil, f, "UIPanelButtonTemplate")
b:SetSize(56, 22)
local label = name
if name == "God" then label = "|cFFFF4444God|r"
elseif name == "Armería" then label = "|cFF00FFCCArmería|r"
elseif name == "Mundo" then label = "|cFFFFFF00Mundo|r"
elseif name == "Bots" then label = "|cFF44FF44Bots|r"
end
b:SetText(label)
b:SetPoint("TOPLEFT", f, "TOPLEFT", 14 + (i - 1) * 58, -42)
b:SetScript("OnClick", function() ShowPage(name) end)
tabButtons[name] = b
local p = CreateFrame("Frame", nil, f)
p:SetPoint("TOPLEFT", f, "TOPLEFT", 18, -70)
p:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -18, 48)
p:Hide()
pages[name] = p
end
---------------------------------------------------------------------------
-- Mount menu (used by the Char tab button)
---------------------------------------------------------------------------
-- Each leaf is { "Name", ".learn <spellID>" }. A wrong ID just prints a
-- harmless "spell does not exist" - fix or add your own on the Custom tab.
local MOUNTS = {
{ "Riding Skills", {
{ "Apprentice Riding (60% ground)", ".learn 33388" },
{ "Journeyman Riding (100% ground)", ".learn 33391" },
{ "Expert Riding (150% flying)", ".learn 34090" },
{ "Artisan Riding (280% flying)", ".learn 34091" },
{ "Cold Weather Flying (Northrend)", ".learn 54197" },
} },
{ "Flying - Basic 150%", {
{ "Golden Gryphon", ".learn 32235" },
{ "Ebon Gryphon", ".learn 32239" },
{ "Snowy Gryphon", ".learn 32240" },
{ "Tawny Wind Rider", ".learn 32243" },
{ "Blue Wind Rider", ".learn 32244" },
{ "Green Wind Rider", ".learn 32245" },
} },
{ "Flying - Epic 280%", {
{ "Swift Red Gryphon", ".learn 32290" },
{ "Swift Blue Gryphon", ".learn 32242" },
{ "Swift Green Gryphon", ".learn 32292" },
{ "Swift Purple Gryphon", ".learn 32289" },
{ "Swift Green Wind Rider", ".learn 32295" },
{ "Swift Yellow Wind Rider",".learn 32297" },
{ "Swift Purple Wind Rider",".learn 32296" },
{ "Swift Flying Machine", ".learn 44153" },
} },
{ "Drakes / Proto-Drakes", {
{ "Violet Proto-Drake", ".learn 43671" },
{ "Red Proto-Drake", ".learn 59961" },
{ "Blue Proto-Drake", ".learn 59996" },
{ "Black Proto-Drake", ".learn 59976" },
{ "Time-Lost Proto-Drake", ".learn 60002" },
{ "Plagued Proto-Drake", ".learn 60021" },
{ "Albino Drake", ".learn 60025" },
{ "Bronze Drake", ".learn 59567" },
{ "Azure Drake", ".learn 59568" },
{ "Blue Drake", ".learn 59569" },
{ "Twilight Drake", ".learn 61230" },
} },
{ "Netherwing Drakes", {
{ "Veridian Netherwing Drake", ".learn 41514" },
{ "Green Netherwing Drake", ".learn 41515" },
{ "Purple Netherwing Drake", ".learn 41516" },
{ "Cobalt Netherwing Drake", ".learn 41517" },
{ "Onyx Netherwing Drake", ".learn 41518" },
{ "Azure Netherwing Drake", ".learn 41519" },
} },
{ "Ground - Special / Fun", {
{ "Big Blizzard Bear", ".learn 58983" },
{ "Swift Zhevra", ".learn 37719" },
{ "Mekgineer's Chopper", ".learn 60421" },
{ "Mechano-hog", ".learn 60424" },
{ "Traveler's Tundra Mammoth (A)", ".learn 61425" },
{ "Traveler's Tundra Mammoth (H)", ".learn 61447" },
{ "Swift Brewfest Ram", ".learn 43900" },
{ "Great Brewfest Kodo", ".learn 49379" },
{ "Headless Horseman's Mount", ".learn 48025" },
{ "Fiery Warhorse", ".learn 36702" },
{ "Reins of the Raven Lord", ".learn 41252" },
{ "Swift White Hawkstrider", ".learn 46628" },
{ "X-51 Nether-Rocket X-TREME", ".learn 46199" },
{ "Argent Hippogryph", ".learn 63844" },
{ "Quel'dorei Steed", ".learn 63643" },
} },
{ "Class Mounts", {
{ "Paladin - Warhorse", ".learn 13819" },
{ "Paladin - Charger", ".learn 23214" },
{ "Warlock - Felsteed", ".learn 5784" },
{ "Warlock - Dreadsteed", ".learn 23161" },
{ "Death Knight - Acherus Deathcharger", ".learn 48778" },
{ "Death Knight - Winged Steed", ".learn 54729" },
} },
}
---------------------------------------------------------------------------
-- Generic nested dropdown: leaves { "Text", ".cmd" }, branches { "Text", { ... } }
-- Returns an opener function that pops the menu at the cursor.
---------------------------------------------------------------------------
local function BuildMenu(globalName, dataTable)
local menu = CreateFrame("Frame", globalName, f, "UIDropDownMenuTemplate")
local function init(_, level)
if not level then return end
local data = (level == 1) and dataTable or UIDROPDOWNMENU_MENU_VALUE
if type(data) ~= "table" then return end
for _, entry in ipairs(data) do
local info = UIDropDownMenu_CreateInfo()
info.text = entry[1]
info.notCheckable = true
if type(entry[2]) == "table" then
info.hasArrow = true
info.value = entry[2]
else
local cmd = entry[2]
info.func = function() RunCmd(cmd); CloseDropDownMenus() end
end
UIDropDownMenu_AddButton(info, level)
end
end
UIDropDownMenu_Initialize(menu, init, "MENU")
return function() ToggleDropDownMenu(1, nil, menu, "cursor", 0, 0) end
end
---------------------------------------------------------------------------
-- AdminTools Core API Export (Consumed by AdminToolsArmory.lua & Ecosystem)
---------------------------------------------------------------------------
AdminTools = AdminTools or {}
AdminTools.RunCmd = RunCmd
AdminTools.MakeButton = MakeButton
AdminTools.MakeEdit = MakeEdit
AdminTools.MakeLabel = MakeLabel
AdminTools.BuildMenu = BuildMenu
AdminTools.FlowButtons = FlowButtons
AdminTools.FormRow = FormRow
AdminTools.FormRow2 = FormRow2
AdminTools.pages = pages
AdminTools.ShowPage = ShowPage
-- 5-man dungeons, grouped by expansion, ordered by level. Teleports land
-- just outside the entrance. Most are ".tele <game_tele name>"; entries that
-- TrinityCore's stock game_tele lacks use raw ".go xyz X Y Z map" coordinates
-- instead (works on any core). If a ".tele" one fails, use the Tele tab >
-- "Lookup tele" box to find your server's name and edit it here.
local DUNGEONS = {
{ "Classic", {
{ "Ragefire Chasm (13-18)", ".tele RagefireChasm" },
{ "Wailing Caverns (15-25)", ".tele TheWailingCaverns" },
{ "The Deadmines (15-25)", ".tele TheDeadmines" },
{ "Shadowfang Keep (16-26)", ".tele ShadowfangKeep" },
{ "Blackfathom Deeps (18-28)", ".tele BlackfathomDeeps" },
{ "The Stockade (22-30)", ".go xyz -8779.9 834.35 94.68 0" },
{ "Gnomeregan (24-34)", ".tele Gnomeregan" },
{ "Razorfen Kraul (25-35)", ".tele RazorfenKraul" },
{ "Scarlet Monastery (28-45)", ".tele ScarletMonastery" },
{ "Razorfen Downs (35-45)", ".tele RazorfenDowns" },
{ "Uldaman (35-45)", ".tele Uldaman" },
{ "Zul'Farrak (42-52)", ".tele ZulFarrak" },
{ "Maraudon (45-55)", ".tele Maraudon" },
{ "Sunken Temple (50-60)", ".tele TheSunkenTemple" },
{ "Blackrock Depths (52-60)", ".tele BlackrockDepths" },
{ "LBRS / UBRS (55-60)", ".tele BlackrockSpire" },
{ "Dire Maul West (55-60)", ".tele DireMaulWest" },
{ "Dire Maul North (56-60)", ".tele DireMaulNorth" },
{ "Dire Maul East (58-60)", ".tele DireMaulEast" },
{ "Scholomance (58-60)", ".tele Scholomance" },
{ "Stratholme (58-60)", ".tele Stratholme" },
} },
{ "Burning Crusade", {
{ "Hellfire Ramparts (60-62)", ".tele HellfireRamparts" },
{ "The Blood Furnace (61-64)", ".tele TheBloodFurnace" },
{ "The Slave Pens (62-64)", ".tele TheSlavePens" },
{ "The Underbog (63-65)", ".tele CoilfangReservoir" },
{ "Mana-Tombs (64-66)", ".tele ManaTombs" },
{ "Auchenai Crypts (65-67)", ".tele AuchenaiCrypts" },
{ "Old Hillsbrad (66-68)", ".tele OldHillsbradFoothills" },
{ "Sethekk Halls (67-69)", ".tele SethekkHalls" },
{ "The Steamvault (68-70)", ".tele TheSteamvault" },
{ "Shadow Labyrinth (70)", ".tele ShadowLabyrinth" },
{ "The Black Morass (70)", ".tele TheBlackMorass" },
{ "The Mechanar (70)", ".tele TheMechanar" },
{ "The Botanica (70)", ".tele TheBotanica" },
{ "The Arcatraz (70)", ".tele TheArcatraz" },
{ "The Shattered Halls (70)", ".tele TheShatteredHalls" },
{ "Magisters' Terrace (70)", ".tele MagistersTerrace" },
} },
{ "Wrath of the Lich King", {
{ "Utgarde Keep (70-72)", ".tele UtgardeKeep" },
{ "The Nexus (71-73)", ".tele TheNexus" },
{ "Azjol-Nerub (72-74)", ".tele AzjolNerub" },
{ "Ahn'kahet: Old Kingdom (73-75)", ".go xyz 3643.31 2036.51 1.79 571" },
{ "Drak'Tharon Keep (74-76)", ".tele DrakTharonKeep" },
{ "The Violet Hold (75-77)", ".tele TheVioletHold" },
{ "Gundrak (76-78)", ".tele Gundrak" },
{ "Halls of Stone (77-79)", ".go xyz 8921.91 -993.5 1039.41 571" },
{ "Halls of Lightning (78-80)", ".go xyz 9182.92 -1384.82 1110.21 571" },
{ "Utgarde Pinnacle (78-80)", ".tele UtgardePinnacle" },
{ "The Oculus (78-80)", ".go xyz 3879.96 6984.62 106.31 571" },
{ "Culling of Stratholme (78-80)", ".go xyz -8750.76 -4442.2 -199.26 1" },
{ "Trial of the Champion (80)", ".tele TrialOfTheChampion" },
{ "The Forge of Souls (80)", ".go xyz 5666.25 2009.2 798.04 571" },
{ "Pit of Saron (80)", ".go xyz 5598.74 2015.85 798.04 571" },
{ "Halls of Reflection (80)", ".go xyz 5630.44 1994.01 798.06 571" },
} },
}
local RAIDS = {
{ "Classic", {
{ "Molten Core (60)", ".tele MoltenCore" },
{ "Blackwing Lair (60)", ".go xyz -7396.4 -1070.18 589.39 469" },
{ "Zul'Gurub (60)", ".tele ZulGurub" },
{ "Ruins of Ahn'Qiraj (AQ20)", ".tele AQ20" },
{ "Temple of Ahn'Qiraj (AQ40)", ".tele AQ40" },
} },
{ "Burning Crusade", {
{ "Karazhan (70)", ".tele Karazhan" },
{ "Gruul's Lair (70)", ".tele GruulsLair" },
{ "Magtheridon's Lair (70)", ".tele MagtheridonsLair" },
{ "Serpentshrine Cavern (70)", ".tele SerpentshrineCavern" },
{ "Tempest Keep: The Eye (70)", ".tele TempestKeep" },
{ "Hyjal Summit (70)", ".tele HyjalSummit" },
{ "Black Temple (70)", ".tele BlackTemple" },
{ "Zul'Aman (70)", ".tele ZulAman" },
{ "Sunwell Plateau (70)", ".tele SunwellPlateau" },
} },
{ "Wrath of the Lich King", {
{ "Naxxramas (80)", ".go xyz 3668.72 -1262.46 243.62 571" },
{ "The Obsidian Sanctum (80)", ".tele TheObsidianSanctum" },
{ "The Eye of Eternity (80)", ".go xyz 3859.44 6989.85 152.04 571" },
{ "Ulduar (80)", ".tele Ulduar" },
{ "Trial of the Crusader (80)", ".tele TrialOfTheCrusader" },
{ "Onyxia's Lair (80)", ".tele OnyxiasLair" },
{ "Vault of Archavon (80)", ".tele VaultOfArchavon" },
{ "Icecrown Citadel (80)", ".go xyz 5873.82 2110.98 636.01 571" },
{ "The Ruby Sanctum (80)", ".tele TheRubySanctum" },
} },
}
-- One decent grinding / questing hub per ~5 levels, 1-80, faction-appropriate.
local GRIND_A = {
{ "1-6 Northshire (Elwynn)", ".tele NorthshireValley" },
{ "6-10 Goldshire (Elwynn)", ".tele Goldshire" },
{ "10-15 Sentinel Hill (Westfall)", ".tele SentinelHill" },
{ "15-20 Lakeshire (Redridge)", ".tele Lakeshire" },
{ "20-25 Darkshire (Duskwood)", ".tele Darkshire" },
{ "25-30 Astranaar (Ashenvale)", ".tele Astranaar" },
{ "30-35 Refuge Pointe (Arathi)", ".tele RefugePointe" },
{ "35-40 Rebel Camp (Stranglethorn)", ".tele RebelCamp" },
{ "40-45 Theramore (Dustwallow)", ".tele TheramoreIsle" },
{ "45-50 Gadgetzan (Tanaris)", ".tele Gadgetzan" },
{ "50-54 Marshal's Refuge (Un'Goro)", ".tele MarshalsRefuge" },
{ "53-58 Chillwind Camp (W. Plague)", ".tele ChillwindCamp" },
{ "55-60 Light's Hope (E. Plague)", ".tele LightsHopeChapel" },
{ "58-63 Honor Hold (Hellfire)", ".tele HonorHold" },
{ "62-66 Telredor (Zangarmarsh)", ".tele Telredor" },
{ "64-67 Telaar (Nagrand)", ".tele Telaar" },
{ "67-70 Sylvanaar (Blade's Edge)", ".tele Sylvanaar" },
{ "68-70 Area 52 (Netherstorm)", ".tele Area52" },
{ "70-72 Valiance Keep (Borean Tundra)", ".tele ValianceKeep" },
{ "71-73 Valgarde (Howling Fjord)", ".tele Valgarde" },
{ "73-75 Wintergarde Keep (Dragonblight)", ".tele WintergardeKeep" },
{ "74-77 Amberpine Lodge (Grizzly Hills)", ".tele AmberpineLodge" },
{ "76-78 Ebon Watch (Zul'Drak)", ".tele EbonWatch" },
{ "77-80 Nesingwary Camp (Sholazar)", ".tele NesingwaryBaseCamp" },
{ "78-80 K3 (Storm Peaks)", ".tele K3" },
{ "79-80 The Argent Vanguard (Icecrown)", ".tele TheArgentVanguard" },
}
local GRIND_H = {
{ "1-6 Valley of Trials (Durotar)", ".tele ValleyOfTrials" },
{ "6-10 Razor Hill (Durotar)", ".tele RazorHill" },
{ "10-15 The Crossroads (Barrens)", ".tele TheCrossroads" },
{ "15-20 The Sepulcher (Silverpine)", ".tele TheSepulcher" },
{ "20-25 Splintertree Post (Ashenvale)", ".tele SplintertreePost" },
{ "25-30 Tarren Mill (Hillsbrad)", ".tele TarrenMill" },
{ "30-35 Hammerfall (Arathi)", ".tele Hammerfall" },
{ "35-40 Grom'gol (Stranglethorn)", ".tele GromgolBaseCamp" },
{ "40-45 Brackenwall (Dustwallow)", ".tele BrackenwallVillage" },
{ "45-50 Gadgetzan (Tanaris)", ".tele Gadgetzan" },
{ "50-54 Bloodvenom Post (Felwood)", ".tele BloodvenomPost" },
{ "52-56 Marshal's Refuge (Un'Goro)", ".tele MarshalsRefuge" },
{ "55-58 Light's Hope (E. Plague)", ".tele LightsHopeChapel" },
{ "58-63 Thrallmar (Hellfire)", ".tele Thrallmar" },
{ "62-66 Zabra'jin (Zangarmarsh)", ".tele Zabrajin" },
{ "64-67 Garadar (Nagrand)", ".tele Garadar" },
{ "67-70 Thunderlord Stronghold (Blade's Edge)", ".tele ThunderlordStronghold" },
{ "68-70 Area 52 (Netherstorm)", ".tele Area52" },
{ "70-72 Warsong Hold (Borean Tundra)", ".tele WarsongHold" },
{ "71-73 Vengeance Landing (Howling Fjord)", ".tele VengeanceLanding" },
{ "73-75 Agmar's Hammer (Dragonblight)", ".tele AgmarsHammer" },
{ "74-77 Conquest Hold (Grizzly Hills)", ".tele ConquestHold" },
{ "76-78 Light's Breach (Zul'Drak)", ".tele LightsBreach" },
{ "77-80 Nesingwary Camp (Sholazar)", ".tele NesingwaryBaseCamp" },
{ "78-80 Camp Tunka'lo (Storm Peaks)", ".tele CampTunkaLo" },
{ "79-80 The Argent Vanguard (Icecrown)", ".tele TheArgentVanguard" },
}
-- Class trainers for the Summon tab: real Blizzard trainer NPCs, faction-
-- matched (verified against each NPC's actual faction template ID in the
-- world database) so a Horde or Alliance character can use them. Death
-- Knight has no stock spawnable trainer (DK training is special-cased at
-- Ebon Hold), so it isn't listed here.
local TRAINERS = {
{ "Alliance", {
{ "Mage", ".npc add temp 198" },
{ "Priest", ".npc add temp 375" },
{ "Warlock", ".npc add temp 459" },
{ "Hunter", ".npc add temp 895" },
{ "Warrior", ".npc add temp 911" },
{ "Rogue", ".npc add temp 915" },
{ "Paladin", ".npc add temp 925" },
{ "Shaman", ".npc add temp 17204" },
{ "Druid", ".npc add temp 5504" },
} },
{ "Horde", {
{ "Mage", ".npc add temp 5883" },
{ "Priest", ".npc add temp 6014" },
{ "Warlock", ".npc add temp 988" },
{ "Hunter", ".npc add temp 987" },
{ "Warrior", ".npc add temp 985" },
{ "Rogue", ".npc add temp 3328" },
{ "Paladin", ".npc add temp 16680" },
{ "Shaman", ".npc add temp 986" },
{ "Druid", ".npc add temp 3033" },
} },
}
local openMounts = BuildMenu("AdminToolsMountMenu", MOUNTS)
local openDungeons = BuildMenu("AdminToolsDungeonMenu", DUNGEONS)
local openRaids = BuildMenu("AdminToolsRaidMenu", RAIDS)
local openGrindA = BuildMenu("AdminToolsGrindAMenu", GRIND_A)
local openGrindH = BuildMenu("AdminToolsGrindHMenu", GRIND_H)
local openTrainers = BuildMenu("AdminToolsTrainerMenu", TRAINERS)
---------------------------------------------------------------------------
-- TELE (grouped by faction, with enemy-capital warning)
---------------------------------------------------------------------------
do
local p = pages["Tele"]
local y = -2
y = TeleSection(p, y, "Alliance", {
{ "Stormwind", "stormwind", "Alliance" },
{ "Ironforge", "ironforge", "Alliance" },
{ "Darnassus", "darnassus", "Alliance" },
{ "The Exodar","theexodar", "Alliance" },
})
y = TeleSection(p, y, "Horde", {
{ "Orgrimmar", "orgrimmar", "Horde" },
{ "Undercity", "undercity", "Horde" },
{ "Thunder Bluff", "thunderbluff", "Horde" },
{ "Silvermoon", "silvermoon", "Horde" },
})
y = TeleSection(p, y, "Neutral", {
{ "Shattrath", "shattrath", "Neutral" },
{ "Dalaran", "dalaran", "Neutral" },
{ "Booty Bay", "bootybay", "Neutral" },
{ "Gadgetzan", "gadgetzan", "Neutral" },
})
y = FormRow(p, y - 2, "Tele to:", function(t) return ".tele " .. t end)
y = FormRow(p, y, "Lookup tele:", function(t) return ".lookup tele " .. t end)
y = FormRow(p, y, "Save spot as:", function(t) return ".tele add " .. t end)
FlowButtons(p, {
{ "Recall (undo)", ".recall" },
{ "Reset Instances", ".instance unbind all" },
}, y - 4)
local note = MakeLabel(p, "Tele names come from the server's game_tele table.")
note:SetPoint("BOTTOMLEFT", p, "BOTTOMLEFT", 4, 2)
end
---------------------------------------------------------------------------
-- TRAVEL (dungeon / raid / grinding-spot dropdowns)
---------------------------------------------------------------------------
do
local p = pages["Travel"]
local defs = {
{ "Dungeons (por nivel) v", openDungeons },
{ "Raids (por nivel) v", openRaids },
{ "Zonas de Leveo - Alianza v", openGrindA },
{ "Zonas de Leveo - Horda v", openGrindH },
}
for i, d in ipairs(defs) do
local b = MakeButton(p, d[1], 260, d[2])
b:SetPoint("TOPLEFT", p, "TOPLEFT", 8, -12 - (i - 1) * 30)
end
local note = MakeLabel(p, "Teleports drop you at the entrance / hub. Dungeons are\n"
.. "not faction-locked, so both sides see the full list; grinding\n"
.. "spots are faction-specific. If a teleport fails, the name is\n"
.. "not in your server's game_tele table - use Tele tab > \"Lookup\n"
.. "tele\" to find it, then edit the tables in AdminTools.lua.")
note:SetJustifyH("LEFT")
note:SetPoint("TOPLEFT", p, "TOPLEFT", 8, -140)
end
---------------------------------------------------------------------------
-- MUNDO (Baluartes de Hermandad, Galeon de los Desertores, Lore & Nucleo)
---------------------------------------------------------------------------
do
local p = pages["Mundo"]
local y = -2
-- Seccion 1: Baluartes de Hermandad
local hB = MakeLabel(p, "Baluartes de Hermandad (Soberania y Beneficios de Guild)", "GameFontNormal")
hB:SetPoint("TOPLEFT", p, "TOPLEFT", 6, y)
y = y - 16
y = FlowButtons(p, {
{ "Censo Baluartes", ".outpost list" },
{ "Reset Todos", ".outpost reset all" },
{ "Recargar Eluna", ".reload ale" },
}, y)
y = y - 2
local hTele = MakeLabel(p, "Teletransporte a Enclaves (1-6):", "GameFontHighlightSmall")
hTele:SetPoint("TOPLEFT", p, "TOPLEFT", 6, y)
y = y - 14
y = FlowButtons(p, {
{ "1. Faro Theramore", ".outpost tele 1" },
{ "2. Costas Azshara", ".outpost tele 2" },
{ "3. Paramos Poniente", ".outpost tele 3" },
{ "4. Cabana Trabalomas",".outpost tele 4" },
{ "5. Caleta Faldir", ".outpost tele 5" },
{ "6. Costa Feralas", ".outpost tele 6" },
}, y)
y = y - 4
y = FormRow(p, y, "Reclamar Enclave (ID 1-6):", function(t) return ".outpost claim " .. t end, 100)
y = FormRow(p, y, "Reset Enclave (ID 1-6):", function(t) return ".outpost reset " .. t end, 100)
y = y - 6
-- Seccion 2: Galeon de los Desertores
local hG = MakeLabel(p, "Galeon Dinamico de los Desertores (Costa de Theramore)", "GameFontNormal")
hG:SetPoint("TOPLEFT", p, "TOPLEFT", 6, y)
y = y - 16
y = FlowButtons(p, {
{ "Estado Evento", ".galleon status" },
{ "Forzar Alarma", ".galleon alert" },
{ "Resetear Calma", ".galleon reset" },
{ "Cubierta Galeon", ".galleon tele" },
{ "Escala de Agua", ".galleon ladder" },
{ "Probar Canon", ".galleon testcannon" },
}, y)
y = y - 2
-- Seccion 3: Lore & Nucleo
local hL = MakeLabel(p, "Puntos Estrategicos Lore & Mundo:", "GameFontHighlightSmall")
hL:SetPoint("TOPLEFT", p, "TOPLEFT", 6, y)
y = y - 14
y = FlowButtons(p, {
{ "Costa Desertores", ".go 4148.6 -2441.7 4.2 0" },
{ "Lady Jaina (Thera)", ".tele theramore" },
{ "Info Servidor", ".server info" },
}, y)
end
---------------------------------------------------------------------------
-- GOD (Poder Supremo, Inmortalidad, Vuelo, Velocidad, Morphs y Trampas)
---------------------------------------------------------------------------
do
local p = pages["God"]
local y = -2
local hGod = MakeLabel(p, "Autoridad Divina & Trampas de Servidor (God Mode):", "GameFontNormal")
hGod:SetPoint("TOPLEFT", p, "TOPLEFT", 6, y)
y = y - 16
y = FlowButtons(p, {
{ "God Mode On/Off", ".cheat god" },
{ "Zero CDs (.cheat cd)", ".cheat cd" },
{ "Instant Cast", ".cheat cast" },
{ "Poder Infinito", ".cheat power" },
{ "Vuelo On", ".gm fly on" },
{ "Vuelo Off", ".gm fly off" },
{ "Invisibilidad On", ".gm visible off" },
{ "Invisibilidad Off", ".gm visible on" },
{ "Caminar Agua", ".cheat waterwalk" },
{ "Revivir", ".revive" },
{ "Morir / Suicidio", ".die" },
{ "Limpiar Auras", ".unaura all" },
{ "Max Habilidades", ".maxskill" },
{ "Explorar Mapa", ".explorecheat 1" },
{ "Limpiar CDs Target", ".cooldown clear" },
{ "Modo GM On", ".gm on" },
{ "Modo GM Off", ".gm off" },
{ "GM Chat On/Off", ".gmchat" },
}, y, 4, 150)
y = y - 4
local hSpd = MakeLabel(p, "Modificadores de Velocidad (.modify speed):", "GameFontHighlightSmall")
hSpd:SetPoint("TOPLEFT", p, "TOPLEFT", 6, y)
y = y - 16
y = FlowButtons(p, {
{ "Speed 1 (Normal)", ".modify speed 1" },
{ "Speed 2 (2x)", ".modify speed 2" },
{ "Speed 3 (3x)", ".modify speed 3" },
{ "Speed 5 (5x)", ".modify speed 5" },
{ "Speed 7 (7x)", ".modify speed 7" },
{ "Speed 10 (10x)", ".modify speed 10" },
{ "Speed 15 (15x)", ".modify speed 15" },
{ "Speed 25 (Ultra)", ".modify speed 25" },
}, y, 4, 150)
y = y - 4
local hScale = MakeLabel(p, "Modificadores de Escala & Tamaño (.modify scale):", "GameFontHighlightSmall")
hScale:SetPoint("TOPLEFT", p, "TOPLEFT", 6, y)
y = y - 16
y = FlowButtons(p, {
{ "Escala 0.25 (Mini)", ".modify scale 0.25" },
{ "Escala 0.5", ".modify scale 0.5" },
{ "Escala 1.0 (Normal)",".modify scale 1" },
{ "Escala 1.5", ".modify scale 1.5" },
{ "Escala 2.5 (Gigante)",".modify scale 2.5" },
{ "Escala 5.0 (Colosal)",".modify scale 5" },
{ "Des-transformar", ".demorph" },
{ "Lady Jaina (28227)", ".morph 28227" },
}, y, 4, 150)
y = y - 4
local hMorph = MakeLabel(p, "Metamorfosis Legendarias Rápidas:", "GameFontHighlightSmall")
hMorph:SetPoint("TOPLEFT", p, "TOPLEFT", 6, y)
y = y - 16
y = FlowButtons(p, {
{ "Lich King (29720)", ".morph 29720" },
{ "Illidan (21108)", ".morph 21108" },
{ "Sylvanas (28213)", ".morph 28213" },
{ "Ragnaros (11121)", ".morph 11121" },
}, y, 4, 150)
y = y - 2
y = FormRow(p, y, "Metamorfosis (ID):", function(t) return ".morph " .. t end, 160)
end
---------------------------------------------------------------------------
-- ARMERÍA (Live Equipment Editor, Inspección 19 slots, Gestión de Gear)
---------------------------------------------------------------------------
do
local p = pages["Armería"]
p:SetScript("OnShow", function(self)
if AdminTools and AdminTools.InitArmory then
AdminTools.InitArmory(self)
end
end)
end
---------------------------------------------------------------------------
-- CHAR (Manipulación Total de Nivel, Oro Real y Personaje / Bots)
---------------------------------------------------------------------------
do
local p = pages["Char"]
local y = -2
-- Cabecera con objetivo dinámico
local targetBanner = MakeLabel(p, "Objetivo Activo: Cargando...", "GameFontHighlightLarge")
targetBanner:SetPoint("TOPLEFT", p, "TOPLEFT", 6, y)
y = y - 20
local function UpdateCharTargetBanner()
local unit = UnitExists("target") and "target" or "player"
local name = UnitName(unit) or "Desconocido"
local lvl = UnitLevel(unit) or 0
local class = UnitClass(unit) or "Clase"
local isPlayer = UnitIsPlayer(unit)
local tag = (unit == "player") and "|cFFFFD700[TÚ MISMO]|r" or (isPlayer and "|cFF00FF00[JUGADOR / BOT]|r" or "|cFFFF8800[NPC]|r")
targetBanner:SetText(string.format("Objetivo: |cFFFFD100%s|r (%s) | Nivel: |cFFFFFFFF%s|r | Clase: |cFFFFFFFF%s|r", name, tag, (lvl > 0 and tostring(lvl) or "??"), class))
end
local watcher = CreateFrame("Frame", nil, p)
watcher:RegisterEvent("PLAYER_TARGET_CHANGED")
watcher:SetScript("OnEvent", function() UpdateCharTargetBanner() end)
p:SetScript("OnShow", function() UpdateCharTargetBanner() end)
local function GetTargetName()
if UnitExists("target") then
return UnitName("target")
end
return UnitName("player")
end
-- Sección 1: Manipulación Directa de Nivel
local hLvl = MakeLabel(p, "Manipulación de Nivel Instantáneo (.character level / .levelup):", "GameFontNormal")
hLvl:SetPoint("TOPLEFT", p, "TOPLEFT", 6, y)
y = y - 16
y = FlowButtons(p, {
{ "Fijar Nivel 80", function() RunCmd(".character level " .. GetTargetName() .. " 80") end },
{ "Fijar Nivel 70", function() RunCmd(".character level " .. GetTargetName() .. " 70") end },
{ "Fijar Nivel 60", function() RunCmd(".character level " .. GetTargetName() .. " 60") end },
{ "Fijar Nivel 1", function() RunCmd(".character level " .. GetTargetName() .. " 1") end },
{ "Nivel +1", ".levelup 1" },
{ "Nivel +5", ".levelup 5" },
{ "Nivel +10", ".levelup 10" },
{ "Nivel -1", ".levelup -1" },
}, y, 4, 150)
y = y - 2
y = FormRow(p, y, "Fijar Nivel Objetivo (1-80):", function(t)
local lvl = tonumber(t) or 80
return ".character level " .. GetTargetName() .. " " .. lvl
end, 140)
-- Sección 2: Manipulación de Oro en Unidades Reales (1 Oro = 10,000 Cobre)
local hGold = MakeLabel(p, "Economía y Oro en Unidades Reales (.modify money):", "GameFontNormal")
hGold:SetPoint("TOPLEFT", p, "TOPLEFT", 6, y)
y = y - 16
y = FlowButtons(p, {
{ "+100 Oro", ".modify money 1000000" },
{ "-100 Oro", ".modify money -1000000" },
{ "+500 Oro", ".modify money 5000000" },
{ "+1,000 Oro", ".modify money 10000000" },
{ "-1,000 Oro", ".modify money -10000000" },
{ "+5,000 Oro", ".modify money 50000000" },
{ "+10,000 Oro", ".modify money 100000000" },
{ "Oro Máx (214k)", ".modify money 2147483647" },
}, y, 4, 150)
y = y - 2
-- Formulario de oro personalizado en unidades reales
local lblGoldCustom = MakeLabel(p, "Oro a Medida (g):")
lblGoldCustom:SetPoint("TOPLEFT", p, "TOPLEFT", 6, y - 5)
local eGold = MakeEdit(p, 100)
eGold:SetPoint("TOPLEFT", p, "TOPLEFT", 122, y)
local btnGiveGold = MakeButton(p, "Dar Oro", 80, function()
local g = tonumber(strtrim(eGold:GetText() or "0")) or 0
if g > 0 then
local copper = floor(g * 10000)
RunCmd(".modify money " .. copper)
eGold:SetText("")
eGold:ClearFocus()
end
end)
btnGiveGold:SetPoint("LEFT", eGold, "RIGHT", 6, 0)
local btnTakeGold = MakeButton(p, "Quitar Oro", 80, function()
local g = tonumber(strtrim(eGold:GetText() or "0")) or 0
if g > 0 then
local copper = floor(g * 10000)
RunCmd(".modify money -" .. copper)
eGold:SetText("")
eGold:ClearFocus()
end
end)
btnTakeGold:SetPoint("LEFT", btnGiveGold, "RIGHT", 6, 0)
local btnZeroGold = MakeButton(p, "Vaciar Oro (0g)", 100, function()
RunCmd(".modify money -2147483647")
end)
btnZeroGold:SetPoint("LEFT", btnTakeGold, "RIGHT", 6, 0)
y = y - 26
-- Sección 3: Hechizos, Talentos, Bolsas y Monturas
local hSpells = MakeLabel(p, "Habilidades, Hechizos, Bolsas y Monturas:", "GameFontNormal")
hSpells:SetPoint("TOPLEFT", p, "TOPLEFT", 6, y)
y = y - 16
y = FlowButtons(p, {
{ "Aprender Hechizos", ".learn all_myspells" },
{ "Aprender Clase", ".learn all_myclass" },
{ "Aprender Talentos", ".learn all_mytalents" },
{ "Aprender Recetas", ".learn all_recipes" },
{ "Idiomas", ".learn all_lang" },
{ "Hechizos GM", ".learn all_gm" },
{ "Reset Talentos", ".reset talents" },
{ "Reset Hechizos", ".reset spells" },
{ "Reset Stats", ".reset stats" },
{ "Reparar Todo", ".repairitems" },
{ "Bolsa 22c x1", ".additem 41600 1" },
{ "Bolsas 22c x4", ".additem 41600 4" },
}, y, 4, 150)
y = y - 2
local mntBtn = MakeButton(p, "Catálogo de Monturas v", 200, openMounts)
mntBtn:SetPoint("TOPLEFT", p, "TOPLEFT", 6, y)
y = y - 28
y = FormRow2(p, y, "Añadir ítem (id cant):", function(a, b)
if b == "" then b = "1" end
return ".additem " .. a .. " " .. b
end)
y = FormRow(p, y, "Añadir Conjunto Set:", function(t) return ".additemset " .. t end)
end
---------------------------------------------------------------------------
-- PARTY (other players & moderation)
---------------------------------------------------------------------------
do
local p = pages["Party"]
local y = FlowButtons(p, {
{ "Summon My Group", ".groupsummon" }, { "Recall Target", ".recall" }, { "Kill Target", ".die" },
{ "Revive Target", ".revive" }, { "Freeze", ".freeze" }, { "Unfreeze", ".unfreeze" },
{ "Mute 1 Hour", ".mute 60" }, { "Unmute Target", ".unmute" }, { "Kick Target", ".kick" },
}, -4)
y = FormRow(p, y - 4, "Appear to:", function(t) return ".appear " .. t end)
y = FormRow(p, y, "Summon:", function(t) return ".summon " .. t end)
y = FormRow(p, y, "Player info:", function(t) return ".pinfo " .. t end)
y = FormRow(p, y, "Revive:", function(t) return ".revive " .. t end)
y = FormRow(p, y, "Kick:", function(t) return ".kick " .. t end)
end
---------------------------------------------------------------------------
-- BOTS (Gestión Táctica, Invocación y Control de Playerbots)
---------------------------------------------------------------------------
do
local p = pages["Bots"]
local y = -2
local hRdf = MakeLabel(p, "Escuadrón Automatizado para Mazmorras y Bandas:", "GameFontNormal")
hRdf:SetPoint("TOPLEFT", p, "TOPLEFT", 6, y)
y = y - 16
y = FlowButtons(p, {
{ "Auto-Llenar RDF (.rdf bots)", ".rdf bots" },
{ "Desbandar Bots (.rdf reset)", ".rdf reset" },
{ "Forzar Auto-Equipar", function() SendChatMessage("equip", "PARTY") end },
{ "Expulsar Bots (*)", ".bot remove *" },
}, y, 4, 150)
y = y - 6
local hSumm = MakeLabel(p, "Invocación Individual de Bots por Rol y Clase:", "GameFontNormal")
hSumm:SetPoint("TOPLEFT", p, "TOPLEFT", 6, y)
y = y - 16
-- Tanques
local hTank = MakeLabel(p, "Tanques:", "GameFontHighlightSmall")
hTank:SetPoint("TOPLEFT", p, "TOPLEFT", 6, y)
y = y - 14
y = FlowButtons(p, {
{ "Paladín Tanque", ".bot addclass paladin" },
{ "Guerrero Tanque", ".bot addclass warrior" },
{ "DK Tanque", ".bot addclass dk" },
{ "Druida Oso", ".bot addclass druid" },
}, y, 4, 150)
y = y - 4
-- Sanadores
local hHeal = MakeLabel(p, "Sanadores (Healers):", "GameFontHighlightSmall")
hHeal:SetPoint("TOPLEFT", p, "TOPLEFT", 6, y)
y = y - 14
y = FlowButtons(p, {
{ "Sacerdote Sagrado", ".bot addclass priest" },
{ "Druida Resto", ".bot addclass druid" },