<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.gpl.rpg.AndorsTrail"
- android:versionCode="24"
- android:versionName="0.6.10a3"
+ android:versionCode="25"
+ android:versionName="0.6.10a4"
android:installLocation="auto"
>
<uses-sdk
android:id="@+id/heroinfo_currentconditions_title"
android:layout_marginTop="@dimen/section_margin"
/>
- <LinearLayout
+ <com.gpl.rpg.AndorsTrail.view.ActorConditionList
android:id="@+id/heroinfo_currentconditions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="vertical"
- android:gravity="left"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/actorinfo_currentconditions"
+ android:id="@+id/monsterinfo_currentconditions_title"
+ android:layout_marginTop="@dimen/section_margin"
+ />
+ <com.gpl.rpg.AndorsTrail.view.ActorConditionList
+ android:id="@+id/monsterinfo_currentconditions"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ />
+
</LinearLayout>
</ScrollView>
<string name="actorinfo_criticalhit">Critical hit:</string>
<string name="actorinfo_defense">Defense:</string>
<string name="actorinfo_movecost">Move cost (AP):</string>
- <string name="actorinfo_basetraits">Unequipped combat statistics (base)</string>
- <string name="actorinfo_currenttraits">Equipped combat statistics (current)</string>
+ <string name="actorinfo_basetraits">Base combat statistics (without equipment and skills)</string>
+ <string name="actorinfo_currenttraits">Combat statistics (current)</string>
<string name="traitsinfo_attack_cost">Attack cost (AP):</string>
<string name="traitsinfo_attack_chance">Attack chance:</string>
<string name="skill_current_level_with_maximum">Current level: %1$d / %2$d</string>
<string name="skill_prerequisite_other_skill">To level up this skill, you need at least level %1$d of the %2$s skill.</string>
<string name="skill_prerequisite_level">To level up this skill, you need at least experience level %1$d.</string>
- <string name="skill_prerequisite_stat">To level up this skill, you need at least %1$d %2$s (unequipped stats).</string>
+ <string name="skill_prerequisite_stat">To level up this skill, you need at least %1$d %2$s (base stats).</string>
<string name="skill_number_of_increases_one">You may select one skill to increase.</string>
<string name="skill_number_of_increases_several">You may select %1$d skills to increase.</string>
<string name="levelup_adds_new_skillpoint">This level also gives you a new skill point to spend!</string>
public static final boolean DEVELOPMENT_DEBUGBUTTONS = false;\r
public static final boolean DEVELOPMENT_VALIDATEDATA = false;\r
public static final boolean DEVELOPMENT_DEBUGMESSAGES = false;\r
- public static final int CURRENT_VERSION = 24;\r
- public static final String CURRENT_VERSION_DISPLAY = "0.6.10a3";\r
+ public static final int CURRENT_VERSION = 25;\r
+ public static final String CURRENT_VERSION_DISPLAY = "0.6.10a4";\r
\r
public final WorldContext world = new WorldContext();\r
public final WorldSetup setup = new WorldSetup(world, this);\r
return new File(root, Constants.FILENAME_SAVEGAME_DIRECTORY);
}
- private static void saveWorld(WorldContext world, OutputStream outStream, String displayInfo) throws IOException {
+ public static void saveWorld(WorldContext world, OutputStream outStream, String displayInfo) throws IOException {
DataOutputStream dest = new DataOutputStream(outStream);
final int flags = 0;
- FileHeader.writeToParcel(dest, world.model.player.traits.name, displayInfo);
+ FileHeader.writeToParcel(dest, world.model.player.actorTraits.name, displayInfo);
world.maps.writeToParcel(dest, flags);
world.model.writeToParcel(dest, flags);
dest.close();
}
- private static int loadWorld(WorldContext world, InputStream inState) throws IOException {
+ public static int loadWorld(WorldContext world, InputStream inState) throws IOException {
DataInputStream src = new DataInputStream(inState);
final FileHeader header = new FileHeader(src);
if (header.fileversion > AndorsTrailApplication.CURRENT_VERSION) return LOAD_RESULT_FUTURE_VERSION;
public FileHeader(DataInputStream src) throws IOException {
int fileversion = src.readInt();
- if (fileversion == 11) fileversion = 5; // Fileversion 5 had no version identifier, but the first byte was 11.
+ if (fileversion == 11) fileversion = 5; // Fileversion 5 had no version identifier, but the first byte was 11.
this.fileversion = fileversion;
if (fileversion >= 14) { // Before fileversion 14 (0.6.7), we had no file header.
this.playerName = src.readUTF();
ConversationStatement s = new ConversationStatement();
if (displayActors) {
assert(actor != null);
- s.iconID = actor.traits.iconID;
- s.actorName = actor.traits.name;
+ s.iconID = actor.actorTraits.iconID;
+ s.actorName = actor.actorTraits.name;
} else {
s.iconID = ConversationStatement.NO_ICON;
}
new DebugButton("dmg", new OnClickListener() {
@Override
public void onClick(View arg0) {
- world.model.player.traits.damagePotential.set(99, 99);
- world.model.player.traits.attackChance = 200;
- world.model.player.traits.attackCost = 1;
+ world.model.player.combatTraits.damagePotential.set(99, 99);
+ world.model.player.combatTraits.attackChance = 200;
+ world.model.player.combatTraits.attackCost = 1;
mainActivity.updateStatus();
mainActivity.showToast("DEBUG: damagePotential=99, chance=200%, cost=1", Toast.LENGTH_SHORT);
}
mainActivity.showToast("DEBUG: damagePotential=1", Toast.LENGTH_SHORT);
}
})*/
- /*,new DebugButton("items", new OnClickListener() {
+ ,new DebugButton("items", new OnClickListener() {
@Override
public void onClick(View arg0) {
world.model.player.inventory.addItem(world.itemTypes.getItemType("elytharan_redeemer"));
world.model.player.inventory.addItem(world.itemTypes.getItemType("calomyran_secrets"));
world.model.player.inventory.addItem(world.itemTypes.getItemType("tail_caverat"));
world.model.player.inventory.addItem(world.itemTypes.getItemType("bwm_leather_cap"));
+ world.model.player.inventory.addItem(world.itemTypes.getItemType("chaosreaper"));
mainActivity.updateStatus();
mainActivity.showToast("DEBUG: added items", Toast.LENGTH_SHORT);
}
- })*/
+ })
/*new DebugButton("skills++", new OnClickListener() {
@Override
public void onClick(View arg0) {
,new DebugButton("hp", new OnClickListener() {
@Override
public void onClick(View arg0) {
- world.model.player.traits.maxHP = 200;
- world.model.player.health.max = world.model.player.traits.maxHP;
+ world.model.player.actorTraits.maxHP = 200;
+ world.model.player.health.max = world.model.player.actorTraits.maxHP;
world.model.player.health.setMax();
world.model.player.conditions.clear();
mainActivity.updateStatus();
mainActivity.showToast("DEBUG: hp set to max", Toast.LENGTH_SHORT);
}
})
+ ,new DebugButton("exp", new OnClickListener() {
+ @Override
+ public void onClick(View arg0) {
+ world.model.player.addExperience(10000);
+ mainActivity.updateStatus();
+ mainActivity.showToast("DEBUG: added 10k exp", Toast.LENGTH_SHORT);
+ }
+ })
,new DebugButton("cg", new OnClickListener() {
@Override
public void onClick(View arg0) {
private void updateTraits() {
heroinfo_stats_gold.setText(getResources().getString(R.string.heroinfo_gold, player.inventory.gold));
- heroinfo_stats_attack.setText(ItemType.describeAttackEffect(player.traits));
- heroinfo_stats_defense.setText(ItemType.describeBlockEffect(player.traits));
+ heroinfo_stats_attack.setText(ItemType.describeAttackEffect(player.combatTraits));
+ heroinfo_stats_defense.setText(ItemType.describeBlockEffect(player.combatTraits));
}
private void updateWorn() {
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
import com.gpl.rpg.AndorsTrail.R;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
-import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition;
-import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionType;
import com.gpl.rpg.AndorsTrail.model.actor.Player;
import com.gpl.rpg.AndorsTrail.model.item.Inventory;
import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnUse;
import com.gpl.rpg.AndorsTrail.model.item.ItemType;
-import com.gpl.rpg.AndorsTrail.view.ActorConditionEffectList;
+import com.gpl.rpg.AndorsTrail.view.ActorConditionList;
import com.gpl.rpg.AndorsTrail.view.BaseTraitsInfoView;
import com.gpl.rpg.AndorsTrail.view.ItemEffectsView;
import com.gpl.rpg.AndorsTrail.view.RangeBar;
import com.gpl.rpg.AndorsTrail.view.TraitsInfoView;
import android.app.Activity;
-import android.content.Context;
import android.content.Intent;
-import android.content.res.Resources;
import android.os.Bundle;
-import android.text.SpannableString;
-import android.text.style.UnderlineSpan;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
-import android.widget.LinearLayout;
import android.widget.TextView;
public final class HeroinfoActivity_Stats extends Activity {
private TraitsInfoView heroinfo_currenttraits;
private ItemEffectsView heroinfo_itemeffects;
private TextView heroinfo_currentconditions_title;
- private LinearLayout heroinfo_currentconditions;
+ private ActorConditionList heroinfo_currentconditions;
private TextView heroinfo_level;
private TextView heroinfo_totalexperience;
private RangeBar rangebar_hp;
setContentView(R.layout.heroinfo_stats);
ImageView iv = (ImageView) findViewById(R.id.heroinfo_image);
- iv.setImageBitmap(world.tileStore.getBitmap(player.traits.iconID));
+ iv.setImageBitmap(world.tileStore.getBitmap(player.actorTraits.iconID));
- ((TextView) findViewById(R.id.heroinfo_title)).setText(player.traits.name);
+ ((TextView) findViewById(R.id.heroinfo_title)).setText(player.actorTraits.name);
heroinfo_ap = (TextView) findViewById(R.id.heroinfo_ap);
heroinfo_movecost = (TextView) findViewById(R.id.heroinfo_movecost);
heroinfo_currenttraits = (TraitsInfoView) findViewById(R.id.heroinfo_currenttraits);
heroinfo_itemeffects = (ItemEffectsView) findViewById(R.id.heroinfo_itemeffects);
heroinfo_currentconditions_title = (TextView) findViewById(R.id.heroinfo_currentconditions_title);
- heroinfo_currentconditions = (LinearLayout) findViewById(R.id.heroinfo_currentconditions);
+ heroinfo_currentconditions = (ActorConditionList) findViewById(R.id.heroinfo_currentconditions);
heroinfo_level = (TextView) findViewById(R.id.heroinfo_level);
heroinfo_totalexperience = (TextView) findViewById(R.id.heroinfo_totalexperience);
heroinfo_level.setText(Integer.toString(player.level));
heroinfo_totalexperience.setText(Integer.toString(player.totalExperience));
heroinfo_ap.setText(player.ap.toString());
- heroinfo_movecost.setText(Integer.toString(player.traits.moveCost));
+ heroinfo_movecost.setText(Integer.toString(player.actorTraits.moveCost));
rangebar_hp.update(player.health);
rangebar_exp.update(player.levelExperience);
- heroinfo_currenttraits.update(player.traits);
+ heroinfo_currenttraits.update(player.combatTraits);
ArrayList<ItemTraits_OnUse> effects_hit = new ArrayList<ItemTraits_OnUse>();
ArrayList<ItemTraits_OnUse> effects_kill = new ArrayList<ItemTraits_OnUse>();
for (int i = 0; i < Inventory.NUM_WORN_SLOTS; ++i) {
if (effects_hit.isEmpty()) effects_hit = null;
if (effects_kill.isEmpty()) effects_kill = null;
heroinfo_itemeffects.update(null, null, effects_hit, effects_kill);
- heroinfo_basetraits.update(player.traits);
+ heroinfo_basetraits.update(player.actorTraits.baseCombatTraits);
}
private void updateConditions() {
} else {
heroinfo_currentconditions_title.setVisibility(View.VISIBLE);
heroinfo_currentconditions.setVisibility(View.VISIBLE);
- heroinfo_currentconditions.removeAllViews();
- final Resources res = getResources();
- final Context context = this;
- for (ActorCondition c : player.conditions) {
- View v = View.inflate(this, R.layout.inventoryitemview, null);
- ((ImageView) v.findViewById(R.id.inv_image)).setImageBitmap(world.tileStore.getBitmap(c.conditionType.iconID));
- SpannableString content = new SpannableString(describeEffect(res, c));
- content.setSpan(new UnderlineSpan(), 0, content.length(), 0);
- ((TextView) v.findViewById(R.id.inv_text)).setText(content);
- final ActorConditionType conditionType = c.conditionType;
- v.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View arg0) {
- Dialogs.showActorConditionInfo(context, conditionType);
- }
- });
- heroinfo_currentconditions.addView(v, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
- }
+ heroinfo_currentconditions.update(player.conditions);
}
}
-
- private static String describeEffect(Resources res, ActorCondition c) {
- return ActorConditionEffectList.describeEffect(res, c.conditionType, c.magnitude, c.duration);
- }
}
final Resources res = getResources();
ImageView img = (ImageView) findViewById(R.id.levelup_image);
- img.setImageBitmap(world.tileStore.getBitmap(player.traits.iconID));
+ img.setImageBitmap(world.tileStore.getBitmap(player.actorTraits.iconID));
TextView tv = (TextView) findViewById(R.id.levelup_description);
tv.setText(res.getString(R.string.levelup_description, player.level+1));
LevelUpActivity.this.finish();
}
- private static void addLevelupEffect(Player player, int selectionID) {
+ public static void addLevelupEffect(Player player, int selectionID) {
int hpIncrease = 0;
switch (selectionID) {
case SELECT_HEALTH:
hpIncrease = Constants.LEVELUP_EFFECT_HEALTH;
break;
case SELECT_ATK_CH:
- player.traits.baseCombatTraits.attackChance += Constants.LEVELUP_EFFECT_ATK_CH;
+ player.actorTraits.baseCombatTraits.attackChance += Constants.LEVELUP_EFFECT_ATK_CH;
break;
case SELECT_ATK_DMG:
- player.traits.baseCombatTraits.damagePotential.max += Constants.LEVELUP_EFFECT_ATK_DMG;
- player.traits.baseCombatTraits.damagePotential.current += Constants.LEVELUP_EFFECT_ATK_DMG;
+ player.actorTraits.baseCombatTraits.damagePotential.max += Constants.LEVELUP_EFFECT_ATK_DMG;
+ player.actorTraits.baseCombatTraits.damagePotential.current += Constants.LEVELUP_EFFECT_ATK_DMG;
break;
case SELECT_DEF_CH:
- player.traits.baseCombatTraits.blockChance += Constants.LEVELUP_EFFECT_DEF_CH;
+ player.actorTraits.baseCombatTraits.blockChance += Constants.LEVELUP_EFFECT_DEF_CH;
break;
}
if (player.nextLevelAddsNewSkillpoint()) {
hpIncrease += player.getSkillLevel(SkillCollection.SKILL_FORTITUDE) * SkillCollection.PER_SKILLPOINT_INCREASE_FORTITUDE_HEALTH;
player.health.max += hpIncrease;
- player.traits.maxHP += hpIncrease;
+ player.actorTraits.maxHP += hpIncrease;
player.health.current += hpIncrease;
player.recalculateLevelExperience();
if (isLoading) return false;\r
if (slot == SLOT_NUMBER_CREATE_NEW_SLOT) return false; // if we're creating a new slot\r
\r
- final String currentPlayerName = model.player.traits.name;\r
+ final String currentPlayerName = model.player.actorTraits.name;\r
final FileHeader header = Savegames.quickload(this, slot);\r
if (header == null) return false;\r
\r
public void onClick(View view) {\r
final int slot = (Integer) view.getTag();\r
if (requiresConfirmation(slot)) {\r
- final String playerName = model.player.traits.name;\r
+ final String playerName = model.player.actorTraits.name;\r
\r
new AlertDialog.Builder(this)\r
.setIcon(android.R.drawable.ic_dialog_alert)\r
CharSequence difficulty = getText(MonsterInfoActivity.getMonsterDifficultyResource(world, monster));
TextView tv = (TextView) findViewById(R.id.monsterencounter_title);
- tv.setText(monster.traits.name);
+ tv.setText(monster.actorTraits.name);
tv = (TextView) findViewById(R.id.monsterencounter_description);
tv.setText(getString(R.string.dialog_monsterencounter_message, difficulty));
ImageView iw = (ImageView) findViewById(R.id.monsterencounter_image);
- iw.setImageBitmap(world.tileStore.getBitmap(monster.traits.iconID));
+ iw.setImageBitmap(world.tileStore.getBitmap(monster.actorTraits.iconID));
Button b = (Button) findViewById(R.id.monsterencounter_attack);
b.setOnClickListener(new OnClickListener() {
import com.gpl.rpg.AndorsTrail.context.WorldContext;\r
import com.gpl.rpg.AndorsTrail.controller.CombatController;\r
import com.gpl.rpg.AndorsTrail.model.actor.Monster;\r
+import com.gpl.rpg.AndorsTrail.view.ActorConditionList;\r
import com.gpl.rpg.AndorsTrail.view.ItemEffectsView;\r
import com.gpl.rpg.AndorsTrail.view.RangeBar;\r
import com.gpl.rpg.AndorsTrail.view.TraitsInfoView;\r
\r
public final class MonsterInfoActivity extends Activity {\r
\r
+ private ImageView monsterinfo_image;\r
+ private TextView monsterinfo_title;\r
+ private TextView monsterinfo_difficulty;\r
+ private TraitsInfoView monsterinfo_currenttraits;\r
+ private ItemEffectsView monsterinfo_onhiteffects;\r
+ private TextView monsterinfo_currentconditions_title;\r
+ private ActorConditionList monsterinfo_currentconditions;\r
+ private RangeBar hp;\r
+ private WorldContext world;\r
+ \r
@Override\r
public void onCreate(Bundle savedInstanceState) {\r
super.onCreate(savedInstanceState);\r
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this);\r
- final WorldContext world = app.world;\r
+ this.world = app.world;\r
requestWindowFeature(Window.FEATURE_NO_TITLE);\r
\r
- final Monster monster = Dialogs.getMonsterFromIntent(getIntent(), world);\r
- if (monster == null) {\r
- finish();\r
- return;\r
- } \r
- \r
setContentView(R.layout.monsterinfo);\r
\r
- ImageView img = (ImageView) findViewById(R.id.monsterinfo_image);\r
- img.setImageBitmap(world.tileStore.getBitmap(monster.traits.iconID));\r
- TextView tv = (TextView) findViewById(R.id.monsterinfo_title);\r
- tv.setText(monster.traits.name);\r
- tv = (TextView) findViewById(R.id.monsterinfo_difficulty);\r
- tv.setText(getMonsterDifficultyResource(world, monster));\r
-\r
+ monsterinfo_image = (ImageView) findViewById(R.id.monsterinfo_image);\r
+ monsterinfo_title = (TextView) findViewById(R.id.monsterinfo_title);\r
+ monsterinfo_difficulty = (TextView) findViewById(R.id.monsterinfo_difficulty);\r
+ \r
Button b = (Button) findViewById(R.id.monsterinfo_close);\r
b.setOnClickListener(new OnClickListener() {\r
@Override\r
}\r
});\r
\r
- ((TraitsInfoView) findViewById(R.id.monsterinfo_currenttraits)).update(monster.traits);\r
- ((ItemEffectsView) findViewById(R.id.monsterinfo_onhiteffects)).update(\r
+ monsterinfo_currenttraits = (TraitsInfoView) findViewById(R.id.monsterinfo_currenttraits);\r
+ monsterinfo_onhiteffects = (ItemEffectsView) findViewById(R.id.monsterinfo_onhiteffects);\r
+ monsterinfo_currentconditions_title = (TextView) findViewById(R.id.monsterinfo_currentconditions_title);\r
+ monsterinfo_currentconditions = (ActorConditionList) findViewById(R.id.monsterinfo_currentconditions);\r
+ hp = (RangeBar) findViewById(R.id.monsterinfo_healthbar);\r
+ hp.init(R.drawable.ui_progress_health, R.string.status_hp);\r
+ }\r
+\r
+ @Override\r
+ protected void onResume() {\r
+ super.onResume();\r
+ \r
+ Monster monster = Dialogs.getMonsterFromIntent(getIntent(), world);\r
+ if (monster == null) {\r
+ finish();\r
+ return;\r
+ } \r
+ \r
+ updateTitle(monster);\r
+ updateTraits(monster);\r
+ updateConditions(monster);\r
+ }\r
+\r
+ private void updateTitle(Monster monster) {\r
+ monsterinfo_image.setImageBitmap(world.tileStore.getBitmap(monster.actorTraits.iconID));\r
+ monsterinfo_title.setText(monster.actorTraits.name);\r
+ monsterinfo_difficulty.setText(getMonsterDifficultyResource(world, monster));\r
+ }\r
+\r
+ private void updateTraits(Monster monster) {\r
+ monsterinfo_currenttraits.update(monster.combatTraits);\r
+ monsterinfo_onhiteffects.update(\r
null, \r
null, \r
- monster.traits.onHitEffects == null ? null : Arrays.asList(monster.traits.onHitEffects), \r
+ monster.actorTraits.onHitEffects == null ? null : Arrays.asList(monster.actorTraits.onHitEffects), \r
null);\r
- RangeBar hp = (RangeBar) findViewById(R.id.monsterinfo_healthbar);\r
- hp.init(R.drawable.ui_progress_health, R.string.status_hp);\r
hp.update(monster.health);\r
}\r
\r
else if (difficulty == 0) return R.string.monster_difficulty_impossible;\r
else return R.string.monster_difficulty_veryhard;\r
}\r
+\r
+ private void updateConditions(Monster monster) {\r
+ if (monster.conditions.isEmpty()) {\r
+ monsterinfo_currentconditions_title.setVisibility(View.GONE);\r
+ monsterinfo_currentconditions.setVisibility(View.GONE);\r
+ } else {\r
+ monsterinfo_currentconditions_title.setVisibility(View.VISIBLE);\r
+ monsterinfo_currentconditions.setVisibility(View.VISIBLE);\r
+ monsterinfo_currentconditions.update(monster.conditions);\r
+ }\r
+ }\r
}\r
import com.gpl.rpg.AndorsTrail.model.ability.traits.AbilityModifierTraits;
import com.gpl.rpg.AndorsTrail.model.ability.traits.StatsModifierTraits;
import com.gpl.rpg.AndorsTrail.model.actor.Actor;
-import com.gpl.rpg.AndorsTrail.model.actor.ActorTraits;
import com.gpl.rpg.AndorsTrail.model.actor.Monster;
import com.gpl.rpg.AndorsTrail.model.actor.Player;
import com.gpl.rpg.AndorsTrail.model.item.Inventory;
public static void applyAbilityEffects(Actor actor, AbilityModifierTraits effects, boolean isWeapon, int magnitude) {
if (effects == null) return;
- ActorTraits traits = actor.traits;
+ CombatTraits actorCombatTraits = actor.combatTraits;
actor.health.addToMax(effects.maxHPBoost * magnitude);
actor.ap.addToMax(effects.maxAPBoost * magnitude);
- traits.moveCost += (effects.moveCostPenalty * magnitude);
+ actor.actorTraits.moveCost += (effects.moveCostPenalty * magnitude);
CombatTraits combatTraits = effects.combatProficiency;
if (combatTraits != null) {
if (!isWeapon) { // For weapons, these stats are modified elsewhere (since they are not cumulative)
- traits.attackCost += (combatTraits.attackCost * magnitude);
- traits.criticalMultiplier += (combatTraits.criticalMultiplier * magnitude);
+ actorCombatTraits.attackCost += (combatTraits.attackCost * magnitude);
+ actorCombatTraits.criticalMultiplier += (combatTraits.criticalMultiplier * magnitude);
}
- traits.attackChance += (combatTraits.attackChance * magnitude);
- traits.criticalChance += (combatTraits.criticalChance * magnitude);
- traits.damagePotential.add(combatTraits.damagePotential.current * magnitude, true);
- traits.damagePotential.max += (combatTraits.damagePotential.max * magnitude);
- traits.blockChance += (combatTraits.blockChance * magnitude);
- traits.damageResistance += (combatTraits.damageResistance * magnitude);
+ actorCombatTraits.attackChance += (combatTraits.attackChance * magnitude);
+ actorCombatTraits.criticalChance += (combatTraits.criticalChance * magnitude);
+ actorCombatTraits.damagePotential.add(combatTraits.damagePotential.current * magnitude, true);
+ actorCombatTraits.damagePotential.max += (combatTraits.damagePotential.max * magnitude);
+ actorCombatTraits.blockChance += (combatTraits.blockChance * magnitude);
+ actorCombatTraits.damageResistance += (combatTraits.damageResistance * magnitude);
}
- if (traits.attackCost <= 0) traits.attackCost = 1;
- if (traits.attackChance < 0) traits.attackChance = 0;
- if (traits.moveCost <= 0) traits.moveCost = 1;
+ if (actorCombatTraits.attackCost <= 0) actorCombatTraits.attackCost = 1;
+ if (actorCombatTraits.attackChance < 0) actorCombatTraits.attackChance = 0;
+ if (actor.actorTraits.moveCost <= 0) actor.actorTraits.moveCost = 1;
+ if (actorCombatTraits.damagePotential.max < 0) actorCombatTraits.damagePotential.set(0, 0);
}
public static void recalculatePlayerCombatTraits(Player player) { recalculateActorCombatTraits(player); }
import com.gpl.rpg.AndorsTrail.context.ViewContext;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
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;
-import com.gpl.rpg.AndorsTrail.model.actor.ActorTraits;
import com.gpl.rpg.AndorsTrail.model.actor.Monster;
import com.gpl.rpg.AndorsTrail.model.actor.Player;
import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnUse;
private void executeAttack() {
context.effectController.waitForCurrentEffect();
- if (!useAPs(model.player.traits.attackCost)) return;
+ if (!useAPs(model.player.combatTraits.attackCost)) return;
Monster target = model.uiSelections.selectedMonster;
AttackResult attack = playerAttacks(model, target);
if (attack.isHit) {
String msg;
- final String monsterName = target.traits.name;
+ final String monsterName = target.actorTraits.name;
if (attack.isCriticalHit) {
msg = r.getString(R.string.combat_result_herohitcritical, monsterName, attack.damage);
} else {
private void maybeAutoEndTurn() {
if (model.player.ap.current < model.player.useItemCost
- && model.player.ap.current < model.player.traits.attackCost
- && model.player.ap.current < model.player.traits.moveCost) {
+ && model.player.ap.current < model.player.combatTraits.attackCost
+ && model.player.ap.current < model.player.actorTraits.moveCost) {
endPlayerTurn();
}
}
private void executeCombatMove(final Coord dest) {
if (model.uiSelections.selectedMonster != null) return;
if (dest == null) return;
- if (!useAPs(model.player.traits.moveCost)) return;
+ if (!useAPs(model.player.actorTraits.moveCost)) 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)) {
private Monster determineNextMonster(Monster previousMonster) {
if (previousMonster != null) {
- if (previousMonster.useAPs(previousMonster.traits.attackCost)) return previousMonster;
+ if (previousMonster.useAPs(previousMonster.combatTraits.attackCost)) return previousMonster;
}
for (MonsterSpawnArea a : model.currentMap.spawnAreas) {
if (!m.isAgressive()) continue;
if (m.rectPosition.isAdjacentTo(model.player.position)) {
- if (m.useAPs(m.traits.attackCost)) return m;
+ if (m.useAPs(m.combatTraits.attackCost)) return m;
}
}
}
context.mainActivity.combatview.updateTurnInfo(currentActiveMonster);
Resources r = context.mainActivity.getResources();
AttackResult attack = monsterAttacks(model, currentActiveMonster);
- String monsterName = currentActiveMonster.traits.name;
+ String monsterName = currentActiveMonster.actorTraits.name;
if (attack.isHit) {
startAttackEffect(attack, model.player.position);
if (attack.isCriticalHit) {
context.mainActivity.updateStatus();
}
- private static float getAverageDamagePerHit(ActorTraits attacker, ActorTraits target) {
- float result = (float) (getAttackHitChance(attacker, target)) * attacker.damagePotential.average() / 100;
- result += (float) attacker.criticalChance * result * attacker.criticalMultiplier / 100;
- result -= target.damageResistance;
+ private static float getAverageDamagePerHit(Actor attacker, Actor target) {
+ float result = (float) (getAttackHitChance(attacker.combatTraits, target.combatTraits)) * attacker.combatTraits.damagePotential.average() / 100;
+ result += (float) attacker.combatTraits.criticalChance * result * attacker.combatTraits.criticalMultiplier / 100;
+ result -= target.combatTraits.damageResistance;
return result;
}
- private static float getAverageDamagePerTurn(ActorTraits attacker, ActorTraits target) {
+ private static float getAverageDamagePerTurn(Actor attacker, Actor target) {
return getAverageDamagePerHit(attacker, target) * attacker.getAttacksPerTurn();
}
- private static int getTurnsToKillTarget(ActorTraits attacker, ActorTraits target) {
- if (attacker.hasCriticalAttacks()) {
- if (attacker.damagePotential.max * attacker.criticalMultiplier <= target.damageResistance) return 999;
+ private static int getTurnsToKillTarget(Actor attacker, Actor target) {
+ if (attacker.combatTraits.hasCriticalAttacks()) {
+ if (attacker.combatTraits.damagePotential.max * attacker.combatTraits.criticalMultiplier <= target.combatTraits.damageResistance) return 999;
} else {
- if (attacker.damagePotential.max <= target.damageResistance) return 999;
+ if (attacker.combatTraits.damagePotential.max <= target.combatTraits.damageResistance) return 999;
}
float averageDamagePerTurn = getAverageDamagePerTurn(attacker, target);
if (averageDamagePerTurn <= 0) return 100;
- return (int) Math.ceil(target.maxHP / averageDamagePerTurn);
+ return (int) Math.ceil(target.actorTraits.maxHP / averageDamagePerTurn);
}
public static int getMonsterDifficulty(WorldContext world, Monster monster) {
// returns [0..100) . 100 == easy.
- int turnsToKillMonster = getTurnsToKillTarget(world.model.player.traits, monster.traits);
+ int turnsToKillMonster = getTurnsToKillTarget(world.model.player, monster);
if (turnsToKillMonster >= 999) return 0;
- int turnsToKillPlayer = getTurnsToKillTarget(monster.traits, world.model.player.traits);
+ int turnsToKillPlayer = getTurnsToKillTarget(monster, world.model.player);
int result = 50 + (turnsToKillPlayer - turnsToKillMonster) * 2;
if (result <= 1) return 1;
else if (result > 100) return 100;
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 ActorTraits attacker, final ActorTraits target) {
+ private static int getAttackHitChance(final CombatTraits attacker, final CombatTraits target) {
final int c = attacker.attackChance - target.blockChance;
// (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.traits, target.traits);
+ int hitChance = getAttackHitChance(attacker.combatTraits, target.combatTraits);
if (!Constants.roll100(hitChance)) return AttackResult.MISS;
- int damage = Constants.rollValue(attacker.traits.damagePotential);
+ int damage = Constants.rollValue(attacker.combatTraits.damagePotential);
boolean isCriticalHit = false;
- if (attacker.traits.hasCriticalAttacks()) {
- isCriticalHit = Constants.roll100(attacker.traits.criticalChance);
+ if (attacker.combatTraits.hasCriticalAttacks()) {
+ isCriticalHit = Constants.roll100(attacker.combatTraits.criticalChance);
if (isCriticalHit) {
- damage *= attacker.traits.criticalMultiplier;
+ damage *= attacker.combatTraits.criticalMultiplier;
}
}
- damage -= target.traits.damageResistance;
+ damage -= target.combatTraits.damageResistance;
if (damage < 0) damage = 0;
target.health.subtract(damage, false);
}
private void applyAttackHitStatusEffects(Actor attacker, Actor target) {
- if (attacker.traits.onHitEffects == null) return;
+ if (attacker.actorTraits.onHitEffects == null) return;
- for (ItemTraits_OnUse e : attacker.traits.onHitEffects) {
+ for (ItemTraits_OnUse e : attacker.actorTraits.onHitEffects) {
context.actorStatsController.applyUseEffect(attacker, target, e);
}
}
if (weapon.effects_equip != null) {
CombatTraits weaponTraits = weapon.effects_equip.combatProficiency;
if (weaponTraits != null) {
- player.traits.attackCost = weaponTraits.attackCost;
- player.traits.criticalMultiplier = weaponTraits.criticalMultiplier;
+ player.combatTraits.attackCost = weaponTraits.attackCost;
+ player.combatTraits.criticalMultiplier = weaponTraits.criticalMultiplier;
}
}
}
if (effects != null) {
ItemTraits_OnUse[] effects_ = new ItemTraits_OnUse[effects.size()];
effects_ = effects.toArray(effects_);
- player.traits.onHitEffects = effects_;
+ player.actorTraits.onHitEffects = effects_;
} else {
- player.traits.onHitEffects = null;
+ player.actorTraits.onHitEffects = null;
}
}
for (MonsterSpawnArea a : map.spawnAreas) {
for (Monster m : a.monsters) {
if (!world.model.currentMap.isWalkable(m.rectPosition)) {
- Coord p = map.getRandomFreePosition(a.area, m.traits.tileSize, model.player.position);
+ Coord p = map.getRandomFreePosition(a.area, m.actorTraits.tileSize, model.player.position);
if (p == null) continue;
m.position.set(p);
}
import android.widget.ImageView;
import com.gpl.rpg.AndorsTrail.R;
+import com.gpl.rpg.AndorsTrail.model.CombatTraits;
import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionEffect;
import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionType;
import com.gpl.rpg.AndorsTrail.model.ability.SkillCollection;
public final class SkillController {
public static void applySkillEffects(Player player) {
- player.traits.attackChance += SkillCollection.PER_SKILLPOINT_INCREASE_WEAPON_CHANCE * player.getSkillLevel(SkillCollection.SKILL_WEAPON_CHANCE);
- player.traits.damagePotential.addToMax(SkillCollection.PER_SKILLPOINT_INCREASE_WEAPON_DAMAGE_MAX * player.getSkillLevel(SkillCollection.SKILL_WEAPON_DMG));
- player.traits.damagePotential.add(SkillCollection.PER_SKILLPOINT_INCREASE_WEAPON_DAMAGE_MIN * player.getSkillLevel(SkillCollection.SKILL_WEAPON_DMG), false);
- player.traits.blockChance += SkillCollection.PER_SKILLPOINT_INCREASE_DODGE * player.getSkillLevel(SkillCollection.SKILL_DODGE);
- player.traits.damageResistance += SkillCollection.PER_SKILLPOINT_INCREASE_BARKSKIN * player.getSkillLevel(SkillCollection.SKILL_BARKSKIN);
- if (player.traits.hasCriticalChanceEffect()) {
- player.traits.criticalChance += player.traits.criticalChance * SkillCollection.PER_SKILLPOINT_INCREASE_MORE_CRITICALS_PERCENT * player.getSkillLevel(SkillCollection.SKILL_MORE_CRITICALS) / 100;
+ 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.hasCriticalChanceEffect()) {
+ combatTraits.criticalChance += combatTraits.criticalChance * SkillCollection.PER_SKILLPOINT_INCREASE_MORE_CRITICALS_PERCENT * player.getSkillLevel(SkillCollection.SKILL_MORE_CRITICALS) / 100;
}
- if (player.traits.hasCriticalMultiplierEffect()) {
- player.traits.criticalMultiplier += player.traits.criticalMultiplier * SkillCollection.PER_SKILLPOINT_INCREASE_BETTER_CRITICALS_PERCENT * player.getSkillLevel(SkillCollection.SKILL_BETTER_CRITICALS) / 100;
+ if (combatTraits.hasCriticalMultiplierEffect()) {
+ combatTraits.criticalMultiplier += combatTraits.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);
this.damageResistance = copy.damageResistance;
}
+ public boolean equals(CombatTraits other) {
+ return
+ this.attackCost == other.attackCost
+ && this.attackChance == other.attackChance
+ && this.criticalChance == other.criticalChance
+ && this.criticalMultiplier == other.criticalMultiplier
+ && this.damagePotential.equals(other.damagePotential)
+ && this.blockChance == other.blockChance
+ && this.damageResistance == other.damageResistance;
+ }
+
public boolean hasAttackChanceEffect() { return attackChance != 0; }
public boolean hasAttackDamageEffect() { return damagePotential.max != 0; }
public boolean hasBlockEffect() { return blockChance != 0; }
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.traits.baseCombatTraits.getCombatStats(skillOrStatID);
- case REQUIREMENT_TYPE_ACTOR_STAT: return player.traits.getActorStats(skillOrStatID);
+ case REQUIREMENT_TYPE_COMBAT_STAT: return player.actorTraits.baseCombatTraits.getCombatStats(skillOrStatID);
+ case REQUIREMENT_TYPE_ACTOR_STAT: return player.actorTraits.getActorStats(skillOrStatID);
default: return 0;
}
}
import java.util.ArrayList;
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.util.Coord;
import com.gpl.rpg.AndorsTrail.util.CoordRect;
import com.gpl.rpg.AndorsTrail.util.Range;
public class Actor {
- public final ActorTraits traits;
+ public final ActorTraits actorTraits;
+ public final CombatTraits combatTraits;
public final Range ap;
public final Range health;
public final Coord position;
public final ArrayList<ActorCondition> conditions = new ArrayList<ActorCondition>();
public final boolean isPlayer;
- public Actor(ActorTraits traits, boolean isPlayer) {
- this.traits = traits;
- this.ap = new Range(traits.maxAP, traits.maxAP);
- this.health = new Range(traits.maxHP, traits.maxHP);
+ public Actor(ActorTraits actorTraits, boolean isPlayer) {
+ this.combatTraits = new CombatTraits(actorTraits.baseCombatTraits);
+ this.actorTraits = actorTraits;
+ this.ap = new Range(actorTraits.maxAP, actorTraits.maxAP);
+ this.health = new Range(actorTraits.maxHP, actorTraits.maxHP);
this.position = new Coord();
- this.rectPosition = new CoordRect(position, traits.tileSize);
+ this.rectPosition = new CoordRect(position, actorTraits.tileSize);
this.isPlayer = isPlayer;
}
+ public int getAttacksPerTurn() { return combatTraits.getAttacksPerTurn(actorTraits.maxAP); }
+
public boolean isDead() {
return health.current <= 0;
}
}
public void resetStatsToBaseTraits() {
- traits.set(traits.baseCombatTraits);
- health.set(traits.maxHP, health.current);
- ap.set(traits.maxAP, ap.current);
- traits.moveCost = traits.baseMoveCost;
+ combatTraits.set(actorTraits.baseCombatTraits);
+ health.set(actorTraits.maxHP, health.current);
+ ap.set(actorTraits.maxAP, ap.current);
+ actorTraits.moveCost = actorTraits.baseMoveCost;
}
// ====== PARCELABLE ===================================================================
- public Actor(DataInputStream src, WorldContext world, int fileversion, boolean isPlayer) throws IOException {
+ public Actor(DataInputStream src, WorldContext world, int fileversion, boolean isPlayer, ActorTraits actorTraits) throws IOException {
this.isPlayer = isPlayer;
- this.traits = new ActorTraits(src, world, fileversion);
+
+ CombatTraits combatTraits = null;
+ boolean readCombatTraits = true;
+ if (fileversion >= 25) readCombatTraits = src.readBoolean();
+ if (readCombatTraits) combatTraits = new CombatTraits(src, fileversion);
+
+ this.actorTraits = isPlayer ? new ActorTraits(src, world, fileversion) : actorTraits;
+ if (!readCombatTraits) combatTraits = new CombatTraits(this.actorTraits.baseCombatTraits);
+ this.combatTraits = combatTraits;
+
this.ap = new Range(src, fileversion);
this.health = new Range(src, fileversion);
this.position = new Coord(src, fileversion);
- this.rectPosition = new CoordRect(position, traits.tileSize);
+ this.rectPosition = new CoordRect(position, this.actorTraits.tileSize);
if (fileversion <= 16) return;
final int n = src.readInt();
for(int i = 0; i < n ; ++i) {
}
public void writeToParcel(DataOutputStream dest, int flags) throws IOException {
- traits.writeToParcel(dest, flags);
+ if (this.combatTraits.equals(actorTraits.baseCombatTraits)) {
+ dest.writeBoolean(false);
+ } else {
+ dest.writeBoolean(true);
+ combatTraits.writeToParcel(dest, flags);
+ }
+ if (isPlayer) actorTraits.writeToParcel(dest, flags);
ap.writeToParcel(dest, flags);
health.writeToParcel(dest, flags);
position.writeToParcel(dest, flags);
import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnUse;
import com.gpl.rpg.AndorsTrail.util.Size;
-public class ActorTraits extends CombatTraits {
+public class ActorTraits {
public static final int STAT_ACTOR_MAX_HP = 0;
public static final int STAT_ACTOR_MAX_AP = 1;
public static final int STAT_ACTOR_MOVECOST = 2;
, int standardMoveCost
, ItemTraits_OnUse[] onHitEffects
) {
- super(baseCombatTraits);
this.iconID = iconID;
this.tileSize = tileSize;
this.baseCombatTraits = baseCombatTraits;
this.baseMoveCost = standardMoveCost;
this.onHitEffects = onHitEffects;
}
- public int getAttacksPerTurn() { return getAttacksPerTurn(maxAP); }
public int getMovesPerTurn() {
return (int) Math.floor(maxAP / moveCost);
}
// ====== PARCELABLE ===================================================================
public ActorTraits(DataInputStream src, WorldContext world, int fileversion) throws IOException {
- super(src, fileversion);
this.iconID = src.readInt();
this.tileSize = new Size(src, fileversion);
this.maxAP = src.readInt();
}
public void writeToParcel(DataOutputStream dest, int flags) throws IOException {
- super.writeToParcel(dest, flags);
dest.writeInt(iconID);
tileSize.writeToParcel(dest, flags);
dest.writeInt(maxAP);
this.monsterTypeID = monsterType.id;
this.position.set(position);
this.millisecondsPerMove = Constants.MONSTER_MOVEMENT_TURN_DURATION_MS / monsterType.getMovesPerTurn();
- this.nextPosition = new CoordRect(new Coord(), traits.tileSize);
+ this.nextPosition = new CoordRect(new Coord(), actorTraits.tileSize);
this.phraseID = monsterType.phraseID;
this.exp = monsterType.exp;
this.dropList = monsterType.dropList;
}
-
+
public void createLoot(Loot container, Player player) {
int exp = this.exp;
exp += exp * player.getSkillLevel(SkillCollection.SKILL_MORE_EXP) * SkillCollection.PER_SKILLPOINT_INCREASE_MORE_EXP_PERCENT / 100;
monsterTypeId = monsterTypeId.replace(' ', '_').replace("\\'", "").toLowerCase();
}
MonsterType monsterType = world.monsterTypes.getMonsterType(monsterTypeId);
+
+ if (fileversion < 25) return readFromParcel_pre_v0610(src, 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);
+ this.monsterTypeID = monsterType.id;
+ this.millisecondsPerMove = Constants.MONSTER_MOVEMENT_TURN_DURATION_MS / monsterType.getMovesPerTurn();
+ this.nextPosition = new CoordRect(new Coord(), actorTraits.tileSize);
+ this.phraseID = monsterType.phraseID;
+ this.exp = monsterType.exp;
+ this.dropList = monsterType.dropList;
+ this.forceAggressive = src.readBoolean();
+ }
+
+ private static Monster readFromParcel_pre_v0610(DataInputStream src, int fileversion, MonsterType monsterType) throws IOException {
Coord position = new Coord(src, fileversion);
Monster m = new Monster(monsterType, position);
m.ap.current = src.readInt();
}
return m;
}
-
+
public void writeToParcel(DataOutputStream dest, int flags) throws IOException {
dest.writeUTF(monsterTypeID);
- position.writeToParcel(dest, flags);
- dest.writeInt(ap.current);
- dest.writeInt(health.current);
+ super.writeToParcel(dest, flags);
dest.writeBoolean(forceAggressive);
}
}
public final class MonsterTypeCollection {
private final HashMap<String, MonsterType> monsterTypesById = new HashMap<String, MonsterType>();
+ public final HashMap<String, MonsterType> DEBUG_monsterTypesById = monsterTypesById;
public MonsterType getMonsterType(String id) {
if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) {
combat.blockChance = 0;
combat.damageResistance = 0;
- traits.baseCombatTraits.set(combat);
+ actorTraits.baseCombatTraits.set(combat);
- traits.maxAP = 10;
- traits.maxHP = 25;
+ actorTraits.maxAP = 10;
+ actorTraits.maxHP = 25;
- traits.name = name;
- traits.moveCost = DEFAULT_PLAYER_MOVECOST;
+ actorTraits.name = name;
+ actorTraits.moveCost = DEFAULT_PLAYER_MOVECOST;
useItemCost = 5;
reequipCost = 5;
// ====== PARCELABLE ===================================================================
public Player(DataInputStream src, WorldContext world, int fileversion) throws IOException {
- super(src, world, fileversion, true);
+ super(src, world, fileversion, true, null);
this.lastPosition = new Coord(src, fileversion);
this.nextPosition = new Coord(src, fileversion);
this.level = src.readInt();
useItemCost = 5;
health.max += 5;
health.current += 5;
- traits.maxHP += 5;
+ actorTraits.maxHP += 5;
}
if (fileversion <= 13) return;
this.current = current;
}
+ public boolean equals(Range r) {
+ return max == r.max && current == r.current;
+ }
+
public void set(Range r) {
this.max = r.max;
this.current = r.current;
--- /dev/null
+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;
+import com.gpl.rpg.AndorsTrail.context.WorldContext;
+import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition;
+import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionType;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.text.SpannableString;
+import android.text.style.UnderlineSpan;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+public final class ActorConditionList extends LinearLayout {
+
+ private final WorldContext world;
+
+ public ActorConditionList(Context context, AttributeSet attr) {
+ super(context, attr);
+ setFocusable(false);
+ setOrientation(LinearLayout.VERTICAL);
+ AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivityContext(context);
+ this.world = app.world;
+ }
+
+ public void update(Collection<ActorCondition> conditions) {
+ removeAllViews();
+ if (conditions == null) return;
+
+ final Context context = getContext();
+ final Resources res = getResources();
+ LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
+
+ for (ActorCondition c : conditions) {
+ View v = View.inflate(context, R.layout.inventoryitemview, null);
+ ((ImageView) v.findViewById(R.id.inv_image)).setImageBitmap(world.tileStore.getBitmap(c.conditionType.iconID));
+ SpannableString content = new SpannableString(describeEffect(res, c));
+ content.setSpan(new UnderlineSpan(), 0, content.length(), 0);
+ ((TextView) v.findViewById(R.id.inv_text)).setText(content);
+ final ActorConditionType conditionType = c.conditionType;
+ v.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View arg0) {
+ Dialogs.showActorConditionInfo(context, conditionType);
+ }
+ });
+ this.addView(v, layoutParams);
+ }
+ }
+
+ private static String describeEffect(Resources res, ActorCondition c) {
+ return ActorConditionEffectList.describeEffect(res, c.conditionType, c.magnitude, c.duration);
+ }
+}
import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.controller.CombatController;
import com.gpl.rpg.AndorsTrail.model.actor.Monster;
+import com.gpl.rpg.AndorsTrail.model.actor.Player;
import com.gpl.rpg.AndorsTrail.util.Coord;
import com.gpl.rpg.AndorsTrail.util.Range;
private final WorldContext world;
private final ViewContext view;
private final Resources res;
+ private final Player player;
private Monster currentMonster;
public CombatView(final Context context, AttributeSet attr) {
super(context, attr);
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivityContext(context);
this.world = app.world;
+ this.player = world.model.player;
this.view = app.currentView.get();
this.res = getResources();
if (currentActiveMonster != null) {
actionBar.setVisibility(View.INVISIBLE);
monsterActionText.setVisibility(View.VISIBLE);
- monsterActionText.setText(res.getString(R.string.combat_monsteraction, currentActiveMonster.traits.name));
+ monsterActionText.setText(res.getString(R.string.combat_monsteraction, currentActiveMonster.actorTraits.name));
} else {
actionBar.setVisibility(View.VISIBLE);
monsterActionText.setVisibility(View.GONE);
monsterBar.setVisibility(View.INVISIBLE);
currentMonster = null;
if (selectedMonster != null) {
- attackMoveButton.setText(res.getString(R.string.combat_attack, world.model.player.traits.attackCost));
+ attackMoveButton.setText(res.getString(R.string.combat_attack, player.combatTraits.attackCost));
monsterBar.setVisibility(View.VISIBLE);
- monsterInfo.setImageBitmap(world.tileStore.getBitmap(selectedMonster.traits.iconID));
+ monsterInfo.setImageBitmap(world.tileStore.getBitmap(selectedMonster.actorTraits.iconID));
updateMonsterHealth(selectedMonster.health);
currentMonster = selectedMonster;
} else if (selectedMovePosition != null) {
- attackMoveButton.setText(res.getString(R.string.combat_move, world.model.player.traits.moveCost));
+ attackMoveButton.setText(res.getString(R.string.combat_move, player.actorTraits.moveCost));
} else {
- attackMoveButton.setText(res.getString(R.string.combat_attack, world.model.player.traits.attackCost));
+ attackMoveButton.setText(res.getString(R.string.combat_attack, player.combatTraits.attackCost));
}
}
public void updateStatus() {
- updatePlayerAP(world.model.player.ap);
+ updatePlayerAP(player.ap);
if (world.model.uiSelections.selectedMonster != null) {
updateMonsterHealth(world.model.uiSelections.selectedMonster.health);
}
}
}
- drawFromMapPosition(canvas, area, model.player.position, model.player.traits.iconID);
+ drawFromMapPosition(canvas, area, model.player.position, model.player.actorTraits.iconID);
for (MonsterSpawnArea a : currentMap.spawnAreas) {
for (Monster m : a.monsters) {
- drawFromMapPosition(canvas, area, m.rectPosition, m.traits.iconID);
+ drawFromMapPosition(canvas, area, m.rectPosition, m.actorTraits.iconID);
}
}
expBar.init(R.drawable.ui_progress_exp, R.string.status_exp);
levelupDrawable = new LayerDrawable(new Drawable[] {
- new BitmapDrawable(world.tileStore.getBitmap(player.traits.iconID))
+ new BitmapDrawable(world.tileStore.getBitmap(player.actorTraits.iconID))
,new BitmapDrawable(world.tileStore.getBitmap(TileStore.iconID_moveselect))
});
if (canLevelUp) {
heroImage.setImageDrawable(levelupDrawable);
} else {
- heroImage.setImageBitmap(world.tileStore.getBitmap(player.traits.iconID));
+ heroImage.setImageBitmap(world.tileStore.getBitmap(player.actorTraits.iconID));
}
}