RuneHive-Tarnish
Neural OSRS Enhancement Framework
Loading...
Searching...
No Matches
MageArena.java
1package com.osroyale.content.activity.impl.magearena;
2
3import com.osroyale.content.ActivityLog;
4import com.osroyale.content.activity.Activity;
5import com.osroyale.content.activity.ActivityDeathType;
6import com.osroyale.content.activity.ActivityType;
7import com.osroyale.content.activity.panel.ActivityPanel;
8import com.osroyale.content.skill.impl.magic.teleport.Teleportation;
9import com.osroyale.content.skill.impl.magic.teleport.TeleportationData;
10import com.osroyale.game.Animation;
11import com.osroyale.game.Graphic;
12import com.osroyale.game.world.World;
13import com.osroyale.game.world.entity.combat.hit.Hit;
14import com.osroyale.game.world.entity.mob.Direction;
15import com.osroyale.game.world.entity.mob.Mob;
16import com.osroyale.game.world.entity.mob.npc.Npc;
17import com.osroyale.game.world.entity.mob.npc.NpcDeath;
18import com.osroyale.game.world.entity.mob.player.Player;
19import com.osroyale.game.world.items.Item;
20import com.osroyale.game.world.pathfinding.TraversalMap;
21import com.osroyale.game.world.position.Area;
22import com.osroyale.game.world.position.Position;
23import com.osroyale.net.packet.out.SendMessage;
24import com.osroyale.util.Utility;
25
26import java.util.HashMap;
27import java.util.HashSet;
28import java.util.Map;
29import java.util.Set;
30
56
57public class MageArena extends Activity {
59 private static final Position[] BOUNDARIES = Utility.getInnerBoundaries(new Position(3105, 3934, 0), 8, 8);
60
62private enum Stage {
63 INITIALIZE, FIGHTING, FINISH
64 }
65
67 private final Player player;
68
70 private int killed;
71
73 private int points;
74
76 private Stage stage = Stage.INITIALIZE;
77
79 private Map<Integer, Npc> monsters = new HashMap<>();
80
82 private MageArena(Player player, int instance) {
83 super(5, instance);
84 this.player = player;
85 }
86
88 public static MageArena create(Player player) {
89 MageArena activity = new MageArena(player, player.playerAssistant.instance());
90 player.move(new Position(3105, 3934, 0));
91 player.gameRecord.start();
92 activity.add(player);
93 activity.resetCooldown();
94 return activity;
95 }
96
98 private Position getAvailablePosition() {
99 Position available = Utility.randomElement(BOUNDARIES);
100 while (!TraversalMap.isTraversable(available, Direction.NORTH, false)) {
101 available = Utility.randomElement(BOUNDARIES);
102 }
103 return available;
104 }
105
107 private void meteors() {
108 if (Utility.random(1, 3) == 2) {
109 Position center = new Position(player.getX() - 2, player.getY() - 2, player.getHeight());
110 Position[] bounds = Utility.getInnerBoundaries(center, 5, 5);
111 Set<Position> meteors = new HashSet<>();
112 for (Position bound : bounds) {
113 if (Utility.random(100) > 55) {
114 meteors.add(bound);
115 }
116 }
117 for (Position meteor : meteors) {
118 World.sendGraphic(new Graphic(659), meteor, getInstance());
119 World.schedule(1, () -> {
120 if (player.getPosition().equals(meteor))
121 player.damage(new Hit(Utility.random(5, 12)));
122 });
123 }
124 }
125 }
126
127 @Override
128 protected void start() {
129 switch (stage) {
130 case INITIALIZE:
131 for (int index = 0; index < 3; index++) {
132 int id = index == 0 ? 1157 : (index == 1 ? 1160 : 1158);
133 Npc monster = new Npc(id, getAvailablePosition());
134 monster.owner = player;
135 monsters.put(id, monster);
136 add(monster);
137 }
138 stage = Stage.FIGHTING;
139 cooldown(1);
140 break;
141 case FIGHTING:
142 for (Npc monster : monsters.values()) {
143 if (!monster.getCombat().isAttacking(player)) {
144 monster.getCombat().attack(player);
145 continue;
146 }
147 if (monster.getCombat().isUnderAttackBy(player) && Utility.random(5, 15) == 5) {
148 monster.speak("ARGHHH!");
149 World.sendGraphic(new Graphic(1213), player.getPosition(), getInstance());
150 player.damage(new Hit(Utility.random(1, 5)));
151 Teleportation.activateOverride(monster, getAvailablePosition(), TeleportationData.MODERN, () -> monster.getCombat().attack(player));
152 }
153 }
154 meteors();
156 break;
157 case FINISH:
158 finish();
159 break;
160 }
161 }
162
163 @Override
164 public void finish() {
165 long time = player.gameRecord.end(ActivityType.KOLODION_ARENA);
166 cleanup();
167 remove(player);
168 ActivityPanel.clear(player);
169 player.move(new Position(2540, 4715, 0));
170
171 player.animate(Animation.RESET, true);
172 player.graphic(Graphic.RESET, true);
173
174 if (stage == Stage.FINISH) {
175 points += 30;
176 player.send(new SendMessage("You have completed Kolodion's arena. Final time: @red@" + Utility.getTime(time) + "</col>. Earned Points: @red@" + points + "</col>."));
177 player.activityLogger.add(ActivityLog.KOLODIONS_MINIGAME);
178 player.completedMageArena = true;
179 }
180
181 player.mageArenaPoints += points;
182 }
183
184 @Override
185 public void cleanup() {
186 for (Npc monster : monsters.values()) {
187 monsters.remove(monster);
188 remove(monster);
189 }
190 }
191
192 @Override
193 public void onLogout(Player player) {
194 finish();
195 }
196
197 @Override
198 public void onRegionChange(Player player) {
199 if (!Area.inkolodionArena(player))
200 finish();
201 }
202
203 @Override
204 public boolean canTeleport(Player player) {
205 player.send(new SendMessage("You can not teleport out of this activity."));
206 return true;
207 }
208
209 @Override
210 public void update() {
211 int progress = (int) Utility.getPercentageAmount(killed, 3);
212 String clock = "Time: <col=FF5500>" + Utility.getTime(System.currentTimeMillis() - player.gameRecord.time) + "</col>";
213 String remain = "Monsters Left: <col=FF5500>" + (3 - killed) + "</col>";
214 String gained = "Points Gained: <col=FF5500>" + points + "</col>";
215 Item[] items = {new Item(2412), new Item(2413), new Item(2414)};
216 ActivityPanel.update(player, progress, "Mage's Arena", "Progress:", Utility.randomElement(items), clock, remain, gained);
217 }
218
219 @Override
220 public void onDeath(Mob mob) {
221 if (mob.isPlayer()) {
222 mob.animate(Animation.RESET, true);
223 mob.graphic(Graphic.RESET, true);
224 finish();
225 return;
226 }
227 if (monsters.containsKey(mob.id)) {
228 killed++;
229 points += Utility.random(15, 20);
230 monsters.remove(mob.id);
231 World.schedule(new NpcDeath(mob.getNpc()));
232 }
233 if (monsters.isEmpty()) {
234 stage = Stage.FINISH;
235 cooldown(10);
236 return;
237 }
239 }
240
241 @Override
242 public ActivityDeathType deathType() {
243 return ActivityDeathType.SAFE;
244 }
245
246 @Override
247 public ActivityType getType() {
248 return ActivityType.KOLODION_ARENA;
249 }
250}
Activity(int cooldown, int instance)
Definition Activity.java:92
static void update(Player player, int amount, String title, String footer, String... strings)
static void sendGraphic(Graphic graphic, Position position, int instance)
Definition World.java:305
static void schedule(Task task)
Definition World.java:284
static boolean isTraversable(Position from, Direction direction, int size)
static< T > T randomElement(Collection< T > collection)
Definition Utility.java:285
static String getTime()
Definition Utility.java:178
static double getPercentageAmount(int progress, int total)
Definition Utility.java:73