add migration message, fix cloning of itemData

This commit is contained in:
Anthony Calosa
2025-08-23 20:07:28 +08:00
parent 1ff16ca509
commit 3a5e11504a
18 changed files with 193 additions and 142 deletions

View File

@@ -86,7 +86,7 @@ public class DialogData implements Serializable {
public ActionData(ActionData other){ public ActionData(ActionData other){
removeItem = other.removeItem; removeItem = other.removeItem;
addItem = other.removeItem; addItem = other.addItem;
addLife = other.addLife; addLife = other.addLife;
addGold = other.addGold; addGold = other.addGold;
addShards = other.addShards; addShards = other.addShards;

View File

@@ -1,20 +1,17 @@
package forge.adventure.data; package forge.adventure.data;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.g2d.Sprite; import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Json;
import forge.adventure.util.Config; import forge.adventure.util.Config;
import forge.adventure.util.Paths;
import java.io.Serializable; import java.io.Serializable;
import java.util.UUID;
/** /**
* Data class that will be used to read Json configuration files * Data class that will be used to read Json configuration files
* ItemData * ItemData
* contains the information for equipment and items. * contains the information for equipment and items.
*/ */
public class ItemData implements Serializable { public class ItemData implements Serializable, Cloneable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public String name; public String name;
public String equipmentSlot; public String equipmentSlot;
@@ -28,6 +25,7 @@ public class ItemData implements Serializable {
public boolean usableInPoi; public boolean usableInPoi;
public boolean isCracked; public boolean isCracked;
public boolean isEquipped; public boolean isEquipped;
public Long longID;
public String commandOnUse; public String commandOnUse;
public int shardsNeeded; public int shardsNeeded;
public DialogData dialogOnUse; public DialogData dialogOnUse;
@@ -56,28 +54,6 @@ public class ItemData implements Serializable {
public Sprite sprite() { public Sprite sprite() {
return Config.instance().getItemSprite(iconName); return Config.instance().getItemSprite(iconName);
} }
private static Array<ItemData> itemList;
public static Array<ItemData> getAllItems() {
if (itemList == null) {
Json json = new Json();
FileHandle handle = Config.instance().getFile(Paths.ITEMS);
if (handle.exists()) {
Array<ItemData> readJson = json.fromJson(Array.class, ItemData.class, handle);
itemList = readJson;
}
}
return itemList;
}
public static ItemData getItem(String name) {
for(ItemData data : new Array.ArrayIterator<>(getAllItems()))
{
if(data.name.equalsIgnoreCase(name))
return data;
}
return null;
}
public String getDescription() { public String getDescription() {
String result = ""; String result = "";
@@ -96,4 +72,14 @@ public class ItemData implements Serializable {
return name; return name;
} }
@Override
public ItemData clone() {
try {
ItemData clone = (ItemData) super.clone();
clone.longID = UUID.randomUUID().getMostSignificantBits();
return clone;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
} }

View File

@@ -0,0 +1,39 @@
package forge.adventure.data;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Json;
import forge.adventure.util.Config;
import forge.adventure.util.Paths;
public class ItemListData
{
private static Array<ItemData> itemList;
private static Array<ItemData> getAllItems() {
if (itemList == null) {
Json json = new Json();
FileHandle handle = Config.instance().getFile(Paths.ITEMS);
if (handle.exists()) {
Array<ItemData> readJson = json.fromJson(Array.class, ItemData.class, handle);
itemList = readJson;
}
}
return itemList;
}
public static ItemData getItem(String name) {
for (ItemData orig : new Array.ArrayIterator<>(getAllItems())) {
if (orig.name.equalsIgnoreCase(name))
return orig.clone();
}
return null;
}
public static Array<ItemData> getSketchBooks() {
Array<ItemData> sketchbooks = new Array<>();
for (ItemData orig : getAllItems()) {
if (orig.questItem || !orig.getName().contains("Landscape Sketchbook"))
continue;
sketchbooks.add(orig.clone());
}
return sketchbooks;
}
}

View File

@@ -2,7 +2,6 @@ package forge.adventure.data;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import forge.StaticData; import forge.StaticData;
import forge.adventure.util.*; import forge.adventure.util.*;
import forge.adventure.world.WorldSave; import forge.adventure.world.WorldSave;
@@ -218,12 +217,12 @@ public class RewardData implements Serializable {
if(itemNames!=null) if(itemNames!=null)
{ {
for(int i=0;i<count+addedCount;i++) { for(int i=0;i<count+addedCount;i++) {
ret.add(new Reward(ItemData.getItem(itemNames[WorldSave.getCurrentSave().getWorld().getRandom().nextInt(itemNames.length)]))); ret.add(new Reward(ItemListData.getItem(itemNames[WorldSave.getCurrentSave().getWorld().getRandom().nextInt(itemNames.length)])));
} }
} }
else if(itemName!=null&&!itemName.isEmpty()) { else if(itemName!=null&&!itemName.isEmpty()) {
for(int i=0;i<count+addedCount;i++) { for(int i=0;i<count+addedCount;i++) {
ret.add(new Reward(ItemData.getItem(itemName))); ret.add(new Reward(ItemListData.getItem(itemName)));
} }
} }
break; break;
@@ -263,21 +262,12 @@ public class RewardData implements Serializable {
} }
} }
break; break;
} }
case "landSketchbookShop": case "landSketchbookShop":
List<ItemData> sketchbookItems = Lists.newArrayList(ItemData.getAllItems()); Array<ItemData> sketchbookItems = ItemListData.getSketchBooks();
sketchbookItems.removeIf(new Predicate<ItemData>() {
@Override
public boolean test(ItemData itemData) {
return itemData.questItem || !itemData.getName().contains("Landscape Sketchbook");
}
});
for(int i=0; i < count + addedCount; i++) { for(int i=0; i < count + addedCount; i++) {
ItemData item = sketchbookItems.get(WorldSave.getCurrentSave().getWorld().getRandom().nextInt(sketchbookItems.size())); ItemData item = sketchbookItems.get(WorldSave.getCurrentSave().getWorld().getRandom().nextInt(sketchbookItems.size));
ret.add(new Reward(item)); ret.add(new Reward(item));
} }

View File

@@ -65,9 +65,9 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
private final Map<String, Byte> characterFlags = new HashMap<>(); private final Map<String, Byte> characterFlags = new HashMap<>();
private final Map<String, Byte> tutorialFlags = new HashMap<>(); private final Map<String, Byte> tutorialFlags = new HashMap<>();
private final Array<ItemData> inventoryItems = new Array<>(); private final ArrayList<ItemData> inventoryItems = new ArrayList<>();
private final Array<Deck> boostersOwned = new Array<>(); private final Array<Deck> boostersOwned = new Array<>();
private final HashMap<String, String> equippedItems = new HashMap<>(); private final HashMap<String, Long> equippedItems = new HashMap<>();
private final List<AdventureQuestData> quests = new ArrayList<>(); private final List<AdventureQuestData> quests = new ArrayList<>();
private final List<AdventureEventData> events = new ArrayList<>(); private final List<AdventureEventData> events = new ArrayList<>();
@@ -175,7 +175,7 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
shards = difficultyData.startingShards; shards = difficultyData.startingShards;
for (String s : difficultyData.startItems) { for (String s : difficultyData.startItems) {
ItemData i = ItemData.getItem(s); ItemData i = ItemListData.getItem(s);
if (i == null) if (i == null)
continue; continue;
inventoryItems.add(i); inventoryItems.add(i);
@@ -219,25 +219,29 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
return deck; return deck;
} }
public Array<ItemData> getItems() { public ArrayList<ItemData> getItems() {
return inventoryItems; return inventoryItems;
} }
public ItemData getItemFromInventory(String name) { public ItemData getItemFromInventory(Long id) {
if (id == null)
return null;
for (ItemData data : inventoryItems) { for (ItemData data : inventoryItems) {
if (data == null) if (data == null)
continue; continue;
if (data.name.equals(name)) if (id.equals(data.longID))
return data; return data;
} }
return null; return null;
} }
public ItemData getEquippedItem(String name) { public ItemData getEquippedItem(Long id) {
if (id == null)
return null;
for (ItemData data : inventoryItems) { for (ItemData data : inventoryItems) {
if (data == null) if (data == null)
continue; continue;
if (data.name.equals(name) && data.isEquipped) if (id.equals(data.longID) && data.isEquipped)
return data; return data;
} }
return null; return null;
@@ -291,7 +295,7 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
return blessing; return blessing;
} }
public Collection<String> getEquippedItems() { public Collection<Long> getEquippedItems() {
return equippedItems.values(); return equippedItems.values();
} }
@@ -324,6 +328,7 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
@Override @Override
public void load(SaveFileData data) { public void load(SaveFileData data) {
boolean migration = false;
clear(); // Reset player data. clear(); // Reset player data.
this.statistic.load(data.readSubData("statistic")); this.statistic.load(data.readSubData("statistic"));
this.difficultyData.startingLife = data.readInt("startingLife"); this.difficultyData.startingLife = data.readInt("startingLife");
@@ -402,21 +407,25 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
if (data.containsKey("inventory")) { if (data.containsKey("inventory")) {
try { try {
ItemData[] inv = (ItemData[]) data.readObject("inventory"); ItemData[] inv = (ItemData[]) data.readObject("inventory");
for (ItemData itemData : inv) { for (int i = 0; i < inv.length; i++) {
if (itemData != null) ItemData itemData = inv[i];
if (itemData != null) {
inventoryItems.add(itemData); inventoryItems.add(itemData);
} }
}
} catch (Exception ignored) { } catch (Exception ignored) {
migration = true;
// migrate from string.. // migrate from string..
try { try {
String[] inv = (String[]) data.readObject("inventory"); String[] inv = (String[]) data.readObject("inventory");
// Prevent items with wrong names from getting through. Hell breaks loose if it causes null pointers. // Prevent items with wrong names from getting through. Hell breaks loose if it causes null pointers.
// This only needs to be done on load. // This only needs to be done on load.
for (String i : inv) { for (int j = 0; j < inv.length; j++) {
ItemData itemData = ItemData.getItem(i); String i = inv[j];
if (itemData != null) ItemData itemData = ItemListData.getItem(i);
if (itemData != null) {
inventoryItems.add(itemData); inventoryItems.add(itemData);
else { } else {
System.err.printf("Cannot find item name %s\n", i); System.err.printf("Cannot find item name %s\n", i);
// Allow official© permission for the player to get a refund. We will allow it this time. // Allow official© permission for the player to get a refund. We will allow it this time.
// TODO: Divine retribution if the player refunds too much. Use the orbital laser cannon. // TODO: Divine retribution if the player refunds too much. Use the orbital laser cannon.
@@ -430,21 +439,28 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
} }
} }
if (data.containsKey("equippedSlots") && data.containsKey("equippedItems")) { if (data.containsKey("equippedSlots") && data.containsKey("equippedItems")) {
try {
String[] slots = (String[]) data.readObject("equippedSlots"); String[] slots = (String[]) data.readObject("equippedSlots");
String[] items = (String[]) data.readObject("equippedItems"); Long[] items = (Long[]) data.readObject("equippedItems");
assert (slots.length == items.length); assert (slots.length == items.length);
// Prevent items with wrong names. If it triggered in inventory, it'll trigger here as well. // Prevent items with wrong names. If it triggered in inventory, it'll trigger here as well.
for (int i = 0; i < slots.length; i++) { for (int i = 0; i < slots.length; i++) {
ItemData itemData = getItemFromInventory(items[i]); ItemData itemData = getItemFromInventory(items[i]);
if (itemData != null) { if (itemData != null) {
if (itemData.longID == null)
itemData = itemData.clone();
if (itemData.longID != null) {
itemData.isEquipped = true; itemData.isEquipped = true;
equippedItems.put(slots[i], items[i]); equippedItems.put(slots[i], itemData.longID);
} else { } else {
System.err.printf("Cannot find equip name %s\n", items[i]); itemData.isEquipped = false;
System.err.println("Missing ID: " + itemData.name);
} }
} }
} }
} catch (Exception ignored) {}
}
if (data.containsKey("boosters")) { if (data.containsKey("boosters")) {
Deck[] decks = (Deck[]) data.readObject("boosters"); Deck[] decks = (Deck[]) data.readObject("boosters");
if (decks != null) { if (decks != null) {
@@ -609,6 +625,9 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
announceFantasy = data.containsKey("announceFantasy") && data.readBool("announceFantasy"); announceFantasy = data.containsKey("announceFantasy") && data.readBool("announceFantasy");
usingCustomDeck = data.containsKey("usingCustomDeck") && data.readBool("usingCustomDeck"); usingCustomDeck = data.containsKey("usingCustomDeck") && data.readBool("usingCustomDeck");
announceCustom = data.containsKey("announceCustom") && data.readBool("announceCustom"); announceCustom = data.containsKey("announceCustom") && data.readBool("announceCustom");
if (migration) {
getCurrentGameStage().setExtraAnnouncement(Forge.getLocalizer().getMessage("lblDataMigrationMsg"));
}
onLifeTotalChangeList.emit(); onLifeTotalChangeList.emit();
onShardsChangeList.emit(); onShardsChangeList.emit();
@@ -652,16 +671,16 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
data.store("shards", shards); data.store("shards", shards);
data.store("deckName", deck.getName()); data.store("deckName", deck.getName());
data.storeObject("inventory", inventoryItems.toArray(ItemData.class)); data.storeObject("inventory", inventoryItems.toArray(new ItemData[0]));
ArrayList<String> slots = new ArrayList<>(); ArrayList<String> slots = new ArrayList<>();
ArrayList<String> items = new ArrayList<>(); ArrayList<Long> items = new ArrayList<>();
for (Map.Entry<String, String> entry : equippedItems.entrySet()) { for (Map.Entry<String, Long> entry : equippedItems.entrySet()) {
slots.add(entry.getKey()); slots.add(entry.getKey());
items.add(entry.getValue()); items.add(entry.getValue());
} }
data.storeObject("equippedSlots", slots.toArray(new String[0])); data.storeObject("equippedSlots", slots.toArray(new String[0]));
data.storeObject("equippedItems", items.toArray(new String[0])); data.storeObject("equippedItems", items.toArray(new Long[0]));
data.storeObject("boosters", boostersOwned.toArray(Deck.class)); data.storeObject("boosters", boostersOwned.toArray(Deck.class));
@@ -973,8 +992,8 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
} }
public boolean hasColorView() { public boolean hasColorView() {
for (String name : equippedItems.values()) { for (Long id : equippedItems.values()) {
ItemData data = ItemData.getItem(name); ItemData data = getEquippedItem(id);
if (data != null && data.effect != null && data.effect.colorView) return true; if (data != null && data.effect != null && data.effect.colorView) return true;
} }
if (blessing != null) { if (blessing != null) {
@@ -985,8 +1004,8 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
public ItemData getRandomEquippedItem() { public ItemData getRandomEquippedItem() {
Array<ItemData> items = new Array<>(); Array<ItemData> items = new Array<>();
for (String name : equippedItems.values()) { for (Long id : equippedItems.values()) {
ItemData item = getEquippedItem(name); ItemData item = getEquippedItem(id);
if (item == null) if (item == null)
continue; continue;
if (isHardorInsaneDifficulty()) { if (isHardorInsaneDifficulty()) {
@@ -1002,8 +1021,8 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
} }
public ItemData getEquippedAbility1() { public ItemData getEquippedAbility1() {
for (String name : equippedItems.values()) { for (Long id : equippedItems.values()) {
ItemData data = ItemData.getItem(name); ItemData data = getEquippedItem(id);
if (data != null && "Ability1".equalsIgnoreCase(data.equipmentSlot)) { if (data != null && "Ability1".equalsIgnoreCase(data.equipmentSlot)) {
return data; return data;
} }
@@ -1012,8 +1031,8 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
} }
public ItemData getEquippedAbility2() { public ItemData getEquippedAbility2() {
for (String name : equippedItems.values()) { for (Long id : equippedItems.values()) {
ItemData data = ItemData.getItem(name); ItemData data = getEquippedItem(id);
if (data != null && "Ability2".equalsIgnoreCase(data.equipmentSlot)) { if (data != null && "Ability2".equalsIgnoreCase(data.equipmentSlot)) {
return data; return data;
} }
@@ -1023,8 +1042,8 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
public int bonusDeckCards() { public int bonusDeckCards() {
int result = 0; int result = 0;
for (String name : equippedItems.values()) { for (Long id : equippedItems.values()) {
ItemData data = ItemData.getItem(name); ItemData data = getEquippedItem(id);
if (data != null && data.effect != null && data.effect.cardRewardBonus > 0) if (data != null && data.effect != null && data.effect.cardRewardBonus > 0)
result += data.effect.cardRewardBonus; result += data.effect.cardRewardBonus;
} }
@@ -1099,7 +1118,7 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
} }
public void removeItem(String name) { public void removeItem(String name) {
ItemData item = ItemData.getItem(name); ItemData item = ItemListData.getItem(name);
if (item != null) if (item != null)
removeItem(item); removeItem(item);
} }
@@ -1107,32 +1126,32 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
public void removeItem(ItemData item) { public void removeItem(ItemData item) {
if (item == null) if (item == null)
return; return;
inventoryItems.removeValue(item, false); inventoryItems.remove(item);
if (equippedItems.values().contains(item.name) && !inventoryItems.contains(item, false)) { if (getEquippedItems().contains(item.longID) && !inventoryItems.contains(item)) {
item.isEquipped = false; item.isEquipped = false;
equippedItems.values().remove(item.name); getEquippedItems().remove(item.longID);
} }
} }
public void equip(ItemData item) { public void equip(ItemData item) {
if (equippedItems.get(item.equipmentSlot) != null && equippedItems.get(item.equipmentSlot).equals(item.name)) { if (equippedItems.get(item.equipmentSlot) != null && equippedItems.get(item.equipmentSlot) == item.longID) {
item.isEquipped = false; item.isEquipped = false;
equippedItems.remove(item.equipmentSlot); equippedItems.remove(item.equipmentSlot);
} else { } else {
item.isEquipped = true; item.isEquipped = true;
equippedItems.put(item.equipmentSlot, item.name); equippedItems.put(item.equipmentSlot, item.longID);
} }
onEquipmentChange.emit(); onEquipmentChange.emit();
} }
public String itemInSlot(String key) { public Long itemInSlot(String key) {
return equippedItems.get(key); return equippedItems.get(key);
} }
public float equipmentSpeed() { public float equipmentSpeed() {
float factor = 1.0f; float factor = 1.0f;
for (String name : equippedItems.values()) { for (Long id : equippedItems.values()) {
ItemData data = ItemData.getItem(name); ItemData data = getEquippedItem(id);
if (data != null && data.effect != null && data.effect.moveSpeed > 0.0) //Avoid negative speeds. It would be silly. if (data != null && data.effect != null && data.effect.moveSpeed > 0.0) //Avoid negative speeds. It would be silly.
factor *= data.effect.moveSpeed; factor *= data.effect.moveSpeed;
} }
@@ -1145,8 +1164,8 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
public float goldModifier(boolean sale) { public float goldModifier(boolean sale) {
float factor = 1.0f; float factor = 1.0f;
for (String name : equippedItems.values()) { for (Long id: equippedItems.values()) {
ItemData data = ItemData.getItem(name); ItemData data = getEquippedItem(id);
if (data != null && data.effect != null && data.effect.goldModifier > 0.0) //Avoid negative modifiers. if (data != null && data.effect != null && data.effect.goldModifier > 0.0) //Avoid negative modifiers.
factor *= data.effect.goldModifier; factor *= data.effect.goldModifier;
} }
@@ -1163,10 +1182,10 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
} }
public boolean hasItem(String name) { public boolean hasItem(String name) {
ItemData itemData = ItemData.getItem(name); ItemData itemData = ItemListData.getItem(name);
if (itemData == null) if (itemData == null)
return false; return false;
return inventoryItems.contains(itemData, false); return inventoryItems.contains(itemData);
} }
public int countItem(String name) { public int countItem(String name) {
@@ -1186,7 +1205,7 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
return addItem(name, true); return addItem(name, true);
} }
public boolean addItem(String name, boolean updateEvent) { public boolean addItem(String name, boolean updateEvent) {
ItemData item = ItemData.getItem(name); ItemData item = ItemListData.getItem(name);
if (item == null) if (item == null)
return false; return false;
inventoryItems.add(item); inventoryItems.add(item);

View File

@@ -9,10 +9,7 @@ import forge.Graphics;
import forge.LobbyPlayer; import forge.LobbyPlayer;
import forge.adventure.character.EnemySprite; import forge.adventure.character.EnemySprite;
import forge.adventure.character.PlayerSprite; import forge.adventure.character.PlayerSprite;
import forge.adventure.data.AdventureEventData; import forge.adventure.data.*;
import forge.adventure.data.EffectData;
import forge.adventure.data.EnemyData;
import forge.adventure.data.ItemData;
import forge.adventure.player.AdventurePlayer; import forge.adventure.player.AdventurePlayer;
import forge.adventure.stage.GameHUD; import forge.adventure.stage.GameHUD;
import forge.adventure.stage.IAfterMatch; import forge.adventure.stage.IAfterMatch;
@@ -246,13 +243,13 @@ public class DuelScene extends ForgeScene {
if (eventData == null || eventData.eventRules.allowsItems) { if (eventData == null || eventData.eventRules.allowsItems) {
//Collect and add items effects first. //Collect and add items effects first.
for (String playerItem : advPlayer.getEquippedItems()) { for (Long id : advPlayer.getEquippedItems()) {
ItemData item = ItemData.getItem(playerItem); ItemData item = Current.player().getEquippedItem(id);
if (item != null && item.effect != null) { if (item != null && item.effect != null) {
playerEffects.add(item.effect); playerEffects.add(item.effect);
if (item.effect.opponent != null) oppEffects.add(item.effect.opponent); if (item.effect.opponent != null) oppEffects.add(item.effect.opponent);
} else { } else {
System.err.printf("Item %s not found.", playerItem); System.err.printf("Item %s not found.", id);
} }
} }
} }
@@ -317,7 +314,7 @@ public class DuelScene extends ForgeScene {
if (eventData != null && eventData.eventRules.allowsItems) { if (eventData != null && eventData.eventRules.allowsItems) {
if (currentEnemy.equipment != null) { if (currentEnemy.equipment != null) {
for (String oppItem : currentEnemy.equipment) { for (String oppItem : currentEnemy.equipment) {
ItemData item = ItemData.getItem(oppItem); ItemData item = ItemListData.getItem(oppItem);
if (item == null) if (item == null)
continue; continue;
equipmentEffects.add(item.effect); equipmentEffects.add(item.effect);

View File

@@ -18,6 +18,7 @@ import forge.adventure.util.*;
import forge.deck.Deck; import forge.deck.Deck;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@@ -75,14 +76,14 @@ public class InventoryScene extends UIScene {
otherButton.setChecked(false); otherButton.setChecked(false);
} }
} }
String item = Current.player().itemInSlot(slotName); Long id = Current.player().itemInSlot(slotName);
if (item != null && !item.isEmpty()) { if (id != null) {
Button changeButton = null; Button changeButton = null;
for (Button invButton : inventoryButtons) { for (Button invButton : inventoryButtons) {
if(itemLocation.get(invButton) == null) if(itemLocation.get(invButton) == null)
continue; continue;
ItemData data = itemLocation.get(invButton).getRight(); ItemData data = itemLocation.get(invButton).getRight();
if (data != null && item.equals(data.equipmentSlot)) { if (data != null && id.equals(data.longID)) {
changeButton = invButton; changeButton = invButton;
break; break;
} }
@@ -298,8 +299,8 @@ public class InventoryScene extends UIScene {
equipButton.setDisabled(false); equipButton.setDisabled(false);
if (equipButton instanceof TextraButton) { if (equipButton instanceof TextraButton) {
TextraButton button = (TextraButton) equipButton; TextraButton button = (TextraButton) equipButton;
String item = Current.player().itemInSlot(data.equipmentSlot); Long id = Current.player().itemInSlot(data.equipmentSlot);
if (item != null && item.equals(data.name) && data.isEquipped) { if (id != null && id.equals(data.longID) && data.isEquipped) {
button.setText("Unequip"); button.setText("Unequip");
} else { } else {
button.setText("Equip"); button.setText("Equip");
@@ -342,8 +343,8 @@ public class InventoryScene extends UIScene {
repairButton.setVisible(false); repairButton.setVisible(false);
int itemSlotsUsed = 0; int itemSlotsUsed = 0;
Array<ItemData> items = new Array<>(); ArrayList<ItemData> items = new ArrayList<>();
for (int i = 0; i < Current.player().getItems().size; i++) { for (int i = 0; i < Current.player().getItems().size(); i++) {
ItemData item = Current.player().getItems().get(i); ItemData item = Current.player().getItems().get(i);
if (item == null) { if (item == null) {
continue; continue;
@@ -373,7 +374,7 @@ public class InventoryScene extends UIScene {
}); });
for (int i = 0; i < items.size; i++) { for (int i = 0; i < items.size(); i++) {
if (i % columns == 0) if (i % columns == 0)
inventory.row(); inventory.row();
Button newActor = createInventorySlot(); Button newActor = createInventorySlot();
@@ -393,7 +394,7 @@ public class InventoryScene extends UIScene {
img.setY((newActor.getHeight() - img.getHeight()) / 2); img.setY((newActor.getHeight() - img.getHeight()) / 2);
newActor.addActor(img); newActor.addActor(img);
itemLocation.put(newActor, Pair.of(item.name, item)); itemLocation.put(newActor, Pair.of(item.name, item));
if (item.isEquipped && Current.player().getEquippedItems().contains(item.name)) { if (item.isEquipped && item.longID != null && Current.player().getEquippedItems().contains(item.longID)) {
Image overlay = new Image(equipOverlay); Image overlay = new Image(equipOverlay);
overlay.setX((newActor.getWidth() - img.getWidth()) / 2); overlay.setX((newActor.getWidth() - img.getWidth()) / 2);
overlay.setY((newActor.getHeight() - img.getHeight()) / 2); overlay.setY((newActor.getHeight() - img.getHeight()) / 2);
@@ -448,10 +449,10 @@ public class InventoryScene extends UIScene {
for (Map.Entry<String, Button> slot : equipmentSlots.entrySet()) { for (Map.Entry<String, Button> slot : equipmentSlots.entrySet()) {
if (slot.getValue().getChildren().size >= 2) if (slot.getValue().getChildren().size >= 2)
slot.getValue().removeActorAt(1, false); slot.getValue().removeActorAt(1, false);
String equippedItem = Current.player().itemInSlot(slot.getKey()); Long id = Current.player().itemInSlot(slot.getKey());
if (equippedItem == null || equippedItem.isEmpty()) if (id == null)
continue; continue;
ItemData item = Current.player().getEquippedItem(equippedItem); ItemData item = Current.player().getEquippedItem(id);
if (item != null) { if (item != null) {
Image img = new Image(item.sprite()); Image img = new Image(item.sprite());
img.setX((slot.getValue().getWidth() - img.getWidth()) / 2); img.setX((slot.getValue().getWidth() - img.getWidth()) / 2);

View File

@@ -77,7 +77,7 @@ public abstract class GameStage extends Stage {
public static float maximumScrollDistance=1.5f; public static float maximumScrollDistance=1.5f;
public static float minimumScrollDistance=0.3f; public static float minimumScrollDistance=0.3f;
private String extraAnnouncement = "";
protected final Dialog dialog; protected final Dialog dialog;
protected Stage dialogStage; protected Stage dialogStage;
@@ -601,6 +601,9 @@ public abstract class GameStage extends Stage {
public void enter() { public void enter() {
stop(); stop();
if (!extraAnnouncement.isEmpty()) {
showImageDialog(extraAnnouncement, null, this::clearExtraAnnouncement);
}
} }
public void leave() { public void leave() {
@@ -701,4 +704,11 @@ public abstract class GameStage extends Stage {
return null; return null;
} }
public void setExtraAnnouncement(String message) {
extraAnnouncement = message;
}
public void clearExtraAnnouncement() {
extraAnnouncement = "";
}
} }

View File

@@ -409,6 +409,7 @@ public class WorldStage extends GameStage implements SaveFileContent {
setBounds(WorldSave.getCurrentSave().getWorld().getWidthInPixels(), WorldSave.getCurrentSave().getWorld().getHeightInPixels()); setBounds(WorldSave.getCurrentSave().getWorld().getWidthInPixels(), WorldSave.getCurrentSave().getWorld().getHeightInPixels());
GridPoint2 pos = background.translateFromWorldToChunk(player.getX(), player.getY()); GridPoint2 pos = background.translateFromWorldToChunk(player.getX(), player.getY());
background.loadChunk(pos.x, pos.y); background.loadChunk(pos.x, pos.y);
super.enter();
} }
@Override @Override

View File

@@ -3542,3 +3542,4 @@ cbPreloadCustomDrafts=Benutzerdefinierte Entwürfe vorladen
nlPreloadCustomDrafts=Wenn aktiviert, werden die benutzerdefinierten Entwurfsdateien beim Start vorab geladen (Forge benötigt beim Parsen von Entwurfsdateien eine längere Startzeit). nlPreloadCustomDrafts=Wenn aktiviert, werden die benutzerdefinierten Entwurfsdateien beim Start vorab geladen (Forge benötigt beim Parsen von Entwurfsdateien eine längere Startzeit).
lblRepairCost=Reparaturkosten: {0} ? lblRepairCost=Reparaturkosten: {0} ?
lblRepair=Reparieren lblRepair=Reparieren
lblDataMigrationMsg=Datenmigration abgeschlossen!\nBitte überprüfen Sie Ihr Inventar und Ihre Ausrüstung.

View File

@@ -3296,3 +3296,4 @@ cbPreloadCustomDrafts=Preload Custom Drafts
nlPreloadCustomDrafts=If enabled, the custom drafts files are preloaded on startup (Forge will have longer startup time when parsing drafts files). nlPreloadCustomDrafts=If enabled, the custom drafts files are preloaded on startup (Forge will have longer startup time when parsing drafts files).
lblRepairCost=Repair Cost: {0} ? lblRepairCost=Repair Cost: {0} ?
lblRepair=Repair lblRepair=Repair
lblDataMigrationMsg=Data Migration completed!\nPlease check your Inventory and Equipments.

View File

@@ -3546,3 +3546,4 @@ cbPreloadCustomDrafts=Precargar borradores personalizados
nlPreloadCustomDrafts=Si está habilitado, los archivos de borradores personalizados se precargan al inicio (Forge tendrá un tiempo de inicio más largo al analizar los archivos de borradores). nlPreloadCustomDrafts=Si está habilitado, los archivos de borradores personalizados se precargan al inicio (Forge tendrá un tiempo de inicio más largo al analizar los archivos de borradores).
lblRepairCost=Costo de reparación: {0} ? lblRepairCost=Costo de reparación: {0} ?
lblRepair=Reparar lblRepair=Reparar
lblDataMigrationMsg=¡Migración de datos completada!\nPor favor revise su inventario y equipos.

View File

@@ -3547,3 +3547,4 @@ cbPreloadCustomDrafts=Précharger les brouillons personnalisés
nlPreloadCustomDrafts=Si cette option est activée, les fichiers de brouillons personnalisés sont préchargés au démarrage (Forge aura un temps de démarrage plus long lors de l'analyse des fichiers de brouillons). nlPreloadCustomDrafts=Si cette option est activée, les fichiers de brouillons personnalisés sont préchargés au démarrage (Forge aura un temps de démarrage plus long lors de l'analyse des fichiers de brouillons).
lblRepairCost=Coût de réparation : {0} ? lblRepairCost=Coût de réparation : {0} ?
lblRepair=Réparation lblRepair=Réparation
lblDataMigrationMsg=Migration des données terminée!\nVeuillez vérifier votre inventaire et vos équipements.

View File

@@ -3545,3 +3545,4 @@ cbPreloadCustomDrafts=Precarica bozze personalizzate
nlPreloadCustomDrafts=Se abilitato, i file delle bozze personalizzate vengono precaricati all'avvio (Forge avrà tempi di avvio più lunghi durante l'analisi dei file delle bozze). nlPreloadCustomDrafts=Se abilitato, i file delle bozze personalizzate vengono precaricati all'avvio (Forge avrà tempi di avvio più lunghi durante l'analisi dei file delle bozze).
lblRepairCost=Costo di riparazione: {0} ? lblRepairCost=Costo di riparazione: {0} ?
lblRepair=Riparazione lblRepair=Riparazione
lblDataMigrationMsg=Migrazione dati completata!\nControlla il tuo inventario e le tue attrezzature.

View File

@@ -3541,3 +3541,4 @@ cbPreloadCustomDrafts=カスタムドラフトをプリロードする
nlPreloadCustomDrafts=有効にすると、起動時にカスタム ドラフト ファイルがプリロードされます (ドラフト ファイルを解析するときに Forge の起動時間が長くなります)。 nlPreloadCustomDrafts=有効にすると、起動時にカスタム ドラフト ファイルがプリロードされます (ドラフト ファイルを解析するときに Forge の起動時間が長くなります)。
lblRepairCost=修理費用: {0}? lblRepairCost=修理費用: {0}?
lblRepair=修理 lblRepair=修理
lblDataMigrationMsg=データ移行が完了しました!\nインベントリと装備を確認してください。

View File

@@ -3630,3 +3630,4 @@ cbPreloadCustomDrafts=Pré-carregar rascunhos personalizados
nlPreloadCustomDrafts=Se habilitado, os arquivos de rascunhos personalizados serão pré-carregados na inicialização (o Forge terá um tempo de inicialização maior ao analisar arquivos de rascunhos). nlPreloadCustomDrafts=Se habilitado, os arquivos de rascunhos personalizados serão pré-carregados na inicialização (o Forge terá um tempo de inicialização maior ao analisar arquivos de rascunhos).
lblRepairCost=Custo do reparo: {0} ? lblRepairCost=Custo do reparo: {0} ?
lblRepair=Reparar lblRepair=Reparar
lblDataMigrationMsg=Migração de dados concluída!\nVerifique seu inventário e equipamentos.

View File

@@ -3532,3 +3532,4 @@ cbPreloadCustomDrafts=预加载自定义草稿
nlPreloadCustomDrafts=如果启用自定义草稿文件将在启动时预加载Forge 在解析草稿文件时会有更长的启动时间)。 nlPreloadCustomDrafts=如果启用自定义草稿文件将在启动时预加载Forge 在解析草稿文件时会有更长的启动时间)。
lblRepairCost=维修费用:{0} lblRepairCost=维修费用:{0}
lblRepair=维修 lblRepair=维修
lblDataMigrationMsg=数据迁移完成!\n请检查您的库存和设备。