55public class Skill implements InteractionEventListener {
76 public static final int MAGIC = 6;
133 private static final String[] SKILL_NAMES =
new String[]{
163 private static final int[] EXP_FOR_LEVEL = {
164 0, 83, 174, 276, 388, 512, 650, 801, 969, 1154, 1358, 1584, 1833, 2107,
165 2411, 2746, 3115, 3523, 3973, 4470, 5018, 5624, 6291, 7028, 7842, 8740,
166 9730, 10824, 12031, 13363, 14833, 16456, 18247, 20224, 22406, 24815, 27473,
167 30408, 33648, 37224, 41171, 45529, 50339, 55649, 61512, 67983, 75127, 83014,
168 91721, 101333, 111945, 123660, 136594, 150872, 166636, 184040, 203254, 224466,
169 247886, 273742, 302288, 333804, 368599, 407015, 449428, 496254, 547953, 605032,
170 668051, 737627, 814445, 899257, 992895, 1096278, 1210421, 1336443, 1475581,
171 1629200, 1798808, 1986068, 2192818, 2421087, 2673114, 2951373, 3258594, 3597792,
172 3972294, 4385776, 4842295, 5346332, 5902831, 6517253, 7195629, 7944614, 8771558,
173 9684577, 10692629, 11805606, 13034431
207 private final int skill;
213 private int maxLevel;
216 private double experience;
218 private boolean doingSkill =
false;
221 public Skill(
int skill,
int level,
double experience) {
225 this.experience = experience;
270 return (
int) experience;
288 this.maxLevel = maxLevel;
297 this.experience = experience;
308 return this.level >= level;
332 public void modifyLevel(Function<Integer, Integer>
function,
int lowerBounds,
int upperBounds) {
333 level =
function.apply(level);
338 if (level < lowerBounds) {
342 if (level > upperBounds) {
381 modifyLevel(level -> amount == 0 ? -level : (
int) (level / amount));
406 public double modifyExperience(Function<Double, Double>
function,
int lowerBounds,
int upperBounds) {
407 experience =
function.apply(experience);
409 if (experience < 0) {
412 if (experience < lowerBounds) {
413 experience = lowerBounds;
416 if (experience > upperBounds) {
417 experience = upperBounds;
457 modifyExperience(experience -> amount == 0 ? -experience : (experience / amount));
469 private static byte binarySearch(
double experience,
int min,
int max) {
470 int mid = (min + max) / 2;
471 double value = EXP_FOR_LEVEL[mid];
473 if (value > experience) {
474 return binarySearch(experience, min, mid - 1);
475 }
else if (value == (
int) experience || EXP_FOR_LEVEL[mid + 1] > experience) {
476 return (
byte) (mid + 1);
479 return binarySearch(experience, mid + 1, max);
484 if ((
int) experience >= EXP_FOR_LEVEL[98]) {
487 return binarySearch(experience, 0, 98);
493 return EXP_FOR_LEVEL[98];
498 return EXP_FOR_LEVEL[level - 1];
503 return SKILL_NAMES[skill];
507 public static Function<Integer, Integer>
add(
int amount) {
508 return level -> level + amount;
512 public static Function<Integer, Integer>
subtract(
int amount) {
513 return level -> level - amount;
517 public static Function<Integer, Integer>
multiply(
double amount) {
518 return level -> (int) (level * amount);
522 public static Function<Integer, Integer>
divide(
double amount) {
523 return level -> amount == 0 ? 0 : (int) (level / amount);
526 public void setDoingSkill(
boolean doingSkill) {
527 this.doingSkill = doingSkill;
530 public boolean isDoingSkill() {
534 protected double modifier() {
554 protected boolean useItem(Player player, ItemOnItemInteractionEvent event) {
558 protected boolean useItem(Player player, ItemOnObjectInteractionEvent event) {
562 protected boolean itemContainerAction(Player player, ItemContainerInteractionEvent event) {
567 public String toString() {
568 return String.format(
"Skill[name=%s, id=%s, level=%s, max=%s, experience=%s]",
getName(skill), skill, level, maxLevel, experience);
572 public boolean onEvent(Player player, InteractionEvent interactionEvent) {
573 final EventDispatcher dispatcher =
new EventDispatcher(interactionEvent);
574 dispatcher.dispatch(InteractionType.CLICK_BUTTON, e -> clickButton(player, (ClickButtonInteractionEvent) e));
575 dispatcher.dispatch(InteractionType.ITEM_ON_ITEM, e -> useItem(player, (ItemOnItemInteractionEvent) e));
576 dispatcher.dispatch(InteractionType.ITEM_ON_OBJECT, e -> useItem(player, (ItemOnObjectInteractionEvent) e));
578 dispatcher.dispatch(InteractionType.FIRST_ITEM_CLICK, e -> clickItem(player, (FirstItemClickInteractionEvent) e));
579 dispatcher.dispatch(InteractionType.SECOND_ITEM_CLICK, e -> clickItem(player, (SecondItemClickInteractionEvent) e));
580 dispatcher.dispatch(InteractionType.THIRD_ITEM_CLICK, e -> clickItem(player, (ThirdItemClickInteractionEvent) e));
582 dispatcher.dispatch(InteractionType.FIRST_CLICK_NPC, e -> clickNpc(player, (FirstNpcClick) e));
583 dispatcher.dispatch(InteractionType.SECOND_CLICK_NPC, e -> clickNpc(player, (SecondNpcClick) e));
584 dispatcher.dispatch(InteractionType.FIRST_CLICK_OBJECT, e -> clickObject(player, (FirstObjectClick) e));
585 dispatcher.dispatch(InteractionType.SECOND_CLICK_OBJECT, e -> clickObject(player, (SecondObjectClick) e));
586 dispatcher.dispatch(InteractionType.THIRD_CLICK_OBJECT, e -> clickObject(player, (ThirdObjectClick) e));
587 dispatcher.dispatch(InteractionType.ITEM_CONTAINER_INTERACTION_EVENT, e -> itemContainerAction(player, (ItemContainerInteractionEvent) e));
588 return interactionEvent.isHandled();