Combat in Remixed Dungeon is a complex system that combines attacking, defending, and damage calculation mechanics.
Combat in Remixed Dungeon involves a two-step process:
1. **Hit Detection**: Determine if an attack successfully hits the target 2. **Damage Calculation**: Calculate the final damage after considering armor and other factors
The hit detection is calculated in CharUtils.java:
// In CharUtils.java float acuRoll = Random.Float(attacker.attackSkill(defender)); float defRoll = Random.Float(defender.defenseSkill(attacker)); boolean hit = (magic ? acuRoll * 2 : acuRoll) >= defRoll; if (hit) { // Attack hits int damage = attacker.damageRoll(); defender.damage(damage, attacker); } else { // Attack misses defender.defenseProc(attacker, 0); }
Note that for magic attacks, the attacker's roll is multiplied by 2, making magic attacks more likely to hit.
The attack skill is calculated in Char.java:
public int attackSkill(Char target) { int[] bf = {0}; forEachBuff(b -> bf[0] += b.attackSkillBonus(this)); int bonus = bf[0]; float accuracy = (float) Math.pow(1.4, bonus); if (target == null) { target = CharsList.DUMMY; } if (rangedWeapon.valid() && level().distance(getPos(), target.getPos()) == 1) { accuracy *= 0.5f; } float mainAccuracyFactor = getActiveWeapon().accuracyFactor(this); float secondaryAccuracyFactor = getSecondaryWeapon().accuracyFactor(this); float skillFactor = Utils.min(20f, mainAccuracyFactor, secondaryAccuracyFactor); int aSkill = (int) ((baseAttackSkill + lvl()) * accuracy * skillFactor); return aSkill; }
The defense skill is also calculated in Char.java:
public int defenseSkill(Char enemy) { int defenseSkill = baseDefenseSkill + lvl(); final int[] bf = {0}; forEachBuff(b -> bf[0] += b.defenceSkillBonus(this)); int bonus = bf[0]; float evasion = (float) Math.pow(1.2, bonus); if (paralysed) { evasion /= 2; } int aEnc = getItemFromSlot(Belongings.Slot.ARMOR).requiredSTR() - effectiveSTR(); if (aEnc > 0) { return (int) (defenseSkill * evasion / Math.pow(1.5, aEnc)); } else { if (getHeroClass() == HeroClass.ROGUE) { if (getCurAction() != null && getSubClass() == HeroSubClass.FREERUNNER && !isStarving()) { evasion *= 2; } return (int) ((defenseSkill - aEnc) * evasion); } else { return (int) (defenseSkill * evasion); } } }
After a successful hit, damage reduction is calculated in the defenseProc method of the Char class:
public int defenseProc(Char enemy, int baseDamage) { int dr = defenceRoll(enemy); final int[] damage = {baseDamage - dr}; forEachBuff(b -> damage[0] = b.defenceProc(this, enemy, damage[0])); damage[0] = getItemFromSlot(Belongings.Slot.ARMOR).defenceProc(enemy, this, damage[0]); if (getOwnerId() != enemy.getId()) { setEnemy(enemy); } return getScript().run("onDefenceProc", enemy, damage[0]).optint(damage[0]); }
The damage reduction (dr) is calculated in the defenceRoll method:
public int defenceRoll(Char enemy) { if (enemy.ignoreDr()) { return 0; } final int[] dr = {dr()}; forEachBuff(b -> dr[0] += b.drBonus(this)); return Random.IntRange(0, dr[0]); }
The base damage reduction is calculated from the equipped armor using its defenceProc method:
public int defenceProc(Char attacker, Char defender, int damage ) { if (glyph != null) { damage = glyph.defenceProc( this, attacker, defender, damage ); } if (!isLevelKnown()) { if (--hitsToKnow <= 0) { setLevelKnown(true); GLog.w(StringsManager.getVar(R.string.Armor_Identify), name(), toString() ); Badges.validateItemLevelAcquired( this ); } } return damage; }
The armor's effective DR (Damage Reduction) is calculated as: tier * 2 + level() * tier + (glyph != null ? tier : 0), where tier represents the armor's base type (Cloth: 1, Leather: 2, Mail: 3, etc.).
(baseAttackSkill + lvl()) * Math.pow(1.4, attackSkillBonuses) * weaponAccuracyFactor(baseDefenseSkill + lvl()) * Math.pow(1.2, defenseSkillBonuses) * class_modifiers1. Attacker rolls a random value between 0 and ''attackSkill(defender)'' 2. Defender rolls a random value between 0 and ''defenseSkill(attacker)'' 3. If ''attackerRoll > defenderRoll'', the attack hits 4. If ''defenderRoll >= attackerRoll'', the attack is evaded
1. If attack hits, damage is calculated considering armor 2. Armor reduces the damage according to the damage reduction formula 3. The final damage is applied to the defender's health