Page 1 of 1

How to set a var before a talent is used?

Posted: Tue Feb 06, 2018 7:02 am
by ghostbuster
I try to make an addon for a class that has a sustained talent that gives great benefits to melee attacks, but forbids all regular attacks (bump, attacks from technique, cunning, etc). Only automatic attacks (TK or retaliation attacks provided by the class) or attacks from some specific talents would be allowed. (because a rand boss or an adventurer with flurry and this sustain would be too unbalanced)

To do that, bumpInto can be superloaded to check if the attack is valid. Attacks triggered by talents are trickier. One solution is to use a turn_procs variable that forbids attacks and to hook or superload attackTarget (and ditto for attackTargetWith) to take into account this turn_procs.

The problem is how to set this turn_procs var?

The initial idea was to use the Actor:preUseTalent hook. According to the wiki, it triggers just before a talent is used. It can check if the sustain is on and if the talent has some characteristics to set the turn proc. (Actually only talents with a psi or sustain_psi field could be allowed to trigger if the sustain is on).

It happens that the Actor:preUseTalent hook is not checked right before the use of a talent, but for all the actor talents at the start of a turn (like the on_pre_use talent field). and this solution does not work.

Indeed, what I would need is to set my turn_procs variable just at the beginning of useTalent in ActorTalents.lua in the engine. AFAIK, engine methods cannot be superloaded, but maybe there is a way...

The other solution that I see is to superload the action field of all the talents in the game to set the turn_procs. It is somehow painful because some talents can do attacks without a "action" (BTF, for instance, but maybe there are others talents like that in vanilla or in addons).

Is there a way that I miss to hook right before before a talent is used?
Do you see any other way to do that?

Re: How to set a var before a talent is used?

Posted: Tue Feb 06, 2018 11:20 am
by HousePet
Now I could be sleep drunk due to passing out unintentionally early, but why do you need anything stored in turn_procs at all?
You can just check for the sustain being active in whatever you do with bumpInto and a modification to Actor:preUseTalent should allow you to disable all talents you want to be non useable until the sustain is disabled.
Forbidding the attacks by blocking it during Combat:attackTarget would be terrible as the talents would still be used, but they would not have any effect.
Engine functions can be superloaded if you want to as well.

Re: How to set a var before a talent is used?

Posted: Tue Feb 06, 2018 12:16 pm
by ghostbuster
Now I could be sleep drunk due to passing out unintentionally early, but why do you need anything stored in turn_procs at all?
You can just check for the sustain being active in whatever you do with bumpInto and a modification to Actor:preUseTalent should allow you to disable all talents you want to be non useable until the sustain is disabled.
Forbidding the attacks by blocking it during Combat:attackTarget would be terrible as the talents would still be used, but they would not have any effect.
Engine functions can be superloaded if you want to as well.
I do not want to disable talents based on the sustain. A stamina consuming talent is not a problem if it does not perform a melee attack. And determining automatically if a talent will perform an attack or not is almost impossible (at least for me :().

You are totally right concerning the fact that the talent should not be used at all.

I will try to superload engine useTalent().
This way, it should be possible to set a var before useTalent, block attacks is required in a hook or superload of attackTarget while keeping track of blocked attacks and to restore energy and cooldown if an attack has been forbidden. This would solve all problems (well, I hope...).
How can engine superloads be done? Just by adding an 'engine' dir in tome-addon/superload?

Re: How to set a var before a talent is used?

Posted: Tue Feb 06, 2018 8:18 pm
by ghostbuster
I finally found how to superload engine.

According to the remarks of HousePet, it is better to cancel at the talent level, not at the attack level, to avoid turn and resource loss .
The simpler and best method is probably the following:
1/ superload useTalent to see if the actor is allowed to attackTarget
If not, check if the talent is blacklisted (known as attacking) and if it is true, cancel the talent and warn the player.
Otherwise, mark the player in a turn_procs and add a turn_procs with the name of the current talent
2/ in an attackTarget superload, check if the player is forbidden to attack
if true, add the talent name (in the turn_procs) to the black list and cancel the attack (or allow it for the first and last time)

The black list can be initialized in load.lua with some talents and after the list will be completed while learning which talents do an attack.
This black list can also be used to invalidate the talent with a onPreUse hook instead of before useTalent.

My question now is :
Where can I store this blacklist to have it saved and restored?
I can maybe use something like
game.addon_blacklist_with_a_very_weird_name_to_avoid_any_collision_with_other_fields
but is it guaranteed to be saved and restored?
And is there a cleaner way?

Re: How to set a var before a talent is used?

Posted: Tue Feb 06, 2018 10:17 pm
by darkgod
To forbid a talent from being used to NOT superload engine.useTalent, superload mod's Actor:preUseTalent or hook on "Actor:preUseTalent"

As for storing stuff in game.whatever_foobar, no it wont get saved. There is a way to do so but it's bad form, if you want something saved in the game state, use game.state.whatever that's what it's for :)