Skip to content

Commit

Permalink
Make the miner less likely to get stuck (ldtteam#5688)
Browse files Browse the repository at this point in the history
Make getWorkingNode more stable/deterministic
Add tracking and validation of rotation
Make node picking sequential until there are 10 nodes built on a level - this should do at least 2 nodes out from shaft on a new level
  • Loading branch information
Mekle001 authored Sep 1, 2020
1 parent efdace4 commit fa594f9
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,12 @@ public void setClearedShaft(final boolean clearedShaft)
@NotNull
public Node getActiveNode()
{
return activeNode == null || activeNode.getStatus() == Node.NodeStatus.COMPLETED ? levels.get(currentLevel).getRandomNode(oldNode) : activeNode;
Node calcNode = activeNode == null || activeNode.getStatus() == Node.NodeStatus.COMPLETED ? levels.get(currentLevel).getRandomNode(oldNode) : activeNode;
if (activeNode != calcNode)
{
activeNode = calcNode;
}
return activeNode;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,12 @@ else if (vectorZ == 1)
rotation = ROTATE_ONCE;
}


if(workingNode.getRot().isPresent() && workingNode.getRot().get() != rotation)
{
Log.getLogger().warn("Calculated rotation doesn't match recorded: x:" + workingNodeX + " z:" + workingNodeZ);
}

final Node parentNode = currentLevel.getNode(workingNode.getParent());
if (parentNode != null && parentNode.getStyle() != Node.NodeType.SHAFT && (parentNode.getStatus() != Node.NodeStatus.COMPLETED || !(world.getBlockState(new BlockPos(
parentNode.getX(),
Expand All @@ -698,12 +704,16 @@ else if (vectorZ == 1)
workingNode = parentNode;
workingNode.setStatus(Node.NodeStatus.AVAILABLE);
buildingMiner.setActiveNode(parentNode);
buildingMiner.markDirty();
//We need to make sure to walk back to the last valid parent
return MINER_CHECK_MINESHAFT;
}

@NotNull final BlockPos standingPosition = new BlockPos(workingNode.getParent().getX(), currentLevel.getDepth(), workingNode.getParent().getZ());
currentStandingPosition = standingPosition;
if ((workingNode.getStatus() == Node.NodeStatus.AVAILABLE || workingNode.getStatus() == Node.NodeStatus.IN_PROGRESS) && !walkToBlock(standingPosition))
{
workingNode.setRot(rotation);
return executeStructurePlacement(workingNode, standingPosition, rotation);
}
return MINER_CHECK_MINESHAFT;
Expand Down Expand Up @@ -825,6 +835,7 @@ else if (getOwnBuilding().getVectorZ() == -1)
private IAIState executeStructurePlacement(@NotNull final Node mineNode, @NotNull final BlockPos standingPosition, final int rotation)
{
mineNode.setStatus(Node.NodeStatus.IN_PROGRESS);
getOwnBuilding().markDirty();
//Preload structures
if (job.getBlueprint() == null)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.minecolonies.coremod.entity.ai.citizen.miner;

import com.minecolonies.api.util.BlockPosUtil;
import com.minecolonies.api.util.Log;
import com.minecolonies.api.util.Vec2i;
import com.minecolonies.coremod.colony.buildings.workerbuildings.BuildingMiner;
import net.minecraft.nbt.CompoundNBT;
Expand All @@ -13,6 +14,7 @@

import java.util.*;


import static com.minecolonies.coremod.entity.ai.citizen.miner.Node.NodeType.*;

/**
Expand Down Expand Up @@ -48,10 +50,9 @@ public class Level
*/
private static final int RANDOM_TYPES = 4;
/**
* Comparator to compare two nodes, for the priority queue.
* The number of nodes that need to be built near the main shaft before randomly picking the next
*/
@NotNull
private static final Comparator<Node> NODE_COMPARATOR = (Node n1, Node n2) -> rand.nextInt(100) > 50 ? 1 : -1;
private static final int MINIMUM_NODES_FOR_RANDOM = 10;
/**
* The hashMap of nodes, check for nodes with the tuple of the parent x and z.
*/
Expand All @@ -61,7 +62,7 @@ public class Level
* The queue of open Nodes. Get a new node to work on here.
*/
@NotNull
private final Queue<Node> openNodes = new PriorityQueue<>(11, NODE_COMPARATOR);
private final Queue<Node> openNodes = new ArrayDeque<>(11);

/**
* The depth of the level stored as the y coordinate.
Expand Down Expand Up @@ -194,7 +195,7 @@ public Level(@NotNull final CompoundNBT compound)
public Node getRandomNode(@Nullable final Node node)
{
Node nextNode = null;
if (node != null && rand.nextInt(RANDOM_TYPES) > 0)
if (node != null && getNumberOfBuiltNodes() > MINIMUM_NODES_FOR_RANDOM && rand.nextInt(RANDOM_TYPES) > 0)
{
nextNode = node.getRandomNextNode(this, 0);
}
Expand Down Expand Up @@ -230,6 +231,9 @@ public void closeNextNode(final int rotation, final Node node)
nodeCenterList.add(getNextNodePositionFromNodeWithRotation(tempNode, rotation, ROTATE_ONCE));
nodeCenterList.add(getNextNodePositionFromNodeWithRotation(tempNode, rotation, ROTATE_THREE_TIMES));
break;
case UNDEFINED:
Log.getLogger().error("Minecolonies node: " + node.getX() + ":" + node.getZ() +" style undefined creating children, Please tell the mod authors about this");
return;
default:
return;
}
Expand All @@ -245,8 +249,14 @@ public void closeNextNode(final int rotation, final Node node)
nodes.put(pos, tempNodeToAdd);
openNodes.add(tempNodeToAdd);
}
nodes.get(new Vec2i(tempNode.getX(), tempNode.getZ())).setStatus(Node.NodeStatus.COMPLETED);
Node I = nodes.get(new Vec2i(tempNode.getX(), tempNode.getZ()));
if(!tempNode.equals(I))
{
Log.getLogger().warn("Minecolonies node: " + node.getX() + ":" + node.getZ() + " not equal to storage during close, Please tell the mod authors about this");
}
tempNode.setStatus(Node.NodeStatus.COMPLETED);
openNodes.removeIf(tempNode::equals);

}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
import net.minecraft.util.math.MathHelper;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Objects;
import java.util.Optional;
import java.util.Random;

/**
Expand All @@ -23,6 +23,7 @@ public class Node
*/
private static final String TAG_X = "idX";
private static final String TAG_Z = "idZ";
private static final String TAG_ROT = "rotation";
private static final String TAG_STYLE = "Style";
private static final String TAG_STATUS = "Status";
private static final String TAG_PARENTX = "ParentX";
Expand All @@ -48,6 +49,11 @@ public class Node
*/
private final int z;

/**
* The rotation that was calculated and used at build time
*/
private Optional<Integer> rot = Optional.empty();

/**
* Central position of parent node.
*/
Expand Down Expand Up @@ -77,7 +83,7 @@ public Node(final int x, final int z, @Nullable final Vec2i parent)
{
this.x = x;
this.z = z;
this.style = NodeType.CROSSROAD;
this.style = NodeType.UNDEFINED;
this.status = NodeStatus.AVAILABLE;
this.parent = parent;
}
Expand Down Expand Up @@ -127,9 +133,18 @@ public static Node createFromNBT(@NotNull final CompoundNBT compound)

//Set the node status in all directions.
@NotNull final Node node = new Node(x, z, parent);
if(style == NodeType.UNDEFINED)
{
Log.getLogger().error("Minecolonies Node " + x + "," + z + " has an undefined style, please tell the mod author about this");
}
node.setStyle(style);
node.setStatus(status);

if(compound.keySet().contains(TAG_ROT))
{
node.setRot(compound.getInt(TAG_ROT));
}

return node;
}

Expand All @@ -142,6 +157,11 @@ public void write(@NotNull final CompoundNBT compound)
{
compound.putInt(TAG_X, x);
compound.putInt(TAG_Z, z);

if(rot.isPresent())
{
compound.putInt(TAG_ROT, rot.get());
}

compound.putString(TAG_STYLE, style.name());
compound.putString(TAG_STATUS, status.name());
Expand Down Expand Up @@ -367,6 +387,26 @@ public enum NodeType
//Crossroad structure
CROSSROAD,
//Bending tunnle
BEND
BEND,
//New node, undefined
UNDEFINED
}

/**
* Get rotation stored in the node as an optional, only set if actually stored.
* @return
*/
public Optional<Integer> getRot()
{
return rot;
}

/**
* Set rotation storaged in the node
* @param rot
*/
public void setRot(int rot)
{
this.rot = Optional.of(rot);
}
}

0 comments on commit fa594f9

Please sign in to comment.