Forever I've been plagued as trying to get multiple magic bursts, or casting successive magic spells and getting the most aggravating 7 words... "Unable to cast spells at this time."
This gets harder to gauge the more FastCast you get, and really its quite difficult to time - only by staring at certain animations and hoping to time it just right.
I took to some math and timed out abilities then inserted some waits and sends to see what I could come up with.
My *hypothesis* is that there is a hard coded server side delay of roughly 2.2-2.5 seconds then tack on latency/network delay for sending your next command. I've tested this theory several times based on measuring the OS clock (os.clock() in LUA) and adding in some delays in aftercast to test. So a simple part of aftercast doing a send_command('wait 2.5; input /ma Cure IV <me>') then Curing myself (with something other than Cure IV to trigger the recast. I've successfully done it in ranges of 2.4ish to 2.6ish.. however I've not had a single issue at 2.7 seconds delay.
Anyway - on to solve (at least based on my information I have right now).
1) Record the os.clock() to a variable inside of aftercast
2) On pretarget of next spell, determine am I < 2.7 seconds from the variable created in #1
3) If I am more than 2.7 - Cast now. If Less than - pause the spell casting for the delta difference of 2.7 - aftercast time - current time.
This seems to work flawlessly, but I wish there was a way to solidify that 2.7 seconds to something measurable based on a) knowing a constant delay and b) assuming the network delay (maybe measuring latency?)
Anyway a bit of the solve in code (note these are snipits to pull this off specifically, they're not fully inclusive of everything I do.)
In user_setup:
Code
function user_setup() waittime = 2.6 end
In pretarget: (The checkblocking(spell) is a function I have to check if there are reasons I can't cast such as terror, silence, etc and rejects the spell in those scenarios).
Code
function job_pretarget(spell) checkblocking(spell) if spell.action_type == 'Magic' then if aftercast_start and os.clock() - aftercast_start < waittime then windower.add_to_chat(8,"Precast too early! Adding Delay:"..waittime - (os.clock() - aftercast_start)) cast_delay(waittime - (os.clock() - aftercast_start)) end end end
And finally in Aftercast(snipit):
Code
function job_aftercast(spell) aftercast_start = os.clock() if spell.action_type ~= 'Magic' then aftercast_start = nil end end