WIP 2 moved fields from ActorTraits onto ActorTraits.

This commit is contained in:
Oskar Wiksten
2012-10-20 20:49:19 +02:00
parent 81c2c2bc40
commit bf809df44f
10 changed files with 200 additions and 48 deletions

View File

@@ -118,14 +118,14 @@ public final class LevelUpActivity extends Activity {
hpIncrease = Constants.LEVELUP_EFFECT_HEALTH;
break;
case SELECT_ATK_CH:
player.baseTraits.baseCombatTraits.attackChance += Constants.LEVELUP_EFFECT_ATK_CH;
player.baseTraits.attackChance += Constants.LEVELUP_EFFECT_ATK_CH;
break;
case SELECT_ATK_DMG:
player.baseTraits.baseCombatTraits.damagePotential.max += Constants.LEVELUP_EFFECT_ATK_DMG;
player.baseTraits.baseCombatTraits.damagePotential.current += Constants.LEVELUP_EFFECT_ATK_DMG;
player.baseTraits.damagePotential.max += Constants.LEVELUP_EFFECT_ATK_DMG;
player.baseTraits.damagePotential.current += Constants.LEVELUP_EFFECT_ATK_DMG;
break;
case SELECT_DEF_CH:
player.baseTraits.baseCombatTraits.blockChance += Constants.LEVELUP_EFFECT_DEF_CH;
player.baseTraits.blockChance += Constants.LEVELUP_EFFECT_DEF_CH;
break;
}
if (player.nextLevelAddsNewSkillpoint()) {

View File

@@ -6,6 +6,7 @@ import java.io.IOException;
import android.util.FloatMath;
import com.gpl.rpg.AndorsTrail.model.actor.ActorTraits;
import com.gpl.rpg.AndorsTrail.util.Range;
public class CombatTraits {
@@ -31,11 +32,11 @@ public class CombatTraits {
public CombatTraits() {
this.damagePotential = new Range();
}
public CombatTraits(CombatTraits copy) {
public CombatTraits(ActorTraits copy) {
this();
set(copy);
}
public void set(CombatTraits copy) {
public void set(ActorTraits copy) {
if (copy == null) return;
this.attackCost = copy.attackCost;
this.attackChance = copy.attackChance;
@@ -46,7 +47,7 @@ public class CombatTraits {
this.damageResistance = copy.damageResistance;
}
public boolean equals(CombatTraits other) {
public boolean isSameValuesAs(ActorTraits other) {
if (other == null) return isZero();
return
this.attackCost == other.attackCost

View File

@@ -82,7 +82,7 @@ public class SkillInfo {
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.baseCombatTraits.getCombatStats(skillOrStatID);
case REQUIREMENT_TYPE_COMBAT_STAT: return player.baseTraits.getCombatStats(skillOrStatID);
case REQUIREMENT_TYPE_ACTOR_STAT: return player.baseTraits.getActorStats(skillOrStatID);
default: return 0;
}

View File

@@ -26,7 +26,7 @@ public class Actor {
public final boolean isImmuneToCriticalHits;
public Actor(ActorTraits baseTraits, boolean isPlayer, boolean isImmuneToCriticalHits) {
this.combatTraits = new CombatTraits(baseTraits.baseCombatTraits);
this.combatTraits = new CombatTraits(baseTraits);
this.baseTraits = baseTraits;
this.ap = new Range(baseTraits.maxAP, baseTraits.maxAP);
this.health = new Range(baseTraits.maxHP, baseTraits.maxHP);
@@ -66,7 +66,7 @@ public class Actor {
}
public void resetStatsToBaseTraits() {
combatTraits.set(baseTraits.baseCombatTraits);
combatTraits.set(baseTraits);
health.set(baseTraits.maxHP, health.current);
ap.set(baseTraits.maxAP, ap.current);
baseTraits.moveCost = baseTraits.baseMoveCost;
@@ -86,7 +86,7 @@ public class Actor {
if (readCombatTraits) combatTraits = new CombatTraits(src, fileversion);
this.baseTraits = isPlayer ? new ActorTraits(src, world, fileversion) : baseTraits;
if (!readCombatTraits) combatTraits = new CombatTraits(this.baseTraits.baseCombatTraits);
if (!readCombatTraits) combatTraits = new CombatTraits(this.baseTraits);
this.combatTraits = combatTraits;
this.ap = new Range(src, fileversion);
@@ -101,7 +101,7 @@ public class Actor {
}
public void writeToParcel(DataOutputStream dest, int flags) throws IOException {
if (this.combatTraits.equals(baseTraits.baseCombatTraits)) {
if (this.combatTraits.isSameValuesAs(baseTraits)) {
dest.writeBoolean(false);
} else {
dest.writeBoolean(true);

View File

@@ -4,9 +4,12 @@ import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import android.util.FloatMath;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.model.CombatTraits;
import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnUse;
import com.gpl.rpg.AndorsTrail.util.Range;
import com.gpl.rpg.AndorsTrail.util.Size;
public class ActorTraits {
@@ -24,24 +27,54 @@ public class ActorTraits {
public int moveCost;
public final int baseMoveCost;
public final CombatTraits baseCombatTraits;
public int attackCost;
public int attackChance;
public int criticalSkill;
public float criticalMultiplier;
public final Range damagePotential;
public int blockChance;
public int damageResistance;
public ItemTraits_OnUse[] onHitEffects;
public ActorTraits(
int iconID
, Size tileSize
, CombatTraits baseCombatTraits
, int attackCost
, int attackChance
, int criticalSkill
, float criticalMultiplier
, Range damagePotential
, int blockChance
, int damageResistance
, int standardMoveCost
, ItemTraits_OnUse[] onHitEffects
) {
this.iconID = iconID;
this.tileSize = tileSize;
this.baseCombatTraits = baseCombatTraits;
this.attackCost = attackCost;
this.attackChance = attackChance;
this.criticalSkill = criticalSkill;
this.criticalMultiplier = criticalMultiplier;
this.damagePotential = damagePotential;
this.blockChance = blockChance;
this.damageResistance = damageResistance;
this.baseMoveCost = standardMoveCost;
this.onHitEffects = onHitEffects;
}
public int getMovesPerTurn() {
return (int) Math.floor(maxAP / moveCost);
public int getMovesPerTurn() { return (int) Math.floor(maxAP / moveCost); }
public boolean hasAttackChanceEffect() { return attackChance != 0; }
public boolean hasAttackDamageEffect() { return damagePotential.max != 0; }
public boolean hasBlockEffect() { return blockChance != 0; }
public boolean hasCriticalSkillEffect() { return criticalSkill != 0; }
public boolean hasCriticalMultiplierEffect() { return criticalMultiplier != 0 && criticalMultiplier != 1; }
public boolean hasCriticalAttacks() { return hasCriticalSkillEffect() && hasCriticalMultiplierEffect(); }
public int getEffectiveCriticalChance() {
if (criticalSkill <= 0) return 0;
int v = (int) (-5 + 2 * FloatMath.sqrt(5*criticalSkill));
if (v < 0) return 0;
return v;
}
public int getActorStats(int statID) {
@@ -52,7 +85,19 @@ public class ActorTraits {
}
return 0;
}
public int getCombatStats(int statID) {
switch (statID) {
case CombatTraits.STAT_COMBAT_ATTACK_COST: return attackCost;
case CombatTraits.STAT_COMBAT_ATTACK_CHANCE: return attackChance;
case CombatTraits.STAT_COMBAT_CRITICAL_SKILL: return criticalSkill;
case CombatTraits.STAT_COMBAT_CRITICAL_MULTIPLIER: return (int) FloatMath.floor(criticalMultiplier);
case CombatTraits.STAT_COMBAT_DAMAGE_POTENTIAL_MIN: return damagePotential.current;
case CombatTraits.STAT_COMBAT_DAMAGE_POTENTIAL_MAX: return damagePotential.max;
case CombatTraits.STAT_COMBAT_BLOCK_CHANCE: return blockChance;
case CombatTraits.STAT_COMBAT_DAMAGE_RESISTANCE: return damageResistance;
}
return 0;
}
// ====== PARCELABLE ===================================================================
@@ -63,7 +108,19 @@ public class ActorTraits {
this.maxHP = src.readInt();
this.name = src.readUTF();
this.moveCost = src.readInt();
this.baseCombatTraits = new CombatTraits(src, fileversion);
this.attackCost = src.readInt();
this.attackChance = src.readInt();
this.criticalSkill = src.readInt();
if (fileversion <= 20) {
this.criticalMultiplier = src.readInt();
} else {
this.criticalMultiplier = src.readFloat();
}
this.damagePotential = new Range(src, fileversion);
this.blockChance = src.readInt();
this.damageResistance = src.readInt();
if (fileversion <= 16) {
this.baseMoveCost = this.moveCost;
} else {
@@ -78,7 +135,15 @@ public class ActorTraits {
dest.writeInt(maxHP);
dest.writeUTF(name);
dest.writeInt(moveCost);
baseCombatTraits.writeToParcel(dest, flags);
dest.writeInt(attackCost);
dest.writeInt(attackChance);
dest.writeInt(criticalSkill);
dest.writeFloat(criticalMultiplier);
damagePotential.writeToParcel(dest, flags);
dest.writeInt(blockChance);
dest.writeInt(damageResistance);
dest.writeInt(baseMoveCost);
}
}

View File

@@ -15,7 +15,6 @@ import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.controller.ActorStatsController;
import com.gpl.rpg.AndorsTrail.controller.Constants;
import com.gpl.rpg.AndorsTrail.controller.ItemController;
import com.gpl.rpg.AndorsTrail.model.CombatTraits;
import com.gpl.rpg.AndorsTrail.model.item.DropListCollection;
import com.gpl.rpg.AndorsTrail.model.item.Inventory;
import com.gpl.rpg.AndorsTrail.model.item.ItemTypeCollection;
@@ -45,7 +44,22 @@ public final class Player extends Actor {
private final HashMap<String, Integer> alignments = new HashMap<String, Integer>();
public Player() {
super(new ActorTraits(TileManager.CHAR_HERO, new Size(1, 1), new CombatTraits(), DEFAULT_PLAYER_MOVECOST, null), true, false);
super(
new ActorTraits(
TileManager.CHAR_HERO
, new Size(1, 1)
, 0 // attackCost
, 0 // attackChance
, 0 // criticalSkill
, 0 // criticalMultiplier
, new Range() // damagePotential
, 0 // blockChance
, 0 // damageResistance
, DEFAULT_PLAYER_MOVECOST
, null)
, true // isPlayer
, false // isImmuneToCriticalHits
);
this.lastPosition = new Coord();
this.nextPosition = new Coord();
this.levelExperience = new Range();
@@ -53,20 +67,15 @@ public final class Player extends Actor {
}
public void initializeNewPlayer(ItemTypeCollection types, DropListCollection dropLists, String name) {
CombatTraits combat = new CombatTraits();
combat.attackCost = DEFAULT_PLAYER_ATTACKCOST;
combat.attackChance = 60;
combat.criticalSkill = 0;
combat.criticalMultiplier = 1;
combat.damagePotential.set(1, 1);
combat.blockChance = 0;
combat.damageResistance = 0;
baseTraits.baseCombatTraits.set(combat);
baseTraits.attackCost = DEFAULT_PLAYER_ATTACKCOST;
baseTraits.attackChance = 60;
baseTraits.criticalSkill = 0;
baseTraits.criticalMultiplier = 1;
baseTraits.damagePotential.set(1, 1);
baseTraits.blockChance = 0;
baseTraits.damageResistance = 0;
baseTraits.maxAP = 10;
baseTraits.maxHP = 25;
baseTraits.name = name;
baseTraits.moveCost = DEFAULT_PLAYER_MOVECOST;
useItemCost = 5;
@@ -292,7 +301,7 @@ public final class Player extends Actor {
}
if (fileversion <= 30) {
this.baseTraits.baseCombatTraits.attackCost = DEFAULT_PLAYER_ATTACKCOST;
this.baseTraits.attackCost = DEFAULT_PLAYER_ATTACKCOST;
}
}

View File

@@ -49,8 +49,8 @@ public final class ItemTraitsParser {
boolean hasEffect = ResourceParserUtils.parseBoolean(parts[startIndex], false);
if (!hasEffect) return null;
ConstRange boostCurrentHP = ResourceParserUtils.parseRange(parts[startIndex + 1], parts[startIndex + 2]);
ConstRange boostCurrentAP = ResourceParserUtils.parseRange(parts[startIndex + 3], parts[startIndex + 4]);
ConstRange boostCurrentHP = ResourceParserUtils.parseConstRange(parts[startIndex + 1], parts[startIndex + 2]);
ConstRange boostCurrentAP = ResourceParserUtils.parseConstRange(parts[startIndex + 3], parts[startIndex + 4]);
final ArrayList<ActorConditionEffect> addedConditions_source = new ArrayList<ActorConditionEffect>();
final ArrayList<ActorConditionEffect> addedConditions_target = new ArrayList<ActorConditionEffect>();
tokenize4Fields.tokenizeArray(parts[startIndex + 5], addedConditions_source, actorConditionEffectParser_withDuration);

View File

@@ -34,9 +34,15 @@ public final class MonsterTypeParser extends ResourceParserFor<MonsterType> {
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])
ResourceParserUtils.parseImageID(tileLoader, parts[1]) // IconID
, ResourceParserUtils.parseSize(parts[4], size1x1) //TODO: This could be loaded from the tileset size instead.
, combatTraits
, 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 }
);

View File

@@ -7,6 +7,7 @@ import com.gpl.rpg.AndorsTrail.model.ability.traits.StatsModifierTraits;
import com.gpl.rpg.AndorsTrail.resource.DynamicTileLoader;
import com.gpl.rpg.AndorsTrail.util.ConstRange;
import com.gpl.rpg.AndorsTrail.util.L;
import com.gpl.rpg.AndorsTrail.util.Range;
import com.gpl.rpg.AndorsTrail.util.Size;
public final class ResourceParserUtils {
@@ -15,7 +16,27 @@ public final class ResourceParserUtils {
String[] parts = s.split(":");
return tileLoader.prepareTileID(parts[0], Integer.parseInt(parts[1]));
}
public static ConstRange parseRange(String min, String max) {
public static Range parseRange(String min, String max) {
if ( (max == null || max.length() <= 0)
&& (min == null || min.length() <= 0) ) {
return null;
}
if (max == null || max.length() <= 0) {
if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) {
L.log("OPTIMIZE: Unable to parse range with min=" + min + " because max was empty.");
}
return null;
}
if (min == null || min.length() <= 0) {
if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) {
L.log("OPTIMIZE: Unable to parse range with max=" + max + " because min was empty.");
}
return null;
}
return new Range(Integer.parseInt(max), Integer.parseInt(min));
}
public static ConstRange parseConstRange(String min, String max) {
if ( (max == null || max.length() <= 0)
&& (min == null || min.length() <= 0) ) {
return null;
@@ -50,7 +71,7 @@ public final class ResourceParserUtils {
String attackChance = parts[startIndex + 1];
String criticalSkill = parts[startIndex + 2];
String criticalMultiplier = parts[startIndex + 3];
ConstRange attackDamage = parseRange(parts[startIndex + 4], parts[startIndex + 5]);
ConstRange attackDamage = parseConstRange(parts[startIndex + 4], parts[startIndex + 5]);
String blockChance = parts[startIndex + 6];
String damageResistance = parts[startIndex + 7];
if ( attackCost.length() <= 0
@@ -102,8 +123,8 @@ public final class ResourceParserUtils {
if (!hasEffect) return null;
String visualEffectID = parts[startIndex + 1];
ConstRange boostCurrentHP = parseRange(parts[startIndex + 2], parts[startIndex + 3]);
ConstRange boostCurrentAP = parseRange(parts[startIndex + 4], parts[startIndex + 5]);
ConstRange boostCurrentHP = parseConstRange(parts[startIndex + 2], parts[startIndex + 3]);
ConstRange boostCurrentAP = parseConstRange(parts[startIndex + 4], parts[startIndex + 5]);
if ( boostCurrentHP == null
&& boostCurrentAP == null
) {
@@ -174,7 +195,7 @@ public final class ResourceParserUtils {
else if (min.equals("1") && max.equals("1")) return one;
else if (min.equals("5") && max.equals("5")) return five;
else if (min.equals("10") && max.equals("10")) return ten;
return parseRange(min, max);
return parseConstRange(min, max);
}
public static final ConstRange always = one;

View File

@@ -57,9 +57,8 @@ public class TraitsInfoView extends TableLayout {
traitsinfo_defense_damageresist = (TextView) findViewById(R.id.traitsinfo_defense_damageresist);
}
public void update(Actor actor) { update(actor.combatTraits, true); }
public void update(ActorTraits actorTraits) { update(actorTraits.baseCombatTraits, true); }
private void update(CombatTraits traits, boolean showEffectiveCriticalChance) {
public void update(Actor actor) { update(actor.combatTraits); }
private void update(CombatTraits traits) {
if (traits != null && traits.attackCost != 0) {
traitsinfo_attack_row1.setVisibility(View.VISIBLE);
traitsinfo_attack_cost.setText(Integer.toString(traits.attackCost));
@@ -90,7 +89,58 @@ public class TraitsInfoView extends TableLayout {
} else {
traitsinfo_critical_row2.setVisibility(View.GONE);
}
if (showEffectiveCriticalChance && traits != null && traits.hasCriticalAttacks()) {
if (traits != null && traits.hasCriticalAttacks()) {
traitsinfo_critical_row3.setVisibility(View.VISIBLE);
traitsinfo_criticalhit_effectivechance.setText(Integer.toString(traits.getEffectiveCriticalChance()) + "%");
} else {
traitsinfo_critical_row3.setVisibility(View.GONE);
}
if (traits != null && traits.hasBlockEffect()) {
traitsinfo_defense_row1.setVisibility(View.VISIBLE);
traitsinfo_defense_chance.setText(Integer.toString(traits.blockChance) + "%");
} else {
traitsinfo_defense_row1.setVisibility(View.GONE);
}
if (traits != null && traits.damageResistance != 0) {
traitsinfo_defense_row2.setVisibility(View.VISIBLE);
traitsinfo_defense_damageresist.setText(Integer.toString(traits.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);
traitsinfo_attack_cost.setText(Integer.toString(traits.attackCost));
} else {
traitsinfo_attack_row1.setVisibility(View.GONE);
}
if (traits != null && traits.hasAttackChanceEffect()) {
traitsinfo_attack_row2.setVisibility(View.VISIBLE);
traitsinfo_attack_chance.setText(Integer.toString(traits.attackChance) + "%");
} else {
traitsinfo_attack_row2.setVisibility(View.GONE);
}
if (traits != null && traits.hasAttackDamageEffect()) {
traitsinfo_attack_row3.setVisibility(View.VISIBLE);
traitsinfo_attack_damage.setText(traits.damagePotential.toMinMaxString());
} else {
traitsinfo_attack_row3.setVisibility(View.GONE);
}
if (traits != null && traits.hasCriticalSkillEffect()) {
traitsinfo_critical_row1.setVisibility(View.VISIBLE);
traitsinfo_criticalhit_skill.setText(Integer.toString(traits.criticalSkill));
} else {
traitsinfo_critical_row1.setVisibility(View.GONE);
}
if (traits != null && traits.hasCriticalMultiplierEffect()) {
traitsinfo_critical_row2.setVisibility(View.VISIBLE);
traitsinfo_criticalhit_multiplier.setText(Float.toString(traits.criticalMultiplier));
} else {
traitsinfo_critical_row2.setVisibility(View.GONE);
}
if (traits != null && traits.hasCriticalAttacks()) {
traitsinfo_critical_row3.setVisibility(View.VISIBLE);
traitsinfo_criticalhit_effectivechance.setText(Integer.toString(traits.getEffectiveCriticalChance()) + "%");
} else {