1package com.osroyale.game.world.entity.combat.strategy.npc;
3import com.osroyale.game.Animation;
4import com.osroyale.game.Graphic;
5import com.osroyale.game.UpdatePriority;
6import com.osroyale.game.engine.GameEngine;
7import com.osroyale.game.world.entity.combat.CombatImpact;
8import com.osroyale.game.world.entity.combat.CombatType;
9import com.osroyale.game.world.entity.combat.attack.FightType;
10import com.osroyale.game.world.entity.combat.effect.impl.CombatPoisonEffect;
11import com.osroyale.game.world.entity.combat.effect.impl.CombatVenomEffect;
12import com.osroyale.game.world.entity.combat.hit.CombatHit;
13import com.osroyale.game.world.entity.combat.hit.Hit;
14import com.osroyale.game.world.entity.combat.projectile.CombatProjectile;
15import com.osroyale.game.world.entity.combat.strategy.basic.MagicStrategy;
16import com.osroyale.game.world.entity.mob.Mob;
17import com.osroyale.game.world.entity.mob.npc.Npc;
18import com.osroyale.util.RandomUtils;
19import org.jire.tarnishps.WorldTask;
21import javax.annotation.Nullable;
22import java.util.Optional;
23import java.util.function.Consumer;
24import java.util.function.Predicate;
28 protected final CombatProjectile combatProjectile;
30 public NpcMagicStrategy(CombatProjectile combatProjectile) {
31 this.combatProjectile = combatProjectile;
35 public CombatProjectile getCombatProjectile() {
36 return combatProjectile;
40 public void start(Npc attacker, Mob defender, Hit[] hits) {
41 sendAnimation(attacker, defender);
42 sendProjectile(attacker, hits, attacker, defender,
null);
45 public void sendAnimation(Npc attacker, Mob defender) {
46 Animation animation = getAttackAnimation(attacker, defender);
47 if (animation.isReset()) {
48 Optional<Animation> projAnim = combatProjectile.getAnimation();
49 if (projAnim.isPresent()) animation = projAnim.get();
52 attacker.animate(animation,
true);
53 combatProjectile.getStart().ifPresent(attacker::graphic);
56 public int sendProjectile(Npc attacker, Hit[] hits,
58 @Nullable Runnable onProjectileLand) {
59 final int duration = combatProjectile.sendProjectile(from, to);
61 final Graphic endGraphic = getEndGraphic(combatProjectile, missed(hits),
SPLASH, duration);
62 if (endGraphic !=
null) to.graphic(endGraphic);
64 for (Hit
hit : hits) {
65 Predicate<CombatImpact> filter = effect -> effect.canAffect(attacker, to,
hit);
66 Consumer<CombatImpact> execute = effect -> effect.impact(attacker, to,
hit,
null);
67 combatProjectile.getEffect().filter(filter).ifPresent(execute);
69 if (attacker.definition.isPoisonous()) {
70 if (CombatVenomEffect.isVenomous(attacker) && RandomUtils.success(0.25)) {
73 CombatPoisonEffect.getPoisonType(attacker.id).ifPresent(to::poison);
78 if (onProjectileLand !=
null) {
79 final int delay = GameEngine.clientTicksToServerTicks(duration);
80 WorldTask.schedule(delay, onProjectileLand);
87 public CombatHit[] getHits(Npc attacker, Mob defender) {
88 return new CombatHit[]{nextMagicHit(attacker, defender, combatProjectile)};
92 public int getAttackDelay(Npc attacker, Mob defender, FightType fightType) {
93 int delay = attacker.definition.getAttackDelay();
95 if (attacker.getPosition().getDistance(defender.getPosition()) > 4) {
103 public int getAttackDistance(Npc attacker, FightType fightType) {
108 public Animation getAttackAnimation(Npc attacker, Mob defender) {
109 return new Animation(attacker.definition.getAttackAnimation(), UpdatePriority.HIGH);
113 public boolean canAttack(Npc attacker, Mob defender) {
118 public CombatType getCombatType() {
119 return CombatType.MAGIC;
static final Graphic SPLASH
void hit(T attacker, Mob defender, Hit hit)