9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-25 01:49:30 +00:00

盔甲重构part3

This commit is contained in:
XiaoMoMi
2025-07-03 23:22:42 +08:00
parent 47edf443b5
commit 7aedabc638
16 changed files with 369 additions and 92 deletions

View File

@@ -5,18 +5,26 @@ items:
trim:
pattern: chainmail
material: custom
hide-tooltip:
- trim
minecraft:chainmail_chestplate:
client-bound-data:
trim:
pattern: chainmail
material: custom
hide-tooltip:
- trim
minecraft:chainmail_leggings:
client-bound-data:
trim:
pattern: chainmail
material: custom
hide-tooltip:
- trim
minecraft:chainmail_boots:
client-bound-data:
trim:
pattern: chainmail
material: custom
material: custom
hide-tooltip:
- trim

View File

@@ -1,22 +0,0 @@
package net.momirealms.craftengine.core.block;
import net.momirealms.craftengine.core.plugin.CraftEngine;
public final class LazyBlockState {
private final String state;
private BlockStateWrapper packedBlockState;
public LazyBlockState(String state) {
this.state = state;
}
public BlockStateWrapper getState() {
if (this.packedBlockState == null) {
this.packedBlockState = CraftEngine.instance().blockManager().createPackedBlockState(state);
if (this.packedBlockState == null) {
CraftEngine.instance().logger().warn("Could not create block state: " + this.state);
}
}
return this.packedBlockState;
}
}

View File

@@ -547,6 +547,10 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
String pattern = data.get("pattern").toString().toLowerCase(Locale.ENGLISH);
return new TrimModifier<>(material, pattern);
}, "trim");
registerDataType((obj) -> {
List<Key> components = MiscUtils.getAsStringList(obj).stream().map(Key::of).toList();
return new HideTooltipModifier<>(components);
}, "hide-tooltip", "hide-flags");
registerDataType((obj) -> {
Map<String, Object> data = MiscUtils.castToMap(obj, false);
Map<String, TextProvider> arguments = new HashMap<>();

View File

@@ -5,27 +5,74 @@ import net.momirealms.craftengine.core.util.Key;
public final class ComponentKeys {
private ComponentKeys() {}
public static final Key ATTRIBUTE_MODIFIERS = Key.of("minecraft", "attribute_modifiers");
public static final Key BANNER_PATTERN = Key.of("minecraft", "banner_patterns");
public static final Key BASE_COLOR = Key.of("minecraft", "base_color");
public static final Key BEES = Key.of("minecraft", "bees");
public static final Key BLOCK_ENTITY_DATA = Key.of("minecraft", "block_entity_data");
public static final Key BLOCK_STATE = Key.of("minecraft", "block_state");
public static final Key BLOCKS_ATTACK = Key.of("minecraft", "blocks_attacks");
public static final Key BREAK_SOUND = Key.of("minecraft", "break_sound");
public static final Key BUCKET_ENTITY_DATA = Key.of("minecraft", "bucket_entity_data");
public static final Key BUNDLE_CONTENTS = Key.of("minecraft", "bundle_contents");
public static final Key CAN_BREAK = Key.of("minecraft", "can_break");
public static final Key CAN_PLACE_ON = Key.of("minecraft", "can_place_on");
public static final Key CHARGED_PROJECTILES = Key.of("minecraft", "charged_projectiles");
public static final Key CONSUMABLE = Key.of("minecraft", "consumable");
public static final Key CONTAINER = Key.of("minecraft", "container");
public static final Key CONTAINER_LOOT = Key.of("minecraft", "container_loot");
public static final Key CUSTOM_DATA = Key.of("minecraft", "custom_data");
public static final Key CUSTOM_MODEL_DATA = Key.of("minecraft", "custom_model_data");
public static final Key CUSTOM_NAME = Key.of("minecraft", "custom_name");
public static final Key ITEM_NAME = Key.of("minecraft", "item_name");
public static final Key LORE = Key.of("minecraft", "lore");
public static final Key DAMAGE = Key.of("minecraft", "damage");
public static final Key MAX_DAMAGE = Key.of("minecraft", "max_damage");
public static final Key DAMAGE_RESISTANT = Key.of("minecraft", "damage_resistant");
public static final Key DEBUG_STICK_STATE = Key.of("minecraft", "debug_stick_state");
public static final Key DEATH_PROTECTION = Key.of("minecraft", "death_protection");
public static final Key DYED_COLOR = Key.of("minecraft", "dyed_color");
public static final Key ENCHANTABLE = Key.of("minecraft", "enchantable");
public static final Key ENCHANTMENT_GLINT_OVERRIDE = Key.of("minecraft", "enchantment_glint_override");
public static final Key ENCHANTMENTS = Key.of("minecraft", "enchantments");
public static final Key STORED_ENCHANTMENTS = Key.of("minecraft", "stored_enchantments");
public static final Key UNBREAKABLE = Key.of("minecraft", "unbreakable");
public static final Key MAX_STACK_SIZE = Key.of("minecraft", "max_stack_size");
public static final Key ENTITY_DATA = Key.of("minecraft", "entity_data");
public static final Key EQUIPPABLE = Key.of("minecraft", "equippable");
public static final Key ITEM_MODEL = Key.of("minecraft", "item_model");
public static final Key TOOLTIP_STYLE = Key.of("minecraft", "tooltip_style");
public static final Key JUKEBOX_PLAYABLE = Key.of("minecraft", "jukebox_playable");
public static final Key TRIM = Key.of("minecraft", "trim");
public static final Key REPAIR_COST = Key.of("minecraft", "repair_cost");
public static final Key CUSTOM_DATA = Key.of("minecraft", "custom_data");
public static final Key PROFILE = Key.of("minecraft", "profile");
public static final Key DYED_COLOR = Key.of("minecraft", "dyed_color");
public static final Key DEATH_PROTECTION = Key.of("minecraft", "death_protection");
public static final Key FOOD = Key.of("minecraft", "food");
public static final Key FIREWORK_EXPLOSION = Key.of("minecraft", "firework_explosion");
public static final Key FIREWORKS = Key.of("minecraft", "fireworks");
public static final Key FOOD = Key.of("minecraft", "food");
public static final Key GLIDER = Key.of("minecraft", "glider");
public static final Key INSTRUMENT = Key.of("minecraft", "instrument");
public static final Key INTANGIBLE_PROJECTILE = Key.of("minecraft", "intangible_projectile");
public static final Key ITEM_MODEL = Key.of("minecraft", "item_model");
public static final Key ITEM_NAME = Key.of("minecraft", "item_name");
public static final Key JUKEBOX_PLAYABLE = Key.of("minecraft", "jukebox_playable");
public static final Key LOCK = Key.of("minecraft", "lock");
public static final Key LODESTONE_TRACKER = Key.of("minecraft", "lodestone_tracker");
public static final Key LORE = Key.of("minecraft", "lore");
public static final Key MAP_COLOR = Key.of("minecraft", "map_color");
public static final Key MAP_DECORATIONS = Key.of("minecraft", "map_decorations");
public static final Key MAP_ID = Key.of("minecraft", "map_id");
public static final Key MAX_DAMAGE = Key.of("minecraft", "max_damage");
public static final Key MAX_STACK_SIZE = Key.of("minecraft", "max_stack_size");
public static final Key NOTE_BLOCK_SOUND = Key.of("minecraft", "note_block_sound");
public static final Key OMINOUS_BOTTLE_AMPLIFIER = Key.of("minecraft", "ominous_bottle_amplifier");
public static final Key POT_DECORATIONS = Key.of("minecraft", "pot_decorations");
public static final Key POTION_CONTENTS = Key.of("minecraft", "potion_contents");
public static final Key POTION_DURATION_SCALE = Key.of("minecraft", "potion_duration_scale");
public static final Key PROFILE = Key.of("minecraft", "profile");
public static final Key PROVIDES_BANNER_PATTERN = Key.of("minecraft", "provides_banner_patterns");
public static final Key PROVIDES_TRIM_MATERIAL = Key.of("minecraft", "provides_trim_material");
public static final Key RARITY = Key.of("minecraft", "rarity");
public static final Key RECIPES = Key.of("minecraft", "recipes");
public static final Key REPAIRABLE = Key.of("minecraft", "repairable");
public static final Key REPAIR_COST = Key.of("minecraft", "repair_cost");
public static final Key STORED_ENCHANTMENTS = Key.of("minecraft", "stored_enchantments");
public static final Key SUSPICIOUS_STEW_EFFECTS = Key.of("minecraft", "suspicious_stew_effects");
public static final Key TOOL = Key.of("minecraft", "tool");
public static final Key TOOLTIP_DISPLAY = Key.of("minecraft", "tooltip_display");
public static final Key TOOLTIP_STYLE = Key.of("minecraft", "tooltip_style");
public static final Key TRIM = Key.of("minecraft", "trim");
public static final Key UNBREAKABLE = Key.of("minecraft", "unbreakable");
public static final Key USE_COOLDOWN = Key.of("minecraft", "use_cooldown");
public static final Key USE_REMAINDER = Key.of("minecraft", "use_remainder");
public static final Key WEAPON = Key.of("minecraft", "weapon");
public static final Key WRITABLE_BOOK_CONTENT = Key.of("minecraft", "writable_book_content");
public static final Key WRITTEN_BOOK_CONTENT = Key.of("minecraft", "written_book_content");
}

View File

@@ -1,23 +0,0 @@
package net.momirealms.craftengine.core.item;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.Key;
public class DelayedInitItem {
private final Key itemId;
private Item<?> item;
public DelayedInitItem(Key itemId) {
this.itemId = itemId;
}
public Item<?> getItem() {
if (this.item == null) {
this.item = CraftEngine.instance().itemManager().createWrappedItem(this.itemId, null);
if (this.item == null) {
CraftEngine.instance().logger().warn("Could not create item: " + this.itemId);
}
}
return this.item;
}
}

View File

@@ -51,7 +51,7 @@ public class ItemSettings {
modifiers.add(new EquippableModifier<>(data));
}
if (!this.equipment.clientBoundModel().asBoolean(Config.globalClientboundModel())) {
modifiers.add(this.equipment.equipment().modifier());
modifiers.addAll(this.equipment.equipment().modifiers());
}
}
if (VersionHelper.isOrAbove1_20_5() && this.foodData != null) {
@@ -64,7 +64,7 @@ public class ItemSettings {
ArrayList<ItemDataModifier<I>> modifiers = new ArrayList<>();
if (this.equipment != null) {
if (this.equipment.clientBoundModel().asBoolean(Config.globalClientboundModel())) {
modifiers.add(this.equipment.equipment().modifier());
modifiers.addAll(this.equipment.equipment().modifiers());
}
}
return modifiers;

View File

@@ -31,8 +31,8 @@ public class ComponentBasedEquipment extends AbstractEquipment implements Suppli
}
@Override
public <I> ItemDataModifier<I> modifier() {
return new EquippableAssetIdModifier<>(this.assetId);
public <I> List<ItemDataModifier<I>> modifiers() {
return List.of(new EquippableAssetIdModifier<>(this.assetId));
}
public EnumMap<EquipmentLayerType, List<Layer>> layers() {

View File

@@ -3,11 +3,13 @@ package net.momirealms.craftengine.core.item.equipment;
import net.momirealms.craftengine.core.item.modifier.ItemDataModifier;
import net.momirealms.craftengine.core.util.Key;
import java.util.List;
public interface Equipment {
Key assetId();
Key type();
<I> ItemDataModifier<I> modifier();
<I> List<ItemDataModifier<I>> modifiers();
}

View File

@@ -1,11 +1,14 @@
package net.momirealms.craftengine.core.item.equipment;
import net.momirealms.craftengine.core.item.ComponentKeys;
import net.momirealms.craftengine.core.item.modifier.HideTooltipModifier;
import net.momirealms.craftengine.core.item.modifier.ItemDataModifier;
import net.momirealms.craftengine.core.item.modifier.TrimModifier;
import net.momirealms.craftengine.core.pack.AbstractPackManager;
import net.momirealms.craftengine.core.util.Key;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -36,8 +39,11 @@ public class TrimBasedEquipment extends AbstractEquipment {
}
@Override
public <I> ItemDataModifier<I> modifier() {
return new TrimModifier<>(AbstractPackManager.NEW_TRIM_MATERIAL, this.assetId.toString());
public <I> List<ItemDataModifier<I>> modifiers() {
return List.of(
new TrimModifier<>(AbstractPackManager.NEW_TRIM_MATERIAL, this.assetId.toString()),
new HideTooltipModifier<>(List.of(ComponentKeys.TRIM))
);
}
public static class Factory implements EquipmentFactory {

View File

@@ -0,0 +1,215 @@
package net.momirealms.craftengine.core.item.modifier;
import com.google.common.collect.ImmutableMap;
import net.momirealms.craftengine.core.item.ComponentKeys;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.item.ItemBuildContext;
import net.momirealms.craftengine.core.item.NetworkItemHandler;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.MiscUtils;
import net.momirealms.craftengine.core.util.VersionHelper;
import net.momirealms.sparrow.nbt.CompoundTag;
import net.momirealms.sparrow.nbt.Tag;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class HideTooltipModifier<I> implements ItemDataModifier<I> {
public static final Map<Key, Integer> TO_LEGACY;
static {
ImmutableMap.Builder<Key, Integer> builder = ImmutableMap.builder();
builder.put(ComponentKeys.ENCHANTMENTS, 1);
builder.put(ComponentKeys.ATTRIBUTE_MODIFIERS, 2);
builder.put(ComponentKeys.UNBREAKABLE, 4);
builder.put(ComponentKeys.CAN_BREAK, 8);
builder.put(ComponentKeys.CAN_PLACE_ON, 16);
builder.put(ComponentKeys.STORED_ENCHANTMENTS, 32);
builder.put(ComponentKeys.POTION_CONTENTS, 32);
builder.put(ComponentKeys.WRITTEN_BOOK_CONTENT, 32);
builder.put(ComponentKeys.FIREWORKS, 32);
builder.put(ComponentKeys.FIREWORK_EXPLOSION, 32);
builder.put(ComponentKeys.BUNDLE_CONTENTS, 32);
builder.put(ComponentKeys.MAP_ID, 32);
builder.put(ComponentKeys.MAP_COLOR, 32);
builder.put(ComponentKeys.MAP_DECORATIONS, 32);
builder.put(ComponentKeys.DYED_COLOR, 64);
builder.put(ComponentKeys.TRIM, 128);
TO_LEGACY = builder.build();
}
private final List<Key> components;
private final Applier<I> applier;
public HideTooltipModifier(List<Key> components) {
this.components = components;
if (VersionHelper.isOrAbove1_21_5()) {
this.applier = new ModernApplier<>(components);
} else if (VersionHelper.isOrAbove1_20_5()) {
if (components.isEmpty()) {
this.applier = new DummyApplier<>();
} else if (components.size() == 1) {
this.applier = new SemiModernApplier<>(components.getFirst());
} else {
List<Applier<I>> appliers = new ArrayList<>();
for (Key key : components) {
appliers.add(new SemiModernApplier<>(key));
}
this.applier = new CompoundApplier<>(appliers);
}
} else {
this.applier = new LegacyApplier<>(components);
}
}
public List<Key> components() {
return components;
}
@Override
public Item<I> apply(Item<I> item, ItemBuildContext context) {
this.applier.apply(item);
return item;
}
@Override
public Item<I> prepareNetworkItem(Item<I> item, ItemBuildContext context, CompoundTag networkData) {
if (VersionHelper.isOrAbove1_21_5()) {
Tag previous = item.getNBTComponent(ComponentKeys.TOOLTIP_DISPLAY);
if (previous != null) {
networkData.put(ComponentKeys.TOOLTIP_DISPLAY.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
} else {
networkData.put(ComponentKeys.TOOLTIP_DISPLAY.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
}
} else if (VersionHelper.isOrAbove1_20_5()) {
for (Key component : this.components) {
Tag previous = item.getNBTComponent(component);
if (previous != null) {
networkData.put(component.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
} else {
networkData.put(component.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
}
}
} else {
Tag previous = item.getNBTTag("HideFlags");
if (previous != null) {
networkData.put("HideFlags", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
} else {
networkData.put("HideFlags", NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
}
}
return item;
}
@Override
public String name() {
return "hide-tooltip";
}
public interface Applier<I> {
void apply(Item<I> item);
}
public static class DummyApplier<T> implements Applier<T> {
@Override
public void apply(Item<T> item) {
}
}
public static class SemiModernApplier<I> implements Applier<I> {
private final Key component;
public SemiModernApplier(Key component) {
this.component = component;
}
@Override
public void apply(Item<I> item) {
Tag previous = item.getNBTComponent(this.component);
if (previous instanceof CompoundTag compoundTag) {
compoundTag.putBoolean("show_in_tooltip", false);
item.setNBTComponent(this.component, compoundTag);
} else {
CompoundTag compoundTag = new CompoundTag();
compoundTag.putBoolean("show_in_tooltip", false);
item.setNBTComponent(this.component, compoundTag);
}
}
}
public record CompoundApplier<I>(List<Applier<I>> appliers) implements Applier<I> {
@Override
public void apply(Item<I> item) {
for (Applier<I> applier : appliers) {
applier.apply(item);
}
}
}
public static class LegacyApplier<W> implements Applier<W> {
private final int legacyValue;
public LegacyApplier(List<Key> components) {
int i = 0;
for (Key key : components) {
Integer flag = TO_LEGACY.get(key);
if (flag != null) {
i += flag;
}
}
this.legacyValue = i;
}
public int legacyValue() {
return legacyValue;
}
@Override
public void apply(Item<W> item) {
Integer previousFlags = (Integer) item.getJavaTag("HideFlags");
if (previousFlags != null) {
item.setTag(this.legacyValue | previousFlags, "HideFlags");
} else {
item.setTag(this.legacyValue, "HideFlags");
}
}
}
public static class ModernApplier<W> implements Applier<W> {
private final List<String> components;
public ModernApplier(List<Key> components) {
this.components = components.stream().map(Key::toString).collect(Collectors.toList());
}
public List<String> components() {
return components;
}
@Override
public void apply(Item<W> item) {
Map<String, Object> data = MiscUtils.castToMap(item.getJavaComponent(ComponentKeys.TOOLTIP_DISPLAY), true);
if (data == null) {
item.setJavaComponent(ComponentKeys.TOOLTIP_DISPLAY, Map.of("hidden_components", this.components));
} else {
if (data.get("hidden_components") instanceof List<?> list) {
List<String> hiddenComponents = list.stream().map(Object::toString).toList();
List<String> mergedComponents = Stream.concat(
hiddenComponents.stream(),
this.components.stream()
).distinct().toList();
Map<String, Object> newData = new HashMap<>(data);
newData.put("hidden_components", mergedComponents);
item.setJavaComponent(ComponentKeys.TOOLTIP_DISPLAY, newData);
} else {
Map<String, Object> newData = new HashMap<>(data);
newData.put("hidden_components", this.components);
item.setJavaComponent(ComponentKeys.TOOLTIP_DISPLAY, newData);
}
}
}
}
}

View File

@@ -1280,6 +1280,12 @@ public abstract class AbstractPackManager implements PackManager {
} catch (Exception ignored) {
}
}
// 修复被干碎的原版盔甲
Key vanillaFixTrimType = Key.of("minecraft", Config.sacrificedVanillaArmorType());
collectedTrims.add(Tuple.of(vanillaFixTrimType, true, true));
processTrimBasedEquipment(new TrimBasedEquipment(vanillaFixTrimType, Config.sacrificedHumanoid(), Config.sacrificedHumanoidLeggings()), generatedPackPath);
// 准备新版本atlas和覆盖纹理
JsonObject modernTrimAtlasJson = null;
if (needModernCompatibility) {
@@ -1329,11 +1335,6 @@ public abstract class AbstractPackManager implements PackManager {
}
}
// 修复被干碎的原版盔甲
Key vanillaFixTrimType = Key.of("minecraft", Config.sacrificedVanillaArmorType());
collectedTrims.add(Tuple.of(vanillaFixTrimType, true, true));
processTrimBasedEquipment(new TrimBasedEquipment(vanillaFixTrimType, Config.sacrificedHumanoid(), Config.sacrificedHumanoidLeggings()), generatedPackPath);
// 准备旧版本atlas和覆盖纹理
JsonObject legacyTrimAtlasJson = null;
if (needLegacyCompatibility) {

View File

@@ -1,7 +1,8 @@
package net.momirealms.craftengine.core.plugin.context.function;
import net.momirealms.craftengine.core.block.LazyBlockState;
import net.momirealms.craftengine.core.item.DelayedInitItem;
import net.momirealms.craftengine.core.block.BlockStateWrapper;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.Context;
import net.momirealms.craftengine.core.plugin.context.number.NumberProvider;
@@ -9,6 +10,7 @@ import net.momirealms.craftengine.core.plugin.context.number.NumberProviders;
import net.momirealms.craftengine.core.plugin.context.parameter.DirectContextParameters;
import net.momirealms.craftengine.core.util.Color;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.LazyReference;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import net.momirealms.craftengine.core.world.Position;
import net.momirealms.craftengine.core.world.Vec3d;
@@ -20,13 +22,20 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Supplier;
public class ParticleFunction<CTX extends Context> extends AbstractConditionalFunction<CTX> {
public static final Map<Key, java.util.function.Function<Map<String, Object>, ParticleData>> DATA_TYPES = new HashMap<>();
static {
registerParticleData(map -> new BlockStateData(
new LazyBlockState(ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("block-state"), "warning.config.function.particle.missing_block_state"))),
LazyReference.lazyReference(new Supplier<>() {
final String blockState = ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("block-state"), "warning.config.function.particle.missing_block_state");
@Override
public BlockStateWrapper get() {
return CraftEngine.instance().blockManager().createPackedBlockState(this.blockState);
}
})),
ParticleTypes.BLOCK, ParticleTypes.FALLING_DUST, ParticleTypes.DUST_PILLAR, ParticleTypes.BLOCK_CRUMBLE, ParticleTypes.BLOCK_MARKER);
registerParticleData(map -> new ColorData(
Color.fromString(ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("color"), "warning.config.function.particle.missing_color").split(","))),
@@ -47,7 +56,14 @@ public class ParticleFunction<CTX extends Context> extends AbstractConditionalFu
ResourceConfigUtils.getAsFloat(map.getOrDefault("scale", 1), "scale")),
ParticleTypes.DUST_COLOR_TRANSITION);
registerParticleData(map -> new ItemStackData(
new DelayedInitItem(Key.of(ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("item"), "warning.config.function.particle.missing_item")))),
LazyReference.lazyReference(new Supplier<>() {
final Key itemId = Key.of(ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("item"), "warning.config.function.particle.missing_item"));
@Override
public Item<?> get() {
return CraftEngine.instance().itemManager().createWrappedItem(this.itemId, null);
}
})
),
ParticleTypes.ITEM);
registerParticleData(map -> new VibrationData(
NumberProviders.fromObject(map.getOrDefault("target-x", 0)),

View File

@@ -1,13 +1,15 @@
package net.momirealms.craftengine.core.plugin.context.function;
import net.momirealms.craftengine.core.block.LazyBlockState;
import net.momirealms.craftengine.core.block.BlockStateWrapper;
import net.momirealms.craftengine.core.block.UpdateOption;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.Context;
import net.momirealms.craftengine.core.plugin.context.number.NumberProvider;
import net.momirealms.craftengine.core.plugin.context.number.NumberProviders;
import net.momirealms.craftengine.core.plugin.context.parameter.DirectContextParameters;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.LazyReference;
import net.momirealms.craftengine.core.util.MCUtils;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import net.momirealms.craftengine.core.world.World;
@@ -18,13 +20,13 @@ import java.util.Map;
import java.util.Optional;
public class PlaceBlockFunction<CTX extends Context> extends AbstractConditionalFunction<CTX> {
private final LazyBlockState lazyBlockState;
private final LazyReference<BlockStateWrapper> lazyBlockState;
private final NumberProvider x;
private final NumberProvider y;
private final NumberProvider z;
private final NumberProvider updateFlags;
public PlaceBlockFunction(LazyBlockState lazyBlockState, NumberProvider x, NumberProvider y, NumberProvider z, NumberProvider updateFlags, List<Condition<CTX>> predicates) {
public PlaceBlockFunction(LazyReference<BlockStateWrapper> lazyBlockState, NumberProvider x, NumberProvider y, NumberProvider z, NumberProvider updateFlags, List<Condition<CTX>> predicates) {
super(predicates);
this.lazyBlockState = lazyBlockState;
this.x = x;
@@ -38,7 +40,7 @@ public class PlaceBlockFunction<CTX extends Context> extends AbstractConditional
Optional<WorldPosition> optionalWorldPosition = ctx.getOptionalParameter(DirectContextParameters.POSITION);
if (optionalWorldPosition.isPresent()) {
World world = optionalWorldPosition.get().world();
world.setBlockAt(MCUtils.fastFloor(this.x.getDouble(ctx)), MCUtils.fastFloor(this.y.getDouble(ctx)), MCUtils.fastFloor(this.z.getDouble(ctx)), this.lazyBlockState.getState(), this.updateFlags.getInt(ctx));
world.setBlockAt(MCUtils.fastFloor(this.x.getDouble(ctx)), MCUtils.fastFloor(this.y.getDouble(ctx)), MCUtils.fastFloor(this.z.getDouble(ctx)), this.lazyBlockState.get(), this.updateFlags.getInt(ctx));
}
}
@@ -56,12 +58,11 @@ public class PlaceBlockFunction<CTX extends Context> extends AbstractConditional
@Override
public Function<CTX> create(Map<String, Object> arguments) {
String state = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("block-state"), "warning.config.function.place_block.missing_block_state");
LazyBlockState lazyBlockState = new LazyBlockState(state);
NumberProvider x = NumberProviders.fromObject(arguments.getOrDefault("x", "<arg:position.x>"));
NumberProvider y = NumberProviders.fromObject(arguments.getOrDefault("y", "<arg:position.y>"));
NumberProvider z = NumberProviders.fromObject(arguments.getOrDefault("z", "<arg:position.z>"));
NumberProvider flags = Optional.ofNullable(arguments.get("update-flags")).map(NumberProviders::fromObject).orElse(NumberProviders.direct(UpdateOption.UPDATE_ALL.flags()));
return new PlaceBlockFunction<>(lazyBlockState, x, y, z, flags, getPredicates(arguments));
return new PlaceBlockFunction<>(LazyReference.lazyReference(() -> CraftEngine.instance().blockManager().createPackedBlockState(state)), x, y, z, flags, getPredicates(arguments));
}
}
}

View File

@@ -0,0 +1,22 @@
package net.momirealms.craftengine.core.util;
import java.util.function.Supplier;
public interface LazyReference<T> {
T get();
static <T> LazyReference<T> lazyReference(final Supplier<T> supplier) {
return new LazyReference<>() {
private T value;
@Override
public T get() {
if (this.value == null) {
this.value = supplier.get();
}
return this.value;
}
};
}
}

View File

@@ -1,16 +1,16 @@
package net.momirealms.craftengine.core.world.particle;
import net.momirealms.craftengine.core.block.BlockStateWrapper;
import net.momirealms.craftengine.core.block.LazyBlockState;
import net.momirealms.craftengine.core.util.LazyReference;
public class BlockStateData implements ParticleData {
private final LazyBlockState blockState;
private final LazyReference<BlockStateWrapper> blockState;
public BlockStateData(LazyBlockState blockState) {
public BlockStateData(LazyReference<BlockStateWrapper> blockState) {
this.blockState = blockState;
}
public BlockStateWrapper blockState() {
return blockState.getState();
return blockState.get();
}
}

View File

@@ -1,16 +1,16 @@
package net.momirealms.craftengine.core.world.particle;
import net.momirealms.craftengine.core.item.DelayedInitItem;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.util.LazyReference;
public class ItemStackData implements ParticleData {
private final DelayedInitItem item;
private final LazyReference<Item<?>> item;
public ItemStackData(DelayedInitItem item) {
public ItemStackData(LazyReference<Item<?>> item) {
this.item = item;
}
public Item<?> item() {
return item.getItem();
return item.get();
}
}