Drive viewer test code

This commit is contained in:
DBotThePony 2021-08-27 13:16:54 +07:00
parent 2166119a75
commit 05bed3a737
Signed by: DBot
GPG Key ID: DCC23B5715498507
17 changed files with 768 additions and 27 deletions

View File

@ -87,6 +87,7 @@ public class Registry {
public static final ResourceLocation MATTER_PANEL = new ResourceLocation(OverdriveThatMatters.MOD_ID, "matter_panel");
public static final ResourceLocation MATTER_REPLICATOR = new ResourceLocation(OverdriveThatMatters.MOD_ID, "matter_replicator");
public static final ResourceLocation MATTER_BOTTLER = new ResourceLocation(OverdriveThatMatters.MOD_ID, "matter_bottler");
public static final ResourceLocation DRIVE_VIEWER = new ResourceLocation(OverdriveThatMatters.MOD_ID, "drive_viewer");
// capabilities
public static final ResourceLocation ANDROID_CAPABILITY = new ResourceLocation(OverdriveThatMatters.MOD_ID, "android_capability");
@ -174,6 +175,7 @@ public class Registry {
public static final Block MATTER_PANEL = new BlockMatterPanel();
public static final Block MATTER_REPLICATOR = new BlockMatterReplicator();
public static final Block MATTER_BOTTLER = new BlockMatterBottler();
public static final Block DRIVE_VIEWER = new BlockDriveViewer();
static {
ANDROID_STATION.setRegistryName(Names.ANDROID_STATION);
@ -186,6 +188,7 @@ public class Registry {
MATTER_PANEL.setRegistryName(Names.MATTER_PANEL);
MATTER_REPLICATOR.setRegistryName(Names.MATTER_REPLICATOR);
MATTER_BOTTLER.setRegistryName(Names.MATTER_BOTTLER);
DRIVE_VIEWER.setRegistryName(Names.DRIVE_VIEWER);
}
@SubscribeEvent
@ -200,6 +203,7 @@ public class Registry {
event.getRegistry().register(MATTER_PANEL);
event.getRegistry().register(MATTER_REPLICATOR);
event.getRegistry().register(MATTER_BOTTLER);
event.getRegistry().register(DRIVE_VIEWER);
// OverdriveThatMatters.LOGGER.info("Registered blocks");
}
@ -216,6 +220,7 @@ public class Registry {
public static final Item MATTER_PANEL = new BlockItem(Blocks.MATTER_PANEL, new Item.Properties().stacksTo(64).tab(OverdriveThatMatters.CREATIVE_TAB));
public static final Item MATTER_REPLICATOR = new BlockItem(Blocks.MATTER_REPLICATOR, new Item.Properties().stacksTo(64).tab(OverdriveThatMatters.CREATIVE_TAB));
public static final Item MATTER_BOTTLER = new BlockItem(Blocks.MATTER_BOTTLER, new Item.Properties().stacksTo(64).tab(OverdriveThatMatters.CREATIVE_TAB));
public static final Item DRIVE_VIEWER = new BlockItem(Blocks.DRIVE_VIEWER, new Item.Properties().stacksTo(64).tab(OverdriveThatMatters.CREATIVE_TAB));
public static final ItemPill PILL_ANDROID = new ItemPill(ItemPill.PillType.BECOME_ANDROID);
public static final ItemPill PILL_HUMANE = new ItemPill(ItemPill.PillType.BECOME_HUMANE);
@ -248,6 +253,7 @@ public class Registry {
MATTER_PANEL.setRegistryName(Names.MATTER_PANEL);
MATTER_REPLICATOR.setRegistryName(Names.MATTER_REPLICATOR);
MATTER_BOTTLER.setRegistryName(Names.MATTER_BOTTLER);
DRIVE_VIEWER.setRegistryName(Names.DRIVE_VIEWER);
PILL_ANDROID.setRegistryName(Names.PILL_ANDROID);
PILL_HUMANE.setRegistryName(Names.PILL_HUMANE);
@ -280,6 +286,7 @@ public class Registry {
event.getRegistry().register(MATTER_PANEL);
event.getRegistry().register(MATTER_REPLICATOR);
event.getRegistry().register(MATTER_BOTTLER);
event.getRegistry().register(DRIVE_VIEWER);
event.getRegistry().register(PILL_ANDROID);
event.getRegistry().register(PILL_HUMANE);
@ -314,6 +321,7 @@ public class Registry {
public static final BlockEntityType<BlockEntityMatterPanel> MATTER_PANEL = BlockEntityType.Builder.of(BlockEntityMatterPanel::new, Blocks.MATTER_PANEL).build(null);
public static final BlockEntityType<BlockEntityMatterReplicator> MATTER_REPLICATOR = BlockEntityType.Builder.of(BlockEntityMatterReplicator::new, Blocks.MATTER_REPLICATOR).build(null);
public static final BlockEntityType<BlockEntityMatterBottler> MATTER_BOTTLER = BlockEntityType.Builder.of(BlockEntityMatterBottler::new, Blocks.MATTER_BOTTLER).build(null);
public static final BlockEntityType<BlockEntityDriveViewer> DRIVE_VIEWER = BlockEntityType.Builder.of(BlockEntityDriveViewer::new, Blocks.DRIVE_VIEWER).build(null);
static {
ANDROID_STATION.setRegistryName(Names.ANDROID_STATION);
@ -326,6 +334,7 @@ public class Registry {
MATTER_PANEL.setRegistryName(Names.MATTER_PANEL);
MATTER_REPLICATOR.setRegistryName(Names.MATTER_REPLICATOR);
MATTER_BOTTLER.setRegistryName(Names.MATTER_BOTTLER);
DRIVE_VIEWER.setRegistryName(Names.DRIVE_VIEWER);
}
@SubscribeEvent
@ -340,6 +349,7 @@ public class Registry {
event.getRegistry().register(MATTER_PANEL);
event.getRegistry().register(MATTER_REPLICATOR);
event.getRegistry().register(MATTER_BOTTLER);
event.getRegistry().register(DRIVE_VIEWER);
// OverdriveThatMatters.LOGGER.info("Registered block entities");
}
@ -575,6 +585,7 @@ public class Registry {
public static final MenuType<MatterPanelMenu> MATTER_PANEL = new MenuType<>(MatterPanelMenu::new);
public static final MenuType<MatterReplicatorMenu> MATTER_REPLICATOR = new MenuType<>(MatterReplicatorMenu::new);
public static final MenuType<MatterBottlerMenu> MATTER_BOTTLER = new MenuType<>(MatterBottlerMenu::new);
public static final MenuType<DriveViewerMenu> DRIVE_VIEWER = new MenuType<>(DriveViewerMenu::new);
static {
ANDROID_STATION.setRegistryName(Names.ANDROID_STATION);
@ -586,6 +597,7 @@ public class Registry {
MATTER_PANEL.setRegistryName(Names.MATTER_PANEL);
MATTER_REPLICATOR.setRegistryName(Names.MATTER_REPLICATOR);
MATTER_BOTTLER.setRegistryName(Names.MATTER_BOTTLER);
DRIVE_VIEWER.setRegistryName(Names.DRIVE_VIEWER);
}
@SubscribeEvent
@ -599,6 +611,7 @@ public class Registry {
event.getRegistry().register(MATTER_PANEL);
event.getRegistry().register(MATTER_REPLICATOR);
event.getRegistry().register(MATTER_BOTTLER);
event.getRegistry().register(DRIVE_VIEWER);
// OverdriveThatMatters.LOGGER.info("Registered menus");
}
@ -614,6 +627,7 @@ public class Registry {
MenuScreens.register(MATTER_PANEL, MatterPanelScreen::new);
MenuScreens.register(MATTER_REPLICATOR, MatterReplicatorScreen::new);
MenuScreens.register(MATTER_BOTTLER, MatterBottlerScreen::new);
MenuScreens.register(DRIVE_VIEWER, DriveViewerScreen::new);
// OverdriveThatMatters.LOGGER.info("Registered screens");
}

View File

@ -0,0 +1,17 @@
package ru.dbotthepony.mc.otm.block;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.EntityBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import ru.dbotthepony.mc.otm.block.entity.BlockEntityDriveViewer;
import javax.annotation.Nullable;
public class BlockDriveViewer extends BlockMatteryRotatable implements EntityBlock {
@Nullable
@Override
public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
return new BlockEntityDriveViewer(blockPos, blockState);
}
}

View File

@ -0,0 +1,52 @@
package ru.dbotthepony.mc.otm.block.entity;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import ru.dbotthepony.mc.otm.Registry;
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage;
import ru.dbotthepony.mc.otm.container.MatteryContainer;
import ru.dbotthepony.mc.otm.menu.DriveViewerMenu;
import javax.annotation.Nullable;
import java.math.BigDecimal;
public class BlockEntityDriveViewer extends BlockEntityMatteryPowered {
public BlockEntityDriveViewer(BlockPos p_155229_, BlockState p_155230_) {
super(Registry.BlockEntities.DRIVE_VIEWER, p_155229_, p_155230_);
energy = new MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, new BigDecimal(30_000));
}
private static final TranslatableComponent NAME = new TranslatableComponent("block.overdrive_that_matters.drive_viewer");
public final MatteryContainer drive_slot = new MatteryContainer(this::setChanged, 1);
@Override
protected Component getDefaultDisplayName() {
return NAME;
}
@Nullable
@Override
public AbstractContainerMenu createMenu(int containerID, Inventory inventory, Player ply) {
return new DriveViewerMenu(containerID, inventory, this);
}
@Override
public CompoundTag save(CompoundTag nbt) {
nbt.put("drive_slot", drive_slot.serializeNBT());
return super.save(nbt);
}
@Override
public void load(CompoundTag nbt) {
super.load(nbt);
drive_slot.deserializeNBT(nbt.get("drive_slot"));
}
}

View File

@ -33,7 +33,7 @@ public interface IMatteryDrive {
List<StoredStack> findItems(@Nonnull ItemStack stack);
@Nullable
StoredStack getItem(@Nonnull UUID id);
StoredStack getItem(int id);
int getStoredCount();
int getCapacity();
@ -42,12 +42,12 @@ public interface IMatteryDrive {
ItemStack insertItem(@Nonnull ItemStack item, boolean simulate);
@Nonnull
default ItemStack extractItem(@Nonnull UUID id, int amount, boolean simulate) {
default ItemStack extractItem(int id, int amount, boolean simulate) {
return extractItem(id, amount, true, simulate);
}
@Nonnull
ItemStack extractItem(@Nonnull UUID id, int amount, boolean obey_stack_size, boolean simulate);
ItemStack extractItem(int id, int amount, boolean obey_stack_size, boolean simulate);
// not extending INBTSerializable to avoid serializing it as forgecaps
CompoundTag serializeNBT();

View File

@ -8,6 +8,7 @@ import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraftforge.registries.RegistryManager;
import ru.dbotthepony.mc.otm.OverdriveThatMatters;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -15,13 +16,18 @@ import java.util.*;
public class MatteryDrive implements IMatteryDrive {
protected final HashMap<Item, List<StoredStack>> items = new HashMap<>();
protected final HashMap<UUID, StoredStack> items_uuid = new HashMap<>();
protected final HashMap<Integer, StoredStack> items_by_id = new HashMap<>();
protected boolean dirty = false;
protected int different_stacks = 0;
protected int stored = 0;
protected int max_different_stacks;
protected int capacity;
protected int next_item_id = 0;
protected int getNextID() {
return next_item_id++;
}
public MatteryDrive(int capacity, int max_different_stacks) {
this.capacity = capacity;
@ -41,13 +47,9 @@ public class MatteryDrive implements IMatteryDrive {
}
var output = new ArrayList<StoredStack>(amount);
int i = 0;
for (var list : items.values()) {
for (var stack : list) {
output.set(i, stack);
i++;
}
output.addAll(list);
}
return output;
@ -120,8 +122,8 @@ public class MatteryDrive implements IMatteryDrive {
@Nullable
@Override
public StoredStack getItem(@Nonnull UUID id) {
return items_uuid.get(id);
public StoredStack getItem(int id) {
return items_by_id.get(id);
}
@Nonnull
@ -156,9 +158,9 @@ public class MatteryDrive implements IMatteryDrive {
different_stacks++;
var copy = item.copy();
copy.setCount(max_insert);
var state = new StoredStack(copy, UUID.randomUUID());
var state = new StoredStack(copy, getNextID());
listing.add(state);
items_uuid.put(state.id(), state);
items_by_id.put(state.id(), state);
markDirty();
}
@ -169,8 +171,8 @@ public class MatteryDrive implements IMatteryDrive {
@Nonnull
@Override
public ItemStack extractItem(@Nonnull UUID id, int amount, boolean obey_stack_size, boolean simulate) {
var get = items_uuid.get(id);
public ItemStack extractItem(int id, int amount, boolean obey_stack_size, boolean simulate) {
var get = items_by_id.get(id);
if (get == null)
return ItemStack.EMPTY;
@ -202,6 +204,7 @@ public class MatteryDrive implements IMatteryDrive {
public CompoundTag serializeNBT() {
final var compound = new CompoundTag();
compound.putInt("next_item_id", next_item_id);
compound.putInt("capacity", capacity);
compound.putInt("max_different_stacks", max_different_stacks);
@ -221,7 +224,7 @@ public class MatteryDrive implements IMatteryDrive {
stack_list.add(stack_nbt);
stack_nbt.putInt("count", stack.stack().getCount());
stack_nbt.putLongArray("uuid", new long[] { stack.id().getMostSignificantBits(), stack.id().getLeastSignificantBits() });
stack_nbt.putInt("id", stack.id());
if (stack.stack().getTag() != null) {
stack_nbt.put("data", stack.stack().getTag());
@ -237,10 +240,11 @@ public class MatteryDrive implements IMatteryDrive {
@Override
public void deserializeNBT(CompoundTag nbt) {
items.clear();
items_uuid.clear();
items_by_id.clear();
stored = 0;
different_stacks = 0;
next_item_id = nbt.getInt("next_item_id");
capacity = nbt.getInt("capacity");
max_different_stacks = nbt.getInt("max_different_stacks");
@ -259,7 +263,7 @@ public class MatteryDrive implements IMatteryDrive {
for (var _stack : stack_list) {
if (_stack instanceof CompoundTag stack) {
var count = stack.getInt("count");
var _uuid = stack.getLongArray("uuid");
var id = stack.getInt("id");
var data = stack.get("data");
var itemstack = new ItemStack(item, count);
@ -270,9 +274,9 @@ public class MatteryDrive implements IMatteryDrive {
stored += count;
different_stacks += 1;
var state = new StoredStack(itemstack, new UUID(_uuid[0], _uuid[1]));
var state = new StoredStack(itemstack, id);
map_list.add(state);
items_uuid.put(state.id(), state);
items_by_id.put(state.id(), state);
}
}
}

View File

@ -0,0 +1,330 @@
package ru.dbotthepony.mc.otm.capability.drive;
import net.minecraft.client.Minecraft;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.fmllegacy.network.NetworkEvent;
import net.minecraftforge.fmllegacy.network.PacketDistributor;
import ru.dbotthepony.mc.otm.OverdriveThatMatters;
import ru.dbotthepony.mc.otm.network.MatteryNetworking;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import java.util.function.Supplier;
public class NetworkedItemView {
record TrackedState(int id, int id_upstream, ItemStack stack) {
TrackedState(int id, ItemStack stack) {
this(id, 0, stack);
}
}
public record ClearPacket(UUID id, boolean remove) {
public void write(FriendlyByteBuf buffer) {
buffer.writeLong(id.getMostSignificantBits());
buffer.writeLong(id.getLeastSignificantBits());
buffer.writeBoolean(remove);
}
public static ClearPacket read(FriendlyByteBuf buffer) {
return new ClearPacket(new UUID(buffer.readLong(), buffer.readLong()), buffer.readBoolean());
}
public void play(Supplier<NetworkEvent.Context> context) {
context.get().setPacketHandled(true);
context.get().enqueueWork(() -> {
var get = TRACKERS_REMOTE.get(id);
if (get == null) {
throw new IllegalStateException("No such item tracker with id " + id);
}
if (remove) {
get.remove();
} else {
get.clear();
}
});
}
}
public record CreatedPacket(UUID id) {
public void write(FriendlyByteBuf buffer) {
buffer.writeLong(id.getMostSignificantBits());
buffer.writeLong(id.getLeastSignificantBits());
}
public static CreatedPacket read(FriendlyByteBuf buffer) {
return new CreatedPacket(new UUID(buffer.readLong(), buffer.readLong()));
}
public void play(Supplier<NetworkEvent.Context> context) {
context.get().setPacketHandled(true);
context.get().enqueueWork(() -> {
new NetworkedItemView(Minecraft.getInstance().player, id, true);
});
}
}
public record StackAddPacket(UUID id, int stack_id, ItemStack stack) {
public void write(FriendlyByteBuf buffer) {
buffer.writeLong(id.getMostSignificantBits());
buffer.writeLong(id.getLeastSignificantBits());
buffer.writeInt(stack_id);
buffer.writeRegistryId(stack.getItem());
buffer.writeInt(stack.getCount());
buffer.writeBoolean(stack.getTag() != null);
if (stack.getTag() != null)
buffer.writeNbt(stack.getShareTag());
}
public static StackAddPacket read(FriendlyByteBuf buffer) {
var id = new UUID(buffer.readLong(), buffer.readLong());
var stack = buffer.readInt();
var item = buffer.readRegistryIdSafe(Item.class);
var count = buffer.readInt();
var state = new ItemStack(item, count);
if (buffer.readBoolean())
state.readShareTag(buffer.readNbt());
return new StackAddPacket(id, stack, state);
}
public void play(Supplier<NetworkEvent.Context> context) {
context.get().setPacketHandled(true);
context.get().enqueueWork(() -> {
var get = TRACKERS_REMOTE.get(id);
if (get == null) {
throw new IllegalStateException("No such item tracker with id " + id);
}
if (get.state.containsKey(stack_id)) {
throw new IllegalStateException("Item tracker " + id + " already has stack with id of " + stack_id);
}
get.state.put(stack_id, new TrackedState(stack_id, stack));
get.clearCache();
});
}
}
public record StackChangePacket(UUID id, int stack_id, int new_count) {
public void write(FriendlyByteBuf buffer) {
buffer.writeLong(id.getMostSignificantBits());
buffer.writeLong(id.getLeastSignificantBits());
buffer.writeInt(stack_id);
buffer.writeInt(new_count);
}
public static StackChangePacket read(FriendlyByteBuf buffer) {
var id = new UUID(buffer.readLong(), buffer.readLong());
var stack_id = buffer.readInt();
var new_count = buffer.readInt();
return new StackChangePacket(id, stack_id, new_count);
}
public void play(Supplier<NetworkEvent.Context> context) {
context.get().setPacketHandled(true);
context.get().enqueueWork(() -> {
var get = TRACKERS_REMOTE.get(id);
if (get == null) {
throw new IllegalStateException("No such item tracker with id " + id);
}
var get_state = get.state.get(stack_id);
if (get_state == null) {
throw new IllegalStateException("Item tracker " + id + " has no stack with id of " + stack_id);
}
get_state.stack.setCount(new_count);
get.clearCache();
});
}
}
public record StackRemovePacket(UUID id, int stack_id) {
public void write(FriendlyByteBuf buffer) {
buffer.writeLong(id.getMostSignificantBits());
buffer.writeLong(id.getLeastSignificantBits());
buffer.writeInt(stack_id);
}
public static StackRemovePacket read(FriendlyByteBuf buffer) {
var id = new UUID(buffer.readLong(), buffer.readLong());
var stack_id = buffer.readInt();
return new StackRemovePacket(id, stack_id);
}
public void play(Supplier<NetworkEvent.Context> context) {
context.get().setPacketHandled(true);
context.get().enqueueWork(() -> {
var get = TRACKERS_REMOTE.get(id);
if (get == null) {
throw new IllegalStateException("No such item tracker with id " + id);
}
var get_state = get.state.remove(stack_id);
if (get_state == null) {
throw new IllegalStateException("Item tracker " + id + " has no stack with id of " + stack_id);
}
get.clearCache();
});
}
}
public final Player ply;
public final UUID id;
public final boolean remote;
protected int next_stack_id = 0;
protected final HashMap<Integer, TrackedState> state = new HashMap<>();
protected final HashMap<Integer, TrackedState> upstream_state = new HashMap<>();
protected final ArrayList<Object> backlog = new ArrayList<>();
private static final HashMap<UUID, NetworkedItemView> TRACKERS_LOCAL = new HashMap<>();
private static final HashMap<UUID, NetworkedItemView> TRACKERS_REMOTE = new HashMap<>();
public static NetworkedItemView getLocal(UUID id) {
return TRACKERS_LOCAL.get(id);
}
public static NetworkedItemView getRemote(UUID id) {
return TRACKERS_REMOTE.get(id);
}
public NetworkedItemView(Player ply) {
this(ply, UUID.randomUUID());
}
public NetworkedItemView(Player ply, UUID id) {
this(ply, id, false);
}
public NetworkedItemView(Player ply, UUID id, boolean remote) {
this.remote = remote;
this.ply = ply;
this.id = id;
if (remote) {
TRACKERS_REMOTE.put(this.id, this);
} else {
TRACKERS_LOCAL.put(this.id, this);
MatteryNetworking.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) ply), new CreatedPacket(this.id));
}
}
private List<ItemStack> view_cache;
public void clearCache() {
view_cache = null;
}
public List<ItemStack> getItems() {
if (view_cache != null)
return view_cache;
var list = new ArrayList<ItemStack>(state.size());
for (var state : this.state.values())
list.add(state.stack);
return view_cache = list;
}
public void addItem(ItemStack stack, int id_upstream) {
if (upstream_state.containsKey(id_upstream))
throw new IllegalStateException("Already tracking ItemStack with upstream id " + id_upstream + "!");
var state = new TrackedState(next_stack_id++, id_upstream, stack);
this.state.put(state.id, state);
this.upstream_state.put(id_upstream, state);
if (!remote) {
backlog.add(new StackAddPacket(id, state.id, stack));
}
clearCache();
}
public void changeItem(int id_upstream, int new_count) {
var get = upstream_state.get(id_upstream);
if (get == null)
throw new IllegalStateException("Unknown ItemStack with upstream id " + id_upstream + "!");
get.stack.setCount(new_count);
if (!remote) {
backlog.add(new StackChangePacket(id, get.id, new_count));
}
clearCache();
}
public void removeItem(int id_upstream) {
var get = upstream_state.get(id_upstream);
if (get == null)
throw new IllegalStateException("Unknown ItemStack with upstream id " + id_upstream + "!");
upstream_state.remove(id_upstream);
state.remove(get.id);
if (!remote) {
backlog.add(new StackRemovePacket(id, get.id));
}
clearCache();
}
public void clear() {
OverdriveThatMatters.LOGGER.info("Clear called");
clearCache();
upstream_state.clear();
state.clear();
if (!remote) {
backlog.clear();
backlog.add(new ClearPacket(id, false));
}
}
public void remove() {
if (!remote) {
TRACKERS_LOCAL.remove(id);
backlog.clear();
backlog.add(new ClearPacket(id, true));
}
}
public void network() {
if (remote)
throw new IllegalStateException("Not a server");
var consumer = PacketDistributor.PLAYER.with(() -> (ServerPlayer) ply);
for (var packet : backlog) {
MatteryNetworking.CHANNEL.send(consumer, packet);
OverdriveThatMatters.LOGGER.info("Send packet {}", packet);
}
backlog.clear();
}
}

View File

@ -4,5 +4,5 @@ import net.minecraft.world.item.ItemStack;
import java.util.UUID;
public record StoredStack(ItemStack stack, UUID id) {
public record StoredStack(ItemStack stack, int id) {
}

View File

@ -0,0 +1,120 @@
package ru.dbotthepony.mc.otm.menu;
import net.minecraft.world.SimpleContainer;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.item.ItemStack;
import ru.dbotthepony.mc.otm.Registry;
import ru.dbotthepony.mc.otm.block.entity.BlockEntityDriveViewer;
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatteryPowered;
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive;
import ru.dbotthepony.mc.otm.capability.drive.NetworkedItemView;
import ru.dbotthepony.mc.otm.menu.data.UUIDDataContainer;
import ru.dbotthepony.mc.otm.menu.slot.MatterySlot;
import javax.annotation.Nullable;
import java.util.UUID;
public class DriveViewerMenu extends PoweredMatteryMenu {
public UUIDDataContainer view_uuid;
public NetworkedItemView view;
public MatterySlot drive_slot;
protected IMatteryDrive last_drive;
public NetworkedItemView getView() {
return view != null ? view : NetworkedItemView.getRemote(view_uuid.getValue());
}
public DriveViewerMenu(int containerID, Inventory inventory) {
this(containerID, inventory, null);
}
public DriveViewerMenu(int containerID, Inventory inventory, @Nullable BlockEntityDriveViewer tile) {
super(Registry.Menus.DRIVE_VIEWER, containerID, inventory, tile);
view_uuid = new UUIDDataContainer();
var container = tile != null ? tile.drive_slot : new SimpleContainer(1);
drive_slot = new MatterySlot(container, 0) {
@Override
public boolean mayPlace(ItemStack stack) {
return stack.getCapability(MatteryCapability.DRIVE).isPresent();
}
};
addSlot(drive_slot);
if (tile != null) {
view = new NetworkedItemView(inventory.player);
view_uuid.setValue(view.id);
}
addDataSlots(view_uuid);
addBatterySlot();
addInventorySlots();
}
@Override
public void broadcastChanges() {
super.broadcastChanges();
if (tile != null) {
var get = ((BlockEntityDriveViewer) tile).drive_slot.getItem(0);
if (get.isEmpty()) {
if (last_drive != null) {
view.clear();
}
last_drive = null;
} else {
var get_cap = get.getCapability(MatteryCapability.DRIVE).resolve();
if (get_cap.isEmpty()) {
if (last_drive != null) {
view.clear();
}
last_drive = null;
} else {
if (last_drive != get_cap.get()) {
view.clear();
for (var stack : get_cap.get().getItems()) {
view.addItem(stack.stack(), stack.id());
}
}
last_drive = get_cap.get();
}
}
view.network();
}
}
@Override
public void removed(Player p_38940_) {
super.removed(p_38940_);
if (!p_38940_.level.isClientSide) {
var view = getView();
if (view != null)
view.remove();
}
}
@Override
protected int getWorkingSlotStart() {
return 0;
}
@Override
protected int getWorkingSlotEnd() {
return 2;
}
}

View File

@ -0,0 +1,81 @@
package ru.dbotthepony.mc.otm.menu.data;
import net.minecraft.world.inventory.ContainerData;
import java.util.UUID;
public class UUIDDataContainer implements ContainerData {
public static final int NETWORK_PAYLOAD_SIZE = 8;
private UUID value;
private final int[] buffer = new int[NETWORK_PAYLOAD_SIZE];
public UUID getValue() {
if (value != null) {
return value;
}
long a = buffer[0];
long b = buffer[1];
long c = buffer[2];
long d = buffer[3];
long upper = a | b << 16 | c << 32 | d << 48;
a = buffer[4];
b = buffer[5];
c = buffer[6];
d = buffer[7];
long lower = a | b << 16 | c << 32 | d << 48;
return value = new UUID(upper, lower);
}
public void setValue(UUID value) {
if (value.equals(this.value)) {
return;
}
this.value = value;
long long_value = value.getMostSignificantBits();
buffer[0] = (int) ((long_value) & 0xFFFF);
buffer[1] = (int) ((long_value >>> 16) & 0xFFFF);
buffer[2] = (int) ((long_value >>> 32) & 0xFFFF);
buffer[3] = (int) ((long_value >>> 48) & 0xFFFF);
long_value = value.getLeastSignificantBits();
buffer[4] = (int) ((long_value) & 0xFFFF);
buffer[5] = (int) ((long_value >>> 16) & 0xFFFF);
buffer[6] = (int) ((long_value >>> 32) & 0xFFFF);
buffer[7] = (int) ((long_value >>> 48) & 0xFFFF);
}
// override
protected void updateValue() {
}
@Override
public int get(int index) {
updateValue();
return buffer[index];
}
@Override
public void set(int index, int _value) {
if (buffer[index] == _value)
return;
value = null;
buffer[index] = _value;
}
@Override
public int getCount() {
return NETWORK_PAYLOAD_SIZE;
}
}

View File

@ -5,6 +5,7 @@ import net.minecraftforge.fmllegacy.network.NetworkDirection;
import net.minecraftforge.fmllegacy.network.NetworkRegistry;
import net.minecraftforge.fmllegacy.network.simple.SimpleChannel;
import ru.dbotthepony.mc.otm.OverdriveThatMatters;
import ru.dbotthepony.mc.otm.capability.drive.NetworkedItemView;
import ru.dbotthepony.mc.otm.network.android.*;
import java.util.Optional;
@ -129,5 +130,50 @@ public class MatteryNetworking {
MatterBottlerSwitchPacket::play,
Optional.of(NetworkDirection.PLAY_TO_SERVER)
);
CHANNEL.registerMessage(
next_network_id++,
NetworkedItemView.ClearPacket.class,
NetworkedItemView.ClearPacket::write,
NetworkedItemView.ClearPacket::read,
NetworkedItemView.ClearPacket::play,
Optional.of(NetworkDirection.PLAY_TO_CLIENT)
);
CHANNEL.registerMessage(
next_network_id++,
NetworkedItemView.CreatedPacket.class,
NetworkedItemView.CreatedPacket::write,
NetworkedItemView.CreatedPacket::read,
NetworkedItemView.CreatedPacket::play,
Optional.of(NetworkDirection.PLAY_TO_CLIENT)
);
CHANNEL.registerMessage(
next_network_id++,
NetworkedItemView.StackAddPacket.class,
NetworkedItemView.StackAddPacket::write,
NetworkedItemView.StackAddPacket::read,
NetworkedItemView.StackAddPacket::play,
Optional.of(NetworkDirection.PLAY_TO_CLIENT)
);
CHANNEL.registerMessage(
next_network_id++,
NetworkedItemView.StackChangePacket.class,
NetworkedItemView.StackChangePacket::write,
NetworkedItemView.StackChangePacket::read,
NetworkedItemView.StackChangePacket::play,
Optional.of(NetworkDirection.PLAY_TO_CLIENT)
);
CHANNEL.registerMessage(
next_network_id++,
NetworkedItemView.StackRemovePacket.class,
NetworkedItemView.StackRemovePacket::write,
NetworkedItemView.StackRemovePacket::read,
NetworkedItemView.StackRemovePacket::play,
Optional.of(NetworkDirection.PLAY_TO_CLIENT)
);
}
}

View File

@ -14,6 +14,7 @@ import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.capability.AndroidCapabilityPlayer;
import ru.dbotthepony.mc.otm.menu.AndroidStationMenu;
import ru.dbotthepony.mc.otm.menu.slot.BatterySlot;
import ru.dbotthepony.mc.otm.menu.slot.MatterySlot;
import ru.dbotthepony.mc.otm.menu.widget.GaugeWidget;
import ru.dbotthepony.mc.otm.screen.panels.*;
@ -104,7 +105,7 @@ public class AndroidStationScreen extends MatteryScreen<AndroidStationMenu> impl
}
@Override
public List<BatterySlot> getBatterySlots() {
public List<MatterySlot> getBatterySlots() {
return List.of(menu.battery_slot);
}

View File

@ -0,0 +1,72 @@
package ru.dbotthepony.mc.otm.screen;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.item.ItemStack;
import ru.dbotthepony.mc.otm.menu.DriveViewerMenu;
import ru.dbotthepony.mc.otm.menu.MatteryMenu;
import ru.dbotthepony.mc.otm.menu.slot.BatterySlot;
import ru.dbotthepony.mc.otm.menu.slot.MatterySlot;
import ru.dbotthepony.mc.otm.menu.widget.GaugeWidget;
import ru.dbotthepony.mc.otm.screen.panels.*;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
public class DriveViewerScreen extends MatteryScreen<DriveViewerMenu> implements MatteryScreen.IMatteryScreenGaugeGetter, MatteryScreen.IMatteryScreenBatteryGetter {
public static final int FRAME_WIDTH = 210;
public static final int FRAME_HEIGHT = 100;
public DriveViewerScreen(DriveViewerMenu menu, Inventory inventory, Component title) {
super(menu, inventory, title);
}
@Override
public List<GaugeWidget> getGauges() {
return List.of(menu.battery_widget);
}
@Override
public List<MatterySlot> getBatterySlots() {
return List.of(menu.battery_slot, menu.drive_slot);
}
@Nullable
@Override
protected FramePanel makeMainFrame() {
var frame = new FramePanel(this, null, 0, 0, FRAME_WIDTH, FRAME_HEIGHT, getTitle());
autoAttachToFrame(frame);
var grid = new GridPanel(this, frame, 0, 0, 0, 0, 3, 3);
grid.setDock(Dock.FILL);
for (int i = 0; i < 9; i++) {
final int index = i;
new AbstractSlotPanel(this, grid, 0, 0) {
@Nonnull
@Override
protected ItemStack getItemStack() {
var view = menu.getView();
if (view != null) {
var list = view.getItems();
if (index >= list.size()) {
return ItemStack.EMPTY;
}
return list.get(index);
}
return ItemStack.EMPTY;
}
};
}
return frame;
}
}

View File

@ -5,6 +5,7 @@ import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.world.entity.player.Inventory;
import ru.dbotthepony.mc.otm.menu.MatterBottlerMenu;
import ru.dbotthepony.mc.otm.menu.slot.BatterySlot;
import ru.dbotthepony.mc.otm.menu.slot.MatterySlot;
import ru.dbotthepony.mc.otm.menu.widget.GaugeWidget;
import ru.dbotthepony.mc.otm.screen.panels.*;
@ -22,7 +23,7 @@ public class MatterBottlerScreen extends MatteryScreen<MatterBottlerMenu> implem
}
@Override
public List<BatterySlot> getBatterySlots() {
public List<MatterySlot> getBatterySlots() {
return List.of(menu.battery_slot);
}

View File

@ -5,6 +5,7 @@ import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Inventory;
import ru.dbotthepony.mc.otm.menu.MatterDecomposerMenu;
import ru.dbotthepony.mc.otm.menu.slot.BatterySlot;
import ru.dbotthepony.mc.otm.menu.slot.MatterySlot;
import ru.dbotthepony.mc.otm.menu.widget.GaugeWidget;
import ru.dbotthepony.mc.otm.screen.panels.*;
@ -22,7 +23,7 @@ public class MatterDecomposerScreen extends MatteryScreen<MatterDecomposerMenu>
}
@Override
public List<BatterySlot> getBatterySlots() {
public List<MatterySlot> getBatterySlots() {
return List.of(menu.battery_slot);
}

View File

@ -4,6 +4,7 @@ import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Inventory;
import ru.dbotthepony.mc.otm.menu.MatterReplicatorMenu;
import ru.dbotthepony.mc.otm.menu.slot.BatterySlot;
import ru.dbotthepony.mc.otm.menu.slot.MatterySlot;
import ru.dbotthepony.mc.otm.menu.widget.GaugeWidget;
import ru.dbotthepony.mc.otm.screen.panels.*;
@ -21,7 +22,7 @@ public class MatterReplicatorScreen extends MatteryScreen<MatterReplicatorMenu>
}
@Override
public List<BatterySlot> getBatterySlots() {
public List<MatterySlot> getBatterySlots() {
return List.of(menu.battery_slot);
}

View File

@ -4,6 +4,7 @@ import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Inventory;
import ru.dbotthepony.mc.otm.menu.MatterScannerMenu;
import ru.dbotthepony.mc.otm.menu.slot.BatterySlot;
import ru.dbotthepony.mc.otm.menu.slot.MatterySlot;
import ru.dbotthepony.mc.otm.menu.widget.GaugeWidget;
import ru.dbotthepony.mc.otm.screen.panels.*;
@ -21,7 +22,7 @@ public class MatterScannerScreen extends MatteryScreen<MatterScannerMenu> implem
}
@Override
public List<BatterySlot> getBatterySlots() {
public List<MatterySlot> getBatterySlots() {
return List.of(menu.battery_slot);
}

View File

@ -57,7 +57,7 @@ public abstract class MatteryScreen<T extends MatteryMenu> extends AbstractConta
}
public interface IMatteryScreenBatteryGetter extends IMatteryScreenLeftPanel {
List<BatterySlot> getBatterySlots();
List<MatterySlot> getBatterySlots();
}
public interface IMatteryScreenGridBased {