Unable To Cast Spells At This Time. Q & Solve?

Eorzea Time
 
 
 
言語: JP EN FR DE
日本語版のFFXIVPRO利用したい場合は、上記の"JP"を設定して、又はjp.ffxivpro.comを直接に利用してもいいです
users online
フォーラム » FFXI » Jobs » Scholar » Unable to cast spells at this time. Q & Solve?
Unable to cast spells at this time. Q & Solve?
Offline
Posts: 182
By Sammeh 2017-10-19 22:14:02  
So I'm hoping for some feedback.

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
[+]
 Ragnarok.Kenshi
Offline
サーバ: Ragnarok
Game: FFXI
user: KenshiDRK
Posts: 123
By Ragnarok.Kenshi 2017-10-20 02:51:40  
Maybe you should have a look at this https://www.bg-wiki.com/bg/Forced_Delay, you also could check for the action packet that finish spells, abilities and WS or just in the aftercast function if you doing on gearswap, and then add those delays.
 Fenrir.Caiir
VIP
Offline
サーバ: Fenrir
Game: FFXI
user: Minjo
Posts: 199
By Fenrir.Caiir 2017-10-20 02:53:58  
I use 2.7 myself. The delay is almost definitely hardcoded around ~2.5, but given that outgoing chunks are pushed out in a UDP packet at intervals, if that outgoing action attempt hits the server before 2.5, it will give that response and then you can't try again for another half second.

Edit the fourth:

I did a bit of testing but I'm going to just leave the matter be until I had some sleep because I may need more precise timing / actually hook 'send' to see when the whole packet is being sent in order to figure out what the actual delay is. That said, if you wait for 6 outgoing 0x15 chunks from the cast completion (2.5-2.99 seconds, usually around 2.6), your spell will work 100% of the time. If you go on the 5th, it's subject to hitting the "Unable..", but may not, which is likely just a matter of when the packet is actually being sent and processed. I don't think you'll ever need to optimize it further than that (and I'm not sure you can given that the packets are sent in intervals)... but when I look into it I can update you.
[+]
Offline
Posts: 182
By Sammeh 2017-10-20 06:23:31  
Are you suggesting effectively setting a variable in aftercast such as AftercastPacketWatch to 0, then a monitor for outbound 0x015 that increments AftercastPacketWatch and on pretarget basically saying while AftercastPacketWatch < 6; sleep .1 ? (If I recall correctly gearswap removes coroutine.sleep ? Any better way? just wait .1; and recast 6 x successive times?)

-Sam
 Leviathan.Comeatmebro
Offline
サーバ: Leviathan
Game: FFXI
user: Rairin
Posts: 6052
By Leviathan.Comeatmebro 2017-10-20 09:26:28  
design your flow better and that won't be an issue

i wouldn't really think it's any more reliable to count outgoing packets though, unless you're counting from spell start and figuring casttime

it's still important to know and consider that your data is only sent out at the time 0x15s are naturally generated(every 400-450ms)

you don't know if the spell finished 50ms or 350ms before the first outgoing packet following the finish.. just wait 2.3s and inject on the following two outgoing 0x15 packets and you're guaranteed fastest possible outcome
 Fenrir.Caiir
VIP
Offline
サーバ: Fenrir
Game: FFXI
user: Minjo
Posts: 199
By Fenrir.Caiir 2017-10-20 09:41:04  
I was more saying that it may be interesting to actually figure out the delay and you can use the outgoing standard client packet to do so, but it's not even possible to optimize it to more than half a second anyway.

And ye, it's not more reliable than just using a delay, it was just easier for me to construct a test that way since I wanted the timers on the 0x15 anyway.

And you could figure out that delay, which is what I was doing (update a ts every outgoing 0x15, when incoming 0x28 meets conditions, initial delay = (current clock - that ts)) when originally checking things out but I didn't realize I was injecting on the same outgoing UDP I was watching, and I was tired so results were confusing the ***out of me.
 Fenrir.Caiir
VIP
Offline
サーバ: Fenrir
Game: FFXI
user: Minjo
Posts: 199
By Fenrir.Caiir 2017-10-20 10:36:50  
So taking into account that me injecting a packet on an outgoing chunk event in windower may place it on the same or the following UDP packet (either can happen, but it's usually on the same unless you're doing nothing else including no gear swaps etc.), I'm willing to bet that the occasional successes injecting on the 5th actually have it being sent out on the sixth, as I've seen successes on lower delays than I've seen failures.

I suppose I can just look at the packet sequence, but you're honestly probably perfectly fine just using the delay you are. It can't really get much better.