Initial pass of implementing clobbered neoforge API

This commit is contained in:
Spottedleaf
2024-08-07 05:34:01 -07:00
parent c3f31b1c90
commit 1053a51d1d
28 changed files with 710 additions and 545 deletions

View File

@@ -1,10 +1,155 @@
package ca.spottedleaf.moonrise.neoforge;
import ca.spottedleaf.moonrise.common.PlatformHooks;
import ca.spottedleaf.moonrise.common.util.CoordinateUtils;
import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkHolderManager;
import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.GenerationChunkHolder;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.EmptyBlockGetter;
import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ImposterProtoChunk;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.chunk.ProtoChunk;
import net.minecraft.world.level.entity.EntityTypeTest;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import net.neoforged.neoforge.common.CommonHooks;
import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.entity.PartEntity;
import net.neoforged.neoforge.event.EventHooks;
import net.neoforged.neoforge.event.entity.EntityJoinLevelEvent;
import net.neoforged.neoforge.event.level.ChunkDataEvent;
import net.neoforged.neoforge.event.level.ChunkEvent;
import java.util.List;
import java.util.function.Predicate;
public final class NeoForgeHooks implements PlatformHooks {
@Override
public void doSomePlatformAction() {
@Override
public int getLightEmission(final BlockState blockState, final BlockGetter world, final BlockPos pos) {
return blockState.getLightEmission(world, pos);
}
@Override
public Predicate<BlockState> maybeHasLightEmission() {
return (final BlockState state) -> {
return state.hasDynamicLightEmission() || state.getLightEmission(EmptyBlockGetter.INSTANCE, BlockPos.ZERO) != 0;
};
}
@Override
public void onExplosion(final Level world, final Explosion explosion, final List<Entity> possiblyAffecting, final double diameter) {
EventHooks.onExplosionDetonate(world, explosion, possiblyAffecting, diameter);
}
@Override
public Vec3 modifyExplosionKnockback(final Level world, final Explosion explosion, final Entity entity, final Vec3 original) {
return EventHooks.getExplosionKnockback(world, explosion, entity, original);
}
@Override
public boolean hasCurrentlyLoadingChunk() {
return true;
}
@Override
public LevelChunk getCurrentlyLoadingChunk(final GenerationChunkHolder holder) {
return holder.currentlyLoading;
}
@Override
public void setCurrentlyLoading(final GenerationChunkHolder holder, final LevelChunk levelChunk) {
holder.currentlyLoading = levelChunk;
}
@Override
public void chunkFullStatusComplete(final LevelChunk newChunk, final ProtoChunk original) {
NeoForge.EVENT_BUS.post(new ChunkEvent.Load(newChunk, !(original instanceof ImposterProtoChunk)));
}
@Override
public boolean allowAsyncTicketUpdates() {
return false;
}
@Override
public void onChunkHolderTicketChange(final ServerLevel world, final NewChunkHolder holder, final int oldLevel, final int newLevel) {
EventHooks.fireChunkTicketLevelUpdated(
world, CoordinateUtils.getChunkKey(holder.chunkX, holder.chunkZ),
oldLevel, newLevel, holder.vanillaChunkHolder
);
}
@Override
public void chunkUnloadFromWorld(final LevelChunk chunk) {
NeoForge.EVENT_BUS.post(new ChunkEvent.Unload(chunk));
}
@Override
public void chunkSyncSave(final ServerLevel world, final ChunkAccess chunk, final CompoundTag data) {
NeoForge.EVENT_BUS.post(new ChunkDataEvent.Save(chunk, world, data));
}
@Override
public void onChunkWatch(final ServerLevel world, final LevelChunk chunk, final ServerPlayer player) {
EventHooks.fireChunkWatch(player, chunk, world);
}
@Override
public void onChunkUnWatch(final ServerLevel world, final ChunkPos chunk, final ServerPlayer player) {
EventHooks.fireChunkUnWatch(player, chunk, world);
}
@Override
public void addToGetEntities(final Level world, final Entity entity, final AABB boundingBox, final Predicate<? super Entity> predicate,
final List<Entity> into) {
for (final PartEntity<?> part : world.getPartEntities()) {
if (part != entity && part.getBoundingBox().intersects(boundingBox) && (predicate == null || predicate.test(part))) {
into.add(part);
}
}
}
@Override
public <T extends Entity> void addToGetEntities(final Level world, final EntityTypeTest<Entity, T> entityTypeTest, final AABB boundingBox,
final Predicate<? super T> predicate, final List<? super T> into, final int maxCount) {
if (into.size() >= maxCount) {
// fix neoforge issue: do not add if list is already full
return;
}
for (final PartEntity<?> part : world.getPartEntities()) {
final T casted = (T)entityTypeTest.tryCast(part);
if (casted != null && casted.getBoundingBox().intersects(boundingBox) && (predicate == null || predicate.test(casted))) {
into.add(casted);
if (into.size() >= maxCount) {
break;
}
}
}
}
@Override
public void entityMove(final Entity entity, final long oldSection, final long newSection) {
CommonHooks.onEntityEnterSection(entity, oldSection, newSection);
}
@Override
public boolean screenEntity(final ServerLevel world, final Entity entity, final boolean fromDisk, final boolean event) {
if (event && NeoForge.EVENT_BUS.post(new EntityJoinLevelEvent(entity, entity.level(), fromDisk)).isCanceled()) {
return false;
}
return true;
}
}

View File

@@ -0,0 +1,29 @@
package ca.spottedleaf.moonrise.neoforge.mixin.chunk_system;
import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.entity.EntityAccess;
import net.minecraft.world.level.entity.PersistentEntitySectionManager;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(ServerLevel.class)
abstract class NeoForgeServerLevelMixin implements ChunkSystemLevel {
/**
* @reason Redirect to new entity manager
* @author Spottedleaf
*/
@Redirect(
method = "addPlayer",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;addNewEntityWithoutEvent(Lnet/minecraft/world/level/entity/EntityAccess;)Z"
)
)
private <T extends EntityAccess> boolean redirectAddPlayerEntity(final PersistentEntitySectionManager<T> instance, final T entity) {
return this.moonrise$getEntityLookup().addNewEntity((Entity)entity, false);
}
}

View File

@@ -3,7 +3,8 @@
"package": "ca.spottedleaf.moonrise.neoforge.mixin",
"mixins": [
"chunk_system.NeoForgeDistanceManagerMixin",
"chunk_system.NeoForgeMinecraftServerMixin"
"chunk_system.NeoForgeMinecraftServerMixin",
"chunk_system.NeoForgeServerLevelMixin"
],
"client": [
]