Assisted Placement, Part III

- blocks placed by helpers make sounds again
- helpers now trigger the proper event and can be cancelled
This commit is contained in:
Zelophed 2021-02-11 00:28:47 +01:00
parent cb2c56d772
commit f3fd32edd3
9 changed files with 94 additions and 156 deletions

View file

@ -64,16 +64,9 @@ public class SailBlock extends ProperDirectionalBlock {
public ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult ray) {
ItemStack heldItem = player.getHeldItem(hand);
if (AllBlocks.SAIL.isIn(heldItem) || AllBlocks.SAIL_FRAME.isIn(heldItem)) {
IPlacementHelper placementHelper = PlacementHelpers.get(placementHelperId);
PlacementOffset offset = placementHelper.getOffset(world, state, pos, ray);
if (!offset.isReplaceable(world))
return ActionResultType.PASS;
offset.placeInWorld(world, ((BlockItem) heldItem.getItem()).getBlock().getDefaultState(), player, heldItem);
return ActionResultType.SUCCESS;
}
IPlacementHelper placementHelper = PlacementHelpers.get(placementHelperId);
if (placementHelper.matchesItem(heldItem))
return placementHelper.getOffset(world, state, pos, ray).placeInWorld(world, (BlockItem) heldItem.getItem(), player, hand, ray);
if (heldItem.getItem() instanceof ShearsItem) {
if (!world.isRemote)

View file

@ -1,13 +1,9 @@
package com.simibubi.create.content.contraptions.components.structureMovement.glue;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.simibubi.create.AllItems;
import com.simibubi.create.foundation.networking.AllPackets;
import com.simibubi.create.foundation.utility.placement.IPlacementHelper;
import com.simibubi.create.foundation.utility.worldWrappers.RayTraceWorld;
import net.minecraft.block.Blocks;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
@ -15,12 +11,8 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.Direction;
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.*;
import net.minecraft.util.math.RayTraceResult.Type;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.IWorld;
import net.minecraft.world.World;
import net.minecraftforge.event.world.BlockEvent.EntityPlaceEvent;
@ -28,6 +20,10 @@ import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.network.PacketDistributor;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@EventBusSubscriber
public class SuperGlueHandler {
@ -65,6 +61,8 @@ public class SuperGlueHandler {
return;
if (AllItems.WRENCH.isIn(placer.getHeldItemMainhand()))
return;
if (event.getPlacedAgainst() == IPlacementHelper.ID)
return;
double distance = placer.getAttribute(PlayerEntity.REACH_DISTANCE)
.getValue();

View file

@ -7,7 +7,6 @@ import com.simibubi.create.content.contraptions.wrench.IWrenchable;
import com.simibubi.create.foundation.block.ProperDirectionalBlock;
import com.simibubi.create.foundation.utility.placement.IPlacementHelper;
import com.simibubi.create.foundation.utility.placement.PlacementHelpers;
import com.simibubi.create.foundation.utility.placement.PlacementOffset;
import com.simibubi.create.foundation.utility.placement.util.PoleHelper;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.block.Block;
@ -17,6 +16,7 @@ import net.minecraft.block.material.PushReaction;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.Fluids;
import net.minecraft.fluid.IFluidState;
import net.minecraft.item.BlockItem;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemStack;
import net.minecraft.state.StateContainer.Builder;
@ -114,26 +114,9 @@ public class PistonExtensionPoleBlock extends ProperDirectionalBlock implements
public ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult ray) {
ItemStack heldItem = player.getHeldItem(hand);
if (AllBlocks.PISTON_EXTENSION_POLE.isIn(heldItem) && !player.isSneaking()) {
IPlacementHelper placementHelper = PlacementHelpers.get(placementHelperId);
PlacementOffset offset = placementHelper.getOffset(world, state, pos, ray);
if (!offset.isReplaceable(world))
return ActionResultType.PASS;
offset.placeInWorld(world, AllBlocks.PISTON_EXTENSION_POLE.getDefaultState(), player, heldItem);
/*BlockPos newPos = new BlockPos(offset.getPos());
if (world.isRemote)
return ActionResultType.SUCCESS;
world.setBlockState(newPos, offset.getTransform().apply(AllBlocks.PISTON_EXTENSION_POLE.getDefaultState()));
if (!player.isCreative())
heldItem.shrink(1);*/
return ActionResultType.SUCCESS;
}
IPlacementHelper placementHelper = PlacementHelpers.get(placementHelperId);
if (placementHelper.matchesItem(heldItem) && !player.isSneaking())
return placementHelper.getOffset(world, state, pos, ray).placeInWorld(world, (BlockItem) heldItem.getItem(), player, hand, ray);
return ActionResultType.PASS;
}

View file

@ -1,9 +1,5 @@
package com.simibubi.create.content.contraptions.relays.advanced;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllShapes;
import com.simibubi.create.AllTileEntities;
@ -15,7 +11,6 @@ import com.simibubi.create.foundation.utility.placement.IPlacementHelper;
import com.simibubi.create.foundation.utility.placement.PlacementHelpers;
import com.simibubi.create.foundation.utility.placement.PlacementOffset;
import com.simibubi.create.foundation.utility.placement.util.PoleHelper;
import net.minecraft.block.Block;
import net.minecraft.block.BlockRenderType;
import net.minecraft.block.BlockState;
@ -44,6 +39,10 @@ import net.minecraft.world.IWorld;
import net.minecraft.world.IWorldReader;
import net.minecraft.world.World;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
public class GantryShaftBlock extends DirectionalKineticBlock {
public static final IProperty<Part> PART = EnumProperty.create("part", Part.class);
@ -66,22 +65,14 @@ public class GantryShaftBlock extends DirectionalKineticBlock {
}
@Override
public ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand,
BlockRayTraceResult ray) {
public ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult ray) {
ItemStack heldItem = player.getHeldItem(hand);
IPlacementHelper placementHelper = PlacementHelpers.get(placementHelperId);
if (!placementHelper.matchesItem(heldItem))
return ActionResultType.PASS;
PlacementOffset offset = placementHelper.getOffset(world, state, pos, ray);
if (!offset.isReplaceable(world))
return ActionResultType.PASS;
offset.placeInWorld(world, ((BlockItem) heldItem.getItem()).getBlock()
.getDefaultState(), player, heldItem);
return ActionResultType.SUCCESS;
return placementHelper.getOffset(world, state, pos, ray).placeInWorld(world, ((BlockItem) heldItem.getItem()), player, hand, ray);
}
@Override

View file

@ -1,7 +1,5 @@
package com.simibubi.create.content.contraptions.relays.advanced;
import java.util.function.Predicate;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllShapes;
import com.simibubi.create.AllTileEntities;
@ -13,11 +11,11 @@ import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.foundation.utility.placement.IPlacementHelper;
import com.simibubi.create.foundation.utility.placement.PlacementHelpers;
import com.simibubi.create.foundation.utility.placement.PlacementOffset;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItem;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
@ -32,6 +30,8 @@ import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import java.util.function.Predicate;
public class SpeedControllerBlock extends HorizontalAxisKineticBlock implements ITE<SpeedControllerTileEntity> {
private static final int placementHelperId = PlacementHelpers.register(new PlacementHelper());
@ -67,19 +67,10 @@ public class SpeedControllerBlock extends HorizontalAxisKineticBlock implements
public ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand,
BlockRayTraceResult ray) {
IPlacementHelper helper = PlacementHelpers.get(placementHelperId);
ItemStack heldItem = player.getHeldItem(hand);
if (helper.matchesItem(heldItem)) {
PlacementOffset offset = helper.getOffset(world, state, pos, ray);
if (!offset.isReplaceable(world))
return ActionResultType.PASS;
offset.placeInWorld(world, AllBlocks.LARGE_COGWHEEL.getDefaultState(), player, heldItem);
return ActionResultType.SUCCESS;
}
IPlacementHelper helper = PlacementHelpers.get(placementHelperId);
if (helper.matchesItem(heldItem))
return helper.getOffset(world, state, pos, ray).placeInWorld(world, (BlockItem) heldItem.getItem(), player, hand, ray);
return ActionResultType.PASS;
}

View file

@ -1,10 +1,5 @@
package com.simibubi.create.content.contraptions.relays.elementary;
import static com.simibubi.create.content.contraptions.base.RotatedPillarKineticBlock.AXIS;
import java.util.List;
import java.util.function.Predicate;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllShapes;
import com.simibubi.create.content.contraptions.base.DirectionalKineticBlock;
@ -16,13 +11,13 @@ import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.foundation.utility.placement.IPlacementHelper;
import com.simibubi.create.foundation.utility.placement.PlacementHelpers;
import com.simibubi.create.foundation.utility.placement.PlacementOffset;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItem;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUseContext;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis;
@ -31,6 +26,11 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.world.World;
import java.util.List;
import java.util.function.Predicate;
import static com.simibubi.create.content.contraptions.base.RotatedPillarKineticBlock.AXIS;
public class CogwheelBlockItem extends BlockItem {
boolean large;
@ -47,49 +47,27 @@ public class CogwheelBlockItem extends BlockItem {
}
@Override
public ActionResultType tryPlace(BlockItemUseContext context) {
public ActionResultType onItemUseFirst(ItemStack stack, ItemUseContext context) {
World world = context.getWorld();
BlockPos pos = context.getPos()
.offset(context.getFace()
.getOpposite());
BlockPos pos = context.getPos();
BlockState state = world.getBlockState(pos);
IPlacementHelper helper = PlacementHelpers.get(placementHelperId);
PlayerEntity player = context.getPlayer();
if (helper.matchesState(state)) {
PlacementOffset offset = helper.getOffset(world, state, pos,
new BlockRayTraceResult(context.getHitVec(), context.getFace(), pos, true));
if (!offset.isReplaceable(world))
return super.tryPlace(context);
offset.placeInWorld(world, this, player, context.getItem());
triggerShiftingGearsAdvancement(world, new BlockPos(offset.getPos()), offset.getTransform()
.apply(getBlock().getDefaultState()), player);
return ActionResultType.SUCCESS;
BlockRayTraceResult ray = new BlockRayTraceResult(context.getHitVec(), context.getFace(), pos, true);
if (helper.matchesState(state) && player != null && !player.isSneaking()) {
return helper.getOffset(world, state, pos, ray).placeInWorld(world, this, player, context.getHand(), ray);
}
if (integratedCogHelperId != -1) {
helper = PlacementHelpers.get(integratedCogHelperId);
if (helper.matchesState(state)) {
PlacementOffset offset = helper.getOffset(world, state, pos,
new BlockRayTraceResult(context.getHitVec(), context.getFace(), pos, true));
if (!offset.isReplaceable(world))
return super.tryPlace(context);
offset.placeInWorld(world, this, player, context.getItem());
triggerShiftingGearsAdvancement(world, new BlockPos(offset.getPos()), offset.getTransform()
.apply(getBlock().getDefaultState()), player);
return ActionResultType.SUCCESS;
if (helper.matchesState(state) && player != null && !player.isSneaking()) {
return helper.getOffset(world, state, pos, ray).placeInWorld(world, this, player, context.getHand(), ray);
}
}
return super.tryPlace(context);
return super.onItemUseFirst(stack, context);
}
@Override

View file

@ -7,7 +7,6 @@ import com.simibubi.create.content.contraptions.relays.encased.EncasedShaftBlock
import com.simibubi.create.foundation.advancement.AllTriggers;
import com.simibubi.create.foundation.utility.placement.IPlacementHelper;
import com.simibubi.create.foundation.utility.placement.PlacementHelpers;
import com.simibubi.create.foundation.utility.placement.PlacementOffset;
import com.simibubi.create.foundation.utility.placement.util.PoleHelper;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.block.BlockState;
@ -77,26 +76,8 @@ public class ShaftBlock extends AbstractShaftBlock {
}
IPlacementHelper helper = PlacementHelpers.get(placementHelperId);
if (helper.getItemPredicate().test(heldItem)) {
PlacementOffset offset = helper.getOffset(world, state, pos, ray);
if (!offset.isReplaceable(world))
return ActionResultType.PASS;
offset.placeInWorld(world, (BlockItem) heldItem.getItem(), player, heldItem);
/*BlockPos newPos = new BlockPos(offset.getPos());
if (world.isRemote)
return ActionResultType.SUCCESS;
Block block = ((BlockItem) heldItem.getItem()).getBlock();
world.setBlockState(newPos, offset.getTransform().apply(block.getDefaultState()));
if (!player.isCreative())
heldItem.shrink(1);*/
return ActionResultType.SUCCESS;
}
if (helper.matchesItem(heldItem))
return helper.getOffset(world, state, pos, ray).placeInWorld(world, (BlockItem) heldItem.getItem(), player, hand, ray);
return ActionResultType.PASS;
}

View file

@ -6,6 +6,7 @@ import com.simibubi.create.foundation.utility.Pair;
import com.simibubi.create.foundation.utility.VecHelper;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
@ -22,6 +23,11 @@ import java.util.stream.Collectors;
@MethodsReturnNonnullByDefault
public interface IPlacementHelper {
/**
* used as an identifier in SuperGlueHandler to skip blocks placed by helpers
*/
BlockState ID = new BlockState(Blocks.AIR, null);
/**
* @return a predicate that gets tested with the items held in the players hands,
* should return true if this placement helper is active with the given item
@ -61,24 +67,6 @@ public interface IPlacementHelper {
CreateClient.outliner.showLine("placementArrowB" + center + target, start.add(offset), endB.add(offset)).lineWidth(1/16f);
}
/*@OnlyIn(Dist.CLIENT)
static void renderArrow(Vec3d center, Direction towards, BlockRayTraceResult ray) {
Direction hitFace = ray.getFace();
if (hitFace.getAxis() == towards.getAxis())
return;
//get the two perpendicular directions to form the arrow
Direction[] directions = Arrays.stream(Direction.Axis.values()).filter(axis -> axis != hitFace.getAxis() && axis != towards.getAxis()).map(Iterate::directionsInAxis).findFirst().orElse(new Direction[]{});
Vec3d startOffset = new Vec3d(towards.getDirectionVec());
Vec3d start = center.add(startOffset);
for (Direction dir : directions) {
Vec3d arrowOffset = new Vec3d(dir.getDirectionVec()).scale(.25);
Vec3d target = center.add(startOffset.scale(0.75)).add(arrowOffset);
CreateClient.outliner.showLine("placementArrow" + towards + dir, start, target).lineWidth(1/16f);
}
}*/
static List<Direction> orderedByDistanceOnlyAxis(BlockPos pos, Vec3d hit, Direction.Axis axis) {
return orderedByDistance(pos, hit, dir -> dir.getAxis() == axis);
}

View file

@ -1,15 +1,26 @@
package com.simibubi.create.foundation.utility.placement;
import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.block.BlockState;
import net.minecraft.block.SoundType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.fluid.Fluids;
import net.minecraft.fluid.IFluidState;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUseContext;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.stats.Stats;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Hand;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.Vec3i;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.util.BlockSnapshot;
import net.minecraftforge.event.world.BlockEvent;
import java.util.function.Function;
@ -55,25 +66,49 @@ public class PlacementOffset {
return world.getBlockState(new BlockPos(pos)).getMaterial().isReplaceable();
}
public void placeInWorld(World world, BlockItem blockItem, PlayerEntity player, ItemStack item) {
placeInWorld(world, blockItem.getBlock().getDefaultState(), player, item);
}
public void placeInWorld(World world, BlockState defaultState, PlayerEntity player, ItemStack item) {
if (world.isRemote)
return;
public ActionResultType placeInWorld(World world, BlockItem blockItem, PlayerEntity player, Hand hand, BlockRayTraceResult ray) {
ItemUseContext context = new ItemUseContext(player, hand, ray);
BlockPos newPos = new BlockPos(pos);
BlockState state = stateTransform.apply(defaultState);
if (!world.isBlockModifiable(player, newPos))
return ActionResultType.PASS;
if (!isReplaceable(world))
return ActionResultType.PASS;
BlockState state = stateTransform.apply(blockItem.getBlock().getDefaultState());
if (state.has(BlockStateProperties.WATERLOGGED)) {
IFluidState fluidState = world.getFluidState(newPos);
state = state.with(BlockStateProperties.WATERLOGGED, fluidState.getFluid() == Fluids.WATER);
}
BlockSnapshot snapshot = BlockSnapshot.getBlockSnapshot(world, newPos);
world.setBlockState(newPos, state);
BlockEvent.EntityPlaceEvent event = new BlockEvent.EntityPlaceEvent(snapshot, IPlacementHelper.ID, player);
if (MinecraftForge.EVENT_BUS.post(event)) {
snapshot.restore(true, false);
return ActionResultType.FAIL;
}
BlockState newState = world.getBlockState(newPos);
SoundType soundtype = newState.getSoundType(world, newPos, player);
world.playSound(player, newPos, soundtype.getPlaceSound(), SoundCategory.BLOCKS, (soundtype.getVolume() + 1.0F) / 2.0F, soundtype.getPitch() * 0.8F);
player.addStat(Stats.ITEM_USED.get(blockItem));
if (world.isRemote)
return ActionResultType.SUCCESS;
if (player instanceof ServerPlayerEntity)
CriteriaTriggers.PLACED_BLOCK.trigger((ServerPlayerEntity) player, newPos, context.getItem());
if (!player.isCreative())
item.shrink(1);
context.getItem().shrink(1);
return ActionResultType.SUCCESS;
}
}