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){
removeItem = other.removeItem;
addItem = other.removeItem;
addItem = other.addItem;
addLife = other.addLife;
addGold = other.addGold;
addShards = other.addShards;

View File

@@ -1,20 +1,17 @@
package forge.adventure.data;
import com.badlogic.gdx.files.FileHandle;
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.Paths;
import java.io.Serializable;
import java.util.UUID;
/**
* Data class that will be used to read Json configuration files
* ItemData
* contains the information for equipment and items.
*/
public class ItemData implements Serializable {
public class ItemData implements Serializable, Cloneable {
private static final long serialVersionUID = 1L;
public String name;
public String equipmentSlot;
@@ -28,6 +25,7 @@ public class ItemData implements Serializable {
public boolean usableInPoi;
public boolean isCracked;
public boolean isEquipped;
public Long longID;
public String commandOnUse;
public int shardsNeeded;
public DialogData dialogOnUse;
@@ -56,28 +54,6 @@ public class ItemData implements Serializable {
public Sprite sprite() {
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() {
String result = "";
@@ -96,4 +72,14 @@ public class ItemData implements Serializable {
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.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import forge.StaticData;
import forge.adventure.util.*;
import forge.adventure.world.WorldSave;
@@ -218,12 +217,12 @@ public class RewardData implements Serializable {
if(itemNames!=null)
{
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()) {
for(int i=0;i<count+addedCount;i++) {
ret.add(new Reward(ItemData.getItem(itemName)));
ret.add(new Reward(ItemListData.getItem(itemName)));
}
}
break;
@@ -263,21 +262,12 @@ public class RewardData implements Serializable {
}
}
break;
}
case "landSketchbookShop":
List<ItemData> sketchbookItems = Lists.newArrayList(ItemData.getAllItems());
sketchbookItems.removeIf(new Predicate<ItemData>() {
@Override
public boolean test(ItemData itemData) {
return itemData.questItem || !itemData.getName().contains("Landscape Sketchbook");
}
});
Array<ItemData> sketchbookItems = ItemListData.getSketchBooks();
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));
}

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

View File

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

View File

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

View File

@@ -101,17 +101,17 @@ public class TileMapScene extends HudScene {
if (WorldSave.getCurrentSave().getPlayer().hasAnnounceFantasy()) {
WorldSave.getCurrentSave().getPlayer().clearAnnounceFantasy();
MapStage.getInstance().showDeckAwardDialog("{BLINK=WHITE;RED}" +
Forge.getLocalizer().getMessage("lblMode") + " " +
Forge.getLocalizer().getMessage("lblChaos") + "{ENDBLINK}\n" +
Forge.getLocalizer().getMessage("lblChaosModeDescription"),
WorldSave.getCurrentSave().getPlayer().getSelectedDeck(), this::initializeDialogs);
Forge.getLocalizer().getMessage("lblMode") + " " +
Forge.getLocalizer().getMessage("lblChaos") + "{ENDBLINK}\n" +
Forge.getLocalizer().getMessage("lblChaosModeDescription"),
WorldSave.getCurrentSave().getPlayer().getSelectedDeck(), this::initializeDialogs);
} else if (WorldSave.getCurrentSave().getPlayer().hasAnnounceCustom()) {
WorldSave.getCurrentSave().getPlayer().clearAnnounceCustom();
MapStage.getInstance().showDeckAwardDialog("{GRADIENT}" +
Forge.getLocalizer().getMessage("lblMode") + " " +
Forge.getLocalizer().getMessage("lblCustom") + "{ENDGRADIENT}\n" +
Forge.getLocalizer().getMessage("lblCustomModeDescription"),
WorldSave.getCurrentSave().getPlayer().getSelectedDeck(), this::initializeDialogs);
Forge.getLocalizer().getMessage("lblMode") + " " +
Forge.getLocalizer().getMessage("lblCustom") + "{ENDGRADIENT}\n" +
Forge.getLocalizer().getMessage("lblCustomModeDescription"),
WorldSave.getCurrentSave().getPlayer().getSelectedDeck(), this::initializeDialogs);
} else {
initializeDialogs();
}

View File

@@ -77,7 +77,7 @@ public abstract class GameStage extends Stage {
public static float maximumScrollDistance=1.5f;
public static float minimumScrollDistance=0.3f;
private String extraAnnouncement = "";
protected final Dialog dialog;
protected Stage dialogStage;
@@ -601,6 +601,9 @@ public abstract class GameStage extends Stage {
public void enter() {
stop();
if (!extraAnnouncement.isEmpty()) {
showImageDialog(extraAnnouncement, null, this::clearExtraAnnouncement);
}
}
public void leave() {
@@ -674,14 +677,14 @@ public abstract class GameStage extends Stage {
Timer.schedule(new Timer.Task() {
@Override
public void run() {
showImageDialog(Current.generateDefeatMessage(), getDefeatBadge(),
() -> FThreads.invokeInEdtNowOrLater(() -> Forge.setTransitionScreen(new CoverScreen(() -> {
Forge.advFreezePlayerControls = false;
WorldStage.getInstance().setPosition(new Vector2(poi.getPosition().x - 16f, poi.getPosition().y + 16f));
WorldStage.getInstance().loadPOI(poi);
WorldSave.getCurrentSave().autoSave();
Forge.clearTransitionScreen();
}, Forge.takeScreenshot()))));
showImageDialog(Current.generateDefeatMessage(), getDefeatBadge(),
() -> FThreads.invokeInEdtNowOrLater(() -> Forge.setTransitionScreen(new CoverScreen(() -> {
Forge.advFreezePlayerControls = false;
WorldStage.getInstance().setPosition(new Vector2(poi.getPosition().x - 16f, poi.getPosition().y + 16f));
WorldStage.getInstance().loadPOI(poi);
WorldSave.getCurrentSave().autoSave();
Forge.clearTransitionScreen();
}, Forge.takeScreenshot()))));
}
}, 1f);
}//Spawn shouldn't be null
@@ -701,4 +704,11 @@ public abstract class GameStage extends Stage {
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());
GridPoint2 pos = background.translateFromWorldToChunk(player.getX(), player.getY());
background.loadChunk(pos.x, pos.y);
super.enter();
}
@Override

View File

@@ -3541,4 +3541,5 @@ lblSuccess=Erfolg
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).
lblRepairCost=Reparaturkosten: {0} ?
lblRepair=Reparieren
lblRepair=Reparieren
lblDataMigrationMsg=Datenmigration abgeschlossen!\nBitte überprüfen Sie Ihr Inventar und Ihre Ausrüstung.

View File

@@ -3295,4 +3295,5 @@ lblSuccess=Success
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).
lblRepairCost=Repair Cost: {0} ?
lblRepair=Repair
lblRepair=Repair
lblDataMigrationMsg=Data Migration completed!\nPlease check your Inventory and Equipments.

View File

@@ -3545,4 +3545,5 @@ lblSuccess=Éxito
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).
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

@@ -3546,4 +3546,5 @@ lblSuccess=Succès
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).
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

@@ -3544,4 +3544,5 @@ lblSuccess=Successo
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).
lblRepairCost=Costo di riparazione: {0} ?
lblRepair=Riparazione
lblRepair=Riparazione
lblDataMigrationMsg=Migrazione dati completata!\nControlla il tuo inventario e le tue attrezzature.

View File

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

View File

@@ -3629,4 +3629,5 @@ lblSuccess=Sucesso
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).
lblRepairCost=Custo do reparo: {0} ?
lblRepair=Reparar
lblRepair=Reparar
lblDataMigrationMsg=Migração de dados concluída!\nVerifique seu inventário e equipamentos.

View File

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