mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-19 15:09:15 +00:00
初步打火石音效补全
This commit is contained in:
@@ -2,6 +2,7 @@ package net.momirealms.craftengine.bukkit.item;
|
||||
|
||||
import com.saicone.rtag.item.ItemTagStream;
|
||||
import net.momirealms.craftengine.bukkit.item.behavior.BucketItemBehavior;
|
||||
import net.momirealms.craftengine.bukkit.item.behavior.FlintAndSteelItemBehavior;
|
||||
import net.momirealms.craftengine.bukkit.item.behavior.WaterBucketItemBehavior;
|
||||
import net.momirealms.craftengine.bukkit.item.factory.BukkitItemFactory;
|
||||
import net.momirealms.craftengine.bukkit.item.listener.ArmorEventListener;
|
||||
@@ -43,6 +44,7 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
||||
static {
|
||||
registerVanillaItemExtraBehavior(WaterBucketItemBehavior.INSTANCE, ItemKeys.WATER_BUCKETS);
|
||||
registerVanillaItemExtraBehavior(BucketItemBehavior.INSTANCE, ItemKeys.BUCKET);
|
||||
registerVanillaItemExtraBehavior(FlintAndSteelItemBehavior.INSTANCE, ItemKeys.FLINT_AND_STEEL);
|
||||
}
|
||||
|
||||
private static BukkitItemManager instance;
|
||||
|
||||
@@ -10,6 +10,7 @@ public class BukkitItemBehaviors extends ItemBehaviors {
|
||||
public static final Key FURNITURE_ITEM = Key.from("craftengine:furniture_item");
|
||||
public static final Key WATER_BUCKET_ITEM = Key.from("craftengine:water_bucket_item");
|
||||
public static final Key BUCKET_ITEM = Key.from("craftengine:bucket_item");
|
||||
public static final Key FLINT_AND_STEEL_ITEM = Key.from("craftengine:flint_and_steel_item");
|
||||
|
||||
public static void init() {
|
||||
register(EMPTY, EmptyItemBehavior.FACTORY);
|
||||
@@ -18,5 +19,6 @@ public class BukkitItemBehaviors extends ItemBehaviors {
|
||||
register(FURNITURE_ITEM, FurnitureItemBehavior.FACTORY);
|
||||
register(WATER_BUCKET_ITEM, WaterBucketItemBehavior.FACTORY);
|
||||
register(BUCKET_ITEM, BucketItemBehavior.FACTORY);
|
||||
register(FLINT_AND_STEEL_ITEM, FlintAndSteelItemBehavior.FACTORY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
package net.momirealms.craftengine.bukkit.item.behavior;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
|
||||
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.DirectionUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.InteractUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.LocationUtils;
|
||||
import net.momirealms.craftengine.bukkit.world.BukkitBlockInWorld;
|
||||
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
||||
import net.momirealms.craftengine.core.entity.player.InteractionResult;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.behavior.ItemBehavior;
|
||||
import net.momirealms.craftengine.core.item.behavior.ItemBehaviorFactory;
|
||||
import net.momirealms.craftengine.core.item.context.UseOnContext;
|
||||
import net.momirealms.craftengine.core.pack.Pack;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.sound.SoundSource;
|
||||
import net.momirealms.craftengine.core.util.Direction;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.RandomUtils;
|
||||
import net.momirealms.craftengine.core.world.BlockPos;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
|
||||
public class FlintAndSteelItemBehavior extends ItemBehavior {
|
||||
public static final FlintAndSteelItemBehavior INSTANCE = new FlintAndSteelItemBehavior();
|
||||
public static final Factory FACTORY = new Factory();
|
||||
private static final Key FLINT_SOUND = Key.of("item.flintandsteel.use");
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public InteractionResult useOnBlock(UseOnContext context) {
|
||||
BlockPos clickedPos = context.getClickedPos();
|
||||
BukkitBlockInWorld clicked = (BukkitBlockInWorld) context.getLevel().getBlockAt(clickedPos);
|
||||
Block block = clicked.block();
|
||||
BlockPos firePos = clickedPos.relative(context.getClickedFace());
|
||||
Direction direction = context.getHorizontalDirection();
|
||||
|
||||
// 最基础的判断能不能着火,不能着火都是扯蛋
|
||||
try {
|
||||
if (!(boolean) CoreReflections.method$BaseFireBlock$canBePlacedAt.invoke(null, context.getLevel().serverWorld(), LocationUtils.toBlockPos(firePos), DirectionUtils.toNMSDirection(direction))) {
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
} catch (ReflectiveOperationException e) {
|
||||
CraftEngine.instance().logger().warn("Failed to run BaseFireBlock$canBePlacedAt", e);
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
|
||||
net.momirealms.craftengine.core.entity.player.Player player = context.getPlayer();
|
||||
ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockDataToId(block.getBlockData()));
|
||||
if (state == null || state.isEmpty()) {
|
||||
return InteractionResult.PASS;
|
||||
} else {
|
||||
// 玩家交互目标是自定义方块
|
||||
if (context.getClickedFace() == Direction.UP) {
|
||||
// 客户端层面必须可交互
|
||||
if (!InteractUtils.isInteractable((Player) player.platformPlayer(), BlockStateUtils.fromBlockData(state.vanillaBlockState().handle()), context.getHitResult(), (Item<ItemStack>) context.getItem())) {
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
// 且没有shift
|
||||
if (!player.isSecondaryUseActive()) {
|
||||
player.playSound(FLINT_SOUND, SoundSource.BLOCK, 1f, RandomUtils.generateRandomFloat(0.8f, 1.2f));
|
||||
}
|
||||
} else {
|
||||
BlockData vanillaBlockState = BlockStateUtils.fromBlockData(state.vanillaBlockState().handle());
|
||||
// 原版状态可燃烧,则跳过
|
||||
if (BlockStateUtils.isBurnable(BlockStateUtils.blockDataToBlockState(vanillaBlockState))) {
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
|
||||
// 客户端一定觉得这个东西不可燃烧
|
||||
BlockPos belowFirePos = firePos.relative(Direction.DOWN);
|
||||
BukkitBlockInWorld belowFireBlock = (BukkitBlockInWorld) context.getLevel().getBlockAt(belowFirePos);
|
||||
boolean belowCanBurn;
|
||||
try {
|
||||
Block belowBlock = belowFireBlock.block();
|
||||
belowCanBurn = BlockStateUtils.isBurnable(BlockStateUtils.blockDataToBlockState(belowBlock.getBlockData())) ||
|
||||
(boolean) CoreReflections.method$BlockStateBase$isFaceSturdy.invoke(
|
||||
BlockStateUtils.blockDataToBlockState(belowFireBlock.block().getBlockData()), context.getLevel().serverWorld(), LocationUtils.toBlockPos(belowFirePos), CoreReflections.instance$Direction$UP, CoreReflections.instance$SupportType$FULL);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
CraftEngine.instance().logger().warn("Failed to call method$BlockStateBase$isFaceSturdy", e);
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
|
||||
// 客户端觉得这玩意可交互,就会忽略声音
|
||||
if (InteractUtils.isInteractable((Player) player.platformPlayer(), vanillaBlockState, context.getHitResult(), (Item<ItemStack>) context.getItem())) {
|
||||
// 如果按住了shift,则不会挥手,补发
|
||||
if (player.isSecondaryUseActive()) {
|
||||
// 如果底部不能燃烧,则燃烧点位为侧面,需要补发
|
||||
if (!belowCanBurn) {
|
||||
player.playSound(FLINT_SOUND, SoundSource.BLOCK, 1f, RandomUtils.generateRandomFloat(0.8f, 1.2f));
|
||||
player.swingHand(context.getHand());
|
||||
}
|
||||
} else {
|
||||
player.playSound(FLINT_SOUND, SoundSource.BLOCK, 1f, RandomUtils.generateRandomFloat(0.8f, 1.2f));
|
||||
}
|
||||
} else {
|
||||
if (!belowCanBurn) {
|
||||
player.playSound(FLINT_SOUND, SoundSource.BLOCK, 1f, RandomUtils.generateRandomFloat(0.8f, 1.2f));
|
||||
player.swingHand(context.getHand());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
|
||||
public static class Factory implements ItemBehaviorFactory {
|
||||
@Override
|
||||
public ItemBehavior create(Pack pack, Path path, Key id, Map<String, Object> arguments) {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,7 @@ import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.block.BlockIgniteEvent;
|
||||
import org.bukkit.event.entity.FoodLevelChangeEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.google.gson.JsonElement;
|
||||
import com.mojang.serialization.DynamicOps;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.ReflectionInitException;
|
||||
import net.momirealms.craftengine.bukkit.util.BukkitReflectionUtils;
|
||||
import net.momirealms.craftengine.core.util.ReflectionUtils;
|
||||
@@ -3296,4 +3297,19 @@ public final class CoreReflections {
|
||||
throw new ReflectionInitException("Failed to initialize reflection", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static final Class<?> clazz$BaseFireBlock = requireNonNull(
|
||||
BukkitReflectionUtils.findReobfOrMojmapClass(
|
||||
"world.level.block.BlockFireAbstract",
|
||||
"world.level.block.BaseFireBlock"
|
||||
)
|
||||
);
|
||||
|
||||
public static final Method method$BaseFireBlock$canBePlacedAt = requireNonNull(
|
||||
ReflectionUtils.getStaticMethod(clazz$BaseFireBlock, boolean.class, clazz$Level, clazz$BlockPos, clazz$Direction)
|
||||
);
|
||||
|
||||
public static final Field field$FireBlock$igniteOdds = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(clazz$FireBlock, Object2IntMap.class, 0)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import net.momirealms.craftengine.core.plugin.context.CooldownData;
|
||||
import net.momirealms.craftengine.core.plugin.network.ConnectionState;
|
||||
import net.momirealms.craftengine.core.plugin.network.EntityPacketHandler;
|
||||
import net.momirealms.craftengine.core.plugin.network.ProtocolVersion;
|
||||
import net.momirealms.craftengine.core.sound.SoundSource;
|
||||
import net.momirealms.craftengine.core.util.Direction;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
@@ -283,8 +284,8 @@ public class BukkitServerPlayer extends Player {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playSound(Key sound, float volume, float pitch) {
|
||||
platformPlayer().playSound(platformPlayer(), sound.toString(), SoundCategory.MASTER, volume, pitch);
|
||||
public void playSound(Key sound, SoundSource source, float volume, float pitch) {
|
||||
platformPlayer().playSound(platformPlayer(), sound.toString(), SoundUtils.toBukkit(source), volume, pitch);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -2,8 +2,10 @@ package net.momirealms.craftengine.bukkit.util;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.ReflectionInitException;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.bukkit.CraftBukkitReflections;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBlocks;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBuiltInRegistries;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.NetworkReflections;
|
||||
import net.momirealms.craftengine.core.block.*;
|
||||
@@ -22,18 +24,26 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class BlockStateUtils {
|
||||
public static final IdentityHashMap<Object, Object> CLIENT_SIDE_NOTE_BLOCKS = new IdentityHashMap<>();
|
||||
private static int vanillaStateSize;
|
||||
private static boolean hasInit;
|
||||
public static Map<Object, Integer> IGNITE_ODDS;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void init(int size) {
|
||||
if (hasInit) {
|
||||
throw new IllegalStateException("BlockStateUtils has already been initialized");
|
||||
}
|
||||
vanillaStateSize = size;
|
||||
try {
|
||||
IGNITE_ODDS = (Map<Object, Integer>) CoreReflections.field$FireBlock$igniteOdds.get(MBlocks.FIRE);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new ReflectionInitException("Failed to initialize instance$FireBlock$igniteOdds", e);
|
||||
}
|
||||
hasInit = true;
|
||||
}
|
||||
|
||||
@@ -248,4 +258,9 @@ public class BlockStateUtils {
|
||||
public static int vanillaStateSize() {
|
||||
return vanillaStateSize;
|
||||
}
|
||||
|
||||
public static boolean isBurnable(Object state) {
|
||||
Object blockOwner = getBlockOwner(state);
|
||||
return IGNITE_ODDS.getOrDefault(blockOwner, 0) > 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ items#misc:
|
||||
template: "default:loot_table/self"
|
||||
settings:
|
||||
template:
|
||||
- default:sound/sand
|
||||
- default:sound/stone
|
||||
- default:pickaxe_power/level_1
|
||||
- default:settings/solid_1x1x1
|
||||
overrides:
|
||||
|
||||
@@ -5,6 +5,7 @@ import net.momirealms.craftengine.core.entity.AbstractEntity;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.plugin.context.CooldownData;
|
||||
import net.momirealms.craftengine.core.plugin.network.NetWorkUser;
|
||||
import net.momirealms.craftengine.core.sound.SoundSource;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.world.BlockPos;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -81,7 +82,11 @@ public abstract class Player extends AbstractEntity implements NetWorkUser {
|
||||
playSound(sound, 1f, 1f);
|
||||
}
|
||||
|
||||
public abstract void playSound(Key sound, float volume, float pitch);
|
||||
public void playSound(Key sound, float volume, float pitch) {
|
||||
playSound(sound, SoundSource.MASTER, volume, pitch);
|
||||
}
|
||||
|
||||
public abstract void playSound(Key sound, SoundSource source, float volume, float pitch);
|
||||
|
||||
public abstract void giveItem(Item<?> item);
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import net.momirealms.craftengine.core.util.Key;
|
||||
|
||||
public class ItemKeys {
|
||||
public static final Key AIR = Key.of("minecraft:air");
|
||||
public static final Key FLINT_AND_STEEL = Key.of("minecraft:flint_and_steel");
|
||||
public static final Key STONE = Key.of("minecraft:stone");
|
||||
public static final Key TRIDENT = Key.of("minecraft:trident");
|
||||
public static final Key SHIELD = Key.of("minecraft:shield");
|
||||
|
||||
Reference in New Issue
Block a user