• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

C++ using getStorageValue in source code

Togu

Advanced OT User
Joined
Jun 22, 2018
Messages
308
Solutions
1
Reaction score
178
Location
Brazil
I've made an simple auto loot gold and platinum coins in sources but it don't have the option to be enabled or disabled by players. Then I've made a talkaction to set a true/false value in the player_storage in database. I was trying to use this storage value to enable or disable the auto loot but it is not working and I don't know why. There aren't compiling errors or console errors during execution.

In monsters.cpp I have this function:
C++:
void MonsterType::createLoot(Container* corpse)
{
   if (g_config.getNumber(ConfigManager::RATE_LOOT) == 0) {
       corpse->startDecaying();
       return;
   }

   Player* owner = g_game.getPlayerByID(corpse->getCorpseOwner());

   std::ostringstream ss;
   ss << "Loot of " << nameDescription << ": ";

   int32_t autoLootGoldValue = 1;

   if (!owner || owner->getStaminaMinutes() > 840) {

       int goldCoins = 0;
       int platinumCoins = 0;

       for (auto it = info.lootItems.rbegin(), end = info.lootItems.rend(); it != end; ++it) {
           auto itemList = createLootItem(*it);
           if (itemList.empty()) {
               continue;
           }

           if (owner->getStorageValue(60320, autoLootGoldValue)) {

               for (Item* item : itemList) {

                   //auto loot gold coin and platinum coin
                   if (item->getID() == 2148 || item->getID() == 2152) {
                       if (item->getID() == 2148) {
                           goldCoins = item->getItemCount();
                       }
                       if (item->getID() == 2152) {
                           platinumCoins = item->getItemCount();
                       }
                       g_game.internalPlayerAddItem(owner, item, true, CONST_SLOT_WHEREEVER);
                   }

                   //check containers
                   if (Container* container = item->getContainer()) {
                       if (!createLootContainer(container, *it)) {
                           delete container;
                           continue;
                       }
                   }

                   //changed for auto loot
                   if (item->getID() != 2148 && item->getID() != 2152) {
                       if (g_game.internalAddItem(corpse, item) != RETURNVALUE_NOERROR) {
                           corpse->internalAddThing(item);
                       }
                   }
               }
           }

           else {

               for (Item* item : itemList) {

                   //check containers
                   if (Container* container = item->getContainer()) {
                       if (!createLootContainer(container, *it)) {
                           delete container;
                           continue;
                       }
                   }

                   //changed for auto loot
                   if (g_game.internalAddItem(corpse, item) != RETURNVALUE_NOERROR) {
                       corpse->internalAddThing(item);
                   }
               }
           }
       }

       if (owner) {

           if (owner->getStorageValue(60320, autoLootGoldValue)) {

               if (goldCoins > 0) {
                   if (goldCoins == 1) {
                       ss << goldCoins << " gold coin, ";
                   }
                   else if (goldCoins > 1) {
                       ss << goldCoins << " gold coins, ";
                   }
               }

               if (platinumCoins > 0) {
                   if (platinumCoins == 1) {
                       ss << platinumCoins << " platinum coin, ";
                   }
                   else if (platinumCoins > 1) {
                       ss << platinumCoins << " platinum coins, ";
                   }
               }
           }

           ss << corpse->getContentDescription();

           if (owner->getParty()) {
               owner->getParty()->broadcastPartyLoot(ss.str());
           } else {
               owner->sendTextMessage(MESSAGE_LOOT, ss.str());
           }
       }
   } else {
       ss << "nothing (due to low stamina)";

       if (owner->getParty()) {
           owner->getParty()->broadcastPartyLoot(ss.str());
       } else {
           owner->sendTextMessage(MESSAGE_LOOT, ss.str());
       }
   }

   corpse->startDecaying();
}

Note: I also tried to use a db.query to get the value but I couldn't.
Note2: The autoloot system on this forum isn't working for me, so don't post the topic saying to use this autoloot.

Any tips?

Edit:
Searched a solution on forum and I think I found it. Gonna test it later.
Solved - [C++] getStorageValue

Edit:
Solved.
 
Last edited:
Solution
Hey, I know you've already solved your problem, I just wanted to tell you that it would probably be a better idea if, instead of a storage, you created a boolean attribute on the player and set that to true or false.

I'm telling you tbis because storages are better used (or even designed) when we set/get them in lua, for game features mainly like quests.

For example, what if you determine that you are going to use the storage key 60320 for this purpose, that is hard coded in your engine, what if in a couple months or if you get a partner to work on this project with you, and he uses that 60320 storage as a quest storage? That would not be nice. (Obviously you would set thoose keys in a config file so that you don't have to...
Hey, I know you've already solved your problem, I just wanted to tell you that it would probably be a better idea if, instead of a storage, you created a boolean attribute on the player and set that to true or false.

I'm telling you tbis because storages are better used (or even designed) when we set/get them in lua, for game features mainly like quests.

For example, what if you determine that you are going to use the storage key 60320 for this purpose, that is hard coded in your engine, what if in a couple months or if you get a partner to work on this project with you, and he uses that 60320 storage as a quest storage? That would not be nice. (Obviously you would set thoose keys in a config file so that you don't have to hard code thoose numbers on your quest scripts)

I made something similar to this, but instead of an auto looter, it was a boolean attribute that when was set to true, the player would see his mana and health as percentage, when false it would be his normal mana/health.
You can check it here: Need % hp/mn command

Edit:
I think this is also faster performance wise, since the getstoragevalue has to search the storageMap. Specially in this case where you are going to search that storageMap everytime someone kills a monster.
 
Last edited:
Solution
Hey, I know you've already solved your problem, I just wanted to tell you that it would probably be a better idea if, instead of a storage, you created a boolean attribute on the player and set that to true or false.

I'm telling you tbis because storages are better used (or even designed) when we set/get them in lua, for game features mainly like quests.

For example, what if you determine that you are going to use the storage key 60320 for this purpose, that is hard coded in your engine, what if in a couple months or if you get a partner to work on this project with you, and he uses that 60320 storage as a quest storage? That would not be nice. (Obviously you would set thoose keys in a config file so that you don't have to hard code thoose numbers on your quest scripts)

I made something similar to this, but instead of an auto looter, it was a boolean attribute that when was set to true, the player would see his mana and health as percentage, when false it would be his normal mana/health.
You can check it here: Need % hp/mn command

Edit:
I think this is also faster performance wise, since the getstoragevalue has to search the storageMap. Specially in this case where you are going to search that storageMap everytime someone kills a monster.
You are the best! Tried it just today just because I needed to learn how to create a new function in C++ and pass it to Lua.
Worked in the first try and now I can do a setTitleDescription() function that will change player's description to put a title (like Crusader Knight, Tank Knight, etc).
Thanks!

Edit:
Code:
!title 1
20:52 You see yourself. You were nominated as a magician.
!title 2
20:52 You see yourself. You were nominated as a supporter.
20:52 You see yourself. You were nominated as a ranger.
20:52 You see yourself. You were nominated as a knight.
 
Last edited:
Back
Top