====== Combat Mechanic ====== Combat in Remixed Dungeon is a complex system that combines attacking, defending, and damage calculation mechanics. ==== Combat Overview ==== 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 ==== Hit Detection System ==== 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. ==== Attack Skill Calculation ==== 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; } ==== Defense Skill Calculation ==== 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); } } } ==== Damage Calculation ==== 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.). ==== Combat Elements ==== ==== Attack Skill ==== * **Function**: Determines the chance to successfully hit an enemy * **Factors**: Base attack skill, level, attack skill bonuses from buffs, weapon accuracy factors * **Formula**: ''(baseAttackSkill + lvl()) * Math.pow(1.4, attackSkillBonuses) * weaponAccuracyFactor'' * **Reference**: [[en:rpd:attack_skill_mechanic|Attack Skill Mechanic]] ==== Defense Skill ==== * **Function**: Determines the chance to successfully evade an attack * **Factors**: Base defense skill, level, defense skill bonuses from buffs, armor encumbrance, paralysis status * **Formula**: ''(baseDefenseSkill + lvl()) * Math.pow(1.2, defenseSkillBonuses) * class_modifiers'' * **Reference**: [[en:rpd:defense_mechanic|Defense Mechanic]] ==== Armor Class ==== * **Function**: Reduces incoming damage from successful hits * **Factors**: Base armor value from equipped armor, armor bonuses from buffs * **Formula**: Damage reduction based on armor value relative to attack skill * **Reference**: [[en:rpd:armor_class|Armor Class]] ==== Evasion ==== * **Function**: Complete avoidance of damage when defense skill roll > attack skill roll * **Result**: No damage taken * **Reference**: [[en:rpd:evasion_mechanic|Evasion Mechanic]] ==== Combat Phases ==== ==== Phase 1: Hit Determination ==== 1. 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 ==== Phase 2: Damage Application ==== 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 ==== Combat Modifiers ==== ==== Status Effects ==== * **Paralysis**: Reduces evasion by 50% for the paralyzed character * **Blessed**: Increases attack skill bonus * **Other Buffs**: Various temporary effects that modify combat stats ==== Weapon Properties ==== * **Accuracy Factor**: Affects attack skill calculation * **Damage Range**: Determines the potential damage dealt * **Speed**: Affects attack frequency ==== Equipment Effects ==== * **Armor**: Reduces incoming damage * **Rings**: Various combat-relevant bonuses * **Enchantments**: Weapon and armor enchantments provide special effects ==== Combat Outcomes ==== ==== Hit ==== * Attack skill > Defense skill roll * Damage is calculated with armor reduction * Target takes reduced damage ==== Miss ==== * Defense skill > Attack skill roll * Target takes no damage * Some classes may have special effects on evade ==== Critical Hit ==== * Not a standard mechanic in Remixed Dungeon (unlike some other roguelikes) * Damage is determined by weapon damage range and modifiers ==== Code References ==== * Java: [[https://github.com/NYRDS/remixed-dungeon/blob/master/RemixedDungeon/src/main/java/com/watabou/pixeldungeon/actors/Char.java|Char.java]] * Java: [[https://github.com/NYRDS/remixed-dungeon/blob/master/RemixedDungeon/src/main/java/com/watabou/pixeldungeon/actors/CharUtils.java|CharUtils.java]] * Java: [[https://github.com/NYRDS/remixed-dungeon/blob/master/RemixedDungeon/src/main/java/com/watabou/pixeldungeon/actors/hero/Hero.java|Hero.java]] ==== Related ==== * [[en:rpd:attack_skill_mechanic|Attack Skill Mechanic]] * [[en:rpd:defense_mechanic|Defense Mechanic]] * [[en:rpd:evasion_mechanic|Evasion Mechanic]] * [[en:rpd:armor_class|Armor Class]] * [[en:rpd:accuracy_mechanic|Accuracy Mechanic]] {{tag> rpd mechanics combat fighting }}