diff --git a/layout/hud/leaderboards.xml b/layout/hud/leaderboards.xml index 9cb39ab0..648a49bd 100644 --- a/layout/hud/leaderboards.xml +++ b/layout/hud/leaderboards.xml @@ -5,6 +5,7 @@ + diff --git a/layout/hud/map-info.xml b/layout/hud/map-info.xml index 591071fa..089331a4 100644 --- a/layout/hud/map-info.xml +++ b/layout/hud/map-info.xml @@ -4,6 +4,7 @@ + diff --git a/layout/pages/loading-screen.xml b/layout/pages/loading-screen.xml index 5be42979..72d28eb4 100644 --- a/layout/pages/loading-screen.xml +++ b/layout/pages/loading-screen.xml @@ -5,6 +5,7 @@ + diff --git a/layout/pages/map-selector/map-selector.xml b/layout/pages/map-selector/map-selector.xml index bdabe814..d1453c00 100644 --- a/layout/pages/map-selector/map-selector.xml +++ b/layout/pages/map-selector/map-selector.xml @@ -4,6 +4,7 @@ + diff --git a/scripts/common/map-cache.js b/scripts/common/map-cache.js new file mode 100644 index 00000000..a3ef7064 --- /dev/null +++ b/scripts/common/map-cache.js @@ -0,0 +1,32 @@ +/** + * Enum for track types + * @enum {number} + */ +const TrackType = { + MAIN: 0, + STAGE: 1, + BONUS: 2 +}; + +/** + * Enum for map credits + * @enum {number} + */ +const MapCreditType = { + UNKNOWN: -1, + AUTHOR: 0, + CONTRIBUTOR: 1, + TESTER: 2, + SPECIAL_THANKS: 3 +}; + +function getMainTrack(mapData, gamemode) { + return mapData.leaderboards.find( + (leaderboard) => + leaderboard.gamemode === gamemode && leaderboard.trackType === TrackType.MAIN && leaderboard.style === 0 + ); +} + +function getNumZones(mapData) { + return mapData.leaderboards.filter((leaderboard) => leaderboard.trackType === TrackType.STAGE).length; +} diff --git a/scripts/hud/leaderboards.js b/scripts/hud/leaderboards.js index 01e4eb20..b500a790 100644 --- a/scripts/hud/leaderboards.js +++ b/scripts/hud/leaderboards.js @@ -36,7 +36,7 @@ class HudLeaderboards { static setMapData(isOfficial) { $.GetContextPanel().SetHasClass('hud-leaderboards--unofficial', !isOfficial); - const img = GameModeInfoWithNull[GameModeAPI.GetCurrentGameMode()].shortName.toLowerCase(); + const img = GameModeInfoWithNull[GameModeAPI.GetCurrentGameMode()].idName.toLowerCase(); this.panels.gamemodeImage.SetImage(`file://{images}/gamemodes/${img}.svg`); @@ -52,7 +52,7 @@ class HudLeaderboards { // Delete existing name labels for (const label of this.panels.credits.Children().slice(1) || []) label.DeleteAsync(0); - const authorCredits = credits.filter((x) => x.type === 'author'); + const authorCredits = credits.filter((x) => x.type === MapCreditType.AUTHOR); for (const credit of authorCredits) { const namePanel = $.CreatePanel('Label', this.panels.credits, '', { @@ -88,13 +88,13 @@ class HudLeaderboards { static setMapStats(data) { const cp = $.GetContextPanel(); - cp.SetDialogVariableInt('tier', data.mainTrack?.difficulty); - cp.SetDialogVariable( - 'type', - $.Localize(data.mainTrack?.isLinear ? '#MapInfo_Type_Linear' : '#MapInfo_Type_Staged') - ); - cp.SetDialogVariableInt('numzones', data.mainTrack?.numZones); - cp.SetDialogVariableInt('runs', data.stats?.completes); + const mainTrack = getMainTrack(data, GameModeAPI.GetCurrentGameMode()); + const numZones = getNumZones(data); + + cp.SetDialogVariableInt('tier', mainTrack?.tier ?? 0); + cp.SetDialogVariable('type', $.Localize(mainTrack?.isLinear ? '#MapInfo_Type_Linear' : '#MapInfo_Type_Staged')); + cp.SetDialogVariableInt('numzones', numZones); + cp.SetDialogVariableInt('runs', data.stats?.completions); } static close() { diff --git a/scripts/hud/map-info.js b/scripts/hud/map-info.js index b651c5af..671f91a2 100644 --- a/scripts/hud/map-info.js +++ b/scripts/hud/map-info.js @@ -11,18 +11,20 @@ class HudMapInfo { this.cachedInfoContainer.visible = true; let authorString = ''; - for (const [i, item] of mapData['credits'].filter((x) => x.type === 'author').entries()) + for (const [i, item] of mapData['credits'].filter((x) => x.type === MapCreditType.AUTHOR).entries()) authorString += (i > 0 ? ', ' : '') + item.user.alias; const cp = $.GetContextPanel(); cp.SetDialogVariable('author', authorString); - const mainTrack = mapData['mainTrack']; - cp.SetDialogVariableInt('tier', mainTrack['difficulty']); + const mainTrack = getMainTrack(mapData, GameModeAPI.GetCurrentGameMode()); + const numZones = getNumZones(mapData); + + cp.SetDialogVariableInt('tier', mainTrack?.tier ?? 0); cp.SetDialogVariable( 'zonetype', - $.Localize(mainTrack['isLinear'] ? '#MapInfo_Type_Linear' : '#MapInfo_Type_Staged') + $.Localize(mainTrack?.isLinear ? '#MapInfo_Type_Linear' : '#MapInfo_Type_Staged') ); - cp.SetDialogVariableInt('numzones', mainTrack['numZones']); + cp.SetDialogVariableInt('numzones', numZones); } else { this.cachedInfoContainer.visible = false; } diff --git a/scripts/pages/loading-screen.js b/scripts/pages/loading-screen.js index 2ccb62af..2b60e110 100644 --- a/scripts/pages/loading-screen.js +++ b/scripts/pages/loading-screen.js @@ -65,13 +65,16 @@ class LoadingScreen { return; } + const mainTrack = getMainTrack(mapData, GameModeAPI.GetCurrentGameMode()); + const numZones = getNumZones(mapData); + this.panels.cp.SetDialogVariable('mapname', mapData.name); - this.panels.cp.SetDialogVariableInt('tier', mapData.mainTrack.difficulty); - this.panels.cp.SetDialogVariableInt('numzones', mapData.mainTrack.numZones); - this.panels.cp.SetDialogVariable('tracktype', mapData.mainTrack.isLinear ? 'Linear' : 'Staged'); + this.panels.cp.SetDialogVariableInt('tier', mainTrack?.tier ?? 0); + this.panels.cp.SetDialogVariableInt('numzones', numZones); + this.panels.cp.SetDialogVariable('tracktype', mainTrack?.isLinear ? 'Linear' : 'Staged'); let authorString = ''; - for (const [i, item] of mapData.credits.filter((x) => x.type === 'author').entries()) + for (const [i, item] of mapData.credits.filter((x) => x.type === MapCreditType.AUTHOR).entries()) authorString += (i > 0 ? ', ' : '') + item.user.alias; this.panels.cp.SetDialogVariable('author', authorString); @@ -80,6 +83,6 @@ class LoadingScreen { this.panels.tierAndType.visible = true; this.panels.numZones.visible = true; - this.panels.backgroundImage.SetImage(mapData.thumbnail.urlLarge); + this.panels.backgroundImage.SetImage(mapData.thumbnail.large); } } diff --git a/scripts/pages/map-selector/map-entry.js b/scripts/pages/map-selector/map-entry.js index 2c8db9af..da8efa6a 100644 --- a/scripts/pages/map-selector/map-entry.js +++ b/scripts/pages/map-selector/map-entry.js @@ -28,84 +28,73 @@ class MapEntry { const mapData = $.GetContextPanel().mapData; if (!mapData) return; + const userMapData = $.GetContextPanel().userMapData; + if (!userMapData) return; + const items = []; const isDownloading = $.GetContextPanel().isDownloading; const mapID = mapData.id; - if (mapData.inLibrary) { - if (mapData.mapFileNeedsUpdate) { - if (isDownloading) { - items.push({ - label: $.Localize('#Action_CancelDownload'), - icon: 'file://{images}/cancel.svg', - style: 'icon-color-red', - - jsCallback: () => $.DispatchEvent('MapSelector_ShowConfirmCancelDownload', mapID) - }); - } else if (MapCacheAPI.MapQueuedForDownload(mapID)) { - items.push({ - label: $.Localize('#Action_RemoveFromQueue'), - icon: 'file://{images}/playlist-remove.svg', - style: 'icon-color-red', - jsCallback: () => $.DispatchEvent('MapSelector_RemoveMapFromDownloadQueue', mapID) - }); - } else { - items.push({ - label: $.Localize('#Action_DownloadMap'), - icon: 'file://{images}/play.svg', - style: 'icon-color-mid-blue', - jsCallback: () => $.DispatchEvent('MapSelector_TryPlayMap', mapID) - }); + if (userMapData.mapFileExists) { + items.push( + { + label: $.Localize('#Action_StartMap'), + icon: 'file://{images}/play.svg', + style: 'icon-color-green', + jsCallback: () => $.DispatchEvent('MapSelector_TryPlayMap', mapID) + }, + // Gamemode override submenu + { + label: $.Localize('#Action_StartMapOverride'), + icon: 'file://{images}/alternative-mode.svg', + style: 'icon-color-green', + jsCallback: () => this.showGameModeOverrideMenu() + }, + { + label: $.Localize('#Action_DeleteMap'), + icon: 'file://{images}/delete.svg', + style: 'icon-color-red', + jsCallback: () => $.DispatchEvent('MapSelector_DeleteMap', mapID) } + ); + } else { + if (isDownloading) { + items.push({ + label: $.Localize('#Action_CancelDownload'), + icon: 'file://{images}/cancel.svg', + style: 'icon-color-red', + jsCallback: () => $.DispatchEvent('MapSelector_ShowConfirmCancelDownload', mapID) + }); + } else if (MapCacheAPI.MapQueuedForDownload(mapID)) { + items.push({ + label: $.Localize('#Action_RemoveFromQueue'), + icon: 'file://{images}/playlist-remove.svg', + style: 'icon-color-red', + jsCallback: () => $.DispatchEvent('MapSelector_RemoveMapFromDownloadQueue', mapID) + }); } else { - items.push( - { - label: $.Localize('#Action_StartMap'), - icon: 'file://{images}/play.svg', - style: 'icon-color-green', - - jsCallback: () => $.DispatchEvent('MapSelector_TryPlayMap', mapID) - }, - - // Gamemode override submenu - { - label: $.Localize('#Action_StartMapOverride'), - icon: 'file://{images}/alternative-mode.svg', - style: 'icon-color-green', - jsCallback: () => this.showGameModeOverrideMenu() - } - ); + items.push({ + label: $.Localize('#Action_DownloadMap'), + icon: 'file://{images}/play.svg', + style: 'icon-color-mid-blue', + jsCallback: () => $.DispatchEvent('MapSelector_TryPlayMap', mapID) + }); } - - items.push({ - label: $.Localize('#Action_DeleteMap'), - icon: 'file://{images}/delete.svg', - style: 'icon-color-red', - jsCallback: () => $.DispatchEvent('MapSelector_ToggleMapStatus', mapID, true, false) - }); - } else { - items.push({ - label: $.Localize('#Action_DownloadMap'), - icon: 'file://{images}/download.svg', - style: 'icon-color-mid-blue', - jsCallback: () => $.DispatchEvent('MapSelector_TryPlayMap', mapID) - }); } - if (mapData.isFavorited) { + if (userMapData.isFavorited) { items.push({ label: $.Localize('#Action_RemoveFromFavorites'), icon: 'file://{images}/favorite-remove.svg', style: 'icon-color-yellow', - - jsCallback: () => $.DispatchEvent('MapSelector_ToggleMapStatus', mapID, false, false) + jsCallback: () => $.DispatchEvent('MapSelector_ToggleMapStatus', mapID, false) }); } else { items.push({ label: $.Localize('#Action_AddToFavorites'), icon: 'file://{images}/star.svg', style: 'icon-color-yellow', - jsCallback: () => $.DispatchEvent('MapSelector_ToggleMapStatus', mapID, false, true) + jsCallback: () => $.DispatchEvent('MapSelector_ToggleMapStatus', mapID, true) }); } diff --git a/scripts/pages/map-selector/map-selector.js b/scripts/pages/map-selector/map-selector.js index bb3c2a24..c66d1610 100644 --- a/scripts/pages/map-selector/map-selector.js +++ b/scripts/pages/map-selector/map-selector.js @@ -345,7 +345,7 @@ class MapSelection { this.panels.credits.RemoveAndDeleteChildren(); // Find all authors - const authorCredits = mapData.credits.filter((x) => x.type === 'author'); + const authorCredits = mapData.credits.filter((x) => x.type === MapCreditType.AUTHOR); const hasCredits = authorCredits.length > 0;