inventory paging - arrows and more

Started by Nixxon, Tue 31/10/2017 00:18:15

Previous topic - Next topic

Nixxon

Hi Guys,

Had a good search on this but couldn't find anything.

I have a very small inventory window integrated into the UI. The window only holds 3 inventory items before the player has to 'page up and down' to scroll through.



While this works, it's not very well optimised.

1. up and down arrows are always on (even if not needed).
Ideally, each would only appear when scrolling up or down was actually available.

For instance. If the player has no inventory objects or 3 objects filling the inventory window, the arrows should not be visible at all.

Additionally, if the player is on the second inventory window, he should only be able to scroll back up to the initial window of 3.

Christ, I hope that makes sense ;)


EDIT - I have found this post - http://www.adventuregamestudio.co.uk/forums/index.php?topic=16999.msg209564#msg209564

However i get the error message.

GlobalScript.asc(92): Error (line 92): undefined symbol 'GetButtonPic'

Crimson Wizard

#1
That should be simple, there is a TopItem property of InventoryWindow.

Sample code:
Code: ags

function UpdateInvScrolls()
{
    btnScrollUp.Visible = invWindow.TopItem > 0;
    brnScrollDown.Visible = invWindow.TopItem + invWindow.ItemsPerRow < invWindow.ItemCount;
}


Now, you need to call that function -
* at game start;
* whenever scroll button is clicked;
* whenever inventory item has been picked or lost.

Regarding the latter, there are two ways to keep track of that. Just for all the goodness sake, don't put UpdateInvScrolls() after each AddInventory in your game!
1. Write your own custom functions for taking and loosing inventory item, which, besides calling actual AGS function AddInventory/LoseInventory would also call UpdateInvScrolls
2. If you really-really do not want to do that (or don't have time), then just put UpdateInvScrolls into repeatedly_execute. (lol, yes, I said that :))

3. Correct method, with on_event callback:
Code: ags

function on_event(EventType event, int data)
{
    if (event == eEventAddInventory || event == eEventLoseInventory)
    {
        UpdateInvScrolls();
    }
}



EDIT:
Quote from: Nixxon on Tue 31/10/2017 00:18:15
EDIT - I have found this post - http://www.adventuregamestudio.co.uk/forums/index.php?topic=16999.msg209564#msg209564

However i get the error message.

GlobalScript.asc(92): Error (line 92): undefined symbol 'GetButtonPic'

That code is sooo old. It uses obsolete functions, also uses a lot of hardcoded constants. I am not sure if monkey0506 would approve that code today :).

Nixxon

#2
Thanks Crim!

That code looks super clean. I figured the 2004 thread might have been a little long in the tooth ;)

I opted for the repeatedly execute path (cause ehh). I do get this 'doosey' in the first room code however.

Code: ags
// room script file
function UpdateInvScrolls()
{
    Button12.Visible = ginvwindow.TopItem > 0;
    Button13.Visible = ginvwindow.TopItem + ginvwindow.ItemsPerRow - 1 < ginvwindow.ItemCount;
}



Error message

Failed to save room room1.crm; details below
room1.asc(4): Error (line 4): '.TopItem' is not a public member of 'GUI'. Are you sure you spelt it correctly (remember, capital letters are important)?


Woops, nevermind. I had the GUI name not the invwindow name.

Compiled ok, I will see how it goes :D


Crimson Wizard

#3
Oh shoot, I double checked and apparently on_event() callback is also called when player takes and loses inventory. So instead of those two methods above you can actually do:

Code: ags

function on_event(EventType event, int data)
{
    if (event == eEventAddInventory || event == eEventLoseInventory)
    {
        UpdateInvScrolls();
    }
}


That should be better than repeatedly_execute.

EDIT: Also there is a small mistake when setting brnScrollDown.Visible, I fixed it in original post.

Nixxon

Oh works a charm Crim. Thank you!! :D

FYI.

This is the code on the Global-script -
Code: ags
function UpdateInvScrolls()
{
    Button12.Visible = InventoryWindow2.TopItem > 0;
    Button13.Visible = InventoryWindow2.TopItem + InventoryWindow2.ItemsPerRow < InventoryWindow2.ItemCount;
}
function on_event(EventType event, int data)
{
    if (event == eEventAddInventory || event == eEventLoseInventory)
    {
        UpdateInvScrolls();
    }
}



Code for Scroll Button/s

Code: ags
function Button13_OnClick(GUIControl *control, MouseButton button)
{
InventoryWindow2.ScrollDown();
    Button12.Visible = InventoryWindow2.TopItem > 0;
    Button13.Visible = InventoryWindow2.TopItem + InventoryWindow2.ItemsPerRow < InventoryWindow2.ItemCount;
}

Crimson Wizard

#5
You really could simply call UpdateInvScrolls() from Button13_OnClick too! Or was there some issue with that?

Nixxon

It doesn't like that Crim.

Code: ags
function Button13_OnClick(GUIControl *control, MouseButton button)
{
InventoryWindow2.ScrollDown();
    Button12.Visible = InventoryWindow2.TopItem > 0;
    Button13.Visible = InventoryWindow2.TopItem + InventoryWindow2.ItemsPerRow < InventoryWindow2.ItemCount;
    UpdateInvScrolls();


GlobalScript.asc(767): Error (line 767): Undefined token 'UpdateInvScrolls'

Crimson Wizard

#7
Quote from: Nixxon on Tue 31/10/2017 01:37:00
GlobalScript.asc(767): Error (line 767): Undefined token 'UpdateInvScrolls'

Oh, you just need to put the function above its first use. This is how it works in AGS, function definition (or import declaration) should always be mentioned before it is first used in script.

Nixxon

Thanks Crim,

Makes sense! It appears to be working flawlessly - I'm afraid to touch it.

might be worth noting that I have added this to the first room script (before load). (this is the room our player restarts in after death).

Code: ags
    Button12.Visible = InventoryWindow2.TopItem > 0;
    Button13.Visible = InventoryWindow2.TopItem + InventoryWindow2.ItemsPerRow < InventoryWindow2.ItemCount;


Otherwise the arrows appear until and inventory item is picked up :)

Crimson Wizard

Quote from: Nixxon on Tue 31/10/2017 01:56:50
might be worth noting that I have added this to the first room script (before load). (this is the room our player restarts in after death).

Otherwise the arrows appear until and inventory item is picked up :)

Right, although I'd suggest to put it just to the game_start.

Another note, if you want to be able to use such function in a room script (instead of copying full function code there), you can declare it in the GlobalScript.ash (header) like this:

Code: ags

import function UpdateInvScrolls();


If you do, then every room script will be able to call it normally.

SMF spam blocked by CleanTalk