RuneHive-Game
Loading...
Searching...
No Matches
Skill.java
Go to the documentation of this file.
1package com.runehive.game.world.entity.skill;
2
3import com.runehive.content.event.EventDispatcher;
4import com.runehive.content.event.InteractionEvent;
5import com.runehive.content.event.InteractionEvent.InteractionType;
6import com.runehive.content.event.InteractionEventListener;
7import com.runehive.content.event.impl.*;
8import com.runehive.game.world.entity.mob.player.Player;
9import com.runehive.util.Stopwatch;
10
11import java.util.function.Function;
12
13/**
14 * Represents a trainable and usable skill.
15 *
16 * @author Michael | Chex
17 */
18public class Skill implements InteractionEventListener {
19
20 /** The attack skill id. */
21 public static final int ATTACK = 0;
22
23 /** The defence skill id. */
24 public static final int DEFENCE = 1;
25
26 /** The strength skill id. */
27 public static final int STRENGTH = 2;
28
29 /** The hitpoints skill id. */
30 public static final int HITPOINTS = 3;
31
32 /** The ranged skill id. */
33 public static final int RANGED = 4;
34
35 /** The prayer skill id. */
36 public static final int PRAYER = 5;
37
38 /** The magic skill id. */
39 public static final int MAGIC = 6;
40
41 /** The cooking skill id. */
42 public static final int COOKING = 7;
43
44 /** The woodcutting skill id. */
45 public static final int WOODCUTTING = 8;
46
47 /** The fletching skill id. */
48 public static final int FLETCHING = 9;
49
50 /** The fishing skill id. */
51 public static final int FISHING = 10;
52
53 /** The firemaking skill id. */
54 public static final int FIREMAKING = 11;
55
56 /** The crafting skill id. */
57 public static final int CRAFTING = 12;
58
59 /** The smithing skill id. */
60 public static final int SMITHING = 13;
61
62 /** The mining skill id. */
63 public static final int MINING = 14;
64
65 /** The herblore skill id. */
66 public static final int HERBLORE = 15;
67
68 /** The agility skill id. */
69 public static final int AGILITY = 16;
70
71 /** The thieving skill id. */
72 public static final int THIEVING = 17;
73
74 /** The slayer skill id. */
75 public static final int SLAYER = 18;
76
77 /** The farming skill id. */
78 public static final int FARMING = 19;
79
80 /** The runecrafting skill id. */
81 public static final int RUNECRAFTING = 20;
82
83 /** The construction skill id. */
84 public static final int CONSTRUCTION = 21;
85
86 /** The hunter skill id. */
87 public static final int HUNTER = 22;
88
89 /** The amount of available skills. */
90 public static final int SKILL_COUNT = 23;
91
92 /** The total skill amount. */
93 public static final int TOTAL_SKILL_LEVEL = 99 * SKILL_COUNT;
94
95 /** An array of skill names. */
96 private static final String[] SKILL_NAMES = new String[]{
97 /* 00 */ "Attack",
98 /* 01 */ "Defence",
99 /* 02 */ "Strength",
100 /* 03 */ "Hitpoints",
101 /* 04 */ "Ranged",
102 /* 05 */ "Prayer",
103 /* 06 */ "Magic",
104 /* 07 */ "Cooking",
105 /* 08 */ "Woodcutting",
106 /* 09 */ "Fletching",
107 /* 10 */ "Fishing",
108 /* 11 */ "Firemaking",
109 /* 12 */ "Crafting",
110 /* 13 */ "Smithing",
111 /* 14 */ "Mining",
112 /* 15 */ "Herblore",
113 /* 16 */ "Agility",
114 /* 17 */ "Thieving",
115 /* 18 */ "Slayer",
116 /* 19 */ "Farming",
117 /* 20 */ "Runecrafting",
118 /* 21 */ "Construction",
119 /* 22 */ "Hunter",
120 };
121
122 /**
123 * An array with the index being the skill level (from [0, 99]) and the
124 * value being the minimum experience requirement for that level.
125 */
126 private static final int[] EXP_FOR_LEVEL = {
127 0, 83, 174, 276, 388, 512, 650, 801, 969, 1154, 1358, 1584, 1833, 2107,
128 2411, 2746, 3115, 3523, 3973, 4470, 5018, 5624, 6291, 7028, 7842, 8740,
129 9730, 10824, 12031, 13363, 14833, 16456, 18247, 20224, 22406, 24815, 27473,
130 30408, 33648, 37224, 41171, 45529, 50339, 55649, 61512, 67983, 75127, 83014,
131 91721, 101333, 111945, 123660, 136594, 150872, 166636, 184040, 203254, 224466,
132 247886, 273742, 302288, 333804, 368599, 407015, 449428, 496254, 547953, 605032,
133 668051, 737627, 814445, 899257, 992895, 1096278, 1210421, 1336443, 1475581,
134 1629200, 1798808, 1986068, 2192818, 2421087, 2673114, 2951373, 3258594, 3597792,
135 3972294, 4385776, 4842295, 5346332, 5902831, 6517253, 7195629, 7944614, 8771558,
136 9684577, 10692629, 11805606, 13034431
137 };
138
139 /** Skill tab string data. */
140 public static final int[][] INTERFACE_DATA = {
141 {4004, 4005},
142 {4008, 4009},
143 {4006, 4007},
144 {4016, 4017},
145 {4010, 4011},
146 {4012, 4013},
147 {4014, 4015},
148 {4034, 4035},
149 {4038, 4039},
150 {4026, 4027},
151 {4032, 4033},
152 {4036, 4037},
153 {4024, 4025},
154 {4030, 4031},
155 {4028, 4029},
156 {4020, 4021},
157 {4018, 4019},
158 {4022, 4023},
159 {12166, 12167},
160 {13926, 13927},
161 {4152, 4153},
162 {24134, 24135},
163 {-1, -1},
164 {-1, -1},
165 {-1, -1}};
166
167 public transient final Stopwatch stopwatch = Stopwatch.start();
168
169 /** The skill id. */
170 private final int skill;
171
172 /** The current level of the skill. */
173 private int level;
174
175 /** The maximum level of the skill. */
176 private int maxLevel;
177
178 /** The current skill experience. */
179 private double experience;
180
181 private boolean doingSkill = false;
182
183 /** Constructs a new {@link Skill}. */
184 public Skill(int skill, int level, double experience) {
185 this.skill = skill;
186 this.level = level;
187 this.maxLevel = getLevelForExperience(experience);
188 this.experience = experience;
189 }
190
191 /**
192 * Gets the skill id.
193 *
194 * @return The skill id.
195 */
196 public int getSkill() {
197 return skill;
198 }
199
200 /**
201 * Gets the current skill level.
202 *
203 * @return The current level.
204 */
205 public int getLevel() {
206 return level;
207 }
208
209 /**
210 * Gets the maximum skill level.
211 *
212 * @return The max level.
213 */
214 public int getMaxLevel() {
215 return maxLevel;
216 }
217
218 /**
219 * Gets the skill experience.
220 *
221 * @return The skill experience.
222 */
223 public double getExperience() {
224 return experience;
225 }
226
227 /**
228 * Gets the floor {@code experience}.
229 *
230 * @return The floor experience.
231 */
232 public int getRoundedExperience() {
233 return (int) experience;
234 }
235
236 /**
237 * Sets the level for this skill.
238 *
239 * @param level The level to set.
240 */
241 public void setLevel(int level) {
242 this.level = level;
243 }
244
245 /**
246 * Sets the maximum level for this skill.
247 *
248 * @param maxLevel The level to set.
249 */
250 public void setMaxLevel(int maxLevel) {
251 this.maxLevel = maxLevel;
252 }
253
254 /**
255 * Sets the experience for this skill.
256 *
257 * @param experience The experience to set.
258 */
259 public void setExperience(double experience) {
260 this.experience = experience;
261 }
262
263 /**
264 * Determines if your level is greater than or equal to {@code level}.
265 *
266 * @param level the level to compare against this one.
267 * @return {@code true} if this level is greater than or equal to the other
268 * one, {@code false} otherwise.
269 */
270 public boolean reqLevel(int level) {
271 return this.level >= level;
272 }
273
274 /**
275 * Modifies the current level with a given function. If the level happens to
276 * fall under 0, the level will be set to 0.
277 *
278 * @param function The function, with this current skill level as the input, and
279 * the new level as an output.
280 */
281 public void modifyLevel(Function<Integer, Integer> function) {
282 modifyLevel(function, 0, maxLevel);
283 }
284
285 /**
286 * Modifies the current level with a given function. The level will be
287 * clipped to the given boundaries as well.If the level happens to fall
288 * under 0, the level will be set to 0, regardless of the given boundaries.
289 *
290 * @param function The function, with this current skill level as the input, and
291 * the new level as an output.
292 * @param lowerBounds The lowest value the level can be modified to.
293 * @param upperBounds The highest value the level can be modified to.
294 */
295 public void modifyLevel(Function<Integer, Integer> function, int lowerBounds, int upperBounds) {
296 level = function.apply(level);
297
298 if (level < 0) {
299 level = 0;
300 } else {
301 if (level < lowerBounds) {
302 level = lowerBounds;
303 }
304
305 if (level > upperBounds) {
306 level = upperBounds;
307 }
308 }
309 }
310
311 /**
312 * Adds levels to this skill by the given amount.
313 *
314 * @param amount The amount to deposit.
315 */
316 public void addLevel(int amount) {
317 modifyLevel(level -> level + amount);
318 }
319
320 /**
321 * Removes levels from this skill by the given amount.
322 *
323 * @param amount The amount to deposit.
324 */
325 public void removeLevel(int amount) {
326 modifyLevel(level -> level - amount);
327 }
328
329 /**
330 * Multiplies the current level of this skill by a given amount.
331 *
332 * @param amount The amount to multiply by.
333 */
334 public void multiplyLevel(double amount) {
335 modifyLevel(level -> (int) (level * amount));
336 }
337
338 /**
339 * Divides the current level of this skill by a given amount.
340 *
341 * @param amount The amount to divide by.
342 */
343 public void divideLevel(double amount) {
344 modifyLevel(level -> amount == 0 ? -level : (int) (level / amount));
345 }
346
347 /**
348 * Modifies the current experience with a given function. If the experience
349 * happens to fall under 0, the experience will be set to 0.
350 *
351 * @param function The function, with this current skill experience as the input,
352 * and the new experience as an output.
353 */
354 public double modifyExperience(Function<Double, Double> function) {
355 return modifyExperience(function, 0, 200_000_000);
356 }
357
358 /**
359 * Modifies the current experience with a given function. The experience
360 * will be clipped to the given boundaries as well. If the experience
361 * happens to fall under 0, the experience will be set to 0, regardless of
362 * the given boundaries.
363 *
364 * @param function The function, with this current skill experience as the input,
365 * and the new experience as an output.
366 * @param lowerBounds The lowest value the experience can be modified to.
367 * @param upperBounds The highest value the experience can be modified to.
368 */
369 public double modifyExperience(Function<Double, Double> function, int lowerBounds, int upperBounds) {
370 experience = function.apply(experience);
371
372 if (experience < 0) {
373 experience = 0;
374 } else {
375 if (experience < lowerBounds) {
376 experience = lowerBounds;
377 }
378
379 if (experience > upperBounds) {
380 experience = upperBounds;
381 }
382 }
383
384 return experience;
385 }
386
387 /**
388 * Adds experiences to this skill by the given amount.
389 *
390 * @param amount The amount to deposit.
391 */
392 public double addExperience(double amount) {
393 return modifyExperience(experience -> experience + amount);
394 }
395
396 /**
397 * Removes experiences from this skill by the given amount.
398 *
399 * @param amount The amount to deposit.
400 */
401 public void removeExperience(double amount) {
403 }
404
405 /**
406 * Multiplies the current experience of this skill by a given amount.
407 *
408 * @param amount The amount to multiply by.
409 */
410 public void multiplyExperience(double amount) {
412 }
413
414 /**
415 * Divides the current experience of this skill by a given amount.
416 *
417 * @param amount The amount to divide by.
418 */
419 public void divideExperience(double amount) {
420 modifyExperience(experience -> amount == 0 ? -experience : (experience / amount));
421 }
422
423 /**
424 * Performs a binary search to quickly search for the level at the given
425 * experience.
426 *
427 * @param experience The experience.
428 * @param min The minimum level to search from.
429 * @param max The maximum level to search to.
430 * @return The level at the given experience.
431 */
432 private static byte binarySearch(double experience, int min, int max) {
433 int mid = (min + max) / 2;
434 double value = EXP_FOR_LEVEL[mid];
435
436 if (value > experience) {
437 return binarySearch(experience, min, mid - 1);
438 } else if (value == (int) experience || EXP_FOR_LEVEL[mid + 1] > experience) {
439 return (byte) (mid + 1);
440 }
441
442 return binarySearch(experience, mid + 1, max);
443 }
444
445 /** Gets the level for a given experience amount. If the experience is larger than the experience at level 99, then the value will always return 99. */
446 public static final byte getLevelForExperience(double experience) {
447 if ((int) experience >= EXP_FOR_LEVEL[98]) {
448 return 99;
449 }
450 return binarySearch(experience, 0, 98);
451 }
452
453 /** Gets the experience for a given level. The level is automatically clipped to be in the range [0, 99]. */
454 public static final int getExperienceForLevel(int level) {
455 if (level >= 99) {
456 return EXP_FOR_LEVEL[98];
457 }
458 if (level < 1) {
459 return 0;
460 }
461 return EXP_FOR_LEVEL[level - 1];
462 }
463
464 /** Gets the name for a skill id. */
465 public static String getName(int skill) {
466 return SKILL_NAMES[skill];
467 }
468
469 /** Creates a function that adds a number by an amount. */
470 public static Function<Integer, Integer> add(int amount) {
471 return level -> level + amount;
472 }
473
474 /** Creates a function that subtracts a number by an amount. */
475 public static Function<Integer, Integer> subtract(int amount) {
476 return level -> level - amount;
477 }
478
479 /** Creates a function that multiplies a number by an amount. */
480 public static Function<Integer, Integer> multiply(double amount) {
481 return level -> (int) (level * amount);
482 }
483
484 /** Creates a function that divides a number by an amount. */
485 public static Function<Integer, Integer> divide(double amount) {
486 return level -> amount == 0 ? 0 : (int) (level / amount);
487 }
488
489 public void setDoingSkill(boolean doingSkill) {
490 this.doingSkill = doingSkill;
491 }
492
493 public boolean isDoingSkill() {
494 return doingSkill;
495 }
496
497 protected double modifier() {
498 return 0;
499 }
500
501 protected boolean clickItem(Player player, ItemInteractionEvent event) {
502 return false;
503 }
504
505 protected boolean clickNpc(Player player, NpcInteractionEvent event) {
506 return false;
507 }
508
509 protected boolean clickObject(Player player, ObjectInteractionEvent event) {
510 return false;
511 }
512
514 return false;
515 }
516
517 protected boolean useItem(Player player, ItemOnItemInteractionEvent event) {
518 return false;
519 }
520
522 return false;
523 }
524
526 return false;
527 }
528
529 @Override
530 public String toString() {
531 return String.format("Skill[name=%s, id=%s, level=%s, max=%s, experience=%s]", getName(skill), skill, level, maxLevel, experience);
532 }
533
534 @Override
535 public boolean onEvent(Player player, InteractionEvent interactionEvent) {
536 final EventDispatcher dispatcher = new EventDispatcher(interactionEvent);
540
544
545 dispatcher.dispatch(InteractionType.FIRST_CLICK_NPC, e -> clickNpc(player, (FirstNpcClick) e));
546 dispatcher.dispatch(InteractionType.SECOND_CLICK_NPC, e -> clickNpc(player, (SecondNpcClick) e));
551 return interactionEvent.isHandled();
552 }
553}
void dispatch(InteractionType type, EventHandler eventHandler)
This class represents a character controlled by a player.
Definition Player.java:125
static final String[] SKILL_NAMES
An array of skill names.
Definition Skill.java:96
static Function< Integer, Integer > add(int amount)
Creates a function that adds a number by an amount.
Definition Skill.java:470
void removeExperience(double amount)
Removes experiences from this skill by the given amount.
Definition Skill.java:401
void modifyLevel(Function< Integer, Integer > function, int lowerBounds, int upperBounds)
Modifies the current level with a given function.
Definition Skill.java:295
static final int TOTAL_SKILL_LEVEL
The total skill amount.
Definition Skill.java:93
static final int SLAYER
The slayer skill id.
Definition Skill.java:75
boolean useItem(Player player, ItemOnItemInteractionEvent event)
Definition Skill.java:517
static final int WOODCUTTING
The woodcutting skill id.
Definition Skill.java:45
boolean itemContainerAction(Player player, ItemContainerInteractionEvent event)
Definition Skill.java:525
boolean useItem(Player player, ItemOnObjectInteractionEvent event)
Definition Skill.java:521
void multiplyLevel(double amount)
Multiplies the current level of this skill by a given amount.
Definition Skill.java:334
static final int[] EXP_FOR_LEVEL
An array with the index being the skill level (from [0, 99]) and the value being the minimum experien...
Definition Skill.java:126
static String getName(int skill)
Gets the name for a skill id.
Definition Skill.java:465
static final byte getLevelForExperience(double experience)
Gets the level for a given experience amount.
Definition Skill.java:446
void divideExperience(double amount)
Divides the current experience of this skill by a given amount.
Definition Skill.java:419
double experience
The current skill experience.
Definition Skill.java:179
void modifyLevel(Function< Integer, Integer > function)
Modifies the current level with a given function.
Definition Skill.java:281
void setMaxLevel(int maxLevel)
Sets the maximum level for this skill.
Definition Skill.java:250
static final int PRAYER
The prayer skill id.
Definition Skill.java:36
static final int RANGED
The ranged skill id.
Definition Skill.java:33
void setExperience(double experience)
Sets the experience for this skill.
Definition Skill.java:259
static final int CRAFTING
The crafting skill id.
Definition Skill.java:57
static final int HERBLORE
The herblore skill id.
Definition Skill.java:66
static final int SMITHING
The smithing skill id.
Definition Skill.java:60
static final int FISHING
The fishing skill id.
Definition Skill.java:51
static final int DEFENCE
The defence skill id.
Definition Skill.java:24
static final int CONSTRUCTION
The construction skill id.
Definition Skill.java:84
boolean clickItem(Player player, ItemInteractionEvent event)
Definition Skill.java:501
static Function< Integer, Integer > divide(double amount)
Creates a function that divides a number by an amount.
Definition Skill.java:485
boolean reqLevel(int level)
Determines if your level is greater than or equal to level.
Definition Skill.java:270
double getExperience()
Gets the skill experience.
Definition Skill.java:223
boolean onEvent(Player player, InteractionEvent interactionEvent)
Definition Skill.java:535
static final int SKILL_COUNT
The amount of available skills.
Definition Skill.java:90
int getLevel()
Gets the current skill level.
Definition Skill.java:205
void setLevel(int level)
Sets the level for this skill.
Definition Skill.java:241
void removeLevel(int amount)
Removes levels from this skill by the given amount.
Definition Skill.java:325
static final int FLETCHING
The fletching skill id.
Definition Skill.java:48
int level
The current level of the skill.
Definition Skill.java:173
static final int FIREMAKING
The firemaking skill id.
Definition Skill.java:54
static final int MAGIC
The magic skill id.
Definition Skill.java:39
static final int[][] INTERFACE_DATA
Skill tab string data.
Definition Skill.java:140
static final int ATTACK
The attack skill id.
Definition Skill.java:21
static final int FARMING
The farming skill id.
Definition Skill.java:78
static byte binarySearch(double experience, int min, int max)
Performs a binary search to quickly search for the level at the given experience.
Definition Skill.java:432
static final int AGILITY
The agility skill id.
Definition Skill.java:69
int getRoundedExperience()
Gets the floor experience.
Definition Skill.java:232
static Function< Integer, Integer > subtract(int amount)
Creates a function that subtracts a number by an amount.
Definition Skill.java:475
void multiplyExperience(double amount)
Multiplies the current experience of this skill by a given amount.
Definition Skill.java:410
int maxLevel
The maximum level of the skill.
Definition Skill.java:176
boolean clickNpc(Player player, NpcInteractionEvent event)
Definition Skill.java:505
static final int THIEVING
The thieving skill id.
Definition Skill.java:72
static final int HUNTER
The hunter skill id.
Definition Skill.java:87
static final int STRENGTH
The strength skill id.
Definition Skill.java:27
static final int COOKING
The cooking skill id.
Definition Skill.java:42
static final int getExperienceForLevel(int level)
Gets the experience for a given level.
Definition Skill.java:454
static final int MINING
The mining skill id.
Definition Skill.java:63
transient final Stopwatch stopwatch
Definition Skill.java:167
void addLevel(int amount)
Adds levels to this skill by the given amount.
Definition Skill.java:316
double modifyExperience(Function< Double, Double > function, int lowerBounds, int upperBounds)
Modifies the current experience with a given function.
Definition Skill.java:369
double modifyExperience(Function< Double, Double > function)
Modifies the current experience with a given function.
Definition Skill.java:354
void setDoingSkill(boolean doingSkill)
Definition Skill.java:489
double addExperience(double amount)
Adds experiences to this skill by the given amount.
Definition Skill.java:392
static Function< Integer, Integer > multiply(double amount)
Creates a function that multiplies a number by an amount.
Definition Skill.java:480
boolean clickObject(Player player, ObjectInteractionEvent event)
Definition Skill.java:509
boolean clickButton(Player player, ClickButtonInteractionEvent event)
Definition Skill.java:513
int getMaxLevel()
Gets the maximum skill level.
Definition Skill.java:214
static final int HITPOINTS
The hitpoints skill id.
Definition Skill.java:30
Skill(int skill, int level, double experience)
Constructs a new Skill.
Definition Skill.java:184
static final int RUNECRAFTING
The runecrafting skill id.
Definition Skill.java:81
void divideLevel(double amount)
Divides the current level of this skill by a given amount.
Definition Skill.java:343
static Stopwatch start()