mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-19 15:09:15 +00:00
重构声音part 1
This commit is contained in:
@@ -73,18 +73,14 @@ public final class BlockEventListener implements Listener {
|
|||||||
// send sound if the placed block's sounds are removed
|
// send sound if the placed block's sounds are removed
|
||||||
if (Config.enableSoundSystem()) {
|
if (Config.enableSoundSystem()) {
|
||||||
Block block = event.getBlock();
|
Block block = event.getBlock();
|
||||||
Object blockState = BlockStateUtils.blockDataToBlockState(block.getBlockData());
|
Object blockState = BlockStateUtils.getBlockState(block);
|
||||||
if (blockState != MBlocks.AIR$defaultState) {
|
if (blockState != MBlocks.AIR$defaultState && BlockStateUtils.isVanillaBlock(blockState)) {
|
||||||
Object ownerBlock = BlockStateUtils.getBlockOwner(blockState);
|
Object soundType = FastNMS.INSTANCE.method$BlockBehaviour$BlockStateBase$getSoundType(blockState);
|
||||||
if (this.manager.isBlockSoundRemoved(ownerBlock)) {
|
Object soundEvent = FastNMS.INSTANCE.field$SoundType$placeSound(soundType);
|
||||||
|
Object soundId = FastNMS.INSTANCE.field$SoundEvent$location(soundEvent);
|
||||||
|
if (this.manager.isPlaceSoundMissing(soundId)) {
|
||||||
if (player.getInventory().getItemInMainHand().getType() != Material.DEBUG_STICK) {
|
if (player.getInventory().getItemInMainHand().getType() != Material.DEBUG_STICK) {
|
||||||
try {
|
player.playSound(block.getLocation().add(0.5, 0.5, 0.5), soundId.toString(), SoundCategory.BLOCKS, 1f, 0.8f);
|
||||||
Object soundType = CoreReflections.field$BlockBehaviour$soundType.get(ownerBlock);
|
|
||||||
Object placeSound = CoreReflections.field$SoundType$placeSound.get(soundType);
|
|
||||||
player.playSound(block.getLocation().add(0.5, 0.5, 0.5), FastNMS.INSTANCE.field$SoundEvent$location(placeSound).toString(), SoundCategory.BLOCKS, 1f, 0.8f);
|
|
||||||
} catch (ReflectiveOperationException e) {
|
|
||||||
this.plugin.logger().warn("Failed to get sound type", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -92,23 +88,19 @@ public final class BlockEventListener implements Listener {
|
|||||||
}
|
}
|
||||||
// resend sound if the clicked block is interactable on client side
|
// resend sound if the clicked block is interactable on client side
|
||||||
if (serverPlayer.shouldResendSound()) {
|
if (serverPlayer.shouldResendSound()) {
|
||||||
try {
|
Block block = event.getBlock();
|
||||||
Block block = event.getBlock();
|
Object blockState = BlockStateUtils.getBlockState(block);
|
||||||
Object blockState = BlockStateUtils.blockDataToBlockState(block.getBlockData());
|
Object soundType = FastNMS.INSTANCE.method$BlockBehaviour$BlockStateBase$getSoundType(blockState);
|
||||||
Object ownerBlock = BlockStateUtils.getBlockOwner(blockState);
|
Object soundEvent = FastNMS.INSTANCE.field$SoundType$placeSound(soundType);
|
||||||
Object soundType = CoreReflections.field$BlockBehaviour$soundType.get(ownerBlock);
|
Object soundId = FastNMS.INSTANCE.field$SoundEvent$location(soundEvent);
|
||||||
Object placeSound = CoreReflections.field$SoundType$placeSound.get(soundType);
|
player.playSound(block.getLocation().add(0.5, 0.5, 0.5), soundId.toString(), SoundCategory.BLOCKS, 1f, 0.8f);
|
||||||
player.playSound(block.getLocation().add(0.5, 0.5, 0.5), FastNMS.INSTANCE.field$SoundEvent$location(placeSound).toString(), SoundCategory.BLOCKS, 1f, 0.8f);
|
|
||||||
} catch (ReflectiveOperationException e) {
|
|
||||||
this.plugin.logger().warn("Failed to get sound type", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||||
public void onPlayerBreak(BlockBreakEvent event) {
|
public void onPlayerBreak(BlockBreakEvent event) {
|
||||||
org.bukkit.block.Block block = event.getBlock();
|
org.bukkit.block.Block block = event.getBlock();
|
||||||
Object blockState = BlockStateUtils.blockDataToBlockState(block.getBlockData());
|
Object blockState = BlockStateUtils.getBlockState(block);
|
||||||
int stateId = BlockStateUtils.blockStateToId(blockState);
|
int stateId = BlockStateUtils.blockStateToId(blockState);
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
Location location = block.getLocation();
|
Location location = block.getLocation();
|
||||||
@@ -194,15 +186,11 @@ public final class BlockEventListener implements Listener {
|
|||||||
}
|
}
|
||||||
// sound system
|
// sound system
|
||||||
if (Config.enableSoundSystem()) {
|
if (Config.enableSoundSystem()) {
|
||||||
Object ownerBlock = BlockStateUtils.getBlockOwner(blockState);
|
Object soundType = FastNMS.INSTANCE.method$BlockBehaviour$BlockStateBase$getSoundType(blockState);
|
||||||
if (this.manager.isBlockSoundRemoved(ownerBlock)) {
|
Object soundEvent = FastNMS.INSTANCE.field$SoundType$breakSound(soundType);
|
||||||
try {
|
Object soundId = FastNMS.INSTANCE.field$SoundEvent$location(soundEvent);
|
||||||
Object soundType = CoreReflections.field$BlockBehaviour$soundType.get(ownerBlock);
|
if (this.manager.isBreakSoundMissing(soundId)) {
|
||||||
Object breakSound = CoreReflections.field$SoundType$breakSound.get(soundType);
|
player.playSound(block.getLocation().add(0.5, 0.5, 0.5), soundId.toString(), SoundCategory.BLOCKS, 1f, 0.8f);
|
||||||
player.playSound(block.getLocation().add(0.5, 0.5, 0.5), FastNMS.INSTANCE.field$SoundEvent$location(breakSound).toString(), SoundCategory.BLOCKS, 1f, 0.8f);
|
|
||||||
} catch (ReflectiveOperationException e) {
|
|
||||||
this.plugin.logger().warn("Failed to get sound type", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -259,15 +247,11 @@ public final class BlockEventListener implements Listener {
|
|||||||
}
|
}
|
||||||
player.playSound(location, state.settings().sounds().stepSound().id().toString(), SoundCategory.BLOCKS, state.settings().sounds().stepSound().volume().get(), state.settings().sounds().stepSound().pitch().get());
|
player.playSound(location, state.settings().sounds().stepSound().id().toString(), SoundCategory.BLOCKS, state.settings().sounds().stepSound().volume().get(), state.settings().sounds().stepSound().pitch().get());
|
||||||
} else if (Config.enableSoundSystem()) {
|
} else if (Config.enableSoundSystem()) {
|
||||||
Object ownerBlock = BlockStateUtils.getBlockOwner(blockState);
|
Object soundType = FastNMS.INSTANCE.method$BlockBehaviour$BlockStateBase$getSoundType(blockState);
|
||||||
if (this.manager.isBlockSoundRemoved(ownerBlock)) {
|
Object soundEvent = FastNMS.INSTANCE.field$SoundType$stepSound(soundType);
|
||||||
try {
|
Object soundId = FastNMS.INSTANCE.field$SoundEvent$location(soundEvent);
|
||||||
Object soundType = CoreReflections.field$BlockBehaviour$soundType.get(ownerBlock);
|
if (this.manager.isStepSoundMissing(soundId)) {
|
||||||
Object stepSound = CoreReflections.field$SoundType$stepSound.get(soundType);
|
player.playSound(player.getLocation(), soundId.toString(), SoundCategory.BLOCKS, 0.15f, 1f);
|
||||||
player.playSound(player.getLocation(), FastNMS.INSTANCE.field$SoundEvent$location(stepSound).toString(), SoundCategory.BLOCKS, 0.15f, 1f);
|
|
||||||
} catch (ReflectiveOperationException e) {
|
|
||||||
this.plugin.logger().warn("Failed to get sound type", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package net.momirealms.craftengine.bukkit.block;
|
package net.momirealms.craftengine.bukkit.block;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
import net.momirealms.craftengine.bukkit.block.behavior.UnsafeCompositeBlockBehavior;
|
import net.momirealms.craftengine.bukkit.block.behavior.UnsafeCompositeBlockBehavior;
|
||||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||||
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
||||||
@@ -31,6 +33,7 @@ import org.bukkit.event.HandlerList;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public final class BukkitBlockManager extends AbstractBlockManager {
|
public final class BukkitBlockManager extends AbstractBlockManager {
|
||||||
@@ -40,7 +43,11 @@ public final class BukkitBlockManager extends AbstractBlockManager {
|
|||||||
private static BukkitBlockManager instance;
|
private static BukkitBlockManager instance;
|
||||||
private final BukkitCraftEngine plugin;
|
private final BukkitCraftEngine plugin;
|
||||||
// 事件监听器
|
// 事件监听器
|
||||||
private BlockEventListener blockEventListener;
|
private final BlockEventListener blockEventListener;
|
||||||
|
// 用于缓存string形式的方块状态到原版方块状态
|
||||||
|
private final Map<String, Object> blockStateCache = new HashMap<>(1024);
|
||||||
|
// 用于临时存储可燃烧自定义方块的列表
|
||||||
|
private final List<DelegatingBlock> burnableBlocks = new ArrayList<>();
|
||||||
// 可燃烧的方块
|
// 可燃烧的方块
|
||||||
private Map<Object, Integer> igniteOdds;
|
private Map<Object, Integer> igniteOdds;
|
||||||
private Map<Object, Integer> burnOdds;
|
private Map<Object, Integer> burnOdds;
|
||||||
@@ -50,15 +57,15 @@ public final class BukkitBlockManager extends AbstractBlockManager {
|
|||||||
// 缓存的原版方块tag包
|
// 缓存的原版方块tag包
|
||||||
private Object cachedUpdateTagsPacket;
|
private Object cachedUpdateTagsPacket;
|
||||||
// 被移除声音的原版方块
|
// 被移除声音的原版方块
|
||||||
private final Set<Object> replacedBlockSounds = new HashSet<>();
|
private Set<Object> missingPlaceSounds = Set.of();
|
||||||
// 用于缓存string形式的方块状态到原版方块状态
|
private Set<Object> missingBreakSounds = Set.of();
|
||||||
private final Map<String, Object> blockStateCache = new HashMap<>(1024);
|
private Set<Object> missingHitSounds = Set.of();
|
||||||
// 用于临时存储可燃烧自定义方块的列表
|
private Set<Object> missingStepSounds = Set.of();
|
||||||
private final List<DelegatingBlock> burnableBlocks = new ArrayList<>();
|
|
||||||
|
|
||||||
public BukkitBlockManager(BukkitCraftEngine plugin) {
|
public BukkitBlockManager(BukkitCraftEngine plugin) {
|
||||||
super(plugin, RegistryUtils.currentBlockRegistrySize(), Config.serverSideBlocks());
|
super(plugin, RegistryUtils.currentBlockRegistrySize(), Config.serverSideBlocks());
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
|
this.blockEventListener = new BlockEventListener(plugin, this);
|
||||||
this.registerServerSideCustomBlocks(Config.serverSideBlocks());
|
this.registerServerSideCustomBlocks(Config.serverSideBlocks());
|
||||||
EmptyBlock.initialize();
|
EmptyBlock.initialize();
|
||||||
instance = this;
|
instance = this;
|
||||||
@@ -71,7 +78,6 @@ public final class BukkitBlockManager extends AbstractBlockManager {
|
|||||||
this.initVanillaBlockSettings();
|
this.initVanillaBlockSettings();
|
||||||
this.deceiveBukkitRegistry();
|
this.deceiveBukkitRegistry();
|
||||||
this.markVanillaNoteBlocks();
|
this.markVanillaNoteBlocks();
|
||||||
this.blockEventListener = new BlockEventListener(plugin, this);
|
|
||||||
Arrays.fill(this.immutableBlockStates, EmptyBlock.INSTANCE.defaultState());
|
Arrays.fill(this.immutableBlockStates, EmptyBlock.INSTANCE.defaultState());
|
||||||
this.plugin.networkManager().registerBlockStatePacketListeners(this.blockStateMappings); // 一定要预先初始化一次,预防id超出上限
|
this.plugin.networkManager().registerBlockStatePacketListeners(this.blockStateMappings); // 一定要预先初始化一次,预防id超出上限
|
||||||
}
|
}
|
||||||
@@ -411,8 +417,20 @@ public final class BukkitBlockManager extends AbstractBlockManager {
|
|||||||
this.clientBoundTags.put(FastNMS.INSTANCE.method$IdMap$getId(MBuiltInRegistries.BLOCK, block).orElseThrow(() -> new IllegalStateException("Block " + id + " not found")), tags);
|
this.clientBoundTags.put(FastNMS.INSTANCE.method$IdMap$getId(MBuiltInRegistries.BLOCK, block).orElseThrow(() -> new IllegalStateException("Block " + id + " not found")), tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isBlockSoundRemoved(Object block) {
|
public boolean isPlaceSoundMissing(Object sound) {
|
||||||
return this.replacedBlockSounds.contains(block);
|
return this.missingPlaceSounds.contains(sound);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBreakSoundMissing(Object sound) {
|
||||||
|
return this.missingBreakSounds.contains(sound);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isHitSoundMissing(Object sound) {
|
||||||
|
return this.missingHitSounds.contains(sound);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStepSoundMissing(Object sound) {
|
||||||
|
return this.missingStepSounds.contains(sound);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void unfreezeRegistry() {
|
private void unfreezeRegistry() {
|
||||||
@@ -463,6 +481,51 @@ public final class BukkitBlockManager extends AbstractBlockManager {
|
|||||||
return this.vanillaBlockStateCount;
|
return this.vanillaBlockStateCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("DuplicatedCode")
|
||||||
|
@Override
|
||||||
|
protected void processSounds() {
|
||||||
|
Set<Object> affectedBlockSoundTypes = new HashSet<>();
|
||||||
|
for (BlockStateWrapper vanillaBlockState : super.tempVisualBlocksInUse) {
|
||||||
|
affectedBlockSoundTypes.add(FastNMS.INSTANCE.method$BlockBehaviour$BlockStateBase$getSoundType(vanillaBlockState.literalObject()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<Object> placeSounds = new HashSet<>();
|
||||||
|
Set<Object> breakSounds = new HashSet<>();
|
||||||
|
Set<Object> stepSounds = new HashSet<>();
|
||||||
|
Set<Object> hitSounds = new HashSet<>();
|
||||||
|
|
||||||
|
for (Object soundType : affectedBlockSoundTypes) {
|
||||||
|
placeSounds.add(FastNMS.INSTANCE.field$SoundEvent$location(FastNMS.INSTANCE.field$SoundType$placeSound(soundType)));
|
||||||
|
breakSounds.add(FastNMS.INSTANCE.field$SoundEvent$location(FastNMS.INSTANCE.field$SoundType$breakSound(soundType)));
|
||||||
|
stepSounds.add(FastNMS.INSTANCE.field$SoundEvent$location(FastNMS.INSTANCE.field$SoundType$stepSound(soundType)));
|
||||||
|
hitSounds.add(FastNMS.INSTANCE.field$SoundEvent$location(FastNMS.INSTANCE.field$SoundType$hitSound(soundType)));
|
||||||
|
}
|
||||||
|
|
||||||
|
ImmutableMap.Builder<Key, Key> soundReplacementBuilder = ImmutableMap.builder();
|
||||||
|
for (Object soundId : placeSounds) {
|
||||||
|
Key previousId = KeyUtils.resourceLocationToKey(soundId);
|
||||||
|
soundReplacementBuilder.put(previousId, Key.of(previousId.namespace(), "replaced." + previousId.value()));
|
||||||
|
}
|
||||||
|
for (Object soundId : breakSounds) {
|
||||||
|
Key previousId = KeyUtils.resourceLocationToKey(soundId);
|
||||||
|
soundReplacementBuilder.put(previousId, Key.of(previousId.namespace(), "replaced." + previousId.value()));
|
||||||
|
}
|
||||||
|
for (Object soundId : stepSounds) {
|
||||||
|
Key previousId = KeyUtils.resourceLocationToKey(soundId);
|
||||||
|
soundReplacementBuilder.put(previousId, Key.of(previousId.namespace(), "replaced." + previousId.value()));
|
||||||
|
}
|
||||||
|
for (Object soundId : hitSounds) {
|
||||||
|
Key previousId = KeyUtils.resourceLocationToKey(soundId);
|
||||||
|
soundReplacementBuilder.put(previousId, Key.of(previousId.namespace(), "replaced." + previousId.value()));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.missingPlaceSounds = placeSounds;
|
||||||
|
this.missingBreakSounds = breakSounds;
|
||||||
|
this.missingHitSounds = hitSounds;
|
||||||
|
this.missingStepSounds = stepSounds;
|
||||||
|
this.soundReplacements = soundReplacementBuilder.buildKeepingLast();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected CustomBlock createCustomBlock(@NotNull Holder.Reference<CustomBlock> holder,
|
protected CustomBlock createCustomBlock(@NotNull Holder.Reference<CustomBlock> holder,
|
||||||
@NotNull BlockStateVariantProvider variantProvider,
|
@NotNull BlockStateVariantProvider variantProvider,
|
||||||
|
|||||||
@@ -1037,8 +1037,10 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
|||||||
// not a custom block
|
// not a custom block
|
||||||
if (BlockStateUtils.isVanillaBlock(stateId)) {
|
if (BlockStateUtils.isVanillaBlock(stateId)) {
|
||||||
if (Config.enableSoundSystem()) {
|
if (Config.enableSoundSystem()) {
|
||||||
Object blockOwner = FastNMS.INSTANCE.method$BlockState$getBlock(blockState);
|
Object soundType = FastNMS.INSTANCE.method$BlockBehaviour$BlockStateBase$getSoundType(blockState);
|
||||||
if (BukkitBlockManager.instance().isBlockSoundRemoved(blockOwner)) {
|
Object soundEvent = FastNMS.INSTANCE.field$SoundType$hitSound(soundType);
|
||||||
|
Object soundId = FastNMS.INSTANCE.field$SoundEvent$location(soundEvent);
|
||||||
|
if (BukkitBlockManager.instance().isHitSoundMissing(soundId)) {
|
||||||
player.startMiningBlock(pos, blockState, null);
|
player.startMiningBlock(pos, blockState, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2293,47 +2295,31 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
|||||||
int state = buf.readInt();
|
int state = buf.readInt();
|
||||||
boolean global = buf.readBoolean();
|
boolean global = buf.readBoolean();
|
||||||
int newState = user.clientModEnabled() ? modBlockStateMapper[state] : blockStateMapper[state];
|
int newState = user.clientModEnabled() ? modBlockStateMapper[state] : blockStateMapper[state];
|
||||||
|
Object blockState = BlockStateUtils.idToBlockState(state);
|
||||||
|
Object soundType = FastNMS.INSTANCE.method$BlockBehaviour$BlockStateBase$getSoundType(blockState);
|
||||||
|
Object soundEvent = FastNMS.INSTANCE.field$SoundType$breakSound(soundType);
|
||||||
|
Object rawSoundId = FastNMS.INSTANCE.field$SoundEvent$location(soundEvent);
|
||||||
if (BlockStateUtils.isVanillaBlock(state)) {
|
if (BlockStateUtils.isVanillaBlock(state)) {
|
||||||
Object blockState = BlockStateUtils.idToBlockState(state);
|
if (BukkitBlockManager.instance().isBreakSoundMissing(rawSoundId)) {
|
||||||
Object block = BlockStateUtils.getBlockOwner(blockState);
|
Key mappedSoundId = BukkitBlockManager.instance().replaceSoundIfExist(KeyUtils.resourceLocationToKey(rawSoundId));
|
||||||
if (BukkitBlockManager.instance().isBlockSoundRemoved(block)) {
|
|
||||||
Object soundType = FastNMS.INSTANCE.method$BlockBehaviour$BlockStateBase$getSoundType(blockState);
|
|
||||||
Object breakSound = FastNMS.INSTANCE.field$SoundType$breakSound(soundType);
|
|
||||||
Key soundId = Key.of(FastNMS.INSTANCE.field$SoundEvent$location(breakSound).toString());
|
|
||||||
Key mappedSoundId = BukkitBlockManager.instance().replaceSoundIfExist(soundId);
|
|
||||||
if (mappedSoundId != null) {
|
if (mappedSoundId != null) {
|
||||||
Object mappedBreakSound = FastNMS.INSTANCE.constructor$SoundEvent(KeyUtils.toResourceLocation(mappedSoundId), Optional.empty());
|
|
||||||
Object mappedBreakSoundHolder = FastNMS.INSTANCE.method$Holder$direct(mappedBreakSound);
|
|
||||||
Object packet = FastNMS.INSTANCE.constructor$ClientboundSoundPacket(
|
Object packet = FastNMS.INSTANCE.constructor$ClientboundSoundPacket(
|
||||||
mappedBreakSoundHolder,
|
FastNMS.INSTANCE.method$Holder$direct(FastNMS.INSTANCE.constructor$SoundEvent(KeyUtils.toResourceLocation(mappedSoundId), Optional.empty())),
|
||||||
CoreReflections.instance$SoundSource$BLOCKS,
|
CoreReflections.instance$SoundSource$BLOCKS,
|
||||||
blockPos.x() + 0.5,
|
blockPos.x() + 0.5, blockPos.y() + 0.5, blockPos.z() + 0.5, 1f, 0.8F,
|
||||||
blockPos.y() + 0.5,
|
|
||||||
blockPos.z() + 0.5,
|
|
||||||
1f,
|
|
||||||
0.8F,
|
|
||||||
RandomUtils.generateRandomLong()
|
RandomUtils.generateRandomLong()
|
||||||
);
|
);
|
||||||
user.sendPacket(packet, true);
|
user.sendPacket(packet, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Object blockState = BlockStateUtils.idToBlockState(state);
|
Key soundId = KeyUtils.resourceLocationToKey(rawSoundId);
|
||||||
Object soundType = FastNMS.INSTANCE.method$BlockBehaviour$BlockStateBase$getSoundType(blockState);
|
|
||||||
Object breakSound = FastNMS.INSTANCE.field$SoundType$breakSound(soundType);
|
|
||||||
Key soundId = Key.of(FastNMS.INSTANCE.field$SoundEvent$location(breakSound).toString());
|
|
||||||
Key mappedSoundId = BukkitBlockManager.instance().replaceSoundIfExist(soundId);
|
Key mappedSoundId = BukkitBlockManager.instance().replaceSoundIfExist(soundId);
|
||||||
Object finalSoundId = KeyUtils.toResourceLocation(mappedSoundId == null ? soundId : mappedSoundId);
|
Object finalSoundId = KeyUtils.toResourceLocation(mappedSoundId == null ? soundId : mappedSoundId);
|
||||||
Object mappedBreakSound = FastNMS.INSTANCE.constructor$SoundEvent(finalSoundId, Optional.empty());
|
|
||||||
Object mappedBreakSoundHolder = FastNMS.INSTANCE.method$Holder$direct(mappedBreakSound);
|
|
||||||
Object packet = FastNMS.INSTANCE.constructor$ClientboundSoundPacket(
|
Object packet = FastNMS.INSTANCE.constructor$ClientboundSoundPacket(
|
||||||
mappedBreakSoundHolder,
|
FastNMS.INSTANCE.method$Holder$direct(FastNMS.INSTANCE.constructor$SoundEvent(finalSoundId, Optional.empty())),
|
||||||
CoreReflections.instance$SoundSource$BLOCKS,
|
CoreReflections.instance$SoundSource$BLOCKS,
|
||||||
blockPos.x() + 0.5,
|
blockPos.x() + 0.5, blockPos.y() + 0.5, blockPos.z() + 0.5, 1f, 0.8F,
|
||||||
blockPos.y() + 0.5,
|
|
||||||
blockPos.z() + 0.5,
|
|
||||||
1f,
|
|
||||||
0.8F,
|
|
||||||
RandomUtils.generateRandomLong()
|
RandomUtils.generateRandomLong()
|
||||||
);
|
);
|
||||||
user.sendPacket(packet, true);
|
user.sendPacket(packet, true);
|
||||||
|
|||||||
@@ -14,10 +14,7 @@ import net.momirealms.craftengine.core.block.parser.BlockNbtParser;
|
|||||||
import net.momirealms.craftengine.core.block.properties.Properties;
|
import net.momirealms.craftengine.core.block.properties.Properties;
|
||||||
import net.momirealms.craftengine.core.block.properties.Property;
|
import net.momirealms.craftengine.core.block.properties.Property;
|
||||||
import net.momirealms.craftengine.core.loot.LootTable;
|
import net.momirealms.craftengine.core.loot.LootTable;
|
||||||
import net.momirealms.craftengine.core.pack.LoadingSequence;
|
import net.momirealms.craftengine.core.pack.*;
|
||||||
import net.momirealms.craftengine.core.pack.Pack;
|
|
||||||
import net.momirealms.craftengine.core.pack.PendingConfigSection;
|
|
||||||
import net.momirealms.craftengine.core.pack.ResourceLocation;
|
|
||||||
import net.momirealms.craftengine.core.pack.cache.IdAllocator;
|
import net.momirealms.craftengine.core.pack.cache.IdAllocator;
|
||||||
import net.momirealms.craftengine.core.pack.model.generation.AbstractModelGenerator;
|
import net.momirealms.craftengine.core.pack.model.generation.AbstractModelGenerator;
|
||||||
import net.momirealms.craftengine.core.pack.model.generation.ModelGeneration;
|
import net.momirealms.craftengine.core.pack.model.generation.ModelGeneration;
|
||||||
@@ -65,8 +62,6 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem
|
|||||||
protected final Map<Key, JsonElement> modBlockStateOverrides = new HashMap<>();
|
protected final Map<Key, JsonElement> modBlockStateOverrides = new HashMap<>();
|
||||||
// 根据外观查找真实状态,用于debug指令
|
// 根据外观查找真实状态,用于debug指令
|
||||||
protected final Map<Integer, List<Integer>> appearanceToRealState = new Int2ObjectOpenHashMap<>();
|
protected final Map<Integer, List<Integer>> appearanceToRealState = new Int2ObjectOpenHashMap<>();
|
||||||
// 声音映射表,和使用了哪些视觉方块有关
|
|
||||||
protected final Map<Key, Key> soundReplacements = new HashMap<>(512, 0.5f);
|
|
||||||
// 用于note_block:0这样格式的自动分配
|
// 用于note_block:0这样格式的自动分配
|
||||||
protected final Map<Key, List<BlockStateWrapper>> blockStateArranger = new HashMap<>();
|
protected final Map<Key, List<BlockStateWrapper>> blockStateArranger = new HashMap<>();
|
||||||
// 根据registry id找note_block:x中的x值
|
// 根据registry id找note_block:x中的x值
|
||||||
@@ -83,6 +78,10 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem
|
|||||||
protected final ImmutableBlockState[] immutableBlockStates;
|
protected final ImmutableBlockState[] immutableBlockStates;
|
||||||
// 原版方块的属性缓存
|
// 原版方块的属性缓存
|
||||||
protected final BlockSettings[] vanillaBlockSettings;
|
protected final BlockSettings[] vanillaBlockSettings;
|
||||||
|
// 临时存储哪些视觉方块被使用了
|
||||||
|
protected final Set<BlockStateWrapper> tempVisualBlocksInUse = new HashSet<>();
|
||||||
|
// 声音映射表,和使用了哪些视觉方块有关
|
||||||
|
protected Map<Key, Key> soundReplacements = Map.of();
|
||||||
|
|
||||||
protected AbstractBlockManager(CraftEngine plugin, int vanillaBlockStateCount, int customBlockCount) {
|
protected AbstractBlockManager(CraftEngine plugin, int vanillaBlockStateCount, int customBlockCount) {
|
||||||
super(plugin);
|
super(plugin);
|
||||||
@@ -122,7 +121,6 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem
|
|||||||
this.blockStateOverrides.clear();
|
this.blockStateOverrides.clear();
|
||||||
this.modBlockStateOverrides.clear();
|
this.modBlockStateOverrides.clear();
|
||||||
this.byId.clear();
|
this.byId.clear();
|
||||||
this.soundReplacements.clear();
|
|
||||||
this.blockStateArranger.clear();
|
this.blockStateArranger.clear();
|
||||||
this.reversedBlockStateArranger.clear();
|
this.reversedBlockStateArranger.clear();
|
||||||
this.appearanceToRealState.clear();
|
this.appearanceToRealState.clear();
|
||||||
@@ -133,8 +131,9 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem
|
|||||||
@Override
|
@Override
|
||||||
public void delayedLoad() {
|
public void delayedLoad() {
|
||||||
this.initSuggestions();
|
this.initSuggestions();
|
||||||
this.clearCache();
|
|
||||||
this.resendTags();
|
this.resendTags();
|
||||||
|
this.processSounds();
|
||||||
|
this.clearCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -147,24 +146,6 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem
|
|||||||
return Optional.ofNullable(this.byId.get(id));
|
return Optional.ofNullable(this.byId.get(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void addCustomBlock(CustomBlock customBlock) {
|
|
||||||
// 绑定外观状态等
|
|
||||||
for (ImmutableBlockState state : customBlock.variantProvider().states()) {
|
|
||||||
int internalId = state.customBlockState().registryId();
|
|
||||||
int appearanceId = state.vanillaBlockState().registryId();
|
|
||||||
int index = internalId - this.vanillaBlockStateCount;
|
|
||||||
this.immutableBlockStates[index] = state;
|
|
||||||
this.blockStateMappings[internalId] = appearanceId;
|
|
||||||
this.appearanceToRealState.computeIfAbsent(appearanceId, k -> new IntArrayList()).add(internalId);
|
|
||||||
this.applyPlatformSettings(state);
|
|
||||||
// generate mod assets
|
|
||||||
if (Config.generateModAssets()) {
|
|
||||||
this.modBlockStateOverrides.put(getBlockOwnerId(state.customBlockState()), this.tempVanillaBlockStateModels.get(appearanceId));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.byId.put(customBlock.id(), customBlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract void applyPlatformSettings(ImmutableBlockState state);
|
protected abstract void applyPlatformSettings(ImmutableBlockState state);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -203,6 +184,7 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem
|
|||||||
|
|
||||||
protected void clearCache() {
|
protected void clearCache() {
|
||||||
this.tempVanillaBlockStateModels.clear();
|
this.tempVanillaBlockStateModels.clear();
|
||||||
|
this.tempVisualBlocksInUse.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void initSuggestions() {
|
protected void initSuggestions() {
|
||||||
@@ -238,6 +220,8 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem
|
|||||||
|
|
||||||
protected abstract int vanillaBlockStateCount();
|
protected abstract int vanillaBlockStateCount();
|
||||||
|
|
||||||
|
protected abstract void processSounds();
|
||||||
|
|
||||||
protected abstract CustomBlock createCustomBlock(@NotNull Holder.Reference<CustomBlock> holder,
|
protected abstract CustomBlock createCustomBlock(@NotNull Holder.Reference<CustomBlock> holder,
|
||||||
@NotNull BlockStateVariantProvider variantProvider,
|
@NotNull BlockStateVariantProvider variantProvider,
|
||||||
@NotNull Map<EventTrigger, List<Function<PlayerOptionalContext>>> events,
|
@NotNull Map<EventTrigger, List<Function<PlayerOptionalContext>>> events,
|
||||||
@@ -538,15 +522,34 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem
|
|||||||
boolean isEntityBlock = entityBlockBehavior != null;
|
boolean isEntityBlock = entityBlockBehavior != null;
|
||||||
|
|
||||||
// 绑定行为
|
// 绑定行为
|
||||||
for (ImmutableBlockState blockState : states) {
|
for (ImmutableBlockState state : states) {
|
||||||
blockState.setBehavior(blockBehavior);
|
|
||||||
if (isEntityBlock) {
|
if (isEntityBlock) {
|
||||||
blockState.setBlockEntityType(entityBlockBehavior.blockEntityType());
|
state.setBlockEntityType(entityBlockBehavior.blockEntityType());
|
||||||
|
}
|
||||||
|
state.setBehavior(blockBehavior);
|
||||||
|
int internalId = state.customBlockState().registryId();
|
||||||
|
int appearanceId = state.vanillaBlockState().registryId();
|
||||||
|
int index = internalId - AbstractBlockManager.this.vanillaBlockStateCount;
|
||||||
|
AbstractBlockManager.this.immutableBlockStates[index] = state;
|
||||||
|
AbstractBlockManager.this.blockStateMappings[internalId] = appearanceId;
|
||||||
|
AbstractBlockManager.this.appearanceToRealState.computeIfAbsent(appearanceId, k -> new IntArrayList()).add(internalId);
|
||||||
|
AbstractBlockManager.this.tempVisualBlocksInUse.add(state.vanillaBlockState());
|
||||||
|
AbstractBlockManager.this.applyPlatformSettings(state);
|
||||||
|
// generate mod assets
|
||||||
|
if (Config.generateModAssets()) {
|
||||||
|
AbstractBlockManager.this.modBlockStateOverrides.put(BlockManager.createCustomBlockKey(index), Optional.ofNullable(AbstractBlockManager.this.tempVanillaBlockStateModels.get(appearanceId))
|
||||||
|
.orElseGet(() -> {
|
||||||
|
// 如果未指定模型,说明复用原版模型?但是部分模型是多部位模型,无法使用变体解决问题
|
||||||
|
// 未来需要靠mod重构彻底解决问题
|
||||||
|
JsonObject json = new JsonObject();
|
||||||
|
json.addProperty("model", "minecraft:block/air");
|
||||||
|
return json;
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加方块
|
// 添加方块
|
||||||
addCustomBlock(customBlock);
|
AbstractBlockManager.this.byId.put(customBlock.id(), customBlock);
|
||||||
|
|
||||||
}, () -> GsonHelper.get().toJson(section)));
|
}, () -> GsonHelper.get().toJson(section)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,25 +11,19 @@ import java.nio.file.Path;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class GsonHelper {
|
public final class GsonHelper {
|
||||||
private final Gson gson;
|
private static final Gson GSON;
|
||||||
|
|
||||||
public GsonHelper() {
|
private GsonHelper() {}
|
||||||
this.gson = new GsonBuilder()
|
|
||||||
|
static {
|
||||||
|
GSON = new GsonBuilder()
|
||||||
.disableHtmlEscaping()
|
.disableHtmlEscaping()
|
||||||
.create();
|
.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Gson getGson() {
|
|
||||||
return gson;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Gson get() {
|
public static Gson get() {
|
||||||
return SingletonHolder.INSTANCE.getGson();
|
return GSON;
|
||||||
}
|
|
||||||
|
|
||||||
private static class SingletonHolder {
|
|
||||||
private static final GsonHelper INSTANCE = new GsonHelper();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void writeJsonFile(JsonElement json, Path path) throws IOException {
|
public static void writeJsonFile(JsonElement json, Path path) throws IOException {
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ byte_buddy_version=1.17.5
|
|||||||
ahocorasick_version=0.6.3
|
ahocorasick_version=0.6.3
|
||||||
snake_yaml_version=2.5
|
snake_yaml_version=2.5
|
||||||
anti_grief_version=0.20
|
anti_grief_version=0.20
|
||||||
nms_helper_version=1.0.96
|
nms_helper_version=1.0.97
|
||||||
evalex_version=3.5.0
|
evalex_version=3.5.0
|
||||||
reactive_streams_version=1.0.4
|
reactive_streams_version=1.0.4
|
||||||
amazon_awssdk_version=2.33.1
|
amazon_awssdk_version=2.33.1
|
||||||
|
|||||||
Reference in New Issue
Block a user