Runtime & MinionTriggerBlock start
This commit is contained in:
@@ -1,7 +1,12 @@
|
||||
package io.github.skippyall.minions;
|
||||
|
||||
import eu.pb4.polymer.core.api.item.PolymerBlockItem;
|
||||
import eu.pb4.polymer.core.api.item.SimplePolymerItem;
|
||||
import io.github.skippyall.minions.minion.MinionItem;
|
||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||
import io.github.skippyall.minions.module.MinionModule;
|
||||
import io.github.skippyall.minions.program.instruction.InstructionType;
|
||||
import io.github.skippyall.minions.program.instruction.Instructions;
|
||||
import net.minecraft.component.DataComponentTypes;
|
||||
import net.minecraft.component.type.DamageResistantComponent;
|
||||
import net.minecraft.entity.damage.DamageType;
|
||||
@@ -14,16 +19,59 @@ import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.registry.tag.TagKey;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static io.github.skippyall.minions.Minions.MOD_ID;
|
||||
|
||||
public class MinionItems {
|
||||
public static final TagKey<DamageType> MINION_ITEM_RESISTS = TagKey.of(RegistryKeys.DAMAGE_TYPE, Identifier.of(MOD_ID, "minion_item_resists"));
|
||||
public static final MinionItem MINION_ITEM = registerItem(Identifier.of(MOD_ID, "minion"), settings -> new MinionItem(settings.component(DataComponentTypes.DAMAGE_RESISTANT, new DamageResistantComponent(MINION_ITEM_RESISTS))));
|
||||
public static final SimplePolymerItem BASIC_UPGRADE_BASE = registerItem(Identifier.of(MOD_ID, "basic_upgrade_base"), settings -> new SimplePolymerItem(settings, Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE));
|
||||
public static final SimplePolymerItem ADVANCED_UPGRADE_BASE = registerItem(Identifier.of(MOD_ID, "advanced_upgrade_base"), settings -> new SimplePolymerItem(settings, Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE));
|
||||
public static final MinionItem MINION_ITEM = registerItem(
|
||||
Identifier.of(MOD_ID, "minion"),
|
||||
settings -> new MinionItem(settings.component(DataComponentTypes.DAMAGE_RESISTANT, new DamageResistantComponent(MINION_ITEM_RESISTS)))
|
||||
);
|
||||
|
||||
public static final SimplePolymerItem BASIC_UPGRADE_BASE = registerItem(
|
||||
Identifier.of(MOD_ID, "basic_upgrade_base"),
|
||||
settings -> new SimplePolymerItem(settings, Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE)
|
||||
);
|
||||
|
||||
public static final SimplePolymerItem ADVANCED_UPGRADE_BASE = registerItem(
|
||||
Identifier.of(MOD_ID, "advanced_upgrade_base"),
|
||||
settings -> new SimplePolymerItem(settings, Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE)
|
||||
);
|
||||
|
||||
|
||||
public static final SimplePolymerItem MOVE_MODULE = registerModule(
|
||||
Identifier.of(MOD_ID, "move_module"),
|
||||
Items.IRON_BOOTS,
|
||||
List.of(Instructions.WALK, Instructions.TURN)
|
||||
);
|
||||
|
||||
public static final SimplePolymerItem ATTACK_MODULE = registerModule(
|
||||
Identifier.of(MOD_ID, "attack_module"),
|
||||
Items.IRON_PICKAXE,
|
||||
List.of(Instructions.ATTACK)
|
||||
);
|
||||
|
||||
public static final SimplePolymerItem INTERACT_MODULE = registerModule(
|
||||
Identifier.of(MOD_ID, "interact_module"),
|
||||
Items.LEVER,
|
||||
List.of(Instructions.USE)
|
||||
);
|
||||
|
||||
public static final SimplePolymerItem MOB_SPAWNING_MODULE = registerModule(
|
||||
Identifier.of(MOD_ID, "mob_spawning_module"),
|
||||
Items.SPAWNER,
|
||||
List.of(),
|
||||
List.of("mobSpawning")
|
||||
);
|
||||
|
||||
public static final PolymerBlockItem MINION_TRIGGER_ITEM =
|
||||
registerItem(
|
||||
MinionRegistration.MINION_TRIGGER_ID,
|
||||
settings -> new PolymerBlockItem(MinionRegistration.MINION_TRIGGER_BLOCK, settings, Items.GOLD_BLOCK)
|
||||
);
|
||||
|
||||
public static <T extends Item> T registerItem(Identifier identifier, Function<Item.Settings, T> constructor, Item.Settings settings) {
|
||||
T item = constructor.apply(settings.registryKey(RegistryKey.of(RegistryKeys.ITEM, identifier)));
|
||||
@@ -37,6 +85,23 @@ public class MinionItems {
|
||||
return registerItem(identifier, constructor, new Item.Settings());
|
||||
}
|
||||
|
||||
public static SimplePolymerItem registerModule(Identifier identifier, Item vanillaItem, List<InstructionType<MinionRuntime>> instructionTypes, List<String> specialEffects) {
|
||||
return registerItem(
|
||||
identifier,
|
||||
settings -> new SimplePolymerItem(settings, vanillaItem),
|
||||
new Item.Settings().component(MinionModule.COMPONENT_TYPE, new MinionModule(instructionTypes, specialEffects))
|
||||
);
|
||||
}
|
||||
|
||||
public static SimplePolymerItem registerModule(Identifier identifier, Item vanillaItem, List<InstructionType<MinionRuntime>> instructionTypes) {
|
||||
return registerModule(
|
||||
identifier,
|
||||
vanillaItem,
|
||||
instructionTypes,
|
||||
List.of()
|
||||
);
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package io.github.skippyall.minions;
|
||||
|
||||
import eu.pb4.polymer.core.api.block.PolymerBlockUtils;
|
||||
import io.github.skippyall.minions.block.MinionTriggerBlock;
|
||||
import io.github.skippyall.minions.block.MinionTriggerBlockEntity;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder;
|
||||
import net.minecraft.block.AbstractBlock;
|
||||
import net.minecraft.block.entity.BlockEntityType;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.sound.BlockSoundGroup;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class MinionRegistration {
|
||||
public static final Identifier MINION_TRIGGER_ID = Identifier.of(Minions.MOD_ID, "minion_trigger");
|
||||
public static final MinionTriggerBlock MINION_TRIGGER_BLOCK = Registry.register(
|
||||
Registries.BLOCK,
|
||||
MINION_TRIGGER_ID,
|
||||
new MinionTriggerBlock(AbstractBlock.Settings.create()
|
||||
.registryKey(RegistryKey.of(RegistryKeys.BLOCK, MINION_TRIGGER_ID))
|
||||
.hardness(5)
|
||||
.strength(5.0F, 6.0F)
|
||||
.sounds(BlockSoundGroup.IRON)
|
||||
.requiresTool()
|
||||
)
|
||||
);
|
||||
public static final BlockEntityType<MinionTriggerBlockEntity> MINION_TRIGGER_BE_TYPE =
|
||||
Registry.register(
|
||||
Registries.BLOCK_ENTITY_TYPE,
|
||||
MINION_TRIGGER_ID,
|
||||
FabricBlockEntityTypeBuilder.create(MinionTriggerBlockEntity::new, MINION_TRIGGER_BLOCK).build()
|
||||
);
|
||||
|
||||
public static void register() {
|
||||
PolymerBlockUtils.registerBlockEntity(MINION_TRIGGER_BE_TYPE);
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,9 @@ package io.github.skippyall.minions;
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||
import io.github.skippyall.minions.minion.skin.SkinProvider;
|
||||
import io.github.skippyall.minions.program.argument.ArgumentType;
|
||||
import io.github.skippyall.minions.program.supplier.ValueSupplierType;
|
||||
import io.github.skippyall.minions.program.instruction.InstructionType;
|
||||
import io.github.skippyall.minions.program.consumer.ValueConsumerType;
|
||||
import io.github.skippyall.minions.program.value.ValueType;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
@@ -13,7 +14,8 @@ import net.minecraft.util.Identifier;
|
||||
|
||||
public class MinionRegistries {
|
||||
public static final Registry<ValueType<?>> VALUE_TYPES = registry("value_type");
|
||||
public static final Registry<ArgumentType<MinionRuntime>> ARGUMENT_TYPE_REGISTRY = registry("argument_type");
|
||||
public static final Registry<ValueSupplierType<MinionRuntime>> ARGUMENT_TYPES = registry("argument_type");
|
||||
public static final Registry<ValueConsumerType<MinionRuntime>> VALUE_CONSUMER_TYPES = registry("value_consumer_type");
|
||||
public static final Registry<InstructionType<MinionRuntime>> INSTRUCTION_TYPES = registry("instruction_type");
|
||||
public static final Registry<SkinProvider> SKIN_PROVIDERS = registry("skin_providers");
|
||||
|
||||
|
||||
@@ -41,6 +41,8 @@ public class Minions implements ModInitializer {
|
||||
|
||||
ValueTypes.register();
|
||||
SkinProviders.register();
|
||||
|
||||
MinionRegistration.register();
|
||||
MinionItems.register();
|
||||
MinionCreativeTab.registerGroup();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
package io.github.skippyall.minions.block;
|
||||
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import eu.pb4.polymer.core.api.block.PolymerBlock;
|
||||
import io.github.skippyall.minions.MinionRegistration;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.BlockWithEntity;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.state.StateManager;
|
||||
import net.minecraft.state.property.BooleanProperty;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.block.WireOrientation;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import xyz.nucleoid.packettweaker.PacketContext;
|
||||
|
||||
public class MinionTriggerBlock extends BlockWithEntity implements PolymerBlock {
|
||||
public static final MapCodec<MinionTriggerBlock> CODEC = createCodec(MinionTriggerBlock::new);
|
||||
|
||||
public static final BooleanProperty POWERED = BooleanProperty.of("powered");
|
||||
|
||||
public MinionTriggerBlock(Settings settings) {
|
||||
super(settings);
|
||||
setDefaultState(getDefaultState().with(POWERED, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||
builder.add(POWERED);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void neighborUpdate(BlockState state, World world, BlockPos pos, Block sourceBlock, @Nullable WireOrientation wireOrientation, boolean notify) {
|
||||
boolean newPower = world.isReceivingRedstonePower(pos);
|
||||
if(state.get(POWERED) != newPower) {
|
||||
world.setBlockState(pos, state.with(POWERED, newPower));
|
||||
world.getBlockEntity(pos, MinionRegistration.MINION_TRIGGER_BE_TYPE).ifPresent(MinionTriggerBlockEntity::updatePower);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasComparatorOutput(BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getComparatorOutput(BlockState state, World world, BlockPos pos) {
|
||||
return world.getBlockEntity(pos, MinionRegistration.MINION_TRIGGER_BE_TYPE).map(MinionTriggerBlockEntity::getComparatorOutput).orElse(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MapCodec<? extends BlockWithEntity> getCodec() {
|
||||
return CODEC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
|
||||
return new MinionTriggerBlockEntity(pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getPolymerBlockState(BlockState state, PacketContext context) {
|
||||
return state.get(POWERED) ? Blocks.REDSTONE_BLOCK.getDefaultState() : Blocks.GOLD_BLOCK.getDefaultState();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package io.github.skippyall.minions.block;
|
||||
|
||||
import io.github.skippyall.minions.MinionRegistration;
|
||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.program.instruction.ConfiguredInstruction;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.storage.ReadView;
|
||||
import net.minecraft.storage.WriteView;
|
||||
import net.minecraft.util.Uuids;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class MinionTriggerBlockEntity extends BlockEntity {
|
||||
private UUID minionUuid;
|
||||
private String instructionName = "";
|
||||
|
||||
public MinionTriggerBlockEntity(BlockPos pos, BlockState state) {
|
||||
super(MinionRegistration.MINION_TRIGGER_BE_TYPE, pos, state);
|
||||
}
|
||||
|
||||
public void updatePower() {
|
||||
boolean powered = getCachedState().get(MinionTriggerBlock.POWERED);
|
||||
ConfiguredInstruction<MinionRuntime> instruction = getInstruction();
|
||||
|
||||
if(instruction != null) {
|
||||
if(powered) {
|
||||
instruction.run(getMinion().getInstructionManager());
|
||||
} else {
|
||||
instruction.stop(getMinion().getInstructionManager());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getComparatorOutput() {
|
||||
ConfiguredInstruction<MinionRuntime> instruction = getInstruction();
|
||||
if(instruction != null && instruction.isRunning()) {
|
||||
return 15;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public MinionFakePlayer getMinion() {
|
||||
if(minionUuid != null && world != null && world.getPlayerByUuid(minionUuid) instanceof MinionFakePlayer minion) {
|
||||
return minion;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ConfiguredInstruction<MinionRuntime> getInstruction() {
|
||||
MinionFakePlayer minion = getMinion();
|
||||
if(minion == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return minion.getInstructionManager().getInstruction(instructionName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockReplaced(BlockPos pos, BlockState oldState) {
|
||||
super.onBlockReplaced(pos, oldState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markRemoved() {
|
||||
super.markRemoved();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readData(ReadView view) {
|
||||
minionUuid = view.read("minionUuid", Uuids.CODEC).orElse(null);
|
||||
instructionName = view.getString("instructionName", "");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeData(WriteView view) {
|
||||
if(minionUuid != null) {
|
||||
view.put("minionUuid", Uuids.CODEC, minionUuid);
|
||||
}
|
||||
view.putString("instructionName", instructionName);
|
||||
}
|
||||
}
|
||||
@@ -7,13 +7,11 @@ import io.github.skippyall.minions.input.TextInput;
|
||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.module.MinionModule;
|
||||
import io.github.skippyall.minions.program.argument.Argument;
|
||||
import io.github.skippyall.minions.program.argument.GenericArgumentType;
|
||||
import io.github.skippyall.minions.program.argument.SpecificArgumentType;
|
||||
import io.github.skippyall.minions.program.dingenskirchen.SpecificDingenskirchenType;
|
||||
import io.github.skippyall.minions.program.supplier.ValueSupplier;
|
||||
import io.github.skippyall.minions.program.supplier.ValueSupplierType;
|
||||
import io.github.skippyall.minions.program.instruction.ConfiguredInstruction;
|
||||
import io.github.skippyall.minions.program.instruction.InstructionType;
|
||||
import io.github.skippyall.minions.program.argument.Parameter;
|
||||
import io.github.skippyall.minions.program.supplier.Parameter;
|
||||
import io.github.skippyall.minions.util.TranslationUtil;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
@@ -45,7 +43,7 @@ public class InstructionGui {
|
||||
public static void instructionList(MinionFakePlayer minion, ServerPlayerEntity player) {
|
||||
SimpleGui gui = new SimpleGui(ScreenHandlerType.GENERIC_9X3, player, false);
|
||||
for(String instructionName : minion.getInstructionManager().getInstructionNames()) {
|
||||
ConfiguredInstruction<?> instruction = minion.getInstructionManager().getInstruction(instructionName);
|
||||
ConfiguredInstruction<MinionRuntime> instruction = minion.getInstructionManager().getInstruction(instructionName);
|
||||
gui.addSlot(instruction.getInstruction().getDisplay().createElement()
|
||||
.setName(Text.literal(instructionName))
|
||||
.setLore(List.of())
|
||||
@@ -58,7 +56,7 @@ public class InstructionGui {
|
||||
public static void createNewInstruction(MinionFakePlayer minion, ServerPlayerEntity player) {
|
||||
selectInstructionModuleMenu(minion, player).thenAccept(instructionType ->
|
||||
TextInput.inputString(player, Text.translatable("minions.gui.instruction.enter_name"), "Instruction").thenAccept(name -> {
|
||||
ConfiguredInstruction<?> configuredInstruction = minion.getInstructionManager().createInstruction(name, instructionType);
|
||||
ConfiguredInstruction<MinionRuntime> configuredInstruction = minion.getInstructionManager().createInstruction(name, instructionType);
|
||||
configureInstructionMenu(name, configuredInstruction, minion, player);
|
||||
})
|
||||
);
|
||||
@@ -73,7 +71,7 @@ public class InstructionGui {
|
||||
return stillExists;
|
||||
}
|
||||
|
||||
public static void configureInstructionMenu(String name, ConfiguredInstruction<?> instruction, MinionFakePlayer minion, ServerPlayerEntity player) {
|
||||
public static void configureInstructionMenu(String name, ConfiguredInstruction<MinionRuntime> instruction, MinionFakePlayer minion, ServerPlayerEntity player) {
|
||||
if(!checkInstructionExists(name, instruction, minion, player)) {
|
||||
return;
|
||||
}
|
||||
@@ -94,12 +92,12 @@ public class InstructionGui {
|
||||
gui.open();
|
||||
}
|
||||
|
||||
private static void updateRunSlot(ConfiguredInstruction<?> instruction, MinionFakePlayer minion, SimpleGui gui) {
|
||||
private static void updateRunSlot(ConfiguredInstruction<MinionRuntime> instruction, MinionFakePlayer minion, SimpleGui gui) {
|
||||
if(!instruction.isRunning()) {
|
||||
gui.setSlot(26, new GuiElementBuilder(Items.ARROW)
|
||||
.setName(Text.literal("Run"))
|
||||
.setCallback(() -> {
|
||||
instruction.run(minion);
|
||||
instruction.run(minion.getInstructionManager());
|
||||
updateRunSlot(instruction, minion, gui);
|
||||
})
|
||||
);
|
||||
@@ -107,14 +105,14 @@ public class InstructionGui {
|
||||
gui.setSlot(26, new GuiElementBuilder(Items.BARRIER)
|
||||
.setName(Text.literal("Stop"))
|
||||
.setCallback(() -> {
|
||||
instruction.stop(minion);
|
||||
instruction.stop(minion.getInstructionManager());
|
||||
updateRunSlot(instruction, minion, gui);
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T, A extends Argument<T, ? extends SpecificDingenskirchenType<T, A, MinionRuntime>, MinionRuntime>> void configureArgumentMenu(String name, ConfiguredInstruction<?> instruction, Parameter<T> parameter, MinionFakePlayer minion, ServerPlayerEntity player) {
|
||||
public static <T, A extends ValueSupplier<T, MinionRuntime>> void configureArgumentMenu(String name, ConfiguredInstruction<MinionRuntime> instruction, Parameter<T> parameter, MinionFakePlayer minion, ServerPlayerEntity player) {
|
||||
if(!checkInstructionExists(name, instruction, minion, player)) {
|
||||
return;
|
||||
}
|
||||
@@ -123,9 +121,9 @@ public class InstructionGui {
|
||||
|
||||
SimpleGui gui = new SimpleGui(ScreenHandlerType.GENERIC_3X3, player, false);
|
||||
gui.setSlot(3, new GuiElementBuilder(Items.STICK)
|
||||
.setName(Text.literal("Type: " + (argument == null ? "Unset" : MinionRegistries.GENERIC_ARGUMENT_TYPE_REGISTRY.getId(argument.getType().getGenericArgumentType()).getPath())))
|
||||
.setName(Text.literal("Type: " + (argument == null ? "Unset" : MinionRegistries.ARGUMENT_TYPES.getId(argument.getType()).getPath())))
|
||||
.setCallback(() -> selectArgumentType(player)
|
||||
.thenApply(type -> type.<T>createTypeSpecific(parameter.type()).openArgumentDialog(player, null)
|
||||
.thenApply(type -> type.openConfiguration(player, parameter.type(), null)
|
||||
.thenAccept(newArgument -> {
|
||||
instruction.getArguments().setArgument(parameter, newArgument);
|
||||
configureArgumentMenu(name, instruction, parameter, minion, player);
|
||||
@@ -137,7 +135,7 @@ public class InstructionGui {
|
||||
if(argument != null) {
|
||||
gui.setSlot(5, new GuiElementBuilder(Items.STRUCTURE_VOID)
|
||||
.setName(Text.literal("Configure"))
|
||||
.setCallback(() -> argument.getType().openArgumentDialog(player, argument)
|
||||
.setCallback(() -> argument.getType().openConfiguration(player, argument.getValueType(), argument)
|
||||
.thenAccept(newArgument -> instruction.getArguments().setArgument(parameter, newArgument))
|
||||
)
|
||||
);
|
||||
@@ -145,12 +143,12 @@ public class InstructionGui {
|
||||
gui.open();
|
||||
}
|
||||
|
||||
public static CompletableFuture<GenericArgumentType> selectArgumentType(ServerPlayerEntity player) {
|
||||
CompletableFuture<GenericArgumentType> future = new CompletableFuture<>();
|
||||
public static CompletableFuture<ValueSupplierType<MinionRuntime>> selectArgumentType(ServerPlayerEntity player) {
|
||||
CompletableFuture<ValueSupplierType<MinionRuntime>> future = new CompletableFuture<>();
|
||||
SimpleGui gui = new SimpleGui(ScreenHandlerType.GENERIC_9X3, player, false);
|
||||
for(GenericArgumentType type : MinionRegistries.GENERIC_ARGUMENT_TYPE_REGISTRY) {
|
||||
for(ValueSupplierType<MinionRuntime> type : MinionRegistries.ARGUMENT_TYPES) {
|
||||
gui.addSlot(new GuiElementBuilder()
|
||||
.setName(Text.translatable(TranslationUtil.getTranslationKey(type, MinionRegistries.GENERIC_ARGUMENT_TYPE_REGISTRY)))
|
||||
.setName(Text.translatable(TranslationUtil.getTranslationKey(type, MinionRegistries.ARGUMENT_TYPES)))
|
||||
.setCallback(() -> future.complete(type))
|
||||
);
|
||||
}
|
||||
@@ -158,13 +156,13 @@ public class InstructionGui {
|
||||
return future;
|
||||
}
|
||||
|
||||
public static CompletableFuture<InstructionType<?>> selectInstructionModuleMenu(MinionFakePlayer minion, ServerPlayerEntity player) {
|
||||
public static CompletableFuture<InstructionType<MinionRuntime>> selectInstructionModuleMenu(MinionFakePlayer minion, ServerPlayerEntity player) {
|
||||
if(minion.getModuleInventory().getModules().isEmpty()) {
|
||||
player.sendMessage(Text.literal("This minion has no modules"));
|
||||
return CompletableFuture.failedFuture(new NoSuchElementException("No modules"));
|
||||
}
|
||||
|
||||
CompletableFuture<InstructionType<?>> future = new CompletableFuture<>();
|
||||
CompletableFuture<InstructionType<MinionRuntime>> future = new CompletableFuture<>();
|
||||
|
||||
SimpleGui gui = new SimpleGui(ScreenHandlerType.GENERIC_9X3, player, false) {
|
||||
@Override
|
||||
@@ -190,11 +188,11 @@ public class InstructionGui {
|
||||
return future;
|
||||
}
|
||||
|
||||
public static CompletableFuture<InstructionType<?>> selectInstructionMenu(MinionModule module, MinionFakePlayer minion, ServerPlayerEntity player) {
|
||||
CompletableFuture<InstructionType<?>> future = new CompletableFuture<>();
|
||||
public static CompletableFuture<InstructionType<MinionRuntime>> selectInstructionMenu(MinionModule module, MinionFakePlayer minion, ServerPlayerEntity player) {
|
||||
CompletableFuture<InstructionType<MinionRuntime>> future = new CompletableFuture<>();
|
||||
|
||||
SimpleGui gui = new SimpleGui(ScreenHandlerType.GENERIC_9X3, player, false);
|
||||
for(InstructionType<?> instructionType : module.instructions()) {
|
||||
for(InstructionType<MinionRuntime> instructionType : module.instructions()) {
|
||||
gui.addSlot(createInstructionElement(instructionType)
|
||||
.setCallback(() -> future.complete(instructionType))
|
||||
);
|
||||
@@ -215,10 +213,10 @@ public class InstructionGui {
|
||||
return instructionBuilder;
|
||||
}
|
||||
|
||||
public static GuiElementBuilder createArgumentElement(Argument<?,?> argument) {
|
||||
public static GuiElementBuilder createArgumentElement(ValueSupplier<?,?> valueSupplier) {
|
||||
GuiElementBuilder argumentBuilder;
|
||||
if(argument != null) {
|
||||
argumentBuilder = argument.getDisplay().createElement();
|
||||
if(valueSupplier != null) {
|
||||
argumentBuilder = valueSupplier.getDisplay().createElement();
|
||||
} else {
|
||||
argumentBuilder = new GuiElementBuilder(Items.RED_WOOL)
|
||||
.setName(Text.translatable("minions.gui.instruction.no_argument_set"));
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
package io.github.skippyall.minions.minion;
|
||||
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.program.instruction.ConfiguredInstruction;
|
||||
import io.github.skippyall.minions.program.instruction.InstructionType;
|
||||
import net.minecraft.storage.ReadView;
|
||||
import net.minecraft.storage.WriteView;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public class MinionInstructionManager {
|
||||
private final MinionFakePlayer minion;
|
||||
private final Map<String, ConfiguredInstruction<?>> configuredInstructions = new HashMap<>();
|
||||
|
||||
public MinionInstructionManager(MinionFakePlayer minion) {
|
||||
this.minion = minion;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
for (ConfiguredInstruction<?> instruction : configuredInstructions.values()) {
|
||||
instruction.tick(minion);
|
||||
}
|
||||
}
|
||||
|
||||
public Set<String> getInstructionNames() {
|
||||
return configuredInstructions.keySet();
|
||||
}
|
||||
|
||||
public <T> ConfiguredInstruction<T> createInstruction(String name, InstructionType<T> instructionType) {
|
||||
ConfiguredInstruction<T> instruction = new ConfiguredInstruction<>(instructionType, name);
|
||||
configuredInstructions.put(name, instruction);
|
||||
return instruction;
|
||||
}
|
||||
|
||||
public void removeInstruction(String name) {
|
||||
ConfiguredInstruction<?> instruction = getInstruction(name);
|
||||
instruction.stop(minion);
|
||||
configuredInstructions.remove(name);
|
||||
}
|
||||
|
||||
public ConfiguredInstruction<?> getInstruction(String name) {
|
||||
return configuredInstructions.get(name);
|
||||
}
|
||||
|
||||
public boolean hasInstruction(String name) {
|
||||
return configuredInstructions.containsKey(name);
|
||||
}
|
||||
|
||||
public void save(WriteView view) {
|
||||
WriteView.ListView list = view.getList("configuredInstructions");
|
||||
for (Map.Entry<String, ConfiguredInstruction<?>> instruction : configuredInstructions.entrySet()) {
|
||||
WriteView inner = list.add();
|
||||
inner.putString("name", instruction.getKey());
|
||||
instruction.getValue().save(inner, minion);
|
||||
}
|
||||
}
|
||||
|
||||
public void load(ReadView view) {
|
||||
ReadView.ListReadView list = view.getListReadView("configuredInstructions");
|
||||
for (ReadView inner : list) {
|
||||
Optional<String> name = inner.getOptionalString("name");
|
||||
if(name.isEmpty()) {
|
||||
Minions.LOGGER.error("Tried deserializing configured instruction without a name of minion \"{}\":", minion.getGameProfile().getName());
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
ConfiguredInstruction<?> instruction = ConfiguredInstruction.load(inner, minion, name.get());
|
||||
configuredInstructions.put(name.get(), instruction);
|
||||
} catch (Exception e) {
|
||||
Minions.LOGGER.error("Could not deserialize configured instruction \"{}\" of minion \"{}\":", name.get(), minion.getGameProfile().getName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,103 @@
|
||||
package io.github.skippyall.minions.minion;
|
||||
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.program.InstructionRuntime;
|
||||
import io.github.skippyall.minions.program.argument.GenericArgumentType;
|
||||
import io.github.skippyall.minions.program.supplier.ValueSupplierType;
|
||||
import io.github.skippyall.minions.program.instruction.ConfiguredInstruction;
|
||||
import io.github.skippyall.minions.program.instruction.InstructionType;
|
||||
import io.github.skippyall.minions.program.consumer.ValueConsumerType;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.storage.ReadView;
|
||||
import net.minecraft.storage.WriteView;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public class MinionRuntime implements InstructionRuntime<MinionRuntime> {
|
||||
private final MinionFakePlayer minion;
|
||||
private final Map<String, ConfiguredInstruction<MinionRuntime>> configuredInstructions = new HashMap<>();
|
||||
|
||||
public MinionRuntime(MinionFakePlayer minion) {
|
||||
this.minion = minion;
|
||||
}
|
||||
|
||||
public MinionFakePlayer getMinion() {
|
||||
return minion;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
for (ConfiguredInstruction<MinionRuntime> instruction : configuredInstructions.values()) {
|
||||
instruction.tick(this);
|
||||
}
|
||||
}
|
||||
|
||||
public Set<String> getInstructionNames() {
|
||||
return configuredInstructions.keySet();
|
||||
}
|
||||
|
||||
public ConfiguredInstruction<MinionRuntime> createInstruction(String name, InstructionType<MinionRuntime> instructionType) {
|
||||
ConfiguredInstruction<MinionRuntime> instruction = new ConfiguredInstruction<>(instructionType, name);
|
||||
configuredInstructions.put(name, instruction);
|
||||
return instruction;
|
||||
}
|
||||
|
||||
public void removeInstruction(String name) {
|
||||
ConfiguredInstruction<MinionRuntime> instruction = getInstruction(name);
|
||||
instruction.stop(this);
|
||||
configuredInstructions.remove(name);
|
||||
}
|
||||
|
||||
public ConfiguredInstruction<MinionRuntime> getInstruction(String name) {
|
||||
return configuredInstructions.get(name);
|
||||
}
|
||||
|
||||
public boolean hasInstruction(String name) {
|
||||
return configuredInstructions.containsKey(name);
|
||||
}
|
||||
|
||||
public void save(WriteView view) {
|
||||
WriteView.ListView list = view.getList("configuredInstructions");
|
||||
for (Map.Entry<String, ConfiguredInstruction<MinionRuntime>> instruction : configuredInstructions.entrySet()) {
|
||||
WriteView inner = list.add();
|
||||
inner.putString("name", instruction.getKey());
|
||||
instruction.getValue().save(inner, this);
|
||||
}
|
||||
}
|
||||
|
||||
public void load(ReadView view) {
|
||||
ReadView.ListReadView list = view.getListReadView("configuredInstructions");
|
||||
for (ReadView inner : list) {
|
||||
Optional<String> name = inner.getOptionalString("name");
|
||||
if(name.isEmpty()) {
|
||||
Minions.LOGGER.error("Tried deserializing configured instruction without a name of minion \"{}\":", minion.getGameProfile().getName());
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
ConfiguredInstruction<MinionRuntime> instruction = ConfiguredInstruction.load(inner, this, name.get());
|
||||
configuredInstructions.put(name.get(), instruction);
|
||||
} catch (Exception e) {
|
||||
Minions.LOGGER.error("Could not deserialize configured instruction \"{}\" of minion \"{}\":", name.get(), minion.getGameProfile().getName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Registry<GenericArgumentType<MinionRuntime>> getGenericArgumentTypeRegistry() {
|
||||
return MinionRegistries.GENERIC_ARGUMENT_TYPE_REGISTRY;
|
||||
public Registry<ValueSupplierType<MinionRuntime>> getArgumentTypeRegistry() {
|
||||
return MinionRegistries.ARGUMENT_TYPES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Registry<InstructionType<MinionRuntime>> getInstructionTypeRegistry() {
|
||||
return MinionRegistries.INSTRUCTION_TYPES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Registry<ValueConsumerType<MinionRuntime>> getValueConsumerTypeRegistry() {
|
||||
return MinionRegistries.VALUE_CONSUMER_TYPES;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import com.mojang.authlib.properties.PropertyMap;
|
||||
import io.github.skippyall.minions.MinionItems;
|
||||
import io.github.skippyall.minions.minion.MinionData;
|
||||
import io.github.skippyall.minions.gui.MinionGui;
|
||||
import io.github.skippyall.minions.minion.MinionInstructionManager;
|
||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||
import io.github.skippyall.minions.minion.MinionItem;
|
||||
import io.github.skippyall.minions.minion.MinionPersistentState;
|
||||
import io.github.skippyall.minions.minion.MinionProfileUtils;
|
||||
@@ -51,11 +51,8 @@ public class MinionFakePlayer extends ServerPlayerEntity {
|
||||
|
||||
private EntityPlayerActionPack actionPack;
|
||||
|
||||
private float moveForward;
|
||||
private float moveSideways;
|
||||
|
||||
private final ModuleInventory moduleInventory = new ModuleInventory();
|
||||
private final MinionInstructionManager instructionManager = new MinionInstructionManager(this);
|
||||
private final MinionRuntime instructionManager = new MinionRuntime(this);
|
||||
|
||||
private final MinionData data;
|
||||
|
||||
@@ -118,7 +115,7 @@ public class MinionFakePlayer extends ServerPlayerEntity {
|
||||
return actionPack;
|
||||
}
|
||||
|
||||
public MinionInstructionManager getInstructionManager() {
|
||||
public MinionRuntime getInstructionManager() {
|
||||
return instructionManager;
|
||||
}
|
||||
|
||||
@@ -127,11 +124,11 @@ public class MinionFakePlayer extends ServerPlayerEntity {
|
||||
}
|
||||
|
||||
public boolean canSpawnMobs() {
|
||||
return true;
|
||||
return moduleInventory.hasAbility("mobSpawning");
|
||||
}
|
||||
|
||||
public boolean canDespawnMobs() {
|
||||
return true;
|
||||
return moduleInventory.hasAbility("mobSpawning");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -249,44 +246,6 @@ public class MinionFakePlayer extends ServerPlayerEntity {
|
||||
return networkHandler.player;
|
||||
}
|
||||
|
||||
/*public void moveForward(float forward) {
|
||||
this.moveForward += forward;
|
||||
EntityPlayerActionPack actionPack = getMinionActionPack();
|
||||
if (moveForward != 0) {
|
||||
actionPack.setForward(moveForward > 0 ? 1 : -1);
|
||||
}
|
||||
}
|
||||
|
||||
public void moveSideways(float sideways) {
|
||||
this.moveSideways += sideways;
|
||||
EntityPlayerActionPack actionPack = getMinionActionPack();
|
||||
if (moveSideways != 0) {
|
||||
actionPack.setStrafing(moveSideways > 0 ? 1 : -1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move(MovementType movementType, Vec3d movement) {
|
||||
float newForward = (float) (moveForward - movement.z);
|
||||
float newSideways = (float) (moveSideways - movement.x);
|
||||
Vec3d newMovement = movement;
|
||||
if ((newForward < 0 && moveForward > 0) || (newForward > 0 && moveForward < 0)) {
|
||||
newMovement = new Vec3d(newMovement.x, newMovement.y, moveForward);
|
||||
moveForward = 0;
|
||||
getMinionActionPack().setForward(0);
|
||||
}else {
|
||||
moveForward = newForward;
|
||||
}
|
||||
if ((newSideways < 0 && moveSideways > 0) || (newSideways > 0 && moveSideways < 0)) {
|
||||
newMovement = new Vec3d(newMovement.x, newMovement.y, moveSideways);
|
||||
moveSideways = 0;
|
||||
getMinionActionPack().setStrafing(0);
|
||||
}else {
|
||||
moveSideways = newSideways;
|
||||
}
|
||||
super.move(movementType, newMovement);
|
||||
}*/
|
||||
|
||||
@Override
|
||||
public void drop(ServerWorld world, DamageSource damageSource) {
|
||||
super.drop(world, damageSource);
|
||||
|
||||
@@ -8,7 +8,6 @@ import com.llamalad7.mixinextras.sugar.Local;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.NetHandlerPlayServerFake;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.network.ClientConnection;
|
||||
import net.minecraft.network.packet.c2s.common.SyncedClientOptions;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import eu.pb4.polymer.core.api.other.PolymerComponent;
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||
import io.github.skippyall.minions.program.instruction.InstructionType;
|
||||
import net.minecraft.component.ComponentType;
|
||||
import net.minecraft.registry.Registries;
|
||||
@@ -13,10 +14,11 @@ import net.minecraft.util.Identifier;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record MinionModule(List<InstructionType<?>> instructions) {
|
||||
public record MinionModule(List<InstructionType<MinionRuntime>> instructions, List<String> specialBehaviour) {
|
||||
public static final Codec<MinionModule> CODEC = RecordCodecBuilder.create(instance ->
|
||||
instance.group(
|
||||
MinionRegistries.INSTRUCTION_TYPES.getCodec().listOf().fieldOf("instructions").forGetter(MinionModule::instructions)
|
||||
MinionRegistries.INSTRUCTION_TYPES.getCodec().listOf().fieldOf("instructions").forGetter(MinionModule::instructions),
|
||||
Codec.STRING.listOf().fieldOf("specialBehaviour").forGetter(MinionModule::specialBehaviour)
|
||||
).apply(instance, MinionModule::new)
|
||||
);
|
||||
|
||||
@@ -24,8 +26,13 @@ public record MinionModule(List<InstructionType<?>> instructions) {
|
||||
|
||||
public static final MinionModule EMPTY = new MinionModule(List.of());
|
||||
|
||||
public MinionModule(List<InstructionType<?>> instructions) {
|
||||
public MinionModule(List<InstructionType<MinionRuntime>> instructions) {
|
||||
this(instructions, List.of());
|
||||
}
|
||||
|
||||
public MinionModule(List<InstructionType<MinionRuntime>> instructions, List<String> specialBehaviour) {
|
||||
this.instructions = List.copyOf(instructions);
|
||||
this.specialBehaviour = List.copyOf(specialBehaviour);
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
|
||||
@@ -19,6 +19,8 @@ import java.util.Set;
|
||||
|
||||
public class ModuleInventory extends SimpleInventory {
|
||||
private final Set<MinionModule> modules = new HashSet<>();
|
||||
private final Set<String> specialAbilities = new HashSet<>();
|
||||
|
||||
public ModuleInventory() {
|
||||
super(27);
|
||||
}
|
||||
@@ -45,10 +47,12 @@ public class ModuleInventory extends SimpleInventory {
|
||||
|
||||
public void updateModules() {
|
||||
modules.clear();
|
||||
specialAbilities.clear();
|
||||
for (ItemStack heldStack : heldStacks) {
|
||||
MinionModule module = heldStack.get(MinionModule.COMPONENT_TYPE);
|
||||
if(module != null) {
|
||||
modules.add(module);
|
||||
specialAbilities.addAll(module.specialBehaviour());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,14 +66,14 @@ public class ModuleInventory extends SimpleInventory {
|
||||
Inventories.writeData(view, heldStacks);
|
||||
}
|
||||
|
||||
public boolean hasModule(MinionModule module) {
|
||||
return modules.contains(module);
|
||||
}
|
||||
|
||||
public Collection<MinionModule> getModules() {
|
||||
return modules;
|
||||
}
|
||||
|
||||
public boolean hasAbility(String ability) {
|
||||
return specialAbilities.contains(ability);
|
||||
}
|
||||
|
||||
public List<InstructionType<?>> getAllInstructions() {
|
||||
ArrayList<InstructionType<?>> instructionTypes = new ArrayList<>();
|
||||
for(MinionModule module : modules) {
|
||||
|
||||
@@ -11,6 +11,7 @@ import net.minecraft.screen.slot.Slot;
|
||||
public class ModuleInventoryScreenHandler extends ScreenHandler {
|
||||
private final int rows = 3;
|
||||
private final ModuleInventory inventory;
|
||||
|
||||
public ModuleInventoryScreenHandler(int syncId, ModuleInventory inventory) {
|
||||
super(ScreenHandlerType.GENERIC_9X3, syncId);
|
||||
this.inventory = inventory;
|
||||
@@ -18,14 +19,13 @@ public class ModuleInventoryScreenHandler extends ScreenHandler {
|
||||
|
||||
public ModuleInventoryScreenHandler(int syncId, PlayerInventory playerInventory, ModuleInventory inventory) {
|
||||
super(ScreenHandlerType.GENERIC_9X3, syncId);
|
||||
int k;
|
||||
int j;
|
||||
|
||||
GenericContainerScreenHandler.checkSize(inventory, 3 * 9);
|
||||
this.inventory = inventory;
|
||||
inventory.onOpen(playerInventory.player);
|
||||
int i = (rows - 4) * 18;
|
||||
for (j = 0; j < rows; ++j) {
|
||||
for (k = 0; k < 9; ++k) {
|
||||
|
||||
for (int j = 0; j < rows; ++j) {
|
||||
for (int k = 0; k < 9; ++k) {
|
||||
this.addSlot(new Slot(inventory, k + j * 9, 8 + k * 18, 18 + j * 18) {
|
||||
@Override
|
||||
public boolean canInsert(ItemStack stack) {
|
||||
@@ -34,14 +34,8 @@ public class ModuleInventoryScreenHandler extends ScreenHandler {
|
||||
});
|
||||
}
|
||||
}
|
||||
for (j = 0; j < 3; ++j) {
|
||||
for (k = 0; k < 9; ++k) {
|
||||
this.addSlot(new Slot(playerInventory, k + j * 9 + 9, 8 + k * 18, 103 + j * 18 + i));
|
||||
}
|
||||
}
|
||||
for (j = 0; j < 9; ++j) {
|
||||
this.addSlot(new Slot(playerInventory, j, 8 + j * 18, 161 + i));
|
||||
}
|
||||
|
||||
addPlayerSlots(playerInventory, 8, 85);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,30 +1,43 @@
|
||||
package io.github.skippyall.minions.program;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import io.github.skippyall.minions.program.argument.Argument;
|
||||
import io.github.skippyall.minions.program.argument.ArgumentList;
|
||||
import io.github.skippyall.minions.program.argument.ArgumentType;
|
||||
import io.github.skippyall.minions.program.argument.Arguments;
|
||||
import io.github.skippyall.minions.program.supplier.ValueSupplier;
|
||||
import io.github.skippyall.minions.program.supplier.ValueSupplierList;
|
||||
import io.github.skippyall.minions.program.supplier.ValueSupplierType;
|
||||
import io.github.skippyall.minions.program.instruction.InstructionType;
|
||||
import io.github.skippyall.minions.program.returnvalue.ValueConsumerType;
|
||||
import io.github.skippyall.minions.program.consumer.ValueConsumer;
|
||||
import io.github.skippyall.minions.program.consumer.ValueConsumerList;
|
||||
import io.github.skippyall.minions.program.consumer.ValueConsumerType;
|
||||
import net.minecraft.registry.Registry;
|
||||
|
||||
public interface InstructionRuntime<R extends InstructionRuntime<R>> {
|
||||
Registry<ArgumentType<R>> getArgumentTypeRegistry();
|
||||
Registry<ValueSupplierType<R>> getArgumentTypeRegistry();
|
||||
|
||||
Registry<InstructionType<R>> getInstructionTypeRegistry();
|
||||
|
||||
Registry<ValueConsumerType<R>> getValueConsumerRegistry();
|
||||
Registry<ValueConsumerType<R>> getValueConsumerTypeRegistry();
|
||||
|
||||
default Codec<ArgumentType<R>> getArgumentTypeCodec() {
|
||||
default Codec<ValueSupplierType<R>> getArgumentTypeCodec() {
|
||||
return getArgumentTypeRegistry().getCodec();
|
||||
}
|
||||
|
||||
default Codec<Argument<?,R>> getArgumentCodec() {
|
||||
return Arguments.createArgumentCodec(getArgumentTypeCodec());
|
||||
default Codec<ValueSupplier<?,R>> getArgumentCodec() {
|
||||
return ValueSupplier.createArgumentCodec(getArgumentTypeCodec());
|
||||
}
|
||||
|
||||
default Codec<ArgumentList<R>> getArgumentListCodec() {
|
||||
return ArgumentList.getCodec(getArgumentTypeCodec());
|
||||
default Codec<ValueSupplierList<R>> getArgumentListCodec() {
|
||||
return ValueSupplierList.getCodec(getArgumentCodec());
|
||||
}
|
||||
|
||||
default Codec<ValueConsumerType<R>> getValueConsumerTypeCodec() {
|
||||
return getValueConsumerTypeRegistry().getCodec();
|
||||
}
|
||||
|
||||
default Codec<ValueConsumer<?,R>> getValueConsumerCodec() {
|
||||
return ValueConsumer.createValueConsumerCodec(getValueConsumerTypeCodec());
|
||||
}
|
||||
|
||||
default Codec<ValueConsumerList<R>> getValueConsumerListCodec() {
|
||||
return ValueConsumerList.getCodec(getValueConsumerCodec());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
package io.github.skippyall.minions.program.argument;
|
||||
|
||||
import io.github.skippyall.minions.gui.GuiDisplay;
|
||||
import io.github.skippyall.minions.program.InstructionRuntime;
|
||||
import io.github.skippyall.minions.program.value.ValueType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* An <code>Argument</code> can be supplied to an instruction with a matching parameter.
|
||||
* Its value is resolved at runtime and can vary between executions.
|
||||
* <code>Argument</code>s are created exclusively by <code>SpecificArgumentType</code>s.
|
||||
* @param <T> The type of the <code>Argument</code>'s value
|
||||
*/
|
||||
public interface Argument<T, R extends InstructionRuntime<R>> {
|
||||
T resolve(R minion);
|
||||
|
||||
GuiDisplay getDisplay();
|
||||
|
||||
ValueType<T> getValueType();
|
||||
|
||||
ArgumentType<R> getType();
|
||||
|
||||
default <U,A extends Argument<U,R>> @Nullable A cast(ValueType<U> type) {
|
||||
if(getValueType() == type) {
|
||||
//noinspection unchecked
|
||||
return (A) this;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
package io.github.skippyall.minions.program.argument;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import io.github.skippyall.minions.program.InstructionRuntime;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ArgumentList<R extends InstructionRuntime<R>> {
|
||||
private final Map<String, Argument<?, R>> arguments;
|
||||
|
||||
public ArgumentList() {
|
||||
arguments = new HashMap<>();
|
||||
}
|
||||
|
||||
public ArgumentList(Map<String, Argument<?,R>> arguments) {
|
||||
this.arguments = new HashMap<>(arguments);
|
||||
}
|
||||
|
||||
public <T> T getValue(Parameter<T> parameter, R runtime) {
|
||||
Argument<T,R> argument = getArgument(parameter);
|
||||
return argument != null ? argument.resolve(runtime) : null;
|
||||
}
|
||||
|
||||
public <T, A extends Argument<T,R>> A getArgument(Parameter<T> parameter) {
|
||||
Argument<?,R> argument = arguments.get(parameter.name());
|
||||
return argument == null ? null : argument.cast(parameter.type());
|
||||
}
|
||||
|
||||
public <T> void setArgument(Parameter<T> parameter, Argument<T,R> argument) {
|
||||
arguments.put(parameter.name(), argument);
|
||||
}
|
||||
|
||||
public boolean hasArgumentFor(Parameter<?> parameter) {
|
||||
return getArgument(parameter) != null;
|
||||
}
|
||||
|
||||
public boolean hasArgumentForAll(Collection<Parameter<?>> checkParameters) {
|
||||
for(Parameter<?> parameter : checkParameters) {
|
||||
if(!hasArgumentFor(parameter)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static <R extends InstructionRuntime<R>> Codec<ArgumentList<R>> getCodec(Codec<ArgumentType<R>> genericCodec) {
|
||||
return Codec.unboundedMap(Codec.STRING, Arguments.createArgumentCodec(genericCodec))
|
||||
.xmap(ArgumentList::new, list -> list.arguments);
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package io.github.skippyall.minions.program.argument;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import io.github.skippyall.minions.program.InstructionRuntime;
|
||||
import io.github.skippyall.minions.program.value.ValueType;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public abstract class ArgumentType<R extends InstructionRuntime<R>> {
|
||||
public abstract <T> Codec<? extends Argument<T,R>> getCodec(ValueType<T> type);
|
||||
|
||||
public abstract <T> CompletableFuture<? extends Argument<T,R>> openConfiguration(ServerPlayerEntity player, ValueType<T> valueType, @Nullable Argument<T,R> previous);
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package io.github.skippyall.minions.program.argument;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.program.InstructionRuntime;
|
||||
|
||||
public class Arguments {
|
||||
public static <R extends InstructionRuntime<R>> Codec<Argument<?,R>> createArgumentCodec(Codec<ArgumentType<R>> codec) {
|
||||
return codec.dispatch(
|
||||
"type",
|
||||
Argument::getType,
|
||||
type ->
|
||||
MinionRegistries.VALUE_TYPES.getCodec().<Argument<?,R>>dispatch(
|
||||
Argument::getValueType,
|
||||
valueType -> type.getCodec(valueType).fieldOf("valueType")
|
||||
).fieldOf("valueType")
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package io.github.skippyall.minions.program.consumer;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.gui.GuiDisplay;
|
||||
import io.github.skippyall.minions.program.InstructionRuntime;
|
||||
import io.github.skippyall.minions.program.value.ValueType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* An <code>ValueSupplier</code> can be supplied to an instruction with a matching parameter.
|
||||
* Its value is resolved at runtime and can vary between executions.
|
||||
* <code>ValueSupplier</code>s are created exclusively by <code>SpecificArgumentType</code>s.
|
||||
* @param <T> The type of the <code>ValueSupplier</code>'s value
|
||||
*/
|
||||
public interface ValueConsumer<T,R extends InstructionRuntime<R>> {
|
||||
void consume(T value, R runtime);
|
||||
|
||||
GuiDisplay getDisplay();
|
||||
|
||||
ValueType<T> getValueType();
|
||||
|
||||
ValueConsumerType<R> getType();
|
||||
|
||||
default <U,A extends ValueConsumer<U,R>> @Nullable A cast(ValueType<U> type) {
|
||||
if(getValueType() == type) {
|
||||
//noinspection unchecked
|
||||
return (A) this;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static <R extends InstructionRuntime<R>> Codec<ValueConsumer<?,R>> createValueConsumerCodec(Codec<ValueConsumerType<R>> codec) {
|
||||
return codec.dispatch(
|
||||
"type",
|
||||
ValueConsumer::getType,
|
||||
type ->
|
||||
MinionRegistries.VALUE_TYPES.getCodec().<ValueConsumer<?,R>>dispatch(
|
||||
ValueConsumer::getValueType,
|
||||
valueType -> type.getCodec(valueType).fieldOf("valueType")
|
||||
).fieldOf("valueType")
|
||||
);
|
||||
}
|
||||
}
|
||||
+11
-4
@@ -1,8 +1,8 @@
|
||||
package io.github.skippyall.minions.program.returnvalue;
|
||||
package io.github.skippyall.minions.program.consumer;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import io.github.skippyall.minions.program.InstructionRuntime;
|
||||
import io.github.skippyall.minions.program.argument.Parameter;
|
||||
import io.github.skippyall.minions.program.supplier.Parameter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -27,8 +27,15 @@ public class ValueConsumerList<R extends InstructionRuntime<R>> {
|
||||
valueConsumers.put(parameter.name(), consumer);
|
||||
}
|
||||
|
||||
public static <R extends InstructionRuntime<R>> Codec<ValueConsumerList<R>> getCodec(Codec<ValueConsumerType<R>> genericCodec) {
|
||||
return Codec.unboundedMap(Codec.STRING, ValueConsumers.createValueConsumersCodec(genericCodec))
|
||||
public <T> void setValue(Parameter<T> parameter, T value, R runtime) {
|
||||
ValueConsumer<T,R> consumer = getValueConsumer(parameter).cast(parameter.type());
|
||||
if (consumer != null) {
|
||||
consumer.consume(value, runtime);
|
||||
}
|
||||
}
|
||||
|
||||
public static <R extends InstructionRuntime<R>> Codec<ValueConsumerList<R>> getCodec(Codec<ValueConsumer<?,R>> valueConsumerCodec) {
|
||||
return Codec.unboundedMap(Codec.STRING, valueConsumerCodec)
|
||||
.xmap(ValueConsumerList::new, list -> list.valueConsumers);
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -1,8 +1,7 @@
|
||||
package io.github.skippyall.minions.program.returnvalue;
|
||||
package io.github.skippyall.minions.program.consumer;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import io.github.skippyall.minions.program.InstructionRuntime;
|
||||
import io.github.skippyall.minions.program.argument.Argument;
|
||||
import io.github.skippyall.minions.program.value.ValueType;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
+15
-10
@@ -2,33 +2,36 @@ package io.github.skippyall.minions.program.instruction;
|
||||
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.program.InstructionRuntime;
|
||||
import io.github.skippyall.minions.program.argument.ArgumentList;
|
||||
import io.github.skippyall.minions.program.supplier.ValueSupplierList;
|
||||
import io.github.skippyall.minions.program.consumer.ValueConsumerList;
|
||||
import net.minecraft.storage.ReadView;
|
||||
import net.minecraft.storage.WriteView;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ConfiguredInstruction<R extends InstructionRuntime<R>> {
|
||||
private final InstructionType<R> instruction;
|
||||
private final ArgumentList<R> arguments;
|
||||
private final ValueSupplierList<R> arguments;
|
||||
private final ValueConsumerList<R> valueConsumers;
|
||||
private @Nullable InstructionExecution<R> execution;
|
||||
private final String name;
|
||||
|
||||
private ConfiguredInstruction(InstructionType<R> instruction, ArgumentList<R> arguments, @Nullable InstructionExecution<R> execution, String name) {
|
||||
private ConfiguredInstruction(InstructionType<R> instruction, ValueSupplierList<R> arguments, ValueConsumerList<R> valueConsumers, @Nullable InstructionExecution<R> execution, String name) {
|
||||
this.instruction = instruction;
|
||||
this.arguments = arguments;
|
||||
this.valueConsumers = valueConsumers;
|
||||
this.execution = execution;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public ConfiguredInstruction(InstructionType<R> instruction, String name) {
|
||||
this(instruction, new ArgumentList<>(), null, name);
|
||||
this(instruction, new ValueSupplierList<>(), new ValueConsumerList<>(), null, name);
|
||||
}
|
||||
|
||||
public InstructionType<R> getInstruction() {
|
||||
return instruction;
|
||||
}
|
||||
|
||||
public ArgumentList<R> getArguments() {
|
||||
public ValueSupplierList<R> getArguments() {
|
||||
return arguments;
|
||||
}
|
||||
|
||||
@@ -75,7 +78,7 @@ public class ConfiguredInstruction<R extends InstructionRuntime<R>> {
|
||||
|
||||
public void stop(R minion) {
|
||||
if(isRunning()) {
|
||||
execution.stop(minion);
|
||||
execution.stop(minion, valueConsumers);
|
||||
execution = null;
|
||||
}
|
||||
}
|
||||
@@ -83,6 +86,7 @@ public class ConfiguredInstruction<R extends InstructionRuntime<R>> {
|
||||
public void save(WriteView view, R minion) {
|
||||
view.put("instruction", minion.getInstructionTypeRegistry().getCodec(), instruction);
|
||||
view.put("arguments", minion.getArgumentListCodec(), arguments);
|
||||
view.put("valueConsumers", minion.getValueConsumerListCodec(), valueConsumers);
|
||||
view.putBoolean("running", isRunning());
|
||||
if(isRunning()) {
|
||||
execution.save(view.get("execution"), minion);
|
||||
@@ -92,7 +96,8 @@ public class ConfiguredInstruction<R extends InstructionRuntime<R>> {
|
||||
public static <R extends InstructionRuntime<R>> ConfiguredInstruction<R> load(ReadView view, R minion, String name) {
|
||||
InstructionType<R> instructionType = view.read("instruction", minion.getInstructionTypeRegistry().getCodec()).orElseThrow();
|
||||
|
||||
ArgumentList<R> arguments = view.read("arguments", minion.getArgumentListCodec()).orElseThrow();
|
||||
ValueSupplierList<R> arguments = view.read("arguments", minion.getArgumentListCodec()).orElseGet(ValueSupplierList::new);
|
||||
ValueConsumerList<R> valueConsumers = view.read("valueConsumers", minion.getValueConsumerListCodec()).orElseGet(ValueConsumerList::new);
|
||||
|
||||
boolean running = view.getBoolean("running", false);
|
||||
|
||||
@@ -100,12 +105,12 @@ public class ConfiguredInstruction<R extends InstructionRuntime<R>> {
|
||||
ReadView executionView = view.getReadView("execution");
|
||||
try {
|
||||
InstructionExecution<R> execution = instructionType.loadExecution(executionView, minion);
|
||||
return new ConfiguredInstruction<>(instructionType, arguments, execution, name);
|
||||
return new ConfiguredInstruction<>(instructionType, arguments, valueConsumers, execution, name);
|
||||
} catch (Exception e) {
|
||||
|
||||
Minions.LOGGER.error("Error while loading execution", e);
|
||||
}
|
||||
}
|
||||
|
||||
return new ConfiguredInstruction<>(instructionType, arguments, null, name);
|
||||
return new ConfiguredInstruction<>(instructionType, arguments, valueConsumers, null, name);
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -1,7 +1,8 @@
|
||||
package io.github.skippyall.minions.program.instruction;
|
||||
|
||||
import io.github.skippyall.minions.program.InstructionRuntime;
|
||||
import io.github.skippyall.minions.program.argument.ArgumentList;
|
||||
import io.github.skippyall.minions.program.supplier.ValueSupplierList;
|
||||
import io.github.skippyall.minions.program.consumer.ValueConsumerList;
|
||||
import net.minecraft.storage.ReadView;
|
||||
import net.minecraft.storage.WriteView;
|
||||
|
||||
@@ -9,7 +10,7 @@ import net.minecraft.storage.WriteView;
|
||||
* Responsible for executing instructions.
|
||||
* When an instruction is executed:
|
||||
* <li>A new instance is created using the factory</li>
|
||||
* <li>{@link InstructionExecution#readArguments(ArgumentList, R) readFromParameters} is called</li>
|
||||
* <li>{@link InstructionExecution#readArguments(ValueSupplierList, R) readFromParameters} is called</li>
|
||||
* <li>{@link InstructionExecution#start(R) start} is called</li>
|
||||
*/
|
||||
public interface InstructionExecution<R extends InstructionRuntime<R>> {
|
||||
@@ -32,19 +33,18 @@ public interface InstructionExecution<R extends InstructionRuntime<R>> {
|
||||
|
||||
/**
|
||||
* Stops this execution. Is called when isDone returns true, but it may also be called before that.
|
||||
* In this case, the return value is ignored.
|
||||
* This should undo changes to the minion unless they are supposed to be permanent.
|
||||
*
|
||||
* @param runtime The runtime that was executing this instruction.
|
||||
*/
|
||||
void stop(R runtime);
|
||||
void stop(R runtime, ValueConsumerList<R> valueConsumers);
|
||||
|
||||
/**
|
||||
* Initializes the execution with its arguments.
|
||||
* Initializes the execution with its parameters. The parameters must be defined by the InstructionType
|
||||
* @param arguments The arguments to initialize the execution
|
||||
* @param runtime The runtime should be used to resolve the arguments
|
||||
*/
|
||||
void readArguments(ArgumentList<R> arguments, R runtime);
|
||||
void readArguments(ValueSupplierList<R> arguments, R runtime);
|
||||
|
||||
/**
|
||||
* Saves the execution, e.g. when the server is closed.
|
||||
|
||||
+11
-14
@@ -2,9 +2,8 @@ package io.github.skippyall.minions.program.instruction;
|
||||
|
||||
import io.github.skippyall.minions.gui.GuiDisplay;
|
||||
import io.github.skippyall.minions.program.InstructionRuntime;
|
||||
import io.github.skippyall.minions.program.argument.Parameter;
|
||||
import io.github.skippyall.minions.program.argument.ArgumentList;
|
||||
import io.github.skippyall.minions.program.value.ValueType;
|
||||
import io.github.skippyall.minions.program.supplier.Parameter;
|
||||
import io.github.skippyall.minions.program.supplier.ValueSupplierList;
|
||||
import net.minecraft.storage.ReadView;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -14,31 +13,29 @@ import java.util.function.Supplier;
|
||||
public class InstructionType<R extends InstructionRuntime<R>> {
|
||||
private final GuiDisplay display;
|
||||
private final Collection<Parameter<?>> parameters;
|
||||
private final Collection<Parameter<?>> returnParameters;
|
||||
private final Supplier<InstructionExecution<R>> executionFactory;
|
||||
|
||||
private InstructionType(GuiDisplay display, Supplier<InstructionExecution<R>> executionFactory, Collection<Parameter<?>> parameters) {
|
||||
public InstructionType(GuiDisplay display, Supplier<InstructionExecution<R>> executionFactory, Collection<Parameter<?>> parameters, Collection<Parameter<?>> returnParameters) {
|
||||
this.display = display;
|
||||
this.parameters = parameters;
|
||||
this.parameters = List.copyOf(parameters);
|
||||
this.returnParameters = List.copyOf(returnParameters);
|
||||
this.executionFactory = executionFactory;
|
||||
}
|
||||
|
||||
public static <R extends InstructionRuntime<R>> InstructionType<R> create(GuiDisplay display, Supplier<InstructionExecution<R>> executionFactory, Collection<Parameter<?>> parameters) {
|
||||
return new InstructionType<>(display, executionFactory, List.copyOf(parameters));
|
||||
}
|
||||
|
||||
public static <Return,R extends InstructionRuntime<R>> InstructionType<R> create(GuiDisplay display, Supplier<InstructionExecution<R>> executionFactory, ValueType<Return> returnType, Parameter<?>... parameters) {
|
||||
return new InstructionType<>(display, executionFactory, List.of(parameters));
|
||||
}
|
||||
|
||||
public Collection<Parameter<?>> getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
public Collection<Parameter<?>> getReturnParameters() {
|
||||
return returnParameters;
|
||||
}
|
||||
|
||||
public GuiDisplay getDisplay() {
|
||||
return display;
|
||||
}
|
||||
|
||||
public InstructionExecution<R> createExecution(ArgumentList<R> parameters, R minion) {
|
||||
public InstructionExecution<R> createExecution(ValueSupplierList<R> parameters, R minion) {
|
||||
InstructionExecution<R> execution = executionFactory.get();
|
||||
execution.readArguments(parameters, minion);
|
||||
return execution;
|
||||
|
||||
@@ -3,47 +3,60 @@ package io.github.skippyall.minions.program.instruction;
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.gui.GuiDisplay;
|
||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.EntityPlayerActionPack;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.program.instruction.execution.ActionExecution;
|
||||
import io.github.skippyall.minions.program.instruction.execution.TurnExecution;
|
||||
import io.github.skippyall.minions.program.instruction.execution.WalkExecution;
|
||||
import io.github.skippyall.minions.program.argument.Parameter;
|
||||
import io.github.skippyall.minions.program.value.ValueType;
|
||||
import io.github.skippyall.minions.program.value.ValueTypes;
|
||||
import io.github.skippyall.minions.program.supplier.Parameter;
|
||||
import io.github.skippyall.minions.util.ModelIdUtil;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class Instructions {
|
||||
public static final InstructionType<Void, MinionFakePlayer> WALK = register(
|
||||
public static final InstructionType<MinionRuntime> WALK = register(
|
||||
"walk",
|
||||
base -> new GuiDisplay.ModelBased(ModelIdUtil.getItemModelId(Items.IRON_BOOTS), base, true),
|
||||
WalkExecution::new,
|
||||
ValueTypes.VOID,
|
||||
WalkExecution.blocksToMoveParam
|
||||
List.of(WalkExecution.blocksToMoveParam)
|
||||
);
|
||||
|
||||
public static final InstructionType<Void, MinionFakePlayer> ATTACK = register(
|
||||
public static final InstructionType<MinionRuntime> TURN = register(
|
||||
"turn",
|
||||
base -> new GuiDisplay.ModelBased(Items.STRUCTURE_VOID, base, true),
|
||||
TurnExecution::new,
|
||||
List.of(TurnExecution.ANGLE, TurnExecution.DIRECTION)
|
||||
);
|
||||
|
||||
public static final InstructionType<MinionRuntime> ATTACK = register(
|
||||
"attack",
|
||||
base -> new GuiDisplay.ModelBased(ModelIdUtil.getItemModelId(Items.IRON_BOOTS), base, true),
|
||||
() -> new ActionExecution(EntityPlayerActionPack.ActionType.ATTACK),
|
||||
ValueTypes.VOID
|
||||
() -> new ActionExecution(EntityPlayerActionPack.ActionType.ATTACK)
|
||||
);
|
||||
|
||||
public static final InstructionType<Void, MinionFakePlayer> USE = register(
|
||||
public static final InstructionType<MinionRuntime> USE = register(
|
||||
"use",
|
||||
base -> new GuiDisplay.ModelBased(ModelIdUtil.getItemModelId(Items.LEVER), base, true),
|
||||
() -> new ActionExecution(EntityPlayerActionPack.ActionType.USE),
|
||||
ValueTypes.VOID
|
||||
() -> new ActionExecution(EntityPlayerActionPack.ActionType.USE)
|
||||
);
|
||||
|
||||
private static <R> InstructionType<R, MinionFakePlayer> register(String id, Function<String, GuiDisplay> displayFunction, Supplier<InstructionExecution<R,MinionFakePlayer>> factory, ValueType<R> returnType, Parameter<?>... parameters) {
|
||||
private static InstructionType<MinionRuntime> register(String id, Function<String, GuiDisplay> displayFunction, Supplier<InstructionExecution<MinionRuntime>> factory, Collection<Parameter<?>> parameters, Collection<Parameter<?>> returnParameters) {
|
||||
Identifier identifier = Identifier.of(Minions.MOD_ID, id);
|
||||
return Registry.register(MinionRegistries.INSTRUCTION_TYPES, identifier, InstructionType.create(displayFunction.apply(identifier.toTranslationKey("instruction_type")), factory, returnType, parameters));
|
||||
return Registry.register(MinionRegistries.INSTRUCTION_TYPES, identifier, new InstructionType<>(displayFunction.apply(identifier.toTranslationKey("instruction_type")), factory, parameters, returnParameters));
|
||||
}
|
||||
|
||||
private static InstructionType<MinionRuntime> register(String id, Function<String, GuiDisplay> displayFunction, Supplier<InstructionExecution<MinionRuntime>> factory, Collection<Parameter<?>> parameters) {
|
||||
return register(id, displayFunction, factory, parameters, List.of());
|
||||
}
|
||||
|
||||
private static InstructionType<MinionRuntime> register(String id, Function<String, GuiDisplay> displayFunction, Supplier<InstructionExecution<MinionRuntime>> factory) {
|
||||
return register(id, displayFunction, factory, List.of(), List.of());
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
|
||||
+12
-12
@@ -1,12 +1,13 @@
|
||||
package io.github.skippyall.minions.program.instruction.execution;
|
||||
|
||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.EntityPlayerActionPack;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.program.argument.ArgumentList;
|
||||
import io.github.skippyall.minions.program.consumer.ValueConsumerList;
|
||||
import io.github.skippyall.minions.program.supplier.ValueSupplierList;
|
||||
import net.minecraft.storage.ReadView;
|
||||
import net.minecraft.storage.WriteView;
|
||||
|
||||
public class ActionExecution implements ContinuousInstructionExecution {
|
||||
public class ActionExecution implements ContinuousInstructionExecution<MinionRuntime> {
|
||||
private final EntityPlayerActionPack.ActionType action;
|
||||
|
||||
public ActionExecution(EntityPlayerActionPack.ActionType action) {
|
||||
@@ -14,24 +15,23 @@ public class ActionExecution implements ContinuousInstructionExecution {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(MinionFakePlayer minion) {
|
||||
minion.getMinionActionPack().start(action, EntityPlayerActionPack.Action.continuous());
|
||||
public void start(MinionRuntime minion) {
|
||||
minion.getMinion().getMinionActionPack().start(action, EntityPlayerActionPack.Action.continuous());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void stop(MinionFakePlayer minion) {
|
||||
minion.getMinionActionPack().stop(action);
|
||||
return null;
|
||||
public void stop(MinionRuntime minion, ValueConsumerList<MinionRuntime> valueConsumers) {
|
||||
minion.getMinion().getMinionActionPack().stop(action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readArguments(ArgumentList parameters, MinionFakePlayer minion) {}
|
||||
public void readArguments(ValueSupplierList<MinionRuntime> parameters, MinionRuntime minion) {}
|
||||
|
||||
@Override
|
||||
public void save(WriteView view, MinionFakePlayer minion) {}
|
||||
public void save(WriteView view, MinionRuntime minion) {}
|
||||
|
||||
@Override
|
||||
public void load(ReadView view, MinionFakePlayer minion) {
|
||||
minion.getMinionActionPack().start(action, EntityPlayerActionPack.Action.continuous());
|
||||
public void load(ReadView view, MinionRuntime minion) {
|
||||
minion.getMinion().getMinionActionPack().start(action, EntityPlayerActionPack.Action.continuous());
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
package io.github.skippyall.minions.program.instruction.execution;
|
||||
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.program.InstructionRuntime;
|
||||
import io.github.skippyall.minions.program.instruction.InstructionExecution;
|
||||
|
||||
public interface ContinuousInstructionExecution extends InstructionExecution<Void,MinionFakePlayer> {
|
||||
public interface ContinuousInstructionExecution<R extends InstructionRuntime<R>> extends InstructionExecution<R> {
|
||||
@Override
|
||||
default boolean isDone(MinionFakePlayer minion) {
|
||||
default boolean isDone(R minion) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -1,6 +1,6 @@
|
||||
package io.github.skippyall.minions.program.instruction.execution;
|
||||
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.program.InstructionRuntime;
|
||||
import io.github.skippyall.minions.program.instruction.InstructionExecution;
|
||||
import net.minecraft.storage.ReadView;
|
||||
import net.minecraft.storage.WriteView;
|
||||
@@ -10,7 +10,7 @@ import net.minecraft.storage.WriteView;
|
||||
* The timer must be set with <code>setTimer</code> when reading from parameters.
|
||||
* Saving and loading of the timer is automatic if the super method is called by the subclass.
|
||||
*/
|
||||
public abstract class TimedInstructionExecution<T> implements InstructionExecution<T,MinionFakePlayer> {
|
||||
public abstract class TimedInstructionExecution<R extends InstructionRuntime<R>> implements InstructionExecution<R> {
|
||||
int timer;
|
||||
|
||||
public int getTimer() {
|
||||
@@ -22,22 +22,22 @@ public abstract class TimedInstructionExecution<T> implements InstructionExecuti
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(MinionFakePlayer minion) {
|
||||
public void tick(R minion) {
|
||||
timer--;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDone(MinionFakePlayer minion) {
|
||||
public boolean isDone(R minion) {
|
||||
return timer > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(WriteView view, MinionFakePlayer minion) {
|
||||
public void save(WriteView view, R minion) {
|
||||
view.putInt("timer", timer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(ReadView view, MinionFakePlayer minion) {
|
||||
public void load(ReadView view, R minion) {
|
||||
timer = view.getInt("timer", 0);
|
||||
}
|
||||
}
|
||||
|
||||
+12
-12
@@ -3,9 +3,10 @@ package io.github.skippyall.minions.program.instruction.execution;
|
||||
import com.mojang.serialization.Codec;
|
||||
import io.github.skippyall.minions.gui.Displayable;
|
||||
import io.github.skippyall.minions.gui.GuiDisplay;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.program.argument.ArgumentList;
|
||||
import io.github.skippyall.minions.program.argument.Parameter;
|
||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||
import io.github.skippyall.minions.program.consumer.ValueConsumerList;
|
||||
import io.github.skippyall.minions.program.supplier.ValueSupplierList;
|
||||
import io.github.skippyall.minions.program.supplier.Parameter;
|
||||
import io.github.skippyall.minions.program.instruction.InstructionExecution;
|
||||
import io.github.skippyall.minions.program.value.ValueTypes;
|
||||
import net.minecraft.storage.ReadView;
|
||||
@@ -14,7 +15,7 @@ import net.minecraft.util.StringIdentifiable;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class TurnExecution implements InstructionExecution<Void,MinionFakePlayer> {
|
||||
public class TurnExecution implements InstructionExecution<MinionRuntime> {
|
||||
public static final Parameter<Float> ANGLE = new Parameter<>("maxAngle", ValueTypes.FLOAT);
|
||||
public static final Parameter<TurnDirection> DIRECTION = new Parameter<>("direction", ValueTypes.TURN_DIRECTION);
|
||||
|
||||
@@ -25,37 +26,36 @@ public class TurnExecution implements InstructionExecution<Void,MinionFakePlayer
|
||||
private TurnDirection direction;
|
||||
|
||||
@Override
|
||||
public void tick(MinionFakePlayer minion) {
|
||||
public void tick(MinionRuntime minion) {
|
||||
float toRotate = Math.min(anglePerTick, maxAngle - rotatedAngle);
|
||||
minion.getMinionActionPack().turn(direction.xFactor * toRotate, direction.yFactor * toRotate);
|
||||
minion.getMinion().getMinionActionPack().turn(direction.xFactor * toRotate, direction.yFactor * toRotate);
|
||||
|
||||
rotatedAngle += toRotate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDone(MinionFakePlayer minion) {
|
||||
public boolean isDone(MinionRuntime minion) {
|
||||
return Math.abs(maxAngle - rotatedAngle) < 0.001F;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void stop(MinionFakePlayer minion) {
|
||||
return null;
|
||||
public void stop(MinionRuntime minion, ValueConsumerList<MinionRuntime> valueConsumers) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readArguments(ArgumentList<MinionFakePlayer> arguments, MinionFakePlayer minion) {
|
||||
public void readArguments(ValueSupplierList<MinionRuntime> arguments, MinionRuntime minion) {
|
||||
maxAngle = arguments.getValue(ANGLE, minion);
|
||||
direction = arguments.getValue(DIRECTION, minion);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(WriteView view, MinionFakePlayer minion) {
|
||||
public void save(WriteView view, MinionRuntime minion) {
|
||||
view.putFloat("maxAngle", maxAngle);
|
||||
view.put("direction", TurnDirection.CODEC, direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(ReadView view, MinionFakePlayer minion) {
|
||||
public void load(ReadView view, MinionRuntime minion) {
|
||||
maxAngle = view.getFloat("maxAngle", 0);
|
||||
direction = view.read("direction", TurnDirection.CODEC).orElseThrow();
|
||||
}
|
||||
|
||||
+15
-14
@@ -1,52 +1,53 @@
|
||||
package io.github.skippyall.minions.program.instruction.execution;
|
||||
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||
import io.github.skippyall.minions.program.consumer.ValueConsumerList;
|
||||
import io.github.skippyall.minions.program.instruction.InstructionExecution;
|
||||
import io.github.skippyall.minions.program.argument.Parameter;
|
||||
import io.github.skippyall.minions.program.argument.ArgumentList;
|
||||
import io.github.skippyall.minions.program.supplier.Parameter;
|
||||
import io.github.skippyall.minions.program.supplier.ValueSupplierList;
|
||||
import io.github.skippyall.minions.program.value.ValueTypes;
|
||||
import net.minecraft.entity.MovementType;
|
||||
import net.minecraft.storage.ReadView;
|
||||
import net.minecraft.storage.WriteView;
|
||||
|
||||
public class WalkExecution implements InstructionExecution<Void,MinionFakePlayer> {
|
||||
public class WalkExecution implements InstructionExecution<MinionRuntime> {
|
||||
public static final Parameter<Float> blocksToMoveParam = new Parameter<>("blocksToMove", ValueTypes.FLOAT);
|
||||
private final float ACCURACY = 1F / 32F;
|
||||
private static final float ACCURACY = 1F / 32F;
|
||||
|
||||
private float totalBlocksToMove;
|
||||
private float blocksMoved;
|
||||
|
||||
@Override
|
||||
public void tick(MinionFakePlayer minion) {
|
||||
float speed = Math.min(minion.getMovementSpeed(), totalBlocksToMove - blocksMoved);
|
||||
minion.move(MovementType.SELF, minion.getHorizontalFacing().getDoubleVector().normalize().multiply(speed));
|
||||
public void tick(MinionRuntime minion) {
|
||||
float speed = Math.min(minion.getMinion().getMovementSpeed(), totalBlocksToMove - blocksMoved);
|
||||
minion.getMinion().move(MovementType.SELF, minion.getMinion().getHorizontalFacing().getDoubleVector().normalize().multiply(speed));
|
||||
blocksMoved += speed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDone(MinionFakePlayer minion) {
|
||||
public boolean isDone(MinionRuntime minion) {
|
||||
return totalBlocksToMove - blocksMoved < ACCURACY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void stop(MinionFakePlayer minion) {
|
||||
return null;
|
||||
public void stop(MinionRuntime minion, ValueConsumerList<MinionRuntime> valueConsumers) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readArguments(ArgumentList<MinionFakePlayer> parameters, MinionFakePlayer minion) {
|
||||
public void readArguments(ValueSupplierList<MinionRuntime> parameters, MinionRuntime minion) {
|
||||
totalBlocksToMove = parameters.getValue(blocksToMoveParam, minion);
|
||||
blocksMoved = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(WriteView view, MinionFakePlayer minion) {
|
||||
public void save(WriteView view, MinionRuntime minion) {
|
||||
view.putFloat("totalBlocksToMove", totalBlocksToMove);
|
||||
view.putFloat("blocksMoved", blocksMoved);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(ReadView view, MinionFakePlayer minion) {
|
||||
public void load(ReadView view, MinionRuntime minion) {
|
||||
totalBlocksToMove = view.getFloat("totalBlocksToMove", 0F);
|
||||
blocksMoved = view.getFloat("blocksMoved", 0F);
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
package io.github.skippyall.minions.program.returnvalue;
|
||||
|
||||
import io.github.skippyall.minions.gui.GuiDisplay;
|
||||
import io.github.skippyall.minions.program.InstructionRuntime;
|
||||
import io.github.skippyall.minions.program.argument.ArgumentType;
|
||||
import io.github.skippyall.minions.program.value.ValueType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* An <code>Argument</code> can be supplied to an instruction with a matching parameter.
|
||||
* Its value is resolved at runtime and can vary between executions.
|
||||
* <code>Argument</code>s are created exclusively by <code>SpecificArgumentType</code>s.
|
||||
* @param <T> The type of the <code>Argument</code>'s value
|
||||
*/
|
||||
public interface ValueConsumer<T,R extends InstructionRuntime<R>> {
|
||||
void consume(T value, R runtime);
|
||||
|
||||
GuiDisplay getDisplay();
|
||||
|
||||
ValueType<T> getValueType();
|
||||
|
||||
ValueConsumerType<R> getType();
|
||||
|
||||
default <U,A extends ValueConsumer<U,R>> @Nullable A cast(ValueType<U> type) {
|
||||
if(getValueType() == type) {
|
||||
//noinspection unchecked
|
||||
return (A) this;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package io.github.skippyall.minions.program.returnvalue;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||
import io.github.skippyall.minions.program.InstructionRuntime;
|
||||
import io.github.skippyall.minions.program.argument.Argument;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class ValueConsumers {
|
||||
public static <R extends InstructionRuntime<R>> Codec<ValueConsumer<?,R>> createValueConsumersCodec(Codec<ValueConsumerType<R>> codec) {
|
||||
return codec.dispatch(
|
||||
"type",
|
||||
ValueConsumer::getType,
|
||||
type ->
|
||||
MinionRegistries.VALUE_TYPES.getCodec().<ValueConsumer<?,R>>dispatch(
|
||||
ValueConsumer::getValueType,
|
||||
valueType -> type.getCodec(valueType).fieldOf("valueType")
|
||||
).fieldOf("valueType")
|
||||
);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package io.github.skippyall.minions.program.argument;
|
||||
package io.github.skippyall.minions.program.supplier;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
+3
-4
@@ -1,14 +1,13 @@
|
||||
package io.github.skippyall.minions.program.argument;
|
||||
package io.github.skippyall.minions.program.supplier;
|
||||
|
||||
import io.github.skippyall.minions.gui.GuiDisplay;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.program.InstructionRuntime;
|
||||
import io.github.skippyall.minions.program.value.ValueType;
|
||||
|
||||
/**
|
||||
* An argument that always resolves to a fixed value
|
||||
* An supplier that always resolves to a fixed value
|
||||
*/
|
||||
public class ValueArgument<T, R extends InstructionRuntime<R>> implements Argument<T, R> {
|
||||
public class ValueArgument<T, R extends InstructionRuntime<R>> implements ValueSupplier<T, R> {
|
||||
private final ValueArgumentType<R> type;
|
||||
private final ValueType<T> valueType;
|
||||
private final T value;
|
||||
+4
-4
@@ -1,4 +1,4 @@
|
||||
package io.github.skippyall.minions.program.argument;
|
||||
package io.github.skippyall.minions.program.supplier;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import io.github.skippyall.minions.program.InstructionRuntime;
|
||||
@@ -8,17 +8,17 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class ValueArgumentType<R extends InstructionRuntime<R>> extends ArgumentType<R> {
|
||||
public class ValueArgumentType<R extends InstructionRuntime<R>> extends ValueSupplierType<R> {
|
||||
@Override
|
||||
public <T> Codec<ValueArgument<T,R>> getCodec(ValueType<T> valueType) {
|
||||
return valueType.codec().xmap(value -> new ValueArgument<>(this, valueType, value), ValueArgument::getValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> CompletableFuture<ValueArgument<V,R>> openConfiguration(ServerPlayerEntity player, ValueType<V> valueType, @Nullable Argument<V,R> previousArgument) {
|
||||
public <V> CompletableFuture<ValueArgument<V,R>> openConfiguration(ServerPlayerEntity player, ValueType<V> valueType, @Nullable ValueSupplier<V,R> previousValueSupplier) {
|
||||
return valueType.openValueDialog(
|
||||
player,
|
||||
previousArgument instanceof ValueArgument<V,R> val ? val.getValue() : valueType.defaultValue()
|
||||
previousValueSupplier instanceof ValueArgument<V,R> val ? val.getValue() : valueType.defaultValue()
|
||||
).thenApply(value -> new ValueArgument<>(this, valueType, value));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package io.github.skippyall.minions.program.supplier;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.gui.GuiDisplay;
|
||||
import io.github.skippyall.minions.program.InstructionRuntime;
|
||||
import io.github.skippyall.minions.program.value.ValueType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* An <code>ValueSupplier</code> can be supplied to an instruction with a matching parameter.
|
||||
* Its value is resolved at runtime and can vary between executions.
|
||||
* <code>ValueSupplier</code>s are created exclusively by <code>SpecificArgumentType</code>s.
|
||||
* @param <T> The type of the <code>ValueSupplier</code>'s value
|
||||
*/
|
||||
public interface ValueSupplier<T, R extends InstructionRuntime<R>> {
|
||||
T resolve(R minion);
|
||||
|
||||
GuiDisplay getDisplay();
|
||||
|
||||
ValueType<T> getValueType();
|
||||
|
||||
ValueSupplierType<R> getType();
|
||||
|
||||
default <U,A extends ValueSupplier<U,R>> @Nullable A cast(ValueType<U> type) {
|
||||
if(getValueType() == type) {
|
||||
//noinspection unchecked
|
||||
return (A) this;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static <R extends InstructionRuntime<R>> Codec<ValueSupplier<?,R>> createArgumentCodec(Codec<ValueSupplierType<R>> codec) {
|
||||
return codec.dispatch(
|
||||
"type",
|
||||
ValueSupplier::getType,
|
||||
type ->
|
||||
MinionRegistries.VALUE_TYPES.getCodec().<ValueSupplier<?,R>>dispatch(
|
||||
ValueSupplier::getValueType,
|
||||
valueType -> type.getCodec(valueType).fieldOf("valueType")
|
||||
).fieldOf("valueType")
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package io.github.skippyall.minions.program.supplier;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import io.github.skippyall.minions.program.InstructionRuntime;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ValueSupplierList<R extends InstructionRuntime<R>> {
|
||||
private final Map<String, ValueSupplier<?, R>> arguments;
|
||||
|
||||
public ValueSupplierList() {
|
||||
arguments = new HashMap<>();
|
||||
}
|
||||
|
||||
public ValueSupplierList(Map<String, ValueSupplier<?,R>> arguments) {
|
||||
this.arguments = new HashMap<>(arguments);
|
||||
}
|
||||
|
||||
public <T> T getValue(Parameter<T> parameter, R runtime) {
|
||||
ValueSupplier<T,R> valueSupplier = getArgument(parameter);
|
||||
return valueSupplier != null ? valueSupplier.resolve(runtime) : null;
|
||||
}
|
||||
|
||||
public <T, A extends ValueSupplier<T,R>> A getArgument(Parameter<T> parameter) {
|
||||
ValueSupplier<?,R> valueSupplier = arguments.get(parameter.name());
|
||||
return valueSupplier == null ? null : valueSupplier.cast(parameter.type());
|
||||
}
|
||||
|
||||
public <T> void setArgument(Parameter<T> parameter, ValueSupplier<T,R> valueSupplier) {
|
||||
arguments.put(parameter.name(), valueSupplier);
|
||||
}
|
||||
|
||||
public boolean hasArgumentFor(Parameter<?> parameter) {
|
||||
return getArgument(parameter) != null;
|
||||
}
|
||||
|
||||
public boolean hasArgumentForAll(Collection<Parameter<?>> checkParameters) {
|
||||
for(Parameter<?> parameter : checkParameters) {
|
||||
if(!hasArgumentFor(parameter)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static <R extends InstructionRuntime<R>> Codec<ValueSupplierList<R>> getCodec(Codec<ValueSupplier<?,R>> argumentCodec) {
|
||||
return Codec.unboundedMap(Codec.STRING, argumentCodec)
|
||||
.xmap(ValueSupplierList::new, list -> list.arguments);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package io.github.skippyall.minions.program.supplier;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import io.github.skippyall.minions.program.InstructionRuntime;
|
||||
import io.github.skippyall.minions.program.value.ValueType;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public abstract class ValueSupplierType<R extends InstructionRuntime<R>> {
|
||||
public abstract <T> Codec<? extends ValueSupplier<T,R>> getCodec(ValueType<T> type);
|
||||
|
||||
public abstract <T> CompletableFuture<? extends ValueSupplier<T,R>> openConfiguration(ServerPlayerEntity player, ValueType<T> valueType, @Nullable ValueSupplier<T,R> previous);
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"values": [
|
||||
"minions:minion_trigger"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user