 |
Castle Paradox
|
View previous topic :: View next topic |
Author |
Message |
Mr B
Joined: 20 Mar 2003 Posts: 382
|
Posted: Sun Jul 16, 2006 5:58 pm Post subject: How Often Are Tags Updated for Plotscript Viewing? |
|
|
I am having some difficulty with a loop in my plotscripts.
I have an instead-of-battle script that triggers a random battle. After the battle is over, an other script is called that checks to see if the character has obtained any of a range of items from that battle. If so, it exchanges them for others.
This is a (shortened) version of that script:
Code: |
while(check tag(16)) do # this tag is true when a level item is in inventory
(
if(inventory(1)) then # item 1 = lvl.1 item
(
delete item(1)
get item(random(20,30))
)
if(inventory(2)) then # item 2 = lvl.2 item
(
delete item(2)
get item(random(40,50))
)
...
wait(1)
)
|
All of the "level items" (items 1-10) set tag 16 to be true if they are in the inventory.
When this script is run without the "wait(1)" statement, the screen turns black and game.exe freezes up.
When I inserted the "wait(1)" command, the script seemed to take an inordinate amount of time to terminate, though I was granted control of the game again.
Are the tags associated with items checked whenever an item is added or removed from the inventory, or is this done every few clock cycles? Checking every once in a while is the only way that I can account for the script freezing up like that without the wait command, as the tag would never be set off.
What exactly is going on here, and how can I compensate for it?
Thanks,
-B
[/code] |
|
Back to top |
|
 |
Mike Caron Technomancer

Joined: 26 Jul 2003 Posts: 889 Location: Why do you keep asking?
|
Posted: Sun Jul 16, 2006 7:31 pm Post subject: |
|
|
Theoretically, tags should be instant. However, depending on how many of a given item you have in your inventory, it may take a long time to delete them one by one.
I'd write this script like this:
Code: | script, level items, begin
variable(count)
#item one
count:= inventory(1) #get the number of the first item
if(count) then, begin #is there a non-zero count of this item?
delete item(1, count) #out with the old...
get item(random(20,30),count) #...in with the new
end
#item two
count:= inventory(2) #get the number of the first item
if(count) then, begin #is there a non-zero count of this item?
delete item(2, count) #out with the old...
get item(random(40,50),count) #...in with the new
end
end |
This way, there's no tags required, no infinite loops either. And, it runs in O(log n) instead of O(n^2) time. Why n^2 instead of n? All of the item commands must check every single item slot since each slot can hold any item, and more than one slot can hold the same item. So, it does 255 reads regardless if there are any items or not.
Thus, if you loop through each individual item one-by-one, you have to do 255 * x reads. If you were holding 99 of a given item, that's 25 245 reads to go through those items! And, of course, 99 ticks which ~= 7 seconds. _________________ I stand corrected. No rivers ran blood today. At least, none that were caused by us.
Final Fantasy Q
OHR Developer BLOG
Official OHRRPGCE Wiki and FAQ |
|
Back to top |
|
 |
Mr B
Joined: 20 Mar 2003 Posts: 382
|
Posted: Mon Jul 17, 2006 10:34 am Post subject: |
|
|
Yeah, the efficiency was horrible.
The only problem I see with your method is that, if I had, say, five of the level items from a battle, I would get five of the same items from the random range. I could simply write a new function with a for loop.
As it is, I "fixed" the problem with a series of "while(inventory(x))" loops. It works, though it is less than elegant.
Hmm...does "delete item(x)" return a different value depending on whether there was actually an item to be deleted? If so, I could do:
Code: | while(delete item(x)) do (get item(random(r1, r2)) |
Thanks for your help -- I think I'll try a variation on your method. |
|
Back to top |
|
 |
Mike Caron Technomancer

Joined: 26 Jul 2003 Posts: 889 Location: Why do you keep asking?
|
Posted: Mon Jul 17, 2006 11:40 am Post subject: |
|
|
I don't think so. Besides, delete item still has to scan all the slots each time, so it's still O(N^2). Ok, here's a revised version:
Code: | script, level items, begin
variable(count)
#item one
count:= inventory(1) #get the number of the first item
if(count) then, begin #is there a non-zero count of this item?
delete item(1, count) #out with the old...
while(count) do (get item(random(20,30),count), count-=1) #...in with the new
end
#item two
count:= inventory(2) #get the number of the first item
if(count) then, begin #is there a non-zero count of this item?
delete item(2, count) #out with the old...
while(count) do (get item(random(40,50),count), count-=1) #...in with the new
end
end |
get item(), while still needing to scan many slots, is not as bad as the other commands, so you can still use it in a loop. In the worst case scenario, all the slots are full, and so it scans all 255 slots uselessly. _________________ I stand corrected. No rivers ran blood today. At least, none that were caused by us.
Final Fantasy Q
OHR Developer BLOG
Official OHRRPGCE Wiki and FAQ |
|
Back to top |
|
 |
Bob the Hamster OHRRPGCE Developer

Joined: 22 Feb 2003 Posts: 2526 Location: Hamster Republic (Southern California Enclave)
|
Posted: Mon Jul 17, 2006 12:00 pm Post subject: Re: How Often Are Tags Updated for Plotscript Viewing? |
|
|
Mr B wrote: |
All of the "level items" (items 1-10) set tag 16 to be true if they are in the inventory.
|
Here is your problem. You cannot use the same item for more than one item. Only the last item will actually matter. So when you wrote while(check tag(16)) do it was actually just checking for item 10, and not for any of the other items.
Use this workaround:
Code: |
define script(autonumber, check level items, none)
script, check level items, begin
return(false)
variable(i)
for(i,1,10), do, begin
if(inventory(i)) return(true)
end
end
|
Then in your other script you can say:
Code: |
while(check level items) do
(
|
We should really fix the multiple-items-using-the-same-tag behavior. a logical OR is what people actually expect.... |
|
Back to top |
|
 |
Mr B
Joined: 20 Mar 2003 Posts: 382
|
Posted: Wed Jul 19, 2006 9:01 am Post subject: |
|
|
Okay, so I can't use the same tag for more than one item -- that explains what was happening very nicely. *laugh* I've managed a work-around, though it's not very elegant! I think I'll use your recommendation. |
|
Back to top |
|
 |
Mike Caron Technomancer

Joined: 26 Jul 2003 Posts: 889 Location: Why do you keep asking?
|
|
Back to top |
|
 |
Mr B
Joined: 20 Mar 2003 Posts: 382
|
Posted: Thu Jul 20, 2006 12:10 pm Post subject: |
|
|
Yours is indeed faster, but James' satisfies my thirst for many autonumbered subscripts.
Also, yours gives multiples of the same item, instead of several different items per level. I expect that I could easily work around that, though! |
|
Back to top |
|
 |
Mike Caron Technomancer

Joined: 26 Jul 2003 Posts: 889 Location: Why do you keep asking?
|
|
Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|