mirror of
https://github.com/BX-Team/DivineMC.git
synced 2025-12-19 14:59:25 +00:00
395 lines
21 KiB
Diff
395 lines
21 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
|
Date: Sat, 1 Feb 2025 16:05:57 +0300
|
|
Subject: [PATCH] Optimize entity stupid brain
|
|
|
|
|
|
diff --git a/net/minecraft/world/entity/AgeableMob.java b/net/minecraft/world/entity/AgeableMob.java
|
|
index 179f4e4b9b1eb57f78bbb2f9fa34b11ea79b7a88..143a4ca51a57934bf545e031b10525dedbe9c3bd 100644
|
|
--- a/net/minecraft/world/entity/AgeableMob.java
|
|
+++ b/net/minecraft/world/entity/AgeableMob.java
|
|
@@ -121,6 +121,16 @@ public abstract class AgeableMob extends PathfinderMob {
|
|
public void onSyncedDataUpdated(EntityDataAccessor<?> key) {
|
|
if (DATA_BABY_ID.equals(key)) {
|
|
this.refreshDimensions();
|
|
+ // DivineMC start - Optimize entity stupid brain
|
|
+ if (isBaby()) {
|
|
+ org.bxteam.divinemc.util.entity.SensorHelper.enableSensor(this, net.minecraft.world.entity.ai.sensing.SensorType.NEAREST_ADULT, true);
|
|
+ } else {
|
|
+ org.bxteam.divinemc.util.entity.SensorHelper.disableSensor(this, net.minecraft.world.entity.ai.sensing.SensorType.NEAREST_ADULT);
|
|
+ if (this.getBrain().hasMemoryValue(net.minecraft.world.entity.ai.memory.MemoryModuleType.NEAREST_VISIBLE_ADULT)) {
|
|
+ this.getBrain().setMemory(net.minecraft.world.entity.ai.memory.MemoryModuleType.NEAREST_VISIBLE_ADULT, java.util.Optional.empty());
|
|
+ }
|
|
+ }
|
|
+ // DivineMC end - Optimize entity stupid brain
|
|
}
|
|
|
|
super.onSyncedDataUpdated(key);
|
|
diff --git a/net/minecraft/world/entity/ai/Brain.java b/net/minecraft/world/entity/ai/Brain.java
|
|
index 8f7efe6b2c191f615dfc8394baec44dc0761ff51..406eb049cb22d0736d8b003a2f547cc25c6f68b6 100644
|
|
--- a/net/minecraft/world/entity/ai/Brain.java
|
|
+++ b/net/minecraft/world/entity/ai/Brain.java
|
|
@@ -45,16 +45,73 @@ public class Brain<E extends LivingEntity> {
|
|
static final Logger LOGGER = LogUtils.getLogger();
|
|
private final Supplier<Codec<Brain<E>>> codec;
|
|
private static final int SCHEDULE_UPDATE_DELAY = 20;
|
|
- private final Map<MemoryModuleType<?>, Optional<? extends ExpirableValue<?>>> memories = Maps.newHashMap();
|
|
- public final Map<SensorType<? extends Sensor<? super E>>, Sensor<? super E>> sensors = Maps.newLinkedHashMap();
|
|
- private final Map<Integer, Map<Activity, Set<BehaviorControl<? super E>>>> availableBehaviorsByPriority = Maps.newTreeMap();
|
|
+ private Map<MemoryModuleType<?>, Optional<? extends ExpirableValue<?>>> memories = Maps.newConcurrentMap(); // DivineMC - concurrent map
|
|
+ public Map<SensorType<? extends Sensor<? super E>>, Sensor<? super E>> sensors = Maps.newLinkedHashMap(); // DivineMC - linked hash map
|
|
+ private final Map<Integer, Map<Activity, Set<BehaviorControl<? super E>>>> availableBehaviorsByPriority = Maps.newTreeMap(); // DivineMC - tree map
|
|
private Schedule schedule = Schedule.EMPTY;
|
|
- private final Map<Activity, Set<Pair<MemoryModuleType<?>, MemoryStatus>>> activityRequirements = Maps.newHashMap();
|
|
+ private Map<Activity, Set<Pair<MemoryModuleType<?>, MemoryStatus>>> activityRequirements = Maps.newHashMap(); // DivineMC - hash map
|
|
private final Map<Activity, Set<MemoryModuleType<?>>> activityMemoriesToEraseWhenStopped = Maps.newHashMap();
|
|
private Set<Activity> coreActivities = Sets.newHashSet();
|
|
private final Set<Activity> activeActivities = Sets.newHashSet();
|
|
private Activity defaultActivity = Activity.IDLE;
|
|
private long lastScheduleUpdate = -9999L;
|
|
+ // DivineMC start - Optimize entity stupid brain
|
|
+ private java.util.ArrayList<net.minecraft.world.entity.ai.behavior.BehaviorControl<? super E>> possibleTasks;
|
|
+ private org.bxteam.divinemc.util.collections.MaskedList<net.minecraft.world.entity.ai.behavior.BehaviorControl<? super E>> runningTasks;
|
|
+
|
|
+ private void onTasksChanged() {
|
|
+ this.runningTasks = null;
|
|
+ this.onPossibleActivitiesChanged();
|
|
+ }
|
|
+
|
|
+ private void onPossibleActivitiesChanged() {
|
|
+ this.possibleTasks = null;
|
|
+ }
|
|
+
|
|
+ private void initPossibleTasks() {
|
|
+ this.possibleTasks = new java.util.ArrayList<>();
|
|
+ for (Map<Activity, Set<BehaviorControl<? super E>>> map : this.availableBehaviorsByPriority.values()) {
|
|
+ for (Map.Entry<Activity, Set<BehaviorControl<? super E>>> entry : map.entrySet()) {
|
|
+ Activity activity = entry.getKey();
|
|
+ if (!this.activeActivities.contains(activity)) {
|
|
+ continue;
|
|
+ }
|
|
+ Set<BehaviorControl<? super E>> set = entry.getValue();
|
|
+ for (BehaviorControl<? super E> task : set) {
|
|
+ //noinspection UseBulkOperation
|
|
+ this.possibleTasks.add(task);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private java.util.ArrayList<net.minecraft.world.entity.ai.behavior.BehaviorControl<? super E>> getPossibleTasks() {
|
|
+ if (this.possibleTasks == null) {
|
|
+ this.initPossibleTasks();
|
|
+ }
|
|
+ return this.possibleTasks;
|
|
+ }
|
|
+
|
|
+ private org.bxteam.divinemc.util.collections.MaskedList<net.minecraft.world.entity.ai.behavior.BehaviorControl<? super E>> getCurrentlyRunningTasks() {
|
|
+ if (this.runningTasks == null) {
|
|
+ this.initCurrentlyRunningTasks();
|
|
+ }
|
|
+ return this.runningTasks;
|
|
+ }
|
|
+
|
|
+ private void initCurrentlyRunningTasks() {
|
|
+ org.bxteam.divinemc.util.collections.MaskedList<net.minecraft.world.entity.ai.behavior.BehaviorControl<? super E>> list = new org.bxteam.divinemc.util.collections.MaskedList<>(new ObjectArrayList<>(), false);
|
|
+
|
|
+ for (Map<Activity, Set<BehaviorControl<? super E>>> map : this.availableBehaviorsByPriority.values()) {
|
|
+ for (Set<BehaviorControl<? super E>> set : map.values()) {
|
|
+ for (BehaviorControl<? super E> task : set) {
|
|
+ list.addOrSet(task, task.getStatus() == Behavior.Status.RUNNING);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ this.runningTasks = list;
|
|
+ }
|
|
+ // DivineMC end - Optimize entity stupid brain
|
|
|
|
public static <E extends LivingEntity> Brain.Provider<E> provider(
|
|
Collection<? extends MemoryModuleType<?>> memoryTypes, Collection<? extends SensorType<? extends Sensor<? super E>>> sensorTypes
|
|
@@ -146,6 +203,12 @@ public class Brain<E extends LivingEntity> {
|
|
for (Brain.MemoryValue<?> memoryValue : memoryValues) {
|
|
memoryValue.setMemoryInternal(this);
|
|
}
|
|
+ // DivineMC start - Optimize entity stupid brain
|
|
+ this.onTasksChanged();
|
|
+ this.memories = new it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap<>(this.memories);
|
|
+ this.sensors = new it.unimi.dsi.fastutil.objects.Reference2ReferenceLinkedOpenHashMap<>(this.sensors);
|
|
+ this.activityRequirements = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(this.activityRequirements);
|
|
+ // DivineMC end - Optimize entity stupid brain
|
|
}
|
|
|
|
public <T> DataResult<T> serializeStart(DynamicOps<T> ops) {
|
|
@@ -165,6 +228,7 @@ public class Brain<E extends LivingEntity> {
|
|
}
|
|
|
|
public <U> void eraseMemory(MemoryModuleType<U> type) {
|
|
+ if (!this.memories.containsKey(type)) return; // DivineMC - skip if memory does not contain key
|
|
this.setMemory(type, Optional.empty());
|
|
}
|
|
|
|
@@ -180,16 +244,33 @@ public class Brain<E extends LivingEntity> {
|
|
this.setMemoryInternal(memoryType, memory.map(ExpirableValue::of));
|
|
}
|
|
|
|
+ // DivineMC start - Optimize entity stupid brain
|
|
<U> void setMemoryInternal(MemoryModuleType<U> memoryType, Optional<? extends ExpirableValue<?>> memory) {
|
|
+ if (memory.isPresent() && this.isEmptyCollection(memory.get().getValue())) {
|
|
+ this.eraseMemory(memoryType);
|
|
+ return;
|
|
+ }
|
|
+
|
|
if (this.memories.containsKey(memoryType)) {
|
|
- if (memory.isPresent() && this.isEmptyCollection(memory.get().getValue())) {
|
|
- this.eraseMemory(memoryType);
|
|
- } else {
|
|
- this.memories.put(memoryType, memory);
|
|
- }
|
|
+ this.increaseMemoryModificationCount(this.memories, memoryType, memory);
|
|
}
|
|
}
|
|
|
|
+ private long memoryModCount = 1;
|
|
+
|
|
+ public long getMemoryModCount() {
|
|
+ return memoryModCount;
|
|
+ }
|
|
+
|
|
+ private <T, A> Object increaseMemoryModificationCount(Map<T, A> map, T key, A newValue) {
|
|
+ Object oldValue = map.put(key, newValue);
|
|
+ if (oldValue == null || ((Optional<?>) oldValue).isPresent() != ((Optional<?>) newValue).isPresent()) {
|
|
+ this.memoryModCount++;
|
|
+ }
|
|
+ return oldValue;
|
|
+ }
|
|
+ // DivineMC end - Optimize entity stupid brain
|
|
+
|
|
public <U> Optional<U> getMemory(MemoryModuleType<U> type) {
|
|
Optional<? extends ExpirableValue<?>> optional = this.memories.get(type);
|
|
if (optional == null) {
|
|
@@ -251,19 +332,7 @@ public class Brain<E extends LivingEntity> {
|
|
@Deprecated
|
|
@VisibleForDebug
|
|
public List<BehaviorControl<? super E>> getRunningBehaviors() {
|
|
- List<BehaviorControl<? super E>> list = new ObjectArrayList<>();
|
|
-
|
|
- for (Map<Activity, Set<BehaviorControl<? super E>>> map : this.availableBehaviorsByPriority.values()) {
|
|
- for (Set<BehaviorControl<? super E>> set : map.values()) {
|
|
- for (BehaviorControl<? super E> behaviorControl : set) {
|
|
- if (behaviorControl.getStatus() == Behavior.Status.RUNNING) {
|
|
- list.add(behaviorControl);
|
|
- }
|
|
- }
|
|
- }
|
|
- }
|
|
-
|
|
- return list;
|
|
+ return this.getCurrentlyRunningTasks(); // DivineMC - Optimize entity stupid brain
|
|
}
|
|
|
|
public void useDefaultActivity() {
|
|
@@ -294,6 +363,7 @@ public class Brain<E extends LivingEntity> {
|
|
this.activeActivities.clear();
|
|
this.activeActivities.addAll(this.coreActivities);
|
|
this.activeActivities.add(activity);
|
|
+ this.onPossibleActivitiesChanged(); // DivineMC - Optimize entity stupid brain
|
|
}
|
|
}
|
|
|
|
@@ -374,11 +444,13 @@ public class Brain<E extends LivingEntity> {
|
|
.computeIfAbsent(activity, activity1 -> Sets.newLinkedHashSet())
|
|
.add((BehaviorControl<? super E>)pair.getSecond());
|
|
}
|
|
+ this.onTasksChanged(); // DivineMC - Optimize entity stupid brain
|
|
}
|
|
|
|
@VisibleForTesting
|
|
public void removeAllBehaviors() {
|
|
this.availableBehaviorsByPriority.clear();
|
|
+ this.onTasksChanged(); // DivineMC - Optimize entity stupid brain
|
|
}
|
|
|
|
public boolean isActive(Activity activity) {
|
|
@@ -395,6 +467,7 @@ public class Brain<E extends LivingEntity> {
|
|
}
|
|
}
|
|
|
|
+ brain.memoryModCount = this.memoryModCount + 1; // DivineMC - Optimize entity stupid brain
|
|
return brain;
|
|
}
|
|
|
|
@@ -429,31 +502,38 @@ public class Brain<E extends LivingEntity> {
|
|
|
|
for (BehaviorControl<? super E> behaviorControl : this.getRunningBehaviors()) {
|
|
behaviorControl.doStop(level, owner, gameTime);
|
|
+ // DivineMC start - Optimize entity stupid brain
|
|
+ if (this.runningTasks != null) {
|
|
+ this.runningTasks.setVisible(behaviorControl, false);
|
|
+ }
|
|
+ // DivineMC end - Optimize entity stupid brain
|
|
}
|
|
}
|
|
|
|
+ // DivineMC start - Optimize entity stupid brain
|
|
private void startEachNonRunningBehavior(ServerLevel level, E entity) {
|
|
- long gameTime = level.getGameTime();
|
|
-
|
|
- for (Map<Activity, Set<BehaviorControl<? super E>>> map : this.availableBehaviorsByPriority.values()) {
|
|
- for (Entry<Activity, Set<BehaviorControl<? super E>>> entry : map.entrySet()) {
|
|
- Activity activity = entry.getKey();
|
|
- if (this.activeActivities.contains(activity)) {
|
|
- for (BehaviorControl<? super E> behaviorControl : entry.getValue()) {
|
|
- if (behaviorControl.getStatus() == Behavior.Status.STOPPED) {
|
|
- behaviorControl.tryStart(level, entity, gameTime);
|
|
- }
|
|
- }
|
|
+ long startTime = level.getGameTime();
|
|
+ for (BehaviorControl<? super E> task : this.getPossibleTasks()) {
|
|
+ if (task.getStatus() == Behavior.Status.STOPPED) {
|
|
+ task.tryStart(level, entity, startTime);
|
|
+ if (this.runningTasks != null && task.getStatus() == Behavior.Status.RUNNING) {
|
|
+ this.runningTasks.setVisible(task, true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
+ // DivineMC end - Optimize entity stupid brain
|
|
|
|
private void tickEachRunningBehavior(ServerLevel level, E entity) {
|
|
long gameTime = level.getGameTime();
|
|
|
|
for (BehaviorControl<? super E> behaviorControl : this.getRunningBehaviors()) {
|
|
behaviorControl.tickOrStop(level, entity, gameTime);
|
|
+ // DivineMC start - Optimize entity stupid brain
|
|
+ if (this.runningTasks != null && behaviorControl.getStatus() != Behavior.Status.RUNNING) {
|
|
+ this.runningTasks.setVisible(behaviorControl, false);
|
|
+ }
|
|
+ // DivineMC end - Optimize entity stupid brain
|
|
}
|
|
}
|
|
|
|
diff --git a/net/minecraft/world/entity/ai/behavior/Behavior.java b/net/minecraft/world/entity/ai/behavior/Behavior.java
|
|
index 5b0cadd2544fb2a627822e645ff32fec2e9cfda9..253b9ad671cf0932bb17d468f8b91a15a86ff77a 100644
|
|
--- a/net/minecraft/world/entity/ai/behavior/Behavior.java
|
|
+++ b/net/minecraft/world/entity/ai/behavior/Behavior.java
|
|
@@ -14,6 +14,10 @@ public abstract class Behavior<E extends LivingEntity> implements BehaviorContro
|
|
private long endTimestamp;
|
|
private final int minDuration;
|
|
private final int maxDuration;
|
|
+ // DivineMC start - Optimize entity stupid brain
|
|
+ private long cachedMemoryModCount = -1;
|
|
+ private boolean cachedHasRequiredMemoryState;
|
|
+ // DivineMC end - Optimize entity stupid brain
|
|
private final String configKey; // Paper - configurable behavior tick rate and timings
|
|
|
|
public Behavior(Map<MemoryModuleType<?>, MemoryStatus> entryCondition) {
|
|
@@ -27,7 +31,7 @@ public abstract class Behavior<E extends LivingEntity> implements BehaviorContro
|
|
public Behavior(Map<MemoryModuleType<?>, MemoryStatus> entryCondition, int minDuration, int maxDuration) {
|
|
this.minDuration = minDuration;
|
|
this.maxDuration = maxDuration;
|
|
- this.entryCondition = entryCondition;
|
|
+ this.entryCondition = new it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap<>(entryCondition); // DivineMC - Optimize entity stupid brain - Use fastutil
|
|
// Paper start - configurable behavior tick rate and timings
|
|
String key = io.papermc.paper.util.MappingEnvironment.reobf() ? io.papermc.paper.util.ObfHelper.INSTANCE.deobfClassName(this.getClass().getName()) : this.getClass().getName();
|
|
int lastSeparator = key.lastIndexOf('.');
|
|
@@ -103,17 +107,26 @@ public abstract class Behavior<E extends LivingEntity> implements BehaviorContro
|
|
return this.getClass().getSimpleName();
|
|
}
|
|
|
|
- protected boolean hasRequiredMemories(E owner) {
|
|
- for (Entry<MemoryModuleType<?>, MemoryStatus> entry : this.entryCondition.entrySet()) {
|
|
- MemoryModuleType<?> memoryModuleType = entry.getKey();
|
|
- MemoryStatus memoryStatus = entry.getValue();
|
|
- if (!owner.getBrain().checkMemory(memoryModuleType, memoryStatus)) {
|
|
- return false;
|
|
+ // DivineMC start - Optimize entity stupid brain
|
|
+ public boolean hasRequiredMemories(E entity) {
|
|
+ net.minecraft.world.entity.ai.Brain<?> brain = entity.getBrain();
|
|
+ long modCount = brain.getMemoryModCount();
|
|
+ if (this.cachedMemoryModCount == modCount) {
|
|
+ return this.cachedHasRequiredMemoryState;
|
|
+ }
|
|
+ this.cachedMemoryModCount = modCount;
|
|
+
|
|
+ it.unimi.dsi.fastutil.objects.ObjectIterator<it.unimi.dsi.fastutil.objects.Reference2ObjectMap.Entry<net.minecraft.world.entity.ai.memory.MemoryModuleType<?>, net.minecraft.world.entity.ai.memory.MemoryStatus>> fastIterator = ((it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap<net.minecraft.world.entity.ai.memory.MemoryModuleType<?>, net.minecraft.world.entity.ai.memory.MemoryStatus>) this.entryCondition).reference2ObjectEntrySet().fastIterator();
|
|
+ while (fastIterator.hasNext()) {
|
|
+ it.unimi.dsi.fastutil.objects.Reference2ObjectMap.Entry<MemoryModuleType<?>, MemoryStatus> entry = fastIterator.next();
|
|
+ if (!brain.checkMemory(entry.getKey(), entry.getValue())) {
|
|
+ return this.cachedHasRequiredMemoryState = false;
|
|
}
|
|
}
|
|
|
|
- return true;
|
|
+ return this.cachedHasRequiredMemoryState = true;
|
|
}
|
|
+ // DivineMC end - Optimize entity stupid brain
|
|
|
|
public static enum Status {
|
|
STOPPED,
|
|
diff --git a/net/minecraft/world/entity/ai/behavior/LongJumpToRandomPos.java b/net/minecraft/world/entity/ai/behavior/LongJumpToRandomPos.java
|
|
index ec90ea4e66c6c38d7ad41805a16c63e006e44be4..0204fe68c97d152a7c3201620b6709a8bebefdf6 100644
|
|
--- a/net/minecraft/world/entity/ai/behavior/LongJumpToRandomPos.java
|
|
+++ b/net/minecraft/world/entity/ai/behavior/LongJumpToRandomPos.java
|
|
@@ -120,6 +120,12 @@ public class LongJumpToRandomPos<E extends Mob> extends Behavior<E> {
|
|
int x = blockPos.getX();
|
|
int y = blockPos.getY();
|
|
int z = blockPos.getZ();
|
|
+ // DivineMC start - Optimize entity stupid brain
|
|
+ if (this.maxLongJumpWidth < 128 && this.maxLongJumpHeight < 128) {
|
|
+ this.jumpCandidates = org.bxteam.divinemc.util.collections.LongJumpChoiceList.forCenter(blockPos, (byte) this.maxLongJumpWidth, (byte) this.maxLongJumpHeight);
|
|
+ return;
|
|
+ }
|
|
+ // DivineMC end - Optimize entity stupid brain
|
|
this.jumpCandidates = BlockPos.betweenClosedStream(
|
|
x - this.maxLongJumpWidth,
|
|
y - this.maxLongJumpHeight,
|
|
@@ -175,11 +181,27 @@ public class LongJumpToRandomPos<E extends Mob> extends Behavior<E> {
|
|
}
|
|
}
|
|
|
|
+ // DivineMC start - Optimize entity stupid brain
|
|
protected Optional<LongJumpToRandomPos.PossibleJump> getJumpCandidate(ServerLevel level) {
|
|
- Optional<LongJumpToRandomPos.PossibleJump> randomItem = WeightedRandom.getRandomItem(level.random, this.jumpCandidates);
|
|
- randomItem.ifPresent(this.jumpCandidates::remove);
|
|
- return randomItem;
|
|
+ Optional<LongJumpToRandomPos.PossibleJump> optional = getRandomFast(level.random, this.jumpCandidates);
|
|
+ skipRemoveIfAlreadyRemoved(optional, this.jumpCandidates::remove);
|
|
+ return optional;
|
|
+ }
|
|
+
|
|
+ private Optional<LongJumpToRandomPos.PossibleJump> getRandomFast(net.minecraft.util.RandomSource random, List<LongJumpToRandomPos.PossibleJump> pool) {
|
|
+ if (pool instanceof org.bxteam.divinemc.util.collections.LongJumpChoiceList longJumpChoiceList) {
|
|
+ return Optional.ofNullable(longJumpChoiceList.removeRandomWeightedByDistanceSq(random));
|
|
+ } else {
|
|
+ return WeightedRandom.getRandomItem(random, pool);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private void skipRemoveIfAlreadyRemoved(Optional<LongJumpToRandomPos.PossibleJump> result, java.util.function.Consumer<? super net.minecraft.world.entity.ai.behavior.LongJumpToRandomPos.PossibleJump> removeAction) {
|
|
+ if (!(this.jumpCandidates instanceof org.bxteam.divinemc.util.collections.LongJumpChoiceList)) {
|
|
+ result.ifPresent(removeAction);
|
|
+ }
|
|
}
|
|
+ // DivineMC end - Optimize entity stupid brain
|
|
|
|
private boolean isAcceptableLandingPosition(ServerLevel level, E entity, BlockPos pos) {
|
|
BlockPos blockPos = entity.blockPosition();
|
|
diff --git a/net/minecraft/world/entity/animal/goat/Goat.java b/net/minecraft/world/entity/animal/goat/Goat.java
|
|
index 6f106f10466440f8e65e04511f67d48f082d703f..15728d4fbe7a12c7a3b94a9ef88e7141b1225fa3 100644
|
|
--- a/net/minecraft/world/entity/animal/goat/Goat.java
|
|
+++ b/net/minecraft/world/entity/animal/goat/Goat.java
|
|
@@ -98,6 +98,13 @@ public class Goat extends Animal {
|
|
this.getNavigation().setCanFloat(true);
|
|
this.setPathfindingMalus(PathType.POWDER_SNOW, -1.0F);
|
|
this.setPathfindingMalus(PathType.DANGER_POWDER_SNOW, -1.0F);
|
|
+ // DivineMC start - Optimize entity stupid brain
|
|
+ if (!this.getBrain().hasMemoryValue(MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM)) {
|
|
+ org.bxteam.divinemc.util.entity.SensorHelper.disableSensor(this, SensorType.NEAREST_ITEMS);
|
|
+ } else if (net.minecraft.SharedConstants.IS_RUNNING_IN_IDE) {
|
|
+ throw new IllegalStateException("Goat Entity has a nearest visible wanted item memory module! This patch(Optimize-Brain, Goat.java changes) should probably be removed permanently!");
|
|
+ }
|
|
+ // DivineMC end - Optimize entity stupid brain
|
|
}
|
|
|
|
public ItemStack createHorn() {
|