2021-06-11 14:02:28 +02:00
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
2021-11-27 09:11:43 +01:00
|
|
|
From: MiniDigger <admin@benndorf.dev>
|
2021-06-11 14:02:28 +02:00
|
|
|
Date: Fri, 3 Jan 2020 16:24:46 +0100
|
|
|
|
Subject: [PATCH] Add Mob Goal API
|
|
|
|
|
|
|
|
|
|
|
|
diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/Goal.java b/src/main/java/com/destroystokyo/paper/entity/ai/Goal.java
|
|
|
|
new file mode 100644
|
|
|
|
index 0000000000000000000000000000000000000000..c57c5416c88e2070a082403ab0dda9d7f08d2a57
|
|
|
|
--- /dev/null
|
|
|
|
+++ b/src/main/java/com/destroystokyo/paper/entity/ai/Goal.java
|
|
|
|
@@ -0,0 +1,66 @@
|
|
|
|
+package com.destroystokyo.paper.entity.ai;
|
|
|
|
+
|
|
|
|
+import org.jetbrains.annotations.NotNull;
|
|
|
|
+
|
|
|
|
+import java.util.EnumSet;
|
|
|
|
+
|
|
|
|
+import org.bukkit.entity.Mob;
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Represents an AI goal of an entity
|
|
|
|
+ */
|
|
|
|
+public interface Goal<T extends Mob> {
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Checks if this goal should be activated
|
|
|
|
+ *
|
|
|
|
+ * @return if this goal should be activated
|
|
|
|
+ */
|
|
|
|
+ boolean shouldActivate();
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Checks if this goal should stay active, defaults to {@link Goal#shouldActivate()}
|
|
|
|
+ *
|
|
|
|
+ * @return if this goal should stay active
|
|
|
|
+ */
|
|
|
|
+ default boolean shouldStayActive() {
|
|
|
|
+ return shouldActivate();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Called when this goal gets activated
|
|
|
|
+ */
|
|
|
|
+ default void start() {
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Called when this goal gets stopped
|
|
|
|
+ */
|
|
|
|
+ default void stop() {
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Called each tick the goal is activated
|
|
|
|
+ */
|
|
|
|
+ default void tick() {
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * A unique key that identifies this type of goal. Plugins should use their own namespace, not the minecraft
|
|
|
|
+ * namespace. Additionally, this key also specifies to what mobs this goal can be applied to
|
|
|
|
+ *
|
|
|
|
+ * @return the goal key
|
|
|
|
+ */
|
|
|
|
+ @NotNull
|
|
|
|
+ GoalKey<T> getKey();
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Returns a list of all applicable flags for this goal.<br>
|
|
|
|
+ *
|
|
|
|
+ * This method is only called on construction.
|
|
|
|
+ *
|
|
|
|
+ * @return the subtypes.
|
|
|
|
+ */
|
|
|
|
+ @NotNull
|
|
|
|
+ EnumSet<GoalType> getTypes();
|
|
|
|
+}
|
|
|
|
diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/GoalKey.java b/src/main/java/com/destroystokyo/paper/entity/ai/GoalKey.java
|
|
|
|
new file mode 100644
|
|
|
|
index 0000000000000000000000000000000000000000..9cd98c6fcfa3eb439d9013ef76ef4661175a0e5a
|
|
|
|
--- /dev/null
|
|
|
|
+++ b/src/main/java/com/destroystokyo/paper/entity/ai/GoalKey.java
|
|
|
|
@@ -0,0 +1,64 @@
|
|
|
|
+package com.destroystokyo.paper.entity.ai;
|
|
|
|
+
|
|
|
|
+import com.google.common.base.Objects;
|
|
|
|
+
|
|
|
|
+import org.jetbrains.annotations.NotNull;
|
|
|
|
+
|
|
|
|
+import java.util.StringJoiner;
|
|
|
|
+
|
|
|
|
+import org.bukkit.NamespacedKey;
|
|
|
|
+import org.bukkit.entity.Mob;
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ *
|
|
|
|
+ * Used to identify a Goal. Consists of a {@link NamespacedKey} and the type of mob the goal can be applied to
|
|
|
|
+ *
|
|
|
|
+ * @param <T> the type of mob the goal can be applied to
|
|
|
|
+ */
|
|
|
|
+public class GoalKey<T extends Mob> {
|
|
|
|
+
|
|
|
|
+ private final Class<T> entityClass;
|
|
|
|
+ private final NamespacedKey namespacedKey;
|
|
|
|
+
|
|
|
|
+ private GoalKey(@NotNull Class<T> entityClass, @NotNull NamespacedKey namespacedKey) {
|
|
|
|
+ this.entityClass = entityClass;
|
|
|
|
+ this.namespacedKey = namespacedKey;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @NotNull
|
|
|
|
+ public Class<T> getEntityClass() {
|
|
|
|
+ return entityClass;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @NotNull
|
|
|
|
+ public NamespacedKey getNamespacedKey() {
|
|
|
|
+ return namespacedKey;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public boolean equals(Object o) {
|
|
|
|
+ if (this == o) return true;
|
|
|
|
+ if (o == null || getClass() != o.getClass()) return false;
|
|
|
|
+ GoalKey<?> goalKey = (GoalKey<?>) o;
|
|
|
|
+ return Objects.equal(entityClass, goalKey.entityClass) &&
|
|
|
|
+ Objects.equal(namespacedKey, goalKey.namespacedKey);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public int hashCode() {
|
|
|
|
+ return Objects.hashCode(entityClass, namespacedKey);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public String toString() {
|
|
|
|
+ return new StringJoiner(", ", GoalKey.class.getSimpleName() + "[", "]")
|
|
|
|
+ .add("entityClass=" + entityClass)
|
|
|
|
+ .add("namespacedKey=" + namespacedKey)
|
|
|
|
+ .toString();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @NotNull
|
|
|
|
+ public static <A extends Mob> GoalKey<A> of(@NotNull Class<A> entityClass, @NotNull NamespacedKey namespacedKey) {
|
|
|
|
+ return new GoalKey<>(entityClass, namespacedKey);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/GoalType.java b/src/main/java/com/destroystokyo/paper/entity/ai/GoalType.java
|
|
|
|
new file mode 100644
|
|
|
|
index 0000000000000000000000000000000000000000..7024c8f484d2460abf3abfe65a29771d814105ec
|
|
|
|
--- /dev/null
|
|
|
|
+++ b/src/main/java/com/destroystokyo/paper/entity/ai/GoalType.java
|
|
|
|
@@ -0,0 +1,17 @@
|
|
|
|
+package com.destroystokyo.paper.entity.ai;
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Represents the subtype of a goal. Used by minecraft to disable certain types of goals if needed.
|
|
|
|
+ */
|
|
|
|
+public enum GoalType {
|
|
|
|
+
|
|
|
|
+ MOVE,
|
|
|
|
+ LOOK,
|
|
|
|
+ JUMP,
|
|
|
|
+ TARGET,
|
|
|
|
+ /**
|
|
|
|
+ * Used to map vanilla goals, that are a behavior goal but don't have a type set...
|
|
|
|
+ */
|
|
|
|
+ UNKNOWN_BEHAVIOR,
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/MobGoals.java b/src/main/java/com/destroystokyo/paper/entity/ai/MobGoals.java
|
|
|
|
new file mode 100644
|
|
|
|
index 0000000000000000000000000000000000000000..e21f7574763dd4f13794f91bbef192ef66a8f5e9
|
|
|
|
--- /dev/null
|
|
|
|
+++ b/src/main/java/com/destroystokyo/paper/entity/ai/MobGoals.java
|
|
|
|
@@ -0,0 +1,50 @@
|
|
|
|
+package com.destroystokyo.paper.entity.ai;
|
|
|
|
+
|
|
|
|
+import org.jetbrains.annotations.NotNull;
|
|
|
|
+import org.jetbrains.annotations.Nullable;
|
|
|
|
+
|
|
|
|
+import java.util.Collection;
|
|
|
|
+
|
|
|
|
+import org.bukkit.entity.Mob;
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Represents a part of the "brain" of a mob. It tracks all tasks (running or not), allows adding and removing goals
|
|
|
|
+ */
|
|
|
|
+public interface MobGoals {
|
|
|
|
+
|
|
|
|
+ <T extends Mob> void addGoal(@NotNull T mob, int priority, @NotNull Goal<T> goal);
|
|
|
|
+
|
|
|
|
+ <T extends Mob> void removeGoal(@NotNull T mob, @NotNull Goal<T> goal);
|
|
|
|
+
|
|
|
|
+ <T extends Mob> void removeAllGoals(@NotNull T mob);
|
|
|
|
+
|
|
|
|
+ <T extends Mob> void removeAllGoals(@NotNull T mob, @NotNull GoalType type);
|
|
|
|
+
|
|
|
|
+ <T extends Mob> void removeGoal(@NotNull T mob, @NotNull GoalKey<T> key);
|
|
|
|
+
|
|
|
|
+ <T extends Mob> boolean hasGoal(@NotNull T mob, @NotNull GoalKey<T> key);
|
|
|
|
+
|
|
|
|
+ @Nullable
|
|
|
|
+ <T extends Mob> Goal<T> getGoal(@NotNull T mob, @NotNull GoalKey<T> key);
|
|
|
|
+
|
|
|
|
+ @NotNull
|
|
|
|
+ <T extends Mob> Collection<Goal<T>> getGoals(@NotNull T mob, @NotNull GoalKey<T> key);
|
|
|
|
+
|
|
|
|
+ @NotNull
|
|
|
|
+ <T extends Mob> Collection<Goal<T>> getAllGoals(@NotNull T mob);
|
|
|
|
+
|
|
|
|
+ @NotNull
|
|
|
|
+ <T extends Mob> Collection<Goal<T>> getAllGoals(@NotNull T mob, @NotNull GoalType type);
|
|
|
|
+
|
|
|
|
+ @NotNull
|
|
|
|
+ <T extends Mob> Collection<Goal<T>> getAllGoalsWithout(@NotNull T mob, @NotNull GoalType type);
|
|
|
|
+
|
|
|
|
+ @NotNull
|
|
|
|
+ <T extends Mob> Collection<Goal<T>> getRunningGoals(@NotNull T mob);
|
|
|
|
+
|
|
|
|
+ @NotNull
|
|
|
|
+ <T extends Mob> Collection<Goal<T>> getRunningGoals(@NotNull T mob, @NotNull GoalType type);
|
|
|
|
+
|
|
|
|
+ @NotNull
|
|
|
|
+ <T extends Mob> Collection<Goal<T>> getRunningGoalsWithout(@NotNull T mob, @NotNull GoalType type);
|
|
|
|
+}
|
|
|
|
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
|
2024-05-16 02:06:59 +02:00
|
|
|
index 1c30e523d08250c8a5477fe4d749b779223f069a..f2fa4c419f212ea5d7ca0aab4ead4bd44dac5947 100644
|
2021-06-11 14:02:28 +02:00
|
|
|
--- a/src/main/java/org/bukkit/Bukkit.java
|
|
|
|
+++ b/src/main/java/org/bukkit/Bukkit.java
|
2024-05-16 02:06:59 +02:00
|
|
|
@@ -2539,6 +2539,16 @@ public final class Bukkit {
|
2021-06-11 14:02:28 +02:00
|
|
|
public static boolean isStopping() {
|
|
|
|
return server.isStopping();
|
|
|
|
}
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Returns the {@link com.destroystokyo.paper.entity.ai.MobGoals} manager
|
|
|
|
+ *
|
|
|
|
+ * @return the mob goals manager
|
|
|
|
+ */
|
|
|
|
+ @NotNull
|
|
|
|
+ public static com.destroystokyo.paper.entity.ai.MobGoals getMobGoals() {
|
|
|
|
+ return server.getMobGoals();
|
|
|
|
+ }
|
|
|
|
// Paper end
|
|
|
|
|
|
|
|
@NotNull
|
|
|
|
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
|
2024-05-10 12:52:03 +02:00
|
|
|
index 1f4ebdaf9cfd14de9ff2d0cea7d110fe7630dc9a..711de014b7cf69459526e6c20c94f29ee4db11c4 100644
|
2021-06-11 14:02:28 +02:00
|
|
|
--- a/src/main/java/org/bukkit/Server.java
|
|
|
|
+++ b/src/main/java/org/bukkit/Server.java
|
2024-05-10 12:52:03 +02:00
|
|
|
@@ -2215,5 +2215,13 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
2021-06-11 14:02:28 +02:00
|
|
|
* @return true if server is in the process of being shutdown
|
|
|
|
*/
|
|
|
|
boolean isStopping();
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Returns the {@link com.destroystokyo.paper.entity.ai.MobGoals} manager
|
|
|
|
+ *
|
|
|
|
+ * @return the mob goals manager
|
|
|
|
+ */
|
|
|
|
+ @NotNull
|
|
|
|
+ com.destroystokyo.paper.entity.ai.MobGoals getMobGoals();
|
|
|
|
// Paper end
|
|
|
|
}
|