RuneHive-Game
Loading...
Searching...
No Matches
Cerberus.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.Task;
8import com.runehive.game.world.World;
9import com.runehive.game.world.entity.combat.CombatType;
10import com.runehive.game.world.entity.combat.hit.CombatHit;
11import com.runehive.game.world.entity.combat.hit.Hit;
12import com.runehive.game.world.entity.combat.hit.HitIcon;
13import com.runehive.game.world.entity.combat.projectile.CombatProjectile;
14import com.runehive.game.world.entity.combat.strategy.CombatStrategy;
15import com.runehive.game.world.entity.combat.strategy.npc.MultiStrategy;
16import com.runehive.game.world.entity.combat.strategy.npc.NpcMagicStrategy;
17import com.runehive.game.world.entity.combat.strategy.npc.NpcMeleeStrategy;
18import com.runehive.game.world.entity.combat.strategy.npc.NpcRangedStrategy;
19import com.runehive.game.world.entity.mob.Mob;
20import com.runehive.game.world.entity.mob.npc.Npc;
21import com.runehive.game.world.entity.mob.player.Player;
22import com.runehive.game.world.entity.mob.prayer.Prayer;
23import com.runehive.game.world.entity.skill.Skill;
24import com.runehive.game.world.position.Area;
25import com.runehive.game.world.position.Position;
26import com.runehive.util.Utility;
27
28import java.util.ArrayList;
29import java.util.Arrays;
30import java.util.Collections;
31import java.util.List;
32
33import static com.runehive.game.world.entity.combat.CombatUtil.createStrategyArray;
34import static com.runehive.game.world.entity.combat.CombatUtil.randomStrategy;
35
36public class Cerberus extends MultiStrategy {
37 private static final MagicAttack MAGIC = new MagicAttack();
38 private static final RangedAttack RANGED = new RangedAttack();
39 private static final LavaAttack LAVA = new LavaAttack();
40 private static final GhostAttack GHOST = new GhostAttack();
41 private static final CombatStrategy<Npc>[] FULL_STRATEGIES = createStrategyArray(NpcMeleeStrategy.get(), MAGIC, RANGED);
42
43 public Cerberus() {
45 }
46
47 @Override
48 public boolean canAttack(Npc attacker, Mob defender) {
49 int random = Utility.random(5, 20);
50
51 boolean spawnedLava = attacker.attributes.is("CERBERUS_LAVA");
52 boolean spawnedGhost = attacker.attributes.is("CERBERUS_GHOST");
53
54 if (attacker.getCurrentHealth() <= 200 && !spawnedLava && random >= 17) {
56 } else if (attacker.getCurrentHealth() <= 400 && !spawnedGhost && random > 14) {
58 } else {
59 currentStrategy = randomStrategy(FULL_STRATEGIES);
60 }
61 return currentStrategy.canAttack(attacker, defender);
62 }
63
64 private static class GhostAttack extends NpcMagicStrategy {
66 super(CombatProjectile.getDefinition("EMPTY"));
67 }
68
69 @Override
70 public void hit(Npc attacker, Mob defender, Hit hit) {
71 }
72
73 @Override
74 public void block(Mob attacker, Npc defender, Hit hit, CombatType combatType) {
75 }
76
77 private void special(Npc ghost, Mob other, Npc attacker) {
78 Projectile projectile = new Projectile(0, 10, 30, 20, 20);
79 Hit hit = new Hit(30);
80 Prayer overhead = null;
81
82 ghost.face(other);
83 ghost.animate(4504);
84
85 switch (ghost.id) {
86 case 5867://RANGED
87 overhead = Prayer.PROTECT_FROM_RANGE;
88 projectile.setId(1230);
89 hit.setIcon(HitIcon.RANGED);
90 break;
91 case 5868://MAGIC
92 overhead = Prayer.PROTECT_FROM_MAGIC;
93 projectile.setId(127);
94 hit.setIcon(HitIcon.MAGIC);
95 break;
96 case 5869://MELEE
97 overhead = Prayer.PROTECT_FROM_MELEE;
98 projectile.setId(1248);
99 hit.setIcon(HitIcon.MELEE);
100 break;
101 }
102
103 Prayer finalOverhead = overhead;
104
105 projectile.send(ghost, other);
106 World.schedule(1, () -> {
107 if (attacker.isDead()) {
108 return;
109 }
110 if (other.getPlayer().equipment.contains(12817)) {
111 hit.setDamage(22);
112 } else if (other.prayer.isActive(finalOverhead)) {
113 int drain = other.getPlayer().equipment.contains(12821) ? 15 : 30;
114 Skill skill = other.skills.get(Skill.PRAYER);
115 skill.modifyLevel(level -> level - drain, 0, skill.getLevel());
116 other.skills.refresh(Skill.PRAYER);
117 hit.setDamage(0);
118 }
119
120 if (hit.getDamage() != 0) {
121 other.writeDamage(hit);
122 }
123 });
124 }
125
126 @Override
127 public void start(Npc attacker, Mob defender, Hit[] hits) {
128 if (!defender.isPlayer()) {
129 return;
130 }
131
132 List<Npc> ghosts = new ArrayList<>(3);
133 Player player = defender.getPlayer();
134
135 ghosts.add(new Npc(5867, player.instance, Position.create(0, 0)));
136 ghosts.add(new Npc(5868, player.instance, Position.create(0, 0)));
137 ghosts.add(new Npc(5869, player.instance, Position.create(0, 0)));
138 Collections.shuffle(ghosts);
139 ghosts.get(0).setPosition(new Position(1239, 1265));
140 ghosts.get(1).setPosition(new Position(1240, 1265));
141 ghosts.get(2).setPosition(new Position(1241, 1265));
142 ghosts.get(0).register();
143 ghosts.get(1).register();
144 ghosts.get(2).register();
145 attacker.animate(4494);
146 attacker.speak("Aaarrrooooooooo");
147 attacker.attributes.set("CERBERUS_GHOST", Boolean.TRUE);
148
149 World.schedule(new Task(1) {
150
151 private boolean possible() {
152 return attacker != null
153 && !attacker.isDead()
154 && defender != null
155 && !defender.isDead()
156 && !defender.inTeleport
157 && !defender.locking.locked()
158 && Area.inCerberus(defender);
159 }
160
161 int count = 0;
162
163 @Override
164 protected void execute() {
165 if (!possible()) {
166 cancel();
167 return;
168 }
169
170 if (count == 0) {
171 ghosts.get(0).walk(new Position(ghosts.get(0).getX(), ghosts.get(0).getY() - 9), true);
172 ghosts.get(1).walk(new Position(ghosts.get(1).getX(), ghosts.get(1).getY() - 9), true);
173 ghosts.get(2).walk(new Position(ghosts.get(2).getX(), ghosts.get(2).getY() - 9), true);
174 } else if (count == 13) {
175 special(ghosts.get(0), player, attacker);
176 } else if (count == 16) {
177 ghosts.get(0).walk(new Position(ghosts.get(0).getX(), ghosts.get(0).getY() + 9), true);
178 special(ghosts.get(1), player, attacker);
179 } else if (count == 19) {
180 ghosts.get(1).walk(new Position(ghosts.get(1).getX(), ghosts.get(1).getY() + 9), true);
181 special(ghosts.get(2), player, attacker);
182 } else if (count == 21) {
183 ghosts.get(2).walk(new Position(ghosts.get(2).getX(), ghosts.get(2).getY() + 9), true);
184 } else if (count == 40) {
185 cancel();
186 }
187 count++;
188 }
189
190 @Override
191 protected void onCancel(boolean logout) {
192 for (Npc ghost : ghosts) {
193 ghost.unregister();
194 }
195 attacker.attributes.set("CERBERUS_GHOST", Boolean.FALSE);
196 }
197 });
198 }
199
200 @Override
201 public CombatHit[] getHits(Npc attacker, Mob defender) {
202 return new CombatHit[]{};
203 }
204 }
205
206 private static class LavaAttack extends NpcMagicStrategy {
208 super(CombatProjectile.getDefinition("EMPTY"));
209 }
210
211 @Override
212 public void hit(Npc attacker, Mob defender, Hit hit) {
213 }
214
215 @Override
216 public void block(Mob attacker, Npc defender, Hit hit, CombatType combatType) {
217 }
218
219 @Override
220 public void start(Npc attacker, Mob defender, Hit[] hits) {
221 Position[] boundaries = Utility.getInnerBoundaries(defender.getPosition(), 5, 5);
222 List<Position> positions = Arrays.asList(boundaries);
223 Collections.shuffle(positions);
224
225 attacker.speak("Grrrrrrrrrrrrrr");
226 attacker.animate(new Animation(4493, UpdatePriority.VERY_HIGH));
227 attacker.attributes.set("CERBERUS_LAVA", Boolean.TRUE);
228
229 World.schedule(lavaTask(attacker, defender, defender.getPosition()));
230 World.schedule(lavaTask(attacker, defender, positions.get(0)));
231 World.schedule(lavaTask(attacker, defender, positions.get(1)));
232 }
233
234 private Task lavaTask(Npc attacker, Mob defender, Position position) {
235 return new Task(1) {
236 int count = 0;
237
238 @Override
239 protected void execute() {
240 if (count == 0) {
241 World.sendGraphic(new Graphic(1246), position, attacker.instance);
242 } else if (count == 19) {
243 World.sendGraphic(new Graphic(1247), position, attacker.instance);
244 attacker.attributes.set("CERBERUS_LAVA", Boolean.FALSE);
245 cancel();
246 return;
247 }
248 if (count % 2 == 0 && defender.getPosition().isWithinDistance(position, 1)) {
249 int damage = defender.getPosition().equals(position) ? 15 : 7;
250 defender.writeDamage(new Hit(damage));
251 }
252 count++;
253 }
254 };
255 }
256
257 @Override
258 public CombatHit[] getHits(Npc attacker, Mob defender) {
259 return new CombatHit[]{};
260 }
261 }
262
263 private static class MagicAttack extends NpcMagicStrategy {
265 super(CombatProjectile.getDefinition("Cerberus magic"));
266 }
267
268 @Override
269 public Animation getAttackAnimation(Npc attacker, Mob defender) {
270 return new Animation(4490, UpdatePriority.HIGH);
271 }
272
273 @Override
274 public CombatHit[] getHits(Npc attacker, Mob defender) {
275 CombatHit combatHit = nextMagicHit(attacker, defender, 29);
276 combatHit.setAccurate(true);
277 return new CombatHit[]{combatHit};
278 }
279 }
280
281 private static class RangedAttack extends NpcRangedStrategy {
283 super(CombatProjectile.getDefinition("Cerberus ranged"));
284 }
285
286 @Override
287 public Animation getAttackAnimation(Npc attacker, Mob defender) {
288 return new Animation(4490, UpdatePriority.HIGH);
289 }
290
291 @Override
292 public CombatHit[] getHits(Npc attacker, Mob defender) {
293 CombatHit combatHit = nextMagicHit(attacker, defender, 29);
294 combatHit.setAccurate(true);
295 return new CombatHit[]{combatHit};
296 }
297 }
298
299}
Class that models a single animation used by an entity.
Represents a single graphic that can be used by entities.
Definition Graphic.java:10
A game representing a cyclic unit of work.
Definition Task.java:11
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
void setPosition(Position position)
Definition Entity.java:106
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
final CombatHit nextMagicHit(T attacker, Mob defender)
void block(Mob attacker, Npc defender, Hit hit, CombatType combatType)
Definition Cerberus.java:74
void block(Mob attacker, Npc defender, Hit hit, CombatType combatType)
Task lavaTask(Npc attacker, Mob defender, Position position)
boolean locked()
Checks if the mob is locked.
Definition Locking.java:52
Handles the mob class.
Definition Mob.java:66
void speak(String forceChat)
Sets the mob's forced chat.
Definition Mob.java:127
final GenericAttributes attributes
Definition Mob.java:95
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
Represents a non-player character in the in-game world.
Definition Npc.java:29
This class represents a character controlled by a player.
Definition Player.java:125
boolean isActive(Prayer... prayers)
Checks if all given prayers are active.
Represents a trainable and usable skill.
Definition Skill.java:18
static final int PRAYER
The prayer skill id.
Definition Skill.java:36
Skill get(int id)
Gets the skill for an id.
void refresh()
Refreshes all the skills for the mob.
boolean contains(int[] bowsWithNoArrowsRequired)
Handles checking if mobs are in a certain area.
Definition Area.java:13
static boolean inCerberus(Interactable entity)
Definition Area.java:125
Represents a single tile on the game world.
Definition Position.java:14
boolean isWithinDistance(Position other, int radius)
Checks if this location is within range of another.
static Position create(int x, int y, int z)
Creates a location.
Handles miscellaneous methods.
Definition Utility.java:27
static int random(int bound)
Definition Utility.java:239
static Position[] getInnerBoundaries(Position position, int width, int length)
Definition Utility.java:621
public< K > boolean is(K key)
Gets the state of a key.
public< K, E > void set(K key, E attribute)
Sets a generic attribute.
Represents different priorities for updating.
The enumerated type whose elements represent the hit icon of a Hit.
Definition HitIcon.java:8
MELEE
Represents the melee sword hit icon.
Definition HitIcon.java:14
RANGED
Represents the ranged bow hit icon.
Definition HitIcon.java:17
MAGIC
Represents the magic hat hit icon.
Definition HitIcon.java:20