Seats, part II
- Any living entity can now use seats - Fix client sync issues with seats - Fixed contraptions double-reversing roll and pitch values when communicating to the collision engine - Seats now transfer their passengers to a contraption when moved and back when disassembled - Attempted further refinements to the collision response of horizontally rotated contraptions - Set up a hook to inject custom interaction between players and contraption mounted blocks on right-click - Seats can now by mounted by players while assembled to a contraption - Minor refactors to the contraption class
89
src/main/java/ContraptionInteractionHandler.java
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
import org.apache.commons.lang3.mutable.MutableObject;
|
||||||
|
|
||||||
|
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
|
||||||
|
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionEntity;
|
||||||
|
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionInteractionPacket;
|
||||||
|
import com.simibubi.create.foundation.networking.AllPackets;
|
||||||
|
import com.simibubi.create.foundation.utility.RaycastHelper;
|
||||||
|
import com.simibubi.create.foundation.utility.RaycastHelper.PredicateTraceResult;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.entity.player.ClientPlayerEntity;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.BlockRayTraceResult;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.util.math.shapes.VoxelShape;
|
||||||
|
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
import net.minecraftforge.client.event.InputEvent.ClickInputEvent;
|
||||||
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||||
|
|
||||||
|
@EventBusSubscriber
|
||||||
|
public class ContraptionInteractionHandler {
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public static void rightClickingOnContraptionsGetsHandledLocally(ClickInputEvent event) {
|
||||||
|
Minecraft mc = Minecraft.getInstance();
|
||||||
|
ClientPlayerEntity player = mc.player;
|
||||||
|
if (player == null)
|
||||||
|
return;
|
||||||
|
if (mc.world == null)
|
||||||
|
return;
|
||||||
|
if (!event.isUseItem())
|
||||||
|
return;
|
||||||
|
Vec3d origin = RaycastHelper.getTraceOrigin(player);
|
||||||
|
|
||||||
|
double reach = mc.playerController.getBlockReachDistance();
|
||||||
|
if (mc.objectMouseOver != null && mc.objectMouseOver.getHitVec() != null)
|
||||||
|
reach = Math.min(mc.objectMouseOver.getHitVec().distanceTo(origin), reach);
|
||||||
|
|
||||||
|
Vec3d target = RaycastHelper.getTraceTarget(player, reach, origin);
|
||||||
|
for (ContraptionEntity contraptionEntity : mc.world.getEntitiesWithinAABB(ContraptionEntity.class,
|
||||||
|
new AxisAlignedBB(origin, target))) {
|
||||||
|
|
||||||
|
Vec3d localOrigin = contraptionEntity.toLocalVector(origin);
|
||||||
|
Vec3d localTarget = contraptionEntity.toLocalVector(target);
|
||||||
|
Contraption contraption = contraptionEntity.getContraption();
|
||||||
|
|
||||||
|
MutableObject<BlockRayTraceResult> mutableResult = new MutableObject<>();
|
||||||
|
PredicateTraceResult predicateResult = RaycastHelper.rayTraceUntil(localOrigin, localTarget, p -> {
|
||||||
|
BlockInfo blockInfo = contraption.blocks.get(p);
|
||||||
|
if (blockInfo == null)
|
||||||
|
return false;
|
||||||
|
BlockState state = blockInfo.state;
|
||||||
|
VoxelShape raytraceShape = state.getShape(Minecraft.getInstance().world, BlockPos.ZERO.down());
|
||||||
|
if (raytraceShape.isEmpty())
|
||||||
|
return false;
|
||||||
|
BlockRayTraceResult rayTrace = raytraceShape.rayTrace(localOrigin, localTarget, p);
|
||||||
|
if (rayTrace != null) {
|
||||||
|
mutableResult.setValue(rayTrace);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (predicateResult == null || predicateResult.missed())
|
||||||
|
return;
|
||||||
|
|
||||||
|
BlockRayTraceResult rayTraceResult = mutableResult.getValue();
|
||||||
|
Hand hand = event.getHand();
|
||||||
|
Direction face = rayTraceResult.getFace();
|
||||||
|
BlockPos pos = rayTraceResult.getPos();
|
||||||
|
|
||||||
|
if (!contraptionEntity.handlePlayerInteraction(player, pos, face, hand))
|
||||||
|
return;
|
||||||
|
AllPackets.channel.sendToServer(new ContraptionInteractionPacket(contraptionEntity, hand,
|
||||||
|
pos, face));
|
||||||
|
event.setCanceled(true);
|
||||||
|
event.setSwingHand(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -26,7 +26,7 @@ public class AllEntityTypes {
|
||||||
public static final RegistryEntry<EntityType<SuperGlueEntity>> SUPER_GLUE =
|
public static final RegistryEntry<EntityType<SuperGlueEntity>> SUPER_GLUE =
|
||||||
register("super_glue", SuperGlueEntity::new, EntityClassification.MISC, 10, Integer.MAX_VALUE, false, SuperGlueEntity::build);
|
register("super_glue", SuperGlueEntity::new, EntityClassification.MISC, 10, Integer.MAX_VALUE, false, SuperGlueEntity::build);
|
||||||
public static final RegistryEntry<EntityType<SeatEntity>> SEAT =
|
public static final RegistryEntry<EntityType<SeatEntity>> SEAT =
|
||||||
register("seat", SeatEntity::new, EntityClassification.MISC, 0, Integer.MAX_VALUE, false, SeatEntity::build);
|
register("seat", SeatEntity::new, EntityClassification.MISC, 5, Integer.MAX_VALUE, false, SeatEntity::build);
|
||||||
|
|
||||||
private static <T extends Entity> RegistryEntry<EntityType<T>> register(String name, IFactory<T> factory,
|
private static <T extends Entity> RegistryEntry<EntityType<T>> register(String name, IFactory<T> factory,
|
||||||
EntityClassification group, int range, int updateFrequency, boolean sendVelocity,
|
EntityClassification group, int range, int updateFrequency, boolean sendVelocity,
|
||||||
|
|
|
@ -1,17 +1,25 @@
|
||||||
package com.simibubi.create.content.contraptions.components.actors;
|
package com.simibubi.create.content.contraptions.components.actors;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import com.simibubi.create.AllShapes;
|
import com.simibubi.create.AllShapes;
|
||||||
|
import com.simibubi.create.content.contraptions.components.structureMovement.IPortableBlock;
|
||||||
|
import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.entity.MobEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.ItemGroup;
|
import net.minecraft.item.ItemGroup;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.pathfinding.PathNodeType;
|
||||||
import net.minecraft.util.ActionResultType;
|
import net.minecraft.util.ActionResultType;
|
||||||
import net.minecraft.util.Hand;
|
import net.minecraft.util.Hand;
|
||||||
import net.minecraft.util.NonNullList;
|
import net.minecraft.util.NonNullList;
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.BlockRayTraceResult;
|
import net.minecraft.util.math.BlockRayTraceResult;
|
||||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||||
|
@ -19,15 +27,16 @@ import net.minecraft.util.math.shapes.VoxelShape;
|
||||||
import net.minecraft.world.IBlockReader;
|
import net.minecraft.world.IBlockReader;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class SeatBlock extends Block {
|
public class SeatBlock extends Block implements IPortableBlock {
|
||||||
|
|
||||||
|
public static MovementBehaviour MOVEMENT = new SeatMovementBehaviour();
|
||||||
private boolean inCreativeTab;
|
private boolean inCreativeTab;
|
||||||
|
|
||||||
public SeatBlock(Properties p_i48440_1_, boolean inCreativeTab) {
|
public SeatBlock(Properties p_i48440_1_, boolean inCreativeTab) {
|
||||||
super(p_i48440_1_);
|
super(p_i48440_1_);
|
||||||
this.inCreativeTab = inCreativeTab;
|
this.inCreativeTab = inCreativeTab;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fillItemGroup(ItemGroup group, NonNullList<ItemStack> p_149666_2_) {
|
public void fillItemGroup(ItemGroup group, NonNullList<ItemStack> p_149666_2_) {
|
||||||
if (group != ItemGroup.SEARCH && !inCreativeTab)
|
if (group != ItemGroup.SEARCH && !inCreativeTab)
|
||||||
|
@ -41,8 +50,21 @@ public class SeatBlock extends Block {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLanded(IBlockReader p_176216_1_, Entity p_176216_2_) {
|
public void onLanded(IBlockReader reader, Entity entity) {
|
||||||
Blocks.PINK_BED.onLanded(p_176216_1_, p_176216_2_);
|
BlockPos pos = entity.getPosition();
|
||||||
|
if (entity instanceof PlayerEntity || !(entity instanceof LivingEntity) || isSeatOccupied(entity.world, pos)) {
|
||||||
|
Blocks.PINK_BED.onLanded(reader, entity);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (reader.getBlockState(pos)
|
||||||
|
.getBlock() != this)
|
||||||
|
return;
|
||||||
|
sitDown(entity.world, pos, entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PathNodeType getAiPathNodeType(BlockState state, IBlockReader world, BlockPos pos, MobEntity entity) {
|
||||||
|
return PathNodeType.RAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -52,17 +74,46 @@ public class SeatBlock extends Block {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ActionResultType onUse(BlockState p_225533_1_, World world, BlockPos pos, PlayerEntity player, Hand p_225533_5_, BlockRayTraceResult p_225533_6_) {
|
public ActionResultType onUse(BlockState p_225533_1_, World world, BlockPos pos, PlayerEntity player,
|
||||||
if (SeatEntity.TAKEN.containsKey(pos))
|
Hand p_225533_5_, BlockRayTraceResult p_225533_6_) {
|
||||||
return ActionResultType.FAIL;
|
if (player.isSneaking())
|
||||||
|
return ActionResultType.PASS;
|
||||||
|
|
||||||
|
List<SeatEntity> seats = world.getEntitiesWithinAABB(SeatEntity.class, new AxisAlignedBB(pos));
|
||||||
|
if (!seats.isEmpty()) {
|
||||||
|
SeatEntity seatEntity = seats.get(0);
|
||||||
|
List<Entity> passengers = seatEntity.getPassengers();
|
||||||
|
if (!passengers.isEmpty() && passengers.get(0) instanceof PlayerEntity)
|
||||||
|
return ActionResultType.PASS;
|
||||||
|
if (!world.isRemote) {
|
||||||
|
seatEntity.removePassengers();
|
||||||
|
player.startRiding(seatEntity);
|
||||||
|
}
|
||||||
|
return ActionResultType.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
if (world.isRemote)
|
if (world.isRemote)
|
||||||
return ActionResultType.SUCCESS;
|
return ActionResultType.SUCCESS;
|
||||||
|
sitDown(world, pos, player);
|
||||||
SeatEntity seat = new SeatEntity(world, pos);
|
|
||||||
world.addEntity(seat);
|
|
||||||
player.startRiding(seat);
|
|
||||||
|
|
||||||
return ActionResultType.SUCCESS;
|
return ActionResultType.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isSeatOccupied(World world, BlockPos pos) {
|
||||||
|
return !world.getEntitiesWithinAABB(SeatEntity.class, new AxisAlignedBB(pos))
|
||||||
|
.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sitDown(World world, BlockPos pos, Entity entity) {
|
||||||
|
if (world.isRemote)
|
||||||
|
return;
|
||||||
|
SeatEntity seat = new SeatEntity(world, pos);
|
||||||
|
seat.setPos(pos.getX() + .5f, pos.getY(), pos.getZ() + .5f);
|
||||||
|
world.addEntity(seat);
|
||||||
|
entity.startRiding(seat, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MovementBehaviour getMovementBehaviour() {
|
||||||
|
return MOVEMENT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.simibubi.create.content.contraptions.components.actors;
|
package com.simibubi.create.content.contraptions.components.actors;
|
||||||
|
|
||||||
import com.simibubi.create.AllEntityTypes;
|
import com.simibubi.create.AllEntityTypes;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.culling.ClippingHelperImpl;
|
import net.minecraft.client.renderer.culling.ClippingHelperImpl;
|
||||||
import net.minecraft.client.renderer.entity.EntityRenderer;
|
import net.minecraft.client.renderer.entity.EntityRenderer;
|
||||||
import net.minecraft.client.renderer.entity.EntityRendererManager;
|
import net.minecraft.client.renderer.entity.EntityRendererManager;
|
||||||
|
@ -8,18 +9,16 @@ import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityType;
|
import net.minecraft.entity.EntityType;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.network.IPacket;
|
import net.minecraft.network.IPacket;
|
||||||
|
import net.minecraft.network.PacketBuffer;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
|
||||||
import net.minecraftforge.fml.network.NetworkHooks;
|
import net.minecraftforge.fml.network.NetworkHooks;
|
||||||
|
|
||||||
import java.util.HashMap;
|
public class SeatEntity extends Entity implements IEntityAdditionalSpawnData {
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class SeatEntity extends Entity {
|
|
||||||
|
|
||||||
public static final Map<BlockPos, SeatEntity> TAKEN = new HashMap<>();
|
|
||||||
|
|
||||||
public SeatEntity(EntityType<?> p_i48580_1_, World p_i48580_2_) {
|
public SeatEntity(EntityType<?> p_i48580_1_, World p_i48580_2_) {
|
||||||
super(p_i48580_1_, p_i48580_2_);
|
super(p_i48580_1_, p_i48580_2_);
|
||||||
|
@ -27,28 +26,39 @@ public class SeatEntity extends Entity {
|
||||||
|
|
||||||
public SeatEntity(World world, BlockPos pos) {
|
public SeatEntity(World world, BlockPos pos) {
|
||||||
this(AllEntityTypes.SEAT.get(), world);
|
this(AllEntityTypes.SEAT.get(), world);
|
||||||
this.setPos(pos.getX() + 0.5, pos.getY() + 0.30, pos.getZ() + 0.5);
|
|
||||||
noClip = true;
|
noClip = true;
|
||||||
TAKEN.put(pos, this);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EntityType.Builder<?> build(EntityType.Builder<?> builder) {
|
public static EntityType.Builder<?> build(EntityType.Builder<?> builder) {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
EntityType.Builder<SeatEntity> entityBuilder = (EntityType.Builder<SeatEntity>) builder;
|
EntityType.Builder<SeatEntity> entityBuilder = (EntityType.Builder<SeatEntity>) builder;
|
||||||
return entityBuilder.size(0, 0);
|
return entityBuilder.size(0.25f, 0.35f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AxisAlignedBB getBoundingBox() {
|
||||||
|
return super.getBoundingBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPos(double x, double y, double z) {
|
||||||
|
super.setPos(x, y, z);
|
||||||
|
AxisAlignedBB bb = getBoundingBox();
|
||||||
|
Vec3d diff = new Vec3d(x, y, z).subtract(bb.getCenter());
|
||||||
|
setBoundingBox(bb.offset(diff));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMotion(Vec3d p_213317_1_) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
public void tick() {
|
||||||
if (world.isRemote)
|
if (world.isRemote)
|
||||||
return;
|
return;
|
||||||
|
boolean blockPresent = world.getBlockState(getPosition())
|
||||||
BlockPos blockPos = new BlockPos(getX(), getY(), getZ());
|
.getBlock() instanceof SeatBlock;
|
||||||
if (isBeingRidden() && world.getBlockState(blockPos).getBlock() instanceof SeatBlock)
|
if (isBeingRidden() && blockPresent)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
TAKEN.remove(blockPos);
|
|
||||||
this.remove();
|
this.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +71,7 @@ public class SeatEntity extends Entity {
|
||||||
protected void removePassenger(Entity entity) {
|
protected void removePassenger(Entity entity) {
|
||||||
super.removePassenger(entity);
|
super.removePassenger(entity);
|
||||||
Vec3d pos = entity.getPositionVec();
|
Vec3d pos = entity.getPositionVec();
|
||||||
entity.setPosition(pos.x, pos.y + 0.7, pos.z);
|
entity.setPosition(pos.x, pos.y + 0.85f, pos.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -85,7 +95,8 @@ public class SeatEntity extends Entity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldRender(SeatEntity p_225626_1_, ClippingHelperImpl p_225626_2_, double p_225626_3_, double p_225626_5_, double p_225626_7_) {
|
public boolean shouldRender(SeatEntity p_225626_1_, ClippingHelperImpl p_225626_2_, double p_225626_3_,
|
||||||
|
double p_225626_5_, double p_225626_7_) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,4 +105,10 @@ public class SeatEntity extends Entity {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeSpawnData(PacketBuffer buffer) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readSpawnData(PacketBuffer additionalData) {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.simibubi.create.content.contraptions.components.actors;
|
||||||
|
|
||||||
|
import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour;
|
||||||
|
|
||||||
|
public class SeatMovementBehaviour extends MovementBehaviour {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -24,6 +24,7 @@ import com.simibubi.create.foundation.collision.ContinuousOBBCollider.Continuous
|
||||||
import com.simibubi.create.foundation.collision.Matrix3d;
|
import com.simibubi.create.foundation.collision.Matrix3d;
|
||||||
import com.simibubi.create.foundation.collision.OrientedBB;
|
import com.simibubi.create.foundation.collision.OrientedBB;
|
||||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||||
|
import com.simibubi.create.foundation.utility.Iterate;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
@ -32,9 +33,11 @@ import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.world.ClientWorld;
|
import net.minecraft.client.world.ClientWorld;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityType;
|
import net.minecraft.entity.EntityType;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
import net.minecraft.entity.MoverType;
|
import net.minecraft.entity.MoverType;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||||
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.util.DamageSource;
|
import net.minecraft.util.DamageSource;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.Direction.Axis;
|
import net.minecraft.util.Direction.Axis;
|
||||||
|
@ -51,10 +54,12 @@ import net.minecraft.world.World;
|
||||||
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
|
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
import net.minecraftforge.common.util.Constants.NBT;
|
||||||
import net.minecraftforge.event.TickEvent.ClientTickEvent;
|
import net.minecraftforge.event.TickEvent.ClientTickEvent;
|
||||||
import net.minecraftforge.event.TickEvent.Phase;
|
import net.minecraftforge.event.TickEvent.Phase;
|
||||||
import net.minecraftforge.event.TickEvent.WorldTickEvent;
|
import net.minecraftforge.event.TickEvent.WorldTickEvent;
|
||||||
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
|
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
|
||||||
|
import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.DistExecutor;
|
import net.minecraftforge.fml.DistExecutor;
|
||||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||||
|
@ -66,7 +71,7 @@ public class ContraptionCollider {
|
||||||
new DamageSource("create.contraption_suffocate").setDamageBypassesArmor();
|
new DamageSource("create.contraption_suffocate").setDamageBypassesArmor();
|
||||||
public static boolean wasClientPlayerGrounded;
|
public static boolean wasClientPlayerGrounded;
|
||||||
public static Cache<World, List<WeakReference<ContraptionEntity>>> activeContraptions = CacheBuilder.newBuilder()
|
public static Cache<World, List<WeakReference<ContraptionEntity>>> activeContraptions = CacheBuilder.newBuilder()
|
||||||
.expireAfterAccess(40, SECONDS)
|
.expireAfterAccess(400, SECONDS)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
@ -102,6 +107,22 @@ public class ContraptionCollider {
|
||||||
runCollisions(world);
|
runCollisions(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void entitiesWhoJustDismountedGetSentToTheRightLocation(LivingUpdateEvent event) {
|
||||||
|
LivingEntity entityLiving = event.getEntityLiving();
|
||||||
|
if (entityLiving == null)
|
||||||
|
return;
|
||||||
|
if (entityLiving.world.isRemote)
|
||||||
|
return;
|
||||||
|
CompoundNBT data = entityLiving.getPersistentData();
|
||||||
|
if (!data.contains("ContraptionDismountLocation"))
|
||||||
|
return;
|
||||||
|
Vec3d position = VecHelper.readNBT(data.getList("ContraptionDismountLocation", NBT.TAG_DOUBLE));
|
||||||
|
if (entityLiving.getRidingEntity() == null)
|
||||||
|
entityLiving.setPositionAndUpdate(position.x, position.y, position.z);
|
||||||
|
data.remove("ContraptionDismountLocation");
|
||||||
|
}
|
||||||
|
|
||||||
private static void runCollisions(World world) {
|
private static void runCollisions(World world) {
|
||||||
List<WeakReference<ContraptionEntity>> list = activeContraptions.getIfPresent(world);
|
List<WeakReference<ContraptionEntity>> list = activeContraptions.getIfPresent(world);
|
||||||
if (list == null)
|
if (list == null)
|
||||||
|
@ -131,9 +152,9 @@ public class ContraptionCollider {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Vec3d centerOfBlock = VecHelper.getCenterOf(BlockPos.ZERO);
|
Vec3d centerOfBlock = VecHelper.getCenterOf(BlockPos.ZERO);
|
||||||
double conRotX = contraptionRotation.z;
|
double conRotX = contraptionRotation.x;
|
||||||
double conRotY = contraptionRotation.y;
|
double conRotY = contraptionRotation.y;
|
||||||
double conRotZ = contraptionRotation.x;
|
double conRotZ = contraptionRotation.z;
|
||||||
Vec3d conMotion = contraptionPosition.subtract(contraptionEntity.getPrevPositionVec());
|
Vec3d conMotion = contraptionPosition.subtract(contraptionEntity.getPrevPositionVec());
|
||||||
Vec3d conAngularMotion = contraptionRotation.subtract(contraptionEntity.getPrevRotationVec());
|
Vec3d conAngularMotion = contraptionRotation.subtract(contraptionEntity.getPrevRotationVec());
|
||||||
Vec3d contraptionCentreOffset = contraptionEntity.stationary ? centerOfBlock : Vec3d.ZERO.add(0, 0.5, 0);
|
Vec3d contraptionCentreOffset = contraptionEntity.stationary ? centerOfBlock : Vec3d.ZERO.add(0, 0.5, 0);
|
||||||
|
@ -180,6 +201,7 @@ public class ContraptionCollider {
|
||||||
// Prepare entity bounds
|
// Prepare entity bounds
|
||||||
OrientedBB obb = new OrientedBB(localBB);
|
OrientedBB obb = new OrientedBB(localBB);
|
||||||
obb.setRotation(rotation);
|
obb.setRotation(rotation);
|
||||||
|
motion = motion.subtract(conMotion);
|
||||||
motion = rotation.transform(motion);
|
motion = rotation.transform(motion);
|
||||||
|
|
||||||
// Vec3d visualizerOrigin = new Vec3d(10, 64, 0);
|
// Vec3d visualizerOrigin = new Vec3d(10, 64, 0);
|
||||||
|
@ -198,41 +220,48 @@ public class ContraptionCollider {
|
||||||
.forEach(shape -> shape.toBoundingBoxList()
|
.forEach(shape -> shape.toBoundingBoxList()
|
||||||
.forEach(bbs::add));
|
.forEach(bbs::add));
|
||||||
|
|
||||||
for (AxisAlignedBB bb : bbs) {
|
boolean doHorizontalPass = conRotX == 0 && conRotZ == 0;
|
||||||
Vec3d currentResponse = collisionResponse.getValue();
|
for (boolean horizontalPass : Iterate.trueAndFalse) {
|
||||||
obb.setCenter(obbCenter.add(currentResponse));
|
|
||||||
ContinuousSeparationManifold intersect = obb.intersect(bb, allowedMotion.getValue());
|
|
||||||
// OutlineParams params = CreateClient.outliner.showAABB(bb, bb.offset(visualizerOrigin))
|
|
||||||
// .withFaceTexture(AllSpecialTextures.HIGHLIGHT_CHECKERED);
|
|
||||||
// params.colored(0xffffff);
|
|
||||||
|
|
||||||
if (intersect == null)
|
for (AxisAlignedBB bb : bbs) {
|
||||||
continue;
|
Vec3d currentResponse = collisionResponse.getValue();
|
||||||
if (surfaceCollision.isFalse())
|
obb.setCenter(obbCenter.add(currentResponse));
|
||||||
surfaceCollision.setValue(intersect.isSurfaceCollision());
|
ContinuousSeparationManifold intersect = obb.intersect(bb, allowedMotion.getValue());
|
||||||
|
|
||||||
double timeOfImpact = intersect.getTimeOfImpact();
|
if (intersect == null)
|
||||||
if (timeOfImpact > 0 && timeOfImpact < 1) {
|
continue;
|
||||||
futureCollision.setTrue();
|
if ((!horizontalPass || !doHorizontalPass) && surfaceCollision.isFalse())
|
||||||
// Vec3d prev = allowedMotion.getValue();
|
surfaceCollision.setValue(intersect.isSurfaceCollision());
|
||||||
allowedMotion.setValue(intersect.getAllowedMotion(allowedMotion.getValue()));
|
|
||||||
// Debug.debugChat("Allowed Motion FROM " + prev.toString());
|
double timeOfImpact = intersect.getTimeOfImpact();
|
||||||
// Debug.debugChat("Allowed Motion TO " + allowedMotion.getValue()
|
if (timeOfImpact > 0 && timeOfImpact < 1) {
|
||||||
// .toString());
|
futureCollision.setTrue();
|
||||||
// params.colored(0x4499ff);
|
allowedMotion.setValue(intersect.getAllowedMotion(allowedMotion.getValue()));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Vec3d separation = intersect.asSeparationVec(entity.stepHeight);
|
|
||||||
if (separation != null && !separation.equals(Vec3d.ZERO)) {
|
Vec3d separation = intersect.asSeparationVec(entity.stepHeight);
|
||||||
collisionResponse.setValue(currentResponse.add(separation));
|
if (separation != null && !separation.equals(Vec3d.ZERO))
|
||||||
// Debug.debugChat("Collision " + currentResponse.add(separation)
|
collisionResponse.setValue(currentResponse.add(separation));
|
||||||
// .toString());
|
|
||||||
// params.colored(0xff9944);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!horizontalPass || !doHorizontalPass)
|
||||||
|
break;
|
||||||
|
|
||||||
|
boolean noVerticalMotionResponse = allowedMotion.getValue().y == motion.y;
|
||||||
|
boolean noVerticalCollision = collisionResponse.getValue().y == 0;
|
||||||
|
if (noVerticalCollision && noVerticalMotionResponse)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Re-run collisions with horizontal offset
|
||||||
|
collisionResponse.setValue(collisionResponse.getValue()
|
||||||
|
.mul(1, 0, 1));
|
||||||
|
allowedMotion.setValue(allowedMotion.getValue()
|
||||||
|
.mul(1, 0, 1)
|
||||||
|
.add(0, motion.y, 0));
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debug.debugChat("----");
|
|
||||||
|
|
||||||
// Resolve collision
|
// Resolve collision
|
||||||
Vec3d entityMotion = entity.getMotion();
|
Vec3d entityMotion = entity.getMotion();
|
||||||
Vec3d totalResponse = collisionResponse.getValue();
|
Vec3d totalResponse = collisionResponse.getValue();
|
||||||
|
@ -240,7 +269,8 @@ public class ContraptionCollider {
|
||||||
boolean hardCollision = !totalResponse.equals(Vec3d.ZERO);
|
boolean hardCollision = !totalResponse.equals(Vec3d.ZERO);
|
||||||
|
|
||||||
rotation.transpose();
|
rotation.transpose();
|
||||||
motionResponse = rotation.transform(motionResponse);
|
motionResponse = rotation.transform(motionResponse)
|
||||||
|
.add(conMotion);
|
||||||
totalResponse = rotation.transform(totalResponse);
|
totalResponse = rotation.transform(totalResponse);
|
||||||
rotation.transpose();
|
rotation.transpose();
|
||||||
|
|
||||||
|
@ -262,7 +292,7 @@ public class ContraptionCollider {
|
||||||
Vec3d contactPoint = entityPosition.subtract(contraptionCentreOffset)
|
Vec3d contactPoint = entityPosition.subtract(contraptionCentreOffset)
|
||||||
.subtract(contraptionPosition);
|
.subtract(contraptionPosition);
|
||||||
contactPoint =
|
contactPoint =
|
||||||
VecHelper.rotate(contactPoint, conAngularMotion.z, conAngularMotion.y, conAngularMotion.x);
|
VecHelper.rotate(contactPoint, conAngularMotion.x, conAngularMotion.y, conAngularMotion.z);
|
||||||
contactPoint = contactPoint.add(contraptionPosition)
|
contactPoint = contactPoint.add(contraptionPosition)
|
||||||
.add(contraptionCentreOffset)
|
.add(contraptionCentreOffset)
|
||||||
.add(conMotion);
|
.add(conMotion);
|
||||||
|
|
|
@ -5,12 +5,15 @@ import static com.simibubi.create.foundation.utility.AngleHelper.getShortestAngl
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.apache.commons.lang3.tuple.MutablePair;
|
import org.apache.commons.lang3.tuple.MutablePair;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.simibubi.create.AllEntityTypes;
|
import com.simibubi.create.AllEntityTypes;
|
||||||
|
import com.simibubi.create.content.contraptions.components.actors.SeatEntity;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.bearing.BearingContraption;
|
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.glue.SuperGlueEntity;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerTileEntity.CartMovementMode;
|
import com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerTileEntity.CartMovementMode;
|
||||||
|
@ -45,6 +48,7 @@ import net.minecraft.tags.BlockTags;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.DamageSource;
|
import net.minecraft.util.DamageSource;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
import net.minecraft.util.ReuseableStream;
|
import net.minecraft.util.ReuseableStream;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
@ -70,7 +74,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
protected BlockPos controllerPos;
|
protected BlockPos controllerPos;
|
||||||
protected Vec3d motionBeforeStall;
|
protected Vec3d motionBeforeStall;
|
||||||
protected boolean stationary;
|
protected boolean stationary;
|
||||||
|
protected boolean initialized;
|
||||||
final List<Entity> collidingEntities = new ArrayList<>();
|
final List<Entity> collidingEntities = new ArrayList<>();
|
||||||
|
|
||||||
private static final Ingredient FUEL_ITEMS = Ingredient.fromItems(Items.COAL, Items.CHARCOAL);
|
private static final Ingredient FUEL_ITEMS = Ingredient.fromItems(Items.COAL, Items.CHARCOAL);
|
||||||
|
@ -98,11 +102,9 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
|
|
||||||
public static ContraptionEntity createMounted(World world, Contraption contraption, float initialAngle) {
|
public static ContraptionEntity createMounted(World world, Contraption contraption, float initialAngle) {
|
||||||
ContraptionEntity entity = new ContraptionEntity(AllEntityTypes.CONTRAPTION.get(), world);
|
ContraptionEntity entity = new ContraptionEntity(AllEntityTypes.CONTRAPTION.get(), world);
|
||||||
entity.contraption = contraption;
|
entity.contraptionCreated(contraption);
|
||||||
entity.initialAngle = initialAngle;
|
entity.initialAngle = initialAngle;
|
||||||
entity.forceYaw(initialAngle);
|
entity.forceYaw(initialAngle);
|
||||||
if (contraption != null)
|
|
||||||
contraption.gatherStoredItems();
|
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,12 +118,25 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
|
|
||||||
public static ContraptionEntity createStationary(World world, Contraption contraption) {
|
public static ContraptionEntity createStationary(World world, Contraption contraption) {
|
||||||
ContraptionEntity entity = new ContraptionEntity(AllEntityTypes.STATIONARY_CONTRAPTION.get(), world);
|
ContraptionEntity entity = new ContraptionEntity(AllEntityTypes.STATIONARY_CONTRAPTION.get(), world);
|
||||||
entity.contraption = contraption;
|
entity.contraptionCreated(contraption);
|
||||||
if (contraption != null)
|
|
||||||
contraption.gatherStoredItems();
|
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void contraptionCreated(Contraption contraption) {
|
||||||
|
this.contraption = contraption;
|
||||||
|
if (contraption == null)
|
||||||
|
return;
|
||||||
|
if (world.isRemote)
|
||||||
|
return;
|
||||||
|
contraption.gatherStoredItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void contraptionInitialize() {
|
||||||
|
if (!world.isRemote)
|
||||||
|
contraption.mountPassengers(this);
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
public <T extends TileEntity & IControlContraption> ContraptionEntity controlledBy(T controller) {
|
public <T extends TileEntity & IControlContraption> ContraptionEntity controlledBy(T controller) {
|
||||||
this.controllerPos = controller.getPos();
|
this.controllerPos = controller.getPos();
|
||||||
return this;
|
return this;
|
||||||
|
@ -142,6 +157,110 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addPassenger(Entity passenger) {
|
||||||
|
super.addPassenger(passenger);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addSittingPassenger(Entity passenger, int seatIndex) {
|
||||||
|
passenger.startRiding(this, true);
|
||||||
|
if (world.isRemote)
|
||||||
|
return;
|
||||||
|
contraption.seatMapping.put(passenger.getUniqueID(), seatIndex);
|
||||||
|
AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> this),
|
||||||
|
new ContraptionSeatMappingPacket(getEntityId(), contraption.seatMapping));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void removePassenger(Entity passenger) {
|
||||||
|
Vec3d transformedVector = getPassengerPosition(passenger);
|
||||||
|
super.removePassenger(passenger);
|
||||||
|
if (world.isRemote)
|
||||||
|
return;
|
||||||
|
if (transformedVector != null)
|
||||||
|
passenger.getPersistentData()
|
||||||
|
.put("ContraptionDismountLocation", VecHelper.writeNBT(transformedVector));
|
||||||
|
contraption.seatMapping.remove(passenger.getUniqueID());
|
||||||
|
AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> this),
|
||||||
|
new ContraptionSeatMappingPacket(getEntityId(), contraption.seatMapping));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updatePassengerPosition(Entity passenger, IMoveCallback callback) {
|
||||||
|
if (!isPassenger(passenger))
|
||||||
|
return;
|
||||||
|
Vec3d transformedVector = getPassengerPosition(passenger);
|
||||||
|
if (transformedVector == null)
|
||||||
|
return;
|
||||||
|
callback.accept(passenger, transformedVector.x, transformedVector.y, transformedVector.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Vec3d getPassengerPosition(Entity passenger) {
|
||||||
|
AxisAlignedBB bb = passenger.getBoundingBox();
|
||||||
|
double ySize = bb.getYSize();
|
||||||
|
BlockPos seat = contraption.getSeat(passenger.getUniqueID());
|
||||||
|
if (seat == null)
|
||||||
|
return null;
|
||||||
|
Vec3d transformedVector = toGlobalVector(new Vec3d(seat).add(.5, passenger.getYOffset() + ySize - .15f, .5))
|
||||||
|
.add(VecHelper.getCenterOf(BlockPos.ZERO))
|
||||||
|
.subtract(0.5, ySize, 0.5);
|
||||||
|
return transformedVector;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean canFitPassenger(Entity p_184219_1_) {
|
||||||
|
return getPassengers().size() < contraption.seats.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean handlePlayerInteraction(PlayerEntity player, BlockPos localPos, Direction side,
|
||||||
|
Hand interactionHand) {
|
||||||
|
int indexOfSeat = contraption.seats.indexOf(localPos);
|
||||||
|
if (indexOfSeat == -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Eject potential existing passenger
|
||||||
|
for (Entry<UUID, Integer> entry : contraption.seatMapping.entrySet()) {
|
||||||
|
if (entry.getValue() != indexOfSeat)
|
||||||
|
continue;
|
||||||
|
for (Entity entity : getPassengers()) {
|
||||||
|
if (!entry.getKey().equals(entity.getUniqueID()))
|
||||||
|
continue;
|
||||||
|
if (entity instanceof PlayerEntity)
|
||||||
|
return false;
|
||||||
|
if (!world.isRemote) {
|
||||||
|
Vec3d transformedVector = getPassengerPosition(entity);
|
||||||
|
entity.stopRiding();
|
||||||
|
if (transformedVector != null)
|
||||||
|
entity.setPositionAndUpdate(transformedVector.x, transformedVector.y, transformedVector.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (world.isRemote)
|
||||||
|
return true;
|
||||||
|
addSittingPassenger(player, indexOfSeat);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3d toGlobalVector(Vec3d localVec) {
|
||||||
|
Vec3d rotationOffset = VecHelper.getCenterOf(BlockPos.ZERO);
|
||||||
|
localVec = localVec.subtract(rotationOffset);
|
||||||
|
localVec = VecHelper.rotate(localVec, getRotationVec());
|
||||||
|
localVec = localVec.add(rotationOffset)
|
||||||
|
.add(getAnchorVec());
|
||||||
|
return localVec;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3d toLocalVector(Vec3d globalVec) {
|
||||||
|
Vec3d rotationOffset = VecHelper.getCenterOf(BlockPos.ZERO);
|
||||||
|
globalVec = globalVec.subtract(getAnchorVec())
|
||||||
|
.subtract(rotationOffset);
|
||||||
|
globalVec = VecHelper.rotate(globalVec, getRotationVec().scale(-1));
|
||||||
|
globalVec = globalVec.add(rotationOffset);
|
||||||
|
return globalVec;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
public void tick() {
|
||||||
if (contraption == null) {
|
if (contraption == null) {
|
||||||
|
@ -149,6 +268,9 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!initialized)
|
||||||
|
contraptionInitialize();
|
||||||
|
|
||||||
checkController();
|
checkController();
|
||||||
|
|
||||||
Entity mountedEntity = getRidingEntity();
|
Entity mountedEntity = getRidingEntity();
|
||||||
|
@ -173,10 +295,6 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
super.tick();
|
super.tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void collisionTick() {
|
|
||||||
// ContraptionCollider.collideEntities(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void tickAsPassenger(Entity e) {
|
public void tickAsPassenger(Entity e) {
|
||||||
boolean rotationLock = false;
|
boolean rotationLock = false;
|
||||||
boolean pauseWhileRotating = false;
|
boolean pauseWhileRotating = false;
|
||||||
|
@ -266,10 +384,8 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
}
|
}
|
||||||
|
|
||||||
public void tickActors(Vec3d movementVector) {
|
public void tickActors(Vec3d movementVector) {
|
||||||
float anglePitch = getPitch(1);
|
Vec3d rotationVec = getRotationVec();
|
||||||
float angleYaw = getYaw(1);
|
Vec3d reversedRotationVec = rotationVec.scale(-1);
|
||||||
float angleRoll = getRoll(1);
|
|
||||||
Vec3d rotationVec = new Vec3d(angleRoll, angleYaw, anglePitch);
|
|
||||||
Vec3d rotationOffset = VecHelper.getCenterOf(BlockPos.ZERO);
|
Vec3d rotationOffset = VecHelper.getCenterOf(BlockPos.ZERO);
|
||||||
boolean stalledPreviously = contraption.stalled;
|
boolean stalledPreviously = contraption.stalled;
|
||||||
|
|
||||||
|
@ -283,7 +399,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
|
|
||||||
Vec3d actorPosition = new Vec3d(blockInfo.pos);
|
Vec3d actorPosition = new Vec3d(blockInfo.pos);
|
||||||
actorPosition = actorPosition.add(actor.getActiveAreaOffset(context));
|
actorPosition = actorPosition.add(actor.getActiveAreaOffset(context));
|
||||||
actorPosition = VecHelper.rotate(actorPosition, angleRoll, angleYaw, anglePitch);
|
actorPosition = VecHelper.rotate(actorPosition, rotationVec);
|
||||||
actorPosition = actorPosition.add(rotationOffset)
|
actorPosition = actorPosition.add(rotationOffset)
|
||||||
.add(getAnchorVec());
|
.add(getAnchorVec());
|
||||||
|
|
||||||
|
@ -295,7 +411,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
if (previousPosition != null) {
|
if (previousPosition != null) {
|
||||||
context.motion = actorPosition.subtract(previousPosition);
|
context.motion = actorPosition.subtract(previousPosition);
|
||||||
Vec3d relativeMotion = context.motion;
|
Vec3d relativeMotion = context.motion;
|
||||||
relativeMotion = VecHelper.rotate(relativeMotion, -angleRoll, -angleYaw, -anglePitch);
|
relativeMotion = VecHelper.rotate(relativeMotion, reversedRotationVec);
|
||||||
context.relativeMotion = relativeMotion;
|
context.relativeMotion = relativeMotion;
|
||||||
newPosVisited = !new BlockPos(previousPosition).equals(gridPosition)
|
newPosVisited = !new BlockPos(previousPosition).equals(gridPosition)
|
||||||
|| context.relativeMotion.length() > 0 && context.firstMovement;
|
|| context.relativeMotion.length() > 0 && context.firstMovement;
|
||||||
|
@ -429,6 +545,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void readAdditional(CompoundNBT compound) {
|
protected void readAdditional(CompoundNBT compound) {
|
||||||
|
initialized = compound.getBoolean("Initialized");
|
||||||
contraption = Contraption.fromNBT(world, compound.getCompound("Contraption"));
|
contraption = Contraption.fromNBT(world, compound.getCompound("Contraption"));
|
||||||
initialAngle = compound.getFloat("InitialAngle");
|
initialAngle = compound.getFloat("InitialAngle");
|
||||||
forceYaw(compound.contains("ForcedYaw") ? compound.getFloat("ForcedYaw") : initialAngle);
|
forceYaw(compound.contains("ForcedYaw") ? compound.getFloat("ForcedYaw") : initialAngle);
|
||||||
|
@ -479,6 +596,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
|
|
||||||
compound.putFloat("InitialAngle", initialAngle);
|
compound.putFloat("InitialAngle", initialAngle);
|
||||||
compound.putBoolean("Stalled", isStalled());
|
compound.putBoolean("Stalled", isStalled());
|
||||||
|
compound.putBoolean("Initialized", initialized);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -499,15 +617,15 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disassemble() {
|
public void disassemble() {
|
||||||
if (!isAlive()) {
|
if (!isAlive())
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
if (getContraption() != null) {
|
if (getContraption() != null) {
|
||||||
remove();
|
remove();
|
||||||
BlockPos offset = new BlockPos(getAnchorVec().add(.5, .5, .5));
|
BlockPos offset = new BlockPos(getAnchorVec().add(.5, .5, .5));
|
||||||
Vec3d rotation = new Vec3d(getRoll(1), getYaw(1), getPitch(1));
|
Vec3d rotation = getRotationVec();
|
||||||
getContraption().addBlocksToWorld(world, offset, rotation);
|
setBoundingBox(new AxisAlignedBB(0, 300, 0, 0, 300, 0));
|
||||||
preventMovedEntitiesFromGettingStuck();
|
contraption.addBlocksToWorld(world, offset, rotation, getPassengers());
|
||||||
|
// preventMovedEntitiesFromGettingStuck();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -633,11 +751,11 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vec3d getRotationVec() {
|
public Vec3d getRotationVec() {
|
||||||
return new Vec3d(getPitch(1), getYaw(1), getRoll(1));
|
return new Vec3d(getRoll(1), getYaw(1), getPitch(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vec3d getPrevRotationVec() {
|
public Vec3d getPrevRotationVec() {
|
||||||
return new Vec3d(getPitch(0), getYaw(0), getRoll(0));
|
return new Vec3d(getRoll(0), getYaw(0), getPitch(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vec3d getPrevPositionVec() {
|
public Vec3d getPrevPositionVec() {
|
||||||
|
@ -653,8 +771,12 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
return false;
|
return false;
|
||||||
if (e instanceof SuperGlueEntity)
|
if (e instanceof SuperGlueEntity)
|
||||||
return false;
|
return false;
|
||||||
|
if (e instanceof SeatEntity)
|
||||||
|
return false;
|
||||||
if (e instanceof IProjectile)
|
if (e instanceof IProjectile)
|
||||||
return false;
|
return false;
|
||||||
|
if (e.getRidingEntity() != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
Entity riding = this.getRidingEntity();
|
Entity riding = this.getRidingEntity();
|
||||||
while (riding != null) {
|
while (riding != null) {
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
package com.simibubi.create.content.contraptions.components.structureMovement;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.networking.SimplePacketBase;
|
||||||
|
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||||
|
import net.minecraft.network.PacketBuffer;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraftforge.fml.network.NetworkEvent.Context;
|
||||||
|
|
||||||
|
public class ContraptionInteractionPacket extends SimplePacketBase {
|
||||||
|
|
||||||
|
private Hand interactionHand;
|
||||||
|
private int target;
|
||||||
|
private BlockPos localPos;
|
||||||
|
private Direction face;
|
||||||
|
|
||||||
|
public ContraptionInteractionPacket(ContraptionEntity target, Hand hand, BlockPos localPos, Direction side) {
|
||||||
|
this.interactionHand = hand;
|
||||||
|
this.localPos = localPos;
|
||||||
|
this.target = target.getEntityId();
|
||||||
|
this.face = side;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContraptionInteractionPacket(PacketBuffer buffer) {
|
||||||
|
target = buffer.readInt();
|
||||||
|
int handId = buffer.readInt();
|
||||||
|
interactionHand = handId == -1 ? null : Hand.values()[handId];
|
||||||
|
localPos = buffer.readBlockPos();
|
||||||
|
face = Direction.byIndex(buffer.readShort());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(PacketBuffer buffer) {
|
||||||
|
buffer.writeInt(target);
|
||||||
|
buffer.writeInt(interactionHand == null ? -1 : interactionHand.ordinal());
|
||||||
|
buffer.writeBlockPos(localPos);
|
||||||
|
buffer.writeShort(face.getIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(Supplier<Context> context) {
|
||||||
|
context.get()
|
||||||
|
.enqueueWork(() -> {
|
||||||
|
ServerPlayerEntity sender = context.get()
|
||||||
|
.getSender();
|
||||||
|
if (sender == null)
|
||||||
|
return;
|
||||||
|
Entity entityByID = sender.getServerWorld()
|
||||||
|
.getEntityByID(target);
|
||||||
|
if (!(entityByID instanceof ContraptionEntity))
|
||||||
|
return;
|
||||||
|
ContraptionEntity contraptionEntity = (ContraptionEntity) entityByID;
|
||||||
|
if (contraptionEntity.handlePlayerInteraction(sender, localPos, face, interactionHand))
|
||||||
|
sender.swingHand(interactionHand, true);
|
||||||
|
});
|
||||||
|
context.get()
|
||||||
|
.setPacketHandled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package com.simibubi.create.content.contraptions.components.structureMovement;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.networking.SimplePacketBase;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.network.PacketBuffer;
|
||||||
|
import net.minecraftforge.fml.network.NetworkEvent.Context;
|
||||||
|
|
||||||
|
public class ContraptionSeatMappingPacket extends SimplePacketBase {
|
||||||
|
|
||||||
|
private Map<UUID, Integer> mapping;
|
||||||
|
private int entityID;
|
||||||
|
|
||||||
|
public ContraptionSeatMappingPacket(int entityID, Map<UUID, Integer> mapping) {
|
||||||
|
this.entityID = entityID;
|
||||||
|
this.mapping = mapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContraptionSeatMappingPacket(PacketBuffer buffer) {
|
||||||
|
entityID = buffer.readInt();
|
||||||
|
mapping = new HashMap<>();
|
||||||
|
short size = buffer.readShort();
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
mapping.put(buffer.readUniqueId(), (int) buffer.readShort());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(PacketBuffer buffer) {
|
||||||
|
buffer.writeInt(entityID);
|
||||||
|
buffer.writeShort(mapping.size());
|
||||||
|
mapping.forEach((k, v) -> {
|
||||||
|
buffer.writeUniqueId(k);
|
||||||
|
buffer.writeShort(v);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(Supplier<Context> context) {
|
||||||
|
context.get()
|
||||||
|
.enqueueWork(() -> {
|
||||||
|
Entity entityByID = Minecraft.getInstance().world
|
||||||
|
.getEntityByID(entityID);
|
||||||
|
if (!(entityByID instanceof ContraptionEntity))
|
||||||
|
return;
|
||||||
|
ContraptionEntity contraptionEntity = (ContraptionEntity) entityByID;
|
||||||
|
contraptionEntity.contraption.seatMapping = mapping;
|
||||||
|
});
|
||||||
|
context.get()
|
||||||
|
.setPacketHandled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -47,10 +47,6 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe
|
||||||
|
|
||||||
if (running && Contraption.isFrozen())
|
if (running && Contraption.isFrozen())
|
||||||
disassemble();
|
disassemble();
|
||||||
if (hourHand != null)
|
|
||||||
hourHand.collisionTick();
|
|
||||||
if (minuteHand != null)
|
|
||||||
minuteHand.collisionTick();
|
|
||||||
|
|
||||||
if (!world.isRemote && assembleNextTick) {
|
if (!world.isRemote && assembleNextTick) {
|
||||||
assembleNextTick = false;
|
assembleNextTick = false;
|
||||||
|
|
|
@ -208,8 +208,6 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
||||||
|
|
||||||
if (world.isRemote)
|
if (world.isRemote)
|
||||||
clientAngleDiff /= 2;
|
clientAngleDiff /= 2;
|
||||||
if (movedContraption != null)
|
|
||||||
movedContraption.collisionTick();
|
|
||||||
if (running && Contraption.isFrozen())
|
if (running && Contraption.isFrozen())
|
||||||
disassemble();
|
disassemble();
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.Direction.Axis;
|
import net.minecraft.util.Direction.Axis;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
import net.minecraft.world.IWorld;
|
import net.minecraft.world.IWorld;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
|
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
|
||||||
|
@ -91,13 +90,13 @@ public class MountedContraption extends Contraption {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeBlocksFromWorld(IWorld world, BlockPos offset) {
|
protected boolean customBlockPlacement(IWorld world, BlockPos pos, BlockState state) {
|
||||||
super.removeBlocksFromWorld(world, offset, (pos, state) -> pos.equals(anchor));
|
return AllBlocks.MINECART_ANCHOR.has(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addBlocksToWorld(World world, BlockPos offset, Vec3d rotation) {
|
protected boolean customBlockRemoval(IWorld world, BlockPos pos, BlockState state) {
|
||||||
super.addBlocksToWorld(world, offset, rotation, (pos, state) -> AllBlocks.MINECART_ANCHOR.has(state));
|
return pos.equals(anchor);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,6 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
|
||||||
super.tick();
|
super.tick();
|
||||||
|
|
||||||
if (movedContraption != null) {
|
if (movedContraption != null) {
|
||||||
movedContraption.collisionTick();
|
|
||||||
if (!movedContraption.isAlive())
|
if (!movedContraption.isAlive())
|
||||||
movedContraption = null;
|
movedContraption = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ import org.apache.commons.lang3.tuple.Pair;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.AllContraptionTypes;
|
import com.simibubi.create.content.contraptions.components.structureMovement.AllContraptionTypes;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.BlockMovementTraits;
|
import com.simibubi.create.content.contraptions.components.structureMovement.BlockMovementTraits;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
|
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity;
|
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.PistonState;
|
import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.PistonState;
|
||||||
import com.simibubi.create.foundation.config.AllConfigs;
|
import com.simibubi.create.foundation.config.AllConfigs;
|
||||||
import com.simibubi.create.foundation.utility.NBTHelper;
|
import com.simibubi.create.foundation.utility.NBTHelper;
|
||||||
|
@ -32,7 +31,6 @@ import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
import net.minecraft.world.IWorld;
|
import net.minecraft.world.IWorld;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
|
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
|
||||||
|
@ -174,44 +172,36 @@ public class PistonContraption extends Contraption {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addGlue(SuperGlueEntity entity) {
|
public BlockPos toLocalPos(BlockPos globalPos) {
|
||||||
BlockPos pos = entity.getHangingPosition();
|
return globalPos.subtract(anchor)
|
||||||
Direction direction = entity.getFacingDirection();
|
|
||||||
BlockPos localPos = pos.subtract(anchor)
|
|
||||||
.offset(orientation, -initialExtensionProgress);
|
.offset(orientation, -initialExtensionProgress);
|
||||||
this.superglue.add(Pair.of(localPos, direction));
|
|
||||||
glueToRemove.add(entity);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addBlocksToWorld(World world, BlockPos offset, Vec3d rotation) {
|
protected boolean customBlockPlacement(IWorld world, BlockPos pos, BlockState state) {
|
||||||
super.addBlocksToWorld(world, offset, rotation, (pos, state) -> {
|
BlockPos pistonPos = anchor.offset(orientation, -1);
|
||||||
BlockPos pistonPos = anchor.offset(orientation, -1);
|
BlockState pistonState = world.getBlockState(pistonPos);
|
||||||
BlockState pistonState = world.getBlockState(pistonPos);
|
TileEntity te = world.getTileEntity(pistonPos);
|
||||||
TileEntity te = world.getTileEntity(pistonPos);
|
if (pos.equals(pistonPos)) {
|
||||||
if (pos.equals(pistonPos)) {
|
if (te == null || te.isRemoved())
|
||||||
if (te == null || te.isRemoved())
|
|
||||||
return true;
|
|
||||||
if (!isExtensionPole(state) && isPiston(pistonState))
|
|
||||||
world.setBlockState(pistonPos, pistonState.with(MechanicalPistonBlock.STATE, PistonState.RETRACTED),
|
|
||||||
3 | 16);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
if (!isExtensionPole(state) && isPiston(pistonState))
|
||||||
return false;
|
world.setBlockState(pistonPos, pistonState.with(MechanicalPistonBlock.STATE, PistonState.RETRACTED),
|
||||||
});
|
3 | 16);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeBlocksFromWorld(IWorld world, BlockPos offset) {
|
protected boolean customBlockRemoval(IWorld world, BlockPos pos, BlockState state) {
|
||||||
super.removeBlocksFromWorld(world, offset, (pos, state) -> {
|
BlockPos pistonPos = anchor.offset(orientation, -1);
|
||||||
BlockPos pistonPos = anchor.offset(orientation, -1);
|
BlockState blockState = world.getBlockState(pos);
|
||||||
BlockState blockState = world.getBlockState(pos);
|
if (pos.equals(pistonPos) && isPiston(blockState)) {
|
||||||
if (pos.equals(pistonPos) && isPiston(blockState)) {
|
world.setBlockState(pos, blockState.with(MechanicalPistonBlock.STATE, PistonState.MOVING), 66 | 16);
|
||||||
world.setBlockState(pos, blockState.with(MechanicalPistonBlock.STATE, PistonState.MOVING), 66 | 16);
|
return true;
|
||||||
return true;
|
}
|
||||||
}
|
return false;
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -6,7 +6,6 @@ import com.simibubi.create.CreateClient;
|
||||||
import com.simibubi.create.foundation.collision.ContinuousOBBCollider.ContinuousSeparationManifold;
|
import com.simibubi.create.foundation.collision.ContinuousOBBCollider.ContinuousSeparationManifold;
|
||||||
import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer;
|
import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer;
|
||||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||||
import com.simibubi.create.foundation.utility.Debug;
|
|
||||||
import com.simibubi.create.foundation.utility.MatrixStacker;
|
import com.simibubi.create.foundation.utility.MatrixStacker;
|
||||||
import com.simibubi.create.foundation.utility.outliner.AABBOutline;
|
import com.simibubi.create.foundation.utility.outliner.AABBOutline;
|
||||||
|
|
||||||
|
@ -31,7 +30,6 @@ public class CollisionDebugger {
|
||||||
angle += delta;
|
angle += delta;
|
||||||
angle = (int) angle;
|
angle = (int) angle;
|
||||||
OBB.setRotation(new Matrix3d().asZRotation(AngleHelper.rad(angle)));
|
OBB.setRotation(new Matrix3d().asZRotation(AngleHelper.rad(angle)));
|
||||||
Debug.debugMessage("Angle: " + angle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void render(MatrixStack ms, SuperRenderTypeBuffer buffer) {
|
public static void render(MatrixStack ms, SuperRenderTypeBuffer buffer) {
|
||||||
|
|
|
@ -6,6 +6,8 @@ import java.util.function.Supplier;
|
||||||
|
|
||||||
import com.simibubi.create.Create;
|
import com.simibubi.create.Create;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.CancelPlayerFallPacket;
|
import com.simibubi.create.content.contraptions.components.structureMovement.CancelPlayerFallPacket;
|
||||||
|
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionInteractionPacket;
|
||||||
|
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionSeatMappingPacket;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionStallPacket;
|
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionStallPacket;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.glue.GlueEffectPacket;
|
import com.simibubi.create.content.contraptions.components.structureMovement.glue.GlueEffectPacket;
|
||||||
import com.simibubi.create.content.contraptions.relays.advanced.sequencer.ConfigureSequencedGearshiftPacket;
|
import com.simibubi.create.content.contraptions.relays.advanced.sequencer.ConfigureSequencedGearshiftPacket;
|
||||||
|
@ -45,6 +47,7 @@ public enum AllPackets {
|
||||||
CONFIGURE_SCROLLABLE(ScrollValueUpdatePacket.class, ScrollValueUpdatePacket::new),
|
CONFIGURE_SCROLLABLE(ScrollValueUpdatePacket.class, ScrollValueUpdatePacket::new),
|
||||||
CANCEL_FALL(CancelPlayerFallPacket.class, CancelPlayerFallPacket::new),
|
CANCEL_FALL(CancelPlayerFallPacket.class, CancelPlayerFallPacket::new),
|
||||||
EXTENDO_INTERACT(ExtendoGripInteractionPacket.class, ExtendoGripInteractionPacket::new),
|
EXTENDO_INTERACT(ExtendoGripInteractionPacket.class, ExtendoGripInteractionPacket::new),
|
||||||
|
CONTRAPTION_INTERACT(ContraptionInteractionPacket.class, ContraptionInteractionPacket::new),
|
||||||
PLACE_ARM(ArmPlacementPacket.class, ArmPlacementPacket::new),
|
PLACE_ARM(ArmPlacementPacket.class, ArmPlacementPacket::new),
|
||||||
|
|
||||||
// Server to Client
|
// Server to Client
|
||||||
|
@ -54,6 +57,7 @@ public enum AllPackets {
|
||||||
CONFIGURE_CONFIG(ConfigureConfigPacket.class, ConfigureConfigPacket::new),
|
CONFIGURE_CONFIG(ConfigureConfigPacket.class, ConfigureConfigPacket::new),
|
||||||
CONTRAPTION_STALL(ContraptionStallPacket.class, ContraptionStallPacket::new),
|
CONTRAPTION_STALL(ContraptionStallPacket.class, ContraptionStallPacket::new),
|
||||||
GLUE_EFFECT(GlueEffectPacket.class, GlueEffectPacket::new),
|
GLUE_EFFECT(GlueEffectPacket.class, GlueEffectPacket::new),
|
||||||
|
CONTRAPTION_SEAT_MAPPING(ContraptionSeatMappingPacket.class, ContraptionSeatMappingPacket::new),
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,10 @@ import net.minecraft.util.math.Vec3i;
|
||||||
|
|
||||||
public class VecHelper {
|
public class VecHelper {
|
||||||
|
|
||||||
|
public static Vec3d rotate(Vec3d vec, Vec3d rotationVec) {
|
||||||
|
return rotate(vec, rotationVec.x, rotationVec.y, rotationVec.z);
|
||||||
|
}
|
||||||
|
|
||||||
public static Vec3d rotate(Vec3d vec, double xRot, double yRot, double zRot) {
|
public static Vec3d rotate(Vec3d vec, double xRot, double yRot, double zRot) {
|
||||||
return rotate(rotate(rotate(vec, xRot, Axis.X), yRot, Axis.Y), zRot, Axis.Z);
|
return rotate(rotate(rotate(vec, xRot, Axis.X), yRot, Axis.Y), zRot, Axis.Z);
|
||||||
}
|
}
|
||||||
|
|
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 306 B |
Before Width: | Height: | Size: 387 B After Width: | Height: | Size: 379 B |
Before Width: | Height: | Size: 389 B After Width: | Height: | Size: 392 B |
Before Width: | Height: | Size: 385 B After Width: | Height: | Size: 389 B |
Before Width: | Height: | Size: 389 B After Width: | Height: | Size: 401 B |
Before Width: | Height: | Size: 385 B After Width: | Height: | Size: 375 B |
Before Width: | Height: | Size: 387 B After Width: | Height: | Size: 390 B |
Before Width: | Height: | Size: 391 B After Width: | Height: | Size: 398 B |
Before Width: | Height: | Size: 407 B After Width: | Height: | Size: 412 B |
Before Width: | Height: | Size: 390 B After Width: | Height: | Size: 403 B |
Before Width: | Height: | Size: 386 B After Width: | Height: | Size: 398 B |
Before Width: | Height: | Size: 387 B After Width: | Height: | Size: 404 B |
Before Width: | Height: | Size: 404 B After Width: | Height: | Size: 408 B |
Before Width: | Height: | Size: 407 B After Width: | Height: | Size: 413 B |
Before Width: | Height: | Size: 387 B After Width: | Height: | Size: 399 B |
Before Width: | Height: | Size: 400 B After Width: | Height: | Size: 416 B |
Before Width: | Height: | Size: 387 B After Width: | Height: | Size: 404 B |