Files
paper-mc/paper-server/patches/features/0030-Moonrise-additions-for-dynamic-hard-collision.patch
Bjarne Koll c136222eeb Moonrise compile fixes and changes
Kept in separate patch for easier revert once leaf smites me.
2025-06-03 16:58:23 +02:00

164 lines
8.6 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Bjarne Koll <git@lynxplay.dev>
Date: Tue, 3 Jun 2025 14:52:34 +0200
Subject: [PATCH] Moonrise additions for dynamic hard collision
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/entity/ChunkSystemEntity.java b/ca/spottedleaf/moonrise/patches/chunk_system/entity/ChunkSystemEntity.java
index c7da23900228aab3a5673eb5adfada5091140319..10921a7702fa9a2f69d084b55a60359e93106a3b 100644
--- a/ca/spottedleaf/moonrise/patches/chunk_system/entity/ChunkSystemEntity.java
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/entity/ChunkSystemEntity.java
@@ -3,17 +3,35 @@ package ca.spottedleaf.moonrise.patches.chunk_system.entity;
import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData;
import net.minecraft.server.level.FullChunkStatus;
import net.minecraft.world.entity.Entity;
+import net.minecraft.world.entity.animal.HappyGhast;
import net.minecraft.world.entity.monster.Shulker;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
public interface ChunkSystemEntity {
- public boolean moonrise$isHardColliding();
+ enum HardColliding {
+ NEVER,
+ ALWAYS,
+ SOMETIMES,
+ ;
+ }
+
+ default public boolean moonrise$isHardColliding() {
+ return switch (this.moonrise$hardCollisionConstant()) {
+ case ALWAYS -> true;
+ case NEVER -> false;
+ case SOMETIMES -> ((Entity)this).canBeCollidedWith(null);
+ };
+ }
+
+ public HardColliding moonrise$hardCollisionConstant();
// for mods to override
- public default boolean moonrise$isHardCollidingUncached() {
- return this instanceof Boat || this instanceof AbstractMinecart || this instanceof Shulker || ((Entity)this).canBeCollidedWith();
+ public default HardColliding moonrise$computeHardCollisionConstant() {
+ if (this instanceof Boat || this instanceof AbstractMinecart || this instanceof Shulker) return HardColliding.ALWAYS;
+ if (this instanceof HappyGhast) return HardColliding.SOMETIMES;
+ return ((Entity)this).canBeCollidedWith(null) ? HardColliding.ALWAYS : HardColliding.NEVER;
}
public FullChunkStatus moonrise$getChunkStatus();
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java
index ba20e87d2105ce53cdaf4049de2388d05fcd1b56..64182ab42eb4b9455ed3a861e54a42e6d1ebe664 100644
--- a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java
@@ -14,6 +14,7 @@ import net.minecraft.nbt.Tag;
import net.minecraft.server.level.FullChunkStatus;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.Mth;
+import net.minecraft.util.ProblemReporter;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntitySpawnReason;
import net.minecraft.world.entity.EntityType;
@@ -23,6 +24,7 @@ import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.chunk.storage.EntityStorage;
import net.minecraft.world.level.entity.Visibility;
+import net.minecraft.world.level.storage.TagValueInput;
import net.minecraft.world.phys.AABB;
import java.util.ArrayList;
import java.util.Arrays;
@@ -40,6 +42,7 @@ public final class ChunkEntitySlices {
private final EntityCollectionBySection allEntities;
private final EntityCollectionBySection hardCollidingEntities;
+ private final EntityCollectionBySection sometimesHardCollidingEntities;
private final Reference2ObjectOpenHashMap<Class<? extends Entity>, EntityCollectionBySection> entitiesByClass;
private final Reference2ObjectOpenHashMap<EntityType<?>, EntityCollectionBySection> entitiesByType;
private final EntityList entities = new EntityList();
@@ -67,6 +70,7 @@ public final class ChunkEntitySlices {
this.allEntities = new EntityCollectionBySection(this);
this.hardCollidingEntities = new EntityCollectionBySection(this);
+ this.sometimesHardCollidingEntities = new EntityCollectionBySection(this);
this.entitiesByClass = new Reference2ObjectOpenHashMap<>();
this.entitiesByType = new Reference2ObjectOpenHashMap<>();
@@ -76,7 +80,11 @@ public final class ChunkEntitySlices {
public static List<Entity> readEntities(final ServerLevel world, final CompoundTag compoundTag) {
// TODO check this and below on update for format changes
- return EntityType.loadEntitiesRecursive(compoundTag.getListOrEmpty("Entities"), world, EntitySpawnReason.LOAD).collect(ImmutableList.toImmutableList());
+ return EntityType.loadEntitiesRecursive(
+ TagValueInput.create(ProblemReporter.DISCARDING, world.registryAccess(), (List<CompoundTag>) (Object) compoundTag.getListOrEmpty("Entities")),
+ world,
+ EntitySpawnReason.LOAD
+ ).collect(ImmutableList.toImmutableList());
}
// Paper start - rewrite chunk system
@@ -117,7 +125,7 @@ public final class ChunkEntitySlices {
}
// Paper end - Entity load/save limit per chunk
CompoundTag compoundTag = new CompoundTag();
- if (entity.save(compoundTag)) {
+ if (entity.save(net.minecraft.world.level.storage.TagValueOutput.createDiscardingWithContext(compoundTag, world.registryAccess()))) {
entitiesTag.add(compoundTag);
}
}
@@ -244,8 +252,9 @@ public final class ChunkEntitySlices {
this.allEntities.addEntity(entity, sectionIndex);
- if (((ChunkSystemEntity)entity).moonrise$isHardColliding()) {
- this.hardCollidingEntities.addEntity(entity, sectionIndex);
+ switch (((ChunkSystemEntity)entity).moonrise$hardCollisionConstant()) {
+ case ALWAYS -> this.hardCollidingEntities.addEntity(entity, sectionIndex);
+ case SOMETIMES -> this.sometimesHardCollidingEntities.addEntity(entity, sectionIndex);
}
for (final Iterator<Reference2ObjectMap.Entry<Class<? extends Entity>, EntityCollectionBySection>> iterator =
@@ -278,8 +287,9 @@ public final class ChunkEntitySlices {
this.allEntities.removeEntity(entity, sectionIndex);
- if (((ChunkSystemEntity)entity).moonrise$isHardColliding()) {
- this.hardCollidingEntities.removeEntity(entity, sectionIndex);
+ switch (((ChunkSystemEntity)entity).moonrise$hardCollisionConstant()) {
+ case ALWAYS -> this.hardCollidingEntities.removeEntity(entity, sectionIndex);
+ case SOMETIMES -> this.sometimesHardCollidingEntities.removeEntity(entity, sectionIndex);
}
for (final Iterator<Reference2ObjectMap.Entry<Class<? extends Entity>, EntityCollectionBySection>> iterator =
@@ -299,6 +309,7 @@ public final class ChunkEntitySlices {
public void getHardCollidingEntities(final Entity except, final AABB box, final List<Entity> into, final Predicate<? super Entity> predicate) {
this.hardCollidingEntities.getEntities(except, box, into, predicate);
+ this.sometimesHardCollidingEntities.getEntities(except, box, into, e -> e.canBeCollidedWith(except) && (predicate == null || predicate.test(e)));
}
public void getEntities(final Entity except, final AABB box, final List<Entity> into, final Predicate<? super Entity> predicate) {
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index cb17579f2fd61e91fa4b220bff1f53f25c0fbaf1..502d83ff853a48f97ac6fbca43011e1171815271 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -383,7 +383,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
// Paper end
// Paper start - rewrite chunk system
- private final boolean isHardColliding = this.moonrise$isHardCollidingUncached();
+ private final HardColliding constantHardCollision = this.moonrise$computeHardCollisionConstant();
private net.minecraft.server.level.FullChunkStatus chunkStatus;
private ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData chunkData;
private int sectionX = Integer.MIN_VALUE;
@@ -392,8 +392,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
private boolean updatingSectionStatus;
@Override
- public final boolean moonrise$isHardColliding() {
- return this.isHardColliding;
+ public final HardColliding moonrise$hardCollisionConstant() {
+ return this.constantHardCollision;
}
@Override