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.
3014 lines
148 KiB
3014 lines
148 KiB
--[[ |
|
Copyright © 2021, Sjshovan (LoTekkie) |
|
All rights reserved. |
|
|
|
Redistribution and use in source and binary forms, with or without |
|
modification, are permitted provided that the following conditions are met: |
|
|
|
* Redistributions of source code must retain the above copyright |
|
notice, this list of conditions and the following disclaimer. |
|
* Redistributions in binary form must reproduce the above copyright |
|
notice, this list of conditions and the following disclaimer in the |
|
documentation and/or other materials provided with the distribution. |
|
* Neither the name of Yield nor the |
|
names of its contributors may be used to endorse or promote products |
|
derived from this software without specific prior written permission. |
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
|
DISCLAIMED. IN NO EVENT SHALL Sjshovan (LoTekkie) BE LIABLE FOR ANY |
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
--]] |
|
|
|
_addon.name = 'Yield'; |
|
_addon.description = 'Track and edit a variety of metrics related to gathering within a simple GUI.'; |
|
_addon.author = 'Sjshovan (LoTekkie) [email protected]'; |
|
_addon.version = '1.0.3'; |
|
_addon.commands = {'/yield', '/yld'}; |
|
|
|
require 'templates'; |
|
require 'libs.baseprices'; |
|
require 'libs.zonenames'; |
|
require 'helpers'; |
|
|
|
require 'common'; |
|
require 'ffxi.enums'; |
|
require 'ffxi.vanatime'; |
|
require 'timer'; |
|
require 'd3d8'; |
|
|
|
--[[ #TODOs & Notes |
|
- cleanup code |
|
- figure out a way to scale better, use table? can we align? |
|
--]] |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- Variables |
|
---------------------------------------------------------------------------------------------------- |
|
local settings = table.copy(defaultSettingsTemplate); |
|
local state = table.copy(stateTemplate); |
|
local metrics = {}; |
|
local textures = {}; |
|
|
|
local ashitaResourceManager = AshitaCore:GetResourceManager(); |
|
local ashitaChatManager = AshitaCore:GetChatManager(); |
|
local ashitaDataManager = AshitaCore:GetDataManager(); |
|
local ashitaParty = ashitaDataManager:GetParty(); |
|
local ashitaPlayer = ashitaDataManager:GetPlayer(); |
|
local ashitaInventory = ashitaDataManager:GetInventory(); |
|
local ashitaTarget = ashitaDataManager:GetTarget(); |
|
local ashitaEntity = ashitaDataManager:GetEntity(); |
|
|
|
local gatherTypes = |
|
{ |
|
[1] = { name = "harvesting", short = "ha.", target = "Harvesting Point", tool = "sickle", toolId = 1020, action = "harvest" }, |
|
[2] = { name = "excavating", short = "ex.", target = "Excavation Point", tool = "pickaxe", toolId = 605, action = "dig up" }, |
|
[3] = { name = "logging", short = "lo.", target = "Logging Point", tool = "hatchet", toolId = 1021, action = "cut off" }, |
|
[4] = { name = "mining", short = "mi.", target = "Mining Point", tool = "pickaxe", toolId = 605, action = "dig up" }, |
|
[5] = { name = "clamming", short = "cl.", target = "Clamming Point", tool = "clamming kit", toolId = 511, action = "find" }, |
|
[6] = { name = "fishing", short = "fi.", target = nil, tool = "bait", toolId = 3, action = "caught" }, |
|
[7] = { name = "digging", short = "di.", target = nil, tool = "gysahl green", toolId = 4545, action = "dig" } |
|
} |
|
|
|
local settingsTypes = |
|
{ |
|
[1] = { name = "general" }, |
|
[2] = { name = "setPrices" }, |
|
[3] = { name = "setColors" }, |
|
[4] = { name = "setAlerts" }, |
|
[5] = { name = "reports" }, |
|
[6] = { name = "feedback" }, |
|
[7] = { name = "about" } |
|
} |
|
|
|
local helpTypes = |
|
{ |
|
[1] = { name = "generalInfo" }, |
|
[2] = { name = "commonQuestions" }, |
|
} |
|
|
|
local metricsTotalsToolTips = |
|
{ |
|
lost = "Total number of yields lost.", |
|
breaks = "Total number of broken tools.", |
|
yields = "Total successful gathers.", |
|
attempts = "Total attempts at gathering.", |
|
} |
|
|
|
local windowScales = |
|
{ |
|
[0] = 1.0; |
|
[1] = 1.15; |
|
[2] = 1.30; |
|
} |
|
|
|
local playerStorage = { available_pct = 100 }; |
|
|
|
local containers = |
|
{ |
|
inventory = 0, |
|
satchel = 5, |
|
sack = 6, |
|
case = 7, |
|
wardrobe = 8, |
|
wardrobe2 = 10, |
|
wardrobe3 = 11, |
|
wardrobe4 = 12 |
|
} |
|
|
|
local helpTable = |
|
{ |
|
commands = |
|
{ |
|
helpSeparator('=', 26), |
|
helpTitle('Commands'), |
|
helpSeparator('=', 26), |
|
helpCommandEntry('unload', 'Unload Yield.'), |
|
helpCommandEntry('reload', 'Reload Yield.'), |
|
helpCommandEntry('find', 'Move Yield to the top left corner of your screen.'); |
|
helpCommandEntry('about', 'Display information about Yield.'), |
|
helpCommandEntry('help', 'Display Yield commands.'), |
|
helpSeparator('=', 26), |
|
}, |
|
|
|
about = |
|
{ |
|
helpSeparator('=', 23), |
|
helpTitle('About'), |
|
helpSeparator('=', 23), |
|
helpTypeEntry('Name', string.format("%s by Lotekkie & Narpt", _addon.name)), |
|
helpTypeEntry('Description', _addon.description), |
|
helpTypeEntry('Author', _addon.author), |
|
helpTypeEntry('Version', _addon.version), |
|
helpTypeEntry('Support/Donate', "https://Paypal.me/Sjshovan OR For Gil donations: I play on Wings private server! (https://www.wingsxi.com/wings/) My in-game name is LoTekkie."), |
|
helpSeparator('=', 23), |
|
} |
|
} |
|
|
|
local modalConfirmPromptTemplate = "Are you sure you want to %s?"; |
|
local defaultFontSize = imgui.GetFontSize(); |
|
|
|
local sounds = { [0] = "" }; |
|
local reports = {}; |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- UI Variables |
|
--------------------------------------------------------------------------------------------------- |
|
local uiVariables = |
|
{ |
|
-- User Set |
|
["var_WindowOpacity"] = { nil, ImGuiVar_FLOAT, 1.0 }, |
|
["var_ShowToolTips"] = { nil, ImGuiVar_BOOLCPP, true }, |
|
["var_TargetValue"] = { nil, ImGuiVar_UINT32, 0 }, |
|
["var_WindowScaleIndex"] = { nil, ImGuiVar_UINT32, 0 }, |
|
["var_ShowDetailedYields"] = { nil, ImGuiVar_BOOLCPP, true }, |
|
["var_YieldDetailsColor"] = { nil, ImGuiVar_FLOATARRAY, 4 }; |
|
["var_UseImageButtons"] = { nil, ImGuiVar_BOOLCPP, true }, |
|
["var_EnableSoundAlerts"] = { nil, ImGuiVar_BOOLCPP, true }, |
|
["var_TargetSoundFile"] = { nil, ImGuiVar_CDSTRING, 128}, |
|
["var_FishingSkillSoundFile"] = { nil, ImGuiVar_CDSTRING, 128}, |
|
["var_ClamBreakSoundFile"] = { nil, ImGuiVar_CDSTRING, 128}, |
|
["var_AutoGenReports"] = { nil, ImGuiVar_BOOLCPP, true }, |
|
["var_ReportFontScale"] = { nil, ImGuiVar_FLOAT, 1.0 }, |
|
["var_WindowLocked"] = { nil, ImGuiVar_BOOLCPP, false }, |
|
|
|
-- Internal |
|
['var_WindowVisible'] = { nil, ImGuiVar_BOOLCPP, true }, |
|
['var_SettingsVisible'] = { nil, ImGuiVar_BOOLCPP, false }, |
|
["var_HelpVisible"] = { nil, ImGuiVar_BOOLCPP, false }, |
|
['var_AllSoundIndex'] = { nil, ImGuiVar_UINT32, 0 }, |
|
['var_AllColors'] = { nil, ImGuiVar_FLOATARRAY, 4 }, |
|
["var_TargetSoundIndex"] = { nil, ImGuiVar_UINT32, 0 }, |
|
["var_FishingSkillSoundIndex"] = { nil, ImGuiVar_UINT32, 0 }, |
|
["var_ClamBreakSoundIndex"] = { nil, ImGuiVar_UINT32, 0 }, |
|
["var_IssueTitle"] = { nil, ImGuiVar_CDSTRING, 256 }, |
|
["var_IssueBody"] = { nil, ImGuiVar_CDSTRING, 16384 }, |
|
['var_ReportSelected'] = { nil, ImGuiVar_INT32, nil }, |
|
} |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: loadUiVariables |
|
-- desc: Loads the ui variables from the Yield settings file. |
|
---------------------------------------------------------------------------------------------------- |
|
function loadUiVariables() |
|
-- Load the UI variables.. |
|
imgui.SetVarValue(uiVariables["var_WindowOpacity"][1], settings.general.opacity); |
|
imgui.SetVarValue(uiVariables["var_TargetValue"][1], settings.general.targetValue); |
|
imgui.SetVarValue(uiVariables["var_ShowToolTips"][1], settings.general.showToolTips); |
|
imgui.SetVarValue(uiVariables["var_WindowScaleIndex"][1], settings.general.windowScaleIndex); |
|
imgui.SetVarValue(uiVariables["var_ShowDetailedYields"][1], settings.general.showDetailedYields); |
|
imgui.SetVarValue(uiVariables["var_UseImageButtons"][1], settings.general.useImageButtons); |
|
imgui.SetVarValue(uiVariables["var_EnableSoundAlerts"][1], settings.general.enableSoundAlerts); |
|
imgui.SetVarValue(uiVariables["var_AutoGenReports"][1], settings.general.autoGenReports); |
|
|
|
local r, g, b, a = colorToRGBA(settings.general.yieldDetailsColor); |
|
imgui.SetVarValue(uiVariables["var_YieldDetailsColor"][1], r/255, g/255, b/255, a/255); |
|
|
|
for gathering, yields in pairs(settings.yields) do -- per yield |
|
for yield, data in pairs(yields) do |
|
imgui.SetVarValue(uiVariables[string.format("var_%s_%s_prices", gathering, yield)][1], data.singlePrice, data.stackPrice); |
|
local r, g, b, a = colorToRGBA(data.color); |
|
imgui.SetVarValue(uiVariables[string.format("var_%s_%s_color", gathering, yield)][1], r/255, g/255, b/255, a/255); |
|
-- re-index for file changes |
|
local soundIndex = getSoundIndex(data.soundFile); |
|
imgui.SetVarValue(uiVariables[string.format("var_%s_%s_soundIndex", gathering, yield)][1], soundIndex); |
|
local soundFile = sounds[soundIndex]; |
|
imgui.SetVarValue(uiVariables[string.format("var_%s_%s_soundFile", gathering, yield)][1], soundFile); |
|
end |
|
-- per gathering |
|
imgui.SetVarValue(uiVariables[string.format("var_%s_priceMode", gathering)][1], settings.priceModes[gathering]); |
|
end |
|
|
|
for gathering, data in pairs(metrics) do -- per metric |
|
imgui.SetVarValue(uiVariables[string.format("var_%s_estimatedValue", gathering)][1], data.estimatedValue); |
|
end |
|
|
|
-- target sound file |
|
local soundIndex = getSoundIndex(settings.general.targetSoundFile); |
|
imgui.SetVarValue(uiVariables["var_TargetSoundIndex"][1], soundIndex); |
|
local soundFile = sounds[soundIndex]; |
|
imgui.SetVarValue(uiVariables["var_TargetSoundFile"][1], soundFile); |
|
|
|
-- fishing skill sound file |
|
soundIndex = getSoundIndex(settings.general.fishingSkillSoundFile); |
|
imgui.SetVarValue(uiVariables["var_FishingSkillSoundIndex"][1], soundIndex); |
|
soundFile = sounds[soundIndex]; |
|
imgui.SetVarValue(uiVariables["var_FishingSkillSoundFile"][1], soundFile); |
|
|
|
-- clam break sound file |
|
soundIndex = getSoundIndex(settings.general.clamBreakSoundFile); |
|
imgui.SetVarValue(uiVariables["var_ClamBreakSoundIndex"][1], soundIndex); |
|
soundFile = sounds[soundIndex]; |
|
imgui.SetVarValue(uiVariables["var_ClamBreakSoundFile"][1], soundFile); |
|
|
|
-- All colors |
|
local r, g, b, a = colorToRGBA(-3877684); |
|
imgui.SetVarValue(uiVariables["var_AllColors"][1], r/255, g/255, b/255, a/255); |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: updatePlotPoints |
|
-- desc: Update the display of all plots every second. |
|
---------------------------------------------------------------------------------------------------- |
|
function updatePlotPoints() |
|
if state.timers[state.gathering] then |
|
totalSecs = metrics[state.gathering].secondsPassed |
|
metrics[state.gathering].secondsPassed = totalSecs + 1 |
|
local timeSpan = 3600 -- one hour |
|
local timePassed = metrics[state.gathering].secondsPassed |
|
local pointsWindowMax = 60 -- one min |
|
local yieldsOverTime = metrics[state.gathering].totals.yields * (timeSpan / timePassed) |
|
local valueOverTime = metrics[state.gathering].estimatedValue * (timeSpan / timePassed) |
|
if totalSecs >= pointsWindowMax then |
|
table.remove(metrics[state.gathering].points.yields, 2) |
|
table.remove(metrics[state.gathering].points.values, 2) |
|
end |
|
table.insert(metrics[state.gathering].points.yields, yieldsOverTime) |
|
table.insert(metrics[state.gathering].points.values, valueOverTime) |
|
end |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: updatePlayerStorage |
|
-- desc: Update the global playerStorage table with gathering tool counts and available inventory space every second. |
|
---------------------------------------------------------------------------------------------------- |
|
function updatePlayerStorage() |
|
local storage = {}; |
|
for _, data in ipairs(gatherTypes) do |
|
if data.name ~= "clamming" then |
|
local itemId = data.toolId; |
|
if data.name == "fishing" then -- check equipment (for fishing bait) |
|
local item = ashitaInventory:GetEquippedItem(data.toolId); |
|
if item then |
|
itemId = getItemIdFromContainers(item.ItemIndex, containers); |
|
end |
|
end |
|
storage[data.tool] = getItemCountFromContainers(itemId, containers); |
|
else -- clamming (key item) |
|
if (AshitaCore:GetDataManager():GetPlayer():HasKeyItem(data.toolId)) then |
|
storage[data.tool] = 1 |
|
else |
|
storage[data.tool] = 0 |
|
end |
|
end |
|
end |
|
storage["available"], storage["available_pct"] = getAvailableStorageFromContainers({0}); |
|
playerStorage = storage; |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: getPrice |
|
-- desc: Get the price for the given yield based on user settings. |
|
---------------------------------------------------------------------------------------------------- |
|
function getPrice(itemName, gatherType) |
|
if gatherType == nil then gatherType = state.gathering; end |
|
local data = settings.yields[gatherType][itemName]; |
|
local price = data.singlePrice or 0; |
|
switch(settings.priceModes[gatherType]) : caseof |
|
{ |
|
[0] = function() price = data.stackPrice / data.stackSize or 0 end, -- stackPrice |
|
[2] = function() price = basePrices[data.id] or 0 end, -- NPCPrice |
|
} |
|
return math.floor(price); |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: adjTotal |
|
-- desc: Modify the "total" metric by the value given. |
|
---------------------------------------------------------------------------------------------------- |
|
function adjTotal(metricName, val) |
|
local total = metrics[state.gathering].totals[metricName] |
|
if total == nil then total = 0 end |
|
metrics[state.gathering].totals[metricName] = total + val |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: adjYield |
|
-- desc: Modify the "yield" metric by the value given. |
|
---------------------------------------------------------------------------------------------------- |
|
function adjYield(yieldName, val) |
|
local yield = metrics[state.gathering].yields[yieldName] |
|
if yield == nil then yield = 0 end |
|
metrics[state.gathering].yields[yieldName] = yield + val |
|
return metrics[state.gathering].yields[yieldName]; |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: recordCurrentZone |
|
-- desc: Get the current zone and append it to the zones table. |
|
---------------------------------------------------------------------------------------------------- |
|
function recordCurrentZone() |
|
local zoneId = getPlayerZoneId(); |
|
if not table.hasvalue(settings.zones[state.gathering], zoneId) then |
|
table.insert(settings.zones[state.gathering], zoneId); |
|
end |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: calcTargetProgress |
|
-- desc: Calculate and normalize the value of progress towards reaching the target value. |
|
---------------------------------------------------------------------------------------------------- |
|
function calcTargetProgress() |
|
local progress = metrics[state.gathering].estimatedValue/settings.general.targetValue |
|
if progress == math.huge or progress ~= progress then progress = 0.0 end |
|
if progress < 0 then progress = 0.0 end |
|
if progress > 1.0 then progress = 1.0 end |
|
return progress |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: getGatherTypeData |
|
-- desc: Obtain a table of gathering related data. |
|
---------------------------------------------------------------------------------------------------- |
|
function getGatherTypeData() |
|
for _, data in ipairs(gatherTypes) do |
|
if data.name == state.gathering then |
|
return data; |
|
end |
|
end |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: getItemCountFromContainers |
|
-- desc: Obtain a count of the given item within the given container types. |
|
---------------------------------------------------------------------------------------------------- |
|
function getItemCountFromContainers(itemId, containers) |
|
itemCount = 0; |
|
for containerName, containerId in pairs(containers) do |
|
for i = 0, ashitaInventory:GetContainerMax(containerId), 1 do -- check containers |
|
local entry = ashitaInventory:GetItem(containerId, i); |
|
if entry then |
|
if entry.Id == itemId and entry.Id ~= 0 and entry.Id ~= 65535 then |
|
local item = ashitaResourceManager:GetItemById(entry.Id); |
|
if item then |
|
local quantity = 1; |
|
if entry.Count and item.StackSize > 1 then |
|
quantity = entry.Count; |
|
end |
|
itemCount = itemCount + quantity; |
|
end |
|
end |
|
end |
|
end |
|
end |
|
return itemCount; |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: getItemPriceFromContainers |
|
-- desc: Obtain the price of a given item from within the given container types. |
|
---------------------------------------------------------------------------------------------------- |
|
function getItemPriceFromContainers(itemId, containers) |
|
for containerName, containerId in pairs(containers) do |
|
for i = 0, ashitaInventory:GetContainerMax(containerId), 1 do -- check containers |
|
local entry = ashitaInventory:GetItem(containerId, i); |
|
if entry then |
|
if entry.Id == itemId and entry.Id ~= 0 and entry.Id ~= 65535 then |
|
return entry.Price; |
|
end |
|
end |
|
end |
|
end |
|
return 0; |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: getItemIdFromContainers |
|
-- desc: Obtain an item ID from the given item index, checks within given container types. |
|
---------------------------------------------------------------------------------------------------- |
|
function getItemIdFromContainers(itemIndex, containers) |
|
itemId = nil; |
|
for containerName, containerId in pairs(containers) do |
|
for i = 0, ashitaInventory:GetContainerMax(containerId), 1 do -- check containers |
|
local entry = ashitaInventory:GetItem(containerId, i); |
|
if entry then |
|
if entry.Index == itemIndex then |
|
return entry.Id; |
|
end |
|
end |
|
end |
|
end |
|
return itemId; |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: getAvailableStorageFromContainers |
|
-- desc: Obtain the available storage space from within the given container types. |
|
---------------------------------------------------------------------------------------------------- |
|
function getAvailableStorageFromContainers(containers) |
|
total = 0; |
|
available = 0; |
|
for _, containerId in pairs(containers) do |
|
local max = ashitaInventory:GetContainerMax(containerId) - 1; |
|
local used = 0; |
|
total = total + max; |
|
for i = 0, max, 1 do |
|
local entry = ashitaInventory:GetItem(containerId, i); |
|
if entry then |
|
if entry.Id > 0 and entry.Id < 65535 then |
|
used = used + 1; |
|
end |
|
end |
|
end |
|
available = available + (max - used); |
|
end |
|
return available, math.floor(available/total*100); -- pct |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: sortKeysByTotalValue |
|
-- desc: Sort yields based on their total value. |
|
---------------------------------------------------------------------------------------------------- |
|
function table.sortKeysByTotalValue(t, desc) |
|
local ret = {} |
|
for k, v in pairs(t) do |
|
table.insert(ret, k) |
|
end |
|
local totalA = function(a, b) return math.floor(getPrice(a) * metrics[state.gathering].yields[a]); end; |
|
local totalB = function(a, b) return math.floor(getPrice(b) * metrics[state.gathering].yields[b]); end; |
|
if (desc) then |
|
table.sort(ret, function(a, b) return totalA(a, b) < totalB(a, b); end); |
|
else |
|
table.sort(ret, function(a, b) return totalA(a, b) > totalB(a, b); end); |
|
end |
|
return ret; |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: updateAllStates |
|
-- desc: Set all tracked gathering states to the given state. |
|
---------------------------------------------------------------------------------------------------- |
|
function updateAllStates(newState) |
|
state.gathering = newState; |
|
state.settings.setPrices.gathering = newState; |
|
state.settings.setColors.gathering = newState; |
|
state.settings.setAlerts.gathering = newState; |
|
state.settings.reports.gathering = newState; |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: getSoundOptions |
|
-- desc: Obtain a formatted string of sound options used for sound selection drop-downs. |
|
---------------------------------------------------------------------------------------------------- |
|
function getSoundOptions() |
|
local options = "None\0"; |
|
for i, file in pairs(sounds) do |
|
options = options..file.."\0"; |
|
end |
|
return options.."\0"; |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: alertYield |
|
-- desc: Play the user set sound for the given yield if alerts are enabled. |
|
---------------------------------------------------------------------------------------------------- |
|
function alertYield(yieldName) |
|
local yieldData = settings.yields[state.gathering][yieldName]; |
|
if yieldData.soundFile ~= "" then |
|
return playAlert(yieldData.soundFile); |
|
end |
|
return false; |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: playAlert |
|
-- desc: Play the given sound file if alerts are enabled. |
|
---------------------------------------------------------------------------------------------------- |
|
function playAlert(soundFile) |
|
if settings.general.enableSoundAlerts then |
|
playSound(soundFile); |
|
return true; |
|
end |
|
return false; |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: playSound |
|
-- desc: Play the given sound file. |
|
---------------------------------------------------------------------------------------------------- |
|
function playSound(soundFile) |
|
if soundFile ~= "" then |
|
ashita.misc.play_sound(string.format(_addon.path.."sounds\\%s", soundFile)); |
|
end |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: getSoundIndex |
|
-- desc: Obtain the stored table index of the given sound file name. |
|
---------------------------------------------------------------------------------------------------- |
|
function getSoundIndex(fileName) |
|
for i, file in pairs(sounds) do |
|
if fileName == file then |
|
return i; |
|
end |
|
end |
|
return 0; |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: checkTargetAlertReady |
|
-- desc: Check if we should play the target value alert. |
|
---------------------------------------------------------------------------------------------------- |
|
function checkTargetAlertReady() |
|
state.values.targetAlertReady = metrics[state.gathering].estimatedValue < settings.general.targetValue; |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: sendIssue |
|
-- desc: Send an issue or feedback to github issues. |
|
---------------------------------------------------------------------------------------------------- |
|
function sendIssue(title, body) |
|
io.popen(string.format('%s "%s" "%s"', _addon.path .. "tools\\sendissue.exe", title, body)); |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: fileExists |
|
-- desc: Check if the given file exits. |
|
---------------------------------------------------------------------------------------------------- |
|
function fileExists(file) |
|
local f = io.open(file, "rb") |
|
if f then f:close() end |
|
return f ~= nil |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: linesFrom |
|
-- desc: Obtain lines from the given file. |
|
---------------------------------------------------------------------------------------------------- |
|
function linesFrom(file) |
|
if not fileExists(file) then return {} end |
|
lines = {} |
|
for line in io.lines(file) do |
|
lines[#lines + 1] = line |
|
end |
|
return lines |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: getPlayerName |
|
-- desc: Obtain the current players name. |
|
---------------------------------------------------------------------------------------------------- |
|
function getPlayerName(lower) |
|
local name = ashitaParty:GetMemberName(0); |
|
if lower then |
|
name = string.lower(name); |
|
end |
|
return name |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: getPlayerZoneId |
|
-- desc: Obtain the current zone ID. |
|
---------------------------------------------------------------------------------------------------- |
|
function getPlayerZoneId() |
|
return ashitaParty:GetMemberZone(0); |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: generateGatheringReport |
|
-- desc: Generate a report file using tracked metrics. |
|
---------------------------------------------------------------------------------------------------- |
|
function generateGatheringReport(gatherType) |
|
if gatherType == nil then gatherType = state.gathering; end |
|
if getPlayerName() == "" then return false; end |
|
local zones = settings.zones[gatherType]; |
|
local zonesCount = table.count(zones); |
|
local metrics = metrics[gatherType]; |
|
local zoneName = zoneNames[getPlayerZoneId()]; |
|
if zonesCount > 0 then -- there has been some activity here. |
|
zoneName = zoneNames[zones[1]]; |
|
if zonesCount > 1 then zoneName = "Multiple Zones"; end |
|
end |
|
zoneName = string.gsub(zoneName, " ", "_"); |
|
local sep = "------------\n"; |
|
local date = os.date('*t'); |
|
local dateTimeStamp = string.format("%.4d_%.2d_%.2d__%.2d_%.2d_%.2d", date.year, date.month, date.day, date.hour, date.min, date.sec); |
|
local fname = string.format('%s__%s.log', zoneName, dateTimeStamp); |
|
local fpath = string.format('%s/%s/%s/%s', _addon.path, 'reports', getPlayerName(), gatherType); |
|
if (not ashita.file.dir_exists(fpath)) then |
|
ashita.file.create_dir(fpath); |
|
end |
|
local file = io.open(string.format('%s/%s', fpath, fname), 'w+'); |
|
if (file ~= nil) then |
|
local dateTimeStampNice = string.format("%.4d-%.2d-%.2d %.2d:%.2d:%.2d", date.year, date.month, date.day, date.hour, date.min, date.sec); |
|
file:write(string.format("%s YIELD REPORT : [%s]\n", string.upper(gatherType), dateTimeStampNice)); |
|
file:write(sep); |
|
file:write("ZONES\n"); |
|
file:write(sep); |
|
if zonesCount > 1 then |
|
for i, id in ipairs(settings.zones[gatherType]) do |
|
local zoneName = zoneNames[id]; |
|
file:write("\t"..zoneName.."\n"); |
|
end |
|
else |
|
file:write("\t"..zoneName.."\n"); |
|
end |
|
file:write(sep); |
|
file:write("METRICS\n"); |
|
file:write(sep); |
|
for name, val in pairs(metrics.totals) do |
|
file:write(string.format("\t%s: %s\n", name, val)); |
|
end |
|
local successRate = metrics.totals.yields/metrics.totals.attempts * 100 |
|
if successRate == math.huge or successRate ~= successRate then successRate = 0.0 end |
|
if successRate < 0 then successRate = 0.0 end |
|
file:write(string.format("\tSuccess Rate: %.2f%%\n", successRate, 0, 100)); |
|
file:write(string.format("\tTime Passed: %s\n", os.date("!%X", (metrics.secondsPassed)))); |
|
file:write(string.format("\tEstimated Value: %s\n", metrics.estimatedValue)); |
|
file:write(string.format("\tYields per Hour: %.2f\n", metrics.points.yields[#metrics.points.yields])); |
|
file:write(string.format("\tValue per Hour: %.2f\n", metrics.points.values[#metrics.points.values])); |
|
file:write(string.format("\tTarget Value: %s\n", settings.general.targetValue)); |
|
local targetReached = metrics.estimatedValue >= settings.general.targetValue; |
|
local targetReachedAnswer = "No"; |
|
if targetReached then targetReachedAnswer = "Yes"; end |
|
file:write(string.format("\tTarget Reached: %s\n", targetReachedAnswer)); |
|
file:write(sep); |
|
file:write("YIELDS\n"); |
|
file:write(sep); |
|
if table.count(metrics.yields) > 0 then |
|
for name, count in pairs(metrics.yields) do |
|
file:write(string.format("\t%s: %s %s\n", name, count, string.format("@%dea.=(%s)", getPrice(name, gatherType), math.floor(getPrice(name, gatherType) * metrics.yields[name])))); |
|
end |
|
else |
|
file:write("\tNone"); |
|
end |
|
file:close(); |
|
reports[gatherType][#reports[gatherType] + 1] = fname; |
|
return true; |
|
end |
|
return false; |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: saveSettings |
|
-- desc: Saves the Yield settings file. |
|
---------------------------------------------------------------------------------------------------- |
|
function saveSettings() |
|
-- Obtain the configuration variables.. |
|
settings.general.opacity = imgui.GetVarValue(uiVariables["var_WindowOpacity"][1]); |
|
settings.general.targetValue = imgui.GetVarValue(uiVariables["var_TargetValue"][1]); |
|
settings.general.showToolTips = imgui.GetVarValue(uiVariables["var_ShowToolTips"][1]); |
|
settings.general.windowScaleIndex = imgui.GetVarValue(uiVariables["var_WindowScaleIndex"][1]); |
|
settings.general.yieldDetailsColor = colorTableToInt(imgui.GetVarValue(uiVariables["var_YieldDetailsColor"][1])); |
|
settings.general.useImageButtons = imgui.GetVarValue(uiVariables["var_UseImageButtons"][1]); |
|
settings.general.enableSoundAlerts = imgui.GetVarValue(uiVariables["var_EnableSoundAlerts"][1]); |
|
settings.general.targetSoundFile = imgui.GetVarValue(uiVariables["var_TargetSoundFile"][1]); |
|
settings.general.fishingSkillSoundFile = imgui.GetVarValue(uiVariables["var_FishingSkillSoundFile"][1]); |
|
settings.general.clamBreakSoundFile = imgui.GetVarValue(uiVariables["var_ClamBreakSoundFile"][1]); |
|
settings.general.autoGenReports = imgui.GetVarValue(uiVariables["var_AutoGenReports"][1]); |
|
|
|
for gathering, yields in pairs(settings.yields) do |
|
for yield, data in pairs(yields) do |
|
local yieldSettings = settings.yields[gathering][yield]; |
|
local prices = imgui.GetVarValue(uiVariables[string.format("var_%s_%s_prices", gathering, yield)][1]); |
|
yieldSettings.singlePrice = prices[1]; |
|
yieldSettings.stackPrice = prices[2]; |
|
yieldSettings.color = colorTableToInt(imgui.GetVarValue(uiVariables[string.format("var_%s_%s_color", gathering, yield)][1])); |
|
yieldSettings.soundFile = imgui.GetVarValue(uiVariables[string.format("var_%s_%s_soundFile", gathering, yield)][1]); |
|
end |
|
settings.priceModes[gathering] = imgui.GetVarValue(uiVariables[string.format("var_%s_priceMode", gathering)][1]); |
|
end |
|
|
|
for _, data in ipairs(gatherTypes) do |
|
metrics[data.name].estimatedValue = tonumber(imgui.GetVarValue(uiVariables[string.format("var_%s_estimatedValue", data.name)][1])) |
|
end |
|
|
|
-- Obtain the metrics.. |
|
settings.metrics = table.copy(metrics); |
|
|
|
-- Obtain the state.. |
|
settings.state.gathering = state.gathering; |
|
settings.state.lastKnownGathering = state.values.lastKnownGathering; |
|
settings.state.windowPosX = state.window.posX; |
|
settings.state.windowPosY = state.window.posY; |
|
settings.state.clamBucketBroken = state.values.clamBucketBroken; |
|
settings.state.clamConfirmedYields = state.values.clamConfirmedYields; |
|
settings.state.clamBucketTotal = state.values.clamBucketTotal; |
|
settings.state.clamBucketPz = state.values.clamBucketPz; |
|
settings.state.clamBucketPzMax = state.values.clamBucketPzMax; |
|
settings.state.firstLoad = state.firstLoad; |
|
|
|
-- Save the configuration variables.. |
|
ashita.settings.save(_addon.path .. 'settings/settings.json', settings); |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: load |
|
-- desc: Called when the addon is loaded. |
|
---------------------------------------------------------------------------------------------------- |
|
ashita.register_event('load', function() |
|
state.initializing = true |
|
|
|
-- Ensure the settings folder exists.. |
|
ashita.file.create_dir(_addon.path .. '/settings/'); |
|
ashita.file.create_dir(_addon.path .. '/reports/'); |
|
ashita.file.create_dir(_addon.path .. '/reports/' .. getPlayerName()); |
|
|
|
-- Load and merge the users settings.. |
|
settings = ashita.settings.load_merged( |
|
_addon.path .. '/settings/settings.json', settings |
|
) |
|
|
|
-- loop through gathering types.. |
|
for _, data in ipairs(gatherTypes) do |
|
-- Populate the metrics table.. |
|
if table.haskey(settings.metrics, data.name) then |
|
metrics[data.name] = table.copy(settings.metrics[data.name]); |
|
else |
|
metrics[data.name] = table.copy(metricsTemplate); |
|
end |
|
-- Initialize state timers.. |
|
state.timers[data.name] = false; |
|
-- Add estimated value ui variables... |
|
uiVariables[string.format("var_%s_estimatedValue", data.name)] = { nil, ImGuiVar_UINT32, 0 } |
|
-- Add textures.. |
|
local texturePath = string.format('images\\%s.png', data.name) |
|
local hres, texture = ashita.d3dx.CreateTextureFromFileA(_addon.path .. texturePath); |
|
|
|
if texture == nil then |
|
state.values.btnTextureFailure = true; |
|
displayResponse(string.format("Yield: Failed to load texture (%s). Buttons will now default to text display.", texturePath), "\31\167%s"); |
|
imgui.SetVarValue(uiVariables["var_UseImageButtons"][1], false); |
|
end |
|
textures[data.name] = texture; |
|
end |
|
|
|
-- Update saved gathering state.. |
|
updateAllStates(settings.state.gathering); |
|
|
|
-- misc state updates.. |
|
checkTargetAlertReady(); |
|
state.values.lastKnownGathering = settings.state.lastKnownGathering; |
|
state.window.posX = settings.state.windowPosX; |
|
state.window.posY = settings.state.windowPosY; |
|
state.values.clamBucketBroken = settings.state.clamBucketBroken; |
|
state.values.clamConfirmedYields = settings.state.clamConfirmedYields; |
|
state.values.clamBucketTotal = settings.state.clamBucketTotal; |
|
state.values.clamBucketPz = settings.state.clamBucketPz; |
|
state.values.clamBucketPzMax = settings.state.clamBucketPzMax; |
|
state.firstLoad = settings.state.firstLoad; |
|
|
|
-- Add price ui variables from settings.. |
|
for gathering, yields in pairs(settings.yields) do |
|
for yield, data in pairs(yields) do -- per yield |
|
uiVariables[string.format("var_%s_%s_prices", gathering, yield)] = { nil, ImGuiVar_INT32ARRAY, 2 }; |
|
uiVariables[string.format("var_%s_%s_color", gathering, yield)] = { nil, ImGuiVar_FLOATARRAY, 4 }; |
|
uiVariables[string.format("var_%s_%s_soundFile", gathering, yield)] = { nil, ImGuiVar_CDSTRING, 128 }; |
|
uiVariables[string.format("var_%s_%s_soundIndex", gathering, yield)] = { nil, ImGuiVar_UINT32, 0 }; |
|
end |
|
-- per gathering |
|
uiVariables[string.format("var_%s_priceMode", gathering)] = { nil, ImGuiVar_UINT32, 0 }; |
|
end |
|
|
|
-- Retrieve sounds files.. |
|
for f in io.popen(string.format('dir "%s\\sounds" /b', _addon.path)):lines() do |
|
sounds[#sounds + 1] = f; |
|
end |
|
|
|
-- Retrieve reports.. |
|
for _, data in ipairs(gatherTypes) do |
|
if not table.haskey(reports, data.name) then reports[data.name] = {}; end |
|
if getPlayerName() ~= "" then |
|
local dirName = string.format("%s\\reports\\%s\\%s", _addon.path, getPlayerName(), data.name); |
|
if ashita.file.dir_exists(dirName) then |
|
for f in io.popen(string.format("dir %s /b", dirName)):lines() do |
|
reports[data.name][#reports[data.name] + 1] = f; |
|
end |
|
else |
|
ashita.file.create_dir(dirName); |
|
end |
|
state.reportsLoaded = true; |
|
end |
|
end |
|
|
|
-- Create timers.. |
|
if ashita.timer.create_timer("updatePlotPoints") then |
|
ashita.timer.adjust_timer("updatePlotPoints", 1, 0, updatePlotPoints) |
|
ashita.timer.start_timer("updatePlotPoints") |
|
end |
|
if ashita.timer.create_timer("updatePlayerStorage") then |
|
ashita.timer.adjust_timer("updatePlayerStorage", 1, 0, updatePlayerStorage) |
|
ashita.timer.start_timer("updatePlayerStorage") |
|
end |
|
|
|
if ashita.timer.create_timer("inactivityCheck") then |
|
ashita.timer.adjust_timer("inactivityCheck", 1, 0, function() |
|
if state.timers[state.gathering] then |
|
state.values.inactivitySeconds = state.values.inactivitySeconds + 1; |
|
if state.values.inactivitySeconds == 300 then -- 5min |
|
for _, data in ipairs(gatherTypes) do |
|
state.timers[data.name] = false; -- shutdown timers |
|
end |
|
displayResponse("Yield: Timers halted due to inactivity.", "\31\140%s"); |
|
end |
|
else |
|
state.values.inactivitySeconds = 0; |
|
end |
|
if state.attempting then |
|
state.values.inactivitySeconds = 0; |
|
end |
|
end) |
|
ashita.timer.start_timer("inactivityCheck") |
|
end |
|
|
|
-- Initialize custom variables.. |
|
for varName, data in pairs(uiVariables) do |
|
if (data[2] >= ImGuiVar_CDSTRING) then |
|
uiVariables[varName][1] = imgui.CreateVar(uiVariables[varName][2], uiVariables[varName][3]); |
|
else |
|
uiVariables[varName][1] = imgui.CreateVar(uiVariables[varName][2]); |
|
end |
|
if (#data > 2 and data[2] < ImGuiVar_CDSTRING) then |
|
imgui.SetVarValue(uiVariables[varName][1], uiVariables[varName][3]); |
|
end |
|
end |
|
|
|
-- Load ui variables from the settings file.. |
|
loadUiVariables(); |
|
|
|
if state.firstLoad then |
|
imgui.SetVarValue(uiVariables["var_HelpVisible"][1], true); |
|
end |
|
end) |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: unload |
|
-- desc: Called when the addon is unloaded. |
|
---------------------------------------------------------------------------------------------------- |
|
ashita.register_event('unload', function() |
|
-- Save the settings file.. |
|
saveSettings(); |
|
|
|
-- Remove timers.. |
|
ashita.timer.remove_timer("updatePlotPoints"); |
|
ashita.timer.remove_timer("updatePlayerStorage"); |
|
ashita.timer.remove_timer("inactivityCheck"); |
|
|
|
-- Cleanup the custom variables.. |
|
for varName, data in pairs(uiVariables) do |
|
if (uiVariables[varName][1] ~= nil) then |
|
imgui.DeleteVar(uiVariables[varName][1]); |
|
end |
|
uiVariables[varName][1] = nil; |
|
end |
|
end) |
|
|
|
--------------------------------------------------------------------------------------------------- |
|
-- func: command |
|
-- desc: Called when the addon is handling a command. |
|
--------------------------------------------------------------------------------------------------- |
|
ashita.register_event('command', function(command, ntype) |
|
local commandArgs = command:lower():args(); |
|
|
|
if not table.hasvalue(_addon.commands, commandArgs[1]) then |
|
return false; |
|
end |
|
|
|
local responseMessage = ""; |
|
local success = true; |
|
|
|
if commandArgs[2] == 'reload' or commandArgs[2] == 'r' then |
|
AshitaCore:GetChatManager():QueueCommand('/addon reload yield', 1); |
|
|
|
elseif commandArgs[2] == 'unload' or commandArgs[2] == 'u' then |
|
response_message = 'Thank you for using Yield. Goodbye.'; |
|
AshitaCore:GetChatManager():QueueCommand('/addon unload yield', 1); |
|
|
|
elseif commandArgs[2] == 'about' or commandArgs[2] == 'a' then |
|
displayHelp(helpTable.about); |
|
|
|
elseif commandArgs[2] == 'help' or commandArgs[2] == 'h' then |
|
displayHelp(helpTable.commands); |
|
--[[ test commands |
|
elseif commandArgs[2] == "test" then |
|
settings.general.showToolTips = not settings.general.showToolTips; |
|
|
|
elseif commandArgs[2] == "test2" then |
|
settings.general.windowScaleIndex = cycleIndex(settings.general.windowScaleIndex, 0, 2, 1); |
|
--]] |
|
elseif commandArgs[2] == "find" or commandArgs[2] == 'f' then |
|
imgui.SetWindowPos(string.format("%s v%s by Lotekkie & Narpt", _addon.name, _addon.version), 0, 0); |
|
else |
|
displayHelp(helpTable.commands); |
|
end |
|
|
|
if responseMessage ~= "" then |
|
displayResponse( |
|
commandResponse(response_message, success) |
|
); |
|
end |
|
|
|
return false; |
|
end) |
|
|
|
--------------------------------------------------------------------------------------------------- |
|
-- func: incoming_text |
|
-- desc: Event called when the addon is asked to handle an incoming chat line. |
|
--------------------------------------------------------------------------------------------------- |
|
ashita.register_event('incoming_text', function(mode, message, modifiedmode, modifiedmessage, blocked) |
|
|
|
-- Ensure proper chat modes.. |
|
if not table.hasvalue({919, 654, 702, 662, 664, 129}, mode) then state.attempting = false; return false; end |
|
if (blocked) then state.attempting = false; return false; end |
|
|
|
-- Remove colors form message.. |
|
message = string.strip_colors(message); |
|
message = string.lower(message); |
|
|
|
-- Ensure we care.. |
|
if not state.attempting then |
|
if state.values.lastKnownGathering == "fishing" then -- play alert on skill-up |
|
local skillup = string.contains(message, string.format("%s's fishing skill rises", getPlayerName(true))) |
|
if skillup then |
|
playAlert(imgui.GetVarValue(uiVariables["var_FishingSkillSoundFile"][1])); |
|
end |
|
elseif getPlayerZoneId() == 4 then -- Bibiki Bay |
|
local obtainedBucket = string.contains(message, "obtained key item: clamming kit"); |
|
local returnedBucket = string.contains(message, "you return the clamming kit"); |
|
local upgraded = string.match(message, "^your clamming capacity has increased to (.*) ponzes!") |
|
if upgraded then |
|
state.values.clamBucketPzMax = tonumber(upgraded); |
|
end |
|
if obtainedBucket or returnedBucket then |
|
state.values.clamConfirmedYields = table.copy(metrics["clamming"].yields); |
|
state.values.clamBucketBroken = false; |
|
state.values.clamBucketPz = 0; |
|
state.values.clamBucketPzMax = 50; |
|
saveSettings(); |
|
end |
|
end |
|
return false; |
|
end |
|
|
|
-- Ensure correct state.. |
|
updateAllStates(state.attemptType); |
|
|
|
-- Check the attempt. |
|
if state.attempting then |
|
if not state.timers[state.gathering] then |
|
state.timers[state.gathering] = true |
|
end |
|
|
|
local val = 0; |
|
local success = false; |
|
local successBreak = false; |
|
local unable = false; |
|
local broken = false; |
|
local full = false; |
|
|
|
local gatherData = getGatherTypeData(state.gathering); |
|
switch(gatherData.name) : caseof |
|
{ |
|
["digging"] = function () |
|
successBreak = false; |
|
success = string.match(message, "obtained: (.*).") or successBreak |
|
unable = string.contains(message, "you dig, but find nothing."); |
|
broken = false; |
|
lost = false; |
|
end, |
|
["fishing"] = function () |
|
successBreak = false; |
|
success = string.match(message, string.format("%s %s a[n]? (.*)!", getPlayerName(true), gatherData.action)) or successBreak |
|
unable = string.contains(message, "you didn't catch anything.") or string.contains(message, "you give up"); |
|
broken = string.contains(message, "your rod breaks."); |
|
lost = string.contains(message, "you lost your catch") or string.contains(message, "your line breaks.") or string.contains(message, "but cannot carry any more items."); |
|
end, |
|
["clamming"] = function () |
|
successBreak = false; |
|
success = string.match(message, string.format("^you %s a[n]? (.*) and toss it into your bucket.", gatherData.action)); |
|
unable = string.contains(message, "with a broken bucket!") --or string.contains(message, "someone has been digging here."); |
|
broken = string.contains(message, "and toss it into your bucket..."); |
|
lost = false; |
|
if success then |
|
if state.values.clamBucketTotal == nil then state.values.clamBucketTotal = 0; end |
|
state.values.clamBucketTotal = state.values.clamBucketTotal + 1; |
|
end |
|
if broken then |
|
success = nil; |
|
metrics[state.gathering].yields = table.copy(state.values.clamConfirmedYields); |
|
metrics[state.gathering].totals.yields = table.sumValues(metrics[state.gathering].yields); |
|
metrics[state.gathering].estimatedValue = 0; |
|
state.values.clamBucketTotal = 0; |
|
state.values.clamBucketPz = 0; |
|
state.values.clamBucketPzMax = 50; |
|
for yield, count in pairs(metrics[state.gathering].yields) do |
|
local price = getPrice(yield); |
|
metrics[state.gathering].estimatedValue = metrics[state.gathering].estimatedValue + (price * count); |
|
end |
|
imgui.SetVarValue(uiVariables[string.format("var_%s_estimatedValue", state.gathering)][1], metrics[state.gathering].estimatedValue); |
|
playAlert(imgui.GetVarValue(uiVariables["var_ClamBreakSoundFile"][1])); |
|
end |
|
if broken or unable then |
|
state.values.clamBucketBroken = true; |
|
ashita.timer.once(1, function () -- let plots update a second |
|
state.timers[state.gathering] = false; |
|
end); |
|
saveSettings(); |
|
end |
|
end, |
|
["default"] = function () |
|
successBreak = string.match(message, string.format("^you %s a[n]? (.*), but your %s .*", gatherData.action, gatherData.tool)); |
|
success = string.match(message, string.format("^you successfully %s a[n]? (.*)!", gatherData.action)) or successBreak |
|
unable = string.contains(message, "you are unable to"); |
|
broken = string.match(message, "^your (.*) breaks!"); |
|
lost = false; |
|
end |
|
} |
|
|
|
full = string.contains(message, "you cannot carry any more") or string.contains(message, "your inventory is full"); |
|
|
|
if success then |
|
local of = string.match(success, "of (.*)"); |
|
if of then success = of end; |
|
end |
|
if success then |
|
success = string.lowerToTitle(success); |
|
if not table.haskey(settings.yields[state.gathering], success) then |
|
displayResponse(string.format("Yield: The %s yield name (%s) is unrecognized! Please report this to LoTekkie.", state.gathering, success), "\31\167%s"); |
|
state.attempting = false; |
|
return false; |
|
end |
|
val = getPrice(success); |
|
adjYield(success, 1); |
|
if state.gathering == "clamming" then |
|
state.values.clamBucketPz = state.values.clamBucketPz + settings.yields[state.gathering][success].pz |
|
end |
|
local soundPlaying = alertYield(success); |
|
if successBreak then adjTotal("breaks", 1); end |
|
adjTotal("yields", 1); |
|
elseif broken then |
|
adjTotal("breaks", 1); |
|
elseif full or lost then |
|
adjTotal("lost", 1); |
|
end |
|
if success or unable or broken or full or lost then |
|
adjTotal("attempts", 1); |
|
recordCurrentZone(); |
|
state.values.lastKnownGathering = state.gathering; |
|
state.attempting = false; |
|
end |
|
curVal = metrics[state.gathering].estimatedValue; |
|
metrics[state.gathering].estimatedValue = curVal + val; |
|
imgui.SetVarValue(uiVariables[string.format("var_%s_estimatedValue", state.gathering)][1], metrics[state.gathering].estimatedValue); |
|
local targetReached = metrics[state.gathering].estimatedValue >= settings.general.targetValue; |
|
if state.values.targetAlertReady and targetReached then |
|
local soundFile = imgui.GetVarValue(uiVariables["var_TargetSoundFile"][1]); |
|
playAlert(soundFile); |
|
state.values.targetAlertReady = false; |
|
end |
|
end |
|
return false; |
|
end); |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: outgoing_packet |
|
-- desc: Event called when the client is sending a packet to the server. |
|
---------------------------------------------------------------------------------------------------- |
|
ashita.register_event('outgoing_packet', function(id, size, packet, packet_modified, blocked) |
|
if id == 0x36 then -- helm |
|
for gathering, data in pairs(gatherTypes) do |
|
if data.target == ashitaTarget:GetTargetName() then |
|
state.attempting = true; |
|
state.attemptType = data.name; |
|
state.gathering = data.name; |
|
end |
|
end |
|
elseif id == 0x01A then -- clam |
|
if ashitaTarget:GetTargetName() == "Clamming Point" and AshitaCore:GetDataManager():GetPlayer():HasKeyItem(511) then |
|
state.attempting = true; |
|
state.attemptType = "clamming"; |
|
state.gathering = "clamming"; |
|
elseif struct.unpack("H", packet, 0x0A) == 0x1104 then -- digging |
|
state.attempting = true; |
|
state.attemptType = "digging"; |
|
state.gathering = "digging"; |
|
else |
|
state.attempting = false; |
|
end |
|
elseif id == 0x110 then -- fishing |
|
local action = struct.unpack("H", packet, 0x0E + 1); |
|
if action ~= 4 then |
|
state.attempting = true; |
|
state.attemptType = "fishing"; |
|
state.gathering = "fishing"; |
|
else |
|
state.attempting = false |
|
end |
|
end |
|
return false; |
|
end); |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: incoming_packet |
|
-- desc: Event called when the client is receiving a packet from the server. |
|
---------------------------------------------------------------------------------------------------- |
|
ashita.register_event('incoming_packet', function(id, size, packet, packet_modified, blocked) |
|
if id == 0x00B then -- zoning out (11) |
|
state.attempting = false; |
|
state.values.zoning = true; |
|
state.values.preZoneCounts["available"] = playerStorage['available']; |
|
state.values.preZoneCounts["available_pct"] = playerStorage["available_pct"]; |
|
for _, data in ipairs(gatherTypes) do |
|
state.timers[data.name] = false; -- shutdown timers |
|
state.values.preZoneCounts[data.tool] = playerStorage[data.tool]; |
|
end |
|
if state.values.lastKnownGathering ~= nil then |
|
if settings.general.autoGenReports then |
|
generateGatheringReport(state.values.lastKnownGathering); |
|
end |
|
state.values.lastKnownGathering = nil; |
|
end |
|
elseif (id == 0x01D and state.values.zoning) then -- inventory ready |
|
state.values.zoning = false; |
|
end |
|
return false; |
|
end); |
|
|
|
-- The settings window |
|
local SettingsWindow = |
|
{ |
|
modalSaveAction = function (self) |
|
imgui.CloseCurrentPopup(); |
|
imgui.SetVarValue(uiVariables["var_SettingsVisible"][1], false) |
|
updateAllStates(state.gathering); |
|
saveSettings(); |
|
imgui.SetVarValue(uiVariables["var_AllSoundIndex"][1], 0); |
|
local r, g, b, a = colorToRGBA(-3877684); |
|
imgui.SetVarValue(uiVariables["var_AllColors"][1], r/255, g/255, b/255, a/255); |
|
checkTargetAlertReady(); |
|
state.values.feedbackSubmitted = false; |
|
state.values.feedbackMissing = false; |
|
imgui.SetVarValue(uiVariables["var_IssueTitle"][1], ""); |
|
imgui.SetVarValue(uiVariables["var_IssueBody"][1], "") |
|
imgui.SetVarValue(uiVariables['var_ReportSelected'][1], nil); |
|
state.values.currentReportName = nil; |
|
end, |
|
|
|
Draw = function (self, title) |
|
local scaledHeightReduction = 0; |
|
if state.window.scale == 1.15 then scaledHeightReduction = 7 elseif state.window.scale == 1.30 then scaledHeightReduction = 12 end; |
|
imgui.SetNextWindowSize(state.window.widthSettings, state.window.heightSettings - scaledHeightReduction, ImGuiSetCond_Always); |
|
if state.values.centerWindow then |
|
imgui.SetNextWindowPosCenter(1); |
|
state.values.centerWindow = false; |
|
end |
|
if (not imgui.Begin(title, uiVariables["var_SettingsVisible"][1], imgui.bor(ImGuiWindowFlags_MenuBar, ImGuiWindowFlags_NoResize))) then |
|
imgui.End(); |
|
return; |
|
end |
|
|
|
imgui.SetWindowFontScale(state.window.scale); |
|
-- SETTINGS_MENU |
|
if imgui.BeginMenuBar() then |
|
for i, data in ipairs(settingsTypes) do |
|
local btnName = string.camelToTitle(data.name); |
|
imguiPushActiveBtnColor(state.settings.activeIndex == i); |
|
if imgui.Button(btnName) then |
|
state.settings.activeIndex = i; |
|
state.values.feedbackSubmitted = false; |
|
state.values.feedbackMissing = false; |
|
imgui.SetVarValue(uiVariables["var_IssueTitle"][1], ""); |
|
imgui.SetVarValue(uiVariables["var_IssueBody"][1], "") |
|
end |
|
imgui.PopStyleColor(); |
|
imgui.SameLine(0.0, state.window.spaceSettingsBtn); |
|
end |
|
imgui.EndMenuBar(); |
|
end |
|
-- /SETTINGS_MENU |
|
|
|
-- render settings pages.. |
|
imgui.BeginGroup(); |
|
imgui.Spacing(); |
|
switch(state.settings.activeIndex) : caseof |
|
{ |
|
[1] = function() renderSettingsGeneral() end, |
|
[2] = function() renderSettingsSetPrices() end, |
|
[3] = function() renderSettingsSetColors() end, |
|
[4] = function() renderSettingsSetAlerts() end, |
|
[5] = function() renderSettingsReports() end, |
|
[6] = function() renderSettingsFeedback() end, |
|
[7] = function() renderSettingsAbout() end, |
|
}; |
|
imgui.EndGroup(); |
|
|
|
imgui.Spacing(); |
|
|
|
if imgui.Button("Done") then |
|
imgui.SetVarValue(uiVariables["var_SettingsVisible"][1], false); |
|
end |
|
|
|
imgui.SameLine(); |
|
imgui.Text("OR close window to save."); |
|
|
|
-- Recalculate |
|
local yieldsExist = table.count(metrics[state.settings.setPrices.gathering].yields) > 0; |
|
if state.settings.activeIndex == 2 and yieldsExist then -- if we are setting prices |
|
local spaceBtnRecalculate = state.window.spaceBtnRecalculate; |
|
if settings.general.showToolTips then spaceBtnRecalculate = spaceBtnRecalculate - ( imgui.GetFontSize() * 24 / defaultFontSize ) end |
|
if state.window.scale == 1.15 then spaceBtnRecalculate = spaceBtnRecalculate + 3 end; |
|
if state.window.scale == 1.30 then spaceBtnRecalculate = spaceBtnRecalculate + 6 end; |
|
imgui.SameLine(0.0, spaceBtnRecalculate); |
|
if imguiShowToolTip("Recalculate the estimated value with your current price settings.", settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
if imgui.Button("Recalculate Value") then |
|
updateAllStates(state.settings.setPrices.gathering); |
|
metrics[state.gathering].estimatedValue = 0; |
|
for yield, count in pairs(metrics[state.gathering].yields) do |
|
local price = getPrice(yield); |
|
metrics[state.gathering].estimatedValue = metrics[state.gathering].estimatedValue + (price * count); |
|
end |
|
imgui.SetVarValue(uiVariables[string.format("var_%s_estimatedValue", state.gathering)][1], metrics[state.gathering].estimatedValue); |
|
end |
|
end |
|
|
|
if state.initializing then |
|
imgui.SetVarValue(uiVariables["var_SettingsVisible"][1], false); |
|
imgui.SetVarValue(uiVariables["var_HelpVisible"][1], false); |
|
imgui.CloseCurrentPopup(); |
|
end |
|
|
|
imgui.PopStyleVar(); |
|
imgui.End(); |
|
end |
|
} |
|
|
|
-- The help window |
|
local helpWindow = |
|
{ |
|
Draw = function (self, title) |
|
local scaledHeightReduction = 0; |
|
if state.window.scale == 1.15 then scaledHeightReduction = 7 elseif state.window.scale == 1.30 then scaledHeightReduction = 12 end; |
|
imgui.SetNextWindowSize(state.window.widthSettings, state.window.heightSettings - scaledHeightReduction, ImGuiSetCond_Always); |
|
if state.values.centerWindow then |
|
imgui.SetNextWindowPosCenter(1); |
|
state.values.centerWindow = false; |
|
end |
|
if (not imgui.Begin(title, uiVariables["var_HelpVisible"][1], imgui.bor(ImGuiWindowFlags_MenuBar, ImGuiWindowFlags_NoResize))) then |
|
imgui.End(); |
|
return; |
|
end |
|
imgui.SetWindowFontScale(state.window.scale); |
|
|
|
-- HELP_MENU |
|
if imgui.BeginMenuBar() then |
|
for i, data in ipairs(helpTypes) do |
|
local btnName = string.camelToTitle(data.name); |
|
imguiPushActiveBtnColor(state.help.activeIndex == i); |
|
if imgui.Button(btnName) then |
|
state.help.activeIndex = i; |
|
end |
|
imgui.PopStyleColor(); |
|
imgui.SameLine(0.0, state.window.spaceSettingsBtn); |
|
end |
|
imgui.EndMenuBar(); |
|
end |
|
-- /HELP_MENU |
|
|
|
imgui.BeginGroup(); |
|
imgui.Spacing(); |
|
switch(state.help.activeIndex) : caseof |
|
{ |
|
[1] = function() renderHelpGeneral() end, |
|
[2] = function() renderHelpQsAndAs() end |
|
}; |
|
imgui.EndGroup(); |
|
imgui.Spacing(); |
|
|
|
if imgui.Button("Done") then |
|
imgui.SetVarValue(uiVariables["var_HelpVisible"][1], false); |
|
end |
|
|
|
imgui.SameLine(); |
|
imgui.Text("OR close window to exit."); |
|
|
|
if state.initializing then |
|
imgui.SetVarValue(uiVariables["var_SettingsVisible"][1], false); |
|
imgui.SetVarValue(uiVariables["var_HelpVisible"][1], false); |
|
imgui.CloseCurrentPopup(); |
|
end |
|
|
|
imgui.End(); |
|
end |
|
} |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: render |
|
-- desc: Called when the addon is rendering. |
|
---------------------------------------------------------------------------------------------------- |
|
ashita.register_event('render', function() |
|
local windowScale = windowScales[settings.general.windowScaleIndex]; |
|
local scaledFontSize = windowScale*defaultFontSize; |
|
|
|
local scaledHeightReduction = 0; |
|
if windowScale == 1.15 then scaledHeightReduction = 34 elseif windowScale == 1.30 then scaledHeightReduction = 54 end; |
|
|
|
imgui.PushStyleVar(ImGuiStyleVar_WindowRounding, 5.0); |
|
imgui.PushStyleVar(ImGuiStyleVar_FrameRounding, 5.0); |
|
imgui.PushStyleVar(ImGuiStyleVar_ChildWindowRounding, 5.0); |
|
imgui.PushStyleVar(ImGuiStyleVar_Alpha, settings.general.opacity); |
|
imgui.PushStyleVar(ImGuiStyleVar_WindowPadding, scaledFontSize*5/defaultFontSize, scaledFontSize*5/defaultFontSize); |
|
imgui.PushStyleColor(ImGuiCol_Border, 0.21, 0.47, 0.59, 0.5); |
|
imgui.PushStyleColor(ImGuiCol_PlotLines, 0.77, 0.83, 0.80, 0.3); |
|
imgui.PushStyleColor(ImGuiCol_PlotHistogram, 0.77, 0.83, 0.80, 0.3); |
|
imgui.PushStyleColor(ImGuiCol_TitleBgActive, 17/255, 17/255, 30/255, 1.0); |
|
|
|
-- MAIN |
|
imgui.SetNextWindowSize(scaledFontSize*250/defaultFontSize, scaledFontSize*500/defaultFontSize - scaledHeightReduction, ImGuiSetCond_Always); |
|
if state.initializing and state.firstLoad then |
|
imgui.SetNextWindowPosCenter(1); |
|
state.values.centerWindow = true; |
|
elseif state.initializing then |
|
imgui.SetNextWindowPos(state.window.posX , state.window.posY); |
|
end |
|
if not imgui.Begin(string.format("%s v%s by Lotekkie & Narpt", _addon.name, _addon.version), imgui.GetVarValue(uiVariables['var_WindowVisible'][1]), imgui.bor(ImGuiWindowFlags_MenuBar, ImGuiWindowFlags_NoResize)) then |
|
imgui.End(); |
|
return |
|
end |
|
|
|
state.window = -- Calculations based on scaled window sizes |
|
{ |
|
scale = windowScale, |
|
height = scaledFontSize * 500.0 / defaultFontSize, |
|
width = scaledFontSize * 250.0 / defaultFontSize, |
|
padX = scaledFontSize * 5.0 / defaultFontSize, |
|
padY = scaledFontSize * 5.0 / defaultFontSize, |
|
spaceGatherBtn = scaledFontSize * 6.5 / defaultFontSize * windowScale + (windowScale - 1.0) * 2, |
|
spaceGatherImg = scaledFontSize * 6.3 / defaultFontSize * windowScale + (windowScale - 1.0) * 4, |
|
heightHeaderMain = scaledFontSize * 15.0 / defaultFontSize, |
|
heightPlot = scaledFontSize * 25.0 / defaultFontSize, |
|
heightYields = scaledFontSize * 130.0 / defaultFontSize, |
|
spaceToolTip = scaledFontSize * 4.0 / defaultFontSize, |
|
spaceFooterBtn = scaledFontSize * 4.0 / defaultFontSize * windowScale + (windowScale - 1.0) * 2, |
|
widthSettings = scaledFontSize * 500.0 / defaultFontSize, |
|
heightSettings = scaledFontSize * 450.0 / defaultFontSize, |
|
heightSettingsContent = scaledFontSize * 367.0 / defaultFontSize, |
|
heightSettingsScroll = scaledFontSize * 343.0 / defaultFontSize, |
|
spacePriceModeRadio = scaledFontSize * 26.0 / defaultFontSize * windowScale + (windowScale - 1.0) * 2, |
|
spacePriceDefaults = scaledFontSize * 177.0 / defaultFontSize, |
|
spaceEstimatedValue = scaledFontSize * 12.0 / defaultFontSize * windowScale + (windowScale - 1.0) * 2, |
|
widthModalConfirm = scaledFontSize * 350.0 / defaultFontSize, |
|
heightModalConfirm = scaledFontSize * 102.0 / defaultFontSize, |
|
spaceColorDefaults = scaledFontSize * 177.0 / defaultFontSize, |
|
widthWidgetDefault = scaledFontSize * 275.0 / defaultFontSize, |
|
spaceSettingsBtn = scaledFontSize * 6.0 / defaultFontSize * windowScale + (windowScale - 1.0) * 2, |
|
spaceSettingsDefaults = scaledFontSize * 377.0 / defaultFontSize, |
|
widthWidgetValue = scaledFontSize * 191.0 / defaultFontSize, |
|
offsetPriceColumns1 = scaledFontSize * 140.0 / defaultFontSize, |
|
offsetPriceColumns2 = scaledFontSize * 270.0 / defaultFontSize, |
|
heightPriceColumns = scaledFontSize * 25.0 / defaultFontSize, |
|
offsetPriceCursorY = scaledFontSize * 2.0 / defaultFontSize, |
|
offsetNameCursorY = scaledFontSize * 5.0 / defaultFontSize, |
|
sizeGatherTexture = scaledFontSize * 20.0 / defaultFontSize, |
|
spaceBtnRecalculate = scaledFontSize * 152.0 / defaultFontSize, |
|
spaceReportsDelete = scaledFontSize * 176.0 / defaultFontSize, |
|
widthReportScale = scaledFontSize * 150.0 / defaultFontSize |
|
} |
|
|
|
imgui.SetWindowFontScale(state.window.scale); |
|
|
|
|
|
if getPlayerName() ~= "" and not state.reportsLoaded then |
|
for _, data in ipairs(gatherTypes) do |
|
local dirName = string.format("%s\\reports\\%s\\%s", _addon.path, getPlayerName(), data.name); |
|
if ashita.file.dir_exists(dirName) then |
|
for f in io.popen(string.format("dir %s /b", dirName)):lines() do |
|
reports[data.name][#reports[data.name] + 1] = f; |
|
end |
|
else |
|
ashita.file.create_dir(dirName); |
|
end |
|
end |
|
state.reportsLoaded = true; |
|
end |
|
|
|
-- MAIN_MENU |
|
if imgui.BeginMenuBar() then |
|
local btnAction = function(data) |
|
updateAllStates(data.name); |
|
state.values.inactivitySeconds = 0; |
|
checkTargetAlertReady(); |
|
imgui.SetVarValue(uiVariables['var_ReportSelected'][1], nil); |
|
state.values.currentReportName = nil; |
|
state.settings.setColors.gathering = data.name; |
|
local r, g, b, a = colorToRGBA(-3877684); |
|
imgui.SetVarValue(uiVariables["var_AllColors"][1], r/255, g/255, b/255, a/255); |
|
state.settings.setAlerts.gathering = data.name; |
|
imgui.SetVarValue(uiVariables["var_AllSoundIndex"][1], 0); |
|
end |
|
for _, data in ipairs(gatherTypes) do |
|
if state.values.btnTextureFailure or not settings.general.useImageButtons then |
|
imguiPushActiveBtnColor(data.name == state.gathering); |
|
if imgui.SmallButton(string.upperfirst(data.short)) then |
|
btnAction(data); |
|
end |
|
else |
|
local texture = textures[data.name]; |
|
imguiPushActiveBtnColor(data.name == state.gathering); |
|
local textureSize = state.window.sizeGatherTexture; |
|
if imgui.ImageButton(texture:Get(), textureSize, textureSize) then |
|
btnAction(data); |
|
end |
|
end |
|
imgui.PopStyleColor(); |
|
if imgui.IsItemHovered() then |
|
imgui.SetTooltip(string.upperfirst(data.name)); |
|
end |
|
imgui.SameLine(0.0, state.window.spaceGatherBtn); |
|
end |
|
imgui.EndMenuBar(); |
|
end |
|
-- /MAIN_MENU |
|
|
|
imguiHalfSep(); |
|
|
|
-- MAIN_HEADER |
|
if imguiShowToolTip(string.format("Progress towards your target value (adjusted within settings)."), settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip) |
|
end |
|
if imgui.BeginChild("Header", -1, state.window.heightHeaderMain) then |
|
imgui.SetWindowFontScale(state.window.scale); |
|
local progress = calcTargetProgress() |
|
|
|
if progress < 1 and progress >= 0.5 then |
|
imgui.PushStyleColor(ImGuiCol_Text, 1, 1, 0.54, 1); -- warn |
|
elseif progress < 0.5 then |
|
imgui.PushStyleColor(ImGuiCol_Text, 1, 0.615, 0.615, 1); -- danger |
|
else |
|
imgui.PushStyleColor(ImGuiCol_Text, 0.39, 0.96, 0.13, 1); -- success |
|
end |
|
imgui.ProgressBar(progress, -1, state.window.heightHeaderMain, string.format("%s/%s", metrics[state.gathering].estimatedValue, settings.general.targetValue)) |
|
imgui.PopStyleColor(); |
|
imgui.EndChild(); |
|
end |
|
-- /MAIN_HEADER |
|
|
|
imguiHalfSep(true); |
|
|
|
-- totals metrics |
|
for total, metric in pairs(table.sortKeysByLength(metrics[state.gathering].totals, true)) do |
|
if state.gathering == "digging" and metric == "breaks" then |
|
if imguiShowToolTip("Current Moon percentage.", settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
imgui.Text(string.format("%s:", string.upperfirst("Moon"))); |
|
imgui.SameLine(); |
|
local moonPct = tostring(ashita.ffxi.vanatime.get_current_date().moon_percent); |
|
imgui.TextUnformatted(moonPct.."%"); |
|
else |
|
if imguiShowToolTip(metricsTotalsToolTips[metric], settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
imgui.Text(string.format("%s:", string.upperfirst(metric))); |
|
imgui.SameLine(); |
|
imgui.Text(metrics[state.gathering].totals[metric]) |
|
end |
|
if state.gathering == "clamming" and metric == "yields" then |
|
imgui.SameLine(); |
|
imgui.Text("~"); |
|
imgui.SameLine(); |
|
if imguiShowToolTip("Total pz value in current bucket (will turn red when within 5 points of limit). ", settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
local pzDiff = state.values.clamBucketPzMax - state.values.clamBucketPz; |
|
if pzDiff <= 5 then |
|
imgui.PushStyleColor(ImGuiCol_Text, 1, 0.615, 0.615, 1); -- danger |
|
elseif pzDiff <= state.values.clamBucketPzMax/2 then |
|
imgui.PushStyleColor(ImGuiCol_Text, 1, 1, 0.54, 1); -- warn |
|
else |
|
imgui.PushStyleColor(ImGuiCol_Text, 0.77, 0.83, 0.80, 1); -- plain |
|
end |
|
imgui.Text(string.format("Bucket: %spz", state.values.clamBucketPz)); |
|
imgui.PopStyleColor(); |
|
end |
|
end |
|
-- totals metrics |
|
|
|
-- gathering tools |
|
if imguiShowToolTip("Total gathering tools on hand.", settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
local gatherData = getGatherTypeData(); |
|
|
|
local avail = playerStorage[gatherData.tool] or 0; |
|
if state.values.zoning then avail = state.values.preZoneCounts[gatherData.tool]; end |
|
|
|
local targetAvail = 12; |
|
if state.gathering == "clamming" then targetAvail = 1; end |
|
|
|
if avail < targetAvail then |
|
imgui.PushStyleColor(ImGuiCol_Text, 1, 0.615, 0.615, 1); -- danger |
|
else |
|
if state.gathering == "clamming" and state.values.clamBucketBroken then |
|
imgui.PushStyleColor(ImGuiCol_Text, 1, 1, 0.54, 1); -- warn |
|
else |
|
imgui.PushStyleColor(ImGuiCol_Text, 0.77, 0.83, 0.80, 1); -- plain |
|
end |
|
end |
|
|
|
local toolName = string.lowerToTitle(gatherData.tool) |
|
if not table.hasvalue({"fishing", "clamming"}, gatherData.name) then |
|
toolName = toolName.."s" |
|
end |
|
imgui.Text(toolName..":"); |
|
imgui.SameLine(); |
|
|
|
local value = avail; |
|
if state.gathering == "clamming" then |
|
if not state.values.clamBucketBroken then |
|
if avail == 1 then value = "Ready"; else value = "None"; end |
|
else |
|
value = "Broken"; |
|
end |
|
end |
|
imgui.Text(value); |
|
imgui.PopStyleColor(); |
|
-- /gathering tools |
|
|
|
-- inventory |
|
if imguiShowToolTip("Total inventory slots available (main inventory only).", settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
local availPct = playerStorage['available_pct']; |
|
if state.values.zoning then availPct = state.values.preZoneCounts['available_pct']; end |
|
if availPct < 50 and availPct >= 25 then |
|
imgui.PushStyleColor(ImGuiCol_Text, 1, 1, 0.54, 1); -- warn |
|
elseif availPct < 25 then |
|
imgui.PushStyleColor(ImGuiCol_Text, 1, 0.615, 0.615, 1); -- danger |
|
else |
|
imgui.PushStyleColor(ImGuiCol_Text, 0.77, 0.83, 0.80, 1); -- plain |
|
end |
|
imgui.Text("Inventory:") |
|
imgui.SameLine(); |
|
|
|
local avail = playerStorage['available'] or 0; |
|
if state.values.zoning then avail = state.values.preZoneCounts['available']; end |
|
|
|
imgui.Text(avail); |
|
imgui.PopStyleColor(); |
|
-- /inventory |
|
|
|
-- time passed |
|
if imguiShowToolTip(string.format("Time passed since your first %s attempt or when the timer was manually started.", string.upperfirst(state.gathering)), settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
imgui.Text("Time Passed:"); |
|
imgui.SameLine(); |
|
local r, g, b, a = 1, 0.615, 0.615, 1 -- danger |
|
if state.timers[state.gathering] then |
|
r, g, b, a = 0.77, 0.83, 0.80, 1 -- plain |
|
end |
|
imgui.TextColored(r, g, b, a, os.date("!%X", (metrics[state.gathering].secondsPassed))) |
|
-- /time passed |
|
|
|
imgui.Spacing(); |
|
|
|
-- timer |
|
if imguiShowToolTip(string.format("Start, stop, or clear the %s timer.", string.upperfirst(state.gathering)), settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
imgui.Text("Timer:") |
|
imgui.SameLine(); |
|
if imgui.SmallButton(state.values.btnStartTimer) then |
|
state.timers[state.gathering] = not state.timers[state.gathering]; |
|
end |
|
if state.timers[state.gathering] then |
|
state.values.btnStartTimer = "Stop"; |
|
else |
|
state.values.btnStartTimer = "Start"; |
|
end |
|
imgui.SameLine(); |
|
if imgui.SmallButton("Clear") then |
|
state.timers[state.gathering] = false; |
|
metrics[state.gathering].secondsPassed = 0; |
|
end |
|
-- /timer |
|
|
|
imguiHalfSep(); |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
-- value |
|
imgui.PushStyleColor(ImGuiCol_Text, 0.39, 0.96, 0.13, 1); -- success |
|
if imguiShowToolTip(string.format("Editable estimated value of all %s yields (yield prices adjusted within settings).", string.upperfirst(state.gathering)), settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
|
|
imgui.Text("Value:") |
|
if settings.general.showToolTips then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
else |
|
imgui.SameLine(); |
|
end |
|
|
|
imgui.PushItemWidth(-1); |
|
imgui.PushAllowKeyboardFocus(false); |
|
if (imgui.InputInt('', uiVariables[string.format("var_%s_estimatedValue", state.gathering)][1])) then |
|
metrics[state.gathering].estimatedValue = imgui.GetVarValue(uiVariables[string.format("var_%s_estimatedValue", state.gathering)][1]); |
|
checkTargetAlertReady(); |
|
end |
|
imgui.PopStyleColor(); |
|
imgui.PopItemWidth(); |
|
imgui.PopAllowKeyboardFocus(); |
|
-- /value |
|
|
|
imguiHalfSep(true); |
|
|
|
-- plot yields |
|
imgui.PushItemWidth(-1); |
|
local plotYields = metrics[state.gathering].points.yields; |
|
local yieldsLabelMap = |
|
{ |
|
[1] = string.format("Yields/HR (%.2f)", metrics[state.gathering].points.yields[#metrics[state.gathering].points.yields]), |
|
[2] = string.format("%.2f/HR", metrics[state.gathering].points.yields[#metrics[state.gathering].points.yields]), |
|
[3] = "" |
|
} |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
local plotYieldsLabel = yieldsLabelMap[state.values.yieldsLabelIndex]; |
|
if imguiShowToolTip(string.format("Plot histogram of %s yields per hour (click the on plot to cycle its label displays).", string.upperfirst(state.gathering)), settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
|
|
local yieldsPerHour = metrics[state.gathering].points.yields[#metrics[state.gathering].points.yields]; |
|
local targetYields = 120; |
|
if state.gathering == "fishing" then targetYields = 90; end |
|
|
|
if yieldsPerHour < targetYields and yieldsPerHour >= targetYields/2 then |
|
imgui.PushStyleColor(ImGuiCol_Text, 1, 1, 0.54, 1); -- warn |
|
elseif yieldsPerHour < targetYields/2 then |
|
imgui.PushStyleColor(ImGuiCol_Text, 1, 0.615, 0.615, 1); -- danger |
|
else |
|
imgui.PushStyleColor(ImGuiCol_Text, 0.39, 0.96, 0.13, 1); -- success |
|
end |
|
|
|
imgui.PlotHistogram("", plotYields, #plotYields, 0, plotYieldsLabel, FLT_MIN, FLT_MAX, 0.0, state.window.heightPlot); |
|
imgui.PopStyleColor() |
|
if imgui.IsItemClicked() then |
|
state.values.yieldsLabelIndex = cycleIndex(state.values.yieldsLabelIndex, 1, 3); |
|
end |
|
if imgui.IsItemClicked(1) then |
|
state.values.yieldsLabelIndex = cycleIndex(state.values.yieldsLabelIndex, 1, 3, -1); |
|
end |
|
if imgui.IsItemHovered() then |
|
if plotYieldsLabel == "" then |
|
imgui.SetTooltip(string.format("Yields/HR (%.2f)", yieldsPerHour)); |
|
else |
|
imgui.SetTooltip(""); |
|
end |
|
end |
|
-- /plot yields |
|
|
|
-- plot values |
|
local plotValues = metrics[state.gathering].points.values; |
|
local valuesLabelMap = |
|
{ |
|
[1] = string.format("Value/HR (%.2f)", metrics[state.gathering].points.values[#metrics[state.gathering].points.values]), |
|
[2] = string.format("%.2f/HR", metrics[state.gathering].points.values[#metrics[state.gathering].points.values]), |
|
[3] = "" |
|
} |
|
local plotValuesLabel = valuesLabelMap[state.values.valuesLabelIndex]; |
|
if imguiShowToolTip("Plot lines of the estimated value per hour (L/R click on the plot to cycle its label displays).", settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
|
|
local valuesPerHour = metrics[state.gathering].points.values[#metrics[state.gathering].points.values]; |
|
local targetValue = 30000; |
|
|
|
if valuesPerHour < targetValue and valuesPerHour >= targetValue/2 then |
|
imgui.PushStyleColor(ImGuiCol_Text, 1, 1, 0.54, 1); -- warn |
|
elseif valuesPerHour < targetValue/2 then |
|
imgui.PushStyleColor(ImGuiCol_Text, 1, 0.615, 0.615, 1); -- danger |
|
else |
|
imgui.PushStyleColor(ImGuiCol_Text, 0.39, 0.96, 0.13, 1); -- success |
|
end |
|
|
|
imgui.PlotLines("", plotValues, #plotValues, 0, plotValuesLabel, FLT_MIN, FLT_MAX, 0.0, state.window.heightPlot); |
|
imgui.PopStyleColor() |
|
if imgui.IsItemClicked() then |
|
state.values.valuesLabelIndex = cycleIndex(state.values.valuesLabelIndex, 1, 3); |
|
end |
|
if imgui.IsItemClicked(1) then |
|
state.values.valuesLabelIndex = cycleIndex(state.values.valuesLabelIndex, 1, 3, -1); |
|
end |
|
if imgui.IsItemHovered() then |
|
if plotValuesLabel == "" then |
|
imgui.SetTooltip(string.format("Value/HR (%.2f)", valuesPerHour)); |
|
else |
|
imgui.SetTooltip(""); |
|
end |
|
end |
|
-- /plot values |
|
imgui.PopItemWidth(); |
|
imguiFullSep(); |
|
|
|
-- MAIN_SCROLLING |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
if imguiShowToolTip(string.format("Scrollable List of current %s yields and their amounts (L/R click on the list to cycle its sorting methods).", string.upperfirst(state.gathering)), settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
|
|
yieldsSortMap = |
|
{ |
|
[1] = { table.sortKeysByAlphabet(metrics[state.gathering].yields, false), "Alphabetical (DESC)" }, |
|
[2] = { table.sortKeysByAlphabet(metrics[state.gathering].yields, true), "Alphabetical (ASC)" }, |
|
[3] = { table.sortbykey(metrics[state.gathering].yields, false), "Count (DESC)" }, |
|
[4] = { table.sortbykey(metrics[state.gathering].yields, true), "Count (ASC)" }, |
|
[5] = { table.sortKeysByTotalValue(metrics[state.gathering].yields, false), "Value (DESC)" }, |
|
[6] = { table.sortKeysByTotalValue(metrics[state.gathering].yields, true), "Value (ASC)"} |
|
} |
|
|
|
if imgui.BeginChild("Scrolling", -1, state.window.heightYields, true) then |
|
imgui.SetWindowFontScale(state.window.scale); |
|
-- yields |
|
imgui.PushTextWrapPos(imgui.GetContentRegionAvailWidth()); |
|
for _, item in pairs(yieldsSortMap[state.values.yieldSortIndex][1]) do |
|
if settings.general.showToolTips then |
|
imgui.SetCursorPosX(imgui.GetCursorPosX() - 3.0); |
|
imgui.TextDisabled('(?)'); |
|
if imgui.IsItemHovered() then |
|
state.values.yieldListHovered = false; |
|
state.values.yieldListBtnsHovered = true; |
|
imgui.SetTooltip(string.format("Manually Add(+) or subtract(-) %s", item)); |
|
elseif state.values.yieldListHovered then |
|
state.values.yieldListBtnsHovered = false |
|
end |
|
imgui.SameLine(0.0, state.window.spaceToolTip - 1.5); |
|
end |
|
imgui.BeginGroup(); |
|
imgui.SmallButton("-"); |
|
if imgui.IsItemClicked() then |
|
adjYield(item, -1); |
|
adjTotal("yields", -1); |
|
val = getPrice(item); |
|
curVal = metrics[state.gathering].estimatedValue; |
|
metrics[state.gathering].estimatedValue = curVal - val; |
|
imgui.SetVarValue(uiVariables[string.format("var_%s_estimatedValue", state.gathering)][1], metrics[state.gathering].estimatedValue); |
|
end |
|
imgui.SameLine(0.0, 1.0); |
|
imgui.SmallButton("+"); |
|
if imgui.IsItemClicked() then |
|
adjYield(item, 1); |
|
adjTotal("yields", 1); |
|
val = getPrice(item); |
|
curVal = metrics[state.gathering].estimatedValue; |
|
metrics[state.gathering].estimatedValue = curVal + val; |
|
imgui.SetVarValue(uiVariables[string.format("var_%s_estimatedValue", state.gathering)][1], metrics[state.gathering].estimatedValue); |
|
end |
|
imgui.EndGroup(); |
|
if imgui.IsItemHovered() then |
|
state.values.yieldListHovered = false; |
|
state.values.yieldListBtnsHovered = true; |
|
imgui.SetTooltip(""); |
|
elseif state.values.yieldListHovered then |
|
state.values.yieldListBtnsHovered = false |
|
imgui.SetTooltip(string.format("Sort Type: %s", yieldsSortMap[state.values.yieldSortIndex][2])); |
|
end |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
local r, g, b, a = colorToRGBA(settings.yields[state.gathering][item].color); |
|
|
|
local shortName = settings.yields[state.gathering][item].short; |
|
local adjItemName = shortName or item; |
|
|
|
imgui.TextColored(r/255, g/255, b/255, a/255, adjItemName..":"); |
|
|
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
imgui.Text(metrics[state.gathering].yields[item]); |
|
|
|
if settings.general.showDetailedYields then |
|
local pricePer = getPrice(item); |
|
local r, g, b, a = colorToRGBA(settings.general.yieldDetailsColor); |
|
imgui.TextColored(r/255, g/255, b/255, a/255, string.format("@%dea.=(%s)", getPrice(item), math.floor(getPrice(item) * metrics[state.gathering].yields[item]))); |
|
end |
|
end |
|
imgui.PopTextWrapPos(); |
|
imgui.EndChild(); |
|
if imgui.IsItemClicked() then |
|
state.values.yieldListClicked = true; |
|
if not state.values.yieldListBtnsHovered then |
|
state.values.yieldSortIndex = cycleIndex(state.values.yieldSortIndex, 1, 6); |
|
end |
|
end |
|
if imgui.IsItemClicked(1) then |
|
state.values.yieldListClicked = true; |
|
if not state.values.yieldListBtnsHovered then |
|
state.values.yieldSortIndex = cycleIndex(state.values.yieldSortIndex, 1, 6, -1); |
|
end |
|
end |
|
if imgui.IsItemHovered() then |
|
if table.count(metrics[state.gathering].yields) == 0 then |
|
imgui.SetTooltip(string.format("Sort Type: %s", yieldsSortMap[state.values.yieldSortIndex][2])); |
|
else |
|
if not state.values.yieldListClicked then |
|
state.values.yieldListHovered = true; |
|
end |
|
end |
|
else |
|
state.values.yieldListHovered = false; |
|
end |
|
if not imgui.IsMouseDown(1) and not imgui.IsMouseDown(0) then |
|
state.values.yieldListClicked = false; |
|
end |
|
-- /yields |
|
end |
|
-- /MAIN_SCROLLING |
|
|
|
imguiFullSep(); |
|
|
|
if imgui.Button("Exit") then |
|
state.actions.modalConfirmAction = function() AshitaCore:GetChatManager():QueueCommand('/addon unload yield', 1); end |
|
state.values.modalConfirmPrompt = string.format(modalConfirmPromptTemplate, "Exit"); |
|
state.values.modalConfirmHelp = "(All gathering data will be saved.)"; |
|
imgui.OpenPopup("Yield Confirm") |
|
end |
|
|
|
imgui.SameLine(0.0, state.window.spaceFooterBtn); |
|
|
|
if imgui.Button("Reload") then |
|
state.actions.modalConfirmAction = function() AshitaCore:GetChatManager():QueueCommand('/addon reload yield', 1); end |
|
state.values.modalConfirmPrompt = string.format(modalConfirmPromptTemplate, "Reload"); |
|
state.values.modalConfirmHelp = "(All gathering data will be saved.)"; |
|
imgui.OpenPopup("Yield Confirm") |
|
end |
|
|
|
imgui.SameLine(0.0, state.window.spaceFooterBtn); |
|
|
|
if imgui.Button("Reset") then |
|
state.actions.modalConfirmAction = function() |
|
-- Generate report.. |
|
if settings.general.autoGenReports then |
|
generateGatheringReport(state.gathering); |
|
end |
|
-- Reset the metrics.. |
|
metrics[state.gathering] = table.copy(metricsTemplate); |
|
-- Reset the timers.. |
|
for timerName, running in pairs(state.timers) do |
|
state.timers[timerName] = false |
|
end |
|
-- Reset ui variables.. |
|
imgui.SetVarValue(uiVariables[string.format("var_%s_estimatedValue", state.gathering)][1], metrics[state.gathering].estimatedValue); |
|
-- Reset the zones.. |
|
settings.zones[state.gathering] = {}; |
|
state.values.lastKnownGathering = nil; |
|
end |
|
state.values.modalConfirmPrompt = string.format(modalConfirmPromptTemplate, "Reset"); |
|
state.values.modalConfirmHelp = string.format("(Current %s data will be lost.)", string.upperfirst(state.gathering)); |
|
state.values.modalConfirmDanger = true; |
|
if state.gathering == "clamming" then |
|
state.values.clamConfirmedYields = {}; |
|
state.values.clamBucketPz = 0; |
|
end |
|
saveSettings(); |
|
imgui.OpenPopup("Yield Confirm") |
|
end |
|
|
|
imgui.SameLine(0.0, state.window.spaceFooterBtn); |
|
|
|
if imgui.Button("Settings") then |
|
if imgui.GetVarValue(uiVariables["var_HelpVisible"][1]) then |
|
imgui.SetVarValue(uiVariables["var_HelpVisible"][1], false); |
|
end |
|
imgui.SetVarValue(uiVariables["var_SettingsVisible"][1], true); |
|
state.values.centerWindow = true; |
|
end |
|
|
|
imgui.SameLine(0.0, state.window.spaceFooterBtn); |
|
|
|
if imgui.Button("Help") then |
|
if imgui.GetVarValue(uiVariables["var_SettingsVisible"][1]) then |
|
imgui.SetVarValue(uiVariables["var_SettingsVisible"][1], false); |
|
end |
|
imgui.SetVarValue(uiVariables["var_HelpVisible"][1], true); |
|
state.values.centerWindow = true; |
|
end |
|
|
|
-- CONFIRM |
|
local scaledHeightReduction = 0; |
|
if windowScale == 1.15 then scaledHeightReduction = 10 elseif windowScale == 1.30 then scaledHeightReduction = 16 end; |
|
imgui.SetNextWindowSize(state.window.widthModalConfirm, state.window.heightModalConfirm - scaledHeightReduction, ImGuiSetCond_Always) |
|
if imgui.BeginPopupModal("Yield Confirm", imgui.GetVarValue(uiVariables['var_WindowVisible'][1]), imgui.bor(ImGuiWindowFlags_NoResize)) then |
|
imgui.SetWindowFontScale(state.window.scale); |
|
imgui.Text(state.values.modalConfirmPrompt); |
|
imgui.Spacing(); |
|
if state.values.modalConfirmHelp then |
|
local r, g, b, a = 0.39, 0.96, 0.13, 1 |
|
if state.values.modalConfirmDanger then |
|
r, g, b, a = 1, 0.615, 0.615, 1 |
|
end |
|
imgui.TextColored(r, g, b, a, state.values.modalConfirmHelp); |
|
end |
|
imguiFullSep(); |
|
if imgui.Button("Yes") or state.initializing then |
|
imgui.CloseCurrentPopup(); |
|
state.actions.modalCancelAction = function() end |
|
state.actions.modalConfirmAction(); |
|
end |
|
imgui.SameLine(0.0, 10); |
|
if imgui.Button("No") then |
|
imgui.CloseCurrentPopup(); |
|
state.actions.modalConfirmAction = function() end |
|
state.actions.modalCancelAction(); |
|
end |
|
imgui.SameLine(); |
|
imgui.Text("OR click away to exit."); |
|
if (not imgui.IsMouseHoveringAnyWindow() and imgui.IsMouseClicked()) then |
|
SettingsWindow:modalSaveAction(); |
|
end |
|
if state.initializing then |
|
imgui.CloseCurrentPopup(); |
|
imgui.SetVarValue(uiVariables["var_SettingsVisible"][1], false); |
|
end |
|
imgui.EndPopup(); |
|
else |
|
state.values.modalConfirmPrompt = "" |
|
state.values.modalConfirmHelp = "" |
|
state.values.modalConfirmDanger = false |
|
end |
|
-- /CONFIRM |
|
|
|
state.initializing = false |
|
-- /MAIN |
|
|
|
state.window.posX, state.window.posY = imgui.GetWindowPos(); |
|
|
|
imgui.End(); |
|
|
|
-- SETTINGS |
|
if imgui.GetVarValue(uiVariables["var_SettingsVisible"][1]) then |
|
state.values.settingsWindowOpen = true; |
|
SettingsWindow:Draw("Yield Settings") |
|
elseif state.values.settingsWindowOpen then |
|
state.values.settingsWindowOpen = false; |
|
SettingsWindow:modalSaveAction(); |
|
end |
|
-- /SETTINGS |
|
|
|
-- HELP |
|
if imgui.GetVarValue(uiVariables["var_HelpVisible"][1]) then |
|
state.values.helpWindowOpen = true; |
|
helpWindow:Draw("Yield Help"); |
|
elseif state.values.helpWindowOpen then |
|
state.values.helpWindowOpen = false; |
|
state.firstLoad = false; |
|
end |
|
-- /HELP |
|
end); |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: renderSettingsGeneral |
|
-- desc: Renders the General settings. |
|
---------------------------------------------------------------------------------------------------- |
|
function renderSettingsGeneral() |
|
if imgui.BeginChild("General", -1, state.window.heightSettingsContent, imgui.GetVarValue(uiVariables['var_WindowVisible'][1])) then |
|
imgui.SetWindowFontScale(state.window.scale); |
|
imgui.PushItemWidth(state.window.widthWidgetDefault); |
|
|
|
imgui.AlignFirstTextHeightToWidgets(); |
|
imgui.TextColored(1, 1, 0.54, 1, "Window"); |
|
|
|
local spaceSettingsDefaults = state.window.spaceSettingsDefaults; |
|
if settings.general.showToolTips then spaceSettingsDefaults = spaceSettingsDefaults - ( imgui.GetFontSize() * 24 / defaultFontSize ) end |
|
imgui.SameLine(0.0, spaceSettingsDefaults); |
|
if imguiShowToolTip("Set all general settings to their defaults.", settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
|
|
--imgui.PushStyleColor(ImGuiCol_Button, 0.21, 0.47, 0.59, 1); -- info |
|
if imgui.Button("Defaults") then |
|
settings.general = table.copy(defaultSettingsTemplate.general); |
|
imgui.SetVarValue(uiVariables["var_WindowOpacity"][1], settings.general.opacity); |
|
imgui.SetVarValue(uiVariables["var_TargetValue"][1], settings.general.targetValue); |
|
imgui.SetVarValue(uiVariables["var_ShowToolTips"][1], settings.general.showToolTips); |
|
imgui.SetVarValue(uiVariables["var_WindowScaleIndex"][1], settings.general.windowScaleIndex); |
|
imgui.SetVarValue(uiVariables["var_ShowDetailedYields"][1], settings.general.showDetailedYields); |
|
imgui.SetVarValue(uiVariables["var_UseImageButtons"][1], settings.general.useImageButtons); |
|
imgui.SetVarValue(uiVariables["var_EnableSoundAlerts"][1], true); |
|
imgui.SetVarValue(uiVariables["var_AutoGenReports"][1], true); |
|
local r, g, b, a = colorToRGBA(settings.general.yieldDetailsColor); |
|
imgui.SetVarValue(uiVariables["var_YieldDetailsColor"][1], r/255, g/255, b/255, a/255); |
|
end |
|
--imgui.PopStyleColor(); |
|
|
|
imguiHalfSep(true); |
|
|
|
-- Opacity |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
if imguiShowToolTip("Current alpha channel value of all Yield windows.", settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
if (imgui.SliderFloat("Window Opacity", uiVariables['var_WindowOpacity'][1], 0.25, 1.0, "%1.2f")) then |
|
settings.general.opacity = imgui.GetVarValue(uiVariables['var_WindowOpacity'][1]) |
|
end |
|
-- /Opacity |
|
|
|
imgui.Spacing(); |
|
|
|
-- Scale |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
if imguiShowToolTip("Current size for all Yield windows.", settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
if imgui.Combo("Window Size", uiVariables['var_WindowScaleIndex'][1], "Small\0Medium\0Large\0\0") then |
|
settings.general.windowScaleIndex = imgui.GetVarValue(uiVariables['var_WindowScaleIndex'][1]); |
|
end |
|
-- /Scale |
|
|
|
imguiFullSep(); |
|
|
|
imgui.TextColored(1, 1, 0.54, 1, "Gathering") |
|
|
|
imguiFullSep(); |
|
|
|
-- Target Value |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
if imguiShowToolTip("Amount you would like to earn this session (affects progress bar).", settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
if (imgui.InputInt("Target Value", uiVariables['var_TargetValue'][1])) then |
|
settings.general.targetValue = imgui.GetVarValue(uiVariables['var_TargetValue'][1]); |
|
end |
|
-- /Target Value |
|
|
|
imgui.Spacing(); |
|
|
|
-- Target Sound |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
if imguiShowToolTip("Sound that will be played when you reach your target value (will only play if your target is reached through gathering).", settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
if imgui.Button("Play") then |
|
end |
|
if imgui.IsItemClicked() then |
|
local soundFile = imgui.GetVarValue(uiVariables["var_TargetSoundFile"][1]); |
|
if soundFile ~= "" then |
|
ashita.misc.play_sound(string.format(_addon.path.."sounds\\%s", soundFile)); |
|
end |
|
end |
|
imgui.SameLine(); |
|
local scaledWidths ={ [0] = 232, [1] = 268, [2] = 304 }; |
|
imgui.PushItemWidth(scaledWidths[settings.general.windowScaleIndex]); |
|
if imgui.Combo("Target Alert", uiVariables["var_TargetSoundIndex"][1], getSoundOptions()) then |
|
local soundIndex = imgui.GetVarValue(uiVariables["var_TargetSoundIndex"][1]); |
|
local soundFile = sounds[soundIndex]; |
|
imgui.SetVarValue(uiVariables["var_TargetSoundFile"][1], ""); |
|
imgui.SetVarValue(uiVariables["var_TargetSoundFile"][1], soundFile); |
|
end |
|
imgui.PopItemWidth(); |
|
-- /Target Sound |
|
|
|
-- Detailed Yields |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
if imguiShowToolTip("Toggles the display of the math breakdown in the scrollable yields list.", settings.general.showToolTips) then |
|
imgui.SameLine(0.0 , state.window.spaceToolTip); |
|
end |
|
if (imgui.Checkbox("Show Detailed Yields", uiVariables['var_ShowDetailedYields'][1])) then |
|
settings.general.showDetailedYields = imgui.GetVarValue(uiVariables['var_ShowDetailedYields'][1]); |
|
end |
|
-- /Detailed Yields |
|
|
|
imgui.Spacing(); |
|
|
|
-- Yield Details Color |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
if imguiShowToolTip("Set the color of the math breakdown in the scrollable yields list.", settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
local r, g, b, a = colorToRGBA(settings.general.yieldDetailsColor); |
|
|
|
if imgui.ColorEdit4("Yield Details Color", uiVariables["var_YieldDetailsColor"][1]) then |
|
settings.general.yieldDetailsColor = colorTableToInt(imgui.GetVarValue(uiVariables["var_YieldDetailsColor"][1])); |
|
end |
|
-- /Yield Details Color |
|
|
|
imgui.Spacing(); |
|
|
|
-- Sound Alerts |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
if imguiShowToolTip("Toggles the set sound alerts for incoming yields.", settings.general.showToolTips) then |
|
imgui.SameLine(0.0 , state.window.spaceToolTip); |
|
end |
|
if (imgui.Checkbox("Enable Sound Alerts", uiVariables['var_EnableSoundAlerts'][1])) then |
|
settings.general.enableSoundAlerts = imgui.GetVarValue(uiVariables['var_EnableSoundAlerts'][1]); |
|
end |
|
-- /Sound Alerts |
|
|
|
-- Reports |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
if imguiShowToolTip("Toggles automatic report generation when zoning or after a data reset (you may still manually generate a report regardless).", settings.general.showToolTips) then |
|
imgui.SameLine(0.0 , state.window.spaceToolTip); |
|
end |
|
if (imgui.Checkbox("Auto Generate Reports", uiVariables['var_AutoGenReports'][1])) then |
|
settings.general.autoGenReports = imgui.GetVarValue(uiVariables['var_AutoGenReports'][1]); |
|
end |
|
-- /Reports |
|
|
|
imguiFullSep(); |
|
|
|
imgui.TextColored(1, 1, 0.54, 1, "Misc") -- warn |
|
|
|
imguiFullSep(); |
|
|
|
-- Image Buttons |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
if imguiShowToolTip("Toggles the display of images used for all gathering buttons. If off, text will be used instead.", settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
if (imgui.Checkbox('Use Image Buttons', uiVariables["var_UseImageButtons"][1])) then |
|
settings.general.useImageButtons = imgui.GetVarValue(uiVariables["var_UseImageButtons"][1]); |
|
end |
|
-- /Image Buttons |
|
|
|
-- Tooltips |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
if imguiShowToolTip("Toggles the display of (?)s and their tooltips.", settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
if (imgui.Checkbox('Show (?) Tooltips', uiVariables['var_ShowToolTips'][1])) then |
|
settings.general.showToolTips = imgui.GetVarValue(uiVariables['var_ShowToolTips'][1]); |
|
end |
|
-- /Tooltips |
|
imgui.PopItemWidth(); |
|
|
|
imgui.EndChild() |
|
end |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: renderSettingsSetPrices |
|
-- desc: Renders the Set Prices settings. |
|
---------------------------------------------------------------------------------------------------- |
|
function renderSettingsSetPrices() |
|
local gathering = state.settings.setPrices.gathering |
|
|
|
if imgui.BeginChild("Set Prices", -1, state.window.heightSettingsContent, imgui.GetVarValue(uiVariables['var_WindowVisible'][1]), imgui.bor(ImGuiWindowFlags_MenuBar, ImGuiWindowFlags_NoResize)) then |
|
imgui.SetWindowFontScale(state.window.scale); |
|
|
|
if imgui.BeginMenuBar() then |
|
local btnAction = function(data) |
|
state.settings.setPrices.gathering = data.name; |
|
end |
|
for _, data in ipairs(gatherTypes) do |
|
if state.values.btnTextureFailure or not settings.general.useImageButtons then |
|
imguiPushActiveBtnColor(data.name == gathering); |
|
if imgui.SmallButton(string.upperfirst(data.short)) then |
|
btnAction(data); |
|
end |
|
else |
|
local texture = textures[data.name]; |
|
imguiPushActiveBtnColor(data.name == gathering); |
|
local textureSize = state.window.sizeGatherTexture; |
|
if imgui.ImageButton(texture:Get(), textureSize, textureSize) then |
|
btnAction(data); |
|
end |
|
end |
|
imgui.PopStyleColor(); |
|
if imgui.IsItemHovered() then |
|
imgui.SetTooltip(string.upperfirst(data.name)); |
|
end |
|
|
|
imgui.SameLine(0.0, state.window.spaceGatherBtn); |
|
end |
|
|
|
-- Defaults |
|
local spacePriceDefaults = state.window.spacePriceDefaults; |
|
if settings.general.showToolTips then |
|
spacePriceDefaults = spacePriceDefaults - ( imgui.GetFontSize() * 24 / defaultFontSize ); |
|
if state.window.scale > 1.0 then spacePriceDefaults = spacePriceDefaults + 2 end; |
|
end |
|
imgui.SameLine(0.0, spacePriceDefaults); |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
if imguiShowToolTip(string.format("Set all %s prices to their default values (0).", string.upperfirst(gathering)), settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
if imgui.SmallButton("Defaults", uiVariables[string.format("var_%s_priceMode", gathering)][1], 2) then |
|
for yield, data in pairs(settings.yields[gathering], true) do |
|
settings.yields[gathering][yield].singlePrice = 0; |
|
settings.yields[gathering][yield].stackPrice = 0; |
|
imgui.SetVarValue(uiVariables[string.format("var_%s_%s_prices", gathering, yield)][1], 0, 0); |
|
end |
|
imgui.SetVarValue(uiVariables[string.format("var_%s_priceMode", gathering)][1], 0); |
|
end |
|
-- Defaults |
|
imgui.EndMenuBar(); |
|
end |
|
|
|
-- Columns |
|
imgui.SetCursorPosX(0); |
|
if imgui.BeginChild("Column Names", imgui.GetWindowWidth(), state.window.heightPriceColumns) then |
|
imgui.SetWindowFontScale(state.window.scale); |
|
imgui.Columns(3, "Price Mode Columns", false); |
|
imgui.SetColumnOffset(1, state.window.offsetPriceColumns1); |
|
--local col2Offset = state.window.offsetPriceColumns2; |
|
imgui.SameLine(0.0, 5.0); |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
local cursorOffsetY = state.window.offsetPriceCursorY; |
|
imgui.SetCursorPosY(imgui.GetCursorPosY() + cursorOffsetY); |
|
--imgui.SetCursorPosX(imgui.GetCursorPosX() + 10.0); |
|
|
|
if imguiShowToolTip("Use the set single-item prices for calculations.", settings.general.showToolTips) then |
|
imgui.SameLine(0.0, 0.0); |
|
end |
|
if imgui.RadioButton("Single Prices", uiVariables[string.format("var_%s_priceMode", gathering)][1], 1) then |
|
settings.priceModes[gathering] = imgui.GetVarValue(uiVariables[string.format("var_%s_priceMode", gathering)][1]); |
|
end |
|
imgui.NextColumn(); |
|
imgui.SetCursorPosY(imgui.GetCursorPosY() + cursorOffsetY); |
|
imgui.SetCursorPosX(imgui.GetCursorPosX() - 5.0); |
|
imgui.SetColumnOffset(2, state.window.offsetPriceColumns2); |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
if imguiShowToolTip("Use the set stack prices for calculations (Yield will do the math for you).", settings.general.showToolTips) then |
|
imgui.SameLine(0.0, 0.0); |
|
end |
|
if imgui.RadioButton("Stack Prices", uiVariables[string.format("var_%s_priceMode", gathering)][1], 0) then |
|
settings.priceModes[gathering] = imgui.GetVarValue(uiVariables[string.format("var_%s_priceMode", gathering)][1]); |
|
end |
|
imgui.NextColumn(); |
|
-- NPC prices |
|
local spacePriceMode = state.window.spacePriceModeRadio; |
|
if settings.general.showToolTips then spacePriceMode = 6.0 end |
|
imgui.SameLine(0.0, spacePriceMode); |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
if imguiShowToolTip(string.format("Use NPC base prices (Yield will automatically fetch the NPC single item prices as you gather). This option will override your set prices without modifying them.", string.upperfirst(gathering)), settings.general.showToolTips) then |
|
imgui.SameLine(0.0, 0.0); |
|
end |
|
if imgui.RadioButton("NPC prices", uiVariables[string.format("var_%s_priceMode", gathering)][1], 2) then |
|
settings.priceModes[gathering] = imgui.GetVarValue(uiVariables[string.format("var_%s_priceMode", gathering)][1]); |
|
end |
|
-- /NPC prices |
|
|
|
imgui.EndChild(); |
|
end |
|
|
|
-- /Columns |
|
imgui.Separator(); |
|
if imgui.BeginChild("Scrolling", -1, -1) then |
|
imgui.SetWindowFontScale(state.window.scale); |
|
for i, yield in pairs(table.sortKeysByAlphabet(settings.yields[gathering], true)) do |
|
local data = settings.yields[gathering][yield]; |
|
if data.id ~= nil then |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
if imguiShowToolTip(string.format("Set the single-item and or stack prices for %s.", yield), settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
imgui.PushItemWidth(state.window.widthWidgetDefault); |
|
local adjItemName = data.short or yield; |
|
local disabled = settings.priceModes[gathering] == 2; |
|
imguiPushDisabled(disabled); |
|
local flags = 0; |
|
if disabled then flags = ImGuiInputTextFlags_ReadOnly; end |
|
if imgui.InputInt2(adjItemName, uiVariables[string.format("var_%s_%s_prices", gathering, yield)][1], imgui.bor(flags)) then |
|
local prices = imgui.GetVarValue(uiVariables[string.format("var_%s_%s_prices", gathering, yield)][1]); |
|
settings.yields[gathering][yield].singlePrice = prices[1]; |
|
settings.yields[gathering][yield].stackPrice = prices[2]; |
|
end |
|
imgui.PopItemWidth(); |
|
imguiPopDisabled(disabled); |
|
end |
|
end |
|
imgui.EndChild() |
|
end |
|
imgui.EndChild() |
|
end |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: renderSettingsSetColors |
|
-- desc: Renders the Set Colors settings. |
|
---------------------------------------------------------------------------------------------------- |
|
function renderSettingsSetColors() |
|
local gathering = state.settings.setColors.gathering; |
|
if imgui.BeginChild("Set Colors", -1, state.window.heightSettingsContent, imgui.GetVarValue(uiVariables['var_WindowVisible'][1]), imgui.bor(ImGuiWindowFlags_MenuBar, ImGuiWindowFlags_NoResize)) then |
|
imgui.SetWindowFontScale(state.window.scale); |
|
if imgui.BeginMenuBar() then |
|
local btnAction = function(data) |
|
state.settings.setColors.gathering = data.name; |
|
local r, g, b, a = colorToRGBA(-3877684); |
|
imgui.SetVarValue(uiVariables["var_AllColors"][1], r/255, g/255, b/255, a/255); |
|
end |
|
for _, data in ipairs(gatherTypes) do |
|
if state.values.btnTextureFailure or not settings.general.useImageButtons then |
|
imguiPushActiveBtnColor(data.name == gathering); |
|
if imgui.SmallButton(string.upperfirst(data.short)) then |
|
btnAction(data); |
|
end |
|
else |
|
local texture = textures[data.name]; |
|
imguiPushActiveBtnColor(data.name == gathering); |
|
local textureSize = state.window.sizeGatherTexture; |
|
if imgui.ImageButton(texture:Get(), textureSize, textureSize) then |
|
btnAction(data); |
|
end |
|
end |
|
imgui.PopStyleColor(); |
|
if imgui.IsItemHovered() then |
|
imgui.SetTooltip(string.upperfirst(data.name)); |
|
end |
|
imgui.SameLine(0.0, state.window.spaceGatherBtn); |
|
end |
|
-- Defaults |
|
local spaceColorDefaults = state.window.spaceColorDefaults; |
|
if settings.general.showToolTips then |
|
spaceColorDefaults = spaceColorDefaults - ( imgui.GetFontSize() * 24 / defaultFontSize ); |
|
if state.window.scale > 1.0 then spaceColorDefaults = spaceColorDefaults + 2 end; |
|
end |
|
imgui.SameLine(0.0, spaceColorDefaults); |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
if imguiShowToolTip(string.format("Set all %s yield colors to their defaults.", string.upperfirst(gathering)), settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
if imgui.SmallButton("Defaults") then |
|
for yield, data in pairs(settings.yields[gathering]) do |
|
settings.yields[gathering][yield].color = -3877684 -- plain |
|
local r, g, b, a = colorToRGBA(-3877684); |
|
imgui.SetVarValue(uiVariables[string.format("var_%s_%s_color", gathering, yield)][1], r/255, g/255, b/255, a/255); |
|
imgui.SetVarValue(uiVariables["var_AllColors"][1], r/255, g/255, b/255, a/255); |
|
end |
|
end |
|
-- /Defaults |
|
imgui.EndMenuBar(); |
|
end |
|
-- All |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
if imguiShowToolTip("Set the text color for all yields when they are displayed in the yield list.", settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
local scaledWidths ={ [0] = 275, [1] = 318, [2] = 364 }; |
|
imgui.PushItemWidth(state.window.widthWidgetDefault); |
|
if imgui.ColorEdit4("Set All", uiVariables["var_AllColors"][1]) then |
|
local color = imgui.GetVarValue(uiVariables["var_AllColors"][1]); |
|
for yield, data in pairs(settings.yields[gathering]) do |
|
imgui.SetVarValue(uiVariables[string.format("var_%s_%s_color", gathering, yield)][1], color[1], color[2], color[3], color[4]); |
|
settings.yields[gathering][yield].color = colorTableToInt(imgui.GetVarValue(uiVariables[string.format("var_%s_%s_color", gathering, yield)][1])); |
|
end |
|
end |
|
imgui.PopItemWidth(); |
|
-- All |
|
imgui.Separator(); |
|
for data, yield in pairs(table.sortKeysByAlphabet(settings.yields[gathering], true)) do |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
if imguiShowToolTip(string.format("Set the text color for %s when its displayed in the yield list.", yield), settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
local r, g, b, a = colorToRGBA(settings.yields[gathering][yield].color); |
|
imgui.PushStyleColor(ImGuiCol_Text, r/255, g/255, b/255, a/255); |
|
imgui.PushItemWidth(state.window.widthWidgetDefault); |
|
local shortName = settings.yields[gathering][yield].short; |
|
local adjItemName = shortName or yield; |
|
if (imgui.ColorEdit4(adjItemName, uiVariables[string.format("var_%s_%s_color", gathering, yield)][1])) then |
|
settings.yields[gathering][yield].color = colorTableToInt(imgui.GetVarValue(uiVariables[string.format("var_%s_%s_color", gathering, yield)][1])); |
|
end |
|
imgui.PopStyleColor(); |
|
imgui.PopItemWidth(); |
|
end |
|
imgui.EndChild() |
|
end |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: renderSettingsSetAlerts |
|
-- desc: Renders the Set Alerts settings. |
|
---------------------------------------------------------------------------------------------------- |
|
function renderSettingsSetAlerts() |
|
local gathering = state.settings.setAlerts.gathering; |
|
if imgui.BeginChild("Set Alerts", -1, state.window.heightSettingsContent, imgui.GetVarValue(uiVariables['var_WindowVisible'][1]), imgui.bor(ImGuiWindowFlags_MenuBar, ImGuiWindowFlags_NoResize)) then |
|
imgui.SetWindowFontScale(state.window.scale); |
|
if imgui.BeginMenuBar() then |
|
local btnAction = function(data) |
|
state.settings.setAlerts.gathering = data.name; |
|
imgui.SetVarValue(uiVariables["var_AllSoundIndex"][1], 0); |
|
end |
|
for _, data in ipairs(gatherTypes) do |
|
if state.values.btnTextureFailure or not settings.general.useImageButtons then |
|
imguiPushActiveBtnColor(data.name == gathering); |
|
if imgui.SmallButton(string.upperfirst(data.short)) then |
|
btnAction(data); |
|
end |
|
else |
|
local texture = textures[data.name]; |
|
imguiPushActiveBtnColor(data.name == gathering); |
|
local textureSize = state.window.sizeGatherTexture; |
|
if imgui.ImageButton(texture:Get(), textureSize, textureSize) then |
|
btnAction(data); |
|
end |
|
end |
|
imgui.PopStyleColor(); |
|
if imgui.IsItemHovered() then |
|
imgui.SetTooltip(string.upperfirst(data.name)); |
|
end |
|
imgui.SameLine(0.0, state.window.spaceGatherBtn); |
|
end |
|
-- Defaults |
|
local spaceColorDefaults = state.window.spaceColorDefaults; |
|
if settings.general.showToolTips then |
|
spaceColorDefaults = spaceColorDefaults - ( imgui.GetFontSize() * 24 / defaultFontSize ); |
|
if state.window.scale > 1.0 then spaceColorDefaults = spaceColorDefaults + 2 end; |
|
end |
|
imgui.SameLine(0.0, spaceColorDefaults); |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
if imguiShowToolTip(string.format("Set all %s yield colors to their defaults.", string.upperfirst(gathering)), settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
if imgui.SmallButton("Defaults") then |
|
for yield, data in pairs(settings.yields[gathering]) do |
|
settings.yields[gathering][yield].soundIndex = 0 |
|
imgui.SetVarValue(uiVariables[string.format("var_%s_%s_soundFile", gathering, yield)][1], ""); |
|
imgui.SetVarValue(uiVariables[string.format("var_%s_%s_soundIndex", gathering, yield)][1], 0); |
|
imgui.SetVarValue(uiVariables["var_AllSoundIndex"][1], 0); |
|
end |
|
if gathering == "fishing" then |
|
imgui.SetVarValue(uiVariables["var_FishingSkillSoundIndex"][1], 0); |
|
imgui.SetVarValue(uiVariables["var_FishingSkillSoundFile"][1], ""); |
|
end |
|
if gathering == "clamming" then |
|
imgui.SetVarValue(uiVariables["var_ClamBreakSoundIndex"][1], 0); |
|
imgui.SetVarValue(uiVariables["var_ClamBreakSoundFile"][1], ""); |
|
end |
|
end |
|
-- /Defaults |
|
imgui.EndMenuBar(); |
|
end |
|
-- All |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
if imguiShowToolTip("Set a sound alert for all yields.", settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
local scaledWidths ={ [0] = 273, [1] = 318, [2] = 364 }; |
|
imgui.PushItemWidth(scaledWidths[settings.general.windowScaleIndex]); |
|
if imgui.Combo("Set All", uiVariables["var_AllSoundIndex"][1], getSoundOptions()) then |
|
local soundIndex = imgui.GetVarValue(uiVariables["var_AllSoundIndex"][1]); |
|
local soundFile = sounds[soundIndex]; |
|
for yield, data in pairs(settings.yields[gathering]) do |
|
imgui.SetVarValue(uiVariables[string.format("var_%s_%s_soundIndex", gathering, yield)][1], soundIndex); |
|
imgui.SetVarValue(uiVariables[string.format("var_%s_%s_soundFile", gathering, yield)][1], ""); |
|
imgui.SetVarValue(uiVariables[string.format("var_%s_%s_soundFile", gathering, yield)][1], soundFile); |
|
end |
|
if gathering == "fishing" then |
|
imgui.SetVarValue(uiVariables["var_FishingSkillSoundIndex"][1], soundIndex); |
|
imgui.SetVarValue(uiVariables["var_FishingSkillSoundFile"][1], ""); |
|
imgui.SetVarValue(uiVariables["var_FishingSkillSoundFile"][1], soundFile); |
|
end |
|
if gathering == "clamming" then |
|
imgui.SetVarValue(uiVariables["var_ClamBreakSoundIndex"][1], soundIndex); |
|
imgui.SetVarValue(uiVariables["var_ClamBreakSoundFile"][1], ""); |
|
imgui.SetVarValue(uiVariables["var_ClamBreakSoundFile"][1], soundFile); |
|
end |
|
end |
|
imgui.PopItemWidth(); |
|
-- All |
|
|
|
imgui.Separator(); |
|
|
|
-- Fishing Skillup |
|
if gathering == "fishing" then |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
if imguiShowToolTip("Set a sound alert for when you receive a fishing skill-up.", settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
if imgui.Button("Play") then end |
|
if imgui.IsItemClicked() then |
|
local soundFile = imgui.GetVarValue(uiVariables["var_FishingSkillSoundFile"][1]); |
|
if soundFile ~= "" then |
|
ashita.misc.play_sound(string.format(_addon.path.."sounds\\%s", soundFile)); |
|
end |
|
end |
|
imgui.SameLine(); |
|
imgui.PushItemWidth(state.window.widthWidgetDefault - 45); |
|
if imgui.Combo("Skill-Up", uiVariables["var_FishingSkillSoundIndex"][1], getSoundOptions()) then |
|
local soundIndex = imgui.GetVarValue(uiVariables["var_FishingSkillSoundIndex"][1]); |
|
local soundFile = sounds[soundIndex]; |
|
imgui.SetVarValue(uiVariables["var_FishingSkillSoundFile"][1], ""); |
|
imgui.SetVarValue(uiVariables["var_FishingSkillSoundFile"][1], soundFile); |
|
end |
|
imgui.PopItemWidth(); |
|
imgui.Separator(); |
|
end |
|
-- /Fishing Skillup |
|
|
|
-- Clamming break |
|
if gathering == "clamming" then |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
if imguiShowToolTip("Set a sound alert for when your clamming bucket breaks.", settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
if imgui.Button("Play") then end |
|
if imgui.IsItemClicked() then |
|
local soundFile = imgui.GetVarValue(uiVariables["var_ClamBreakSoundFile"][1]); |
|
if soundFile ~= "" then |
|
ashita.misc.play_sound(string.format(_addon.path.."sounds\\%s", soundFile)); |
|
end |
|
end |
|
imgui.SameLine(); |
|
imgui.PushItemWidth(state.window.widthWidgetDefault - 45); |
|
if imgui.Combo("Bucket Break", uiVariables["var_ClamBreakSoundIndex"][1], getSoundOptions()) then |
|
local soundIndex = imgui.GetVarValue(uiVariables["var_ClamBreakSoundIndex"][1]); |
|
local soundFile = sounds[soundIndex]; |
|
imgui.SetVarValue(uiVariables["var_ClamBreakSoundFile"][1], ""); |
|
imgui.SetVarValue(uiVariables["var_ClamBreakSoundFile"][1], soundFile); |
|
end |
|
imgui.PopItemWidth(); |
|
imgui.Separator(); |
|
end |
|
-- /Clamming break |
|
|
|
for data, yield in pairs(table.sortKeysByAlphabet(settings.yields[gathering], true)) do |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
if imguiShowToolTip(string.format("Set a sound alert for %s when it enters the yields list.", yield), settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
local shortName = settings.yields[gathering][yield].short; |
|
local adjItemName = shortName or yield; |
|
if imgui.Button("Play") then end |
|
if imgui.IsItemClicked() then |
|
local soundFile = imgui.GetVarValue(uiVariables[string.format("var_%s_%s_soundFile", gathering, yield)][1]); |
|
if soundFile ~= "" then |
|
ashita.misc.play_sound(string.format(_addon.path.."sounds\\%s", soundFile)); |
|
end |
|
end |
|
imgui.SameLine(); |
|
imgui.PushItemWidth(state.window.widthWidgetDefault - 45); |
|
if imgui.Combo(adjItemName, uiVariables[string.format("var_%s_%s_soundIndex", gathering, yield)][1], getSoundOptions()) then |
|
local soundIndex = imgui.GetVarValue(uiVariables[string.format("var_%s_%s_soundIndex", gathering, yield)][1]); |
|
local soundFile = sounds[soundIndex]; |
|
imgui.SetVarValue(uiVariables[string.format("var_%s_%s_soundFile", gathering, yield)][1], ""); |
|
imgui.SetVarValue(uiVariables[string.format("var_%s_%s_soundFile", gathering, yield)][1], soundFile); |
|
end |
|
imgui.PopItemWidth(); |
|
end |
|
imgui.EndChild(); |
|
end |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: renderSettingsReports |
|
-- desc: Renders the Reports section in settings. |
|
---------------------------------------------------------------------------------------------------- |
|
function renderSettingsReports() |
|
local gathering = state.settings.reports.gathering; |
|
local sortedReports = table.sortReportsByDate(reports[gathering], true); |
|
imgui.PushStyleVar(ImGuiStyleVar_WindowPadding, 5, 5); |
|
if imgui.BeginChild("Reports", -1, state.window.heightSettingsContent, imgui.GetVarValue(uiVariables['var_WindowVisible'][1]), imgui.bor(ImGuiWindowFlags_MenuBar, ImGuiWindowFlags_NoResize)) then |
|
imgui.SetWindowFontScale(state.window.scale); |
|
if imgui.BeginMenuBar() then |
|
local btnAction = function(data) |
|
state.settings.reports.gathering = data.name; |
|
imgui.SetVarValue(uiVariables['var_ReportSelected'][1], nil); |
|
state.values.currentReportName = nil; |
|
end |
|
for _, data in ipairs(gatherTypes) do |
|
if state.values.btnTextureFailure or not settings.general.useImageButtons then |
|
imguiPushActiveBtnColor(data.name == gathering); |
|
if imgui.SmallButton(string.upperfirst(data.short)) then |
|
btnAction(data); |
|
end |
|
else |
|
local texture = textures[data.name]; |
|
imguiPushActiveBtnColor(data.name == gathering); |
|
local textureSize = state.window.sizeGatherTexture; |
|
if imgui.ImageButton(texture:Get(), textureSize, textureSize) then |
|
btnAction(data); |
|
end |
|
end |
|
imgui.PopStyleColor(); |
|
if imgui.IsItemHovered() then |
|
imgui.SetTooltip(string.upperfirst(data.name)); |
|
end |
|
imgui.SameLine(0.0, state.window.spaceGatherBtn); |
|
end |
|
-- Generate |
|
local spaceColorDefaults = state.window.spaceColorDefaults; |
|
if settings.general.showToolTips then |
|
spaceColorDefaults = spaceColorDefaults - ( imgui.GetFontSize() * 24 / defaultFontSize ); |
|
if state.window.scale > 1.0 then spaceColorDefaults = spaceColorDefaults + 2 end; |
|
end |
|
imgui.SameLine(0.0, spaceColorDefaults); |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
if imguiShowToolTip(string.format("Manually generate a %s report using its current yield data.", string.upperfirst(gathering)), settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
local disabled = imguiPushDisabled(state.values.genReportDisabled); |
|
if imgui.SmallButton("Generate") then |
|
if not disabled then |
|
state.values.currentReportName = nil |
|
if generateGatheringReport(gathering) then |
|
state.values.genReportDisabled = true; |
|
ashita.timer.once(2, function() |
|
state.values.genReportDisabled = false; |
|
end); |
|
end |
|
end |
|
end |
|
imguiPopDisabled(disabled); |
|
-- /Generate |
|
imgui.EndMenuBar(); |
|
end |
|
imgui.SetCursorPosX(0); |
|
imgui.PushStyleColor(ImGuiCol_Border, 0, 0, 0, 0); |
|
if imgui.BeginChild("Report List", imgui.GetWindowWidth(), state.window.heightYields-25, true) then |
|
imgui.SetWindowFontScale(state.window.scale); |
|
imgui.PushTextWrapPos(imgui.GetContentRegionAvailWidth()); |
|
|
|
if table.count(reports[gathering]) > 0 then |
|
for _, file in ipairs(sortedReports, true) do |
|
local name = file |
|
if _ == 1 and #reports[gathering] > 1 then |
|
imgui.PushStyleColor(ImGuiCol_Text, 1, 1, 0.54, 1); -- warn |
|
name = file.." --latest" |
|
else |
|
imgui.PushStyleColor(ImGuiCol_Text, 0.77, 0.83, 0.80, 1); -- plain |
|
end |
|
if imgui.Selectable(name, imgui.GetVarValue(uiVariables["var_ReportSelected"][1]) == _, ImGuiSelectableFlags_AllowDoubleClick) then |
|
imgui.SetVarValue(uiVariables['var_ReportSelected'][1], _); |
|
state.values.readReportDisabled = false; |
|
if (imgui.IsMouseDoubleClicked(0)) then |
|
state.values.currentReportName = sortedReports[imgui.GetVarValue(uiVariables["var_ReportSelected"][1])]; |
|
end |
|
end |
|
imgui.PopStyleColor(); |
|
end |
|
else |
|
if getPlayerName() ~= "" then |
|
imgui.Text("No reports..") |
|
else |
|
imgui.TextColored(1, 0.615, 0.615, 1, string.format("Unable to manage reports with no character loaded.")); |
|
end |
|
end |
|
imgui.EndChild() |
|
end |
|
imgui.PopStyleColor(); |
|
|
|
imgui.Separator(); |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
if imguiShowToolTip("Read the selected report within the view window below (or double-click on the file name to perform this action).", settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
local disabled = imguiPushDisabled(imgui.GetVarValue(uiVariables["var_ReportSelected"][1]) == 0); |
|
if imgui.Button("Read") then -- here |
|
local selectedIndex = imgui.GetVarValue(uiVariables["var_ReportSelected"][1]); |
|
local fname = sortedReports[selectedIndex]; |
|
if state.values.currentReportName ~= fname then |
|
state.values.currentReportName = fname; |
|
end |
|
end |
|
imguiPopDisabled(disabled); |
|
imgui.SameLine(0.0, state.window.spaceSettingsBtn * 2); |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
if imguiShowToolTip("Clear the selection window above and the report view window below.", settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
disabled = imguiPushDisabled(imgui.GetVarValue(uiVariables["var_ReportSelected"][1]) == 0); |
|
if imgui.Button("Clear") then |
|
state.values.currentReportName = nil; |
|
imgui.SetVarValue(uiVariables["var_ReportSelected"][1], nil); |
|
end |
|
imguiPopDisabled(disabled); |
|
|
|
imgui.SameLine(0.0, state.window.spaceSettingsBtn * 2); |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
if imguiShowToolTip("Adjust the font scale of the report.", settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
imgui.PushItemWidth(state.window.widthReportScale); |
|
imgui.SliderFloat("", uiVariables['var_ReportFontScale'][1], 1.0, 1.5, "%.2f") |
|
imgui.PopItemWidth(); |
|
imgui.SameLine(); |
|
|
|
local spaceReportsDeleteMap = {[0] = state.window.spaceReportsDelete, [1] = state.window.spaceReportsDelete - 5, [2] = state.window.spaceReportsDelete - 8}; |
|
local spaceReportsDelete = spaceReportsDeleteMap[settings.general.windowScaleIndex] |
|
if settings.general.showToolTips then |
|
spaceReportsDelete = spaceReportsDelete - ( (imgui.GetFontSize() * 24) * 4 / defaultFontSize ); |
|
if state.window.scale > 1.0 then spaceReportsDelete = spaceReportsDelete + 2 end; |
|
end |
|
|
|
imgui.SameLine(0.0, spaceReportsDelete); |
|
|
|
local disabled = imguiPushDisabled(imgui.GetVarValue(uiVariables["var_ReportSelected"][1]) == 0); |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
if imguiShowToolTip("Delete the selected report entry.", settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
|
|
if imgui.Button("Delete") then |
|
if not disabled and getPlayerName() ~= "" then |
|
local selectedIndex = imgui.GetVarValue(uiVariables["var_ReportSelected"][1]); |
|
local fname = sortedReports[selectedIndex]; |
|
if fname ~= nil then |
|
local fpath = string.format('%s/%s/%s/%s/%s', _addon.path, 'reports', getPlayerName(), gathering, fname); |
|
os.remove(fpath); |
|
for _, fileName in ipairs(reports[gathering]) do |
|
if fileName == fname then |
|
table.remove(reports[gathering], _) |
|
end |
|
end |
|
state.values.currentReportName = nil; |
|
imgui.SetVarValue(uiVariables["var_ReportSelected"][1], #sortedReports-1); |
|
end |
|
end |
|
end |
|
|
|
imguiPopDisabled(disabled); |
|
|
|
imgui.Separator(); |
|
|
|
imgui.SetCursorPosX(0); |
|
imgui.PushStyleColor(ImGuiCol_Border, 0, 0, 0, 0); |
|
if imgui.BeginChild("Read Report", imgui.GetWindowWidth(), -1, true) then |
|
imgui.SetWindowFontScale(imgui.GetVarValue(uiVariables['var_ReportFontScale'][1])); |
|
imgui.PushTextWrapPos(imgui.GetContentRegionAvailWidth()); |
|
local fname = state.values.currentReportName; |
|
if fname ~= nil then |
|
if getPlayerName() ~= "" then |
|
local fpath = string.format('%s/%s/%s/%s/%s', _addon.path, 'reports', getPlayerName(), gathering, fname); |
|
local lines = linesFrom(fpath); |
|
if table.count(lines) > 0 then |
|
for _, line in pairs(lines) do |
|
imgui.TextUnformatted(line); |
|
end |
|
else |
|
imgui.TextColored(1, 0.615, 0.615, 1, string.format("File (%s) is unable to be read. Either this file has been moved, deleted, or you have changed characters. Reload yield to update this list.", state.values.currentReportName)) |
|
end |
|
else |
|
imgui.TextColored(1, 0.615, 0.615, 1, string.format("Unable to manage reports with no character loaded.")); |
|
end |
|
elseif getPlayerName() == "" then |
|
imgui.TextColored(1, 0.615, 0.615, 1, string.format("Unable to manage reports with no character loaded.")); |
|
end |
|
imgui.EndChild() |
|
end |
|
imgui.PopStyleColor(); |
|
imgui.EndChild(); |
|
end |
|
imgui.PopStyleVar(); |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: renderSettingsFeedback |
|
-- desc: Renders the Reports section in settings. |
|
---------------------------------------------------------------------------------------------------- |
|
function renderSettingsFeedback() |
|
if imgui.BeginChild("Set Alerts", -1, state.window.heightSettingsContent, true) then |
|
imgui.SetWindowFontScale(state.window.scale); |
|
local hasTitle = imgui.GetVarValue(uiVariables["var_IssueTitle"][1]):len() > 0; |
|
local hasBody = imgui.GetVarValue(uiVariables["var_IssueBody"][1]):len() > 0; |
|
local msg = "I hope you are enjoying Yield!" |
|
local widget = imgui.Text |
|
local r, g, b, a = 0.77, 0.83, 0.80, 1 -- plain |
|
if not hasTitle and state.values.feedbackMissing then |
|
msg = "Please enter a title. " |
|
widget = imgui.BulletText; |
|
r, g, b, a = 1, 0.615, 0.615, 1 -- danger |
|
elseif not hasBody and state.values.feedbackMissing then |
|
msg = "Please enter some feedback. " |
|
widget = imgui.BulletText; |
|
r, g, b, a = 1, 0.615, 0.615, 1 -- danger |
|
end |
|
local fontWidth = (msg:len()*imgui.GetFontSize()/2) / 1.75 |
|
imgui.SetCursorPosX(imgui.GetContentRegionAvailWidth()/2 - fontWidth); |
|
imgui.PushStyleColor(ImGuiCol_Text, r, g, b, a); |
|
widget(msg); |
|
imgui.PopStyleColor(); |
|
imguiFullSep(); |
|
imgui.PushTextWrapPos(imgui.GetContentRegionAvailWidth()); |
|
imgui.SetCursorPosX(imgui.GetContentRegionAvailWidth()/16); |
|
imgui.Text("If you have discovered a problem or want to provide some feedback you can do so here anonymously!") |
|
local widgetWidth = state.window.widthWidgetDefault+75 |
|
local centerWidget = imgui.GetWindowContentRegionWidth()/2 - widgetWidth/2 |
|
if settings.general.showToolTips then centerWidget = centerWidget - ( imgui.GetFontSize() * 24 / defaultFontSize ); end |
|
imgui.SetCursorPosY(imgui.GetWindowHeight() / 5); |
|
imgui.SetCursorPosX(centerWidget); |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
imgui.PushItemWidth(widgetWidth); |
|
if imguiShowToolTip("Enter a title for your feedback/issue submission.", settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
imgui.InputText('Title', uiVariables['var_IssueTitle'][1], 128, imgui.bor(ImGuiInputTextFlags_EnterReturnsTrue)); |
|
imgui.Spacing(); |
|
imgui.SetCursorPosX(centerWidget); |
|
imgui.AlignFirstTextHeightToWidgets(); |
|
if imguiShowToolTip("Enter your feedback/issue.", settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
imgui.InputTextMultiline('Body', uiVariables['var_IssueBody'][1], 16384, state.window.widthWidgetDefault+75, imgui.GetTextLineHeight() * 16, imgui.bor(ImGuiInputTextFlags_AllowTabInput, ImGuiInputTextFlags_EnterReturnsTrue)); |
|
imgui.PopItemWidth(); |
|
imgui.Spacing(); |
|
local widgetPos = state.window.widthWidgetDefault+75 |
|
local centerWidget = imgui.GetWindowContentRegionWidth()/2 - widgetPos/2 |
|
imgui.SetCursorPosX(centerWidget); |
|
if not state.values.feedbackSubmitted then |
|
if imgui.Button("Submit") then |
|
if not hasBody or not hasTitle then |
|
state.values.feedbackMissing = true; |
|
else |
|
state.values.feedbackSubmitted = true; |
|
state.values.feedbackMissing = false; |
|
local title = imgui.GetVarValue(uiVariables["var_IssueTitle"][1]); |
|
local body = imgui.GetVarValue(uiVariables["var_IssueBody"][1]); |
|
sendIssue(title, body); |
|
imgui.SetVarValue(uiVariables["var_IssueTitle"][1], ""); |
|
imgui.SetVarValue(uiVariables["var_IssueBody"][1], "") |
|
end |
|
end |
|
end |
|
if state.values.feedbackSubmitted then |
|
imgui.SetCursorPosX(centerWidget); |
|
imgui.PushStyleColor(ImGuiCol_Text, 0.39, 0.96, 0.13, 1); -- success |
|
imgui.Text("Thank you for your feedback!"); |
|
imgui.PopStyleColor(); |
|
imgui.SameLine(); |
|
imgui.PushStyleColor(ImGuiCol_Text, 1, 0.615, 0.615, 1); -- danger |
|
imgui.Text("<3"); |
|
imgui.PopStyleColor(); |
|
end |
|
imgui.PushTextWrapPos(imgui.GetWindowContentRegionWidth()); |
|
imgui.SetCursorPosY(imgui.GetWindowHeight()-imgui.GetTextLineHeight()*2); |
|
if imguiShowToolTip("All submissions are anonymous and will go to LoTekkie's github issue tracker for Ashita-Yield.", settings.general.showToolTips) then |
|
imgui.SameLine(0.0, state.window.spaceToolTip); |
|
end |
|
imgui.Text("* To: https://github.com/LoTekkie/Ashita-Yield/issues."); |
|
imgui.PopTextWrapPos(); |
|
imgui.EndChild(); |
|
end |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: renderSettingsAbout |
|
-- desc: Renders the About section in settings. |
|
--------------------------------------------------------------------------------------------------- |
|
function renderSettingsAbout() |
|
if imgui.BeginChild("About", -1, state.window.heightSettingsContent, true) then |
|
imgui.SetWindowFontScale(state.window.scale); |
|
imgui.Spacing(); |
|
imgui.PushTextWrapPos(imgui.GetContentRegionAvailWidth()); |
|
imgui.TextColored(1, 1, 0.54, 1, "Name:"); imgui.Text(string.format("%s by Lotekkie & Narpt", _addon.name)); |
|
imgui.Spacing(); |
|
imgui.TextColored(1, 1, 0.54, 1, "Description:"); imgui.Text(_addon.description); imgui.Text("https://github.com/LoTekkie/Ashita-Yield"); |
|
imgui.Spacing(); |
|
imgui.TextColored(1, 1, 0.54, 1, "Author:"); imgui.Text(_addon.author); |
|
imgui.Spacing(); |
|
imgui.TextColored(1, 1, 0.54, 1, "Version:"); imgui.Text(_addon.version); |
|
imgui.Spacing(); |
|
imgui.TextColored(1, 1, 0.54, 1, "Support/Donate:"); imgui.Text("https://Paypal.me/Sjshovan\nOR\nFor Gil donations: I play on Wings private server! (https://www.wingsxi.com/wings/) My in-game name is LoTekkie."); |
|
imgui.Spacing(); |
|
imgui.PushStyleColor(ImGuiCol_Button, 0.21, 0.47, 0.59, 1); -- info |
|
if imgui.Button("Go to Paypal") then |
|
ashita.misc.open_url("https://Paypal.me/Sjshovan"); |
|
end |
|
imgui.PopStyleColor(); |
|
imguiFullSep(); |
|
imgui.TextColored(1, 1, 0.54, 1, "Special Thanks:"); |
|
imguiFullSep(); |
|
imgui.Text("To Narpt (https://www.twitch.tv/narpt): For his awesome streams, invaluable feedback/ideas/testing, and the inspiration to make this!"); |
|
imgui.Spacing(); |
|
imgui.Text("To Hughesyourdaddy (https://www.omega-ffxi.com): For granting me the freedom to create this within the FFXI Omega private server."); |
|
imgui.Spacing(); |
|
imgui.Text("To the Ashita team (https://www.ashitaxi.com/): For making this possible."); |
|
imgui.Spacing(); |
|
imgui.Text("To Ashita Discord members (https://discord.gg/3FbepVGh): For their feedback and knowledge."); |
|
imgui.Spacing(); |
|
imgui.Text("To everyone who reported bugs and submitted feedback, thanks for helping make Yield great!"); |
|
imgui.EndChild(); |
|
end |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: renderHelpGeneral |
|
-- desc: Renders the general help section with the help window. |
|
--------------------------------------------------------------------------------------------------- |
|
function renderHelpGeneral() |
|
if imgui.BeginChild("HelpGeneral", -1, state.window.heightSettingsContent, true) then |
|
imgui.SetWindowFontScale(state.window.scale); |
|
imgui.Spacing(); |
|
imgui.PushTextWrapPos(imgui.GetContentRegionAvailWidth()); |
|
if state.firstLoad then |
|
imgui.TextColored(1, 1, 0.54, 1, "Welcome to Yield!"); imgui.Separator(); |
|
imgui.Text("Before you begin, please take a moment to read through the following general information and common questions to familiarize yourself."); |
|
imgui.Text("If you would like to read this later you can open this window anytime by click the 'Help' button located at the bottom of the app."); |
|
imguiHalfSep(true); |
|
end |
|
imgui.TextColored(1, 1, 0.54, 1, "Navigating Yield"); imgui.Separator(); |
|
imgui.Text("Your main tool for navigating Yield is the mouse. You will find that if you take your time and hover over the (?) tooltips as well as other items within the interface that Yield will give you an explanation of each item, don't be afraid to take the time to explore!"); |
|
imgui.Text("The real power of Yield comes from within its Settings window. There are a variety of features and customization options there to accommodate almost every gatherer's need."); |
|
imguiHalfSep(true); |
|
imgui.TextColored(1, 1, 0.54, 1, "Gathering"); imgui.Separator(); |
|
imgui.Text("Yield supports every gathering type in the game and switching between them here is a breeze, simply click on the icons at the top of the Main window. If you hover your mouse over them, Yield will tell you which gathering type you are switching to. If you start gathering and forget to switch, don't worry, Yield will automatically switch to the correct type and begin working to keep track of your stats!"); |
|
imgui.Spacing(); |
|
imgui.Text("Don't forget to set those prices! Before heading out to begin gathering, it is recommended that you set your prices for yields within the Settings/Set Prices window. If you forget for some reason, that's ok, you can always update the prices later and recalculate your Estimated Value from within the same window."); |
|
imgui.Spacing(); |
|
imgui.Text("Yield is intelligent and will begin tracking and recording for you without the need for you to do anything first. After you load Yield, simply start gathering and watch the magic happen!"); |
|
imguiHalfSep(true); |
|
imgui.TextColored(1, 1, 0.54, 1, "Settings"); imgui.Separator(); |
|
imgui.Text("Yield automatically saves all the changes you make in your Settings window each time the Settings window is closed. You do not need to worry about reloading and losing your Prices/Colors/Alerts or any of your current metrics. When you exit the game and come back, everything will be right where you left it."); |
|
imguiHalfSep(true); |
|
imgui.TextColored(1, 1, 0.54, 1, "Alerts"); imgui.Separator(); |
|
imgui.Text("Yield ships with a variety of sounds, used for alerts, out of the box. If you find yourself wanting to add custom sounds, it couldn't be easier. All sounds used for Yield alerts can be found within the /sounds folder. To add a new sound, ensure the sound file is in .wav format (e.g. my_new_sound.wav), and drop it into /sounds. After that, reload Yield and your new sound should be available in all sound selection drop-downs.") |
|
imguiHalfSep(true); |
|
imgui.TextColored(1, 1, 0.54, 1, "Reports"); imgui.Separator(); |
|
imgui.Text("Yield allows you to generate detailed reports using the metrics it has tracked while you gathered. You do not need to use Yield to manage these files but these reports can be read and deleted from within the Settings/Reports window. These files are stored locally with the /reports folder of the Yield addon. It is safe to remove these files even while Yield is loaded. Yield will inform you that the files no longer exist if you attempt to read them."); |
|
imgui.Text("Generation of reports can occur both manually and automatically. If you enable automatic generation of reports Yield will generate a report both when you zone and when you reset the data for a particular gathering type."); |
|
imgui.Text("While automatic report generation can happen when you zone, it won't always happen when you zone. Yield will attempt to determine when it should generate on zone change based on your activity."); |
|
imguiHalfSep(true); |
|
imgui.TextColored(1, 1, 0.54, 1, "Tips/Tricks"); imgui.Separator(); |
|
imgui.Text("1. Double-click on the title bar of any window to minimize it."); |
|
imgui.Text("2. left-click or right-click on your plots within the Main window to cycle the display of their labels."); |
|
imgui.Text("3. left-click or right-click on the yields list within the Main window to cycle the sorting methods of the list."); |
|
imgui.Text("4. If you forget to shut off your timer when you walk away from Yield, it will automatically shut them off for you after approx. 5 minutes."); |
|
imgui.Text("5. You can Double-click on a file name in Reports to view its contents rather than using the Read button."); |
|
imgui.Text("6. You can left-click drag on the R: G: B: A: color boxes with your mouse to change their values quickly. You can also left-click on the main color box to change color input methods."); |
|
imgui.Text("7. You can view the moon percentage by switching to the digging gathering type."); |
|
imguiHalfSep(true); |
|
imgui.TextColored(1, 1, 0.54, 1, "Bugs/Errors"); imgui.Separator(); |
|
imgui.Text("Unfortunately, nothing is perfect, not even Yield. You may come across a problem while using Yield to help you become the ultimate gatherer. I understand the frustration of these occurrences and that is why I added an easy in-app way to report these problems directly to me so I can quickly get the issues resolved."); |
|
imgui.Text("To report an issue directly to me, simply head on over to Settings/Feedback. Enter a title, an explanation, and hit submit."); |
|
imgui.Text("By taking a mere moment to send a report, you are effectively taking part in the active development of Yield and helping it become even better. This time you take to do so is greatly appreciated!"); |
|
imguiHalfSep(true); |
|
imgui.TextColored(1, 1, 0.54, 1, "Text Commands"); imgui.Separator(); |
|
imgui.Text("Yield has a few text commands to quickly load/reload/unload. To see a full list of the available commands type: '/yield help' in your chat while Yield is loaded."); |
|
imgui.Spacing(); |
|
imgui.EndChild(); |
|
end |
|
end |
|
|
|
---------------------------------------------------------------------------------------------------- |
|
-- func: renderHelpQsAndAs |
|
-- desc: Renders the Q's and A's section with the help window. |
|
--------------------------------------------------------------------------------------------------- |
|
function renderHelpQsAndAs() |
|
if imgui.BeginChild("HelpQnA", -1, state.window.heightSettingsContent, true) then |
|
imgui.SetWindowFontScale(state.window.scale); |
|
imgui.Spacing(); |
|
imgui.PushTextWrapPos(imgui.GetContentRegionAvailWidth()); |
|
imgui.Separator(); |
|
imgui.TextColored(1, 1, 0.54, 1, "Q: Is this addon available for Windower?"); imgui.Separator(); |
|
imgui.Text("A: Unfortunately, No. Windower does not currently offer the technology used to create this addon. If they ever do, I will absolutely port it over. ") |
|
imguiFullSep(); |
|
imgui.TextColored(1, 1, 0.54, 1, "Q: Why isn't feature X/Y/Z implemented?"); imgui.Separator(); |
|
imgui.Text("A: I'm positive many of you out there have some amazing ideas on how to make Yield better. I'd love to hear them! You can contact me through Feedback in Settings, by email ([email protected]), or on discord (LoTekkie #6070).") |
|
imguiFullSep(); |
|
imgui.TextColored(1, 1, 0.54, 1, "Q: How can I donate/support?"); imgui.Separator(); |
|
imgui.Text("A: Head on over to the About section in Settings. There you can see some ways that I am able to receive your support. Thank you!"); |
|
imguiFullSep(); |
|
imgui.TextColored(1, 1, 0.54, 1, "Q: I have upgraded from a previous version now everything went bonkers! What do I do?"); imgui.Separator(); |
|
imgui.Text("A: If you reach a scenario where Yield wont display correctly or is acting strange, first try reloading the addon. If you are still experiencing issues try the following steps:") |
|
imgui.Text("1. Exit out of Final Fantasy 11."); |
|
imgui.Text("2. Navigate to the Yield addon and delete your settings/ folder."); |
|
imgui.Text("3. Start Final Fantasy 11 and load Yield.") |
|
imgui.Text("If you are still experiencing issues, reach out to me and I will attempt to solve them."); |
|
imguiFullSep(); |
|
imgui.TextColored(1, 1, 0.54, 1, "Q: I cannot find the Yield window! What do I do?"); imgui.Separator(); |
|
imgui.Text("A: Type /yield find or /yld f in your chat bar. This will force the Yield window to return to the top left of your screen."); |
|
imguiFullSep(); |
|
imgui.TextColored(1, 1, 0.54, 1, "Q: Which server do you play on?"); imgui.Separator(); |
|
imgui.Text("A: I am currently playing on Wings private server (https://www.wingsxi.com/). My in-game name is LoTekkie. Hope to see you around!"); |
|
imguiFullSep(); |
|
imgui.TextColored(1, 1, 0.54, 1, "Q: Have you created any other FFXI addons?"); imgui.Separator(); |
|
imgui.Text("A: Yes, I have also authored Mount Muzzle(Windower+Ashita) and Battle Stations(Windower). You can obtain these through their respective launchers."); |
|
imguiFullSep(); |
|
imgui.TextColored(1, 1, 0.54, 1, "Q: I have a question that I don't see here. How do I contact you?"); imgui.Separator(); |
|
imgui.Text("A: You can contact me through Feedback in Settings, by email ([email protected]), or on discord (LoTekkie #6070)."); |
|
imgui.Spacing(); |
|
imgui.EndChild(); |
|
end |
|
end |