RuneHive-Tarnish
Neural OSRS Enhancement Framework
Loading...
Searching...
No Matches
Cerberus.java
1package com.osroyale.game.world.entity.combat.strategy.npc.boss;
2
3import com.osroyale.game.Animation;
4import com.osroyale.game.Graphic;
5import com.osroyale.game.Projectile;
6import com.osroyale.game.UpdatePriority;
7import com.osroyale.game.task.Task;
8import com.osroyale.game.world.World;
9import com.osroyale.game.world.entity.combat.CombatType;
10import com.osroyale.game.world.entity.combat.hit.CombatHit;
11import com.osroyale.game.world.entity.combat.hit.Hit;
12import com.osroyale.game.world.entity.combat.hit.HitIcon;
13import com.osroyale.game.world.entity.combat.projectile.CombatProjectile;
14import com.osroyale.game.world.entity.combat.strategy.CombatStrategy;
15import com.osroyale.game.world.entity.combat.strategy.npc.MultiStrategy;
16import com.osroyale.game.world.entity.combat.strategy.npc.NpcMagicStrategy;
17import com.osroyale.game.world.entity.combat.strategy.npc.NpcMeleeStrategy;
18import com.osroyale.game.world.entity.combat.strategy.npc.NpcRangedStrategy;
19import com.osroyale.game.world.entity.mob.Mob;
20import com.osroyale.game.world.entity.mob.npc.Npc;
21import com.osroyale.game.world.entity.mob.player.Player;
22import com.osroyale.game.world.entity.mob.prayer.Prayer;
23import com.osroyale.game.world.entity.skill.Skill;
24import com.osroyale.game.world.position.Area;
25import com.osroyale.game.world.position.Position;
26import com.osroyale.util.Utility;
27
28import java.util.ArrayList;
29import java.util.Arrays;
30import java.util.Collections;
31import java.util.List;
32
33import static com.osroyale.game.world.entity.combat.CombatUtil.createStrategyArray;
34import static com.osroyale.game.world.entity.combat.CombatUtil.randomStrategy;
35
69
70public class Cerberus extends MultiStrategy {
71 private static final MagicAttack MAGIC = new MagicAttack();
72 private static final RangedAttack RANGED = new RangedAttack();
73 private static final LavaAttack LAVA = new LavaAttack();
74 private static final GhostAttack GHOST = new GhostAttack();
75 private static final CombatStrategy<Npc>[] FULL_STRATEGIES = createStrategyArray(NpcMeleeStrategy.get(), MAGIC, RANGED);
76
77 public Cerberus() {
78 currentStrategy = MAGIC;
79 }
80
81 @Override
82 public boolean canAttack(Npc attacker, Mob defender) {
83 int random = Utility.random(5, 20);
84
85 boolean spawnedLava = attacker.attributes.is("CERBERUS_LAVA");
86 boolean spawnedGhost = attacker.attributes.is("CERBERUS_GHOST");
87
88 if (attacker.getCurrentHealth() <= 200 && !spawnedLava && random >= 17) {
89 currentStrategy = LAVA;
90 } else if (attacker.getCurrentHealth() <= 400 && !spawnedGhost && random > 14) {
91 currentStrategy = GHOST;
92 } else {
93 currentStrategy = randomStrategy(FULL_STRATEGIES);
94 }
95 return currentStrategy.canAttack(attacker, defender);
96 }
97
98 private static class GhostAttack extends NpcMagicStrategy {
99 GhostAttack() {
100 super(CombatProjectile.getDefinition("EMPTY"));
101 }
102
103 @Override
104 public void hit(Npc attacker, Mob defender, Hit hit) {
105 }
106
107 @Override
108 public void block(Mob attacker, Npc defender, Hit hit, CombatType combatType) {
109 }
110
111 private void special(Npc ghost, Mob other, Npc attacker) {
112 Projectile projectile = new Projectile(0, 10, 30, 20, 20);
113 Hit hit = new Hit(30);
114 Prayer overhead = null;
115
116 ghost.face(other);
117 ghost.animate(4504);
118
119 switch (ghost.id) {
120 case 5867://RANGED
121 overhead = Prayer.PROTECT_FROM_RANGE;
122 projectile.setId(1230);
123 hit.setIcon(HitIcon.RANGED);
124 break;
125 case 5868://MAGIC
126 overhead = Prayer.PROTECT_FROM_MAGIC;
127 projectile.setId(127);
128 hit.setIcon(HitIcon.MAGIC);
129 break;
130 case 5869://MELEE
131 overhead = Prayer.PROTECT_FROM_MELEE;
132 projectile.setId(1248);
133 hit.setIcon(HitIcon.MELEE);
134 break;
135 }
136
137 Prayer finalOverhead = overhead;
138
139 projectile.send(ghost, other);
140 World.schedule(1, () -> {
141 if (attacker.isDead()) {
142 return;
143 }
144 if (other.getPlayer().equipment.contains(12817)) {
145 hit.setDamage(22);
146 } else if (other.prayer.isActive(finalOverhead)) {
147 int drain = other.getPlayer().equipment.contains(12821) ? 15 : 30;
148 Skill skill = other.skills.get(Skill.PRAYER);
149 skill.modifyLevel(level -> level - drain, 0, skill.getLevel());
150 other.skills.refresh(Skill.PRAYER);
151 hit.setDamage(0);
152 }
153
154 if (hit.getDamage() != 0) {
155 other.writeDamage(hit);
156 }
157 });
158 }
159
160 @Override
161 public void start(Npc attacker, Mob defender, Hit[] hits) {
162 if (!defender.isPlayer()) {
163 return;
164 }
165
166 List<Npc> ghosts = new ArrayList<>(3);
167 Player player = defender.getPlayer();
168
169 ghosts.add(new Npc(5867, player.instance, Position.create(0, 0)));
170 ghosts.add(new Npc(5868, player.instance, Position.create(0, 0)));
171 ghosts.add(new Npc(5869, player.instance, Position.create(0, 0)));
172 Collections.shuffle(ghosts);
173 ghosts.get(0).setPosition(new Position(1239, 1265));
174 ghosts.get(1).setPosition(new Position(1240, 1265));
175 ghosts.get(2).setPosition(new Position(1241, 1265));
176 ghosts.get(0).register();
177 ghosts.get(1).register();
178 ghosts.get(2).register();
179 attacker.animate(4494);
180 attacker.speak("Aaarrrooooooooo");
181 attacker.attributes.set("CERBERUS_GHOST", Boolean.TRUE);
182
183 World.schedule(new Task(1) {
184
185 private boolean possible() {
186 return attacker != null
187 && !attacker.isDead()
188 && defender != null
189 && !defender.isDead()
190 && !defender.inTeleport
191 && !defender.locking.locked()
192 && Area.inCerberus(defender);
193 }
194
195 int count = 0;
196
197 @Override
198 protected void execute() {
199 if (!possible()) {
200 cancel();
201 return;
202 }
203
204 if (count == 0) {
205 ghosts.get(0).walk(new Position(ghosts.get(0).getX(), ghosts.get(0).getY() - 9), true);
206 ghosts.get(1).walk(new Position(ghosts.get(1).getX(), ghosts.get(1).getY() - 9), true);
207 ghosts.get(2).walk(new Position(ghosts.get(2).getX(), ghosts.get(2).getY() - 9), true);
208 } else if (count == 13) {
209 special(ghosts.get(0), player, attacker);
210 } else if (count == 16) {
211 ghosts.get(0).walk(new Position(ghosts.get(0).getX(), ghosts.get(0).getY() + 9), true);
212 special(ghosts.get(1), player, attacker);
213 } else if (count == 19) {
214 ghosts.get(1).walk(new Position(ghosts.get(1).getX(), ghosts.get(1).getY() + 9), true);
215 special(ghosts.get(2), player, attacker);
216 } else if (count == 21) {
217 ghosts.get(2).walk(new Position(ghosts.get(2).getX(), ghosts.get(2).getY() + 9), true);
218 } else if (count == 40) {
219 cancel();
220 }
221 count++;
222 }
223
224 @Override
225 protected void onCancel(boolean logout) {
226 for (Npc ghost : ghosts) {
227 ghost.unregister();
228 }
229 attacker.attributes.set("CERBERUS_GHOST", Boolean.FALSE);
230 }
231 });
232 }
233
234 @Override
235 public CombatHit[] getHits(Npc attacker, Mob defender) {
236 return new CombatHit[]{};
237 }
238 }
239
240 private static class LavaAttack extends NpcMagicStrategy {
241 LavaAttack() {
242 super(CombatProjectile.getDefinition("EMPTY"));
243 }
244
245 @Override
246 public void hit(Npc attacker, Mob defender, Hit hit) {
247 }
248
249 @Override
250 public void block(Mob attacker, Npc defender, Hit hit, CombatType combatType) {
251 }
252
253 @Override
254 public void start(Npc attacker, Mob defender, Hit[] hits) {
255 Position[] boundaries = Utility.getInnerBoundaries(defender.getPosition(), 5, 5);
256 List<Position> positions = Arrays.asList(boundaries);
257 Collections.shuffle(positions);
258
259 attacker.speak("Grrrrrrrrrrrrrr");
260 attacker.animate(new Animation(4493, UpdatePriority.VERY_HIGH));
261 attacker.attributes.set("CERBERUS_LAVA", Boolean.TRUE);
262
263 World.schedule(lavaTask(attacker, defender, defender.getPosition()));
264 World.schedule(lavaTask(attacker, defender, positions.get(0)));
265 World.schedule(lavaTask(attacker, defender, positions.get(1)));
266 }
267
268 private Task lavaTask(Npc attacker, Mob defender, Position position) {
269 return new Task(1) {
270 int count = 0;
271
272 @Override
273 protected void execute() {
274 if (count == 0) {
275 World.sendGraphic(new Graphic(1246), position, attacker.instance);
276 } else if (count == 19) {
277 World.sendGraphic(new Graphic(1247), position, attacker.instance);
278 attacker.attributes.set("CERBERUS_LAVA", Boolean.FALSE);
279 cancel();
280 return;
281 }
282 if (count % 2 == 0 && defender.getPosition().isWithinDistance(position, 1)) {
283 int damage = defender.getPosition().equals(position) ? 15 : 7;
284 defender.writeDamage(new Hit(damage));
285 }
286 count++;
287 }
288 };
289 }
290
291 @Override
292 public CombatHit[] getHits(Npc attacker, Mob defender) {
293 return new CombatHit[]{};
294 }
295 }
296
297 private static class MagicAttack extends NpcMagicStrategy {
298 MagicAttack() {
299 super(CombatProjectile.getDefinition("Cerberus magic"));
300 }
301
302 @Override
303 public Animation getAttackAnimation(Npc attacker, Mob defender) {
304 return new Animation(4490, UpdatePriority.HIGH);
305 }
306
307 @Override
308 public CombatHit[] getHits(Npc attacker, Mob defender) {
309 CombatHit combatHit = nextMagicHit(attacker, defender, 29);
310 combatHit.setAccurate(true);
311 return new CombatHit[]{combatHit};
312 }
313 }
314
315 private static class RangedAttack extends NpcRangedStrategy {
316 RangedAttack() {
317 super(CombatProjectile.getDefinition("Cerberus ranged"));
318 }
319
320 @Override
321 public Animation getAttackAnimation(Npc attacker, Mob defender) {
322 return new Animation(4490, UpdatePriority.HIGH);
323 }
324
325 @Override
326 public CombatHit[] getHits(Npc attacker, Mob defender) {
327 CombatHit combatHit = nextMagicHit(attacker, defender, 29);
328 combatHit.setAccurate(true);
329 return new CombatHit[]{combatHit};
330 }
331 }
332
333}
static void sendGraphic(Graphic graphic, Position position, int instance)
Definition World.java:305
static void schedule(Task task)
Definition World.java:284
void face(GameObject object)
Definition Mob.java:326
void speak(String forceChat)
Definition Mob.java:164
void modifyLevel(Function< Integer, Integer > function)
Definition Skill.java:318
boolean isWithinDistance(Position other, int radius)
static Position create(int x, int y, int z)