• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Problem with auto cast ability

Status
Not open for further replies.
Level 3
Joined
Nov 28, 2008
Messages
24
Hi! I'm currently learning vJass and I'm trying to make an ability that deals 50% of the hero's int upon hitting the target. The ability is an auto casting ability (like Searing Arrows) and the hero has a ranged attack. So, I figured out that I will be needing a trigger to detect if the ability is autocast (right-clicked). Here's what I have :

JASS:
scope Autocast initializer Init

    globals
        //code of the spell
        private constant integer SPELL_ID = 'A000'
        group autocastgroup = CreateGroup()
    endglobals
    
    private function Cond takes nothing returns boolean
        if GetUnitAbilityLevel(GetTriggerUnit(), SPELL_ID) > 0 then
            if GetIssuedOrderId() == OrderId("flamingarrows") then
                //If autocast on, add unit to group
                call GroupAddUnit(autocastgroup, GetTriggerUnit())
            elseif GetIssuedOrderId() == OrderId("unflamingarrows") then
                //If autocast off, remove unit from group
                call GroupRemoveUnit(autocastgroup, GetTriggerUnit())
            endif
        endif
        return false
    endfunction
    
    private function Init takes nothing returns nothing
        local trigger a = CreateTrigger()
        local integer b = bj_MAX_PLAYERS
        loop
            exitwhen b < 0
            call TriggerRegisterPlayerUnitEvent(a, Player(b), EVENT_PLAYER_UNIT_ISSUED_ORDER, null)
            set b = b - 1
        endloop
        call TriggerAddCondition(a, Condition(function Cond))
    endfunction
    
endscope

The trigger basically adds the unit to autocastgroup when autocast is on. Then, here's the trigger of the ability :

JASS:
scope SomeAbility initializer Init

    globals
        //code of the spell
        private constant integer SPELL_ID = 'A000'
        private trigger DamageTrg = CreateTrigger()
        private group AttackedGrp = CreateGroup()
    endglobals
    
    private function Actions takes nothing returns boolean
        //these locals are for later use in the other spell actions
        local unit a = GetEventDamageSource()
        local unit b = GetTriggerUnit()
        local real c = GetEventDamage()
        local texttag d
        
        //to check if the unit has ability and if the ability is autocast(if the unit is the autocastgroup)
        if GetUnitAbilityLevel(a, SPELL_ID) > 0 and IsUnitInGroup(a, autocastgroup) then
        
            //this is to see if the floating text shows when the missile reaches/hits the target
            set d = CreateTextTag()
            call SetTextTagText(d, "YES!", 0.023)
            call SetTextTagColor(d, 150, 150, 200, 0)
            call SetTextTagPosUnit(d, b, 50.)
            call SetTextTagPermanent(d, false)
            call SetTextTagFadepoint(d, 0.)
            call SetTextTagLifespan(d, 2.)
            call SetTextTagVelocity(d, 0., 0.023)
            
            //other spell actions
        endif
        set a = null
        set b = null
        set d = null
        return false
    endfunction
    
    private function Cond takes nothing returns boolean
        if not IsUnitInGroup(GetTriggerUnit(), AttackedGrp) then
            //Damage Detection
            call GroupAddUnit(AttackedGrp, GetTriggerUnit())
            call TriggerRegisterUnitEvent(DamageTrg, GetTriggerUnit(), EVENT_UNIT_DAMAGED)
        endif
        return false
    endfunction
    
    private function Init takes nothing returns nothing
        local trigger a = CreateTrigger()
        local integer b = bj_MAX_PLAYERS
        loop
            exitwhen b < 0
            call TriggerRegisterPlayerUnitEvent(a, Player(b), EVENT_PLAYER_UNIT_ATTACKED, null)
            set b = b - 1
        endloop
        call TriggerAddCondition(a, Condition(function Cond))
        call TriggerAddCondition(DamageTrg, Condition(function Actions))
        set a = null
    endfunction
    
endscope

When I tested, it works fine. The floating text shows when the missile reaches the target and the ability is set to auto casting and the vice versa. Now here comes the problem :

*Floating text doesn't show when the missile hits the target if auto casting is turned off just after the missile is released. (Before the missile is released, auto casting is turned on)

*Floating text shows when the missile hits the target if auto casting is turned on just after the missile is released. (Before the missile is released, auto casting is turned off)

So, is it possible to fix this? +rep to those who help. Also, do let me know if my coding is inefficient. Thanks!
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
Of course this happens, the approach is inaccurate. You would have to take another path to turn this properly. You do not have access to the missile. Either trigger it (the missile) or what is commonly practised is to not take Searing Arrows but an an arrow spell or orb ability which transfers a unique buff upon impact to the target that you immediately remove again but are able to identify the attack on EVENT_UNIT_DAMAGED by checking for the buff's presence.
 
Level 3
Joined
Nov 28, 2008
Messages
24
Of course this happens, the approach is inaccurate. You would have to take another path to turn this properly. You do not have access to the missile. Either trigger it (the missile) or what is commonly practised is to not take Searing Arrows but an an arrow spell or orb ability which transfers a unique buff upon impact to the target that you immediately remove again but are able to identify the attack on EVENT_UNIT_DAMAGED by checking for the buff's presence.

Many thanks for the help! I think I've got it.
Added rep!
 
Status
Not open for further replies.
Top