mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-19 15:09:15 +00:00
优化转化类行为目标状态
This commit is contained in:
@@ -2,6 +2,7 @@ package net.momirealms.craftengine.bukkit.block;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
|
||||
import net.momirealms.craftengine.core.block.AbstractBlockStateWrapper;
|
||||
import net.momirealms.craftengine.core.block.BlockStateWrapper;
|
||||
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
||||
import net.momirealms.craftengine.core.block.properties.Property;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
@@ -30,6 +31,21 @@ public class BukkitCustomBlockStateWrapper extends AbstractBlockStateWrapper {
|
||||
}).orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockStateWrapper withProperty(String propertyName, String propertyValue) {
|
||||
Optional<ImmutableBlockState> immutableBlockState = getImmutableBlockState();
|
||||
if (immutableBlockState.isPresent()) {
|
||||
Property<?> property = immutableBlockState.get().owner().value().getProperty(propertyName);
|
||||
if (property != null) {
|
||||
Comparable<?> value = property.valueByName(propertyValue);
|
||||
if (value != null) {
|
||||
return ImmutableBlockState.with(immutableBlockState.get(), property, value).customBlockState();
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasProperty(String propertyName) {
|
||||
return getImmutableBlockState().map(state -> state.owner().value().getProperty(propertyName) != null).orElse(false);
|
||||
|
||||
@@ -3,6 +3,8 @@ package net.momirealms.craftengine.bukkit.block;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
|
||||
import net.momirealms.craftengine.core.block.AbstractBlockStateWrapper;
|
||||
import net.momirealms.craftengine.core.block.BlockRegistryMirror;
|
||||
import net.momirealms.craftengine.core.block.BlockStateWrapper;
|
||||
import net.momirealms.craftengine.core.block.StatePropertyAccessor;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
|
||||
@@ -33,4 +35,11 @@ public class BukkitVanillaBlockStateWrapper extends AbstractBlockStateWrapper {
|
||||
public String getAsString() {
|
||||
return BlockStateUtils.fromBlockData(super.blockState).getAsString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockStateWrapper withProperty(String propertyName, String propertyValue) {
|
||||
Object newState = this.accessor.withProperty(propertyName, propertyValue);
|
||||
if (newState == super.blockState) return this;
|
||||
return BlockRegistryMirror.byId(BlockStateUtils.blockStateToId(newState));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,12 +2,14 @@ package net.momirealms.craftengine.bukkit.block.behavior;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.bukkit.CraftBukkitReflections;
|
||||
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
|
||||
import net.momirealms.craftengine.core.block.*;
|
||||
import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.RandomUtils;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.util.*;
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.Callable;
|
||||
@@ -15,23 +17,47 @@ import java.util.concurrent.Callable;
|
||||
public class ChangeOverTimeBlockBehavior extends BukkitBlockBehavior {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
private final float changeSpeed;
|
||||
private final Key nextBlock;
|
||||
private final String nextBlock;
|
||||
private final LazyReference<BlockStateWrapper> lazyState;
|
||||
private final List<String> excludedProperties;
|
||||
|
||||
public ChangeOverTimeBlockBehavior(CustomBlock customBlock, float changeSpeed, Key nextBlock) {
|
||||
public ChangeOverTimeBlockBehavior(CustomBlock customBlock, float changeSpeed, String nextBlock, List<String> excludedProperties) {
|
||||
super(customBlock);
|
||||
this.changeSpeed = changeSpeed;
|
||||
this.nextBlock = nextBlock;
|
||||
this.excludedProperties = excludedProperties;
|
||||
this.lazyState = LazyReference.lazyReference(() -> CraftEngine.instance().blockManager().createBlockState(this.nextBlock));
|
||||
}
|
||||
|
||||
public String nextBlock() {
|
||||
return nextBlock;
|
||||
}
|
||||
|
||||
public BlockStateWrapper nextState() {
|
||||
return this.lazyState.get();
|
||||
}
|
||||
|
||||
public CompoundTag filter(CompoundTag properties) {
|
||||
for (String property : this.excludedProperties) {
|
||||
properties.remove(property);
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void randomTick(Object thisBlock, Object[] args, Callable<Object> superMethod) throws ReflectiveOperationException {
|
||||
public void randomTick(Object thisBlock, Object[] args, Callable<Object> superMethod) {
|
||||
if (RandomUtils.generateRandomFloat(0F, 1F) >= this.changeSpeed) return;
|
||||
Optional<Object> nextState = BukkitBlockManager.instance().blockById(this.nextBlock)
|
||||
.map(CustomBlock::defaultState)
|
||||
.map(ImmutableBlockState::customBlockState)
|
||||
.map(BlockStateWrapper::literalObject);
|
||||
if (nextState.isEmpty()) return;
|
||||
CraftBukkitReflections.method$CraftEventFactory$handleBlockFormEvent.invoke(null, args[1], args[2], nextState.get(), UpdateOption.UPDATE_ALL.flags());
|
||||
Object blockState = args[0];
|
||||
BlockStateUtils.getOptionalCustomBlockState(blockState).ifPresent(state -> {
|
||||
BlockStateWrapper nextState = this.nextState();
|
||||
if (nextState == null) return;
|
||||
nextState = nextState.withProperties(filter(state.propertiesNbt()));
|
||||
try {
|
||||
CraftBukkitReflections.method$CraftEventFactory$handleBlockFormEvent.invoke(null, args[1], args[2], nextState.literalObject(), UpdateOption.UPDATE_ALL.flags());
|
||||
} catch (ReflectiveOperationException e) {
|
||||
CraftEngine.instance().logger().warn("Failed to call block form event", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static class Factory implements BlockBehaviorFactory {
|
||||
@@ -39,8 +65,9 @@ public class ChangeOverTimeBlockBehavior extends BukkitBlockBehavior {
|
||||
@Override
|
||||
public BlockBehavior create(CustomBlock block, Map<String, Object> arguments) {
|
||||
float changeSpeed = ResourceConfigUtils.getAsFloat(arguments.getOrDefault("change-speed", 0.05688889F), "change-speed");
|
||||
Key nextBlock = Key.of(ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.getOrDefault("next-block", "minecraft:air"), "warning.config.block.behavior.change_over_time.missing_next_block"));
|
||||
return new ChangeOverTimeBlockBehavior(block, changeSpeed, nextBlock);
|
||||
String nextBlock = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.getOrDefault("next-block", "minecraft:air"), "warning.config.block.behavior.change_over_time.missing_next_block");
|
||||
List<String> excludedProperties = MiscUtils.getAsStringList(arguments.get("excluded-properties"));
|
||||
return new ChangeOverTimeBlockBehavior(block, changeSpeed, nextBlock, excludedProperties);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,40 +1,53 @@
|
||||
package net.momirealms.craftengine.bukkit.block.behavior;
|
||||
|
||||
import net.momirealms.craftengine.core.block.BlockBehavior;
|
||||
import net.momirealms.craftengine.core.block.BlockStateWrapper;
|
||||
import net.momirealms.craftengine.core.block.CustomBlock;
|
||||
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
||||
import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory;
|
||||
import net.momirealms.craftengine.core.block.parser.BlockStateParser;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.util.LazyReference;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class StrippableBlockBehavior extends BukkitBlockBehavior {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
private final String stripped;
|
||||
private final LazyReference<ImmutableBlockState> lazyState;
|
||||
private final LazyReference<BlockStateWrapper> lazyState;
|
||||
private final List<String> excludedProperties;
|
||||
|
||||
public StrippableBlockBehavior(CustomBlock block, String stripped) {
|
||||
public StrippableBlockBehavior(CustomBlock block, String stripped, List<String> excludedProperties) {
|
||||
super(block);
|
||||
this.stripped = stripped;
|
||||
this.lazyState = LazyReference.lazyReference(() -> BlockStateParser.deserialize(this.stripped));
|
||||
this.lazyState = LazyReference.lazyReference(() -> CraftEngine.instance().blockManager().createBlockState(this.stripped));
|
||||
this.excludedProperties = excludedProperties;
|
||||
}
|
||||
|
||||
public String stripped() {
|
||||
return this.stripped;
|
||||
}
|
||||
|
||||
public ImmutableBlockState strippedState() {
|
||||
public BlockStateWrapper strippedState() {
|
||||
return this.lazyState.get();
|
||||
}
|
||||
|
||||
public CompoundTag filter(CompoundTag properties) {
|
||||
for (String property : this.excludedProperties) {
|
||||
properties.remove(property);
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
public static class Factory implements BlockBehaviorFactory {
|
||||
|
||||
@Override
|
||||
public BlockBehavior create(CustomBlock block, Map<String, Object> arguments) {
|
||||
String stripped = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("stripped"), "warning.config.block.behavior.strippable.missing_stripped");
|
||||
return new StrippableBlockBehavior(block, stripped);
|
||||
List<String> excludedProperties = MiscUtils.getAsStringList(arguments.get("excluded-properties"));
|
||||
return new StrippableBlockBehavior(block, stripped, excludedProperties);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,21 +70,19 @@ public class AxeItemBehavior extends ItemBehavior {
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
|
||||
ImmutableBlockState newState = behaviorOptional.get().strippedState();
|
||||
BlockStateWrapper newState = behaviorOptional.get().strippedState();
|
||||
if (newState == null) {
|
||||
CraftEngine.instance().logger().warn("stripped block " + behaviorOptional.get().stripped() + " does not exist");
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
|
||||
BlockStateWrapper
|
||||
|
||||
newState = newState.with(customState.propertiesNbt());
|
||||
newState = newState.withProperties(behaviorOptional.get().filter(customState.propertiesNbt()));
|
||||
BukkitExistingBlock clicked = (BukkitExistingBlock) context.getLevel().getBlockAt(context.getClickedPos());
|
||||
org.bukkit.entity.Player bukkitPlayer = null;
|
||||
if (player != null) {
|
||||
bukkitPlayer = ((org.bukkit.entity.Player) player.platformPlayer());
|
||||
// Call bukkit event
|
||||
EntityChangeBlockEvent event = new EntityChangeBlockEvent(bukkitPlayer, clicked.block(), BlockStateUtils.fromBlockData(newState.customBlockState().literalObject()));
|
||||
EntityChangeBlockEvent event = new EntityChangeBlockEvent(bukkitPlayer, clicked.block(), BlockStateUtils.fromBlockData(newState.literalObject()));
|
||||
if (EventUtils.fireAndCheckCancel(event)) {
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
@@ -95,7 +93,7 @@ public class AxeItemBehavior extends ItemBehavior {
|
||||
if (ItemUtils.isEmpty(item)) return InteractionResult.FAIL;
|
||||
BlockPos pos = context.getClickedPos();
|
||||
context.getLevel().playBlockSound(Vec3d.atCenterOf(pos), AXE_STRIP_SOUND, 1, 1);
|
||||
FastNMS.INSTANCE.method$LevelWriter$setBlock(context.getLevel().serverWorld(), LocationUtils.toBlockPos(pos), newState.customBlockState().literalObject(), UpdateOption.UPDATE_ALL_IMMEDIATE.flags());
|
||||
FastNMS.INSTANCE.method$LevelWriter$setBlock(context.getLevel().serverWorld(), LocationUtils.toBlockPos(pos), newState.literalObject(), UpdateOption.UPDATE_ALL_IMMEDIATE.flags());
|
||||
clicked.block().getWorld().sendGameEvent(bukkitPlayer, GameEvent.BLOCK_CHANGE, new Vector(pos.x(), pos.y(), pos.z()));
|
||||
Material material = MaterialUtils.getMaterial(item.vanillaId());
|
||||
if (bukkitPlayer != null) {
|
||||
@@ -123,7 +121,7 @@ public class AxeItemBehavior extends ItemBehavior {
|
||||
itemStack.damage(1, bukkitPlayer);
|
||||
}
|
||||
}
|
||||
return InteractionResult.SUCCESS;
|
||||
return InteractionResult.SUCCESS_AND_CANCEL;
|
||||
}
|
||||
|
||||
public static class Factory implements ItemBehaviorFactory {
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package net.momirealms.craftengine.core.block;
|
||||
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.sparrow.nbt.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface BlockStateWrapper extends Comparable<BlockStateWrapper> {
|
||||
|
||||
Object literalObject();
|
||||
@@ -15,10 +18,27 @@ public interface BlockStateWrapper extends Comparable<BlockStateWrapper> {
|
||||
|
||||
boolean hasProperty(String propertyName);
|
||||
|
||||
BlockStateWrapper withProperty(String propertyName, String propertyValue);
|
||||
|
||||
String getAsString();
|
||||
|
||||
@Override
|
||||
default int compareTo(@NotNull BlockStateWrapper o) {
|
||||
return Integer.compare(registryId(), o.registryId());
|
||||
}
|
||||
|
||||
default BlockStateWrapper withProperties(CompoundTag properties) {
|
||||
BlockStateWrapper result = this;
|
||||
for (Map.Entry<String, Tag> entry : properties.entrySet()) {
|
||||
Tag value = entry.getValue();
|
||||
if (value instanceof StringTag stringTag) {
|
||||
result = result.withProperty(entry.getKey(), stringTag.getAsString());
|
||||
} else if (value instanceof IntTag intTag) {
|
||||
result = result.withProperty(entry.getKey(), String.valueOf(intTag.getAsInt()));
|
||||
} else if (value instanceof ByteTag byteTag) {
|
||||
result = result.withProperty(entry.getKey(), String.valueOf(byteTag.booleanValue()));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import net.momirealms.craftengine.core.block.entity.BlockEntityType;
|
||||
import net.momirealms.craftengine.core.block.entity.render.element.BlockEntityElement;
|
||||
import net.momirealms.craftengine.core.block.entity.render.element.BlockEntityElementConfig;
|
||||
import net.momirealms.craftengine.core.block.entity.tick.BlockEntityTicker;
|
||||
import net.momirealms.craftengine.core.block.properties.EnumProperty;
|
||||
import net.momirealms.craftengine.core.block.properties.Property;
|
||||
import net.momirealms.craftengine.core.entity.player.Player;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package net.momirealms.craftengine.core.block;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface StatePropertyAccessor {
|
||||
@@ -11,4 +13,7 @@ public interface StatePropertyAccessor {
|
||||
boolean hasProperty(String property);
|
||||
|
||||
<T> T getPropertyValue(String property);
|
||||
|
||||
@NotNull
|
||||
Object withProperty(String propertyName, String value);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import net.momirealms.sparrow.nbt.IntTag;
|
||||
import net.momirealms.sparrow.nbt.NumericTag;
|
||||
import net.momirealms.sparrow.nbt.Tag;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -5,6 +5,7 @@ import net.momirealms.craftengine.core.item.context.BlockPlaceContext;
|
||||
import net.momirealms.craftengine.core.util.Direction;
|
||||
import net.momirealms.craftengine.core.util.HorizontalDirection;
|
||||
import net.momirealms.sparrow.nbt.Tag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -155,7 +156,7 @@ public abstract class Property<T extends Comparable<T>> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
public @NotNull String toString() {
|
||||
return this.property.name + "=" + this.property.valueName(this.value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,8 @@ import com.google.common.collect.ImmutableMap;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.sparrow.nbt.StringTag;
|
||||
import net.momirealms.sparrow.nbt.Tag;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ byte_buddy_version=1.17.5
|
||||
ahocorasick_version=0.6.3
|
||||
snake_yaml_version=2.5
|
||||
anti_grief_version=1.0.2
|
||||
nms_helper_version=1.0.103
|
||||
nms_helper_version=1.0.104
|
||||
evalex_version=3.5.0
|
||||
reactive_streams_version=1.0.4
|
||||
amazon_awssdk_version=2.34.5
|
||||
|
||||
Reference in New Issue
Block a user