RuneHive-Game
Loading...
Searching...
No Matches
Vorkath.java
Go to the documentation of this file.
1package com.runehive.game.world.entity.combat.strategy.npc.boss;
2
3import com.runehive.game.Animation;
4import com.runehive.game.Graphic;
5import com.runehive.game.Projectile;
6import com.runehive.game.UpdatePriority;
7import com.runehive.game.task.TickableTask;
8import com.runehive.game.world.World;
9import com.runehive.game.world.entity.combat.Combat;
10import com.runehive.game.world.entity.combat.CombatType;
11import com.runehive.game.world.entity.combat.CombatUtil;
12import com.runehive.game.world.entity.combat.attack.FightType;
13import com.runehive.game.world.entity.combat.hit.CombatHit;
14import com.runehive.game.world.entity.combat.hit.Hit;
15import com.runehive.game.world.entity.combat.hit.Hitsplat;
16import com.runehive.game.world.entity.combat.projectile.CombatProjectile;
17import com.runehive.game.world.entity.combat.strategy.CombatStrategy;
18import com.runehive.game.world.entity.combat.strategy.npc.MultiStrategy;
19import com.runehive.game.world.entity.combat.strategy.npc.NpcMagicStrategy;
20import com.runehive.game.world.entity.combat.strategy.npc.NpcMeleeStrategy;
21import com.runehive.game.world.entity.combat.strategy.npc.NpcRangedStrategy;
22import com.runehive.game.world.entity.combat.strategy.npc.impl.DragonfireStrategy;
23import com.runehive.game.world.entity.mob.Mob;
24import com.runehive.game.world.entity.mob.data.LockType;
25import com.runehive.game.world.entity.mob.npc.Npc;
26import com.runehive.game.world.object.CustomGameObject;
27import com.runehive.game.world.pathfinding.TraversalMap;
28import com.runehive.game.world.position.Area;
29import com.runehive.game.world.position.Position;
30import com.runehive.net.packet.out.SendWidget;
31import com.runehive.util.RandomUtils;
32import com.runehive.util.Utility;
33
34import java.util.Collections;
35import java.util.Deque;
36import java.util.LinkedList;
37import java.util.List;
38
39import static com.runehive.game.world.entity.combat.CombatUtil.createStrategyArray;
40
41/**
42 * The combat definition for Vorkath.
43 *
44 * @author Daniel
45 */
46public class Vorkath extends MultiStrategy {
47 private static final NpcMeleeStrategy MELEE = NpcMeleeStrategy.get();
48 private static final MagicAttack MAGIC = new MagicAttack();
49 private static final RangedAttack RANGED = new RangedAttack();
50 private static final FireballAttack FIREBALL = new FireballAttack();
51
52 private static final DragonfireStrategy DRAGONFIRE = new DragonfireAttack();
55
56 private static final VenomSpecial VENOM_SPECIAL = new VenomSpecial();
57 private static final FrozenSpecial FROZEN_SPECIAL = new FrozenSpecial();
58
61 private final CombatStrategy<Npc>[] SPECIALS = createStrategyArray(VENOM_SPECIAL, FROZEN_SPECIAL);
62
63 private final Deque<CombatStrategy<Npc>> strategyQueue = new LinkedList<>();
64 private int specialIndex;
65
66 public Vorkath() {
68 }
69
70 @Override
71 public void init(Npc attacker, Mob defender) {
72 if (strategyQueue.isEmpty()) {
73 for (int index = 0; index < 6; index++) {
75 }
77 }
79 }
80
81 @Override
82 public boolean canAttack(Npc attacker, Mob defender) {
83 if (currentStrategy == MELEE && !MELEE.canAttack(attacker, defender)) {
85 }
86 return currentStrategy.canAttack(attacker, defender);
87 }
88
89 @Override
90 public boolean withinDistance(Npc attacker, Mob defender) {
91 if (currentStrategy == MELEE && !MELEE.withinDistance(attacker, defender)) {
93 }
94 return currentStrategy.canAttack(attacker, defender);
95 }
96
97 private static class VenomSpecial extends NpcMagicStrategy {
99 super(CombatProjectile.getDefinition("EMPTY"));
100 }
101
102 @Override
103 public int getAttackDelay(Npc attacker, Mob defender, FightType fightType) {
104 return 30;
105 }
106
107 @Override
108 public void start(Npc attacker, Mob defender, Hit[] hits) {
109 World.schedule(2, () -> {
110 attacker.animate(new Animation(7957, UpdatePriority.HIGH));
111 List<Position> boundaries = TraversalMap.getTraversableTiles(attacker.getPosition().transform(-7, -7), 30, 30);
112 Collections.shuffle(boundaries);
113
114 World.schedule(1, () -> {
115
116 Projectile projectile = new Projectile(1483, 10, 85, 20, 0);
117 projectile.send(attacker, defender.getPosition());
118 World.schedule(AcidTask(defender, defender.getPosition().copy()));
119
120
121 for (int index = 0; index < 40; index++) {
122 Position position = boundaries.get(index);
123 projectile.send(attacker, position);
124 World.schedule(AcidTask(defender, position));
125 }
126
127 final Projectile projectile2 = new Projectile(1482, 15, 95, 15, 15);
128
129 World.schedule(dragonFireTickableTask(attacker, defender, projectile2));
130 });
131 });
132 }
133
135 return new TickableTask(false, 1) {
136
137 private boolean possible() {
138 return attacker != null
139 && !attacker.isDead()
140 && !defender.isDead()
141 && !defender.inTeleport
142 && !defender.locking.locked()
143 && Area.inVorkath(defender);
144 }
145
146 @Override
147 protected void onCancel(boolean logout) {
148 super.onCancel(logout);
149
150 if (!logout && attacker != null) {
151 final Combat<? extends Mob> combat = attacker.getCombat();
152 if (combat != null) {
153 combat.clearDamageQueue();
154 }
155 }
156 }
157
158 @Override
159 protected void tick() {
160 if (!possible()) {
161 cancel();
162 return;
163 }
164
165 if (tick > 27) {
166 cancel();
167 return;
168 }
169
170 if (tick < 3) {
171 return;
172 }
173
174 Position position = defender.getPosition().copy();
175 projectile.send(attacker, position);
176
177 World.schedule(3, () -> {
178 if (!possible()) {
179 final Combat<? extends Mob> combat = defender.getCombat();
180 if (combat != null) {
181 combat.clearDamageQueue();
182 }
183 return;
184 }
185
187
188 if (defender.getPosition().equals(position)) {
189 defender.damage(new Hit(Utility.random(30)));
190 }
191 });
192 }
193 };
194 }
195
197 return new TickableTask(false, 2) {
198 private CustomGameObject object;
199
200 @Override
201 protected void tick() {
202 if (tick == 1) {
203 object = new CustomGameObject(32000, defender.instance, position);
204 object.register();
205 } else if (tick == 13) {
206 object.unregister();
207 cancel();
208 return;
209 }
210
211 if (defender.getPosition().equals(position) && Area.inVorkath(defender)) {
212 defender.writeDamage(new Hit(Utility.random(1, 10)));
213 }
214 }
215 };
216 }
217
218 @Override
219 public CombatHit[] getHits(Npc attacker, Mob defender) {
220 CombatHit combatHit = nextMagicHit(attacker, defender, 0);
221 combatHit.setAccurate(true);
222 combatHit.setDamage(-1);
223 return new CombatHit[]{combatHit};
224 }
225 }
226
227 private static class RangedAttack extends NpcRangedStrategy {
228
230 super(CombatProjectile.getDefinition("Vorkath Ranged"));
231 }
232
233 @Override
234 public Animation getAttackAnimation(Npc attacker, Mob defender) {
235 return new Animation(7952, UpdatePriority.HIGH);
236 }
237
238 @Override
239 public CombatHit[] getHits(Npc attacker, Mob defender) {
240 return new CombatHit[]{nextRangedHit(attacker, defender, 32)};
241 }
242 }
243
244 private static class MagicAttack extends NpcMagicStrategy {
245
247 super(CombatProjectile.getDefinition("Vorkath Magic"));
248 }
249
250 @Override
251 public Animation getAttackAnimation(Npc attacker, Mob defender) {
252 return new Animation(7952, UpdatePriority.HIGH);
253 }
254
255 @Override
256 public CombatHit[] getHits(Npc attacker, Mob defender) {
257 return new CombatHit[]{nextRangedHit(attacker, defender, 32)};
258 }
259 }
260
261 private static class FrozenSpecial extends NpcMagicStrategy {
262 private final Projectile PROJECTILE = new Projectile(1470, 5, 85, 30, 30, 40);
263
265 super(CombatProjectile.getDefinition("Vorkath Frozen Special"));
266 }
267
268 @Override
269 public Animation getAttackAnimation(Npc attacker, Mob defender) {
270 return new Animation(7952, UpdatePriority.HIGH);
271 }
272
273 @Override
274 public void hit(Npc attacker, Mob defender, Hit hit) {
275 defender.graphic(new Graphic(369));
276 defender.locking.lock(LockType.FREEZE);
277
278 attacker.blockInteract = true;
279 attacker.resetFace();
280 attacker.face(new Position(2277, 4057));
281 attacker.animate(new Animation(7960, UpdatePriority.HIGH));
282 PROJECTILE.send(attacker, new Position(2277, 4057));
283
284 World.schedule(4, () -> {
285 attacker.blockInteract = false;
286 Npc zombie = new Npc(8063, defender.instance, new Position(2277, 4057)) {
287 @Override
288 public void appendDeath() {
289 super.appendDeath();
290 defender.locking.unlock();
292 }
293 };
294 zombie.instance = defender.instance;
295 zombie.register();
296 zombie.walkTo(defender, () -> {
297 World.sendGraphic(new Graphic(1460, true), zombie.getPosition(), defender.instance);
298 defender.damage(new Hit(60 * zombie.getCurrentHealth() / zombie.getMaximumHealth()));
299 defender.locking.unlock();
301 zombie.unregister();
302 });
303 });
304 }
305
306 @Override
307 public int getAttackDelay(Npc attacker, Mob defender, FightType fightType) {
308 return 15;
309 }
310
311 @Override
312 public CombatHit[] getHits(Npc attacker, Mob defender) {
313 CombatHit combatHit = nextMagicHit(attacker, defender, -1);
314 combatHit.setAccurate(false);
315 return new CombatHit[]{combatHit};
316 }
317 }
318
319 private static class DragonfireAttack extends DragonfireStrategy {
321 super(CombatProjectile.getDefinition("Metalic dragonfire"));
322 }
323
324 @Override
325 public Animation getAttackAnimation(Npc attacker, Mob defender) {
326 return new Animation(7952, UpdatePriority.HIGH);
327 }
328
329 @Override
330 public int getAttackDistance(Npc attacker, FightType fightType) {
331 return 10;
332 }
333
334 @Override
335 public CombatHit[] getHits(Npc attacker, Mob defender) {
336 return new CombatHit[]{CombatUtil.generateDragonfire(attacker, defender, 85, true)};
337 }
338 }
339
340 private static class VenomDragonfireAttack extends DragonfireStrategy {
342 super(CombatProjectile.getDefinition("Vorkath Venom Dragonfire"));
343 }
344
345 @Override
346 public Animation getAttackAnimation(Npc attacker, Mob defender) {
347 return new Animation(7952, UpdatePriority.HIGH);
348 }
349
350 @Override
351 public int getAttackDistance(Npc attacker, FightType fightType) {
352 return 10;
353 }
354
355 @Override
356 public void hit(Npc attacker, Mob defender, Hit hit) {
357 super.hit(attacker, defender, hit);
358 if (hit.isAccurate()) {
359 defender.venom();
360 }
361 }
362
363 @Override
364 public CombatHit[] getHits(Npc attacker, Mob defender) {
365 CombatHit combatHit = CombatUtil.generateDragonfire(attacker, defender, 75, true);
366 combatHit.setHitsplat(Hitsplat.VENOM);
367 return new CombatHit[]{combatHit};
368 }
369 }
370
371 private static class PinkDragonfireAttack extends DragonfireStrategy {
373 super(CombatProjectile.getDefinition("Vorkath Pink Dragonfire"));
374 }
375
376 @Override
377 public Animation getAttackAnimation(Npc attacker, Mob defender) {
378 return new Animation(7952, UpdatePriority.HIGH);
379 }
380
381 @Override
382 public void hitsplat(Npc attacker, Mob defender, Hit hit) {
383 super.hitsplat(attacker, defender, hit);
384
385 if (defender.isPlayer()) {
386 defender.prayer.reset();
387 }
388 }
389
390 @Override
391 public int getAttackDistance(Npc attacker, FightType fightType) {
392 return 10;
393 }
394
395 @Override
396 public CombatHit[] getHits(Npc attacker, Mob defender) {
397 return new CombatHit[]{CombatUtil.generateDragonfire(attacker, defender, 80, true)};
398 }
399 }
400
401 private static class FireballAttack extends DragonfireStrategy {
402 private final Projectile PROJECTILE = new Projectile(1481, 5, 105, 30, 30, 40);
403 private final Graphic GRAPHIC = new Graphic(1466, true);
405
407 super(CombatProjectile.getDefinition("EMPTY"));
408 }
409
410 @Override
411 public Animation getAttackAnimation(Npc attacker, Mob defender) {
412 return new Animation(7960, UpdatePriority.HIGH);
413 }
414
415 @Override
416 public void start(Npc attacker, Mob defender, Hit[] hits) {
417 super.start(attacker, defender, hits);
418 position = defender.getPosition().copy();
419 }
420
421 @Override
422 public void attack(Npc attacker, Mob defender, Hit hit) {
423 PROJECTILE.send(attacker, position);
424 }
425
426 @Override
427 public void hit(Npc attacker, Mob defender, Hit hit) {
428 super.hitsplat(attacker, defender, hit);
430 hit.setAccurate(false);
431 if (defender.getPosition().equals(position)) {
432 hit.setAs(CombatUtil.generateDragonfire(attacker, defender, 150, true));
433 hit.setAccurate(true);
434 } else if (Utility.withinOctal(defender.getPosition(), defender.width(), defender.length(), position, 1, 1, 1)) {
435 hit.setAs(CombatUtil.generateDragonfire(attacker, defender, 150, true));
436 hit.modifyDamage(damage -> damage / 2);
437 hit.setAccurate(true);
438 }
439 }
440
441 @Override
442 public int getAttackDistance(Npc attacker, FightType fightType) {
443 return 10;
444 }
445
446 @Override
447 public CombatHit[] getHits(Npc attacker, Mob defender) {
448 return new CombatHit[]{nextMagicHit(attacker, defender, -1, CombatUtil.getHitDelay(attacker, defender, CombatType.MAGIC) + 1, 1)};
449 }
450 }
451
452}
Class that models a single animation used by an entity.
Represents a single graphic that can be used by entities.
Definition Graphic.java:10
Represents the game world.
Definition World.java:46
static void schedule(Task task)
Submits a new event.
Definition World.java:247
static void sendGraphic(Graphic graphic, Position position, int instance)
Sends a graphic to the world.
Definition World.java:268
A collection of util methods and constants related to combat.
static int getHitDelay(final Mob attacker, final Mob defender, final CombatType type)
Gets the hit delay for the specified type.
static CombatHit generateDragonfire(Mob attacker, Mob defender, int max, boolean prayer)
A wrapper for a Hit object, adding additional variables for hit and hitsplat delays.
A Hit object holds the damage amount and hitsplat data.
Definition Hit.java:10
void setDamage(int damage)
Sets the hit damage.
Definition Hit.java:98
void setHitsplat(Hitsplat hitsplat)
Definition Hit.java:163
final CombatHit nextRangedHit(T attacker, Mob defender)
final CombatHit nextMagicHit(T attacker, Mob defender)
int getAttackDelay(Npc attacker, Mob defender, FightType fightType)
Definition Vorkath.java:307
int getAttackDelay(Npc attacker, Mob defender, FightType fightType)
Definition Vorkath.java:103
TickableTask dragonFireTickableTask(Mob attacker, Mob defender, Projectile projectile)
Definition Vorkath.java:134
static final CombatStrategy< Npc >[] FULL_STRATEGIES
Definition Vorkath.java:59
boolean locked()
Checks if the mob is locked.
Definition Locking.java:52
Handles the mob class.
Definition Mob.java:66
abstract Combat<? extends Mob > getCombat()
The combat of the mob.
void face(GameObject object)
Sets the client update flag to face a certain direction.
Definition Mob.java:289
final boolean isPlayer()
Check if an entity is a player.
Definition Mob.java:564
void walkTo(Position position)
Definition Mob.java:374
void resetFace()
Resets the mob's face location.
Definition Mob.java:330
Optional< Graphic > graphic
Definition Mob.java:91
void venom()
Applies venom to the entity.
Definition Mob.java:508
Represents a non-player character in the in-game world.
Definition Npc.java:29
void appendDeath()
Handles the mob death.
Definition Npc.java:147
void register()
Registers an entity to the World.
Definition Npc.java:112
void unregister()
Unregisters an entity from the World.
Definition Npc.java:126
void reset()
Iterates through the active prayers and disables them all.
Represents a static game object loaded from the map fs.
Contains traversal data for a set of regions.
static List< Position > getTraversableTiles(Position southWest, int width, int length)
Returns a List of positions that are traversable from the specified position.
Handles checking if mobs are in a certain area.
Definition Area.java:13
static boolean inVorkath(Interactable entity)
Definition Area.java:183
Represents a single tile on the game world.
Definition Position.java:14
Position transform(int diffX, int diffY, int diffZ)
Creates a new location based on this location.
Position copy()
Creates a deep copy of this location.
A static-util class that provides additional functionality for generating pseudo-random numbers.
static< T > T random(T[] array)
Pseudo-randomly retrieves a element from array.
Handles miscellaneous methods.
Definition Utility.java:27
static int random(int bound)
Definition Utility.java:239
static boolean withinOctal(Interactable source, Interactable target, int distance)
Definition Utility.java:703
Represents different priorities for updating.
The enumerated type whose elements represent the fighting types.