mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-12 07:16:10 +01:00
CollideCarts
- Contraptions now run their collision from a separate ticking hook - Minecart mounted contraptions now run the collision algorithm
This commit is contained in:
parent
d9105b4e60
commit
a13d9fcede
3 changed files with 135 additions and 85 deletions
|
@ -6,7 +6,7 @@ org.gradle.daemon=false
|
|||
# mod version info
|
||||
mod_version=0.3
|
||||
minecraft_version=1.15.2
|
||||
forge_version=31.2.3
|
||||
forge_version=31.2.21
|
||||
|
||||
# dependency versions
|
||||
registrate_version=0.0.3.17
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.content.contraptions.components.actors.BlockBreakingMovementBehaviour;
|
||||
import com.simibubi.create.foundation.collision.Matrix3d;
|
||||
|
@ -14,11 +22,10 @@ import com.simibubi.create.foundation.utility.VecHelper;
|
|||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.CocoaBlock;
|
||||
import net.minecraft.block.material.PushReaction;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.IProjectile;
|
||||
import net.minecraft.entity.MoverType;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
|
@ -34,21 +41,72 @@ import net.minecraft.world.World;
|
|||
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.event.TickEvent.ClientTickEvent;
|
||||
import net.minecraftforge.event.TickEvent.Phase;
|
||||
import net.minecraftforge.event.TickEvent.WorldTickEvent;
|
||||
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||
|
||||
@EventBusSubscriber
|
||||
public class ContraptionCollider {
|
||||
|
||||
static Map<Object, AxisAlignedBB> renderedBBs = new HashMap<>();
|
||||
public static boolean wasClientPlayerGrounded;
|
||||
public static Cache<World, List<WeakReference<ContraptionEntity>>> activeContraptions = CacheBuilder.newBuilder()
|
||||
.expireAfterAccess(20, SECONDS)
|
||||
.build();
|
||||
|
||||
@SubscribeEvent
|
||||
public static void addSpawnedContraptionsToCollisionList(EntityJoinWorldEvent event) {
|
||||
Entity entity = event.getEntity();
|
||||
if (!(entity instanceof ContraptionEntity))
|
||||
return;
|
||||
try {
|
||||
List<WeakReference<ContraptionEntity>> list = activeContraptions.get(event.getWorld(), ArrayList::new);
|
||||
ContraptionEntity contraption = (ContraptionEntity) entity;
|
||||
list.add(new WeakReference<>(contraption));
|
||||
} catch (ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static void playerCollisionHappensOnClientTick(ClientTickEvent event) {
|
||||
if (event.phase == Phase.START)
|
||||
return;
|
||||
ClientWorld world = Minecraft.getInstance().world;
|
||||
if (world == null)
|
||||
return;
|
||||
runCollisions(world);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void entityCollisionHappensPreWorldTick(WorldTickEvent event) {
|
||||
if (event.phase == Phase.START)
|
||||
return;
|
||||
World world = event.world;
|
||||
runCollisions(world);
|
||||
}
|
||||
|
||||
private static void runCollisions(World world) {
|
||||
List<WeakReference<ContraptionEntity>> list = activeContraptions.getIfPresent(world);
|
||||
if (list == null)
|
||||
return;
|
||||
for (Iterator<WeakReference<ContraptionEntity>> iterator = list.iterator(); iterator.hasNext();) {
|
||||
WeakReference<ContraptionEntity> weakReference = iterator.next();
|
||||
ContraptionEntity contraptionEntity = weakReference.get();
|
||||
if (contraptionEntity == null || !contraptionEntity.isAlive()) {
|
||||
iterator.remove();
|
||||
continue;
|
||||
}
|
||||
collideEntities(contraptionEntity);
|
||||
}
|
||||
}
|
||||
|
||||
public static void collideEntities(ContraptionEntity contraptionEntity) {
|
||||
if (Contraption.isFrozen())
|
||||
return;
|
||||
if (!contraptionEntity.collisionEnabled())
|
||||
return;
|
||||
|
||||
World world = contraptionEntity.getEntityWorld();
|
||||
// Vec3d contraptionMotion = contraptionEntity.getMotion();
|
||||
Contraption contraption = contraptionEntity.getContraption();
|
||||
AxisAlignedBB bounds = contraptionEntity.getBoundingBox();
|
||||
Vec3d contraptionPosition = contraptionEntity.getPositionVec();
|
||||
|
@ -61,7 +119,7 @@ public class ContraptionCollider {
|
|||
return;
|
||||
|
||||
for (Entity entity : world.getEntitiesWithinAABB((EntityType<?>) null, bounds.grow(1),
|
||||
e -> canBeCollidedWith(e))) {
|
||||
contraptionEntity::canCollideWith)) {
|
||||
if (entity instanceof PlayerEntity && !world.isRemote)
|
||||
return;
|
||||
|
||||
|
@ -70,7 +128,7 @@ public class ContraptionCollider {
|
|||
Vec3d centerY = new Vec3d(0, entity.getBoundingBox()
|
||||
.getYSize() / 2, 0);
|
||||
Vec3d position = entityPosition.subtract(contraptionPosition)
|
||||
.subtract(centerOfBlock)
|
||||
.subtract(contraptionEntity.stationary ? centerOfBlock : Vec3d.ZERO.add(0, 0.5, 0))
|
||||
.add(centerY);
|
||||
position =
|
||||
VecHelper.rotate(position, -contraptionRotation.z, -contraptionRotation.y, -contraptionRotation.x);
|
||||
|
@ -107,7 +165,7 @@ public class ContraptionCollider {
|
|||
|
||||
obb.setCenter(obb.getCenter()
|
||||
.add(intersect));
|
||||
entity.move(MoverType.PLAYER, intersect);
|
||||
entity.move(MoverType.PISTON, intersect);
|
||||
|
||||
Vec3d entityMotion = entity.getMotion();
|
||||
if (entityMotion.getX() > 0 == intersect.getX() < 0)
|
||||
|
@ -134,49 +192,10 @@ public class ContraptionCollider {
|
|||
if (entity instanceof ServerPlayerEntity)
|
||||
((ServerPlayerEntity) entity).connection.floatingTickCount = 0;
|
||||
});
|
||||
|
||||
// Vec3d positionOffset = contraptionPosition.scale(-1);
|
||||
// AxisAlignedBB entityBB = entity.getBoundingBox()
|
||||
// .offset(positionOffset)
|
||||
// .grow(1.0E-7D);
|
||||
// Vec3d entityMotion = entity.getMotion();
|
||||
// Vec3d relativeMotion = entityMotion.subtract(contraptionMotion);
|
||||
// Vec3d allowedMovement = Entity.getAllowedMovement(relativeMotion, entityBB, world,
|
||||
// ISelectionContext.forEntity(entity), potentialHits);
|
||||
// potentialHits.createStream()
|
||||
// .forEach(voxelShape -> pushEntityOutOfShape(entity, voxelShape, positionOffset, contraptionMotion));
|
||||
//
|
||||
//
|
||||
// if (allowedMovement.equals(relativeMotion))
|
||||
// continue;
|
||||
//
|
||||
// if (allowedMovement.y != relativeMotion.y) {
|
||||
// entity.handleFallDamage(entity.fallDistance, 1);
|
||||
// entity.fallDistance = 0;
|
||||
// entity.onGround = true;
|
||||
// DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> checkForClientPlayerCollision(entity));
|
||||
// }
|
||||
//
|
||||
// if (entity instanceof ServerPlayerEntity)
|
||||
// ((ServerPlayerEntity) entity).connection.floatingTickCount = 0;
|
||||
// if (entity instanceof PlayerEntity && !world.isRemote)
|
||||
// return;
|
||||
//
|
||||
// entity.setMotion(allowedMovement.add(contraptionMotion));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static boolean canBeCollidedWith(Entity e) {
|
||||
if (e instanceof PlayerEntity && e.isSpectator())
|
||||
return false;
|
||||
if (e.noClip)
|
||||
return false;
|
||||
if (e instanceof IProjectile)
|
||||
return false;
|
||||
return e.getPushReaction() == PushReaction.NORMAL;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
private static void checkForClientPlayerCollision(Entity entity) {
|
||||
if (entity != Minecraft.getInstance().player)
|
||||
|
@ -258,7 +277,8 @@ public class ContraptionCollider {
|
|||
BlockPos pos = contraption.blocks.get(p).pos;
|
||||
VoxelShape collisionShape = blockState.getCollisionShape(world, p);
|
||||
return collisionShape.withOffset(pos.getX(), pos.getY(), pos.getZ());
|
||||
}));
|
||||
})
|
||||
.filter(Predicates.not(VoxelShape::isEmpty)));
|
||||
|
||||
return potentialHits;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import org.apache.commons.lang3.tuple.MutablePair;
|
|||
import com.google.common.collect.ImmutableSet;
|
||||
import com.simibubi.create.AllEntityTypes;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.bearing.BearingContraption;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerTileEntity.CartMovementMode;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.mounted.MountedContraption;
|
||||
import com.simibubi.create.foundation.item.ItemHelper;
|
||||
|
@ -24,8 +25,11 @@ import net.minecraft.block.material.PushReaction;
|
|||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.IProjectile;
|
||||
import net.minecraft.entity.item.BoatEntity;
|
||||
import net.minecraft.entity.item.HangingEntity;
|
||||
import net.minecraft.entity.item.minecart.FurnaceMinecartEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.item.crafting.Ingredient;
|
||||
|
@ -170,7 +174,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
|||
}
|
||||
|
||||
public void collisionTick() {
|
||||
ContraptionCollider.collideEntities(this);
|
||||
// ContraptionCollider.collideEntities(this);
|
||||
}
|
||||
|
||||
public void tickAsPassenger(Entity e) {
|
||||
|
@ -233,14 +237,17 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
|||
int i = MathHelper.floor(furnaceCart.getX());
|
||||
int j = MathHelper.floor(furnaceCart.getY());
|
||||
int k = MathHelper.floor(furnaceCart.getZ());
|
||||
if (furnaceCart.world.getBlockState(new BlockPos(i, j - 1, k)).isIn(BlockTags.RAILS))
|
||||
if (furnaceCart.world.getBlockState(new BlockPos(i, j - 1, k))
|
||||
.isIn(BlockTags.RAILS))
|
||||
--j;
|
||||
|
||||
BlockPos blockpos = new BlockPos(i, j, k);
|
||||
BlockState blockstate = this.world.getBlockState(blockpos);
|
||||
if (furnaceCart.canUseRail() && blockstate.isIn(BlockTags.RAILS))
|
||||
if (fuel > 1)
|
||||
riding.setMotion(riding.getMotion().normalize().scale(1));
|
||||
riding.setMotion(riding.getMotion()
|
||||
.normalize()
|
||||
.scale(1));
|
||||
if (fuel < 5 && contraption != null) {
|
||||
ItemStack coal = ItemHelper.extract(contraption.inventory, FUEL_ITEMS, 1, false);
|
||||
if (!coal.isEmpty())
|
||||
|
@ -277,7 +284,8 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
|||
Vec3d actorPosition = new Vec3d(blockInfo.pos);
|
||||
actorPosition = actorPosition.add(actor.getActiveAreaOffset(context));
|
||||
actorPosition = VecHelper.rotate(actorPosition, angleRoll, angleYaw, anglePitch);
|
||||
actorPosition = actorPosition.add(rotationOffset).add(getAnchorVec());
|
||||
actorPosition = actorPosition.add(rotationOffset)
|
||||
.add(getAnchorVec());
|
||||
|
||||
boolean newPosVisited = false;
|
||||
BlockPos gridPosition = new BlockPos(actorPosition);
|
||||
|
@ -300,8 +308,8 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
|||
if (activeAreaOffset.mul(VecHelper.planeByNormal(new Vec3d(facing.getDirectionVec())))
|
||||
.equals(Vec3d.ZERO)) {
|
||||
if (VecHelper.onSameAxis(blockInfo.pos, BlockPos.ZERO, facing.getAxis())) {
|
||||
context.motion = new Vec3d(facing.getDirectionVec()).scale(
|
||||
facing.getAxis().getCoordinate(roll - prevRoll, yaw - prevYaw, pitch - prevPitch));
|
||||
context.motion = new Vec3d(facing.getDirectionVec()).scale(facing.getAxis()
|
||||
.getCoordinate(roll - prevRoll, yaw - prevYaw, pitch - prevPitch));
|
||||
context.relativeMotion = context.motion;
|
||||
int timer = context.data.getInt("StationaryTimer");
|
||||
if (timer > 0) {
|
||||
|
@ -504,8 +512,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doWaterSplashEffect() {
|
||||
}
|
||||
protected void doWaterSplashEffect() {}
|
||||
|
||||
public void preventMovedEntitiesFromGettingStuck() {
|
||||
Vec3d stuckTest = new Vec3d(0, -2, 0);
|
||||
|
@ -514,9 +521,11 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
|||
e.onGround = true;
|
||||
|
||||
Vec3d vec = stuckTest;
|
||||
AxisAlignedBB axisalignedbb = e.getBoundingBox().offset(0, 2, 0);
|
||||
AxisAlignedBB axisalignedbb = e.getBoundingBox()
|
||||
.offset(0, 2, 0);
|
||||
ISelectionContext iselectioncontext = ISelectionContext.forEntity(this);
|
||||
VoxelShape voxelshape = e.world.getWorldBorder().getShape();
|
||||
VoxelShape voxelshape = e.world.getWorldBorder()
|
||||
.getShape();
|
||||
Stream<VoxelShape> stream =
|
||||
VoxelShapes.compare(voxelshape, VoxelShapes.create(axisalignedbb.shrink(1.0E-7D)), IBooleanFunction.AND)
|
||||
? Stream.empty()
|
||||
|
@ -592,8 +601,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
|||
|
||||
@Override
|
||||
// Make sure nothing can move contraptions out of the way
|
||||
public void setMotion(Vec3d motionIn) {
|
||||
}
|
||||
public void setMotion(Vec3d motionIn) {}
|
||||
|
||||
@Override
|
||||
public void setPositionAndUpdate(double x, double y, double z) {
|
||||
|
@ -625,7 +633,29 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
|||
}
|
||||
|
||||
public Vec3d getRotationVec() {
|
||||
return new Vec3d(pitch, yaw, roll);
|
||||
return new Vec3d(getPitch(1), getYaw(1), getRoll(1));
|
||||
}
|
||||
|
||||
public boolean canCollideWith(Entity e) {
|
||||
if (e instanceof PlayerEntity && e.isSpectator())
|
||||
return false;
|
||||
if (e.noClip)
|
||||
return false;
|
||||
if (e instanceof HangingEntity)
|
||||
return false;
|
||||
if (e instanceof SuperGlueEntity)
|
||||
return false;
|
||||
if (e instanceof IProjectile)
|
||||
return false;
|
||||
|
||||
Entity riding = this.getRidingEntity();
|
||||
while (riding != null) {
|
||||
if (riding == e)
|
||||
return false;
|
||||
riding = riding.getRidingEntity();
|
||||
}
|
||||
|
||||
return e.getPushReaction() == PushReaction.NORMAL;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue