Fix Bob Ross morph carpets not disappearing

This commit is contained in:
Graphica 2017-06-07 23:54:03 -04:00 committed by cnr
parent 4628af6e81
commit 8138b5d241
1 changed files with 60 additions and 106 deletions

View File

@ -5,11 +5,9 @@ import java.time.YearMonth;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import mineplex.core.common.util.C;
import mineplex.core.common.util.LineFormat;
@ -21,12 +19,16 @@ import mineplex.core.hologram.Hologram;
import mineplex.core.hologram.HologramManager;
import mineplex.core.itemstack.ItemStackFactory;
import mineplex.core.recharge.Recharge;
import mineplex.core.treasure.event.TreasureFinishEvent;
import mineplex.core.treasure.event.TreasureStartEvent;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
@ -48,17 +50,14 @@ import mineplex.core.utils.UtilGameProfile;
*/
public class MorphBobRoss extends MorphGadget
{
/** Radius within which painting is not allowed near treasure chests */
private static final int TREASURE_RADIUS = 4;
/** 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 quarter second, per player */
private static final int DESTROY_LIMIT = 4;
/** 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;
/** The # of milliseconds for which paint blocks exist */
private static final long PAINT_MILLISECONDS = 30000;
/** Height above a player's location at which quotes are to be displayed */
private static final double QUOTE_HEIGHT = 2.25;
@ -196,10 +195,11 @@ public class MorphBobRoss extends MorphGadget
/** Map of items in players' inventories */
private final Map<UUID, ItemStack> _inventoryItems = new HashMap<>();
private final Map<UUID, Integer> _paintColors = new HashMap<>();
/** Colors that are being used by painting players */
private final Map<UUID, Byte> _paintColors = new HashMap<>();
/** Blocks that have been painted */
private final List<PaintedBlock> _paintBlocks = new ArrayList<>();
/** Locations at which treasure is currently being opened */
private final Map<UUID, Location> _openingTreasure = new HashMap<>();
private final HologramManager _holograms;
@ -277,6 +277,7 @@ public class MorphBobRoss extends MorphGadget
{
if (Recharge.Instance.use(event.getPlayer(), COLOR_KEY, COLOR_COOLDOWN, false, false))
{
changePaintColor(event.getPlayer(), true);
}
}
@ -284,6 +285,7 @@ public class MorphBobRoss extends MorphGadget
{
if (Recharge.Instance.use(event.getPlayer(), COLOR_KEY, COLOR_COOLDOWN, false, false))
{
changePaintColor(event.getPlayer(), false);
}
}
@ -296,40 +298,7 @@ public class MorphBobRoss extends MorphGadget
@EventHandler
public void updateEvent(UpdateEvent event)
{
if (event.getType() == UpdateType.FASTER) // do paint removal
{
int limit = 0;
int offset = 0;
// 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 * getActive().size())
{
Block block = _paintBlocks.get(offset).block;
if (block.getType() == Material.CARPET)
{
_paintBlocks.remove(offset);
block.setType(Material.AIR);
limit++;
}
else
{
// 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 quote displaying
if (event.getType() == UpdateType.TICK) // do quote displaying
{
for (Player player : getActive())
{
@ -377,10 +346,12 @@ public class MorphBobRoss extends MorphGadget
if (item.getType() == Material.STICK && player.getItemInHand().equals(item))
{
togglePainting(player);
}
else if (!player.getItemInHand().equals(item) && item.getType() != Material.STICK)
{
togglePainting(player);
}
}
@ -401,6 +372,14 @@ public class MorphBobRoss extends MorphGadget
return;
}
for (Location location : _openingTreasure.values())
{
if (location.toVector().isInSphere(event.getPlayer().getLocation().toVector(), TREASURE_RADIUS))
{
return;
}
}
// check if the player has been issued a paintbrush
if (_inventoryItems.containsKey(player.getUniqueId()))
{
@ -419,28 +398,15 @@ public class MorphBobRoss extends MorphGadget
// check that there is room to paint and that the block below is solid and not more paint.
if ((block.isEmpty() || carpet) && UtilBlock.fullSolid(down) && !UtilBlock.bottomSlab(down))
{
int index;
PaintedBlock blk = new PaintedBlock(block);
if (carpet) // if block is a carpet
{
// remove old paint if it was painted
if ((index = _paintBlocks.indexOf(blk)) != -1)
{
_paintBlocks.remove(index);
}
else // if it's non-paint carpet
// if the block is a non-paint carpet
if (carpet && !Manager.getBlockRestore().contains(block))
{
return; // don't paint
}
}
// mark block as painted
_paintBlocks.add(blk);
// actually paint block
block.setType(Material.CARPET);
block.setData((byte) (15 - item.getData().getData()));
Manager.getBlockRestore().add(block, Material.CARPET.getId(), (byte) (15 - item.getData().getData()),
block.getTypeId(), block.getData(), PAINT_MILLISECONDS);
}
}
}
@ -456,6 +422,7 @@ public class MorphBobRoss extends MorphGadget
UUID uuid = event.getPlayer().getUniqueId();
_inventoryItems.remove(uuid);
_paintColors.remove(uuid);
}
}
@ -466,6 +433,7 @@ public class MorphBobRoss extends MorphGadget
*/
private void changePaintColor(Player player, boolean reverse)
{
ItemStack item = _inventoryItems.remove(player.getUniqueId());
byte data = selectPaintColor(player, reverse);
@ -483,22 +451,27 @@ public class MorphBobRoss extends MorphGadget
*/
private void togglePainting(Player player)
{
ItemStack item = _inventoryItems.remove(player.getUniqueId());
ItemStack newItem;
if (item.getType() == Material.STICK)
{
byte data = selectPaintColor(player, false);
byte data;
if (!_paintColors.containsKey(player.getUniqueId()))
{
data = selectPaintColor(player, false);
}
else
{
data = COLOR_ORDER[_paintColors.get(player.getUniqueId())];
}
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);
}
@ -521,11 +494,11 @@ public class MorphBobRoss extends MorphGadget
{
UUID uuid = player.getUniqueId();
int value;
byte value;
if (!_paintColors.containsKey(uuid))
{
value = ThreadLocalRandom.current().nextInt(0, 16);
value = (byte) ThreadLocalRandom.current().nextInt(0, 16);
_paintColors.put(uuid, value);
}
else
@ -588,43 +561,24 @@ public class MorphBobRoss extends MorphGadget
}
/**
* Data class holding information on blocks which have been painted
* Disable painting in the area around treasure being opened.
*/
private class PaintedBlock
@EventHandler(priority = EventPriority.LOW)
public void disableOnTreasureStart(TreasureStartEvent event)
{
/** The time at which the block was painted */
long time;
/** The block which was painted */
Block block;
/**
* Construct a PaintedBlock
*
* @param block The block which has been painted.
*/
public PaintedBlock(Block block)
{
this.block = block;
this.time = System.currentTimeMillis();
_openingTreasure.put(event.getPlayer().getUniqueId(), event.getPlayer().getLocation());
Manager.getBlockRestore().restoreBlockAround(Material.CARPET, event.getPlayer().getLocation(), TREASURE_RADIUS);
}
/**
* Overrides default equals behavior to have comparisons between
* multiple {@link PaintedBlock} objects match comparisons between
* their contained {@link PaintedBlock#block} fields.
* Enable painting in the area around treasure no longer being opened.
*/
@Override
public boolean equals(Object o)
@EventHandler(priority = EventPriority.HIGH)
public void enableOnTreasureFinish(TreasureFinishEvent event)
{
if (o instanceof PaintedBlock)
if (_openingTreasure.containsKey(event.getPlayer().getUniqueId()))
{
return block.equals(((PaintedBlock) o).block);
}
else
{
return super.equals(o);
}
_openingTreasure.remove(event.getPlayer().getUniqueId());
}
}
}