From 844afc2a95101a8549dde2ff2a2f1bb772d643c7 Mon Sep 17 00:00:00 2001 From: Oskar Wiksten Date: Sun, 21 Oct 2012 13:24:21 +0200 Subject: [PATCH] WIP 4 actor traits refactoring - Created savegame loaders for pre-versioncode-33. --- .../controller/ItemController.java | 19 -- .../rpg/AndorsTrail/model/CombatTraits.java | 17 +- .../rpg/AndorsTrail/model/ModelContainer.java | 2 +- .../rpg/AndorsTrail/model/actor/Actor.java | 23 +- .../AndorsTrail/model/actor/ActorTraits.java | 34 +- .../rpg/AndorsTrail/model/actor/Monster.java | 32 +- .../rpg/AndorsTrail/model/actor/Player.java | 139 +++----- .../rpg/AndorsTrail/model/item/Inventory.java | 18 +- .../AndorsTrail/model/item/ItemContainer.java | 26 -- .../gpl/rpg/AndorsTrail/model/item/Loot.java | 3 +- ...ySavegameFormatReaderForItemContainer.java | 40 +++ .../LegacySavegameFormatReaderForMonster.java | 105 ++++++ .../LegacySavegameFormatReaderForPlayer.java | 310 ++++++++++++++++++ 13 files changed, 578 insertions(+), 190 deletions(-) create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/LegacySavegameFormatReaderForItemContainer.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/LegacySavegameFormatReaderForMonster.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/LegacySavegameFormatReaderForPlayer.java diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ItemController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ItemController.java index f64dce893..b137cb4e9 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ItemController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ItemController.java @@ -6,7 +6,6 @@ import com.gpl.rpg.AndorsTrail.Dialogs; import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.model.ModelContainer; -import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionEffect; import com.gpl.rpg.AndorsTrail.model.ability.SkillCollection; import com.gpl.rpg.AndorsTrail.model.ability.traits.AbilityModifierTraits; import com.gpl.rpg.AndorsTrail.model.actor.Player; @@ -325,22 +324,4 @@ public final class ItemController { model.player.inventory.quickitem[quickSlotId] = itemType; view.mainActivity.updateStatus(); } - - public static void correctActorConditionsFromItemsPre0611b1(Player player, String conditionTypeID, WorldContext world, String itemTypeIDWithCondition) { - if (!player.hasCondition(conditionTypeID)) return; - boolean hasItemWithCondition = false; - for (ItemType t : player.inventory.wear) { - if (t == null) continue; - if (t.effects_equip == null) continue; - if (t.effects_equip.addedConditions == null) continue; - for(ActorConditionEffect e : t.effects_equip.addedConditions) { - if (!e.conditionType.conditionTypeID.equals(conditionTypeID)) continue; - hasItemWithCondition = true; - break; - } - } - if (hasItemWithCondition) return; - - ActorStatsController.removeConditionsFromUnequippedItem(player, world.itemTypes.getItemType(itemTypeIDWithCondition)); - } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/CombatTraits.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/CombatTraits.java index b3ac0bab2..22648c3f3 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/CombatTraits.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/CombatTraits.java @@ -7,6 +7,7 @@ import java.io.IOException; import android.util.FloatMath; import com.gpl.rpg.AndorsTrail.model.actor.ActorTraits; +import com.gpl.rpg.AndorsTrail.savegames.LegacySavegameFormatReaderForPlayer.LegacySavegameData_Actor; import com.gpl.rpg.AndorsTrail.util.Range; public class CombatTraits { @@ -111,16 +112,22 @@ public class CombatTraits { this.attackCost = src.readInt(); this.attackChance = src.readInt(); this.criticalSkill = src.readInt(); - if (fileversion <= 20) { - this.criticalMultiplier = src.readInt(); - } else { - this.criticalMultiplier = src.readFloat(); - } + this.criticalMultiplier = src.readFloat(); this.damagePotential = new Range(src, fileversion); this.blockChance = src.readInt(); this.damageResistance = src.readInt(); } + public CombatTraits(LegacySavegameData_Actor savegameData) { + this.attackCost = savegameData.attackCost; + this.attackChance = savegameData.attackChance; + this.criticalSkill = savegameData.criticalSkill; + this.criticalMultiplier = savegameData.criticalMultiplier; + this.damagePotential = savegameData.damagePotential; + this.blockChance = savegameData.blockChance; + this.damageResistance = savegameData.damageResistance; + } + public void writeToParcel(DataOutputStream dest, int flags) throws IOException { dest.writeInt(attackCost); dest.writeInt(attackChance); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/ModelContainer.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/ModelContainer.java index ef873d48b..351c8ae36 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/ModelContainer.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/ModelContainer.java @@ -26,7 +26,7 @@ public final class ModelContainer { // ====== PARCELABLE =================================================================== public ModelContainer(DataInputStream src, WorldContext world, int fileversion) throws IOException { - this.player = new Player(src, world, fileversion); + this.player = Player.readFromParcel(src, world, fileversion); this.currentMap = world.maps.findPredefinedMap(src.readUTF()); this.uiSelections = new InterfaceData(src, world, fileversion); if (uiSelections.selectedPosition != null) { diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Actor.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Actor.java index 360275962..b0086bb3d 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Actor.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Actor.java @@ -9,6 +9,7 @@ import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.model.CombatTraits; import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition; import com.gpl.rpg.AndorsTrail.model.listeners.ActorConditionListeners; +import com.gpl.rpg.AndorsTrail.savegames.LegacySavegameFormatReaderForPlayer.LegacySavegameData_Actor; import com.gpl.rpg.AndorsTrail.util.Coord; import com.gpl.rpg.AndorsTrail.util.CoordRect; import com.gpl.rpg.AndorsTrail.util.Range; @@ -86,8 +87,7 @@ public class Actor { this.isImmuneToCriticalHits = isImmuneToCriticalHits; CombatTraits combatTraits = null; - boolean readCombatTraits = true; - if (fileversion >= 25) readCombatTraits = src.readBoolean(); + boolean readCombatTraits = src.readBoolean(); if (readCombatTraits) combatTraits = new CombatTraits(src, fileversion); this.baseTraits = isPlayer ? new ActorTraits(src, world, fileversion) : baseTraits; @@ -101,13 +101,26 @@ public class Actor { this.health = new Range(src, fileversion); this.position = new Coord(src, fileversion); this.rectPosition = new CoordRect(position, this.baseTraits.tileSize); - if (fileversion <= 16) return; - final int n = src.readInt(); - for(int i = 0; i < n ; ++i) { + final int numConditions = src.readInt(); + for(int i = 0; i < numConditions; ++i) { conditions.add(new ActorCondition(src, world, fileversion)); } } + public Actor(LegacySavegameData_Actor savegameData, boolean isPlayer) { + this.isPlayer = isPlayer; + this.isImmuneToCriticalHits = savegameData.isImmuneToCriticalHits; + this.baseTraits = new ActorTraits(savegameData); + this.iconID = savegameData.iconID; + this.tileSize = savegameData.tileSize; + this.combatTraits = new CombatTraits(savegameData); + this.ap = savegameData.ap; + this.health = savegameData.health; + this.position = savegameData.position; + this.rectPosition = savegameData.rectPosition; + this.conditions.addAll(savegameData.conditions); + } + public void writeToParcel(DataOutputStream dest, int flags) throws IOException { if (this.combatTraits.isSameValuesAs(baseTraits)) { dest.writeBoolean(false); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/ActorTraits.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/ActorTraits.java index 032120b58..710d8d6c1 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/ActorTraits.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/ActorTraits.java @@ -9,6 +9,7 @@ import android.util.FloatMath; import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.model.CombatTraits; import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnUse; +import com.gpl.rpg.AndorsTrail.savegames.LegacySavegameFormatReaderForPlayer.LegacySavegameData_Actor; import com.gpl.rpg.AndorsTrail.util.Range; import com.gpl.rpg.AndorsTrail.util.Size; @@ -108,24 +109,31 @@ public class ActorTraits { this.maxHP = src.readInt(); this.name = src.readUTF(); this.moveCost = src.readInt(); - this.attackCost = src.readInt(); this.attackChance = src.readInt(); this.criticalSkill = src.readInt(); - if (fileversion <= 20) { - this.criticalMultiplier = src.readInt(); - } else { - this.criticalMultiplier = src.readFloat(); - } + this.criticalMultiplier = src.readFloat(); this.damagePotential = new Range(src, fileversion); this.blockChance = src.readInt(); this.damageResistance = src.readInt(); - - if (fileversion <= 16) { - this.baseMoveCost = this.moveCost; - } else { - this.baseMoveCost = src.readInt(); - } + this.baseMoveCost = src.readInt(); + } + + public ActorTraits(LegacySavegameData_Actor savegameData) { + this.iconID = savegameData.iconID; + this.tileSize = savegameData.tileSize; + this.maxAP = savegameData.maxAP; + this.maxHP = savegameData.maxHP; + this.name = savegameData.name; + this.moveCost = savegameData.moveCost; + this.attackCost = savegameData.baseAttackCost; + this.attackChance = savegameData.baseAttackChance; + this.criticalSkill = savegameData.baseCriticalSkill; + this.criticalMultiplier = savegameData.baseCriticalMultiplier; + this.damagePotential = savegameData.baseDamagePotential; + this.blockChance = savegameData.baseBlockChance; + this.damageResistance = savegameData.baseDamageResistance; + this.baseMoveCost = savegameData.baseMoveCost; } public void writeToParcel(DataOutputStream dest, int flags) throws IOException { @@ -135,7 +143,6 @@ public class ActorTraits { dest.writeInt(maxHP); dest.writeUTF(name); dest.writeInt(moveCost); - dest.writeInt(attackCost); dest.writeInt(attackChance); dest.writeInt(criticalSkill); @@ -143,7 +150,6 @@ public class ActorTraits { damagePotential.writeToParcel(dest, flags); dest.writeInt(blockChance); dest.writeInt(damageResistance); - dest.writeInt(baseMoveCost); } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Monster.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Monster.java index 224a85278..a68e70a92 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Monster.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Monster.java @@ -10,6 +10,8 @@ import com.gpl.rpg.AndorsTrail.model.ability.SkillCollection; import com.gpl.rpg.AndorsTrail.model.item.DropList; import com.gpl.rpg.AndorsTrail.model.item.ItemContainer; import com.gpl.rpg.AndorsTrail.model.item.Loot; +import com.gpl.rpg.AndorsTrail.savegames.LegacySavegameFormatReaderForMonster; +import com.gpl.rpg.AndorsTrail.savegames.LegacySavegameFormatReaderForMonster.LegacySavegameData_Monster; import com.gpl.rpg.AndorsTrail.util.Coord; import com.gpl.rpg.AndorsTrail.util.CoordRect; @@ -74,7 +76,8 @@ public final class Monster extends Actor { } MonsterType monsterType = world.monsterTypes.getMonsterType(monsterTypeId); - if (fileversion < 25) return readFromParcel_pre_v0610(src, fileversion, monsterType); + if (fileversion < 25) return LegacySavegameFormatReaderForMonster.readFromParcel_pre_v25(src, fileversion, monsterType); + if (fileversion < 33) return LegacySavegameFormatReaderForMonster.readFromParcel_pre_v33(src, world, fileversion, monsterType); return new Monster(src, world, fileversion, monsterType); } @@ -90,22 +93,23 @@ public final class Monster extends Actor { this.forceAggressive = src.readBoolean(); this.faction = monsterType.faction; this.monsterClass = monsterType.monsterClass; - if (fileversion >= 31) { - if (src.readBoolean()) { - this.shopItems = new ItemContainer(src, world, fileversion); - } + if (src.readBoolean()) { + this.shopItems = new ItemContainer(src, world, fileversion); } } - private static Monster readFromParcel_pre_v0610(DataInputStream src, int fileversion, MonsterType monsterType) throws IOException { - Coord position = new Coord(src, fileversion); - Monster m = new Monster(monsterType, position); - m.ap.current = src.readInt(); - m.health.current = src.readInt(); - if (fileversion >= 12) { - m.forceAggressive = src.readBoolean(); - } - return m; + public Monster(LegacySavegameData_Monster savegameData, MonsterType monsterType) { + super(savegameData, false); + this.monsterTypeID = monsterType.id; + this.millisecondsPerMove = Constants.MONSTER_MOVEMENT_TURN_DURATION_MS / monsterType.baseTraits.getMovesPerTurn(); + this.nextPosition = new CoordRect(new Coord(), monsterType.baseTraits.tileSize); + this.phraseID = monsterType.phraseID; + this.exp = monsterType.exp; + this.dropList = monsterType.dropList; + this.forceAggressive = savegameData.forceAggressive; + this.faction = monsterType.faction; + this.monsterClass = monsterType.monsterClass; + this.shopItems = savegameData.shopItems; } public void writeToParcel(DataOutputStream dest, int flags) throws IOException { diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Player.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Player.java index 51f21286a..b767170f0 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Player.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Player.java @@ -7,20 +7,20 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map.Entry; -import android.util.FloatMath; import android.util.SparseIntArray; import com.gpl.rpg.AndorsTrail.AndorsTrailApplication; import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.controller.ActorStatsController; import com.gpl.rpg.AndorsTrail.controller.Constants; -import com.gpl.rpg.AndorsTrail.controller.ItemController; import com.gpl.rpg.AndorsTrail.model.item.DropListCollection; import com.gpl.rpg.AndorsTrail.model.item.Inventory; import com.gpl.rpg.AndorsTrail.model.item.ItemTypeCollection; import com.gpl.rpg.AndorsTrail.model.item.Loot; import com.gpl.rpg.AndorsTrail.model.quest.QuestProgress; import com.gpl.rpg.AndorsTrail.resource.tiles.TileManager; +import com.gpl.rpg.AndorsTrail.savegames.LegacySavegameFormatReaderForPlayer; +import com.gpl.rpg.AndorsTrail.savegames.LegacySavegameFormatReaderForPlayer.LegacySavegameData_Player; import com.gpl.rpg.AndorsTrail.util.Coord; import com.gpl.rpg.AndorsTrail.util.Range; import com.gpl.rpg.AndorsTrail.util.Size; @@ -161,11 +161,6 @@ public final class Player extends Actor { public static boolean thisLevelAddsNewSkillpoint(int level) { return ((level - Constants.FIRST_SKILL_POINT_IS_GIVEN_AT_LEVEL) % Constants.NEW_SKILL_POINT_EVERY_N_LEVELS == 0); } - public static int getExpectedNumberOfSkillpointsForLevel(int level) { - level -= Constants.FIRST_SKILL_POINT_IS_GIVEN_AT_LEVEL; - if (level < 0) return 0; - return 1 + (int) FloatMath.floor((float) level / Constants.NEW_SKILL_POINT_EVERY_N_LEVELS); - } public boolean hasAvailableSkillpoints() { return availableSkillIncreases > 0; } @@ -184,6 +179,16 @@ public final class Player extends Actor { // ====== PARCELABLE =================================================================== + public static Player readFromParcel(DataInputStream src, WorldContext world, int fileversion) throws IOException { + Player player; + if (fileversion < 33) player = LegacySavegameFormatReaderForPlayer.readFromParcel_pre_v33(src, world, fileversion); + else player = new Player(src, world, fileversion); + + LegacySavegameFormatReaderForPlayer.upgradeSavegame(player, world, fileversion); + + return player; + } + public Player(DataInputStream src, WorldContext world, int fileversion) throws IOException { super(src, world, fileversion, true, false, null); this.lastPosition = new Coord(src, fileversion); @@ -193,74 +198,16 @@ public final class Player extends Actor { this.levelExperience = new Range(); this.recalculateLevelExperience(); this.inventory = new Inventory(src, world, fileversion); - - if (fileversion <= 13) { - final int size1 = src.readInt(); - for(int i = 0; i < size1; ++i) { - String keyName = src.readUTF(); - if ("mikhail_visited".equals(keyName)) addQuestProgress(new QuestProgress("andor", 1)); - else if ("qmikhail_bread_complete".equals(keyName)) addQuestProgress(new QuestProgress("mikhail_bread", 100)); - else if ("qmikhail_bread".equals(keyName)) addQuestProgress(new QuestProgress("mikhail_bread", 10)); - else if ("qmikhail_rats_complete".equals(keyName)) addQuestProgress(new QuestProgress("mikhail_rats", 100)); - else if ("qmikhail_rats".equals(keyName)) addQuestProgress(new QuestProgress("mikhail_rats", 10)); - else if ("oromir".equals(keyName)) addQuestProgress(new QuestProgress("leta", 20)); - else if ("qleta_complete".equals(keyName)) addQuestProgress(new QuestProgress("leta", 100)); - else if ("qodair".equals(keyName)) addQuestProgress(new QuestProgress("odair", 10)); - else if ("qodair_complete".equals(keyName)) addQuestProgress(new QuestProgress("odair", 100)); - else if ("qleonid_bonemeal".equals(keyName)) { - addQuestProgress(new QuestProgress("bonemeal", 10)); - addQuestProgress(new QuestProgress("bonemeal", 20)); - } - else if ("qtharal_complete".equals(keyName)) addQuestProgress(new QuestProgress("bonemeal", 30)); - else if ("qthoronir_complete".equals(keyName)) addQuestProgress(new QuestProgress("bonemeal", 100)); - else if ("qleonid_andor".equals(keyName)) addQuestProgress(new QuestProgress("andor", 10)); - else if ("qgruil_andor".equals(keyName)) addQuestProgress(new QuestProgress("andor", 20)); - else if ("qgruil_andor_complete".equals(keyName)) addQuestProgress(new QuestProgress("andor", 30)); - else if ("qleonid_crossglen".equals(keyName)) addQuestProgress(new QuestProgress("crossglen", 1)); - else if ("qjan".equals(keyName)) addQuestProgress(new QuestProgress("jan", 10)); - else if ("qjan_complete".equals(keyName)) addQuestProgress(new QuestProgress("jan", 100)); - else if ("qbucus_thieves".equals(keyName)) addQuestProgress(new QuestProgress("andor", 40)); - else if ("qfallhaven_derelict".equals(keyName)) addQuestProgress(new QuestProgress("andor", 50)); - else if ("qfallhaven_drunk".equals(keyName)) addQuestProgress(new QuestProgress("fallhavendrunk", 10)); - else if ("qfallhaven_drunk_complete".equals(keyName)) addQuestProgress(new QuestProgress("fallhavendrunk", 100)); - else if ("qnocmar_unnmir".equals(keyName)) addQuestProgress(new QuestProgress("nocmar", 10)); - else if ("qnocmar".equals(keyName)) addQuestProgress(new QuestProgress("nocmar", 20)); - else if ("qnocmar_complete".equals(keyName)) addQuestProgress(new QuestProgress("nocmar", 200)); - else if ("qfallhaven_tavern_room2".equals(keyName)) addQuestProgress(new QuestProgress("fallhaventavern", 10)); - else if ("qarcir".equals(keyName)) addQuestProgress(new QuestProgress("arcir", 10)); - else if ("qfallhaven_oldman".equals(keyName)) addQuestProgress(new QuestProgress("calomyran", 10)); - else if ("qcalomyran_tornpage".equals(keyName)) addQuestProgress(new QuestProgress("calomyran", 20)); - else if ("qfallhaven_oldman_complete".equals(keyName)) addQuestProgress(new QuestProgress("calomyran", 100)); - else if ("qbucus".equals(keyName)) addQuestProgress(new QuestProgress("bucus", 10)); - else if ("qthoronir_catacombs".equals(keyName)) addQuestProgress(new QuestProgress("bucus", 20)); - else if ("qathamyr_complete".equals(keyName)) addQuestProgress(new QuestProgress("bucus", 40)); - else if ("qfallhaven_church".equals(keyName)) addQuestProgress(new QuestProgress("bucus", 50)); - else if ("qbucus_complete".equals(keyName)) addQuestProgress(new QuestProgress("bucus", 100)); - } - } this.useItemCost = src.readInt(); this.reequipCost = src.readInt(); - final int size2 = src.readInt(); - for(int i = 0; i < size2; ++i) { - if (fileversion <= 21) { - this.skillLevels.put(i, src.readInt()); - } else { - final int skillID = src.readInt(); - this.skillLevels.put(skillID, src.readInt()); - } + final int numSkills = src.readInt(); + for(int i = 0; i < numSkills; ++i) { + final int skillID = src.readInt(); + this.skillLevels.put(skillID, src.readInt()); } this.spawnMap = src.readUTF(); this.spawnPlace = src.readUTF(); - - if (fileversion <= 12) { - useItemCost = 5; - health.max += 5; - health.current += 5; - baseTraits.maxHP += 5; - } - if (fileversion <= 13) return; - final int numquests = src.readInt(); for(int i = 0; i < numquests; ++i) { final String questID = src.readUTF(); @@ -272,37 +219,35 @@ public final class Player extends Actor { } } - if (fileversion <= 21) { - int assignedSkillpoints = 0; - for (int i = 0; i < skillLevels.size(); ++i) assignedSkillpoints += skillLevels.valueAt(i); - this.availableSkillIncreases = getExpectedNumberOfSkillpointsForLevel(this.level) - assignedSkillpoints; - } else { - this.availableSkillIncreases = src.readInt(); - } + this.availableSkillIncreases = src.readInt(); - if (fileversion <= 21) { - if (hasExactQuestProgress("prim_hunt", 240)) addQuestProgress(new QuestProgress("bwm_agent", 250)); - if (hasExactQuestProgress("bwm_agent", 240)) addQuestProgress(new QuestProgress("prim_hunt", 250)); + final int numAlignments = src.readInt(); + for(int i = 0; i < numAlignments; ++i) { + final String faction = src.readUTF(); + final int alignment = src.readInt(); + alignments.put(faction, alignment); } - - if (fileversion >= 26) { - final int size3 = src.readInt(); - for(int i = 0; i < size3; ++i) { - final String faction = src.readUTF(); - final int alignment = src.readInt(); - alignments.put(faction, alignment); - } - } - - if (fileversion <= 27) { - ItemController.correctActorConditionsFromItemsPre0611b1(this, "bless", world, "elytharan_redeemer"); - ItemController.correctActorConditionsFromItemsPre0611b1(this, "blackwater_misery", world, "bwm_dagger"); - ItemController.correctActorConditionsFromItemsPre0611b1(this, "regen", world, "ring_shadow0"); - } - - if (fileversion <= 30) { - this.baseTraits.attackCost = DEFAULT_PLAYER_ATTACKCOST; + } + + public Player(LegacySavegameData_Player savegameData) { + super(savegameData, true); + this.lastPosition = savegameData.lastPosition; + this.nextPosition = savegameData.nextPosition; + this.level = savegameData.level; + this.totalExperience = savegameData.totalExperience; + this.levelExperience = new Range(); + this.recalculateLevelExperience(); + this.inventory = savegameData.inventory; + this.useItemCost = savegameData.useItemCost; + this.reequipCost = savegameData.reequipCost; + for(int i = 0; i < savegameData.skillLevels.size(); ++i) { + this.skillLevels.put(savegameData.skillLevels.keyAt(i), savegameData.skillLevels.valueAt(i)); } + this.spawnMap = savegameData.spawnMap; + this.spawnPlace = savegameData.spawnPlace; + this.questProgress.putAll(savegameData.questProgress); + this.availableSkillIncreases = savegameData.availableSkillIncreases; + this.alignments.putAll(savegameData.alignments); } public void writeToParcel(DataOutputStream dest, int flags) throws IOException { diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/Inventory.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/Inventory.java index 5c3f31d8b..f20ccd45e 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/Inventory.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/Inventory.java @@ -5,6 +5,7 @@ import java.io.DataOutputStream; import java.io.IOException; import com.gpl.rpg.AndorsTrail.context.WorldContext; +import com.gpl.rpg.AndorsTrail.savegames.LegacySavegameFormatReaderForItemContainer; public final class Inventory extends ItemContainer { @@ -58,7 +59,7 @@ public final class Inventory extends ItemContainer { super(src, world, fileversion); gold = src.readInt(); - if (fileversion < 23) this.gold += ItemContainer.SavegameUpdate.refundUpgradedItems(this); + if (fileversion < 23) LegacySavegameFormatReaderForItemContainer.refundUpgradedItems(this); final int size = src.readInt(); for(int i = 0; i < size; ++i) { @@ -68,13 +69,14 @@ public final class Inventory extends ItemContainer { wear[i] = null; } } - if (fileversion < 19) return; - final int quickSlots = src.readInt(); - for(int i = 0; i < quickSlots; ++i) { - if (src.readBoolean()) { - quickitem[i] = world.itemTypes.getItemType(src.readUTF()); - } else { - quickitem[i] = null; + if (fileversion >= 19) { + final int quickSlots = src.readInt(); + for(int i = 0; i < quickSlots; ++i) { + if (src.readBoolean()) { + quickitem[i] = world.itemTypes.getItemType(src.readUTF()); + } else { + quickitem[i] = null; + } } } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/ItemContainer.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/ItemContainer.java index e24727b30..4ac780d20 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/ItemContainer.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/ItemContainer.java @@ -5,9 +5,7 @@ import java.io.DataOutputStream; import java.io.IOException; import java.util.ArrayList; -import com.gpl.rpg.AndorsTrail.AndorsTrailApplication; import com.gpl.rpg.AndorsTrail.context.WorldContext; -import com.gpl.rpg.AndorsTrail.util.L; public class ItemContainer { public final ArrayList items = new ArrayList(); @@ -133,28 +131,4 @@ public class ItemContainer { e.writeToParcel(dest, flags); } } - - public static class SavegameUpdate { - public static int refundUpgradedItems(ItemContainer container) { - int removedCost = 0; - for (ItemEntry e : container.items) { - if (e.quantity >= 2 && isRefundableItem(e.itemType)) { - if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) { - L.log("INFO: Refunding " + (e.quantity-1) + " items of type \"" + e.itemType.id + "\" for a total of " + ((e.quantity-1) * e.itemType.fixedBaseMarketCost) + "gc."); - } - removedCost += (e.quantity-1) * e.itemType.fixedBaseMarketCost; - e.quantity = 1; - } - } - return removedCost; - } - - private static boolean isRefundableItem(ItemType itemType) { - if (itemType.hasManualPrice) return false; - if (itemType.isQuestItem()) return false; - if (itemType.displayType == ItemType.DISPLAYTYPE_EXTRAORDINARY) return false; - if (itemType.displayType == ItemType.DISPLAYTYPE_LEGENDARY) return false; - return itemType.baseMarketCost > itemType.fixedBaseMarketCost; - } - } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/Loot.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/Loot.java index 629360975..6951758af 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/Loot.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/Loot.java @@ -5,6 +5,7 @@ import java.io.DataOutputStream; import java.io.IOException; import com.gpl.rpg.AndorsTrail.context.WorldContext; +import com.gpl.rpg.AndorsTrail.savegames.LegacySavegameFormatReaderForItemContainer; import com.gpl.rpg.AndorsTrail.util.Coord; public final class Loot { @@ -51,7 +52,7 @@ public final class Loot { this.exp = src.readInt(); this.gold = src.readInt(); this.items = new ItemContainer(src, world, fileversion); - if (fileversion < 23) this.gold += ItemContainer.SavegameUpdate.refundUpgradedItems(this.items); + if (fileversion < 23) LegacySavegameFormatReaderForItemContainer.refundUpgradedItems(this); this.position = new Coord(src, fileversion); if (fileversion <= 15) { diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/LegacySavegameFormatReaderForItemContainer.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/LegacySavegameFormatReaderForItemContainer.java new file mode 100644 index 000000000..fd5c592e9 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/LegacySavegameFormatReaderForItemContainer.java @@ -0,0 +1,40 @@ +package com.gpl.rpg.AndorsTrail.savegames; + +import com.gpl.rpg.AndorsTrail.AndorsTrailApplication; +import com.gpl.rpg.AndorsTrail.model.item.Inventory; +import com.gpl.rpg.AndorsTrail.model.item.ItemContainer; +import com.gpl.rpg.AndorsTrail.model.item.ItemType; +import com.gpl.rpg.AndorsTrail.model.item.ItemContainer.ItemEntry; +import com.gpl.rpg.AndorsTrail.model.item.Loot; +import com.gpl.rpg.AndorsTrail.util.L; + +public final class LegacySavegameFormatReaderForItemContainer { + public static void refundUpgradedItems(Inventory inventory) { + inventory.gold += getRefundForUpgradedItems(inventory); + } + public static void refundUpgradedItems(Loot loot) { + loot.gold += getRefundForUpgradedItems(loot.items); + } + + private static int getRefundForUpgradedItems(ItemContainer container) { + int removedCost = 0; + for (ItemEntry e : container.items) { + if (e.quantity >= 2 && isRefundableItem(e.itemType)) { + if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) { + L.log("INFO: Refunding " + (e.quantity-1) + " items of type \"" + e.itemType.id + "\" for a total of " + ((e.quantity-1) * e.itemType.fixedBaseMarketCost) + "gc."); + } + removedCost += (e.quantity-1) * e.itemType.fixedBaseMarketCost; + e.quantity = 1; + } + } + return removedCost; + } + + private static boolean isRefundableItem(ItemType itemType) { + if (itemType.hasManualPrice) return false; + if (itemType.isQuestItem()) return false; + if (itemType.displayType == ItemType.DISPLAYTYPE_EXTRAORDINARY) return false; + if (itemType.displayType == ItemType.DISPLAYTYPE_LEGENDARY) return false; + return itemType.baseMarketCost > itemType.fixedBaseMarketCost; + } +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/LegacySavegameFormatReaderForMonster.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/LegacySavegameFormatReaderForMonster.java new file mode 100644 index 000000000..b48d41002 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/LegacySavegameFormatReaderForMonster.java @@ -0,0 +1,105 @@ +package com.gpl.rpg.AndorsTrail.savegames; + +import java.io.DataInputStream; +import java.io.IOException; + +import com.gpl.rpg.AndorsTrail.context.WorldContext; +import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition; +import com.gpl.rpg.AndorsTrail.model.actor.Monster; +import com.gpl.rpg.AndorsTrail.model.actor.MonsterType; +import com.gpl.rpg.AndorsTrail.model.item.ItemContainer; +import com.gpl.rpg.AndorsTrail.savegames.LegacySavegameFormatReaderForPlayer.LegacySavegameData_Actor; +import com.gpl.rpg.AndorsTrail.util.Coord; +import com.gpl.rpg.AndorsTrail.util.CoordRect; +import com.gpl.rpg.AndorsTrail.util.Range; + +public class LegacySavegameFormatReaderForMonster { + public static Monster readFromParcel_pre_v25(DataInputStream src, int fileversion, MonsterType monsterType) throws IOException { + Coord position = new Coord(src, fileversion); + Monster m = new Monster(monsterType, position); + m.ap.current = src.readInt(); + m.health.current = src.readInt(); + if (fileversion >= 12) { + m.forceAggressive = src.readBoolean(); + } + return m; + } + + public static Monster readFromParcel_pre_v33(DataInputStream src, WorldContext world, int fileversion, MonsterType monsterType) throws IOException { + LegacySavegameData_Monster savegameData = readMonsterDataPreV33(src, world, fileversion, monsterType); + return new Monster(savegameData, monsterType); + } + + private static LegacySavegameData_Monster readMonsterDataPreV33(DataInputStream src, WorldContext world, int fileversion, MonsterType monsterType) throws IOException { + LegacySavegameData_Monster result = new LegacySavegameData_Monster(); + result.isImmuneToCriticalHits = monsterType.isImmuneToCriticalHits(); + + boolean readCombatTraits = true; + if (fileversion >= 25) readCombatTraits = src.readBoolean(); + if (readCombatTraits) { + result.attackCost = src.readInt(); + result.attackChance = src.readInt(); + result.criticalSkill = src.readInt(); + if (fileversion <= 20) { + result.criticalMultiplier = src.readInt(); + } else { + result.criticalMultiplier = src.readFloat(); + } + result.damagePotential = new Range(src, fileversion); + result.blockChance = src.readInt(); + result.damageResistance = src.readInt(); + } + + result.iconID = monsterType.baseTraits.iconID; + result.tileSize = monsterType.baseTraits.tileSize; + result.maxAP = monsterType.baseTraits.maxAP; + result.maxHP = monsterType.baseTraits.maxHP; + result.name = monsterType.baseTraits.name; + result.moveCost = monsterType.baseTraits.moveCost; + + result.baseAttackCost = monsterType.baseTraits.attackCost; + result.baseAttackChance = monsterType.baseTraits.attackChance; + result.baseCriticalSkill = monsterType.baseTraits.criticalSkill; + result.baseCriticalMultiplier = monsterType.baseTraits.criticalMultiplier; + result.baseDamagePotential = monsterType.baseTraits.damagePotential; + result.baseBlockChance = monsterType.baseTraits.blockChance; + result.baseDamageResistance = monsterType.baseTraits.damageResistance; + result.baseMoveCost = monsterType.baseTraits.baseMoveCost; + + if (!readCombatTraits) { + result.attackCost = result.baseAttackCost; + result.attackChance = result.baseAttackChance; + result.criticalSkill = result.baseCriticalSkill; + result.criticalMultiplier = result.baseCriticalMultiplier; + result.damagePotential = result.baseDamagePotential; + result.blockChance = result.baseBlockChance; + result.damageResistance = result.baseDamageResistance; + } + + result.ap = new Range(src, fileversion); + result.health = new Range(src, fileversion); + result.position = new Coord(src, fileversion); + result.rectPosition = new CoordRect(result.position, result.tileSize); + if (fileversion > 16) { + final int n = src.readInt(); + for(int i = 0; i < n; ++i) { + result.conditions.add(new ActorCondition(src, world, fileversion)); + } + } + + result.forceAggressive = src.readBoolean(); + if (fileversion >= 31) { + if (src.readBoolean()) { + result.shopItems = new ItemContainer(src, world, fileversion); + } + } + + return result; + } + + public static final class LegacySavegameData_Monster extends LegacySavegameData_Actor { + // from Monster + public boolean forceAggressive; + public ItemContainer shopItems; + } +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/LegacySavegameFormatReaderForPlayer.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/LegacySavegameFormatReaderForPlayer.java new file mode 100644 index 000000000..553895899 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/LegacySavegameFormatReaderForPlayer.java @@ -0,0 +1,310 @@ +package com.gpl.rpg.AndorsTrail.savegames; + +import java.io.DataInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; + +import android.util.FloatMath; +import android.util.SparseIntArray; + +import com.gpl.rpg.AndorsTrail.context.WorldContext; +import com.gpl.rpg.AndorsTrail.controller.ActorStatsController; +import com.gpl.rpg.AndorsTrail.controller.Constants; +import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition; +import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionEffect; +import com.gpl.rpg.AndorsTrail.model.ability.SkillInfo; +import com.gpl.rpg.AndorsTrail.model.actor.Player; +import com.gpl.rpg.AndorsTrail.model.item.Inventory; +import com.gpl.rpg.AndorsTrail.model.item.ItemType; +import com.gpl.rpg.AndorsTrail.model.quest.QuestProgress; +import com.gpl.rpg.AndorsTrail.util.Coord; +import com.gpl.rpg.AndorsTrail.util.CoordRect; +import com.gpl.rpg.AndorsTrail.util.Range; +import com.gpl.rpg.AndorsTrail.util.Size; + +public final class LegacySavegameFormatReaderForPlayer { + public static Player readFromParcel_pre_v33(DataInputStream src, WorldContext world, int fileversion) throws IOException { + LegacySavegameData_Player savegameData = readPlayerDataPreV33(src, world, fileversion); + return new Player(savegameData); + } + + private static LegacySavegameData_Player readPlayerDataPreV33(DataInputStream src, WorldContext world, int fileversion) throws IOException { + LegacySavegameData_Player result = new LegacySavegameData_Player(); + result.isImmuneToCriticalHits = false; + + boolean readCombatTraits = true; + if (fileversion >= 25) readCombatTraits = src.readBoolean(); + if (readCombatTraits) { + result.attackCost = src.readInt(); + result.attackChance = src.readInt(); + result.criticalSkill = src.readInt(); + if (fileversion <= 20) { + result.criticalMultiplier = src.readInt(); + } else { + result.criticalMultiplier = src.readFloat(); + } + result.damagePotential = new Range(src, fileversion); + result.blockChance = src.readInt(); + result.damageResistance = src.readInt(); + } + + result.iconID = src.readInt(); + result.tileSize = new Size(src, fileversion); + result.maxAP = src.readInt(); + result.maxHP = src.readInt(); + result.name = src.readUTF(); + result.moveCost = src.readInt(); + + result.baseAttackCost = src.readInt(); + result.baseAttackChance = src.readInt(); + result.baseCriticalSkill = src.readInt(); + if (fileversion <= 20) { + result.baseCriticalMultiplier = src.readInt(); + } else { + result.baseCriticalMultiplier = src.readFloat(); + } + result.baseDamagePotential = new Range(src, fileversion); + result.baseBlockChance = src.readInt(); + result.baseDamageResistance = src.readInt(); + + if (fileversion <= 16) { + result.baseMoveCost = result.moveCost; + } else { + result.baseMoveCost = src.readInt(); + } + + if (!readCombatTraits) { + result.attackCost = result.baseAttackCost; + result.attackChance = result.baseAttackChance; + result.criticalSkill = result.baseCriticalSkill; + result.criticalMultiplier = result.baseCriticalMultiplier; + result.damagePotential = result.baseDamagePotential; + result.blockChance = result.baseBlockChance; + result.damageResistance = result.baseDamageResistance; + } + + result.ap = new Range(src, fileversion); + result.health = new Range(src, fileversion); + result.position = new Coord(src, fileversion); + result.rectPosition = new CoordRect(result.position, result.tileSize); + if (fileversion > 16) { + final int n = src.readInt(); + for(int i = 0; i < n ; ++i) { + result.conditions.add(new ActorCondition(src, world, fileversion)); + } + } + + result.lastPosition = new Coord(src, fileversion); + result.nextPosition = new Coord(src, fileversion); + result.level = src.readInt(); + result.totalExperience = src.readInt(); + result.inventory = new Inventory(src, world, fileversion); + + if (fileversion <= 13) readQuestProgressPreV13(result, src, world, fileversion); + + result.useItemCost = src.readInt(); + result.reequipCost = src.readInt(); + final int size2 = src.readInt(); + for(int i = 0; i < size2; ++i) { + if (fileversion <= 21) { + result.skillLevels.put(i, src.readInt()); + } else { + final int skillID = src.readInt(); + result.skillLevels.put(skillID, src.readInt()); + } + } + result.spawnMap = src.readUTF(); + result.spawnPlace = src.readUTF(); + + if (fileversion > 13) { + final int numquests = src.readInt(); + for(int i = 0; i < numquests; ++i) { + final String questID = src.readUTF(); + result.questProgress.put(questID, new HashSet()); + final int numprogress = src.readInt(); + for(int j = 0; j < numprogress; ++j) { + int progress = src.readInt(); + result.questProgress.get(questID).add(progress); + } + } + } + + result.availableSkillIncreases = 0; + if (fileversion > 21) { + result.availableSkillIncreases = src.readInt(); + } + + if (fileversion >= 26) { + final int size3 = src.readInt(); + for(int i = 0; i < size3; ++i) { + final String faction = src.readUTF(); + final int alignment = src.readInt(); + result.alignments.put(faction, alignment); + } + } + + return result; + } + + public static final class LegacySavegameData_Player extends LegacySavegameData_Actor { + // from Player + public Coord lastPosition; + public Coord nextPosition; + public int level; + public int totalExperience; + public Inventory inventory; + public final HashMap > questProgress = new HashMap >(); + public final HashMap alignments = new HashMap(); + public int useItemCost; + public int reequipCost; + public final SparseIntArray skillLevels = new SparseIntArray(); + public String spawnMap; + public String spawnPlace; + public int availableSkillIncreases = 0; + } + + public static class LegacySavegameData_Actor { + // from Actor + public boolean isImmuneToCriticalHits; + public int iconID; + public Size tileSize; + public Range ap; + public Range health; + public Coord position; + public CoordRect rectPosition; + public final ArrayList conditions = new ArrayList(); + + // from ActorTraits + public int maxAP; + public int maxHP; + public String name; + public int moveCost; + public int baseMoveCost; + public int baseAttackCost; + public int baseAttackChance; + public int baseCriticalSkill; + public float baseCriticalMultiplier; + public Range baseDamagePotential; + public int baseBlockChance; + public int baseDamageResistance; + + // from CombatTraits + public int attackCost; + public int attackChance; + public int criticalSkill; + public float criticalMultiplier; + public Range damagePotential; + public int blockChance; + public int damageResistance; + } + + private static void readQuestProgressPreV13(LegacySavegameData_Player player, DataInputStream src, WorldContext world, int fileversion) throws IOException { + final int size1 = src.readInt(); + for(int i = 0; i < size1; ++i) { + String keyName = src.readUTF(); + if ("mikhail_visited".equals(keyName)) addQuestProgress(player, "andor", 1); + else if ("qmikhail_bread_complete".equals(keyName)) addQuestProgress(player, "mikhail_bread", 100); + else if ("qmikhail_bread".equals(keyName)) addQuestProgress(player, "mikhail_bread", 10); + else if ("qmikhail_rats_complete".equals(keyName)) addQuestProgress(player, "mikhail_rats", 100); + else if ("qmikhail_rats".equals(keyName)) addQuestProgress(player, "mikhail_rats", 10); + else if ("oromir".equals(keyName)) addQuestProgress(player, "leta", 20); + else if ("qleta_complete".equals(keyName)) addQuestProgress(player, "leta", 100); + else if ("qodair".equals(keyName)) addQuestProgress(player, "odair", 10); + else if ("qodair_complete".equals(keyName)) addQuestProgress(player, "odair", 100); + else if ("qleonid_bonemeal".equals(keyName)) { + addQuestProgress(player, "bonemeal", 10); + addQuestProgress(player, "bonemeal", 20); + } + else if ("qtharal_complete".equals(keyName)) addQuestProgress(player, "bonemeal", 30); + else if ("qthoronir_complete".equals(keyName)) addQuestProgress(player, "bonemeal", 100); + else if ("qleonid_andor".equals(keyName)) addQuestProgress(player, "andor", 10); + else if ("qgruil_andor".equals(keyName)) addQuestProgress(player, "andor", 20); + else if ("qgruil_andor_complete".equals(keyName)) addQuestProgress(player, "andor", 30); + else if ("qleonid_crossglen".equals(keyName)) addQuestProgress(player, "crossglen", 1); + else if ("qjan".equals(keyName)) addQuestProgress(player, "jan", 10); + else if ("qjan_complete".equals(keyName)) addQuestProgress(player, "jan", 100); + else if ("qbucus_thieves".equals(keyName)) addQuestProgress(player, "andor", 40); + else if ("qfallhaven_derelict".equals(keyName)) addQuestProgress(player, "andor", 50); + else if ("qfallhaven_drunk".equals(keyName)) addQuestProgress(player, "fallhavendrunk", 10); + else if ("qfallhaven_drunk_complete".equals(keyName)) addQuestProgress(player, "fallhavendrunk", 100); + else if ("qnocmar_unnmir".equals(keyName)) addQuestProgress(player, "nocmar", 10); + else if ("qnocmar".equals(keyName)) addQuestProgress(player, "nocmar", 20); + else if ("qnocmar_complete".equals(keyName)) addQuestProgress(player, "nocmar", 200); + else if ("qfallhaven_tavern_room2".equals(keyName)) addQuestProgress(player, "fallhaventavern", 10); + else if ("qarcir".equals(keyName)) addQuestProgress(player, "arcir", 10); + else if ("qfallhaven_oldman".equals(keyName)) addQuestProgress(player, "calomyran", 10); + else if ("qcalomyran_tornpage".equals(keyName)) addQuestProgress(player, "calomyran", 20); + else if ("qfallhaven_oldman_complete".equals(keyName)) addQuestProgress(player, "calomyran", 100); + else if ("qbucus".equals(keyName)) addQuestProgress(player, "bucus", 10); + else if ("qthoronir_catacombs".equals(keyName)) addQuestProgress(player, "bucus", 20); + else if ("qathamyr_complete".equals(keyName)) addQuestProgress(player, "bucus", 40); + else if ("qfallhaven_church".equals(keyName)) addQuestProgress(player, "bucus", 50); + else if ("qbucus_complete".equals(keyName)) addQuestProgress(player, "bucus", 100); + } + } + + private static void addQuestProgress(LegacySavegameData_Player player, String questID, int progress) { + if (!player.questProgress.containsKey(questID)) player.questProgress.put(questID, new HashSet()); + else if (player.questProgress.get(questID).contains(progress)) return; + player.questProgress.get(questID).add(progress); + } + + public static void upgradeSavegame(Player player, WorldContext world, int fileversion) { + + if (fileversion <= 12) { + player.useItemCost = 5; + player.health.max += 5; + player.health.current += 5; + player.baseTraits.maxHP += 5; + } + + if (fileversion <= 21) { + int assignedSkillpoints = 0; + for(SkillInfo skill : world.skills.getAllSkills()) { + assignedSkillpoints += player.getSkillLevel(skill.id); + } + player.availableSkillIncreases = getExpectedNumberOfSkillpointsForLevel(player.level) - assignedSkillpoints; + } + + if (fileversion <= 21) { + if (player.hasExactQuestProgress("prim_hunt", 240)) player.addQuestProgress(new QuestProgress("bwm_agent", 250)); + if (player.hasExactQuestProgress("bwm_agent", 240)) player.addQuestProgress(new QuestProgress("prim_hunt", 250)); + } + + if (fileversion <= 27) { + correctActorConditionsFromItemsPre0611b1(player, "bless", world, "elytharan_redeemer"); + correctActorConditionsFromItemsPre0611b1(player, "blackwater_misery", world, "bwm_dagger"); + correctActorConditionsFromItemsPre0611b1(player, "regen", world, "ring_shadow0"); + } + + if (fileversion <= 30) { + player.baseTraits.attackCost = Player.DEFAULT_PLAYER_ATTACKCOST; + } + } + + public static int getExpectedNumberOfSkillpointsForLevel(int level) { + level -= Constants.FIRST_SKILL_POINT_IS_GIVEN_AT_LEVEL; + if (level < 0) return 0; + return 1 + (int) FloatMath.floor((float) level / Constants.NEW_SKILL_POINT_EVERY_N_LEVELS); + } + + private static void correctActorConditionsFromItemsPre0611b1(Player player, String conditionTypeID, WorldContext world, String itemTypeIDWithCondition) { + if (!player.hasCondition(conditionTypeID)) return; + boolean hasItemWithCondition = false; + for (ItemType t : player.inventory.wear) { + if (t == null) continue; + if (t.effects_equip == null) continue; + if (t.effects_equip.addedConditions == null) continue; + for(ActorConditionEffect e : t.effects_equip.addedConditions) { + if (!e.conditionType.conditionTypeID.equals(conditionTypeID)) continue; + hasItemWithCondition = true; + break; + } + } + if (hasItemWithCondition) return; + + ActorStatsController.removeConditionsFromUnequippedItem(player, world.itemTypes.getItemType(itemTypeIDWithCondition)); + } +}