RanvierMUD / core

Core engine code for Ranvier
https://ranviermud.com
MIT License
45 stars 40 forks source link

Item Properties(name, keywords, roomdesc) not hydrating properly. #34

Closed ratacat closed 5 years ago

ratacat commented 5 years ago

To replicate: Load an item from item definition in datasource. Modify the name, keywords, or roomdesc. Save the player. Quit the game. Login again. It will reset to the original name, keywords, and roomdesc.

This seems to be an issue with hydrating, not serializing. Look at hydrate method in Inventory.js, aprox lines 86 - 110.

hydrate(state, belongsTo) {
    // Item is imported here to prevent circular dependency with Item having an Inventory
    const Item = require('./Item');

    for (const [uuid, def] of this) {
      if (def instanceof Item) {
        def.belongsTo = belongsTo;
        continue;
      }

      if (!def.entityReference) {
        continue;
      }

      const area = state.AreaManager.getAreaByReference(def.entityReference);
      let newItem = state.ItemFactory.create(area, def.entityReference);
\\=======================================================
\\ The line above this is where the item is created exactly from entityReference.
\\ Currently the 'serialized' state of the item is saved in def. 
\\=======================================================
      newItem.uuid = uuid;
      newItem.belongsTo = belongsTo;
      newItem.initializeInventory(def.inventory);
      newItem.hydrate(state, def);
\\=======================================================
\\ Here the serialized def is passed into hydrate on the newly created item.
\\=======================================================
      this.set(uuid, newItem);
      state.ItemManager.add(newItem);
    }
  }
}
  hydrate(state, serialized = {}) {
\\=======================================================
\\ serialized data is saved in serialized
\\=======================================================
    if (this.__hydrated) {
      Logger.warn('Attempted to hydrate already hydrated item.');
      return false;
    }

    // perform deep copy if behaviors is set to prevent sharing of the object between
    // item instances
    if (serialized.behaviors) {
      const behaviors = JSON.parse(JSON.stringify(serialized.behaviors));
      this.behaviors = new Map(Object.entries(behaviors));
    }
\\=======================================================
\\ serialized gets used here to set the behaviors
\\=======================================================
    this.setupBehaviors(state.ItemBehaviorManager);

    this.metadata = JSON.parse(JSON.stringify(serialized.metadata || this.metadata));
\\=======================================================
\\ and here for the metadata
\\=======================================================
    this.closed = 'closed' in serialized ? serialized.closed : this.closed;
    this.locked = 'locked' in serialized ? serialized.locked : this.locked;

    if (typeof this.area === 'string') {
      this.area = state.AreaManager.getArea(this.area);
    }

    // if the item was saved with a custom inventory hydrate it
    if (this.inventory) {
      this.inventory.hydrate(state, this);
    } else {
    // otherwise load its default inv
      this.defaultItems.forEach(defaultItemId => {
        Logger.verbose(`\tDIST: Adding item [${defaultItemId}] to item [${this.name}]`);
        const newItem = state.ItemFactory.create(this.area, defaultItemId);
        newItem.hydrate(state);
        state.ItemManager.add(newItem);
        this.addItem(newItem);
      });
    }

    this.__hydrated = true;
  }

Nowhere does it set the other properties though. I believe it should be name, keywords, roomdesc, desc

shawncplus commented 5 years ago

Your code is out of date, they were added in 361ddd6bbe8c42fbd0a2189ac0dbf017f1254fe1

ratacat commented 5 years ago

oh my god! you're so very right. Thanks Shawn.

The other part of the changes pulled in, not sure why those didn't make it...oh well