Acting up

- Reimplemented support for contaption actors such as the drill and the harvester for contraption entities
This commit is contained in:
simibubi 2019-12-07 14:36:49 +01:00
parent da27a63447
commit f991c88fc2
12 changed files with 85 additions and 243 deletions

View file

@ -1,159 +0,0 @@
package com.simibubi.create.foundation.utility;
import java.nio.ByteBuffer;
import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.MathHelper;
@Deprecated
public abstract class BufferManipulator {
public static final int FORMAT_LENGTH = DefaultVertexFormats.BLOCK.getSize();
protected ByteBuffer original;
protected ByteBuffer mutable;
public BufferManipulator(ByteBuffer original) {
original.rewind();
this.original = original;
this.mutable = GLAllocation.createDirectByteBuffer(original.capacity());
this.mutable.order(original.order());
this.mutable.limit(original.limit());
mutable.put(this.original);
mutable.rewind();
}
protected static int vertexCount(ByteBuffer buffer) {
return buffer.limit() / FORMAT_LENGTH;
}
protected static int getBufferPosition(int vertexIndex) {
return vertexIndex * FORMAT_LENGTH;
}
protected static float getX(ByteBuffer buffer, int index) {
return buffer.getFloat(getBufferPosition(index));
}
protected static float getY(ByteBuffer buffer, int index) {
return buffer.getFloat(getBufferPosition(index) + 4);
}
protected static float getZ(ByteBuffer buffer, int index) {
return buffer.getFloat(getBufferPosition(index) + 8);
}
protected static byte getR(ByteBuffer buffer, int index) {
return buffer.get(getBufferPosition(index) + 12);
}
protected static byte getG(ByteBuffer buffer, int index) {
return buffer.get(getBufferPosition(index) + 13);
}
protected static byte getB(ByteBuffer buffer, int index) {
return buffer.get(getBufferPosition(index) + 14);
}
protected static byte getA(ByteBuffer buffer, int index) {
return buffer.get(getBufferPosition(index) + 15);
}
protected static void putPos(ByteBuffer buffer, int index, float x, float y, float z) {
int pos = getBufferPosition(index);
buffer.putFloat(pos, x);
buffer.putFloat(pos + 4, y);
buffer.putFloat(pos + 8, z);
}
protected static float rotateX(float x, float y, float z, float sin, float cos, Axis axis) {
return axis == Axis.Y ? x * cos + z * sin : axis == Axis.Z ? x * cos - y * sin : x;
}
protected static float rotateY(float x, float y, float z, float sin, float cos, Axis axis) {
return axis == Axis.Y ? y : axis == Axis.Z ? y * cos + x * sin : y * cos - z * sin;
}
protected static float rotateZ(float x, float y, float z, float sin, float cos, Axis axis) {
return axis == Axis.Y ? z * cos - x * sin : axis == Axis.Z ? z : z * cos + y * sin;
}
protected static void putLight(ByteBuffer buffer, int index, int packedLight) {
buffer.putInt(getBufferPosition(index) + 24, packedLight);
}
protected static void putColor(ByteBuffer buffer, int index, byte r, byte g, byte b, byte a) {
int bufferPosition = getBufferPosition(index);
buffer.put(bufferPosition + 12, r);
buffer.put(bufferPosition + 13, g);
buffer.put(bufferPosition + 14, b);
buffer.put(bufferPosition + 15, a);
}
public ByteBuffer getTranslated(float xIn, float yIn, float zIn, int packedLightCoords) {
original.rewind();
mutable.rewind();
for (int vertex = 0; vertex < vertexCount(original); vertex++) {
putPos(mutable, vertex, getX(original, vertex) + xIn, getY(original, vertex) + yIn,
getZ(original, vertex) + zIn);
putLight(mutable, vertex, packedLightCoords);
}
return mutable;
}
public static ByteBuffer remanipulateBuffer(ByteBuffer buffer, float x, float y, float z, float xOrigin,
float yOrigin, float zOrigin, float yaw, float pitch) {
buffer.rewind();
float cosYaw = MathHelper.cos(yaw);
float sinYaw = MathHelper.sin(yaw);
float cosPitch = MathHelper.cos(pitch);
float sinPitch = MathHelper.sin(pitch);
for (int vertex = 0; vertex < vertexCount(buffer); vertex++) {
float xL = getX(buffer, vertex) - xOrigin;
float yL = getY(buffer, vertex) - yOrigin;
float zL = getZ(buffer, vertex) - zOrigin;
float xL2 = rotateX(xL, yL, zL, sinPitch, cosPitch, Axis.X);
float yL2 = rotateY(xL, yL, zL, sinPitch, cosPitch, Axis.X);
float zL2 = rotateZ(xL, yL, zL, sinPitch, cosPitch, Axis.X);
xL = rotateX(xL2, yL2, zL2, sinYaw, cosYaw, Axis.Y);
yL = rotateY(xL2, yL2, zL2, sinYaw, cosYaw, Axis.Y);
zL = rotateZ(xL2, yL2, zL2, sinYaw, cosYaw, Axis.Y);
float xPos = xL + x + xOrigin;
float yPos = yL + y + yOrigin;
float zPos = zL + z + zOrigin;
putPos(buffer, vertex, xPos, yPos, zPos);
}
return buffer;
}
public static ByteBuffer recolorBuffer(ByteBuffer buffer, int color) {
buffer.rewind();
boolean defaultColor = color == -1;
int b = defaultColor ? 128 : color & 0xFF;
int g = defaultColor ? 128 : (color >> 8) & 0xFF;
int r = defaultColor ? 128 : (color >> 16) & 0xFF;
for (int vertex = 0; vertex < vertexCount(buffer); vertex++) {
float lum = 1;
int r2 = (int) (r * lum);
int g2 = (int) (g * lum);
int b2 = (int) (b * lum);
putColor(buffer, vertex, (byte) r2, (byte) g2, (byte) b2, (byte) 255);
}
return buffer;
}
}

View file

@ -94,7 +94,7 @@ public class DrillBlock extends DirectionalKineticBlock
World world = context.world;
BlockPos pos = context.currentGridPos;
pos = pos.offset(movement);
// pos = pos.offset(movement);
BlockState stateVisited = world.getBlockState(pos);
if (stateVisited.getCollisionShape(world, pos).isEmpty())

View file

@ -113,8 +113,8 @@ public class HarvesterBlock extends HorizontalBlock implements IHaveMovementBeha
BlockState block = context.state;
BlockPos pos = context.currentGridPos;
if (movement != block.get(HORIZONTAL_FACING))
return;
// if (movement != block.get(HORIZONTAL_FACING))
// return;
BlockState stateVisited = world.getBlockState(pos);
boolean notCropButCuttable = false;

View file

@ -29,11 +29,12 @@ public class HarvesterTileEntityRenderer extends TileEntityRenderer<HarvesterTil
public static SuperByteBuffer renderInContraption(MovementContext context) {
BlockState state = context.state;
Direction facing = context.getMovementDirection();
float speed = (float) (facing == state.get(HORIZONTAL_FACING)
? context.getAnimationSpeed() * facing.getAxisDirection().getOffset()
: 0);
if (facing.getAxis() == Axis.X)
speed = -speed;
float speed = -500 * state.get(HORIZONTAL_FACING).getAxisDirection().getOffset();
// float speed = (float) (facing != state.get(HORIZONTAL_FACING)
// ? context.getAnimationSpeed() * facing.getAxisDirection().getOffset()
// : 0);
// if (facing.getAxis() == Axis.X)
// speed = -speed;
float time = AnimationTickHolder.getRenderTick();
float angle = (float) (((time * speed) % 360) / 180 * (float) Math.PI);

View file

@ -29,6 +29,7 @@ import com.simibubi.create.modules.contraptions.receivers.contraptions.mounted.M
import com.simibubi.create.modules.contraptions.receivers.contraptions.piston.PistonContraption;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.FallingBlock;
import net.minecraft.block.PistonBlock;
import net.minecraft.block.ShulkerBoxBlock;
@ -44,6 +45,7 @@ import net.minecraft.util.Direction.Axis;
import net.minecraft.util.Direction.AxisDirection;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.IWorld;
import net.minecraft.world.World;
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
@ -449,7 +451,7 @@ public class Contraption {
constructCollisionBox = constructCollisionBox.union(new AxisAlignedBB(localPos));
}
public static Contraption fromNBT(CompoundNBT nbt) {
public static Contraption fromNBT(World world, CompoundNBT nbt) {
String type = nbt.getString("Type");
Contraption contraption = new Contraption();
if (type.equals("Piston"))
@ -458,11 +460,11 @@ public class Contraption {
contraption = new MountedContraption();
if (type.equals("Bearing"))
contraption = new BearingContraption();
contraption.readNBT(nbt);
contraption.readNBT(world, nbt);
return contraption;
}
public void readNBT(CompoundNBT nbt) {
public void readNBT(World world, CompoundNBT nbt) {
nbt.getList("Blocks", 10).forEach(c -> {
CompoundNBT comp = (CompoundNBT) c;
BlockInfo info = new BlockInfo(NBTUtil.readBlockPos(comp.getCompound("Pos")),
@ -474,7 +476,7 @@ public class Contraption {
nbt.getList("Actors", 10).forEach(c -> {
CompoundNBT comp = (CompoundNBT) c;
BlockInfo info = blocks.get(NBTUtil.readBlockPos(comp.getCompound("Pos")));
MovementContext context = MovementContext.readNBT(comp);
MovementContext context = MovementContext.readNBT(world, comp);
getActors().add(MutablePair.of(info, context));
});
@ -553,6 +555,19 @@ public class Contraption {
disassemble(world, offset, yaw, pitch, (pos, state) -> false);
}
public void removeBlocksFromWorld(IWorld world, BlockPos offset) {
removeBlocksFromWorld(world, offset, (pos, state) -> false);
}
public void removeBlocksFromWorld(IWorld world, BlockPos offset, BiPredicate<BlockPos, BlockState> customRemoval) {
for (BlockInfo block : blocks.values()) {
BlockPos add = block.pos.add(anchor).add(offset);
if (customRemoval.test(add, block.state))
continue;
world.setBlockState(add, Blocks.AIR.getDefaultState(), 67);
}
}
public void disassemble(IWorld world, BlockPos offset, float yaw, float pitch,
BiPredicate<BlockPos, BlockState> customPlacement) {
for (BlockInfo block : blocks.values()) {
@ -580,6 +595,16 @@ public class Contraption {
}
}
public void initActors(World world) {
for (MutablePair<BlockInfo, MovementContext> pair : actors) {
MovementContext context = new MovementContext(world, pair.left.state);
context.world = world;
context.motion = Vec3d.ZERO;
context.currentGridPos = BlockPos.ZERO;
pair.setRight(context);
}
}
public List<MutablePair<BlockInfo, MovementContext>> getActors() {
return actors;
}

View file

@ -67,7 +67,6 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
@Override
public void tick() {
super.tick();
attachToController();
Entity e = getRidingEntity();
@ -90,31 +89,32 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
pitch = angleLerp(speed, pitch, targetPitch);
tickActors(movementVector);
super.tick();
return;
}
prevYaw = yaw;
prevPitch = pitch;
prevRoll = roll;
tickActors(new Vec3d(posX - prevPosX, posY - prevPosY, posZ - prevPosZ));
super.tick();
}
public void tickActors(Vec3d movementVector) {
getContraption().getActors().forEach(pair -> {
MovementContext context = pair.right;
float deg = -yaw + initialAngle;
float deg = (getRidingEntity() != null ? yaw + 180 : yaw) + initialAngle;
context.motion = VecHelper.rotate(movementVector, deg, Axis.Y);
if (context.world == null)
context.world = world;
Vec3d offset = new Vec3d(pair.left.pos.subtract(getContraption().getAnchor()));
world.addParticle(ParticleTypes.BUBBLE, offset.x, offset.y, offset.z, 0, 0, 0);
Vec3d rotationOffset = VecHelper.getCenterOf(BlockPos.ZERO);
Vec3d offset = new Vec3d(pair.left.pos);
offset = VecHelper.rotate(offset, deg, Axis.Y);
world.addParticle(ParticleTypes.CRIT, offset.x, offset.y, offset.z, 0, 0, 0);
offset = offset.add(new Vec3d(getPosition()).add(0.5, 0, 0.5));
world.addParticle(ParticleTypes.NOTE, offset.x, offset.y, offset.z, 0, 10, 0);
offset = offset.add(rotationOffset);
offset = offset.add(posX, posY, posZ);
if (world.isRemote)
return;
@ -219,7 +219,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
@Override
protected void readAdditional(CompoundNBT compound) {
contraption = Contraption.fromNBT(compound.getCompound("Contraption"));
contraption = Contraption.fromNBT(world, compound.getCompound("Contraption"));
initialAngle = compound.getFloat("InitialAngle");
if (compound.contains("Controller"))
controllerPos = NBTUtil.readBlockPos(compound.getCompound("Controller"));

View file

@ -36,14 +36,12 @@ public interface IHaveMovementBehavior {
public BlockPos currentGridPos;
public Vec3d motion;
public float movementSpeedModifier = 1;
public MoverType moverType;
public World world;
public BlockState state;
public MovementContext(BlockState state, MoverType moverType) {
public MovementContext(World world, BlockState state) {
this.world = world;
this.state = state;
this.moverType = moverType;
}
public Direction getMovementDirection() {
@ -51,13 +49,12 @@ public interface IHaveMovementBehavior {
}
public float getAnimationSpeed() {
int modifier = moverType == MoverType.MINECART ? 1000 : 200;
int modifier = 1000;
return ((int) (motion.length() * modifier)) / 100 * 100;
}
public static MovementContext readNBT(CompoundNBT nbt) {
MovementContext context = new MovementContext(NBTUtil.readBlockState(nbt.getCompound("State")),
MoverType.valueOf(nbt.getString("MoverType")));
public static MovementContext readNBT(World world, CompoundNBT nbt) {
MovementContext context = new MovementContext(world, NBTUtil.readBlockState(nbt.getCompound("State")));
context.motion = VecHelper.readNBT(nbt.getList("Motion", NBT.TAG_DOUBLE));
context.movementSpeedModifier = nbt.getFloat("SpeedModifier");
context.currentGridPos = NBTUtil.readBlockPos(nbt.getCompound("GridPos"));
@ -66,7 +63,6 @@ public interface IHaveMovementBehavior {
public CompoundNBT writeToNBT(CompoundNBT nbt) {
nbt.put("State", NBTUtil.writeBlockState(state));
nbt.putString("MoverType", moverType.name());
nbt.put("Motion", VecHelper.writeNBT(motion));
nbt.putFloat("SpeedModifier", movementSpeedModifier);
nbt.put("GridPos", NBTUtil.writeBlockPos(currentGridPos));

View file

@ -21,6 +21,7 @@ public class BearingContraption extends Contraption {
construct.facing = direction;
if (!construct.searchMovedStructure(world, pos.offset(direction), direction))
return null;
construct.initActors(world);
return construct;
}
@ -40,12 +41,12 @@ public class BearingContraption extends Contraption {
}
@Override
public void readNBT(CompoundNBT tag) {
public void readNBT(World world, CompoundNBT tag) {
sailBlocks = tag.getInt("Sails");
facing = Direction.byIndex(tag.getInt("Facing"));
super.readNBT(tag);
super.readNBT(world, tag);
}
public int getSailBlocks() {
return sailBlocks;
}

View file

@ -6,14 +6,12 @@ import com.simibubi.create.modules.contraptions.receivers.contraptions.Contrapti
import com.simibubi.create.modules.contraptions.receivers.contraptions.ContraptionEntity;
import com.simibubi.create.modules.contraptions.receivers.contraptions.IControlContraption;
import net.minecraft.block.Blocks;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity implements IControlContraption {
@ -64,6 +62,8 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
public float getGeneratedSpeed() {
if (!running || !isWindmill)
return 0;
if (movedContraption == null)
return 0;
int sails = ((BearingContraption) movedContraption.getContraption()).getSailBlocks();
return MathHelper.clamp(sails, 0, 128);
}
@ -109,6 +109,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
return;
movedContraption = new ContraptionEntity(world, contraption, 0).controlledBy(this);
BlockPos anchor = pos.offset(direction);
contraption.removeBlocksFromWorld(world, BlockPos.ZERO);
movedContraption.setPosition(anchor.getX(), anchor.getY(), anchor.getZ());
world.addEntity(movedContraption);
@ -117,10 +118,6 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
angle = 0;
sendData();
for (BlockInfo info : contraption.blocks.values()) {
getWorld().setBlockState(info.pos.add(contraption.getAnchor()), Blocks.AIR.getDefaultState(), 67);
}
updateGeneratedRotation();
}

View file

@ -4,15 +4,10 @@ import static com.simibubi.create.modules.contraptions.receivers.contraptions.mo
import java.util.List;
import org.apache.commons.lang3.tuple.MutablePair;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.modules.contraptions.receivers.contraptions.Contraption;
import com.simibubi.create.modules.contraptions.receivers.contraptions.IHaveMovementBehavior.MovementContext;
import com.simibubi.create.modules.contraptions.receivers.contraptions.IHaveMovementBehavior.MoverType;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.entity.item.minecart.AbstractMinecartEntity;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.state.properties.RailShape;
@ -44,20 +39,8 @@ public class MountedContraption extends Contraption {
contraption.add(pos, new BlockInfo(pos,
AllBlocks.MINECART_ANCHOR.block.getDefaultState().with(BlockStateProperties.HORIZONTAL_AXIS, axis),
null));
for (BlockInfo block : contraption.blocks.values()) {
if (BlockPos.ZERO.equals(block.pos))
continue;
world.setBlockState(block.pos.add(pos), Blocks.AIR.getDefaultState(), 67);
}
for (MutablePair<BlockInfo, MovementContext> pair : contraption.getActors()) {
MovementContext context = new MovementContext(pair.left.state, MoverType.MINECART);
context.world = world;
context.motion = vec;
context.currentGridPos = pair.left.pos;
pair.setRight(context);
}
contraption.removeBlocksFromWorld(world, BlockPos.ZERO);
contraption.initActors(world);
return contraption;
}
@ -83,6 +66,11 @@ public class MountedContraption extends Contraption {
return capture;
}
@Override
public void removeBlocksFromWorld(IWorld world, BlockPos offset) {
super.removeBlocksFromWorld(world, offset, (pos, state) -> pos.equals(anchor));
}
@Override
public void disassemble(IWorld world, BlockPos offset, float yaw, float pitch) {
super.disassemble(world, offset, yaw, pitch, (pos, state) -> AllBlocks.MINECART_ANCHOR.typeOf(state));

View file

@ -1,17 +1,12 @@
package com.simibubi.create.modules.contraptions.receivers.contraptions.piston;
import org.apache.commons.lang3.tuple.MutablePair;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllTileEntities;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.receivers.contraptions.ContraptionEntity;
import com.simibubi.create.modules.contraptions.receivers.contraptions.IControlContraption;
import com.simibubi.create.modules.contraptions.receivers.contraptions.IHaveMovementBehavior.MovementContext;
import com.simibubi.create.modules.contraptions.receivers.contraptions.IHaveMovementBehavior.MoverType;
import com.simibubi.create.modules.contraptions.receivers.contraptions.piston.MechanicalPistonBlock.PistonState;
import net.minecraft.block.Blocks;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.Direction;
@ -19,7 +14,6 @@ import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
public class MechanicalPistonTileEntity extends KineticTileEntity implements IControlContraption {
@ -85,23 +79,8 @@ public class MechanicalPistonTileEntity extends KineticTileEntity implements ICo
offset = contraption.initialExtensionProgress;
sendData();
getWorld().setBlockState(pos, getBlockState().with(MechanicalPistonBlock.STATE, PistonState.MOVING), 66);
for (BlockInfo block : contraption.blocks.values()) {
BlockPos startPos = block.pos.offset(direction, contraption.initialExtensionProgress);
BlockPos add = startPos.add(contraption.getAnchor());
if (add.equals(pos))
continue;
getWorld().setBlockState(add, Blocks.AIR.getDefaultState(), 67);
}
for (MutablePair<BlockInfo, MovementContext> pair : contraption.getActors()) {
MovementContext context = new MovementContext(pair.left.state, MoverType.PISTON);
context.world = world;
context.motion = new Vec3d(direction.getDirectionVec()).scale(getMovementSpeed()).normalize();
context.currentGridPos = pair.left.pos.offset(direction, getModulatedOffset(offset));
pair.setRight(context);
}
BlockPos startPos = BlockPos.ZERO.offset(direction, contraption.initialExtensionProgress);
contraption.removeBlocksFromWorld(world, startPos);
movedContraption = new ContraptionEntity(getWorld(), contraption, 0).controlledBy(this);
moveContraption();
world.addEntity(movedContraption);

View file

@ -43,6 +43,7 @@ public class PistonContraption extends Contraption {
return null;
if (!construct.searchMovedStructure(world, construct.anchor, retract ? direction.getOpposite() : direction))
return null;
construct.initActors(world);
return construct;
}
@ -155,8 +156,21 @@ public class PistonContraption extends Contraption {
}
@Override
public void readNBT(CompoundNBT nbt) {
super.readNBT(nbt);
public void removeBlocksFromWorld(IWorld world, BlockPos offset) {
super.removeBlocksFromWorld(world, offset, (pos, state) -> {
BlockPos pistonPos = anchor.offset(orientation, -initialExtensionProgress - 1);
BlockState blockState = world.getBlockState(pos);
if (pos.equals(pistonPos) && blockState.getBlock() instanceof MechanicalPistonBlock) {
world.setBlockState(pos, blockState.with(MechanicalPistonBlock.STATE, PistonState.MOVING), 66);
return true;
}
return false;
});
}
@Override
public void readNBT(World world, CompoundNBT nbt) {
super.readNBT(world, nbt);
extensionLength = nbt.getInt("ExtensionLength");
initialExtensionProgress = nbt.getInt("InitialLength");
orientation = Direction.byIndex(nbt.getInt("Orientation"));