Ok, I'm thinking of doing a major-revamp on my large script file. I am considering creating a spell queue.
There is sufficient output from the mud I play to detect when spellcasting has begun and ended, as well as spellcasting failure messages.
I would need to set up either a multidimensioned array (if possible), or 3 seperate arrays, to accomodate the following values:
SpellName, SpellTarget, SpellPriority.
So far, I would expect to create the following functions/subroutines to handle spellcasting with the queue:
- Add_Spell
- Drop_Spell (all spells on 'target')
- Pause_Casting
- Resume_Casting
- Resume_Casting_Delayed
- Clear_Queue
- Save_Last_Spell
Before casting, a flag would be checked to make sure casting is enabled (and not paused). Resume_Casting_Delayed would be called when the spell was interrupted due to movement. I wouldn't want to restart casting right away in case of further movement, so I would establish a timer to resume after... say 5 seconds.
I will probably set up variables for about 10 priority levels. (Top, HealMe, HealOther, Blessings, Defense, Hide, Offense, Misc, Bottom). I would have subroutines for each spell that sets the priority then calls the Add_Spell. I see more flexibility in creating variables for each priority level so that if I want to switch them around, I can do it in one spot (if hardcoded), or via alias (if softcoded). I may make a special subroutine/alias for casting a spell with the priory included with the alias. For example "cast 9 teleport nick".
I am confident I could write the code for everything I mentioned above. Here's where I am uncertain:
What's the best way to run through the spell queue? I see three options, and I'll list them in the order from what I guesstimate would be most efficient to least efficient:
It's important to note, I don't want to lose the order of spells with the same priority rank.
1. Sort the queue after every casting, or when a spell is added. Essentially, a for-next loop run once for each priory level. First run, it looks for any 10's, and places them at the top, then it searches for 9's, and places them after the 10's, etc... down to 1. Tough to maintain order of spells with same rank during sorting - prolly would need second array set.
2. Scan the array each casting. A For-next loop that starts at 'Nextspell' [a pointer], and runs through the array (wrapping around to the beginning when needed). When it finds a 10, it casts it, then... increases nextspell by 1. When adding a spell, I would work 'backwards' from nextspell, looking for the first blank spot. Ack, casting order would get messed up. Assuming I resolve that, if no 10 is found, it scans again, looking for a 9, etc, etc...
Actually, I don't think #2 is viable, I don't see a way, offhand, to keep spells with same priority in order. I was probably trying to brainstorm a cast-on-the-fly-while-doing-a-shellsort when I came up with this idea.
3. Make an array for each priority level. If my queue can stack 20 spells, I would need 3 * 20 * 10 data fields. That's 600 fields! This may not be a good option...
Another thing I just realized, is that Add_Spell could 'insert' the spell at a certain level in the queue, then push all the rest down.
---
This is one of those times where you are trying to finish a 'session' before going to bed. My brain is starting to turn to mush. As I wrote out my options, I think I have eliminated the latter two. I'll leave this posting here and come back to brainstorm further before I formulate my plan and begin writing the code. When I'm all done, I'll prolly post the code here as an example for others.
Magnum. (Now half-asleep)
There is sufficient output from the mud I play to detect when spellcasting has begun and ended, as well as spellcasting failure messages.
I would need to set up either a multidimensioned array (if possible), or 3 seperate arrays, to accomodate the following values:
SpellName, SpellTarget, SpellPriority.
So far, I would expect to create the following functions/subroutines to handle spellcasting with the queue:
- Add_Spell
- Drop_Spell (all spells on 'target')
- Pause_Casting
- Resume_Casting
- Resume_Casting_Delayed
- Clear_Queue
- Save_Last_Spell
Before casting, a flag would be checked to make sure casting is enabled (and not paused). Resume_Casting_Delayed would be called when the spell was interrupted due to movement. I wouldn't want to restart casting right away in case of further movement, so I would establish a timer to resume after... say 5 seconds.
I will probably set up variables for about 10 priority levels. (Top, HealMe, HealOther, Blessings, Defense, Hide, Offense, Misc, Bottom). I would have subroutines for each spell that sets the priority then calls the Add_Spell. I see more flexibility in creating variables for each priority level so that if I want to switch them around, I can do it in one spot (if hardcoded), or via alias (if softcoded). I may make a special subroutine/alias for casting a spell with the priory included with the alias. For example "cast 9 teleport nick".
I am confident I could write the code for everything I mentioned above. Here's where I am uncertain:
What's the best way to run through the spell queue? I see three options, and I'll list them in the order from what I guesstimate would be most efficient to least efficient:
It's important to note, I don't want to lose the order of spells with the same priority rank.
1. Sort the queue after every casting, or when a spell is added. Essentially, a for-next loop run once for each priory level. First run, it looks for any 10's, and places them at the top, then it searches for 9's, and places them after the 10's, etc... down to 1. Tough to maintain order of spells with same rank during sorting - prolly would need second array set.
2. Scan the array each casting. A For-next loop that starts at 'Nextspell' [a pointer], and runs through the array (wrapping around to the beginning when needed). When it finds a 10, it casts it, then... increases nextspell by 1. When adding a spell, I would work 'backwards' from nextspell, looking for the first blank spot. Ack, casting order would get messed up. Assuming I resolve that, if no 10 is found, it scans again, looking for a 9, etc, etc...
Actually, I don't think #2 is viable, I don't see a way, offhand, to keep spells with same priority in order. I was probably trying to brainstorm a cast-on-the-fly-while-doing-a-shellsort when I came up with this idea.
3. Make an array for each priority level. If my queue can stack 20 spells, I would need 3 * 20 * 10 data fields. That's 600 fields! This may not be a good option...
Another thing I just realized, is that Add_Spell could 'insert' the spell at a certain level in the queue, then push all the rest down.
---
This is one of those times where you are trying to finish a 'session' before going to bed. My brain is starting to turn to mush. As I wrote out my options, I think I have eliminated the latter two. I'll leave this posting here and come back to brainstorm further before I formulate my plan and begin writing the code. When I'm all done, I'll prolly post the code here as an example for others.
Magnum. (Now half-asleep)