mirror of
https://github.com/OMGeeky/andors-trail.git
synced 2026-01-08 04:27:18 +01:00
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:
@@ -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>
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 ===================================================================
|
||||
|
||||
Reference in New Issue
Block a user