/
MagicCombatStrategy.kt
104 lines (89 loc) · 4.39 KB
/
MagicCombatStrategy.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package gg.rsmod.plugins.content.combat.strategy
import gg.rsmod.game.model.Graphic
import gg.rsmod.game.model.Tile
import gg.rsmod.game.model.combat.XpMode
import gg.rsmod.game.model.entity.Npc
import gg.rsmod.game.model.entity.Pawn
import gg.rsmod.game.model.entity.Player
import gg.rsmod.plugins.api.ProjectileType
import gg.rsmod.plugins.api.Skills
import gg.rsmod.plugins.api.ext.getVarbit
import gg.rsmod.plugins.api.ext.message
import gg.rsmod.plugins.api.ext.playSound
import gg.rsmod.plugins.content.combat.Combat
import gg.rsmod.plugins.content.combat.CombatConfigs
import gg.rsmod.plugins.content.combat.createProjectile
import gg.rsmod.plugins.content.combat.dealHit
import gg.rsmod.plugins.content.combat.formula.MagicCombatFormula
import gg.rsmod.plugins.content.combat.strategy.magic.CombatSpell
import gg.rsmod.plugins.content.magic.MagicSpells
/**
* @author Tom <rspsmods@gmail.com>
*/
object MagicCombatStrategy : CombatStrategy {
override fun getAttackRange(pawn: Pawn): Int = 10
override fun canAttack(pawn: Pawn, target: Pawn): Boolean {
if (pawn is Player) {
val spell = pawn.attr[Combat.CASTING_SPELL]!!
val requirements = MagicSpells.getMetadata(spell.id)
if (requirements != null && !MagicSpells.canCast(pawn, requirements.lvl, requirements.items, requirements.spellbook)) {
return false
}
}
return true
}
override fun attack(pawn: Pawn, target: Pawn) {
val world = pawn.world
val spell = pawn.attr[Combat.CASTING_SPELL]!!
val projectile = pawn.createProjectile(target, gfx = spell.projectile, type = ProjectileType.MAGIC, endHeight = spell.projectilEndHeight)
pawn.animate(spell.castAnimation)
spell.castGfx?.let { gfx -> pawn.graphic(gfx) }
spell.impactGfx?.let { gfx -> target.graphic(Graphic(gfx.id, gfx.height, projectile.lifespan)) }
if (spell.projectile > 0) {
world.spawn(projectile)
}
if (pawn is Player) {
if (spell.castSound != -1) {
pawn.playSound(id = spell.castSound, volume = 1, delay = 0)
}
MagicSpells.getMetadata(spell.id)?.let { requirement -> MagicSpells.removeRunes(pawn, requirement.items) }
}
val formula = MagicCombatFormula
val accuracy = formula.getAccuracy(pawn, target)
val maxHit = formula.getMaxHit(pawn, target)
val landHit = accuracy >= world.randomDouble()
val hitDelay = getHitDelay(pawn.getCentreTile(), target.getCentreTile())
val damage = pawn.dealHit(target = target, maxHit = maxHit, landHit = landHit, delay = hitDelay).hit.hitmarks.sumBy { it.damage }
if (damage >= 0 && pawn.entityType.isPlayer) {
addCombatXp(pawn as Player, target, damage, spell)
}
}
fun getHitDelay(start: Tile, target: Tile): Int {
val distance = start.getDistance(target)
return 2 + Math.floor((1.0 + distance) / 3.0).toInt()
}
private fun addCombatXp(player: Player, target: Pawn, damage: Int, spell: CombatSpell) {
val modDamage = if (target.entityType.isNpc) Math.min(target.getCurrentHp(), damage) else damage
val mode = CombatConfigs.getXpMode(player)
val multiplier = if (target is Npc) Combat.getNpcXpMultiplier(target) else 1.0
val baseXp = spell.baseXp
if (mode == XpMode.MAGIC) {
val defensive = player.getVarbit(Combat.SELECTED_AUTOCAST_VARBIT) != 0 && player.getVarbit(Combat.DEFENSIVE_MAGIC_CAST_VARBIT) != 0
if (!defensive) {
player.addXp(Skills.MAGIC, (modDamage * 2.0 * multiplier) + baseXp)
player.addXp(Skills.HITPOINTS, modDamage * 1.33 * multiplier)
} else {
player.addXp(Skills.MAGIC, (modDamage * 1.33 * multiplier) + baseXp)
player.addXp(Skills.DEFENCE, modDamage * multiplier)
player.addXp(Skills.HITPOINTS, modDamage * 1.33 * multiplier)
}
} else if (mode == XpMode.SHARED) {
player.addXp(Skills.MAGIC, (modDamage * 1.33 * multiplier) + baseXp)
player.addXp(Skills.DEFENCE, modDamage * multiplier)
player.addXp(Skills.HITPOINTS, modDamage * 1.33 * multiplier)
} else {
player.addXp(Skills.MAGIC, (modDamage * 2.0 * multiplier) + baseXp)
player.addXp(Skills.HITPOINTS, modDamage * 1.33 * multiplier)
}
}
}