/** * Updates the player's max health and mana using class data. * * @param player player to update the health and mana for */ public void updateHealthAndMana(Player player) { if (player == null) { return; } // Update maxes double health = bonusHealth; maxMana = bonusMana; for (PlayerClass c : classes.values()) { health += c.getHealth(); maxMana += c.getMana(); } if (health == bonusHealth) { health += SkillAPI.getSettings().getDefaultHealth(); } if (health == 0) { health = 20; } if (SkillAPI.getSettings().isModifyHealth()) VersionManager.setMaxHealth(player, health); mana = Math.min(mana, maxMana); // Health scaling is available starting with 1.6.2 if (SkillAPI.getSettings().isModifyHealth() && VersionManager.isVersionAtLeast(VersionManager.V1_6_2)) { if (SkillAPI.getSettings().isOldHealth()) { player.setHealthScaled(true); player.setHealthScale(20); } else { player.setHealthScaled(false); } } }
/** * Handles attribute menu interaction * * @param event event details */ @EventHandler public void onClick(InventoryClickEvent event) { // Class selection if (InventoryManager.isMatching(event.getInventory(), MENU_KEY)) { // Do nothing when clicking outside the inventory if (event.getSlot() == -999) { return; } boolean top = event.getRawSlot() < event.getView().getTopInventory().getSize(); AttributeManager manager = SkillAPI.getAttributeManager(); // Interact with the skill tree when clicking in the top region if (top) { if (event.getSlot() < manager.getKeys().size() || event.getCursor() != null) { event.setCancelled(true); PlayerData data = SkillAPI.getPlayerData((Player) event.getWhoClicked()); if (event.isRightClick() && SkillAPI.getSettings().isAttributesDowngrade()) { data.refundAttribute(manager.getKeys().toArray()[event.getSlot()].toString()); } else if (event.isLeftClick()) { Object[] keys = manager.getKeys().toArray(); data.upAttribute(keys[event.getSlot()].toString()); } data.openAttributeMenu(); } } // Do not allow shift clicking items into the inventory else if (event.isShiftClick()) { event.setCancelled(true); } } }
/** * Resets the class data for the owner under the given group. This will remove the profession * entirely, leaving no remaining data until the player professes again to a starting class. * * @param group group to reset */ public void reset(String group) { stopPassives(getPlayer()); clearBonuses(); PlayerClass playerClass = classes.remove(group); if (playerClass != null) { // Remove skills RPGClass data = playerClass.getData(); for (Skill skill : data.getSkills()) { skills.remove(skill.getName()); combos.removeSkill(skill); } // Update GUI features if (getPlayer() != null) { ClassBoardManager.clear(new VersionPlayer(getPlayer())); } // Call the event Bukkit.getPluginManager().callEvent(new PlayerClassChangeEvent(playerClass, data, null)); } // Restore default class if applicable GroupSettings settings = SkillAPI.getSettings().getGroupSettings(group); RPGClass rpgClass = settings.getDefault(); if (rpgClass != null && settings.getPermission() == null) { setClass(rpgClass); } updateHealthAndMana(player.getPlayer()); }
/** * Retrieves the data of the professed class under the main class group. The "main" group is * determined by the setting in the config. * * @return main professed class data or null if not professed for the main group */ public PlayerClass getMainClass() { String main = SkillAPI.getSettings().getMainGroup(); if (classes.containsKey(main)) { return classes.get(main); } else if (classes.size() > 0) { return classes.values().toArray(new PlayerClass[classes.size()])[0]; } else { return null; } }
/** * Initializes a new account data representation for a player. * * @param player player to store the data for */ public PlayerData(OfflinePlayer player, boolean init) { this.player = player; this.skillBar = new PlayerSkillBar(this); this.combos = new PlayerCombos(this); this.init = SkillAPI.isLoaded() && init; this.scheme = "default"; for (String group : SkillAPI.getGroups()) { GroupSettings settings = SkillAPI.getSettings().getGroupSettings(group); RPGClass rpgClass = settings.getDefault(); if (rpgClass != null && settings.getPermission() == null) { setClass(rpgClass); } } }
/** Opens the attribute menu */ public void openAttributeMenu() { Player player = getPlayer(); if (SkillAPI.getSettings().isAttributesEnabled() && player != null) { AttributeManager manager = SkillAPI.getAttributeManager(); Inventory inv = InventoryManager.createInventory( AttributeListener.MENU_KEY, (manager.getKeys().size() + 8) / 9, "Attributes (" + attribPoints + " points)"); int i = 0; for (String key : manager.getKeys()) { ItemStack icon = manager.getAttribute(key).getIcon().clone(); ItemMeta meta = icon.getItemMeta(); meta.setDisplayName(meta.getDisplayName().replace("{amount}", "" + getAttribute(key))); icon.setItemMeta(meta); inv.setItem(i++, icon); } player.openInventory(inv); } }
/** * Professes the player into the class if they are able to. This will reset the class data if the * group options are set to reset upon profession. Otherwise, all skills, experience, and levels * of the current class under the group will be retained and carried over into the new profession. * * @param rpgClass class to profess into * @return true if successfully professed, false otherwise */ public boolean profess(RPGClass rpgClass) { if (rpgClass != null && canProfess(rpgClass)) { // Reset data if applicable if (SkillAPI.getSettings().getGroupSettings(rpgClass.getGroup()).isProfessReset()) { reset(rpgClass.getGroup()); } // Inherit previous class data if any PlayerClass current = classes.get(rpgClass.getGroup()); RPGClass previous; if (current == null) { previous = null; current = new PlayerClass(this, rpgClass); classes.put(rpgClass.getGroup(), current); } else { previous = current.getData(); current.setClassData(rpgClass); } // Add skills for (Skill skill : rpgClass.getSkills()) { if (!skills.containsKey(skill.getKey())) { skills.put(skill.getKey(), new PlayerSkill(this, skill, current)); combos.addSkill(skill); } } Bukkit.getPluginManager() .callEvent(new PlayerClassChangeEvent(current, previous, current.getData())); updateHealthAndMana(getPlayer()); updateScoreboard(); return true; } else { return false; } }
/** * Casts a skill for the player. In order to cast the skill, the player must be online, have the * skill unlocked, have enough mana, have the skill off cooldown, and have a proper target if * applicable. * * @param skill skill to cast * @return true if successfully cast the skill, false otherwise */ public boolean cast(PlayerSkill skill) { // Invalid skill if (skill == null) { throw new IllegalArgumentException("Skill cannot be null"); } SkillStatus status = skill.getStatus(); int level = skill.getLevel(); double cost = skill.getData().getManaCost(level); // Not unlocked if (level <= 0) { return false; } // On Cooldown if (status == SkillStatus.ON_COOLDOWN) { SkillAPI.getLanguage() .sendMessage( ErrorNodes.COOLDOWN, getPlayer(), FilterType.COLOR, RPGFilter.COOLDOWN.setReplacement(skill.getCooldown() + ""), RPGFilter.SKILL.setReplacement(skill.getData().getName())); } // Not enough mana else if (status == SkillStatus.MISSING_MANA) { SkillAPI.getLanguage() .sendMessage( ErrorNodes.MANA, getPlayer(), FilterType.COLOR, RPGFilter.SKILL.setReplacement(skill.getData().getName()), RPGFilter.MANA.setReplacement(getMana() + ""), RPGFilter.COST.setReplacement((int) Math.ceil(cost) + ""), RPGFilter.MISSING.setReplacement((int) Math.ceil(cost - getMana()) + "")); } // Skill Shots else if (skill.getData() instanceof SkillShot) { Player p = getPlayer(); PlayerCastSkillEvent event = new PlayerCastSkillEvent(this, skill, p); Bukkit.getPluginManager().callEvent(event); // Make sure it isn't cancelled if (!event.isCancelled()) { try { if (((SkillShot) skill.getData()).cast(p, level)) { skill.startCooldown(); if (SkillAPI.getSettings().isShowSkillMessages()) { skill.getData().sendMessage(p, SkillAPI.getSettings().getMessageRadius()); } if (SkillAPI.getSettings().isManaEnabled()) { useMana(cost, ManaCost.SKILL_CAST); } return true; } } catch (Exception ex) { Bukkit.getLogger() .severe( "Failed to cast skill - " + skill.getData().getName() + ": Internal skill error"); ex.printStackTrace(); } } } // Target Skills else if (skill.getData() instanceof TargetSkill) { Player p = getPlayer(); LivingEntity target = TargetHelper.getLivingTarget(p, skill.getData().getRange(level)); // Must have a target if (target == null) { return false; } PlayerCastSkillEvent event = new PlayerCastSkillEvent(this, skill, p); Bukkit.getPluginManager().callEvent(event); // Make sure it isn't cancelled if (!event.isCancelled()) { try { if (((TargetSkill) skill.getData()) .cast(p, target, level, !SkillAPI.getSettings().canAttack(p, target))) { skill.startCooldown(); if (SkillAPI.getSettings().isShowSkillMessages()) { skill.getData().sendMessage(p, SkillAPI.getSettings().getMessageRadius()); } if (SkillAPI.getSettings().isManaEnabled()) { useMana(cost, ManaCost.SKILL_CAST); } return true; } } catch (Exception ex) { Bukkit.getLogger() .severe( "Failed to cast skill - " + skill.getData().getName() + ": Internal skill error"); ex.printStackTrace(); } } } return false; }
/** * Starts a new task for regenerating mana over time. The task is started automatically so don't * initialize this class unless wanting to start a new task. * * @param plugin SkillAPI reference */ public ManaTask(SkillAPI plugin) { this.plugin = plugin; runTaskTimer( plugin, SkillAPI.getSettings().getGainFreq(), SkillAPI.getSettings().getGainFreq()); }