mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-23 21:46:40 +01:00
Flimsy Collision
- Fixed server crash on startup - Fixed crash when entities get killed by anything other than players - Pulleys no longer force push blocks below them - Drill and Saw now applies damage to entities while moved in a contraption - Made tooltip formatting a tad more lenient - Added contraption collision to Pistons and Pulleys - applied by stationary blocks, other contraptions and entities. (needs polish)
This commit is contained in:
parent
2c21902f1f
commit
6031d9fce1
22 changed files with 497 additions and 382 deletions
|
@ -1,9 +1,12 @@
|
|||
package com.simibubi.create.foundation.block;
|
||||
|
||||
import net.minecraft.client.renderer.color.IBlockColor;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
public interface IHaveColorHandler {
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public IBlockColor getColorHandler();
|
||||
|
||||
}
|
||||
|
|
|
@ -53,9 +53,8 @@ public class TooltipHelper {
|
|||
|
||||
for (int i = 0; i < words.length; i++) {
|
||||
String word = words[i];
|
||||
if (word.matches("_.+_")) {
|
||||
word = highlightColor + word.substring(1, word.length() - 1) + defaultColor;
|
||||
}
|
||||
if (word.matches("_.+_.?"))
|
||||
word = highlightColor + word.replaceAll("\\_", "") + defaultColor;
|
||||
|
||||
boolean lastWord = i == words.length - 1;
|
||||
|
||||
|
|
|
@ -5,8 +5,11 @@ import com.simibubi.create.modules.contraptions.components.contraptions.Movement
|
|||
import com.simibubi.create.modules.contraptions.components.contraptions.MovementContext;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.NBTUtil;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
@ -28,17 +31,28 @@ public class BlockBreakingMovementBehaviour extends MovementBehaviour {
|
|||
|
||||
if (world.isRemote)
|
||||
return;
|
||||
if (stateVisited.getCollisionShape(world, pos).isEmpty())
|
||||
if (stateVisited.getCollisionShape(world, pos).isEmpty()) {
|
||||
DamageSource damageSource = getDamageSource();
|
||||
if (damageSource == null)
|
||||
return;
|
||||
for (Entity entity : world.getEntitiesWithinAABB(Entity.class, new AxisAlignedBB(pos))) {
|
||||
float damage = (float) MathHelper.clamp(Math.abs(context.relativeMotion.length() * 10) + 1, 5, 20);
|
||||
entity.attackEntityFrom(damageSource, damage);
|
||||
entity.setMotion(entity.getMotion().add(context.relativeMotion.scale(3)));
|
||||
}
|
||||
return;
|
||||
if (stateVisited.getBlockHardness(world, pos) == -1)
|
||||
return;
|
||||
if (!canBreak(stateVisited))
|
||||
}
|
||||
if (!canBreak(world, pos, stateVisited))
|
||||
return;
|
||||
|
||||
context.data.put("BreakingPos", NBTUtil.writeBlockPos(pos));
|
||||
context.stall = true;
|
||||
}
|
||||
|
||||
protected DamageSource getDamageSource() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopMoving(MovementContext context) {
|
||||
CompoundNBT data = context.data;
|
||||
|
@ -84,7 +98,7 @@ public class BlockBreakingMovementBehaviour extends MovementBehaviour {
|
|||
BlockState stateToBreak = world.getBlockState(breakingPos);
|
||||
float blockHardness = stateToBreak.getBlockHardness(world, breakingPos);
|
||||
|
||||
if (!BlockBreakingKineticTileEntity.isBreakable(stateToBreak, blockHardness) || !canBreak(stateToBreak)) {
|
||||
if (!canBreak(world, breakingPos, stateToBreak)) {
|
||||
if (destroyProgress != 0) {
|
||||
destroyProgress = 0;
|
||||
data.remove("Progress");
|
||||
|
@ -117,12 +131,12 @@ public class BlockBreakingMovementBehaviour extends MovementBehaviour {
|
|||
data.putInt("Progress", destroyProgress);
|
||||
}
|
||||
|
||||
protected boolean canBreak(BlockState state) {
|
||||
return true;
|
||||
public boolean canBreak(World world, BlockPos breakingPos, BlockState state) {
|
||||
float blockHardness = state.getBlockHardness(world, breakingPos);
|
||||
return BlockBreakingKineticTileEntity.isBreakable(state, blockHardness);
|
||||
}
|
||||
|
||||
protected void onBlockBroken(MovementContext context, BlockPos pos) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
|||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.MovementContext;
|
||||
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
@ -26,5 +27,10 @@ public class DrillMovementBehaviour extends BlockBreakingMovementBehaviour {
|
|||
public SuperByteBuffer renderInContraption(MovementContext context) {
|
||||
return DrillTileEntityRenderer.renderInContraption(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DamageSource getDamageSource() {
|
||||
return DrillBlock.damageSourceDrill;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import net.minecraft.block.BlockState;
|
|||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
@ -22,15 +23,15 @@ public class SawMovementBehaviour extends BlockBreakingMovementBehaviour {
|
|||
public boolean isActive(MovementContext context) {
|
||||
return SawBlock.isHorizontal(context.state);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Vec3d getActiveAreaOffset(MovementContext context) {
|
||||
return new Vec3d(context.state.get(SawBlock.FACING).getDirectionVec()).scale(.65f);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean canBreak(BlockState state) {
|
||||
return super.canBreak(state) && state.isIn(BlockTags.LOGS);
|
||||
public boolean canBreak(World world, BlockPos breakingPos, BlockState state) {
|
||||
return super.canBreak(world, breakingPos, state) && state.isIn(BlockTags.LOGS);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -57,4 +58,9 @@ public class SawMovementBehaviour extends BlockBreakingMovementBehaviour {
|
|||
entity.setMotion(context.relativeMotion.scale(distance / 20f));
|
||||
world.addEntity(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DamageSource getDamageSource() {
|
||||
return SawBlock.damageSourceSaw;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -192,7 +192,10 @@ public abstract class Contraption {
|
|||
return false;
|
||||
ChassisTileEntity chassis = (ChassisTileEntity) te;
|
||||
chassis.addAttachedChasses(frontier, visited);
|
||||
for (BlockPos blockPos : chassis.getIncludedBlockPositions(movementDirection, false))
|
||||
List<BlockPos> includedBlockPositions = chassis.getIncludedBlockPositions(movementDirection, false);
|
||||
if (includedBlockPositions == null)
|
||||
return false;
|
||||
for (BlockPos blockPos : includedBlockPositions)
|
||||
if (!visited.contains(blockPos))
|
||||
frontier.add(blockPos);
|
||||
return true;
|
||||
|
@ -259,7 +262,7 @@ public abstract class Contraption {
|
|||
NBTUtil.readBlockState(comp.getCompound("Block")),
|
||||
comp.contains("Data") ? comp.getCompound("Data") : null);
|
||||
blocks.put(info.pos, info);
|
||||
|
||||
|
||||
if (world.isRemote) {
|
||||
Block block = info.state.getBlock();
|
||||
BlockRenderLayer renderLayer = block.getRenderLayer();
|
||||
|
@ -407,6 +410,8 @@ public abstract class Contraption {
|
|||
if (AllBlocks.SAW.typeOf(state))
|
||||
state = state.with(SawBlock.RUNNING, false);
|
||||
|
||||
if (world.getBlockState(targetPos).getBlockHardness(world, targetPos) == -1)
|
||||
continue;
|
||||
world.destroyBlock(targetPos, world.getBlockState(targetPos).getCollisionShape(world, targetPos).isEmpty());
|
||||
world.setBlockState(targetPos, state, 3 | BlockFlags.IS_MOVING);
|
||||
TileEntity tileEntity = world.getTileEntity(targetPos);
|
||||
|
|
|
@ -0,0 +1,251 @@
|
|||
package com.simibubi.create.modules.contraptions.components.contraptions;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.modules.contraptions.components.actors.BlockBreakingMovementBehaviour;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.material.PushReaction;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.MoverType;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.Direction.AxisDirection;
|
||||
import net.minecraft.util.ReuseableStream;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
|
||||
|
||||
public class ContraptionCollider {
|
||||
|
||||
static Map<Object, AxisAlignedBB> renderedBBs = new HashMap<>();
|
||||
|
||||
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();
|
||||
|
||||
if (contraption == null)
|
||||
return;
|
||||
if (bounds == null)
|
||||
return;
|
||||
|
||||
for (Entity entity : world.getEntitiesWithinAABB((EntityType<?>) null, bounds.grow(1),
|
||||
e -> e.getPushReaction() == PushReaction.NORMAL)) {
|
||||
|
||||
ReuseableStream<VoxelShape> potentialHits =
|
||||
getPotentiallyCollidedShapes(world, contraption, contraptionPosition, entity);
|
||||
if (potentialHits.createStream().count() == 0)
|
||||
continue;
|
||||
|
||||
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));
|
||||
|
||||
if (allowedMovement.equals(relativeMotion))
|
||||
continue;
|
||||
if (allowedMovement.y != relativeMotion.y) {
|
||||
entity.fall(entity.fallDistance, 1);
|
||||
entity.fallDistance = 0;
|
||||
entity.onGround = true;
|
||||
}
|
||||
|
||||
if (entity instanceof PlayerEntity && !world.isRemote)
|
||||
return;
|
||||
|
||||
entity.setMotion(allowedMovement.add(contraptionMotion));
|
||||
entity.velocityChanged = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void pushEntityOutOfShape(Entity entity, VoxelShape voxelShape, Vec3d positionOffset) {
|
||||
AxisAlignedBB entityBB = entity.getBoundingBox().offset(positionOffset);
|
||||
Vec3d entityMotion = entity.getMotion();
|
||||
|
||||
if (!voxelShape.toBoundingBoxList().stream().anyMatch(entityBB::intersects))
|
||||
return;
|
||||
|
||||
AxisAlignedBB shapeBB = voxelShape.getBoundingBox();
|
||||
Direction bestSide = Direction.DOWN;
|
||||
double bestOffset = 100;
|
||||
double finalOffset = 0;
|
||||
|
||||
for (Direction face : Direction.values()) {
|
||||
Axis axis = face.getAxis();
|
||||
double d = axis == Axis.X ? entityBB.getXSize() + shapeBB.getXSize()
|
||||
: axis == Axis.Y ? entityBB.getYSize() + shapeBB.getYSize()
|
||||
: entityBB.getZSize() + shapeBB.getZSize();
|
||||
d = d + .5f;
|
||||
|
||||
Vec3d nudge = new Vec3d(face.getDirectionVec()).scale(d);
|
||||
AxisAlignedBB nudgedBB = entityBB.offset(nudge.getX(), nudge.getY(), nudge.getZ());
|
||||
double nudgeDistance = face.getAxisDirection() == AxisDirection.POSITIVE ? -d : d;
|
||||
double offset = voxelShape.getAllowedOffset(face.getAxis(), nudgedBB, nudgeDistance);
|
||||
double abs = Math.abs(nudgeDistance - offset);
|
||||
if (abs < Math.abs(bestOffset) && abs != 0) {
|
||||
bestOffset = abs;
|
||||
finalOffset = abs;
|
||||
bestSide = face;
|
||||
}
|
||||
}
|
||||
|
||||
if (bestOffset != 0) {
|
||||
entity.move(MoverType.SELF, new Vec3d(bestSide.getDirectionVec()).scale(finalOffset));
|
||||
boolean positive = bestSide.getAxisDirection() == AxisDirection.POSITIVE;
|
||||
|
||||
double clamped;
|
||||
switch (bestSide.getAxis()) {
|
||||
case X:
|
||||
clamped = positive ? Math.max(0, entityMotion.x) : Math.min(0, entityMotion.x);
|
||||
entity.setMotion(clamped, entityMotion.y, entityMotion.z);
|
||||
break;
|
||||
case Y:
|
||||
clamped = positive ? Math.max(0, entityMotion.y) : Math.min(0, entityMotion.y);
|
||||
entity.setMotion(entityMotion.x, clamped, entityMotion.z);
|
||||
entity.fall(entity.fallDistance, 1);
|
||||
entity.fallDistance = 0;
|
||||
entity.onGround = true;
|
||||
break;
|
||||
case Z:
|
||||
clamped = positive ? Math.max(0, entityMotion.z) : Math.min(0, entityMotion.z);
|
||||
entity.setMotion(entityMotion.x, entityMotion.y, clamped);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ReuseableStream<VoxelShape> getPotentiallyCollidedShapes(World world, Contraption contraption,
|
||||
Vec3d contraptionPosition, Entity entity) {
|
||||
AxisAlignedBB blockScanBB = entity.getBoundingBox().offset(contraptionPosition.scale(-1)).grow(.5f);
|
||||
BlockPos min = new BlockPos(blockScanBB.minX, blockScanBB.minY, blockScanBB.minZ);
|
||||
BlockPos max = new BlockPos(blockScanBB.maxX, blockScanBB.maxY, blockScanBB.maxZ);
|
||||
|
||||
ReuseableStream<VoxelShape> potentialHits =
|
||||
new ReuseableStream<>(BlockPos.getAllInBox(min, max).filter(contraption.blocks::containsKey).map(p -> {
|
||||
BlockState blockState = contraption.blocks.get(p).state;
|
||||
BlockPos pos = contraption.blocks.get(p).pos;
|
||||
VoxelShape collisionShape = blockState.getCollisionShape(world, p);
|
||||
return collisionShape.withOffset(pos.getX(), pos.getY(), pos.getZ());
|
||||
}));
|
||||
|
||||
return potentialHits;
|
||||
}
|
||||
|
||||
public static boolean collideBlocks(ContraptionEntity contraptionEntity) {
|
||||
if (Contraption.isFrozen())
|
||||
return true;
|
||||
if (!contraptionEntity.collisionEnabled())
|
||||
return false;
|
||||
|
||||
World world = contraptionEntity.getEntityWorld();
|
||||
Vec3d motion = contraptionEntity.getMotion();
|
||||
Contraption contraption = contraptionEntity.getContraption();
|
||||
AxisAlignedBB bounds = contraptionEntity.getBoundingBox();
|
||||
Vec3d position = contraptionEntity.getPositionVec();
|
||||
BlockPos gridPos = new BlockPos(position);
|
||||
|
||||
if (contraption == null)
|
||||
return false;
|
||||
if (bounds == null)
|
||||
return false;
|
||||
if (motion.equals(Vec3d.ZERO))
|
||||
return false;
|
||||
|
||||
Direction movementDirection = Direction.getFacingFromVector(motion.x, motion.y, motion.z);
|
||||
|
||||
// Blocks in the world
|
||||
if (movementDirection.getAxisDirection() == AxisDirection.POSITIVE)
|
||||
gridPos = gridPos.offset(movementDirection);
|
||||
if (isCollidingWithWorld(world, contraption, gridPos, movementDirection))
|
||||
return true;
|
||||
|
||||
// Other moving Contraptions
|
||||
for (ContraptionEntity otherContraptionEntity : world.getEntitiesWithinAABB(ContraptionEntity.class,
|
||||
bounds.grow(1), e -> !e.equals(contraptionEntity))) {
|
||||
|
||||
if (!otherContraptionEntity.collisionEnabled())
|
||||
continue;
|
||||
|
||||
Vec3d otherMotion = otherContraptionEntity.getMotion();
|
||||
Contraption otherContraption = otherContraptionEntity.getContraption();
|
||||
AxisAlignedBB otherBounds = otherContraptionEntity.getBoundingBox();
|
||||
Vec3d otherPosition = otherContraptionEntity.getPositionVec();
|
||||
|
||||
if (otherContraption == null)
|
||||
return false;
|
||||
if (otherBounds == null)
|
||||
return false;
|
||||
|
||||
if (!bounds.offset(motion).intersects(otherBounds.offset(otherMotion)))
|
||||
continue;
|
||||
|
||||
for (BlockPos colliderPos : contraption.getColliders(world, movementDirection)) {
|
||||
colliderPos = colliderPos.add(gridPos).subtract(new BlockPos(otherPosition));
|
||||
if (!otherContraption.blocks.containsKey(colliderPos))
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isCollidingWithWorld(World world, Contraption contraption, BlockPos anchor,
|
||||
Direction movementDirection) {
|
||||
for (BlockPos pos : contraption.getColliders(world, movementDirection)) {
|
||||
BlockPos colliderPos = pos.add(anchor);
|
||||
|
||||
if (!world.isBlockPresent(colliderPos))
|
||||
return true;
|
||||
|
||||
BlockState collidedState = world.getBlockState(colliderPos);
|
||||
BlockInfo blockInfo = contraption.blocks.get(pos);
|
||||
|
||||
if (blockInfo.state.getBlock() instanceof IPortableBlock) {
|
||||
IPortableBlock block = (IPortableBlock) blockInfo.state.getBlock();
|
||||
if (block.getMovementBehaviour() instanceof BlockBreakingMovementBehaviour) {
|
||||
BlockBreakingMovementBehaviour behaviour =
|
||||
(BlockBreakingMovementBehaviour) block.getMovementBehaviour();
|
||||
if (!behaviour.canBreak(world, colliderPos, collidedState)
|
||||
&& !collidedState.getCollisionShape(world, pos).isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (AllBlocks.PULLEY_MAGNET.typeOf(collidedState) && pos.equals(BlockPos.ZERO)
|
||||
&& movementDirection == Direction.UP)
|
||||
continue;
|
||||
|
||||
if (!collidedState.getMaterial().isReplaceable()
|
||||
&& !collidedState.getCollisionShape(world, colliderPos).isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -9,7 +9,9 @@ import com.simibubi.create.AllEntities;
|
|||
import com.simibubi.create.AllPackets;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.bearing.BearingContraption;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.piston.LinearActuatorTileEntity;
|
||||
|
||||
import net.minecraft.block.material.PushReaction;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
|
@ -93,6 +95,10 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
|||
return this;
|
||||
}
|
||||
|
||||
public boolean collisionEnabled() {
|
||||
return stationary && controllerTE instanceof LinearActuatorTileEntity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (contraption == null) {
|
||||
|
@ -102,52 +108,19 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
|||
|
||||
attachToController();
|
||||
|
||||
Entity e = getRidingEntity();
|
||||
if (e != null) {
|
||||
Entity riding = e;
|
||||
while (riding.getRidingEntity() != null)
|
||||
riding = riding.getRidingEntity();
|
||||
Vec3d movementVector = riding.getMotion();
|
||||
if (riding instanceof BoatEntity)
|
||||
movementVector = new Vec3d(posX - prevPosX, posY - prevPosY, posZ - prevPosZ);
|
||||
Vec3d motion = movementVector.normalize();
|
||||
if (motion.length() > 0) {
|
||||
targetYaw = yawFromVector(motion);
|
||||
if (targetYaw < 0)
|
||||
targetYaw += 360;
|
||||
if (yaw < 0)
|
||||
yaw += 360;
|
||||
}
|
||||
|
||||
// if (Math.abs(getShortestAngleDiff(yaw, targetYaw)) >= 175) {
|
||||
// initialAngle += 180;
|
||||
// yaw += 180;
|
||||
// prevYaw = yaw;
|
||||
// } else {
|
||||
float speed = 0.2f;
|
||||
prevYaw = yaw;
|
||||
yaw = angleLerp(speed, yaw, targetYaw);
|
||||
// }
|
||||
|
||||
boolean wasStalled = isStalled();
|
||||
tickActors(movementVector);
|
||||
if (isStalled()) {
|
||||
if (!wasStalled)
|
||||
motionBeforeStall = riding.getMotion();
|
||||
riding.setMotion(0, 0, 0);
|
||||
}
|
||||
|
||||
if (wasStalled && !isStalled()) {
|
||||
riding.setMotion(motionBeforeStall);
|
||||
motionBeforeStall = Vec3d.ZERO;
|
||||
}
|
||||
|
||||
super.tick();
|
||||
Entity mountedEntity = getRidingEntity();
|
||||
if (mountedEntity != null) {
|
||||
tickAsPassenger(mountedEntity);
|
||||
return;
|
||||
}
|
||||
|
||||
if (getMotion().length() > 1 / 4098f)
|
||||
move(getMotion().x, getMotion().y, getMotion().z);
|
||||
if (getMotion().length() < 1 / 4098f)
|
||||
setMotion(Vec3d.ZERO);
|
||||
|
||||
move(getMotion().x, getMotion().y, getMotion().z);
|
||||
if (ContraptionCollider.collideBlocks(this))
|
||||
controllerTE.collided();
|
||||
|
||||
tickActors(new Vec3d(posX - prevPosX, posY - prevPosY, posZ - prevPosZ));
|
||||
|
||||
prevYaw = yaw;
|
||||
|
@ -156,6 +129,46 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
|||
|
||||
super.tick();
|
||||
}
|
||||
|
||||
public void collisionTick() {
|
||||
ContraptionCollider.collideEntities(this);
|
||||
}
|
||||
|
||||
public void tickAsPassenger(Entity e) {
|
||||
Entity riding = e;
|
||||
while (riding.getRidingEntity() != null)
|
||||
riding = riding.getRidingEntity();
|
||||
Vec3d movementVector = riding.getMotion();
|
||||
if (riding instanceof BoatEntity)
|
||||
movementVector = new Vec3d(posX - prevPosX, posY - prevPosY, posZ - prevPosZ);
|
||||
Vec3d motion = movementVector.normalize();
|
||||
|
||||
if (motion.length() > 0) {
|
||||
targetYaw = yawFromVector(motion);
|
||||
if (targetYaw < 0)
|
||||
targetYaw += 360;
|
||||
if (yaw < 0)
|
||||
yaw += 360;
|
||||
}
|
||||
|
||||
prevYaw = yaw;
|
||||
yaw = angleLerp(0.2f, yaw, targetYaw);
|
||||
|
||||
boolean wasStalled = isStalled();
|
||||
tickActors(movementVector);
|
||||
if (isStalled()) {
|
||||
if (!wasStalled)
|
||||
motionBeforeStall = riding.getMotion();
|
||||
riding.setMotion(0, 0, 0);
|
||||
}
|
||||
|
||||
if (wasStalled && !isStalled()) {
|
||||
riding.setMotion(motionBeforeStall);
|
||||
motionBeforeStall = Vec3d.ZERO;
|
||||
}
|
||||
|
||||
super.tick();
|
||||
}
|
||||
|
||||
public void tickActors(Vec3d movementVector) {
|
||||
float anglePitch = getPitch(1);
|
||||
|
@ -237,14 +250,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
|||
}
|
||||
}
|
||||
|
||||
public void moveTo(double x, double y, double z) {
|
||||
move(x - posX, y - posY, z - posZ);
|
||||
}
|
||||
|
||||
public void move(double x, double y, double z) {
|
||||
|
||||
// Collision and stuff
|
||||
|
||||
setPosition(posX + x, posY + y, posZ + z);
|
||||
}
|
||||
|
||||
|
@ -259,9 +265,6 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
|||
}
|
||||
|
||||
public void rotate(double roll, double yaw, double pitch) {
|
||||
|
||||
// Collision and stuff
|
||||
|
||||
this.yaw += yaw;
|
||||
this.pitch += pitch;
|
||||
this.roll += roll;
|
||||
|
@ -397,9 +400,8 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
|||
|
||||
public void disassemble() {
|
||||
if (getContraption() != null) {
|
||||
float yaw = getYaw(1);
|
||||
getContraption().disassemble(world, new BlockPos(getPositionVec().add(.5, .5, .5)),
|
||||
new Vec3d(getRoll(1), yaw, getPitch(1)));
|
||||
new Vec3d(getRoll(1), getYaw(1), getPitch(1)));
|
||||
}
|
||||
remove();
|
||||
}
|
||||
|
@ -440,8 +442,13 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
|||
}
|
||||
|
||||
@Override
|
||||
// Make sure nothing can move contraptions out of the way
|
||||
public void setMotion(Vec3d motionIn) {
|
||||
// Make sure nothing can move contraptions out of the way
|
||||
}
|
||||
|
||||
@Override
|
||||
public PushReaction getPushReaction() {
|
||||
return PushReaction.IGNORE;
|
||||
}
|
||||
|
||||
public void setContraptionMotion(Vec3d vec) {
|
||||
|
|
|
@ -68,4 +68,6 @@ public interface IControlContraption {
|
|||
|
||||
}
|
||||
|
||||
public void collided();
|
||||
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ public class ClockworkBearingBlock extends BearingBlock implements IWithTileEnti
|
|||
if (!worldIn.isRemote) {
|
||||
withTileEntityDo(worldIn, pos, te -> {
|
||||
if (te.running) {
|
||||
te.disassembleConstruct();
|
||||
te.disassemble();
|
||||
return;
|
||||
}
|
||||
te.assembleNextTick = true;
|
||||
|
|
|
@ -46,7 +46,7 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe
|
|||
}
|
||||
|
||||
if (running && Contraption.isFrozen())
|
||||
disassembleConstruct();
|
||||
disassemble();
|
||||
|
||||
if (!world.isRemote && assembleNextTick) {
|
||||
assembleNextTick = false;
|
||||
|
@ -57,12 +57,11 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe
|
|||
hourHand.getContraption().stop(world);
|
||||
if (minuteHand != null)
|
||||
minuteHand.getContraption().stop(world);
|
||||
disassembleConstruct();
|
||||
disassemble();
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
assembleConstruct();
|
||||
}
|
||||
} else
|
||||
assemble();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -148,7 +147,7 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe
|
|||
return speed;
|
||||
}
|
||||
|
||||
public void assembleConstruct() {
|
||||
public void assemble() {
|
||||
Direction direction = getBlockState().get(BlockStateProperties.FACING);
|
||||
|
||||
// Collect Construct
|
||||
|
@ -182,14 +181,14 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe
|
|||
sendData();
|
||||
}
|
||||
|
||||
public void disassembleConstruct() {
|
||||
public void disassemble() {
|
||||
if (!running)
|
||||
return;
|
||||
|
||||
|
||||
hourAngle = 0;
|
||||
minuteAngle = 0;
|
||||
applyRotations();
|
||||
|
||||
|
||||
if (hourHand != null) {
|
||||
hourHand.disassemble();
|
||||
}
|
||||
|
@ -280,8 +279,12 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe
|
|||
@Override
|
||||
public void remove() {
|
||||
if (!world.isRemote)
|
||||
disassembleConstruct();
|
||||
disassemble();
|
||||
super.remove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collided() {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ public class MechanicalBearingBlock extends BearingBlock implements IWithTileEnt
|
|||
if (!worldIn.isRemote) {
|
||||
withTileEntityDo(worldIn, pos, te -> {
|
||||
if (te.running) {
|
||||
te.disassembleConstruct();
|
||||
te.disassemble();
|
||||
return;
|
||||
}
|
||||
te.assembleNextTick = true;
|
||||
|
|
|
@ -81,7 +81,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
|||
@Override
|
||||
public void remove() {
|
||||
if (!world.isRemote)
|
||||
disassembleConstruct();
|
||||
disassemble();
|
||||
super.remove();
|
||||
}
|
||||
|
||||
|
@ -144,7 +144,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
|||
return speed;
|
||||
}
|
||||
|
||||
public void assembleConstruct() {
|
||||
public void assemble() {
|
||||
Direction direction = getBlockState().get(BlockStateProperties.FACING);
|
||||
|
||||
// Collect Construct
|
||||
|
@ -168,7 +168,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
|||
updateGeneratedRotation();
|
||||
}
|
||||
|
||||
public void disassembleConstruct() {
|
||||
public void disassemble() {
|
||||
if (!running)
|
||||
return;
|
||||
if (movedContraption != null)
|
||||
|
@ -190,7 +190,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
|||
clientAngleDiff /= 2;
|
||||
|
||||
if (running && Contraption.isFrozen())
|
||||
disassembleConstruct();
|
||||
disassemble();
|
||||
|
||||
if (!world.isRemote && assembleNextTick) {
|
||||
assembleNextTick = false;
|
||||
|
@ -201,13 +201,13 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
|||
|| movedContraption.getContraption().blocks.isEmpty())) {
|
||||
if (movedContraption != null)
|
||||
movedContraption.getContraption().stop(world);
|
||||
disassembleConstruct();
|
||||
disassemble();
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
if (speed == 0 && !isWindmill)
|
||||
return;
|
||||
assembleConstruct();
|
||||
assemble();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -275,4 +275,8 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
|||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collided() {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -50,16 +50,23 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
|
|||
super.tick();
|
||||
boolean contraptionPresent = movedContraption != null;
|
||||
|
||||
if (contraptionPresent)
|
||||
if (contraptionPresent) {
|
||||
movedContraption.collisionTick();
|
||||
if (!movedContraption.isAlive())
|
||||
movedContraption = null;
|
||||
}
|
||||
|
||||
if (world.isRemote)
|
||||
clientOffsetDiff *= .75f;
|
||||
|
||||
if (waitingForSpeedChange) {
|
||||
if (waitingForSpeedChange && contraptionPresent) {
|
||||
if (world.isRemote) {
|
||||
float syncSpeed = clientOffsetDiff / 2f;
|
||||
offset += syncSpeed;
|
||||
movedContraption.setContraptionMotion(toMotionVector(syncSpeed));
|
||||
return;
|
||||
}
|
||||
movedContraption.setContraptionMotion(Vec3d.ZERO);
|
||||
// movedContraption.setMotion(Vec3d.ZERO);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -72,7 +79,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
|
|||
sendData();
|
||||
return;
|
||||
}
|
||||
assembleConstruct();
|
||||
assemble();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -96,6 +103,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
|
|||
offset = offset <= 0 ? 0 : extensionRange;
|
||||
if (!world.isRemote) {
|
||||
applyContraptionMotion();
|
||||
applyContraptionPosition();
|
||||
tryDisassemble();
|
||||
if (waitingForSpeedChange) {
|
||||
forceMove = true;
|
||||
|
@ -134,7 +142,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
|
|||
public void remove() {
|
||||
this.removed = true;
|
||||
if (!world.isRemote)
|
||||
disassembleConstruct();
|
||||
disassemble();
|
||||
super.remove();
|
||||
}
|
||||
|
||||
|
@ -185,9 +193,9 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
|
|||
|
||||
}
|
||||
|
||||
protected abstract void assembleConstruct();
|
||||
public abstract void disassemble();
|
||||
|
||||
protected abstract void disassembleConstruct();
|
||||
protected abstract void assemble();
|
||||
|
||||
protected abstract int getExtensionRange();
|
||||
|
||||
|
@ -203,7 +211,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
|
|||
|
||||
protected void tryDisassemble() {
|
||||
if (removed) {
|
||||
disassembleConstruct();
|
||||
disassemble();
|
||||
return;
|
||||
}
|
||||
if (movementMode.get() == MovementMode.MOVE_NEVER_PLACE) {
|
||||
|
@ -215,7 +223,18 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
|
|||
waitingForSpeedChange = true;
|
||||
return;
|
||||
}
|
||||
disassembleConstruct();
|
||||
disassemble();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collided() {
|
||||
if (world.isRemote) {
|
||||
waitingForSpeedChange = true;
|
||||
return;
|
||||
}
|
||||
offset = getGridOffset(offset - getMovementSpeed());
|
||||
applyContraptionPosition();
|
||||
tryDisassemble();
|
||||
}
|
||||
|
||||
protected void applyContraptionMotion() {
|
||||
|
@ -229,6 +248,8 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
|
|||
}
|
||||
|
||||
protected void applyContraptionPosition() {
|
||||
if (movedContraption == null)
|
||||
return;
|
||||
Vec3d vec = toPosition(offset);
|
||||
movedContraption.setPosition(vec.x, vec.y, vec.z);
|
||||
if (getSpeed() == 0 || waitingForSpeedChange)
|
||||
|
|
|
@ -5,6 +5,7 @@ import com.simibubi.create.AllTileEntities;
|
|||
import com.simibubi.create.foundation.behaviour.ValueBoxTransform;
|
||||
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
|
||||
import com.simibubi.create.modules.contraptions.base.IRotate;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionCollider;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.DirectionalExtenderScrollOptionSlot;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock.PistonState;
|
||||
|
@ -39,11 +40,20 @@ public class MechanicalPistonTileEntity extends LinearActuatorTileEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void assembleConstruct() {
|
||||
public void assemble() {
|
||||
Direction direction = getBlockState().get(BlockStateProperties.FACING);
|
||||
|
||||
// Collect Construct
|
||||
PistonContraption contraption = PistonContraption.movePistonAt(world, pos, direction, getMovementSpeed() < 0);
|
||||
Direction movementDirection = getSpeed() > 0 ? direction : direction.getOpposite();
|
||||
|
||||
if (contraption != null) {
|
||||
BlockPos anchor = contraption.getAnchor().offset(direction, contraption.initialExtensionProgress);
|
||||
if (ContraptionCollider.isCollidingWithWorld(world, contraption, anchor.offset(movementDirection),
|
||||
movementDirection))
|
||||
contraption = null;
|
||||
}
|
||||
|
||||
if (contraption == null)
|
||||
return;
|
||||
|
||||
|
@ -69,7 +79,7 @@ public class MechanicalPistonTileEntity extends LinearActuatorTileEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void disassembleConstruct() {
|
||||
public void disassemble() {
|
||||
if (!running)
|
||||
return;
|
||||
if (!removed)
|
||||
|
@ -86,6 +96,13 @@ public class MechanicalPistonTileEntity extends LinearActuatorTileEntity {
|
|||
AllBlocks.MECHANICAL_PISTON.get().onBlockHarvested(world, pos, getBlockState(), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collided() {
|
||||
super.collided();
|
||||
if (!running && getSpeed() > 0)
|
||||
assembleNextTick = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getMovementSpeed() {
|
||||
float movementSpeed = getSpeed() / 512f;
|
||||
|
@ -138,82 +155,4 @@ public class MechanicalPistonTileEntity extends LinearActuatorTileEntity {
|
|||
: ((PistonContraption) movedContraption.getContraption()).initialExtensionProgress;
|
||||
}
|
||||
|
||||
// private boolean hasBlockCollisions(float newOffset) {
|
||||
// if (PistonContraption.isFrozen())
|
||||
// return true;
|
||||
//
|
||||
// Direction movementDirection = getBlockState().get(BlockStateProperties.FACING);
|
||||
// BlockPos relativePos = BlockPos.ZERO.offset(movementDirection, getModulatedOffset(newOffset));
|
||||
//
|
||||
// // Other moving Pistons
|
||||
// int maxPossibleRange = parameters.maxPistonPoles.get() + parameters.maxChassisRange.get()
|
||||
// + parameters.maxChassisForTranslation.get();
|
||||
// Iterator<MechanicalPistonTileEntity> iterator = Create.constructHandler.getOtherMovingPistonsInWorld(this)
|
||||
// .iterator();
|
||||
// pistonLoop: while (iterator.hasNext()) {
|
||||
// MechanicalPistonTileEntity otherPiston = iterator.next();
|
||||
//
|
||||
// if (otherPiston == this)
|
||||
// continue;
|
||||
// if (!otherPiston.running || otherPiston.movedContraption == null) {
|
||||
// iterator.remove();
|
||||
// continue;
|
||||
// }
|
||||
// if (otherPiston.pos.manhattanDistance(pos) > maxPossibleRange * 2)
|
||||
// continue;
|
||||
//
|
||||
// Direction otherMovementDirection = otherPiston.getBlockState().get(BlockStateProperties.FACING);
|
||||
// BlockPos otherRelativePos = BlockPos.ZERO.offset(otherMovementDirection,
|
||||
// getModulatedOffset(otherPiston.offset));
|
||||
//
|
||||
// for (AxisAlignedBB tBB : Arrays.asList(movedContraption.constructCollisionBox,
|
||||
// movedContraption.pistonCollisionBox)) {
|
||||
// for (AxisAlignedBB oBB : Arrays.asList(otherPiston.movedContraption.constructCollisionBox,
|
||||
// otherPiston.movedContraption.pistonCollisionBox)) {
|
||||
// if (tBB == null || oBB == null)
|
||||
// continue;
|
||||
//
|
||||
// boolean frontalCollision = otherMovementDirection == movementDirection.getOpposite();
|
||||
// BlockPos thisColliderOffset = relativePos.offset(movementDirection,
|
||||
// frontalCollision ? (getMovementSpeed() > 0 ? 1 : -1) : 0);
|
||||
// AxisAlignedBB thisBB = tBB.offset(thisColliderOffset);
|
||||
// AxisAlignedBB otherBB = oBB.offset(otherRelativePos);
|
||||
//
|
||||
// if (thisBB.intersects(otherBB)) {
|
||||
// boolean actuallyColliding = false;
|
||||
// for (BlockPos colliderPos : movedContraption.getColliders(world, movementDirection)) {
|
||||
// colliderPos = colliderPos.add(thisColliderOffset).subtract(otherRelativePos);
|
||||
// if (!otherPiston.movedContraption.blocks.containsKey(colliderPos))
|
||||
// continue;
|
||||
// actuallyColliding = true;
|
||||
// }
|
||||
// if (!actuallyColliding)
|
||||
// continue pistonLoop;
|
||||
// hadCollisionWithOtherPiston = true;
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// if (!running)
|
||||
// return false;
|
||||
//
|
||||
// // Other Blocks in world
|
||||
// for (BlockPos pos : movedContraption.getColliders(world,
|
||||
// getMovementSpeed() > 0 ? movementDirection : movementDirection.getOpposite())) {
|
||||
// BlockPos colliderPos = pos.add(relativePos);
|
||||
//
|
||||
// if (!world.isBlockPresent(colliderPos))
|
||||
// return true;
|
||||
// if (!world.getBlockState(colliderPos).getMaterial().isReplaceable()
|
||||
// && !world.getBlockState(colliderPos).getCollisionShape(world, colliderPos).isEmpty())
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// return false;
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
|
@ -1,167 +0,0 @@
|
|||
/*package com.simibubi.create.modules.contraptions.receivers.constructs.piston;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||
|
||||
@EventBusSubscriber
|
||||
public class MovingConstructHandler {
|
||||
|
||||
static List<AxisAlignedBB> renderedBBs = new LinkedList<>();
|
||||
static Map<IWorld, List<MechanicalPistonTileEntity>> movingPistons = new HashMap<>();
|
||||
|
||||
public void onLoadWorld(IWorld world) {
|
||||
movingPistons.put(world, new ArrayList<>());
|
||||
Create.logger.debug("Prepared Construct List for " + world.getDimension().getType().getRegistryName());
|
||||
}
|
||||
|
||||
public void onUnloadWorld(IWorld world) {
|
||||
movingPistons.remove(world);
|
||||
Create.logger.debug("Removed Construct List for " + world.getDimension().getType().getRegistryName());
|
||||
}
|
||||
|
||||
// public static void moveEntities(MechanicalPistonTileEntity te, float movementSpeed, Direction movementDirection,
|
||||
// float newOffset) {
|
||||
// if (PistonContraption.isFrozen())
|
||||
// return;
|
||||
//
|
||||
// World world = te.getWorld();
|
||||
// Vec3d movementVec = new Vec3d(te.getBlockState().get(BlockStateProperties.FACING).getDirectionVec());
|
||||
// Contraption construct = te.movedContraption;
|
||||
//
|
||||
//// if (world.isRemote) {
|
||||
//// renderedBBs.clear();
|
||||
//// if (construct.pistonCollisionBox != null)
|
||||
//// renderedBBs.add(construct.pistonCollisionBox.offset(te.getConstructOffset(0)));
|
||||
//// if (construct.constructCollisionBox != null)
|
||||
//// renderedBBs.add(construct.constructCollisionBox.offset(te.getConstructOffset(0)));
|
||||
////
|
||||
//// }
|
||||
//
|
||||
// if (construct.getCollisionBoxFront() != null) {
|
||||
// AxisAlignedBB constructBB = construct.getCollisionBoxFront().offset(te.getConstructOffset(0)).grow(.5f);
|
||||
//
|
||||
// for (Entity entity : world.getEntitiesWithinAABB((EntityType<?>) null, constructBB,
|
||||
// e -> e.getPushReaction() == PushReaction.NORMAL)) {
|
||||
//
|
||||
// AxisAlignedBB entityScanBB = entity.getBoundingBox().offset(movementVec.scale(-1 * newOffset))
|
||||
// .grow(.5f);
|
||||
// BlockPos min = new BlockPos(entityScanBB.minX, entityScanBB.minY, entityScanBB.minZ);
|
||||
// BlockPos max = new BlockPos(entityScanBB.maxX, entityScanBB.maxY, entityScanBB.maxZ);
|
||||
//
|
||||
// Stream<VoxelShape> hits = BlockPos.getAllInBox(min, max).filter(construct.blocks::containsKey)
|
||||
// .map(pos -> {
|
||||
// Vec3d vec = new Vec3d(pos).add(te.getConstructOffset(te.getMovementSpeed() > 0 ? 1 : 0));
|
||||
// return construct.blocks.get(pos).state.getShape(world, new BlockPos(vec)).withOffset(vec.x,
|
||||
// vec.y, vec.z);
|
||||
// });
|
||||
// ReuseableStream<VoxelShape> potentialHits = new ReuseableStream<>(hits);
|
||||
//
|
||||
// AxisAlignedBB entityBB = entity.getBoundingBox();
|
||||
// Vec3d motion = entity.getMotion();
|
||||
// Vec3d movement = new Vec3d(movementDirection.getDirectionVec()).scale(-movementSpeed).add(motion);
|
||||
// Vec3d allowedMovement = Entity.getAllowedMovement(movement, entityBB, world,
|
||||
// ISelectionContext.forEntity(entity), potentialHits);
|
||||
//
|
||||
// for (Object shape : potentialHits.createStream().toArray()) {
|
||||
// VoxelShape voxelShape = (VoxelShape) shape;
|
||||
// if (!entityBB.intersects(voxelShape.getBoundingBox()))
|
||||
// continue;
|
||||
//
|
||||
// Direction bestSide = Direction.DOWN;
|
||||
// double bestOffset = 100;
|
||||
// double finalOffset = 0;
|
||||
//
|
||||
// for (Direction face : Direction.values()) {
|
||||
// Axis axis = face.getAxis();
|
||||
// double d = axis == Axis.X ? entityBB.getXSize()
|
||||
// : axis == Axis.Y ? entityBB.getYSize() : entityBB.getZSize();
|
||||
// d = d + 1.5f;
|
||||
//
|
||||
// Vec3d nudge = new Vec3d(face.getDirectionVec()).scale(d);
|
||||
// AxisAlignedBB nudgedBB = entityBB.offset(nudge.getX(), nudge.getY(), nudge.getZ());
|
||||
// double nudgeDistance = face.getAxisDirection() == AxisDirection.POSITIVE ? -d : d;
|
||||
// double offset = voxelShape.getAllowedOffset(face.getAxis(), nudgedBB, nudgeDistance);
|
||||
// double abs = Math.abs(nudgeDistance - offset);
|
||||
// if (abs < Math.abs(bestOffset) && abs != 0) {
|
||||
// bestOffset = abs;
|
||||
// finalOffset = abs;
|
||||
// bestSide = face;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (bestOffset != 0) {
|
||||
// entity.move(MoverType.SELF, new Vec3d(bestSide.getDirectionVec()).scale(finalOffset));
|
||||
// switch (bestSide.getAxis()) {
|
||||
// case X:
|
||||
// entity.setMotion(0, motion.y, motion.z);
|
||||
// break;
|
||||
// case Y:
|
||||
// entity.setMotion(motion.x, bestSide == Direction.UP ? movementSpeed + 1 / 8f : 0, motion.z);
|
||||
// entity.fall(entity.fallDistance, 1);
|
||||
// entity.fallDistance = 0;
|
||||
// entity.onGround = true;
|
||||
// break;
|
||||
// case Z:
|
||||
// entity.setMotion(motion.x, motion.y, 0);
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (!allowedMovement.equals(movement)) {
|
||||
// if (allowedMovement.y != movement.y) {
|
||||
// entity.fall(entity.fallDistance, 1);
|
||||
// entity.fallDistance = 0;
|
||||
// entity.onGround = true;
|
||||
// }
|
||||
// if (entity instanceof PlayerEntity && !world.isRemote)
|
||||
// return;
|
||||
// entity.setMotion(allowedMovement.subtract(movement.subtract(motion)));
|
||||
// entity.velocityChanged = true;
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
public void add(MechanicalPistonTileEntity mechanicalPistonTileEntity) {
|
||||
movingPistons.get(mechanicalPistonTileEntity.getWorld()).add(mechanicalPistonTileEntity);
|
||||
}
|
||||
|
||||
public void remove(MechanicalPistonTileEntity mechanicalPistonTileEntity) {
|
||||
movingPistons.get(mechanicalPistonTileEntity.getWorld()).remove(mechanicalPistonTileEntity);
|
||||
}
|
||||
|
||||
public List<MechanicalPistonTileEntity> getOtherMovingPistonsInWorld(
|
||||
MechanicalPistonTileEntity mechanicalPistonTileEntity) {
|
||||
return movingPistons.get(mechanicalPistonTileEntity.getWorld());
|
||||
}
|
||||
|
||||
// @SubscribeEvent
|
||||
// @OnlyIn(value = Dist.CLIENT)
|
||||
// public static void onRenderWorld(RenderWorldLastEvent event) {
|
||||
// for (AxisAlignedBB bb : renderedBBs) {
|
||||
// TessellatorHelper.prepareForDrawing();
|
||||
// GlStateManager.disableTexture();
|
||||
// GlStateManager.lineWidth(3);
|
||||
// int color = ColorHelper.rainbowColor(renderedBBs.indexOf(bb) * 170);
|
||||
// WorldRenderer.drawSelectionBoundingBox(bb.grow(1 / 256f), (color >> 16 & 0xFF) / 256f,
|
||||
// (color >> 8 & 0xFF) / 256f, (color & 0xFF) / 256f, 1);
|
||||
// GlStateManager.lineWidth(1);
|
||||
// GlStateManager.enableTexture();
|
||||
// TessellatorHelper.cleanUpAfterDrawing();
|
||||
// }
|
||||
// }
|
||||
|
||||
}*/
|
|
@ -131,24 +131,24 @@ public class PistonContraption extends Contraption {
|
|||
return true;
|
||||
for (int offset = 0; offset <= AllConfigs.SERVER.kinetics.maxChassisRange.get(); offset++) {
|
||||
if (offset == 1 && retracting)
|
||||
break;
|
||||
return true;
|
||||
BlockPos currentPos = pos.offset(orientation, offset + initialExtensionProgress);
|
||||
if (!world.isBlockPresent(currentPos))
|
||||
return false;
|
||||
BlockState state = world.getBlockState(currentPos);
|
||||
if (state.getMaterial().isReplaceable())
|
||||
break;
|
||||
return true;
|
||||
if (state.getCollisionShape(world, currentPos).isEmpty())
|
||||
break;
|
||||
return true;
|
||||
if (AllBlocks.MECHANICAL_PISTON_HEAD.typeOf(state) && state.get(FACING) == direction.getOpposite())
|
||||
break;
|
||||
return true;
|
||||
if (!BlockMovementTraits.movementAllowed(world, currentPos))
|
||||
return retracting;
|
||||
frontier.add(currentPos);
|
||||
if (BlockMovementTraits.notSupportive(state, orientation))
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
return false; // too many
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -4,7 +4,6 @@ import com.simibubi.create.modules.contraptions.components.contraptions.AllContr
|
|||
import com.simibubi.create.modules.contraptions.components.contraptions.Contraption;
|
||||
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
|
@ -22,7 +21,7 @@ public class PulleyContraption extends Contraption {
|
|||
return null;
|
||||
PulleyContraption construct = new PulleyContraption();
|
||||
construct.initialOffset = initialOffset;
|
||||
if (!construct.searchMovedStructure(world, pos, Direction.DOWN))
|
||||
if (!construct.searchMovedStructure(world, pos, null))
|
||||
return null;
|
||||
construct.initActors(world);
|
||||
return construct;
|
||||
|
|
|
@ -5,6 +5,7 @@ import com.simibubi.create.AllTileEntities;
|
|||
import com.simibubi.create.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.behaviour.CenteredSideValueBoxTransform;
|
||||
import com.simibubi.create.foundation.behaviour.ValueBoxTransform;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionCollider;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.piston.LinearActuatorTileEntity;
|
||||
|
||||
|
@ -19,7 +20,7 @@ import net.minecraft.util.math.Vec3d;
|
|||
public class PulleyTileEntity extends LinearActuatorTileEntity {
|
||||
|
||||
protected int initialOffset;
|
||||
|
||||
|
||||
public PulleyTileEntity() {
|
||||
super(AllTileEntities.ROPE_PULLEY.type);
|
||||
}
|
||||
|
@ -30,7 +31,7 @@ public class PulleyTileEntity extends LinearActuatorTileEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void assembleConstruct() {
|
||||
protected void assemble() {
|
||||
if (speed == 0)
|
||||
return;
|
||||
if (offset >= getExtensionRange() && getSpeed() > 0)
|
||||
|
@ -43,6 +44,14 @@ public class PulleyTileEntity extends LinearActuatorTileEntity {
|
|||
BlockPos anchor = pos.down((int) (offset + 1));
|
||||
initialOffset = (int) (offset);
|
||||
PulleyContraption contraption = PulleyContraption.assemblePulleyAt(world, anchor, (int) offset);
|
||||
|
||||
if (contraption != null) {
|
||||
Direction movementDirection = getSpeed() > 0 ? Direction.DOWN : Direction.UP;
|
||||
if (ContraptionCollider.isCollidingWithWorld(world, contraption, anchor.offset(movementDirection),
|
||||
movementDirection))
|
||||
contraption = null;
|
||||
}
|
||||
|
||||
if (contraption == null && getSpeed() > 0)
|
||||
return;
|
||||
|
||||
|
@ -66,7 +75,7 @@ public class PulleyTileEntity extends LinearActuatorTileEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void disassembleConstruct() {
|
||||
public void disassemble() {
|
||||
if (!running)
|
||||
return;
|
||||
offset = getGridOffset(offset);
|
||||
|
@ -124,7 +133,7 @@ public class PulleyTileEntity extends LinearActuatorTileEntity {
|
|||
if (stateBelow.getMaterial().isReplaceable() || stateBelow.getShape(world, posBelow).isEmpty())
|
||||
return;
|
||||
|
||||
disassembleConstruct();
|
||||
disassemble();
|
||||
assembleNextTick = true;
|
||||
}
|
||||
|
||||
|
@ -133,18 +142,18 @@ public class PulleyTileEntity extends LinearActuatorTileEntity {
|
|||
initialOffset = tag.getInt("InitialOffset");
|
||||
super.read(tag);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CompoundNBT write(CompoundNBT tag) {
|
||||
tag.putInt("InitialOffset", initialOffset);
|
||||
return super.write(tag);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected int getExtensionRange() {
|
||||
return Math.min(AllConfigs.SERVER.kinetics.maxRopeLength.get(), pos.getY() - 1);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected int getInitialOffset() {
|
||||
return initialOffset;
|
||||
|
|
|
@ -53,10 +53,11 @@ import net.minecraft.util.math.RayTraceResult;
|
|||
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.IEnviromentBlockReader;
|
||||
import net.minecraft.world.IWorldReader;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.storage.loot.LootParameters;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.common.Tags;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
@ -317,6 +318,7 @@ public class BeltBlock extends HorizontalKineticBlock
|
|||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public boolean addDestroyEffects(BlockState state, World world, BlockPos pos, ParticleManager manager) {
|
||||
// From Particle Manager, but reduced density for belts with lots of boxes
|
||||
VoxelShape voxelshape = state.getShape(world, pos);
|
||||
|
@ -603,25 +605,9 @@ public class BeltBlock extends HorizontalKineticBlock
|
|||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public IBlockColor getColorHandler() {
|
||||
return color;
|
||||
}
|
||||
|
||||
private static BeltColor color = new BeltColor();
|
||||
|
||||
private static class BeltColor implements IBlockColor {
|
||||
|
||||
@Override
|
||||
public int getColor(BlockState state, IEnviromentBlockReader reader, BlockPos pos, int layer) {
|
||||
TileEntity tileEntity = reader.getTileEntity(pos);
|
||||
if (tileEntity instanceof BeltTileEntity) {
|
||||
BeltTileEntity te = (BeltTileEntity) tileEntity;
|
||||
if (te.color != -1)
|
||||
return te.color;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return new BeltColor();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
package com.simibubi.create.modules.contraptions.relays.belt;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.renderer.color.IBlockColor;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IEnviromentBlockReader;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class BeltColor implements IBlockColor {
|
||||
|
||||
@Override
|
||||
public int getColor(BlockState state, IEnviromentBlockReader reader, BlockPos pos, int layer) {
|
||||
TileEntity tileEntity = reader.getTileEntity(pos);
|
||||
if (tileEntity instanceof BeltTileEntity) {
|
||||
BeltTileEntity te = (BeltTileEntity) tileEntity;
|
||||
if (te.color != -1)
|
||||
return te.color;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
|
@ -152,7 +152,10 @@ public class ToolEvents {
|
|||
|
||||
@SubscribeEvent
|
||||
public static void shadowSteelToolsDropMoreXPonKill(LivingExperienceDropEvent event) {
|
||||
ItemStack heldItemMainhand = event.getAttackingPlayer().getHeldItemMainhand();
|
||||
PlayerEntity attackingPlayer = event.getAttackingPlayer();
|
||||
if (attackingPlayer == null)
|
||||
return;
|
||||
ItemStack heldItemMainhand = attackingPlayer.getHeldItemMainhand();
|
||||
if (heldItemMainhand.getItem() instanceof ShadowSteelToolItem) {
|
||||
int level = EnchantmentHelper.getEnchantmentLevel(Enchantments.LOOTING, heldItemMainhand);
|
||||
float modifier = 1 + event.getEntity().world.getRandom().nextFloat() * level;
|
||||
|
|
Loading…
Reference in a new issue