• 🏆 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!

Make AI use backstab when in Wind Walk?

Status
Not open for further replies.
Level 13
Joined
Oct 16, 2010
Messages
731
So I came across a lil situation where my AI would use Wind Walk then run away and heal which was fine. But then when they got high enough level they would attack again whilst still being invisible.
So I tried to add a trigger that makes them attack a nearby hero if they come across one but the trigger works and they go to a hero but don't attack it. And instead just stand there invisible like some kind of stalker. Then they come out of wind walk and get killed most of the time!
I was wondering if there was a specific command I had to make them use but I couldn't find one. Any help?

  • AI Cast Wind Walk Backstab
    • Events
    • Conditions
    • Actions
      • Set AINearbyTargets = (Units within 3000.00 of TempPoint matching ((((Matching unit) is A Hero) Equal to True) and ((((Matching unit) is alive) Equal to True) and (((Owner of (Matching unit)) is an enemy of AITempPlayer) Equal to True))))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in AINearbyTargets) Greater than or equal to 1
        • Then - Actions
          • Set AICastPoint = (Position of AIHeroUnit)
          • Unit - Order AIHeroUnit to Attack (Random unit from AINearbyTargets)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (AIHeroUnit is in AIWantSpell) Equal to False
            • Then - Actions
              • Unit Group - Add AIHeroUnit to AIWantSpell
            • Else - Actions
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (AIHeroUnit is in AIWantSpell) Equal to True
            • Then - Actions
              • Unit Group - Remove AIHeroUnit from AIWantSpell
            • Else - Actions
 
Is there any event? Whatever...
If you dont declare AICastPoint and AIHeroUnit in other trigger (what i think) do this:

- 'Set AICastPoint' should befirst action, before you set your UnitGroup, then TempPoint should be replaced by AICastPoint (when u use InRangeWith)
- Don't set AICastPoint = Position of AIHeroUnit ... set it = position of triggering unit
- Don't check if hero is in this group (useless)
- No need to check if number > 0, just let TRIGGERING unit attack a random unit from AINearbyTargets (if group should be empty, there just wont be an attack)
(But you will need an unit event that you can use triggering unit as reference)

Last step, removing memory leaks:
- custom script: call RemoveLocation (udg_AICastPoint)
- custom script: call Destroy UnitGroup (udg_AINearbyTargets)
 
Last edited:
Level 13
Joined
Oct 16, 2010
Messages
731
This trigger is run by a seperate trigger. The seperate trigger picks all player out of a group (the group has been set to all player slots held by a computer). And at the start of that things like AIHeroUnit are set. It then runs a big If, Then, Else chain where it decides what the computer will make the hero do. If a hero hits all the conditions of a specific part of the chain then it adds them to a group (like AIWantSpellGroup) of which then causes the chain to stop allowing them to perform that section of the chain. So they need to be added and removed from the different groups depending on whether they fit the conditions or not.

Also the part about checking to see if any units are in the group is needed due to adding the Hero into the unit group. Otherwise it'd end up adding them into the group when they actually had no target.


Anyway this still does not solve the problem of them not attacking when in Wind Walk!!!
 
Level 18
Joined
Nov 1, 2006
Messages
1,612
Was this problem ever solved? I am having the exact same issue while trying to create some AI. If you order the unit to attack they will make their way all the way over to the enemy and then do nothing until WW is broken.

I am going to try adding a temporary dummy ability and ordering the Hero to cast that to break invis. When that ability is used, I'll then order the Hero to attack and trigger backstab dmg.
 
Level 18
Joined
Nov 1, 2006
Messages
1,612
*UPDATE* Karzama, I created a work around to solve this issue. Excuse the poor code, it's a WIP.

I created a trigger that registers when the unit casts Wind Walk. It promptly removes the Wind Walk buff and adds 'Agho' (permanent invisibility) to the Hero. The result is unnoticeable and the unit remains invisible, but can be seen by truesight. I then create a dummy unit and cast a dummy ability on the Hero which has no effect except for to add the a dummy Wind Walk buff. It also creates a timer that will measure the duration of Wind Walk and remove buffs upon expiration.

JASS:
function Trig_AI_Ghost_Walk_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000' and udg_AI_mode_ON == true 
endfunction

function Trig_AI_Ghost_Walk_Actions takes nothing returns nothing
    local unit d = GetTriggerUnit()
    local unit u
    local integer i = 0
    local integer lvl = GetUnitAbilityLevel(d, 'A000')
    local boolean exit = false
    //I had to put this in a loop bc for some reason it wouldn't register without one. The i variable is used as a backup to prevent an infinite loop but you don't need it.
    loop
        exitwhen exit == true or i == 10
        set i = i + 1
        if GetUnitAbilityLevel(d, 'B005') > 0 then
            call UnitRemoveAbility(d, 'B005')
            call UnitAddAbility(d, 'Agho')
            set exit = true
        endif
        call TriggerSleepAction(0.01)
    endloop
    set u = CreateUnit(GetOwningPlayer(d), 'h00G', GetUnitX(d), GetUnitY(d), bj_UNIT_FACING)
    call UnitApplyTimedLife(u, 'BTLF', 1.00)
    call UnitAddAbility( u, 'A04N' )
    call SetUnitAbilityLevel(u, 'A04N', lvl)
    call IssueTargetOrder( u, "rejuvination", d )
    call TimerStart(udg_AI_Gen_Timer[11],(20.0+(10.0*(I2R(lvl - 1)))), false, null)
    set d = null
    set u = null
endfunction

//===========================================================================
function InitTrig_AI_Ghost_Walk takes nothing returns nothing
    set gg_trg_AI_Ghost_Walk = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_AI_Ghost_Walk, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_AI_Ghost_Walk, Condition( function Trig_AI_Ghost_Walk_Conditions ) )
    call TriggerAddAction( gg_trg_AI_Ghost_Walk, function Trig_AI_Ghost_Walk_Actions )
endfunction

I then created a trigger that registers when a unit takes damage from a unit with the dummy Wind Walk buff. When this trigger fires, it adds the backstab damage to the attack and creates floating text (see below for details). Since it is a "unit takes damage" trigger, the Event had to be added from another trigger. If you need help with that let me know.

JASS:
function Trig_GW_Backstab_Conditions takes nothing returns boolean
    return GetUnitAbilityLevel(GetEventDamageSource(), 'B01R') > 0 and udg_AI_mode_ON == true
endfunction

function Trig_GW_Backstab_Actions takes nothing returns nothing    
    local unit d = GetEventDamageSource()
    local unit u = GetTriggerUnit()
    local real dmg = (GetUnitAbilityLevel(d, 'A000') * 60.0)
    local force f = CreateForce()
    local force g = CreateForce()
    call UnitRemoveAbility(d, 'Agho')
    call UnitRemoveAbility(d, 'B01R')
    if GetWidgetLife(u) > 0 and GetWidgetLife(d) > 0 then
        call UnitDamageTarget(d, u, dmg, true, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
        // Text Tag being created
        call CreateTextTagUnitBJ( ( "|cffFF0000" + ( I2S(R2I(dmg)) + "|r" ) ), u, 0, 10, 100, 100, 100, 0 )
        if (IsPlayerInForce(GetLocalPlayer(), bj_FORCE_ALL_PLAYERS))then
            call SetTextTagVisibility(bj_lastCreatedTextTag, false)
        endif
        call ForceEnumAllies(f, GetOwningPlayer(d), null)
        call ForceEnumAllies(g, GetOwningPlayer(u), null)
        if (IsPlayerInForce(GetLocalPlayer(), f)) or (IsPlayerInForce(GetLocalPlayer(), g)) then
            call SetTextTagVisibility(bj_lastCreatedTextTag, true)
        endif
        call SetTextTagVelocity(bj_lastCreatedTextTag, 0, 0.04)
        call SetTextTagPermanent(bj_lastCreatedTextTag, false)
        call SetTextTagFadepoint(bj_lastCreatedTextTag, 2.00)
        call SetTextTagLifespan(bj_lastCreatedTextTag, 3.00)
    endif
    call DestroyForce(f)
    call DestroyForce(g)
    set f = null
    set g = null
    set d = null
    set u = null
endfunction

//===========================================================================
function InitTrig_GW_Backstab takes nothing returns nothing
    set gg_trg_GW_Backstab = CreateTrigger(  )
    call TriggerAddCondition( gg_trg_GW_Backstab, Condition( function Trig_GW_Backstab_Conditions ) )
    call TriggerAddAction( gg_trg_GW_Backstab, function Trig_GW_Backstab_Actions )
endfunction

Then, just create a trigger that fires whenever the Wind Walk duration is over that will remove all buffs from the unit.

JASS:
function Trig_GW_DEBUFF_Conditions takes nothing returns boolean
    return udg_AI_mode_ON == true
endfunction

function Trig_GW_DEBUFF_Actions takes nothing returns nothing
    //If you want this to be multi-instanceable, you'll need to create a global unit array for this to work
    call UnitRemoveAbility(udg_GameDeathKnight, 'Agho')
    call UnitRemoveAbility(udg_GameDeathKnight, 'B01R')
endfunction

//===========================================================================
function InitTrig_GW_DEBUFF takes nothing returns nothing
    set gg_trg_GW_DEBUFF = CreateTrigger(  )
    call TriggerRegisterTimerExpireEvent(gg_trg_GW_DEBUFF, udg_AI_Gen_Timer[11])
    call TriggerAddCondition( gg_trg_GW_DEBUFF, Condition( function Trig_GW_DEBUFF_Conditions ) )
    call TriggerAddAction( gg_trg_GW_DEBUFF, function Trig_GW_DEBUFF_Actions )
endfunction

NOTE: I didn't need this spell to be MUI in my map so this version is not, however if you need it to be then just create a Timer Array and set each timer = Player ID to get that to work properly.
 
Level 5
Joined
Aug 9, 2012
Messages
119
of course it didnt works,
try it yourself for your hero....
if u order to attack ground( then it means attack all nearby enemies)
IT wont attack because it recognize ur state in invisible...

try to pick unit within windwalk area , maybe around 1000-2500 AoE ffrom the caster
then randomly picked the targeted, filter it... hero unit, and belong to enemy
then order the AI to atttack directly...
hope tht helps
 
Level 18
Joined
Nov 1, 2006
Messages
1,612
if u order to attack ground( then it means attack all nearby enemies)
IT wont attack because it recognize ur state in invisible...

As you can see below, he was ordering the unit to attack a UNIT not the ground. There seems to be a bug that will not allow a Hero to attack and break invisibility if it has the Wind Walk buff.

  • Unit - Order AIHeroUnit to Attack (Random unit from AINearbyTargets)
Try for yourself. The Hero will move right up to within attack range and then will do nothing until the buff duration is over.
 
Status
Not open for further replies.
Top