Misc.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. package com.gmail.nossr50.util;
  2. import java.util.Random;
  3. import org.bukkit.Location;
  4. import org.bukkit.Material;
  5. import org.bukkit.block.Block;
  6. import org.bukkit.entity.AnimalTamer;
  7. import org.bukkit.entity.Entity;
  8. import org.bukkit.entity.Item;
  9. import org.bukkit.entity.LivingEntity;
  10. import org.bukkit.entity.Player;
  11. import org.bukkit.entity.Tameable;
  12. import org.bukkit.event.entity.EntityDamageEvent;
  13. import org.bukkit.inventory.ItemStack;
  14. import org.bukkit.plugin.PluginManager;
  15. import com.gmail.nossr50.mcMMO;
  16. import com.gmail.nossr50.config.AdvancedConfig;
  17. import com.gmail.nossr50.config.Config;
  18. import com.gmail.nossr50.events.fake.FakeBlockBreakEvent;
  19. import com.gmail.nossr50.events.fake.FakeBlockDamageEvent;
  20. import com.gmail.nossr50.events.fake.FakePlayerAnimationEvent;
  21. import com.gmail.nossr50.events.items.McMMOItemSpawnEvent;
  22. import com.gmail.nossr50.mods.ModChecks;
  23. import com.gmail.nossr50.party.PartyManager;
  24. public final class Misc {
  25. private static Random random = new Random();
  26. public static int toolDurabilityLoss = Config.getInstance().getAbilityToolDamage();
  27. public static int abilityLengthIncreaseLevel = AdvancedConfig.getInstance().getAbilityLength();
  28. public static boolean isSpawnerXPEnabled = Config.getInstance().getExperienceGainsMobspawnersEnabled();
  29. public static final int PLAYER_RESPAWN_COOLDOWN_SECONDS = 5;
  30. public static final int TIME_CONVERSION_FACTOR = 1000;
  31. public static final double SKILL_MESSAGE_MAX_SENDING_DISTANCE = 10.0;
  32. public static final int NORMAL_SKILL_ACTIVATION_CHANCE = 100;
  33. public static final int LUCKY_SKILL_ACTIVATION_CHANCE = 75;
  34. //Sound Pitches & Volumes from CB
  35. public static final float ANVIL_USE_PITCH = 0.3F; // Not in CB directly, I went off the place sound values
  36. public static final float ANVIL_USE_VOLUME = 1.0F; // Not in CB directly, I went off the place sound values
  37. public static final float FIZZ_PITCH = 2.6F + (Misc.getRandom().nextFloat() - Misc.getRandom().nextFloat()) * 0.8F;
  38. public static final float FIZZ_VOLUME = 0.5F;
  39. public static final float POP_PITCH = ((getRandom().nextFloat() - getRandom().nextFloat()) * 0.7F + 1.0F) * 2.0F;
  40. public static final float POP_VOLUME = 0.2F;
  41. private Misc() {};
  42. /**
  43. * Calculate activation chance for a skill.
  44. *
  45. * @param isLucky true if the player has the appropriate "lucky" perk, false otherwise
  46. * @return the activation chance
  47. */
  48. public static int calculateActivationChance(boolean isLucky) {
  49. if (isLucky) {
  50. return LUCKY_SKILL_ACTIVATION_CHANCE;
  51. }
  52. return NORMAL_SKILL_ACTIVATION_CHANCE;
  53. }
  54. public static boolean isFriendlyPet(Player attacker, Tameable pet) {
  55. if (pet.isTamed()) {
  56. AnimalTamer tamer = pet.getOwner();
  57. if (tamer instanceof Player) {
  58. Player owner = (Player) tamer;
  59. if (owner == attacker || PartyManager.inSameParty(attacker, owner)) {
  60. return true;
  61. }
  62. }
  63. }
  64. return false;
  65. }
  66. public static boolean isNPCEntity(Entity entity) {
  67. if (entity == null || entity.hasMetadata("NPC")) {
  68. return true;
  69. }
  70. return false;
  71. }
  72. public static boolean isNPCPlayer(Player player) {
  73. if (player == null || player.hasMetadata("NPC")) {
  74. return true;
  75. }
  76. return false;
  77. }
  78. public static void sendSkillMessage(Player player, String message) {
  79. for (Player otherPlayer : player.getWorld().getPlayers()) {
  80. if (otherPlayer != player && Misc.isNear(player.getLocation(), otherPlayer.getLocation(), Misc.SKILL_MESSAGE_MAX_SENDING_DISTANCE)) {
  81. otherPlayer.sendMessage(message);
  82. }
  83. }
  84. }
  85. /**
  86. * Gets a capitalized version of the target string.
  87. *
  88. * @param target String to capitalize
  89. * @return the capitalized string
  90. */
  91. public static String getCapitalized(String target) {
  92. String firstLetter = target.substring(0,1);
  93. String remainder = target.substring(1);
  94. String capitalized = firstLetter.toUpperCase() + remainder.toLowerCase();
  95. return capitalized;
  96. }
  97. /**
  98. * Gets a nicely formatted string version of an item name from a given item ID.
  99. *
  100. * @param itemID The ID of the item to convert to string.
  101. * @return the nicely formatting string
  102. */
  103. public static String prettyItemString(int itemID) {
  104. String baseString = Material.getMaterial(itemID).toString();
  105. String[] substrings = baseString.split("_");
  106. String prettyString = "";
  107. int size = 1;
  108. for (String s : substrings) {
  109. prettyString = prettyString.concat(Misc.getCapitalized(s));
  110. if (size < substrings.length) {
  111. prettyString = prettyString.concat(" ");
  112. }
  113. size++;
  114. }
  115. return prettyString;
  116. }
  117. /**
  118. * Gets the int represented by this string.
  119. *
  120. * @param string The string to parse
  121. * @return the int represented by this string
  122. */
  123. public static int getInt(String string) {
  124. if (isInt(string)) {
  125. return Integer.parseInt(string);
  126. }
  127. return 0;
  128. }
  129. /**
  130. * Gets the long represented by this string.
  131. *
  132. * @param string The string to parse
  133. * @return the long represented by this string
  134. */
  135. public static long getLong(String string) {
  136. if (isLong(string)) {
  137. return Long.parseLong(string);
  138. }
  139. return 0;
  140. }
  141. /**
  142. * Gets the long represented by this string.
  143. *
  144. * @param string The string to parse
  145. * @return the long represented by this string
  146. */
  147. public static double getDouble(String string) {
  148. if (isDouble(string)) {
  149. return Double.parseDouble(string);
  150. }
  151. return 0;
  152. }
  153. /**
  154. * Checks to see if an entity is currently invincible.
  155. *
  156. * @param le The LivingEntity to check
  157. * @param event The event the entity is involved in
  158. * @return true if the entity is invincible, false otherwise
  159. */
  160. public static boolean isInvincible(LivingEntity le, EntityDamageEvent event) {
  161. /*
  162. * So apparently if you do more damage to a LivingEntity than its last damage int you bypass the invincibility.
  163. * So yeah, this is for that.
  164. */
  165. if (le.getNoDamageTicks() > le.getMaximumNoDamageTicks() / 2.0F && event.getDamage() <= le.getLastDamage()) {
  166. return true;
  167. }
  168. return false;
  169. }
  170. /**
  171. * Simulate a block break event.
  172. *
  173. * @param block The block to break
  174. * @param player The player breaking the block
  175. * @param shouldArmSwing true if an armswing event should be fired, false otherwise
  176. * @return true if the event wasn't cancelled, false otherwise
  177. */
  178. public static boolean blockBreakSimulate(Block block, Player player, Boolean shouldArmSwing) {
  179. //Support for NoCheat
  180. if (shouldArmSwing) {
  181. FakePlayerAnimationEvent armswing = new FakePlayerAnimationEvent(player);
  182. mcMMO.p.getServer().getPluginManager().callEvent(armswing);
  183. }
  184. PluginManager pluginManger = mcMMO.p.getServer().getPluginManager();
  185. FakeBlockDamageEvent damageEvent = new FakeBlockDamageEvent(player, block, player.getItemInHand(), true);
  186. pluginManger.callEvent(damageEvent);
  187. FakeBlockBreakEvent breakEvent = new FakeBlockBreakEvent(block, player);
  188. pluginManger.callEvent(breakEvent);
  189. if (!damageEvent.isCancelled() && !breakEvent.isCancelled()) {
  190. return true;
  191. }
  192. return false;
  193. }
  194. /**
  195. * Get the upgrade tier of the item in hand.
  196. *
  197. * @param inHand The item to check the tier of
  198. * @return the tier of the item
  199. */
  200. public static int getTier(ItemStack inHand) {
  201. int tier = 0;
  202. if (ItemChecks.isWoodTool(inHand)) {
  203. tier = 1;
  204. }
  205. else if (ItemChecks.isStoneTool(inHand)) {
  206. tier = 2;
  207. }
  208. else if (ItemChecks.isIronTool(inHand)) {
  209. tier = 3;
  210. }
  211. else if (ItemChecks.isGoldTool(inHand)) {
  212. tier = 1;
  213. }
  214. else if (ItemChecks.isDiamondTool(inHand)) {
  215. tier = 4;
  216. }
  217. else if (ModChecks.isCustomTool(inHand)) {
  218. tier = ModChecks.getToolFromItemStack(inHand).getTier();
  219. }
  220. return tier;
  221. }
  222. /**
  223. * Determine if two locations are near each other.
  224. *
  225. * @param first The first location
  226. * @param second The second location
  227. * @param maxDistance The max distance apart
  228. * @return true if the distance between <code>first</code> and <code>second</code> is less than <code>maxDistance</code>, false otherwise
  229. */
  230. public static boolean isNear(Location first, Location second, double maxDistance) {
  231. if (!first.getWorld().equals(second.getWorld())) {
  232. return false;
  233. }
  234. if (first.distanceSquared(second) < (maxDistance * maxDistance)) {
  235. return true;
  236. }
  237. return false;
  238. }
  239. /**
  240. * Determine if a string represents an Integer
  241. *
  242. * @param string String to check
  243. * @return true if the string is an Integer, false otherwise
  244. */
  245. public static boolean isInt(String string) {
  246. try {
  247. Integer.parseInt(string);
  248. return true;
  249. }
  250. catch (NumberFormatException nFE) {
  251. return false;
  252. }
  253. }
  254. /**
  255. * Determine if a string represents a Long
  256. *
  257. * @param string String to check
  258. * @return true if the string is a Long, false otherwise
  259. */
  260. public static boolean isLong(String string) {
  261. try {
  262. Long.parseLong(string);
  263. return true;
  264. }
  265. catch (NumberFormatException nFE) {
  266. return false;
  267. }
  268. }
  269. /**
  270. * Determine if a string represents a Double
  271. *
  272. * @param string String to check
  273. * @return true if the string is a Double, false otherwise
  274. */
  275. public static boolean isDouble(String string) {
  276. try {
  277. Double.parseDouble(string);
  278. return true;
  279. }
  280. catch (NumberFormatException nFE) {
  281. return false;
  282. }
  283. }
  284. /**
  285. * Drop items at a given location.
  286. *
  287. * @param location The location to drop the items at
  288. * @param is The items to drop
  289. * @param quantity The amount of items to drop
  290. */
  291. public static void dropItems(Location location, ItemStack is, int quantity) {
  292. for (int i = 0; i < quantity; i++) {
  293. dropItem(location, is);
  294. }
  295. }
  296. /**
  297. * Randomly drop an item at a given location.
  298. *
  299. * @param location The location to drop the items at
  300. * @param is The item to drop
  301. * @param chance The percentage chance for the item to drop
  302. */
  303. public static void randomDropItem(Location location, ItemStack is, int chance) {
  304. if (random.nextInt(100) < chance) {
  305. dropItem(location, is);
  306. }
  307. }
  308. /**
  309. * Randomly drop items at a given location.
  310. *
  311. * @param location The location to drop the items at
  312. * @param is The item to drop
  313. * @param chance The percentage chance for the item to drop
  314. * @param quantity The amount of items to drop
  315. */
  316. public static void randomDropItems(Location location, ItemStack is, int chance, int quantity) {
  317. for (int i = 0; i < quantity; i++) {
  318. randomDropItem(location, is, chance);
  319. }
  320. }
  321. /**
  322. * Drop an item at a given location.
  323. *
  324. * @param location The location to drop the item at
  325. * @param itemStack The item to drop
  326. */
  327. public static void dropItem(Location location, ItemStack itemStack) {
  328. if (itemStack.getType() == Material.AIR) {
  329. return;
  330. }
  331. // We can't get the item until we spawn it and we want to make it cancellable, so we have a custom event.
  332. McMMOItemSpawnEvent event = new McMMOItemSpawnEvent(location, itemStack);
  333. mcMMO.p.getServer().getPluginManager().callEvent(event);
  334. if (event.isCancelled())
  335. return;
  336. Item newItem = location.getWorld().dropItemNaturally(location, itemStack);
  337. ItemStack cloned = itemStack.clone();
  338. cloned.setAmount(newItem.getItemStack().getAmount());
  339. newItem.setItemStack(cloned);
  340. }
  341. /**
  342. * Check if a skill level is higher than the max bonus level of the ability.
  343. *
  344. * @param skillLevel Skill level to check
  345. * @param maxLevel Max level of the ability
  346. * @return whichever value is lower
  347. */
  348. public static int skillCheck(int skillLevel, int maxLevel) {
  349. //TODO: Could we just use Math.min(skillLevel, maxLevel) here?
  350. if (skillLevel > maxLevel) {
  351. return maxLevel;
  352. }
  353. return skillLevel;
  354. }
  355. /**
  356. * Get the max power level for a player.
  357. *
  358. * @return the maximum power level for a player
  359. */
  360. public static int getPowerLevelCap() {
  361. int levelCap = Config.getInstance().getPowerLevelCap();
  362. if (levelCap > 0) {
  363. return levelCap;
  364. }
  365. return Integer.MAX_VALUE;
  366. }
  367. public static Random getRandom() {
  368. return random;
  369. }
  370. }