mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-29 20:09:13 +00:00
方块实体2
This commit is contained in:
@@ -4,9 +4,11 @@ import net.momirealms.craftengine.core.block.BlockBehavior;
|
||||
import net.momirealms.craftengine.core.block.CustomBlock;
|
||||
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
||||
import net.momirealms.craftengine.core.block.behavior.AbstractBlockBehavior;
|
||||
import net.momirealms.craftengine.core.block.behavior.EntityBlockBehavior;
|
||||
import net.momirealms.craftengine.core.entity.player.InteractionResult;
|
||||
import net.momirealms.craftengine.core.item.context.BlockPlaceContext;
|
||||
import net.momirealms.craftengine.core.item.context.UseOnContext;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -31,6 +33,22 @@ public class UnsafeCompositeBlockBehavior extends BukkitBlockBehavior {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public EntityBlockBehavior getEntityBehavior() {
|
||||
EntityBlockBehavior target = null;
|
||||
for (AbstractBlockBehavior behavior : this.behaviors) {
|
||||
if (behavior instanceof EntityBlockBehavior entityBehavior) {
|
||||
if (target == null) {
|
||||
target = entityBehavior;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Multiple entity block behaviors are not allowed");
|
||||
}
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult useOnBlock(UseOnContext context, ImmutableBlockState state) {
|
||||
for (AbstractBlockBehavior behavior : this.behaviors) {
|
||||
|
||||
@@ -19,7 +19,6 @@ import net.momirealms.craftengine.bukkit.util.LocationUtils;
|
||||
import net.momirealms.craftengine.core.block.BlockStateWrapper;
|
||||
import net.momirealms.craftengine.core.block.EmptyBlock;
|
||||
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
||||
import net.momirealms.craftengine.core.block.UpdateOption;
|
||||
import net.momirealms.craftengine.core.block.entity.BlockEntity;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.config.Config;
|
||||
@@ -36,6 +35,7 @@ import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.function.Consumer;
|
||||
@@ -217,59 +217,84 @@ public final class WorldStorageInjector {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
private static void compareAndUpdateBlockState(int x, int y, int z, Object newState, Object previousState, InjectedHolder holder) {
|
||||
try {
|
||||
Optional<ImmutableBlockState> optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(newState);
|
||||
CESection section = holder.ceSection();
|
||||
// 如果是原版方块
|
||||
if (optionalCustomState.isEmpty()) {
|
||||
// 那么应该清空自定义块
|
||||
ImmutableBlockState previous = section.setBlockState(x, y, z, EmptyBlock.STATE);
|
||||
// 处理 自定义块 -> 原版块
|
||||
if (!previous.isEmpty()) {
|
||||
CEChunk chunk = holder.ceChunk();
|
||||
chunk.setDirty(true);
|
||||
if (previous.hasBlockEntity()) {
|
||||
BlockPos pos = new BlockPos(
|
||||
chunk.chunkPos().x * 16 + x,
|
||||
section.sectionY() * 16 + y,
|
||||
chunk.chunkPos().z * 16 + z
|
||||
);
|
||||
BlockEntity blockEntity = chunk.getBlockEntity(pos);
|
||||
if (blockEntity != null) {
|
||||
blockEntity.preRemove();
|
||||
chunk.removeBlockEntity(pos);
|
||||
}
|
||||
}
|
||||
if (Config.enableLightSystem()) {
|
||||
// 自定义块到原版块,只需要判断旧块是否和客户端一直
|
||||
BlockStateWrapper wrapper = previous.vanillaBlockState();
|
||||
if (wrapper != null) {
|
||||
updateLight(holder, wrapper.literalObject(), previousState, x, y, z);
|
||||
}
|
||||
Optional<ImmutableBlockState> optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(newState);
|
||||
CESection section = holder.ceSection();
|
||||
// 如果是原版方块
|
||||
if (optionalCustomState.isEmpty()) {
|
||||
// 那么应该清空自定义块
|
||||
ImmutableBlockState previous = section.setBlockState(x, y, z, EmptyBlock.STATE);
|
||||
// 处理 自定义块 -> 原版块
|
||||
if (!previous.isEmpty()) {
|
||||
CEChunk chunk = holder.ceChunk();
|
||||
chunk.setDirty(true);
|
||||
if (previous.hasBlockEntity()) {
|
||||
BlockPos pos = new BlockPos(chunk.chunkPos.x * 16 + x, section.sectionY * 16 + y, chunk.chunkPos.z * 16 + z);
|
||||
BlockEntity blockEntity = chunk.getBlockEntity(pos, false);
|
||||
if (blockEntity != null) {
|
||||
blockEntity.preRemove();
|
||||
chunk.removeBlockEntity(pos);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ImmutableBlockState immutableBlockState = optionalCustomState.get();
|
||||
ImmutableBlockState previousImmutableBlockState = section.setBlockState(x, y, z, immutableBlockState);
|
||||
if (previousImmutableBlockState == immutableBlockState) return;
|
||||
// 处理 自定义块到自定义块或原版块到自定义块
|
||||
holder.ceChunk().setDirty(true);
|
||||
// 不可能!绝对不可能!
|
||||
if (immutableBlockState.isEmpty()) return;
|
||||
// 如果新方块的光照属性和客户端认为的不同
|
||||
if (Config.enableLightSystem()) {
|
||||
if (previousImmutableBlockState.isEmpty()) {
|
||||
// 原版块到自定义块,只需要判断新块是否和客户端视觉一致
|
||||
updateLight(holder, immutableBlockState.vanillaBlockState().literalObject(), newState, x, y, z);
|
||||
} else {
|
||||
// 自定义块到自定义块
|
||||
updateLight$complex(holder, immutableBlockState.vanillaBlockState().literalObject(), newState, previousState, x, y, z);
|
||||
// 自定义块到原版块,只需要判断旧块是否和客户端一直
|
||||
BlockStateWrapper wrapper = previous.vanillaBlockState();
|
||||
if (wrapper != null) {
|
||||
updateLight(holder, wrapper.literalObject(), previousState, x, y, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
CraftEngine.instance().logger().warn("Failed to intercept setBlockState", e);
|
||||
} else {
|
||||
ImmutableBlockState newImmutableBlockState = optionalCustomState.get();
|
||||
ImmutableBlockState previousImmutableBlockState = section.setBlockState(x, y, z, newImmutableBlockState);
|
||||
if (previousImmutableBlockState == newImmutableBlockState) return;
|
||||
// 处理 自定义块到自定义块或原版块到自定义块
|
||||
CEChunk chunk = holder.ceChunk();
|
||||
chunk.setDirty(true);
|
||||
// 如果两个方块没有相同的主人 且 旧方块有方块实体
|
||||
if (!previousImmutableBlockState.isEmpty()) {
|
||||
if (previousImmutableBlockState.owner() != newImmutableBlockState.owner() && previousImmutableBlockState.hasBlockEntity()) {
|
||||
BlockPos pos = new BlockPos(chunk.chunkPos.x * 16 + x, section.sectionY * 16 + y, chunk.chunkPos.z * 16 + z);
|
||||
BlockEntity blockEntity = chunk.getBlockEntity(pos, false);
|
||||
if (blockEntity != null) {
|
||||
try {
|
||||
blockEntity.preRemove();
|
||||
} catch (Throwable t) {
|
||||
CraftEngine.instance().logger().warn("Error removing block entity " + blockEntity.getClass().getName(), t);
|
||||
}
|
||||
chunk.removeBlockEntity(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (newImmutableBlockState.hasBlockEntity()) {
|
||||
BlockPos pos = new BlockPos(chunk.chunkPos.x * 16 + x, section.sectionY * 16 + y, chunk.chunkPos.z * 16 + z);
|
||||
BlockEntity blockEntity = chunk.getBlockEntity(pos, false);
|
||||
if (blockEntity != null && !blockEntity.isValidBlockState(newImmutableBlockState)) {
|
||||
chunk.removeBlockEntity(pos);
|
||||
blockEntity = null;
|
||||
}
|
||||
if (blockEntity == null) {
|
||||
blockEntity = Objects.requireNonNull(newImmutableBlockState.behavior().getEntityBehavior()).createBlockEntity(pos, newImmutableBlockState);
|
||||
if (blockEntity != null) {
|
||||
chunk.addBlockEntity(blockEntity);
|
||||
}
|
||||
} else {
|
||||
blockEntity.setBlockState(newImmutableBlockState);
|
||||
// 方块类型未变,仅更新状态,选择性更新ticker
|
||||
chunk.replaceOrCreateTickingBlockEntity(blockEntity);
|
||||
}
|
||||
}
|
||||
// 如果新方块的光照属性和客户端认为的不同
|
||||
if (Config.enableLightSystem()) {
|
||||
if (previousImmutableBlockState.isEmpty()) {
|
||||
// 原版块到自定义块,只需要判断新块是否和客户端视觉一致
|
||||
updateLight(holder, newImmutableBlockState.vanillaBlockState().literalObject(), newState, x, y, z);
|
||||
} else {
|
||||
// 自定义块到自定义块
|
||||
updateLight$complex(holder, newImmutableBlockState.vanillaBlockState().literalObject(), newState, previousState, x, y, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package net.momirealms.craftengine.bukkit.util;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import org.bukkit.World;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user