diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/BulkSelectionInterface.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/BulkSelectionInterface.java index 1ec034e16..b155d5df7 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/BulkSelectionInterface.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/BulkSelectionInterface.java @@ -255,7 +255,7 @@ public class BulkSelectionInterface extends Activity implements TextWatcher { if (amount > totalAvailableAmount) return false; if (interfaceType == BULK_INTERFACE_BUY) { - if (amount * pricePerUnit > world.model.player.inventory.gold) return false; + if (amount * pricePerUnit > world.model.player.getGold()) return false; } return true; diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ConversationActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ConversationActivity.java index 451692279..2ae2d172a 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ConversationActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ConversationActivity.java @@ -215,7 +215,7 @@ public final class ConversationActivity extends Activity implements OnKeyListene return; } else if (phraseID.equalsIgnoreCase(ConversationCollection.PHRASE_SHOP)) { assert(npc != null); - assert(npc.dropList != null); + assert(npc.getDropList() != null); Intent intent = new Intent(this, ShopActivity.class); intent.setData(Uri.parse("content://com.gpl.rpg.AndorsTrail/shop")); Dialogs.addMonsterIdentifiers(intent, npc); @@ -350,7 +350,7 @@ public final class ConversationActivity extends Activity implements OnKeyListene } s.text = text; s.color = color; - s.isPlayerActor = actor != null ? actor.isPlayer : false; + s.isPlayerActor = actor != null ? actor == player : false; conversationHistory.add(s); statementList.clearFocus(); listAdapter.notifyDataSetChanged(); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/DebugInterface.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/DebugInterface.java index d61f97413..d3e5c845e 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/DebugInterface.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/DebugInterface.java @@ -34,9 +34,9 @@ public final class DebugInterface { new DebugButton("dmg", new OnClickListener() { @Override public void onClick(View arg0) { - world.model.player.combatTraits.damagePotential.set(99, 99); - world.model.player.combatTraits.attackChance = 200; - world.model.player.combatTraits.attackCost = 1; + world.model.player.damagePotential.set(99, 99); + world.model.player.attackChance = 200; + world.model.player.attackCost = 1; mainActivity.updateStatus(); mainActivity.showToast("DEBUG: damagePotential=99, chance=200%, cost=1", Toast.LENGTH_SHORT); } @@ -129,7 +129,7 @@ public final class DebugInterface { public void onClick(View arg0) { world.model.player.baseTraits.maxHP = 200; world.model.player.health.max = world.model.player.baseTraits.maxHP; - world.model.player.health.setMax(); + world.model.player.setMaxHP(); world.model.player.conditions.clear(); mainActivity.updateStatus(); mainActivity.showToast("DEBUG: hp set to max", Toast.LENGTH_SHORT); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Inventory.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Inventory.java index 9a7077445..8c6db50d0 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Inventory.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Inventory.java @@ -6,7 +6,6 @@ import com.gpl.rpg.AndorsTrail.R; import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.controller.ItemController; -import com.gpl.rpg.AndorsTrail.model.CombatTraits; import com.gpl.rpg.AndorsTrail.model.actor.Player; import com.gpl.rpg.AndorsTrail.model.item.Inventory; import com.gpl.rpg.AndorsTrail.model.item.ItemContainer; @@ -164,14 +163,19 @@ public final class HeroinfoActivity_Inventory extends Activity { private void updateTraits() { heroinfo_stats_gold.setText(getResources().getString(R.string.heroinfo_gold, player.inventory.gold)); - CombatTraits c = player.combatTraits; StringBuilder sb = new StringBuilder(); - ItemController.describeAttackEffect(c.attackChance, c.damagePotential.current, c.damagePotential.max, c.criticalSkill, c.criticalMultiplier, sb); + ItemController.describeAttackEffect( + player.getAttackChance(), + player.getDamagePotential().current, + player.getDamagePotential().max, + player.getCriticalSkill(), + player.getCriticalMultiplier(), + sb); heroinfo_stats_attack.setText(sb.toString()); sb = new StringBuilder(); - ItemController.describeBlockEffect(c.blockChance, c.damageResistance, sb); + ItemController.describeBlockEffect(player.getBlockChance(), player.getDamageResistance(), sb); heroinfo_stats_defense.setText(sb.toString()); } @@ -281,12 +285,10 @@ public final class HeroinfoActivity_Inventory extends Activity { boolean enabled = true; if (world.model.uiSelections.isInCombat) { - int ap = world.model.player.reequipCost; + int ap = world.model.player.getReequipCost(); text = getResources().getString(R.string.iteminfo_action_unequip_ap, ap); if (ap > 0) { - if (world.model.player.ap.current < ap) { - enabled = false; - } + enabled = world.model.player.hasAPs(ap); } } else { text = getResources().getString(R.string.iteminfo_action_unequip); @@ -304,7 +306,7 @@ public final class HeroinfoActivity_Inventory extends Activity { final boolean isInCombat = world.model.uiSelections.isInCombat; if (itemType.isEquippable()) { if (isInCombat) { - ap = world.model.player.reequipCost; + ap = world.model.player.getReequipCost(); text = getResources().getString(R.string.iteminfo_action_equip_ap, ap); } else { text = getResources().getString(R.string.iteminfo_action_equip); @@ -312,7 +314,7 @@ public final class HeroinfoActivity_Inventory extends Activity { action = ItemInfoActivity.ITEMACTION_EQUIP; } else if (itemType.isUsable()) { if (isInCombat) { - ap = world.model.player.useItemCost; + ap = world.model.player.getUseItemCost(); text = getResources().getString(R.string.iteminfo_action_use_ap, ap); } else { text = getResources().getString(R.string.iteminfo_action_use); @@ -320,9 +322,7 @@ public final class HeroinfoActivity_Inventory extends Activity { action = ItemInfoActivity.ITEMACTION_USE; } if (isInCombat && ap > 0) { - if (world.model.player.ap.current < ap) { - enabled = false; - } + enabled = world.model.player.hasAPs(ap); } Dialogs.showItemInfo(HeroinfoActivity_Inventory.this, itemType.id, action, text, enabled, -1); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Skills.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Skills.java index 699cf1269..d9df87740 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Skills.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Skills.java @@ -67,7 +67,7 @@ public final class HeroinfoActivity_Skills extends Activity { private void updateSkillList() { TextView listskills_number_of_increases = (TextView) findViewById(R.id.heroinfo_listskills_number_of_increases); - int numberOfSkillIncreases = player.availableSkillIncreases; + int numberOfSkillIncreases = player.getAvailableSkillIncreases(); if (numberOfSkillIncreases > 0) { if (numberOfSkillIncreases == 1) { listskills_number_of_increases.setText(R.string.skill_number_of_increases_one); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Stats.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Stats.java index 3f4fb6964..e223b2899 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Stats.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Stats.java @@ -107,10 +107,10 @@ public final class HeroinfoActivity_Stats extends Activity { } private void updateTraits() { - heroinfo_level.setText(Integer.toString(player.level)); - heroinfo_totalexperience.setText(Integer.toString(player.totalExperience)); + heroinfo_level.setText(Integer.toString(player.getLevel())); + heroinfo_totalexperience.setText(Integer.toString(player.getTotalExperience())); heroinfo_ap.setText(player.ap.toString()); - heroinfo_movecost.setText(Integer.toString(player.baseTraits.moveCost)); + heroinfo_movecost.setText(Integer.toString(player.getMoveCost())); rangebar_hp.update(player.health); rangebar_exp.update(player.levelExperience); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/LevelUpActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/LevelUpActivity.java index c9df6b590..8ce0a6ad3 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/LevelUpActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/LevelUpActivity.java @@ -91,7 +91,7 @@ public final class LevelUpActivity extends Activity { } world.tileManager.setImageViewTile(levelup_title, player); - levelup_description.setText(res.getString(R.string.levelup_description, player.level+1)); + levelup_description.setText(res.getString(R.string.levelup_description, player.getLevel() + 1)); if (player.nextLevelAddsNewSkillpoint()) { levelup_adds_new_skillpoint.setVisibility(View.VISIBLE); } else { diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java index 56bb3a2c4..44491a7e8 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java @@ -132,7 +132,7 @@ public final class MainActivity extends Activity { final Coord p = world.model.player.nextPosition; Monster m = world.model.currentMap.getMonsterAt(p); if (m == null) return; //Shouldn't happen. - m.forceAggressive = true; + m.forceAggressive(); view.combatController.setCombatSelection(m, p); view.combatController.enterCombat(CombatController.BEGIN_TURN_PLAYER); } else if (resultCode == ConversationActivity.ACTIVITYRESULT_REMOVE) { @@ -163,7 +163,7 @@ public final class MainActivity extends Activity { private boolean save(int slot) { final Player player = world.model.player; - return Savegames.saveWorld(world, this, slot, getString(R.string.savegame_currenthero_displayinfo, player.level, player.totalExperience, player.inventory.gold)); + return Savegames.saveWorld(world, this, slot, getString(R.string.savegame_currenthero_displayinfo, player.getLevel(), player.getTotalExperience(), player.getGold())); } @Override diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MonsterInfoActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MonsterInfoActivity.java index 8d990acab..766fd26ac 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MonsterInfoActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MonsterInfoActivity.java @@ -1,7 +1,5 @@ package com.gpl.rpg.AndorsTrail.activity; -import java.util.Arrays; - import com.gpl.rpg.AndorsTrail.AndorsTrailApplication; import com.gpl.rpg.AndorsTrail.Dialogs; import com.gpl.rpg.AndorsTrail.R; @@ -89,11 +87,11 @@ public final class MonsterInfoActivity extends Activity { monsterinfo_onhiteffects.update( null, null, - monster.baseTraits.onHitEffects == null ? null : Arrays.asList(monster.baseTraits.onHitEffects), + monster.getOnHitEffectsAsList(), null, false); hp.update(monster.health); - monsterinfo_immune_criticals.setVisibility(monster.isImmuneToCriticalHits ? View.VISIBLE : View.GONE); + monsterinfo_immune_criticals.setVisibility(monster.isImmuneToCriticalHits() ? View.VISIBLE : View.GONE); } public static int getMonsterDifficultyResource(WorldContext world, Monster monster) { diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ShopActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ShopActivity.java index 61ec70fc4..033dca1a8 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ShopActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ShopActivity.java @@ -190,7 +190,7 @@ public final class ShopActivity extends TabActivity implements OnContainerItemCl } private void updateGc() { - String gc = getResources().getString(R.string.shop_yourgold, player.inventory.gold); + String gc = getResources().getString(R.string.shop_yourgold, player.getGold()); shop_buy_gc.setText(gc); shop_sell_gc.setText(gc); } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ActorStatsController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ActorStatsController.java index 3aaa96253..a19b0c286 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ActorStatsController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ActorStatsController.java @@ -167,37 +167,43 @@ public class ActorStatsController { public static void applyAbilityEffects(Actor actor, AbilityModifierTraits effects, int multiplier) { if (effects == null) return; - CombatTraits actorCombatTraits = actor.combatTraits; - actor.health.addToMax(effects.increaseMaxHP * multiplier); actor.ap.addToMax(effects.increaseMaxAP * multiplier); - actor.baseTraits.moveCost += effects.increaseMoveCost * multiplier; + actor.moveCost += effects.increaseMoveCost * multiplier; - actorCombatTraits.attackCost += effects.increaseAttackCost * multiplier; + actor.attackCost += effects.increaseAttackCost * multiplier; //criticalMultiplier should not be increased. It is always defined by the weapon in use. - actorCombatTraits.attackChance += effects.increaseAttackChance * multiplier; - actorCombatTraits.criticalSkill += effects.increaseCriticalSkill * multiplier; - actorCombatTraits.damagePotential.add(effects.increaseMinDamage * multiplier, true); - actorCombatTraits.damagePotential.addToMax(effects.increaseMaxDamage * multiplier); - actorCombatTraits.blockChance += effects.increaseBlockChance * multiplier; - actorCombatTraits.damageResistance += effects.increaseDamageResistance * multiplier; + actor.attackChance += effects.increaseAttackChance * multiplier; + actor.criticalSkill += effects.increaseCriticalSkill * multiplier; + actor.damagePotential.add(effects.increaseMinDamage * multiplier, true); + actor.damagePotential.addToMax(effects.increaseMaxDamage * multiplier); + actor.blockChance += effects.increaseBlockChance * multiplier; + actor.damageResistance += effects.increaseDamageResistance * multiplier; - if (actorCombatTraits.attackCost <= 0) actorCombatTraits.attackCost = 1; - if (actorCombatTraits.attackChance < 0) actorCombatTraits.attackChance = 0; - if (actor.baseTraits.moveCost <= 0) actor.baseTraits.moveCost = 1; - if (actorCombatTraits.damagePotential.max < 0) actorCombatTraits.damagePotential.set(0, 0); + if (actor.attackCost <= 0) actor.attackCost = 1; + if (actor.attackChance < 0) actor.attackChance = 0; + if (actor.moveCost <= 0) actor.moveCost = 1; + if (actor.damagePotential.max < 0) actor.damagePotential.set(0, 0); } - public static void recalculatePlayerCombatTraits(Player player) { recalculateActorCombatTraits(player); } - public static void recalculateMonsterCombatTraits(Monster monster) { recalculateActorCombatTraits(monster); } + public static void recalculatePlayerCombatTraits(Player player) { + player.resetStatsToBaseTraits(); + ItemController.applyInventoryEffects(player); + SkillController.applySkillEffects(player); + applyEffectsFromCurrentConditions(player); + ItemController.recalculateHitEffectsFromWornItems(player); + player.health.capAtMax(); + player.ap.capAtMax(); + } + public static void recalculateMonsterCombatTraits(Monster monster) { + monster.resetStatsToBaseTraits(); + applyEffectsFromCurrentConditions(monster); + monster.health.capAtMax(); + monster.ap.capAtMax(); + } private static void recalculateActorCombatTraits(Actor actor) { - actor.resetStatsToBaseTraits(); - if (actor.isPlayer) ItemController.applyInventoryEffects((Player) actor); - if (actor.isPlayer) SkillController.applySkillEffects((Player) actor); - applyEffectsFromCurrentConditions(actor); - if (actor.isPlayer) ItemController.recalculateHitEffectsFromWornItems((Player) actor); - actor.health.capAtMax(); - actor.ap.capAtMax(); + if (actor.isPlayer) recalculatePlayerCombatTraits((Player) actor); + else recalculateMonsterCombatTraits((Monster) actor); } public void applyConditionsToPlayer(Player player, boolean isFullRound) { @@ -227,7 +233,7 @@ public class ActorStatsController { player.conditions.remove(i); player.conditionListener.onActorConditionRemoved(player, c); } - recalculateActorCombatTraits(player); + recalculatePlayerCombatTraits(player); } } } @@ -398,7 +404,7 @@ public class ActorStatsController { public void applySkillEffectsForNewRound(Player player, PredefinedMap currentMap) { int level = player.getSkillLevel(SkillCollection.SKILL_REGENERATION); if (level > 0) { - boolean hasAdjacentMonster = MovementController.hasAdjacentAggressiveMonster(currentMap, player.position); + boolean hasAdjacentMonster = MovementController.hasAdjacentAggressiveMonster(currentMap, player); if (!hasAdjacentMonster) { boolean changed = player.health.add(level * SkillCollection.PER_SKILLPOINT_INCREASE_REGENERATION, false); if (changed) view.mainActivity.updateStatus(); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/CombatController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/CombatController.java index 634104905..163b3ae60 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/CombatController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/CombatController.java @@ -15,7 +15,6 @@ import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.VisualEffectCompletedCallback; import com.gpl.rpg.AndorsTrail.model.AttackResult; -import com.gpl.rpg.AndorsTrail.model.CombatTraits; import com.gpl.rpg.AndorsTrail.model.ModelContainer; import com.gpl.rpg.AndorsTrail.model.ability.SkillCollection; import com.gpl.rpg.AndorsTrail.model.actor.Actor; @@ -134,7 +133,7 @@ public final class CombatController implements VisualEffectCompletedCallback { public boolean canExitCombat() { return getAdjacentMonster() == null; } private Monster getAdjacentMonster() { - return MovementController.getAdjacentAggressiveMonster(model.currentMap, model.player.position); + return MovementController.getAdjacentAggressiveMonster(model.currentMap, model.player); } public void executeMoveAttack(int dx, int dy) { @@ -168,7 +167,7 @@ public final class CombatController implements VisualEffectCompletedCallback { private AttackResult lastAttackResult; private void executePlayerAttack() { if (context.effectController.isRunningVisualEffect()) return; - if (!useAPs(model.player.combatTraits.attackCost)) return; + if (!useAPs(model.player.getAttackCost())) return; final Monster target = model.uiSelections.selectedMonster; this.currentlyAttackedMonster = target; @@ -228,7 +227,7 @@ public final class CombatController implements VisualEffectCompletedCallback { player.ap.add(player.getSkillLevel(SkillCollection.SKILL_CLEAVE) * SkillCollection.PER_SKILLPOINT_INCREASE_CLEAVE_AP, false); player.health.add(player.getSkillLevel(SkillCollection.SKILL_EATER) * SkillCollection.PER_SKILLPOINT_INCREASE_EATER_HEALTH, false); - model.statistics.addMonsterKill(killedMonster.monsterTypeID); + model.statistics.addMonsterKill(killedMonster.getMonsterTypeID()); model.player.addExperience(loot.exp); totalExpThisFight += loot.exp; loot.exp = 0; @@ -248,9 +247,9 @@ public final class CombatController implements VisualEffectCompletedCallback { private boolean playerHasApLeft() { final Player player = model.player; - if (player.hasAPs(player.useItemCost)) return true; - if (player.hasAPs(player.combatTraits.attackCost)) return true; - if (player.hasAPs(player.baseTraits.moveCost)) return true; + if (player.hasAPs(player.getUseItemCost())) return true; + if (player.hasAPs(player.getAttackCost())) return true; + if (player.hasAPs(player.getMoveCost())) return true; return false; } private void playerActionCompleted() { @@ -266,7 +265,7 @@ public final class CombatController implements VisualEffectCompletedCallback { private void executeCombatMove(final Coord dest) { if (model.uiSelections.selectedMonster != null) return; if (dest == null) return; - if (!useAPs(model.player.baseTraits.moveCost)) return; + if (!useAPs(model.player.getMoveCost())) return; int fleeChanceBias = model.player.getSkillLevel(SkillCollection.SKILL_EVASION) * SkillCollection.PER_SKILLPOINT_INCREASE_EVASION_FLEE_CHANCE_PERCENTAGE; if (Constants.roll100(Constants.FLEE_FAIL_CHANCE_PERCENT - fleeChanceBias)) { @@ -309,15 +308,15 @@ public final class CombatController implements VisualEffectCompletedCallback { private Monster determineNextMonster(Monster previousMonster) { if (previousMonster != null) { - if (previousMonster.hasAPs(previousMonster.combatTraits.attackCost)) return previousMonster; + if (previousMonster.hasAPs(previousMonster.getAttackCost())) return previousMonster; } for (MonsterSpawnArea a : model.currentMap.spawnAreas) { for (Monster m : a.monsters) { if (!m.isAgressive()) continue; - if (m.rectPosition.isAdjacentTo(model.player.position)) { - if (m.hasAPs(m.combatTraits.attackCost)) return m; + if (m.isAdjacentTo(model.player)) { + if (m.hasAPs(m.getAttackCost())) return m; } } } @@ -332,7 +331,7 @@ public final class CombatController implements VisualEffectCompletedCallback { endMonsterTurn(); return; } - currentActiveMonster.useAPs(currentActiveMonster.combatTraits.attackCost); + currentActiveMonster.useAPs(currentActiveMonster.getAttackCost()); context.mainActivity.combatview.updateTurnInfo(currentActiveMonster); Resources r = context.mainActivity.getResources(); @@ -407,16 +406,16 @@ public final class CombatController implements VisualEffectCompletedCallback { } private static boolean hasCriticalAttack(Actor attacker, Actor target) { - if (!attacker.combatTraits.hasCriticalAttacks()) return false; - if (target.isImmuneToCriticalHits) return false; + if (!attacker.hasCriticalAttacks()) return false; + if (target.isImmuneToCriticalHits()) return false; return true; } private static float getAverageDamagePerHit(Actor attacker, Actor target) { - float result = (float) (getAttackHitChance(attacker.combatTraits, target.combatTraits)) * attacker.combatTraits.damagePotential.average() / 100; + float result = (float) (getAttackHitChance(attacker, target)) * attacker.getDamagePotential().average() / 100; if (hasCriticalAttack(attacker, target)) { - result += (float) attacker.combatTraits.getEffectiveCriticalChance() * result * attacker.combatTraits.criticalMultiplier / 100; + result += (float) attacker.getEffectiveCriticalChance() * result * attacker.getCriticalMultiplier() / 100; } - result -= target.combatTraits.damageResistance; + result -= target.getDamageResistance(); return result; } private static float getAverageDamagePerTurn(Actor attacker, Actor target) { @@ -424,14 +423,14 @@ public final class CombatController implements VisualEffectCompletedCallback { } private static int getTurnsToKillTarget(Actor attacker, Actor target) { if (hasCriticalAttack(attacker, target)) { - if (attacker.combatTraits.damagePotential.max * attacker.combatTraits.criticalMultiplier <= target.combatTraits.damageResistance) return 999; + if (attacker.getDamagePotential().max * attacker.getCriticalMultiplier() <= target.getDamageResistance()) return 999; } else { - if (attacker.combatTraits.damagePotential.max <= target.combatTraits.damageResistance) return 999; + if (attacker.getDamagePotential().max <= target.getDamageResistance()) return 999; } float averageDamagePerTurn = getAverageDamagePerTurn(attacker, target); if (averageDamagePerTurn <= 0) return 100; - return (int) FloatMath.ceil(target.health.max / averageDamagePerTurn); + return (int) FloatMath.ceil(target.getMaxHP() / averageDamagePerTurn); } public static int getMonsterDifficulty(WorldContext world, Monster monster) { // returns [0..100) . 100 == easy. @@ -460,25 +459,25 @@ public final class CombatController implements VisualEffectCompletedCallback { private static final int n = 50; private static final int F = 40; private static final float two_divided_by_PI = (float) (2f / Math.PI); - private static int getAttackHitChance(final CombatTraits attacker, final CombatTraits target) { - final int c = attacker.attackChance - target.blockChance; + private static int getAttackHitChance(final Actor attacker, final Actor target) { + final int c = attacker.getAttackChance() - target.getBlockChance(); // (2/pi)*atan(..) will vary from -1 to +1 . return (int) (50 * (1 + two_divided_by_PI * (float)Math.atan((float)(c-n) / F))); } private AttackResult attack(final Actor attacker, final Actor target) { - int hitChance = getAttackHitChance(attacker.combatTraits, target.combatTraits); + int hitChance = getAttackHitChance(attacker, target); if (!Constants.roll100(hitChance)) return AttackResult.MISS; - int damage = Constants.rollValue(attacker.combatTraits.damagePotential); + int damage = Constants.rollValue(attacker.getDamagePotential()); boolean isCriticalHit = false; if (hasCriticalAttack(attacker, target)) { - isCriticalHit = Constants.roll100(attacker.combatTraits.getEffectiveCriticalChance()); + isCriticalHit = Constants.roll100(attacker.getEffectiveCriticalChance()); if (isCriticalHit) { - damage *= attacker.combatTraits.criticalMultiplier; + damage *= attacker.getCriticalMultiplier(); } } - damage -= target.combatTraits.damageResistance; + damage -= target.getDamageResistance(); if (damage < 0) damage = 0; target.health.subtract(damage, false); @@ -488,9 +487,10 @@ public final class CombatController implements VisualEffectCompletedCallback { } private void applyAttackHitStatusEffects(Actor attacker, Actor target) { - if (attacker.baseTraits.onHitEffects == null) return; + ItemTraits_OnUse[] onHitEffects = attacker.getOnHitEffects(); + if (onHitEffects == null) return; - for (ItemTraits_OnUse e : attacker.baseTraits.onHitEffects) { + for (ItemTraits_OnUse e : onHitEffects) { context.actorStatsController.applyUseEffect(attacker, target, e); } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/Controller.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/Controller.java index 2ef3f2f99..f2ed76c73 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/Controller.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/Controller.java @@ -54,7 +54,7 @@ public final class Controller { Dialogs.showMonsterEncounter(view.mainActivity, view, m); } } else { - Dialogs.showConversation(view.mainActivity, view, m.phraseID, m); + Dialogs.showConversation(view.mainActivity, view, m.getPhraseID(), m); } } @@ -82,8 +82,7 @@ public final class Controller { player.setMaxAP(); player.setMaxHP(); if (area != null) { - player.spawnPlace = area.id; - player.spawnMap = world.model.currentMap.name; + player.setSpawnPlace(world.model.currentMap.name, area.id); } for (PredefinedMap m : world.maps.predefinedMaps) { m.resetTemporaryData(); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ItemController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ItemController.java index b137cb4e9..0a5dd35a3 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ItemController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ItemController.java @@ -39,7 +39,7 @@ public final class ItemController { if (!type.isEquippable()) return; final Player player = model.player; if (model.uiSelections.isInCombat) { - if (!player.useAPs(player.reequipCost)) return; + if (!player.useAPs(player.getReequipCost())) return; } if (!player.inventory.removeItem(type.id, 1)) return; @@ -62,7 +62,7 @@ public final class ItemController { if (player.inventory.isEmptySlot(slot)) return; if (model.uiSelections.isInCombat) { - if (!player.useAPs(player.reequipCost)) return; + if (!player.useAPs(player.getReequipCost())) return; } unequipSlot(player, slot); @@ -81,7 +81,7 @@ public final class ItemController { if (!type.isUsable()) return; final Player player = model.player; if (model.uiSelections.isInCombat) { - if (!player.useAPs(player.useItemCost)) return; + if (!player.useAPs(player.getUseItemCost())) return; } if (!player.inventory.removeItem(type.id, 1)) return; @@ -101,8 +101,8 @@ public final class ItemController { public static void applyInventoryEffects(Player player) { ItemType weapon = getMainWeapon(player); if (weapon != null) { - player.combatTraits.attackCost = 0; - player.combatTraits.criticalMultiplier = weapon.effects_equip.stats.setCriticalMultiplier; + player.attackCost = 0; + player.criticalMultiplier = weapon.effects_equip.stats.setCriticalMultiplier; } applyInventoryEffects(player, Inventory.WEARSLOT_WEAPON); @@ -153,9 +153,9 @@ public final class ItemController { if (effects != null) { ItemTraits_OnUse[] effects_ = new ItemTraits_OnUse[effects.size()]; effects_ = effects.toArray(effects_); - player.baseTraits.onHitEffects = effects_; + player.onHitEffects = effects_; } else { - player.baseTraits.onHitEffects = null; + player.onHitEffects = null; } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MonsterMovementController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MonsterMovementController.java index d4346db4c..c9b7aed5c 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MonsterMovementController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MonsterMovementController.java @@ -38,7 +38,7 @@ public final class MonsterMovementController { for (MonsterSpawnArea a : model.currentMap.spawnAreas) { for (Monster m : a.monsters) { if (!m.isAgressive()) continue; - if (!m.rectPosition.isAdjacentTo(model.player.position)) continue; + if (!m.isAdjacentTo(model.player)) continue; int aggressionChanceBias = model.player.getSkillLevel(SkillCollection.SKILL_EVASION) * SkillCollection.PER_SKILLPOINT_INCREASE_EVASION_MONSTER_ATTACK_CHANCE_PERCENTAGE; if (Constants.roll100(Constants.MONSTER_AGGRESSION_CHANCE_PERCENT - aggressionChanceBias)) { @@ -50,7 +50,7 @@ public final class MonsterMovementController { } private boolean moveMonster(final Monster m, final MonsterSpawnArea area, long currentTime) { - m.nextActionTime += m.millisecondsPerMove; + m.nextActionTime += getMillisecondsPerMove(m); if (m.movementDestination == null) { // Monster has waited and should start to move again. m.movementDestination = new Coord(m.position); @@ -89,7 +89,11 @@ public final class MonsterMovementController { private void cancelCurrentMonsterMovement(final Monster m) { m.movementDestination = null; - m.nextActionTime += m.millisecondsPerMove * Constants.rollValue(Constants.monsterWaitTurns); + m.nextActionTime += getMillisecondsPerMove(m) * Constants.rollValue(Constants.monsterWaitTurns); + } + + private static int getMillisecondsPerMove(Monster m) { + return Constants.MONSTER_MOVEMENT_TURN_DURATION_MS * m.getMoveCost() / m.getMaxAP(); } private static int sgn(int i) { diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java index 3f5a8a609..74d4dab55 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java @@ -233,7 +233,7 @@ public final class MovementController implements TimedMessageTask.Callback { } public static void respawnPlayer(final Resources res, final WorldContext world) { - placePlayerAt(res, world, MapObject.MAPEVENT_REST, world.model.player.spawnMap, world.model.player.spawnPlace, 0, 0); + placePlayerAt(res, world, MapObject.MAPEVENT_REST, world.model.player.getSpawnMap(), world.model.player.getSpawnPlace(), 0, 0); } public static void moveBlockedActors(final WorldContext world) { @@ -304,20 +304,21 @@ public final class MovementController implements TimedMessageTask.Callback { public static void refreshMonsterAggressiveness(final PredefinedMap map, final Player player) { for(MonsterSpawnArea a : map.spawnAreas) { for (Monster m : a.monsters) { - if (m.faction == null) continue; - if (player.getAlignment(m.faction) < 0) m.forceAggressive = true; + String faction = m.getFaction(); + if (faction == null) continue; + if (player.getAlignment(faction) < 0) m.forceAggressive(); } } } - public static boolean hasAdjacentAggressiveMonster(PredefinedMap map, Coord position) { - return getAdjacentAggressiveMonster(map, position) != null; + public static boolean hasAdjacentAggressiveMonster(PredefinedMap map, Player player) { + return getAdjacentAggressiveMonster(map, player) != null; } - public static Monster getAdjacentAggressiveMonster(PredefinedMap map, Coord position) { + public static Monster getAdjacentAggressiveMonster(PredefinedMap map, Player player) { for (MonsterSpawnArea a : map.spawnAreas) { for (Monster m : a.monsters) { if (!m.isAgressive()) continue; - if (m.rectPosition.isAdjacentTo(position)) return m; + if (m.isAdjacentTo(player)) return m; } } return null; diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/SkillController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/SkillController.java index c41ac9ff2..604827eff 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/SkillController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/SkillController.java @@ -17,17 +17,16 @@ import com.gpl.rpg.AndorsTrail.util.ConstRange; public final class SkillController { public static void applySkillEffects(Player player) { - CombatTraits combatTraits = player.combatTraits; - combatTraits.attackChance += SkillCollection.PER_SKILLPOINT_INCREASE_WEAPON_CHANCE * player.getSkillLevel(SkillCollection.SKILL_WEAPON_CHANCE); - combatTraits.damagePotential.addToMax(SkillCollection.PER_SKILLPOINT_INCREASE_WEAPON_DAMAGE_MAX * player.getSkillLevel(SkillCollection.SKILL_WEAPON_DMG)); - combatTraits.damagePotential.add(SkillCollection.PER_SKILLPOINT_INCREASE_WEAPON_DAMAGE_MIN * player.getSkillLevel(SkillCollection.SKILL_WEAPON_DMG), false); - combatTraits.blockChance += SkillCollection.PER_SKILLPOINT_INCREASE_DODGE * player.getSkillLevel(SkillCollection.SKILL_DODGE); - combatTraits.damageResistance += SkillCollection.PER_SKILLPOINT_INCREASE_BARKSKIN * player.getSkillLevel(SkillCollection.SKILL_BARKSKIN); - if (combatTraits.hasCriticalSkillEffect()) { - combatTraits.criticalSkill += combatTraits.criticalSkill * SkillCollection.PER_SKILLPOINT_INCREASE_MORE_CRITICALS_PERCENT * player.getSkillLevel(SkillCollection.SKILL_MORE_CRITICALS) / 100; + player.attackChance += SkillCollection.PER_SKILLPOINT_INCREASE_WEAPON_CHANCE * player.getSkillLevel(SkillCollection.SKILL_WEAPON_CHANCE); + player.damagePotential.addToMax(SkillCollection.PER_SKILLPOINT_INCREASE_WEAPON_DAMAGE_MAX * player.getSkillLevel(SkillCollection.SKILL_WEAPON_DMG)); + player.damagePotential.add(SkillCollection.PER_SKILLPOINT_INCREASE_WEAPON_DAMAGE_MIN * player.getSkillLevel(SkillCollection.SKILL_WEAPON_DMG), false); + player.blockChance += SkillCollection.PER_SKILLPOINT_INCREASE_DODGE * player.getSkillLevel(SkillCollection.SKILL_DODGE); + player.damageResistance += SkillCollection.PER_SKILLPOINT_INCREASE_BARKSKIN * player.getSkillLevel(SkillCollection.SKILL_BARKSKIN); + if (player.hasCriticalSkillEffect()) { + player.criticalSkill += player.criticalSkill * SkillCollection.PER_SKILLPOINT_INCREASE_MORE_CRITICALS_PERCENT * player.getSkillLevel(SkillCollection.SKILL_MORE_CRITICALS) / 100; } - if (combatTraits.hasCriticalMultiplierEffect()) { - combatTraits.criticalMultiplier += combatTraits.criticalMultiplier * SkillCollection.PER_SKILLPOINT_INCREASE_BETTER_CRITICALS_PERCENT * player.getSkillLevel(SkillCollection.SKILL_BETTER_CRITICALS) / 100; + if (player.hasCriticalMultiplierEffect()) { + player.criticalMultiplier += player.criticalMultiplier * SkillCollection.PER_SKILLPOINT_INCREASE_BETTER_CRITICALS_PERCENT * player.getSkillLevel(SkillCollection.SKILL_BETTER_CRITICALS) / 100; } player.ap.addToMax(SkillCollection.PER_SKILLPOINT_INCREASE_SPEED * player.getSkillLevel(SkillCollection.SKILL_SPEED)); /*final int berserkLevel = player.getSkillLevel(Skills.SKILL_BERSERKER); @@ -145,7 +144,7 @@ public final class SkillController { Player player = world.model.player; - if (player.combatTraits.attackChance - monster.combatTraits.blockChance > SkillCollection.CONCUSSION_THRESHOLD) { + if (player.getAttackChance() - monster.getBlockChance() > SkillCollection.CONCUSSION_THRESHOLD) { if (rollForSkillChance(player, SkillCollection.SKILL_CONCUSSION, SkillCollection.PER_SKILLPOINT_INCREASE_CONCUSSION_CHANCE)) { addConditionToActor(monster, world, "concussion", 1, 5); } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/VisualEffectController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/VisualEffectController.java index 597f4c87e..692768fa0 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/VisualEffectController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/VisualEffectController.java @@ -141,7 +141,7 @@ public final class VisualEffectController { } public static void addSplatter(PredefinedMap map, Monster m) { - int iconID = getSplatterIconFromMonsterClass(m.monsterClass); + int iconID = getSplatterIconFromMonsterClass(m.getMonsterClass()); if (iconID > 0) map.splatters.add(new BloodSplatter(iconID, m.position)); } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/ability/SkillInfo.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/ability/SkillInfo.java index 817b23a93..ec4cc8800 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/ability/SkillInfo.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/ability/SkillInfo.java @@ -81,9 +81,9 @@ public class SkillInfo { private int getRequirementActualValue(Player player) { switch (requirementType) { case REQUIREMENT_TYPE_SKILL_LEVEL: return player.getSkillLevel(skillOrStatID); - case REQUIREMENT_TYPE_EXPERIENCE_LEVEL: return player.level; - case REQUIREMENT_TYPE_COMBAT_STAT: return player.baseTraits.getCombatStats(skillOrStatID); - case REQUIREMENT_TYPE_ACTOR_STAT: return player.baseTraits.getActorStats(skillOrStatID); + case REQUIREMENT_TYPE_EXPERIENCE_LEVEL: return player.getLevel(); + case REQUIREMENT_TYPE_COMBAT_STAT: return player.getCombatStats(skillOrStatID); + case REQUIREMENT_TYPE_ACTOR_STAT: return player.getActorStats(skillOrStatID); default: return 0; } } 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 1195ec63a..606de60f6 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Actor.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Actor.java @@ -4,10 +4,15 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import android.util.FloatMath; 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.item.ItemTraits_OnUse; import com.gpl.rpg.AndorsTrail.model.listeners.ActorConditionListeners; import com.gpl.rpg.AndorsTrail.savegames.LegacySavegameFormatReaderForPlayer.LegacySavegameData_Actor; import com.gpl.rpg.AndorsTrail.util.Coord; @@ -16,34 +21,68 @@ import com.gpl.rpg.AndorsTrail.util.Range; import com.gpl.rpg.AndorsTrail.util.Size; public class Actor { - public final ActorTraits baseTraits; - public final CombatTraits combatTraits; public final int iconID; - public String name; public final Size tileSize; - public final Range ap; - public final Range health; - public final Coord position; + public final Coord position = new Coord(); public final CoordRect rectPosition; + public final boolean isPlayer; + private final boolean isImmuneToCriticalHits; + protected String name; + + // TODO: Should be privates + public final Range ap = new Range(); + public final Range health = new Range(); public final ArrayList conditions = new ArrayList(); public final ActorConditionListeners conditionListener = new ActorConditionListeners(); - public final boolean isPlayer; - public final boolean isImmuneToCriticalHits; + public int moveCost; + public int attackCost; + public int attackChance; + public int criticalSkill; + public float criticalMultiplier; + public final Range damagePotential = new Range(); + public int blockChance; + public int damageResistance; + public ItemTraits_OnUse[] onHitEffects; - public Actor(ActorTraits baseTraits, Size tileSize, boolean isPlayer, boolean isImmuneToCriticalHits) { - this.combatTraits = new CombatTraits(baseTraits); - this.baseTraits = baseTraits; - this.iconID = baseTraits.iconID; + public Actor(int iconID, Size tileSize, boolean isPlayer, boolean isImmuneToCriticalHits) { + this.iconID = iconID; this.tileSize = tileSize; - this.ap = new Range(baseTraits.maxAP, baseTraits.maxAP); - this.health = new Range(baseTraits.maxHP, baseTraits.maxHP); - this.position = new Coord(); - this.rectPosition = new CoordRect(position, tileSize); + this.rectPosition = new CoordRect(this.position, this.tileSize); this.isPlayer = isPlayer; this.isImmuneToCriticalHits = isImmuneToCriticalHits; } - public int getAttacksPerTurn() { return combatTraits.getAttacksPerTurn(baseTraits.maxAP); } + public boolean isImmuneToCriticalHits() { return isImmuneToCriticalHits; } + public String getName() { return name; } + public int getMaxAP() { return ap.max; } + public int getMaxHP() { return health.max; } + public int getMoveCost() { return moveCost; } + public int getAttackCost() { return attackCost; } + public int getAttackChance() { return attackChance; } + public int getCriticalSkill() { return criticalSkill; } + public float getCriticalMultiplier() { return criticalMultiplier; } + public Range getDamagePotential() { return damagePotential; } + public int getBlockChance() { return blockChance; } + public int getDamageResistance() { return damageResistance; } + public ItemTraits_OnUse[] getOnHitEffects() { return onHitEffects; } + public List getOnHitEffectsAsList() { return onHitEffects == null ? null : Arrays.asList(onHitEffects); } + + public boolean hasAttackChanceEffect_() { return getAttackChance() != 0; } + public boolean hasAttackDamageEffect_() { return getDamagePotential().max != 0; } + public boolean hasBlockEffect_() { return getBlockChance() != 0; } + public boolean hasCriticalSkillEffect() { return getCriticalSkill() != 0; } + public boolean hasCriticalMultiplierEffect() { float m = getCriticalMultiplier(); return m != 0 && m != 1; } + public boolean hasCriticalAttacks() { return hasCriticalSkillEffect() && hasCriticalMultiplierEffect(); } + + public int getAttacksPerTurn() { return (int) Math.floor(getMaxAP() / getAttackCost()); } + public int getEffectiveCriticalChance() { return getEffectiveCriticalChance(getCriticalSkill()); } + public static int getEffectiveCriticalChance(int criticalSkill) { + if (criticalSkill <= 0) return 0; + int v = (int) (-5 + 2 * FloatMath.sqrt(5*criticalSkill)); + if (v < 0) return 0; + return v; + } + public boolean isDead() { return health.current <= 0; @@ -54,7 +93,6 @@ public class Actor { public void setMaxHP() { health.setMax(); } - public String getName() { return name; } public boolean useAPs(int cost) { if (ap.current < cost) return false; @@ -71,18 +109,11 @@ public class Actor { } return false; } - - public void resetStatsToBaseTraits() { - combatTraits.set(baseTraits); - health.set(baseTraits.maxHP, health.current); - ap.set(baseTraits.maxAP, ap.current); - baseTraits.moveCost = baseTraits.baseMoveCost; - } - // ====== PARCELABLE =================================================================== + /* public Actor(DataInputStream src, WorldContext world, int fileversion, boolean isPlayer, boolean isImmuneToCriticalHits, Size tileSize, ActorTraits baseTraits) throws IOException { this.isPlayer = isPlayer; this.isImmuneToCriticalHits = isImmuneToCriticalHits; @@ -140,5 +171,5 @@ public class Actor { for (ActorCondition c : conditions) { c.writeToParcel(dest, flags); } - } + }*/ } 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 b7ec6013b..bc9068641 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Monster.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Monster.java @@ -5,65 +5,86 @@ import java.io.DataOutputStream; import java.io.IOException; import com.gpl.rpg.AndorsTrail.context.WorldContext; -import com.gpl.rpg.AndorsTrail.controller.Constants; +import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition; 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; +import com.gpl.rpg.AndorsTrail.util.Range; public final class Monster extends Actor { - public final String monsterTypeID; - public final int millisecondsPerMove; public Coord movementDestination = null; public long nextActionTime = 0; - public boolean forceAggressive = false; public final CoordRect nextPosition; - public final String phraseID; - public final int exp; - public final DropList dropList; - public final String faction; + private boolean forceAggressive = false; private ItemContainer shopItems = null; - public final int monsterClass; - public Monster(MonsterType monsterType, Coord position) { - super(monsterType.baseTraits, monsterType.tileSize, false, monsterType.isImmuneToCriticalHits()); - this.monsterTypeID = monsterType.id; - this.position.set(position); - this.millisecondsPerMove = Constants.MONSTER_MOVEMENT_TURN_DURATION_MS / monsterType.baseTraits.getMovesPerTurn(); + private final MonsterType monsterType; + + public Monster(MonsterType monsterType) { + super(monsterType.iconID, monsterType.tileSize, false, monsterType.isImmuneToCriticalHits()); + this.monsterType = monsterType; this.nextPosition = new CoordRect(new Coord(), monsterType.tileSize); - this.phraseID = monsterType.phraseID; - this.exp = monsterType.exp; - this.dropList = monsterType.dropList; - this.faction = monsterType.faction; - this.monsterClass = monsterType.monsterClass; + resetStatsToBaseTraits(); } + public void resetStatsToBaseTraits() { + this.name = monsterType.name; + this.ap.set(monsterType.maxAP, monsterType.maxAP); + this.health.set(monsterType.maxHP, monsterType.maxHP); + this.position.set(position); + this.moveCost = monsterType.moveCost; + this.attackCost = monsterType.attackCost; + this.attackChance = monsterType.attackChance; + this.criticalSkill = monsterType.criticalSkill; + this.criticalMultiplier = monsterType.criticalMultiplier; + if (monsterType.damagePotential != null) this.damagePotential.set(monsterType.damagePotential); + else this.damagePotential.set(0, 0); + this.blockChance = monsterType.blockChance; + this.damageResistance = monsterType.damageResistance; + this.onHitEffects = monsterType.onHitEffects; + } + + public DropList getDropList() { return monsterType.dropList; } + public int getExp() { return monsterType.exp; } + public String getPhraseID() { return monsterType.phraseID; } + public String getMonsterTypeID() { return monsterType.id; } + public String getFaction() { return monsterType.faction; } + public int getMonsterClass() { return monsterType.monsterClass; } + public void createLoot(Loot container, Player player) { - int exp = this.exp; + int exp = this.getExp(); exp += exp * player.getSkillLevel(SkillCollection.SKILL_MORE_EXP) * SkillCollection.PER_SKILLPOINT_INCREASE_MORE_EXP_PERCENT / 100; container.exp += exp; - if (this.dropList == null) return; - this.dropList.createRandomLoot(container, player); + DropList dropList = getDropList(); + if (dropList == null) return; + dropList.createRandomLoot(container, player); } public ItemContainer getShopItems(Player player) { if (shopItems != null) return shopItems; Loot loot = new Loot(); shopItems = loot.items; - this.dropList.createRandomLoot(loot, player); + getDropList().createRandomLoot(loot, player); return shopItems; } public void resetShopItems() { this.shopItems = null; } + public boolean isAdjacentTo(Player p) { + return this.rectPosition.isAdjacentTo(p.position); + } public boolean isAgressive() { - return phraseID == null || forceAggressive; + return getPhraseID() == null || forceAggressive; + } + + public void forceAggressive() { + forceAggressive = true; } @@ -77,44 +98,104 @@ public final class Monster extends Actor { MonsterType monsterType = world.monsterTypes.getMonsterType(monsterTypeId); if (fileversion < 25) return LegacySavegameFormatReaderForMonster.readFromParcel_pre_v25(src, fileversion, monsterType); - if (fileversion < 33) return LegacySavegameFormatReaderForMonster.readFromParcel_pre_v33(src, world, fileversion, monsterType); + //if (fileversion < 33) return LegacySavegameFormatReaderForMonster.readFromParcel_pre_v33(src, world, fileversion, monsterType); return new Monster(src, world, fileversion, monsterType); } public Monster(DataInputStream src, WorldContext world, int fileversion, MonsterType monsterType) throws IOException { - super(src, world, fileversion, false, monsterType.isImmuneToCriticalHits(), monsterType.tileSize, monsterType.baseTraits); - this.monsterTypeID = monsterType.id; - this.millisecondsPerMove = Constants.MONSTER_MOVEMENT_TURN_DURATION_MS / monsterType.baseTraits.getMovesPerTurn(); - this.nextPosition = new CoordRect(new Coord(), monsterType.tileSize); - this.phraseID = monsterType.phraseID; - this.exp = monsterType.exp; - this.dropList = monsterType.dropList; + this(monsterType); + + boolean readCombatTraits = true; + if (fileversion >= 25) readCombatTraits = src.readBoolean(); + if (readCombatTraits) { + this.attackCost = src.readInt(); + this.attackChance = src.readInt(); + this.criticalSkill = src.readInt(); + this.criticalMultiplier = src.readFloat(); + this.damagePotential.set(new Range(src, fileversion)); + this.blockChance = src.readInt(); + this.damageResistance = src.readInt(); + } + + /*this.name = src.readUTF();*/ + + this.ap.readFromParcel(src, fileversion); + this.health.readFromParcel(src, fileversion); + this.position.readFromParcel(src, fileversion); + if (fileversion > 16) { + final int numConditions = src.readInt(); + for(int i = 0; i < numConditions; ++i) { + conditions.add(new ActorCondition(src, world, fileversion)); + } + } + + if (fileversion >= 34) { + this.moveCost = src.readInt(); + } this.forceAggressive = src.readBoolean(); - this.faction = monsterType.faction; - this.monsterClass = monsterType.monsterClass; - if (src.readBoolean()) { - this.shopItems = new ItemContainer(src, world, fileversion); + if (fileversion >= 31) { + if (src.readBoolean()) { + this.shopItems = new ItemContainer(src, world, fileversion); + } } } + /* public Monster(LegacySavegameData_Monster savegameData, MonsterType monsterType) { - super(savegameData, false); + this(monsterType, savegameData.position); + this.isPlayer = isPlayer; + this.isImmuneToCriticalHits = savegameData.isImmuneToCriticalHits; + this.baseTraits = new ActorTraits(savegameData); + this.name = savegameData.name; + 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); + + this.monsterTypeID = monsterType.id; this.millisecondsPerMove = Constants.MONSTER_MOVEMENT_TURN_DURATION_MS / monsterType.baseTraits.getMovesPerTurn(); this.nextPosition = new CoordRect(new Coord(), monsterType.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 { - dest.writeUTF(monsterTypeID); - super.writeToParcel(dest, flags); + dest.writeUTF(getMonsterTypeID()); + if (attackCost == monsterType.attackCost + && attackChance == monsterType.attackChance + && criticalSkill == monsterType.criticalSkill + && criticalMultiplier == monsterType.criticalMultiplier + && damagePotential.equals(monsterType.damagePotential) + && blockChance == monsterType.blockChance + && damageResistance == monsterType.damageResistance + ) { + dest.writeBoolean(false); + } else { + dest.writeBoolean(true); + dest.writeInt(attackCost); + dest.writeInt(attackChance); + dest.writeInt(criticalSkill); + dest.writeFloat(criticalMultiplier); + damagePotential.writeToParcel(dest, flags); + dest.writeInt(blockChance); + dest.writeInt(damageResistance); + } + ap.writeToParcel(dest, flags); + health.writeToParcel(dest, flags); + position.writeToParcel(dest, flags); + dest.writeInt(conditions.size()); + for (ActorCondition c : conditions) { + c.writeToParcel(dest, flags); + } + dest.writeInt(moveCost); + dest.writeBoolean(forceAggressive); if (shopItems != null) { dest.writeBoolean(true); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/MonsterType.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/MonsterType.java index 615e14f0f..c831d0453 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/MonsterType.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/MonsterType.java @@ -1,6 +1,8 @@ package com.gpl.rpg.AndorsTrail.model.actor; import com.gpl.rpg.AndorsTrail.model.item.DropList; +import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnUse; +import com.gpl.rpg.AndorsTrail.util.ConstRange; import com.gpl.rpg.AndorsTrail.util.Size; public final class MonsterType { @@ -23,9 +25,20 @@ public final class MonsterType { public final boolean isUnique; // Unique monsters are not respawned. public final String faction; public final int monsterClass; - public final ActorTraits baseTraits; public final Size tileSize; - + public final int iconID; + public final int maxAP; + public final int maxHP; + public final int moveCost; + public final int attackCost; + public final int attackChance; + public final int criticalSkill; + public final float criticalMultiplier; + public final ConstRange damagePotential; + public final int blockChance; + public final int damageResistance; + public final ItemTraits_OnUse[] onHitEffects; + public MonsterType( String id, String name, @@ -37,7 +50,18 @@ public final class MonsterType { String faction, int monsterClass, Size tileSize, - ActorTraits baseTraits) { + int iconID, + int maxAP, + int maxHP, + int moveCost, + int attackCost, + int attackChance, + int criticalSkill, + float criticalMultiplier, + ConstRange damagePotential, + int blockChance, + int damageResistance, + ItemTraits_OnUse[] onHitEffects) { this.id = id; this.name = name; this.spawnGroup = spawnGroup; @@ -48,7 +72,18 @@ public final class MonsterType { this.isUnique = isUnique; this.monsterClass = monsterClass; this.tileSize = tileSize; - this.baseTraits = baseTraits; + this.iconID = iconID; + this.maxAP = maxAP; + this.maxHP = maxHP; + this.moveCost = moveCost; + this.attackCost = attackCost; + this.attackChance = attackChance; + this.criticalSkill = criticalSkill; + this.criticalMultiplier = criticalMultiplier; + this.damagePotential = damagePotential; + this.blockChance = blockChance; + this.damageResistance = damageResistance; + this.onHitEffects = onHitEffects; } public boolean isImmuneToCriticalHits() { @@ -57,4 +92,16 @@ public final class MonsterType { else if (monsterClass == MONSTERCLASS_DEMON) return true; return false; } + + public boolean hasCombatStats() { + if (attackCost != 10) return true; + if (attackChance != 0) return true; + if (criticalSkill != 0) return true; + if (criticalMultiplier != 0) return true; + if (damagePotential.current != 0) return true; + if (damagePotential.max != 0) return true; + if (blockChance != 0) return true; + if (damageResistance != 0) return true; + return false; + } } 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 d5c1ad505..4bb68dc17 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Player.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Player.java @@ -3,24 +3,29 @@ package com.gpl.rpg.AndorsTrail.model.actor; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; 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.model.CombatTraits; +import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition; import com.gpl.rpg.AndorsTrail.model.item.DropListCollection; import com.gpl.rpg.AndorsTrail.model.item.Inventory; +import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnUse; 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; @@ -31,32 +36,56 @@ public final class Player extends Actor { public static final Size DEFAULT_PLAYER_SIZE = new Size(1, 1); public final Coord lastPosition; public final Coord nextPosition; + + // TODO: Should be privates public int level; - public int totalExperience; + public final PlayerBaseTraits baseTraits = new PlayerBaseTraits(); public final Range levelExperience; // ranges from 0 to the delta-amount of exp required for next level public final Inventory inventory; - private final HashMap > questProgress = new HashMap >(); + public int availableSkillIncreases = 0; public int useItemCost; public int reequipCost; + + private int totalExperience; + private final HashMap > questProgress = new HashMap >(); private final SparseIntArray skillLevels = new SparseIntArray(); - public String spawnMap; - public String spawnPlace; - public int availableSkillIncreases = 0; + private String spawnMap; + private String spawnPlace; private final HashMap alignments = new HashMap(); + public class PlayerBaseTraits { + public int maxAP; + public int maxHP; + public int moveCost; + public int attackCost; + public int attackChance; + public int criticalSkill; + public float criticalMultiplier; + public final Range damagePotential = new Range(); + public int blockChance; + public int damageResistance; + public int useItemCost; + public int reequipCost; + } + + public void resetStatsToBaseTraits() { + this.ap.max = this.baseTraits.maxAP; + this.health.max = this.baseTraits.maxHP; + this.moveCost = this.baseTraits.moveCost; + this.attackCost = this.baseTraits.attackCost; + this.attackChance = this.baseTraits.attackChance; + this.criticalSkill = this.baseTraits.criticalSkill; + this.criticalMultiplier = this.baseTraits.criticalMultiplier; + this.damagePotential.set(this.baseTraits.damagePotential); + this.blockChance = this.baseTraits.blockChance; + this.damageResistance = this.baseTraits.damageResistance; + this.useItemCost = this.baseTraits.useItemCost; + this.reequipCost = this.baseTraits.reequipCost; + } + public Player() { super( - new ActorTraits( - TileManager.CHAR_HERO - , 0 // attackCost - , 0 // attackChance - , 0 // criticalSkill - , 0 // criticalMultiplier - , new Range() // damagePotential - , 0 // blockChance - , 0 // damageResistance - , DEFAULT_PLAYER_MOVECOST - , null) + TileManager.CHAR_HERO , DEFAULT_PLAYER_SIZE , true // isPlayer , false // isImmuneToCriticalHits @@ -68,6 +97,9 @@ public final class Player extends Actor { } public void initializeNewPlayer(ItemTypeCollection types, DropListCollection dropLists, String name) { + baseTraits.maxAP = 10; + baseTraits.maxHP = 25; + baseTraits.moveCost = DEFAULT_PLAYER_MOVECOST; baseTraits.attackCost = DEFAULT_PLAYER_ATTACKCOST; baseTraits.attackChance = 60; baseTraits.criticalSkill = 0; @@ -75,18 +107,16 @@ public final class Player extends Actor { baseTraits.damagePotential.set(1, 1); baseTraits.blockChance = 0; baseTraits.damageResistance = 0; - baseTraits.maxAP = 10; - baseTraits.maxHP = 25; + baseTraits.useItemCost = 5; + baseTraits.reequipCost = 5; this.name = name; - baseTraits.moveCost = DEFAULT_PLAYER_MOVECOST; - useItemCost = 5; - reequipCost = 5; - - level = 1; - totalExperience = 1; - availableSkillIncreases = 0; - skillLevels.clear(); - alignments.clear(); + this.level = 1; + this.totalExperience = 1; + this.inventory.clear(); + this.questProgress.clear(); + this.skillLevels.clear(); + this.availableSkillIncreases = 0; + this.alignments.clear(); recalculateLevelExperience(); Loot startItems = new Loot(); @@ -94,11 +124,11 @@ public final class Player extends Actor { inventory.add(startItems); if (AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES) { - spawnMap = "debugmap"; - spawnPlace = "start"; + this.spawnMap = "debugmap"; + this.spawnPlace = "start"; } else { - spawnMap = "home"; - spawnPlace = "rest"; + this.spawnMap = "home"; + this.spawnPlace = "rest"; } ActorStatsController.recalculatePlayerCombatTraits(this); @@ -176,20 +206,62 @@ public final class Player extends Actor { alignments.put(faction, newValue); } + public void setSpawnPlace(String spawnMap, String spawnPlace) { + this.spawnPlace = spawnPlace; + this.spawnMap = spawnMap; + } + + public void setName(String name) { + this.name = name; + } + public int getReequipCost() { return reequipCost; } + public int getUseItemCost() { return useItemCost; } + public int getAvailableSkillIncreases() { return availableSkillIncreases; } + public int getLevel() { return level; } + public int getTotalExperience() { return totalExperience; } + public int getGold() { return inventory.gold; } + public String getSpawnMap() { return spawnMap; } + public String getSpawnPlace() { return spawnPlace; } + + + public int getActorStats(int statID) { + switch (statID) { + case ActorTraits.STAT_ACTOR_MAX_HP: return baseTraits.maxHP; + case ActorTraits.STAT_ACTOR_MAX_AP: return baseTraits.maxAP; + case ActorTraits.STAT_ACTOR_MOVECOST: return baseTraits.moveCost; + } + return 0; + } + public int getCombatStats(int statID) { + switch (statID) { + case CombatTraits.STAT_COMBAT_ATTACK_COST: return baseTraits.attackCost; + case CombatTraits.STAT_COMBAT_ATTACK_CHANCE: return baseTraits.attackChance; + case CombatTraits.STAT_COMBAT_CRITICAL_SKILL: return baseTraits.criticalSkill; + case CombatTraits.STAT_COMBAT_CRITICAL_MULTIPLIER: return (int) FloatMath.floor(baseTraits.criticalMultiplier); + case CombatTraits.STAT_COMBAT_DAMAGE_POTENTIAL_MIN: return baseTraits.damagePotential.current; + case CombatTraits.STAT_COMBAT_DAMAGE_POTENTIAL_MAX: return baseTraits.damagePotential.max; + case CombatTraits.STAT_COMBAT_BLOCK_CHANCE: return baseTraits.blockChance; + case CombatTraits.STAT_COMBAT_DAMAGE_RESISTANCE: return baseTraits.damageResistance; + } + return 0; + } // ====== PARCELABLE =================================================================== public static Player readFromParcel(DataInputStream src, WorldContext world, int fileversion) throws IOException { - Player player; + /* Player player; if (fileversion < 34) player = LegacySavegameFormatReaderForPlayer.readFromParcel_pre_v34(src, world, fileversion); else player = new Player(src, world, fileversion); + */ + Player 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, DEFAULT_PLAYER_SIZE, null); this.lastPosition = new Coord(src, fileversion); @@ -229,7 +301,103 @@ public final class Player extends Actor { alignments.put(faction, alignment); } } + */ + public Player(DataInputStream src, WorldContext world, int fileversion) throws IOException { + this(); + + this.name = src.readUTF(); + this.iconID = src.readInt(); + + if (fileversion <= 33) { + LegacySavegameFormatReaderForPlayer.readCombatTraitsPreV034(src, fileversion); + /*this.iconID = */src.readInt(); + /*this.tileSize = */new Size(src, fileversion); + } + + this.baseTraits.maxAP = src.readInt(); + this.baseTraits.maxHP = src.readInt(); + this.moveCost = src.readInt(); + + this.baseTraits.attackCost = src.readInt(); + this.baseTraits.attackChance = src.readInt(); + this.baseTraits.criticalSkill = src.readInt(); + if (fileversion <= 20) { + this.baseTraits.criticalMultiplier = src.readInt(); + } else { + this.baseTraits.criticalMultiplier = src.readFloat(); + } + this.baseTraits.damagePotential.readFromParcel(src, fileversion); + this.baseTraits.blockChance = src.readInt(); + this.baseTraits.damageResistance = src.readInt(); + + if (fileversion <= 16) { + this.baseTraits.moveCost = this.moveCost; + } else { + this.baseTraits.moveCost = src.readInt(); + } + + this.ap.set(new Range(src, fileversion)); + this.health.set(new Range(src, fileversion)); + this.position.set(new Coord(src, fileversion)); + if (fileversion > 16) { + final int n = src.readInt(); + for(int i = 0; i < n ; ++i) { + this.conditions.add(new ActorCondition(src, world, fileversion)); + } + } + + this.lastPosition.readFromParcel(src, fileversion); + this.nextPosition.readFromParcel(src, fileversion); + this.level = src.readInt(); + this.totalExperience = src.readInt(); + this.inventory.readFromParcel(src, world, fileversion); + + if (fileversion <= 13) LegacySavegameFormatReaderForPlayer.readQuestProgressPreV13(this, src, world, fileversion); + + 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()); + } + } + this.spawnMap = src.readUTF(); + this.spawnPlace = src.readUTF(); + + if (fileversion > 13) { + final int numquests = src.readInt(); + for(int i = 0; i < numquests; ++i) { + final String questID = src.readUTF(); + this.questProgress.put(questID, new HashSet()); + final int numprogress = src.readInt(); + for(int j = 0; j < numprogress; ++j) { + int progress = src.readInt(); + this.questProgress.get(questID).add(progress); + } + } + } + + this.availableSkillIncreases = 0; + if (fileversion > 21) { + this.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(); + this.alignments.put(faction, alignment); + } + } + } + + /* public Player(LegacySavegameData_Player savegameData) { super(savegameData, true); this.lastPosition = savegameData.lastPosition; @@ -250,9 +418,29 @@ public final class Player extends Actor { this.availableSkillIncreases = savegameData.availableSkillIncreases; this.alignments.putAll(savegameData.alignments); } - + */ public void writeToParcel(DataOutputStream dest, int flags) throws IOException { - super.writeToParcel(dest, flags); + dest.writeUTF(name); + dest.writeInt(iconID); + dest.writeInt(baseTraits.maxAP); + dest.writeInt(baseTraits.maxHP); + dest.writeInt(moveCost); + dest.writeInt(baseTraits.attackCost); + dest.writeInt(baseTraits.attackChance); + dest.writeInt(baseTraits.criticalSkill); + dest.writeFloat(baseTraits.criticalMultiplier); + baseTraits.damagePotential.writeToParcel(dest, flags); + dest.writeInt(baseTraits.blockChance); + dest.writeInt(baseTraits.damageResistance); + dest.writeInt(baseTraits.moveCost); + + ap.writeToParcel(dest, flags); + health.writeToParcel(dest, flags); + position.writeToParcel(dest, flags); + dest.writeInt(conditions.size()); + for (ActorCondition c : conditions) { + c.writeToParcel(dest, flags); + } lastPosition.writeToParcel(dest, flags); nextPosition.writeToParcel(dest, flags); dest.writeInt(level); 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 f20ccd45e..bf29b0084 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/Inventory.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/Inventory.java @@ -27,6 +27,13 @@ public final class Inventory extends ItemContainer { public Inventory() { } + public void clear() { + for(int i = 0; i < NUM_WORN_SLOTS; ++i) wear[i] = null; + for(int i = 0; i < NUM_QUICK_SLOTS; ++i) quickitem[i] = null; + gold = 0; + items.clear(); + } + public void add(final Loot loot) { this.gold += loot.gold; this.add(loot.items); @@ -56,26 +63,31 @@ public final class Inventory extends ItemContainer { // ====== PARCELABLE =================================================================== public Inventory(DataInputStream src, WorldContext world, int fileversion) throws IOException { - super(src, world, fileversion); + this.readFromParcel(src, world, fileversion); + } + public void readFromParcel(DataInputStream src, WorldContext world, int fileversion) throws IOException { + super.readFromParcel(src, world, fileversion); gold = src.readInt(); if (fileversion < 23) LegacySavegameFormatReaderForItemContainer.refundUpgradedItems(this); - final int size = src.readInt(); - for(int i = 0; i < size; ++i) { + for(int i = 0; i < NUM_WORN_SLOTS; ++i) { + wear[i] = null; + } + final int numWornSlots = src.readInt(); + for(int i = 0; i < numWornSlots; ++i) { if (src.readBoolean()) { wear[i] = world.itemTypes.getItemType(src.readUTF()); - } else { - wear[i] = null; } } + for(int i = 0; i < NUM_QUICK_SLOTS; ++i) { + 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 4ac780d20..188a328fd 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/ItemContainer.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/ItemContainer.java @@ -118,6 +118,11 @@ public class ItemContainer { // ====== PARCELABLE =================================================================== public ItemContainer(DataInputStream src, WorldContext world, int fileversion) throws IOException { + readFromParcel(src, world, fileversion); + } + + public void readFromParcel(DataInputStream src, WorldContext world, int fileversion) throws IOException { + items.clear(); final int size = src.readInt(); for(int i = 0; i < size; ++i) { ItemEntry entry = new ItemEntry(src, world, fileversion); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/MonsterSpawnArea.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/MonsterSpawnArea.java index 741188962..e6a600c62 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/MonsterSpawnArea.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/MonsterSpawnArea.java @@ -62,7 +62,9 @@ public final class MonsterSpawnArea { spawn(p, context.monsterTypes.getMonsterType(monsterTypeID)); } public void spawn(Coord p, MonsterType type) { - monsters.add(new Monster(type, p)); + Monster m = new Monster(type); + m.position.set(p); + monsters.add(m); quantity.current++; } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/MonsterTypeParser.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/MonsterTypeParser.java index c1f19025c..1b6023de9 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/MonsterTypeParser.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/MonsterTypeParser.java @@ -3,14 +3,13 @@ package com.gpl.rpg.AndorsTrail.resource.parsers; import android.util.FloatMath; import com.gpl.rpg.AndorsTrail.controller.Constants; -import com.gpl.rpg.AndorsTrail.model.CombatTraits; import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionTypeCollection; -import com.gpl.rpg.AndorsTrail.model.actor.ActorTraits; import com.gpl.rpg.AndorsTrail.model.actor.MonsterType; import com.gpl.rpg.AndorsTrail.model.item.DropListCollection; import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnUse; import com.gpl.rpg.AndorsTrail.resource.DynamicTileLoader; import com.gpl.rpg.AndorsTrail.resource.ResourceFileTokenizer.ResourceParserFor; +import com.gpl.rpg.AndorsTrail.util.ConstRange; import com.gpl.rpg.AndorsTrail.util.Pair; import com.gpl.rpg.AndorsTrail.util.Size; @@ -30,29 +29,24 @@ public final class MonsterTypeParser extends ResourceParserFor { @Override public Pair parseRow(String[] parts) { - final String monsterTypeId = parts[0]; - final CombatTraits combatTraits = ResourceParserUtils.parseCombatTraits(parts, 11); final ItemTraits_OnUse hitEffect = itemTraitsParser.parseItemTraits_OnUse(parts, 21, true); - final ActorTraits baseTraits = new ActorTraits( - ResourceParserUtils.parseImageID(tileLoader, parts[1]) // IconID - , ResourceParserUtils.parseInt(parts[11], 10) // AttackCost - , ResourceParserUtils.parseInt(parts[12], 0) //AttackChance - , ResourceParserUtils.parseInt(parts[13], 0) //CriticalSkill - , ResourceParserUtils.parseFloat(parts[14], 0) //CriticalMultiplier - , ResourceParserUtils.parseRange(parts[15], parts[16]) //DamagePotential - , ResourceParserUtils.parseInt(parts[17], 0) //BlockChance - , ResourceParserUtils.parseInt(parts[18], 0) //DamageResistance - , ResourceParserUtils.parseInt(parts[10], 10) // MoveCost - , hitEffect == null ? null : new ItemTraits_OnUse[] { hitEffect } - ); - baseTraits.maxHP = ResourceParserUtils.parseInt(parts[8], 1); - baseTraits.maxAP = ResourceParserUtils.parseInt(parts[9], 10); + int maxHP = ResourceParserUtils.parseInt(parts[8], 1); + int maxAP = ResourceParserUtils.parseInt(parts[9], 10); + int attackCost = ResourceParserUtils.parseInt(parts[11], 10); + int attackChance = ResourceParserUtils.parseInt(parts[12], 0); + ConstRange damagePotential = ResourceParserUtils.parseConstRange(parts[15], parts[16]); + int criticalSkill = ResourceParserUtils.parseInt(parts[13], 0); + float criticalMultiplier = ResourceParserUtils.parseFloat(parts[14], 0); + int blockChance = ResourceParserUtils.parseInt(parts[17], 0); + int damageResistance = ResourceParserUtils.parseInt(parts[18], 0); - final int exp = getExpectedMonsterExperience(combatTraits, hitEffect, baseTraits.maxHP, baseTraits.maxAP); + final int exp = getExpectedMonsterExperience(attackCost, attackChance, damagePotential, criticalSkill, criticalMultiplier, blockChance, damageResistance, hitEffect, maxHP, maxAP); + + final String monsterTypeId = parts[0]; return new Pair(monsterTypeId, new MonsterType( monsterTypeId , parts[2] // Name - , parts[3] // Tags + , parts[3] // SpawnGroup , exp // Exp , droplists.getDropList(parts[19]) // Droplist , ResourceParserUtils.parseNullableString(parts[20]) // PhraseID @@ -60,21 +54,45 @@ public final class MonsterTypeParser extends ResourceParserFor { , ResourceParserUtils.parseNullableString(parts[7]) // Faction , ResourceParserUtils.parseInt(parts[5], MonsterType.MONSTERCLASS_HUMANOID) // MonsterClass , ResourceParserUtils.parseSize(parts[4], size1x1) //TODO: This could be loaded from the tileset size instead. - , baseTraits + , ResourceParserUtils.parseImageID(tileLoader, parts[1]) // IconID + , maxAP + , maxHP + , ResourceParserUtils.parseInt(parts[10], 10) // MoveCost + , attackCost + , attackChance + , criticalSkill + , criticalMultiplier + , damagePotential + , blockChance + , damageResistance + , hitEffect == null ? null : new ItemTraits_OnUse[] { hitEffect } )); } private static float div100(int v) { return (float) v / 100f; } - private static int getExpectedMonsterExperience(final CombatTraits t, ItemTraits_OnUse hitEffect, final int maxHP, final int maxAP) { - if (t == null) return 0; - final float avgAttackHP = t.getAttacksPerTurn(maxAP) * div100(t.attackChance) * t.damagePotential.averagef() * (1 + div100(t.criticalSkill) * t.criticalMultiplier); - final float avgDefenseHP = maxHP * (1 + div100(t.blockChance)) + Constants.EXP_FACTOR_DAMAGERESISTANCE * t.damageResistance; + private static int getExpectedMonsterExperience( + int attackCost, + int attackChance, + ConstRange damagePotential, + int criticalSkill, + float criticalMultiplier, + int blockChance, + int damageResistance, + ItemTraits_OnUse hitEffect, + final int maxHP, + final int maxAP) { + final float averageDamage = damagePotential != null ? damagePotential.averagef() : 0; + final float avgAttackHP = getAttacksPerTurn(maxAP, attackCost) * div100(attackChance) * averageDamage * (1 + div100(criticalSkill) * criticalMultiplier); + final float avgDefenseHP = maxHP * (1 + div100(blockChance)) + Constants.EXP_FACTOR_DAMAGERESISTANCE * damageResistance; int attackConditionBonus = 0; if (hitEffect != null && hitEffect.addedConditions_target != null && hitEffect.addedConditions_target.length > 0) { attackConditionBonus += 50; } return (int) FloatMath.ceil((avgAttackHP * 3 + avgDefenseHP) * Constants.EXP_FACTOR_SCALING) + attackConditionBonus; } + private static int getAttacksPerTurn(int maxAP, int attackCost) { + return (int) Math.floor(maxAP / attackCost); + } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/tiles/TileManager.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/tiles/TileManager.java index 8bed39258..5715f67f6 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/tiles/TileManager.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/tiles/TileManager.java @@ -106,7 +106,7 @@ public final class TileManager { HashSet iconIDs = new HashSet(); for(MonsterSpawnArea a : map.spawnAreas) { for(String monsterTypeID : a.monsterTypeIDs) { - iconIDs.add(world.monsterTypes.getMonsterType(monsterTypeID).baseTraits.iconID); + iconIDs.add(world.monsterTypes.getMonsterType(monsterTypeID).iconID); } } iconIDs.addAll(tileMap.usedTileIDs); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/LegacySavegameFormatReaderForMonster.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/LegacySavegameFormatReaderForMonster.java index 0fa8e8056..ce15a1866 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/LegacySavegameFormatReaderForMonster.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/LegacySavegameFormatReaderForMonster.java @@ -15,16 +15,17 @@ 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); + Monster m = new Monster(monsterType); + m.position.set(new Coord(src, fileversion)); m.ap.current = src.readInt(); m.health.current = src.readInt(); if (fileversion >= 12) { - m.forceAggressive = src.readBoolean(); + if (src.readBoolean()) m.forceAggressive(); } 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); @@ -50,21 +51,21 @@ public class LegacySavegameFormatReaderForMonster { result.damageResistance = src.readInt(); } - result.iconID = monsterType.baseTraits.iconID; + result.iconID = monsterType.iconID; result.tileSize = monsterType.tileSize; - result.maxAP = monsterType.baseTraits.maxAP; - result.maxHP = monsterType.baseTraits.maxHP; + result.maxAP = monsterType.maxAP; + result.maxHP = monsterType.maxHP; result.name = monsterType.name; - result.moveCost = monsterType.baseTraits.moveCost; + result.moveCost = monsterType.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; + result.baseAttackCost = monsterType.attackCost; + result.baseAttackChance = monsterType.attackChance; + result.baseCriticalSkill = monsterType.criticalSkill; + result.baseCriticalMultiplier = monsterType.criticalMultiplier; + result.baseDamagePotential = new Range(monsterType.damagePotential); + result.baseBlockChance = monsterType.blockChance; + result.baseDamageResistance = monsterType.damageResistance; + result.baseMoveCost = monsterType.moveCost; if (!readCombatTraits) { result.attackCost = result.baseAttackCost; @@ -101,5 +102,5 @@ public class LegacySavegameFormatReaderForMonster { // 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 index 8108770a4..066f971e4 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/LegacySavegameFormatReaderForPlayer.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/savegames/LegacySavegameFormatReaderForPlayer.java @@ -25,6 +25,7 @@ import com.gpl.rpg.AndorsTrail.util.Range; import com.gpl.rpg.AndorsTrail.util.Size; public final class LegacySavegameFormatReaderForPlayer { + /* public static Player readFromParcel_pre_v34(DataInputStream src, WorldContext world, int fileversion) throws IOException { LegacySavegameData_Player savegameData = readPlayerDataPreV34(src, world, fileversion); return new Player(savegameData); @@ -164,6 +165,7 @@ public final class LegacySavegameFormatReaderForPlayer { public String spawnPlace; public int availableSkillIncreases = 0; } + */ public static class LegacySavegameData_Actor { // from Actor @@ -200,7 +202,7 @@ public final class LegacySavegameFormatReaderForPlayer { public int damageResistance; } - private static void readQuestProgressPreV13(LegacySavegameData_Player player, DataInputStream src, WorldContext world, int fileversion) throws IOException { + public static void readQuestProgressPreV13(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(); @@ -245,10 +247,11 @@ public final class LegacySavegameFormatReaderForPlayer { } } - private static void addQuestProgress(LegacySavegameData_Player player, String questID, int progress) { - if (!player.questProgress.containsKey(questID)) player.questProgress.put(questID, new HashSet()); + private static void addQuestProgress(Player player, String questID, int progress) { + player.addQuestProgress(new QuestProgress(questID, 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); + player.questProgress.get(questID).add(progress);*/ } public static void upgradeSavegame(Player player, WorldContext world, int fileversion) { @@ -265,7 +268,7 @@ public final class LegacySavegameFormatReaderForPlayer { for(SkillInfo skill : world.skills.getAllSkills()) { assignedSkillpoints += player.getSkillLevel(skill.id); } - player.availableSkillIncreases = getExpectedNumberOfSkillpointsForLevel(player.level) - assignedSkillpoints; + player.availableSkillIncreases = getExpectedNumberOfSkillpointsForLevel(player.getLevel()) - assignedSkillpoints; } if (fileversion <= 21) { @@ -307,4 +310,21 @@ public final class LegacySavegameFormatReaderForPlayer { ActorStatsController.removeConditionsFromUnequippedItem(player, world.itemTypes.getItemType(itemTypeIDWithCondition)); } + + public static void readCombatTraitsPreV034(DataInputStream src, int fileversion) throws IOException { + if (fileversion < 25) return; + if (!src.readBoolean()) return; + + /*attackCost = */src.readInt(); + /*attackChance = */src.readInt(); + /*criticalSkill = */src.readInt(); + if (fileversion <= 20) { + /*criticalMultiplier = */src.readInt(); + } else { + /*criticalMultiplier = */src.readFloat(); + } + /*damagePotential = */new Range(src, fileversion); + /*blockChance = */src.readInt(); + /*damageResistance = */src.readInt(); + } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/util/Coord.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/util/Coord.java index 1cba41ef7..88178792a 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/util/Coord.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/util/Coord.java @@ -36,6 +36,9 @@ public final class Coord { // ====== PARCELABLE =================================================================== public Coord(DataInputStream src, int fileversion) throws IOException { + this.readFromParcel(src, fileversion); + } + public void readFromParcel(DataInputStream src, int fileversion) throws IOException { this.x = src.readInt(); this.y = src.readInt(); } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/util/Range.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/util/Range.java index d9e0efc40..320c6fce6 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/util/Range.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/util/Range.java @@ -79,6 +79,9 @@ public final class Range { // ====== PARCELABLE =================================================================== public Range(DataInputStream src, int fileversion) throws IOException { + this.readFromParcel(src, fileversion); + } + public void readFromParcel(DataInputStream src, int fileversion) throws IOException { this.max = src.readInt(); this.current = src.readInt(); } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/ActorConditionList.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/ActorConditionList.java index ddc9fa6e8..367c27352 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/ActorConditionList.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/ActorConditionList.java @@ -1,7 +1,5 @@ package com.gpl.rpg.AndorsTrail.view; -import java.util.Collection; - import com.gpl.rpg.AndorsTrail.AndorsTrailApplication; import com.gpl.rpg.AndorsTrail.Dialogs; import com.gpl.rpg.AndorsTrail.R; @@ -31,7 +29,7 @@ public final class ActorConditionList extends LinearLayout { this.world = app.world; } - public void update(Collection conditions) { + public void update(Iterable conditions) { removeAllViews(); if (conditions == null) return; diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/BaseTraitsInfoView.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/BaseTraitsInfoView.java index ae391e7cd..b8435ae46 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/BaseTraitsInfoView.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/BaseTraitsInfoView.java @@ -1,7 +1,7 @@ package com.gpl.rpg.AndorsTrail.view; import com.gpl.rpg.AndorsTrail.R; -import com.gpl.rpg.AndorsTrail.model.actor.ActorTraits; +import com.gpl.rpg.AndorsTrail.model.actor.Player.PlayerBaseTraits; import android.content.Context; import android.util.AttributeSet; @@ -18,9 +18,15 @@ public final class BaseTraitsInfoView extends TraitsInfoView { basetraitsinfo_max_ap = (TextView) findViewById(R.id.basetraitsinfo_max_ap); } - public void update(ActorTraits traits) { - super.update(traits); - + public void update(PlayerBaseTraits traits) { + super.update( + traits.attackCost + ,traits.attackChance + ,traits.damagePotential + ,traits.criticalSkill + ,traits.criticalMultiplier + ,traits.blockChance + ,traits.damageResistance); basetraitsinfo_max_hp.setText(Integer.toString(traits.maxHP)); basetraitsinfo_max_ap.setText(Integer.toString(traits.maxAP)); } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/CombatView.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/CombatView.java index 3cd37f3a8..5d1ecedd1 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/CombatView.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/CombatView.java @@ -135,15 +135,15 @@ public final class CombatView extends RelativeLayout { monsterBar.setVisibility(View.INVISIBLE); currentMonster = null; if (selectedMonster != null) { - attackMoveButton.setText(res.getString(R.string.combat_attack, player.combatTraits.attackCost)); + attackMoveButton.setText(res.getString(R.string.combat_attack, player.getAttackCost())); monsterBar.setVisibility(View.VISIBLE); world.tileManager.setImageViewTile(monsterInfo, selectedMonster); updateMonsterHealth(selectedMonster.health); currentMonster = selectedMonster; } else if (selectedMovePosition != null) { - attackMoveButton.setText(res.getString(R.string.combat_move, player.baseTraits.moveCost)); + attackMoveButton.setText(res.getString(R.string.combat_move, player.getMoveCost())); } else { - attackMoveButton.setText(res.getString(R.string.combat_attack, player.combatTraits.attackCost)); + attackMoveButton.setText(res.getString(R.string.combat_attack, player.getAttackCost())); } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/TraitsInfoView.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/TraitsInfoView.java index d4af84c58..b9a197f7c 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/TraitsInfoView.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/TraitsInfoView.java @@ -1,9 +1,9 @@ package com.gpl.rpg.AndorsTrail.view; import com.gpl.rpg.AndorsTrail.R; -import com.gpl.rpg.AndorsTrail.model.CombatTraits; import com.gpl.rpg.AndorsTrail.model.actor.Actor; import com.gpl.rpg.AndorsTrail.model.actor.ActorTraits; +import com.gpl.rpg.AndorsTrail.util.Range; import android.content.Context; import android.util.AttributeSet; @@ -57,58 +57,77 @@ public class TraitsInfoView extends TableLayout { traitsinfo_defense_damageresist = (TextView) findViewById(R.id.traitsinfo_defense_damageresist); } - public void update(Actor actor) { update(actor.combatTraits); } - private void update(CombatTraits traits) { - if (traits != null && traits.attackCost != 0) { + public void update(Actor actor) { + update( + actor.getAttackCost() + ,actor.getAttackChance() + ,actor.getDamagePotential() + ,actor.getCriticalSkill() + ,actor.getCriticalMultiplier() + ,actor.getBlockChance() + ,actor.getDamageResistance()); + } + + public void update( + int attackCost + ,int attackChance + ,Range damagePotential + ,int criticalSkill + ,float criticalMultiplier + ,int blockChance + ,int damageResistance + ) { + if (attackCost != 0) { traitsinfo_attack_row1.setVisibility(View.VISIBLE); - traitsinfo_attack_cost.setText(Integer.toString(traits.attackCost)); + traitsinfo_attack_cost.setText(Integer.toString(attackCost)); } else { traitsinfo_attack_row1.setVisibility(View.GONE); } - if (traits != null && traits.hasAttackChanceEffect()) { + if (attackChance != 0) { traitsinfo_attack_row2.setVisibility(View.VISIBLE); - traitsinfo_attack_chance.setText(Integer.toString(traits.attackChance) + "%"); + traitsinfo_attack_chance.setText(Integer.toString(attackChance) + "%"); } else { traitsinfo_attack_row2.setVisibility(View.GONE); } - if (traits != null && traits.hasAttackDamageEffect()) { + if (damagePotential.max != 0) { traitsinfo_attack_row3.setVisibility(View.VISIBLE); - traitsinfo_attack_damage.setText(traits.damagePotential.toMinMaxString()); + traitsinfo_attack_damage.setText(damagePotential.toMinMaxString()); } else { traitsinfo_attack_row3.setVisibility(View.GONE); } - if (traits != null && traits.hasCriticalSkillEffect()) { + if (criticalSkill != 0) { traitsinfo_critical_row1.setVisibility(View.VISIBLE); - traitsinfo_criticalhit_skill.setText(Integer.toString(traits.criticalSkill)); + traitsinfo_criticalhit_skill.setText(Integer.toString(criticalSkill)); } else { traitsinfo_critical_row1.setVisibility(View.GONE); } - if (traits != null && traits.hasCriticalMultiplierEffect()) { + if (criticalMultiplier != 0 && criticalMultiplier != 1) { traitsinfo_critical_row2.setVisibility(View.VISIBLE); - traitsinfo_criticalhit_multiplier.setText(Float.toString(traits.criticalMultiplier)); + traitsinfo_criticalhit_multiplier.setText(Float.toString(criticalMultiplier)); } else { traitsinfo_critical_row2.setVisibility(View.GONE); } - if (traits != null && traits.hasCriticalAttacks()) { + if (criticalSkill != 0 && criticalMultiplier != 0 && criticalMultiplier != 1) { traitsinfo_critical_row3.setVisibility(View.VISIBLE); - traitsinfo_criticalhit_effectivechance.setText(Integer.toString(traits.getEffectiveCriticalChance()) + "%"); + traitsinfo_criticalhit_effectivechance.setText(Integer.toString(Actor.getEffectiveCriticalChance(criticalSkill)) + "%"); } else { traitsinfo_critical_row3.setVisibility(View.GONE); } - if (traits != null && traits.hasBlockEffect()) { + if (blockChance != 0) { traitsinfo_defense_row1.setVisibility(View.VISIBLE); - traitsinfo_defense_chance.setText(Integer.toString(traits.blockChance) + "%"); + traitsinfo_defense_chance.setText(Integer.toString(blockChance) + "%"); } else { traitsinfo_defense_row1.setVisibility(View.GONE); } - if (traits != null && traits.damageResistance != 0) { + if (damageResistance != 0) { traitsinfo_defense_row2.setVisibility(View.VISIBLE); - traitsinfo_defense_damageresist.setText(Integer.toString(traits.damageResistance)); + traitsinfo_defense_damageresist.setText(Integer.toString(damageResistance)); } else { traitsinfo_defense_row2.setVisibility(View.GONE); } } + /* public void update(ActorTraits traits) { if (traits != null && traits.attackCost != 0) { traitsinfo_attack_row1.setVisibility(View.VISIBLE); @@ -159,4 +178,5 @@ public class TraitsInfoView extends TableLayout { traitsinfo_defense_row2.setVisibility(View.GONE); } } + */ }