Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

import de.dafuqs.spectrum.*;
import de.dafuqs.spectrum.compat.claims.*;
import de.dafuqs.spectrum.registries.*;
import net.minecraft.block.*;
import net.minecraft.block.entity.*;
import net.minecraft.entity.*;
import net.minecraft.entity.player.*;
import net.minecraft.item.*;
import net.minecraft.registry.*;
import net.minecraft.screen.*;
import net.minecraft.server.network.*;
import net.minecraft.server.world.*;
import net.minecraft.util.*;
import net.minecraft.util.hit.*;
Expand Down Expand Up @@ -51,25 +53,28 @@ protected void dispense(ServerWorld world, BlockPos pos) {
world.emitGameEvent(null, GameEvent.BLOCK_ACTIVATE, pos);
} else {
ItemStack stack = blockEntity.getStack(slot);
tryPlace(stack, pointer);
PlayerEntity cause = blockEntity.getOwnerIfOnline();
tryPlace(stack, pointer, cause);
}
}

// We can't reuse the vanilla BlockPlacementDispenserBehavior, since we are using a different orientation for our block:
// BlockPlacerBlock.ORIENTATION instead of DispenserBlock.FACING
protected void tryPlace(@NotNull ItemStack stack, BlockPointer pointer) {
protected void tryPlace(@NotNull ItemStack stack, BlockPointer pointer, PlayerEntity cause) {
World world = pointer.getWorld();
if (stack.getItem() instanceof BlockItem blockItem) {
Direction facing = pointer.getBlockState().get(BlockPlacerBlock.ORIENTATION).getFacing();
BlockPos placementPos = pointer.getPos().offset(facing);
Direction placementDirection = world.isAir(placementPos.down()) ? facing : Direction.UP;

if (!GenericClaimModsCompat.canPlaceBlock(world, placementPos, null)) {
if (!GenericClaimModsCompat.canPlaceBlock(world, placementPos, cause)) {
return;
}

try {
blockItem.place(new BlockPlacerPlacementContext(world, placementPos, facing, stack, placementDirection));
if(blockItem.place(new BlockPlacerPlacementContext(world, placementPos, facing, stack, placementDirection, cause)).isAccepted()) {
if(cause != null && cause.getAbilities().creativeMode) { stack.decrement(1); }
}
world.syncWorldEvent(WorldEvents.DISPENSER_DISPENSES, pointer.getPos(), 0);
world.syncWorldEvent(WorldEvents.DISPENSER_ACTIVATED, pointer.getPos(), pointer.getBlockState().get(BlockPlacerBlock.ORIENTATION).getFacing().getId());
world.emitGameEvent(null, GameEvent.BLOCK_PLACE, placementPos);
Expand All @@ -83,6 +88,10 @@ protected void tryPlace(@NotNull ItemStack stack, BlockPointer pointer) {
}
}

protected void tryPlace(@NotNull ItemStack itemStack, BlockPointer pointer) {
this.tryPlace(itemStack, pointer, null);
}

@Override
public void neighborUpdate(BlockState state, World world, BlockPos pos, Block sourceBlock, BlockPos sourcePos, boolean notify) {
boolean bl = world.isReceivingRedstonePower(pos) || world.isReceivingRedstonePower(pos.up());
Expand All @@ -102,10 +111,13 @@ public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Ran

@Override
public void onPlaced(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack itemStack) {
if (itemStack.hasCustomName()) {
if (world.getBlockEntity(pos) instanceof BlockPlacerBlockEntity blockPlacerBlockEntity) {
if (world.getBlockEntity(pos) instanceof BlockPlacerBlockEntity blockPlacerBlockEntity) {
if (itemStack.hasCustomName()) {
blockPlacerBlockEntity.setCustomName(itemStack.getName());
}
if (placer instanceof ServerPlayerEntity serverPlayerEntity) {
blockPlacerBlockEntity.setOwner(serverPlayerEntity);
}
}

}
Expand Down Expand Up @@ -133,9 +145,28 @@ public int getComparatorOutput(BlockState state, World world, BlockPos pos) {
}

public static final class BlockPlacerPlacementContext extends AutomaticItemPlacementContext {
// Shadows the variable facing in the superclass.
private final Direction facing;
private final PlayerEntity cause;

public BlockPlacerPlacementContext(World world, BlockPos pos, Direction facing, ItemStack stack, Direction side) {
public BlockPlacerPlacementContext(World world, BlockPos pos, Direction facing, ItemStack stack, Direction side, PlayerEntity cause) {
super(world, pos, facing, stack, side);
this.facing = facing;
this.cause = cause;
}

public BlockPlacerPlacementContext(World world, BlockPos pos, Direction facing, ItemStack stack, Direction side) {
this(world, pos, facing, stack, side, null);
}

// Not global, as to avoid any exploits where Ender Droppers et al. can be placed without player consent.
@Nullable @Override
public PlayerEntity getPlayer() {
return this.getStack().isIn(SpectrumItemTags.PLAYER_ATTRIBUTED_PLACEMENT) ? this.cause : null;
}

public Direction getPlayerLookDirection() {
return facing.getOpposite();
}

// SlabBlocks cause a non-funny StackOverflowError
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
package de.dafuqs.spectrum.blocks.redstone;

import de.dafuqs.spectrum.api.block.*;
import de.dafuqs.spectrum.inventories.*;
import de.dafuqs.spectrum.registries.*;
import net.minecraft.block.*;
import net.minecraft.block.entity.*;
import net.minecraft.entity.player.*;
import net.minecraft.nbt.*;
import net.minecraft.screen.*;
import net.minecraft.text.*;
import net.minecraft.util.math.*;

public class BlockPlacerBlockEntity extends DispenserBlockEntity {
import java.util.*;

public class BlockPlacerBlockEntity extends DispenserBlockEntity implements PlayerOwned {

private UUID ownerUUID;

public BlockPlacerBlockEntity(BlockPos pos, BlockState state) {
super(SpectrumBlockEntities.BLOCK_PLACER, pos, state);
Expand All @@ -25,4 +31,26 @@ protected ScreenHandler createScreenHandler(int syncId, PlayerInventory playerIn
return Spectrum3x3ContainerScreenHandler.createTier1(syncId, playerInventory, this);
}

@Override
public UUID getOwnerUUID() {
return this.ownerUUID;
}

@Override
public void setOwner(PlayerEntity playerEntity) {
this.ownerUUID = playerEntity.getUuid();
this.markDirty();
}

@Override
public void writeNbt(NbtCompound nbt) {
super.writeNbt(nbt);
PlayerOwned.writeOwnerUUID(nbt, this.ownerUUID);
}

@Override
public void readNbt(NbtCompound nbt) {
super.readNbt(nbt);
this.ownerUUID = PlayerOwned.readOwnerUUID(nbt);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ protected void appendProperties(StateManager.Builder<Block, BlockState> builder)
public BlockState getPlacementState(ItemPlacementContext ctx) {
Direction direction = ctx.getPlayerLookDirection().getOpposite();
Direction direction2 = switch (direction) {
case DOWN -> ctx.getPlayer().getHorizontalFacing().getOpposite();
case UP -> ctx.getPlayer().getHorizontalFacing();
case DOWN -> ctx.getHorizontalPlayerFacing().getOpposite();
case UP -> ctx.getHorizontalPlayerFacing();
case NORTH, SOUTH, WEST, EAST -> Direction.UP;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class SpectrumItemTags {
public static final TagKey<Item> PASTEL_NODE_UPGRADES = of("pastel_node_upgrades");
public static final TagKey<Item> TAG_FILTERING_ITEMS = of("tag_filtering_items");
public static final TagKey<Item> WEEPING_GALA_LOGS = of("weeping_gala_logs");
public static final TagKey<Item> PLAYER_ATTRIBUTED_PLACEMENT = of("player_attributed_placement");

private static TagKey<Item> of(String id) {
return TagKey.of(RegistryKeys.ITEM, SpectrumCommon.locate(id));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"values": [
"spectrum:block_breaker",
"spectrum:block_placer"
]
}