mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-16 23:11:40 +01:00
Portable Deployers
- Server speed sync no longer goes nuts when server speed increased from low tps - Flimsy attempts at better syncing a bearings' current angle - Portable Storage abilities are (for now) available to the Barrel only - Deployers can now be mounted on moving structures and will activate at every visited block position
This commit is contained in:
parent
e0b36a79c9
commit
7dd29e9ffd
18 changed files with 681 additions and 344 deletions
|
@ -71,7 +71,7 @@ public class ServerSpeedProvider {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
float target = ((float) getSyncInterval()) / Math.max(clientTimer, 1);
|
float target = ((float) getSyncInterval()) / Math.max(clientTimer, 1);
|
||||||
modifier.target(target);
|
modifier.target(Math.min(target, 1));
|
||||||
clientTimer = 0;
|
clientTimer = 0;
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -150,17 +150,15 @@ public class Contraption {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (int limit = 1000; limit > 0; limit--) {
|
for (int limit = 1000; limit > 0; limit--) {
|
||||||
if (frontier.isEmpty()) {
|
if (frontier.isEmpty())
|
||||||
onAssembled(world, pos);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
if (!moveBlock(world, frontier.remove(0), direction, frontier, visited))
|
if (!moveBlock(world, frontier.remove(0), direction, frontier, visited))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onAssembled(World world, BlockPos pos) {
|
public void gatherStoredItems() {
|
||||||
List<IItemHandlerModifiable> list =
|
List<IItemHandlerModifiable> list =
|
||||||
storage.values().stream().map(MountedStorage::getItemHandler).collect(Collectors.toList());
|
storage.values().stream().map(MountedStorage::getItemHandler).collect(Collectors.toList());
|
||||||
inventory = new CombinedInvWrapper(Arrays.copyOf(list.toArray(), list.size(), IItemHandlerModifiable[].class));
|
inventory = new CombinedInvWrapper(Arrays.copyOf(list.toArray(), list.size(), IItemHandlerModifiable[].class));
|
||||||
|
@ -504,7 +502,7 @@ public class Contraption {
|
||||||
nbt.getList("Actors", 10).forEach(c -> {
|
nbt.getList("Actors", 10).forEach(c -> {
|
||||||
CompoundNBT comp = (CompoundNBT) c;
|
CompoundNBT comp = (CompoundNBT) c;
|
||||||
BlockInfo info = blocks.get(NBTUtil.readBlockPos(comp.getCompound("Pos")));
|
BlockInfo info = blocks.get(NBTUtil.readBlockPos(comp.getCompound("Pos")));
|
||||||
MovementContext context = MovementContext.readNBT(world, comp);
|
MovementContext context = MovementContext.readNBT(world, info, comp);
|
||||||
context.contraption = this;
|
context.contraption = this;
|
||||||
getActors().add(MutablePair.of(info, context));
|
getActors().add(MutablePair.of(info, context));
|
||||||
});
|
});
|
||||||
|
@ -549,6 +547,7 @@ public class Contraption {
|
||||||
for (MutablePair<BlockInfo, MovementContext> actor : getActors()) {
|
for (MutablePair<BlockInfo, MovementContext> actor : getActors()) {
|
||||||
CompoundNBT compound = new CompoundNBT();
|
CompoundNBT compound = new CompoundNBT();
|
||||||
compound.put("Pos", NBTUtil.writeBlockPos(actor.left.pos));
|
compound.put("Pos", NBTUtil.writeBlockPos(actor.left.pos));
|
||||||
|
getMovement(actor.left.state).writeExtraData(actor.right);
|
||||||
actor.right.writeToNBT(compound);
|
actor.right.writeToNBT(compound);
|
||||||
actorsNBT.add(compound);
|
actorsNBT.add(compound);
|
||||||
}
|
}
|
||||||
|
@ -591,6 +590,7 @@ public class Contraption {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeBlocksFromWorld(IWorld world, BlockPos offset, BiPredicate<BlockPos, BlockState> customRemoval) {
|
public void removeBlocksFromWorld(IWorld world, BlockPos offset, BiPredicate<BlockPos, BlockState> customRemoval) {
|
||||||
|
storage.values().forEach(MountedStorage::empty);
|
||||||
for (BlockInfo block : blocks.values()) {
|
for (BlockInfo block : blocks.values()) {
|
||||||
BlockPos add = block.pos.add(anchor).add(offset);
|
BlockPos add = block.pos.add(anchor).add(offset);
|
||||||
if (customRemoval.test(add, block.state))
|
if (customRemoval.test(add, block.state))
|
||||||
|
@ -635,10 +635,9 @@ public class Contraption {
|
||||||
|
|
||||||
public void initActors(World world) {
|
public void initActors(World world) {
|
||||||
for (MutablePair<BlockInfo, MovementContext> pair : actors) {
|
for (MutablePair<BlockInfo, MovementContext> pair : actors) {
|
||||||
BlockState blockState = pair.left.state;
|
MovementContext context = new MovementContext(world, pair.left);
|
||||||
MovementContext context = new MovementContext(world, blockState);
|
|
||||||
context.contraption = this;
|
context.contraption = this;
|
||||||
getMovement(blockState).startMoving(context);
|
getMovement(pair.left.state).startMoving(context);
|
||||||
pair.setRight(context);
|
pair.setRight(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,8 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
this.prevYaw = initialAngle;
|
this.prevYaw = initialAngle;
|
||||||
this.yaw = initialAngle;
|
this.yaw = initialAngle;
|
||||||
this.targetYaw = initialAngle;
|
this.targetYaw = initialAngle;
|
||||||
|
if (contraption != null)
|
||||||
|
contraption.gatherStoredItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends TileEntity & IControlContraption> ContraptionEntity controlledBy(T controller) {
|
public <T extends TileEntity & IControlContraption> ContraptionEntity controlledBy(T controller) {
|
||||||
|
@ -92,7 +94,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
Vec3d movementVector = e.getMotion();
|
Vec3d movementVector = e.getMotion();
|
||||||
Vec3d motion = movementVector.normalize();
|
Vec3d motion = movementVector.normalize();
|
||||||
if (motion.length() > 0) {
|
if (motion.length() > 0) {
|
||||||
targetYaw = yawFromMotion(motion);
|
targetYaw = yawFromVector(motion);
|
||||||
targetPitch = (float) ((Math.atan(motion.y) * 73.0D) / Math.PI * 180);
|
targetPitch = (float) ((Math.atan(motion.y) * 73.0D) / Math.PI * 180);
|
||||||
if (targetYaw < 0)
|
if (targetYaw < 0)
|
||||||
targetYaw += 360;
|
targetYaw += 360;
|
||||||
|
@ -254,8 +256,12 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
disassemble();
|
disassemble();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float yawFromMotion(Vec3d motion) {
|
public static float yawFromVector(Vec3d vec) {
|
||||||
return (float) ((3 * Math.PI / 2 + Math.atan2(motion.z, motion.x)) / Math.PI * 180);
|
return (float) ((3 * Math.PI / 2 + Math.atan2(vec.z, vec.x)) / Math.PI * 180);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float pitchFromVector(Vec3d vec) {
|
||||||
|
return (float) ((Math.acos(vec.y)) / Math.PI * 180);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getYaw(float partialTicks) {
|
public float getYaw(float partialTicks) {
|
||||||
|
|
|
@ -69,7 +69,7 @@ public class ContraptionRenderer {
|
||||||
context.world = world;
|
context.world = world;
|
||||||
|
|
||||||
BlockInfo blockInfo = actor.getLeft();
|
BlockInfo blockInfo = actor.getLeft();
|
||||||
SuperByteBuffer render = Contraption.getMovement(blockInfo.state).renderInContraption(context);
|
for (SuperByteBuffer render : Contraption.getMovement(blockInfo.state).renderListInContraption(context)) {
|
||||||
if (render == null)
|
if (render == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -82,6 +82,7 @@ public class ContraptionRenderer {
|
||||||
render.light((lx, ly, lz) -> getLight(world, lx, ly, lz)).renderInto(buffer);
|
render.light((lx, ly, lz) -> getLight(world, lx, ly, lz)).renderInto(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static int getLight(World world, float lx, float ly, float lz) {
|
public static int getLight(World world, float lx, float ly, float lz) {
|
||||||
MutableBlockPos pos = new MutableBlockPos();
|
MutableBlockPos pos = new MutableBlockPos();
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package com.simibubi.create.modules.contraptions.components.contraptions;
|
package com.simibubi.create.modules.contraptions.components.contraptions;
|
||||||
|
|
||||||
import com.simibubi.create.AllTileEntities;
|
|
||||||
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
@ -17,9 +15,14 @@ public class MountedStorage {
|
||||||
|
|
||||||
ItemStackHandler handler;
|
ItemStackHandler handler;
|
||||||
boolean working;
|
boolean working;
|
||||||
|
private TileEntity te;
|
||||||
|
|
||||||
public MountedStorage(TileEntity te) {
|
public MountedStorage(TileEntity te) {
|
||||||
|
this.te = te;
|
||||||
handler = dummyHandler;
|
handler = dummyHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void empty() {
|
||||||
if (te != null) {
|
if (te != null) {
|
||||||
IItemHandler teHandler =
|
IItemHandler teHandler =
|
||||||
te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).orElse(dummyHandler);
|
te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).orElse(dummyHandler);
|
||||||
|
@ -68,11 +71,8 @@ public class MountedStorage {
|
||||||
if (te == null)
|
if (te == null)
|
||||||
return false;
|
return false;
|
||||||
TileEntityType<?> type = te.getType();
|
TileEntityType<?> type = te.getType();
|
||||||
if (type == TileEntityType.CHEST || type == TileEntityType.SHULKER_BOX || type == TileEntityType.BARREL)
|
if (type == TileEntityType.BARREL)
|
||||||
return true;
|
return true;
|
||||||
if (type == AllTileEntities.FLEXCRATE.type)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package com.simibubi.create.modules.contraptions.components.contraptions;
|
package com.simibubi.create.modules.contraptions.components.contraptions;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
||||||
|
|
||||||
import net.minecraft.entity.item.ItemEntity;
|
import net.minecraft.entity.item.ItemEntity;
|
||||||
|
@ -45,8 +48,17 @@ public abstract class MovementBehaviour {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OnlyIn(value = Dist.CLIENT)
|
||||||
|
public List<SuperByteBuffer> renderListInContraption(MovementContext context) {
|
||||||
|
return Arrays.asList(renderInContraption(context));
|
||||||
|
}
|
||||||
|
|
||||||
public void stopMoving(MovementContext context) {
|
public void stopMoving(MovementContext context) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void writeExtraData(MovementContext context) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,9 @@ import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.nbt.NBTUtil;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
|
||||||
import net.minecraftforge.common.util.Constants.NBT;
|
import net.minecraftforge.common.util.Constants.NBT;
|
||||||
|
|
||||||
public class MovementContext {
|
public class MovementContext {
|
||||||
|
@ -17,14 +17,17 @@ public class MovementContext {
|
||||||
public Vec3d rotation;
|
public Vec3d rotation;
|
||||||
public World world;
|
public World world;
|
||||||
public BlockState state;
|
public BlockState state;
|
||||||
|
public CompoundNBT tileData;
|
||||||
|
|
||||||
public boolean stall;
|
public boolean stall;
|
||||||
public CompoundNBT data;
|
public CompoundNBT data;
|
||||||
public Contraption contraption;
|
public Contraption contraption;
|
||||||
|
public Object temporaryData;
|
||||||
|
|
||||||
public MovementContext(World world, BlockState state) {
|
public MovementContext(World world, BlockInfo info) {
|
||||||
this.world = world;
|
this.world = world;
|
||||||
this.state = state;
|
this.state = info.state;
|
||||||
|
this.tileData = info.nbt;
|
||||||
|
|
||||||
motion = Vec3d.ZERO;
|
motion = Vec3d.ZERO;
|
||||||
relativeMotion = Vec3d.ZERO;
|
relativeMotion = Vec3d.ZERO;
|
||||||
|
@ -44,9 +47,8 @@ public class MovementContext {
|
||||||
return (((int) (length * modifier + 100 * Math.signum(length))) / 100) * 100;
|
return (((int) (length * modifier + 100 * Math.signum(length))) / 100) * 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MovementContext readNBT(World world, CompoundNBT nbt) {
|
public static MovementContext readNBT(World world, BlockInfo info, CompoundNBT nbt) {
|
||||||
BlockState state = NBTUtil.readBlockState(nbt.getCompound("State"));
|
MovementContext context = new MovementContext(world, info);
|
||||||
MovementContext context = new MovementContext(world, state);
|
|
||||||
context.motion = VecHelper.readNBT(nbt.getList("Motion", NBT.TAG_DOUBLE));
|
context.motion = VecHelper.readNBT(nbt.getList("Motion", NBT.TAG_DOUBLE));
|
||||||
context.relativeMotion = VecHelper.readNBT(nbt.getList("RelativeMotion", NBT.TAG_DOUBLE));
|
context.relativeMotion = VecHelper.readNBT(nbt.getList("RelativeMotion", NBT.TAG_DOUBLE));
|
||||||
context.rotation = VecHelper.readNBT(nbt.getList("Rotation", NBT.TAG_DOUBLE));
|
context.rotation = VecHelper.readNBT(nbt.getList("Rotation", NBT.TAG_DOUBLE));
|
||||||
|
@ -58,7 +60,6 @@ public class MovementContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompoundNBT writeToNBT(CompoundNBT nbt) {
|
public CompoundNBT writeToNBT(CompoundNBT nbt) {
|
||||||
nbt.put("State", NBTUtil.writeBlockState(state));
|
|
||||||
nbt.put("Motion", VecHelper.writeNBT(motion));
|
nbt.put("Motion", VecHelper.writeNBT(motion));
|
||||||
nbt.put("RelativeMotion", VecHelper.writeNBT(relativeMotion));
|
nbt.put("RelativeMotion", VecHelper.writeNBT(relativeMotion));
|
||||||
nbt.put("Rotation", VecHelper.writeNBT(rotation));
|
nbt.put("Rotation", VecHelper.writeNBT(rotation));
|
||||||
|
|
|
@ -24,9 +24,12 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
||||||
protected boolean assembleNextTick;
|
protected boolean assembleNextTick;
|
||||||
protected boolean isWindmill;
|
protected boolean isWindmill;
|
||||||
|
|
||||||
|
protected float clientAngleDiff;
|
||||||
|
|
||||||
public MechanicalBearingTileEntity() {
|
public MechanicalBearingTileEntity() {
|
||||||
super(AllTileEntities.MECHANICAL_BEARING.type);
|
super(AllTileEntities.MECHANICAL_BEARING.type);
|
||||||
isWindmill = false;
|
isWindmill = false;
|
||||||
|
setLazyTickRate(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -92,6 +95,16 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
||||||
super.read(tag);
|
super.read(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readClientUpdate(CompoundNBT tag) {
|
||||||
|
float angleBefore = angle;
|
||||||
|
super.readClientUpdate(tag);
|
||||||
|
clientAngleDiff = angle - angleBefore;
|
||||||
|
if (Math.abs(clientAngleDiff) > 20)
|
||||||
|
clientAngleDiff = 0;
|
||||||
|
angle = angleBefore;
|
||||||
|
}
|
||||||
|
|
||||||
public float getInterpolatedAngle(float partialTicks) {
|
public float getInterpolatedAngle(float partialTicks) {
|
||||||
if (movedContraption != null && movedContraption.isStalled())
|
if (movedContraption != null && movedContraption.isStalled())
|
||||||
partialTicks = 0;
|
partialTicks = 0;
|
||||||
|
@ -106,8 +119,10 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
||||||
|
|
||||||
public float getAngularSpeed() {
|
public float getAngularSpeed() {
|
||||||
float speed = getSpeed() * 3 / 10f;
|
float speed = getSpeed() * 3 / 10f;
|
||||||
if (world.isRemote)
|
if (world.isRemote) {
|
||||||
speed *= ServerSpeedProvider.get();
|
speed *= ServerSpeedProvider.get();
|
||||||
|
speed += clientAngleDiff / 3f;
|
||||||
|
}
|
||||||
return speed;
|
return speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,9 +135,9 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
||||||
return;
|
return;
|
||||||
if (isWindmill && contraption.getSailBlocks() == 0)
|
if (isWindmill && contraption.getSailBlocks() == 0)
|
||||||
return;
|
return;
|
||||||
|
contraption.removeBlocksFromWorld(world, BlockPos.ZERO);
|
||||||
movedContraption = new ContraptionEntity(world, contraption, 0).controlledBy(this);
|
movedContraption = new ContraptionEntity(world, contraption, 0).controlledBy(this);
|
||||||
BlockPos anchor = pos.offset(direction);
|
BlockPos anchor = pos.offset(direction);
|
||||||
contraption.removeBlocksFromWorld(world, BlockPos.ZERO);
|
|
||||||
movedContraption.setPosition(anchor.getX(), anchor.getY(), anchor.getZ());
|
movedContraption.setPosition(anchor.getX(), anchor.getY(), anchor.getZ());
|
||||||
world.addEntity(movedContraption);
|
world.addEntity(movedContraption);
|
||||||
|
|
||||||
|
@ -150,17 +165,20 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
||||||
public void tick() {
|
public void tick() {
|
||||||
super.tick();
|
super.tick();
|
||||||
|
|
||||||
|
if (world.isRemote)
|
||||||
|
clientAngleDiff /= 2;
|
||||||
|
|
||||||
if (running && Contraption.isFrozen())
|
if (running && Contraption.isFrozen())
|
||||||
disassembleConstruct();
|
disassembleConstruct();
|
||||||
|
|
||||||
if (!world.isRemote && assembleNextTick) {
|
if (!world.isRemote && assembleNextTick) {
|
||||||
assembleNextTick = false;
|
assembleNextTick = false;
|
||||||
if (running) {
|
if (running) {
|
||||||
if (movedContraption != null)
|
|
||||||
movedContraption.getContraption().stop(world);
|
|
||||||
boolean canDisassemble = Math.abs(angle) < 45 || Math.abs(angle) > 7 * 45;
|
boolean canDisassemble = Math.abs(angle) < 45 || Math.abs(angle) > 7 * 45;
|
||||||
if (speed == 0 && (canDisassemble || movedContraption == null
|
if (speed == 0 && (canDisassemble || movedContraption == null
|
||||||
|| movedContraption.getContraption().blocks.isEmpty())) {
|
|| movedContraption.getContraption().blocks.isEmpty())) {
|
||||||
|
if (movedContraption != null)
|
||||||
|
movedContraption.getContraption().stop(world);
|
||||||
disassembleConstruct();
|
disassembleConstruct();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -184,6 +202,13 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
||||||
applyRotation();
|
applyRotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void lazyTick() {
|
||||||
|
super.lazyTick();
|
||||||
|
if (movedContraption != null && !world.isRemote)
|
||||||
|
sendData();
|
||||||
|
}
|
||||||
|
|
||||||
private void applyRotation() {
|
private void applyRotation() {
|
||||||
if (movedContraption != null) {
|
if (movedContraption != null) {
|
||||||
Axis axis = getBlockState().get(BlockStateProperties.FACING).getAxis();
|
Axis axis = getBlockState().get(BlockStateProperties.FACING).getAxis();
|
||||||
|
|
|
@ -76,7 +76,7 @@ public class CartAssemblerBlock extends AbstractRailBlock {
|
||||||
if (contraption == null)
|
if (contraption == null)
|
||||||
return;
|
return;
|
||||||
ContraptionEntity entity = new ContraptionEntity(world, contraption,
|
ContraptionEntity entity = new ContraptionEntity(world, contraption,
|
||||||
ContraptionEntity.yawFromMotion(cart.getMotion()));
|
ContraptionEntity.yawFromVector(cart.getMotion()));
|
||||||
entity.setPosition(pos.getX(), pos.getY(), pos.getZ());
|
entity.setPosition(pos.getX(), pos.getY(), pos.getZ());
|
||||||
world.addEntity(entity);
|
world.addEntity(entity);
|
||||||
entity.startRiding(cart);
|
entity.startRiding(cart);
|
||||||
|
|
|
@ -93,6 +93,7 @@ public class MechanicalPistonTileEntity extends KineticTileEntity implements ICo
|
||||||
|
|
||||||
if (!removed)
|
if (!removed)
|
||||||
getWorld().setBlockState(pos, getBlockState().with(MechanicalPistonBlock.STATE, PistonState.EXTENDED), 3);
|
getWorld().setBlockState(pos, getBlockState().with(MechanicalPistonBlock.STATE, PistonState.EXTENDED), 3);
|
||||||
|
if (movedContraption != null)
|
||||||
movedContraption.disassemble();
|
movedContraption.disassemble();
|
||||||
running = false;
|
running = false;
|
||||||
movedContraption = null;
|
movedContraption = null;
|
||||||
|
|
|
@ -6,9 +6,12 @@ import com.simibubi.create.foundation.utility.AllShapes;
|
||||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
import com.simibubi.create.modules.contraptions.base.DirectionalAxisKineticBlock;
|
import com.simibubi.create.modules.contraptions.base.DirectionalAxisKineticBlock;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.IPortableBlock;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.MovementBehaviour;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.block.material.PushReaction;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.item.ItemUseContext;
|
import net.minecraft.item.ItemUseContext;
|
||||||
|
@ -25,7 +28,10 @@ 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 DeployerBlock extends DirectionalAxisKineticBlock implements IWithTileEntity<DeployerTileEntity> {
|
public class DeployerBlock extends DirectionalAxisKineticBlock
|
||||||
|
implements IWithTileEntity<DeployerTileEntity>, IPortableBlock {
|
||||||
|
|
||||||
|
public static MovementBehaviour MOVEMENT = new DeployerMovementBehaviour();
|
||||||
|
|
||||||
public DeployerBlock() {
|
public DeployerBlock() {
|
||||||
super(Properties.from(Blocks.ANDESITE));
|
super(Properties.from(Blocks.ANDESITE));
|
||||||
|
@ -41,6 +47,11 @@ public class DeployerBlock extends DirectionalAxisKineticBlock implements IWithT
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PushReaction getPushReaction(BlockState state) {
|
||||||
|
return PushReaction.PUSH_ONLY;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
|
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
|
||||||
return AllShapes.SHORT_CASING_12_VOXEL.get(state.get(FACING));
|
return AllShapes.SHORT_CASING_12_VOXEL.get(state.get(FACING));
|
||||||
|
@ -60,8 +71,12 @@ public class DeployerBlock extends DirectionalAxisKineticBlock implements IWithT
|
||||||
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
|
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||||
if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) {
|
if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) {
|
||||||
withTileEntityDo(worldIn, pos, te -> {
|
withTileEntityDo(worldIn, pos, te -> {
|
||||||
|
if (te.player != null && !isMoving) {
|
||||||
te.player.inventory.dropAllItems();
|
te.player.inventory.dropAllItems();
|
||||||
te.overflowItems.forEach(itemstack -> te.player.dropItem(itemstack, true, false));
|
te.overflowItems.forEach(itemstack -> te.player.dropItem(itemstack, true, false));
|
||||||
|
te.player.remove();
|
||||||
|
te.player = null;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
worldIn.removeTileEntity(pos);
|
worldIn.removeTileEntity(pos);
|
||||||
|
@ -112,4 +127,9 @@ public class DeployerBlock extends DirectionalAxisKineticBlock implements IWithT
|
||||||
return new Vec3d(0, yRot, zRot);
|
return new Vec3d(0, yRot, zRot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MovementBehaviour getMovementBehaviour() {
|
||||||
|
return MOVEMENT;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ package com.simibubi.create.modules.contraptions.components.deployer;
|
||||||
import java.util.OptionalInt;
|
import java.util.OptionalInt;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
import com.simibubi.create.foundation.utility.Lang;
|
||||||
|
|
||||||
|
@ -12,12 +14,14 @@ import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.Pose;
|
import net.minecraft.entity.Pose;
|
||||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||||
import net.minecraft.inventory.container.INamedContainerProvider;
|
import net.minecraft.inventory.container.INamedContainerProvider;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.network.IPacket;
|
import net.minecraft.network.IPacket;
|
||||||
import net.minecraft.network.NetworkManager;
|
import net.minecraft.network.NetworkManager;
|
||||||
import net.minecraft.network.PacketDirection;
|
import net.minecraft.network.PacketDirection;
|
||||||
import net.minecraft.network.play.ServerPlayNetHandler;
|
import net.minecraft.network.play.ServerPlayNetHandler;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.util.EntityDamageSource;
|
import net.minecraft.util.EntityDamageSource;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.util.text.ITextComponent;
|
import net.minecraft.util.text.ITextComponent;
|
||||||
import net.minecraft.util.text.StringTextComponent;
|
import net.minecraft.util.text.StringTextComponent;
|
||||||
|
@ -35,8 +39,10 @@ import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||||
public class DeployerFakePlayer extends FakePlayer {
|
public class DeployerFakePlayer extends FakePlayer {
|
||||||
|
|
||||||
private static final NetworkManager NETWORK_MANAGER = new NetworkManager(PacketDirection.CLIENTBOUND);
|
private static final NetworkManager NETWORK_MANAGER = new NetworkManager(PacketDirection.CLIENTBOUND);
|
||||||
public static final GameProfile DEPLOYER_PROFILE = new GameProfile(
|
public static final GameProfile DEPLOYER_PROFILE =
|
||||||
UUID.fromString("9e2faded-cafe-4ec2-c314-dad129ae971d"), "Deployer");
|
new GameProfile(UUID.fromString("9e2faded-cafe-4ec2-c314-dad129ae971d"), "Deployer");
|
||||||
|
Pair<BlockPos, Float> blockBreakingProgress;
|
||||||
|
ItemStack spawnedItemEffects;
|
||||||
|
|
||||||
public DeployerFakePlayer(ServerWorld world) {
|
public DeployerFakePlayer(ServerWorld world) {
|
||||||
super(world, DEPLOYER_PROFILE);
|
super(world, DEPLOYER_PROFILE);
|
||||||
|
@ -88,6 +94,13 @@ public class DeployerFakePlayer extends FakePlayer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove(boolean keepData) {
|
||||||
|
if (blockBreakingProgress != null && !world.isRemote)
|
||||||
|
world.sendBlockBreakProgress(getEntityId(), blockBreakingProgress.getKey(), -1);
|
||||||
|
super.remove(keepData);
|
||||||
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void deployerKillsDoNotSpawnXP(LivingExperienceDropEvent event) {
|
public static void deployerKillsDoNotSpawnXP(LivingExperienceDropEvent event) {
|
||||||
if (event.getAttackingPlayer() instanceof DeployerFakePlayer)
|
if (event.getAttackingPlayer() instanceof DeployerFakePlayer)
|
||||||
|
|
|
@ -0,0 +1,263 @@
|
||||||
|
package com.simibubi.create.modules.contraptions.components.deployer;
|
||||||
|
|
||||||
|
import static net.minecraftforge.eventbus.api.Event.Result.DENY;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
import com.simibubi.create.foundation.utility.WrappedWorld;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.deployer.DeployerTileEntity.Mode;
|
||||||
|
import com.simibubi.create.modules.curiosities.tools.SandPaperItem;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.block.material.Material;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.entity.ai.attributes.AttributeModifier;
|
||||||
|
import net.minecraft.entity.item.ItemEntity;
|
||||||
|
import net.minecraft.fluid.Fluid;
|
||||||
|
import net.minecraft.fluid.Fluids;
|
||||||
|
import net.minecraft.inventory.EquipmentSlotType;
|
||||||
|
import net.minecraft.item.BlockItem;
|
||||||
|
import net.minecraft.item.BlockItemUseContext;
|
||||||
|
import net.minecraft.item.BucketItem;
|
||||||
|
import net.minecraft.item.FlintAndSteelItem;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.ItemUseContext;
|
||||||
|
import net.minecraft.item.Items;
|
||||||
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.util.ActionResult;
|
||||||
|
import net.minecraft.util.ActionResultType;
|
||||||
|
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.RayTraceContext;
|
||||||
|
import net.minecraft.util.math.RayTraceContext.BlockMode;
|
||||||
|
import net.minecraft.util.math.RayTraceContext.FluidMode;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.server.ServerWorld;
|
||||||
|
import net.minecraftforge.common.ForgeHooks;
|
||||||
|
import net.minecraftforge.event.entity.player.PlayerInteractEvent.LeftClickBlock;
|
||||||
|
import net.minecraftforge.event.entity.player.PlayerInteractEvent.RightClickBlock;
|
||||||
|
import net.minecraftforge.eventbus.api.Event.Result;
|
||||||
|
|
||||||
|
public class DeployerHandler {
|
||||||
|
|
||||||
|
private static final class ItemUseWorld extends WrappedWorld {
|
||||||
|
private final Direction face;
|
||||||
|
private final BlockPos pos;
|
||||||
|
boolean rayMode = false;
|
||||||
|
|
||||||
|
private ItemUseWorld(World world, Direction face, BlockPos pos) {
|
||||||
|
super(world);
|
||||||
|
this.face = face;
|
||||||
|
this.pos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockRayTraceResult rayTraceBlocks(RayTraceContext context) {
|
||||||
|
rayMode = true;
|
||||||
|
BlockRayTraceResult rayTraceBlocks = super.rayTraceBlocks(context);
|
||||||
|
rayMode = false;
|
||||||
|
return rayTraceBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState getBlockState(BlockPos position) {
|
||||||
|
if (rayMode && (pos.offset(face.getOpposite(), 3).equals(position)
|
||||||
|
|| pos.offset(face.getOpposite(), 1).equals(position)))
|
||||||
|
return Blocks.BEDROCK.getDefaultState();
|
||||||
|
return world.getBlockState(position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean shouldActivate(ItemStack held, World world, BlockPos targetPos) {
|
||||||
|
if (held.getItem() instanceof BlockItem)
|
||||||
|
if (!world.getBlockState(targetPos).getMaterial().isReplaceable())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (held.getItem() instanceof BucketItem) {
|
||||||
|
BucketItem bucketItem = (BucketItem) held.getItem();
|
||||||
|
Fluid fluid = bucketItem.getFluid();
|
||||||
|
if (fluid != Fluids.EMPTY && world.getFluidState(targetPos).getFluid() == fluid)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void activate(DeployerFakePlayer player, Vec3d vec, BlockPos clickedPos, Vec3d extensionVector, Mode mode) {
|
||||||
|
Multimap<String, AttributeModifier> attributeModifiers =
|
||||||
|
player.getHeldItemMainhand().getAttributeModifiers(EquipmentSlotType.MAINHAND);
|
||||||
|
player.getAttributes().applyAttributeModifiers(attributeModifiers);
|
||||||
|
activateInner(player, vec, clickedPos, extensionVector, mode);
|
||||||
|
player.getAttributes().removeAttributeModifiers(attributeModifiers);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void activateInner(DeployerFakePlayer player, Vec3d vec, BlockPos clickedPos, Vec3d extensionVector,
|
||||||
|
Mode mode) {
|
||||||
|
|
||||||
|
Vec3d rayOrigin = vec.add(extensionVector.scale(3 / 2f + 1 / 64f));
|
||||||
|
Vec3d rayTarget = vec.add(extensionVector.scale(5 / 2f - 1 / 64f));
|
||||||
|
player.setPosition(rayOrigin.x, rayOrigin.y, rayOrigin.z);
|
||||||
|
BlockPos pos = new BlockPos(vec);
|
||||||
|
ItemStack stack = player.getHeldItemMainhand();
|
||||||
|
Item item = stack.getItem();
|
||||||
|
|
||||||
|
// Check for entities
|
||||||
|
final ServerWorld world = player.getServerWorld();
|
||||||
|
List<LivingEntity> entities = world.getEntitiesWithinAABB(LivingEntity.class, new AxisAlignedBB(clickedPos));
|
||||||
|
Hand hand = Hand.MAIN_HAND;
|
||||||
|
if (!entities.isEmpty()) {
|
||||||
|
LivingEntity entity = entities.get(world.rand.nextInt(entities.size()));
|
||||||
|
List<ItemEntity> capturedDrops = new ArrayList<>();
|
||||||
|
boolean success = false;
|
||||||
|
entity.captureDrops(capturedDrops);
|
||||||
|
|
||||||
|
// Use on entity
|
||||||
|
if (mode == Mode.USE) {
|
||||||
|
ActionResultType cancelResult = ForgeHooks.onInteractEntity(player, entity, hand);
|
||||||
|
if (cancelResult == ActionResultType.FAIL) {
|
||||||
|
entity.captureDrops(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (cancelResult == null) {
|
||||||
|
if (entity.processInitialInteract(player, hand))
|
||||||
|
success = true;
|
||||||
|
else if (stack.interactWithEntity(player, entity, hand))
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Punch entity
|
||||||
|
if (mode == Mode.PUNCH) {
|
||||||
|
player.resetCooldown();
|
||||||
|
player.attackTargetEntityWithCurrentItem(entity);
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
entity.captureDrops(null);
|
||||||
|
capturedDrops.forEach(e -> player.inventory.placeItemBackInInventory(world, e.getItem()));
|
||||||
|
if (success)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shoot ray
|
||||||
|
RayTraceContext rayTraceContext =
|
||||||
|
new RayTraceContext(rayOrigin, rayTarget, BlockMode.OUTLINE, FluidMode.NONE, player);
|
||||||
|
BlockRayTraceResult result = world.rayTraceBlocks(rayTraceContext);
|
||||||
|
BlockState clickedState = world.getBlockState(clickedPos);
|
||||||
|
Direction face = result.getFace();
|
||||||
|
if (face == null)
|
||||||
|
face = Direction.getFacingFromVector(extensionVector.x, extensionVector.y, extensionVector.z).getOpposite();
|
||||||
|
|
||||||
|
// Left click
|
||||||
|
if (mode == Mode.PUNCH) {
|
||||||
|
LeftClickBlock event = ForgeHooks.onLeftClickBlock(player, clickedPos, face);
|
||||||
|
if (event.isCanceled())
|
||||||
|
return;
|
||||||
|
if (!world.isBlockModifiable(player, clickedPos))
|
||||||
|
return;
|
||||||
|
if (world.extinguishFire(player, clickedPos, face))
|
||||||
|
return;
|
||||||
|
if (clickedState.isAir(world, clickedPos)) {
|
||||||
|
player.blockBreakingProgress = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (event.getUseBlock() != Result.DENY)
|
||||||
|
clickedState.onBlockClicked(world, clickedPos, player);
|
||||||
|
if (stack.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
float progress = clickedState.getPlayerRelativeBlockHardness(player, world, clickedPos) * 16;
|
||||||
|
float before = 0;
|
||||||
|
Pair<BlockPos, Float> blockBreakingProgress = player.blockBreakingProgress;
|
||||||
|
if (blockBreakingProgress != null)
|
||||||
|
before = blockBreakingProgress.getValue();
|
||||||
|
progress += before;
|
||||||
|
|
||||||
|
if (progress >= 1) {
|
||||||
|
player.interactionManager.tryHarvestBlock(clickedPos);
|
||||||
|
world.sendBlockBreakProgress(player.getEntityId(), clickedPos, -1);
|
||||||
|
player.blockBreakingProgress = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((int) (before * 10) != (int) (progress * 10))
|
||||||
|
world.sendBlockBreakProgress(player.getEntityId(), clickedPos, (int) (progress * 10));
|
||||||
|
player.blockBreakingProgress = Pair.of(clickedPos, progress);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Right click
|
||||||
|
ItemUseContext itemusecontext = new ItemUseContext(player, hand, result);
|
||||||
|
RightClickBlock event = ForgeHooks.onRightClickBlock(player, hand, clickedPos, face);
|
||||||
|
|
||||||
|
// Item has custom active use
|
||||||
|
if (event.getUseItem() != DENY) {
|
||||||
|
ActionResultType actionresult = stack.onItemUseFirst(itemusecontext);
|
||||||
|
if (actionresult != ActionResultType.PASS)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean holdingSomething = !player.getHeldItemMainhand().isEmpty();
|
||||||
|
boolean flag1 =
|
||||||
|
!(player.isSneaking() && holdingSomething) || (stack.doesSneakBypassUse(world, clickedPos, player));
|
||||||
|
|
||||||
|
// Use on block
|
||||||
|
if (event.getUseBlock() != DENY && flag1 && clickedState.onBlockActivated(world, player, hand, result))
|
||||||
|
return;
|
||||||
|
if (stack.isEmpty())
|
||||||
|
return;
|
||||||
|
if (event.getUseItem() == DENY)
|
||||||
|
return;
|
||||||
|
if (item instanceof BlockItem && !clickedState.isReplaceable(new BlockItemUseContext(itemusecontext)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Reposition fire placement for convenience
|
||||||
|
if (item == Items.FLINT_AND_STEEL) {
|
||||||
|
Direction newFace = result.getFace();
|
||||||
|
BlockPos newPos = result.getPos();
|
||||||
|
if (!FlintAndSteelItem.canSetFire(clickedState, world, clickedPos))
|
||||||
|
newFace = Direction.UP;
|
||||||
|
if (clickedState.getMaterial() == Material.AIR)
|
||||||
|
newPos = newPos.offset(face.getOpposite());
|
||||||
|
result = new BlockRayTraceResult(result.getHitVec(), newFace, newPos, result.isInside());
|
||||||
|
itemusecontext = new ItemUseContext(player, hand, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 'Inert' item use behaviour & block placement
|
||||||
|
ActionResultType onItemUse = stack.onItemUse(itemusecontext);
|
||||||
|
if (onItemUse == ActionResultType.SUCCESS)
|
||||||
|
return;
|
||||||
|
if (item == Items.ENDER_PEARL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// buckets create their own ray, We use a fake wall to contain the active area
|
||||||
|
World itemUseWorld = world;
|
||||||
|
if (item instanceof BucketItem || item instanceof SandPaperItem)
|
||||||
|
itemUseWorld = new ItemUseWorld(world, face, pos);
|
||||||
|
|
||||||
|
ActionResult<ItemStack> onItemRightClick = item.onItemRightClick(itemUseWorld, player, hand);
|
||||||
|
player.setHeldItem(hand, onItemRightClick.getResult());
|
||||||
|
|
||||||
|
CompoundNBT tag = stack.getOrCreateTag();
|
||||||
|
if (stack.getItem() instanceof SandPaperItem && tag.contains("Polishing"))
|
||||||
|
player.spawnedItemEffects = ItemStack.read(tag.getCompound("Polishing"));
|
||||||
|
if (stack.isFood())
|
||||||
|
player.spawnedItemEffects = stack.copy();
|
||||||
|
|
||||||
|
if (!player.getActiveItemStack().isEmpty())
|
||||||
|
player.setHeldItem(hand, stack.onItemUseFinish(world, player));
|
||||||
|
|
||||||
|
player.resetActiveHand();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,175 @@
|
||||||
|
package com.simibubi.create.modules.contraptions.components.deployer;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.item.ItemHelper;
|
||||||
|
import com.simibubi.create.foundation.utility.NBTHelper;
|
||||||
|
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
||||||
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.MovementBehaviour;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.MovementContext;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.deployer.DeployerTileEntity.Mode;
|
||||||
|
import com.simibubi.create.modules.logistics.item.filter.FilterItem;
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.server.ServerWorld;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
import net.minecraftforge.common.util.Constants.NBT;
|
||||||
|
|
||||||
|
public class DeployerMovementBehaviour extends MovementBehaviour {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vec3d getActiveAreaOffset(MovementContext context) {
|
||||||
|
return new Vec3d(context.state.get(DeployerBlock.FACING).getDirectionVec()).scale(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitNewPosition(MovementContext context, BlockPos pos) {
|
||||||
|
if (context.world.isRemote)
|
||||||
|
return;
|
||||||
|
|
||||||
|
tryGrabbingItem(context);
|
||||||
|
DeployerFakePlayer player = getPlayer(context);
|
||||||
|
Mode mode = getMode(context);
|
||||||
|
if (mode == Mode.USE && !DeployerHandler.shouldActivate(player.getHeldItemMainhand(), context.world, pos))
|
||||||
|
return;
|
||||||
|
|
||||||
|
activate(context, pos, player, mode);
|
||||||
|
tryDisposeOfExcess(context);
|
||||||
|
context.stall = player.blockBreakingProgress != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void activate(MovementContext context, BlockPos pos, DeployerFakePlayer player, Mode mode) {
|
||||||
|
Vec3d facingVec = new Vec3d(context.state.get(DeployerBlock.FACING).getDirectionVec());
|
||||||
|
facingVec = VecHelper.rotate(facingVec, context.rotation.x, context.rotation.y, context.rotation.z);
|
||||||
|
Vec3d vec = context.position.subtract(facingVec.scale(2));
|
||||||
|
|
||||||
|
player.rotationYaw = ContraptionEntity.yawFromVector(facingVec);
|
||||||
|
player.rotationPitch = ContraptionEntity.pitchFromVector(facingVec) - 90;
|
||||||
|
|
||||||
|
DeployerHandler.activate(player, vec, pos, facingVec, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick(MovementContext context) {
|
||||||
|
if (context.world.isRemote)
|
||||||
|
return;
|
||||||
|
if (!context.stall)
|
||||||
|
return;
|
||||||
|
|
||||||
|
DeployerFakePlayer player = getPlayer(context);
|
||||||
|
Mode mode = getMode(context);
|
||||||
|
|
||||||
|
Pair<BlockPos, Float> blockBreakingProgress = player.blockBreakingProgress;
|
||||||
|
if (blockBreakingProgress != null) {
|
||||||
|
int timer = context.data.getInt("Timer");
|
||||||
|
if (timer < 20) {
|
||||||
|
timer++;
|
||||||
|
context.data.putInt("Timer", timer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.data.remove("Timer");
|
||||||
|
activate(context, blockBreakingProgress.getKey(), player, mode);
|
||||||
|
tryDisposeOfExcess(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
context.stall = player.blockBreakingProgress != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stopMoving(MovementContext context) {
|
||||||
|
if (context.world.isRemote)
|
||||||
|
return;
|
||||||
|
tryDisposeOfEverything(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tryGrabbingItem(MovementContext context) {
|
||||||
|
DeployerFakePlayer player = getPlayer(context);
|
||||||
|
if (player == null)
|
||||||
|
return;
|
||||||
|
if (player.getHeldItemMainhand().isEmpty()) {
|
||||||
|
ItemStack held = ItemHelper.extract(context.contraption.inventory,
|
||||||
|
stack -> FilterItem.test(stack, getFilter(context)), 1, false);
|
||||||
|
player.setHeldItem(Hand.MAIN_HAND, held);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tryDisposeOfEverything(MovementContext context) {
|
||||||
|
DeployerFakePlayer player = getPlayer(context);
|
||||||
|
if (player == null)
|
||||||
|
return;
|
||||||
|
ItemStack held = player.getHeldItemMainhand();
|
||||||
|
if (!held.isEmpty()) {
|
||||||
|
dropItem(context, held);
|
||||||
|
player.setHeldItem(Hand.MAIN_HAND, ItemStack.EMPTY);
|
||||||
|
}
|
||||||
|
tryDisposeOfExcess(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tryDisposeOfExcess(MovementContext context) {
|
||||||
|
DeployerFakePlayer player = getPlayer(context);
|
||||||
|
if (player == null)
|
||||||
|
return;
|
||||||
|
PlayerInventory inv = player.inventory;
|
||||||
|
ItemStack filter = getFilter(context);
|
||||||
|
|
||||||
|
for (List<ItemStack> list : Arrays.asList(inv.armorInventory, inv.offHandInventory, inv.mainInventory)) {
|
||||||
|
for (int i = 0; i < list.size(); ++i) {
|
||||||
|
ItemStack itemstack = list.get(i);
|
||||||
|
if (itemstack.isEmpty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (list == inv.mainInventory && i == inv.currentItem && FilterItem.test(itemstack, filter))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
dropItem(context, itemstack);
|
||||||
|
list.set(i, ItemStack.EMPTY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeExtraData(MovementContext context) {
|
||||||
|
DeployerFakePlayer player = getPlayer(context);
|
||||||
|
if (player == null)
|
||||||
|
return;
|
||||||
|
context.data.put("HeldItem", player.getHeldItemMainhand().serializeNBT());
|
||||||
|
}
|
||||||
|
|
||||||
|
private DeployerFakePlayer getPlayer(MovementContext context) {
|
||||||
|
if (!(context.temporaryData instanceof DeployerFakePlayer) && context.world instanceof ServerWorld) {
|
||||||
|
DeployerFakePlayer deployerFakePlayer = new DeployerFakePlayer((ServerWorld) context.world);
|
||||||
|
deployerFakePlayer.inventory.read(context.tileData.getList("Inventory", NBT.TAG_COMPOUND));
|
||||||
|
if (context.data.contains("HeldItem"))
|
||||||
|
deployerFakePlayer.setHeldItem(Hand.MAIN_HAND, ItemStack.read(context.data.getCompound("HeldItem")));
|
||||||
|
context.tileData.remove("Inventory");
|
||||||
|
context.temporaryData = deployerFakePlayer;
|
||||||
|
}
|
||||||
|
return (DeployerFakePlayer) context.temporaryData;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemStack getFilter(MovementContext context) {
|
||||||
|
return ItemStack.read(context.tileData.getCompound("Filter"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Mode getMode(MovementContext context) {
|
||||||
|
return NBTHelper.readEnum(context.tileData.getString("Mode"), Mode.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public List<SuperByteBuffer> renderListInContraption(MovementContext context) {
|
||||||
|
return DeployerTileEntityRenderer.renderListInContraption(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
package com.simibubi.create.modules.contraptions.components.deployer;
|
package com.simibubi.create.modules.contraptions.components.deployer;
|
||||||
|
|
||||||
import static com.simibubi.create.modules.contraptions.base.DirectionalKineticBlock.FACING;
|
import static com.simibubi.create.modules.contraptions.base.DirectionalKineticBlock.FACING;
|
||||||
import static net.minecraftforge.eventbus.api.Event.Result.DENY;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -9,15 +8,12 @@ import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.advancement.AllCriterionTriggers;
|
|
||||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
|
||||||
import net.minecraft.tileentity.TileEntity;
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import com.google.common.collect.Multimap;
|
|
||||||
import com.simibubi.create.AllBlockPartials;
|
import com.simibubi.create.AllBlockPartials;
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.AllTileEntities;
|
import com.simibubi.create.AllTileEntities;
|
||||||
|
import com.simibubi.create.foundation.advancement.AllCriterionTriggers;
|
||||||
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
|
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
|
||||||
import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour;
|
import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour;
|
||||||
import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour.SlotPositioning;
|
import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour.SlotPositioning;
|
||||||
|
@ -25,32 +21,16 @@ import com.simibubi.create.foundation.behaviour.inventory.ExtractingBehaviour;
|
||||||
import com.simibubi.create.foundation.item.ItemHelper;
|
import com.simibubi.create.foundation.item.ItemHelper;
|
||||||
import com.simibubi.create.foundation.utility.NBTHelper;
|
import com.simibubi.create.foundation.utility.NBTHelper;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
import com.simibubi.create.foundation.utility.WrappedWorld;
|
|
||||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||||
import com.simibubi.create.modules.curiosities.tools.SandPaperItem;
|
import com.simibubi.create.modules.curiosities.tools.SandPaperItem;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import net.minecraft.block.material.Material;
|
|
||||||
import net.minecraft.entity.LivingEntity;
|
|
||||||
import net.minecraft.entity.ai.attributes.AttributeModifier;
|
|
||||||
import net.minecraft.entity.item.ItemEntity;
|
import net.minecraft.entity.item.ItemEntity;
|
||||||
import net.minecraft.entity.player.PlayerInventory;
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
import net.minecraft.fluid.Fluid;
|
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||||
import net.minecraft.fluid.Fluids;
|
|
||||||
import net.minecraft.inventory.EquipmentSlotType;
|
|
||||||
import net.minecraft.item.BlockItem;
|
|
||||||
import net.minecraft.item.BlockItemUseContext;
|
|
||||||
import net.minecraft.item.BucketItem;
|
|
||||||
import net.minecraft.item.FlintAndSteelItem;
|
|
||||||
import net.minecraft.item.Item;
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.item.ItemUseContext;
|
|
||||||
import net.minecraft.item.Items;
|
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.nbt.ListNBT;
|
import net.minecraft.nbt.ListNBT;
|
||||||
import net.minecraft.util.ActionResult;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.ActionResultType;
|
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.Hand;
|
import net.minecraft.util.Hand;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
|
@ -61,13 +41,8 @@ import net.minecraft.util.math.RayTraceContext;
|
||||||
import net.minecraft.util.math.RayTraceContext.BlockMode;
|
import net.minecraft.util.math.RayTraceContext.BlockMode;
|
||||||
import net.minecraft.util.math.RayTraceContext.FluidMode;
|
import net.minecraft.util.math.RayTraceContext.FluidMode;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.World;
|
|
||||||
import net.minecraft.world.server.ServerWorld;
|
import net.minecraft.world.server.ServerWorld;
|
||||||
import net.minecraftforge.common.ForgeHooks;
|
|
||||||
import net.minecraftforge.common.util.Constants.NBT;
|
import net.minecraftforge.common.util.Constants.NBT;
|
||||||
import net.minecraftforge.event.entity.player.PlayerInteractEvent.LeftClickBlock;
|
|
||||||
import net.minecraftforge.event.entity.player.PlayerInteractEvent.RightClickBlock;
|
|
||||||
import net.minecraftforge.eventbus.api.Event.Result;
|
|
||||||
import net.minecraftforge.items.IItemHandler;
|
import net.minecraftforge.items.IItemHandler;
|
||||||
import net.minecraftforge.items.ItemHandlerHelper;
|
import net.minecraftforge.items.ItemHandlerHelper;
|
||||||
|
|
||||||
|
@ -86,10 +61,7 @@ public class DeployerTileEntity extends KineticTileEntity {
|
||||||
protected float reach;
|
protected float reach;
|
||||||
protected boolean boop = false;
|
protected boolean boop = false;
|
||||||
protected List<ItemStack> overflowItems = new ArrayList<>();
|
protected List<ItemStack> overflowItems = new ArrayList<>();
|
||||||
protected Pair<BlockPos, Float> blockBreakingProgress;
|
|
||||||
|
|
||||||
private ListNBT deferredInventoryList;
|
private ListNBT deferredInventoryList;
|
||||||
private ItemStack spawnItemEffects;
|
|
||||||
|
|
||||||
enum State {
|
enum State {
|
||||||
WAITING, EXPANDING, RETRACTING, DUMPING;
|
WAITING, EXPANDING, RETRACTING, DUMPING;
|
||||||
|
@ -152,10 +124,10 @@ public class DeployerTileEntity extends KineticTileEntity {
|
||||||
|
|
||||||
if (getSpeed() == 0)
|
if (getSpeed() == 0)
|
||||||
return;
|
return;
|
||||||
if (!world.isRemote && blockBreakingProgress != null) {
|
if (!world.isRemote && player != null && player.blockBreakingProgress != null) {
|
||||||
if (world.isAirBlock(blockBreakingProgress.getKey())) {
|
if (world.isAirBlock(player.blockBreakingProgress.getKey())) {
|
||||||
world.sendBlockBreakProgress(player.getEntityId(), blockBreakingProgress.getKey(), -1);
|
world.sendBlockBreakProgress(player.getEntityId(), player.blockBreakingProgress.getKey(), -1);
|
||||||
blockBreakingProgress = null;
|
player.blockBreakingProgress = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (timer > 0) {
|
if (timer > 0) {
|
||||||
|
@ -191,50 +163,21 @@ public class DeployerTileEntity extends KineticTileEntity {
|
||||||
extracting.extract(1);
|
extracting.extract(1);
|
||||||
|
|
||||||
Direction facing = getBlockState().get(FACING);
|
Direction facing = getBlockState().get(FACING);
|
||||||
if (stack.getItem() instanceof BlockItem) {
|
if (mode == Mode.USE && !DeployerHandler.shouldActivate(stack, world, pos.offset(facing, 2))) {
|
||||||
if (!world.getBlockState(pos.offset(facing, 2)).getMaterial().isReplaceable()) {
|
|
||||||
timer = getTimerSpeed() * 10;
|
timer = getTimerSpeed() * 10;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (stack.getItem() instanceof BucketItem) {
|
|
||||||
BucketItem bucketItem = (BucketItem) stack.getItem();
|
|
||||||
Fluid fluid = bucketItem.getFluid();
|
|
||||||
if (fluid != Fluids.EMPTY && world.getFluidState(pos.offset(facing, 2)).getFluid() == fluid) {
|
|
||||||
timer = getTimerSpeed() * 10;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for advancement conditions
|
// Check for advancement conditions
|
||||||
if (mode == Mode.PUNCH && !boop) {
|
if (mode == Mode.PUNCH && !boop && startBoop(facing))
|
||||||
if (world.isAirBlock(pos.offset(facing,1)) && world.isAirBlock(pos.offset(facing,2))) {
|
|
||||||
BlockPos otherDeployer = pos.offset(facing, 4);
|
|
||||||
if (world.isBlockPresent(otherDeployer)){
|
|
||||||
TileEntity otherTile = world.getTileEntity(otherDeployer);
|
|
||||||
if (otherTile instanceof DeployerTileEntity){
|
|
||||||
DeployerTileEntity deployerTile = (DeployerTileEntity) otherTile;
|
|
||||||
if (world.getBlockState(otherDeployer).get(FACING).getOpposite() == facing && deployerTile.mode == Mode.PUNCH) {
|
|
||||||
//two facing deployer
|
|
||||||
boop = true;
|
|
||||||
reach = 1f;
|
|
||||||
timer = 1000;
|
|
||||||
state = State.EXPANDING;
|
|
||||||
sendData();
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
state = State.EXPANDING;
|
state = State.EXPANDING;
|
||||||
Vec3d movementVector = getMovementVector();
|
Vec3d movementVector = getMovementVector();
|
||||||
Vec3d rayOrigin = VecHelper.getCenterOf(pos).add(movementVector.scale(3 / 2f));
|
Vec3d rayOrigin = VecHelper.getCenterOf(pos).add(movementVector.scale(3 / 2f));
|
||||||
Vec3d rayTarget = VecHelper.getCenterOf(pos).add(movementVector.scale(5 / 2f));
|
Vec3d rayTarget = VecHelper.getCenterOf(pos).add(movementVector.scale(5 / 2f));
|
||||||
RayTraceContext rayTraceContext = new RayTraceContext(rayOrigin, rayTarget, BlockMode.OUTLINE,
|
RayTraceContext rayTraceContext =
|
||||||
FluidMode.NONE, player);
|
new RayTraceContext(rayOrigin, rayTarget, BlockMode.OUTLINE, FluidMode.NONE, player);
|
||||||
BlockRayTraceResult result = world.rayTraceBlocks(rayTraceContext);
|
BlockRayTraceResult result = world.rayTraceBlocks(rayTraceContext);
|
||||||
reach = (float) (.5f + Math.min(result.getHitVec().subtract(rayOrigin).length(), .75f));
|
reach = (float) (.5f + Math.min(result.getHitVec().subtract(rayOrigin).length(), .75f));
|
||||||
|
|
||||||
|
@ -244,37 +187,10 @@ public class DeployerTileEntity extends KineticTileEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == State.EXPANDING) {
|
if (state == State.EXPANDING) {
|
||||||
if (boop){
|
if (boop)
|
||||||
TileEntity otherTile = world.getTileEntity(pos.offset(getBlockState().get(FACING),4));
|
triggerBoop();
|
||||||
if (otherTile instanceof DeployerTileEntity){
|
else
|
||||||
DeployerTileEntity deployerTile = (DeployerTileEntity) otherTile;
|
|
||||||
if (deployerTile.boop && deployerTile.state == State.EXPANDING){
|
|
||||||
if(deployerTile.timer <= 0){
|
|
||||||
//everything should be met
|
|
||||||
boop = false;
|
|
||||||
state = State.RETRACTING;
|
|
||||||
timer = 1000;
|
|
||||||
deployerTile.boop = false;
|
|
||||||
deployerTile.state = State.RETRACTING;
|
|
||||||
deployerTile.timer = 1000;
|
|
||||||
|
|
||||||
deployerTile.sendData();
|
|
||||||
sendData();
|
|
||||||
|
|
||||||
//award nearby players
|
|
||||||
List<ServerPlayerEntity> players = world.getEntitiesWithinAABB(ServerPlayerEntity.class, new AxisAlignedBB(pos).grow(9));
|
|
||||||
players.forEach(AllCriterionTriggers.DEPLOYER_BOOP::trigger);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Multimap<String, AttributeModifier> attributeModifiers = stack
|
|
||||||
.getAttributeModifiers(EquipmentSlotType.MAINHAND);
|
|
||||||
player.getAttributes().applyAttributeModifiers(attributeModifiers);
|
|
||||||
activate();
|
activate();
|
||||||
player.getAttributes().removeAttributeModifiers(attributeModifiers);
|
|
||||||
heldItem = player.getHeldItemMainhand();
|
|
||||||
|
|
||||||
state = State.RETRACTING;
|
state = State.RETRACTING;
|
||||||
timer = 1000;
|
timer = 1000;
|
||||||
|
@ -292,183 +208,61 @@ public class DeployerTileEntity extends KineticTileEntity {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean startBoop(Direction facing) {
|
||||||
|
if (!world.isAirBlock(pos.offset(facing, 1)) || !world.isAirBlock(pos.offset(facing, 2)))
|
||||||
|
return false;
|
||||||
|
BlockPos otherDeployer = pos.offset(facing, 4);
|
||||||
|
if (!world.isBlockPresent(otherDeployer))
|
||||||
|
return false;
|
||||||
|
TileEntity otherTile = world.getTileEntity(otherDeployer);
|
||||||
|
if (!(otherTile instanceof DeployerTileEntity))
|
||||||
|
return false;
|
||||||
|
DeployerTileEntity deployerTile = (DeployerTileEntity) otherTile;
|
||||||
|
if (world.getBlockState(otherDeployer).get(FACING).getOpposite() != facing || deployerTile.mode != Mode.PUNCH)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
boop = true;
|
||||||
|
reach = 1f;
|
||||||
|
timer = 1000;
|
||||||
|
state = State.EXPANDING;
|
||||||
|
sendData();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void triggerBoop() {
|
||||||
|
TileEntity otherTile = world.getTileEntity(pos.offset(getBlockState().get(FACING), 4));
|
||||||
|
if (!(otherTile instanceof DeployerTileEntity))
|
||||||
|
return;
|
||||||
|
|
||||||
|
DeployerTileEntity deployerTile = (DeployerTileEntity) otherTile;
|
||||||
|
if (!deployerTile.boop || deployerTile.state != State.EXPANDING)
|
||||||
|
return;
|
||||||
|
if (deployerTile.timer > 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// everything should be met
|
||||||
|
boop = false;
|
||||||
|
deployerTile.boop = false;
|
||||||
|
deployerTile.state = State.RETRACTING;
|
||||||
|
deployerTile.timer = 1000;
|
||||||
|
deployerTile.sendData();
|
||||||
|
|
||||||
|
// award nearby players
|
||||||
|
List<ServerPlayerEntity> players =
|
||||||
|
world.getEntitiesWithinAABB(ServerPlayerEntity.class, new AxisAlignedBB(pos).grow(9));
|
||||||
|
players.forEach(AllCriterionTriggers.DEPLOYER_BOOP::trigger);
|
||||||
|
}
|
||||||
|
|
||||||
protected void activate() {
|
protected void activate() {
|
||||||
// Update player position and angle
|
|
||||||
Vec3d movementVector = getMovementVector();
|
Vec3d movementVector = getMovementVector();
|
||||||
Direction direction = getBlockState().get(FACING);
|
Direction direction = getBlockState().get(FACING);
|
||||||
Vec3d center = VecHelper.getCenterOf(pos);
|
Vec3d center = VecHelper.getCenterOf(pos);
|
||||||
Vec3d rayOrigin = center.add(movementVector.scale(3 / 2f + 1 / 64f));
|
|
||||||
Vec3d rayTarget = center.add(movementVector.scale(5 / 2f - 1 / 64f));
|
|
||||||
BlockPos clickedPos = pos.offset(direction, 2);
|
BlockPos clickedPos = pos.offset(direction, 2);
|
||||||
|
|
||||||
player.rotationYaw = direction.getHorizontalAngle();
|
player.rotationYaw = direction.getHorizontalAngle();
|
||||||
player.rotationPitch = direction == Direction.UP ? -90 : direction == Direction.DOWN ? 90 : 0;
|
player.rotationPitch = direction == Direction.UP ? -90 : direction == Direction.DOWN ? 90 : 0;
|
||||||
player.setPosition(rayOrigin.x, rayOrigin.y, rayOrigin.z);
|
|
||||||
|
|
||||||
ItemStack stack = player.getHeldItemMainhand();
|
DeployerHandler.activate(player, center, clickedPos, movementVector, mode);
|
||||||
Item item = stack.getItem();
|
heldItem = player.getHeldItemMainhand();
|
||||||
|
|
||||||
// Check for entities
|
|
||||||
World world = this.world;
|
|
||||||
List<LivingEntity> entities = world.getEntitiesWithinAABB(LivingEntity.class, new AxisAlignedBB(clickedPos));
|
|
||||||
Hand hand = Hand.MAIN_HAND;
|
|
||||||
if (!entities.isEmpty()) {
|
|
||||||
LivingEntity entity = entities.get(world.rand.nextInt(entities.size()));
|
|
||||||
List<ItemEntity> capturedDrops = new ArrayList<>();
|
|
||||||
boolean success = false;
|
|
||||||
entity.captureDrops(capturedDrops);
|
|
||||||
|
|
||||||
// Use on entity
|
|
||||||
if (mode == Mode.USE) {
|
|
||||||
ActionResultType cancelResult = ForgeHooks.onInteractEntity(player, entity, hand);
|
|
||||||
if (cancelResult == ActionResultType.FAIL) {
|
|
||||||
entity.captureDrops(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (cancelResult == null) {
|
|
||||||
if (entity.processInitialInteract(player, hand))
|
|
||||||
success = true;
|
|
||||||
else if (stack.interactWithEntity(player, entity, hand))
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Punch entity
|
|
||||||
if (mode == Mode.PUNCH) {
|
|
||||||
player.resetCooldown();
|
|
||||||
player.attackTargetEntityWithCurrentItem(entity);
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
entity.captureDrops(null);
|
|
||||||
capturedDrops.forEach(e -> player.inventory.placeItemBackInInventory(this.world, e.getItem()));
|
|
||||||
if (success)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shoot ray
|
|
||||||
RayTraceContext rayTraceContext = new RayTraceContext(rayOrigin, rayTarget, BlockMode.OUTLINE, FluidMode.NONE,
|
|
||||||
player);
|
|
||||||
BlockRayTraceResult result = world.rayTraceBlocks(rayTraceContext);
|
|
||||||
BlockState clickedState = world.getBlockState(clickedPos);
|
|
||||||
|
|
||||||
// Left click
|
|
||||||
if (mode == Mode.PUNCH) {
|
|
||||||
LeftClickBlock event = ForgeHooks.onLeftClickBlock(player, clickedPos, direction.getOpposite());
|
|
||||||
if (event.isCanceled())
|
|
||||||
return;
|
|
||||||
if (!world.isBlockModifiable(player, clickedPos))
|
|
||||||
return;
|
|
||||||
if (world.extinguishFire(player, clickedPos, direction.getOpposite()))
|
|
||||||
return;
|
|
||||||
if (clickedState.isAir(world, clickedPos))
|
|
||||||
return;
|
|
||||||
if (event.getUseBlock() != Result.DENY)
|
|
||||||
clickedState.onBlockClicked(world, clickedPos, player);
|
|
||||||
if (stack.isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
float progress = clickedState.getPlayerRelativeBlockHardness(player, world, clickedPos) * 16;
|
|
||||||
float before = 0;
|
|
||||||
if (blockBreakingProgress != null)
|
|
||||||
before = blockBreakingProgress.getValue();
|
|
||||||
progress += before;
|
|
||||||
|
|
||||||
if (progress >= 1) {
|
|
||||||
player.interactionManager.tryHarvestBlock(clickedPos);
|
|
||||||
world.sendBlockBreakProgress(player.getEntityId(), clickedPos, -1);
|
|
||||||
blockBreakingProgress = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((int) (before * 10) != (int) (progress * 10))
|
|
||||||
world.sendBlockBreakProgress(player.getEntityId(), clickedPos, (int) (progress * 10));
|
|
||||||
blockBreakingProgress = Pair.of(clickedPos, progress);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Right click
|
|
||||||
ItemUseContext itemusecontext = new ItemUseContext(player, hand, result);
|
|
||||||
RightClickBlock event = ForgeHooks.onRightClickBlock(player, hand, clickedPos, direction.getOpposite());
|
|
||||||
|
|
||||||
// Item has custom active use
|
|
||||||
if (event.getUseItem() != DENY) {
|
|
||||||
ActionResultType actionresult = stack.onItemUseFirst(itemusecontext);
|
|
||||||
if (actionresult != ActionResultType.PASS)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean holdingSomething = !player.getHeldItemMainhand().isEmpty();
|
|
||||||
boolean flag1 = !(player.isSneaking() && holdingSomething)
|
|
||||||
|| (stack.doesSneakBypassUse(world, clickedPos, player));
|
|
||||||
|
|
||||||
// Use on block
|
|
||||||
if (event.getUseBlock() != DENY && flag1 && clickedState.onBlockActivated(world, player, hand, result))
|
|
||||||
return;
|
|
||||||
if (stack.isEmpty())
|
|
||||||
return;
|
|
||||||
if (event.getUseItem() == DENY)
|
|
||||||
return;
|
|
||||||
if (item instanceof BlockItem && !clickedState.isReplaceable(new BlockItemUseContext(itemusecontext)))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Reposition fire placement for convenience
|
|
||||||
if (item == Items.FLINT_AND_STEEL) {
|
|
||||||
Direction newFace = result.getFace();
|
|
||||||
BlockPos newPos = result.getPos();
|
|
||||||
if (!FlintAndSteelItem.canSetFire(clickedState, world, clickedPos))
|
|
||||||
newFace = Direction.UP;
|
|
||||||
if (clickedState.getMaterial() == Material.AIR)
|
|
||||||
newPos = newPos.offset(direction);
|
|
||||||
result = new BlockRayTraceResult(result.getHitVec(), newFace, newPos, result.isInside());
|
|
||||||
itemusecontext = new ItemUseContext(player, hand, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 'Inert' item use behaviour & block placement
|
|
||||||
ActionResultType onItemUse = stack.onItemUse(itemusecontext);
|
|
||||||
if (onItemUse == ActionResultType.SUCCESS)
|
|
||||||
return;
|
|
||||||
if (item == Items.ENDER_PEARL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// buckets create their own ray, We use a fake wall to contain the active area
|
|
||||||
if (item instanceof BucketItem || item instanceof SandPaperItem) {
|
|
||||||
world = new WrappedWorld(world) {
|
|
||||||
|
|
||||||
boolean rayMode = false;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockRayTraceResult rayTraceBlocks(RayTraceContext context) {
|
|
||||||
rayMode = true;
|
|
||||||
BlockRayTraceResult rayTraceBlocks = super.rayTraceBlocks(context);
|
|
||||||
rayMode = false;
|
|
||||||
return rayTraceBlocks;
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState getBlockState(BlockPos position) {
|
|
||||||
if (rayMode
|
|
||||||
&& (pos.offset(direction, 3).equals(position) || pos.offset(direction, 1).equals(position)))
|
|
||||||
return Blocks.BEDROCK.getDefaultState();
|
|
||||||
return world.getBlockState(position);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionResult<ItemStack> onItemRightClick = item.onItemRightClick(world, player, hand);
|
|
||||||
player.setHeldItem(hand, onItemRightClick.getResult());
|
|
||||||
|
|
||||||
CompoundNBT tag = stack.getOrCreateTag();
|
|
||||||
if (stack.getItem() instanceof SandPaperItem && tag.contains("Polishing"))
|
|
||||||
spawnItemEffects = ItemStack.read(tag.getCompound("Polishing"));
|
|
||||||
if (stack.isFood())
|
|
||||||
spawnItemEffects = stack.copy();
|
|
||||||
|
|
||||||
if (!player.getActiveItemStack().isEmpty())
|
|
||||||
player.setHeldItem(hand, stack.onItemUseFinish(world, player));
|
|
||||||
|
|
||||||
player.resetActiveHand();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void returnAndDeposit() {
|
protected void returnAndDeposit() {
|
||||||
|
@ -556,11 +350,12 @@ public class DeployerTileEntity extends KineticTileEntity {
|
||||||
@Override
|
@Override
|
||||||
public CompoundNBT writeToClient(CompoundNBT compound) {
|
public CompoundNBT writeToClient(CompoundNBT compound) {
|
||||||
compound.putFloat("Reach", reach);
|
compound.putFloat("Reach", reach);
|
||||||
if (player != null)
|
if (player != null) {
|
||||||
compound.put("HeldItem", player.getHeldItemMainhand().serializeNBT());
|
compound.put("HeldItem", player.getHeldItemMainhand().serializeNBT());
|
||||||
if (spawnItemEffects != null) {
|
if (player.spawnedItemEffects != null) {
|
||||||
compound.put("Particle", spawnItemEffects.serializeNBT());
|
compound.put("Particle", player.spawnedItemEffects.serializeNBT());
|
||||||
spawnItemEffects = null;
|
player.spawnedItemEffects = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return super.writeToClient(compound);
|
return super.writeToClient(compound);
|
||||||
}
|
}
|
||||||
|
@ -584,14 +379,6 @@ public class DeployerTileEntity extends KineticTileEntity {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void remove() {
|
|
||||||
if (!world.isRemote && blockBreakingProgress != null)
|
|
||||||
world.sendBlockBreakProgress(player.getEntityId(), blockBreakingProgress.getKey(), -1);
|
|
||||||
super.remove();
|
|
||||||
player = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AllBlockPartials getHandPose() {
|
public AllBlockPartials getHandPose() {
|
||||||
return mode == Mode.PUNCH ? AllBlockPartials.DEPLOYER_HAND_PUNCHING
|
return mode == Mode.PUNCH ? AllBlockPartials.DEPLOYER_HAND_PUNCHING
|
||||||
: heldItem.isEmpty() ? AllBlockPartials.DEPLOYER_HAND_POINTING : AllBlockPartials.DEPLOYER_HAND_HOLDING;
|
: heldItem.isEmpty() ? AllBlockPartials.DEPLOYER_HAND_POINTING : AllBlockPartials.DEPLOYER_HAND_HOLDING;
|
||||||
|
|
|
@ -4,18 +4,23 @@ import static com.simibubi.create.modules.contraptions.base.DirectionalAxisKinet
|
||||||
import static com.simibubi.create.modules.contraptions.base.DirectionalKineticBlock.FACING;
|
import static com.simibubi.create.modules.contraptions.base.DirectionalKineticBlock.FACING;
|
||||||
import static net.minecraft.state.properties.BlockStateProperties.AXIS;
|
import static net.minecraft.state.properties.BlockStateProperties.AXIS;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
import com.simibubi.create.AllBlockPartials;
|
import com.simibubi.create.AllBlockPartials;
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.foundation.behaviour.filtering.FilteringRenderer;
|
import com.simibubi.create.foundation.behaviour.filtering.FilteringRenderer;
|
||||||
import com.simibubi.create.foundation.block.SafeTileEntityRenderer;
|
import com.simibubi.create.foundation.block.SafeTileEntityRenderer;
|
||||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||||
|
import com.simibubi.create.foundation.utility.NBTHelper;
|
||||||
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
||||||
import com.simibubi.create.foundation.utility.TessellatorHelper;
|
import com.simibubi.create.foundation.utility.TessellatorHelper;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
import com.simibubi.create.modules.contraptions.base.IRotate;
|
import com.simibubi.create.modules.contraptions.base.IRotate;
|
||||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
|
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.MovementContext;
|
||||||
import com.simibubi.create.modules.contraptions.components.deployer.DeployerTileEntity.Mode;
|
import com.simibubi.create.modules.contraptions.components.deployer.DeployerTileEntity.Mode;
|
||||||
import com.simibubi.create.modules.contraptions.components.deployer.DeployerTileEntity.State;
|
import com.simibubi.create.modules.contraptions.components.deployer.DeployerTileEntity.State;
|
||||||
|
|
||||||
|
@ -33,12 +38,14 @@ import net.minecraft.util.Direction.Axis;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public class DeployerTileEntityRenderer extends SafeTileEntityRenderer<DeployerTileEntity> {
|
public class DeployerTileEntityRenderer extends SafeTileEntityRenderer<DeployerTileEntity> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderWithGL(DeployerTileEntity te, double x, double y, double z, float partialTicks, int destroyStage) {
|
public void renderWithGL(DeployerTileEntity te, double x, double y, double z, float partialTicks,
|
||||||
|
int destroyStage) {
|
||||||
renderItem(te, x, y, z, partialTicks);
|
renderItem(te, x, y, z, partialTicks);
|
||||||
FilteringRenderer.renderOnTileEntity(te, x, y, z, partialTicks, destroyStage);
|
FilteringRenderer.renderOnTileEntity(te, x, y, z, partialTicks, destroyStage);
|
||||||
renderComponents(te, x, y, z, partialTicks);
|
renderComponents(te, x, y, z, partialTicks);
|
||||||
|
@ -64,8 +71,8 @@ public class DeployerTileEntityRenderer extends SafeTileEntityRenderer<DeployerT
|
||||||
GlStateManager.translatef(0, 1 / 8f, -1 / 16f);
|
GlStateManager.translatef(0, 1 / 8f, -1 / 16f);
|
||||||
|
|
||||||
ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer();
|
ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer();
|
||||||
boolean isBlockItem = (te.heldItem.getItem() instanceof BlockItem)
|
boolean isBlockItem =
|
||||||
&& itemRenderer.getModelWithOverrides(te.heldItem).isGui3d();
|
(te.heldItem.getItem() instanceof BlockItem) && itemRenderer.getModelWithOverrides(te.heldItem).isGui3d();
|
||||||
float scale = punching ? .75f : isBlockItem ? .75f - 1 / 64f : .5f;
|
float scale = punching ? .75f : isBlockItem ? .75f - 1 / 64f : .5f;
|
||||||
GlStateManager.scaled(scale, scale, scale);
|
GlStateManager.scaled(scale, scale, scale);
|
||||||
TransformType transform = punching ? TransformType.THIRD_PERSON_RIGHT_HAND : TransformType.FIXED;
|
TransformType transform = punching ? TransformType.THIRD_PERSON_RIGHT_HAND : TransformType.FIXED;
|
||||||
|
@ -84,8 +91,8 @@ public class DeployerTileEntityRenderer extends SafeTileEntityRenderer<DeployerT
|
||||||
BlockState blockState = te.getBlockState();
|
BlockState blockState = te.getBlockState();
|
||||||
BlockPos pos = te.getPos();
|
BlockPos pos = te.getPos();
|
||||||
|
|
||||||
SuperByteBuffer pole = renderAndTransform(AllBlockPartials.DEPLOYER_POLE, blockState, pos, true);
|
SuperByteBuffer pole = renderAndTransform(getWorld(), AllBlockPartials.DEPLOYER_POLE, blockState, pos, true);
|
||||||
SuperByteBuffer hand = renderAndTransform(te.getHandPose(), blockState, pos, false);
|
SuperByteBuffer hand = renderAndTransform(getWorld(), te.getHandPose(), blockState, pos, false);
|
||||||
|
|
||||||
Vec3d offset = getHandOffset(te, partialTicks, blockState);
|
Vec3d offset = getHandOffset(te, partialTicks, blockState);
|
||||||
pole.translate(x + offset.x, y + offset.y, z + offset.z).renderInto(buffer);
|
pole.translate(x + offset.x, y + offset.y, z + offset.z).renderInto(buffer);
|
||||||
|
@ -115,21 +122,44 @@ public class DeployerTileEntityRenderer extends SafeTileEntityRenderer<DeployerT
|
||||||
return AllBlocks.SHAFT.block.getDefaultState().with(AXIS, ((IRotate) state.getBlock()).getRotationAxis(state));
|
return AllBlocks.SHAFT.block.getDefaultState().with(AXIS, ((IRotate) state.getBlock()).getRotationAxis(state));
|
||||||
}
|
}
|
||||||
|
|
||||||
private SuperByteBuffer renderAndTransform(AllBlockPartials renderBlock, BlockState deployerState, BlockPos pos,
|
private static SuperByteBuffer renderAndTransform(World world, AllBlockPartials renderBlock,
|
||||||
boolean axisDirectionMatters) {
|
BlockState deployerState, BlockPos pos, boolean axisDirectionMatters) {
|
||||||
SuperByteBuffer buffer = renderBlock.renderOn(deployerState);
|
SuperByteBuffer buffer = renderBlock.renderOn(deployerState);
|
||||||
Direction facing = deployerState.get(FACING);
|
Direction facing = deployerState.get(FACING);
|
||||||
|
|
||||||
float zRotFirst = axisDirectionMatters
|
float zRotFirst =
|
||||||
&& (deployerState.get(AXIS_ALONG_FIRST_COORDINATE) ^ facing.getAxis() == Axis.Z) ? 90 : 0;
|
axisDirectionMatters && (deployerState.get(AXIS_ALONG_FIRST_COORDINATE) ^ facing.getAxis() == Axis.Z) ? 90
|
||||||
|
: 0;
|
||||||
float yRot = AngleHelper.horizontalAngle(facing);
|
float yRot = AngleHelper.horizontalAngle(facing);
|
||||||
float zRot = facing == Direction.UP ? 270 : facing == Direction.DOWN ? 90 : 0;
|
float zRot = facing == Direction.UP ? 270 : facing == Direction.DOWN ? 90 : 0;
|
||||||
|
|
||||||
buffer.rotateCentered(Axis.Z, (float) ((zRotFirst) / 180 * Math.PI));
|
buffer.rotateCentered(Axis.Z, (float) ((zRotFirst) / 180 * Math.PI));
|
||||||
buffer.rotateCentered(Axis.Y, (float) ((yRot) / 180 * Math.PI));
|
buffer.rotateCentered(Axis.Y, (float) ((yRot) / 180 * Math.PI));
|
||||||
buffer.rotateCentered(Axis.Z, (float) ((zRot) / 180 * Math.PI));
|
buffer.rotateCentered(Axis.Z, (float) ((zRot) / 180 * Math.PI));
|
||||||
buffer.light(deployerState.getPackedLightmapCoords(getWorld(), pos));
|
buffer.light(deployerState.getPackedLightmapCoords(world, pos));
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<SuperByteBuffer> renderListInContraption(MovementContext context) {
|
||||||
|
BlockState blockState = context.state;
|
||||||
|
BlockPos pos = BlockPos.ZERO;
|
||||||
|
Mode mode = NBTHelper.readEnum(context.tileData.getString("Mode"), Mode.class);
|
||||||
|
World world = context.world;
|
||||||
|
AllBlockPartials handPose =
|
||||||
|
mode == Mode.PUNCH ? AllBlockPartials.DEPLOYER_HAND_PUNCHING : AllBlockPartials.DEPLOYER_HAND_POINTING;
|
||||||
|
|
||||||
|
SuperByteBuffer pole = renderAndTransform(world, AllBlockPartials.DEPLOYER_POLE, blockState, pos, true);
|
||||||
|
SuperByteBuffer hand = renderAndTransform(world, handPose, blockState, pos, false);
|
||||||
|
|
||||||
|
Vec3d center = VecHelper.getCenterOf(new BlockPos(context.position));
|
||||||
|
double distance = context.position.distanceTo(center);
|
||||||
|
double nextDistance = context.position.add(context.motion).distanceTo(center);
|
||||||
|
Vec3d offset = new Vec3d(blockState.get(FACING).getDirectionVec())
|
||||||
|
.scale(.5f - MathHelper.lerp(Minecraft.getInstance().getRenderPartialTicks(), distance, nextDistance));
|
||||||
|
pole.translate(offset.x, offset.y, offset.z);
|
||||||
|
hand.translate(offset.x, offset.y, offset.z);
|
||||||
|
|
||||||
|
return Arrays.asList(pole, hand);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,6 +138,7 @@ public class FlexcrateBlock extends ProperDirectionalBlock {
|
||||||
|
|
||||||
if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) {
|
if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) {
|
||||||
FlexcrateTileEntity te = (FlexcrateTileEntity) worldIn.getTileEntity(pos);
|
FlexcrateTileEntity te = (FlexcrateTileEntity) worldIn.getTileEntity(pos);
|
||||||
|
if (!isMoving)
|
||||||
te.onDestroyed();
|
te.onDestroyed();
|
||||||
worldIn.removeTileEntity(pos);
|
worldIn.removeTileEntity(pos);
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,6 +157,9 @@ public class FilterItem extends Item implements INamedContainerProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean test(ItemStack stack, ItemStack filter, boolean matchNBT) {
|
private static boolean test(ItemStack stack, ItemStack filter, boolean matchNBT) {
|
||||||
|
if (filter.isEmpty())
|
||||||
|
return true;
|
||||||
|
|
||||||
if (!(filter.getItem() instanceof FilterItem))
|
if (!(filter.getItem() instanceof FilterItem))
|
||||||
return (matchNBT ? ItemHandlerHelper.canItemStacksStack(filter, stack)
|
return (matchNBT ? ItemHandlerHelper.canItemStacksStack(filter, stack)
|
||||||
: ItemStack.areItemsEqual(filter, stack));
|
: ItemStack.areItemsEqual(filter, stack));
|
||||||
|
|
Loading…
Reference in a new issue