diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/morph/MorphBobRoss.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/morph/MorphBobRoss.java index 8a2a18b4d..7217d82c6 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/morph/MorphBobRoss.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/morph/MorphBobRoss.java @@ -13,6 +13,7 @@ import java.util.concurrent.TimeUnit; import mineplex.core.common.util.C; import mineplex.core.common.util.LineFormat; +import mineplex.core.common.util.UtilBlock; import mineplex.core.common.util.UtilEvent; import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilText; @@ -28,6 +29,7 @@ import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.inventory.ItemStack; import com.mojang.authlib.GameProfile; @@ -49,12 +51,15 @@ public class MorphBobRoss extends MorphGadget /** The inventory slot in which the paint brush is placed */ private static final int PAINT_BRUSH_SLOT = 2; - /** Max # of blocks that can be destroyed every half second */ - private static final int DESTROY_LIMIT = 20; + /** Max # of blocks that can be destroyed every quarter second, per player */ + private static final int DESTROY_LIMIT = 4; - /** The # of minutes for which paint blocks exist */ + /** The # of seconds for which paint blocks exist */ private static final int PAINT_SECONDS = 30; + /** The # of minutes after which the code will stop trying to remove paint */ + private static final int PAINT_EXPIRE = 10; + /** Height above a player's location at which quotes are to be displayed */ private static final double QUOTE_HEIGHT = 2.25; @@ -67,12 +72,6 @@ public class MorphBobRoss extends MorphGadget /** Cooldown time for changing paint colors (milliseconds) */ private static final long COLOR_COOLDOWN = 220; - /** Cooldown key for cleaning and putting paint on the brush */ - private static final String PAINT_KEY = "Beat The Devil Out Of It"; - - /** Cooldown time for cleaning and putting paint on the brush (milliseconds) */ - private static final long PAINT_COOLDOWN = 700; - /** Cooldown key for displaying a Bob Ross quote above head */ private static final String QUOTE_KEY = "Bob Ross Quote"; @@ -88,6 +87,26 @@ public class MorphBobRoss extends MorphGadget /** Formatted name for the clean brush */ private static final String BRUSH_NAME = C.cYellow + "Clean Paintbrush"; + /** Determines the order in which colors are selected */ + private static final byte[] COLOR_ORDER = { + (byte) 1, + (byte) 14, + (byte) 11, + (byte) 10, + (byte) 2, + (byte) 6, + (byte) 12, + (byte) 4, + (byte) 5, + (byte) 13, + (byte) 9, + (byte) 15, + (byte) 7, + (byte) 8, + (byte) 0, + (byte) 3 + }; + /** Paint colors for displaying in players' hotbars */ private static final String[] PAINT_COLORS = { C.cBlackB + "Midnight Black", @@ -146,7 +165,7 @@ public class MorphBobRoss extends MorphGadget {"The only thing worse than", "yellow snow is green snow."}, {"Look around.", "Look at what we have.", "Beauty is everywhere—", "you only have to look to see it."}, {"Just go out and talk to a tree.", "Make friends with it."}, - {"How do you make a round circle with a square knife? That’s your challenge for the day."}, + {"How do you make a round circle with a square knife?", "That’s your challenge for the day."}, {"Water's like me. It's laaazy...", "Boy, it always looks for the easiest way to do things"}, {"Oooh, if you have never been to Alaska,", "go there while it is still wild."}, {"If I paint something,", "I don't want to have to explain what it is."}, @@ -177,6 +196,8 @@ public class MorphBobRoss extends MorphGadget /** Map of items in players' inventories */ private final Map _inventoryItems = new HashMap<>(); + private final Map _paintColors = new HashMap<>(); + /** Blocks that have been painted */ private final List _paintBlocks = new ArrayList<>(); @@ -188,11 +209,11 @@ public class MorphBobRoss extends MorphGadget C.cGray + "Become the creator of your own world!", C.cGray + "Leave a trail of paint behind you as you walk.", "", - C.cGreen + "Right click " + C.cWhite + "on your " + C.cYellow + "Paintbrush" + C.cWhite + " (stick) to paint", + C.cGreen + "Hold " + C.cWhite + "your " + C.cYellow + "paintbrush" + C.cWhite + " (stick) to paint.", "", - C.cGreen + "Right click " + C.cWhite + "on your " + C.cYellow + "Paint" + C.cWhite + " (dyes) to stop painting", - "", - C.cGreen + "Left click " + C.cWhite + "on your " + C.cYellow + "Paint " + C.cWhite + "to change paintbrush colors.", + C.cGreen + "Left" + C.cWhite + " and " + C.cGreen + "right click" + C.cWhite + " on your", + C.cYellow + "paintbrush" + C.cWhite + " and " + C.cYellow + "paints" + C.cWhite + " (dyes)", + C.cWhite + "to change paint colors.", "", C.cGreen + "Crouch " + C.cWhite + "to say a Bob Ross quote." }, LineFormat.LORE), -14, Material.PAINTING, (byte) 0, YearMonth.of(2017, Month.JUNE)); @@ -256,14 +277,14 @@ public class MorphBobRoss extends MorphGadget { if (Recharge.Instance.use(event.getPlayer(), COLOR_KEY, COLOR_COOLDOWN, false, false)) { - changePaintColor(event.getPlayer()); + changePaintColor(event.getPlayer(), true); } } else if (UtilEvent.isAction(event, UtilEvent.ActionType.R)) { - if (Recharge.Instance.use(event.getPlayer(), PAINT_KEY, PAINT_COOLDOWN, false, false)) + if (Recharge.Instance.use(event.getPlayer(), COLOR_KEY, COLOR_COOLDOWN, false, false)) { - togglePainting(event.getPlayer()); + changePaintColor(event.getPlayer(), false); } } } @@ -280,27 +301,35 @@ public class MorphBobRoss extends MorphGadget int limit = 0; int offset = 0; - // destroy up to 20 paint blocks that are older than a set number of minutes + // destroy paint blocks that are too old while (!_paintBlocks.isEmpty() && offset < _paintBlocks.size() && _paintBlocks.get(offset).time < System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(PAINT_SECONDS) - && limit < DESTROY_LIMIT) + && limit < DESTROY_LIMIT * getActive().size()) { - Block block = _paintBlocks.get(0).block; + Block block = _paintBlocks.get(offset).block; if (block.getType() == Material.CARPET) { - _paintBlocks.remove(0); + _paintBlocks.remove(offset); block.setType(Material.AIR); limit++; } else { - offset++; + // stop trying to remove paint after a certain amount of time + if (_paintBlocks.get(offset).time > System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(PAINT_EXPIRE)) + { + _paintBlocks.remove(offset); + } + else + { + offset++; + } } } } - else if (event.getType() == UpdateType.TICK) // do random quote displaying + else if (event.getType() == UpdateType.TICK) // do quote displaying { for (Player player : getActive()) { @@ -338,6 +367,25 @@ public class MorphBobRoss extends MorphGadget } } } + else if (event.getType() == UpdateType.FASTEST) + { + for (Player player : getActive()) + { + if (_inventoryItems.containsKey(player.getUniqueId())) + { + ItemStack item = _inventoryItems.get(player.getUniqueId()); + + if (item.getType() == Material.STICK && player.getItemInHand().equals(item)) + { + togglePainting(player); + } + else if (!player.getItemInHand().equals(item) && item.getType() != Material.STICK) + { + togglePainting(player); + } + } + } + } } /** @@ -364,12 +412,12 @@ public class MorphBobRoss extends MorphGadget } Block block = player.getLocation().getBlock(); - Material down = block.getRelative(BlockFace.DOWN).getType(); + Block down = block.getRelative(BlockFace.DOWN); boolean carpet = block.getType() == Material.CARPET; // check that there is room to paint and that the block below is solid and not more paint. - if ((block.isEmpty() || carpet) && down.isSolid() && down != Material.CARPET) + if ((block.isEmpty() || carpet) && UtilBlock.fullSolid(down) && !UtilBlock.bottomSlab(down)) { int index; PaintedBlock blk = new PaintedBlock(block); @@ -398,14 +446,28 @@ public class MorphBobRoss extends MorphGadget } /** - * Cycle the selected paint color for a player. + * Clean hash maps on player disconnect. */ - private void changePaintColor(Player player) + @EventHandler + public void onPlayerDisconnect(PlayerQuitEvent event) + { + if (isActive(event.getPlayer())) + { + UUID uuid = event.getPlayer().getUniqueId(); + _inventoryItems.remove(uuid); + _paintColors.remove(uuid); + } + } + + /** + * Cycle the selected paint color for a player. + * + * @param reverse Whether to cycle backwards through colors. + */ + private void changePaintColor(Player player, boolean reverse) { ItemStack item = _inventoryItems.remove(player.getUniqueId()); - byte data = item.getData().getData(); - data++; - if (data > 15) data = 0; + byte data = selectPaintColor(player, reverse); ItemStack newItem = ItemStackFactory.Instance.CreateStack(Material.INK_SACK, data, 1, PAINT_COLORS[data] + " " + PAINT_BRUSHES[ThreadLocalRandom.current().nextInt(0, PAINT_BRUSHES.length)]); @@ -426,12 +488,17 @@ public class MorphBobRoss extends MorphGadget ItemStack newItem; if (item.getType() == Material.STICK) { - byte data = ((byte) ThreadLocalRandom.current().nextInt(0, 16)); + byte data = selectPaintColor(player, false); newItem = ItemStackFactory.Instance.CreateStack(Material.INK_SACK, data, 1, PAINT_COLORS[data] + " " + PAINT_BRUSHES[ThreadLocalRandom.current().nextInt(0, PAINT_BRUSHES.length)]); } else { + if (_paintColors.containsKey(player.getUniqueId())) + { + _paintColors.remove(player.getUniqueId()); + } + newItem = ItemStackFactory.Instance.CreateStack(Material.STICK, (byte) 0, 1, BRUSH_NAME); } @@ -441,6 +508,51 @@ public class MorphBobRoss extends MorphGadget player.updateInventory(); } + /** + * Changes the paint color currently assigned to a player. + * If one is not assigned, a new one will be given. + * + * @param player The player to whom to assign the paint color. + * @param reverse Whether to reverse through paint colors when choosing a new one. + * + * @return the dye data value for the newly selected color. + */ + private byte selectPaintColor(Player player, boolean reverse) + { + UUID uuid = player.getUniqueId(); + + int value; + + if (!_paintColors.containsKey(uuid)) + { + value = ThreadLocalRandom.current().nextInt(0, 16); + _paintColors.put(uuid, value); + } + else + { + value = _paintColors.get(uuid); + + if (reverse) + { + if (--value < 0) + { + value = 15; + } + } + else + { + if (++value > 15) + { + value = 0; + } + } + + _paintColors.put(uuid, value); + } + + return COLOR_ORDER[value]; + } + /** * Give a paintbrush item to a player. */