Add persistent storage for party inventories
This commit is contained in:
+1
-1
@@ -36,7 +36,7 @@ mod_name=Stalinium
|
||||
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
|
||||
mod_license=MIT
|
||||
# The mod version. See https://semver.org/
|
||||
mod_version=0.2.1
|
||||
mod_version=0.2.2
|
||||
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
|
||||
# This should match the base package used for the mod sources.
|
||||
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
package net.krituximon.stalinium.block.entity;
|
||||
|
||||
import net.krituximon.stalinium.event.ComradeHandler;
|
||||
import net.krituximon.stalinium.util.StaliniumPartyCacheData;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
@@ -29,22 +30,39 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class StaliniumCacheBlockEntity extends BlockEntity {
|
||||
private static final int SIZE = 27;
|
||||
private static final Map<UUID, SimpleContainer> PARTY_INVENTORIES = new ConcurrentHashMap<>();
|
||||
|
||||
public StaliniumCacheBlockEntity(BlockPos pos, BlockState state) {
|
||||
super(ModBlockEntities.STALINIUM_CACHE_BE.get(), pos, state);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Obtain – and create if necessary – the inventory that belongs to the player’s party.
|
||||
*/
|
||||
public static SimpleContainer getPartyInventory(@Nullable Player who) {
|
||||
UUID key;
|
||||
if (who == null) {
|
||||
UUID defaultKey = UUID.randomUUID();
|
||||
return PARTY_INVENTORIES.computeIfAbsent(defaultKey, __ -> new SimpleContainer(SIZE));
|
||||
key = new UUID(0L, 0L); // world-wide default dump
|
||||
} else {
|
||||
Optional<ComradeHandler.Party> opt = ComradeHandler.findPartyOf(who.getUUID());
|
||||
key = opt.map(p -> p.leader).orElse(who.getUUID());
|
||||
}
|
||||
Optional<ComradeHandler.Party> opt = ComradeHandler.findPartyOf(who.getUUID());
|
||||
UUID key = opt.map(p -> p.leader).orElse(who.getUUID());
|
||||
return PARTY_INVENTORIES.computeIfAbsent(key, __ -> new SimpleContainer(SIZE));
|
||||
|
||||
// We keep the containers in the world-persistent SavedData
|
||||
Level lvl = who != null ? who.level() : null;
|
||||
if (lvl == null || lvl.isClientSide) // should never happen on the server
|
||||
return new SimpleContainer(SIZE);
|
||||
|
||||
StaliniumPartyCacheData data = StaliniumPartyCacheData.get(lvl);
|
||||
return data.getOrCreate(key);
|
||||
}
|
||||
|
||||
/* ---------- helper to mark the SavedData dirty whenever the container changes ---------- */
|
||||
public static void markDirty(Level level, UUID key) {
|
||||
if (level.isClientSide) return;
|
||||
StaliniumPartyCacheData.get(level).setDirty();
|
||||
}
|
||||
|
||||
// drop-logic unchanged …
|
||||
public void drops() {
|
||||
SimpleContainer inv = getPartyInventory(null);
|
||||
SimpleContainer tmp = new SimpleContainer(SIZE);
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
package net.krituximon.stalinium.util;
|
||||
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.nbt.*;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.ContainerHelper;
|
||||
import net.minecraft.world.SimpleContainer;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.saveddata.SavedData;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* World-persistent store for every party’s cache inventory.
|
||||
* Saved/loaded automatically by the game.
|
||||
*/
|
||||
public class StaliniumPartyCacheData extends SavedData {
|
||||
private static final String DATA_NAME = "stalinium_party_caches";
|
||||
private static final int SIZE = 27;
|
||||
|
||||
private final Map<UUID, SimpleContainer> inventories = new HashMap<>();
|
||||
|
||||
/* ------------------------------------------------- */
|
||||
/* helper that produces an inventory wired to setDirty */
|
||||
/* ------------------------------------------------- */
|
||||
|
||||
private SimpleContainer newContainer() {
|
||||
/* Every time the container changes, flag the data object. */
|
||||
return new SimpleContainer(SIZE) {
|
||||
@Override
|
||||
public void setChanged() {
|
||||
super.setChanged();
|
||||
StaliniumPartyCacheData.this.setDirty();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/* ---------------- public API ---------------- */
|
||||
|
||||
/** Get (or lazily create) the inventory for the given party / player. */
|
||||
public SimpleContainer getOrCreate(UUID id) {
|
||||
return inventories.computeIfAbsent(id, __ -> newContainer());
|
||||
}
|
||||
|
||||
/* ---------------- persistence ---------------- */
|
||||
|
||||
@Override
|
||||
public CompoundTag save(CompoundTag tag, HolderLookup.Provider provider) {
|
||||
ListTag list = new ListTag();
|
||||
|
||||
inventories.forEach((uuid, container) -> {
|
||||
CompoundTag entry = new CompoundTag();
|
||||
entry.putUUID("Id", uuid);
|
||||
|
||||
NonNullList<ItemStack> tmp =
|
||||
NonNullList.withSize(container.getContainerSize(), ItemStack.EMPTY);
|
||||
for (int i = 0; i < container.getContainerSize(); ++i) {
|
||||
tmp.set(i, container.getItem(i));
|
||||
}
|
||||
ContainerHelper.saveAllItems(entry, tmp, provider);
|
||||
list.add(entry);
|
||||
});
|
||||
|
||||
tag.put("Inventories", list);
|
||||
return tag;
|
||||
}
|
||||
|
||||
/** Deserializer – now also uses {@link #newContainer()} so the hook survives loading. */
|
||||
public static StaliniumPartyCacheData load(CompoundTag tag, HolderLookup.Provider provider) {
|
||||
StaliniumPartyCacheData data = new StaliniumPartyCacheData();
|
||||
ListTag list = tag.getList("Inventories", Tag.TAG_COMPOUND);
|
||||
|
||||
list.forEach(t -> {
|
||||
CompoundTag entry = (CompoundTag) t;
|
||||
UUID id = entry.getUUID("Id");
|
||||
|
||||
SimpleContainer cont = data.newContainer();
|
||||
NonNullList<ItemStack> tmp = NonNullList.withSize(SIZE, ItemStack.EMPTY);
|
||||
ContainerHelper.loadAllItems(entry, tmp, provider);
|
||||
for (int i = 0; i < SIZE; ++i) cont.setItem(i, tmp.get(i));
|
||||
|
||||
data.inventories.put(id, cont);
|
||||
});
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/* ---------------- factory / access ---------------- */
|
||||
|
||||
private static final SavedData.Factory<StaliniumPartyCacheData> FACTORY =
|
||||
new SavedData.Factory<>(StaliniumPartyCacheData::new, StaliniumPartyCacheData::load);
|
||||
|
||||
public static StaliniumPartyCacheData get(Level lvl) {
|
||||
if (lvl.isClientSide) throw new IllegalStateException("Called on client");
|
||||
return ((ServerLevel) lvl).getDataStorage().computeIfAbsent(FACTORY, DATA_NAME);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user