Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa1632a21f | ||
|
|
5eabd83633 | ||
|
|
dd31ed6b54 | ||
|
|
36e5c571de | ||
|
|
94fc986edd | ||
|
|
53ebfb462c |
@@ -1,9 +1,6 @@
|
||||
# Nitori
|
||||
A performance mod that converts patches into mixins using the Ignite Framework for Paper/Spigot.
|
||||
|
||||
> [!CAUTION]
|
||||
> Nitori is more or less depraced to use [Leaf](https://github.com/Winds-Studio/Leaf) in it's replacement for performance orianted features.
|
||||
|
||||
## Optimizations:
|
||||
This plugin provides the following optimizations:
|
||||
- Faster Entity tracker by utilizing **Multiple Cores** this will allow larger servers to have way more entities
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
group=net.gensokyoreimagined.nitori
|
||||
version=1.5-SNAPSHOT
|
||||
version=1.6-SNAPSHOT
|
||||
description=Converting patches into mixins, for the Ignite Framework
|
||||
|
||||
org.gradle.parallel=true
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
package net.gensokyoreimagined.nitori.access;
|
||||
|
||||
public interface ITypeFilterableList {
|
||||
|
||||
Object[] getBackingArray();
|
||||
|
||||
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
package net.gensokyoreimagined.nitori.common.chunkwatching;
|
||||
|
||||
public interface PlayerClientVDTracking {
|
||||
|
||||
boolean isClientViewDistanceChanged();
|
||||
|
||||
int getClientViewDistance();
|
||||
|
||||
}
|
||||
//public interface PlayerClientVDTracking {
|
||||
//
|
||||
// boolean isClientViewDistanceChanged();
|
||||
//
|
||||
// int getClientViewDistance();
|
||||
//
|
||||
//}
|
||||
@@ -1,26 +1,26 @@
|
||||
package net.gensokyoreimagined.nitori.common.world.chunk;
|
||||
|
||||
import net.minecraft.server.level.FullChunkStatus;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class ChunkStatusTracker {
|
||||
|
||||
//Add other callback types in the future when needed
|
||||
private static final ArrayList<BiConsumer<ServerLevel, ChunkPos>> UNLOAD_CALLBACKS = new ArrayList<>();
|
||||
public static void onChunkStatusChange(ServerLevel serverWorld, ChunkPos pos, FullChunkStatus levelType) {
|
||||
boolean loaded = levelType.isOrAfter(FullChunkStatus.FULL);
|
||||
if (!loaded) {
|
||||
for (int i = 0; i < UNLOAD_CALLBACKS.size(); i++) {
|
||||
UNLOAD_CALLBACKS.get(i).accept(serverWorld, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void registerUnloadCallback(BiConsumer<ServerLevel, ChunkPos> callback) {
|
||||
UNLOAD_CALLBACKS.add(callback);
|
||||
}
|
||||
}
|
||||
//import net.minecraft.server.level.FullChunkStatus;
|
||||
//import net.minecraft.server.level.ServerLevel;
|
||||
//import net.minecraft.world.level.ChunkPos;
|
||||
//
|
||||
//import java.util.ArrayList;
|
||||
//import java.util.function.BiConsumer;
|
||||
//
|
||||
//public class ChunkStatusTracker {
|
||||
//
|
||||
// //Add other callback types in the future when needed
|
||||
// private static final ArrayList<BiConsumer<ServerLevel, ChunkPos>> UNLOAD_CALLBACKS = new ArrayList<>();
|
||||
// public static void onChunkStatusChange(ServerLevel serverWorld, ChunkPos pos, FullChunkStatus levelType) {
|
||||
// boolean loaded = levelType.isOrAfter(FullChunkStatus.FULL);
|
||||
// if (!loaded) {
|
||||
// for (int i = 0; i < UNLOAD_CALLBACKS.size(); i++) {
|
||||
// UNLOAD_CALLBACKS.get(i).accept(serverWorld, pos);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public static void registerUnloadCallback(BiConsumer<ServerLevel, ChunkPos> callback) {
|
||||
// UNLOAD_CALLBACKS.add(callback);
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,48 @@
|
||||
package net.gensokyoreimagined.nitori.common.world.listeners;
|
||||
|
||||
import net.minecraft.world.level.border.WorldBorder;
|
||||
import net.minecraft.world.level.border.BorderChangeListener;
|
||||
|
||||
public interface WorldBorderListenerOnce extends BorderChangeListener {
|
||||
|
||||
void lithium$onWorldBorderShapeChange(WorldBorder worldBorder);
|
||||
|
||||
default void onAreaReplaced(WorldBorder border) {
|
||||
this.lithium$onWorldBorderShapeChange(border);
|
||||
}
|
||||
|
||||
@Override
|
||||
default void onBorderSizeSet(WorldBorder border, double size) {
|
||||
this.lithium$onWorldBorderShapeChange(border);
|
||||
}
|
||||
|
||||
@Override
|
||||
default void onBorderSizeLerping(WorldBorder border, double fromSize, double toSize, long time) {
|
||||
this.lithium$onWorldBorderShapeChange(border);
|
||||
}
|
||||
|
||||
@Override
|
||||
default void onBorderCenterSet(WorldBorder border, double centerX, double centerZ) {
|
||||
this.lithium$onWorldBorderShapeChange(border);
|
||||
}
|
||||
|
||||
@Override
|
||||
default void onBorderSetWarningTime(WorldBorder border, int warningTime) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
default void onBorderSetWarningBlocks(WorldBorder border, int warningBlockDistance) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
default void onBorderSetDamagePerBlock(WorldBorder border, double damagePerBlock) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
default void onBorderSetDamageSafeZOne(WorldBorder border, double safeZoneRadius) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
package net.gensokyoreimagined.nitori.mixin;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.entity.EntityTickList;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Mixin(EntityTickList.class)
|
||||
public class MixinEntityTickList {
|
||||
@Unique
|
||||
private Int2ObjectLinkedOpenHashMap<Entity> nitori$entities = new Int2ObjectLinkedOpenHashMap<>();
|
||||
@Unique
|
||||
private Int2ObjectLinkedOpenHashMap<Entity> nitori$iteratorPointer = null;
|
||||
|
||||
// I've decided I hate Paper's design.
|
||||
// All of these are effectively Overwrites.
|
||||
|
||||
@Unique
|
||||
private void nitori$ensureActiveIsNotIterated() {
|
||||
if (nitori$iteratorPointer == nitori$entities) {
|
||||
// Avoid a ConcurrentModificationException by cloning the map before modifying it.
|
||||
// Side effect is that it allocates more memory to avoid blocking the main thread, but it's all pointers anyway.
|
||||
nitori$entities = nitori$entities.clone();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "add", at = @At("HEAD"), cancellable = true)
|
||||
public void add(Entity entity, CallbackInfo ci) {
|
||||
nitori$ensureActiveIsNotIterated();
|
||||
nitori$entities.put(entity.getId(), entity);
|
||||
ci.cancel();
|
||||
}
|
||||
|
||||
@Inject(method = "remove", at = @At("HEAD"), cancellable = true)
|
||||
public void remove(Entity entity, CallbackInfo ci) {
|
||||
nitori$ensureActiveIsNotIterated();
|
||||
nitori$entities.remove(entity.getId());
|
||||
ci.cancel();
|
||||
}
|
||||
|
||||
@Inject(method = "contains", at = @At("HEAD"), cancellable = true)
|
||||
public void contains(Entity entity, CallbackInfoReturnable<Boolean> ci) {
|
||||
ci.setReturnValue(nitori$entities.containsKey(entity.getId()));
|
||||
ci.cancel();
|
||||
}
|
||||
|
||||
@Inject(method = "forEach", at = @At("HEAD"), cancellable = true)
|
||||
public void forEach(Consumer<Entity> action, CallbackInfo ci) {
|
||||
if (nitori$iteratorPointer == nitori$entities) {
|
||||
nitori$entities = nitori$entities.clone(); // Avoid a ConcurrentModificationException by cloning the map before iterating over it.
|
||||
}
|
||||
|
||||
nitori$iteratorPointer = nitori$entities; // Mark the map as being iterated.
|
||||
|
||||
try {
|
||||
nitori$iteratorPointer.values().forEach(action); // Iterate over the map.
|
||||
} finally {
|
||||
nitori$iteratorPointer = null; // Mark the map as no longer being iterated.
|
||||
}
|
||||
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.alloc.chunk_random;
|
||||
|
||||
import net.gensokyoreimagined.nitori.common.world.ChunkRandomSource;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
@Mixin(Level.class)
|
||||
public class WorldMixin implements ChunkRandomSource {
|
||||
@Shadow
|
||||
protected int randValue;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void nitori$getRandomPosInChunk(int x, int y, int z, int mask, BlockPos.MutableBlockPos out) {
|
||||
this.randValue = this.randValue * 3 + 1013904223;
|
||||
int rand = this.randValue >> 2;
|
||||
out.set(x + (rand & 15), y + (rand >> 16 & mask), z + (rand >> 8 & 15));
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.collections.goals;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
|
||||
import net.minecraft.world.entity.ai.goal.GoalSelector;
|
||||
import net.minecraft.world.entity.ai.goal.WrappedGoal;
|
||||
import net.minecraft.util.profiling.ProfilerFiller;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Mixin(GoalSelector.class)
|
||||
public abstract class GoalSelectorMixin {
|
||||
|
||||
@Mutable
|
||||
@Shadow
|
||||
@Final
|
||||
private Set<WrappedGoal> availableGoals;
|
||||
|
||||
/**
|
||||
* Replace the goal set with an optimized collection type which performs better for iteration.
|
||||
*/
|
||||
@Inject(method = "<init>", at = @At("RETURN"))
|
||||
private void reinit(Supplier<ProfilerFiller> supplier, CallbackInfo ci) {
|
||||
this.availableGoals = new ObjectLinkedOpenHashSet<>(this.availableGoals);
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.entity.inactive_navigations;
|
||||
|
||||
import net.gensokyoreimagined.nitori.common.entity.NavigatingEntity;
|
||||
import net.gensokyoreimagined.nitori.common.world.ServerWorldExtended;
|
||||
import net.minecraft.world.entity.ai.navigation.PathNavigation;
|
||||
import net.minecraft.world.level.pathfinder.Path;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(PathNavigation.class)
|
||||
public abstract class EntityNavigationMixin {
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
protected Level level;
|
||||
|
||||
@Shadow
|
||||
protected Path path;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
protected Mob mob;
|
||||
|
||||
@Inject(
|
||||
method = "recomputePath",
|
||||
at = @At(
|
||||
value = "INVOKE_ASSIGN",
|
||||
target = "Lnet/minecraft/world/entity/ai/navigation/PathNavigation;createPath(Lnet/minecraft/core/BlockPos;I)Lnet/minecraft/world/level/pathfinder/Path;",
|
||||
shift = At.Shift.AFTER
|
||||
)
|
||||
)
|
||||
private void updateListeningState(CallbackInfo ci) {
|
||||
if (((NavigatingEntity) this.mob).lithium$isRegisteredToWorld()) {
|
||||
if (this.path == null) {
|
||||
((ServerWorldExtended) this.level).lithium$setNavigationInactive(this.mob);
|
||||
} else {
|
||||
((ServerWorldExtended) this.level).lithium$setNavigationActive(this.mob);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "moveTo(Lnet/minecraft/world/level/pathfinder/Path;D)Z", at = @At(value = "RETURN"))
|
||||
private void updateListeningState2(Path path, double speed, CallbackInfoReturnable<Boolean> cir) {
|
||||
if (((NavigatingEntity) this.mob).lithium$isRegisteredToWorld()) {
|
||||
if (this.path == null) {
|
||||
((ServerWorldExtended) this.level).lithium$setNavigationInactive(this.mob);
|
||||
} else {
|
||||
((ServerWorldExtended) this.level).lithium$setNavigationActive(this.mob);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "stop", at = @At(value = "RETURN"))
|
||||
private void stopListening(CallbackInfo ci) {
|
||||
if (((NavigatingEntity) this.mob).lithium$isRegisteredToWorld()) {
|
||||
((ServerWorldExtended) this.level).lithium$setNavigationInactive(this.mob);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.entity.inactive_navigations;
|
||||
|
||||
import net.gensokyoreimagined.nitori.common.entity.NavigatingEntity;
|
||||
import net.gensokyoreimagined.nitori.common.world.ServerWorldExtended;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.ai.navigation.PathNavigation;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.spongepowered.asm.mixin.Intrinsic;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(Mob.class)
|
||||
public abstract class MobEntityMixin extends Entity implements NavigatingEntity {
|
||||
private PathNavigation nitori$registeredNavigation;
|
||||
|
||||
public MobEntityMixin(EntityType<?> type, Level world) {
|
||||
super(type, world);
|
||||
}
|
||||
|
||||
@Shadow
|
||||
public abstract PathNavigation getNavigation();
|
||||
|
||||
@Override
|
||||
public boolean lithium$isRegisteredToWorld() {
|
||||
return this.nitori$registeredNavigation != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lithium$setRegisteredToWorld(PathNavigation navigation) {
|
||||
this.nitori$registeredNavigation = navigation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PathNavigation lithium$getRegisteredNavigation() {
|
||||
return this.nitori$registeredNavigation;
|
||||
}
|
||||
|
||||
@Inject(method = "startRiding", at = @At("RETURN"))
|
||||
private void onNavigationReplacement(Entity entity, boolean force, CallbackInfoReturnable<Boolean> cir) {
|
||||
this.lithium$updateNavigationRegistration();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Intrinsic
|
||||
public void stopRiding() {
|
||||
super.stopRiding();
|
||||
}
|
||||
|
||||
@SuppressWarnings({"MixinAnnotationTarget", "UnresolvedMixinReference"})
|
||||
@Inject(method = "stopRiding()V", at = @At("RETURN"))
|
||||
private void updateOnStopRiding(CallbackInfo ci) {
|
||||
this.lithium$updateNavigationRegistration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lithium$updateNavigationRegistration() {
|
||||
if (this.lithium$isRegisteredToWorld()) {
|
||||
PathNavigation navigation = this.getNavigation();
|
||||
if (this.nitori$registeredNavigation != navigation) {
|
||||
((ServerWorldExtended) this.level()).lithium$setNavigationInactive((Mob) (Object) this);
|
||||
this.nitori$registeredNavigation = navigation;
|
||||
|
||||
if (navigation.getPath() != null) {
|
||||
((ServerWorldExtended) this.level()).lithium$setNavigationActive((Mob) (Object) this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.logic.fast_bits_blockpos;
|
||||
|
||||
import net.minecraft.core.SectionPos;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
@Mixin(SectionPos.class)
|
||||
public interface ChunkSectionPosAccessor {
|
||||
@Invoker("<init>")
|
||||
public static SectionPos invokeChunkSectionPos(int i, int j, int k) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.logic.fast_bits_blockpos;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
|
||||
/**
|
||||
* Credit to PaperMC Patch #0421
|
||||
*/
|
||||
@Mixin(BlockPos.class)
|
||||
public class OptimizedBlockPosBitsMixin {
|
||||
|
||||
/**
|
||||
* @author QPCrummer
|
||||
* @reason Inline
|
||||
*/
|
||||
@Overwrite
|
||||
public static long offset(long value, int x, int y, int z) {
|
||||
return asLong((int) (value >> 38) + x, (int) ((value << 52) >> 52) + y, (int) ((value << 26) >> 38) + z);
|
||||
}
|
||||
|
||||
/**
|
||||
* @author QPCrummer
|
||||
* @reason Inline
|
||||
*/
|
||||
@Overwrite
|
||||
public static int getX(long packedPos) {
|
||||
return (int) (packedPos >> 38);
|
||||
}
|
||||
|
||||
/**
|
||||
* @author QPCrummer
|
||||
* @reason Inline
|
||||
*/
|
||||
@Overwrite
|
||||
public static int getY(long packedPos) {
|
||||
return (int) ((packedPos << 52) >> 52);
|
||||
}
|
||||
|
||||
/**
|
||||
* @author QPCrummer
|
||||
* @reason Inline
|
||||
*/
|
||||
@Overwrite
|
||||
public static int getZ(long packedPos) {
|
||||
return (int) ((packedPos << 26) >> 38);
|
||||
}
|
||||
|
||||
/**
|
||||
* @author QPCrummer
|
||||
* @reason Inline
|
||||
*/
|
||||
@Overwrite
|
||||
public static BlockPos of(long packedPos) {
|
||||
return new BlockPos((int) (packedPos >> 38), (int) ((packedPos << 52) >> 52), (int) ((packedPos << 26) >> 38));
|
||||
}
|
||||
|
||||
/**
|
||||
* @author QPCrummer
|
||||
* @reason Inline
|
||||
*/
|
||||
@Overwrite
|
||||
public static long asLong(int x, int y, int z) {
|
||||
return (((long) x & (long) 67108863) << 38) | (((long) y & (long) 4095)) | (((long) z & (long) 67108863) << 12);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.math.fast_blockops;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
|
||||
|
||||
@Mixin(BlockPos.class)
|
||||
public abstract class BlockPosMixin extends Vec3i {
|
||||
|
||||
public BlockPosMixin(int x, int y, int z) {
|
||||
super(x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* @author JellySquid
|
||||
* @reason Simplify and inline
|
||||
*/
|
||||
@Override
|
||||
@Overwrite
|
||||
public BlockPos above() {
|
||||
return new BlockPos(this.getX(), this.getY() + 1, this.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* @author JellySquid
|
||||
* @reason Simplify and inline
|
||||
*/
|
||||
@Override
|
||||
@Overwrite
|
||||
public BlockPos above(int distance) {
|
||||
return new BlockPos(this.getX(), this.getY() + distance, this.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* @author JellySquid
|
||||
* @reason Simplify and inline
|
||||
*/
|
||||
@Override
|
||||
@Overwrite
|
||||
public BlockPos below() {
|
||||
return new BlockPos(this.getX(), this.getY() - 1, this.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* @author JellySquid
|
||||
* @reason Simplify and inline
|
||||
*/
|
||||
@Override
|
||||
@Overwrite
|
||||
public BlockPos below(int distance) {
|
||||
return new BlockPos(this.getX(), this.getY() - distance, this.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* @author JellySquid
|
||||
* @reason Simplify and inline
|
||||
*/
|
||||
@Overwrite
|
||||
public BlockPos north() {
|
||||
return new BlockPos(this.getX(), this.getY(), this.getZ() - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @author JellySquid
|
||||
* @reason Simplify and inline
|
||||
*/
|
||||
@Overwrite
|
||||
public BlockPos north(int distance) {
|
||||
return new BlockPos(this.getX(), this.getY(), this.getZ() - distance);
|
||||
}
|
||||
|
||||
/**
|
||||
* @author JellySquid
|
||||
* @reason Simplify and inline
|
||||
*/
|
||||
@Overwrite
|
||||
public BlockPos south() {
|
||||
return new BlockPos(this.getX(), this.getY(), this.getZ() + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @author JellySquid
|
||||
* @reason Simplify and inline
|
||||
*/
|
||||
@Overwrite
|
||||
public BlockPos south(int distance) {
|
||||
return new BlockPos(this.getX(), this.getY(), this.getZ() + distance);
|
||||
}
|
||||
|
||||
/**
|
||||
* @author JellySquid
|
||||
* @reason Simplify and inline
|
||||
*/
|
||||
@Overwrite
|
||||
public BlockPos west() {
|
||||
return new BlockPos(this.getX() - 1, this.getY(), this.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* @author JellySquid
|
||||
* @reason Simplify and inline
|
||||
*/
|
||||
@Overwrite
|
||||
public BlockPos west(int distance) {
|
||||
return new BlockPos(this.getX() - distance, this.getY(), this.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* @author JellySquid
|
||||
* @reason Simplify and inline
|
||||
*/
|
||||
@Overwrite
|
||||
public BlockPos east() {
|
||||
return new BlockPos(this.getX() + 1, this.getY(), this.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* @author JellySquid
|
||||
* @reason Simplify and inline
|
||||
*/
|
||||
@Overwrite
|
||||
public BlockPos east(int distance) {
|
||||
return new BlockPos(this.getX() + distance, this.getY(), this.getZ());
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.math.fast_blockops;
|
||||
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
/**
|
||||
* The vector of each Direction is usually stored inside another object, which introduces indirection and makes things
|
||||
* harder for the JVM to optimize. This patch simply hoists the offset fields to the Direction enum itself.
|
||||
*/
|
||||
@Mixin(Direction.class)
|
||||
public class DirectionMixin {
|
||||
@Unique
|
||||
private int nitori$getStepX, nitori$getStepY, nitori$getStepZ;
|
||||
|
||||
@Inject(method = "<init>", at = @At("RETURN"))
|
||||
private void reinit(String enumName, int ordinal, int id, int idOpposite, int idHorizontal, String name, Direction.AxisDirection direction, Direction.Axis axis, Vec3i vector, CallbackInfo ci) {
|
||||
this.nitori$getStepX = vector.getX();
|
||||
this.nitori$getStepY = vector.getY();
|
||||
this.nitori$getStepZ = vector.getZ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @reason Avoid indirection to aid inlining
|
||||
* @author JellySquid
|
||||
*/
|
||||
@Overwrite
|
||||
public int getStepX() {
|
||||
return this.nitori$getStepX;
|
||||
}
|
||||
|
||||
/**
|
||||
* @reason Avoid indirection to aid inlining
|
||||
* @author JellySquid
|
||||
*/
|
||||
@Overwrite
|
||||
public int getStepY() {
|
||||
return this.nitori$getStepY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @reason Avoid indirection to aid inlining
|
||||
* @author JellySquid
|
||||
*/
|
||||
@Overwrite
|
||||
public int getStepZ() {
|
||||
return this.nitori$getStepZ;
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.math.random;
|
||||
|
||||
import net.gensokyoreimagined.nitori.common.math.random.RandomGeneratorRandom;
|
||||
import io.netty.util.internal.ThreadLocalRandom;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.levelgen.RandomSupport;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(RandomSource.class)
|
||||
public interface RandomMixin {
|
||||
@Inject(method = "create(J)Lnet/minecraft/util/RandomSource;", at = @At(value = "HEAD"), cancellable = true)
|
||||
private static void fasterrandom$createInject(long seed, @NotNull CallbackInfoReturnable<RandomSource> cir) {
|
||||
cir.setReturnValue(new RandomGeneratorRandom(seed));
|
||||
}
|
||||
|
||||
@Inject(method = "createNewThreadLocalInstance", at = @At(value = "HEAD"), cancellable = true)
|
||||
private static void fasterrandom$createLocalInject(@NotNull CallbackInfoReturnable<RandomSource> cir) {
|
||||
cir.setReturnValue(new RandomGeneratorRandom(ThreadLocalRandom.current().nextLong()));
|
||||
}
|
||||
|
||||
@Inject(method = "createThreadSafe", at = @At(value = "HEAD"), cancellable = true)
|
||||
private static void fasterrandom$createThreadSafeInject(@NotNull CallbackInfoReturnable<RandomSource> cir) {
|
||||
cir.setReturnValue(new RandomGeneratorRandom(RandomSupport.generateUniqueSeed()));
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.vmp.entity.move_zero_velocity;
|
||||
package net.gensokyoreimagined.nitori.mixin.network.move_zero_velocity;
|
||||
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.MoverType;
|
||||
@@ -0,0 +1,70 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.removed;
|
||||
|
||||
//import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap;
|
||||
//import net.minecraft.world.entity.Entity;
|
||||
//import net.minecraft.world.level.entity.EntityTickList;
|
||||
//import org.spongepowered.asm.mixin.Mixin;
|
||||
//import org.spongepowered.asm.mixin.Unique;
|
||||
//import org.spongepowered.asm.mixin.injection.At;
|
||||
//import org.spongepowered.asm.mixin.injection.Inject;
|
||||
//import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
//import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
//
|
||||
//import java.util.function.Consumer;
|
||||
//
|
||||
//@Mixin(EntityTickList.class)
|
||||
//public class MixinEntityTickList {
|
||||
// @Unique
|
||||
// private Int2ObjectLinkedOpenHashMap<Entity> nitori$entities = new Int2ObjectLinkedOpenHashMap<>();
|
||||
// @Unique
|
||||
// private Int2ObjectLinkedOpenHashMap<Entity> nitori$iteratorPointer = null;
|
||||
//
|
||||
// // I've decided I hate Paper's design.
|
||||
// // All of these are effectively Overwrites.
|
||||
//
|
||||
// @Unique
|
||||
// private void nitori$ensureActiveIsNotIterated() {
|
||||
// if (nitori$iteratorPointer == nitori$entities) {
|
||||
// // Avoid a ConcurrentModificationException by cloning the map before modifying it.
|
||||
// // Side effect is that it allocates more memory to avoid blocking the main thread, but it's all pointers anyway.
|
||||
// nitori$entities = nitori$entities.clone();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Inject(method = "add", at = @At("HEAD"), cancellable = true)
|
||||
// public void add(Entity entity, CallbackInfo ci) {
|
||||
// nitori$ensureActiveIsNotIterated();
|
||||
// nitori$entities.put(entity.getId(), entity);
|
||||
// ci.cancel();
|
||||
// }
|
||||
//
|
||||
// @Inject(method = "remove", at = @At("HEAD"), cancellable = true)
|
||||
// public void remove(Entity entity, CallbackInfo ci) {
|
||||
// nitori$ensureActiveIsNotIterated();
|
||||
// nitori$entities.remove(entity.getId());
|
||||
// ci.cancel();
|
||||
// }
|
||||
//
|
||||
// @Inject(method = "contains", at = @At("HEAD"), cancellable = true)
|
||||
// public void contains(Entity entity, CallbackInfoReturnable<Boolean> ci) {
|
||||
// ci.setReturnValue(nitori$entities.containsKey(entity.getId()));
|
||||
// ci.cancel();
|
||||
// }
|
||||
//
|
||||
// @Inject(method = "forEach", at = @At("HEAD"), cancellable = true)
|
||||
// public void forEach(Consumer<Entity> action, CallbackInfo ci) {
|
||||
// if (nitori$iteratorPointer == nitori$entities) {
|
||||
// nitori$entities = nitori$entities.clone(); // Avoid a ConcurrentModificationException by cloning the map before iterating over it.
|
||||
// }
|
||||
//
|
||||
// nitori$iteratorPointer = nitori$entities; // Mark the map as being iterated.
|
||||
//
|
||||
// try {
|
||||
// nitori$iteratorPointer.values().forEach(action); // Iterate over the map.
|
||||
// } finally {
|
||||
// nitori$iteratorPointer = null; // Mark the map as no longer being iterated.
|
||||
// }
|
||||
//
|
||||
// ci.cancel();
|
||||
// }
|
||||
//}
|
||||
@@ -12,7 +12,7 @@
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
package net.gensokyoreimagined.nitori.access;
|
||||
package net.gensokyoreimagined.nitori.mixin.removed.access;
|
||||
|
||||
//import ca.spottedleaf.moonrise.common.list.EntityList;
|
||||
//
|
||||
@@ -12,7 +12,7 @@
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
package net.gensokyoreimagined.nitori.access;
|
||||
package net.gensokyoreimagined.nitori.mixin.removed.access;
|
||||
|
||||
//public interface IMixinIteratorSafeOrderedReferenceSetAccess {
|
||||
// @SuppressWarnings("EmptyMethod")
|
||||
@@ -0,0 +1,8 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.removed.access;
|
||||
|
||||
//public interface ITypeFilterableList {
|
||||
//
|
||||
// Object[] getBackingArray();
|
||||
//
|
||||
//
|
||||
//}
|
||||
@@ -1,4 +1,4 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.unapplied.alloc.chunk_random;
|
||||
package net.gensokyoreimagined.nitori.mixin.removed.alloc.chunk_random;
|
||||
|
||||
//import net.gensokyoreimagined.nitori.common.world.ChunkRandomSource;
|
||||
//import net.minecraft.world.level.block.state.BlockState;
|
||||
@@ -0,0 +1,23 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.removed.alloc.chunk_random;
|
||||
|
||||
//import net.gensokyoreimagined.nitori.common.world.ChunkRandomSource;
|
||||
//import net.minecraft.core.BlockPos;
|
||||
//import net.minecraft.world.level.Level;
|
||||
//import org.spongepowered.asm.mixin.Mixin;
|
||||
//import org.spongepowered.asm.mixin.Shadow;
|
||||
//
|
||||
//@Mixin(Level.class)
|
||||
//public class WorldMixin implements ChunkRandomSource {
|
||||
// @Shadow
|
||||
// protected int randValue;
|
||||
//
|
||||
// /**
|
||||
// * {@inheritDoc}
|
||||
// */
|
||||
// @Override
|
||||
// public void nitori$getRandomPosInChunk(int x, int y, int z, int mask, BlockPos.MutableBlockPos out) {
|
||||
// this.randValue = this.randValue * 3 + 1013904223;
|
||||
// int rand = this.randValue >> 2;
|
||||
// out.set(x + (rand & 15), y + (rand >> 16 & mask), z + (rand >> 8 & 15));
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,33 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.removed.collections.goals;
|
||||
|
||||
//import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
|
||||
//import net.minecraft.world.entity.ai.goal.GoalSelector;
|
||||
//import net.minecraft.world.entity.ai.goal.WrappedGoal;
|
||||
//import net.minecraft.util.profiling.ProfilerFiller;
|
||||
//import org.spongepowered.asm.mixin.Final;
|
||||
//import org.spongepowered.asm.mixin.Mixin;
|
||||
//import org.spongepowered.asm.mixin.Mutable;
|
||||
//import org.spongepowered.asm.mixin.Shadow;
|
||||
//import org.spongepowered.asm.mixin.injection.At;
|
||||
//import org.spongepowered.asm.mixin.injection.Inject;
|
||||
//import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
//
|
||||
//import java.util.Set;
|
||||
//import java.util.function.Supplier;
|
||||
//
|
||||
//@Mixin(GoalSelector.class)
|
||||
//public abstract class GoalSelectorMixin {
|
||||
//
|
||||
// @Mutable
|
||||
// @Shadow
|
||||
// @Final
|
||||
// private Set<WrappedGoal> availableGoals;
|
||||
//
|
||||
// /**
|
||||
// * Replace the goal set with an optimized collection type which performs better for iteration.
|
||||
// */
|
||||
// @Inject(method = "<init>", at = @At("RETURN"))
|
||||
// private void reinit(Supplier<ProfilerFiller> supplier, CallbackInfo ci) {
|
||||
// this.availableGoals = new ObjectLinkedOpenHashSet<>(this.availableGoals);
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,66 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.removed.entity.inactive_navigations;
|
||||
|
||||
//import net.gensokyoreimagined.nitori.common.entity.NavigatingEntity;
|
||||
//import net.gensokyoreimagined.nitori.common.world.ServerWorldExtended;
|
||||
//import net.minecraft.world.entity.ai.navigation.PathNavigation;
|
||||
//import net.minecraft.world.level.pathfinder.Path;
|
||||
//import net.minecraft.world.entity.Mob;
|
||||
//import net.minecraft.world.level.Level;
|
||||
//import org.spongepowered.asm.mixin.Final;
|
||||
//import org.spongepowered.asm.mixin.Mixin;
|
||||
//import org.spongepowered.asm.mixin.Shadow;
|
||||
//import org.spongepowered.asm.mixin.injection.At;
|
||||
//import org.spongepowered.asm.mixin.injection.Inject;
|
||||
//import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
//import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
//
|
||||
//@Mixin(PathNavigation.class)
|
||||
//public abstract class EntityNavigationMixin {
|
||||
//
|
||||
// @Shadow
|
||||
// @Final
|
||||
// protected Level level;
|
||||
//
|
||||
// @Shadow
|
||||
// protected Path path;
|
||||
//
|
||||
// @Shadow
|
||||
// @Final
|
||||
// protected Mob mob;
|
||||
//
|
||||
// @Inject(
|
||||
// method = "recomputePath",
|
||||
// at = @At(
|
||||
// value = "INVOKE_ASSIGN",
|
||||
// target = "Lnet/minecraft/world/entity/ai/navigation/PathNavigation;createPath(Lnet/minecraft/core/BlockPos;I)Lnet/minecraft/world/level/pathfinder/Path;",
|
||||
// shift = At.Shift.AFTER
|
||||
// )
|
||||
// )
|
||||
// private void updateListeningState(CallbackInfo ci) {
|
||||
// if (((NavigatingEntity) this.mob).lithium$isRegisteredToWorld()) {
|
||||
// if (this.path == null) {
|
||||
// ((ServerWorldExtended) this.level).lithium$setNavigationInactive(this.mob);
|
||||
// } else {
|
||||
// ((ServerWorldExtended) this.level).lithium$setNavigationActive(this.mob);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Inject(method = "moveTo(Lnet/minecraft/world/level/pathfinder/Path;D)Z", at = @At(value = "RETURN"))
|
||||
// private void updateListeningState2(Path path, double speed, CallbackInfoReturnable<Boolean> cir) {
|
||||
// if (((NavigatingEntity) this.mob).lithium$isRegisteredToWorld()) {
|
||||
// if (this.path == null) {
|
||||
// ((ServerWorldExtended) this.level).lithium$setNavigationInactive(this.mob);
|
||||
// } else {
|
||||
// ((ServerWorldExtended) this.level).lithium$setNavigationActive(this.mob);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Inject(method = "stop", at = @At(value = "RETURN"))
|
||||
// private void stopListening(CallbackInfo ci) {
|
||||
// if (((NavigatingEntity) this.mob).lithium$isRegisteredToWorld()) {
|
||||
// ((ServerWorldExtended) this.level).lithium$setNavigationInactive(this.mob);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,76 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.removed.entity.inactive_navigations;
|
||||
|
||||
//import net.gensokyoreimagined.nitori.common.entity.NavigatingEntity;
|
||||
//import net.gensokyoreimagined.nitori.common.world.ServerWorldExtended;
|
||||
//import net.minecraft.world.entity.Entity;
|
||||
//import net.minecraft.world.entity.EntityType;
|
||||
//import net.minecraft.world.entity.ai.navigation.PathNavigation;
|
||||
//import net.minecraft.world.entity.Mob;
|
||||
//import net.minecraft.world.level.Level;
|
||||
//import org.spongepowered.asm.mixin.Intrinsic;
|
||||
//import org.spongepowered.asm.mixin.Mixin;
|
||||
//import org.spongepowered.asm.mixin.Shadow;
|
||||
//import org.spongepowered.asm.mixin.injection.At;
|
||||
//import org.spongepowered.asm.mixin.injection.Inject;
|
||||
//import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
//import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
//
|
||||
//@Mixin(Mob.class)
|
||||
//public abstract class MobEntityMixin extends Entity implements NavigatingEntity {
|
||||
// private PathNavigation nitori$registeredNavigation;
|
||||
//
|
||||
// public MobEntityMixin(EntityType<?> type, Level world) {
|
||||
// super(type, world);
|
||||
// }
|
||||
//
|
||||
// @Shadow
|
||||
// public abstract PathNavigation getNavigation();
|
||||
//
|
||||
// @Override
|
||||
// public boolean lithium$isRegisteredToWorld() {
|
||||
// return this.nitori$registeredNavigation != null;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void lithium$setRegisteredToWorld(PathNavigation navigation) {
|
||||
// this.nitori$registeredNavigation = navigation;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public PathNavigation lithium$getRegisteredNavigation() {
|
||||
// return this.nitori$registeredNavigation;
|
||||
// }
|
||||
//
|
||||
// @Inject(method = "startRiding", at = @At("RETURN"))
|
||||
// private void onNavigationReplacement(Entity entity, boolean force, CallbackInfoReturnable<Boolean> cir) {
|
||||
// this.lithium$updateNavigationRegistration();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// @Intrinsic
|
||||
// public void stopRiding() {
|
||||
// super.stopRiding();
|
||||
// }
|
||||
//
|
||||
// @SuppressWarnings({"MixinAnnotationTarget", "UnresolvedMixinReference"})
|
||||
// @Inject(method = "stopRiding()V", at = @At("RETURN"))
|
||||
// private void updateOnStopRiding(CallbackInfo ci) {
|
||||
// this.lithium$updateNavigationRegistration();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void lithium$updateNavigationRegistration() {
|
||||
// if (this.lithium$isRegisteredToWorld()) {
|
||||
// PathNavigation navigation = this.getNavigation();
|
||||
// if (this.nitori$registeredNavigation != navigation) {
|
||||
// ((ServerWorldExtended) this.level()).lithium$setNavigationInactive((Mob) (Object) this);
|
||||
// this.nitori$registeredNavigation = navigation;
|
||||
//
|
||||
// if (navigation.getPath() != null) {
|
||||
// ((ServerWorldExtended) this.level()).lithium$setNavigationActive((Mob) (Object) this);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//}
|
||||
@@ -1,4 +1,4 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.entity.inactive_navigations;
|
||||
package net.gensokyoreimagined.nitori.mixin.removed.entity.inactive_navigations;
|
||||
|
||||
//import net.gensokyoreimagined.nitori.common.entity.NavigatingEntity;
|
||||
//import net.gensokyoreimagined.nitori.common.world.ServerWorldExtended;
|
||||
@@ -1,4 +1,4 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.entity.inactive_navigations;
|
||||
package net.gensokyoreimagined.nitori.mixin.removed.entity.inactive_navigations;
|
||||
|
||||
//import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
|
||||
//import net.gensokyoreimagined.nitori.common.entity.NavigatingEntity;
|
||||
@@ -0,0 +1,13 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.removed.logic.fast_bits_blockpos;
|
||||
|
||||
//import net.minecraft.core.SectionPos;
|
||||
//import org.spongepowered.asm.mixin.Mixin;
|
||||
//import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
//
|
||||
//@Mixin(SectionPos.class)
|
||||
//public interface ChunkSectionPosAccessor {
|
||||
// @Invoker("<init>")
|
||||
// public static SectionPos invokeChunkSectionPos(int i, int j, int k) {
|
||||
// throw new AssertionError();
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,67 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.removed.logic.fast_bits_blockpos;
|
||||
|
||||
//import net.minecraft.core.BlockPos;
|
||||
//import org.spongepowered.asm.mixin.Mixin;
|
||||
//import org.spongepowered.asm.mixin.Overwrite;
|
||||
//
|
||||
///**
|
||||
// * Credit to PaperMC Patch #0421
|
||||
// */
|
||||
//@Mixin(BlockPos.class)
|
||||
//public class OptimizedBlockPosBitsMixin {
|
||||
//
|
||||
// /**
|
||||
// * @author QPCrummer
|
||||
// * @reason Inline
|
||||
// */
|
||||
// @Overwrite
|
||||
// public static long offset(long value, int x, int y, int z) {
|
||||
// return asLong((int) (value >> 38) + x, (int) ((value << 52) >> 52) + y, (int) ((value << 26) >> 38) + z);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @author QPCrummer
|
||||
// * @reason Inline
|
||||
// */
|
||||
// @Overwrite
|
||||
// public static int getX(long packedPos) {
|
||||
// return (int) (packedPos >> 38);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @author QPCrummer
|
||||
// * @reason Inline
|
||||
// */
|
||||
// @Overwrite
|
||||
// public static int getY(long packedPos) {
|
||||
// return (int) ((packedPos << 52) >> 52);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @author QPCrummer
|
||||
// * @reason Inline
|
||||
// */
|
||||
// @Overwrite
|
||||
// public static int getZ(long packedPos) {
|
||||
// return (int) ((packedPos << 26) >> 38);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @author QPCrummer
|
||||
// * @reason Inline
|
||||
// */
|
||||
// @Overwrite
|
||||
// public static BlockPos of(long packedPos) {
|
||||
// return new BlockPos((int) (packedPos >> 38), (int) ((packedPos << 52) >> 52), (int) ((packedPos << 26) >> 38));
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @author QPCrummer
|
||||
// * @reason Inline
|
||||
// */
|
||||
// @Overwrite
|
||||
// public static long asLong(int x, int y, int z) {
|
||||
// return (((long) x & (long) 67108863) << 38) | (((long) y & (long) 4095)) | (((long) z & (long) 67108863) << 12);
|
||||
// }
|
||||
//
|
||||
//}
|
||||
@@ -1,6 +1,4 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.logic.fast_bits_blockpos;
|
||||
|
||||
//TODO: impl this
|
||||
package net.gensokyoreimagined.nitori.mixin.removed.logic.fast_bits_blockpos;
|
||||
|
||||
//import net.minecraft.core.BlockPos;
|
||||
//import net.minecraft.world.level.ChunkPos;
|
||||
@@ -1,4 +1,4 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.logic.fast_rotations;
|
||||
package net.gensokyoreimagined.nitori.mixin.removed.logic.fast_rotations;
|
||||
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import net.minecraft.nbt.FloatTag;
|
||||
@@ -1,4 +1,4 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.logic.recipe_manager;
|
||||
package net.gensokyoreimagined.nitori.mixin.removed.logic.recipe_manager.recipe_manager;
|
||||
|
||||
//import net.minecraft.world.Container;
|
||||
//import net.minecraft.world.item.crafting.Recipe;
|
||||
@@ -1,4 +1,4 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.math.random;
|
||||
package net.gensokyoreimagined.nitori.mixin.removed.math.random;
|
||||
|
||||
//import net.gensokyoreimagined.nitori.common.math.random.RandomGeneratorRandom;
|
||||
//import net.minecraft.world.entity.Entity;
|
||||
@@ -0,0 +1,29 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.removed.math.random;
|
||||
|
||||
//import net.gensokyoreimagined.nitori.common.math.random.RandomGeneratorRandom;
|
||||
//import io.netty.util.internal.ThreadLocalRandom;
|
||||
//import net.minecraft.util.RandomSource;
|
||||
//import net.minecraft.world.level.levelgen.RandomSupport;
|
||||
//import org.jetbrains.annotations.NotNull;
|
||||
//import org.spongepowered.asm.mixin.Mixin;
|
||||
//import org.spongepowered.asm.mixin.injection.At;
|
||||
//import org.spongepowered.asm.mixin.injection.Inject;
|
||||
//import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
//
|
||||
//@Mixin(RandomSource.class)
|
||||
//public interface RandomMixin {
|
||||
// @Inject(method = "create(J)Lnet/minecraft/util/RandomSource;", at = @At(value = "HEAD"), cancellable = true)
|
||||
// private static void fasterrandom$createInject(long seed, @NotNull CallbackInfoReturnable<RandomSource> cir) {
|
||||
// cir.setReturnValue(new RandomGeneratorRandom(seed));
|
||||
// }
|
||||
//
|
||||
// @Inject(method = "createNewThreadLocalInstance", at = @At(value = "HEAD"), cancellable = true)
|
||||
// private static void fasterrandom$createLocalInject(@NotNull CallbackInfoReturnable<RandomSource> cir) {
|
||||
// cir.setReturnValue(new RandomGeneratorRandom(ThreadLocalRandom.current().nextLong()));
|
||||
// }
|
||||
//
|
||||
// @Inject(method = "createThreadSafe", at = @At(value = "HEAD"), cancellable = true)
|
||||
// private static void fasterrandom$createThreadSafeInject(@NotNull CallbackInfoReturnable<RandomSource> cir) {
|
||||
// cir.setReturnValue(new RandomGeneratorRandom(RandomSupport.generateUniqueSeed()));
|
||||
// }
|
||||
//}
|
||||
@@ -1,4 +1,4 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.math.random.creation;
|
||||
package net.gensokyoreimagined.nitori.mixin.removed.math.random.creation;
|
||||
|
||||
//import net.gensokyoreimagined.nitori.mixin.math.random.math.GetRandomInterface;
|
||||
//import net.minecraft.server.rcon.thread.QueryThreadGs4;
|
||||
@@ -1,4 +1,4 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.math.random.creation;
|
||||
package net.gensokyoreimagined.nitori.mixin.removed.math.random.creation;
|
||||
|
||||
//import net.minecraft.server.level.ServerPlayer;
|
||||
//import net.minecraft.server.level.ServerLevel;
|
||||
@@ -1,4 +1,4 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.math.random.math;
|
||||
package net.gensokyoreimagined.nitori.mixin.removed.math.random.math;
|
||||
|
||||
//import net.minecraft.util.Mth;
|
||||
//import net.minecraft.util.RandomSource;
|
||||
@@ -0,0 +1,76 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.removed.vmp.general.collections;
|
||||
|
||||
//import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
|
||||
//import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
//import net.gensokyoreimagined.nitori.access.ITypeFilterableList;
|
||||
//import net.minecraft.util.ClassInstanceMultiMap;
|
||||
//import org.objectweb.asm.Opcodes;
|
||||
//import org.spongepowered.asm.mixin.*;
|
||||
//import org.spongepowered.asm.mixin.injection.At;
|
||||
//import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
//
|
||||
//import java.util.*;
|
||||
//
|
||||
//@Mixin(value = ClassInstanceMultiMap.class, priority = 1005) // priority compatibility hack for lithium
|
||||
//public abstract class MixinTypeFilterableList<T> extends AbstractCollection<T> implements ITypeFilterableList {
|
||||
//
|
||||
// @Mutable
|
||||
// @Shadow @Final private Map<Class<?>, List<T>> byClass;
|
||||
//
|
||||
// @Mutable
|
||||
// @Shadow @Final private List<T> allInstances;
|
||||
//
|
||||
// @Shadow @Final private Class<T> baseClass;
|
||||
//
|
||||
// @Redirect(method = "<init>", at = @At(value = "FIELD", target = "Lnet/minecraft/util/ClassInstanceMultiMap;byClass:Ljava/util/Map;", opcode = Opcodes.PUTFIELD))
|
||||
// private void redirectSetElementsByType(ClassInstanceMultiMap<T> instance, Map<Class<?>, List<T>> value) {
|
||||
// this.byClass = new Object2ObjectLinkedOpenHashMap<>();
|
||||
// }
|
||||
//
|
||||
// @Redirect(method = "<init>", at = @At(value = "FIELD", target = "Lnet/minecraft/util/ClassInstanceMultiMap;allInstances:Ljava/util/List;", opcode = Opcodes.PUTFIELD))
|
||||
// private void redirectSetAllElements(ClassInstanceMultiMap<T> instance, List<T> value) {
|
||||
// this.allInstances = new ObjectArrayList<>();
|
||||
// }
|
||||
//
|
||||
// @Redirect(method = "<init>", at = @At(value = "INVOKE", target = "Lcom/google/common/collect/Maps;newHashMap()Ljava/util/HashMap;", remap = false))
|
||||
// private HashMap<?, ?> redirectNewHashMap() {
|
||||
// return null; // avoid unnecessary alloc
|
||||
// }
|
||||
//
|
||||
// @Redirect(method = "<init>", at = @At(value = "INVOKE", target = "Lcom/google/common/collect/Lists;newArrayList()Ljava/util/ArrayList;", remap = false))
|
||||
// private ArrayList<?> redirectNewArrayList() {
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public Object[] getBackingArray() {
|
||||
// return ((ObjectArrayList<T>) this.allInstances).elements();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @author ishland
|
||||
// * @reason use fastutil array list for faster iteration & use array for filtering iteration
|
||||
// */
|
||||
// @Overwrite
|
||||
// public <S> Collection<S> find(Class<S> type) {
|
||||
// List<T> cached = this.byClass.get(type);
|
||||
// if (cached != null) return (Collection<S>) cached;
|
||||
//
|
||||
// if (!this.baseClass.isAssignableFrom(type)) {
|
||||
// throw new IllegalArgumentException("Don't know how to search for " + type);
|
||||
// } else {
|
||||
// List<? extends T> list = this.byClass.computeIfAbsent(type,
|
||||
// typeClass -> {
|
||||
// ObjectArrayList<T> ts = new ObjectArrayList<>(this.allInstances.size());
|
||||
// for (Object _allElement : ((ObjectArrayList<T>) this.allInstances).elements()) {
|
||||
// if (typeClass.isInstance(_allElement)) {
|
||||
// ts.add((T) _allElement);
|
||||
// }
|
||||
// }
|
||||
// return ts;
|
||||
// }
|
||||
// );
|
||||
// return (Collection<S>) list;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,22 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.removed.vmp.playerwatching;
|
||||
|
||||
//import net.minecraft.server.level.ChunkTrackingView;
|
||||
//import org.spongepowered.asm.mixin.Mixin;
|
||||
//import org.spongepowered.asm.mixin.Overwrite;
|
||||
//
|
||||
//@Mixin(ChunkTrackingView.class)
|
||||
//public interface MixinChunkFilter {
|
||||
//
|
||||
// /**
|
||||
// * @author ishland
|
||||
// * @reason use chebyshev distance
|
||||
// */
|
||||
// @Overwrite
|
||||
// static boolean isWithinDistance(int centerX, int centerZ, int viewDistance, int x, int z, boolean includeEdge) {
|
||||
// int actualViewDistance = viewDistance + (includeEdge ? 1 : 0);
|
||||
// int xDistance = Math.abs(centerX - x);
|
||||
// int zDistance = Math.abs(centerZ - z);
|
||||
// return xDistance <= actualViewDistance && zDistance <= actualViewDistance;
|
||||
// }
|
||||
//
|
||||
//}
|
||||
@@ -0,0 +1,46 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.removed.vmp.playerwatching;
|
||||
|
||||
//import net.gensokyoreimagined.nitori.common.chunkwatching.PlayerClientVDTracking;
|
||||
//import net.minecraft.server.level.ClientInformation;
|
||||
//import net.minecraft.server.level.ServerPlayer;
|
||||
//import org.spongepowered.asm.mixin.Mixin;
|
||||
//import org.spongepowered.asm.mixin.Unique;
|
||||
//import org.spongepowered.asm.mixin.injection.At;
|
||||
//import org.spongepowered.asm.mixin.injection.Inject;
|
||||
//import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
//
|
||||
//@Mixin(ServerPlayer.class)
|
||||
//public class MixinServerPlayerEntity implements PlayerClientVDTracking {
|
||||
//
|
||||
// @Unique
|
||||
// private boolean vdChanged = false;
|
||||
//
|
||||
// @Unique
|
||||
// private int clientVD = 2;
|
||||
//
|
||||
// @Inject(method = "updateOptions", at = @At("HEAD"))
|
||||
// private void onClientSettingsChanged(ClientInformation packet, CallbackInfo ci) {
|
||||
// final int currentVD = packet.viewDistance();
|
||||
// if (currentVD != this.clientVD) this.vdChanged = true;
|
||||
// this.clientVD = Math.max(2, currentVD);
|
||||
// }
|
||||
//
|
||||
// @Inject(method = "restoreFrom", at = @At("RETURN"))
|
||||
// private void onPlayerCopy(ServerPlayer oldPlayer, boolean alive, CallbackInfo ci) {
|
||||
// this.clientVD = ((PlayerClientVDTracking) oldPlayer).getClientViewDistance();
|
||||
// this.vdChanged = true;
|
||||
// }
|
||||
//
|
||||
// @Unique
|
||||
// @Override
|
||||
// public boolean isClientViewDistanceChanged() {
|
||||
// return this.vdChanged;
|
||||
// }
|
||||
//
|
||||
// @Unique
|
||||
// @Override
|
||||
// public int getClientViewDistance() {
|
||||
// this.vdChanged = false;
|
||||
// return this.clientVD;
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,35 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.removed.vmp.playerwatching.optimize_nearby_player_lookups;
|
||||
|
||||
//import net.minecraft.world.entity.Entity;
|
||||
//import net.minecraft.world.entity.EntityType;
|
||||
//import net.minecraft.world.entity.LivingEntity;
|
||||
//import net.minecraft.world.entity.Mob;
|
||||
//import net.minecraft.world.entity.player.Player;
|
||||
//import net.minecraft.world.level.Level;
|
||||
//import org.spongepowered.asm.mixin.Mixin;
|
||||
//import org.spongepowered.asm.mixin.injection.At;
|
||||
//import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
//
|
||||
//import java.util.List;
|
||||
//import java.util.function.Predicate;
|
||||
//
|
||||
//@Mixin(Mob.class)
|
||||
//public abstract class MixinMobEntity extends LivingEntity {
|
||||
//
|
||||
// protected MixinMobEntity(EntityType<? extends LivingEntity> entityType, Level world) {
|
||||
// super(entityType, world);
|
||||
// }
|
||||
//
|
||||
// @Redirect(method = "checkDespawn", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;findNearbyPlayer(Lnet/minecraft/world/entity/Entity;DLjava/util/function/Predicate;)Lnet/minecraft/world/entity/player/Player;"))
|
||||
// private Player redirectGetClosestPlayer(Level instance, Entity entity, double v, Predicate predicate) {
|
||||
// final Player closestPlayer = instance.getNearestPlayer(entity, this.getType().getCategory().getDespawnDistance());
|
||||
// if (closestPlayer != null) {
|
||||
// return closestPlayer;
|
||||
// } else {
|
||||
// final List<? extends Player> players = this.level().players();
|
||||
// if (players.isEmpty()) return null;
|
||||
// return players.get(0);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//}
|
||||
@@ -0,0 +1,23 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.removed.world.portal_checks;
|
||||
|
||||
//import net.minecraft.world.entity.Entity;
|
||||
//import net.minecraft.world.level.portal.PortalShape;
|
||||
//import net.minecraft.world.phys.Vec3;
|
||||
//import net.minecraft.server.level.ServerLevel;
|
||||
//import net.minecraft.world.entity.EntityDimensions;
|
||||
//import org.spongepowered.asm.mixin.Mixin;
|
||||
//import org.spongepowered.asm.mixin.injection.At;
|
||||
//import org.spongepowered.asm.mixin.injection.Inject;
|
||||
//import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
//
|
||||
//@Mixin({PortalShape.class})
|
||||
//public class DisablePortalChecksMixin {
|
||||
// @Inject(
|
||||
// at = {@At("HEAD")},
|
||||
// method = {"findCollisionFreePosition"},
|
||||
// cancellable = true
|
||||
// )
|
||||
// private static void init(Vec3 fallback, ServerLevel world, Entity entity, EntityDimensions dimensions, CallbackInfoReturnable<Vec3> cir) {
|
||||
// cir.setReturnValue(fallback);
|
||||
// }
|
||||
//}
|
||||
@@ -1,8 +1,5 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.removed.world.tick_scheduler;
|
||||
|
||||
//TODO: Make this work with paper
|
||||
|
||||
|
||||
//import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
//import it.unimi.dsi.fastutil.longs.Long2ReferenceAVLTreeMap;
|
||||
//import it.unimi.dsi.fastutil.objects.ObjectIterator;
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.shapes.lazy_shape_context;
|
||||
|
||||
import net.minecraft.world.phys.shapes.EntityCollisionContext;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.*;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Constant;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyConstant;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@Mixin(EntityCollisionContext.class)
|
||||
public class EntityShapeContextMixin {
|
||||
@Mutable
|
||||
@Shadow
|
||||
@Final
|
||||
private ItemStack heldItem;
|
||||
|
||||
@Mutable
|
||||
@Shadow
|
||||
@Final
|
||||
private Predicate<FluidState> canStandOnFluid;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
@Nullable
|
||||
private Entity entity;
|
||||
|
||||
/**
|
||||
* Mixin the instanceof to always return false to avoid the expensive inventory access.
|
||||
* No need to use Opcodes.INSTANCEOF or similar.
|
||||
*/
|
||||
@SuppressWarnings("InvalidInjectorMethodSignature")
|
||||
@ModifyConstant(
|
||||
method = "<init>(Lnet/minecraft/world/entity/Entity;)V",
|
||||
constant = @Constant(classValue = LivingEntity.class, ordinal = 0)
|
||||
)
|
||||
private static boolean redirectInstanceOf(Object ignored, Class<?> constant) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("InvalidInjectorMethodSignature")
|
||||
@ModifyConstant(
|
||||
method = "<init>(Lnet/minecraft/world/entity/Entity;)V",
|
||||
constant = @Constant(classValue = LivingEntity.class, ordinal = 2)
|
||||
)
|
||||
private static boolean redirectInstanceOf2(Object ignored, Class<?> constant) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "<init>(Lnet/minecraft/world/entity/Entity;)V",
|
||||
at = @At("TAIL")
|
||||
)
|
||||
private void initFields(Entity entity, CallbackInfo ci) {
|
||||
this.heldItem = null;
|
||||
this.canStandOnFluid = null;
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "isHoldingItem",
|
||||
at = @At("HEAD")
|
||||
)
|
||||
public void isHolding(Item item, CallbackInfoReturnable<Boolean> cir) {
|
||||
this.nitori$initHeldItem();
|
||||
}
|
||||
|
||||
@Intrinsic
|
||||
public ItemStack getHeldItem() {
|
||||
return this.heldItem;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"UnresolvedMixinReference", "MixinAnnotationTarget"})
|
||||
@Inject(
|
||||
method = "getHeldItem",
|
||||
at = @At("HEAD")
|
||||
)
|
||||
private void nitori$initHeldItem(CallbackInfoReturnable<ItemStack> callbackInfoReturnable) {
|
||||
this.nitori$initHeldItem();
|
||||
}
|
||||
|
||||
@Unique
|
||||
private void nitori$initHeldItem() {
|
||||
if (this.heldItem == null) {
|
||||
this.heldItem = this.entity instanceof LivingEntity ? ((LivingEntity) this.entity).getMainHandItem() : ItemStack.EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "canStandOnFluid",
|
||||
at = @At("HEAD")
|
||||
)
|
||||
public void canWalkOnFluid(FluidState state, FluidState fluidState, CallbackInfoReturnable<Boolean> cir) {
|
||||
if (this.canStandOnFluid == null) {
|
||||
if (this.entity instanceof LivingEntity livingEntity) {
|
||||
this.canStandOnFluid = livingEntity::canStandOnFluid;
|
||||
} else {
|
||||
this.canStandOnFluid = (liquid) -> false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.shapes.precompute_shape_arrays;
|
||||
|
||||
import net.minecraft.world.phys.shapes.CubePointRange;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(CubePointRange.class)
|
||||
public class FractionalDoubleListMixin {
|
||||
@Shadow
|
||||
@Final
|
||||
private int parts;
|
||||
|
||||
private double scale;
|
||||
|
||||
@Inject(method = "<init>(I)V", at = @At("RETURN"))
|
||||
public void initScale(int sectionCount, CallbackInfo ci) {
|
||||
this.scale = 1.0D / this.parts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author JellySquid
|
||||
* @reason Replace division with multiplication
|
||||
*/
|
||||
@Overwrite
|
||||
public double getDouble(int position) {
|
||||
return position * this.scale;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.unapplied.shapes.lazy_shape_context;
|
||||
|
||||
//import net.minecraft.world.phys.shapes.EntityCollisionContext;
|
||||
//import net.minecraft.world.entity.Entity;
|
||||
//import net.minecraft.world.entity.LivingEntity;
|
||||
//import net.minecraft.world.level.material.FluidState;
|
||||
//import net.minecraft.world.item.Item;
|
||||
//import net.minecraft.world.item.ItemStack;
|
||||
//import org.jetbrains.annotations.Nullable;
|
||||
//import org.spongepowered.asm.mixin.*;
|
||||
//import org.spongepowered.asm.mixin.injection.At;
|
||||
//import org.spongepowered.asm.mixin.injection.Constant;
|
||||
//import org.spongepowered.asm.mixin.injection.Inject;
|
||||
//import org.spongepowered.asm.mixin.injection.ModifyConstant;
|
||||
//import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
//import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
//
|
||||
//import java.util.function.Predicate;
|
||||
//
|
||||
//@Mixin(EntityCollisionContext.class)
|
||||
//public class EntityShapeContextMixin {
|
||||
// @Mutable
|
||||
// @Shadow
|
||||
// @Final
|
||||
// private ItemStack heldItem;
|
||||
//
|
||||
// @Mutable
|
||||
// @Shadow
|
||||
// @Final
|
||||
// private Predicate<FluidState> canStandOnFluid;
|
||||
//
|
||||
// @Shadow
|
||||
// @Final
|
||||
// @Nullable
|
||||
// private Entity entity;
|
||||
//
|
||||
// /**
|
||||
// * Mixin the instanceof to always return false to avoid the expensive inventory access.
|
||||
// * No need to use Opcodes.INSTANCEOF or similar.
|
||||
// */
|
||||
// @SuppressWarnings("InvalidInjectorMethodSignature")
|
||||
// @ModifyConstant(
|
||||
// method = "<init>(Lnet/minecraft/world/entity/Entity;)V",
|
||||
// constant = @Constant(classValue = LivingEntity.class, ordinal = 0)
|
||||
// )
|
||||
// private static boolean redirectInstanceOf(Object ignored, Class<?> constant) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// @SuppressWarnings("InvalidInjectorMethodSignature")
|
||||
// @ModifyConstant(
|
||||
// method = "<init>(Lnet/minecraft/world/entity/Entity;)V",
|
||||
// constant = @Constant(classValue = LivingEntity.class, ordinal = 2)
|
||||
// )
|
||||
// private static boolean redirectInstanceOf2(Object ignored, Class<?> constant) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// @Inject(
|
||||
// method = "<init>(Lnet/minecraft/world/entity/Entity;)V",
|
||||
// at = @At("TAIL")
|
||||
// )
|
||||
// private void initFields(Entity entity, CallbackInfo ci) {
|
||||
// this.heldItem = null;
|
||||
// this.canStandOnFluid = null;
|
||||
// }
|
||||
//
|
||||
// @Inject(
|
||||
// method = "isHoldingItem",
|
||||
// at = @At("HEAD")
|
||||
// )
|
||||
// public void isHolding(Item item, CallbackInfoReturnable<Boolean> cir) {
|
||||
// this.nitori$initHeldItem();
|
||||
// }
|
||||
//
|
||||
// @Intrinsic
|
||||
// public ItemStack getHeldItem() {
|
||||
// return this.heldItem;
|
||||
// }
|
||||
//
|
||||
// @SuppressWarnings({"UnresolvedMixinReference", "MixinAnnotationTarget"})
|
||||
// @Inject(
|
||||
// method = "getHeldItem",
|
||||
// at = @At("HEAD")
|
||||
// )
|
||||
// private void nitori$initHeldItem(CallbackInfoReturnable<ItemStack> callbackInfoReturnable) {
|
||||
// this.nitori$initHeldItem();
|
||||
// }
|
||||
//
|
||||
// @Unique
|
||||
// private void nitori$initHeldItem() {
|
||||
// if (this.heldItem == null) {
|
||||
// this.heldItem = this.entity instanceof LivingEntity ? ((LivingEntity) this.entity).getMainHandItem() : ItemStack.EMPTY;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Inject(
|
||||
// method = "canStandOnFluid",
|
||||
// at = @At("HEAD")
|
||||
// )
|
||||
// public void canWalkOnFluid(FluidState state, FluidState fluidState, CallbackInfoReturnable<Boolean> cir) {
|
||||
// if (this.canStandOnFluid == null) {
|
||||
// if (this.entity instanceof LivingEntity livingEntity) {
|
||||
// this.canStandOnFluid = livingEntity::canStandOnFluid;
|
||||
// } else {
|
||||
// this.canStandOnFluid = (liquid) -> false;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,33 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.unapplied.shapes.precompute_shape_arrays;
|
||||
|
||||
//import net.minecraft.world.phys.shapes.CubePointRange;
|
||||
//import org.spongepowered.asm.mixin.Final;
|
||||
//import org.spongepowered.asm.mixin.Mixin;
|
||||
//import org.spongepowered.asm.mixin.Overwrite;
|
||||
//import org.spongepowered.asm.mixin.Shadow;
|
||||
//import org.spongepowered.asm.mixin.injection.At;
|
||||
//import org.spongepowered.asm.mixin.injection.Inject;
|
||||
//import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
//
|
||||
//@Mixin(CubePointRange.class)
|
||||
//public class FractionalDoubleListMixin {
|
||||
// @Shadow
|
||||
// @Final
|
||||
// private int parts;
|
||||
//
|
||||
// private double scale;
|
||||
//
|
||||
// @Inject(method = "<init>(I)V", at = @At("RETURN"))
|
||||
// public void initScale(int sectionCount, CallbackInfo ci) {
|
||||
// this.scale = 1.0D / this.parts;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @author JellySquid
|
||||
// * @reason Replace division with multiplication
|
||||
// */
|
||||
// @Overwrite
|
||||
// public double getDouble(int position) {
|
||||
// return position * this.scale;
|
||||
// }
|
||||
//}
|
||||
@@ -1,76 +0,0 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.vmp.general.collections;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.gensokyoreimagined.nitori.access.ITypeFilterableList;
|
||||
import net.minecraft.util.ClassInstanceMultiMap;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.spongepowered.asm.mixin.*;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Mixin(value = ClassInstanceMultiMap.class, priority = 1005) // priority compatibility hack for lithium
|
||||
public abstract class MixinTypeFilterableList<T> extends AbstractCollection<T> implements ITypeFilterableList {
|
||||
|
||||
@Mutable
|
||||
@Shadow @Final private Map<Class<?>, List<T>> byClass;
|
||||
|
||||
@Mutable
|
||||
@Shadow @Final private List<T> allInstances;
|
||||
|
||||
@Shadow @Final private Class<T> baseClass;
|
||||
|
||||
@Redirect(method = "<init>", at = @At(value = "FIELD", target = "Lnet/minecraft/util/ClassInstanceMultiMap;byClass:Ljava/util/Map;", opcode = Opcodes.PUTFIELD))
|
||||
private void redirectSetElementsByType(ClassInstanceMultiMap<T> instance, Map<Class<?>, List<T>> value) {
|
||||
this.byClass = new Object2ObjectLinkedOpenHashMap<>();
|
||||
}
|
||||
|
||||
@Redirect(method = "<init>", at = @At(value = "FIELD", target = "Lnet/minecraft/util/ClassInstanceMultiMap;allInstances:Ljava/util/List;", opcode = Opcodes.PUTFIELD))
|
||||
private void redirectSetAllElements(ClassInstanceMultiMap<T> instance, List<T> value) {
|
||||
this.allInstances = new ObjectArrayList<>();
|
||||
}
|
||||
|
||||
@Redirect(method = "<init>", at = @At(value = "INVOKE", target = "Lcom/google/common/collect/Maps;newHashMap()Ljava/util/HashMap;", remap = false))
|
||||
private HashMap<?, ?> redirectNewHashMap() {
|
||||
return null; // avoid unnecessary alloc
|
||||
}
|
||||
|
||||
@Redirect(method = "<init>", at = @At(value = "INVOKE", target = "Lcom/google/common/collect/Lists;newArrayList()Ljava/util/ArrayList;", remap = false))
|
||||
private ArrayList<?> redirectNewArrayList() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getBackingArray() {
|
||||
return ((ObjectArrayList<T>) this.allInstances).elements();
|
||||
}
|
||||
|
||||
/**
|
||||
* @author ishland
|
||||
* @reason use fastutil array list for faster iteration & use array for filtering iteration
|
||||
*/
|
||||
@Overwrite
|
||||
public <S> Collection<S> find(Class<S> type) {
|
||||
List<T> cached = this.byClass.get(type);
|
||||
if (cached != null) return (Collection<S>) cached;
|
||||
|
||||
if (!this.baseClass.isAssignableFrom(type)) {
|
||||
throw new IllegalArgumentException("Don't know how to search for " + type);
|
||||
} else {
|
||||
List<? extends T> list = this.byClass.computeIfAbsent(type,
|
||||
typeClass -> {
|
||||
ObjectArrayList<T> ts = new ObjectArrayList<>(this.allInstances.size());
|
||||
for (Object _allElement : ((ObjectArrayList<T>) this.allInstances).elements()) {
|
||||
if (typeClass.isInstance(_allElement)) {
|
||||
ts.add((T) _allElement);
|
||||
}
|
||||
}
|
||||
return ts;
|
||||
}
|
||||
);
|
||||
return (Collection<S>) list;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.vmp.playerwatching;
|
||||
|
||||
import net.minecraft.server.level.ChunkTrackingView;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
|
||||
@Mixin(ChunkTrackingView.class)
|
||||
public interface MixinChunkFilter {
|
||||
|
||||
/**
|
||||
* @author ishland
|
||||
* @reason use chebyshev distance
|
||||
*/
|
||||
@Overwrite
|
||||
static boolean isWithinDistance(int centerX, int centerZ, int viewDistance, int x, int z, boolean includeEdge) {
|
||||
int actualViewDistance = viewDistance + (includeEdge ? 1 : 0);
|
||||
int xDistance = Math.abs(centerX - x);
|
||||
int zDistance = Math.abs(centerZ - z);
|
||||
return xDistance <= actualViewDistance && zDistance <= actualViewDistance;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.vmp.playerwatching;
|
||||
|
||||
import net.gensokyoreimagined.nitori.common.chunkwatching.PlayerClientVDTracking;
|
||||
import net.minecraft.server.level.ClientInformation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(ServerPlayer.class)
|
||||
public class MixinServerPlayerEntity implements PlayerClientVDTracking {
|
||||
|
||||
@Unique
|
||||
private boolean vdChanged = false;
|
||||
|
||||
@Unique
|
||||
private int clientVD = 2;
|
||||
|
||||
@Inject(method = "updateOptions", at = @At("HEAD"))
|
||||
private void onClientSettingsChanged(ClientInformation packet, CallbackInfo ci) {
|
||||
final int currentVD = packet.viewDistance();
|
||||
if (currentVD != this.clientVD) this.vdChanged = true;
|
||||
this.clientVD = Math.max(2, currentVD);
|
||||
}
|
||||
|
||||
@Inject(method = "restoreFrom", at = @At("RETURN"))
|
||||
private void onPlayerCopy(ServerPlayer oldPlayer, boolean alive, CallbackInfo ci) {
|
||||
this.clientVD = ((PlayerClientVDTracking) oldPlayer).getClientViewDistance();
|
||||
this.vdChanged = true;
|
||||
}
|
||||
|
||||
@Unique
|
||||
@Override
|
||||
public boolean isClientViewDistanceChanged() {
|
||||
return this.vdChanged;
|
||||
}
|
||||
|
||||
@Unique
|
||||
@Override
|
||||
public int getClientViewDistance() {
|
||||
this.vdChanged = false;
|
||||
return this.clientVD;
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.vmp.playerwatching.optimize_nearby_player_lookups;
|
||||
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@Mixin(Mob.class)
|
||||
public abstract class MixinMobEntity extends LivingEntity {
|
||||
|
||||
protected MixinMobEntity(EntityType<? extends LivingEntity> entityType, Level world) {
|
||||
super(entityType, world);
|
||||
}
|
||||
|
||||
@Redirect(method = "checkDespawn", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;findNearbyPlayer(Lnet/minecraft/world/entity/Entity;DLjava/util/function/Predicate;)Lnet/minecraft/world/entity/player/Player;"))
|
||||
private Player redirectGetClosestPlayer(Level instance, Entity entity, double v, Predicate predicate) {
|
||||
final Player closestPlayer = instance.getNearestPlayer(entity, this.getType().getCategory().getDespawnDistance());
|
||||
if (closestPlayer != null) {
|
||||
return closestPlayer;
|
||||
} else {
|
||||
final List<? extends Player> players = this.level().players();
|
||||
if (players.isEmpty()) return null;
|
||||
return players.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.world.block_entity_ticking;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import net.gensokyoreimagined.nitori.common.util.collections.HashedReferenceList;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.TickingBlockEntity;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(Level.class)
|
||||
public class HashedReferenceListMixin {
|
||||
// Implementation of 0006-lithium-HashedReferenceList.patch
|
||||
@Mutable
|
||||
@Final @Shadow
|
||||
public List<TickingBlockEntity> blockEntityTickers;
|
||||
|
||||
// Implementation of 0006-lithium-HashedReferenceList.patch
|
||||
@Mutable
|
||||
@Final @Shadow
|
||||
private List<TickingBlockEntity> pendingBlockEntityTickers;
|
||||
|
||||
// Implementation of 0006-lithium-HashedReferenceList.patch
|
||||
@Inject(method = "<init>", at = @At("RETURN"))
|
||||
private void onInit(CallbackInfo ci) {
|
||||
this.blockEntityTickers = new HashedReferenceList<>(Lists.newArrayList());
|
||||
this.pendingBlockEntityTickers = new HashedReferenceList<>(Lists.newArrayList());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.world.block_entity_ticking.sleeping;
|
||||
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.entity.TickingBlockEntity;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(ServerLevel.class)
|
||||
public class ServerWorldMixin {
|
||||
|
||||
@Redirect(
|
||||
method = "dumpBlockEntityTickers",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/entity/TickingBlockEntity;getPos()Lnet/minecraft/core/BlockPos;")
|
||||
)
|
||||
private BlockPos getPosOrOrigin(TickingBlockEntity instance) {
|
||||
BlockPos pos = instance.getPos();
|
||||
if (pos == null) {
|
||||
return BlockPos.ZERO;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.world.block_entity_ticking.sleeping;
|
||||
|
||||
import net.gensokyoreimagined.nitori.common.block.entity.SleepingBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityTicker;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.entity.TickingBlockEntity;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Coerce;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
@Mixin(LevelChunk.class)
|
||||
public class WorldChunkMixin {
|
||||
|
||||
@Inject(
|
||||
method = "lambda$updateBlockEntityTicker$5",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;addBlockEntityTicker(Lnet/minecraft/world/level/block/entity/TickingBlockEntity;)V" ),
|
||||
locals = LocalCapture.CAPTURE_FAILHARD
|
||||
)
|
||||
private void setBlockEntityTickingOrder(BlockEntity blockEntity, BlockEntityTicker<?> blockEntityTicker, BlockPos pos, @Coerce Object wrappedBlockEntityTickInvoker, CallbackInfoReturnable<?> cir, TickingBlockEntity blockEntityTickInvoker, @Coerce Object wrappedBlockEntityTickInvoker2) {
|
||||
if (blockEntity instanceof SleepingBlockEntity sleepingBlockEntity) {
|
||||
sleepingBlockEntity.lithium$setTickWrapper((WrappedBlockEntityTickInvokerAccessor) wrappedBlockEntityTickInvoker2);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "lambda$updateBlockEntityTicker$5",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/chunk/LevelChunk$RebindableTickingBlockEntityWrapper;rebind(Lnet/minecraft/world/level/block/entity/TickingBlockEntity;)V" ),
|
||||
locals = LocalCapture.CAPTURE_FAILHARD
|
||||
)
|
||||
private void setBlockEntityTickingOrder(BlockEntity blockEntity, BlockEntityTicker<?> blockEntityTicker, BlockPos pos, @Coerce Object wrappedBlockEntityTickInvoker, CallbackInfoReturnable<?> cir, TickingBlockEntity blockEntityTickInvoker) {
|
||||
if (blockEntity instanceof SleepingBlockEntity sleepingBlockEntity) {
|
||||
sleepingBlockEntity.lithium$setTickWrapper((WrappedBlockEntityTickInvokerAccessor) wrappedBlockEntityTickInvoker);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.world.block_entity_ticking.sleeping;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(Level.class)
|
||||
public class WorldMixin {
|
||||
|
||||
@Redirect(
|
||||
method = "tickBlockEntities",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;shouldTickBlocksAt(Lnet/minecraft/core/BlockPos;)Z" )
|
||||
)
|
||||
private boolean shouldTickBlockPosFilterNull(Level instance, BlockPos pos) {
|
||||
if (pos == null) {
|
||||
return false;
|
||||
}
|
||||
return instance.shouldTickBlocksAt(pos);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.world.block_entity_ticking.sleeping.brewing_stand;
|
||||
|
||||
import net.gensokyoreimagined.nitori.common.block.entity.SleepingBlockEntity;
|
||||
import net.gensokyoreimagined.nitori.mixin.world.block_entity_ticking.sleeping.WrappedBlockEntityTickInvokerAccessor;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.entity.BrewingStandBlockEntity;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.TickingBlockEntity;
|
||||
import org.spongepowered.asm.mixin.Intrinsic;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(BrewingStandBlockEntity.class)
|
||||
public class BrewingStandBlockEntityMixin extends BlockEntity implements SleepingBlockEntity {
|
||||
|
||||
@Shadow
|
||||
int brewTime;
|
||||
|
||||
private WrappedBlockEntityTickInvokerAccessor tickWrapper = null;
|
||||
private TickingBlockEntity sleepingTicker = null;
|
||||
|
||||
public BrewingStandBlockEntityMixin(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||
super(type, pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WrappedBlockEntityTickInvokerAccessor lithium$getTickWrapper() {
|
||||
return tickWrapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lithium$setTickWrapper(WrappedBlockEntityTickInvokerAccessor tickWrapper) {
|
||||
this.tickWrapper = tickWrapper;
|
||||
this.lithium$setSleepingTicker(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TickingBlockEntity lithium$getSleepingTicker() {
|
||||
return sleepingTicker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lithium$setSleepingTicker(TickingBlockEntity sleepingTicker) {
|
||||
this.sleepingTicker = sleepingTicker;
|
||||
}
|
||||
|
||||
@Inject(method = "serverTick", at = @At("HEAD"))
|
||||
private static void checkSleep(Level world, BlockPos pos, BlockState state, BrewingStandBlockEntity blockEntity, CallbackInfo ci) {
|
||||
((BrewingStandBlockEntityMixin) (Object) blockEntity).checkSleep(state);
|
||||
}
|
||||
|
||||
@Inject(method = "serverTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/entity/BrewingStandBlockEntity;setChanged(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)V"))
|
||||
private static void wakeUpOnMarkDirty(Level world, BlockPos pos, BlockState state, BrewingStandBlockEntity blockEntity, CallbackInfo ci) {
|
||||
((BrewingStandBlockEntityMixin) (Object) blockEntity).wakeUpNow();
|
||||
}
|
||||
|
||||
private void checkSleep(BlockState state) {
|
||||
if (this.brewTime == 0 && state.is(Blocks.BREWING_STAND) && this.level != null) {
|
||||
this.nitori$startSleeping();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "loadAdditional", at = @At("RETURN"))
|
||||
private void wakeUpAfterFromTag(CallbackInfo ci) {
|
||||
if (this.isSleeping() && this.level != null && !this.level.isClientSide()) {
|
||||
this.wakeUpNow();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Intrinsic
|
||||
public void setChanged() {
|
||||
super.setChanged();
|
||||
}
|
||||
|
||||
@SuppressWarnings({"MixinAnnotationTarget", "UnresolvedMixinReference"})
|
||||
@Inject(method = "markDirty()V", at = @At("RETURN"))
|
||||
private void wakeOnMarkDirty(CallbackInfo ci) {
|
||||
if (this.isSleeping() && this.level != null && !this.level.isClientSide) {
|
||||
this.wakeUpNow();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,69 +1,69 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.world.block_entity_ticking.sleeping.campfire;
|
||||
|
||||
//import net.gensokyoreimagined.nitori.common.block.entity.SleepingBlockEntity;
|
||||
//import net.gensokyoreimagined.nitori.mixin.world.block_entity_ticking.sleeping.WrappedBlockEntityTickInvokerAccessor;
|
||||
//import net.minecraft.world.entity.Entity;
|
||||
//import net.minecraft.world.level.block.state.BlockState;
|
||||
//import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
//import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
//import net.minecraft.world.level.block.entity.CampfireBlockEntity;
|
||||
//import net.minecraft.world.entity.LivingEntity;
|
||||
//import net.minecraft.world.item.ItemStack;
|
||||
//import net.minecraft.nbt.CompoundTag;
|
||||
//import net.minecraft.core.HolderLookup;
|
||||
//import net.minecraft.core.BlockPos;
|
||||
//import net.minecraft.world.level.block.entity.TickingBlockEntity;
|
||||
//import org.spongepowered.asm.mixin.Mixin;
|
||||
//import org.spongepowered.asm.mixin.injection.At;
|
||||
//import org.spongepowered.asm.mixin.injection.Inject;
|
||||
//import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
//import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
//
|
||||
//@Mixin(CampfireBlockEntity.class)
|
||||
//public class CampfireBlockEntityMixin extends BlockEntity implements SleepingBlockEntity {
|
||||
//
|
||||
// private WrappedBlockEntityTickInvokerAccessor tickWrapper = null;
|
||||
// private TickingBlockEntity sleepingTicker = null;
|
||||
//
|
||||
// public CampfireBlockEntityMixin(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||
// super(type, pos, state);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public WrappedBlockEntityTickInvokerAccessor lithium$getTickWrapper() {
|
||||
// return tickWrapper;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void lithium$setTickWrapper(WrappedBlockEntityTickInvokerAccessor tickWrapper) {
|
||||
// this.tickWrapper = tickWrapper;
|
||||
// this.lithium$setSleepingTicker(null);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public TickingBlockEntity lithium$getSleepingTicker() {
|
||||
// return sleepingTicker;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void lithium$setSleepingTicker(TickingBlockEntity sleepingTicker) {
|
||||
// this.sleepingTicker = sleepingTicker;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// @Inject(
|
||||
// method = "placeFood",
|
||||
// at = @At(value = "INVOKE", target = "Lnet/minecraft/core/NonNullList;set(ILjava/lang/Object;)Ljava/lang/Object;")
|
||||
// )
|
||||
// private void wakeUpOnAddItem(LivingEntity user, ItemStack stack, int cookTime, CallbackInfoReturnable<Boolean> cir) {
|
||||
// this.wakeUpNow();
|
||||
// }
|
||||
//
|
||||
// @Inject(
|
||||
// method = "loadAdditional",
|
||||
// at = @At(value = "RETURN")
|
||||
// )
|
||||
// private void wakeUpOnReadNbt(CompoundTag nbt, HolderLookup.Provider registryLookup, CallbackInfo ci) {
|
||||
// this.wakeUpNow();
|
||||
// }
|
||||
//}
|
||||
import net.gensokyoreimagined.nitori.common.block.entity.SleepingBlockEntity;
|
||||
import net.gensokyoreimagined.nitori.mixin.world.block_entity_ticking.sleeping.WrappedBlockEntityTickInvokerAccessor;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.entity.CampfireBlockEntity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.entity.TickingBlockEntity;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(CampfireBlockEntity.class)
|
||||
public class CampfireBlockEntityMixin extends BlockEntity implements SleepingBlockEntity {
|
||||
|
||||
private WrappedBlockEntityTickInvokerAccessor tickWrapper = null;
|
||||
private TickingBlockEntity sleepingTicker = null;
|
||||
|
||||
public CampfireBlockEntityMixin(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||
super(type, pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WrappedBlockEntityTickInvokerAccessor lithium$getTickWrapper() {
|
||||
return tickWrapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lithium$setTickWrapper(WrappedBlockEntityTickInvokerAccessor tickWrapper) {
|
||||
this.tickWrapper = tickWrapper;
|
||||
this.lithium$setSleepingTicker(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TickingBlockEntity lithium$getSleepingTicker() {
|
||||
return sleepingTicker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lithium$setSleepingTicker(TickingBlockEntity sleepingTicker) {
|
||||
this.sleepingTicker = sleepingTicker;
|
||||
}
|
||||
|
||||
|
||||
@Inject(
|
||||
method = "placeFood",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/core/NonNullList;set(ILjava/lang/Object;)Ljava/lang/Object;")
|
||||
)
|
||||
private void wakeUpOnAddItem(LivingEntity user, ItemStack stack, int cookTime, CallbackInfoReturnable<Boolean> cir) {
|
||||
this.wakeUpNow();
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "loadAdditional",
|
||||
at = @At(value = "RETURN")
|
||||
)
|
||||
private void wakeUpOnReadNbt(CompoundTag nbt, HolderLookup.Provider registryLookup, CallbackInfo ci) {
|
||||
this.wakeUpNow();
|
||||
}
|
||||
}
|
||||
@@ -1,40 +1,34 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.world.block_entity_ticking.sleeping.campfire.lit;
|
||||
|
||||
//import net.gensokyoreimagined.nitori.common.block.entity.SleepingBlockEntity;
|
||||
//import net.minecraft.core.BlockPos;
|
||||
//import net.minecraft.world.SimpleContainer;
|
||||
//import net.minecraft.world.item.ItemStack;
|
||||
//import net.minecraft.world.level.Level;
|
||||
//import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
//import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
//import net.minecraft.world.level.block.entity.CampfireBlockEntity;
|
||||
//import net.minecraft.world.level.block.state.BlockState;
|
||||
//import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
//import org.bukkit.event.block.BlockCookEvent;
|
||||
//import org.spongepowered.asm.mixin.Mixin;
|
||||
//import org.spongepowered.asm.mixin.injection.At;
|
||||
//import org.spongepowered.asm.mixin.injection.Inject;
|
||||
//import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
//import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
//
|
||||
//import java.util.Optional;
|
||||
//
|
||||
//@Mixin(CampfireBlockEntity.class)
|
||||
//public abstract class CampfireBlockEntityMixin extends BlockEntity implements SleepingBlockEntity {
|
||||
//
|
||||
// public CampfireBlockEntityMixin(BlockPos pos, BlockState state) {
|
||||
// super(BlockEntityType.CAMPFIRE, pos, state);
|
||||
// }
|
||||
//
|
||||
// @Inject(
|
||||
// method = "cookTick",
|
||||
// at = @At("RETURN"),
|
||||
// locals = LocalCapture.CAPTURE_FAILHARD
|
||||
// )
|
||||
// private static void trySleepLit(Level world, BlockPos pos, BlockState state, CampfireBlockEntity campfire, CallbackInfo ci, boolean flag) {
|
||||
// if (!flag) {
|
||||
// CampfireBlockEntityMixin self = (CampfireBlockEntityMixin) (Object) campfire;
|
||||
// self.nitori$startSleeping();
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
import net.gensokyoreimagined.nitori.common.block.entity.SleepingBlockEntity;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.entity.CampfireBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
@Mixin(CampfireBlockEntity.class)
|
||||
public abstract class CampfireBlockEntityMixin extends BlockEntity implements SleepingBlockEntity {
|
||||
|
||||
public CampfireBlockEntityMixin(BlockPos pos, BlockState state) {
|
||||
super(BlockEntityType.CAMPFIRE, pos, state);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "cookTick",
|
||||
at = @At("RETURN"),
|
||||
locals = LocalCapture.CAPTURE_FAILHARD
|
||||
)
|
||||
private static void trySleepLit(Level world, BlockPos pos, BlockState state, CampfireBlockEntity campfire, CallbackInfo ci, boolean flag) {
|
||||
if (!flag) {
|
||||
CampfireBlockEntityMixin self = (CampfireBlockEntityMixin) (Object) campfire;
|
||||
self.nitori$startSleeping();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,34 +1,34 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.world.block_entity_ticking.sleeping.campfire.unlit;
|
||||
|
||||
//import net.gensokyoreimagined.nitori.common.block.entity.SleepingBlockEntity;
|
||||
//import net.minecraft.core.BlockPos;
|
||||
//import net.minecraft.world.level.Level;
|
||||
//import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
//import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
//import net.minecraft.world.level.block.entity.CampfireBlockEntity;
|
||||
//import net.minecraft.world.level.block.state.BlockState;
|
||||
//import org.spongepowered.asm.mixin.Mixin;
|
||||
//import org.spongepowered.asm.mixin.injection.At;
|
||||
//import org.spongepowered.asm.mixin.injection.Inject;
|
||||
//import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
//import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
//
|
||||
//@Mixin(CampfireBlockEntity.class)
|
||||
//public abstract class CampfireBlockEntityMixin extends BlockEntity implements SleepingBlockEntity {
|
||||
//
|
||||
// public CampfireBlockEntityMixin(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||
// super(type, pos, state);
|
||||
// }
|
||||
//
|
||||
// @Inject(
|
||||
// method = "cooldownTick",
|
||||
// at = @At("RETURN"),
|
||||
// locals = LocalCapture.CAPTURE_FAILHARD
|
||||
// )
|
||||
// private static void trySleepLit(Level world, BlockPos pos, BlockState state, CampfireBlockEntity campfire, CallbackInfo ci, boolean flag) {
|
||||
// if (!flag) {
|
||||
// CampfireBlockEntityMixin self = (CampfireBlockEntityMixin) (Object) campfire;
|
||||
// self.nitori$startSleeping();
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
import net.gensokyoreimagined.nitori.common.block.entity.SleepingBlockEntity;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.entity.CampfireBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
@Mixin(CampfireBlockEntity.class)
|
||||
public abstract class CampfireBlockEntityMixin extends BlockEntity implements SleepingBlockEntity {
|
||||
|
||||
public CampfireBlockEntityMixin(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||
super(type, pos, state);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "cooldownTick",
|
||||
at = @At("RETURN"),
|
||||
locals = LocalCapture.CAPTURE_FAILHARD
|
||||
)
|
||||
private static void trySleepLit(Level world, BlockPos pos, BlockState state, CampfireBlockEntity campfire, CallbackInfo ci, boolean flag) {
|
||||
if (!flag) {
|
||||
CampfireBlockEntityMixin self = (CampfireBlockEntityMixin) (Object) campfire;
|
||||
self.nitori$startSleeping();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.world.block_entity_ticking.sleeping.hopper;
|
||||
|
||||
//import net.gensokyoreimagined.nitori.common.block.entity.SleepingBlockEntity;
|
||||
//import net.gensokyoreimagined.nitori.mixin.world.block_entity_ticking.sleeping.WrappedBlockEntityTickInvokerAccessor;
|
||||
//import net.minecraft.world.level.block.state.BlockState;
|
||||
//import net.minecraft.world.level.block.HopperBlock;
|
||||
//import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
//import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
//import net.minecraft.world.level.block.entity.HopperBlockEntity;
|
||||
//import net.minecraft.core.BlockPos;
|
||||
//import net.minecraft.world.level.Level;
|
||||
//import net.minecraft.world.level.block.entity.TickingBlockEntity;
|
||||
//import org.spongepowered.asm.mixin.Mixin;
|
||||
//import org.spongepowered.asm.mixin.Shadow;
|
||||
//import org.spongepowered.asm.mixin.injection.At;
|
||||
//import org.spongepowered.asm.mixin.injection.Inject;
|
||||
//import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
//import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
//
|
||||
//import java.util.function.BooleanSupplier;
|
||||
//
|
||||
//@Mixin(HopperBlockEntity.class)
|
||||
//public class HopperBlockEntityMixin extends BlockEntity implements SleepingBlockEntity {
|
||||
//
|
||||
// @Shadow
|
||||
// private long tickedGameTime;
|
||||
//
|
||||
// @Shadow
|
||||
// private native boolean isOnCooldown();
|
||||
//
|
||||
// private WrappedBlockEntityTickInvokerAccessor tickWrapper = null;
|
||||
// private TickingBlockEntity sleepingTicker = null;
|
||||
//
|
||||
// @Inject(
|
||||
// method = "tryMoveItems",
|
||||
// at = @At(value = "RETURN", ordinal = 2)
|
||||
// )
|
||||
// private static void sleepIfNoCooldownAndLocked(Level world, BlockPos pos, BlockState state, HopperBlockEntity blockEntity, BooleanSupplier booleanSupplier, CallbackInfoReturnable<Boolean> cir) {
|
||||
// if (!((HopperBlockEntityMixin) (Object) blockEntity).isOnCooldown() &&
|
||||
// !((HopperBlockEntityMixin) (Object) blockEntity).isSleeping() &&
|
||||
// !state.get(HopperBlock.ENABLED)) {
|
||||
// ((HopperBlockEntityMixin) (Object) blockEntity).lithium$startSleeping();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public WrappedBlockEntityTickInvokerAccessor lithium$getTickWrapper() {
|
||||
// return tickWrapper;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void lithium$setTickWrapper(WrappedBlockEntityTickInvokerAccessor tickWrapper) {
|
||||
// this.tickWrapper = tickWrapper;
|
||||
// this.lithium$setSleepingTicker(null);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public TickingBlockEntity lithium$getSleepingTicker() {
|
||||
// return sleepingTicker;
|
||||
// }
|
||||
//
|
||||
// public HopperBlockEntityMixin(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||
// super(type, pos, state);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void lithium$setSleepingTicker(TickingBlockEntity sleepingTicker) {
|
||||
// this.sleepingTicker = sleepingTicker;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean nitori$startSleeping() {
|
||||
// if (this.isSleeping()) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// WrappedBlockEntityTickInvokerAccessor tickWrapper = this.lithium$getTickWrapper();
|
||||
// if (tickWrapper != null) {
|
||||
// this.lithium$setSleepingTicker(tickWrapper.getWrapped());
|
||||
// tickWrapper.callSetWrapped(SleepingBlockEntity.SLEEPING_BLOCK_ENTITY_TICKER);
|
||||
//
|
||||
// // Set the last tick time to max value, so other hoppers transferring into this hopper will set it to 7gt
|
||||
// // cooldown. Then when waking up, we make sure to not tick this hopper in the same gametick.
|
||||
// // This makes the observable hopper cooldown not be different from vanilla.
|
||||
// this.tickedGameTime = Long.MAX_VALUE;
|
||||
// return true;
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// @Inject(
|
||||
// method = "setTransferCooldown",
|
||||
// at = @At("HEAD" )
|
||||
// )
|
||||
// private void wakeUpOnCooldownSet(int transferCooldown, CallbackInfo ci) {
|
||||
// if (transferCooldown == 7) {
|
||||
// if (this.tickedGameTime == Long.MAX_VALUE) {
|
||||
// this.sleepOnlyCurrentTick();
|
||||
// } else {
|
||||
// this.wakeUpNow();
|
||||
// }
|
||||
// } else if (transferCooldown > 0 && this.sleepingTicker != null) {
|
||||
// this.wakeUpNow();
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,67 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.world.block_entity_ticking.sleeping.shulker_box;
|
||||
|
||||
import net.gensokyoreimagined.nitori.common.block.entity.SleepingBlockEntity;
|
||||
import net.gensokyoreimagined.nitori.mixin.world.block_entity_ticking.sleeping.WrappedBlockEntityTickInvokerAccessor;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.TickingBlockEntity;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(ShulkerBoxBlockEntity.class)
|
||||
public class ShulkerBoxBlockEntityMixin implements SleepingBlockEntity {
|
||||
@Shadow
|
||||
private ShulkerBoxBlockEntity.AnimationStatus animationStatus;
|
||||
@Shadow
|
||||
private float progress;
|
||||
@Shadow
|
||||
private float progressOld;
|
||||
private WrappedBlockEntityTickInvokerAccessor tickWrapper = null;
|
||||
private TickingBlockEntity sleepingTicker = null;
|
||||
|
||||
@Override
|
||||
public WrappedBlockEntityTickInvokerAccessor lithium$getTickWrapper() {
|
||||
return tickWrapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lithium$setTickWrapper(WrappedBlockEntityTickInvokerAccessor tickWrapper) {
|
||||
this.tickWrapper = tickWrapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TickingBlockEntity lithium$getSleepingTicker() {
|
||||
return sleepingTicker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lithium$setSleepingTicker(TickingBlockEntity sleepingTicker) {
|
||||
this.sleepingTicker = sleepingTicker;
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "triggerEvent",
|
||||
at = @At("HEAD")
|
||||
)
|
||||
private void wakeUpOnSyncedBlockEvent(int type, int data, CallbackInfoReturnable<Boolean> cir) {
|
||||
if (this.sleepingTicker != null) {
|
||||
this.wakeUpNow();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "updateAnimation",
|
||||
at = @At(value = "RETURN")
|
||||
)
|
||||
private void sleepOnAnimationEnd(Level world, BlockPos pos, BlockState state, CallbackInfo ci) {
|
||||
if (this.animationStatus == animationStatus.CLOSED && this.progressOld == 0.0f && this.progress == 0.0f) {
|
||||
this.nitori$startSleeping();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.world.block_entity_ticking.world_border;
|
||||
|
||||
//import net.gensokyoreimagined.nitori.common.world.listeners.WorldBorderListenerOnce;
|
||||
//import net.minecraft.server.level.FullChunkStatus;
|
||||
//import net.minecraft.server.level.ServerLevel;
|
||||
//import net.minecraft.core.BlockPos;
|
||||
//import net.minecraft.world.level.ChunkPos;
|
||||
//import net.minecraft.world.level.Level;
|
||||
//import net.minecraft.world.level.border.WorldBorder;
|
||||
//import net.minecraft.world.level.border.BorderStatus;
|
||||
//import net.minecraft.world.level.chunk.LevelChunk;
|
||||
//import org.spongepowered.asm.mixin.Final;
|
||||
//import org.spongepowered.asm.mixin.Mixin;
|
||||
//import org.spongepowered.asm.mixin.Shadow;
|
||||
//import org.spongepowered.asm.mixin.injection.At;
|
||||
//import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
//
|
||||
//@Mixin(targets = "net.minecraft.world.level.chunk.LevelChunk$BoundTickingBlockEntity")
|
||||
//public abstract class DirectBlockEntityTickInvokerMixin implements WorldBorderListenerOnce {
|
||||
//
|
||||
// @Shadow
|
||||
// @Final
|
||||
// LevelChunk LevelChunk;
|
||||
//
|
||||
// @Shadow
|
||||
// public abstract BlockPos getPos();
|
||||
//
|
||||
// private byte worldBorderState = 0;
|
||||
//
|
||||
// @Redirect(
|
||||
// method = "tick",
|
||||
// at = @At(
|
||||
// value = "INVOKE",
|
||||
// target = "Lnet/minecraft/world/chunk/WorldChunk;canTickBlockEntity(Lnet/minecraft/util/math/BlockPos;)Z"
|
||||
// )
|
||||
// )
|
||||
// private boolean cachedCanTickBlockEntity(LevelChunk instance, BlockPos pos) {
|
||||
// if (this.isInsideWorldBorder()) {
|
||||
// Level world = this.LevelChunk.getLevel();
|
||||
// if (world instanceof ServerLevel serverWorld) {
|
||||
// return this.LevelChunk.getFullStatus().isOrAfter(FullChunkStatus.BLOCK_TICKING) && serverWorld.areEntitiesLoaded(ChunkPos.asLong(pos));
|
||||
// }
|
||||
// return true;
|
||||
// } else {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private boolean isInsideWorldBorder() {
|
||||
// if (this.worldBorderState == (byte) 0) {
|
||||
// this.startWorldBorderCaching();
|
||||
// }
|
||||
//
|
||||
// int worldBorderState = this.worldBorderState;
|
||||
// if ((worldBorderState & 3) == 3) {
|
||||
// return (worldBorderState & 4) != 0;
|
||||
// }
|
||||
// return this.LevelChunk.getLevel().getWorldBorder().isWithinBounds(this.getPos());
|
||||
// }
|
||||
//
|
||||
// private void startWorldBorderCaching() {
|
||||
// this.worldBorderState = (byte) 1;
|
||||
// WorldBorder worldBorder = this.LevelChunk.getLevel().getWorldBorder();
|
||||
// worldBorder.addListener(this);
|
||||
// boolean isStationary = worldBorder.getStatus() == BorderStatus.STATIONARY;
|
||||
// if (worldBorder.isWithinBounds(this.getPos())) {
|
||||
// if (isStationary || worldBorder.getStatus() == BorderStatus.GROWING) {
|
||||
// this.worldBorderState |= (byte) 6;
|
||||
// }
|
||||
// } else {
|
||||
// if (isStationary || worldBorder.getStatus() == BorderStatus.SHRINKING) {
|
||||
// this.worldBorderState |= (byte) 2;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void lithium$onWorldBorderShapeChange(WorldBorder worldBorder) {
|
||||
// this.worldBorderState = (byte) 0;
|
||||
// }
|
||||
//}
|
||||
@@ -1,23 +0,0 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.world.portal_checks;
|
||||
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.portal.PortalShape;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.EntityDimensions;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin({PortalShape.class})
|
||||
public class DisablePortalChecksMixin {
|
||||
@Inject(
|
||||
at = {@At("HEAD")},
|
||||
method = {"findCollisionFreePosition"},
|
||||
cancellable = true
|
||||
)
|
||||
private static void init(Vec3 fallback, ServerLevel world, Entity entity, EntityDimensions dimensions, CallbackInfoReturnable<Vec3> cir) {
|
||||
cir.setReturnValue(fallback);
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
// Gale - virtual thread support
|
||||
|
||||
package net.gensokyoreimagined.nitori.virtual_thread;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
/**
|
||||
* An implementation of {@link VirtualThreadService} that can create virtual threads directly.
|
||||
*
|
||||
* @author Martijn Muijsers
|
||||
*/
|
||||
final class DirectVirtualThreadService extends VirtualThreadService {
|
||||
|
||||
private DirectVirtualThreadService() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ThreadFactory createFactory() {
|
||||
// Disabled until Minecraft requires servers to have a Java version that can read class files compiled with functionality from Java 19+ on preview / Java 21+ on stable
|
||||
throw new UnsupportedOperationException();
|
||||
// return Thread.ofVirtual().factory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Thread start(@NotNull Runnable task) {
|
||||
// Disabled until Minecraft requires servers to have a Java version that can read class files compiled with functionality from Java 19+ on preview / Java 21+ on stable
|
||||
throw new UnsupportedOperationException();
|
||||
// Objects.requireNonNull(task, "The task to start a virtual thread cannot be null");
|
||||
// return Thread.ofVirtual().start(task);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A functional {@link DirectVirtualThreadService}.
|
||||
* @throws Throwable If creating virtual threads directly is not supported by the current runtime.
|
||||
* This could be any {@link Throwable}, including an {@link Exception} or an {@link Error}.
|
||||
*/
|
||||
static @NotNull DirectVirtualThreadService create() throws Throwable {
|
||||
// Disabled until Minecraft requires servers to have a Java version that can read class files compiled with functionality from Java 19+ on preview / Java 21+ on stable
|
||||
throw new UnsupportedOperationException();
|
||||
// var service = new DirectVirtualThreadService();
|
||||
// // Run some tests to verify
|
||||
// service.runTest();
|
||||
// // If we end up here, it works
|
||||
// return service;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
// Gale - virtual thread support
|
||||
|
||||
package net.gensokyoreimagined.nitori.virtual_thread;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
/**
|
||||
* An implementation of {@link VirtualThreadService} that can create virtual threads using Java reflection.
|
||||
*
|
||||
* @author Martijn Muijsers
|
||||
*/
|
||||
final class ReflectionVirtualThreadService extends VirtualThreadService {
|
||||
|
||||
/**
|
||||
* The {@link Thread}<code>#ofVirtual()</code> method.
|
||||
*/
|
||||
private final @NotNull Method Thread_ofVirtual_method;
|
||||
|
||||
/**
|
||||
* The {@link Thread}<code>.Builder#factory()</code> method.
|
||||
*/
|
||||
private final @NotNull Method Thread_Builder_factory_method;
|
||||
|
||||
/**
|
||||
* The {@link Thread}<code>.Builder#start(Runnable)</code> method.
|
||||
*/
|
||||
private final @NotNull Method Thread_Builder_start_method;
|
||||
|
||||
private ReflectionVirtualThreadService() throws Throwable {
|
||||
this.Thread_ofVirtual_method = Objects.requireNonNull(Thread.class.getMethod("ofVirtual"));
|
||||
// The Thread.Builder class
|
||||
var Thread_Builder_class = Objects.requireNonNull(Class.forName("java.lang.Thread$Builder"));
|
||||
this.Thread_Builder_factory_method = Objects.requireNonNull(Thread_Builder_class.getMethod("factory"));
|
||||
this.Thread_Builder_start_method = Objects.requireNonNull(Thread_Builder_class.getMethod("start", Runnable.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ThreadFactory createFactory() {
|
||||
try {
|
||||
return (ThreadFactory) this.Thread_Builder_factory_method.invoke(this.Thread_ofVirtual_method.invoke(null));
|
||||
} catch (Exception e) {
|
||||
// This should not be possible because it was tested in create()
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Thread start(@NotNull Runnable task) {
|
||||
Objects.requireNonNull(task, "The task to start a virtual thread cannot be null");
|
||||
try {
|
||||
return (Thread) this.Thread_Builder_start_method.invoke(this.Thread_ofVirtual_method.invoke(null), task);
|
||||
} catch (Exception e) {
|
||||
// This should not be possible because it was tested in create()
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A functional {@link ReflectionVirtualThreadService}.
|
||||
* @throws Throwable If creating virtual threads via reflection is not supported by the current runtime.
|
||||
* This could be any {@link Throwable}, including an {@link Exception} or an {@link Error}.
|
||||
*/
|
||||
static @NotNull ReflectionVirtualThreadService create() throws Throwable {
|
||||
// This will already throw something if the reflection fails
|
||||
var service = new ReflectionVirtualThreadService();
|
||||
// Run some tests to verify
|
||||
service.runTest();
|
||||
// If we end up here, it works
|
||||
return service;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
// Gale - virtual thread support
|
||||
|
||||
package net.gensokyoreimagined.nitori.virtual_thread;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
/**
|
||||
* An abstract service to create virtual threads.
|
||||
*
|
||||
* @author Martijn Muijsers
|
||||
*/
|
||||
public sealed abstract class VirtualThreadService permits ReflectionVirtualThreadService, DirectVirtualThreadService {
|
||||
|
||||
/**
|
||||
* @return A {@link ThreadFactory} that produces virtual threads.
|
||||
*/
|
||||
public abstract @NotNull ThreadFactory createFactory();
|
||||
|
||||
/**
|
||||
* @param task The runnable for the thread to execute.
|
||||
* @return A virtual thread that has been started with the given task.
|
||||
*/
|
||||
public abstract @NotNull Thread start(Runnable task);
|
||||
|
||||
/**
|
||||
* Runs a test on the {@link #createFactory} and {@link #start} methods,
|
||||
* which certainly throws some {@link Throwable} if something goes wrong.
|
||||
*/
|
||||
protected void runTest() throws Throwable {
|
||||
// This will definitely throw something if it doesn't work
|
||||
try {
|
||||
this.start(() -> {}).join();
|
||||
} catch (InterruptedException ignored) {} // Except InterruptedException, we don't care about that one
|
||||
try {
|
||||
var thread = this.createFactory().newThread(() -> {});
|
||||
thread.start();
|
||||
thread.join();
|
||||
} catch (InterruptedException ignored) {} // Except InterruptedException, we don't care about that one
|
||||
// If we end up here, it works
|
||||
}
|
||||
|
||||
private static boolean initialized = false;
|
||||
|
||||
/**
|
||||
* The {@link VirtualThreadService} for the current runtime,
|
||||
* or null if virtual threads are not supported, or if not {@link #initialized} yet.
|
||||
*/
|
||||
private static @Nullable VirtualThreadService implementation;
|
||||
|
||||
/**
|
||||
* @return Whether virtual threads are supported on the current runtime.
|
||||
*/
|
||||
public static boolean isSupported() {
|
||||
return get() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The {@link VirtualThreadService} for the current runtime,
|
||||
* or null if virtual threads are not {@linkplain #isSupported() supported}.
|
||||
*
|
||||
* This method is thread-safe only after the first time it has been fully run.
|
||||
*/
|
||||
public static @Nullable VirtualThreadService get() {
|
||||
if (!initialized) {
|
||||
initialized = true;
|
||||
try {
|
||||
implementation = DirectVirtualThreadService.create();
|
||||
} catch (Throwable ignored) {
|
||||
try {
|
||||
implementation = ReflectionVirtualThreadService.create();
|
||||
} catch (Throwable ignored2) {}
|
||||
}
|
||||
}
|
||||
return implementation;
|
||||
}
|
||||
|
||||
/**
|
||||
* The minimum major version of Java that is known to support using virtual threads
|
||||
* (although possibly behind a feature preview flag).
|
||||
*/
|
||||
public static final int minimumJavaMajorVersionWithFeaturePreview = 19;
|
||||
|
||||
/**
|
||||
* The minimum major version of Java that is known to support using virtual threads
|
||||
* even without any feature preview flags.
|
||||
*/
|
||||
public static final int minimumJavaMajorVersionWithoutFeaturePreview = 21;
|
||||
|
||||
public static int getJavaMajorVersion() {
|
||||
var version = System.getProperty("java.version");
|
||||
if (version.startsWith("1.")) {
|
||||
return version.charAt(2) - '0';
|
||||
}
|
||||
int dotIndex = version.indexOf(".");
|
||||
return Integer.parseInt(dotIndex == -1 ? version : version.substring(0, dotIndex));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
package net.gensokyoreimagined.nitori.virtual_thread;
|
||||
|
||||
/*
|
||||
Original patch:
|
||||
https://github.com/GaleMC/Gale/blob/ver/1.20.2/patches/server/0145-Virtual-thread-support.patch
|
||||
*/
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"id": "Nitori",
|
||||
"version": "1.5-SNAPSHOT",
|
||||
"version": "1.6-SNAPSHOT",
|
||||
"mixins": [
|
||||
"mixins.core.json"
|
||||
]
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"collections.chunk_tickets.SortedArraySetMixin",
|
||||
"collections.entity_by_type.TypeFilterableListMixin",
|
||||
"collections.entity_filtering.TypeFilterableListMixin",
|
||||
"collections.goals.GoalSelectorMixin",
|
||||
"collections.mob_spawning.SpawnSettingsMixin",
|
||||
"collections.fluid_submersion.EntityMixin",
|
||||
"collections.brain.BrainMixin",
|
||||
@@ -41,13 +40,7 @@
|
||||
"entity.replace_entitytype_predicates.AbstractDecorationEntityMixin",
|
||||
"entity.replace_entitytype_predicates.ItemFrameEntityMixin",
|
||||
"entity.pathfinding.TargetPredicateMixin",
|
||||
"entity.inactive_navigations.EntityNavigationMixin",
|
||||
"entity.inactive_navigations.MobEntityMixin",
|
||||
"logic.fast_bits_blockpos.OptimizedBlockPosBitsMixin",
|
||||
"logic.fast_rotations.EulerAngleMixin",
|
||||
"logic.reduce_ray_casting.BlockViewCastingMixin",
|
||||
"math.fast_blockops.BlockPosMixin",
|
||||
"math.fast_blockops.DirectionMixin",
|
||||
"math.fast_util.AxisCycleDirectionMixin$BackwardMixin",
|
||||
"math.fast_util.AxisCycleDirectionMixin$ForwardMixin",
|
||||
"math.fast_util.DirectionMixin",
|
||||
@@ -61,30 +54,29 @@
|
||||
"math.rounding.FastRoundingSurfaceBuildMixin",
|
||||
"math.sine_lut.MixinMth",
|
||||
"math.vec.FastMathVec3DMixin",
|
||||
"math.random.RandomMixin",
|
||||
"network.microopt.VarIntsMixin",
|
||||
"network.microopt.StringEncodingMixin",
|
||||
"network.block_breaking.CacheBlockBreakPacketMixin",
|
||||
"vmp.playerwatching.MixinChunkFilter",
|
||||
"vmp.playerwatching.MixinServerPlayerEntity",
|
||||
"vmp.playerwatching.optimize_nearby_player_lookups.MixinMobEntity",
|
||||
"vmp.general.collections.MixinTypeFilterableList",
|
||||
"vmp.entity.move_zero_velocity.MixinEntity",
|
||||
"network.move_zero_velocity.MixinEntity",
|
||||
"shapes.blockstate_cache.BlockMixin",
|
||||
"shapes.lazy_shape_context.EntityShapeContextMixin",
|
||||
"shapes.precompute_shape_arrays.FractionalDoubleListMixin",
|
||||
"shapes.precompute_shape_arrays.SimpleVoxelShapeMixin",
|
||||
"shapes.specialized_shapes.VoxelShapeMixin",
|
||||
"util.MixinLevelBlockEntityRetrieval",
|
||||
"util.accessors.EntityTrackingSectionAccessor",
|
||||
"util.block_tracking.AbstractBlockStateMixin",
|
||||
"util.block_entity_retrieval.WorldMixin",
|
||||
"world.block_entity_ticking.sleeping.WrappedBlockEntityTickInvokerAccessor",
|
||||
"world.block_entity_ticking.sleeping.furnace.AbstractFurnaceBlockEntityMixin",
|
||||
"world.block_entity_ticking.sleeping.brewing_stand.BrewingStandBlockEntityMixin",
|
||||
"world.block_entity_ticking.sleeping.shulker_box.ShulkerBoxBlockEntityMixin",
|
||||
"world.block_entity_ticking.sleeping.campfire.unlit.CampfireBlockEntityMixin",
|
||||
"world.block_entity_ticking.sleeping.campfire.lit.CampfireBlockEntityMixin",
|
||||
"world.block_entity_ticking.sleeping.campfire.CampfireBlockEntityMixin",
|
||||
"world.block_entity_ticking.sleeping.ServerWorldMixin",
|
||||
"world.block_entity_ticking.sleeping.WorldMixin",
|
||||
"world.block_entity_ticking.sleeping.WrappedBlockEntityTickInvokerAccessor",
|
||||
"world.block_entity_ticking.support_cache.BlockEntityMixin",
|
||||
"world.block_entity_ticking.support_cache.DirectBlockEntityTickInvokerMixin",
|
||||
"world.block_entity_ticking.support_cache.WorldChunkMixin",
|
||||
"world.portal_checks.DisablePortalChecksMixin",
|
||||
"world.blending.BlendMixin",
|
||||
"world.farmland.FarmlandBlockMixin",
|
||||
"world.biome_access.BiomeAccessMixin"
|
||||
|
||||
Reference in New Issue
Block a user