* Fix typo

* Support old save files
This commit is contained in:
Eradev
2025-07-08 19:20:16 -04:00
committed by GitHub
parent 286ade792f
commit cc4a43f0a2
4 changed files with 34 additions and 30 deletions

View File

@@ -11,7 +11,7 @@ public class DifficultyData {
public String name=""; public String name="";
public int startingLife=10; public int startingLife=10;
public int startingShards=1; public int startingShards=1;
public int staringMoney=10; public int startingMoney=10;
public float enemyLifeFactor=1; public float enemyLifeFactor=1;
public boolean startingDifficulty; public boolean startingDifficulty;
public int spawnRank = 1; //0 for "easy", 1 for "normal", 2 for "hard". To filter map spawns based on this. public int spawnRank = 1; //0 for "easy", 1 for "normal", 2 for "hard". To filter map spawns based on this.

View File

@@ -7,6 +7,7 @@ import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Null; import com.badlogic.gdx.utils.Null;
import com.github.tommyettinger.textra.TextraLabel; import com.github.tommyettinger.textra.TextraLabel;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import forge.Forge; import forge.Forge;
import forge.adventure.data.*; import forge.adventure.data.*;
import forge.adventure.pointofintrest.PointOfInterestChanges; import forge.adventure.pointofintrest.PointOfInterestChanges;
@@ -130,7 +131,6 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
AdventureQuestController.clear(); AdventureQuestController.clear();
} }
static public AdventurePlayer current() { static public AdventurePlayer current() {
return WorldSave.getCurrentSave().getPlayer(); return WorldSave.getCurrentSave().getPlayer();
} }
@@ -151,7 +151,7 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
cards.addAllFlat(deck.getAllCardsInASinglePool().toFlatList()); cards.addAllFlat(deck.getAllCardsInASinglePool().toFlatList());
this.difficultyData.startingLife = difficultyData.startingLife; this.difficultyData.startingLife = difficultyData.startingLife;
this.difficultyData.staringMoney = difficultyData.staringMoney; this.difficultyData.startingMoney = difficultyData.startingMoney;
this.difficultyData.startingDifficulty = difficultyData.startingDifficulty; this.difficultyData.startingDifficulty = difficultyData.startingDifficulty;
this.difficultyData.name = difficultyData.name; this.difficultyData.name = difficultyData.name;
this.difficultyData.spawnRank = difficultyData.spawnRank; this.difficultyData.spawnRank = difficultyData.spawnRank;
@@ -161,7 +161,7 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
this.difficultyData.goldLoss = difficultyData.goldLoss; this.difficultyData.goldLoss = difficultyData.goldLoss;
this.difficultyData.lifeLoss = difficultyData.lifeLoss; this.difficultyData.lifeLoss = difficultyData.lifeLoss;
gold = difficultyData.staringMoney; gold = difficultyData.startingMoney;
name = n; name = n;
heroRace = race; heroRace = race;
avatarIndex = avatar; avatarIndex = avatar;
@@ -190,7 +190,7 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
maxLife = diff.startingLife; maxLife = diff.startingLife;
this.difficultyData.startingShards = diff.startingShards; this.difficultyData.startingShards = diff.startingShards;
this.difficultyData.startingLife = diff.startingLife; this.difficultyData.startingLife = diff.startingLife;
this.difficultyData.staringMoney = diff.staringMoney; this.difficultyData.startingMoney = diff.startingMoney;
this.difficultyData.startingDifficulty = diff.startingDifficulty; this.difficultyData.startingDifficulty = diff.startingDifficulty;
this.difficultyData.name = diff.name; this.difficultyData.name = diff.name;
this.difficultyData.spawnRank = diff.spawnRank; this.difficultyData.spawnRank = diff.spawnRank;
@@ -300,10 +300,15 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
@Override @Override
public void load(SaveFileData data) { public void load(SaveFileData data) {
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");
this.difficultyData.staringMoney = data.readInt("staringMoney"); // Support for old typo
if (data.containsKey("staringMoney")) {
this.difficultyData.startingMoney = data.readInt("staringMoney");
} else {
this.difficultyData.startingMoney = data.readInt("startingMoney");
}
this.difficultyData.startingDifficulty = data.readBool("startingDifficulty"); this.difficultyData.startingDifficulty = data.readBool("startingDifficulty");
this.difficultyData.name = data.readString("difficultyName"); this.difficultyData.name = data.readString("difficultyName");
this.difficultyData.enemyLifeFactor = data.readFloat("enemyLifeFactor"); this.difficultyData.enemyLifeFactor = data.readFloat("enemyLifeFactor");
@@ -372,14 +377,14 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
if (data.containsKey("inventory")) { if (data.containsKey("inventory")) {
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 (String i : inv) {
if (ItemData.getItem(i) != null) inventoryItems.add(i); if (ItemData.getItem(i) != null) inventoryItems.add(i);
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.
//TODoooo: 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.
System.out.println("Developers have blessed you! You are allowed to cheat the cost of the item back!"); System.out.println("Developers have blessed you! You are allowed to cheat the cost of the item back!");
} }
} }
@@ -389,7 +394,7 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
String[] items = (String[]) data.readObject("equippedItems"); String[] items = (String[]) data.readObject("equippedItems");
assert (slots.length == items.length); assert (slots.length == items.length);
//Like above, 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++) {
if (ItemData.getItem(items[i]) != null) if (ItemData.getItem(items[i]) != null)
equippedItems.put(slots[i], items[i]); equippedItems.put(slots[i], items[i]);
@@ -454,15 +459,15 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
} }
} }
// load decks // Load decks
// check if this save has dynamic deck count, use set-count load if not // Check if this save has dynamic deck count, use set-count load if not
boolean hasDynamicDeckCount = data.containsKey("deckCount"); boolean hasDynamicDeckCount = data.containsKey("deckCount");
if (hasDynamicDeckCount) { if (hasDynamicDeckCount) {
int dynamicDeckCount = data.readInt("deckCount"); int dynamicDeckCount = data.readInt("deckCount");
// in case the save had previously saved more decks than the current version allows (in case of the max being lowered) // In case the save had previously saved more decks than the current version allows (in case of the max being lowered)
dynamicDeckCount = Math.min(MAX_DECK_COUNT, dynamicDeckCount); dynamicDeckCount = Math.min(MAX_DECK_COUNT, dynamicDeckCount);
for (int i = 0; i < dynamicDeckCount; i++){ for (int i = 0; i < dynamicDeckCount; i++){
// the first x elements are pre-created // The first x elements are pre-created
if (i < MIN_DECK_COUNT) { if (i < MIN_DECK_COUNT) {
decks.set(i, new Deck(data.readString("deck_name_" + i))); decks.set(i, new Deck(data.readString("deck_name_" + i)));
} }
@@ -473,11 +478,11 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
if (data.containsKey("sideBoardCards_" + i)) if (data.containsKey("sideBoardCards_" + i))
decks.get(i).getOrCreate(DeckSection.Sideboard).addAll(CardPool.fromCardList(Lists.newArrayList((String[]) data.readObject("sideBoardCards_" + i)))); decks.get(i).getOrCreate(DeckSection.Sideboard).addAll(CardPool.fromCardList(Lists.newArrayList((String[]) data.readObject("sideBoardCards_" + i))));
} }
// in case we allow removing decks from the deck selection GUI, populate up to the minimum // In case we allow removing decks from the deck selection GUI, populate up to the minimum
for (int i = dynamicDeckCount++; i < MIN_DECK_COUNT; i++) { for (int i = dynamicDeckCount++; i < MIN_DECK_COUNT; i++) {
decks.set(i, new Deck(Forge.getLocalizer().getMessage("lblEmptyDeck"))); decks.set(i, new Deck(Forge.getLocalizer().getMessage("lblEmptyDeck")));
} }
// legacy load // Legacy load
} else { } else {
for (int i = 0; i < MIN_DECK_COUNT; i++) { for (int i = 0; i < MIN_DECK_COUNT; i++) {
if (!data.containsKey("deck_name_" + i)) { if (!data.containsKey("deck_name_" + i)) {
@@ -502,7 +507,7 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
} }
} }
if (data.containsKey("noSellCards")) { if (data.containsKey("noSellCards")) {
//Legacy list of unsellable cards. Now done via CardRequest flags. Convert the corresponding cards. // Legacy list of unsellable cards. Now done via CardRequest flags. Convert the corresponding cards.
PaperCard[] items = (PaperCard[]) data.readObject("noSellCards"); PaperCard[] items = (PaperCard[]) data.readObject("noSellCards");
CardPool noSellPool = new CardPool(); CardPool noSellPool = new CardPool();
noSellPool.addAllFlat(List.of(items)); noSellPool.addAllFlat(List.of(items));
@@ -524,7 +529,7 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
System.out.printf("Converted legacy noSellCards item - %s (%d / %d copies)%n", item, noSellCopies, totalCopies); System.out.printf("Converted legacy noSellCards item - %s (%d / %d copies)%n", item, noSellCopies, totalCopies);
//Also go through their decks and update cards there. // Also go through their decks and update cards there.
for (Deck deck : decks) { for (Deck deck : decks) {
int inUse = 0; int inUse = 0;
for (Map.Entry<DeckSection, CardPool> section : deck) { for (Map.Entry<DeckSection, CardPool> section : deck) {
@@ -565,7 +570,7 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
data.store("statistic", this.statistic.save()); data.store("statistic", this.statistic.save());
data.store("startingLife", this.difficultyData.startingLife); data.store("startingLife", this.difficultyData.startingLife);
data.store("staringMoney", this.difficultyData.staringMoney); data.store("startingMoney", this.difficultyData.startingMoney);
data.store("startingDifficulty", this.difficultyData.startingDifficulty); data.store("startingDifficulty", this.difficultyData.startingDifficulty);
data.store("difficultyName", this.difficultyData.name); data.store("difficultyName", this.difficultyData.name);
data.store("enemyLifeFactor", this.difficultyData.enemyLifeFactor); data.store("enemyLifeFactor", this.difficultyData.enemyLifeFactor);
@@ -610,7 +615,7 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
data.storeObject("blessing", blessing); data.storeObject("blessing", blessing);
//Save character flags. // Save character flags.
ArrayList<String> characterFlagsKey = new ArrayList<>(); ArrayList<String> characterFlagsKey = new ArrayList<>();
ArrayList<Byte> characterFlagsValue = new ArrayList<>(); ArrayList<Byte> characterFlagsValue = new ArrayList<>();
for (Map.Entry<String, Byte> entry : characterFlags.entrySet()) { for (Map.Entry<String, Byte> entry : characterFlags.entrySet()) {
@@ -620,7 +625,7 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
data.storeObject("characterFlagsKey", characterFlagsKey.toArray(new String[0])); data.storeObject("characterFlagsKey", characterFlagsKey.toArray(new String[0]));
data.storeObject("characterFlagsValue", characterFlagsValue.toArray(new Byte[0])); data.storeObject("characterFlagsValue", characterFlagsValue.toArray(new Byte[0]));
//Save quest flags. // Save quest flags.
ArrayList<String> questFlagsKey = new ArrayList<>(); ArrayList<String> questFlagsKey = new ArrayList<>();
ArrayList<Byte> questFlagsValue = new ArrayList<>(); ArrayList<Byte> questFlagsValue = new ArrayList<>();
for (Map.Entry<String, Byte> entry : questFlags.entrySet()) { for (Map.Entry<String, Byte> entry : questFlags.entrySet()) {
@@ -818,7 +823,7 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
onLifeTotalChangeList.emit(); onLifeTotalChangeList.emit();
onGoldChangeList.emit(); onGoldChangeList.emit();
return life < 1; return life < 1;
//If true, the player would have had 0 or less, and thus is actually "defeated" if the caller cares about it // If true, the player would have had 0 or less, and thus is actually "defeated" if the caller cares about it
} }
public void win() { public void win() {

View File

@@ -354,7 +354,7 @@ public class NewGameScene extends MenuScene {
matchImpacts.name = "Duels"; matchImpacts.name = "Duels";
DialogData economyImpacts = new DialogData(); DialogData economyImpacts = new DialogData();
economyImpacts.text = String.format("Difficulty: %s\nStarting Gold: %d\nStarting Mana Shards: %d\nCard Sale Price: %d%%\nMana Shard Sale Price: %d%%\nRandom loot rate: %d%%", selectedDifficulty.name, selectedDifficulty.staringMoney, selectedDifficulty.startingShards, (int) (selectedDifficulty.sellFactor * 100), (int) (selectedDifficulty.shardSellRatio * 100), (int) (selectedDifficulty.rewardMaxFactor * 100)); economyImpacts.text = String.format("Difficulty: %s\nStarting Gold: %d\nStarting Mana Shards: %d\nCard Sale Price: %d%%\nMana Shard Sale Price: %d%%\nRandom loot rate: %d%%", selectedDifficulty.name, selectedDifficulty.startingMoney, selectedDifficulty.startingShards, (int) (selectedDifficulty.sellFactor * 100), (int) (selectedDifficulty.shardSellRatio * 100), (int) (selectedDifficulty.rewardMaxFactor * 100));
economyImpacts.name = "Economy"; economyImpacts.name = "Economy";
difficultySummary.options = new DialogData[3]; difficultySummary.options = new DialogData[3];

View File

@@ -68,7 +68,6 @@
"Anax and Cymede & Kynaios and Tiro", "Anax and Cymede & Kynaios and Tiro",
"Call from the Grave", "Call from the Grave",
"Mise" "Mise"
], ],
"restrictedEditions": [ "restrictedEditions": [
"HTR", "HTR",
@@ -94,7 +93,7 @@
"name": "Easy", "name": "Easy",
"startingLife": 16, "startingLife": 16,
"startingShards": 5, "startingShards": 5,
"staringMoney": 500, "startingMoney": 500,
"enemyLifeFactor": 0.8, "enemyLifeFactor": 0.8,
"spawnRank": 0, "spawnRank": 0,
"goldLoss": 0.02, "goldLoss": 0.02,
@@ -131,7 +130,7 @@
"name": "Normal", "name": "Normal",
"startingLife": 12, "startingLife": 12,
"startingShards": 2, "startingShards": 2,
"staringMoney": 250, "startingMoney": 250,
"startingDifficulty": true, "startingDifficulty": true,
"enemyLifeFactor": 1.0, "enemyLifeFactor": 1.0,
"rewardMaxFactor" : 1.0, "rewardMaxFactor" : 1.0,
@@ -168,7 +167,7 @@
"name": "Hard", "name": "Hard",
"startingLife": 8, "startingLife": 8,
"startingShards": 0, "startingShards": 0,
"staringMoney": 125, "startingMoney": 125,
"enemyLifeFactor": 1.5, "enemyLifeFactor": 1.5,
"rewardMaxFactor" : 0.5, "rewardMaxFactor" : 0.5,
"spawnRank": 2, "spawnRank": 2,
@@ -201,7 +200,7 @@
"name": "Insane", "name": "Insane",
"startingLife": 7, "startingLife": 7,
"startingShards": 0, "startingShards": 0,
"staringMoney": 0, "startingMoney": 0,
"enemyLifeFactor": 2.5, "enemyLifeFactor": 2.5,
"rewardMaxFactor" : 0.0, "rewardMaxFactor" : 0.0,
"spawnRank": 2, "spawnRank": 2,