Fixing & Listening

This commit is contained in:
skippyall
2026-01-18 00:52:13 +01:00
parent 3f2a52fd0a
commit 382b394523
29 changed files with 284 additions and 63 deletions
+5 -5
View File
@@ -122,14 +122,14 @@ 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 {
def release = "https://maven.foxgalaxy.de/private-releases"
def snapshot = "https://maven.foxgalaxy.de/private-snapshot"
url = version.endsWith('SNAPSHOT') ? snapshot : release
url = "https://maven.foxgalaxy.de/private"
credentials {
username = "${maven_user}"
password = "${maven_password}"
username = project.property("foxgalaxy_user_name")
password = project.property("foxgalaxy_password")
}
}
}
}
@@ -6,6 +6,9 @@ import io.github.skippyall.minions.block.MinionTriggerBlockItem;
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.MobSpawningAbility;
import io.github.skippyall.minions.module.SpecialAbilities;
import io.github.skippyall.minions.module.SpecialAbility;
import io.github.skippyall.minions.program.instruction.InstructionType;
import io.github.skippyall.minions.program.instruction.Instructions;
import io.github.skippyall.minions.reference.ReferenceItem;
@@ -66,7 +69,7 @@ public class MinionItems {
Identifier.of(MOD_ID, "mob_spawning_module"),
Items.SPAWNER,
List.of(),
List.of("mobSpawning")
List.of(SpecialAbilities.MOB_SPAWNING)
);
public static final PolymerBlockItem MINION_TRIGGER_ITEM =
@@ -89,11 +92,11 @@ public class MinionItems {
return registerItem(identifier, constructor, new Item.Settings());
}
public static SimplePolymerItem registerModule(Identifier identifier, Item vanillaItem, List<InstructionType<MinionRuntime>> instructionTypes, List<String> specialEffects) {
public static SimplePolymerItem registerModule(Identifier identifier, Item vanillaItem, List<InstructionType<MinionRuntime>> instructionTypes, List<SpecialAbility> specialAbilities) {
return registerItem(
identifier,
settings -> new SimplePolymerItem(settings, vanillaItem),
new Item.Settings().component(MinionModule.COMPONENT_TYPE, new MinionModule(instructionTypes, specialEffects))
new Item.Settings().component(MinionModule.COMPONENT_TYPE, new MinionModule(instructionTypes, specialAbilities))
);
}
@@ -7,6 +7,7 @@ import io.github.skippyall.minions.gui.GuiDisplay;
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;
@@ -30,6 +31,7 @@ public class MinionRegistries {
public static final Registry<Codec<? extends ConfiguredInstructionListener>> INSTRUCTION_LISTENER_CODECS = registry("instruction_listener_codec");
public static final Registry<Codec<? extends MinionListener>> MINION_LISTENER_CODECS = registry("minion_listener_codec");
public static final Registry<MapCodec<? extends Reference>> REFERENCE_CODEC = registry("reference_codec");
public static final Registry<SpecialAbility> SPECIAL_ABILITIES = registry("special_ability");
public static final RegistryKey<Registry<GuiDisplay>> GUI_DISPLAY = key("gui_display");
public static final RegistryKey<Registry<ReferenceEntry>> REFERENCE_ENTRY = key("reference_entry");
@@ -11,6 +11,7 @@ import io.github.skippyall.minions.module.MinionModule;
import io.github.skippyall.minions.program.instruction.Instructions;
import io.github.skippyall.minions.program.supplier.ValueSuppliers;
import io.github.skippyall.minions.program.value.ValueTypes;
import io.github.skippyall.minions.reference.Reference;
import io.github.skippyall.minions.util.PolymerUtil;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
@@ -35,6 +36,7 @@ public class Minions implements ModInitializer {
MinionData.register();
MinionModule.register();
Reference.register();
MinionBlocks.register();
MinionItems.register();
@@ -3,28 +3,36 @@ package io.github.skippyall.minions.block;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import io.github.skippyall.minions.minion.MinionListener;
import io.github.skippyall.minions.minion.MinionPersistentState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.registry.RegistryKey;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import java.util.Optional;
import java.util.UUID;
import java.util.function.BiFunction;
public class BlockEntityMinionListener implements MinionListener {
public abstract class BlockEntityMinionListener<E extends BlockEntity> implements MinionListener {
protected RegistryKey<World> worldKey;
protected BlockPos pos;
protected BlockEntityType<E> type;
public BlockEntityMinionListener(RegistryKey<World> worldKey, BlockPos pos) {
public BlockEntityMinionListener(RegistryKey<World> worldKey, BlockPos pos, BlockEntityType<E> type) {
this.worldKey = worldKey;
this.pos = pos;
this.type = type;
}
public static final Codec<BlockEntityMinionListener> CODEC = RecordCodecBuilder.create(instance ->
public static <L extends BlockEntityMinionListener<?>> Codec<L> getCodec(BiFunction<RegistryKey<World>, BlockPos, L> constructor) {
return RecordCodecBuilder.create(instance ->
instance.group(
World.CODEC.fieldOf("world").forGetter(listener -> listener.worldKey),
BlockPos.CODEC.fieldOf("pos").forGetter(listener -> listener.pos)
).apply(instance, BlockEntityMinionListener::new));
).apply(instance, constructor));
}
private BlockEntityState getBlockEntityState(MinecraftServer server) {
World world = server.getWorld(worldKey);
@@ -32,21 +40,39 @@ public class BlockEntityMinionListener implements MinionListener {
return BlockEntityState.UNLOADED;
}
if(world.getBlockEntity(pos) instanceof MinionListeningBlockEntity) {
if(world.getBlockEntity(pos, type).isPresent()) {
return BlockEntityState.LOADED;
} else {
return BlockEntityState.REMOVED;
}
}
public Optional<MinionListeningBlockEntity> getBlockEntity(MinecraftServer server) {
public Optional<E> getBlockEntity(MinecraftServer server) {
World world = server.getWorld(worldKey);
if(world != null && world.isPosLoaded(pos) && world.getBlockEntity(pos) instanceof MinionListeningBlockEntity be) {
return Optional.of(be);
if(world != null && world.isPosLoaded(pos)) {
return world.getBlockEntity(pos, type);
}
return Optional.empty();
}
public boolean removeIfBeRemoved(MinecraftServer server, UUID minion) {
if(getBlockEntityState(server) == BlockEntityState.REMOVED) {
remove(minion);
return true;
}
return false;
}
public void add(UUID minion) {
MinionPersistentState.INSTANCE.getMinionData(minion).listeners().addListener(this);
MinionPersistentState.INSTANCE.markDirty();
}
public void remove(UUID minion) {
MinionPersistentState.INSTANCE.getMinionData(minion).listeners().removeListener(this);
MinionPersistentState.INSTANCE.markDirty();
}
public enum BlockEntityState {
LOADED,
REMOVED,
@@ -1,7 +0,0 @@
package io.github.skippyall.minions.block;
import io.github.skippyall.minions.minion.MinionListener;
public interface MinionListeningBlockEntity extends MinionListener {
}
@@ -96,7 +96,12 @@ public class MinionTriggerBlock extends BlockWithEntity implements PolymerBlock,
@Override
protected ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit) {
if(world.isClient()) {
return ActionResult.CONSUME;
}
world.getBlockEntity(pos, MinionBlocks.MINION_TRIGGER_BE_TYPE).ifPresent(be -> {
String name = MinionPersistentState.INSTANCE.getMinionData(be.getMinionUuid()).name();
player.sendMessage(Text.translatable("minions.reference.instruction.tooltip", name, be.getInstructionName()), true);
});
@@ -1,6 +1,7 @@
package io.github.skippyall.minions.block;
import io.github.skippyall.minions.MinionBlocks;
import io.github.skippyall.minions.minion.MinionPersistentState;
import io.github.skippyall.minions.minion.MinionRuntime;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
import io.github.skippyall.minions.program.instruction.ConfiguredInstruction;
@@ -0,0 +1,32 @@
package io.github.skippyall.minions.block;
import io.github.skippyall.minions.MinionBlocks;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
import io.github.skippyall.minions.program.instruction.ConfiguredInstructionListener;
import net.minecraft.registry.RegistryKey;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import java.util.UUID;
public class MinionTriggerMinionListener extends BlockEntityMinionListener<MinionTriggerBlockEntity> implements ConfiguredInstructionListener {
boolean registeredListener;
String instructionName;
public MinionTriggerMinionListener(RegistryKey<World> worldKey, BlockPos pos, String instructionName, boolean registeredListener) {
super(worldKey, pos, MinionBlocks.MINION_TRIGGER_BE_TYPE);
this.instructionName = instructionName;
this.registeredListener = registeredListener;
}
@Override
public void onMinionSpawn(MinionFakePlayer minion) {
if(!registeredListener) {
minion.getInstructionManager().getInstruction(instructionName).addListener(this);
}
}
@Override
public void onMinionRemove(MinionFakePlayer minion) {
}
}
@@ -15,6 +15,7 @@ import net.minecraft.item.Items;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import net.minecraft.util.Rarity;
@@ -5,7 +5,9 @@ import com.mojang.datafixers.util.Pair;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import eu.pb4.polymer.core.api.other.PolymerComponent;
import io.github.skippyall.minions.MinionRegistries;
import io.github.skippyall.minions.Minions;
import io.github.skippyall.minions.util.SerializableListenerManager;
import net.minecraft.component.ComponentType;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtOps;
@@ -19,36 +21,33 @@ import org.jetbrains.annotations.Nullable;
import java.util.Optional;
import java.util.UUID;
public record MinionData(UUID uuid, String name, Optional<PropertyMap> skin, boolean isSpawned) {
public record MinionData(UUID uuid, String name, Optional<PropertyMap> skin, boolean isSpawned, SerializableListenerManager<MinionListener> listeners) {
public static final Codec<MinionData> CODEC = RecordCodecBuilder.create(instance ->
instance.group(
Uuids.CODEC.fieldOf("uuid").forGetter(MinionData::uuid),
Codec.STRING.fieldOf("name").forGetter(MinionData::name),
Codecs.GAME_PROFILE_PROPERTY_MAP.optionalFieldOf("skin").forGetter(MinionData::skin),
Codec.BOOL.optionalFieldOf("isSpawned", false).forGetter(MinionData::isSpawned)
Codec.BOOL.optionalFieldOf("isSpawned", false).forGetter(MinionData::isSpawned),
SerializableListenerManager.getCodec(MinionRegistries.MINION_LISTENER_CODECS).optionalFieldOf("listeners", new SerializableListenerManager<>(MinionRegistries.MINION_LISTENER_CODECS)).forGetter(MinionData::listeners)
).apply(instance, MinionData::new)
);
public static final ComponentType<UUID> COMPONENT = Registry.register(Registries.DATA_COMPONENT_TYPE, Identifier.of(Minions.MOD_ID, "minion_data"), ComponentType.<UUID>builder().codec(Uuids.CODEC).build());
public static MinionData createDefault() {
return new MinionData(UUID.randomUUID(), MinionProfileUtils.newDefaultMinionName(), Optional.empty(), false);
}
public MinionData withUuid(UUID uuid) {
return new MinionData(uuid, name, skin, isSpawned);
return new MinionData(UUID.randomUUID(), MinionProfileUtils.newDefaultMinionName(), Optional.empty(), false, new SerializableListenerManager<>(MinionRegistries.MINION_LISTENER_CODECS));
}
public MinionData withName(String name) {
return new MinionData(uuid, name, skin, isSpawned);
return new MinionData(uuid, name, skin, isSpawned, listeners);
}
public MinionData withSkin(Optional<PropertyMap> skin) {
return new MinionData(uuid, name, skin, isSpawned);
return new MinionData(uuid, name, skin, isSpawned, listeners);
}
public MinionData withSpawned(boolean isSpawned) {
return new MinionData(uuid, name, skin, isSpawned);
return new MinionData(uuid, name, skin, isSpawned, listeners);
}
public NbtCompound writeNbt() {
@@ -3,6 +3,7 @@ package io.github.skippyall.minions.minion;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
import io.github.skippyall.minions.program.instruction.ConfiguredInstruction;
import io.github.skippyall.minions.util.SerializableListenerManager;
import org.jetbrains.annotations.Nullable;
public interface MinionListener extends SerializableListenerManager.SerializableListener {
default void onMinionSpawn(MinionFakePlayer minion) {}
@@ -12,4 +13,36 @@ public interface MinionListener extends SerializableListenerManager.Serializable
default void onInstructionsUpdate(MinionFakePlayer minion) {}
default void onInstructionRename(MinionFakePlayer minion, ConfiguredInstruction<?> instruction, String newName) {}
interface Delegating extends MinionListener {
@Nullable MinionListener getBacking();
@Override
default void onMinionSpawn(MinionFakePlayer minion) {
if(getBacking() != null) {
getBacking().onMinionSpawn(minion);
}
}
@Override
default void onMinionRemove(MinionFakePlayer minion) {
if(getBacking() != null) {
getBacking().onMinionRemove(minion);
}
}
@Override
default void onInstructionsUpdate(MinionFakePlayer minion) {
if(getBacking() != null) {
getBacking().onMinionSpawn(minion);
}
}
@Override
default void onInstructionRename(MinionFakePlayer minion, ConfiguredInstruction<?> instruction, String newName) {
if(getBacking() != null) {
getBacking().onInstructionRename(minion, instruction, newName);
}
}
}
}
@@ -35,6 +35,14 @@ public class MinionRuntime implements InstructionRuntime<MinionRuntime> {
}
}
public void disableInstructionType(InstructionType<MinionRuntime> instructionType) {
}
public void enableInstructionType(InstructionType<MinionRuntime> instructionType) {
}
public Set<String> getInstructionNames() {
return configuredInstructions.keySet();
}
@@ -12,7 +12,9 @@ import io.github.skippyall.minions.minion.MinionRuntime;
import io.github.skippyall.minions.minion.MinionItem;
import io.github.skippyall.minions.minion.MinionPersistentState;
import io.github.skippyall.minions.minion.MinionProfileUtils;
import io.github.skippyall.minions.module.MobSpawningAbility;
import io.github.skippyall.minions.module.ModuleInventory;
import io.github.skippyall.minions.module.SpecialAbilities;
import io.github.skippyall.minions.util.SerializableListenerManager;
import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity;
@@ -56,7 +58,7 @@ public class MinionFakePlayer extends ServerPlayerEntity {
private EntityPlayerActionPack actionPack;
private final SerializableListenerManager<MinionListener> minionListeners = new SerializableListenerManager<>(MinionRegistries.MINION_LISTENER_CODECS);
private final ModuleInventory moduleInventory = new ModuleInventory();
private final ModuleInventory moduleInventory = new ModuleInventory(this);
private final MinionRuntime instructionManager = new MinionRuntime(this);
private final MinionData data;
@@ -93,8 +95,8 @@ public class MinionFakePlayer extends ServerPlayerEntity {
instance.unsetRemoved();
instance.getAttributeInstance(EntityAttributes.STEP_HEIGHT).setBaseValue(0.6F);
instance.interactionManager.changeGameMode(GameMode.SURVIVAL);
server.getPlayerManager().sendToDimension(new EntitySetHeadYawS2CPacket(instance, (byte) (instance.headYaw * 256 / 360)), level.getRegistryKey());//instance.dimension);
server.getPlayerManager().sendToDimension(EntityPositionSyncS2CPacket.create(instance), level.getRegistryKey());//instance.dimension);
server.getPlayerManager().sendToDimension(new EntitySetHeadYawS2CPacket(instance, (byte) (instance.headYaw * 256 / 360)), level.getRegistryKey());
server.getPlayerManager().sendToDimension(EntityPositionSyncS2CPacket.create(instance), level.getRegistryKey());
instance.getWorld().getChunkManager().updatePosition(instance);
instance.dataTracker.set(PLAYER_MODEL_PARTS, (byte) 0x7f); // show all model layers (incl. capes)
instance.getAbilities().flying = false;
@@ -143,11 +145,11 @@ public class MinionFakePlayer extends ServerPlayerEntity {
}
public boolean canSpawnMobs() {
return moduleInventory.hasAbility("mobSpawning");
return moduleInventory.hasAbility(SpecialAbilities.MOB_SPAWNING);
}
public boolean canDespawnMobs() {
return moduleInventory.hasAbility("mobSpawning");
return moduleInventory.hasAbility(SpecialAbilities.MOB_SPAWNING);
}
@Override
@@ -14,11 +14,11 @@ import net.minecraft.util.Identifier;
import java.util.List;
public record MinionModule(List<InstructionType<MinionRuntime>> instructions, List<String> specialBehaviour) {
public record MinionModule(List<InstructionType<MinionRuntime>> instructions, List<SpecialAbility> specialAbilities) {
public static final Codec<MinionModule> CODEC = RecordCodecBuilder.create(instance ->
instance.group(
MinionRegistries.INSTRUCTION_TYPES.getCodec().listOf().fieldOf("instructions").forGetter(MinionModule::instructions),
Codec.STRING.listOf().fieldOf("specialBehaviour").forGetter(MinionModule::specialBehaviour)
MinionRegistries.SPECIAL_ABILITIES.getCodec().listOf().fieldOf("specialAbilities").forGetter(MinionModule::specialAbilities)
).apply(instance, MinionModule::new)
);
@@ -30,9 +30,9 @@ public record MinionModule(List<InstructionType<MinionRuntime>> instructions, Li
this(instructions, List.of());
}
public MinionModule(List<InstructionType<MinionRuntime>> instructions, List<String> specialBehaviour) {
public MinionModule(List<InstructionType<MinionRuntime>> instructions, List<SpecialAbility> specialAbilities) {
this.instructions = List.copyOf(instructions);
this.specialBehaviour = List.copyOf(specialBehaviour);
this.specialAbilities = List.copyOf(specialAbilities);
}
public static void register() {
@@ -0,0 +1,15 @@
package io.github.skippyall.minions.module;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
public class MobSpawningAbility implements SpecialAbility {
@Override
public void onAdd(MinionFakePlayer minion) {
SpecialAbility.super.onAdd(minion);
}
@Override
public void onRemove(MinionFakePlayer minion) {
SpecialAbility.super.onRemove(minion);
}
}
@@ -1,5 +1,6 @@
package io.github.skippyall.minions.module;
import io.github.skippyall.minions.minion.MinionRuntime;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
import io.github.skippyall.minions.program.instruction.InstructionType;
import net.minecraft.inventory.Inventories;
@@ -19,10 +20,14 @@ import java.util.Set;
public class ModuleInventory extends SimpleInventory {
private final Set<MinionModule> modules = new HashSet<>();
private final Set<String> specialAbilities = new HashSet<>();
private final Set<InstructionType<MinionRuntime>> instructions = new HashSet<>();
private final Set<SpecialAbility> specialAbilities = new HashSet<>();
public ModuleInventory() {
private final MinionFakePlayer minion;
public ModuleInventory(MinionFakePlayer minion) {
super(27);
this.minion = minion;
}
public static void openModuleInventory(ServerPlayerEntity player, MinionFakePlayer minion) {
@@ -46,13 +51,37 @@ public class ModuleInventory extends SimpleInventory {
}
public void updateModules() {
Set<MinionModule> oldModules = Set.copyOf(modules);
Set<InstructionType<MinionRuntime>> oldInstructions = Set.copyOf(instructions);
Set<SpecialAbility> oldAbilities = Set.copyOf(specialAbilities);
modules.clear();
instructions.clear();
specialAbilities.clear();
for (ItemStack heldStack : heldStacks) {
MinionModule module = heldStack.get(MinionModule.COMPONENT_TYPE);
if(module != null) {
modules.add(module);
specialAbilities.addAll(module.specialBehaviour());
instructions.addAll(module.instructions());
specialAbilities.addAll(module.specialAbilities());
for(SpecialAbility ability : module.specialAbilities()) {
if(!oldAbilities.contains(ability)) {
ability.onAdd(minion);
}
}
}
}
for(InstructionType<MinionRuntime> instructionType : oldInstructions) {
if(!instructions.contains(instructionType)) {
minion.getInstructionManager().disableInstructionType(instructionType);
}
}
for(SpecialAbility ability : oldAbilities) {
if(!specialAbilities.contains(ability)) {
ability.onRemove(minion);
}
}
}
@@ -70,7 +99,7 @@ public class ModuleInventory extends SimpleInventory {
return modules;
}
public boolean hasAbility(String ability) {
public boolean hasAbility(SpecialAbility ability) {
return specialAbilities.contains(ability);
}
@@ -12,11 +12,6 @@ public class ModuleInventoryScreenHandler extends ScreenHandler {
private final int rows = 3;
private final ModuleInventory inventory;
public ModuleInventoryScreenHandler(int syncId, ModuleInventory inventory) {
super(ScreenHandlerType.GENERIC_9X3, syncId);
this.inventory = inventory;
}
public ModuleInventoryScreenHandler(int syncId, PlayerInventory playerInventory, ModuleInventory inventory) {
super(ScreenHandlerType.GENERIC_9X3, syncId);
@@ -0,0 +1,10 @@
package io.github.skippyall.minions.module;
import io.github.skippyall.minions.MinionRegistries;
import io.github.skippyall.minions.Minions;
import net.minecraft.registry.Registry;
import net.minecraft.util.Identifier;
public class SpecialAbilities {
public static final MobSpawningAbility MOB_SPAWNING = Registry.register(MinionRegistries.SPECIAL_ABILITIES, Identifier.of(Minions.MOD_ID, "mob_spawning"), new MobSpawningAbility());
}
@@ -0,0 +1,11 @@
package io.github.skippyall.minions.module;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
public interface SpecialAbility {
default void onAdd(MinionFakePlayer minion) {}
default void onRemove(MinionFakePlayer minion) {}
default void tick(MinionFakePlayer minion) {}
}
@@ -17,7 +17,7 @@ public class ConfiguredInstruction<R extends InstructionRuntime<R>> {
private final ValueConsumerList<R> valueConsumers;
private @Nullable InstructionExecution<R> execution;
private SerializableListenerManager<ConfiguredInstructionListener> listeners;
private SerializableListenerManager<ConfiguredInstructionListener> listeners = new SerializableListenerManager<>(MinionRegistries.INSTRUCTION_LISTENER_CODECS);
private ConfiguredInstruction(InstructionType<R> instruction, ValueSupplierList<R> arguments, ValueConsumerList<R> valueConsumers, @Nullable InstructionExecution<R> execution, SerializableListenerManager<ConfiguredInstructionListener> listeners) {
this(instruction, arguments, valueConsumers, execution);
@@ -29,7 +29,6 @@ public class ConfiguredInstruction<R extends InstructionRuntime<R>> {
this.arguments = arguments;
this.valueConsumers = valueConsumers;
this.execution = execution;
arguments.addListener(this::onSupplierChange);
valueConsumers.addListener(this::onConsumerChange);
}
@@ -114,9 +114,11 @@ public class MineBlockExecution implements InstructionExecution<MinionRuntime> {
MinionFakePlayer player = runtime.getMinion();
EntityPlayerActionPack ap = player.getMinionActionPack();
if(currentBlock != null) {
player.getWorld().setBlockBreakingInfo(-1, currentBlock, -1);
player.interactionManager.processBlockBreakingAction(currentBlock, PlayerActionC2SPacket.Action.ABORT_DESTROY_BLOCK, Direction.DOWN, player.getWorld().getTopYInclusive(), -1);
}
}
@Override
public void readArguments(ValueSupplierList<MinionRuntime> arguments, MinionRuntime runtime) {
@@ -8,6 +8,8 @@ import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.item.tooltip.TooltipType;
import net.minecraft.util.Identifier;
import org.jetbrains.annotations.Nullable;
import xyz.nucleoid.packettweaker.PacketContext;
public class ReferenceItem extends Item implements PolymerItem {
@@ -20,6 +22,11 @@ public class ReferenceItem extends Item implements PolymerItem {
return Items.PAPER;
}
@Override
public @Nullable Identifier getPolymerItemModel(ItemStack stack, PacketContext context) {
return null;
}
@Override
public ItemStack getPolymerItemStack(ItemStack itemStack, TooltipType tooltipType, PacketContext context) {
ItemStack stack = PolymerItem.super.getPolymerItemStack(itemStack, tooltipType, context);
@@ -5,7 +5,15 @@ import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Consumer;
public class ListenerManager<T> {
protected final List<T> listeners = new CopyOnWriteArrayList<>();
protected final List<T> listeners;
public ListenerManager() {
this(new CopyOnWriteArrayList<>());
}
protected ListenerManager(List<T> listeners) {
this.listeners = listeners;
}
public void forEachListener(Consumer<T> listenerConsumer) {
for(T listener : listeners) {
@@ -6,7 +6,10 @@ 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;
public class SerializableListenerManager<T extends SerializableListenerManager.SerializableListener> extends ListenerManager<T> {
private final Registry<Codec<? extends T>> registry;
@@ -15,6 +18,29 @@ public class SerializableListenerManager<T extends SerializableListenerManager.S
this.registry = registry;
}
public SerializableListenerManager(Registry<Codec<? extends T>> registry, List<T> listeners) {
super(listeners);
this.registry = registry;
}
public static <T extends SerializableListener> Codec<SerializableListenerManager<T>> getCodec(Registry<Codec<? extends T>> registry) {
return registry.getCodec().<T>dispatch(
listener -> listener.getCodecId().map(registry::get).orElse(Codec.unit(null)),
codec -> codec.fieldOf("data")
).listOf().xmap(
list -> new SerializableListenerManager<>(registry, new CopyOnWriteArrayList<>(list)),
manager -> {
List<T> serializableListeners = new ArrayList<>();
for(T listener : manager.listeners) {
if(listener.getCodecId().isPresent()) {
serializableListeners.add(listener);
}
}
return serializableListeners;
}
);
}
public void save(WriteView view) {
WriteView.ListView listView = view.getList("listeners");
for (T listener : listeners) {
@@ -1,4 +1,4 @@
{
"type": "minions:item",
"data": "minecraft:iron_pickaxe"
"data": "minecraft:iron_sword"
}
@@ -0,0 +1,4 @@
{
"type": "minions:item",
"data": "minecraft:iron_pickaxe"
}
@@ -0,0 +1,4 @@
{
"type": "minions:item",
"data": "minecraft:structure_void"
}
@@ -0,0 +1,4 @@
{
"type": "minions:item",
"data": "minecraft:iron_boots"
}