diff --git a/changelog-de.md b/changelog-de.md index 4f6f14629..97f4c581a 100644 --- a/changelog-de.md +++ b/changelog-de.md @@ -1,5 +1,42 @@ ## Changelog - Extension +##### 3.10.0.0 + +**Neu** +- QI Fortschritts Übersicht hinzugefügt (öffnet sich automatisch, wenn die QI-Spieler Rangliste geöffnet wird) +- Quellen für Gegenstände: In der Produktionsübersicht für Gegenstände und Fragmente gibt es nun die Möglichkeit, sich eine Liste von Gebäude ausgeben zu lassen, die einen bestimmten Gegenstand produzieren (auch, wenn diese nicht gebaut sind) +- Produktionsübersicht: Tabellen für Münz-, Vorrats- und FP-Boots hinzugefügt +- Effizienzbewertung: Feld für Spezialproduktion abschließen Fragmente hinzugefügt +- Stadtübersicht: Anzeigeoption für Gebäude, die eine erhabene Stufe haben und "abgelaufene" Gebäude +- Wiederholtes Bauen: + - !!! ACHTUNG !!! Obwohl das Feature an sich grünes Licht von Inno bekommen hat, könnte es trotzdem vorkommen, dass die Bot-Erkennung ausgelöst wird. Benutzung auf eigene Gefahr!!! + - Kann in den Einstellungen aktiviert werden + - Wenn ein Gebäude aus dem Baumenü oder dem Umbaulager gebaut wird, wird das gleiche Gebäude automatisch erneut ausgewählt + +**Update** +- Tooltip: Design der Gebäude-Tooltips angepasst +- Gebäude-Effizienz: + - Gebäude-Tooltips hinzugefügt + - Ergebnisseite wird nun zuerst angezeigt + - Itemliste versteckt +- Menü: Von unten nach rechts verschoben, weil die möglichen Einstellungen gerne übersehen werden +- Gefechte: + - Symbole für blauen/roten Angriff in die Countdown-Liste hinzugefügt + - Angriffsfarben zur Karte hinzugefügt + - Neue Kartenansicht, die die Angriffsfarben besser sichtbar macht +- GG Aktive Spieler: + - Modul entfernt auf Anfrage durch Inno + +**BugFix** +- Tooltip: + - manche Browser haben nicht das korrekte Design verwendet + - konnte offen bleiben, obwohl zugehöriges Fenster geschlossen wurde +- Umbau-Liste: + - Standardhöhe gesetzt + - Umplatzieren von Gebäuden verringerte den Zähler +- Gebäude-Effizienz: + - Die Bewertungen bei anderen Spielern haben dein aktuelles Zeitalter genutzt, statt ihr eigenes + ##### 3.9.0.0 **Neu** diff --git a/changelog-en.md b/changelog-en.md index 2d3523476..5833e48be 100644 --- a/changelog-en.md +++ b/changelog-en.md @@ -1,12 +1,49 @@ ## Changelog - Extension +##### 3.10.0.0 + +**New** +- QI Progress Overview added (opens automatically when opening the QI player ranking) +- Item Sources: Production Overview for Items/Fragments now offers an option to display a list of buildings that produce a certain item (even if not currently build) +- Production Overview: Added Tables for resources boosts (FP, coins, supplies) +- Efficiency rating: Added FSP Fragments to the evaluation +- City Overview: Highlight option for ascendable and decayed buildings +- Repeat Building Selection: + - !!! ATTENTION !!! Although the feature was green-lit by Inno, it might happen that the bot detection triggers. Use at your own risk!!! + - Can be activated in the settings + - When a building is built from the build menu or placed from the reconstruction storage, the same building is selected again automatically. + +**Update** +- Tooltip: made design similar to original FoE tooltips +- Building Efficiency: + - Added building tooltips + - Results will now be shown first + - Item list hidden to make the table less crowded +- Menu: Moved it back to the right (default was bottom), because of a game update and y'all do not look at settings +- GBG: + - Added symbols for the battle type (red/blue) to the countdown list + - Added attack colors to the map + - Added map view to highlight attack colors better +- GBG active players: + - removed the module on Innos request + +**BugFix** +- Tooltip: + - Some browsers did not use the correct design + - Did sometimes not vanish when a box was closed +- Reconstruction List: + - Set a default height + - Moving buildings reduced counter +- Building Efficiency: + - Other players ratings were based on your age instead of theirs + ##### 3.9.0.0 **New** - In reconstruction mode a building list, sortable by building size is offered - GE-Results: Menu icon now shows the current number of attempts - Tooltips: some modules now show the building information as a tooltip: - - Effiziency module - in the "add building" dialogue + - Efficiency module - in the "add building" dialogue - Boost Inventory - Reconstruction size-list - let us know on discord where else you would like to see that info @@ -20,7 +57,7 @@ - Broke for some players due to a game update - Same buildings with/without allies were not counted correctly - Porduction Overview: - - Fragment amount was not korrekt for some buildings + - Fragment amount was not correct for some buildings - Not all buildings were listed in fragments overview ##### 3.8.1.0 diff --git a/css/web/_menu_bottom.css b/css/web/_menu_bottom.css index 07457e0ed..3511623ce 100644 --- a/css/web/_menu_bottom.css +++ b/css/web/_menu_bottom.css @@ -15,11 +15,11 @@ left: 1035px; bottom: 0; width: 270px; - height: 48px; + height: 43px; border-radius: 2px 2px 0 0; transition: all 0.1s ease; border-bottom-width: 0; - background-color: #553419; + background-color: #301e0fcc; } .hud-bottom #foe-helper-hud-wrapper { @@ -32,7 +32,7 @@ .hud-bottom #foe-helper-hud-slider { position: absolute; left: 0; - top: 2px; + top: 0; transition: left 0.7s ease-in-out; height: inherit; } @@ -43,9 +43,9 @@ .hud-bottom .hud-btn span:first-child { display: inline-flex; - width: 76%; - height: 76%; - margin-top: 12%; + width: 80%; + height: 80%; + margin-top: 10%; } .hud-bottom .hud-btn span.hud-counter { diff --git a/css/web/_menu_box.css b/css/web/_menu_box.css index bbfc1936f..9ef84d91f 100644 --- a/css/web/_menu_box.css +++ b/css/web/_menu_box.css @@ -11,3 +11,9 @@ * ************************************************************************************** */ +#menu_box .hud-btn span:first-child { + display: inline-flex; + width: 80%; + height: 80%; + margin-top: 10%; +} \ No newline at end of file diff --git a/css/web/_menu_right.css b/css/web/_menu_right.css index 24cf65c08..bbfc1936f 100644 --- a/css/web/_menu_right.css +++ b/css/web/_menu_right.css @@ -11,110 +11,3 @@ * ************************************************************************************** */ - -#foe-helper-hud.hud-right { - right: 0; - top: 400px; - width: 51px; - height: 270px; - border-radius: 4px 0 0 4px; - transition: height 0.2s linear; - border-width: 0; - background-color: #301e0fcc; -} - -.hud-right::before { - top: 0; - border-bottom: 2px solid #755b43; -} - -.hud-right::after { - border-top: 2px solid #755b43; - left: 0; - bottom: 0; -} - -.hud-right #foe-helper-hud-wrapper { - width: inherit; - height: 218px; - right: 0; - top: 1px; -} - -.hud-right #foe-helper-hud-slider { - position: absolute; - top: 0; - right: 0; - transition: top 0.7s ease-in-out; -} - -.hud-right .hud-btn { - height: 47px; - width: 48px; - margin-bottom: 2px; -} - -.hud-right .menu-placeholder { - width: 49px; - height: 49px; -} - -.hud-right .hud-btn span.hud-counter { - padding: 2px; - width: 16px; - height: 16px; - bottom: 2px; - left: 2px; - line-height: 16px; -} - -.hud-btn-up, -.hud-btn-down { - position: absolute; - width: 50px; - height: 14px; - right: 0; - display: block; - z-index: 1; - box-shadow: 0 0 1px 1px var(--black-50); -} - -.hud-btn-up-active, .hud-btn-down-active { - background: var(--background-hud-btn); -} - -.hud-btn-up-active:hover, .hud-btn-down-active:hover { - filter: brightness(1.3) contrast(1.1); -} - -.hud-btn-up-active { - top: -15px; - border-radius: 5px 0 0 0; -} - -.hud-btn-down-active { - bottom: -14px; - border-radius: 0 0 0 5px; -} - -.hud-btn-up::before, -.hud-btn-down::before { - content: ''; - display: block; - position: absolute; - right: 30%; - top: 2px; - width: 0; - height: 0; - border-left: 12px solid transparent; - border-right: 12px solid transparent; -} - -.hud-btn-up::before { - border-bottom: 9px solid #48291b; -} - -.hud-btn-down::before { - bottom: 1px; - border-top: 9px solid #48291b; -} \ No newline at end of file diff --git a/css/web/boxes.css b/css/web/boxes.css index ba1763464..e5682fd87 100644 --- a/css/web/boxes.css +++ b/css/web/boxes.css @@ -187,6 +187,11 @@ a[target="_blank"] svg { outline: none !important; } +.btn-default a { + color: inherit; + text-decoration: inherit; +} + .btn-default[disabled], .btn-default[disabled]:hover { filter: saturate(10%) brightness(80%); } @@ -376,7 +381,8 @@ table.foe-table thead th { } table.foe-table tbody tr:nth-child(odd), ul.foe-table li:nth-child(odd) { - background-color: var(--background-table-odd); + -webkit-backdrop-filter: brightness(1.1) saturate(1.1); + backdrop-filter: brightness(1.1) saturate(1.1); } table.foe-table:not(.no-hover) tbody tr:hover { @@ -1275,9 +1281,9 @@ FP-Bar */ max-width: 250px; padding: 8px; color: var(--text-tab-active); + background-color: var(--text-darkest); text-align: center; text-decoration: none; - background-color: var(--text-darkest); -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; @@ -1352,14 +1358,14 @@ FP-Bar */ width: 180px; border: 2px solid #373c32; background-color: var(--bg-tooltip); - z-index: 999; + box-shadow: 0 0 2px 1px var(--black-65); color: #f2ede1; + z-index: 999; padding: 5px; pointer-events: none; user-select: none; margin: 0; opacity: 1; - box-shadow: 0 0 2px 1px var(--black-65); box-sizing: border-box; } @@ -1722,7 +1728,6 @@ input[type="range"]::-webkit-slider-thumb { font-size: 0.75rem; font-weight: 400; box-sizing: border-box; - border: 2px solid #755b43; box-shadow: 0 0 1px 1px var(--black-50); } @@ -1746,7 +1751,6 @@ input[type="range"]::-webkit-slider-thumb { } .hud-btn-left, .hud-btn-right { - border: 2px solid #624d3a; border-bottom-width: 0; } @@ -1771,7 +1775,7 @@ input[type="range"]::-webkit-slider-thumb { } .hud-btn-right-active { - right: -13px; + right: -14px; } .hud-btn-left-active { @@ -1791,7 +1795,7 @@ input[type="range"]::-webkit-slider-thumb { border-bottom: 12px solid transparent; position: relative; top: 25%; - left: 2px; + left: 4px; } .hud-btn-left-active::before { @@ -1811,16 +1815,16 @@ input[type="range"]::-webkit-slider-thumb { } .hud-btn { - width: 43px; - height: 43px; + width: 40px; + height: 40px; margin: 1px; display: block; position: relative; box-sizing: border-box; border: 2px solid transparent; border-radius: 4px; - box-shadow: inset 0 0 1px 2px #1f1309cc, 0 0 2px #00000087; - background: linear-gradient(#553419, #553419) padding-box, linear-gradient(to bottom, #82ae4c, #4f7421) border-box; + box-shadow: inset 0 0 1px 1px #1f1309cc, 0 0 2px #000000c9; + background: linear-gradient(#4d2e16, #492d16) padding-box, linear-gradient(to bottom, #82ae4c, #4f7421) border-box; text-align: center; } @@ -1837,9 +1841,9 @@ input[type="range"]::-webkit-slider-thumb { background-repeat: no-repeat; background-size: contain; display: inline-flex; - width: 70%; - height: 70%; - margin-top: 15%; + width: 76%; + height: 76%; + margin-top: 12%; } .hud-btn span.hud-counter { @@ -1861,6 +1865,120 @@ input[type="range"]::-webkit-slider-thumb { font-size: 0.8rem; } + +#foe-helper-hud.hud-right { + right: 0; + top: 400px; + width: 49px; + height: 270px; + border-radius: 4px 0 0 4px; + transition: height 0.2s linear; + border-width: 0; + background-color: #301e0fcc; +} + +.hud-right::before { + top: 0; + border-bottom: 2px solid #755b43; +} + +.hud-right::after { + border-top: 2px solid #755b43; + left: 0; + bottom: 0; +} + +.hud-right #foe-helper-hud-wrapper { + width: inherit; + height: 218px; + right: 0; + top: 1px; +} + +.hud-right #foe-helper-hud-slider { + position: absolute; + top: 0; + right: 0; + transition: top 0.7s ease-in-out; +} + +.hud-right .hud-btn { + height: 45px; + width: 46px; + margin-bottom: 2px; +} + +.hud-right .menu-placeholder { + width: 49px; + height: 49px; +} + +.hud-right .hud-btn span.hud-counter { + padding: 2px; + width: 16px; + height: 16px; + bottom: 2px; + left: 2px; + line-height: 16px; +} + +.hud-right .hud-btn-up, +.hud-right .hud-btn-down { + position: absolute; + width: 49px; + height: 14px; + right: 0; + z-index: 1; +} + +.hud-right .hud-btn-up { + top: -14px; +} + +.hud-right .hud-btn-down { + bottom: -14px; +} + +.hud-btn-up-active, .hud-btn-down-active { + background: var(--background-hud-btn); +} + +.hud-btn-up-active:hover, .hud-btn-down-active:hover { + filter: brightness(1.3) contrast(1.1); +} + +.hud-btn-up-active { + top: -15px; + border-radius: 5px 0 0 0; +} + +.hud-btn-down-active { + bottom: -14px; + border-radius: 0 0 0 5px; +} + +.hud-btn-up::before, +.hud-btn-down::before { + content: ''; + display: block; + position: absolute; + right: 25%; + top: 2px; + width: 0; + height: 0; + border-left: 12px solid transparent; + border-right: 12px solid transparent; +} + +.hud-btn-up::before { + border-bottom: 9px solid #48291b; +} + +.hud-btn-down::before { + bottom: 1px; + border-top: 9px solid #48291b; +} + .menu-placeholder { background: var(--black-50); border-radius: 4px; @@ -1985,6 +2103,16 @@ tr.sorter-header th:not(.no-sort).descending:after { opacity: 1; } +.sticky { + top: 0; + position: sticky; + z-index: 200; +} + +.w-full { + width: 100% +} + .scrollup { border-radius: 50%; width: 30px; @@ -1996,6 +2124,13 @@ tr.sorter-header th:not(.no-sort).descending:after { z-index: 101; } + +.d-none { + display: none; +} +.d-none { + display: none; +} /*fallback for all tools that do not specify their own scale*/ :root { --unit_scale: 3/5; diff --git a/css/web/variables.css b/css/web/variables.css index d1299e638..1564f7f0d 100644 --- a/css/web/variables.css +++ b/css/web/variables.css @@ -53,7 +53,7 @@ --background-tabs: linear-gradient(#494241, #2b2c33); --background-tabs-active: linear-gradient(#4a5c7a, #3b4863); - --background-table-hover: rgba(243, 214, 160, 0.2); + --background-table-hover: #ffb45733; --background-table-odd: rgba(255, 158, 69, 0.07); --background-table-darker: #40190080; --background-table-info: #003c6d4d; @@ -81,6 +81,10 @@ --text-info: #42a1ee; --text-danger: #f34f4f; + --background-color-ascendable: #f37317; + --border-color-ascendable: #ce5900; + --background-color-decayed: #2b2b2b; + --border-color-decayed: #161616; --background-color-military: #fff; --border-color-military: #bbb; --background-color-residential: #7abaff; diff --git a/js/inject.js b/js/inject.js index 7984a5998..fc4568c54 100644 --- a/js/inject.js +++ b/js/inject.js @@ -132,7 +132,7 @@ function inject (loadBeta = false, extUrl = chrome.runtime.getURL(''), betaDate= // Document loaded if(document.head !== null){ let MenuSetting = localStorage.getItem('SelectedMenu'); - MenuSetting = MenuSetting ? MenuSetting : 'BottomBar'; + MenuSetting = MenuSetting ? MenuSetting : 'RightBar'; let cssname = "_menu_" + MenuSetting.toLowerCase().replace("bar",""); let cssFiles = [ @@ -143,8 +143,7 @@ function inject (loadBeta = false, extUrl = chrome.runtime.getURL(''), betaDate= ]; // insert stylesheet - for(let i in cssFiles) - { + for(let i in cssFiles) { if(!cssFiles.hasOwnProperty(i)) { break; } diff --git a/js/internal.json b/js/internal.json index 67d08d255..83594d544 100644 --- a/js/internal.json +++ b/js/internal.json @@ -1,5 +1,6 @@ [ "srcLinks", + "mouseActions", "_languages", "_helper", "_menu", @@ -39,6 +40,7 @@ "fp-collector", "maptradewarning", "guildmemberstat", + "qiprogress", "quests", "gexstat", "dbexport", diff --git a/js/web/_helper/js/_helper.js b/js/web/_helper/js/_helper.js index d2a6f9552..2bc260227 100644 --- a/js/web/_helper/js/_helper.js +++ b/js/web/_helper/js/_helper.js @@ -281,6 +281,7 @@ let HTML = { $('#' + args['id']).fadeToggle('fast', function () { $(this).remove(); + Tooltips.deactivate() }); }); } @@ -854,7 +855,7 @@ let HTML = { icon: d['type'], hideAfter: d['hideAfter'], position: Settings.GetSetting('NotificationsPosition', true), - extraClass: localStorage.getItem('SelectedMenu') || 'bottombar', + extraClass: localStorage.getItem('SelectedMenu') || 'RightBar', stack: localStorage.getItem('NotificationStack') || 4 }); }, @@ -970,7 +971,7 @@ let HTML = { let CurrentCell = DataRow[ValidColumnNames[j]]; if (CurrentCell !== undefined) { if ($.isNumeric(CurrentCell)) { - CurrentCells.push(Number(CurrentCell).toLocaleString(i18n('Local'))); + CurrentCells.push(Number(CurrentCell).toLocaleString(i18n('Local'),{useGrouping:false})); } else { CurrentCells.push(CurrentCell); @@ -990,7 +991,27 @@ let HTML = { // with UTF-8 BOM let BlobData = new Blob(["\uFEFF" + FileContent], { type: "application/octet-binary;charset=ANSI" }); - MainParser.ExportFile(BlobData, FileName + '.' + Format); + MainParser.ExportFile(BlobData, FileName + '-' + moment().format('YYYY-MM-DD') + '.' + Format); + }); + }, + + + FilterTable: (selector) => { + $(selector).on('click', (e) => {e.stopPropagation()}) + $(selector).on('keyup', function (e) { + let filter = $(this).val().toLowerCase() + let table = $(this).parents("table") + if (filter.length >= 2) { + $("tbody tr", table).hide() + $("tbody tr", table).filter(function() { + let foundText = ($(this).text().toLowerCase().indexOf(filter) > -1) + if (foundText) + $(this).show() + }); + } + else { + $("tbody tr", table).show() + } }); }, diff --git a/js/web/_i18n/de.json b/js/web/_i18n/de.json index ce3743548..a1af5c1d0 100644 --- a/js/web/_i18n/de.json +++ b/js/web/_i18n/de.json @@ -231,6 +231,8 @@ "Boxes.CityMap.QIActionRechargeCycle": "pro Stunde", "Boxes.CityMap.QICycle": "alle 10 Stunden", "Boxes.CityMap.QIHint": "Alle Werte, außer Aktionen pro Stunde, nehmen an, dass die Gebäude fertiggestellt sind.", + "Boxes.CityMap.ShowAscendableBuildings": "Markiere Gebäude, die erhaben sein können", + "Boxes.CityMap.ShowDecayedBuildings": "Markiere Gebäude, die abgelaufen sind", "Boxes.CityMap.ShowNoStreetBuildings": "Markiere Gebäude, die keine Straße brauchen", "Boxes.CityMap.ShowSubmitBox": "Stadtplaner", "Boxes.CityMap.StreetsAmount": "Anzahl Straßen: ", @@ -473,6 +475,7 @@ "Boxes.GuildFights.ShowRoundSelector": "zeige GG Rundenauswahl", "Boxes.GuildFights.SnapshotLog": "Snapshot Log", "Boxes.GuildFights.SnapShotLogDisclaimer": "Achtung: Diese Daten basieren auf den von dir erfassten Daten. Das bedeutet, dass die hier gezeigten Zahlen wahrscheinlich nicht 100%ig stimmen, da für ein exaktes Ergebnis die Rangliste immer um Mitternacht geöffnet werden muss. ", + "Boxes.GuildFights.Switch": "Ansicht ändern", "Boxes.GuildFights.Time": "um", "Boxes.GuildFights.Title": "Spieler Übersicht", "Boxes.GuildFights.Total": "Gesamt", @@ -580,6 +583,7 @@ "Boxes.HiddenRewards.Title": "Ereignisse", "Boxes.HiddenRewards.none": "keine", "Boxes.HiddenRewards.onlyVis": "nur aufgedeckte", + "Boxes.HiddenRewards.twolaneWarning": "Wenn ein Ereignis auf einer zweispurigen Straße angezeigt wird, muss eine zweispurige Straße gebaut werden, um es einsammeln zu könnnen!", "Boxes.InactivesSettings.Title":"Abgelaufen Alarme umschalten", "Boxes.InactivesSettings.Toggle":"Klick zum Umschalten", "Boxes.InactivesSettings.NoAlert":"kein Alarm", @@ -642,6 +646,7 @@ "Boxes.Investment.TotalFP": "Lager + Umlauf + Gewinn: ", "Boxes.Investment.UpToDate": "Die Investitionen wurden vor weniger als 30 Minuten aktualisiert.", "Boxes.Investment.UpdateRequired": "Deine Investitionen sind älter als 30 Minuten. Bitte aktualisiere sie über das Rathaus.", + "Boxes.ItemSources.Title": "Quellen für Gegenstände", "Boxes.Kits.Antiques_Dealer": "Antiquitätenhändler", "Boxes.Kits.Base": "Stufe 1 Gebäude oder Auswahlkit", "Boxes.Kits.Cultural_Settlements": "Kulturellen-Siedlungen", @@ -904,6 +909,7 @@ "Boxes.Productions.Done": "Fertig", "Boxes.Productions.EmptyList": "Du hast keine Gebäude in dieser Kategorie.", "Boxes.Productions.FilterTable": "Gebäude filtern", + "Boxes.Productions.FSP": "Spezial-Production abschließen Fragment", "Boxes.Productions.GoodEraTotal": "Gesamt", "Boxes.Productions.GuildGoods": "Gildengüter", "Boxes.Productions.GuildPower": "Gildenmacht", @@ -976,6 +982,8 @@ "Boxes.ProductionsRating.ShowValuesPerTile": "Werte pro Feld", "Boxes.ProductionsRating.Title": "Gebäude - Effizienzberechnung", "Boxes.ProductionsRating.Filter":"Suche", + "Boxes.ProductionsRating.Reset":"Auf Standartwerte zurücksetzen", + "Boxes.ProductionsRating.ConfirmReset":"Bestätige Rücksetzen?", "Boxes.ProductionsRating.FindSpecialBuilding":"Spezialgebäude finden", "Boxes.PvPArena.Title": "PvP-Arena", "Boxes.PvPArena.Type": "Art", @@ -986,6 +994,14 @@ "Boxes.PvPArena.Tabs.DefenseFights": "Verteidigung", "Boxes.PvPArena.Tabs.LostAttackFights": "verl. Angriffe", "Boxes.QIMap.Title": "QI Karte", + "Boxes.QiProgress.Actions": "Aktionen", + "Boxes.QiProgress.Progress": "Fortschritt", + "Boxes.QiProgress.QiRound": "QI Runde", + "Boxes.QiProgress.ShowProgressFilter": "Forschrittsfilter anzeigen", + "Boxes.QiProgress.ShowRoundSelector": "Runden-Auswahl anzeigen", + "Boxes.QiProgress.SnapshotLog": "QI Snapshot Log", + "Boxes.QiProgress.SnapShotLogDisclaimer": "Diese Daten sind nicht zu 100% zutreffend, wenn du nicht um Mitternacht (Server-Zeit) den Spielerfortschritt trackst.", + "Boxes.QiProgress.Title": "QI Übersicht", "Boxes.ReconstructionList.Title":"Umbau-Menü Größenliste", "Boxes.RecurringQuests.Title": "Wiederkehrende Quests", "Boxes.RecurringQuests.showCounter": "Zeige Zähler für offene Quests im Menu", @@ -1217,7 +1233,9 @@ "Eras.9.short": "JHW", "Eras.GvGAllAge": "Alle Zeitalter", "General.Boost":"Boost", + "General.Date":"Datum", "General.GB": "Legendäres Bauwerk", + "General.Items": "Items", "General.Level": "Stufe", "General.Player": "Spieler", "General.Reset": "Zurücksetzen", @@ -1486,9 +1504,9 @@ "Settings.Entry.ShowGBGBuildings": "GG Gebäude Empfehlung", "Settings.ShowGBGBuildings.Title": "GG Gebäude Empfehlung anzeigen", "Settings.ShowGBGBuildings.Desc": "Zeigt beim Öffnen des Baumenüs einer GG Provinz eine Tabelle an mit den möglichen Gebäudekombinationen die besser sind als die aktuell vorhandene, sortiert nach relativer Beanspruchung der Gildenkasse.", - "Settings.Entry.ShowOtherGuildActivity": "GG Aktive Spieler", - "Settings.ShowOtherGuildActivity.Title": "Aktive Spieler anderer Gilde", - "Settings.ShowOtherGuildActivity.Desc": "Wenn sich beim Besuch anderer Gilden die Anzahl Kämpfe der Spieler in kurzer Zeit geändert haben, wird eine Liste mit den aktiven Spielern ausgegeben.", + "Settings.Entry.RepeatSelectBuilding": "Wiederholtes Bauen", + "Settings.RepeatSelectBuilding.Title": "Wiederholtes Bauen", + "Settings.RepeatSelectBuilding.Desc": " !!! Achtung - Auch wenn unwahrscheinlich, kann es bei Nutzung dieser Option dazu kommen, das Innos Bot-Erkennung ausgelöst wird mit einer damit verbundenen kurzen Sperre !!! Bitte gebt uns Bescheid, sollte es dazu kommen.

Nachdem ein Gebäude aus dem Baumenu oder der Umbauleiste platziert wurde, wird das gleiche Gebäude automatisch nochmal ausgewählt (Straßen ausgenommen).", "Settings.ShowPvPArena.Title": "PvP-Arena-Protokoll", "Settings.ShowPvPArena.Desc": "Soll das PvP-Arena-Protokoll angezeigt werden, wenn die PvP-Arena geöffnet wird?", "Settings.Tab.About": "Info + Website", diff --git a/js/web/_i18n/en.json b/js/web/_i18n/en.json index ea42ddc9e..7df33e9b8 100644 --- a/js/web/_i18n/en.json +++ b/js/web/_i18n/en.json @@ -231,6 +231,8 @@ "Boxes.CityMap.QIActionRechargeCycle": "every hour", "Boxes.CityMap.QICycle": "every 10 hours", "Boxes.CityMap.QIHint": "All displayed values, except Actions per Hour, assume your buildings have finished construction.", + "Boxes.CityMap.ShowAscendableBuildings": "Highlight ascendable buildings", + "Boxes.CityMap.ShowDecayedBuildings": "Highlight decayed buildings", "Boxes.CityMap.ShowNoStreetBuildings": "Highlight buildings that do not need streets", "Boxes.CityMap.ShowSubmitBox": "City planner", "Boxes.CityMap.StreetsAmount": "Number of Streets: ", @@ -473,6 +475,7 @@ "Boxes.GuildFights.ShowRoundSelector": "show GBG round selector", "Boxes.GuildFights.SnapshotLog": "Snapshot Log", "Boxes.GuildFights.SnapShotLogDisclaimer": "Disclaimer: This data is based on your collected data. The numbers shown here are probably not 100% accurate. You'd have to open the list at midnight for them to be correct.", + "Boxes.GuildFights.Switch": "Switch view", "Boxes.GuildFights.Time": "at", "Boxes.GuildFights.Title": "GBG Overview", "Boxes.GuildFights.Total": "Total", @@ -579,6 +582,7 @@ "Boxes.HiddenRewards.Title": "Incidents Overview", "Boxes.HiddenRewards.none": "none", "Boxes.HiddenRewards.onlyVis": "only uncovered", + "Boxes.HiddenRewards.twolaneWarning": "If an incident is displayed to be on a two-lane road, such a road must be built in order to be able to collect the reward!", "Boxes.InactivesSettings.Title":"Toggle expiry Alert", "Boxes.InactivesSettings.Toggle":"Click to toggle:", "Boxes.InactivesSettings.NoAlert":"No alert", @@ -641,6 +645,7 @@ "Boxes.Investment.TotalFP": "Stock + Invested + Profit = ", "Boxes.Investment.UpToDate": "The investment list was updated less than 30 minutes ago.", "Boxes.Investment.UpdateRequired": "The investment list is older than 30 minutes. Please update your investment list in the Town Hall.", + "Boxes.ItemSources.Title": "Item Sources", "Boxes.Kits.Antiques_Dealer": "Antiques Dealer", "Boxes.Kits.Base": "Level 1 building or selection kit", "Boxes.Kits.new_not_categorized": "New / not yet categorized", @@ -904,6 +909,7 @@ "Boxes.Productions.Done": "Done", "Boxes.Productions.EmptyList": "There are no buildings in this category.", "Boxes.Productions.FilterTable": "Filter buildings", + "Boxes.Productions.FSP": "Finish Special Production Fragment", "Boxes.Productions.GoodEraTotal": "Total", "Boxes.Productions.GuildGoods": "Treasury Goods", "Boxes.Productions.GuildPower": "Guild Power", @@ -977,6 +983,8 @@ "Boxes.ProductionsRating.Title": "Buildings Efficiency Rating", "Boxes.ProductionsRating.Filter":"Search", "Boxes.ProductionsRating.FindSpecialBuilding":"Find Special Building", + "Boxes.ProductionsRating.Reset":"Reset to default", + "Boxes.ProductionsRating.ConfirmReset":"Confirm Reset?", "Boxes.PvPArena.Title": "PvP-Arena", "Boxes.PvPArena.Type": "Type", "Boxes.PvPArena.PlayerName": "Player", @@ -986,6 +994,14 @@ "Boxes.PvPArena.Tabs.DefenseFights": "Defense", "Boxes.PvPArena.Tabs.LostAttackFights": "lost Attacks", "Boxes.QIMap.Title": "Quantum Incursion Map", + "Boxes.QiProgress.Actions": "Actions", + "Boxes.QiProgress.Progress": "Progress", + "Boxes.QiProgress.QiRound": "QI Round", + "Boxes.QiProgress.ShowProgressFilter": "Show progress filter", + "Boxes.QiProgress.ShowRoundSelector": "Show QI round selector", + "Boxes.QiProgress.SnapshotLog": "QI Snapshot Log", + "Boxes.QiProgress.SnapShotLogDisclaimer": "Disclaimer: This data is based on your collected data. The numbers shown here are probably not 100% accurate. You'd have to open the list at midnight for them to be correct.", + "Boxes.QiProgress.Title": "QI Overview", "Boxes.ReconstructionList.Title":"Reconstruction Size List", "Boxes.RecurringQuests.AND": "AND", "Boxes.RecurringQuests.OR": "OR", @@ -1216,8 +1232,10 @@ "Eras.9.short": "PE", "Eras.GvGAllAge": "All Ages", "General.Boost":"Boost", + "General.Date":"Date", "General.GB": "Great Building", "General.Guild": "Guild", + "General.Items": "Items", "General.Level": "Level", "General.Player": "Player", "General.Reset": "Reset", @@ -1483,9 +1501,9 @@ "Settings.Entry.ShowGBGBuildings": "GBG Building Recommendation", "Settings.ShowGBGBuildings.Title": "Show GBG Building Recommendation", "Settings.ShowGBGBuildings.Desc": "When opening the building menu in a GBG Province, a table is displayed, showing the possible building combinations that would be better than the current one, sorted by their relative impact on the Guild Treasury.", - "Settings.Entry.ShowOtherGuildActivity": "GBG Active Players", - "Settings.ShowOtherGuildActivity.Title": "Other Guilds Active Players", - "Settings.ShowOtherGuildActivity.Desc": "If when visiting other guilds, the number of battles of any Player changed, a List of active players is shown.", + "Settings.Entry.RepeatSelectBuilding": "Repeat Building Selection", + "Settings.RepeatSelectBuilding.Title": "Repeat last Building Selection", + "Settings.RepeatSelectBuilding.Desc": "!!! Attention - Although unlikely, using this option might trigger INNOs bot detection and may cause a short ban period !!! Please let us know should that happen.

After placing a building from the build menu or the reconstruction side bar will cause the same building to be selected automatically (streets excluded).", "Settings.ShowPvPArena.Title": "PvP-Arena-Protocol", "Settings.ShowPvPArena.Desc": "Show PvP-Arena-Protocol, when opening the PvP-Arena?", "Settings.Tab.About": "Info + Website", diff --git a/js/web/_i18n/fr.json b/js/web/_i18n/fr.json index 3e92420ab..4df2c0db7 100644 --- a/js/web/_i18n/fr.json +++ b/js/web/_i18n/fr.json @@ -229,6 +229,8 @@ "Boxes.CityMap.QIActionRechargeCycle": "Toutes les heures", "Boxes.CityMap.QICycle": "toutes les 10 heures", "Boxes.CityMap.QIHint": "Toutes les valeurs affichées, à 'exception des actions par heure, supposent que la construction de vos bâtiments est terminée.", + "Boxes.CityMap.ShowAscendableBuildings": "Mettre en surbrillance les bâtiments améliorables", + "Boxes.CityMap.ShowDecayedBuildings": "Mettre en surbrillance les bâtiments limités échus", "Boxes.CityMap.ShowNoStreetBuildings": "Mettre en surbrillance les bâtiments qui n'ont pas besoin de route", "Boxes.CityMap.ShowSubmitBox": "Envoyer", "Boxes.CityMap.StreetsAmount": "Nombres de routes : ", @@ -469,6 +471,7 @@ "Boxes.GuildFights.ShowRoundSelector": "Afficher le sélecteur de tour de CBG", "Boxes.GuildFights.SnapShotLogDisclaimer": "Avis de non-responsabilité : ces données sont basées sur vos données collectées. Les chiffres présentés ici ne sont probablement pas exacts à 100 %. Il faudrait ouvrir la liste à minuit pour qu'ils soient corrects.", "Boxes.GuildFights.SnapshotLog": "Log des aperçus instantanés", + "Boxes.GuildFights.Switch": "Changer la vue", "Boxes.GuildFights.Time": "à", "Boxes.GuildFights.Title": "Activité de membre", "Boxes.GuildFights.Total": "Total", @@ -575,6 +578,7 @@ "Boxes.HiddenRewards.Title": "Récompenses cachées", "Boxes.HiddenRewards.none": "aucun", "Boxes.HiddenRewards.onlyVis": "seulement découvert", + "Boxes.HiddenRewards.twolaneWarning": "Si un incident s'avère sur une route à deux voies, une telle route doit être construite afin de pouvoir récupérer la récompense !", "Boxes.InactivesSettings.AlertActive": "Alerte active", "Boxes.InactivesSettings.NoAlert": "Pas d'alerte", "Boxes.InactivesSettings.Title": "Activer/désactiver l'alerte d'expiration", @@ -637,6 +641,7 @@ "Boxes.Investment.TotalFP": "Total PF (stock + investis + gains) : ", "Boxes.Investment.UpToDate": "La liste des investissements a été mise à jour il y a moins de 30 minutes.", "Boxes.Investment.UpdateRequired": "La liste des investissements a plus de 30 minutes. Veuillez mettre à jour votre liste d'investissements à l'Hôtel de Ville.", + "Boxes.ItemSources.Title": "Objet produit par ...", "Boxes.Kits.Antiques_Dealer": "Antiquaire", "Boxes.Kits.Base": "Bâtiment niv 1 ou Kit de sélection", "Boxes.Kits.Cultural_Settlements": "Colonies culturelles", @@ -900,6 +905,7 @@ "Boxes.Productions.DateNA": "Inconnu", "Boxes.Productions.Done": "Terminé", "Boxes.Productions.EmptyList": "Il n'y a pas de bâtiment dans cette catégorie.", + "Boxes.Productions.FSP": "Finition Fragment de production spéciale", "Boxes.Productions.FilterTable": "Filtre Bâtiments", "Boxes.Productions.GoodEraTotal": "Total", "Boxes.Productions.GuildGoods": "Trésorerie de guilde", @@ -958,6 +964,7 @@ "Boxes.ProductionsRating.AddBuilding": "Ajouter un bâtiment spécial", "Boxes.ProductionsRating.AddBuildings": "Ajouter tous les bâtiments sélectionnés", "Boxes.ProductionsRating.BuildingName": "Bâtiment", + "Boxes.ProductionsRating.ConfirmReset": "Confirmer la réinitialisation ?", "Boxes.ProductionsRating.CountTooltip": "Remarque : tous les bâtiments ne correspondent peut-être pas encore à l'époque indiquée à côté du nom. Vérifiez sur la carte pour être sûr !", "Boxes.ProductionsRating.Disclaimer": "Pour les bâtiments de chaîne, l’ensemble de la chaîne est traité comme un seul bâtiment. Pour les ensembles, nous supposons que toutes les pièces sont entièrement connectées.", "Boxes.ProductionsRating.Enabled": "Activé", @@ -967,6 +974,7 @@ "Boxes.ProductionsRating.FindSpecialBuilding": "Trouver un bâtiment spécial", "Boxes.ProductionsRating.HighlightsExplained": "Comment mettre en évidence les bâtiments : cliquez sur n'importe quelle ligne pour sélectionner les bâtiments que vous souhaitez comparer plus facilement. Les résultats de la recherche sont marqués automatiquement.", "Boxes.ProductionsRating.ProdPerTile": "Production quotidienne prévue/case", + "Boxes.ProductionsRating.Reset": "Rétablissement des valeurs par défaut", "Boxes.ProductionsRating.Results": "Résultat", "Boxes.ProductionsRating.Score": "Note", "Boxes.ProductionsRating.Settings": "Réglages", @@ -983,6 +991,15 @@ "Boxes.PvPArena.Title": "Arène JcJ", "Boxes.PvPArena.Type": "Type", "Boxes.QIMap.Title": "Carte des Incursions Quantiques", + "Boxes.QiProgress.Actions": "Actions", + "Boxes.QiProgress.Progress": "Progrès", + "Boxes.QiProgress.QiRound": "Tour IQ", + "Boxes.QiProgress.ShowProgressFilter": "Filtre Afficher Progrès", + "Boxes.QiProgress.ShowRoundSelector": "Afficher Sélecteur Tour QI", + "Boxes.QiProgress.SnapShotLogDisclaimer": "Avis de non-responsabilité : ces données sont basées sur vos données collectées. Les chiffres présentés ici ne sont probablement pas exacts à 100 %. Il faudrait ouvrir la liste à minuit pour qu'ils soient corrects.", + "Boxes.QiProgress.SnapshotLog": "IQ Log aperçu instantané", + "Boxes.QiProgress.Title": "Aperçu IQ", + "Boxes.ReconstructionList.Title": "Liste de tailles des objets en Reconstruction", "Boxes.RecurringQuests.AND": "ET", "Boxes.RecurringQuests.OR": "OU", "Boxes.RecurringQuests.Table.Quest": "Nom de la quête", @@ -1065,6 +1082,21 @@ "Boxes.Technologies.NoTechs": "Vous avez atteint la fin de cette ère.", "Boxes.Technologies.Resource": "Ressource", "Boxes.Technologies.Title": "Recherches technologiques", + "Boxes.Tooltip.Building.addInhabitant": "Ajouter un habitant unique", + "Boxes.Tooltip.Building.after": "Après", + "Boxes.Tooltip.Building.allyRooms": "Emplacement Alliés historiques", + "Boxes.Tooltip.Building.canMotivate": "Peut-être motivé", + "Boxes.Tooltip.Building.canPolish": "Peut être poli", + "Boxes.Tooltip.Building.costs": "Coûts", + "Boxes.Tooltip.Building.lifeSupport": "est affecté par le système de survie", + "Boxes.Tooltip.Building.noPlunder": "Ne peut pas être pillé", + "Boxes.Tooltip.Building.produces": "Produit", + "Boxes.Tooltip.Building.provides": "Fournit", + "Boxes.Tooltip.Building.road": "Route requise", + "Boxes.Tooltip.Building.road2": "route 2 voies requise", + "Boxes.Tooltip.Building.size+time": "Taille et temps de construction", + "Boxes.Tooltip.Building.traits": "Caractéristiques", + "Boxes.Tooltip.Building.when": "Quand", "Boxes.Treasury.Action": "Message", "Boxes.Treasury.Amount": "Montant", "Boxes.Treasury.DateTime": "Date/Heure", @@ -1201,10 +1233,12 @@ "Eras.9.short": "Prog", "Eras.GvGAllAge": "Toutes ères", "General.Boost": "Boost", + "General.Date": "Date", "General.GB": "Grand Monument", "General.Good": "Ressource", "General.Goods": "Ressources", "General.Guild": "Guilde", + "General.Items": "Objets", "General.Level": "Niveau", "General.Player": "Joueur", "General.Reset": "Réinitialiser", @@ -1363,10 +1397,12 @@ "Settings.Entry.Help": "Aide", "Settings.Entry.HideHelperDuringBattle": "Visibilité de l'assistant en bataille", "Settings.Entry.LoadBeta": "Charger la version Beta actuelle", + "Settings.Entry.LoadBeta2": "Charger la version Beta", "Settings.Entry.MenuContent": "Contenu du menu", "Settings.Entry.MenuLength": "Menu", "Settings.Entry.NotificationsPosition": "Emplacement de la notification", "Settings.Entry.NotificationsStack": "Notifications multiples", + "Settings.Entry.RepeatSelectBuilding": "Répéter le bâtiment sélectionné", "Settings.Entry.ResetBoxPositions": "Fenêtres", "Settings.Entry.RivalSound": "Rival son", "Settings.Entry.SelectedMenu": "Position du menu", @@ -1383,11 +1419,11 @@ "Settings.Entry.ShowMapTradeWarning": "Bloqueur de négociation", "Settings.Entry.ShowMarketFilter": "Filtre de marché", "Settings.Entry.ShowNotifications": "Notifications", - "Settings.Entry.ShowOtherGuildActivity": "Joueurs actifs en CbG", "Settings.Entry.ShowOwnPartOnAllGBs": "Calculatrice GM", "Settings.Entry.ShowPlayersMotivation": "Activité PO/MO", "Settings.Entry.ShowPotions": "Potions de bataille", "Settings.Entry.ShowPvPArena": "Arène JcJ - Compte rendu", + "Settings.Entry.ShowReconstructionList": "Liste de taille en mode Reconstruction", "Settings.Entry.ShowRougeUnitWarning": "Voyou Alerte uniquement", "Settings.Entry.ShowScoutingTimes": "Info d'éclaireur", "Settings.Entry.Version": "Version", @@ -1411,6 +1447,9 @@ "Settings.InfoboxEntryCount.Title": "Nb d'infos techniques", "Settings.LoadBeta.Desc": "Uniquement disponible dans l'extension séparée !!!
Il a à télécharger et à ajouter manuellement aux extensions.
Elle ne peut pas être utilisée conjointement avec l'extension Helper habituelle !

Dans la version bêta, les erreurs sont plus susceptibles de se produire que dans la version publiée ! Veuillez nous informer de tout bogue trouvé sur Discord ou Github !
Les temps de chargement de l'extension peuvent être plus longs que d'habitude !
Le jeu doit être rechargé pour changer de mode !", "Settings.LoadBeta.Title": "Charger la version Beta actuelle", + "Settings.LoadBeta2.Button": "Charger la version Beta", + "Settings.LoadBeta2.Desc": "L'extension bêta doit être installée et mise à jour manuellement. Soit cliquez régulièrement sur le bouton ci-dessous pour télécharger la version bêta actuelle, soit utilisez un Git-Manager

Décompressez le zip téléchargé et dans les paramètres de l'extension Chrome, activez le mode développeur pour « charger l'extension décompressée ».

Une seule version du Helper doit être active à tout moment pour éviter les interférences !", + "Settings.LoadBeta2.Title": "Charger la version Beta actuelle", "Settings.MenuContent.Desc": "Quels boutons voulez-vous dans le menu ?
Vert : afficher le bouton. Rouge : masquer le bouton.", "Settings.MenuContent.Title": "Contenu du menu", "Settings.MenuLength.Desc": "Combien d'éléments le menu devrait-il avoir ?
Vide ou \"0\" pour une hauteur automatique.", @@ -1421,6 +1460,8 @@ "Settings.NotificationsPosition.Title": "Emplacement de la notification", "Settings.NotificationsStack.Desc": "Combien de notifications souhaitez-vous voir simultanément ? La valeur par défaut est 4.", "Settings.NotificationsStack.Title": "Notifications multiples", + "Settings.RepeatSelectBuilding.Desc": "! ! ! Attention - Bien que peu probable, l'utilisation de cette option pourrait déclencher la détection du bot INNO et entraîner une courte période de ban  ! ! ! Veuillez nous en informer si cela se produit.

Après avoir placé un bâtiment à partir du menu de construction ou de la barre latérale de reconstruction, le même bâtiment sera automatiquement sélectionné (rues exclues).", + "Settings.RepeatSelectBuilding.Title": "Répéter le dernier bâtiment sélectionné", "Settings.ResetBoxPositions.Button": "Supprimer !", "Settings.ResetBoxPositions.Desc": "Toutes les positions des fenêtres doivent-elles être réinitialisées ? Ceci peut faire réapparaitre des fenêtres en dehors de votre vue.", "Settings.ResetBoxPositions.Title": "Positionnement des fenêtres", @@ -1456,8 +1497,6 @@ "Settings.ShowMarketFilter.Title": "Afficher l'outil de filtrage du marché", "Settings.ShowNotifications.Desc": "FoE Helper utilise des notifications à divers endroits. Vous pouvez les activer ou les désactiver ici.", "Settings.ShowNotifications.Title": "Notifications", - "Settings.ShowOtherGuildActivity.Desc": "Si lors de la visite d'autres guildes, le nombre de batailles d'un joueur a changé, une liste des joueurs actifs s'affiche.", - "Settings.ShowOtherGuildActivity.Title": "Joueurs actifs des autres guildes", "Settings.ShowOwnPartBP.Desc": "Afficher les plans", "Settings.ShowOwnPartMedals.Desc": "Afficher les médailles", "Settings.ShowOwnPartOnAllGBs.Desc": "Modifie la 'Calculatrice GM interne' pour les GM des autres joueurs", @@ -1468,6 +1507,8 @@ "Settings.ShowPotions.Title": "Potions de bataille", "Settings.ShowPvPArena.Desc": "Afficher le compte-rendu de l'arène JcJ, lors de l'ouverture de l'arène JcJ ?", "Settings.ShowPvPArena.Title": "Compte-rendu Arène JcJ", + "Settings.ShowReconstructionList.Desc": "Fournit une liste triable de tous les bâtiments et de leurs tailles en mode reconstruction", + "Settings.ShowReconstructionList.Title": "Afficher la liste des tailles en mode reconstruction", "Settings.ShowRougeUnitWarning.Desc": "Masquer les boutons \"Attaque\" et \"Bataille auto.\" afin d'éviter une défaite s'il ne reste que des voyous après la première vague.", "Settings.ShowRougeUnitWarning.Title": "Alerte voyou Uniquement", "Settings.ShowScoutingTimes.Desc": "Affiche une fenêtre lors de l'ouverture de la carte, indiquant les durées d'exploration des provinces actuellement disponibles et la progression de l'exploration actuelle", diff --git a/js/web/_i18n/ja.json b/js/web/_i18n/ja.json index 019e5d5d1..3572bd09e 100644 --- a/js/web/_i18n/ja.json +++ b/js/web/_i18n/ja.json @@ -180,7 +180,7 @@ "Boxes.Campagne.Resource": "リソースアイテム", "Boxes.Campagne.Reward": "報酬 ", "Boxes.Campagne.Title": "セクターのリソースコスト ", - "Boxes.Castle.AntiqueDealer": "", + "Boxes.Castle.AntiqueDealer": "古物商", "Boxes.Castle.AuctionsWon": "", "Boxes.Castle.Battle": "", "Boxes.Castle.Battles": "", @@ -1093,8 +1093,8 @@ "Boxes.UnitsGex.Won": "", "Boxes.cardGame.Attack": "攻撃", "Boxes.cardGame.Bonus": "ボーナス", - "Boxes.cardGame.WarningCertainDeath": "", - "Boxes.cardGame.WarningPossibleDeath": "", + "Boxes.cardGame.WarningCertainDeath": "このカードをプレイすると負ける!引き直すか、体力回復を買うことを検討しよう!", + "Boxes.cardGame.WarningPossibleDeath": "このカードをプレイすると負けるかもしれない!引き直すか、体力回復を買うことを検討しよう!", "Boxes.doubleFPprevention.Text": "", "Boxes.doubleFPprevention.Title": "", "Boxes.findGB.Title": "", @@ -1365,7 +1365,6 @@ "Settings.Entry.ShowMapTradeWarning": "", "Settings.Entry.ShowMarketFilter": "", "Settings.Entry.ShowNotifications": "", - "Settings.Entry.ShowOtherGuildActivity": "", "Settings.Entry.ShowOwnPartOnAllGBs": "", "Settings.Entry.ShowPlayersMotivation": "", "Settings.Entry.ShowPotions": "", @@ -1438,8 +1437,6 @@ "Settings.ShowMarketFilter.Title": "", "Settings.ShowNotifications.Desc": "", "Settings.ShowNotifications.Title": "", - "Settings.ShowOtherGuildActivity.Desc": "", - "Settings.ShowOtherGuildActivity.Title": "", "Settings.ShowOwnPartBP.Desc": "", "Settings.ShowOwnPartMedals.Desc": "", "Settings.ShowOwnPartOnAllGBs.Desc": "", diff --git a/js/web/_i18n/nl.json b/js/web/_i18n/nl.json index 5a58097d0..4d1762363 100644 --- a/js/web/_i18n/nl.json +++ b/js/web/_i18n/nl.json @@ -1379,7 +1379,6 @@ "Settings.Entry.ShowMapTradeWarning": "Onderhandel blokkade", "Settings.Entry.ShowMarketFilter": "Markt filter", "Settings.Entry.ShowNotifications": "Meldingen", - "Settings.Entry.ShowOtherGuildActivity": "GSP Actieve Spelers", "Settings.Entry.ShowOwnPartOnAllGBs": "GG Calculator", "Settings.Entry.ShowPlayersMotivation": "Motivatie Activiteit", "Settings.Entry.ShowPotions": "Gevechtsdranken", @@ -1452,8 +1451,6 @@ "Settings.ShowMarketFilter.Title": "Toon de Markt filter tool", "Settings.ShowNotifications.Desc": "De assistent gebruikt op verschillende plekken meldingen. Je kan dit hier aan- of uitschakelen.", "Settings.ShowNotifications.Title": "Meldingen", - "Settings.ShowOtherGuildActivity.Desc": "Als, bij het bezoeken van andere gildes, het aantal gevechten van willekeurige spelers is veranderd dan verschijnt er een lijst van actieve spelers.", - "Settings.ShowOtherGuildActivity.Title": "Overige Gildes Actieve spelers", "Settings.ShowOwnPartBP.Desc": "Toon Blauwdrukken", "Settings.ShowOwnPartMedals.Desc": "Toon Medailles", "Settings.ShowOwnPartOnAllGBs.Desc": "Ververst de 'GG rekenmachine' voor GG's van andere spelers", diff --git a/js/web/_i18n/ru.json b/js/web/_i18n/ru.json index 25d394668..003121ba2 100644 --- a/js/web/_i18n/ru.json +++ b/js/web/_i18n/ru.json @@ -253,8 +253,11 @@ "Boxes.CityMap.street": "Дороги", "Boxes.CityMap.tower": "Башни", "Boxes.Citymap.Efficiency": "Эффективность", + "Boxes.CloseBox.ButtonSize": "Размер кнопки", "Boxes.CloseBox.CloseAllButton": "Кнопка Закрыть все", "Boxes.CloseBox.HideAllButton": "Кнопка Спрятать все", + "Boxes.CloseBox.Horizontal": "горизонтальный", + "Boxes.CloseBox.Vertical": "вертикальный", "Boxes.CombatCalculator.Efficiency": "Эффективность", "Boxes.CombatCalculator.EfficiencyTT": "Оценка эффективности в соответствии с настройками в модуле эффективности", "Boxes.CombatCalculator.Name": "Название здания", @@ -848,6 +851,13 @@ "Boxes.Technologies.NoTechs": "Вы достигли конца эпохи", "Boxes.Technologies.Resource": "Ресурс", "Boxes.Technologies.Title": "Стоимость исследования", + "Boxes.Tooltip.Building.canMotivate": "может быть мотивирован", + "Boxes.Tooltip.Building.canPolish": "может быть мотивирован", + "Boxes.Tooltip.Building.produces": "Производит", + "Boxes.Tooltip.Building.provides": "Обеспечивает", + "Boxes.Tooltip.Building.road": "требует дороги", + "Boxes.Tooltip.Building.size+time": "Размер и время строительства", + "Boxes.Tooltip.Building.traits": "Особенность", "Boxes.Treasury.Action": "Сообщение", "Boxes.Treasury.Amount": "Количество", "Boxes.Treasury.DateTime": "Дата/Время", diff --git a/js/web/_i18n/sr_Latn.json b/js/web/_i18n/sr_Latn.json index 613470cb9..988c684d9 100644 --- a/js/web/_i18n/sr_Latn.json +++ b/js/web/_i18n/sr_Latn.json @@ -1378,7 +1378,6 @@ "Settings.Entry.ShowMapTradeWarning": "Blokator pregovaranja ", "Settings.Entry.ShowMarketFilter": "Filter tržišta ", "Settings.Entry.ShowNotifications": "Upozorenja ", - "Settings.Entry.ShowOtherGuildActivity": "GBG Aktivni igraci ", "Settings.Entry.ShowOwnPartOnAllGBs": "GB Kalkulator ", "Settings.Entry.ShowPlayersMotivation": "Aktivnosti motivacije ", "Settings.Entry.ShowPotions": "Borbene napitke ", @@ -1451,8 +1450,6 @@ "Settings.ShowMarketFilter.Title": "Prikaži alat za filtriranje tržišta ", "Settings.ShowNotifications.Desc": "Pomoćnik koristi obaveštenja na raznim mestima. Ovde možete ovo uključiti ili isključiti.", "Settings.ShowNotifications.Title": "Upozorenja ", - "Settings.ShowOtherGuildActivity.Desc": "Ako se prilikom posete drugim gildovima promeni broj bitaka bilo kog igrača, prikazuje se lista aktivnih igrača.", - "Settings.ShowOtherGuildActivity.Title": "Aktivni igraci drugih gilda ", "Settings.ShowOwnPartBP.Desc": "Prikaži planove ", "Settings.ShowOwnPartMedals.Desc": "Prikaži medalje ", "Settings.ShowOwnPartOnAllGBs.Desc": "Ažurira 'GB kalkulator' za GB drugih igraca ", diff --git a/js/web/_main/js/_main.js b/js/web/_main/js/_main.js index 029641500..2df438ad6 100644 --- a/js/web/_main/js/_main.js +++ b/js/web/_main/js/_main.js @@ -243,6 +243,7 @@ GetFights = () =>{ GuildMemberStat.checkForDB(ExtPlayerID); GexStat.checkForDB(ExtPlayerID); GuildFights.checkForDB(ExtPlayerID); + QiProgress.checkForDB(ExtPlayerID); // which tab is active in StartUp Object? let vals = { @@ -416,7 +417,7 @@ GetFights = () =>{ MainParser.UpdateActiveMap('gex'); }); - // gg is entered + // GBG is entered FoEproxy.addHandler('GuildBattlegroundService', 'getBattleground', (data, postData) => { MainParser.UpdateActiveMap('gg'); }); @@ -813,13 +814,13 @@ GetFights = () =>{ GameTimeOffset = data.responseData.time * 1000 - new Date().getTime(); GameTime = data.responseData.time; if (MainMenuLoaded) return; + MainMenuLoaded = true; await StartUpDone; let MenuSetting = localStorage.getItem('SelectedMenu'); - MenuSetting = MenuSetting || 'BottomBar'; - MainParser.SelectedMenu = MenuSetting; - _menu.CallSelectedMenu(MenuSetting); + MainParser.SelectedMenu = MenuSetting || 'RightBar'; + _menu.CallSelectedMenu(MainParser.SelectedMenu); MainParser.setLanguage(); @@ -915,7 +916,7 @@ let MainParser = { savedFight: null, DebugMode: false, Language: 'en', - SelectedMenu: 'BottomBar', + SelectedMenu: 'RightBar', i18n: null, BonusService: null, Boosts: {}, @@ -1483,7 +1484,7 @@ let MainParser = { MainParser.Allies.names = Object.assign({}, ...rawStats.map(a=>({[a.id]:a.name}))) }, getProd:(CityMapId) => { - let M= MainParser.Allies + let M = MainParser.Allies if (!M.buildingList?.[CityMapId]) return null let prod={} Object.values(M.buildingList[CityMapId]).forEach(id=> { @@ -1501,13 +1502,32 @@ let MainParser = { }, tooltip:(id)=>{ if (!MainParser.Allies.buildingList?.[id]) return "" - return `data-original-title ="` + Object.keys(MainParser.Allies.buildingList[id]).map(a=> { - ally=MainParser.Allies.allyList[a] - return `` + MainParser.Allies.names[ally.allyId] + " (" + i18n("Boxes.Productions.AllyRarity."+ally.rarity.value) + " - " + i18n("General.Level") + " " + ally.level + ")" - }).join("
") + `"` + return `data-allies ="${JSON.stringify(Object.values(MainParser.Allies.buildingList[id]))}"` }, setRarities:(raw)=>{ MainParser.Allies.rarities=Object.assign({}, ...raw.map(r=>({[r.id.value]:r}))) + }, + getAllieData:(id)=>{ + ally={ + id:id, + allyId:MainParser.Allies.allyList[id].allyId, + rarity:MainParser.Allies.allyList[id].rarity.value, + level:MainParser.Allies.allyList[id].level, + name:MainParser.Allies.names[MainParser.Allies.allyList[id].allyId], + } + let prod = {} + let stat = MainParser.Allies.stats[ally.allyId][ally.rarity][ally.level] + let type = "military" + for (let s of Object.keys(stat)) { // ToDo: check stats to change type whenever implemented + if (s=="level") continue + if (prod[s]) + prod[s].concat(stat[s]) + else + prod[s]=stat[s] + } + ally.prod = prod + ally.type = type + return ally } }, diff --git a/js/web/_menu/js/_menu.js b/js/web/_menu/js/_menu.js index b65f47e4b..382606779 100644 --- a/js/web/_menu/js/_menu.js +++ b/js/web/_menu/js/_menu.js @@ -15,7 +15,7 @@ let _menu = { isBottom: false, - selectedMenu: 'BottomBar', + selectedMenu: 'RightBar', MenuScrollTop: 0, MenuScrollLeft: 0, SlideParts: 0, @@ -77,20 +77,20 @@ let _menu = { * @param selMenu * @constructor */ - CallSelectedMenu: (selMenu = 'BottomBar') => { + CallSelectedMenu: (selMenu = 'RightBar') => { window.onresize = (function(event){ if (event.target == window) _menu.OverflowCheck() }) - if (selMenu === 'BottomBar') { - _menu.selectedMenu = 'BottomBar'; - _menu_bottom.BuildOverlayMenu(); - } - else if (selMenu === 'RightBar') { + if (selMenu === 'RightBar') { _menu.selectedMenu = 'RightBar'; _menu_right.BuildOverlayMenu(); } + else if (selMenu === 'BottomBar') { + _menu.selectedMenu = 'BottomBar'; + _menu_bottom.BuildOverlayMenu(); + } else if (selMenu === 'Box') { _menu.selectedMenu = 'Box'; _menu_box.BuildBoxMenu(); diff --git a/js/web/_menu_bottom/js/_menu_bottom.js b/js/web/_menu_bottom/js/_menu_bottom.js index 28dce550a..33e8423c5 100644 --- a/js/web/_menu_bottom/js/_menu_bottom.js +++ b/js/web/_menu_bottom/js/_menu_bottom.js @@ -13,7 +13,7 @@ let _menu_bottom = { - btnSize: 45, + btnSize: 42, /** * Create the div holders and put them to the DOM diff --git a/js/web/_menu_right/js/_menu_right.js b/js/web/_menu_right/js/_menu_right.js index cf0f87c51..02236af33 100644 --- a/js/web/_menu_right/js/_menu_right.js +++ b/js/web/_menu_right/js/_menu_right.js @@ -23,7 +23,6 @@ let _menu_right = { hudWrapper.append(hudInner); - let btnUp = $('').addClass('hud-btn-up'), btnDown = $('').addClass('hud-btn-down hud-btn-down-active'); @@ -31,18 +30,15 @@ let _menu_right = { hud.append(hudWrapper) hud.append(btnDown); - // Wenn sie die Fenstergröße verändert, neu berechnen window.onresize = function (event) { if (event.target == window) _menu_right.SetMenuHeight(true); }; $('body').append(hud).ready(function () { - // Buttons einfügen _menu.ListLinks(_menu_right.InsertMenuItem); _menu_right.CheckButtons(); - // korrekten Platz für das Menu ermitteln _menu_right.SetMenuHeight(); window.dispatchEvent(new CustomEvent('foe-helper#menu_loaded')); @@ -106,14 +102,14 @@ let _menu_right = { _menu.CallSelectedMenu('Box') } - // hat der Spieler eine Länge vorgebeben? + // has a length been set manually? let MenuLength = localStorage.getItem('MenuLength'); if (MenuLength !== null && MenuLength < _menu.HudCount) { _menu.HudCount = _menu.HudLength = parseInt(MenuLength); } - _menu.HudHeight = (_menu.HudCount * 49); + _menu.HudHeight = (_menu.HudCount * 47); _menu.SlideParts = Math.ceil(MenuItemCount / _menu.HudCount); $('#foe-helper-hud').height(_menu.HudHeight + 2); @@ -128,7 +124,6 @@ let _menu_right = { let activeIdx = 0; - $('.hud-btn').click(function () { activeIdx = $(this).index('.hud-btn'); }); diff --git a/js/web/battle-assist/css/battle-assist.css b/js/web/battle-assist/css/battle-assist.css index 085f75199..99cae5832 100644 --- a/js/web/battle-assist/css/battle-assist.css +++ b/js/web/battle-assist/css/battle-assist.css @@ -119,6 +119,10 @@ margin-left: 5px; } +#battleAssistAAConfig { + height: 60vh; +} + #battleAssistAAConfig .BattleWave { display: flex; flex-direction: column; diff --git a/js/web/battle-assist/js/battle-assist.js b/js/web/battle-assist/js/battle-assist.js index 587fbe227..a0327c711 100644 --- a/js/web/battle-assist/js/battle-assist.js +++ b/js/web/battle-assist/js/battle-assist.js @@ -18,8 +18,8 @@ FoEproxy.addHandler('BattlefieldService', 'all', (data, postData) => { return; } - HTML.CloseOpenBox('battleAssistNextEraDialog'); - HTML.CloseOpenBox('battleAssistRogueDialog'); + $('#battleAssistNextEraDialog').remove(); + $('#battleAssistRogueDialog').remove(); const state = data.responseData.__class__ === 'BattleRealm' ? data.responseData.state : data.responseData; diff --git a/js/web/bettermusic/css/bettermusic.css b/js/web/bettermusic/css/bettermusic.css index 137bca8f0..d7a3c085b 100644 --- a/js/web/bettermusic/css/bettermusic.css +++ b/js/web/bettermusic/css/bettermusic.css @@ -41,11 +41,6 @@ width:auto; } -#musicSettingsScenesX tr th { - position: sticky; - top: 0px; -} - #betterMusicDialog .flex > div { min-width: 40%; padding: 0.5em; diff --git a/js/web/bettermusic/js/bettermusic.js b/js/web/bettermusic/js/bettermusic.js index 67ab30dd9..bfe095928 100644 --- a/js/web/bettermusic/js/bettermusic.js +++ b/js/web/bettermusic/js/bettermusic.js @@ -327,12 +327,12 @@ let betterMusic = { htmltext += ``; htmltext += ``; - htmltext += ``; + htmltext += `
${i18n('Boxes.BetterMusic.Scenes')}
${i18n('Boxes.BetterMusic.TitleName')}
>`; for (let scene in betterMusic.Scenes) { htmltext += ``; } - htmltext += ``; + htmltext += ``; for (let title in betterMusic.PossibleTracks) { htmltext += ``; diff --git a/js/web/bluegalaxy/css/bluegalaxy.css b/js/web/bluegalaxy/css/bluegalaxy.css index 7fce396ac..5095723e9 100644 --- a/js/web/bluegalaxy/css/bluegalaxy.css +++ b/js/web/bluegalaxy/css/bluegalaxy.css @@ -78,12 +78,6 @@ display: block; } -#bluegalaxy table th { - position: sticky; - top: 0px; - z-index: 1; -} - #bluegalaxy table th[data-type] { cursor: pointer } diff --git a/js/web/bluegalaxy/js/bluegalaxy.js b/js/web/bluegalaxy/js/bluegalaxy.js index e5de7cf36..a11c3253e 100644 --- a/js/web/bluegalaxy/js/bluegalaxy.js +++ b/js/web/bluegalaxy/js/bluegalaxy.js @@ -249,7 +249,7 @@ let BlueGalaxy = { table.push('
${i18n('Boxes.BetterMusic.Scenes')}
${i18n('Boxes.BetterMusic.TitleName')}${betterMusic.Scenes[scene].Name}
${betterMusic.PossibleTracks[title].Name}
'); - table.push('' + + table.push('' + '' + ''+ '' + diff --git a/js/web/boost_inventory/css/boost_inventory.css b/js/web/boost_inventory/css/boost_inventory.css index cc4218774..633beec67 100644 --- a/js/web/boost_inventory/css/boost_inventory.css +++ b/js/web/boost_inventory/css/boost_inventory.css @@ -23,10 +23,7 @@ margin-left: 9px; } #BoostInventory thead { - position: sticky; - top: 0px; font-weight: 600; - z-index: 100; } #BoostInventory td:nth-child(3), #BoostInventory th:nth-child(3) { text-align: center; diff --git a/js/web/boost_inventory/js/boost_inventory.js b/js/web/boost_inventory/js/boost_inventory.js index 643868612..f0523c345 100644 --- a/js/web/boost_inventory/js/boost_inventory.js +++ b/js/web/boost_inventory/js/boost_inventory.js @@ -94,7 +94,7 @@ let BoostInventory = { c.push(`
' + i18n('Boxes.BlueGalaxy.Building') + '
`) - c.push('') + c.push('') c.push('') c.push('') diff --git a/js/web/castle/css/castle.css b/js/web/castle/css/castle.css index 1ad941ddc..dc23dae49 100644 --- a/js/web/castle/css/castle.css +++ b/js/web/castle/css/castle.css @@ -41,8 +41,6 @@ #Castle .castle_wrapper .foe-table tr th { border-top: 1px solid var(--border-table-top); border-bottom: 1px solid var(--border-table-bottom); - position: sticky; - top: 0; } #Castle .castle_wrapper .icon { diff --git a/js/web/castle/js/castle.js b/js/web/castle/js/castle.js index 0fb46a2a8..e91dcf0e0 100644 --- a/js/web/castle/js/castle.js +++ b/js/web/castle/js/castle.js @@ -894,7 +894,7 @@ let Castle = { if (!Castle.Settings.showGroupNames) { - h.push(``); + h.push(``); } h.push(``); diff --git a/js/web/citymap/css/citymap.css b/js/web/citymap/css/citymap.css index fc82aef5d..4680038d3 100755 --- a/js/web/citymap/css/citymap.css +++ b/js/web/citymap/css/citymap.css @@ -292,15 +292,6 @@ background-color: var(--background-color-special); border-color: var(--border-color-special); }*/ -#grid-outer span.noStreet.highlight { - background-color: var(--background-color-noStreet); - border-color: var(--border-color-noStreet); - animation-name: color; - animation-duration: 1s; - animation-iteration-count: infinite; - animation-direction: alternate; - animation-timing-function: ease-in-out; -} /*#grid-outer span.chain { background-color: var(--background-color-chain); border-color: var(--border-color-chain); @@ -349,18 +340,36 @@ } /* mark old buildings*/ -span.older-1.diagonal { +#grid-outer span.older-1.diagonal { background-image: repeating-linear-gradient(45deg, transparent, transparent 5px, rgb(128, 152, 93) 2px, rgb(128, 152, 93) 7px) } -span.older-2.diagonal { +#grid-outer span.older-2.diagonal { background-image: repeating-linear-gradient(317deg, transparent, transparent 5px, rgb(133, 95, 14) 2px, rgb(133, 95, 14) 7px) } -span.older-3.diagonal { +#grid-outer span.older-3.diagonal { background-image: repeating-linear-gradient(45deg, transparent, transparent 5px, rgb(165, 74, 62) 2px, rgb(165, 74, 62) 7px); } -span.to-old.diagonal { +#grid-outer span.to-old.diagonal { background-image: repeating-linear-gradient(202deg, transparent, transparent 5px, rgb(171, 26, 13) 2px, rgb(171, 26, 13) 7px) } +#grid-outer span.noStreet.highlight { + background-color: var(--background-color-noStreet); + border-color: var(--border-color-noStreet); + animation-name: color; + animation-duration: 1s; + animation-iteration-count: infinite; + animation-direction: alternate; + animation-timing-function: ease-in-out; +} +#grid-outer span.ascendable.highlight2 { + background-color: var(--background-color-ascendable); + border-color: var(--border-color-ascendable); +} +#grid-outer span.decayed.highlight3 { + background-image: linear-gradient(45deg, transparent 50%, var(--background-color-ascendable) 50%); + background-color: var(--background-color-decayed); + border-color: var(--border-color-decayed); +} [data-view="skew"] .older-1.diagonal { background-image: repeating-linear-gradient(15deg, transparent, transparent 5px, rgb(128, 152, 93) 2px, rgb(128, 152, 93) 7px) diff --git a/js/web/citymap/js/citymap.js b/js/web/citymap/js/citymap.js index d4cb8a454..26caba898 100644 --- a/js/web/citymap/js/citymap.js +++ b/js/web/citymap/js/citymap.js @@ -35,6 +35,16 @@ let CityMap = { QIStats: null, QIAreas: [], + AscendingBuildings: new Promise((resolve) => { + let timer = () => { + if (!MainParser.BuildingUpgrades) { + setTimeout(timer,500) + } else { + resolve (Object.assign({},...Object.values(MainParser.BuildingUpgrades).filter(x => x.upgradeItem.id.includes("ascended")).map(x=>x.upgradeSteps[0].buildingIds.map((Id,i)=>({[Id]:x.upgradeSteps[1].buildingIds[i]}))).flat())) + } + } + timer() + }), /** * @param event @@ -122,7 +132,6 @@ let CityMap = { /** * Stadtkarte vorbereiten => Menü rein - * * @param Title */ PrepareBox: (Title)=> { @@ -187,6 +196,8 @@ let CityMap = { if(ActiveMap === 'main'){ $('#highlight-old-buildings')[0].checked=false; $('#show-nostreet-buildings')[0].checked=false; + $('#show-ascendable-buildings')[0].checked=false; + $('#show-decayed-buildings')[0].checked=false; } $('#grid-outer').attr('data-unit', unit); @@ -220,12 +231,22 @@ let CityMap = { mapfilters.append( $('
${i18n('Boxes.Castle.Type')}${HTML.i18nTooltip(i18n('Boxes.Castle.Progress'))}${HTML.i18nTooltip(i18n('Boxes.Castle.CastlePoints'))}
${i18n('Boxes.Castle.Type')}${HTML.i18nTooltip(i18n('Boxes.Castle.Progress'))}${HTML.i18nTooltip(i18n('Boxes.Castle.CastlePoints'))}
'); - t.push(''); + t.push(''); t.push(''); t.push(''); @@ -182,6 +182,8 @@ let CompareFriendsThreads = { } t.push(''); + t.push(''); + t.push(''); let PlayerList = Object.values(PlayerDict).filter(obj => (obj['IsFriend'] === true)); @@ -205,9 +207,10 @@ let CompareFriendsThreads = { } if(CompareFriendsThreads.Threads[x]['participants'].findIndex(p => p.playerId === Player.PlayerID) === -1){ - t.push(``); - } else { - t.push(``); + t.push(``); + } + else { + t.push(``); } } @@ -217,6 +220,7 @@ let CompareFriendsThreads = { t.push(''); t.push('
 
'); + t.push(''); $('#friendsCompareBoxBody').html(t.join('')); } diff --git a/js/web/customTooltip/css/customTooltip.css b/js/web/customTooltip/css/customTooltip.css index e50503ec3..c2091ff15 100644 --- a/js/web/customTooltip/css/customTooltip.css +++ b/js/web/customTooltip/css/customTooltip.css @@ -1,15 +1,58 @@ +#TooltipContainer.window-box { + border: 2px solid #2a2c27; + background: #343832; + color: #f7f4ed; +} + +#TooltipContainer.window-box .foe-table tr td { + border-top: 1px solid #fff3; + border-bottom: 1px solid #0004; +} + +#TooltipContainer.window-box .foe-table th { + background: #0004; + box-shadow: inset 0 0 0 2000px var(--black-50), 0 1px 0 0 #fff3, 0 2px 0 0 #0004; +} + +.buildingTT table.foe-table tbody tr:nth-child(odd), .buildingTT .foe-table li:nth-child(odd) { + background-color: #fff1; + backdrop-filter: none; +} + +.buildingTT { + width: min-content; +} + +.buildingTT h2 { + padding: 0.2em 0.5em; + color: #f2ede1; + background-color: #0002; +} + +.buildingTT .imgContainer { + min-width:150px; + max-width:150px; + vertical-align:top +} + +.buildingTT .imgContainer img { + display: block; + margin: 0 auto; + max-width: 100%; +} + .HXBuilding th { border-bottom: unset; } .HXBuilding td { width: 300px; display: flex; - white-space-collapse: preserve; - text-wrap-mode: nowrap; + white-space: nowrap; } .HXBuilding img { padding-right: 3px; max-width: 24px; + max-height: 25px; } .HXBuilding .multiCol { flex-wrap: wrap; @@ -84,9 +127,12 @@ .HXBuilding .limited img{ align-self: flex-start; } +.HXBuilding .allyName { + display: flex; + flex-wrap: wrap; + column-gap: 0.5em; +} - - @keyframes bounce { 0% { transform: translateX(0%) } 30% { transform: translateX(0%) } diff --git a/js/web/customTooltip/js/customTooltip.js b/js/web/customTooltip/js/customTooltip.js index 0507829b3..50aa031b2 100644 --- a/js/web/customTooltip/js/customTooltip.js +++ b/js/web/customTooltip/js/customTooltip.js @@ -87,18 +87,22 @@ let Tooltips = { Tooltips.Container.style.top = (event.y+10) + "px"; Tooltips.checkposition() }, - buildingTT: (e)=>{ - let id=e?.currentTarget?.dataset?.meta_id||MainParser?.CityMapData[e?.currentTarget?.dataset?.id]?.cityentity_id - let era = Technologies.InnoEraNames[MainParser?.CityMapData[e?.currentTarget?.dataset?.id]?.level] + buildingTT: async (e)=>{ + let id = e?.currentTarget?.dataset?.meta_id||MainParser?.CityMapData[e?.currentTarget?.dataset?.id]?.cityentity_id if (!id) return - - let meta=MainParser.CityEntities[id] - let h = `
`+ + let era = e?.currentTarget?.dataset?.era||Technologies.InnoEraNames[MainParser?.CityMapData[e?.currentTarget?.dataset?.id]?.level] + let meta = MainParser.CityEntities[id] + let allies = JSON.parse(e?.currentTarget?.dataset?.allies||"null") + let eff = Math.round(e?.currentTarget?.previousElementSibling?.dataset?.number) + if (!eff && era) eff=Math.round(100 * Productions.rateBuildings([id],true,era)?.[0]?.score||0) + + let h = `
+

${meta.name} ${eff ? `(${i18n("Boxes.Kits.Efficiency")}: ${eff})`:''}

+
`+ - `
${meta.name}
`+ - `
+ `+ `
`; - h += Tooltips.BuildingData(meta,era); + h += await Tooltips.BuildingData(meta,era,allies); h += "
" setTimeout(()=>{ $(".handleOverflow").each((index,e)=>{ @@ -111,7 +115,11 @@ let Tooltips = { },100) return h }, - BuildingData:(meta,onlyEra=null)=>{ + BuildingData:async (meta,onlyEra=null,allies=null)=>{ + if (onlyEra && Array.isArray(onlyEra)) { + allies = [].concat(onlyEra) + onlyEra = null + } let numberWithCommas = (x) => { if (!x) return "" return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); @@ -122,7 +130,7 @@ let Tooltips = { let span = (x,withHighlight=false) => `${numberWithCommas(x)}`; let longSpan = (x) => `
${x}
` - let range = (x,y,withHighlight=false) => span(x,withHighlight) + (x!=y ?` - `+ span(y,withHighlight):``); + let range = (x,y,withHighlight=false) => span(x,withHighlight) + (x!=y ?` - `+ span(y,withHighlight):``); let formatTime = (x) => { let min=Math.floor(x/60) let sec = x-min*60 @@ -136,16 +144,6 @@ let Tooltips = { if (day>0) time = day + (hour+sec+min>0 ? (hour>9?hour:"0"+hour) + (sec+min>0 ? ":"+(min>9?min:"0"+min)+(sec>0?":"+(sec>9?sec:"0"+sec):""):""):"")+"d" return time } - let src=(x)=>{ - if (!x) return "" - x=x.replace(/(.*?)_[0-9]+/gm,"$1"); - let link = srcLinks.get(`/shared/icons/${x}.png`,true,true); - if (link.includes("antiquedealer_flag")) link = srcLinks.get(`/shared/icons/reward_icons/reward_icon_${x}.png`,true,true); - if (link.includes("antiquedealer_flag")) link = srcLinks.get(`/city/buildings/${x.replace(/(\D*?)_(.*)/,"$1_SS_$2")}.png`,true); - return link - } - - let icons = (x) => ``;// ${y ? `style="background: url(${src(y)}); background-size: contain; background-repeat: no-repeat;"`:""}>`; let genericEval = (rew) => { let [x1,amount,name] = rew.name.match(/^([+\-]?\d*)x? (.*)$/)||["",1,rew.name] @@ -153,19 +151,19 @@ let Tooltips = { let icon = "" let fragment = "" if (rew.iconAssetName=="icon_fragment") { - icon = icons(rew.assembledReward?.iconAssetName||rew.assembledReward?.subType) + icon = srcLinks.icons(rew.assembledReward?.iconAssetName||rew.assembledReward?.subType) name = name.replace(/Fragments? of/,"").replace(/.*?'(.*?)'.*/,"$1") - fragment = icons("icon_tooltip_fragment") + fragment = srcLinks.icons("icon_tooltip_fragment") } else if (rew.type=="unit") { name = /nextera/i.test(rew.id)? "of next era" : "" - icon = icons(rew.subType=="rogue"?"rogue":( + icon = srcLinks.icons(rew.subType=="rogue"?"rogue":( rew.subType.includes("champion")?"chivalry": Unit.Types.filter(x=>x.unitTypeId==rew.subType)[0].unitClass )) } else - icon = icons(rew.iconAssetName) + icon = srcLinks.icons(rew.iconAssetName) return {icon:icon,amount:amount,name:name,fragment:fragment} } @@ -205,16 +203,16 @@ let Tooltips = { traits = "", motMod = "", polMod = "", - ifMot = `${icons("when_motivated")}` + ifMot = `${srcLinks.icons("when_motivated")}` if (levels?.AllAge?.socialInteraction?.interactionType) { if (levels?.AllAge?.socialInteraction?.interactionType == "motivate") { - motMod = `${icons("reward_x2")+i18n("Boxes.Tooltip.Building.when")+icons("when_motivated")}` - traits+=`${icons("when_motivated")}${i18n("Boxes.Tooltip.Building.canPolish")}` + motMod = `${srcLinks.icons("reward_x2")+i18n("Boxes.Tooltip.Building.when")+srcLinks.icons("when_motivated")}` + traits+=`${srcLinks.icons("when_motivated")}${i18n("Boxes.Tooltip.Building.canPolish")}` } else if (levels?.AllAge?.socialInteraction?.interactionType == "polish") { - polMod = `${icons("reward_x2")+"when"+icons("when_motivated")}` - traits+=`${icons("when_motivated")}${i18n("Boxes.Tooltip.Building.canMotivate")}` + polMod = `${srcLinks.icons("reward_x2")+"when"+srcLinks.icons("when_motivated")}` + traits+=`${srcLinks.icons("when_motivated")}${i18n("Boxes.Tooltip.Building.canMotivate")}` } } for (let a of meta.abilities||[]) { @@ -230,40 +228,59 @@ let Tooltips = { traits += `◄ ${i18n("Boxes.Tooltip.Building.addInhabitant")} (${capFirsts(a.action.animationId)})` } - for (r of levels.AllAge?.ally?.rooms || []) { - ally += ''+icons("historical_allies_slot_tooltip_icon_empty") + capFirsts(r.allyType) + (r.rarity?.value ? (" ("+capFirsts(r.rarity?.value)+")"):"")+`` + for (let r of levels.AllAge?.ally?.rooms || []) { + let allydata = null + for (a of allies||[]) { + allydata = MainParser.Allies.getAllieData(a) + if (r.allyType == allydata.type && (!r.rarity?.value || r.rarity?.value == allydata.rarity)) break + allydata = null + } + ally += `${srcLinks.icons("historical_allies_slot_tooltip_icon_" + (allydata ? "full" :"empty"))}
${capFirsts(r.allyType) + (r.rarity?.value ? (" ("+i18n("Boxes.Productions.AllyRarity."+r.rarity?.value)+")"):"")}` + if (allydata) { + ally+=`
${MainParser.Allies.names[allydata.allyId]}(${i18n("Boxes.Productions.AllyRarity."+allydata.rarity)} - ${i18n("General.Level")} ${allydata.level})
` + //productions: + for (b of allydata.prod.boosts||[]) { + ally+=`${srcLinks.icons(b.type+feature[b.targetedFeature])} ${b.value + percent(b.type)}` + } + + } + ally+=`
` } if (levels.AllAge.eraRequirement?.era && era =="") { - era = icons("era") + " " + i18n("Eras."+(Technologies.Eras[levels.AllAge.eraRequirement?.era])) + era = srcLinks.icons("era") + " " + i18n("Eras."+(Technologies.Eras[levels.AllAge.eraRequirement?.era])) } if (era != "") out += "" + era + "" if (levels?.AllAge?.limited?.config?.expireTime) { - out += `${icons("limited_building_downgrade") + MainParser.CityEntities[levels.AllAge.limited.config.targetCityEntityId].name} (${i18n("Boxes.Tooltip.Building.after")} ${formatTime(levels.AllAge.limited.config.expireTime)})` + out += `${srcLinks.icons("limited_building_downgrade") + MainParser.CityEntities[levels.AllAge.limited.config.targetCityEntityId].name} (${i18n("Boxes.Tooltip.Building.after")} ${formatTime(levels.AllAge.limited.config.expireTime)})` + } + + if (await CityMap.canAscend(meta.id)) { + out += `${srcLinks.icons("limited_building_upgrade") + MainParser.CityEntities[(await CityMap.AscendingBuildings)[meta.id]].name}` } let provides="" for ([resource,amount] of Object.entries(levels.AllAge?.staticResources?.resources?.resources||{})) { - provides+=`${icons(resource)+" "+ span(amount,true)}` + provides+=`${srcLinks.icons(resource)+" "+ span(amount,true)}` } for ([resource,amount] of Object.entries(levels?.[minEra]?.staticResources?.resources?.resources||{})) { - provides+=`${icons(resource)+" "+ range(amount,levels[maxEra]?.staticResources?.resources?.resources?.[resource],true)}` + provides+=`${srcLinks.icons(resource)+" "+ range(amount,levels[maxEra]?.staticResources?.resources?.resources?.[resource],true)}` } if (levels.AllAge?.happiness?.provided) { - provides+=`${icons("happiness")+" "+ span(levels.AllAge?.happiness?.provided,true) + polMod}` + provides+=`${srcLinks.icons("happiness")+" "+ span(levels.AllAge?.happiness?.provided,true) + polMod}` } if (levels?.[minEra]?.happiness?.provided && levels[maxEra]?.happiness?.provided) { - provides+=`${icons("happiness") + " " + range(levels?.[minEra]?.happiness?.provided,levels[maxEra]?.happiness?.provided,true) + polMod}` + provides+=`${srcLinks.icons("happiness") + " " + range(levels?.[minEra]?.happiness?.provided,levels[maxEra]?.happiness?.provided,true) + polMod}` } for (let [i,b] of Object.entries(levels.AllAge?.boosts?.boosts||[])){ - provides+=`${icons(b.type+feature[b.targetedFeature]) + " " + span(b.value) + percent(b.type)}` + provides+=`${srcLinks.icons(b.type+feature[b.targetedFeature]) + " " + span(b.value) + percent(b.type)}` } for (let [i,b] of Object.entries(levels?.[minEra]?.boosts?.boosts||[])){ - provides+=`${icons(b.type+feature[b.targetedFeature]) + " " + range(b.value,levels[maxEra]?.boosts?.boosts[i].value) + percent(b.type)}` + provides+=`${srcLinks.icons(b.type+feature[b.targetedFeature]) + " " + range(b.value,levels[maxEra]?.boosts?.boosts[i].value) + percent(b.type)}` } let prods="" @@ -275,13 +292,13 @@ let Tooltips = { if (product.type == "resources") { for (let [res,amount] of Object.entries(product.playerResources?.resources||{})) { if (amount !=0) - prods+=`${icons(goodsList.includes(res)?"goods":res) + span(amount)+t + ((["supplies","coins","money"].includes(res) && !product.onlyWhenMotivated) ? motMod : "") + (product.onlyWhenMotivated?ifMot:"")}` + prods+=`${srcLinks.icons(goodsList.includes(res)?"goods":res) + span(amount)+t + ((["supplies","coins","money"].includes(res) && !product.onlyWhenMotivated) ? motMod : "") + (product.onlyWhenMotivated?ifMot:"")}` } } if (product.type == "guildResources") { for (let [res,amount] of Object.entries(product.guildResources?.resources||{})) { if (amount !=0) - prods+=`${icons(goodsList.includes(res)?"treasury_goods":res) + span(amount)+t + (product.onlyWhenMotivated?ifMot:"")}` + prods+=`${srcLinks.icons(goodsList.includes(res)?"treasury_goods":res) + span(amount)+t + (product.onlyWhenMotivated?ifMot:"")}` } } if (product.type == "unit") { @@ -290,7 +307,7 @@ let Tooltips = { product.unitTypeId.includes("champion")?"chivalry": Unit.Types.filter(x=>x.unitTypeId==product.unitTypeId)[0].unitClass )) - prods+=`${icons(iconId) + span(product.amount)+t + (product.onlyWhenMotivated?ifMot:"")}` + prods+=`${srcLinks.icons(iconId) + span(product.amount)+t + (product.onlyWhenMotivated?ifMot:"")}` } } if (product.type == "genericReward") { @@ -304,13 +321,13 @@ let Tooltips = { if (random.product.type == "resources") { for (let [res,amount] of Object.entries(random.product.playerResources?.resources||{})) { if (amount !=0) - prods+=icons(goodsList.includes(res)?"goods":res) + span(amount) + prods+=srcLinks.icons(goodsList.includes(res)?"goods":res) + span(amount) } } if (random.product.type == "guildResources") { for (let [res,amount] of Object.entries(random.product.guildResources?.resources||{})) { if (amount !=0) - prods+=icons(goodsList.includes(res)?"treasury_goods":res) + span(amount) + prods+=srcLinks.icons(goodsList.includes(res)?"treasury_goods":res) + span(amount) } } if (random.product.type == "unit") { @@ -319,7 +336,7 @@ let Tooltips = { random.product.unitTypeId.includes("champion")?"chivalry": Unit.Types.filter(x=>x.unitTypeId==random.product.unitTypeId)[0].unitClass )) - prods+=icons(iconId) + span(random.product.amount) + prods+=srcLinks.icons(iconId) + span(random.product.amount) } } if (random.product.type == "genericReward") { @@ -338,13 +355,13 @@ let Tooltips = { if (product.type == "resources") { for (let [res,amount] of Object.entries(product.playerResources?.resources||{})) { if (amount !=0) - prods+=`${icons(goodsList.includes(res)?"goods":res) + range(amount,levels?.[maxEra]?.production?.options?.[oIndex]?.products?.[pIndex]?.playerResources?.resources?.[res])+t + ((["supplies","coins","money"].includes(res) && !product.onlyWhenMotivated) ? motMod : "") + (product.onlyWhenMotivated?ifMot:"")}` + prods+=`${srcLinks.icons(goodsList.includes(res)?"goods":res) + range(amount,levels?.[maxEra]?.production?.options?.[oIndex]?.products?.[pIndex]?.playerResources?.resources?.[res])+t + ((["supplies","coins","money"].includes(res) && !product.onlyWhenMotivated) ? motMod : "") + (product.onlyWhenMotivated?ifMot:"")}` } } if (product.type == "guildResources") { for (let [res,amount] of Object.entries(product.guildResources?.resources||{})) { if (amount !=0) - prods+=`${icons(goodsList.includes(res)?"treasury_goods":res) + range(amount,levels?.[maxEra]?.production?.options?.[oIndex]?.products?.[pIndex]?.guildResources?.resources?.[res])+t + (product.onlyWhenMotivated?ifMot:"")}` + prods+=`${srcLinks.icons(goodsList.includes(res)?"treasury_goods":res) + range(amount,levels?.[maxEra]?.production?.options?.[oIndex]?.products?.[pIndex]?.guildResources?.resources?.[res])+t + (product.onlyWhenMotivated?ifMot:"")}` } } if (product.type == "unit") { @@ -353,7 +370,7 @@ let Tooltips = { product.unitTypeId.includes("champion")?"chivalry": Unit.Types.filter(x=>x.unitTypeId==product.unitTypeId)[0].unitClass )) - prods+=`${icons(iconId) + range(product.amount,levels?.[maxEra]?.production?.options?.[oIndex]?.products?.[pIndex].amount)+t + (product.onlyWhenMotivated?ifMot:"")}` + prods+=`${srcLinks.icons(iconId) + range(product.amount,levels?.[maxEra]?.production?.options?.[oIndex]?.products?.[pIndex].amount)+t + (product.onlyWhenMotivated?ifMot:"")}` } } if (product.type == "genericReward") { @@ -373,13 +390,13 @@ let Tooltips = { if (random.product.type == "resources") { for (let [res,amount] of Object.entries(random.product.playerResources?.resources||{})) { if (amount !=0) - prods+=icons(goodsList.includes(res)?"goods":res) + range(amount,levels?.[maxEra]?.production?.options?.[oIndex]?.products?.[pIndex]?.products?.[rIndex]?.product?.playerResources?.resources?.[res]) + prods+=srcLinks.icons(goodsList.includes(res)?"goods":res) + range(amount,levels?.[maxEra]?.production?.options?.[oIndex]?.products?.[pIndex]?.products?.[rIndex]?.product?.playerResources?.resources?.[res]) } } if (random.product.type == "guildResources") { for (let [res,amount] of Object.entries(random.product.guildResources?.resources||{})) { if (amount !=0) - prods+=icons(goodsList.includes(res)?"treasury_goods":res) + range(amount,levels?.[maxEra]?.production?.options?.[oIndex]?.products?.[pIndex]?.products?.[rIndex]?.product?.guildResources?.resources?.[res]) + prods+=srcLinks.icons(goodsList.includes(res)?"treasury_goods":res) + range(amount,levels?.[maxEra]?.production?.options?.[oIndex]?.products?.[pIndex]?.products?.[rIndex]?.product?.guildResources?.resources?.[res]) } } if (random.product.type == "unit") { @@ -388,7 +405,7 @@ let Tooltips = { random.product.unitTypeId.includes("champion")?"chivalry": Unit.Types.filter(x=>x.unitTypeId==random.product.unitTypeId)[0].unitClass )) - prods+=icons(iconId) + range(random.product.amount,levels?.[maxEra]?.production?.options?.[oIndex]?.products?.[pIndex?.products?.[rIndex]?.product].amount) + prods+=srcLinks.icons(iconId) + range(random.product.amount,levels?.[maxEra]?.production?.options?.[oIndex]?.products?.[pIndex?.products?.[rIndex]?.product].amount) } } if (random.product.type == "genericReward") { @@ -410,7 +427,7 @@ let Tooltips = { let costs = "" for ([resource,amount] of Object.entries(levels.AllAge?.buildResourcesRequirement?.cost?.resources||{})) { - if (amount>0) costs += `
${icons(resource) + " " + span(amount)}
` + if (amount>0) costs += `
${srcLinks.icons(resource) + " " + span(amount)}
` } if (ally!="") out+=`${i18n("Boxes.Tooltip.Building.allyRooms")}`+ally @@ -419,12 +436,13 @@ let Tooltips = { if (costs !="") out+=`${i18n("Boxes.Tooltip.Building.costs")}`+costs+`` out+=`${i18n("Boxes.Tooltip.Building.size+time")}` - out+=`
${icons("size")} ${levels.AllAge.placement.size.y+"x"+levels.AllAge.placement.size.x}
${icons("icon_time")}${formatTime(levels.AllAge.constructionTime.time)}
` + out+=`
${srcLinks.icons("size")} ${levels.AllAge.placement.size.y+"x"+levels.AllAge.placement.size.x}
` + out+=levels.AllAge?.constructionTime?.time ? `
${srcLinks.icons("icon_time")}${formatTime(levels.AllAge.constructionTime.time)}
`:`` if (levels.AllAge.streetConnectionRequirement?.requiredLevel) { if (levels.AllAge.streetConnectionRequirement?.requiredLevel == 2) - out+=`
${icons("street_required")} ${i18n("Boxes.Tooltip.Building.road2")}
` + out+=`
${srcLinks.icons("street_required")} ${i18n("Boxes.Tooltip.Building.road2")}
` else if (levels.AllAge.streetConnectionRequirement?.requiredLevel == 1) - out+=`
${icons("road_required")} ${i18n("Boxes.Tooltip.Building.road")}
` + out+=`
${srcLinks.icons("road_required")} ${i18n("Boxes.Tooltip.Building.road")}
` } out+=`` @@ -447,7 +465,7 @@ let Tooltips = { info = "", boosts="", abilityList={}, - ifMot = `${icons("when_motivated")}` + ifMot = `${srcLinks.icons("when_motivated")}` for (let a of meta.abilities||[]) { if (a.__class__=="BuildingPlacementAbility") { @@ -459,30 +477,30 @@ let Tooltips = { } } if (a.__class__=="ChainStartAbility") { - set =icons(a.chainId) + MainParser.BuildingChains[a.chainId].name + '' + a.description + set =srcLinks.icons(a.chainId) + MainParser.BuildingChains[a.chainId].name + '' + a.description } if (a.__class__=="ChainLinkAbility") { - set =icons(a.chainId) + MainParser.BuildingChains[a.chainId].name + set =srcLinks.icons(a.chainId) + MainParser.BuildingChains[a.chainId].name } if (a.__class__=="BuildingSetAbility") { - set =icons(a.setId) + MainParser.BuildingSets[a.setId].name + set =srcLinks.icons(a.setId) + MainParser.BuildingSets[a.setId].name } if (a.__class__=="PolishableAbility") { - traits+=`${icons("when_motivated")}can be polished` - polMod = `${icons("reward_x2")+i18n("Boxes.Tooltip.Building.when")+icons("when_motivated")}` + traits+=`${srcLinks.icons("when_motivated")}can be polished` + polMod = `${srcLinks.icons("reward_x2")+i18n("Boxes.Tooltip.Building.when")+srcLinks.icons("when_motivated")}` } if (a.__class__ == "MotivatableAbility") { - traits+=`${icons("when_motivated")}can be motivated` - motMod = `${icons("reward_x2")+i18n("Boxes.Tooltip.Building.when")+icons("when_motivated")}` + traits+=`${srcLinks.icons("when_motivated")}can be motivated` + motMod = `${srcLinks.icons("reward_x2")+i18n("Boxes.Tooltip.Building.when")+srcLinks.icons("when_motivated")}` } if (a.__class__ == "AddCoinsToSupplyProductionWhenMotivatedAbility") { - motMod = `${"+"+icons("money")+i18n("Boxes.Tooltip.Building.when")+icons("when_motivated")}` + motMod = `${"+"+srcLinks.icons("money")+i18n("Boxes.Tooltip.Building.when")+srcLinks.icons("when_motivated")}` } if (a.__class__=="NotPlunderableAbility") { - traits+=``+icons("eventwindow_plunder_repel") + i18n("Boxes.Tooltip.Building.noPlunder")+`` + traits+=``+srcLinks.icons("eventwindow_plunder_repel") + i18n("Boxes.Tooltip.Building.noPlunder")+`` } if (a.__class__=="AffectedByLifeSupportAbility") { - traits+=``+icons("life_support") + i18n("Boxes.Tooltip.Building.lifeSupport")+`` + traits+=``+srcLinks.icons("life_support") + i18n("Boxes.Tooltip.Building.lifeSupport")+`` } if (a.__class__=="DisplayInfoTextAbility") { info += a.text @@ -492,10 +510,10 @@ let Tooltips = { if (a.boostHints){ for (let b of a.boostHints||[]){ if (b.boostHintEraMap?.AllAge) { - boosts+=`${icons(b.boostHintEraMap.AllAge.type+feature[b.boostHintEraMap.AllAge.targetedFeature]) + " " + span(b.boostHintEraMap.AllAge.value) + percent(b.boostHintEraMap.AllAge.type)}` + boosts+=`${srcLinks.icons(b.boostHintEraMap.AllAge.type+feature[b.boostHintEraMap.AllAge.targetedFeature]) + " " + span(b.boostHintEraMap.AllAge.value) + percent(b.boostHintEraMap.AllAge.type)}` } if (b.boostHintEraMap?.[minEra] && b.boostHintEraMap?.[maxEra]) { - boosts+=`${icons(b.boostHintEraMap?.[minEra].type+feature[b.boostHintEraMap?.[minEra].targetedFeature]) + " " + range(b.boostHintEraMap?.[minEra].value,b.boostHintEraMap[maxEra].value) + percent(b.boostHintEraMap?.[minEra].type)}` + boosts+=`${srcLinks.icons(b.boostHintEraMap?.[minEra].type+feature[b.boostHintEraMap?.[minEra].targetedFeature]) + " " + range(b.boostHintEraMap?.[minEra].value,b.boostHintEraMap[maxEra].value) + percent(b.boostHintEraMap?.[minEra].type)}` } } } @@ -504,7 +522,7 @@ let Tooltips = { } if (meta?.requirements?.min_era && meta?.requirements?.min_era != "MultiAge" && era =="") { - era = `${icons("era") + " " + i18n("Eras."+(Technologies.Eras[meta.requirements.min_era]))}` + era = `${srcLinks.icons("era") + " " + i18n("Eras."+(Technologies.Eras[meta.requirements.min_era]))}` } if (era != "") out += "" + era + "" @@ -513,31 +531,31 @@ let Tooltips = { let provides="" if (meta.provided_population || meta.required_population) { - provides+=`${icons("population")+" "+ span((meta.provided_population||0) - (meta.required_population||0),true)}` + provides+=`${srcLinks.icons("population")+" "+ span((meta.provided_population||0) - (meta.required_population||0),true)}` } else if ((levels?.[minEra]?.provided_population && levels?.[maxEra]?.provided_population)||(levels?.[minEra]?.required_population && levels?.[maxEra]?.required_population)) { - provides+=`${icons("population") + " " + range((levels?.[minEra].provided_population||0)-(levels?.[minEra].required_population||0),(levels?.[maxEra].provided_population||0)-(levels?.[maxEra].required_population||0),true)}` + provides+=`${srcLinks.icons("population") + " " + range((levels?.[minEra].provided_population||0)-(levels?.[minEra].required_population||0),(levels?.[maxEra].provided_population||0)-(levels?.[maxEra].required_population||0),true)}` } if (meta.provided_happiness) { - provides+=`${icons("happiness")+" "+ span((meta.provided_happiness||0),true)}` + provides+=`${srcLinks.icons("happiness")+" "+ span((meta.provided_happiness||0),true)}` } else if ((levels?.[minEra]?.provided_happiness && levels?.[maxEra]?.provided_happiness)) { - provides+=`${icons("happiness") + " " + range(levels?.[minEra].provided_happiness||0,levels?.[maxEra].provided_happiness||0,true) + polMod}` + provides+=`${srcLinks.icons("happiness") + " " + range(levels?.[minEra].provided_happiness||0,levels?.[maxEra].provided_happiness||0,true) + polMod}` } if (levels?.[minEra]?.ranking_points && levels?.[maxEra]?.ranking_points) { - provides+=`${icons("rank") + " " + range(levels?.[minEra].ranking_points,levels?.[maxEra].ranking_points)}` + provides+=`${srcLinks.icons("rank") + " " + range(levels?.[minEra].ranking_points,levels?.[maxEra].ranking_points)}` } for ([resource,amount] of Object.entries(meta?.static_resources?.resources||{})) { - if (amount>0) provides+=`${icons(resource)+" "+ span(amount)}` + if (amount>0) provides+=`${srcLinks.icons(resource)+" "+ span(amount)}` } let prods="" if (meta.available_products) { if (levels?.[minEra]?.produced_money && levels?.[maxEra]?.produced_money) { - prods+=`${icons("money") + range(levels?.[minEra].produced_money,levels?.[maxEra].produced_money) + motMod}` + prods+=`${srcLinks.icons("money") + range(levels?.[minEra].produced_money,levels?.[maxEra].produced_money) + motMod}` } if (levels?.[minEra]?.clan_power && levels?.[maxEra]?.clan_power) { - prods+=`${icons("clan_power") + range(levels?.[minEra].clan_power,levels?.[maxEra].clan_power) + motMod}` + prods+=`${srcLinks.icons("clan_power") + range(levels?.[minEra].clan_power,levels?.[maxEra].clan_power) + motMod}` } for (let p of meta.available_products) { @@ -547,49 +565,49 @@ let Tooltips = { if (goodsList.includes(res)) res="goods" if (amount !=0) - prods+=`${icons(res) + span(amount)+t + motMod}` + prods+=`${srcLinks.icons(res) + span(amount)+t + motMod}` else - prods+=`${icons(res) + range(levels?.[minEra].production_values[p.production_option-1].value,levels?.[maxEra].production_values[p.production_option-1].value)+t + motMod}` + prods+=`${srcLinks.icons(res) + range(levels?.[minEra].production_values[p.production_option-1].value,levels?.[maxEra].production_values[p.production_option-1].value)+t + motMod}` } if (p.unit_class) { - prods+=`${icons(p.unit_class) + p.name}` + prods+=`${srcLinks.icons(p.unit_class) + p.name}` } } for (let a of abilityList.AddResourcesAbility||[]) { for (let [res,amount] of Object.entries(a.additionalResources?.[minEra]?.resources||{})) { if (amount !=0) - prods+=`${icons(goodsList.includes(res)?"goods":res) + range(a.additionalResources?.[minEra].resources[res],a.additionalResources[maxEra].resources[res])}` + prods+=`${srcLinks.icons(goodsList.includes(res)?"goods":res) + range(a.additionalResources?.[minEra].resources[res],a.additionalResources[maxEra].resources[res])}` } for (let [res,amount] of Object.entries(a.additionalResources?.AllAge?.resources||{})) { if (amount !=0) - prods+=`${icons(goodsList.includes(res)?"goods":res) + span(amount)}` + prods+=`${srcLinks.icons(goodsList.includes(res)?"goods":res) + span(amount)}` } } for (let a of abilityList.AddResourcesToGuildTreasuryAbility||[]) { for (let [res,amount] of Object.entries(a.additionalResources?.[minEra]?.resources||{})) { if (amount !=0) - prods+=`${icons(goodsList.includes(res)?"treasury_goods":res) + range(a.additionalResources?.[minEra].resources[res],a.additionalResources[maxEra].resources[res])}` + prods+=`${srcLinks.icons(goodsList.includes(res)?"treasury_goods":res) + range(a.additionalResources?.[minEra].resources[res],a.additionalResources[maxEra].resources[res])}` } for (let [res,amount] of Object.entries(a.additionalResources?.AllAge?.resources||{})) { if (amount !=0) - prods+=`${icons(goodsList.includes(res)?"treasury_goods":res) + span(amount)}` + prods+=`${srcLinks.icons(goodsList.includes(res)?"treasury_goods":res) + span(amount)}` } } for (let a of abilityList.AddResourcesWhenMotivatedAbility||[]) { for (let [res,amount] of Object.entries(a.additionalResources?.[minEra]?.resources||{})) { if (amount !=0) - prods+=`${icons(goodsList.includes(res)?"goods":res) + range(a.additionalResources?.[minEra].resources[res],a.additionalResources[maxEra].resources[res])+ifMot}` + prods+=`${srcLinks.icons(goodsList.includes(res)?"goods":res) + range(a.additionalResources?.[minEra].resources[res],a.additionalResources[maxEra].resources[res])+ifMot}` } for (let [res,amount] of Object.entries(a.additionalResources?.AllAge?.resources||{})) { if (amount !=0) - prods+=`${icons(goodsList.includes(res)?"goods":res) + span(amount)+ifMot}` + prods+=`${srcLinks.icons(goodsList.includes(res)?"goods":res) + span(amount)+ifMot}` } } for (let a of abilityList.RandomUnitOfAgeWhenMotivatedAbility||[]) { - prods+=`${icons("military")+(a.amount||1)+ifMot}` + prods+=`${srcLinks.icons("military")+(a.amount||1)+ifMot}` } for (let a of abilityList.RandomBlueprintWhenMotivatedAbility||[]) { - prods+=`${icons("blueprint")+(a.amount||1)+ifMot}` + prods+=`${srcLinks.icons("blueprint")+(a.amount||1)+ifMot}` } for (let a of abilityList.RandomChestRewardAbility||[]) { prods+=`` @@ -603,7 +621,7 @@ let Tooltips = { amountBA = rew.reward?.possible_rewards?.[0]?.reward?.amount||amountBA amountMax = a.rewards?.[maxEra]?.possible_rewards?.[id]?.reward?.possible_rewards?.[0]?.reward?.amount||amountMax } - prods+=icons(asset) + range(amountBA,amountMax) + prods+=srcLinks.icons(asset) + range(amountBA,amountMax) prods+=`${rew.drop_chance}%` } @@ -614,23 +632,23 @@ let Tooltips = { for (let a of abilityList.BonusOnSetAdjacencyAbility||[]) { for (let b of a.bonuses) { if (Object.values(b.boost).length>0) { - boosts+=`` } else { - prods+=`` } @@ -644,12 +662,12 @@ let Tooltips = { boosts+='" first=false } - boosts+=`` @@ -658,14 +676,14 @@ let Tooltips = { prods+='" first=false } - prods+=`` } @@ -675,7 +693,7 @@ let Tooltips = { let costs = "" for ([resource,amount] of Object.entries(meta?.requirements?.cost?.resources||{})) { - if (amount>0) costs += `
${icons(resource) + " " + span(amount)}
` + if (amount>0) costs += `
${srcLinks.icons(resource) + " " + span(amount)}
` } provides=provides+boosts if (provides!="") out+=``+provides @@ -683,11 +701,12 @@ let Tooltips = { if (costs !="") out+=`` out+=`` - out+=`` diff --git a/js/web/eventchests/css/eventchests.css b/js/web/eventchests/css/eventchests.css index f7575b9f6..11e08fca0 100644 --- a/js/web/eventchests/css/eventchests.css +++ b/js/web/eventchests/css/eventchests.css @@ -45,6 +45,18 @@ float: right; } +#eventpresentsBody td.icon { + position: relative; +} + +#eventpresentsBody .fragment img { + position: absolute; + bottom: 3px; + right: 0; + height: 18px; + width: auto; +} + #eventpresentsBody tr.destroyed td { text-decoration: line-through; background-color: var(--black-65); diff --git a/js/web/eventchests/js/eventchests.js b/js/web/eventchests/js/eventchests.js index cb9633810..9fccd4bc3 100644 --- a/js/web/eventchests/js/eventchests.js +++ b/js/web/eventchests/js/eventchests.js @@ -135,20 +135,28 @@ let EventPresents = { for (let present of EventPresents.Presents) { let icon; + let frag = "" if (present.status.value !== "used") { h.push(''); if(present.reward.type === "unit") { - if(Unit.CoordsRaw) { - icon = ``; - } - + asset = present.reward.subType + } else if (present.reward.type=="building") { + asset = MainParser.CityEntities[present.reward.subType].asset_id } else { - icon = ``; + asset = present.reward.iconAssetName } - - h.push(''); + if (asset == "icon_fragment") { + if (present.reward.assembledReward.type=="building") + asset = MainParser.CityEntities[present.reward.assembledReward.subType].asset_id + else + asset = present.reward.assembledReward.iconAssetName + frag = ''+srcLinks.icons("icon_tooltip_fragment")+''; + } + icon = ``; + + h.push(''); h.push(''); h.push(''); } diff --git a/js/web/eventhandler/js/eventhandler.js b/js/web/eventhandler/js/eventhandler.js index 6ff59f5be..d4fb19e11 100644 --- a/js/web/eventhandler/js/eventhandler.js +++ b/js/web/eventhandler/js/eventhandler.js @@ -259,11 +259,7 @@ let EventHandler = { // get the correct 24h time if(match['groups']['half']) { - if(match['groups']['half'] === 'am' && h === 12) - { - h = 12; - } - else if(match['groups']['half'] === 'am' && h !== 12) + if(match['groups']['half'] === 'am' && h < 12) { h += 12; } @@ -280,7 +276,10 @@ let EventHandler = { case 'yesterday': refDate = moment().subtract(1, 'day'); break; - + case 'date': + moment.locale(OldLocale); + refDate = moment(match['groups']['d'],moment.defaultFormat) + break; default: refDate = moment().day(capitalize(day)); if (refDate.isAfter(MainParser.getCurrentDate())) refDate = refDate.subtract(7 * 86400000); //Date is in the future => subtract 1 week @@ -676,6 +675,7 @@ let EventHandler = { friday : /Freitag um (?[012]?\d):(?[0-5]?\d)/g, saturday : /Samstag um (?[012]?\d):(?[0-5]?\d)/g, sunday : /Sonntag um (?[012]?\d):(?[0-5]?\d)/g, + date : /am (?.*?) um (?[012]?\d):(?[0-5]?\d)/g, }, en: { today : /today at (?[012]?\d):(?[0-5]?\d) (?(a|p)m)/g, @@ -687,6 +687,7 @@ let EventHandler = { friday : /Friday at (?[012]?\d):(?[0-5]?\d) (?(a|p)m)/g, saturday : /Saturday at (?[012]?\d):(?[0-5]?\d) (?(a|p)m)/g, sunday : /Sunday at (?[012]?\d):(?[0-5]?\d) (?(a|p)m)/g, + date : /on (?.*?) at (?[012]?\d):(?[0-5]?\d) (?(a|p)m)/g, }, pt: { today : /hoje às (?[012]?\d):(?[0-5]?\d)( horas)?/g, @@ -720,6 +721,7 @@ let EventHandler = { friday : /Vendredi à (?[012]?\d):(?[0-5]?\d)/g, saturday : /Samedi à (?[012]?\d):(?[0-5]?\d)/g, sunday : /Dimanche à (?[012]?\d):(?[0-5]?\d)/g, + date : /le (?.*?) à (?[012]?\d):(?[0-5]?\d)/g, }, it: { today : /oggi alle (?[012]?\d):(?[0-5]?\d)/g, diff --git a/js/web/findGB/css/findGB.css b/js/web/findGB/css/findGB.css index 21425b138..2c432c97d 100644 --- a/js/web/findGB/css/findGB.css +++ b/js/web/findGB/css/findGB.css @@ -21,11 +21,6 @@ overflow: auto; } -#foundGB th { - position:sticky; - top:0px; -} - #foundGB .progress { background: linear-gradient(90deg, var(--background-table-success) 0, var(--background-table-success) var(--p), transparent var(--p), transparent) } diff --git a/js/web/findGB/js/findGB.js b/js/web/findGB/js/findGB.js index e9f12284f..76713a0a3 100644 --- a/js/web/findGB/js/findGB.js +++ b/js/web/findGB/js/findGB.js @@ -53,7 +53,7 @@ let findGB = { } html = ``; - html += `
${b.level + "x" + icons(a.setId)} ► ` + boosts+=`
${b.level + "x" + srcLinks.icons(a.setId)} ► ` if (b.boost.AllAge) { - boosts+=icons(b.boost.AllAge.type+feature[b.boost.AllAge.targetedFeature]) + " " + span(b.boost.AllAge.value) + percent(b.boost.AllAge.type) + boosts+=srcLinks.icons(b.boost.AllAge.type+feature[b.boost.AllAge.targetedFeature]) + " " + span(b.boost.AllAge.value) + percent(b.boost.AllAge.type) } if (b.boost?.[minEra] && b.boost[maxEra]) { - boosts+=icons(b.boost?.[minEra].type+feature[b.boost?.[minEra].targetedFeature]) + " " + range(b.boost?.[minEra].value,b.boost[maxEra].value) + percent(b.boost?.[minEra].type) + boosts+=srcLinks.icons(b.boost?.[minEra].type+feature[b.boost?.[minEra].targetedFeature]) + " " + range(b.boost?.[minEra].value,b.boost[maxEra].value) + percent(b.boost?.[minEra].type) } boosts+=`
${b.level + "x" + icons(a.setId)} ► ` + prods+=`
${b.level + "x" + srcLinks.icons(a.setId)} ► ` if (b.revenue?.AllAge) { let [res,amount] = Object.entries(b.revenue?.AllAge?.resources)[0] - prods+=icons(goodsList.includes(res)?"goods":res) + span(amount) + prods+=srcLinks.icons(goodsList.includes(res)?"goods":res) + span(amount) } if (b.revenue?.[minEra] && b.revenue?.[maxEra]) { let [res,amount] = Object.entries(b.revenue?.[minEra]?.resources)[0] - prods+=icons(goodsList.includes(res)?"goods":res) + range(amount,b.revenue?.[maxEra].resources[res]) + prods+=srcLinks.icons(goodsList.includes(res)?"goods":res) + range(amount,b.revenue?.[maxEra].resources[res]) } prods+=`
' + a.description+"
${b.level + "x" + icons(a.chainId)} ► ` + boosts+=`
${b.level + "x" + srcLinks.icons(a.chainId)} ► ` if (b.boost.AllAge) { - boosts+=icons(b.boost.AllAge.type+feature[b.boost.AllAge.targetedFeature]) + " " + span(b.boost.AllAge.value) + percent(b.boost.AllAge.type) + boosts+=srcLinks.icons(b.boost.AllAge.type+feature[b.boost.AllAge.targetedFeature]) + " " + span(b.boost.AllAge.value) + percent(b.boost.AllAge.type) } if (b.boost?.[minEra] && b.boost[maxEra]) { - boosts+=icons(b.boost?.[minEra].type+feature[b.boost?.[minEra].targetedFeature]) + " " + range(b.boost?.[minEra].value,b.boost[maxEra].value) + percent(b.boost?.[minEra].type) + boosts+=srcLinks.icons(b.boost?.[minEra].type+feature[b.boost?.[minEra].targetedFeature]) + " " + range(b.boost?.[minEra].value,b.boost[maxEra].value) + percent(b.boost?.[minEra].type) } boosts+=`
' + a.description+"
${b.level + "x" + icons(a.chainId)} ► ` + prods+=`
${b.level + "x" + srcLinks.icons(a.chainId)} ► ` if (b.revenue?.AllAge) { let [res,amount] = Object.entries(b.revenue?.AllAge?.resources)[0] - prods+=icons(goodsList.includes(res)?"goods":res) + span(amount) + prods+=srcLinks.icons(goodsList.includes(res)?"goods":res) + span(amount) } if (b.revenue?.[minEra] && b.revenue?.[maxEra]) { let [res,amount] = Object.entries(b.revenue?.[minEra]?.resources)[0] - prods+=icons(goodsList.includes(res)?"goods":res) + range(amount,b.revenue?.[maxEra].resources[res]) + prods+=srcLinks.icons(goodsList.includes(res)?"goods":res) + range(amount,b.revenue?.[maxEra].resources[res]) } prods+=`
${i18n("Boxes.Tooltip.Building.provides")}
${i18n("Boxes.Tooltip.Building.costs")}
`+costs+`
${i18n("Boxes.Tooltip.Building.size+time")}
${icons("size")} ${meta.width+"x"+meta.length}
${icons("icon_time")}${formatTime(meta.construction_time)}
` + out+=`
${srcLinks.icons("size")} ${meta.width+"x"+meta.length}
` + out+=meta.construction_time?`
${srcLinks.icons("icon_time")}${formatTime(meta.construction_time)}
`:`` if (meta.requirements?.street_connection_level == 2) - out+=`
${icons("street_required")} ${i18n("Boxes.Tooltip.Building.road2")}
` + out+=`
${srcLinks.icons("street_required")} ${i18n("Boxes.Tooltip.Building.road2")}
` else if (meta.requirements?.street_connection_level == 1) - out+=`
${icons("road_required")} ${i18n("Boxes.Tooltip.Building.road")}
` + out+=`
${srcLinks.icons("road_required")} ${i18n("Boxes.Tooltip.Building.road")}
` out+=`
'+ (icon.search("antiquedealer_flag") === -1 ? icon : '') + ''+ (icon.search("antiquedealer_flag") === -1 ? icon : '') + frag + '' + present.reward.name + (present.status.value === "visible" ? '' : '') +'
`; + html += `
`; html += ``; html += ``; html += `
`; - html += `` + html += `
${i18n("General.Player")}${i18n("General.GB")}${i18n("General.Level")}
` for (i of findGB.found) { html += findGB.row(i) diff --git a/js/web/fp-collector/css/fp-collector.css b/js/web/fp-collector/css/fp-collector.css index 187bbcef4..734d5c47e 100644 --- a/js/web/fp-collector/css/fp-collector.css +++ b/js/web/fp-collector/css/fp-collector.css @@ -27,9 +27,6 @@ justify-content: space-between; align-items: center; padding: 2px 5px; - position: sticky; - top: 0; - z-index: 1; } #fp-collectorBody .btn-tight { diff --git a/js/web/fp-collector/js/fp-collector.js b/js/web/fp-collector/js/fp-collector.js index 25f92f358..aefc624aa 100644 --- a/js/web/fp-collector/js/fp-collector.js +++ b/js/web/fp-collector/js/fp-collector.js @@ -387,7 +387,7 @@ let FPCollector = { } $('#fp-collectorBody').append( - `
+ `
${i18n('Boxes.FPCollector.Total')} ${i18n('Boxes.FPCollector.FP')}
`, diff --git a/js/web/gbgbuildings/js/gbgbuildings.js b/js/web/gbgbuildings/js/gbgbuildings.js index 840cc5819..77100da8d 100644 --- a/js/web/gbgbuildings/js/gbgbuildings.js +++ b/js/web/gbgbuildings/js/gbgbuildings.js @@ -56,7 +56,7 @@ FoEproxy.addHandler('ClanService', 'getTreasury', (data, postData) => { let GBGBuildings = { oldGBG:true, treasury:{}, - block:{ // get from GBG building meta-data: Object.assign({},...x.map(b=>({id:b.id,value:Number(b.description.replace(/.*? (\d+)% chance to not increase.*/gm,"$1"))})).filter(b=>b.value).sort((a,b)=>a.value-b.value).map(b=>({[b.id]:b.value}))) + block:{ // get from GBG building meta-data: Object.assign({"free":0},...x.map(b=>({id:b.id,value:Number(b.description.replace(/.*? (\d+)% chance to not increase.*/gm,"$1"))})).filter(b=>b.value).sort((a,b)=>a.value-b.value).map(b=>({[b.id]:b.value}))) "free":0, "watchtower": 8, "guild_command_post_improvised": 20, @@ -218,8 +218,8 @@ let GBGBuildings = { let lastCost = 10000; let src = (b) => { let link="" - if (GBGBuildings.oldGBG) link = srcLinks.get("/guild_battlegrounds/hud/guild_battlegrounds_sector_buildings_"+b+".png",true,true) - if (!GBGBuildings.oldGBG || link.includes("antiquedealer_flag")) link = srcLinks.get("/guild_battlegrounds/hud/guild_battlegrounds_sector_buildings_"+b+"_gbg2024.png",true) + if (!GBGBuildings.oldGBG) link = srcLinks.get("/guild_battlegrounds/hud/guild_battlegrounds_sector_buildings_"+b+"_gbg2024.png",true,true) + if (GBGBuildings.oldGBG || link.includes("antiquedealer_flag")) link = srcLinks.get("/guild_battlegrounds/hud/guild_battlegrounds_sector_buildings_"+b+".png",true) return link } for (let s of sets) { diff --git a/js/web/gexstat/css/gexstat.css b/js/web/gexstat/css/gexstat.css index dc9c3de98..a32a370be 100644 --- a/js/web/gexstat/css/gexstat.css +++ b/js/web/gexstat/css/gexstat.css @@ -174,12 +174,6 @@ width: 50px; } -#GexStatBody table thead.sticky th { - position: sticky; - top: 0; - z-index: 1; -} - #GexStat table tbody td.progress { border-left: 1px solid var(--border-table-top); border-right: 1px solid var(--border-table-top); diff --git a/js/web/gexstat/js/gexstat.js b/js/web/gexstat/js/gexstat.js index 60d9913d4..0f5fbb34a 100644 --- a/js/web/gexstat/js/gexstat.js +++ b/js/web/gexstat/js/gexstat.js @@ -1034,7 +1034,14 @@ FoEproxy.addHandler('GuildExpeditionService', 'getOverview', (data, postData) => FoEproxy.addHandler('GuildExpeditionNotificationService', 'GuildExpeditionStateNotification', (data, postData) => { if (data.responseData) GExAttempts.updateState(data.responseData) }); - +FoEproxy.addHandler('GuildExpeditionService', 'getState', (data, postData) => { + for (let x of data.responseData) { + if (!x.currentEntityId) continue; + GExAttempts.state.GEprogress = x.currentEntityId; + localStorage.setItem('GEx.state',JSON.stringify(GExAttempts.state)) + GExAttempts.refreshGUI() + } +}); let GExAttempts = { count:0, next:null, @@ -1046,6 +1053,7 @@ let GExAttempts = { }, deactivationTimer:null, activationTimer:null, + last:null, refreshGUI:()=>{ //hidenumber when GE completed, not running or out of attempts @@ -1090,10 +1098,15 @@ let GExAttempts = { setNext:(time)=>{ let timer=3600000 - if (time) + if (time) { timer = (time-GameTime+3600)*1000 - else - GExAttempts.setCount(Math.min(GExAttempts.count + 1,8)) + GExAttempts.last = time + } else { + let amount = Math.floor((moment().unix() - GExAttempts.last + 100)/3600) + GExAttempts.setCount(Math.min(GExAttempts.count + amount,8)) + GExAttempts.last += 3600*amount + timer = (GExAttempts.last - moment().unix() + 3600)*1000 + } if (GExAttempts.next) clearTimeout(GExAttempts.next) diff --git a/js/web/greatbuildings/css/greatbuildings.css b/js/web/greatbuildings/css/greatbuildings.css index 253f79d26..4240ff802 100644 --- a/js/web/greatbuildings/css/greatbuildings.css +++ b/js/web/greatbuildings/css/greatbuildings.css @@ -43,10 +43,7 @@ } #greatbuildings #greatbuildingsBody table th { - position: sticky; - top: 0; cursor: pointer; - z-index: 1; font-size: 85%; } diff --git a/js/web/greatbuildings/js/greatbuildings.js b/js/web/greatbuildings/js/greatbuildings.js index 4c6db89a5..2e3757224 100644 --- a/js/web/greatbuildings/js/greatbuildings.js +++ b/js/web/greatbuildings/js/greatbuildings.js @@ -36,7 +36,7 @@ let GreatBuildings = 20: [10, 15, 30, 40, 60, 70, 90, 105, 120, 135, 155, 170, 190, 210, 225, 245, 265, 285, 305, 325, 340, 360, 380, 405, 425, 445, 465, 485, 505, 530, 550, 570, 595, 615, 635, 660, 680, 705, 725, 750, 770, 795, 820, 840, 865, 890, 910, 935, 960, 980, 1005, 1030, 1055, 1080, 1100, 1125, 1150, 1175, 1200, 1225, 1250, 1275, 1300, 1325, 1350, 1375, 1400, 1425, 1450, 1475, 1500, 1525, 1550, 1575, 1600, 1630, 1655, 1680, 1705, 1730, 1760, 1785, 1810, 1835, 1865, 1890, 1915, 1945, 1970, 1995, 2025, 2050, 2075, 2105, 2130, 2160, 2185, 2210, 2240, 2265, 2295, 2320, 2350, 2375, 2405, 2430, 2460, 2485, 2515, 2540, 2570, 2600, 2625, 2655, 2680, 2710, 2740, 2765, 2795, 2825, 2850, 2880, 2910, 2935, 2965, 2995, 3025, 3050, 3080, 3110, 3135, 3165, 3195], 21: [10, 15, 30, 45, 60, 75, 90, 105, 125, 140, 160, 180, 195, 215, 235, 255, 275, 295, 315, 335, 355, 375, 395, 415, 440, 460, 480, 500, 525, 545, 570, 590, 615, 635, 660, 680, 705, 730, 750, 775, 800, 820, 845, 870, 895, 920, 940, 965, 990, 1015, 1040, 1065, 1090, 1115, 1140, 1165, 1190, 1215, 1240, 1265, 1290, 1315, 1340, 1370, 1395, 1420, 1445, 1475, 1500, 1525, 1550, 1575, 1605, 1630, 1660, 1685, 1710, 1740, 1765, 1790, 1820, 1845, 1875, 1900, 1930, 1955, 1980, 2010, 2035, 2065, 2095, 2120, 2150, 2175, 2205, 2230, 2260, 2290, 2315, 2345, 2375, 2400, 2430, 2460, 2485, 2515, 2545, 2570, 2600, 2630, 2660, 2690, 2715, 2745, 2775, 2805, 2830, 2860, 2890, 2920, 2950, 2980, 3010, 3040, 3065, 3095, 3125, 3155, 3185, 3215, 3245, 3275, 3305, 3335, 3365, 3395, 3425, 3455, 3485, 3515, 3545, 3575, 3605, 3635, 3670, 3700, 3730, 3760, 3790, 3820, 3850, 3880, 3910, 3945, 3975, 4005, 4035, 4065, 4100, 4130], 22: [10, 20, 30, 45, 60, 75, 95, 110, 130, 145, 165, 185, 205, 220, 240, 260, 280, 305, 325, 345, 365, 385, 410, 430, 450, 475, 495, 520, 540, 565, 590, 610, 635, 655, 680, 705, 730, 750, 775, 800, 825, 850, 875, 900, 925, 950, 975, 1000, 1025, 1050, 1075, 1100, 1125, 1150, 1180, 1205, 1230, 1255, 1280, 1310, 1335, 1360, 1390, 1415, 1440, 1465, 1495, 1520, 1550, 1575, 1605, 1630, 1655, 1685, 1715, 1740, 1770, 1795, 1825, 1850, 1880, 1905, 1935, 1965, 1990, 2020, 2050, 2075, 2105, 2135, 2160, 2190, 2220, 2250, 2275, 2305, 2335, 2365, 2395, 2420], - 23: [10, 20, 30, 45, 65, 80, 95, 115, 135, 150, 170, 190, 210, 230, 250, 270, 290, 310, 335, 355, 375, 400, 420, 445, 465, 490, 515, 535, 560, 585, 605, 630, 655, 680, 705, 730, 750, 775, 800, 825, 850, 875, 905, 930, 955, 980, 1005, 1030, 1055, 1085, 1110, 1135, 1160, 1190, 1215, 1240, 1270, 1295, 1325, 1350, 1375, 1405, 1430, 1460, 1485, 1515, 1545, 1570] //to be filled + 23: [10, 20, 30, 45, 65, 80, 95, 115, 135, 150, 170, 190, 210, 230, 250, 270, 290, 310, 335, 355, 375, 400, 420, 445, 465, 490, 515, 535, 560, 585, 605, 630, 655, 680, 705, 730, 750, 775, 800, 825, 850, 875, 905, 930, 955, 980, 1005, 1030, 1055, 1085, 1110, 1135, 1160, 1190, 1215, 1240, 1270, 1295, 1325, 1350, 1375, 1405, 1430, 1460, 1485, 1515, 1545, 1570, 1600, 1625, 1655, 1680, 1710, 1740, 1765, 1795, 1825, 1855, 1880, 1910, 1940, 1970, 1995, 2025, 2055, 2085, 2115, 2145, 2175, 2200, 2230, 2260, 2290, 2320, 2350, 2380, 2410, 2440, 2470, 2500, 2530, 2560, 2590, 2620, 2650, 2685, 2715, 2745, 2775, 2805, 2835, 2865, 2895, 2930, 2960, 2990, 3020, 3055, 3085, 3115, 3145] }, GreatBuildingsData: [ @@ -357,7 +357,7 @@ let GreatBuildings = h.push('
${i18n("General.Player")}${i18n("General.GB")}${i18n("General.Level")}
'); - h.push(''); + h.push(''); h.push(''); h.push(''); h.push(''); diff --git a/js/web/guildfights/css/guildfights.css b/js/web/guildfights/css/guildfights.css index 3dc1f0d2f..ea25b657b 100644 --- a/js/web/guildfights/css/guildfights.css +++ b/js/web/guildfights/css/guildfights.css @@ -45,8 +45,6 @@ #GildPlayersBody tr th, #GildPlayersDetailViewBody tr th { - position: sticky; - top: 0; background-color: rgba(0, 0, 0, 0.45); line-height: 25px; @@ -167,17 +165,10 @@ padding: 0; } - #GildPlayersDetailViewBody .datetimepicker { padding: 2px 0 0 2px; background-color: rgba(0, 0, 0, 0.45); height: 28px; - position: sticky; - top: 0; -} - -#GildPlayersDetailViewBody .gbglog th { - top: 30px; } #GildPlayersDetailViewBody .sorter-header th { @@ -204,147 +195,13 @@ } #LiveGildFightingBody .province-color, #LiveGildFightingBody .province-color-round { - width: 10px; - height: 10px; + width: 13px; + height: 13px; display: inline-block; box-shadow: 0 1px 1px var(--black-65); - border-radius: 50%; -} - -/* A */ -#province-0 .province-color, -#province-4 .province-color, -#province-5 .province-color, -#province-12 .province-color, -#province-13 .province-color, -#province-14 .province-color, -#province-15 .province-color, -#province-28 .province-color, -#province-29 .province-color, -#province-30 .province-color, -#province-31 .province-color, -#province-32 .province-color, -#province-33 .province-color, -#province-34 .province-color, -#province-35 .province-color, -#timer-0 .province-color, -#timer-4 .province-color, -#timer-5 .province-color, -#timer-12 .province-color, -#timer-13 .province-color, -#timer-14 .province-color, -#timer-15 .province-color, -#timer-28 .province-color, -#timer-29 .province-color, -#timer-30 .province-color, -#timer-31 .province-color, -#timer-32 .province-color, -#timer-33 .province-color, -#timer-34 .province-color, -#timer-35 .province-color { - border-radius: 2px 100% 2px 2px; -} - -/* B */ -#province-1 .province-color, -#province-6 .province-color, -#province-7 .province-color, -#province-16 .province-color, -#province-17 .province-color, -#province-18 .province-color, -#province-19 .province-color, -#province-36 .province-color, -#province-37 .province-color, -#province-38 .province-color, -#province-39 .province-color, -#province-40 .province-color, -#province-41 .province-color, -#province-42 .province-color, -#province-43 .province-color, -#timer-1 .province-color, -#timer-6 .province-color, -#timer-7 .province-color, -#timer-16 .province-color, -#timer-17 .province-color, -#timer-18 .province-color, -#timer-19 .province-color, -#timer-36 .province-color, -#timer-37 .province-color, -#timer-38 .province-color, -#timer-39 .province-color, -#timer-40 .province-color, -#timer-41 .province-color, -#timer-42 .province-color, -#timer-43 .province-color { - border-radius: 2px 2px 100% 2px; -} - -/* C */ -#province-2 .province-color, -#province-8 .province-color, -#province-9 .province-color, -#province-20 .province-color, -#province-21 .province-color, -#province-22 .province-color, -#province-23 .province-color, -#province-44 .province-color, -#province-45 .province-color, -#province-46 .province-color, -#province-47 .province-color, -#province-48 .province-color, -#province-49 .province-color, -#province-50 .province-color, -#province-51 .province-color, -#timer-2 .province-color, -#timer-8 .province-color, -#timer-9 .province-color, -#timer-20 .province-color, -#timer-21 .province-color, -#timer-22 .province-color, -#timer-23 .province-color, -#timer-44 .province-color, -#timer-45 .province-color, -#timer-46 .province-color, -#timer-47 .province-color, -#timer-48 .province-color, -#timer-49 .province-color, -#timer-50 .province-color, -#timer-51 .province-color { - border-radius: 2px 2px 2px 100%; -} - -/* D */ -#province-3 .province-color, -#province-10 .province-color, -#province-11 .province-color, -#province-24 .province-color, -#province-25 .province-color, -#province-26 .province-color, -#province-27 .province-color, -#province-52 .province-color, -#province-53 .province-color, -#province-54 .province-color, -#province-55 .province-color, -#province-56 .province-color, -#province-57 .province-color, -#province-58 .province-color, -#province-59 .province-color, -#timer-3 .province-color, -#timer-10 .province-color, -#timer-11 .province-color, -#timer-24 .province-color, -#timer-25 .province-color, -#timer-26 .province-color, -#timer-27 .province-color, -#timer-52 .province-color, -#timer-53 .province-color, -#timer-54 .province-color, -#timer-55 .province-color, -#timer-56 .province-color, -#timer-57 .province-color, -#timer-58 .province-color, -#timer-59 .province-color { - border-radius: 100% 2px 2px 2px; + border-radius: 2px; + top: 2px; + position: relative; } #LiveGildFightingBody .tabs ul li a span { @@ -391,7 +248,7 @@ #LiveGildFightingBody #progress tr td:first-child, #LiveGildFightingBody #nextup tr td:first-child { - width: 60px; + width: 69px; } #LiveGildFightingBody table.foe-table tr.highlight-row { @@ -424,6 +281,12 @@ vertical-align: middle; } +#LiveGildFightingBody .smaller { + font-size: 8px; + bottom: 2px; + position: relative; +} + #LiveGildFightingBody .gbg-red:before { background-image: url(../../x_img/gbg-red.png); } @@ -503,4 +366,10 @@ position: absolute; top: 40px; left: 3px; +} + +#ProvinceMap #switchGBGMap { + position: absolute; + top: 40px; + right: 3px; } \ No newline at end of file diff --git a/js/web/guildfights/js/guildfights.js b/js/web/guildfights/js/guildfights.js index 35640ac66..50f3b56f2 100644 --- a/js/web/guildfights/js/guildfights.js +++ b/js/web/guildfights/js/guildfights.js @@ -75,11 +75,6 @@ FoEproxy.addHandler('GuildBattlegroundService', 'getBattleground', (data, postDa } }); -FoEproxy.addHandler("ClanService","getClanData",(data)=>{ - if (ActiveMap != 'gg') return - GuildFights.otherGuilds.check(data) -}) - /** * @type {{SettingsExport: GuildFights.SettingsExport, curDetailViewFilter: null, UpdateDB: ((function(*, *): Promise)|*), GBGRound: null, PrevActionTimestamp: null, NewActionTimestamp: null, InjectionLoaded: boolean, MapData: null, BuildPlayerContent: ((function(*=): Promise)|*), intiateDatePicker: ((function(): Promise)|*), GBGHistoryView: boolean, LogDatePicker: null, NewAction: null, PrevAction: null, init: GuildFights.init, PrepareColors: GuildFights.PrepareColors, SetBoxNavigation: ((function(*=): Promise)|*), PlayerBoxContent: *[], DeleteAlert: GuildFights.DeleteAlert, PlayerBoxSettingsSaveValues: GuildFights.PlayerBoxSettingsSaveValues, ToggleProgressList: GuildFights.ToggleProgressList, Colors: null, RefreshTable: GuildFights.RefreshTable, SetAlert: GuildFights.SetAlert, formatRange: (function(): string), GetAlertButton: (function(integer): string), Tabs: *[], ToggleCopyButton: GuildFights.ToggleCopyButton, Alerts: *[], PlayersPortraits: null, GetTabContent: (function(): string), ShowPlayerBox: GuildFights.ShowPlayerBox, CurrentGBGRound: null, showGuildColumn: number, curDateFilter: null, SortedColors: null, ShowGuildBox: GuildFights.ShowGuildBox, BuildFightContent: GuildFights.BuildFightContent, BuildDetailViewContent: ((function(*): Promise)|*), SetTabContent: GuildFights.SetTabContent, BuildDetailViewLog: ((function(*): Promise)|*), TabsContent: *[], GetAlerts: (function(): Promise), UpdateCounter: GuildFights.UpdateCounter, GBGAllRounds: null, ProvinceNames: null, checkForDB: ((function(*): Promise)|*), HandlePlayerLeaderboard: ((function(*): Promise)|*), SetTabs: GuildFights.SetTabs, CopyToClipBoard: GuildFights.CopyToClipBoard, GetTabs: (function(): string), DeleteOldSnapshots: ((function(*=): Promise)|*), PlayerBoxSettings: {showProgressFilter: number, showOnlyActivePlayers: number, showLogButton: number, showRoundSelector: number}, Neighbours: *[], curDateEndFilter: null, ShowPlayerBoxSettings: GuildFights.ShowPlayerBoxSettings, SaveLiveFightSettings: GuildFights.SaveLiveFightSettings, ShowLiveFightSettings: GuildFights.ShowLiveFightSettings, ShowDetailViewBox: GuildFights.ShowDetailViewBox}} */ @@ -724,10 +719,10 @@ let GuildFights = { tA += playerNew['attrition'] b.push(''); - b.push(''); + b.push(''); + b.push(''); b.push(''); - b.push(''); b.push('
' + i18n('Boxes.GreatBuildings.GreatBulding') + '' + i18n('Boxes.GreatBuildings.Level') + '
' + (parseInt(i) + 1) + '.' + playerNew.player_id + '.' + (parseInt(i) + 1) + '.' + playerNew['name'] + ''); b.push(playerNew['negotiationsWon'] + negotaionAddOn); @@ -767,17 +762,16 @@ let GuildFights = { let tNF = (tN * 2) + tF; - t.push(''); + t.push('
'); - t.push(''); + t.push(''); t.push(''); - t.push(''); - t.push(''); - t.push(''); - t.push(''); - t.push(''); - t.push(''); + t.push(''); + t.push(''); + t.push(''); + t.push(''); + t.push(''); t.push(''); t.push(''); @@ -796,13 +790,10 @@ let GuildFights = { GuildFights.curDetailViewFilter = { content: 'player', player_id: player_id, gbground: gbground }; - if ($('#GildPlayersDetailView').length === 0) - { + if ($('#GildPlayersDetailView').length === 0) { GuildFights.ShowDetailViewBox(GuildFights.curDetailViewFilter); } - else - { - + else { GuildFights.BuildDetailViewContent(GuildFights.curDetailViewFilter); } }); @@ -894,7 +885,7 @@ let GuildFights = { h.push('
' + playerName + ': ' + moment.unix(gbground).subtract(11, 'd').format(i18n('DateShort')) + ` - ` + moment.unix(gbground).format(i18n('Date')) + '
'); h.push('

' + i18n('Boxes.GuildFights.SnapShotLogDisclaimer') + '

') - h.push('
  ' + i18n('Boxes.GuildFights.Player') + ' (' + HTML.Format(tN) + ') (' + HTML.Format(tF) + ')' + i18n('Boxes.GuildFights.Total') + ' (' + HTML.Format(tNF) + ')' + i18n('Boxes.GuildFights.Player') + ' (' + HTML.Format(tN) + ') (' + HTML.Format(tF) + ')' + i18n('Boxes.GuildFights.Total') + ' (' + HTML.Format(tNF) + ')' + i18n('Boxes.GuildFights.Attrition') + ' (' + HTML.Format(tA) + ')
'); + h.push('
'); h.push(''); h.push(''); h.push(''); @@ -925,7 +916,7 @@ let GuildFights = { detaildata.sort(function (a, b) { return b.time - a.time }); - h.push('
'); + h.push('
'); h.push('
' + i18n('Boxes.GuildFights.Date') + '
'); h.push(''); h.push(''); @@ -1181,7 +1172,7 @@ let GuildFights = { // If sectors doesnt belong to anyone if (mapdata[i]['ownerId'] === undefined && mapdata[i]['conquestProgress'].length > 0) { progress.push(``); - progress.push(``); + progress.push(``); if (GuildFights.showGuildColumn) progress.push(``); @@ -1261,12 +1252,17 @@ let GuildFights = { if (showCountdowns) { let countDownDate = moment.unix(prov[x]['lockedUntil'] - 2), color = GuildFights.SortedColors.find(e => e['id'] === prov[x]['ownerId']), + battleType = prov[x].isAttackBattleType ? '🔴' : '🔵', intervalID = setInterval(() => { GuildFights.UpdateCounter(countDownDate, intervalID, prov[x]['id']); }, 1000); nextup.push(``); - nextup.push(``); + nextup.push(``); GuildFights.UpdateCounter(countDownDate, intervalID, prov[x]['id']); @@ -1371,7 +1367,8 @@ let GuildFights = { copycache.sort(function (a, b) { return a.lockedUntil - b.lockedUntil }); copycache.forEach((mapElem) => { - copy += `${moment.unix(mapElem.lockedUntil - 2).format('HH:mm')} ${mapElem.title}\n`; + let battleType = mapElem.isAttackBattleType ? '🔴' : '🔵'; + copy += `${moment.unix(mapElem.lockedUntil - 2).format('HH:mm')} ${mapElem.title} ${battleType}\n`; }); if (copy !== '') @@ -1578,15 +1575,14 @@ let GuildFights = { c.push(`

`); c.push(`

`); c.push(`

`); - c.push(`

${i18n('Boxes.General.Export')}: `); - c.push(`

`); + c.push(`

${i18n('Boxes.General.Export')}: `); + c.push(`

`); $('#GildPlayersSettingsBox').html(c.join('')); }, PlayerBoxSettingsSaveValues: () => { - GuildFights.PlayerBoxSettings.showRoundSelector = $("#gf_showRoundSelector").is(':checked') ? 1 : 0; GuildFights.PlayerBoxSettings.showProgressFilter = $("#gf_showProgressFilter").is(':checked') ? 1 : 0; GuildFights.PlayerBoxSettings.showLogButton = $("#gf_showLogButton").is(':checked') ? 1 : 0; @@ -1595,51 +1591,7 @@ let GuildFights = { $(`#GildPlayersSettingsBox`).fadeToggle('fast', function () { $(this).remove(); - GuildFights.BuildPlayerContent(GuildFights.CurrentGBGRound); - - }); - - }, - - - SettingsExport: (type) => { - - let blob, file; - let BOM = "\uFEFF"; - - if (type === 'json') { - let json = JSON.stringify(GuildFights.PlayerBoxContent); - - blob = new Blob([BOM + json], { - type: 'application/json;charset=utf-8' - }); - file = `ggfights-${ExtWorld}.json`; - } - - else if (type === 'csv') { - let csv = []; - - for (let i in GuildFights.PlayerBoxContent) { - if (!GuildFights.PlayerBoxContent.hasOwnProperty(i)) { - break; - } - - let r = GuildFights.PlayerBoxContent[i]; - console.log(r); - csv.push(`${r['player_id']};${r['player']};${r['negotiationsWon']};${r['battlesWon']};${r['attrition']};${r['total']}`); - } - - blob = new Blob([BOM + csv.join('\r\n')], { - type: 'text/csv;charset=utf-8' - }); - file = `ggfights-${ExtWorld}.csv`; - } - - MainParser.ExportFile(blob, file); - - $(`#GildPlayersSettingsBox`).fadeToggle('fast', function () { - $(this).remove(); }); }, @@ -1781,50 +1733,7 @@ let GuildFights = { GuildFights.ShowGuildBox(true) ); }); - }, - - otherGuilds: { - members:{}, - currentClan:null, - last:null, - check: (data) => { - id = data.responseData.id - if (id==ExtGuildID) return - let m=data.responseData.members - time = moment() - if (id!=GuildFights.otherGuilds.currentClan || GuildFights.otherGuilds.last.diff(time)>300000) { - GuildFights.otherGuilds.currentClan = id - GuildFights.otherGuilds.members = {} - for (x of m) GuildFights.otherGuilds.members[x.name] = x.won_battles; - } else { - let actives=[] - for (x of m) if (GuildFights.otherGuilds.members[x.name] < x.won_battles) { - actives.push(x.name) - GuildFights.otherGuilds.members[x.name] = x.won_battles - } - if (Object.values(actives).length>0) GuildFights.otherGuilds.show(data.responseData.name,actives) - } - GuildFights.otherGuilds.last=time - }, - show: (guildName,list)=> { - if(!Settings.GetSetting('ShowOtherGuildActivity')) return; - if ($('#OtherGuildActivity').length === 0) { - //HTML.AddCssFile(''); - HTML.Box({ - 'id': 'OtherGuildActivity', - 'title': i18n('Boxes.OtherGuildActivity.Title'), - 'auto_close': true, - 'minimize': true, - 'dragdrop': true - }); - } - let body=`

${guildName}

    `; - for (let x of list) body += `
  • ${x}
  • ` - body +=`
      `; - $('#OtherGuildActivityBody').html(body); - } - } - + }, }; /** @@ -1917,6 +1826,7 @@ let ProvinceMap = { ProvinceMap.Map = document.createElement("canvas"); ProvinceMap.MapCTX = ProvinceMap.Map.getContext('2d'); + ProvinceMap.view = "guildType"; $(ProvinceMap.Map).attr({ id: 'province-map', @@ -1929,13 +1839,17 @@ let ProvinceMap = { id: 'province-map-wrap', }); $(wrapper).html(ProvinceMap.Map); - $('#ProvinceMapBody').html(wrapper).append(''+i18n('Boxes.GvGMap.Action.Zoom')+''); + $('#ProvinceMapBody').html(wrapper).append(''+i18n('Boxes.GvGMap.Action.Zoom')+''+i18n('Boxes.GuildFights.Switch')+''); ProvinceMap.mapDrag(); $('#zoomGBGMap').click(function (e) { $('#province-map').toggleClass('zoomed'); }); + $('#switchGBGMap').click(function (e) { + ProvinceMap.view = ProvinceMap.view == "battleType" ? "guildType" : "battleType"; + ProvinceMap.BuildMap(); + }); ProvinceMap.MapCTX.strokeStyle = ProvinceMap.StrokeColor; ProvinceMap.MapCTX.lineWidth = 2; @@ -1952,6 +1866,7 @@ let ProvinceMap = { this.short = data.short; this.links = data.links; this.flag = data.flag; + this.battleType = data.battleType; this.isSpawnSpot = data.isSpawnSpot; this.owner = { id: data.ownerID, @@ -1969,7 +1884,7 @@ let ProvinceMap = { } Province.prototype.updateMapSector = function () { - this.drawMapSector(GuildFights.MapData.map['id']); + this.drawMapSector(GuildFights.MapData.map['id']); } Province.prototype.drawMapSector = function (mapType = 'waterfall_archipelago') { @@ -2008,6 +1923,11 @@ let ProvinceMap = { else { ProvinceMap.MapCTX.fillStyle = sector.owner.colors.highlight; + if (ProvinceMap.view == "battleType" && sector.battleType == "red" && sector.owner.colors.cid !== "own_guild_colour") + ProvinceMap.MapCTX.fillStyle = "#cf401e"; + else if (ProvinceMap.view == "battleType" && sector.battleType == "blue" && sector.owner.colors.cid !== "own_guild_colour") + ProvinceMap.MapCTX.fillStyle = "#4a98dd"; + if (mapType === 'volcano_archipelago') sector.drawSectorShape(); else @@ -2016,11 +1936,11 @@ let ProvinceMap = { mapStuff.y = mapStuff.y - 20; if (sector.lockedUntil === undefined && sector.conquestProgress.length === 0) - sector.drawTitleAndSlots(true, mapStuff.x, mapStuff.y); + sector.drawTitleAndSlots(mapType, true, mapStuff.x, mapStuff.y); else { if (mapType === 'waterfall_archipelago') mapStuff.y = mapStuff.y - 10; - sector.drawTitleAndSlots(false, mapStuff.x, mapStuff.y); + sector.drawTitleAndSlots(mapType, false, mapStuff.x, mapStuff.y); } mapStuff.y = mapStuff.y+23; @@ -2043,7 +1963,7 @@ let ProvinceMap = { ProvinceMap.MapCTX.fillText(provinceUnlockTime,mapStuff.x,mapStuff.y+5); } - Province.prototype.drawTitleAndSlots = function(drawCentered = true, x, y) { + Province.prototype.drawTitleAndSlots = function(mapType, drawCentered = true, x, y) { let titleY = y; let slotsY = y - 20; if (drawCentered) { @@ -2051,9 +1971,28 @@ let ProvinceMap = { slotsY = y - 10; } - ProvinceMap.MapCTX.font = 'bold 30px Arial'; + // do not draw dots for own sectors + if (this.owner.colors.cid != "own_guild_colour") { + ProvinceMap.MapCTX.strokeStyle = '#000'; + + ProvinceMap.MapCTX.beginPath(); + ProvinceMap.MapCTX.arc(x-36, titleY+12, 5, 0, 2*Math.PI); + + ProvinceMap.MapCTX.fillStyle = '#f00'; + if (this.battleType == 'blue') + ProvinceMap.MapCTX.fillStyle = '#00f'; + + if (ProvinceMap.view == "battleType") + ProvinceMap.MapCTX.fillStyle = this.owner.colors.highlight; + ProvinceMap.MapCTX.stroke(); + ProvinceMap.MapCTX.fill(); + } + ProvinceMap.MapCTX.strokeStyle = '#fff5'; + + ProvinceMap.MapCTX.font = 'bold 28px Arial'; ProvinceMap.MapCTX.strokeText(this.short, x, titleY); + ProvinceMap.MapCTX.fillStyle = '#000'; ProvinceMap.MapCTX.fillText(this.short, x, titleY); @@ -2065,6 +2004,7 @@ let ProvinceMap = { slots = '··'; else if (this.totalBuildingSlots == 3) slots = '···'; + ProvinceMap.MapCTX.strokeText(slots, x, slotsY); ProvinceMap.MapCTX.fillText(slots, x, slotsY); } @@ -2164,6 +2104,7 @@ let ProvinceMap = { }; let prov = GuildFights.MapData['map']['provinces'][i.id]; + data.battleType = prov.isAttackBattleType ? 'red' : 'blue'; if (prov['ownerId']) { data.ownerID = prov['ownerId']; @@ -2220,7 +2161,6 @@ let ProvinceMap = { * @constructor */ RefreshSector: (socketData = []) => { - // TO DO: check sector unlock times and refresh let updatedProvince = ProvinceMap.Provinces.find(p => p.id === 0); // first sector does not have an ID, make it the default one if (socketData['id'] !== undefined) @@ -2237,8 +2177,6 @@ let ProvinceMap = { updatedProvince.owner.colors = ProvinceMap.getSectorColors(socketData.ownerId); } - //GuildFights.MapData.map.provinces[socketData['id'] || 0] = updatedProvince; - updatedProvince.updateMapSector(); }, diff --git a/js/web/guildmemberstat/css/guildmemberstat.css b/js/web/guildmemberstat/css/guildmemberstat.css index e1209a72a..952d63bc6 100644 --- a/js/web/guildmemberstat/css/guildmemberstat.css +++ b/js/web/guildmemberstat/css/guildmemberstat.css @@ -189,10 +189,7 @@ #GuildMemberStatBody table th { line-height: 23px; - position: sticky; - top: 0; cursor: pointer; - z-index: 10; } #GuildMemberStatBody .detail-item>table th { diff --git a/js/web/guildmemberstat/js/guildmemberstat.js b/js/web/guildmemberstat/js/guildmemberstat.js index 462ba368d..0c0a668fa 100644 --- a/js/web/guildmemberstat/js/guildmemberstat.js +++ b/js/web/guildmemberstat/js/guildmemberstat.js @@ -968,7 +968,7 @@ let GuildMemberStat = { h.push(`
    `); h.push(`
    `); h.push('
' + i18n('Boxes.GuildFights.Date') + '
${mapdata[i]['title']} ${GuildFights.MapData['title']}${i18n('Boxes.GuildFights.NoOwner')}
${prov[x]['title']}`) + nextup.push(` `) + nextup.push(`${battleType}`) + nextup.push(` ${prov[x]['title']} `) + nextup.push(`
'); - h.push('' + + h.push('' + '' + `` + `` + @@ -1273,7 +1273,7 @@ let GuildMemberStat = { // Create Inactivity Overview if (Member['activity'] !== undefined) { - d.push(`
${i18n('Boxes.GuildMemberStat.Member')}
`); + d.push(`
${i18n('Boxes.GuildMemberStat.Inactivity')}${i18n('Boxes.GuildMemberStat.Date')}
`); let warnings = Member['activity']; @@ -1305,7 +1305,7 @@ let GuildMemberStat = { // Create GEX Overview if (Member['gex'] !== undefined) { - d.push(`
${i18n('Boxes.GuildMemberStat.Inactivity')}${i18n('Boxes.GuildMemberStat.Date')}
`); + d.push(`
${i18n('Boxes.GuildMemberStat.GEXWeek')}${i18n('Boxes.GuildMemberStat.Rank')}${i18n('Boxes.GuildMemberStat.Points')}${i18n('Boxes.GuildMemberStat.Level')}
`); let gex = Member['gex']; for (let i in gex) { @@ -1335,7 +1335,7 @@ let GuildMemberStat = { // Create GBG Overview if (Member['gbg'] !== undefined) { - d.push(`
${i18n('Boxes.GuildMemberStat.GEXWeek')}${i18n('Boxes.GuildMemberStat.Rank')}${i18n('Boxes.GuildMemberStat.Points')}${i18n('Boxes.GuildMemberStat.Level')}
`); + d.push(`
${i18n('Boxes.GuildMemberStat.GBFRound')}${i18n('Boxes.GuildMemberStat.Rank')}${i18n('Boxes.GuildMemberStat.Battles')}${i18n('Boxes.GuildMemberStat.Negotiations')}
`); let gbg = Member['gbg']; @@ -1376,7 +1376,7 @@ let GuildMemberStat = { let totalGoods = 0; let totalPower = 0; - d.push(`
${i18n('Boxes.GuildMemberStat.GBFRound')}${i18n('Boxes.GuildMemberStat.Rank')}${i18n('Boxes.GuildMemberStat.Battles')}${i18n('Boxes.GuildMemberStat.Negotiations')}
`); + d.push(`
${i18n('Boxes.GuildMemberStat.GuildSupportBuildings')} (${i18n('Boxes.GuildMemberStat.LastUpdate') + ' ' + moment(guildbuildings.date).fromNow()})
`); // Group GuildGoods buildings by name and their era let guildGoodsBuildings = guildbuildings['buildings'].filter(function (data) { return data.resources !== undefined }).reduce(function (res, obj) { @@ -1413,7 +1413,7 @@ let GuildMemberStat = { if (guildGoodsBuildings.length) { - d.push(`
${i18n('Boxes.GuildMemberStat.GuildSupportBuildings')} (${i18n('Boxes.GuildMemberStat.LastUpdate') + ' ' + moment(guildbuildings.date).fromNow()})
`); + d.push(`
${i18n('Boxes.GuildMemberStat.GuildGoods')}
`); guildGoodsBuildings.forEach(plbuilding => { let goodslist = ''; @@ -1452,7 +1452,7 @@ let GuildMemberStat = { if (guildPowerBuildings.length) { - d.push(`
${i18n('Boxes.GuildMemberStat.GuildGoods')}
`); + d.push(`
${i18n('Boxes.GuildMemberStat.GuildPower')}
`); guildPowerBuildings.forEach(plbuilding => { let countBuilding = typeof plbuilding.count != 'undefined' ? plbuilding.count : 1; @@ -1604,7 +1604,7 @@ let GuildMemberStat = { if (EraGroup) { d.push(`
${i18n('Boxes.GuildMemberStat.GuildPower')}
` + - `` + + `` + `` + `` + ``); @@ -1728,7 +1728,7 @@ let GuildMemberStat = { let h = []; h.push(`
#${i18n('Boxes.GuildMemberStat.Eras')}${i18n('Boxes.GuildMemberStat.GuildMembers')}
` + - ``); + `
${i18n('Boxes.GuildMemberStat.Rank')}${i18n('Boxes.GuildMemberStat.Member')}${i18n('Boxes.GuildMemberStat.Eras')}${i18n('Boxes.GuildMemberStat.Points')}
`); if (EraGroup[eraId].members !== undefined) { @@ -1747,7 +1747,7 @@ let GuildMemberStat = { { let EraTreasuryGoods = TreasuryGoodsData[EraGroup[eraId].era]; - h.push(`
${i18n('Boxes.GuildMemberStat.Rank')}${i18n('Boxes.GuildMemberStat.Member')}${i18n('Boxes.GuildMemberStat.Eras')}${i18n('Boxes.GuildMemberStat.Points')}
`); + h.push(`
${i18n('Boxes.GuildMemberStat.EraTreasuryGoods')}
`); EraTreasuryGoods.forEach(good => { h.push(``); }); @@ -1867,7 +1867,7 @@ let GuildMemberStat = { if (guildGoodsBuildings.length) { - d.push(`
${i18n('Boxes.GuildMemberStat.EraTreasuryGoods')}
${good.name}${HTML.Format(good.value)}
`); + d.push(`
${i18n('Boxes.GuildMemberStat.GuildGoods')}
`); guildGoodsBuildings.forEach(plbuilding => { let countBuilding = typeof plbuilding.count != 'undefined' ? plbuilding.count : 1; @@ -1882,7 +1882,7 @@ let GuildMemberStat = { if (guildPowerBuildings.length) { - d.push(`
${i18n('Boxes.GuildMemberStat.GuildGoods')}
`); + d.push(`
${i18n('Boxes.GuildMemberStat.GuildPower')}
`); guildPowerBuildings.forEach(plbuilding => { let countBuilding = typeof plbuilding.count != 'undefined' ? plbuilding.count : 1; @@ -1898,7 +1898,7 @@ let GuildMemberStat = { d.push(``); d.push(`
`); - d.push(`
${i18n('Boxes.GuildMemberStat.GuildPower')}
` + + d.push(`
` + `` + `` + `` + @@ -2003,7 +2003,7 @@ let GuildMemberStat = { return; } - d.push(`
#${i18n('Boxes.GuildMemberStat.GuildBuildings')}${i18n('Boxes.GuildMemberStat.Level')}
`); + d.push(`
${i18n('Boxes.GuildMemberStat.Eras')} ${i18n('Boxes.GuildMemberStat.ProducedTreasuryGoods')} ${i18n('Boxes.GuildMemberStat.TreasuryGoods')}
`); ExportContent.push(['eraID', 'era', 'good', 'produceable', 'instock']); @@ -2201,7 +2201,7 @@ let GuildMemberStat = { }); d.push(`
`); - d.push(`
${i18n('Boxes.GuildMemberStat.Eras')} ${i18n('Boxes.GuildMemberStat.ProducedTreasuryGoods')} ${i18n('Boxes.GuildMemberStat.TreasuryGoods')}
` + + d.push(`
` + `` + `` + `` + @@ -2223,7 +2223,7 @@ let GuildMemberStat = { d.push(``); d.push(`
`); - d.push(`
${i18n('Boxes.GuildMemberStat.GreatBuildings')}${i18n('Boxes.GuildMemberStat.Available')}${i18n('Boxes.GuildMemberStat.MinLevel')}
` + + d.push(`
` + `` + `` + `` + @@ -2314,7 +2314,7 @@ let GuildMemberStat = { let NoGbMember = GBOverview[id]['NoGbMember']; d.push(`
` + - `
${i18n('Boxes.GuildMemberStat.GreatBuildings')}${i18n('Boxes.GuildMemberStat.Member')}${i18n('Boxes.GuildMemberStat.Level')}
` + + `
` + `` + `` + `` + diff --git a/js/web/hidden-rewards/css/hidden-rewards.css b/js/web/hidden-rewards/css/hidden-rewards.css index ecd4e992c..ecdc90045 100644 --- a/js/web/hidden-rewards/css/hidden-rewards.css +++ b/js/web/hidden-rewards/css/hidden-rewards.css @@ -11,9 +11,11 @@ * ************************************************************************************** */ - #HiddenRewardBox { +#HiddenRewardBox { top: 30%; left: 30px; + height: 400px; + width: 350px; } #HiddenRewardBox img { @@ -22,16 +24,15 @@ max-width: 3.5em; max-height: 2.5em; } + #HiddenRewardBox #HiddenRewardBoxBody { - max-height: 400px; - min-width: 350px; - overflow: hidden; - overflow-y: auto; + overflow: hidden; + overflow-y: auto; } #HiddenRewardBox table td.incident { vertical-align: middle; - text-align: center; + text-align: center; min-height: 30px; } @@ -40,28 +41,72 @@ color: var(--text-bright); } -td[title="incident_sos"], td[title="incident_beach_gear"], td[title="incident_shipwreck"], td[title="incident_flotsam"] { - background: linear-gradient(to top right, #20423f, 15%, #20423f, 35%, #d4ab70, 65%, #d4ab70); +td[title="incident_sos"], +td[title="incident_beach_gear"], +td[title="incident_shipwreck"], +td[title="incident_flotsam"] { + background: linear-gradient(to top right, #20423f, 15%, #20423f, 35%, #d4ab70, 65%, #d4ab70); } td[title="incident_sos"] img { filter: drop-shadow(1px 1px 3px white); } -td[title="incident_fallen_tree_1x1"], td[title="incident_blocked_road_1x1"], td[title="incident_blocked_road_2x2"], td[title="incident_fallen_tree_2x2"], td[title="incident_pothole_1x1"], td[title="incident_pothole_2x2"] { - background-color: #818272; +td[title="incident_fallen_tree_1x1"], +td[title="incident_blocked_road_1x1"], +td[title="incident_blocked_road_2x2"], +td[title="incident_fallen_tree_2x2"], +td[title="incident_pothole_1x1"], +td[title="incident_pothole_2x2"] { + background-color: #818272; } -td[title="incident_sculptor"],td[title="incident_chest"],td[title="incident_hero"], td[title="incident_beehive"], td[title="incident_crates"], td[title="incident_broken_cart"], td[title="incident_car_accident"], td[title="incident_clothesline"], td[title="incident_dinosaur_bones"], td[title="incident_empty_clothesline"], td[title="incident_fruit_vendor"], td[title="incident_kite"], td[title="incident_mammoth_bones"], td[title="incident_musician"], td[title="incident_overgrowth"], td[title="incident_quicksand"], td[title="incident_statue"], td[title="incident_stick_hut"], td[title="incident_treasure_chest"], td[title="incident_wine_cask"], td[title="spring_cherry_tree"], td[title="ages_birthday_gift_1"], td[title="ages_birthday_gift_2"], td[title="ages_birthday_gift_3"] { - background-color: #5d6324; +td[title="incident_sculptor"], +td[title="incident_chest"], +td[title="incident_hero"], +td[title="incident_beehive"], +td[title="incident_crates"], +td[title="incident_broken_cart"], +td[title="incident_car_accident"], +td[title="incident_clothesline"], +td[title="incident_dinosaur_bones"], +td[title="incident_empty_clothesline"], +td[title="incident_fruit_vendor"], +td[title="incident_kite"], +td[title="incident_mammoth_bones"], +td[title="incident_musician"], +td[title="incident_overgrowth"], +td[title="incident_quicksand"], +td[title="incident_statue"], +td[title="incident_stick_hut"], +td[title="incident_treasure_chest"], +td[title="incident_wine_cask"], +td[title="spring_cherry_tree"], +td[title="ages_birthday_gift_1"], +td[title="ages_birthday_gift_2"], +td[title="ages_birthday_gift_3"] { + background-color: #5d6324; } -td[title="incident_rhino"], td[title="incident_castaway"], td[title="incident_fisherman"], td[title="incident_floating_chest"] { - background-color: #20423f; +td[title="incident_rhino"], +td[title="incident_castaway"], +td[title="incident_fisherman"], +td[title="incident_floating_chest"] { + background-color: #20423f; } #HiddenRewardBox tr.unavailable { opacity: 0.5; font-style: italic; +} + +#HiddenRewardBox .warning { + color: var(--text-bright); + padding: 5px; + text-align: center; +} + +#HiddenRewardBox .dark-bg { + border-bottom: 1px solid var(--text-bright); } \ No newline at end of file diff --git a/js/web/hidden-rewards/js/hidden-rewards.js b/js/web/hidden-rewards/js/hidden-rewards.js index a101495fc..5a353797a 100644 --- a/js/web/hidden-rewards/js/hidden-rewards.js +++ b/js/web/hidden-rewards/js/hidden-rewards.js @@ -18,9 +18,12 @@ FoEproxy.addHandler('HiddenRewardService', 'getOverview', (data, postData) => { HiddenRewards.GEprogress = JSON.parse(localStorage.getItem('HiddenRewards.GEprogress')||'0'); HiddenRewards.RefreshGui(fromHandler); - if (HiddenRewards.FirstCycle) { //Alle 60 Sekunden aktualisieren (Startbeginn des Ereignisses könnte erreicht worden sein) + if (HiddenRewards.FirstCycle) { //Timer setzen HiddenRewards.FirstCycle = false; - setInterval(HiddenRewards.RefreshGui, 60000); + data.responseData.hiddenRewards.forEach(x=>{ + if (x.startTime && x.startTime>GameTime) + setTimeout(HiddenRewards.RefreshGui, (x.startTime+5-GameTime)*1000) + }) } }); @@ -68,6 +71,7 @@ let HiddenRewards = { 'auto_close': true, 'dragdrop': true, 'minimize': true, + 'resize': true, 'settings': 'HiddenRewards.ShowSettingsButton()' }); @@ -94,11 +98,12 @@ let HiddenRewards = { let positionX = Rewards[idx].position.position || 0; let isGE = false; let SkipEvent = true; + let twolane = false // prüfen ob der Spieler in seiner Stadt eine zweispurige Straße hat if (position === 'cityRoadBig') { - if (CurrentEraID >= Technologies.Eras.ProgressiveEra) - SkipEvent = false; + if (CurrentEraID >= Technologies.Eras.ProgressiveEra) SkipEvent = false + twolane = true } else { SkipEvent = false; @@ -126,7 +131,8 @@ let HiddenRewards = { starts: Rewards[idx].startTime, expires: Rewards[idx].expireTime, isGE: isGE, - positionGE: positionX + positionGE: positionX, + twolane: twolane }); } @@ -179,6 +185,11 @@ let HiddenRewards = { BuildBox: () => { let h = []; + let twolane = 0 < [...new Set(Object.values(MainParser.CityMapData).filter(x=>x.type=="street").map(x=>x.cityentity_id))].filter(x=>MainParser.CityEntities[x].requirements.street_connection_level == 2).length + let warning = HiddenRewards.FilteredCache.filter(x=>x.twolane).length > 0 && !twolane + if (warning) { + h.push(`
${i18n("Boxes.HiddenRewards.twolaneWarning")}
`) + } h.push('
${i18n('Boxes.GuildMemberStat.Member')}${i18n('Boxes.GuildMemberStat.Level')}${i18n('Boxes.GuildMemberStat.UnlockedLevel')}
'); h.push(''); diff --git a/js/web/infoboard/css/infoboard.css b/js/web/infoboard/css/infoboard.css index a7bf3ba58..d0e2aacd0 100644 --- a/js/web/infoboard/css/infoboard.css +++ b/js/web/infoboard/css/infoboard.css @@ -61,10 +61,7 @@ table.info-table tr td { display: flex; align-items: center; background-color: rgba(0,0,0, 0.5); - position: sticky; - top: 0; padding: 5px; - z-index: 100; } #BackgroundInfo #BackgroundInfoBody .filter-row span { @@ -108,7 +105,8 @@ table.info-table tr td { } #BackgroundInfoTable .welcome { - background-color: var(--background-table-odd); + -webkit-backdrop-filter: brightness(1.1) saturate(1.1); + backdrop-filter: brightness(1.1) saturate(1.1); } #BackgroundInfoTable .welcome td:first-child { diff --git a/js/web/infoboard/js/infoboard.js b/js/web/infoboard/js/infoboard.js index 55cb35982..666caae36 100644 --- a/js/web/infoboard/js/infoboard.js +++ b/js/web/infoboard/js/infoboard.js @@ -121,7 +121,7 @@ let Infoboard = { h = []; // Filter - h.push('
'); + h.push('
'); h.push('
'); - h.push('' + + h.push('' + '' + '' + '' + @@ -410,14 +410,14 @@ let Investment = { removeUnsafeCalc = (InvestmentSettings && InvestmentSettings.removeUnsafeCalc !== undefined) ? InvestmentSettings.removeUnsafeCalc : 0, showinvestmentsautomatically = Settings.GetSetting('ShowInvestments'); - c.push(`

${i18n('Boxes.Investment.Overview.AdditionalColumns')}:

`); - c.push(`

`); - c.push(`

`); - c.push(`

`); - c.push(`

`); - c.push(`


`); - c.push(`

`); - c.push(`


`); + c.push(`

${i18n('Boxes.Investment.Overview.AdditionalColumns')}:


`); + c.push(`
`); + c.push(`
`); + c.push(`
`); + c.push(`
`); + c.push(`

`); + c.push(``); + c.push(`
`); c.push(`

`); $('#InvestmentSettingsBox').html(c.join('')); diff --git a/js/web/kits/css/kits.css b/js/web/kits/css/kits.css index ab23117fb..39abb75d3 100644 --- a/js/web/kits/css/kits.css +++ b/js/web/kits/css/kits.css @@ -86,10 +86,7 @@ #kits h2 { background: linear-gradient(to bottom, var(--text-darker), #281207cc); padding: 5px; - position: sticky; - top: 0; width: 100%; - z-index: 500; box-sizing: border-box; } diff --git a/js/web/kits/data/sets.json b/js/web/kits/data/sets.json index f80c8c5ea..928d42220 100644 --- a/js/web/kits/data/sets.json +++ b/js/web/kits/data/sets.json @@ -1,6 +1,6 @@ [ { - "udate": "Winter Event 2024 (14 October 2024)" + "udate": "Wildlife Event 2024 (22 December 2024)" }, { "groupname": "Events" @@ -63,6 +63,24 @@ {"first": "A_MultiAge_PatrickBonusSet20a"} ] }, + { + "name": "Shika_Shrine", + "buildings": [ + {"first": "W_MultiAge_WILD25A1"} + ] + }, + { + "name": "Koi_Pond", + "buildings": [ + {"first": "W_MultiAge_WILD25B1"} + ] + }, + { + "name": "Usagi_Bonbori_Gate", + "buildings": [ + {"first": "W_MultiAge_WILD25C1"} + ] + }, { "name": "Flamingo_Habitat", "buildings": [ @@ -111,11 +129,18 @@ ] }, { + "comment":"OLD VERSION!!! remove at some point!!!", "name": "Mountain_Reserve", "buildings": [ {"first": "R_MultiAge_WildBonus21a"} ] }, + { + "name": "Mountain_Reserve", + "buildings": [ + {"first": "W_MultiAge_WILD21A1"} + ] + }, { "name": "Yukitomo_Tower", "buildings": [ @@ -988,15 +1013,35 @@ "buildings": [ {"first": "W_MultiAge_GR24D1"} ] - },{ + }, + { + "name": "Neo_Checkmate_Square", + "buildings": [ + {"first": "W_MultiAge_GR25A1"} + ] + }, + { + "name": "Neo_Aviary", + "buildings": [ + {"first": "W_MultiAge_GR25B1"} + ] + }, + { "groupname": "Guild_Expeditions" }, { + "comment":"OLD VERSION!!! remove at some point!!!", "name": "Terrace_Farm", "buildings": [ {"first": "P_MultiAge_Expedition16"} ] }, + { + "name": "Terrace_Farm", + "buildings": [ + {"first": "W_MultiAge_Expedition16aBase"} + ] + }, { "name": "Fountain_of_Youth", "buildings": [ @@ -1154,6 +1199,5 @@ "buildings": [ {"first": "L_AllAge_CupBonus1"} ] - } - + } ] \ No newline at end of file diff --git a/js/web/kits/js/kits.js b/js/web/kits/js/kits.js index 071eaa26e..56ed8862c 100644 --- a/js/web/kits/js/kits.js +++ b/js/web/kits/js/kits.js @@ -474,7 +474,7 @@ let Kits = { if (!GroupName) { t += '
' - t += `

` + favourite + ChainSetIco +' '+ KitText + (ChainSetIco!="" ? "": eff) + upgrades + '

' + t += `

` + favourite + ChainSetIco +' '+ KitText + (ChainSetIco!="" ? "": eff) + upgrades + '

' } if(buildings.length) { buildings.forEach((building) => { diff --git a/js/web/market/css/market.css b/js/web/market/css/market.css index 5f13cae7d..55fa7d8c8 100644 --- a/js/web/market/css/market.css +++ b/js/web/market/css/market.css @@ -24,10 +24,7 @@ } #Market #MarketBody table th { - position: sticky; - top: 0; cursor: pointer; - z-index: 1; font-size: 85%; } diff --git a/js/web/market/js/market.js b/js/web/market/js/market.js index 57dd878e1..bc53d600b 100644 --- a/js/web/market/js/market.js +++ b/js/web/market/js/market.js @@ -187,7 +187,7 @@ let Market = { // Filters h.push('
'); h.push('
' + i18n('Boxes.Investment.Overview.Player') + '' + i18n('Boxes.Investment.Overview.Building') + '
'); - h.push(''); + h.push(''); h.push(''); h.push(''); @@ -312,7 +312,7 @@ let Market = { // Table h.push('
'); h.push('' + i18n('Boxes.Market.TradePartner') + '
'); - h.push(''); + h.push(''); h.push(''); h.push(''); h.push(''); @@ -514,8 +514,8 @@ let Market = { let autoOpen = Settings.GetSetting('ShowMarketFilter'); let h = []; - h.push(`


`); - h.push(`

`); + h.push(`${i18n('Boxes.General.Export')}: `); + h.push(``); h.push(`

`); h.push(`

`); diff --git a/js/web/marketoffers/css/marketoffers.css b/js/web/marketoffers/css/marketoffers.css index fa3370bb0..18f02ae96 100644 --- a/js/web/marketoffers/css/marketoffers.css +++ b/js/web/marketoffers/css/marketoffers.css @@ -25,10 +25,7 @@ } #MarketOffers #MarketOffersBody table th { - position: sticky; - top: 0; cursor: pointer; - z-index: 1; font-size: 85%; } @@ -92,10 +89,7 @@ } #MarketOffersEvents #MarketOffersEventsBody table th { - position: sticky; - top: 0; cursor: pointer; - z-index: 1; font-size: 85%; } diff --git a/js/web/marketoffers/js/marketoffers.js b/js/web/marketoffers/js/marketoffers.js index be3dc7867..2b63e4f5d 100644 --- a/js/web/marketoffers/js/marketoffers.js +++ b/js/web/marketoffers/js/marketoffers.js @@ -134,6 +134,7 @@ let MarketOffers = { h.push('
' + i18n('Boxes.Market.OfferColumn') + '' + i18n('Boxes.Market.NeedColumn') + '
'); h.push(''); + h.push(''); h.push(''); h.push('') h.push(''); @@ -144,6 +145,7 @@ let MarketOffers = { h.push(''); h.push(''); h.push(''); + h.push(''); for (let i = 0; i < GoodsList.length; i++) { let CurrentGood = GoodsList[i], @@ -214,8 +216,8 @@ let MarketOffers = { */ ShowSettingsButton: () => { let h = []; - h.push(`

`); - h.push(`

`); + h.push(`${i18n('Boxes.General.Export')}: `); + h.push(``); $('#MarketOffersSettingsBox').html(h.join('')); }, @@ -298,6 +300,7 @@ let MarketOffers = { }); h.push(''); + h.push(''); h.push(''); h.push(''); @@ -312,6 +315,7 @@ let MarketOffers = { h.push(''); if (MarketOffers.CurrentEventsTab === 'accepted') h.push(''); h.push(''); + h.push(''); for (let i = 0; i < EventList.length; i++) { let Event = EventList[i]; diff --git a/js/web/mouseActions/js/mouseActions.js b/js/web/mouseActions/js/mouseActions.js new file mode 100644 index 000000000..ce2d089f6 --- /dev/null +++ b/js/web/mouseActions/js/mouseActions.js @@ -0,0 +1,131 @@ +/* + * ************************************************************************************* + * + * Copyright (C) 2024 FoE-Helper team - All Rights Reserved + * You may use, distribute and modify this code under the + * terms of the AGPL license. + * + * See file LICENSE.md or go to + * https://github.com/mainIine/foe-helfer-extension/blob/master/LICENSE.md + * for full license details. + * + * ************************************************************************************* + */ + +let mouseActions = { + actions:[], + randomClickRadius:3, + targetEl:null, + + init: async () => { + x = new Promise((resolve) => { + let timer = () => { + if ($("#openfl-content canvas").length==0) { + setTimeout(timer,50) + } else { + resolve() + } + } + timer() + }), + await x + mouseActions.targetEl = $("#openfl-content canvas")[0] + $("#openfl-content").on("click",(e) => { + let X=e.clientX, + Y=e.clientY + for (action of mouseActions.actions) { + let coords1=mouseActions.calcCoords(action.area[0]), + coords2=mouseActions.calcCoords(action.area[1]), + [X1,X2]=coords1[0]=X && Y1<=Y && Y2>=Y) ^ !inside){ + action.callback(X,Y) + } + + } + }) + }, + + addAction:(area,callback)=>{ + mouseActions.actions.push({area:area,callback:callback}) + }, + + simulate: (element, eventName, options={}) => { + + if (!/^(?:click|dblclick|mouse(?:down|enter|leave|up|over|move|out))$/.test(eventName)) return + + let oEvent = new MouseEvent(eventName,options) + element.dispatchEvent(oEvent) + return ; + }, + + click: (vars={})=> { + mouseActions.simulate(mouseActions.targetEl, "mousedown", vars) + mouseActions.simulate(mouseActions.targetEl, "mouseup", vars) + }, + + calcCoords: (coords,anchor="TopLeft")=> { + let H = window.innerHeight, + W = window.innerWidth, + xOld = coords[0], + yOld = coords[1], + x,y,xNew,yNew, + anchorOld = coords[2] || "TopLeft" + + if (anchorOld.includes("Center")){ + x = xOld + Math.floor(W/2) + y = yOld + Math.floor(H/2) + } + if (anchorOld.includes("Top")) y = yOld + if (anchorOld.includes("Bottom")) y = yOld + H + if (anchorOld.includes("Left")) x = xOld + if (anchorOld.includes("Right")) x = xOld + W + + if (anchor.includes("Center")){ + xNew = x - Math.floor(W/2) + yNew = y - Math.floor(H/2) + } + if (anchor.includes("Top")) yNew = y + if (anchor.includes("Bottom")) yNew = y - H + if (anchor.includes("Left")) xNew = x + if (anchor.includes("Right")) xNew = x - W + return [xNew,yNew,anchor] + }, + + randomClick: (coords,n=1)=> { + let TLCoords=mouseActions.calcCoords(coords,"TopLeft") + X=Math.max(TLCoords[0] + Math.floor(Math.random()*(2*mouseActions.randomClickRadius +1)) - mouseActions.randomClickRadius,0) + Y=Math.max(TLCoords[1] + Math.floor(Math.random()*(2*mouseActions.randomClickRadius +1)) - mouseActions.randomClickRadius,0) + + mouseActions.simulate(mouseActions.targetEl, "mousemove", {clientX:X,clientY:Y}) + for (let i=0;i{ + buildRepeat.lastBuildClick = mouseActions.calcCoords([X,Y],"BottomLeft") +}) + +FoEproxy.addRequestHandler("CityMapService","placeBuilding",(data)=>{ + if (MainParser.CityEntities[data.requestData[0].cityentity_id].type != "street") buildRepeat.click() +}) + +FoEproxy.addFoeHelperHandler('ReconstructionBuildingPlaced',(data)=>{ + if (MainParser.CityMapData[data.id].type != "street" && !data.last) buildRepeat.click() +}); + +let buildRepeat = { + lastBuildClick: null, + click: () => { + if(!Settings.GetSetting('RepeatSelectBuilding')) return; + mouseActions.randomClick(buildRepeat.lastBuildClick) + } +} + diff --git a/js/web/part-calc/css/part-calc.css b/js/web/part-calc/css/part-calc.css index 364eda9e9..f21623e62 100644 --- a/js/web/part-calc/css/part-calc.css +++ b/js/web/part-calc/css/part-calc.css @@ -358,11 +358,6 @@ color: var(--text-success); } -#PowerLevelingBox table.foe-table th { - position: sticky; - top: 0; -} - #PowerLevelingBox .hidden-text { opacity: 0; display: inline-block; diff --git a/js/web/part-calc/js/part-calc.js b/js/web/part-calc/js/part-calc.js index 39c177572..f6754faca 100644 --- a/js/web/part-calc/js/part-calc.js +++ b/js/web/part-calc/js/part-calc.js @@ -1532,7 +1532,7 @@ let Parts = { h.push('
' + i18n('Boxes.MarketOffers.Era') + '' + i18n('Boxes.MarketOffers.InventoryOfferSum') + '' + i18n('Boxes.MarketOffers.InventoryNeedSum') + '
' + i18n('Boxes.MarketOffersEvents.Date') + '' + i18n('Boxes.Market.RateColumn') + '' + i18n('Boxes.Market.PlayerColumn') + '
'); - h.push(''); + h.push(''); h.push(''); h.push(''); h.push(''); diff --git a/js/web/popgame/css/popgame.css b/js/web/popgame/css/popgame.css index 56eae4534..0ccbf06d3 100644 --- a/js/web/popgame/css/popgame.css +++ b/js/web/popgame/css/popgame.css @@ -34,7 +34,7 @@ } #PGwrapper.wildlife { position: relative; - top: calc(50% - 226px); + top: calc(50% - 225px); left: calc(50% - 260px); } #PGwarning { diff --git a/js/web/popgame/js/popgame.js b/js/web/popgame/js/popgame.js index a5bd9a427..f74871867 100644 --- a/js/web/popgame/js/popgame.js +++ b/js/web/popgame/js/popgame.js @@ -56,25 +56,12 @@ FoEproxy.addHandler('RewardService', 'collectReward', (data, postData) => { }); -$('#container').on("click", function (e) { - if ($('#Popgame').length === 0) return; - if (Popgame.rewardactive==0) return; - - let X=e.clientX, - Y=e.clientY, - Xc = window.innerWidth/2, - Yc = window.innerHeight/2; - - if (X>Xc-313 && XYc-324 && (XXc+73 || YYc+172)) return; - - if (Popgame.rewardactive > 0) Popgame.rewardactive -= 1; - if ($('#Popgame.closed').length === 0) return; - if (Popgame.rewardactive!==0) return; - if (Popgame.minimized) return; - $('#Popgame').addClass("open"); - $('#Popgame').removeClass("closed"); -}); - +mouseActions.addAction([[-57, 151, 'Center'],[72, 173, 'Center']],()=>{ + Popgame.clearReward() +}) +mouseActions.addAction([[284, 297, 'Center'],[-312, -337, 'Center'],false],()=>{ + Popgame.clearReward() +}) FoEproxy.addHandler('PopGameService', 'popTile', (data, postData) => { if ($('#Popgame').length === 0) return; @@ -315,6 +302,18 @@ let Popgame = { Popgame.grid[x][y] = tile.type + ((tile.popType === "default" || tile.type === "grandPrize") ? "" : "_reward"); } }, + clearReward:()=>{ + if ($('#Popgame').length === 0) return; + if (Popgame.rewardactive==0) return; + + if (Popgame.rewardactive > 0) Popgame.rewardactive -= 1; + if ($('#Popgame.closed').length === 0) return; + if (Popgame.rewardactive!==0) return; + if (Popgame.minimized) return; + $('#Popgame').addClass("open"); + $('#Popgame').removeClass("closed"); + }, + tracking: null, trackingReset:()=>{ Popgame.tracking = {start:{total:0,grandPrize:0},afterPop:{total:0,grandPrize:0},leftOnBoard:{grandPrize:0}}; diff --git a/js/web/productions/css/productions.css b/js/web/productions/css/productions.css index a0c043ba0..07cbc576e 100644 --- a/js/web/productions/css/productions.css +++ b/js/web/productions/css/productions.css @@ -57,8 +57,6 @@ background-color: #3f2a1b; color: var(--text-bright); padding-top: 15px; - position: sticky; - top: 0; } #Productions #ProductionsBody table tr.highlight-row { background-color: rgba(40, 18, 7, 0.8); @@ -72,8 +70,6 @@ line-height: 18px; } #Productions #ProductionsBody table thead { - position: sticky; - top: 0; background-color: rgba(0, 0, 0, 0.35); } #Productions #ProductionsBody table thead th small { @@ -118,6 +114,12 @@ #Productions #ProductionsBody .tabs ul li a span, #Productions th.boost span { background: transparent url('../images/productions.png') -233px 2px no-repeat; } +#Productions #ProductionsBody .tabs ul li.forge_points_production, #Productions #ProductionsBody .tabs ul li.coin_production, #Productions #ProductionsBody .tabs ul li.supply_production { + display: none; +} +#Productions #ProductionsBody .btn-tight.typeBoost { + border-radius: 3px; +} #Productions th.boost span { height: 25px; display: block; @@ -144,6 +146,17 @@ background-repeat: no-repeat; background-position: center center, -312px 0px; } +#ProductionsRatingBody.tilevalues .buildingvalue { + display: none; +} +#ProductionsRatingBody:not(.tilevalues) .tilevalue { + display: none; +} + +#ProductionsRatingBody.showitems .items { + display: none; +} + #ProductionsRating #ProductionsRatingBody span.resicon.def_boost_attacker-guild_expedition { background-position: center center, -366px 0px; } @@ -153,6 +166,9 @@ #ProductionsRating #ProductionsRatingBody span.resicon.def_boost_defender-guild_expedition { background-position: center center, -391px 0px; } +#ProductionsRating #ProductionsRatingBody span.resicon.fsp { + background-position: -762px 0px; +} #ProductionsRating #ProductionsRatingBody th i { display: block; } @@ -270,10 +286,18 @@ color: var(--text-bright); font-weight: 600; } -#ProductionsRating #ProductionsRatingBody tr.highlighted-explained, #ProductionsRating #ProductionsRatingBody .only-highlighted tr { +#ProductionsRating #ProductionsRatingBody tr.highlighted-explained, +#ProductionsRating .showhighlighted tbody tr { display: none; } -#ProductionsRating #ProductionsRatingBody tr.highlighted-explained.highlighted-explained, #ProductionsRating #ProductionsRatingBody .only-highlighted tr.highlighted-explained, #ProductionsRating #ProductionsRatingBody tr.highlighted-explained.highlighted, #ProductionsRating #ProductionsRatingBody .only-highlighted tr.highlighted, #ProductionsRating #ProductionsRatingBody tr.highlighted-explained.highlighted2, #ProductionsRating #ProductionsRatingBody .only-highlighted tr.highlighted2, #ProductionsRating #ProductionsRatingBody tr.highlighted-explained.additional, #ProductionsRating #ProductionsRatingBody .only-highlighted tr.additional { +#ProductionsRating #ProductionsRatingBody tr.highlighted-explained.highlighted-explained, +#ProductionsRating #ProductionsRatingBody tr.highlighted-explained.highlighted, +#ProductionsRating #ProductionsRatingBody tr.highlighted-explained.highlighted2, +#ProductionsRating #ProductionsRatingBody tr.highlighted-explained.additional, +#ProductionsRating .showhighlighted tbody tr.highlighted-explained, +#ProductionsRating .showhighlighted tbody tr.highlighted, +#ProductionsRating .showhighlighted tbody tr.highlighted2, +#ProductionsRating .showhighlighted tbody tr.additional { display: table-row; } #ProductionsRating #ProductionsRatingBody tr.highlighted-explained td { @@ -451,9 +475,7 @@ float: right; margin-right: 5px; } -#ProductionsRating #ProductionsRatingBody .tilevalue { - display: none; -} + input[id*="ProdPerTile"] { width: 100px; } @@ -463,10 +485,7 @@ input[id*="ProdPerTile"] { } #ProductionsRating #ProductionsRatingBody table thead { font-size: 85%; - position: sticky; - top: 0; cursor: pointer; - z-index: 1; } #ProductionsRating #ProductionsRatingBody table td { font-size: 85%; @@ -554,3 +573,38 @@ input[id*="ProdPerTile"] { #ProductionsRating #ProductionsRatingBody span.resicon.goods-previous { background-position: -524px 2px; } +#ItemSources { + height: 500px; +} +#ItemSourcesBody div { + overflow-y: auto; + height: 100%; +} +#ItemSourcesBody img { + width: 25px; +} +#ItemSourcesBody table { + width: 100%; +} +#ItemSourcesBody td { + background-image: url('../../../../css/images/hud/chevron-down.svg'); + background-size: 20px 20px; + background-position: right 5px; + background-repeat: no-repeat; +} +#ItemSourcesBody td.open { + background-image: url('../../../../css/images/hud/chevron-left.svg'); +} +#ItemSourcesBody td:hover { + cursor: url('../../../../css/images/cursor_hover.cur'), auto; +} +#ItemSourcesBody .filterTable { + float: right; +} +#ItemSourcesBody .innerTable { + background: var(--text-darker); + margin: 0 -5px; +} +#ItemSourcesBody .innerTable:not(:empty) { + margin-top: 5px; +} \ No newline at end of file diff --git a/js/web/productions/images/productions.png b/js/web/productions/images/productions.png index 2e4d8f1e6..b69a402c3 100644 Binary files a/js/web/productions/images/productions.png and b/js/web/productions/images/productions.png differ diff --git a/js/web/productions/js/productions.js b/js/web/productions/js/productions.js index b358cf4fd..31485222a 100644 --- a/js/web/productions/js/productions.js +++ b/js/web/productions/js/productions.js @@ -26,10 +26,13 @@ let Productions = { Types: [ 'strategy_points', // Forge Points + 'forge_points_production', // FP Boost 'goods', // Goods and special goods 'items', // Fragments, blueprints, boosts etc 'money', // Coins + 'coin_production', // Coin Boost 'supplies', + 'supply_production', // Supply Boost 'medals', 'premium', // Diamonds 'population', @@ -64,42 +67,73 @@ let Productions = { 'generic_building' ], - RatingCurrentTab: 'Settings', - Rating: JSON.parse(localStorage.getItem('ProductionRatingEnableds2')||"{}"), - RatingProdPerTiles: {}, - - RatingTypes: [ - 'strategy_points', // Forge Punkte - 'money', // Münzen - 'supplies', // Werkzeuge - 'medals', // Medaillien - 'clan_power', // Macht der Gilde - 'clan_goods', // Gildengüter (Arche, Ehrenstatue etc.) - 'population', // Bevölkerung - 'happiness', // Zufriedenheit - 'units', // Einheiten - 'att_boost_attacker-all', //Angriffsbonus angreifende Armee - 'att_boost_attacker-guild_expedition', - 'att_boost_attacker-battleground', - 'att_boost_attacker-guild_raids', - 'def_boost_attacker-all', //Verteidigungsbonus angreifende Armee - 'def_boost_attacker-guild_expedition', - 'def_boost_attacker-battleground', - 'def_boost_attacker-guild_raids', - 'att_boost_defender-all', //Angriffsbonus verteidigenden Armee - 'att_boost_defender-guild_expedition', - 'att_boost_defender-battleground', - 'att_boost_defender-guild_raids', - 'def_boost_defender-all', //Verteidigungsbonus verteidigenden Armee - 'def_boost_defender-guild_expedition', - 'def_boost_defender-battleground', - 'def_boost_defender-guild_raids', - 'goods-previous', - 'goods-current', - 'goods-next', - ], + RatingCurrentTab: 'Results', + fragmentsSet: new Set(), - + efficiencySettings:Object.assign(JSON.parse(localStorage.getItem("Productions.efficiencySettings")||`{"tilevalues":false,"showitems":true,"showhighlighted":false}`),{showhighlighted:false}), + + Rating: { + Data:null, + Types:null, + load: (overwrite=null) => { + Productions.Rating.Data = Object.assign({ + 'strategy_points': {order:1,perTile:5,active:true}, + 'money': {order:2,perTile:null,active:false}, + 'supplies': {order:3,perTile:null,active:false}, + 'medals': {order:4,perTile:null,active:false}, + 'clan_power': {order:5,perTile:null,active:false}, + 'clan_goods': {order:6,perTile:10,active:true}, + 'population': {order:7,perTile:null,active:false}, + 'happiness': {order:8,perTile:null,active:false}, + 'units': {order:9,perTile:1,active:true}, + 'att_boost_attacker-all': {order:10,perTile:3,active:true} , + 'att_boost_attacker-guild_expedition': {order:11,perTile:null,active:false}, + 'att_boost_attacker-battleground': {order:12,perTile:3,active:true} , + 'att_boost_attacker-guild_raids': {order:13,perTile:null,active:false}, + 'def_boost_attacker-all': {order:14,perTile:3,active:true}, + 'def_boost_attacker-guild_expedition': {order:15,perTile:null,active:false}, + 'def_boost_attacker-battleground': {order:16,perTile:3,active:true} , + 'def_boost_attacker-guild_raids': {order:17,perTile:null,active:false}, + 'att_boost_defender-all': {order:18,perTile:2,active:true}, + 'att_boost_defender-guild_expedition': {order:19,perTile:null,active:false}, + 'att_boost_defender-battleground': {order:20,perTile:null,active:false}, + 'att_boost_defender-guild_raids': {order:21,perTile:null,active:false}, + 'def_boost_defender-all': {order:22,perTile:2,active:true}, + 'def_boost_defender-guild_expedition': {order:23,perTile:null,active:false}, + 'def_boost_defender-battleground': {order:24,perTile:null,active:false}, + 'def_boost_defender-guild_raids': {order:25,perTile:null,active:false}, + 'goods-previous': {order:26,perTile:4,active:true}, + 'goods-current': {order:27,perTile:5,active:true}, + 'goods-next': {order:28,perTile:null,active:false}, + 'fsp': {order:29,perTile:1,active:true}, + }, overwrite || JSON.parse(localStorage.getItem('Productions.Rating.Data')||"{}")) + Productions.Rating.Types = Object.keys(Productions.Rating.Data).sort((a,b)=>Productions.Rating.Data[a].order-Productions.Rating.Data[b].order) + + + //conversion of old data - remove at some point------------------------------------ + if (localStorage.getItem('ProductionRatingEnableds2')) { + let Rating = JSON.parse(localStorage.getItem('ProductionRatingEnableds2')||"{}") + for (let [type,active] of Object.entries(Rating)) { + if (Productions.Rating.Data[type]) Productions.Rating.Data[type].active = active + } + localStorage.removeItem('ProductionRatingEnableds2') + Productions.Rating.save() + } + if (localStorage.getItem('ProductionRatingProdPerTiles')) { + let RatingProdPerTiles = Object.assign({},JSON.parse(localStorage.getItem('ProductionRatingProdPerTiles')||"{}")) + for (let [type,perTile] of Object.entries(RatingProdPerTiles)) { + if (Productions.Rating.Data[type]) Productions.Rating.Data[type].perTile = perTile + } + localStorage.removeItem('ProductionRatingProdPerTiles') + Productions.Rating.save() + } + //------------------------------------------------------------------------------ + }, + save:() => { + localStorage.setItem('Productions.Rating.Data', JSON.stringify(Productions.Rating.Data)) + } + + }, init: () => { if (CityMap.IsExtern) return @@ -262,6 +296,7 @@ let Productions = { Productions.BuildingsProducts["goods"].push(saveBuilding) } if (production.type == "resources") { + let types = Object.keys(production.resources) if (production.resources.money) { if (Productions.BuildingsProducts.money.find(x => x.id == building.id) == undefined) Productions.BuildingsProducts["money"].push(saveBuilding) @@ -281,7 +316,7 @@ let Productions = { if (Productions.BuildingsProducts.strategy_points.find(x => x.id == building.id) == undefined) Productions.BuildingsProducts["strategy_points"].push(saveBuilding) } - if (production.resources.all_goods_of_age || production.resources.random_goods_of_age || production.resources.random_good_of_age || production.resources.all_goods_of_previous_age) { + if (types.find(x => x.includes('random_good_of_') || x.includes('all_goods_of_'))) { if (Productions.BuildingsProducts.goods.find(x => x.id == building.id) == undefined) Productions.BuildingsProducts["goods"].push(saveBuilding) } @@ -290,10 +325,6 @@ let Productions = { if (Productions.BuildingsProducts.items.find(x => x.id == building.id) == undefined) Productions.BuildingsProducts["items"].push(saveBuilding) } - if (production.resources?.icon == "next_age_goods") { - if (Productions.BuildingsProducts.goods.find(x => x.id == building.id) == undefined) - Productions.BuildingsProducts["goods"].push(saveBuilding) - } }) } if (building.state.production) { @@ -375,29 +406,48 @@ let Productions = { $("#Productions #"+type).html(firstTabContent) // fill other tables on demand - $('.production-tabs li').click(function() { + $('.production-tabs li, #Productions .typeBoost').click(function() { let type = $("a", this).attr("href").replace("#","") if ($("#Productions #"+type).html().length === 0) { let content = Productions.buildTableByType(type) - $("#Productions #"+type).html(content) - $('.TSinactive').tableSorter() - $('.TSinactive').removeClass('TSinactive') - Productions.filterTable('#Productions .filterCurrentList') + $("#Productions #"+type).html(content).promise().done(() => { + + $('#Productions .typeBoost').click(function(e) { + e.preventDefault() + let type = $("a", this).attr("href").replace("#","") + + if ($("#Productions #"+type).html().length === 0) { + let content = Productions.buildTableByType(type) + $("#Productions #"+type).html(content) + $('.TSinactive').tableSorter() + $('.TSinactive').removeClass('TSinactive') + HTML.FilterTable('#Productions .filterCurrentList') + } + $("#Productions .content").css('display','none') + $("#Productions #"+type).css('display','block') + }); + + }) + $('.TSinactive').tableSorter() + $('.TSinactive').removeClass('TSinactive') + HTML.FilterTable('#Productions .filterCurrentList') } + $("#Productions .content").css('display','none') + $("#Productions #"+type).css('display','block') }); // extra functionality $('.production-tabs').tabslet({ active: Productions.ActiveTab }) $('.TSinactive').tableSorter() $('.TSinactive').removeClass('TSinactive') - Productions.filterTable('#Productions .filterCurrentList') + HTML.FilterTable('#Productions .filterCurrentList') // show a building on the map $('#Productions').on('click', '.foe-table .show-entity', function () { Productions.ShowOnMap($(this).data('id')); }); - }); + }); }, setChainsAndSets(buildings) { @@ -426,35 +476,13 @@ let Productions = { } }, - filterTable: (selector) => { - $(selector).on('keyup', function (e) { - let filter = $(this).val().toLowerCase() - let table = $(this).parents("table") - if (filter.length >= 2) { - $("tbody tr", table).hide() - $("tbody tr", table).filter(function() { - let foundText = ($(this).text().toLowerCase().indexOf(filter) > -1) - if (foundText) - $(this).show() - }); - } - else { - $("tbody tr", table).show() - } - }); - }, - buildQITable(type) { let table = [], tableGr = [], rowA = [], - groupedBuildings = [], boostCounter = {}, - typeSum = 0, - amount = 0, boosts = {}, - buildingIds = Productions.BuildingsProducts[type], - Sum = {} + buildingIds = Productions.BuildingsProducts[type] buildingIds.forEach(b => { let building = CityMap.getBuildingById(b.id) @@ -467,7 +495,7 @@ let Productions = { if (building.chainBuilding !== undefined) rowA.push('') rowA.push('') - rowA.push('') + rowA.push('') if (building.boosts !== undefined) { boosts = {} @@ -487,26 +515,12 @@ let Productions = { for (let type of Object.keys(MainParser.BoostSums)) { if (type.includes('guild_raids')) { if (boosts[type] != undefined) - rowA.push('') + rowA.push('') else - rowA.push('') + rowA.push('') } } } - /* - let updateGroup = groupedBuildings.find(x => x.building.name == building.name) - if (updateGroup == undefined) { - groupedBuildings.push({ - building: building, - amount: 1, - values: amount, - boosts: boosts, - }) - } - else { - updateGroup.amount++ - updateGroup.values += amount - }*/ rowA.push('') rowA.push('
' + i18n('Boxes.PowerLeveling.Level') + '' + i18n('Boxes.PowerLeveling.P1') + '' + building.name + '' + building.name + ''+ HTML.Format(boosts[type]) +''+ HTML.Format(boosts[type]) +'--' + i18n("Eras."+Technologies.Eras[building.eraName]+".short") + '') @@ -518,7 +532,7 @@ let Productions = { if (rowA.length > 0) { table.push('') - table.push('') + table.push('') table.push('') table.push('') table.push('') @@ -591,22 +605,22 @@ let Productions = { if (!type.includes('att') && !type.includes('def')) { if (type != 'items') { - let productionByCategoryTrue=Productions.getBuildingProductionByCategory(true, building, type) - let productionByCategoryFalse=Productions.getBuildingProductionByCategory(false, building, type) - currentAmount = parseFloat(productionByCategoryTrue.amount) - amount = parseFloat(productionByCategoryFalse.amount) - hasRandomProductions = productionByCategoryFalse.hasRandomProductions - let doubled = productionByCategoryFalse.doubleWhenMotivated - - if (type == 'money' && building.type != "greatbuilding" && building.type != "main_building") { + let currentProductionByCategory = Productions.getBuildingProductionByCategory(true, building, type) + let generalProductionByCategory = Productions.getBuildingProductionByCategory(false, building, type) + currentAmount = parseFloat(currentProductionByCategory.amount) + amount = parseFloat(generalProductionByCategory.amount) + hasRandomProductions = generalProductionByCategory.hasRandomProductions + let doubled = generalProductionByCategory.doubleWhenMotivated + + if (type == 'money' && building.isBoostable) { amount = Math.round(amount + (amount * ((MainParser.BoostSums.coin_production + (Productions.HappinessBoost * 100)) / 100))) * (doubled ? 2 : 1) currentAmount = Math.round(currentAmount + (currentAmount * ((MainParser.BoostSums.coin_production + (Productions.HappinessBoost * 100)) / 100))) } - else if (type == 'supplies' && building.type != "greatbuilding") { + else if (type == 'supplies' && building.isBoostable) { amount = Math.round(amount + (amount * ((MainParser.BoostSums.supply_production + (Productions.HappinessBoost * 100)) / 100))) * (doubled ? 2 : 1) currentAmount = Math.round(currentAmount + (currentAmount *((MainParser.BoostSums.supply_production + (Productions.HappinessBoost * 100)) / 100))) } - else if (type == 'strategy_points' && building.type != "greatbuilding" && building.type != "main_building" && !building.entityId.includes("CastleSystem")) { + else if (type == 'strategy_points' && building.isBoostable) { amount = Math.round(amount + (amount *((MainParser.BoostSums.forge_points_production) / 100))) currentAmount = Math.round(currentAmount + (currentAmount *((MainParser.BoostSums.forge_points_production) / 100))) } @@ -615,15 +629,15 @@ let Productions = { let parsedCurrentAmount = (currentAmount >= 10000 ? HTML.FormatNumberShort(currentAmount) : HTML.Format(currentAmount)) let parsedAmount = (currentAmount >= 10000 ? HTML.FormatNumberShort(amount) : HTML.Format(amount)) - if (productionByCategoryFalse.units.length>0 || productionByCategoryTrue.units.length>0) { - if (productionByCategoryTrue.units.length > 0) - rowA.push(productionByCategoryTrue.units.map(x=>`${x.amount} `).join(" ")) + if (generalProductionByCategory.units.length>0 || currentProductionByCategory.units.length>0) { + if (currentProductionByCategory.units.length > 0) + rowA.push(currentProductionByCategory.units.map(x=>`${x.amount} `).join(" ")) else rowA.push(" - ") rowA.push(" / ") - if (productionByCategoryFalse.units.length > 0) - rowA.push(productionByCategoryFalse.units.map(x=>`${x.amount?x.amount:""}${x.amount && x. random ? "+":""}${x.random ? "Ø"+x.random:""} `).join(" ")) + if (generalProductionByCategory.units.length > 0) + rowA.push(generalProductionByCategory.units.map(x=>`${x.amount?x.amount:""}${x.amount && x. random ? "+":""}${x.random ? "Ø"+x.random:""} `).join(" ")) else rowA.push(" - ") } else { @@ -631,7 +645,7 @@ let Productions = { if (currentAmount < amount && building.type != 'production') rowA.push(parsedCurrentAmount + ' / ' + (hasRandomProductions ? 'Ø' : '') + parsedAmount) else { - unitType = productionByCategoryTrue.type + unitType = currentProductionByCategory.type if (unitType != null){ rowA.push(' ') } @@ -643,7 +657,7 @@ let Productions = { typeSum += amount typeCurrentSum += currentAmount - for (let u of productionByCategoryFalse.units) { + for (let u of generalProductionByCategory.units) { if (u.type.includes("next")) { a=a+1 } @@ -659,7 +673,7 @@ let Productions = { Sum[n] = {current:null,theory:u} } } - for (let u of productionByCategoryTrue.units) { + for (let u of currentProductionByCategory.units) { if (u.type.includes("next")) { a=a+1 } @@ -771,18 +785,25 @@ let Productions = { if (rowA.length > 0) { table.push('
') - table.push('') + table.push('') table.push('') table.push('') if (!type.includes('att') && !type.includes('def') && type!='items') { table.push('') } else { - table.push('') + table.push('') } table.push('') table.push('') @@ -879,7 +900,7 @@ let Productions = { building: building, amount: 1, } - for (era of eras) { + for (let era of eras) { gBuilding[era] = 0 } updateGroup = gBuilding @@ -891,14 +912,14 @@ let Productions = { let currentGoods = Productions.getBuildingProductionByCategory(true, building, type) let allGoods = Productions.getBuildingProductionByCategory(false, building, type) - + eras.forEach(era => { let currentGoodAmount = 0 let goodAmount = 0 if (allGoods != undefined) { erasCurrent[era] += currentGoodAmount = currentGoods?.eras?.[era] || 0 erasTotal[era] += goodAmount = allGoods?.eras?.[era] || 0 - updateGroup[era] += goodAmount = allGoods?.eras?.[era] || 0 + updateGroup[era] += goodAmount } rowA.push('
' + i18n('Boxes.Productions.ModeGroups') + ' ') table.push((typeCurrentSum >= 10000 ? HTML.FormatNumberShort(typeCurrentSum) : HTML.Format(typeCurrentSum))+ "/" + (typeSum >= 10000 ? HTML.FormatNumberShort(typeSum) : HTML.Format(typeSum))) - if (type == 'strategy_points') - table.push(' · '+i18n('General.Boost')+': '+MainParser.BoostSums.forge_points_production+'%') + if (type == 'strategy_points') { + table.push(' ') + } + else if (type == 'money') { + table.push(' ') + } + else if (type == 'supplies') { + table.push(' ') + } table.push(''+(type=="items" ? ''+i18n('Boxes.ItemSources.Title')+'' : '')+'
') if (currentGoodAmount != goodAmount) { @@ -937,10 +958,10 @@ let Productions = { // single view table table.push('') - table.push('') + table.push('') table.push('') table.push('') - table.push('') + table.push(``) table.push('') table.push('') table.push('') @@ -961,9 +982,10 @@ let Productions = { // grouped view table.push('
' + i18n('Boxes.Productions.ModeGroups') + ' ${HTML.Format(Object.values(erasCurrent).reduce((a,b)=>a+b))}/${HTML.Format(Object.values(erasTotal).reduce((a,b)=>a+b))}
') - table.push('') + table.push('') table.push('') - table.push('') + table.push('') + table.push(``) table.push('') table.push('') table.push('') @@ -998,7 +1020,7 @@ let Productions = { buildGroupedTable: (type, groupedBuildings, boostCounter) => { let tableGr = [], rowB = [] tableGr.push('
' + i18n('Boxes.Productions.ModeSingle') + '' + i18n('Boxes.Productions.ModeSingle') + '${HTML.Format(Object.values(erasCurrent).reduce((a,b)=>a+b))}/${HTML.Format(Object.values(erasTotal).reduce((a,b)=>a+b))}
' + i18n('Boxes.Productions.Headings.number') + '
') - tableGr.push('') + tableGr.push('') tableGr.push('') tableGr.push('') tableGr.push('') @@ -1059,7 +1081,7 @@ let Productions = { } table.push('
' + (type=="items" || type=="units" ?i18n('Boxes.Productions.ModeSum') : i18n('Boxes.Productions.ModeSingle')) + '
') - table.push('') + table.push('') table.push('') table.push('') table.push('') @@ -1096,7 +1118,7 @@ let Productions = { let prod = { amount: 0, type: null, // units - units:[], + units: [], hasRandomProductions: false, doubleWhenMotivated: false } @@ -1182,6 +1204,9 @@ let Productions = { if (category == "goods") { return CityMap.getBuildingGoodsByEra(current, building) } + if (category == "forge_points_production" || category == "coin_production" || category == "supply_production") { + prod.amount = building.boosts.filter(x => x.type[0] == category)[0].value // not really rock solid like this + } return prod }, @@ -1195,7 +1220,7 @@ let Productions = { if (production.type == "genericReward") { if (production.resources?.icon.includes("good")) return false let frag = production.resources.subType == "fragment" - allItems += production.resources.amount + "x " + (frag ? "🧩 " : "" ) + production.resources.name + "
" + allItems += ''+production.resources.amount + "x " + (frag ? "🧩 " : "" ) + production.resources.name + "
" itemArray.push({fragment:frag,name:production.resources.name,amount:production.resources.amount,random:0}) } }) @@ -1211,7 +1236,7 @@ let Productions = { if (resource.type == "unit") { allUnits += "Ø " + amount + "x " + (frag ? "🧩 " : "" ) + `` + "
" } else { - allItems += "Ø " + amount + "x " + (frag ? "🧩 " : "" ) + resource.name + "
" + allItems += "Ø " + amount + "x " + (frag ? "🧩 " : "" ) + resource.name + "
" itemArray.push({fragment:frag,name:resource.name,amount:0,random:amount}) } } @@ -1223,8 +1248,10 @@ let Productions = { } } if (production.resources?.type == "consumable") { + let itemId = production.resources.id.split('#')[1] + itemId = (itemId == undefined) ? '' : itemId let frag = production.resources.subType == "fragment" - allItems += production.resources.amount + "x " + (frag ? "🧩 " : "" ) + production.resources.name + "
" + allItems += ``+production.resources.amount + "x " + (frag ? "🧩 " : "" ) + production.resources.name + "
" itemArray.push({fragment:frag,name:production.resources.name,amount:production.resources.amount,random:0}) } }) @@ -1277,7 +1304,7 @@ let Productions = { // ab dem zweiten Eintrag verstecken let style = Productions.TabsContent.length > 0 ? ' style="display:none"' : ''; - Productions.TabsContent.push('
' + content + '
'); + Productions.TabsContent.push('
' + content + '
'); }, /** @@ -1413,6 +1440,9 @@ let Productions = { } else if (GoodType === 'items') { return i18n('Boxes.Productions.fragments'); + } + else if (GoodType === 'fsp') { + return i18n('Boxes.Productions.FSP'); } else { if(GoodType && GoodsData[GoodType]){ @@ -1424,25 +1454,16 @@ let Productions = { }, - ShowRating: (external = false) => { + ShowRating: (external = false, eraName = null) => { + if (!Productions.Rating.Data) Productions.Rating.load() if (CityMap.IsExtern && !external) return + let era = (eraName == null) ? CurrentEra : eraName if ($('#ProductionsRating').length === 0) { Productions.BuildingsAll = Object.values(CityMap.createNewCityMapEntities()) Productions.setChainsAndSets(Productions.BuildingsAll) - let Rating = localStorage.getItem('ProductionRatingEnableds2'); - if (Rating !== null) Productions.Rating = JSON.parse(Rating) - - let RatingProdPerTiles = localStorage.getItem('ProductionRatingProdPerTiles'); - if (RatingProdPerTiles !== null) Productions.RatingProdPerTiles = JSON.parse(RatingProdPerTiles); - - for (let type of Productions.RatingTypes) { - if (Productions.Rating[type] === undefined) Productions.Rating[type] = true - if (Productions.RatingProdPerTiles[type] === undefined) Productions.RatingProdPerTiles[type] = Productions.GetDefaultProdPerTile(type) - } - HTML.Box({ id: 'ProductionsRating', title: i18n('Boxes.ProductionsRating.Title'), @@ -1458,23 +1479,30 @@ let Productions = { Productions.CalcRatingBody(); }); + $('#ProductionsRating').on('click', '.reset-button', function () { + if (window.confirm(i18n('Boxes.ProductionsRating.ConfirmReset'))) { + Productions.Rating.load("{}") + Productions.Rating.save() + Productions.CalcRatingBody(); + } + }); } else { HTML.CloseOpenBox('ProductionsRating'); } - Productions.CalcRatingBody(); + Productions.CalcRatingBody(era); }, //AdditionalBuildings:[], AdditionalSpecialBuildings:null, - CalcRatingBody: () => { + CalcRatingBody: (era = '') => { if (!Productions.AdditionalSpecialBuildings) { let spB = Object.values(MainParser.CityEntities).filter(x=> (x.is_special && !["O_","U_","V_","H_","Y_"].includes(x.id.substring(0,2))) || x.id.substring(0,11)=="W_MultiAge_") Productions.AdditionalSpecialBuildings = {} for (x of spB) { - Productions.AdditionalSpecialBuildings[x.id] = {id:x.id,name:x.name,selected:false} + Productions.AdditionalSpecialBuildings[x.id] = {id:x.id,name:x.name,selected:false,filter:x.id+";"+x.name} } } let h = []; @@ -1490,21 +1518,21 @@ let Productions = { h.push('' + i18n('Boxes.ProductionsRating.ProdPerTile') + '') h.push('') - for (let type of Productions.RatingTypes) { + for (let type of Productions.Rating.Types) { h.push('
  • ') - let activeSetting = (Productions.RatingProdPerTiles[type] != null && Productions.Rating[type] != false) + let activeSetting = (Productions.Rating.Data[type].perTile != null && Productions.Rating.Data[type].active != false) h.push('') h.push('') h.push('') - if (Productions.RatingProdPerTiles[type] != null) { - h.push('') + if (Productions.Rating.Data[type].perTile != null) { + h.push('') } else { h.push('') } h.push('
  • ') } - h.push('
  • ' + i18n('Boxes.ProductionsRating.Results') + '
  • ') + h.push('
  • ' + i18n('Boxes.ProductionsRating.Results') + '' + i18n('Boxes.ProductionsRating.Reset') + '
  • ') h.push('') h.push('

    '+i18n('Boxes.ProductionsRating.Explainer')+'

    ') h.push('

    '+i18n('Boxes.ProductionsRating.Disclaimer')+'

    ') @@ -1540,7 +1568,7 @@ let Productions = { let selectedAdditionals = Object.values(Productions.AdditionalSpecialBuildings).filter(x=>x.selected).map(x=>x.id); - ratedBuildings = Productions.rateBuildings(uniqueBuildings).concat(Productions.rateBuildings(selectedAdditionals,true)) + ratedBuildings = Productions.rateBuildings(uniqueBuildings,false,era).concat(Productions.rateBuildings(selectedAdditionals,true,era)) ratedBuildings.sort((a, b) => { if (a.score < b.score) return -1 @@ -1548,17 +1576,12 @@ let Productions = { return 0 }) - let colNumber = 0 - for (let i = 0; i < Productions.RatingTypes.length; i++) { - let type = Productions.RatingTypes[i]; - if (!Productions.Rating[type]) continue; - colNumber++ - } + let colNumber = Object.values(Productions.Rating.Data).filter(x=>x.active && x.perTile!=null).length h.push('
    ' + i18n('Boxes.Productions.ModeSingle') + '
    '); - h.push(''); + h.push(''); h.push('') h.push(''); h.push(''); h.push(''); - let tileRatings = JSON.parse(localStorage.getItem('ProductionRatingProdPerTiles')) - for (const type of Productions.RatingTypes) { - if (!Productions.Rating[type] || Productions.RatingProdPerTiles[type] == null) continue - h.push(''); - h.push(''); + for (const type of Productions.Rating.Types) { + if (!Productions.Rating.Data[type].active || Productions.Rating.Data[type].perTile == null) continue + h.push(''); + h.push(''); } h.push(''); h.push(''); @@ -1587,7 +1609,7 @@ let Productions = { [randomItems,randomUnits]=Productions.showBuildingItems(false, building.building) h.push(``) h.push('') - h.push('') - for (const type of Productions.RatingTypes) { + for (const type of Productions.Rating.Types) { + if (!Productions.Rating.Data[type].active || Productions.Rating.Data[type].perTile == null) continue if (building[type] != undefined) { h.push(`'); + b.push(''); + b.push(''); + b.push(''); + b.push(''); + b.push(''); + b.push(''); + b.push(''); + + QiProgress.ProgressContent.push({ + player_id: playerNew.player_id, + player: playerNew.name, + actions: playerNew.actions, + progress: playerNew.progress + }) + } + + t.push('
    ') @@ -1572,11 +1595,10 @@ let Productions = { h.push('
    ' + i18n('Boxes.ProductionsRating.Score') + '' + i18n('Boxes.ProductionsRating.BuildingName') + ''+(tileRatings?.[type] !== undefined ? parseFloat(tileRatings[type]) : Productions.GetDefaultProdPerTile(type))+''+(tileRatings?.[type] !== undefined ? parseFloat(tileRatings[type]) : Productions.GetDefaultProdPerTile(type))+''+(Productions.Rating.Data[type].perTile || 0)+''+(Productions.Rating.Data[type].perTile || 0)+'Items
    '+Math.round(building.score * 100)+''+building.building.name) + h.push(''+building.building.name) let eraShortName = i18n("Eras."+Technologies.Eras[building.building.eraName]+".short") if (eraShortName != "-") h.push(" ("+i18n("Eras."+Technologies.Eras[building.building.eraName]+".short") +')') @@ -1595,7 +1617,8 @@ let Productions = { if (buildingCount[building.building.entityId]) h.push('' + buildingCount[building.building.entityId]+'x') if (!building.highlight) h.push(' ') h.push('`) h.push(HTML.Format(building[type])) @@ -1626,22 +1649,29 @@ let Productions = { else { h.push('Something went wrong'); } - + SaveSettings=(x)=>{ + Productions.efficiencySettings[x]=$('#'+x).is(':checked') + localStorage.setItem("Productions.efficiencySettings",JSON.stringify(Productions.efficiencySettings)) + if ($('#'+x).is(':checked')) { + $("#ProductionsRatingBody").addClass(x); + } else { + $("#ProductionsRatingBody").removeClass(x); + } + } $('#ProductionsRatingBody').html(h.join('')).promise().done(function () { $('.TSinactive').tableSorter() $('.TSinactive').removeClass('TSinactive') $('#tilevalues, label[tilevalues]').on('click', function () { - $("#ProductionsRatingBody .buildingvalue").toggle(); - $("#ProductionsRatingBody .tilevalue").toggle(); + SaveSettings("tilevalues") }); $('#showitems, label[showitems]').on('click', function () { - $("#ProductionsRatingBody table .items").toggle(); + SaveSettings("showitems") }); $('#showhighlighted, label[showhighlighted]').on('click', function () { - $("#ProductionsRatingBody tbody").toggleClass('only-highlighted'); + SaveSettings("showhighlighted") }); $('.show-all').on('click', function () { @@ -1663,9 +1693,6 @@ let Productions = { $(".ratingtable .highlighted td:nth-child(2)").each((x,el)=>{ marked.push(el.dataset.text) }) - tilevalues=$('#tilevalues').is(':checked') - showitems=$('#showitems').is(':checked') - showhighlighted=$('#showhighlighted').is(':checked') search=new RegExp($('#efficiencyBuildingFilter').val(),"i") Productions.CalcRatingBody() setTimeout(()=>{ @@ -1675,26 +1702,24 @@ let Productions = { } }) $('#efficiencyBuildingFilter').val(search.source=="(?:)"?"":search.source) - $('#efficiencyBuildingFilter').trigger("input") - if (tilevalues) $('#tilevalues').trigger("click") - if (showitems) $('#showitems').trigger("click") - if (showhighlighted) $('#showhighlighted').trigger("click") + $('#efficiencyBuildingFilter').trigger("input") },500) }) + if (Productions.efficiencySettings.tilevalues != $('#tilevalues').is(':checked')) $('#tilevalues').trigger("click") + if (Productions.efficiencySettings.showitems != $('#showitems').is(':checked')) $('#showitems').trigger("click") + if (Productions.efficiencySettings.showhighlighted != $('#showhighlighted').is(':checked')) $('#showhighlighted').trigger("click") + $('#findMetaBuilding').on('input', function () { let regEx=new RegExp($(this).val(),"i"); filterMeta(regEx) }); let filterMeta = (regEx) => { $('#ProductionsRatingBody .overlay .results').html("") - let foundBuildings = Object.values(Productions.AdditionalSpecialBuildings).filter(x => regEx.test(x.name) && x.selected).sort((a,b)=>(a.name>b.name?1:-1)) + let foundBuildings = Object.values(Productions.AdditionalSpecialBuildings).filter(x => regEx.test(x.filter)) + .sort((a,b)=>(((a.selected != b.selected) ? (a.selected ? -2 : 2) : 0)+(a.name>b.name?1:-1))) for (building of foundBuildings) { - $('#ProductionsRatingBody .overlay .results').append(`
  • ${building.name}
  • `) - } - foundBuildings = Object.values(Productions.AdditionalSpecialBuildings).filter(x => regEx.test(x.name) && !x.selected).sort((a,b)=>(a.name>b.name?1:-1)) - for (building of foundBuildings) { - $('#ProductionsRatingBody .overlay .results').append(`
  • ${building.name}
  • `) + $('#ProductionsRatingBody .overlay .results').append(`
  • ${building.name}
  • `) } } filterMeta(/./) @@ -1710,24 +1735,21 @@ let Productions = { elem.parent().children('input[type=number]').toggleClass('hidden') - Productions.Rating[type] = isChecked - localStorage.setItem('ProductionRatingEnableds2', JSON.stringify(Productions.Rating)) + Productions.Rating.Data[type].active = isChecked + if (isChecked) { - Productions.RatingProdPerTiles[type] = parseFloat(elem.parent().children('input[type=number]').val()) - if (isNaN(Productions.RatingProdPerTiles[type])) Productions.RatingProdPerTiles[type] = 0 - - localStorage.setItem('ProductionRatingProdPerTiles', JSON.stringify(Productions.RatingProdPerTiles)) + Productions.Rating.Data[type].perTile = parseFloat(elem.parent().children('input[type=number]').val()) || 0 } + Productions.Rating.save() }) $('#ProductionsRating input[type=number]').on('blur', function () { let elem = $(this) let type = elem.attr('id').replace('ProdPerTile-','') - Productions.RatingProdPerTiles[type] = parseFloat(elem.val()) - if (isNaN(Productions.RatingProdPerTiles[type])) Productions.RatingProdPerTiles[type] = 0 + Productions.Rating.Data[type].perTile = parseFloat(elem.val()) || 0 - localStorage.setItem('ProductionRatingProdPerTiles', JSON.stringify(Productions.RatingProdPerTiles)) + Productions.Rating.save() Productions.CalcRatingBody() }); @@ -1749,11 +1771,11 @@ let Productions = { }, - rateBuildings: (buildingType,additional=false) => { + rateBuildings: (buildingType,additional=false, era=null) => { + if (!Productions.Rating.Data) Productions.Rating.load() let ratedBuildings = [] - let tileRatings = JSON.parse(localStorage.getItem('ProductionRatingProdPerTiles')) if (additional) { - buildingType = buildingType.map(x=>CityMap.createNewCityMapEntity(x)) + buildingType = buildingType.map(x=>CityMap.createNewCityMapEntity(x,era||CurrentEra)) } for (const building of buildingType) { if (building.entityId.includes("L_AllAge_EasterBonus1") || building.entityId.includes("L_AllAge_Expedition16") || building.entityId.includes("L_AllAge_ShahBonus17") || (building.isSpecial == undefined && building.type != "greatbuilding")) continue // do not include wishingwell type buildings @@ -1763,9 +1785,9 @@ let Productions = { let ratedBuilding = { building: building } - for (const type of Object.keys(Productions.Rating)) { - if (Productions.Rating[type] != false) { - let desiredValuePerTile = ((tileRatings != null && tileRatings != undefined) ? parseFloat(tileRatings[type]) : Productions.GetDefaultProdPerTile(type)) + for (const type of Object.keys(Productions.Rating.Data)) { + if (Productions.Rating.Data[type].active) { + let desiredValuePerTile = parseFloat(Productions.Rating.Data[type].perTile) || 0 if (desiredValuePerTile !== null && !isNaN(desiredValuePerTile)) { let typeValue = Productions.getRatingValueForType(building, type) || 0 // production amount let valuePerTile = typeValue / size @@ -1828,6 +1850,31 @@ let Productions = { } } } + else if (type == "fsp") { + let fsp = 0 + if (building.production) { + let possibleProductions = building.production.filter(x => x.type == "genericReward").concat(building.production.filter(x => x.type == "random")) + let multiplier = 1 + for (let production of possibleProductions) { + if (production.type == "genericReward") { + if (!production.resources.id.includes('rush_event_buildings_instant')) continue + + if (production.resources.subType == 'rush_event_buildings_instant') + multiplier = 30 // 30, because 30 fragments are needed for one item + fsp = production.resources.amount * multiplier + } + else if (production.type == "random") { + let hasFsp = production.resources.filter(x => x.id?.includes('rush_event_buildings_instant')) + if (hasFsp.length === 0) continue + + if (hasFsp[0].subType == "instant_finish_building") + multiplier = 30 // 30, because 30 fragments are needed for one item + fsp = hasFsp[0].amount * hasFsp[0].dropChance * multiplier + } + } + } + return fsp + } else return 0 }, @@ -1846,41 +1893,6 @@ let Productions = { }) }, - - GetDefaultProdPerTile: (Type) => { - if (Type === 'strategy_points') return 5 - if (Type === 'money') return null - if (Type === 'supplies') return null - if (Type === 'medals') return null - if (Type === 'clan_power') return null - if (Type === 'clan_goods') return 10 - if (Type === 'population') return null - if (Type === 'happiness') return null - if (Type === 'units') return 1 - if (Type === 'att_boost_attacker-all') return 3 - if (Type === 'att_boost_attacker-guild_expedition') return null - if (Type === 'att_boost_attacker-battleground') return 3 - if (Type === 'att_boost_attacker-guild_raids') return null - if (Type === 'def_boost_attacker-all') return 3 - if (Type === 'def_boost_attacker-guild_expedition') return null - if (Type === 'def_boost_attacker-battleground') return 3 - if (Type === 'def_boost_attacker-guild_raids') return null - if (Type === 'att_boost_defender-all') return 2 - if (Type === 'att_boost_defender-guild_expedition') return null - if (Type === 'att_boost_defender-battleground') return null - if (Type === 'att_boost_defender-guild_raids') return null - if (Type === 'def_boost_defender-all') return 2 - if (Type === 'def_boost_defender-guild_expedition') return null - if (Type === 'def_boost_defender-battleground') return null - if (Type === 'def_boost_defender-guild_raids') return null - if (Type === 'goods-previous') return 4 - if (Type === 'goods-current') return 5 - if (Type === 'goods-next') return null - else return 0 - }, - - - /** * */ @@ -1919,5 +1931,73 @@ let Productions = { Productions.CalcBody() $(`#ProductionsSettingsBox`).remove() - }, + }, + + showItemSources:()=>{ + if ( $('#ItemSources').length === 0 ) { + HTML.Box({ + id: 'ItemSources', + title: i18n('Boxes.ItemSources.Title'), + auto_close: true, + dragdrop: true, + minimize: true, + resize: true + }); + } + + let items = Productions.buildingItemList() + + h = `
    + + + + + ` + for (let item of Object.values(items)) { + h += `` + } + h +=` +
    Items
    ${srcLinks.icons(item.icon)} ${item.name}
    +
    ` + $('#ItemSourcesBody').html(h) + $('#ItemSourcesBody .sortable-table').tableSorter() + HTML.FilterTable('#ItemSourcesBody .filterTable') + }, + + buildingItemList: () => { + let temp = Object.assign({},...Object.values(MainParser.CityEntities).filter(b=>b.id[0]=="W").map(x=>({[x.id]:[...JSON.stringify(x).matchAll(/"id":"([^"]*?)"[^()[\]{}]*?"name":"([^"]*?)"[^()[\]{}]*?"iconAssetName":"([^"]*?)"[^{}]*?"__class__":"GenericReward"/gm)].map(a=>({id:a[1],name:a[2],icon:a[3]}))}))) + let gl = Object.values(GoodsList).map(g=>g.id) + let items = {} + for (let [building,list] of Object.entries(temp)) { + for (let item of list) { + if (gl.includes(item.icon)) continue + if (["","icon_fragment"].includes(item.icon)) continue + if (/#\d+/.test(item.id)) { + item.id=item.id.replaceAll(/#\d+/g,'') + item.name=item.name.replaceAll(/\s?\d+\s?/g,'') + } + if (items[item.id]) { + if (!items[item.id].buildings.includes(building)) items[item.id].buildings.push(building) + } else { + items[item.id] = {name:item.name,buildings:[building],id:item.id,icon:item.icon} + } + } + } + return items + }, + + updateItemSources:(item)=>{ + let itemId = '#item-'+helper.str.cleanup(item.name) + $(itemId).parent('td').toggleClass('open') + if ($(itemId).html() != '') { + $(itemId).html('') + return + } + h=`
      ` + for (b of item.buildings) { + h+=`
    • ${MainParser.CityEntities[b].name}
    • ` + } + h+=`
    ` + $(itemId).html(h) + }, }; diff --git a/js/web/qiprogress/css/qiprogress.css b/js/web/qiprogress/css/qiprogress.css new file mode 100644 index 000000000..f63dd0315 --- /dev/null +++ b/js/web/qiprogress/css/qiprogress.css @@ -0,0 +1,32 @@ +#QiProgressList { + width: 570px; + height: 500px; +} + +#QiProgressListBody { + overflow: auto; +} + +#qi_roundswitch { + padding: 2px; +} + +#QiProgressTable img { + max-height: 25px; + border-radius: 2px; +} + +#QiProgressTable .tdmin { + width: 1%; + white-space: nowrap; +} + +#QiProgressPlayerDetails { + width: 400px; +} + +#QiProgressPlayerDetails .pname { + padding: 10px 5px; + color: var(--text-bright); + font-size: 1.0rem; +} \ No newline at end of file diff --git a/js/web/qiprogress/js/qiprogress.js b/js/web/qiprogress/js/qiprogress.js new file mode 100644 index 000000000..46bca8584 --- /dev/null +++ b/js/web/qiprogress/js/qiprogress.js @@ -0,0 +1,720 @@ +/* + * + * * ************************************************************************************** + * * Copyright (C) 2024 FoE-Helper team - All Rights Reserved + * * You may use, distribute and modify this code under the + * * terms of the AGPL license. + * * + * * See file LICENSE.md or go to + * * https://github.com/mainIine/foe-helfer-extension/blob/master/LICENSE.md + * * for full license details. + * * + * * ************************************************************************************** + * + */ + + +FoEproxy.addHandler('GuildRaidsService', 'getMemberActivityOverview', (data, postData) => { + QiProgress.HandleQiProgress(data.responseData.rows); +}); + +FoEproxy.addHandler('GuildRaidsService', 'getState', (data, postData) => { + QiProgress.GlobalRankingTimeout = setTimeout(()=>{ + if (data.responseData.__class__ == 'GuildRaidsRunningState') { + QiProgress.CurrentQISeason = data.responseData.endsAt + } + else if (data.responseData.__class__ == 'GuildRaidsPendingState') { + // 259200 = 3 days + QiProgress.CurrentQISeason = data.responseData.startsAt - 259200 + } + else if (data.responseData.__class__ == 'GuildRaidsFinishedState') { + QiProgress.CurrentQISeason = data.responseData.nextStartsAt - 259200 + } + + if (QiProgress.curDateFilter === null || QiProgress.curDateEndFilter === null) { + QiProgress.curDateFilter = moment.unix(QiProgress.CurrentQISeason).subtract(11, 'd').format('YYYYMMDD') + QiProgress.curDateEndFilter = moment.unix(QiProgress.CurrentQISeason).format('YYYYMMDD') + } + },500) +}); + +let QiProgress = { + ProgressListContent: [], + PrevAction: null, + PrevActionTimestamp: null, + NewAction: null, + NewActionTimestamp: null, + CurrentQISeason: null, // timestamp of round end + AllRounds: null, + ProgressContent: [], + curDateFilter: null, + curDateEndFilter: null, + GlobalRankingTimeout: null, + NewActionTimestamp: null, + HistoryView: false, + ProgressSettings: { + showRoundSelector: 1, + showProgressFilter: 1, + showOnlyActivePlayers: 0, + }, + + /** + * + * @returns {Promise} + */ + checkForDB: async (playerID) => { + const DBName = `FoeHelperDB_Qi_${playerID}`; + + QiProgress.db = new Dexie(DBName); + + QiProgress.db.version(1).stores({ + snapshots: '&[player_id+qiround+time],[qiround+player_id], [date+player_id], qiround', + history: '&qiround' + }); + + QiProgress.db.open(); + }, + + + /** + * Shows the player overview + */ + ShowProgressList: () => { + if ($('#QiProgressList').length === 0) { + + HTML.Box({ + id: 'QiProgressList', + title: i18n('Boxes.QiProgress.Title'), + auto_close: true, + dragdrop: true, + minimize: true, + resize: true, + settings: 'QiProgress.ShowSettings()' + }); + HTML.AddCssFile('qiprogress'); + } + + QiProgress.BuildProgressList(QiProgress.CurrentQISeason); + }, + + /** + * Built the player content content + * @param qiRound + * @returns {Promise} + */ + BuildProgressList: async (qiRound) => { + + let newRound = false; + let updateDetailView = false; + + await QiProgress.SetBoxNavigation(qiRound); + + let CurrentSnapshot = await QiProgress.db.snapshots + .where({ + qiround: QiProgress.CurrentQISeason + }) + .first(); + + if (CurrentSnapshot === undefined) { + newRound = true; + // if there is a new round delete previous snapshots + QiProgress.DeleteOldSnapshots(QiProgress.CurrentQISeason); + } + + let t = [], + b = [], + tA = 0, + tP = 0, + histView = false; + + QiProgress.ProgressContent = []; + + QiProgress.ProgressContent.push({ + player_id: 'player_id', + player: 'player', + actions: 'actions', + progress: 'progress', + }); + + if (qiRound && qiRound !== null && qiRound !== QiProgress.CurrentQISeason) { + let d = await QiProgress.db.history.where({ qiround: qiRound }).toArray(); + QiProgress.qiRound = d[0].participation?.sort(function (a, b) { + return a.rank - b.rank; + }); + histView = true; + } + else { + QiProgress.qiRound = QiProgress.NewAction; + } + + for (let i in QiProgress.qiRound) { + if (!QiProgress.qiRound.hasOwnProperty(i)) break; + + let playerNew = QiProgress.qiRound[i]; + + let newActions = '', + diffActions = 0, + newProgress = '', + diffProgress = 0, + newProgressClass = '', + change = false; + + // older snapshot available? + if (QiProgress.PrevAction !== null && histView === false) { + let playerOld = QiProgress.PrevAction.find(p => (p['player_id'] === playerNew['player_id'])); + + // any data on this player? + if (playerOld !== undefined) { + if (playerOld.actions < playerNew.actions) { + diffActions = playerNew.actions - playerOld.actions + newActions = ' ↑ ' + HTML.Format(diffActions) + ''; + change = true; + } + if (playerOld.progress < playerNew.progress) { + diffProgress = playerNew.progress - playerOld.progress + newProgress = ' ↑ ' + diffProgress + ''; + change = true; + } + } + } + + if ((change === true || newRound === true) && QiProgress.HistoryView === false) { + await QiProgress.UpdateDB('player', { + qiRound: QiProgress.CurrentQISeason, + player_id: playerNew.player_id, + name: playerNew.name, + actions: playerNew.actions, + progress: playerNew.progress, + diffActions: diffActions, + diffProgress: diffProgress, + time: moment().unix() + }); + updateDetailView = true; + } + + newProgressClass = change && !newRound ? 'new ' : ''; + + tA += playerNew.actions; + tP += playerNew.progress; + + b.push('
    ' + playerNew.player_id + '' + (parseInt(i) + 1) + '.' + playerNew.name + '' + HTML.Format(playerNew.actions) + newActions + '' + HTML.Format(playerNew.progress) + newProgress + '
    '); + t.push(''); + t.push(''); + t.push(''); + t.push(''); + t.push(''); + t.push(''); + t.push(''); + t.push(''); + + t.push(''); + t.push(b.join('')); + t.push(''); + + $('#qiContentWrapper').html(t.join('')).promise().done(function () { + + $('#QiProgressListBody tr.showdetailview').off('click').on('click', function () { + let player_id = $(this).data('player'); + let qiRound = $(this).data('qiround'); + + QiProgress.curDetailViewFilter = { content: 'player', player_id: player_id, qiround: qiRound }; + + if ($('#QiProgressDetailView').length === 0) { + QiProgress.ShowPlayerDetailsBox(QiProgress.curDetailViewFilter); + } + }); + + $("#QiProgress").on("remove", function () { + if ($('#QiProgressDetailView').length !== 0) { + $('#QiProgressDetailView').fadeOut(50, function () { + $(this).remove(); + }); + } + }); + + // check if member has a new progress + let newPlayerProgress = $('#QiProgressTable tbody').find('tr.new').length; + if (newPlayerProgress > 0) { + $('button#qi_filterProgressList').html('↑ ' + newPlayerProgress); + $('button#qi_filterProgressList').attr("disabled", false); + + if (QiProgress.ProgressSettings.showOnlyActivePlayers === 1) { + QiProgress.ToggleProgressList('qi_filterProgressList'); + } + } + }); + + if ($('#QiProgressHeader .title').find('.time-diff').length === 0) { + $('#QiProgressHeader .title').append($('').addClass('time-diff')); + } + + // es gibt schon einen Snapshot vorher + if (QiProgress.PrevActionTimestamp !== null) { + let start = moment.unix(QiProgress.PrevActionTimestamp), + end = moment.unix(QiProgress.NewActionTimestamp), + duration = moment.duration(end.diff(start)); + + let time = duration.humanize(); + + $('.time-diff').text( + HTML.i18nReplacer(i18n('Boxes.QiProgress.LastSnapshot'), { time: time }) + ); + } + }, + + + ProgressListSettingsSaveValues: () => { + QiProgress.ProgressSettings.showRoundSelector = $("#gf_showRoundSelector").is(':checked') ? 1 : 0; + QiProgress.ProgressSettings.showProgressFilter = $("#gf_showProgressFilter").is(':checked') ? 1 : 0; + + localStorage.setItem('QiProgressProgressSettings', JSON.stringify(QiProgress.ProgressSettings)); + + $(`#QiProgressListSettingsBox`).fadeToggle('fast', function () { + $(this).remove(); + QiProgress.BuildProgressList(QiProgress.CurrentQISeason); + }); + }, + + + /** + * Filters the list for players with new progress + */ + ToggleProgressList: (id) => { + let elem = $('#QiProgressTable > tbody'); + let nelem = elem.find('tr.new'); + let act = $('#' + id).hasClass('filtered') ? 'show' : 'hide'; + + if (act === 'hide') { + if (nelem.length !== 0) { + let oelem = elem.find('tr:not(.new)'); + QiProgress.ProgressSettings.showOnlyActivePlayers = 1; + localStorage.setItem('QiProgressProgressSettings', JSON.stringify(QiProgress.ProgressSettings)); + $('#QiProgressTable > thead .text-warning').hide(); + oelem.hide(); + $('#' + id).addClass('filtered btn-green'); + } + } + else if (act === 'show') { + elem.find('tr').show(); + QiProgress.ProgressSettings.showOnlyActivePlayers = 0; + localStorage.setItem('QiProgressProgressSettings', JSON.stringify(QiProgress.ProgressSettings)); + $('#QiProgressTable > thead .text-warning').show(); + $('#' + id).removeClass('filtered btn-green'); + } + }, + + ShowPlayerDetailsBox: (d) => { + if ($('#QiProgressPlayerDetails').length === 0) { + let ptop = null, + pright = null; + + HTML.Box({ + id: 'QiProgressPlayerDetails', + title: i18n('Boxes.QiProgress.SnapshotLog'), + auto_close: true, + dragdrop: true, + minimize: true, + resize: true + }); + + if (localStorage.getItem('QiProgressPlayerDetailsCords') === null) { + ptop = $('#QiProgress').length !== 0 ? $('#QiProgress').position().top : 0; + pright = $('#QiProgress').length !== 0 ? ($('#QiProgress').position().left + $('#QiProgress').width() + 10) : 0; + $('#QiProgressPlayerDetails').css('top', ptop + 'px').css('left', (pright * 1) + 'px'); + } + } + + QiProgress.BuildPlayerDetailContent(d); + }, + + + BuildPlayerDetailContent: async (d) => { + let player_id = d.player_id ? d.player_id : null, + content = d.content ? d.content : 'player', + qiround = d.qiround ? d.qiround : QiProgress.CurrentQISeason, + playerName = null, + dailyProgress = [], + detaildata = [], + h = []; + + if (player_id === null && content === "player") return; + + if (content === "player") { + detaildata = await QiProgress.db.snapshots.where({ qiround: qiround, player_id: player_id }).toArray(); + + playerName = detaildata[0].name; + dailyProgress = detaildata.reduce(function (res, obj) { + let date = moment.unix(obj.time).format('YYYYMMDD'); + + if (!(date in res)) { + res.__array.push(res[date] = { date: date, time: obj.time, actions: obj.actions, progress: obj.progress }); + } + else { + res[date].actions += +obj.actions; + res[date].progress += +obj.progress; + } + return res; + }, { __array: [] }).__array.sort(function (a, b) { return b.date - a.date }); + + + h.push('
    ' + playerName + ': ' + moment.unix(qiround).subtract(11, 'd').format(i18n('DateShort')) + ` - ` + moment.unix(qiround).format(i18n('Date')) + '
    '); + h.push('

    ' + i18n('Boxes.QiProgress.SnapShotLogDisclaimer') + '

    ') + h.push('
    ' + i18n('General.Player') + '' + i18n('Boxes.QiProgress.Actions') + '
    (' + HTML.Format(tA) + ')
    ' + i18n('Boxes.QiProgress.Progress') + '
    (' + HTML.Format(tP) + ')
    '); + h.push(''); + h.push(''); + h.push(''); + h.push(''); + h.push(''); + h.push(''); + + dailyProgress.forEach(day => { + let id = moment.unix(day.time).format(i18n('DateTime')); + h.push(''); + h.push(``); + h.push(``); + h.push(``); + h.push(''); + + }); + + h.push('
    ' + i18n('General.Date') + '' + HTML.i18nTooltip(i18n('Boxes.QiProgress.Actions')) + '' + HTML.i18nTooltip(i18n('Boxes.QiProgress.Progress')) + '
    ${moment.unix(day.time).format(i18n('Date'))}${HTML.Format(day.actions)}${HTML.Format(day.progress)}
    '); + } + else if (content === "filter") { + detaildata = await QiProgress.db.snapshots.where({ qiround: qiround }).and(function (item) { + return (item.date >= QiProgress.curDateFilter && item.date <= QiProgress.curDateEndFilter) + }).toArray(); + + detaildata.sort(function (a, b) { return b.time - a.time }); + + h.push('
    '); + h.push(''); + h.push(''); + h.push(''); + h.push(''); + h.push(''); + h.push(''); + h.push(''); + h.push(''); + + detaildata.forEach(e => { + h.push(''); + h.push(``); + h.push(``); + h.push(``); + h.push(``); + h.push(''); + }); + + h.push('
    ' + i18n('Boxes.QiProgress.Date') + '' + i18n('Boxes.QiProgress.Player') + '' + HTML.i18nTooltip(i18n('Boxes.QiProgress.Actions')) + '' + HTML.i18nTooltip(i18n('Boxes.QiProgress.Progress')) + '
    ${moment.unix(e.time).format(i18n('DateTime'))}${e.name}${HTML.Format(e.actions)}${HTML.Format(e.progress)}
    '); + } + + $('#QiProgressPlayerDetailsBody').html(h.join('')).promise().done(function () { + + $('#QiProgressPlayerDetailsBody .qilog').tableSorter(); + + if ($('#qiLogDatepicker').length !== 0) { + QiProgress.intiateDatePicker(); + } + $('#QiProgressPlayerDetailsBody tr.sorter-header').on('click', function () { + $(this).parents('.foe-table').find('tr.open').removeClass("open"); + + }); + + $('#QiProgressPlayerDetailsBody > .foe-table tr').on('click', function () { + + if ($(this).next("tr.detailview").length) { + $(this).next("tr.detailview").remove(); + $(this).removeClass('open'); + } + else { + if (!$(this).hasClass("hasdetail")) return; + + let date = $(this).data("id"); + let player = $(this).data("player"); + let awidth = $(this).find('td:first-child').width(); + let bwidth = $(this).find('td:nth-child(2)').width(); + let cwidth = $(this).find('td:nth-child(3)').width(); + let dwidth = $(this).find('td:nth-child(4)').width(); + let ewidth = $(this).find('td:last-child').width(); + + $(this).addClass('open'); + + QiProgress.BuildDetailViewLog({ date: date, player: player, width: { a: awidth, b: bwidth, c: cwidth, d: dwidth, e: ewidth } }); + } + }); + + }); + }, + + + formatRange: () => { + let text = undefined; + let dateStart = moment(QiProgress.curDateFilter); + let dateEnd = moment(QiProgress.curDateEndFilter); + + if (dateStart.isSame(dateEnd)) { + text = `${dateStart.format(i18n('Date'))}`; + } + else if (dateStart.year() !== (dateEnd.year())) { + text = `${dateStart.format(i18n('Date'))}` + ' - ' + `${dateEnd.format(i18n('Date'))}`; + } + else { + text = `${dateStart.format(i18n('DateShort'))}` + ' - ' + `${dateEnd.format(i18n('Date'))}`; + } + + return text; + }, + + + /** + * @param qiRound + * @returns {Promise} + */ + SetBoxNavigation: async (qiRound) => { + let h = []; + let i = 0; + let storageSettings = localStorage.getItem('QiProgressProgressSettings') + let ProgressSettings = (storageSettings != null && storageSettings != 'undefined') ? JSON.parse(localStorage.getItem('QiProgressProgressSettings')) : '{}'; + + QiProgress.ProgressSettings.showRoundSelector = (ProgressSettings.showRoundSelector !== null) ? ProgressSettings.showRoundSelector : QiProgress.ProgressSettings.showRoundSelector; + QiProgress.ProgressSettings.showProgressFilter = (ProgressSettings.showProgressFilter !== null) ? ProgressSettings.showProgressFilter : QiProgress.ProgressSettings.showProgressFilter; + + if (QiProgress.AllRounds === undefined || QiProgress.AllRounds === null) { + // get all available entires + const qiRounds = await QiProgress.db.history.where('qiround').above(0).keys(); + qiRounds.sort(function (a, b) { return b - a }); + QiProgress.AllRounds = qiRounds; + + } + + //set latest round to show if available and no specific round is set + if (!qiRound && QiProgress.AllRounds && QiProgress.AllRounds.length) { + qiRound = QiProgress.AllRounds[i]; + } + + if (qiRound && QiProgress.AllRounds && QiProgress.AllRounds.length) { + let index = QiProgress.AllRounds.indexOf(qiRound); + let previousweek = QiProgress.AllRounds[index + 1] || null; + let nextweek = QiProgress.AllRounds[index - 1] || null; + + h.push(`
    `); + + if (QiProgress.ProgressSettings.showRoundSelector) { + h.push(`${i18n('Boxes.QiProgress.QiRound')} `); + h.push(` `); + h.push(``); + } + + if (qiRound === QiProgress.CurrentQISeason) { + h.push(`
    `); + if (QiProgress.ProgressSettings.showProgressFilter === 1) { + h.push(``); + } + h.push(`
    `); + } + h.push(`
    `); + } + + h.push(`
    `); + + $('#QiProgressListBody').html(h.join('')).promise().done(function () { + + $('.btn-set-week').off().on('click', function () { + QiProgress.HistoryView = true; + let week = $(this).data('week'); + + if (!QiProgress.AllRounds.includes(week)) { return } + + QiProgress.BuildProgressList(week); + }); + + $('#qi-select-qiRound').off().on('change', function () { + QiProgress.HistoryView = true; + let week = parseInt($(this).val()); + + if (!QiProgress.AllRounds.includes(week) || week === QiProgress.CurrentQISeason) { return} + + QiProgress.BuildPlayerContent(week); + }); + + $('button#qi_showLog').off('click').on('click', function () { + QiProgress.curDetailViewFilter = { content: 'filter', qiRound: QiProgress.CurrentQISeason }; + QiProgress.ShowPlayerDetailsBox(QiProgress.curDetailViewFilter) + }); + + $('button#qi_filterProgressList').on('click', function () { + QiProgress.ToggleProgressList('qi_filterProgressList'); + }); + }); + }, + + + ShowSettings: () => { + let c = []; + let Settings = QiProgress.ProgressSettings; + c.push(`

    `); + c.push(`

    `); + c.push(`

    `); + c.push(`

    ${i18n('Boxes.General.Export')}: `); + c.push(`

    `); + + $('#QiProgressListSettingsBox').html(c.join('')); + }, + + /** + * @param d + * @returns {Promise} + */ + HandleQiProgress: async (d) => { + // immer zwei vorhalten, für Referenz Daten (LiveUpdate) + if (localStorage.getItem('QiProgress.NewAction') !== null) { + QiProgress.PrevAction = JSON.parse(localStorage.getItem('QiProgress.NewAction')); + QiProgress.PrevActionTimestamp = parseInt(localStorage.getItem('QiProgress.NewActionTimestamp')); + } + else if (QiProgress.NewAction !== null) { + QiProgress.PrevAction = QiProgress.NewAction; + QiProgress.PrevActionTimestamp = QiProgress.NewActionTimestamp; + } + + let players = [] + let sumActions = 0 + let sumProgress = 0 + + for (let i in d) { + if (!d.hasOwnProperty(i)) { break; } + sumActions += d[i].actionPoints || 0; + sumProgress += d[i].progressContribution || 0; + + players.push({ + qiround: QiProgress.CurrentQISeason, + rank: i * 1 + 1, + player_id: d[i].player.player_id, + name: d[i].player.name, + avatar: d[i].player.avatar, + actions: d[i].actionPoints || 0, + progress: d[i].progressContribution || 0 + }); + } + + await QiProgress.UpdateDB('history', { participation: players, actions: sumActions, progress: sumProgress }); + + QiProgress.HistoryView = false; + QiProgress.NewAction = players; + localStorage.setItem('QiProgress.NewAction', JSON.stringify(QiProgress.NewAction)); + + QiProgress.NewActionTimestamp = moment().unix(); + localStorage.setItem('QiProgress.NewActionTimestamp', QiProgress.NewActionTimestamp); + + if ($('#QiProgress').length > 0) { + QiProgress.BuildProgressList(QiProgress.CurrentQISeason); + console.log(1) + } + else { + QiProgress.ShowProgressList(); + } + }, + + + /** + * @param content + * @param data + * @returns {Promise} + */ + UpdateDB: async (content, data) => { + if (content === 'history') { + await QiProgress.db.history.put({ + qiround: QiProgress.CurrentQISeason, + actions: data.actions, + progress: data.progress, + participation: data.participation + }); + } + + if (content === 'player') { + let actions = 0 + + let CurrentSnapshot = await QiProgress.db.snapshots + .where({ + qiround: QiProgress.CurrentQISeason, + player_id: data.player_id + }) + .first(); + + if (CurrentSnapshot === undefined) { + actions = data.actions + progress = data.progress + } + else { + actions = data.diffActions + progress = data.diffProgress + } + + await QiProgress.db.snapshots.add({ + qiround: QiProgress.CurrentQISeason, + player_id: data.player_id, + name: data.name, + date: parseInt(moment.unix(data.time).format("YYYYMMDD")), + time: data.time, + actions: actions, + progress: progress + }); + } + + }, + + /** + * Filters the list for players with new progress + */ + ToggleProgressList: (id) => { + let elem = $('#QiProgressTable > tbody'); + let nelem = elem.find('tr.new'); + let act = $('#' + id).hasClass('filtered') ? 'show' : 'hide'; + + if (act === 'hide') { + if (nelem.length !== 0) { + let oelem = elem.find('tr:not(.new)'); + QiProgress.ProgressSettings.showOnlyActivePlayers = 1; + localStorage.setItem('QiProgressProgressSettings', JSON.stringify(QiProgress.PlayerBoxSettings)); + $('#QiProgressTable > thead .text-warning').hide(); + oelem.hide(); + $('#' + id).addClass('filtered btn-green'); + } + } + + else if (act === 'show') { + elem.find('tr').show(); + QiProgress.ProgressSettings.showOnlyActivePlayers = 0; + localStorage.setItem('QiProgressProgressSettings', JSON.stringify(QiProgress.PlayerBoxSettings)); + $('#QiProgressTable > thead .text-warning').show(); + $('#' + id).removeClass('filtered btn-green'); + } + }, + + + DeleteOldSnapshots: async (qiround) => { + let deleteCount = await QiProgress.db.snapshots.where("qiround").notEqual(qiround).delete(); + }, +} \ No newline at end of file diff --git a/js/web/reconstruction/css/reconstruction.css b/js/web/reconstruction/css/reconstruction.css index e18dba7e1..03bebb32e 100644 --- a/js/web/reconstruction/css/reconstruction.css +++ b/js/web/reconstruction/css/reconstruction.css @@ -13,11 +13,24 @@ -#ReconstructionListBody { - overflow-y: auto; + #ReconstructionListBody { + overflow-y: auto; +} +#ReconstructionList { + height: 400px; } #ReconstructionListBody td:nth-last-child(2){ - padding-right: 0; - text-align: right; + padding-right: 0; + text-align: right; +} + +#ReconstructionListBody td:nth-child(3){ + text-align: center; + min-width: 50px; +} + +#ReconstructionListBody tr.sorter-header th:last-child:before, +#ReconstructionListBody tr.sorter-header th:last-child:after { + left: 5px; } \ No newline at end of file diff --git a/js/web/reconstruction/js/reconstruction.js b/js/web/reconstruction/js/reconstruction.js index 2fc9683cb..b411b899a 100644 --- a/js/web/reconstruction/js/reconstruction.js +++ b/js/web/reconstruction/js/reconstruction.js @@ -25,14 +25,23 @@ FoEproxy.addHandler('CityReconstructionService', 'getDraft', (data, postData) => "__class__": "ReconstructionDraftEntity" })) } - reconstruction.draft = {} + reconstruction.draft = Object.assign({},...data.responseData.map(b=>({[b.entityId]:b}))) + reconstruction.count = {} + reconstruction.pages = { + prod: [], + happ: [], + street: [], + greatbuilding: [], + } for (let b of data.responseData) { - let id = MainParser.CityMapData[b.entityId].cityentity_id - if (!reconstruction.draft[id]) reconstruction.draft[id] = {placed:0,stored:0} + let id = MainParser.CityMapData[b.entityId].cityentity_id + "#" + (MainParser.CityMapData[b.entityId].level||0) + if (!reconstruction.count[id]) reconstruction.count[id] = {placed:0,stored:0} if (b.position) - reconstruction.draft[id].placed++ - else - reconstruction.draft[id].stored++ + reconstruction.count[id].placed++ + else { + reconstruction.count[id].stored++ + if (reconstruction.count[id].stored == 1) reconstruction.pageUpdate(id) + } } reconstruction.showTable() @@ -42,30 +51,98 @@ FoEproxy.addHandler('CityReconstructionService', 'getDraft', (data, postData) => FoEproxy.addHandler('AutoAidService', 'getStates', (data, postData) => { $('#ReconstructionList').remove() }); +FoEproxy.addHandler('InventoryService', 'getGreatBuildings', (data, postData) => { + $('#ReconstructionList').remove() +}); FoEproxy.addRequestHandler('CityReconstructionService', 'saveDraft', (data) => { for (let x of data.requestData[0]) { - let id = MainParser.CityMapData[x.entityId].cityentity_id - if (x.position) { - reconstruction.draft[id].placed++ - reconstruction.draft[id].stored-- - } else { - reconstruction.draft[id].placed-- - reconstruction.draft[id].stored++ + let id = MainParser.CityMapData[x.entityId].cityentity_id + "#" + (MainParser.CityMapData[x.entityId].level||0) + let pagesUpdated=false + if (x.position && !reconstruction.draft[x.entityId].position) { + reconstruction.count[id].placed++ + reconstruction.count[id].stored-- + if (reconstruction.count[id].stored==0) { + reconstruction.pageUpdate(id) + pagesUpdated=true + } + FoEproxy.triggerFoeHelperHandler('ReconstructionBuildingPlaced',{id:x.entityId,last:(reconstruction.count[id].stored==0)}) + } else if (!x.position) { + reconstruction.count[id].placed-- + reconstruction.count[id].stored++ + if (reconstruction.count[id].stored==1) { + reconstruction.pageUpdate(id) + pagesUpdated=true + } } - $('.reconstructionLine[data-meta_id="'+id+'"] td:nth-child(2)').html("x"+reconstruction.draft[id].stored) - if (reconstruction.draft[id].stored > 0) - $('.reconstructionLine[data-meta_id="'+id+'"]').show() + reconstruction.draft[x.entityId] = x + $('.reconstructionLine[data-page_id="'+id+'"] td:nth-child(2)').html("x"+reconstruction.count[id].stored) + if (reconstruction.count[id].stored > 0) + $('.reconstructionLine[data-page_id="'+id+'"]').show() else - $('.reconstructionLine[data-meta_id="'+id+'"]').hide() - + $('.reconstructionLine[data-page_id="'+id+'"]').hide() + if (pagesUpdated) reconstruction.updateTable() } }); let reconstruction = { draft:null, - + count:null, + pageMapper:{ + "culture":"happ", + "cultural_goods_production":"prod", + "decoration":"happ", + "diplomacy":"happ", + "static_provider":"happ", + "random_production":"prod", + "military":"prod", + "goods":"prod", + "production":"prod", + "residential":"prod", + "tower":"prod", + "clan_power_production":"prod" + }, + pages: null, + rcIcons:null, + roadIcons:null, + pageUpdate:(id)=>{ + let meta = MainParser.CityEntities[id.split("#")[0]] + if (["friends_tavern", + "main_building", + "impediment", + "hub_part", + "off_grid", + "outpost_ship", + "hub_main"].includes(meta.type)) return + let page = id[0]=="W"? "prod" : reconstruction.pageMapper[meta.type]||meta.type + if (reconstruction.count[id].stored==0) { //remove from pages + reconstruction.pages[page].splice(reconstruction.pages[page].indexOf(id),1) + } else { //add to pages + reconstruction.pages[page].unshift(id) + } + }, + updateTable:()=>{ + for (let [page,list] of Object.entries(reconstruction.pages)) { + for (let i = 0;i`+(Math.floor(i/4)+1)) + } + } + }, showTable:()=>{ + if (!reconstruction.rcIcons) { + reconstruction.rcIcons = { + happ:srcLinks.get("/shared/gui/reconstructionmenu/rc_icon_happynessbuildings.png",true), + prod:srcLinks.get("/shared/gui/reconstructionmenu/rc_icon_productionbuildings.png",true), + greatbuilding:srcLinks.get("/shared/gui/constructionmenu/icon_greatbuilding.png",true), + street:srcLinks.get("/shared/gui/constructionmenu/icon_street.png",true), + } + reconstruction.roadIcons = { + 0:"", + 1:srcLinks.icons("road_required"), + 2:srcLinks.icons("street_required") + } + } + if ( $('#ReconstructionList').length === 0 ) { HTML.AddCssFile('reconstruction'); @@ -80,32 +157,27 @@ let reconstruction = { }); } - let icons = (x) => ``; - h =` - + - + + ` - for (let [id,b] of Object.entries(reconstruction.draft)) { - let meta=MainParser.CityEntities[id] + for (let [id,b] of Object.entries(reconstruction.count)) { + let meta=MainParser.CityEntities[id.split("#")[0]] let width = meta.width||meta.components.AllAge.placement.size.x let length = meta.length||meta.components.AllAge.placement.size.y - let road="" - if ((meta?.components?.AllAge?.streetConnectionRequirement?.requiredLevel || meta?.requirements?.street_connection_level) == 2) - road = icons("street_required") - else if ((meta?.components?.AllAge.streetConnectionRequirement?.requiredLevel || meta?.requirements?.street_connection_level) == 1) - road = icons("road_required") - - h+=` + let road = meta?.components?.AllAge.streetConnectionRequirement?.requiredLevel || meta?.requirements?.street_connection_level || 0 + h+=` - + + ` @@ -114,7 +186,8 @@ let reconstruction = { $('#ReconstructionListBody').html(h) - $('#ReconstructionListBody .sortable-table').tableSorter() + $('#ReconstructionListBody .sortable-table').tableSorter() + setTimeout(reconstruction.updateTable,200) }, } diff --git a/js/web/recurring-quests/css/recurring-quests.css b/js/web/recurring-quests/css/recurring-quests.css index a2d214952..e9b654e9d 100644 --- a/js/web/recurring-quests/css/recurring-quests.css +++ b/js/web/recurring-quests/css/recurring-quests.css @@ -26,10 +26,6 @@ text-align: justify; } -#RecurringQuestsBoxBody thead { - position: sticky; - top:0; -} #RecurringQuestsBoxBody th:last-child, #RecurringQuestsBoxBody td:last-child { text-align: center; diff --git a/js/web/recurring-quests/js/recurring-quests.js b/js/web/recurring-quests/js/recurring-quests.js index 76a051211..28c677f1a 100644 --- a/js/web/recurring-quests/js/recurring-quests.js +++ b/js/web/recurring-quests/js/recurring-quests.js @@ -106,7 +106,7 @@ let Recurring = { h.push(`
    ${i18n('Boxes.CityMap.Building')} #${icons("road_required")}?${srcLinks.icons("icon_copy")}${srcLinks.icons("road_required")}
    `); - h.push(''); + h.push(''); h.push(''); h.push(``); h.push(``); diff --git a/js/web/scoutingtimes/js/scoutingtimes.js b/js/web/scoutingtimes/js/scoutingtimes.js index ce8b68d09..2da49719f 100644 --- a/js/web/scoutingtimes/js/scoutingtimes.js +++ b/js/web/scoutingtimes/js/scoutingtimes.js @@ -46,10 +46,12 @@ FoEproxy.addHandler('CampaignService', 'start', (data, postData) => { if (!Settings.GetSetting('ShowScoutingTimes')) { return; } - + maxShip = Math.floor(Object.values(data.responseData.provinces).map(x=>x.id||0).pop()/100) for (let province of data.responseData.provinces) { - scoutingTimes.Provinces[province.id] = province; + if (province.provinceType=="ship") province.parentIds=province.parentIds.concat([...Array(maxShip - province.id/100).keys()].map(x=>(x+province.id/100+1)*100)) + scoutingTimes.Provinces[province.id||0] = province; } + scoutingTimes.scoutPosition = data.responseData.scout?.current_province|0; scoutingTimes.scoutTarget = data.responseData.scout?.path[data.responseData.scout?.path?.length-1]|0; scoutingTimes.scoutTraveltime = data.responseData.scout.time_to_target; diff --git a/js/web/settings/config/config.json b/js/web/settings/config/config.json index 41ef36ae7..a918d19bb 100644 --- a/js/web/settings/config/config.json +++ b/js/web/settings/config/config.json @@ -41,12 +41,6 @@ "group": "Auto", "sort": 9 }, - { - "name": "ShowOtherGuildActivity", - "status": true, - "group": "Auto", - "sort": 9 - }, { "name": "AutoOpenInfoBox", "status": false, @@ -163,6 +157,12 @@ "group": "Boxes", "sort": 19 }, + { + "name": "RepeatSelectBuilding", + "status": false, + "group": "Boxes", + "sort": 20 + }, { "name": "SelectedMenu", "callback": "MenuSelected", diff --git a/js/web/settings/js/settings.js b/js/web/settings/js/settings.js index 295c0e3cd..9485a0a97 100644 --- a/js/web/settings/js/settings.js +++ b/js/web/settings/js/settings.js @@ -641,7 +641,7 @@ let Settings = { icon: 'success', hideAfter: 6000, position: pos, - extraClass: localStorage.getItem('SelectedMenu') || 'bottombar', + extraClass: localStorage.getItem('SelectedMenu') || 'RightBar', afterHidden: function () { $('.jq-toast-wrap').remove(); } diff --git a/js/web/srcLinks/js/srcLinks.js b/js/web/srcLinks/js/srcLinks.js index ebe79de8d..0a4275855 100644 --- a/js/web/srcLinks/js/srcLinks.js +++ b/js/web/srcLinks/js/srcLinks.js @@ -110,15 +110,14 @@ let srcLinks = { getReward:(icon) => { - let url3 = srcLinks.get(`/shared/unit_portraits/armyuniticons_90x90/armyuniticons_90x90_${icon}.png`,true, true) // does not work :( - let url2 = srcLinks.get(`/shared/icons/goods_large/${icon}.png`,true, true) - let url1 = srcLinks.get(`/shared/icons/reward_icons/reward_icon_${icon}.png`,true, true) - let url = url3 + let url = srcLinks.get(`/shared/unit_portraits/armyuniticons_90x90/armyuniticons_90x90_${icon}.jpg`,true, true) // does not work :( - if (url3.indexOf("antiquedealer_flag") > -1) - url = url2 - if (url2.indexOf("antiquedealer_flag") > -1) - url = url1 + if (url.indexOf("antiquedealer_flag") > -1) + url = srcLinks.get(`/shared/icons/goods_large/${icon}.png`,true, true) + if (url.indexOf("antiquedealer_flag") > -1) + url = srcLinks.get(`/shared/icons/reward_icons/reward_icon_${icon}.png`,true, true) + if (url.indexOf("antiquedealer_flag") > -1) + url = srcLinks.get(`/city/buildings/${icon?.replace(/(\D*?)_(.*)/,"$1_SS_$2")}.png`,true); return url; }, @@ -133,7 +132,17 @@ let srcLinks = { } return url1; + }, + + icons: (x) => { + if (!x) return "" + x=x.replace(/(.*?)_[0-9]+/gm,"$1"); + let link = srcLinks.get(`/shared/icons/${x}.png`,true,true); + if (link.includes("antiquedealer_flag")) link = srcLinks.get(`/shared/icons/reward_icons/reward_icon_${x}.png`,true,true); + if (link.includes("antiquedealer_flag")) link = srcLinks.get(`/city/buildings/${x.replace(/(\D*?)_(.*)/,"$1_SS_$2")}.png`,true); + return ``; } + } srcLinks.init() \ No newline at end of file diff --git a/js/web/technologies/css/technologies.css b/js/web/technologies/css/technologies.css index 83835285b..f7ecea5b7 100644 --- a/js/web/technologies/css/technologies.css +++ b/js/web/technologies/css/technologies.css @@ -39,10 +39,7 @@ } #technologies #technologiesBody table th { - position: sticky; - top: 0; cursor: pointer; - z-index: 1; font-size: 85%; } diff --git a/js/web/technologies/js/technologies.js b/js/web/technologies/js/technologies.js index 89d6b6dcb..2dafda0f0 100644 --- a/js/web/technologies/js/technologies.js +++ b/js/web/technologies/js/technologies.js @@ -366,7 +366,7 @@ let Technologies = { h.push('
    ${i18n('Boxes.RecurringQuests.Table.Quest')} ⇋${i18n('Boxes.RecurringQuests.Table.Tasks')} ⇋
    '); - h.push('' + + h.push('' + '' + '' + '' + diff --git a/js/web/treasury/js/treasury.js b/js/web/treasury/js/treasury.js index 2a9125d83..ed729bf3c 100644 --- a/js/web/treasury/js/treasury.js +++ b/js/web/treasury/js/treasury.js @@ -49,11 +49,13 @@ let Treasury = { }); } - let LogArray = Logs['responseData']['logs']; - for (let i = 0; i < LogArray.length; i++) { - Treasury.Logs[Treasury.Logs.length] = LogArray[i]; - } - + let LogArray = Logs['responseData']['logs'].map(x=>{ + let date = EventHandler.ParseDate(x.createdAt) + x.createdAt = date||x.createdAt + return x + }); + Treasury.Logs = Treasury.Logs.concat(LogArray); + Treasury.CalcBody(); }, @@ -97,7 +99,7 @@ let Treasury = { CurrentLine.push(GoodsData[GoodID]['name'].replace(/;/g, '')); CurrentLine.push(CurrentLog['amount']); CurrentLine.push(CurrentLog['action'].replace(/;/g, '')); - CurrentLine.push(CurrentLog['createdAt'].replace(/;/g, '')); + CurrentLine.push(typeof CurrentLog['createdAt'] == "object" ? CurrentLog['createdAt'].toLocaleString().replace(/,/g,"") : CurrentLog['createdAt'].replace(/;/g, '')); h.push(CurrentLine.join(';')); } diff --git a/manifest.json b/manifest.json index 901dc284f..982a1a8a2 100644 --- a/manifest.json +++ b/manifest.json @@ -2,7 +2,7 @@ "name": "__MSG_appName__", "description": "__MSG_appDesc__", "default_locale": "en", - "version": "3.9.0.0", + "version": "3.10.0.0", "manifest_version": 3, "permissions": [ diff --git a/manifests/chromium/manifest_.json b/manifests/chromium/manifest_.json index 5ef67873b..d1068c589 100644 --- a/manifests/chromium/manifest_.json +++ b/manifests/chromium/manifest_.json @@ -2,7 +2,7 @@ "name": "__MSG_appName__", "description": "__MSG_appDesc__", "default_locale": "en", - "version": "3.9.0.0", + "version": "3.10.0.0", "manifest_version": 3, "permissions": [ diff --git a/manifests/firefox/manifest_.json b/manifests/firefox/manifest_.json index 8a183895d..585829a23 100644 --- a/manifests/firefox/manifest_.json +++ b/manifests/firefox/manifest_.json @@ -2,7 +2,7 @@ "name": "__MSG_appName__", "description": "__MSG_appDesc__", "default_locale": "en", - "version": "3.9.0.0", + "version": "3.10.0.0", "manifest_version": 3, "permissions": [ diff --git a/planner/planner.js b/planner/planner.js index fb2cd3dd9..28c9d1300 100644 --- a/planner/planner.js +++ b/planner/planner.js @@ -58,16 +58,16 @@ function drawMap () { let city = Object.values(cityData) mapBuildings = [] - if (mapData != undefined) { + if (mapData !== undefined) { for (let expansion of mapData) { drawExpansion(expansion) } } for (let building of city) { - let buildingData = Object.values(metaData).find(x => x.id == building.cityentity_id) + let buildingData = Object.values(metaData).find(x => x.id === building.cityentity_id) - if (buildingData.type != "off_grid" && buildingData.type != "outpost_ship" && buildingData.type != "friends_tavern" && !buildingData.type.includes("hub")) { + if (buildingData.type !== "off_grid" && buildingData.type !== "outpost_ship" && buildingData.type !== "friends_tavern" && !buildingData.type.includes("hub")) { let newBuilding = new MapBuilding(building, buildingData) mapBuildings.push(newBuilding) newBuilding.draw() @@ -86,11 +86,35 @@ function drawEmptyMap () { function drawExpansion (expansion) { ctx.fillStyle = '#fffead' ctx.strokeStyle = '#cbca4a' + ctx.lineWidth = 0.5 + + // ctx.fillRect((expansion.x || 0) * size, (expansion.y || 0) * size, expansion.width * size, expansion.length * size) + // ctx.strokeRect((expansion.x || 0) * size, (expansion.y || 0) * size, expansion.width * size, expansion.length * size) + + // draw the 1x1 squares for each expansion + for (let a = 0; a < expansion.length; a++) + { + for (let b = 0; b < expansion.width; b++) + { + createMapGridPart({ + x: ((expansion.x === undefined || isNaN(expansion.x)) ? 0 : expansion.x) + a, + y: (expansion.y === undefined ? 0 : expansion.y) + b + }); + } + } - ctx.fillRect((expansion.x || 0) * size, (expansion.y || 0) * size, expansion.width * size, expansion.length * size) + ctx.strokeStyle = '#8c8a19' ctx.strokeRect((expansion.x || 0) * size, (expansion.y || 0) * size, expansion.width * size, expansion.length * size) } +function createMapGridPart(data) { + let top = data.y * size, + left = data.x * size; + + ctx.fillRect(left, top, size, size); + ctx.strokeRect(left, top, size, size); +} + class MapBuilding { constructor(data, metaData) { @@ -106,31 +130,31 @@ class MapBuilding { needsStreet = function() { let needsStreet = this.meta.requirements?.street_connection_level - if (needsStreet == undefined) { + if (needsStreet === undefined) { this.meta.abilities.forEach(ability => { - if (ability.__class__ == "StreetConnectionRequirementComponent") + if (ability.__class__ === "StreetConnectionRequirementComponent") needsStreet = 1 }); - if (this.meta.components?.AllAge?.streetConnectionRequirement != undefined) + if (this.meta.components?.AllAge?.streetConnectionRequirement !== undefined) needsStreet = this.meta.components.AllAge.streetConnectionRequirement.requiredLevel } - return (needsStreet == undefined ? 0 : needsStreet) + return (needsStreet === undefined ? 0 : needsStreet) } setColorByType = function() { let color = '#888' - if (this.meta.type == 'main_building') + if (this.meta.type === 'main_building') color = '#ffb300' - else if (this.meta.type == 'military') + else if (this.meta.type === 'military') color = '#fff' - else if (this.meta.type == 'greatbuilding') + else if (this.meta.type === 'greatbuilding') color = '#e6542f' - else if (this.meta.type == 'residential') + else if (this.meta.type === 'residential') color = '#7abaff' - else if (this.meta.type == 'production') + else if (this.meta.type === 'production') color = '#416dff' - if (this.needsStreet() == 0) + if (this.needsStreet() === 0) color = '#793bc9' return color @@ -206,7 +230,7 @@ class MapBuilding { function redrawMap () { ctx.clearRect(0,0,canvas.width,canvas.height) - if (mapData != undefined) { + if (mapData !== undefined) { for (let expansion of mapData) { drawExpansion(expansion) } @@ -233,18 +257,18 @@ function showStoredBuildings () { // generate amount for (let building of storedBuildings) { - if (building.meta.type == 'street') continue + if (building.meta.type === 'street') continue let amount = buildingsAmount.get(building.meta.id) - if (amount == undefined) + if (amount === undefined) buildingsAmount.set(building.meta.id, 1) else buildingsAmount.set(building.meta.id, ++amount) } buildingsAmount.forEach((amount, buildingId) => { - let building = storedBuildings.find(x => x.meta.id == buildingId) - let noStreet = (building.needsStreet() == 0) ? ' nostreet' : '' + let building = storedBuildings.find(x => x.meta.id === buildingId) + let noStreet = (building.needsStreet() === 0) ? ' nostreet' : '' html.push('
  • '+ ''+building.meta.name + ' (' + (building.meta.length || building.meta.components.AllAge.placement.size.y)+'x'+(building.meta.width || building.meta.components.AllAge.placement.size.x) +')' + ''+(amount > 1 ? amount : '')+'
  • '
    ' + i18n('Boxes.Technologies.Resource') + '' + i18n('Boxes.Technologies.DescRequired') + '