public static int critChance(Unit a, Unit b) { // Determine crit chance int critRate = a.getEquppedWeapon().getCrit() + a.getTotalSkill() / 2; int avoid = b.getTotalLuck(); return critRate - avoid; }
/** * Decides who gets xp. This model is a bit limited, as only one unit can get XP in a fight, but * only player units should get XP, there should be no XP in multiplayer, and player units should * not attack other player units. * * @return Weather attacker, defender or neither get XP. */ public int isXPAwarded() { if (attackerXP > 0 && attacker.getTeam() == 0 && (returnValue != 1 && returnValue != 3)) return 1; if (defenderXP > 0 && defender.getTeam() == 0 && (returnValue != 2 && returnValue != 3)) return 2; return 0; }
/** Checks if anything died. */ public void deathCheck() { attackerDied = attacker.isDead(); defenderDied = defender.isDead(); // if either have died, cut the battle short. if (attackerDied || defenderDied) controlState = 6; // If we have no more attacks, move on to the next phase else if (numAttacks == 0) controlState = 2; // If we do have attacks, go back to fighting. else controlState = 3; }
/** * Gets the chance a unit can hit its target * * @param a The attacking Unit * @param b The defending Unit * @param m The map it takes place on. * @return The hit chance. */ public static int hitChance(Unit a, Unit b, Map m) { // Determine Hit Rate, Evasion, and Weapon Advantage. int hitRate = a.getTotalSkill() * 2 + a.getTotalLuck() + a.getEquppedWeapon().getHit(); int evade = b.getTotalSpd() * 2 + b.getTotalLuck() + m.getTerrainAtPoint(b.getCoord()).getEvade(); int weaponAdvantage = weaponAdvantageAccuracy(a.getEquppedWeapon(), b.getEquppedWeapon()); return (hitRate + weaponAdvantage - evade); }
public void loadRecorces() { controlState = 2; // If fight with graphics if (graphics) { // TODO } // Otw, no graphics. else { xDir = attacker.getX() - defender.getX(); yDir = attacker.getY() - defender.getY(); if (xDir > 1) xDir = 1; if (xDir < -1) xDir = -1; if (yDir > 1) yDir = 1; if (yDir < -1) yDir = -1; } }
/** * Determines the amount of damage * * @param a The unit dealing damage (not necessarily attacker) * @param b The unit taking damage (not necessarily defender) * @return The amount of damage taken */ public static int determineDamage(Unit a, Unit b) { int attack = a.getEquppedWeapon().getDmg(); switch (a.getEquppedWeapon().getStrOrMag()) { case 0: attack += a.getTotalStr(); break; case 1: attack += a.getTotalMag(); break; // case other? What else do we need? Half/half? } int defense = 0; switch (a.getEquppedWeapon().getWeaponType()) { case 0: case 1: case 2: case 3: defense = (int) b.getTotalDef(); break; case 4: case 5: case 6: defense = (int) b.getTotalRes(); break; } return attack - defense; }
/** * Determines how much XP a unit should get * * @param a The attacking unit * @param b The defnding unit * @param xp The base XP for the action * @return The amount of XP Unit a gets */ public int xpMath(Unit a, Unit b, int xp) { float ret = xp; // If A is overleveled (more than 2 higher), reduce by 10% for each level too hight. if (a.getLevel() > b.getLevel() + 2) { ret = ret - (a.getLevel() - b.getLevel() - 2) * xp * 0.1f; if (ret < 1) ret = 1; } // if A is underleveled give it 20% more xp per level it was weaker than b. else if (a.getLevel() < b.getLevel()) ret = ret + (b.getLevel() - a.getLevel()) * xp * .2f; return (int) ret; }
/** * Start up a fight * * @param a The attacker * @param d The defender * @param mode Full animation (true) or no animation (false). * @param m The terrain map. */ public void start(Unit a, Unit d, boolean mode, Map m) { super.start(); map = m; controlState = 0; attacker = a; defender = d; graphics = mode; // Clean the flags. numAttacks = 0; attackPhase = 0; attackerTurn = false; defenderTurn = false; attackerDied = false; defenderDied = false; attackerXP = 0; defenderXP = 0; returnValue = NOBODYDIED; int x = attacker.getX() - defender.getX(); if (x > 0) x = 1; else x = -1; attackerHealthBar = new FightHealthBarUI(attacker.getTotalHP(), attacker.getCurHP(), x); defenderHealthBar = new FightHealthBarUI(defender.getTotalHP(), defender.getCurHP(), -x); }
/** * Simulates 1 attack, from a to b * * @param a The unit attacking. Not necessarily attacker * @param b The unit defending. Not necessarily defender */ public void attack(Unit a, Unit b) { // Get the RNG int d100 = (int) Math.ceil(Math.random() * 100); // Do we hit? boolean hit = d100 < hitChance(a, b, map); if (hit) { // Get the RNG d100 = (int) Math.ceil(Math.random() * 100); // Deterimine raw damage attackDamage = determineDamage(a, b); // (Insert Damage Resist abilities) // Do we crit? boolean crit = d100 < critChance(a, b); if (crit) { attackDamage = attackDamage * 3; attackResult = 2; } else { attackResult = 1; } // Take Damage b.takeDamage(attackDamage); if (attackerTurn) defenderHealthBar.damage(attackDamage); else attackerHealthBar.damage(attackDamage); a.getEquppedWeapon().dull(); } // we missed else attackResult = 0; }
/** Starts up the attack. */ public void startAttack() { // Nobody has attacked yet. The attacker goes first if (attackPhase == 0) { attackPhase = 1; attackerTurn = true; numAttacks = attacker.numAttacks(); controlState = 3; } // Now it's the defender's turn else if (attackPhase == 1) { attackPhase = 2; attackerTurn = false; defenderTurn = true; numAttacks = defender.numAttacks(); controlState = 3; } // Now the speed round else if (attackPhase == 2) { attackPhase = 3; attackerTurn = false; defenderTurn = false; int speedDef = attacker.getTotalSpd() - defender.getTotalSpd(); // the attacker is fast enough. FIGHT if (speedDef >= 4) { attackerTurn = true; numAttacks = attacker.numAttacks(); controlState = 3; } // the defender is fast enough. FIGHT else if (speedDef <= -4) { defenderTurn = true; numAttacks = defender.numAttacks(); controlState = 3; } // they were the same-ish speed. No more fighting. else controlState = 1; } // We can't get to attack phase 4 else controlState = 1; }
/** Cleans up, and awards XP TODO */ public void cleanup() { // Just in case they're not back where they belong. if (!graphics) { attacker.moveInstantly(attacker.getCoord()); defender.moveInstantly(defender.getCoord()); } // Award XP if (attacker.getTeam() == 0) { int xp = 10; if (defenderDied) xp += 20; attackerXP = xpMath(attacker, defender, xp); } if (defender.getTeam() == 0) { int xp = 10; if (attackerDied) xp += 20; defenderXP = xpMath(defender, attacker, xp); } }
/** * Determines if a can even hit b * * @param a The unit attacking. Not necessarily attacker * @param b The unit defending. Not necessarily defender * @return If an attack can be made. */ public boolean canAttack(Unit a, Unit b) { // TODO Automatic weapon selection if at the wrong range. int dist = a.distanceTo(b); return (a.getEquppedWeapon().getMinRange() <= dist && a.getEquppedWeapon().getMaxRange() >= dist); }
/** renders the scene. */ public void animate() { // always check this if (active) { if (graphics) { } else { if (attackerTurn) { if (frameCount > noGraphicDamagePoint) attacker.moveVisually( attacker.getX() + xDir * (.05 * (double) (frameCount - noGraphicFrames)), attacker.getY() + yDir * (.05 * (frameCount - noGraphicFrames))); else attacker.moveVisually( attacker.getX() - xDir * .05 * frameCount, attacker.getY() - yDir * .05 * frameCount); } if (defenderTurn) { if (frameCount > noGraphicDamagePoint) defender.moveVisually( defender.getX() - xDir * (.05 * (frameCount - noGraphicFrames)), defender.getY() - yDir * (.05 * (frameCount - noGraphicFrames))); else defender.moveVisually( defender.getX() + xDir * .05 * frameCount, defender.getY() + yDir * .05 * frameCount); } } } }