kaansoral / adventureland

Adventure Land The Open Source CODE MMORPG
Other
199 stars 62 forks source link

Return object from Exchangeables on Currency or stackable reward is not descriptive #99

Open Will-Crain opened 9 months ago

Will-Crain commented 9 months ago

The problem

Currently, when a player opens an exchangeable, the return object on the exchange function does not return useful information in the following two cases:

  1. The player receives any currency (untested for Shells, but easily verifiable with Gold)
  2. The player receives a stackable item for an item they already have a stack for in their inventory

Some background

starting with the exchange function

//Source code of: exchange
async function exchange(item_num)
{
    parent.e_item=item_num;
    var call=await parent.exchange(1),num=undefined,name=undefined;
    if(!call.in_progress) return call;
    if(character.q.exchange) num=character.q.exchange.num;
    while(character.q.exchange || character.items[num] && character.items[num].name=="placeholder")
        await sleep(1);
    if(character.items[num]) name=character.items[num].name;
    else num=undefined;
    return {success:true,reward:name,num:num};
}

This code function executes parent.exchange, which I believe is located in js/functions.js line 3122. Then, the exchange function awaits the exchange animation via await sleep(1) calls while q.exchange is in progress.

When the exchange is finished, the function checks what item ended up in the q.exchange.num slot and returns the name (reward) and inventory slot (num) of the reward

This is where the crux of the problem lies. For items that don't stay in the slot the exchange placeholder item sat in, the return object is basically empty image

Case 1

When opening an exchangeable, the return object only populates reward and num if the resulting item is an actual item. Currency rewards (gold, shells) result in the returned object having an undefined reward and num property

The following objects were generated with the code (executed in the in-game snippet runner),

exchange(ITEM_INDEX).then( (s) => console.log(s) )

image ^ A functioning example: Raw Emerald that contained a Weapon Box. reward isweaponbox because the emerald resulted in a weaponbox, and num is 26, because that's the slot the item ended up in.

image ^ A broken example: Green Envelope that contained 50,000 gold

Looking back to the exchange function, reward gets set to name if & only if character.items[num] is not falsey. num in this context is the character.q.exchange.num, which is the inventory index of the placeholder item during the exchange. In most cases, this placeholder item index is also the slot the rewarded item ends up in. However, once exchanges finish that reward a currency, the currency doesn't remain as an item in your inventory. Because it doesn't stick around in your inventory, character.items[num] goes back to being falsey, which keeps reward undefined and resets num to undefined

Case 2

In another example, the return object also breaks when you receive a stackable item for which you already have a non-full stack of.

The exchange's placheolder item sits in a non-empty slot in the character's inventory. If the reward is a stackable item, the item joins an existing non-full stack. This leads to another empty return object, since the reward does not end up in the inventory slot that the placeholder item was in.

When opening a Green Envelope and receiving a Firecracker while there are no other firecrackers in my inventory, the following object is returned image

However, with that firecracker still in my inventory, receiving another returns an empty object. image

Conclusion

I don't know how to fix this, otherwise I would've opened a PR with the fix.