Shuffling items between multiple inventories. Getting array error...

Started by Nerren, Thu 28/11/2024 13:03:54

Previous topic - Next topic

Nerren

Hello everyone,

I've recently gotten back into AGS after many years away, and am working on a new RPG.  I thought I had a workable idea for item equipping.  The player has base stats, but can equip 1 weapon, 1 armor piece and 1 jewelry piece for stat increases and aesthetics.  I decided my main inventory screen will have an "Equip" button, and also a section with equipped items.  There are 3 dummy characters I created, and on the Inventory GUI I assigned 3 separate inventories to these 3 characters.  There is a cEquippedWeapon, cEquippedArmor and cEquippedJewelry character that I'm referencing with my script.  The idea is that the player selects the item they want to equip, so it becomes the ActiveInventory object.  They then click the "Equip" button on the GUI, which runs the on_click code.  The code should take note of Inventory Item #, with 1 and 2 being weapons, 3 and 4 being armor, 5 and 6 being jewely.  It should allow each of the 2 to be equipped (which player.LoseInventory and cEquipped___.AddInventory are used), but only if there isn't already an item equipped / in that secondary character inventory already.  Once working, I'm going to add the stat boosts, view changes, etc. 

The problem is that I am getting an error on the line of code at :
Code: ags
        if (cEquippedWeapon.InventoryQuantity > 0)

The error thrown when I try to run the game is:

GlobalScript.asc(2131): Error (line 2131): Expected array index after 'Character::InventoryQuantity'

For reference, the entire on_click event script for the Equip Button is:

Code: ags
function btnInvEquip_OnClick(GUIControl *control, MouseButton button)
{
  
    InventoryItem* selectedItem = player.ActiveInventory; // Get the currently selected inventory item

    if (selectedItem == null)
    {
        Display("You must select an item first");
        return;
    }

    // Check if the item is a weapon (IDs 1-2)
    if (selectedItem.ID == 1 || selectedItem.ID == 2)
    {
        if (cEquippedWeapon.InventoryQuantity > 0)
        {
            Display("You already have a weapon equipped.");
        }
        else
        {
            cEquippedWeapon.AddInventory(selectedItem);
            player.LoseInventory(selectedItem);
            Display("You've equipped the weapon.");
        }
    }
    // Check if the item is armor (IDs 3-4)
    else if (selectedItem.ID == 3 || selectedItem.ID == 4)
    {
        if (cEquippedArmor.InventoryQuantity > 0)
        {
            Display("You already have armor equipped.");
        }
        else
        {
            cEquippedArmor.AddInventory(selectedItem);
            player.LoseInventory(selectedItem);
            Display("Armor equipped!");
        }
    }
    // Check if the item is jewelry (IDs 5-6)
    else if (selectedItem.ID == 5 || selectedItem.ID == 6)
    {
        if (cEquippedJewelry.InventoryQuantity > 0)
        {
            Display("You already have jewelry equipped.");
        }
        else
        {
            cEquippedJewelry.AddInventory(selectedItem);
            player.LoseInventory(selectedItem);
            Display("Jewelry equipped!");
        }
    }
    // If the item doesn't belong to any category for testing
    else
    {
        Display("This item cannot be equipped.");
    }

}


If anyone has any insight into this, I'd greatly appreciate it.  I didn't think it was too complicated of a script, and I can't seem to find anything on the forum with those keywords.

Thanks!

Bill


Snarky

This doesn't work quite the way you want it to. Since cEquippedWeapon is a character, its inventory can include all sorts of items (basically, it is a list of all the inventory items in the game, with a count of how many instances the character has of that item), and InventoryQuantity is about how many it has of a particular item, and therefore has to be used like cEquippedWeapon.InventoryQuantity[iItem] (where iItem is the particular item to check). You can see an example in the manual, which should be the first place you check in cases like this.

There's no easy way to check if the inventory includes any weapon, or count how many items are in the inventory in total. (You would have to loop through the whole inventory, or link the inventory to an InvWindow, which does that under the hood.)

Personally I wouldn't use characters or inventories at all, but instead just use an InventoryItem variable for each equippable slot:

Code: ags
InventoryItem* equippedWeapon;
InventoryItem* equippedArmor;
InventoryItem* equippedJewelry;

// ...

        if (equippedWeapon != null )
        {
            Display("You already have a weapon equipped.");
        }
        else
        {
            equippedWeapon = selectedItem;
            player.LoseInventory(selectedItem);
            Display("You've equipped the weapon.");
        }
// ...

(You could also wrap these variables up in a struct, but it's not really necessary.)

Also, it's not the case here, but in general be aware that the AGS compiler doesn't distinguish condition lines from the lines immediately following, so if an error message says that there's a mistake on an if/for/while etc. line, the error might actually be on the next line.

Nerren

That's great to know moving forward, thanks so much for the insight.  That was so much simpler to implement and works great.  A few tweaks, and it'll be exactly what I need. 

Thanks again for the assistance!

Bill

SMF spam blocked by CleanTalk