C++ Money currency little bug

Discussion in 'Support' started by Shadow_, Jul 11, 2018.

  1. Shadow_

    Shadow_ CarcooIzx.zapto.org

    Joined:
    Jun 2, 2018
    Messages:
    202
    Likes Received:
    24
    Best Answers:
    3
    Hello guys,
    i have a little money bug ii have added new 2 currencies in my OT in sources in my game.cpp i got a little bug when i say !aol or !bless or buying using NPC and i have gold nuggets(only)i take random number of scarab coins , crystal coins , platinum coins , gold coins ( when i have scarab coins or crystal coins i take 99 scrab coins and 99 crystal coin as it should be but using gold nuggets gives random number of money i think its from unit_xx but i don't know how to fix it.
    here is my game.cpp add money code :
    Code (C++):
    1. void Game::addMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0*/)
    2. {
    3.     if (money == 0) {
    4.         return;
    5.     }
    6.     uint32_t goldNuggets = money / 100000000;
    7.     money -= goldNuggets * 100000000;
    8.     while (goldNuggets > 0) {
    9.         const uint16_t count = std::min<uint32_t>(100, goldNuggets);
    10.         Item* remaindItem = Item::CreateItem(ITEM_GOLD_NUGGET, count);
    11.         ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags);
    12.         if (ret != RETURNVALUE_NOERROR) {
    13.             internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
    14.         }
    15.         goldNuggets -= count;
    16.     }
    17.    
    18.      uint32_t scarabCoins = money / 1000000;
    19.     if (scarabCoins != 0) {
    20.         Item* remaindItem = Item::CreateItem(ITEM_SCARAB_COIN, scarabCoins);
    21.         ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags);
    22.         if (ret != RETURNVALUE_NOERROR) {
    23.             internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
    24.         }
    25.         money -= scarabCoins * 1000000;
    26.     }
    27.    
    28.     uint32_t crystalCoins = money / 10000;
    29.     if (crystalCoins != 0) {
    30.         Item* remaindItem = Item::CreateItem(ITEM_CRYSTAL_COIN, crystalCoins);
    31.         ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags);
    32.         if (ret != RETURNVALUE_NOERROR) {
    33.             internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
    34.         }
    35.         money -= crystalCoins * 10000;
    36.     }
    37.     uint16_t platinumCoins = money / 100;
    38.     if (platinumCoins != 0) {
    39.         Item* remaindItem = Item::CreateItem(ITEM_PLATINUM_COIN, platinumCoins);
    40.         ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags);
    41.         if (ret != RETURNVALUE_NOERROR) {
    42.             internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
    43.         }
    44.         money -= platinumCoins * 100;
    45.     }
    46.     if (money != 0) {
    47.         Item* remaindItem = Item::CreateItem(ITEM_GOLD_COIN, money);
    48.         ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags);
    49.         if (ret != RETURNVALUE_NOERROR) {
    50.             internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
    51.         }
    52.     }
    53. }
    54.  
     
  2. Best Answer:
    Post #7 by Vulcan_, Jul 13, 2018
  3. Shadow_

    Shadow_ CarcooIzx.zapto.org

    Joined:
    Jun 2, 2018
    Messages:
    202
    Likes Received:
    24
    Best Answers:
    3
    bump -- whats up guys ? xD
     
  4. president vankk

    president vankk Web Developer & AuraOT Owner

    Joined:
    Jul 10, 2009
    Messages:
    5,716
    Likes Received:
    299
    Best Answers:
    7
    Hello, good morning. You should be fine doing exactly what Vulcan_ said on his post on this thread.
     
    Shadow_ likes this.
  5. Shadow_

    Shadow_ CarcooIzx.zapto.org

    Joined:
    Jun 2, 2018
    Messages:
    202
    Likes Received:
    24
    Best Answers:
    3
    Yeah , i tried to exchange it from scratch x6 times lol @Vulcan_ maybe you know how to solve it?
     
  6. Vulcan_

    Vulcan_ Support Team Support Team

    Joined:
    Feb 14, 2015
    Messages:
    4,038
    Likes Received:
    1,849
    Best Answers:
    316
    works fine for me
    [​IMG]
    i used an aol command, takes 1 cc
    started off with 1 gold nugget -> remove 1cc = 99 scarab coins and 99 cc
    if i start off with 99 scarab coins and no cc -> remove 1 cc = 98 scarab coins and 99 cc
    1 scarab coin -> remove 1 cc = 99 cc

    this is the code i used:

    game.cpp
    Code (C++):
    1.  
    2. void Game::addMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0*/)
    3. {
    4.     if (money == 0) {
    5.         return;
    6.     }
    7.     uint32_t goldNuggets = money / 100000000;
    8.     money -= goldNuggets * 100000000;
    9.     while (goldNuggets > 0) {
    10.         const uint16_t count = std::min<uint32_t>(100, goldNuggets);
    11.         Item* remaindItem = Item::CreateItem(ITEM_GOLD_NUGGET, count);
    12.         ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags);
    13.         if (ret != RETURNVALUE_NOERROR) {
    14.             internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
    15.         }
    16.         goldNuggets -= count;
    17.     }
    18.  
    19.     uint32_t scarabCoins = money / 1000000;
    20.     if (scarabCoins != 0) {
    21.         Item* remaindItem = Item::CreateItem(ITEM_SCARAB_COIN, scarabCoins);
    22.         ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags);
    23.         if (ret != RETURNVALUE_NOERROR) {
    24.             internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
    25.         }
    26.         money -= scarabCoins * 1000000;
    27.     }
    28.  
    29.     uint32_t crystalCoins = money / 10000;
    30.     if (crystalCoins != 0) {
    31.         Item* remaindItem = Item::CreateItem(ITEM_CRYSTAL_COIN, crystalCoins);
    32.         ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags);
    33.         if (ret != RETURNVALUE_NOERROR) {
    34.             internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
    35.         }
    36.         money -= crystalCoins * 10000;
    37.     }
    38.     uint16_t platinumCoins = money / 100;
    39.     if (platinumCoins != 0) {
    40.         Item* remaindItem = Item::CreateItem(ITEM_PLATINUM_COIN, platinumCoins);
    41.         ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags);
    42.         if (ret != RETURNVALUE_NOERROR) {
    43.             internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
    44.         }
    45.         money -= platinumCoins * 100;
    46.     }
    47.     if (money != 0) {
    48.         Item* remaindItem = Item::CreateItem(ITEM_GOLD_COIN, money);
    49.         ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags);
    50.         if (ret != RETURNVALUE_NOERROR) {
    51.             internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
    52.         }
    53.     }
    54. }
    player.cpp
    Code (C++):
    1. if (itemId != ITEM_GOLD_COIN && itemId != ITEM_PLATINUM_COIN && itemId != ITEM_CRYSTAL_COIN && itemId != ITEM_SCARAB_COIN && itemId != ITEM_GOLD_NUGGET) {
    item.cpp
    Code (C++):
    1.  
    2. uint32_t Item::getWorth() const
    3. {
    4.     switch (id) {
    5.     case ITEM_GOLD_COIN:
    6.         return count;
    7.  
    8.     case ITEM_PLATINUM_COIN:
    9.         return count * 100;
    10.  
    11.     case ITEM_CRYSTAL_COIN:
    12.         return count * 10000;
    13.  
    14.     case ITEM_SCARAB_COIN:
    15.         return count * 1000000;
    16.  
    17.     case ITEM_GOLD_NUGGET:
    18.         return count * 100000000;
    19.  
    20.     default:
    21.         return 0;
    22.     }
    23. }
    const.h
    Code (C++):
    1.  
    2.     ITEM_SCARAB_COIN = 2159,
    3.     ITEM_GOLD_NUGGET = 2157,
    luascript.cpp
    Code (C++):
    1.  
    2.     registerEnum(ITEM_SCARAB_COIN)
    3.     registerEnum(ITEM_GOLD_NUGGET)
     
    Shadow_ and bayview like this.
  7. Shadow_

    Shadow_ CarcooIzx.zapto.org

    Joined:
    Jun 2, 2018
    Messages:
    202
    Likes Received:
    24
    Best Answers:
    3
    keep knowing that i have changed gold_nugget id to 9971 ( gold ingot id ) :
    [​IMG]
    @Vulcan_ after using your script the same bug

    Its working but when you have only 1 gold nugget when you have more than 4-50 nugget it doesn't give you exactly the scarab coins i mean not 99 and 99 cc
     
    Last edited: Jul 13, 2018
  8. Vulcan_

    Vulcan_ Support Team Support Team

    Joined:
    Feb 14, 2015
    Messages:
    4,038
    Likes Received:
    1,849
    Best Answers:
    316
    Best Answer
    uint32_t holds up to a value of 4,294,967,295
    42 gold nuggets = 4,200,000,000
    after 43 the number loops back around to 0 and starts counting from there again
    basically you need to set the stuff that deals with item::getWorth() and uses money to uint64_t so it holds that big of a value
    in game.cpp replace Game::removeMoney with this
    Code (C++):
    1. bool Game::removeMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0*/)
    2. {
    3.     if (cylinder == nullptr) {
    4.         return false;
    5.     }
    6.  
    7.     if (money == 0) {
    8.         return true;
    9.     }
    10.  
    11.     std::vector<Container*> containers;
    12.  
    13.     std::multimap<uint64_t, Item*> moneyMap;
    14.     uint64_t moneyCount = 0;
    15.  
    16.     for (size_t i = cylinder->getFirstIndex(), j = cylinder->getLastIndex(); i < j; ++i) {
    17.         Thing* thing = cylinder->getThing(i);
    18.         if (!thing) {
    19.             continue;
    20.         }
    21.  
    22.         Item* item = thing->getItem();
    23.         if (!item) {
    24.             continue;
    25.         }
    26.  
    27.         Container* container = item->getContainer();
    28.         if (container) {
    29.             containers.push_back(container);
    30.         } else {
    31.             const uint64_t worth = item->getWorth();
    32.             if (worth != 0) {
    33.                 moneyCount += worth;
    34.                 moneyMap.emplace(worth, item);
    35.             }
    36.         }
    37.     }
    38.  
    39.     size_t i = 0;
    40.     while (i < containers.size()) {
    41.         Container* container = containers[i++];
    42.         for (Item* item : container->getItemList()) {
    43.             Container* tmpContainer = item->getContainer();
    44.             if (tmpContainer) {
    45.                 containers.push_back(tmpContainer);
    46.             } else {
    47.                 const uint64_t worth = item->getWorth();
    48.                 if (worth != 0) {
    49.                     moneyCount += worth;
    50.                     moneyMap.emplace(worth, item);
    51.                 }
    52.             }
    53.         }
    54.     }
    55.  
    56.     if (moneyCount < money) {
    57.         return false;
    58.     }
    59.  
    60.     for (const auto& moneyEntry : moneyMap) {
    61.         Item* item = moneyEntry.second;
    62.         if (moneyEntry.first < money) {
    63.             internalRemoveItem(item);
    64.             money -= moneyEntry.first;
    65.         } else if (moneyEntry.first > money) {
    66.             const uint64_t worth = moneyEntry.first / item->getItemCount();
    67.             const uint32_t removeCount = std::ceil(money / static_cast<double>(worth));
    68.  
    69.             addMoney(cylinder, (worth * removeCount) - money, flags);
    70.             internalRemoveItem(item, removeCount);
    71.             break;
    72.         } else {
    73.             internalRemoveItem(item);
    74.             break;
    75.         }
    76.     }
    77.     return true;
    78. }
    inside of item.cpp in Item::getWorth() replace case ITEM_GOLD_NUGGET: with this
    Code (C++):
    1.     case ITEM_GOLD_NUGGET:
    2.         return count * 100000000ULL;
    if you ever add more money items, inside of Item::getWorth(), the number you multiply with (return count * <this number>) needs to have ULL at the end of it (see 100000000ULL above)
     
  9. Sarah Wesker

    Sarah Wesker S.E ©

    Joined:
    Mar 16, 2017
    Messages:
    279
    Likes Received:
    122
    Best Answers:
    20
    the answer of Vulcan_ is correct!
    but missing this:
    Code (Text):
    1.  
    2. uint32_t Item::getWorth() const
    3.  
    change to
    Code (Text):
    1.  
    2. uint64_t Item::getWorth() const
    result:
    Code (Text):
    1.  
    2. uint64_t Item::getWorth() const
    3. {
    4.     switch (id) {
    5.     case ITEM_GOLD_COIN:
    6.         return count;
    7.  
    8.     case ITEM_PLATINUM_COIN:
    9.         return count * 100;
    10.  
    11.     case ITEM_CRYSTAL_COIN:
    12.         return count * 10000;
    13.  
    14.     case ITEM_SCARAB_COIN:
    15.         return count * 1000000ULL;
    16.  
    17.     case ITEM_GOLD_NUGGET:
    18.         return count * 100000000ULL;
    19.  
    20.     default:
    21.         return 0;
    22.     }
    23. }
    also search in item.h
    Code (Text):
    1. uint32_t getWorth() const;
    and change for
    Code (Text):
    1. uint64_t getWorth() const;
     
    Last edited: Jul 14, 2018
    Shadow_ and Vulcan_ like this.
  10. Vulcan_

    Vulcan_ Support Team Support Team

    Joined:
    Feb 14, 2015
    Messages:
    4,038
    Likes Received:
    1,849
    Best Answers:
    316
    nice catch, forgot to recheck what i changed in items.cpp
    but that case ITEM_GOLD_NUGGET needs to be return count * 100000000ULL
     
    Shadow_ likes this.
  11. Sarah Wesker

    Sarah Wesker S.E ©

    Joined:
    Mar 16, 2017
    Messages:
    279
    Likes Received:
    122
    Best Answers:
    20
    Sure ;)
     
    Shadow_ likes this.
  12. Shadow_

    Shadow_ CarcooIzx.zapto.org

    Joined:
    Jun 2, 2018
    Messages:
    202
    Likes Received:
    24
    Best Answers:
    3
    Thank you both guys @Sarah Wesker and @Vulcan_ after reading it iam sure 100% its working without testing
     
    Sarah Wesker likes this.

Share This Page

Loading...