From 49eb55cbf0f544a364135f9cf5d1530c6d63b98a Mon Sep 17 00:00:00 2001 From: "oskar.wiksten@gmail.com" Date: Wed, 12 Oct 2011 22:04:46 +0000 Subject: [PATCH] Structural refactoring: moved CombatTraits from being a superclass of ActorTraits into being a property of Actor (for issue 251 & issue 253). Save active monster conditions in savegame file (issue 253). Save individual monster combat stats in savegame file (issue 251). Display active monster conditions on monster info dialog. (issue 252). Renamed "unequipped stats" to "Base combat statistics (without equipment and skills)". Bumped version number. git-svn-id: https://andors-trail.googlecode.com/svn/trunk@177 08aca716-68be-ccc6-4d58-36f5abd142ac --- AndorsTrail/AndroidManifest.xml | 4 +- AndorsTrail/res/layout/heroinfo_stats.xml | 4 +- AndorsTrail/res/layout/monsterinfo.xml | 14 ++++ AndorsTrail/res/values/strings.xml | 6 +- .../AndorsTrail/AndorsTrailApplication.java | 4 +- .../com/gpl/rpg/AndorsTrail/Savegames.java | 8 +- .../activity/ConversationActivity.java | 4 +- .../AndorsTrail/activity/DebugInterface.java | 23 ++++-- .../activity/HeroinfoActivity_Inventory.java | 4 +- .../activity/HeroinfoActivity_Stats.java | 46 +++-------- .../AndorsTrail/activity/LevelUpActivity.java | 14 ++-- .../activity/LoadSaveActivity.java | 4 +- .../activity/MonsterEncounterActivity.java | 4 +- .../activity/MonsterInfoActivity.java | 79 ++++++++++++++----- .../controller/ActorStatsController.java | 28 +++---- .../controller/CombatController.java | 60 +++++++------- .../controller/ItemController.java | 8 +- .../controller/MovementController.java | 2 +- .../controller/SkillController.java | 20 ++--- .../rpg/AndorsTrail/model/CombatTraits.java | 11 +++ .../AndorsTrail/model/ability/SkillInfo.java | 4 +- .../rpg/AndorsTrail/model/actor/Actor.java | 48 +++++++---- .../AndorsTrail/model/actor/ActorTraits.java | 6 +- .../rpg/AndorsTrail/model/actor/Monster.java | 28 +++++-- .../model/actor/MonsterTypeCollection.java | 1 + .../rpg/AndorsTrail/model/actor/Player.java | 14 ++-- .../com/gpl/rpg/AndorsTrail/util/Range.java | 4 + .../AndorsTrail/view/ActorConditionList.java | 62 +++++++++++++++ .../gpl/rpg/AndorsTrail/view/CombatView.java | 15 ++-- .../gpl/rpg/AndorsTrail/view/MainView.java | 4 +- .../gpl/rpg/AndorsTrail/view/StatusView.java | 4 +- 31 files changed, 343 insertions(+), 194 deletions(-) create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/ActorConditionList.java diff --git a/AndorsTrail/AndroidManifest.xml b/AndorsTrail/AndroidManifest.xml index a26ec43..15040ff 100644 --- a/AndorsTrail/AndroidManifest.xml +++ b/AndorsTrail/AndroidManifest.xml @@ -3,8 +3,8 @@ - + + + + diff --git a/AndorsTrail/res/values/strings.xml b/AndorsTrail/res/values/strings.xml index 1cdb08d..ba44914 100644 --- a/AndorsTrail/res/values/strings.xml +++ b/AndorsTrail/res/values/strings.xml @@ -113,8 +113,8 @@ Critical hit: Defense: Move cost (AP): - Unequipped combat statistics (base) - Equipped combat statistics (current) + Base combat statistics (without equipment and skills) + Combat statistics (current) Attack cost (AP): Attack chance: @@ -444,7 +444,7 @@ Current level: %1$d / %2$d To level up this skill, you need at least level %1$d of the %2$s skill. To level up this skill, you need at least experience level %1$d. - To level up this skill, you need at least %1$d %2$s (unequipped stats). + To level up this skill, you need at least %1$d %2$s (base stats). You may select one skill to increase. You may select %1$d skills to increase. This level also gives you a new skill point to spend! diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java index dc468ff..41e8dc9 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java @@ -19,8 +19,8 @@ public final class AndorsTrailApplication extends Application { public static final boolean DEVELOPMENT_DEBUGBUTTONS = false; public static final boolean DEVELOPMENT_VALIDATEDATA = false; public static final boolean DEVELOPMENT_DEBUGMESSAGES = false; - public static final int CURRENT_VERSION = 24; - public static final String CURRENT_VERSION_DISPLAY = "0.6.10a3"; + public static final int CURRENT_VERSION = 25; + public static final String CURRENT_VERSION_DISPLAY = "0.6.10a4"; public final WorldContext world = new WorldContext(); public final WorldSetup setup = new WorldSetup(world, this); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/Savegames.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/Savegames.java index b4f8842..8c2ea49 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/Savegames.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/Savegames.java @@ -94,15 +94,15 @@ public final class Savegames { 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; @@ -176,7 +176,7 @@ public final class Savegames { 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(); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ConversationActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ConversationActivity.java index ed6232a..58faf3e 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ConversationActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ConversationActivity.java @@ -242,8 +242,8 @@ public final class ConversationActivity extends Activity { 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; } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/DebugInterface.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/DebugInterface.java index 0a5c25f..f5da0ab 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/DebugInterface.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/DebugInterface.java @@ -33,9 +33,9 @@ public final class DebugInterface { 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); } @@ -48,7 +48,7 @@ public final class DebugInterface { 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")); @@ -62,11 +62,12 @@ public final class DebugInterface { 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) { @@ -116,14 +117,22 @@ public final class DebugInterface { ,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) { 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 d056fd4..56f114c 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Inventory.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Inventory.java @@ -143,8 +143,8 @@ public final class HeroinfoActivity_Inventory extends Activity { 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() { 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 8bdd9af..0ed6112 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Stats.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity_Stats.java @@ -6,30 +6,23 @@ import com.gpl.rpg.AndorsTrail.Dialogs; 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 { @@ -43,7 +36,7 @@ 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; @@ -60,15 +53,15 @@ public final class HeroinfoActivity_Stats extends Activity { 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); @@ -118,11 +111,11 @@ public final class HeroinfoActivity_Stats extends Activity { 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 effects_hit = new ArrayList(); ArrayList effects_kill = new ArrayList(); for (int i = 0; i < Inventory.NUM_WORN_SLOTS; ++i) { @@ -134,7 +127,7 @@ public final class HeroinfoActivity_Stats extends Activity { 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() { @@ -144,28 +137,7 @@ public final class HeroinfoActivity_Stats extends Activity { } 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); - } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/LevelUpActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/LevelUpActivity.java index 2b66db6..bc3c508 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/LevelUpActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/LevelUpActivity.java @@ -36,7 +36,7 @@ public final class LevelUpActivity extends Activity { 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)); @@ -98,21 +98,21 @@ public final class LevelUpActivity extends Activity { 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()) { @@ -122,7 +122,7 @@ public final class LevelUpActivity extends Activity { 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(); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/LoadSaveActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/LoadSaveActivity.java index 12a042f..2f8114f 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/LoadSaveActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/LoadSaveActivity.java @@ -103,7 +103,7 @@ public final class LoadSaveActivity extends Activity implements OnClickListener if (isLoading) return false; if (slot == SLOT_NUMBER_CREATE_NEW_SLOT) return false; // if we're creating a new slot - final String currentPlayerName = model.player.traits.name; + final String currentPlayerName = model.player.actorTraits.name; final FileHeader header = Savegames.quickload(this, slot); if (header == null) return false; @@ -117,7 +117,7 @@ public final class LoadSaveActivity extends Activity implements OnClickListener public void onClick(View view) { final int slot = (Integer) view.getTag(); if (requiresConfirmation(slot)) { - final String playerName = model.player.traits.name; + final String playerName = model.player.actorTraits.name; new AlertDialog.Builder(this) .setIcon(android.R.drawable.ic_dialog_alert) diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MonsterEncounterActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MonsterEncounterActivity.java index 4bad549..3dce23d 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MonsterEncounterActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MonsterEncounterActivity.java @@ -37,13 +37,13 @@ public final class MonsterEncounterActivity extends Activity { 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() { diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MonsterInfoActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MonsterInfoActivity.java index e67c987..1d3a2d9 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MonsterInfoActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MonsterInfoActivity.java @@ -8,6 +8,7 @@ import com.gpl.rpg.AndorsTrail.R; 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.view.ActorConditionList; import com.gpl.rpg.AndorsTrail.view.ItemEffectsView; import com.gpl.rpg.AndorsTrail.view.RangeBar; import com.gpl.rpg.AndorsTrail.view.TraitsInfoView; @@ -23,28 +24,29 @@ import android.widget.TextView; public final class MonsterInfoActivity extends Activity { + private ImageView monsterinfo_image; + private TextView monsterinfo_title; + private TextView monsterinfo_difficulty; + private TraitsInfoView monsterinfo_currenttraits; + private ItemEffectsView monsterinfo_onhiteffects; + private TextView monsterinfo_currentconditions_title; + private ActorConditionList monsterinfo_currentconditions; + private RangeBar hp; + private WorldContext world; + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); - final WorldContext world = app.world; + this.world = app.world; requestWindowFeature(Window.FEATURE_NO_TITLE); - final Monster monster = Dialogs.getMonsterFromIntent(getIntent(), world); - if (monster == null) { - finish(); - return; - } - setContentView(R.layout.monsterinfo); - ImageView img = (ImageView) findViewById(R.id.monsterinfo_image); - img.setImageBitmap(world.tileStore.getBitmap(monster.traits.iconID)); - TextView tv = (TextView) findViewById(R.id.monsterinfo_title); - tv.setText(monster.traits.name); - tv = (TextView) findViewById(R.id.monsterinfo_difficulty); - tv.setText(getMonsterDifficultyResource(world, monster)); - + monsterinfo_image = (ImageView) findViewById(R.id.monsterinfo_image); + monsterinfo_title = (TextView) findViewById(R.id.monsterinfo_title); + monsterinfo_difficulty = (TextView) findViewById(R.id.monsterinfo_difficulty); + Button b = (Button) findViewById(R.id.monsterinfo_close); b.setOnClickListener(new OnClickListener() { @Override @@ -53,14 +55,42 @@ public final class MonsterInfoActivity extends Activity { } }); - ((TraitsInfoView) findViewById(R.id.monsterinfo_currenttraits)).update(monster.traits); - ((ItemEffectsView) findViewById(R.id.monsterinfo_onhiteffects)).update( + monsterinfo_currenttraits = (TraitsInfoView) findViewById(R.id.monsterinfo_currenttraits); + monsterinfo_onhiteffects = (ItemEffectsView) findViewById(R.id.monsterinfo_onhiteffects); + monsterinfo_currentconditions_title = (TextView) findViewById(R.id.monsterinfo_currentconditions_title); + monsterinfo_currentconditions = (ActorConditionList) findViewById(R.id.monsterinfo_currentconditions); + hp = (RangeBar) findViewById(R.id.monsterinfo_healthbar); + hp.init(R.drawable.ui_progress_health, R.string.status_hp); + } + + @Override + protected void onResume() { + super.onResume(); + + Monster monster = Dialogs.getMonsterFromIntent(getIntent(), world); + if (monster == null) { + finish(); + return; + } + + updateTitle(monster); + updateTraits(monster); + updateConditions(monster); + } + + private void updateTitle(Monster monster) { + monsterinfo_image.setImageBitmap(world.tileStore.getBitmap(monster.actorTraits.iconID)); + monsterinfo_title.setText(monster.actorTraits.name); + monsterinfo_difficulty.setText(getMonsterDifficultyResource(world, monster)); + } + + private void updateTraits(Monster monster) { + monsterinfo_currenttraits.update(monster.combatTraits); + monsterinfo_onhiteffects.update( null, null, - monster.traits.onHitEffects == null ? null : Arrays.asList(monster.traits.onHitEffects), + monster.actorTraits.onHitEffects == null ? null : Arrays.asList(monster.actorTraits.onHitEffects), null); - RangeBar hp = (RangeBar) findViewById(R.id.monsterinfo_healthbar); - hp.init(R.drawable.ui_progress_health, R.string.status_hp); hp.update(monster.health); } @@ -73,4 +103,15 @@ public final class MonsterInfoActivity extends Activity { else if (difficulty == 0) return R.string.monster_difficulty_impossible; else return R.string.monster_difficulty_veryhard; } + + private void updateConditions(Monster monster) { + if (monster.conditions.isEmpty()) { + monsterinfo_currentconditions_title.setVisibility(View.GONE); + monsterinfo_currentconditions.setVisibility(View.GONE); + } else { + monsterinfo_currentconditions_title.setVisibility(View.VISIBLE); + monsterinfo_currentconditions.setVisibility(View.VISIBLE); + monsterinfo_currentconditions.update(monster.conditions); + } + } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ActorStatsController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ActorStatsController.java index 1804ab8..442c3d9 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ActorStatsController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ActorStatsController.java @@ -9,7 +9,6 @@ import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionType; 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; @@ -88,29 +87,30 @@ public class ActorStatsController { 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); } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/CombatController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/CombatController.java index 0be0aa4..aa31f65 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/CombatController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/CombatController.java @@ -14,10 +14,10 @@ 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.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; @@ -172,7 +172,7 @@ public final class CombatController { 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); @@ -180,7 +180,7 @@ public final class CombatController { 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 { @@ -241,8 +241,8 @@ public final class CombatController { 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(); } } @@ -250,7 +250,7 @@ public final class CombatController { 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)) { @@ -299,7 +299,7 @@ public final class CombatController { 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) { @@ -307,7 +307,7 @@ public final class CombatController { 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; } } } @@ -327,7 +327,7 @@ public final class CombatController { 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) { @@ -368,31 +368,31 @@ public final class CombatController { 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; @@ -411,25 +411,25 @@ public final class CombatController { 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); @@ -439,9 +439,9 @@ public final class CombatController { } 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); } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ItemController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ItemController.java index 629c050..c11a9f8 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ItemController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ItemController.java @@ -110,8 +110,8 @@ public final class ItemController { 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; } } } @@ -140,9 +140,9 @@ public final class ItemController { 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; } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java index b313b77..8ac65ea 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java @@ -232,7 +232,7 @@ public final class MovementController implements TimedMessageTask.Callback { 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); } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/SkillController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/SkillController.java index c81f372..90024a7 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/SkillController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/SkillController.java @@ -4,6 +4,7 @@ import android.content.res.Resources; 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; @@ -14,16 +15,17 @@ import com.gpl.rpg.AndorsTrail.model.item.DropList.DropItem; 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); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/CombatTraits.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/CombatTraits.java index 510fc29..70661a1 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/CombatTraits.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/CombatTraits.java @@ -44,6 +44,17 @@ public class CombatTraits { 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; } 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 31491fa..884da8a 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/ability/SkillInfo.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/ability/SkillInfo.java @@ -78,8 +78,8 @@ 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.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; } } 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 0b5a67e..5993117 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Actor.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Actor.java @@ -6,13 +6,15 @@ import java.io.IOException; 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; @@ -20,15 +22,18 @@ public class Actor { public final ArrayList conditions = new ArrayList(); 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; } @@ -53,22 +58,31 @@ public class Actor { } 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) { @@ -77,7 +91,13 @@ public class Actor { } 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); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/ActorTraits.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/ActorTraits.java index 2a6303b..23e39ae 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/ActorTraits.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/ActorTraits.java @@ -9,7 +9,7 @@ import com.gpl.rpg.AndorsTrail.model.CombatTraits; 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; @@ -34,14 +34,12 @@ public class ActorTraits extends CombatTraits { , 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); } @@ -59,7 +57,6 @@ public class ActorTraits extends CombatTraits { // ====== 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(); @@ -75,7 +72,6 @@ public class ActorTraits extends CombatTraits { } public void writeToParcel(DataOutputStream dest, int flags) throws IOException { - super.writeToParcel(dest, flags); dest.writeInt(iconID); tileSize.writeToParcel(dest, flags); dest.writeInt(maxAP); 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 901f1df..5dcf648 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Monster.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Monster.java @@ -30,12 +30,12 @@ public final class Monster extends Actor { 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; @@ -57,6 +57,24 @@ public final class Monster extends Actor { 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(); @@ -66,12 +84,10 @@ public final class Monster extends Actor { } 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); } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/MonsterTypeCollection.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/MonsterTypeCollection.java index a8178d9..f359966 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/MonsterTypeCollection.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/MonsterTypeCollection.java @@ -15,6 +15,7 @@ import com.gpl.rpg.AndorsTrail.util.L; public final class MonsterTypeCollection { private final HashMap monsterTypesById = new HashMap(); + public final HashMap DEBUG_monsterTypesById = monsterTypesById; public MonsterType getMonsterType(String id) { if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) { 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 306ad62..f52967f 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Player.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Player.java @@ -56,13 +56,13 @@ public final class Player extends Actor { 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; @@ -163,7 +163,7 @@ public final class Player extends Actor { // ====== 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(); @@ -234,7 +234,7 @@ public final class Player extends Actor { useItemCost = 5; health.max += 5; health.current += 5; - traits.maxHP += 5; + actorTraits.maxHP += 5; } if (fileversion <= 13) return; diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/util/Range.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/util/Range.java index e8c2778..98c2089 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/util/Range.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/util/Range.java @@ -16,6 +16,10 @@ public final class Range { 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; diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/ActorConditionList.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/ActorConditionList.java new file mode 100644 index 0000000..affc575 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/ActorConditionList.java @@ -0,0 +1,62 @@ +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 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); + } +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/CombatView.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/CombatView.java index 2b52c78..6c6e111 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/CombatView.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/CombatView.java @@ -17,6 +17,7 @@ import com.gpl.rpg.AndorsTrail.context.ViewContext; 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; @@ -32,12 +33,14 @@ public final class CombatView extends RelativeLayout { 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(); @@ -93,7 +96,7 @@ public final class CombatView extends RelativeLayout { 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); @@ -111,20 +114,20 @@ public final class CombatView extends RelativeLayout { 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); } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/MainView.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/MainView.java index 6a0e472..2928ff0 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/MainView.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/MainView.java @@ -261,10 +261,10 @@ public final class MainView extends SurfaceView implements SurfaceHolder.Callbac } } - 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); } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/StatusView.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/StatusView.java index 771eb0f..7b8be72 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/StatusView.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/StatusView.java @@ -64,7 +64,7 @@ public final class StatusView extends RelativeLayout { 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)) }); @@ -95,7 +95,7 @@ public final class StatusView extends RelativeLayout { if (canLevelUp) { heroImage.setImageDrawable(levelupDrawable); } else { - heroImage.setImageBitmap(world.tileStore.getBitmap(player.traits.iconID)); + heroImage.setImageBitmap(world.tileStore.getBitmap(player.actorTraits.iconID)); } } -- 2.49.0