Skip to content

Commit

Permalink
feat: implement basic block drops
Browse files Browse the repository at this point in the history
  • Loading branch information
smartcmd committed Jun 14, 2024
1 parent 1ce33a6 commit c30db24
Show file tree
Hide file tree
Showing 12 changed files with 89 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ default <DATATYPE> void updateBlockProperty(BlockPropertyType<DATATYPE> property

void onRandomUpdate(BlockStateWithPos blockState);

static void checkParam(EntityPlayer player, Dimension dimension, BlockState blockState, Vector3ic targetBlockPos, Vector3ic placeBlockPos, Vector3fc clickPos, BlockFace blockFace) {
default void checkPlaceMethodParam(EntityPlayer player, Dimension dimension, BlockState blockState, Vector3ic targetBlockPos, Vector3ic placeBlockPos, Vector3fc clickPos, BlockFace blockFace) {
Preconditions.checkState(getBlockType() == blockState.getBlockType());
// player is nullable
Preconditions.checkNotNull(dimension);
Preconditions.checkNotNull(blockState);
Expand All @@ -73,8 +74,27 @@ static void checkParam(EntityPlayer player, Dimension dimension, BlockState bloc
Preconditions.checkNotNull(blockFace);
}

boolean place(EntityPlayer player, Dimension dimension, BlockState blockState, Vector3ic targetBlockPos, Vector3ic placeBlockPos, Vector3fc clickPos, BlockFace blockFace);
/**
* Try to place a block
* @param player The player who is placing the block, can be null
* @param dimension The dimension where the block is placed
* @param blockState The block that is being placed
* @param targetBlockPos The block that the player clicked on
* @param placeBlockPos The pos that the player is trying to place the block on
* @param clickPos The precise pos where the player clicked
* @param blockFace The face of the block that the player clicked on
* @return true if the block is placed successfully, false if failed
*/
boolean place(
EntityPlayer player, Dimension dimension, BlockState blockState,
Vector3ic targetBlockPos, Vector3ic placeBlockPos, Vector3fc clickPos,
BlockFace blockFace);

/**
* Called when a block is placed.
* @param currentBlockState The block that is being replaced
* @param newBlockState The block that is replacing the current block
*/
void onPlace(BlockStateWithPos currentBlockState, BlockState newBlockState);

/**
Expand All @@ -91,11 +111,25 @@ static void checkParam(EntityPlayer player, Dimension dimension, BlockState bloc
*/
boolean onInteract(EntityPlayer player, ItemStack itemStack, Dimension dimension, Vector3ic blockPos, Vector3ic placeBlockPos, Vector3fc clickPos, BlockFace blockFace);

/**
* Called when a block is replaced.
* @param currentBlockState The block that is being replaced
* @param newBlockState The block that is replacing the current block
*/
void onReplace(BlockStateWithPos currentBlockState, BlockState newBlockState);

/**
* Called when a block is broken by non-creative game mode player
* @param blockState The block that was broken
* @param usedItem The item that was used to break the block
* @param player The player who broke the block, can be null
*/
void onBreak(BlockStateWithPos blockState, ItemStack usedItem, EntityPlayer player);

void onScheduledUpdate(BlockStateWithPos blockState);

default ItemStack[] getDrops(ItemStack itemStack) {
// TODO: needs more works
if (getBlockType().getItemType() != null) {
return new ItemStack[] {getBlockType().getItemType().createItemStack()};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ public Builder loc(Location3fc loc) {
return this;
}

public Builder pos(Vector3fc pos) {
return pos(pos.x(), pos.y(), pos.z());
}

public Builder pos(float x, float y, float z) {
nbtBuilder.putCompound("Pos",
NbtMap.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,7 @@ default void forceDropItem(Container container, int slot, int count) {
default void dropItemInPlayerPos(ItemStack itemStack) {
var playerLoc = getLocation();
var dimension = playerLoc.dimension();
var entityItem = EntityTypes.ITEM_TYPE.createEntity(
SimpleEntityInitInfo.builder()
.dimension(dimension)
.pos(playerLoc.x(), playerLoc.y() + this.getEyeHeight() - 0.25f, playerLoc.z())
.motion(MathUtils.getDirectionVector(playerLoc.yaw(), playerLoc.pitch()).mul(0.5f))
.build()
);
entityItem.setItemStack(itemStack);
entityItem.setPickupDelay(40);
dimension.getEntityService().addEntity(entityItem);
dimension.dropItem(itemStack, playerLoc, MathUtils.getDirectionVector(playerLoc.yaw(), playerLoc.pitch()).mul(0.5f), 40);
}

default void sendItemInHandUpdate() {
Expand Down
19 changes: 18 additions & 1 deletion Allay-API/src/main/java/org/allaymc/api/world/Dimension.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
import org.allaymc.api.block.type.BlockState;
import org.allaymc.api.blockentity.BlockEntity;
import org.allaymc.api.entity.Entity;
import org.allaymc.api.entity.init.SimpleEntityInitInfo;
import org.allaymc.api.entity.interfaces.EntityPlayer;
import org.allaymc.api.entity.type.EntityTypes;
import org.allaymc.api.item.ItemStack;
import org.allaymc.api.math.position.Position3i;
import org.allaymc.api.utils.MathUtils;
Expand All @@ -34,6 +36,7 @@
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;

import static org.allaymc.api.block.type.BlockTypes.AIR_TYPE;

Expand Down Expand Up @@ -411,7 +414,21 @@ default void addSound(float x, float y, float z, String sound, float volume, flo
getChunkService().getChunkByLevelPos((int) x, (int) z).addChunkPacket(packet);
}

default void dropItem(ItemStack itemStack, float x, float y, float z) {
default void dropItem(ItemStack itemStack, Vector3fc pos) {
var rand = ThreadLocalRandom.current();
dropItem(itemStack, pos, new org.joml.Vector3f(rand.nextFloat(0.2f) - 0.1f, 0.2f, rand.nextFloat(0.2f) - 0.1f), 10);
}

default void dropItem(ItemStack itemStack, Vector3fc pos, Vector3fc motion, int pickupDelay) {
var entityItem = EntityTypes.ITEM_TYPE.createEntity(
SimpleEntityInitInfo.builder()
.dimension(this)
.pos(pos)
.motion(motion)
.build()
);
entityItem.setItemStack(itemStack);
entityItem.setPickupDelay(pickupDelay);
getEntityService().addEntity(entityItem);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import org.allaymc.api.block.BlockBehavior;
import org.allaymc.api.block.component.annotation.RequireBlockProperty;
import org.allaymc.api.block.data.BlockFace;
import org.allaymc.api.block.function.Place;
import org.allaymc.api.block.property.type.BlockPropertyType;
import org.allaymc.api.block.type.BlockState;
import org.allaymc.api.block.type.BlockType;
Expand All @@ -30,7 +29,7 @@ public BlockBarrelBaseComponentImpl(BlockType<? extends BlockBehavior> blockType

@Override
public boolean place(EntityPlayer player, Dimension dimension, BlockState blockState, Vector3ic targetBlockPos, Vector3ic placeBlockPos, Vector3fc clickPos, BlockFace blockFace) {
Place.checkParam(player, dimension, blockState, targetBlockPos, placeBlockPos, clickPos, blockFace);
checkPlaceMethodParam(player, dimension, blockState, targetBlockPos, placeBlockPos, clickPos, blockFace);
if (player != null) {
if (abs(player.getLocation().x() - placeBlockPos.x()) < 2 && abs(player.getLocation().z() - placeBlockPos.z()) < 2) {
var y = player.getLocation().y() + player.getEyeHeight();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public BlockChestBaseComponentImpl(BlockType<? extends BlockBehavior> blockType)

@Override
public boolean place(EntityPlayer player, Dimension dimension, BlockState blockState, Vector3ic targetBlockPos, Vector3ic placeBlockPos, Vector3fc clickPos, BlockFace blockFace) {
checkPlaceMethodParam(player, dimension, blockState, targetBlockPos, placeBlockPos, clickPos, blockFace);
var face = MinecraftCardinalDirection.EAST;
if (player != null) {
face = toMinecraftCardinalDirection(player.getHorizontalFace().opposite());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import org.allaymc.api.block.component.event.BlockOnReplaceEvent;
import org.allaymc.api.block.data.BlockFace;
import org.allaymc.api.block.data.BlockStateWithPos;
import org.allaymc.api.block.function.Place;
import org.allaymc.api.block.type.BlockState;
import org.allaymc.api.block.type.BlockType;
import org.allaymc.api.utils.Identifier;
Expand All @@ -18,6 +17,7 @@
import org.allaymc.api.entity.interfaces.EntityPlayer;
import org.allaymc.api.item.ItemStack;
import org.allaymc.api.world.Dimension;
import org.joml.Vector3f;
import org.joml.Vector3fc;
import org.joml.Vector3ic;

Expand Down Expand Up @@ -60,7 +60,7 @@ public void onScheduledUpdate(BlockStateWithPos blockState) {

@Override
public boolean place(EntityPlayer player, Dimension dimension, BlockState blockState, Vector3ic targetBlockPos, Vector3ic placeBlockPos, Vector3fc clickPos, BlockFace blockFace) {
Place.checkParam(player, dimension, blockState, targetBlockPos, placeBlockPos, clickPos, blockFace);
checkPlaceMethodParam(player, dimension, blockState, targetBlockPos, placeBlockPos, clickPos, blockFace);
// TODO: check whether the old block can be replaced
dimension.setBlockState(placeBlockPos.x(), placeBlockPos.y(), placeBlockPos.z(), blockState);
return true;
Expand All @@ -76,6 +76,16 @@ public void onReplace(BlockStateWithPos currentBlockState, BlockState newBlockSt
manager.callEvent(new BlockOnReplaceEvent(currentBlockState, newBlockState));
}

@Override
public void onBreak(BlockStateWithPos blockState, ItemStack usedItem, EntityPlayer player) {
if (!blockState.blockState().getBlockType().getMaterial().isAlwaysDestroyable() && !usedItem.isCorrectToolFor(blockState.blockState())) return;
var drops = getDrops(usedItem);
if (drops.length == 0) return;
for (var drop : drops) {
player.getDimension().dropItem(drop, new Vector3f(blockState.pos()).add(0.5f, 0.5f, 0.5f));
}
}

@Override
public boolean onInteract(EntityPlayer player, ItemStack itemStack, Dimension dimension, Vector3ic blockPos, Vector3ic placeBlockPos, Vector3fc clickPos, BlockFace blockFace) {
var event = new BlockOnInteractEvent(player, itemStack, dimension, blockPos, placeBlockPos, clickPos, blockFace, false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import org.allaymc.api.block.BlockBehavior;
import org.allaymc.api.block.component.annotation.RequireBlockProperty;
import org.allaymc.api.block.data.BlockFace;
import org.allaymc.api.block.function.Place;
import org.allaymc.api.block.property.type.BlockPropertyType;
import org.allaymc.api.block.type.BlockState;
import org.allaymc.api.block.type.BlockType;
Expand All @@ -28,7 +27,7 @@ public BlockStairsBaseComponentImpl(BlockType<? extends BlockBehavior> blockType

@Override
public boolean place(EntityPlayer player, Dimension dimension, BlockState blockState, Vector3ic targetBlockPos, Vector3ic placeBlockPos, Vector3fc clickPos, BlockFace blockFace) {
Place.checkParam(player, dimension, blockState, targetBlockPos, placeBlockPos, clickPos, blockFace);
checkPlaceMethodParam(player, dimension, blockState, targetBlockPos, placeBlockPos, clickPos, blockFace);
if (player != null) {
var stairFace = player.getHorizontalFace();
blockState = blockState.setProperty(VanillaBlockPropertyTypes.WEIRDO_DIRECTION, stairFace.toStairDirectionValue());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import org.allaymc.api.block.component.annotation.RequireBlockProperty;
import org.allaymc.api.block.component.common.BlockLiquidComponent;
import org.allaymc.api.block.data.BlockFace;
import org.allaymc.api.block.function.Place;
import org.allaymc.api.block.property.enums.TorchFacingDirection;
import org.allaymc.api.block.property.type.BlockPropertyType;
import org.allaymc.api.block.type.BlockState;
Expand Down Expand Up @@ -39,7 +38,7 @@ private static TorchFacingDirection computeTorchFacingDirection(BlockFace blockF

@Override
public boolean place(EntityPlayer player, Dimension dimension, BlockState blockState, Vector3ic targetBlockPos, Vector3ic placeBlockPos, Vector3fc clickPos, BlockFace blockFace) {
Place.checkParam(player, dimension, blockState, targetBlockPos, placeBlockPos, clickPos, blockFace);
checkPlaceMethodParam(player, dimension, blockState, targetBlockPos, placeBlockPos, clickPos, blockFace);
var oldBlock = dimension.getBlockState(placeBlockPos);
var torchFace = computeTorchFacingDirection(blockFace);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.allaymc.api.entity.type.EntityTypes;
import org.allaymc.api.eventbus.EventHandler;
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
import org.joml.Vector3f;

import java.util.Objects;
import java.util.concurrent.ThreadLocalRandom;
Expand Down Expand Up @@ -77,19 +78,8 @@ private void onReplace(BlockOnReplaceEvent event) {
var dimension = pos.dimension();
var rand = ThreadLocalRandom.current();
for (var itemStack : container.getItemStacks()) {
if (itemStack != Container.EMPTY_SLOT_PLACE_HOLDER) {
var entity = EntityTypes.ITEM_TYPE.createEntity(
SimpleEntityInitInfo
.builder()
.pos(pos.x() + rand.nextFloat(0.5f) + 0.25f, pos.y() + rand.nextFloat(0.5f) + 0.25f, pos.z() + rand.nextFloat(0.5f) + 0.25f)
.dimension(dimension)
.motion(rand.nextFloat(0.2f) - 0.1f, 0.2f, rand.nextFloat(0.2f) - 0.1f)
.build()
);
entity.setItemStack(itemStack);
entity.setPickupDelay(10);
dimension.getEntityService().addEntity(entity);
}
if (itemStack == Container.EMPTY_SLOT_PLACE_HOLDER) continue;
dimension.dropItem(itemStack, new Vector3f(pos.x() + rand.nextFloat(0.5f) + 0.25f, pos.y() + rand.nextFloat(0.5f) + 0.25f, pos.z() + rand.nextFloat(0.5f) + 0.25f));
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package org.allaymc.server.network.processor;

import lombok.extern.slf4j.Slf4j;
import org.allaymc.api.block.data.BlockStateWithPos;
import org.allaymc.api.container.FullContainerType;
import org.allaymc.api.entity.interfaces.EntityPlayer;
import org.allaymc.api.math.location.Location3f;
import org.allaymc.api.math.position.Position3i;
import org.allaymc.api.network.processor.PacketProcessor;
import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.protocol.bedrock.data.GameType;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@

import lombok.extern.slf4j.Slf4j;
import org.allaymc.api.block.data.BlockFace;
import org.allaymc.api.block.data.BlockStateWithPos;
import org.allaymc.api.block.type.BlockState;
import org.allaymc.api.container.FullContainerType;
import org.allaymc.api.entity.interfaces.EntityPlayer;
import org.allaymc.api.math.location.Location3f;
import org.allaymc.api.math.position.Position3i;
import org.allaymc.api.math.position.Position3ic;
import org.allaymc.api.network.processor.PacketProcessor;
import org.allaymc.api.utils.MathUtils;
import org.cloudburstmc.math.vector.Vector3f;
Expand Down Expand Up @@ -164,9 +167,12 @@ protected void completeBreak(EntityPlayer player, int x, int y, int z) {
pk.setPosition(Vector3f.from(breakBlockX + 0.5f, breakBlockY + 0.5f, breakBlockZ + 0.5f));
pk.setData(oldState.blockStateHash());
player.getCurrentChunk().addChunkPacket(pk);
// TODO: on break
breakBlock.getBehavior().onBreak(
new BlockStateWithPos(breakBlock, new Position3i(breakBlockX, breakBlockY, breakBlockZ, player.getDimension()), 0),
player.getContainer(FullContainerType.PLAYER_INVENTORY).getItemInHand(),
player
);
world.setBlockState(breakBlockX, breakBlockY, breakBlockZ, AIR_TYPE.getDefaultState());
// TODO: drop items
} else {
log.warn("Mismatch block breaking complete time! Expected: {}gt, actual: {}gt", stopBreakingTime, currentTime);
}
Expand Down

0 comments on commit c30db24

Please sign in to comment.