Merge branch 'kril-kotlinification-attempt' into 'master'

Draft: Kril kotlinification attempt

See merge request 2009scape/2009scape!2190
This commit is contained in:
dam 2025-11-29 07:02:36 +02:00
commit 655e5c6af8
2 changed files with 144 additions and 156 deletions

View file

@ -1,156 +0,0 @@
package content.region.asgarnia.trollheim.handlers.gwd;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.BattleState;
import core.game.node.entity.combat.CombatStyle;
import core.game.node.entity.combat.CombatSwingHandler;
import core.game.node.entity.combat.InteractionType;
import core.game.node.entity.combat.equipment.ArmourSet;
import core.game.node.entity.impl.Projectile;
import core.game.node.entity.impl.Animator.Priority;
import core.game.node.entity.player.Player;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.tools.RandomFunction;
import static core.api.ContentAPIKt.*;
/**
* Handles K'ril Tsutsaroth's combat.
* @author Emperor
*/
public final class GWDTsutsarothSwingHandler extends CombatSwingHandler {
/**
* The melee attack animation.
*/
private static final Animation MELEE_ATTACK = new Animation(6945, Priority.HIGH);
/**
* The range attack animation.
*/
private static final Animation MAGIC_ATTACK = new Animation(6947, Priority.HIGH);
/**
* The magic start graphic.
*/
private static final Graphics MAGIC_START = new Graphics(1210);
/**
* If K'ril is performing its special attack.
*/
private boolean special;
/**
* Constructs a new {@code GWDTsutsarothSwingHandler} {@Code Object}.
*/
public GWDTsutsarothSwingHandler() {
super(CombatStyle.MELEE);
}
@Override
public InteractionType canSwing(Entity entity, Entity victim) {
return CombatStyle.MELEE.getSwingHandler().canSwing(entity, victim);
}
@Override
public int swing(Entity entity, Entity victim, BattleState state) {
int ticks = 1;
special = false;
int hit = 0;
CombatStyle style = CombatStyle.MELEE;
if (RandomFunction.randomize(10) < 4) {
ticks += (int) Math.ceil(entity.getLocation().getDistance(victim.getLocation()) * 0.3);
style = CombatStyle.MAGIC;
} else if (RandomFunction.randomize(10) == 0) {
if (special = (victim instanceof Player)) {
((Player) victim).getPacketDispatch().sendMessage("K'ril Tsutsaroth slams through your protection prayer, leaving you feeling drained.");
}
entity.sendChat("YARRRRRRR!");
}
if (style.getSwingHandler().isAccurateImpact(entity, victim)) {
int max = style.getSwingHandler().calculateHit(entity, victim, special ? 1.08 : 1.0);
hit = RandomFunction.random(max);
state.setMaximumHit(max);
if (style == CombatStyle.MELEE) {
applyPoison(victim, entity, 80);
}
if (special) {
((Player) victim).getSkills().decrementPrayerPoints((double) hit / 2);
}
}
state.setEstimatedHit(hit);
state.setStyle(style);
return ticks;
}
@Override
public void visualize(Entity entity, Entity victim, BattleState state) {
if(entity == null || state == null || state.getStyle() == null){
return;
}
if (state.getStyle() == CombatStyle.MELEE) {
entity.animate(MELEE_ATTACK);
} else {
entity.visualize(MAGIC_ATTACK, MAGIC_START);
Projectile.magic(entity, victim, 1211, 0, 0, 46, 1).send();
}
}
@Override
public ArmourSet getArmourSet(Entity e) {
return getType().getSwingHandler().getArmourSet(e);
}
@Override
public double getSetMultiplier(Entity e, int skillId) {
return getType().getSwingHandler().getSetMultiplier(e, skillId);
}
@Override
public void impact(Entity entity, Entity victim, BattleState state) {
if (state.getStyle() == CombatStyle.MAGIC) {
if (state.getEstimatedHit() > -1) {
victim.getImpactHandler().handleImpact(entity, state.getEstimatedHit(), CombatStyle.MAGIC, state);
}
return;
}
state.getStyle().getSwingHandler().impact(entity, victim, state);
}
@Override
public void visualizeImpact(Entity entity, Entity victim, BattleState state) {
victim.animate(victim.getProperties().getDefenceAnimation());
}
@Override
public void adjustBattleState(Entity entity, Entity victim, BattleState state) {
super.adjustBattleState(entity, victim, state);
}
@Override
protected int getFormattedHit(Entity entity, Entity victim, BattleState state, int hit) {
if (!special) {
if (state.getArmourEffect() != ArmourSet.VERAC && victim.hasProtectionPrayer(state.getStyle())) {
hit *= entity instanceof Player ? 0.6 : 0;
}
}
return formatHit(victim, hit);
}
@Override
public int calculateAccuracy(Entity entity) {
return getType().getSwingHandler().calculateAccuracy(entity);
}
@Override
public int calculateDefence(Entity victim, Entity attacker) {
return getType().getSwingHandler().calculateDefence(victim, attacker);
}
@Override
public int calculateHit(Entity entity, Entity victim, double modifier) {
return getType().getSwingHandler().calculateHit(entity, victim, modifier);
}
}

View file

@ -0,0 +1,144 @@
package content.region.asgarnia.trollheim.handlers.gwd
import core.api.applyPoison
import core.game.node.entity.Entity
import core.game.node.entity.combat.BattleState
import core.game.node.entity.combat.CombatStyle
import core.game.node.entity.combat.CombatSwingHandler
import core.game.node.entity.combat.InteractionType
import core.game.node.entity.impl.Animator.Priority
import core.game.node.entity.impl.Projectile
import core.game.node.entity.player.Player
import core.game.world.update.flag.context.Animation
import core.game.world.update.flag.context.Graphics
import core.tools.RandomFunction
import kotlin.math.ceil
import core.api.log
import core.tools.Log
/**
* Handles K'ril Tsutsaroth's combat.
* @author Emperor
* @author Damighty - Kotlin conversion ~~and special attack fixes~~
*/
class GWDTsutsarothSwingHandler : CombatSwingHandler(CombatStyle.MELEE) {
companion object {
private val MELEE_ATTACK = Animation(6945, Priority.HIGH)
private val MAGIC_ATTACK = Animation(6947, Priority.HIGH)
private val MAGIC_START = Graphics(1210)
}
override fun canSwing(entity: Entity, victim: Entity): InteractionType? = CombatStyle.MELEE.swingHandler.canSwing(entity, victim)
override fun swing(entity: Entity?, victim: Entity?, state: BattleState?): Int {
log(this::class.java, Log.DEBUG, "KRIL:SWING.START")
entity ?: return 1
victim ?: return 1
state ?: return 1
var ticks = 1
var isSpecialAttack = false
when {
RandomFunction.randomize(10) < 4 -> {
log(this::class.java, Log.DEBUG, "KRIL:STYLE.MAGIC_CHOSEN")
val distance = entity.location.getDistance(victim.location)
ticks += ceil(distance * 0.3).toInt()
state.style = CombatStyle.MAGIC
log(this::class.java, Log.DEBUG, "KRIL:STYLE.MAGIC_SET")
}
else -> {
log(this::class.java, Log.DEBUG, "KRIL:STYLE.MELEE_CHOSEN")
if (victim is Player && victim.hasProtectionPrayer(CombatStyle.MELEE))
if (RandomFunction.randomize(10) == 0) {
isSpecialAttack = true
log(this::class.java, Log.DEBUG, "KRIL:SPECIAL.SET=$isSpecialAttack")
}
state.style = CombatStyle.MELEE
log(this::class.java, Log.DEBUG, "KRIL:STYLE.MELEE_SET")
}
}
log(this::class.java, Log.DEBUG, "KRIL:SPECIAL.CHECK-L64:$isSpecialAttack")
val handler = state.style.swingHandler
val hit = when {
isSpecialAttack -> {
state.maximumHit = 49
val specialHitRoll = RandomFunction.random(35, 49 + 1)
log(this::class.java, Log.DEBUG, "KRIL:HIT.CALC.SPECIAL:$specialHitRoll")
specialHitRoll
}
handler.isAccurateImpact(entity, victim) -> {
val maxHit = handler.calculateHit(entity, victim, 1.0)
state.maximumHit = maxHit
log(this::class.java, Log.DEBUG, "KRIL:HIT.CALC.ACCURATE.MAX=$maxHit")
RandomFunction.random(maxHit)
}
else -> {
log(this::class.java, Log.ERR, "KRIL:HIT.CALC.FAILURE")
0
}
}
if (state.style == CombatStyle.MELEE && handler.isAccurateImpact(entity, victim)) {
applyPoison(victim, entity, 76)
}
log(this::class.java, Log.DEBUG, "KRIL:SPECIAL.CHECK-L90:$isSpecialAttack")
if (isSpecialAttack && victim is Player) {
entity.sendChat("YARRRRRRR!")
log(this::class.java, Log.DEBUG, "KRIL:SPECIAL.DRAIN.FROM:${victim.skills.prayerPoints}")
victim.skills.prayerPoints = victim.skills.prayerPoints / 2
log(this::class.java, Log.DEBUG, "KRIL:SPECIAL.DRAIN.TO:${victim.skills.prayerPoints}")
victim.packetDispatch.sendMessage("K'ril Tsutsaroth slams through your protection prayer, leaving you feeling drained.")
}
state.estimatedHit = hit
log(this::class.java, Log.DEBUG, "KRIL:SWING.END:HIT=$hit")
return ticks
}
override fun visualize(entity: Entity, victim: Entity?, state: BattleState?) {
when (state?.style) {
CombatStyle.MELEE -> entity.animate(MELEE_ATTACK)
CombatStyle.MAGIC -> {
entity.visualize(MAGIC_ATTACK, MAGIC_START)
victim?.let {
Projectile.magic(entity, it, 1211, 0, 0, 46, 1).send()
}
}
CombatStyle.RANGE, null -> { }
}
}
override fun impact(entity: Entity?, victim: Entity?, state: BattleState?) {
when (state?.style) {
CombatStyle.MAGIC -> {
if (state.estimatedHit > -1) {
victim?.impactHandler?.handleImpact(entity, state.estimatedHit, CombatStyle.MAGIC, state)
}
}
CombatStyle.MELEE -> {
victim?.impactHandler?.handleImpact(entity, state.estimatedHit, CombatStyle.MELEE, state)
}
CombatStyle.RANGE, null -> { }
}
}
override fun visualizeImpact(entity: Entity?, victim: Entity?, state: BattleState?) {
victim?.animate(victim.properties.defenceAnimation)
}
override fun calculateAccuracy(entity: Entity?): Int = type?.swingHandler?.calculateAccuracy(entity) ?: 0
override fun calculateDefence(victim: Entity?, attacker: Entity?): Int = type?.swingHandler?.calculateDefence(victim, attacker) ?: 0
override fun calculateHit(entity: Entity?, victim: Entity?, modifier: Double): Int = type?.swingHandler?.calculateHit(entity, victim, modifier) ?: 0
override fun getSetMultiplier(e: Entity?, skillId: Int): Double = type?.swingHandler?.getSetMultiplier(e, skillId) ?: 1.0
}