Skip to content

Commit 13cc46c

Browse files
committed
Combat script for all chromatic dragons!
1 parent 8274faa commit 13cc46c

File tree

2 files changed

+132
-0
lines changed

2 files changed

+132
-0
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
package game.combat.npcHooks.dragons
2+
3+
import api.predef.*
4+
import engine.combat.prayer.CombatPrayer
5+
import game.item.consumable.potion.PotionEffect.Companion.hasAntiFire
6+
import game.player.Sound
7+
import io.luna.game.model.mob.Mob
8+
import io.luna.game.model.mob.Npc
9+
import io.luna.game.model.mob.Player
10+
import io.luna.game.model.mob.block.Animation
11+
import io.luna.game.model.mob.block.Graphic
12+
import io.luna.game.model.mob.combat.attack.MagicCombatAttack
13+
import io.luna.game.model.mob.combat.damage.CombatDamage
14+
import io.luna.game.model.mob.combat.damage.CombatDamageRequest
15+
import io.luna.game.model.mob.combat.damage.CombatDamageType
16+
import java.lang.Double.max
17+
import kotlin.math.floor
18+
19+
/**
20+
* A dragonfire-based [MagicCombatAttack] used by dragons.
21+
*
22+
* Protection against this attack is calculated from a combination of:
23+
* - An anti-dragon shield
24+
* - An antifire potion
25+
* - Protect from Magic
26+
*
27+
* The total protection value is then used to reduce both the attack's effective
28+
* accuracy and maximum damage.
29+
*
30+
* @param attacker The dragon performing the attack.
31+
* @param victim The target of the attack.
32+
* @param maxHit The maximum damage before protection is applied.
33+
*/
34+
class DragonFireCombatAttack(
35+
attacker: Npc,
36+
victim: Mob,
37+
private val maxHit: Int = 50
38+
) : MagicCombatAttack<Npc>(
39+
attacker,
40+
victim,
41+
DRAGON_FIRE_CAST_ANIMATION,
42+
DRAGON_FIRE_START_GRAPHIC,
43+
null,
44+
null,
45+
Sound.DRAGONBREATH,
46+
null,
47+
attacker.combatDef().attackSpeed,
48+
1
49+
) {
50+
51+
companion object {
52+
53+
/**
54+
* The standard anti-dragon shield item id.
55+
*/
56+
val DRAGON_FIRE_SHIELD = 1540
57+
58+
/**
59+
* The starting graphic displayed for the dragonfire attack.
60+
*/
61+
val DRAGON_FIRE_START_GRAPHIC = Graphic(1, 100, 0)
62+
63+
/**
64+
* The cast animation used when the dragon breathes fire.
65+
*/
66+
val DRAGON_FIRE_CAST_ANIMATION = Animation(81)
67+
}
68+
69+
/**
70+
* The total protection currently applied against this dragonfire attack.
71+
*
72+
* This value is built from the victim's active defensive sources during damage calculation.
73+
*/
74+
private var protection = 0.0
75+
76+
/**
77+
* Calculates the dragonfire damage against the supplied target.
78+
*
79+
* If the target is a player, the following protection values are added:
80+
* - Anti-dragon shield: 80%
81+
* - Antifire potion: 20%
82+
* - Protect from Magic: 40%
83+
*
84+
* The final protection value is used to reduce:
85+
* - Effective accuracy
86+
* - Resulting maximum hit
87+
*
88+
* @param other The target being evaluated for damage.
89+
* @return The resolved combat damage for this attack.
90+
*/
91+
override fun calculateDamage(other: Mob?): CombatDamage {
92+
if (other is Player) {
93+
protection += if (other.equipment.shield?.id == DRAGON_FIRE_SHIELD) 0.80 else 0.0
94+
protection += if (other.hasAntiFire()) 0.20 else 0.0
95+
protection += if (other.combat.prayers.isActive(CombatPrayer.PROTECT_FROM_MAGIC)) 0.40 else 0.0
96+
}
97+
98+
return CombatDamageRequest.Builder(attacker, victim, CombatDamageType.MAGIC)
99+
.setFlatBonusAccuracy(max(1.0 - protection, 0.0))
100+
.setBaseMaxHit((maxHit - floor(maxHit * protection).toInt()).coerceAtLeast(0))
101+
.ignoreProtectionPrayers()
102+
.build()
103+
.resolve()
104+
}
105+
106+
override fun onAttackArrived(damage: CombatDamage?) {
107+
if (damage != null && damage.amount.isPresent && victim is Player) {
108+
if (protection >= 0.8) {
109+
victim.sendMessage("Your shield absorbs most of the dragon fire!")
110+
} else if (protection <= 0.2) {
111+
victim.sendMessage("You're horribly burnt by the dragon fire!")
112+
} else {
113+
victim.sendMessage("You manage to resist some of the dragon fire!")
114+
}
115+
}
116+
}
117+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package game.combat.npcHooks.dragons
2+
3+
import api.combat.npc.NpcCombatHandler.combat
4+
import api.predef.*
5+
6+
// Chromatic dragons have a small chance to deal dragonfire.
7+
combat(941, 55, 53, 54) {
8+
attack {
9+
if (rand(5) == 0) {
10+
DragonFireCombatAttack(npc, other)
11+
} else {
12+
melee(animationId = if (rand(2) == 0) 91 else 80)
13+
}
14+
}
15+
}

0 commit comments

Comments
 (0)