This site has been archived and made available for preservation purposes. No edits can be made.

Saving items of players

(Difference between revisions)
Return to current revision
  1.  
    This script saves the players inventory. The inventory data will be saved when the player leaves the server, and will be reassigned once a player with the same name joins (which is weak due to player name conflicts, etc.; however, you can easily change this script to use a combination of name / password).
    [h="2"] Code [/h]
    [highlight=cpp]
    #include "vaultscript.h"
    #include <unordered_map>
    #include <algorithm>

    using namespace vaultmp;
  2. -

    struct _hash_Base { inline size_t operator() (const Base& base) const { return std::hash<std::underlying_type<Base>::type>()(static_cast<std::underlying_type<Base>::type>(base)); }};
  3.  

    template <typename V>
    using mBaseHash = std::unordered_multimap<Base, V, _hash_Base>;

    struct ItemData {
    UCount count;
    Value condition;
    State equipped;
    };

    std::unordered_map<String, mBaseHash<ItemData>> playerItems;

    Void VAULTSCRIPT OnPlayerDisconnect(ID player, Reason reason) noexcept
    {
    // Get player name (the key for the item store)
    String name = GetName(player);

    // Clear player item store
    playerItems.erase(name);

    // Get all items
    IDVector items = Item::GetList();

    for (const auto& id : items)
    {
    Item item(id);

    // baseID of the item
    Base base = item.GetBase();

    static const Base PipBoy = static_cast<Base>(0x00015038);
    static const Base PipBoyGloves = static_cast<Base>(0x00025B83);

    // If the item belongs to the player, save it. Don't save PipBoy stuff because that's equipped by default
    if (base != PipBoy && base != PipBoyGloves && item.GetItemContainer() == player)
    {
    UCount count = item.GetItemCount();
    Value condition = item.GetItemCondition();
    State equipped = item.GetItemEquipped();

    // Find an existing item for stacking
    auto it = find_if(playerItems[name].begin(), playerItems[name].end(), [&](const std::pair<const Base, ItemData>& itemData) { return itemData.first == base && itemData.second.condition == condition && itemData.second.equipped == False;});

    // Either use the existing item data or create a new entry
    ItemData& data = it != playerItems[name].end() ? it->second : playerItems[name].emplace(base, ItemData())->second;

    // Store the data
    data.count += count;
    data.condition = condition;
    data.equipped = equipped;
    }
    }
    }

    Base VAULTSCRIPT OnPlayerRequestGame(ID player) noexcept
    {
    // Player object
    Player pplayer(player);

    // Get player name (the key for the item store)
    String name = pplayer.GetName();

    for (const auto& item : playerItems[name])
    {
    // Add the item
    pplayer.AddItem(item.first, item.second.count, item.second.condition);

    // Equip the item if it was equipped
    if (item.second.equipped)
    pplayer.EquipItem(item.first, True, False);
    }

    return static_cast<Base>(0x00000000);
    }
    [/highlight]
    [category]Script examples[/category]