Listening in both directions
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
package io.github.skippyall.minions.client;
|
||||
|
||||
import eu.pb4.polymer.networking.api.client.PolymerClientNetworking;
|
||||
import io.github.skippyall.minions.MinionBlocks;
|
||||
import io.github.skippyall.minions.registration.MinionBlocks;
|
||||
import io.github.skippyall.minions.util.PolymerUtil;
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.BlockRenderLayerMap;
|
||||
|
||||
@@ -12,6 +12,11 @@ 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.registration.MinionBlocks;
|
||||
import io.github.skippyall.minions.registration.MinionCreativeTab;
|
||||
import io.github.skippyall.minions.registration.MinionItems;
|
||||
import io.github.skippyall.minions.registration.MinionRegistration;
|
||||
import io.github.skippyall.minions.registration.MinionRegistries;
|
||||
import io.github.skippyall.minions.util.PolymerUtil;
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
|
||||
@@ -41,12 +46,12 @@ public class Minions implements ModInitializer {
|
||||
MinionBlocks.register();
|
||||
MinionItems.register();
|
||||
MinionCreativeTab.registerGroup();
|
||||
MinionRegistration.register();
|
||||
|
||||
PolymerUtil.register();
|
||||
|
||||
ServerLifecycleEvents.SERVER_STARTED.register(server -> {
|
||||
MinionPersistentState.create(server);
|
||||
MinionPersistentState.INSTANCE.getMinionData().forEach((uuid, data) -> {
|
||||
MinionPersistentState.get(server).getMinionData().forEach((uuid, data) -> {
|
||||
if(data.isSpawned()) {
|
||||
MinionFakePlayer.spawnMinion(data, server.getOverworld(), null, null, true);
|
||||
}
|
||||
@@ -57,6 +62,12 @@ public class Minions implements ModInitializer {
|
||||
MinionsCommand.register(commandDispatcher);
|
||||
});
|
||||
|
||||
/*ServerBlockEntityEvents.BLOCK_ENTITY_LOAD.register((blockEntity, world) -> {
|
||||
if(blockEntity instanceof MinionTriggerBlockEntity) {
|
||||
world.updateComparators(blockEntity.getPos(), MinionBlocks.MINION_TRIGGER_BLOCK);
|
||||
}
|
||||
});*/
|
||||
|
||||
PolymerResourcePackUtils.addModAssets(Minions.MOD_ID);
|
||||
}
|
||||
}
|
||||
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
package io.github.skippyall.minions.block;
|
||||
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.program.instruction.ConfiguredInstructionListener;
|
||||
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.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class BlockEntityMinionInstructionListener<E extends BlockEntity> extends BlockEntityMinionListener<E> {
|
||||
protected BlockEntityMinionInstructionListener(RegistryKey<World> worldKey, BlockPos pos, UUID minionUuid, BlockEntityType<E> type) {
|
||||
super(worldKey, pos, minionUuid, type);
|
||||
}
|
||||
|
||||
protected abstract Map<String, ConfiguredInstructionListener> getInstructionListeners();
|
||||
|
||||
@Override
|
||||
public void onMinionSpawn(MinionFakePlayer minion) {
|
||||
super.onMinionSpawn(minion);
|
||||
registerInstructionListeners();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void add(MinecraftServer server) {
|
||||
super.add(server);
|
||||
if(minion != null) {
|
||||
registerInstructionListeners();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(MinecraftServer server) {
|
||||
super.remove(server);
|
||||
if(minion != null) {
|
||||
removeInstructionListeners();
|
||||
}
|
||||
}
|
||||
|
||||
public void registerInstructionListeners() {
|
||||
for(Map.Entry<String, ConfiguredInstructionListener> listener : getInstructionListeners().entrySet()) {
|
||||
minion.getInstructionManager().getInstruction(listener.getKey()).addListener(listener.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public void removeInstructionListeners() {
|
||||
for(Map.Entry<String, ConfiguredInstructionListener> listener : getInstructionListeners().entrySet()) {
|
||||
minion.getInstructionManager().getInstruction(listener.getKey()).removeListener(listener.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,36 +1,67 @@
|
||||
package io.github.skippyall.minions.block;
|
||||
|
||||
import com.mojang.datafixers.util.Function3;
|
||||
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 io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
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.Uuids;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public abstract class BlockEntityMinionListener<E extends BlockEntity> implements MinionListener {
|
||||
protected RegistryKey<World> worldKey;
|
||||
protected BlockPos pos;
|
||||
protected UUID minionUuid;
|
||||
protected BlockEntityType<E> type;
|
||||
protected @Nullable MinionFakePlayer minion;
|
||||
|
||||
public BlockEntityMinionListener(RegistryKey<World> worldKey, BlockPos pos, BlockEntityType<E> type) {
|
||||
protected BlockEntityMinionListener(RegistryKey<World> worldKey, BlockPos pos, UUID minionUuid, BlockEntityType<E> type) {
|
||||
this.worldKey = worldKey;
|
||||
this.pos = pos;
|
||||
this.minionUuid = minionUuid;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public static <L extends BlockEntityMinionListener<?>> Codec<L> getCodec(BiFunction<RegistryKey<World>, BlockPos, L> constructor) {
|
||||
@Override
|
||||
public void onMinionSpawn(MinionFakePlayer minion) {
|
||||
MinionListener.super.onMinionSpawn(minion);
|
||||
this.minion = minion;
|
||||
removeIfBeRemoved(minion.getServer());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMinionRemove(MinionFakePlayer minion) {
|
||||
MinionListener.super.onMinionRemove(minion);
|
||||
this.minion = null;
|
||||
}
|
||||
|
||||
public static <T extends BlockEntityMinionListener<?>> T getListener(World world, BlockPos pos, UUID minionUuid, Class<T> clazz) {
|
||||
if(minionUuid != null) {
|
||||
for (MinionListener listener : MinionPersistentState.get(world.getServer()).getMinionData(minionUuid).listeners()) {
|
||||
if (listener instanceof BlockEntityMinionListener<?> tl && tl.pos.equals(pos) && tl.worldKey.equals(world.getRegistryKey()) && clazz.isInstance(tl)) {
|
||||
return clazz.cast(tl);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <L extends BlockEntityMinionListener<?>> Codec<L> getCodec(Function3<RegistryKey<World>, BlockPos, UUID, L> constructor) {
|
||||
return RecordCodecBuilder.create(instance ->
|
||||
instance.group(
|
||||
World.CODEC.fieldOf("world").forGetter(listener -> listener.worldKey),
|
||||
BlockPos.CODEC.fieldOf("pos").forGetter(listener -> listener.pos)
|
||||
BlockPos.CODEC.fieldOf("pos").forGetter(listener -> listener.pos),
|
||||
Uuids.CODEC.fieldOf("minionUuid").forGetter(listener -> listener.minionUuid)
|
||||
).apply(instance, constructor));
|
||||
}
|
||||
|
||||
@@ -55,22 +86,23 @@ public abstract class BlockEntityMinionListener<E extends BlockEntity> implement
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public boolean removeIfBeRemoved(MinecraftServer server, UUID minion) {
|
||||
public boolean removeIfBeRemoved(MinecraftServer server) {
|
||||
if(getBlockEntityState(server) == BlockEntityState.REMOVED) {
|
||||
remove(minion);
|
||||
remove(server);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void add(UUID minion) {
|
||||
MinionPersistentState.INSTANCE.getMinionData(minion).listeners().addListener(this);
|
||||
MinionPersistentState.INSTANCE.markDirty();
|
||||
protected void add(MinecraftServer server) {
|
||||
MinionPersistentState.get(server).getMinionData(minionUuid).listeners().addListener(this);
|
||||
MinionPersistentState.get(server).markDirty();
|
||||
this.minion = (MinionFakePlayer) server.getPlayerManager().getPlayer(minionUuid);
|
||||
}
|
||||
|
||||
public void remove(UUID minion) {
|
||||
MinionPersistentState.INSTANCE.getMinionData(minion).listeners().removeListener(this);
|
||||
MinionPersistentState.INSTANCE.markDirty();
|
||||
public void remove(MinecraftServer server) {
|
||||
MinionPersistentState.get(server).getMinionData(minionUuid).listeners().removeListener(this);
|
||||
MinionPersistentState.get(server).markDirty();
|
||||
}
|
||||
|
||||
public enum BlockEntityState {
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
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) {
|
||||
}
|
||||
}
|
||||
+10
-15
@@ -1,4 +1,4 @@
|
||||
package io.github.skippyall.minions.block;
|
||||
package io.github.skippyall.minions.block.miniontrigger;
|
||||
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import eu.pb4.polymer.core.api.block.PolymerBlock;
|
||||
@@ -8,7 +8,7 @@ import eu.pb4.polymer.resourcepack.api.PolymerResourcePackUtils;
|
||||
import eu.pb4.polymer.virtualentity.api.BlockWithElementHolder;
|
||||
import eu.pb4.polymer.virtualentity.api.ElementHolder;
|
||||
import eu.pb4.polymer.virtualentity.api.elements.ItemDisplayElement;
|
||||
import io.github.skippyall.minions.MinionBlocks;
|
||||
import io.github.skippyall.minions.registration.MinionBlocks;
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.minion.MinionPersistentState;
|
||||
import io.github.skippyall.minions.reference.InstructionReference;
|
||||
@@ -22,8 +22,6 @@ import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.ShapeContext;
|
||||
import net.minecraft.block.SideShapeType;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.block.entity.BlockEntityTicker;
|
||||
import net.minecraft.block.entity.BlockEntityType;
|
||||
import net.minecraft.component.DataComponentTypes;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
@@ -75,6 +73,12 @@ public class MinionTriggerBlock extends BlockWithEntity implements PolymerBlock,
|
||||
return state.isSideSolid(world, pos, Direction.UP, SideShapeType.RIGID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStateReplaced(BlockState state, ServerWorld world, BlockPos pos, boolean moved) {
|
||||
super.onStateReplaced(state, world, pos, moved);
|
||||
world.getBlockEntity(pos, MinionBlocks.MINION_TRIGGER_BE_TYPE).ifPresent(MinionTriggerBlockEntity::removeListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||
builder.add(POWERED);
|
||||
@@ -101,8 +105,7 @@ public class MinionTriggerBlock extends BlockWithEntity implements PolymerBlock,
|
||||
}
|
||||
|
||||
world.getBlockEntity(pos, MinionBlocks.MINION_TRIGGER_BE_TYPE).ifPresent(be -> {
|
||||
|
||||
String name = MinionPersistentState.INSTANCE.getMinionData(be.getMinionUuid()).name();
|
||||
String name = MinionPersistentState.get(world.getServer()).getMinionData(be.getMinionUuid()).name();
|
||||
player.sendMessage(Text.translatable("minions.reference.instruction.tooltip", name, be.getInstructionName()), true);
|
||||
});
|
||||
return ActionResult.SUCCESS;
|
||||
@@ -113,6 +116,7 @@ public class MinionTriggerBlock extends BlockWithEntity implements PolymerBlock,
|
||||
if(!canPlaceAt(state, world, pos)) {
|
||||
dropStacks(state, world, pos);
|
||||
world.removeBlock(pos, false);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean newPower = world.isReceivingRedstonePower(pos);
|
||||
@@ -147,15 +151,6 @@ public class MinionTriggerBlock extends BlockWithEntity implements PolymerBlock,
|
||||
return PolymerUtil.isOnClient(context) ? state : Blocks.COMPARATOR.getDefaultState().with(AbstractRedstoneGateBlock.POWERED, state.get(POWERED));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, BlockEntityType<T> type) {
|
||||
if(type == MinionBlocks.MINION_TRIGGER_BE_TYPE) {
|
||||
return MinionTriggerBlockEntity::tick;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ElementHolder createElementHolder(ServerWorld world, BlockPos pos, BlockState initialBlockState) {
|
||||
ElementHolder holder = new ElementHolder() {
|
||||
+26
-28
@@ -1,7 +1,7 @@
|
||||
package io.github.skippyall.minions.block;
|
||||
package io.github.skippyall.minions.block.miniontrigger;
|
||||
|
||||
import io.github.skippyall.minions.MinionBlocks;
|
||||
import io.github.skippyall.minions.minion.MinionPersistentState;
|
||||
import io.github.skippyall.minions.block.BlockEntityMinionListener;
|
||||
import io.github.skippyall.minions.registration.MinionBlocks;
|
||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.program.instruction.ConfiguredInstruction;
|
||||
@@ -11,7 +11,6 @@ import net.minecraft.storage.ReadView;
|
||||
import net.minecraft.storage.WriteView;
|
||||
import net.minecraft.util.Uuids;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
@@ -20,38 +19,34 @@ public class MinionTriggerBlockEntity extends BlockEntity {
|
||||
private UUID minionUuid;
|
||||
private String instructionName = "";
|
||||
|
||||
private boolean first = true;
|
||||
private boolean runningCache = false;
|
||||
|
||||
public MinionTriggerBlockEntity(BlockPos pos, BlockState state) {
|
||||
super(MinionBlocks.MINION_TRIGGER_BE_TYPE, pos, state);
|
||||
}
|
||||
|
||||
public void setInstruction(UUID minionUuid, String instructionName) {
|
||||
this.minionUuid = minionUuid;
|
||||
this.instructionName = instructionName;
|
||||
markDirty();
|
||||
public void removeListener() {
|
||||
MinionTriggerMinionListener.removeListener(world, pos, minionUuid, instructionName);
|
||||
}
|
||||
|
||||
public static void tick(World world, BlockPos pos, BlockState state, BlockEntity blockEntity) {
|
||||
if(!(blockEntity instanceof MinionTriggerBlockEntity triggerBlockEntity)) {
|
||||
return;
|
||||
}
|
||||
if(triggerBlockEntity.first) {
|
||||
triggerBlockEntity.first = false;
|
||||
world.updateComparators(pos, MinionBlocks.MINION_TRIGGER_BLOCK);
|
||||
triggerBlockEntity.runningCache = triggerBlockEntity.getInstruction().map(ConfiguredInstruction::isRunning).orElse(false);
|
||||
} else {
|
||||
boolean isRunning = triggerBlockEntity.getInstruction().map(ConfiguredInstruction::isRunning).orElse(false);
|
||||
if (isRunning != triggerBlockEntity.runningCache) {
|
||||
world.updateComparators(pos, MinionBlocks.MINION_TRIGGER_BLOCK);
|
||||
triggerBlockEntity.runningCache = isRunning;
|
||||
}
|
||||
public void addListener() {
|
||||
MinionTriggerMinionListener.addListener(world, pos, minionUuid, instructionName);
|
||||
}
|
||||
|
||||
public void setInstruction(UUID minionUuid, String instructionName) {
|
||||
removeListener();
|
||||
this.minionUuid = minionUuid;
|
||||
this.instructionName = instructionName;
|
||||
addListener();
|
||||
markDirty();
|
||||
}
|
||||
|
||||
public void updatePower() {
|
||||
boolean powered = getCachedState().get(MinionTriggerBlock.POWERED);
|
||||
|
||||
MinionTriggerMinionListener listener = getListener();
|
||||
if(listener != null) {
|
||||
listener.incomingPowerCache = powered;
|
||||
}
|
||||
|
||||
getMinion().ifPresent(minion -> {
|
||||
getInstruction().ifPresent(instruction -> {
|
||||
if(powered) {
|
||||
@@ -61,12 +56,11 @@ public class MinionTriggerBlockEntity extends BlockEntity {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public int getComparatorOutput() {
|
||||
Optional<ConfiguredInstruction<MinionRuntime>> instruction = getInstruction();
|
||||
if(instruction.isPresent() && instruction.get().isRunning()) {
|
||||
MinionTriggerMinionListener listener = getListener();
|
||||
if(listener != null && listener.runningCache) {
|
||||
return 15;
|
||||
}
|
||||
return 0;
|
||||
@@ -95,6 +89,10 @@ public class MinionTriggerBlockEntity extends BlockEntity {
|
||||
return getMinion().flatMap(this::getInstruction);
|
||||
}
|
||||
|
||||
public MinionTriggerMinionListener getListener() {
|
||||
return BlockEntityMinionListener.getListener(world, pos, minionUuid, MinionTriggerMinionListener.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readData(ReadView view) {
|
||||
minionUuid = view.read("minionUuid", Uuids.CODEC).orElse(null);
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package io.github.skippyall.minions.block;
|
||||
package io.github.skippyall.minions.block.miniontrigger;
|
||||
|
||||
import eu.pb4.polymer.core.api.item.PolymerBlockItem;
|
||||
import eu.pb4.polymer.resourcepack.api.PolymerResourcePackUtils;
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
package io.github.skippyall.minions.block.miniontrigger;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.block.BlockEntityMinionInstructionListener;
|
||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||
import io.github.skippyall.minions.registration.MinionBlocks;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.program.instruction.ConfiguredInstruction;
|
||||
import io.github.skippyall.minions.program.instruction.ConfiguredInstructionListener;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Uuids;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public class MinionTriggerMinionListener extends BlockEntityMinionInstructionListener<MinionTriggerBlockEntity> {
|
||||
public static final Codec<MinionTriggerMinionListener> CODEC = RecordCodecBuilder.create(instance ->
|
||||
instance.group(
|
||||
World.CODEC.fieldOf("world").forGetter(listener -> listener.worldKey),
|
||||
BlockPos.CODEC.fieldOf("pos").forGetter(listener -> listener.pos),
|
||||
Uuids.CODEC.fieldOf("minionUuid").forGetter(listener -> listener.minionUuid),
|
||||
Codec.STRING.fieldOf("instructionName").forGetter(listener -> listener.instructionName)
|
||||
).apply(instance, MinionTriggerMinionListener::new));
|
||||
|
||||
String instructionName;
|
||||
final TriggerInstructionListener listener = new TriggerInstructionListener();
|
||||
|
||||
boolean runningCache;
|
||||
boolean incomingPowerCache;
|
||||
|
||||
private MinionTriggerMinionListener(RegistryKey<World> worldKey, BlockPos pos, UUID minionUuid, String instructionName) {
|
||||
super(worldKey, pos, minionUuid, MinionBlocks.MINION_TRIGGER_BE_TYPE);
|
||||
this.instructionName = Objects.requireNonNull(instructionName);
|
||||
}
|
||||
|
||||
public static void addListener(World world, BlockPos pos, UUID minion, String instructionName) {
|
||||
MinionTriggerMinionListener listener = new MinionTriggerMinionListener(world.getRegistryKey(), pos, minion, instructionName);
|
||||
listener.add(world.getServer());
|
||||
}
|
||||
|
||||
public static void removeListener(World world, BlockPos pos, UUID minion, String instructionName) {
|
||||
MinionTriggerMinionListener old = getListener(world, pos, minion, MinionTriggerMinionListener.class);
|
||||
if(old != null) {
|
||||
old.remove(world.getServer());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, ConfiguredInstructionListener> getInstructionListeners() {
|
||||
return Map.of(instructionName, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMinionSpawn(MinionFakePlayer minion) {
|
||||
super.onMinionSpawn(minion);
|
||||
runningCache = minion.getInstructionManager().getInstruction(instructionName).isRunning();
|
||||
updateComparatorsIfLoaded(minion.getServer());
|
||||
|
||||
ConfiguredInstruction<MinionRuntime> instruction = minion.getInstructionManager().getInstruction(instructionName);
|
||||
if(instruction.isRunning() && !incomingPowerCache) {
|
||||
instruction.stop(minion.getInstructionManager());
|
||||
} else if (!instruction.isRunning() && incomingPowerCache) {
|
||||
instruction.run(minion.getInstructionManager());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMinionRemove(MinionFakePlayer minion) {
|
||||
super.onMinionRemove(minion);
|
||||
runningCache = false;
|
||||
updateComparatorsIfLoaded(minion.getServer());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInstructionRename(MinionFakePlayer minion, ConfiguredInstruction<?> instruction, String oldName, String newName) {
|
||||
super.onInstructionRename(minion, instruction, oldName, newName);
|
||||
if(instructionName.equals(oldName)) {
|
||||
instructionName = newName;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void add(MinecraftServer server) {
|
||||
super.add(server);
|
||||
runningCache = minion.getInstructionManager().getInstruction(instructionName).isRunning();
|
||||
updateComparatorsIfLoaded(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Identifier> getCodecId() {
|
||||
return Optional.of(Identifier.of(Minions.MOD_ID, "minion_trigger"));
|
||||
}
|
||||
|
||||
public void updateComparatorsIfLoaded(MinecraftServer server) {
|
||||
World world = server.getWorld(worldKey);
|
||||
if(world.isPosLoaded(pos)) {
|
||||
world.updateComparators(pos, MinionBlocks.MINION_TRIGGER_BLOCK);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
return runningCache;
|
||||
}
|
||||
|
||||
public class TriggerInstructionListener implements ConfiguredInstructionListener {
|
||||
@Override
|
||||
public void onRun(ConfiguredInstruction<?> instruction) {
|
||||
runningCache = true;
|
||||
updateComparatorsIfLoaded(minion.getServer());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop(ConfiguredInstruction<?> instruction) {
|
||||
runningCache = false;
|
||||
updateComparatorsIfLoaded(minion.getServer());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ public class ListSubcommand {
|
||||
.executes(ListSubcommand::list);
|
||||
|
||||
public static int list(CommandContext<ServerCommandSource> context) {
|
||||
Collection<MinionData> minions = MinionPersistentState.INSTANCE.getMinionData().values();
|
||||
Collection<MinionData> minions = MinionPersistentState.get(context.getSource().getServer()).getMinionData().values();
|
||||
for (MinionData minion : minions) {
|
||||
context.getSource().sendFeedback(() -> Text.literal(minion.name() + "(" + minion.uuid() + "):" + minion.isSpawned()), false);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
import io.github.skippyall.minions.minion.MinionData;
|
||||
import io.github.skippyall.minions.minion.MinionPersistentState;
|
||||
import io.github.skippyall.minions.minion.MinionProfileUtils;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
@@ -21,13 +22,13 @@ public class MinionArgument {
|
||||
|
||||
public static final MinionSuggestionProvider SUGGESTION_PROVIDER = new MinionSuggestionProvider();
|
||||
|
||||
public static MinionData parse(String argument) throws CommandSyntaxException {
|
||||
public static MinionData parse(MinecraftServer server, String argument) throws CommandSyntaxException {
|
||||
Optional<MinionData> data = Optional.empty();
|
||||
if(argument.startsWith(MinionProfileUtils.PREFIX)) {
|
||||
data = MinionPersistentState.INSTANCE.getMinionWithName(argument);
|
||||
data = MinionPersistentState.get(server).getMinionWithName(argument);
|
||||
} else {
|
||||
try {
|
||||
data = Optional.ofNullable(MinionPersistentState.INSTANCE.getMinionData(UUID.fromString(argument)));
|
||||
data = Optional.ofNullable(MinionPersistentState.get(server).getMinionData(UUID.fromString(argument)));
|
||||
} catch (IllegalArgumentException ignored) {}
|
||||
}
|
||||
|
||||
@@ -40,7 +41,7 @@ public class MinionArgument {
|
||||
public static class MinionSuggestionProvider implements SuggestionProvider<ServerCommandSource> {
|
||||
@Override
|
||||
public CompletableFuture<Suggestions> getSuggestions(CommandContext<ServerCommandSource> context, SuggestionsBuilder builder) throws CommandSyntaxException {
|
||||
for (MinionData data : MinionPersistentState.INSTANCE.getMinionDataList()) {
|
||||
for (MinionData data : MinionPersistentState.get(context.getSource().getServer()).getMinionDataList()) {
|
||||
builder.suggest(data.name());
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ public class SpawnSubcommand {
|
||||
);
|
||||
|
||||
public static int spawnCommand(ServerCommandSource source, String minion, PosArgument pos, boolean force) throws CommandSyntaxException {
|
||||
MinionData data = MinionArgument.parse(minion);
|
||||
MinionData data = MinionArgument.parse(source.getServer(), minion);
|
||||
MinionFakePlayer.spawnMinion(data, source.getWorld(), pos != null ? pos.getPos(source) : null, pos != null ? pos.getRotation(source) : null, force);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ public class ConfigureInstructionGui extends InstructionBoundSimpleGui {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInstructionRename(MinionFakePlayer minion, ConfiguredInstruction<?> instruction, String newName) {
|
||||
public void onInstructionRename(MinionFakePlayer minion, ConfiguredInstruction<?> instruction, String oldName, String newName) {
|
||||
this.setTitle(Text.literal(newName));
|
||||
name = newName;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package io.github.skippyall.minions.gui;
|
||||
|
||||
import com.mojang.authlib.properties.PropertyMap;
|
||||
import com.mojang.serialization.Codec;
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.registration.MinionRegistries;
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.util.TranslationUtil;
|
||||
import it.unimi.dsi.fastutil.objects.ReferenceSortedSets;
|
||||
@@ -15,7 +15,6 @@ 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;
|
||||
|
||||
@@ -2,7 +2,7 @@ package io.github.skippyall.minions.gui;
|
||||
|
||||
import eu.pb4.sgui.api.elements.GuiElementBuilder;
|
||||
import eu.pb4.sgui.api.gui.SimpleGui;
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.registration.MinionRegistries;
|
||||
import io.github.skippyall.minions.gui.input.Result;
|
||||
import io.github.skippyall.minions.gui.input.TextInput;
|
||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||
@@ -164,6 +164,7 @@ public class InstructionGui {
|
||||
if (!future.isDone()) {
|
||||
future.cancel(false);
|
||||
}
|
||||
super.onClose();
|
||||
}
|
||||
};
|
||||
gui.setTitle(Text.translatable("minions.gui.instruction.select_instruction"));
|
||||
@@ -193,6 +194,7 @@ public class InstructionGui {
|
||||
if (!future.isDone()) {
|
||||
future.cancel(false);
|
||||
}
|
||||
super.onClose();
|
||||
}
|
||||
};
|
||||
gui.setTitle(Text.translatable("minions.gui.instruction.select_instruction"));
|
||||
|
||||
@@ -2,7 +2,7 @@ package io.github.skippyall.minions.gui;
|
||||
|
||||
import eu.pb4.sgui.api.elements.GuiElementBuilder;
|
||||
import eu.pb4.sgui.api.gui.SimpleGui;
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.registration.MinionRegistries;
|
||||
import io.github.skippyall.minions.gui.input.TextInput;
|
||||
import io.github.skippyall.minions.minion.MinionData;
|
||||
import io.github.skippyall.minions.minion.MinionItem;
|
||||
@@ -49,9 +49,9 @@ public class MinionLookGui extends SimpleGui {
|
||||
GuiElementBuilder builder = new GuiElementBuilder()
|
||||
.setItem(Items.PLAYER_HEAD)
|
||||
.setCallback(() -> currentSkinProvider.openSkinMenu(player).thenAccept(skin -> {
|
||||
MinionItem.setData(getData().withSkin(skin), minionItem);
|
||||
MinionItem.setData(player.getServer(), getData().withSkin(skin), minionItem);
|
||||
}));
|
||||
if(MinionItem.getData(minionItem) != null && MinionItem.getData(minionItem).skin().isPresent()) {
|
||||
if(MinionItem.getData(player.getServer(), minionItem) != null && MinionItem.getData(player.getServer(), minionItem).skin().isPresent()) {
|
||||
builder.setComponent(DataComponentTypes.PROFILE, new ProfileComponent(Optional.empty(), Optional.empty(), getData().skin().get()));
|
||||
}
|
||||
setSlot(16, builder);
|
||||
@@ -77,7 +77,7 @@ public class MinionLookGui extends SimpleGui {
|
||||
}
|
||||
|
||||
private MinionData getData() {
|
||||
return MinionItem.getDataOrDefault(minionItem);
|
||||
return MinionItem.getDataOrDefault(player.getServer(), minionItem);
|
||||
}
|
||||
|
||||
public static void open(ServerPlayerEntity player, ItemStack minionItem) {
|
||||
@@ -87,9 +87,9 @@ public class MinionLookGui extends SimpleGui {
|
||||
}
|
||||
|
||||
public void openRenameGui(ServerPlayerEntity player, ItemStack minionItem) {
|
||||
TextInput.inputSync(player, Text.translatable("minions.gui.look.rename.title"), "Minion", MinionProfileUtils::checkMinionNameWithoutPrefix)
|
||||
TextInput.inputSync(player, Text.translatable("minions.gui.look.rename.title"), "Minion", name -> MinionProfileUtils.checkMinionNameWithoutPrefix(player.getServer(), name))
|
||||
.thenAccept(name -> {
|
||||
MinionItem.setData(getData().withName(MinionProfileUtils.PREFIX + name), minionItem);
|
||||
MinionItem.setData(player.getServer(), getData().withName(MinionProfileUtils.PREFIX + name), minionItem);
|
||||
open();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,22 +1,19 @@
|
||||
package io.github.skippyall.minions.minion;
|
||||
|
||||
import com.mojang.authlib.properties.PropertyMap;
|
||||
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.registration.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;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Uuids;
|
||||
import net.minecraft.util.dynamic.Codecs;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
@@ -28,14 +25,17 @@ public record MinionData(UUID uuid, String name, Optional<PropertyMap> skin, boo
|
||||
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),
|
||||
SerializableListenerManager.getCodec(MinionRegistries.MINION_LISTENER_CODECS).optionalFieldOf("listeners", new SerializableListenerManager<>(MinionRegistries.MINION_LISTENER_CODECS)).forGetter(MinionData::listeners)
|
||||
SerializableListenerManager.getCodec(MinionRegistries.MINION_LISTENER_CODECS).optionalFieldOf("listeners").xmap(
|
||||
optional -> optional.orElseGet(() -> new SerializableListenerManager<>(MinionRegistries.MINION_LISTENER_CODECS)),
|
||||
Optional::of
|
||||
).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, new SerializableListenerManager<>(MinionRegistries.MINION_LISTENER_CODECS));
|
||||
public static MinionData createDefault(MinecraftServer server) {
|
||||
return new MinionData(UUID.randomUUID(), MinionProfileUtils.newDefaultMinionName(server), Optional.empty(), false, new SerializableListenerManager<>(MinionRegistries.MINION_LISTENER_CODECS));
|
||||
}
|
||||
|
||||
public MinionData withName(String name) {
|
||||
@@ -50,14 +50,6 @@ public record MinionData(UUID uuid, String name, Optional<PropertyMap> skin, boo
|
||||
return new MinionData(uuid, name, skin, isSpawned, listeners);
|
||||
}
|
||||
|
||||
public NbtCompound writeNbt() {
|
||||
return (NbtCompound) MinionData.CODEC.encode(this, NbtOps.INSTANCE, null).result().orElse(new NbtCompound());
|
||||
}
|
||||
|
||||
public static MinionData readNbt(NbtCompound nbt) {
|
||||
return MinionData.CODEC.decode(NbtOps.INSTANCE, nbt).resultOrPartial().map(Pair::getFirst).orElseGet(MinionData::createDefault);
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
PolymerComponent.registerDataComponent(COMPONENT);
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUsageContext;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.item.tooltip.TooltipType;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.text.Text;
|
||||
@@ -23,7 +24,6 @@ import net.minecraft.world.World;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import xyz.nucleoid.packettweaker.PacketContext;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class MinionItem extends Item implements PolymerItem {
|
||||
@@ -50,7 +50,7 @@ public class MinionItem extends Item implements PolymerItem {
|
||||
|
||||
@Override
|
||||
public void appendTooltip(ItemStack stack, TooltipContext context, TooltipDisplayComponent component, Consumer<Text> tooltip, TooltipType type) {
|
||||
MinionData data = getData(stack);
|
||||
MinionData data = null /*getData(stack)*/;
|
||||
if(data != null) {
|
||||
tooltip.accept(Text.translatable("minions.minion_item.tooltip", data.name()));
|
||||
}
|
||||
@@ -70,31 +70,31 @@ public class MinionItem extends Item implements PolymerItem {
|
||||
@Override
|
||||
public ActionResult useOnBlock(ItemUsageContext context) {
|
||||
if(!context.getWorld().isClient) {
|
||||
MinionData data = getDataOrDefault(context.getStack());
|
||||
MinionData data = getDataOrDefault(context.getWorld().getServer(), context.getStack());
|
||||
MinionFakePlayer.spawnMinion(data, (ServerWorld) context.getWorld(), context.getBlockPos().toCenterPos().add(0,0.5,0), new Vec2f(0, 0));
|
||||
}
|
||||
context.getStack().decrement(1);
|
||||
return ActionResult.SUCCESS;
|
||||
}
|
||||
|
||||
public static void setData(MinionData data, ItemStack item) {
|
||||
public static void setData(MinecraftServer server, MinionData data, ItemStack item) {
|
||||
item.set(MinionData.COMPONENT, data.uuid());
|
||||
MinionPersistentState.INSTANCE.updateMinionData(data);
|
||||
MinionPersistentState.get(server).updateMinionData(data);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static MinionData getData(ItemStack item) {
|
||||
public static MinionData getData(MinecraftServer server, ItemStack item) {
|
||||
if(item.contains(MinionData.COMPONENT)) {
|
||||
return MinionPersistentState.INSTANCE.getMinionData(item.get(MinionData.COMPONENT));
|
||||
return MinionPersistentState.get(server).getMinionData(item.get(MinionData.COMPONENT));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static MinionData getDataOrDefault(ItemStack item) {
|
||||
MinionData data = getData(item);
|
||||
public static MinionData getDataOrDefault(MinecraftServer server, ItemStack item) {
|
||||
MinionData data = getData(server, item);
|
||||
if(data == null) {
|
||||
data = MinionData.createDefault();
|
||||
setData(data, item);
|
||||
data = MinionData.createDefault(server);
|
||||
setData(server, data, item);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ public interface MinionListener extends SerializableListenerManager.Serializable
|
||||
|
||||
default void onInstructionsUpdate(MinionFakePlayer minion) {}
|
||||
|
||||
default void onInstructionRename(MinionFakePlayer minion, ConfiguredInstruction<?> instruction, String newName) {}
|
||||
default void onInstructionRename(MinionFakePlayer minion, ConfiguredInstruction<?> instruction, String oldName, String newName) {}
|
||||
|
||||
interface Delegating extends MinionListener {
|
||||
@Nullable MinionListener getBacking();
|
||||
@@ -34,14 +34,14 @@ public interface MinionListener extends SerializableListenerManager.Serializable
|
||||
@Override
|
||||
default void onInstructionsUpdate(MinionFakePlayer minion) {
|
||||
if(getBacking() != null) {
|
||||
getBacking().onMinionSpawn(minion);
|
||||
getBacking().onInstructionsUpdate(minion);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
default void onInstructionRename(MinionFakePlayer minion, ConfiguredInstruction<?> instruction, String newName) {
|
||||
default void onInstructionRename(MinionFakePlayer minion, ConfiguredInstruction<?> instruction, String oldName, String newName) {
|
||||
if(getBacking() != null) {
|
||||
getBacking().onInstructionRename(minion, instruction, newName);
|
||||
getBacking().onInstructionRename(minion, instruction, oldName, newName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,6 @@ public class MinionPersistentState extends PersistentState {
|
||||
|
||||
public static PersistentStateType<MinionPersistentState> TYPE = new PersistentStateType<>("minion", MinionPersistentState::new, MinionPersistentState.CODEC, null);
|
||||
|
||||
public static MinionPersistentState INSTANCE;
|
||||
|
||||
private final Map<UUID, MinionData> minionData = new HashMap<>();
|
||||
|
||||
public MinionPersistentState() {
|
||||
@@ -62,7 +60,7 @@ public class MinionPersistentState extends PersistentState {
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
public static void create(MinecraftServer server) {
|
||||
INSTANCE = server.getWorld(World.OVERWORLD).getPersistentStateManager().getOrCreate(TYPE);
|
||||
public static MinionPersistentState get(MinecraftServer server) {
|
||||
return server.getWorld(World.OVERWORLD).getPersistentStateManager().getOrCreate(TYPE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.properties.PropertyMap;
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import io.github.skippyall.minions.gui.input.Result;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.StringHelper;
|
||||
|
||||
@@ -27,7 +28,7 @@ public class MinionProfileUtils {
|
||||
return newProfile;
|
||||
}
|
||||
|
||||
public static Result<String, Text> checkMinionNameWithoutPrefix(String name) {
|
||||
public static Result<String, Text> checkMinionNameWithoutPrefix(MinecraftServer server, String name) {
|
||||
for(char c : name.toCharArray()) {
|
||||
if(!StringReader.isAllowedInUnquotedString(c)) {
|
||||
return new Result.Error<>(Text.translatable("minions.generic.name.invalid_char"));
|
||||
@@ -42,22 +43,22 @@ public class MinionProfileUtils {
|
||||
return new Result.Error<>(Text.translatable("minions.generic.name.invalid"));
|
||||
}
|
||||
|
||||
if(MinionPersistentState.INSTANCE.isMinionNameTaken(PREFIX + name)) {
|
||||
if(MinionPersistentState.get(server).isMinionNameTaken(PREFIX + name)) {
|
||||
return new Result.Error<>(Text.translatable("minions.generic.name.taken"));
|
||||
}
|
||||
|
||||
return new Result.Success<>(name);
|
||||
}
|
||||
|
||||
public static String newDefaultMinionName() {
|
||||
public static String newDefaultMinionName(MinecraftServer server) {
|
||||
int i = 0;
|
||||
while (MinionPersistentState.INSTANCE.isMinionNameTaken("+Minion" + i)) {
|
||||
while (MinionPersistentState.get(server).isMinionNameTaken("+Minion" + i)) {
|
||||
i++;
|
||||
}
|
||||
return "+Minion" + i;
|
||||
}
|
||||
|
||||
public static boolean isMinion(UUID uuid) {
|
||||
return MinionPersistentState.INSTANCE.isMinion(uuid);
|
||||
public static boolean isMinion(MinecraftServer server, UUID uuid) {
|
||||
return MinionPersistentState.get(server).isMinion(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.github.skippyall.minions.minion;
|
||||
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.registration.MinionRegistries;
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.program.InstructionRuntime;
|
||||
@@ -83,7 +83,7 @@ public class MinionRuntime implements InstructionRuntime<MinionRuntime> {
|
||||
|
||||
|
||||
minion.forEachMinionListener(minionListener -> {
|
||||
minionListener.onInstructionRename(minion , instruction, newName);
|
||||
minionListener.onInstructionRename(minion, instruction, oldName, newName);
|
||||
minionListener.onInstructionsUpdate(minion);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,8 +3,7 @@ package io.github.skippyall.minions.minion.fakeplayer;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.properties.PropertyMap;
|
||||
import io.github.skippyall.minions.MinionItems;
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.registration.MinionItems;
|
||||
import io.github.skippyall.minions.minion.MinionListener;
|
||||
import io.github.skippyall.minions.minion.MinionData;
|
||||
import io.github.skippyall.minions.gui.MinionGui;
|
||||
@@ -12,7 +11,6 @@ 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;
|
||||
@@ -57,12 +55,9 @@ 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(this);
|
||||
private final MinionRuntime instructionManager = new MinionRuntime(this);
|
||||
|
||||
private final MinionData data;
|
||||
|
||||
public static void spawnMinion(MinionData data, ServerWorld level, @Nullable Vec3d pos, @Nullable Vec2f rot) {
|
||||
spawnMinion(data, level, pos, rot, false);
|
||||
}
|
||||
@@ -79,8 +74,8 @@ public class MinionFakePlayer extends ServerPlayerEntity {
|
||||
}
|
||||
|
||||
private static void doSpawn(MinionData data, GameProfile profile, MinecraftServer server, ServerWorld level, @Nullable Vec3d pos, @Nullable Vec2f rot) {
|
||||
MinionFakePlayer instance = new MinionFakePlayer(server, level, profile, SyncedClientOptions.createDefault(), data);
|
||||
MinionPersistentState.INSTANCE.updateMinionData(data.withSpawned(true));
|
||||
MinionFakePlayer instance = new MinionFakePlayer(server, level, profile, SyncedClientOptions.createDefault());
|
||||
MinionPersistentState.get(server).updateMinionData(data.withSpawned(true));
|
||||
|
||||
if(pos != null && rot != null) {
|
||||
instance.fixStartingPosition = () -> instance.refreshPositionAndAngles(pos.x, pos.y, pos.z, rot.x, rot.y);
|
||||
@@ -101,18 +96,17 @@ public class MinionFakePlayer extends ServerPlayerEntity {
|
||||
instance.dataTracker.set(PLAYER_MODEL_PARTS, (byte) 0x7f); // show all model layers (incl. capes)
|
||||
instance.getAbilities().flying = false;
|
||||
|
||||
instance.minionListeners.forEachListener(listener -> listener.onMinionSpawn(instance));
|
||||
instance.listeners().forEach(listener -> listener.onMinionSpawn(instance));
|
||||
}
|
||||
|
||||
public static MinionFakePlayer respawnFake(MinecraftServer server, ServerWorld level, GameProfile profile, SyncedClientOptions cli, MinionData data)
|
||||
public static MinionFakePlayer respawnFake(MinecraftServer server, ServerWorld level, GameProfile profile, SyncedClientOptions cli)
|
||||
{
|
||||
return new MinionFakePlayer(server, level, profile, cli, data);
|
||||
return new MinionFakePlayer(server, level, profile, cli);
|
||||
}
|
||||
|
||||
private MinionFakePlayer(MinecraftServer server, ServerWorld worldIn, GameProfile profile, SyncedClientOptions cli, MinionData data)
|
||||
private MinionFakePlayer(MinecraftServer server, ServerWorld worldIn, GameProfile profile, SyncedClientOptions cli)
|
||||
{
|
||||
super(server, worldIn, profile, cli);
|
||||
this.data = data;
|
||||
actionPack = new EntityPlayerActionPack(this);
|
||||
}
|
||||
|
||||
@@ -129,19 +123,23 @@ public class MinionFakePlayer extends ServerPlayerEntity {
|
||||
}
|
||||
|
||||
public MinionData getData() {
|
||||
return data;
|
||||
return MinionPersistentState.get(getServer()).getMinionData(getUuid());
|
||||
}
|
||||
|
||||
public SerializableListenerManager<MinionListener> listeners() {
|
||||
return getData().listeners();
|
||||
}
|
||||
|
||||
public void addMinionListener(MinionListener listener) {
|
||||
minionListeners.addListener(listener);
|
||||
listeners().addListener(listener);
|
||||
}
|
||||
|
||||
public void removeMinionListener(MinionListener listener) {
|
||||
minionListeners.removeListener(listener);
|
||||
listeners().removeListener(listener);
|
||||
}
|
||||
|
||||
public void forEachMinionListener(Consumer<MinionListener> listenerConsumer) {
|
||||
minionListeners.forEachListener(listenerConsumer);
|
||||
listeners().forEach(listenerConsumer);
|
||||
}
|
||||
|
||||
public boolean canSpawnMobs() {
|
||||
@@ -173,7 +171,7 @@ public class MinionFakePlayer extends ServerPlayerEntity {
|
||||
|
||||
public void kill(Text reason)
|
||||
{
|
||||
minionListeners.forEachListener(listener -> listener.onMinionRemove(this));
|
||||
listeners().forEach(listener -> listener.onMinionRemove(this));
|
||||
|
||||
shakeOff();
|
||||
|
||||
@@ -185,7 +183,7 @@ public class MinionFakePlayer extends ServerPlayerEntity {
|
||||
}));
|
||||
}
|
||||
|
||||
MinionPersistentState.INSTANCE.updateMinionData(data.withSpawned(false));
|
||||
MinionPersistentState.get(getServer()).updateMinionData(getData().withSpawned(false));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -266,15 +264,15 @@ public class MinionFakePlayer extends ServerPlayerEntity {
|
||||
@Override
|
||||
public void drop(ServerWorld world, DamageSource damageSource) {
|
||||
super.drop(world, damageSource);
|
||||
ItemEntity entity = dropStack(world, toItemStack());
|
||||
ItemEntity entity = dropStack(world, toItemStack(getServer()));
|
||||
if (entity != null) {
|
||||
entity.setNeverDespawn();
|
||||
}
|
||||
}
|
||||
|
||||
private ItemStack toItemStack() {
|
||||
private ItemStack toItemStack(MinecraftServer server) {
|
||||
ItemStack stack = new ItemStack(MinionItems.MINION_ITEM);
|
||||
MinionItem.setData(data, stack);
|
||||
MinionItem.setData(server, getData(), stack);
|
||||
return stack;
|
||||
}
|
||||
|
||||
@@ -283,7 +281,6 @@ public class MinionFakePlayer extends ServerPlayerEntity {
|
||||
super.writeCustomData(view);
|
||||
moduleInventory.writeData(view.get("modules"));
|
||||
instructionManager.save(view.get("instructionManager"));
|
||||
minionListeners.save(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -291,6 +288,5 @@ public class MinionFakePlayer extends ServerPlayerEntity {
|
||||
super.readCustomData(view);
|
||||
moduleInventory.readData(view.getReadView("modules"));
|
||||
instructionManager.load(view.getReadView("instructionManager"));
|
||||
minionListeners.load(view);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.github.skippyall.minions.minion.skin;
|
||||
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.registration.MinionRegistries;
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
@@ -54,7 +54,7 @@ public class PlayerListMixin {
|
||||
@WrapOperation(method = "respawnPlayer", at = @At(value = "NEW", target = "(Lnet/minecraft/server/MinecraftServer;Lnet/minecraft/server/world/ServerWorld;Lcom/mojang/authlib/GameProfile;Lnet/minecraft/network/packet/c2s/common/SyncedClientOptions;)Lnet/minecraft/server/network/ServerPlayerEntity;"))
|
||||
public ServerPlayerEntity makePlayerForRespawn(MinecraftServer minecraftServer, ServerWorld serverLevel, GameProfile gameProfile, SyncedClientOptions clientInformation, Operation<ServerPlayerEntity> original, ServerPlayerEntity serverPlayer, boolean bl) {
|
||||
if (serverPlayer instanceof MinionFakePlayer minion) {
|
||||
return MinionFakePlayer.respawnFake(minecraftServer, serverLevel, gameProfile, clientInformation, minion.getData());
|
||||
return MinionFakePlayer.respawnFake(minecraftServer, serverLevel, gameProfile, clientInformation);
|
||||
}
|
||||
return original.call(minecraftServer, serverLevel, gameProfile, clientInformation);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package io.github.skippyall.minions.module;
|
||||
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.registration.MinionRegistries;
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||
import io.github.skippyall.minions.program.instruction.InstructionType;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.github.skippyall.minions.module;
|
||||
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.registration.MinionRegistries;
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.github.skippyall.minions.program.consumer;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.registration.MinionRegistries;
|
||||
import io.github.skippyall.minions.program.InstructionRuntime;
|
||||
import io.github.skippyall.minions.program.value.ValueType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
+6
-6
@@ -1,6 +1,6 @@
|
||||
package io.github.skippyall.minions.program.instruction;
|
||||
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.registration.MinionRegistries;
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.program.InstructionRuntime;
|
||||
import io.github.skippyall.minions.program.supplier.Parameter;
|
||||
@@ -66,7 +66,7 @@ public class ConfiguredInstruction<R extends InstructionRuntime<R>> {
|
||||
Minions.LOGGER.error("An error occurred while executing configured Instruction", e);
|
||||
}
|
||||
|
||||
listeners.forEachListener(listener -> listener.onRun(this));
|
||||
listeners.forEach(listener -> listener.onRun(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,20 +87,20 @@ public class ConfiguredInstruction<R extends InstructionRuntime<R>> {
|
||||
if(execution != null) {
|
||||
execution.stop(minion, valueConsumers);
|
||||
execution = null;
|
||||
listeners.forEachListener(listener -> listener.onStop(this));
|
||||
listeners.forEach(listener -> listener.onStop(this));
|
||||
}
|
||||
}
|
||||
|
||||
private void onSupplierChange(Parameter<?> parameter) {
|
||||
listeners.forEachListener(listener -> listener.onSupplierChange(this, parameter));
|
||||
listeners.forEach(listener -> listener.onSupplierChange(this, parameter));
|
||||
}
|
||||
|
||||
private void onConsumerChange(Parameter<?> parameter) {
|
||||
listeners.forEachListener(listener -> listener.onConsumerChange(this, parameter));
|
||||
listeners.forEach(listener -> listener.onConsumerChange(this, parameter));
|
||||
}
|
||||
|
||||
public void onInstructionRemove() {
|
||||
listeners.forEachListener(listener -> listener.onInstructionRemove(this));
|
||||
listeners.forEach(listener -> listener.onInstructionRemove(this));
|
||||
}
|
||||
|
||||
public void addListener(ConfiguredInstructionListener listener) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.github.skippyall.minions.program.instruction;
|
||||
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.registration.MinionRegistries;
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.EntityPlayerActionPack;
|
||||
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
package io.github.skippyall.minions.program.instruction.execution.inventory;
|
||||
|
||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.program.consumer.ValueConsumerList;
|
||||
import io.github.skippyall.minions.program.instruction.InstructionExecution;
|
||||
import io.github.skippyall.minions.program.supplier.ValueSupplierList;
|
||||
import net.minecraft.component.EnchantmentEffectComponentTypes;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
import net.minecraft.screen.slot.SlotActionType;
|
||||
import net.minecraft.storage.ReadView;
|
||||
import net.minecraft.storage.WriteView;
|
||||
|
||||
public class SwapItemExecution implements InstructionExecution<MinionRuntime> {
|
||||
private int fromSlot;
|
||||
private boolean fromScreen;
|
||||
private int toSlot;
|
||||
private boolean toScreen;
|
||||
|
||||
@Override
|
||||
public void start(MinionRuntime runtime) {
|
||||
MinionFakePlayer minion = runtime.getMinion();
|
||||
|
||||
if((fromScreen || toScreen) && minion.currentScreenHandler == null) {
|
||||
return;
|
||||
}
|
||||
if(!(checkBounds(minion, fromSlot, fromScreen) && checkBounds(minion, toSlot, toScreen))) {
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack fromStack = getStack(minion, fromSlot, fromScreen);
|
||||
ItemStack toStack = getStack(minion, toSlot, toScreen);
|
||||
|
||||
if(!(canExchange(minion, fromSlot, fromScreen, toStack) && canExchange(minion, toSlot, toScreen, fromStack))) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private boolean checkBounds(MinionFakePlayer minion, int slot, boolean screen) {
|
||||
if(screen) {
|
||||
return slot >= 0 && slot < minion.currentScreenHandler.slots.size();
|
||||
} else {
|
||||
return slot >= 0 && slot <= PlayerInventory.OFF_HAND_SLOT;
|
||||
}
|
||||
}
|
||||
|
||||
private ItemStack getStack(MinionFakePlayer minion, int slot, boolean screen) {
|
||||
if(screen) {
|
||||
return minion.currentScreenHandler.getSlot(slot).getStack();
|
||||
} else {
|
||||
return minion.getInventory().getStack(slot);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canExchange(MinionFakePlayer minion, int slotIndex, boolean screen, ItemStack newStack) {
|
||||
if(screen) {
|
||||
Slot slot = minion.currentScreenHandler.getSlot(slotIndex);
|
||||
if(!slot.getStack().isEmpty() && !slot.canTakeItems(minion)) {
|
||||
return false;
|
||||
}
|
||||
if(!newStack.isEmpty() && !slot.canInsert(newStack)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if(slotIndex >= PlayerInventory.MAIN_SIZE && slotIndex < PlayerInventory.OFF_HAND_SLOT) {
|
||||
if(!minion.canEquip(newStack, PlayerInventory.EQUIPMENT_SLOTS.get(slotIndex))) {
|
||||
return false;
|
||||
}
|
||||
if(EnchantmentHelper.hasAnyEnchantmentsWith(minion.getInventory().getStack(slotIndex), EnchantmentEffectComponentTypes.PREVENT_ARMOR_CHANGE)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void simulateClick(MinionFakePlayer minion, int slotIndex, boolean screen) {
|
||||
if(screen) {
|
||||
minion.currentScreenHandler.onSlotClick(slotIndex, 0, SlotActionType.SWAP, minion);
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(MinionRuntime runtime) {
|
||||
InstructionExecution.super.tick(runtime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDone(MinionRuntime runtime) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop(MinionRuntime runtime, ValueConsumerList<MinionRuntime> valueConsumers) {
|
||||
InstructionExecution.super.stop(runtime, valueConsumers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readArguments(ValueSupplierList<MinionRuntime> arguments, MinionRuntime runtime) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(WriteView view, MinionRuntime runtime) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(ReadView view, MinionRuntime runtime) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ package io.github.skippyall.minions.program.supplier;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.registration.MinionRegistries;
|
||||
import io.github.skippyall.minions.program.value.ValueType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.github.skippyall.minions.program.supplier;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.registration.MinionRegistries;
|
||||
import io.github.skippyall.minions.program.InstructionRuntime;
|
||||
import io.github.skippyall.minions.program.value.ValueType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.github.skippyall.minions.program.supplier;
|
||||
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.registration.MinionRegistries;
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.minion.MinionRuntime;
|
||||
import net.minecraft.registry.Registry;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.github.skippyall.minions.program.value;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.registration.MinionRegistries;
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.gui.input.ChoiceInput;
|
||||
import io.github.skippyall.minions.gui.input.TextInput;
|
||||
|
||||
@@ -3,7 +3,7 @@ package io.github.skippyall.minions.reference;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import eu.pb4.polymer.core.api.other.PolymerComponent;
|
||||
import io.github.skippyall.minions.MinionRegistries;
|
||||
import io.github.skippyall.minions.registration.MinionRegistries;
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import net.fabricmc.fabric.api.item.v1.ComponentTooltipAppenderRegistry;
|
||||
import net.minecraft.component.ComponentType;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.github.skippyall.minions.reference;
|
||||
|
||||
import eu.pb4.polymer.core.api.item.PolymerItem;
|
||||
import io.github.skippyall.minions.MinionItems;
|
||||
import io.github.skippyall.minions.registration.MinionItems;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import net.minecraft.component.DataComponentTypes;
|
||||
import net.minecraft.item.Item;
|
||||
|
||||
+4
-3
@@ -1,8 +1,9 @@
|
||||
package io.github.skippyall.minions;
|
||||
package io.github.skippyall.minions.registration;
|
||||
|
||||
import eu.pb4.polymer.core.api.block.PolymerBlockUtils;
|
||||
import io.github.skippyall.minions.block.MinionTriggerBlock;
|
||||
import io.github.skippyall.minions.block.MinionTriggerBlockEntity;
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.block.miniontrigger.MinionTriggerBlock;
|
||||
import io.github.skippyall.minions.block.miniontrigger.MinionTriggerBlockEntity;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder;
|
||||
import net.minecraft.block.AbstractBlock;
|
||||
import net.minecraft.block.entity.BlockEntityType;
|
||||
+2
-1
@@ -1,6 +1,7 @@
|
||||
package io.github.skippyall.minions;
|
||||
package io.github.skippyall.minions.registration;
|
||||
|
||||
import eu.pb4.polymer.core.api.item.PolymerItemGroupUtils;
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemGroup;
|
||||
+4
-4
@@ -1,12 +1,11 @@
|
||||
package io.github.skippyall.minions;
|
||||
package io.github.skippyall.minions.registration;
|
||||
|
||||
import eu.pb4.polymer.core.api.item.PolymerBlockItem;
|
||||
import eu.pb4.polymer.core.api.item.SimplePolymerItem;
|
||||
import io.github.skippyall.minions.block.MinionTriggerBlockItem;
|
||||
import io.github.skippyall.minions.block.miniontrigger.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;
|
||||
@@ -75,7 +74,8 @@ public class MinionItems {
|
||||
public static final PolymerBlockItem MINION_TRIGGER_ITEM =
|
||||
registerItem(
|
||||
MinionBlocks.MINION_TRIGGER_ID,
|
||||
settings -> new MinionTriggerBlockItem(MinionBlocks.MINION_TRIGGER_BLOCK, settings, Items.COMPARATOR)
|
||||
settings -> new MinionTriggerBlockItem(MinionBlocks.MINION_TRIGGER_BLOCK, settings, Items.COMPARATOR),
|
||||
new Item.Settings().useBlockPrefixedTranslationKey()
|
||||
);
|
||||
|
||||
public static final ReferenceItem REFERENCE_ITEM = registerItem(Identifier.of(MOD_ID, "reference"), ReferenceItem::new);
|
||||
@@ -0,0 +1,13 @@
|
||||
package io.github.skippyall.minions.registration;
|
||||
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.block.miniontrigger.MinionTriggerMinionListener;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class MinionRegistration {
|
||||
|
||||
public static void register() {
|
||||
Registry.register(MinionRegistries.MINION_LISTENER_CODECS, Identifier.of(Minions.MOD_ID, "minion_trigger"), MinionTriggerMinionListener.CODEC);
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -1,7 +1,8 @@
|
||||
package io.github.skippyall.minions;
|
||||
package io.github.skippyall.minions.registration;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import io.github.skippyall.minions.Minions;
|
||||
import io.github.skippyall.minions.docs.ReferenceEntry;
|
||||
import io.github.skippyall.minions.gui.GuiDisplay;
|
||||
import io.github.skippyall.minions.minion.MinionListener;
|
||||
@@ -1,10 +1,12 @@
|
||||
package io.github.skippyall.minions.util;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ListenerManager<T> {
|
||||
public class ListenerManager<T> implements Iterable<T> {
|
||||
protected final List<T> listeners;
|
||||
|
||||
public ListenerManager() {
|
||||
@@ -15,17 +17,44 @@ public class ListenerManager<T> {
|
||||
this.listeners = listeners;
|
||||
}
|
||||
|
||||
public void forEachListener(Consumer<T> listenerConsumer) {
|
||||
for(T listener : listeners) {
|
||||
listenerConsumer.accept(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public void addListener(T listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
public void removeListener(T listener) {
|
||||
listeners.remove(listener);
|
||||
onRemove(listener);
|
||||
}
|
||||
|
||||
protected void onRemove(T listener) {}
|
||||
|
||||
@Override
|
||||
public @NotNull Iterator<T> iterator() {
|
||||
return new Iterator<>() {
|
||||
final Iterator<T> backing = listeners.iterator();
|
||||
T last;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return backing.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
last = backing.next();
|
||||
return last;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
backing.remove();
|
||||
onRemove(last);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return super.equals(obj);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,6 +81,8 @@
|
||||
"item.minions.advanced_upgrade_base": "Advanced Upgrade Base",
|
||||
"item.minions.reference": "Reference",
|
||||
|
||||
"block.minions.minion_trigger": "Minion Trigger",
|
||||
|
||||
"minions.minion_item.tooltip": "Name: %s",
|
||||
"minions.generic.name.invalid_char": "Name contains invalid character",
|
||||
"minions.generic.name.too_long": "Name is too long",
|
||||
|
||||
Reference in New Issue
Block a user