From da3afa2e1deb285d2847295faba50f4bac0174cb Mon Sep 17 00:00:00 2001 From: UTDZac Date: Mon, 16 Sep 2024 16:05:16 -0700 Subject: [PATCH 01/12] Re-center creator's name on credits screen Shifting it over a smidge to the left so it feels more centered. --- ironmon_tracker/screens/NavigationMenu.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ironmon_tracker/screens/NavigationMenu.lua b/ironmon_tracker/screens/NavigationMenu.lua index ccea2c1d..fdf8446a 100644 --- a/ironmon_tracker/screens/NavigationMenu.lua +++ b/ironmon_tracker/screens/NavigationMenu.lua @@ -287,7 +287,7 @@ function NavigationMenu.drawCredits(canvas) Drawing.drawText(canvas.x + 3, textLineY, createdByText, Theme.COLORS[NavigationMenu.Colors.highlight], canvas.shadow) textLineY = textLineY + Constants.SCREEN.LINESPACING - local colOffsetX = Utils.getCenteredTextX(Main.CreditsList.CreatedBy, canvas.w) + local colOffsetX = -8 + Utils.getCenteredTextX(Main.CreditsList.CreatedBy, canvas.w) Drawing.drawText(canvas.x + colOffsetX, textLineY, Main.CreditsList.CreatedBy, canvas.text, canvas.shadow) textLineY = textLineY + Constants.SCREEN.LINESPACING + 3 From b5ed562b57fdbc7dfcaab8ca6b95d04945a1d0ce Mon Sep 17 00:00:00 2001 From: UTDZac Date: Mon, 16 Sep 2024 17:07:42 -0700 Subject: [PATCH 02/12] Cleanup duplicate text that got drawn over This was really only noticeable in Bizhawk 2.10 rc. for many tabs and a few other rows, the text would be drawn twice: once before the tab's background, and once after. Removing the occurrence before. --- ironmon_tracker/screens/CoverageCalcScreen.lua | 6 +++--- ironmon_tracker/screens/ExtrasScreen.lua | 6 +++--- ironmon_tracker/screens/HealsInBagScreen.lua | 6 +++--- ironmon_tracker/screens/LogTabRoutes.lua | 6 +++--- ironmon_tracker/screens/SetupScreen.lua | 6 +++--- ironmon_tracker/screens/StreamConnectOverlay.lua | 6 +++--- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/ironmon_tracker/screens/CoverageCalcScreen.lua b/ironmon_tracker/screens/CoverageCalcScreen.lua index 47d86b3d..ba209677 100644 --- a/ironmon_tracker/screens/CoverageCalcScreen.lua +++ b/ironmon_tracker/screens/CoverageCalcScreen.lua @@ -331,7 +331,7 @@ function CoverageCalcScreen.createButtons() local tabWidth = (tabPadding * 2) + Utils.calcWordPixelLength(tabText) SCREEN.Buttons["Tab" .. tabText] = { type = Constants.ButtonTypes.NO_BORDER, - getText = function(self) return tabText end, + getCustomText = function(self) return tabText end, tab = SCREEN.Tabs[tabKey], isSelected = false, box = { startX, startY, tabWidth, TAB_HEIGHT }, @@ -355,8 +355,8 @@ function CoverageCalcScreen.createButtons() if self.isSelected then gui.drawLine(x + 1, y + h, x + w - 1, y + h, bgColor) -- Remove bottom edge end - local centeredOffsetX = Utils.getCenteredTextX(self:getText(), w) - 2 - Drawing.drawText(x + centeredOffsetX, y, self:getText(), Theme.COLORS[self.textColor], shadowcolor) + local centeredOffsetX = Utils.getCenteredTextX(self:getCustomText(), w) - 2 + Drawing.drawText(x + centeredOffsetX, y, self:getCustomText(), Theme.COLORS[self.textColor], shadowcolor) end, onClick = function(self) SCREEN.changeTab(self.tab) end, } diff --git a/ironmon_tracker/screens/ExtrasScreen.lua b/ironmon_tracker/screens/ExtrasScreen.lua index 9314238a..880280c9 100644 --- a/ironmon_tracker/screens/ExtrasScreen.lua +++ b/ironmon_tracker/screens/ExtrasScreen.lua @@ -152,7 +152,7 @@ function ExtrasScreen.createTabs() for _, tuple in ipairs(tabs) do ExtrasScreen.Buttons["Tab" .. tuple[1]] = { type = Constants.ButtonTypes.NO_BORDER, - getText = function(self) return Resources.ExtrasScreen[tuple[2]] end, + getCustomText = function(self) return Resources.ExtrasScreen[tuple[2]] end, tab = ExtrasScreen.Tabs[tuple[1]], isSelected = false, box = { @@ -180,8 +180,8 @@ function ExtrasScreen.createTabs() if self.isSelected then gui.drawLine(x + 1, y + h, x + w - 1, y + h, bgColor) -- Remove bottom edge end - local centeredOffsetX = Utils.getCenteredTextX(self:getText(), w) - 2 - Drawing.drawText(x + centeredOffsetX, y, self:getText(), Theme.COLORS[self.textColor], shadowcolor) + local centeredOffsetX = Utils.getCenteredTextX(self:getCustomText(), w) - 2 + Drawing.drawText(x + centeredOffsetX, y, self:getCustomText(), Theme.COLORS[self.textColor], shadowcolor) end, onClick = function(self) ExtrasScreen.currentTab = self.tab diff --git a/ironmon_tracker/screens/HealsInBagScreen.lua b/ironmon_tracker/screens/HealsInBagScreen.lua index 7d732d14..f06e50c4 100644 --- a/ironmon_tracker/screens/HealsInBagScreen.lua +++ b/ironmon_tracker/screens/HealsInBagScreen.lua @@ -141,7 +141,7 @@ function HealsInBagScreen.createButtons() local tabWidth = (tabPadding * 2) + Utils.calcWordPixelLength(tabText) SCREEN.Buttons["Tab" .. tab.tabKey] = { type = Constants.ButtonTypes.NO_BORDER, - getText = function(self) return tabText end, + getCustomText = function(self) return tabText end, tab = SCREEN.Tabs[tab.tabKey], isSelected = false, box = { startX, startY, tabWidth, TAB_HEIGHT }, @@ -165,8 +165,8 @@ function HealsInBagScreen.createButtons() if self.isSelected then gui.drawLine(x + 1, y + h, x + w - 1, y + h, bgColor) -- Remove bottom edge end - local centeredOffsetX = Utils.getCenteredTextX(self:getText(), w) - 2 - Drawing.drawText(x + centeredOffsetX, y, self:getText(), Theme.COLORS[self.textColor], shadowcolor) + local centeredOffsetX = Utils.getCenteredTextX(self:getCustomText(), w) - 2 + Drawing.drawText(x + centeredOffsetX, y, self:getCustomText(), Theme.COLORS[self.textColor], shadowcolor) end, onClick = function(self) SCREEN.changeTab(self.tab) end, } diff --git a/ironmon_tracker/screens/LogTabRoutes.lua b/ironmon_tracker/screens/LogTabRoutes.lua index 06777ab2..4a6aca26 100644 --- a/ironmon_tracker/screens/LogTabRoutes.lua +++ b/ironmon_tracker/screens/LogTabRoutes.lua @@ -137,7 +137,7 @@ function LogTabRoutes.buildPagedButtons() local rowButton = { type = Constants.ButtonTypes.NO_BORDER, - getText = function(self) return routeName end, + getCustomText = function(self) return routeName end, id = mapId, numTrainers = route.numTrainers, minTrainerLv = route.minTrainerLv, @@ -163,7 +163,7 @@ function LogTabRoutes.buildPagedButtons() local trainersInArea = (route.EncountersAreas["Trainers"] or {}).trainers or {} if LogSearchScreen.currentFilter == LogSearchScreen.FilterBy.RouteName then - if Utils.containsText(self:getText(), LogSearchScreen.searchText, true) then + if Utils.containsText(self:getCustomText(), LogSearchScreen.searchText, true) then return true end elseif LogSearchScreen.currentFilter == LogSearchScreen.FilterBy.TrainerName then @@ -266,7 +266,7 @@ function LogTabRoutes.buildPagedButtons() -- Route Name textColor = Theme.COLORS[routeBar.cols[2].textColor or false] or Theme.COLORS[LogTabRoutes.Colors.text] - Drawing.drawText(x + routeBar.cols[2].x + 3, y + centeredY, self:getText(), textColor, shadowcolor) + Drawing.drawText(x + routeBar.cols[2].x + 3, y + centeredY, self:getCustomText(), textColor, shadowcolor) local col, text, centeredX -- # Wilds and levels diff --git a/ironmon_tracker/screens/SetupScreen.lua b/ironmon_tracker/screens/SetupScreen.lua index 9f45a719..443d126e 100644 --- a/ironmon_tracker/screens/SetupScreen.lua +++ b/ironmon_tracker/screens/SetupScreen.lua @@ -184,7 +184,7 @@ function SetupScreen.createTabs() for _, tab in ipairs(Utils.getSortedList(SCREEN.Tabs)) do SCREEN.Buttons["Tab" .. tab.tabKey] = { type = Constants.ButtonTypes.NO_BORDER, - getText = function(self) return Resources.SetupScreen[tab.resourceKey] end, + getCustomText = function(self) return Resources.SetupScreen[tab.resourceKey] end, tab = SCREEN.Tabs[tab.tabKey], isSelected = false, box = { @@ -212,8 +212,8 @@ function SetupScreen.createTabs() if self.isSelected then gui.drawLine(x + 1, y + h, x + w - 1, y + h, bgColor) -- Remove bottom edge end - local centeredOffsetX = Utils.getCenteredTextX(self:getText(), w) - 2 - Drawing.drawText(x + centeredOffsetX, y, self:getText(), Theme.COLORS[self.textColor], shadowcolor) + local centeredOffsetX = Utils.getCenteredTextX(self:getCustomText(), w) - 2 + Drawing.drawText(x + centeredOffsetX, y, self:getCustomText(), Theme.COLORS[self.textColor], shadowcolor) end, onClick = function(self) SCREEN.currentTab = self.tab diff --git a/ironmon_tracker/screens/StreamConnectOverlay.lua b/ironmon_tracker/screens/StreamConnectOverlay.lua index fccab754..4915fafb 100644 --- a/ironmon_tracker/screens/StreamConnectOverlay.lua +++ b/ironmon_tracker/screens/StreamConnectOverlay.lua @@ -170,7 +170,7 @@ function StreamConnectOverlay.createTabButtons() local tabWidth = (tabPadding * 2) + Utils.calcWordPixelLength(tabText) SCREEN.Buttons["Tab" .. tab.tabKey] = { type = Constants.ButtonTypes.NO_BORDER, - getText = function(self) return tabText end, + getCustomText = function(self) return tabText end, tab = SCREEN.Tabs[tab.tabKey], isSelected = false, box = { startX, startY, tabWidth, TAB_HEIGHT }, @@ -193,8 +193,8 @@ function StreamConnectOverlay.createTabButtons() if self.isSelected then gui.drawLine(x + 1, y + h, x + w - 1, y + h, bgColor) -- Remove bottom edge end - local centeredOffsetX = Utils.getCenteredTextX(self:getText(), w) - 2 - Drawing.drawText(x + centeredOffsetX, y, self:getText(), Theme.COLORS[self.textColor], shadowcolor) + local centeredOffsetX = Utils.getCenteredTextX(self:getCustomText(), w) - 2 + Drawing.drawText(x + centeredOffsetX, y, self:getCustomText(), Theme.COLORS[self.textColor], shadowcolor) end, onClick = function(self) SCREEN.changeTab(self.tab) end, } From b7d1cb7d50a57c9ccc942be9a909cde1a86f7f08 Mon Sep 17 00:00:00 2001 From: UTDZac Date: Tue, 17 Sep 2024 12:10:36 -0700 Subject: [PATCH 03/12] Remove incorrect param for !pivots command --- ironmon_tracker/Languages/English.lua | 2 +- ironmon_tracker/Languages/French.lua | 2 +- ironmon_tracker/Languages/German.lua | 2 +- ironmon_tracker/Languages/Italian.lua | 2 +- ironmon_tracker/Languages/Japanese.lua | 2 +- ironmon_tracker/Languages/Spanish.lua | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ironmon_tracker/Languages/English.lua b/ironmon_tracker/Languages/English.lua index 6b785093..73e614de 100644 --- a/ironmon_tracker/Languages/English.lua +++ b/ironmon_tracker/Languages/English.lua @@ -614,7 +614,7 @@ ScreenResources{ CMD_Dungeon_Name = "Dungeon Info", CMD_Dungeon_Help = "name > Displays info about which trainers have been defeated for an area.", CMD_Pivots_Name = "Pivots Seen", - CMD_Pivots_Help = "name > Displays known early game wild encounters for an area.", + CMD_Pivots_Help = "> Displays known early game wild encounters for an area.", CMD_Revo_Name = "Pokémon Random Evolutions", CMD_Revo_Help = "name [target-evo] > Displays randomized evolution possibilities for a Pokémon, and it's [target-evo] if more than one available.", CMD_Coverage_Name = "Move Coverage Effectiveness", diff --git a/ironmon_tracker/Languages/French.lua b/ironmon_tracker/Languages/French.lua index ab229736..a384ac85 100644 --- a/ironmon_tracker/Languages/French.lua +++ b/ironmon_tracker/Languages/French.lua @@ -615,7 +615,7 @@ ScreenResources{ CMD_Dungeon_Name = "Dungeon Info", CMD_Dungeon_Help = "name > Displays info about which trainers have been defeated for an area.", CMD_Pivots_Name = "Pivots Seen", - CMD_Pivots_Help = "name > Displays known early game wild encounters for an area.", + CMD_Pivots_Help = "> Displays known early game wild encounters for an area.", CMD_Revo_Name = "Pokémon Random Evolutions", CMD_Revo_Help = "name [target-evo] > Displays randomized evolution possibilities for a Pokémon, and it's [target-evo] if more than one available.", CMD_Coverage_Name = "Move Coverage Effectiveness", diff --git a/ironmon_tracker/Languages/German.lua b/ironmon_tracker/Languages/German.lua index 84ea9c3f..3f4b1731 100644 --- a/ironmon_tracker/Languages/German.lua +++ b/ironmon_tracker/Languages/German.lua @@ -615,7 +615,7 @@ ScreenResources{ CMD_Dungeon_Name = "Dungeon Info", CMD_Dungeon_Help = "name > Displays info about which trainers have been defeated for an area.", CMD_Pivots_Name = "Pivots Seen", - CMD_Pivots_Help = "name > Displays known early game wild encounters for an area.", + CMD_Pivots_Help = "> Displays known early game wild encounters for an area.", CMD_Revo_Name = "Pokémon Random Evolutions", CMD_Revo_Help = "name [target-evo] > Displays randomized evolution possibilities for a Pokémon, and it's [target-evo] if more than one available.", CMD_Coverage_Name = "Move Coverage Effectiveness", diff --git a/ironmon_tracker/Languages/Italian.lua b/ironmon_tracker/Languages/Italian.lua index b78b68b8..e32095a2 100644 --- a/ironmon_tracker/Languages/Italian.lua +++ b/ironmon_tracker/Languages/Italian.lua @@ -615,7 +615,7 @@ ScreenResources{ CMD_Dungeon_Name = "Dungeon Info", CMD_Dungeon_Help = "name > Displays info about which trainers have been defeated for an area.", CMD_Pivots_Name = "Pivots Seen", - CMD_Pivots_Help = "name > Displays known early game wild encounters for an area.", + CMD_Pivots_Help = "> Displays known early game wild encounters for an area.", CMD_Revo_Name = "Pokémon Random Evolutions", CMD_Revo_Help = "name [target-evo] > Displays randomized evolution possibilities for a Pokémon, and it's [target-evo] if more than one available.", CMD_Coverage_Name = "Move Coverage Effectiveness", diff --git a/ironmon_tracker/Languages/Japanese.lua b/ironmon_tracker/Languages/Japanese.lua index d10e1fc1..60b95d6c 100644 --- a/ironmon_tracker/Languages/Japanese.lua +++ b/ironmon_tracker/Languages/Japanese.lua @@ -617,7 +617,7 @@ ScreenResources{ CMD_Dungeon_Name = "Dungeon Info", CMD_Dungeon_Help = "name > Displays info about which trainers have been defeated for an area.", CMD_Pivots_Name = "Pivots Seen", - CMD_Pivots_Help = "name > Displays known early game wild encounters for an area.", + CMD_Pivots_Help = "> Displays known early game wild encounters for an area.", CMD_Revo_Name = "Pokémon Random Evolutions", CMD_Revo_Help = "name [target-evo] > Displays randomized evolution possibilities for a Pokémon, and it's [target-evo] if more than one available.", CMD_Coverage_Name = "Move Coverage Effectiveness", diff --git a/ironmon_tracker/Languages/Spanish.lua b/ironmon_tracker/Languages/Spanish.lua index e287c30e..2e78b35c 100644 --- a/ironmon_tracker/Languages/Spanish.lua +++ b/ironmon_tracker/Languages/Spanish.lua @@ -615,7 +615,7 @@ ScreenResources{ CMD_Dungeon_Name = "Dungeon Info", CMD_Dungeon_Help = "name > Displays info about which trainers have been defeated for an area.", CMD_Pivots_Name = "Pivots Seen", - CMD_Pivots_Help = "name > Displays known early game wild encounters for an area.", + CMD_Pivots_Help = "> Displays known early game wild encounters for an area.", CMD_Revo_Name = "Pokémon Random Evolutions", CMD_Revo_Help = "name [target-evo] > Displays randomized evolution possibilities for a Pokémon, and it's [target-evo] if more than one available.", CMD_Coverage_Name = "Move Coverage Effectiveness", From 08c0e9cfed2ea4cf2ed269c599741d14b70f55ca Mon Sep 17 00:00:00 2001 From: UTDZac Date: Tue, 17 Sep 2024 13:32:25 -0700 Subject: [PATCH 04/12] Add !unfought command to show remaining trainers Gives a contextually relevant list of available unfought trainers, helping guide the player to go find trainers they may have missed. --- ironmon_tracker/Languages/English.lua | 2 + ironmon_tracker/Languages/French.lua | 2 + ironmon_tracker/Languages/German.lua | 2 + ironmon_tracker/Languages/Italian.lua | 2 + ironmon_tracker/Languages/Japanese.lua | 2 + ironmon_tracker/Languages/Spanish.lua | 2 + ironmon_tracker/Program.lua | 5 +- ironmon_tracker/data/DataHelper.lua | 86 ++++++++- ironmon_tracker/data/RouteData.lua | 227 ++++++++++++++++++++--- ironmon_tracker/data/TrainerData.lua | 67 +++++++ ironmon_tracker/network/EventHandler.lua | 12 +- 11 files changed, 369 insertions(+), 40 deletions(-) diff --git a/ironmon_tracker/Languages/English.lua b/ironmon_tracker/Languages/English.lua index 73e614de..d35c31f3 100644 --- a/ironmon_tracker/Languages/English.lua +++ b/ironmon_tracker/Languages/English.lua @@ -613,6 +613,8 @@ ScreenResources{ CMD_Route_Help = "name > Displays trainer and wild encounter info for a route or area.", CMD_Dungeon_Name = "Dungeon Info", CMD_Dungeon_Help = "name > Displays info about which trainers have been defeated for an area.", + CMD_Unfought_Name = "Unfought Trainers", + CMD_Unfought_Help = "[dungeon] [sevii]> Displays a summary of areas with trainers that have yet to be defeated. Use 'dungeon' to include partially completed dungeons.", CMD_Pivots_Name = "Pivots Seen", CMD_Pivots_Help = "> Displays known early game wild encounters for an area.", CMD_Revo_Name = "Pokémon Random Evolutions", diff --git a/ironmon_tracker/Languages/French.lua b/ironmon_tracker/Languages/French.lua index a384ac85..f2c384a2 100644 --- a/ironmon_tracker/Languages/French.lua +++ b/ironmon_tracker/Languages/French.lua @@ -614,6 +614,8 @@ ScreenResources{ CMD_Route_Help = "name > Displays trainer and wild encounter info for a route or area.", CMD_Dungeon_Name = "Dungeon Info", CMD_Dungeon_Help = "name > Displays info about which trainers have been defeated for an area.", + CMD_Unfought_Name = "Unfought Trainers", + CMD_Unfought_Help = "[dungeon] [sevii]> Displays a summary of areas with trainers that have yet to be defeated. Use 'dungeon' to include partially completed dungeons.", CMD_Pivots_Name = "Pivots Seen", CMD_Pivots_Help = "> Displays known early game wild encounters for an area.", CMD_Revo_Name = "Pokémon Random Evolutions", diff --git a/ironmon_tracker/Languages/German.lua b/ironmon_tracker/Languages/German.lua index 3f4b1731..4d42d383 100644 --- a/ironmon_tracker/Languages/German.lua +++ b/ironmon_tracker/Languages/German.lua @@ -614,6 +614,8 @@ ScreenResources{ CMD_Route_Help = "name > Displays trainer and wild encounter info for a route or area.", CMD_Dungeon_Name = "Dungeon Info", CMD_Dungeon_Help = "name > Displays info about which trainers have been defeated for an area.", + CMD_Unfought_Name = "Unfought Trainers", + CMD_Unfought_Help = "[dungeon] [sevii]> Displays a summary of areas with trainers that have yet to be defeated. Use 'dungeon' to include partially completed dungeons.", CMD_Pivots_Name = "Pivots Seen", CMD_Pivots_Help = "> Displays known early game wild encounters for an area.", CMD_Revo_Name = "Pokémon Random Evolutions", diff --git a/ironmon_tracker/Languages/Italian.lua b/ironmon_tracker/Languages/Italian.lua index e32095a2..5ad4fd83 100644 --- a/ironmon_tracker/Languages/Italian.lua +++ b/ironmon_tracker/Languages/Italian.lua @@ -614,6 +614,8 @@ ScreenResources{ CMD_Route_Help = "name > Displays trainer and wild encounter info for a route or area.", CMD_Dungeon_Name = "Dungeon Info", CMD_Dungeon_Help = "name > Displays info about which trainers have been defeated for an area.", + CMD_Unfought_Name = "Unfought Trainers", + CMD_Unfought_Help = "[dungeon] [sevii]> Displays a summary of areas with trainers that have yet to be defeated. Use 'dungeon' to include partially completed dungeons.", CMD_Pivots_Name = "Pivots Seen", CMD_Pivots_Help = "> Displays known early game wild encounters for an area.", CMD_Revo_Name = "Pokémon Random Evolutions", diff --git a/ironmon_tracker/Languages/Japanese.lua b/ironmon_tracker/Languages/Japanese.lua index 60b95d6c..41259f45 100644 --- a/ironmon_tracker/Languages/Japanese.lua +++ b/ironmon_tracker/Languages/Japanese.lua @@ -616,6 +616,8 @@ ScreenResources{ CMD_Route_Help = "name > Displays trainer and wild encounter info for a route or area.", CMD_Dungeon_Name = "Dungeon Info", CMD_Dungeon_Help = "name > Displays info about which trainers have been defeated for an area.", + CMD_Unfought_Name = "Unfought Trainers", + CMD_Unfought_Help = "[dungeon] [sevii]> Displays a summary of areas with trainers that have yet to be defeated. Use 'dungeon' to include partially completed dungeons.", CMD_Pivots_Name = "Pivots Seen", CMD_Pivots_Help = "> Displays known early game wild encounters for an area.", CMD_Revo_Name = "Pokémon Random Evolutions", diff --git a/ironmon_tracker/Languages/Spanish.lua b/ironmon_tracker/Languages/Spanish.lua index 2e78b35c..c3c2c399 100644 --- a/ironmon_tracker/Languages/Spanish.lua +++ b/ironmon_tracker/Languages/Spanish.lua @@ -614,6 +614,8 @@ ScreenResources{ CMD_Route_Help = "name > Displays trainer and wild encounter info for a route or area.", CMD_Dungeon_Name = "Dungeon Info", CMD_Dungeon_Help = "name > Displays info about which trainers have been defeated for an area.", + CMD_Unfought_Name = "Unfought Trainers", + CMD_Unfought_Help = "[dungeon] [sevii]> Displays a summary of areas with trainers that have yet to be defeated. Use 'dungeon' to include partially completed dungeons.", CMD_Pivots_Name = "Pivots Seen", CMD_Pivots_Help = "> Displays known early game wild encounters for an area.", CMD_Revo_Name = "Pokémon Random Evolutions", diff --git a/ironmon_tracker/Program.lua b/ironmon_tracker/Program.lua index 1a3a7b6a..e2818b18 100644 --- a/ironmon_tracker/Program.lua +++ b/ironmon_tracker/Program.lua @@ -1147,10 +1147,11 @@ end --- Returns a list of trainerIds of trainers defeated in the combined area (Use RouteData.CombinedAreas), as well as the total number of trainers in those areas --- @param mapIdList table +--- @param saveBlock1Addr number? (Optional) Include the SaveBlock 1 address if known to avoid extra memory reads --- @return table defeatedTrainers, number totalTrainers -function Program.getDefeatedTrainersByCombinedArea(mapIdList) +function Program.getDefeatedTrainersByCombinedArea(mapIdList, saveBlock1Addr) if type(mapIdList) ~= "table" then return {}, 0 end - local saveBlock1Addr = Utils.getSaveBlock1Addr() + saveBlock1Addr = saveBlock1Addr or Utils.getSaveBlock1Addr() local totalTrainers = 0 local defeatedTrainers = {} for _, mapId in ipairs(mapIdList) do diff --git a/ironmon_tracker/data/DataHelper.lua b/ironmon_tracker/data/DataHelper.lua index 2371f0e3..f5ec1e34 100644 --- a/ironmon_tracker/data/DataHelper.lua +++ b/ironmon_tracker/data/DataHelper.lua @@ -1132,9 +1132,89 @@ end ---@param params string? ---@return string response -function DataHelper.EventRequests.getRemainingTrainers(params) - -- TODO: Implement in a later patch - return buildDefaultResponse(params) +function DataHelper.EventRequests.getUnfoughtTrainers(params) + local allowPartialDungeons = Utils.containsText(params, "dungeon", true) + local includeSevii + if GameSettings.game == 3 then + includeSevii = Utils.containsText(params, "sevii", true) + else + includeSevii = true -- to allow routes above the sevii route id for RSE + end + + local MAX_AREAS_TO_CHECK = 6 + local saveBlock1Addr = Utils.getSaveBlock1Addr() + local trainersToExclude = TrainerData.getExcludedTrainers() + local currentRouteId = TrackerAPI.getMapId() + + -- Build a map of all trainers to what route they are on + local trainerToRoute = {} + for routeId, route in pairs(RouteData.Info or {}) do + local canUseRoute = (includeSevii or routeId < 230) -- find a way to check for dungeons + if canUseRoute and route.trainers and #route.trainers > 0 then + for _, trainerId in ipairs(route.trainers or {}) do + trainerToRoute[trainerId] = routeId + end + end + end + + local info = {} + local checkedIds = {} + for _, trainerId in ipairs(TrainerData.OrderedIds or {}) do + if not checkedIds[trainerId] and not trainersToExclude[trainerId] and trainerToRoute[trainerId] then + -- Check area for defeated trainers and mark each trainer as checked + local routeId = trainerToRoute[trainerId] or -1 + local route = RouteData.Info[routeId] or {} + local defeatedTrainers, totalTrainers + local ifDungeonAndIncluded = true -- true for non-dungeons, otherwise gets excluded if partially completed + if route.area ~= nil then + defeatedTrainers, totalTrainers = Program.getDefeatedTrainersByCombinedArea(route.area, saveBlock1Addr) + -- Don't include dungeons that are partially completed unless the player is currently there + if route.area.dungeon and #defeatedTrainers > 0 then + local isThere = false + for _, id in ipairs(route.area or {}) do + if id == currentRouteId then + isThere = true + break + end + end + ifDungeonAndIncluded = isThere or allowPartialDungeons + end + for _, areaRouteId in ipairs(route.area) do + local areaRoute = RouteData.Info[areaRouteId] or {} + for _, id in ipairs(areaRoute.trainers or {}) do + checkedIds[id] = true + end + end + elseif route.trainers and #route.trainers > 0 then + defeatedTrainers, totalTrainers = Program.getDefeatedTrainersByLocation(routeId, saveBlock1Addr) + -- Don't include dungeons that are partially completed unless the player is currently there + if route.dungeon and #defeatedTrainers > 0 and currentRouteId ~= routeId then + ifDungeonAndIncluded = allowPartialDungeons + end + for _, id in ipairs(route.trainers) do + checkedIds[id] = true + end + end + + -- Add to info if area has unfought trainers (not all defeated) + if defeatedTrainers and totalTrainers and #defeatedTrainers < totalTrainers and ifDungeonAndIncluded then + local routeName = route.area and route.area.name or route.name + local routeText = string.format("%s (%s/%s)", routeName, #defeatedTrainers, totalTrainers) + table.insert(info, routeText) + end + + if #info >= MAX_AREAS_TO_CHECK then + table.insert(info, "...") + break + end + end + end + if #info == 0 then + table.insert(info, "All available trainers have been defeated!") + end + + local prefix = string.format("%s %s", "Unfought Trainers", OUTPUT_CHAR) + return buildResponse(prefix, info, ", ") end ---@param params string? diff --git a/ironmon_tracker/data/RouteData.lua b/ironmon_tracker/data/RouteData.lua index 1ca8292e..e9385af9 100644 --- a/ironmon_tracker/data/RouteData.lua +++ b/ironmon_tracker/data/RouteData.lua @@ -392,23 +392,23 @@ function RouteData.setupRouteInfoAsFRLG() -- [AreaName] = { combained list of mapIds } RouteData.CombinedAreas = { - MtMoon = { name = "Mt. Moon" }, - SSAnne = { name = "S.S. Anne" }, - RockTunnel = { name = "Rock Tunnel" }, - RocketHideout = { name = "Rocket Hideout" }, - PokemonTower = { name = "Pokémon Tower" }, - CinnabarMansion = { name = "Poké Mansion (Cinnabar)" }, - SilphCo = { name = "Silph Co." }, - VictoryRoad = { name = "Victory Road" }, - EliteFour = { name = "Elite Four (Indigo Plateau)" }, + MtMoon = { name = "Mt. Moon", dungeon = true }, + SSAnne = { name = "S.S. Anne", dungeon = true }, + RockTunnel = { name = "Rock Tunnel", dungeon = true }, + RocketHideout = { name = "Rocket Hideout", dungeon = true }, + PokemonTower = { name = "Pokémon Tower", dungeon = true }, + CinnabarMansion = { name = "Poké Mansion (Cinnabar)", dungeon = true }, + SilphCo = { name = "Silph Co.", dungeon = true }, + VictoryRoad = { name = "Victory Road", dungeon = true }, + EliteFour = { name = "Elite Four (Indigo Plateau)", dungeon = true }, SafariZone = { name = "Safari Zone" }, CeruleanCave = { name = "Cerulean Cave" }, SeafoamIslands = { name = "Seafoam Islands" }, SummitPath = { name = "Summit Path" }, RubyPath = { name = "Ruby Path" }, - IcefallCave = { name = "Icefall Cave" }, - TrainerTower = { name = "Trainer Tower" }, - LostCave = { name = "Lost Cave" }, + IcefallCave = { name = "Icefall Cave", dungeon = true }, + TrainerTower = { name = "Trainer Tower", dungeon = true }, + LostCave = { name = "Lost Cave", dungeon = true }, TanobyChambers = { name = "Tanoby Chambers" }, } @@ -432,6 +432,7 @@ function RouteData.setupRouteInfoAsFRLG() [5] = { name = "Oak's Lab", icon = RouteData.Icons.BuildingDoorSmall, + dungeon = true, trainers = { 326, 327, 328 }, }, [8] = { @@ -449,46 +450,55 @@ function RouteData.setupRouteInfoAsFRLG() [12] = { name = "Cerulean Gym", icon = RouteData.Icons.GymBuilding, + dungeon = true, trainers = { 150, 234, 415 }, }, [15] = { name = "Celadon Gym", icon = RouteData.Icons.GymBuilding, + dungeon = true, trainers = { 132, 133, 160, 265, 266, 267, 402, 417 }, }, [20] = { name = "Fuchsia Gym", icon = RouteData.Icons.GymBuilding, + dungeon = true, trainers = { 294, 295, 288, 289, 292, 293, 418 }, }, [25] = { name = "Vermilion Gym", icon = RouteData.Icons.GymBuilding, + dungeon = true, trainers = { 141, 220, 423, 416 }, }, [27] = { name = "Game Corner", icon = RouteData.Icons.BuildingDoorLarge, + dungeon = true, trainers = { 357 }, }, [28] = { name = "Pewter Gym", icon = RouteData.Icons.GymBuilding, + dungeon = true, trainers = { 142, 414 }, }, [34] = { name = "Saffron Gym", icon = RouteData.Icons.GymBuilding, + dungeon = true, trainers = { 280, 281, 282, 283, 462, 463, 464, 420 }, }, [36] = { name = "Cinnabar Gym", icon = RouteData.Icons.GymBuilding, + dungeon = true, trainers = { 177, 178, 179, 180, 213, 214, 215, 419 }, }, [37] = { name = "Viridian Gym", icon = RouteData.Icons.GymBuilding, + dungeon = true, trainers = { 296, 297, 322, 323, 324, 392, 400, 401, 350 }, }, [77] = { @@ -1145,6 +1155,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Mt. Moon 1F", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.MtMoon, + dungeon = true, trainers = { 181, 91, 120, 121, 169, 108, 109 }, [RouteData.EncounterArea.LAND] = { { pokemonID = 41, rate = 0.69, minLv = 7, maxLv = 10, }, @@ -1157,6 +1168,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Mt. Moon B1F", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.MtMoon, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 46, rate = 1.00, minLv = 5, maxLv = 10, }, }, @@ -1165,6 +1177,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Mt. Moon B2F", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.MtMoon, + dungeon = true, trainers = { 170, 351, 352, 353, 354 }, [RouteData.EncounterArea.LAND] = { { pokemonID = 41, rate = 0.49, minLv = 8, maxLv = 11, }, @@ -1189,32 +1202,38 @@ function RouteData.setupRouteInfoAsFRLG() name = "S.S. Anne Ext.", -- Exterior icon = RouteData.Icons.BuildingDoorSmall, area = RouteData.CombinedAreas.SSAnne, + dungeon = true, }, [119] = { name = "S.S. Anne 1F", icon = RouteData.Icons.BuildingDoorSmall, area = RouteData.CombinedAreas.SSAnne, + dungeon = true, }, [120] = { name = "S.S. Anne 2F", -- 2F corridor (Rival Fight) icon = RouteData.Icons.BuildingDoorSmall, area = RouteData.CombinedAreas.SSAnne, + dungeon = true, trainers = { 426, 427, 428 }, }, [121] = { name = "S.S. Anne 3F", icon = RouteData.Icons.BuildingDoorSmall, area = RouteData.CombinedAreas.SSAnne, + dungeon = true, }, [122] = { name = "S.S. Anne B1F", icon = RouteData.Icons.BuildingDoorSmall, area = RouteData.CombinedAreas.SSAnne, + dungeon = true, }, [123] = { name = "S.S. Anne Deck", icon = RouteData.Icons.BuildingDoorSmall, area = RouteData.CombinedAreas.SSAnne, + dungeon = true, trainers = { 134, 135 }, }, [124] = { @@ -1229,6 +1248,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Victory Road 1F", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.VictoryRoad, + dungeon = true, trainers = { 406, 396 }, [RouteData.EncounterArea.LAND] = { { pokemonID = 95, rate = 0.30, minLv = 40, maxLv = 46, }, @@ -1245,6 +1265,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Victory Road 2F", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.VictoryRoad, + dungeon = true, trainers = { 167, 325, 287, 290, 298 }, [RouteData.EncounterArea.LAND] = { { pokemonID = 66, rate = 0.20, minLv = 34, maxLv = 34, }, @@ -1262,6 +1283,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Victory Road 3F", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.VictoryRoad, + dungeon = true, trainers = { 393, 394, 403, 404, 485, 485 }, [RouteData.EncounterArea.LAND] = { { pokemonID = 95, rate = 0.30, minLv = 40, maxLv = 46, }, @@ -1278,95 +1300,111 @@ function RouteData.setupRouteInfoAsFRLG() name = "Rocket Hideout B1F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.RocketHideout, + dungeon = true, trainers = { 358, 359, 360, 361, 362 }, }, [129] = { name = "Rocket Hideout B2F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.RocketHideout, + dungeon = true, trainers = { 363 }, }, [130] = { name = "Rocket Hideout B3F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.RocketHideout, + dungeon = true, trainers = { 364, 365 }, }, [131] = { name = "Rocket Hideout B4F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.RocketHideout, + dungeon = true, trainers = { 348, 368, 366, 367 }, }, [132] = { name = "Silph Co. 1F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.SilphCo, + dungeon = true, }, [133] = { name = "Silph Co. 2F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.SilphCo, + dungeon = true, trainers = { 336, 337, 373, 374 }, }, [134] = { name = "Silph Co. 3F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.SilphCo, + dungeon = true, trainers = { 338, 375 }, }, [135] = { name = "Silph Co. 4F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.SilphCo, + dungeon = true, trainers = { 339, 376, 377 }, }, [136] = { name = "Silph Co. 5F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.SilphCo, + dungeon = true, trainers = { 340, 378, 379, 286 }, }, [137] = { name = "Silph Co. 6F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.SilphCo, + dungeon = true, trainers = { 341, 380, 381 }, }, [138] = { name = "Silph Co. 7F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.SilphCo, + dungeon = true, trainers = { 342, 383, 384, 385, 432, 433, 434 }, }, [139] = { name = "Silph Co. 8F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.SilphCo, + dungeon = true, trainers = { 343, 382, 386 }, }, [140] = { name = "Silph Co. 9F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.SilphCo, + dungeon = true, trainers = { 344, 387, 388 }, }, [141] = { name = "Silph Co. 10F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.SilphCo, + dungeon = true, trainers = { 345, 389 }, }, [142] = { name = "Silph Co. 11F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.SilphCo, + dungeon = true, trainers = { 349, 390, 391 }, }, [143] = { name = "Poké Mansion 1F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.CinnabarMansion, + dungeon = true, trainers = { 335, 534 }, [RouteData.EncounterArea.LAND] = { { pokemonID = 20, rate = 0.30, minLv = 32, maxLv = 36, }, @@ -1381,6 +1419,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Poké Mansion 2F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.CinnabarMansion, + dungeon = true, trainers = { 216 }, [RouteData.EncounterArea.LAND] = { { pokemonID = 20, rate = 0.30, minLv = 32, maxLv = 36, }, @@ -1395,6 +1434,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Poké Mansion 3F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.CinnabarMansion, + dungeon = true, trainers = { 218, 346 }, [RouteData.EncounterArea.LAND] = { { pokemonID = 20, rate = 0.30, minLv = 32, maxLv = 36, }, @@ -1409,6 +1449,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Poké Mansion B1F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.CinnabarMansion, + dungeon = true, trainers = { 219, 347 }, [RouteData.EncounterArea.LAND] = { { pokemonID = 20, rate = 0.30, minLv = 34, maxLv = 38, }, @@ -1656,6 +1697,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Rock Tunnel 1F", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.RockTunnel, + dungeon = true, trainers = { 192, 193, 194, 168, 476, 475, 474 }, [RouteData.EncounterArea.LAND] = { { pokemonID = 74, rate = 0.35, minLv = 15, maxLv = 17, }, @@ -1669,6 +1711,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Rock Tunnel B1F", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.RockTunnel, + dungeon = true, trainers = { 158, 159, 189, 190, 191, 164, 165, 166 }, [RouteData.EncounterArea.LAND] = { { pokemonID = 74, rate = 0.35, minLv = 15, maxLv = 17, }, @@ -1788,17 +1831,20 @@ function RouteData.setupRouteInfoAsFRLG() name = "Pokémon Tower 1F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.PokemonTower, + dungeon = true, }, [162] = { name = "Pokémon Tower 2F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.PokemonTower, + dungeon = true, trainers = { 429, 430, 431 }, }, [163] = { name = "Pokémon Tower 3F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.PokemonTower, + dungeon = true, trainers = { 441, 442, 443 }, [RouteData.EncounterArea.LAND] = { { pokemonID = 92, rate = 0.90, minLv = 13, maxLv = 19, }, @@ -1810,6 +1856,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Pokémon Tower 4F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.PokemonTower, + dungeon = true, trainers = { 444, 445, 446 }, [RouteData.EncounterArea.LAND] = { { pokemonID = 92, rate = 0.86, minLv = 13, maxLv = 19, }, @@ -1821,6 +1868,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Pokémon Tower 5F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.PokemonTower, + dungeon = true, trainers = { 447, 448, 449, 450 }, [RouteData.EncounterArea.LAND] = { { pokemonID = 92, rate = 0.86, minLv = 13, maxLv = 19, }, @@ -1832,6 +1880,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Pokémon Tower 6F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.PokemonTower, + dungeon = true, trainers = { 451, 452, 453 }, [RouteData.EncounterArea.LAND] = { { pokemonID = 92, rate = 0.85, minLv = 17, maxLv = 19, }, @@ -1846,6 +1895,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Pokémon Tower 7F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.PokemonTower, + dungeon = true, trainers = { 369, 370, 371 }, [RouteData.EncounterArea.LAND] = { { pokemonID = 92, rate = 0.75, minLv = 15, maxLv = 19, }, @@ -1872,12 +1922,14 @@ function RouteData.setupRouteInfoAsFRLG() name = "S.S. Anne Rooms", icon = RouteData.Icons.BuildingDoorSmall, area = RouteData.CombinedAreas.SSAnne, + dungeon = true, trainers = { 483, 127, 223, 482, 422, 421, 126, 96 }, -- Untested }, [178] = { name = "S.S. Anne Rooms", icon = RouteData.Icons.BuildingDoorSmall, area = RouteData.CombinedAreas.SSAnne, + dungeon = true, trainers = { 138, 139, 224, 140, 136, 137 }, -- Untested }, [212] = { @@ -1888,30 +1940,35 @@ function RouteData.setupRouteInfoAsFRLG() name = "Lorelei's Room", icon = RouteData.Icons.EliteFourStatue, area = RouteData.CombinedAreas.EliteFour, + dungeon = true, trainers = { 410 }, }, [214] = { name = "Bruno's Room", icon = RouteData.Icons.EliteFourStatue, area = RouteData.CombinedAreas.EliteFour, + dungeon = true, trainers = { 411 }, }, [215] = { name = "Agatha's Room", icon = RouteData.Icons.EliteFourStatue, area = RouteData.CombinedAreas.EliteFour, + dungeon = true, trainers = { 412 }, }, [216] = { name = "Lance's Room", icon = RouteData.Icons.EliteFourStatue, area = RouteData.CombinedAreas.EliteFour, + dungeon = true, trainers = { 413 }, }, [217] = { name = "Champion's Room", icon = RouteData.Icons.EliteFourStatue, area = RouteData.CombinedAreas.EliteFour, + dungeon = true, trainers = { 438, 439, 440 }, }, [219] = { @@ -1938,6 +1995,7 @@ function RouteData.setupRouteInfoAsFRLG() [228] = { name = "Dojo", icon = RouteData.Icons.BuildingDoorSmall, + dungeon = true, trainers = { 321, 319, 320, 318, 317 }, }, -- [[Sevii Isles]] @@ -2634,12 +2692,14 @@ function RouteData.setupRouteInfoAsFRLG() [292] = { name = "Rocket Warehouse", icon = RouteData.Icons.BuildingDoorSmall, + dungeon = true, trainers = { 545, 541, 542, 544, 516, 543 }, }, [293] = { name = "Icefall Cave Entrance", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.IcefallCave, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 86, rate = 0.40, minLv = 43, maxLv = 47, }, { pokemonID = 42, rate = 0.25, minLv = 45, maxLv = 48, }, @@ -2672,6 +2732,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Icefall Cave 1F", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.IcefallCave, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 220, rate = 0.50, minLv = 23, maxLv = 31, }, { pokemonID = 42, rate = 0.25, minLv = 45, maxLv = 48, }, @@ -2684,6 +2745,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Icefall Cave B1F", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.IcefallCave, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 220, rate = 0.50, minLv = 23, maxLv = 31, }, { pokemonID = 42, rate = 0.25, minLv = 45, maxLv = 48, }, @@ -2696,6 +2758,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Icefall Cave Back", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.IcefallCave, + dungeon = true, trainers = { 539 }, [RouteData.EncounterArea.LAND] = { { pokemonID = 86, rate = 0.40, minLv = 43, maxLv = 47, }, @@ -2728,41 +2791,49 @@ function RouteData.setupRouteInfoAsFRLG() name = "Trainer Tower 1F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.TrainerTower, + dungeon = true, }, [299] = { name = "Trainer Tower 2F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.TrainerTower, + dungeon = true, }, [300] = { name = "Trainer Tower 3F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.TrainerTower, + dungeon = true, }, [301] = { name = "Trainer Tower 4F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.TrainerTower, + dungeon = true, }, [302] = { name = "Trainer Tower 5F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.TrainerTower, + dungeon = true, }, [303] = { name = "Trainer Tower 6F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.TrainerTower, + dungeon = true, }, [304] = { name = "Trainer Tower 7F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.TrainerTower, + dungeon = true, }, [305] = { name = "Trainer Tower 8F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.TrainerTower, + dungeon = true, }, [317] = { name = "Pattern Bush", @@ -2782,6 +2853,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Lost Cave Room 1", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.LostCave, + dungeon = true, trainers = { 607 }, [RouteData.EncounterArea.LAND] = { { pokemonID = 93, rate = 0.30, minLv = 44, maxLv = 52, }, @@ -2795,6 +2867,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Lost Cave Room 2", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.LostCave, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 93, rate = 0.30, minLv = 44, maxLv = 52, }, { pokemonID = 92, rate = 0.25, minLv = 38, maxLv = 40, }, @@ -2807,6 +2880,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Lost Cave Room 3", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.LostCave, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 93, rate = 0.30, minLv = 44, maxLv = 52, }, { pokemonID = 92, rate = 0.25, minLv = 38, maxLv = 40, }, @@ -2819,6 +2893,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Lost Cave Room 4", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.LostCave, + dungeon = true, trainers = { 608 }, [RouteData.EncounterArea.LAND] = { { pokemonID = 93, rate = 0.30, minLv = 44, maxLv = 52, }, @@ -2832,6 +2907,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Lost Cave Room 5", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.LostCave, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 93, rate = 0.30, minLv = 44, maxLv = 52, }, { pokemonID = 92, rate = 0.25, minLv = 38, maxLv = 40, }, @@ -2844,6 +2920,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Lost Cave Room 6", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.LostCave, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 93, rate = 0.30, minLv = 44, maxLv = 52, }, { pokemonID = 92, rate = 0.25, minLv = 38, maxLv = 40, }, @@ -2856,6 +2933,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Lost Cave Room 7", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.LostCave, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 93, rate = 0.30, minLv = 44, maxLv = 52, }, { pokemonID = 92, rate = 0.25, minLv = 38, maxLv = 40, }, @@ -2868,6 +2946,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Lost Cave Room 8", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.LostCave, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 93, rate = 0.30, minLv = 44, maxLv = 52, }, { pokemonID = 92, rate = 0.25, minLv = 38, maxLv = 40, }, @@ -2880,6 +2959,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Lost Cave Room 9", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.LostCave, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 93, rate = 0.30, minLv = 44, maxLv = 52, }, { pokemonID = 92, rate = 0.25, minLv = 38, maxLv = 40, }, @@ -2892,6 +2972,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Lost Cave Room 10", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.LostCave, + dungeon = true, trainers = { 606 }, [RouteData.EncounterArea.LAND] = { { pokemonID = 93, rate = 0.30, minLv = 44, maxLv = 52, }, @@ -2905,6 +2986,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Lost Cave Room 11", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.LostCave, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 93, rate = 0.30, minLv = 44, maxLv = 52, }, { pokemonID = 41, rate = 0.20, minLv = 37, maxLv = 37, }, @@ -2917,6 +2999,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Lost Cave Room 12", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.LostCave, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 93, rate = 0.30, minLv = 44, maxLv = 52, }, { pokemonID = 41, rate = 0.20, minLv = 37, maxLv = 37, }, @@ -2929,6 +3012,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Lost Cave Room 13", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.LostCave, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 93, rate = 0.30, minLv = 44, maxLv = 52, }, { pokemonID = 41, rate = 0.20, minLv = 37, maxLv = 37, }, @@ -2941,6 +3025,7 @@ function RouteData.setupRouteInfoAsFRLG() name = "Lost Cave Room 14", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.LostCave, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 93, rate = 0.30, minLv = 44, maxLv = 52, }, { pokemonID = 41, rate = 0.20, minLv = 37, maxLv = 37, }, @@ -3080,27 +3165,27 @@ function RouteData.setupRouteInfoAsRSE() -- [AreaName] = { combained list of mapIds } RouteData.CombinedAreas = { - GraniteCave = { name = "Granite Cave" }, + GraniteCave = { name = "Granite Cave", dungeon = true }, OceanicMuseum = { name = "Oceanic Museum" }, - TrickHouse = { name = "Trick House" }, - MeteorFalls = { name = "Meteor Falls" }, - LavaridgeGym = { name = "Lavaridge Gym" }, + TrickHouse = { name = "Trick House", dungeon = true }, + MeteorFalls = { name = "Meteor Falls", dungeon = true }, + LavaridgeGym = { name = "Lavaridge Gym", dungeon = true }, MirageTower = { name = "Mirage Tower" }, - AbandonedShip = { name = "Abandoned Ship" }, - WeatherInstitute = { name = "Weather Institute" }, - MtPyre = { name = "Mt. Pyre" }, - MagmaHideout = { name = "Magma Hideout" }, - AquaHideout = { name = "Aqua Hideout" }, - SpaceCenter = { name = "Space Center" }, + AbandonedShip = { name = "Abandoned Ship", dungeon = true }, + WeatherInstitute = { name = "Weather Institute", dungeon = true }, + MtPyre = { name = "Mt. Pyre", dungeon = true }, + MagmaHideout = { name = "Magma Hideout", dungeon = true }, + AquaHideout = { name = "Aqua Hideout", dungeon = true }, + SpaceCenter = { name = "Space Center", dungeon = true }, CaveOrigin = { name = "Cave of Origin" }, - SootopolisGym = { name = "Sootopolis Gym" }, + SootopolisGym = { name = "Sootopolis Gym", dungeon = true }, SkyPillar = { name = "Sky Pillar" }, - VictoryRoad = { name = "Victory Road" }, - EliteFour = { name = "Elite Four (Ever Grande City)" }, - SSTidal = { name = "S.S. Tidal" }, - SeafloorCavern = { name = "Seafloor Cavern" }, + VictoryRoad = { name = "Victory Road", dungeon = true }, + EliteFour = { name = "Elite Four (Ever Grande City)", dungeon = true }, + SSTidal = { name = "S.S. Tidal", dungeon = true }, + SeafloorCavern = { name = "Seafloor Cavern", dungeon = true }, ShoalCave = { name = "Shoal Cave" }, - NewMauville = { name = "New Mauville" }, + NewMauville = { name = "New Mauville", dungeon = true }, SafariZone = { name = "Safari Zone" }, ArtisanCave = { name = "Artisan Cave" }, NavelRock = { name = "Navel Rock" }, @@ -4219,18 +4304,21 @@ function RouteData.setupRouteInfoAsRSE() RouteData.Info[65] = { name = "Dewford Gym", icon = RouteData.Icons.GymBuilding, + dungeon = true, trainers = { 426, 573, 572, 179, 574, 425, 266 }, } RouteData.Info[69] = { name = "Lavaridge Gym 1F", icon = RouteData.Icons.GymBuilding, area = RouteData.CombinedAreas.LavaridgeGym, + dungeon = true, trainers = { 202, 204, 501, 201, 648, 203, 205, 650, 268 }, } RouteData.Info[70] = { name = "Lavaridge Gym B1F", icon = RouteData.Icons.GymBuilding, area = RouteData.CombinedAreas.LavaridgeGym, + dungeon = true, -- trainers = { }, -- Combine with id=69 } RouteData.Info[71] = { @@ -4240,6 +4328,7 @@ function RouteData.setupRouteInfoAsRSE() RouteData.Info[79] = { name = "Petalburg Gym", icon = RouteData.Icons.GymBuilding, + dungeon = true, trainers = { 71, 89, 72, 90, 73, 91, 74, 269 }, } RouteData.Info[86] = { @@ -4256,33 +4345,39 @@ function RouteData.setupRouteInfoAsRSE() RouteData.Info[89] = { name = "Mauville Gym", icon = RouteData.Icons.GymBuilding, + dungeon = true, trainers = { 649, 191, 323, 802, 194, 267 }, } RouteData.Info[94] = { name = "Rustboro Gym", icon = RouteData.Icons.GymBuilding, + dungeon = true, trainers = { 320, 321, 571, 265 }, } RouteData.Info[100] = { name = "Fortree Gym", icon = RouteData.Icons.GymBuilding, + dungeon = true, trainers = { 402, 401, 655, 654, 404, 803, 270 }, } RouteData.Info[108] = { name = "Mossdeep Gym", icon = RouteData.Icons.GymBuilding, + dungeon = true, trainers = { 233, 246, 245, 235, 591, 584, 583, 585, 582, 234, 575, 244, 271 }, } RouteData.Info[109] = { name = "Sootopolis Gym 1F", icon = RouteData.Icons.GymBuilding, area = RouteData.CombinedAreas.SootopolisGym, + dungeon = true, trainers = { 128, 613, 115, 502, 131, 614, 301, 130, 118, 129, 272 }, } RouteData.Info[110] = { name = "Sootopolis Gym B1F", icon = RouteData.Icons.GymBuilding, area = RouteData.CombinedAreas.SootopolisGym, + dungeon = true, -- trainers = { }, -- Combine with id=109 } -- Ruby/Sapphire gyms have different trainers @@ -4297,36 +4392,42 @@ function RouteData.setupRouteInfoAsRSE() name = "Sidney's Room", icon = RouteData.Icons.EliteFourStatue, area = RouteData.CombinedAreas.EliteFour, + dungeon = true, trainers = { 261 }, } RouteData.Info[112] = { name = "Phoebe's Room", icon = RouteData.Icons.EliteFourStatue, area = RouteData.CombinedAreas.EliteFour, + dungeon = true, trainers = { 262 }, } RouteData.Info[113] = { name = "Glacia's Room", icon = RouteData.Icons.EliteFourStatue, area = RouteData.CombinedAreas.EliteFour, + dungeon = true, trainers = { 263 }, } RouteData.Info[114] = { name = "Drake's Room", icon = RouteData.Icons.EliteFourStatue, area = RouteData.CombinedAreas.EliteFour, + dungeon = true, trainers = { 264 }, } RouteData.Info[115] = { name = "Champion's Room", icon = RouteData.Icons.EliteFourStatue, area = RouteData.CombinedAreas.EliteFour, + dungeon = true, trainers = { 335 }, } RouteData.Info[125 + offset] = { name = "Meteor Falls 1Fa", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.MeteorFalls, + dungeon = true, trainers = { 681, 392, 804 }, -- Combined [RouteData.EncounterArea.LAND] = { { pokemonID = 41, rate = 0.80, }, @@ -4353,6 +4454,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Meteor Falls 1Fb", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.MeteorFalls, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 42, rate = 0.65, }, { pokemonID = {338,337,338}, rate = 0.35, }, @@ -4379,6 +4481,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Meteor Falls 2Fa", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.MeteorFalls, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 42, rate = 0.65, }, { pokemonID = {338,337,338}, rate = 0.35, }, @@ -4405,6 +4508,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Meteor Falls 2Fb", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.MeteorFalls, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 42, rate = 0.50, }, { pokemonID = {338,337,338}, rate = 0.25, }, @@ -4433,6 +4537,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Meteor Falls 2Fc", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.MeteorFalls, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 42, rate = 0.50, }, { pokemonID = {338,337,338}, rate = 0.25, }, @@ -4453,6 +4558,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Granite Cave 1Fa", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.GraniteCave, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 296, rate = 0.50, }, { pokemonID = 41, rate = 0.30, }, @@ -4464,6 +4570,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Granite Cave B1F", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.GraniteCave, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 304, rate = 0.40, }, { pokemonID = 41, rate = 0.30, }, @@ -4476,6 +4583,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Granite Cave B2F", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.GraniteCave, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 304, rate = 0.40, }, { pokemonID = 41, rate = 0.30, }, @@ -4491,6 +4599,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Granite Cave 1Fb", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.GraniteCave, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 296, rate = 0.50, }, { pokemonID = 41, rate = 0.30, }, @@ -4522,6 +4631,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Mt. Pyre 1F", icon = RouteData.Icons.MountainTop, area = RouteData.CombinedAreas.MtPyre, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = {355,353,353}, rate = 1.00, }, }, @@ -4530,6 +4640,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Mt. Pyre 2F", icon = RouteData.Icons.MountainTop, area = RouteData.CombinedAreas.MtPyre, + dungeon = true, trainers = isGameEmerald and { 145, 35, 31, 640 } or { 145, 640 }, [RouteData.EncounterArea.LAND] = { @@ -4540,6 +4651,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Mt. Pyre 3F", icon = RouteData.Icons.MountainTop, area = RouteData.CombinedAreas.MtPyre, + dungeon = true, trainers = isGameEmerald and { 247, 9, 236 } or { 247, 236 }, [RouteData.EncounterArea.LAND] = { @@ -4550,6 +4662,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Mt. Pyre 4F", icon = RouteData.Icons.MountainTop, area = RouteData.CombinedAreas.MtPyre, + dungeon = true, trainers = { 109 }, [RouteData.EncounterArea.LAND] = { { pokemonID = {355,353,353}, rate = 0.90, }, @@ -4560,6 +4673,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Mt. Pyre 5F", icon = RouteData.Icons.MountainTop, area = RouteData.CombinedAreas.MtPyre, + dungeon = true, trainers = { 190 }, [RouteData.EncounterArea.LAND] = { { pokemonID = {355,353,353}, rate = 0.90, }, @@ -4570,6 +4684,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Mt. Pyre 6F", icon = RouteData.Icons.MountainTop, area = RouteData.CombinedAreas.MtPyre, + dungeon = true, trainers = isGameEmerald and { 108, 475 } or { 108 }, [RouteData.EncounterArea.LAND] = { @@ -4581,12 +4696,14 @@ function RouteData.setupRouteInfoAsRSE() name = "Aqua Hideout 1F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.AquaHideout, + dungeon = true, trainers = { 2, }, } RouteData.Info[144 + offset] = { name = "Aqua Hideout B1F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.AquaHideout, + dungeon = true, trainers = isGameEmerald and { 23, 3, 192, 193 } or { 23, 3 }, } @@ -4594,17 +4711,20 @@ function RouteData.setupRouteInfoAsRSE() name = "Aqua Hideout B2F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.AquaHideout, + dungeon = true, trainers = { 24, 27, 28, 30 }, } RouteData.Info[146 + offset] = { name = "Seafloor Cavern U.", -- Underwater icon = RouteData.Icons.OceanWaves, area = RouteData.CombinedAreas.SeafloorCavern, + dungeon = true, } RouteData.Info[147 + offset] = { name = "Seafloor Cavern", -- Entrance icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.SeafloorCavern, + dungeon = true, trainers = isGameEmerald and { 6, 7, 8, 9, 567, 33, 34 } -- All caverns combined here or { 6, 7, 8, 33, 34 }, [RouteData.EncounterArea.LAND] = { @@ -4633,31 +4753,37 @@ function RouteData.setupRouteInfoAsRSE() name = "Seafloor Cavern 1", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.SeafloorCavern, + dungeon = true, } RouteData.Info[149 + offset] = { name = "Seafloor Cavern 2", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.SeafloorCavern, + dungeon = true, } RouteData.Info[150 + offset] = { name = "Seafloor Cavern 3", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.SeafloorCavern, + dungeon = true, } RouteData.Info[151 + offset] = { name = "Seafloor Cavern 4", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.SeafloorCavern, + dungeon = true, } RouteData.Info[152 + offset] = { name = "Seafloor Cavern 5", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.SeafloorCavern, + dungeon = true, } RouteData.Info[153 + offset] = { name = "Seafloor Cavern 6", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.SeafloorCavern, + dungeon = true, [RouteData.EncounterArea.SURFING] = { { pokemonID = 72, rate = 0.60, }, { pokemonID = 41, rate = 0.35, }, @@ -4680,6 +4806,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Seafloor Cavern 7", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.SeafloorCavern, + dungeon = true, [RouteData.EncounterArea.SURFING] = { { pokemonID = 72, rate = 0.60, }, { pokemonID = 41, rate = 0.35, }, @@ -4702,11 +4829,13 @@ function RouteData.setupRouteInfoAsRSE() name = "Seafloor Cavern 8", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.SeafloorCavern, + dungeon = true, } RouteData.Info[156 + offset] = { name = "Seafloor Cavern 9", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.SeafloorCavern, + dungeon = true, } RouteData.Info[157 + offset] = { name = "Cave of Origin", @@ -4788,6 +4917,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Victory Road 1F", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.VictoryRoad, + dungeon = true, trainers = isGameEmerald and { 80, 96, 97, 81, 100, 83, 417, 38, 99, 82, 98, 540, 546, 79, 325, 324, 519 } or { 80, 96, 97, 81, 100, 83, 99, 82, 98, 79, 519 }, [RouteData.EncounterArea.LAND] = { @@ -4900,6 +5030,7 @@ function RouteData.setupRouteInfoAsRSE() name = "New Mauville 1", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.NewMauville, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 81, rate = 0.50, }, { pokemonID = 100, rate = 0.50, }, @@ -4909,6 +5040,7 @@ function RouteData.setupRouteInfoAsRSE() name = "New Mauville 2", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.NewMauville, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 81, rate = 0.49, }, { pokemonID = 100, rate = 0.49, }, @@ -4920,16 +5052,19 @@ function RouteData.setupRouteInfoAsRSE() name = "Abandoned Ship Deck", icon = RouteData.Icons.BuildingDoorSmall, area = RouteData.CombinedAreas.AbandonedShip, + dungeon = true, } RouteData.Info[187 + offset] = { name = "Abandoned Ship 1F", -- Corridors icon = RouteData.Icons.BuildingDoorSmall, area = RouteData.CombinedAreas.AbandonedShip, + dungeon = true, } RouteData.Info[188 + offset] = { name = "Abandoned Ship 1F", -- Rooms icon = RouteData.Icons.BuildingDoorSmall, area = RouteData.CombinedAreas.AbandonedShip, + dungeon = true, trainers = isGameEmerald and { 144, 375, 66, 547, 418, 642 } or { 66, 642 }, } @@ -4937,6 +5072,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Abandoned Ship B1F", -- Corridors icon = RouteData.Icons.BuildingDoorSmall, area = RouteData.CombinedAreas.AbandonedShip, + dungeon = true, [RouteData.EncounterArea.SURFING] = { { pokemonID = 72, rate = 0.99, }, { pokemonID = 73, rate = 0.01, }, @@ -4950,37 +5086,44 @@ function RouteData.setupRouteInfoAsRSE() name = "Abandoned Ship B1F", -- Rooms icon = RouteData.Icons.BuildingDoorSmall, area = RouteData.CombinedAreas.AbandonedShip, + dungeon = true, trainers = { 496 }, } RouteData.Info[191 + offset] = { name = "Abandoned Ship B1F", -- Rooms icon = RouteData.Icons.BuildingDoorSmall, area = RouteData.CombinedAreas.AbandonedShip, + dungeon = true, } RouteData.Info[192 + offset] = { name = "Abandoned Ship Uw1", -- Underwater 1 icon = RouteData.Icons.OceanWaves, area = RouteData.CombinedAreas.AbandonedShip, + dungeon = true, } RouteData.Info[193 + offset] = { name = "Abandoned Ship B1F", -- Rooms icon = RouteData.Icons.BuildingDoorSmall, area = RouteData.CombinedAreas.AbandonedShip, + dungeon = true, } RouteData.Info[194 + offset] = { name = "Abandoned Ship 1F", -- Rooms icon = RouteData.Icons.BuildingDoorSmall, area = RouteData.CombinedAreas.AbandonedShip, + dungeon = true, } RouteData.Info[195 + offset] = { name = "Abandoned Ship Cpt", -- Captain's Office icon = RouteData.Icons.BuildingDoorSmall, area = RouteData.CombinedAreas.AbandonedShip, + dungeon = true, } RouteData.Info[196 + offset] = { name = "Abandoned Ship Uw2", -- Underwater 2 icon = RouteData.Icons.OceanWaves, area = RouteData.CombinedAreas.AbandonedShip, + dungeon = true, } RouteData.Info[238 + offset] = { name = "Safari Zone NW.", @@ -5074,53 +5217,62 @@ function RouteData.setupRouteInfoAsRSE() RouteData.Info[243 + offset] = { name = "Seashore House", icon = RouteData.Icons.BuildingDoorSmall, + dungeon = true, trainers = { 65, 647, 493 }, } RouteData.Info[247 + offset] = { name = "Trick House 1", icon = RouteData.Icons.BuildingDoorSmall, area = RouteData.CombinedAreas.TrickHouse, + dungeon = true, trainers = { 611, 612, 332 }, } RouteData.Info[248 + offset] = { name = "Trick House 2", icon = RouteData.Icons.BuildingDoorSmall, area = RouteData.CombinedAreas.TrickHouse, + dungeon = true, trainers = { 274, 275, 281 }, } RouteData.Info[249 + offset] = { name = "Trick House 3", icon = RouteData.Icons.BuildingDoorSmall, area = RouteData.CombinedAreas.TrickHouse, + dungeon = true, trainers = { 215, 473, 630 }, } RouteData.Info[250 + offset] = { name = "Trick House 4", icon = RouteData.Icons.BuildingDoorSmall, area = RouteData.CombinedAreas.TrickHouse, + dungeon = true, trainers = { 188, 428, 429 }, } RouteData.Info[251 + offset] = { name = "Trick House 5", icon = RouteData.Icons.BuildingDoorSmall, area = RouteData.CombinedAreas.TrickHouse, + dungeon = true, } RouteData.Info[252 + offset] = { name = "Trick House 6", icon = RouteData.Icons.BuildingDoorSmall, area = RouteData.CombinedAreas.TrickHouse, + dungeon = true, trainers = { 561, 554, 407 }, } RouteData.Info[253 + offset] = { name = "Trick House 7", icon = RouteData.Icons.BuildingDoorSmall, area = RouteData.CombinedAreas.TrickHouse, + dungeon = true, trainers = { 237, 105, 248, 848, 850, 849 }, } RouteData.Info[254 + offset] = { name = "Trick House 8", icon = RouteData.Icons.BuildingDoorSmall, area = RouteData.CombinedAreas.TrickHouse, + dungeon = true, trainers = { 93, 76, 77 }, } RouteData.Info[270 + offset] = { @@ -5131,6 +5283,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Weather Institute 1F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.WeatherInstitute, + dungeon = true, trainers = isGameEmerald and { 26, 17, 596 } or { 26, 17 }, } @@ -5138,6 +5291,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Weather Institute 2F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.WeatherInstitute, + dungeon = true, trainers = { 18, 19, 32 }, } if isGameEmerald then @@ -5145,12 +5299,14 @@ function RouteData.setupRouteInfoAsRSE() name = "City Space Center 1F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.SpaceCenter, + dungeon = true, trainers = { 586, 22, 587, 116 }, } RouteData.Info[276 + offset] = { name = "City Space Center 2F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.SpaceCenter, + dungeon = true, trainers = { 588, 589, 590, 734, 514 }, } end @@ -5158,23 +5314,27 @@ function RouteData.setupRouteInfoAsRSE() name = "S.S. Tidal Hall", icon = RouteData.Icons.BuildingDoorSmall, area = RouteData.CombinedAreas.SSTidal, + dungeon = true, } RouteData.Info[278 + offset] = { name = "S.S. Tidal Deck", icon = RouteData.Icons.BuildingDoorSmall, area = RouteData.CombinedAreas.SSTidal, + dungeon = true, trainers = { 494, 495 }, } RouteData.Info[279 + offset] = { name = "S.S. Tidal Rooms", icon = RouteData.Icons.BuildingDoorSmall, area = RouteData.CombinedAreas.SSTidal, + dungeon = true, trainers = { 641, 138, 255, 294, 119, 256 }, } RouteData.Info[285 + offset] = { name = "Victory Road B1F", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.VictoryRoad, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 42, rate = 0.35, }, { pokemonID = 297, rate = 0.35, }, @@ -5191,6 +5351,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Victory Road B2F", icon = RouteData.Icons.CaveEntrance, area = RouteData.CombinedAreas.VictoryRoad, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 42, rate = 0.35, }, { pokemonID = {303,302,302}, rate = 0.35, }, @@ -5250,6 +5411,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Mt. Pyre Ext.", icon = RouteData.Icons.MountainTop, area = RouteData.CombinedAreas.MtPyre, + dungeon = true, trainers = isGameEmerald and { 5, 4, 569 } -- instead of 4,5 could be 23,24 or 27,28 or { 5, 4 }, [RouteData.EncounterArea.LAND] = { @@ -5263,6 +5425,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Mt. Pyre Summit", icon = RouteData.Icons.MountainTop, area = RouteData.CombinedAreas.MtPyre, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = {355,353,353}, rate = 0.85, }, { pokemonID = {355,353,353}, rate = 0.13, }, @@ -5341,6 +5504,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Magma Hideout 1F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.MagmaHideout, + dungeon = true, trainers = { 717, 716 }, [RouteData.EncounterArea.LAND] = { { pokemonID = 74, rate = 0.55, }, @@ -5352,6 +5516,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Magma Hideout 2Fa", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.MagmaHideout, + dungeon = true, trainers = { 718, 721, 720, 719, 727, 725, 722, 723 }, [RouteData.EncounterArea.LAND] = { { pokemonID = 74, rate = 0.55, }, @@ -5363,6 +5528,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Magma Hideout 2Fb", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.MagmaHideout, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 74, rate = 0.55, }, { pokemonID = 324, rate = 0.30, }, @@ -5373,6 +5539,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Magma Hideout 3Fa", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.MagmaHideout, + dungeon = true, trainers = { 724, 726, 729 }, [RouteData.EncounterArea.LAND] = { { pokemonID = 74, rate = 0.55, }, @@ -5384,6 +5551,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Magma Hideout 3Fb", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.MagmaHideout, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 74, rate = 0.55, }, { pokemonID = 324, rate = 0.30, }, @@ -5394,6 +5562,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Magma Hideout 4F", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.MagmaHideout, + dungeon = true, trainers = { 728, 730, 731, 732, 601 }, [RouteData.EncounterArea.LAND] = { { pokemonID = 74, rate = 0.55, }, @@ -5412,6 +5581,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Magma Hideout 3Fc", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.MagmaHideout, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 74, rate = 0.55, }, { pokemonID = 324, rate = 0.30, }, @@ -5422,6 +5592,7 @@ function RouteData.setupRouteInfoAsRSE() name = "Magma Hideout 2Fc", icon = RouteData.Icons.BuildingDoorLarge, area = RouteData.CombinedAreas.MagmaHideout, + dungeon = true, [RouteData.EncounterArea.LAND] = { { pokemonID = 74, rate = 0.55, }, { pokemonID = 324, rate = 0.30, }, diff --git a/ironmon_tracker/data/TrainerData.lua b/ironmon_tracker/data/TrainerData.lua index 14eb06bb..e6067e36 100644 --- a/ironmon_tracker/data/TrainerData.lua +++ b/ironmon_tracker/data/TrainerData.lua @@ -3,6 +3,7 @@ TrainerData = {} -- These are populated later after the game being played is determined TrainerData.Trainers = {} +TrainerData.OrderedIds = {} TrainerData.GymTMs = {} TrainerData.FinalTrainer = {} -- The final trainer to defeat to win Ironmon @@ -256,6 +257,25 @@ function TrainerData.setupTrainersAsRubySapphire() { leader = "Wallace", number = 3, }, } + -- Ordered by average level of party Pokémon, lowest to highest + TrainerData.OrderedIds = { + 616, 603, 615, 333, 318, 520, 523, 526, 529, 532, 535, 337, 319, 114, 136, 604, 320, 483, 617, 621, 631, 322, 280, 575, 273, + 351, 605, 336, 339, 321, 493, 581, 65, 340, 425, 491, 538, 545, 359, 57, 195, 464, 647, 64, 179, 334, 426, 490, 512, 586, 612, + 265, 332, 196, 227, 275, 302, 585, 606, 36, 37, 232, 243, 281, 292, 293, 352, 481, 611, 627, 635, 656, 338, 287, 194, 274, + 299, 344, 353, 358, 266, 419, 78, 94, 115, 191, 213, 312, 364, 369, 471, 476, 626, 629, 521, 524, 527, 530, 533, 536, 326, 51, + 189, 206, 214, 218, 323, 420, 427, 472, 628, 649, 143, 183, 327, 342, 434, 474, 513, 579, 597, 677, 267, 216, 632, 124, 125, + 126, 201, 212, 313, 630, 203, 205, 469, 473, 44, 202, 204, 211, 215, 447, 470, 648, 650, 345, 602, 350, 39, 152, 224, 225, 400, + 416, 445, 448, 693, 46, 153, 156, 158, 182, 188, 343, 408, 441, 446, 496, 584, 618, 619, 620, 651, 268, 692, 52, 58, 59, 66, + 71, 72, 73, 74, 89, 90, 91, 151, 154, 155, 157, 223, 387, 398, 399, 415, 428, 429, 442, 443, 444, 484, 559, 582, 583, 642, 680, + 45, 226, 307, 404, 552, 591, 599, 653, 383, 269, 75, 384, 402, 405, 435, 553, 560, 652, 654, 53, 107, 127, 190, 401, 403, 406, + 436, 522, 525, 528, 531, 534, 537, 568, 588, 655, 294, 669, 286, 270, 92, 95, 106, 109, 236, 238, 249, 254, 300, 378, 589, 592, + 673, 108, 145, 247, 413, 453, 567, 569, 596, 640, 667, 675, 661, 662, 663, 664, 665, 666, 159, 164, 181, 374, 450, 455, 458, + 463, 492, 570, 593, 668, 676, 88, 161, 165, 167, 170, 172, 174, 180, 414, 452, 460, 461, 671, 672, 674, 678, 686, 687, 160, + 162, 163, 166, 169, 235, 397, 449, 451, 454, 457, 670, 234, 244, 246, 376, 377, 385, 386, 407, 573, 171, 233, 245, 571, 168, + 301, 392, 459, 465, 561, 572, 600, 131, 554, 128, 248, 614, 681, 272, 118, 129, 130, 237, 613, 601, 81, 82, 83, 98, 105, 271, + 80, 99, 100, 495, 519, 76, 79, 96, 97, 255, 494, 93, 119, 138, 256, 641, 77, 261, 262, 263, 264, 335 + } + local classToTrainers = { [TrainerData.Classes.Archie] = { 1, 34, 35 }, [TrainerData.Classes.TeamAquaGrunt] = { {2, 29}, }, @@ -372,6 +392,31 @@ function TrainerData.setupTrainersAsEmerald() { leader = "Juan", number = 3, }, } + -- Ordered by average level of party Pokémon, lowest to highest + TrainerData.OrderedIds = { + 616, 333, 603, 615, 318, 520, 523, 526, 529, 532, 535, 483, 604, 621, 337, 319, 114, 136, 321, 571, 617, 631, 694, 695, 753, + 754, 351, 10, 273, 280, 322, 339, 605, 696, 336, 320, 16, 340, 493, 538, 545, 359, 57, 65, 490, 698, 265, 64, 179, 425, 426, + 491, 572, 573, 574, 647, 697, 334, 592, 593, 599, 600, 768, 769, 21, 36, 37, 302, 352, 512, 612, 699, 700, 715, 20, 196, 232, + 275, 293, 481, 606, 701, 702, 703, 735, 736, 332, 287, 227, 243, 281, 292, 344, 353, 358, 611, 635, 656, 627, 266, 51, 78, 94, + 191, 194, 274, 299, 323, 364, 369, 419, 471, 476, 626, 649, 755, 756, 757, 802, 338, 708, 709, 206, 213, 214, 218, 312, 420, + 427, 472, 513, 628, 629, 705, 706, 707, 710, 711, 712, 746, 747, 752, 143, 183, 189, 326, 327, 342, 434, 474, 521, 524, 527, + 530, 533, 536, 677, 704, 713, 714, 679, 146, 216, 579, 632, 597, 1, 124, 125, 126, 212, 217, 313, 566, 267, 202, 469, 470, 570, + 630, 743, 744, 745, 44, 201, 203, 204, 205, 211, 473, 501, 648, 650, 153, 154, 215, 224, 448, 740, 741, 602, 693, 268, 669, + 350, 46, 144, 158, 343, 345, 375, 399, 408, 416, 441, 444, 446, 496, 619, 620, 642, 651, 737, 738, 742, 760, 765, 766, 182, 9, + 19, 39, 58, 59, 66, 71, 72, 73, 74, 89, 90, 91, 151, 152, 155, 156, 157, 188, 223, 236, 247, 398, 400, 415, 418, 442, 443, 445, + 447, 484, 547, 559, 739, 748, 749, 750, 751, 759, 761, 692, 17, 18, 45, 52, 225, 226, 307, 401, 428, 429, 503, 539, 552, 596, + 655, 680, 26, 32, 75, 116, 405, 435, 553, 560, 618, 652, 653, 719, 720, 763, 269, 11, 92, 107, 127, 254, 404, 406, 654, 716, + 717, 718, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 764, 767, 12, 13, 29, 53, 95, 106, 195, 249, 300, 378, + 384, 402, 436, 522, 525, 528, 531, 534, 537, 569, 762, 803, 294, 387, 270, 286, 667, 3, 31, 35, 145, 164, 192, 238, 504, 505, + 586, 640, 2, 4, 5, 22, 23, 24, 27, 28, 108, 109, 180, 190, 193, 475, 577, 587, 588, 589, 590, 674, 661, 662, 663, 664, 665, 666, + 668, 673, 88, 137, 159, 167, 168, 174, 374, 377, 403, 413, 453, 455, 459, 461, 463, 492, 506, 507, 509, 511, 594, 598, 675, 733, + 758, 678, 687, 15, 30, 160, 161, 162, 163, 165, 166, 169, 170, 171, 172, 181, 383, 385, 397, 414, 449, 450, 451, 452, 454, 457, + 458, 460, 508, 510, 576, 580, 595, 670, 671, 672, 676, 686, 376, 386, 464, 567, 578, 6, 7, 8, 233, 234, 235, 244, 245, 246, 407, + 575, 582, 583, 584, 585, 591, 33, 130, 301, 392, 601, 465, 514, 561, 115, 131, 502, 554, 614, 681, 118, 128, 129, 613, 105, 237, + 248, 848, 849, 850, 34, 271, 272, 81, 82, 83, 98, 100, 38, 79, 80, 99, 324, 325, 417, 495, 540, 546, 734, 519, 76, 255, 494, 93, + 96, 97, 119, 138, 256, 641, 77, 261, 262, 263, 264, 335, 804 + } + local classToTrainers = { [TrainerData.Classes.Archie] = { 34 }, [TrainerData.Classes.AromaLady] = { 36, 37, {39, 43}, 705, 747 }, @@ -494,6 +539,28 @@ function TrainerData.setupTrainersAsFRLG() { leader = "Giovanni", number = 26, }, } + -- Ordered by average level of party Pokémon, lowest to highest (includes sevii) + TrainerData.OrderedIds = { + 326, 327, 328, 102, 103, 532, 531, 104, 106, 116, 329, 330, 331, 91, 105, 109, 110, 117, 181, 142, 89, 107, 108, 120, 169, 352, + 353, 123, 170, 414, 125, 183, 351, 354, 90, 92, 95, 118, 121, 143, 471, 93, 153, 182, 356, 111, 122, 146, 151, 152, 234, 332, + 333, 334, 94, 99, 135, 137, 139, 184, 223, 224, 355, 363, 483, 100, 126, 127, 134, 138, 144, 154, 222, 258, 259, 260, 261, 421, + 426, 427, 428, 415, 98, 114, 130, 149, 150, 188, 192, 361, 422, 475, 416, 112, 115, 140, 145, 156, 163, 164, 171, 186, 191, 193, + 357, 360, 364, 465, 474, 96, 97, 136, 141, 148, 157, 158, 185, 187, 189, 194, 220, 221, 228, 265, 358, 359, 365, 368, 131, 159, + 165, 172, 225, 262, 362, 402, 441, 446, 448, 450, 451, 476, 484, 535, 429, 430, 431, 128, 132, 133, 155, 168, 366, 367, 371, 423, + 443, 445, 447, 482, 129, 160, 226, 233, 264, 266, 267, 442, 444, 449, 452, 453, 467, 486, 536, 348, 166, 190, 197, 206, 301, 341, + 369, 374, 390, 417, 173, 207, 255, 302, 305, 309, 314, 336, 340, 370, 382, 385, 227, 231, 238, 241, 268, 276, 469, 195, 198, 202, + 208, 229, 244, 249, 306, 313, 316, 337, 344, 375, 377, 381, 386, 387, 388, 466, 470, 479, 162, 196, 199, 204, 205, 209, 236, 239, + 250, 251, 252, 253, 256, 269, 273, 274, 278, 285, 286, 300, 304, 307, 315, 335, 338, 342, 343, 345, 373, 376, 380, 383, 384, 477, + 478, 480, 487, 488, 489, 235, 237, 240, 271, 277, 279, 310, 468, 473, 490, 119, 230, 242, 272, 280, 288, 318, 321, 472, 248, 319, + 391, 201, 203, 232, 245, 247, 254, 282, 295, 303, 339, 346, 378, 379, 389, 464, 481, 491, 534, 178, 216, 219, 281, 289, 293, 294, + 308, 347, 462, 559, 519, 551, 243, 270, 538, 556, 177, 213, 320, 546, 555, 558, 548, 550, 349, 432, 433, 434, 180, 215, 246, 317, + 518, 523, 527, 537, 547, 554, 560, 218, 283, 292, 324, 400, 463, 528, 529, 539, 549, 552, 553, 561, 592, 597, 392, 401, 420, 418, + 595, 297, 557, 742, 167, 322, 179, 214, 287, 419, 393, 396, 403, 404, 406, 394, 296, 323, 325, 298, 350, 485, 545, 612, 291, 616, + 435, 436, 437, 590, 290, 520, 524, 540, 541, 565, 566, 567, 569, 591, 610, 613, 614, 615, 620, 599, 600, 564, 607, 570, 571, 572, + 517, 593, 608, 619, 587, 525, 516, 542, 568, 573, 574, 577, 579, 581, 583, 585, 596, 606, 611, 617, 618, 526, 562, 563, 575, 576, + 578, 580, 582, 584, 588, 589, 609, 521, 522, 586, 598, 601, 410, 543, 411, 544, 412, 413, 438, 439, 440 + } + local classToTrainers = { [TrainerData.Classes.AromaLady] = { 523, 558, 577, 588 }, [TrainerData.Classes.Beauty] = { {265, 269}, {273, 275}, 655, 666 }, diff --git a/ironmon_tracker/network/EventHandler.lua b/ironmon_tracker/network/EventHandler.lua index 07bcf16a..dcb84a5d 100644 --- a/ironmon_tracker/network/EventHandler.lua +++ b/ironmon_tracker/network/EventHandler.lua @@ -503,13 +503,11 @@ EventHandler.DefaultEvents = { Command = "!dungeon", Fulfill = function(self, request) return DataHelper.EventRequests.getDungeon(request.SanitizedInput) end, }, - -- CMD_RemainingTrainers = { - -- Type = EventHandler.EventTypes.Command, - -- Name = "Remaining Trainers", -- TODO: Move to Resources file - -- Command = "!trainers", - -- Help = "> Displays a summary of trainers that have yet to be defeated.", -- TODO: Move to Resources file - -- Fulfill = function(self, request) return DataHelper.EventRequests.getRemainingTrainers(request.SanitizedInput) end, - -- }, + CMD_Unfought = { + Type = EventHandler.EventTypes.Command, + Command = "!unfought", + Fulfill = function(self, request) return DataHelper.EventRequests.getUnfoughtTrainers(request.SanitizedInput) end, + }, CMD_Pivots = { Type = EventHandler.EventTypes.Command, Command = "!pivots", From 42a56cbaf507251b83414945b05bed6cb49a8612 Mon Sep 17 00:00:00 2001 From: UTDZac Date: Tue, 17 Sep 2024 20:41:33 -0700 Subject: [PATCH 05/12] [MGBA] Add EXP yield to Pokemon info screen --- ironmon_tracker/Languages/English.lua | 1 + ironmon_tracker/Languages/French.lua | 1 + ironmon_tracker/Languages/German.lua | 1 + ironmon_tracker/Languages/Italian.lua | 1 + ironmon_tracker/Languages/Japanese.lua | 1 + ironmon_tracker/Languages/Spanish.lua | 1 + ironmon_tracker/MGBADisplay.lua | 4 ++++ 7 files changed, 10 insertions(+) diff --git a/ironmon_tracker/Languages/English.lua b/ironmon_tracker/Languages/English.lua index d35c31f3..21622407 100644 --- a/ironmon_tracker/Languages/English.lua +++ b/ironmon_tracker/Languages/English.lua @@ -834,6 +834,7 @@ ScreenResources{ CommandsUsageSyntax = "Usage Syntax", CommandsExampleUsage = "Example Usage", PokemonInfoBST = "BST", + PokemonInfoEXP = "EXP", PokemonInfoWeight = "Weight", PokemonInfoEvolution = "Evolution", PokemonInfoKg = "kg", diff --git a/ironmon_tracker/Languages/French.lua b/ironmon_tracker/Languages/French.lua index f2c384a2..0f0558df 100644 --- a/ironmon_tracker/Languages/French.lua +++ b/ironmon_tracker/Languages/French.lua @@ -835,6 +835,7 @@ ScreenResources{ CommandsUsageSyntax = "Usage Syntax", -- NEEDS TRANSLATION CommandsExampleUsage = "Example Usage", -- NEEDS TRANSLATION PokemonInfoBST = "BST", -- NEEDS TRANSLATION + PokemonInfoEXP = "EXP", -- NEEDS TRANSLATION PokemonInfoWeight = "Weight", -- NEEDS TRANSLATION PokemonInfoEvolution = "Evolution", -- NEEDS TRANSLATION PokemonInfoKg = "kg", -- NEEDS TRANSLATION diff --git a/ironmon_tracker/Languages/German.lua b/ironmon_tracker/Languages/German.lua index 4d42d383..44f632f6 100644 --- a/ironmon_tracker/Languages/German.lua +++ b/ironmon_tracker/Languages/German.lua @@ -835,6 +835,7 @@ ScreenResources{ CommandsUsageSyntax = "Usage Syntax", -- NEEDS TRANSLATION CommandsExampleUsage = "Example Usage", -- NEEDS TRANSLATION PokemonInfoBST = "BST", -- NEEDS TRANSLATION + PokemonInfoEXP = "EXP", -- NEEDS TRANSLATION PokemonInfoWeight = "Weight", -- NEEDS TRANSLATION PokemonInfoEvolution = "Evolution", -- NEEDS TRANSLATION PokemonInfoKg = "kg", -- NEEDS TRANSLATION diff --git a/ironmon_tracker/Languages/Italian.lua b/ironmon_tracker/Languages/Italian.lua index 5ad4fd83..b5f68e3f 100644 --- a/ironmon_tracker/Languages/Italian.lua +++ b/ironmon_tracker/Languages/Italian.lua @@ -835,6 +835,7 @@ ScreenResources{ CommandsUsageSyntax = "Usage Syntax", -- NEEDS TRANSLATION CommandsExampleUsage = "Example Usage", -- NEEDS TRANSLATION PokemonInfoBST = "BST", -- NEEDS TRANSLATION + PokemonInfoEXP = "EXP", -- NEEDS TRANSLATION PokemonInfoWeight = "Weight", -- NEEDS TRANSLATION PokemonInfoEvolution = "Evolution", -- NEEDS TRANSLATION PokemonInfoKg = "kg", -- NEEDS TRANSLATION diff --git a/ironmon_tracker/Languages/Japanese.lua b/ironmon_tracker/Languages/Japanese.lua index 41259f45..54d2cd50 100644 --- a/ironmon_tracker/Languages/Japanese.lua +++ b/ironmon_tracker/Languages/Japanese.lua @@ -837,6 +837,7 @@ ScreenResources{ CommandsUsageSyntax = "Usage Syntax", -- NEEDS TRANSLATION CommandsExampleUsage = "Example Usage", -- NEEDS TRANSLATION PokemonInfoBST = "BST", -- NEEDS TRANSLATION + PokemonInfoEXP = "EXP", -- NEEDS TRANSLATION PokemonInfoWeight = "Weight", -- NEEDS TRANSLATION PokemonInfoEvolution = "Evolution", -- NEEDS TRANSLATION PokemonInfoKg = "kg", -- NEEDS TRANSLATION diff --git a/ironmon_tracker/Languages/Spanish.lua b/ironmon_tracker/Languages/Spanish.lua index c3c2c399..e8c702f5 100644 --- a/ironmon_tracker/Languages/Spanish.lua +++ b/ironmon_tracker/Languages/Spanish.lua @@ -835,6 +835,7 @@ ScreenResources{ CommandsUsageSyntax = "Usage Syntax", -- NEEDS TRANSLATION CommandsExampleUsage = "Example Usage", -- NEEDS TRANSLATION PokemonInfoBST = "BST", -- NEEDS TRANSLATION + PokemonInfoEXP = "EXP", -- NEEDS TRANSLATION PokemonInfoWeight = "Weight", -- NEEDS TRANSLATION PokemonInfoEvolution = "Evolution", -- NEEDS TRANSLATION PokemonInfoKg = "kg", -- NEEDS TRANSLATION diff --git a/ironmon_tracker/MGBADisplay.lua b/ironmon_tracker/MGBADisplay.lua index de56d827..3d133568 100644 --- a/ironmon_tracker/MGBADisplay.lua +++ b/ironmon_tracker/MGBADisplay.lua @@ -610,9 +610,13 @@ MGBADisplay.LineBuilder = { MGBADisplay.DataFormatter.formatPokemonInfo(data) + -- If viewing the mon, note that exp gained is calculated based on the viewed mon's level + local markExpAsBoosted = data.x.viewedPokemonLevel ~= 0 and "*" or "" + local labelBar = "%-12s %s" table.insert(lines, Utils.formatUTF8("%-13s%s", data.p.name, Utils.formatUTF8("[%s]", data.p.typeline))) table.insert(lines, Utils.formatUTF8(labelBar, Resources.MGBAScreens.PokemonInfoBST .. ":", data.p.bst)) + table.insert(lines, Utils.formatUTF8(labelBar, Resources.MGBAScreens.PokemonInfoEXP .. ":", data.p.expYield .. markExpAsBoosted)) table.insert(lines, Utils.formatUTF8(labelBar, Resources.MGBAScreens.PokemonInfoWeight .. ":", data.p.weight)) table.insert(lines, Utils.formatUTF8(labelBar, Resources.MGBAScreens.PokemonInfoEvolution .. ":", data.p.evodetails)) From 6a0ace5d70d3686ad2d51e8db06ce5634b45c779 Mon Sep 17 00:00:00 2001 From: UTDZac Date: Wed, 18 Sep 2024 11:53:22 -0700 Subject: [PATCH 06/12] Fix !unfought to strictly orderby weakest trainers Previously, it would orderby next available route with the next weakest trainer, meaning routes with a large level gap would incorrectly display first on the list. --- ironmon_tracker/data/DataHelper.lua | 116 +++++++++++++++------------ ironmon_tracker/data/TrainerData.lua | 19 ++++- 2 files changed, 83 insertions(+), 52 deletions(-) diff --git a/ironmon_tracker/data/DataHelper.lua b/ironmon_tracker/data/DataHelper.lua index f5ec1e34..0f636724 100644 --- a/ironmon_tracker/data/DataHelper.lua +++ b/ironmon_tracker/data/DataHelper.lua @@ -1141,76 +1141,90 @@ function DataHelper.EventRequests.getUnfoughtTrainers(params) includeSevii = true -- to allow routes above the sevii route id for RSE end - local MAX_AREAS_TO_CHECK = 6 + local MAX_AREAS_TO_CHECK = 7 local saveBlock1Addr = Utils.getSaveBlock1Addr() local trainersToExclude = TrainerData.getExcludedTrainers() local currentRouteId = TrackerAPI.getMapId() - -- Build a map of all trainers to what route they are on - local trainerToRoute = {} - for routeId, route in pairs(RouteData.Info or {}) do - local canUseRoute = (includeSevii or routeId < 230) -- find a way to check for dungeons - if canUseRoute and route.trainers and #route.trainers > 0 then - for _, trainerId in ipairs(route.trainers or {}) do - trainerToRoute[trainerId] = routeId - end - end - end - - local info = {} + -- For a given unfought trainer, this function returns unfought trainer counts for its route/area local checkedIds = {} - for _, trainerId in ipairs(TrainerData.OrderedIds or {}) do - if not checkedIds[trainerId] and not trainersToExclude[trainerId] and trainerToRoute[trainerId] then - -- Check area for defeated trainers and mark each trainer as checked - local routeId = trainerToRoute[trainerId] or -1 - local route = RouteData.Info[routeId] or {} - local defeatedTrainers, totalTrainers - local ifDungeonAndIncluded = true -- true for non-dungeons, otherwise gets excluded if partially completed - if route.area ~= nil then - defeatedTrainers, totalTrainers = Program.getDefeatedTrainersByCombinedArea(route.area, saveBlock1Addr) - -- Don't include dungeons that are partially completed unless the player is currently there - if route.area.dungeon and #defeatedTrainers > 0 then - local isThere = false - for _, id in ipairs(route.area or {}) do - if id == currentRouteId then - isThere = true - break - end - end - ifDungeonAndIncluded = isThere or allowPartialDungeons - end - for _, areaRouteId in ipairs(route.area) do - local areaRoute = RouteData.Info[areaRouteId] or {} - for _, id in ipairs(areaRoute.trainers or {}) do - checkedIds[id] = true + local function getUnfinishedRouteInfo(trainerId) + local trainer = TrainerData.Trainers[trainerId] or {} + local routeId = trainer.routeId or -1 + local route = RouteData.Info[routeId] or {} + + -- If sevii is excluded (default option), skip those routes and non-existent routes + if routeId == -1 or (routeId >= 230 and not includeSevii) then + return nil + end + -- Skip certain trainers, only checking unfought trainers + if checkedIds[trainerId] or trainersToExclude[trainerId] or not TrainerData.shouldUseTrainer(trainerId) then + return nil + end + if Program.hasDefeatedTrainer(trainerId, saveBlock1Addr) then + return nil + end + + -- Check area for defeated trainers and mark each trainer as checked + local defeatedTrainers = {} + local totalTrainers = 0 + local ifDungeonAndIncluded = true -- true for non-dungeons, otherwise gets excluded if partially completed + if route.area and #route.area > 0 then + defeatedTrainers, totalTrainers = Program.getDefeatedTrainersByCombinedArea(route.area, saveBlock1Addr) + -- Don't include dungeons that are partially completed unless the player is currently there + if route.area.dungeon and #defeatedTrainers > 0 then + local isThere = false + for _, id in ipairs(route.area or {}) do + if id == currentRouteId then + isThere = true + break end end - elseif route.trainers and #route.trainers > 0 then - defeatedTrainers, totalTrainers = Program.getDefeatedTrainersByLocation(routeId, saveBlock1Addr) - -- Don't include dungeons that are partially completed unless the player is currently there - if route.dungeon and #defeatedTrainers > 0 and currentRouteId ~= routeId then - ifDungeonAndIncluded = allowPartialDungeons - end - for _, id in ipairs(route.trainers) do + ifDungeonAndIncluded = isThere or allowPartialDungeons + end + for _, areaRouteId in ipairs(route.area) do + local areaRoute = RouteData.Info[areaRouteId] or {} + for _, id in ipairs(areaRoute.trainers or {}) do checkedIds[id] = true end end + elseif route.trainers and #route.trainers > 0 then + defeatedTrainers, totalTrainers = Program.getDefeatedTrainersByLocation(routeId, saveBlock1Addr) + -- Don't include dungeons that are partially completed unless the player is currently there + if route.dungeon and #defeatedTrainers > 0 and currentRouteId ~= routeId then + ifDungeonAndIncluded = allowPartialDungeons + end + for _, id in ipairs(route.trainers) do + checkedIds[id] = true + end + else + return nil + end + + -- Add to info if route/area has unfought trainers (not all defeated) + if #defeatedTrainers < totalTrainers and ifDungeonAndIncluded then + local routeName = route.area and route.area.name or route.name + return string.format("%s (%s/%s)", routeName, #defeatedTrainers, totalTrainers) + end + end - -- Add to info if area has unfought trainers (not all defeated) - if defeatedTrainers and totalTrainers and #defeatedTrainers < totalTrainers and ifDungeonAndIncluded then - local routeName = route.area and route.area.name or route.name - local routeText = string.format("%s (%s/%s)", routeName, #defeatedTrainers, totalTrainers) + local info = {} + for _, trainerId in ipairs(TrainerData.OrderedIds or {}) do + local routeText = getUnfinishedRouteInfo(trainerId) + if routeText ~= nil then table.insert(info, routeText) end - if #info >= MAX_AREAS_TO_CHECK then table.insert(info, "...") break end - end end if #info == 0 then - table.insert(info, "All available trainers have been defeated!") + local reminderText = "" + if not allowPartialDungeons or not includeSevii then + reminderText = ' (Use param "dungeon" and/or "sevii" to check partially completed dungeons or Sevii Islands.)' + end + table.insert(info, string.format("%s s", "All available trainers have been defeated!", reminderText)) end local prefix = string.format("%s %s", "Unfought Trainers", OUTPUT_CHAR) diff --git a/ironmon_tracker/data/TrainerData.lua b/ironmon_tracker/data/TrainerData.lua index e6067e36..fa430743 100644 --- a/ironmon_tracker/data/TrainerData.lua +++ b/ironmon_tracker/data/TrainerData.lua @@ -223,7 +223,7 @@ function TrainerData.getPortraitIcon(trainerClass) end -- Helper function to convert Class->{TrainerId(List)} to TrainerId->{Class,Group} -local mapClassesToTrainers = function(classMap, trainerList) +local function mapClassesToTrainers(classMap, trainerList) for class, trainers in pairs(classMap) do for _, item in pairs(trainers) do -- Could be a list of raw ids, or a range ids as pair (fromID, toID) @@ -245,6 +245,20 @@ local mapClassesToTrainers = function(classMap, trainerList) end end +-- For each trainer, add info on what route they can be found on +local function mapRoutesToTrainers() + for routeId, route in pairs(RouteData.Info or {}) do + if route.trainers and #route.trainers > 0 then + for _, trainerId in ipairs(route.trainers or {}) do + local trainer = TrainerData.Trainers[trainerId] + if trainer then + trainer.routeId = routeId + end + end + end + end +end + function TrainerData.setupTrainersAsRubySapphire() TrainerData.GymTMs = { { leader = "Roxanne", number = 39, }, @@ -349,6 +363,7 @@ function TrainerData.setupTrainersAsRubySapphire() TrainerData.Trainers = {} mapClassesToTrainers(classToTrainers, TrainerData.Trainers) + mapRoutesToTrainers() -- Mark Rivals so they can be distinguished TrainerData.Trainers[520].whichRival = "Brendan Left" @@ -490,6 +505,7 @@ function TrainerData.setupTrainersAsEmerald() TrainerData.Trainers = {} mapClassesToTrainers(classToTrainers, TrainerData.Trainers) + mapRoutesToTrainers() -- Mark Rivals so they can be distinguished TrainerData.Trainers[520].whichRival = "Brendan Left" @@ -625,6 +641,7 @@ function TrainerData.setupTrainersAsFRLG() TrainerData.Trainers = {} mapClassesToTrainers(classToTrainers, TrainerData.Trainers) + mapRoutesToTrainers() -- Custom trainer adjustments TrainerData.Trainers[317].group = TrainerData.TrainerGroups.Boss -- Dojo Leader From 6a84ec247e701682cfdc451c1fecdc23513fecf8 Mon Sep 17 00:00:00 2001 From: UTDZac Date: Wed, 18 Sep 2024 12:20:45 -0700 Subject: [PATCH 07/12] Fix code tab alignment, oops --- ironmon_tracker/data/DataHelper.lua | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ironmon_tracker/data/DataHelper.lua b/ironmon_tracker/data/DataHelper.lua index 0f636724..61fce392 100644 --- a/ironmon_tracker/data/DataHelper.lua +++ b/ironmon_tracker/data/DataHelper.lua @@ -1210,14 +1210,14 @@ function DataHelper.EventRequests.getUnfoughtTrainers(params) local info = {} for _, trainerId in ipairs(TrainerData.OrderedIds or {}) do - local routeText = getUnfinishedRouteInfo(trainerId) - if routeText ~= nil then - table.insert(info, routeText) - end - if #info >= MAX_AREAS_TO_CHECK then - table.insert(info, "...") - break - end + local routeText = getUnfinishedRouteInfo(trainerId) + if routeText ~= nil then + table.insert(info, routeText) + end + if #info >= MAX_AREAS_TO_CHECK then + table.insert(info, "...") + break + end end if #info == 0 then local reminderText = "" From e534a160630a05529f77769b75fd7a9bcfe34b01 Mon Sep 17 00:00:00 2001 From: UTDZac Date: Wed, 18 Sep 2024 15:15:21 -0700 Subject: [PATCH 08/12] Clarify help text for !unfought command --- ironmon_tracker/Languages/English.lua | 2 +- ironmon_tracker/Languages/French.lua | 2 +- ironmon_tracker/Languages/German.lua | 2 +- ironmon_tracker/Languages/Italian.lua | 2 +- ironmon_tracker/Languages/Japanese.lua | 2 +- ironmon_tracker/Languages/Spanish.lua | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ironmon_tracker/Languages/English.lua b/ironmon_tracker/Languages/English.lua index 21622407..b32a7405 100644 --- a/ironmon_tracker/Languages/English.lua +++ b/ironmon_tracker/Languages/English.lua @@ -614,7 +614,7 @@ ScreenResources{ CMD_Dungeon_Name = "Dungeon Info", CMD_Dungeon_Help = "name > Displays info about which trainers have been defeated for an area.", CMD_Unfought_Name = "Unfought Trainers", - CMD_Unfought_Help = "[dungeon] [sevii]> Displays a summary of areas with trainers that have yet to be defeated. Use 'dungeon' to include partially completed dungeons.", + CMD_Unfought_Help = "[dungeon] [sevii]> Displays a list of areas ordered by lowest-level, undefeated trainers. (Add param 'dungeon' to include partially completed dungeons.)", CMD_Pivots_Name = "Pivots Seen", CMD_Pivots_Help = "> Displays known early game wild encounters for an area.", CMD_Revo_Name = "Pokémon Random Evolutions", diff --git a/ironmon_tracker/Languages/French.lua b/ironmon_tracker/Languages/French.lua index 0f0558df..6d4071f6 100644 --- a/ironmon_tracker/Languages/French.lua +++ b/ironmon_tracker/Languages/French.lua @@ -615,7 +615,7 @@ ScreenResources{ CMD_Dungeon_Name = "Dungeon Info", CMD_Dungeon_Help = "name > Displays info about which trainers have been defeated for an area.", CMD_Unfought_Name = "Unfought Trainers", - CMD_Unfought_Help = "[dungeon] [sevii]> Displays a summary of areas with trainers that have yet to be defeated. Use 'dungeon' to include partially completed dungeons.", + CMD_Unfought_Help = "[dungeon] [sevii]> Displays a list of areas ordered by lowest-level, undefeated trainers. (Add param 'dungeon' to include partially completed dungeons.)", CMD_Pivots_Name = "Pivots Seen", CMD_Pivots_Help = "> Displays known early game wild encounters for an area.", CMD_Revo_Name = "Pokémon Random Evolutions", diff --git a/ironmon_tracker/Languages/German.lua b/ironmon_tracker/Languages/German.lua index 44f632f6..0d0b6366 100644 --- a/ironmon_tracker/Languages/German.lua +++ b/ironmon_tracker/Languages/German.lua @@ -615,7 +615,7 @@ ScreenResources{ CMD_Dungeon_Name = "Dungeon Info", CMD_Dungeon_Help = "name > Displays info about which trainers have been defeated for an area.", CMD_Unfought_Name = "Unfought Trainers", - CMD_Unfought_Help = "[dungeon] [sevii]> Displays a summary of areas with trainers that have yet to be defeated. Use 'dungeon' to include partially completed dungeons.", + CMD_Unfought_Help = "[dungeon] [sevii]> Displays a list of areas ordered by lowest-level, undefeated trainers. (Add param 'dungeon' to include partially completed dungeons.)", CMD_Pivots_Name = "Pivots Seen", CMD_Pivots_Help = "> Displays known early game wild encounters for an area.", CMD_Revo_Name = "Pokémon Random Evolutions", diff --git a/ironmon_tracker/Languages/Italian.lua b/ironmon_tracker/Languages/Italian.lua index b5f68e3f..33aeb099 100644 --- a/ironmon_tracker/Languages/Italian.lua +++ b/ironmon_tracker/Languages/Italian.lua @@ -615,7 +615,7 @@ ScreenResources{ CMD_Dungeon_Name = "Dungeon Info", CMD_Dungeon_Help = "name > Displays info about which trainers have been defeated for an area.", CMD_Unfought_Name = "Unfought Trainers", - CMD_Unfought_Help = "[dungeon] [sevii]> Displays a summary of areas with trainers that have yet to be defeated. Use 'dungeon' to include partially completed dungeons.", + CMD_Unfought_Help = "[dungeon] [sevii]> Displays a list of areas ordered by lowest-level, undefeated trainers. (Add param 'dungeon' to include partially completed dungeons.)", CMD_Pivots_Name = "Pivots Seen", CMD_Pivots_Help = "> Displays known early game wild encounters for an area.", CMD_Revo_Name = "Pokémon Random Evolutions", diff --git a/ironmon_tracker/Languages/Japanese.lua b/ironmon_tracker/Languages/Japanese.lua index 54d2cd50..85e8b746 100644 --- a/ironmon_tracker/Languages/Japanese.lua +++ b/ironmon_tracker/Languages/Japanese.lua @@ -617,7 +617,7 @@ ScreenResources{ CMD_Dungeon_Name = "Dungeon Info", CMD_Dungeon_Help = "name > Displays info about which trainers have been defeated for an area.", CMD_Unfought_Name = "Unfought Trainers", - CMD_Unfought_Help = "[dungeon] [sevii]> Displays a summary of areas with trainers that have yet to be defeated. Use 'dungeon' to include partially completed dungeons.", + CMD_Unfought_Help = "[dungeon] [sevii]> Displays a list of areas ordered by lowest-level, undefeated trainers. (Add param 'dungeon' to include partially completed dungeons.)", CMD_Pivots_Name = "Pivots Seen", CMD_Pivots_Help = "> Displays known early game wild encounters for an area.", CMD_Revo_Name = "Pokémon Random Evolutions", diff --git a/ironmon_tracker/Languages/Spanish.lua b/ironmon_tracker/Languages/Spanish.lua index e8c702f5..ea313d46 100644 --- a/ironmon_tracker/Languages/Spanish.lua +++ b/ironmon_tracker/Languages/Spanish.lua @@ -615,7 +615,7 @@ ScreenResources{ CMD_Dungeon_Name = "Dungeon Info", CMD_Dungeon_Help = "name > Displays info about which trainers have been defeated for an area.", CMD_Unfought_Name = "Unfought Trainers", - CMD_Unfought_Help = "[dungeon] [sevii]> Displays a summary of areas with trainers that have yet to be defeated. Use 'dungeon' to include partially completed dungeons.", + CMD_Unfought_Help = "[dungeon] [sevii]> Displays a list of areas ordered by lowest-level, undefeated trainers. (Add param 'dungeon' to include partially completed dungeons.)", CMD_Pivots_Name = "Pivots Seen", CMD_Pivots_Help = "> Displays known early game wild encounters for an area.", CMD_Revo_Name = "Pokémon Random Evolutions", From 450490e24657239f717e780a9f08a34f0973f21e Mon Sep 17 00:00:00 2001 From: UTDZac Date: Wed, 18 Sep 2024 22:03:48 -0700 Subject: [PATCH 09/12] Fix string placeholder typo "s" -> "%s" --- ironmon_tracker/data/DataHelper.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ironmon_tracker/data/DataHelper.lua b/ironmon_tracker/data/DataHelper.lua index 61fce392..b0abe3c6 100644 --- a/ironmon_tracker/data/DataHelper.lua +++ b/ironmon_tracker/data/DataHelper.lua @@ -1224,7 +1224,7 @@ function DataHelper.EventRequests.getUnfoughtTrainers(params) if not allowPartialDungeons or not includeSevii then reminderText = ' (Use param "dungeon" and/or "sevii" to check partially completed dungeons or Sevii Islands.)' end - table.insert(info, string.format("%s s", "All available trainers have been defeated!", reminderText)) + table.insert(info, string.format("%s %s", "All available trainers have been defeated!", reminderText)) end local prefix = string.format("%s %s", "Unfought Trainers", OUTPUT_CHAR) From e1a6845f3d5a89d5e9179cba4075b77625b212e9 Mon Sep 17 00:00:00 2001 From: CyanSMP64 Date: Thu, 19 Sep 2024 23:27:18 +1200 Subject: [PATCH 10/12] nat dex add constants to support extended nicknames --- ironmon_tracker/Program.lua | 51 ++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/ironmon_tracker/Program.lua b/ironmon_tracker/Program.lua index 1a3a7b6a..d2969c2d 100644 --- a/ironmon_tracker/Program.lua +++ b/ironmon_tracker/Program.lua @@ -45,6 +45,12 @@ Program = { offsetBattleResultsLastAttackerMove = 0x22, offsetBattleCommConfirmedCount = 0x4, offsetBattleCommLevitate = 0x6, + offsetPokemonSubstruct = 0x20, + offsetPokemonStatus = 0x50, + offsetPokemonStatsLvCurHp = 0x54, + offsetPokemonStatsMaxHpAtk = 0x58, + offsetPokemonStatsDefSpe = 0x5C, + offsetPokemonStatsSpaSpd = 0x60, sizeofBaseStatsPokemon = 0x1C, sizeofExpTablePokemon = 0x194, @@ -55,7 +61,12 @@ Program = { sizeofTMHMMoveId = 0x2, sizeofGameStat = 0x4, sizeofLastAttackerMove = 0x2, + sizeofPokemonStruct = 0x64, + sizeofPokemonNickname = 0xA, }, + Values = { + ShinyOdds = 8, -- n/65536 + } } Program.GameData = { @@ -629,7 +640,7 @@ function Program.updatePokemonTeams() end -- Next Pokemon - Each is offset by 100 bytes - addressOffset = addressOffset + 100 + addressOffset = addressOffset + Program.Addresses.sizeofPokemonStruct end end @@ -645,18 +656,18 @@ function Program.readNewPokemon(startAddress, personality) local miscoffset = (MiscData.TableData.misc[aux] - 1) * 12 -- Pokemon Data substructure: https://bulbapedia.bulbagarden.net/wiki/Pok%C3%A9mon_data_substructures_(Generation_III) - local growth1 = Utils.bit_xor(Memory.readdword(startAddress + 32 + growthoffset), magicword) - local growth2 = Utils.bit_xor(Memory.readdword(startAddress + 32 + growthoffset + 4), magicword) -- Experience - local growth3 = Utils.bit_xor(Memory.readdword(startAddress + 32 + growthoffset + 8), magicword) - local attack1 = Utils.bit_xor(Memory.readdword(startAddress + 32 + attackoffset), magicword) - local attack2 = Utils.bit_xor(Memory.readdword(startAddress + 32 + attackoffset + 4), magicword) - local attack3 = Utils.bit_xor(Memory.readdword(startAddress + 32 + attackoffset + 8), magicword) - local effort1 = Utils.bit_xor(Memory.readdword(startAddress + 32 + effortoffset), magicword) - local effort2 = Utils.bit_xor(Memory.readdword(startAddress + 32 + effortoffset + 4), magicword) - local misc2 = Utils.bit_xor(Memory.readdword(startAddress + 32 + miscoffset + 4), magicword) + local growth1 = Utils.bit_xor(Memory.readdword(startAddress + Program.Addresses.offsetPokemonSubstruct + growthoffset), magicword) + local growth2 = Utils.bit_xor(Memory.readdword(startAddress + Program.Addresses.offsetPokemonSubstruct + growthoffset + 4), magicword) -- Experience + local growth3 = Utils.bit_xor(Memory.readdword(startAddress + Program.Addresses.offsetPokemonSubstruct + growthoffset + 8), magicword) + local attack1 = Utils.bit_xor(Memory.readdword(startAddress + Program.Addresses.offsetPokemonSubstruct + attackoffset), magicword) + local attack2 = Utils.bit_xor(Memory.readdword(startAddress + Program.Addresses.offsetPokemonSubstruct + attackoffset + 4), magicword) + local attack3 = Utils.bit_xor(Memory.readdword(startAddress + Program.Addresses.offsetPokemonSubstruct + attackoffset + 8), magicword) + local effort1 = Utils.bit_xor(Memory.readdword(startAddress + Program.Addresses.offsetPokemonSubstruct + effortoffset), magicword) + local effort2 = Utils.bit_xor(Memory.readdword(startAddress + Program.Addresses.offsetPokemonSubstruct + effortoffset + 4), magicword) + local misc2 = Utils.bit_xor(Memory.readdword(startAddress + Program.Addresses.offsetPokemonSubstruct + miscoffset + 4), magicword) local nickname = "" - for i=0, 9, 1 do + for i=0, Program.Addresses.sizeofPokemonNickname - 1, 1 do local charByte = Memory.readbyte(startAddress + 8 + i) if charByte == Program.Addresses.nicknameCharEnd then break end -- end of sequence nickname = nickname .. (GameSettings.GameCharMap[charByte] or Constants.HIDDEN_INFO) @@ -664,8 +675,8 @@ function Program.readNewPokemon(startAddress, personality) nickname = Utils.formatSpecialCharacters(nickname) -- Unused data memory reads - -- local effort3 = Utils.bit_xor(Memory.readdword(startAddress + 32 + effortoffset + 8), magicword) - -- local misc3 = Utils.bit_xor(Memory.readdword(startAddress + 32 + miscoffset + 8), magicword) + -- local effort3 = Utils.bit_xor(Memory.readdword(startAddress + Program.Addresses.offsetPokemonSubstruct + effortoffset + 8), magicword) + -- local misc3 = Utils.bit_xor(Memory.readdword(startAddress + Program.Addresses.offsetPokemonSubstruct + miscoffset + 8), magicword) -- Checksum, currently unused -- local cs = Utils.addhalves(growth1) + Utils.addhalves(growth2) + Utils.addhalves(growth3) @@ -682,16 +693,16 @@ function Program.readNewPokemon(startAddress, personality) local secretID = Utils.getbits(otid, 16, 16) local p1 = math.floor(personality / 65536) local p2 = personality % 65536 - local isShiny = Utils.bit_xor(Utils.bit_xor(Utils.bit_xor(trainerID, secretID), p1), p2) < 8 + local isShiny = Utils.bit_xor(Utils.bit_xor(Utils.bit_xor(trainerID, secretID), p1), p2) < Program.Values.ShinyOdds local hasPokerus if GameSettings.game ~= 3 then -- PokeRus doesn't exist in FRLG due to lack of passing time - local misc1 = Utils.bit_xor(Memory.readdword(startAddress + 32 + miscoffset), magicword) + local misc1 = Utils.bit_xor(Memory.readdword(startAddress + Program.Addresses.offsetPokemonSubstruct + miscoffset), magicword) -- First 4 bits are number of days until Pokerus is cured, Second 4 bits are the strain variation hasPokerus = Utils.getbits(misc1, 0, 8) > 0 end -- Determine status condition - local status_aux = Memory.readdword(startAddress + 80) + local status_aux = Memory.readdword(startAddress + Program.Addresses.offsetPokemonStatus) local sleep_turns_result = 0 local status_result = 0 if status_aux == 0 then --None @@ -712,10 +723,10 @@ function Program.readNewPokemon(startAddress, personality) end -- Can likely improve this further using memory.read_bytes_as_array but would require testing to verify - local level_and_currenthp = Memory.readdword(startAddress + 84) - local maxhp_and_atk = Memory.readdword(startAddress + 88) - local def_and_speed = Memory.readdword(startAddress + 92) - local spatk_and_spdef = Memory.readdword(startAddress + 96) + local level_and_currenthp = Memory.readdword(startAddress + Program.Addresses.offsetPokemonStatsLvCurHp) + local maxhp_and_atk = Memory.readdword(startAddress + Program.Addresses.offsetPokemonStatsMaxHpAtk) + local def_and_speed = Memory.readdword(startAddress + Program.Addresses.offsetPokemonStatsDefSpe) + local spatk_and_spdef = Memory.readdword(startAddress + Program.Addresses.offsetPokemonStatsSpaSpd) return Program.DefaultPokemon:new({ personality = personality, From dd5bef3b51a9b2a7d9333ca2f473cb5f8c14d652 Mon Sep 17 00:00:00 2001 From: UTDZac Date: Thu, 19 Sep 2024 16:13:21 -0700 Subject: [PATCH 11/12] New feature: Show IVs/EVs in log viewer The button to reveal the IVs and EVs of the pokemon in the log viewer is only present for pokemon on the player's team (currently uses the first mon found of each species on their team). --- ironmon_tracker/Languages/English.lua | 5 + ironmon_tracker/Languages/French.lua | 5 + ironmon_tracker/Languages/German.lua | 5 + ironmon_tracker/Languages/Italian.lua | 5 + ironmon_tracker/Languages/Japanese.lua | 5 + ironmon_tracker/Languages/Spanish.lua | 5 + .../screens/LogTabPokemonDetails.lua | 116 ++++++++++++++++-- 7 files changed, 135 insertions(+), 11 deletions(-) diff --git a/ironmon_tracker/Languages/English.lua b/ironmon_tracker/Languages/English.lua index b32a7405..bcd37aff 100644 --- a/ironmon_tracker/Languages/English.lua +++ b/ironmon_tracker/Languages/English.lua @@ -534,6 +534,11 @@ ScreenResources{ HeaderTabMisc = "Misc.", LabelBaseStats = "Base Stats", LabelBSTTotal = "Total", -- Usage: "Total: 505" + LabelYourIVs = "Your IVs", + LabelYourEVs = "Your EVs", + LabelShowIVs = "Show IVs", + LabelShowEVs = "Show EVs", + LabelShowBST = "Show BST", ButtonLevelupMoves = "Levelup Moves", ButtonTMMoves = "TM Moves", LabelGymTMs = "Gym TMs", diff --git a/ironmon_tracker/Languages/French.lua b/ironmon_tracker/Languages/French.lua index 6d4071f6..2340ab26 100644 --- a/ironmon_tracker/Languages/French.lua +++ b/ironmon_tracker/Languages/French.lua @@ -534,6 +534,11 @@ ScreenResources{ HeaderTabMisc = "Misc.", -- NEEDS TRANSLATION LabelBaseStats = "Base Stats", -- NEEDS TRANSLATION LabelBSTTotal = "Total", -- NEEDS TRANSLATION + LabelYourIVs = "Your IVs", -- NEEDS TRANSLATION + LabelYourEVs = "Your EVs", -- NEEDS TRANSLATION + LabelShowIVs = "Show IVs", -- NEEDS TRANSLATION + LabelShowEVs = "Show EVs", -- NEEDS TRANSLATION + LabelShowBST = "Show BST", -- NEEDS TRANSLATION ButtonLevelupMoves = "Levelup Moves", -- NEEDS TRANSLATION ButtonTMMoves = "TM Moves", -- NEEDS TRANSLATION LabelGymTMs = "Gym TMs", -- NEEDS TRANSLATION diff --git a/ironmon_tracker/Languages/German.lua b/ironmon_tracker/Languages/German.lua index 0d0b6366..ce008dc5 100644 --- a/ironmon_tracker/Languages/German.lua +++ b/ironmon_tracker/Languages/German.lua @@ -534,6 +534,11 @@ ScreenResources{ HeaderTabMisc = "Misc.", -- NEEDS TRANSLATION LabelBaseStats = "Base Stats", -- NEEDS TRANSLATION LabelBSTTotal = "Total", -- NEEDS TRANSLATION + LabelYourIVs = "Your IVs", -- NEEDS TRANSLATION + LabelYourEVs = "Your EVs", -- NEEDS TRANSLATION + LabelShowIVs = "Show IVs", -- NEEDS TRANSLATION + LabelShowEVs = "Show EVs", -- NEEDS TRANSLATION + LabelShowBST = "Show BST", -- NEEDS TRANSLATION ButtonLevelupMoves = "Levelup Moves", -- NEEDS TRANSLATION ButtonTMMoves = "TM Moves", -- NEEDS TRANSLATION LabelGymTMs = "Gym TMs", -- NEEDS TRANSLATION diff --git a/ironmon_tracker/Languages/Italian.lua b/ironmon_tracker/Languages/Italian.lua index 33aeb099..081aa76f 100644 --- a/ironmon_tracker/Languages/Italian.lua +++ b/ironmon_tracker/Languages/Italian.lua @@ -534,6 +534,11 @@ ScreenResources{ HeaderTabMisc = "Misc.", -- NEEDS TRANSLATION LabelBaseStats = "Base Stats", -- NEEDS TRANSLATION LabelBSTTotal = "Total", -- NEEDS TRANSLATION + LabelYourIVs = "Your IVs", -- NEEDS TRANSLATION + LabelYourEVs = "Your EVs", -- NEEDS TRANSLATION + LabelShowIVs = "Show IVs", -- NEEDS TRANSLATION + LabelShowEVs = "Show EVs", -- NEEDS TRANSLATION + LabelShowBST = "Show BST", -- NEEDS TRANSLATION ButtonLevelupMoves = "Levelup Moves", -- NEEDS TRANSLATION ButtonTMMoves = "TM Moves", -- NEEDS TRANSLATION LabelGymTMs = "Gym TMs", -- NEEDS TRANSLATION diff --git a/ironmon_tracker/Languages/Japanese.lua b/ironmon_tracker/Languages/Japanese.lua index 85e8b746..656b29ad 100644 --- a/ironmon_tracker/Languages/Japanese.lua +++ b/ironmon_tracker/Languages/Japanese.lua @@ -536,6 +536,11 @@ ScreenResources{ HeaderTabMisc = "Misc.", -- NEEDS TRANSLATION LabelBaseStats = "Base Stats", -- NEEDS TRANSLATION LabelBSTTotal = "Total", -- NEEDS TRANSLATION + LabelYourIVs = "Your IVs", -- NEEDS TRANSLATION + LabelYourEVs = "Your EVs", -- NEEDS TRANSLATION + LabelShowIVs = "Show IVs", -- NEEDS TRANSLATION + LabelShowEVs = "Show EVs", -- NEEDS TRANSLATION + LabelShowBST = "Show BST", -- NEEDS TRANSLATION ButtonLevelupMoves = "Levelup Moves", -- NEEDS TRANSLATION ButtonTMMoves = "TM Moves", -- NEEDS TRANSLATION LabelGymTMs = "Gym TMs", -- NEEDS TRANSLATION diff --git a/ironmon_tracker/Languages/Spanish.lua b/ironmon_tracker/Languages/Spanish.lua index ea313d46..d9372f4d 100644 --- a/ironmon_tracker/Languages/Spanish.lua +++ b/ironmon_tracker/Languages/Spanish.lua @@ -534,6 +534,11 @@ ScreenResources{ HeaderTabMisc = "Misc.", -- NEEDS TRANSLATION LabelBaseStats = "Base Stats", -- NEEDS TRANSLATION LabelBSTTotal = "Total", -- NEEDS TRANSLATION + LabelYourIVs = "Your IVs", -- NEEDS TRANSLATION + LabelYourEVs = "Your EVs", -- NEEDS TRANSLATION + LabelShowIVs = "Show IVs", -- NEEDS TRANSLATION + LabelShowEVs = "Show EVs", -- NEEDS TRANSLATION + LabelShowBST = "Show BST", -- NEEDS TRANSLATION ButtonLevelupMoves = "Levelup Moves", -- NEEDS TRANSLATION ButtonTMMoves = "TM Moves", -- NEEDS TRANSLATION LabelGymTMs = "Gym TMs", -- NEEDS TRANSLATION diff --git a/ironmon_tracker/screens/LogTabPokemonDetails.lua b/ironmon_tracker/screens/LogTabPokemonDetails.lua index f64ee8c8..3443e7f0 100644 --- a/ironmon_tracker/screens/LogTabPokemonDetails.lua +++ b/ironmon_tracker/screens/LogTabPokemonDetails.lua @@ -15,6 +15,8 @@ LogTabPokemonDetails = { currentEvoSet = 1, prevEvosPerSet = 1, evosPerSet = 3, + playerTeam = {}, + currentStatView = "ShowBST", } LogTabPokemonDetails.TemporaryButtons = {} @@ -59,6 +61,8 @@ function LogTabPokemonDetails.initialize() LogTabPokemonDetails.currentEvoSet = 1 LogTabPokemonDetails.prevEvosPerSet = 1 LogTabPokemonDetails.evosPerSet = 3 + LogTabPokemonDetails.playerTeam = {} + LogTabPokemonDetails.currentStatView = "ShowBST" end function LogTabPokemonDetails.refreshButtons() @@ -89,6 +93,7 @@ function LogTabPokemonDetails.buildZoomButtons(pokemonID) LogTabPokemonDetails.currentPreEvoSet = 1 LogTabPokemonDetails.currentEvoSet = 1 + LogTabPokemonDetails.currentStatView = "ShowBST" if data.p.abilities[1] == data.p.abilities[2] then data.p.abilities[2] = nil @@ -729,6 +734,79 @@ function LogTabPokemonDetails.buildZoomButtons(pokemonID) LogTabPokemonDetails.Pager.totalLearnedMoves = #data.p.moves LogTabPokemonDetails.Pager.totalTMMoves = #data.p.tmmoves LogTabPokemonDetails.Pager:changeTab(LogTabPokemonDetails.Tabs.LevelMoves) + + -- LABEL/BUTTON FOR "Show IVs/EVs/BST" + LogTabPokemonDetails.playerTeam = {} + for _, pokemon in pairs(Program.GameData.PlayerTeam or {}) do + if PokemonData.isValid(pokemon.pokemonID) and not LogTabPokemonDetails.playerTeam[pokemon.pokemonID] then + local pokemonName = data.p.name + -- Use Nickname if looking at the log page for a mon on the player's team + if Options["Show nicknames"] and not Utils.isNilOrEmpty(pokemon.nickname) then + pokemonName = Utils.formatSpecialCharacters(pokemon.nickname) + end + LogTabPokemonDetails.playerTeam[pokemon.pokemonID] = { + name = pokemonName, + ivs = pokemon.ivs, + evs = pokemon.evs, + } + end + end + + local showBtnBox = { LogOverlay.TabBox.x + 66, LogOverlay.TabBox.y + 42, 43, 11 } -- x, y, width, height + + local lblStatGraphHeader = { + type = Constants.ButtonTypes.NO_BORDER, + getText = function(self) + if LogTabPokemonDetails.currentStatView == "ShowIVs" then + return Resources.LogOverlay.LabelYourIVs + elseif LogTabPokemonDetails.currentStatView == "ShowEVs" then + return Resources.LogOverlay.LabelYourEVs + else + return Resources.LogOverlay.LabelBaseStats + end + end, + textColor = LogTabPokemonDetails.Colors.text, + boxColors = { LogTabPokemonDetails.Colors.border, LogTabPokemonDetails.Colors.boxFill }, + box = { LogOverlay.TabBox.x + 4, showBtnBox[2], showBtnBox[3], showBtnBox[4] }, + } + local lblBaseStatTotal = { + type = Constants.ButtonTypes.NO_BORDER, + getText = function(self) return string.format("%s: %s", Resources.LogOverlay.LabelBSTTotal, data.p.bst) end, + textColor = LogTabPokemonDetails.Colors.text, + boxColors = { LogTabPokemonDetails.Colors.border, LogTabPokemonDetails.Colors.boxFill }, + box = showBtnBox, + isVisible = function(self) return LogTabPokemonDetails.playerTeam[pokemonID or false] == nil end, + } + local btnChangeStatGraph = { + type = Constants.ButtonTypes.FULL_BORDER, + getText = function(self) + if LogTabPokemonDetails.currentStatView == "ShowBST" then + return Resources.LogOverlay.LabelShowIVs + elseif LogTabPokemonDetails.currentStatView == "ShowIVs" then + return Resources.LogOverlay.LabelShowEVs + else + return Resources.LogOverlay.LabelShowBST + end + end, + textColor = LogTabPokemonDetails.Colors.highlight, + boxColors = { LogTabPokemonDetails.Colors.border, LogTabPokemonDetails.Colors.boxFill }, + box = showBtnBox, + isVisible = function(self) return LogTabPokemonDetails.playerTeam[pokemonID or false] ~= nil end, + onClick = function(self) + -- On click: change from viewing Base Stats -> IVs -> EVs -> Base Stats + if LogTabPokemonDetails.currentStatView == "ShowBST" then + LogTabPokemonDetails.currentStatView = "ShowIVs" + elseif LogTabPokemonDetails.currentStatView == "ShowIVs" then + LogTabPokemonDetails.currentStatView = "ShowEVs" + else + LogTabPokemonDetails.currentStatView = "ShowBST" + end + Program.redraw(true) + end, + } + table.insert(LogTabPokemonDetails.TemporaryButtons, lblStatGraphHeader) + table.insert(LogTabPokemonDetails.TemporaryButtons, lblBaseStatTotal) + table.insert(LogTabPokemonDetails.TemporaryButtons, btnChangeStatGraph) end -- USER INPUT FUNCTIONS @@ -769,7 +847,11 @@ function LogTabPokemonDetails.drawTab() end -- Draw Pokemon name - local nameText = Utils.toUpperUTF8(data.p.name) + local pokemonName = data.p.name + if LogTabPokemonDetails.currentStatView ~= "ShowBST" and LogTabPokemonDetails.playerTeam[data.p.id] then + pokemonName = LogTabPokemonDetails.playerTeam[data.p.id].name + end + local nameText = Utils.toUpperUTF8(pokemonName) Drawing.drawTransparentTextbox(LogOverlay.TabBox.x + 3, LogOverlay.TabBox.y + 2, nameText, highlightColor, fillColor, shadowcolor) -- data.p.helditems -- unused @@ -782,6 +864,7 @@ function LogTabPokemonDetails.drawStatGraph(data, shadowcolor) local borderColor = Theme.COLORS[LogTabPokemonDetails.Colors.border] local fillColor = Theme.COLORS[LogTabPokemonDetails.Colors.boxFill] + -- If these change, also update "lblStatGraphHeader", "lblBaseStatTotal", etc. above local statBox = { x = LogOverlay.TabBox.x + 6, y = LogOverlay.TabBox.y + 53, @@ -791,11 +874,6 @@ function LogTabPokemonDetails.drawStatGraph(data, shadowcolor) labelW = 17, } - -- Draw header for stat box - local bstTotal = string.format("%s: %s", Resources.LogOverlay.LabelBSTTotal, data.p.bst) - Drawing.drawTransparentTextbox(statBox.x, statBox.y - 11, Resources.LogOverlay.LabelBaseStats, textColor, fillColor, shadowcolor) - Drawing.drawTransparentTextbox(statBox.x + statBox.width - 39, statBox.y - 11, bstTotal, textColor, fillColor, shadowcolor) - -- Draw stat box gui.drawRectangle(statBox.x, statBox.y, statBox.width, statBox.height, borderColor, fillColor) local quarterMark = statBox.height/4 @@ -810,15 +888,31 @@ function LogTabPokemonDetails.drawStatGraph(data, shadowcolor) gui.drawLine(statBox.x - 2, statBox.y + statBox.height, statBox.x, statBox.y + statBox.height, borderColor) gui.drawLine(statBox.x + statBox.width, statBox.y + statBox.height, statBox.x + statBox.width + 2, statBox.y + statBox.height, borderColor) + local barVals = {} + local pokemon = LogTabPokemonDetails.playerTeam[data.p.id] + for _, statKey in ipairs(Constants.OrderedLists.STATSTAGES) do + if pokemon ~= nil and LogTabPokemonDetails.currentStatView == "ShowIVs" then + barVals[statKey] = pokemon.ivs[statKey] or 0 + elseif pokemon ~= nil and LogTabPokemonDetails.currentStatView == "ShowEVs" then + barVals[statKey] = pokemon.evs[statKey] or 0 + else + barVals[statKey] = data.p[statKey] or 0 + end + end + local statX = statBox.x + 1 for _, statKey in ipairs(Constants.OrderedLists.STATSTAGES) do + local barVal = barVals[statKey] + if LogTabPokemonDetails.currentStatView == "ShowIVs" then + barVal = math.min(barVal * 8, 255) -- Scale IV bar x8 to fill + end -- Draw the vertical bar - local barH = math.floor(data.p[statKey] / 255 * (statBox.height - 2) + 0.5) + local barH = math.floor(barVal / 255 * (statBox.height - 2) + 0.5) local barY = statBox.y + statBox.height - barH - 1 -- -1/-2 for box pixel border margin local barColor - if data.p[statKey] >= 180 then -- top ~70% + if barVal >= 180 then -- top ~70% barColor = Theme.COLORS["Positive text"] - elseif data.p[statKey] <= 40 then -- bottom ~15% + elseif barVal <= 40 then -- bottom ~15% barColor = Theme.COLORS["Negative text"] else barColor = textColor @@ -830,9 +924,9 @@ function LogTabPokemonDetails.drawStatGraph(data, shadowcolor) -- Draw the bar's label local statLabelOffsetX = (3 - string.len(statKey)) * 2 - local statValueOffsetX = (3 - string.len(tostring(data.p[statKey]))) * 2 + local statValueOffsetX = (3 - string.len(tostring(barVals[statKey]))) * 2 Drawing.drawText(statX + statLabelOffsetX, statBox.y + statBox.height + 1, Utils.firstToUpper(statKey), textColor, shadowcolor) - Drawing.drawText(statX + statValueOffsetX, statBox.y + statBox.height + 11, data.p[statKey], barColor, shadowcolor) + Drawing.drawText(statX + statValueOffsetX, statBox.y + statBox.height + 11, barVals[statKey], barColor, shadowcolor) statX = statX + statBox.labelW end end \ No newline at end of file From 7639c864ecaaa0625284a7a132726006c6a5b75b Mon Sep 17 00:00:00 2001 From: UTDZac Date: Thu, 19 Sep 2024 16:28:30 -0700 Subject: [PATCH 12/12] 8.6.1 Release --- ironmon_tracker/Main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ironmon_tracker/Main.lua b/ironmon_tracker/Main.lua index 64ed4d18..c3cd04b0 100644 --- a/ironmon_tracker/Main.lua +++ b/ironmon_tracker/Main.lua @@ -1,7 +1,7 @@ Main = {} -- The latest version of the tracker. Should be updated with each PR. -Main.Version = { major = "8", minor = "6", patch = "0" } +Main.Version = { major = "8", minor = "6", patch = "1" } Main.CreditsList = { -- based on the PokemonBizhawkLua project by MKDasher CreatedBy = "Besteon",