Thanks again
Thanks again
is it possible to change a called functions name based on some rule
i.e.
currently i have it setup like this
but what i want to do is somthing like thisCode:function precast(spell) whitemage_precast(spell) -- For WHM Sub Job redmage_precast(spell) -- For RDM Sub Job paladin_precast(spell) -- For PLD Sub Job beastmaster_precast(spell) -- For BST Sub Job dancer_precast(spell) -- For DNC Sub Job end
Code:function precast(spell) [player.sub_job]_precast(spell) -- For Sub Job end
Issue with the continuously looping auto-Pianissimo should be fixed now, on dev, as part of the include library update. Will get to live whenever the next merge happens.
Note that you may need to update the brd job file as well, as a lot of stuff from the job files has been moved into the libraries, so if you don't keep it updated you may end up keeping the broken code.
Yes.
_G is the global reference table to the user environment space (from within that space), which means that all vars and functions descend from that. As such, it's possible to use standard string concatenation on table elements within it in order to find a reference to a specific function.Code:function precast(spell) if _G[player.sub_job..'_precast'] then _G[player.sub_job..'_precast'](spell) else -- default code if no defined subjob function end end function WHM_precast(spell) end function RDM_precast(spell) end function PLD_precast(spell) end function DNC_precast(spell) end etc.
If you want another example, check the handle_actions() function in Mote-Include.
ok one more question
how do i stop just a sub-function not the main function
i.e.
what i want to do is stop the sub function but not the main functionCode:function precast(spell) if _G[player.sub_job..'_precast'] then _G[player.sub_job..'_precast'](spell) end if spell.type == "CorsairRoll" then if buffactive[spell.english] then cancel_spell() return end end end function WAR_precast(spell) return end end function MNK_precast(spell) return end end
also whats that way to stop both the sub function and the main function
im thinking
return --stops both the main and sub function
return end --stops just the sub function
edit
ok im wrong
return --stops the function it is in
what i want to be able to do is stop the precast function from a sub function
here is an example
with the above code i get (in chat)Code:function precast (spell) test() add_to_chat(7,"test") end function test() add_to_chat(7,"test1") return end
test1
test
but what i want is
test1
I am horribly confused, because your question doesn't make any sense. Or only makes sense when asked by someone with no understanding of programming whatsoever.
'return end', as you have them in the subjob versions of the precast function, is invalid syntax. Any time you start certain types of code (eg: function, if, for), there must be a matching end. If you do not have a start point, then the end will break the code.
For example, breaking this down point by point:
function: starts the function definitionCode:function WAR_precast(spell) return end end
WAR_precast: gives the function a name
(spell): gives a parameter list to the function
return: tells the function to stop executing, and return nil (since you didn't specify anything else) to the calling point
end: ends the function
end: ***BUG*** the function has already ended, so this is invalid code
The 'return' instruction tells lua to stop executing the current function, and return to the point in the code that the function was originally called. A simplified model:
Code:function precast(spell) WAR_precast(spell) -- *1* << when WAR_precast is done, it returns here; if WAR_precast returned a value, you can assign it to a variable here print('WAR_precast is done') print('everything after that continues normally') print("I'm not sure how you could not understand this") print('if you want to stop this function, put in another return') return print('this will never print out') end function WAR_precast(spell) print('started WAR_precast') return -- << this ends the function; nothing else is run; it returns to point *1* above print('this will never print out') end
sorry about that i was editing my post while you posted
so here is the new part
ok im wrong
return --stops the function it is in
what i want to be able to do is stop the precast function from a sub function
here is an example
with the above code i get (in chat)Code:function precast (spell) test() add_to_chat(7,"test") end function test() add_to_chat(7,"test1") return end
test1
test
but what i want is
test1
For that, you have two scenarios:
1) If test() is run, then everything is complete and you never want to run anything following that. This would be the case where you have WAR_precast, WHM_precast, etc, and if they get run then you know that everything has been handled. However if they were not run (because they didn't exist) then you need to continue with whatever the default implementation is. So:
Code:function precast(spell) if _G[player.sub_job..'_precast'] then _G[player.sub_job..'_precast'](spell) else -- default code if no defined subjob function end end function WHM_precast(spell) -- whm stuff end function RDM_precast(spell) -- rdm stuff end function PLD_precast(spell) -- pld stuff end
2) You have some default handling in the main precast() function that you may or may not want to allow to run, depending on info that only the subjob function knows about. In this case, you need to be able to return some signal value to the calling function to let it know what the subjob function determined.
This is what I commonly use the eventArgs parameter for.
In the above example, WHM is the only subjob function that sets eventArgs.handled to true. If the subjob is RDM, PLD, or anything else (which doesn't have a defined function to run), then eventArgs.handled remains false, and the precast function doesn't return, but instead continues on to the "do more stuff" section. WHM, however, is stopped, and none of the remaining code is run.Code:function precast(spell) local eventArgs = {handled = false} if _G[player.sub_job..'_precast'] then _G[player.sub_job..'_precast'](spell, eventArgs) end if eventArgs.handled then return end -- do more stuff end function WHM_precast(spell, eventArgs) -- whm stuff eventArgs.handled = true end function RDM_precast(spell, eventArgs) -- rdm stuff end function PLD_precast(spell, eventArgs) -- pld stuff end
ok that was what i was trying to avoid but i did come up with this
this question is actually for this code http://pastebin.com/RgKyV47yCode:function precast (spell) --main function if test(spell) then cancel_spell() return end add_to_chat(7,"test") end function test(spell) --sub function if spell then add_to_chat(7,"test1") return true end add_to_chat(7,"test2") return false end
i was hoping there was a function that would do it for me
Ah, yes, a third scenario. However this one depends on the purpose of the test() function (and given what you'd described thus far, I did not expect it to fall into the third scenario's parameters, so didn't give it any consideration).
If the purpose of the test function is explicitly and solely to return that true/false value that you use to determine whether to cancel a spell, then yes, you can go with that pattern.
However if the test function is primarily for another purpose, but only returns a value indicating whether to cancel the spell as a side effect, then it should not be done in that way.
Code:function precast(spell) -- this pattern is fine if check_to_interrupt(spell) then cancel_spell() return end -- this pattern is bad if whm_handling(spell) then cancel_spell() return end end function check_to_interrupt(spell) if spell.english == 'spell we want to cancel' then return true else return false end end function whm_handling(spell) -- do whm stuff -- do more whm stuff if spell.english == 'spell we want to cancel' then return true else return false end end
this is what i wanted it for
but i was hoping for a command that would do it with it not being in an ifCode:function precast(spell) if spell_stopper(spell) then cancel_spell() return end end function spell_stopper(spell) if spell.english ~= 'Ranged' and spell.type ~= 'WeaponSkill' then if spell.action_type == 'Ability' then if spell and (windower.ffxi.get_ability_recasts()[spell.recast_id] > 0) then return true end elseif spell.action_type == 'Magic' then if spell and (windower.ffxi.get_spell_recasts()[spell.recast_id] > 0)then return true elseif spell then if spell.tp_cost > player.tp then return true end if spell.mp_cost > player.mp and not (buffactive['Manawell'] or buffactive['Manafont']) then return true end end end end if buffactive['sleep'] then return true end if spell.type == "Trust" and party.count > 1 then if player.in_combat then return true end if partynames.party1:contains(string.gsub(spell.english, "%s+", "")) then return true end end if windower.wc_match(spell.english, 'Warp*|Teleport*|Recall*|Retrace|Escape') then return true end if midaction() or pet_midaction() then return true end if player.tp < 1000 and spell.type == 'WeaponSkill' then return true end return false end
i.e.
return --stops current function
kill_function --stops gearswap from continuing or something like that
these are all the ones i thought of before i even asked this question thay all do there job
Spoiler: show
I have recently returned to the game after taking an 8-month break, so I'm converting my spellcasts to Gearswap. Gearswap is really, really awsome -- so easy to troubleshoot problems compared to spellcast, and with the limited testing I've done so far, it seems to have much more precise timing! Thanks very much, Byrthnoth!!
However, I did notice a bug in the release version. It seems that in order to use the windower.ffxi.get_spell_recasts() function, spell.id must be used instead of the documented spell.recast_id. Recast_id seems to have the buffarray index? I didn't check the testing version.
Also, I can start casting with about 80 time-units remaining. Seems like quite a lot if they are 60ths of a second. Maybe the number doesnt account for any network delays, but I have a very good connection from the east coast USA...
actualy the correct way is
for abilitys (jobabilitys)
windower.ffxi.get_ability_recasts()[spell.recast_id]
for spells(magic,songs,ninjutsu)
windower.ffxi.get_spell_recasts()[spell.recast_id]
thay are both off by about .01 seconds tho i have tried to compensate but i cant
you need to check your connection with japan not east coast USA
i have about a 10 ms delay with japan
Back with more questions concerning a Geo.lua. I couldn't get the sub job specific bits asked and answered earlier, but for the most part, it works between the two now.
Today was the first time I got to use it in any content as /Rdm and I noticed that none of the midcast sets for my enfeebles were working. The original .lua I pulled off of FFXIAH, and it's not the first thing I've found to not work. Trying to solve it myself, I looked at Mote's Sch .lua and saw enfeebles defined as MndEnfeebles and IntEnfeebles, just like they were here. When I checked the mapping file, I didn't see any enfeebles listed though, just the ElementalEnfeebles. I added them all in at the bottom, reloaded, and still no luck.
I'm also having issues with getting Bagua Pants +1 to swap in during the midcast of Indi- spells. The original .lua had..
sets.midcast['Indi-*'] =
Which never worked for me. I've tried a few different strings that I've seen in other luas, but none have worked yet. Any ideas?
Upon reading the "Gearswap for Dummies" thread I saw something regarding copy/pasting your gear sets into newly released .luas, and figured I'd try that with a fresh copy of Mote's Geo.lua. I got a few errors from the custom sets that were blank, but after deleting those, it ran, but the above issues still happen. The sets.idle.Pet set (for Loupan -Dt) doesn't seem to be working for me either.
The original modded .lua.
Gear copied into Motes Geo.lua
Any help would be appreciated, specially with the enfeebling issues. Still really new to gearswap and not all that great at coding. :3
Make sure you're referring to the correct resources. The XML resources (windower/plugins/resources) are largely deprecated, and what used to be spell.id in the XML resources is spell.recast_id in the lua resources (windower/res).Originally Posted by Heatsink
MndEnfeebles and IntEnfeebles are custom spell maps. They won't be in Mote-Mappings. Check the job_get_spell_map() function sch or whm. Remove any changes you made to Mote-Mappings.
That's a completely nonsensical set name. It will never work. Would recommend a simple:
sets.midcast.Indi = {}
or
sets.midcast.Geomancy.Indi = {}
and add Indi as a custom spell map. Along with the enfeebles, you'd end up with something like:
Code:function job_get_spell_map(spell, default_spell_map) if spell.action_type == 'Magic' then if spell.skill == 'Enfeebling Magic' then if spell.type == 'WhiteMagic' then return 'MndEnfeebles' else return 'IntEnfeebles' end elseif spell.skill == 'Geomancy' then if spell.english:startswith('Indi') then return 'Indi' end end end end
That was most likely a recommendation for using sidecar files. You end up with files like:
GearSwap/data/Malithar/geo.lua -- downloaded version of my file
GearSwap/data/Malithar/gear/geo.lua -- sidecar version.
The sidecar version only needs a copy of the user_setup(), init_gear_sets(), and select_default_macro_book() functions (and user_unload(), if appropriate). Place all your customizations (gear, macro book, mode definitions, etc) in the sidecar file, while leaving the original to maintain the rules to be used. Update the original as new versions are released in the repository.
If you want to modify rule functions, you can create those in the sidecar file as well. I'll be adding the above rules to the repository version for convenience, though.
Will need more detail on that.
Everything listed above worked great, thanks a ton Motenten! ^^/ Seems I'll need to learn a lot about custom spell maps, pretty cool that you can define out your own rules like that. Makes sense once I looked at it more, thanks again!
As for the pet gear, I'm referring to the
When a luopans present, I'm needing my idle set to be Idris, Geo. Mitaines +1, and Dunna + other idle gear, however it doesn't switch to the defined set in the aftercast. I've tried defining each piece of the set as well as a set_combine, but it doesn't seem to notice that there's a pet present at all.Code:-- .Pet sets are for when Luopan is present. sets.idle.Pet =
i finally have my nin tool map done
Spoiler: show
Remember my issue where, randomly, when using my Nightingale/Troubadour macro, some times Gearswap would not correctly swap into Bihu Justaucorps +1 to augment the duration of Troubadour?
Thanks to Byrth and other people we finally nailed down the issue a bit, full read HERE.
tl;dr there are likely multiple things causing this random issue (one possibly being in the Hook) but a common thing probably is the intersection of aftercast packet from the first JA (Nightingale) and the Precast packet from the second JA (Troubadour)
We'll proceed fixing this issue in several ways because it might affect other people and other Luas as well, it's just that nobody noticed.
As you can notice from Byrth's last post I've been suggested to use Midaction().
So far I used this function only once, in my SCH Lua. At the beginning of my precast I have the following
I get roughly how it works. If an action is currently ongoing (i.e. casting a spell) this will interrupt the precast function and so no gear will be swapped.Code:if midaction() then cancel_spell() return end
With an action (spell) that actually has a casting time it's easy to understand how this could work, but how would this work with a JA?
What is considered to be a "midaction(true)" JA for Gearswap? How should I implement this?