Fandom

Rune of Shadows Wiki

Detailed calculations

58pages on
this wiki
Add New Page
Comments0 Share
Number of Hits:
	
	protected static int getNumHits(Unit unit, Unit other, Unit attacker, int distance) {
		int numHits = 0;
		
		numHits = unit.getNumHits(distance) + getExtraHits(unit, other, attacker);
		
		return numHits;
	}

	public byte getNumHits(int distance) {
		byte numHits = this.equip.getNumHits();
		
		if (wrath > 0) {
			numHits += 1;
		}
		
		if (distance == 1 && this.hasSkill("fury")) {
			numHits += 1;
		}
		
		if (distance > 1) {
			if (this.equip.hasSkill("ranged_hits")) {
				numHits += this.equip.getSkillParam("ranged_hits");
			}
		}
		
		return numHits;
	}

	protected static int getExtraHits(Unit unit, Unit other, Unit attacker) {
		int deltaAS = unit.getAS() - other.getAS();
		int extraHits = 0;
		int limit = 2;
		
		if (unit.hasSkill("relentess")) limit += 2;
		
		if (			! unit.getEquippedWeapon().hasSkill("radius") 
				&&	! unit.getEquippedWeapon().hasSkill("chain")
				&& 	deltaAS > 0) {
			extraHits = deltaAS / (2 + unit.getEquippedWeapon().getWeight());
			if (extraHits > limit) extraHits = limit;
		}
		
		if 	(unit == attacker 	&& unit.hasSkill("pursuit"))	extraHits += 1;
		else if (unit != attacker 	&& unit.hasSkill("defender"))	extraHits += 1;
		
		if (unit.hasSkill("tempest") && unit.getEquippedWeapon().equals("blade")) extraHits += 1;
		
		return extraHits;
	}


Chance to hit:

	protected static short calculateHitRate(Unit unit, Unit other, int distance) {
		boolean magicAtk = false;
		boolean magicDef = false;
		if (unit.getEquippedWeapon().hasSkill("magic")) magicAtk = true;
		if (unit.getEquippedWeapon().hasSkill("magic") && ! unit.getEquippedWeapon().hasSkill("physical")) magicDef = true;
		
		short chanceToHit = (short) (unit.getAtk(magicAtk) - other.getDef(magicDef, distance));
		Item item;
		
		if (unit.getEquippedWeapon().getType().equals("bow")) {
			if (unit.getEquippedMisc() != null && unit.getEquippedMisc().hasSkill("eq_bow_atk")) {
				chanceToHit += unit.getEquippedMisc().getSkillParam("eq_bow_atk");
			}
			if (other.getEquippedMisc() != null && other.getEquippedMisc().hasSkill("ranged_def_bonus")) {
				chanceToHit -= other.getEquippedMisc().getSkillParam("ranged_def_bonus");
			}
		}
		
		
		if (! unit.getEquippedWeapon().hasSkill("ignore_triangle") && ! other.getEquippedWeapon().hasSkill("ignore_triangle")) {
			item = unit.getEquippedWeapon();
			if (item.getType().equals("blade")) {
				item = other.getEquippedWeapon();
				
				if (item.getType().equals("heavy")) {
					chanceToHit += 15;
				}
				else if (item.getType().equals("pole")) {
					chanceToHit -= 15;
				}
			}
			else if (item.getType().equals("pole")) {
				item = other.getEquippedWeapon();
				
				if (item.getType().equals("blade")) {
					chanceToHit += 15;
				}
				else if (item.getType().equals("heavy")) {
					chanceToHit -= 15;
				}
			}
			else if (item.getType().equals("heavy")) {
				item = other.getEquippedWeapon();
				
				if (item.getType().equals("pole")) {
					chanceToHit += 15;
				}
				else if (item.getType().equals("blade")) {
					chanceToHit -= 15;
				}
			}
		}
		
		for (Item supportItem  : unit.getItems()) {
			if (magicAtk) {
				if (supportItem.hasSkill("ueq_matk_boost")) {
					chanceToHit += supportItem.getSkillParam("ueq_matk_boost");
				}
			}
		}
		
		int dist = 0;
		for (Unit support : unit.getMap().getSupportUnits()) {
			if (support.isAlliedWith(unit)) {
				if (support != unit) {
					dist = Math.abs( unit.getX() - support.getX() ) + Math.abs( unit.getY() - support.getY() );
					
					if (dist <= 3) {
						chanceToHit += (support.getLeadership() - 1) * 5;
						
						if (support.hasSkill("zeal")) {
							chanceToHit += 15;
						}
						
						if (support.hasWeaponSkill("inspire")) {
							chanceToHit += support.getEquippedWeapon().getSkillParam("inspire");
						}
					}
				}
			}
			else {
				dist = Math.abs( unit.getX() - support.getX() ) + Math.abs( unit.getY() - support.getY() );
				
				if (dist <= 3) {
					if (support.hasSkill("daunt")) {
						chanceToHit += 15;
					}
				}
			}
			
			if (support.isAlliedWith(other)) {
				if (support != other) {
					dist = Math.abs( other.getX() - support.getX() ) + Math.abs( other.getY() - support.getY() );
					
					if (dist <= 3) {
						chanceToHit -= (support.getLeadership() - 1) * 5;
					}
				}
			}
		}
		
		if (chanceToHit > 100) 		return 100;
		else if (chanceToHit < 0) 	return 0;
		
		
		return chanceToHit;
	}

	public short getAtk(boolean magic) {
		calculateSecondaryStats();
		short atk = 0;
		
		if (magic) {
			atk = (short) (
					this.equip.getMagAtk() 
					+ this.armor.getMagAtk()
					+ this.sMagAtk
			);
		}
		else {
			atk = (short) (
					this.equip.getAtkBonus() 
					+ this.armor.getAtkBonus()
					+ this.sAtk
					- 2 * getInventoryWeight());
		}
		
		if (this.misc != null) {
			atk += this.misc.getAtkBonus();
		}

		atk += equip.getRankAtkBonus(this);
		
		if (! magic) {
			if (frozen > 0) {
				atk -= 25;
			}
			if (blind > 0) {
				atk -= 50;
			}
			
			if (hasSkill("arms_expertise")) {
				atk += 20;
			}
			
			if (hasSkill("brute_force")) {
				atk -= 25;
			}
		}
		else {
			if (hasSkill("flare")) {
				atk += 30;
			}
		}
		
		if (bless > 0) {
			atk += 20;
		}
		
		if (! hasSkill("resolve")) {
			if (hp * 12 < mhp) {
				atk -= 15;
			}
			else if (hp * 6 < mhp) {
				atk -= 10;
			}
			else if (hp * 3 < mhp) {
				atk -= 5;
			}
		}
		
		return atk;
	}
	public short getDef(boolean magic, int distance) {
		calculateSecondaryStats();
		int def = 0;
		
		if (magic) {
			def = (
					this.equip.getMagDef()
					+ this.armor.getMagDef()
					+ this.sMagDef
			);
		}
		else {
			def = (
					this.equip.getDefBonus()
					+ this.armor.getDefBonus()
					+ this.sDef
					- 2 * getInventoryWeight()
			);
		}
		
		if (this.misc != null) {
			def += this.misc.getDefBonus();
		}
		
		if (! magic) {
			if (stun > 0) {
				def -= 50;
			}
			if (frozen > 0) {
				def -= 25;
			}
			
			if (! this.hasSkill("flying")) {
				def += map.getDefBonus(x, y);
			}
			if (hasSkill("reflex")) {
				def += 20;
			}
			
			if (distance == 1 && hasSkill("parry")) {
				def += 20;
			}
			else if (distance > 1 && hasSkill("cover")) {
				def += 20;
			}
			
			if (hasSkill("berserk")) {
				def -= 10;
			}
		}
		else {
			if (hasSkill("resistance")) {
				def += 30;
			}
			if (barrier > 0) {
				def += 70;
			}
		}
		
		if (bless > 0) {
			def += 20;
		}
		
		if (! hasSkill("resolve")) {
			if (hp * 12 < mhp) {
				def -= 15;
			}
			else if (hp * 6 < mhp) {
				def -= 10;
			}
			else if (hp * 3 < mhp) {
				def -= 5;
			}
		}
		
		return (short) def;
	}


Damage:

	protected void doDamage(Duel duel, Unit unit, Unit other, Unit attacker, int dx, int dy, boolean critical, int divisor) {
		short damage = 0;
		Item weapon = unit.getEquippedWeapon();
		Item misc = unit.getEquippedMisc();
		
		damage = calculateDamage(unit, other, attacker, dx, dy, divisor);
		if (critical) {
			if (unit.hasSkill("death_blow")) 	damage *= 4;
			else 					damage *= 2;
		}
		if (! (unit.hasSkill("luna") && GameMath.rollVs(40))) damage -= other.getAC();
		
		if (damage > 0) {
			other.takeDamage(damage);
			if (critical) {
				Log.addEntry("Critical hit!! " + 
						other.getName() + " (" + other.getType() + ") took " 
						+ damage + " damage! (" 
						+ other.getHP() + "/" + other.getMHP() + " HP)");
			}
			else {
				Log.addEntry(
						other.getName() + " (" + other.getType() + ") took " 
						+ damage + " damage! (" 
						+ other.getHP() + "/" + other.getMHP() + " HP)");
			}
			
			if (weapon.hasSkill("backlash_percent")) {
				unit.takeDamage(damage * weapon.getSkillParam("backlash_percent") / 100);
			}
			
			if (weapon.hasSkill("stun") && ! other.hasSkill("discipline")) {
				other.addStun( weapon.getSkillParam("stun"));
				maxTurns -= other.getRemainingAtks();
				other.setRemainingAtks(0);
			}
			if ( weapon.hasSkill("poison")) {
				other.addPoison(weapon.getSkillParam("poison"));
			}
			if ( weapon.hasSkill("freeze")) {
				other.addFrozen(weapon.getSkillParam("freeze"));
			}
			if ( weapon.hasSkill("blind")) {
				other.addBlind(weapon.getSkillParam("blind"));
			}
			if (misc != null) {
				if (weapon.getType().equals("bow")) {
					if (misc.hasSkill("poison_bow")) {
						other.addPoison(misc.getSkillParam("poison_bow"));
					}
					if (misc.hasSkill("freeze_bow")) {
						other.addFrozen(misc.getSkillParam("freeze_bow"));
					}
				}
			}
			
			int heal = 0;
			
			if (weapon.hasSkill("vampiric")) {
				heal += damage / 2;
			}
			if (unit.hasSkill("sol")) {
				heal += damage / 4;
			}
			
			if (heal > 0) unit.recoverHP(heal);
		}
		
		if (weapon.hasSkill("blind_always")) {
			other.addBlind( weapon.getSkillParam("blind_always"));
		}
		if (weapon.hasSkill("stun_always") && ! other.hasSkill("discipline")) {
			other.addStun( weapon.getSkillParam("stun_always"));
			maxTurns -= other.getRemainingAtks();
			other.setRemainingAtks(0);
		}
		if (weapon.hasSkill("corrode")) {
			other.getEquippedWeapon().decreaseUses(other, weapon.getSkillParam("corrode"));
		}
		
		misc = other.getEquippedMisc();
		
		if (misc != null) {
			if (misc.hasSkill("retaliation_percent")) {
				unit.takeDamage(damage * misc.getSkillParam("retaliation_percent") / 100);
			}
			if (misc.hasSkill("static_shield") && ! other.hasSkill("discipline")) {
				unit.addStun( misc.getSkillParam("static_shield"));
				maxTurns -= unit.getRemainingAtks();
				unit.setRemainingAtks(0);
			}
		}
	}
	
	protected static short calculateDamage(Unit unit, Unit other, Unit attacker, int dx, int dy, int divisor) {
		short damage = 0;
		int distance = Math.abs(dx) + Math.abs(dy);
		Item weapon = unit.getEquippedWeapon();
		Item misc = unit.getEquippedMisc();
		boolean magic = weapon.hasSkill("magic");
		
		if (other.hasSkill("great_shield") && distance > 1 && ! weapon.hasSkill("radius", "chain")) return 0;
		
		damage = (short) (unit.getDmg() / divisor);
		
		if (unit == attacker) {
			if (unit.hasSkill("mounted")) {
				if (weapon.hasSkill("charge")) {
					damage += weapon.getSkillParam("charge");
				}
			}
		}
		if (other.hasSkill("mounted")) {
			if (weapon.hasSkill("mounted")) {
				damage += weapon.getSkillParam("mounted");
			}
		}
		if (other.hasSkill("undead")) {
			if (weapon.hasSkill("undead")) {
				damage += weapon.getSkillParam("undead");
			}
			if (unit.hasSkill("holy_knight")) {
				damage += weapon.getPower();
			}
		}
		if (other.hasSkill("monster")) {
			if (weapon.hasSkill("monster")) {
				damage += weapon.getSkillParam("monster");
			}
		}
		if (distance > 1) {
			if (weapon.hasSkill("throw_bonus")) {
				damage += weapon.getSkillParam("throw_bonus");
			}
		}
		if (weapon.hasSkill("fire")) {
			if (other.getEquippedArmor().hasSkill("fire_weak")) {
				damage += weapon.getPower();
			}
			if (other.hasSkill("fireproof")) {
				damage -= weapon.getPower() / 2;
			}
		}
		if (weapon.getType().equals("bow")) {
			if (unit.getEquippedMisc() != null) {
				if (misc.hasSkill("fire_bow")) {
					if (other.getEquippedArmor().hasSkill("fire_weak")) {
						damage += weapon.getPower();
					}
					if (other.hasSkill("fireproof")) {
						damage -= weapon.getPower() / 2;
					}
				}
				if (misc.hasSkill("silver_bow")) {
					if (other.hasSkill("monster")) {
						damage += weapon.getPower();
					}
				}
			}
		}
		if (distance == 1 && unit.hasSkill("rage")) {
			damage += (short) ((unit.getMHP() - unit.getHP()) * damage / 2 / unit.getMHP());
		}
		if (! magic && ! weapon.hasSkill("mechanical")) {
			int bonus = 0;
			
			if (distance == 1) {
				if (unit.getEquippedArmor().hasSkill("dmg_melee_boost_percent")) {
					bonus += unit.getEquippedArmor().getSkillParam("dmg_melee_boost_percent");
				}
				
				if (unit.hasSkill("berserk")) 		bonus += 20;
				if (unit.hasSkill("brute_force")) 	bonus += 30;
			}
			
			damage = (short) ((100 + unit.getStr() * 2 + bonus) * damage / 100);
		}
		else if (magic)	{
			int bonus = 0;
			
			if (unit.hasSkill("supercharge")) bonus += 50;
			
			damage = (short) ((100 + bonus) * damage / 100);
		}
		
		if (other.hasSkill("resilience")) damage *= 0.8;
		
		if (weapon.hasSkill("pierce") || (misc != null && misc.hasSkill("eq_bow_pierce") && weapon.getType().equals("bow"))) {
			int pierce = 0;
			
			if (unit.hasSkill("precision")) pierce += 1;
			if (weapon.hasSkill("pierce")) pierce += weapon.getSkillParam("pierce");
			if (misc != null && misc.hasSkill("eq_bow_pierce") && weapon.getType().equals("bow")) pierce += misc.getSkillParam("eq_bow_pierce");
			
			if (pierce > other.getAC()) {
				damage += other.getAC();
			}
			else {
				damage += pierce;
			}
		}
		
		if (unit.getAvatar() > 0) {
			damage *= 3;
		}
		
		if (weapon.hasSkill("dmg_percent")) {
			damage = (short) (other.getHP() * weapon.getSkillParam("dmg_percent") / 100);
		}
		
		if (damage < 0) return 0;
		
		return damage;
	}

	public short getDmg() {
		short dmg = this.equip.getPower();
		
		if (hasSkill("power_focus") && this.equip.hasSkill("magic")) {
			dmg = (short) (dmg * 5 / 4);
		}
		
		return dmg;
	}

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.