You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

989 lines
42 KiB

local AceGUI = LibStub("AceGUI-3.0")
local MDT = MDT
local db
local tonumber,tinsert,slen,pairs,ipairs,tostring,next,type,sformat = tonumber,table.insert,string.len,pairs,ipairs,tostring,next,type,string.format
local UnitName,UnitGUID,UnitCreatureType,UnitHealthMax,UnitLevel = UnitName,UnitGUID,UnitCreatureType,UnitHealthMax,UnitLevel
--[[
How to map (OUTDATED - use python script instead):
1. /mdt devmode
2. Install Plater Mod that adds NPCs on Nameplate Added event
Tov0UTniu0)f)KJuIvstI7sL2dBnQtTsnlsK8uvzMaxNGggqaol7f(231XwZUR9XjKGZ1W5Cpx4A6m6okzgL886DXINzwRuFebgbLe(TfOKtgZpPK5ucLCdDZS5lMphp(seUC1Yz53KViNswGcict(UtEW4PKBXDPKCCgxw1KHnSkWQybiw8fHaq1lR18G0OJfPEqvoowuRLHhfDGhCided6Z7yhunWkJ4kCu8Pyr7aD9DOEB2E)dot1EKxARkdot8jqlWqC8gFS3kW1)xozYeP2dUqSGBeO6Nahm0d9N7Lx6JugotflowlfXIppiFzACABJrBkQVT)X1VJuhf0YapKMp2hCERcVbsMKmUrXrdS3vPCzei83BG7nkJdR5H1yYrha6KyXOpY7Dj2Bz)sJgAq2V9TzVTIgM)Huxd8RCdgDD1bWLMm9sswwNSVNuaUe(NBNtatfo9vMltjlHTGJd6qpXgg3H16oCnTx3xF9J7kcuYNAAsdmfkdIWpC0zQTTqUI59TWkM9hsrxGZOGwK9SDixhJ3TbRSuEPfcAUPwJpc9c4Ta)kcXbd)m48yBiDZQPtNI)4WecmI0(0rjgBttQVJa9p)
3. Call MDT:AddNPCFromUnit("mouseover") with macro to add untargetable units
4. Use Keybinds to add NPCs and patrolpaths to the map
]]
function MDT:ToggleDevMode()
db = MDT:GetDB()
db.devMode = not db.devMode
ReloadUI()
end
local function tshow(t, name, indent)
local cart -- a container
local autoref -- for self references
--[[ counts the number of elements in a table
local function tablecount(t)
local n = 0
for _, _ in pairs(t) do n = n+1 end
return n
end
]]
-- (RiciLake) returns true if the table is empty
local function isemptytable(t) return next(t) == nil end
local function basicSerialize (o)
local so = tostring(o)
if type(o) == "function" then
local info = debug.getinfo(o, "S")
-- info.name is nil because o is not a calling level
if info.what == "C" then
return sformat("%q", so .. ", C function")
else
-- the information is defined through lines
return sformat("%q", so .. ", defined in (" ..
info.linedefined .. "-" .. info.lastlinedefined ..
")" .. info.source)
end
elseif type(o) == "number" or type(o) == "boolean" then
return so
else
return sformat("%q", so)
end
end
local function addtocart (value, name, indent, saved, field)
indent = indent or ""
saved = saved or {}
field = field or name
cart = cart .. indent .. field
if type(value) ~= "table" then
cart = cart .. " = " .. basicSerialize(value) .. ";\n"
else
if saved[value] then
cart = cart .. " = {}; -- " .. saved[value]
.. " (self reference)\n"
autoref = autoref .. name .. " = " .. saved[value] .. ";\n"
else
saved[value] = name
--if tablecount(value) == 0 then
if isemptytable(value) then
cart = cart .. " = {};\n"
else
cart = cart .. " = {\n"
for k, v in pairs(value) do
k = basicSerialize(k)
local fname = sformat("%s[%s]", name, k)
field = sformat("[%s]", k)
-- three spaces between levels
addtocart(v, fname, indent .. " ", saved, field)
end
cart = cart .. indent .. "};\n"
end
end
end
end
name = name or "__unnamed__"
if type(t) ~= "table" then
return name .. " = " .. basicSerialize(t)
end
cart, autoref = "", ""
addtocart(t, name, indent)
return cart .. autoref
end
function MDT:AddNPCFromUnit(unit)
db = MDT:GetDB()
local npcId
local guid = UnitGUID(unit)
if guid then
npcId = select(6,strsplit("-", guid))
npcId = tonumber(npcId)
end
local added
for _,npcData in pairs(MDT.dungeonEnemies[db.currentDungeonIdx]) do
if npcData.id == npcId then added = true; break end
end
if npcId and not added then
local npcName = UnitName(unit)
local npcHealth = UnitHealthMax(unit)
local npcLevel = UnitLevel(unit)
local npcCreatureType = UnitCreatureType(unit)
local npcScale = 1
local npcCount = 0
tinsert(MDT.dungeonEnemies[db.currentDungeonIdx], {
name = npcName,
health = npcHealth,
level = npcLevel,
creatureType = npcCreatureType,
id = npcId,
scale = npcScale,
count = npcCount,
clones = {},
})
return npcId
end
end
local currentEnemyIdx
local currentCloneGroup
local currentTeeming
local currentInspiring
local currentPatrol
local currentBossEnemyIdx = 1
---CreateDevPanel
---Creates the dev panel which contains buttons to add npcs, objects to the map
function MDT:CreateDevPanel(frame)
db = MDT:GetDB()
frame.devPanel = AceGUI:Create("TabGroup")
local devPanel = frame.devPanel
devPanel.frame:SetFrameStrata("HIGH")
devPanel.frame:SetFrameLevel(50)
devPanel:SetTabs(
{
{text="POI", value="tab1"},
{text="Enemy", value="tab2"},
{text="Infested", value="tab3"},
{text="Week", value="tab4"},
{text="Corrupted", value="tab5"},
{text="Manage DB", value="tab6"},
}
)
devPanel:SetWidth(250)
devPanel:ClearAllPoints()
devPanel:SetPoint("TOPRIGHT",frame.topPanel,"TOPLEFT",0,0)
devPanel:SetLayout("Flow")
devPanel.frame:Hide()
MDT:FixAceGUIShowHide(devPanel)
-- function that draws the widgets for the first tab
local function DrawGroup1(container)
--mapLink Options
local option1 = AceGUI:Create("EditBox")
option1:SetLabel("Target Floor / Bot Index")
option1:SetText(1)
local option2 = AceGUI:Create("EditBox")
option2:SetLabel("Direction 1up -1d 2r -2l")
option2:SetText(1)
container:AddChild(option1)
container:AddChild(option2)
--door options
local option3 = AceGUI:Create("EditBox")
option3:SetLabel("Door Name / Connected Index")
option3:SetText("")
local option4 = AceGUI:Create("EditBox")
option4:SetLabel("Door Descripting")
option4:SetText("")
local lockedCheckbox = AceGUI:Create("CheckBox")
lockedCheckbox:SetLabel("Lockpickable")
container:AddChild(option3)
container:AddChild(option4)
container:AddChild(lockedCheckbox)
--graveyard options
local option5 = AceGUI:Create("EditBox")
option5:SetLabel("Graveyard Description")
option5:SetText("")
container:AddChild(option5)
local buttons = {
[1] = {
text="MapLink",
func=function()
if not MDT.mapPOIs[db.currentDungeonIdx] then MDT.mapPOIs[db.currentDungeonIdx] = {} end
if not MDT.mapPOIs[db.currentDungeonIdx][MDT:GetCurrentSubLevel()] then
MDT.mapPOIs[db.currentDungeonIdx][MDT:GetCurrentSubLevel()] = {}
end
local links = MDT.mapPOIs[db.currentDungeonIdx][MDT:GetCurrentSubLevel()]
local posx,posy = 300,-200
local t = tonumber(option1:GetText())
local d = tonumber(option2:GetText())
local c = tonumber(option3:GetText())
if t and d then
tinsert(links,{x=posx,y=posy,target=t,direction=d,connectionIndex=c,template="MapLinkPinTemplate",type="mapLink"})
MDT:POI_UpdateAll()
end
end,
},
[2] = {
text="Door",
func=function()
if not MDT.mapPOIs[db.currentDungeonIdx] then MDT.mapPOIs[db.currentDungeonIdx] = {} end
if not MDT.mapPOIs[db.currentDungeonIdx][MDT:GetCurrentSubLevel()] then
MDT.mapPOIs[db.currentDungeonIdx][MDT:GetCurrentSubLevel()] = {}
end
local links = MDT.mapPOIs[db.currentDungeonIdx][MDT:GetCurrentSubLevel()]
local posx,posy = 300,-200
local doorNameText = option3:GetText()
local doorDescriptionText = option4:GetText()
local lockpickableStatus = lockedCheckbox:GetValue() or nil
tinsert(links,{x=posx,y=posy,template="MapLinkPinTemplate",type="door",doorName=doorNameText,doorDescription = doorDescriptionText,lockpick=lockpickableStatus})
MDT:POI_UpdateAll()
end,
},
[3] = {
text="Graveyard",
func=function()
if not MDT.mapPOIs[db.currentDungeonIdx] then MDT.mapPOIs[db.currentDungeonIdx] = {} end
if not MDT.mapPOIs[db.currentDungeonIdx][MDT:GetCurrentSubLevel()] then
MDT.mapPOIs[db.currentDungeonIdx][MDT:GetCurrentSubLevel()] = {}
end
local links = MDT.mapPOIs[db.currentDungeonIdx][MDT:GetCurrentSubLevel()]
local posx,posy = 300,-200
local graveyardDescriptionText = option5:GetText()
tinsert(links,{x=posx,y=posy,template="DeathReleasePinTemplate",type="graveyard",graveyardDescription=graveyardDescriptionText})
MDT:POI_UpdateAll()
end,
},
[4] = {
text="General Note",
func=function()
if not MDT.mapPOIs[db.currentDungeonIdx] then MDT.mapPOIs[db.currentDungeonIdx] = {} end
if not MDT.mapPOIs[db.currentDungeonIdx][MDT:GetCurrentSubLevel()] then
MDT.mapPOIs[db.currentDungeonIdx][MDT:GetCurrentSubLevel()] = {}
end
local pois = MDT.mapPOIs[db.currentDungeonIdx][MDT:GetCurrentSubLevel()]
local posx,posy = 300,-200
local noteText = option5:GetText()
tinsert(pois,{x=posx,y=posy,template="MapLinkPinTemplate",type="generalNote",text=noteText})
MDT:POI_UpdateAll()
end,
},
[5] = {
text="Heavy Cannon",
func=function()
if not MDT.mapPOIs[db.currentDungeonIdx] then MDT.mapPOIs[db.currentDungeonIdx] = {} end
if not MDT.mapPOIs[db.currentDungeonIdx][MDT:GetCurrentSubLevel()] then
MDT.mapPOIs[db.currentDungeonIdx][MDT:GetCurrentSubLevel()] = {}
end
local pois = MDT.mapPOIs[db.currentDungeonIdx][MDT:GetCurrentSubLevel()]
local posx,posy = 300,-200
tinsert(pois,{x=posx,y=posy,template="MapLinkPinTemplate",type="heavyCannon"})
MDT:POI_UpdateAll()
end,
},
[6] = {
text="Mechagon Bot",
func=function()
if not MDT.mapPOIs[db.currentDungeonIdx] then MDT.mapPOIs[db.currentDungeonIdx] = {} end
if not MDT.mapPOIs[db.currentDungeonIdx][MDT:GetCurrentSubLevel()] then
MDT.mapPOIs[db.currentDungeonIdx][MDT:GetCurrentSubLevel()] = {}
end
local pois = MDT.mapPOIs[db.currentDungeonIdx][MDT:GetCurrentSubLevel()]
local botIndex = tonumber(option1:GetText())
local posx,posy = 400+(30*botIndex),-250
tinsert(pois,{x=posx,y=posy,template="MapLinkPinTemplate",type="mechagonBot",botIndex=botIndex})
MDT:POI_UpdateAll()
end,
},
[7] = {
text="Export to LUA",
func=function()
local export = tshow(MDT.mapPOIs[db.currentDungeonIdx],"MDT.mapPOIs[dungeonIndex]")
MDT.main_frame.ExportFrame:ClearAllPoints()
MDT.main_frame.ExportFrame:Show()
MDT.main_frame.ExportFrame:SetPoint("CENTER", MDT.main_frame,"CENTER",0,50)
MDT.main_frame.ExportFrameEditbox:SetText(export)
MDT.main_frame.ExportFrameEditbox:HighlightText(0, slen(export))
MDT.main_frame.ExportFrameEditbox:SetFocus()
end,
},
}
for buttonIdx,buttonData in ipairs(buttons) do
local button = AceGUI:Create("Button")
button:SetText(buttonData.text)
button:SetCallback("OnClick",buttonData.func)
container:AddChild(button)
end
end
-- function that draws the widgets for the second tab
local function DrawGroup2(container)
local editBoxes = {}
local countSlider
local scaleSlider
local dropdown
local function updateFields(health,level,creatureType,id,scale,count,idx)
if idx then
local data = MDT.dungeonEnemies[db.currentDungeonIdx][idx]
if not data then return end
health = data.health
level = data.level
creatureType = data.creatureType
id = data.id
scale = data.scale
count = data.count
end
editBoxes[1]:SetText(id)
editBoxes[2]:SetText(health)
editBoxes[3]:SetText(level)
editBoxes[4]:SetText(creatureType)
scaleSlider:SetValue(scale)
countSlider:SetValue(count)
end
local enemyInfoButton = AceGUI:Create("Button")
enemyInfoButton:SetText("Open Enemy Info")
enemyInfoButton:SetCallback("OnClick",function()
local devBlip = MDT:GetCurrentDevmodeBlip()
if devBlip then MDT:ShowEnemyInfoFrame(devBlip) else print("MDT DevMode: Please select a blip") end
end)
container:AddChild(enemyInfoButton)
local collectedSpellsButton = AceGUI:Create("Button")
collectedSpellsButton:SetText("Add collected spells")
collectedSpellsButton:SetCallback("OnClick",function()
MDT.DataCollection:AddCollectedDataToEnemyTable(db.currentDungeonIdx,false,true)
end)
container:AddChild(collectedSpellsButton)
local collectedCharacteristicsButton = AceGUI:Create("Button")
collectedCharacteristicsButton:SetText("Add collected characteristics")
collectedCharacteristicsButton:SetCallback("OnClick",function()
MDT.DataCollection:AddCollectedDataToEnemyTable(db.currentDungeonIdx,true,false)
end)
container:AddChild(collectedCharacteristicsButton)
local collectedHealthButton = AceGUI:Create("Button")
collectedHealthButton:SetText("Add collected Health Values")
collectedHealthButton:SetCallback("OnClick",function()
if db.newDataCollectionActive then
MDT:ProcessHealthTrack()
else
print("MDT DevMode: Cant process Health Track, reload to enable Data Collection first!")
MDT:ToggleDataCollection()
end
end)
container:AddChild(collectedHealthButton)
local cleanSpellDataButton = AceGUI:Create("Button")
cleanSpellDataButton:SetText("Clean spells")
cleanSpellDataButton:SetCallback("OnClick",function()
local blacklist = MDT:GetEnemyInfoSpellBlacklist()
for i=1,100 do
local enemies = MDT.dungeonEnemies[i]
if enemies then
for enemyIdx,enemy in pairs(enemies) do
if enemy.spells then
for spellId, spell in pairs(enemy.spells) do
if blacklist[spellId] then
enemy.spells[spellId] = nil
end
end
end
end
end
end
MDT.EnemyInfoFrame:Hide()
end)
container:AddChild(cleanSpellDataButton)
local button3 = AceGUI:Create("Button")
button3:SetText("Export to LUA")
button3:SetCallback("OnClick",function()
MDT:CleanEnemyData(db.currentDungeonIdx)
local export = tshow(MDT.dungeonEnemies[db.currentDungeonIdx],"MDT.dungeonEnemies[dungeonIndex]")
MDT.main_frame.ExportFrame:ClearAllPoints()
MDT.main_frame.ExportFrame:Show()
MDT.main_frame.ExportFrame:SetPoint("CENTER", MDT.main_frame,"CENTER",0,50)
MDT.main_frame.ExportFrameEditbox:SetText(export)
MDT.main_frame.ExportFrameEditbox:HighlightText(0, slen(export))
MDT.main_frame.ExportFrameEditbox:SetFocus()
end)
container:AddChild(button3)
local function updateDropdown(npcId,idx)
if not MDT.dungeonEnemies[db.currentDungeonIdx] then return end
idx = idx or 1
local enemies = {}
for mobIdx,data in ipairs(MDT.dungeonEnemies[db.currentDungeonIdx]) do
tinsert(enemies,mobIdx,data.name)
if npcId then
if data.id == npcId then idx = mobIdx end
end
end
dropdown:SetList(enemies)
dropdown:SetValue(idx)
currentEnemyIdx = idx
updateFields(nil,nil,nil,nil,nil,nil,idx)
end
dropdown = AceGUI:Create("Dropdown")
dropdown:SetCallback("OnValueChanged", function(widget,callbackName,key)
currentEnemyIdx = key
updateFields(nil,nil,nil,nil,nil,nil,key)
local dungeonEnemyBlips = MDT:GetDungeonEnemyBlips()
for _,v in ipairs(dungeonEnemyBlips) do
v.devSelected = nil
end
MDT:UpdateMap()
end)
container:AddChild(dropdown)
countSlider = AceGUI:Create("Slider")
countSlider:SetLabel("Count")
countSlider:SetSliderValues(0,15,1)
countSlider:SetValue(4)
countSlider:SetCallback("OnMouseUp",function(widget,callbackName,value)
local count = tonumber(value)
local npcIdx = tonumber(dropdown:GetValue())
local data = MDT.dungeonEnemies[db.currentDungeonIdx][npcIdx]
data["count"] = value
MDT:UpdateMap()
end)
container:AddChild(countSlider)
local fields = {
[1] = "id",
[2] = "health",
[3] = "level",
[4] = "creatureType",
}
for idx,name in ipairs(fields) do
editBoxes[idx] = AceGUI:Create("EditBox")
editBoxes[idx]:SetLabel(name)
editBoxes[idx]:SetCallback("OnEnterPressed",function(widget,callbackName,text)
local value = text
if name ~= "creatureType" then
value = tonumber(text)
end
local npcIdx = dropdown:GetValue()
local data = MDT.dungeonEnemies[db.currentDungeonIdx][npcIdx]
data[name] = value
MDT:UpdateMap()
end)
container:AddChild(editBoxes[idx])
end
scaleSlider = AceGUI:Create("Slider")
scaleSlider:SetLabel("Scale")
scaleSlider:SetSliderValues(0,5,0.1)
scaleSlider:SetValue(1)
scaleSlider:SetCallback("OnMouseUp",function(widget,callbackName,value)
local npcIdx = tonumber(dropdown:GetValue())
local data = MDT.dungeonEnemies[db.currentDungeonIdx][npcIdx]
data["scale"] = value
MDT:UpdateMap()
end)
container:AddChild(scaleSlider)
local button1 = AceGUI:Create("Button")
button1:SetText("Create from Target")
button1:SetCallback("OnClick",function()
local npcId = MDT:AddNPCFromUnit("target")
updateDropdown(npcId)
end)
container:AddChild(button1)
--make boss
local button2 = AceGUI:Create("Button")
button2:SetText("Make Boss")
button2:SetCallback("OnClick",function()
local currentBlip = MDT:GetCurrentDevmodeBlip()
if currentBlip then
--encounterID
local encounterID, encounterName, description, displayInfo, iconImage = EJ_GetCreatureInfo(1)
if not encounterID then
print("MDT: Error - Make sure to open Encounter Journal and navigate to the boss you want to add!")
return
end
for i=1,10000 do
local ixd = EJ_GetCreatureInfo(currentBossEnemyIdx,i)
if ixd == encounterID then
encounterID = i
break
end
end
local data = MDT.dungeonEnemies[db.currentDungeonIdx][currentBlip.enemyIdx]
data.isBoss = true
local mapID = C_Map.GetBestMapForUnit("player")
data.instanceID = mapID and EJ_GetInstanceForMap(mapID) or 0
data.encounterID = encounterID
--use this data as follows:
--if (not EncounterJournal) then LoadAddOn('Blizzard_EncounterJournal') end
--EncounterJournal_OpenJournal(23,data.instanceID,data.encounterID)
MDT:UpdateMap()
end
end)
container:AddChild(button2)
--blips movable toggle
local blipsMovableCheckbox = AceGUI:Create("CheckBox")
blipsMovableCheckbox:SetLabel("Blips Movable")
blipsMovableCheckbox:SetCallback("OnValueChanged",function (widget,callbackName,value)
db.devModeBlipsMovable = value or nil
end)
container:AddChild(blipsMovableCheckbox)
--blips scrollable toggle
local blipsScrollableCheckbox = AceGUI:Create("CheckBox")
blipsScrollableCheckbox:SetLabel("Blips Scrollable")
blipsScrollableCheckbox:SetCallback("OnValueChanged",function (widget,callbackName,value)
db.devModeBlipsScrollable = value or nil
end)
container:AddChild(blipsScrollableCheckbox)
--clone options
--group
local cloneGroup = AceGUI:Create("EditBox")
cloneGroup:SetLabel("Group of clone:")
cloneGroup:SetCallback("OnEnterPressed",function(widget,callbackName,text)
local value = tonumber(text)
if value and value>0 then currentCloneGroup = value else currentCloneGroup = nil end
local currentBlip = MDT:GetCurrentDevmodeBlip()
if currentBlip then
local data = MDT.dungeonEnemies[db.currentDungeonIdx][currentBlip.enemyIdx]
data.clones[currentBlip.cloneIdx].g = currentCloneGroup
MDT:UpdateMap()
end
end)
container:AddChild(cloneGroup)
local cloneGroupMaxButton = AceGUI:Create("Button")
cloneGroupMaxButton:SetText("New Group")
cloneGroupMaxButton:SetCallback("OnClick",function (widget,callbackName)
local maxGroup = 0
for _,data in pairs(MDT.dungeonEnemies[db.currentDungeonIdx]) do
for _,clone in pairs(data.clones) do
maxGroup = (clone.g and (clone.g>maxGroup)) and clone.g or maxGroup
end
end
currentCloneGroup = maxGroup+1
cloneGroup:SetText(currentCloneGroup)
end)
container:AddChild(cloneGroupMaxButton)
local teemingCheckbox = AceGUI:Create("CheckBox")
teemingCheckbox:SetLabel("Teeming")
teemingCheckbox:SetCallback("OnValueChanged",function(widget,callbackName,value)
currentTeeming = value and true or nil
local currentBlip = MDT:GetCurrentDevmodeBlip()
if currentBlip then
local data = MDT.dungeonEnemies[db.currentDungeonIdx][currentBlip.enemyIdx]
data.clones[currentBlip.cloneIdx].teeming = currentTeeming
MDT:UpdateMap()
end
end)
teemingCheckbox:SetValue(currentTeeming)
container:AddChild(teemingCheckbox)
--patrol
local patrolCheckbox = AceGUI:Create("CheckBox")
patrolCheckbox:SetLabel("Patrol")
patrolCheckbox:SetCallback("OnValueChanged",function(widget,callbackName,value)
currentPatrol = value or nil
local currentBlip = MDT:GetCurrentDevmodeBlip()
if currentBlip then
local data = MDT.dungeonEnemies[db.currentDungeonIdx][currentBlip.enemyIdx]
data.clones[currentBlip.cloneIdx].patrol = currentPatrol and (data.clones[currentBlip.cloneIdx].patrol or {}) or nil
if not data.clones[currentBlip.cloneIdx].patrol then
currentBlip.patrolActive = false
end
currentBlip:ShowBlipPatrol(false)
MDT:UpdateMap()
end
end)
container:AddChild(patrolCheckbox)
--stealthdetect
local stealthDetectCheckbox = AceGUI:Create("CheckBox")
stealthDetectCheckbox:SetLabel("Stealth Detect")
stealthDetectCheckbox:SetCallback("OnValueChanged",function (widget,callbackName,value)
local currentBlip = MDT:GetCurrentDevmodeBlip()
local data = MDT.dungeonEnemies[db.currentDungeonIdx][currentBlip.enemyIdx]
data.stealthDetect = value or nil
MDT:UpdateMap()
end)
container:AddChild(stealthDetectCheckbox)
--stealth
local stealthCheckbox = AceGUI:Create("CheckBox")
stealthCheckbox:SetLabel("Stealthed")
stealthCheckbox:SetCallback("OnValueChanged",function (widget,callbackName,value)
local currentBlip = MDT:GetCurrentDevmodeBlip()
local data = MDT.dungeonEnemies[db.currentDungeonIdx][currentBlip.enemyIdx]
data.stealth = value or nil
MDT:UpdateMap()
end)
container:AddChild(stealthCheckbox)
--neutral
local neutralCheckbox = AceGUI:Create("CheckBox")
neutralCheckbox:SetLabel("Neutral")
neutralCheckbox:SetCallback("OnValueChanged",function (widget,callbackName,value)
local currentBlip = MDT:GetCurrentDevmodeBlip()
local data = MDT.dungeonEnemies[db.currentDungeonIdx][currentBlip.enemyIdx]
data.neutral = value or nil
MDT:UpdateMap()
end)
container:AddChild(neutralCheckbox)
--upstairs
local upstairsCheckbox = AceGUI:Create("CheckBox")
upstairsCheckbox:SetLabel("Upstairs")
upstairsCheckbox:SetCallback("OnValueChanged",function (widget,callbackName,value)
local currentBlip = MDT:GetCurrentDevmodeBlip()
if currentBlip then
local data = MDT.dungeonEnemies[db.currentDungeonIdx][currentBlip.enemyIdx]
data.clones[currentBlip.cloneIdx].upstairs = value or nil
MDT:UpdateMap()
end
end)
container:AddChild(upstairsCheckbox)
--negative teeming
local negativeteemingCheckbox = AceGUI:Create("CheckBox")
negativeteemingCheckbox:SetLabel("Negative Teeming")
negativeteemingCheckbox:SetCallback("OnValueChanged",function (widget,callbackName,value)
local currentBlip = MDT:GetCurrentDevmodeBlip()
if currentBlip then
local data = MDT.dungeonEnemies[db.currentDungeonIdx][currentBlip.enemyIdx]
data.clones[currentBlip.cloneIdx].negativeTeeming = value or nil
MDT:UpdateMap()
end
end)
container:AddChild(negativeteemingCheckbox)
local inspiringCheckbox = AceGUI:Create("CheckBox")
inspiringCheckbox:SetLabel("Inspiring")
inspiringCheckbox:SetCallback("OnValueChanged",function(widget,callbackName,value)
currentInspiring = value and true or nil
local currentBlip = MDT:GetCurrentDevmodeBlip()
if currentBlip then
local data = MDT.dungeonEnemies[db.currentDungeonIdx][currentBlip.enemyIdx]
data.clones[currentBlip.cloneIdx].inspiring = currentInspiring
MDT:UpdateMap()
end
end)
inspiringCheckbox:SetValue(currentInspiring)
container:AddChild(inspiringCheckbox)
--faction
local faction = AceGUI:Create("EditBox")
faction:SetLabel("Faction:")
faction:SetCallback("OnEnterPressed",function(widget,callbackName,text)
local value = tonumber(text)
local currentBlip = MDT:GetCurrentDevmodeBlip()
if currentBlip then
local data = MDT.dungeonEnemies[db.currentDungeonIdx][currentBlip.enemyIdx]
data.clones[currentBlip.cloneIdx].faction = value
MDT:UpdateMap()
end
end)
container:AddChild(faction)
--sublevel
local sublevel = AceGUI:Create("EditBox")
sublevel:SetLabel("Sublevel:")
sublevel:SetCallback("OnEnterPressed",function(widget,callbackName,text)
local value = tonumber(text)
local currentBlip = MDT:GetCurrentDevmodeBlip()
if currentBlip then
local data = MDT.dungeonEnemies[db.currentDungeonIdx][currentBlip.enemyIdx]
data.clones[currentBlip.cloneIdx].sublevel = value
MDT:UpdateMap()
end
end)
container:AddChild(sublevel)
--enter clone options into the GUI (red)
local currentBlip = MDT:GetCurrentDevmodeBlip()
if currentBlip then
cloneGroup:SetText(currentBlip.clone.g)
currentCloneGroup = currentBlip.clone.g
teemingCheckbox:SetValue(currentBlip.clone.teeming)
inspiringCheckbox:SetValue(currentBlip.clone.inspiring)
currentTeeming = currentBlip.clone.teeming
currentPatrol = currentBlip.patrol and true or nil
patrolCheckbox:SetValue(currentBlip.clone.patrol)
stealthDetectCheckbox:SetValue(currentBlip.data.stealthDetect)
stealthCheckbox:SetValue(currentBlip.data.stealth)
neutralCheckbox:SetValue(currentBlip.data.neutral)
upstairsCheckbox:SetValue(currentBlip.clone.upstairs)
negativeteemingCheckbox:SetValue(currentBlip.clone.negativeTeeming)
faction:SetText(currentBlip.clone.faction)
sublevel:SetText(currentBlip.clone.sublevel)
else
cloneGroup:SetText(currentCloneGroup)
end
blipsMovableCheckbox:SetValue(db.devModeBlipsMovable)
blipsScrollableCheckbox:SetValue(db.devModeBlipsScrollable)
updateDropdown(nil,currentEnemyIdx)
end
local function DrawGroup3(container)
for i=1,12 do
local infestedCheckbox = AceGUI:Create("CheckBox")
infestedCheckbox:SetLabel("Infested Week "..i)
infestedCheckbox:SetCallback("OnValueChanged",function (widget,callbackName,value)
local currentBlip = MDT:GetCurrentDevmodeBlip()
local data = MDT.dungeonEnemies[db.currentDungeonIdx][currentBlip.enemyIdx]
data.clones[currentBlip.cloneIdx].infested = data.clones[currentBlip.cloneIdx].infested or {}
data.clones[currentBlip.cloneIdx].infested[i] = value or nil
MDT:UpdateMap()
end)
local currentBlip = MDT:GetCurrentDevmodeBlip()
if currentBlip then
infestedCheckbox:SetValue(currentBlip.clone.infested and currentBlip.clone.infested[i])
end
container:AddChild(infestedCheckbox)
end
end
local function DrawGroup4(container)
for i=1,12 do
local weekCheckbox = AceGUI:Create("CheckBox")
weekCheckbox:SetLabel("Week "..i)
weekCheckbox:SetCallback("OnValueChanged",function (widget,callbackName,value)
local currentBlip = MDT:GetCurrentDevmodeBlip()
local data = MDT.dungeonEnemies[db.currentDungeonIdx][currentBlip.enemyIdx]
data.clones[currentBlip.cloneIdx].week = data.clones[currentBlip.cloneIdx].week or {}
data.clones[currentBlip.cloneIdx].week[i] = value or nil
MDT:UpdateMap()
end)
local currentBlip = MDT:GetCurrentDevmodeBlip()
if currentBlip then
weekCheckbox:SetValue(currentBlip.clone.week and currentBlip.clone.week[i])
end
container:AddChild(weekCheckbox)
end
end
local spireNames = {
[1] = "Entropic Spire of Ny'alotha",
[2] = "Cursed Spire of Ny'alotha",
[3] = "Brutal Spire of Ny'alotha",
[4] = "Defiled Spire of Ny'alotha",
}
local function DrawGroup5(container)
local index,tooltipIndex,scale
local week = {}
local indexEditbox = AceGUI:Create("EditBox")
indexEditbox:SetLabel("Index")
indexEditbox:SetCallback("OnEnterPressed",function(widget,callbackName,text)
index = tonumber(text)
end)
container:AddChild(indexEditbox)
local tooltipIndexEditbox = AceGUI:Create("EditBox")
tooltipIndexEditbox:SetLabel("Tooltip Index")
tooltipIndexEditbox:SetCallback("OnEnterPressed",function(widget,callbackName,text)
tooltipIndex = tonumber(text)
end)
container:AddChild(tooltipIndexEditbox)
local tooltipIndexLabel = AceGUI:Create("Label")
tooltipIndexLabel:SetText("1 = Entropic Spire of Ny'alotha (Sam'rek)\n2 = Cursed Spire of Ny'alotha (Voidweaver)\n3 = Brutal Spire of Ny'alotha (Urg'roth)\n4 = Defiled Spire of Ny'alotha (Blood)\n")
container:AddChild(tooltipIndexLabel)
local scaleEditbox = AceGUI:Create("EditBox")
scaleEditbox:SetLabel("Scale")
scaleEditbox:SetCallback("OnEnterPressed",function(widget,callbackName,text)
scale = tonumber(text)
end)
container:AddChild(scaleEditbox)
for i=1,12 do
local weekCheckbox = AceGUI:Create("CheckBox")
weekCheckbox:SetLabel("Week "..i)
weekCheckbox:SetCallback("OnValueChanged",function (widget,callbackName,value)
if value then week[i] = true else week[i] = nil end
end)
container:AddChild(weekCheckbox)
end
local createSpireButton = AceGUI:Create("Button")
createSpireButton:SetText("Create Spire+NPC")
local tooltipIdxToNpcId = {
[1] = 161243,
[2] = 161241,
[3] = 161124,
[4] = 161244,
}
createSpireButton:SetCallback("OnClick",function()
if not MDT.mapPOIs[db.currentDungeonIdx] then MDT.mapPOIs[db.currentDungeonIdx] = {} end
if not MDT.mapPOIs[db.currentDungeonIdx][MDT:GetCurrentSubLevel()] then
MDT.mapPOIs[db.currentDungeonIdx][MDT:GetCurrentSubLevel()] = {}
end
local pois = MDT.mapPOIs[db.currentDungeonIdx][MDT:GetCurrentSubLevel()]
local posx,posy = 300,-200
local newWeek = MDT:DeepCopy(week)
tinsert(pois,{x=posx,y=posy,index=index,weeks=newWeek,tooltipText=spireNames[tooltipIndex],template="VignettePinTemplate",type="nyalothaSpire",scale=scale,npcId=tooltipIdxToNpcId[tooltipIndex]})
newWeek = MDT:DeepCopy(week)
MDT:POI_UpdateAll()
--add associated NPC to the map
MDT:AddCloneFromData(tooltipIdxToNpcId[tooltipIndex],newWeek)
end)
container:AddChild(createSpireButton)
end
local function DrawGroup6(container)
local clearCacheButton = AceGUI:Create("Button")
clearCacheButton:SetText("Clear Cache")
clearCacheButton:SetCallback("OnClick",function()
MDT:ResetDataCache()
db.dataCollection[db.currentDungeonIdx] = {}
db.dataCollectionCC[db.currentDungeonIdx] = {}
end)
container:AddChild(clearCacheButton)
local resetDbButton = AceGUI:Create("Button")
resetDbButton:SetText("Hard Reset DB")
resetDbButton:SetCallback("OnClick",function()
MDT:OpenConfirmationFrame(300, 150, "Reset MDT DB", "Confirm", "Do you want to reset MDT DB?", function()
MDT:HardReset()
end, "Cancel", nil)
end)
container:AddChild(resetDbButton)
local vdtDbButton = AceGUI:Create("Button")
vdtDbButton:SetText("VDT DB")
vdtDbButton:SetCallback("OnClick",function()
ViragDevTool_AddData(db)
end)
container:AddChild(vdtDbButton)
local leechButton = AceGUI:Create("Button")
leechButton:SetText("Leech Data")
leechButton:SetCallback("OnClick",function()
MDT:RequestDataCollectionUpdate()
end)
container:AddChild(leechButton)
end
-- Callback function for OnGroupSelected
local function SelectGroup(container, event, group)
container:ReleaseChildren()
if group == "tab1" then
DrawGroup1(container)
elseif group == "tab2" then
DrawGroup2(container)
elseif group == "tab3" then
DrawGroup3(container)
elseif group == "tab4" then
DrawGroup4(container)
elseif group == "tab5" then
DrawGroup5(container)
elseif group == "tab6" then
DrawGroup6(container)
end
end
devPanel:SetCallback("OnGroupSelected", SelectGroup)
devPanel:SelectTab("tab2")
--hook UpdateMap
local originalFunc = MDT.UpdateMap
function MDT:UpdateMap(...)
originalFunc(...)
local selectedTab
for k,v in pairs(devPanel.tabs) do
if v.selected == true then selectedTab = v.value; break end
end
--currentEnemyIdx
local currentBlip = MDT:GetCurrentDevmodeBlip()
if currentBlip then
currentEnemyIdx=currentBlip.enemyIdx
end
devPanel:SelectTab(selectedTab)
--show patrol
local dungeonEnemyBlips = MDT:GetDungeonEnemyBlips()
for _,v in ipairs(dungeonEnemyBlips) do
v:DisplayPatrol(v.devSelected)
end
end
end
function MDT:AddCloneFromData(npcId, weeks)
local sublevel= MDT:GetCurrentSubLevel()
local x,y = 320,-200
local data
for _,enemyData in pairs(MDT.dungeonEnemies[db.currentDungeonIdx]) do
if enemyData.id == npcId then
data = enemyData
break
end
end
if not data then
print("Could not find enemy with id "..npcId)
return
end
tinsert(data.clones,{x=x,y=y,sublevel=sublevel,week=weeks})
print(string.format("MDT: Created clone %s %d at %d,%d",data.name,#data.clones,x,y))
MDT:UpdateMap()
end
---AddCloneAtCursorPosition
---Adds a clone at the cursor position to the dungeon enemy table
---bound to hotkey and used to add new npcs to the map
function MDT:AddCloneAtCursorPosition()
if not MouseIsOver(MDTScrollFrame) then return end
if currentEnemyIdx then
local data = MDT.dungeonEnemies[db.currentDungeonIdx][currentEnemyIdx]
local cursorx,cursory = MDT:GetCursorPosition()
local scale = self:GetScale()
cursorx = cursorx*(1/scale)
cursory = cursory*(1/scale)
tinsert(data.clones,{ x=cursorx, y=cursory, sublevel= MDT:GetCurrentSubLevel(), g=currentCloneGroup, teeming=currentTeeming})
print(string.format("MDT: Created clone %s %d at %d,%d",data.name,#data.clones,cursorx,cursory))
MDT:UpdateMap()
end
end
---AddPatrolWaypointAtCursorPosition
---Adds a patrol waypoint to the selected enemy
function MDT:AddPatrolWaypointAtCursorPosition()
if not MouseIsOver(MDTScrollFrame) then return end
local currentBlip = MDT:GetCurrentDevmodeBlip()
if currentBlip then
local data = MDT.dungeonEnemies[db.currentDungeonIdx][currentBlip.enemyIdx]
local cloneData = data.clones[currentBlip.cloneIdx]
cloneData.patrol = cloneData.patrol or {}
cloneData.patrol[1] = {x=cloneData.x,y=cloneData.y}
local cursorx,cursory = MDT:GetCursorPosition()
local scale = MDT:GetScale()
cursorx = cursorx*(1/scale)
cursory = cursory*(1/scale)
--snap onto other waypoints
local patrolBlips = MDT:GetPatrolBlips()
for idx,waypoint in pairs(patrolBlips) do
if MouseIsOver(waypoint) then
cursorx = waypoint.x
cursory = waypoint.y
end
end
--snap onto blip
if MouseIsOver(currentBlip) then
cursorx = currentBlip.clone.x
cursory = currentBlip.clone.y
end
tinsert(cloneData.patrol,{x=cursorx,y=cursory})
print(string.format("MDT: Created Waypoint %d of %s %d at %d,%d",1,data.name,#cloneData.patrol,cursorx,cursory))
MDT:UpdateMap()
end
end