9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-23 08:59:27 +00:00

重构context again

This commit is contained in:
XiaoMoMi
2025-05-06 02:34:03 +08:00
parent dd3e1276ec
commit 79c441c0e0
98 changed files with 1022 additions and 216 deletions

View File

@@ -1,13 +1,20 @@
package net.momirealms.craftengine.bukkit.util;
import org.bukkit.attribute.Attribute;
import org.bukkit.attribute.AttributeInstance;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Player;
import java.util.Objects;
import java.util.Optional;
public class LegacyAttributeUtils {
public static void setMaxHealth(ArmorStand entity) {
Objects.requireNonNull(entity.getAttribute(Attribute.GENERIC_MAX_HEALTH)).setBaseValue(0.01);
}
public static double getLuck(Player player) {
return Optional.ofNullable(player.getAttribute(Attribute.GENERIC_LUCK)).map(AttributeInstance::getValue).orElse(1d);
}
}

View File

@@ -292,3 +292,4 @@ warning.config.conflict_matcher.all_of.missing_terms: "<yellow>Issue found in co
warning.config.conflict_matcher.any_of.missing_terms: "<yellow>Issue found in config.yml at 'resource-pack.duplicated-files-handler' - Missing required 'terms' argument for 'any_of' matcher.</yellow>"
warning.config.conflict_resolution.missing_type: "<yellow>Issue found in config.yml at 'resource-pack.duplicated-files-handler' - Missing required 'type' argument for one of the resolutions.</yellow>"
warning.config.conflict_resolution.invalid_type: "<yellow>Issue found in config.yml at 'resource-pack.duplicated-files-handler' - One of the resolutions is using the invalid type '<arg:0>'.</yellow>"
warning.config.function.command.missing_command: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'command' argument for 'command' function.</yellow>"

View File

@@ -10,7 +10,6 @@ import net.momirealms.craftengine.bukkit.world.BukkitWorld;
import net.momirealms.craftengine.core.block.CustomBlock;
import net.momirealms.craftengine.core.block.ImmutableBlockState;
import net.momirealms.craftengine.core.block.UpdateOption;
import net.momirealms.craftengine.core.entity.player.InteractionHand;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.plugin.context.ContextHolder;
import net.momirealms.craftengine.core.plugin.context.parameter.CommonParameters;
@@ -176,9 +175,9 @@ public final class CraftEngineBlocks {
BukkitServerPlayer serverPlayer = BukkitCraftEngine.instance().adapt(player);
if (player != null) {
builder.withParameter(CommonParameters.PLAYER, serverPlayer);
builder.withOptionalParameter(CommonParameters.TOOL, serverPlayer.getItemInHand(InteractionHand.MAIN_HAND));
//mark item builder.withOptionalParameter(CommonParameters.MAIN_HAND_ITEM, serverPlayer.getItemInHand(InteractionHand.MAIN_HAND));
}
for (Item<?> item : state.getDrops(builder, world)) {
for (Item<?> item : state.getDrops(builder, world, serverPlayer)) {
world.dropItemNaturally(vec3d, item);
}
}

View File

@@ -9,7 +9,6 @@ import net.momirealms.craftengine.bukkit.util.LocationUtils;
import net.momirealms.craftengine.bukkit.world.BukkitWorld;
import net.momirealms.craftengine.core.entity.furniture.AnchorType;
import net.momirealms.craftengine.core.entity.furniture.CustomFurniture;
import net.momirealms.craftengine.core.entity.player.InteractionHand;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.loot.LootTable;
import net.momirealms.craftengine.core.plugin.context.ContextHolder;
@@ -275,9 +274,9 @@ public final class CraftEngineFurniture {
builder.withParameter(CommonParameters.WORLD, world);
if (player != null) {
builder.withParameter(CommonParameters.PLAYER, player);
builder.withOptionalParameter(CommonParameters.TOOL, player.getItemInHand(InteractionHand.MAIN_HAND));
//mark item builder.withOptionalParameter(CommonParameters.MAIN_HAND_ITEM, player.getItemInHand(InteractionHand.MAIN_HAND));
}
List<Item<ItemStack>> items = lootTable.getRandomItems(builder.build(), world);
List<Item<ItemStack>> items = lootTable.getRandomItems(builder.build(), world, player);
for (Item<ItemStack> item : items) {
world.dropItemNaturally(vec3d, item);
}

View File

@@ -153,9 +153,9 @@ public class BlockEventListener implements Listener {
ContextHolder.Builder builder = ContextHolder.builder()
.withParameter(CommonParameters.WORLD, world)
.withParameter(CommonParameters.LOCATION, vec3d)
.withParameter(CommonParameters.PLAYER, serverPlayer)
.withOptionalParameter(CommonParameters.TOOL, itemInHand);
for (Item<Object> item : state.getDrops(builder, world)) {
.withParameter(CommonParameters.PLAYER, serverPlayer);
//mark item .withOptionalParameter(CommonParameters.MAIN_HAND_ITEM, itemInHand);
for (Item<Object> item : state.getDrops(builder, world, serverPlayer)) {
world.dropItemNaturally(vec3d, item);
}
}
@@ -174,11 +174,11 @@ public class BlockEventListener implements Listener {
ContextHolder.Builder builder = ContextHolder.builder()
.withParameter(CommonParameters.WORLD, world)
.withParameter(CommonParameters.LOCATION, vec3d)
.withParameter(CommonParameters.PLAYER, serverPlayer)
.withOptionalParameter(CommonParameters.TOOL, serverPlayer.getItemInHand(InteractionHand.MAIN_HAND));
.withParameter(CommonParameters.PLAYER, serverPlayer);
//mark item .withOptionalParameter(CommonParameters.MAIN_HAND_ITEM, serverPlayer.getItemInHand(InteractionHand.MAIN_HAND));
ContextHolder contextHolder = builder.build();
for (LootTable<?> lootTable : it.lootTables()) {
for (Item<?> item : lootTable.getRandomItems(contextHolder, world)) {
for (Item<?> item : lootTable.getRandomItems(contextHolder, world, serverPlayer)) {
world.dropItemNaturally(vec3d, item);
}
}
@@ -216,7 +216,7 @@ public class BlockEventListener implements Listener {
ContextHolder.Builder builder = ContextHolder.builder()
.withParameter(CommonParameters.WORLD, world)
.withParameter(CommonParameters.LOCATION, vec3d);
for (Item<?> item : immutableBlockState.getDrops(builder, world)) {
for (Item<?> item : immutableBlockState.getDrops(builder, world, null)) {
world.dropItemNaturally(vec3d, item);
}
}
@@ -236,7 +236,7 @@ public class BlockEventListener implements Listener {
builder.withParameter(CommonParameters.LOCATION, vec3d);
ContextHolder contextHolder = builder.build();
for (LootTable<?> lootTable : it.lootTables()) {
for (Item<?> item : lootTable.getRandomItems(contextHolder, world)) {
for (Item<?> item : lootTable.getRandomItems(contextHolder, world, null)) {
world.dropItemNaturally(vec3d, item);
}
}
@@ -334,7 +334,7 @@ public class BlockEventListener implements Listener {
if (yield < 1f) {
builder.withParameter(CommonParameters.EXPLOSION_RADIUS, 1.0f / yield);
}
for (Item<Object> item : state.getDrops(builder, world)) {
for (Item<Object> item : state.getDrops(builder, world, null)) {
world.dropItemNaturally(vec3d, item);
}
world.playBlockSound(vec3d, state.sounds().breakSound());

View File

@@ -40,7 +40,7 @@ public class FallingBlockRemoveListener implements Listener {
net.momirealms.craftengine.core.world.World world = new BukkitWorld(fallingBlock.getWorld());
builder.withParameter(CommonParameters.LOCATION, vec3d);
builder.withParameter(CommonParameters.WORLD, world);
for (Item<Object> item : immutableBlockState.getDrops(builder, world)) {
for (Item<Object> item : immutableBlockState.getDrops(builder, world, null)) {
world.dropItemNaturally(vec3d, item);
}
Object entityData = Reflections.field$Entity$entityData.get(fallingBlockEntity);

View File

@@ -73,7 +73,7 @@ public class BushBlockBehavior extends BukkitBlockBehavior {
net.momirealms.craftengine.core.world.World world = new BukkitWorld(FastNMS.INSTANCE.method$Level$getCraftWorld(level));
builder.withParameter(CommonParameters.LOCATION, vec3d);
builder.withParameter(CommonParameters.WORLD, world);
for (Item<Object> item : previousState.getDrops(builder, world)) {
for (Item<Object> item : previousState.getDrops(builder, world, null)) {
world.dropItemNaturally(vec3d, item);
}
world.playBlockSound(vec3d, previousState.sounds().breakSound());

View File

@@ -12,8 +12,8 @@ import net.momirealms.craftengine.core.block.UpdateOption;
import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory;
import net.momirealms.craftengine.core.block.properties.IntegerProperty;
import net.momirealms.craftengine.core.block.properties.Property;
import net.momirealms.craftengine.core.loot.LootContext;
import net.momirealms.craftengine.core.plugin.context.ContextHolder;
import net.momirealms.craftengine.core.plugin.context.SimpleContext;
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.CommonParameters;
@@ -145,12 +145,14 @@ public class CropBlockBehavior extends BushBlockBehavior {
int x = FastNMS.INSTANCE.field$Vec3i$x(pos);
int y = FastNMS.INSTANCE.field$Vec3i$y(pos);
int z = FastNMS.INSTANCE.field$Vec3i$z(pos);
net.momirealms.craftengine.core.world.World wrappedWorld = new BukkitWorld(world);
int i = this.getAge(immutableBlockState) + this.boneMealBonus.getInt(new LootContext(wrappedWorld, 1, ContextHolder.builder()
.withParameter(CommonParameters.WORLD, wrappedWorld)
.withParameter(CommonParameters.LOCATION, Vec3d.atCenterOf(new Vec3i(x, y, z)))
.build()));
int i = this.getAge(immutableBlockState) + this.boneMealBonus.getInt(
SimpleContext.of(
ContextHolder.builder()
.withParameter(CommonParameters.WORLD, new BukkitWorld(world))
.withParameter(CommonParameters.LOCATION, Vec3d.atCenterOf(new Vec3i(x, y, z)))
.build()
)
);
int maxAge = this.ageProperty.max;
if (i > maxAge) {
i = maxAge;

View File

@@ -99,7 +99,7 @@ public class FallingBlockBehavior extends BukkitBlockBehavior {
net.momirealms.craftengine.core.world.World world = new BukkitWorld(FastNMS.INSTANCE.method$Level$getCraftWorld(level));
builder.withParameter(CommonParameters.LOCATION, vec3d);
builder.withParameter(CommonParameters.WORLD, world);
for (Item<Object> item : immutableBlockState.getDrops(builder, world)) {
for (Item<Object> item : immutableBlockState.getDrops(builder, world, null)) {
world.dropItemNaturally(vec3d, item);
}
Object entityData = Reflections.field$Entity$entityData.get(fallingBlockEntity);

View File

@@ -127,7 +127,7 @@ public class LeavesBlockBehavior extends WaterLoggedBlockBehavior {
ContextHolder.Builder builder = ContextHolder.builder()
.withParameter(CommonParameters.LOCATION, vec3d)
.withParameter(CommonParameters.WORLD, world);
for (Item<Object> item : immutableBlockState.getDrops(builder, world)) {
for (Item<Object> item : immutableBlockState.getDrops(builder, world, null)) {
world.dropItemNaturally(vec3d, item);
}
}

View File

@@ -63,7 +63,7 @@ public class SugarCaneBlockBehavior extends BushBlockBehavior {
ContextHolder.Builder builder = ContextHolder.builder()
.withParameter(CommonParameters.LOCATION, vec3d)
.withParameter(CommonParameters.WORLD, world);
for (Item<Object> item : currentState.getDrops(builder, world)) {
for (Item<Object> item : currentState.getDrops(builder, world, null)) {
world.dropItemNaturally(vec3d, item);
}
world.playBlockSound(vec3d, currentState.sounds().breakSound());

View File

@@ -1,8 +1,10 @@
package net.momirealms.craftengine.bukkit.entity;
import net.momirealms.craftengine.bukkit.util.KeyUtils;
import net.momirealms.craftengine.bukkit.world.BukkitWorld;
import net.momirealms.craftengine.core.entity.Entity;
import net.momirealms.craftengine.core.util.Direction;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.world.World;
import java.lang.ref.WeakReference;
@@ -62,4 +64,9 @@ public class BukkitEntity extends Entity {
public org.bukkit.entity.Entity literalObject() {
return this.entity.get();
}
@Override
public Key type() {
return KeyUtils.namespacedKey2Key(literalObject().getType().getKey());
}
}

View File

@@ -6,7 +6,6 @@ import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
import net.momirealms.craftengine.bukkit.util.KeyUtils;
import net.momirealms.craftengine.bukkit.util.Reflections;
import net.momirealms.craftengine.bukkit.world.BukkitWorld;
import net.momirealms.craftengine.core.entity.player.InteractionHand;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.loot.AbstractVanillaLootManager;
import net.momirealms.craftengine.core.loot.LootTable;
@@ -70,16 +69,17 @@ public class BukkitVanillaLootManager extends AbstractVanillaLootManager impleme
ContextHolder.Builder builder = ContextHolder.builder();
builder.withParameter(CommonParameters.WORLD, world);
builder.withParameter(CommonParameters.LOCATION, vec3d);
BukkitServerPlayer optionalPlayer = null;
if (VersionHelper.isOrAbove1_20_5()) {
if (event.getDamageSource().getCausingEntity() instanceof Player player) {
BukkitServerPlayer serverPlayer = this.plugin.adapt(player);
builder.withParameter(CommonParameters.PLAYER, serverPlayer);
builder.withOptionalParameter(CommonParameters.TOOL, serverPlayer.getItemInHand(InteractionHand.MAIN_HAND));
optionalPlayer = this.plugin.adapt(player);
builder.withParameter(CommonParameters.PLAYER, optionalPlayer);
//mark item builder.withOptionalParameter(CommonParameters.MAIN_HAND_ITEM, serverPlayer.getItemInHand(InteractionHand.MAIN_HAND));
}
}
ContextHolder contextHolder = builder.build();
for (LootTable<?> lootTable : loot.lootTables()) {
for (Item<?> item : lootTable.getRandomItems(contextHolder, world)) {
for (Item<?> item : lootTable.getRandomItems(contextHolder, world, optionalPlayer)) {
world.dropItemNaturally(vec3d, item);
}
}

View File

@@ -75,6 +75,7 @@ public class BukkitCraftEngine extends CraftEngine {
super.classPathAppender = new ReflectionClassPathAppender(this);
super.scheduler = new BukkitSchedulerAdapter(this);
super.logger = new JavaPluginLogger(bootstrap.getLogger());
super.platform = new BukkitPlatform();
// find mod class if present
Class<?> modClass = ReflectionUtils.getClazz(MOD_CLASS);
if (modClass != null) {

View File

@@ -0,0 +1,12 @@
package net.momirealms.craftengine.bukkit.plugin;
import net.momirealms.craftengine.core.plugin.Platform;
import org.bukkit.Bukkit;
public class BukkitPlatform implements Platform {
@Override
public void dispatchCommand(String command) {
Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), command);
}
}

View File

@@ -26,6 +26,8 @@ import net.momirealms.craftengine.core.world.BlockPos;
import net.momirealms.craftengine.core.world.World;
import net.momirealms.craftengine.core.world.WorldEvents;
import org.bukkit.*;
import org.bukkit.attribute.Attribute;
import org.bukkit.attribute.AttributeInstance;
import org.bukkit.block.Block;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
@@ -800,4 +802,18 @@ public class BukkitServerPlayer extends Player {
this.resourcePackUUID.clear();
}
}
@Override
public void performCommand(String command) {
platformPlayer().performCommand(command);
}
@Override
public double luck() {
if (VersionHelper.isOrAbove1_21_3()) {
return Optional.ofNullable(platformPlayer().getAttribute(Attribute.LUCK)).map(AttributeInstance::getValue).orElse(1d);
} else {
return LegacyAttributeUtils.getLuck(platformPlayer());
}
}
}

View File

@@ -2,6 +2,7 @@ package net.momirealms.craftengine.core.block;
import it.unimi.dsi.fastutil.objects.Reference2ObjectArrayMap;
import net.momirealms.craftengine.core.block.properties.Property;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.loot.LootTable;
import net.momirealms.craftengine.core.plugin.context.ContextHolder;
@@ -12,6 +13,7 @@ import net.momirealms.craftengine.shared.block.BlockBehavior;
import net.momirealms.sparrow.nbt.CompoundTag;
import net.momirealms.sparrow.nbt.NBT;
import net.momirealms.sparrow.nbt.Tag;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.util.List;
@@ -138,12 +140,16 @@ public class ImmutableBlockState extends BlockStateHolder {
return state.with(property, (T) value);
}
public List<Item<Object>> getDrops(@NotNull ContextHolder.Builder builder, @NotNull World world) {
return this.getDrops(builder, world, null);
}
@SuppressWarnings("unchecked")
public List<Item<Object>> getDrops(ContextHolder.Builder builder, World world) {
public List<Item<Object>> getDrops(@NotNull ContextHolder.Builder builder, @NotNull World world, @Nullable Player player) {
CustomBlock block = owner.value();
if (block == null) return List.of();
LootTable<Object> lootTable = (LootTable<Object>) block.lootTable();
if (lootTable == null) return List.of();
return lootTable.getRandomItems(builder.withParameter(CommonParameters.BLOCK_STATE, this).build(), world);
return lootTable.getRandomItems(builder.withParameter(CommonParameters.BLOCK_STATE, this).build(), world, player);
}
}

View File

@@ -1,16 +1,24 @@
package net.momirealms.craftengine.core.entity;
import net.momirealms.craftengine.core.util.Direction;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.world.Vec3d;
import net.momirealms.craftengine.core.world.World;
public abstract class Entity {
public abstract Key type();
public abstract double x();
public abstract double y();
public abstract double z();
public Vec3d position() {
return new Vec3d(x(), y(), z());
}
public abstract void tick();
public abstract int entityID();

View File

@@ -11,6 +11,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
public abstract class Player extends Entity implements NetWorkUser {
private static final Key TYPE = Key.of("minecraft:player");
public abstract boolean isSecondaryUseActive();
@@ -84,4 +85,13 @@ public abstract class Player extends Entity implements NetWorkUser {
public abstract void clearView();
public abstract void unloadCurrentResourcePack();
public abstract void performCommand(String command);
public abstract double luck();
@Override
public Key type() {
return TYPE;
}
}

View File

@@ -185,15 +185,15 @@ public class CustomSmithingTransformRecipe<T> implements Recipe<T> {
throw new LocalizedResourceConfigException("warning.config.recipe.smithing_transform.post_processor.missing_type");
}
Key key = Key.withDefaultNamespace(type, Key.DEFAULT_NAMESPACE);
ItemDataProcessor.Factory factory = BuiltInRegistries.SMITHING_RESULT_PROCESSOR_FACTORY.getValue(key);
ItemDataProcessor.ProcessorFactory factory = BuiltInRegistries.SMITHING_RESULT_PROCESSOR_FACTORY.getValue(key);
if (factory == null) {
throw new LocalizedResourceConfigException("warning.config.recipe.smithing_transform.post_processor.invalid_type", type);
}
return factory.create(map);
}
public static void register(Key key, ItemDataProcessor.Factory factory) {
Holder.Reference<ItemDataProcessor.Factory> holder = ((WritableRegistry<ItemDataProcessor.Factory>) BuiltInRegistries.SMITHING_RESULT_PROCESSOR_FACTORY)
public static void register(Key key, ItemDataProcessor.ProcessorFactory factory) {
Holder.Reference<ItemDataProcessor.ProcessorFactory> holder = ((WritableRegistry<ItemDataProcessor.ProcessorFactory>) BuiltInRegistries.SMITHING_RESULT_PROCESSOR_FACTORY)
.registerForHolder(new ResourceKey<>(Registries.SMITHING_RESULT_PROCESSOR_FACTORY.location(), key));
holder.bindValue(factory);
}
@@ -203,7 +203,7 @@ public class CustomSmithingTransformRecipe<T> implements Recipe<T> {
Key type();
interface Factory {
interface ProcessorFactory {
ItemDataProcessor create(Map<String, Object> arguments);
}
}
@@ -231,7 +231,7 @@ public class CustomSmithingTransformRecipe<T> implements Recipe<T> {
return ItemDataProcessors.KEEP_COMPONENTS;
}
public static class Factory implements ItemDataProcessor.Factory {
public static class Factory implements ProcessorFactory {
@Override
public ItemDataProcessor create(Map<String, Object> arguments) {
@@ -268,7 +268,7 @@ public class CustomSmithingTransformRecipe<T> implements Recipe<T> {
return ItemDataProcessors.KEEP_TAGS;
}
public static class Factory implements ItemDataProcessor.Factory {
public static class Factory implements ProcessorFactory {
@Override
public ItemDataProcessor create(Map<String, Object> arguments) {

View File

@@ -1,6 +1,5 @@
package net.momirealms.craftengine.core.loot.condition;
package net.momirealms.craftengine.core.loot;
import net.momirealms.craftengine.core.loot.LootContext;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.condition.*;
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
@@ -8,7 +7,6 @@ import net.momirealms.craftengine.core.registry.BuiltInRegistries;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.registry.Registries;
import net.momirealms.craftengine.core.registry.WritableRegistry;
import net.momirealms.craftengine.core.util.Factory;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import net.momirealms.craftengine.core.util.ResourceKey;
@@ -31,10 +29,11 @@ public class LootConditions {
register(CommonConditions.INVERTED, new InvertedCondition.FactoryImpl<>(LootConditions::fromMap));
register(CommonConditions.FALLING_BLOCK, new FallingBlockCondition.FactoryImpl<>());
register(CommonConditions.RANDOM, new RandomCondition.FactoryImpl<>());
register(CommonConditions.DISTANCE, new DistanceCondition.FactoryImpl<>());
}
public static void register(Key key, Factory<Condition<LootContext>> factory) {
Holder.Reference<Factory<Condition<LootContext>>> holder = ((WritableRegistry<Factory<Condition<LootContext>>>) BuiltInRegistries.LOOT_CONDITION_FACTORY)
public static void register(Key key, ConditionFactory<LootContext> factory) {
Holder.Reference<ConditionFactory<LootContext>> holder = ((WritableRegistry<ConditionFactory<LootContext>>) BuiltInRegistries.LOOT_CONDITION_FACTORY)
.registerForHolder(new ResourceKey<>(Registries.LOOT_CONDITION_FACTORY.location(), key));
holder.bindValue(factory);
}
@@ -85,10 +84,18 @@ public class LootConditions {
public static Condition<LootContext> fromMap(Map<String, Object> map) {
String type = ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("type"), "warning.config.loot_table.condition.missing_type");
Key key = Key.withDefaultNamespace(type, Key.DEFAULT_NAMESPACE);
Factory<Condition<LootContext>> factory = BuiltInRegistries.LOOT_CONDITION_FACTORY.getValue(key);
if (factory == null) {
throw new LocalizedResourceConfigException("warning.config.loot_table.condition.invalid_type", type);
if (key.value().charAt(0) == '!') {
ConditionFactory<LootContext> factory = BuiltInRegistries.LOOT_CONDITION_FACTORY.getValue(new Key(key.namespace(), key.value().substring(1)));
if (factory == null) {
throw new LocalizedResourceConfigException("warning.config.loot_table.condition.invalid_type", type);
}
return new InvertedCondition<>(factory.create(map));
} else {
ConditionFactory<LootContext> factory = BuiltInRegistries.LOOT_CONDITION_FACTORY.getValue(key);
if (factory == null) {
throw new LocalizedResourceConfigException("warning.config.loot_table.condition.invalid_type", type);
}
return factory.create(map);
}
return factory.create(map);
}
}

View File

@@ -1,25 +1,38 @@
package net.momirealms.craftengine.core.loot;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.plugin.context.ContextHolder;
import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
import net.momirealms.craftengine.core.plugin.context.parameter.CommonParameters;
import net.momirealms.craftengine.core.world.World;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
public class LootContext extends PlayerOptionalContext {
private final World world;
private final float luck;
private Item<?> tempLoot;
public LootContext(World world, float luck, ContextHolder contexts) {
super(contexts.getOptional(CommonParameters.PLAYER).orElse(null), contexts);
public LootContext(@NotNull World world, @Nullable Player player, float luck, @NotNull ContextHolder contexts) {
super(player, contexts);
this.world = world;
this.luck = luck;
}
public float luck() {
return luck;
return this.luck;
}
public World world() {
return world;
return this.world;
}
public Item<?> tempLoot() {
return this.tempLoot;
}
public void setTempLoot(Item<?> tempLoot) {
this.tempLoot = tempLoot;
}
}

View File

@@ -2,7 +2,6 @@ package net.momirealms.craftengine.core.loot;
import com.google.common.collect.Lists;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.loot.condition.LootConditions;
import net.momirealms.craftengine.core.loot.entry.LootEntry;
import net.momirealms.craftengine.core.loot.entry.LootEntryContainer;
import net.momirealms.craftengine.core.loot.function.LootFunction;

View File

@@ -1,8 +1,8 @@
package net.momirealms.craftengine.core.loot;
import com.google.common.collect.Lists;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.loot.condition.LootConditions;
import net.momirealms.craftengine.core.loot.entry.LootEntryContainer;
import net.momirealms.craftengine.core.loot.entry.LootEntryContainers;
import net.momirealms.craftengine.core.loot.function.LootFunction;
@@ -79,7 +79,11 @@ public class LootTable<T> {
}
public ArrayList<Item<T>> getRandomItems(ContextHolder parameters, World world) {
return this.getRandomItems(new LootContext(world, 1, parameters));
return this.getRandomItems(parameters, world, null);
}
public ArrayList<Item<T>> getRandomItems(ContextHolder parameters, World world, @Nullable Player player) {
return this.getRandomItems(new LootContext(world, player, player == null ? 1f : (float) player.luck(), parameters));
}
private ArrayList<Item<T>> getRandomItems(LootContext context) {

View File

@@ -1,7 +1,7 @@
package net.momirealms.craftengine.core.loot.entry;
import net.momirealms.craftengine.core.loot.LootConditions;
import net.momirealms.craftengine.core.loot.LootContext;
import net.momirealms.craftengine.core.loot.condition.LootConditions;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.util.Key;

View File

@@ -1,7 +1,7 @@
package net.momirealms.craftengine.core.loot.entry;
import net.momirealms.craftengine.core.loot.LootConditions;
import net.momirealms.craftengine.core.loot.LootContext;
import net.momirealms.craftengine.core.loot.condition.LootConditions;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.number.NumberProvider;
import net.momirealms.craftengine.core.plugin.context.number.NumberProviders;

View File

@@ -1,8 +1,8 @@
package net.momirealms.craftengine.core.loot.entry;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.loot.LootConditions;
import net.momirealms.craftengine.core.loot.LootContext;
import net.momirealms.craftengine.core.loot.condition.LootConditions;
import net.momirealms.craftengine.core.loot.function.LootFunction;
import net.momirealms.craftengine.core.loot.function.LootFunctions;
import net.momirealms.craftengine.core.plugin.CraftEngine;

View File

@@ -2,10 +2,10 @@ package net.momirealms.craftengine.core.loot.function;
import net.momirealms.craftengine.core.item.Enchantment;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.loot.LootConditions;
import net.momirealms.craftengine.core.loot.LootContext;
import net.momirealms.craftengine.core.loot.condition.LootConditions;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.parameter.CommonParameters;
import net.momirealms.craftengine.core.plugin.context.parameter.PlayerParameters;
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
import net.momirealms.craftengine.core.registry.Holder;
@@ -18,12 +18,12 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
public class LootFunctionApplyBonusCount<T> extends AbstractLootConditionalFunction<T> {
public class ApplyBonusCountFunction<T> extends AbstractLootConditionalFunction<T> {
public static final Factory<?> FACTORY = new Factory<>();
private final Key enchantment;
private final Formula formula;
public LootFunctionApplyBonusCount(List<Condition<LootContext>> predicates, Key enchantment, Formula formula) {
public ApplyBonusCountFunction(List<Condition<LootContext>> predicates, Key enchantment, Formula formula) {
super(predicates);
this.enchantment = enchantment;
this.formula = formula;
@@ -31,7 +31,7 @@ public class LootFunctionApplyBonusCount<T> extends AbstractLootConditionalFunct
@Override
protected Item<T> applyInternal(Item<T> item, LootContext context) {
Optional<Item<?>> itemInHand = context.getOptionalParameter(CommonParameters.TOOL);
Optional<Item<?>> itemInHand = context.getOptionalParameter(PlayerParameters.MAIN_HAND_ITEM);
int level = itemInHand.map(value -> value.getEnchantment(this.enchantment).map(Enchantment::level).orElse(0)).orElse(0);
int newCount = this.formula.apply(item.count(), level);
item.count(newCount);
@@ -56,7 +56,7 @@ public class LootFunctionApplyBonusCount<T> extends AbstractLootConditionalFunct
List<Condition<LootContext>> conditions = Optional.ofNullable(arguments.get("conditions"))
.map(it -> LootConditions.fromMapList((List<Map<String, Object>>) it))
.orElse(Collections.emptyList());
return new LootFunctionApplyBonusCount<>(conditions, Key.from(enchantment), Formulas.fromMap(formulaMap));
return new ApplyBonusCountFunction<>(conditions, Key.from(enchantment), Formulas.fromMap(formulaMap));
}
}

View File

@@ -1,8 +1,8 @@
package net.momirealms.craftengine.core.loot.function;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.loot.LootConditions;
import net.momirealms.craftengine.core.loot.LootContext;
import net.momirealms.craftengine.core.loot.condition.LootConditions;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.number.NumberProvider;
import net.momirealms.craftengine.core.plugin.context.number.NumberProviders;
@@ -15,11 +15,11 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
public class LootFunctionDropExp<T> extends AbstractLootConditionalFunction<T> {
public class DropExpFunction<T> extends AbstractLootConditionalFunction<T> {
public static final Factory<?> FACTORY = new Factory<>();
private final NumberProvider value;
public LootFunctionDropExp(NumberProvider value, List<Condition<LootContext>> predicates) {
public DropExpFunction(NumberProvider value, List<Condition<LootContext>> predicates) {
super(predicates);
this.value = value;
}
@@ -44,7 +44,7 @@ public class LootFunctionDropExp<T> extends AbstractLootConditionalFunction<T> {
List<Condition<LootContext>> conditions = Optional.ofNullable(arguments.get("conditions"))
.map(it -> LootConditions.fromMapList((List<Map<String, Object>>) it))
.orElse(Collections.emptyList());
return new LootFunctionDropExp<>(NumberProviders.fromObject(value), conditions);
return new DropExpFunction<>(NumberProviders.fromObject(value), conditions);
}
}
}

View File

@@ -1,8 +1,8 @@
package net.momirealms.craftengine.core.loot.function;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.loot.LootConditions;
import net.momirealms.craftengine.core.loot.LootContext;
import net.momirealms.craftengine.core.loot.condition.LootConditions;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.parameter.CommonParameters;
import net.momirealms.craftengine.core.util.Key;
@@ -13,10 +13,10 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
public class LootFunctionExplosionDecay<T> extends AbstractLootConditionalFunction<T> {
public class ExplosionDecayFunction<T> extends AbstractLootConditionalFunction<T> {
public static final Factory<?> FACTORY = new Factory<>();
public LootFunctionExplosionDecay(List<Condition<LootContext>> predicates) {
public ExplosionDecayFunction(List<Condition<LootContext>> predicates) {
super(predicates);
}
@@ -49,7 +49,7 @@ public class LootFunctionExplosionDecay<T> extends AbstractLootConditionalFuncti
List<Condition<LootContext>> conditions = Optional.ofNullable(arguments.get("conditions"))
.map(it -> LootConditions.fromMapList((List<Map<String, Object>>) it))
.orElse(Collections.emptyList());
return new LootFunctionExplosionDecay<>(conditions);
return new ExplosionDecayFunction<>(conditions);
}
}
}

View File

@@ -23,10 +23,10 @@ public class LootFunctions {
public static final Key DROP_EXP = Key.from("craftengine:drop_exp");
static {
register(SET_COUNT, LootFunctionSetCount.FACTORY);
register(EXPLOSION_DECAY, LootFunctionExplosionDecay.FACTORY);
register(APPLY_BONUS, LootFunctionApplyBonusCount.FACTORY);
register(DROP_EXP, LootFunctionDropExp.FACTORY);
register(SET_COUNT, SetCountFunction.FACTORY);
register(EXPLOSION_DECAY, ExplosionDecayFunction.FACTORY);
register(APPLY_BONUS, ApplyBonusCountFunction.FACTORY);
register(DROP_EXP, DropExpFunction.FACTORY);
}
public static <T> void register(Key key, LootFunctionFactory<T> factory) {

View File

@@ -1,8 +1,8 @@
package net.momirealms.craftengine.core.loot.function;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.loot.LootConditions;
import net.momirealms.craftengine.core.loot.LootContext;
import net.momirealms.craftengine.core.loot.condition.LootConditions;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.number.NumberProvider;
import net.momirealms.craftengine.core.plugin.context.number.NumberProviders;
@@ -14,13 +14,13 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
public class LootFunctionSetCount<T> extends AbstractLootConditionalFunction<T> {
public class SetCountFunction<T> extends AbstractLootConditionalFunction<T> {
public static final Factory<?> FACTORY = new Factory<>();
private final NumberProvider value;
private final boolean add;
public LootFunctionSetCount(List<Condition<LootContext>> conditions, NumberProvider value, boolean add) {
public SetCountFunction(List<Condition<LootContext>> conditions, NumberProvider value, boolean add) {
super(conditions);
this.value = value;
this.add = add;
@@ -47,7 +47,7 @@ public class LootFunctionSetCount<T> extends AbstractLootConditionalFunction<T>
List<Condition<LootContext>> conditions = Optional.ofNullable(arguments.get("conditions"))
.map(it -> LootConditions.fromMapList((List<Map<String, Object>>) it))
.orElse(Collections.emptyList());
return new LootFunctionSetCount<>(conditions, NumberProviders.fromObject(value), add);
return new SetCountFunction<>(conditions, NumberProviders.fromObject(value), add);
}
}
}

View File

@@ -2,8 +2,8 @@ package net.momirealms.craftengine.core.pack.conflict.matcher;
import net.momirealms.craftengine.core.pack.conflict.PathContext;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.condition.ConditionFactory;
import net.momirealms.craftengine.core.plugin.locale.LocalizedException;
import net.momirealms.craftengine.core.util.Factory;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
@@ -27,7 +27,7 @@ public class PathMatcherContains implements Condition<PathContext> {
return PathMatchers.CONTAINS;
}
public static class FactoryImpl implements Factory<Condition<PathContext>> {
public static class FactoryImpl implements ConditionFactory<PathContext> {
@Override
public Condition<PathContext> create(Map<String, Object> arguments) {

View File

@@ -2,8 +2,8 @@ package net.momirealms.craftengine.core.pack.conflict.matcher;
import net.momirealms.craftengine.core.pack.conflict.PathContext;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.condition.ConditionFactory;
import net.momirealms.craftengine.core.plugin.locale.LocalizedException;
import net.momirealms.craftengine.core.util.Factory;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
@@ -27,7 +27,7 @@ public class PathMatcherExact implements Condition<PathContext> {
return PathMatchers.EXACT;
}
public static class FactoryImpl implements Factory<Condition<PathContext>> {
public static class FactoryImpl implements ConditionFactory<PathContext> {
@Override
public Condition<PathContext> create(Map<String, Object> arguments) {

View File

@@ -2,8 +2,8 @@ package net.momirealms.craftengine.core.pack.conflict.matcher;
import net.momirealms.craftengine.core.pack.conflict.PathContext;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.condition.ConditionFactory;
import net.momirealms.craftengine.core.plugin.locale.LocalizedException;
import net.momirealms.craftengine.core.util.Factory;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
@@ -27,7 +27,7 @@ public class PathMatcherFilename implements Condition<PathContext> {
return PathMatchers.FILENAME;
}
public static class FactoryImpl implements Factory<Condition<PathContext>> {
public static class FactoryImpl implements ConditionFactory<PathContext> {
@Override
public Condition<PathContext> create(Map<String, Object> arguments) {

View File

@@ -2,8 +2,8 @@ package net.momirealms.craftengine.core.pack.conflict.matcher;
import net.momirealms.craftengine.core.pack.conflict.PathContext;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.condition.ConditionFactory;
import net.momirealms.craftengine.core.plugin.locale.LocalizedException;
import net.momirealms.craftengine.core.util.Factory;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
@@ -30,7 +30,7 @@ public class PathMatcherParentPrefix implements Condition<PathContext> {
return PathMatchers.PARENT_PATH_PREFIX;
}
public static class FactoryImpl implements Factory<Condition<PathContext>> {
public static class FactoryImpl implements ConditionFactory<PathContext> {
@Override
public Condition<PathContext> create(Map<String, Object> arguments) {

View File

@@ -2,8 +2,8 @@ package net.momirealms.craftengine.core.pack.conflict.matcher;
import net.momirealms.craftengine.core.pack.conflict.PathContext;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.condition.ConditionFactory;
import net.momirealms.craftengine.core.plugin.locale.LocalizedException;
import net.momirealms.craftengine.core.util.Factory;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
@@ -30,7 +30,7 @@ public class PathMatcherParentSuffix implements Condition<PathContext> {
return PathMatchers.PARENT_PATH_SUFFIX;
}
public static class FactoryImpl implements Factory<Condition<PathContext>> {
public static class FactoryImpl implements ConditionFactory<PathContext> {
@Override
public Condition<PathContext> create(Map<String, Object> arguments) {

View File

@@ -2,16 +2,12 @@ package net.momirealms.craftengine.core.pack.conflict.matcher;
import net.momirealms.craftengine.core.pack.conflict.PathContext;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.condition.AllOfCondition;
import net.momirealms.craftengine.core.plugin.context.condition.AnyOfCondition;
import net.momirealms.craftengine.core.plugin.context.condition.InvertedCondition;
import net.momirealms.craftengine.core.plugin.context.condition.CommonConditions;
import net.momirealms.craftengine.core.plugin.context.condition.*;
import net.momirealms.craftengine.core.plugin.locale.LocalizedException;
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.registry.Registries;
import net.momirealms.craftengine.core.registry.WritableRegistry;
import net.momirealms.craftengine.core.util.Factory;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import net.momirealms.craftengine.core.util.ResourceKey;
@@ -40,8 +36,9 @@ public class PathMatchers {
register(CONTAINS, new PathMatcherContains.FactoryImpl());
}
public static void register(Key key, Factory<Condition<PathContext>> factory) {
Holder.Reference<Factory<Condition<PathContext>>> holder = ((WritableRegistry<Factory<Condition<PathContext>>>) BuiltInRegistries.PATH_MATCHER_FACTORY).registerForHolder(new ResourceKey<>(Registries.PATH_MATCHER_FACTORY.location(), key));
public static void register(Key key, ConditionFactory<PathContext> factory) {
Holder.Reference<ConditionFactory<PathContext>> holder = ((WritableRegistry<ConditionFactory<PathContext>>) BuiltInRegistries.PATH_MATCHER_FACTORY)
.registerForHolder(new ResourceKey<>(Registries.PATH_MATCHER_FACTORY.location(), key));
holder.bindValue(factory);
}
@@ -56,10 +53,18 @@ public class PathMatchers {
public static Condition<PathContext> fromMap(Map<String, Object> map) {
String type = ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("type"), () -> new LocalizedException("warning.config.conflict_matcher.missing_type"));
Key key = Key.withDefaultNamespace(type, Key.DEFAULT_NAMESPACE);
Factory<Condition<PathContext>> factory = BuiltInRegistries.PATH_MATCHER_FACTORY.getValue(key);
if (factory == null) {
throw new LocalizedException("warning.config.conflict_matcher.invalid_type", type);
if (key.value().charAt(0) == '!') {
ConditionFactory<PathContext> factory = BuiltInRegistries.PATH_MATCHER_FACTORY.getValue(new Key(key.namespace(), key.value().substring(1)));
if (factory == null) {
throw new LocalizedException("warning.config.conflict_matcher.invalid_type", type);
}
return new InvertedCondition<>(factory.create(map));
} else {
ConditionFactory<PathContext> factory = BuiltInRegistries.PATH_MATCHER_FACTORY.getValue(key);
if (factory == null) {
throw new LocalizedException("warning.config.conflict_matcher.invalid_type", type);
}
return factory.create(map);
}
return factory.create(map);
}
}

View File

@@ -2,8 +2,8 @@ package net.momirealms.craftengine.core.pack.conflict.matcher;
import net.momirealms.craftengine.core.pack.conflict.PathContext;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.condition.ConditionFactory;
import net.momirealms.craftengine.core.plugin.locale.LocalizedException;
import net.momirealms.craftengine.core.util.Factory;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
@@ -36,7 +36,7 @@ public class PathPatternMatcher implements Condition<PathContext> {
return pattern;
}
public static class FactoryImpl implements Factory<Condition<PathContext>> {
public static class FactoryImpl implements ConditionFactory<PathContext> {
@Override
public Condition<PathContext> create(Map<String, Object> arguments) {

View File

@@ -46,6 +46,7 @@ public abstract class CraftEngine implements Plugin {
protected PluginLogger logger;
protected Consumer<Supplier<String>> debugger = (s) -> {};
protected Config config;
protected Platform platform;
protected ClassPathAppender classPathAppender;
protected DependencyManager dependencyManager;
protected SchedulerAdapter<?> scheduler;
@@ -428,4 +429,9 @@ public abstract class CraftEngine implements Plugin {
public CompatibilityManager compatibilityManager() {
return compatibilityManager;
}
@Override
public Platform platform() {
return platform;
}
}

View File

@@ -0,0 +1,6 @@
package net.momirealms.craftengine.core.plugin;
public interface Platform {
void dispatchCommand(String command);
}

View File

@@ -90,4 +90,6 @@ public interface Plugin {
void debug(Supplier<String> message);
CompatibilityManager compatibilityManager();
Platform platform();
}

View File

@@ -23,7 +23,8 @@ public abstract class AbstractCommonContext implements Context {
@NotNull
public TagResolver[] tagResolvers() {
if (this.tagResolvers == null) {
this.tagResolvers = new TagResolver[]{ShiftTag.INSTANCE, ImageTag.INSTANCE, new I18NTag(this), new NamedArgumentTag(this), new PlaceholderTag(null)};
this.tagResolvers = new TagResolver[]{ShiftTag.INSTANCE, ImageTag.INSTANCE, new I18NTag(this), new NamedArgumentTag(this),
new PlaceholderTag(null), new ExpressionTag(this)};
}
return this.tagResolvers;
}
@@ -38,9 +39,10 @@ public abstract class AbstractCommonContext implements Context {
return this.contexts.getOrThrow(parameter);
}
@Override
public <T> AbstractCommonContext withParameter(ContextKey<T> parameter, T value) {
this.contexts.withParameter(parameter, value);
return this;
}
// It's not designed as mutable
// @Override
// public <T> AbstractCommonContext withParameter(ContextKey<T> parameter, T value) {
// this.contexts.withParameter(parameter, value);
// return this;
// }
}

View File

@@ -13,6 +13,4 @@ public interface Context {
<T> Optional<T> getOptionalParameter(ContextKey<T> parameter);
<T> T getParameterOrThrow(ContextKey<T> parameter);
<T> Context withParameter(ContextKey<T> parameter, T value);
}

View File

@@ -96,7 +96,7 @@ public class ContextHolder {
public <T> T getParameterOrThrow(ContextKey<T> parameter) {
Supplier<T> object = (Supplier<T>) this.params.get(parameter);
if (object == null) {
throw new NoSuchElementException(parameter.id().toString());
throw new NoSuchElementException(parameter.id());
} else {
return object.get();
}

View File

@@ -0,0 +1,20 @@
package net.momirealms.craftengine.core.plugin.context;
import net.momirealms.craftengine.core.entity.furniture.Furniture;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.plugin.context.parameter.CommonParameterProvider;
import net.momirealms.craftengine.core.plugin.context.parameter.PlayerParameterProvider;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class PlayerFurnitureActionContext extends PlayerOptionalContext {
public PlayerFurnitureActionContext(@NotNull Player player, @NotNull Furniture furniture, @NotNull ContextHolder contexts) {
super(player, contexts, List.of(new CommonParameterProvider(), new PlayerParameterProvider(player)));
}
public static PlayerFurnitureActionContext of(@NotNull Player player, @NotNull Furniture furniture, @NotNull ContextHolder contexts) {
return new PlayerFurnitureActionContext(player, furniture, contexts);
}
}

View File

@@ -14,7 +14,7 @@ import java.util.Map;
public class PlayerOptionalContext extends AbstractAdditionalParameterContext implements Context {
public static final PlayerOptionalContext EMPTY = new PlayerOptionalContext(null, ContextHolder.EMPTY);
private final Player player;
protected final Player player;
public PlayerOptionalContext(@Nullable Player player, @NotNull ContextHolder contexts) {
super(contexts, player == null ? List.of(new CommonParameterProvider()) : List.of(new CommonParameterProvider(), new PlayerParameterProvider(player)));
@@ -52,7 +52,7 @@ public class PlayerOptionalContext extends AbstractAdditionalParameterContext im
@NotNull
public TagResolver[] tagResolvers() {
if (this.tagResolvers == null) {
this.tagResolvers = new TagResolver[]{ShiftTag.INSTANCE, ImageTag.INSTANCE, new PlaceholderTag(this.player), new I18NTag(this), new NamedArgumentTag(this)};
this.tagResolvers = new TagResolver[]{ShiftTag.INSTANCE, ImageTag.INSTANCE, new PlaceholderTag(this.player), new I18NTag(this), new NamedArgumentTag(this), new ExpressionTag(this)};
}
return this.tagResolvers;
}

View File

@@ -0,0 +1,12 @@
package net.momirealms.craftengine.core.plugin.context;
import java.util.Optional;
public interface RelationalContext extends Context {
ContextHolder viewerContexts();
<T> Optional<T> getViewerOptionalParameter(ContextKey<T> parameter);
<T> T getViewerParameterOrThrow(ContextKey<T> parameter);
}

View File

@@ -0,0 +1,12 @@
package net.momirealms.craftengine.core.plugin.context;
public class SimpleContext extends AbstractCommonContext {
public SimpleContext(ContextHolder contexts) {
super(contexts);
}
public static SimpleContext of(ContextHolder contexts) {
return new SimpleContext(contexts);
}
}

View File

@@ -0,0 +1,67 @@
package net.momirealms.craftengine.core.plugin.context;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.plugin.text.minimessage.*;
import java.util.Optional;
public class ViewerContext implements RelationalContext {
private final Context owner;
private final PlayerOptionalContext viewer;
private TagResolver[] tagResolvers;
public ViewerContext(Context owner, PlayerOptionalContext viewer) {
this.owner = owner;
this.viewer = viewer;
}
public static ViewerContext of(Context owner, PlayerOptionalContext viewer) {
return new ViewerContext(owner, viewer);
}
@Override
public <T> Optional<T> getViewerOptionalParameter(ContextKey<T> parameter) {
return this.viewer.getOptionalParameter(parameter);
}
@Override
public ContextHolder viewerContexts() {
return this.viewer.contexts();
}
@Override
public <T> T getViewerParameterOrThrow(ContextKey<T> parameter) {
return this.viewer.getParameterOrThrow(parameter);
}
@Override
public ContextHolder contexts() {
return this.owner.contexts();
}
@Override
public <T> Optional<T> getOptionalParameter(ContextKey<T> parameter) {
return this.owner.getOptionalParameter(parameter);
}
@Override
public <T> T getParameterOrThrow(ContextKey<T> parameter) {
return this.owner.getParameterOrThrow(parameter);
}
@Override
public TagResolver[] tagResolvers() {
if (this.tagResolvers == null) {
Player optionalOwner = null;
if (this.owner instanceof PlayerOptionalContext context) {
optionalOwner = context.player();
}
this.tagResolvers = new TagResolver[]{ShiftTag.INSTANCE, ImageTag.INSTANCE,
new PlaceholderTag(optionalOwner), new ViewerPlaceholderTag(this.viewer.player()),
new NamedArgumentTag(this.owner), new ViewerNamedArgumentTag(this.viewer),
new I18NTag(this), new ExpressionTag(this)};
}
return this.tagResolvers;
}
}

View File

@@ -3,7 +3,6 @@ package net.momirealms.craftengine.core.plugin.context.condition;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.Context;
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
import net.momirealms.craftengine.core.util.Factory;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.MiscUtils;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
@@ -35,7 +34,7 @@ public class AllOfCondition<CTX extends Context> implements Condition<CTX> {
return CommonConditions.ALL_OF;
}
public static class FactoryImpl<CTX extends Context> implements Factory<Condition<CTX>> {
public static class FactoryImpl<CTX extends Context> implements ConditionFactory<CTX> {
private final Function<Map<String, Object>, Condition<CTX>> factory;
public FactoryImpl(Function<Map<String, Object>, Condition<CTX>> factory) {

View File

@@ -3,7 +3,6 @@ package net.momirealms.craftengine.core.plugin.context.condition;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.Context;
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
import net.momirealms.craftengine.core.util.Factory;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.MiscUtils;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
@@ -35,7 +34,7 @@ public class AnyOfCondition<CTX extends Context> implements Condition<CTX> {
return CommonConditions.ANY_OF;
}
public static class FactoryImpl<CTX extends Context> implements Factory<Condition<CTX>> {
public static class FactoryImpl<CTX extends Context> implements ConditionFactory<CTX> {
private final Function<Map<String, Object>, Condition<CTX>> factory;
public FactoryImpl(Function<Map<String, Object>, Condition<CTX>> factory) {

View File

@@ -16,4 +16,5 @@ public final class CommonConditions {
public static final Key RANDOM = Key.from("craftengine:random");
public static final Key ENCHANTMENT = Key.from("craftengine:enchantment");
public static final Key FALLING_BLOCK = Key.from("craftengine:falling_block");
public static final Key DISTANCE = Key.from("craftengine:distance");
}

View File

@@ -0,0 +1,11 @@
package net.momirealms.craftengine.core.plugin.context.condition;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.Context;
import java.util.Map;
public interface ConditionFactory<CTX extends Context> {
Condition<CTX> create(Map<String, Object> args);
}

View File

@@ -0,0 +1,65 @@
package net.momirealms.craftengine.core.plugin.context.condition;
import net.momirealms.craftengine.core.entity.player.Player;
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.CommonParameters;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.world.Vec3d;
import net.momirealms.craftengine.core.world.World;
import java.util.Map;
import java.util.Optional;
// TODO It's designed for players for the moment, better using entities
public class DistanceCondition<CTX extends Context> implements Condition<CTX> {
private final NumberProvider min;
private final NumberProvider max;
public DistanceCondition(NumberProvider min, NumberProvider max) {
this.max = max;
this.min = min;
}
@Override
public Key type() {
return CommonConditions.DISTANCE;
}
@Override
public boolean test(CTX ctx) {
float min = this.min.getFloat(ctx);
float max = this.max.getFloat(ctx);
Optional<Player> optionalPlayer = ctx.getOptionalParameter(CommonParameters.PLAYER);
World world = ctx.getParameterOrThrow(CommonParameters.WORLD);
Vec3d location = ctx.getParameterOrThrow(CommonParameters.LOCATION);
if (optionalPlayer.isEmpty()) {
return false;
}
Player player = optionalPlayer.get();
if (!player.world().uuid().equals(world.uuid())) {
return false;
}
double dx = location.x() - player.x();
double dy = location.y() - player.y();
double dz = location.z() - player.z();
double distanceSquared = dx * dx + dy * dy + dz * dz;
double minSquared = min * min;
double maxSquared = max * max;
return distanceSquared >= minSquared && distanceSquared <= maxSquared;
}
public static class FactoryImpl<CTX extends Context> implements ConditionFactory<CTX> {
@Override
public Condition<CTX> create(Map<String, Object> arguments) {
NumberProvider min = NumberProviders.fromObject(arguments.getOrDefault("min", 0));
NumberProvider max = NumberProviders.fromObject(arguments.getOrDefault("max", 32));
return new DistanceCondition<>(min, max);
}
}
}

View File

@@ -2,7 +2,6 @@ package net.momirealms.craftengine.core.plugin.context.condition;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.Context;
import net.momirealms.craftengine.core.util.Factory;
import net.momirealms.craftengine.core.util.Key;
import java.util.Map;
@@ -19,7 +18,7 @@ public class EmptyCondition<CTX extends Context> implements Condition<CTX> {
return true;
}
public static class FactoryImpl<CTX extends Context> implements Factory<Condition<CTX>> {
public static class FactoryImpl<CTX extends Context> implements ConditionFactory<CTX> {
@Override
public Condition<CTX> create(Map<String, Object> arguments) {

View File

@@ -4,9 +4,8 @@ import net.momirealms.craftengine.core.item.Enchantment;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.Context;
import net.momirealms.craftengine.core.plugin.context.parameter.CommonParameters;
import net.momirealms.craftengine.core.plugin.context.parameter.PlayerParameters;
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
import net.momirealms.craftengine.core.util.Factory;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
@@ -30,14 +29,14 @@ public class EnchantmentCondition<CTX extends Context> implements Condition<CTX>
@Override
public boolean test(CTX ctx) {
Optional<Item<?>> item = ctx.getOptionalParameter(CommonParameters.TOOL);
Optional<Item<?>> item = ctx.getOptionalParameter(PlayerParameters.MAIN_HAND_ITEM);
if (item.isEmpty()) return false;
Optional<Enchantment> enchantment = item.get().getEnchantment(id);
int level = enchantment.map(Enchantment::level).orElse(0);
return this.expression.apply(level);
}
public static class FactoryImpl<CTX extends Context> implements Factory<Condition<CTX>> {
public static class FactoryImpl<CTX extends Context> implements ConditionFactory<CTX> {
@Override
public Condition<CTX> create(Map<String, Object> arguments) {

View File

@@ -3,7 +3,6 @@ package net.momirealms.craftengine.core.plugin.context.condition;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.Context;
import net.momirealms.craftengine.core.plugin.context.parameter.CommonParameters;
import net.momirealms.craftengine.core.util.Factory;
import net.momirealms.craftengine.core.util.Key;
import java.util.Map;
@@ -20,7 +19,7 @@ public class FallingBlockCondition<CTX extends Context> implements Condition<CTX
return ctx.getOptionalParameter(CommonParameters.FALLING_BLOCK).orElse(false);
}
public static class FactoryImpl<CTX extends Context> implements Factory<Condition<CTX>> {
public static class FactoryImpl<CTX extends Context> implements ConditionFactory<CTX> {
@Override
public Condition<CTX> create(Map<String, Object> arguments) {

View File

@@ -3,7 +3,6 @@ package net.momirealms.craftengine.core.plugin.context.condition;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.Context;
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
import net.momirealms.craftengine.core.util.Factory;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.MiscUtils;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
@@ -30,7 +29,7 @@ public class InvertedCondition<CTX extends Context> implements Condition<CTX> {
return CommonConditions.INVERTED;
}
public static class FactoryImpl<CTX extends Context> implements Factory<Condition<CTX>> {
public static class FactoryImpl<CTX extends Context> implements ConditionFactory<CTX> {
private final Function<Map<String, Object>, Condition<CTX>> factory;
public FactoryImpl(Function<Map<String, Object>, Condition<CTX>> factory) {

View File

@@ -5,7 +5,10 @@ import net.momirealms.craftengine.core.block.properties.Property;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.Context;
import net.momirealms.craftengine.core.plugin.context.parameter.CommonParameters;
import net.momirealms.craftengine.core.util.*;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.MiscUtils;
import net.momirealms.craftengine.core.util.Pair;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import java.util.ArrayList;
import java.util.List;
@@ -41,7 +44,7 @@ public class MatchBlockPropertyCondition<CTX extends Context> implements Conditi
}).orElse(false);
}
public static class FactoryImpl<CTX extends Context> implements Factory<Condition<CTX>> {
public static class FactoryImpl<CTX extends Context> implements ConditionFactory<CTX> {
@Override
public Condition<CTX> create(Map<String, Object> arguments) {

View File

@@ -3,9 +3,8 @@ package net.momirealms.craftengine.core.plugin.context.condition;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.Context;
import net.momirealms.craftengine.core.plugin.context.parameter.CommonParameters;
import net.momirealms.craftengine.core.plugin.context.parameter.PlayerParameters;
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
import net.momirealms.craftengine.core.util.Factory;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.MiscUtils;
@@ -27,7 +26,7 @@ public class MatchItemCondition<CTX extends Context> implements Condition<CTX> {
@Override
public boolean test(CTX ctx) {
Optional<Item<?>> item = ctx.getOptionalParameter(CommonParameters.TOOL);
Optional<Item<?>> item = ctx.getOptionalParameter(PlayerParameters.MAIN_HAND_ITEM);
if (item.isEmpty()) return false;
Key key = item.get().id();
String itemId = key.toString();
@@ -43,7 +42,7 @@ public class MatchItemCondition<CTX extends Context> implements Condition<CTX> {
return false;
}
public static class FactoryImpl<CTX extends Context> implements Factory<Condition<CTX>> {
public static class FactoryImpl<CTX extends Context> implements ConditionFactory<CTX> {
@Override
public Condition<CTX> create(Map<String, Object> arguments) {

View File

@@ -4,17 +4,20 @@ 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.util.Factory;
import net.momirealms.craftengine.core.plugin.context.parameter.CommonParameters;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.RandomUtils;
import java.util.Map;
import java.util.Optional;
public class RandomCondition<CTX extends Context> implements Condition<CTX> {
private final NumberProvider chance;
private final boolean previous;
public RandomCondition(NumberProvider chance) {
public RandomCondition(NumberProvider chance, boolean previous) {
this.chance = chance;
this.previous = previous;
}
@Override
@@ -24,15 +27,25 @@ public class RandomCondition<CTX extends Context> implements Condition<CTX> {
@Override
public boolean test(CTX ctx) {
return RandomUtils.generateRandomFloat(0, 1) < this.chance.getFloat(ctx);
if (this.previous) {
// TODO This might produce bugs if the context doesn't use a common provider
Optional<Double> random = ctx.getOptionalParameter(CommonParameters.LAST_RANDOM);
return random.map(d -> d < this.chance.getFloat(ctx))
.orElseGet(() -> RandomUtils.generateRandomFloat(0, 1) < this.chance.getFloat(ctx));
} else {
Optional<Double> random = ctx.getOptionalParameter(CommonParameters.RANDOM);
return random.map(d -> d < this.chance.getFloat(ctx))
.orElseGet(() -> RandomUtils.generateRandomFloat(0, 1) < this.chance.getFloat(ctx));
}
}
public static class FactoryImpl<CTX extends Context> implements Factory<Condition<CTX>> {
public static class FactoryImpl<CTX extends Context> implements ConditionFactory<CTX> {
@Override
public Condition<CTX> create(Map<String, Object> arguments) {
NumberProvider provider = NumberProviders.fromObject(arguments.getOrDefault("value", 0.5f));
return new RandomCondition<>(provider);
boolean useLastRandom = Boolean.parseBoolean(arguments.getOrDefault("use-last", "false").toString());
return new RandomCondition<>(provider, useLastRandom);
}
}
}

View File

@@ -3,7 +3,6 @@ package net.momirealms.craftengine.core.plugin.context.condition;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.Context;
import net.momirealms.craftengine.core.plugin.context.parameter.CommonParameters;
import net.momirealms.craftengine.core.util.Factory;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.RandomUtils;
@@ -27,7 +26,7 @@ public class SurvivesExplosionCondition<CTX extends Context> implements Conditio
return true;
}
public static class FactoryImpl<CTX extends Context> implements Factory<Condition<CTX>> {
public static class FactoryImpl<CTX extends Context> implements ConditionFactory<CTX> {
@Override
public Condition<CTX> create(Map<String, Object> arguments) {

View File

@@ -4,9 +4,8 @@ import net.momirealms.craftengine.core.item.Enchantment;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.Context;
import net.momirealms.craftengine.core.plugin.context.parameter.CommonParameters;
import net.momirealms.craftengine.core.plugin.context.parameter.PlayerParameters;
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
import net.momirealms.craftengine.core.util.Factory;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.RandomUtils;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
@@ -32,13 +31,13 @@ public class TableBonusCondition<CTX extends Context> implements Condition<CTX>
@Override
public boolean test(CTX ctx) {
Optional<Item<?>> item = ctx.getOptionalParameter(CommonParameters.TOOL);
Optional<Item<?>> item = ctx.getOptionalParameter(PlayerParameters.MAIN_HAND_ITEM);
int level = item.map(value -> value.getEnchantment(this.enchantmentType).map(Enchantment::level).orElse(0)).orElse(0);
float f = this.values.get(Math.min(level, this.values.size() - 1));
return RandomUtils.generateRandomFloat(0, 1) < f;
}
public static class FactoryImpl<CTX extends Context> implements Factory<Condition<CTX>> {
public static class FactoryImpl<CTX extends Context> implements ConditionFactory<CTX> {
@Override
public Condition<CTX> create(Map<String, Object> arguments) {

View File

@@ -0,0 +1,55 @@
package net.momirealms.craftengine.core.plugin.context.function;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.Context;
import net.momirealms.craftengine.core.util.Factory;
import net.momirealms.craftengine.core.util.MCUtils;
import net.momirealms.craftengine.core.util.MiscUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
// TODO 将loot functions迁移过来
public abstract class AbstractConditionalFunction<CTX extends Context> implements Function<CTX> {
protected final List<Condition<CTX>> predicates;
private final Predicate<CTX> compositePredicates;
public AbstractConditionalFunction(List<Condition<CTX>> predicates) {
this.predicates = predicates;
this.compositePredicates = MCUtils.allOf(predicates);
}
@Override
public void run(CTX ctx) {
if (this.compositePredicates.test(ctx)) {
this.runInternal(ctx);
}
}
protected abstract void runInternal(CTX ctx);
public static abstract class AbstractFactory<CTX extends Context> implements Factory<Function<CTX>> {
private final java.util.function.Function<Map<String, Object>, Condition<CTX>> factory;
public AbstractFactory(java.util.function.Function<Map<String, Object>, Condition<CTX>> factory) {
this.factory = factory;
}
protected List<Condition<CTX>> getPredicates(Map<String, Object> arguments) {
Object predicates = arguments.get("conditions");
if (predicates == null) return List.of();
if (predicates instanceof List<?> list) {
List<Condition<CTX>> conditions = new ArrayList<>(list.size());
for (Object o : list) {
conditions.add(factory.apply(MiscUtils.castToMap(o, false)));
}
return conditions;
} else if (predicates instanceof Map<?,?> map) {
return List.of(factory.apply(MiscUtils.castToMap(map, false)));
}
throw new IllegalArgumentException("Unsupported condition type: " + predicates.getClass().getSimpleName());
}
}
}

View File

@@ -0,0 +1,78 @@
package net.momirealms.craftengine.core.plugin.context.function;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.Platform;
import net.momirealms.craftengine.core.plugin.context.*;
import net.momirealms.craftengine.core.plugin.context.parameter.CommonParameters;
import net.momirealms.craftengine.core.plugin.context.selector.PlayerSelector;
import net.momirealms.craftengine.core.plugin.context.selector.PlayerSelectors;
import net.momirealms.craftengine.core.plugin.context.text.TextProvider;
import net.momirealms.craftengine.core.plugin.context.text.TextProviders;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.MiscUtils;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Map;
import java.util.Optional;
public class CommandFunction<CTX extends Context> extends AbstractConditionalFunction<CTX> {
private final List<TextProvider> command;
private final boolean asPlayer;
private final PlayerSelector<CTX> selector;
public CommandFunction(List<Condition<CTX>> predicates, List<TextProvider> command, boolean asPlayer, @Nullable PlayerSelector<CTX> selector) {
super(predicates);
this.asPlayer = asPlayer;
this.command = command;
this.selector = selector;
}
@Override
public void runInternal(CTX ctx) {
if (this.asPlayer) {
Optional<Player> owner = ctx.getOptionalParameter(CommonParameters.PLAYER);
if (this.selector == null) {
owner.ifPresent(it -> {
for (TextProvider c : this.command) {
it.performCommand(c.get(ctx));
}
});
} else {
for (Player viewer : this.selector.get(ctx)) {
RelationalContext relationalContext = ViewerContext.of(ctx, PlayerOptionalContext.of(viewer, ContextHolder.EMPTY));
for (TextProvider c : this.command) {
viewer.performCommand(c.get(relationalContext));
}
}
}
} else {
Platform platform = CraftEngine.instance().platform();
for (TextProvider c : this.command) {
platform.dispatchCommand(c.get(ctx));
}
}
}
@Override
public Key type() {
return CommonFunctions.COMMAND;
}
public static class FactoryImpl<CTX extends Context> extends AbstractFactory<CTX> {
public FactoryImpl(java.util.function.Function<Map<String, Object>, Condition<CTX>> factory) {
super(factory);
}
@Override
public Function<CTX> create(Map<String, Object> arguments) {
Object command = ResourceConfigUtils.requireNonNullOrThrow(ResourceConfigUtils.get(arguments, "command", "commands"), "warning.config.function.command.missing_command");
List<TextProvider> commands = MiscUtils.getAsStringList(command).stream().map(TextProviders::fromString).toList();
boolean asPlayer = (boolean) arguments.getOrDefault("as-player", false);
return new CommandFunction<>(getPredicates(arguments), commands, asPlayer, PlayerSelectors.fromObject(arguments.get("target")));
}
}
}

View File

@@ -0,0 +1,8 @@
package net.momirealms.craftengine.core.plugin.context.function;
import net.momirealms.craftengine.core.util.Key;
public class CommonFunctions {
public static final Key COMMAND = Key.of("craftengine:command");
}

View File

@@ -0,0 +1,11 @@
package net.momirealms.craftengine.core.plugin.context.function;
import net.momirealms.craftengine.core.plugin.context.Context;
import net.momirealms.craftengine.core.util.Key;
public interface Function<CTX extends Context> {
void run(CTX ctx);
Key type();
}

View File

@@ -2,7 +2,6 @@ package net.momirealms.craftengine.core.plugin.context.parameter;
import net.momirealms.craftengine.core.block.ImmutableBlockState;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.plugin.context.ContextKey;
import net.momirealms.craftengine.core.world.Vec3d;
import net.momirealms.craftengine.core.world.World;
@@ -17,6 +16,5 @@ public final class CommonParameters {
public static final ContextKey<Boolean> FALLING_BLOCK = ContextKey.of("falling_block");
public static final ContextKey<Float> EXPLOSION_RADIUS = ContextKey.of("explosion_radius");
public static final ContextKey<Player> PLAYER = ContextKey.of("player");
public static final ContextKey<Item<?>> TOOL = ContextKey.of("tool");
public static final ContextKey<ImmutableBlockState> BLOCK_STATE = ContextKey.of("block_state");
}

View File

@@ -1,6 +1,7 @@
package net.momirealms.craftengine.core.plugin.context.parameter;
import net.momirealms.craftengine.core.entity.Entity;
import net.momirealms.craftengine.core.entity.player.InteractionHand;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.plugin.context.ContextKey;
import net.momirealms.craftengine.core.plugin.context.LazyContextParameterProvider;
@@ -19,12 +20,15 @@ public class PlayerParameterProvider implements LazyContextParameterProvider {
CONTEXT_FUNCTIONS.put(PlayerParameters.X, Entity::x);
CONTEXT_FUNCTIONS.put(PlayerParameters.Y, Entity::y);
CONTEXT_FUNCTIONS.put(PlayerParameters.Z, Entity::z);
CONTEXT_FUNCTIONS.put(PlayerParameters.POS, Entity::position);
CONTEXT_FUNCTIONS.put(PlayerParameters.BLOCK_X, p -> MCUtils.fastFloor(p.x()));
CONTEXT_FUNCTIONS.put(PlayerParameters.BLOCK_Y, p -> MCUtils.fastFloor(p.y()));
CONTEXT_FUNCTIONS.put(PlayerParameters.BLOCK_Z, p -> MCUtils.fastFloor(p.z()));
CONTEXT_FUNCTIONS.put(PlayerParameters.NAME, Player::name);
CONTEXT_FUNCTIONS.put(PlayerParameters.UUID, Player::uuid);
CONTEXT_FUNCTIONS.put(PlayerParameters.WORLD_NAME, p -> p.world().name());
CONTEXT_FUNCTIONS.put(PlayerParameters.MAIN_HAND_ITEM, p -> p.getItemInHand(InteractionHand.MAIN_HAND));
CONTEXT_FUNCTIONS.put(PlayerParameters.OFF_HAND_ITEM, p -> p.getItemInHand(InteractionHand.OFF_HAND));
}
private final Player player;

View File

@@ -1,6 +1,8 @@
package net.momirealms.craftengine.core.plugin.context.parameter;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.plugin.context.ContextKey;
import net.momirealms.craftengine.core.world.Vec3d;
import java.util.UUID;
@@ -10,10 +12,13 @@ public final class PlayerParameters {
public static final ContextKey<Double> X = ContextKey.of("player.x");
public static final ContextKey<Double> Y = ContextKey.of("player.y");
public static final ContextKey<Double> Z = ContextKey.of("player.z");
public static final ContextKey<Vec3d> POS = ContextKey.of("player.pos");
public static final ContextKey<Integer> BLOCK_X = ContextKey.of("player.block_x");
public static final ContextKey<Integer> BLOCK_Y = ContextKey.of("player.block_y");
public static final ContextKey<Integer> BLOCK_Z = ContextKey.of("player.block_z");
public static final ContextKey<String> NAME = ContextKey.of("player.name");
public static final ContextKey<String> WORLD_NAME = ContextKey.of("player.world.name");
public static final ContextKey<UUID> UUID = ContextKey.of("player.uuid");
public static final ContextKey<Item<?>> MAIN_HAND_ITEM = ContextKey.of("player.main_hand");
public static final ContextKey<Item<?>> OFF_HAND_ITEM = ContextKey.of("player.off_hand");
}

View File

@@ -0,0 +1,58 @@
package net.momirealms.craftengine.core.plugin.context.selector;
import net.momirealms.craftengine.core.entity.player.Player;
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.ContextHolder;
import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
import net.momirealms.craftengine.core.plugin.context.parameter.CommonParameters;
import net.momirealms.craftengine.core.util.Key;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class AllPlayerSelector<CTX extends Context> implements PlayerSelector<CTX> {
private final List<Condition<CTX>> predicates;
public AllPlayerSelector(List<Condition<CTX>> predicates) {
this.predicates = predicates;
}
public AllPlayerSelector() {
this.predicates = List.of();
}
public List<Condition<CTX>> predicates() {
return predicates;
}
@SuppressWarnings("unchecked")
@Override
public List<Player> get(CTX context) {
if (this.predicates.isEmpty()) {
return Arrays.asList(CraftEngine.instance().networkManager().onlineUsers());
} else {
List<Player> players = new ArrayList<>();
outer: for (Player player : CraftEngine.instance().networkManager().onlineUsers()) {
PlayerOptionalContext newContext = PlayerOptionalContext.of(player, ContextHolder.builder()
.withOptionalParameter(CommonParameters.WORLD, context.getOptionalParameter(CommonParameters.WORLD).orElse(null))
.withOptionalParameter(CommonParameters.LOCATION, context.getOptionalParameter(CommonParameters.LOCATION).orElse(null))
);
for (Condition<CTX> predicate : this.predicates) {
if (!predicate.test((CTX) newContext)) {
continue outer;
}
}
players.add(player);
}
return players;
}
}
@Override
public Key type() {
return PlayerSelectors.ALL;
}
}

View File

@@ -0,0 +1,14 @@
package net.momirealms.craftengine.core.plugin.context.selector;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.plugin.context.Context;
import net.momirealms.craftengine.core.util.Key;
import java.util.List;
public interface PlayerSelector<CTX extends Context> {
List<Player> get(CTX context);
Key type();
}

View File

@@ -0,0 +1,21 @@
package net.momirealms.craftengine.core.plugin.context.selector;
import net.momirealms.craftengine.core.plugin.context.Context;
import net.momirealms.craftengine.core.util.Key;
public class PlayerSelectors {
public static final Key ALL = Key.of("craftengine:all");
public static final Key SELF = Key.of("craftengine:self");
public static <CTX extends Context> PlayerSelector<CTX> fromObject(Object object) {
if (object == null) return null;
if (object instanceof String string) {
if (string.equals("self") || string.equals("@self") || string.equals("@s")) {
return new SelfPlayerSelector<>();
} else if (string.equals("all") || string.equals("@all") || string.equals("@a")) {
return new AllPlayerSelector<>();
}
}
throw new UnsupportedOperationException("Not supported yet.");
}
}

View File

@@ -0,0 +1,21 @@
package net.momirealms.craftengine.core.plugin.context.selector;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.plugin.context.Context;
import net.momirealms.craftengine.core.plugin.context.parameter.CommonParameters;
import net.momirealms.craftengine.core.util.Key;
import java.util.List;
public class SelfPlayerSelector<CTX extends Context> implements PlayerSelector<CTX> {
@Override
public List<Player> get(CTX context) {
return List.of(context.getParameterOrThrow(CommonParameters.PLAYER));
}
@Override
public Key type() {
return PlayerSelectors.SELF;
}
}

View File

@@ -0,0 +1,26 @@
package net.momirealms.craftengine.core.plugin.context.text;
import net.momirealms.craftengine.core.plugin.context.Context;
import net.momirealms.craftengine.core.util.Key;
public class PlainTextProvider implements TextProvider {
private final String text;
public PlainTextProvider(String text) {
this.text = text;
}
public static PlainTextProvider of(String text) {
return new PlainTextProvider(text);
}
@Override
public String get(Context context) {
return this.text;
}
@Override
public Key type() {
return TextProviders.PLAIN;
}
}

View File

@@ -0,0 +1,29 @@
package net.momirealms.craftengine.core.plugin.context.text;
import net.kyori.adventure.text.Component;
import net.momirealms.craftengine.core.plugin.context.Context;
import net.momirealms.craftengine.core.util.AdventureHelper;
import net.momirealms.craftengine.core.util.Key;
public class TagTextProvider implements TextProvider {
private final String text;
public TagTextProvider(String text) {
this.text = text;
}
public static TagTextProvider of(String text) {
return new TagTextProvider(text);
}
@Override
public String get(Context context) {
Component resultComponent = AdventureHelper.customMiniMessage().deserialize(this.text, context.tagResolvers());
return AdventureHelper.plainTextContent(resultComponent);
}
@Override
public Key type() {
return TextProviders.TAG;
}
}

View File

@@ -0,0 +1,11 @@
package net.momirealms.craftengine.core.plugin.context.text;
import net.momirealms.craftengine.core.plugin.context.Context;
import net.momirealms.craftengine.core.util.Key;
public interface TextProvider {
String get(Context context);
Key type();
}

View File

@@ -0,0 +1,15 @@
package net.momirealms.craftengine.core.plugin.context.text;
import net.momirealms.craftengine.core.util.Key;
public class TextProviders {
public static final Key PLAIN = Key.of("craftengine:plain");
public static final Key TAG = Key.of("craftengine:tag");
public static TextProvider fromString(String string) {
if (!string.contains("<") || !string.contains(">")) {
return PlainTextProvider.of(string);
}
return TagTextProvider.of(string);
}
}

View File

@@ -0,0 +1,33 @@
package net.momirealms.craftengine.core.plugin.event;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.PlayerBlockActionContext;
import net.momirealms.craftengine.core.plugin.context.condition.InvertedCondition;
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
import net.momirealms.craftengine.core.util.Factory;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import java.util.Map;
public class BlockEventConditions {
public static Condition<PlayerBlockActionContext> fromMap(Map<String, Object> map) {
String type = ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("type"), "TODO I18N");
Key key = Key.withDefaultNamespace(type, Key.DEFAULT_NAMESPACE);
if (key.value().charAt(0) == '!') {
Factory<Condition<PlayerBlockActionContext>> factory = BuiltInRegistries.PLAYER_BLOCK_CONDITION_FACTORY.getValue(new Key(key.namespace(), key.value().substring(1)));
if (factory == null) {
throw new LocalizedResourceConfigException("TODO I18N", type);
}
return new InvertedCondition<>(factory.create(map));
} else {
Factory<Condition<PlayerBlockActionContext>> factory = BuiltInRegistries.PLAYER_BLOCK_CONDITION_FACTORY.getValue(key);
if (factory == null) {
throw new LocalizedResourceConfigException("TODO I18N", type);
}
return factory.create(map);
}
}
}

View File

@@ -0,0 +1,40 @@
package net.momirealms.craftengine.core.plugin.event;
import net.momirealms.craftengine.core.plugin.context.PlayerBlockActionContext;
import net.momirealms.craftengine.core.plugin.context.function.CommandFunction;
import net.momirealms.craftengine.core.plugin.context.function.CommonFunctions;
import net.momirealms.craftengine.core.plugin.context.function.Function;
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.registry.Registries;
import net.momirealms.craftengine.core.registry.WritableRegistry;
import net.momirealms.craftengine.core.util.Factory;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import net.momirealms.craftengine.core.util.ResourceKey;
import java.util.Map;
public class BlockEventFunctions {
static {
register(CommonFunctions.COMMAND, new CommandFunction.FactoryImpl<>(BlockEventConditions::fromMap));
}
public static <T> void register(Key key, Factory<Function<PlayerBlockActionContext>> factory) {
Holder.Reference<Factory<Function<PlayerBlockActionContext>>> holder = ((WritableRegistry<Factory<Function<PlayerBlockActionContext>>>) BuiltInRegistries.PLAYER_BLOCK_FUNCTION_FACTORY)
.registerForHolder(new ResourceKey<>(Registries.PLAYER_BLOCK_FUNCTION_FACTORY.location(), key));
holder.bindValue(factory);
}
public static Function<PlayerBlockActionContext> fromMap(Map<String, Object> map) {
String type = ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("type"), "TODO I18N");
Key key = Key.withDefaultNamespace(type, Key.DEFAULT_NAMESPACE);
Factory<Function<PlayerBlockActionContext>> factory = BuiltInRegistries.PLAYER_BLOCK_FUNCTION_FACTORY.getValue(key);
if (factory == null) {
throw new LocalizedResourceConfigException("TODO I18N", type);
}
return factory.create(map);
}
}

View File

@@ -0,0 +1,8 @@
package net.momirealms.craftengine.core.plugin.event;
public enum EventTrigger {
USE_ITEM,
USE_ITEM_ON,
CONSUME,
}

View File

@@ -1,15 +0,0 @@
package net.momirealms.craftengine.core.plugin.event;
import net.momirealms.craftengine.core.util.Key;
public class Trigger {
private final Key id;
public Trigger(Key id) {
this.id = id;
}
public Key id() {
return id;
}
}

View File

@@ -1,21 +0,0 @@
package net.momirealms.craftengine.core.plugin.event;
import net.momirealms.craftengine.core.util.Key;
import java.util.HashMap;
import java.util.Map;
public class Triggers {
public static final Map<Key, Trigger> TRIGGERS = new HashMap<>();
public static final Trigger USE_ITEM = create(Key.of("use_item"));
public static final Trigger INTERACT = create(Key.of("interact"));
public static final Trigger CONSUME = create(Key.of("consume"));
public static final Trigger BREAK = create(Key.of("break"));
private static Trigger create(Key id) {
Trigger trigger = new Trigger(id);
TRIGGERS.put(id, trigger);
return trigger;
}
}

View File

@@ -19,7 +19,7 @@ public interface NetworkManager extends Manageable {
Channel getChannel(Player player);
NetWorkUser[] onlineUsers();
Player[] onlineUsers();
default void sendPacket(@NotNull NetWorkUser player, Object packet) {
sendPacket(player, packet, false);

View File

@@ -0,0 +1,59 @@
package net.momirealms.craftengine.core.plugin.text.minimessage;
import com.ezylang.evalex.EvaluationException;
import com.ezylang.evalex.Expression;
import com.ezylang.evalex.parser.ParseException;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.Context;
import net.kyori.adventure.text.minimessage.ParsingException;
import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.ArgumentQueue;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import net.momirealms.craftengine.core.util.AdventureHelper;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;
import java.util.Objects;
public class ExpressionTag implements TagResolver {
private final net.momirealms.craftengine.core.plugin.context.Context context;
public ExpressionTag(@NotNull net.momirealms.craftengine.core.plugin.context.Context context) {
this.context = Objects.requireNonNull(context, "context");
}
@Override
public @Nullable Tag resolve(@NotNull String name, @NotNull ArgumentQueue arguments, @NotNull Context ctx) throws ParsingException {
if (!has(name)) {
return null;
}
String format = arguments.popOr("No format provided").toString();
String expr = arguments.popOr("No expression provided").toString();
Component resultComponent = AdventureHelper.customMiniMessage().deserialize(expr, context.tagResolvers());
String resultString = AdventureHelper.plainTextContent(resultComponent);
Expression expression = new Expression(resultString);
try {
Number numberValue = expression.evaluate().getNumberValue();
DecimalFormat df = new DecimalFormat(format);
DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.US);
df.setDecimalFormatSymbols(symbols);
String formatted = df.format(numberValue);
return Tag.selfClosingInserting(Component.text(formatted));
} catch (IllegalArgumentException e) {
throw ctx.newException("Invalid number format: " + format, arguments);
} catch (EvaluationException | ParseException e) {
throw ctx.newException("Invalid expression: " + e.getMessage(), arguments);
}
}
@Override
public boolean has(@NotNull String name) {
return "expr".equals(name);
}
}

View File

@@ -24,11 +24,11 @@ public class I18NTag implements TagResolver {
}
String i18nKey = arguments.popOr("No argument i18n key provided").toString();
String translation = TranslationManager.instance().miniMessageTranslation(i18nKey);
return Tag.inserting(AdventureHelper.miniMessage().deserialize(translation, this.context.tagResolvers()));
return Tag.selfClosingInserting(AdventureHelper.miniMessage().deserialize(translation, this.context.tagResolvers()));
}
@Override
public boolean has(@NotNull String name) {
return "i18n".equals(name) || "l10n".equals(name);
return "i18n".equals(name);
}
}

View File

@@ -34,9 +34,9 @@ public class ImageTag implements TagResolver {
if (arguments.hasNext()) {
int row = arguments.popOr("No argument row provided").asInt().orElseThrow(() -> ctx.newException("Invalid argument number", arguments));
int column = arguments.popOr("No argument column provided").asInt().orElseThrow(() -> ctx.newException("Invalid argument number", arguments));
return Tag.inserting(Component.empty().children(List.of(optional.get().componentAt(row,column))));
return Tag.selfClosingInserting(Component.empty().children(List.of(optional.get().componentAt(row,column))));
} else {
return Tag.inserting(Component.empty().children(List.of(optional.get().componentAt(0,0))));
return Tag.selfClosingInserting(Component.empty().children(List.of(optional.get().componentAt(0,0))));
}
} else {
throw ctx.newException("Invalid image id", arguments);

View File

@@ -13,9 +13,6 @@ import java.util.List;
import java.util.Objects;
public class IndexedArgumentTag implements TagResolver {
private static final String NAME_0 = "argument";
private static final String NAME_1 = "arg";
private final List<? extends ComponentLike> argumentComponents;
public IndexedArgumentTag(@NotNull List<? extends ComponentLike> argumentComponents) {
@@ -39,6 +36,6 @@ public class IndexedArgumentTag implements TagResolver {
@Override
public boolean has(@NotNull String name) {
return name.equals(NAME_0) || name.equals(NAME_1);
return name.equals("arg");
}
}

View File

@@ -14,9 +14,6 @@ import java.util.Objects;
import java.util.Optional;
public class NamedArgumentTag implements TagResolver {
private static final String NAME_0 = "argument";
private static final String NAME_1 = "arg";
private final Context context;
public NamedArgumentTag(@NotNull Context context) {
@@ -39,6 +36,6 @@ public class NamedArgumentTag implements TagResolver {
@Override
public boolean has(@NotNull String name) {
return name.equals(NAME_0) || name.equals(NAME_1);
return name.equals("arg");
}
}

View File

@@ -28,7 +28,7 @@ public class PlaceholderTag implements TagResolver {
if (parsed.equals(placeholder)) {
parsed = arguments.popOr("No default papi value provided").toString();
}
return Tag.inserting(AdventureHelper.miniMessage().deserialize(parsed));
return Tag.selfClosingInserting(AdventureHelper.miniMessage().deserialize(parsed));
}
@Override

View File

@@ -25,7 +25,7 @@ public class ShiftTag implements TagResolver {
String shiftAmount = arguments.popOr("No argument shift provided").toString();
try {
int shift = Integer.parseInt(shiftAmount);
return Tag.inserting(AdventureHelper.miniMessage().deserialize(CraftEngine.instance().fontManager().createMiniMessageOffsets(shift)));
return Tag.selfClosingInserting(AdventureHelper.miniMessage().deserialize(CraftEngine.instance().fontManager().createMiniMessageOffsets(shift)));
} catch (NumberFormatException e) {
throw ctx.newException("Invalid shift value", arguments);
}

View File

@@ -0,0 +1,16 @@
package net.momirealms.craftengine.core.plugin.text.minimessage;
import net.momirealms.craftengine.core.plugin.context.Context;
import org.jetbrains.annotations.NotNull;
public class ViewerNamedArgumentTag extends NamedArgumentTag {
public ViewerNamedArgumentTag(@NotNull Context context) {
super(context);
}
@Override
public boolean has(@NotNull String name) {
return name.equals("viewer_arg");
}
}

View File

@@ -0,0 +1,17 @@
package net.momirealms.craftengine.core.plugin.text.minimessage;
import net.momirealms.craftengine.core.entity.player.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class ViewerPlaceholderTag extends PlaceholderTag {
public ViewerPlaceholderTag(@Nullable Player player) {
super(player);
}
@Override
public boolean has(@NotNull String name) {
return "viewer_papi".equals(name);
}
}

View File

@@ -9,7 +9,7 @@ import net.momirealms.craftengine.core.item.recipe.CustomSmithingTransformRecipe
import net.momirealms.craftengine.core.item.recipe.RecipeFactory;
import net.momirealms.craftengine.core.loot.LootContext;
import net.momirealms.craftengine.core.loot.entry.LootEntryContainerFactory;
import net.momirealms.craftengine.core.loot.function.LootFunctionApplyBonusCount;
import net.momirealms.craftengine.core.loot.function.ApplyBonusCountFunction;
import net.momirealms.craftengine.core.loot.function.LootFunctionFactory;
import net.momirealms.craftengine.core.pack.conflict.PathContext;
import net.momirealms.craftengine.core.pack.conflict.resolution.ResolutionFactory;
@@ -22,6 +22,9 @@ import net.momirealms.craftengine.core.pack.model.special.SpecialModelFactory;
import net.momirealms.craftengine.core.pack.model.tint.TintFactory;
import net.momirealms.craftengine.core.plugin.config.template.TemplateArgumentFactory;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.PlayerBlockActionContext;
import net.momirealms.craftengine.core.plugin.context.condition.ConditionFactory;
import net.momirealms.craftengine.core.plugin.context.function.Function;
import net.momirealms.craftengine.core.plugin.context.number.NumberProvider;
import net.momirealms.craftengine.core.util.Factory;
import net.momirealms.craftengine.core.util.Key;
@@ -30,13 +33,13 @@ import net.momirealms.craftengine.core.util.ResourceKey;
public class BuiltInRegistries {
public static final Registry<CustomBlock> BLOCK = createRegistry(Registries.BLOCK);
public static final Registry<Key> OPTIMIZED_ITEM_ID = createRegistry(Registries.OPTIMIZED_ITEM_ID);
public static final Registry<PropertyFactory> PROPERTY_FACTORY = createRegistry(Registries.PROPERTY_FACTORY);
public static final Registry<BlockBehaviorFactory> BLOCK_BEHAVIOR_FACTORY = createRegistry(Registries.BLOCK_BEHAVIOR_FACTORY);
public static final Registry<ItemBehaviorFactory> ITEM_BEHAVIOR_FACTORY = createRegistry(Registries.ITEM_BEHAVIOR_FACTORY);
public static final Registry<PropertyFactory> PROPERTY_FACTORY = createRegistry(Registries.PROPERTY_FACTORY);
public static final Registry<LootFunctionFactory<?>> LOOT_FUNCTION_FACTORY = createRegistry(Registries.LOOT_FUNCTION_FACTORY);
public static final Registry<Factory<Condition<LootContext>>> LOOT_CONDITION_FACTORY = createRegistry(Registries.LOOT_CONDITION_FACTORY);
public static final Registry<ConditionFactory<LootContext>> LOOT_CONDITION_FACTORY = createRegistry(Registries.LOOT_CONDITION_FACTORY);
public static final Registry<LootEntryContainerFactory<?>> LOOT_ENTRY_CONTAINER_FACTORY = createRegistry(Registries.LOOT_ENTRY_CONTAINER_FACTORY);
public static final Registry<Factory<NumberProvider>> NUMBER_PROVIDER_FACTORY = createRegistry(Registries.NUMBER_PROVIDER_FACTORY);
public static final Registry<ItemBehaviorFactory> ITEM_BEHAVIOR_FACTORY = createRegistry(Registries.ITEM_BEHAVIOR_FACTORY);
public static final Registry<TemplateArgumentFactory> TEMPLATE_ARGUMENT_FACTORY = createRegistry(Registries.TEMPLATE_ARGUMENT_FACTORY);
public static final Registry<ItemModelFactory> ITEM_MODEL_FACTORY = createRegistry(Registries.ITEM_MODEL_FACTORY);
public static final Registry<TintFactory> TINT_FACTORY = createRegistry(Registries.TINT_FACTORY);
@@ -45,12 +48,14 @@ public class BuiltInRegistries {
public static final Registry<ConditionPropertyFactory> CONDITION_PROPERTY_FACTORY = createRegistry(Registries.CONDITION_PROPERTY_FACTORY);
public static final Registry<SelectPropertyFactory> SELECT_PROPERTY_FACTORY = createRegistry(Registries.SELECT_PROPERTY_FACTORY);
public static final Registry<RecipeFactory<?>> RECIPE_FACTORY = createRegistry(Registries.RECIPE_FACTORY);
public static final Registry<LootFunctionApplyBonusCount.FormulaFactory> FORMULA_FACTORY = createRegistry(Registries.FORMULA_FACTORY);
public static final Registry<Factory<Condition<PathContext>>> PATH_MATCHER_FACTORY = createRegistry(Registries.PATH_MATCHER_FACTORY);
public static final Registry<ApplyBonusCountFunction.FormulaFactory> FORMULA_FACTORY = createRegistry(Registries.FORMULA_FACTORY);
public static final Registry<ConditionFactory<PathContext>> PATH_MATCHER_FACTORY = createRegistry(Registries.PATH_MATCHER_FACTORY);
public static final Registry<ResolutionFactory> RESOLUTION_FACTORY = createRegistry(Registries.RESOLUTION_FACTORY);
public static final Registry<CustomSmithingTransformRecipe.ItemDataProcessor.Factory> SMITHING_RESULT_PROCESSOR_FACTORY = createRegistry(Registries.SMITHING_RESULT_PROCESSOR_FACTORY);
public static final Registry<CustomSmithingTransformRecipe.ItemDataProcessor.ProcessorFactory> SMITHING_RESULT_PROCESSOR_FACTORY = createRegistry(Registries.SMITHING_RESULT_PROCESSOR_FACTORY);
public static final Registry<HitBoxFactory> HITBOX_FACTORY = createRegistry(Registries.HITBOX_FACTORY);
public static final Registry<ResourcePackHostFactory> RESOURCE_PACK_HOST_FACTORY = createRegistry(Registries.RESOURCE_PACK_HOST_FACTORY);
public static final Registry<Factory<Function<PlayerBlockActionContext>>> PLAYER_BLOCK_FUNCTION_FACTORY = createRegistry(Registries.PLAYER_BLOCK_FUNCTION_FACTORY);
public static final Registry<Factory<Condition<PlayerBlockActionContext>>> PLAYER_BLOCK_CONDITION_FACTORY = createRegistry(Registries.PLAYER_BLOCK_CONDITION_FACTORY);
private static <T> Registry<T> createRegistry(ResourceKey<? extends Registry<T>> key) {
return new MappedRegistry<>(key);

View File

@@ -9,7 +9,7 @@ import net.momirealms.craftengine.core.item.recipe.CustomSmithingTransformRecipe
import net.momirealms.craftengine.core.item.recipe.RecipeFactory;
import net.momirealms.craftengine.core.loot.LootContext;
import net.momirealms.craftengine.core.loot.entry.LootEntryContainerFactory;
import net.momirealms.craftengine.core.loot.function.LootFunctionApplyBonusCount;
import net.momirealms.craftengine.core.loot.function.ApplyBonusCountFunction;
import net.momirealms.craftengine.core.loot.function.LootFunctionFactory;
import net.momirealms.craftengine.core.pack.conflict.PathContext;
import net.momirealms.craftengine.core.pack.conflict.resolution.ResolutionFactory;
@@ -22,6 +22,9 @@ import net.momirealms.craftengine.core.pack.model.special.SpecialModelFactory;
import net.momirealms.craftengine.core.pack.model.tint.TintFactory;
import net.momirealms.craftengine.core.plugin.config.template.TemplateArgumentFactory;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.PlayerBlockActionContext;
import net.momirealms.craftengine.core.plugin.context.condition.ConditionFactory;
import net.momirealms.craftengine.core.plugin.context.function.Function;
import net.momirealms.craftengine.core.plugin.context.number.NumberProvider;
import net.momirealms.craftengine.core.util.Factory;
import net.momirealms.craftengine.core.util.Key;
@@ -36,7 +39,7 @@ public class Registries {
public static final ResourceKey<Registry<ItemBehaviorFactory>> ITEM_BEHAVIOR_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("item_behavior_factory"));
public static final ResourceKey<Registry<LootFunctionFactory<?>>> LOOT_FUNCTION_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("loot_function_factory"));
public static final ResourceKey<Registry<LootEntryContainerFactory<?>>> LOOT_ENTRY_CONTAINER_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("loot_entry_container_factory"));
public static final ResourceKey<Registry<Factory<Condition<LootContext>>>> LOOT_CONDITION_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("loot_condition_factory"));
public static final ResourceKey<Registry<ConditionFactory<LootContext>>> LOOT_CONDITION_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("loot_condition_factory"));
public static final ResourceKey<Registry<Factory<NumberProvider>>> NUMBER_PROVIDER_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("number_provider_factory"));
public static final ResourceKey<Registry<TemplateArgumentFactory>> TEMPLATE_ARGUMENT_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("template_argument_factory"));
public static final ResourceKey<Registry<ItemModelFactory>> ITEM_MODEL_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("item_model_factory"));
@@ -46,10 +49,12 @@ public class Registries {
public static final ResourceKey<Registry<ConditionPropertyFactory>> CONDITION_PROPERTY_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("condition_property_factory"));
public static final ResourceKey<Registry<SelectPropertyFactory>> SELECT_PROPERTY_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("select_property_factory"));
public static final ResourceKey<Registry<RecipeFactory<?>>> RECIPE_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("recipe_factory"));
public static final ResourceKey<Registry<LootFunctionApplyBonusCount.FormulaFactory>> FORMULA_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("formula_factory"));
public static final ResourceKey<Registry<Factory<Condition<PathContext>>>> PATH_MATCHER_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("path_matcher_factory"));
public static final ResourceKey<Registry<ApplyBonusCountFunction.FormulaFactory>> FORMULA_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("formula_factory"));
public static final ResourceKey<Registry<ConditionFactory<PathContext>>> PATH_MATCHER_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("path_matcher_factory"));
public static final ResourceKey<Registry<ResolutionFactory>> RESOLUTION_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("resolution_factory"));
public static final ResourceKey<Registry<CustomSmithingTransformRecipe.ItemDataProcessor.Factory>> SMITHING_RESULT_PROCESSOR_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("smithing_result_processor_factory"));
public static final ResourceKey<Registry<CustomSmithingTransformRecipe.ItemDataProcessor.ProcessorFactory>> SMITHING_RESULT_PROCESSOR_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("smithing_result_processor_factory"));
public static final ResourceKey<Registry<HitBoxFactory>> HITBOX_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("hitbox_factory"));
public static final ResourceKey<Registry<ResourcePackHostFactory>> RESOURCE_PACK_HOST_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("resource_pack_host_factory"));
public static final ResourceKey<Registry<Factory<Function<PlayerBlockActionContext>>>> PLAYER_BLOCK_FUNCTION_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("player_block_function_factory"));
public static final ResourceKey<Registry<Factory<Condition<PlayerBlockActionContext>>>> PLAYER_BLOCK_CONDITION_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("player_block_condition_factory"));
}

View File

@@ -1,5 +1,7 @@
package net.momirealms.craftengine.core.util;
import org.jetbrains.annotations.NotNull;
public record Key(String namespace, String value) {
public static final String DEFAULT_NAMESPACE = "craftengine";
@@ -27,6 +29,10 @@ public record Key(String namespace, String value) {
return of(decompose(namespacedId, "minecraft"));
}
public static Key fromNamespaceAndPath(String namespace, String path) {
return Key.of(namespace, path);
}
public String[] decompose() {
return new String[] { namespace, value };
}
@@ -47,7 +53,7 @@ public record Key(String namespace, String value) {
}
@Override
public String toString() {
public @NotNull String toString() {
return namespace + ":" + value;
}

View File

@@ -4,7 +4,7 @@ org.gradle.jvmargs=-Xmx1G
# Rule: [major update].[feature update].[bug fix]
project_version=0.0.53-beta.3
config_version=31
lang_version=10
lang_version=11
project_group=net.momirealms
latest_supported_version=1.21.5
@@ -39,7 +39,7 @@ lz4_version=1.8.0
geantyref_version=1.3.16
zstd_version=1.5.7-2
commons_io_version=2.18.0
sparrow_nbt_version=0.7.1
sparrow_nbt_version=0.7.3
sparrow_util_version=0.39
fastutil_version=8.5.15
netty_version=4.1.119.Final