Replace old paint bucket recursive filling.

This commit is contained in:
William Burns 2016-02-24 21:34:41 +00:00
parent 35a853a198
commit a5060e014b
1 changed files with 84 additions and 42 deletions

View File

@ -740,53 +740,95 @@ public class Draw extends SoloGame
}
@EventHandler
public void PaintBucket(PlayerInteractEvent event)
{
public void paintFill(PlayerInteractEvent e)
{
if (!IsLive())
return;
Player player = event.getPlayer();
if (!UtilGear.isMat(player.getItemInHand(), Material.IRON_HOE))
return;
Player p = e.getPlayer();
if (!_drawers.HasPlayer(player))
return;
Block block = player.getTargetBlock((HashSet<Byte>) null, 200);
if (block == null || !_canvas.contains(block))
return;
//Fill
byte color = block.getData();
Material material = block.getType();
if (color == _brushColor && material == _brushMaterial)
return;
FillRecurse(block, color, material);
for (Player other : UtilServer.getPlayers())
other.playSound(other.getLocation(), Sound.SPLASH, 0.4f, 1.5f);
}
public void FillRecurse(Block block, byte color, Material material)
{
if (block.getType() != material)
return;
if (block.getData() != color)
return;
if (!_canvas.contains(block))
return;
block.setType(_brushMaterial);
block.setData(_brushColor);
for (Block other : UtilBlock.getSurrounding(block, false))
if (!UtilGear.isMat(p.getItemInHand(), Material.IRON_HOE))
{
FillRecurse(other, color, material);
// Not the correct tool (iron hoe = paint fill).
return;
}
if (!_drawers.HasPlayer(p))
{
// Not drawing.
return;
}
// Get the target block that the player clicks on.
Block target = p.getTargetBlock((HashSet<Byte>)null, 200);
if (target == null || !_canvas.contains(target))
{
// Target block is non-existent or not in the canvas.
return;
}
// Play sound to all players.
for (Player player : UtilServer.getPlayers())
{
player.playSound(player.getLocation(), Sound.SPLASH, 0.4f, 1.5f);
}
// Save the current block info to check later if it's the same.
BlockInfo originalInfo = new BlockInfo(target.getType(), target.getData());
// List of blocks needing to be changed.
ArrayList<Block> pending = new ArrayList<>();
// Add the current target block to pending changes.
boolean targetBlock = true;
pending.add(target);
// Cycle through all pending blocks if there are any left.
pendingBlocks: while (!pending.isEmpty())
{
// Find the center block and remove it from the list sequentially.
Block center = pending.get(0);
pending.remove(0);
// Check if it's the original target block.
if (!targetBlock)
{
// It's not: make sure that it's the same as the original block info.
if (center.getType() != originalInfo.getType())
{
// Not the same block type.
continue pendingBlocks;
}
if (center.getData() != originalInfo.getData())
{
// Not the same block data/colour.
continue pendingBlocks;
}
}
else
{
// Set so that we know the next block isn't the original target.
targetBlock = false;
}
// Set the center block type and data/colour.
center.setType(_brushMaterial);
center.setData(_brushColor);
// Cycle through the surrounding blocks and see if they need filling in.
blocks: for (Block other : UtilBlock.getSurrounding(center, false))
{
if (pending.contains(other))
{
// Already awaiting a change. :+1:
continue blocks;
}
// Add it to the pending list for change later.
pending.add(other);
}
}
}