Recheck storage slots after spawn preload and streaming handoff

This commit is contained in:
2026-09-20 17:46:45 +02:00
parent 1201f9666f
commit e8d472c6ff
7 changed files with 200 additions and 32 deletions
+22 -3
View File
@@ -4,6 +4,11 @@ inventory=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_SpawnSceneInventory.c'
scene=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_SpawnClientScene.c'
def cpp(s):
s=s.replace('protected ','').replace('static ','')
s=s.replace('ERR_SpawnSceneInventory.InStorage(', 'InStorage(')
s=s.replace('InventoryItemComponent item = InventoryItemComponent.Cast(entity.FindComponent(InventoryItemComponent));', 'Item* item = entity->item;')
s=s.replace('InventoryStorageSlot slot = item.GetParentSlot();', 'Slot* slot = item->slot;')
s=s.replace('BaseInventoryStorageComponent storage = slot.GetStorage();', 'Storage* storage = slot->storage;')
s=s.replace('storage.FindItemSlot(entity)', 'storage->FindItemSlot(entity)').replace('storage.Get(slot.GetID())', 'storage->Get(slot->id)').replace('storage.GetAll(visible)', 'storage->GetAll(visible)')
s=s.replace('out array<IEntity> ', 'Items& ').replace('array<IEntity> ', 'Items ')
s=s.replace('foreach (IEntity root : roots)', 'for (IEntity root : roots)').replace('foreach (IEntity item : contents)', 'for (IEntity item : contents)')
s=s.replace('InventoryStorageManagerComponent inventory = InventoryStorageManagerComponent.Cast(root.FindComponent(InventoryStorageManagerComponent));', 'Inventory* inventory = root->inventory;')
@@ -15,7 +20,7 @@ def cpp(s):
s=s.replace('Replication.IsServer()', 'Replication::server').replace('GetGame().GetWorld().GetWorldTime()', 'now')
s=s.replace('ERR_SpawnSceneInventory.Gather(', 'Gather(').replace('ERR_SpawnSceneInventory.Same(', 'Same(')
return s
methods='\n'.join(cpp(body(inventory,key)) for key in ('static bool Gather(', 'static bool Same('))
methods='\n'.join(cpp(body(inventory,key)) for key in ('static bool InStorage(', 'static bool Gather(', 'static bool Same('))
methods+='\n'+cpp(body(scene,'protected bool ERR_ClientStockReady('))
methods+='\n'+cpp(body(scene,'protected void ERR_RefreshSceneInventory('))
methods+='\n'+cpp(body(scene,'bool ERR_TakeScenePreload('))
@@ -28,7 +33,10 @@ template<class T>struct List:std::vector<T>{using std::vector<T>::vector;using s
int Count()const{return this->size();}void Insert(T x){this->push_back(x);}bool Contains(T x)const{return std::find(this->begin(),this->end(),x)!=this->end();}
int Find(T x)const{auto i=std::find(this->begin(),this->end(),x);return i==this->end()?-1:i-this->begin();}};
struct Entity;using IEntity=Entity*;using Items=List<IEntity>;using RplId=int;
struct Inventory{Items items;};struct Entity{Inventory* inventory=nullptr;};
struct Storage;struct Slot{Storage* storage=nullptr;int id=0;};struct Item{Slot* slot=nullptr;};
struct Inventory{Items items;};struct Entity{Inventory* inventory=nullptr;Item* item=nullptr;};
struct Storage{Items visible;IEntity stored=nullptr;Slot* slot=nullptr;
Slot* FindItemSlot(IEntity e){return stored==e?slot:nullptr;}IEntity Get(int id){return slot&&slot->id==id?stored:nullptr;}void GetAll(Items& out){out=visible;}};
void InventoryItems(Inventory* inv,Items& items){items={};for(auto x:inv->items)if(x&&!items.Contains(x))items.Insert(x);}
struct RplComponent{IEntity entity=nullptr;IEntity GetEntity(){return entity;}};
namespace Replication{bool server=true;std::map<int,RplComponent*> nodes;RplComponent* FindItem(int id){auto it=nodes.find(id);return it==nodes.end()?nullptr:it->second;}}
@@ -61,7 +69,18 @@ int main(){
inv.items={};for(int i=0;i<20;i++)assert(!p.ERR_ClientStockReady());
inv.items={&gun,&mag};assert(!p.ERR_ClientStockReady());
inv.items={&gun,&mag,&other};assert(!p.ERR_ClientStockReady());
inv.items={&gun,&mag,&map};assert(p.ERR_ClientStockReady());
inv.items={&gun,&mag,&map};assert(!p.ERR_ClientStockReady());
Storage gs,ms,ps;Slot gslot{&gs,0},mslot{&ms,1},pslot{&ps,2};Item gi{&gslot},mi{&mslot},pi{&pslot};
gun.item=&gi;mag.item=&mi;map.item=&pi;
gs.stored=&gun;gs.slot=&gslot;gs.visible={&gun};ms.stored=&mag;ms.slot=&mslot;ms.visible={&mag};ps.stored=&map;ps.slot=&pslot;ps.visible={&map};
assert(p.ERR_ClientStockReady());
// Manager still contains the gun, but the actual crate UI cannot read it.
gs.visible={};assert(!p.ERR_ClientStockReady());gs.visible={&gun};
gs.stored=&other;assert(!p.ERR_ClientStockReady());gs.stored=&gun;
gi.slot=nullptr;assert(!p.ERR_ClientStockReady());gi.slot=&gslot;
gslot.storage=nullptr;assert(!p.ERR_ClientStockReady());gslot.storage=&gs;
gs.slot=&mslot;assert(!p.ERR_ClientStockReady());gs.slot=&gslot;
assert(p.ERR_ClientStockReady());
cr.entity=nullptr;assert(!p.ERR_ClientStockReady());cr.entity=&crate;
crate.inventory=nullptr;assert(!p.ERR_ClientStockReady());crate.inventory=&inv;
mr.entity=nullptr;assert(!p.ERR_ClientStockReady());mr.entity=&mag;