mirror of
https://github.com/Minestom/Minestom.git
synced 2024-12-27 03:27:56 +01:00
Added EntityAI to facilitate AI integration with other entity types (eg FakePlayer)
This commit is contained in:
parent
137273f05f
commit
7da5550858
@ -3,6 +3,7 @@ package net.minestom.server.entity;
|
||||
import com.extollit.gaming.ai.path.HydrazinePathFinder;
|
||||
import com.extollit.gaming.ai.path.model.IPath;
|
||||
import net.minestom.server.attribute.Attributes;
|
||||
import net.minestom.server.entity.ai.EntityAI;
|
||||
import net.minestom.server.entity.ai.GoalSelector;
|
||||
import net.minestom.server.entity.ai.TargetSelector;
|
||||
import net.minestom.server.entity.pathfinding.NavigableEntity;
|
||||
@ -24,9 +25,8 @@ import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public abstract class EntityCreature extends LivingEntity implements NavigableEntity {
|
||||
public abstract class EntityCreature extends LivingEntity implements NavigableEntity, EntityAI {
|
||||
|
||||
private int removalAnimationDelay = 1000;
|
||||
|
||||
@ -82,57 +82,13 @@ public abstract class EntityCreature extends LivingEntity implements NavigableEn
|
||||
|
||||
@Override
|
||||
public void update(long time) {
|
||||
|
||||
if (getInstance() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Goal selectors
|
||||
{
|
||||
// Supplier used to get the next goal selector which should start
|
||||
// (null if not found)
|
||||
final Supplier<GoalSelector> goalSelectorSupplier = () -> {
|
||||
for (GoalSelector goalSelector : goalSelectors) {
|
||||
final boolean start = goalSelector.shouldStart();
|
||||
if (start) {
|
||||
return goalSelector;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
// true if the goal selector changed this tick
|
||||
boolean newGoalSelector = false;
|
||||
|
||||
if (currentGoalSelector == null) {
|
||||
// No goal selector, get a new one
|
||||
this.currentGoalSelector = goalSelectorSupplier.get();
|
||||
newGoalSelector = currentGoalSelector != null;
|
||||
} else {
|
||||
final boolean stop = currentGoalSelector.shouldEnd();
|
||||
if (stop) {
|
||||
// The current goal selector stopped, find a new one
|
||||
this.currentGoalSelector.end();
|
||||
this.currentGoalSelector = goalSelectorSupplier.get();
|
||||
newGoalSelector = currentGoalSelector != null;
|
||||
}
|
||||
}
|
||||
|
||||
// Start the new goal selector
|
||||
if (newGoalSelector) {
|
||||
this.currentGoalSelector.start();
|
||||
}
|
||||
|
||||
// Execute tick for the current goal selector
|
||||
if (currentGoalSelector != null) {
|
||||
currentGoalSelector.tick(time);
|
||||
}
|
||||
}
|
||||
|
||||
// AI
|
||||
aiTick(time);
|
||||
|
||||
// Path finding
|
||||
pathFindingTick(getAttributeValue(Attributes.MOVEMENT_SPEED));
|
||||
|
||||
// Fire, item pickup, ...
|
||||
super.update(time);
|
||||
}
|
||||
|
||||
@ -242,26 +198,29 @@ public abstract class EntityCreature extends LivingEntity implements NavigableEn
|
||||
this.removalAnimationDelay = removalAnimationDelay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the goal selectors of this entity.
|
||||
*
|
||||
* @return a modifiable list containing the entity goal selectors
|
||||
*/
|
||||
@NotNull
|
||||
@Override
|
||||
public List<GoalSelector> getGoalSelectors() {
|
||||
return goalSelectors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the target selectors of this entity.
|
||||
*
|
||||
* @return a modifiable list containing the entity target selectors
|
||||
*/
|
||||
@NotNull
|
||||
@Override
|
||||
public List<TargetSelector> getTargetSelectors() {
|
||||
return targetSelectors;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public GoalSelector getCurrentGoalSelector() {
|
||||
return currentGoalSelector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCurrentGoalSelector(GoalSelector currentGoalSelector) {
|
||||
this.currentGoalSelector = currentGoalSelector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the entity target.
|
||||
*
|
||||
|
102
src/main/java/net/minestom/server/entity/ai/EntityAI.java
Normal file
102
src/main/java/net/minestom/server/entity/ai/EntityAI.java
Normal file
@ -0,0 +1,102 @@
|
||||
package net.minestom.server.entity.ai;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents an entity which can contain
|
||||
* {@link GoalSelector goal selectors} and {@link TargetSelector target selectors}.
|
||||
*/
|
||||
public interface EntityAI {
|
||||
|
||||
/**
|
||||
* Gets the goal selectors of this entity.
|
||||
*
|
||||
* @return a modifiable list containing the entity goal selectors
|
||||
*/
|
||||
@NotNull
|
||||
List<GoalSelector> getGoalSelectors();
|
||||
|
||||
/**
|
||||
* Gets the target selectors of this entity.
|
||||
*
|
||||
* @return a modifiable list containing the entity target selectors
|
||||
*/
|
||||
@NotNull
|
||||
List<TargetSelector> getTargetSelectors();
|
||||
|
||||
/**
|
||||
* Gets the current entity goal selector.
|
||||
*
|
||||
* @return the current entity goal selector, null if not any
|
||||
*/
|
||||
@Nullable
|
||||
GoalSelector getCurrentGoalSelector();
|
||||
|
||||
/**
|
||||
* Changes the entity current goal selector.
|
||||
* <p>
|
||||
* Mostly unsafe since the current goal selector should normally
|
||||
* be chosen during the entity tick method.
|
||||
*
|
||||
* @param goalSelector the new entity goal selector, null to disable it
|
||||
*/
|
||||
void setCurrentGoalSelector(@Nullable GoalSelector goalSelector);
|
||||
|
||||
/**
|
||||
* Performs an AI tick, it includes finding a new {@link GoalSelector}
|
||||
* or tick the current one,
|
||||
*
|
||||
* @param time the tick time in milliseconds
|
||||
*/
|
||||
default void aiTick(long time) {
|
||||
GoalSelector currentGoalSelector = getCurrentGoalSelector();
|
||||
// true if the goal selector changed this tick
|
||||
boolean newGoalSelector = false;
|
||||
|
||||
if (currentGoalSelector == null) {
|
||||
// No goal selector, get a new one
|
||||
currentGoalSelector = findGoal();
|
||||
newGoalSelector = currentGoalSelector != null;
|
||||
} else {
|
||||
final boolean stop = currentGoalSelector.shouldEnd();
|
||||
if (stop) {
|
||||
// The current goal selector stopped, find a new one
|
||||
currentGoalSelector.end();
|
||||
currentGoalSelector = findGoal();
|
||||
newGoalSelector = currentGoalSelector != null;
|
||||
}
|
||||
}
|
||||
|
||||
// Start the new goal selector
|
||||
if (newGoalSelector) {
|
||||
setCurrentGoalSelector(currentGoalSelector);
|
||||
currentGoalSelector.start();
|
||||
}
|
||||
|
||||
// Execute tick for the current goal selector
|
||||
if (currentGoalSelector != null) {
|
||||
currentGoalSelector.tick(time);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a new {@link GoalSelector} for the entity.
|
||||
* <p>
|
||||
* Uses {@link GoalSelector#shouldStart()} and return the goal selector if true.
|
||||
*
|
||||
* @return the goal selector found, null if not any
|
||||
*/
|
||||
private GoalSelector findGoal() {
|
||||
for (GoalSelector goalSelector : getGoalSelectors()) {
|
||||
final boolean start = goalSelector.shouldStart();
|
||||
if (start) {
|
||||
return goalSelector;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -71,7 +71,7 @@ public class RedstonePlacementRule extends BlockPlacementRule {
|
||||
|
||||
// TODO power
|
||||
|
||||
final String[] properties = new String[]{
|
||||
final String[] properties = {
|
||||
"east=" + east,
|
||||
"north=" + north,
|
||||
"power=" + power,
|
||||
|
Loading…
Reference in New Issue
Block a user