diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..50ec34d
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.project b/.project
new file mode 100644
index 0000000..acce0b5
--- /dev/null
+++ b/.project
@@ -0,0 +1,23 @@
+
+
+ ModRPG-git
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+
+
diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..e9441bb
--- /dev/null
+++ b/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
+encoding/=UTF-8
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..fbf1aac
--- /dev/null
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,16 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=11
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
+org.eclipse.jdt.core.compiler.release=enabled
+org.eclipse.jdt.core.compiler.source=11
diff --git a/.settings/org.eclipse.ltk.core.refactoring.prefs b/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000..b196c64
--- /dev/null
+++ b/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/blocked.yml b/blocked.yml
new file mode 100644
index 0000000..bfcdba3
--- /dev/null
+++ b/blocked.yml
@@ -0,0 +1,66 @@
+# All blocks with an inventory or any blocks that when right clicked shouldn't equip armor.
+blocked:
+ - FURNACE
+ - CHEST
+ - TRAPPED_CHEST
+ - BEACON
+ - DISPENSER
+ - DROPPER
+ - HOPPER
+ - WORKBENCH
+ - ENCHANTMENT_TABLE
+ - ENDER_CHEST
+ - ANVIL
+ - BED_BLOCK
+ - FENCE_GATE
+ - SPRUCE_FENCE_GATE
+ - BIRCH_FENCE_GATE
+ - ACACIA_FENCE_GATE
+ - JUNGLE_FENCE_GATE
+ - DARK_OAK_FENCE_GATE
+ - IRON_DOOR_BLOCK
+ - WOODEN_DOOR
+ - SPRUCE_DOOR
+ - BIRCH_DOOR
+ - JUNGLE_DOOR
+ - ACACIA_DOOR
+ - DARK_OAK_DOOR
+ - WOOD_BUTTON
+ - STONE_BUTTON
+ - TRAP_DOOR
+ - IRON_TRAPDOOR
+ - DIODE_BLOCK_OFF
+ - DIODE_BLOCK_ON
+ - REDSTONE_COMPARATOR_OFF
+ - REDSTONE_COMPARATOR_ON
+ - FENCE
+ - SPRUCE_FENCE
+ - BIRCH_FENCE
+ - JUNGLE_FENCE
+ - DARK_OAK_FENCE
+ - ACACIA_FENCE
+ - NETHER_FENCE
+ - BREWING_STAND
+ - CAULDRON
+ - SIGN_POST
+ - WALL_SIGN
+ - SIGN
+ - LEVER
+ - BLACK_SHULKER_BOX
+ - BLUE_SHULKER_BOX
+ - BROWN_SHULKER_BOX
+ - CYAN_SHULKER_BOX
+ - GRAY_SHULKER_BOX
+ - GREEN_SHULKER_BOX
+ - LIGHT_BLUE_SHULKER_BOX
+ - LIME_SHULKER_BOX
+ - MAGENTA_SHULKER_BOX
+ - ORANGE_SHULKER_BOX
+ - PINK_SHULKER_BOX
+ - PURPLE_SHULKER_BOX
+ - RED_SHULKER_BOX
+ - SILVER_SHULKER_BOX
+ - WHITE_SHULKER_BOX
+ - YELLOW_SHULKER_BOX
+ - DAYLIGHT_DETECTOR_INVERTED
+ - DAYLIGHT_DETECTOR
diff --git a/config.yml b/config.yml
new file mode 100644
index 0000000..06a6f33
--- /dev/null
+++ b/config.yml
@@ -0,0 +1,38 @@
+ManaDamage: 10
+TimeLimit: 60000
+SpeedMod: 0.015
+HPMod: 1
+MPMod: 1
+LUKAVD: 5
+LUKCRIT: 10
+BaseHP: 100
+BaseMP: 50
+BaseSpeed: 0.2
+ATKMod: 1
+SlotExpandRate: 0
+MaxSlot: 4
+MaxForge: 30
+RateOfNote: 20
+ManaRecover: 15
+HPRecover: 10
+DefaultAttackRange: 2
+HungerDamage: 15
+enableLeftAttack: true
+NoTick: true
+Worlds:
+ - test1
+ - lottery
+LeakArmorMod: 0.1
+ArrowEnchMod: 0.1
+StatusRandomMax: 3
+RequiredDamageDueToMobs: 0.3
+DeathPenaltyWorlds:
+ - world
+Penalty:
+ LevelLose: true
+ ClearRace: false
+ ResetStatus: true
+ MakeUp: true
+MakeUpSkills:
+ - ReturnsByDeath
+MakeUpMod: 0.3
\ No newline at end of file
diff --git a/forge.yml b/forge.yml
new file mode 100644
index 0000000..ec4e546
--- /dev/null
+++ b/forge.yml
@@ -0,0 +1,13 @@
+max:
+ slot:
+Random:
+ tier:
+ 0:
+ ...
+ 5:
+technique:
+ slot:
+ tier:
+ 0:
+ ...
+ 24:
\ No newline at end of file
diff --git a/mobs.yml b/mobs.yml
new file mode 100644
index 0000000..91da9a6
--- /dev/null
+++ b/mobs.yml
@@ -0,0 +1,7 @@
+level:
+ Method1:
+ MobType: Amount
+ MobType: Amount
+ Method2:
+ MobType: Amount
+ MobType: Amount
diff --git a/plugin.yml b/plugin.yml
new file mode 100644
index 0000000..a0cb67c
--- /dev/null
+++ b/plugin.yml
@@ -0,0 +1,37 @@
+main: nashi.NRPG.Main
+api-version: 1.14
+name: NRPG
+version: '2.0'
+description: RPG plugin with potion, races and skills
+softdepend:
+- MythicMobs
+- ProtocolLib
+author: Nashi
+commands:
+ nrpg:
+ description: base command
+ usage: /nrpg
+ stat:
+ description: stat command
+ usage: /stat
+ skilledit:
+ description: edit skill command
+ usage: /skilledit
+ cast:
+ description: change cast time command
+ usage: /cast ticks
+ slot:
+ description: modify skillslot command
+ usage: /slot
+ scale:
+ description: modify heal scale command
+ usage: /scale
+ abandon:
+ description: abandon skill command
+ usage: /abandon
+ reset:
+ description: reset command
+ usage: /reset
+ race:
+ description: race command
+ usage: /race
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..8a6d081
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,38 @@
+
+ 4.0.0
+
+ nashi
+ NRPG
+ 0.0.1-SNAPSHOT
+ jar
+
+ NRPG
+ http://maven.apache.org
+
+
+ UTF-8
+
+
+
+ spigotmc-repo
+ https://hub.spigotmc.org/nexus/content/repositories/snapshots/
+
+
+
+ dmulloy2-repo
+ http://repo.dmulloy2.net/nexus/repository/public/
+
+
+
+
+
+
+ junit
+ junit
+ 3.8.1
+ test
+
+
+
diff --git a/races.yml b/races.yml
new file mode 100644
index 0000000..f1b2f97
--- /dev/null
+++ b/races.yml
@@ -0,0 +1,44 @@
+RaceName:
+ default: true
+ DisplayName:
+ Info:
+ SkillList:
+ - skillname
+ Mod:
+ Slot:
+ ATK:
+ LUK:
+ Speed:
+ MP:
+ HP:
+ Items:
+ Helmet:
+ enable: true
+ DisplayName:
+ Material:
+ Color: r,g,b
+ damage:
+ Chestplate:
+ enable: true
+ DisplayName:
+ Material:
+ Color: r,g,b
+ damage:
+ Leggings:
+ enable: true
+ DisplayName:
+ Material:
+ Color: r,g,b
+ damage:
+ Boots:
+ enable: true
+ DisplayName:
+ Material:
+ Color: r,g,b
+ damage:
+ OffHand:
+ enable: true
+ DisplayName:
+ Material:
+ Color: r,g,b
+ damage:
\ No newline at end of file
diff --git a/skills.yml b/skills.yml
new file mode 100644
index 0000000..695b5cb
--- /dev/null
+++ b/skills.yml
@@ -0,0 +1,9 @@
+Skillname:
+ Info:
+ var: double
+ CostMP: double
+ Description: String
+ Difficulty: int
+ Times: int
+ general: boolean
+
\ No newline at end of file
diff --git a/src/main/java/edited/com/codingforcookies/armorequip/AfterArmorEquipEvent.java b/src/main/java/edited/com/codingforcookies/armorequip/AfterArmorEquipEvent.java
new file mode 100644
index 0000000..4563c2a
--- /dev/null
+++ b/src/main/java/edited/com/codingforcookies/armorequip/AfterArmorEquipEvent.java
@@ -0,0 +1,28 @@
+package edited.com.codingforcookies.armorequip;
+
+import org.bukkit.entity.Player;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+
+public final class AfterArmorEquipEvent extends PlayerEvent {
+ private static final HandlerList handlers = new HandlerList();
+ private static ArmorEquipEvent event;
+
+ public AfterArmorEquipEvent(Player player, ArmorEquipEvent event) {
+ super(player);
+ AfterArmorEquipEvent.event = event;
+ }
+
+ public static ArmorEquipEvent getEquipEvent() {
+ return event;
+ }
+
+ public static final HandlerList getHandlerList() {
+ return handlers;
+ }
+
+ public final HandlerList getHandlers() {
+ return handlers;
+ }
+
+}
diff --git a/src/main/java/edited/com/codingforcookies/armorequip/ArmorEquipEvent.java b/src/main/java/edited/com/codingforcookies/armorequip/ArmorEquipEvent.java
new file mode 100644
index 0000000..e403b10
--- /dev/null
+++ b/src/main/java/edited/com/codingforcookies/armorequip/ArmorEquipEvent.java
@@ -0,0 +1,141 @@
+package edited.com.codingforcookies.armorequip;
+
+import org.bukkit.entity.Player;
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+import org.bukkit.inventory.ItemStack;
+
+/**
+ * @author Arnah
+ * @since Jul 30, 2015
+ */
+public final class ArmorEquipEvent extends PlayerEvent implements Cancellable{
+
+ private static final HandlerList handlers = new HandlerList();
+ private boolean cancel = false;
+ private final EquipMethod equipType;
+ private final ArmorType type;
+ private ItemStack oldArmorPiece, newArmorPiece;
+
+ /**
+ * @param player The player who put on / removed the armor.
+ * @param type The ArmorType of the armor added
+ * @param oldArmorPiece The ItemStack of the armor removed.
+ * @param newArmorPiece The ItemStack of the armor added.
+ */
+ public ArmorEquipEvent(final Player player, final EquipMethod equipType, final ArmorType type, final ItemStack oldArmorPiece, final ItemStack newArmorPiece){
+ super(player);
+ this.equipType = equipType;
+ this.type = type;
+ this.oldArmorPiece = oldArmorPiece;
+ this.newArmorPiece = newArmorPiece;
+ }
+
+ /**
+ * Gets a list of handlers handling this event.
+ *
+ * @return A list of handlers handling this event.
+ */
+ public static HandlerList getHandlerList(){
+ return handlers;
+ }
+
+ /**
+ * Gets a list of handlers handling this event.
+ *
+ * @return A list of handlers handling this event.
+ */
+ @Override
+ public final HandlerList getHandlers(){
+ return handlers;
+ }
+
+ /**
+ * Sets if this event should be cancelled.
+ *
+ * @param cancel If this event should be cancelled.
+ */
+ public final void setCancelled(final boolean cancel){
+ this.cancel = cancel;
+ }
+
+ /**
+ * Gets if this event is cancelled.
+ *
+ * @return If this event is cancelled
+ */
+ public final boolean isCancelled(){
+ return cancel;
+ }
+
+ public final ArmorType getType(){
+ return type;
+ }
+
+ /**
+ * Returns the last equipped armor piece, could be a piece of armor, or null
+ */
+ public final ItemStack getOldArmorPiece(){
+ return oldArmorPiece;
+ }
+
+ public final void setOldArmorPiece(final ItemStack oldArmorPiece){
+ this.oldArmorPiece = oldArmorPiece;
+ }
+
+ /**
+ * Returns the newly equipped armor, could be a piece of armor, or null
+ */
+ public final ItemStack getNewArmorPiece(){
+ return newArmorPiece;
+ }
+
+ public final void setNewArmorPiece(final ItemStack newArmorPiece){
+ this.newArmorPiece = newArmorPiece;
+ }
+
+ /**
+ * Gets the method used to either equip or unequip an armor piece.
+ */
+ public EquipMethod getMethod(){
+ return equipType;
+ }
+
+ public enum EquipMethod{// These have got to be the worst documentations ever.
+ /**
+ * When you shift click an armor piece to equip or unequip
+ */
+ SHIFT_CLICK,
+ /**
+ * When you drag and drop the item to equip or unequip
+ */
+ DRAG,
+ /**
+ * When you manually equip or unequip the item. Use to be DRAG
+ */
+ PICK_DROP,
+ /**
+ * When you right click an armor piece in the hotbar without the inventory open to equip.
+ */
+ HOTBAR,
+ /**
+ * When you press the hotbar slot number while hovering over the armor slot to equip or unequip
+ */
+ HOTBAR_SWAP,
+ /**
+ * When in range of a dispenser that shoots an armor piece to equip.
+ * Requires the spigot version to have {@link org.bukkit.event.block.BlockDispenseArmorEvent} implemented.
+ */
+ DISPENSER,
+ /**
+ * When an armor piece is removed due to it losing all durability.
+ */
+ BROKE,
+ /**
+ * When you die causing all armor to unequip
+ */
+ DEATH,
+ ;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/edited/com/codingforcookies/armorequip/ArmorListener.java b/src/main/java/edited/com/codingforcookies/armorequip/ArmorListener.java
new file mode 100644
index 0000000..1fc53e9
--- /dev/null
+++ b/src/main/java/edited/com/codingforcookies/armorequip/ArmorListener.java
@@ -0,0 +1,291 @@
+package edited.com.codingforcookies.armorequip;
+
+import java.util.List;
+import org.bukkit.Bukkit;
+import org.bukkit.Material;
+import org.bukkit.Sound;
+import org.bukkit.entity.Player;
+import org.bukkit.event.Event.Result;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.block.Action;
+import org.bukkit.event.entity.PlayerDeathEvent;
+import org.bukkit.event.inventory.ClickType;
+import org.bukkit.event.inventory.InventoryAction;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.event.inventory.InventoryDragEvent;
+import org.bukkit.event.inventory.InventoryType;
+import org.bukkit.event.player.PlayerInteractEvent;
+import org.bukkit.event.player.PlayerItemBreakEvent;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.Damageable;
+import org.bukkit.inventory.meta.ItemMeta;
+
+import nashi.NRPG.Main;
+import nashi.NRPG.API.Utils;
+
+public class ArmorListener implements Listener {
+ private final List blockedMaterials;
+
+ public ArmorListener(List blockedMaterials) {
+ this.blockedMaterials = blockedMaterials;
+ }
+
+ @EventHandler
+ public final void inventoryClick(InventoryClickEvent e) {
+ boolean shift = false;
+ boolean numberkey = false;
+ if (e.isCancelled()) {
+ return;
+ }
+ if (e.getAction() == InventoryAction.NOTHING) {
+ return;
+ }
+ if ((e.getClick().equals(ClickType.SHIFT_LEFT)) || (e.getClick().equals(ClickType.SHIFT_RIGHT))) {
+ shift = true;
+ }
+ if (e.getClick().equals(ClickType.NUMBER_KEY)) {
+ numberkey = true;
+ }
+ if ((e.getSlotType() != InventoryType.SlotType.ARMOR) && (e.getSlotType() != InventoryType.SlotType.QUICKBAR)
+ && (e.getSlotType() != InventoryType.SlotType.CONTAINER)) {
+ return;
+ }
+ if ((e.getClickedInventory() != null) && (!e.getClickedInventory().getType().equals(InventoryType.PLAYER))) {
+ return;
+ }
+ if ((!e.getInventory().getType().equals(InventoryType.CRAFTING))
+ && (!e.getInventory().getType().equals(InventoryType.PLAYER))) {
+ return;
+ }
+ if (!(e.getWhoClicked() instanceof Player)) {
+ return;
+ }
+ ArmorType newArmorType = ArmorType.matchType(shift ? e.getCurrentItem() : e.getCursor());
+ if ((!shift) && (newArmorType != null) && (e.getRawSlot() != newArmorType.getSlot())) {
+ return;
+ }
+ if (shift) {
+ newArmorType = ArmorType.matchType(e.getCurrentItem());
+ if (newArmorType != null) {
+ boolean equipping = true;
+ if (e.getRawSlot() == newArmorType.getSlot()) {
+ equipping = false;
+ }
+ if ((!newArmorType.equals(ArmorType.HELMET))
+ || (equipping ? !isAirOrNull(e.getWhoClicked().getInventory().getHelmet())
+ : isAirOrNull(e.getWhoClicked().getInventory().getHelmet()))) {
+ if ((!newArmorType.equals(ArmorType.CHESTPLATE))
+ || (equipping ? !isAirOrNull(e.getWhoClicked().getInventory().getChestplate())
+ : isAirOrNull(e.getWhoClicked().getInventory().getChestplate()))) {
+ if ((!newArmorType.equals(ArmorType.LEGGINGS))
+ || (equipping ? !isAirOrNull(e.getWhoClicked().getInventory().getLeggings())
+ : isAirOrNull(e.getWhoClicked().getInventory().getLeggings()))) {
+ if ((!newArmorType.equals(ArmorType.BOOTS))
+ || (equipping ? !isAirOrNull(e.getWhoClicked().getInventory().getBoots())
+ : isAirOrNull(e.getWhoClicked().getInventory().getBoots()))) {
+ return;
+ }
+ }
+ }
+ }
+ ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent((Player) e.getWhoClicked(),
+ ArmorEquipEvent.EquipMethod.SHIFT_CLICK, newArmorType, equipping ? null : e.getCurrentItem(),
+ equipping ? e.getCurrentItem() : null);
+ Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent);
+ if (armorEquipEvent.isCancelled()) {
+ e.setCancelled(true);
+ }
+ Bukkit.getScheduler().scheduleSyncDelayedTask(Main.getPlugin(), new Runnable() {
+ @Override
+ public void run() {
+ AfterArmorEquipEvent ae = new AfterArmorEquipEvent((Player) e.getWhoClicked(), armorEquipEvent);
+ Bukkit.getServer().getPluginManager().callEvent(ae);
+ }
+ }, 5L);
+ }
+ } else {
+ ItemStack newArmorPiece = e.getCursor();
+ ItemStack oldArmorPiece = e.getCurrentItem();
+ if (numberkey) {
+ if (e.getClickedInventory().getType().equals(InventoryType.PLAYER)) {
+ ItemStack hotbarItem = e.getClickedInventory().getItem(e.getHotbarButton());
+ if (!isAirOrNull(hotbarItem)) {
+ newArmorType = ArmorType.matchType(hotbarItem);
+ newArmorPiece = hotbarItem;
+ oldArmorPiece = e.getClickedInventory().getItem(e.getSlot());
+ } else {
+ newArmorType = ArmorType
+ .matchType(!isAirOrNull(e.getCurrentItem()) ? e.getCurrentItem() : e.getCursor());
+ }
+ }
+ } else if ((isAirOrNull(e.getCursor())) && (!isAirOrNull(e.getCurrentItem()))) {
+ newArmorType = ArmorType.matchType(e.getCurrentItem());
+ }
+ if ((newArmorType != null) && (e.getRawSlot() == newArmorType.getSlot())) {
+ ArmorEquipEvent.EquipMethod method = ArmorEquipEvent.EquipMethod.PICK_DROP;
+ if ((e.getAction().equals(InventoryAction.HOTBAR_SWAP)) || (numberkey)) {
+ method = ArmorEquipEvent.EquipMethod.HOTBAR_SWAP;
+ }
+ ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent((Player) e.getWhoClicked(), method, newArmorType,
+ oldArmorPiece, newArmorPiece);
+ Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent);
+ if (armorEquipEvent.isCancelled()) {
+ e.setCancelled(true);
+ }
+ Bukkit.getScheduler().scheduleSyncDelayedTask(Main.getPlugin(), new Runnable() {
+ @Override
+ public void run() {
+ AfterArmorEquipEvent ae = new AfterArmorEquipEvent((Player) e.getWhoClicked(), armorEquipEvent);
+ Bukkit.getServer().getPluginManager().callEvent(ae);
+ }
+ }, 5L);
+ }
+ }
+ }
+
+ @EventHandler
+ public void playerInteractEvent(PlayerInteractEvent e) {
+ if (e.getAction() == Action.PHYSICAL) {
+ return;
+ }
+ if ((e.getAction() == Action.RIGHT_CLICK_AIR) || (e.getAction() == Action.RIGHT_CLICK_BLOCK)) {
+ Player player = e.getPlayer();
+ Material mat;
+ if ((e.getClickedBlock() != null) && (e.getAction() == Action.RIGHT_CLICK_BLOCK)) {
+ mat = e.getClickedBlock().getType();
+ for (String s : this.blockedMaterials) {
+ if (mat.name().equalsIgnoreCase(s)) {
+ return;
+ }
+ }
+ }
+ ArmorType newArmorType = ArmorType.matchType(e.getItem());
+ if ((newArmorType != null) && (((newArmorType.equals(ArmorType.HELMET))
+ && (isAirOrNull(e.getPlayer().getInventory().getHelmet())))
+ || ((newArmorType.equals(ArmorType.CHESTPLATE))
+ && (isAirOrNull(e.getPlayer().getInventory().getChestplate())))
+ || ((newArmorType.equals(ArmorType.LEGGINGS))
+ && (isAirOrNull(e.getPlayer().getInventory().getLeggings())))
+ || ((newArmorType.equals(ArmorType.BOOTS))
+ && (isAirOrNull(e.getPlayer().getInventory().getBoots()))))) {
+ ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(e.getPlayer(), ArmorEquipEvent.EquipMethod.HOTBAR,
+ ArmorType.matchType(e.getItem()), null, e.getItem());
+ Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent);
+ if (armorEquipEvent.isCancelled()) {
+ e.setCancelled(true);
+ player.updateInventory();
+ } else {
+ switch (newArmorType) {
+ case CHESTPLATE:
+ player.getInventory().setChestplate(e.getItem().clone());
+ break;
+ case BOOTS:
+ player.getInventory().setBoots(e.getItem().clone());
+ break;
+ case HELMET:
+ player.getInventory().setHelmet(e.getItem().clone());
+ break;
+ case LEGGINGS:
+ player.getInventory().setLeggings(e.getItem().clone());
+ break;
+ }
+ e.getItem().setAmount(0);
+ Bukkit.getScheduler().scheduleSyncDelayedTask(Main.getPlugin(), new Runnable() {
+ @Override
+ public void run() {
+ AfterArmorEquipEvent ae = new AfterArmorEquipEvent(player, armorEquipEvent);
+ Bukkit.getServer().getPluginManager().callEvent(ae);
+ }
+ }, 5L);
+ }
+ }
+ }
+ }
+
+ @EventHandler
+ public void inventoryDrag(InventoryDragEvent event) {
+ ArmorType type = ArmorType.matchType(event.getOldCursor());
+ if (event.getRawSlots().isEmpty()) {
+ return;
+ }
+ if ((type != null)
+ && (type.getSlot() == ((Integer) event.getRawSlots().stream().findFirst().orElse(Integer.valueOf(0)))
+ .intValue())) {
+ ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent((Player) event.getWhoClicked(),
+ ArmorEquipEvent.EquipMethod.DRAG, type, null, event.getOldCursor());
+ Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent);
+ if (armorEquipEvent.isCancelled()) {
+ event.setResult(Result.DENY);
+ event.setCancelled(true);
+ }
+ }
+ }
+
+ @EventHandler
+ public void itemBreakEvent(PlayerItemBreakEvent e) {
+ ArmorType type = ArmorType.matchType(e.getBrokenItem());
+ if (type != null) {
+ Player p = e.getPlayer();
+ ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(p, ArmorEquipEvent.EquipMethod.BROKE, type,
+ e.getBrokenItem(), null);
+ Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent);
+ if (armorEquipEvent.isCancelled()) {
+ ItemStack i = e.getBrokenItem().clone();
+ i.setAmount(1);
+
+ ItemMeta im = i.getItemMeta();
+ ((Damageable) im).setDamage(((Damageable) im).getDamage() - 1);
+ i.setItemMeta(im);
+
+ if (type.equals(ArmorType.HELMET)) {
+ p.getInventory().setHelmet(i);
+ } else if (type.equals(ArmorType.CHESTPLATE)) {
+ p.getInventory().setChestplate(i);
+ } else if (type.equals(ArmorType.LEGGINGS)) {
+ p.getInventory().setLeggings(i);
+ } else if (type.equals(ArmorType.BOOTS)) {
+ p.getInventory().setBoots(i);
+ }
+ } else {
+ switch (type) {
+ case CHESTPLATE:
+ p.getInventory().setChestplate(null);
+ break;
+ case BOOTS:
+ p.getInventory().setBoots(null);
+ break;
+ case HELMET:
+ p.getInventory().setHelmet(null);
+ break;
+ case LEGGINGS:
+ p.getInventory().setLeggings(null);
+ break;
+ }
+ p.getWorld().playSound(p.getLocation(), Sound.ENTITY_ITEM_BREAK, 2, 2);
+ Bukkit.getScheduler().scheduleSyncDelayedTask(Main.getPlugin(), new Runnable() {
+ @Override
+ public void run() {
+ AfterArmorEquipEvent ae = new AfterArmorEquipEvent(p, armorEquipEvent);
+ Bukkit.getServer().getPluginManager().callEvent(ae);
+ }
+ }, 5L);
+ }
+ }
+ }
+
+ @EventHandler
+ public void playerDeathEvent(PlayerDeathEvent e) {
+ Player p = e.getEntity();
+ for (ItemStack i : p.getInventory().getArmorContents()) {
+ if (!isAirOrNull(i)) {
+ Bukkit.getServer().getPluginManager().callEvent(
+ new ArmorEquipEvent(p, ArmorEquipEvent.EquipMethod.DEATH, ArmorType.matchType(i), i, null));
+ }
+ }
+ }
+
+ private boolean isAirOrNull(ItemStack item) {
+ return (item == null) || (item.getType().equals(Material.AIR) || Utils.isNotDrop(item));
+ }
+}
diff --git a/src/main/java/edited/com/codingforcookies/armorequip/ArmorType.java b/src/main/java/edited/com/codingforcookies/armorequip/ArmorType.java
new file mode 100644
index 0000000..6fc877c
--- /dev/null
+++ b/src/main/java/edited/com/codingforcookies/armorequip/ArmorType.java
@@ -0,0 +1,38 @@
+package edited.com.codingforcookies.armorequip;
+
+import org.bukkit.Material;
+import org.bukkit.inventory.ItemStack;
+
+public enum ArmorType {
+ HELMET(5), CHESTPLATE(6), LEGGINGS(7), BOOTS(8);
+
+ private final int slot;
+
+ private ArmorType(int slot) {
+ this.slot = slot;
+ }
+
+ public static final ArmorType matchType(ItemStack itemStack) {
+ if ((itemStack == null) || (itemStack.getType().equals(Material.AIR))) {
+ return null;
+ }
+ String type = itemStack.getType().name();
+ if ((type.endsWith("_HELMET")) || (type.endsWith("_SKULL"))) {
+ return HELMET;
+ }
+ if (type.endsWith("_CHESTPLATE")) {
+ return CHESTPLATE;
+ }
+ if (type.endsWith("_LEGGINGS")) {
+ return LEGGINGS;
+ }
+ if (type.endsWith("_BOOTS")) {
+ return BOOTS;
+ }
+ return null;
+ }
+
+ public int getSlot() {
+ return this.slot;
+ }
+}
diff --git a/src/main/java/edited/com/codingforcookies/armorequip/DispenserArmorListener.java b/src/main/java/edited/com/codingforcookies/armorequip/DispenserArmorListener.java
new file mode 100644
index 0000000..5da73b1
--- /dev/null
+++ b/src/main/java/edited/com/codingforcookies/armorequip/DispenserArmorListener.java
@@ -0,0 +1,43 @@
+package edited.com.codingforcookies.armorequip;
+
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.block.BlockDispenseArmorEvent;
+import org.bukkit.inventory.ItemStack;
+
+public class DispenserArmorListener implements Listener {
+ @EventHandler
+ public void dispenseArmorEvent(BlockDispenseArmorEvent event) {
+ ArmorType type = ArmorType.matchType(event.getItem());
+ if ((type != null) && ((event.getTargetEntity() instanceof Player))) {
+ Player p = (Player) event.getTargetEntity();
+ ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(p, ArmorEquipEvent.EquipMethod.DISPENSER, type, null,
+ event.getItem());
+ Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent);
+ if (armorEquipEvent.isCancelled()) {
+ event.setCancelled(true);
+ } else {
+ event.setCancelled(true);
+ ItemStack item = event.getItem().clone();
+ switch (type) {
+ case CHESTPLATE:
+ p.getInventory().setChestplate(item);
+ break;
+ case BOOTS:
+ p.getInventory().setBoots(item);
+ break;
+ case HELMET:
+ p.getInventory().setHelmet(item);
+ break;
+ case LEGGINGS:
+ p.getInventory().setLeggings(item);
+ break;
+ }
+ AfterArmorEquipEvent ae = new AfterArmorEquipEvent(p, armorEquipEvent);
+ Bukkit.getServer().getPluginManager().callEvent(ae);
+ }
+ }
+ }
+}
diff --git a/src/main/java/nashi/NRPG/API/SkillAPI.java b/src/main/java/nashi/NRPG/API/SkillAPI.java
new file mode 100644
index 0000000..4e14bf0
--- /dev/null
+++ b/src/main/java/nashi/NRPG/API/SkillAPI.java
@@ -0,0 +1,346 @@
+package nashi.NRPG.API;
+
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.World;
+import org.bukkit.attribute.Attribute;
+import org.bukkit.block.Block;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.entity.ArmorStand;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.entity.Player;
+import org.bukkit.plugin.Plugin;
+import org.bukkit.scheduler.BukkitRunnable;
+import org.bukkit.util.Vector;
+
+import nashi.NRPG.Main;
+import nashi.NRPG.Players.Players;
+import nashi.NRPG.Players.Players.PlayerData;
+import nashi.NRPG.Skills.Skill;
+import nashi.NRPG.listeners.EventListener;
+import nashi.NRPG.listeners.ModifyItem;
+import nashi.NRPG.listeners.EventListener.Casting;
+
+public class SkillAPI {
+ public static HashMap Silence = new HashMap();
+
+ public static void setSilenceTime(Player player, long ms) {
+ Silence.put(player.getUniqueId(), System.currentTimeMillis() + ms);
+ }
+
+ public static PlayerData getPlayerData(Player player) {
+ return Players.Data.get(player);
+ }
+
+ public static boolean inSkillMode(Player player) {
+ return EventListener.skillmode.get(player);
+ }
+
+ public static Casting getCast(Player player) {
+ if (EventListener.cast.containsKey(player)) {
+ return EventListener.cast.get(player);
+ }
+ return null;
+ }
+
+ public static void setPlayerMaxAttackRange(Player player, double range) {
+ ModifyItem.edit.put(player, range);
+ }
+
+ public static void resetPlayerMaxAttackRange(Player player, double range) {
+ if (ModifyItem.edit.containsKey(player)) {
+ ModifyItem.edit.remove(player);
+ }
+ }
+
+ public static void damage(LivingEntity e, Player player, double amount) {
+ ModifyItem.edit.put(player, Double.MAX_VALUE);
+ e.damage(amount + player.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE).getValue(), player);
+ ModifyItem.edit.remove(player);
+ }
+
+ public static long getRemainingSilenceTime(Player player) {
+ return Silence.get(player.getUniqueId()) - System.currentTimeMillis();
+ }
+
+ public static boolean costMP(Player player, double MP) {
+ return Players.Data.get(player).costMP(MP);
+ }
+
+ private static final Set containerTypes = EnumSet.of(Material.CHEST, Material.DROPPER, Material.HOPPER,
+ Material.DISPENSER, Material.TRAPPED_CHEST, Material.BREWING_STAND, Material.FURNACE,
+ Material.BLAST_FURNACE, Material.CHEST_MINECART, Material.BLACK_SHULKER_BOX, Material.BLUE_SHULKER_BOX,
+ Material.BROWN_SHULKER_BOX, Material.CYAN_SHULKER_BOX, Material.GRAY_SHULKER_BOX,
+ Material.GREEN_SHULKER_BOX, Material.ENDER_CHEST, Material.BARREL, Material.BEACON, Material.JUKEBOX,
+ Material.NOTE_BLOCK, Material.COMMAND_BLOCK, Material.COMMAND_BLOCK_MINECART, Material.CHAIN_COMMAND_BLOCK,
+ Material.ITEM_FRAME);
+
+ public static boolean isContainer(Material mat) {
+ return containerTypes.contains(mat);
+ }
+
+ public static List getEntityFromLoc(Location loc, int range) {
+ List near = loc.getWorld().getLivingEntities();
+ ArrayList l = new ArrayList();
+ for (LivingEntity target : near) {
+ if ((target.getLocation().distance(loc) <= range) && (!(target instanceof ArmorStand))) {
+ l.add(target);
+ }
+ }
+ return l;
+ }
+
+ public static List blocksFromTwoPoints(Location loc1, Location loc2, World w) {
+ List blocks = new ArrayList();
+
+ int minx = Math.min(loc1.getBlockX(), loc2.getBlockX()), miny = Math.min(loc1.getBlockY(), loc2.getBlockY()),
+ minz = Math.min(loc1.getBlockZ(), loc2.getBlockZ()),
+ maxx = Math.max(loc1.getBlockX(), loc2.getBlockX()),
+ maxy = Math.max(loc1.getBlockY(), loc2.getBlockY()),
+ maxz = Math.max(loc1.getBlockZ(), loc2.getBlockZ());
+ for (int x = minx; x <= maxx; x++) {
+ for (int y = miny; y <= maxy; y++) {
+ for (int z = minz; z <= maxz; z++) {
+ Block b = w.getBlockAt(x, y, z);
+ if (b.getType() != Material.AIR) {
+ blocks.add(b);
+ }
+ }
+ }
+ }
+
+ return blocks;
+ }
+
+ /**
+ * 用於計算拋物線的重力加速度,必須為負數。
+ */
+ private static final double G = -9.8;
+ /**
+ * 拋物線運動時的速度加快倍數,數字越大,速度越快。
+ */
+ private static final double SPEED = 1;
+ /**
+ * 變更運動方向的週期。
+ */
+ private static final long PERIOD = 1;
+
+ /**
+ * 將目標推離玩家。
+ *
+ * @param player 玩家
+ * @param target 要推離的目標
+ * @param distance 離地到落地的距離
+ * @param rad 起飛角度
+ */
+ public static void push(Player player, Entity target, double distance, double rad) {
+ Location playerLocation = player.getLocation();
+ Location targetLocation = target.getLocation();
+
+ Vector vector = getDirection(playerLocation, targetLocation);
+
+ move(target, vector, distance, rad);
+ }
+
+ public static void push(Location loc, Entity target, double distance, double rad) {
+ Location targetLocation = target.getLocation();
+
+ Vector vector = getDirection(loc, targetLocation);
+
+ move(target, vector, distance, rad);
+ }
+
+ /**
+ * 將目標拉進玩家。
+ *
+ * @param player 玩家
+ * @param target 要拉進的目標
+ * @param distance 離地到落地的距離
+ * @param rad 起飛角度
+ */
+ public static void pull(Player player, Entity target, double distance, double rad) {
+ Location playerLocation = player.getLocation();
+ Location targetLocation = target.getLocation();
+
+ Vector vector = getDirection(targetLocation, playerLocation);
+
+ move(target, vector, distance, rad);
+ }
+
+ public static void pull(Location loc, Entity target, double distance, double rad) {
+ Location targetLocation = target.getLocation();
+
+ Vector vector = getDirection(targetLocation, loc);
+
+ move(target, vector, distance, rad);
+ }
+
+ /**
+ * 取得某個點朝向另一個點的方向。
+ */
+ private static Vector getDirection(Location from, Location to) {
+ return new Vector(to.getX() - from.getX(), to.getY() - from.getY(), to.getZ() - from.getZ());
+ }
+
+ /**
+ * 將目標朝向指定方向以指定弧度拋出。
+ *
+ * @param target 目標
+ * @param vector 方向
+ * @param distance 起飛到落地的距離
+ * @param rad 弧度(單位是 rad)
+ */
+ private static void move(Entity target, Vector vector, double distance, double rad) {
+
+ double v = Math.sqrt((G / (-Math.tan(rad) * Math.cos(rad) * Math.cos(rad))) * distance / 2);
+ double vx = v * Math.cos(rad);
+
+ double coefficient1 = (G / (2 * v * v * Math.cos(rad) * Math.cos(rad)));
+ double coefficient2 = Math.tan(rad);
+
+ vector.normalize().setY(0);
+
+ new BukkitRunnable() {
+
+ private Location last = new Location(target.getWorld(), 0, 0, 0);
+ double now = 0;
+
+ @Override
+ public void run() {
+ double x = vx / 20 * now;
+ if (x > distance) {
+ this.cancel();
+ return;
+ }
+ double y = coefficient1 * x * x + coefficient2 * x;
+
+ Location end = vector.clone().multiply(x).setY(y).toLocation(target.getWorld());
+ Vector move = getDirection(last, end);
+ try {
+ target.setVelocity(move);
+ } catch (Exception e) {
+ this.cancel();
+ }
+ last = end;
+
+ now += PERIOD * SPEED;
+
+ }
+
+ }.runTaskTimer(Main.getPlugin(), 0, PERIOD);
+
+ }
+
+ public static Vector getRightDirection(Location l) {
+ Vector direction = l.getDirection().normalize();
+ return new Vector(-direction.getZ(), 0.0, direction.getX()).normalize();
+ }
+
+ public static Vector getLeftDirection(Location l) {
+ Vector direction = l.getDirection().normalize();
+ return new Vector(direction.getZ(), 0.0, -direction.getX()).normalize();
+ }
+
+ public static LivingEntity getEntityInLineOfSight(Player player, double range) {
+ ArrayList entities = (ArrayList) player.getNearbyEntities(range, range, range);
+ ArrayList sightBlock = (ArrayList) player.getLineOfSight((Set) null, (int) range);
+ ArrayList sight = new ArrayList();
+ for (int i = 0; i < sightBlock.size(); i++) {
+ Block b = sightBlock.get(i);
+ if (!Utils.transparentBlocks.contains(b.getType())) {
+ break;
+ }
+ sight.add(sightBlock.get(i).getLocation());
+ }
+ for (int i = 0; i < sight.size(); i++) {
+ for (int k = 0; k < entities.size(); k++) {
+ if (Math.abs(entities.get(k).getLocation().getX() - sight.get(i).getX()) < 1.3) {
+ if (Math.abs(entities.get(k).getLocation().getY() - sight.get(i).getY()) < 1.5) {
+ if (Math.abs(entities.get(k).getLocation().getZ() - sight.get(i).getZ()) < 1.3) {
+ if (entities.get(k) instanceof LivingEntity && (!(entities.get(k) instanceof ArmorStand))) {
+ return (LivingEntity) entities.get(k);
+ }
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ public static List getNearEntity(Player player, int range) {
+ List near = player.getLocation().getWorld().getLivingEntities();
+ ArrayList l = new ArrayList();
+ for (LivingEntity target : near) {
+ if (target.getLocation().distance(player.getLocation()) <= range && target != player
+ && (!(target instanceof ArmorStand))) {
+ l.add(target);
+ }
+ }
+ return l;
+ }
+
+ public static List getNumbersTargetsFromList(List List, int maxtargets) {
+ if (List.size() <= maxtargets) {
+ return List;
+ } else {
+ int i;
+ List l = new ArrayList();
+ for (i = 0; i <= maxtargets; i++) {
+ LivingEntity le = List.get(i);
+ l.add(le);
+ }
+ return l;
+ }
+ }
+
+ public static double getSkillInfo(Player player, String skillname, String Info) {
+ YamlConfiguration pf = Players.getYaml(player);
+ return pf.getDouble("Skills." + skillname + ".Custom." + Info);
+ }
+
+ public static double getPublicSkillInfo(String skillname, String Info) {
+ YamlConfiguration f = Players.skillsetting;
+ return f.getDouble(skillname + "." + Info);
+ }
+
+ public static boolean getSkillPublicBoolean(String skillname, String Info) {
+ YamlConfiguration f = Players.skillsetting;
+ return f.getBoolean(skillname + "." + Info);
+ }
+
+ public static Location BlockLocPlayerLook(Player player, int maxdistance) {
+ Block block = player.getTargetBlock((Set) null, maxdistance);
+ Location bl = block.getLocation();
+ return bl;
+ }
+
+ public static long getRemainingCooldown(Player player, String skillname) {
+ if (Skill.cooldowns.containsKey(player.getUniqueId() + "." + skillname)) {
+ return Skill.cooldowns.get(player.getUniqueId() + "." + skillname) - System.currentTimeMillis();
+ } else {
+ return 0;
+ }
+ }
+
+ public static Vector getPlayerLookDir(Player player) {
+ return player.getLocation().getDirection();
+ }
+
+ public static void setCooldown(Player player, String skillname, long CD) {
+ Skill.cooldowns.put(player.getUniqueId() + "." + skillname, System.currentTimeMillis() + CD);
+ }
+
+ public static Plugin plugin() {
+ return Main.getPlugin();
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/nashi/NRPG/API/Utils.java b/src/main/java/nashi/NRPG/API/Utils.java
new file mode 100644
index 0000000..0255c02
--- /dev/null
+++ b/src/main/java/nashi/NRPG/API/Utils.java
@@ -0,0 +1,370 @@
+package nashi.NRPG.API;
+
+import java.io.File;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Random;
+
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.Material;
+import org.bukkit.NamespacedKey;
+import org.bukkit.World;
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+import org.bukkit.persistence.PersistentDataContainer;
+import org.bukkit.persistence.PersistentDataType;
+import org.bukkit.scheduler.BukkitRunnable;
+
+import nashi.NRPG.Main;
+import nashi.NRPG.Items.CreateItem;
+import nashi.NRPG.Players.Leveling;
+import nashi.NRPG.Players.Players;
+import nashi.NRPG.Players.Races;
+import nashi.NRPG.Skills.Cast;
+import nashi.NRPG.Skills.Skill;
+import nashi.NRPG.Skills.SkillName;
+import nashi.NRPG.Skills.Skill.Skills;
+import nashi.NRPG.listeners.AllAboutDamage;
+
+public class Utils {
+ public static boolean Penalty_MakeUp;
+ private static HashMap playerstatus = new HashMap();
+ public static Random rand = new Random();
+ public static double manaDMG;
+ public static float SPDSpeed;
+ public static double HPHealth;
+ public static double ManaMP;
+ public static double LUKAVD;
+ public static double LUKCRIT;
+ public static double basehp;
+ public static double basemp;
+ public static float basespd;
+ public static List transparentBlocks = new ArrayList();
+ public static int MaxSlot;
+ public static int RMP;
+ public static int RHP;
+ public static NamespacedKey key = new NamespacedKey(Main.getPlugin(), "NRPG_Consumables");
+ public static double defaultattackrange;
+ public static double hunger;
+ public static double exarmor;
+ public static double arrowdamagemod;
+ public static int STATRAND;
+ public static double PercentDamageLVL;
+ public static List deathpenworld = new ArrayList();
+ public static boolean Penalty_LVL;
+ public static boolean Penalty_Race;
+ public static boolean Penalty_Status;
+ public static List MakeUpSkills = new ArrayList();
+ public static double MakeUpMod;
+
+ public static void additem(Player player, ItemStack item) {
+ if (item == null) {
+ return;
+ }
+ if (player.getInventory().firstEmpty() != -1) {
+ player.getInventory().addItem(item);
+ } else {
+ player.getWorld().dropItem(player.getLocation(), item);
+ }
+ }
+
+ public static void util() {
+ transparentBlocks.clear();
+ transparentBlocks.add(Material.CAVE_AIR);
+ transparentBlocks.add(Material.AIR);
+ transparentBlocks.add(Material.BLACK_CARPET);
+ transparentBlocks.add(Material.BLUE_CARPET);
+ transparentBlocks.add(Material.BROWN_CARPET);
+ transparentBlocks.add(Material.CYAN_CARPET);
+ transparentBlocks.add(Material.MAGENTA_CARPET);
+ transparentBlocks.add(Material.ORANGE_CARPET);
+ transparentBlocks.add(Material.PINK_CARPET);
+ transparentBlocks.add(Material.PURPLE_CARPET);
+ transparentBlocks.add(Material.RED_CARPET);
+ transparentBlocks.add(Material.WHITE_CARPET);
+ transparentBlocks.add(Material.YELLOW_CARPET);
+ transparentBlocks.add(Material.CARROT);
+ transparentBlocks.add(Material.WHEAT);
+ transparentBlocks.add(Material.DEAD_BUSH);
+ transparentBlocks.add(Material.DETECTOR_RAIL);
+ transparentBlocks.add(Material.ACACIA_FENCE_GATE);
+ transparentBlocks.add(Material.BIRCH_FENCE_GATE);
+ transparentBlocks.add(Material.DARK_OAK_FENCE_GATE);
+ transparentBlocks.add(Material.JUNGLE_FENCE_GATE);
+ transparentBlocks.add(Material.OAK_FENCE_GATE);
+ transparentBlocks.add(Material.SPRUCE_FENCE_GATE);
+ transparentBlocks.add(Material.FLOWER_POT);
+ transparentBlocks.add(Material.LADDER);
+ transparentBlocks.add(Material.LEVER);
+ transparentBlocks.add(Material.GRASS);
+ transparentBlocks.add(Material.POWERED_RAIL);
+ transparentBlocks.add(Material.REDSTONE_TORCH);
+ transparentBlocks.add(Material.REDSTONE_WIRE);
+ transparentBlocks.add(Material.ACACIA_SIGN);
+ transparentBlocks.add(Material.BIRCH_SIGN);
+ transparentBlocks.add(Material.DARK_OAK_SIGN);
+ transparentBlocks.add(Material.JUNGLE_SIGN);
+ transparentBlocks.add(Material.OAK_SIGN);
+ transparentBlocks.add(Material.SPRUCE_SIGN);
+ transparentBlocks.add(Material.SNOW);
+ transparentBlocks.add(Material.STONE_BUTTON);
+ transparentBlocks.add(Material.SUGAR_CANE);
+ transparentBlocks.add(Material.TORCH);
+ transparentBlocks.add(Material.TRIPWIRE);
+ transparentBlocks.add(Material.VINE);
+ transparentBlocks.add(Material.ACACIA_WALL_SIGN);
+ transparentBlocks.add(Material.BIRCH_WALL_SIGN);
+ transparentBlocks.add(Material.DARK_OAK_WALL_SIGN);
+ transparentBlocks.add(Material.JUNGLE_WALL_SIGN);
+ transparentBlocks.add(Material.OAK_WALL_SIGN);
+ transparentBlocks.add(Material.SPRUCE_WALL_SIGN);
+ transparentBlocks.add(Material.WATER);
+ transparentBlocks.add(Material.LAVA);
+ transparentBlocks.add(Material.LARGE_FERN);
+ transparentBlocks.add(Material.FERN);
+ transparentBlocks.add(Material.TALL_GRASS);
+ transparentBlocks.add(Material.SEAGRASS);
+ transparentBlocks.add(Material.TALL_SEAGRASS);
+
+ }
+
+ public static long time = System.currentTimeMillis();
+
+ public static String getRandomMakeUpSkills() {
+ return MakeUpSkills.get(rand.nextInt(MakeUpSkills.size()));
+ }
+
+ public static Status getStatusFromInt(int i, int lvl) {
+ Random rand = new Random(time + i);
+ return new Status(rand.nextInt(Utils.STATRAND) + 1, rand.nextInt(Utils.STATRAND) + 1,
+ rand.nextInt(Utils.STATRAND) + 1, rand.nextInt(Utils.STATRAND) + 1, rand.nextInt(Utils.STATRAND) + 1,
+ rand.nextInt(Utils.STATRAND) + 1, rand.nextInt(Utils.STATRAND) + 1, rand.nextInt(Utils.STATRAND) + 1,
+ lvl);
+ }
+
+ public static Status getStatusFromInt(int i) {
+ Random rand = new Random(time + i);
+ return new Status(rand.nextInt(Utils.STATRAND) + 1, rand.nextInt(Utils.STATRAND) + 1,
+ rand.nextInt(Utils.STATRAND) + 1, rand.nextInt(Utils.STATRAND) + 1, rand.nextInt(Utils.STATRAND) + 1,
+ rand.nextInt(Utils.STATRAND) + 1, rand.nextInt(Utils.STATRAND) + 1, rand.nextInt(Utils.STATRAND) + 1,
+ 1);
+ }
+
+ public static void init() {
+ Races.init();
+ Leveling.init();
+ util();
+ CreateItem.init();
+ FileConfiguration yml = Main.getPlugin().getConfig();
+ RMP = yml.getInt("ManaRecover");
+ RHP = yml.getInt("HPRecover");
+ manaDMG = yml.getDouble("ManaDamage");
+ Cast.timelimit = yml.getLong("TimeLimit");
+ MaxSlot = yml.getInt("MaxSlot");
+ basespd = (float) yml.getDouble("BaseSpeed");
+ basehp = yml.getDouble("BaseHP");
+ basemp = yml.getDouble("BaseMP");
+ LUKAVD = yml.getDouble("LUKAVD");
+ LUKCRIT = yml.getDouble("LUKCRIT");
+ HPHealth = yml.getDouble("HPMod");
+ ManaMP = yml.getDouble("MPMod");
+ SPDSpeed = (float) yml.getDouble("SpeedMod");
+ defaultattackrange = yml.getDouble("DefaultAttackRange");
+ hunger = yml.getDouble("HungerDamage");
+ exarmor = yml.getDouble("LeakArmorMod");
+ arrowdamagemod = yml.getDouble("ArrowEnchMod");
+ STATRAND = yml.getInt("StatusRandomMax");
+ PercentDamageLVL = yml.getDouble("RequiredDamageDueToMobs");
+ Penalty_LVL = yml.getBoolean("Penalty.LevelLose");
+ Penalty_Race = yml.getBoolean("Penalty.ResetRace");
+ Penalty_Status = yml.getBoolean("Penalty.ResetStatus");
+ Penalty_Status = yml.getBoolean("Penalty.MakeUp");
+ MakeUpMod = yml.getDouble("MakeUpMod");
+ Main.worlds.clear();
+ deathpenworld.clear();
+ MakeUpSkills.clear();
+ try {
+ for (String str : yml.getStringList("MakeUpSkills")) {
+ MakeUpSkills.add(str);
+ }
+ } catch (Exception e) {
+ }
+ try {
+ for (String str : yml.getStringList("DeathPenaltyWorlds")) {
+ deathpenworld.add(Bukkit.getWorld(str));
+ }
+ } catch (Exception e) {
+ }
+ try {
+ for (String str : yml.getStringList("Worlds")) {
+ Main.worlds.add(Bukkit.getWorld(str));
+ }
+ } catch (Exception e) {
+ }
+ Players.skillsetting = YamlConfiguration
+ .loadConfiguration(new File(Main.getPlugin().getDataFolder() + File.separator + "skills.yml"));
+
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ Utils.time = System.currentTimeMillis();
+ }
+ }.runTaskTimerAsynchronously(Main.getPlugin(), 1728000, 1728000);
+ }
+
+ public static class Status {
+ private int ATK;
+ private int HP;
+ private int SPD;
+ private int LUK;
+ private int MP;
+ private int AR;
+ private int AT;
+ private int LVL;
+ private int SKL;
+
+ public Status() {
+ this.ATK = 0;
+ this.SPD = 0;
+ this.HP = 0;
+ this.MP = 0;
+ this.LUK = 0;
+ this.LVL = 1;
+ this.AR = 0;
+ this.AT = 0;
+ }
+
+ public Status(int SKL, int AR, int AT, int atk, int spd, int hp, int mp, int luk, int lvl) {
+ this.SKL = SKL;
+ this.AR = AR;
+ this.AT = AT;
+ this.ATK = atk;
+ this.SPD = spd;
+ this.HP = hp;
+ this.MP = mp;
+ this.LUK = luk;
+ this.LVL = lvl;
+ }
+
+ public int getArmor() {
+ return this.AR;
+ }
+
+ public int getArmorToughness() {
+ return AT;
+ }
+
+ public int getLvL() {
+ return this.LVL;
+ }
+
+ public void setLvL(int lvl) {
+ this.LVL = lvl;
+ }
+
+ public int getATK() {
+ return this.ATK;
+ }
+
+ public int getHP() {
+ return this.HP;
+ }
+
+ public int getMP() {
+ return this.MP;
+ }
+
+ public int getSpeed() {
+ return this.SPD;
+ }
+
+ public int getLucky() {
+ return this.LUK;
+ }
+
+ public int getSKL() {
+ return this.SKL;
+ }
+ }
+
+ public static Status getPlayerStatus(Player player) {
+ return playerstatus.get(player);
+ }
+
+ public static void setPlayerStatus(Player player, Status status) {
+ playerstatus.put(player, status);
+ }
+
+ public static boolean isSuccess(double rate) {
+ return rand.nextInt(100) < rate;
+ }
+
+ public static ItemStack getSkillItem(String skillname, Player player) {
+ ItemStack item = new ItemStack(Material.ENCHANTED_BOOK);
+ ItemMeta im = item.getItemMeta();
+ skillname = SkillName.get(skillname);
+ im.setDisplayName(ChatColor.LIGHT_PURPLE + skillname);
+ List lore = new ArrayList();
+ lore.add(ChatColor.YELLOW + Players.skillsetting.getString(skillname + ".Description"));
+ int cost;
+
+ try {
+ Skills sk = Skill.skills.get(skillname);
+ Class> clazz = sk.skill;
+ Object s = clazz.getDeclaredConstructor().newInstance();
+ Method skill = clazz.getMethod("getManaCost", Player.class);
+ cost = (int) skill.invoke(s, player);
+ } catch (Exception e) {
+ cost = (int) Players.skillsetting.getDouble(skillname + ".CostMP");
+ }
+ lore.add(ChatColor.YELLOW + "消耗魔力: " + cost);
+ lore.add(ChatColor.YELLOW + "需要詠唱次數: " + Players.skillsetting.getString(skillname + ".Times"));
+ lore.add(ChatColor.YELLOW + "冷卻時間: " + Players.skillsetting.getString(skillname + ".Cooldown"));
+ im.setLore(lore);
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ pdc.set(AllAboutDamage.key, PersistentDataType.STRING, "ItemsNotDrop");
+ item.setItemMeta(im);
+
+ return item;
+ }
+
+ public static ItemStack getSkillItem(String skillname, String Cost) {
+ ItemStack item = new ItemStack(Material.ENCHANTED_BOOK);
+ ItemMeta im = item.getItemMeta();
+ skillname = SkillName.get(skillname);
+ im.setDisplayName(ChatColor.LIGHT_PURPLE + skillname);
+ List lore = new ArrayList();
+ lore.add(ChatColor.YELLOW + Players.skillsetting.getString(skillname + ".Description"));
+ lore.add(Cost);
+ lore.add(ChatColor.YELLOW + "需要詠唱次數: " + Players.skillsetting.getString(skillname + ".Times"));
+ lore.add(ChatColor.YELLOW + "冷卻時間: " + Players.skillsetting.getString(skillname + ".Cooldown"));
+ im.setLore(lore);
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ pdc.set(AllAboutDamage.key, PersistentDataType.STRING, "ItemsNotDrop");
+ item.setItemMeta(im);
+ return item;
+ }
+
+ public static void setNotDrop(ItemStack item) {
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ pdc.set(AllAboutDamage.key, PersistentDataType.STRING, "ItemsNotDrop");
+ item.setItemMeta(im);
+ }
+
+ public static boolean isNotDrop(ItemStack item) {
+ try {
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ return pdc.has(AllAboutDamage.key, PersistentDataType.STRING);
+ } catch (NullPointerException e) {
+ return false;
+ }
+ }
+}
diff --git a/src/main/java/nashi/NRPG/Commands/AbandonCommand.java b/src/main/java/nashi/NRPG/Commands/AbandonCommand.java
new file mode 100644
index 0000000..31f256a
--- /dev/null
+++ b/src/main/java/nashi/NRPG/Commands/AbandonCommand.java
@@ -0,0 +1,69 @@
+package nashi.NRPG.Commands;
+
+import java.util.List;
+
+import org.bukkit.ChatColor;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.entity.Player;
+
+import nashi.NRPG.Players.Players;
+import nashi.NRPG.Skills.Skill;
+import nashi.NRPG.Skills.SkillName;
+
+public class AbandonCommand implements CommandExecutor {
+ @Override
+ public boolean onCommand(CommandSender sender, Command cmd, String cmdlable, String[] args) {
+ if (args.length == 0) {
+ Commands.sendHelp(sender);
+ return true;
+ } else {
+ if (args[0] != null) {
+ if (sender instanceof Player) {
+ Player player = (Player) sender;
+ if (!player.hasPermission("nrpg.abandon")) {
+ player.sendMessage(ChatColor.RED + "你沒有權限使用此指令");
+ return true;
+ }
+ String sk = args[0];
+ String skillname = SkillName.get(sk);
+ if (Skill.GeneralSkills.contains(skillname)) {
+ player.sendMessage(ChatColor.RED + "你無法放棄通用技能");
+ return true;
+ }
+ if (Players.Data.get(player).getRace().getSkillList().contains(skillname)) {
+ player.sendMessage(ChatColor.RED + "你無法放棄種族技能");
+ return true;
+ }
+ YamlConfiguration y = Players.getYaml(player);
+ boolean have = false;
+ List skl = y.getStringList("UniqeSkills");
+ if (skl.contains(skillname)) {
+ have = true;
+ }
+ if (have) {
+ skl.remove(skillname);
+ y.set("UniqeSkills", skl);
+ y.set("UsedSlots", y.getInt("UsedSlots") - 1);
+ for(int i = 1;i<=9;i++) {
+ try {
+ if(y.getString("Slot." + i).equals(skillname)) {
+ y.set("Slot."+i, null);
+ }
+ }catch(Exception e) {}
+ }
+ player.sendMessage(ChatColor.GREEN + "你已放棄技能- " + skillname);
+ } else {
+ player.sendMessage(ChatColor.RED + "技能不存在,請確認是否擁有此技能或名稱是否正確");
+ }
+
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/src/main/java/nashi/NRPG/Commands/CastCommand.java b/src/main/java/nashi/NRPG/Commands/CastCommand.java
new file mode 100644
index 0000000..66f2ec3
--- /dev/null
+++ b/src/main/java/nashi/NRPG/Commands/CastCommand.java
@@ -0,0 +1,39 @@
+package nashi.NRPG.Commands;
+
+import org.bukkit.ChatColor;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.entity.Player;
+
+import nashi.NRPG.Players.Players;
+import nashi.NRPG.Skills.Cast;
+
+public class CastCommand implements CommandExecutor {
+ @Override
+ public boolean onCommand(CommandSender sender, Command cmd, String cmdlable, String[] args) {
+ if (args.length == 0) {
+ Commands.sendHelp(sender);
+ return true;
+ } else {
+ if (args[0] != null) {
+ if (sender instanceof Player) {
+ Player player = (Player) sender;
+ int speed = Integer.parseInt(args[0]);
+ YamlConfiguration y = Players.getYaml(player);
+ if (speed > 0 && speed <= 20) {
+ y.set("CastSpeed", speed);
+ Cast.castspeed.put(player, speed);
+ player.sendMessage(ChatColor.GREEN +"你已將詠唱間隔設定為 " + speed + " ticks");
+ } else {
+ player.sendMessage(ChatColor.RED +"請輸入1~20的數字");
+ }
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/src/main/java/nashi/NRPG/Commands/Commands.java b/src/main/java/nashi/NRPG/Commands/Commands.java
new file mode 100644
index 0000000..7aacb3a
--- /dev/null
+++ b/src/main/java/nashi/NRPG/Commands/Commands.java
@@ -0,0 +1,407 @@
+package nashi.NRPG.Commands;
+
+import java.io.File;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.bukkit.ChatColor;
+import org.bukkit.Material;
+import org.bukkit.NamespacedKey;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemFlag;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+import org.bukkit.persistence.PersistentDataContainer;
+import org.bukkit.persistence.PersistentDataType;
+
+import nashi.NRPG.Main;
+import nashi.NRPG.API.SkillAPI;
+import nashi.NRPG.API.Utils;
+import nashi.NRPG.Items.CreateItem;
+import nashi.NRPG.Players.Players;
+import nashi.NRPG.Skills.Cast;
+import nashi.NRPG.Skills.Skill;
+import nashi.NRPG.Skills.SkillItem;
+import nashi.NRPG.Skills.SkillName;
+import nashi.NRPG.listeners.ModifyItem;
+
+public class Commands implements CommandExecutor {
+ @Override
+ public boolean onCommand(CommandSender sender, Command cmd, String cmdlable, String[] args) {
+ if (args.length == 0) {
+ sendHelp(sender);
+ return true;
+ } else {
+ if (args[0].equalsIgnoreCase("key") && args.length >= 4) {
+ if (!sender.hasPermission("nrpg.op")) {
+ sender.sendMessage("No permission");
+ return true;
+ }
+ if (sender instanceof Player) {
+ Player player = (Player) sender;
+ String key = args[1];
+ String type = args[2];
+ type = type.toUpperCase();
+ String data = args[3];
+ ItemStack item = player.getInventory().getItemInMainHand();
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ int c = 0;
+ String[] sp = data.split(",");
+ switch (type) {
+ case "INTEGER":
+ pdc.set(new NamespacedKey(Main.getPlugin(), key), PersistentDataType.INTEGER,
+ Integer.parseInt(data));
+ break;
+ case "INTEGER_ARRAY":
+ int[] ia = new int[data.length()];
+ for (String str : sp) {
+ ia[c] = Integer.parseInt(str);
+ c++;
+ }
+ pdc.set(new NamespacedKey(Main.getPlugin(), key), PersistentDataType.INTEGER_ARRAY, ia);
+ break;
+ case "BYTE":
+ pdc.set(new NamespacedKey(Main.getPlugin(), key), PersistentDataType.BYTE,
+ Byte.parseByte(data));
+ break;
+ case "BYTE_ARRAY":
+ byte[] ba = new byte[data.length()];
+ for (String str : sp) {
+ ba[c] = Byte.parseByte(str);
+ c++;
+ }
+ pdc.set(new NamespacedKey(Main.getPlugin(), key), PersistentDataType.BYTE_ARRAY, ba);
+ break;
+ case "DOUBLE":
+ pdc.set(new NamespacedKey(Main.getPlugin(), key), PersistentDataType.DOUBLE,
+ Double.parseDouble(data));
+ break;
+ case "FLOAT":
+ pdc.set(new NamespacedKey(Main.getPlugin(), key), PersistentDataType.FLOAT,
+ Float.parseFloat(data));
+ break;
+ case "LONG":
+ pdc.set(new NamespacedKey(Main.getPlugin(), key), PersistentDataType.LONG,
+ Long.parseLong(data));
+ break;
+ case "LONG_ARRAY":
+ long[] la = new long[data.length()];
+ for (String str : sp) {
+ la[c] = Long.parseLong(str);
+ c++;
+ }
+ pdc.set(new NamespacedKey(Main.getPlugin(), key), PersistentDataType.LONG_ARRAY, la);
+ break;
+ case "SHORT":
+ pdc.set(new NamespacedKey(Main.getPlugin(), key), PersistentDataType.SHORT,
+ Short.parseShort(data));
+ break;
+ default:
+ pdc.set(new NamespacedKey(Main.getPlugin(), key), PersistentDataType.STRING, data);
+ break;
+ }
+ item.setItemMeta(im);
+ return true;
+ }
+
+ }
+ if (args[0].equalsIgnoreCase("potion")) {
+ if (!sender.hasPermission("nrpg.op")) {
+ sender.sendMessage("No permission");
+ return true;
+ }
+ if (sender instanceof Player) {
+ Player player = (Player) sender;
+ ItemStack i = player.getInventory().getItemInMainHand();
+ if (i != null && i.getType() != Material.AIR) {
+ ItemMeta im = i.getItemMeta();
+ im.setUnbreakable(true);
+ im.addItemFlags(ItemFlag.HIDE_UNBREAKABLE);
+ im.getPersistentDataContainer().set(Utils.key, PersistentDataType.STRING, "Consumables");
+ i.setItemMeta(im);
+ player.sendMessage("已修改道具");
+ }
+ }
+ return true;
+ }
+ if (args[0].equalsIgnoreCase("skillitem")) {
+ if (!sender.hasPermission("nrpg.op")) {
+ sender.sendMessage("No permission");
+ return true;
+ }
+ if (sender instanceof Player) {
+ Player player = (Player) sender;
+ ItemStack i = player.getInventory().getItemInMainHand();
+ if (i != null && i.getType() != Material.AIR) {
+ SkillItem.setSkillItem(i, SkillName.get(args[1]), Integer.parseInt(args[2]),
+ Integer.parseInt(args[3]), Integer.parseInt(args[4]), Integer.parseInt(args[5]));
+ player.sendMessage("已修改道具");
+ }
+ }
+ return true;
+ }
+ if (args[0].equalsIgnoreCase("modcast") && args[1] != null) {
+ if (!sender.hasPermission("nrpg.op")) {
+ sender.sendMessage("No permission");
+ return true;
+ }
+ if (sender instanceof Player) {
+ Player player = (Player) sender;
+ ItemStack item = player.getInventory().getItemInMainHand();
+ if (item == null) {
+ player.sendMessage("請手持想要修改的物品");
+ }
+ int mod = Integer.parseInt(args[1]);
+ ModifyItem.setItemCastMod(item, mod);
+ player.sendMessage("已將此道具的額外詠唱速度設為" + mod);
+ }
+ return true;
+ }
+ if (args[0].equalsIgnoreCase("mana") && args[1] != null) {
+ if (!sender.hasPermission("nrpg.op")) {
+ sender.sendMessage("No permission");
+ return true;
+ }
+ if (sender instanceof Player) {
+ Player player = (Player) sender;
+ ItemStack item = player.getInventory().getItemInMainHand();
+ if (item == null) {
+ player.sendMessage("請手持想要修改的物品");
+ }
+ int mod = Integer.parseInt(args[1]);
+ ModifyItem.setItemMP(item, mod);
+ player.sendMessage("裝備此道具時獲得的魔力修改為" + mod);
+ }
+ return true;
+ }
+
+ if (args[0].equalsIgnoreCase("mp") && args[1] != null) {
+ if (!sender.hasPermission("nrpg.op")) {
+ sender.sendMessage("No permission");
+ return true;
+ }
+ if (sender instanceof Player) {
+ Player player = (Player) sender;
+ ItemStack item = player.getInventory().getItemInMainHand();
+ if (item == null) {
+ player.sendMessage("請手持想要修改的物品");
+ }
+ int mod = Integer.parseInt(args[1]);
+ ModifyItem.setPotionMP(item, mod);
+ player.sendMessage("消耗此道具時獲得的魔力修改為" + mod);
+ }
+ return true;
+ }
+ if (args[0].equalsIgnoreCase("hp") && args[1] != null) {
+ if (!sender.hasPermission("nrpg.op")) {
+ sender.sendMessage("No permission");
+ return true;
+ }
+ if (sender instanceof Player) {
+ Player player = (Player) sender;
+ ItemStack item = player.getInventory().getItemInMainHand();
+ if (item == null) {
+ player.sendMessage("請手持想要修改的物品");
+ }
+ int mod = Integer.parseInt(args[1]);
+ ModifyItem.setPotionHP(item, mod);
+ player.sendMessage("消耗此道具時獲得的血量修改為" + mod);
+ }
+ return true;
+ }
+
+ if (args[0].equalsIgnoreCase("book") && args[1] != null) {
+ if (!sender.hasPermission("nrpg.op")) {
+ sender.sendMessage("No permission");
+ return true;
+ }
+ if (sender instanceof Player) {
+ Player player = (Player) sender;
+ String sk = args[1];
+ if (SkillName.get(sk) != null) {
+ String skillname = SkillName.get(sk);
+ ItemStack i = player.getInventory().getItemInMainHand();
+ if (i != null && i.getType() != Material.AIR) {
+ ItemMeta im = i.getItemMeta();
+ im.setDisplayName(ChatColor.GOLD + "技能書" + ChatColor.AQUA + skillname);
+ List lore = new ArrayList();
+ lore.add(ChatColor.GREEN + "使用此書即可學習技能-" + ChatColor.LIGHT_PURPLE + skillname);
+ lore.add(ChatColor.GREEN + "技能說明: ");
+ lore.add(ChatColor.YELLOW + Players.skillsetting.getString(skillname + ".Description"));
+ im.setLore(lore);
+ im.setUnbreakable(true);
+ im.addItemFlags(ItemFlag.HIDE_UNBREAKABLE);
+ i.setItemMeta(im);
+ ModifyItem.setSkillBookSkill(i, skillname);
+ } else {
+ ItemStack a = new ItemStack(Material.ENCHANTED_BOOK);
+ ItemMeta im = a.getItemMeta();
+ im.setDisplayName(ChatColor.GOLD + "技能書" + ChatColor.AQUA + skillname);
+ List lore = new ArrayList();
+ lore.add(ChatColor.GREEN + "使用此書即可學習技能-" + ChatColor.LIGHT_PURPLE + skillname);
+ lore.add(ChatColor.GREEN + "技能說明: ");
+ lore.add(ChatColor.YELLOW + Players.skillsetting.getString(skillname + ".Description"));
+ im.setLore(lore);
+ im.setUnbreakable(true);
+ im.addItemFlags(ItemFlag.HIDE_UNBREAKABLE);
+ a.setItemMeta(im);
+ ModifyItem.setSkillBookSkill(a, skillname);
+ player.getInventory().setItemInMainHand(a);
+ }
+ }
+ }
+ return true;
+ }
+ if (args[0].equalsIgnoreCase("reload")) {
+ if (!sender.hasPermission("nrpg.op")) {
+ sender.sendMessage("No permission");
+ return true;
+ }
+ SkillAPI.plugin().reloadConfig();
+ Utils.init();
+ return true;
+ }
+ if (args[0].equalsIgnoreCase("range") && args[1] != null) {
+ if (!sender.hasPermission("nrpg.op")) {
+ sender.sendMessage("No permission");
+ return true;
+ }
+ if (sender instanceof Player) {
+ Player player = (Player) sender;
+ ItemStack item = player.getInventory().getItemInMainHand();
+ if (item == null) {
+ player.sendMessage("請手持想要修改的物品");
+ }
+ double mod = Double.parseDouble(args[1]);
+ ModifyItem.setItemRangeMod(item, mod);
+ player.sendMessage("已將此道具的額外攻擊距離設為" + mod);
+ }
+ return true;
+ }
+
+ if (args[0].equalsIgnoreCase("forge") && args[1] != null) {
+ if (!sender.hasPermission("nrpg.op")) {
+ sender.sendMessage("No permission");
+ return true;
+ }
+ if (sender instanceof Player) {
+ Player player = (Player) sender;
+ ItemStack item = player.getInventory().getItemInMainHand();
+ if (item == null) {
+ player.sendMessage("請手持想要修改的物品");
+ }
+ CreateItem.setItemForgeSlot(item, Integer.parseInt(args[1]));
+ CreateItem.setItemForgeTime(item, 0);
+
+ player.sendMessage(
+ "已將此道具設定為可鍛造物品, 欄位:" + CreateItem.getEquipmentSlotFromInt(Integer.parseInt(args[1])));
+ }
+ return true;
+ }
+
+ if (args[0].equalsIgnoreCase("material") && args[1] != null) {
+ if (!sender.hasPermission("nrpg.op")) {
+ sender.sendMessage("No permission");
+ return true;
+ }
+ if (sender instanceof Player) {
+ Player player = (Player) sender;
+ ItemStack item = player.getInventory().getItemInMainHand();
+ if (item == null) {
+ player.sendMessage("請手持想要修改的物品");
+ }
+ String tier = args[1];
+ CreateItem.setItemForgeMaterialTier(item, tier);
+ player.sendMessage("已將此道具設定為" + tier + "等級素材");
+ }
+ return true;
+ }
+ if (args[0].equalsIgnoreCase("unloadskill") && args[1] != null) {
+ if (!sender.hasPermission("nrpg.op")) {
+ sender.sendMessage("No permission");
+ return true;
+ }
+ try {
+ String sk = args[1];
+ Class> clazz = Skill.skills.get(sk).skill;
+ Object s = clazz.getDeclaredConstructor().newInstance();
+ Method skill = clazz.getMethod("unload");
+ skill.invoke(s);
+ } catch (Exception e) {
+
+ }
+ }
+ if (args[0].equalsIgnoreCase("loadskill") && args[1] != null) {
+ if (!sender.hasPermission("nrpg.op")) {
+ sender.sendMessage("No permission");
+ return true;
+ }
+
+ String sk = args[1];
+ if (SkillName.get(sk) != null) {
+ Class> clz = Skill.skills.get(SkillName.get(sk)).skill;
+ try {
+ Method set = clz.getMethod("unload");
+ Object s = clz.getDeclaredConstructor().newInstance();
+ set.invoke(s);
+ } catch (Exception e) {
+ }
+ }
+ File fileEntry = new File(
+ SkillAPI.plugin().getDataFolder() + File.separator + "skills" + File.separator + sk + ".jar");
+ try {
+ File f = fileEntry;
+ URL u = f.toURI().toURL();
+ URLClassLoader child = new URLClassLoader(new URL[] { u }, Main.class.getClassLoader());
+ Class> clazz = Class.forName(sk + "." + sk, true, child);
+ Object s = clazz.getDeclaredConstructor().newInstance();
+ try {
+ Method set = clazz.getMethod("load");
+ set.invoke(s);
+ } catch (Exception e) {
+ }
+ try {
+ if (SkillAPI.getSkillPublicBoolean(sk, "general")) {
+ Skill.GeneralSkills.add(sk);
+ }
+ Method skill = clazz.getMethod("skill", Player.class);
+ Skill.skills.put(sk, new Skill.Skills(skill, s, clazz));
+ SkillName.put(sk);
+ } catch (Exception e) {
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static void sendHelp(CommandSender sender) {
+ sender.sendMessage(ChatColor.GOLD + "NRPG指令幫助");
+ sender.sendMessage(ChatColor.YELLOW + "/stat " + ChatColor.GREEN + "能力值");
+ sender.sendMessage(ChatColor.YELLOW + "/skilledit " + ChatColor.GREEN + "調整技能參數");
+ sender.sendMessage(ChatColor.YELLOW + "/cast 間隔 " + ChatColor.GREEN + "修改詠唱速度,越低越快");
+ sender.sendMessage(ChatColor.YELLOW + "/slot " + ChatColor.GREEN + "將技能綁定至欄位上");
+ sender.sendMessage(ChatColor.YELLOW + "/scale 格數 " + ChatColor.GREEN + "調整血量的最高格數顯示");
+ sender.sendMessage(ChatColor.YELLOW + "/abandon 技能名稱 " + ChatColor.GREEN + "捨棄技能");
+ sender.sendMessage(ChatColor.YELLOW + "/race " + ChatColor.GREEN + "種族相關指令");
+ sender.sendMessage(ChatColor.YELLOW + "/reset " + ChatColor.GREEN + "重設玩家資料");
+ sender.sendMessage(ChatColor.GOLD + "技能運作說明");
+ sender.sendMessage(ChatColor.YELLOW + "切換雙手物品位置(快捷鍵F): " + ChatColor.GREEN + "施法模式");
+ sender.sendMessage(ChatColor.YELLOW + "施法方式: " + ChatColor.GREEN + "Actionbar會顯示詠唱進度條,在跑到" + Cast.right
+ + Cast.logo + ChatColor.GREEN + "的時候點右鍵進行詠唱");
+ sender.sendMessage(ChatColor.RED + "每個技能需要的成功次數不同");
+ sender.sendMessage(ChatColor.RED + "詠唱時間為" + ChatColor.LIGHT_PURPLE + (Cast.timelimit / 1000) + ChatColor.RED
+ + "秒,時間過後則會判定失敗");
+ sender.sendMessage(ChatColor.RED + "施法失敗會導致爆炸");
+ }
+}
diff --git a/src/main/java/nashi/NRPG/Commands/RaceCommand.java b/src/main/java/nashi/NRPG/Commands/RaceCommand.java
new file mode 100644
index 0000000..ca2c266
--- /dev/null
+++ b/src/main/java/nashi/NRPG/Commands/RaceCommand.java
@@ -0,0 +1,105 @@
+package nashi.NRPG.Commands;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.bukkit.ChatColor;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.entity.Player;
+
+import nashi.NRPG.Players.Players;
+import nashi.NRPG.Players.Races;
+import nashi.NRPG.Players.Players.PlayerData;
+import nashi.NRPG.Players.Races.Race;
+
+public class RaceCommand implements CommandExecutor {
+ public static Set enable = new HashSet();
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command cmd, String cmdlable, String[] args) {
+ if (!(sender instanceof Player)) {
+ return true;
+ }
+ Player player = (Player) sender;
+ if (args.length == 0) {
+ sendRaceHelp(player);
+ return true;
+ } else {
+ if (args[0].equalsIgnoreCase("choose") && args[1] != null) {
+ PlayerData pd = Players.Data.get(player);
+ if (!pd.getRace().getName().equals(Races.defaultRace.getName())) {
+ player.sendMessage(ChatColor.RED + "你已經選擇過種族了");
+ return true;
+ }
+ String racename = args[1];
+ Race race = Races.getRace(racename);
+ if (race == null) {
+ player.sendMessage(ChatColor.RED + "種族不存在,請確認名稱是否正確");
+ return true;
+ }
+ YamlConfiguration y = Players.getYaml(player);
+ pd.setRace(player, race);
+ y.set("Race", race.getName());
+ player.sendMessage(ChatColor.GREEN + "你已成為" + race.getDisplayName());
+
+ return true;
+ }
+ if (args[0].equalsIgnoreCase("exterior")) {
+ if (enable.contains(player)) {
+ disable(player);
+ player.sendMessage(ChatColor.RED + "種族外觀特徵已停用");
+ } else {
+ enable(player);
+ player.sendMessage(ChatColor.GREEN + "種族外觀特徵已啟用");
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static void sendRaceHelp(Player sender) {
+ /*String able;
+ if (enable.contains(sender)) {
+ able = ChatColor.GREEN + "啟用";
+ } else {
+ able = ChatColor.RED + "停用";
+ }
+ sender.sendMessage(ChatColor.YELLOW + "種族外觀: " + able);
+ sender.sendMessage(
+ ChatColor.GREEN + "輸入" + ChatColor.YELLOW + "/race exterior " + ChatColor.GREEN + "即可啟用或停用種族外觀特徵");
+*/
+ sender.sendMessage(
+ ChatColor.GREEN + "輸入" + ChatColor.YELLOW + "/race choose 種族英文名 " + ChatColor.GREEN + "即可選擇種族");
+ sender.sendMessage(ChatColor.RED + "選擇種族後將無法更改");
+
+ /*
+ sender.sendMessage(ChatColor.GREEN + "種族列表:");
+ Set keys = Races.races.keySet();
+ for (String key : keys) {
+ Race race = Races.getRace(key);
+ sender.sendMessage(ChatColor.GOLD + key + ChatColor.GRAY + ": " + ChatColor.YELLOW + race.getDisplayName()
+ + " " + ChatColor.LIGHT_PURPLE + race.getDescription());
+ }
+ */
+ }
+
+ public static void disable(Player player) {
+ YamlConfiguration y = Players.getYaml(player);
+ y.set("Exterior", false);
+ enable.remove(player);
+ }
+
+ public static void enable(Player player) {
+ YamlConfiguration y = Players.getYaml(player);
+ y.set("Exterior", true);
+ enable.add(player);
+ }
+
+ public static boolean isEnable(Player player) {
+ return enable.contains(player);
+ }
+}
diff --git a/src/main/java/nashi/NRPG/Commands/ResetCommand.java b/src/main/java/nashi/NRPG/Commands/ResetCommand.java
new file mode 100644
index 0000000..e71a11d
--- /dev/null
+++ b/src/main/java/nashi/NRPG/Commands/ResetCommand.java
@@ -0,0 +1,49 @@
+package nashi.NRPG.Commands;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.bukkit.ChatColor;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.bukkit.scheduler.BukkitRunnable;
+
+import nashi.NRPG.API.SkillAPI;
+import nashi.NRPG.Players.Players;
+
+public class ResetCommand implements CommandExecutor {
+ private static Set reset = new HashSet();
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command cmd, String cmdlable, String[] args) {
+ if (sender instanceof Player) {
+ Player player = (Player) sender;
+ if (args.length == 0) {
+ player.sendMessage(ChatColor.RED + "如果確定要重設資料請在30秒內輸入/reset confirm");
+ reset.add(player);
+ sec(player);
+ } else if (args[0].equalsIgnoreCase("confirm")) {
+ if (reset.contains(player)) {
+ reset.remove(player);
+ Players.delete(player);
+ Players.delete(player);// bug 需要reset兩次來生效..
+ player.sendMessage(ChatColor.GOLD + "你已重設你的資料");
+ }
+ }
+
+ return true;
+ }
+ return false;
+ }
+
+ private void sec(Player player) {
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ reset.remove(player);
+ }
+ }.runTaskLater(SkillAPI.plugin(), 600);
+ }
+}
diff --git a/src/main/java/nashi/NRPG/Commands/ScaleCommand.java b/src/main/java/nashi/NRPG/Commands/ScaleCommand.java
new file mode 100644
index 0000000..927ca16
--- /dev/null
+++ b/src/main/java/nashi/NRPG/Commands/ScaleCommand.java
@@ -0,0 +1,36 @@
+package nashi.NRPG.Commands;
+
+import org.bukkit.ChatColor;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.entity.Player;
+
+import nashi.NRPG.Players.Players;
+
+public class ScaleCommand implements CommandExecutor {
+ @Override
+ public boolean onCommand(CommandSender sender, Command cmd, String cmdlable, String[] args) {
+ if (args.length == 0) {
+ Commands.sendHelp(sender);
+ return true;
+ } else {
+ if (args[0] != null) {
+ if (sender instanceof Player) {
+ Player player = (Player) sender;
+ int i = Integer.parseInt(args[0]);
+ YamlConfiguration y = Players.getYaml(player);
+ y.set("Scale", i);
+ if (i < 1) {
+ sender.sendMessage(ChatColor.RED + "請輸入大於1的數字");
+ return true;
+ }
+ player.setHealthScale(i);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/nashi/NRPG/Commands/SkillEditCommand.java b/src/main/java/nashi/NRPG/Commands/SkillEditCommand.java
new file mode 100644
index 0000000..763fb3e
--- /dev/null
+++ b/src/main/java/nashi/NRPG/Commands/SkillEditCommand.java
@@ -0,0 +1,46 @@
+package nashi.NRPG.Commands;
+
+import org.bukkit.ChatColor;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.entity.Player;
+
+import nashi.NRPG.Players.Players;
+import nashi.NRPG.Skills.GUI;
+import nashi.NRPG.Skills.SkillName;
+
+public class SkillEditCommand implements CommandExecutor {
+ @Override
+ public boolean onCommand(CommandSender sender, Command cmd, String cmdlable, String[] args) {
+ if (args.length == 0) {
+ if (sender instanceof Player) {
+ Player player = (Player) sender;
+ GUI.EditGUI(player, 0);
+ }
+ return true;
+ } else {
+ if (sender instanceof Player) {
+ Player player = (Player) sender;
+ String skname = SkillName.get(args[0]);
+ YamlConfiguration y = Players.getYaml(player);
+ if (y.getStringList("UniqeSkills").contains(skname)) {
+ try {
+ if (y.getConfigurationSection(("Skills." + skname + ".Custom")).getKeys(false).size() > 0) {
+ GUI.openSkillEditGUI(player, skname);
+ } else {
+ player.sendMessage(ChatColor.RED + "請確認技能是否有可自定的數值");
+ }
+ } catch (Exception e) {
+ player.sendMessage(ChatColor.RED + "請確認技能是否有可自定的數值");
+ }
+ } else {
+ player.sendMessage(ChatColor.RED + "技能不存在,請確認是否擁有此技能或名稱是否正確");
+ }
+ }
+ return true;
+
+ }
+ }
+}
diff --git a/src/main/java/nashi/NRPG/Commands/SkillSlotCommand.java b/src/main/java/nashi/NRPG/Commands/SkillSlotCommand.java
new file mode 100644
index 0000000..85877f2
--- /dev/null
+++ b/src/main/java/nashi/NRPG/Commands/SkillSlotCommand.java
@@ -0,0 +1,64 @@
+package nashi.NRPG.Commands;
+
+import nashi.NRPG.Players.Players;
+import nashi.NRPG.Skills.GUI;
+import nashi.NRPG.Skills.SkillName;
+import nashi.NRPG.listeners.EventListener;
+
+import org.bukkit.ChatColor;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.entity.Player;
+
+public class SkillSlotCommand implements CommandExecutor {
+ public boolean onCommand(CommandSender sender, Command cmd, String cmdlable, String[] args) {
+ Player player;
+ if (args.length == 0) {
+ if (sender instanceof Player) {
+ player = (Player) sender;
+ if (!EventListener.skillmode.get(player)) {
+ GUI.SlotGUI(player, 0);
+ } else {
+ player.sendMessage(ChatColor.RED + "請先離開施法模式");
+ }
+ }
+
+ return true;
+ } else if (args[0] == null) {
+ return false;
+ } else {
+ if (sender instanceof Player) {
+ player = (Player) sender;
+ int slot = Integer.parseInt(args[0]) - 1;
+ if (slot < 0 || slot > 8) {
+ player.sendMessage(ChatColor.RED + "請輸入1~9的數字");
+ return true;
+ }
+
+ YamlConfiguration y = Players.getYaml(player);
+
+ try {
+ String skname = SkillName.get(args[1]);
+ boolean have = false;
+ if (y.getStringList("UniqeSkills").contains(skname)) {
+ have = true;
+ }
+
+ if (have) {
+ y.set("Slot." + slot, skname);
+ player.sendMessage(ChatColor.GREEN + "你已將" + skname + "綁定至欄位" + (slot + 1));
+ } else {
+ player.sendMessage(ChatColor.RED + "技能不存在,請確認是否擁有此技能或名稱是否正確");
+ }
+ } catch (ArrayIndexOutOfBoundsException var10) {
+ y.set("Slot." + slot, (Object) null);
+ player.sendMessage(ChatColor.GREEN + "你已將欄位" + (slot + 1) + "清空");
+ }
+ }
+
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/nashi/NRPG/Commands/StatCommand.java b/src/main/java/nashi/NRPG/Commands/StatCommand.java
new file mode 100644
index 0000000..9c01851
--- /dev/null
+++ b/src/main/java/nashi/NRPG/Commands/StatCommand.java
@@ -0,0 +1,57 @@
+package nashi.NRPG.Commands;
+
+import java.text.DecimalFormat;
+
+import org.bukkit.ChatColor;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.entity.Player;
+
+import nashi.NRPG.API.Utils;
+import nashi.NRPG.Players.Players;
+import nashi.NRPG.Players.Players.PlayerData;
+import nashi.NRPG.Skills.SkillName;
+
+public class StatCommand implements CommandExecutor {
+ public static DecimalFormat df = new DecimalFormat("#.##");
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command cmd, String cmdlable, String[] args) {
+
+ if (sender instanceof Player) {
+ Player player = (Player) sender;
+ YamlConfiguration y = Players.getYaml(player);
+ PlayerData pdata = Players.Data.get(player);
+ player.sendMessage(ChatColor.GREEN + "詠唱間隔: " + y.getInt("CastSpeed"));
+
+ player.sendMessage(ChatColor.GREEN + "種族: " + ChatColor.GOLD + pdata.getRace().getDisplayName());
+ int slot = y.getInt("UniqueSkillSlots");
+ if (slot < 0) {
+ slot = 0;
+ }
+ player.sendMessage(ChatColor.GREEN + "等級: " + ChatColor.GOLD + pdata.getStatus().getLvL());
+ player.sendMessage(ChatColor.GOLD + "能力值");
+ player.sendMessage(ChatColor.GREEN + "血量倍率: " + ChatColor.GOLD + df.format(pdata.getTotalStatusHP()*pdata.getStatus().getLvL()));
+ player.sendMessage(ChatColor.GREEN + "魔力倍率: " + ChatColor.GOLD + df.format(pdata.getTotalStatusMP()*pdata.getStatus().getLvL()));
+ player.sendMessage(ChatColor.GREEN + "攻擊倍率: " + ChatColor.GOLD + df.format(pdata.getDamage()));
+ player.sendMessage(ChatColor.GREEN + "遠程倍率: " + ChatColor.GOLD + df.format(pdata.getRangeDamage()));
+ player.sendMessage(ChatColor.GREEN + "技能倍率: " + ChatColor.GOLD + df.format(pdata.getSkillDamage()));
+ player.sendMessage(ChatColor.GREEN + "迴避率/爆擊率: " + ChatColor.GOLD + df.format(pdata.getTotalStatusLUK()*Utils.LUKAVD)+"% / "+df.format(pdata.getTotalStatusLUK()*Utils.LUKCRIT)+"%");
+ player.sendMessage(ChatColor.GREEN + "速度: " + ChatColor.GOLD + df.format(pdata.getTotalStatusSpeed()*Utils.SPDSpeed+Utils.basespd));
+ player.sendMessage(ChatColor.GREEN + "裝甲倍率: " + ChatColor.GOLD + df.format(pdata.getTotalStatusArmor()));
+ player.sendMessage(
+ ChatColor.GREEN + "抗性倍率: " + ChatColor.GOLD + df.format(pdata.getTotalStatusArmorToughness()));
+ player.sendMessage(ChatColor.GREEN + "額外技能槽數量: " + ChatColor.GOLD + slot);
+ player.sendMessage(ChatColor.GREEN + "技能列表: ");
+ for (String str : y.getStringList("UniqeSkills")) {
+ player.sendMessage(ChatColor.YELLOW + "- " + ChatColor.LIGHT_PURPLE + SkillName.get(str)
+ + ChatColor.GREEN + " " + Players.skillsetting.getString(SkillName.get(str) + ".Description"));
+ }
+ return true;
+ }
+ return false;
+ }
+
+}
diff --git a/src/main/java/nashi/NRPG/CustomEvents/CastEvent.java b/src/main/java/nashi/NRPG/CustomEvents/CastEvent.java
new file mode 100644
index 0000000..a1c0080
--- /dev/null
+++ b/src/main/java/nashi/NRPG/CustomEvents/CastEvent.java
@@ -0,0 +1,49 @@
+package nashi.NRPG.CustomEvents;
+
+import org.bukkit.entity.Player;
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+
+import nashi.NRPG.listeners.EventListener.Casting;
+
+public class CastEvent extends Event implements Cancellable {
+ private static final HandlerList handlers = new HandlerList();
+ private Casting cast;
+ private Player player;
+ private boolean b;
+
+ public CastEvent(Player player, Casting cast) {
+ this.cast = cast;
+ this.player = player;
+ }
+
+ public Casting getCast() {
+ return cast;
+ }
+
+ public Player getPlayer() {
+ return player;
+ }
+
+ @Override
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+
+ @Override
+ public boolean isCancelled() {
+ // TODO Auto-generated method stub
+ return b;
+ }
+
+ @Override
+ public void setCancelled(boolean arg0) {
+ b = arg0;
+
+ }
+}
diff --git a/src/main/java/nashi/NRPG/CustomEvents/CastStartEvent.java b/src/main/java/nashi/NRPG/CustomEvents/CastStartEvent.java
new file mode 100644
index 0000000..f38d152
--- /dev/null
+++ b/src/main/java/nashi/NRPG/CustomEvents/CastStartEvent.java
@@ -0,0 +1,68 @@
+package nashi.NRPG.CustomEvents;
+
+import org.bukkit.ChatColor;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+import org.bukkit.persistence.PersistentDataContainer;
+import org.bukkit.persistence.PersistentDataType;
+
+import nashi.NRPG.listeners.ModifyItem;
+import nashi.NRPG.listeners.EventListener.Casting;
+
+public class CastStartEvent extends Event implements Cancellable {
+ private static final HandlerList handlers = new HandlerList();
+ private Casting cast;
+ private Player player;
+
+ public CastStartEvent(Player player, Casting cast) {
+ this.cast = cast;
+ this.player = player;
+ ItemStack item = player.getInventory().getItemInOffHand();
+ if (item == null || item.getType() == Material.AIR) {
+ ItemStack n = new ItemStack(Material.STICK);
+ ItemMeta m = n.getItemMeta();
+ m.setDisplayName(ChatColor.GOLD + "施法判定用道具");
+ PersistentDataContainer pdc = m.getPersistentDataContainer();
+ byte a = 100;
+ pdc.set(ModifyItem.CastHelp, PersistentDataType.BYTE, a);
+ n.setItemMeta(m);
+ player.getInventory().setItemInOffHand(n);
+ }
+ }
+
+ public Casting getCast() {
+ return cast;
+ }
+
+ public Player getPlayer() {
+ return player;
+ }
+
+ @Override
+ public boolean isCancelled() {
+ // TODO Auto-generated method stub
+ return b;
+ }
+
+ private boolean b;
+
+ @Override
+ public void setCancelled(boolean arg0) {
+ b = arg0;
+
+ }
+
+ @Override
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+}
diff --git a/src/main/java/nashi/NRPG/CustomEvents/PreSkillUseEvent.java b/src/main/java/nashi/NRPG/CustomEvents/PreSkillUseEvent.java
new file mode 100644
index 0000000..a2156d2
--- /dev/null
+++ b/src/main/java/nashi/NRPG/CustomEvents/PreSkillUseEvent.java
@@ -0,0 +1,56 @@
+package nashi.NRPG.CustomEvents;
+
+import org.bukkit.entity.Player;
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+
+public class PreSkillUseEvent extends Event implements Cancellable {
+ private static final HandlerList handlers = new HandlerList();
+ private Player player;
+ private String SkillName;
+ private boolean cd;
+ private boolean isCancelled;
+ private boolean isitem;
+
+ public PreSkillUseEvent(Player player, String skillname, boolean isSkillItem) {
+ this.player = player;
+ this.SkillName = skillname;
+ this.isitem = isSkillItem;
+ }
+
+ public boolean isCastByItem() {
+ return this.isitem;
+ }
+
+ public boolean toCooldown() {
+ return this.cd;
+ }
+
+ public String getSkillName() {
+ return this.SkillName;
+ }
+
+ public Player getPlayer() {
+ return player;
+ }
+
+ @Override
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return isCancelled;
+ }
+
+ @Override
+ public void setCancelled(boolean cancelled) {
+ this.isCancelled = cancelled;
+ }
+}
diff --git a/src/main/java/nashi/NRPG/CustomEvents/RaceChangeEvent.java b/src/main/java/nashi/NRPG/CustomEvents/RaceChangeEvent.java
new file mode 100644
index 0000000..b659e16
--- /dev/null
+++ b/src/main/java/nashi/NRPG/CustomEvents/RaceChangeEvent.java
@@ -0,0 +1,41 @@
+package nashi.NRPG.CustomEvents;
+
+import org.bukkit.entity.Player;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+
+import nashi.NRPG.Players.Races.Race;
+
+public class RaceChangeEvent extends Event {
+ private static final HandlerList handlers = new HandlerList();
+ private Player player;
+ private Race race;
+ private Race old;
+
+ public RaceChangeEvent(Player player, Race old, Race race) {
+ this.player = player;
+ this.race = race;
+ this.old = old;
+ }
+
+ public Race getOldRace() {
+ return old;
+ }
+
+ public Race getRace() {
+ return this.race;
+ }
+
+ public Player getPlayer() {
+ return player;
+ }
+
+ @Override
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+}
diff --git a/src/main/java/nashi/NRPG/CustomEvents/SkillItemGenerateEvent.java b/src/main/java/nashi/NRPG/CustomEvents/SkillItemGenerateEvent.java
new file mode 100644
index 0000000..040b3e7
--- /dev/null
+++ b/src/main/java/nashi/NRPG/CustomEvents/SkillItemGenerateEvent.java
@@ -0,0 +1,40 @@
+package nashi.NRPG.CustomEvents;
+
+import org.bukkit.entity.Player;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+import org.bukkit.inventory.ItemStack;
+
+public class SkillItemGenerateEvent extends Event {
+ private static final HandlerList handlers = new HandlerList();
+ private Player player;
+ private ItemStack item;
+ private String skillname;
+
+ public SkillItemGenerateEvent(Player player, ItemStack item, String skillname) {
+ this.player = player;
+ this.item = item;
+ this.skillname = skillname;
+ }
+
+ public String getSkillName() {
+ return skillname;
+ }
+
+ public ItemStack getItem() {
+ return this.item;
+ }
+
+ public Player getPlayer() {
+ return player;
+ }
+
+ @Override
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+}
diff --git a/src/main/java/nashi/NRPG/CustomEvents/SkillLearnEvent.java b/src/main/java/nashi/NRPG/CustomEvents/SkillLearnEvent.java
new file mode 100644
index 0000000..92e25bc
--- /dev/null
+++ b/src/main/java/nashi/NRPG/CustomEvents/SkillLearnEvent.java
@@ -0,0 +1,33 @@
+package nashi.NRPG.CustomEvents;
+
+import org.bukkit.entity.Player;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+
+public class SkillLearnEvent extends Event {
+ private static final HandlerList handlers = new HandlerList();
+ private String skillname;
+ private Player player;
+
+ public SkillLearnEvent(Player player, String skillname) {
+ this.player = player;
+ this.skillname = skillname;
+ }
+
+ public String getSkillName() {
+ return this.skillname;
+ }
+
+ public Player getPlayer() {
+ return player;
+ }
+
+ @Override
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+}
diff --git a/src/main/java/nashi/NRPG/CustomEvents/SkillUsedEvent.java b/src/main/java/nashi/NRPG/CustomEvents/SkillUsedEvent.java
new file mode 100644
index 0000000..b9cb41e
--- /dev/null
+++ b/src/main/java/nashi/NRPG/CustomEvents/SkillUsedEvent.java
@@ -0,0 +1,39 @@
+package nashi.NRPG.CustomEvents;
+
+import org.bukkit.entity.Player;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+
+public class SkillUsedEvent extends Event {
+ private static final HandlerList handlers = new HandlerList();
+ private Player player;
+ private String SkillName;
+ private boolean success;
+
+ public SkillUsedEvent(Player player, String skillname, boolean isSuccess) {
+ this.player = player;
+ this.SkillName = skillname;
+ this.success = isSuccess;
+ }
+
+ public boolean isSuccess() {
+ return this.success;
+ }
+
+ public String getSkillName() {
+ return this.SkillName;
+ }
+
+ public Player getPlayer() {
+ return player;
+ }
+
+ @Override
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+}
diff --git a/src/main/java/nashi/NRPG/Items/CreateItem.java b/src/main/java/nashi/NRPG/Items/CreateItem.java
new file mode 100644
index 0000000..6cbcdf4
--- /dev/null
+++ b/src/main/java/nashi/NRPG/Items/CreateItem.java
@@ -0,0 +1,303 @@
+package nashi.NRPG.Items;
+
+import java.io.File;
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Set;
+import java.util.UUID;
+
+import org.bukkit.ChatColor;
+import org.bukkit.Material;
+import org.bukkit.NamespacedKey;
+import org.bukkit.Note;
+import org.bukkit.Note.Tone;
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.inventory.EquipmentSlot;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+import org.bukkit.inventory.meta.SkullMeta;
+import org.bukkit.persistence.PersistentDataContainer;
+import org.bukkit.persistence.PersistentDataType;
+import com.mojang.authlib.GameProfile;
+import com.mojang.authlib.properties.Property;
+
+import nashi.NRPG.Main;
+
+public class CreateItem {
+ public static Note notes[] = new Note[25];
+ public static final char blank = ' ';
+ public static final int size = 25;
+ public static int max;
+ public static long rate;
+ private static NamespacedKey key_item_forge = new NamespacedKey(Main.getPlugin(), "NRPG_Forge_Item_Forge");
+ private static NamespacedKey key_item_time = new NamespacedKey(Main.getPlugin(), "NRPG_Forge_Item_Time");
+ private static NamespacedKey key_item_type = new NamespacedKey(Main.getPlugin(), "NRPG_Forge_Item_Type");
+ public static NamespacedKey key_material = new NamespacedKey(Main.getPlugin(), "NRPG_Forge_Material");
+ public static NamespacedKey key_click = new NamespacedKey(Main.getPlugin(), "NRPG_Forge_Click");
+ public static ItemStack click;
+ public static HashMap limits = new HashMap();
+ public static HashMap technique = new HashMap();
+ public static HashMap rand_technique = new HashMap();
+
+ public static void init() {
+ notes[0] = new Note(0, Tone.A, false);
+ notes[1] = new Note(0, Tone.A, true);
+ notes[2] = new Note(0, Tone.B, false);
+ notes[3] = new Note(0, Tone.C, false);
+ notes[4] = new Note(0, Tone.C, true);
+ notes[5] = new Note(0, Tone.D, false);
+ notes[6] = new Note(0, Tone.D, true);
+ notes[7] = new Note(0, Tone.E, false);
+ notes[8] = new Note(0, Tone.F, false);
+ notes[9] = new Note(0, Tone.F, true);
+ notes[10] = new Note(0, Tone.G, false);
+ notes[11] = new Note(0, Tone.G, true);
+
+ notes[12] = new Note(1, Tone.A, false);
+ notes[13] = new Note(1, Tone.A, true);
+ notes[14] = new Note(1, Tone.B, false);
+ notes[15] = new Note(1, Tone.C, false);
+ notes[16] = new Note(1, Tone.C, true);
+ notes[17] = new Note(1, Tone.D, false);
+ notes[18] = new Note(1, Tone.D, true);
+ notes[19] = new Note(1, Tone.E, false);
+ notes[20] = new Note(1, Tone.F, false);
+ notes[21] = new Note(1, Tone.F, true);
+ notes[22] = new Note(1, Tone.G, false);
+ notes[23] = new Note(1, Tone.G, true);
+
+ notes[24] = new Note(2, Tone.F, true);
+ FileConfiguration yml = Main.getPlugin().getConfig();
+ YamlConfiguration forge = YamlConfiguration
+ .loadConfiguration(new File(Main.getPlugin().getDataFolder() + File.separator + "forge.yml"));
+ Set slot = forge.getConfigurationSection("technique").getKeys(false);
+ technique.clear();
+ rand_technique.clear();
+ for (String slotkey : slot) {
+ Set tier = forge.getConfigurationSection("technique." + slotkey).getKeys(false);
+ for (String tierkey : tier) {
+ Technique[] tech = new Technique[25];
+ for (int i = 0; i < 25; i++) {
+ String str = forge.getString("technique." + slotkey + "." + tierkey + "." + i);
+ tech[i] = new Technique(str, Integer.parseInt(slotkey));
+ }
+ technique.put(slotkey + "." + tierkey, tech);
+ }
+ }
+ Set slots = forge.getConfigurationSection("max").getKeys(false);
+ limits.clear();
+ for (String slotkey : slots) {
+ String str = forge.getString("max." + slotkey);
+ limits.put(slotkey, new Technique(str, Integer.parseInt(slotkey)));
+ }
+ // Random
+ Set RandomLevel = forge.getConfigurationSection("Random").getKeys(false);
+ for (String slotkey : RandomLevel) {
+ Technique[] tech = new Technique[6];
+ for (int s = 0; s <= 5; s++) {
+ String str = forge.getString("Random." + slotkey + "." + s);
+ tech[s] = new Technique(str);
+ }
+ rand_technique.put("r" + slotkey, tech);
+ }
+ // Random Ended
+ max = yml.getInt("MaxForge");
+ rate = yml.getLong("RateOfNote");
+ ItemStack item = getCustomTextureHead(
+ "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNDNkMDRkYmE1MWY4OTI0OTU4MzRmZjcxYTQyOWE4YTkxMDE1YTVhNzg2Yjg1NmZmZTljMDI0Y2RiNTJmYmM4ZiJ9fX0=");
+ ItemMeta im = item.getItemMeta();
+ im.setDisplayName(ChatColor.GOLD + "" + ChatColor.BOLD + "鍛造");
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ pdc.set(key_click, PersistentDataType.INTEGER, 1);
+ item.setItemMeta(im);
+ click = item;
+ }
+
+ public static ItemStack getCustomTextureHead(String value) {
+ ItemStack head = new ItemStack(Material.PLAYER_HEAD);
+ SkullMeta meta = (SkullMeta) head.getItemMeta();
+ GameProfile profile = new GameProfile(UUID.randomUUID(), "");
+ profile.getProperties().put("textures", new Property("textures", value));
+ Field profileField = null;
+ try {
+ profileField = meta.getClass().getDeclaredField("profile");
+ profileField.setAccessible(true);
+ profileField.set(meta, profile);
+ } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
+ e.printStackTrace();
+ }
+ head.setItemMeta(meta);
+ return head;
+ }
+
+ public static class Technique {
+ public boolean isRandom = false;
+ public double Rand_Max;
+ public double Rand_Min;
+
+ public double MAX_MANA;
+ public double MAX_HEALTH;
+ public double ARMOR_TOUGHNESS;
+ public double ARMOR;
+ public double ATTACK_DAMAGE;
+ public double ATTACK_SPEED;
+ public double ATTACK_RANGE;
+ public double KNOCKBACK_RESISTANCE;
+ public double MOVEMENT_SPEED;
+ public double CAST_MOD;
+
+ public EquipmentSlot slot;
+
+ public Technique(String raw, int slot) {
+ String[] str = raw.split(",");
+ this.MAX_MANA = Double.parseDouble(str[0]);
+ this.MAX_HEALTH = Double.parseDouble(str[1]);
+ this.ARMOR_TOUGHNESS = Double.parseDouble(str[2]);
+ this.ARMOR = Double.parseDouble(str[3]);
+ this.ATTACK_DAMAGE = Double.parseDouble(str[4]);
+ this.ATTACK_SPEED = Double.parseDouble(str[5]);
+ this.ATTACK_RANGE = Double.parseDouble(str[6]);
+ this.KNOCKBACK_RESISTANCE = Double.parseDouble(str[7]);
+ this.MOVEMENT_SPEED = Double.parseDouble(str[8]);
+ this.CAST_MOD = Double.parseDouble(str[9]);
+ this.slot = getEquipmentSlotFromInt(slot);
+ this.isRandom = false;
+ }
+
+ public Technique(double arr[], int slot) {
+ this.MAX_MANA = arr[0];
+ this.MAX_HEALTH = arr[1];
+ this.ARMOR_TOUGHNESS = arr[2];
+ this.ARMOR = arr[3];
+ this.ATTACK_DAMAGE = arr[4];
+ this.ATTACK_SPEED = arr[5];
+ this.ATTACK_RANGE = arr[6];
+ this.KNOCKBACK_RESISTANCE = arr[7];
+ this.MOVEMENT_SPEED = arr[8];
+ this.CAST_MOD = arr[9];
+ this.slot = getEquipmentSlotFromInt(slot);
+ this.isRandom = false;
+ }
+
+ public Technique(double arr[]) {// for Random
+ this.Rand_Min = arr[0];
+ this.Rand_Max = arr[1];
+ this.MAX_MANA = arr[2];
+ this.MAX_HEALTH = arr[3];
+ this.ARMOR_TOUGHNESS = arr[4];
+ this.ARMOR = arr[5];
+ this.ATTACK_DAMAGE = arr[6];
+ this.ATTACK_SPEED = arr[7];
+ this.ATTACK_RANGE = arr[8];
+ this.KNOCKBACK_RESISTANCE = arr[9];
+ this.MOVEMENT_SPEED = arr[10];
+ this.CAST_MOD = arr[11];
+ this.isRandom = true;
+ }
+
+ public Technique(String raw) {// for Random
+ String[] str = raw.split(",");
+ this.Rand_Min = Double.parseDouble(str[0]);
+ this.Rand_Max = Double.parseDouble(str[1]);
+ this.MAX_MANA = Double.parseDouble(str[2]);
+ this.MAX_HEALTH = Double.parseDouble(str[3]);
+ this.ARMOR_TOUGHNESS = Double.parseDouble(str[4]);
+ this.ARMOR = Double.parseDouble(str[5]);
+ this.ATTACK_DAMAGE = Double.parseDouble(str[6]);
+ this.ATTACK_SPEED = Double.parseDouble(str[7]);
+ this.ATTACK_RANGE = Double.parseDouble(str[8]);
+ this.KNOCKBACK_RESISTANCE = Double.parseDouble(str[9]);
+ this.MOVEMENT_SPEED = Double.parseDouble(str[10]);
+ this.CAST_MOD = Double.parseDouble(str[11]);
+ this.isRandom = true;
+ }
+
+ public boolean isRandom() {
+ return this.isRandom;
+ }
+ }
+
+ public static EquipmentSlot getEquipmentSlotFromInt(int i) {
+ switch (i) {
+ case 0:
+ return EquipmentSlot.HAND;
+ case 1:
+ return EquipmentSlot.FEET;
+ case 2:
+ return EquipmentSlot.LEGS;
+ case 3:
+ return EquipmentSlot.CHEST;
+ case 4:
+ return EquipmentSlot.HEAD;
+ default:
+ return EquipmentSlot.OFF_HAND;
+
+ }
+ }
+
+ public static void setItemForgeMaterialTier(ItemStack item, String tier) {
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ pdc.set(key_material, PersistentDataType.STRING, tier);
+ item.setItemMeta(im);
+ }
+
+ public static void setItemForgeKey(ItemStack item, int i) {
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ pdc.set(key_item_forge, PersistentDataType.INTEGER, i);
+ item.setItemMeta(im);
+ }
+
+ public static void setItemForgeSlot(ItemStack item, int i) {
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ pdc.set(key_item_type, PersistentDataType.INTEGER, i);
+ item.setItemMeta(im);
+ }
+
+ public static int getItemForgeKey(ItemStack item) {
+ if (item == null || item.getType() == Material.AIR) {
+ return -1;
+ }
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ if (pdc.has(key_item_forge, PersistentDataType.INTEGER)) {
+ return pdc.get(key_item_forge, PersistentDataType.INTEGER);
+ }
+ return -1;
+ }
+
+ public static int getItemForgeSlot(ItemStack item) {
+ if (item == null || item.getType() == Material.AIR) {
+ return -1;
+ }
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ if (pdc.has(key_item_type, PersistentDataType.INTEGER)) {
+ return pdc.get(key_item_type, PersistentDataType.INTEGER);
+ }
+ return -1;
+ }
+
+ public static int getItemForgeTime(ItemStack item) {
+ if (item == null || item.getType() == Material.AIR) {
+ return -1;
+ }
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ if (pdc.has(key_item_time, PersistentDataType.INTEGER)) {
+ return pdc.get(key_item_time, PersistentDataType.INTEGER);
+ }
+ return -1;
+ }
+
+ public static void setItemForgeTime(ItemStack item, int i) {
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ pdc.set(key_item_time, PersistentDataType.INTEGER, i);
+ item.setItemMeta(im);
+ }
+
+}
diff --git a/src/main/java/nashi/NRPG/Main.java b/src/main/java/nashi/NRPG/Main.java
new file mode 100644
index 0000000..99807ad
--- /dev/null
+++ b/src/main/java/nashi/NRPG/Main.java
@@ -0,0 +1,297 @@
+package nashi.NRPG;
+
+import java.io.File;
+import java.text.DecimalFormat;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.World;
+import org.bukkit.attribute.Attribute;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.EquipmentSlot;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.PlayerInventory;
+import org.bukkit.plugin.Plugin;
+import org.bukkit.plugin.java.JavaPlugin;
+import org.bukkit.scheduler.BukkitRunnable;
+import org.bukkit.scoreboard.DisplaySlot;
+import org.bukkit.scoreboard.Objective;
+import org.bukkit.scoreboard.Scoreboard;
+import org.bukkit.scoreboard.Team;
+
+import edited.com.codingforcookies.armorequip.ArmorListener;
+import edited.com.codingforcookies.armorequip.DispenserArmorListener;
+import nashi.NRPG.API.Utils;
+import nashi.NRPG.Commands.AbandonCommand;
+import nashi.NRPG.Commands.CastCommand;
+import nashi.NRPG.Commands.Commands;
+import nashi.NRPG.Commands.RaceCommand;
+import nashi.NRPG.Commands.ResetCommand;
+import nashi.NRPG.Commands.ScaleCommand;
+import nashi.NRPG.Commands.SkillEditCommand;
+import nashi.NRPG.Commands.SkillSlotCommand;
+import nashi.NRPG.Commands.StatCommand;
+import nashi.NRPG.Players.Players;
+import nashi.NRPG.Players.Players.PlayerData;
+import nashi.NRPG.Skills.Magic;
+import nashi.NRPG.Skills.NewSkill;
+import nashi.NRPG.Skills.SkillName;
+import nashi.NRPG.listeners.AllAboutDamage;
+import nashi.NRPG.listeners.EventListener;
+import nashi.NRPG.listeners.ForgeListener;
+import nashi.NRPG.listeners.ModifyItem;
+import nashi.NRPG.listeners.MythicMobsListener;
+import nashi.NRPG.listeners.ProtocolLibEvent;
+import nashi.NRPG.listeners.SkillItemListener;
+
+public class Main extends JavaPlugin {
+ private static Plugin plugin;
+ private static boolean loaded;
+ public static boolean cancel;
+ public static Set worlds = new HashSet();
+
+ public void onEnable() {
+ plugin = this;
+ if (!new File(getDataFolder(), "config.yml").exists()) {
+ saveDefaultConfig();
+ }
+ if (!new File(getDataFolder(), "skills.yml").exists()) {
+ getPlugin().saveResource("skills.yml", false);
+ }
+ if (!new File(getDataFolder(), "mobs.yml").exists()) {
+ getPlugin().saveResource("mobs.yml", false);
+ }
+ if (!new File(getDataFolder(), "blocked.yml").exists()) {
+ getPlugin().saveResource("blocked.yml", false);
+ }
+ if (!new File(getDataFolder(), "races.yml").exists()) {
+ getPlugin().saveResource("races.yml", false);
+ }
+ reloadConfig();
+ Bukkit.getLogger().info("Loading Settings...");
+ Utils.init();
+
+ getCommand("nrpg").setExecutor(new Commands());
+
+ getCommand("stat").setExecutor(new StatCommand());
+ getCommand("skilledit").setExecutor(new SkillEditCommand());
+ getCommand("cast").setExecutor(new CastCommand());
+ getCommand("slot").setExecutor(new SkillSlotCommand());
+ getCommand("scale").setExecutor(new ScaleCommand());
+ getCommand("abandon").setExecutor(new AbandonCommand());
+ getCommand("race").setExecutor(new RaceCommand());
+ getCommand("reset").setExecutor(new ResetCommand());
+
+ Bukkit.getLogger().info("Loading Skills..");
+ NewSkill.loadskill();
+ Bukkit.getLogger().info(SkillName.skillname.size() + " skill(s) loaded");
+
+ getServer().getPluginManager().registerEvents(new EventListener(), this);
+ getServer().getPluginManager().registerEvents(new AllAboutDamage(), this);
+ getServer().getPluginManager().registerEvents(new ModifyItem(), this);
+ getServer().getPluginManager().registerEvents(new ForgeListener(), this);
+ getServer().getPluginManager().registerEvents(new SkillItemListener(), this);
+
+ if (Bukkit.getServer().getPluginManager().isPluginEnabled("MythicMobs")) {
+ Bukkit.getLogger().info("MythicMobs Detected");
+ getServer().getPluginManager().registerEvents(new MythicMobsListener(), this);
+ }
+
+ YamlConfiguration block = YamlConfiguration.loadConfiguration(new File(getDataFolder(), "blocked.yml"));
+ getServer().getPluginManager().registerEvents(new ArmorListener(block.getStringList("blocked")), this);
+ if (Bukkit.getServer().getPluginManager().isPluginEnabled("ProtocolLib")) {
+ Bukkit.getLogger().info("ProtocolLib Detected");
+ cancel = true;
+ ProtocolLibEvent.run();
+ } else {
+ cancel = false;
+ }
+ try {
+ Class.forName("org.bukkit.event.block.BlockDispenseArmorEvent");
+ getServer().getPluginManager().registerEvents(new DispenserArmorListener(), this);
+ } catch (Exception localException) {
+ }
+ if (Bukkit.getOnlinePlayers().size() > 0) {
+ Bukkit.getLogger().warning("/reload command is not recommended");
+ Bukkit.getLogger().warning("Might causes problems");
+ Bukkit.getLogger().info("Loading All Online Players..");
+ for (Player player : Bukkit.getServer().getOnlinePlayers()) {
+ Players.loadYaml(player);
+ EventListener.skillmode.put(player, false);
+ Magic.check(player);
+ Main.setPlayerScoreboard(player);
+ YamlConfiguration py = Players.getYaml(player);
+ int a = py.getInt("Scale");
+ if (a > 0) {
+ player.setHealthScale(a);
+ }
+ PlayerData pd = Players.Data.get(player);
+
+ float speed = 0.0f;
+ double hp = 0.0;
+ double mp = 0.0;
+ double ar = 0.0;
+ double at = 0.0;
+ ItemStack helmet = player.getInventory().getHelmet();
+ ModifyItem.updateItem(helmet, EquipmentSlot.HEAD);
+ mp += ModifyItem.getItemMP(helmet);
+ hp += ModifyItem.getItemHP(helmet);
+ speed += ModifyItem.getItemSD(helmet);
+ ar += ModifyItem.getItemAR(helmet);
+ at += ModifyItem.getItemAT(helmet);
+
+ ItemStack chest = player.getInventory().getChestplate();
+ ModifyItem.updateItem(chest, EquipmentSlot.CHEST);
+ mp += ModifyItem.getItemMP(chest);
+ hp += ModifyItem.getItemHP(chest);
+ speed += ModifyItem.getItemSD(chest);
+ ar += ModifyItem.getItemAR(chest);
+ at += ModifyItem.getItemAT(chest);
+
+ ItemStack leg = player.getInventory().getLeggings();
+ ModifyItem.updateItem(leg, EquipmentSlot.LEGS);
+ mp += ModifyItem.getItemMP(leg);
+ hp += ModifyItem.getItemHP(leg);
+ speed += ModifyItem.getItemSD(leg);
+ ar += ModifyItem.getItemAR(leg);
+ at += ModifyItem.getItemAT(leg);
+
+ ItemStack boot = player.getInventory().getBoots();
+ ModifyItem.updateItem(boot, EquipmentSlot.FEET);
+ mp += ModifyItem.getItemMP(boot);
+ hp += ModifyItem.getItemHP(boot);
+ speed += ModifyItem.getItemSD(boot);
+ ar += ModifyItem.getItemAR(boot);
+ at += ModifyItem.getItemAT(boot);
+
+ ItemStack off = player.getInventory().getItemInOffHand();
+ ModifyItem.updateItem(off, EquipmentSlot.OFF_HAND);
+ mp += ModifyItem.getItemMP(off);
+ hp += ModifyItem.getItemHP(off);
+ speed += ModifyItem.getItemSD(off);
+ ar += ModifyItem.getItemAR(off);
+ at += ModifyItem.getItemAT(off);
+ pd.calc(player, mp, hp, speed, ar, at);
+ EventListener.setData(player, pd);
+ }
+ }
+
+ loaded = true;
+ a();
+ b();
+ Bukkit.getLogger().info("NRPG is loaded");
+ }
+
+ private static void a() {
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ if (!loaded) {
+ this.cancel();
+ }
+ for (Player player : Bukkit.getServer().getOnlinePlayers()) {
+ if (!player.isDead()) {
+ PlayerData pd = Players.Data.get(player);
+ pd.addCurrentMP(Utils.RMP);
+ double hp = player.getHealth();
+ double max = player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
+ if (hp + Utils.RHP < max) {
+ player.setHealth(hp + Utils.RHP);
+ } else if (hp < max) {
+ player.setHealth(max);
+ }
+ }
+ }
+
+ }
+ }.runTaskTimerAsynchronously(Main.getPlugin(), 200, 200);
+ }
+
+ private static void b() {
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ if (!loaded) {
+ this.cancel();
+ }
+ for (Player player : Bukkit.getServer().getOnlinePlayers()) {
+ Main.updateScoreBoard(player);
+ }
+
+ }
+ }.runTaskTimerAsynchronously(Main.getPlugin(), 5, 5);
+ }
+
+ private static Scoreboard board;
+ private static Objective o;
+
+ public static void setPlayerScoreboard(Player p) {
+ PlayerData pd = Players.Data.get(p);
+ board = Bukkit.getServer().getScoreboardManager().getNewScoreboard();
+ o = board.registerNewObjective("NRPG", "dummy", "狀態欄");
+ o.setDisplayName(ChatColor.GOLD + "狀態欄");
+ o.setDisplaySlot(DisplaySlot.SIDEBAR);
+ Team HP = board.registerNewTeam("HP");
+ Team MP = board.registerNewTeam("MP");
+ HP.addEntry("" + ChatColor.RED + ChatColor.RED);
+ MP.addEntry("" + ChatColor.LIGHT_PURPLE + ChatColor.LIGHT_PURPLE);
+ DecimalFormat dff = new DecimalFormat("#");
+ HP.setPrefix(ChatColor.RED + "HP:" + dff.format(p.getHealth()) + "/"
+ + dff.format(p.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()));
+ o.getScore("" + ChatColor.RED + ChatColor.RED).setScore(14);
+ MP.setPrefix(ChatColor.LIGHT_PURPLE + "MP:" + dff.format(pd.getCurrentMP()) + "/" + dff.format(pd.getMaxMana()));
+ o.getScore("" + ChatColor.LIGHT_PURPLE + ChatColor.LIGHT_PURPLE).setScore(13);
+ p.setScoreboard(board);
+ }
+
+ public static void updateScoreBoard(Player player) {
+ PlayerData pd = Players.Data.get(player);
+ DecimalFormat dff = new DecimalFormat("#");
+ Scoreboard board = player.getScoreboard();
+ board.getTeam("HP").setPrefix(ChatColor.RED + "HP:" + dff.format(player.getHealth()) + "/"
+ + dff.format(player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()));
+ board.getTeam("MP")
+ .setPrefix(ChatColor.LIGHT_PURPLE + "MP:" + dff.format(pd.getCurrentMP()) + "/" + dff.format(pd.getMaxMana()));
+ }
+
+ public void onDisable() {
+ Bukkit.getLogger().info("Disabling NRPG");
+ loaded = false;
+
+ NewSkill.unloadAllSkills();
+ for (Player player : Bukkit.getServer().getOnlinePlayers()) {
+ player.closeInventory();
+ if (EventListener.backup.containsKey(player)) {
+ PlayerInventory inv = player.getInventory();
+ ItemStack[] back = EventListener.backup.get(player);
+ int i = 0;
+ for (ItemStack item : back) {
+ inv.setItem(i, item);
+ i++;
+ }
+ double d;
+ if (EventListener.extra.containsKey(player)) {
+ d = EventListener.extra.get(player);
+ } else {
+ d = 0;
+ }
+ EventListener.skillmode.put(player, false);
+ player.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE)
+ .setBaseValue(player.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE).getBaseValue() - d);
+ EventListener.extra.remove(player);
+ EventListener.castmod.remove(player);
+ }
+ Players.unload(player);
+ player.kickPlayer("伺服器重新載入中");
+ }
+ Bukkit.getLogger().info("NRPG Disabled");
+ }
+
+ public static Plugin getPlugin() {
+ return plugin;
+ }
+
+}
diff --git a/src/main/java/nashi/NRPG/Players/Leveling.java b/src/main/java/nashi/NRPG/Players/Leveling.java
new file mode 100644
index 0000000..58f0c60
--- /dev/null
+++ b/src/main/java/nashi/NRPG/Players/Leveling.java
@@ -0,0 +1,64 @@
+package nashi.NRPG.Players;
+
+import java.io.File;
+import java.util.HashMap;
+
+import org.bukkit.Bukkit;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.entity.Player;
+import org.bukkit.scheduler.BukkitRunnable;
+
+import nashi.NRPG.Main;
+import nashi.NRPG.API.SkillAPI;
+import nashi.NRPG.API.Utils.Status;
+import nashi.NRPG.listeners.MythicMobsListener;
+
+public class Leveling {
+ public static YamlConfiguration setting;
+
+ public static void init() {
+ setting = YamlConfiguration
+ .loadConfiguration(new File(Main.getPlugin().getDataFolder() + File.separator + "mobs.yml"));
+
+ }
+
+ public static void check(Player player) {
+ try {
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ HashMap map = MythicMobsListener.MobsKilled.get(player);
+ Players.PlayerData pd = Players.Data.get(player);
+ Status s = pd.getStatus();
+ int level = s.getLvL();
+ for (String key : Leveling.setting.getConfigurationSection("" + level).getKeys(false)) {
+ boolean b = true;
+ for (String type : Leveling.setting.getConfigurationSection("" + level + "." + key)
+ .getKeys(false)) {
+ int a = Leveling.setting.getInt("" + level + "." + key + "." + type);
+ if (!map.containsKey(type)) {
+ b = false;
+ break;
+ }
+ if (map.get(type) < a) {
+ b = false;
+ break;
+ }
+ }
+ if (b) {
+ s.setLvL(level + 1);
+ map.clear();
+ MythicMobsListener.MobsKilled.put(player, map);
+ Bukkit.getScheduler().scheduleSyncDelayedTask(SkillAPI.plugin(), new Runnable() {
+ public void run() {
+ Players.recalcData(player, pd);
+ }
+ }, 0);
+ }
+ }
+ }
+ }.runTaskLaterAsynchronously(Main.getPlugin(), 0);
+ } catch (Exception e) {
+ }
+ }
+}
diff --git a/src/main/java/nashi/NRPG/Players/Players.java b/src/main/java/nashi/NRPG/Players/Players.java
new file mode 100644
index 0000000..c8a47dd
--- /dev/null
+++ b/src/main/java/nashi/NRPG/Players/Players.java
@@ -0,0 +1,528 @@
+package nashi.NRPG.Players;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+
+import org.bukkit.Bukkit;
+import org.bukkit.attribute.Attribute;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.EquipmentSlot;
+import org.bukkit.inventory.ItemStack;
+
+import nashi.NRPG.Skills.Cast;
+import nashi.NRPG.Skills.Magic;
+import nashi.NRPG.listeners.EventListener;
+import nashi.NRPG.listeners.ModifyItem;
+import nashi.NRPG.listeners.MythicMobsListener;
+import nashi.NRPG.Main;
+import nashi.NRPG.API.SkillAPI;
+import nashi.NRPG.API.Utils;
+import nashi.NRPG.API.Utils.Status;
+import nashi.NRPG.Commands.RaceCommand;
+import nashi.NRPG.CustomEvents.RaceChangeEvent;
+import nashi.NRPG.Items.CreateItem;
+import nashi.NRPG.Players.Races.Race;
+
+public class Players {
+ public static HashMap file = new HashMap();
+ public static YamlConfiguration skillsetting;
+ public static YamlConfiguration mobsetting;
+ public static HashMap Data = new HashMap();
+
+ public static YamlConfiguration getYaml(Player player) {
+ return file.get(player);
+ }
+
+ public static void loadYaml(Player player) {
+ // File p = new File(
+ // Main.getPlugin().getDataFolder() + File.separator + "players" +
+ // File.separator + "players.yml");
+
+ File f = new File(Main.getPlugin().getDataFolder() + File.separator + "players" + File.separator
+ + player.getUniqueId().toString() + ".yml");
+ HashMap map = new HashMap();
+ if (!f.exists()) {
+ try {
+ f.createNewFile();
+ YamlConfiguration y = YamlConfiguration.loadConfiguration(f);
+ y.set("ID", player.getName());
+ y.set("CastSpeed", 10);
+ y.set("Race", Races.defaultRace.getName());
+ Status stat = Utils.getStatusFromInt(player.getUniqueId().hashCode());
+ Utils.setPlayerStatus(player, stat);
+ y.set("Status.ATK", stat.getATK());
+ y.set("Status.SKL", stat.getSKL());
+ y.set("Status.AR", stat.getArmor());
+ y.set("Status.AT", stat.getArmorToughness());
+ y.set("Status.Speed", stat.getSpeed());
+ y.set("Status.HP", stat.getHP());
+ y.set("Status.MP", stat.getMP());
+ y.set("Status.LUK", stat.getLucky());
+ y.set("Status.LVL", stat.getLvL());
+ y.set("UniqueSkillSlots",
+ Utils.MaxSlot
+ - (stat.getSKL() + stat.getATK() + stat.getHP() + stat.getLucky() + stat.getSpeed()
+ + stat.getMP() + stat.getArmor() + stat.getArmorToughness()) / Utils.STATRAND);
+ y.set("UsedSlots", 0);
+ y.set("Exterior", false);
+ file.put(player, y);
+ Cast.castspeed.put(player, 10);
+ RaceCommand.disable(player);
+ y.save(f);
+ Data.put(player, new PlayerData(player, stat));
+ y.set("MP", Data.get(player).getCurrentMP());
+ if ((stat.getATK() + stat.getSKL() + stat.getHP() + stat.getLucky() + stat.getSpeed() + stat.getMP()
+ + stat.getArmor() + stat.getArmorToughness()) < ((Utils.STATRAND) + 1) * 8 * Utils.MakeUpMod) {
+ Magic.learnSkill(player, Utils.getRandomMakeUpSkills(), true);
+ }
+ /*
+ * if (!p.exists()) { try { p.createNewFile(); YamlConfiguration py =
+ * YamlConfiguration.loadConfiguration(p); if
+ * (!py.contains(player.getUniqueId().toString())) {
+ * py.set(player.getUniqueId().toString(), true); py.save(p); if ((stat.getATK()
+ * + stat.getHP() + stat.getLucky() + stat.getSpeed() + stat.getMP() +
+ * stat.getArmor() + stat.getArmorToughness()) < ((Utils.STATRAND) + 1) * 7
+ * Utils.MakeUpMod) { Magic.learnSkill(player, Utils.getRandomMakeUpSkills(),
+ * true); } } } catch (IOException e) { e.printStackTrace(); } } else {
+ * YamlConfiguration py = YamlConfiguration.loadConfiguration(p); if
+ * (!py.contains(player.getUniqueId().toString())) {
+ * py.set(player.getUniqueId().toString(), true); py.save(p); if ((stat.getATK()
+ * + stat.getHP() + stat.getLucky() + stat.getSpeed() + stat.getMP() +
+ * stat.getArmor() + stat.getArmorToughness()) < ((Utils.STATRAND) + 1) * 7
+ * Utils.MakeUpMod) { Magic.learnSkill(player, Utils.getRandomMakeUpSkills()); }
+ * } }
+ */
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ } else {
+ YamlConfiguration y = YamlConfiguration.loadConfiguration(f);
+ file.put(player, y);
+ Cast.castspeed.put(player, y.getInt("CastSpeed"));
+ int lvl = y.getInt("Status.LVL");
+ if (lvl <= 0) {
+ lvl = 1;
+ }
+ Status stat = new Status(y.getInt("Status.SKL"), y.getInt("Status.AR"), y.getInt("Status.AT"),
+ y.getInt("Status.ATK"), y.getInt("Status.Speed"), y.getInt("Status.HP"), y.getInt("Status.MP"),
+ y.getInt("Status.LUK"), lvl);
+ Utils.setPlayerStatus(player, stat);
+ try {
+ Data.put(player, new PlayerData(player, Races.getRace(y.getString("Race")), stat, y.getDouble("MP")));
+ } catch (Exception e) {
+ Data.put(player,
+ new PlayerData(player, Races.getRace(Races.defaultRace.getName()), stat, y.getDouble("MP")));
+ }
+ if (y.getBoolean("Exterior")) {
+ RaceCommand.enable(player);
+ } else {
+ RaceCommand.disable(player);
+ }
+ try {
+ for (String key : y.getConfigurationSection("MobsKilled").getKeys(false)) {
+ map.put(key, y.getInt("MobsKilled." + key));
+ }
+ } catch (Exception e) {
+ }
+ }
+ MythicMobsListener.MobsKilled.put(player, map);
+ }
+
+ public static void save(Player player) {
+ File f = new File(Main.getPlugin().getDataFolder() + File.separator + "players",
+ player.getUniqueId().toString() + ".yml");
+ PlayerData pd = Data.get(player);
+ YamlConfiguration y = file.get(player);
+ y.set("Race", pd.getRace().getName());
+ y.set("MP", Data.get(player).getCurrentMP());
+ y.set("CastSpeed", Cast.castspeed.get(player));
+ y.set("Status.SKL", pd.getStatus().getSKL());
+ y.set("Status.AR", pd.getStatus().getArmor());
+ y.set("Status.AT", pd.getStatus().getArmorToughness());
+ y.set("Status.ATK", pd.getStatus().getATK());
+ y.set("Status.MP", pd.getStatus().getMP());
+ y.set("Status.LUK", pd.getStatus().getLucky());
+ y.set("Status.HP", pd.getStatus().getHP());
+ y.set("Status.Speed", pd.getStatus().getSpeed());
+ y.set("Status.LVL", pd.getStatus().getLvL());
+ HashMap map = MythicMobsListener.MobsKilled.get(player);
+ try {
+ for (String key : map.keySet()) {
+ y.set("MobsKilled." + key, map.get(key));
+ }
+ } catch (Exception e) {
+ }
+ map.clear();
+ MythicMobsListener.MobsKilled.remove(player);
+ try {
+ y.save(f);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void delete(Player player) {
+ unload(player);
+ File f = new File(Main.getPlugin().getDataFolder() + File.separator + "players",
+ player.getUniqueId().toString() + ".yml");
+ f.delete();
+ loadYaml(player);
+ }
+
+ public static void unload(Player player) {
+ RaceCommand.disable(player);
+ save(player);
+ file.remove(player);
+ }
+
+ public static void recalcData(Player player, PlayerData pd) {
+
+ float speed = 0.0f;
+ double hp = 0.0;
+ double mp = 0.0;
+ double ar = 0.0;
+ double at = 0.0;
+ ItemStack helmet = player.getInventory().getHelmet();
+ if (CreateItem.getItemForgeSlot(helmet) == 4) {
+ ModifyItem.updateItem(helmet, EquipmentSlot.HEAD);
+ mp += ModifyItem.getItemMP(helmet);
+ hp += ModifyItem.getItemHP(helmet);
+ speed += ModifyItem.getItemSD(helmet);
+ ar += ModifyItem.getItemAR(helmet);
+ at += ModifyItem.getItemAT(helmet);
+ }
+
+ ItemStack chest = player.getInventory().getChestplate();
+ if (CreateItem.getItemForgeSlot(chest) == 3) {
+ ModifyItem.updateItem(chest, EquipmentSlot.CHEST);
+ mp += ModifyItem.getItemMP(chest);
+ hp += ModifyItem.getItemHP(chest);
+ speed += ModifyItem.getItemSD(chest);
+ ar += ModifyItem.getItemAR(chest);
+ at += ModifyItem.getItemAT(chest);
+ }
+
+ ItemStack leg = player.getInventory().getLeggings();
+ if (CreateItem.getItemForgeSlot(leg) == 2) {
+ ModifyItem.updateItem(leg, EquipmentSlot.LEGS);
+ mp += ModifyItem.getItemMP(leg);
+ hp += ModifyItem.getItemHP(leg);
+ speed += ModifyItem.getItemSD(leg);
+ ar += ModifyItem.getItemAR(leg);
+ at += ModifyItem.getItemAT(leg);
+ }
+
+ ItemStack boot = player.getInventory().getBoots();
+ if (CreateItem.getItemForgeSlot(boot) == 1) {
+ ModifyItem.updateItem(boot, EquipmentSlot.FEET);
+ mp += ModifyItem.getItemMP(boot);
+ hp += ModifyItem.getItemHP(boot);
+ speed += ModifyItem.getItemSD(boot);
+ ar += ModifyItem.getItemAR(boot);
+ at += ModifyItem.getItemAT(boot);
+ }
+
+ ItemStack off = player.getInventory().getItemInOffHand();
+ if (CreateItem.getItemForgeSlot(off) == 5) {
+ ModifyItem.updateItem(off, EquipmentSlot.OFF_HAND);
+ mp += ModifyItem.getItemMP(off);
+ hp += ModifyItem.getItemHP(off);
+ speed += ModifyItem.getItemSD(off);
+ ar += ModifyItem.getItemAR(off);
+ at += ModifyItem.getItemAT(off);
+ }
+
+ pd.calc(player, mp, hp, speed, ar, at);
+ EventListener.setData(player, pd);
+
+ }
+
+ public static class PlayerData {
+ private double hp;
+ private double mp;
+ private double dmg;
+ private double dmg_skill;
+ private double dmg_range;
+ private float spd;
+ private double avd;
+ private double crit;
+ private Status stat;
+ private double CurrentMP;
+ private Race race;
+ public double armor;
+ public double armor_toughness;
+
+ private double STSKL;
+ private double STATK;
+ private double STHP;
+ private double STSPD;
+ private double STLUK;
+ private double STMP;
+ private double STAR;
+ private double START;
+
+ public PlayerData(Player player, Race race, Status stat, double currentMP) {
+ this.race = race;
+ this.stat = stat;
+
+ this.STAR = stat.getArmor() * race.getArmorMod();
+ this.START = stat.getArmorToughness() * race.getArmorToughnessMod();
+ this.STSKL = stat.getSKL() * race.getSkillModify();
+ this.STATK = stat.getATK() * race.getAttackModify();
+ this.STHP = stat.getHP() * race.getHealthModify();
+ this.STSPD = stat.getSpeed() * race.getSpeedModify();
+ this.STMP = stat.getMP() * race.getManaModify();
+ this.STLUK = stat.getLucky() * race.getLuckyModify();
+ double temp = this.STHP * Utils.HPHealth * Utils.basehp * stat.getLvL();
+ if (temp < 1) {
+ temp = 1;
+ }
+ this.hp = temp;
+ this.mp = (this.STMP) * Utils.ManaMP * Utils.basemp * stat.getLvL();
+ if (this.STSPD * Utils.SPDSpeed + Utils.basespd > 1) {
+ this.spd = 1;
+ } else {
+ this.spd = (float) (this.STSPD * Utils.SPDSpeed + Utils.basespd);
+ }
+ this.avd = this.STLUK * Utils.LUKAVD;
+ this.crit = this.STLUK * Utils.LUKCRIT;
+ this.dmg_skill = (this.STSKL);
+ this.dmg = (this.STATK);
+ this.dmg_range = (stat.getATK() * race.getRangeModify());
+ player.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE).setBaseValue(1);
+ this.CurrentMP = currentMP;
+ }
+
+ public void setRace(Player player, Race race) {
+ Race old = this.race;
+ this.race = race;
+ YamlConfiguration yml = getYaml(player);
+ int slot = yml.getInt("UniqueSkillSlots") + race.getSlotModify() - old.getSlotModify();
+ yml.set("UniqueSkillSlots", slot);
+ for (String skillname : yml.getStringList("UniqeSkills")) {
+ try {
+ for (String str : yml.getConfigurationSection("Skills." + skillname + ".Max").getKeys(false)) {
+ double ori = yml.getDouble("Skills." + skillname + ".Max." + str);
+ PlayerData st = Players.Data.get(player);
+ double mod;
+ int i = (int) SkillAPI.getPublicSkillInfo(skillname, "ModType");
+ switch (i) {
+ case 1:
+ mod = st.getTotalStatusATK();
+ break;
+ case 2:
+ mod = st.getTotalStatusHP();
+ break;
+ case 3:
+ mod = st.getTotalStatusMP();
+ break;
+ case 4:
+ mod = st.getTotalStatusSpeed();
+ break;
+ case 5:
+ mod = st.getTotalStatusLUK();
+ break;
+ case 6:
+ mod = st.getTotalStatusSKL();
+ break;
+ default:
+ mod = 1;
+ break;
+ }
+ yml.set("Skills." + skillname + ".Max." + str,
+ ori * yml.getDouble("Skills." + skillname + ".Mod." + str) * mod);
+ }
+ } catch (Exception e1) {
+ }
+ }
+ this.STAR = stat.getArmor() * race.getArmorMod();
+ this.START = stat.getArmorToughness() * race.getArmorToughnessMod();
+ this.STATK = stat.getATK() * race.getAttackModify();
+ this.STHP = stat.getHP() * race.getHealthModify();
+ this.STSPD = stat.getSpeed() * race.getSpeedModify();
+ this.STMP = stat.getMP() * race.getManaModify();
+ this.STLUK = stat.getLucky() * race.getLuckyModify();
+ this.STSKL = stat.getSKL() * race.getSkillModify();
+ double temp = (this.STHP) * Utils.HPHealth * stat.getLvL() * Utils.basehp;
+ if (temp < 1) {
+ temp = 1;
+ }
+ this.hp = temp;
+ this.mp = (this.STMP) * Utils.ManaMP * stat.getLvL() * Utils.basemp;
+ if ((this.STSPD) * Utils.SPDSpeed + Utils.basespd > 1) {
+ this.spd = 1;
+ } else {
+ this.spd = (float) ((this.STSPD) * Utils.SPDSpeed + Utils.basespd);
+ }
+ this.avd = this.STLUK * Utils.LUKAVD;
+ this.crit = this.STLUK * Utils.LUKCRIT;
+ this.dmg = (this.STATK);
+ this.dmg_skill = (this.STSKL);
+ this.dmg_range = (stat.getATK() * race.getRangeModify());
+ player.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE).setBaseValue(1);
+ Magic.check(player);
+ RaceChangeEvent le = new RaceChangeEvent(player, old, race);
+ Bukkit.getServer().getPluginManager().callEvent(le);
+ }
+
+ public double getTotalStatusArmor() {
+ return this.STAR;
+ }
+
+ public double getTotalStatusArmorToughness() {
+ return this.START;
+ }
+
+ public double getTotalStatusATK() {
+ return this.STATK;
+ }
+
+ public double getTotalStatusHP() {
+ return this.STHP;
+ }
+
+ public double getTotalStatusMP() {
+ return this.STMP;
+ }
+
+ public double getTotalStatusLUK() {
+ return this.STLUK;
+ }
+
+ public double getTotalStatusSpeed() {
+ return this.STSPD;
+ }
+
+ public PlayerData(Player player, Status stat) {
+ this.race = new Race(null, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, null, null);
+ this.stat = stat;
+ setRace(player, Races.defaultRace);
+ this.STAR = stat.getArmor() * race.getArmorMod();
+ this.START = stat.getArmorToughness() * race.getArmorToughnessMod();
+ this.STATK = stat.getATK() * race.getAttackModify();
+ this.STHP = stat.getHP() * race.getHealthModify();
+ this.STSPD = stat.getSpeed() * race.getSpeedModify();
+ this.STMP = stat.getMP() * race.getManaModify();
+ this.STLUK = stat.getLucky() * race.getLuckyModify();
+ double temp = this.STHP * Utils.HPHealth * Utils.basehp * stat.getLvL();
+ if (temp < 1) {
+ temp = 1;
+ }
+ this.hp = temp;
+ this.mp = this.STMP * Utils.ManaMP * Utils.basemp * stat.getLvL();
+ if (this.STSPD * Utils.SPDSpeed + Utils.basespd > 1) {
+ this.spd = 1;
+ } else {
+ this.spd = (float) (this.STSPD * Utils.SPDSpeed + Utils.basespd);
+ }
+ this.avd = (stat.getLucky() + race.getLuckyModify()) * Utils.LUKAVD;
+ this.crit = (stat.getLucky() + race.getLuckyModify()) * Utils.LUKCRIT;
+ this.dmg = (this.STATK);
+ this.dmg_skill = (this.STSKL);
+ this.dmg_range = (stat.getATK() * race.getRangeModify());
+ player.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE).setBaseValue(1);
+ this.CurrentMP = this.mp;
+ }
+
+ public Race getRace() {
+ return this.race;
+ }
+
+ public double getCurrentMP() {
+ return this.CurrentMP;
+ }
+
+ public void setCurrentMP(double mp) {
+ this.CurrentMP = mp;
+ }
+
+ public void addCurrentMP(double amp) {
+ if (this.CurrentMP + amp < 0) {
+ this.CurrentMP = 0;
+ } else if (this.CurrentMP + amp >= this.mp) {
+ this.CurrentMP = this.mp;
+ } else {
+ this.CurrentMP += amp;
+ }
+ }
+
+ public double getMaxHealth() {
+ return this.hp;
+ }
+
+ public double getMaxMana() {
+ return this.mp;
+ }
+
+ public float getSpeed() {
+ return this.spd;
+ }
+
+ public double getCrit() {
+ return this.crit;
+ }
+
+ public double getAvoid() {
+ return this.avd;
+ }
+
+ public Status getStatus() {
+ return this.stat;
+ }
+
+ public double getDamage() {
+ return this.dmg * this.stat.getLvL();
+ }
+
+ public double getSkillDamage() {
+ return this.dmg_skill * this.stat.getLvL();
+ }
+
+ public double getRangeDamage() {
+ return this.dmg_range * this.stat.getLvL();
+ }
+
+ public void calc(Player player, double mana, double health, float speed, double ar, double at) {
+ double temp = (this.STHP) * Utils.HPHealth * (Utils.basehp + health) * stat.getLvL();
+ if (temp < 1) {
+ temp = 1;
+ }
+ this.hp = temp;
+ this.mp = this.STMP * Utils.ManaMP * (mana + Utils.basemp) * stat.getLvL();
+ float tempspeed = (float) (this.STSPD * Utils.SPDSpeed * speed + Utils.basespd);
+ if (tempspeed > 1) {
+ this.spd = 1;
+ } else {
+ this.spd = tempspeed;
+ }
+ this.avd = (stat.getLucky() * race.getLuckyModify()) * Utils.LUKAVD;
+ this.crit = (stat.getLucky() * race.getLuckyModify()) * Utils.LUKCRIT;
+ this.dmg = (stat.getATK() * race.getAttackModify());
+ this.dmg_skill = (stat.getSKL() * race.getSkillModify());
+ this.dmg_range = (stat.getATK() * race.getRangeModify());
+ player.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE).setBaseValue(1);
+ armor = (ar) * this.STAR;
+ player.getAttribute(Attribute.GENERIC_ARMOR).setBaseValue(armor);
+ armor_toughness = (at) * this.START;
+ // player.getAttribute(Attribute.GENERIC_ARMOR_TOUGHNESS).setBaseValue(armor_toughness);
+ }
+
+ public boolean costMP(double mp) {
+ if (mp <= 0) {
+ return true;
+ }
+ if (this.CurrentMP - mp >= 0) {
+ this.CurrentMP -= mp;
+ return true;
+ }
+ return false;
+
+ }
+
+ public double getTotalStatusSKL() {
+ return this.STSKL;
+ }
+ }
+}
diff --git a/src/main/java/nashi/NRPG/Players/Races.java b/src/main/java/nashi/NRPG/Players/Races.java
new file mode 100644
index 0000000..415289b
--- /dev/null
+++ b/src/main/java/nashi/NRPG/Players/Races.java
@@ -0,0 +1,355 @@
+package nashi.NRPG.Players;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+
+import org.bukkit.ChatColor;
+import org.bukkit.Color;
+import org.bukkit.Material;
+import org.bukkit.attribute.Attribute;
+import org.bukkit.attribute.AttributeModifier;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.inventory.EquipmentSlot;
+import org.bukkit.inventory.ItemFlag;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.Damageable;
+import org.bukkit.inventory.meta.ItemMeta;
+import org.bukkit.inventory.meta.LeatherArmorMeta;
+
+import nashi.NRPG.Main;
+import nashi.NRPG.API.Utils;
+
+public class Races {
+ public static HashMap races = new HashMap();
+ public static Race defaultRace;
+
+ public static Race getRace(String name) {
+ if (races.containsKey(name.toLowerCase())) {
+ return races.get(name.toLowerCase());
+ }
+ return null;
+ }
+
+ public static class Race {
+ private String name;
+ private String displayname;
+ private String des;
+ private int slotmod;
+ private double strmod;
+ private double spdmod;
+ private double hpmod;
+ private double mpmod;
+ private double lukmod;
+ private double rangemod;
+ private List skilllist;
+ ItemStack[] items;
+ private double armod;
+ private double atmod;
+ private double skmod;
+
+ public Race(String name, String display, String des, int slot, double str, double spd, double hp, double mp,
+ double luk, double ar, double at, double rangemod, double skmod, List skills,
+ ItemStack[] armor) {
+ this.des = des;
+ this.name = name;
+ this.displayname = display;
+ this.slotmod = slot;
+ this.strmod = str;
+ this.spdmod = spd;
+ this.hpmod = hp;
+ this.mpmod = mp;
+ this.lukmod = luk;
+ this.skilllist = skills;
+ this.items = armor;
+ this.armod = ar;
+ this.atmod = at;
+ this.rangemod = rangemod;
+ this.skmod = skmod;
+ }
+
+ public String getDescription() {
+ return this.des;
+ }
+
+ public ItemStack[] getArmor() {
+ return this.items.clone();
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public String getDisplayName() {
+ return this.displayname;
+ }
+
+ public List getSkillList() {
+ return this.skilllist;
+ }
+
+ public int getSlotModify() {
+ return this.slotmod;
+ }
+
+ public double getRangeModify() {
+ return this.rangemod;
+ }
+
+ public double getAttackModify() {
+ return this.strmod;
+ }
+
+ public double getHealthModify() {
+ return this.hpmod;
+ }
+
+ public double getManaModify() {
+ return this.mpmod;
+ }
+
+ public double getSkillModify() {
+ return this.skmod;
+ }
+
+ public double getLuckyModify() {
+ return this.lukmod;
+ }
+
+ public double getSpeedModify() {
+ return this.spdmod;
+ }
+
+ public double getArmorMod() {
+ return this.armod;
+ }
+
+ public double getArmorToughnessMod() {
+ return this.atmod;
+ }
+
+ }
+
+ public static void init() {
+ races.clear();
+ defaultRace = null;
+ YamlConfiguration yml = YamlConfiguration
+ .loadConfiguration(new File(Main.getPlugin().getDataFolder() + File.separator + "races.yml"));
+ Set key = yml.getKeys(false);
+ for (String name : key) {
+ String display = yml.getString(name + ".DisplayName");
+ String des = yml.getString(name + ".Info");
+ List skills = yml.getStringList(name + ".SkillList");
+ int slot = yml.getInt(name + ".Mod.Slot");
+ double atk = yml.getDouble(name + ".Mod.ATK");
+ double luk = yml.getDouble(name + ".Mod.LUK");
+ double spd = yml.getDouble(name + ".Mod.Speed");
+ double mp = yml.getDouble(name + ".Mod.MP");
+ double hp = yml.getDouble(name + ".Mod.HP");
+ double at = yml.getDouble(name + ".Mod.AT");
+ double sk = yml.getDouble(name + ".Mod.SKL");
+ double ar = yml.getDouble(name + ".Mod.AR");
+ double range = yml.getDouble(name + ".Mod.RG");
+ String[] color;
+ int red;
+ int green;
+ int blue;
+
+ ItemStack[] items = new ItemStack[5];
+ ItemStack helmet = null;
+ if (yml.getBoolean(name + ".Items.Helmet.enable")) {
+ String helmat = yml.getString(name + ".Items.Helmet.Material");
+ helmet = new ItemStack(Material.valueOf(helmat));
+ Utils.setNotDrop(helmet);
+ if (helmat.toLowerCase().contains("leather")) {
+ LeatherArmorMeta lam = (LeatherArmorMeta) helmet.getItemMeta();
+ lam.addAttributeModifier(Attribute.GENERIC_ARMOR, new AttributeModifier(UUID.randomUUID(),
+ "NRPGMOD", 0, AttributeModifier.Operation.ADD_NUMBER, EquipmentSlot.HEAD));
+ color = yml.getString(name + ".Items.Helmet.Color").replaceAll(" ", "").split(",");
+ red = Integer.parseInt(color[0]);
+ green = Integer.parseInt(color[1]);
+ blue = Integer.parseInt(color[2]);
+ lam.setColor(Color.fromRGB(red, green, blue));
+ ((Damageable) lam).setDamage(yml.getInt(name + ".Items.Helmet.damage"));
+ String itemname = yml.getString(name + ".Items.Helmet.DisplayName");
+ if (itemname != null) {
+ lam.setDisplayName(ChatColor.translateAlternateColorCodes('&', itemname));
+ }
+ lam.addItemFlags(ItemFlag.HIDE_UNBREAKABLE);
+ lam.setUnbreakable(true);
+ helmet.setItemMeta(lam);
+ } else {
+ ItemMeta lam = helmet.getItemMeta();
+ lam.addAttributeModifier(Attribute.GENERIC_ARMOR, new AttributeModifier(UUID.randomUUID(),
+ "NRPGMOD", 0, AttributeModifier.Operation.ADD_NUMBER, EquipmentSlot.HEAD));
+ ((Damageable) lam).setDamage(yml.getInt(name + ".Items.Helmet.damage"));
+ lam.addItemFlags(ItemFlag.HIDE_UNBREAKABLE);
+ lam.setUnbreakable(true);
+ String itemname = yml.getString(name + ".Items.Helmet.DisplayName");
+ if (itemname != null) {
+ lam.setDisplayName(ChatColor.translateAlternateColorCodes('&', itemname));
+ }
+ helmet.setItemMeta(lam);
+ }
+ }
+
+ ItemStack chestplate = null;
+ if (yml.getBoolean(name + ".Items.Chestplate.enable")) {
+ String mat = yml.getString(name + ".Items.Chestplate.Material");
+ chestplate = new ItemStack(Material.valueOf(mat));
+ Utils.setNotDrop(chestplate);
+ if (mat.toLowerCase().contains("leather")) {
+ LeatherArmorMeta lam = (LeatherArmorMeta) chestplate.getItemMeta();
+ lam.addAttributeModifier(Attribute.GENERIC_ARMOR, new AttributeModifier(UUID.randomUUID(),
+ "NRPGMOD", 0, AttributeModifier.Operation.ADD_NUMBER, EquipmentSlot.CHEST));
+ color = yml.getString(name + ".Items.Chestplate.Color").replaceAll(" ", "").split(",");
+ red = Integer.parseInt(color[0]);
+ green = Integer.parseInt(color[1]);
+ blue = Integer.parseInt(color[2]);
+ lam.setColor(Color.fromRGB(red, green, blue));
+ ((Damageable) lam).setDamage(yml.getInt(name + ".Items.Chestplate.damage"));
+ lam.addItemFlags(ItemFlag.HIDE_UNBREAKABLE);
+ lam.setUnbreakable(true);
+ String itemname = yml.getString(name + ".Items.Chestplate.DisplayName");
+ if (itemname != null) {
+ lam.setDisplayName(ChatColor.translateAlternateColorCodes('&', itemname));
+ }
+ chestplate.setItemMeta(lam);
+ } else {
+ ItemMeta lam = chestplate.getItemMeta();
+ lam.addAttributeModifier(Attribute.GENERIC_ARMOR, new AttributeModifier(UUID.randomUUID(),
+ "NRPGMOD", 0, AttributeModifier.Operation.ADD_NUMBER, EquipmentSlot.CHEST));
+ ((Damageable) lam).setDamage(yml.getInt(name + ".Items.Chestplate.damage"));
+ lam.addItemFlags(ItemFlag.HIDE_UNBREAKABLE);
+ lam.setUnbreakable(true);
+ String itemname = yml.getString(name + ".Items.Chestplate.DisplayName");
+ if (itemname != null) {
+ lam.setDisplayName(ChatColor.translateAlternateColorCodes('&', itemname));
+ }
+ chestplate.setItemMeta(lam);
+ }
+ }
+
+ ItemStack leggings = null;
+ if (yml.getBoolean(name + ".Items.Leggings.enable")) {
+ String mat = yml.getString(name + ".Items.Leggings.Material");
+ leggings = new ItemStack(Material.valueOf(mat));
+ Utils.setNotDrop(leggings);
+ if (mat.toLowerCase().contains("leather")) {
+ LeatherArmorMeta lam = (LeatherArmorMeta) leggings.getItemMeta();
+ lam.addAttributeModifier(Attribute.GENERIC_ARMOR, new AttributeModifier(UUID.randomUUID(),
+ "NRPGMOD", 0, AttributeModifier.Operation.ADD_NUMBER, EquipmentSlot.LEGS));
+ color = yml.getString(name + ".Items.Leggings.Color").replaceAll(" ", "").split(",");
+ red = Integer.parseInt(color[0]);
+ green = Integer.parseInt(color[1]);
+ blue = Integer.parseInt(color[2]);
+ lam.setColor(Color.fromRGB(red, green, blue));
+ ((Damageable) lam).setDamage(yml.getInt(name + ".Items.Leggings.damage"));
+ lam.addItemFlags(ItemFlag.HIDE_UNBREAKABLE);
+ lam.setUnbreakable(true);
+ String itemname = yml.getString(name + ".Items.Leggings.DisplayName");
+ if (itemname != null) {
+ lam.setDisplayName(ChatColor.translateAlternateColorCodes('&', itemname));
+ }
+ leggings.setItemMeta(lam);
+ } else {
+ ItemMeta lam = leggings.getItemMeta();
+ lam.addAttributeModifier(Attribute.GENERIC_ARMOR, new AttributeModifier(UUID.randomUUID(),
+ "NRPGMOD", 0, AttributeModifier.Operation.ADD_NUMBER, EquipmentSlot.LEGS));
+ ((Damageable) lam).setDamage(yml.getInt(name + ".Items.Leggings.damage"));
+ lam.addItemFlags(ItemFlag.HIDE_UNBREAKABLE);
+ lam.setUnbreakable(true);
+ String itemname = yml.getString(name + ".Items.Leggings.DisplayName");
+ if (itemname != null) {
+ lam.setDisplayName(ChatColor.translateAlternateColorCodes('&', itemname));
+ }
+ leggings.setItemMeta(lam);
+ }
+ }
+ ItemStack boots = null;
+ if (yml.getBoolean(name + ".Items.Boots.enable")) {
+ String mat = yml.getString(name + ".Items.Boots.Material");
+ boots = new ItemStack(Material.valueOf(mat));
+ Utils.setNotDrop(boots);
+ if (mat.toLowerCase().contains("leather")) {
+ LeatherArmorMeta lam = (LeatherArmorMeta) boots.getItemMeta();
+ lam.addAttributeModifier(Attribute.GENERIC_ARMOR, new AttributeModifier(UUID.randomUUID(),
+ "NRPGMOD", 0, AttributeModifier.Operation.ADD_NUMBER, EquipmentSlot.FEET));
+ color = yml.getString(name + ".Items.Boots.Color").replaceAll(" ", "").split(",");
+ red = Integer.parseInt(color[0]);
+ green = Integer.parseInt(color[1]);
+ blue = Integer.parseInt(color[2]);
+ lam.setColor(Color.fromRGB(red, green, blue));
+ ((Damageable) lam).setDamage(yml.getInt(name + ".Items.Boots.damage"));
+ lam.addItemFlags(ItemFlag.HIDE_UNBREAKABLE);
+ lam.setUnbreakable(true);
+ String itemname = yml.getString(name + ".Items.Boots.DisplayName");
+ if (itemname != null) {
+ lam.setDisplayName(ChatColor.translateAlternateColorCodes('&', itemname));
+ }
+ boots.setItemMeta(lam);
+ } else {
+ ItemMeta lam = boots.getItemMeta();
+ lam.addAttributeModifier(Attribute.GENERIC_ARMOR, new AttributeModifier(UUID.randomUUID(),
+ "NRPGMOD", 0, AttributeModifier.Operation.ADD_NUMBER, EquipmentSlot.FEET));
+ ((Damageable) lam).setDamage(yml.getInt(name + ".Items.Boots.damage"));
+ lam.addItemFlags(ItemFlag.HIDE_UNBREAKABLE);
+ lam.setUnbreakable(true);
+ String itemname = yml.getString(name + ".Items.Boots.DisplayName");
+ if (itemname != null) {
+ lam.setDisplayName(ChatColor.translateAlternateColorCodes('&', itemname));
+ }
+ boots.setItemMeta(lam);
+ }
+ }
+ ItemStack off = null;
+ if (yml.getBoolean(name + ".Items.OffHand.enable")) {
+ String mat = yml.getString(name + ".Items.OffHand.Material");
+ off = new ItemStack(Material.valueOf(mat));
+ Utils.setNotDrop(off);
+ if (mat.toLowerCase().contains("leather")) {
+ LeatherArmorMeta lam = (LeatherArmorMeta) off.getItemMeta();
+ lam.addAttributeModifier(Attribute.GENERIC_ARMOR, new AttributeModifier(UUID.randomUUID(),
+ "NRPGMOD", 0, AttributeModifier.Operation.ADD_NUMBER, EquipmentSlot.FEET));
+ color = yml.getString(name + ".Items.OffHand.Color").replaceAll(" ", "").split(",");
+ red = Integer.parseInt(color[0]);
+ green = Integer.parseInt(color[1]);
+ blue = Integer.parseInt(color[2]);
+ lam.setColor(Color.fromRGB(red, green, blue));
+ ((Damageable) lam).setDamage(yml.getInt(name + ".Items.OffHand.damage"));
+ lam.addItemFlags(ItemFlag.HIDE_UNBREAKABLE);
+ lam.setUnbreakable(true);
+ String itemname = yml.getString(name + ".Items.OffHand.DisplayName");
+ if (itemname != null) {
+ lam.setDisplayName(ChatColor.translateAlternateColorCodes('&', itemname));
+ }
+ off.setItemMeta(lam);
+ } else {
+ ItemMeta lam = off.getItemMeta();
+ lam.addAttributeModifier(Attribute.GENERIC_ARMOR, new AttributeModifier(UUID.randomUUID(),
+ "NRPGMOD", 0, AttributeModifier.Operation.ADD_NUMBER, EquipmentSlot.FEET));
+ ((Damageable) lam).setDamage(yml.getInt(name + ".Items.OffHand.damage"));
+ lam.addItemFlags(ItemFlag.HIDE_UNBREAKABLE);
+ lam.setUnbreakable(true);
+ String itemname = yml.getString(name + ".Items.OffHand.DisplayName");
+ if (itemname != null) {
+ lam.setDisplayName(ChatColor.translateAlternateColorCodes('&', itemname));
+ }
+ off.setItemMeta(lam);
+ }
+ }
+ items[0] = helmet;
+ items[1] = chestplate;
+ items[2] = leggings;
+ items[3] = boots;
+ items[4] = off;
+ Race race = new Race(name, display, des, slot, atk, spd, hp, mp, luk, ar, at, range, sk, skills, items);
+ if (yml.getBoolean(name + ".default")) {
+ Races.defaultRace = race;
+ }
+ races.put(name.toLowerCase(), race);
+ }
+ }
+}
diff --git a/src/main/java/nashi/NRPG/Skills/Cast.java b/src/main/java/nashi/NRPG/Skills/Cast.java
new file mode 100644
index 0000000..4f90f6b
--- /dev/null
+++ b/src/main/java/nashi/NRPG/Skills/Cast.java
@@ -0,0 +1,80 @@
+package nashi.NRPG.Skills;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Random;
+import java.util.Set;
+
+import org.bukkit.ChatColor;
+import org.bukkit.entity.Player;
+
+public class Cast {
+ public static long timelimit;
+ public static final int length = 20;
+ public static final String logo = "✡";
+ private static final String normal = "-";
+ public static final ChatColor wrong = ChatColor.YELLOW;
+ public static final ChatColor right = ChatColor.AQUA;
+ public static final ChatColor current = ChatColor.LIGHT_PURPLE;
+
+ public static HashMap castspeed = new HashMap();
+
+ public static class Abracadabra {
+ private String str;
+ private Set pos;
+
+ public Abracadabra(String str, Set set) {
+ this.str = str;
+ this.pos = set;
+ }
+
+ public String getString() {
+ return this.str;
+ }
+
+ public Set getPos() {
+ return this.pos;
+ }
+ }
+
+ public static Abracadabra getabracadabra(int num) {
+ StringBuilder sb = new StringBuilder();
+ Random rand = new Random();
+ int l = 0;
+ Set pos = new HashSet();
+ while (l < length) {
+ l++;
+ sb.append(normal);
+ }
+ l = 0;
+ while (l < num) {
+ int s = rand.nextInt(length);
+ if (!pos.contains(s)) {
+ pos.add(s);
+ l++;
+ } else {
+ while (pos.contains(s)) {
+ s = (s + 1) % length;
+ }
+ pos.add(s);
+ l++;
+ }
+ }
+ for (int i : pos) {
+ sb.replace(i, i + 1, logo);
+ }
+ Abracadabra a = new Abracadabra(sb.toString(), pos);
+ return a;
+ }
+
+ public static String getDisplay(String str, int pos) {
+ str = str.replaceAll(logo, right + logo).replaceAll(normal, wrong + normal);
+ String s = str.substring(0, pos * 3) + current;
+ try {
+ s += str.substring(pos * 3 + 2, str.length());
+ } catch (Exception e) {
+
+ }
+ return s;
+ }
+}
diff --git a/src/main/java/nashi/NRPG/Skills/GUI.java b/src/main/java/nashi/NRPG/Skills/GUI.java
new file mode 100644
index 0000000..bb4bcd8
--- /dev/null
+++ b/src/main/java/nashi/NRPG/Skills/GUI.java
@@ -0,0 +1,162 @@
+package nashi.NRPG.Skills;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Set;
+
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.Material;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+
+import nashi.NRPG.API.Utils;
+import nashi.NRPG.CustomEvents.SkillItemGenerateEvent;
+import nashi.NRPG.Players.Players;
+
+public class GUI {
+ public static HashMap editpage = new HashMap();
+
+ public static void EditGUI(Player player, int page) {
+ editpage.put(player, page);
+ Inventory inv = Bukkit.createInventory(player, 54, "技能調整介面");
+ YamlConfiguration yml = Players.getYaml(player);
+ // All Skill
+ List skilllist = yml.getStringList("UniqeSkills");
+ int i = 0;
+ int skip = (page - 1) * 53 - 1;
+ for (String skillname : skilllist) {
+ if (i >= 53) {
+ break;
+ }
+ if (skip > 0) {
+ skip--;
+ continue;
+ }
+ try {
+ if (yml.getConfigurationSection(("Skills." + skillname + ".Custom")).getKeys(false).size() > 0) {
+ ItemStack item = Utils.getSkillItem(skillname,player);
+ SkillItemGenerateEvent event = new SkillItemGenerateEvent(player, item, skillname);
+ Bukkit.getPluginManager().callEvent(event);
+ inv.setItem(i, item);
+ i++;
+ }
+ } catch (Exception e) {
+ }
+ }
+ if (i >= 53) {
+ ItemStack item = new ItemStack(Material.ARROW);
+ ItemMeta im = item.getItemMeta();
+ im.setDisplayName(ChatColor.GREEN + "下一頁");
+ item.setItemMeta(im);
+ Utils.setNotDrop(item);
+ inv.setItem(53, item);
+ }
+ player.openInventory(inv);
+ }
+
+ public static void SlotGUI(Player player, int page) {
+ Inventory inv = Bukkit.createInventory(player, 54, "技能欄位設定");
+ YamlConfiguration yml = Players.getYaml(player);
+ // Current Setting
+ for (int s = 0; s < 9; s++) {
+ String skillname = yml.getString("Slot." + s);
+ if (skillname != null) {
+ ItemStack item = Utils.getSkillItem(skillname,player);
+ inv.setItem(s, item);
+ }
+ }
+ // All Skill
+ List skilllist = yml.getStringList("UniqeSkills");
+ ItemStack b = new ItemStack(Material.BARRIER);
+ Utils.setNotDrop(b);
+ for (int i = 9; i < 18; i++) {
+ inv.setItem(i, b);
+ }
+ int i = 0;
+ int skip = (page - 1) * 35 - 1;
+ for (String skillname : skilllist) {
+ if (i >= 35) {
+ break;
+ }
+ if (skip > 0) {
+ skip--;
+ continue;
+ }
+ ItemStack item = Utils.getSkillItem(skillname,player);
+ inv.setItem(i + 18, item);
+ i++;
+ }
+ if (i >= 35) {
+ ItemStack item = new ItemStack(Material.ARROW);
+ ItemMeta im = item.getItemMeta();
+ im.setDisplayName(ChatColor.GREEN + "下一頁");
+ item.setItemMeta(im);
+ Utils.setNotDrop(item);
+ inv.setItem(53, item);
+ }
+ player.openInventory(inv);
+ }
+
+ public static void openSkillEditGUI(Player player, String skillname) {
+ YamlConfiguration yml = Players.getYaml(player);
+ Inventory inv = Bukkit.createInventory(player, 27, "技能設定-" + skillname);
+ ItemStack skill = new ItemStack(Material.ENCHANTED_BOOK);
+ ItemMeta skillmeta = skill.getItemMeta();
+ skillmeta.setDisplayName(ChatColor.LIGHT_PURPLE + skillname);
+ skill.setItemMeta(skillmeta);
+ inv.setItem(9, skill);
+ Set key = yml.getConfigurationSection("Skills." + skillname + ".Custom").getKeys(false);
+ int t = 1;
+ int m = 10;
+ int b = 19;
+ if (key.size() <= 0) {
+ player.sendMessage(ChatColor.RED + "此技能沒有可調整的數值");
+ return;
+ }
+ for (String str : key) {
+ if (t >= 8) {
+ break;
+ }
+ ItemStack top = new ItemStack(Material.GREEN_WOOL);
+ ItemStack mid = new ItemStack(Material.ACACIA_SIGN);
+ ItemStack bot = new ItemStack(Material.RED_WOOL);
+ ItemMeta tm = top.getItemMeta();
+ ItemMeta mm = mid.getItemMeta();
+ ItemMeta bm = bot.getItemMeta();
+ tm.setDisplayName(ChatColor.GREEN + "提升:" + str);
+ mm.setDisplayName(ChatColor.GOLD + str + "數值");
+ bm.setDisplayName(ChatColor.RED + "降低:" + str);
+ List tl = new ArrayList();// L 0.01 R 0.1 SL 0.05 SR 0.5
+ tl.add(ChatColor.YELLOW + "點此左鍵來提升0.01");
+ tl.add(ChatColor.YELLOW + "點此Shift+左鍵來提升0.1");
+ tl.add(ChatColor.YELLOW + "點此右鍵來提升1");
+ tl.add(ChatColor.YELLOW + "點此Shift+右鍵來提升10");
+ List bl = new ArrayList();// L 0.01 R 0.1 SL 0.05 SR 0.5
+ bl.add(ChatColor.YELLOW + "點此左鍵來降低0.01");
+ bl.add(ChatColor.YELLOW + "點此Shift+左鍵來降低0.1");
+ bl.add(ChatColor.YELLOW + "點此右鍵來降低1");
+ bl.add(ChatColor.YELLOW + "點此Shift+右鍵來降低10");
+ List ml = new ArrayList();
+ ml.add(ChatColor.YELLOW + "當前: " + yml.getString("Skills." + skillname + ".Custom." + str));
+ ml.add(ChatColor.YELLOW + "最大: " + yml.getString("Skills." + skillname + ".Max." + str));
+ tm.setLore(tl);
+ mm.setLore(ml);
+ bm.setLore(bl);
+ top.setItemMeta(tm);
+ mid.setItemMeta(mm);
+ bot.setItemMeta(bm);
+ inv.setItem(t, top);
+ inv.setItem(m, mid);
+ inv.setItem(b, bot);
+ t++;
+ m++;
+ b++;
+ }
+ player.openInventory(inv);
+ }
+}
diff --git a/src/main/java/nashi/NRPG/Skills/Magic.java b/src/main/java/nashi/NRPG/Skills/Magic.java
new file mode 100644
index 0000000..74f95d8
--- /dev/null
+++ b/src/main/java/nashi/NRPG/Skills/Magic.java
@@ -0,0 +1,219 @@
+package nashi.NRPG.Skills;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.bukkit.Bukkit;
+import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.entity.Player;
+
+import nashi.NRPG.API.SkillAPI;
+import nashi.NRPG.CustomEvents.SkillLearnEvent;
+import nashi.NRPG.Players.Players;
+import nashi.NRPG.Players.Players.PlayerData;
+
+public class Magic {
+ public static boolean learnSkill(Player player, String skillname, boolean isMakeUp) {
+ YamlConfiguration yml = Players.getYaml(player);
+ ConfigurationSection sec = Players.skillsetting.getConfigurationSection(skillname);
+ yml.set("Skills." + skillname, sec);
+ if (isMakeUp) {
+ yml.set("Skills." + skillname + ".isMakeUp", true);
+ }
+ try {
+ for (String str : yml.getConfigurationSection("Skills." + skillname + ".Max").getKeys(false)) {
+ double ori = yml.getDouble("Skills." + skillname + ".Max." + str);
+ PlayerData st = Players.Data.get(player);
+ double mod;
+ int i = (int) SkillAPI.getPublicSkillInfo(skillname, "ModType");
+ switch (i) {
+ case 1:
+ mod = st.getTotalStatusATK();
+ break;
+ case 2:
+ mod = st.getTotalStatusHP();
+ break;
+ case 3:
+ mod = st.getTotalStatusMP();
+ break;
+ case 4:
+ mod = st.getTotalStatusSpeed();
+ break;
+ case 5:
+ mod = st.getTotalStatusLUK();
+ break;
+ default:
+ mod = 1;
+ break;
+ }
+ yml.set("Skills." + skillname + ".Max." + str,
+ ori * yml.getDouble("Skills." + skillname + ".Mod." + str) * mod);
+ }
+ } catch (Exception e) {
+ }
+
+ List list;
+ try {
+ list = yml.getStringList("UniqeSkills");
+ } catch (Exception e) {
+ list = new ArrayList();
+ }
+ if (!list.contains(skillname)) {
+ list.add(skillname);
+ yml.set("UniqeSkills", list);
+ yml.set("UsedSlots", yml.getInt("UsedSlots") + 1);
+ SkillLearnEvent se = new SkillLearnEvent(player, skillname);
+ Bukkit.getServer().getPluginManager().callEvent(se);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public static boolean learnSkill(Player player, String skillname) {
+ YamlConfiguration yml = Players.getYaml(player);
+ ConfigurationSection sec = Players.skillsetting.getConfigurationSection(skillname);
+ yml.set("Skills." + skillname, sec);
+ try {
+ for (String str : yml.getConfigurationSection("Skills." + skillname + ".Max").getKeys(false)) {
+ double ori = yml.getDouble("Skills." + skillname + ".Max." + str);
+ PlayerData st = Players.Data.get(player);
+ double mod;
+ int i = (int) SkillAPI.getPublicSkillInfo(skillname, "ModType");
+ switch (i) {
+ case 1:
+ mod = st.getTotalStatusATK();
+ break;
+ case 2:
+ mod = st.getTotalStatusHP();
+ break;
+ case 3:
+ mod = st.getTotalStatusMP();
+ break;
+ case 4:
+ mod = st.getTotalStatusSpeed();
+ break;
+ case 5:
+ mod = st.getTotalStatusLUK();
+ break;
+ default:
+ mod = 1;
+ break;
+ }
+ yml.set("Skills." + skillname + ".Max." + str,
+ ori * yml.getDouble("Skills." + skillname + ".Mod." + str) * mod);
+ }
+ } catch (Exception e) {
+ }
+
+ List list;
+ try {
+ list = yml.getStringList("UniqeSkills");
+ } catch (Exception e) {
+ list = new ArrayList();
+ }
+ if (!list.contains(skillname)) {
+ list.add(skillname);
+ yml.set("UniqeSkills", list);
+ yml.set("UsedSlots", yml.getInt("UsedSlots") + 1);
+ SkillLearnEvent se = new SkillLearnEvent(player, skillname);
+ Bukkit.getServer().getPluginManager().callEvent(se);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public static void learnGenSkill(Player player, String skillname) {
+ YamlConfiguration yml = Players.getYaml(player);
+ ConfigurationSection sec = Players.skillsetting.getConfigurationSection(skillname);
+ yml.set("Skills." + skillname, sec);
+ List list;
+ try {
+ list = yml.getStringList("UniqeSkills");
+ } catch (Exception e) {
+ list = new ArrayList();
+ }
+ list.add(skillname);
+ yml.set("UniqeSkills", list);
+ try {
+ for (String str : yml.getConfigurationSection("Skills." + skillname + ".Max").getKeys(false)) {
+ double ori = yml.getDouble("Skills." + skillname + ".Max." + str);
+ PlayerData st = Players.Data.get(player);
+ double mod;
+ int i = (int) SkillAPI.getPublicSkillInfo(skillname, "ModType");
+ switch (i) {
+ case 1:
+ mod = st.getTotalStatusATK();
+ break;
+ case 2:
+ mod = st.getTotalStatusHP();
+ break;
+ case 3:
+ mod = st.getTotalStatusMP();
+ break;
+ case 4:
+ mod = st.getTotalStatusSpeed();
+ break;
+ case 5:
+ mod = st.getTotalStatusLUK();
+ break;
+ default:
+ mod = 1;
+ break;
+ }
+ yml.set("Skills." + skillname + ".Max." + str,
+ ori * yml.getDouble("Skills." + skillname + ".Mod." + str) * mod);
+ }
+ } catch (Exception e) {
+ }
+ SkillLearnEvent se = new SkillLearnEvent(player, skillname);
+ Bukkit.getServer().getPluginManager().callEvent(se);
+ }
+
+ public static void check(Player player) {
+ Set add = new HashSet();
+ YamlConfiguration y = Players.getYaml(player);
+ List set;
+ try {
+ set = y.getStringList("UniqeSkills");
+ } catch (NullPointerException e) {
+ set = new ArrayList();
+ }
+ try {
+ for (String str : Skill.GeneralSkills) {
+ if (!set.contains(str)) {
+ add.add(str);
+ }
+ }
+ } catch (NullPointerException e) {
+ }
+
+ for (int i = 0; i <= 9; i++) {
+ try {
+ if (!set.contains(y.getString("Slot." + i))) {
+ y.set("Slot." + i, null);
+ }
+ } catch (NullPointerException e) {
+ }
+ }
+
+ try {
+ for (String str : Players.Data.get(player).getRace().getSkillList()) {
+ if (!set.contains(str)) {
+ add.add(str);
+ }
+ }
+ } catch (NullPointerException e) {
+ }
+ try {
+ for (String str : add) {
+ learnGenSkill(player, str);
+ }
+ } catch (NullPointerException e) {
+ }
+ }
+}
diff --git a/src/main/java/nashi/NRPG/Skills/NewSkill.java b/src/main/java/nashi/NRPG/Skills/NewSkill.java
new file mode 100644
index 0000000..999899b
--- /dev/null
+++ b/src/main/java/nashi/NRPG/Skills/NewSkill.java
@@ -0,0 +1,72 @@
+package nashi.NRPG.Skills;
+
+import java.io.File;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+import org.bukkit.entity.Player;
+
+import nashi.NRPG.Main;
+import nashi.NRPG.API.SkillAPI;
+import nashi.NRPG.Skills.Skill.Skills;
+
+public abstract class NewSkill {
+
+ private static void load(File fileEntry) {
+ try {
+ File f = fileEntry;
+ URL u = f.toURI().toURL();
+ URLClassLoader child = new URLClassLoader(new URL[] { u }, Main.class.getClassLoader());
+ Class> clazz = Class.forName(
+ fileEntry.getName().replaceAll(".jar", "") + "." + fileEntry.getName().replaceAll(".jar", ""), true,
+ child);
+ Object s = clazz.getDeclaredConstructor().newInstance();
+ try {
+ Method set = clazz.getMethod("load");
+ set.invoke(s);
+ } catch (Exception e) {
+ }
+ try {
+ String name = fileEntry.getName().replaceAll(".jar", "");
+ if (SkillAPI.getSkillPublicBoolean(name, "general")) {
+ Skill.GeneralSkills.add(name);
+ }
+ Method skill = clazz.getMethod("skill", Player.class);
+ Skill.skills.put(name, new Skill.Skills(skill, s, clazz));
+ SkillName.put(name);
+ } catch (Exception e) {
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void unloadAllSkills() {
+ for (String key : Skill.skills.keySet()) {
+ Skills skill = Skill.skills.get(key);
+ Class> clazz = skill.skill;
+ try {
+ Object s = clazz.getDeclaredConstructor().newInstance();
+ Method set = clazz.getMethod("unload");
+ set.invoke(s);
+ } catch (Exception e) {
+ }
+ }
+ }
+
+ private static void listFilesForFolder(final File folder) {
+ for (final File fileEntry : folder.listFiles()) {
+ if (fileEntry.isDirectory()) {
+ listFilesForFolder(fileEntry);
+ } else {
+ load(fileEntry);
+ }
+ }
+ }
+
+ public static void loadskill() {
+ final File folder = new File(Main.getPlugin().getDataFolder() + File.separator + "skills");
+ listFilesForFolder(folder);
+ }
+}
diff --git a/src/main/java/nashi/NRPG/Skills/Skill.java b/src/main/java/nashi/NRPG/Skills/Skill.java
new file mode 100644
index 0000000..83e7e10
--- /dev/null
+++ b/src/main/java/nashi/NRPG/Skills/Skill.java
@@ -0,0 +1,104 @@
+package nashi.NRPG.Skills;
+
+import java.lang.reflect.Method;
+import java.text.DecimalFormat;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.World;
+import org.bukkit.entity.Player;
+
+import nashi.NRPG.Main;
+import nashi.NRPG.API.SkillAPI;
+import nashi.NRPG.CustomEvents.PreSkillUseEvent;
+import nashi.NRPG.CustomEvents.SkillUsedEvent;
+import nashi.NRPG.Players.Players;
+import nashi.NRPG.Players.Players.PlayerData;
+
+public abstract class Skill {
+ public static HashMap cooldowns = new HashMap();
+ public static HashMap skills = new HashMap();
+ public static Set GeneralSkills = new HashSet();
+ public static DecimalFormat formatter = new DecimalFormat("#.##");
+
+ public static void cast(String skillname, Player player, boolean isSkillItem) {
+ World world = player.getWorld();
+ try {
+ if (Main.worlds.contains(world)) {
+ player.sendMessage(ChatColor.RED + "你無法在這個世界使用技能");
+ return;
+ }
+ } catch (Exception e) {
+ }
+ if (SkillAPI.Silence.containsKey(player.getUniqueId())) {
+ double secondsLeft = SkillAPI.Silence.get(player.getUniqueId()) - System.currentTimeMillis();
+ if (secondsLeft > 0) {
+ player.sendMessage(ChatColor.RED + "你已被沉默 " + Skill.formatter.format((secondsLeft / 1000)) + " 秒");
+ return;
+ }
+ }
+ int cooldownTime = (int) SkillAPI.getPublicSkillInfo(skillname, "Cooldown");
+ if (cooldowns.containsKey(player.getUniqueId() + "." + skillname)) {
+ double secondsLeft = cooldowns.get(player.getUniqueId() + "." + skillname) - System.currentTimeMillis();
+ if (secondsLeft > 0) {
+ player.sendMessage(ChatColor.RED + "技能冷卻時間剩餘:" + Skill.formatter.format((secondsLeft / 1000)) + " 秒");
+ return;
+ }
+ }
+ PlayerData p = Players.Data.get(player);
+ double cost = SkillAPI.getPublicSkillInfo(skillname, "CostMP");
+ if (p.getCurrentMP() - cost < 0) {
+ player.sendMessage(ChatColor.RED + "魔力不足");
+ return;
+ }
+
+ PreSkillUseEvent psue = new PreSkillUseEvent(player, skillname, isSkillItem);
+ Bukkit.getPluginManager().callEvent(psue);
+ if (psue.isCancelled()) {
+ if (psue.toCooldown()) {
+ cooldowns.put(player.getUniqueId() + "." + skillname, System.currentTimeMillis() + cooldownTime);
+ }
+ return;
+ }
+
+ try {
+
+ cooldowns.put(player.getUniqueId() + "." + skillname, System.currentTimeMillis() + cooldownTime);
+ Skills sk = skills.get(skillname);
+ Class> clazz = sk.skill;
+ Object s = clazz.getDeclaredConstructor().newInstance();
+ Method skill = clazz.getMethod("skill", Player.class);
+ boolean b = (boolean) skill.invoke(s, player);
+ if (!b) {
+ cooldowns.put(player.getUniqueId() + "." + skillname, (long) (-cooldownTime));
+ }
+
+ SkillUsedEvent sue = new SkillUsedEvent(player, skillname, b);
+ Bukkit.getPluginManager().callEvent(sue);
+
+ } catch (Exception e) {
+ if (e instanceof NoSuchMethodException) {
+ return;
+ }
+ e.printStackTrace();
+ }
+ return;
+ }
+
+ public static class Skills {
+ public Method method;
+ public Object object;
+ public Class> skill;
+
+ public Skills(Method l, Object v, Class> c) {
+ method = l;
+ object = v;
+ skill = c;
+ }
+
+ }
+
+}
diff --git a/src/main/java/nashi/NRPG/Skills/SkillItem.java b/src/main/java/nashi/NRPG/Skills/SkillItem.java
new file mode 100644
index 0000000..d7d41e2
--- /dev/null
+++ b/src/main/java/nashi/NRPG/Skills/SkillItem.java
@@ -0,0 +1,123 @@
+package nashi.NRPG.Skills;
+
+import org.bukkit.Material;
+import org.bukkit.NamespacedKey;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+import org.bukkit.persistence.PersistentDataContainer;
+import org.bukkit.persistence.PersistentDataType;
+
+import nashi.NRPG.Main;
+
+public class SkillItem {
+ public static NamespacedKey Item_Skillname = new NamespacedKey(Main.getPlugin(), "NRPG_SkillItem_SkillName");
+ public static NamespacedKey Item_SkillDifficulty = new NamespacedKey(Main.getPlugin(), "NRPG_SkillItem_Difficulty");
+ public static NamespacedKey Item_SkillTime = new NamespacedKey(Main.getPlugin(), "NRPG_SkillItem_Times");
+ public static NamespacedKey Item_SkillLimitTimeUse = new NamespacedKey(Main.getPlugin(),
+ "NRPG_SkillItem_LimitTimeUse");
+ public static NamespacedKey Item_SkillUseDamage = new NamespacedKey(Main.getPlugin(), "NRPG_SkillItem_UseDamage");
+
+
+ public static void setSkillItem(ItemStack item, String skillname, int damage, int time, int limit, int difficulty) {
+ setSkill(item, skillname);
+ setUseDamage(item, damage);
+ setSkillTime(item, time);
+ setSkillLimitTimeUse(item, limit);
+ setSkillDifficulty(item, difficulty);
+ }
+
+ public static void setSkill(ItemStack item, String skillname) {
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ pdc.set(SkillItem.Item_Skillname, PersistentDataType.STRING, skillname);
+ item.setItemMeta(im);
+ }
+
+ public static String getSkill(ItemStack item) {
+ if (item == null || item.getType() == Material.AIR) {
+ return null;
+ }
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ if (pdc.has(SkillItem.Item_Skillname, PersistentDataType.STRING)) {
+ return pdc.get(SkillItem.Item_Skillname, PersistentDataType.STRING);
+ }
+ return null;
+ }
+
+ public static void setUseDamage(ItemStack item, int damage) {
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ pdc.set(SkillItem.Item_SkillUseDamage, PersistentDataType.INTEGER, damage);
+ item.setItemMeta(im);
+ }
+
+ public static int getUseDamage(ItemStack item) {
+ if (item == null || item.getType() == Material.AIR) {
+ return -1;
+ }
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ if (pdc.has(SkillItem.Item_SkillUseDamage, PersistentDataType.INTEGER)) {
+ return pdc.get(SkillItem.Item_SkillUseDamage, PersistentDataType.INTEGER);
+ }
+ return -1;
+ }
+
+ public static void setSkillTime(ItemStack item, int time) {
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ pdc.set(SkillItem.Item_SkillTime, PersistentDataType.INTEGER, time);
+ item.setItemMeta(im);
+ }
+
+ public static int getSkillTime(ItemStack item) {
+ if (item == null || item.getType() == Material.AIR) {
+ return -1;
+ }
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ if (pdc.has(SkillItem.Item_SkillTime, PersistentDataType.INTEGER)) {
+ return pdc.get(SkillItem.Item_SkillTime, PersistentDataType.INTEGER);
+ }
+ return -1;
+ }
+
+ public static void setSkillLimitTimeUse(ItemStack item, int limit) {
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ pdc.set(SkillItem.Item_SkillLimitTimeUse, PersistentDataType.INTEGER, limit);
+ item.setItemMeta(im);
+ }
+
+ public static int getSkillLimitTimeUse(ItemStack item) {
+ if (item == null || item.getType() == Material.AIR) {
+ return -1;
+ }
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ if (pdc.has(SkillItem.Item_SkillLimitTimeUse, PersistentDataType.INTEGER)) {
+ return pdc.get(SkillItem.Item_SkillLimitTimeUse, PersistentDataType.INTEGER);
+ }
+ return -1;
+ }
+
+ public static void setSkillDifficulty(ItemStack item, int difficulty) {
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ pdc.set(SkillItem.Item_SkillDifficulty, PersistentDataType.INTEGER, difficulty);
+ item.setItemMeta(im);
+ }
+
+ public static int getSkillDifficulty(ItemStack item) {
+ if (item == null || item.getType() == Material.AIR) {
+ return -1;
+ }
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ if (pdc.has(SkillItem.Item_SkillDifficulty, PersistentDataType.INTEGER)) {
+ return pdc.get(SkillItem.Item_SkillDifficulty, PersistentDataType.INTEGER);
+ }
+ return -1;
+ }
+}
diff --git a/src/main/java/nashi/NRPG/Skills/SkillName.java b/src/main/java/nashi/NRPG/Skills/SkillName.java
new file mode 100644
index 0000000..17b7c77
--- /dev/null
+++ b/src/main/java/nashi/NRPG/Skills/SkillName.java
@@ -0,0 +1,20 @@
+package nashi.NRPG.Skills;
+
+import java.util.HashMap;
+import java.util.HashSet;
+
+public class SkillName {
+ public static HashMap skillname = new HashMap();
+ public static HashSet SkillList = new HashSet();
+
+ public static void put(String Skillname) {
+ skillname.put(Skillname.toLowerCase(), Skillname);
+ if (!SkillList.contains(Skillname)) {
+ SkillList.add(Skillname);
+ }
+ }
+
+ public static String get(String Skillname) {
+ return skillname.get(Skillname.toLowerCase());
+ }
+}
diff --git a/src/main/java/nashi/NRPG/listeners/AllAboutDamage.java b/src/main/java/nashi/NRPG/listeners/AllAboutDamage.java
new file mode 100644
index 0000000..f90245e
--- /dev/null
+++ b/src/main/java/nashi/NRPG/listeners/AllAboutDamage.java
@@ -0,0 +1,174 @@
+package nashi.NRPG.listeners;
+
+import org.bukkit.Location;
+import org.bukkit.NamespacedKey;
+import org.bukkit.Sound;
+import org.bukkit.attribute.Attribute;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.entity.Player;
+import org.bukkit.entity.Projectile;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.Listener;
+import org.bukkit.event.entity.EntityDamageByEntityEvent;
+import org.bukkit.event.entity.EntityDamageEvent;
+import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
+import org.bukkit.event.entity.EntityDamageEvent.DamageModifier;
+import org.bukkit.event.entity.EntityShootBowEvent;
+
+import nashi.NRPG.Main;
+import nashi.NRPG.API.Utils;
+import nashi.NRPG.Players.Players;
+import nashi.NRPG.Players.Players.PlayerData;
+
+@SuppressWarnings("deprecation")
+public class AllAboutDamage implements Listener {
+ public static NamespacedKey key = new NamespacedKey(Main.getPlugin(), "NRPG_ItemsNotDrop");
+
+ @EventHandler
+ public void hunger(EntityDamageEvent e) {
+ if (e.getCause() == DamageCause.STARVATION) {
+ e.setDamage(Utils.hunger);
+ }
+ }
+
+ public static double damagecalc(double damage, double defense, double toughness) {
+ double max = Math.max(defense / 5, defense - damage / (toughness / 4 + 2));
+ double damageTaken = damage * (1 - Math.min(20, max) / 25);
+ if (max > 20) {
+ damageTaken -= (max - 20) * Utils.exarmor;
+ }
+ if (damageTaken > 1) {
+ return damageTaken;
+ }
+ return 1;
+ }
+
+ @EventHandler(priority = EventPriority.LOWEST)
+ public void arrow(EntityShootBowEvent e) {
+ Projectile p = (Projectile) e.getProjectile();
+ p.setShooter(e.getEntity());
+ }
+
+ @EventHandler//(priority = EventPriority.LOW)
+ public void attack(EntityDamageByEntityEvent e) {
+ Entity enty = e.getEntity();
+ Entity damer = e.getDamager();
+ if(!(enty instanceof LivingEntity)) {
+ return;
+ }
+ LivingEntity ent = (LivingEntity) enty;
+ if(ent.getNoDamageTicks()>0) {
+ return;
+ }
+ if(e.getDamage()==0) {
+ return;
+ }
+ if (ent instanceof Player) {
+ Player player = (Player) ent;
+ PlayerData pdata = Players.Data.get(player);
+ try {
+ if (Utils.isSuccess(pdata.getAvoid())) {
+ e.setCancelled(true);
+ return;
+ }
+ } catch (Exception e1) {
+
+ }
+ }
+ if (damer instanceof Projectile) {
+ Projectile p = (Projectile) damer;
+ if (p.getShooter() instanceof Player) {
+ Player atker = (Player) p.getShooter();
+ Players.PlayerData adata = Players.Data.get(atker);
+ double dmg = e.getDamage();
+ double extra = atker.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE).getValue();
+ double damage = dmg + adata.getDamage();
+ if (damage < 1.0) {
+ damage = 1.0;
+ }
+
+ if (Utils.isSuccess((double) adata.getCrit())) {
+ damage = (damage + extra) * 2.0 * adata.getRangeDamage();
+ } else {
+ damage = (damage + extra) * adata.getRangeDamage();
+ }
+ if (ent instanceof Player) {
+ Player player = (Player) ent;
+ PlayerData pdata = Players.Data.get(player);
+ e.setDamage(DamageModifier.ARMOR, 0);
+ e.setDamage(damagecalc(damage, pdata.armor, pdata.armor_toughness));
+ } else {
+ e.setDamage(damage);
+ }
+ return;
+ }
+ }
+ if (e.getCause() != DamageCause.ENTITY_ATTACK) {
+ return;
+ }
+ if (damer instanceof Player) {
+ double damage;
+ Player atker = (Player) damer;
+ PlayerData adata = Players.Data.get(atker);
+ double range = ModifyItem.getPlayerAttackRange(atker);
+ if (ent.getLocation().distance(atker.getLocation()) > range) {
+ e.setCancelled(true);
+ return;
+ }
+ double dmg = e.getDamage();
+ double mod = 1.0;
+ boolean skill = true;
+ if (range != Double.MAX_VALUE) {
+ skill = false;
+ double base = atker.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE).getValue()
+ * ModifyItem.AtkModBasedCD(atker);
+ if (ent instanceof LivingEntity) {
+ base += ModifyItem.extraATKBasedEnch(atker, (LivingEntity) ent);
+ }
+ mod = base / dmg;
+ }
+ damage = dmg;
+ if (damage < 1.0) {
+ damage = 1.0;
+ }
+ if (Utils.isSuccess(adata.getCrit())) {
+ damage = (mod * damage * 2.0);
+ if (Main.cancel) {
+ Location loc = atker.getLocation();
+ Sound sound = Sound.ENTITY_PLAYER_ATTACK_CRIT;
+ ProtocolLibEvent.setWhitelist(sound);
+ loc.getWorld().playSound(loc, sound, 1.0f, 2.0f);
+ }
+ } else {
+ damage = (mod * damage);
+ if (Main.cancel) {
+ Location loc = atker.getLocation();
+ Sound sound = Sound.ENTITY_PLAYER_ATTACK_WEAK;
+ ProtocolLibEvent.setWhitelist(sound);
+ loc.getWorld().playSound(loc, sound, 1.0f, 2.0f);
+ }
+ }
+ if (ent instanceof Player) {
+ Player player = (Player) ent;
+ PlayerData pdata = Players.Data.get(player);
+ e.setDamage(DamageModifier.ARMOR, 0);
+ if (skill) {
+ e.setDamage(damagecalc(damage * adata.getSkillDamage(), pdata.armor, pdata.armor_toughness));
+ } else {
+ e.setDamage(damagecalc(damage * adata.getDamage(), pdata.armor, pdata.armor_toughness));
+ }
+ } else {
+ if (skill) {
+ e.setDamage(damage * adata.getSkillDamage());
+ } else {
+ e.setDamage(damage * adata.getDamage());
+ }
+ }
+ ModifyItem.atktime.put(atker, System.currentTimeMillis());
+
+ return;
+ }
+ }
+}
diff --git a/src/main/java/nashi/NRPG/listeners/EventListener.java b/src/main/java/nashi/NRPG/listeners/EventListener.java
new file mode 100644
index 0000000..ba5c969
--- /dev/null
+++ b/src/main/java/nashi/NRPG/listeners/EventListener.java
@@ -0,0 +1,962 @@
+package nashi.NRPG.listeners;
+
+import edited.com.codingforcookies.armorequip.AfterArmorEquipEvent;
+import edited.com.codingforcookies.armorequip.ArmorType;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+
+import nashi.NRPG.Main;
+import nashi.NRPG.API.SkillAPI;
+import nashi.NRPG.API.Utils;
+import nashi.NRPG.API.Utils.Status;
+import nashi.NRPG.CustomEvents.CastEvent;
+import nashi.NRPG.CustomEvents.CastStartEvent;
+import nashi.NRPG.CustomEvents.SkillItemGenerateEvent;
+import nashi.NRPG.Players.Players;
+import nashi.NRPG.Players.Players.PlayerData;
+import nashi.NRPG.Players.Races.Race;
+import nashi.NRPG.Skills.Cast;
+import nashi.NRPG.Skills.GUI;
+import nashi.NRPG.Skills.Magic;
+import nashi.NRPG.Skills.Skill;
+import nashi.NRPG.Skills.SkillName;
+import nashi.NRPG.Skills.Cast.Abracadabra;
+import net.minecraft.server.v1_16_R3.IChatBaseComponent;
+import net.minecraft.server.v1_16_R3.IChatBaseComponent.ChatSerializer;
+import net.minecraft.server.v1_16_R3.PacketPlayOutTitle;
+import net.minecraft.server.v1_16_R3.PacketPlayOutTitle.EnumTitleAction;
+
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.Particle;
+import org.bukkit.Sound;
+import org.bukkit.attribute.Attribute;
+import org.bukkit.attribute.AttributeModifier;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.ItemFrame;
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.entity.Player;
+import org.bukkit.event.Event;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.Listener;
+import org.bukkit.event.block.Action;
+import org.bukkit.event.block.BlockPlaceEvent;
+import org.bukkit.event.entity.PlayerDeathEvent;
+import org.bukkit.event.inventory.ClickType;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.event.inventory.InventoryCloseEvent;
+import org.bukkit.event.inventory.InventoryType;
+import org.bukkit.event.player.PlayerDropItemEvent;
+import org.bukkit.event.player.PlayerInteractEntityEvent;
+import org.bukkit.event.player.PlayerInteractEvent;
+import org.bukkit.event.player.PlayerJoinEvent;
+import org.bukkit.event.player.PlayerLoginEvent;
+import org.bukkit.event.player.PlayerMoveEvent;
+import org.bukkit.event.player.PlayerQuitEvent;
+import org.bukkit.event.player.PlayerRespawnEvent;
+import org.bukkit.event.player.PlayerSwapHandItemsEvent;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.PlayerInventory;
+import org.bukkit.inventory.meta.ItemMeta;
+import org.bukkit.persistence.PersistentDataContainer;
+import org.bukkit.persistence.PersistentDataType;
+import org.bukkit.scheduler.BukkitRunnable;
+
+public class EventListener implements Listener {
+ public static HashMap scooldowns = new HashMap();
+ public static HashMap skillmode = new HashMap();
+ private static DecimalFormat df = new DecimalFormat("#.##");
+ public static HashMap backup = new HashMap();
+ public static HashMap castCD = new HashMap();
+ public static HashMap cast = new HashMap();
+ public static long CD = 500L;
+ public static HashMap refresh = new HashMap();
+
+ @EventHandler
+ public void move(PlayerMoveEvent event) {
+ Player player = event.getPlayer();
+ if (!refresh.containsKey(player)) {
+ PlayerData pd = Players.Data.get(player);
+ Players.recalcData(player, pd);
+ refresh.put(player, System.currentTimeMillis() + 10000);
+ return;
+ }
+ if (refresh.get(player) < System.currentTimeMillis()) {
+ PlayerData pd = Players.Data.get(player);
+ Players.recalcData(player, pd);
+ }
+ }
+
+ @EventHandler
+ public void caststart(CastEvent e) {
+ if (e.isCancelled()) {
+ return;
+ }
+ Player player = e.getPlayer();
+ PlayerInventory inv = player.getInventory();
+ ItemStack item = inv.getItemInMainHand();
+ Casting cast = e.getCast();
+ Abracadabra a = cast.getAbracadabra();
+ Set s = a.getPos();
+ if (!cast.validPos()) {
+ return;
+ }
+ if (cast.getSuccessTime() < 1) {
+ cast.setWand(item);
+ int i = ModifyItem.getItemCastMod(item);
+ if (castmod.containsKey(player)) {
+ i += castmod.get(player);
+ }
+ cast.setModSuccess(i);
+ }
+ if (!cast.getWand().equals(item)) {
+ cast.setModSuccess(0);
+ }
+ if (s.contains(cast.getPos())) {
+ cast.success();
+ player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 3.0f, 3.0f);
+ if (cast.getSuccessTime() + cast.getSuccessMod() >= cast.getNeededTimes()) {
+ castCD.put(player, System.currentTimeMillis() + CD);
+ ItemStack n = inv.getItemInOffHand();
+ ItemMeta m = n.getItemMeta();
+ PersistentDataContainer pdc = m.getPersistentDataContainer();
+ if (pdc.has(ModifyItem.CastHelp, PersistentDataType.BYTE)) {
+ inv.setItemInOffHand(null);
+ }
+ EventListener.cast.remove(player);
+ Skill.cast(cast.getSkillName(), player, false);
+ }
+ } else {
+ int t = cast.getSuccessTime();
+ String skname = cast.getSkillName();
+ Location loc = player.getLocation();
+ loc.getWorld().playSound(loc, Sound.ENTITY_GENERIC_EXPLODE, (float) t, 3.0f);
+ loc.getWorld().spawnParticle(Particle.EXPLOSION_HUGE, loc, 2);
+ double cost = SkillAPI.getPublicSkillInfo(skname, "CostMP");
+ SkillAPI.costMP(player, cost);
+ double damage = cost * Utils.manaDMG * ((0.0 + t) / cast.getNeededTimes());
+ SkillAPI.damage((LivingEntity) player, (Player) player, damage);
+ for (LivingEntity ent : SkillAPI.getNearEntity((Player) player, (int) ((int) Math.pow(cost, 0.5)))) {
+ SkillAPI.damage((LivingEntity) ent, (Player) player, damage);
+ }
+ ItemStack n = inv.getItemInOffHand();
+ ItemMeta m = n.getItemMeta();
+ try {
+ PersistentDataContainer pdc = m.getPersistentDataContainer();
+ if (pdc.has(ModifyItem.CastHelp, PersistentDataType.BYTE)) {
+ inv.setItemInOffHand(null);
+ }
+ } catch (Exception pdc) {
+ // empty catch block
+ }
+ castCD.put(player, System.currentTimeMillis() + CD);
+ EventListener.cast.remove(player);
+ return;
+ }
+ }
+
+ @EventHandler
+ public void close(InventoryCloseEvent e) {
+ Player player = (Player) e.getPlayer();
+ PlayerData pd = Players.Data.get(player);
+ Players.recalcData(player, pd);
+
+ }
+
+ @EventHandler
+ public void equip(AfterArmorEquipEvent e) {
+ Player player = e.getPlayer();
+ PlayerData pd = Players.Data.get(player);
+ Players.recalcData(player, pd);
+ }
+
+ @EventHandler
+ public void logout(PlayerQuitEvent e) {
+ Player player = e.getPlayer();
+ Players.unload((Player) player);
+ if (backup.containsKey(player)) {
+ PlayerInventory inv = player.getInventory();
+ ItemStack[] back = backup.get(player).clone();
+ int n = back.length;
+ for (int n2 = 0; n2 < n; n2++) {
+ ItemStack item = back[n2];
+ inv.setItem(n2, item);
+ }
+ backup.remove(player);
+ }
+ if (ModifyItem.edit.containsKey(player)) {
+ ModifyItem.edit.remove(player);
+ }
+ }
+
+ @EventHandler
+ public void login(PlayerLoginEvent e) {
+ Player player = e.getPlayer();
+ Players.loadYaml(player);
+ skillmode.put(player, false);
+ Magic.check(player);
+ }
+
+ @EventHandler
+ public void Join(PlayerJoinEvent e) {
+ Player player = e.getPlayer();
+ Main.setPlayerScoreboard(player);
+ YamlConfiguration y = Players.getYaml(player);
+ y.set("ID", player.getName());
+ int a = y.getInt("Scale");
+ if (a > 0) {
+ player.setHealthScale(a);
+ } else {
+ player.setHealthScale(20.0);
+ }
+ PlayerData pd = Players.Data.get(player);
+ Players.recalcData(player, pd);
+ if (ModifyItem.edit.containsKey(player)) {
+ ModifyItem.edit.remove(player);
+ }
+ }
+
+ @EventHandler
+ public void respawn(PlayerRespawnEvent e) {
+ Player player = e.getPlayer();
+ if (backup.containsKey(player)) {
+ PlayerInventory inv = player.getInventory();
+ ItemStack[] back = backup.get(player).clone();
+ int n = back.length;
+ for (int n2 = 0; n2 < n; n2++) {
+ ItemStack item = back[n2];
+ inv.setItem(n2, item);
+ }
+ backup.remove(player);
+ skillmode.put(player, false);
+ }
+ Players.PlayerData pdata = Players.Data.get(player);
+ Players.recalcData(player, pdata);
+ }
+
+ public static void setData(Player player, Players.PlayerData pdata) {
+ if (skillmode.get(player)) {
+ double d;
+ if (extra.containsKey(player)) {
+ d = extra.get(player);
+ } else {
+ d = 0;
+ }
+ player.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE)
+ .setBaseValue(player.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE).getBaseValue() + d);
+ player.getAttribute(Attribute.GENERIC_MAX_HEALTH).setBaseValue(pdata.getMaxHealth());
+ player.setWalkSpeed(pdata.getSpeed());
+ if (pdata.getCurrentMP() > pdata.getMaxMana()) {
+ pdata.setCurrentMP(pdata.getMaxMana());
+ }
+ } else {
+ if (player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getBaseValue() != pdata.getMaxHealth()) {
+ player.getAttribute(Attribute.GENERIC_MAX_HEALTH).setBaseValue(pdata.getMaxHealth());
+ }
+ player.setWalkSpeed(pdata.getSpeed());
+ if (pdata.getCurrentMP() > pdata.getMaxMana()) {
+ pdata.setCurrentMP(pdata.getMaxMana());
+ }
+ }
+ }
+
+ @EventHandler
+ public void check(InventoryClickEvent e) {
+ if (e.isCancelled()) {
+ return;
+ }
+ try {
+ if (e.getClickedInventory().getType() == InventoryType.PLAYER) {
+ ItemStack i = e.getCurrentItem();
+ if (i == null) {
+ return;
+ }
+ ItemStack c = e.getCursor();
+ if (e.getSlotType() == InventoryType.SlotType.ARMOR && Utils.isNotDrop(i)) {
+ if (c == null || c.getType() == Material.AIR) {
+ e.setCancelled(true);
+ return;
+ }
+ int slot = e.getSlot();
+ ArmorType at = ArmorType.matchType(c);
+ if (at == null) {
+ return;
+ }
+ if (at.equals(ArmorType.BOOTS) && slot != 36) {
+ e.setCancelled(true);
+ return;
+ }
+ if (at.equals(ArmorType.LEGGINGS) && slot != 37) {
+ e.setCancelled(true);
+ return;
+ }
+ if (at.equals(ArmorType.CHESTPLATE) && slot != 38) {
+ e.setCancelled(true);
+ return;
+ }
+ if (at.equals(ArmorType.HELMET) && slot != 39) {
+ e.setCancelled(true);
+ return;
+ }
+ e.setCurrentItem(null);
+ }
+ }
+ } catch (Exception i) {
+ // empty catch block
+ }
+ }
+
+ @EventHandler
+ public void SkillEditPageGUI(InventoryClickEvent e) {
+ if (!e.getView().getTitle().contains("技能調整")) {
+ return;
+ }
+ e.setCancelled(true);
+ Player player = (Player) e.getWhoClicked();
+ if (e.getClick() == ClickType.valueOf("SWAP_OFFHAND")) {
+ player.closeInventory();
+ ItemStack item = player.getInventory().getItemInOffHand().clone();
+ new BukkitRunnable() {
+ public void run() {
+ player.getInventory().setItemInOffHand(item);
+ }
+ }.runTaskLater(SkillAPI.plugin(), 1L);
+ return;
+ }
+ if (e.getClick() != ClickType.LEFT && e.getClick() != ClickType.RIGHT) {
+ return;
+ }
+ ItemStack item = e.getCurrentItem();
+ if (item == null) {
+ return;
+ }
+ if (!item.hasItemMeta()) {
+ return;
+ }
+ ItemMeta im = item.getItemMeta();
+ if (!im.hasDisplayName()) {
+ return;
+ }
+ if (ChatColor.stripColor(im.getDisplayName()).equals("下一頁")) {
+
+ GUI.EditGUI(player, (GUI.editpage.get(player) + 1));
+ } else {
+ String skillname = SkillName.get(ChatColor.stripColor(im.getDisplayName()));
+ if (skillname == null) {
+ return;
+ }
+ GUI.openSkillEditGUI(player, skillname);
+ }
+ }
+
+ @EventHandler
+ public void SlotEditClose(InventoryCloseEvent e) {
+ if (!e.getView().getTitle().contains("技能欄位設定")) {
+ return;
+ }
+ e.getView().setCursor(null);
+ Player player = (Player) e.getPlayer();
+ Inventory inv = e.getInventory();
+ String[] skills = new String[9];
+ int i = 0;
+ while (i < 9) {
+ ItemStack item = inv.getItem(i);
+ if (item != null && item.hasItemMeta()) {
+ ItemMeta im = item.getItemMeta();
+ skills[i] = SkillName.get(ChatColor.stripColor(im.getDisplayName()));
+ }
+ ++i;
+ }
+ YamlConfiguration y = Players.getYaml(player);
+ int slot = 0;
+ while (slot < 9) {
+ String skname = skills[slot];
+ y.set("Slot." + slot, skname);
+ ++slot;
+ }
+ PlayerInventory pi = player.getInventory();
+ int i2 = 0;
+ while (i2 < pi.getSize()) {
+ ItemStack item = pi.getItem(i2);
+ if (Utils.isNotDrop(item)) {
+ pi.setItem(i2, null);
+ }
+ ++i2;
+ }
+ }
+
+ @EventHandler
+ public void SlotPageGUI(InventoryClickEvent e) {
+ if (!e.getView().getTitle().contains("技能欄位設定")) {
+ return;
+ }
+ Player player = (Player) e.getWhoClicked();
+ if (e.getClick() == ClickType.valueOf("SWAP_OFFHAND")) {
+ e.setCancelled(true);
+ player.closeInventory();
+ ItemStack item = player.getInventory().getItemInOffHand().clone();
+ new BukkitRunnable() {
+ public void run() {
+ player.getInventory().setItemInOffHand(item);
+ }
+ }.runTaskLater(SkillAPI.plugin(), 1L);
+ return;
+ }
+ if (e.getClick() != ClickType.LEFT && e.getClick() != ClickType.RIGHT) {
+ e.setCancelled(true);
+ return;
+ }
+ if (e.getRawSlot() < 0 || e.getRawSlot() > 53) {
+ e.setCancelled(true);
+ return;
+ }
+ try {
+ if (e.getClickedInventory().equals(player.getInventory())) {
+ e.setCancelled(true);
+ return;
+ }
+ ItemStack item = e.getCurrentItem();
+ if (item == null) {
+ return;
+ }
+ if (!item.hasItemMeta()) {
+ e.setCancelled(true);
+ return;
+ }
+ ItemMeta im = item.getItemMeta();
+ if (!im.hasDisplayName()) {
+ e.setCancelled(true);
+ return;
+ }
+ if (ChatColor.stripColor(im.getDisplayName()).equals("下一頁")) {
+ e.setCancelled(true);
+ GUI.SlotGUI((Player) player, (GUI.editpage.get(player) + 1));
+ return;
+ }
+ if (SkillName.get(ChatColor.stripColor(im.getDisplayName())) == null) {
+ e.setCancelled(true);
+ }
+ } catch (Exception e1) {
+ e.setCancelled(true);
+ }
+ }
+
+ @EventHandler
+ public void SkillEditGUI(InventoryClickEvent e) {
+ Player player = (Player) e.getWhoClicked();
+ if ((skillmode.get(player) || cast.containsKey(player)) && !e.getView().getTitle().contains("技能設定")
+ && !e.getView().getTitle().contains("技能調整")) {
+ e.setCancelled(true);
+ return;
+ }
+ if (!e.getView().getTitle().contains("技能設定")) {
+ return;
+ }
+ if (e.getClick() == ClickType.valueOf("SWAP_OFFHAND")) {
+ e.setCancelled(true);
+ player.closeInventory();
+ ItemStack item = player.getInventory().getItemInOffHand().clone();
+ new BukkitRunnable() {
+ public void run() {
+ player.getInventory().setItemInOffHand(item);
+ }
+ }.runTaskLater(SkillAPI.plugin(), 1L);
+ return;
+ }
+ if (e.getClick() != ClickType.LEFT && e.getClick() != ClickType.RIGHT && e.getClick() != ClickType.SHIFT_LEFT
+ && e.getClick() != ClickType.SHIFT_RIGHT) {
+ e.setCancelled(true);
+ return;
+ }
+ e.setCancelled(true);
+ String skillName = e.getView().getTitle().split("-")[1];
+ ItemStack item = e.getCurrentItem();
+ if (item == null) {
+ return;
+ }
+ YamlConfiguration yml = Players.getYaml((Player) player);
+ ItemMeta im = item.getItemMeta();
+ boolean increase = im.getDisplayName().contains("提升");
+ String var = ChatColor.stripColor(im.getDisplayName()).split(":")[1];
+ double max = yml.getDouble("Skills." + skillName + ".Max." + var);
+ if (e.isShiftClick()) {
+ if (increase) {
+ if (e.isLeftClick()) {
+ double mod = Double
+ .parseDouble(df.format(yml.getDouble("Skills." + skillName + ".Custom." + var) + 0.1));
+ if (mod > max) {
+ mod = max;
+ }
+ yml.set("Skills." + skillName + ".Custom." + var, mod);
+ } else {
+ double mod = Double
+ .parseDouble(df.format(yml.getDouble("Skills." + skillName + ".Custom." + var) + 10));
+ if (mod > max) {
+ mod = max;
+ }
+ yml.set("Skills." + skillName + ".Custom." + var, mod);
+ }
+ } else if (e.isLeftClick()) {
+ double mod = Double
+ .parseDouble(df.format(yml.getDouble("Skills." + skillName + ".Custom." + var) - 0.1));
+ if (mod < 0.0) {
+ mod = 0.0;
+ }
+ yml.set("Skills." + skillName + ".Custom." + var, mod);
+ } else {
+ double mod = Double
+ .parseDouble(df.format(yml.getDouble("Skills." + skillName + ".Custom." + var) - 10));
+ if (mod < 0.0) {
+ mod = 0.0;
+ }
+ yml.set("Skills." + skillName + ".Custom." + var, mod);
+ }
+ } else if (increase) {
+ if (e.isLeftClick()) {
+ double mod = Double
+ .parseDouble(df.format(yml.getDouble("Skills." + skillName + ".Custom." + var) + 0.01));
+ if (mod > max) {
+ mod = max;
+ }
+ yml.set("Skills." + skillName + ".Custom." + var, mod);
+ } else {
+ double mod = Double.parseDouble(df.format(yml.getDouble("Skills." + skillName + ".Custom." + var) + 1));
+ if (mod > max) {
+ mod = max;
+ }
+ yml.set("Skills." + skillName + ".Custom." + var, mod);
+ }
+ } else if (e.isLeftClick()) {
+ double mod = Double.parseDouble(df.format(yml.getDouble("Skills." + skillName + ".Custom." + var) - 0.01));
+ if (mod < 0.0) {
+ mod = 0.0;
+ }
+ yml.set("Skills." + skillName + ".Custom." + var, mod);
+ } else {
+ double mod = Double.parseDouble(df.format(yml.getDouble("Skills." + skillName + ".Custom." + var) - 1));
+ if (mod < 0.0) {
+ mod = 0.0;
+ }
+ yml.set("Skills." + skillName + ".Custom." + var, mod);
+ }
+ GUI.openSkillEditGUI((Player) player, skillName);
+ }
+
+ @EventHandler
+ public void die(PlayerDeathEvent e) {
+ List drops = e.getDrops();
+ List items = new ArrayList();
+ for (ItemStack item : drops) {
+ if (!Utils.isNotDrop(item)) {
+ items.add(item);
+ }
+ }
+ drops.clear();
+ drops.addAll(items);
+ Player player = e.getEntity();
+ if (Utils.deathpenworld.contains(player.getWorld())) {
+ PlayerData pd = Players.Data.get(player);
+ Status status = pd.getStatus();
+ if (Utils.Penalty_MakeUp) {
+ YamlConfiguration yml = Players.getYaml(player);
+ try {
+ for (String skill : yml.getConfigurationSection("Skills").getKeys(false)) {
+ if (yml.getBoolean("Skills." + skill + ".isMakeUp")) {
+ yml.set("Skills." + skill, null);
+ }
+ }
+ } catch (Exception e1) {
+
+ }
+ }
+ if (Utils.Penalty_LVL) {
+ status.setLvL(1);
+ }
+ if (Utils.Penalty_Status) {
+ Status stat = Utils.getStatusFromInt(player.getUniqueId().hashCode(), status.getLvL());
+ status = stat;
+ Utils.setPlayerStatus(player, stat);
+ Race race = pd.getRace();
+ Players.Data.put(player, pd);
+ if (!Utils.Penalty_Race) {
+ pd = new PlayerData(player, race, stat, pd.getCurrentMP());
+ } else {
+ pd = new PlayerData(player, stat);
+ }
+ } else if (Utils.Penalty_Race) {
+ Utils.setPlayerStatus(player, status);
+ pd = new PlayerData(player, status);
+ Players.Data.put(player, pd);
+ }
+ }
+ }
+
+ @EventHandler
+ public void drop(PlayerDropItemEvent e) {
+ Player player = e.getPlayer();
+ if (cast.containsKey(player) || skillmode.get(player).booleanValue()) {
+ e.setCancelled(true);
+ }
+ if (Utils.isNotDrop(e.getItemDrop().getItemStack())) {
+ e.setCancelled(true);
+ }
+ }
+
+ public static HashMap extra = new HashMap();
+ public static HashMap castmod = new HashMap();
+
+ @EventHandler(priority = EventPriority.HIGHEST)
+ public void SkillMode(PlayerSwapHandItemsEvent e) {
+ if (e.isCancelled()) {
+ return;
+ }
+ Player player = e.getPlayer();
+ e.setCancelled(true);
+ YamlConfiguration y = Players.getYaml(player);
+ if (skillmode.get(player)) {// from skill mode
+ PlayerInventory inv = player.getInventory();
+ ItemStack[] back = backup.get(player).clone();
+ int n = back.length;
+ for (int n2 = 0; n2 < n; n2++) {
+ ItemStack item = back[n2];
+ inv.setItem(n2, item);
+ }
+ double d;
+ if (extra.containsKey(player)) {
+ d = extra.get(player);
+ } else {
+ d = 0;
+ }
+ backup.remove(player);
+ skillmode.put(player, false);
+ player.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE)
+ .setBaseValue(player.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE).getBaseValue() - d);
+ extra.remove(player);
+ castmod.remove(player);
+ } else {// to skillmode
+ PlayerInventory inv = player.getInventory();
+ ItemStack[] back = new ItemStack[9];
+ for (int i = 0; i < 9; i++) {
+ back[i] = inv.getItem(i);
+ }
+ backup.put(player, back);
+ double d = 0;
+ int c = ModifyItem.getItemCastMod(inv.getItemInMainHand());
+ try {
+ for (AttributeModifier a : inv.getItemInMainHand().getItemMeta()
+ .getAttributeModifiers(Attribute.GENERIC_ATTACK_DAMAGE)) {
+ d += a.getAmount();
+ }
+ } catch (Exception e1) {
+ }
+ extra.put(player, d);
+ castmod.put(player, c);
+ player.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE)
+ .setBaseValue(player.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE).getBaseValue() + d);
+ int i = 0;
+ while (i < 9) {
+ try {
+ String sk = y.getString("Slot." + i);
+ ItemStack item = Utils.getSkillItem(sk, player);
+ SkillItemGenerateEvent event = new SkillItemGenerateEvent(player, item, sk);
+ Bukkit.getPluginManager().callEvent(event);
+ inv.setItem(i, item);
+ } catch (NullPointerException e1) {
+ ItemStack item = new ItemStack(Material.BARRIER);
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ pdc.set(AllAboutDamage.key, PersistentDataType.STRING, "ItemsNotDrop");
+ item.setItemMeta(im);
+ inv.setItem(i, item);
+ }
+ ++i;
+ }
+ skillmode.put(player, true);
+ }
+ }
+
+ public static void sendTitle(Player player, String title, int time1, int time2, int time3) {
+ IChatBaseComponent chatTitle = ChatSerializer.a("{\"text\": \"" + title + "\"}");
+ PacketPlayOutTitle titleT = new PacketPlayOutTitle(EnumTitleAction.ACTIONBAR, chatTitle);
+ PacketPlayOutTitle length = new PacketPlayOutTitle(time1, time2, time3);
+ ((CraftPlayer) player).getHandle().playerConnection.sendPacket(titleT);
+ ((CraftPlayer) player).getHandle().playerConnection.sendPacket(length);
+ }
+
+ public static void playercast(final Player player, final Casting cast, long speed, long limit) {
+ CastStartEvent ce = new CastStartEvent(player, cast);
+ Bukkit.getPluginManager().callEvent(ce);
+ if (ce.isCancelled()) {
+ return;
+ }
+ EventListener.cast.put(player, cast);
+ final String a = cast.getAbracadabra().getString();
+ sendTitle(player, Cast.getDisplay(a, cast.getPos()), 5, 5, 5);
+ /*
+ * player.spigot().sendMessage(ChatMessageType.ACTION_BAR,
+ * TextComponent.fromLegacyText(Cast.getDisplay(a, cast.getPos())));
+ */
+ final long breaktime = System.currentTimeMillis() + limit;
+ new BukkitRunnable() {
+
+ public void run() {
+ if (!EventListener.cast.containsKey(player)) {
+ this.cancel();
+ return;
+ }
+ if (System.currentTimeMillis() > breaktime) {
+ int t = cast.getSuccessTime();
+ String skname = cast.getSkillName();
+ double cost = SkillAPI.getPublicSkillInfo(skname, "CostMP");
+ SkillAPI.costMP((Player) player, cost);
+ double damage = cost * Utils.manaDMG * ((0.0 + t) / cast.getNeededTimes());
+ Location loc = player.getLocation();
+ loc.getWorld().playSound(loc, Sound.ENTITY_GENERIC_EXPLODE, (float) t, 3.0f);
+ loc.getWorld().spawnParticle(Particle.EXPLOSION_HUGE, loc, 2);
+ SkillAPI.damage(player, player, damage);
+ for (LivingEntity ent : SkillAPI.getNearEntity(player, ((int) Math.pow(cost, 0.5)))) {
+ SkillAPI.damage(ent, player, damage);
+ }
+ EventListener.cast.remove(player);
+ EventListener.castCD.put(player, System.currentTimeMillis() + EventListener.CD);
+ this.cancel();
+ return;
+ }
+ cast.nextPos();
+ sendTitle(player, Cast.getDisplay(a, cast.getPos()), 5, 5, 5);
+ /*
+ * player.spigot().sendMessage(ChatMessageType.ACTION_BAR,
+ * TextComponent.fromLegacyText(Cast.getDisplay(a, cast.getPos())));
+ */
+ }
+ }.runTaskTimer(Main.getPlugin(), speed, speed);
+ }
+
+ @EventHandler
+ public void place(BlockPlaceEvent e) {
+ Player player = e.getPlayer();
+ if (cast.containsKey(player) || skillmode.get(player).booleanValue()) {
+ e.setCancelled(true);
+ }
+ }
+
+ @EventHandler
+ public void itemframe(PlayerInteractEntityEvent event) {
+
+ Player player = event.getPlayer();
+
+ Entity e = event.getRightClicked();
+
+ if (e instanceof ItemFrame) {
+
+ if (Utils.isNotDrop(player.getInventory().getItemInMainHand())) {
+ event.setCancelled(true);
+ }
+
+ }
+
+ }
+
+ @EventHandler(priority = EventPriority.LOWEST)
+ public void interact(PlayerInteractEvent event) {
+ ItemStack item;
+ Player player = event.getPlayer();
+ if ((item = event.getItem()) != null) {
+ if (!item.hasItemMeta()) {
+ return;
+ }
+ ItemMeta im = item.getItemMeta();
+ if (im.isUnbreakable()) {
+ String skillname = ModifyItem.getSkillBookSkill(item);
+ if (skillname != null) {
+ event.setCancelled(true);
+ YamlConfiguration y = Players.getYaml((Player) player);
+ int slot = y.getInt("UniqueSkillSlots");
+ if (slot > y.getInt("UsedSlots")) {
+ if (!Magic.learnSkill((Player) player, skillname)) {
+ player.sendMessage(ChatColor.RED + "你已經擁有此技能");
+ return;
+ }
+ ItemStack book = player.getInventory().getItemInMainHand();
+ book.setAmount(book.getAmount() - 1);
+ player.sendMessage(ChatColor.GREEN + "你已學習了" + skillname);
+ } else {
+ player.sendMessage(ChatColor.RED + "請確認你是否擁有足夠的欄位");
+ }
+ return;
+ }
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ if (pdc.has(Utils.key, PersistentDataType.STRING)) {
+ event.setCancelled(true);
+ double hp = 0.0;
+ double mp = 0.0;
+ Players.PlayerData pd = Players.Data.get(player);
+ pd.addCurrentMP(mp += ModifyItem.getPotionMP(item));
+ double chp = player.getHealth();
+ double max = player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
+ if (chp + (hp += ModifyItem.getPotionHP(item)) < 0.0) {
+ player.setHealth(0.0);
+ } else if (chp + hp < max) {
+ player.setHealth(chp + hp);
+ } else {
+ player.setHealth(max);
+ }
+ int amount = item.getAmount();
+ item.setAmount(amount - 1);
+ return;
+ }
+ }
+ }
+ if (cast.containsKey(player)) {
+ if (event.getAction().equals(Action.LEFT_CLICK_AIR) || event.getAction().equals(Action.LEFT_CLICK_BLOCK)) {
+ return;
+ }
+ event.setCancelled(true);
+ Casting c = cast.get(player);
+ CastEvent ce = new CastEvent(player, c);
+ Bukkit.getPluginManager().callEvent((Event) ce);
+ return;
+ }
+ if (!event.getAction().equals(Action.RIGHT_CLICK_AIR) && !event.getAction().equals(Action.RIGHT_CLICK_BLOCK)) {
+ return;
+ }
+ long cooldowntime = 100L;
+ if (scooldowns.containsKey(player.getUniqueId())
+ && System.currentTimeMillis() - scooldowns.get(player.getUniqueId()) <= cooldowntime) {
+ return;
+ }
+ if (skillmode.get(player)) {
+ if (castCD.containsKey(player) && castCD.get(player) > System.currentTimeMillis()) {
+ return;
+ }
+ if (skillmode.get(player)) {
+ event.setCancelled(true);
+ scooldowns.put(player.getUniqueId(), System.currentTimeMillis());
+ int slot = player.getInventory().getHeldItemSlot();
+ YamlConfiguration y = Players.getYaml(player);
+ try {
+ String sk = y.getString("Slot." + slot);
+ if (sk.length() < 1) {
+ return;
+ }
+ double cost = SkillAPI.getPublicSkillInfo(sk, "CostMP");
+ Players.PlayerData pd = Players.Data.get(player);
+ if (pd.getCurrentMP() - cost < 0.0) {
+ player.sendMessage(ChatColor.RED + "魔力不足");
+ return;
+ }
+ if (SkillAPI.getPublicSkillInfo(sk, "Times") < 1.0) {
+ Skill.cast(sk, player, false);
+ } else {
+ long time = SkillAPI.getRemainingCooldown((Player) player, sk);
+ if (time > 0L) {
+ player.sendMessage(ChatColor.RED + "技能冷卻時間剩餘:" + time + " 毫秒");
+ return;
+ }
+ Cast.Abracadabra abra = Cast
+ .getabracadabra(((int) SkillAPI.getPublicSkillInfo(sk, "Difficulty")));
+ EventListener.playercast(player,
+ new Casting(sk, abra, (int) SkillAPI.getPublicSkillInfo(sk, "Times")),
+ (Cast.castspeed.get(player)), Cast.timelimit);
+ }
+ } catch (NullPointerException sk) {
+ // empty catch block
+ }
+ }
+ }
+
+ }
+
+ public static class Casting {
+ private int success = 0;
+ private String skillname;
+ private Cast.Abracadabra abracadabra;
+ private int pos;
+ private boolean d;
+ private int needed;
+ private boolean s;
+ private int add = 0;
+ private ItemStack item = null;
+
+ public Casting(String skillname, Cast.Abracadabra abracadabra, int needed) {
+ this.skillname = skillname;
+ this.abracadabra = abracadabra;
+ this.pos = 1;
+ this.d = true;
+ this.needed = needed;
+ this.s = true;
+ }
+
+ public int getSuccessMod() {
+ return this.add;
+ }
+
+ public int getNeededTimes() {
+ return this.needed;
+ }
+
+ public void setModSuccess(int mod) {
+ this.add = mod;
+ }
+
+ public ItemStack getWand() {
+ return this.item;
+ }
+
+ public void setWand(ItemStack wand) {
+ this.item = wand;
+ }
+
+ public boolean validPos() {
+ return !this.s;
+ }
+
+ public void nextPos() {
+ this.s = false;
+ if (this.pos < 20 && this.d) {
+ ++this.pos;
+ } else if (this.pos == 20 || this.pos == 1) {
+ d = !d;
+ this.pos = this.d ? ++this.pos : --this.pos;
+ } else {
+ --this.pos;
+ }
+ }
+
+ public int getPos() {
+ return this.pos - 1;
+ }
+
+ public Cast.Abracadabra getAbracadabra() {
+ return this.abracadabra;
+ }
+
+ public int getSuccessTime() {
+ return this.success;
+ }
+
+ public String getSkillName() {
+ return this.skillname;
+ }
+
+ public void success() {
+ this.s = true;
+ ++this.success;
+ }
+
+ public void addSuccessTime(int i) {
+ this.success += i;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/nashi/NRPG/listeners/ForgeListener.java b/src/main/java/nashi/NRPG/listeners/ForgeListener.java
new file mode 100644
index 0000000..e4c5c66
--- /dev/null
+++ b/src/main/java/nashi/NRPG/listeners/ForgeListener.java
@@ -0,0 +1,597 @@
+package nashi.NRPG.listeners;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.UUID;
+
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.Instrument;
+import org.bukkit.Material;
+import org.bukkit.Note;
+import org.bukkit.Sound;
+import org.bukkit.attribute.Attribute;
+import org.bukkit.attribute.AttributeModifier;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.block.Action;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.event.inventory.InventoryCloseEvent;
+import org.bukkit.event.inventory.InventoryType;
+import org.bukkit.event.player.PlayerInteractEvent;
+import org.bukkit.event.player.PlayerQuitEvent;
+import org.bukkit.inventory.EquipmentSlot;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+import org.bukkit.persistence.PersistentDataContainer;
+import org.bukkit.persistence.PersistentDataType;
+import org.bukkit.scheduler.BukkitRunnable;
+
+import com.google.common.collect.Multimap;
+
+import nashi.NRPG.Main;
+import nashi.NRPG.API.Utils;
+import nashi.NRPG.Items.CreateItem;
+import nashi.NRPG.Items.CreateItem.Technique;
+
+public class ForgeListener implements Listener {
+
+ @EventHandler
+ public void openGUI(PlayerInteractEvent event) {
+ Player player = event.getPlayer();
+ if (!(player.isSneaking() && event.getAction() == Action.RIGHT_CLICK_BLOCK
+ && (event.getClickedBlock().getType() == Material.ANVIL
+ || event.getClickedBlock().getType() == Material.CHIPPED_ANVIL
+ || event.getClickedBlock().getType() == Material.DAMAGED_ANVIL))) {
+ return;
+ }
+ event.setCancelled(true);
+ Inventory inv = Bukkit.createInventory(player, InventoryType.FURNACE, "裝備/武器鍛造");
+ player.openInventory(inv);
+ }
+
+ @EventHandler
+ public void ForgeGUI(InventoryClickEvent event) {
+ if (!event.getView().getTitle().equals("裝備/武器鍛造")) {
+ return;
+ }
+ event.setCancelled(true);
+ Inventory inv = event.getView().getTopInventory();
+ if (event.getCurrentItem() == null) {
+ return;
+ }
+ ItemStack clicked = event.getCurrentItem().clone();
+ if (!clicked.hasItemMeta()) {
+ return;
+ }
+ Player player = (Player) event.getWhoClicked();
+ ItemStack item = inv.getItem(0);
+ ItemStack mat = inv.getItem(1);
+ if (clicked.getItemMeta().getPersistentDataContainer().has(CreateItem.key_click, PersistentDataType.INTEGER)) {
+ int time = CreateItem.getItemForgeTime(item);
+ if (CreateItem.max - time < 1) {
+ player.sendMessage(ChatColor.RED + "此道具已無法繼續鍛造");
+ player.closeInventory();
+ return;
+ }
+ int key = CreateItem.getItemForgeKey(item);
+ CreateItem.setItemForgeKey(item, -1);
+ if (key != -1) {
+ CreateItem.setItemForgeTime(item, time + 1);
+ int a = mat.getAmount();
+ Technique tech = getTechnique(item, mat, key);
+ if (tech.isRandom()) {
+ int bond = (int) (tech.Rand_Max - tech.Rand_Min);
+
+ double r = Utils.rand.nextInt(bond) + tech.Rand_Min;
+
+ double[] raw = new double[10];
+ raw[0] = r * tech.MAX_MANA;
+ r = Utils.rand.nextInt(bond) + tech.Rand_Min;
+ raw[1] = r * tech.MAX_HEALTH;
+ r = Utils.rand.nextInt(bond) + tech.Rand_Min;
+ raw[2] = r * tech.ARMOR_TOUGHNESS;
+ r = Utils.rand.nextInt(bond) + tech.Rand_Min;
+ raw[3] = r * tech.ARMOR;
+ r = Utils.rand.nextInt(bond) + tech.Rand_Min;
+ raw[4] = r * tech.ATTACK_DAMAGE;
+ r = Utils.rand.nextInt(bond) + tech.Rand_Min;
+ raw[5] = r * tech.ATTACK_SPEED;
+ r = Utils.rand.nextInt(bond) + tech.Rand_Min;
+ raw[6] = r * tech.ATTACK_RANGE;
+ r = Utils.rand.nextInt(bond) + tech.Rand_Min;
+ raw[7] = r * tech.KNOCKBACK_RESISTANCE;
+ r = Utils.rand.nextInt(bond) + tech.Rand_Min;
+ raw[8] = r * tech.MOVEMENT_SPEED;
+ r = Utils.rand.nextInt(bond) + tech.Rand_Min;
+ raw[9] = r * tech.CAST_MOD;
+ tech = new Technique(raw, CreateItem.getItemForgeSlot(item));
+ }
+ Technique t = getLimitTechnique(item);
+ if (a > 1) {
+ mat.setAmount(a - 1);
+ inv.setItem(1, mat);
+ } else {
+ inv.setItem(1, null);
+ }
+ ItemMeta meta = item.getItemMeta();
+ EquipmentSlot equip = tech.slot;
+ int castmod = 0;
+ double mp = 0, hp = 0, armor = 0, armor_toughness = 0, movement_speed = 0, attack_range = 0,
+ attack_speed = 0, knockback_resistance = 0, damage = 0;
+ if (meta.hasAttributeModifiers()) {
+ Multimap map = meta.getAttributeModifiers(equip);
+ Collection g_armor = map.get(Attribute.GENERIC_ARMOR);
+ double add_amount = 0;
+ double scalar_amount = 0;
+ double addmult_amount = 0;
+ for (AttributeModifier am : g_armor) {
+ switch (am.getOperation()) {
+ case ADD_NUMBER:
+ add_amount += am.getAmount();
+ break;
+ case ADD_SCALAR:
+ scalar_amount += am.getAmount();
+ break;
+ case MULTIPLY_SCALAR_1:
+ addmult_amount += am.getAmount();
+ break;
+ default:
+ break;
+ }
+ }
+ g_armor.clear();
+ if (add_amount + tech.ARMOR != 0) {
+ double amount = add_amount + tech.ARMOR;
+ armor = amount;
+ }
+ if (scalar_amount != 0) {
+ g_armor.add(new AttributeModifier(UUID.randomUUID(), "generic.armor", scalar_amount,
+ AttributeModifier.Operation.ADD_SCALAR, equip));
+ }
+ if (addmult_amount != 0) {
+ g_armor.add(new AttributeModifier(UUID.randomUUID(), "generic.armor", addmult_amount,
+ AttributeModifier.Operation.MULTIPLY_SCALAR_1, equip));
+ }
+
+ Collection g_hp = map.get(Attribute.GENERIC_MAX_HEALTH);
+ add_amount = 0;
+ scalar_amount = 0;
+ addmult_amount = 0;
+ for (AttributeModifier am : g_hp) {
+ switch (am.getOperation()) {
+ case ADD_NUMBER:
+ add_amount += am.getAmount();
+ break;
+ case ADD_SCALAR:
+ scalar_amount += am.getAmount();
+ break;
+ case MULTIPLY_SCALAR_1:
+ addmult_amount += am.getAmount();
+ break;
+ default:
+ break;
+ }
+ }
+ g_hp.clear();
+ if (add_amount + tech.MAX_HEALTH != 0) {
+ double amount = add_amount + tech.MAX_HEALTH;
+ hp = amount;
+ }
+ if (scalar_amount != 0) {
+ g_hp.add(new AttributeModifier(UUID.randomUUID(), "generic.maxHealth", scalar_amount,
+ AttributeModifier.Operation.ADD_SCALAR, equip));
+ }
+ if (addmult_amount != 0) {
+ g_hp.add(new AttributeModifier(UUID.randomUUID(), "generic.maxHealth", addmult_amount,
+ AttributeModifier.Operation.MULTIPLY_SCALAR_1, equip));
+ }
+
+ Collection at = map.get(Attribute.GENERIC_ARMOR_TOUGHNESS);
+ add_amount = 0;
+ scalar_amount = 0;
+ addmult_amount = 0;
+ for (AttributeModifier am : at) {
+ switch (am.getOperation()) {
+ case ADD_NUMBER:
+ add_amount += am.getAmount();
+ break;
+ case ADD_SCALAR:
+ scalar_amount += am.getAmount();
+ break;
+ case MULTIPLY_SCALAR_1:
+ addmult_amount += am.getAmount();
+ break;
+ default:
+ break;
+ }
+ }
+ at.clear();
+ if (add_amount + tech.ARMOR_TOUGHNESS != 0) {
+ double amount = add_amount + tech.ARMOR_TOUGHNESS;
+ armor_toughness = amount;
+ }
+ if (scalar_amount != 0) {
+ at.add(new AttributeModifier(UUID.randomUUID(), "generic.armorToughness", scalar_amount,
+ AttributeModifier.Operation.ADD_SCALAR, equip));
+ }
+ if (addmult_amount != 0) {
+ at.add(new AttributeModifier(UUID.randomUUID(), "generic.armorToughness", addmult_amount,
+ AttributeModifier.Operation.MULTIPLY_SCALAR_1, equip));
+ }
+
+ Collection ad = map.get(Attribute.GENERIC_ATTACK_DAMAGE);
+ add_amount = 0;
+ scalar_amount = 0;
+ addmult_amount = 0;
+ for (AttributeModifier am : ad) {
+ switch (am.getOperation()) {
+ case ADD_NUMBER:
+ add_amount += am.getAmount();
+ break;
+ case ADD_SCALAR:
+ scalar_amount += am.getAmount();
+ break;
+ case MULTIPLY_SCALAR_1:
+ addmult_amount += am.getAmount();
+ break;
+ default:
+ break;
+ }
+ }
+ ad.clear();
+ if (add_amount + tech.ATTACK_DAMAGE != 0) {
+ double amount = add_amount + tech.ATTACK_DAMAGE;
+ if (amount > t.ATTACK_DAMAGE) {
+ amount = t.ATTACK_DAMAGE;
+ }
+ damage = amount;
+ ad.add(new AttributeModifier(UUID.randomUUID(), "generic.attackDamage", amount,
+ AttributeModifier.Operation.ADD_NUMBER, equip));
+ }
+ if (scalar_amount != 0) {
+ ad.add(new AttributeModifier(UUID.randomUUID(), "generic.attackDamage", scalar_amount,
+ AttributeModifier.Operation.ADD_SCALAR, equip));
+ }
+ if (addmult_amount != 0) {
+ ad.add(new AttributeModifier(UUID.randomUUID(), "generic.attackDamage", addmult_amount,
+ AttributeModifier.Operation.MULTIPLY_SCALAR_1, equip));
+ }
+
+ Collection as = map.get(Attribute.GENERIC_ATTACK_SPEED);
+ add_amount = 0;
+ scalar_amount = 0;
+ addmult_amount = 0;
+ for (AttributeModifier am : as) {
+ switch (am.getOperation()) {
+ case ADD_NUMBER:
+ add_amount += am.getAmount();
+ break;
+ case ADD_SCALAR:
+ scalar_amount += am.getAmount();
+ break;
+ case MULTIPLY_SCALAR_1:
+ addmult_amount += am.getAmount();
+ break;
+ default:
+ break;
+ }
+ }
+ as.clear();
+ if (add_amount + tech.ATTACK_SPEED != 0) {
+ double amount = add_amount + tech.ATTACK_SPEED;
+ if (amount > t.ATTACK_SPEED) {
+ amount = t.ATTACK_SPEED;
+ }
+ attack_speed = amount;
+ as.add(new AttributeModifier(UUID.randomUUID(), "generic.attackSpeed", amount,
+ AttributeModifier.Operation.ADD_NUMBER, equip));
+ }
+ if (scalar_amount != 0) {
+ as.add(new AttributeModifier(UUID.randomUUID(), "generic.attackSpeed", scalar_amount,
+ AttributeModifier.Operation.ADD_SCALAR, equip));
+ }
+ if (addmult_amount != 0) {
+ as.add(new AttributeModifier(UUID.randomUUID(), "generic.attackSpeed", addmult_amount,
+ AttributeModifier.Operation.MULTIPLY_SCALAR_1, equip));
+ }
+
+ Collection kr = map.get(Attribute.GENERIC_KNOCKBACK_RESISTANCE);
+ add_amount = 0;
+ scalar_amount = 0;
+ addmult_amount = 0;
+ for (AttributeModifier am : kr) {
+ switch (am.getOperation()) {
+ case ADD_NUMBER:
+ add_amount += am.getAmount();
+ break;
+ case ADD_SCALAR:
+ scalar_amount += am.getAmount();
+ break;
+ case MULTIPLY_SCALAR_1:
+ addmult_amount += am.getAmount();
+ break;
+ default:
+ break;
+ }
+ }
+ kr.clear();
+ if (add_amount + tech.KNOCKBACK_RESISTANCE != 0) {
+ double amount = add_amount + tech.KNOCKBACK_RESISTANCE;
+ if (amount > t.KNOCKBACK_RESISTANCE) {
+ amount = t.KNOCKBACK_RESISTANCE;
+ }
+ knockback_resistance = amount;
+ kr.add(new AttributeModifier(UUID.randomUUID(), "generic.knockbackResistance", amount,
+ AttributeModifier.Operation.ADD_NUMBER, equip));
+ }
+ if (scalar_amount != 0) {
+ kr.add(new AttributeModifier(UUID.randomUUID(), "generic.knockbackResistance", scalar_amount,
+ AttributeModifier.Operation.ADD_SCALAR, equip));
+ }
+ if (addmult_amount != 0) {
+ kr.add(new AttributeModifier(UUID.randomUUID(), "generic.knockbackResistance", addmult_amount,
+ AttributeModifier.Operation.MULTIPLY_SCALAR_1, equip));
+ }
+
+ Collection ms = map.get(Attribute.GENERIC_MOVEMENT_SPEED);
+ add_amount = 0;
+ scalar_amount = 0;
+ addmult_amount = 0;
+ for (AttributeModifier am : ms) {
+ switch (am.getOperation()) {
+ case ADD_NUMBER:
+ add_amount += am.getAmount();
+ break;
+ case ADD_SCALAR:
+ scalar_amount += am.getAmount();
+ break;
+ case MULTIPLY_SCALAR_1:
+ addmult_amount += am.getAmount();
+ break;
+ default:
+ break;
+ }
+ }
+ ms.clear();
+ if (add_amount + tech.MOVEMENT_SPEED != 0) {
+ double amount = add_amount + tech.MOVEMENT_SPEED;
+ if (amount > t.MOVEMENT_SPEED) {
+ amount = t.MOVEMENT_SPEED;
+ }
+ movement_speed = amount;
+ if (equip.equals(EquipmentSlot.HAND)) {
+ ms.add(new AttributeModifier(UUID.randomUUID(), "generic.movementSpeed", amount,
+ AttributeModifier.Operation.ADD_NUMBER, equip));
+ }
+ }
+ if (scalar_amount != 0) {
+ ms.add(new AttributeModifier(UUID.randomUUID(), "generic.movementSpeed", scalar_amount,
+ AttributeModifier.Operation.ADD_SCALAR, equip));
+ }
+ if (addmult_amount != 0) {
+ ms.add(new AttributeModifier(UUID.randomUUID(), "generic.movementSpeed", addmult_amount,
+ AttributeModifier.Operation.MULTIPLY_SCALAR_1, equip));
+ }
+ meta.setAttributeModifiers(map);
+ // mod attribute
+
+ } else {// if no attribute then add
+ meta.addAttributeModifier(Attribute.GENERIC_ATTACK_DAMAGE, new AttributeModifier(UUID.randomUUID(),
+ "generic.attackDamage", tech.ATTACK_DAMAGE, AttributeModifier.Operation.ADD_NUMBER, equip));
+ meta.addAttributeModifier(Attribute.GENERIC_ATTACK_SPEED, new AttributeModifier(UUID.randomUUID(),
+ "generic.attackSpeed", tech.ATTACK_SPEED, AttributeModifier.Operation.ADD_NUMBER, equip));
+ meta.addAttributeModifier(Attribute.GENERIC_KNOCKBACK_RESISTANCE,
+ new AttributeModifier(UUID.randomUUID(), "generic.knockbackResistance",
+ tech.KNOCKBACK_RESISTANCE, AttributeModifier.Operation.ADD_NUMBER, equip));
+ if (equip.equals(EquipmentSlot.HAND)) {
+ meta.addAttributeModifier(Attribute.GENERIC_MOVEMENT_SPEED,
+ (new AttributeModifier(UUID.randomUUID(), "generic.movementSpeed", tech.MOVEMENT_SPEED,
+ AttributeModifier.Operation.ADD_NUMBER, equip)));
+ }
+ hp = tech.MAX_HEALTH;
+ armor = tech.ARMOR;
+ armor_toughness = tech.ARMOR_TOUGHNESS;
+ movement_speed = tech.MOVEMENT_SPEED;
+ attack_speed = tech.ATTACK_SPEED;
+ knockback_resistance = tech.KNOCKBACK_RESISTANCE;
+ damage = tech.ATTACK_DAMAGE;
+ }
+
+ item.setItemMeta(meta);
+ double cast = ModifyItem.getItemCastMod(item) + tech.CAST_MOD;
+ double range = ModifyItem.getItemRangeMod(item) + tech.ATTACK_RANGE;
+ double mana = ModifyItem.getItemMP(item) + tech.MAX_MANA;
+ if (cast != 0) {
+ if (cast > t.CAST_MOD) {
+ cast = t.CAST_MOD;
+ }
+ ModifyItem.setItemCastMod(item, cast);
+ castmod = (int) cast;
+ }
+ if (range != 0) {
+ if (range > t.ATTACK_RANGE) {
+ range = t.ATTACK_RANGE;
+ }
+ ModifyItem.setItemRangeMod(item, range);
+ attack_range = range;
+ }
+ if (mana != 0) {
+ if (mana > t.MAX_MANA) {
+ mana = t.MAX_MANA;
+ }
+ ModifyItem.setItemMP(item, mana);
+ mp = mana;
+ }
+ // weapon mod
+ player.getLocation().getWorld().playSound(player.getLocation(), Sound.BLOCK_ANVIL_USE, 3, 1);
+ ItemMeta im = item.getItemMeta();
+ List lore;
+ if (im.hasLore()) {
+ lore = im.getLore();
+ } else {
+ lore = new ArrayList();
+ }
+ hp += ModifyItem.getItemHP(item);
+ armor += ModifyItem.getItemAR(item);
+ armor_toughness += ModifyItem.getItemAT(item);
+ movement_speed += ModifyItem.getItemSD(item);
+ if (movement_speed > t.MOVEMENT_SPEED) {
+ movement_speed = t.MOVEMENT_SPEED;
+ }
+ if (hp > t.MAX_HEALTH) {
+ hp = t.MAX_HEALTH;
+ }
+ if (armor > t.ARMOR) {
+ armor = t.ARMOR;
+ }
+ if (armor_toughness > t.ARMOR_TOUGHNESS) {
+ armor_toughness = t.ARMOR_TOUGHNESS;
+ }
+ ModifyItem.setItemHP(item, hp);
+ ModifyItem.setItemAR(item, armor);
+ ModifyItem.setItemAT(item, armor_toughness);
+ if (!equip.equals(EquipmentSlot.HAND)) {
+ ModifyItem.setItemSD(item, movement_speed);
+ }
+ ModifyItem.LoreBuilder(item, tech.slot, hp, mp, armor, armor_toughness, movement_speed, attack_range,
+ attack_speed, knockback_resistance, castmod, damage, time + 1, lore);
+ }
+ return;
+ }
+ int clickSlot = event.getSlot();
+ int type = CreateItem.getItemForgeSlot(clicked);
+ if (type != -1) {
+ int oldtype = CreateItem.getItemForgeSlot(inv.getItem(0));
+ if (oldtype != -1) {
+ return;
+ } else {
+ ItemStack stack = clicked.clone();
+ stack.setAmount(1);
+ inv.setItem(0, stack);
+ int amount = clicked.getAmount();
+ if (amount > 1) {
+ clicked.setAmount(amount - 1);
+ player.getInventory().setItem(clickSlot, clicked);
+ } else {
+ player.getInventory().setItem(clickSlot, null);
+ }
+ }
+ } else {
+ String oldtier = getItemForgeMaterialTier(inv.getItem(1));
+ if (oldtier == "-1") {
+ String tier = getItemForgeMaterialTier(clicked);
+ if (tier != "-1") {
+ inv.setItem(1, clicked);
+ player.getInventory().setItem(clickSlot, null);
+ }
+ } else {
+ return;
+ }
+ }
+
+ item = inv.getItem(0);
+ mat = inv.getItem(1);
+ if (item != null && mat != null) {
+ inv.setItem(2, CreateItem.click.clone());
+ PlayerForging(player, inv, item);
+ } else {
+ inv.setItem(2, null);
+ }
+
+ }
+
+ private static Technique getTechnique(ItemStack item, ItemStack material, int note) {
+ String tier = getItemForgeMaterialTier(material);
+ int slot = CreateItem.getItemForgeSlot(item);
+ String str = slot + "." + tier;
+ if (CreateItem.technique.containsKey(str)) {
+ return CreateItem.technique.get(str)[note];
+ } else if (CreateItem.rand_technique.containsKey(tier)) {
+ return CreateItem.rand_technique.get(tier)[slot];
+ } else {
+ System.out.println("Wrong Config? Error: \"" + tier + "\"");
+ return new Technique("0,0,0,0,0,0,0,0,0,0", slot);
+ }
+ }
+
+ private static Technique getLimitTechnique(ItemStack item) {
+ int slot = CreateItem.getItemForgeSlot(item);
+ String str = "" + slot;
+ if (CreateItem.limits.containsKey(str)) {
+ return CreateItem.limits.get(str);
+ } else {
+ return new Technique("0,0,0,0,0,0,0,0,0,0", slot);
+ }
+ }
+
+ private static String getItemForgeMaterialTier(ItemStack item) {
+ if (item == null || item.getType() == Material.AIR) {
+ return "-1";
+ }
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ if (pdc.has(CreateItem.key_material, PersistentDataType.STRING)) {
+ return pdc.get(CreateItem.key_material, PersistentDataType.STRING);
+ }
+ return "-1";
+ }
+
+ private static Note getNoteFromInt(int i) {
+ return CreateItem.notes[i];
+ }
+
+ private static int getRandomIntforNote() {
+ return Utils.rand.nextInt(CreateItem.size);
+ }
+
+ private static void playNote(Note note, Player player) {
+ player.playNote(player.getLocation(), Instrument.BIT, note);
+ }
+
+ private static void PlayerForging(Player player, Inventory inv, ItemStack item) {
+ int time = CreateItem.getItemForgeTime(item);
+ if (CreateItem.max - time < 1) {
+ player.sendMessage(ChatColor.RED + "此道具已無法繼續鍛造");
+ player.closeInventory();
+ return;
+ }
+ int i = getRandomIntforNote();
+ Note note = getNoteFromInt(i);
+ CreateItem.setItemForgeKey(item, i);
+ playNote(note, player);
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ if (inv.getItem(0) != null && inv.getItem(1) != null) {
+ if (inv.getItem(0).equals(item)) {
+ PlayerForging(player, inv, item);
+ }
+ }
+ }
+ }.runTaskLater(Main.getPlugin(), CreateItem.rate);
+ }
+
+ @EventHandler
+ public void leave(PlayerQuitEvent event) {
+ Player player = event.getPlayer();
+ player.closeInventory();
+ }
+
+ @EventHandler
+ public void closeEvent(InventoryCloseEvent event) {
+ Player player = (Player) event.getPlayer();
+ Inventory inv = event.getInventory();
+ if (!event.getView().getTitle().equals("裝備/武器鍛造")) {
+ return;
+ }
+ Utils.additem(player, inv.getItem(0));
+ Utils.additem(player, inv.getItem(1));
+ inv.setItem(0, null);
+ inv.setItem(1, null);
+ inv.setItem(2, null);
+ }
+}
diff --git a/src/main/java/nashi/NRPG/listeners/ModifyItem.java b/src/main/java/nashi/NRPG/listeners/ModifyItem.java
new file mode 100644
index 0000000..cc600b7
--- /dev/null
+++ b/src/main/java/nashi/NRPG/listeners/ModifyItem.java
@@ -0,0 +1,680 @@
+package nashi.NRPG.listeners;
+
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.UUID;
+
+import org.bukkit.ChatColor;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.NamespacedKey;
+import org.bukkit.attribute.Attribute;
+import org.bukkit.attribute.AttributeModifier;
+import org.bukkit.enchantments.Enchantment;
+import org.bukkit.entity.EntityType;
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.block.Action;
+import org.bukkit.event.player.PlayerInteractEvent;
+import org.bukkit.event.player.PlayerItemHeldEvent;
+import org.bukkit.inventory.EquipmentSlot;
+import org.bukkit.inventory.ItemFlag;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+import org.bukkit.persistence.PersistentDataContainer;
+import org.bukkit.persistence.PersistentDataType;
+
+import com.google.common.collect.Multimap;
+
+import nashi.NRPG.Main;
+import nashi.NRPG.API.SkillAPI;
+import nashi.NRPG.API.Utils;
+
+public class ModifyItem implements Listener {
+ public static NamespacedKey Item_Range = new NamespacedKey(Main.getPlugin(), "NRPG_AttackRange");
+ public static NamespacedKey Castkey = new NamespacedKey(Main.getPlugin(), "NRPG_CastMod");
+ public static HashMap edit = new HashMap();
+ public static HashMap atktime = new HashMap();
+ public static NamespacedKey CastHelp = new NamespacedKey(Main.getPlugin(), "NRPG_CastHelp");
+ public static NamespacedKey Item_MP = new NamespacedKey(Main.getPlugin(), "NRPG_ItemMP");// mp
+ public static NamespacedKey Item_HP = new NamespacedKey(Main.getPlugin(), "NRPG_ItemHP");// hp
+ public static NamespacedKey Item_AR = new NamespacedKey(Main.getPlugin(), "NRPG_ItemAR");// armor
+ public static NamespacedKey Item_AT = new NamespacedKey(Main.getPlugin(), "NRPG_ItemAT");// armor toughness
+ public static NamespacedKey Item_SD = new NamespacedKey(Main.getPlugin(), "NRPG_ItemSD");// speed
+
+ public static void updateItem(ItemStack item, EquipmentSlot equip) {
+ if (item == null || item.getType().equals(Material.AIR) || equip.equals(EquipmentSlot.HAND)) {
+ return;
+ }
+ double hp = 0, armor = 0, armor_toughness = 0, movement_speed = 0;
+ try {
+ ItemMeta meta = item.getItemMeta();
+ if (meta.hasAttributeModifiers()) {
+ Multimap map = meta.getAttributeModifiers(equip);
+ Collection g_armor = map.get(Attribute.GENERIC_ARMOR);
+ double add_amount = 0;
+ double scalar_amount = 0;
+ double addmult_amount = 0;
+ for (AttributeModifier am : g_armor) {
+ switch (am.getOperation()) {
+ case ADD_NUMBER:
+ add_amount += am.getAmount();
+ break;
+ default:
+ break;
+ }
+ }
+ g_armor.clear();
+ armor = add_amount;
+ if (scalar_amount != 0) {
+ g_armor.add(new AttributeModifier(UUID.randomUUID(), "generic.armor", scalar_amount,
+ AttributeModifier.Operation.ADD_SCALAR, equip));
+ }
+ if (addmult_amount != 0) {
+ g_armor.add(new AttributeModifier(UUID.randomUUID(), "generic.armor", addmult_amount,
+ AttributeModifier.Operation.MULTIPLY_SCALAR_1, equip));
+ }
+
+ Collection g_hp = map.get(Attribute.GENERIC_MAX_HEALTH);
+ add_amount = 0;
+ scalar_amount = 0;
+ addmult_amount = 0;
+ for (AttributeModifier am : g_hp) {
+ switch (am.getOperation()) {
+ case ADD_NUMBER:
+ add_amount += am.getAmount();
+ break;
+ case ADD_SCALAR:
+ scalar_amount += am.getAmount();
+ break;
+ case MULTIPLY_SCALAR_1:
+ addmult_amount += am.getAmount();
+ break;
+ default:
+ break;
+ }
+ }
+ g_hp.clear();
+ hp = add_amount;
+ if (scalar_amount != 0) {
+ g_hp.add(new AttributeModifier(UUID.randomUUID(), "generic.maxHealth", scalar_amount,
+ AttributeModifier.Operation.ADD_SCALAR, equip));
+ }
+ if (addmult_amount != 0) {
+ g_hp.add(new AttributeModifier(UUID.randomUUID(), "generic.maxHealth", addmult_amount,
+ AttributeModifier.Operation.MULTIPLY_SCALAR_1, equip));
+ }
+
+ Collection at = map.get(Attribute.GENERIC_ARMOR_TOUGHNESS);
+ add_amount = 0;
+ scalar_amount = 0;
+ addmult_amount = 0;
+ for (AttributeModifier am : at) {
+ switch (am.getOperation()) {
+ case ADD_NUMBER:
+ add_amount += am.getAmount();
+ break;
+ case ADD_SCALAR:
+ scalar_amount += am.getAmount();
+ break;
+ case MULTIPLY_SCALAR_1:
+ addmult_amount += am.getAmount();
+ break;
+ default:
+ break;
+ }
+ }
+ at.clear();
+
+ armor_toughness = add_amount;
+ if (scalar_amount != 0) {
+ at.add(new AttributeModifier(UUID.randomUUID(), "generic.armorToughness", scalar_amount,
+ AttributeModifier.Operation.ADD_SCALAR, equip));
+ }
+ if (addmult_amount != 0) {
+ at.add(new AttributeModifier(UUID.randomUUID(), "generic.armorToughness", addmult_amount,
+ AttributeModifier.Operation.MULTIPLY_SCALAR_1, equip));
+ }
+
+ Collection ms = map.get(Attribute.GENERIC_MOVEMENT_SPEED);
+ add_amount = 0;
+ scalar_amount = 0;
+ addmult_amount = 0;
+ for (AttributeModifier am : ms) {
+ switch (am.getOperation()) {
+ case ADD_NUMBER:
+ add_amount += am.getAmount();
+ break;
+ case ADD_SCALAR:
+ scalar_amount += am.getAmount();
+ break;
+ case MULTIPLY_SCALAR_1:
+ addmult_amount += am.getAmount();
+ break;
+ default:
+ break;
+ }
+ }
+ ms.clear();
+
+ movement_speed = add_amount;
+ if (scalar_amount != 0) {
+ ms.add(new AttributeModifier(UUID.randomUUID(), "generic.movementSpeed", scalar_amount,
+ AttributeModifier.Operation.ADD_SCALAR, equip));
+ }
+ if (addmult_amount != 0) {
+ ms.add(new AttributeModifier(UUID.randomUUID(), "generic.movementSpeed", addmult_amount,
+ AttributeModifier.Operation.MULTIPLY_SCALAR_1, equip));
+ }
+ meta.setAttributeModifiers(map);
+ // mod attribute
+ if (hp + armor + armor_toughness + movement_speed != 0) {
+ item.setItemMeta(meta);
+ setItemHP(item, getItemHP(item) + hp);
+ setItemAR(item, getItemAR(item) + armor);
+ setItemAT(item, getItemAT(item) + armor_toughness);
+ setItemSD(item, getItemSD(item) + movement_speed);
+ }
+ }
+
+ } catch (Exception e) {
+
+ }
+ }
+
+ public static void setItemHP(ItemStack item, double amount) {
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ pdc.set(ModifyItem.Item_HP, PersistentDataType.DOUBLE, amount);
+ item.setItemMeta(im);
+ }
+
+ public static double getItemHP(ItemStack item) {
+ double range = 0;
+ if (item == null || item.getType() == Material.AIR) {
+ return range;
+ }
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ if (pdc.has(Item_HP, PersistentDataType.DOUBLE)) {
+ range += pdc.get(Item_HP, PersistentDataType.DOUBLE);
+ }
+ return range;
+ }
+
+ public static void setItemAR(ItemStack item, double amount) {
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ pdc.set(ModifyItem.Item_AR, PersistentDataType.DOUBLE, amount);
+ item.setItemMeta(im);
+ }
+
+ public static double getItemAR(ItemStack item) {
+ double range = 0;
+ if (item == null || item.getType() == Material.AIR) {
+ return range;
+ }
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ if (pdc.has(Item_AR, PersistentDataType.DOUBLE)) {
+ range += pdc.get(Item_AR, PersistentDataType.DOUBLE);
+ }
+ return range;
+ }
+
+ public static void setItemAT(ItemStack item, double amount) {
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ pdc.set(ModifyItem.Item_AT, PersistentDataType.DOUBLE, amount);
+ item.setItemMeta(im);
+ }
+
+ public static double getItemAT(ItemStack item) {
+ double range = 0;
+ if (item == null || item.getType() == Material.AIR) {
+ return range;
+ }
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ if (pdc.has(Item_AT, PersistentDataType.DOUBLE)) {
+ range += pdc.get(Item_AT, PersistentDataType.DOUBLE);
+ }
+ return range;
+ }
+
+ public static void setItemSD(ItemStack item, double amount) {
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ pdc.set(ModifyItem.Item_SD, PersistentDataType.DOUBLE, amount);
+ item.setItemMeta(im);
+ }
+
+ public static double getItemSD(ItemStack item) {
+ double range = 0;
+ if (item == null || item.getType() == Material.AIR) {
+ return range;
+ }
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ if (pdc.has(Item_SD, PersistentDataType.DOUBLE)) {
+ range += pdc.get(Item_SD, PersistentDataType.DOUBLE);
+ }
+ return range;
+ }
+
+ @EventHandler
+ public void click(PlayerInteractEvent event) {
+ Player player = event.getPlayer();
+ if ((event.getAction().equals(Action.LEFT_CLICK_AIR))) {
+ double range = getPlayerAttackRange(player);
+ LivingEntity e = SkillAPI.getEntityInLineOfSight(player, range);
+ if (e == null) {
+ return;
+ }
+ Location loc = player.getEyeLocation();
+ if (e.getLocation().distance(loc) > 4) {
+ double dmg = player.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE).getValue() * AtkModBasedCD(player)
+ + extraATKBasedEnch(player, e);
+ e.damage(dmg, player);
+ }
+ atktime.put(player, System.currentTimeMillis());
+ }
+ if (event.getAction().equals(Action.LEFT_CLICK_BLOCK)) {
+ atktime.put(player, System.currentTimeMillis());
+ }
+ }
+
+ @EventHandler
+ public void itemswitch(PlayerItemHeldEvent event) {
+ Player player = event.getPlayer();
+ atktime.put(player, System.currentTimeMillis());
+ }
+
+ private static String LorePrefix = ChatColor.WHITE + "〕";
+ private static DecimalFormat df = new DecimalFormat("#.##");
+ private static String LoreLine = ChatColor.WHITE + "==============================";
+
+ public static void LoreBuilder(ItemStack item, EquipmentSlot slot, double hp, double mp, double armor,
+ double armor_toughness, double movement_speed, double attack_range, double attack_speed,
+ double knockback_resistance, int castmod, double damage, int forge_time, List oldLore) {
+ if (!item.hasItemMeta()) {
+ return;
+ }
+ ItemMeta meta = item.getItemMeta();
+ meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
+ List lore = new ArrayList();
+ String str = LorePrefix + "欄位: ";
+ switch (slot) {
+ case CHEST:
+ str += "胸甲";
+ break;
+ case FEET:
+ str += "鞋子";
+ break;
+ case LEGS:
+ str += "褲甲";
+ break;
+ case HEAD:
+ str += "頭盔";
+ break;
+ case OFF_HAND:
+ str += "副手";
+ break;
+ case HAND:
+ str += "武器";
+ break;
+ }
+ lore.add(str);
+ if (hp != 0) {
+ lore.add(ModifyItem.HPLoreBuilder(hp));
+ }
+ if (mp != 0) {
+ lore.add(ModifyItem.MPLoreBuilder(mp));
+ }
+ if ((int) (armor * 100) != 0) {
+ lore.add(ModifyItem.ArmorLoreBuilder(armor));
+ }
+ if ((int) (armor_toughness * 100) != 0) {
+ lore.add(ModifyItem.ArmorToughnessLoreBuilder(armor_toughness));
+ }
+ if ((int) (damage * 100) != 0) {
+ lore.add(ModifyItem.DamageLoreBuilder(damage));
+ }
+ if ((int) (attack_range * 100) != 0) {
+ lore.add(ModifyItem.AttackRangeLoreBuilder(attack_range));
+ }
+ if ((int) (attack_speed * 100) != 0) {
+ lore.add(ModifyItem.AttackSpeedLoreBuilder(attack_speed));
+ }
+ if ((int) (movement_speed * 100) != 0) {
+ lore.add(ModifyItem.MovementSpeedLoreBuilder(movement_speed));
+ }
+ if ((int) (knockback_resistance * 100) != 0) {
+ lore.add(ModifyItem.KnockbackResistanceLoreBuilder(knockback_resistance));
+ }
+ if (castmod != 0) {
+ lore.add(ModifyItem.CastModLoreBuilder(castmod));
+ }
+ if (forge_time != 0) {
+ lore.add(ForgeLoreBuilder(forge_time));
+ }
+ if (oldLore.size() > 0) {
+ boolean t = true;
+ for (String l : oldLore) {
+ if (!l.startsWith(ModifyItem.LorePrefix) && !l.equals(ModifyItem.LoreLine)) {
+ if (t) {
+ lore.add(ModifyItem.LoreLine);// 分隔線
+ t = false;
+ }
+ lore.add(l);
+ }
+ }
+ }
+ meta.setLore(lore);
+ item.setItemMeta(meta);
+ }
+
+ public static String ForgeLoreBuilder(int amount) {
+ String str = LorePrefix + "已鍛造次數: ";
+ str += amount;
+ return str;
+ }
+
+ public static String MPLoreBuilder(double amount) {
+ String str = LorePrefix + "魔力: ";
+ if (amount < 0) {
+ str += df.format(amount);
+ } else {
+ str += "+" + df.format(amount);
+ }
+ return str;
+ }
+
+ public static String HPLoreBuilder(double amount) {
+ String str = LorePrefix + "血量: ";
+ if (amount < 0) {
+ str += df.format(amount);
+ } else {
+ str += "+" + df.format(amount);
+ }
+ return str;
+ }
+
+ public static String ArmorLoreBuilder(double amount) {
+ String str = LorePrefix + "裝甲: ";
+ if (amount < 0) {
+ str += df.format(amount);
+ } else {
+ str += "+" + df.format(amount);
+ }
+ return str;
+ }
+
+ public static String ArmorToughnessLoreBuilder(double amount) {
+ String str = LorePrefix + "抗性: ";
+ if (amount < 0) {
+ str += df.format(amount);
+ } else {
+ str += "+" + df.format(amount);
+ }
+ return str;
+ }
+
+ public static String MovementSpeedLoreBuilder(double amount) {
+ String str = LorePrefix + "移動速度: ";
+ if (amount < 0) {
+ str += df.format(amount);
+ } else {
+ str += "+" + df.format(amount);
+ }
+ return str;
+ }
+
+ public static String AttackRangeLoreBuilder(double amount) {
+ String str = LorePrefix + "攻擊距離: ";
+ if (amount < 0) {
+ str += df.format(amount);
+ } else {
+ str += "+" + df.format(amount);
+ }
+ return str;
+ }
+
+ public static String AttackSpeedLoreBuilder(double amount) {
+ String str = LorePrefix + "攻擊速度: ";
+ if (amount < 0) {
+ str += df.format(amount);
+ } else {
+ str += "+" + df.format(amount);
+ }
+ return str;
+ }
+
+ public static String KnockbackResistanceLoreBuilder(double amount) {
+ String str = LorePrefix + "抗擊退機率: ";
+ amount *= 100;
+ if (amount < 0) {
+ str += ((int) amount) + "%";
+ } else {
+ str += "+" + ((int) amount) + "%";
+ }
+ return str;
+ }
+
+ public static String CastModLoreBuilder(int amount) {
+ String str = LorePrefix + "技能詠唱次數需求";
+ if (amount < 0) {
+ str += "增加: " + df.format(Math.abs(amount));
+ } else {
+ str += "減少: " + df.format(amount);
+ }
+ return str;
+ }
+
+ public static String DamageLoreBuilder(double amount) {
+ String str = LorePrefix + "傷害: ";
+ if (amount < 0) {
+ str += df.format(amount);
+ } else {
+ str += "+" + df.format(amount);
+ }
+ return str;
+ }
+
+ public static double getPlayerAttackRange(Player player) {
+ if (edit.containsKey(player)) {
+ return edit.get(player);
+ }
+ ItemStack item = player.getInventory().getItemInMainHand();
+ double range = Utils.defaultattackrange;
+ if (item == null || item.getType() == Material.AIR) {
+ return range;
+ }
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ if (pdc.has(Item_Range, PersistentDataType.DOUBLE)) {
+ range += pdc.get(Item_Range, PersistentDataType.DOUBLE);
+ }
+ return range;
+ }
+
+ public static double getItemRangeMod(ItemStack item) {
+ double range = 0;
+ if (item == null || item.getType() == Material.AIR) {
+ return range;
+ }
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ if (pdc.has(Item_Range, PersistentDataType.DOUBLE)) {
+ range += pdc.get(Item_Range, PersistentDataType.DOUBLE);
+ }
+ return range;
+ }
+
+ public static double getItemMP(ItemStack item) {
+ double range = 0;
+ if (item == null || item.getType() == Material.AIR) {
+ return range;
+ }
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ if (pdc.has(Item_MP, PersistentDataType.DOUBLE)) {
+ range += pdc.get(Item_MP, PersistentDataType.DOUBLE);
+ }
+ return range;
+ }
+
+ public static void setItemRangeMod(ItemStack item, double range) {
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ pdc.set(ModifyItem.Item_Range, PersistentDataType.DOUBLE, range);
+ item.setItemMeta(im);
+ }
+
+ public static void setItemMP(ItemStack item, double amount) {
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ pdc.set(ModifyItem.Item_MP, PersistentDataType.DOUBLE, amount);
+ item.setItemMeta(im);
+ }
+
+ public static void setItemCastMod(ItemStack item, double time) {
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ pdc.set(ModifyItem.Castkey, PersistentDataType.DOUBLE, time);
+ item.setItemMeta(im);
+ }
+
+ public static int getItemCastMod(ItemStack item) {
+ if (item == null || item.getType() == Material.AIR) {
+ return 0;
+ }
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ if (pdc.has(ModifyItem.Castkey, PersistentDataType.DOUBLE)) {
+ return pdc.get(ModifyItem.Castkey, PersistentDataType.DOUBLE).intValue();
+ }
+ return 0;
+ }
+
+ public static double AtkModBasedCD(Player player) {
+ if (!atktime.containsKey(player)) {
+ return 1;
+ }
+ long o = atktime.get(player);
+ long n = System.currentTimeMillis();
+ double t = (n - o) / 50.0;
+ double T = 1 / player.getAttribute(Attribute.GENERIC_ATTACK_SPEED).getValue() * 20;
+ double mult = 0.2 + ((t + 0.5) / T) * ((t + 0.5) / T) * 0.8;
+ if (mult > 1) {
+ mult = 1;
+ }
+ return mult;
+ }
+
+ public static double extraATKBasedEnch(Player player, LivingEntity e) {
+ double dmg = 0;
+ ItemStack item = player.getInventory().getItemInMainHand();
+ if (item.containsEnchantment(Enchantment.DAMAGE_ALL)) {
+ dmg += item.getEnchantmentLevel(Enchantment.DAMAGE_ALL) * 0.5;
+ }
+ EntityType type = e.getType();
+ if (type == EntityType.SPIDER || type == EntityType.CAVE_SPIDER || type == EntityType.ENDERMITE
+ || type == EntityType.SILVERFISH) {
+ if (item.containsEnchantment(Enchantment.DAMAGE_ARTHROPODS)) {
+ dmg += item.getEnchantmentLevel(Enchantment.DAMAGE_ARTHROPODS) * 2.5;
+ }
+ }
+ if (type == EntityType.SKELETON || type == EntityType.SKELETON_HORSE || type == EntityType.STRAY
+ || type == EntityType.WITHER_SKELETON || type == EntityType.WITHER || type == EntityType.ZOMBIE
+ || type == EntityType.HUSK || type == EntityType.ZOMBIE_VILLAGER || type == EntityType.ZOMBIFIED_PIGLIN
+ || type == EntityType.DROWNED || type == EntityType.ZOMBIE_HORSE || type == EntityType.PHANTOM) {
+ if (item.containsEnchantment(Enchantment.DAMAGE_UNDEAD)) {
+ dmg += item.getEnchantmentLevel(Enchantment.DAMAGE_UNDEAD) * 2.5;
+ }
+ }
+ double mult;
+ if (!atktime.containsKey(player)) {
+ mult = 1;
+ } else {
+ long o = atktime.get(player);
+ long n = System.currentTimeMillis();
+ long t = (n - o) / 50;
+ double T = 1 / player.getAttribute(Attribute.GENERIC_ATTACK_SPEED).getValue() * 20;
+ mult = 0.2 + ((t + 0.5) / T) * 0.8;
+ if (mult > 1) {
+ mult = 1;
+ }
+ }
+ return dmg * mult;
+ }
+
+ public static NamespacedKey Potion_HP = new NamespacedKey(Main.getPlugin(), "NRPG_Potion_HP");
+ public static NamespacedKey Potion_MP = new NamespacedKey(Main.getPlugin(), "NRPG_Potion_MP");
+
+ public static int getPotionMP(ItemStack item) {
+ int range = 0;
+ if (item == null || item.getType() == Material.AIR) {
+ return range;
+ }
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ if (pdc.has(Potion_MP, PersistentDataType.INTEGER)) {
+ range += pdc.get(Potion_MP, PersistentDataType.INTEGER);
+ }
+ return range;
+ }
+
+ public static double getPotionHP(ItemStack item) {
+ int range = 0;
+ if (item == null || item.getType() == Material.AIR) {
+ return range;
+ }
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ if (pdc.has(Potion_HP, PersistentDataType.INTEGER)) {
+ range += pdc.get(Potion_HP, PersistentDataType.INTEGER);
+ }
+ return range;
+ }
+
+ public static void setPotionHP(ItemStack item, int amount) {
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ pdc.set(Potion_HP, PersistentDataType.INTEGER, amount);
+ item.setItemMeta(im);
+ }
+
+ public static void setPotionMP(ItemStack item, int amount) {
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ pdc.set(Potion_MP, PersistentDataType.INTEGER, amount);
+ item.setItemMeta(im);
+ }
+
+ public static NamespacedKey SkillBook_key = new NamespacedKey(Main.getPlugin(), "NRPG_SkillBook_Skillname");
+
+ public static String getSkillBookSkill(ItemStack item) {
+ if (item == null || item.getType() == Material.AIR) {
+ return null;
+ }
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ if (pdc.has(SkillBook_key, PersistentDataType.STRING)) {
+ return pdc.get(SkillBook_key, PersistentDataType.STRING);
+ }
+ return null;
+ }
+
+ public static void setSkillBookSkill(ItemStack item, String amount) {
+ ItemMeta im = item.getItemMeta();
+ PersistentDataContainer pdc = im.getPersistentDataContainer();
+ pdc.set(SkillBook_key, PersistentDataType.STRING, amount);
+ item.setItemMeta(im);
+ }
+}
diff --git a/src/main/java/nashi/NRPG/listeners/MythicMobsListener.java b/src/main/java/nashi/NRPG/listeners/MythicMobsListener.java
new file mode 100644
index 0000000..bde2e6c
--- /dev/null
+++ b/src/main/java/nashi/NRPG/listeners/MythicMobsListener.java
@@ -0,0 +1,112 @@
+package nashi.NRPG.listeners;
+
+import java.util.HashMap;
+import java.util.UUID;
+
+import org.bukkit.Bukkit;
+import org.bukkit.OfflinePlayer;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.Listener;
+import org.bukkit.event.entity.EntityDamageByEntityEvent;
+import org.bukkit.event.entity.EntityDamageEvent;
+import io.lumine.xikage.mythicmobs.MythicMobs;
+import io.lumine.xikage.mythicmobs.api.bukkit.events.MythicMobDeathEvent;
+import io.lumine.xikage.mythicmobs.mobs.ActiveMob;
+import io.lumine.xikage.mythicmobs.mobs.MobManager;
+import nashi.NRPG.Players.Leveling;
+
+public class MythicMobsListener implements Listener {
+ public static HashMap> MobsKilled = new HashMap>();
+ public static HashMap> DamageDelt = new HashMap>();
+ public static MythicMobs mythicMobs = MythicMobs.inst();
+ public static MobManager mobManager = mythicMobs.getMobManager();
+ public static final String total = "total";
+ public static final double amount = 0.3;
+
+ @EventHandler
+ public void MyThicMobsDie(MythicMobDeathEvent event) {
+ String type = event.getMobType().getInternalName();
+ HashMap map = DamageDelt.get(event.getMob());
+ double delt = map.get(total);
+ for (String str : map.keySet()) {
+ if (str.equals(total)) {
+ continue;
+ }
+ if (map.get(str) / delt < amount) {
+ continue;
+ }
+ OfflinePlayer offp = Bukkit.getServer().getOfflinePlayer(UUID.fromString(str));
+ if (offp.isOnline()) {
+ Player player = offp.getPlayer();
+ HashMap mk;
+ if (MobsKilled.containsKey(player)) {
+ mk = MobsKilled.get(player);
+ } else {
+ mk = new HashMap();
+ }
+ int n;
+ if (mk.containsKey(type)) {
+ n = mk.get(type);
+ } else {
+ n = 0;
+ }
+ mk.put(type, n + 1);
+ MobsKilled.put(player, mk);
+ Leveling.check(player);
+ }
+
+ }
+ }
+
+ @EventHandler(priority = EventPriority.MONITOR)
+ public void DmgDeltCalc(EntityDamageEvent event) {
+ ActiveMob mob = mobManager.getMythicMobInstance(event.getEntity());
+ if (mob == null) {
+ return;
+ }
+ HashMap map;
+ if (!DamageDelt.containsKey(mob)) {
+ map = new HashMap();
+ } else {
+ map = DamageDelt.get(mob);
+ }
+ double damage = event.getDamage();
+ double c;
+ if (map.containsKey(total)) {
+ c = map.get(total);
+ } else {
+ c = 0;
+ }
+ map.put(total, c + damage);
+ DamageDelt.put(mob, map);
+ }
+
+ @EventHandler(priority = EventPriority.MONITOR)
+ public void DmgDeltCalc(EntityDamageByEntityEvent event) {
+ ActiveMob mob = mobManager.getMythicMobInstance(event.getEntity());
+ if (mob == null) {
+ return;
+ }
+ HashMap map;
+ if (!DamageDelt.containsKey(mob)) {
+ map = new HashMap();
+ } else {
+ map = DamageDelt.get(mob);
+ }
+ double damage = event.getDamage();
+ if (event.getDamager() instanceof Player) {
+ Player player = (Player) event.getDamager();
+ double c;
+ if (map.containsKey(player.getUniqueId().toString())) {
+ c = map.get(player.getUniqueId().toString());
+ } else {
+ c = 0;
+ }
+ map.put(player.getUniqueId().toString(), c + damage);
+ }
+ DamageDelt.put(mob, map);
+ }
+
+}
diff --git a/src/main/java/nashi/NRPG/listeners/ProtocolLibEvent.java b/src/main/java/nashi/NRPG/listeners/ProtocolLibEvent.java
new file mode 100644
index 0000000..7250350
--- /dev/null
+++ b/src/main/java/nashi/NRPG/listeners/ProtocolLibEvent.java
@@ -0,0 +1,41 @@
+package nashi.NRPG.listeners;
+
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+
+import org.bukkit.Sound;
+
+import com.comphenix.protocol.PacketType;
+import com.comphenix.protocol.ProtocolLibrary;
+import com.comphenix.protocol.events.ListenerPriority;
+import com.comphenix.protocol.events.PacketAdapter;
+import com.comphenix.protocol.events.PacketEvent;
+
+import nashi.NRPG.API.SkillAPI;
+
+public class ProtocolLibEvent {
+ public static HashSet sounds = new LinkedHashSet(500);
+
+ public static void run() {
+ ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(SkillAPI.plugin(),
+ ListenerPriority.NORMAL, PacketType.Play.Server.NAMED_SOUND_EFFECT) {
+ @Override
+ public void onPacketSending(PacketEvent event) {
+ if (event.getPacketType() == PacketType.Play.Server.NAMED_SOUND_EFFECT) {
+ Sound sound = event.getPacket().getSoundEffects().read(0);
+ if (!sound.name().contains("ENTITY_PLAYER_ATTACK")) {
+ return;
+ }
+ if (sounds.contains(sound)) {
+ return;
+ }
+ event.setCancelled(true);
+ }
+ }
+ });
+ }
+
+ public static void setWhitelist(Sound sound) {
+ ProtocolLibEvent.sounds.add(sound);
+ }
+}
diff --git a/src/main/java/nashi/NRPG/listeners/SkillItemListener.java b/src/main/java/nashi/NRPG/listeners/SkillItemListener.java
new file mode 100644
index 0000000..0034ec7
--- /dev/null
+++ b/src/main/java/nashi/NRPG/listeners/SkillItemListener.java
@@ -0,0 +1,141 @@
+package nashi.NRPG.listeners;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.bukkit.ChatColor;
+import org.bukkit.World;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.block.Action;
+import org.bukkit.event.player.PlayerInteractEvent;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.Damageable;
+import org.bukkit.inventory.meta.ItemMeta;
+
+import nashi.NRPG.Main;
+import nashi.NRPG.API.SkillAPI;
+import nashi.NRPG.Players.Players;
+import nashi.NRPG.Skills.Cast;
+import nashi.NRPG.Skills.Skill;
+import nashi.NRPG.Skills.SkillItem;
+import nashi.NRPG.listeners.EventListener.Casting;
+
+public class SkillItemListener implements Listener {
+
+ @EventHandler
+ public void use(PlayerInteractEvent event) {
+ Player player = event.getPlayer();
+ if (EventListener.cast.containsKey(player)) {
+ return;
+ }
+ if (event.getAction() != Action.RIGHT_CLICK_AIR && event.getAction() != Action.RIGHT_CLICK_BLOCK) {
+ return;
+ }
+ long cooldowntime = 100L;
+ if (EventListener.scooldowns.containsKey(player.getUniqueId())
+ && System.currentTimeMillis() - EventListener.scooldowns.get(player.getUniqueId()) <= cooldowntime) {
+ return;
+ }
+ try {
+ ItemStack item = player.getInventory().getItemInMainHand();
+ int limit = SkillItem.getSkillLimitTimeUse(item);
+ if (limit == 0) {
+ return;
+ }
+ EventListener.scooldowns.put(player.getUniqueId(), System.currentTimeMillis());
+ String sk = SkillItem.getSkill(item);
+ if (sk == null) {
+ return;
+ }
+ event.setCancelled(true);
+ World world = player.getWorld();
+ try {
+ if (Main.worlds.contains(world)) {
+ player.sendMessage(ChatColor.RED + "你無法在這個世界使用技能");
+ return;
+ }
+ } catch (Exception e) {
+ }
+ if (SkillAPI.Silence.containsKey(player.getUniqueId())) {
+ double secondsLeft = SkillAPI.Silence.get(player.getUniqueId()) - System.currentTimeMillis();
+ if (secondsLeft > 0) {
+ player.sendMessage(ChatColor.RED + "你已被沉默 " + Skill.formatter.format((secondsLeft / 1000)) + " 秒");
+ return;
+ }
+ }
+ if (Skill.cooldowns.containsKey(player.getUniqueId() + "." + sk)) {
+ double secondsLeft = Skill.cooldowns.get(player.getUniqueId() + "." + sk) - System.currentTimeMillis();
+ if (secondsLeft > 0) {
+ player.sendMessage(
+ ChatColor.RED + "技能冷卻時間剩餘:" + Skill.formatter.format((secondsLeft / 1000)) + " 秒");
+ return;
+ }
+ }
+ double cost = SkillAPI.getPublicSkillInfo(sk, "CostMP");
+ Players.PlayerData pd = Players.Data.get(player);
+ if (pd.getCurrentMP() - cost < 0.0) {
+ player.sendMessage(ChatColor.RED + "魔力不足");
+ return;
+ }
+ int difficulty = SkillItem.getSkillDifficulty(item);
+ if (difficulty == -1) {
+ difficulty = (int) SkillAPI.getPublicSkillInfo(sk, "Difficulty");
+ }
+ int req = SkillItem.getSkillTime(item);
+ if (req != -1) {
+ if (req == 0) {
+ Skill.cast(sk, player, true);
+ } else {
+ long time = SkillAPI.getRemainingCooldown(player, sk);
+ if (time > 0L) {
+ player.sendMessage(ChatColor.RED + "技能冷卻時間剩餘:" + Skill.formatter.format((time / 1000)) + " 秒");
+ return;
+ }
+ Cast.Abracadabra abra = Cast.getabracadabra((difficulty));
+ EventListener.playercast(player, new Casting(sk, abra, req), (Cast.castspeed.get(player)),
+ Cast.timelimit);
+ }
+ } else {
+ if (SkillAPI.getPublicSkillInfo(sk, "Times") < 1.0) {
+ Skill.cast(sk, player, true);
+ } else {
+ long time = SkillAPI.getRemainingCooldown(player, sk);
+ if (time > 0L) {
+ player.sendMessage(ChatColor.RED + "技能冷卻時間剩餘:" + Skill.formatter.format((time / 1000)) + " 秒");
+ return;
+ }
+ Cast.Abracadabra abra = Cast.getabracadabra((difficulty));
+ EventListener.playercast(player,
+ new Casting(sk, abra, (int) SkillAPI.getPublicSkillInfo(sk, "Times")),
+ (Cast.castspeed.get(player)), Cast.timelimit);
+ }
+ }
+ SkillItem.setSkillLimitTimeUse(item, limit - 1);
+ if (limit - 1 == 0) {
+ ItemMeta im = item.getItemMeta();
+ List lore;
+ if (im.hasLore()) {
+ lore = im.getLore();
+ } else {
+ lore = new ArrayList();
+ }
+ lore.add(ChatColor.RED + "技能次數已耗盡");
+ im.setLore(lore);
+ item.setItemMeta(im);
+ }
+ int damage = SkillItem.getUseDamage(item);
+ if (damage > 0) {
+ Damageable dmg = ((Damageable) item.getItemMeta());
+ dmg.setDamage(dmg.getDamage() + damage);
+ item.setItemMeta((ItemMeta) dmg);
+ if (item.getType().getMaxDurability() < dmg.getDamage()) {
+ item.setAmount(0);
+ }
+ }
+ } catch (NullPointerException sk) {
+ // empty catch block
+ }
+ }
+}
diff --git a/target/classes/.gitignore b/target/classes/.gitignore
new file mode 100644
index 0000000..4ed4006
--- /dev/null
+++ b/target/classes/.gitignore
@@ -0,0 +1,2 @@
+/edited/
+/nashi/
diff --git a/target/test-classes/nashi/NRPG/AppTest.class b/target/test-classes/nashi/NRPG/AppTest.class
new file mode 100644
index 0000000..60a5313
Binary files /dev/null and b/target/test-classes/nashi/NRPG/AppTest.class differ