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;
|
||||
}
|
||||
float target = ((float) getSyncInterval()) / Math.max(clientTimer, 1);
|
||||
modifier.target(target);
|
||||
modifier.target(Math.min(target, 1));
|
||||
clientTimer = 0;
|
||||
|
||||
});
|
||||
|
|
|
@ -150,17 +150,15 @@ public class Contraption {
|
|||
return false;
|
||||
|
||||
for (int limit = 1000; limit > 0; limit--) {
|
||||
if (frontier.isEmpty()) {
|
||||
onAssembled(world, pos);
|
||||
if (frontier.isEmpty())
|
||||
return true;
|
||||
}
|
||||
if (!moveBlock(world, frontier.remove(0), direction, frontier, visited))
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void onAssembled(World world, BlockPos pos) {
|
||||
public void gatherStoredItems() {
|
||||
List<IItemHandlerModifiable> list =
|
||||
storage.values().stream().map(MountedStorage::getItemHandler).collect(Collectors.toList());
|
||||
inventory = new CombinedInvWrapper(Arrays.copyOf(list.toArray(), list.size(), IItemHandlerModifiable[].class));
|
||||
|
@ -504,7 +502,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(world, comp);
|
||||
MovementContext context = MovementContext.readNBT(world, info, comp);
|
||||
context.contraption = this;
|
||||
getActors().add(MutablePair.of(info, context));
|
||||
});
|
||||
|
@ -549,6 +547,7 @@ public class Contraption {
|
|||
for (MutablePair<BlockInfo, MovementContext> actor : getActors()) {
|
||||
CompoundNBT compound = new CompoundNBT();
|
||||
compound.put("Pos", NBTUtil.writeBlockPos(actor.left.pos));
|
||||
getMovement(actor.left.state).writeExtraData(actor.right);
|
||||
actor.right.writeToNBT(compound);
|
||||
actorsNBT.add(compound);
|
||||
}
|
||||
|
@ -591,6 +590,7 @@ public class Contraption {
|
|||
}
|
||||
|
||||
public void removeBlocksFromWorld(IWorld world, BlockPos offset, BiPredicate<BlockPos, BlockState> customRemoval) {
|
||||
storage.values().forEach(MountedStorage::empty);
|
||||
for (BlockInfo block : blocks.values()) {
|
||||
BlockPos add = block.pos.add(anchor).add(offset);
|
||||
if (customRemoval.test(add, block.state))
|
||||
|
@ -635,10 +635,9 @@ public class Contraption {
|
|||
|
||||
public void initActors(World world) {
|
||||
for (MutablePair<BlockInfo, MovementContext> pair : actors) {
|
||||
BlockState blockState = pair.left.state;
|
||||
MovementContext context = new MovementContext(world, blockState);
|
||||
MovementContext context = new MovementContext(world, pair.left);
|
||||
context.contraption = this;
|
||||
getMovement(blockState).startMoving(context);
|
||||
getMovement(pair.left.state).startMoving(context);
|
||||
pair.setRight(context);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,6 +70,8 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
|||
this.prevYaw = initialAngle;
|
||||
this.yaw = initialAngle;
|
||||
this.targetYaw = initialAngle;
|
||||
if (contraption != null)
|
||||
contraption.gatherStoredItems();
|
||||
}
|
||||
|
||||
public <T extends TileEntity & IControlContraption> ContraptionEntity controlledBy(T controller) {
|
||||
|
@ -84,15 +86,15 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
|||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
attachToController();
|
||||
|
||||
|
||||
Entity e = getRidingEntity();
|
||||
if (e != null) {
|
||||
Vec3d movementVector = e.getMotion();
|
||||
Vec3d motion = movementVector.normalize();
|
||||
if (motion.length() > 0) {
|
||||
targetYaw = yawFromMotion(motion);
|
||||
targetYaw = yawFromVector(motion);
|
||||
targetPitch = (float) ((Math.atan(motion.y) * 73.0D) / Math.PI * 180);
|
||||
if (targetYaw < 0)
|
||||
targetYaw += 360;
|
||||
|
@ -254,8 +256,12 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
|||
disassemble();
|
||||
}
|
||||
|
||||
public static float yawFromMotion(Vec3d motion) {
|
||||
return (float) ((3 * Math.PI / 2 + Math.atan2(motion.z, motion.x)) / Math.PI * 180);
|
||||
public static float yawFromVector(Vec3d vec) {
|
||||
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) {
|
||||
|
|
|
@ -69,17 +69,18 @@ public class ContraptionRenderer {
|
|||
context.world = world;
|
||||
|
||||
BlockInfo blockInfo = actor.getLeft();
|
||||
SuperByteBuffer render = Contraption.getMovement(blockInfo.state).renderInContraption(context);
|
||||
if (render == null)
|
||||
continue;
|
||||
for (SuperByteBuffer render : Contraption.getMovement(blockInfo.state).renderListInContraption(context)) {
|
||||
if (render == null)
|
||||
continue;
|
||||
|
||||
int posX = blockInfo.pos.getX();
|
||||
int posY = blockInfo.pos.getY();
|
||||
int posZ = blockInfo.pos.getZ();
|
||||
int posX = blockInfo.pos.getX();
|
||||
int posY = blockInfo.pos.getY();
|
||||
int posZ = blockInfo.pos.getZ();
|
||||
|
||||
render.translate(posX, posY, posZ);
|
||||
transform.accept(render);
|
||||
render.light((lx, ly, lz) -> getLight(world, lx, ly, lz)).renderInto(buffer);
|
||||
render.translate(posX, posY, posZ);
|
||||
transform.accept(render);
|
||||
render.light((lx, ly, lz) -> getLight(world, lx, ly, lz)).renderInto(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package com.simibubi.create.modules.contraptions.components.contraptions;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
|
@ -17,9 +15,14 @@ public class MountedStorage {
|
|||
|
||||
ItemStackHandler handler;
|
||||
boolean working;
|
||||
private TileEntity te;
|
||||
|
||||
public MountedStorage(TileEntity te) {
|
||||
this.te = te;
|
||||
handler = dummyHandler;
|
||||
}
|
||||
|
||||
public void empty() {
|
||||
if (te != null) {
|
||||
IItemHandler teHandler =
|
||||
te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).orElse(dummyHandler);
|
||||
|
@ -68,11 +71,8 @@ public class MountedStorage {
|
|||
if (te == null)
|
||||
return false;
|
||||
TileEntityType<?> type = te.getType();
|
||||
if (type == TileEntityType.CHEST || type == TileEntityType.SHULKER_BOX || type == TileEntityType.BARREL)
|
||||
if (type == TileEntityType.BARREL)
|
||||
return true;
|
||||
if (type == AllTileEntities.FLEXCRATE.type)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package com.simibubi.create.modules.contraptions.components.contraptions;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
||||
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
|
@ -45,8 +48,17 @@ public abstract class MovementBehaviour {
|
|||
return null;
|
||||
}
|
||||
|
||||
@OnlyIn(value = Dist.CLIENT)
|
||||
public List<SuperByteBuffer> renderListInContraption(MovementContext context) {
|
||||
return Arrays.asList(renderInContraption(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.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.NBTUtil;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
|
||||
import net.minecraftforge.common.util.Constants.NBT;
|
||||
|
||||
public class MovementContext {
|
||||
|
@ -17,14 +17,17 @@ public class MovementContext {
|
|||
public Vec3d rotation;
|
||||
public World world;
|
||||
public BlockState state;
|
||||
public CompoundNBT tileData;
|
||||
|
||||
public boolean stall;
|
||||
public CompoundNBT data;
|
||||
public Contraption contraption;
|
||||
public Object temporaryData;
|
||||
|
||||
public MovementContext(World world, BlockState state) {
|
||||
public MovementContext(World world, BlockInfo info) {
|
||||
this.world = world;
|
||||
this.state = state;
|
||||
this.state = info.state;
|
||||
this.tileData = info.nbt;
|
||||
|
||||
motion = Vec3d.ZERO;
|
||||
relativeMotion = Vec3d.ZERO;
|
||||
|
@ -44,9 +47,8 @@ public class MovementContext {
|
|||
return (((int) (length * modifier + 100 * Math.signum(length))) / 100) * 100;
|
||||
}
|
||||
|
||||
public static MovementContext readNBT(World world, CompoundNBT nbt) {
|
||||
BlockState state = NBTUtil.readBlockState(nbt.getCompound("State"));
|
||||
MovementContext context = new MovementContext(world, state);
|
||||
public static MovementContext readNBT(World world, BlockInfo info, CompoundNBT nbt) {
|
||||
MovementContext context = new MovementContext(world, info);
|
||||
context.motion = VecHelper.readNBT(nbt.getList("Motion", NBT.TAG_DOUBLE));
|
||||
context.relativeMotion = VecHelper.readNBT(nbt.getList("RelativeMotion", 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) {
|
||||
nbt.put("State", NBTUtil.writeBlockState(state));
|
||||
nbt.put("Motion", VecHelper.writeNBT(motion));
|
||||
nbt.put("RelativeMotion", VecHelper.writeNBT(relativeMotion));
|
||||
nbt.put("Rotation", VecHelper.writeNBT(rotation));
|
||||
|
|
|
@ -24,9 +24,12 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
|||
protected boolean assembleNextTick;
|
||||
protected boolean isWindmill;
|
||||
|
||||
protected float clientAngleDiff;
|
||||
|
||||
public MechanicalBearingTileEntity() {
|
||||
super(AllTileEntities.MECHANICAL_BEARING.type);
|
||||
isWindmill = false;
|
||||
setLazyTickRate(3);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -92,6 +95,16 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
|||
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) {
|
||||
if (movedContraption != null && movedContraption.isStalled())
|
||||
partialTicks = 0;
|
||||
|
@ -106,8 +119,10 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
|||
|
||||
public float getAngularSpeed() {
|
||||
float speed = getSpeed() * 3 / 10f;
|
||||
if (world.isRemote)
|
||||
if (world.isRemote) {
|
||||
speed *= ServerSpeedProvider.get();
|
||||
speed += clientAngleDiff / 3f;
|
||||
}
|
||||
return speed;
|
||||
}
|
||||
|
||||
|
@ -120,9 +135,9 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
|||
return;
|
||||
if (isWindmill && contraption.getSailBlocks() == 0)
|
||||
return;
|
||||
contraption.removeBlocksFromWorld(world, BlockPos.ZERO);
|
||||
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);
|
||||
|
||||
|
@ -150,17 +165,20 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
|||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
if (world.isRemote)
|
||||
clientAngleDiff /= 2;
|
||||
|
||||
if (running && Contraption.isFrozen())
|
||||
disassembleConstruct();
|
||||
|
||||
if (!world.isRemote && assembleNextTick) {
|
||||
assembleNextTick = false;
|
||||
if (running) {
|
||||
if (movedContraption != null)
|
||||
movedContraption.getContraption().stop(world);
|
||||
boolean canDisassemble = Math.abs(angle) < 45 || Math.abs(angle) > 7 * 45;
|
||||
if (speed == 0 && (canDisassemble || movedContraption == null
|
||||
|| movedContraption.getContraption().blocks.isEmpty())) {
|
||||
if (movedContraption != null)
|
||||
movedContraption.getContraption().stop(world);
|
||||
disassembleConstruct();
|
||||
}
|
||||
return;
|
||||
|
@ -184,6 +202,13 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
|||
applyRotation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lazyTick() {
|
||||
super.lazyTick();
|
||||
if (movedContraption != null && !world.isRemote)
|
||||
sendData();
|
||||
}
|
||||
|
||||
private void applyRotation() {
|
||||
if (movedContraption != null) {
|
||||
Axis axis = getBlockState().get(BlockStateProperties.FACING).getAxis();
|
||||
|
|
|
@ -76,7 +76,7 @@ public class CartAssemblerBlock extends AbstractRailBlock {
|
|||
if (contraption == null)
|
||||
return;
|
||||
ContraptionEntity entity = new ContraptionEntity(world, contraption,
|
||||
ContraptionEntity.yawFromMotion(cart.getMotion()));
|
||||
ContraptionEntity.yawFromVector(cart.getMotion()));
|
||||
entity.setPosition(pos.getX(), pos.getY(), pos.getZ());
|
||||
world.addEntity(entity);
|
||||
entity.startRiding(cart);
|
||||
|
|
|
@ -93,7 +93,8 @@ public class MechanicalPistonTileEntity extends KineticTileEntity implements ICo
|
|||
|
||||
if (!removed)
|
||||
getWorld().setBlockState(pos, getBlockState().with(MechanicalPistonBlock.STATE, PistonState.EXTENDED), 3);
|
||||
movedContraption.disassemble();
|
||||
if (movedContraption != null)
|
||||
movedContraption.disassemble();
|
||||
running = false;
|
||||
movedContraption = null;
|
||||
sendData();
|
||||
|
|
|
@ -6,9 +6,12 @@ import com.simibubi.create.foundation.utility.AllShapes;
|
|||
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
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.Blocks;
|
||||
import net.minecraft.block.material.PushReaction;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
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.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() {
|
||||
super(Properties.from(Blocks.ANDESITE));
|
||||
|
@ -41,6 +47,11 @@ public class DeployerBlock extends DirectionalAxisKineticBlock implements IWithT
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PushReaction getPushReaction(BlockState state) {
|
||||
return PushReaction.PUSH_ONLY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
|
||||
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) {
|
||||
if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) {
|
||||
withTileEntityDo(worldIn, pos, te -> {
|
||||
te.player.inventory.dropAllItems();
|
||||
te.overflowItems.forEach(itemstack -> te.player.dropItem(itemstack, true, false));
|
||||
if (te.player != null && !isMoving) {
|
||||
te.player.inventory.dropAllItems();
|
||||
te.overflowItems.forEach(itemstack -> te.player.dropItem(itemstack, true, false));
|
||||
te.player.remove();
|
||||
te.player = null;
|
||||
}
|
||||
});
|
||||
|
||||
worldIn.removeTileEntity(pos);
|
||||
|
@ -112,4 +127,9 @@ public class DeployerBlock extends DirectionalAxisKineticBlock implements IWithT
|
|||
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.UUID;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
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.player.ServerPlayerEntity;
|
||||
import net.minecraft.inventory.container.INamedContainerProvider;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.IPacket;
|
||||
import net.minecraft.network.NetworkManager;
|
||||
import net.minecraft.network.PacketDirection;
|
||||
import net.minecraft.network.play.ServerPlayNetHandler;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.EntityDamageSource;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
|
@ -35,14 +39,16 @@ import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
|||
public class DeployerFakePlayer extends FakePlayer {
|
||||
|
||||
private static final NetworkManager NETWORK_MANAGER = new NetworkManager(PacketDirection.CLIENTBOUND);
|
||||
public static final GameProfile DEPLOYER_PROFILE = new GameProfile(
|
||||
UUID.fromString("9e2faded-cafe-4ec2-c314-dad129ae971d"), "Deployer");
|
||||
public static final GameProfile DEPLOYER_PROFILE =
|
||||
new GameProfile(UUID.fromString("9e2faded-cafe-4ec2-c314-dad129ae971d"), "Deployer");
|
||||
Pair<BlockPos, Float> blockBreakingProgress;
|
||||
ItemStack spawnedItemEffects;
|
||||
|
||||
public DeployerFakePlayer(ServerWorld world) {
|
||||
super(world, DEPLOYER_PROFILE);
|
||||
connection = new FakePlayNetHandler(world.getServer(), this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public OptionalInt openContainer(INamedContainerProvider container) {
|
||||
return OptionalInt.empty();
|
||||
|
@ -73,7 +79,7 @@ public class DeployerFakePlayer extends FakePlayer {
|
|||
if (event.getEntity() instanceof DeployerFakePlayer)
|
||||
event.setNewHeight(0);
|
||||
}
|
||||
|
||||
|
||||
@SubscribeEvent
|
||||
public static void deployerCollectsDropsFromKilledEntities(LivingDropsEvent event) {
|
||||
if (!(event.getSource() instanceof EntityDamageSource))
|
||||
|
@ -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
|
||||
public static void deployerKillsDoNotSpawnXP(LivingExperienceDropEvent event) {
|
||||
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;
|
||||
|
||||
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.Arrays;
|
||||
|
@ -9,15 +8,12 @@ import java.util.Iterator;
|
|||
import java.util.List;
|
||||
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 com.google.common.collect.Multimap;
|
||||
import com.simibubi.create.AllBlockPartials;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
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.filtering.FilteringBehaviour;
|
||||
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.utility.NBTHelper;
|
||||
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.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.player.PlayerInventory;
|
||||
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.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUseContext;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.ListNBT;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Hand;
|
||||
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.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.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.ItemHandlerHelper;
|
||||
|
||||
|
@ -86,10 +61,7 @@ public class DeployerTileEntity extends KineticTileEntity {
|
|||
protected float reach;
|
||||
protected boolean boop = false;
|
||||
protected List<ItemStack> overflowItems = new ArrayList<>();
|
||||
protected Pair<BlockPos, Float> blockBreakingProgress;
|
||||
|
||||
private ListNBT deferredInventoryList;
|
||||
private ItemStack spawnItemEffects;
|
||||
|
||||
enum State {
|
||||
WAITING, EXPANDING, RETRACTING, DUMPING;
|
||||
|
@ -152,10 +124,10 @@ public class DeployerTileEntity extends KineticTileEntity {
|
|||
|
||||
if (getSpeed() == 0)
|
||||
return;
|
||||
if (!world.isRemote && blockBreakingProgress != null) {
|
||||
if (world.isAirBlock(blockBreakingProgress.getKey())) {
|
||||
world.sendBlockBreakProgress(player.getEntityId(), blockBreakingProgress.getKey(), -1);
|
||||
blockBreakingProgress = null;
|
||||
if (!world.isRemote && player != null && player.blockBreakingProgress != null) {
|
||||
if (world.isAirBlock(player.blockBreakingProgress.getKey())) {
|
||||
world.sendBlockBreakProgress(player.getEntityId(), player.blockBreakingProgress.getKey(), -1);
|
||||
player.blockBreakingProgress = null;
|
||||
}
|
||||
}
|
||||
if (timer > 0) {
|
||||
|
@ -191,50 +163,21 @@ public class DeployerTileEntity extends KineticTileEntity {
|
|||
extracting.extract(1);
|
||||
|
||||
Direction facing = getBlockState().get(FACING);
|
||||
if (stack.getItem() instanceof BlockItem) {
|
||||
if (!world.getBlockState(pos.offset(facing, 2)).getMaterial().isReplaceable()) {
|
||||
timer = getTimerSpeed() * 10;
|
||||
return;
|
||||
}
|
||||
if (mode == Mode.USE && !DeployerHandler.shouldActivate(stack, world, pos.offset(facing, 2))) {
|
||||
timer = getTimerSpeed() * 10;
|
||||
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
|
||||
if (mode == Mode.PUNCH && !boop) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check for advancement conditions
|
||||
if (mode == Mode.PUNCH && !boop && startBoop(facing))
|
||||
return;
|
||||
|
||||
state = State.EXPANDING;
|
||||
Vec3d movementVector = getMovementVector();
|
||||
Vec3d rayOrigin = VecHelper.getCenterOf(pos).add(movementVector.scale(3 / 2f));
|
||||
Vec3d rayTarget = VecHelper.getCenterOf(pos).add(movementVector.scale(5 / 2f));
|
||||
RayTraceContext rayTraceContext = new RayTraceContext(rayOrigin, rayTarget, BlockMode.OUTLINE,
|
||||
FluidMode.NONE, player);
|
||||
RayTraceContext rayTraceContext =
|
||||
new RayTraceContext(rayOrigin, rayTarget, BlockMode.OUTLINE, FluidMode.NONE, player);
|
||||
BlockRayTraceResult result = world.rayTraceBlocks(rayTraceContext);
|
||||
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 (boop){
|
||||
TileEntity otherTile = world.getTileEntity(pos.offset(getBlockState().get(FACING),4));
|
||||
if (otherTile instanceof DeployerTileEntity){
|
||||
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();
|
||||
player.getAttributes().removeAttributeModifiers(attributeModifiers);
|
||||
heldItem = player.getHeldItemMainhand();
|
||||
if (boop)
|
||||
triggerBoop();
|
||||
else
|
||||
activate();
|
||||
|
||||
state = State.RETRACTING;
|
||||
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() {
|
||||
// Update player position and angle
|
||||
Vec3d movementVector = getMovementVector();
|
||||
Direction direction = getBlockState().get(FACING);
|
||||
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);
|
||||
|
||||
player.rotationYaw = direction.getHorizontalAngle();
|
||||
player.rotationPitch = direction == Direction.UP ? -90 : direction == Direction.DOWN ? 90 : 0;
|
||||
player.setPosition(rayOrigin.x, rayOrigin.y, rayOrigin.z);
|
||||
|
||||
ItemStack stack = player.getHeldItemMainhand();
|
||||
Item item = stack.getItem();
|
||||
|
||||
// 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();
|
||||
DeployerHandler.activate(player, center, clickedPos, movementVector, mode);
|
||||
heldItem = player.getHeldItemMainhand();
|
||||
}
|
||||
|
||||
protected void returnAndDeposit() {
|
||||
|
@ -556,11 +350,12 @@ public class DeployerTileEntity extends KineticTileEntity {
|
|||
@Override
|
||||
public CompoundNBT writeToClient(CompoundNBT compound) {
|
||||
compound.putFloat("Reach", reach);
|
||||
if (player != null)
|
||||
if (player != null) {
|
||||
compound.put("HeldItem", player.getHeldItemMainhand().serializeNBT());
|
||||
if (spawnItemEffects != null) {
|
||||
compound.put("Particle", spawnItemEffects.serializeNBT());
|
||||
spawnItemEffects = null;
|
||||
if (player.spawnedItemEffects != null) {
|
||||
compound.put("Particle", player.spawnedItemEffects.serializeNBT());
|
||||
player.spawnedItemEffects = null;
|
||||
}
|
||||
}
|
||||
return super.writeToClient(compound);
|
||||
}
|
||||
|
@ -584,14 +379,6 @@ public class DeployerTileEntity extends KineticTileEntity {
|
|||
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() {
|
||||
return mode == Mode.PUNCH ? AllBlockPartials.DEPLOYER_HAND_PUNCHING
|
||||
: 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 net.minecraft.state.properties.BlockStateProperties.AXIS;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.simibubi.create.AllBlockPartials;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.behaviour.filtering.FilteringRenderer;
|
||||
import com.simibubi.create.foundation.block.SafeTileEntityRenderer;
|
||||
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.TessellatorHelper;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.contraptions.base.IRotate;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
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.State;
|
||||
|
||||
|
@ -33,12 +38,14 @@ 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.World;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class DeployerTileEntityRenderer extends SafeTileEntityRenderer<DeployerTileEntity> {
|
||||
|
||||
@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);
|
||||
FilteringRenderer.renderOnTileEntity(te, x, y, z, partialTicks, destroyStage);
|
||||
renderComponents(te, x, y, z, partialTicks);
|
||||
|
@ -64,8 +71,8 @@ public class DeployerTileEntityRenderer extends SafeTileEntityRenderer<DeployerT
|
|||
GlStateManager.translatef(0, 1 / 8f, -1 / 16f);
|
||||
|
||||
ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer();
|
||||
boolean isBlockItem = (te.heldItem.getItem() instanceof BlockItem)
|
||||
&& itemRenderer.getModelWithOverrides(te.heldItem).isGui3d();
|
||||
boolean isBlockItem =
|
||||
(te.heldItem.getItem() instanceof BlockItem) && itemRenderer.getModelWithOverrides(te.heldItem).isGui3d();
|
||||
float scale = punching ? .75f : isBlockItem ? .75f - 1 / 64f : .5f;
|
||||
GlStateManager.scaled(scale, scale, scale);
|
||||
TransformType transform = punching ? TransformType.THIRD_PERSON_RIGHT_HAND : TransformType.FIXED;
|
||||
|
@ -84,8 +91,8 @@ public class DeployerTileEntityRenderer extends SafeTileEntityRenderer<DeployerT
|
|||
BlockState blockState = te.getBlockState();
|
||||
BlockPos pos = te.getPos();
|
||||
|
||||
SuperByteBuffer pole = renderAndTransform(AllBlockPartials.DEPLOYER_POLE, blockState, pos, true);
|
||||
SuperByteBuffer hand = renderAndTransform(te.getHandPose(), blockState, pos, false);
|
||||
SuperByteBuffer pole = renderAndTransform(getWorld(), AllBlockPartials.DEPLOYER_POLE, blockState, pos, true);
|
||||
SuperByteBuffer hand = renderAndTransform(getWorld(), te.getHandPose(), blockState, pos, false);
|
||||
|
||||
Vec3d offset = getHandOffset(te, partialTicks, blockState);
|
||||
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));
|
||||
}
|
||||
|
||||
private SuperByteBuffer renderAndTransform(AllBlockPartials renderBlock, BlockState deployerState, BlockPos pos,
|
||||
boolean axisDirectionMatters) {
|
||||
private static SuperByteBuffer renderAndTransform(World world, AllBlockPartials renderBlock,
|
||||
BlockState deployerState, BlockPos pos, boolean axisDirectionMatters) {
|
||||
SuperByteBuffer buffer = renderBlock.renderOn(deployerState);
|
||||
Direction facing = deployerState.get(FACING);
|
||||
|
||||
float zRotFirst = axisDirectionMatters
|
||||
&& (deployerState.get(AXIS_ALONG_FIRST_COORDINATE) ^ facing.getAxis() == Axis.Z) ? 90 : 0;
|
||||
float zRotFirst =
|
||||
axisDirectionMatters && (deployerState.get(AXIS_ALONG_FIRST_COORDINATE) ^ facing.getAxis() == Axis.Z) ? 90
|
||||
: 0;
|
||||
float yRot = AngleHelper.horizontalAngle(facing);
|
||||
float zRot = facing == Direction.UP ? 270 : facing == Direction.DOWN ? 90 : 0;
|
||||
|
||||
buffer.rotateCentered(Axis.Z, (float) ((zRotFirst) / 180 * Math.PI));
|
||||
buffer.rotateCentered(Axis.Y, (float) ((yRot) / 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;
|
||||
}
|
||||
|
||||
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,7 +138,8 @@ public class FlexcrateBlock extends ProperDirectionalBlock {
|
|||
|
||||
if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) {
|
||||
FlexcrateTileEntity te = (FlexcrateTileEntity) worldIn.getTileEntity(pos);
|
||||
te.onDestroyed();
|
||||
if (!isMoving)
|
||||
te.onDestroyed();
|
||||
worldIn.removeTileEntity(pos);
|
||||
}
|
||||
|
||||
|
|
|
@ -157,6 +157,9 @@ public class FilterItem extends Item implements INamedContainerProvider {
|
|||
}
|
||||
|
||||
private static boolean test(ItemStack stack, ItemStack filter, boolean matchNBT) {
|
||||
if (filter.isEmpty())
|
||||
return true;
|
||||
|
||||
if (!(filter.getItem() instanceof FilterItem))
|
||||
return (matchNBT ? ItemHandlerHelper.canItemStacksStack(filter, stack)
|
||||
: ItemStack.areItemsEqual(filter, stack));
|
||||
|
|
Loading…
Reference in a new issue