diff --git a/LICENSE b/LICENSE index c986429..e0bddef 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2024 +Copyright (c) 2024 skippyall Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/TODO.txt b/TODO.txt new file mode 100644 index 0000000..f81f296 --- /dev/null +++ b/TODO.txt @@ -0,0 +1,35 @@ +- Module: + - Bewegungsmodul ✓ + - Angriffsmodul ✓ + - Abbaumodul ✓ + - Platziermodul / Verwendungsmodul ✓ + - Werfmodul + - Inventarmanagementmodul (Noch nicht wirklich) + - Inventaropenmodul (Nä) + +- Detektoren: + - Blockdetektor + - Entitydetektor + - Dimensiondetektor + - Positiondetektor + - Inventardetektor + +- Programmieren: Nö + - Variablen Nö + - (Listen) Nö + - Warten Nö + - Wiederholen Nö + - Wiederhole bis/während Nö + - Wiederhole x mal/(für jedes Element) Nö + - Bedingung Nö + +- VariableTypen: + - Integer ✓ + - String ✓ + - Position (Nö) + - Block (weisned) + - BlockType + - (NBT) Nö + - (World) Nö + - (Chunk) Nö + - Inventory (weisned) diff --git a/build.gradle b/build.gradle index d64efcb..db268b5 100644 --- a/build.gradle +++ b/build.gradle @@ -108,6 +108,11 @@ jar { from("LICENSE") { rename { "${it}_${project.archives_base_name}"} } + + from("src/main/resoures/assets/minions/lang") { + include("*") + into("data/minions/lang/") + } } // configure the maven publication @@ -124,15 +129,10 @@ publishing { // Notice: This block does NOT have the same function as the block in the top level. // The repositories here will be used for publishing your artifact, not for // retrieving dependencies. - if(project.hasProperty("foxgalaxy_user_name") && project.hasProperty("foxgalaxy_password")) { - maven { - url = "https://maven.foxgalaxy.de/private" - - credentials { - username = project.property("foxgalaxy_user_name") - password = project.property("foxgalaxy_password") - } - } + maven { + name = "foxgalaxy" + url = "https://maven.foxgalaxy.de/private" + credentials(PasswordCredentials) } } } diff --git a/gradle.properties b/gradle.properties index c2d996d..99abc21 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ org.gradle.jvmargs=-Xmx1G yarn_mappings=1.21.7+build.2 # Mod Properties - mod_version = 1.0.0-SNAPSHOT-1 + mod_version = 1.0.0-TEST-1 maven_group = io.github.skippyall archives_base_name = Minions diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..d997cfc Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 3c0465a..c61a118 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1 +1,7 @@ -distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..739907d --- /dev/null +++ b/gradlew @@ -0,0 +1,248 @@ +#!/bin/sh + +# +# Copyright © 2015 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/2d6327017519d23b96af35865dc997fcb544fb40/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..c4bdd3a --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,93 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/publish b/publish new file mode 100644 index 0000000..1041747 --- /dev/null +++ b/publish @@ -0,0 +1,2 @@ +#!/bin/bash +bash gradlew publish -PfoxgalaxyPassword=$(read -s -p "Enter Password: ") \ No newline at end of file diff --git a/src/client/java/io/github/skippyall/minions/client/MinionsClient.java b/src/client/java/io/github/skippyall/minions/client/MinionsClient.java index 85f64fa..c99fdde 100644 --- a/src/client/java/io/github/skippyall/minions/client/MinionsClient.java +++ b/src/client/java/io/github/skippyall/minions/client/MinionsClient.java @@ -1,8 +1,8 @@ package io.github.skippyall.minions.client; import eu.pb4.polymer.networking.api.client.PolymerClientNetworking; -import io.github.skippyall.minions.registration.MinionBlocks; import io.github.skippyall.minions.polymer.VersionSync; +import io.github.skippyall.minions.registration.MinionBlocks; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.rendering.v1.BlockRenderLayerMap; import net.minecraft.client.render.BlockRenderLayer; diff --git a/src/main/java/io/github/skippyall/minions/MinionMixinConfigPlugin.java b/src/main/java/io/github/skippyall/minions/MinionMixinConfigPlugin.java index bba6579..7528226 100644 --- a/src/main/java/io/github/skippyall/minions/MinionMixinConfigPlugin.java +++ b/src/main/java/io/github/skippyall/minions/MinionMixinConfigPlugin.java @@ -21,10 +21,10 @@ public class MinionMixinConfigPlugin implements IMixinConfigPlugin { @Override public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { - if(mixinClassName.startsWith("io.github.skippyall.mixins.compat.universal_graves.")) { + if(mixinClassName.startsWith("io.github.skippyall.minions.mixins.compat.universal_graves.")) { return MinionsConfig.get().compat.enableGravesCompat && FabricLoader.getInstance().isModLoaded("universal-graves"); } - if(mixinClassName.startsWith("io.github.skippyall.mixins.antimobcap.")) { + if(mixinClassName.startsWith("io.github.skippyall.minions.mixins.antimobcap.")) { return MinionsConfig.get().minion.enableMobCapHacks; } return true; diff --git a/src/main/java/io/github/skippyall/minions/Minions.java b/src/main/java/io/github/skippyall/minions/Minions.java index 1898537..8aaba56 100644 --- a/src/main/java/io/github/skippyall/minions/Minions.java +++ b/src/main/java/io/github/skippyall/minions/Minions.java @@ -3,10 +3,10 @@ package io.github.skippyall.minions; import eu.pb4.polymer.resourcepack.api.PolymerResourcePackUtils; 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.MinionPersistentState; -import io.github.skippyall.minions.registration.MinionRegistration; +import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; import io.github.skippyall.minions.polymer.VersionSync; +import io.github.skippyall.minions.registration.MinionRegistration; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; @@ -38,12 +38,6 @@ public class Minions implements ModInitializer { CommandRegistrationCallback.EVENT.register(MinionsCommand::register); - /*ServerBlockEntityEvents.BLOCK_ENTITY_LOAD.register((blockEntity, world) -> { - if(blockEntity instanceof MinionTriggerBlockEntity) { - world.updateComparators(blockEntity.getPos(), MinionBlocks.MINION_TRIGGER_BLOCK); - } - });*/ - PolymerResourcePackUtils.addModAssets(Minions.MOD_ID); ResourceManagerHelper.get(ResourceType.SERVER_DATA).registerReloadListener(new DocsManager()); diff --git a/src/main/java/io/github/skippyall/minions/MinionsConfig.java b/src/main/java/io/github/skippyall/minions/MinionsConfig.java index a4140d2..fb05f23 100644 --- a/src/main/java/io/github/skippyall/minions/MinionsConfig.java +++ b/src/main/java/io/github/skippyall/minions/MinionsConfig.java @@ -8,7 +8,6 @@ import com.electronwill.nightconfig.core.serde.ObjectDeserializer; import com.electronwill.nightconfig.core.serde.ObjectSerializer; import com.electronwill.nightconfig.core.serde.SerdeException; import com.electronwill.nightconfig.core.serde.annotations.SerdeComment; -import com.electronwill.nightconfig.core.serde.annotations.SerdeSkipDeserializingIf; import com.electronwill.nightconfig.toml.TomlFormat; import com.electronwill.nightconfig.toml.TomlParser; import net.fabricmc.loader.api.FabricLoader; @@ -17,31 +16,24 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import static com.electronwill.nightconfig.core.serde.annotations.SerdeSkipDeserializingIf.SkipDeIf.IS_MISSING; - public class MinionsConfig { private static MinionsConfig INSTANCE; - @SerdeSkipDeserializingIf(IS_MISSING) public Minion minion = new Minion(); public static class Minion { @SerdeComment("The prefix for all minion names") - @SerdeSkipDeserializingIf(IS_MISSING) public String minionPrefix = "+"; @SerdeComment("Makes minions not raise the mob cap if they can't spawn mobs.") @SerdeComment("Might cause incompatibilities.") - @SerdeSkipDeserializingIf(IS_MISSING) public boolean enableMobCapHacks = true; } - @SerdeSkipDeserializingIf(IS_MISSING) public Compat compat = new Compat(); public static class Compat { @SerdeComment("Enables compat with Universal Graves, which allows everyone to pick up graves from minions") - @SerdeSkipDeserializingIf(IS_MISSING) public boolean enableGravesCompat = true; } @@ -66,12 +58,15 @@ public class MinionsConfig { public static void loadConfig() { try { + CommentedConfig defaultConfig = ObjectSerializer.standard().serializeFields(new MinionsConfig(), TomlFormat::newConfig); + CommentedConfig config = new TomlParser().parse(getPath(), (file, configFormat) -> { - CommentedConfig defaultConfig = ObjectSerializer.standard().serializeFields(new MinionsConfig(), TomlFormat::newConfig); configFormat.createWriter().write(defaultConfig, file, WritingMode.REPLACE); return true; }); + //Always use default values when entries are missing + config.addAll(defaultConfig); INSTANCE = ObjectDeserializer.standard().deserializeFields(config, MinionsConfig::new); } catch (SerdeException | ParsingException | WritingException e) { Minions.LOGGER.error("Error while reading config", e); diff --git a/src/main/java/io/github/skippyall/minions/block/input/AnalogInputBlock.java b/src/main/java/io/github/skippyall/minions/block/input/AnalogInputBlock.java index 9a7d591..0a7b247 100644 --- a/src/main/java/io/github/skippyall/minions/block/input/AnalogInputBlock.java +++ b/src/main/java/io/github/skippyall/minions/block/input/AnalogInputBlock.java @@ -16,7 +16,9 @@ public class AnalogInputBlock extends Block { @Override protected ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit) { - player.getInventory().offer(ClipboardItem.createBlockPosReference(world, pos), true); + if(!world.isClient) { + player.getInventory().offer(ClipboardItem.createBlockPosReference(world, pos), true); + } return ActionResult.SUCCESS; } } diff --git a/src/main/java/io/github/skippyall/minions/block/instruction_bound/InstructionBoundBlockEntity.java b/src/main/java/io/github/skippyall/minions/block/instruction_bound/InstructionBoundBlockEntity.java index b04bf38..39f0c49 100644 --- a/src/main/java/io/github/skippyall/minions/block/instruction_bound/InstructionBoundBlockEntity.java +++ b/src/main/java/io/github/skippyall/minions/block/instruction_bound/InstructionBoundBlockEntity.java @@ -7,6 +7,7 @@ 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.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; import java.util.Optional; @@ -25,13 +26,17 @@ public abstract class InstructionBoundBlockEntity getListenerClass(); public void removeListener() { - L listener = getListener(); - listener.remove(world.getServer()); + if(world instanceof ServerWorld serverWorld) { + L listener = getListener(); + listener.remove(serverWorld.getServer()); + } } public void addListener() { - L listener = createListener(); - listener.add(world.getServer()); + if(world instanceof ServerWorld serverWorld) { + L listener = createListener(); + listener.add(serverWorld.getServer()); + } } public void setInstruction(UUID minionUuid, String instructionName) { diff --git a/src/main/java/io/github/skippyall/minions/block/miniontrigger/MinionTriggerBlock.java b/src/main/java/io/github/skippyall/minions/block/miniontrigger/MinionTriggerBlock.java index 601eb24..e4188c9 100644 --- a/src/main/java/io/github/skippyall/minions/block/miniontrigger/MinionTriggerBlock.java +++ b/src/main/java/io/github/skippyall/minions/block/miniontrigger/MinionTriggerBlock.java @@ -8,11 +8,10 @@ import eu.pb4.polymer.resourcepack.api.PolymerResourcePackUtils; import eu.pb4.polymer.virtualentity.api.BlockWithElementHolder; import eu.pb4.polymer.virtualentity.api.ElementHolder; 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.Minions; +import io.github.skippyall.minions.block.instruction_bound.InstructionBoundBlock; import io.github.skippyall.minions.polymer.VersionSync; +import io.github.skippyall.minions.registration.MinionBlocks; import net.minecraft.block.AbstractRedstoneGateBlock; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -21,6 +20,7 @@ import net.minecraft.block.SideShapeType; import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntityType; import net.minecraft.component.DataComponentTypes; +import net.minecraft.item.ItemDisplayContext; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.server.network.ServerPlayNetworkHandler; @@ -120,7 +120,7 @@ public class MinionTriggerBlock extends InstructionBoundBlock implements Polymer ElementHolder holder = new ElementHolder() { @Override public boolean startWatching(ServerPlayNetworkHandler player) { - if(PolymerResourcePackUtils.hasMainPack(player)) { + if(PolymerResourcePackUtils.hasMainPack(player) && !VersionSync.isOnClient(player)) { return super.startWatching(player); } else { return false; @@ -130,7 +130,9 @@ public class MinionTriggerBlock extends InstructionBoundBlock implements Polymer ItemStack stack = new ItemStack(Items.BARRIER); stack.set(DataComponentTypes.ITEM_MODEL, Identifier.of(Minions.MOD_ID, "minion_trigger_no_plate_" + (initialBlockState.get(MinionTriggerBlock.POWERED) ? "active" : "inactive"))); - holder.addElement(new ItemDisplayElement(stack)); + ItemDisplayElement element = new ItemDisplayElement(stack); + element.setItemDisplayContext(ItemDisplayContext.NONE); + holder.addElement(element); return holder; } } diff --git a/src/main/java/io/github/skippyall/minions/block/miniontrigger/MinionTriggerBlockEntity.java b/src/main/java/io/github/skippyall/minions/block/miniontrigger/MinionTriggerBlockEntity.java index 74ddb45..32ed91e 100644 --- a/src/main/java/io/github/skippyall/minions/block/miniontrigger/MinionTriggerBlockEntity.java +++ b/src/main/java/io/github/skippyall/minions/block/miniontrigger/MinionTriggerBlockEntity.java @@ -1,21 +1,13 @@ 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.registration.MinionBlocks; -import io.github.skippyall.minions.minion.MinionRuntime; -import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; -import io.github.skippyall.minions.program.instruction.ConfiguredInstruction; import net.minecraft.block.BlockState; -import net.minecraft.block.entity.BlockEntity; import net.minecraft.storage.ReadView; import net.minecraft.storage.WriteView; import net.minecraft.util.Uuids; import net.minecraft.util.math.BlockPos; -import java.util.Optional; -import java.util.UUID; - public class MinionTriggerBlockEntity extends InstructionBoundBlockEntity { public MinionTriggerBlockEntity(BlockPos pos, BlockState state) { super(MinionBlocks.MINION_TRIGGER_BE_TYPE, pos, state); diff --git a/src/main/java/io/github/skippyall/minions/block/miniontrigger/MinionTriggerMinionListener.java b/src/main/java/io/github/skippyall/minions/block/miniontrigger/MinionTriggerMinionListener.java index 2657093..41373f7 100644 --- a/src/main/java/io/github/skippyall/minions/block/miniontrigger/MinionTriggerMinionListener.java +++ b/src/main/java/io/github/skippyall/minions/block/miniontrigger/MinionTriggerMinionListener.java @@ -5,10 +5,10 @@ import com.mojang.serialization.codecs.RecordCodecBuilder; import io.github.skippyall.minions.Minions; import io.github.skippyall.minions.listener.BlockEntityMinionInstructionListener; import io.github.skippyall.minions.minion.MinionRuntime; -import io.github.skippyall.minions.registration.MinionBlocks; import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; import io.github.skippyall.minions.program.instruction.ConfiguredInstruction; import io.github.skippyall.minions.program.instruction.ConfiguredInstructionListener; +import io.github.skippyall.minions.registration.MinionBlocks; import net.minecraft.registry.RegistryKey; import net.minecraft.server.MinecraftServer; import net.minecraft.util.Identifier; diff --git a/src/main/java/io/github/skippyall/minions/clipboard/ClipboardItem.java b/src/main/java/io/github/skippyall/minions/clipboard/ClipboardItem.java index 3b11dd7..29e0e23 100644 --- a/src/main/java/io/github/skippyall/minions/clipboard/ClipboardItem.java +++ b/src/main/java/io/github/skippyall/minions/clipboard/ClipboardItem.java @@ -1,9 +1,9 @@ package io.github.skippyall.minions.clipboard; import eu.pb4.polymer.core.api.item.PolymerItem; +import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; import io.github.skippyall.minions.registration.MinionComponentTypes; import io.github.skippyall.minions.registration.MinionItems; -import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; import net.minecraft.component.DataComponentTypes; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -22,7 +22,7 @@ public class ClipboardItem extends Item implements PolymerItem { @Override public Item getPolymerItem(ItemStack itemStack, PacketContext context) { - return Items.PAPER; + return /*VersionSync.isOnClient(context) ? this : */Items.PAPER; } @Override diff --git a/src/main/java/io/github/skippyall/minions/command/DocsSubcommand.java b/src/main/java/io/github/skippyall/minions/command/DocsSubcommand.java index 84956ee..07e7362 100644 --- a/src/main/java/io/github/skippyall/minions/command/DocsSubcommand.java +++ b/src/main/java/io/github/skippyall/minions/command/DocsSubcommand.java @@ -12,8 +12,8 @@ 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; +import static net.minecraft.server.command.CommandManager.literal; public class DocsSubcommand { public static final LiteralArgumentBuilder DOCS = literal("docs") diff --git a/src/main/java/io/github/skippyall/minions/command/MinionsCommand.java b/src/main/java/io/github/skippyall/minions/command/MinionsCommand.java index b10e095..2823d68 100644 --- a/src/main/java/io/github/skippyall/minions/command/MinionsCommand.java +++ b/src/main/java/io/github/skippyall/minions/command/MinionsCommand.java @@ -14,7 +14,8 @@ public class MinionsCommand { LiteralArgumentBuilder builder = literal("minions") .then(SpawnSubcommand.SPAWN) .then(ListSubcommand.LIST) - .then(DocsSubcommand.DOCS); + .then(DocsSubcommand.DOCS) + .then(TestSubcommand.TEST); if(MinionsConfig.get().minion.enableMobCapHacks) { builder.then(MobCapDebugSubcommand.MOB_CAP_DEBUG); diff --git a/src/main/java/io/github/skippyall/minions/command/TestSubcommand.java b/src/main/java/io/github/skippyall/minions/command/TestSubcommand.java new file mode 100644 index 0000000..089b69a --- /dev/null +++ b/src/main/java/io/github/skippyall/minions/command/TestSubcommand.java @@ -0,0 +1,78 @@ +package io.github.skippyall.minions.command; + +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; +import io.github.skippyall.minions.Minions; +import net.minecraft.block.Blocks; +import net.minecraft.command.argument.BlockPosArgumentType; +import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.text.Text; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.world.World; + +import java.util.Collection; +import java.util.HashSet; + +import static net.minecraft.server.command.CommandManager.argument; +import static net.minecraft.server.command.CommandManager.literal; + +public class TestSubcommand { + public static LiteralArgumentBuilder TEST = literal("test") + .then(argument("pos", BlockPosArgumentType.blockPos()) + .executes(TestSubcommand::execute) + ); + + + private static int execute(CommandContext context) { + try { + BlockPos pos = BlockPosArgumentType.getBlockPos(context, "pos"); + Collection result = findInputs(context.getSource().getWorld(), pos); + for (BlockPos resultPos : result) { + context.getSource().sendFeedback(() -> Text.literal(resultPos.toShortString()), false); + } + } catch (Throwable e) { + Minions.LOGGER.error("Error", e); + } + return 0; + } + + private static Collection findInputs(World world, BlockPos pos) { + //positions that are already processed + Collection visitedPositions = new HashSet<>(); + //positions we are currently looking at + Collection currentPositions = new HashSet<>(); + //new positions are added here + Collection newPositions = new HashSet<>(); + //resulting machines + Collection machines = new HashSet<>(); + + currentPositions.add(pos); + + while(!currentPositions.isEmpty()) { + for(BlockPos currentPosition : currentPositions) { + for(Direction dir : Direction.values()) { + //check each neighbor of the current positions + BlockPos newPos = currentPosition.offset(dir); + //Do not check blocks that were already checked + if(!visitedPositions.contains(newPos)) { + if (world.getBlockState(newPos).getBlock() == Blocks.REDSTONE_BLOCK) { + //Add pipes to positions for the next iteration + newPositions.add(newPos); + } else if (world.getBlockState(newPos).getBlock() == Blocks.IRON_BLOCK) { + //Add machines to output set + machines.add(newPos); + } + //Add checked blocks here so that they are not checked again + visitedPositions.add(newPos); + } + } + } + //Check the new positions in the next iteration + currentPositions = newPositions; + newPositions = new HashSet<>(); + } + + return machines; + } +} diff --git a/src/main/java/io/github/skippyall/minions/docs/DocsEntry.java b/src/main/java/io/github/skippyall/minions/docs/DocsEntry.java index 9633186..31a4a75 100644 --- a/src/main/java/io/github/skippyall/minions/docs/DocsEntry.java +++ b/src/main/java/io/github/skippyall/minions/docs/DocsEntry.java @@ -6,7 +6,6 @@ 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; diff --git a/src/main/java/io/github/skippyall/minions/docs/DocsManager.java b/src/main/java/io/github/skippyall/minions/docs/DocsManager.java index 38698c0..ea7de95 100644 --- a/src/main/java/io/github/skippyall/minions/docs/DocsManager.java +++ b/src/main/java/io/github/skippyall/minions/docs/DocsManager.java @@ -8,7 +8,6 @@ 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; diff --git a/src/main/java/io/github/skippyall/minions/docs/ReferenceEntry.java b/src/main/java/io/github/skippyall/minions/docs/ReferenceEntry.java index 43b5687..2addd61 100644 --- a/src/main/java/io/github/skippyall/minions/docs/ReferenceEntry.java +++ b/src/main/java/io/github/skippyall/minions/docs/ReferenceEntry.java @@ -50,7 +50,7 @@ public record ReferenceEntry(Metadata metadata, RegistryKey object, Text shor 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)); + bodyElements.add(new PlainMessageDialogBody(longDescription, 200)); return bodyElements; } diff --git a/src/main/java/io/github/skippyall/minions/gui/GuiDisplay.java b/src/main/java/io/github/skippyall/minions/gui/GuiDisplay.java index 3a8ae6a..9328196 100644 --- a/src/main/java/io/github/skippyall/minions/gui/GuiDisplay.java +++ b/src/main/java/io/github/skippyall/minions/gui/GuiDisplay.java @@ -15,6 +15,7 @@ import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.registry.Registries; import net.minecraft.registry.Registry; import net.minecraft.text.Text; +import net.minecraft.util.Formatting; import net.minecraft.util.Identifier; import net.minecraft.util.Rarity; import net.minecraft.util.Uuids; @@ -46,7 +47,7 @@ public interface GuiDisplay { static ItemStack getDisplayStackWithName(Registry registry, T element, DynamicRegistryManager manager) { ItemStack stack = getDisplayStack(registry, element, manager); - stack.set(DataComponentTypes.ITEM_NAME, Text.translatable(TranslationUtil.getTranslationKey(element, registry))); + stack.set(DataComponentTypes.CUSTOM_NAME, Text.translatable(TranslationUtil.getTranslationKey(element, registry)).styled(style -> style.withItalic(false).withColor(Formatting.WHITE))); return stack; } diff --git a/src/main/java/io/github/skippyall/minions/gui/MinionBoundSimpleGui.java b/src/main/java/io/github/skippyall/minions/gui/MinionBoundSimpleGui.java deleted file mode 100644 index 7ea084b..0000000 --- a/src/main/java/io/github/skippyall/minions/gui/MinionBoundSimpleGui.java +++ /dev/null @@ -1,37 +0,0 @@ -package io.github.skippyall.minions.gui; - -import eu.pb4.sgui.api.gui.SimpleGui; -import io.github.skippyall.minions.minion.MinionListener; -import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; -import net.minecraft.screen.ScreenHandlerType; -import net.minecraft.server.network.ServerPlayerEntity; - -public class MinionBoundSimpleGui extends SimpleGui implements MinionListener { - protected final MinionFakePlayer minion; - - public MinionBoundSimpleGui(ScreenHandlerType type, ServerPlayerEntity player, MinionFakePlayer minion) { - super(type, player, false); - this.minion = minion; - minion.addMinionListener(this); - } - - public MinionFakePlayer getMinion() { - return minion; - } - - @Override - public void onMinionRemove(MinionFakePlayer minion) { - close(); - } - - @Override - public void onClose() { - minion.removeMinionListener(this); - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof MinionBoundSimpleGui that)) return false; - return minion == that.minion && player == that.player; - } -} diff --git a/src/main/java/io/github/skippyall/minions/gui/MinionLookGui.java b/src/main/java/io/github/skippyall/minions/gui/MinionLookGui.java index c4f5938..b16f338 100644 --- a/src/main/java/io/github/skippyall/minions/gui/MinionLookGui.java +++ b/src/main/java/io/github/skippyall/minions/gui/MinionLookGui.java @@ -2,12 +2,12 @@ package io.github.skippyall.minions.gui; import eu.pb4.sgui.api.elements.GuiElementBuilder; import eu.pb4.sgui.api.gui.SimpleGui; -import io.github.skippyall.minions.registration.MinionRegistries; import io.github.skippyall.minions.gui.input.TextInput; import io.github.skippyall.minions.minion.MinionData; import io.github.skippyall.minions.minion.MinionItem; import io.github.skippyall.minions.minion.MinionProfileUtils; import io.github.skippyall.minions.minion.skin.SkinProvider; +import io.github.skippyall.minions.registration.MinionRegistries; import io.github.skippyall.minions.registration.SkinProviders; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.ProfileComponent; diff --git a/src/main/java/io/github/skippyall/minions/gui/MinionsGui.java b/src/main/java/io/github/skippyall/minions/gui/MinionsGui.java index ebec233..08ecbf0 100644 --- a/src/main/java/io/github/skippyall/minions/gui/MinionsGui.java +++ b/src/main/java/io/github/skippyall/minions/gui/MinionsGui.java @@ -6,23 +6,25 @@ import org.jetbrains.annotations.Nullable; public abstract class MinionsGui { protected final @Nullable MinionsGui parent; protected final ServerPlayerEntity viewer; - private @Nullable MinionsGui child = null; + protected @Nullable MinionsGui child = null; private boolean open = true; public MinionsGui(MinionsGui parent) { this.viewer = parent.viewer; this.parent = parent; parent.child = this; - open(); } public MinionsGui(ServerPlayerEntity viewer) { this.viewer = viewer; this.parent = null; - open(); } - protected void open() {} + public ServerPlayerEntity getViewer() { + return viewer; + } + + protected abstract void open(); protected void reopen() { open(); @@ -38,17 +40,26 @@ public abstract class MinionsGui { public void close() { if(open) { - if(child != null) { - child.close(); - } if(parent != null) { parent.child = null; parent.reopen(); } - onClose(); - open = false; + closeNoOpen(parent == null); } } - protected void onClose() {} + private void closeNoOpen(boolean closeBacking) { + if(child != null) { + child.closeNoOpen(closeBacking); + } + if(parent != null) { + parent.child = null; + } + if(closeBacking) { + closeBacking(); + } + open = false; + } + + protected abstract void closeBacking(); } diff --git a/src/main/java/io/github/skippyall/minions/gui/PaginatedList.java b/src/main/java/io/github/skippyall/minions/gui/PaginatedList.java index 2dde6ef..3fd3af3 100644 --- a/src/main/java/io/github/skippyall/minions/gui/PaginatedList.java +++ b/src/main/java/io/github/skippyall/minions/gui/PaginatedList.java @@ -1,55 +1,79 @@ package io.github.skippyall.minions.gui; import eu.pb4.sgui.api.elements.GuiElementBuilder; -import eu.pb4.sgui.api.gui.SlotGuiInterface; -import io.github.skippyall.minions.gui.minion.MinionGui; +import eu.pb4.sgui.api.gui.SimpleGui; import net.minecraft.item.Items; +import net.minecraft.screen.ScreenHandlerType; import net.minecraft.text.Text; import net.minecraft.util.collection.IndexedIterable; import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Function; +import java.util.function.BiFunction; -public class PaginatedList { - public static void createList(SlotGuiInterface gui, int size, Function display, Runnable onBack) { - AtomicInteger page = new AtomicInteger(0); - addItems(page, gui, size, display); +public class PaginatedList extends MinionsGui { + private int page = 0; + private SimpleGui gui; + private final Text title; + private final int size; + private final BiFunction display; - gui.setSlot(27, MinionGui.backButton(onBack)); + public PaginatedList(MinionsGui parent, Text title, int size, BiFunction display) { + super(parent); + this.title = title; + this.size = size; + this.display = display; + open(); } - public static void createList(SlotGuiInterface gui, List list, Function display, Runnable onBack) { - createList(gui, list.size(), i -> display.apply(list.get(i)), onBack); + @Override + protected void open() { + gui = new SimpleGui(ScreenHandlerType.GENERIC_9X4, viewer, false) { + @Override + public void onClose() { + onBackingClosed(); + } + }; + gui.setTitle(title); + addItems(); + gui.open(); } - public static void createList(SlotGuiInterface gui, IndexedIterable list, Function display, Runnable onBack) { - createList(gui, list.size(), i -> display.apply(list.get(i)), onBack); + @Override + protected void closeBacking() { + gui.close(); } - private static void addItems(AtomicInteger page, SlotGuiInterface gui, int size, Function display) { - for(int i = 27 * page.get(); i < Math.min(27 * (page.get() + 1), size); i++) { - gui.addSlot(display.apply(i)); + public static void createList(MinionsGui parent, Text title, List list, BiFunction display) { + new PaginatedList(parent, title, list.size(), (i, gui) -> display.apply(list.get(i), gui)); + } + + public static void createList(MinionsGui parent, Text title, IndexedIterable list, BiFunction display) { + new PaginatedList(parent, title, list.size(), (i, gui) -> display.apply(list.get(i), gui)); + } + + private void addItems() { + for(int i = 27 * page; i < Math.min(27 * (page + 1), size); i++) { + gui.addSlot(display.apply(i, this)); } - if(page.get() > 0) { + if(page > 0) { gui.setSlot(30, new GuiElementBuilder(Items.SPECTRAL_ARROW) .setItemName(Text.translatable("book.page_button.previous")) .setCallback(() -> { - page.decrementAndGet(); - addItems(page, gui, size, display); + page--; + addItems(); }) ); } else { gui.clearSlot(30); } - if(27 * (page.get() + 1) < size) { + if(27 * (page + 1) < size) { gui.setSlot(32, new GuiElementBuilder(Items.ARROW) .setItemName(Text.translatable("book.page_button.next")) .setCallback(() -> { - page.incrementAndGet(); - addItems(page, gui, size, display); + page++; + addItems(); }) ); } else { diff --git a/src/main/java/io/github/skippyall/minions/gui/input/ChoiceInput.java b/src/main/java/io/github/skippyall/minions/gui/input/ChoiceInput.java index 0e6ba7d..2c9df98 100644 --- a/src/main/java/io/github/skippyall/minions/gui/input/ChoiceInput.java +++ b/src/main/java/io/github/skippyall/minions/gui/input/ChoiceInput.java @@ -4,6 +4,8 @@ import eu.pb4.sgui.api.elements.GuiElementBuilder; import eu.pb4.sgui.api.gui.SimpleGui; import io.github.skippyall.minions.gui.Displayable; import io.github.skippyall.minions.gui.GuiDisplay; +import io.github.skippyall.minions.gui.MinionsGui; +import io.github.skippyall.minions.gui.minion.SimpleMinionsGui; import net.minecraft.item.Items; import net.minecraft.screen.ScreenHandlerType; import net.minecraft.server.network.ServerPlayerEntity; @@ -72,6 +74,36 @@ public class ChoiceInput { return future; } + public static CompletableFuture confirm(MinionsGui parent, Text title) { + CompletableFuture future = new CompletableFuture<>(); + + new SimpleMinionsGui(parent, (onClose, me) -> { + SimpleGui gui = new SimpleGui(ScreenHandlerType.GENERIC_3X3, parent.getViewer(), false) { + @Override + public void onClose() { + future.cancel(false); + onClose.run(); + } + }; + + gui.setTitle(title); + + gui.setSlot(3, new GuiElementBuilder(Items.REDSTONE_BLOCK) + .setName(Text.translatable("minions.gui.abort")) + .setCallback(() -> future.cancel(false)) + ); + + gui.setSlot(5, new GuiElementBuilder(Items.EMERALD_BLOCK) + .setName(Text.translatable("minions.gui.confirm")) + .setCallback(() -> future.complete(null)) + ); + + gui.open(); + return gui; + }); + return future; + } + public static BiFunction> inputBoolean(Text title) { return createDialogOpener(ScreenHandlerType.GENERIC_3X3, title, value -> { if(value) { diff --git a/src/main/java/io/github/skippyall/minions/gui/input/Result.java b/src/main/java/io/github/skippyall/minions/gui/input/Result.java index 8dd4e9b..f0ffdec 100644 --- a/src/main/java/io/github/skippyall/minions/gui/input/Result.java +++ b/src/main/java/io/github/skippyall/minions/gui/input/Result.java @@ -1,10 +1,12 @@ package io.github.skippyall.minions.gui.input; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Optional; import java.util.function.Consumer; import java.util.function.Function; +import java.util.function.Supplier; public interface Result { static Result wrap(UnsafeOperation toWrap) { @@ -23,6 +25,22 @@ public interface Result { } } + static Result ofNullable(@Nullable T value, E error) { + if(value != null) { + return new Success<>(value); + } else { + return new Error<>(error); + } + } + + static Result ofNullable(@Nullable T value, Supplier error) { + if(value != null) { + return new Success<>(value); + } else { + return new Error<>(error.get()); + } + } + boolean isSuccess(); T getOrDefault(T defaultValue); @@ -33,10 +51,18 @@ public interface Result { @NotNull Optional getOptional(); + @NotNull Optional getOptionalError(); + void ifSuccess(@NotNull Consumer handler); void ifError(@NotNull Consumer> handler); + Result map(Function mapper); + + Result flatMap(Function> mapper); + + Result mapError(Function mapper); + record Success(T result) implements Result { @Override public boolean isSuccess() { @@ -48,6 +74,11 @@ public interface Result { return result; } + @Override + public @NotNull Optional getOptionalError() { + return Optional.empty(); + } + @Override public T getOrThrow() { return result; @@ -60,7 +91,7 @@ public interface Result { @Override public @NotNull Optional getOptional() { - return Optional.of(result); + return Optional.ofNullable(result); } @Override @@ -72,6 +103,21 @@ public interface Result { public void ifError(@NotNull Consumer> handler) { } + + @Override + public Result map(Function mapper) { + return new Success<>(mapper.apply(result)); + } + + @Override + public Result flatMap(Function> mapper) { + return mapper.apply(result); + } + + @Override + public Result mapError(Function mapper) { + return new Success<>(result); + } } record Error(E message) implements Result { @@ -101,6 +147,11 @@ public interface Result { return Optional.empty(); } + @Override + public @NotNull Optional getOptionalError() { + return Optional.ofNullable(message); + } + @Override public void ifSuccess(@NotNull Consumer handler) { @@ -110,6 +161,21 @@ public interface Result { public void ifError(@NotNull Consumer> handler) { handler.accept(this); } + + @Override + public Result map(Function mapper) { + return new Error<>(message); + } + + @Override + public Result flatMap(Function> mapper) { + return new Error<>(message); + } + + @Override + public Result mapError(Function mapper) { + return new Error<>(mapper.apply(message)); + } } interface UnsafeOperation { diff --git a/src/main/java/io/github/skippyall/minions/gui/input/TextInput.java b/src/main/java/io/github/skippyall/minions/gui/input/TextInput.java index 9add272..bde1964 100644 --- a/src/main/java/io/github/skippyall/minions/gui/input/TextInput.java +++ b/src/main/java/io/github/skippyall/minions/gui/input/TextInput.java @@ -2,6 +2,8 @@ package io.github.skippyall.minions.gui.input; import eu.pb4.sgui.api.elements.GuiElementBuilder; import eu.pb4.sgui.api.gui.AnvilInputGui; +import io.github.skippyall.minions.gui.MinionsGui; +import io.github.skippyall.minions.gui.minion.SimpleMinionsGui; import net.minecraft.item.Items; import net.minecraft.screen.AnvilScreenHandler; import net.minecraft.server.network.ServerPlayerEntity; @@ -37,24 +39,54 @@ public class TextInput extends AnvilInputGui { return input(player, title, defaultValue, (String string) -> CompletableFuture.completedFuture(parser.apply(string))); } + public static CompletableFuture inputSync(MinionsGui gui, Text title, String defaultValue, Function> parser) { + return input(gui, title, defaultValue, (String string) -> CompletableFuture.completedFuture(parser.apply(string))); + } + public static CompletableFuture input(ServerPlayerEntity player, Text title, String defaultValue, Function>> parser) { CompletableFuture future = new CompletableFuture<>(); new TextInput<>(player, title, defaultValue, parser, future).open(); return future; } + public static CompletableFuture input(MinionsGui gui, Text title, String defaultValue, Function>> parser) { + CompletableFuture future = new CompletableFuture<>(); + new SimpleMinionsGui(gui, (onClose, me) -> { + TextInput input = new TextInput<>(gui.getViewer(), title, defaultValue, parser, future); + future.handle((v, e) -> { + onClose.run(); + return null; + }); + input.open(); + return input; + }); + return future; + } + public static CompletableFuture inputString(ServerPlayerEntity player, Text title, String defaultValue) { return inputSync(player, title, defaultValue, Result.Success::new); } + public static CompletableFuture inputString(MinionsGui gui, Text title, String defaultValue) { + return inputSync(gui, title, defaultValue, Result.Success::new); + } + public static CompletableFuture inputLong(ServerPlayerEntity player, Text title, String defaultValue) { return inputSync(player, title, defaultValue, string -> Result.wrapCustomError(() -> Long.valueOf(string), Text.translatable("minions.command.input.int.fail"))); } + public static CompletableFuture inputLong(MinionsGui gui, Text title, String defaultValue) { + return inputSync(gui, title, defaultValue, string -> Result.wrapCustomError(() -> Long.valueOf(string), Text.translatable("minions.command.input.int.fail"))); + } + public static CompletableFuture inputDouble(ServerPlayerEntity player, Text title, String defaultValue) { return inputSync(player, title, defaultValue, string -> Result.wrapCustomError(() -> Double.valueOf(string), Text.translatable("minions.command.input.float.fail"))); } + public static CompletableFuture inputDouble(MinionsGui gui, Text title, String defaultValue) { + return inputSync(gui, title, defaultValue, string -> Result.wrapCustomError(() -> Double.valueOf(string), Text.translatable("minions.command.input.float.fail"))); + } + @Override public void onInput(String input) { updateConfirmButton(input); diff --git a/src/main/java/io/github/skippyall/minions/gui/instruction/ArgumentGui.java b/src/main/java/io/github/skippyall/minions/gui/instruction/ArgumentGui.java index 7a03fb5..8e91d55 100644 --- a/src/main/java/io/github/skippyall/minions/gui/instruction/ArgumentGui.java +++ b/src/main/java/io/github/skippyall/minions/gui/instruction/ArgumentGui.java @@ -3,79 +3,160 @@ package io.github.skippyall.minions.gui.instruction; import eu.pb4.sgui.api.elements.GuiElementBuilder; import eu.pb4.sgui.api.gui.SimpleGui; import io.github.skippyall.minions.gui.GuiDisplay; +import io.github.skippyall.minions.gui.MinionsGui; +import io.github.skippyall.minions.gui.PaginatedList; +import io.github.skippyall.minions.gui.minion.GuiContext; import io.github.skippyall.minions.minion.MinionRuntime; import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; import io.github.skippyall.minions.program.instruction.ConfiguredInstruction; import io.github.skippyall.minions.program.supplier.Parameter; import io.github.skippyall.minions.program.supplier.ValueSupplier; +import io.github.skippyall.minions.program.supplier.ValueSupplierList; import io.github.skippyall.minions.program.supplier.ValueSupplierType; import io.github.skippyall.minions.registration.MinionRegistries; import io.github.skippyall.minions.util.TranslationUtil; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.screen.ScreenHandlerType; -import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; import org.jetbrains.annotations.Nullable; -import java.util.concurrent.CompletableFuture; +public class ArgumentGui extends MinionsGui { + private final GuiContext.ValueSupplier context; + private final MinionFakePlayer minion; + private final ConfiguredInstruction instruction; + private final Parameter parameter; -public class ArgumentGui { - public static > void configureArgumentMenu(String instructionName, ConfiguredInstruction instruction, Parameter parameter, MinionFakePlayer minion, ServerPlayerEntity player) { - if (!InstructionGui.checkInstructionExists(instructionName, instruction, minion, player)) { - return; + private SimpleGui gui; + + private @Nullable ValueSupplierType argumentType; + private @Nullable ValueSupplierList.ValueSupplierEntry entry; + + public ArgumentGui(MinionsGui parent, GuiContext.ValueSupplier context) { + super(parent); + minion = context.getMinion(); + instruction = context.getInstruction(); + this.parameter = context.getParameter(); + this.context = context; + + this.entry = instruction.getArguments().getEntry(parameter); + if(entry != null) { + this.argumentType = entry.getSupplier().getType(); } - - @Nullable ValueSupplier argument = instruction.getArguments().getArgument(parameter); - - if(argument == null) { - configureTypeAndValue(instructionName, instruction, parameter, minion, player); - return; - } - - configureArgumentHelper(instructionName, instruction, parameter, argument, minion, player); + open(); } - private static void configureArgumentHelper(String instructionName, ConfiguredInstruction instruction, Parameter parameter, ValueSupplier argument, MinionFakePlayer minion, ServerPlayerEntity player) { - SimpleGui gui = new InstructionBoundSimpleGui(ScreenHandlerType.GENERIC_3X3, player, minion, instruction); + public String getInstructionName() { + return context.getName(); + } - ItemStack displayStack = GuiDisplay.getDisplayStack(MinionRegistries.VALUE_SUPPLIER_TYPES, argument.getType(), player.getRegistryManager()); + public @Nullable ValueSupplier getArgument() { + if(entry != null) { + return entry.getSupplier(); + } + return null; + } + + @Override + protected void open() { + gui = new SimpleGui(ScreenHandlerType.GENERIC_3X3, viewer, false) { + @Override + public void onClose() { + onBackingClosed(); + } + }; + gui.setTitle(Text.translatable( + "minions.gui.instruction.argument.title", + parameter.name(), + Text.translatable(TranslationUtil.getTranslationKey(parameter.type(), MinionRegistries.VALUE_TYPES)) + )); + + updateTypeConfiguration(); + updateArgumentConfiguration(); + updateConverterConfiguration(); + gui.open(); + } + + private void updateTypeConfiguration() { + ItemStack displayStack; + if(argumentType != null) { + displayStack = GuiDisplay.getDisplayStack(MinionRegistries.VALUE_SUPPLIER_TYPES, argumentType, viewer.getRegistryManager()); + } else { + displayStack = new ItemStack(Items.BARRIER); + } gui.setSlot(3, new GuiElementBuilder(displayStack) - .setName(Text.translatable("minions.gui.instruction.argument.configure.type", Text.translatable(TranslationUtil.getTranslationKey(argument.getType(), MinionRegistries.VALUE_SUPPLIER_TYPES, "minions.gui.instruction.argument.configure.type.unset")))) - .setCallback(() -> configureTypeAndValue(instructionName, instruction, parameter, minion, player)) + .setName(Text.translatable("minions.gui.instruction.argument.configure.type")) + .addLoreLine(Text.translatable(TranslationUtil.getTranslationKey( + argumentType, + MinionRegistries.VALUE_SUPPLIER_TYPES, + "minions.gui.not_set" + ))) + .setCallback(this::selectArgumentType) ); - gui.setSlot(5, new GuiElementBuilder(Items.STRUCTURE_VOID) - .setName(Text.literal("Configure")) - .setCallback(() -> argument.getType().openConfiguration(player, argument.getValueType(), argument) - .thenAccept(newArgument -> { - instruction.getArguments().setArgument(parameter, newArgument); - configureArgumentMenu(instructionName, instruction, parameter, minion, player); - }) - ) - ); - gui.open(); } - public static CompletableFuture> selectArgumentType(ServerPlayerEntity player, MinionFakePlayer minion, ConfiguredInstruction instruction) { - CompletableFuture> future = new CompletableFuture<>(); - SimpleGui gui = new InstructionBoundSimpleGui(ScreenHandlerType.GENERIC_9X3, player, minion, instruction); - for (ValueSupplierType type : MinionRegistries.VALUE_SUPPLIER_TYPES) { - gui.addSlot(new GuiElementBuilder(GuiDisplay.getDisplayStackWithName(MinionRegistries.VALUE_SUPPLIER_TYPES, type, player.getRegistryManager())) - .setCallback(() -> future.complete(type)) + private void updateArgumentConfiguration() { + if(argumentType != null) { + gui.setSlot(4, new GuiElementBuilder(Items.STRUCTURE_VOID) + .setName(Text.translatable("minions.gui.instruction.argument.configure.data")) + .addLoreLine(getArgument() != null ? getArgument().getDisplayText() : Text.translatable("minions.gui.not_set")) + .setCallback(() -> argumentType.openConfiguration(this, parameter.type(), getArgument()) + .thenAccept(newArgument -> { + setArgument(newArgument); + if(child != null) { + child.close(); + } + }) + ) ); } - gui.open(); - return future; } - public static void configureTypeAndValue(String name, ConfiguredInstruction instruction, Parameter parameter, MinionFakePlayer minion, ServerPlayerEntity player) { - selectArgumentType(player, minion, instruction) - .thenApply(type -> type.openConfiguration(player, parameter.type(), null) - .thenAccept(v -> { - instruction.getArguments().setArgument(parameter, v); - configureArgumentMenu(name, instruction, parameter, minion, player); + private void updateConverterConfiguration() { + if(entry != null) { + gui.setSlot(5, new GuiElementBuilder(Items.CRAFTER) + .setName(Text.translatable("minions.gui.instruction.converters")) + .setCallback(this::configureConvertersMenu) + ); + } + } + + @Override + protected void closeBacking() { + gui.close(); + } + + public void setArgumentType(ValueSupplierType type) { + this.argumentType = type; + if(entry != null && getArgument().getType() != argumentType) { + instruction.getArguments().removeEntry(parameter); + entry = null; + } + updateTypeConfiguration(); + } + + public void setArgument(ValueSupplier argument) { + if(entry != null) { + entry.setSupplier(argument); + } else { + entry = instruction.getArguments().createEntry(parameter, argument); + } + } + + public void selectArgumentType() { + PaginatedList.createList(this, Text.translatable("minions.gui.instruction.argument.configure.type.title"), MinionRegistries.VALUE_SUPPLIER_TYPES, (type, me) -> + new GuiElementBuilder(GuiDisplay.getDisplayStackWithName(MinionRegistries.VALUE_SUPPLIER_TYPES, type, viewer.getRegistryManager())) + .setCallback(() -> { + setArgumentType(type); + me.close(); }) - ); + ); + } + + public void configureConvertersMenu() { + if(entry != null) { + new ConverterListGui(this, entry.getConverters(), entry.getSupplier().getValueType(), entry.getParameter().type()); + } } } diff --git a/src/main/java/io/github/skippyall/minions/gui/instruction/ConfigureInstructionGui.java b/src/main/java/io/github/skippyall/minions/gui/instruction/ConfigureInstructionGui.java index 5d1d78a..4d502b9 100644 --- a/src/main/java/io/github/skippyall/minions/gui/instruction/ConfigureInstructionGui.java +++ b/src/main/java/io/github/skippyall/minions/gui/instruction/ConfigureInstructionGui.java @@ -1,78 +1,100 @@ package io.github.skippyall.minions.gui.instruction; import eu.pb4.sgui.api.elements.GuiElementBuilder; +import eu.pb4.sgui.api.gui.SimpleGui; +import io.github.skippyall.minions.clipboard.ClipboardItem; +import io.github.skippyall.minions.gui.MinionsGui; import io.github.skippyall.minions.gui.input.ChoiceInput; +import io.github.skippyall.minions.gui.minion.GuiContext; +import io.github.skippyall.minions.minion.MinionListener; import io.github.skippyall.minions.minion.MinionRuntime; import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; import io.github.skippyall.minions.program.instruction.ConfiguredInstruction; +import io.github.skippyall.minions.program.instruction.ConfiguredInstructionListener; import io.github.skippyall.minions.program.supplier.Parameter; -import io.github.skippyall.minions.clipboard.ClipboardItem; import net.minecraft.item.Items; import net.minecraft.screen.ScreenHandlerType; -import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundEvents; import net.minecraft.text.Text; -public class ConfigureInstructionGui extends InstructionBoundSimpleGui { +public class ConfigureInstructionGui extends MinionsGui implements ConfiguredInstructionListener, MinionListener { private String name; + private final ConfiguredInstruction instruction; + private final MinionFakePlayer minion; - private ConfigureInstructionGui(ScreenHandlerType type, ServerPlayerEntity player, MinionFakePlayer minion, ConfiguredInstruction configuredInstruction, String name) { - super(type, player, minion, configuredInstruction); - this.name = name; - init(); - } - - public static void configureInstructionMenu(String name, ConfiguredInstruction instruction, MinionFakePlayer minion, ServerPlayerEntity player) { - if(!InstructionGui.checkInstructionExists(name, instruction, minion, player)) { - return; - } - - ConfigureInstructionGui gui = new ConfigureInstructionGui(ScreenHandlerType.GENERIC_9X3, player, minion, instruction, name); - - gui.open(); - } + private final GuiContext.Instruction context; - private void init() { - setTitle(Text.literal(name)); + private SimpleGui gui; + + public ConfigureInstructionGui(MinionsGui parent, GuiContext.Instruction context) { + super(parent); + this.name = context.getName(); + this.instruction = context.getInstruction(); + this.minion = context.getMinion(); + this.context = context; + minion.addMinionListener(this); + instruction.addListener(this); + open(); + } - setSlot(7, new GuiElementBuilder(Items.ANVIL) + @Override + protected void open() { + gui = new SimpleGui(ScreenHandlerType.GENERIC_9X3, viewer, false) { + @Override + public void onClose() { + onBackingClosed(); + } + }; + + gui.setTitle(Text.literal(name)); + + gui.setSlot(7, new GuiElementBuilder(Items.ANVIL) .setName(Text.translatable("minions.gui.instruction.configure.rename")) - .setCallback(() -> InstructionGui.inputInstructionName(minion, player, name).thenAccept(newName -> { + .setCallback(() -> InstructionGui.inputInstructionName(this, context, name).thenAccept(newName -> { minion.getInstructionManager().setInstructionName(name, newName); - configureInstructionMenu(newName, instruction, minion, player); + reopen(); })) ); - setSlot(8, new GuiElementBuilder(Items.LAVA_BUCKET) + gui.setSlot(8, new GuiElementBuilder(Items.LAVA_BUCKET) .setName(Text.translatable("minions.gui.instruction.configure.delete")) - .setCallback(() -> ChoiceInput.confirm(player, Text.translatable("minions.gui.instruction.configure.delete.confirm", name)) + .setCallback(() -> ChoiceInput.confirm(this, Text.translatable("minions.gui.instruction.configure.delete.confirm", name)) .thenAccept(v -> { minion.getInstructionManager().removeInstruction(name); - InstructionGui.instructionList(minion, player); + close(); })) ); updateSuppliers(); - setSlot(13, InstructionGui.createInstructionElement(instruction.getInstruction(), player.getRegistryManager())); + gui.setSlot(13, InstructionGui.createInstructionElement(instruction.getInstruction(), viewer.getRegistryManager())); - setSlot(25, new GuiElementBuilder(Items.FEATHER) + gui.setSlot(25, new GuiElementBuilder(Items.FEATHER) .setName(Text.translatable("minions.gui.instruction.configure.copy")) .addLoreLine(Text.translatable("minions.gui.instruction.configure.copy.description")) .setCallback(() -> { - player.getInventory().offer(ClipboardItem.createInstructionReference(minion, name), true); - player.playSoundToPlayer(SoundEvents.BLOCK_NOTE_BLOCK_CHIME.value(), SoundCategory.BLOCKS, 1, 1); + viewer.getInventory().offer(ClipboardItem.createInstructionReference(minion, name), true); + viewer.playSoundToPlayer(SoundEvents.BLOCK_NOTE_BLOCK_CHIME.value(), SoundCategory.BLOCKS, 1, 1); }) ); updateRunSlot(); + gui.open(); + } + + @Override + protected void closeBacking() { + gui.close(); + minion.removeMinionListener(this); + instruction.removeListener(this); } @Override public void onInstructionRename(MinionFakePlayer minion, ConfiguredInstruction instruction, String oldName, String newName) { - this.setTitle(Text.literal(newName)); + gui.setTitle(Text.literal(newName)); name = newName; + context.setName(newName); } @Override @@ -92,12 +114,12 @@ public class ConfigureInstructionGui extends InstructionBoundSimpleGui { private void updateRunSlot() { if(!instruction.isRunning()) { - setSlot(26, new GuiElementBuilder(Items.ARROW) + gui.setSlot(26, new GuiElementBuilder(Items.ARROW) .setName(Text.translatable("minions.gui.instruction.run")) .setCallback(() -> instruction.run(minion.getInstructionManager())) ); } else { - setSlot(26, new GuiElementBuilder(Items.BARRIER) + gui.setSlot(26, new GuiElementBuilder(Items.BARRIER) .setName(Text.translatable("minions.gui.instruction.stop")) .setCallback(() -> instruction.stop(minion.getInstructionManager())) ); @@ -107,8 +129,8 @@ public class ConfigureInstructionGui extends InstructionBoundSimpleGui { private void updateSuppliers() { int slot = 12; for(Parameter parameter : instruction.getInstruction().getParameters().reversed()) { - setSlot(slot, InstructionGui.createParameterElement(parameter, instruction.getArguments().getArgument(parameter), player.getRegistryManager()) - .setCallback(() -> ArgumentGui.configureArgumentMenu(name, instruction, parameter, minion, player)) + gui.setSlot(slot, InstructionGui.createParameterElement(parameter, instruction.getArguments().getArgument(parameter), viewer.getRegistryManager()) + .setCallback(() -> new ArgumentGui(this, GuiContext.ValueSupplier.create(context, parameter))) ); slot--; } diff --git a/src/main/java/io/github/skippyall/minions/gui/instruction/ConverterGui.java b/src/main/java/io/github/skippyall/minions/gui/instruction/ConverterGui.java index d90e63b..8cfccac 100644 --- a/src/main/java/io/github/skippyall/minions/gui/instruction/ConverterGui.java +++ b/src/main/java/io/github/skippyall/minions/gui/instruction/ConverterGui.java @@ -1,71 +1,131 @@ package io.github.skippyall.minions.gui.instruction; import eu.pb4.sgui.api.elements.GuiElementBuilder; +import eu.pb4.sgui.api.gui.SimpleGui; import io.github.skippyall.minions.gui.GuiDisplay; +import io.github.skippyall.minions.gui.MinionsGui; import io.github.skippyall.minions.gui.PaginatedList; -import io.github.skippyall.minions.minion.MinionRuntime; -import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; +import io.github.skippyall.minions.program.conversion.ConverterList; import io.github.skippyall.minions.program.conversion.ValueConverter; import io.github.skippyall.minions.program.conversion.ValueConverterType; -import io.github.skippyall.minions.program.instruction.ConfiguredInstruction; -import io.github.skippyall.minions.program.supplier.Parameter; -import io.github.skippyall.minions.program.supplier.ValueSupplierList; import io.github.skippyall.minions.program.value.ValueType; import io.github.skippyall.minions.registration.MinionRegistries; import net.minecraft.item.Items; import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.screen.ScreenHandlerType; -import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.Text; import org.jetbrains.annotations.Nullable; -public class ConverterGui { - public static void configureConvertersMenu(ServerPlayerEntity player, MinionFakePlayer minion, ConfiguredInstruction instruction, Parameter parameter, Runnable back) { - InstructionBoundSimpleGui gui = new InstructionBoundSimpleGui(ScreenHandlerType.GENERIC_9X4, player, minion, instruction); +public class ConverterGui extends MinionsGui { + private @Nullable ValueConverterType valueConverterType; + private @Nullable ValueConverter converter; + private ConverterList list; + private ValueType from, to; + + private SimpleGui gui; + private boolean isNew; + private int index; + + public ConverterGui(MinionsGui parent, @Nullable ValueConverter converter, ValueType from, ValueType to, ConverterList list, boolean isNew, int index) { + super(parent); + open(); + this.converter = converter; + if(converter != null) { + this.valueConverterType = converter.getType(); + } + this.from = from; + this.to = to; + this.list = list; + this.isNew = isNew; + this.index = index; + } + + @Override + protected void open() { + gui = new SimpleGui(ScreenHandlerType.GENERIC_3X3, viewer, false) { + @Override + public void onClose() { + onBackingClosed(); + } + }; + + gui.setTitle(Text.translatable("minions.gui.instruction.converter.title")); + + updateTypeDisplay(); + updateConverterDisplay(); - ValueSupplierList.ValueSupplierEntry entry = instruction.getArguments().getEntry(parameter); - PaginatedList.createList( - gui, - entry.getConverters(), - converter -> createConverterElement(converter, player.getRegistryManager()) - .setCallback(() -> configureConverter(player, minion, instruction, parameter, entry, converter)), - back - ); gui.open(); } + @Override + protected void reopen() { + gui.open(); + } + + private void updateTypeDisplay() { + gui.setSlot(3, new GuiElementBuilder(GuiDisplay.getDisplayStackWithName(MinionRegistries.VALUE_CONVERTER_TYPES, valueConverterType, viewer.getRegistryManager())) + .setCallback(this::configureType) + ); + } + + private void updateConverterDisplay() { + gui.setSlot(5, new GuiElementBuilder(Items.STRUCTURE_VOID) + .setName(Text.translatable("minions.gui.instruction.converter.title")) + .addLoreLine(converter == null ? Text.translatable("minions.gui.not_set") : converter.getDisplayText()) + .setCallback(this::configureData) + ); + } + + @Override + protected void closeBacking() { + gui.close(); + } + + private void setType(ValueConverterType valueConverterType) { + this.valueConverterType = valueConverterType; + updateTypeDisplay(); + } + + public void setConverter(ValueConverter converter) { + this.converter = converter; + if(isNew) { + list.getConverters().add(index, converter); + isNew = false; + } else { + list.getConverters().set(index, converter); + } + updateConverterDisplay(); + } + + private void configureType() { + PaginatedList.createList( + this, + Text.translatable("minions.gui.instruction.converter.type.title"), + MinionRegistries.VALUE_CONVERTER_TYPES, + (type, me) -> new GuiElementBuilder( + GuiDisplay.getDisplayStackWithName(MinionRegistries.VALUE_CONVERTER_TYPES, type, viewer.getRegistryManager()) + ).setCallback(() -> { + setType(type); + me.close(); + }) + ); + } + + private void configureData() { + if(valueConverterType != null) { + valueConverterType.configure(this, from, to, converter) + .thenAccept(newConverter -> { + setConverter(newConverter); + if(child != null) { + child.close(); + } + }); + } + } + public static GuiElementBuilder createConverterElement(ValueConverter converter, DynamicRegistryManager manager) { GuiElementBuilder builder = new GuiElementBuilder(GuiDisplay.getDisplayStack(MinionRegistries.VALUE_CONVERTER_TYPES, converter.getType(), manager)); builder.addLoreLine(converter.getDisplayText()); return builder; } - - public static void configureConverter(ServerPlayerEntity player, MinionFakePlayer minion, ConfiguredInstruction instruction, Parameter parameter, ValueSupplierList.ValueSupplierEntry entry, @Nullable ValueConverter converter) { - InstructionBoundSimpleGui gui = new InstructionBoundSimpleGui(ScreenHandlerType.GENERIC_3X3, player, minion, instruction); - gui.setSlot(3, new GuiElementBuilder(GuiDisplay.getDisplayStackWithName(MinionRegistries.VALUE_CONVERTER_TYPES, converter.getType(), player.getRegistryManager())) - .setCallback(() -> { - InstructionBoundSimpleGui chooseTypeGui = new InstructionBoundSimpleGui(ScreenHandlerType.GENERIC_9X4, player, minion, instruction); - PaginatedList.createList( - chooseTypeGui, - MinionRegistries.VALUE_CONVERTER_TYPES, - type -> new GuiElementBuilder(GuiDisplay.getDisplayStackWithName(MinionRegistries.VALUE_CONVERTER_TYPES, type, player.getRegistryManager())) - .setCallback(() -> { - entry.set - }), - () -> configureConverter(player, minion, instruction, parameter, entry, converter) - ); - })); - - gui.setSlot(5, new GuiElementBuilder(Items.STRUCTURE_VOID)); - - gui.open(); - } - - public static void selectConverterMenu(ValueType from, ValueType to, ServerPlayerEntity player, MinionFakePlayer minion, ConfiguredInstruction instruction) { - InstructionBoundSimpleGui gui = new InstructionBoundSimpleGui(ScreenHandlerType.GENERIC_9X3, player, minion, instruction); - for(ValueConverterType valueConverterType : MinionRegistries.VALUE_CONVERTER_TYPES) { - gui.addSlot(new GuiElementBuilder(GuiDisplay.getDisplayStackWithName(MinionRegistries.VALUE_CONVERTER_TYPES, valueConverterType, player.getRegistryManager())) - .setCallback(() -> valueConverterType.configure(player, from, to, null).thenAccept(c -> ))); - } - gui.open(); - } } diff --git a/src/main/java/io/github/skippyall/minions/gui/instruction/ConverterListGui.java b/src/main/java/io/github/skippyall/minions/gui/instruction/ConverterListGui.java new file mode 100644 index 0000000..9be8480 --- /dev/null +++ b/src/main/java/io/github/skippyall/minions/gui/instruction/ConverterListGui.java @@ -0,0 +1,109 @@ +package io.github.skippyall.minions.gui.instruction; + +import eu.pb4.sgui.api.elements.GuiElementBuilder; +import eu.pb4.sgui.api.gui.SimpleGui; +import io.github.skippyall.minions.gui.GuiDisplay; +import io.github.skippyall.minions.gui.MinionsGui; +import io.github.skippyall.minions.program.conversion.ConverterList; +import io.github.skippyall.minions.program.conversion.ValueConverter; +import io.github.skippyall.minions.program.value.ValueType; +import io.github.skippyall.minions.registration.MinionRegistries; +import io.github.skippyall.minions.util.TranslationUtil; +import net.minecraft.item.Items; +import net.minecraft.screen.ScreenHandlerType; +import net.minecraft.text.Text; + +public class ConverterListGui extends MinionsGui { + private ConverterList converters; + + private SimpleGui gui; + private int page = 0; + + private ValueType inputType; + private ValueType outputType; + + public ConverterListGui(MinionsGui parent, ConverterList converters, ValueType inputType, ValueType outputType) { + super(parent); + this.converters = converters; + this.inputType = inputType; + this.outputType = outputType; + open(); + } + + @Override + protected void open() { + gui = new SimpleGui(ScreenHandlerType.GENERIC_9X3, viewer, false) { + @Override + public void onClose() { + onBackingClosed(); + } + }; + + gui.setTitle(Text.translatable("minions.gui.instruction.converters")); + + updateConverters(); + + gui.setSlot(21, new GuiElementBuilder(Items.SPECTRAL_ARROW) + .setCallback(() -> { + if(page > 0) { + page--; + updateConverters(); + } + }) + ); + + gui.setSlot(23, new GuiElementBuilder(Items.ARROW) + .setCallback(() -> { + if(page * 4 + 4 < converters.getConverters().size()) { + page++; + updateConverters(); + } + }) + ); + + gui.open(); + } + + public void updateConverters() { + int lastConverter = Math.min(5, converters.getConverters().size() + 2 - page * 4); + for(int i = 0; i < lastConverter; i++) { + //Each page has 5 converters, but the last is displayed on the next page as well + int converterIndex = page * 4 + i; + //without input element + int actualConverterIndex = converterIndex - 1; + int slot = 9 + 2 * i; + if(converterIndex == 0) { + gui.setSlot(slot, new GuiElementBuilder(Items.DROPPER)); + } else if(converterIndex == converters.getConverters().size() + 1) { + gui.setSlot(slot, new GuiElementBuilder(Items.HOPPER)); + } else { + ValueConverter converter = converters.getConverters().get(actualConverterIndex); + ValueType fromType = actualConverterIndex >= 1 ? converters.getConverters().get(actualConverterIndex - 1).getTo() : inputType; + ValueType toType = actualConverterIndex < converters.getConverters().size() - 1 ? converters.getConverters().get(actualConverterIndex + 1).getFrom() : outputType; + + gui.setSlot(slot, new GuiElementBuilder(GuiDisplay.getDisplayStackWithName(MinionRegistries.VALUE_CONVERTER_TYPES, converter.getType(), viewer.getRegistryManager())) + .addLoreLine(converter.getDisplayText()) + .setCallback(() -> new ConverterGui(this, converter, fromType, toType, converters, false, actualConverterIndex)) + ); + } + if(i != 4 && actualConverterIndex != converters.getConverters().size()) { + ValueType fromType = actualConverterIndex >= 0 ? converters.getConverters().get(actualConverterIndex).getTo() : inputType; + ValueType toType = actualConverterIndex < converters.getConverters().size() - 1 ? converters.getConverters().get(actualConverterIndex + 1).getFrom() : outputType; + + gui.setSlot(slot + 1, new GuiElementBuilder(Items.MAGENTA_GLAZED_TERRACOTTA) + .setName(Text.translatable( + "minions.gui.instruction.converters.cast", + Text.translatable(TranslationUtil.getTranslationKey(fromType, MinionRegistries.VALUE_TYPES)), + Text.translatable(TranslationUtil.getTranslationKey(toType, MinionRegistries.VALUE_TYPES)) + )) + .setCallback(() -> new ConverterGui(this, null, fromType, toType, converters, true, actualConverterIndex + 1)) + ); + } + } + } + + @Override + protected void closeBacking() { + gui.close(); + } +} diff --git a/src/main/java/io/github/skippyall/minions/gui/instruction/InstructionBoundSimpleGui.java b/src/main/java/io/github/skippyall/minions/gui/instruction/InstructionBoundSimpleGui.java deleted file mode 100644 index 40fe37a..0000000 --- a/src/main/java/io/github/skippyall/minions/gui/instruction/InstructionBoundSimpleGui.java +++ /dev/null @@ -1,30 +0,0 @@ -package io.github.skippyall.minions.gui.instruction; - -import io.github.skippyall.minions.gui.MinionBoundSimpleGui; -import io.github.skippyall.minions.minion.MinionRuntime; -import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; -import io.github.skippyall.minions.program.instruction.ConfiguredInstruction; -import io.github.skippyall.minions.program.instruction.ConfiguredInstructionListener; -import net.minecraft.screen.ScreenHandlerType; -import net.minecraft.server.network.ServerPlayerEntity; - -public class InstructionBoundSimpleGui extends MinionBoundSimpleGui implements ConfiguredInstructionListener { - protected final ConfiguredInstruction instruction; - - public InstructionBoundSimpleGui(ScreenHandlerType type, ServerPlayerEntity player, MinionFakePlayer minion, ConfiguredInstruction instruction) { - super(type, player, minion); - this.instruction = instruction; - instruction.addListener(this); - } - - @Override - public void onInstructionRemove(ConfiguredInstruction instruction) { - close(); - } - - @Override - public void onClose() { - super.onClose(); - instruction.removeListener(this); - } -} diff --git a/src/main/java/io/github/skippyall/minions/gui/instruction/InstructionGui.java b/src/main/java/io/github/skippyall/minions/gui/instruction/InstructionGui.java index 37426a7..18066d1 100644 --- a/src/main/java/io/github/skippyall/minions/gui/instruction/InstructionGui.java +++ b/src/main/java/io/github/skippyall/minions/gui/instruction/InstructionGui.java @@ -3,18 +3,20 @@ package io.github.skippyall.minions.gui.instruction; import eu.pb4.sgui.api.elements.GuiElementBuilder; import eu.pb4.sgui.api.gui.SimpleGui; import io.github.skippyall.minions.gui.GuiDisplay; -import io.github.skippyall.minions.gui.MinionBoundSimpleGui; -import io.github.skippyall.minions.registration.MinionComponentTypes; -import io.github.skippyall.minions.registration.MinionRegistries; +import io.github.skippyall.minions.gui.MinionsGui; import io.github.skippyall.minions.gui.input.Result; import io.github.skippyall.minions.gui.input.TextInput; +import io.github.skippyall.minions.gui.minion.GuiContext; +import io.github.skippyall.minions.gui.minion.SimpleMinionsGui; import io.github.skippyall.minions.minion.MinionRuntime; import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; import io.github.skippyall.minions.module.MinionModule; -import io.github.skippyall.minions.program.supplier.ValueSupplier; import io.github.skippyall.minions.program.instruction.ConfiguredInstruction; import io.github.skippyall.minions.program.instruction.InstructionType; import io.github.skippyall.minions.program.supplier.Parameter; +import io.github.skippyall.minions.program.supplier.ValueSupplier; +import io.github.skippyall.minions.registration.MinionComponentTypes; +import io.github.skippyall.minions.registration.MinionRegistries; import io.github.skippyall.minions.util.TranslationUtil; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; @@ -28,63 +30,50 @@ import java.util.NoSuchElementException; import java.util.concurrent.CompletableFuture; public class InstructionGui { - public static void openInstructionMainMenu(MinionFakePlayer minion, ServerPlayerEntity player) { - SimpleGui gui = new MinionBoundSimpleGui(ScreenHandlerType.GENERIC_3X3, player, minion); - gui.setTitle(Text.translatable("minions.gui.instruction.title")); + public static MinionsGui openInstructionMainMenu(MinionsGui parent, GuiContext.Minion context) { + return new SimpleMinionsGui(parent, (onClose, me) -> { + ServerPlayerEntity player = parent.getViewer(); - gui.setSlot(3, new GuiElementBuilder() - .setItem(Items.BOOK) - .setName(Text.translatable("minions.gui.instruction.list")) - .setCallback(() -> instructionList(minion, player)) - ); - gui.setSlot(5, new GuiElementBuilder() - .setItem(Items.WRITABLE_BOOK) - .setName(Text.translatable("minions.gui.instruction.create")) - .setCallback(() -> createNewInstruction(minion, player)) - ); + SimpleGui gui = new SimpleGui(ScreenHandlerType.GENERIC_3X3, player, false) { + @Override + public void onClose() { + onClose.run(); + } + }; + gui.setTitle(Text.translatable("minions.gui.instruction.title")); - gui.open(); - } - - public static void instructionList(MinionFakePlayer minion, ServerPlayerEntity player) { - SimpleGui gui = new MinionBoundSimpleGui(ScreenHandlerType.GENERIC_9X3, player, minion) { - @Override - public void onInstructionsUpdate(MinionFakePlayer minion) { - resetInstructionList(this, minion, player); - } - }; - gui.setTitle(Text.translatable("minions.gui.instruction.title")); - resetInstructionList(gui, minion, player); - - gui.open(); - } - - private static void resetInstructionList(SimpleGui gui, MinionFakePlayer minion, ServerPlayerEntity player) { - int i = 0; - for (String instructionName : minion.getInstructionManager().getInstructionNames()) { - ConfiguredInstruction instruction = minion.getInstructionManager().getInstruction(instructionName); - gui.setSlot(i, new GuiElementBuilder(GuiDisplay.getGuiDisplayFor(MinionRegistries.INSTRUCTION_TYPES, instruction.getInstruction(), player.getRegistryManager()).createItemStack()) - .setName(Text.literal(instructionName)) - .setCallback(() -> ConfigureInstructionGui.configureInstructionMenu(instructionName, instruction, minion, player)) + gui.setSlot(3, new GuiElementBuilder() + .setItem(Items.BOOK) + .setName(Text.translatable("minions.gui.instruction.list")) + .setCallback(() -> new InstructionListGui(me, context)) ); - i++; - } + gui.setSlot(5, new GuiElementBuilder() + .setItem(Items.WRITABLE_BOOK) + .setName(Text.translatable("minions.gui.instruction.create")) + .setCallback(() -> createNewInstruction(me, context)) + ); + + gui.open(); + return gui; + }); } - public static void createNewInstruction(MinionFakePlayer minion, ServerPlayerEntity player) { - selectInstructionModuleMenu(minion, player).thenAccept(instructionType -> - inputInstructionName(minion, player, "Instruction").thenAccept(name -> { + public static void createNewInstruction(MinionsGui parent, GuiContext.Minion context) { + MinionFakePlayer minion = context.getMinion(); + ServerPlayerEntity viewer = parent.getViewer(); + selectInstructionModuleMenu(parent, context).thenAccept(instructionType -> + inputInstructionName(parent, context, "Instruction").thenAccept(name -> { if (!minion.isRemoved() && !minion.isDisconnected()) { ConfiguredInstruction configuredInstruction = minion.getInstructionManager().createInstruction(name, instructionType); - ConfigureInstructionGui.configureInstructionMenu(name, configuredInstruction, minion, player); + new ConfigureInstructionGui(parent, GuiContext.Instruction.create(context, configuredInstruction, name)); } }) ); } - public static CompletableFuture inputInstructionName(MinionFakePlayer minion, ServerPlayerEntity player, String defaultValue) { - return TextInput.inputSync(player, Text.translatable("minions.gui.instruction.enter_name"), defaultValue, name -> { - if (minion.getInstructionManager().hasInstruction(name)) { + public static CompletableFuture inputInstructionName(MinionsGui parent, GuiContext.Minion context, String defaultValue) { + return TextInput.inputSync(parent, Text.translatable("minions.gui.instruction.enter_name"), defaultValue, name -> { + if (context.getMinion().getInstructionManager().hasInstruction(name)) { return new Result.Error<>(Text.translatable("minions.gui.instruction.name_already_used")); } return new Result.Success<>(name); @@ -100,62 +89,71 @@ public class InstructionGui { return stillExists; } - public static CompletableFuture> selectInstructionModuleMenu(MinionFakePlayer minion, ServerPlayerEntity player) { + public static CompletableFuture> selectInstructionModuleMenu(MinionsGui parent, GuiContext.Minion context) { + MinionFakePlayer minion = context.getMinion(); + ServerPlayerEntity viewer = parent.getViewer(); + if (minion.getModuleInventory().getModules().isEmpty()) { - player.sendMessage(Text.translatable("minions.gui.instruction.no_modules")); + viewer.sendMessage(Text.translatable("minions.gui.instruction.no_modules")); return CompletableFuture.failedFuture(new NoSuchElementException("No modules")); } CompletableFuture> future = new CompletableFuture<>(); - SimpleGui gui = new MinionBoundSimpleGui(ScreenHandlerType.GENERIC_9X3, player, minion) { - @Override - public void onClose() { - if (!future.isDone()) { - future.cancel(false); + new SimpleMinionsGui(parent, (closeHandler, me) -> { + SimpleGui gui = new SimpleGui(ScreenHandlerType.GENERIC_9X3, viewer, false) { + @Override + public void onClose() { + if (!future.isDone()) { + future.cancel(false); + } + closeHandler.run(); } - super.onClose(); - } - }; - gui.setTitle(Text.translatable("minions.gui.instruction.select_instruction")); + }; + gui.setTitle(Text.translatable("minions.gui.instruction.select_instruction")); - for (int i = 0; i < minion.getModuleInventory().size(); i++) { - ItemStack moduleItem = minion.getModuleInventory().getStack(i); - MinionModule module = moduleItem.get(MinionComponentTypes.MODULE); - if (module != null && !module.instructions().isEmpty()) { - gui.addSlot(new GuiElementBuilder(moduleItem) - .setCallback(() -> selectInstructionMenu(module, minion, player) - .thenApply(future::complete) - ) - ); + for (int i = 0; i < minion.getModuleInventory().size(); i++) { + ItemStack moduleItem = minion.getModuleInventory().getStack(i); + MinionModule module = moduleItem.get(MinionComponentTypes.MODULE); + if (module != null && !module.instructions().isEmpty()) { + gui.addSlot(new GuiElementBuilder(moduleItem) + .setCallback(() -> selectInstructionMenu(parent, context, module) + .thenApply(future::complete) + ) + ); + } } - } - gui.open(); + gui.open(); + return gui; + }); return future; } - public static CompletableFuture> selectInstructionMenu(MinionModule module, MinionFakePlayer minion, ServerPlayerEntity player) { + public static CompletableFuture> selectInstructionMenu(MinionsGui parent, GuiContext.Minion context, MinionModule module) { CompletableFuture> future = new CompletableFuture<>(); - SimpleGui gui = new MinionBoundSimpleGui(ScreenHandlerType.GENERIC_9X3, player, minion) { - @Override - public void onClose() { - if (!future.isDone()) { - future.cancel(false); + new SimpleMinionsGui(parent, (closeHandler, me) -> { + SimpleGui gui = new SimpleGui(ScreenHandlerType.GENERIC_9X3, parent.getViewer(), false) { + @Override + public void onClose() { + if (!future.isDone()) { + future.cancel(false); + } + closeHandler.run(); } - super.onClose(); + }; + gui.setTitle(Text.translatable("minions.gui.instruction.select_instruction")); + + for (InstructionType instructionType : module.instructions()) { + gui.addSlot(createInstructionElement(instructionType, parent.getViewer().getRegistryManager()) + .setCallback(() -> future.complete(instructionType)) + ); } - }; - gui.setTitle(Text.translatable("minions.gui.instruction.select_instruction")); - for (InstructionType instructionType : module.instructions()) { - gui.addSlot(createInstructionElement(instructionType, player.getRegistryManager()) - .setCallback(() -> future.complete(instructionType)) - ); - } - - gui.open(); + gui.open(); + return gui; + }); return future; } diff --git a/src/main/java/io/github/skippyall/minions/gui/instruction/InstructionListGui.java b/src/main/java/io/github/skippyall/minions/gui/instruction/InstructionListGui.java new file mode 100644 index 0000000..f967780 --- /dev/null +++ b/src/main/java/io/github/skippyall/minions/gui/instruction/InstructionListGui.java @@ -0,0 +1,69 @@ +package io.github.skippyall.minions.gui.instruction; + +import eu.pb4.sgui.api.elements.GuiElementBuilder; +import eu.pb4.sgui.api.gui.SimpleGui; +import io.github.skippyall.minions.gui.GuiDisplay; +import io.github.skippyall.minions.gui.MinionsGui; +import io.github.skippyall.minions.gui.minion.GuiContext; +import io.github.skippyall.minions.minion.MinionListener; +import io.github.skippyall.minions.minion.MinionRuntime; +import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; +import io.github.skippyall.minions.program.instruction.ConfiguredInstruction; +import io.github.skippyall.minions.registration.MinionRegistries; +import net.minecraft.screen.ScreenHandlerType; +import net.minecraft.text.Text; + +public class InstructionListGui extends MinionsGui implements MinionListener { + private final GuiContext.Minion context; + private final MinionFakePlayer minion; + private SimpleGui gui; + + public InstructionListGui(MinionsGui parent, GuiContext.Minion context) { + super(parent); + this.context = context; + this.minion = context.getMinion(); + open(); + } + + @Override + public void onInstructionsUpdate(MinionFakePlayer minion) { + resetInstructionList(); + } + + @Override + protected void open() { + minion.addMinionListener(this); + gui = new SimpleGui(ScreenHandlerType.GENERIC_9X3, viewer, false) { + @Override + public void onClose() { + onBackingClosed(); + } + }; + gui.setTitle(Text.translatable("minions.gui.instruction.title")); + resetInstructionList(); + gui.open(); + } + + @Override + protected void reopen() { + gui.open(); + } + + @Override + protected void closeBacking() { + minion.removeMinionListener(this); + gui.close(); + } + + private void resetInstructionList() { + int i = 0; + for (String instructionName : minion.getInstructionManager().getInstructionNames()) { + ConfiguredInstruction instruction = minion.getInstructionManager().getInstruction(instructionName); + gui.setSlot(i, new GuiElementBuilder(GuiDisplay.getGuiDisplayFor(MinionRegistries.INSTRUCTION_TYPES, instruction.getInstruction(), viewer.getRegistryManager()).createItemStack()) + .setName(Text.literal(instructionName)) + .setCallback(() -> new ConfigureInstructionGui(this, GuiContext.Instruction.create(context, instruction, instructionName))) + ); + i++; + } + } +} diff --git a/src/main/java/io/github/skippyall/minions/gui/minion/GuiContext.java b/src/main/java/io/github/skippyall/minions/gui/minion/GuiContext.java new file mode 100644 index 0000000..a9e0334 --- /dev/null +++ b/src/main/java/io/github/skippyall/minions/gui/minion/GuiContext.java @@ -0,0 +1,43 @@ +package io.github.skippyall.minions.gui.minion; + +import io.github.skippyall.minions.minion.MinionRuntime; +import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; +import io.github.skippyall.minions.program.instruction.ConfiguredInstruction; +import io.github.skippyall.minions.program.supplier.Parameter; +import net.minecraft.server.network.ServerPlayerEntity; + +public interface GuiContext { + ServerPlayerEntity getViewer(); + + static GuiContext create(ServerPlayerEntity viewer) { + return new GuiContextImpl(viewer); + } + + interface Minion extends GuiContext { + MinionFakePlayer getMinion(); + + static GuiContext.Minion create(GuiContext context, MinionFakePlayer minion) { + return new GuiContextImpl.MinionImpl(context, minion); + } + } + + interface Instruction extends Minion { + ConfiguredInstruction getInstruction(); + + String getName(); + + void setName(String name); + + static GuiContext.Instruction create(GuiContext.Minion context, ConfiguredInstruction instruction, String name) { + return new GuiContextImpl.InstructionImpl(context, instruction, name); + } + } + + interface ValueSupplier extends Instruction { + Parameter getParameter(); + + static GuiContext.ValueSupplier create(GuiContext.Instruction context, Parameter parameter) { + return new GuiContextImpl.ValueSupplierImpl(context, parameter); + } + } +} diff --git a/src/main/java/io/github/skippyall/minions/gui/minion/GuiContextImpl.java b/src/main/java/io/github/skippyall/minions/gui/minion/GuiContextImpl.java new file mode 100644 index 0000000..20b4feb --- /dev/null +++ b/src/main/java/io/github/skippyall/minions/gui/minion/GuiContextImpl.java @@ -0,0 +1,120 @@ +package io.github.skippyall.minions.gui.minion; + +import io.github.skippyall.minions.minion.MinionRuntime; +import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; +import io.github.skippyall.minions.program.instruction.ConfiguredInstruction; +import io.github.skippyall.minions.program.supplier.Parameter; +import net.minecraft.server.network.ServerPlayerEntity; + +//If only this mod was kotlin +public class GuiContextImpl implements GuiContext { + private final ServerPlayerEntity viewer; + + public GuiContextImpl(ServerPlayerEntity viewer) { + this.viewer = viewer; + } + + @Override + public ServerPlayerEntity getViewer() { + return viewer; + } + + public static class MinionImpl extends DelegatingGuiContextImpl implements GuiContext.Minion { + private final MinionFakePlayer minion; + + public MinionImpl(GuiContext context, MinionFakePlayer minion) { + super(context); + this.minion = minion; + } + + @Override + public MinionFakePlayer getMinion() { + return minion; + } + } + + public static class InstructionImpl extends DelegatingMinionImpl implements GuiContext.Instruction { + private final ConfiguredInstruction instruction; + private String name; + + public InstructionImpl(GuiContext.Minion context, ConfiguredInstruction instruction, String name) { + super(context); + this.instruction = instruction; + this.name = name; + } + + @Override + public ConfiguredInstruction getInstruction() { + return instruction; + } + + @Override + public String getName() { + return name; + } + + @Override + public void setName(String name) { + this.name = name; + } + } + + public static class ValueSupplierImpl extends DelegatingInstructionImpl implements GuiContext.ValueSupplier { + private final Parameter parameter; + + public ValueSupplierImpl(GuiContext.Instruction context, Parameter parameter) { + super(context); + this.parameter = parameter; + } + + @Override + public Parameter getParameter() { + return parameter; + } + } + + public static class DelegatingGuiContextImpl implements GuiContext { + protected final C context; + + public DelegatingGuiContextImpl(C context) { + this.context = context; + } + + @Override + public ServerPlayerEntity getViewer() { + return context.getViewer(); + } + } + + public static class DelegatingMinionImpl extends DelegatingGuiContextImpl implements GuiContext.Minion { + public DelegatingMinionImpl(C context) { + super(context); + } + + @Override + public MinionFakePlayer getMinion() { + return context.getMinion(); + } + } + + public static class DelegatingInstructionImpl extends DelegatingMinionImpl implements GuiContext.Instruction { + public DelegatingInstructionImpl(C context) { + super(context); + } + + @Override + public ConfiguredInstruction getInstruction() { + return context.getInstruction(); + } + + @Override + public String getName() { + return context.getName(); + } + + @Override + public void setName(String name) { + context.setName(name); + } + } +} diff --git a/src/main/java/io/github/skippyall/minions/gui/minion/MinionGui.java b/src/main/java/io/github/skippyall/minions/gui/minion/MinionGui.java index ba0f210..fb3c2eb 100644 --- a/src/main/java/io/github/skippyall/minions/gui/minion/MinionGui.java +++ b/src/main/java/io/github/skippyall/minions/gui/minion/MinionGui.java @@ -7,13 +7,8 @@ import io.github.skippyall.minions.gui.instruction.InstructionGui; import io.github.skippyall.minions.minion.MinionListener; import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; import io.github.skippyall.minions.module.ModuleInventory; -import net.minecraft.entity.EquipmentSlot; -import net.minecraft.entity.player.PlayerInventory; -import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.screen.ScreenHandlerType; -import net.minecraft.screen.slot.ArmorSlot; -import net.minecraft.screen.slot.Slot; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; @@ -25,6 +20,7 @@ public class MinionGui extends MinionsGui implements MinionListener { super(viewer); this.minion = minion; minion.addMinionListener(this); + open(); } public MinionFakePlayer getMinion() { @@ -46,7 +42,7 @@ public class MinionGui extends MinionsGui implements MinionListener { .setItem(Items.COMMAND_BLOCK) .setName(Text.translatable("minions.gui.main.instructions")) .setCallback(() -> { - InstructionGui.openInstructionMainMenu(minion, viewer); + InstructionGui.openInstructionMainMenu(this, GuiContext.Minion.create(GuiContext.create(viewer), minion)); }) ); gui.setSlot(3, new GuiElementBuilder() @@ -75,7 +71,7 @@ public class MinionGui extends MinionsGui implements MinionListener { } @Override - protected void onClose() { + protected void closeBacking() { gui.close(); minion.removeMinionListener(this); } @@ -84,10 +80,4 @@ public class MinionGui extends MinionsGui implements MinionListener { public void onMinionRemove(MinionFakePlayer minion) { close(); } - - public static GuiElementBuilder backButton(Runnable onBack) { - return new GuiElementBuilder(Items.COMPASS) - .setItemName(Text.translatable("gui.back")) - .setCallback(onBack); - } } diff --git a/src/main/java/io/github/skippyall/minions/gui/minion/MinionInventoryGui.java b/src/main/java/io/github/skippyall/minions/gui/minion/MinionInventoryGui.java index 4efc147..439e708 100644 --- a/src/main/java/io/github/skippyall/minions/gui/minion/MinionInventoryGui.java +++ b/src/main/java/io/github/skippyall/minions/gui/minion/MinionInventoryGui.java @@ -22,6 +22,7 @@ public class MinionInventoryGui extends MinionsGui { super(parent); this.parent = parent; this.minion = parent.getMinion(); + open(); } @Override @@ -61,7 +62,7 @@ public class MinionInventoryGui extends MinionsGui { } @Override - protected void onClose() { + protected void closeBacking() { gui.close(); } } diff --git a/src/main/java/io/github/skippyall/minions/gui/minion/SimpleMinionsGui.java b/src/main/java/io/github/skippyall/minions/gui/minion/SimpleMinionsGui.java new file mode 100644 index 0000000..b0f1c9f --- /dev/null +++ b/src/main/java/io/github/skippyall/minions/gui/minion/SimpleMinionsGui.java @@ -0,0 +1,27 @@ +package io.github.skippyall.minions.gui.minion; + +import eu.pb4.sgui.api.gui.GuiInterface; +import io.github.skippyall.minions.gui.MinionsGui; + +import java.util.function.BiFunction; + +public class SimpleMinionsGui extends MinionsGui { + private GuiInterface gui; + private final BiFunction guiFactory; + + public SimpleMinionsGui(MinionsGui parent, BiFunction guiFactory) { + super(parent); + this.guiFactory = guiFactory; + open(); + } + + @Override + protected void open() { + gui = guiFactory.apply(this::onBackingClosed, this); + } + + @Override + protected void closeBacking() { + gui.close(); + } +} diff --git a/src/main/java/io/github/skippyall/minions/listener/ListenerManager.java b/src/main/java/io/github/skippyall/minions/listener/ListenerManager.java index 6d33f3d..6e5ae6f 100644 --- a/src/main/java/io/github/skippyall/minions/listener/ListenerManager.java +++ b/src/main/java/io/github/skippyall/minions/listener/ListenerManager.java @@ -3,17 +3,17 @@ package io.github.skippyall.minions.listener; import org.jetbrains.annotations.NotNull; import java.util.Iterator; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; public class ListenerManager implements Iterable { - protected final List listeners; + protected final Set listeners; public ListenerManager() { - this(new CopyOnWriteArrayList<>()); + this(new CopyOnWriteArraySet<>()); } - protected ListenerManager(List listeners) { + protected ListenerManager(Set listeners) { this.listeners = listeners; } @@ -23,34 +23,11 @@ public class ListenerManager implements Iterable { public void removeListener(T listener) { listeners.remove(listener); - onRemove(listener); } - protected void onRemove(T listener) {} - @Override public @NotNull Iterator iterator() { - return new Iterator<>() { - final Iterator backing = listeners.iterator(); - T last; - - @Override - public boolean hasNext() { - return backing.hasNext(); - } - - @Override - public T next() { - last = backing.next(); - return last; - } - - @Override - public void remove() { - backing.remove(); - onRemove(last); - } - }; + return listeners.iterator(); } @Override diff --git a/src/main/java/io/github/skippyall/minions/listener/SerializableListenerManager.java b/src/main/java/io/github/skippyall/minions/listener/SerializableListenerManager.java index 48d6aaa..fa4cc9a 100644 --- a/src/main/java/io/github/skippyall/minions/listener/SerializableListenerManager.java +++ b/src/main/java/io/github/skippyall/minions/listener/SerializableListenerManager.java @@ -2,25 +2,21 @@ package io.github.skippyall.minions.listener; import com.mojang.serialization.Codec; import net.minecraft.registry.Registry; -import net.minecraft.storage.ReadView; -import net.minecraft.storage.WriteView; import net.minecraft.util.Identifier; import java.util.ArrayList; import java.util.List; import java.util.Optional; -import java.util.concurrent.CopyOnWriteArrayList; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; public class SerializableListenerManager extends ListenerManager { - private final Registry> registry; - - public SerializableListenerManager(Registry> registry) { - this.registry = registry; + public SerializableListenerManager() { + super(); } - public SerializableListenerManager(Registry> registry, List listeners) { + protected SerializableListenerManager(Set listeners) { super(listeners); - this.registry = registry; } public static Codec> getCodec(Registry> registry) { @@ -28,7 +24,7 @@ public class SerializableListenerManager listener.getCodecId().map(registry::get).orElse(Codec.unit(null)), codec -> codec.fieldOf("data") ).listOf().xmap( - list -> new SerializableListenerManager<>(registry, new CopyOnWriteArrayList<>(list)), + list -> new SerializableListenerManager<>(new CopyOnWriteArraySet<>(list)), manager -> { List serializableListeners = new ArrayList<>(); for(T listener : manager.listeners) { @@ -41,37 +37,6 @@ public class SerializableListenerManager codec = registry.get(listener.getCodecId().get()); - listenerView.put("id", Identifier.CODEC, listener.getCodecId().get()); - //noinspection unchecked - listenerView.put("data", (Codec) codec, listener); - } - } - } - - public void load(ReadView view) { - ReadView.ListReadView listView = view.getListReadView("listeners"); - for (ReadView listenerView : listView) { - Optional id = listenerView.read("id", Identifier.CODEC); - if(id.isEmpty()) { - continue; - } - - Codec codec = registry.get(id.get()); - - Optional listener = listenerView.read("data", codec); - - if(listener.isPresent()) { - listeners.add(listener.get()); - } - } - } - public interface SerializableListener { default Optional getCodecId() { return Optional.empty(); diff --git a/src/main/java/io/github/skippyall/minions/minion/MinionData.java b/src/main/java/io/github/skippyall/minions/minion/MinionData.java index 9f513fc..6f15fb1 100644 --- a/src/main/java/io/github/skippyall/minions/minion/MinionData.java +++ b/src/main/java/io/github/skippyall/minions/minion/MinionData.java @@ -3,8 +3,8 @@ package io.github.skippyall.minions.minion; import com.mojang.authlib.properties.PropertyMap; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import io.github.skippyall.minions.registration.MinionRegistries; import io.github.skippyall.minions.listener.SerializableListenerManager; +import io.github.skippyall.minions.registration.MinionRegistries; import net.minecraft.server.MinecraftServer; import net.minecraft.util.Uuids; import net.minecraft.util.dynamic.Codecs; @@ -27,7 +27,7 @@ public record MinionData( Codecs.GAME_PROFILE_PROPERTY_MAP.optionalFieldOf("skin").forGetter(MinionData::skin), Codec.BOOL.optionalFieldOf("isSpawned", false).forGetter(MinionData::isSpawned), SerializableListenerManager.getCodec(MinionRegistries.MINION_LISTENER_CODECS).optionalFieldOf("listeners").xmap( - optional -> optional.orElseGet(() -> new SerializableListenerManager<>(MinionRegistries.MINION_LISTENER_CODECS)), + optional -> optional.orElseGet(SerializableListenerManager::new), Optional::of ).forGetter(MinionData::listeners), MinionConfig.CODEC.optionalFieldOf("config", new MinionConfig()).forGetter(MinionData::config) @@ -40,7 +40,7 @@ public record MinionData( MinionProfileUtils.newDefaultMinionName(server), Optional.empty(), false, - new SerializableListenerManager<>(MinionRegistries.MINION_LISTENER_CODECS), + new SerializableListenerManager<>(), new MinionConfig() ); } diff --git a/src/main/java/io/github/skippyall/minions/minion/MinionListener.java b/src/main/java/io/github/skippyall/minions/minion/MinionListener.java index b643e5f..0c14d3e 100644 --- a/src/main/java/io/github/skippyall/minions/minion/MinionListener.java +++ b/src/main/java/io/github/skippyall/minions/minion/MinionListener.java @@ -1,8 +1,8 @@ package io.github.skippyall.minions.minion; +import io.github.skippyall.minions.listener.SerializableListenerManager; import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; import io.github.skippyall.minions.program.instruction.ConfiguredInstruction; -import io.github.skippyall.minions.listener.SerializableListenerManager; import org.jetbrains.annotations.Nullable; public interface MinionListener extends SerializableListenerManager.SerializableListener { diff --git a/src/main/java/io/github/skippyall/minions/minion/MinionRuntime.java b/src/main/java/io/github/skippyall/minions/minion/MinionRuntime.java index 70ed434..4d7cb80 100644 --- a/src/main/java/io/github/skippyall/minions/minion/MinionRuntime.java +++ b/src/main/java/io/github/skippyall/minions/minion/MinionRuntime.java @@ -1,13 +1,13 @@ package io.github.skippyall.minions.minion; -import io.github.skippyall.minions.registration.MinionRegistries; import io.github.skippyall.minions.Minions; import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; import io.github.skippyall.minions.program.InstructionRuntime; -import io.github.skippyall.minions.program.supplier.ValueSupplierType; +import io.github.skippyall.minions.program.consumer.ValueConsumerType; import io.github.skippyall.minions.program.instruction.ConfiguredInstruction; import io.github.skippyall.minions.program.instruction.InstructionType; -import io.github.skippyall.minions.program.consumer.ValueConsumerType; +import io.github.skippyall.minions.program.supplier.ValueSupplierType; +import io.github.skippyall.minions.registration.MinionRegistries; import net.minecraft.registry.Registry; import net.minecraft.storage.ReadView; import net.minecraft.storage.WriteView; diff --git a/src/main/java/io/github/skippyall/minions/minion/fakeplayer/EntityPlayerActionPack.java b/src/main/java/io/github/skippyall/minions/minion/fakeplayer/EntityPlayerActionPack.java index 3ed7e83..53a39ff 100644 --- a/src/main/java/io/github/skippyall/minions/minion/fakeplayer/EntityPlayerActionPack.java +++ b/src/main/java/io/github/skippyall/minions/minion/fakeplayer/EntityPlayerActionPack.java @@ -2,11 +2,6 @@ package io.github.skippyall.minions.minion.fakeplayer; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import io.github.skippyall.minions.mixins.EntityAccessor; import net.minecraft.block.BlockState; import net.minecraft.command.argument.EntityAnchorArgumentType; @@ -32,6 +27,11 @@ import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec2f; import net.minecraft.util.math.Vec3d; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + public class EntityPlayerActionPack { private final MinionFakePlayer player; diff --git a/src/main/java/io/github/skippyall/minions/minion/fakeplayer/FakeClientConnection.java b/src/main/java/io/github/skippyall/minions/minion/fakeplayer/FakeClientConnection.java index e45fce8..ddeedc1 100644 --- a/src/main/java/io/github/skippyall/minions/minion/fakeplayer/FakeClientConnection.java +++ b/src/main/java/io/github/skippyall/minions/minion/fakeplayer/FakeClientConnection.java @@ -4,8 +4,8 @@ package io.github.skippyall.minions.minion.fakeplayer; import io.netty.channel.embedded.EmbeddedChannel; import net.minecraft.network.ClientConnection; import net.minecraft.network.NetworkSide; -import net.minecraft.network.state.NetworkState; import net.minecraft.network.listener.PacketListener; +import net.minecraft.network.state.NetworkState; public class FakeClientConnection extends ClientConnection { public FakeClientConnection(NetworkSide p) diff --git a/src/main/java/io/github/skippyall/minions/minion/fakeplayer/MinionFakePlayer.java b/src/main/java/io/github/skippyall/minions/minion/fakeplayer/MinionFakePlayer.java index 46f7154..adaa912 100644 --- a/src/main/java/io/github/skippyall/minions/minion/fakeplayer/MinionFakePlayer.java +++ b/src/main/java/io/github/skippyall/minions/minion/fakeplayer/MinionFakePlayer.java @@ -3,18 +3,18 @@ package io.github.skippyall.minions.minion.fakeplayer; import com.mojang.authlib.GameProfile; import com.mojang.authlib.properties.PropertyMap; -import io.github.skippyall.minions.registration.MinionConfigOptions; -import io.github.skippyall.minions.registration.MinionItems; -import io.github.skippyall.minions.minion.MinionListener; -import io.github.skippyall.minions.minion.MinionData; import io.github.skippyall.minions.gui.minion.MinionGui; -import io.github.skippyall.minions.minion.MinionRuntime; +import io.github.skippyall.minions.listener.SerializableListenerManager; +import io.github.skippyall.minions.minion.MinionData; import io.github.skippyall.minions.minion.MinionItem; +import io.github.skippyall.minions.minion.MinionListener; import io.github.skippyall.minions.minion.MinionPersistentState; import io.github.skippyall.minions.minion.MinionProfileUtils; +import io.github.skippyall.minions.minion.MinionRuntime; import io.github.skippyall.minions.module.ModuleInventory; +import io.github.skippyall.minions.registration.MinionConfigOptions; +import io.github.skippyall.minions.registration.MinionItems; import io.github.skippyall.minions.registration.SpecialAbilities; -import io.github.skippyall.minions.listener.SerializableListenerManager; import net.minecraft.block.BlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.EquipmentSlot; @@ -91,6 +91,7 @@ public class MinionFakePlayer extends ServerPlayerEntity { instance.setHealth(20.0F); instance.unsetRemoved(); instance.getAttributeInstance(EntityAttributes.STEP_HEIGHT).setBaseValue(0.6F); + instance.getAttributeInstance(EntityAttributes.WAYPOINT_TRANSMIT_RANGE).setBaseValue(0); instance.interactionManager.changeGameMode(GameMode.SURVIVAL); server.getPlayerManager().sendToDimension(new EntitySetHeadYawS2CPacket(instance, (byte) (instance.headYaw * 256 / 360)), level.getRegistryKey()); server.getPlayerManager().sendToDimension(EntityPositionSyncS2CPacket.create(instance), level.getRegistryKey()); @@ -281,7 +282,7 @@ public class MinionFakePlayer extends ServerPlayerEntity { @Override public void drop(ServerWorld world, DamageSource damageSource) { super.drop(world, damageSource); - ItemEntity entity = dropStack(world, toItemStack(getServer())); + ItemEntity entity = dropItem(toItemStack(world.getServer()), true, false); if (entity != null) { entity.setNeverDespawn(); } diff --git a/src/main/java/io/github/skippyall/minions/minion/fakeplayer/Tracer.java b/src/main/java/io/github/skippyall/minions/minion/fakeplayer/Tracer.java index 51e9d08..1e29f14 100644 --- a/src/main/java/io/github/skippyall/minions/minion/fakeplayer/Tracer.java +++ b/src/main/java/io/github/skippyall/minions/minion/fakeplayer/Tracer.java @@ -1,8 +1,6 @@ //code from https://github.com/gnembon/fabric-carpet package io.github.skippyall.minions.minion.fakeplayer; -import java.util.Optional; -import java.util.function.Predicate; import net.minecraft.entity.Entity; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.EntityHitResult; @@ -12,6 +10,9 @@ import net.minecraft.util.math.Vec3d; import net.minecraft.world.RaycastContext; import net.minecraft.world.World; +import java.util.Optional; +import java.util.function.Predicate; + public class Tracer { public static HitResult rayTrace(Entity source, float partialTicks, double reach, boolean fluids) diff --git a/src/main/java/io/github/skippyall/minions/minion/program/instruction/ActionExecution.java b/src/main/java/io/github/skippyall/minions/minion/program/instruction/ActionExecution.java index 4e764ff..369a378 100644 --- a/src/main/java/io/github/skippyall/minions/minion/program/instruction/ActionExecution.java +++ b/src/main/java/io/github/skippyall/minions/minion/program/instruction/ActionExecution.java @@ -4,7 +4,7 @@ import io.github.skippyall.minions.minion.MinionRuntime; import io.github.skippyall.minions.minion.fakeplayer.EntityPlayerActionPack; import io.github.skippyall.minions.program.consumer.ValueConsumerList; import io.github.skippyall.minions.program.instruction.execution.ContinuousInstructionExecution; -import io.github.skippyall.minions.program.supplier.ValueSupplierList; +import io.github.skippyall.minions.program.supplier.ParameterValueList; import net.minecraft.storage.ReadView; import net.minecraft.storage.WriteView; @@ -39,7 +39,7 @@ public class ActionExecution implements ContinuousInstructionExecution parameters, MinionRuntime minion) {} + public void readArguments(ParameterValueList parameters, MinionRuntime minion) {} @Override public void save(WriteView view, MinionRuntime minion) {} diff --git a/src/main/java/io/github/skippyall/minions/minion/program/instruction/MineBlockExecution.java b/src/main/java/io/github/skippyall/minions/minion/program/instruction/MineBlockExecution.java index ad6a86d..7eebece 100644 --- a/src/main/java/io/github/skippyall/minions/minion/program/instruction/MineBlockExecution.java +++ b/src/main/java/io/github/skippyall/minions/minion/program/instruction/MineBlockExecution.java @@ -6,7 +6,7 @@ import io.github.skippyall.minions.minion.fakeplayer.EntityPlayerActionPack; import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; import io.github.skippyall.minions.program.consumer.ValueConsumerList; import io.github.skippyall.minions.program.instruction.InstructionExecution; -import io.github.skippyall.minions.program.supplier.ValueSupplierList; +import io.github.skippyall.minions.program.supplier.ParameterValueList; import net.minecraft.block.BlockState; import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket; import net.minecraft.storage.ReadView; @@ -121,7 +121,7 @@ public class MineBlockExecution implements InstructionExecution { } @Override - public void readArguments(ValueSupplierList arguments, MinionRuntime runtime) { + public void readArguments(ParameterValueList arguments, MinionRuntime runtime) { } diff --git a/src/main/java/io/github/skippyall/minions/minion/program/instruction/inventory/SwapItemExecution.java b/src/main/java/io/github/skippyall/minions/minion/program/instruction/inventory/SwapItemExecution.java index 58d2980..3985487 100644 --- a/src/main/java/io/github/skippyall/minions/minion/program/instruction/inventory/SwapItemExecution.java +++ b/src/main/java/io/github/skippyall/minions/minion/program/instruction/inventory/SwapItemExecution.java @@ -5,7 +5,7 @@ import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; import io.github.skippyall.minions.program.consumer.ValueConsumerList; import io.github.skippyall.minions.program.instruction.InstructionExecution; import io.github.skippyall.minions.program.supplier.Parameter; -import io.github.skippyall.minions.program.supplier.ValueSupplierList; +import io.github.skippyall.minions.program.supplier.ParameterValueList; import io.github.skippyall.minions.registration.ValueTypes; import net.minecraft.item.ItemStack; import net.minecraft.screen.ScreenHandler; @@ -114,11 +114,11 @@ public class SwapItemExecution implements InstructionExecution { } @Override - public void readArguments(ValueSupplierList arguments, MinionRuntime runtime) { - fromSlot = Math.clamp(arguments.getValue(FROM_SLOT, runtime), 0, Integer.MAX_VALUE); - fromScreen = arguments.getValue(FROM_SCREEN, runtime); - toSlot = Math.clamp(arguments.getValue(TO_SLOT, runtime), 0, Integer.MAX_VALUE); - toScreen = arguments.getValue(TO_SCREEN, runtime); + public void readArguments(ParameterValueList arguments, MinionRuntime runtime) { + fromSlot = Math.clamp(arguments.getValue(FROM_SLOT), 0, Integer.MAX_VALUE); + fromScreen = arguments.getValue(FROM_SCREEN); + toSlot = Math.clamp(arguments.getValue(TO_SLOT), 0, Integer.MAX_VALUE); + toScreen = arguments.getValue(TO_SCREEN); } @Override diff --git a/src/main/java/io/github/skippyall/minions/minion/program/instruction/move/TurnExecution.java b/src/main/java/io/github/skippyall/minions/minion/program/instruction/move/TurnExecution.java index ec9b077..2cea952 100644 --- a/src/main/java/io/github/skippyall/minions/minion/program/instruction/move/TurnExecution.java +++ b/src/main/java/io/github/skippyall/minions/minion/program/instruction/move/TurnExecution.java @@ -1,8 +1,8 @@ package io.github.skippyall.minions.minion.program.instruction.move; import io.github.skippyall.minions.minion.MinionRuntime; -import io.github.skippyall.minions.program.supplier.ValueSupplierList; import io.github.skippyall.minions.program.supplier.Parameter; +import io.github.skippyall.minions.program.supplier.ParameterValueList; import io.github.skippyall.minions.registration.ValueTypes; public class TurnExecution extends AbstractTurnExecution { @@ -10,9 +10,9 @@ public class TurnExecution extends AbstractTurnExecution { public static final Parameter DIRECTION = new Parameter<>("direction", ValueTypes.TURN_DIRECTION); @Override - public void readArguments(ValueSupplierList arguments, MinionRuntime minion) { - float maxAngle = arguments.getValue(ANGLE, minion).floatValue(); - TurnDirection direction = arguments.getValue(DIRECTION, minion); + public void readArguments(ParameterValueList arguments, MinionRuntime minion) { + float maxAngle = arguments.getValue(ANGLE).floatValue(); + TurnDirection direction = arguments.getValue(DIRECTION); float turnYaw = maxAngle * direction.xFactor; float turnPitch = maxAngle * direction.yFactor; diff --git a/src/main/java/io/github/skippyall/minions/minion/program/instruction/move/TurnVectorExecution.java b/src/main/java/io/github/skippyall/minions/minion/program/instruction/move/TurnVectorExecution.java index c445ac3..ab53a0a 100644 --- a/src/main/java/io/github/skippyall/minions/minion/program/instruction/move/TurnVectorExecution.java +++ b/src/main/java/io/github/skippyall/minions/minion/program/instruction/move/TurnVectorExecution.java @@ -2,7 +2,7 @@ package io.github.skippyall.minions.minion.program.instruction.move; import io.github.skippyall.minions.minion.MinionRuntime; import io.github.skippyall.minions.program.supplier.Parameter; -import io.github.skippyall.minions.program.supplier.ValueSupplierList; +import io.github.skippyall.minions.program.supplier.ParameterValueList; import io.github.skippyall.minions.registration.ValueTypes; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec2f; @@ -14,10 +14,10 @@ public class TurnVectorExecution extends AbstractTurnExecution { public static final Parameter Z = new Parameter<>("z", ValueTypes.DOUBLE); @Override - public void readArguments(ValueSupplierList arguments, MinionRuntime runtime) { - double x = arguments.getValue(X, runtime); - double y = arguments.getValue(Y, runtime); - double z = arguments.getValue(Z, runtime); + public void readArguments(ParameterValueList arguments, MinionRuntime runtime) { + double x = arguments.getValue(X); + double y = arguments.getValue(Y); + double z = arguments.getValue(Z); Vec3d vector = new Vec3d(x, y, z); Vec2f rotation = vectorToRotation(vector); diff --git a/src/main/java/io/github/skippyall/minions/minion/program/instruction/move/WalkExecution.java b/src/main/java/io/github/skippyall/minions/minion/program/instruction/move/WalkExecution.java index ba90653..0926285 100644 --- a/src/main/java/io/github/skippyall/minions/minion/program/instruction/move/WalkExecution.java +++ b/src/main/java/io/github/skippyall/minions/minion/program/instruction/move/WalkExecution.java @@ -3,7 +3,7 @@ package io.github.skippyall.minions.minion.program.instruction.move; import io.github.skippyall.minions.minion.MinionRuntime; import io.github.skippyall.minions.program.instruction.InstructionExecution; import io.github.skippyall.minions.program.supplier.Parameter; -import io.github.skippyall.minions.program.supplier.ValueSupplierList; +import io.github.skippyall.minions.program.supplier.ParameterValueList; import io.github.skippyall.minions.registration.ValueTypes; import net.minecraft.entity.MovementType; import net.minecraft.storage.ReadView; @@ -29,8 +29,8 @@ public class WalkExecution implements InstructionExecution { } @Override - public void readArguments(ValueSupplierList parameters, MinionRuntime minion) { - totalBlocksToMove = parameters.getValue(blocksToMoveParam, minion).floatValue(); + public void readArguments(ParameterValueList parameters, MinionRuntime minion) { + totalBlocksToMove = parameters.getValue(blocksToMoveParam).floatValue(); blocksMoved = 0; } diff --git a/src/main/java/io/github/skippyall/minions/minion/program/supplier/AnalogInputSupplier.java b/src/main/java/io/github/skippyall/minions/minion/program/supplier/AnalogInputSupplier.java index 038606e..ac96f16 100644 --- a/src/main/java/io/github/skippyall/minions/minion/program/supplier/AnalogInputSupplier.java +++ b/src/main/java/io/github/skippyall/minions/minion/program/supplier/AnalogInputSupplier.java @@ -5,6 +5,8 @@ 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.gui.MinionsGui; +import io.github.skippyall.minions.gui.minion.SimpleMinionsGui; import io.github.skippyall.minions.minion.MinionRuntime; import io.github.skippyall.minions.program.supplier.ValueSupplier; import io.github.skippyall.minions.program.supplier.ValueSupplierType; @@ -17,7 +19,6 @@ 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; @@ -62,7 +63,7 @@ public class AnalogInputSupplier implements ValueSupplier { @Override public Text getDisplayText() { - return Text.translatable("value_supplier_type.minions.analog_input.display", analogInputPos.toString(), analogInputWorld.getValue().toString()); + return Text.translatable("value_supplier.minions.analog_input.display", analogInputPos.toShortString(), analogInputWorld.getValue().toString()); } public static class AnalogInputSupplierType extends ValueSupplierType { @@ -75,22 +76,29 @@ public class AnalogInputSupplier implements ValueSupplier { } @Override - public CompletableFuture> openConfiguration(ServerPlayerEntity player, ValueType valueType, @Nullable ValueSupplier previous) { + public CompletableFuture> openConfiguration(MinionsGui parent, ValueType valueType, @Nullable ValueSupplier previous) { CompletableFuture> future = new CompletableFuture<>(); + new SimpleMinionsGui(parent, (onClose, me) -> { + SimpleGui gui = new SimpleGui(ScreenHandlerType.GENERIC_3X3, parent.getViewer(), false) { + @Override + public void onClose() { + onClose.run(); + } + }; + gui.setTitle(Text.translatable("value_supplier.minions.analog_input")); - 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())); - } - }) - .setItemName(Text.translatable("value_supplier_type.minions.analog_input.config.click_with_reference")) - ); - gui.open(); + gui.setSlot(4, new GuiElementBuilder(MinionItems.REFERENCE_ITEM) + .setCallback(() -> { + ItemStack cursor = parent.getViewer().currentScreenHandler.getCursorStack(); + if (cursor.isOf(MinionItems.REFERENCE_ITEM) && cursor.get(MinionComponentTypes.REFERENCE) instanceof BlockPosClipboard pos) { + future.complete(new AnalogInputSupplier(pos.world(), pos.pos())); + } + }) + .setItemName(Text.translatable("value_supplier.minions.analog_input.config.click_with_reference")) + ); + gui.open(); + return gui; + }); return future; } } diff --git a/src/main/java/io/github/skippyall/minions/module/MinionModule.java b/src/main/java/io/github/skippyall/minions/module/MinionModule.java index 15f1d6d..e7e32f9 100644 --- a/src/main/java/io/github/skippyall/minions/module/MinionModule.java +++ b/src/main/java/io/github/skippyall/minions/module/MinionModule.java @@ -2,9 +2,9 @@ package io.github.skippyall.minions.module; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import io.github.skippyall.minions.registration.MinionRegistries; import io.github.skippyall.minions.minion.MinionRuntime; import io.github.skippyall.minions.program.instruction.InstructionType; +import io.github.skippyall.minions.registration.MinionRegistries; import java.util.List; diff --git a/src/main/java/io/github/skippyall/minions/program/InstructionRuntime.java b/src/main/java/io/github/skippyall/minions/program/InstructionRuntime.java index 6765707..f1667de 100644 --- a/src/main/java/io/github/skippyall/minions/program/InstructionRuntime.java +++ b/src/main/java/io/github/skippyall/minions/program/InstructionRuntime.java @@ -1,13 +1,13 @@ package io.github.skippyall.minions.program; import com.mojang.serialization.Codec; -import io.github.skippyall.minions.program.supplier.ValueSupplier; -import io.github.skippyall.minions.program.supplier.ValueSupplierList; -import io.github.skippyall.minions.program.supplier.ValueSupplierType; -import io.github.skippyall.minions.program.instruction.InstructionType; import io.github.skippyall.minions.program.consumer.ValueConsumer; import io.github.skippyall.minions.program.consumer.ValueConsumerList; import io.github.skippyall.minions.program.consumer.ValueConsumerType; +import io.github.skippyall.minions.program.instruction.InstructionType; +import io.github.skippyall.minions.program.supplier.ValueSupplier; +import io.github.skippyall.minions.program.supplier.ValueSupplierList; +import io.github.skippyall.minions.program.supplier.ValueSupplierType; import net.minecraft.registry.Registry; public interface InstructionRuntime> { diff --git a/src/main/java/io/github/skippyall/minions/program/consumer/ValueConsumer.java b/src/main/java/io/github/skippyall/minions/program/consumer/ValueConsumer.java index 09da40b..8723e32 100644 --- a/src/main/java/io/github/skippyall/minions/program/consumer/ValueConsumer.java +++ b/src/main/java/io/github/skippyall/minions/program/consumer/ValueConsumer.java @@ -1,9 +1,9 @@ package io.github.skippyall.minions.program.consumer; import com.mojang.serialization.Codec; -import io.github.skippyall.minions.registration.MinionRegistries; import io.github.skippyall.minions.program.InstructionRuntime; import io.github.skippyall.minions.program.value.ValueType; +import io.github.skippyall.minions.registration.MinionRegistries; import org.jetbrains.annotations.Nullable; /** diff --git a/src/main/java/io/github/skippyall/minions/program/conversion/CastConverter.java b/src/main/java/io/github/skippyall/minions/program/conversion/CastConverter.java index 722570b..9238fa7 100644 --- a/src/main/java/io/github/skippyall/minions/program/conversion/CastConverter.java +++ b/src/main/java/io/github/skippyall/minions/program/conversion/CastConverter.java @@ -2,10 +2,14 @@ package io.github.skippyall.minions.program.conversion; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; +import io.github.skippyall.minions.gui.MinionsGui; +import io.github.skippyall.minions.gui.input.Result; +import io.github.skippyall.minions.program.value.TypedValue; import io.github.skippyall.minions.program.value.ValueType; import io.github.skippyall.minions.registration.MinionRegistries; import io.github.skippyall.minions.registration.ValueConverters; -import net.minecraft.server.network.ServerPlayerEntity; +import io.github.skippyall.minions.util.TranslationUtil; +import net.minecraft.text.Text; import org.jetbrains.annotations.Nullable; import java.util.concurrent.CompletableFuture; @@ -26,8 +30,8 @@ public class CastConverter implements ValueConverter { } @Override - public T convert(F fromValue) { - return Casts.getCast(from, to).cast(fromValue); + public Result convert(F fromValue) { + return Casts.castOrError(new TypedValue<>(fromValue, from), to); } @Override @@ -45,6 +49,11 @@ public class CastConverter implements ValueConverter { return ValueConverters.CAST_CONVERTER; } + @Override + public Text getDisplayText() { + return Text.translatable("value_converter.minions.cast.display", Text.translatable(TranslationUtil.getTranslationKey(from, MinionRegistries.VALUE_TYPES)), Text.translatable(TranslationUtil.getTranslationKey(to, MinionRegistries.VALUE_TYPES))); + } + public static class Type implements ValueConverterType> { @Override public MapCodec> getCodec() { @@ -57,7 +66,7 @@ public class CastConverter implements ValueConverter { } @Override - public CompletableFuture> configure(ServerPlayerEntity player, ValueType from, ValueType to, @Nullable CastConverter old) { + public CompletableFuture> configure(MinionsGui parent, ValueType from, ValueType to, @Nullable ValueConverter old) { return CompletableFuture.completedFuture(new CastConverter<>(from, to)); } } diff --git a/src/main/java/io/github/skippyall/minions/program/conversion/Casts.java b/src/main/java/io/github/skippyall/minions/program/conversion/Casts.java index 0fdf426..61c9601 100644 --- a/src/main/java/io/github/skippyall/minions/program/conversion/Casts.java +++ b/src/main/java/io/github/skippyall/minions/program/conversion/Casts.java @@ -1,7 +1,12 @@ package io.github.skippyall.minions.program.conversion; +import io.github.skippyall.minions.gui.input.Result; +import io.github.skippyall.minions.program.value.TypedValue; import io.github.skippyall.minions.program.value.ValueType; +import io.github.skippyall.minions.registration.MinionRegistries; import io.github.skippyall.minions.registration.ValueTypes; +import io.github.skippyall.minions.util.TranslationUtil; +import net.minecraft.text.Text; import org.jetbrains.annotations.Nullable; public class Casts { @@ -12,11 +17,11 @@ public class Casts { } if(from == ValueTypes.LONG && to == ValueTypes.DOUBLE) { //noinspection unchecked - return (Cast) new Cast<>(ValueTypes.LONG, ValueTypes.DOUBLE, (v) -> (double)v); + return (Cast) new Cast<>(ValueTypes.LONG, ValueTypes.DOUBLE, Long::doubleValue); } if(from == ValueTypes.DOUBLE && to == ValueTypes.LONG) { //noinspection unchecked - return (Cast) new Cast.CastCrafter<>(ValueTypes.DOUBLE, ValueTypes.LONG, (v) -> (long)(double)v).lossy().craftCast(); + return (Cast) new Cast.CastCrafter<>(ValueTypes.DOUBLE, ValueTypes.LONG, Double::longValue).lossy().craftCast(); } if((from == ValueTypes.DOUBLE || from == ValueTypes.LONG) && to == ValueTypes.STRING) { //noinspection unchecked @@ -26,6 +31,23 @@ public class Casts { return null; } + public static @Nullable T cast(TypedValue from, ValueType to) { + @Nullable Cast cast = getCast(from.type(), to); + if(cast != null) { + return cast.cast(from.value()); + } else { + return null; + } + } + + public static Result castOrError(TypedValue from, ValueType to) { + return Result.ofNullable(Casts.cast(from, to), () -> Text.translatable( + "value_converter.minions.cast.cast_failed", + from.type().getDisplayText(from.value()), + Text.translatable(TranslationUtil.getTranslationKey(to, MinionRegistries.VALUE_TYPES)) + )); + } + public static boolean canCastSafely(ValueType from, ValueType to) { if(from == to) { return true; diff --git a/src/main/java/io/github/skippyall/minions/program/conversion/ConverterList.java b/src/main/java/io/github/skippyall/minions/program/conversion/ConverterList.java new file mode 100644 index 0000000..79e0872 --- /dev/null +++ b/src/main/java/io/github/skippyall/minions/program/conversion/ConverterList.java @@ -0,0 +1,81 @@ +package io.github.skippyall.minions.program.conversion; + +import com.mojang.serialization.Codec; +import io.github.skippyall.minions.gui.input.Result; +import io.github.skippyall.minions.program.value.TypedValue; +import io.github.skippyall.minions.program.value.ValueType; +import net.minecraft.text.Text; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.ListIterator; +import java.util.Objects; + +public class ConverterList { + public static final Codec CODEC = ValueConverter.CODEC.listOf().xmap(ConverterList::new, l -> l.converters); + + private final List> converters; + + public ConverterList() { + this.converters = new ArrayList<>(); + } + + private ConverterList(List> converters) { + this.converters = new ArrayList<>(converters); + } + + public static ConverterList of(List> converters) { + return new ConverterList(new ArrayList<>(converters)); + } + + public List> getConverters() { + return converters; + } + + public ValueType getInputType() { + return converters.getFirst().getFrom(); + } + + public ValueType getOutputType() { + return converters.getLast().getTo(); + } + + public Result, Text> convert(TypedValue input) { + if(converters.isEmpty()) { + return new Result.Success<>(input); + } else { + ListIterator> iterator = converters.listIterator(); + return convert(input, iterator.next(), iterator); + } + } + + private Result, Text> convert(TypedValue from, ValueConverter converter, ListIterator> iterator) { + Result inter = Casts.castOrError(from, converter.getFrom()); + if(inter instanceof Result.Error error) { + return new Result.Error<>(Text.translatable("minions.converter.list.passing_error", iterator.previousIndex(), error.message())); + } + Result to = converter.convert(inter.getOrThrow()); + + if(iterator.hasNext() && to instanceof Result.Success success) { + return convert(new TypedValue<>(success.result(), converter.getTo()), iterator.next(), iterator); + } else { + return to.map(v -> new TypedValue<>(v, converter.getTo())); + } + } + + public Result<@Nullable Void, Text> check() { + return new Result.Success<>(null); + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof ConverterList that)) return false; + return Objects.equals(converters, that.converters); + } + + @Override + public int hashCode() { + return Objects.hashCode(converters); + } +} diff --git a/src/main/java/io/github/skippyall/minions/program/conversion/EqualityConverter.java b/src/main/java/io/github/skippyall/minions/program/conversion/EqualityConverter.java index 619ab00..7404583 100644 --- a/src/main/java/io/github/skippyall/minions/program/conversion/EqualityConverter.java +++ b/src/main/java/io/github/skippyall/minions/program/conversion/EqualityConverter.java @@ -1,16 +1,20 @@ package io.github.skippyall.minions.program.conversion; import com.mojang.serialization.MapCodec; +import io.github.skippyall.minions.gui.MinionsGui; +import io.github.skippyall.minions.gui.input.Result; import io.github.skippyall.minions.program.value.ValueType; import io.github.skippyall.minions.registration.MinionRegistries; +import io.github.skippyall.minions.registration.ValueConverters; import io.github.skippyall.minions.registration.ValueTypes; -import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.Text; import org.jetbrains.annotations.Nullable; import java.util.concurrent.CompletableFuture; public class EqualityConverter implements ValueConverter { public static final MapCodec> CODEC = MinionRegistries.VALUE_TYPES.getCodec().dispatchMap( + "value_type", EqualityConverter::getFrom, EqualityConverter::getCodec ); @@ -24,8 +28,8 @@ public class EqualityConverter implements ValueConverter { } @Override - public Boolean convert(F from) { - return compareValue.equals(from); + public Result convert(F from) { + return new Result.Success<>(compareValue.equals(from)); } @Override @@ -40,7 +44,12 @@ public class EqualityConverter implements ValueConverter { @Override public ValueConverterType getType() { - return null; + return ValueConverters.EQUALITY_CONVERTER; + } + + @Override + public Text getDisplayText() { + return Text.translatable("value_converter.minions.equality.display", fromType.getDisplayText(compareValue)); } private static MapCodec> getCodec(ValueType fromType) { @@ -60,14 +69,13 @@ public class EqualityConverter implements ValueConverter { } @Override - public CompletableFuture> configure(ServerPlayerEntity player, ValueType from, ValueType to, @Nullable EqualityConverter old) { - if(to == ValueTypes.BOOLEAN) { - //noinspection unchecked - return from.openValueDialog(player, old != null && old.fromType == from ? (F) old.compareValue : null) - .thenApply(compareValue -> new EqualityConverter<>(from, compareValue)); - } else { - return CompletableFuture.failedFuture(new IllegalArgumentException("EqualityConverter does not support converting to " + to)); + public CompletableFuture> configure(MinionsGui parent, ValueType from, ValueType to, @Nullable ValueConverter old) { + F oldValue = null; + if(old instanceof EqualityConverter eq && eq.fromType == from) { + oldValue = from.checkedCast(eq.compareValue); } + return from.openValueDialog(parent, oldValue) + .thenApply(compareValue -> new EqualityConverter<>(from, compareValue)); } } } diff --git a/src/main/java/io/github/skippyall/minions/program/conversion/ValueConverter.java b/src/main/java/io/github/skippyall/minions/program/conversion/ValueConverter.java index cf72e77..a83f12b 100644 --- a/src/main/java/io/github/skippyall/minions/program/conversion/ValueConverter.java +++ b/src/main/java/io/github/skippyall/minions/program/conversion/ValueConverter.java @@ -1,6 +1,7 @@ package io.github.skippyall.minions.program.conversion; import com.mojang.serialization.Codec; +import io.github.skippyall.minions.gui.input.Result; import io.github.skippyall.minions.program.value.ValueType; import io.github.skippyall.minions.registration.MinionRegistries; import net.minecraft.text.Text; @@ -8,7 +9,7 @@ import net.minecraft.text.Text; public interface ValueConverter { Codec> CODEC = MinionRegistries.VALUE_CONVERTER_TYPES.getCodec().dispatch(ValueConverter::getType, ValueConverterType::getCodec); - T convert(F from); + Result convert(F from); ValueType getFrom(); diff --git a/src/main/java/io/github/skippyall/minions/program/conversion/ValueConverterType.java b/src/main/java/io/github/skippyall/minions/program/conversion/ValueConverterType.java index e5ac035..af541a3 100644 --- a/src/main/java/io/github/skippyall/minions/program/conversion/ValueConverterType.java +++ b/src/main/java/io/github/skippyall/minions/program/conversion/ValueConverterType.java @@ -1,8 +1,8 @@ package io.github.skippyall.minions.program.conversion; import com.mojang.serialization.MapCodec; +import io.github.skippyall.minions.gui.MinionsGui; import io.github.skippyall.minions.program.value.ValueType; -import net.minecraft.server.network.ServerPlayerEntity; import org.jetbrains.annotations.Nullable; import java.util.concurrent.CompletableFuture; @@ -12,5 +12,5 @@ public interface ValueConverterType> { boolean isSupportedConversion(ValueType from, ValueType to); - CompletableFuture configure(ServerPlayerEntity player, ValueType from, ValueType to, @Nullable C old); + CompletableFuture configure(MinionsGui parent, ValueType from, ValueType to, @Nullable ValueConverter old); } diff --git a/src/main/java/io/github/skippyall/minions/program/instruction/ConfiguredInstruction.java b/src/main/java/io/github/skippyall/minions/program/instruction/ConfiguredInstruction.java index 999d4ef..0304894 100644 --- a/src/main/java/io/github/skippyall/minions/program/instruction/ConfiguredInstruction.java +++ b/src/main/java/io/github/skippyall/minions/program/instruction/ConfiguredInstruction.java @@ -1,12 +1,13 @@ package io.github.skippyall.minions.program.instruction; -import io.github.skippyall.minions.registration.MinionRegistries; import io.github.skippyall.minions.Minions; -import io.github.skippyall.minions.program.InstructionRuntime; -import io.github.skippyall.minions.program.supplier.Parameter; -import io.github.skippyall.minions.program.supplier.ValueSupplierList; -import io.github.skippyall.minions.program.consumer.ValueConsumerList; import io.github.skippyall.minions.listener.SerializableListenerManager; +import io.github.skippyall.minions.program.InstructionRuntime; +import io.github.skippyall.minions.program.consumer.ValueConsumerList; +import io.github.skippyall.minions.program.supplier.Parameter; +import io.github.skippyall.minions.program.supplier.ParameterValueList; +import io.github.skippyall.minions.program.supplier.ValueSupplierList; +import io.github.skippyall.minions.registration.MinionRegistries; import net.minecraft.storage.ReadView; import net.minecraft.storage.WriteView; import org.jetbrains.annotations.Nullable; @@ -22,15 +23,27 @@ public class ConfiguredInstruction> { private @Nullable InstructionExecution execution; private boolean paused = false; - private SerializableListenerManager listeners = new SerializableListenerManager<>(MinionRegistries.INSTRUCTION_LISTENER_CODECS); + private SerializableListenerManager listeners = new SerializableListenerManager<>(); - private ConfiguredInstruction(InstructionType instruction, ValueSupplierList arguments, ValueConsumerList valueConsumers, @Nullable InstructionExecution execution, SerializableListenerManager listeners, boolean paused) { + private ConfiguredInstruction( + InstructionType instruction, + ValueSupplierList arguments, + ValueConsumerList valueConsumers, + @Nullable InstructionExecution execution, + SerializableListenerManager listeners, + boolean paused + ) { this(instruction, arguments, valueConsumers, execution); this.listeners = listeners; this.paused = paused; } - private ConfiguredInstruction(InstructionType instruction, ValueSupplierList arguments, ValueConsumerList valueConsumers, @Nullable InstructionExecution execution) { + private ConfiguredInstruction( + InstructionType instruction, + ValueSupplierList arguments, + ValueConsumerList valueConsumers, + @Nullable InstructionExecution execution + ) { this.instruction = instruction; this.arguments = arguments; this.valueConsumers = valueConsumers; @@ -52,7 +65,7 @@ public class ConfiguredInstruction> { } public boolean canRun() { - return instruction != null && arguments != null && arguments.checkRun(instruction).isSuccess(); + return instruction != null && arguments != null && arguments.checkRun(instruction) == null; } public boolean isRunning() { @@ -65,8 +78,9 @@ public class ConfiguredInstruction> { public void run(R minion) { if(canRun() && !isRunning()) { + ParameterValueList resolvedArguments = arguments.resolve(minion); try { - execution = instruction.createExecution(arguments, minion); + execution = instruction.createExecution(resolvedArguments, minion); execution.start(minion); } catch (Exception e) { Minions.LOGGER.error("An error occurred while executing configured Instruction", e); @@ -132,17 +146,17 @@ public class ConfiguredInstruction> { listeners.removeListener(listener); } - public void save(WriteView view, R minion) { - view.put("instruction", minion.getInstructionTypeRegistry().getCodec(), instruction); - view.put("arguments", minion.getArgumentListCodec(), arguments); - view.put("valueConsumers", minion.getValueConsumerListCodec(), valueConsumers); + public void save(WriteView view, R runtime) { + view.put("instruction", runtime.getInstructionTypeRegistry().getCodec(), instruction); + view.put("arguments", runtime.getArgumentListCodec(), arguments); + view.put("valueConsumers", runtime.getValueConsumerListCodec(), valueConsumers); view.putBoolean("running", isRunning()); view.putBoolean("paused", paused); - if(execution != null) { - execution.save(view.get("execution"), minion); - } + view.put("listeners", SerializableListenerManager.getCodec(MinionRegistries.INSTRUCTION_LISTENER_CODECS), listeners); - listeners.save(view); + if(execution != null) { + execution.save(view.get("execution"), runtime); + } } public static > ConfiguredInstruction load(ReadView view, R minion) { @@ -154,8 +168,10 @@ public class ConfiguredInstruction> { boolean running = view.getBoolean("running", false); boolean paused = view.getBoolean("paused", false); - SerializableListenerManager listeners = new SerializableListenerManager<>(MinionRegistries.INSTRUCTION_LISTENER_CODECS); - listeners.load(view); + SerializableListenerManager listeners = view.read( + "listeners", + SerializableListenerManager.getCodec(MinionRegistries.INSTRUCTION_LISTENER_CODECS) + ).orElseGet(SerializableListenerManager::new); if(running) { ReadView executionView = view.getReadView("execution"); diff --git a/src/main/java/io/github/skippyall/minions/program/instruction/ConfiguredInstructionListener.java b/src/main/java/io/github/skippyall/minions/program/instruction/ConfiguredInstructionListener.java index f791af3..5892752 100644 --- a/src/main/java/io/github/skippyall/minions/program/instruction/ConfiguredInstructionListener.java +++ b/src/main/java/io/github/skippyall/minions/program/instruction/ConfiguredInstructionListener.java @@ -1,7 +1,7 @@ package io.github.skippyall.minions.program.instruction; -import io.github.skippyall.minions.program.supplier.Parameter; import io.github.skippyall.minions.listener.SerializableListenerManager; +import io.github.skippyall.minions.program.supplier.Parameter; public interface ConfiguredInstructionListener extends SerializableListenerManager.SerializableListener { default void onRun(ConfiguredInstruction instruction) {} diff --git a/src/main/java/io/github/skippyall/minions/program/instruction/InstructionExecution.java b/src/main/java/io/github/skippyall/minions/program/instruction/InstructionExecution.java index c3ee90e..76e0487 100644 --- a/src/main/java/io/github/skippyall/minions/program/instruction/InstructionExecution.java +++ b/src/main/java/io/github/skippyall/minions/program/instruction/InstructionExecution.java @@ -1,8 +1,9 @@ package io.github.skippyall.minions.program.instruction; import io.github.skippyall.minions.program.InstructionRuntime; -import io.github.skippyall.minions.program.supplier.ValueSupplierList; import io.github.skippyall.minions.program.consumer.ValueConsumerList; +import io.github.skippyall.minions.program.supplier.ParameterValueList; +import io.github.skippyall.minions.program.supplier.ValueSupplierList; import net.minecraft.storage.ReadView; import net.minecraft.storage.WriteView; @@ -48,7 +49,7 @@ public interface InstructionExecution> { * @param arguments The arguments to initialize the execution * @param runtime The runtime should be used to resolve the arguments */ - void readArguments(ValueSupplierList arguments, R runtime); + void readArguments(ParameterValueList arguments, R runtime); /** * Saves the execution, e.g. when the server is closed. @@ -62,7 +63,7 @@ public interface InstructionExecution> { interface Stateless> extends InstructionExecution { @Override - default void readArguments(ValueSupplierList arguments, R runtime) {} + default void readArguments(ParameterValueList arguments, R runtime) {} @Override default void save(WriteView view, R runtime) {} diff --git a/src/main/java/io/github/skippyall/minions/program/instruction/InstructionType.java b/src/main/java/io/github/skippyall/minions/program/instruction/InstructionType.java index 1852f20..2053608 100644 --- a/src/main/java/io/github/skippyall/minions/program/instruction/InstructionType.java +++ b/src/main/java/io/github/skippyall/minions/program/instruction/InstructionType.java @@ -2,7 +2,7 @@ package io.github.skippyall.minions.program.instruction; import io.github.skippyall.minions.program.InstructionRuntime; import io.github.skippyall.minions.program.supplier.Parameter; -import io.github.skippyall.minions.program.supplier.ValueSupplierList; +import io.github.skippyall.minions.program.supplier.ParameterValueList; import net.minecraft.storage.ReadView; import java.util.Collection; @@ -33,9 +33,9 @@ public class InstructionType> { return returnParameters; } - public InstructionExecution createExecution(ValueSupplierList parameters, R minion) { + public InstructionExecution createExecution(ParameterValueList arguments, R minion) { InstructionExecution execution = executionFactory.get(); - execution.readArguments(parameters, minion); + execution.readArguments(arguments, minion); return execution; } diff --git a/src/main/java/io/github/skippyall/minions/program/supplier/FixedValueSupplier.java b/src/main/java/io/github/skippyall/minions/program/supplier/FixedValueSupplier.java index f827c6d..d8a534a 100644 --- a/src/main/java/io/github/skippyall/minions/program/supplier/FixedValueSupplier.java +++ b/src/main/java/io/github/skippyall/minions/program/supplier/FixedValueSupplier.java @@ -39,6 +39,6 @@ public class FixedValueSupplier> implements V @Override public Text getDisplayText() { - return Text.translatable("value_supplier_type.minions.fixed.display", valueType.getDisplayText(value)); + return valueType.getDisplayText(value); } } diff --git a/src/main/java/io/github/skippyall/minions/program/supplier/FixedValueSupplierType.java b/src/main/java/io/github/skippyall/minions/program/supplier/FixedValueSupplierType.java index 8908367..343d433 100644 --- a/src/main/java/io/github/skippyall/minions/program/supplier/FixedValueSupplierType.java +++ b/src/main/java/io/github/skippyall/minions/program/supplier/FixedValueSupplierType.java @@ -1,9 +1,9 @@ package io.github.skippyall.minions.program.supplier; import com.mojang.serialization.Codec; +import io.github.skippyall.minions.gui.MinionsGui; import io.github.skippyall.minions.program.InstructionRuntime; import io.github.skippyall.minions.program.value.ValueType; -import net.minecraft.server.network.ServerPlayerEntity; import org.jetbrains.annotations.Nullable; import java.util.concurrent.CompletableFuture; @@ -15,10 +15,10 @@ public class FixedValueSupplierType> extends Val } @Override - public CompletableFuture> openConfiguration(ServerPlayerEntity player, ValueType valueType, @Nullable ValueSupplier previousValueSupplier) { + public CompletableFuture> openConfiguration(MinionsGui parent, ValueType valueType, @Nullable ValueSupplier previousValueSupplier) { return valueType.openValueDialog( - player, - previousValueSupplier instanceof FixedValueSupplier val ? val.getValue() : valueType.defaultValue() + parent, + previousValueSupplier instanceof FixedValueSupplier val && val.getValueType() == valueType ? valueType.checkedCast(val.getValue()) : valueType.defaultValue() ).thenApply(value -> new FixedValueSupplier<>(this, valueType, value)); } } diff --git a/src/main/java/io/github/skippyall/minions/program/supplier/Parameter.java b/src/main/java/io/github/skippyall/minions/program/supplier/Parameter.java index f2d111b..db42204 100644 --- a/src/main/java/io/github/skippyall/minions/program/supplier/Parameter.java +++ b/src/main/java/io/github/skippyall/minions/program/supplier/Parameter.java @@ -3,9 +3,8 @@ package io.github.skippyall.minions.program.supplier; import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; 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.program.value.ValueType; +import io.github.skippyall.minions.registration.MinionRegistries; import org.jetbrains.annotations.Nullable; public record Parameter(String name, ValueType type) { diff --git a/src/main/java/io/github/skippyall/minions/program/supplier/ParameterValueList.java b/src/main/java/io/github/skippyall/minions/program/supplier/ParameterValueList.java new file mode 100644 index 0000000..ad89ba2 --- /dev/null +++ b/src/main/java/io/github/skippyall/minions/program/supplier/ParameterValueList.java @@ -0,0 +1,21 @@ +package io.github.skippyall.minions.program.supplier; + +import java.util.HashMap; +import java.util.Map; + +public class ParameterValueList { + private final Map, Object> values; + + public ParameterValueList() { + values = new HashMap<>(); + } + + public T getValue(Parameter parameter) { + //noinspection unchecked + return (T) values.get(parameter); + } + + public void setValue(Parameter parameter, T value) { + values.put(parameter, value); + } +} diff --git a/src/main/java/io/github/skippyall/minions/program/supplier/ValueSupplier.java b/src/main/java/io/github/skippyall/minions/program/supplier/ValueSupplier.java index 1e56ee9..e62d4bd 100644 --- a/src/main/java/io/github/skippyall/minions/program/supplier/ValueSupplier.java +++ b/src/main/java/io/github/skippyall/minions/program/supplier/ValueSupplier.java @@ -2,9 +2,9 @@ package io.github.skippyall.minions.program.supplier; import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; -import io.github.skippyall.minions.registration.MinionRegistries; import io.github.skippyall.minions.program.InstructionRuntime; import io.github.skippyall.minions.program.value.ValueType; +import io.github.skippyall.minions.registration.MinionRegistries; import net.minecraft.text.Text; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/io/github/skippyall/minions/program/supplier/ValueSupplierList.java b/src/main/java/io/github/skippyall/minions/program/supplier/ValueSupplierList.java index a74e479..4c4a2aa 100644 --- a/src/main/java/io/github/skippyall/minions/program/supplier/ValueSupplierList.java +++ b/src/main/java/io/github/skippyall/minions/program/supplier/ValueSupplierList.java @@ -5,43 +5,40 @@ import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import io.github.skippyall.minions.gui.input.Result; import io.github.skippyall.minions.program.InstructionRuntime; -import io.github.skippyall.minions.program.conversion.Cast; import io.github.skippyall.minions.program.conversion.Casts; -import io.github.skippyall.minions.program.conversion.ValueConverter; +import io.github.skippyall.minions.program.conversion.ConverterList; import io.github.skippyall.minions.program.instruction.InstructionType; -import io.github.skippyall.minions.program.value.ValueType; +import io.github.skippyall.minions.program.value.TypedValue; import net.minecraft.text.Text; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.function.Consumer; public class ValueSupplierList> { - private final Map, ValueSupplierEntry> arguments = new HashMap<>(); + private final Map, ValueSupplierEntry> arguments = new HashMap<>(); private final List>> changeListeners = new ArrayList<>(); public ValueSupplierList() { } - private ValueSupplierList(List> arguments) { - for(ValueSupplierEntry argument : arguments) { + private ValueSupplierList(List> arguments) { + for(ValueSupplierEntry argument : arguments) { this.arguments.put(argument.parameter, argument); } } - private List> toCodecList() { + private List> toCodecList() { return List.copyOf(arguments.values()); } public T getValue(Parameter parameter, R runtime) { - ValueSupplierEntry entry = getEntry(parameter); + ValueSupplierEntry entry = getEntry(parameter); return parameter.type().checkedCast(entry.getValue(runtime)); } @@ -53,47 +50,55 @@ public class ValueSupplierList> { } } - public

ValueSupplierEntry getEntry(Parameter

parameter) { + public

ValueSupplierEntry getEntry(Parameter

parameter) { //noinspection unchecked - return (ValueSupplierEntry) arguments.get(parameter); + return (ValueSupplierEntry) arguments.get(parameter); } - public void setArgument(Parameter parameter, ValueSupplier valueSupplier) { - arguments.put(parameter, new ValueSupplierEntry<>(parameter, valueSupplier, List.of())); - onChange(parameter); + public

ValueSupplierEntry createEntry(Parameter

parameter, ValueSupplier supplier) { + ValueSupplierEntry entry = new ValueSupplierEntry<>(parameter, supplier, new ConverterList()); + arguments.put(parameter, entry); + return entry; } - public void setArgument(Parameter parameter, ValueSupplier valueSupplier, List> converter) { - arguments.put(parameter, new ValueSupplierEntry<>(parameter, valueSupplier, converter)); - onChange(parameter); + public void removeEntry(Parameter parameter) { + arguments.remove(parameter); + } + + public ParameterValueList resolve(R runtime) { + ParameterValueList list = new ParameterValueList(); + for(ValueSupplierEntry argument : arguments.values()) { + argument.addToList(list, runtime); + } + return list; } public boolean hasArgumentFor(Parameter parameter) { return arguments.containsKey(parameter); } - public Result<@Nullable Void, Text> checkHasArguments(Collection> checkParameters) { + public @Nullable Text checkHasArguments(Collection> checkParameters) { for(Parameter parameter : checkParameters) { if(!hasArgumentFor(parameter)) { - return new Result.Error<>(Text.translatable("minions.gui.instruction.check.argument_not_set", parameter.name())); + return Text.translatable("minions.gui.instruction.check.argument_not_set", parameter.name()); } } - return new Result.Success<>(null); + return null; } - public Result<@Nullable Void, Text> checkRun(InstructionType instructionType) { - Result<@Nullable Void, Text> checkResult = checkHasArguments(instructionType.getParameters()); - if(!checkResult.isSuccess()) { + public @Nullable Text checkRun(InstructionType instructionType) { + @Nullable Text checkResult = checkHasArguments(instructionType.getParameters()); + if(checkResult != null) { return checkResult; } - for(ValueSupplierEntry entry : arguments.values()) { + for(ValueSupplierEntry entry : arguments.values()) { checkResult = entry.check(); - if(!checkResult.isSuccess()) { + if(checkResult != null) { return checkResult; } } - return new Result.Success<>(null); + return null; } private void onChange(Parameter parameter) { @@ -117,18 +122,18 @@ public class ValueSupplierList> { .xmap(ValueSupplierList::new, ValueSupplierList::toCodecList); } - public static class ValueSupplierEntry> { + public static class ValueSupplierEntry> { private Parameter

parameter; - private ValueSupplier supplier; - private List> converters; + private ValueSupplier supplier; + private ConverterList converters; - public ValueSupplierEntry(Parameter

parameter, ValueSupplier supplier, Collection> converters) { + public ValueSupplierEntry(Parameter

parameter, ValueSupplier supplier, ConverterList converters) { this.parameter = parameter; this.supplier = supplier; - this.converters = new LinkedList<>(converters); + this.converters = converters; } - public List> getConverters() { + public ConverterList getConverters() { return converters; } @@ -136,7 +141,7 @@ public class ValueSupplierList> { return parameter; } - public ValueSupplier getSupplier() { + public ValueSupplier getSupplier() { return supplier; } @@ -144,64 +149,36 @@ public class ValueSupplierList> { this.parameter = parameter; } - public void setSupplier(ValueSupplier supplier) { + public void setSupplier(ValueSupplier supplier) { this.supplier = supplier; } - public void setConverters(List> converters) { - this.converters = converters; + private void addToList(ParameterValueList list, R runtime) { + list.setValue(parameter, getValue(runtime)); } public @Nullable P getValue(R runtime) { - S value = supplier.resolve(runtime); - Iterator> iterator = converters.iterator(); - Object convertedValue = convert(supplier.getValueType(), value, iterator.next(), iterator); - - return finalCast(convertedValue); + return getValue(supplier, runtime); } - private @Nullable P finalCast(Object value) { - //noinspection unchecked - ValueType lastConvertedType = (ValueType) converters.getLast().getTo(); - F convertedValue = lastConvertedType.checkedCast(value); - if(convertedValue == null) { - return null; - } + //Ich liebe generische Typen (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) + private @Nullable P getValue(ValueSupplier supplier, R runtime) { + S value = supplier.resolve(runtime); + Result, Text> convertedResult = converters.convert(new TypedValue<>(value, supplier.getValueType())); - Cast cast = Casts.getCast(lastConvertedType, parameter.type()); - if(cast != null) { - return cast.cast(convertedValue); - } + return convertedResult.flatMap(convertedValue -> Casts.castOrError(convertedValue, parameter.type())).getOrDefault(null); + } + + public @Nullable Text check() { + //TODO check it return null; } - private @Nullable Object convert(ValueType fromType, F from, ValueConverter converter, Iterator> iterator) { - Cast cast = Casts.getCast(fromType, converter.getFrom()); - if(cast == null) { - return null; - } - I inter = cast.cast(from); - if(inter == null) { - return null; - } - T to = converter.convert(inter); - - if(iterator.hasNext() && to != null) { - return convert(converter.getTo(), to, iterator.next(), iterator); - } else { - return to; - } - } - - public Result<@Nullable Void, Text> check() { - return new Result.Success<>(null); - } - - public static > MapCodec> getCodec(Codec> argumentCodec) { + public static > MapCodec> getCodec(Codec> argumentCodec) { return RecordCodecBuilder.mapCodec(instance -> instance.group( Parameter.CODEC.fieldOf("parameter").forGetter(e -> e.parameter), argumentCodec.fieldOf("argument").forGetter(e -> e.supplier), - ValueConverter.CODEC.listOf().optionalFieldOf("converter", List.of()).forGetter(e -> e.converters) + ConverterList.CODEC.fieldOf("converter").forGetter(e -> e.converters) ).apply(instance, ValueSupplierEntry::new)); } } diff --git a/src/main/java/io/github/skippyall/minions/program/supplier/ValueSupplierType.java b/src/main/java/io/github/skippyall/minions/program/supplier/ValueSupplierType.java index 0d79c3f..7ea95cc 100644 --- a/src/main/java/io/github/skippyall/minions/program/supplier/ValueSupplierType.java +++ b/src/main/java/io/github/skippyall/minions/program/supplier/ValueSupplierType.java @@ -1,9 +1,9 @@ package io.github.skippyall.minions.program.supplier; import com.mojang.serialization.Codec; +import io.github.skippyall.minions.gui.MinionsGui; import io.github.skippyall.minions.program.InstructionRuntime; import io.github.skippyall.minions.program.value.ValueType; -import net.minecraft.server.network.ServerPlayerEntity; import org.jetbrains.annotations.Nullable; import java.util.concurrent.CompletableFuture; @@ -11,5 +11,5 @@ import java.util.concurrent.CompletableFuture; public abstract class ValueSupplierType> { public abstract Codec> getCodec(ValueType type); - public abstract CompletableFuture> openConfiguration(ServerPlayerEntity player, ValueType valueType, @Nullable ValueSupplier previous); + public abstract CompletableFuture> openConfiguration(MinionsGui gui, ValueType valueType, @Nullable ValueSupplier previous); } diff --git a/src/main/java/io/github/skippyall/minions/program/value/RestrictionRule.java b/src/main/java/io/github/skippyall/minions/program/value/RestrictionRule.java deleted file mode 100644 index 79eda44..0000000 --- a/src/main/java/io/github/skippyall/minions/program/value/RestrictionRule.java +++ /dev/null @@ -1,12 +0,0 @@ -package io.github.skippyall.minions.program.value; - -import io.github.skippyall.minions.gui.input.Result; -import net.minecraft.text.Text; - -public interface RestrictionRule { - Result validate(T value); - - default boolean matches(T value) { - return validate(value).isSuccess(); - } -} diff --git a/src/main/java/io/github/skippyall/minions/program/value/SimpleValueType.java b/src/main/java/io/github/skippyall/minions/program/value/SimpleValueType.java index 62ff567..e9ce4cf 100644 --- a/src/main/java/io/github/skippyall/minions/program/value/SimpleValueType.java +++ b/src/main/java/io/github/skippyall/minions/program/value/SimpleValueType.java @@ -1,18 +1,17 @@ package io.github.skippyall.minions.program.value; import com.mojang.serialization.Codec; -import net.minecraft.server.network.ServerPlayerEntity; +import io.github.skippyall.minions.gui.MinionsGui; 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(Codec codec, T defaultValue, Function checkedCast, BiFunction> valueDialogOpener, Function textDisplay) implements ValueType { +public record SimpleValueType(Codec codec, T defaultValue, Function checkedCast, BiFunction> valueDialogOpener, Function textDisplay) implements ValueType { @Override - public CompletableFuture openValueDialog(ServerPlayerEntity player, T previousValue) { - return valueDialogOpener.apply(player, previousValue); + public CompletableFuture openValueDialog(MinionsGui parent, T previousValue) { + return valueDialogOpener.apply(parent, previousValue); } @Override diff --git a/src/main/java/io/github/skippyall/minions/program/value/TypeRestriction.java b/src/main/java/io/github/skippyall/minions/program/value/TypeRestriction.java deleted file mode 100644 index 4e747a4..0000000 --- a/src/main/java/io/github/skippyall/minions/program/value/TypeRestriction.java +++ /dev/null @@ -1,6 +0,0 @@ -package io.github.skippyall.minions.program.value; - -import java.util.Collection; - -public record TypeRestriction(ValueType type, Collection> rules) { -} diff --git a/src/main/java/io/github/skippyall/minions/program/value/TypedValue.java b/src/main/java/io/github/skippyall/minions/program/value/TypedValue.java new file mode 100644 index 0000000..b1608cd --- /dev/null +++ b/src/main/java/io/github/skippyall/minions/program/value/TypedValue.java @@ -0,0 +1,7 @@ +package io.github.skippyall.minions.program.value; + +public record TypedValue(T value, ValueType type) { + public static TypedValue of(Object o, ValueType type) { + return new TypedValue<>(type.checkedCast(o), type); + } +} diff --git a/src/main/java/io/github/skippyall/minions/program/value/ValueType.java b/src/main/java/io/github/skippyall/minions/program/value/ValueType.java index 9feb2fe..091620c 100644 --- a/src/main/java/io/github/skippyall/minions/program/value/ValueType.java +++ b/src/main/java/io/github/skippyall/minions/program/value/ValueType.java @@ -1,16 +1,14 @@ package io.github.skippyall.minions.program.value; import com.mojang.serialization.Codec; -import net.minecraft.server.network.ServerPlayerEntity; +import io.github.skippyall.minions.gui.MinionsGui; 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 interface ValueType { - CompletableFuture openValueDialog(ServerPlayerEntity player, T previousValue); + CompletableFuture openValueDialog(MinionsGui gui, T previousValue); Text getDisplayText(T value); diff --git a/src/main/java/io/github/skippyall/minions/registration/ClipboardTypes.java b/src/main/java/io/github/skippyall/minions/registration/ClipboardTypes.java index 7eb4e4a..a66cecf 100644 --- a/src/main/java/io/github/skippyall/minions/registration/ClipboardTypes.java +++ b/src/main/java/io/github/skippyall/minions/registration/ClipboardTypes.java @@ -3,8 +3,8 @@ package io.github.skippyall.minions.registration; import com.mojang.serialization.MapCodec; 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.Clipboard; +import io.github.skippyall.minions.clipboard.InstructionClipboard; import net.minecraft.registry.Registry; import net.minecraft.util.Identifier; diff --git a/src/main/java/io/github/skippyall/minions/registration/Instructions.java b/src/main/java/io/github/skippyall/minions/registration/Instructions.java index 92b1440..e78faf6 100644 --- a/src/main/java/io/github/skippyall/minions/registration/Instructions.java +++ b/src/main/java/io/github/skippyall/minions/registration/Instructions.java @@ -1,17 +1,17 @@ package io.github.skippyall.minions.registration; -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.InstructionType; import io.github.skippyall.minions.Minions; import io.github.skippyall.minions.minion.MinionRuntime; import io.github.skippyall.minions.minion.fakeplayer.EntityPlayerActionPack; import io.github.skippyall.minions.minion.program.instruction.ActionExecution; import io.github.skippyall.minions.minion.program.instruction.MineBlockExecution; +import io.github.skippyall.minions.minion.program.instruction.inventory.SwapItemExecution; import io.github.skippyall.minions.minion.program.instruction.move.ContinuousWalkExecution; import io.github.skippyall.minions.minion.program.instruction.move.TurnExecution; import io.github.skippyall.minions.minion.program.instruction.move.TurnVectorExecution; import io.github.skippyall.minions.minion.program.instruction.move.WalkExecution; +import io.github.skippyall.minions.program.instruction.InstructionExecution; +import io.github.skippyall.minions.program.instruction.InstructionType; import io.github.skippyall.minions.program.supplier.Parameter; import net.minecraft.registry.Registry; import net.minecraft.util.Identifier; diff --git a/src/main/java/io/github/skippyall/minions/registration/MinionBlocks.java b/src/main/java/io/github/skippyall/minions/registration/MinionBlocks.java index 06c2b9b..29cf009 100644 --- a/src/main/java/io/github/skippyall/minions/registration/MinionBlocks.java +++ b/src/main/java/io/github/skippyall/minions/registration/MinionBlocks.java @@ -9,7 +9,6 @@ import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityT import net.minecraft.block.AbstractBlock; import net.minecraft.block.entity.BlockEntityType; import net.minecraft.block.piston.PistonBehavior; -import net.minecraft.network.packet.CustomPayload; import net.minecraft.registry.Registries; import net.minecraft.registry.Registry; import net.minecraft.registry.RegistryKey; diff --git a/src/main/java/io/github/skippyall/minions/registration/MinionComponentTypes.java b/src/main/java/io/github/skippyall/minions/registration/MinionComponentTypes.java index 7eee3d8..b952fbf 100644 --- a/src/main/java/io/github/skippyall/minions/registration/MinionComponentTypes.java +++ b/src/main/java/io/github/skippyall/minions/registration/MinionComponentTypes.java @@ -2,8 +2,8 @@ package io.github.skippyall.minions.registration; import eu.pb4.polymer.core.api.other.PolymerComponent; import io.github.skippyall.minions.Minions; -import io.github.skippyall.minions.module.MinionModule; import io.github.skippyall.minions.clipboard.Clipboard; +import io.github.skippyall.minions.module.MinionModule; import net.fabricmc.fabric.api.item.v1.ComponentTooltipAppenderRegistry; import net.minecraft.component.ComponentType; import net.minecraft.registry.Registries; diff --git a/src/main/java/io/github/skippyall/minions/registration/MinionItems.java b/src/main/java/io/github/skippyall/minions/registration/MinionItems.java index f6b09c6..cf5916d 100644 --- a/src/main/java/io/github/skippyall/minions/registration/MinionItems.java +++ b/src/main/java/io/github/skippyall/minions/registration/MinionItems.java @@ -3,12 +3,12 @@ package io.github.skippyall.minions.registration; import eu.pb4.polymer.core.api.item.PolymerBlockItem; import eu.pb4.polymer.core.api.item.SimplePolymerItem; import io.github.skippyall.minions.block.miniontrigger.MinionTriggerBlockItem; +import io.github.skippyall.minions.clipboard.ClipboardItem; import io.github.skippyall.minions.minion.MinionItem; import io.github.skippyall.minions.minion.MinionRuntime; import io.github.skippyall.minions.module.MinionModule; import io.github.skippyall.minions.module.SpecialAbility; import io.github.skippyall.minions.program.instruction.InstructionType; -import io.github.skippyall.minions.clipboard.ClipboardItem; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.DamageResistantComponent; import net.minecraft.entity.damage.DamageType; diff --git a/src/main/java/io/github/skippyall/minions/registration/MinionRegistries.java b/src/main/java/io/github/skippyall/minions/registration/MinionRegistries.java index 3468bac..d3e7515 100644 --- a/src/main/java/io/github/skippyall/minions/registration/MinionRegistries.java +++ b/src/main/java/io/github/skippyall/minions/registration/MinionRegistries.java @@ -3,6 +3,7 @@ package io.github.skippyall.minions.registration; import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import io.github.skippyall.minions.Minions; +import io.github.skippyall.minions.clipboard.Clipboard; import io.github.skippyall.minions.docs.DocsEntry; import io.github.skippyall.minions.docs.ReferenceEntry; import io.github.skippyall.minions.gui.GuiDisplay; @@ -11,13 +12,12 @@ import io.github.skippyall.minions.minion.MinionListener; import io.github.skippyall.minions.minion.MinionRuntime; import io.github.skippyall.minions.minion.skin.SkinProvider; import io.github.skippyall.minions.module.SpecialAbility; -import io.github.skippyall.minions.program.instruction.ConfiguredInstructionListener; -import io.github.skippyall.minions.program.supplier.ValueSupplierType; -import io.github.skippyall.minions.program.instruction.InstructionType; import io.github.skippyall.minions.program.consumer.ValueConsumerType; -import io.github.skippyall.minions.program.value.ValueType; -import io.github.skippyall.minions.clipboard.Clipboard; import io.github.skippyall.minions.program.conversion.ValueConverterType; +import io.github.skippyall.minions.program.instruction.ConfiguredInstructionListener; +import io.github.skippyall.minions.program.instruction.InstructionType; +import io.github.skippyall.minions.program.supplier.ValueSupplierType; +import io.github.skippyall.minions.program.value.ValueType; import net.fabricmc.fabric.api.event.registry.DynamicRegistries; import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder; import net.fabricmc.fabric.api.event.registry.RegistryAttribute; @@ -27,16 +27,16 @@ import net.minecraft.util.Identifier; public class MinionRegistries { public static final Registry> VALUE_TYPES = registry("value_type"); - public static final Registry> VALUE_SUPPLIER_TYPES = registry("value_supplier_type"); - public static final Registry> VALUE_CONSUMER_TYPES = registry("value_consumer_type"); - public static final Registry> INSTRUCTION_TYPES = registry("instruction_type"); - public static final Registry> VALUE_CONVERTER_TYPES = registry("value_converter_type"); + public static final Registry> VALUE_SUPPLIER_TYPES = registry("value_supplier"); + public static final Registry> VALUE_CONSUMER_TYPES = registry("value_consumer"); + public static final Registry> INSTRUCTION_TYPES = registry("instruction"); + public static final Registry> VALUE_CONVERTER_TYPES = registry("value_converter"); public static final Registry SKIN_PROVIDERS = registry("skin_provider"); public static final Registry> GUI_DISPLAY_TYPE = registry("gui_display_type"); public static final Registry> INSTRUCTION_LISTENER_CODECS = registry("instruction_listener_codec"); public static final Registry> MINION_LISTENER_CODECS = registry("minion_listener_codec"); - public static final Registry> CLIPBOARD_TYPES = registry("clipboard_type"); + public static final Registry> CLIPBOARD_TYPES = registry("clipboard"); public static final Registry SPECIAL_ABILITIES = registry("special_ability"); public static final Registry> MINION_CONFIG_OPTIONS = registry("minion_config_option"); public static final Registry> DOCS_ENTRY_TYPES = registry("docs_entry_type"); diff --git a/src/main/java/io/github/skippyall/minions/registration/SkinProviders.java b/src/main/java/io/github/skippyall/minions/registration/SkinProviders.java index 125424c..5ba2c1c 100644 --- a/src/main/java/io/github/skippyall/minions/registration/SkinProviders.java +++ b/src/main/java/io/github/skippyall/minions/registration/SkinProviders.java @@ -1,10 +1,10 @@ package io.github.skippyall.minions.registration; +import io.github.skippyall.minions.Minions; import io.github.skippyall.minions.minion.skin.Base64SkinProvider; import io.github.skippyall.minions.minion.skin.NameSkinProvider; import io.github.skippyall.minions.minion.skin.SkinProvider; import io.github.skippyall.minions.minion.skin.UUIDSkinProvider; -import io.github.skippyall.minions.Minions; import net.minecraft.registry.Registry; import net.minecraft.util.Identifier; diff --git a/src/main/java/io/github/skippyall/minions/registration/SpecialAbilities.java b/src/main/java/io/github/skippyall/minions/registration/SpecialAbilities.java index 2e9af45..152f53b 100644 --- a/src/main/java/io/github/skippyall/minions/registration/SpecialAbilities.java +++ b/src/main/java/io/github/skippyall/minions/registration/SpecialAbilities.java @@ -1,7 +1,7 @@ package io.github.skippyall.minions.registration; -import io.github.skippyall.minions.module.MobSpawningAbility; import io.github.skippyall.minions.Minions; +import io.github.skippyall.minions.module.MobSpawningAbility; import io.github.skippyall.minions.module.SpecialAbility; import net.minecraft.registry.Registry; import net.minecraft.util.Identifier; diff --git a/src/main/java/io/github/skippyall/minions/registration/ValueConverters.java b/src/main/java/io/github/skippyall/minions/registration/ValueConverters.java index 900f247..fb56ad2 100644 --- a/src/main/java/io/github/skippyall/minions/registration/ValueConverters.java +++ b/src/main/java/io/github/skippyall/minions/registration/ValueConverters.java @@ -8,8 +8,8 @@ import net.minecraft.registry.Registry; import net.minecraft.util.Identifier; public class ValueConverters { - public static final EqualityConverter.EqualityConverterType EQUALITY_CONVERTER = register("equality_converter", new EqualityConverter.EqualityConverterType()); - public static final CastConverter.Type CAST_CONVERTER = register("cast_converter", new CastConverter.Type()); + public static final EqualityConverter.EqualityConverterType EQUALITY_CONVERTER = register("equality", new EqualityConverter.EqualityConverterType()); + public static final CastConverter.Type CAST_CONVERTER = register("cast", new CastConverter.Type()); private static > T register(String name, T type) { return Registry.register(MinionRegistries.VALUE_CONVERTER_TYPES, Identifier.of(Minions.MOD_ID, name), type); diff --git a/src/main/java/io/github/skippyall/minions/registration/ValueSuppliers.java b/src/main/java/io/github/skippyall/minions/registration/ValueSuppliers.java index acd3fa9..2b5884c 100644 --- a/src/main/java/io/github/skippyall/minions/registration/ValueSuppliers.java +++ b/src/main/java/io/github/skippyall/minions/registration/ValueSuppliers.java @@ -1,10 +1,10 @@ package io.github.skippyall.minions.registration; +import io.github.skippyall.minions.Minions; +import io.github.skippyall.minions.minion.MinionRuntime; import io.github.skippyall.minions.minion.program.supplier.AnalogInputSupplier; import io.github.skippyall.minions.program.supplier.FixedValueSupplierType; import io.github.skippyall.minions.program.supplier.ValueSupplierType; -import io.github.skippyall.minions.Minions; -import io.github.skippyall.minions.minion.MinionRuntime; import net.minecraft.registry.Registry; import net.minecraft.util.Identifier; diff --git a/src/main/java/io/github/skippyall/minions/registration/ValueTypes.java b/src/main/java/io/github/skippyall/minions/registration/ValueTypes.java index 164890a..4c65e98 100644 --- a/src/main/java/io/github/skippyall/minions/registration/ValueTypes.java +++ b/src/main/java/io/github/skippyall/minions/registration/ValueTypes.java @@ -1,16 +1,17 @@ package io.github.skippyall.minions.registration; 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.Minions; -import io.github.skippyall.minions.gui.input.ChoiceInput; import io.github.skippyall.minions.gui.input.TextInput; import io.github.skippyall.minions.minion.program.instruction.move.TurnDirection; +import io.github.skippyall.minions.program.value.SimpleValueType; +import io.github.skippyall.minions.program.value.ValueType; import net.minecraft.registry.Registry; import net.minecraft.text.Text; import net.minecraft.util.Identifier; +import java.util.concurrent.CompletableFuture; + public class ValueTypes { public static ValueType LONG = register( "long", @@ -18,8 +19,8 @@ public class ValueTypes { Codec.LONG, 0L, o -> o instanceof Long l ? l : null, - (player, oldValue) -> TextInput.inputLong( - player, + (parent, oldValue) -> TextInput.inputLong( + parent, Text.literal("Integer"), String.valueOf(oldValue) ), @@ -33,8 +34,8 @@ public class ValueTypes { Codec.DOUBLE, 0D, o -> o instanceof Double d ? d : null, - (player, oldValue) -> TextInput.inputDouble( - player, + (parent, oldValue) -> TextInput.inputDouble( + parent, Text.literal("Number"), String.valueOf(oldValue) ), @@ -48,7 +49,8 @@ public class ValueTypes { Codec.BOOL, false, o -> o instanceof Boolean b ? b : null, - ChoiceInput.inputBoolean(Text.literal("")), + //TODO Properly implement ChoiceInput + (gui, value) -> CompletableFuture.completedFuture(value),//ChoiceInput.inputBoolean(Text.literal("")), value -> Text.literal(value.toString()) ) ); @@ -59,8 +61,8 @@ public class ValueTypes { Codec.STRING, "", o -> o instanceof String s ? s : null, - ((player, oldValue) -> TextInput.inputString( - player, + ((parent, oldValue) -> TextInput.inputString( + parent, Text.literal("Text"), oldValue) ), @@ -74,7 +76,8 @@ public class ValueTypes { TurnDirection.CODEC, TurnDirection.RIGHT, o -> o instanceof TurnDirection d ? d : null, - ChoiceInput.createDialogOpener(TurnDirection.values()), + //TODO Properly implement ChoiceInput + (parent, oldValue) -> CompletableFuture.completedFuture(oldValue), // ChoiceInput.createDialogOpener(TurnDirection.values()), value -> Text.literal(value.name) ) ); diff --git a/src/main/resources/TODO.txt b/src/main/resources/TODO.txt deleted file mode 100644 index 9a3bffb..0000000 --- a/src/main/resources/TODO.txt +++ /dev/null @@ -1,35 +0,0 @@ -- Module: - - Bewegungsmodul <-- - - Angriffsmodul <-- - - Abbaumodul <-- - - Platziermodul / Verwendungsmodul <-- - - Werfmodul - - Inventarmanagementmodul <-- - - Inventaropenmodul - -- Detektoren: - - Blockdetektor <-- - - Entitydetektor < - - Dimensiondetektor - - Positiondetektor - - Inventardetektor - -- Programmieren: - - Variablen - - (Listen) - - Warten - - Wiederholen - - Wiederhole bis/während - - Wiederhole x mal/(für jedes Element) - - Bedingung - -- VariableTypen: - - Integer - - String - - Position - - Block - - BlockType - - (NBT) - - (World) - - (Chunk) - - Inventory diff --git a/src/main/resources/data/minions/lang/en_us.json b/src/main/resources/assets/minions/lang/en_us.json similarity index 65% rename from src/main/resources/data/minions/lang/en_us.json rename to src/main/resources/assets/minions/lang/en_us.json index 8dfc25f..549fbd3 100644 --- a/src/main/resources/data/minions/lang/en_us.json +++ b/src/main/resources/assets/minions/lang/en_us.json @@ -9,6 +9,7 @@ "minions.gui.confirm": "Confirm", "minions.gui.abort": "Abort", "minions.gui.back": "Back", + "minions.gui.not_set": "Not set", "minions.gui.look.skin.name": "Name", "minions.gui.look.skin.name.title": "Enter a player name", @@ -35,13 +36,24 @@ "minions.gui.instruction.configure.copy.description": "Click here and then use a Minion Trigger Block to bind it", "minions.gui.instruction.run": "Run", "minions.gui.instruction.stop": "Stop", - "minions.gui.instruction.argument.configure.type": "Type: %s", - "minions.gui.instruction.argument.configure.type.unset": "Unset", + "minions.gui.instruction.argument.title": "Argument for %s (%s)", + "minions.gui.instruction.argument.configure.type": "Argument Type", + "minions.gui.instruction.argument.configure.type.title": "Select an Argument Type", + "minions.gui.instruction.argument.configure.data": "Argument Data", + "minions.gui.instruction.argument.configure.data.title": "Configure Argument Data", "minions.gui.instruction.parameter": "%s: %s", "minions.gui.instruction.argument": "Argument: %s", "minions.gui.instruction.check.argument_not_set": "Argument %s is not set", + "minions.gui.instruction.converters": "Converters", + "minions.gui.instruction.converters.cast": "Cast from %s to %s", + "minions.gui.instruction.converter.title": "Configure Converter", + "minions.gui.instruction.converter.type.title": "Select a Converter Type", + "minions.gui.instruction.converter.data": "Converter Data", + + "minions.converter.list.passing_error": "Error while passing previous value to converter #%s: %s", + "minions.command.input.int.fail": "Not an integer", "minions.command.input.float.fail": "Not a number", "minions.command.action.details": "Set how to %s", @@ -60,25 +72,33 @@ "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.description": "Walk forward a specified amount of blocks", - "instruction_type.minions.turn": "Turn", - "instruction_type.minions.turn.description": "Turn the head by specific angle", - "instruction_type.minions.attack": "Attack", - "instruction_type.minions.attack.description": "Attack and mine blocks\n Test", - "instruction_type.minions.use": "Use", - "instruction_type.minions.use.description": "Use and place blocks", + "instruction.minions.walk": "Walk", + "instruction.minions.walk.description": "Walk forward a specified amount of blocks", + "instruction.minions.turn": "Turn", + "instruction.minions.turn.description": "Turn the head by specific angle", + "instruction.minions.attack": "Attack", + "instruction.minions.attack.description": "Attack and mine blocks\n Test", + "instruction.minions.use": "Use", + "instruction.minions.use.description": "Use and place blocks", + "instruction.minions.swap_item": "Swap Items", - "value_type.minions.integer": "Integer", - "value_type.minions.float": "Decimal", + "value_type.minions.long": "Integer", + "value_type.minions.double": "Decimal", + "value_type.minions.boolean": "Boolean", "value_type.minions.string": "Text", "value_type.minions.turn_direction": "Turn Direction", - "value_supplier_type.minions.fixed": "Fixed Value", - "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", + "value_supplier.minions.fixed": "Fixed Value", + "value_supplier.minions.analog_input": "Analog Input", + "value_supplier.minions.analog_input.display": "Analog Input at %s in %s", + "value_supplier.minions.analog_input.config.click_with_reference": "Click here with a position clipboard", + + "value_converter.minions.cast.display": "Cast from %s to %s", + "value_converter.minions.cast.cast_failed": "Cast of value %s to %s failed", + "value_converter.minions.equality.display": "Equal to %s", + + "value_converter.minions.equality": "Equality", + "value_converter.minions.cast": "Cast", "item.minions.attack_module": "Attack Module", "item.minions.interact_module": "Interact Module", diff --git a/src/main/resources/data/minions/minions/gui_display/instruction_type/attack.json b/src/main/resources/data/minions/minions/gui_display/instruction/attack.json similarity index 100% rename from src/main/resources/data/minions/minions/gui_display/instruction_type/attack.json rename to src/main/resources/data/minions/minions/gui_display/instruction/attack.json diff --git a/src/main/resources/data/minions/minions/gui_display/instruction_type/mine_block.json b/src/main/resources/data/minions/minions/gui_display/instruction/mine_block.json similarity index 100% rename from src/main/resources/data/minions/minions/gui_display/instruction_type/mine_block.json rename to src/main/resources/data/minions/minions/gui_display/instruction/mine_block.json diff --git a/src/main/resources/data/minions/minions/gui_display/instruction/swap_item.json b/src/main/resources/data/minions/minions/gui_display/instruction/swap_item.json new file mode 100644 index 0000000..c1164bd --- /dev/null +++ b/src/main/resources/data/minions/minions/gui_display/instruction/swap_item.json @@ -0,0 +1,4 @@ +{ + "type": "minions:item", + "data": "minecraft:chest" +} \ No newline at end of file diff --git a/src/main/resources/data/minions/minions/gui_display/instruction_type/turn.json b/src/main/resources/data/minions/minions/gui_display/instruction/turn.json similarity index 100% rename from src/main/resources/data/minions/minions/gui_display/instruction_type/turn.json rename to src/main/resources/data/minions/minions/gui_display/instruction/turn.json diff --git a/src/main/resources/data/minions/minions/gui_display/instruction_type/turn_vector.json b/src/main/resources/data/minions/minions/gui_display/instruction/turn_vector.json similarity index 100% rename from src/main/resources/data/minions/minions/gui_display/instruction_type/turn_vector.json rename to src/main/resources/data/minions/minions/gui_display/instruction/turn_vector.json diff --git a/src/main/resources/data/minions/minions/gui_display/instruction_type/use.json b/src/main/resources/data/minions/minions/gui_display/instruction/use.json similarity index 100% rename from src/main/resources/data/minions/minions/gui_display/instruction_type/use.json rename to src/main/resources/data/minions/minions/gui_display/instruction/use.json diff --git a/src/main/resources/data/minions/minions/gui_display/instruction_type/walk.json b/src/main/resources/data/minions/minions/gui_display/instruction/walk.json similarity index 100% rename from src/main/resources/data/minions/minions/gui_display/instruction_type/walk.json rename to src/main/resources/data/minions/minions/gui_display/instruction/walk.json diff --git a/src/main/resources/data/minions/minions/gui_display/instruction_type/walk_continuous.json b/src/main/resources/data/minions/minions/gui_display/instruction/walk_continuous.json similarity index 100% rename from src/main/resources/data/minions/minions/gui_display/instruction_type/walk_continuous.json rename to src/main/resources/data/minions/minions/gui_display/instruction/walk_continuous.json diff --git a/src/main/resources/data/minions/minions/gui_display/value_converter/cast.json b/src/main/resources/data/minions/minions/gui_display/value_converter/cast.json new file mode 100644 index 0000000..f53b224 --- /dev/null +++ b/src/main/resources/data/minions/minions/gui_display/value_converter/cast.json @@ -0,0 +1,11 @@ +{ + "type": "minions:stack", + "data": { + "id": "minecraft:player_head", + "components": { + "minecraft:profile": { + "name": "CastCrafter" + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/data/minions/minions/gui_display/value_converter/equality.json b/src/main/resources/data/minions/minions/gui_display/value_converter/equality.json new file mode 100644 index 0000000..79506f9 --- /dev/null +++ b/src/main/resources/data/minions/minions/gui_display/value_converter/equality.json @@ -0,0 +1,4 @@ +{ + "type": "minions:item", + "data": "minecraft:comparator" +} \ No newline at end of file diff --git a/src/main/resources/data/minions/minions/gui_display/value_supplier/analog_input.json b/src/main/resources/data/minions/minions/gui_display/value_supplier/analog_input.json new file mode 100644 index 0000000..79506f9 --- /dev/null +++ b/src/main/resources/data/minions/minions/gui_display/value_supplier/analog_input.json @@ -0,0 +1,4 @@ +{ + "type": "minions:item", + "data": "minecraft:comparator" +} \ No newline at end of file diff --git a/src/main/resources/data/minions/minions/gui_display/value_supplier_type/fixed.json b/src/main/resources/data/minions/minions/gui_display/value_supplier/fixed.json similarity index 100% rename from src/main/resources/data/minions/minions/gui_display/value_supplier_type/fixed.json rename to src/main/resources/data/minions/minions/gui_display/value_supplier/fixed.json diff --git a/src/main/resources/data/minions/minions/gui_display/value_type/boolean.json b/src/main/resources/data/minions/minions/gui_display/value_type/boolean.json new file mode 100644 index 0000000..ae2a2a4 --- /dev/null +++ b/src/main/resources/data/minions/minions/gui_display/value_type/boolean.json @@ -0,0 +1,4 @@ +{ + "type": "minions:item", + "data": "minecraft:lever" +} \ No newline at end of file