WIP 4 actor traits refactoring - Created savegame loaders for pre-versioncode-33.

This commit is contained in:
Oskar Wiksten
2012-10-21 13:24:21 +02:00
parent 21fca91ca7
commit 844afc2a95
13 changed files with 578 additions and 190 deletions

View File

@@ -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));
}
}

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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;
}
}
}
}

View File

@@ -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<ItemEntry> items = new ArrayList<ItemEntry>();
@@ -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;
}
}
}

View File

@@ -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) {

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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<Integer>());
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<String, HashSet<Integer> > questProgress = new HashMap<String, HashSet<Integer> >();
public final HashMap<String, Integer> alignments = new HashMap<String, Integer>();
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<ActorCondition> conditions = new ArrayList<ActorCondition>();
// 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<Integer>());
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));
}
}