Cast, Convert & more
This commit is contained in:
@@ -2,7 +2,7 @@ package io.github.skippyall.minions.client;
|
|||||||
|
|
||||||
import eu.pb4.polymer.networking.api.client.PolymerClientNetworking;
|
import eu.pb4.polymer.networking.api.client.PolymerClientNetworking;
|
||||||
import io.github.skippyall.minions.registration.MinionBlocks;
|
import io.github.skippyall.minions.registration.MinionBlocks;
|
||||||
import io.github.skippyall.minions.util.PolymerUtil;
|
import io.github.skippyall.minions.polymer.VersionSync;
|
||||||
import net.fabricmc.api.ClientModInitializer;
|
import net.fabricmc.api.ClientModInitializer;
|
||||||
import net.fabricmc.fabric.api.client.rendering.v1.BlockRenderLayerMap;
|
import net.fabricmc.fabric.api.client.rendering.v1.BlockRenderLayerMap;
|
||||||
import net.minecraft.client.render.BlockRenderLayer;
|
import net.minecraft.client.render.BlockRenderLayer;
|
||||||
@@ -12,6 +12,6 @@ public class MinionsClient implements ClientModInitializer {
|
|||||||
public void onInitializeClient() {
|
public void onInitializeClient() {
|
||||||
BlockRenderLayerMap.putBlock(MinionBlocks.MINION_TRIGGER_BLOCK, BlockRenderLayer.TRANSLUCENT);
|
BlockRenderLayerMap.putBlock(MinionBlocks.MINION_TRIGGER_BLOCK, BlockRenderLayer.TRANSLUCENT);
|
||||||
|
|
||||||
PolymerClientNetworking.registerCommonHandler(PolymerUtil.VersionSyncPayload.class, (client, handler, payload) -> {});
|
PolymerClientNetworking.registerCommonHandler(VersionSync.VersionSyncPayload.class, (client, handler, payload) -> {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,13 +2,16 @@ package io.github.skippyall.minions;
|
|||||||
|
|
||||||
import eu.pb4.polymer.resourcepack.api.PolymerResourcePackUtils;
|
import eu.pb4.polymer.resourcepack.api.PolymerResourcePackUtils;
|
||||||
import io.github.skippyall.minions.command.MinionsCommand;
|
import io.github.skippyall.minions.command.MinionsCommand;
|
||||||
|
import io.github.skippyall.minions.docs.DocsManager;
|
||||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||||
import io.github.skippyall.minions.minion.MinionPersistentState;
|
import io.github.skippyall.minions.minion.MinionPersistentState;
|
||||||
import io.github.skippyall.minions.registration.MinionRegistration;
|
import io.github.skippyall.minions.registration.MinionRegistration;
|
||||||
import io.github.skippyall.minions.util.PolymerUtil;
|
import io.github.skippyall.minions.polymer.VersionSync;
|
||||||
import net.fabricmc.api.ModInitializer;
|
import net.fabricmc.api.ModInitializer;
|
||||||
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
|
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
|
||||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||||
|
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
|
||||||
|
import net.minecraft.resource.ResourceType;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -23,7 +26,7 @@ public class Minions implements ModInitializer {
|
|||||||
|
|
||||||
MinionRegistration.register();
|
MinionRegistration.register();
|
||||||
|
|
||||||
PolymerUtil.register();
|
VersionSync.register();
|
||||||
|
|
||||||
ServerLifecycleEvents.SERVER_STARTED.register(server -> {
|
ServerLifecycleEvents.SERVER_STARTED.register(server -> {
|
||||||
MinionPersistentState.get(server).getMinionData().forEach((uuid, data) -> {
|
MinionPersistentState.get(server).getMinionData().forEach((uuid, data) -> {
|
||||||
@@ -42,5 +45,7 @@ public class Minions implements ModInitializer {
|
|||||||
});*/
|
});*/
|
||||||
|
|
||||||
PolymerResourcePackUtils.addModAssets(Minions.MOD_ID);
|
PolymerResourcePackUtils.addModAssets(Minions.MOD_ID);
|
||||||
|
|
||||||
|
ResourceManagerHelper.get(ResourceType.SERVER_DATA).registerReloadListener(new DocsManager());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package io.github.skippyall.minions.block.input;
|
||||||
|
|
||||||
|
import io.github.skippyall.minions.clipboard.ClipboardItem;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.util.ActionResult;
|
||||||
|
import net.minecraft.util.hit.BlockHitResult;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public class AnalogInputBlock extends Block {
|
||||||
|
public AnalogInputBlock(Settings settings) {
|
||||||
|
super(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit) {
|
||||||
|
player.getInventory().offer(ClipboardItem.createBlockPosReference(world, pos), true);
|
||||||
|
return ActionResult.SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
+63
@@ -0,0 +1,63 @@
|
|||||||
|
package io.github.skippyall.minions.block.instruction_bound;
|
||||||
|
|
||||||
|
import io.github.skippyall.minions.block.miniontrigger.MinionTriggerBlockEntity;
|
||||||
|
import io.github.skippyall.minions.clipboard.InstructionClipboard;
|
||||||
|
import io.github.skippyall.minions.minion.MinionPersistentState;
|
||||||
|
import io.github.skippyall.minions.registration.MinionBlocks;
|
||||||
|
import io.github.skippyall.minions.registration.MinionComponentTypes;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockEntityProvider;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.entity.BlockEntityType;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.server.world.ServerWorld;
|
||||||
|
import net.minecraft.sound.SoundCategory;
|
||||||
|
import net.minecraft.sound.SoundEvents;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.ActionResult;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.hit.BlockHitResult;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public abstract class InstructionBoundBlock extends Block implements BlockEntityProvider {
|
||||||
|
public InstructionBoundBlock(Settings settings) {
|
||||||
|
super(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract BlockEntityType<? extends InstructionBoundBlockEntity<?>> getBlockEntityType();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ActionResult onUseWithItem(ItemStack stack, BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
|
||||||
|
if(stack.get(MinionComponentTypes.REFERENCE) instanceof InstructionClipboard instruction) {
|
||||||
|
world.getBlockEntity(pos, getBlockEntityType()).ifPresent(be -> {
|
||||||
|
be.setInstruction(instruction.selectedMinion(), instruction.selectedInstruction());
|
||||||
|
player.playSoundToPlayer(SoundEvents.BLOCK_NOTE_BLOCK_CHIME.value(), SoundCategory.BLOCKS, 1, 1);
|
||||||
|
stack.decrement(1);
|
||||||
|
});
|
||||||
|
return ActionResult.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.onUseWithItem(stack, state, world, pos, player, hand, hit);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit) {
|
||||||
|
if(world.isClient()) {
|
||||||
|
return ActionResult.CONSUME;
|
||||||
|
}
|
||||||
|
|
||||||
|
world.getBlockEntity(pos, getBlockEntityType()).ifPresent(be -> {
|
||||||
|
String name = MinionPersistentState.get(world.getServer()).getMinionData(be.getMinionUuid()).name();
|
||||||
|
player.sendMessage(Text.translatable("minions.reference.instruction.tooltip", name, be.getInstructionName()), true);
|
||||||
|
});
|
||||||
|
return ActionResult.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStateReplaced(BlockState state, ServerWorld world, BlockPos pos, boolean moved) {
|
||||||
|
super.onStateReplaced(state, world, pos, moved);
|
||||||
|
world.getBlockEntity(pos, MinionBlocks.MINION_TRIGGER_BE_TYPE).ifPresent(MinionTriggerBlockEntity::removeListener);
|
||||||
|
}
|
||||||
|
}
|
||||||
+71
@@ -0,0 +1,71 @@
|
|||||||
|
package io.github.skippyall.minions.block.instruction_bound;
|
||||||
|
|
||||||
|
import io.github.skippyall.minions.listener.BlockEntityMinionListener;
|
||||||
|
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.block.entity.BlockEntityType;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public abstract class InstructionBoundBlockEntity<L extends BlockEntityMinionListener<?>> extends BlockEntity {
|
||||||
|
protected UUID minionUuid;
|
||||||
|
protected String instructionName = "";
|
||||||
|
|
||||||
|
public InstructionBoundBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||||
|
super(type, pos, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract L createListener();
|
||||||
|
|
||||||
|
protected abstract Class<L> getListenerClass();
|
||||||
|
|
||||||
|
public void removeListener() {
|
||||||
|
L listener = getListener();
|
||||||
|
listener.remove(world.getServer());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addListener() {
|
||||||
|
L listener = createListener();
|
||||||
|
listener.add(world.getServer());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInstruction(UUID minionUuid, String instructionName) {
|
||||||
|
removeListener();
|
||||||
|
this.minionUuid = minionUuid;
|
||||||
|
this.instructionName = instructionName;
|
||||||
|
addListener();
|
||||||
|
markDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<MinionFakePlayer> getMinion() {
|
||||||
|
if(minionUuid != null && world != null && world.getPlayerByUuid(minionUuid) instanceof MinionFakePlayer minion) {
|
||||||
|
return Optional.of(minion);
|
||||||
|
}
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getMinionUuid() {
|
||||||
|
return minionUuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInstructionName() {
|
||||||
|
return instructionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<ConfiguredInstruction<MinionRuntime>> getInstruction(MinionFakePlayer minion) {
|
||||||
|
return Optional.ofNullable(minion.getInstructionManager().getInstruction(instructionName));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<ConfiguredInstruction<MinionRuntime>> getInstruction() {
|
||||||
|
return getMinion().flatMap(this::getInstruction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public L getListener() {
|
||||||
|
return BlockEntityMinionListener.getListener(world, pos, minionUuid, getListenerClass());
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
-52
@@ -8,35 +8,27 @@ import eu.pb4.polymer.resourcepack.api.PolymerResourcePackUtils;
|
|||||||
import eu.pb4.polymer.virtualentity.api.BlockWithElementHolder;
|
import eu.pb4.polymer.virtualentity.api.BlockWithElementHolder;
|
||||||
import eu.pb4.polymer.virtualentity.api.ElementHolder;
|
import eu.pb4.polymer.virtualentity.api.ElementHolder;
|
||||||
import eu.pb4.polymer.virtualentity.api.elements.ItemDisplayElement;
|
import eu.pb4.polymer.virtualentity.api.elements.ItemDisplayElement;
|
||||||
|
import io.github.skippyall.minions.block.instruction_bound.InstructionBoundBlock;
|
||||||
|
import io.github.skippyall.minions.block.instruction_bound.InstructionBoundBlockEntity;
|
||||||
import io.github.skippyall.minions.registration.MinionBlocks;
|
import io.github.skippyall.minions.registration.MinionBlocks;
|
||||||
import io.github.skippyall.minions.Minions;
|
import io.github.skippyall.minions.Minions;
|
||||||
import io.github.skippyall.minions.minion.MinionPersistentState;
|
import io.github.skippyall.minions.polymer.VersionSync;
|
||||||
import io.github.skippyall.minions.clipboard.InstructionClipboard;
|
|
||||||
import io.github.skippyall.minions.registration.MinionComponentTypes;
|
|
||||||
import io.github.skippyall.minions.util.PolymerUtil;
|
|
||||||
import net.minecraft.block.AbstractRedstoneGateBlock;
|
import net.minecraft.block.AbstractRedstoneGateBlock;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.BlockWithEntity;
|
|
||||||
import net.minecraft.block.ShapeContext;
|
import net.minecraft.block.ShapeContext;
|
||||||
import net.minecraft.block.SideShapeType;
|
import net.minecraft.block.SideShapeType;
|
||||||
import net.minecraft.block.entity.BlockEntity;
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.block.entity.BlockEntityType;
|
||||||
import net.minecraft.component.DataComponentTypes;
|
import net.minecraft.component.DataComponentTypes;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.item.Items;
|
import net.minecraft.item.Items;
|
||||||
import net.minecraft.server.network.ServerPlayNetworkHandler;
|
import net.minecraft.server.network.ServerPlayNetworkHandler;
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
import net.minecraft.server.world.ServerWorld;
|
import net.minecraft.server.world.ServerWorld;
|
||||||
import net.minecraft.sound.SoundCategory;
|
|
||||||
import net.minecraft.sound.SoundEvents;
|
|
||||||
import net.minecraft.state.StateManager;
|
import net.minecraft.state.StateManager;
|
||||||
import net.minecraft.state.property.BooleanProperty;
|
import net.minecraft.state.property.BooleanProperty;
|
||||||
import net.minecraft.text.Text;
|
|
||||||
import net.minecraft.util.ActionResult;
|
|
||||||
import net.minecraft.util.Hand;
|
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.hit.BlockHitResult;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
import net.minecraft.util.shape.VoxelShape;
|
import net.minecraft.util.shape.VoxelShape;
|
||||||
@@ -47,7 +39,7 @@ import net.minecraft.world.block.WireOrientation;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import xyz.nucleoid.packettweaker.PacketContext;
|
import xyz.nucleoid.packettweaker.PacketContext;
|
||||||
|
|
||||||
public class MinionTriggerBlock extends BlockWithEntity implements PolymerBlock, PolymerKeepModel, PolymerClientDecoded, BlockWithElementHolder {
|
public class MinionTriggerBlock extends InstructionBoundBlock implements PolymerBlock, PolymerKeepModel, PolymerClientDecoded, BlockWithElementHolder {
|
||||||
public static final MapCodec<MinionTriggerBlock> CODEC = createCodec(MinionTriggerBlock::new);
|
public static final MapCodec<MinionTriggerBlock> CODEC = createCodec(MinionTriggerBlock::new);
|
||||||
|
|
||||||
public static final BooleanProperty POWERED = BooleanProperty.of("powered");
|
public static final BooleanProperty POWERED = BooleanProperty.of("powered");
|
||||||
@@ -73,44 +65,11 @@ public class MinionTriggerBlock extends BlockWithEntity implements PolymerBlock,
|
|||||||
return state.isSideSolid(world, pos, Direction.UP, SideShapeType.RIGID);
|
return state.isSideSolid(world, pos, Direction.UP, SideShapeType.RIGID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStateReplaced(BlockState state, ServerWorld world, BlockPos pos, boolean moved) {
|
|
||||||
super.onStateReplaced(state, world, pos, moved);
|
|
||||||
world.getBlockEntity(pos, MinionBlocks.MINION_TRIGGER_BE_TYPE).ifPresent(MinionTriggerBlockEntity::removeListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||||
builder.add(POWERED);
|
builder.add(POWERED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ActionResult onUseWithItem(ItemStack stack, BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
|
|
||||||
if(stack.get(MinionComponentTypes.REFERENCE) instanceof InstructionClipboard instruction) {
|
|
||||||
world.getBlockEntity(pos, MinionBlocks.MINION_TRIGGER_BE_TYPE).ifPresent(be -> {
|
|
||||||
be.setInstruction(instruction.selectedMinion(), instruction.selectedInstruction());
|
|
||||||
player.playSoundToPlayer(SoundEvents.BLOCK_NOTE_BLOCK_CHIME.value(), SoundCategory.BLOCKS, 1, 1);
|
|
||||||
stack.decrement(1);
|
|
||||||
});
|
|
||||||
return ActionResult.SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.onUseWithItem(stack, state, world, pos, player, hand, hit);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit) {
|
|
||||||
if(world.isClient()) {
|
|
||||||
return ActionResult.CONSUME;
|
|
||||||
}
|
|
||||||
|
|
||||||
world.getBlockEntity(pos, MinionBlocks.MINION_TRIGGER_BE_TYPE).ifPresent(be -> {
|
|
||||||
String name = MinionPersistentState.get(world.getServer()).getMinionData(be.getMinionUuid()).name();
|
|
||||||
player.sendMessage(Text.translatable("minions.reference.instruction.tooltip", name, be.getInstructionName()), true);
|
|
||||||
});
|
|
||||||
return ActionResult.SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void neighborUpdate(BlockState state, World world, BlockPos pos, Block sourceBlock, @Nullable WireOrientation wireOrientation, boolean notify) {
|
protected void neighborUpdate(BlockState state, World world, BlockPos pos, Block sourceBlock, @Nullable WireOrientation wireOrientation, boolean notify) {
|
||||||
if(!canPlaceAt(state, world, pos)) {
|
if(!canPlaceAt(state, world, pos)) {
|
||||||
@@ -136,19 +95,19 @@ public class MinionTriggerBlock extends BlockWithEntity implements PolymerBlock,
|
|||||||
return world.getBlockEntity(pos, MinionBlocks.MINION_TRIGGER_BE_TYPE).map(MinionTriggerBlockEntity::getComparatorOutput).orElse(0);
|
return world.getBlockEntity(pos, MinionBlocks.MINION_TRIGGER_BE_TYPE).map(MinionTriggerBlockEntity::getComparatorOutput).orElse(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected MapCodec<? extends BlockWithEntity> getCodec() {
|
|
||||||
return CODEC;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
|
public @Nullable BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
|
||||||
return new MinionTriggerBlockEntity(pos, state);
|
return new MinionTriggerBlockEntity(pos, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected BlockEntityType<MinionTriggerBlockEntity> getBlockEntityType() {
|
||||||
|
return MinionBlocks.MINION_TRIGGER_BE_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState getPolymerBlockState(BlockState state, PacketContext context) {
|
public BlockState getPolymerBlockState(BlockState state, PacketContext context) {
|
||||||
return PolymerUtil.isOnClient(context) ? state : net.minecraft.block.Blocks.COMPARATOR.getDefaultState().with(AbstractRedstoneGateBlock.POWERED, state.get(POWERED));
|
return VersionSync.isOnClient(context) ? state : net.minecraft.block.Blocks.COMPARATOR.getDefaultState().with(AbstractRedstoneGateBlock.POWERED, state.get(POWERED));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+8
-43
@@ -1,5 +1,6 @@
|
|||||||
package io.github.skippyall.minions.block.miniontrigger;
|
package io.github.skippyall.minions.block.miniontrigger;
|
||||||
|
|
||||||
|
import io.github.skippyall.minions.block.instruction_bound.InstructionBoundBlockEntity;
|
||||||
import io.github.skippyall.minions.listener.BlockEntityMinionListener;
|
import io.github.skippyall.minions.listener.BlockEntityMinionListener;
|
||||||
import io.github.skippyall.minions.registration.MinionBlocks;
|
import io.github.skippyall.minions.registration.MinionBlocks;
|
||||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||||
@@ -15,28 +16,19 @@ import net.minecraft.util.math.BlockPos;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class MinionTriggerBlockEntity extends BlockEntity {
|
public class MinionTriggerBlockEntity extends InstructionBoundBlockEntity<MinionTriggerMinionListener> {
|
||||||
private UUID minionUuid;
|
|
||||||
private String instructionName = "";
|
|
||||||
|
|
||||||
public MinionTriggerBlockEntity(BlockPos pos, BlockState state) {
|
public MinionTriggerBlockEntity(BlockPos pos, BlockState state) {
|
||||||
super(MinionBlocks.MINION_TRIGGER_BE_TYPE, pos, state);
|
super(MinionBlocks.MINION_TRIGGER_BE_TYPE, pos, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeListener() {
|
@Override
|
||||||
MinionTriggerMinionListener.removeListener(world, pos, minionUuid, instructionName);
|
protected MinionTriggerMinionListener createListener() {
|
||||||
|
return new MinionTriggerMinionListener(world.getRegistryKey(), pos, minionUuid, instructionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addListener() {
|
@Override
|
||||||
MinionTriggerMinionListener.addListener(world, pos, minionUuid, instructionName);
|
protected Class<MinionTriggerMinionListener> getListenerClass() {
|
||||||
}
|
return MinionTriggerMinionListener.class;
|
||||||
|
|
||||||
public void setInstruction(UUID minionUuid, String instructionName) {
|
|
||||||
removeListener();
|
|
||||||
this.minionUuid = minionUuid;
|
|
||||||
this.instructionName = instructionName;
|
|
||||||
addListener();
|
|
||||||
markDirty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updatePower() {
|
public void updatePower() {
|
||||||
@@ -66,33 +58,6 @@ public class MinionTriggerBlockEntity extends BlockEntity {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<MinionFakePlayer> getMinion() {
|
|
||||||
if(minionUuid != null && world != null && world.getPlayerByUuid(minionUuid) instanceof MinionFakePlayer minion) {
|
|
||||||
return Optional.of(minion);
|
|
||||||
}
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public UUID getMinionUuid() {
|
|
||||||
return minionUuid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getInstructionName() {
|
|
||||||
return instructionName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Optional<ConfiguredInstruction<MinionRuntime>> getInstruction(MinionFakePlayer minion) {
|
|
||||||
return Optional.ofNullable(minion.getInstructionManager().getInstruction(instructionName));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Optional<ConfiguredInstruction<MinionRuntime>> getInstruction() {
|
|
||||||
return getMinion().flatMap(this::getInstruction);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MinionTriggerMinionListener getListener() {
|
|
||||||
return BlockEntityMinionListener.getListener(world, pos, minionUuid, MinionTriggerMinionListener.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void readData(ReadView view) {
|
protected void readData(ReadView view) {
|
||||||
minionUuid = view.read("minionUuid", Uuids.CODEC).orElse(null);
|
minionUuid = view.read("minionUuid", Uuids.CODEC).orElse(null);
|
||||||
|
|||||||
+2
-14
@@ -36,23 +36,11 @@ public class MinionTriggerMinionListener extends BlockEntityMinionInstructionLis
|
|||||||
boolean runningCache;
|
boolean runningCache;
|
||||||
boolean incomingPowerCache;
|
boolean incomingPowerCache;
|
||||||
|
|
||||||
private MinionTriggerMinionListener(RegistryKey<World> worldKey, BlockPos pos, UUID minionUuid, String instructionName) {
|
MinionTriggerMinionListener(RegistryKey<World> worldKey, BlockPos pos, UUID minionUuid, String instructionName) {
|
||||||
super(worldKey, pos, minionUuid, MinionBlocks.MINION_TRIGGER_BE_TYPE);
|
super(worldKey, pos, minionUuid, MinionBlocks.MINION_TRIGGER_BE_TYPE);
|
||||||
this.instructionName = Objects.requireNonNull(instructionName);
|
this.instructionName = Objects.requireNonNull(instructionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addListener(World world, BlockPos pos, UUID minion, String instructionName) {
|
|
||||||
MinionTriggerMinionListener listener = new MinionTriggerMinionListener(world.getRegistryKey(), pos, minion, instructionName);
|
|
||||||
listener.add(world.getServer());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void removeListener(World world, BlockPos pos, UUID minion, String instructionName) {
|
|
||||||
MinionTriggerMinionListener old = getListener(world, pos, minion, MinionTriggerMinionListener.class);
|
|
||||||
if(old != null) {
|
|
||||||
old.remove(world.getServer());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Map<String, ConfiguredInstructionListener> getInstructionListeners() {
|
protected Map<String, ConfiguredInstructionListener> getInstructionListeners() {
|
||||||
return Map.of(instructionName, listener);
|
return Map.of(instructionName, listener);
|
||||||
@@ -88,7 +76,7 @@ public class MinionTriggerMinionListener extends BlockEntityMinionInstructionLis
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void add(MinecraftServer server) {
|
public void add(MinecraftServer server) {
|
||||||
super.add(server);
|
super.add(server);
|
||||||
runningCache = minion.getInstructionManager().getInstruction(instructionName).isRunning();
|
runningCache = minion.getInstructionManager().getInstruction(instructionName).isRunning();
|
||||||
updateComparatorsIfLoaded(server);
|
updateComparatorsIfLoaded(server);
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package io.github.skippyall.minions.clipboard;
|
||||||
|
|
||||||
|
import com.mojang.serialization.MapCodec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
import net.minecraft.component.ComponentsAccess;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.tooltip.TooltipType;
|
||||||
|
import net.minecraft.registry.RegistryKey;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public record BlockPosClipboard(RegistryKey<World> world, BlockPos pos) implements Clipboard {
|
||||||
|
public static final MapCodec<BlockPosClipboard> CODEC = RecordCodecBuilder.mapCodec(instance ->
|
||||||
|
instance.group(
|
||||||
|
World.CODEC.fieldOf("world").forGetter(BlockPosClipboard::world),
|
||||||
|
BlockPos.CODEC.fieldOf("pos").forGetter(BlockPosClipboard::pos)
|
||||||
|
).apply(instance, BlockPosClipboard::new)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MapCodec<BlockPosClipboard> getCodec() {
|
||||||
|
return CODEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void appendTooltip(Item.TooltipContext context, Consumer<Text> textConsumer, TooltipType type, ComponentsAccess components) {
|
||||||
|
textConsumer.accept(Text.translatable("minions.reference.block.tooltip", pos.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,6 +10,8 @@ import net.minecraft.item.ItemStack;
|
|||||||
import net.minecraft.item.Items;
|
import net.minecraft.item.Items;
|
||||||
import net.minecraft.item.tooltip.TooltipType;
|
import net.minecraft.item.tooltip.TooltipType;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import xyz.nucleoid.packettweaker.PacketContext;
|
import xyz.nucleoid.packettweaker.PacketContext;
|
||||||
|
|
||||||
@@ -40,4 +42,10 @@ public class ClipboardItem extends Item implements PolymerItem {
|
|||||||
stack.set(MinionComponentTypes.REFERENCE, new InstructionClipboard(minion.getUuid(), instructionName, minion.getGameProfile().getName()));
|
stack.set(MinionComponentTypes.REFERENCE, new InstructionClipboard(minion.getUuid(), instructionName, minion.getGameProfile().getName()));
|
||||||
return stack;
|
return stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ItemStack createBlockPosReference(World world, BlockPos pos) {
|
||||||
|
ItemStack stack = new ItemStack(MinionItems.REFERENCE_ITEM);
|
||||||
|
stack.set(MinionComponentTypes.REFERENCE, new BlockPosClipboard(world.getRegistryKey(), pos));
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package io.github.skippyall.minions.command;
|
||||||
|
|
||||||
|
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||||
|
import com.mojang.brigadier.context.CommandContext;
|
||||||
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
|
import com.mojang.brigadier.suggestion.Suggestions;
|
||||||
|
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||||
|
import io.github.skippyall.minions.docs.DocsManager;
|
||||||
|
import net.minecraft.command.argument.IdentifierArgumentType;
|
||||||
|
import net.minecraft.server.command.ServerCommandSource;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
import static net.minecraft.server.command.CommandManager.literal;
|
||||||
|
import static net.minecraft.server.command.CommandManager.argument;
|
||||||
|
|
||||||
|
public class DocsSubcommand {
|
||||||
|
public static final LiteralArgumentBuilder<ServerCommandSource> DOCS = literal("docs")
|
||||||
|
.then(
|
||||||
|
argument("docName", IdentifierArgumentType.identifier())
|
||||||
|
.suggests(DocsSubcommand::getSuggestions)
|
||||||
|
.executes(DocsSubcommand::execute)
|
||||||
|
);
|
||||||
|
|
||||||
|
public static CompletableFuture<Suggestions> getSuggestions(CommandContext<ServerCommandSource> context, SuggestionsBuilder builder) {
|
||||||
|
DocsManager.getDocsEntryIds().forEach(id -> builder.suggest(id.toString()));
|
||||||
|
return CompletableFuture.completedFuture(builder.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int execute(CommandContext<ServerCommandSource> context) throws CommandSyntaxException {
|
||||||
|
Identifier id = IdentifierArgumentType.getIdentifier(context, "docName");
|
||||||
|
DocsManager.showDocsEntry(context.getSource().getPlayerOrThrow(), id);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,7 +13,8 @@ public class MinionsCommand {
|
|||||||
public static void register(CommandDispatcher<ServerCommandSource> dispatcher, CommandRegistryAccess access, CommandManager.RegistrationEnvironment environment) {
|
public static void register(CommandDispatcher<ServerCommandSource> dispatcher, CommandRegistryAccess access, CommandManager.RegistrationEnvironment environment) {
|
||||||
LiteralArgumentBuilder<ServerCommandSource> builder = literal("minions")
|
LiteralArgumentBuilder<ServerCommandSource> builder = literal("minions")
|
||||||
.then(SpawnSubcommand.SPAWN)
|
.then(SpawnSubcommand.SPAWN)
|
||||||
.then(ListSubcommand.LIST);
|
.then(ListSubcommand.LIST)
|
||||||
|
.then(DocsSubcommand.DOCS);
|
||||||
|
|
||||||
if(MinionsConfig.get().minion.enableMobCapHacks) {
|
if(MinionsConfig.get().minion.enableMobCapHacks) {
|
||||||
builder.then(MobCapDebugSubcommand.MOB_CAP_DEBUG);
|
builder.then(MobCapDebugSubcommand.MOB_CAP_DEBUG);
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package io.github.skippyall.minions.docs;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.MapCodec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
import io.github.skippyall.minions.registration.MinionRegistries;
|
||||||
|
import net.minecraft.dialog.body.DialogBody;
|
||||||
|
import net.minecraft.registry.DynamicRegistryManager;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public interface DocsEntry {
|
||||||
|
Codec<DocsEntry> CODEC = MinionRegistries.DOCS_ENTRY_TYPES.getCodec().dispatch(DocsEntry::getCodec, Function.identity());
|
||||||
|
|
||||||
|
Metadata getMetadata();
|
||||||
|
|
||||||
|
List<DialogBody> getDialog(DynamicRegistryManager manager);
|
||||||
|
|
||||||
|
MapCodec<? extends DocsEntry> getCodec();
|
||||||
|
|
||||||
|
record Metadata(String titleKey) {
|
||||||
|
public static final MapCodec<Metadata> CODEC = RecordCodecBuilder.mapCodec(instance ->
|
||||||
|
instance.group(
|
||||||
|
Codec.STRING.fieldOf("title").forGetter(Metadata::titleKey)
|
||||||
|
).apply(instance, Metadata::new)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,145 @@
|
|||||||
|
package io.github.skippyall.minions.docs;
|
||||||
|
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
import com.mojang.serialization.JsonOps;
|
||||||
|
import io.github.skippyall.minions.Minions;
|
||||||
|
import net.fabricmc.fabric.api.resource.SimpleResourceReloadListener;
|
||||||
|
import net.minecraft.dialog.AfterAction;
|
||||||
|
import net.minecraft.dialog.DialogActionButtonData;
|
||||||
|
import net.minecraft.dialog.DialogButtonData;
|
||||||
|
import net.minecraft.dialog.DialogCommonData;
|
||||||
|
import net.minecraft.dialog.action.DynamicRunCommandDialogAction;
|
||||||
|
import net.minecraft.dialog.action.SimpleDialogAction;
|
||||||
|
import net.minecraft.dialog.type.MultiActionDialog;
|
||||||
|
import net.minecraft.registry.entry.RegistryEntry;
|
||||||
|
import net.minecraft.resource.Resource;
|
||||||
|
import net.minecraft.resource.ResourceManager;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.text.ClickEvent;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.Pair;
|
||||||
|
import net.minecraft.util.StrictJsonParser;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
public class DocsManager implements SimpleResourceReloadListener<Pair<Map<Identifier, DocsEntry>, DocsTree>> {
|
||||||
|
private static Map<Identifier, DocsEntry> docs;
|
||||||
|
private static DocsTree tree;
|
||||||
|
|
||||||
|
public static DocsTree getTree() {
|
||||||
|
return tree;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void showDocsEntry(ServerPlayerEntity player, Identifier id) {
|
||||||
|
DocsEntry entry = getDocsEntry(id);
|
||||||
|
if(entry == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<DialogActionButtonData> buttons = new ArrayList<>();
|
||||||
|
if(tree != null) {
|
||||||
|
DocsTree.DocElement element = tree.getElement(id);
|
||||||
|
if (element.previous() != null) {
|
||||||
|
Identifier previousId = element.previous().getId();
|
||||||
|
buttons.add(getDialogButton(Text.literal("<- ").append(Text.translatable(getDocsEntry(previousId).getMetadata().titleKey())), previousId.toString()));
|
||||||
|
}
|
||||||
|
if (element.next() != null) {
|
||||||
|
Identifier nextId = element.next().getId();
|
||||||
|
buttons.add(getDialogButton(Text.translatable(getDocsEntry(nextId).getMetadata().titleKey()).append(Text.literal(" ->")), nextId.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buttons.add(new DialogActionButtonData(
|
||||||
|
new DialogButtonData(Text.translatable("gui.ok"), 100),
|
||||||
|
Optional.empty()
|
||||||
|
));
|
||||||
|
|
||||||
|
player.openDialog(RegistryEntry.of(new MultiActionDialog(
|
||||||
|
new DialogCommonData(
|
||||||
|
Text.translatable(entry.getMetadata().titleKey()),
|
||||||
|
Optional.empty(),
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
AfterAction.CLOSE,
|
||||||
|
entry.getDialog(player.getRegistryManager()),
|
||||||
|
List.of()
|
||||||
|
),
|
||||||
|
buttons,
|
||||||
|
Optional.empty(),
|
||||||
|
2
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static DialogActionButtonData getDialogButton(Text text, String dialogToOpen) {
|
||||||
|
return new DialogActionButtonData(
|
||||||
|
new DialogButtonData(
|
||||||
|
text, 100
|
||||||
|
),
|
||||||
|
Optional.of(new SimpleDialogAction(new ClickEvent.RunCommand("/minions docs " + dialogToOpen)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DocsEntry getDocsEntry(Identifier id) {
|
||||||
|
return docs.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Collection<Identifier> getDocsEntryIds() {
|
||||||
|
return docs.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<Pair<Map<Identifier, DocsEntry>, DocsTree>> load(ResourceManager resourceManager, Executor executor) {
|
||||||
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
|
Map<Identifier, Resource> resources = resourceManager.findResources("docs", id -> id.getNamespace().equals(Minions.MOD_ID) && id.getPath().endsWith(".json"));
|
||||||
|
|
||||||
|
final DocsTree.BranchElement[] root = {null};
|
||||||
|
Map<Identifier, DocsEntry> docsEntries = new HashMap<>();
|
||||||
|
resources.forEach((id, resource) -> {
|
||||||
|
try(Reader reader = resource.getReader()) {
|
||||||
|
if(id.getPath().equals("docs/tree.json")) {
|
||||||
|
DocsTree.BranchElement.CODEC.decode(JsonOps.INSTANCE, StrictJsonParser.parse(reader))
|
||||||
|
.ifSuccess(entry -> root[0] = entry.getFirst())
|
||||||
|
.ifError(error -> Minions.LOGGER.warn("Could not parse docs tree {}: {}", id, error.message()));
|
||||||
|
} else {
|
||||||
|
Identifier docId = Identifier.of(id.getNamespace(), id.getPath().substring("docs/".length(), id.getPath().length() - ".json".length()));
|
||||||
|
DocsEntry.CODEC.decode(JsonOps.INSTANCE, StrictJsonParser.parse(reader))
|
||||||
|
.ifSuccess(entry -> docsEntries.put(docId, entry.getFirst()))
|
||||||
|
.ifError(error -> Minions.LOGGER.warn("Could not parse docs entry {}: {}", id, error.message()));
|
||||||
|
}
|
||||||
|
} catch (IOException | JsonParseException e) {
|
||||||
|
Minions.LOGGER.warn("Could not read file {}", id, e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if(root[0] != null) {
|
||||||
|
DocsTree tree = new DocsTree(root[0]);
|
||||||
|
return new Pair<>(docsEntries, tree);
|
||||||
|
} else {
|
||||||
|
return new Pair<>(docsEntries, null);
|
||||||
|
}
|
||||||
|
}, executor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<Void> apply(Pair<Map<Identifier, DocsEntry>, DocsTree> o, ResourceManager resourceManager, Executor executor) {
|
||||||
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
|
docs = o.getLeft();
|
||||||
|
tree = o.getRight();
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Identifier getFabricId() {
|
||||||
|
return Identifier.of(Minions.MOD_ID, "docs");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
package io.github.skippyall.minions.docs;
|
||||||
|
|
||||||
|
import com.mojang.datafixers.util.Either;
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public class DocsTree {
|
||||||
|
private final BranchElement root;
|
||||||
|
private final Map<Identifier, DocElement> entries = new HashMap<>();
|
||||||
|
|
||||||
|
public DocsTree(BranchElement root) {
|
||||||
|
this.root = root;
|
||||||
|
initEntries();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initEntries() {
|
||||||
|
DocElement element = root.first();
|
||||||
|
do {
|
||||||
|
entries.put(element.id, element);
|
||||||
|
element = element.next();
|
||||||
|
} while (element != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BranchElement getRoot() {
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocElement getElement(Identifier id) {
|
||||||
|
return entries.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static abstract sealed class Element {
|
||||||
|
private BranchElement parent;
|
||||||
|
|
||||||
|
public BranchElement getParent() {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setParent(BranchElement parent) {
|
||||||
|
this.parent = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocElement next() {
|
||||||
|
return parent.next(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocElement previous() {
|
||||||
|
return parent.previous(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class DocElement extends Element {
|
||||||
|
public static final Codec<DocElement> CODEC = Identifier.CODEC.xmap(DocElement::new, DocElement::getId);
|
||||||
|
|
||||||
|
private final Identifier id;
|
||||||
|
|
||||||
|
public DocElement(Identifier element) {
|
||||||
|
this.id = element;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Identifier getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class BranchElement extends Element {
|
||||||
|
public static final Codec<BranchElement> CODEC = Codec.<BranchElement>recursive("DocsBranch", codec ->
|
||||||
|
Codec.either(codec, DocElement.CODEC)
|
||||||
|
.xmap(
|
||||||
|
Either::unwrap,
|
||||||
|
element -> switch (element) {
|
||||||
|
case BranchElement branch -> Either.left(branch);
|
||||||
|
case DocElement doc -> Either.right(doc);
|
||||||
|
}
|
||||||
|
).listOf()
|
||||||
|
.xmap(BranchElement::new, branch -> branch.e)
|
||||||
|
).xmap(BranchElement::setParents, Function.identity());
|
||||||
|
|
||||||
|
private final List<Element> e;
|
||||||
|
|
||||||
|
public BranchElement(List<Element> elements) {
|
||||||
|
e = elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocElement first() {
|
||||||
|
return switch (e.getFirst()) {
|
||||||
|
case BranchElement branch -> branch.first();
|
||||||
|
case DocElement doc -> doc;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocElement last() {
|
||||||
|
return switch (e.getLast()) {
|
||||||
|
case BranchElement branch -> branch.last();
|
||||||
|
case DocElement doc -> doc;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocElement next(Element current) {
|
||||||
|
int nextIndex = e.indexOf(current) + 1;
|
||||||
|
if(nextIndex < e.size()) {
|
||||||
|
return switch (e.get(nextIndex)) {
|
||||||
|
case BranchElement branch -> branch.first();
|
||||||
|
case DocElement doc -> doc;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
if(getParent() != null) {
|
||||||
|
return getParent().next(this);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocElement previous(Element current) {
|
||||||
|
int previousIndex = e.indexOf(current) - 1;
|
||||||
|
if(previousIndex >= 0) {
|
||||||
|
return switch (e.get(previousIndex)) {
|
||||||
|
case BranchElement branch -> branch.first();
|
||||||
|
case DocElement doc -> doc;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
if(getParent() != null) {
|
||||||
|
return getParent().previous(this);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private BranchElement setParents() {
|
||||||
|
for(Element element : e) {
|
||||||
|
element.setParent(this);
|
||||||
|
if(element instanceof BranchElement branch) {
|
||||||
|
branch.setParents();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,14 +1,81 @@
|
|||||||
package io.github.skippyall.minions.docs;
|
package io.github.skippyall.minions.docs;
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.MapCodec;
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
import io.github.skippyall.minions.gui.GuiDisplay;
|
||||||
|
import net.minecraft.dialog.body.DialogBody;
|
||||||
|
import net.minecraft.dialog.body.ItemDialogBody;
|
||||||
|
import net.minecraft.dialog.body.PlainMessageDialogBody;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.registry.DynamicRegistryManager;
|
||||||
|
import net.minecraft.registry.Registries;
|
||||||
|
import net.minecraft.registry.RegistryKey;
|
||||||
|
import net.minecraft.registry.RegistryKeys;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.text.TextCodecs;
|
import net.minecraft.text.TextCodecs;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
public record ReferenceEntry(Text shortDescription, Text longDescription) {
|
import java.util.ArrayList;
|
||||||
public static final Codec<ReferenceEntry> CODEC = RecordCodecBuilder.create(instance ->
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public record ReferenceEntry(Metadata metadata, RegistryKey<?> object, Text shortDescription, Text longDescription) implements DocsEntry {
|
||||||
|
private static final Codec<RegistryKey<?>> REGISTRY_KEY_CODEC = RecordCodecBuilder.create(instance ->
|
||||||
instance.group(
|
instance.group(
|
||||||
|
Identifier.CODEC.fieldOf("registry").forGetter(RegistryKey::getRegistry),
|
||||||
|
Identifier.CODEC.fieldOf("value").forGetter(RegistryKey::getValue)
|
||||||
|
).apply(instance, (registry, value) -> RegistryKey.of(RegistryKey.ofRegistry(registry), value))
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final MapCodec<ReferenceEntry> CODEC = RecordCodecBuilder.mapCodec(instance ->
|
||||||
|
instance.group(
|
||||||
|
Metadata.CODEC.fieldOf("metadata").forGetter(ReferenceEntry::getMetadata),
|
||||||
|
REGISTRY_KEY_CODEC.fieldOf("object").forGetter(ReferenceEntry::object),
|
||||||
TextCodecs.CODEC.fieldOf("shortDescription").forGetter(ReferenceEntry::shortDescription),
|
TextCodecs.CODEC.fieldOf("shortDescription").forGetter(ReferenceEntry::shortDescription),
|
||||||
TextCodecs.CODEC.fieldOf("longDescription").forGetter(ReferenceEntry::longDescription)
|
TextCodecs.CODEC.fieldOf("longDescription").forGetter(ReferenceEntry::longDescription)
|
||||||
).apply(instance, ReferenceEntry::new));
|
).apply(instance, ReferenceEntry::new));
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Metadata getMetadata() {
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<DialogBody> getDialog(DynamicRegistryManager manager) {
|
||||||
|
List<DialogBody> bodyElements = new ArrayList<>();
|
||||||
|
|
||||||
|
GuiDisplay display = getObjectDisplay(manager);
|
||||||
|
if(display != null) {
|
||||||
|
bodyElements.add(new ItemDialogBody(display.createItemStack(), Optional.empty(), false, false, 16, 16));
|
||||||
|
}
|
||||||
|
bodyElements.add(new PlainMessageDialogBody(Text.translatable(object.getValue().toTranslationKey(object.getRegistry().getPath())), 200));
|
||||||
|
bodyElements.add(new PlainMessageDialogBody(longDescription.copy().append("\n".repeat(100)), 200));
|
||||||
|
|
||||||
|
return bodyElements;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GuiDisplay getObjectDisplay(DynamicRegistryManager manager) {
|
||||||
|
GuiDisplay display = GuiDisplay.DEFAULT_DISPLAY;
|
||||||
|
if(object.isOf(RegistryKeys.ITEM) || object.isOf(RegistryKeys.BLOCK)) {
|
||||||
|
Item item;
|
||||||
|
if(object.isOf(RegistryKeys.ITEM)) {
|
||||||
|
item = Registries.ITEM.get(object.getValue());
|
||||||
|
} else {
|
||||||
|
item = Registries.BLOCK.get(object.getValue()).asItem();
|
||||||
|
}
|
||||||
|
if(item != null) {
|
||||||
|
display = new GuiDisplay.ItemBased(item);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Identifier displayId = object.getValue().withPrefixedPath(object.getRegistry().getPath() + "/");
|
||||||
|
display = GuiDisplay.getGuiDisplay(displayId, manager);
|
||||||
|
}
|
||||||
|
return display;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MapCodec<? extends DocsEntry> getCodec() {
|
||||||
|
return CODEC;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,18 +100,22 @@ public class InstructionGui {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static <T, A extends ValueSupplier<T, MinionRuntime>> void configureArgumentMenu(String instructionName, ConfiguredInstruction<MinionRuntime> instruction, Parameter<T> parameter, MinionFakePlayer minion, ServerPlayerEntity player) {
|
public static <T, A extends ValueSupplier<T, MinionRuntime>> void configureArgumentMenu(String instructionName, ConfiguredInstruction<MinionRuntime> instruction, Parameter<?> parameter, MinionFakePlayer minion, ServerPlayerEntity player) {
|
||||||
if (!checkInstructionExists(instructionName, instruction, minion, player)) {
|
if (!checkInstructionExists(instructionName, instruction, minion, player)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable A argument = instruction.getArguments().getArgument(parameter);
|
@Nullable ValueSupplier<?, MinionRuntime> argument = instruction.getArguments().getArgument(parameter);
|
||||||
|
|
||||||
if(argument == null) {
|
if(argument == null) {
|
||||||
configureTypeAndValue(instructionName, instruction, parameter, minion, player);
|
configureTypeAndValue(instructionName, instruction, parameter, minion, player);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configureArgumentHelper(instructionName, instruction, parameter, argument, minion, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> void configureArgumentHelper(String instructionName, ConfiguredInstruction<MinionRuntime> instruction, Parameter<?> parameter, ValueSupplier<T, MinionRuntime> argument, MinionFakePlayer minion, ServerPlayerEntity player) {
|
||||||
SimpleGui gui = new InstructionBoundSimpleGui(ScreenHandlerType.GENERIC_3X3, player, minion, instruction);
|
SimpleGui gui = new InstructionBoundSimpleGui(ScreenHandlerType.GENERIC_3X3, player, minion, instruction);
|
||||||
|
|
||||||
ItemStack displayStack = GuiDisplay.getDisplayStack(MinionRegistries.VALUE_SUPPLIER_TYPES, argument.getType(), player.getRegistryManager());
|
ItemStack displayStack = GuiDisplay.getDisplayStack(MinionRegistries.VALUE_SUPPLIER_TYPES, argument.getType(), player.getRegistryManager());
|
||||||
|
|||||||
+1
-1
@@ -26,7 +26,7 @@ public abstract class BlockEntityMinionInstructionListener<E extends BlockEntity
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void add(MinecraftServer server) {
|
public void add(MinecraftServer server) {
|
||||||
super.add(server);
|
super.add(server);
|
||||||
if(minion != null) {
|
if(minion != null) {
|
||||||
registerInstructionListeners();
|
registerInstructionListeners();
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ public abstract class BlockEntityMinionListener<E extends BlockEntity> implement
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void add(MinecraftServer server) {
|
public void add(MinecraftServer server) {
|
||||||
MinionPersistentState.get(server).getMinionData(minionUuid).listeners().addListener(this);
|
MinionPersistentState.get(server).getMinionData(minionUuid).listeners().addListener(this);
|
||||||
MinionPersistentState.get(server).markDirty();
|
MinionPersistentState.get(server).markDirty();
|
||||||
this.minion = (MinionFakePlayer) server.getPlayerManager().getPlayer(minionUuid);
|
this.minion = (MinionFakePlayer) server.getPlayerManager().getPlayer(minionUuid);
|
||||||
|
|||||||
+1
-1
@@ -190,7 +190,7 @@ public class EntityPlayerActionPack
|
|||||||
if (onlyRideables)
|
if (onlyRideables)
|
||||||
{
|
{
|
||||||
entities = player.getWorld().getOtherEntities(player, player.getBoundingBox().expand(3.0D, 1.0D, 3.0D),
|
entities = player.getWorld().getOtherEntities(player, player.getBoundingBox().expand(3.0D, 1.0D, 3.0D),
|
||||||
e -> (e instanceof MinecartEntity || e instanceof BoatEntity || e instanceof AbstractHorseEntity) && ((EntityAccessor)e).invokeCanAddPassenger(player));
|
e -> (e instanceof MinecartEntity || e instanceof BoatEntity || e instanceof AbstractHorseEntity) && ((EntityAccessor)e).minions$canAddPassenger(player));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ import net.minecraft.entity.attribute.EntityAttributes;
|
|||||||
import net.minecraft.entity.damage.DamageSource;
|
import net.minecraft.entity.damage.DamageSource;
|
||||||
import net.minecraft.entity.player.HungerManager;
|
import net.minecraft.entity.player.HungerManager;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.entity.vehicle.AbstractBoatEntity;
|
||||||
|
import net.minecraft.entity.vehicle.BoatEntity;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.network.DisconnectionInfo;
|
import net.minecraft.network.DisconnectionInfo;
|
||||||
import net.minecraft.network.NetworkSide;
|
import net.minecraft.network.NetworkSide;
|
||||||
@@ -210,6 +212,21 @@ public class MinionFakePlayer extends ServerPlayerEntity {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean startRiding(Entity entityToRide, boolean force) {
|
||||||
|
if (super.startRiding(entityToRide, force)) {
|
||||||
|
// from ClientPacketListener.handleSetEntityPassengersPacket
|
||||||
|
if (entityToRide instanceof AbstractBoatEntity) {
|
||||||
|
this.lastYaw = entityToRide.getYaw();
|
||||||
|
this.setYaw(entityToRide.getYaw());
|
||||||
|
this.setHeadYaw(entityToRide.getHeadYaw());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void shakeOff()
|
private void shakeOff()
|
||||||
{
|
{
|
||||||
if (getVehicle() instanceof PlayerEntity) stopRiding();
|
if (getVehicle() instanceof PlayerEntity) stopRiding();
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package io.github.skippyall.minions.instruction;
|
package io.github.skippyall.minions.minion.program.instruction;
|
||||||
|
|
||||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||||
import io.github.skippyall.minions.minion.fakeplayer.EntityPlayerActionPack;
|
import io.github.skippyall.minions.minion.fakeplayer.EntityPlayerActionPack;
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
//partially code from https://github.com/gnembon/fabric-carpet (EntityPlayerActionPack)
|
//partially code from https://github.com/gnembon/fabric-carpet (EntityPlayerActionPack)
|
||||||
package io.github.skippyall.minions.instruction;
|
package io.github.skippyall.minions.minion.program.instruction;
|
||||||
|
|
||||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||||
import io.github.skippyall.minions.minion.fakeplayer.EntityPlayerActionPack;
|
import io.github.skippyall.minions.minion.fakeplayer.EntityPlayerActionPack;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package io.github.skippyall.minions.instruction.inventory;
|
package io.github.skippyall.minions.minion.program.instruction.inventory;
|
||||||
|
|
||||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package io.github.skippyall.minions.instruction.move;
|
package io.github.skippyall.minions.minion.program.instruction.move;
|
||||||
|
|
||||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||||
import io.github.skippyall.minions.program.instruction.InstructionExecution;
|
import io.github.skippyall.minions.program.instruction.InstructionExecution;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package io.github.skippyall.minions.instruction.move;
|
package io.github.skippyall.minions.minion.program.instruction.move;
|
||||||
|
|
||||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||||
import io.github.skippyall.minions.program.instruction.InstructionExecution;
|
import io.github.skippyall.minions.program.instruction.InstructionExecution;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package io.github.skippyall.minions.instruction.move;
|
package io.github.skippyall.minions.minion.program.instruction.move;
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import io.github.skippyall.minions.gui.Displayable;
|
import io.github.skippyall.minions.gui.Displayable;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package io.github.skippyall.minions.instruction.move;
|
package io.github.skippyall.minions.minion.program.instruction.move;
|
||||||
|
|
||||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||||
import io.github.skippyall.minions.program.supplier.ValueSupplierList;
|
import io.github.skippyall.minions.program.supplier.ValueSupplierList;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package io.github.skippyall.minions.instruction.move;
|
package io.github.skippyall.minions.minion.program.instruction.move;
|
||||||
|
|
||||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||||
import io.github.skippyall.minions.program.supplier.Parameter;
|
import io.github.skippyall.minions.program.supplier.Parameter;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package io.github.skippyall.minions.instruction.move;
|
package io.github.skippyall.minions.minion.program.instruction.move;
|
||||||
|
|
||||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||||
import io.github.skippyall.minions.program.instruction.InstructionExecution;
|
import io.github.skippyall.minions.program.instruction.InstructionExecution;
|
||||||
+100
@@ -0,0 +1,100 @@
|
|||||||
|
package io.github.skippyall.minions.minion.program.supplier;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
import eu.pb4.sgui.api.elements.GuiElementBuilder;
|
||||||
|
import eu.pb4.sgui.api.gui.SimpleGui;
|
||||||
|
import io.github.skippyall.minions.clipboard.BlockPosClipboard;
|
||||||
|
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||||
|
import io.github.skippyall.minions.program.supplier.ValueSupplier;
|
||||||
|
import io.github.skippyall.minions.program.supplier.ValueSupplierType;
|
||||||
|
import io.github.skippyall.minions.program.value.ValueType;
|
||||||
|
import io.github.skippyall.minions.registration.MinionBlocks;
|
||||||
|
import io.github.skippyall.minions.registration.MinionComponentTypes;
|
||||||
|
import io.github.skippyall.minions.registration.MinionItems;
|
||||||
|
import io.github.skippyall.minions.registration.ValueSuppliers;
|
||||||
|
import io.github.skippyall.minions.registration.ValueTypes;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.registry.RegistryKey;
|
||||||
|
import net.minecraft.screen.ScreenHandlerType;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
public class AnalogInputSupplier implements ValueSupplier<Long, MinionRuntime> {
|
||||||
|
public static final Codec<AnalogInputSupplier> CODEC = RecordCodecBuilder.create(instance ->
|
||||||
|
instance.group(
|
||||||
|
World.CODEC.fieldOf("analogInputWorld").forGetter(s -> s.analogInputWorld),
|
||||||
|
BlockPos.CODEC.fieldOf("analogInputPos").forGetter(s -> s.analogInputPos)
|
||||||
|
).apply(instance, AnalogInputSupplier::new));
|
||||||
|
|
||||||
|
private final RegistryKey<World> analogInputWorld;
|
||||||
|
private final BlockPos analogInputPos;
|
||||||
|
|
||||||
|
public AnalogInputSupplier(RegistryKey<World> analogInputWorld, BlockPos analogInputPos) {
|
||||||
|
this.analogInputWorld = analogInputWorld;
|
||||||
|
this.analogInputPos = analogInputPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long resolve(MinionRuntime minion) {
|
||||||
|
World world = minion.getMinion().getServer().getWorld(analogInputWorld);
|
||||||
|
if(world != null && world.isPosLoaded(analogInputPos) && world.getBlockState(analogInputPos).isOf(MinionBlocks.ANALOG_INPUT_BLOCK)) {
|
||||||
|
return (long) world.getReceivedRedstonePower(analogInputPos);
|
||||||
|
} else {
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ValueType<Long> getValueType() {
|
||||||
|
return ValueTypes.LONG;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ValueSupplierType<MinionRuntime> getType() {
|
||||||
|
return ValueSuppliers.ANALOG_INPUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Text getDisplayText() {
|
||||||
|
return Text.translatable("value_supplier_type.minions.analog_input.display", analogInputPos.toString(), analogInputWorld.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class AnalogInputSupplierType extends ValueSupplierType<MinionRuntime> {
|
||||||
|
@Override
|
||||||
|
public <T> Codec<? extends ValueSupplier<T, MinionRuntime>> getCodec(ValueType<T> type) {
|
||||||
|
if(type == ValueTypes.LONG) {
|
||||||
|
return ValueSupplier.castCodec(CODEC, ValueTypes.LONG, type);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> CompletableFuture<ValueSupplier<T, MinionRuntime>> openConfiguration(ServerPlayerEntity player, ValueType<T> valueType, @Nullable ValueSupplier<T, MinionRuntime> previous) {
|
||||||
|
if(valueType != ValueTypes.LONG) {
|
||||||
|
return CompletableFuture.failedFuture(new IllegalArgumentException("Value type " + valueType + " not allowed"));
|
||||||
|
}
|
||||||
|
|
||||||
|
CompletableFuture<ValueSupplier<T, MinionRuntime>> future = new CompletableFuture<>();
|
||||||
|
|
||||||
|
SimpleGui gui = new SimpleGui(ScreenHandlerType.GENERIC_3X3, player, false);
|
||||||
|
gui.setTitle(Text.translatable("value_supplier_type.minions.analog_input"));
|
||||||
|
|
||||||
|
gui.setSlot(4, new GuiElementBuilder(MinionItems.REFERENCE_ITEM)
|
||||||
|
.setCallback(() -> {
|
||||||
|
ItemStack cursor = player.currentScreenHandler.getCursorStack();
|
||||||
|
if(cursor.isOf(MinionItems.REFERENCE_ITEM) && cursor.get(MinionComponentTypes.REFERENCE) instanceof BlockPosClipboard pos) {
|
||||||
|
future.complete(new AnalogInputSupplier(pos.world(), pos.pos()).cast(valueType));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setItemName(Text.translatable("value_supplier_type.minions.analog_input.config.click_with_reference"))
|
||||||
|
);
|
||||||
|
return future;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,8 +4,13 @@ import net.minecraft.entity.Entity;
|
|||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||||
|
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@Mixin(Entity.class)
|
@Mixin(Entity.class)
|
||||||
public interface EntityAccessor {
|
public interface EntityAccessor {
|
||||||
@Invoker("canAddPassenger")
|
@Invoker("canAddPassenger")
|
||||||
boolean invokeCanAddPassenger(Entity other);
|
boolean minions$canAddPassenger(Entity other);
|
||||||
|
|
||||||
|
@Invoker("streamIntoPassengers")
|
||||||
|
Stream<Entity> minions$streamIntoPassengers();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package io.github.skippyall.minions.mixins;
|
||||||
|
|
||||||
|
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||||
|
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||||
|
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.block.entity.PistonBlockEntity;
|
||||||
|
import net.minecraft.block.piston.PistonBehavior;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Direction;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
|
||||||
|
@Mixin(PistonBlockEntity.class)
|
||||||
|
public abstract class PistonMovingBlockEntityMixin {
|
||||||
|
@WrapOperation(method = "pushEntities", at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "Lnet/minecraft/entity/Entity;getPistonBehavior()Lnet/minecraft/block/piston/PistonBehavior;"
|
||||||
|
))
|
||||||
|
private static PistonBehavior moveFakePlayers(Entity entity, Operation<PistonBehavior> original, World world, BlockPos pos, float f, PistonBlockEntity pistonBlockEntity)
|
||||||
|
{
|
||||||
|
if (entity instanceof MinionFakePlayer && pistonBlockEntity.getPushedBlock().isOf(Blocks.SLIME_BLOCK))
|
||||||
|
{
|
||||||
|
Vec3d vec3d = entity.getVelocity();
|
||||||
|
double x = vec3d.x;
|
||||||
|
double y = vec3d.y;
|
||||||
|
double z = vec3d.z;
|
||||||
|
Direction direction = pistonBlockEntity.getMovementDirection();
|
||||||
|
switch (direction.getAxis()) {
|
||||||
|
case X -> x = direction.getOffsetX();
|
||||||
|
case Y -> y = direction.getOffsetY();
|
||||||
|
case Z -> z = direction.getOffsetZ();
|
||||||
|
}
|
||||||
|
|
||||||
|
entity.setVelocity(x, y, z);
|
||||||
|
}
|
||||||
|
return original.call(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,20 +1,21 @@
|
|||||||
package io.github.skippyall.minions.mixins;
|
package io.github.skippyall.minions.mixins;
|
||||||
|
|
||||||
|
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||||
|
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||||
|
import io.github.skippyall.minions.mixinhelper.EntityViewMixinHelper;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.predicate.entity.EntityPredicates;
|
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
import net.minecraft.server.world.ServerWorld;
|
import net.minecraft.server.world.ServerWorld;
|
||||||
import net.minecraft.world.SpawnHelper;
|
import net.minecraft.world.SpawnHelper;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
|
||||||
|
|
||||||
@Mixin(SpawnHelper.class)
|
@Mixin(SpawnHelper.class)
|
||||||
public class SpawnHelperMixin {
|
public class SpawnHelperMixin {
|
||||||
@Redirect(method = "spawnEntitiesInChunk(Lnet/minecraft/entity/SpawnGroup;Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/world/chunk/Chunk;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/SpawnHelper$Checker;Lnet/minecraft/world/SpawnHelper$Runner;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/world/ServerWorld;getClosestPlayer(DDDDZ)Lnet/minecraft/entity/player/PlayerEntity;"))
|
@WrapOperation(method = "spawnEntitiesInChunk(Lnet/minecraft/entity/SpawnGroup;Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/world/chunk/Chunk;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/SpawnHelper$Checker;Lnet/minecraft/world/SpawnHelper$Runner;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/world/ServerWorld;getClosestPlayer(DDDDZ)Lnet/minecraft/entity/player/PlayerEntity;"))
|
||||||
private static PlayerEntity checkMobSpawningMinion(ServerWorld instance, double x, double y, double z, double maxDistance, boolean b) {
|
private static PlayerEntity checkMobSpawningMinion(ServerWorld world, double x, double y, double z, double maxDistance, boolean ignoreCreative, Operation<PlayerEntity> original) {
|
||||||
return instance.getClosestPlayer(x, y, z, maxDistance, EntityPredicates.EXCEPT_SPECTATOR.and(entity -> {
|
EntityViewMixinHelper.ADDITIONAL_PREDICATE.set(entity -> {
|
||||||
if(entity instanceof ServerPlayerEntity player) {
|
if(entity instanceof ServerPlayerEntity player) {
|
||||||
if(player instanceof MinionFakePlayer minion) {
|
if(player instanceof MinionFakePlayer minion) {
|
||||||
return minion.canSpawnMobs();
|
return minion.canSpawnMobs();
|
||||||
@@ -22,6 +23,9 @@ public class SpawnHelperMixin {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}));
|
});
|
||||||
|
PlayerEntity player = original.call(world, x, y, z, maxDistance, ignoreCreative);
|
||||||
|
EntityViewMixinHelper.ADDITIONAL_PREDICATE.remove();
|
||||||
|
return player;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package io.github.skippyall.minions.mixins;
|
||||||
|
|
||||||
|
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
|
||||||
|
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.world.tick.TickManager;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
|
||||||
|
@Mixin(TickManager.class)
|
||||||
|
public abstract class TickRateManagerMixin {
|
||||||
|
@Shadow
|
||||||
|
public abstract boolean shouldTick();
|
||||||
|
|
||||||
|
@ModifyReturnValue(method = "shouldSkipTick", at = @At("TAIL"))
|
||||||
|
private boolean handler(boolean alreadyFrozen, Entity entity) {
|
||||||
|
if (alreadyFrozen) return true;
|
||||||
|
if (shouldTick()) return false;
|
||||||
|
|
||||||
|
return !isActualPlayer(entity) && // not carrying players
|
||||||
|
((EntityAccessor) entity)
|
||||||
|
.minions$streamIntoPassengers()
|
||||||
|
.noneMatch(TickRateManagerMixin::isActualPlayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private static boolean isActualPlayer(Entity e) {
|
||||||
|
return e instanceof PlayerEntity && !(e instanceof MinionFakePlayer);
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-3
@@ -1,4 +1,4 @@
|
|||||||
package io.github.skippyall.minions.util;
|
package io.github.skippyall.minions.polymer;
|
||||||
|
|
||||||
import eu.pb4.polymer.networking.api.PolymerNetworking;
|
import eu.pb4.polymer.networking.api.PolymerNetworking;
|
||||||
import eu.pb4.polymer.networking.api.server.PolymerServerNetworking;
|
import eu.pb4.polymer.networking.api.server.PolymerServerNetworking;
|
||||||
@@ -9,7 +9,7 @@ import net.minecraft.server.network.ServerPlayNetworkHandler;
|
|||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import xyz.nucleoid.packettweaker.PacketContext;
|
import xyz.nucleoid.packettweaker.PacketContext;
|
||||||
|
|
||||||
public class PolymerUtil {
|
public class VersionSync {
|
||||||
public static final int NETWORK_VERSION = 1;
|
public static final int NETWORK_VERSION = 1;
|
||||||
|
|
||||||
public static boolean isOnClient(PacketContext context) {
|
public static boolean isOnClient(PacketContext context) {
|
||||||
@@ -29,7 +29,7 @@ public class PolymerUtil {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Id<? extends CustomPayload> getId() {
|
public Id<? extends CustomPayload> getId() {
|
||||||
return null;
|
return PACKET_ID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2,6 +2,7 @@ package io.github.skippyall.minions.program.supplier;
|
|||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
import io.github.skippyall.minions.program.value.SimpleValueType;
|
||||||
import io.github.skippyall.minions.registration.MinionRegistries;
|
import io.github.skippyall.minions.registration.MinionRegistries;
|
||||||
import io.github.skippyall.minions.program.value.ValueType;
|
import io.github.skippyall.minions.program.value.ValueType;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package io.github.skippyall.minions.program.supplier;
|
package io.github.skippyall.minions.program.supplier;
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.DataResult;
|
||||||
import io.github.skippyall.minions.registration.MinionRegistries;
|
import io.github.skippyall.minions.registration.MinionRegistries;
|
||||||
import io.github.skippyall.minions.program.InstructionRuntime;
|
import io.github.skippyall.minions.program.InstructionRuntime;
|
||||||
import io.github.skippyall.minions.program.value.ValueType;
|
import io.github.skippyall.minions.program.value.ValueType;
|
||||||
@@ -31,14 +32,33 @@ public interface ValueSupplier<T, R extends InstructionRuntime<R>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WARNING: If originalType is not the type of the value suppliers from the codec, this will leak wrong generics!
|
||||||
|
*/
|
||||||
|
static <T, U, R extends InstructionRuntime<R>, A extends ValueSupplier<U,R>, C extends ValueSupplier<T, R>> @Nullable Codec<A> castCodec(Codec<C> codec, ValueType<T> originalType, ValueType<U> newType) {
|
||||||
|
if(originalType == newType) {
|
||||||
|
//noinspection unchecked
|
||||||
|
return (Codec<A>) codec;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static <R extends InstructionRuntime<R>> Codec<ValueSupplier<?,R>> createArgumentCodec(Codec<ValueSupplierType<R>> codec) {
|
static <R extends InstructionRuntime<R>> Codec<ValueSupplier<?,R>> createArgumentCodec(Codec<ValueSupplierType<R>> codec) {
|
||||||
return codec.dispatch(
|
return codec.dispatch(
|
||||||
"type",
|
"type",
|
||||||
ValueSupplier::getType,
|
ValueSupplier::getType,
|
||||||
type ->
|
type ->
|
||||||
MinionRegistries.VALUE_TYPES.getCodec().<ValueSupplier<?,R>>dispatch(
|
MinionRegistries.VALUE_TYPES.getCodec().<ValueSupplier<?,R>>partialDispatch(
|
||||||
ValueSupplier::getValueType,
|
"type",
|
||||||
valueType -> type.getCodec(valueType).fieldOf("valueType")
|
s -> DataResult.success(s.getValueType()),
|
||||||
|
valueType -> {
|
||||||
|
if(type.getCodec(valueType) != null) {
|
||||||
|
return DataResult.success(type.getCodec(valueType).fieldOf("valueType"));
|
||||||
|
} else {
|
||||||
|
return DataResult.error(() -> "Supplier type " + type + "not available for value type " + valueType);
|
||||||
|
}
|
||||||
|
}
|
||||||
).fieldOf("valueType")
|
).fieldOf("valueType")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package io.github.skippyall.minions.program.supplier;
|
|||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import io.github.skippyall.minions.program.InstructionRuntime;
|
import io.github.skippyall.minions.program.InstructionRuntime;
|
||||||
|
import io.github.skippyall.minions.program.value.Cast;
|
||||||
|
import io.github.skippyall.minions.program.value.Casts;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -22,17 +24,29 @@ public class ValueSupplierList<R extends InstructionRuntime<R>> {
|
|||||||
this.arguments = new HashMap<>(arguments);
|
this.arguments = new HashMap<>(arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T getValue(Parameter<T> parameter, R runtime) {
|
public <F, T> T getValue(Parameter<T> parameter, R runtime) {
|
||||||
ValueSupplier<T,R> valueSupplier = getArgument(parameter);
|
//noinspection unchecked
|
||||||
return valueSupplier != null ? valueSupplier.resolve(runtime) : null;
|
ValueSupplier<F,R> valueSupplier = (ValueSupplier<F, R>) getArgument(parameter);
|
||||||
|
if(valueSupplier == null) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T, A extends ValueSupplier<T,R>> A getArgument(Parameter<T> parameter) {
|
if(valueSupplier.getValueType() == parameter.type()) {
|
||||||
ValueSupplier<?,R> valueSupplier = arguments.get(parameter.name());
|
return valueSupplier.cast(parameter.type()).resolve(runtime);
|
||||||
return valueSupplier == null ? null : valueSupplier.cast(parameter.type());
|
} else {
|
||||||
|
Cast<F,T> cast = Casts.getCast(valueSupplier.getValueType(), parameter.type());
|
||||||
|
if(cast != null) {
|
||||||
|
return cast.cast(valueSupplier.resolve(runtime));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> void setArgument(Parameter<T> parameter, ValueSupplier<T,R> valueSupplier) {
|
public ValueSupplier<?,R> getArgument(Parameter<?> parameter) {
|
||||||
|
return arguments.get(parameter.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> void setArgument(Parameter<T> parameter, ValueSupplier<?,R> valueSupplier) {
|
||||||
arguments.put(parameter.name(), valueSupplier);
|
arguments.put(parameter.name(), valueSupplier);
|
||||||
onChange(parameter);
|
onChange(parameter);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
package io.github.skippyall.minions.program.value;
|
||||||
|
|
||||||
|
public class Cast<F, T> {
|
||||||
|
private final ValueType<F> from;
|
||||||
|
private final ValueType<T> to;
|
||||||
|
|
||||||
|
private final Caster<F,T> caster;
|
||||||
|
|
||||||
|
private final boolean lossy, canFail;
|
||||||
|
|
||||||
|
public Cast(ValueType<F> from, ValueType<T> to, Caster<F,T> caster) {
|
||||||
|
this(from, to, caster, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Cast(ValueType<F> from, ValueType<T> to, Caster<F,T> caster, boolean lossy, boolean canFail) {
|
||||||
|
this.from = from;
|
||||||
|
this.to = to;
|
||||||
|
this.caster = caster;
|
||||||
|
|
||||||
|
this.lossy = lossy;
|
||||||
|
this.canFail = canFail;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T cast(F from) {
|
||||||
|
return caster.cast(from);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueType<F> getFrom() {
|
||||||
|
return from;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueType<T> getTo() {
|
||||||
|
return to;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLossy() {
|
||||||
|
return lossy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canFail() {
|
||||||
|
return canFail;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CastCrafter<F, T> {
|
||||||
|
private final ValueType<F> from;
|
||||||
|
private final ValueType<T> to;
|
||||||
|
|
||||||
|
private final Caster<F,T> caster;
|
||||||
|
|
||||||
|
private boolean lossy, canFail;
|
||||||
|
|
||||||
|
public CastCrafter(ValueType<F> from, ValueType<T> to, Caster<F, T> caster) {
|
||||||
|
this.from = from;
|
||||||
|
this.to = to;
|
||||||
|
this.caster = caster;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CastCrafter<F, T> lossy() {
|
||||||
|
lossy = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CastCrafter<F, T> canFail() {
|
||||||
|
canFail = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cast<F, T> craftCast() {
|
||||||
|
return new Cast<>(from, to, caster, lossy, canFail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface Caster<F, T> {
|
||||||
|
T cast(F from);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package io.github.skippyall.minions.program.value;
|
||||||
|
|
||||||
|
import io.github.skippyall.minions.registration.ValueTypes;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public class Casts {
|
||||||
|
public static <F,T> @Nullable Cast<F,T> getCast(ValueType<F> from, ValueType<T> to) {
|
||||||
|
if(from == to) {
|
||||||
|
//noinspection unchecked
|
||||||
|
return new Cast<>(from, to, v -> (T)v);
|
||||||
|
}
|
||||||
|
if(from == ValueTypes.LONG && to == ValueTypes.DOUBLE) {
|
||||||
|
//noinspection unchecked
|
||||||
|
return (Cast<F, T>) new Cast<>(ValueTypes.LONG, ValueTypes.DOUBLE, (v) -> (double)v);
|
||||||
|
}
|
||||||
|
if(from == ValueTypes.DOUBLE && to == ValueTypes.LONG) {
|
||||||
|
//noinspection unchecked
|
||||||
|
return (Cast<F, T>) new Cast.CastCrafter<>(ValueTypes.DOUBLE, ValueTypes.LONG, (v) -> (long)(double)v).lossy().craftCast();
|
||||||
|
}
|
||||||
|
if((from == ValueTypes.DOUBLE || from == ValueTypes.LONG) && to == ValueTypes.STRING) {
|
||||||
|
//noinspection unchecked
|
||||||
|
return (Cast<F, T>) new Cast.CastCrafter<>(from, ValueTypes.STRING, String::valueOf).craftCast();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean canCastSafely(ValueType<?> from, ValueType<?> to) {
|
||||||
|
if(from == to) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
Cast<?,?> cast = getCast(from, to);
|
||||||
|
return cast != null && !cast.canFail() && !cast.isLossy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package io.github.skippyall.minions.program.value;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
public class LongValueType implements ValueType<Long> {
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<Long> openValueDialog(ServerPlayerEntity player, Long previousValue) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Text getDisplayText(Long value) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Codec<Long> codec() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long defaultValue() {
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package io.github.skippyall.minions.program.value;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public record SimpleValueType<T>(Codec<T> codec, T defaultValue, BiFunction<ServerPlayerEntity, T, CompletableFuture<T>> valueDialogOpener, Function<T, Text> textDisplay) implements ValueType<T> {
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<T> openValueDialog(ServerPlayerEntity player, T previousValue) {
|
||||||
|
return valueDialogOpener.apply(player, previousValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Text getDisplayText(T value) {
|
||||||
|
return textDisplay.apply(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,17 +3,18 @@ package io.github.skippyall.minions.program.value;
|
|||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public record ValueType<T>(Codec<T> codec, T defaultValue, BiFunction<ServerPlayerEntity, T, CompletableFuture<T>> valueDialogOpener, Function<T, Text> textDisplay) {
|
public interface ValueType<T> {
|
||||||
public CompletableFuture<T> openValueDialog(ServerPlayerEntity player, T previousValue) {
|
CompletableFuture<T> openValueDialog(ServerPlayerEntity player, T previousValue);
|
||||||
return valueDialogOpener.apply(player, previousValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Text getDisplayText(T value) {
|
Text getDisplayText(T value);
|
||||||
return textDisplay.apply(value);
|
|
||||||
}
|
Codec<T> codec();
|
||||||
|
|
||||||
|
T defaultValue();
|
||||||
}
|
}
|
||||||
|
|||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
package io.github.skippyall.minions.program.value.conversion;
|
||||||
|
|
||||||
|
import io.github.skippyall.minions.program.value.ValueType;
|
||||||
|
|
||||||
|
public interface ValueConverter<F,T> {
|
||||||
|
T convert(F from);
|
||||||
|
|
||||||
|
ValueType<F> getFrom();
|
||||||
|
|
||||||
|
ValueType<T> getTo();
|
||||||
|
|
||||||
|
ValueConverterType<?> getType();
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
package io.github.skippyall.minions.program.value.conversion;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
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 interface ValueConverterType<C extends ValueConverter<?,?>> {
|
||||||
|
Codec<C> getCodec(ValueType<?> from, ValueType<?> to);
|
||||||
|
|
||||||
|
boolean isSupportedFromType(ValueType<?> type);
|
||||||
|
|
||||||
|
boolean isSupportedToType(ValueType<?> type);
|
||||||
|
|
||||||
|
CompletableFuture<C> configure(ServerPlayerEntity player, ValueType<?> from, ValueType<?> to, @Nullable C old);
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ package io.github.skippyall.minions.registration;
|
|||||||
|
|
||||||
import com.mojang.serialization.MapCodec;
|
import com.mojang.serialization.MapCodec;
|
||||||
import io.github.skippyall.minions.Minions;
|
import io.github.skippyall.minions.Minions;
|
||||||
|
import io.github.skippyall.minions.clipboard.BlockPosClipboard;
|
||||||
import io.github.skippyall.minions.clipboard.InstructionClipboard;
|
import io.github.skippyall.minions.clipboard.InstructionClipboard;
|
||||||
import io.github.skippyall.minions.clipboard.Clipboard;
|
import io.github.skippyall.minions.clipboard.Clipboard;
|
||||||
import net.minecraft.registry.Registry;
|
import net.minecraft.registry.Registry;
|
||||||
@@ -14,5 +15,6 @@ public class ClipboardTypes {
|
|||||||
|
|
||||||
static void register() {
|
static void register() {
|
||||||
register("instruction", InstructionClipboard.CODEC);
|
register("instruction", InstructionClipboard.CODEC);
|
||||||
|
register("position", BlockPosClipboard.CODEC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package io.github.skippyall.minions.registration;
|
||||||
|
|
||||||
|
import io.github.skippyall.minions.Minions;
|
||||||
|
import io.github.skippyall.minions.docs.ReferenceEntry;
|
||||||
|
import net.minecraft.registry.Registry;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
public class DocsEntryTypes {
|
||||||
|
public static void register() {
|
||||||
|
Registry.register(MinionRegistries.DOCS_ENTRY_TYPES, Identifier.of(Minions.MOD_ID, "reference_entry"), ReferenceEntry.CODEC);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
package io.github.skippyall.minions.registration;
|
package io.github.skippyall.minions.registration;
|
||||||
|
|
||||||
import io.github.skippyall.minions.instruction.inventory.SwapItemExecution;
|
import io.github.skippyall.minions.minion.program.instruction.inventory.SwapItemExecution;
|
||||||
import io.github.skippyall.minions.program.instruction.InstructionExecution;
|
import io.github.skippyall.minions.program.instruction.InstructionExecution;
|
||||||
import io.github.skippyall.minions.program.instruction.InstructionType;
|
import io.github.skippyall.minions.program.instruction.InstructionType;
|
||||||
import io.github.skippyall.minions.Minions;
|
import io.github.skippyall.minions.Minions;
|
||||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||||
import io.github.skippyall.minions.minion.fakeplayer.EntityPlayerActionPack;
|
import io.github.skippyall.minions.minion.fakeplayer.EntityPlayerActionPack;
|
||||||
import io.github.skippyall.minions.instruction.ActionExecution;
|
import io.github.skippyall.minions.minion.program.instruction.ActionExecution;
|
||||||
import io.github.skippyall.minions.instruction.MineBlockExecution;
|
import io.github.skippyall.minions.minion.program.instruction.MineBlockExecution;
|
||||||
import io.github.skippyall.minions.instruction.move.ContinuousWalkExecution;
|
import io.github.skippyall.minions.minion.program.instruction.move.ContinuousWalkExecution;
|
||||||
import io.github.skippyall.minions.instruction.move.TurnExecution;
|
import io.github.skippyall.minions.minion.program.instruction.move.TurnExecution;
|
||||||
import io.github.skippyall.minions.instruction.move.TurnVectorExecution;
|
import io.github.skippyall.minions.minion.program.instruction.move.TurnVectorExecution;
|
||||||
import io.github.skippyall.minions.instruction.move.WalkExecution;
|
import io.github.skippyall.minions.minion.program.instruction.move.WalkExecution;
|
||||||
import io.github.skippyall.minions.program.supplier.Parameter;
|
import io.github.skippyall.minions.program.supplier.Parameter;
|
||||||
import net.minecraft.registry.Registry;
|
import net.minecraft.registry.Registry;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
|||||||
@@ -2,12 +2,14 @@ package io.github.skippyall.minions.registration;
|
|||||||
|
|
||||||
import eu.pb4.polymer.core.api.block.PolymerBlockUtils;
|
import eu.pb4.polymer.core.api.block.PolymerBlockUtils;
|
||||||
import io.github.skippyall.minions.Minions;
|
import io.github.skippyall.minions.Minions;
|
||||||
|
import io.github.skippyall.minions.block.input.AnalogInputBlock;
|
||||||
import io.github.skippyall.minions.block.miniontrigger.MinionTriggerBlock;
|
import io.github.skippyall.minions.block.miniontrigger.MinionTriggerBlock;
|
||||||
import io.github.skippyall.minions.block.miniontrigger.MinionTriggerBlockEntity;
|
import io.github.skippyall.minions.block.miniontrigger.MinionTriggerBlockEntity;
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder;
|
import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder;
|
||||||
import net.minecraft.block.AbstractBlock;
|
import net.minecraft.block.AbstractBlock;
|
||||||
import net.minecraft.block.entity.BlockEntityType;
|
import net.minecraft.block.entity.BlockEntityType;
|
||||||
import net.minecraft.block.piston.PistonBehavior;
|
import net.minecraft.block.piston.PistonBehavior;
|
||||||
|
import net.minecraft.network.packet.CustomPayload;
|
||||||
import net.minecraft.registry.Registries;
|
import net.minecraft.registry.Registries;
|
||||||
import net.minecraft.registry.Registry;
|
import net.minecraft.registry.Registry;
|
||||||
import net.minecraft.registry.RegistryKey;
|
import net.minecraft.registry.RegistryKey;
|
||||||
@@ -35,6 +37,15 @@ public class MinionBlocks {
|
|||||||
FabricBlockEntityTypeBuilder.create(MinionTriggerBlockEntity::new, MINION_TRIGGER_BLOCK).build()
|
FabricBlockEntityTypeBuilder.create(MinionTriggerBlockEntity::new, MINION_TRIGGER_BLOCK).build()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
public static final Identifier ANALOG_INPUT_BLOCK_ID = Identifier.of(Minions.MOD_ID, "analog_input");
|
||||||
|
public static final AnalogInputBlock ANALOG_INPUT_BLOCK = Registry.register(
|
||||||
|
Registries.BLOCK,
|
||||||
|
ANALOG_INPUT_BLOCK_ID,
|
||||||
|
new AnalogInputBlock(AbstractBlock.Settings.create()
|
||||||
|
.registryKey(RegistryKey.of(RegistryKeys.BLOCK, ANALOG_INPUT_BLOCK_ID))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
public static void register() {
|
public static void register() {
|
||||||
PolymerBlockUtils.registerBlockEntity(MINION_TRIGGER_BE_TYPE);
|
PolymerBlockUtils.registerBlockEntity(MINION_TRIGGER_BE_TYPE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ import net.minecraft.util.Identifier;
|
|||||||
import static io.github.skippyall.minions.minion.MinionConfig.booleanOption;
|
import static io.github.skippyall.minions.minion.MinionConfig.booleanOption;
|
||||||
|
|
||||||
public class MinionConfigOptions {
|
public class MinionConfigOptions {
|
||||||
public static final MinionConfig.Option<Boolean> showInServerList = register(booleanOption(id("showInServerList"), false));
|
public static final MinionConfig.Option<Boolean> showInServerList = register(booleanOption(id("show_in_server_list"), false));
|
||||||
public static final MinionConfig.Option<Boolean> showInTabList = register(booleanOption(id("showInTabList"), false));
|
public static final MinionConfig.Option<Boolean> showInTabList = register(booleanOption(id("show_in_tab_list"), false));
|
||||||
public static final MinionConfig.Option<Boolean> sendLoginMessage = register(booleanOption(id("sendLoginMessage"), false));
|
public static final MinionConfig.Option<Boolean> sendLoginMessage = register(booleanOption(id("send_login_message"), false));
|
||||||
public static final MinionConfig.Option<Boolean> sendLogoutMessage = register(booleanOption(id("sendLogoutMessage"), false));
|
public static final MinionConfig.Option<Boolean> sendLogoutMessage = register(booleanOption(id("send_logout_message"), false));
|
||||||
public static final MinionConfig.Option<Boolean> countForSleeping = register(booleanOption(id("countForSleeping"), false));
|
public static final MinionConfig.Option<Boolean> countForSleeping = register(booleanOption(id("count_for_sleeping"), false));
|
||||||
public static final MinionConfig.Option<Boolean> countForPlayerLimit = register(booleanOption(id("countForPlayerLimit"), false));
|
public static final MinionConfig.Option<Boolean> countForPlayerLimit = register(booleanOption(id("count_for_player_limit"), false));
|
||||||
public static final MinionConfig.Option<Boolean> spawnAndDespawnMobs = register(booleanOption(id("spawnAndDespawnMobs"), false));
|
public static final MinionConfig.Option<Boolean> spawnAndDespawnMobs = register(booleanOption(id("spawn_and_despawn_mobs"), false));
|
||||||
|
|
||||||
private static <T> MinionConfig.Option<T> register(MinionConfig.Option<T> option) {
|
private static <T> MinionConfig.Option<T> register(MinionConfig.Option<T> option) {
|
||||||
return Registry.register(MinionRegistries.MINION_CONFIG_OPTIONS, option.key(), option);
|
return Registry.register(MinionRegistries.MINION_CONFIG_OPTIONS, option.key(), option);
|
||||||
@@ -23,4 +23,6 @@ public class MinionConfigOptions {
|
|||||||
private static Identifier id(String name) {
|
private static Identifier id(String name) {
|
||||||
return Identifier.of(Minions.MOD_ID, name);
|
return Identifier.of(Minions.MOD_ID, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void register() {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,12 @@ public class MinionRegistration {
|
|||||||
MinionRegistries.register();
|
MinionRegistries.register();
|
||||||
|
|
||||||
ClipboardTypes.register();
|
ClipboardTypes.register();
|
||||||
|
DocsEntryTypes.register();
|
||||||
GuiDisplayTypes.register();
|
GuiDisplayTypes.register();
|
||||||
Instructions.register();
|
Instructions.register();
|
||||||
MinionBlocks.register();
|
MinionBlocks.register();
|
||||||
MinionComponentTypes.register();
|
MinionComponentTypes.register();
|
||||||
|
MinionConfigOptions.register();
|
||||||
MinionItems.register();
|
MinionItems.register();
|
||||||
MinionListeners.register();
|
MinionListeners.register();
|
||||||
SkinProviders.register();
|
SkinProviders.register();
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package io.github.skippyall.minions.registration;
|
|||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import com.mojang.serialization.MapCodec;
|
import com.mojang.serialization.MapCodec;
|
||||||
import io.github.skippyall.minions.Minions;
|
import io.github.skippyall.minions.Minions;
|
||||||
|
import io.github.skippyall.minions.docs.DocsEntry;
|
||||||
import io.github.skippyall.minions.docs.ReferenceEntry;
|
import io.github.skippyall.minions.docs.ReferenceEntry;
|
||||||
import io.github.skippyall.minions.gui.GuiDisplay;
|
import io.github.skippyall.minions.gui.GuiDisplay;
|
||||||
import io.github.skippyall.minions.minion.MinionConfig;
|
import io.github.skippyall.minions.minion.MinionConfig;
|
||||||
@@ -35,9 +36,10 @@ public class MinionRegistries {
|
|||||||
public static final Registry<MapCodec<? extends Clipboard>> CLIPBOARD_TYPES = registry("clipboard_type");
|
public static final Registry<MapCodec<? extends Clipboard>> CLIPBOARD_TYPES = registry("clipboard_type");
|
||||||
public static final Registry<SpecialAbility> SPECIAL_ABILITIES = registry("special_ability");
|
public static final Registry<SpecialAbility> SPECIAL_ABILITIES = registry("special_ability");
|
||||||
public static final Registry<MinionConfig.Option<?>> MINION_CONFIG_OPTIONS = registry("minion_config_option");
|
public static final Registry<MinionConfig.Option<?>> MINION_CONFIG_OPTIONS = registry("minion_config_option");
|
||||||
|
public static final Registry<MapCodec<? extends DocsEntry>> DOCS_ENTRY_TYPES = registry("docs_entry_type");
|
||||||
|
|
||||||
public static final RegistryKey<Registry<GuiDisplay>> GUI_DISPLAY = key("gui_display");
|
public static final RegistryKey<Registry<GuiDisplay>> GUI_DISPLAY = key("gui_display");
|
||||||
public static final RegistryKey<Registry<ReferenceEntry>> REFERENCE_ENTRY = key("reference_entry");
|
public static final RegistryKey<Registry<ReferenceEntry>> DOCS_ENTRY = key("docs_entry");
|
||||||
|
|
||||||
private static <T> Registry<T> registry(String id) {
|
private static <T> Registry<T> registry(String id) {
|
||||||
return FabricRegistryBuilder.<T>createSimple(key(id)).attribute(RegistryAttribute.OPTIONAL).buildAndRegister();
|
return FabricRegistryBuilder.<T>createSimple(key(id)).attribute(RegistryAttribute.OPTIONAL).buildAndRegister();
|
||||||
@@ -49,6 +51,5 @@ public class MinionRegistries {
|
|||||||
|
|
||||||
public static void register() {
|
public static void register() {
|
||||||
DynamicRegistries.register(GUI_DISPLAY, GuiDisplay.CODEC);
|
DynamicRegistries.register(GUI_DISPLAY, GuiDisplay.CODEC);
|
||||||
DynamicRegistries.register(REFERENCE_ENTRY, ReferenceEntry.CODEC);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package io.github.skippyall.minions.registration;
|
package io.github.skippyall.minions.registration;
|
||||||
|
|
||||||
|
import io.github.skippyall.minions.minion.program.supplier.AnalogInputSupplier;
|
||||||
import io.github.skippyall.minions.program.supplier.FixedValueSupplierType;
|
import io.github.skippyall.minions.program.supplier.FixedValueSupplierType;
|
||||||
import io.github.skippyall.minions.program.supplier.ValueSupplierType;
|
import io.github.skippyall.minions.program.supplier.ValueSupplierType;
|
||||||
import io.github.skippyall.minions.Minions;
|
import io.github.skippyall.minions.Minions;
|
||||||
@@ -9,6 +10,7 @@ import net.minecraft.util.Identifier;
|
|||||||
|
|
||||||
public class ValueSuppliers {
|
public class ValueSuppliers {
|
||||||
public static final FixedValueSupplierType<MinionRuntime> FIXED_VALUE_SUPPLIER_TYPE = register("fixed", new FixedValueSupplierType<>());
|
public static final FixedValueSupplierType<MinionRuntime> FIXED_VALUE_SUPPLIER_TYPE = register("fixed", new FixedValueSupplierType<>());
|
||||||
|
public static final AnalogInputSupplier.AnalogInputSupplierType ANALOG_INPUT = register("analog_input", new AnalogInputSupplier.AnalogInputSupplierType());
|
||||||
|
|
||||||
public static <T extends ValueSupplierType<MinionRuntime>> T register(String id, T type) {
|
public static <T extends ValueSupplierType<MinionRuntime>> T register(String id, T type) {
|
||||||
return Registry.register(MinionRegistries.VALUE_SUPPLIER_TYPES, Identifier.of(Minions.MOD_ID, id), type);
|
return Registry.register(MinionRegistries.VALUE_SUPPLIER_TYPES, Identifier.of(Minions.MOD_ID, id), type);
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
package io.github.skippyall.minions.registration;
|
package io.github.skippyall.minions.registration;
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
|
import io.github.skippyall.minions.program.value.SimpleValueType;
|
||||||
import io.github.skippyall.minions.program.value.ValueType;
|
import io.github.skippyall.minions.program.value.ValueType;
|
||||||
import io.github.skippyall.minions.Minions;
|
import io.github.skippyall.minions.Minions;
|
||||||
import io.github.skippyall.minions.gui.input.ChoiceInput;
|
import io.github.skippyall.minions.gui.input.ChoiceInput;
|
||||||
import io.github.skippyall.minions.gui.input.TextInput;
|
import io.github.skippyall.minions.gui.input.TextInput;
|
||||||
import io.github.skippyall.minions.instruction.move.TurnDirection;
|
import io.github.skippyall.minions.minion.program.instruction.move.TurnDirection;
|
||||||
import net.minecraft.registry.Registry;
|
import net.minecraft.registry.Registry;
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
@@ -79,7 +80,7 @@ public class ValueTypes {
|
|||||||
return Registry.register(
|
return Registry.register(
|
||||||
MinionRegistries.VALUE_TYPES,
|
MinionRegistries.VALUE_TYPES,
|
||||||
identifier,
|
identifier,
|
||||||
new ValueType<>(
|
new SimpleValueType<>(
|
||||||
codec,
|
codec,
|
||||||
defaultValue,
|
defaultValue,
|
||||||
valueDialogOpener,
|
valueDialogOpener,
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"type": "minions:reference_entry",
|
||||||
|
"metadata": {
|
||||||
|
"title": "Hi"
|
||||||
|
},
|
||||||
|
"object": {
|
||||||
|
"registry": "minions:value_type",
|
||||||
|
"value": "minions:float"
|
||||||
|
},
|
||||||
|
"shortDescription": "Whatever floats your goat",
|
||||||
|
"longDescription": "A decimal value"
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
[
|
||||||
|
"minions:test"
|
||||||
|
]
|
||||||
@@ -55,6 +55,7 @@
|
|||||||
"minions.command.minion.not_present": "This minion does not exist",
|
"minions.command.minion.not_present": "This minion does not exist",
|
||||||
|
|
||||||
"minions.reference.instruction.tooltip": "Linked to instruction %s in %s",
|
"minions.reference.instruction.tooltip": "Linked to instruction %s in %s",
|
||||||
|
"minions.reference.block.tooltip": "Linked to block at %s",
|
||||||
|
|
||||||
"instruction_type.minions.walk": "Walk",
|
"instruction_type.minions.walk": "Walk",
|
||||||
"instruction_type.minions.walk.description": "Walk forward a specified amount of blocks",
|
"instruction_type.minions.walk.description": "Walk forward a specified amount of blocks",
|
||||||
@@ -70,8 +71,11 @@
|
|||||||
"value_type.minions.string": "Text",
|
"value_type.minions.string": "Text",
|
||||||
"value_type.minions.turn_direction": "Turn Direction",
|
"value_type.minions.turn_direction": "Turn Direction",
|
||||||
|
|
||||||
"value_supplier_type.minions.fixed": "Value",
|
"value_supplier_type.minions.fixed": "Fixed Value",
|
||||||
"value_supplier_type.minions.fixed.display": "Fixed Value: %s",
|
"value_supplier_type.minions.fixed.display": "Fixed Value: %s",
|
||||||
|
"value_supplier_type.minions.analog_input": "Analog Input",
|
||||||
|
"value_supplier_type.minions.analog_input.display": "Analog Input at %s in %s",
|
||||||
|
"value_supplier_type.minions.analog_input.config.click_with_reference": "Click here with a position clipboard",
|
||||||
|
|
||||||
"item.minions.attack_module": "Attack Module",
|
"item.minions.attack_module": "Attack Module",
|
||||||
"item.minions.interact_module": "Interact Module",
|
"item.minions.interact_module": "Interact Module",
|
||||||
|
|||||||
@@ -9,20 +9,22 @@
|
|||||||
"EntityAccessor",
|
"EntityAccessor",
|
||||||
"EntityMixin",
|
"EntityMixin",
|
||||||
"EntityViewMixin",
|
"EntityViewMixin",
|
||||||
"compat.universal_graves.GraveMixin",
|
|
||||||
"MinecraftServerMixin",
|
"MinecraftServerMixin",
|
||||||
"MobEntityMixin",
|
"MobEntityMixin",
|
||||||
|
"PistonMovingBlockEntityMixin",
|
||||||
"PlayerListEntryS2CPacket$EntryMixin",
|
"PlayerListEntryS2CPacket$EntryMixin",
|
||||||
"PlayerListMixin",
|
"PlayerListMixin",
|
||||||
"PlayerMixin",
|
"PlayerMixin",
|
||||||
"ServerPlayNetworkHandlerMixin",
|
"ServerPlayNetworkHandlerMixin",
|
||||||
"SleepManagerMixin",
|
"SleepManagerMixin",
|
||||||
"SpawnHelperMixin",
|
"SpawnHelperMixin",
|
||||||
|
"TickRateManagerMixin",
|
||||||
"antimobcap.ChunkLevelManager$DistanceFromNearestPlayerTrackerMixin",
|
"antimobcap.ChunkLevelManager$DistanceFromNearestPlayerTrackerMixin",
|
||||||
"antimobcap.ChunkLevelManagerMixin",
|
"antimobcap.ChunkLevelManagerMixin",
|
||||||
"antimobcap.ChunkPosDistanceLevelPropagatorMixin",
|
"antimobcap.ChunkPosDistanceLevelPropagatorMixin",
|
||||||
"antimobcap.ServerChunkManagerAccessor",
|
"antimobcap.ServerChunkManagerAccessor",
|
||||||
"antimobcap.ServerChunkManagerMixin"
|
"antimobcap.ServerChunkManagerMixin",
|
||||||
|
"compat.universal_graves.GraveMixin"
|
||||||
],
|
],
|
||||||
"client": [],
|
"client": [],
|
||||||
"server": [],
|
"server": [],
|
||||||
|
|||||||
Reference in New Issue
Block a user