I'v done alot..more then I think I should be able to considering my knowlege (or lack there of) on coding princables. Hense why I find my self in the prediciment I am in now I'm still stuck on having it so I can stack timers (via add_timer). I have timers that cant be escaped via, CANNOT_ABORT in the right area or somthing like that. But the timers will not stack IE, the timer that was running in a command a second ago would finish and execute but nothing would happen after if you typed the commands twice or more.
I'm probably not being clear, basicly what I have been trying to do is have it so I can type somthing like.
dig
dig
dig
And given I have it so dig is uninterrupptable, the following digs would stack so that when the first one is up the second one would start, and so on.
This small snippet I belive said it would allow timer stacking but I do not see how:
I'm not sure I quite understand what's going on. Could you be a little more specific? If I'm understanding correctly, the timer will happen once, but no stacking occurs beyond the first one. So you can type dig twice and get two digs, but typing three or thirty is the same as two.
As for the timer snippet, that seems to be something else entirely: time-delayed commands, not queuing up commands waiting for previous ones to finish.
No no..if I spam dig and change it so dig can be cancelled it simply ignores the other commands. I want it so dig can be spammed..and the commands get stuck in que. So if someone stupidly typed dig 15 times...they would dig...it would finish and go to the next dig...it would finish and go to the next...all 15 times.
I'm afraid I'm not understanding. Either you'll have to be more precise or you'll have to show some code and explain what exactly you're talking about.
If you type anything you stop digging, thats not what I want I want it so you can type things and not stop digging..that I can do. I do that by changing
ch->substate = SUB_NONE; to ch->substate = SUB_TIMER_CANT_ABORT; Now if you type dig multiple times while it's currently digging it just ignores you when you time dig after that till it's complete. I dont want it to ignore the commands that come after it.
So if I spam dig five times, it causes the player to be stuck digging 5 times with no way to stop till the 5 times are up. So in game it would like like this:
Player types:
dig
dig
dig
dig
dig
and from there on they will be stuck digging till all 5 digs are up.
You start digging.
-timer-
You have found nothing!
You start digging.
-timer-
You have found nothing!
Etc, Etc I hope I explained it better this time. It's as explained as I can get it.
Well, that code you posted isn't the code that starts the digging. In fact it's quite the opposite; it's the code that stops the digging if the player types something while the dig is in progress.
There are a number of ways of doing this. Some are very simple but not very powerful (e.g. they limit you to only queuing up dig.) Others are more complex but also more powerful.
I'd suggest starting simple. The first thing to ask is: do you truly understand the existing timer/substate system? The reason I've been prodding you with all these questions is to see how well you grasp that. You'll need to fully understand it before you even attempt to move on.
Where in the code do you end up at the end of a dig? That part is where you'll want to check if another dig is waiting, and if so, start the timer process again. (This is one of the simpler and much less powerful ways of handling things.)
Hrmm I understand the actual timer part just fine, bad wording on my part I guess. My problem was I thought while set to CANNOT_ABORT it pretty , much ignores the following digs.
Well, obviously it'll ignore the rest. You have to actually queue them up, it won't do it on its own. Look at this code from interp.c:
Quote:
/* check for a timer delayed command (search, dig, detrap, etc) */
if ( (timer=get_timerptr(ch, TIMER_DO_FUN)) != NULL )
{
int tempsub;
tempsub = ch->substate;
ch->substate = SUB_TIMER_DO_ABORT;
(timer->do_fun)(ch,"");
if ( char_died(ch) )
return;
if ( ch->substate != SUB_TIMER_CANT_ABORT )
{
ch->substate = tempsub;
extract_timer( ch, timer );
}
else
{
ch->substate = tempsub;
return;
}
}
So somewhere in all of this, you're going to have to queue up commands. What you're doing is not letting the dig abort, fine, but where is it going to queue the next commands? When the code realizes it can't abort, it returns: look at the code I posted.
Well, can you describe to me how you think these timers and substates work? Be as precise as possible - the more I understand about your perception, the more I can help you.
To be honest I understand how they work as in how to use them, and little past that, it appears it simply adds a timer to the charecter via linked list.
What happens, then, when you're waiting on the timer, and the player types dig again? Where does the code go? Describe the sequence of function calls that a) starts the timer, b) interrupts the timer, c) finishes executing the timer normally. You'll need to look at that and understand it to figure out how to start stacking up timers.
Thats where I'm lost I can track whats happening through adding the timer within the command, but past that I'm lost. I imagin it has somthing to do with interp.c past that, thats why I'm here asking for help.
Why not use wait states? I mean, you are really only trying to delay the character, so why not just lag his output a little? I'm sure the fletch command on Avatar works that way.
And you are rewarded with a nice non-cancelable (that a word?) stack of fletch commands.
Also, I believe the next one will not be analyzed until out of the wait state, so people in the room wont get spammed all at once either.
Best thing about this is your avoid all of the timer mumbo-jumbo that is really irrelevant for this type of thing. If you don't want it to be able to be canceled, don't use a timer. Use a waite state instead.
For the unknowing, wait states can be set via WAIT_STATE(x), where x is the number you specify to wait (in ticks? I'm not sure)
Hoped that helpped ya in some way. Maybe you can still avoid all of the timers :)
The problem with wait-states is that they're truly not cancellable and aren't a good way of implementing command queues - which normally can be 'flushed'. That being said if the idea here is to make something truly not cancellable, it could be done with wait-states although the timer approach is more general.
Thanks for the suggestion about wait states, but stacking timers is defiently what I'm looking for. I wish I could just use wait states and be done with it. Mind guiding me a bit Ksilyan as you can see I'm lost on the inner workings of add_timer.
Even if I prefer the timer solution, what is wrong with wait states? If your intention is to make it completely non-cancellable, what do you get with timers that you don't get with wait states?
The only marked advantage that I can see to used non-cancellable queueing timers rather than wait_state is that you could allow a special command or character to wipe the queue, since the command buffer is actually interpretted instead of left sitting on the descriptor data.
Oh no no, dont get me wrong I'm not sure if I stated but I believe I did, I stated it in the begining I was just using dig as an example. The whole point of this thread was stackable timers, and I figured in order to make them stackable you had to make them no cancelable via typing anything....wich is the only way because if you left it to where you can cancel it by typing anything it surely wouldnt be stackable.
You have to make them not cancelable but that's just the beginning. You also have to make one start when the previous one finishes, meaning you'll have to keep a record of them somewhere, with e.g. a queue. I think you should perfectly understand how a single timer works, though, before trying to tackle stacking them.
All of this being said, the wait-state approach would probably work for every skill as well, albeit less elegantly.
Well, ok, but still, what's wrong with using wait states? Many commands have a 'beats' property which is how long to "lag out" the character. You could set that for the skills you want delayed/stacked and your problem should be solved.
Yes, wait states could provide what you are looking for quite easily, without all of the timer stuff. It is a little less dynamic (if you planned to have a command to cancel them), but overall it should work well.
IF you look through the code I think you will find that wait states are used quite a bit for lots of things (espeically if you want to be mean to your players...) :P