mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-26 02:19:23 +00:00
重构挖掘
This commit is contained in:
@@ -148,6 +148,12 @@ block:
|
||||
# - Use `client-bound-item-data` to safely sync custom block data to clients.
|
||||
# Documentation: https://mo-mi.gitbook.io/xiaomomi-plugins/craftengine/plugin-wiki/craftengine/add-new-contents/items/item-data/client-bound-item-data
|
||||
simplify-adventure-break-check: false
|
||||
# Whether plugin should predict the next block to break
|
||||
# This can help improve mining experience to some extent
|
||||
predict-breaking:
|
||||
enable: true
|
||||
interval: 5
|
||||
extended-interaction-range: 0.5
|
||||
|
||||
furniture:
|
||||
# Automatically remove outdated furniture entities when a chunk is loaded.
|
||||
|
||||
@@ -661,7 +661,7 @@ templates#settings#blocks:
|
||||
- "default:sound/stone"
|
||||
- "default:pickaxe_power/level_{break_power}"
|
||||
overrides:
|
||||
hardness: 4.5
|
||||
hardness: 3.0
|
||||
resistance: 3.0
|
||||
push-reaction: NORMAL
|
||||
is-redstone-conductor: true
|
||||
@@ -677,7 +677,7 @@ templates#settings#blocks:
|
||||
- "default:sound/deepslate"
|
||||
- "default:pickaxe_power/level_{break_power}"
|
||||
overrides:
|
||||
hardness: 6.0
|
||||
hardness: 4.5
|
||||
resistance: 3.0
|
||||
push-reaction: NORMAL
|
||||
is-redstone-conductor: true
|
||||
|
||||
@@ -17,6 +17,7 @@ import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.context.ContextHolder;
|
||||
import net.momirealms.craftengine.core.world.Vec3d;
|
||||
import net.momirealms.craftengine.core.world.World;
|
||||
import net.momirealms.craftengine.core.world.WorldEvents;
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
@@ -183,7 +184,7 @@ public final class CraftEngineBlocks {
|
||||
world.playBlockSound(vec3d, state.sounds().breakSound());
|
||||
}
|
||||
if (sendParticles) {
|
||||
FastNMS.INSTANCE.method$Level$levelEvent(world.serverWorld(), 2001, LocationUtils.toBlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), state.customBlockState().registryId());
|
||||
FastNMS.INSTANCE.method$Level$levelEvent(world.serverWorld(), WorldEvents.BLOCK_BREAK_EFFECT, LocationUtils.toBlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), state.customBlockState().registryId());
|
||||
}
|
||||
block.setType(Material.AIR, applyPhysics);
|
||||
return true;
|
||||
|
||||
@@ -7,15 +7,14 @@ import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
||||
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
|
||||
import net.momirealms.craftengine.bukkit.util.*;
|
||||
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.properties.Property;
|
||||
import net.momirealms.craftengine.core.entity.player.InteractionHand;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemKeys;
|
||||
import net.momirealms.craftengine.core.loot.LootTable;
|
||||
import net.momirealms.craftengine.core.loot.parameter.LootParameters;
|
||||
import net.momirealms.craftengine.core.plugin.config.Config;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import net.momirealms.craftengine.core.util.context.ContextHolder;
|
||||
import net.momirealms.craftengine.core.world.BlockPos;
|
||||
@@ -38,7 +37,6 @@ 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;
|
||||
@@ -95,7 +93,7 @@ public class BlockEventListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) // I forget why it's LOW before
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||
public void onPlayerBreak(BlockBreakEvent event) {
|
||||
org.bukkit.block.Block block = event.getBlock();
|
||||
Object blockState = BlockStateUtils.blockDataToBlockState(block.getBlockData());
|
||||
@@ -106,9 +104,8 @@ public class BlockEventListener implements Listener {
|
||||
if (!state.isEmpty()) {
|
||||
Location location = block.getLocation();
|
||||
BukkitServerPlayer serverPlayer = this.plugin.adapt(player);
|
||||
// double check to prevent dupe
|
||||
// if simply adventure check, player would be survival mode for the moment
|
||||
if (serverPlayer.isAdventureMode() && !serverPlayer.canBreak(LocationUtils.toBlockPos(location))) {
|
||||
// double check adventure mode to prevent dupe
|
||||
if (!FastNMS.INSTANCE.mayBuild(serverPlayer.serverPlayer()) && !serverPlayer.canBreak(LocationUtils.toBlockPos(location))) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -133,15 +130,19 @@ public class BlockEventListener implements Listener {
|
||||
// play sound
|
||||
Vec3d vec3d = new Vec3d(location.getBlockX() + 0.5, location.getBlockY() + 0.5, location.getBlockZ() + 0.5);
|
||||
world.playBlockSound(vec3d, state.sounds().breakSound());
|
||||
if (player.getGameMode() == GameMode.CREATIVE) {
|
||||
if (player.getGameMode() == GameMode.CREATIVE || !customBreakEvent.dropItems()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Item<ItemStack> itemInHand = serverPlayer.getItemInHand(InteractionHand.MAIN_HAND);
|
||||
Key itemId = Optional.ofNullable(itemInHand).map(Item::id).orElse(ItemKeys.AIR);
|
||||
// do not drop if it's not the correct tool
|
||||
if (!state.settings().isCorrectTool(itemId) || !customBreakEvent.dropItems()) {
|
||||
return;
|
||||
BlockSettings settings = state.settings();
|
||||
if (settings.requireCorrectTool()) {
|
||||
if (itemInHand == null) return;
|
||||
if (!settings.isCorrectTool(itemInHand.id()) &&
|
||||
(!settings.respectToolComponent() || !FastNMS.INSTANCE.method$ItemStack$isCorrectToolForDrops(itemInHand.getLiteralObject(), state.customBlockState().handle()))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// drop items
|
||||
ContextHolder.Builder builder = ContextHolder.builder();
|
||||
|
||||
@@ -133,6 +133,7 @@ public class BukkitCustomBlock extends CustomBlock {
|
||||
if (settings.burnable()) {
|
||||
Reflections.method$FireBlock$setFlammable.invoke(Reflections.instance$Blocks$FIRE, mcBlock, settings.burnChance(), settings.fireSpreadChance());
|
||||
}
|
||||
Reflections.field$BlockStateBase$requiresCorrectToolForDrops.set(mcBlockState, settings.requireCorrectTool());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
CraftEngine.instance().logger().warn("Failed to init block settings", e);
|
||||
|
||||
@@ -19,6 +19,7 @@ import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import net.momirealms.craftengine.core.util.context.ContextHolder;
|
||||
import net.momirealms.craftengine.core.world.BlockPos;
|
||||
import net.momirealms.craftengine.core.world.Vec3d;
|
||||
import net.momirealms.craftengine.core.world.WorldEvents;
|
||||
import net.momirealms.craftengine.shared.block.BlockBehavior;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
@@ -76,7 +77,7 @@ public class BushBlockBehavior extends BukkitBlockBehavior {
|
||||
world.dropItemNaturally(vec3d, item);
|
||||
}
|
||||
world.playBlockSound(vec3d, previousState.sounds().breakSound());
|
||||
FastNMS.INSTANCE.method$Level$levelEvent(level, 2001, blockPos, stateId);
|
||||
FastNMS.INSTANCE.method$Level$levelEvent(level, WorldEvents.BLOCK_BREAK_EFFECT, blockPos, stateId);
|
||||
}
|
||||
return Reflections.method$Block$defaultBlockState.invoke(Reflections.instance$Blocks$AIR);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import net.momirealms.craftengine.core.util.context.ContextHolder;
|
||||
import net.momirealms.craftengine.core.world.BlockPos;
|
||||
import net.momirealms.craftengine.core.world.Vec3d;
|
||||
import net.momirealms.craftengine.core.world.WorldEvents;
|
||||
import net.momirealms.craftengine.shared.block.BlockBehavior;
|
||||
|
||||
import java.util.List;
|
||||
@@ -69,7 +70,7 @@ public class SugarCaneBlockBehavior extends BushBlockBehavior {
|
||||
world.dropItemNaturally(vec3d, item);
|
||||
}
|
||||
world.playBlockSound(vec3d, currentState.sounds().breakSound());
|
||||
FastNMS.INSTANCE.method$Level$levelEvent(level, 2001, blockPos, stateId);
|
||||
FastNMS.INSTANCE.method$Level$levelEvent(level, WorldEvents.BLOCK_BREAK_EFFECT, blockPos, stateId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import net.momirealms.craftengine.core.plugin.network.NetWorkUser;
|
||||
import net.momirealms.craftengine.core.plugin.network.NetworkManager;
|
||||
import net.momirealms.craftengine.core.util.*;
|
||||
import net.momirealms.craftengine.core.world.BlockPos;
|
||||
import net.momirealms.craftengine.core.world.WorldEvents;
|
||||
import net.momirealms.craftengine.core.world.chunk.Palette;
|
||||
import net.momirealms.craftengine.core.world.chunk.PalettedContainer;
|
||||
import net.momirealms.craftengine.core.world.chunk.packet.MCSection;
|
||||
@@ -221,7 +222,7 @@ public class PacketConsumers {
|
||||
try {
|
||||
FriendlyByteBuf buf = event.getBuffer();
|
||||
int eventId = buf.readInt();
|
||||
if (eventId != 2001) return;
|
||||
if (eventId != WorldEvents.BLOCK_BREAK_EFFECT) return;
|
||||
BlockPos blockPos = buf.readBlockPos(buf);
|
||||
int state = buf.readInt();
|
||||
boolean global = buf.readBoolean();
|
||||
@@ -1118,17 +1119,19 @@ public class PacketConsumers {
|
||||
if (Config.enableSoundSystem()) {
|
||||
Object blockOwner = Reflections.field$StateHolder$owner.get(blockState);
|
||||
if (BukkitBlockManager.instance().isBlockSoundRemoved(blockOwner)) {
|
||||
player.startMiningBlock(world, pos, blockState, false, null);
|
||||
player.startMiningBlock(pos, blockState, null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (player.isMiningBlock() || player.shouldSyncAttribute()) {
|
||||
if (player.isMiningBlock()) {
|
||||
player.stopMiningBlock();
|
||||
} else {
|
||||
player.setClientSideCanBreakBlock(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (player.isAdventureMode()) {
|
||||
if (Config.simplyAdventureCheck()) {
|
||||
if (Config.simplifyAdventureCheck()) {
|
||||
ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockStateUnsafe(stateId);
|
||||
if (!player.canBreak(pos, state.vanillaBlockState().handle())) {
|
||||
player.preventMiningBlock();
|
||||
@@ -1141,7 +1144,7 @@ public class PacketConsumers {
|
||||
}
|
||||
}
|
||||
}
|
||||
player.startMiningBlock(world, pos, blockState, true, BukkitBlockManager.instance().getImmutableBlockStateUnsafe(stateId));
|
||||
player.startMiningBlock(pos, blockState, BukkitBlockManager.instance().getImmutableBlockStateUnsafe(stateId));
|
||||
} else if (action == Reflections.instance$ServerboundPlayerActionPacket$Action$ABORT_DESTROY_BLOCK) {
|
||||
if (player.isMiningBlock()) {
|
||||
player.abortMiningBlock();
|
||||
|
||||
@@ -9,20 +9,21 @@ import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
||||
import net.momirealms.craftengine.bukkit.util.*;
|
||||
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.InteractionHand;
|
||||
import net.momirealms.craftengine.core.entity.player.Player;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemKeys;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.config.Config;
|
||||
import net.momirealms.craftengine.core.plugin.network.ConnectionState;
|
||||
import net.momirealms.craftengine.core.util.Direction;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
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.*;
|
||||
import net.momirealms.craftengine.core.world.WorldEvents;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
@@ -62,6 +63,7 @@ public class BukkitServerPlayer extends Player {
|
||||
private boolean swingHandAck;
|
||||
private float miningProgress;
|
||||
|
||||
private int lastSuccessfulBreak;
|
||||
private int resentSoundTick;
|
||||
private int resentSwingTick;
|
||||
|
||||
@@ -73,6 +75,8 @@ public class BukkitServerPlayer extends Player {
|
||||
private final Map<Integer, List<Integer>> furnitureView = new ConcurrentHashMap<>();
|
||||
private final Map<Integer, Object> entityTypeView = new ConcurrentHashMap<>();
|
||||
|
||||
private boolean clientSideCanBreak = true;
|
||||
|
||||
public BukkitServerPlayer(BukkitCraftEngine plugin, Channel channel) {
|
||||
this.channel = channel;
|
||||
this.plugin = plugin;
|
||||
@@ -108,8 +112,8 @@ public class BukkitServerPlayer extends Player {
|
||||
|
||||
@Override
|
||||
public boolean shouldSyncAttribute() {
|
||||
long current = System.currentTimeMillis();
|
||||
if (current - this.lastAttributeSyncTime > 10000) {
|
||||
long current = gameTicks();
|
||||
if (current - this.lastAttributeSyncTime > 100) {
|
||||
this.lastAttributeSyncTime = current;
|
||||
return true;
|
||||
}
|
||||
@@ -209,13 +213,7 @@ public class BukkitServerPlayer extends Player {
|
||||
|
||||
@Override
|
||||
public int gameTicks() {
|
||||
try {
|
||||
Object serverPlayer = serverPlayer();
|
||||
Object gameMode = Reflections.field$ServerPlayer$gameMode.get(serverPlayer);
|
||||
return (int) Reflections.field$ServerPlayerGameMode$gameTicks.get(gameMode);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException("Failed to get current tick", e);
|
||||
}
|
||||
return FastNMS.INSTANCE.field$MinecraftServer$currentTick();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -266,6 +264,11 @@ public class BukkitServerPlayer extends Player {
|
||||
this.plugin.networkManager().sendPacket(this, packet, immediately);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPackets(List<Object> packet, boolean immediately) {
|
||||
this.plugin.networkManager().sendPackets(this, packet, immediately);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receivePacket(Object packet) {
|
||||
this.plugin.networkManager().receivePacket(this, packet);
|
||||
@@ -319,45 +322,75 @@ public class BukkitServerPlayer extends Player {
|
||||
if (this.isDestroyingBlock) {
|
||||
this.tickBlockDestroy();
|
||||
}
|
||||
// if it's not destroying custom blocks, we do predict
|
||||
if (Config.predictBreaking()) {
|
||||
if (!this.isDestroyingCustomBlock && (gameTicks() + entityID()) % Config.predictBreakingInterval() == 0) {
|
||||
this.predictNextBlockToMine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getDestroyProgress(Object blockState, BlockPos pos) {
|
||||
try {
|
||||
Object serverPlayer = serverPlayer();
|
||||
Object blockPos = LocationUtils.toBlockPos(pos.x(), pos.y(), pos.z());
|
||||
return (float) Reflections.method$BlockStateBase$getDestroyProgress.invoke(blockState, serverPlayer, Reflections.method$Entity$level.invoke(serverPlayer), blockPos);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
this.plugin.logger().warn("Failed to get destroy progress for player " + platformPlayer().getName());
|
||||
return 0f;
|
||||
return FastNMS.INSTANCE.method$BlockStateBase$getDestroyProgress(blockState, serverPlayer(), FastNMS.INSTANCE.field$CraftWorld$ServerLevel(platformPlayer().getWorld()), LocationUtils.toBlockPos(pos));
|
||||
}
|
||||
|
||||
private void predictNextBlockToMine() {
|
||||
double range = getInteractionRange() + Config.extendedInteractionRange();
|
||||
RayTraceResult result = platformPlayer().rayTraceBlocks(range, FluidCollisionMode.NEVER);
|
||||
if (result == null) {
|
||||
if (!this.clientSideCanBreak) {
|
||||
setClientSideCanBreakBlock(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
Block hitBlock = result.getHitBlock();
|
||||
if (hitBlock == null) {
|
||||
if (!this.clientSideCanBreak) {
|
||||
setClientSideCanBreakBlock(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
int stateId = BlockStateUtils.blockDataToId(hitBlock.getBlockData());
|
||||
if (BlockStateUtils.isVanillaBlock(stateId)) {
|
||||
if (!this.clientSideCanBreak) {
|
||||
setClientSideCanBreakBlock(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (this.clientSideCanBreak) {
|
||||
setClientSideCanBreakBlock(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void startMiningBlock(org.bukkit.World world, BlockPos pos, Object state, boolean custom, @Nullable ImmutableBlockState immutableBlockState) {
|
||||
public void startMiningBlock(BlockPos pos, Object state, @Nullable ImmutableBlockState immutableBlockState) {
|
||||
// instant break
|
||||
boolean custom = immutableBlockState != null;
|
||||
if (custom && getDestroyProgress(state, pos) >= 1f) {
|
||||
assert immutableBlockState != null;
|
||||
// not an instant break on client side
|
||||
PackedBlockState vanillaBlockState = immutableBlockState.vanillaBlockState();
|
||||
// if it's not an instant break on client side, we should resend level event
|
||||
if (vanillaBlockState != null && getDestroyProgress(vanillaBlockState.handle(), pos) < 1f) {
|
||||
try {
|
||||
Object levelEventPacket = Reflections.constructor$ClientboundLevelEventPacket.newInstance(2001, LocationUtils.toBlockPos(pos), BlockStateUtils.blockStateToId(this.destroyedState), false);
|
||||
sendPacket(levelEventPacket, false);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
this.plugin.logger().warn("Failed to send level event packet", e);
|
||||
}
|
||||
Object levelEventPacket = FastNMS.INSTANCE.constructor$ClientboundLevelEventPacket(
|
||||
WorldEvents.BLOCK_BREAK_EFFECT, LocationUtils.toBlockPos(pos), BlockStateUtils.blockStateToId(this.destroyedState), false);
|
||||
sendPacket(levelEventPacket, false);
|
||||
}
|
||||
//ParticleUtils.addBlockBreakParticles(world, LocationUtils.toBlockPos(pos), state);
|
||||
return;
|
||||
}
|
||||
setCanBreakBlock(!custom);
|
||||
// if it's a custom one, we prevent it, otherwise we allow it
|
||||
setClientSideCanBreakBlock(!custom);
|
||||
// set some base info
|
||||
setDestroyPos(pos);
|
||||
setDestroyedState(state);
|
||||
setIsDestroyingBlock(true, custom);
|
||||
}
|
||||
|
||||
private void setCanBreakBlock(boolean canBreak) {
|
||||
@Override
|
||||
public void setClientSideCanBreakBlock(boolean canBreak) {
|
||||
try {
|
||||
if (this.clientSideCanBreak == canBreak && !shouldSyncAttribute()) {
|
||||
return;
|
||||
}
|
||||
this.clientSideCanBreak = canBreak;
|
||||
if (canBreak) {
|
||||
if (VersionHelper.isVersionNewerThan1_20_5()) {
|
||||
Object serverPlayer = serverPlayer();
|
||||
@@ -379,8 +412,7 @@ public class BukkitServerPlayer extends Player {
|
||||
} else {
|
||||
Object fatiguePacket = MobEffectUtils.createPacket(Reflections.instance$MobEffecr$mining_fatigue, entityID(), (byte) 9, -1, false, false, false);
|
||||
Object hastePacket = MobEffectUtils.createPacket(Reflections.instance$MobEffecr$haste, entityID(), (byte) 0, -1, false, false, false);
|
||||
sendPacket(fatiguePacket, true);
|
||||
sendPacket(hastePacket, true);
|
||||
sendPackets(List.of(fatiguePacket, hastePacket), true);
|
||||
}
|
||||
}
|
||||
} catch (ReflectiveOperationException e) {
|
||||
@@ -390,17 +422,26 @@ public class BukkitServerPlayer extends Player {
|
||||
|
||||
@Override
|
||||
public void stopMiningBlock() {
|
||||
setCanBreakBlock(true);
|
||||
setClientSideCanBreakBlock(true);
|
||||
setIsDestroyingBlock(false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preventMiningBlock() {
|
||||
setCanBreakBlock(false);
|
||||
setClientSideCanBreakBlock(false);
|
||||
setIsDestroyingBlock(false, false);
|
||||
abortMiningBlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void abortMiningBlock() {
|
||||
this.swingHandAck = false;
|
||||
this.miningProgress = 0;
|
||||
if (this.destroyPos != null) {
|
||||
this.broadcastDestroyProgress(platformPlayer(), this.destroyPos, LocationUtils.toBlockPos(this.destroyPos), -1);
|
||||
}
|
||||
}
|
||||
|
||||
private void resetEffect(Object mobEffect) throws ReflectiveOperationException {
|
||||
Object effectInstance = Reflections.method$ServerPlayer$getEffect.invoke(serverPlayer(), mobEffect);
|
||||
Object packet;
|
||||
@@ -412,24 +453,13 @@ public class BukkitServerPlayer extends Player {
|
||||
sendPacket(packet, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void abortMiningBlock() {
|
||||
abortDestroyProgress();
|
||||
}
|
||||
|
||||
private void tickBlockDestroy() {
|
||||
// prevent server from taking over breaking blocks
|
||||
if (this.isDestroyingCustomBlock) {
|
||||
try {
|
||||
Object serverPlayer = serverPlayer();
|
||||
Object gameMode = Reflections.field$ServerPlayer$gameMode.get(serverPlayer);
|
||||
Reflections.field$ServerPlayerGameMode$isDestroyingBlock.set(gameMode, false);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
// if player swings hand is this tick
|
||||
if (!this.swingHandAck) return;
|
||||
this.swingHandAck = false;
|
||||
int currentTick = gameTicks();
|
||||
// optimize break speed, otherwise it would be too fast
|
||||
if (currentTick - this.lastSuccessfulBreak <= 5) return;
|
||||
try {
|
||||
org.bukkit.entity.Player player = platformPlayer();
|
||||
double range = getInteractionRange();
|
||||
@@ -444,8 +474,8 @@ public class BukkitServerPlayer extends Player {
|
||||
}
|
||||
Object blockPos = LocationUtils.toBlockPos(hitPos);
|
||||
Object serverPlayer = serverPlayer();
|
||||
Object gameMode = Reflections.field$ServerPlayer$gameMode.get(serverPlayer);
|
||||
int currentTick = (int) Reflections.field$ServerPlayerGameMode$gameTicks.get(gameMode);
|
||||
|
||||
// send hit sound if the sound is removed
|
||||
if (currentTick - this.lastHitBlockTime > 3) {
|
||||
Object blockOwner = Reflections.field$StateHolder$owner.get(this.destroyedState);
|
||||
Object soundType = Reflections.field$BlockBehaviour$soundType.get(blockOwner);
|
||||
@@ -457,9 +487,14 @@ public class BukkitServerPlayer extends Player {
|
||||
|
||||
// accumulate progress (custom blocks only)
|
||||
if (this.isDestroyingCustomBlock) {
|
||||
// prevent server from taking over breaking custom blocks
|
||||
Object gameMode = FastNMS.INSTANCE.field$ServerPlayer$gameMode(serverPlayer);
|
||||
Reflections.field$ServerPlayerGameMode$isDestroyingBlock.set(gameMode, false);
|
||||
// check item in hand
|
||||
Item<ItemStack> item = this.getItemInHand(InteractionHand.MAIN_HAND);
|
||||
if (item != null) {
|
||||
Material itemMaterial = item.getItem().getType();
|
||||
// creative mode + invalid item in hand
|
||||
if (canInstabuild() && (itemMaterial == Material.DEBUG_STICK
|
||||
|| itemMaterial == Material.TRIDENT
|
||||
|| (VersionHelper.isVersionNewerThan1_20_5() && itemMaterial == MaterialUtils.MACE)
|
||||
@@ -468,37 +503,65 @@ public class BukkitServerPlayer extends Player {
|
||||
}
|
||||
}
|
||||
|
||||
float progressToAdd = (float) Reflections.method$BlockStateBase$getDestroyProgress.invoke(this.destroyedState, serverPlayer, Reflections.method$Entity$level.invoke(serverPlayer), blockPos);
|
||||
float progressToAdd = getDestroyProgress(this.destroyedState, hitPos);
|
||||
int id = BlockStateUtils.blockStateToId(this.destroyedState);
|
||||
ImmutableBlockState customState = BukkitBlockManager.instance().getImmutableBlockState(id);
|
||||
// double check custom block
|
||||
if (customState != null && !customState.isEmpty()) {
|
||||
if (!customState.settings().isCorrectTool(item == null ? ItemKeys.AIR : item.id())) {
|
||||
progressToAdd *= customState.settings().incorrectToolSpeed();
|
||||
BlockSettings blockSettings = customState.settings();
|
||||
if (blockSettings.requireCorrectTool()) {
|
||||
if (item != null) {
|
||||
// it's correct on plugin side
|
||||
if (blockSettings.isCorrectTool(item.id())) {
|
||||
// but not on serverside
|
||||
if (!FastNMS.INSTANCE.method$ItemStack$isCorrectToolForDrops(item.getLiteralObject(), this.destroyedState)) {
|
||||
// we fix the speed
|
||||
progressToAdd = progressToAdd * (10f / 3f);
|
||||
}
|
||||
} else {
|
||||
// not a correct tool on plugin side and not a correct tool on serverside
|
||||
if (!blockSettings.respectToolComponent() || !FastNMS.INSTANCE.method$ItemStack$isCorrectToolForDrops(item.getLiteralObject(), this.destroyedState)) {
|
||||
progressToAdd = progressToAdd * (10f / 3f) * blockSettings.incorrectToolSpeed();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// item is null, but it requires correct tool, then we reset the speed
|
||||
progressToAdd = progressToAdd * (10f / 3f) * blockSettings.incorrectToolSpeed();
|
||||
}
|
||||
}
|
||||
|
||||
// accumulate progress
|
||||
this.miningProgress = progressToAdd + miningProgress;
|
||||
int packetStage = (int) (this.miningProgress * 10.0F);
|
||||
if (packetStage != this.lastSentState) {
|
||||
this.lastSentState = packetStage;
|
||||
// broadcast changes
|
||||
broadcastDestroyProgress(player, hitPos, blockPos, packetStage);
|
||||
}
|
||||
|
||||
// can break now
|
||||
if (this.miningProgress >= 1f) {
|
||||
if (isAdventureMode() && Config.simplyAdventureCheck()) {
|
||||
// for simplified adventure break, switch mayBuild temporarily
|
||||
if (isAdventureMode() && Config.simplifyAdventureCheck()) {
|
||||
// check the appearance state
|
||||
if (canBreak(hitPos, customState.vanillaBlockState().handle())) {
|
||||
player.setGameMode(GameMode.SURVIVAL);
|
||||
// Error might occur so we use try here
|
||||
try {
|
||||
FastNMS.INSTANCE.setMayBuild(serverPlayer, true);
|
||||
Reflections.method$ServerPlayerGameMode$destroyBlock.invoke(gameMode, blockPos);
|
||||
} finally {
|
||||
player.setGameMode(GameMode.ADVENTURE);
|
||||
FastNMS.INSTANCE.setMayBuild(serverPlayer, false);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// normal break check
|
||||
Reflections.method$ServerPlayerGameMode$destroyBlock.invoke(gameMode, blockPos);
|
||||
}
|
||||
Object levelEventPacket = Reflections.constructor$ClientboundLevelEventPacket.newInstance(2001, blockPos, id, false);
|
||||
sendPacket(levelEventPacket, false);
|
||||
this.stopMiningBlock();
|
||||
// send break particle + (removed sounds)
|
||||
sendPacket(FastNMS.INSTANCE.constructor$ClientboundLevelEventPacket(WorldEvents.BLOCK_BREAK_EFFECT, blockPos, id, false), false);
|
||||
this.lastSuccessfulBreak = currentTick;
|
||||
this.destroyPos = null;
|
||||
this.setIsDestroyingBlock(false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -507,8 +570,8 @@ public class BukkitServerPlayer extends Player {
|
||||
}
|
||||
}
|
||||
|
||||
private void broadcastDestroyProgress(org.bukkit.entity.Player player, BlockPos hitPos, Object blockPos, int stage) throws ReflectiveOperationException {
|
||||
Object packet = Reflections.constructor$ClientboundBlockDestructionPacket.newInstance(Integer.MAX_VALUE - entityID(), blockPos, stage);
|
||||
private void broadcastDestroyProgress(org.bukkit.entity.Player player, BlockPos hitPos, Object blockPos, int stage) {
|
||||
Object packet = FastNMS.INSTANCE.constructor$ClientboundBlockDestructionPacket(Integer.MAX_VALUE - entityID(), blockPos, stage);
|
||||
for (org.bukkit.entity.Player other : player.getWorld().getPlayers()) {
|
||||
Location otherLocation = other.getLocation();
|
||||
double d0 = (double) hitPos.x() - otherLocation.getX();
|
||||
@@ -522,52 +585,22 @@ public class BukkitServerPlayer extends Player {
|
||||
|
||||
@Override
|
||||
public double getInteractionRange() {
|
||||
try {
|
||||
if (VersionHelper.isVersionNewerThan1_20_5()) {
|
||||
Object attributeInstance = Reflections.method$ServerPlayer$getAttribute.invoke(serverPlayer(), Reflections.instance$Holder$Attribute$block_interaction_range);
|
||||
if (attributeInstance == null) return 4.5d;
|
||||
return (double) Reflections.method$AttributeInstance$getValue.invoke(attributeInstance);
|
||||
} else {
|
||||
return 4.5d;
|
||||
}
|
||||
} catch (ReflectiveOperationException e) {
|
||||
plugin.logger().warn("Failed to get interaction range for player " + platformPlayer().getName(), e);
|
||||
return 4.5d;
|
||||
}
|
||||
return FastNMS.INSTANCE.getInteractionRange(serverPlayer());
|
||||
}
|
||||
|
||||
public void setIsDestroyingBlock(boolean value, boolean custom) {
|
||||
if (value) {
|
||||
this.isDestroyingBlock = true;
|
||||
this.isDestroyingCustomBlock = custom;
|
||||
this.swingHandAck = true;
|
||||
this.miningProgress = 0;
|
||||
} else {
|
||||
this.isDestroyingBlock = false;
|
||||
this.swingHandAck = false;
|
||||
if (this.destroyPos != null) {
|
||||
try {
|
||||
this.broadcastDestroyProgress(platformPlayer(), this.destroyPos, LocationUtils.toBlockPos(this.destroyPos), -1);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
plugin.logger().warn("Failed to set isDestroyingCustomBlock", e);
|
||||
}
|
||||
}
|
||||
this.destroyPos = null;
|
||||
this.miningProgress = 0;
|
||||
this.destroyedState = null;
|
||||
this.isDestroyingCustomBlock = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void abortDestroyProgress() {
|
||||
this.swingHandAck = false;
|
||||
public void setIsDestroyingBlock(boolean is, boolean custom) {
|
||||
this.miningProgress = 0;
|
||||
if (this.destroyPos == null) return;
|
||||
try {
|
||||
this.broadcastDestroyProgress(platformPlayer(), this.destroyPos, LocationUtils.toBlockPos(this.destroyPos), -1);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
plugin.logger().warn("Failed to abort destroyProgress", e);
|
||||
this.isDestroyingBlock = is;
|
||||
this.isDestroyingCustomBlock = custom && is;
|
||||
if (is) {
|
||||
this.swingHandAck = true;
|
||||
} else {
|
||||
this.swingHandAck = false;
|
||||
this.destroyedState = null;
|
||||
if (this.destroyPos != null) {
|
||||
this.broadcastDestroyProgress(platformPlayer(), this.destroyPos, LocationUtils.toBlockPos(this.destroyPos), -1);
|
||||
this.destroyPos = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2418,6 +2418,12 @@ public class Reflections {
|
||||
)
|
||||
);
|
||||
|
||||
public static final Field field$BlockStateBase$requiresCorrectToolForDrops = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(
|
||||
clazz$BlockStateBase, boolean.class, 5
|
||||
)
|
||||
);
|
||||
|
||||
public static final Field field$BlockStateBase$canOcclude = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(
|
||||
clazz$BlockStateBase, boolean.class, 6
|
||||
@@ -2925,11 +2931,11 @@ public class Reflections {
|
||||
)
|
||||
);
|
||||
|
||||
public static final Field field$ServerPlayer$gameMode = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(
|
||||
clazz$ServerPlayer, clazz$ServerPlayerGameMode, 0
|
||||
)
|
||||
);
|
||||
// public static final Field field$ServerPlayer$gameMode = requireNonNull(
|
||||
// ReflectionUtils.getDeclaredField(
|
||||
// clazz$ServerPlayer, clazz$ServerPlayerGameMode, 0
|
||||
// )
|
||||
// );
|
||||
|
||||
public static final Field field$ServerPlayerGameMode$destroyProgressStart = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(
|
||||
@@ -2937,11 +2943,11 @@ public class Reflections {
|
||||
)
|
||||
);
|
||||
|
||||
public static final Field field$ServerPlayerGameMode$gameTicks = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(
|
||||
clazz$ServerPlayerGameMode, int.class, 1
|
||||
)
|
||||
);
|
||||
// public static final Field field$ServerPlayerGameMode$gameTicks = requireNonNull(
|
||||
// ReflectionUtils.getDeclaredField(
|
||||
// clazz$ServerPlayerGameMode, int.class, 1
|
||||
// )
|
||||
// );
|
||||
|
||||
public static final Field field$ServerPlayerGameMode$delayedTickStart = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(
|
||||
@@ -3009,11 +3015,11 @@ public class Reflections {
|
||||
)
|
||||
);
|
||||
|
||||
public static final Method method$BlockStateBase$getDestroyProgress = requireNonNull(
|
||||
ReflectionUtils.getDeclaredMethod(
|
||||
clazz$BlockStateBase, float.class, clazz$Player, clazz$BlockGetter, clazz$BlockPos
|
||||
)
|
||||
);
|
||||
// public static final Method method$BlockStateBase$getDestroyProgress = requireNonNull(
|
||||
// ReflectionUtils.getDeclaredMethod(
|
||||
// clazz$BlockStateBase, float.class, clazz$Player, clazz$BlockGetter, clazz$BlockPos
|
||||
// )
|
||||
// );
|
||||
|
||||
public static final Class<?> clazz$ClientboundBlockDestructionPacket = requireNonNull(
|
||||
ReflectionUtils.getClazz(
|
||||
@@ -3022,11 +3028,11 @@ public class Reflections {
|
||||
)
|
||||
);
|
||||
|
||||
public static final Constructor<?> constructor$ClientboundBlockDestructionPacket = requireNonNull(
|
||||
ReflectionUtils.getConstructor(
|
||||
clazz$ClientboundBlockDestructionPacket, int.class, clazz$BlockPos, int.class
|
||||
)
|
||||
);
|
||||
// public static final Constructor<?> constructor$ClientboundBlockDestructionPacket = requireNonNull(
|
||||
// ReflectionUtils.getConstructor(
|
||||
// clazz$ClientboundBlockDestructionPacket, int.class, clazz$BlockPos, int.class
|
||||
// )
|
||||
// );
|
||||
|
||||
public static final Class<?> clazz$ServerboundSwingPacket = requireNonNull(
|
||||
ReflectionUtils.getClazz(
|
||||
@@ -4955,11 +4961,11 @@ public class Reflections {
|
||||
)
|
||||
);
|
||||
|
||||
public static final Constructor<?> constructor$ClientboundLevelEventPacket = requireNonNull(
|
||||
ReflectionUtils.getConstructor(
|
||||
clazz$ClientboundLevelEventPacket, int.class, clazz$BlockPos, int.class, boolean.class
|
||||
)
|
||||
);
|
||||
// public static final Constructor<?> constructor$ClientboundLevelEventPacket = requireNonNull(
|
||||
// ReflectionUtils.getConstructor(
|
||||
// clazz$ClientboundLevelEventPacket, int.class, clazz$BlockPos, int.class, boolean.class
|
||||
// )
|
||||
// );
|
||||
|
||||
public static final Field field$ClientboundLevelEventPacket$eventId = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(
|
||||
|
||||
@@ -17,6 +17,8 @@ public class BlockSettings {
|
||||
float resistance = 2f;
|
||||
boolean canOcclude;
|
||||
boolean fluidState;
|
||||
boolean requireCorrectTools;
|
||||
boolean respectToolComponent;
|
||||
Tristate isRedstoneConductor = Tristate.UNDEFINED;
|
||||
Tristate isSuffocating = Tristate.UNDEFINED;
|
||||
Tristate isViewBlocking = Tristate.UNDEFINED;
|
||||
@@ -74,6 +76,8 @@ public class BlockSettings {
|
||||
newSettings.itemId = settings.itemId;
|
||||
newSettings.tags = settings.tags;
|
||||
newSettings.burnChance = settings.burnChance;
|
||||
newSettings.requireCorrectTools = settings.requireCorrectTools;
|
||||
newSettings.respectToolComponent = settings.respectToolComponent;
|
||||
newSettings.fireSpreadChance = settings.fireSpreadChance;
|
||||
newSettings.isRedstoneConductor = settings.isRedstoneConductor;
|
||||
newSettings.isSuffocating = settings.isSuffocating;
|
||||
@@ -130,6 +134,10 @@ public class BlockSettings {
|
||||
return incorrectToolSpeed;
|
||||
}
|
||||
|
||||
public boolean requireCorrectTool() {
|
||||
return requireCorrectTools || !correctTools.isEmpty();
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
@@ -175,10 +183,13 @@ public class BlockSettings {
|
||||
}
|
||||
|
||||
public boolean isCorrectTool(Key key) {
|
||||
if (this.correctTools.isEmpty()) return true;
|
||||
return this.correctTools.contains(key);
|
||||
}
|
||||
|
||||
public boolean respectToolComponent() {
|
||||
return respectToolComponent;
|
||||
}
|
||||
|
||||
public BlockSettings correctTools(Set<Key> correctTools) {
|
||||
this.correctTools = correctTools;
|
||||
return this;
|
||||
@@ -249,6 +260,16 @@ public class BlockSettings {
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockSettings requireCorrectTool(boolean requireCorrectTool) {
|
||||
this.requireCorrectTools = requireCorrectTool;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockSettings respectToolComponent(boolean respectToolComponent) {
|
||||
this.respectToolComponent = respectToolComponent;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockSettings incorrectToolSpeed(float incorrectToolSpeed) {
|
||||
this.incorrectToolSpeed = incorrectToolSpeed;
|
||||
return this;
|
||||
@@ -392,6 +413,14 @@ public class BlockSettings {
|
||||
List<String> tools = MiscUtils.getAsStringList(value);
|
||||
return settings -> settings.correctTools(tools.stream().map(Key::of).collect(Collectors.toSet()));
|
||||
}));
|
||||
registerFactory("require-correct-tools", (value -> {
|
||||
boolean booleanValue = (boolean) value;
|
||||
return settings -> settings.requireCorrectTool(booleanValue);
|
||||
}));
|
||||
registerFactory("respect-tool-component", (value -> {
|
||||
boolean booleanValue = (boolean) value;
|
||||
return settings -> settings.respectToolComponent(booleanValue);
|
||||
}));
|
||||
registerFactory("incorrect-tool-dig-speed", (value -> {
|
||||
float floatValue = MiscUtils.getAsFloat(value);
|
||||
return settings -> settings.incorrectToolSpeed(floatValue);
|
||||
|
||||
@@ -5,11 +5,11 @@ import net.momirealms.craftengine.core.entity.Entity;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.plugin.network.NetWorkUser;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.world.BlockHitResult;
|
||||
import net.momirealms.craftengine.core.world.BlockPos;
|
||||
import net.momirealms.craftengine.core.world.FluidCollisionRule;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class Player extends Entity implements NetWorkUser {
|
||||
|
||||
public abstract boolean isSecondaryUseActive();
|
||||
@@ -23,8 +23,12 @@ public abstract class Player extends Entity implements NetWorkUser {
|
||||
@Override
|
||||
public abstract Object serverPlayer();
|
||||
|
||||
public abstract void sendPackets(List<Object> packet, boolean immediately);
|
||||
|
||||
public abstract float getDestroyProgress(Object blockState, BlockPos pos);
|
||||
|
||||
public abstract void setClientSideCanBreakBlock(boolean canBreak);
|
||||
|
||||
public abstract void stopMiningBlock();
|
||||
|
||||
public abstract void preventMiningBlock();
|
||||
@@ -33,8 +37,6 @@ public abstract class Player extends Entity implements NetWorkUser {
|
||||
|
||||
public abstract double getInteractionRange();
|
||||
|
||||
public abstract void abortDestroyProgress();
|
||||
|
||||
public abstract void onSwingHand();
|
||||
|
||||
public abstract boolean isMiningBlock();
|
||||
|
||||
@@ -111,7 +111,10 @@ public class Config {
|
||||
protected boolean furniture$hide_base_entity;
|
||||
|
||||
protected boolean block$sound_system$enable;
|
||||
protected boolean block$simply_adventure_break_check;
|
||||
protected boolean block$simplify_adventure_break_check;
|
||||
protected boolean block$predict_breaking;
|
||||
protected int block$predict_breaking_interval;
|
||||
protected double block$extended_interaction_range;
|
||||
|
||||
protected boolean recipe$enable;
|
||||
protected boolean recipe$disable_vanilla_recipes$all;
|
||||
@@ -282,7 +285,10 @@ public class Config {
|
||||
|
||||
// block
|
||||
block$sound_system$enable = config.getBoolean("block.sound-system.enable", true);
|
||||
block$simply_adventure_break_check = config.getBoolean("block.simplify-adventure-break-check", true);
|
||||
block$simplify_adventure_break_check = config.getBoolean("block.simplify-adventure-break-check", false);
|
||||
block$predict_breaking = config.getBoolean("block.predict-breaking.enable", true);
|
||||
block$predict_breaking_interval = Math.max(config.getInt("block.predict-breaking.interval", 10), 1);
|
||||
block$extended_interaction_range = Math.max(config.getDouble("block.predict-breaking.extended-interaction-range", 0.5), 0.0);
|
||||
|
||||
// recipe
|
||||
recipe$enable = config.getBoolean("recipe.enable", true);
|
||||
@@ -392,8 +398,8 @@ public class Config {
|
||||
return instance.block$sound_system$enable;
|
||||
}
|
||||
|
||||
public static boolean simplyAdventureCheck() {
|
||||
return instance.block$simply_adventure_break_check;
|
||||
public static boolean simplifyAdventureCheck() {
|
||||
return instance.block$simplify_adventure_break_check;
|
||||
}
|
||||
|
||||
public static boolean enableRecipeSystem() {
|
||||
@@ -668,6 +674,18 @@ public class Config {
|
||||
return instance.image$intercept_packets$set_score;
|
||||
}
|
||||
|
||||
public static boolean predictBreaking() {
|
||||
return instance.block$predict_breaking;
|
||||
}
|
||||
|
||||
public static int predictBreakingInterval() {
|
||||
return instance.block$predict_breaking_interval;
|
||||
}
|
||||
|
||||
public static double extendedInteractionRange() {
|
||||
return instance.block$extended_interaction_range;
|
||||
}
|
||||
|
||||
public YamlDocument loadOrCreateYamlData(String fileName) {
|
||||
File file = new File(this.plugin.dataFolderFile(), fileName);
|
||||
if (!file.exists()) {
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
package net.momirealms.craftengine.core.world;
|
||||
|
||||
public class WorldEvents {
|
||||
public static final int DISPENSER_DISPENSES = 1000;
|
||||
public static final int DISPENSER_FAILS_TO_DISPENSE = 1001;
|
||||
public static final int DISPENSER_SHOOTS = 1002;
|
||||
public static final int FIREWORK_SHOT = 1004;
|
||||
public static final int FIRE_EXTINGUISHED = 1009;
|
||||
public static final int PLAY_RECORD = 1010;
|
||||
public static final int STOP_RECORD = 1011;
|
||||
public static final int GHAST_WARNS = 1015;
|
||||
public static final int GHAST_SHOOTS = 1016;
|
||||
public static final int ENDER_DRAGON_SHOOTS = 1017;
|
||||
public static final int BLAZE_SHOOTS = 1018;
|
||||
public static final int ZOMBIE_ATTACKS_WOODEN_DOOR = 1019;
|
||||
public static final int ZOMBIE_ATTACKS_IRON_DOOR = 1020;
|
||||
public static final int ZOMBIE_BREAKS_WOODEN_DOOR = 1021;
|
||||
public static final int WITHER_BREAKS_BLOCK = 1022;
|
||||
public static final int WITHER_SPAWNED = 1023;
|
||||
public static final int WITHER_SHOOTS = 1024;
|
||||
public static final int BAT_TAKES_OFF = 1025;
|
||||
public static final int ZOMBIE_INFECTS = 1026;
|
||||
public static final int ZOMBIE_VILLAGER_CONVERTED = 1027;
|
||||
public static final int ENDER_DRAGON_DIES = 1028;
|
||||
public static final int ANVIL_DESTROYED = 1029;
|
||||
public static final int ANVIL_USED = 1030;
|
||||
public static final int ANVIL_LANDS = 1031;
|
||||
public static final int PORTAL_TRAVEL = 1032;
|
||||
public static final int CHORUS_FLOWER_GROWS = 1033;
|
||||
public static final int CHORUS_FLOWER_DIES = 1034;
|
||||
public static final int BREWING_STAND_BREWS = 1035;
|
||||
public static final int END_PORTAL_CREATED = 1038;
|
||||
public static final int PHANTOM_BITES = 1039;
|
||||
public static final int ZOMBIE_CONVERTS_TO_DROWNED = 1040;
|
||||
public static final int HUSK_CONVERTS_TO_ZOMBIE_BY_DROWNING = 1041;
|
||||
public static final int GRINDSTONE_USED = 1042;
|
||||
public static final int BOOK_PAGE_TURNED = 1043;
|
||||
public static final int SMITHING_TABLE_USED = 1044;
|
||||
public static final int POINTED_DRIPSTONE_LANDING = 1045;
|
||||
public static final int LAVA_DRIPPING_ON_CAULDRON_FROM_DRIPSTONE = 1046;
|
||||
public static final int WATER_DRIPPING_ON_CAULDRON_FROM_DRIPSTONE = 1047;
|
||||
public static final int SKELETON_CONVERTS_TO_STRAY = 1048;
|
||||
public static final int CRAFTER_SUCCESSFULLY_CRAFTS_ITEM = 1049;
|
||||
public static final int CRAFTER_FAILS_TO_CRAFT_ITEM = 1050;
|
||||
public static final int COMPOSTER_COMPOSTS = 1500;
|
||||
public static final int LAVA_CONVERTS_BLOCK = 1501;
|
||||
public static final int REDSTONE_TORCH_BURNS_OUT = 1502;
|
||||
public static final int ENDER_EYE_PLACED_IN_END_PORTAL_FRAME = 1503;
|
||||
public static final int FLUID_DRIPS_FROM_DRIPSTONE = 1504;
|
||||
public static final int BONE_MEAL_PARTICLES_AND_SOUND = 1505;
|
||||
public static final int DISPENSER_ACTIVATION_SMOKE = 2000;
|
||||
public static final int BLOCK_BREAK_EFFECT = 2001;
|
||||
public static final int SPLASH_POTION_EFFECT = 2002;
|
||||
public static final int ENDER_EYE_ENTITY_BREAK_ANIMATION = 2003;
|
||||
public static final int SPAWNER_SPAWNS_MOB = 2004;
|
||||
public static final int DRAGON_BREATH = 2006;
|
||||
public static final int INSTANT_SPLASH_POTION = 2007;
|
||||
public static final int ENDER_DRAGON_DESTROYS_BLOCK = 2008;
|
||||
public static final int WET_SPONGE_VAPORIZES = 2009;
|
||||
public static final int CRAFTER_ACTIVATION_SMOKE = 2010;
|
||||
public static final int BEE_FERTILIZES_PLANT = 2011;
|
||||
public static final int TURTLE_EGG_PLACED = 2012;
|
||||
public static final int SMASH_ATTACK = 2013;
|
||||
public static final int END_GATEWAY_SPAWNS = 3000;
|
||||
public static final int ENDER_DRAGON_RESURRECTED = 3001;
|
||||
public static final int ELECTRIC_SPARK = 3002;
|
||||
public static final int COPPER_APPLY_WAX = 3003;
|
||||
public static final int COPPER_REMOVE_WAX = 3004;
|
||||
public static final int COPPER_SCRAPE_OXIDATION = 3005;
|
||||
public static final int SCULK_CHARGE = 3006;
|
||||
public static final int SCULK_SHRIEKER_SHRIEK = 3007;
|
||||
public static final int BLOCK_FINISHED_BRUSHING = 3008;
|
||||
public static final int SNIFFER_EGG_CRACKS = 3009;
|
||||
public static final int TRIAL_SPAWNER_SPAWNS_MOB_AT_SPAWNER = 3011;
|
||||
public static final int TRIAL_SPAWNER_SPAWNS_MOB_AT_LOCATION = 3012;
|
||||
public static final int TRIAL_SPAWNER_DETECTS_PLAYER = 3013;
|
||||
public static final int TRIAL_SPAWNER_EJECTS_ITEM = 3014;
|
||||
public static final int VAULT_ACTIVATES = 3015;
|
||||
public static final int VAULT_DEACTIVATES = 3016;
|
||||
public static final int VAULT_EJECTS_ITEM = 3017;
|
||||
public static final int COBWEB_WEAVED = 3018;
|
||||
public static final int OMINOUS_TRIAL_SPAWNER_DETECTS_PLAYER = 3019;
|
||||
public static final int TRIAL_SPAWNER_TURNS_OMINOUS = 3020;
|
||||
public static final int OMINOUS_ITEM_SPAWNER_SPAWNS_ITEM = 3021;
|
||||
|
||||
private WorldEvents() {}
|
||||
}
|
||||
@@ -51,7 +51,7 @@ byte_buddy_version=1.17.5
|
||||
ahocorasick_version=0.6.3
|
||||
snake_yaml_version=2.4
|
||||
anti_grief_version=0.13
|
||||
nms_helper_version=0.58.1
|
||||
nms_helper_version=0.58.7
|
||||
# Ignite Dependencies
|
||||
mixinextras_version=0.4.1
|
||||
mixin_version=0.15.2+mixin.0.8.7
|
||||
|
||||
Reference in New Issue
Block a user