Added immunity to critical hits for ghosts, undead and demons.

Added a way to re-sort the player's inventory by moving items to top/bottom.
Auto-close the level-up dialog if the player cannot level up (issue 284)

git-svn-id: https://andors-trail.googlecode.com/svn/trunk@222 08aca716-68be-ccc6-4d58-36f5abd142ac
This commit is contained in:
oskar.wiksten
2012-03-12 21:16:57 +00:00
parent f498de517c
commit 2fe1e3f0b0
13 changed files with 89 additions and 20 deletions

View File

@@ -90,7 +90,7 @@
</LinearLayout>
<!-- Workaround http://code.google.com/p/andors-trail/issues/detail?id=242 -->
<ListView android:layout_width="match_parent" android:layout_height="wrap_content" />
<ListView android:layout_width="match_parent" android:layout_height="1dp" />
</LinearLayout>

View File

@@ -63,6 +63,12 @@
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_immune_criticals"
android:id="@+id/monsterinfo_immune_criticals"
/>
<com.gpl.rpg.AndorsTrail.view.ItemEffectsView
android:id="@+id/monsterinfo_onhiteffects"
android:layout_width="match_parent"

View File

@@ -13,4 +13,6 @@
<item android:id="@+id/inv_assign_slot3" android:title="@string/inventory_assign_slot3"></item>
</menu>
</item>
<item android:title="@string/inventory_movetop" android:id="@+id/inv_menu_movetop" />
<item android:title="@string/inventory_movebottom" android:id="@+id/inv_menu_movebottom" />
</menu>

View File

@@ -484,4 +484,8 @@
<string name="skill_shortdescription_shadow_bless">Resistance against all types of conditions</string>
<string name="skill_longdescription_shadow_bless">Lowers the chance of being afflicted with all types of conditions by %1$d %% for every skill level. This includes all types conditions caused by monster attacks such as Poison, Dazed or Fatigue.</string>
<string name="inventory_movetop">Move to top</string>
<string name="inventory_movebottom">Move to bottom</string>
<string name="actorinfo_immune_criticals">Immune to critical hits</string>
</resources>

View File

@@ -229,6 +229,12 @@ public final class HeroinfoActivity_Inventory extends Activity {
case R.id.inv_assign_slot3:
view.itemController.setQuickItem(lastSelectedItem, 2);
break;
case R.id.inv_menu_movetop:
player.inventory.sortToTop(getSelectedItemType(info).id);
break;
case R.id.inv_menu_movebottom:
player.inventory.sortToBottom(getSelectedItemType(info).id);
break;
default:
return super.onContextItemSelected(item);
}

View File

@@ -21,6 +21,9 @@ import com.gpl.rpg.AndorsTrail.model.actor.Player;
public final class LevelUpActivity extends Activity {
private WorldContext world;
private Player player;
private ImageView levelup_image;
private TextView levelup_description;
private View levelup_adds_new_skillpoint;
/** Called when the activity is first created. */
@Override
@@ -34,13 +37,10 @@ public final class LevelUpActivity extends Activity {
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.levelup);
final Resources res = getResources();
ImageView img = (ImageView) findViewById(R.id.levelup_image);
world.tileManager.setImageViewTile(img, player);
TextView tv = (TextView) findViewById(R.id.levelup_description);
tv.setText(res.getString(R.string.levelup_description, player.level+1));
levelup_image = (ImageView) findViewById(R.id.levelup_image);
levelup_description = (TextView) findViewById(R.id.levelup_description);
levelup_adds_new_skillpoint = findViewById(R.id.levelup_adds_new_skillpoint);
Button b;
@@ -79,12 +79,24 @@ public final class LevelUpActivity extends Activity {
}
});
b.setText(getString(R.string.levelup_add_blockchance, Constants.LEVELUP_EFFECT_DEF_CH));
View v = findViewById(R.id.levelup_adds_new_skillpoint);
}
@Override
protected void onResume() {
super.onResume();
final Resources res = getResources();
if (!player.canLevelup()) {
this.finish();
return;
}
world.tileManager.setImageViewTile(levelup_image, player);
levelup_description.setText(res.getString(R.string.levelup_description, player.level+1));
if (player.nextLevelAddsNewSkillpoint()) {
v.setVisibility(View.VISIBLE);
levelup_adds_new_skillpoint.setVisibility(View.VISIBLE);
} else {
v.setVisibility(View.GONE);
levelup_adds_new_skillpoint.setVisibility(View.GONE);
}
}

View File

@@ -30,6 +30,7 @@ public final class MonsterInfoActivity extends Activity {
private TraitsInfoView monsterinfo_currenttraits;
private ItemEffectsView monsterinfo_onhiteffects;
private TextView monsterinfo_currentconditions_title;
private TextView monsterinfo_immune_criticals;
private ActorConditionList monsterinfo_currentconditions;
private RangeBar hp;
private WorldContext world;
@@ -47,6 +48,7 @@ public final class MonsterInfoActivity extends Activity {
monsterinfo_image = (ImageView) findViewById(R.id.monsterinfo_image);
monsterinfo_title = (TextView) findViewById(R.id.monsterinfo_title);
monsterinfo_difficulty = (TextView) findViewById(R.id.monsterinfo_difficulty);
monsterinfo_immune_criticals = (TextView) findViewById(R.id.monsterinfo_immune_criticals);
Button b = (Button) findViewById(R.id.monsterinfo_close);
b.setOnClickListener(new OnClickListener() {
@@ -93,6 +95,7 @@ public final class MonsterInfoActivity extends Activity {
monster.actorTraits.onHitEffects == null ? null : Arrays.asList(monster.actorTraits.onHitEffects),
null);
hp.update(monster.health);
monsterinfo_immune_criticals.setVisibility(monster.isImmuneToCriticalHits ? View.VISIBLE : View.GONE);
}
public static int getMonsterDifficultyResource(WorldContext world, Monster monster) {

View File

@@ -411,9 +411,16 @@ public final class CombatController implements VisualEffectCompletedCallback {
context.mainActivity.updateStatus();
}
private static boolean hasCriticalAttack(Actor attacker, Actor target) {
if (!attacker.combatTraits.hasCriticalAttacks()) return false;
if (target.isImmuneToCriticalHits) return false;
return true;
}
private static float getAverageDamagePerHit(Actor attacker, Actor target) {
float result = (float) (getAttackHitChance(attacker.combatTraits, target.combatTraits)) * attacker.combatTraits.damagePotential.average() / 100;
result += (float) attacker.combatTraits.criticalChance * result * attacker.combatTraits.criticalMultiplier / 100;
if (hasCriticalAttack(attacker, target)) {
result += (float) attacker.combatTraits.criticalChance * result * attacker.combatTraits.criticalMultiplier / 100;
}
result -= target.combatTraits.damageResistance;
return result;
}
@@ -421,7 +428,7 @@ public final class CombatController implements VisualEffectCompletedCallback {
return getAverageDamagePerHit(attacker, target) * attacker.getAttacksPerTurn();
}
private static int getTurnsToKillTarget(Actor attacker, Actor target) {
if (attacker.combatTraits.hasCriticalAttacks()) {
if (hasCriticalAttack(attacker, target)) {
if (attacker.combatTraits.damagePotential.max * attacker.combatTraits.criticalMultiplier <= target.combatTraits.damageResistance) return 999;
} else {
if (attacker.combatTraits.damagePotential.max <= target.combatTraits.damageResistance) return 999;
@@ -466,7 +473,7 @@ public final class CombatController implements VisualEffectCompletedCallback {
int damage = Constants.rollValue(attacker.combatTraits.damagePotential);
boolean isCriticalHit = false;
if (attacker.combatTraits.hasCriticalAttacks()) {
if (hasCriticalAttack(attacker, target)) {
isCriticalHit = Constants.roll100(attacker.combatTraits.criticalChance);
if (isCriticalHit) {
damage *= attacker.combatTraits.criticalMultiplier;

View File

@@ -21,8 +21,9 @@ public class Actor {
public final CoordRect rectPosition;
public final ArrayList<ActorCondition> conditions = new ArrayList<ActorCondition>();
public final boolean isPlayer;
public final boolean isImmuneToCriticalHits;
public Actor(ActorTraits actorTraits, boolean isPlayer) {
public Actor(ActorTraits actorTraits, boolean isPlayer, boolean isImmuneToCriticalHits) {
this.combatTraits = new CombatTraits(actorTraits.baseCombatTraits);
this.actorTraits = actorTraits;
this.ap = new Range(actorTraits.maxAP, actorTraits.maxAP);
@@ -30,6 +31,7 @@ public class Actor {
this.position = new Coord();
this.rectPosition = new CoordRect(position, actorTraits.tileSize);
this.isPlayer = isPlayer;
this.isImmuneToCriticalHits = isImmuneToCriticalHits;
}
public int getAttacksPerTurn() { return combatTraits.getAttacksPerTurn(actorTraits.maxAP); }
@@ -64,11 +66,13 @@ public class Actor {
actorTraits.moveCost = actorTraits.baseMoveCost;
}
// ====== PARCELABLE ===================================================================
public Actor(DataInputStream src, WorldContext world, int fileversion, boolean isPlayer, ActorTraits actorTraits) throws IOException {
public Actor(DataInputStream src, WorldContext world, int fileversion, boolean isPlayer, boolean isImmuneToCriticalHits, ActorTraits actorTraits) throws IOException {
this.isPlayer = isPlayer;
this.isImmuneToCriticalHits = isImmuneToCriticalHits;
CombatTraits combatTraits = null;
boolean readCombatTraits = true;

View File

@@ -28,7 +28,7 @@ public final class Monster extends Actor {
public final int monsterClass;
public Monster(MonsterType monsterType, Coord position) {
super(monsterType, false);
super(monsterType, false, monsterType.isImmuneToCriticalHits());
this.monsterTypeID = monsterType.id;
this.position.set(position);
this.millisecondsPerMove = Constants.MONSTER_MOVEMENT_TURN_DURATION_MS / monsterType.getMovesPerTurn();
@@ -68,7 +68,7 @@ public final class Monster extends Actor {
}
public Monster(DataInputStream src, WorldContext world, int fileversion, MonsterType monsterType) throws IOException {
super(src, world, fileversion, false, monsterType);
super(src, world, fileversion, false, monsterType.isImmuneToCriticalHits(), monsterType);
this.monsterTypeID = monsterType.id;
this.millisecondsPerMove = Constants.MONSTER_MOVEMENT_TURN_DURATION_MS / monsterType.getMovesPerTurn();
this.nextPosition = new CoordRect(new Coord(), actorTraits.tileSize);

View File

@@ -56,4 +56,11 @@ public final class MonsterType extends ActorTraits {
this.isUnique = isUnique;
this.monsterClass = monsterClass;
}
public boolean isImmuneToCriticalHits() {
if (monsterClass == MONSTERCLASS_GHOST) return true;
else if (monsterClass == MONSTERCLASS_UNDEAD) return true;
else if (monsterClass == MONSTERCLASS_DEMON) return true;
return false;
}
}

View File

@@ -40,7 +40,7 @@ public final class Player extends Actor {
private final HashMap<String, Integer> alignments = new HashMap<String, Integer>();
public Player() {
super(new ActorTraits(TileManager.CHAR_HERO, new Size(1, 1), new CombatTraits(), DEFAULT_PLAYER_MOVECOST, null), true);
super(new ActorTraits(TileManager.CHAR_HERO, new Size(1, 1), new CombatTraits(), DEFAULT_PLAYER_MOVECOST, null), true, false);
this.lastPosition = new Coord();
this.nextPosition = new Coord();
this.levelExperience = new Range();
@@ -177,7 +177,7 @@ public final class Player extends Actor {
// ====== PARCELABLE ===================================================================
public Player(DataInputStream src, WorldContext world, int fileversion) throws IOException {
super(src, world, fileversion, true, null);
super(src, world, fileversion, true, false, null);
this.lastPosition = new Coord(src, fileversion);
this.nextPosition = new Coord(src, fileversion);
this.level = src.readInt();

View File

@@ -87,6 +87,12 @@ public class ItemContainer {
}
return null;
}
public int findItemIndex(String itemTypeID) {
for (int i = 0; i < items.size(); ++i) {
if (items.get(i).itemType.id.equals(itemTypeID)) return i;
}
return -1;
}
public boolean hasItem(String itemTypeID) { return findItem(itemTypeID) != null; }
public boolean hasItem(String itemTypeID, int minimumQuantity) {
return getItemQuantity(itemTypeID) >= minimumQuantity;
@@ -97,6 +103,18 @@ public class ItemContainer {
if (e == null) return 0;
return e.quantity;
}
public void sortToTop(String itemTypeID) {
int i = findItemIndex(itemTypeID);
if (i <= 0) return;
items.add(0, items.remove(i));
}
public void sortToBottom(String itemTypeID) {
int i = findItemIndex(itemTypeID);
if (i < 0) return;
items.add(items.remove(i));
}
// ====== PARCELABLE ===================================================================