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.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import mineplex.core.common.util.C; import mineplex.core.common.util.C;
import mineplex.core.common.util.LineFormat; import mineplex.core.common.util.LineFormat;
@ -21,12 +19,16 @@ import mineplex.core.hologram.Hologram;
import mineplex.core.hologram.HologramManager; import mineplex.core.hologram.HologramManager;
import mineplex.core.itemstack.ItemStackFactory; import mineplex.core.itemstack.ItemStackFactory;
import mineplex.core.recharge.Recharge; import mineplex.core.recharge.Recharge;
import mineplex.core.treasure.event.TreasureFinishEvent;
import mineplex.core.treasure.event.TreasureStartEvent;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
@ -48,17 +50,14 @@ import mineplex.core.utils.UtilGameProfile;
*/ */
public class MorphBobRoss extends MorphGadget 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 */ /** The inventory slot in which the paint brush is placed */
private static final int PAINT_BRUSH_SLOT = 2; private static final int PAINT_BRUSH_SLOT = 2;
/** Max # of blocks that can be destroyed every quarter second, per player */ /** The # of milliseconds for which paint blocks exist */
private static final int DESTROY_LIMIT = 4; private static final long PAINT_MILLISECONDS = 30000;
/** 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 */ /** Height above a player's location at which quotes are to be displayed */
private static final double QUOTE_HEIGHT = 2.25; private static final double QUOTE_HEIGHT = 2.25;
@ -196,10 +195,11 @@ public class MorphBobRoss extends MorphGadget
/** Map of items in players' inventories */ /** Map of items in players' inventories */
private final Map<UUID, ItemStack> _inventoryItems = new HashMap<>(); 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 */ /** Locations at which treasure is currently being opened */
private final List<PaintedBlock> _paintBlocks = new ArrayList<>(); private final Map<UUID, Location> _openingTreasure = new HashMap<>();
private final HologramManager _holograms; 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)) if (Recharge.Instance.use(event.getPlayer(), COLOR_KEY, COLOR_COOLDOWN, false, false))
{ {
changePaintColor(event.getPlayer(), true); 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)) if (Recharge.Instance.use(event.getPlayer(), COLOR_KEY, COLOR_COOLDOWN, false, false))
{ {
changePaintColor(event.getPlayer(), false); changePaintColor(event.getPlayer(), false);
} }
} }
@ -296,40 +298,7 @@ public class MorphBobRoss extends MorphGadget
@EventHandler @EventHandler
public void updateEvent(UpdateEvent event) public void updateEvent(UpdateEvent event)
{ {
if (event.getType() == UpdateType.FASTER) // do paint removal if (event.getType() == UpdateType.TICK) // do quote displaying
{
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
{ {
for (Player player : getActive()) for (Player player : getActive())
{ {
@ -377,10 +346,12 @@ public class MorphBobRoss extends MorphGadget
if (item.getType() == Material.STICK && player.getItemInHand().equals(item)) if (item.getType() == Material.STICK && player.getItemInHand().equals(item))
{ {
togglePainting(player); togglePainting(player);
} }
else if (!player.getItemInHand().equals(item) && item.getType() != Material.STICK) else if (!player.getItemInHand().equals(item) && item.getType() != Material.STICK)
{ {
togglePainting(player); togglePainting(player);
} }
} }
@ -401,6 +372,14 @@ public class MorphBobRoss extends MorphGadget
return; 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 // check if the player has been issued a paintbrush
if (_inventoryItems.containsKey(player.getUniqueId())) 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. // 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)) if ((block.isEmpty() || carpet) && UtilBlock.fullSolid(down) && !UtilBlock.bottomSlab(down))
{ {
int index; // if the block is a non-paint carpet
PaintedBlock blk = new PaintedBlock(block); if (carpet && !Manager.getBlockRestore().contains(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
{ {
return; // don't paint return; // don't paint
} }
}
// mark block as painted // mark block as painted
_paintBlocks.add(blk); Manager.getBlockRestore().add(block, Material.CARPET.getId(), (byte) (15 - item.getData().getData()),
block.getTypeId(), block.getData(), PAINT_MILLISECONDS);
// actually paint block
block.setType(Material.CARPET);
block.setData((byte) (15 - item.getData().getData()));
} }
} }
} }
@ -456,6 +422,7 @@ public class MorphBobRoss extends MorphGadget
UUID uuid = event.getPlayer().getUniqueId(); UUID uuid = event.getPlayer().getUniqueId();
_inventoryItems.remove(uuid); _inventoryItems.remove(uuid);
_paintColors.remove(uuid); _paintColors.remove(uuid);
} }
} }
@ -466,6 +433,7 @@ public class MorphBobRoss extends MorphGadget
*/ */
private void changePaintColor(Player player, boolean reverse) private void changePaintColor(Player player, boolean reverse)
{ {
ItemStack item = _inventoryItems.remove(player.getUniqueId()); ItemStack item = _inventoryItems.remove(player.getUniqueId());
byte data = selectPaintColor(player, reverse); byte data = selectPaintColor(player, reverse);
@ -483,22 +451,27 @@ public class MorphBobRoss extends MorphGadget
*/ */
private void togglePainting(Player player) private void togglePainting(Player player)
{ {
ItemStack item = _inventoryItems.remove(player.getUniqueId()); ItemStack item = _inventoryItems.remove(player.getUniqueId());
ItemStack newItem; ItemStack newItem;
if (item.getType() == Material.STICK) 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, newItem = ItemStackFactory.Instance.CreateStack(Material.INK_SACK, data, 1,
PAINT_COLORS[data] + " " + PAINT_BRUSHES[ThreadLocalRandom.current().nextInt(0, PAINT_BRUSHES.length)]); PAINT_COLORS[data] + " " + PAINT_BRUSHES[ThreadLocalRandom.current().nextInt(0, PAINT_BRUSHES.length)]);
} }
else else
{ {
if (_paintColors.containsKey(player.getUniqueId()))
{
_paintColors.remove(player.getUniqueId());
}
newItem = ItemStackFactory.Instance.CreateStack(Material.STICK, (byte) 0, 1, BRUSH_NAME); newItem = ItemStackFactory.Instance.CreateStack(Material.STICK, (byte) 0, 1, BRUSH_NAME);
} }
@ -521,11 +494,11 @@ public class MorphBobRoss extends MorphGadget
{ {
UUID uuid = player.getUniqueId(); UUID uuid = player.getUniqueId();
int value; byte value;
if (!_paintColors.containsKey(uuid)) if (!_paintColors.containsKey(uuid))
{ {
value = ThreadLocalRandom.current().nextInt(0, 16); value = (byte) ThreadLocalRandom.current().nextInt(0, 16);
_paintColors.put(uuid, value); _paintColors.put(uuid, value);
} }
else 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 */ _openingTreasure.put(event.getPlayer().getUniqueId(), event.getPlayer().getLocation());
long time; Manager.getBlockRestore().restoreBlockAround(Material.CARPET, event.getPlayer().getLocation(), TREASURE_RADIUS);
/** 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();
} }
/** /**
* Overrides default equals behavior to have comparisons between * Enable painting in the area around treasure no longer being opened.
* multiple {@link PaintedBlock} objects match comparisons between
* their contained {@link PaintedBlock#block} fields.
*/ */
@Override @EventHandler(priority = EventPriority.HIGH)
public boolean equals(Object o) public void enableOnTreasureFinish(TreasureFinishEvent event)
{ {
if (o instanceof PaintedBlock) if (_openingTreasure.containsKey(event.getPlayer().getUniqueId()))
{ {
return block.equals(((PaintedBlock) o).block); _openingTreasure.remove(event.getPlayer().getUniqueId());
}
else
{
return super.equals(o);
}
} }
} }
} }