diff --git a/src/main/java/thut/api/entity/blockentity/BlockEntityBase.java b/src/main/java/thut/api/entity/blockentity/BlockEntityBase.java index 856ee7369e..5f693db1d5 100644 --- a/src/main/java/thut/api/entity/blockentity/BlockEntityBase.java +++ b/src/main/java/thut/api/entity/blockentity/BlockEntityBase.java @@ -64,7 +64,7 @@ public static class BlockEntityType extends EntityTyp public BlockEntityType(final EntityType.EntityFactory factory) { super(factory, MobCategory.MISC, true, false, true, true, ImmutableSet.of(), - new EntityDimensions(1, 1, true), 64, 1); + new EntityDimensions(1, 1, true), 64, 1, e -> true, e -> 64, e -> 1, null); } @Override @@ -72,6 +72,12 @@ public T customClientSpawn(final SpawnEntity packet, final Level world) { return this.create(world); } + + @Override + public boolean isBlockDangerous(BlockState p_20631_) + { + return false; + } } public static void setup() @@ -155,7 +161,7 @@ public BlockPos getOriginalPos() public Vec3 getV() { - return v; + return this.getDeltaMovement(); } public Vec3 getA() @@ -272,7 +278,7 @@ public void checkCollision() var tileV = this.getV(); var usBounds = this.getBoundingBox().inflate(Math.abs(tileV.x()), Math.abs(tileV.y()), Math.abs(tileV.z())); - usBounds = usBounds.expandTowards(0, this.getSpeedUp(), 0); + usBounds = usBounds.inflate(0, this.getSpeedUp(), 0); for (var entry : this.recentCollides.entrySet()) { @@ -298,7 +304,8 @@ public void checkCollision() var entityR = this.position().add(pos.x(), pos.y(), pos.z()); - if (newVy > 0) entityR = entityR.add(0, 0, 0); + double dvy = newVy > 0 ? newVy : 0; + entityR = entityR.add(0, dvy, 0); var entityO = this.position().subtract(xo, yo, zo); double x = entity.getX(); @@ -398,6 +405,7 @@ protected void setV(final Vec3 vec) v = vec; a = F.normalize().scalarMult(this.getAccel()).toVec3d(); this.dataSync.set(POS, Optional.of(r.add(v).add(a))); + this.setDeltaMovement(v); } } diff --git a/src/main/java/thut/api/entity/blockentity/render/RenderBlockEntity.java b/src/main/java/thut/api/entity/blockentity/render/RenderBlockEntity.java index 9da9d76cb2..1827dbd81e 100644 --- a/src/main/java/thut/api/entity/blockentity/render/RenderBlockEntity.java +++ b/src/main/java/thut/api/entity/blockentity/render/RenderBlockEntity.java @@ -70,7 +70,7 @@ public void render(final T entity, final float entityYaw, final float partialTic final IBlockEntity blockEntity = entity; var v = entity.getV(); - mat.translate(v.x(), v.y(), v.z()); + if (v.y() > 0) mat.translate(v.x(), v.y(), v.z()); final int xMin = Mth.floor(blockEntity.getMin().getX()); final int xMax = Mth.floor(blockEntity.getMax().getX()); diff --git a/src/main/java/thut/api/world/WorldTickManager.java b/src/main/java/thut/api/world/WorldTickManager.java index 2a0d56e7d1..9528c2ddf2 100644 --- a/src/main/java/thut/api/world/WorldTickManager.java +++ b/src/main/java/thut/api/world/WorldTickManager.java @@ -1,168 +1,178 @@ -package thut.api.world; - -import java.util.List; -import java.util.Map; -import java.util.function.Predicate; -import java.util.function.Supplier; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; - -import net.minecraft.resources.ResourceKey; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.Level; -import net.minecraftforge.event.TickEvent.Phase; -import net.minecraftforge.event.TickEvent.WorldTickEvent; -import net.minecraftforge.event.world.WorldEvent; -import thut.core.common.ThutCore; - -public class WorldTickManager -{ - private static class WorldData - { - private final List data = Lists.newArrayList(); - - private final ServerLevel world; - - private final List pendingRemove = Lists.newArrayList(); - private final List pendingAdd = Lists.newArrayList(); - - private boolean ticking = false; - - public WorldData(final ServerLevel world) - { - this.world = world; - } - - public void onWorldTickEnd() - { - this.ticking = true; - for (final IWorldTickListener data : this.data) data.onTickEnd(this.world); - this.ticking = false; - for (final IWorldTickListener data : this.pendingRemove) this.removeData(data); - for (final IWorldTickListener data : this.pendingAdd) this.addData(data); - this.pendingRemove.clear(); - this.pendingAdd.clear(); - } - - public void onWorldTickStart() - { - this.ticking = true; - for (final IWorldTickListener data : this.data) data.onTickStart(this.world); - this.ticking = false; - for (final IWorldTickListener data : this.pendingRemove) this.removeData(data); - for (final IWorldTickListener data : this.pendingAdd) this.addData(data); - this.pendingRemove.clear(); - this.pendingAdd.clear(); - } - - public void addData(final IWorldTickListener data) - { - if (this.data.contains(data)) return; - data.onAttach(this.world); - if (!this.ticking) this.data.add(data); - else this.pendingAdd.add(data); - } - - public void removeData(final IWorldTickListener data) - { - if (!this.ticking) - { - if (!this.data.remove(data)) return; - data.onDetach(this.world); - } - else this.pendingRemove.add(data); - } - - public void detach() - { - for (final IWorldTickListener data : this.data) data.onDetach(this.world); - } - } - - public static class StaticData - { - public final Predicate> valid; - - public final Supplier data; - - public StaticData(final Supplier data, final Predicate> valid) - { - this.data = data; - this.valid = valid; - } - } - - public static List staticData = Lists.newArrayList(); - - static Map, WorldData> dataMap = Maps.newHashMap(); - - public static Map, List> pathHelpers = Maps.newHashMap(); - - public static void registerStaticData(final Supplier data, - final Predicate> valid) - { - WorldTickManager.staticData.add(new StaticData(data, valid)); - } - - public static void addWorldData(final ResourceKey key, final IWorldTickListener data) - { - final WorldData holder = WorldTickManager.dataMap.get(key); - if (holder == null) - { - ThutCore.LOGGER.error("Adding Data before load???"); - return; - } - holder.addData(data); - } - - public static void removeWorldData(final ResourceKey key, final IWorldTickListener data) - { - final WorldData holder = WorldTickManager.dataMap.get(key); - if (holder == null) - { - ThutCore.LOGGER.error("Removing Data before load???"); - return; - } - holder.removeData(data); - } - - public static void onWorldLoad(final WorldEvent.Load event) - { - if (event.getWorld().isClientSide()) return; - if (!(event.getWorld() instanceof ServerLevel level)) return; - final ResourceKey key = level.dimension(); - if (WorldTickManager.dataMap.containsKey(key)) WorldTickManager.dataMap.get(key).detach(); - final WorldData data = new WorldData(level); - WorldTickManager.dataMap.put(key, data); - WorldTickManager.staticData.forEach(s -> { - if (s.valid.test(key)) data.addData(s.data.get()); - }); - WorldTickManager.pathHelpers.put(key, Lists.newArrayList()); - } - - public static void onWorldUnload(final WorldEvent.Unload event) - { - if (event.getWorld().isClientSide()) return; - if (!(event.getWorld() instanceof ServerLevel level)) return; - final ResourceKey key = level.dimension(); - if (WorldTickManager.dataMap.containsKey(key)) WorldTickManager.dataMap.remove(key).detach(); - WorldTickManager.pathHelpers.remove(key); - } - - public static void onWorldTick(final WorldTickEvent event) - { - if (event.world instanceof ServerLevel) - { - final ResourceKey key = event.world.dimension(); - final WorldData data = WorldTickManager.dataMap.get(key); - if (data == null) - { - ThutCore.LOGGER.error("Ticking world before load???"); - return; - } - if (event.phase == Phase.END) data.onWorldTickEnd(); - else data.onWorldTickStart(); - } - } -} +package thut.api.world; + +import java.util.List; +import java.util.Map; +import java.util.function.Predicate; +import java.util.function.Supplier; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; + +import net.minecraft.resources.ResourceKey; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.Level; +import net.minecraftforge.event.TickEvent.Phase; +import net.minecraftforge.event.TickEvent.WorldTickEvent; +import net.minecraftforge.event.world.WorldEvent; +import thut.core.common.ThutCore; + +public class WorldTickManager +{ + private static class WorldData + { + private final List data = Lists.newArrayList(); + + private final ServerLevel world; + + private final List pendingRemove = Lists.newArrayList(); + private final List pendingAdd = Lists.newArrayList(); + + private boolean ticking = false; + + public WorldData(final ServerLevel world) + { + this.world = world; + } + + public void onWorldTickEnd() + { + this.ticking = true; + for (final IWorldTickListener data : this.data) data.onTickEnd(this.world); + this.ticking = false; + for (final IWorldTickListener data : this.pendingRemove) this.removeData(data); + for (final IWorldTickListener data : this.pendingAdd) this.addData(data); + this.pendingRemove.clear(); + this.pendingAdd.clear(); + } + + public void onWorldTickStart() + { + this.ticking = true; + for (final IWorldTickListener data : this.data) data.onTickStart(this.world); + this.ticking = false; + for (final IWorldTickListener data : this.pendingRemove) this.removeData(data); + for (final IWorldTickListener data : this.pendingAdd) this.addData(data); + this.pendingRemove.clear(); + this.pendingAdd.clear(); + } + + public void addData(final IWorldTickListener data) + { + if (this.data.contains(data)) return; + data.onAttach(this.world); + if (!this.ticking) this.data.add(data); + else this.pendingAdd.add(data); + } + + public void removeData(final IWorldTickListener data) + { + if (!this.ticking) + { + if (!this.data.remove(data)) return; + data.onDetach(this.world); + } + else this.pendingRemove.add(data); + } + + public void detach() + { + for (final IWorldTickListener data : this.data) data.onDetach(this.world); + } + } + + public static class StaticData + { + public final Predicate> valid; + + public final Supplier data; + + public StaticData(final Supplier data, final Predicate> valid) + { + this.data = data; + this.valid = valid; + } + } + + public static List staticData = Lists.newArrayList(); + + static Map, WorldData> dataMap = Maps.newHashMap(); + + public static Map, List> pathHelpers = Maps.newHashMap(); + + public static void registerStaticData(final Supplier data, + final Predicate> valid) + { + WorldTickManager.staticData.add(new StaticData(data, valid)); + } + + public static void addWorldData(final ResourceKey key, final IWorldTickListener data) + { + final WorldData holder = WorldTickManager.dataMap.get(key); + if (holder == null) + { + ThutCore.LOGGER.error("Adding Data before load???"); + return; + } + holder.addData(data); + } + + public static void removeWorldData(final ResourceKey key, final IWorldTickListener data) + { + final WorldData holder = WorldTickManager.dataMap.get(key); + if (holder == null) + { + ThutCore.LOGGER.error("Removing Data before load???"); + return; + } + holder.removeData(data); + } + + public static void onWorldLoad(final WorldEvent.Load event) + { + if (event.getWorld().isClientSide()) return; + if (!(event.getWorld() instanceof ServerLevel level)) return; + final ResourceKey key = level.dimension(); + if (WorldTickManager.dataMap.containsKey(key)) WorldTickManager.dataMap.get(key).detach(); + final WorldData data = new WorldData(level); + WorldTickManager.dataMap.put(key, data); + WorldTickManager.staticData.forEach(s -> { + if (s.valid.test(key)) data.addData(s.data.get()); + }); + WorldTickManager.pathHelpers.put(key, Lists.newArrayList()); + } + + public static void onWorldUnload(final WorldEvent.Unload event) + { + if (event.getWorld().isClientSide()) return; + if (!(event.getWorld() instanceof ServerLevel level)) return; + final ResourceKey key = level.dimension(); + if (WorldTickManager.dataMap.containsKey(key)) WorldTickManager.dataMap.remove(key).detach(); + WorldTickManager.pathHelpers.remove(key); + } + + public static void onWorldTick(final WorldTickEvent event) + { + if (event.world instanceof ServerLevel) + { + // Uncomment to produce server lag for testing. +// if (event.world.getRandom().nextDouble() > 0.9) +// { +// long start = System.nanoTime(); +// int wait = event.world.getRandom().nextInt(1000000, 100000000); +// while (System.nanoTime() < start + wait) +// {} +// System.out.println("Delayed: " + (wait / 1e9d)); +// } + + final ResourceKey key = event.world.dimension(); + final WorldData data = WorldTickManager.dataMap.get(key); + if (data == null) + { + ThutCore.LOGGER.error("Ticking world before load???"); + return; + } + if (event.phase == Phase.END) data.onWorldTickEnd(); + else data.onWorldTickStart(); + } + } +}