mirror of
https://github.com/PaperMC/Paper.git
synced 2025-07-31 04:02:06 -07:00
164 lines
8.6 KiB
Diff
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
|