-
Notifications
You must be signed in to change notification settings - Fork 141
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Clean-up damage/attack roll calculations and bonus builders
- Loading branch information
1 parent
d392913
commit 547ef90
Showing
7 changed files
with
150 additions
and
108 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 7 additions & 7 deletions
14
game/plugin/entity/combat/src/framework/attack/attack_type.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
74 changes: 74 additions & 0 deletions
74
game/plugin/entity/combat/src/framework/attack/attack_utils.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import AttackType.Magic | ||
import AttackType.Ranged | ||
import CombatBonus.MeleeStrength | ||
import CombatBonus.RangedStrength | ||
import org.apollo.game.model.entity.Mob | ||
import org.apollo.game.plugins.api.* | ||
|
||
enum class RollType { | ||
Attack, | ||
Defence, | ||
Damage | ||
} | ||
|
||
fun calculateBasicMaxRoll(rollType: RollType, mob: Mob, modifiers: List<Double> = emptyList()): Int { | ||
val style = mob.combatState.attack.style | ||
val attackType = mob.combatState.attack.type | ||
|
||
if (attackType == Magic) { | ||
throw IllegalStateException("Basic roll calculator called for a magic attack. Unsupported") | ||
} | ||
|
||
val styleBonus = when (rollType) { | ||
RollType.Attack -> style.attackBonus | ||
RollType.Defence -> style.defenceBonus | ||
RollType.Damage -> { | ||
if (style == AttackStyle.Accurate && attackType != Ranged) { | ||
0 | ||
} else { | ||
style.strengthBonus | ||
} | ||
} | ||
} | ||
|
||
val baseSkill = when (rollType) { | ||
RollType.Attack -> { | ||
if (attackType == Ranged) { | ||
mob.skills.ranged | ||
} else { | ||
mob.skills.attack | ||
} | ||
} | ||
RollType.Defence -> mob.skills.defence | ||
RollType.Damage -> { | ||
if (attackType == Ranged) { | ||
mob.skills.ranged | ||
} else { | ||
mob.skills.strength | ||
} | ||
} | ||
} | ||
|
||
val equipmentBonuses = mob.combatState.bonuses | ||
val equipmentBonus = when (rollType) { | ||
RollType.Attack -> equipmentBonuses.attack[attackType] | ||
RollType.Defence -> equipmentBonuses.defence[attackType] | ||
RollType.Damage -> { | ||
if (attackType == Ranged) { | ||
equipmentBonuses[RangedStrength] | ||
} else { | ||
equipmentBonuses[MeleeStrength] | ||
} | ||
} | ||
} | ||
|
||
val modifier = modifiers.reduce { a, b -> a + b } | ||
val effectiveLevel = baseSkill.currentLevel * modifier + styleBonus + 8 | ||
val maxRoll = if (rollType == RollType.Damage) { | ||
0.5 + effectiveLevel * (equipmentBonus + 64) / 640 | ||
} else { | ||
effectiveLevel * (equipmentBonus + 64) | ||
} | ||
|
||
return maxRoll.toInt() | ||
} |
96 changes: 62 additions & 34 deletions
96
game/plugin/entity/combat/src/framework/combat_bonuses.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,46 +1,74 @@ | ||
data class DamageBonuses(val stab: Int, val slash: Int, val crush: Int, val magic: Int, val range: Int) | ||
enum class CombatBonus { | ||
MeleeStrength, | ||
RangedStrength, | ||
Prayer | ||
} | ||
|
||
data class AttackBonuses(private val bonuses: Map<AttackType, Int>) { | ||
companion object { | ||
fun default() = AttackBonusesBuilder().build() | ||
} | ||
|
||
operator fun get(key: AttackType): Int = bonuses[key]!! | ||
} | ||
|
||
data class CombatBonuses( | ||
val attack: DamageBonuses, | ||
val defence: DamageBonuses, | ||
val meleeStrength: Int, | ||
val rangedStrength: Int, | ||
val prayer: Int | ||
) | ||
val attack: AttackBonuses, | ||
val defence: AttackBonuses, | ||
private val combatBonuses: Map<CombatBonus, Int> | ||
) { | ||
companion object { | ||
fun default() = CombatBonusesBuilder().build() | ||
} | ||
|
||
operator fun get(key: CombatBonus): Int = combatBonuses[key]!! | ||
} | ||
|
||
class CombatBonusesBuilder { | ||
var meleeStrength = 0 | ||
var rangedStrength = 0 | ||
var prayer = 0 | ||
var attackBonuses = DamageBonuses(0, 0, 0, 0, 0) | ||
var defenceBonuses = DamageBonuses(0, 0, 0, 0, 0) | ||
var meleeStrength = 0 | ||
var rangedStrength = 0 | ||
var prayer = 0 | ||
var attackBonuses = AttackBonuses.default() | ||
var defenceBonuses = AttackBonuses.default() | ||
|
||
fun attack(configurer: DamageBonusesBuilder.() -> Unit) { | ||
val builder = DamageBonusesBuilder() | ||
builder.configurer() | ||
fun attack(configurer: AttackBonusesBuilder.() -> Unit) { | ||
val builder = AttackBonusesBuilder() | ||
builder.configurer() | ||
|
||
attackBonuses = builder.build() | ||
} | ||
attackBonuses = builder.build() | ||
} | ||
|
||
fun defence(configurer: DamageBonusesBuilder.() -> Unit) { | ||
val builder = DamageBonusesBuilder() | ||
builder.configurer() | ||
fun defence(configurer: AttackBonusesBuilder.() -> Unit) { | ||
val builder = AttackBonusesBuilder() | ||
builder.configurer() | ||
|
||
defenceBonuses = builder.build() | ||
} | ||
defenceBonuses = builder.build() | ||
} | ||
|
||
fun build(): CombatBonuses { | ||
return CombatBonuses(attackBonuses, defenceBonuses, meleeStrength, rangedStrength, prayer) | ||
} | ||
fun build(): CombatBonuses { | ||
return CombatBonuses(attackBonuses, defenceBonuses, mapOf( | ||
CombatBonus.MeleeStrength to meleeStrength, | ||
CombatBonus.RangedStrength to rangedStrength, | ||
CombatBonus.Prayer to prayer | ||
)) | ||
} | ||
} | ||
|
||
class DamageBonusesBuilder( | ||
var stab: Int = 0, | ||
var slash: Int = 0, | ||
var crush: Int = 0, | ||
var magic: Int = 0, | ||
var range: Int = 0 | ||
class AttackBonusesBuilder( | ||
var stab: Int = 0, | ||
var slash: Int = 0, | ||
var crush: Int = 0, | ||
var magic: Int = 0, | ||
var range: Int = 0 | ||
) { | ||
fun build(): DamageBonuses { | ||
return DamageBonuses(stab, slash, crush, magic, range) | ||
} | ||
|
||
fun build(): AttackBonuses { | ||
return AttackBonuses(mapOf( | ||
AttackType.Stab to stab, | ||
AttackType.Slash to slash, | ||
AttackType.Crush to crush, | ||
AttackType.Magic to magic, | ||
AttackType.Ranged to range | ||
)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters