Skip to content

Commit

Permalink
feat: implement silk_touch
Browse files Browse the repository at this point in the history
  • Loading branch information
smartcmd committed Jun 15, 2024
1 parent e6fae94 commit 3d6096f
Show file tree
Hide file tree
Showing 16 changed files with 203 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ boolean place(

default ItemStack[] getDrops(BlockState blockState, ItemStack usedItem) {
// TODO: 时运
// TODO: silk touch (精准采集)
if (getBlockType().getItemType() != null) {
return new ItemStack[] {getBlockType().getItemType().createItemStack()};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.allaymc.api.command.SenderType;
import org.allaymc.api.entity.Entity;
import org.allaymc.api.entity.interfaces.EntityPlayer;
import org.allaymc.api.item.enchantment.EnchantmentType;
import org.cloudburstmc.protocol.bedrock.data.GameType;
import org.cloudburstmc.protocol.bedrock.data.command.CommandParamData;
import org.cloudburstmc.protocol.bedrock.data.command.CommandParamOption;
Expand Down Expand Up @@ -130,6 +131,14 @@ default CommandNode str(String name) {
return str(name, "");
}

default CommandNode shortNum(String name, short defaultValue) {
return addLeaf(getFactory().shortNum(name, this, defaultValue));
}

default CommandNode shortNum(String name) {
return shortNum(name, (short) 0);
}

default CommandNode intNum(String name, int defaultValue) {
return addLeaf(getFactory().intNum(name, this, defaultValue));
}
Expand Down Expand Up @@ -259,4 +268,12 @@ default CommandNode wildcardTarget(String name) {
default CommandNode wildcardTarget(String name, String defaultValue) {
return addLeaf(getFactory().wildcardTarget(name, this, defaultValue));
}

default CommandNode enchantmentNode(String name) {
return enchantmentNode(name, null);
}

default CommandNode enchantmentNode(String name, EnchantmentType defaultValue) {
return addLeaf(getFactory().enchantmentNode(name, this, defaultValue));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.allaymc.api.ApiInstanceHolder;
import org.allaymc.api.entity.Entity;
import org.allaymc.api.entity.interfaces.EntityPlayer;
import org.allaymc.api.item.enchantment.EnchantmentType;
import org.cloudburstmc.protocol.bedrock.data.GameType;
import org.joml.Vector3fc;

Expand All @@ -25,6 +26,8 @@ static CommandNodeFactory getFactory() {

CommandNode str(String name, CommandNode parent, String defaultValue);

CommandNode shortNum(String name, CommandNode parent, short defaultValue);

CommandNode intNum(String name, CommandNode parent, int defaultValue);

CommandNode longNum(String name, CommandNode parent, long defaultValue);
Expand Down Expand Up @@ -56,4 +59,6 @@ static CommandNodeFactory getFactory() {
CommandNode pos(String name, CommandNode parent, Vector3fc defaultValue);

CommandNode wildcardTarget(String name, CommandNode parent, String defaultValue);

CommandNode enchantmentNode(String name, CommandNode parent, EnchantmentType defaultValue);
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ default void dropItemInPlayerPos(ItemStack itemStack) {
dimension.dropItem(itemStack, playerLoc.add(0, + this.getEyeHeight() - 0.25f, 0, new Vector3f()), MathUtils.getDirectionVector(playerLoc.yaw(), playerLoc.pitch()).mul(0.5f), 40);
}

default ItemStack getItemInHand() {
return getContainer(FullContainerType.PLAYER_INVENTORY).getItemInHand();
}

default void sendItemInHandUpdate() {
var inv = getContainer(FullContainerType.PLAYER_INVENTORY);
var itemStack = inv.getItemInHand();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@
import org.allaymc.api.block.data.BlockFace;
import org.allaymc.api.block.type.BlockState;
import org.allaymc.api.block.type.BlockTypes;
import org.allaymc.api.data.VanillaBlockId;
import org.allaymc.api.data.VanillaItemId;
import org.allaymc.api.entity.interfaces.EntityPlayer;
import org.allaymc.api.item.ItemHelper;
import org.allaymc.api.item.ItemStack;
import org.allaymc.api.item.component.ItemComponent;
import org.allaymc.api.item.enchantment.EnchantmentInstance;
import org.allaymc.api.item.enchantment.EnchantmentType;
import org.allaymc.api.item.type.ItemType;
import org.allaymc.api.world.Dimension;
Expand All @@ -17,14 +15,12 @@
import org.joml.Vector3fc;
import org.joml.Vector3ic;

import java.util.EnumMap;
import java.util.Collection;
import java.util.List;

import static org.allaymc.api.block.type.BlockTypes.BAMBOO_BLOCK_TYPE;
import static org.allaymc.api.data.VanillaItemTags.*;
import static org.allaymc.api.data.VanillaItemTags.WOODEN_TIER;
import static org.allaymc.api.data.VanillaMaterialTypes.*;
import static org.allaymc.api.item.type.ItemTypes.BAMBOO_TYPE;
import static org.allaymc.api.item.type.ItemTypes.SHEARS_TYPE;

/**
Expand Down Expand Up @@ -148,6 +144,8 @@ default NbtMap saveNBT() {

short getEnchantmentLevel(EnchantmentType enchantmentType);

Collection<EnchantmentInstance> getEnchantments();

void addEnchantment(EnchantmentType enchantmentType, short level);

/**
Expand Down Expand Up @@ -199,4 +197,17 @@ default boolean canInstantBreak(BlockState blockState) {
}
return false;
}

default boolean checkEnchantmentCompatibility(EnchantmentType type) {
return getIncompatibleEnchantmentType(type) == null;
}

default EnchantmentType getIncompatibleEnchantmentType(EnchantmentType type) {
for (var enchantmentInstance : getEnchantments()) {
if (!enchantmentInstance.getType().checkCompatibility(type)) {
return enchantmentInstance.getType();
}
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public interface EnchantmentType {
EnchantmentInstance createInstance(short level);

default boolean checkCompatibility(EnchantmentType other) {
// TODO
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.allaymc.api.block.data.BlockStateWithPos;
import org.allaymc.api.block.type.BlockState;
import org.allaymc.api.block.type.BlockType;
import org.allaymc.api.item.enchantment.type.EnchantmentSilkTouchType;
import org.allaymc.api.utils.Identifier;
import org.allaymc.api.component.annotation.ComponentIdentifier;
import org.allaymc.api.component.annotation.Manager;
Expand All @@ -21,6 +22,8 @@
import org.joml.Vector3fc;
import org.joml.Vector3ic;

import java.util.Arrays;

/**
* Allay Project 2023/4/8
*
Expand Down Expand Up @@ -79,10 +82,15 @@ public void onReplace(BlockStateWithPos currentBlockState, BlockState newBlockSt
@Override
public void onBreak(BlockStateWithPos blockState, ItemStack usedItem, EntityPlayer player) {
if (!blockState.blockState().getBlockType().getMaterial().isAlwaysDestroyable() && !usedItem.isCorrectToolFor(blockState.blockState())) return;
var dropPos = new Vector3f(blockState.pos()).add(0.5f, 0.5f, 0.5f);
if (usedItem.hasEnchantment(EnchantmentSilkTouchType.SILK_TOUCH_TYPE)) {
// 精准采集, 直接掉落方块本身
player.getDimension().dropItem(blockState.blockState().toItemStack(), dropPos);
return;
}
var drops = getDrops(blockState.blockState(), 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));
player.getDimension().dropItem(drop, dropPos);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,11 @@ public static long computeSpecialValue(byte specialValueBits, BlockPropertyType.
private final Set<BlockTag> blockTags;
@Getter
private final Material material;
private final ItemType<?> blockItemType;

private Class<T> injectedClass;
@Getter
private BlockState defaultState;
private ItemType<?> blockItemType;
private Map<Integer, Integer> hashToMeta;
@Getter
private T blockBehavior;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public void registerDefaultCommands() {
register(new WhitelistCommand());
register(new ScoreboardCommand());
register(new TimeCommand());
register(new EnchantCommand());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package org.allaymc.server.command.defaults;

import org.allaymc.api.command.SimpleCommand;
import org.allaymc.api.command.tree.CommandTree;
import org.allaymc.api.container.Container;
import org.allaymc.api.container.FullContainerType;
import org.allaymc.api.entity.interfaces.EntityPlayer;
import org.allaymc.api.i18n.TrKeys;
import org.allaymc.api.item.enchantment.EnchantmentType;

import java.util.Collection;

/**
* Allay Project 2024/6/15
*
* @author daoge_cmd
*/
public class EnchantCommand extends SimpleCommand {

public EnchantCommand() {
super("enchant", TrKeys.M_COMMANDS_ENCHANT_DESCRIPTION);
}

@Override
public void prepareCommandTree(CommandTree tree) {
tree.getRoot()
.playerTarget("player")
.enchantmentNode("enchantmentName")
.shortNum("level")
.exec(ctx -> {
Collection<EntityPlayer> players = ctx.getFirstResult();
EnchantmentType enchantmentType = ctx.getSecondResult();
short level = ctx.getThirdResult();
for (var player : players) {
var item = player.getContainer(FullContainerType.PLAYER_INVENTORY).getItemInHand();
if (item == Container.EMPTY_SLOT_PLACE_HOLDER) {
// 手上没东西
ctx.addOutput(TrKeys.M_COMMANDS_ENCHANT_NOITEM);
return ctx.fail();
}
var incompatibleEnchantmentType = item.getIncompatibleEnchantmentType(enchantmentType);
if (incompatibleEnchantmentType != null) {
// 新附魔和已有附魔有冲突
ctx.addOutput(TrKeys.M_COMMANDS_ENCHANT_CANTCOMBINE, incompatibleEnchantmentType.getIdentifier(), enchantmentType.getIdentifier());
return ctx.fail();
}
item.addEnchantment(enchantmentType, level);
player.sendItemInHandUpdate();
ctx.addOutput(TrKeys.M_COMMANDS_ENCHANT_SUCCESS, enchantmentType.getIdentifier());
}
return ctx.success();
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.allaymc.api.command.tree.CommandNodeFactory;
import org.allaymc.api.entity.Entity;
import org.allaymc.api.entity.interfaces.EntityPlayer;
import org.allaymc.api.item.enchantment.EnchantmentType;
import org.allaymc.server.command.tree.node.*;
import org.cloudburstmc.protocol.bedrock.data.GameType;
import org.joml.Vector3fc;
Expand All @@ -26,6 +27,11 @@ public CommandNode str(String name, CommandNode parent, String defaultValue) {
return new StringNode(name, parent, defaultValue);
}

@Override
public CommandNode shortNum(String name, CommandNode parent, short defaultValue) {
return new ShortNode(name, parent, defaultValue);
}

@Override
public CommandNode intNum(String name, CommandNode parent, int defaultValue) {
return new IntNode(name, parent, defaultValue);
Expand Down Expand Up @@ -105,4 +111,9 @@ public CommandNode pos(String name, CommandNode parent, Vector3fc defaultValue)
public CommandNode wildcardTarget(String name, CommandNode parent, String defaultValue) {
return new WildcardTargetNode(name, parent, defaultValue);
}

@Override
public CommandNode enchantmentNode(String name, CommandNode parent, EnchantmentType defaultValue) {
return new EnchantmentNode(name, parent, defaultValue);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.allaymc.server.command.tree.node;

import org.allaymc.api.command.tree.CommandNode;
import org.allaymc.api.item.enchantment.EnchantmentRegistry;
import org.allaymc.api.item.enchantment.EnchantmentType;
import org.allaymc.api.utils.Identifier;

import static org.allaymc.api.utils.Identifier.DEFAULT_NAMESPACE;

/**
* Allay Project 2024/6/15
*
* @author daoge_cmd
*/
public class EnchantmentNode extends EnumNode {

protected static final String[] ENCHANTMENT_STR_ARRAY =
EnchantmentRegistry.getRegistry().getContent().m1().values()
.stream()
.map(type -> type.getIdentifier().path())
.toArray(String[]::new);

public EnchantmentNode(String name, CommandNode parent, EnchantmentType defaultValue) {
super(name, parent, defaultValue, ENCHANTMENT_STR_ARRAY);
}

@Override
protected Object argToResult(String arg) {
return EnchantmentRegistry.getRegistry().getByK2(new Identifier(DEFAULT_NAMESPACE, arg));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package org.allaymc.server.command.tree.node;

import org.allaymc.api.command.tree.BaseNode;
import org.allaymc.api.command.tree.CommandContext;
import org.allaymc.api.command.tree.CommandNode;
import org.cloudburstmc.protocol.bedrock.data.command.CommandParam;
import org.cloudburstmc.protocol.bedrock.data.command.CommandParamData;

/**
* Allay Project 2024/6/15
*
* @author daoge_cmd
*/
public class ShortNode extends BaseNode {

public ShortNode(String name, CommandNode parent, short defaultValue) {
super(name, parent, defaultValue);
}

@Override
public boolean match(CommandContext context) {
var arg = context.queryArg();
short number;
try {
number = Short.parseShort(arg);
} catch (NumberFormatException e) {
return false;
}
context.putResult(number);
context.popArg();
return true;
}

@Override
public CommandParamData toNetworkData() {
var data = super.toNetworkData();
data.setType(CommandParam.INT);
return data;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,11 @@ public short getEnchantmentLevel(EnchantmentType enchantmentType) {
return instance == null ? 0 : instance.getLevel();
}

@Override
public Collection<EnchantmentInstance> getEnchantments() {
return enchantments.values();
}

@Override
public void addEnchantment(EnchantmentType enchantmentType, short level) {
enchantments.put(enchantmentType, new SimpleEnchantmentInstance(enchantmentType, level));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ public void handleSync(EntityPlayer player, InventoryTransactionPacket packet) {
Vector3ic blockPos = MathUtils.CBVecToJOMLVec(packet.getBlockPosition());
Vector3fc clickPos = MathUtils.CBVecToJOMLVec(packet.getClickPosition());
BlockFace blockFace = BlockFace.fromId(packet.getBlockFace());
var inv = player.getContainer(FullContainerType.PLAYER_INVENTORY);
var itemStack = inv.getItemInHand();
var itemStack = player.getItemInHand();
var world = player.getLocation().dimension();
switch (packet.getActionType()) {
case ITEM_USE_CLICK_BLOCK -> {
Expand Down Expand Up @@ -78,7 +77,7 @@ public void handleSync(EntityPlayer player, InventoryTransactionPacket packet) {
var target = player.getDimension().getEntityByRuntimeId(packet.getRuntimeEntityId());
Preconditions.checkNotNull(target, "Player " + player.getOriginName() + " try to attack a entity which doesn't exist! Entity id: " + packet.getRuntimeEntityId());
switch (packet.getActionType()) {
case ITEM_USE_ON_ENTITY_INTERACT -> target.onInteract(player, player.getContainer(FullContainerType.PLAYER_INVENTORY).getItemInHand());
case ITEM_USE_ON_ENTITY_INTERACT -> target.onInteract(player, player.getItemInHand());
case ITEM_USE_ON_ENTITY_ATTACK -> {
EntityDamageComponent damageable;
if (target instanceof EntityDamageComponent cast) {
Expand All @@ -88,7 +87,7 @@ public void handleSync(EntityPlayer player, InventoryTransactionPacket packet) {
return;
}
// TODO: Check whether the player can touch the target entity or not (to prevent cheater)
var itemInHand = player.getContainer(FullContainerType.PLAYER_INVENTORY).getItemInHand();
var itemInHand = player.getItemInHand();
var damage = itemInHand.calculateAttackDamage();
if (damage == 0) damage = 1;
var damageContainer = DamageContainer.entityAttack(player, damage);
Expand Down
Loading

0 comments on commit 3d6096f

Please sign in to comment.