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

[Solved] Movement trigger problems

Status
Not open for further replies.
Level 12
Joined
Jun 15, 2016
Messages
472
Hello everyone, I've been scratching my head at this problem for a while:

In this paste there's a test map for an AI script and some auxiliary triggers. In the map, blue player is supposed to act in a similar way to Illidan's player in the last TFT mission, i.e. blue player's paladin is going from one circle of power to another and attempting to channel from them.

The problem: the AI handles blue player's paladin reaching the vicinity of the circle of power, and the actual command for him to step on the circle of power is handled by this script:


JASS:
function Trig_COP1_Prompt_Conditions takes nothing returns boolean
   if RectContainsCoords(udg_SUR[0],GetUnitX(udg_WM),GetUnitY(udg_WM)) then
       return (not (udg_IsChanneling or IsUnitDeadBJ(udg_WM)))
   else
       return false
   endif
endfunction

function COP1_Channel takes nothing returns nothing
   set udg_IsChanneling = true
   set udg_Contested_COP = 0
   call TriggerExecute(gg_trg_red_sun_channeling)
endfunction

function Trig_COP1_Prompt_Actions takes nothing returns nothing
   local group Cfoes = CreateGroup()
   local integer Cnum = 0
   local unit Cunit
   
   call GroupEnumUnitsInRect(Cfoes,udg_SUR[0],null)
   set Cunit = FirstOfGroup(Cfoes)
   
   loop
       exitwhen Cunit == null
       exitwhen Cnum > 0
       
       loop
           exitwhen not ((GetUnitTypeId(Cunit) == udg_COP_ID) or (GetUnitState(Cunit,UNIT_STATE_LIFE) <= 0))
           call GroupRemoveUnit(Cfoes,Cunit)
           set Cunit = FirstOfGroup(Cfoes)
       endloop
       
       if GetOwningPlayer(Cunit) != udg_WMPlayer then
           set Cnum = Cnum + 1
           //call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\Resurrect\\ResurrectTarget.mdl",Cunit,"overhead"))
       else
           call GroupRemoveUnit(Cfoes,Cunit)
           set Cunit = FirstOfGroup(Cfoes)
       endif
   endloop
   
   if Cnum == 0 then
       if RectContainsCoords(udg_COP[0],GetUnitX(udg_WM),GetUnitY(udg_WM)) then
           //call BJDebugMsg("Can start channeling COP1")
           call COP1_Channel()
       else
           call IssuePointOrder(udg_WM,"smart",GetLocationX(udg_COP_MID[0]),GetLocationY(udg_COP_MID[0]))
           //call BJDebugMsg("order WM to COP1")
       endif
   else
       call DoNothing()
       //call BJDebugMsg("Enemies surrounding COP1, can't channel")
   endif
   
   call DestroyGroup(Cfoes)
   set Cfoes = null
   set Cunit = null
endfunction

//===========================================================================
function InitTrig_COP1_Prompt takes nothing returns nothing
    set gg_trg_COP1_Prompt = CreateTrigger()
    call TriggerRegisterTimerEvent(gg_trg_COP1_Prompt,1.00,true)
    call TriggerAddCondition(gg_trg_COP1_Prompt,Condition(function Trig_COP1_Prompt_Conditions))
    call TriggerAddAction(gg_trg_COP1_Prompt, function Trig_COP1_Prompt_Actions)
endfunction


However, this seems to work only part of the time, for some circles of power there is a higher chance to start channeling, for others lower. This script is replicated 4 times to 4 different circles of power, without any difference between them. Any ideas on what might cause the problem?
 
Level 18
Joined
Nov 21, 2012
Messages
835
If I understand right: you periodically checking if Palading enters surrounding region, then number of units not owner by player blue == 0 then start channel? If so please try this:
JASS:
//---------------------------------------------------
native UnitAlive takes unit u returns boolean
//---------------------------------------------------

function Trig_COP1_Prompt_Conditions takes nothing returns boolean
    return (not udg_IsChanneling) and UnitAlive(udg_WM) and RectContainsCoords(udg_SUR[0],GetUnitX(udg_WM),GetUnitY(udg_WM))
endfunction

function COP1_Channel takes nothing returns nothing
   set udg_IsChanneling = true
   set udg_Contested_COP = 0
   call TriggerExecute(gg_trg_red_sun_channeling)
endfunction

function Trig_COP1_Prompt_Actions takes nothing returns nothing
   local integer Cnum = 0
    local unit u=null
  
    call GroupEnumUnitsInRect(udg_ug, udg_SUR[0], null)
    loop
        set u = FirstOfGroup(udg_ug)
        exitwhen u == null
        if UnitAlive(u) and GetOwningPlayer(u) != udg_WMPlayer and GetUnitTypeId(u) != udg_COP_ID then
            set Cnum = Cnum + 1
            exitwhen true
        endif  
        call GroupRemoveUnit(udg_ug, u)
    endloop
    call GroupClear (udg_ug)
  
    if Cnum==0 then
        if IsUnitInRangeLoc(udg_WM, udg_COP_MID[0], 64.00) then
            call COP1_Channel()
        else
            call IssuePointOrderLoc(udg_WM, "smart", udg_COP_MID[0])
        endif
    endif  
  
    set u=null
endfunction
//===========================================================================
function InitTrig_COP1_Prompt_Copy takes nothing returns nothing
    set gg_trg_COP1_Prompt_Copy = CreateTrigger()
    call TriggerRegisterTimerEvent(gg_trg_COP1_Prompt_Copy,1.00,true)
    call TriggerAddCondition(gg_trg_COP1_Prompt_Copy,Condition(function Trig_COP1_Prompt_Conditions))
    call TriggerAddAction(gg_trg_COP1_Prompt_Copy, function Trig_COP1_Prompt_Actions)
endfunction
declare native UnitAlive only once, duplicate for 3 other circles try if this working :)

edit:
udg_ug - unit group global
use this group without creating/destroying group every second
 
Last edited:
Status
Not open for further replies.
Top