Gw Temp

Menu

Tutorial - 'User Friendly CMS II - Listing' by Jerm

An item about RPGMaker 2000 posted on

Blurb

A continuation of the User-Friendly CMS guide. A well written, in-depth tutorial!

Body

User Friendly CMS II: Listing
-----------------------------
In part I of this series (aptly not named "part I"), I set down the basics of creating a cursor that automatically continued to scroll in a direction if an arrow key was held down. Such a feature however would not be very useful without a long list to actually scroll down. So here we are. In part II, I will detail how to create a list of items that both auto-condenses itself to close up gaps and extends beyond the page boundaries preset for it.

First off, I'm writing this in the context of being an Item menu list. That's the basis for how I'm going to designate a lot of the things brought up during this tutorial, but of course it could be interchanged for any function. This is a CMS we're talking about.

Secondly, this won't be as straightforward as my previous one. The first tutorial was basically an add-on for a preexisting script. And while this is technically an add-on from part I of this series anyway, it's still a monster of its own. So it may take a few reads to get all the pieces together.

For the purpose of this tutorial, we will have ten total items. It can be more or less in your own version, of course. These items can have their own names, but I will call them Item #1 - Item #10 for easy memory. There will be two markers for each of these items, one to designate a slot number, and the other for quantity. A variable is required to store the slot number, however I would recommend using RM2k3's built-in item system to store the quantity. Why? In a CMS, I doubt they'd be used for anything else. Also, it'll keep the variables from getting too overcrowded.

So go to variables and create a variable for each item, and then an actual item for each in the database menu. Now, we'll need a visual marker. An image. Basically, a picture of the item's name; all pictures having the same HxW dimensions. The width isn't so important here as the height. The images I use for my own game are 16 pixels tall. So this tutorial will be based on that. If yours are taller or shorter, alter the script when needed.

Finally, you will want to create four more variables. You can change the name if you wish, but I call them Var:[Loop #], Var:[Current Slot], Var:[Scroll Slot], and Var:[Max Slot]. We will get into the details of these as we go.

Now that we have this set, we can begin programming the listing script. To get back into the mindset of what's going on here, let's dig up the skeleton from the first tutorial again:

(1) Loop
(2) Move Picture: 1, (V[Menu X],V[Menu Y]), 0.1 Sec (No Wait)
(3) Variable Oper: [PASSWORD] Set, 0
(4) Wait: 0.1 Sec
(5) Key Input Proc: [PASSWORD] (1,2,3,4) (No Wait)
(6) Branch if Var [PASSWORD] is 1 or more
(6.1) Branch if Switch [CURSOR PAUSE] is OFF
(6.11) Switch Operation: [CURSOR PAUSE] ON
(6.12) Variable Oper: [PASSWORD] Set, 0
(6.13) Wait: 0.2 Sec
(6.14) Key Input Proc: [PASSWORD] (1,2,3,4) (No Wait)
(6.2) Jump to Label: 1
(7) Key Input Proc: [PASSWORD] (1,2,3,4,5,6) (Wait)
(8) Switch Operation: [CURSOR PAUSE] OFF
(9) Label: 1
(10) Branch if Var [PASSWORD] is 1
[insert code here for moving cursor down]
(11) Branch if Var [PASSWORD] is 2
[insert code here for moving cursor left]
(12) Branch if Var [PASSWORD] is 3
[insert code here for moving cursor right]
(13) Branch if Var [PASSWORD] is 4
[insert code here for moving cursor up]
(14) Branch if Var [PASSWORD] is 5
(15) Branch if Var [PASSWORD] is 6
(16) End Loop

If you'll note, this is the extended skeleton version for the auto-scrolling I set up in part I. Might as well keep it. Now, the first thing we'll need to do is fill in the [insert code here] parts. Because they're going to be needed later on. We'll ignore numbers 2 and 3, as this tutorial will focus on a basic top-to-bottom list that only needs to move up and down. So now as soon as we know the image dimensions, we can place and move the cursor. On a few conditions. Where does it start? What's the top slot and what's the bottom slot?

Well, that will vary from game to game. But knowing this will be necessary for the next part so I will just pull a number out of the air. Let's pretend the item in slot 1 (top of the list) will have a Y of 50 (50 pixels from the top of the screen). And for the hell of it, X is at 25 (25 pixels from the left of the screen). Now, how tall are the images you use for the item pictures. My own are 16 pixels tall as mentioned above. So slot 1 would be at 50, slot two at 50+16 or 66, etc. Until you reach the bottom slot before the list scrolls off the screen or out of the area you have designated for the list. Let's say there is room for five items in the list. So the final Y would be 114 (50+16+16+16+16). Obviously, you should change these numbers to suit your own CMS.

The final stage will look like this:

(1) Variable Oper: [Scroll Slot] Set, 1
(2) Variable Oper: [Current Slot] Set, 1
(3) Variable Oper: [Menu X] Set, 25
(4) Variable Oper: [Menu Y] Set, 50
(5) Show Picture: 1, (V[Menu X],V[Menu Y])
(6) Loop
(7) Move Picture: 1, (V[Menu X],V[Menu Y]), 0.1 Sec (No Wait)
(8) Call Event: Item Organizer[1]
(9) Variable Oper: [PASSWORD] Set, 0
(10) Wait: 0.1 Sec
(11) Key Input Proc: [PASSWORD] (1,2,3,4) (No Wait)
(12) Branch if Var [PASSWORD] is 1 or more
(12.1) Branch if Switch [CURSOR PAUSE] is OFF
(12.11) Switch Operation: [CURSOR PAUSE] ON
(12.12) Variable Oper: [PASSWORD] Set, 0
(12.13) Wait: 0.2 Sec
(12.14) Key Input Proc: [PASSWORD] (1,2,3,4) (No Wait)
(12.2) Jump to Label: 1
(13) Key Input Proc: [PASSWORD] (1,2,3,4,5,6) (Wait)
(14) Switch Operation: [CURSOR PAUSE] OFF
(15) Label: 1
(16) Branch if Var [PASSWORD] is 1
(16.1) Branch if Var [Current Slot] is Var [Max Slot] Equal
(16.11) Variable Oper: [Current Slot] Set, 1
(16.12) Variable Oper: [Scroll Slot] Set, 1
(16.13) Variable Oper: [Menu Y] Set, 50
(16.2) Else Handler
(16.21) Branch if Var [Menu Y] is 114
(16.211) Variable Oper: [Scroll Slot] Set, 1
(16.212) Variable Oper: [Current Slot] Set, 1
(16.22) Else Handler
(16.221) Variable Oper: [Current Slot] +, 1
(16.222) Variable Oper: [Menu Y] +, 16
(17) Branch if Var [PASSWORD] is 2
(18) Branch if Var [PASSWORD] is 3
(19) Branch if Var [PASSWORD] is 4
(19.1) Branch if Var [Menu Y] is 50
(19.11) Branch if Var [Current Slot] is 1
(19.111) Variable Oper: [Scroll Slot] Set, Var:[Max Slot]
(19.112) Variable Oper: [Current Slot] Set, Var:[Max Slot]
(19.113) Branch if Var [Max Slot] is 5 or more
(19.1131) Variable Oper: [Scroll Slot] -, 4
(19.1132) Variable Oper: [Menu Y] Set, 114
(19.114) Else Handler
(19.1141) Variable Oper: [Scroll Slot] Set, 1
(19.1142) Branch if Var [Max Slot] is 4
(19.11421) Variable Oper: [Menu Y] Set, 98
(19.1143) Branch if Var [Max Slot] is 3
(19.11431) Variable Oper: [Menu Y] Set, 82
(19.1144) Branch if Var [Max Slot] is 2
(19.11441) Variable Oper: [Menu Y] Set, 66
(19.1145) Branch if Var [Max Slot] is 1
(19.11451) Variable Oper: [Menu Y] Set, 50
(19.12) Else Handler
(19.121) Variable Oper: [Scroll Slot] -, 1
(19.122) Variable Oper: [Current Slot] -, 1
(19.2) Else Handler
(19.21) Variable Oper: [Current Slot] -, 1
(19.22) Variable Oper: [Menu Y] -, 16
(20) Branch if Var [PASSWORD] is 5
(21) Branch if Var [PASSWORD] is 6
(22) End Loop

Oh yeah, now we're getting convoluted. Let's start the explanation then. Lines (1) - (5) are presets, what you want to happen when the menu is opened up but not be looped. Starting with (3) - (5), we just enter the coordinates for slot 1 and put the cursor there. Lines (1) and (2) however, give us our first look at two of the new variables I had created earlier. So let's talk about them.

Hopefully their names help out a little, Var:[Current Slot] is the marker for what slot the cursor is currently in. In the item organizing that goes on below, each item is given its own slot number. This number is used to play against Var:[Current Slot] to determine which specific item is being highlighted at the time.

Var:[Scroll Slot] is a little bit more complicated. Going by what we're using, let's say we have 10 items, and the screen can only show 5 at a time. So Items 1-5 are shown at Scroll Slot 1. Now we move the cursor down to the bottom of that (slot 5) and hit down once. The screen should scroll down a notch and we now see Items 2-6. And Scroll Slot would be 2. The purpose of this variable is to determine which items will be showing (done in the final part of this tutorial). The max of Var:[Scroll Slot] is always Var:[Max Slot] subtracted by one less than how many items can appear on the screen at once. With a minimum of 1.

Line (8) calls up a new event to organize and list the items, which will get detailed below. So we will skip over it for the moment.

Next we get more of the same all the way down until line (16.1). Now we've actually fleshed out what happens when a direction is hit. (16.1) and its subsets detail what happens when the down arrow is hit (Var:[Password] is 1).

Basically when you hit that key, there are three possibilities. If the cursor (var:[Current Slot]) is equal to var:[Max Slot] (meaning it's at the bottom of the list), then all three marker variables (var:[Current Slot], var:[Scroll Slot], Var:[Menu Y]) reset to the top (lines (16.1) to (16.13)). If not, then two options remain. Is the current slot at the bottom of the screen or not? If so, then we move one space down the list, scroll down the page a notch, but the cursor's position stays at the bottom (lines (16.21) to (16.212). And if not, then the cursor moves down a slot, but the screen doesn't scroll (lines (16.221) to (16.222)).

It gets complicated though, when up is hit instead (Var:[Password] is 4). This is because the outcome of where the cursor ends up when it begins at the top of the list varies depending on what Var:[Max Slot] is. But for the most part, it's just a reciprocal of what happens when down is hit. Var:[Scroll Slot] and Var:[Current Slot] get -1 one when the cursor is at the top of the display screen, but not the list, Var:[Current Slot] gets -1 and Var:[Menu Y] gets -16 when the cursor isn't at the top. But what happens when the cursor is at the top and Var:[Current Slot] is 1, when we have to swing around to the bottom of the list?

As noted earlier, the max of Var:[Scroll Slot] is Var:[Max Slot] subtracted by one less the number of item slots that can appear at one time. So per lines (19.111) and (19.1131) we set Var:[Scroll Slot] to Var:[Max Slot] and then subtract it by 4 (1 less than the five visible slots). Then in line (19.1141), on the condition that Var:[Max Slot] is not 5 or greater in line (18.114) we set Var:[Scroll Slot] to 1, the minimum. This is to keep it from getting into the negatives or 0 and causing bugs. Var:[Menu Y] is then sifted through a process of elimination based on what Var:[Max Slot] really is in the subsets of lines (19.1142) to (19.1145). For example, if Var:[Max Slot] were only 4 when there is room for five items at a time, then the bottom slot would be slot 4. And etc.

So that's that.

Now we will create a script that takes these items, boots out the ones that have zero quantity, and puts the remainders in a specific order. Due to the length of the final product, you may want to place this as its own page (or event). In fact, it may be necessary considering it will be called back at various times when navigating the menu itself. This tutorial will assume you have done so. In line (8) shown and mentioned above, it is a separate event called Item Organizer[1]. Change the name however you want.

The beginning of the script in Item Organizer[1] will look like this:

(1) Variable Oper: [Item #1] Set, 1
(2) Variable Oper: [Item #2] Set, 2
(3) Variable Oper: [Item #3] Set, 3
(4) Variable Oper: [Item #4] Set, 4
(5) Variable Oper: [Item #5] Set, 5
(6) Variable Oper: [Item #6] Set, 6
(7) Variable Oper: [Item #7] Set, 7
(8) Variable Oper: [Item #8] Set, 8
(9) Variable Oper: [Item #9] Set, 9
(10) Variable Oper: [Item #10] Set, 10
(11) Variable Oper: [Max Slot] Set, 10
(12) Variable Oper: [Loop #] Set, 1
(13) Loop
(14) End Loop

This creates a set 'em up and knock 'em down style to the script. Basically, giving the items their predesignated numbers in advance. Within the loop (detailed below), we will go through each one and check if any are currently in the party's stock. If not, they are eliminated and all numbers below them are pushed up a slot.

Now let's go into the loop and begin elimination:

(1) Variable Oper: [Item #1] Set, 1
(2) Variable Oper: [Item #2] Set, 2
(3) Variable Oper: [Item #3] Set, 3
(4) Variable Oper: [Item #4] Set, 4
(5) Variable Oper: [Item #5] Set, 5
(6) Variable Oper: [Item #6] Set, 6
(7) Variable Oper: [Item #7] Set, 7
(8) Variable Oper: [Item #8] Set, 8
(9) Variable Oper: [Item #9] Set, 9
(10) Variable Oper: [Item #10] Set, 10
(11) Variable Oper: [Max Slot] Set, 10
(12) Variable Oper: [Loop #] Set, 1
(13) Loop
(14) Branch if Var[Loop #] is 2
(14.1) Branch if Item #2 Not Possessed
(14.11) Variable Oper: [Item #2] Set, 0
(14.12) Jump to Label 2
(14.2) Else Handler
(14.21) Jump to Label 1
(15) Branch if Var[Loop #] is 3
(15.1) Branch if Item #3 Not Possessed
(15.11) Variable Oper: [Item #3] Set, 0
(15.12) Jump to Label 3
(15.2) Else Handler
(15.21) Jump to Label 1
(16) Branch if Var[Loop #] is 4
(16.1) Branch if Item #4 Not Possessed
(16.11) Variable Oper: [Item #4] Set, 0
(16.12) Jump to Label 4
(16.2) Else Handler
(16.21) Jump to Label 1
(17) Branch if Var[Loop #] is 5
(17.1) Branch if Item #5 Not Possessed
(17.11) Variable Oper: [Item #5] Set, 0
(17.12) Jump to Label 5
(17.2) Else Handler
(17.21) Jump to Label 1
(18) Branch if Var[Loop #] is 6
(18.1) Branch if Item #6 Not Possessed
(18.11) Variable Oper: [Item #6] Set, 0
(18.12) Jump to Label 6
(18.2) Else Handler
(18.21) Jump to Label 1
(19) Branch if Var[Loop #] is 7
(19.1) Branch if Item #7 Not Possessed
(19.11) Variable Oper: [Item #7] Set, 0
(19.12) Jump to Label 7
(19.2) Else Handler
(19.21) Jump to Label 1
(20) Branch if Var[Loop #] is 8
(20.1) Branch if Item #8 Not Possessed
(20.11) Variable Oper: [Item #8] Set, 0
(20.12) Jump to Label 8
(20.2) Else Handler
(20.21) Jump to Label 1
(21) Branch if Var[Loop #] is 9
(21.1) Branch if Item #9 Not Possessed
(21.11) Variable Oper: [Item #9] Set, 0
(21.12) Jump to Label 9
(21.2) Else Handler
(21.21) Jump to Label 1
(22) Branch if Var[Loop #] is 10
(22.1) Branch if Item #10 Not Possessed
(22.11) Variable Oper: [Item #10] Set, 0
(22.12) Jump to Label 10
(22.2) Else Handler
(22.21) Jump to Label 1
(23) Branch if Var[Loop #] is 11
(23.1) Break Loop
(24) Branch if Item #1 Not Possessed
(24.1) Variable Oper: [Item #1] Set, 0
(24.2) Variable Oper: [Item #2] -, 1
(24.3) Label 2
(24.4) Variable Oper: [Item #3] -, 1
(24.5) Label 3
(24.6) Variable Oper: [Item #4] -, 1
(24.7) Label 4
(24.8) Variable Oper: [Item #5] -, 1
(24.9) Label 5
(24.A) Variable Oper: [Item #6] -, 1
(24.B) Label 6
(24.C) Variable Oper: [Item #7] -, 1
(24.D) Label 7
(24.E) Variable Oper: [Item #8] -, 1
(24.F) Label 8
(24.G) Variable Oper: [Item #9] -, 1
(24.H) Label 9
(24.I) Variable Oper: [Item #10] -, 1
(24.J) Label 10
(24.K) Variable Oper: [Max Slot] -, 1
(25) Label 1
(26) Variable Oper: [Loop #] +, 1
(27) End Loop
(28) Branch if Var[Max Slot] is 0 or less
(28.1) Variable Oper: [Max Slot] Set, 1

You'll have noticed a few things, mainly how long this is. Trust me, it could be longer. It was a lot of trial and error working my way to this and I created some NIGHTMARE scripts during the process. Mostly the length of this is due to repetitive motions. The actual gist of what is being done is fairly simple. It just has to be repeated for each item. Another note of point is the mass of Labels used. Basically it boils down to one label per item. The maximum number of labels for a page is 100, so the max of items would be 100. I hope you're not planning on having more than that. Finally, the line (24) subset goes into letters once they pass (24.9). I didn't want to go into double digits because that would get confusing (that's how I designate Branch If subsets), just pretend the letters are continuing increments that carry on from where the 9 left off.

Okay, so let's go to the explanation. I will describe this in chronological order, which will save a bit of time and space, I hope.

Initially in lines (1) through (10), we give all items a preset number. This will be their initial and--if all items are accounted for--final slot number. Then we set Var:[Max Slot] to the highest item # slot (in this case 10) in line (11), and Var:[Loop #] to 1 in line (12). With Var:[Loop #] being at one the first time around, it will skip over half of the script there to line (24). So we basically start in the middle.

Here in line (24) it asks if you have any of Item #1. If you do, it skips the 'not possessed' subset down to line (26), which increases Var:[Loop #] by 1. If you don't have any of Item #1, then Var:[Item #1] is set to 0, and all items below it go up a slot by subtracting themselves by 1 (lines (24.1) to (24.I)). With one item gone, Var:[Max Slot] also drops by 1 (line (24.K)).

Either way, line (27) hits and jumps us back to line (13). Only this time Var:[Loop #] is 2 instead. This activates line (14). Inside of the (14.?) subset, we're given more of the same, only with Item #2 instead of #1. If no Item #2 is possessed, Var:[Item #2] goes to 0, and we jump to Label 2 and the cycle repeats. All the way until Var:[Loop #] hits 11 and then we break out of the loop.

In the end, let's say we had a few of Item #2, Item #3, Item #7, and Item #10. Through this script, Var:[Item #2] would be 1, Var:[Item #3] would be 2, Var:[Item #7] would be 3, Var:[Item #10] would be 4, and Var:[Max Slot] would also be 4. All other item variables would be 0. So now we have an order.

Finally in line (28), we make sure that Var:[Max Slot] is never 0 or less. That would create bugs if you tried to move the cursor on an empty list.

But that's only half of it. Now that we have them organized, we now have to place their representing pictures for the cursor to point to or highlight.

To do this, we need to know the X and Y coordinates for the pictures. As stated near the top of this tutorial, I placed the defaults of X and Y to 25 and 50 respectively. And Y goes up in increments of 16 per slot.

So now with that in mind let's go to the basics of part 2 (this will come directly after line (28.1) above):

(29) Erase Picture: 2
(30) Branch if Var[Item #1] is Var[Scroll Slot] equal
(30.1) Show Picture: 2, Item #1, (25,50)
(31) Branch if Var[Item #2] is Var[Scroll Slot] equal
(31.1) Show Picture: 2, Item #2, (25,50)
(32) Branch if Var[Item #3] is Var[Scroll Slot] equal
(32.1) Show Picture: 2, Item #3, (25,50)
(33) Branch if Var[Item #4] is Var[Scroll Slot] equal
(33.1) Show Picture: 2, Item #4, (25,50)
(34) Branch if Var[Item #5] is Var[Scroll Slot] equal
(34.1) Show Picture: 2, Item #5, (25,50)
(35) Branch if Var[Item #6] is Var[Scroll Slot] equal
(35.1) Show Picture: 2, Item #6, (25,50)
(36) Branch if Var[Item #7] is Var[Scroll Slot] equal
(36.1) Show Picture: 2, Item #7, (25,50)
(37) Branch if Var[Item #8] is Var[Scroll Slot] equal
(37.1) Show Picture: 2, Item #8, (25,50)
(38) Branch if Var[Item #9] is Var[Scroll Slot] equal
(38.1) Show Picture: 2, Item #9, (25,50)
(39) Branch if Var[Item #10] is Var[Scroll Slot] equal
(39.1) Show Picture: 2, Item #10, (25,50)

This will place the picture for the item that goes in slot #1. Line (29) is needed just in case your inventory is empty. If no Var[Item #?] is equal to Var:[Scroll Slot] then no picture will be placed there.

Continuing from there we go to the second slot. To do this, we simply add one to the scroll slot.

(40) Variable Oper: [Scroll Slot] +, 1
(41) Erase Picture: 3
(42) Branch if Var[Item #2] is Var[Scroll Slot] equal
(42.1) Show Picture: 3, Item #2, (25,66)
(43) Branch if Var[Item #3] is Var[Scroll Slot] equal
(43.1) Show Picture: 3, Item #3, (25,66)
(44) Branch if Var[Item #4] is Var[Scroll Slot] equal
(44.1) Show Picture: 3, Item #4, (25,66)
(45) Branch if Var[Item #5] is Var[Scroll Slot] equal
(45.1) Show Picture: 3, Item #5, (25,66)
(46) Branch if Var[Item #6] is Var[Scroll Slot] equal
(46.1) Show Picture: 3, Item #6, (25,66)
(47) Branch if Var[Item #7] is Var[Scroll Slot] equal
(47.1) Show Picture: 3, Item #7, (25,66)
(48) Branch if Var[Item #8] is Var[Scroll Slot] equal
(48.1) Show Picture: 3, Item #8, (25,66)
(49) Branch if Var[Item #9] is Var[Scroll Slot] equal
(49.1) Show Picture: 3, Item #9, (25,66)
(50) Branch if Var[Item #10] is Var[Scroll Slot] equal
(50.1) Show Picture: 3, Item #10, (25,66)

A few small differences this time around. The pictures shown are given a new number (called Picture 3 here, will vary between games) and coordinates. The Y coordinate has increased by 16 (the height of the item pictures as mentioned above). Another small difference seen is Item #1 is removed from this. This is because Item #1 will never be in Slot #2. If you have it, it will always be top of the list. There's none before 1. The third time around for this, the same will be true with Item #2. It can only be in slot #2, or slot #1 if Item #1 isn't in your inventory at the time.

This pattern will repeat until you reach the last row of visible slots. This tutorial's mock item menu had a max of 5 visible, so we would repeat three more times to add to the two above. Increasing the Picture # and Y coordinate accordingly.

Afterwards however, don't forget to reset Var:[Scroll Slot] back to what it was before. A simple:

Variable Oper: [Scroll Slot] -, 4

will do it here, as it would have been given +1 four times. This will also vary between games, depending on the final number of slots visible.

And that's that. A not so basic outline of how to organize a list of items or such. Hopefully it's coherent enough that any altering needed (increasing number of items, size of pictures, etc) can easily be done.

A few notes in post:

1. Though this script says differently, the cursor should generally have a higher picture number than the item images. This is because a higher numbered picture will be placed "in front" of a picture with a lower number. If they overlap, the lower numbered image would be concealed. It depends on what kind of cursor you use though. A highlighting cursor should definitely be higher, but a pointing cursor might not need to be.

2. This tutorial does not account for using items. I will have to get to that next time as this is long enough already. But if you were to use up an item on the bottom of the list with the script as it is, bugs will occur. A safeguard has to be created.

3. If the X variable really was at 25, the image would more than likely be halfway into the left side of your screen. So that's probably a number that'll have to change for your own menu.

4. Though I said '50 items' as an example in the previous tutorial for how automatic scrolling would be helpful; it's still helpful here, with just 10 items.