9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-22 16:39:28 +00:00

添加一些基础条件和函数

还需要对vanilla-loots系统进行重构
This commit is contained in:
XiaoMoMi
2025-05-14 21:44:56 +08:00
parent f7016bacdf
commit c047e5a83c
32 changed files with 608 additions and 74 deletions

View File

@@ -90,7 +90,10 @@ warning.config.condition.match_block_property.missing_properties: "<yellow>Issue
warning.config.condition.match_item.missing_id: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'id' argument for 'match_item' condition.</yellow>"
warning.config.condition.table_bonus.missing_enchantment: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'enchantment' argument for 'table_bonus' condition.</yellow>"
warning.config.condition.table_bonus.missing_chances: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'chances' argument for 'table_bonus' condition.</yellow>"
warning.config.condition.click_type.missing_click_type: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'click-type' argument for 'click_type' condition.</yellow>"
warning.config.condition.permission.missing_permission: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'permission' argument for 'permission' condition.</yellow>"
warning.config.condition.equals.missing_value1: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'value1' argument for 'equals' condition.</yellow>"
warning.config.condition.equals.missing_value2: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'value2' argument for 'equals' condition.</yellow>"
warning.config.condition.expression.missing_expression: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'expression' argument for 'expression' condition.</yellow>"
warning.config.structure.not_section: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is expected to be a config section while it's actually a(n) '<arg:2>'.</yellow>"
warning.config.image.duplicate: "<yellow>Issue found in file <arg:0> - Duplicated image '<arg:1>'. Please check if there is the same configuration in other files.</yellow>"
warning.config.image.missing_height: "<yellow>Issue found in file <arg:0> - The image '<arg:1>' is missing the required 'height' argument.</yellow>"
@@ -302,4 +305,9 @@ warning.config.event.condition.missing_type: "<yellow>Issue found in file <arg:0
warning.config.event.condition.invalid_type: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is using an invalid 'type' argument '<arg:2>' for event condition.</yellow>"
warning.config.function.missing_type: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'type' argument for function.</yellow>"
warning.config.function.invalid_type: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is using an invalid function type '<arg:2>'.</yellow>"
warning.config.function.command.missing_command: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'command' argument for 'command' function.</yellow>"
warning.config.function.command.missing_command: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'command' argument for 'command' function.</yellow>"
warning.config.function.actionbar.missing_actionbar: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'actionbar' argument for 'actionbar' function.</yellow>"
warning.config.function.message.missing_message: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'message' argument for 'message' function.</yellow>"
warning.config.selector.missing_type: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'type' argument for selector.</yellow>"
warning.config.selector.invalid_type: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is using an invalid selector type '<arg:2>'.</yellow>"
warning.config.selector.invalid_target: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is using an invalid selector target '<arg:2>'.</yellow>"

View File

@@ -90,7 +90,8 @@ warning.config.condition.match_block_property.missing_properties: "<yellow>在
warning.config.condition.match_item.missing_id: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 缺少 'match_item' 条件所需的 'id' 参数</yellow>"
warning.config.condition.table_bonus.missing_enchantment: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 缺少 'table_bonus' 条件所需的 'enchantment' 参数</yellow>"
warning.config.condition.table_bonus.missing_chances: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 缺少 'table_bonus' 条件所需的 'chances' 参数</yellow>"
warning.config.condition.click_type.missing_click_type: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'click-type' argument for 'click_type' condition.</yellow>"
warning.config.structure.not_section: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 应为配置段落 但实际类型为 '<arg:2>'</yellow>"
warning.config.image.duplicate: "<yellow>在文件 <arg:0> 发现问题 - 重复的图片配置 '<arg:1>' 请检查其他文件中是否存在相同配置</yellow>"
warning.config.image.missing_height: "<yellow>在文件 <arg:0> 发现问题 - 图片 '<arg:1>' 缺少必需的 'height' 参数</yellow>"

View File

@@ -11,6 +11,7 @@ import net.momirealms.craftengine.bukkit.world.BukkitWorld;
import net.momirealms.craftengine.core.block.ImmutableBlockState;
import net.momirealms.craftengine.core.block.properties.Property;
import net.momirealms.craftengine.core.entity.player.InteractionHand;
import net.momirealms.craftengine.core.item.CustomItem;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.loot.LootTable;
import net.momirealms.craftengine.core.plugin.config.Config;
@@ -42,6 +43,7 @@ import org.bukkit.event.world.GenericGameEvent;
import org.bukkit.inventory.ItemStack;
import java.util.List;
import java.util.Optional;
public class BlockEventListener implements Listener {
private final BukkitCraftEngine plugin;
@@ -121,11 +123,35 @@ public class BlockEventListener implements Listener {
Object blockState = BlockStateUtils.blockDataToBlockState(block.getBlockData());
int stateId = BlockStateUtils.blockStateToId(blockState);
Player player = event.getPlayer();
Location location = block.getLocation();
BukkitServerPlayer serverPlayer = this.plugin.adapt(player);
net.momirealms.craftengine.core.world.World world = new BukkitWorld(player.getWorld());
WorldPosition position = new WorldPosition(world, location.getBlockX() + 0.5, location.getBlockY() + 0.5, location.getBlockZ() + 0.5);
Item<ItemStack> itemInHand = serverPlayer.getItemInHand(InteractionHand.MAIN_HAND);
if (itemInHand != null) {
Optional<CustomItem<ItemStack>> optionalCustomItem = itemInHand.getCustomItem();
if (optionalCustomItem.isPresent()) {
Cancellable dummy = Cancellable.dummy();
optionalCustomItem.get().execute(
PlayerOptionalContext.of(serverPlayer, ContextHolder.builder()
.withParameter(DirectContextParameters.BLOCK, new BukkitBlockInWorld(block))
.withParameter(DirectContextParameters.POSITION, position)
.withParameter(DirectContextParameters.PLAYER, serverPlayer)
.withParameter(DirectContextParameters.EVENT, dummy)
.withOptionalParameter(DirectContextParameters.ITEM_IN_HAND, itemInHand)
), EventTrigger.BREAK
);
if (dummy.isCancelled()) {
event.setCancelled(true);
return;
}
}
}
if (!BlockStateUtils.isVanillaBlock(stateId)) {
ImmutableBlockState state = manager.getImmutableBlockStateUnsafe(stateId);
if (!state.isEmpty()) {
Location location = block.getLocation();
BukkitServerPlayer serverPlayer = this.plugin.adapt(player);
// double check adventure mode to prevent dupe
if (!FastNMS.INSTANCE.mayBuild(serverPlayer.serverPlayer()) && !serverPlayer.canBreak(LocationUtils.toBlockPos(location), null)) {
return;
@@ -139,10 +165,6 @@ public class BlockEventListener implements Listener {
return;
}
Item<ItemStack> itemInHand = serverPlayer.getItemInHand(InteractionHand.MAIN_HAND);
net.momirealms.craftengine.core.world.World world = new BukkitWorld(location.getWorld());
WorldPosition position = new WorldPosition(world, location.getBlockX() + 0.5, location.getBlockY() + 0.5, location.getBlockZ() + 0.5);
// execute functions
Cancellable cancellable = Cancellable.dummy();
PlayerOptionalContext context = PlayerOptionalContext.of(serverPlayer, ContextHolder.builder()
@@ -180,12 +202,12 @@ public class BlockEventListener implements Listener {
}
// drop items
ContextHolder.Builder builder = ContextHolder.builder()
ContextHolder.Builder lootContext = ContextHolder.builder()
.withParameter(DirectContextParameters.POSITION, position)
.withParameter(DirectContextParameters.PLAYER, serverPlayer)
.withParameter(DirectContextParameters.BLOCK, new BukkitBlockInWorld(block))
.withOptionalParameter(DirectContextParameters.ITEM_IN_HAND, itemInHand);
for (Item<Object> item : state.getDrops(builder, world, serverPlayer)) {
for (Item<Object> item : state.getDrops(lootContext, world, serverPlayer)) {
world.dropItemNaturally(position, item);
}
}
@@ -197,23 +219,19 @@ public class BlockEventListener implements Listener {
event.setDropItems(false);
event.setExpToDrop(0);
}
Location location = block.getLocation();
BukkitServerPlayer serverPlayer = this.plugin.adapt(player);
net.momirealms.craftengine.core.world.World world = new BukkitWorld(player.getWorld());
WorldPosition position = new WorldPosition(world, location.getBlockX() + 0.5, location.getBlockY() + 0.5, location.getBlockZ() + 0.5);
ContextHolder.Builder builder = ContextHolder.builder()
ContextHolder lootContext = ContextHolder.builder()
.withParameter(DirectContextParameters.BLOCK, new BukkitBlockInWorld(block))
.withParameter(DirectContextParameters.POSITION, position)
.withParameter(DirectContextParameters.PLAYER, serverPlayer)
.withOptionalParameter(DirectContextParameters.ITEM_IN_HAND, serverPlayer.getItemInHand(InteractionHand.MAIN_HAND));
ContextHolder contextHolder = builder.build();
.withOptionalParameter(DirectContextParameters.ITEM_IN_HAND, itemInHand).build();
for (LootTable<?> lootTable : it.lootTables()) {
for (Item<?> item : lootTable.getRandomItems(contextHolder, world, serverPlayer)) {
for (Item<?> item : lootTable.getRandomItems(lootContext, world, serverPlayer)) {
world.dropItemNaturally(position, item);
}
}
});
}
// sound system
if (Config.enableSoundSystem()) {
Object ownerBlock = BlockStateUtils.getBlockOwner(blockState);

View File

@@ -8,6 +8,7 @@ import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.world.World;
import java.lang.ref.WeakReference;
import java.util.UUID;
public class BukkitEntity extends AbstractEntity {
private final WeakReference<org.bukkit.entity.Entity> entity;
@@ -69,4 +70,14 @@ public class BukkitEntity extends AbstractEntity {
public Key type() {
return KeyUtils.namespacedKey2Key(literalObject().getType().getKey());
}
@Override
public String name() {
return literalObject().getName();
}
@Override
public UUID uuid() {
return literalObject().getUniqueId();
}
}

View File

@@ -13,6 +13,7 @@ import net.momirealms.craftengine.bukkit.world.BukkitWorld;
import net.momirealms.craftengine.core.block.BlockSettings;
import net.momirealms.craftengine.core.block.ImmutableBlockState;
import net.momirealms.craftengine.core.block.PackedBlockState;
import net.momirealms.craftengine.core.entity.player.GameMode;
import net.momirealms.craftengine.core.entity.player.InteractionHand;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.item.Item;
@@ -27,7 +28,10 @@ import net.momirealms.craftengine.core.util.VersionHelper;
import net.momirealms.craftengine.core.world.BlockPos;
import net.momirealms.craftengine.core.world.World;
import net.momirealms.craftengine.core.world.WorldEvents;
import org.bukkit.*;
import org.bukkit.FluidCollisionMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.SoundCategory;
import org.bukkit.attribute.Attribute;
import org.bukkit.attribute.AttributeInstance;
import org.bukkit.block.Block;
@@ -145,18 +149,18 @@ public class BukkitServerPlayer extends Player {
}
@Override
public boolean isCreativeMode() {
return platformPlayer().getGameMode() == GameMode.CREATIVE;
public GameMode gameMode() {
return switch (platformPlayer().getGameMode()) {
case CREATIVE -> GameMode.CREATIVE;
case SPECTATOR -> GameMode.SPECTATOR;
case ADVENTURE -> GameMode.ADVENTURE;
case SURVIVAL -> GameMode.SURVIVAL;
};
}
@Override
public boolean isSpectatorMode() {
return platformPlayer().getGameMode() == GameMode.SPECTATOR;
}
@Override
public boolean isAdventureMode() {
return platformPlayer().getGameMode() == GameMode.ADVENTURE;
public void setGameMode(GameMode gameMode) {
platformPlayer().setGameMode(Objects.requireNonNull(org.bukkit.GameMode.getByValue(gameMode.id())));
}
@Override
@@ -175,6 +179,14 @@ public class BukkitServerPlayer extends Player {
sendPacket(packet, false);
}
@Override
public void sendTitle(Component title, Component subtitle, int fadeIn, int stay, int fadeOut) {
Object titlePacket = FastNMS.INSTANCE.constructor$ClientboundSetTitleTextPacket(ComponentUtils.adventureToMinecraft(title));
Object subtitlePacket = FastNMS.INSTANCE.constructor$ClientboundSetSubtitleTextPacket(ComponentUtils.adventureToMinecraft(subtitle));
Object timePacket = FastNMS.INSTANCE.constructor$ClientboundSetTitlesAnimationPacket(fadeIn, stay, fadeOut);
sendPackets(List.of(titlePacket, subtitlePacket, timePacket), false);
}
@Override
public void sendMessage(Component text, boolean overlay) {
Object packet = FastNMS.INSTANCE.constructor$ClientboundSystemChatPacket(ComponentUtils.adventureToMinecraft(text), overlay);
@@ -816,4 +828,9 @@ public class BukkitServerPlayer extends Player {
return LegacyAttributeUtils.getLuck(platformPlayer());
}
}
@Override
public boolean isFlying() {
return platformPlayer().isFlying();
}
}