Herbalism.java 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532
  1. package com.gmail.nossr50.skills.gathering;
  2. import org.bukkit.CropState;
  3. import org.bukkit.DyeColor;
  4. import org.bukkit.Location;
  5. import org.bukkit.Material;
  6. import org.bukkit.block.Block;
  7. import org.bukkit.entity.Player;
  8. import org.bukkit.event.block.BlockBreakEvent;
  9. import org.bukkit.inventory.ItemStack;
  10. import org.bukkit.inventory.PlayerInventory;
  11. import org.bukkit.material.MaterialData;
  12. import com.gmail.nossr50.mcMMO;
  13. import com.gmail.nossr50.config.AdvancedConfig;
  14. import com.gmail.nossr50.config.Config;
  15. import com.gmail.nossr50.config.mods.CustomBlocksConfig;
  16. import com.gmail.nossr50.datatypes.AbilityType;
  17. import com.gmail.nossr50.datatypes.PlayerProfile;
  18. import com.gmail.nossr50.datatypes.SkillType;
  19. import com.gmail.nossr50.datatypes.mods.CustomBlock;
  20. import com.gmail.nossr50.locale.LocaleLoader;
  21. import com.gmail.nossr50.runnables.GreenThumbTimer;
  22. import com.gmail.nossr50.util.Misc;
  23. import com.gmail.nossr50.util.ModChecks;
  24. import com.gmail.nossr50.util.Permissions;
  25. import com.gmail.nossr50.util.Skills;
  26. import com.gmail.nossr50.util.Users;
  27. public class Herbalism {
  28. static AdvancedConfig advancedConfig = AdvancedConfig.getInstance();
  29. /**
  30. * Activate the Green Terra ability.
  31. *
  32. * @param player The player activating the ability
  33. * @param block The block to be changed by Green Terra
  34. */
  35. public static void greenTerra(Player player, Block block) {
  36. PlayerInventory inventory = player.getInventory();
  37. boolean hasSeeds = inventory.contains(Material.SEEDS);
  38. if (!hasSeeds) {
  39. player.sendMessage("You need more seeds to spread Green Terra"); //TODO: Needs more locale.
  40. }
  41. else if (hasSeeds && !block.getType().equals(Material.WHEAT)) {
  42. inventory.removeItem(new ItemStack(Material.SEEDS));
  43. player.updateInventory(); // Needed until replacement available
  44. greenTerraConvert(player, block);
  45. }
  46. }
  47. public static void greenTerraConvert(Player player, Block block) {
  48. Material type = block.getType();
  49. if (Misc.blockBreakSimulate(block, player, false)) {
  50. if (Config.getInstance().getHerbalismGreenThumbSmoothbrickToMossy() && type == Material.SMOOTH_BRICK && block.getData() == 0) {
  51. block.setTypeIdAndData(block.getTypeId(), (byte) 1, false); //Set type of the brick to mossy, force the client update
  52. }
  53. else if (Config.getInstance().getHerbalismGreenThumbDirtToGrass() && type == Material.DIRT) {
  54. block.setType(Material.GRASS);
  55. }
  56. else if (Config.getInstance().getHerbalismGreenThumbCobbleToMossy() && type == Material.COBBLESTONE) {
  57. block.setType(Material.MOSSY_COBBLESTONE);
  58. // Don't award double drops to mossified cobblestone
  59. mcMMO.placeStore.setTrue(block);
  60. }
  61. else if (Config.getInstance().getHerbalismGreenThumbCobbleWallToMossyWall() && type == Material.COBBLE_WALL) {
  62. block.setData((byte) 1);
  63. }
  64. }
  65. }
  66. /**
  67. * Check for extra Herbalism drops.
  68. *
  69. * @param block The block to check for extra drops
  70. * @param player The player getting extra drops
  71. * @param event The event to use for Green Thumb
  72. * @param plugin mcMMO plugin instance
  73. */
  74. public static void herbalismProcCheck(final Block block, Player player, BlockBreakEvent event, mcMMO plugin) {
  75. if (player == null)
  76. return;
  77. final PlayerProfile profile = Users.getProfile(player);
  78. final double MAX_CHANCE = advancedConfig.getHerbalismDoubleDropsChanceMax();
  79. final int MAX_BONUS_LEVEL = advancedConfig.getHerbalismDoubleDropsMaxLevel();
  80. int herbLevel = profile.getSkillLevel(SkillType.HERBALISM);
  81. int id = block.getTypeId();
  82. Material type = block.getType();
  83. Byte data = block.getData();
  84. Location location = block.getLocation();
  85. Material mat = null;
  86. int xp = 0;
  87. int catciDrops = 0;
  88. int caneDrops = 0;
  89. boolean customPlant = false;
  90. int randomChance = 100;
  91. if (Permissions.luckyHerbalism(player)) {
  92. randomChance = (int) (randomChance * 0.75);
  93. }
  94. float chance = (float) (((double) MAX_CHANCE / (double) MAX_BONUS_LEVEL) * herbLevel);
  95. if (chance > MAX_CHANCE) chance = (float) MAX_CHANCE;
  96. switch (type) {
  97. case BROWN_MUSHROOM:
  98. case RED_MUSHROOM:
  99. if (!mcMMO.placeStore.isTrue(block)) {
  100. mat = Material.getMaterial(id);
  101. xp = Config.getInstance().getHerbalismXPMushrooms();
  102. }
  103. break;
  104. case CACTUS:
  105. for (int y = 0; y <= 2; y++) {
  106. Block b = block.getRelative(0, y, 0);
  107. if (b.getType().equals(Material.CACTUS)) {
  108. mat = Material.CACTUS;
  109. if (!mcMMO.placeStore.isTrue(b)) {
  110. if (chance > Misc.getRandom().nextInt(randomChance)) {
  111. catciDrops++;
  112. }
  113. xp += Config.getInstance().getHerbalismXPCactus();
  114. }
  115. }
  116. }
  117. break;
  118. case CROPS:
  119. if (data == CropState.RIPE.getData()) {
  120. mat = Material.WHEAT;
  121. xp = Config.getInstance().getHerbalismXPWheat();
  122. if (Permissions.greenThumbWheat(player)) {
  123. greenThumbWheat(block, player, event, plugin);
  124. }
  125. }
  126. break;
  127. case MELON_BLOCK:
  128. if (!mcMMO.placeStore.isTrue(block)) {
  129. mat = Material.MELON;
  130. xp = Config.getInstance().getHerbalismXPMelon();
  131. }
  132. break;
  133. case NETHER_WARTS:
  134. if (data == (byte) 0x3) {
  135. mat = Material.NETHER_STALK;
  136. xp = Config.getInstance().getHerbalismXPNetherWart();
  137. if (Permissions.greenThumbNetherwart(player)) {
  138. greenThumbWheat(block, player, event, plugin);
  139. }
  140. }
  141. break;
  142. case PUMPKIN:
  143. case JACK_O_LANTERN:
  144. if (!mcMMO.placeStore.isTrue(block)) {
  145. mat = Material.getMaterial(id);
  146. xp = Config.getInstance().getHerbalismXPPumpkin();
  147. }
  148. break;
  149. case RED_ROSE:
  150. case YELLOW_FLOWER:
  151. if (!mcMMO.placeStore.isTrue(block)) {
  152. mat = Material.getMaterial(id);
  153. xp = Config.getInstance().getHerbalismXPFlowers();
  154. }
  155. break;
  156. case SUGAR_CANE_BLOCK:
  157. for (int y = 0; y <= 2; y++) {
  158. Block b = block.getRelative(0, y, 0);
  159. if (b.getType().equals(Material.SUGAR_CANE_BLOCK)) {
  160. mat = Material.SUGAR_CANE;
  161. if (!mcMMO.placeStore.isTrue(b)) {
  162. if (chance > Misc.getRandom().nextInt(randomChance)) {
  163. caneDrops++;
  164. }
  165. xp += Config.getInstance().getHerbalismXPSugarCane();
  166. }
  167. }
  168. }
  169. break;
  170. case VINE:
  171. if (!mcMMO.placeStore.isTrue(block)) {
  172. mat = type;
  173. xp = Config.getInstance().getHerbalismXPVines();
  174. }
  175. break;
  176. case WATER_LILY:
  177. if (!mcMMO.placeStore.isTrue(block)) {
  178. mat = type;
  179. xp = Config.getInstance().getHerbalismXPLilyPads();
  180. }
  181. break;
  182. case COCOA:
  183. if (((data) & 0x8) == 0x8) {
  184. mat = Material.COCOA;
  185. xp = Config.getInstance().getHerbalismXPCocoa();
  186. if (Permissions.greenThumbCocoa(player)) {
  187. greenThumbWheat(block, player, event, plugin);
  188. }
  189. }
  190. break;
  191. case CARROT:
  192. if (data == CropState.RIPE.getData()) {
  193. mat = Material.CARROT;
  194. xp = Config.getInstance().getHerbalismXPCarrot();
  195. if (Permissions.greenThumbCarrots(player)) {
  196. greenThumbWheat(block, player, event, plugin);
  197. }
  198. }
  199. break;
  200. case POTATO:
  201. if (data == CropState.RIPE.getData()) {
  202. mat = Material.POTATO;
  203. xp = Config.getInstance().getHerbalismXPPotato();
  204. if (Permissions.greenThumbPotatoes(player)) {
  205. greenThumbWheat(block, player, event, plugin);
  206. }
  207. }
  208. break;
  209. default:
  210. ItemStack item = (new MaterialData(block.getTypeId(), block.getData())).toItemStack(1);
  211. if (Config.getInstance().getBlockModsEnabled() && CustomBlocksConfig.getInstance().customHerbalismBlocks.contains(item)) {
  212. customPlant = true;
  213. xp = ModChecks.getCustomBlock(block).getXpGain();
  214. }
  215. break;
  216. }
  217. if (mat == null && !customPlant) {
  218. return;
  219. }
  220. if (Permissions.herbalismDoubleDrops(player)) {
  221. ItemStack is = null;
  222. if (customPlant) {
  223. is = new ItemStack(ModChecks.getCustomBlock(block).getItemDrop());
  224. }
  225. else {
  226. if (mat == Material.COCOA) {
  227. try {
  228. is = new ItemStack(Material.INK_SACK, 1, DyeColor.BROWN.getDyeData());
  229. }
  230. catch (Exception e) {
  231. is = new ItemStack(Material.INK_SACK, 1, (short) 3);
  232. }
  233. }
  234. else if (mat == Material.CARROT) {
  235. is = new ItemStack(Material.CARROT_ITEM);
  236. }
  237. else if (mat == Material.POTATO) {
  238. is = new ItemStack(Material.POTATO_ITEM);
  239. }
  240. else {
  241. is = new ItemStack(mat);
  242. }
  243. }
  244. if (chance > Misc.getRandom().nextInt(randomChance)) {
  245. Config configInstance = Config.getInstance();
  246. switch (type) {
  247. case BROWN_MUSHROOM:
  248. if (configInstance.getBrownMushroomsDoubleDropsEnabled()) {
  249. Misc.dropItem(location, is);
  250. }
  251. break;
  252. case CACTUS:
  253. if (configInstance.getCactiDoubleDropsEnabled()) {
  254. Misc.dropItems(location, is, catciDrops);
  255. }
  256. break;
  257. case CROPS:
  258. if (configInstance.getWheatDoubleDropsEnabled()) {
  259. Misc.dropItem(location, is);
  260. }
  261. break;
  262. case MELON_BLOCK:
  263. if (configInstance.getMelonsDoubleDropsEnabled()) {
  264. Misc.dropItem(location, is);
  265. }
  266. break;
  267. case NETHER_WARTS:
  268. if (configInstance.getNetherWartsDoubleDropsEnabled()) {
  269. Misc.dropItem(location, is);
  270. }
  271. break;
  272. case PUMPKIN:
  273. if (configInstance.getPumpkinsDoubleDropsEnabled()) {
  274. Misc.dropItem(location, is);
  275. }
  276. break;
  277. case RED_MUSHROOM:
  278. if (configInstance.getRedMushroomsDoubleDropsEnabled()) {
  279. Misc.dropItem(location, is);
  280. }
  281. break;
  282. case SUGAR_CANE_BLOCK:
  283. if (configInstance.getSugarCaneDoubleDropsEnabled()) {
  284. Misc.dropItems(location, is, caneDrops);
  285. }
  286. break;
  287. case VINE:
  288. if (configInstance.getVinesDoubleDropsEnabled()) {
  289. Misc.dropItem(location, is);
  290. }
  291. break;
  292. case WATER_LILY:
  293. if (configInstance.getWaterLiliesDoubleDropsEnabled()) {
  294. Misc.dropItem(location, is);
  295. }
  296. break;
  297. case YELLOW_FLOWER:
  298. if (configInstance.getYellowFlowersDoubleDropsEnabled()) {
  299. Misc.dropItem(location, is);
  300. }
  301. break;
  302. case COCOA:
  303. if (configInstance.getCocoaDoubleDropsEnabled()) {
  304. Misc.dropItem(location, is);
  305. }
  306. break;
  307. case CARROT:
  308. if (configInstance.getCarrotDoubleDropsEnabled()) {
  309. Misc.dropItem(location, is);
  310. }
  311. break;
  312. case POTATO:
  313. if (configInstance.getPotatoDoubleDropsEnabled()) {
  314. Misc.dropItem(location, is);
  315. }
  316. break;
  317. default:
  318. if (customPlant) {
  319. CustomBlock customBlock = ModChecks.getCustomBlock(block);
  320. int minimumDropAmount = customBlock.getMinimumDropAmount();
  321. int maximumDropAmount = customBlock.getMaximumDropAmount();
  322. is = customBlock.getItemDrop();
  323. if (minimumDropAmount != maximumDropAmount) {
  324. Misc.dropItems(location, is, minimumDropAmount);
  325. Misc.randomDropItems(location, is, 50, maximumDropAmount - minimumDropAmount);
  326. }
  327. else {
  328. Misc.dropItems(location, is, minimumDropAmount);
  329. }
  330. }
  331. break;
  332. }
  333. }
  334. }
  335. if (Config.getInstance().getHerbalismAFKDisabled() && player.isInsideVehicle())
  336. return;
  337. Skills.xpProcessing(player, profile, SkillType.HERBALISM, xp);
  338. }
  339. /**
  340. * Apply the Green Thumb ability to crops.
  341. *
  342. * @param block The block to apply the ability to
  343. * @param player The player using the ability
  344. * @param event The event triggering the ability
  345. * @param plugin mcMMO plugin instance
  346. */
  347. private static void greenThumbWheat(Block block, Player player, BlockBreakEvent event, mcMMO plugin) {
  348. final int MAX_CHANCE = advancedConfig.getGreenThumbChanceMax();
  349. final int MAX_BONUS_LEVEL = advancedConfig.getGreenThumbMaxLevel();
  350. PlayerProfile profile = Users.getProfile(player);
  351. int herbLevel = profile.getSkillLevel(SkillType.HERBALISM);
  352. PlayerInventory inventory = player.getInventory();
  353. boolean hasSeeds = false;
  354. Location location = block.getLocation();
  355. Material type = block.getType();
  356. switch(type) {
  357. case CROPS:
  358. hasSeeds = inventory.contains(Material.SEEDS);
  359. break;
  360. case COCOA:
  361. // Broken: Requires an update to bukkit to enable seaching for variable-sized ItemStacks.
  362. try {
  363. hasSeeds = inventory.contains(new ItemStack(Material.INK_SACK, 1, DyeColor.BROWN.getDyeData()), 1);
  364. }
  365. catch(Exception e) {
  366. hasSeeds = inventory.contains(new ItemStack(Material.INK_SACK, 1, (short) 3), 1);
  367. }
  368. break;
  369. case CARROT:
  370. hasSeeds = inventory.contains(Material.CARROT_ITEM);
  371. break;
  372. case POTATO:
  373. hasSeeds = inventory.contains(Material.POTATO_ITEM);
  374. break;
  375. case NETHER_WARTS:
  376. hasSeeds = inventory.contains(Material.NETHER_STALK);
  377. break;
  378. default:
  379. break;
  380. }
  381. int randomChance = 100;
  382. if (Permissions.luckyHerbalism(player)) {
  383. randomChance = (int) (randomChance * 0.75);
  384. }
  385. float chance = (float) (((double) MAX_CHANCE / (double) MAX_BONUS_LEVEL) * herbLevel);
  386. if (chance > MAX_CHANCE) chance = (float) MAX_CHANCE;
  387. if (hasSeeds && profile.getAbilityMode(AbilityType.GREEN_TERRA) || hasSeeds && (chance > Misc.getRandom().nextInt(randomChance))) {
  388. event.setCancelled(true);
  389. switch(type) {
  390. case CROPS:
  391. Misc.dropItem(location, new ItemStack(Material.WHEAT));
  392. Misc.randomDropItems(location, new ItemStack(Material.SEEDS), 50, 3);
  393. inventory.removeItem(new ItemStack(Material.SEEDS));
  394. break;
  395. case COCOA:
  396. try {
  397. Misc.dropItems(location, new ItemStack(Material.INK_SACK, 1, DyeColor.BROWN.getDyeData()), 3);
  398. inventory.removeItem(new ItemStack(Material.INK_SACK, 1, DyeColor.BROWN.getDyeData()));
  399. }
  400. catch(Exception e) {
  401. Misc.dropItems(location, new ItemStack(Material.INK_SACK, 1, (short) 3), 3);
  402. inventory.removeItem(new ItemStack(Material.INK_SACK, 1, (short) 3));
  403. }
  404. break;
  405. case CARROT:
  406. Misc.dropItem(location, new ItemStack(Material.CARROT_ITEM));
  407. Misc.randomDropItems(location, new ItemStack(Material.CARROT_ITEM), 50, 3);
  408. inventory.removeItem(new ItemStack(Material.CARROT_ITEM));
  409. break;
  410. case POTATO:
  411. Misc.dropItem(location, new ItemStack(Material.POTATO_ITEM));
  412. Misc.randomDropItems(location, new ItemStack(Material.POTATO_ITEM), 50, 3);
  413. Misc.randomDropItem(location, new ItemStack(Material.POISONOUS_POTATO), 2);
  414. inventory.removeItem(new ItemStack(Material.POTATO_ITEM));
  415. break;
  416. case NETHER_WARTS:
  417. Misc.dropItems(location, new ItemStack(Material.NETHER_STALK), 2);
  418. Misc.randomDropItems(location, new ItemStack(Material.NETHER_STALK), 50, 2);
  419. inventory.removeItem(new ItemStack(Material.NETHER_STALK));
  420. break;
  421. default:
  422. break;
  423. }
  424. plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new GreenThumbTimer(block, profile, type), 1);
  425. player.updateInventory(); // Needed until replacement available
  426. }
  427. }
  428. /**
  429. * Apply the Green Thumb ability to blocks.
  430. *
  431. * @param is The item in the player's hand
  432. * @param player The player activating the ability
  433. * @param block The block being used in the ability
  434. */
  435. public static void greenThumbBlocks(ItemStack is, Player player, Block block) {
  436. final int MAX_CHANCE = advancedConfig.getGreenThumbChanceMax();
  437. final int MAX_BONUS_LEVEL = advancedConfig.getGreenThumbMaxLevel();
  438. PlayerProfile profile = Users.getProfile(player);
  439. int skillLevel = profile.getSkillLevel(SkillType.HERBALISM);
  440. int seeds = is.getAmount();
  441. player.setItemInHand(new ItemStack(Material.SEEDS, seeds - 1));
  442. int randomChance = 100;
  443. if (Permissions.luckyHerbalism(player)) {
  444. randomChance = (int) (randomChance * 0.75);
  445. }
  446. float chance = (float) (((double) MAX_CHANCE / (double) MAX_BONUS_LEVEL) * skillLevel);
  447. if (chance > MAX_CHANCE) chance = (float) MAX_CHANCE;
  448. if (chance > Misc.getRandom().nextInt(randomChance)) {
  449. greenTerraConvert(player, block);
  450. }
  451. else {
  452. player.sendMessage(LocaleLoader.getString("Herbalism.Ability.GTh.Fail"));
  453. }
  454. }
  455. }