in Minecraft/src/main/java/com/microsoft/Malmo/MissionHandlers/MovingTargetDecoratorImplementation.java [117:214]
public void update(World world)
{
if (this.mustWaitTurn && !this.isOurTurn) // Using the turn scheduler?
return;
if (!this.mustWaitTurn)
{
// Not using turn scheduler - using update speed
this.timeSinceLastUpdate++;
if (this.timeSinceLastUpdate < this.speedInTicks)
return;
}
this.timeSinceLastUpdate = 0;
this.isOurTurn = false; // We're taking it right now.
if (!pinchedByPlayer(world))
{
BlockPos posHead = this.path.peekFirst();
BlockPos posTail = this.path.peekLast();
// For now, only move in 2D - can make this more flexible later.
ArrayList<BlockPos> possibleMovesForward = new ArrayList<BlockPos>();
ArrayList<BlockPos> possibleMovesBackward = new ArrayList<BlockPos>();
for (int x = -1; x <= 1; x++)
{
for (int z = -1; z <= 1; z++)
{
if (z != 0 && x != 0)
continue; // No diagonal moves.
if (z == 0 && x == 0)
continue; // Don't allow no-op.
// Check this is a valid move...
BlockPos candidateHeadPos = new BlockPos(posHead.getX() + x, posHead.getY(), posHead.getZ() + z);
BlockPos candidateTailPos = new BlockPos(posTail.getX() + x, posTail.getY(), posTail.getZ() + z);
if (isValid(world, candidateHeadPos))
possibleMovesForward.add(candidateHeadPos);
if (isValid(world, candidateTailPos))
possibleMovesBackward.add(candidateTailPos);
}
}
// Choose whether to move the "head" or the "tail"
ArrayList<BlockPos> candidates = null;
boolean forwards = true;
if (possibleMovesBackward.isEmpty())
{
candidates = possibleMovesForward;
forwards = true;
}
else if (possibleMovesForward.isEmpty())
{
candidates = possibleMovesBackward;
forwards = false;
}
else
{
forwards = this.rng.nextDouble() < 0.5;
candidates = forwards ? possibleMovesForward : possibleMovesBackward;
}
if (!candidates.isEmpty())
{
BlockDrawingHelper drawContext = new BlockDrawingHelper();
drawContext.beginDrawing(world);
BlockPos newPos = candidates.get(this.rng.nextInt(candidates.size()));
if (forwards)
{
// Add the new head:
this.originalPath.addFirst(world.getBlockState(newPos));
drawContext.setBlockState(world, newPos, this.blockType);
this.path.addFirst(newPos);
// Move the tail?
if (this.path.size() > this.pathSize)
{
drawContext.setBlockState(world, posTail, new XMLBlockState(this.originalPath.removeLast()));
this.path.removeLast();
}
}
else
{
// Backwards - add the new tail:
this.originalPath.addLast(world.getBlockState(newPos));
drawContext.setBlockState(world, newPos, this.blockType);
this.path.addLast(newPos);
// Move the head?
if (this.path.size() > this.pathSize)
{
drawContext.setBlockState(world, posHead, new XMLBlockState(this.originalPath.removeFirst()));
this.path.removeFirst();
}
}
drawContext.endDrawing(world);
}
}
if (this.mustWaitTurn)
{
// Let server know we have finished.
Map<String, String> data = new HashMap<String, String>();
data.put("agentname", this.guid);
MalmoMod.network.sendToServer(new MalmoMod.MalmoMessage(MalmoMessageType.CLIENT_TURN_TAKEN, 0, data));
}
}