Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f8eb1578b2 | |||
| 48a38b87c5 |
@@ -1,6 +1,7 @@
|
|||||||
# User-specific stuff
|
# User-specific stuff
|
||||||
.idea/
|
.idea/
|
||||||
urlaub/
|
urlaub/
|
||||||
|
.kotlin/
|
||||||
|
|
||||||
*.iml
|
*.iml
|
||||||
*.ipr
|
*.ipr
|
||||||
|
|||||||
+1
-1
@@ -51,7 +51,7 @@ public abstract class InstructionBoundBlock extends Block implements EntityBlock
|
|||||||
}
|
}
|
||||||
|
|
||||||
world.getBlockEntity(pos, getBlockEntityType()).ifPresent(be -> {
|
world.getBlockEntity(pos, getBlockEntityType()).ifPresent(be -> {
|
||||||
String name = MinionPersistentState.get(world.getServer()).getMinionData(be.getMinionUuid()).name();
|
String name = MinionPersistentState.get(world.getServer()).getMinionData(be.getMinionUuid()).getName();
|
||||||
player.sendSystemMessage(Component.translatable("minions.reference.instruction.tooltip", be.getInstructionName(), name));
|
player.sendSystemMessage(Component.translatable("minions.reference.instruction.tooltip", be.getInstructionName(), name));
|
||||||
});
|
});
|
||||||
return InteractionResult.SUCCESS;
|
return InteractionResult.SUCCESS;
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public class ListSubcommand {
|
|||||||
public static int list(CommandContext<CommandSourceStack> context) {
|
public static int list(CommandContext<CommandSourceStack> context) {
|
||||||
Collection<MinionData> minions = MinionPersistentState.get(context.getSource().getServer()).getMinionData().values();
|
Collection<MinionData> minions = MinionPersistentState.get(context.getSource().getServer()).getMinionData().values();
|
||||||
for (MinionData minion : minions) {
|
for (MinionData minion : minions) {
|
||||||
context.getSource().sendSuccess(() -> Component.literal(minion.name() + "(" + minion.uuid() + "):" + minion.isSpawned()), false);
|
context.getSource().sendSuccess(() -> Component.literal(minion.getName() + "(" + minion.getUuid() + "):" + minion.isSpawned()), false);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public class MinionArgument {
|
|||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Suggestions> getSuggestions(CommandContext<CommandSourceStack> context, SuggestionsBuilder builder) throws CommandSyntaxException {
|
public CompletableFuture<Suggestions> getSuggestions(CommandContext<CommandSourceStack> context, SuggestionsBuilder builder) throws CommandSyntaxException {
|
||||||
for (MinionData data : MinionPersistentState.get(context.getSource().getServer()).getMinionDataList()) {
|
for (MinionData data : MinionPersistentState.get(context.getSource().getServer()).getMinionDataList()) {
|
||||||
builder.suggest(data.name());
|
builder.suggest(data.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.buildFuture();
|
return builder.buildFuture();
|
||||||
|
|||||||
@@ -27,9 +27,10 @@ import java.util.UUID;
|
|||||||
public interface GuiDisplay {
|
public interface GuiDisplay {
|
||||||
Codec<GuiDisplay> CODEC = MinionRegistries.GUI_DISPLAY_TYPE.byNameCodec().dispatch(GuiDisplay::getCodec, codec -> codec.fieldOf("data"));
|
Codec<GuiDisplay> CODEC = MinionRegistries.GUI_DISPLAY_TYPE.byNameCodec().dispatch(GuiDisplay::getCodec, codec -> codec.fieldOf("data"));
|
||||||
GuiDisplay DEFAULT_DISPLAY = new ItemBased(Items.BARRIER);
|
GuiDisplay DEFAULT_DISPLAY = new ItemBased(Items.BARRIER);
|
||||||
TooltipDisplay TOOLTIP_DISPLAY = createTooltipDisplay();
|
|
||||||
|
|
||||||
private static TooltipDisplay createTooltipDisplay() {
|
TooltipDisplay TOOLTIP_HIDE_ALL_COMPONENTS = createHideAllTooltip();
|
||||||
|
|
||||||
|
private static TooltipDisplay createHideAllTooltip() {
|
||||||
LinkedHashSet<DataComponentType<?>> set = new LinkedHashSet<>();
|
LinkedHashSet<DataComponentType<?>> set = new LinkedHashSet<>();
|
||||||
for(DataComponentType<?> type : BuiltInRegistries.DATA_COMPONENT_TYPE) {
|
for(DataComponentType<?> type : BuiltInRegistries.DATA_COMPONENT_TYPE) {
|
||||||
if(type != DataComponents.LORE) {
|
if(type != DataComponents.LORE) {
|
||||||
@@ -106,7 +107,7 @@ public interface GuiDisplay {
|
|||||||
@Override
|
@Override
|
||||||
public ItemStackTemplate createItemStackTemplate() {
|
public ItemStackTemplate createItemStackTemplate() {
|
||||||
return new ItemStackTemplate(item, DataComponentPatch.builder()
|
return new ItemStackTemplate(item, DataComponentPatch.builder()
|
||||||
.set(DataComponents.TOOLTIP_DISPLAY, TOOLTIP_DISPLAY)
|
.set(DataComponents.TOOLTIP_DISPLAY, TOOLTIP_HIDE_ALL_COMPONENTS)
|
||||||
.set(DataComponents.RARITY, Rarity.COMMON)
|
.set(DataComponents.RARITY, Rarity.COMMON)
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
@@ -130,6 +131,7 @@ public interface GuiDisplay {
|
|||||||
public ItemStackTemplate createItemStackTemplate() {
|
public ItemStackTemplate createItemStackTemplate() {
|
||||||
return new ItemStackTemplate(Items.PLAYER_HEAD, DataComponentPatch.builder()
|
return new ItemStackTemplate(Items.PLAYER_HEAD, DataComponentPatch.builder()
|
||||||
.set(DataComponents.PROFILE, ResolvableProfile.createUnresolved(uuid))
|
.set(DataComponents.PROFILE, ResolvableProfile.createUnresolved(uuid))
|
||||||
|
.set(DataComponents.TOOLTIP_DISPLAY, TOOLTIP_HIDE_ALL_COMPONENTS)
|
||||||
.build()
|
.build()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import io.github.skippyall.minions.minion.MinionProfileUtils
|
|||||||
import io.github.skippyall.minions.minion.skin.SkinProvider
|
import io.github.skippyall.minions.minion.skin.SkinProvider
|
||||||
import io.github.skippyall.minions.registration.MinionRegistries
|
import io.github.skippyall.minions.registration.MinionRegistries
|
||||||
import io.github.skippyall.minions.registration.SkinProviders
|
import io.github.skippyall.minions.registration.SkinProviders
|
||||||
|
import kotlinx.coroutines.future.await
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import net.fabricmc.fabric.api.entity.FakePlayer
|
import net.fabricmc.fabric.api.entity.FakePlayer
|
||||||
import net.minecraft.core.component.DataComponents
|
import net.minecraft.core.component.DataComponents
|
||||||
@@ -20,8 +21,6 @@ import net.minecraft.world.item.ItemStack
|
|||||||
import net.minecraft.world.item.Items
|
import net.minecraft.world.item.Items
|
||||||
import net.minecraft.world.item.component.ResolvableProfile
|
import net.minecraft.world.item.component.ResolvableProfile
|
||||||
import java.util.Optional
|
import java.util.Optional
|
||||||
import java.util.function.Consumer
|
|
||||||
import java.util.function.Function
|
|
||||||
|
|
||||||
class MinionLookGui(
|
class MinionLookGui(
|
||||||
viewer: ServerPlayer,
|
viewer: ServerPlayer,
|
||||||
@@ -82,20 +81,24 @@ class MinionLookGui(
|
|||||||
gui.setSlot(16, builder)
|
gui.setSlot(16, builder)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun updateSkinProvider() {
|
||||||
|
gui.setSlot(
|
||||||
|
25, GuiElementBuilder()
|
||||||
|
.setItem(Items.GREEN_STAINED_GLASS_PANE)
|
||||||
|
.setComponent(DataComponents.CUSTOM_NAME, currentSkinProvider.getDisplayName())
|
||||||
|
.setCallback(Runnable { this.cycleSkinProvider() })
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun openSkinGui() {
|
fun openSkinGui() {
|
||||||
currentSkinProvider.openSkinMenu(this)
|
scope.launch {
|
||||||
.thenCompose(Function { profile: ResolvableProfile? ->
|
val profile = currentSkinProvider.openSkinMenu(this@MinionLookGui).await()
|
||||||
profile!!.resolveProfile(
|
val skin = profile.resolveProfile(viewer.level().server.services().profileResolver()).await()
|
||||||
viewer.level().server.services().profileResolver()
|
|
||||||
)
|
data.skin = Optional.ofNullable(skin?.properties())
|
||||||
})
|
|
||||||
.thenAccept(Consumer { skin: GameProfile? ->
|
updateSkin()
|
||||||
MinionItem.setData(
|
}
|
||||||
viewer.level().server, this.data.withSkin(
|
|
||||||
Optional.of(skin!!.properties())
|
|
||||||
), minionItem
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun cycleSkinProvider() {
|
private fun cycleSkinProvider() {
|
||||||
@@ -109,15 +112,6 @@ class MinionLookGui(
|
|||||||
updateSkinProvider()
|
updateSkinProvider()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateSkinProvider() {
|
|
||||||
gui.setSlot(
|
|
||||||
25, GuiElementBuilder()
|
|
||||||
.setItem(Items.GREEN_STAINED_GLASS_PANE)
|
|
||||||
.setComponent(DataComponents.CUSTOM_NAME, currentSkinProvider.getDisplayName())
|
|
||||||
.setCallback(Runnable { this.cycleSkinProvider() })
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun openRenameGui() {
|
fun openRenameGui() {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
val newName = TextInput.input(
|
val newName = TextInput.input(
|
||||||
@@ -126,10 +120,11 @@ class MinionLookGui(
|
|||||||
"Minion",
|
"Minion",
|
||||||
) { name ->
|
) { name ->
|
||||||
MinionProfileUtils.checkMinionNameWithoutPrefix(viewer.level().server, name)
|
MinionProfileUtils.checkMinionNameWithoutPrefix(viewer.level().server, name)
|
||||||
}
|
}.await()
|
||||||
|
|
||||||
if(newName != null) {
|
if(newName != null) {
|
||||||
this@MinionLookGui.data.withName(newName)
|
data.name = newName
|
||||||
|
updateName()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ abstract class MinionsGui {
|
|||||||
|
|
||||||
protected abstract fun open()
|
protected abstract fun open()
|
||||||
|
|
||||||
protected fun reopen() {
|
protected open fun reopen() {
|
||||||
open()
|
open()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,26 +4,26 @@ import eu.pb4.sgui.api.elements.GuiElementBuilder
|
|||||||
import eu.pb4.sgui.api.gui.SimpleGui
|
import eu.pb4.sgui.api.gui.SimpleGui
|
||||||
import io.github.skippyall.minions.gui.MinionsGui
|
import io.github.skippyall.minions.gui.MinionsGui
|
||||||
import io.github.skippyall.minions.gui.minion.SimpleMinionsGui
|
import io.github.skippyall.minions.gui.minion.SimpleMinionsGui
|
||||||
import kotlinx.coroutines.CompletableDeferred
|
|
||||||
import kotlinx.coroutines.future.asCompletableFuture
|
|
||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
import net.minecraft.world.inventory.MenuType
|
import net.minecraft.world.inventory.MenuType
|
||||||
import net.minecraft.world.item.Items
|
import net.minecraft.world.item.Items
|
||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
|
|
||||||
object BooleanInput {
|
object BooleanInput {
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
fun confirm(
|
fun confirm(
|
||||||
parent: MinionsGui,
|
parent: MinionsGui,
|
||||||
title: Component,
|
title: Component,
|
||||||
falseText: Component = Component.translatable("minions.gui.abort"),
|
falseText: Component = Component.translatable("minions.gui.abort"),
|
||||||
trueText: Component = Component.translatable("minions.gui.confirm")
|
trueText: Component = Component.translatable("minions.gui.confirm")
|
||||||
): CompletableDeferred<Boolean> {
|
): CompletableFuture<Boolean> {
|
||||||
val deferred = CompletableDeferred<Boolean>()
|
val future = CompletableFuture<Boolean>()
|
||||||
|
|
||||||
SimpleMinionsGui(parent) { onClose: Runnable, me: SimpleMinionsGui ->
|
SimpleMinionsGui(parent) { onClose: Runnable, me: SimpleMinionsGui ->
|
||||||
val gui: SimpleGui = object : SimpleGui(MenuType.GENERIC_3x3, parent.viewer, false) {
|
val gui: SimpleGui = object : SimpleGui(MenuType.GENERIC_3x3, parent.viewer, false) {
|
||||||
override fun onPlayerClose(success: Boolean) {
|
override fun onPlayerClose(success: Boolean) {
|
||||||
deferred.complete(false)
|
future.complete(false)
|
||||||
onClose.run()
|
onClose.run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -33,7 +33,7 @@ object BooleanInput {
|
|||||||
3, GuiElementBuilder(Items.REDSTONE_BLOCK)
|
3, GuiElementBuilder(Items.REDSTONE_BLOCK)
|
||||||
.setName(falseText)
|
.setName(falseText)
|
||||||
.setCallback(Runnable {
|
.setCallback(Runnable {
|
||||||
deferred.complete(false)
|
future.complete(false)
|
||||||
me.goBack()
|
me.goBack()
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
@@ -42,7 +42,7 @@ object BooleanInput {
|
|||||||
5, GuiElementBuilder(Items.EMERALD_BLOCK)
|
5, GuiElementBuilder(Items.EMERALD_BLOCK)
|
||||||
.setName(trueText)
|
.setName(trueText)
|
||||||
.setCallback(Runnable {
|
.setCallback(Runnable {
|
||||||
deferred.complete(true)
|
future.complete(true)
|
||||||
me.goBack()
|
me.goBack()
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
@@ -50,22 +50,6 @@ object BooleanInput {
|
|||||||
gui.open()
|
gui.open()
|
||||||
gui
|
gui
|
||||||
}
|
}
|
||||||
return deferred
|
return future
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
@JvmOverloads
|
|
||||||
fun confirmFuture(
|
|
||||||
parent: MinionsGui,
|
|
||||||
title: Component,
|
|
||||||
falseText: Component = Component.translatable("minions.gui.abort"),
|
|
||||||
trueText: Component = Component.translatable("minions.gui.confirm")
|
|
||||||
): CompletableFuture<Boolean> {
|
|
||||||
return confirm(
|
|
||||||
parent,
|
|
||||||
title,
|
|
||||||
falseText,
|
|
||||||
trueText
|
|
||||||
).asCompletableFuture()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,7 @@ import java.util.function.Consumer;
|
|||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public interface Result<T, E> {
|
public sealed interface Result<T, E> permits Result.Success, Result.Error {
|
||||||
static <T> Result<T, String> wrap(UnsafeOperation<T> toWrap) {
|
static <T> Result<T, String> wrap(UnsafeOperation<T> toWrap) {
|
||||||
return wrapCustomError(toWrap, Exception::getMessage);
|
return wrapCustomError(toWrap, Exception::getMessage);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,6 @@ package io.github.skippyall.minions.gui.input
|
|||||||
import eu.pb4.sgui.api.elements.GuiElementBuilder
|
import eu.pb4.sgui.api.elements.GuiElementBuilder
|
||||||
import eu.pb4.sgui.api.gui.AnvilInputGui
|
import eu.pb4.sgui.api.gui.AnvilInputGui
|
||||||
import io.github.skippyall.minions.gui.MinionsGui
|
import io.github.skippyall.minions.gui.MinionsGui
|
||||||
import kotlinx.coroutines.CompletableDeferred
|
|
||||||
import kotlinx.coroutines.Deferred
|
|
||||||
import kotlinx.coroutines.future.asCompletableFuture
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
import net.minecraft.world.inventory.AnvilMenu
|
import net.minecraft.world.inventory.AnvilMenu
|
||||||
@@ -29,10 +26,9 @@ class TextInput<T>(
|
|||||||
private lateinit var gui: AnvilInputGui
|
private lateinit var gui: AnvilInputGui
|
||||||
|
|
||||||
private var result: Result<T, Component>? = null
|
private var result: Result<T, Component>? = null
|
||||||
val deferred = CompletableDeferred<T?>()
|
val future = CompletableFuture<T?>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
updateConfirmButton(defaultValue)
|
|
||||||
open()
|
open()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,14 +40,15 @@ class TextInput<T>(
|
|||||||
|
|
||||||
override fun onPlayerClose(success: Boolean) {
|
override fun onPlayerClose(success: Boolean) {
|
||||||
onBackingClosed()
|
onBackingClosed()
|
||||||
if (deferred.isActive) {
|
if (!future.isDone) {
|
||||||
deferred.complete(null)
|
future.complete(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gui.setTitle(title)
|
gui.setTitle(title)
|
||||||
gui.setDefaultInputValue(defaultValue)
|
gui.setDefaultInputValue(defaultValue)
|
||||||
|
updateConfirmButton(defaultValue)
|
||||||
gui.open()
|
gui.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,7 +71,8 @@ class TextInput<T>(
|
|||||||
|
|
||||||
fun onConfirm() {
|
fun onConfirm() {
|
||||||
result?.ifSuccess { success: T ->
|
result?.ifSuccess { success: T ->
|
||||||
deferred.complete(success)
|
future.complete(success)
|
||||||
|
goBack()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +83,7 @@ class TextInput<T>(
|
|||||||
title: Component,
|
title: Component,
|
||||||
defaultValue: String,
|
defaultValue: String,
|
||||||
parser: suspend (String) -> Result<T, Component>,
|
parser: suspend (String) -> Result<T, Component>,
|
||||||
): Deferred<T?> {
|
): CompletableFuture<T?> {
|
||||||
val input = TextInput(
|
val input = TextInput(
|
||||||
parent = gui,
|
parent = gui,
|
||||||
title = title,
|
title = title,
|
||||||
@@ -93,22 +91,7 @@ class TextInput<T>(
|
|||||||
parser = parser,
|
parser = parser,
|
||||||
)
|
)
|
||||||
|
|
||||||
return input.deferred
|
return input.future
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun <T>inputFuture(
|
|
||||||
gui: MinionsGui,
|
|
||||||
title: Component,
|
|
||||||
defaultValue: String,
|
|
||||||
parser: (String) -> Result<T, Component>,
|
|
||||||
): CompletableFuture<T?> {
|
|
||||||
return input(
|
|
||||||
gui = gui,
|
|
||||||
title = title,
|
|
||||||
defaultValue = defaultValue,
|
|
||||||
parser = parser
|
|
||||||
).asCompletableFuture()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@@ -116,7 +99,7 @@ class TextInput<T>(
|
|||||||
gui: MinionsGui,
|
gui: MinionsGui,
|
||||||
title: Component,
|
title: Component,
|
||||||
defaultValue: String,
|
defaultValue: String,
|
||||||
): Deferred<String?> {
|
): CompletableFuture<String?> {
|
||||||
return input<String>(
|
return input<String>(
|
||||||
gui = gui,
|
gui = gui,
|
||||||
title = title,
|
title = title,
|
||||||
@@ -125,25 +108,12 @@ class TextInput<T>(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun inputStringFuture(
|
|
||||||
gui: MinionsGui,
|
|
||||||
title: Component,
|
|
||||||
defaultValue: String,
|
|
||||||
): CompletableFuture<String?> {
|
|
||||||
return inputString(
|
|
||||||
gui = gui,
|
|
||||||
title = title,
|
|
||||||
defaultValue = defaultValue,
|
|
||||||
).asCompletableFuture()
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun inputLong(
|
fun inputLong(
|
||||||
gui: MinionsGui,
|
gui: MinionsGui,
|
||||||
title: Component,
|
title: Component,
|
||||||
defaultValue: Long,
|
defaultValue: Long,
|
||||||
): Deferred<Long?> {
|
): CompletableFuture<Long?> {
|
||||||
return input<Long>(
|
return input<Long>(
|
||||||
gui = gui,
|
gui = gui,
|
||||||
title = title,
|
title = title,
|
||||||
@@ -157,25 +127,12 @@ class TextInput<T>(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun inputLongFuture(
|
|
||||||
gui: MinionsGui,
|
|
||||||
title: Component,
|
|
||||||
defaultValue: Long,
|
|
||||||
): CompletableFuture<Long?> {
|
|
||||||
return inputLong(
|
|
||||||
gui = gui,
|
|
||||||
title = title,
|
|
||||||
defaultValue = defaultValue,
|
|
||||||
).asCompletableFuture()
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun inputDouble(
|
fun inputDouble(
|
||||||
gui: MinionsGui,
|
gui: MinionsGui,
|
||||||
title: Component,
|
title: Component,
|
||||||
defaultValue: Double,
|
defaultValue: Double,
|
||||||
): Deferred<Double?> {
|
): CompletableFuture<Double?> {
|
||||||
return input<Double>(
|
return input<Double>(
|
||||||
gui = gui,
|
gui = gui,
|
||||||
title = title,
|
title = title,
|
||||||
@@ -188,18 +145,5 @@ class TextInput<T>(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun inputDoubleFuture(
|
|
||||||
gui: MinionsGui,
|
|
||||||
title: Component,
|
|
||||||
defaultValue: Double,
|
|
||||||
): CompletableFuture<Double?> {
|
|
||||||
return inputDouble(
|
|
||||||
gui = gui,
|
|
||||||
title = title,
|
|
||||||
defaultValue = defaultValue,
|
|
||||||
).asCompletableFuture()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import io.github.skippyall.minions.gui.MinionsGui;
|
|||||||
import io.github.skippyall.minions.gui.PaginatedList;
|
import io.github.skippyall.minions.gui.PaginatedList;
|
||||||
import io.github.skippyall.minions.gui.minion.GuiContext;
|
import io.github.skippyall.minions.gui.minion.GuiContext;
|
||||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
|
||||||
import io.github.skippyall.minions.program.instruction.ConfiguredInstruction;
|
import io.github.skippyall.minions.program.instruction.ConfiguredInstruction;
|
||||||
import io.github.skippyall.minions.program.supplier.Parameter;
|
import io.github.skippyall.minions.program.supplier.Parameter;
|
||||||
import io.github.skippyall.minions.program.supplier.ValueSupplier;
|
import io.github.skippyall.minions.program.supplier.ValueSupplier;
|
||||||
|
|||||||
+1
-1
@@ -60,7 +60,7 @@ public class ConfigureInstructionGui extends MinionsGui implements ConfiguredIns
|
|||||||
|
|
||||||
gui.setSlot(7, new GuiElementBuilder(Items.LAVA_BUCKET)
|
gui.setSlot(7, new GuiElementBuilder(Items.LAVA_BUCKET)
|
||||||
.setName(Component.translatable("minions.gui.instruction.configure.delete"))
|
.setName(Component.translatable("minions.gui.instruction.configure.delete"))
|
||||||
.setCallback(() -> BooleanInput.confirmFuture(this, Component.translatable("minions.gui.instruction.configure.delete.confirm", name))
|
.setCallback(() -> BooleanInput.confirm(this, Component.translatable("minions.gui.instruction.configure.delete.confirm", name))
|
||||||
.thenAccept((confirmed) -> {
|
.thenAccept((confirmed) -> {
|
||||||
if(confirmed) {
|
if(confirmed) {
|
||||||
minion.getInstructionManager().removeInstruction(name);
|
minion.getInstructionManager().removeInstruction(name);
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ public class ConverterGui extends MinionsGui {
|
|||||||
|
|
||||||
public ConverterGui(MinionsGui parent, @Nullable ValueConverter<?,?> converter, ValueType<?> from, ValueType<?> to, ConverterList list, boolean isNew, int index) {
|
public ConverterGui(MinionsGui parent, @Nullable ValueConverter<?,?> converter, ValueType<?> from, ValueType<?> to, ConverterList list, boolean isNew, int index) {
|
||||||
super(parent);
|
super(parent);
|
||||||
open();
|
|
||||||
this.converter = converter;
|
this.converter = converter;
|
||||||
if(converter != null) {
|
if(converter != null) {
|
||||||
this.valueConverterType = converter.getType();
|
this.valueConverterType = converter.getType();
|
||||||
@@ -38,6 +37,8 @@ public class ConverterGui extends MinionsGui {
|
|||||||
this.list = list;
|
this.list = list;
|
||||||
this.isNew = isNew;
|
this.isNew = isNew;
|
||||||
this.index = index;
|
this.index = index;
|
||||||
|
|
||||||
|
open();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public class ConverterListGui extends MinionsGui {
|
|||||||
|
|
||||||
gui.setSlot(23, new GuiElementBuilder(Items.ARROW)
|
gui.setSlot(23, new GuiElementBuilder(Items.ARROW)
|
||||||
.setCallback(() -> {
|
.setCallback(() -> {
|
||||||
if(page * 4 + 4 < converters.getConverters().size()) {
|
if(page * 4 + 4 < converters.getConverters().size() + 1) {
|
||||||
page++;
|
page++;
|
||||||
updateConverters();
|
updateConverters();
|
||||||
}
|
}
|
||||||
@@ -67,6 +67,10 @@ public class ConverterListGui extends MinionsGui {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void updateConverters() {
|
public void updateConverters() {
|
||||||
|
for(int slot = 9; slot < 18; slot++) {
|
||||||
|
gui.clearSlot(slot);
|
||||||
|
}
|
||||||
|
|
||||||
int lastConverter = Math.min(5, converters.getConverters().size() + 2 - page * 4);
|
int lastConverter = Math.min(5, converters.getConverters().size() + 2 - page * 4);
|
||||||
for(int i = 0; i < lastConverter; i++) {
|
for(int i = 0; i < lastConverter; i++) {
|
||||||
//Each page has 5 converters, but the last is displayed on the next page as well
|
//Each page has 5 converters, but the last is displayed on the next page as well
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ public class InstructionGui {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static CompletableFuture<String> inputInstructionName(MinionsGui parent, GuiContext.Minion context, String defaultValue) {
|
public static CompletableFuture<String> inputInstructionName(MinionsGui parent, GuiContext.Minion context, String defaultValue) {
|
||||||
return TextInput.inputFuture(parent, Component.translatable("minions.gui.instruction.enter_name"), defaultValue, name -> {
|
return TextInput.input(parent, Component.translatable("minions.gui.instruction.enter_name"), defaultValue, (name, _) -> {
|
||||||
if (context.getMinion().getInstructionManager().hasInstruction(name)) {
|
if (context.getMinion().getInstructionManager().hasInstruction(name)) {
|
||||||
return new Result.Error<>(Component.translatable("minions.gui.instruction.name_already_used"));
|
return new Result.Error<>(Component.translatable("minions.gui.instruction.name_already_used"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
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.level.ServerPlayer;
|
|
||||||
|
|
||||||
public interface GuiContext {
|
|
||||||
ServerPlayer getViewer();
|
|
||||||
|
|
||||||
static GuiContext create(ServerPlayer 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<MinionRuntime> getInstruction();
|
|
||||||
|
|
||||||
String getName();
|
|
||||||
|
|
||||||
void setName(String name);
|
|
||||||
|
|
||||||
static GuiContext.Instruction create(GuiContext.Minion context, ConfiguredInstruction<MinionRuntime> 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package io.github.skippyall.minions.gui.minion
|
||||||
|
|
||||||
|
import io.github.skippyall.minions.gui.minion.GuiContextImpl.*
|
||||||
|
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.level.ServerPlayer
|
||||||
|
|
||||||
|
interface GuiContext {
|
||||||
|
val viewer: ServerPlayer
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
fun create(viewer: ServerPlayer): GuiContext {
|
||||||
|
return GuiContextImpl(viewer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Minion : GuiContext {
|
||||||
|
val minion: MinionFakePlayer
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
fun create(context: GuiContext, minion: MinionFakePlayer): Minion {
|
||||||
|
return MinionImpl(
|
||||||
|
if(context is MinionImpl) context.context else context,
|
||||||
|
minion
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Instruction : Minion {
|
||||||
|
val instruction: ConfiguredInstruction<MinionRuntime>
|
||||||
|
|
||||||
|
var name: String
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
fun create(context: Minion, instruction: ConfiguredInstruction<MinionRuntime>, name: String): Instruction {
|
||||||
|
return InstructionImpl(
|
||||||
|
if(context is InstructionImpl) context.context else context,
|
||||||
|
instruction,
|
||||||
|
name
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ValueSupplier : Instruction {
|
||||||
|
val parameter: Parameter<*>
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
fun create(context: Instruction, parameter: Parameter<*>): ValueSupplier {
|
||||||
|
return ValueSupplierImpl(
|
||||||
|
if(context is ValueSupplierImpl) context.context else context,
|
||||||
|
parameter
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
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.level.ServerPlayer;
|
|
||||||
|
|
||||||
//If only this mod was kotlin
|
|
||||||
public class GuiContextImpl implements GuiContext {
|
|
||||||
private final ServerPlayer viewer;
|
|
||||||
|
|
||||||
public GuiContextImpl(ServerPlayer viewer) {
|
|
||||||
this.viewer = viewer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ServerPlayer getViewer() {
|
|
||||||
return viewer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class MinionImpl extends DelegatingGuiContextImpl<GuiContext> implements GuiContext.Minion {
|
|
||||||
private final MinionFakePlayer minion;
|
|
||||||
|
|
||||||
public MinionImpl(GuiContext context, MinionFakePlayer minion) {
|
|
||||||
super(context instanceof DelegatingGuiContextImpl<?> impl ? impl.context : context);
|
|
||||||
this.minion = minion;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MinionFakePlayer getMinion() {
|
|
||||||
return minion;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class InstructionImpl extends DelegatingMinionImpl<GuiContext.Minion> implements GuiContext.Instruction {
|
|
||||||
private final ConfiguredInstruction<MinionRuntime> instruction;
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
public InstructionImpl(GuiContext.Minion context, ConfiguredInstruction<MinionRuntime> instruction, String name) {
|
|
||||||
super(context instanceof DelegatingMinionImpl<?> impl ? impl.context : context);
|
|
||||||
this.instruction = instruction;
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ConfiguredInstruction<MinionRuntime> getInstruction() {
|
|
||||||
return instruction;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class ValueSupplierImpl extends DelegatingInstructionImpl<GuiContext.Instruction> implements GuiContext.ValueSupplier {
|
|
||||||
private final Parameter<?> parameter;
|
|
||||||
|
|
||||||
public ValueSupplierImpl(GuiContext.Instruction context, Parameter<?> parameter) {
|
|
||||||
super(context instanceof DelegatingInstructionImpl<?> impl ? impl.context : context);
|
|
||||||
this.parameter = parameter;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Parameter<?> getParameter() {
|
|
||||||
return parameter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class DelegatingGuiContextImpl<C extends GuiContext> implements GuiContext {
|
|
||||||
protected final C context;
|
|
||||||
|
|
||||||
public DelegatingGuiContextImpl(C context) {
|
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ServerPlayer getViewer() {
|
|
||||||
return context.getViewer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class DelegatingMinionImpl<C extends GuiContext.Minion> extends DelegatingGuiContextImpl<C> implements GuiContext.Minion {
|
|
||||||
public DelegatingMinionImpl(C context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MinionFakePlayer getMinion() {
|
|
||||||
return context.getMinion();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class DelegatingInstructionImpl<C extends GuiContext.Instruction> extends DelegatingMinionImpl<C> implements GuiContext.Instruction {
|
|
||||||
public DelegatingInstructionImpl(C context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ConfiguredInstruction<MinionRuntime> getInstruction() {
|
|
||||||
return context.getInstruction();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return context.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setName(String name) {
|
|
||||||
context.setName(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
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.level.ServerPlayer
|
||||||
|
|
||||||
|
//Thank you kotlin
|
||||||
|
class GuiContextImpl(override val viewer: ServerPlayer) : GuiContext {
|
||||||
|
class MinionImpl(
|
||||||
|
val context: GuiContext,
|
||||||
|
override val minion: MinionFakePlayer
|
||||||
|
) : GuiContext by context, GuiContext.Minion
|
||||||
|
|
||||||
|
class InstructionImpl(
|
||||||
|
val context: GuiContext.Minion,
|
||||||
|
override val instruction: ConfiguredInstruction<MinionRuntime>,
|
||||||
|
override var name: String
|
||||||
|
) : GuiContext.Minion by context, GuiContext.Instruction
|
||||||
|
|
||||||
|
class ValueSupplierImpl(
|
||||||
|
val context: GuiContext.Instruction,
|
||||||
|
override val parameter: Parameter<*>
|
||||||
|
) : GuiContext.Instruction by context, GuiContext.ValueSupplier
|
||||||
|
}
|
||||||
@@ -47,7 +47,7 @@ public abstract class BlockEntityMinionListener<E extends BlockEntity> implement
|
|||||||
|
|
||||||
public static <T extends BlockEntityMinionListener<?>> T getListener(Level world, BlockPos pos, UUID minionUuid, Class<T> clazz) {
|
public static <T extends BlockEntityMinionListener<?>> T getListener(Level world, BlockPos pos, UUID minionUuid, Class<T> clazz) {
|
||||||
if(minionUuid != null) {
|
if(minionUuid != null) {
|
||||||
for (MinionListener listener : MinionPersistentState.get(world.getServer()).getMinionData(minionUuid).listeners()) {
|
for (MinionListener listener : MinionPersistentState.get(world.getServer()).getMinionData(minionUuid).getListeners()) {
|
||||||
if (listener instanceof BlockEntityMinionListener<?> tl && tl.pos.equals(pos) && tl.worldKey.equals(world.dimension()) && clazz.isInstance(tl)) {
|
if (listener instanceof BlockEntityMinionListener<?> tl && tl.pos.equals(pos) && tl.worldKey.equals(world.dimension()) && clazz.isInstance(tl)) {
|
||||||
return clazz.cast(tl);
|
return clazz.cast(tl);
|
||||||
}
|
}
|
||||||
@@ -95,13 +95,13 @@ public abstract class BlockEntityMinionListener<E extends BlockEntity> implement
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void add(MinecraftServer server) {
|
public void add(MinecraftServer server) {
|
||||||
MinionPersistentState.get(server).getMinionData(minionUuid).listeners().addListener(this);
|
MinionPersistentState.get(server).getMinionData(minionUuid).getListeners().addListener(this);
|
||||||
MinionPersistentState.get(server).setDirty();
|
MinionPersistentState.get(server).setDirty();
|
||||||
this.minion = (MinionFakePlayer) server.getPlayerList().getPlayer(minionUuid);
|
this.minion = (MinionFakePlayer) server.getPlayerList().getPlayer(minionUuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove(MinecraftServer server) {
|
public void remove(MinecraftServer server) {
|
||||||
MinionPersistentState.get(server).getMinionData(minionUuid).listeners().removeListener(this);
|
MinionPersistentState.get(server).getMinionData(minionUuid).getListeners().removeListener(this);
|
||||||
MinionPersistentState.get(server).setDirty();
|
MinionPersistentState.get(server).setDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
package io.github.skippyall.minions.listener;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
|
||||||
|
|
||||||
public class ListenerManager<T> implements Iterable<T> {
|
|
||||||
protected final Set<T> listeners;
|
|
||||||
|
|
||||||
public ListenerManager() {
|
|
||||||
this(new CopyOnWriteArraySet<>());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected ListenerManager(Set<T> listeners) {
|
|
||||||
this.listeners = listeners;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addListener(T listener) {
|
|
||||||
listeners.add(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeListener(T listener) {
|
|
||||||
listeners.remove(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull Iterator<T> iterator() {
|
|
||||||
return listeners.iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
return super.equals(obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package io.github.skippyall.minions.listener
|
||||||
|
|
||||||
|
import java.util.concurrent.CopyOnWriteArraySet
|
||||||
|
|
||||||
|
open class ListenerManager<T>(
|
||||||
|
protected val listeners: MutableSet<T> = CopyOnWriteArraySet(),
|
||||||
|
val onChange: () -> Unit = {},
|
||||||
|
) : MutableIterable<T> by listeners {
|
||||||
|
|
||||||
|
fun addListener(listener: T) {
|
||||||
|
listeners.add(listener)
|
||||||
|
onChange()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeListener(listener: T) {
|
||||||
|
listeners.remove(listener)
|
||||||
|
onChange()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun iterator(): MutableIterator<T> {
|
||||||
|
val iterator = listeners.iterator()
|
||||||
|
return object : MutableIterator<T> by iterator {
|
||||||
|
override fun remove() {
|
||||||
|
iterator.remove()
|
||||||
|
onChange()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package io.github.skippyall.minions.listener;
|
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
|
||||||
import com.mojang.serialization.MapCodec;
|
|
||||||
import net.minecraft.core.Registry;
|
|
||||||
import net.minecraft.resources.Identifier;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
|
||||||
|
|
||||||
public class SerializableListenerManager<T extends SerializableListenerManager.SerializableListener> extends ListenerManager<T> {
|
|
||||||
public SerializableListenerManager() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected SerializableListenerManager(Set<T> listeners) {
|
|
||||||
super(listeners);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T extends SerializableListener> Codec<SerializableListenerManager<T>> getCodec(Registry<Codec<? extends T>> registry) {
|
|
||||||
return registry.byNameCodec().<T>dispatch(
|
|
||||||
listener -> listener.getCodecId().map(registry::getValue).orElse(MapCodec.unitCodec(null)),
|
|
||||||
codec -> codec.fieldOf("data")
|
|
||||||
).listOf().xmap(
|
|
||||||
list -> new SerializableListenerManager<>(new CopyOnWriteArraySet<>(list)),
|
|
||||||
manager -> {
|
|
||||||
List<T> serializableListeners = new ArrayList<>();
|
|
||||||
for(T listener : manager.listeners) {
|
|
||||||
if(listener.getCodecId().isPresent()) {
|
|
||||||
serializableListeners.add(listener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return serializableListeners;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface SerializableListener {
|
|
||||||
default Optional<Identifier> getCodecId() {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package io.github.skippyall.minions.listener
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec
|
||||||
|
import com.mojang.serialization.MapCodec
|
||||||
|
import io.github.skippyall.minions.listener.SerializableListenerManager.SerializableListener
|
||||||
|
import net.minecraft.core.Registry
|
||||||
|
import net.minecraft.resources.Identifier
|
||||||
|
import java.util.Optional
|
||||||
|
import java.util.concurrent.CopyOnWriteArraySet
|
||||||
|
|
||||||
|
class SerializableListenerManager<T : SerializableListener>(
|
||||||
|
listeners: MutableSet<T> = CopyOnWriteArraySet(),
|
||||||
|
onChange: () -> Unit = {},
|
||||||
|
) : ListenerManager<T>(listeners, onChange) {
|
||||||
|
|
||||||
|
interface SerializableListener {
|
||||||
|
val codecId: Optional<Identifier>
|
||||||
|
get() = Optional.empty<Identifier>()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
|
fun <T : SerializableListener> getCodec(
|
||||||
|
registry: Registry<Codec<out T>>,
|
||||||
|
onChange: () -> Unit = {},
|
||||||
|
): Codec<SerializableListenerManager<T>> {
|
||||||
|
return registry.byNameCodec().dispatch(
|
||||||
|
{ listener -> listener.codecId.map(registry::getValue)
|
||||||
|
.orElseGet { MapCodec.unitCodec(null) }
|
||||||
|
},
|
||||||
|
{ codec -> codec.fieldOf("data") }
|
||||||
|
).listOf().xmap(
|
||||||
|
{ list -> SerializableListenerManager<T>(CopyOnWriteArraySet<T>(list), onChange) },
|
||||||
|
{ manager ->
|
||||||
|
val serializableListeners: MutableList<T> = mutableListOf()
|
||||||
|
for (listener in manager.listeners) {
|
||||||
|
if (listener.codecId.isPresent) {
|
||||||
|
serializableListeners.add(listener)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return@xmap serializableListeners
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
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.listener.SerializableListenerManager;
|
|
||||||
import io.github.skippyall.minions.registration.MinionRegistries;
|
|
||||||
import net.minecraft.core.UUIDUtil;
|
|
||||||
import net.minecraft.server.MinecraftServer;
|
|
||||||
import net.minecraft.util.ExtraCodecs;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public record MinionData(
|
|
||||||
UUID uuid,
|
|
||||||
String name,
|
|
||||||
Optional<PropertyMap> skin,
|
|
||||||
boolean isSpawned,
|
|
||||||
SerializableListenerManager<MinionListener> listeners,
|
|
||||||
MinionConfig config
|
|
||||||
) {
|
|
||||||
public static final Codec<MinionData> CODEC = RecordCodecBuilder.create(instance ->
|
|
||||||
instance.group(
|
|
||||||
UUIDUtil.AUTHLIB_CODEC.fieldOf("uuid").forGetter(MinionData::uuid),
|
|
||||||
Codec.STRING.fieldOf("name").forGetter(MinionData::name),
|
|
||||||
ExtraCodecs.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(SerializableListenerManager::new),
|
|
||||||
Optional::of
|
|
||||||
).forGetter(MinionData::listeners),
|
|
||||||
MinionConfig.CODEC.optionalFieldOf("config", new MinionConfig()).forGetter(MinionData::config)
|
|
||||||
).apply(instance, MinionData::new)
|
|
||||||
);
|
|
||||||
|
|
||||||
public static MinionData createDefault(MinecraftServer server) {
|
|
||||||
return new MinionData(
|
|
||||||
UUID.randomUUID(),
|
|
||||||
MinionProfileUtils.newDefaultMinionName(server),
|
|
||||||
Optional.empty(),
|
|
||||||
false,
|
|
||||||
new SerializableListenerManager<>(),
|
|
||||||
new MinionConfig()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MinionData withName(String name) {
|
|
||||||
return new MinionData(uuid, name, skin, isSpawned, listeners, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MinionData withSkin(Optional<PropertyMap> skin) {
|
|
||||||
return new MinionData(uuid, name, skin, isSpawned, listeners, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MinionData withSpawned(boolean isSpawned) {
|
|
||||||
return new MinionData(uuid, name, skin, isSpawned, listeners, config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
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.listener.SerializableListenerManager
|
||||||
|
import io.github.skippyall.minions.registration.MinionRegistries
|
||||||
|
import net.minecraft.core.UUIDUtil
|
||||||
|
import net.minecraft.server.MinecraftServer
|
||||||
|
import net.minecraft.util.ExtraCodecs
|
||||||
|
import java.util.Optional
|
||||||
|
import java.util.UUID
|
||||||
|
import kotlin.properties.ReadWriteProperty
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
|
class MinionData(
|
||||||
|
initialUuid: UUID,
|
||||||
|
initialName: String,
|
||||||
|
initialSkin: Optional<PropertyMap>,
|
||||||
|
initialIsSpawned: Boolean,
|
||||||
|
val listeners: SerializableListenerManager<MinionListener>,
|
||||||
|
initialConfig: MinionConfig,
|
||||||
|
var onDirty: Runnable = {},
|
||||||
|
) {
|
||||||
|
var uuid by DirtyProperty(initialUuid, this::setDirty)
|
||||||
|
var name by DirtyProperty(initialName, this::setDirty)
|
||||||
|
var skin by DirtyProperty(initialSkin, this::setDirty)
|
||||||
|
var isSpawned by DirtyProperty(initialIsSpawned, this::setDirty)
|
||||||
|
var config by DirtyProperty(initialConfig, this::setDirty)
|
||||||
|
|
||||||
|
fun setDirty() {
|
||||||
|
this@MinionData.onDirty.run()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmField
|
||||||
|
val CODEC: Codec<MinionData> =
|
||||||
|
RecordCodecBuilder.create { instance ->
|
||||||
|
instance.group(
|
||||||
|
UUIDUtil.AUTHLIB_CODEC.fieldOf("uuid").forGetter(MinionData::uuid),
|
||||||
|
Codec.STRING.fieldOf("name").forGetter(MinionData::name),
|
||||||
|
ExtraCodecs.PROPERTY_MAP.optionalFieldOf("skin").forGetter(MinionData::skin),
|
||||||
|
Codec.BOOL.optionalFieldOf("isSpawned", false).forGetter(MinionData::isSpawned),
|
||||||
|
SerializableListenerManager.getCodec<MinionListener>(MinionRegistries.MINION_LISTENER_CODECS)
|
||||||
|
.optionalFieldOf("listeners").xmap(
|
||||||
|
{ optional -> optional.orElseGet { SerializableListenerManager() } },
|
||||||
|
Optional<SerializableListenerManager<MinionListener>>::of
|
||||||
|
).forGetter(MinionData::listeners),
|
||||||
|
MinionConfig.CODEC.optionalFieldOf("config", MinionConfig())
|
||||||
|
.forGetter(MinionData::config)
|
||||||
|
).apply(
|
||||||
|
instance,
|
||||||
|
::MinionData
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun createDefault(server: MinecraftServer): MinionData {
|
||||||
|
return MinionData(
|
||||||
|
UUID.randomUUID(),
|
||||||
|
MinionProfileUtils.newDefaultMinionName(server),
|
||||||
|
Optional.empty<PropertyMap>(),
|
||||||
|
false,
|
||||||
|
SerializableListenerManager(),
|
||||||
|
MinionConfig()
|
||||||
|
) {
|
||||||
|
MinionPersistentState.get(server).isDirty = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DirtyProperty<V>(var value: V, val onDirty: () -> Unit) : ReadWriteProperty<Any?, V> {
|
||||||
|
override fun getValue(thisRef: Any?, property: KProperty<*>): V {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setValue(thisRef: Any?, property: KProperty<*>, value: V) {
|
||||||
|
this.value = value
|
||||||
|
onDirty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -79,7 +79,7 @@ public class MinionItem extends Item implements PolymerItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void setData(MinecraftServer server, MinionData data, ItemStack item) {
|
public static void setData(MinecraftServer server, MinionData data, ItemStack item) {
|
||||||
item.set(MinionComponentTypes.MINION_DATA, data.uuid());
|
item.set(MinionComponentTypes.MINION_DATA, data.getUuid());
|
||||||
MinionPersistentState.get(server).updateMinionData(data);
|
MinionPersistentState.get(server).updateMinionData(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,8 @@ public class MinionPersistentState extends SavedData {
|
|||||||
|
|
||||||
public MinionPersistentState(List<MinionData> dataList) {
|
public MinionPersistentState(List<MinionData> dataList) {
|
||||||
for (MinionData data : dataList) {
|
for (MinionData data : dataList) {
|
||||||
minionData.put(data.uuid(), data);
|
data.setOnDirty(this::setDirty);
|
||||||
|
minionData.put(data.getUuid(), data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +49,8 @@ public class MinionPersistentState extends SavedData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void updateMinionData(MinionData data) {
|
public void updateMinionData(MinionData data) {
|
||||||
minionData.put(data.uuid(), data);
|
minionData.put(data.getUuid(), data);
|
||||||
|
data.setOnDirty(this::setDirty);
|
||||||
setDirty();
|
setDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +64,7 @@ public class MinionPersistentState extends SavedData {
|
|||||||
|
|
||||||
public Optional<MinionData> getMinionWithName(String name) {
|
public Optional<MinionData> getMinionWithName(String name) {
|
||||||
return minionData.values().stream()
|
return minionData.values().stream()
|
||||||
.filter(data -> data.name().equals(name))
|
.filter(data -> data.getName().equals(name))
|
||||||
.findFirst();
|
.findFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -73,16 +73,16 @@ public class MinionFakePlayer extends ServerPlayer {
|
|||||||
if(!data.isSpawned() || force) {
|
if(!data.isSpawned() || force) {
|
||||||
MinecraftServer server = level.getServer();
|
MinecraftServer server = level.getServer();
|
||||||
|
|
||||||
PropertyMap skin = data.skin().orElse(null);
|
PropertyMap skin = data.getSkin().orElse(null);
|
||||||
|
|
||||||
GameProfile profile = MinionProfileUtils.makeNewMinionProfile(data.uuid(), data.name(), skin);
|
GameProfile profile = MinionProfileUtils.makeNewMinionProfile(data.getUuid(), data.getName(), skin);
|
||||||
server.schedule(server.wrapRunnable(() -> doSpawn(data, profile, server, level, pos, rot)));
|
server.schedule(server.wrapRunnable(() -> doSpawn(data, profile, server, level, pos, rot)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void doSpawn(MinionData data, GameProfile profile, MinecraftServer server, ServerLevel level, @Nullable Vec3 pos, @Nullable Vec2 rot) {
|
private static void doSpawn(MinionData data, GameProfile profile, MinecraftServer server, ServerLevel level, @Nullable Vec3 pos, @Nullable Vec2 rot) {
|
||||||
MinionFakePlayer instance = new MinionFakePlayer(server, level, profile, ClientInformation.createDefault());
|
MinionFakePlayer instance = new MinionFakePlayer(server, level, profile, ClientInformation.createDefault());
|
||||||
MinionPersistentState.get(server).updateMinionData(data.withSpawned(true));
|
data.setSpawned(true);
|
||||||
|
|
||||||
if(pos != null && rot != null) {
|
if(pos != null && rot != null) {
|
||||||
instance.fixStartingPosition = () -> instance.snapTo(pos.x, pos.y, pos.z, rot.x, rot.y);
|
instance.fixStartingPosition = () -> instance.snapTo(pos.x, pos.y, pos.z, rot.x, rot.y);
|
||||||
@@ -158,7 +158,7 @@ public class MinionFakePlayer extends ServerPlayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public SerializableListenerManager<MinionListener> listeners() {
|
public SerializableListenerManager<MinionListener> listeners() {
|
||||||
return getData().listeners();
|
return getData().getListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addMinionListener(MinionListener listener) {
|
public void addMinionListener(MinionListener listener) {
|
||||||
@@ -174,7 +174,7 @@ public class MinionFakePlayer extends ServerPlayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean canSpawnMobs() {
|
public boolean canSpawnMobs() {
|
||||||
return moduleInventory.hasAbility(SpecialAbilities.MOB_SPAWNING) || getData().config().getOption(MinionConfigOptions.spawnAndDespawnMobs);
|
return moduleInventory.hasAbility(SpecialAbilities.MOB_SPAWNING) || getData().getConfig().getOption(MinionConfigOptions.spawnAndDespawnMobs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canDespawnMobs() {
|
public boolean canDespawnMobs() {
|
||||||
@@ -213,7 +213,7 @@ public class MinionFakePlayer extends ServerPlayer {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
MinionPersistentState.get(getServer()).updateMinionData(getData().withSpawned(false));
|
getData().setSpawned(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import java.util.concurrent.CompletableFuture;
|
|||||||
public class NameSkinProvider implements SkinProvider {
|
public class NameSkinProvider implements SkinProvider {
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<ResolvableProfile> openSkinMenu(MinionsGui parent) {
|
public CompletableFuture<ResolvableProfile> openSkinMenu(MinionsGui parent) {
|
||||||
return TextInput.inputStringFuture(parent, Component.translatable("minions.gui.look.skin.name.title"), "")
|
return TextInput.inputString(parent, Component.translatable("minions.gui.look.skin.name.title"), "")
|
||||||
.thenApply(name -> name != null ? ResolvableProfile.createUnresolved(name) : null);
|
.thenApply(name -> name != null ? ResolvableProfile.createUnresolved(name) : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import java.util.concurrent.CompletableFuture;
|
|||||||
public class UUIDSkinProvider implements SkinProvider {
|
public class UUIDSkinProvider implements SkinProvider {
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<ResolvableProfile> openSkinMenu(MinionsGui parent) {
|
public CompletableFuture<ResolvableProfile> openSkinMenu(MinionsGui parent) {
|
||||||
return TextInput.inputStringFuture(parent, Component.translatable("minions.gui.look.skin.uuid.title"), "")
|
return TextInput.inputString(parent, Component.translatable("minions.gui.look.skin.uuid.title"), "")
|
||||||
.thenApply(name -> name != null ? ResolvableProfile.createUnresolved(name) : null);
|
.thenApply(name -> name != null ? ResolvableProfile.createUnresolved(name) : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -13,7 +13,7 @@ import org.spongepowered.asm.mixin.injection.ModifyArg;
|
|||||||
public class ClientboundPlayerInfoUpdatePacket$EntryMixin {
|
public class ClientboundPlayerInfoUpdatePacket$EntryMixin {
|
||||||
@ModifyArg(method = "<init>(Lnet/minecraft/server/level/ServerPlayer;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket$Entry;<init>(Ljava/util/UUID;Lcom/mojang/authlib/GameProfile;ZILnet/minecraft/world/level/GameType;Lnet/minecraft/network/chat/Component;ZILnet/minecraft/network/chat/RemoteChatSession$Data;)V"), index = 2)
|
@ModifyArg(method = "<init>(Lnet/minecraft/server/level/ServerPlayer;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket$Entry;<init>(Ljava/util/UUID;Lcom/mojang/authlib/GameProfile;ZILnet/minecraft/world/level/GameType;Lnet/minecraft/network/chat/Component;ZILnet/minecraft/network/chat/RemoteChatSession$Data;)V"), index = 2)
|
||||||
private static boolean removeMinionFromTabList(boolean original, @Local(argsOnly = true) ServerPlayer player) {
|
private static boolean removeMinionFromTabList(boolean original, @Local(argsOnly = true) ServerPlayer player) {
|
||||||
if(player instanceof MinionFakePlayer minion && !minion.getData().config().getOption(MinionConfigOptions.showInTabList)) {
|
if(player instanceof MinionFakePlayer minion && !minion.getData().getConfig().getOption(MinionConfigOptions.showInTabList)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public class MinecraftServerMixin {
|
|||||||
public List<ServerPlayer> ignoreFakePlayers(List<ServerPlayer> original) {
|
public List<ServerPlayer> ignoreFakePlayers(List<ServerPlayer> original) {
|
||||||
return original.stream()
|
return original.stream()
|
||||||
.filter(player -> !(player instanceof MinionFakePlayer minion
|
.filter(player -> !(player instanceof MinionFakePlayer minion
|
||||||
&& !minion.getData().config().getOption(MinionConfigOptions.showInServerList)))
|
&& !minion.getData().getConfig().getOption(MinionConfigOptions.showInServerList)))
|
||||||
.collect(Collectors.toCollection(ArrayList::new));
|
.collect(Collectors.toCollection(ArrayList::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ public class PlayerListMixin {
|
|||||||
|
|
||||||
@WrapOperation(method = "placeNewPlayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;broadcastSystemMessage(Lnet/minecraft/network/chat/Component;Z)V"))
|
@WrapOperation(method = "placeNewPlayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;broadcastSystemMessage(Lnet/minecraft/network/chat/Component;Z)V"))
|
||||||
public void noLoginMessage(PlayerList instance, Component message, boolean overlay, Operation<Void> original, @Local(argsOnly = true) ServerPlayer player) {
|
public void noLoginMessage(PlayerList instance, Component message, boolean overlay, Operation<Void> original, @Local(argsOnly = true) ServerPlayer player) {
|
||||||
if(!(player instanceof MinionFakePlayer minion && !minion.getData().config().getOption(MinionConfigOptions.sendLoginMessage))) {
|
if(!(player instanceof MinionFakePlayer minion && !minion.getData().getConfig().getOption(MinionConfigOptions.sendLoginMessage))) {
|
||||||
original.call(instance, message, overlay);
|
original.call(instance, message, overlay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,7 @@ public class PlayerListMixin {
|
|||||||
@ModifyReceiver(method = "canPlayerLogin", at = @At(value = "INVOKE", target = "Ljava/util/List;size()I"))
|
@ModifyReceiver(method = "canPlayerLogin", at = @At(value = "INVOKE", target = "Ljava/util/List;size()I"))
|
||||||
public List<ServerPlayer> noMinionCounting(List<ServerPlayer> instance) {
|
public List<ServerPlayer> noMinionCounting(List<ServerPlayer> instance) {
|
||||||
return instance.stream()
|
return instance.stream()
|
||||||
.filter(player -> !(player instanceof MinionFakePlayer minion && !minion.getData().config().getOption(MinionConfigOptions.countForPlayerLimit)))
|
.filter(player -> !(player instanceof MinionFakePlayer minion && !minion.getData().getConfig().getOption(MinionConfigOptions.countForPlayerLimit)))
|
||||||
.collect(Collectors.toCollection(ArrayList::new));
|
.collect(Collectors.toCollection(ArrayList::new));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -19,7 +19,7 @@ public class ServerGamePacketListenerImplMixin {
|
|||||||
|
|
||||||
@WrapOperation(method = "removePlayerFromWorld", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;broadcastSystemMessage(Lnet/minecraft/network/chat/Component;Z)V"))
|
@WrapOperation(method = "removePlayerFromWorld", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;broadcastSystemMessage(Lnet/minecraft/network/chat/Component;Z)V"))
|
||||||
public void noLogoutMessage(PlayerList instance, Component message, boolean overlay, Operation<Void> original) {
|
public void noLogoutMessage(PlayerList instance, Component message, boolean overlay, Operation<Void> original) {
|
||||||
if(!(player instanceof MinionFakePlayer minion && !minion.getData().config().getOption(MinionConfigOptions.sendLogoutMessage))) {
|
if(!(player instanceof MinionFakePlayer minion && !minion.getData().getConfig().getOption(MinionConfigOptions.sendLogoutMessage))) {
|
||||||
original.call(instance, message, overlay);
|
original.call(instance, message, overlay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||||||
public class SleepStatusMixin {
|
public class SleepStatusMixin {
|
||||||
@WrapOperation(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;isSpectator()Z"))
|
@WrapOperation(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;isSpectator()Z"))
|
||||||
public boolean excludeMinions(ServerPlayer instance, Operation<Boolean> original) {
|
public boolean excludeMinions(ServerPlayer instance, Operation<Boolean> original) {
|
||||||
if (instance instanceof MinionFakePlayer minion && !minion.getData().config().getOption(MinionConfigOptions.countForSleeping)) {
|
if (instance instanceof MinionFakePlayer minion && !minion.getData().getConfig().getOption(MinionConfigOptions.countForSleeping)) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return original.call(instance);
|
return original.call(instance);
|
||||||
|
|||||||
+1
-1
@@ -78,8 +78,8 @@ public class ConfiguredInstruction<R extends InstructionRuntime<R>> {
|
|||||||
|
|
||||||
public void run(R minion) {
|
public void run(R minion) {
|
||||||
if(canRun() && !isRunning()) {
|
if(canRun() && !isRunning()) {
|
||||||
ParameterValueList resolvedArguments = arguments.resolve(minion);
|
|
||||||
try {
|
try {
|
||||||
|
ParameterValueList resolvedArguments = arguments.resolve(minion);
|
||||||
execution = instruction.createExecution(resolvedArguments, minion);
|
execution = instruction.createExecution(resolvedArguments, minion);
|
||||||
execution.start(minion);
|
execution.start(minion);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
@@ -37,11 +37,6 @@ public class ValueSupplierList<R extends InstructionRuntime<R>> {
|
|||||||
return List.copyOf(arguments.values());
|
return List.copyOf(arguments.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T getValue(Parameter<T> parameter, R runtime) {
|
|
||||||
ValueSupplierEntry<?,R> entry = getEntry(parameter);
|
|
||||||
return parameter.type().checkedCast(entry.getValue(runtime));
|
|
||||||
}
|
|
||||||
|
|
||||||
public ValueSupplier<?,R> getArgument(Parameter<?> parameter) {
|
public ValueSupplier<?,R> getArgument(Parameter<?> parameter) {
|
||||||
if(arguments.containsKey(parameter)) {
|
if(arguments.containsKey(parameter)) {
|
||||||
return arguments.get(parameter).supplier;
|
return arguments.get(parameter).supplier;
|
||||||
@@ -153,20 +148,24 @@ public class ValueSupplierList<R extends InstructionRuntime<R>> {
|
|||||||
this.supplier = supplier;
|
this.supplier = supplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addToList(ParameterValueList list, R runtime) {
|
private @Nullable Component addToList(ParameterValueList list, R runtime) {
|
||||||
list.setValue(parameter, getValue(runtime));
|
Result<P, Component> result = getValue(supplier, runtime);
|
||||||
|
switch (result) {
|
||||||
|
case Result.Success<P, Component> success -> {
|
||||||
|
list.setValue(parameter, success.result());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
case Result.Error<P, Component> error -> {
|
||||||
|
return error.message();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable P getValue(R runtime) {
|
private <S> Result<P, Component> getValue(ValueSupplier<S, R> supplier, R runtime) {
|
||||||
return getValue(supplier, runtime);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Ich liebe generische Typen (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)
|
|
||||||
private <S> @Nullable P getValue(ValueSupplier<S, R> supplier, R runtime) {
|
|
||||||
S value = supplier.resolve(runtime);
|
S value = supplier.resolve(runtime);
|
||||||
Result<TypedValue<?>, Component> convertedResult = converters.convert(new TypedValue<>(value, supplier.getValueType()));
|
Result<TypedValue<?>, Component> convertedResult = converters.convert(new TypedValue<>(value, supplier.getValueType()));
|
||||||
|
|
||||||
return convertedResult.flatMap(convertedValue -> Casts.castOrError(convertedValue, parameter.type())).getOrDefault(null);
|
return convertedResult.flatMap(convertedValue -> Casts.castOrError(convertedValue, parameter.type()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable Component check() {
|
public @Nullable Component check() {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public class ValueTypes {
|
|||||||
Codec.LONG,
|
Codec.LONG,
|
||||||
0L,
|
0L,
|
||||||
o -> o instanceof Long l ? l : null,
|
o -> o instanceof Long l ? l : null,
|
||||||
(parent, oldValue) -> TextInput.inputLongFuture(
|
(parent, oldValue) -> TextInput.inputLong(
|
||||||
parent,
|
parent,
|
||||||
Component.literal("Integer"),
|
Component.literal("Integer"),
|
||||||
oldValue
|
oldValue
|
||||||
@@ -37,10 +37,10 @@ public class ValueTypes {
|
|||||||
Codec.DOUBLE,
|
Codec.DOUBLE,
|
||||||
0D,
|
0D,
|
||||||
o -> o instanceof Double d ? d : null,
|
o -> o instanceof Double d ? d : null,
|
||||||
(parent, oldValue) -> TextInput.inputDoubleFuture(
|
(parent, oldValue) -> TextInput.inputDouble(
|
||||||
parent,
|
parent,
|
||||||
Component.literal("Number"),
|
Component.literal("Number"),
|
||||||
oldValue
|
oldValue != null ? oldValue : 0D
|
||||||
),
|
),
|
||||||
value -> Component.literal(value.toString())
|
value -> Component.literal(value.toString())
|
||||||
)
|
)
|
||||||
@@ -52,7 +52,7 @@ public class ValueTypes {
|
|||||||
Codec.BOOL,
|
Codec.BOOL,
|
||||||
false,
|
false,
|
||||||
o -> o instanceof Boolean b ? b : null,
|
o -> o instanceof Boolean b ? b : null,
|
||||||
(parent, value) -> BooleanInput.confirmFuture(parent, Component.literal(""), Component.translatable("value_type.minions.boolean.false"), Component.translatable("value_type.minions.boolean.true")),
|
(parent, value) -> BooleanInput.confirm(parent, Component.literal(""), Component.translatable("value_type.minions.boolean.false"), Component.translatable("value_type.minions.boolean.true")),
|
||||||
value -> Component.literal(value.toString())
|
value -> Component.literal(value.toString())
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -63,7 +63,7 @@ public class ValueTypes {
|
|||||||
Codec.STRING,
|
Codec.STRING,
|
||||||
"",
|
"",
|
||||||
o -> o instanceof String s ? s : null,
|
o -> o instanceof String s ? s : null,
|
||||||
((parent, oldValue) -> TextInput.inputStringFuture(
|
((parent, oldValue) -> TextInput.inputString(
|
||||||
parent,
|
parent,
|
||||||
Component.literal("Text"),
|
Component.literal("Text"),
|
||||||
oldValue
|
oldValue
|
||||||
|
|||||||
@@ -1,11 +1,4 @@
|
|||||||
{
|
{
|
||||||
"type": "minions:stack",
|
"type": "minions:head",
|
||||||
"data": {
|
"data": "459dbceed3ea4abc903cfdcae3065dd3"
|
||||||
"id": "minecraft:player_head",
|
|
||||||
"components": {
|
|
||||||
"minecraft:profile": {
|
|
||||||
"name": "CastCrafter"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user