mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-25 18:09:27 +00:00
门,完结
This commit is contained in:
@@ -23,6 +23,7 @@ import net.momirealms.craftengine.core.item.context.BlockPlaceContext;
|
||||
import net.momirealms.craftengine.core.item.context.UseOnContext;
|
||||
import net.momirealms.craftengine.core.plugin.context.ContextHolder;
|
||||
import net.momirealms.craftengine.core.plugin.context.parameter.DirectContextParameters;
|
||||
import net.momirealms.craftengine.core.sound.SoundData;
|
||||
import net.momirealms.craftengine.core.util.Direction;
|
||||
import net.momirealms.craftengine.core.util.HorizontalDirection;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
@@ -51,6 +52,8 @@ public class DoorBlockBehavior extends AbstractCanSurviveBlockBehavior {
|
||||
private final Property<Boolean> openProperty;
|
||||
private final boolean canOpenWithHand;
|
||||
private final boolean canOpenByWindCharge;
|
||||
private final SoundData openSound;
|
||||
private final SoundData closeSound;
|
||||
|
||||
public DoorBlockBehavior(CustomBlock block,
|
||||
Property<DoubleBlockHalf> halfProperty,
|
||||
@@ -59,7 +62,9 @@ public class DoorBlockBehavior extends AbstractCanSurviveBlockBehavior {
|
||||
Property<Boolean> poweredProperty,
|
||||
Property<Boolean> openProperty,
|
||||
boolean canOpenWithHand,
|
||||
boolean canOpenByWindCharge) {
|
||||
boolean canOpenByWindCharge,
|
||||
SoundData openSound,
|
||||
SoundData closeSound) {
|
||||
super(block, 0);
|
||||
this.halfProperty = halfProperty;
|
||||
this.facingProperty = facingProperty;
|
||||
@@ -68,6 +73,8 @@ public class DoorBlockBehavior extends AbstractCanSurviveBlockBehavior {
|
||||
this.openProperty = openProperty;
|
||||
this.canOpenWithHand = canOpenWithHand;
|
||||
this.canOpenByWindCharge = canOpenByWindCharge;
|
||||
this.openSound = openSound;
|
||||
this.closeSound = closeSound;
|
||||
}
|
||||
|
||||
public boolean isOpen(ImmutableBlockState state) {
|
||||
@@ -138,7 +145,7 @@ public class DoorBlockBehavior extends AbstractCanSurviveBlockBehavior {
|
||||
@Override
|
||||
public void setPlacedBy(BlockPlaceContext context, ImmutableBlockState state) {
|
||||
BlockPos pos = context.getClickedPos();
|
||||
context.getLevel().setBlockAt(pos.x(), pos.y() + 1, pos.z(), state.with(this.halfProperty, DoubleBlockHalf.UPPER).customBlockState(), 3);
|
||||
context.getLevel().setBlockAt(pos.x(), pos.y() + 1, pos.z(), state.with(this.halfProperty, DoubleBlockHalf.UPPER).customBlockState(), UpdateOption.UPDATE_ALL.flags());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -213,19 +220,33 @@ public class DoorBlockBehavior extends AbstractCanSurviveBlockBehavior {
|
||||
|
||||
public void setOpen(@Nullable Player player, Object serverLevel, ImmutableBlockState state, BlockPos pos, boolean isOpen) {
|
||||
if (isOpen(state) != isOpen) {
|
||||
org.bukkit.World world = FastNMS.INSTANCE.method$Level$getCraftWorld(serverLevel);
|
||||
FastNMS.INSTANCE.method$LevelWriter$setBlock(serverLevel, LocationUtils.toBlockPos(pos), state.with(this.openProperty, isOpen).customBlockState().handle(), UpdateOption.builder().updateImmediate().updateClients().build().flags());
|
||||
FastNMS.INSTANCE.method$Level$getCraftWorld(serverLevel).sendGameEvent(player == null ? null : (org.bukkit.entity.Player) player.platformPlayer(), isOpen ? GameEvent.BLOCK_OPEN : GameEvent.BLOCK_CLOSE, new Vector(pos.x(), pos.y(), pos.z()));
|
||||
// todo 播放声音
|
||||
world.sendGameEvent(player == null ? null : (org.bukkit.entity.Player) player.platformPlayer(), isOpen ? GameEvent.BLOCK_OPEN : GameEvent.BLOCK_CLOSE, new Vector(pos.x(), pos.y(), pos.z()));
|
||||
SoundData soundData = isOpen ? this.openSound : this.closeSound;
|
||||
if (soundData != null) {
|
||||
new BukkitWorld(world).playBlockSound(
|
||||
new Vec3d(pos.x() + 0.5, pos.y() + 0.5, pos.z() + 0.5),
|
||||
soundData
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult useOnBlock(UseOnContext context, ImmutableBlockState state) {
|
||||
if (!this.canOpenWithHand || context.getPlayer().isSecondaryUseActive()) {
|
||||
if (!this.canOpenWithHand) {
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
if (context.getItem() == null) {
|
||||
setOpen(context.getPlayer(), context.getLevel().serverWorld(), state, context.getClickedPos(), !state.get(this.openProperty));
|
||||
return InteractionResult.SUCCESS;
|
||||
} else if (!context.getPlayer().isSecondaryUseActive()) {
|
||||
setOpen(context.getPlayer(), context.getLevel().serverWorld(), state, context.getClickedPos(), !state.get(this.openProperty));
|
||||
return InteractionResult.SUCCESS_AND_CANCEL;
|
||||
} else {
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
setOpen(context.getPlayer(), context.getLevel().serverWorld(), state, context.getClickedPos(), !state.get(this.openProperty));
|
||||
return InteractionResult.SUCCESS_AND_CANCEL;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -258,8 +279,15 @@ public class DoorBlockBehavior extends AbstractCanSurviveBlockBehavior {
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
boolean flag = event.getNewCurrent() > 0;
|
||||
if (flag != immutableBlockState.get(this.openProperty)) {
|
||||
FastNMS.INSTANCE.method$Level$getCraftWorld(level).sendGameEvent(null, flag ? GameEvent.BLOCK_OPEN : GameEvent.BLOCK_CLOSE, new Vector(bukkitBlock.getX(), bukkitBlock.getY(), bukkitBlock.getZ()));
|
||||
// todo 播放声音
|
||||
org.bukkit.World world = FastNMS.INSTANCE.method$Level$getCraftWorld(level);
|
||||
world.sendGameEvent(null, flag ? GameEvent.BLOCK_OPEN : GameEvent.BLOCK_CLOSE, new Vector(bukkitBlock.getX(), bukkitBlock.getY(), bukkitBlock.getZ()));
|
||||
SoundData soundData = flag ? this.openSound : this.closeSound;
|
||||
if (soundData != null) {
|
||||
new BukkitWorld(world).playBlockSound(
|
||||
new Vec3d(FastNMS.INSTANCE.field$Vec3i$x(blockPos) + 0.5, FastNMS.INSTANCE.field$Vec3i$y(blockPos) + 0.5, FastNMS.INSTANCE.field$Vec3i$z(blockPos) + 0.5),
|
||||
soundData
|
||||
);
|
||||
}
|
||||
}
|
||||
FastNMS.INSTANCE.method$LevelWriter$setBlock(level, blockPos, immutableBlockState.with(this.poweredProperty, flag).with(this.openProperty, flag).customBlockState().handle(), UpdateOption.Flags.UPDATE_CLIENTS);
|
||||
}
|
||||
@@ -297,7 +325,14 @@ public class DoorBlockBehavior extends AbstractCanSurviveBlockBehavior {
|
||||
Property<Boolean> powered = (Property<Boolean>) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("powered"), "warning.config.block.behavior.door.missing_powered");
|
||||
boolean canOpenWithHand = (boolean) arguments.getOrDefault("can-open-with-hand", true);
|
||||
boolean canOpenByWindCharge = (boolean) arguments.getOrDefault("can-open-by-wind-charge", true);
|
||||
return new DoorBlockBehavior(block, half, facing, hinge, powered, open, canOpenWithHand, canOpenByWindCharge);
|
||||
Map<String, Object> sounds = (Map<String, Object>) arguments.get("sounds");
|
||||
SoundData openSound = null;
|
||||
SoundData closeSound = null;
|
||||
if (sounds != null) {
|
||||
openSound = Optional.ofNullable(sounds.get("open")).map(obj -> SoundData.create(obj, 1, 1)).orElse(null);
|
||||
closeSound = Optional.ofNullable(sounds.get("close")).map(obj -> SoundData.create(obj, 1, 1)).orElse(null);
|
||||
}
|
||||
return new DoorBlockBehavior(block, half, facing, hinge, powered, open, canOpenWithHand, canOpenByWindCharge, openSound, closeSound);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
public static final NamespacedKey FURNITURE_KEY = KeyUtils.toNamespacedKey(FurnitureManager.FURNITURE_KEY);
|
||||
@@ -95,15 +96,31 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
COLLISION_ENTITY_TYPE = Config.colliderType();
|
||||
Bukkit.getPluginManager().registerEvents(this.dismountListener, this.plugin.javaPlugin());
|
||||
Bukkit.getPluginManager().registerEvents(this.furnitureEventListener, this.plugin.javaPlugin());
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
List<Entity> entities = world.getEntities();
|
||||
for (Entity entity : entities) {
|
||||
if (entity instanceof ItemDisplay display) {
|
||||
handleBaseEntityLoadEarly(display);
|
||||
} else if (entity instanceof Interaction interaction) {
|
||||
handleCollisionEntityLoadOnEntitiesLoad(interaction);
|
||||
} else if (entity instanceof Boat boat) {
|
||||
handleCollisionEntityLoadOnEntitiesLoad(boat);
|
||||
if (VersionHelper.isFolia()) {
|
||||
BiConsumer<Entity, Runnable> taskExecutor = (entity, runnable) -> entity.getScheduler().run(this.plugin.javaPlugin(), (t) -> runnable.run(), () -> {});
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
List<Entity> entities = world.getEntities();
|
||||
for (Entity entity : entities) {
|
||||
if (entity instanceof ItemDisplay display) {
|
||||
taskExecutor.accept(entity, () -> handleBaseEntityLoadEarly(display));
|
||||
} else if (entity instanceof Interaction interaction) {
|
||||
taskExecutor.accept(entity, () -> handleCollisionEntityLoadOnEntitiesLoad(interaction));
|
||||
} else if (entity instanceof Boat boat) {
|
||||
taskExecutor.accept(entity, () -> handleCollisionEntityLoadOnEntitiesLoad(boat));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
List<Entity> entities = world.getEntities();
|
||||
for (Entity entity : entities) {
|
||||
if (entity instanceof ItemDisplay display) {
|
||||
handleBaseEntityLoadEarly(display);
|
||||
} else if (entity instanceof Interaction interaction) {
|
||||
handleCollisionEntityLoadOnEntitiesLoad(interaction);
|
||||
} else if (entity instanceof Boat boat) {
|
||||
handleCollisionEntityLoadOnEntitiesLoad(boat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -266,6 +283,12 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
}
|
||||
|
||||
public void handleCollisionEntityLoadOnEntitiesLoad(Entity collisionEntity) {
|
||||
// faster
|
||||
if (FastNMS.INSTANCE.method$CraftEntity$getHandle(collisionEntity) instanceof CollisionEntity) {
|
||||
collisionEntity.remove();
|
||||
return;
|
||||
}
|
||||
|
||||
// not a collision entity
|
||||
Byte flag = collisionEntity.getPersistentDataContainer().get(FURNITURE_COLLISION, PersistentDataType.BYTE);
|
||||
if (flag == null || flag != 1) {
|
||||
|
||||
@@ -350,6 +350,9 @@ items:
|
||||
type: door_block
|
||||
can-open-with-hand: true
|
||||
can-open-by-wind-charge: true
|
||||
sounds:
|
||||
open: block.wooden_door.open
|
||||
close: block.wooden_door.close
|
||||
loot:
|
||||
template: default:loot_table/self
|
||||
settings:
|
||||
|
||||
Reference in New Issue
Block a user