|
geniusclown Magician
Joined: 23 Apr 2003 Posts: 358 Location: USA
|
Posted: Mon Jul 04, 2011 6:59 pm
Loops and %{i} |
I am working on a script to handle two prioritized queues for commands. The game in question (Dragonrealms) utilizes roundtimes so the point of the queue is to send each command when I'm not in roundtime, then wait for the next roundtime before sending another command. To do this, I have two list variables @queue and @loop, and a non-list variable @queueexec. A series of triggers works flawlessly with the roundtime handling subroutine to send the command in @queueexec, then %pop(queue) into @queueexec if there's something in @queue, and if @queue is empty, it will instead %pop(loop) into @queueexec and also add the command back to the end of @loop. In this way, I can have a long series of commands to repeat (such as a combat combo), and easily interject extra commands.
The two primary aliases to create the queues are "q" and "loop". "loop" creates the list @loop directly - in addition to temp=%-1 and a few checks and balances to make it play nice with the triggers, it assigns its value simply with "loop=@temp". I will wipe and chage @loop, but I won't add to it. @queue, on the other hand, I am constantly adding things to the end without removing the earlier items (like a normal queue), so it uses #FORALL (%-1) {queue=%additem(%i,@queue)}, which works flawlessly when using from my command line.
Here's where the problems begin: when I have aliases that add items to the queue. For example, one alias that gives me problems is #AL {loot} {#FORALL (%-1) {q get %i|put %i in my pack}}. There are some other handlers in there to put certain items in different containers, but the syntax and problems are the same. Often (but not always) when calling "q" from within a #LOOP or #FORALL of another alias, I start getting the item %{i} in my @queue, and it gets wierder.
If the last item in @queue is %{i}, and I add more to @queue, %{i} vanishes for a moment, everything stacks on, then %{i} appears at the end again. Wierder still, sometimes an item being put into @queue will get pulled into @loop instead - this usually occurs when I'm in combat and so the @loop is cycling every 1-6 seconds, and I add extra stuff to @queue such as skinning and looting kills as they fall, or putting a special move in middle of the cycling combo.
I believe that the problem is that both the secondary alias (e.g. "loot") and the core alias (i.e. "q") both use %i, and they seem to be mixing their use of the variable %i. Since they're separate program blocks, they don't nest with %i, %j, etc - unless I can force it to? The items that get loaded into @loop instead of @queue are probably getting grabbed by the trigger that cycles @loop.
So, my question is, how can I get two different blocks to differentiate the %i from one loop to the other? I have tried things such as setting a temporary variable to %-1 to adding #PRIORITY to the "q" assignment block. As I type this, I realize that I'm using the same temporary variable in several blocks, and that may be causing part of my problem... my biggest confusion is that %{i} is what appears in my list, but I don't use the braces anywhere in my code.
Any help would be appreciated. |
|
_________________ .geniusclown |
|
|
|
charneus Wizard
Joined: 19 Jun 2005 Posts: 1876 Location: California
|
Posted: Mon Jul 04, 2011 10:46 pm |
I'm not sure, but have you tried looking at #SECTION? It might be what you're looking for. Other than that, I don't have anything else to offer.
|
|
|
|
geniusclown Magician
Joined: 23 Apr 2003 Posts: 358 Location: USA
|
Posted: Tue Jul 05, 2011 1:53 am |
I'm not familiar with that command, and it's not in the help files. All references to it on these forums is for CMUD, which crashes my computer. I don't think it's a valid command in zMUD...
|
|
_________________ .geniusclown |
|
|
|
charneus Wizard
Joined: 19 Jun 2005 Posts: 1876 Location: California
|
Posted: Tue Jul 05, 2011 5:18 am |
Oops, didn't realise this was the zMUD forum and not the CMUD forum. Not sure what you can do about it in zMUD, then. It does seem like the two loops are interconnecting with each other and kind of messing things up for you. You might try setting a state variable to check each time the script runs, like:
#IF (!@scriptrunning) {do this}
Otherwise, not sure what else to do. |
|
|
|
geniusclown Magician
Joined: 23 Apr 2003 Posts: 358 Location: USA
|
Posted: Tue Jul 05, 2011 5:10 pm |
I've considered the suggestion to set a flag, but I think it would be very cumbersome. Instead, I'm reworking any alias or trigger that calls the "q" alias to do it within the other alias/trigger so that "q" won't be used except on the command line. After stripping the extra code I've tried writing into "q" as failsafe to stop this recurring error, it's only one line of code, so it's not such a big deal.
As I proceed with this, I'm discovering that the problem may be apart from the unnaturally nested loops. The "loot" alias is a simple one that causes the %{i} error every time, so I figured it would be a good place to start. I replaced the line of loot that calls "q" to a #FORALL command, and the %{i} stopped appearing in my lists - but I'm the first item doesn't make it from the queue into the queueexec. So, I've discovered that the problem may not be caused by an alias using #FORALL from within a #FORALL (as I thought). Instead, I think it's caused by another trigger firing multiple times that manipulates the queue list.
Let me be more specific. When I'm in roundtime while executing a looped series of commands, the most recent command from the loop is in @queueexec waiting for the roundtime to reach zero. If I then add something to @queue, I want that command to be sent next rather than what's currently in @queueexec, so I created an expression trigger I called loophole. Here's the exact code for it:
#TRIGGER "loophole" (%if(%len(@loop)&%match(@loop,@queueexec)&%numitems(@queue)&%trigger(queue2),1,0)) {
#PRIORITY {
#ECHO ---loophole changing queueexec to %item( @queue, 1)
noRt=%ends( %item( @queue, 1), " noRt")
queueexec=%replace( %pop( queue), " noRt", "")
#ECHO ---loophole just changed queueexec to @queueexec
}
} "" {nocr}
The #ECHOs have been added to help me debug, and the #PRIORITY command was an attempt to fix this problem (but didn't work). I'm not sure why this copy & paste isn't showing that this is an expression trigger, but it is. The parameter %trigger(queue2) is referring to the expression trigger that waits for the roundtime counter to reach zero (when it does, it sends @queueexec to the mud, disables itself and enables the next expression trigger, queue3, which waits for the roundtime from the command just sent by queue2 - my workaround for the inconsistencies of mulit-state expression triggers).
If you're wondering about the "noRt" that keeps appearing, if I add this to the end of a command being put in either queue, whenever the command gets loaded from the queue into queueexec, it sets a flag variable @noRt to 0 or 1, and strips it from the string. Then, when the core roundtime handler executes this command, it will also create an artificial 0.1 second roundtime so that the script will run smoothly and not have to handle commands that don't generate a roundtime differently.
The big problem is that as soon as this trigger is supposed to fire, it fires twice. With the debugging code in there, I add to @queue "stow stuff1 noRt|stow stuff2 noRt|stow stuff3 noRt" while in roundtime. I get the following output:
---loophole changing queueexec to stow stuff1 noRt
---loophole changing queueexec to stow stuff1 noRt
---loophole just changed queueexec to stow stuff1
---loophole just changed queueexec to
... @queueexec is empty and @queue is "stow stuff2 noRt|stow stuff3 noRt", and when the roundtimer reaches zero, the script continues without a problem, except that it never sends "stow stuff1" to the mud.
So, new question (which will also solve a few other unrelated problems I'm having): When an expression trigger fires, how can I prevent it from firing again before it's done executing the block from the first firing? Setting an extra state is not an option because expression triggers are very unreliable when they have multiple states. |
|
_________________ .geniusclown |
|
|
|
geniusclown Magician
Joined: 23 Apr 2003 Posts: 358 Location: USA
|
Posted: Wed Jul 06, 2011 7:01 pm |
A few more tweaks, and some of my bugs are being worked out. The %{i} thing is still driving me mad, but I did figure out a good way to get my expression triggers to not fire multiple times... The first line of the trigger's code turns itself off via #T-, followed by a #PRIORITY block (not sure if it's necessary, but better safe than sorry until the unknowns are fixed), and ending with the trigger turning itself back on via #T+.
I'm still looking for a solution to the loops issue. |
|
_________________ .geniusclown |
|
|
|
|
|
|
You cannot post new topics in this forum You cannot 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
|
|