Fake Arrays
Moderators: marionline, SDHawk
Fake Arrays
I'm just checking that the OHR still does not in fact support arrays. I'm building a fake array now and wondering if that's been added since the last time I've built one (it was a long time ago). If not, is there an estimate on when arrays will be supported, if ever?
EDIT: I knew I'd have follow-up questions on this. Can global variables only store numerical data or is it possible to store slice lookup codes? If not, is there a way to attach a global variable to a lookup code in some way?
EDIT: I knew I'd have follow-up questions on this. Can global variables only store numerical data or is it possible to store slice lookup codes? If not, is there a way to attach a global variable to a lookup code in some way?
Last edited by kylekrack on Tue Aug 11, 2015 10:49 am, edited 1 time in total.
My pronouns are they/them
Ps. I love my wife
Ps. I love my wife
- Bob the Hamster
- Lord of the Slimes
- Posts: 7660
- Joined: Tue Oct 16, 2007 2:34 pm
- Location: Hamster Republic (Ontario Enclave)
- Contact:
Ok, that's great, but it means I don't know what I'm doing wrong. I have a slice collection which displays a row of 10 "item" sprites across the top. I am attempting to use an array to cycle through tags attached to each item and setting the sprite visible if the item is "owned." For example, if tag 3 is on, then the player has item 1, and the sprite for item1 should be set to visible.
I didn't know how to use a for loop to append lookup codes to global variables, so I repeated the subscript manually to append each item.
I didn't know how to use a for loop to append lookup codes to global variables, so I repeated the subscript manually to append each item.
Code: Select all
define constant(100, array:items) # creating an array for the item icons onscreen
script, append items, begin
variable(length)
length := 0
subscript, append this, sl, begin
write global(array:items + length, lookup slice(sl))
length += 1
end
append this(sli:item0)
append this(sli:item1)
append this(sli:item2)
append this(sli:item3)
append this(sli:item4)
append this(sli:item5)
append this(sli:item6)
append this(sli:item7)
append this(sli:item8)
append this(sli:item9)
end
global variable(0,inv)
script, draw inventory, begin
inv := load slice collection(1)
variable(i) #this reads the items array and checks the tags to make the item "had"
for(i,0,9) do(
if(check tag(i + 2)) then(
set slice visible(read global(array:items + i),true)
)
else(
set slice visible(read global(array:items + i),false)
)
)
end
My pronouns are they/them
Ps. I love my wife
Ps. I love my wife
- Bob the Hamster
- Lord of the Slimes
- Posts: 7660
- Joined: Tue Oct 16, 2007 2:34 pm
- Location: Hamster Republic (Ontario Enclave)
- Contact:
Some day we will have real arrays, but for now, there are two different ways that I like to do fake arrays.
The first method is probably easiest, but it requires that you set an upper limit on the size of your array. For example, suppose you are confident that you will never need more than 100 elements in the array.
This is pretty simple, but also I think it is not what you want, since you are talking about appending items. Instead, you want a fake array where you don't need to know how many items it will have in advance. For this, you can use the children of a hidden slice.
This method is a little more complicated, and uses a little more memory, but it is probably much better for your purposes.
It can be used for temporary arrays stored in local variables in just one script (don't forget to "free slice" at the end!) or it can be used for global arrays that are set up in your "new game" script (don't forget to turn on the option to save slice handles in savegames, and don't forget to think about what happens if you change your mind about how the array should be organized and then you load an old .rsav file)
The first method is probably easiest, but it requires that you set an upper limit on the size of your array. For example, suppose you are confident that you will never need more than 100 elements in the array.
Code: Select all
global variable(1000, myarray)
# Globals 1000 to 1999 are reserved for the array
script, read my array, index, begin
exit returning(read global(@myarray + index))
end
script, write my array, index, value, begin
write global(@my array + index, value)
end
Code: Select all
script, create fake array, begin
# This returns a slice handle that you can use as an empty fake array.
# You can store the handle in a global or local variable, and when you
# are done with it you can delete it with "free slice"
variable(a)
a := create container(0, 0)
set slice visible(a, false)
end
script, append to fake array, a, val, begin
# Append a new number to the end of an array
variable(e)
e := create container(0, 0)
set slice extra(e, 0, val)
set parent(e, a)
end
script, read fake array, a, index, begin
# Return the number at the given index of the array, if it exists.
variable(e)
e := slice child(a, index)
if(e) then(
exit returning(get slice extra(e, 0))
)else(
script error(string sprintf(0, $1="Array index %d out of bounds", index))
)
end
script, write fake array, a, index, value, begin
# Write a new number into the given index of an array, if it exists.
variable(e)
e := slice child(a, index)
if(e) then(
set slice extra(e, 0, value)
)else(
script error(string sprintf(0, $1="Array index %d out of bounds", index))
)
end
It can be used for temporary arrays stored in local variables in just one script (don't forget to "free slice" at the end!) or it can be used for global arrays that are set up in your "new game" script (don't forget to turn on the option to save slice handles in savegames, and don't forget to think about what happens if you change your mind about how the array should be organized and then you load an old .rsav file)
- Bob the Hamster
- Lord of the Slimes
- Posts: 7660
- Joined: Tue Oct 16, 2007 2:34 pm
- Location: Hamster Republic (Ontario Enclave)
- Contact:
I wrote a wiki article about fake arrays last time someone asked.
http://rpg.hamsterrepublic.com/ohrrpgce ... ake_arrays
Arrays of global variables are easier to inspect, using the script debugger (press V a few times until it shows global variables), although you can't see where the array ends.
http://rpg.hamsterrepublic.com/ohrrpgce ... ake_arrays
Arrays of global variables are easier to inspect, using the script debugger (press V a few times until it shows global variables), although you can't see where the array ends.
I used this article for help when I started making it, actually! Thank you for creating it, I found it very useful. The script debugger worked fine, I started at 100 instead of 1000, but I was able to infer/had an idea of where it ended, so that wasn't an issue.TMC wrote:I wrote a wiki article about fake arrays last time someone asked.
http://rpg.hamsterrepublic.com/ohrrpgce ... ake_arrays
Arrays of global variables are easier to inspect, using the script debugger (press V a few times until it shows global variables), although you can't see where the array ends.
My pronouns are they/them
Ps. I love my wife
Ps. I love my wife
If you do use global variables for a variable length array, it's convenient to store the length in a global immediately before the array so that you can see it in the script debugger:
After all, you probably want to have the length of the array actually stored somewhere, and update the length as you append to it:
Also, neat, someone actually using 'subscript' :)
Code: Select all
define constant(99, array:items length)
define constant(100, array:items)
Code: Select all
# array is the global id of the start of the array, and the length is stored in the global immediately before it.
script, append, array, item, begin
write global(array + read global(array -- 1), item) #array[length] := item
write global(array -- 1, read global(array -- 1) + 1) # length += 1
end
...
append(array:items, lookup slice(sli:item0))
append(array:items, lookup slice(sli:item1))
append(array:items, lookup slice(sli:item2))
append(array:items, lookup slice(sli:item3))
append(array:items, lookup slice(sli:item4))
append(array:items, lookup slice(sli:item5))
append(array:items, lookup slice(sli:item6))
append(array:items, lookup slice(sli:item7))
append(array:items, lookup slice(sli:item8))
append(array:items, lookup slice(sli:item9))
Last edited by TMC on Thu Aug 13, 2015 8:57 am, edited 1 time in total.
I believe I stubbed my toe on my desk when I discovered it. I got a little bit too excited. It's super useful though, especially for expanding the usability of local variables in many circumstances.TMC wrote:Also, neat, someone actually using 'subscript'
My pronouns are they/them
Ps. I love my wife
Ps. I love my wife
- Bob the Hamster
- Lord of the Slimes
- Posts: 7660
- Joined: Tue Oct 16, 2007 2:34 pm
- Location: Hamster Republic (Ontario Enclave)
- Contact:
That includes the ability to modify the local variables of the parent script (which you can't do with a separate script), so you can deduplicate repeated code by moving it into a subscript.
Last edited by TMC on Fri Aug 14, 2015 6:21 am, edited 1 time in total.