diff --git a/forge-gui-mobile/src/forge/adventure/data/SettingData.java b/forge-gui-mobile/src/forge/adventure/data/SettingData.java index 22666448259..488c4371cae 100644 --- a/forge-gui-mobile/src/forge/adventure/data/SettingData.java +++ b/forge-gui-mobile/src/forge/adventure/data/SettingData.java @@ -25,4 +25,5 @@ public class SettingData { public boolean useAllCardVariants; public boolean excludeAlchemyVariants; public boolean generateLDADecks; + public boolean bindEquipmentLoadoutsToDecks; } diff --git a/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java b/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java index 8af71299fc4..6395c8a92e3 100644 --- a/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java +++ b/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java @@ -72,6 +72,7 @@ public class AdventurePlayer implements Serializable, SaveFileContent { private final ArrayList inventoryItems = new ArrayList<>(); private final Array boostersOwned = new Array<>(); private final HashMap equippedItems = new HashMap<>(); + private final HashMap> deckLoadouts = new HashMap<>(); private final List quests = new ArrayList<>(); private final List events = new ArrayList<>(); private final Set unsupportedCards = new HashSet<>(); @@ -199,7 +200,39 @@ public void create(String n, Deck startingDeck, boolean male, int race, int avat } public void setSelectedDeckSlot(int slot) { + setSelectedDeckSlot(slot, true); + } + + public void setSelectedDeckSlot(int slot, boolean switchLoadout) { if (slot >= 0 && slot < getDeckCount()) { + boolean bindLoadouts = Config.instance().getSettingData().bindEquipmentLoadoutsToDecks; + if (switchLoadout && bindLoadouts && slot != selectedDeckIndex) { + // Save current loadout to old deck + deckLoadouts.put(selectedDeckIndex, new HashMap<>(equippedItems)); + + // Clear current equipment + for (ItemData item : inventoryItems) { + if (item != null) { + item.isEquipped = false; + } + } + equippedItems.clear(); + + // Restore loadout for new deck (if any) + if (deckLoadouts.containsKey(slot)) { + HashMap newLoadout = deckLoadouts.get(slot); + for (Map.Entry entry : newLoadout.entrySet()) { + ItemData item = getItemFromInventory(entry.getValue()); + if (item != null) { + item.isEquipped = true; + equippedItems.put(entry.getKey(), entry.getValue()); + } + } + } + + onEquipmentChange.emit(); + } + selectedDeckIndex = slot; deck = decks.get(selectedDeckIndex); setColorIdentity(DeckProxy.getColorIdentity(deck)); @@ -630,7 +663,25 @@ public void load(SaveFileData data) { } } - setSelectedDeckSlot(data.readInt("selectedDeckIndex")); + // Load deck loadouts (equipment tied to each deck) + for (int i = 0; i < getDeckCount(); i++) { + if (data.containsKey("deckLoadout_slots_" + i) && data.containsKey("deckLoadout_items_" + i)) { + try { + String[] loadoutSlots = (String[]) data.readObject("deckLoadout_slots_" + i); + Long[] loadoutItems = (Long[]) data.readObject("deckLoadout_items_" + i); + if (loadoutSlots.length == loadoutItems.length) { + HashMap loadout = new HashMap<>(); + for (int j = 0; j < loadoutSlots.length; j++) { + loadout.put(loadoutSlots[j], loadoutItems[j]); + } + deckLoadouts.put(i, loadout); + } + } catch (Exception ignored) {} + } + } + + // Use false to skip loadout switching during load (equippedItems already loaded correctly above) + setSelectedDeckSlot(data.readInt("selectedDeckIndex"), false); CardPool cardPool = CardPool.fromCardList(Lists.newArrayList((String[]) data.readObject("cards"))); cards.addAll(cardPool.getFilteredPool(isValid)); unsupportedCards.addAll(cardPool.getFilteredPool(isUnsupported).toFlatList()); @@ -823,6 +874,24 @@ public SaveFileData save() { if (decks.get(i).get(DeckSection.Commander) != null) data.storeObject("commanderCards_" + i, decks.get(i).get(DeckSection.Commander).toCardList("\n").split("\n")); } + + // Save deck loadouts (equipment tied to each deck) + // First, save current equipment to current deck's loadout + deckLoadouts.put(selectedDeckIndex, new HashMap<>(equippedItems)); + for (int i = 0; i < getDeckCount(); i++) { + if (deckLoadouts.containsKey(i)) { + HashMap loadout = deckLoadouts.get(i); + ArrayList loadoutSlots = new ArrayList<>(); + ArrayList loadoutItems = new ArrayList<>(); + for (Map.Entry entry : loadout.entrySet()) { + loadoutSlots.add(entry.getKey()); + loadoutItems.add(entry.getValue()); + } + data.storeObject("deckLoadout_slots_" + i, loadoutSlots.toArray(new String[0])); + data.storeObject("deckLoadout_items_" + i, loadoutItems.toArray(new Long[0])); + } + } + data.store("selectedDeckIndex", selectedDeckIndex); data.storeObject("cards", cards.toCardList("\n").split("\n")); diff --git a/forge-gui-mobile/src/forge/adventure/scene/SettingsScene.java b/forge-gui-mobile/src/forge/adventure/scene/SettingsScene.java index 187f0431ec3..d8e53b3630f 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/SettingsScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/SettingsScene.java @@ -253,6 +253,13 @@ public void changed(ChangeEvent event, Actor actor) { Config.instance().saveSettings(); } }); + addSettingField(Forge.getLocalizer().getMessage("lblBindEquipmentLoadoutsToDecks"), Config.instance().getSettingData().bindEquipmentLoadoutsToDecks, new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + Config.instance().getSettingData().bindEquipmentLoadoutsToDecks = ((CheckBox) actor).isChecked(); + Config.instance().saveSettings(); + } + }); addCheckBox(Forge.getLocalizer().getMessage("cbAnte"), ForgePreferences.FPref.UI_ANTE); addCheckBox(Forge.getLocalizer().getMessage("cbAnteMatchRarity"), ForgePreferences.FPref.UI_ANTE_MATCH_RARITY); addCheckBox(Forge.getLocalizer().getMessage("lblPromptAutoSell"), ForgePreferences.FPref.PROMPT_FOR_AUTOSELL); diff --git a/forge-gui/res/languages/de-DE.properties b/forge-gui/res/languages/de-DE.properties index 589e94b517e..9fe27ceff9c 100644 --- a/forge-gui/res/languages/de-DE.properties +++ b/forge-gui/res/languages/de-DE.properties @@ -3095,6 +3095,7 @@ lblShowShopOverlay=Shop -Artikelname anzeigen lblUseAllCardVariants=Use Card Variants from All Sets (Restart Required) lblExcludeAlchemyVariants=Exclude variants rebalanced for Arena's Alchemy and Historic formats lblGenerateLDADecks=Generate Archetype Decks instead of Genetic AI Decks +lblBindEquipmentLoadoutsToDecks=Ausrüstung an Decks binden lblExitToWoldMap=Zurück zur Weltkarte? lblStartArena=Willst du in die Arena gehen? lblWouldYouLikeDestroy=Möchten Sie {0} zerstören? diff --git a/forge-gui/res/languages/en-US.properties b/forge-gui/res/languages/en-US.properties index 4f21850bbce..de677c3e66f 100644 --- a/forge-gui/res/languages/en-US.properties +++ b/forge-gui/res/languages/en-US.properties @@ -3173,6 +3173,7 @@ lblShowShopOverlay=Display Shop Item names lblUseAllCardVariants=Use Card Variants from All Sets (Restart Required) lblExcludeAlchemyVariants=Exclude variants rebalanced for Arena's Alchemy and Historic formats lblGenerateLDADecks=Generate Archetype Decks instead of Genetic AI Decks +lblBindEquipmentLoadoutsToDecks=Bind equipment loadouts to decks lblExitToWoldMap=Exit to the World Map? lblStartArena=Do you want to go into the Arena? lblWouldYouLikeDestroy=Would you like to destroy {0}? diff --git a/forge-gui/res/languages/es-ES.properties b/forge-gui/res/languages/es-ES.properties index 66504503985..93c67970685 100644 --- a/forge-gui/res/languages/es-ES.properties +++ b/forge-gui/res/languages/es-ES.properties @@ -3083,6 +3083,7 @@ lblShowShopOverlay=Nombre del artículo de la tienda de exhibición lblUseAllCardVariants=Use Card Variants from All Sets (Restart Required) lblExcludeAlchemyVariants=Exclude variants rebalanced for Arena's Alchemy and Historic formats lblGenerateLDADecks=Generate Archetype Decks instead of Genetic AI Decks +lblBindEquipmentLoadoutsToDecks=Vincular equipamiento a mazos lblExitToWoldMap=Salir al mapa del mundo? lblStartArena=¿Quieres ir a la arena? lblWouldYouLikeDestroy=¿Le gustaría destruir {0}? @@ -3518,7 +3519,7 @@ lblDeclareBlockersForCard=Declarar bloqueadores para tarjeta lblBlockWithCard=Bloquear con tarjeta lblPayManaWithCard=Pagar mana con tarjeta lblAll=TODO -lblMine=Mo +lblMine=M�o lblSelectRewards=Seleccionar {0} recompensas lblDefaultCollection=Colecciones predeterminadas lblSellable=Vendible diff --git a/forge-gui/res/languages/fr-FR.properties b/forge-gui/res/languages/fr-FR.properties index c0d24a27ec4..1151b65bfd0 100644 --- a/forge-gui/res/languages/fr-FR.properties +++ b/forge-gui/res/languages/fr-FR.properties @@ -3077,6 +3077,7 @@ lblShowShopOverlay=Nom de l'article de la boutique d'affichage lblUseAllCardVariants=Use Card Variants from All Sets (Restart Required) lblExcludeAlchemyVariants=Exclude variants rebalanced for Arena's Alchemy and Historic formats lblGenerateLDADecks=Generate Archetype Decks instead of Genetic AI Decks +lblBindEquipmentLoadoutsToDecks=Lier l'équipement aux decks lblExitToWoldMap=Sortir sur la carte du monde? lblStartArena=Voulez-vous entrer dans l'arène? lblWouldYouLikeDestroy=Souhaitez-vous détruire {0}? diff --git a/forge-gui/res/languages/it-IT.properties b/forge-gui/res/languages/it-IT.properties index 45281d7148a..768da247df5 100644 --- a/forge-gui/res/languages/it-IT.properties +++ b/forge-gui/res/languages/it-IT.properties @@ -3075,6 +3075,7 @@ lblShowShopOverlay=Visualizza il nome dell'articolo del negozio lblUseAllCardVariants=Use Card Variants from All Sets (Restart Required) lblExcludeAlchemyVariants=Exclude variants rebalanced for Arena's Alchemy and Historic formats lblGenerateLDADecks=Generate Archetype Decks instead of Genetic AI Decks +lblBindEquipmentLoadoutsToDecks=Associa equipaggiamento ai mazzi lblExitToWoldMap=Esci alla mappa del mondo? lblStartArena=Vuoi andare nell'arena? lblWouldYouLikeDestroy=Vorresti distruggere {0}? diff --git a/forge-gui/res/languages/ja-JP.properties b/forge-gui/res/languages/ja-JP.properties index cd6645d7007..fdf145551ba 100644 --- a/forge-gui/res/languages/ja-JP.properties +++ b/forge-gui/res/languages/ja-JP.properties @@ -3071,6 +3071,7 @@ lblShowShopOverlay=ショップアイテム名を表示します lblUseAllCardVariants=Use Card Variants from All Sets (Restart Required) lblExcludeAlchemyVariants=Exclude variants rebalanced for Arena's Alchemy and Historic formats lblGenerateLDADecks=Generate Archetype Decks instead of Genetic AI Decks +lblBindEquipmentLoadoutsToDecks=装備をデッキに紐付ける lblExitToWoldMap=世界地図に終了しますか? lblStartArena=アリーナに行きたいですか? lblWouldYouLikeDestroy={0}を破壊しますか? diff --git a/forge-gui/res/languages/pt-BR.properties b/forge-gui/res/languages/pt-BR.properties index e3e0355ff29..0c97dedad46 100644 --- a/forge-gui/res/languages/pt-BR.properties +++ b/forge-gui/res/languages/pt-BR.properties @@ -3160,6 +3160,7 @@ lblDisableNotForSaleOverlay=Disable Not For Sale Overlay lblUseAllCardVariants=Use Card Variants from All Sets (Restart Required) lblExcludeAlchemyVariants=Exclude variants rebalanced for Arena's Alchemy and Historic formats lblGenerateLDADecks=Generate Archetype Decks instead of Genetic AI Decks +lblBindEquipmentLoadoutsToDecks=Vincular equipamentos aos decks lblExitToWoldMap=Sair para o mapa do mundo? lblStartArena=Você quer entrar na arena? lblWouldYouLikeDestroy=Você gostaria de destruir {0}? diff --git a/forge-gui/res/languages/zh-CN.properties b/forge-gui/res/languages/zh-CN.properties index 4d0ae5f2a50..ed2f195bd7e 100644 --- a/forge-gui/res/languages/zh-CN.properties +++ b/forge-gui/res/languages/zh-CN.properties @@ -3062,6 +3062,7 @@ lblDisableNotForSaleOverlay=Disable Not For Sale Overlay lblUseAllCardVariants=使用来自所有系列的牌张重印版(这需要重新启动) lblExcludeAlchemyVariants=Exclude variants rebalanced for Arena's Alchemy and Historic formats lblGenerateLDADecks=生成原型套牌而不是由AI生成的套牌 +lblBindEquipmentLoadoutsToDecks=将装备配置绑定到套牌 lblExitToWoldMap=退出世界地图? lblStartArena=您想进入竞技场吗? lblWouldYouLikeDestroy=您想销毁{0}吗?