The Forums Are Now Closed!

The content will remain as a historical reference, thank you.

Precastcheck function

By on February 2, 2011 1:26:08 AM from Demigod Forums Demigod Forums


Join Date 07/2009

Hi mithy,


i have written a new abilitytask.lua that will let you use a "precastcheck" like function to analyse all ability information before casting. Before it was limited to checking yourself (it was only for minion code) but i have modified it for eviction to allow me to analyse target buffs.


i was wondering if you had a method to make this less destructive (although it is not too bad now, i cannot make it so that the rest of the State {} function is repasted in BeginCastState{}


If you have the time can you check it out? it works as is but i just wanted to see if there was a less destructive method.


Cheers exx

Locked Post 7 Replies
Search this post
Subscription Options

Reason for Karma (Optional)
Successfully updated karma reason!
February 2, 2011 11:01:55 AM from Demigod Forums Demigod Forums

I don't think you need to do that at all?

Look at this line, present in the original:

Code: c++
  1. self.Unit.Callbacks.OnAbilityBeginCast:Call( self, self.Unit )

This runs any callback functions of this type added to the casting unit every time casting starts.  Since it passes 'self' (the AbilityTask itself in this case), you should be able to access self.Target from within this callback.


So, to use this, you need to add a callback function to the unit whenever the Eviction ability is on the unit, and remove it when the Eviction ability is removed.  Here's some prototype code that you should be able to get working with some testing: 

Code: c++
  1. --Add to the Eviction item's actual ability blueprint
  2. EvictionTime = 120,
  3. OnAbilityAdded = function(self, unit)
  4.     unit.Callbacks.OnAbilityBeginCast:Add(self.EvictionCheck, self)
  5. end,
  6. OnRemoveAbility = function(self, unit)
  7.     unit.Callbacks.OnAbilityBeginCast:Remove(self.EvictionCheck)
  8. end,
  9. --This function gets its first param from the above Add() (the ability def), and the second two params from its Call()
  10. --in AbilityTask.BeginCastState.OnEnterState (which are self and self.Unit, self being the AbilityTask)
  11. EvictionCheck = function(abilDef, abilTask, caster)
  12.     --Make sure the ability task in question is eviction; abilDef will always be eviction's blueprint, but abilTask
  13.     --will not always be an eviction cast (it's triggered for all ability casts while this callback is on the unit
  14.     if abilTask.AbilityName == abilDef.Name and abilTask.Target then
  15.         --Looks for an EvictionTime var on the target unit - set this using GetGameTimeSeconds() upon successful cast
  16.         local targetEvicted = abilTask.Target.EvictionTime
  17.         if targetEvicted and GetGameTimeSeconds() - targetEvicted < abilDef.EvictionTime then
  18.             abilTask:AbortCast()
  19.         end
  20.     end
  21. end,

The game's callback add/remove system is a little confusing, because if the Add() call specifies a second parameter, that becomes the first parameter to a Call() of that callback.  If you want to be more/less confused, look at the Add/Remove/Call functions in /lua/system/Callback.lua.

Regardless, this should work fine, because it can get a handle to the target via the abilityTask passed to it, and then issue an AbortCast() directly to the abilityTask if the target matches conditions.  I just put some dummy conditions in using GetGameTimeSeconds so it would make sense while I was writing it - just replace that with however you're already doing has-been-evicted-detection.

Reason for Karma (Optional)
Successfully updated karma reason!
February 2, 2011 11:16:37 AM from Demigod Forums Demigod Forums

Nevertheless, in the future, if you want to hook a State, you do it just like you would the Class it belongs to (a State is essentially a sub-Class).  FA's state system had some quirks that sometimes made hooks of them not quite work how you would expect, but I'll take a shot at translating your original code just in case they fixed that in Demigod (plus something this simple would probably work just fine):

Code: c++
  1. local prevClass = AbilityTask
  2. AbilityTask = Class(prevClass) {
  3.     BeginCastState = State(prevClass.BeginCastState) {
  4.         OnEnterState = function(self)
  5.             if self.Ability.PreCastCheck then
  6.                 # do we have any check that may prevent this ability from launching
  7.                 if not self.Ability:PreCastCheck(self.Unit) then
  8.                     self.KillTask = true
  9.                     return
  10.                 end
  11.             end
  12.             prevClass.BeginCastState.OnEnterState(self)
  13.         end,
  14.     },
  15. }
Reason for Karma (Optional)
Successfully updated karma reason!
February 2, 2011 7:00:16 PM from Demigod Forums Demigod Forums

k ty mithy.


"I don't think you need to do that at all?"


i am positive that you need to do it (from the method i was using), i spent 4 hours trying to get the precast check function to recognise the target entity but it wouldnt no matter how i did it (params.Targets[1], target, self.Target etc). Each would only give me a nil value. Upon adding (self, self.Target, self.Ability) to the function it ran straight away.


Although i didnt use a callback i was trying to reference it from the precastcheck function itself.




1+ for being so awesomely helpful .


Reason for Karma (Optional)
Successfully updated karma reason!
February 2, 2011 7:20:33 PM from Demigod Forums Demigod Forums

ok i took your fixed hook in abilitytask.lua and am going to use that for the moment so that i have a simple method of using a precastcheck/kill:task method


it works great:


i was missing this when i tried to do it

BeginCastState = State(prevClass.BeginCastState) {

Ty again!

Reason for Karma (Optional)
Successfully updated karma reason!
February 2, 2011 7:45:37 PM from Demigod Forums Demigod Forums

Did you even try the callback method?  I assure you it will work, as it has the actual AbilityTask as one of its parameters.  It's also the way this kind of thing is supposed to be done, and while it's confusing at first, once you learn how callbacks work you can do a ton of stuff with them that would otherwise require re-writes of tons of base code.

The original pre-cast check function never has the AbilityTask object itself passed to it, only the casting unit and the ability blueprint.  'self' in the pre-cast check is the ability blueprint, not the AbilityTask object, which is why you couldn't get a target from it.

Reason for Karma (Optional)
Successfully updated karma reason!
February 3, 2011 12:52:59 AM from Demigod Forums Demigod Forums

yere i understand that, however, if i was to use the callback strategy it would require me to rewrite all my effects code (which currently just hijacks the buff timer and is activated by the buff itself) and so at this point it is easier for me to use the altered ability task.lua. Also now that this has been changed i can use it for all the precast checks, as it does not require much extra code.


IMO the precast check should have always had access to this data (i dont really understand why you would want a precast check that only allows you to check yourself) so i figure it is kinda of a system update .

I have used callbacks before but i find that they tend to cause alot of problems (like ub code -- this uses alot of them) as if they were added as an afterthought. Nevertheless, when i get some time i might look into them and get more familiar with them.


Reason for Karma (Optional)
Successfully updated karma reason!
February 3, 2011 1:52:08 PM from Demigod Forums Demigod Forums

This shouldn't cause any problems, and like I said, you could pretty much just paste your version of the pre-cast function in and change the parameter references, but w/e.

Reason for Karma (Optional)
Successfully updated karma reason!
Stardock Forums v1.0.0.0    #101114  walnut1   Server Load Time: 00:00:00.0000110   Page Render Time: