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.
|
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
|
||||||
mod_license=MIT
|
mod_license=MIT
|
||||||
# The mod version. See https://semver.org/
|
# 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.
|
# 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.
|
# This should match the base package used for the mod sources.
|
||||||
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
|
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
package net.krituximon.stalinium.block.entity;
|
package net.krituximon.stalinium.block.entity;
|
||||||
|
|
||||||
import net.krituximon.stalinium.event.ComradeHandler;
|
import net.krituximon.stalinium.event.ComradeHandler;
|
||||||
|
import net.krituximon.stalinium.util.StaliniumPartyCacheData;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.HolderLookup;
|
import net.minecraft.core.HolderLookup;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
@@ -29,22 +30,39 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
|
|
||||||
public class StaliniumCacheBlockEntity extends BlockEntity {
|
public class StaliniumCacheBlockEntity extends BlockEntity {
|
||||||
private static final int SIZE = 27;
|
private static final int SIZE = 27;
|
||||||
private static final Map<UUID, SimpleContainer> PARTY_INVENTORIES = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
public StaliniumCacheBlockEntity(BlockPos pos, BlockState state) {
|
public StaliniumCacheBlockEntity(BlockPos pos, BlockState state) {
|
||||||
super(ModBlockEntities.STALINIUM_CACHE_BE.get(), pos, 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) {
|
public static SimpleContainer getPartyInventory(@Nullable Player who) {
|
||||||
|
UUID key;
|
||||||
if (who == null) {
|
if (who == null) {
|
||||||
UUID defaultKey = UUID.randomUUID();
|
key = new UUID(0L, 0L); // world-wide default dump
|
||||||
return PARTY_INVENTORIES.computeIfAbsent(defaultKey, __ -> new SimpleContainer(SIZE));
|
} 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());
|
// We keep the containers in the world-persistent SavedData
|
||||||
return PARTY_INVENTORIES.computeIfAbsent(key, __ -> new SimpleContainer(SIZE));
|
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() {
|
public void drops() {
|
||||||
SimpleContainer inv = getPartyInventory(null);
|
SimpleContainer inv = getPartyInventory(null);
|
||||||
SimpleContainer tmp = new SimpleContainer(SIZE);
|
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