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

Issue with conditionals.

Status
Not open for further replies.
Level 12
Joined
Dec 2, 2016
Messages
733
So the following checks if the triggering unit 'Attacked unit' is Player 2(Teal)
Checks if the attacker is not equal to the triggering unit.

It then checks if the unit type of the attacker is not equal to the listed unit types.

Now all this works and runs, but the issue I'm having is the 'preventAttack' function.

What I want this code to do is that if any of the 3 regions contain a 'Flag' unit or the 'TriggeringUnit' then prevent the attacking units attack.
What happens right now is it only prevents the 'AttackingUnit's attack if the region the 'TriggeringUnit' is in also contains the 'Flag' unit. I need to prevent the attack if like said above ^ any of the 3 regions contain both the triggering unit and the flag. Doesn't need to be in the same region only that at least 1 of the regions contains the flag, and one of the regions contains the triggering unit. I'm not sure how to fix this, if you could help would be much appreciated. Thanks.


JASS:
function preventAttack takes nothing returns nothing
   
    if (( RectContainsUnit(gg_rct_Base01a, GetTriggerUnit()) == true and RectContainsUnit(gg_rct_Base01a, GetEnumUnit()) == true) or (RectContainsUnit(gg_rct_Base02a, GetTriggerUnit()) == true and RectContainsUnit(gg_rct_Base02a, GetEnumUnit()) == true) or (RectContainsUnit(gg_rct_Base03a, GetTriggerUnit()) == true and RectContainsUnit(gg_rct_Base03a, GetEnumUnit()) == true))then
        call DisplayTextToForce( GetPlayersAll(), "Stop" )
        call PauseUnitBJ( true, GetAttacker() )
        call IssueImmediateOrderBJ( GetAttacker(), "stop" )
        call PauseUnitBJ( false, GetAttacker() )
   else
    endif
endfunction

Entire code below:




JASS:
scope fixTeal initializer registerFix

globals
endglobals

function preventAttack takes nothing returns nothing
   
    if (( RectContainsUnit(gg_rct_Base01a, GetTriggerUnit()) == true and RectContainsUnit(gg_rct_Base01a, GetEnumUnit()) == true) or (RectContainsUnit(gg_rct_Base02a, GetTriggerUnit()) == true and RectContainsUnit(gg_rct_Base02a, GetEnumUnit()) == true) or (RectContainsUnit(gg_rct_Base03a, GetTriggerUnit()) == true and RectContainsUnit(gg_rct_Base03a, GetEnumUnit()) == true))then
        call DisplayTextToForce( GetPlayersAll(), "Stop" )
        call PauseUnitBJ( true, GetAttacker() )
        call IssueImmediateOrderBJ( GetAttacker(), "stop" )
        call PauseUnitBJ( false, GetAttacker() )
   else
    endif
endfunction

function mainMain takes nothing returns nothing

 if (GetOwningPlayer(GetTriggerUnit()) == Player(2) and GetOwningPlayer(GetAttacker()) != GetOwningPlayer(GetTriggerUnit()) )  then
          
 if (GetUnitTypeId(GetAttacker()) != 'U007' and GetUnitTypeId(GetAttacker()) != 'U008' and GetUnitTypeId(GetAttacker()) != 'E002' and GetUnitTypeId(GetAttacker()) != 'E001' and GetUnitTypeId(GetAttacker()) != 'AVFV')  then
    call ForGroupBJ( GetUnitsOfPlayerAndTypeId(GetOwningPlayer(GetTriggerUnit()), 'hFlg'), function preventAttack )
   endif
    endif

endfunction



function registerFix takes nothing returns nothing
local trigger TealFix = CreateListedTrigger()
    set TealFix = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( TealFix, EVENT_PLAYER_UNIT_ATTACKED )
    call TriggerAddAction( TealFix, function mainMain)
endfunction

endscope
 
Level 18
Joined
Nov 21, 2012
Messages
835
try this:
JASS:
globals
    boolean flagFound = false           
endglobals

function FindFlag takes nothing returns nothing
    if GetUnitTypeId(GetEnumUnit()) == 'hFlg' then
        set flagFound=true   
    endif
   
//    if (( RectContainsUnit(gg_rct_Base01a, GetTriggerUnit()) == true and RectContainsUnit(gg_rct_Base01a, GetEnumUnit()) == true) or (RectContainsUnit(gg_rct_Base02a, GetTriggerUnit()) == true and RectContainsUnit(gg_rct_Base02a, GetEnumUnit()) == true) or (RectContainsUnit(gg_rct_Base03a, GetTriggerUnit()) == true and RectContainsUnit(gg_rct_Base03a, GetEnumUnit()) == true))then
  //      call DisplayTextToForce( GetPlayersAll(), "Stop" )
    //    call PauseUnitBJ( true, GetAttacker() )
      //  call IssueImmediateOrderBJ( GetAttacker(), "stop" )
        //call PauseUnitBJ( false, GetAttacker() )
//   else
  //  endif
endfunction

function mainMain takes nothing returns nothing
    local unit u=GetTriggerUnit()
    local player p=GetOwningPlayer(u)
    local integer attId=GetUnitTypeId(GetAttacker()
    local group g=null
           
    if (p == Player(2) and GetOwningPlayer(GetAttacker()) != p ) then   
        if (attId != 'U007' and attId != 'U008' and attId != 'E002' and attId != 'E001' and attId != 'AVFV') then
            //check if attacked unit is in rect
            if RectContainsUnit(gg_rct_Base01a, u) or RectContainsUnit(gg_rct_Base02a, u) or RectContainsUnit(gg_rct_Base03a, u) then
                // now only look for "flag" unit
                set flagFound=false
                set g = GetUnitsInRectOfPlayer(gg_rct_Base01a, p)
                call ForGroup( GetUnitsInRectOfPlayer(GetPlayableMapRect(), p), function FindFlag )
                set g = GetUnitsInRectOfPlayer(gg_rct_Base02a, p)
                call ForGroup( GetUnitsInRectOfPlayer(GetPlayableMapRect(), p), function FindFlag )
                set g = GetUnitsInRectOfPlayer(gg_rct_Base03a, p)
                call ForGroup( GetUnitsInRectOfPlayer(GetPlayableMapRect(), p), function FindFlag )

                if flagFound then
                    call DisplayTextToForce( GetPlayersAll(), "Stop" )
                    call PauseUnitBJ( true, GetAttacker() )
                    call IssueImmediateOrderBJ( GetAttacker(), "stop" )               
                endif
                call DestroyGroup(g)
                set g=null
               
                //call ForGroupBJ( GetUnitsOfPlayerAndTypeId(GetOwningPlayer(u), 'hFlg'), function preventAttack )
            endif
       endif
    endif   
    set u=null
endfunction



function registerFix takes nothing returns nothing
local trigger TealFix = CreateListedTrigger()
    set TealFix = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( TealFix, EVENT_PLAYER_UNIT_ATTACKED )
    call TriggerAddAction( TealFix, function mainMain)
endfunction

of course you can cut most of these BJ function later, and use trigger condition instead of action (in registerFix).
 
preventAttack has no access to GetTriggerUnit or GetAttacker, only GetEnumUnit.

Try something like this:
JASS:
function mainMain takes nothing returns nothing
    local group grp = null
    local unit u = null

 if (GetOwningPlayer(GetTriggerUnit()) == Player(2) and GetOwningPlayer(GetAttacker()) != GetOwningPlayer(GetTriggerUnit()) )  then
      
 if (GetUnitTypeId(GetAttacker()) != 'U007' and GetUnitTypeId(GetAttacker()) != 'U008' and GetUnitTypeId(GetAttacker()) != 'E002' and GetUnitTypeId(GetAttacker()) != 'E001' and GetUnitTypeId(GetAttacker()) != 'AVFV')  then
    set grp = GetUnitsOfPlayerAndTypeId(GetOwningPlayer(GetTriggerUnit()), 'hFlg')
    loop
        set u = FirstOfGroup(grp)
        exitwhen u == null
        if (RectContainsUnit(gg_rct_Base01a, GetTriggerUnit()) and RectContainsUnit(gg_rct_Base01a, u)) or (RectContainsUnit(gg_rct_Base02a, GetTriggerUnit()) and RectContainsUnit(gg_rct_Base02a, u)) or (RectContainsUnit(gg_rct_Base03a, GetTriggerUnit()) and RectContainsUnit(gg_rct_Base03a, u)) then
            call DisplayTextToForce( GetPlayersAll(), "Stop" )
            call PauseUnitBJ( true, GetAttacker() )
            call IssueImmediateOrderBJ( GetAttacker(), "stop" )
            call PauseUnitBJ( false, GetAttacker() )
       endif
       call GroupRemoveUnit(grp, u)
    endloop
 
    call DestroyGroup(grp)
    set grp = null
    set u = null
endif
endif

endfunction

Also, you should use some more local variables instead of calling the same functions multiple times. Use booleans for RectContainsUnit(gg_rct_Base01a, GetTriggerUnit()).

edit:

JASS:
function mainMain takes nothing returns nothing
    local unit triggerUnit = GetTriggerUnit()
    local unit attacker = GetAttacker()
    local player triggerPlayer = GetOwningPlayer(triggerUnit)
    local integer attackerId
    local group grp = null
    local unit u = null
    local boolean inBase1
    local boolean inBase2
    local boolean inBase3
    local boolean attackerStopped = false

    if triggerPlayer == Player(2) and GetOwningPlayer(attacker) != triggerPlayer then
        set attackerId = GetUnitTypeId(attacker)

        if attackerId != 'U007' and attackerId != 'U008' and attackerId != 'E002' and attackerId != 'E001' and attackerId != 'AVFV' then
            set inBase1 = RectContainsUnit(gg_rct_Base01a, triggerUnit)
            set inBase2 = RectContainsUnit(gg_rct_Base02a, triggerUnit)
            set inBase3 = RectContainsUnit(gg_rct_Base03a, triggerUnit)

            if inBase1 or inBase2 or inBase3 then
                set grp = GetUnitsOfPlayerAndTypeId(triggerPlayer, 'hFlg')

                loop
                    set u = FirstOfGroup(grp)
                    exitwhen u == null or attackerStopped
                    if (inBase1 and RectContainsUnit(gg_rct_Base01a, u)) or (inBase2 and RectContainsUnit(gg_rct_Base02a, u)) or (inBase3 and RectContainsUnit(gg_rct_Base03a, u)) then
                        call DisplayTextToForce( GetPlayersAll(), "Stop" )
                        call PauseUnitBJ( true, attacker )
                        call IssueImmediateOrderBJ( attacker, "stop" )
                        call PauseUnitBJ( false, attacker )
                        set attackerStopped = true
                    endif
                    call GroupRemoveUnit(grp, u)
                endloop
 
                call DestroyGroup(grp)
                set grp = null
                set u = null
            endif
        endif
    endif
   
    set triggerUnit = null
    set attacker = null
    set triggerPlayer = null
endfunction

And as ZiBitheWand3r3r said, all these BJs (red functions) can be eliminated.
 
Last edited:
Level 12
Joined
Dec 2, 2016
Messages
733
preventAttack has no access to GetTriggerUnit or GetAttacker, only GetEnumUnit.

Try something like this:
JASS:
function mainMain takes nothing returns nothing
    local group grp = null
    local unit u = null

 if (GetOwningPlayer(GetTriggerUnit()) == Player(2) and GetOwningPlayer(GetAttacker()) != GetOwningPlayer(GetTriggerUnit()) )  then
     
 if (GetUnitTypeId(GetAttacker()) != 'U007' and GetUnitTypeId(GetAttacker()) != 'U008' and GetUnitTypeId(GetAttacker()) != 'E002' and GetUnitTypeId(GetAttacker()) != 'E001' and GetUnitTypeId(GetAttacker()) != 'AVFV')  then
    set grp = GetUnitsOfPlayerAndTypeId(GetOwningPlayer(GetTriggerUnit()), 'hFlg')
    loop
        set u = FirstOfGroup(grp)
        exitwhen u == null
        if (RectContainsUnit(gg_rct_Base01a, GetTriggerUnit()) and RectContainsUnit(gg_rct_Base01a, u)) or (RectContainsUnit(gg_rct_Base02a, GetTriggerUnit()) and RectContainsUnit(gg_rct_Base02a, u)) or (RectContainsUnit(gg_rct_Base03a, GetTriggerUnit()) and RectContainsUnit(gg_rct_Base03a, u)) then
            call DisplayTextToForce( GetPlayersAll(), "Stop" )
            call PauseUnitBJ( true, GetAttacker() )
            call IssueImmediateOrderBJ( GetAttacker(), "stop" )
            call PauseUnitBJ( false, GetAttacker() )
       endif
       call GroupRemoveUnit(grp, u)
    endloop
 
    call DestroyGroup(grp)
    set grp = null
    set u = null
endif
endif

endfunction

Also, you should use some more local variables instead of calling the same functions multiple times. Use booleans for RectContainsUnit(gg_rct_Base01a, GetTriggerUnit()).

edit:

JASS:
function mainMain takes nothing returns nothing
    local unit triggerUnit = GetTriggerUnit()
    local unit attacker = GetAttacker()
    local player triggerPlayer = GetOwningPlayer(triggerUnit)
    local integer attackerId
    local group grp = null
    local unit u = null
    local boolean inBase1
    local boolean inBase2
    local boolean inBase3
    local boolean attackerStopped = false

    if triggerPlayer == Player(2) and GetOwningPlayer(attacker) != triggerPlayer then
        set attackerId = GetUnitTypeId(attacker)

        if attackerId != 'U007' and attackerId != 'U008' and attackerId != 'E002' and attackerId != 'E001' and attackerId != 'AVFV' then
            set inBase1 = RectContainsUnit(gg_rct_Base01a, triggerUnit)
            set inBase2 = RectContainsUnit(gg_rct_Base02a, triggerUnit)
            set inBase3 = RectContainsUnit(gg_rct_Base03a, triggerUnit)

            if inBase1 or inBase2 or inBase3 then
                set grp = GetUnitsOfPlayerAndTypeId(triggerPlayer, 'hFlg')

                loop
                    set u = FirstOfGroup(grp)
                    exitwhen u == null or attackerStopped
                    if (inBase1 and RectContainsUnit(gg_rct_Base01a, u)) or (inBase2 and RectContainsUnit(gg_rct_Base02a, u)) or (inBase3 and RectContainsUnit(gg_rct_Base03a, u)) then
                        call DisplayTextToForce( GetPlayersAll(), "Stop" )
                        call PauseUnitBJ( true, attacker )
                        call IssueImmediateOrderBJ( attacker, "stop" )
                        call PauseUnitBJ( false, attacker )
                        set attackerStopped = true
                    endif
                    call GroupRemoveUnit(grp, u)
                endloop
 
                call DestroyGroup(grp)
                set grp = null
                set u = null
            endif
        endif
    endif
  
    set triggerUnit = null
    set attacker = null
    set triggerPlayer = null
endfunction

And as ZiBitheWand3r3r said, all these BJs (red functions) can be eliminated.


Same thing, only stops the attack when the flag is in the region that the triggering unit is in.
 
Oh I see, just reread the OP, you want to stop the attack whenever one of the regions contains the triggering unit OR contains a flag? Then you just need to change the "and"s to "or"s

EDIT: reread OP fully again, I misunderstood. So you want to stop the attack when one of the regions contains the triggering unit AND one of the regions contains a flag owned by triggering unit's owner.
In that case, you need to check for both conditions separately. What you're doing is checking if any of the regions contain both the triggering unit and a flag.

Code example:
JASS:
function FlagsInBasesFilter takes nothing returns boolean
    local unit u = GetFilterUnit()
    local boolean r = GetUnitTypeId(u) == 'hFlg' and (RectContainsUnit(gg_rct_Base01a, u) or RectContainsUnit(gg_rct_Base02a, u) or RectContainsUnit(gg_rct_Base03a, u))
    set u = null
    return r
endfunction

function mainMain takes nothing returns nothing
    local unit triggerUnit = GetTriggerUnit()
    local unit attacker = GetAttacker()
    local player triggerPlayer = GetOwningPlayer(triggerUnit)
    local integer attackerId
    local group grp = null

    if triggerPlayer == Player(2) and GetOwningPlayer(attacker) != triggerPlayer then
        set attackerId = GetUnitTypeId(attacker)

        if attackerId != 'U007' and attackerId != 'U008' and attackerId != 'E002' and attackerId != 'E001' and attackerId != 'AVFV' then
            if RectContainsUnit(gg_rct_Base01a, triggerUnit) or RectContainsUnit(gg_rct_Base02a, triggerUnit) or RectContainsUnit(gg_rct_Base03a, triggerUnit) then
                set grp = CreateGroup()
                call GroupEnumUnitsOfPlayer(grp, triggerPlayer, function FlagsInBasesFilter)

                if FirstOfGroup(grp) != null then
                    call DisplayTextToForce( GetPlayersAll(), "Stop" )
                    call PauseUnitBJ( true, attacker )
                    call IssueImmediateOrderBJ( attacker, "stop" )
                    call PauseUnitBJ( false, attacker )
                endif

                call DestroyGroup(grp)
                set grp = null
            endif
        endif
    endif
 
    set triggerUnit = null
    set attacker = null
    set triggerPlayer = null
endfunction

I've edited the code example a couple of times, I'm done now :p
 
Last edited:
Level 12
Joined
Dec 2, 2016
Messages
733
Oh I see, just reread the OP, you want to stop the attack whenever one of the regions contains the triggering unit OR contains a flag? Then you just need to change the "and"s to "or"s
e.g.:
JASS:
function FlagsInBasesFilter takes nothing returns boolean
    local unit u = GetFilterUnit()
    local boolean r = GetUnitTypeId(u) == 'hFlg' and (RectContainsUnit(gg_rct_Base01a, u) or RectContainsUnit(gg_rct_Base02a, u) or RectContainsUnit(gg_rct_Base03a, u))
    set u = null
    return r
endfunction

function mainMain takes nothing returns nothing
    local unit triggerUnit = GetTriggerUnit()
    local unit attacker = GetAttacker()
    local player triggerPlayer = GetOwningPlayer(triggerUnit)
    local integer attackerId
    local group grp = null
    local boolean stopAttack

    if triggerPlayer == Player(2) and GetOwningPlayer(attacker) != triggerPlayer then
        set attackerId = GetUnitTypeId(attacker)

        if attackerId != 'U007' and attackerId != 'U008' and attackerId != 'E002' and attackerId != 'E001' and attackerId != 'AVFV' then
            set stopAttack = RectContainsUnit(gg_rct_Base01a, triggerUnit) or RectContainsUnit(gg_rct_Base02a, triggerUnit) or RectContainsUnit(gg_rct_Base03a, triggerUnit)

            if not stopAttack then
                set grp = CreateGroup()
                call GroupEnumUnitsOfPlayer(grp, triggerPlayer, function FlagsInBasesFilter)

                set stopAttack = FirstOfGroup(grp) != null
 
                call DestroyGroup(grp)
                set grp = null
            endif

            if stopAttack then
                call DisplayTextToForce( GetPlayersAll(), "Stop" )
                call PauseUnitBJ( true, attacker )
                call IssueImmediateOrderBJ( attacker, "stop" )
                call PauseUnitBJ( false, attacker )
            endif
        endif
    endif
 
    set triggerUnit = null
    set attacker = null
    set triggerPlayer = null
endfunction


Well now it prevents attacks on all of the structures even outside the region.

Basically, I have a base. The base consists of 3 regions. If a player builds a flag in the base. I don't want anyone else to be able to kill their structures inside that base if the base (consisting of 3 regions) contains a flag(As well as the triggering unit). But players should be allowed to kill structures owned by that player outside the actual base/regions.
 
Level 12
Joined
Dec 2, 2016
Messages
733
I edited my last post, I initially thought you wanted to prevent the attack when one of the regions contained the triggering unit OR a flag, I've updated the code example to only prevent the attack if one of the regions contains a flag and if the triggering unit is in one of the regions.

I just tested, it's back to the original issue. When you attack the structure in the region with the flag it prevents, and anywhere else(inside the other 2 regions without the flag) will allow you to kill. Appreciate the help.
Screenshot - 90b7928a646f794e6fee8109986a76e0 - Gyazo
Screen capture - 081e3ef8b49bd5a58b9c357609420e1e - Gyazo
 
Hmm, and the flags are all owned by Player(2)?
Edit: made a quick test map, which seems to work
The barricade is the "flag" (1 HP), the knight is filtered so can always attack. The footman is stopped.
Type 1, 2 or 3 to create a "flag" in one of the regions.

JASS:
function KnightFilter takes nothing returns boolean
    return GetUnitTypeId(GetFilterUnit()) != 'hkni'
endfunction

function FlagInRegion takes nothing returns boolean
    local unit flag = GetFilterUnit()
    local real fX
    local real fY
    local boolean r = GetUnitTypeId(flag) == 'hhou' and GetUnitState(flag, UNIT_STATE_LIFE) > 0
  
    if r then
        set fX = GetUnitX(flag)
        set fY = GetUnitY(flag)
        set r = RectContainsCoords(gg_rct_R1, fX, fY) or RectContainsCoords(gg_rct_R2, fX, fY) or RectContainsCoords(gg_rct_R3, fX, fY)
    endif
  
    set flag = null
    return r
endfunction

function Trig_Test_Actions takes nothing returns boolean
    local unit attacker = GetAttacker()
    local unit victim = GetTriggerUnit()
    local player plrVictim = GetOwningPlayer(victim)
    local group grp = null
    local real vX
    local real vY
  
    if plrVictim == Player(1) and plrVictim != GetOwningPlayer(attacker) then
        set vX = GetUnitX(victim)
        set vY = GetUnitY(victim)
      
        if RectContainsCoords(gg_rct_R1, vX, vY) or RectContainsCoords(gg_rct_R2, vX, vY) or RectContainsCoords(gg_rct_R3, vX, vY) then
            set grp = CreateGroup()
            call GroupEnumUnitsOfPlayer(grp, plrVictim, function FlagInRegion)
          
            if FirstOfGroup(grp) != null then
                call BJDebugMsg("Stop")
                call PauseUnit(attacker, true)
                call IssueImmediateOrder(attacker, "stop")
                call PauseUnit(attacker, false)
            else
                call BJDebugMsg("No flag")
            endif
          
            call DestroyGroup(grp)
            set grp = null
        else
            call BJDebugMsg("Victim not in a region")
        endif
    endif
  
    set attacker = null
    set victim = null
    set plrVictim = null
  
    return false
endfunction

//===========================================================================
function InitTrig_Test takes nothing returns nothing
    set gg_trg_Test = CreateTrigger(  )
    call TriggerRegisterPlayerUnitEvent(gg_trg_Test, Player(1), EVENT_PLAYER_UNIT_ATTACKED, function KnightFilter)
    call TriggerAddCondition( gg_trg_Test, function Trig_Test_Actions )
endfunction
 

Attachments

  • FlagTest.w3m
    18.7 KB · Views: 38
Last edited:
Level 12
Joined
Dec 2, 2016
Messages
733
Hmm, and the flags are all owned by Player(2)?
Edit: made a quick test map, which seems to work
The barricade is the "flag" (1 HP), the knight is filtered so can always attack. The footman is stopped.
Type 1, 2 or 3 to create a "flag" in one of the regions.



I pretty much copy pasted the code, and modified it for my map.

JASS:
function FlagInRegion takes nothing returns boolean
    local unit flag = GetFilterUnit()
    local real fX
    local real fY
    local boolean r = GetUnitTypeId(flag) == 'hFlg' and GetUnitState(flag, UNIT_STATE_LIFE) > 0
    if r then
        set fX = GetUnitX(flag)
        set fY = GetUnitY(flag)
        set r = RectContainsCoords(gg_rct_Base01a, fX, fY) or RectContainsCoords(gg_rct_Base01b, fX, fY) or RectContainsCoords(gg_rct_Base01c, fX, fY)
    endif
    set flag = null
    return r
endfunction


function Trig_Test_Actions takes nothing returns boolean
    local unit attacker = GetAttacker()
    local unit victim = GetTriggerUnit()
    local player plrVictim = GetOwningPlayer(victim)
    local group grp = null
    local real vX
    local real vY
    if plrVictim == Player(2) and plrVictim != GetOwningPlayer(attacker) then
        set vX = GetUnitX(victim)
        set vY = GetUnitY(victim)
     
        if RectContainsCoords(gg_rct_Base01a, vX, vY) or RectContainsCoords(gg_rct_Base02a, vX, vY) or RectContainsCoords(gg_rct_Base03a, vX, vY) then
            set grp = CreateGroup()
            call GroupEnumUnitsOfPlayer(grp, plrVictim, function FlagInRegion)
         
            if FirstOfGroup(grp) != null then
                call BJDebugMsg("Stop")
                call PauseUnit(attacker, true)
                call IssueImmediateOrder(attacker, "stop")
                call PauseUnit(attacker, false)
            else
                call BJDebugMsg("No flag")
            endif
         
            call DestroyGroup(grp)
            set grp = null
        else
            call BJDebugMsg("Victim not in a region")
        endif
    endif
    set attacker = null
    set victim = null
    set plrVictim = null
    return false
endfunction




function InitTrig_TealFixer takes nothing returns nothing
    set gg_trg_TealFixer = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_TealFixer, EVENT_PLAYER_UNIT_ATTACKED )
    call TriggerAddCondition( gg_trg_TealFixer, function Trig_Test_Actions )
endfunction
Your test map works, but when I insert the code into my map with some modifications too it. You can kill all houses and no message shows up, flag and triggering unit are owned by Player(2) - Teal

Attacking unit is Player(0) - Red

Does it look like I did something wrong? ^
 
Last edited:
Two things that stand out to me:
You're registering the event for all players (TriggerRegisterAnyUnitEventBJ), but then you're stopping anything from happening for all players except for Player(2) (plrVictim == Player(2)). This means the script will only run when Player(2) is attacked, even though you're registering when any player is attacked (but it seems like you only want it to run when Player(2) is attacked).

It looks like you're essentially overwriting the trigger variable from "TealFixer" trigger (set gg_trg_TealFixer = CreateTrigger( )) from "RegisterTeal" trigger, so there might be some conflicts there. Unless this is intentional, the bottom function should probably be named "InitTrig_TealFixer" instead (the name has to be "InitTrig_TriggerName" or it won't work).

I'll have another look later.
 
Level 12
Joined
Dec 2, 2016
Messages
733
Two things that stand out to me:
You're registering the event for all players (TriggerRegisterAnyUnitEventBJ), but then you're stopping anything from happening for all players except for Player(2) (plrVictim == Player(2)). This means the script will only run when Player(2) is attacked, even though you're registering when any player is attacked (but it seems like you only want it to run when Player(2) is attacked).

It looks like you're essentially overwriting the trigger variable from "TealFixer" trigger (set gg_trg_TealFixer = CreateTrigger( )) from "RegisterTeal" trigger, so there might be some conflicts there. Unless this is intentional, the bottom function should probably be named "InitTrig_TealFixer" instead (the name has to be "InitTrig_TriggerName" or it won't work).

I'll have another look later.

Yes you were right about that, I renamed the init trigger wrong. Fixed that and now it's running, I'm however having the same issue again where it only prevents the attack of the houses in the same region as the flag. No idea why this is happening, starting to think it might be an issue with my map. I updated the code post with the errors fixed. Idk do think you can see anything wrong that would be causing this?
 
The only things I can really think of is maybe the flags aren't always owned by Player(2)? Or maybe the trigger is being disabled somewhere else?
I also notice that in FlagInRegion you are using different regions than in Trig_Test_Actions, could that have anything to do with it? Seems like FlagInRegion should be checking the same regions as Trig_Test_Actions.
 
Level 12
Joined
Dec 2, 2016
Messages
733
The only things I can really think of is maybe the flags aren't always owned by Player(2)? Or maybe the trigger is being disabled somewhere else?
I also notice that in FlagInRegion you are using different regions than in Trig_Test_Actions, could that have anything to do with it? Seems like FlagInRegion should be checking the same regions as Trig_Test_Actions.
Oh that's gotta be it, I misspelled the regions. I'll give that a test today after work thanks.
 
Level 12
Joined
Dec 2, 2016
Messages
733
No problem :)


So I'm expanding onto this code, adding for the other bases in the game. It seems that once I add more than 3 'else if' statements it gives me a parsing error. I tried to look up what 'Parse' error is but couldn't really find anything explaining it. Also I'm sure this isn't the most efficient way of doing this, sorry in advance lol I'm still in the learning stages of Jass.

Basically when I add the 4th region checks / else if statement. I get the Parse error and it highlights
JASS:
 set grp = CreateGroup()

If I remove the 4th region check it runs. If you could help me out would be appreciated! Thanks.

JASS:
function FlagInRegion takes nothing returns boolean
    local unit flag = GetFilterUnit()
    local real fX
    local real fY
    local boolean r = GetUnitTypeId(flag) == 'hFlg' and GetUnitState(flag, UNIT_STATE_LIFE) > 0
    local boolean base1
    local boolean base2
    local boolean base3
    local boolean base4

   

    if r then
        set fX = GetUnitX(flag)
        set fY = GetUnitY(flag)
        set base1 = RectContainsCoords(gg_rct_Base01a, fX, fY) or RectContainsCoords(gg_rct_Base01b, fX, fY) or RectContainsCoords(gg_rct_Base01c, fX, fY)
        set base2 = RectContainsCoords(gg_rct_Base02a, fX, fY) or RectContainsCoords(gg_rct_Base02b, fX, fY) or RectContainsCoords(gg_rct_Base02c, fX, fY) or RectContainsCoords(gg_rct_Base02d, fX, fY) or RectContainsCoords(gg_rct_Base02e, fX, fY)
        set base3 = RectContainsCoords(gg_rct_Base03a, fX, fY) or RectContainsCoords(gg_rct_Base03b, fX, fY)
        set base4 = RectContainsCoords(gg_rct_Base04a, fX, fY) or RectContainsCoords(gg_rct_Base04b, fX, fY) or RectContainsCoords(gg_rct_Base04c, fX, fY)
      



endif
 set flag = null
    return r
    return base1
    return base2
    return base3
    return base4

endfunction



function Trig_Test_Actions takes nothing returns boolean
    local unit attacker = GetAttacker()
    local unit victim = GetTriggerUnit()
    local player plrVictim = GetOwningPlayer(victim)
    local group grp = null
    local real vX
    local real vY
    if plrVictim == Player(2) and plrVictim != GetOwningPlayer(attacker) then
        set vX = GetUnitX(victim)
        set vY = GetUnitY(victim)

        if RectContainsCoords(gg_rct_Base01a, vX, vY) or RectContainsCoords(gg_rct_Base01b, vX, vY) or RectContainsCoords(gg_rct_Base01c, vX, vY) then
            set grp = CreateGroup()
            call GroupEnumUnitsOfPlayer(grp, plrVictim, function FlagInRegion)
         
            if FirstOfGroup(grp) != null then
               // call BJDebugMsg("Stop")
                call PauseUnit(attacker, true)
                call IssueImmediateOrder(attacker, "stop")
                call PauseUnit(attacker, false)
            else
                //call BJDebugMsg("No flag")
            endif
         
            call DestroyGroup(grp)
            set grp = null
           
        elseif RectContainsCoords(gg_rct_Base02a, vX, vY) or RectContainsCoords(gg_rct_Base02b, vX, vY) or RectContainsCoords(gg_rct_Base02c, vX, vY) or RectContainsCoords(gg_rct_Base02d, vX, vY) or RectContainsCoords(gg_rct_Base02e, vX, vY) then
           set grp = CreateGroup()
            call GroupEnumUnitsOfPlayer(grp, plrVictim, function FlagInRegion)
         
            if FirstOfGroup(grp) != null then
              //  call BJDebugMsg("Stop")
                call PauseUnit(attacker, true)
                call IssueImmediateOrder(attacker, "stop")
                call PauseUnit(attacker, false)
            else
              //  call BJDebugMsg("No flag")
            endif
         
            call DestroyGroup(grp)
            set grp = null
                     
        elseif RectContainsCoords(gg_rct_Base03a, vX, vY) or RectContainsCoords(gg_rct_Base03b, vX, vY) then
           set grp = CreateGroup()
            call GroupEnumUnitsOfPlayer(grp, plrVictim, function FlagInRegion)
         
            if FirstOfGroup(grp) != null then
             //   call BJDebugMsg("Stop")
                call PauseUnit(attacker, true)
                call IssueImmediateOrder(attacker, "stop")
                call PauseUnit(attacker, false)
            else
               // call BJDebugMsg("No flag")
            endif
         
            call DestroyGroup(grp)
            set grp = null
                     
                     
 elseif RectContainsCoords(gg_rct_Base04a, vX, vY) or RectContainsCoords(gg_rct_Base04b, vX, vY) or RectContainsCoords(gg_rct_Base04c, vX, vY) then
           set grp = CreateGroup()
            call GroupEnumUnitsOfPlayer(grp, plrVictim, function FlagInRegion)
         
            if FirstOfGroup(grp) != null then
            DisplayTextToForce( attacker, "This base is claimed!" )
                call PauseUnit(attacker, true)
                call IssueImmediateOrder(attacker, "stop")
                call PauseUnit(attacker, false)
            else
               
            endif
         
            call DestroyGroup(grp)
            set grp = null
           
             endif
    endif
    set attacker = null
    set victim = null
    set plrVictim = null
    return false
endfunction




function InitTrig_TealFixer takes nothing returns nothing
    set gg_trg_TealFixer = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_TealFixer, EVENT_PLAYER_UNIT_ATTACKED )
    call TriggerAddCondition( gg_trg_TealFixer, function Trig_Test_Actions )
endfunction
 
You have an extra endif:
JASS:
elseif RectContainsCoords(gg_rct_Base04a, vX, vY) or RectContainsCoords(gg_rct_Base04b, vX, vY) or RectContainsCoords(gg_rct_Base04c, vX, vY) then
           set grp = CreateGroup()
            call GroupEnumUnitsOfPlayer(grp, plrVictim, function FlagInRegion)
        
            if FirstOfGroup(grp) != null then
            DisplayTextToForce( attacker, "This base is claimed!" )
                call PauseUnit(attacker, true)
                call IssueImmediateOrder(attacker, "stop")
                call PauseUnit(attacker, false)
            else
              
            endif
        
            call DestroyGroup(grp)
            set grp = null
          
             endif // <-- remove this one
    endif

Btw, not sure what you're doing in your first function:
JASS:
    return r // Everything after this will never execute
    return base1
    return base2
    return base3
    return base4
 
Level 12
Joined
Dec 2, 2016
Messages
733
You have an extra endif:
JASS:
elseif RectContainsCoords(gg_rct_Base04a, vX, vY) or RectContainsCoords(gg_rct_Base04b, vX, vY) or RectContainsCoords(gg_rct_Base04c, vX, vY) then
           set grp = CreateGroup()
            call GroupEnumUnitsOfPlayer(grp, plrVictim, function FlagInRegion)
       
            if FirstOfGroup(grp) != null then
            DisplayTextToForce( attacker, "This base is claimed!" )
                call PauseUnit(attacker, true)
                call IssueImmediateOrder(attacker, "stop")
                call PauseUnit(attacker, false)
            else
             
            endif
       
            call DestroyGroup(grp)
            set grp = null
         
             endif // <-- remove this one
    endif

Btw, not sure what you're doing in your first function:
JASS:
    return r // Everything after this will never execute
    return base1
    return base2
    return base3
    return base4

If I remove that, it gives me an error saying Missing endblock.

JASS:
if plrVictim == Player(2) and plrVictim != GetOwningPlayer(attacker) then
        set vX = GetUnitX(victim)
        set vY = GetUnitY(victim)

        if RectContainsCoords(gg_rct_Base01a, vX, vY) or RectContainsCoords(gg_rct_Base01b, vX, vY) or RectContainsCoords(gg_rct_Base01c, vX, vY) then
            set grp = CreateGroup()
            call GroupEnumUnitsOfPlayer(grp, plrVictim, function FlagInRegion)

These 2 would require the endif.

And I'm trying to check if those regions contain the flag. Do I need to create multiple functions to check for each base, to return the boolean?
 
Ah, right, I forgot about the first if statement. The indentation is a bit confusing.
I checked again, I think this must be it, you're missing a call keyword:
JASS:
            if FirstOfGroup(grp) != null then
            DisplayTextToForce( attacker, "This base is claimed!" ) // <-- add "call" at the front
                call PauseUnit(attacker, true)
                call IssueImmediateOrder(attacker, "stop")
                call PauseUnit(attacker, false)
            else
          
            endif

For the first function, change it to this:

JASS:
function FlagInRegion takes nothing returns boolean
    local unit flag = GetFilterUnit()
    local real fX
    local real fY
    local boolean r = GetUnitTypeId(flag) == 'hFlg' and GetUnitState(flag, UNIT_STATE_LIFE) > 0
    local boolean base1
    local boolean base2
    local boolean base3
    local boolean base4

 

    if r then
        set fX = GetUnitX(flag)
        set fY = GetUnitY(flag)
        set base1 = RectContainsCoords(gg_rct_Base01a, fX, fY) or RectContainsCoords(gg_rct_Base01b, fX, fY) or RectContainsCoords(gg_rct_Base01c, fX, fY)
        set base2 = RectContainsCoords(gg_rct_Base02a, fX, fY) or RectContainsCoords(gg_rct_Base02b, fX, fY) or RectContainsCoords(gg_rct_Base02c, fX, fY) or RectContainsCoords(gg_rct_Base02d, fX, fY) or RectContainsCoords(gg_rct_Base02e, fX, fY)
        set base3 = RectContainsCoords(gg_rct_Base03a, fX, fY) or RectContainsCoords(gg_rct_Base03b, fX, fY)
        set base4 = RectContainsCoords(gg_rct_Base04a, fX, fY) or RectContainsCoords(gg_rct_Base04b, fX, fY) or RectContainsCoords(gg_rct_Base04c, fX, fY)
 
        set r = base1 or base2 or base3 or base4 // change "or" to "and" depending on your needs


endif
 set flag = null
    return r

endfunction

or better yet:

JASS:
function FlagInRegion takes nothing returns boolean
    local unit flag = GetFilterUnit()
    local real fX
    local real fY
    local boolean r = GetUnitTypeId(flag) == 'hFlg' and GetUnitState(flag, UNIT_STATE_LIFE) > 0

 

    if r then
        set fX = GetUnitX(flag)
        set fY = GetUnitY(flag)
        set r = RectContainsCoords(gg_rct_Base01a, fX, fY) or RectContainsCoords(gg_rct_Base01b, fX, fY) or RectContainsCoords(gg_rct_Base01c, fX, fY)
    
        // remove the "not" keywords if ALL bases must contain the flag
        if not r then
           set r = RectContainsCoords(gg_rct_Base02a, fX, fY) or RectContainsCoords(gg_rct_Base02b, fX, fY) or RectContainsCoords(gg_rct_Base02c, fX, fY) or RectContainsCoords(gg_rct_Base02d, fX, fY) or RectContainsCoords(gg_rct_Base02e, fX, fY)

            if not r then
                set r = RectContainsCoords(gg_rct_Base03a, fX, fY) or RectContainsCoords(gg_rct_Base03b, fX, fY)

                if not r then
                   set r = RectContainsCoords(gg_rct_Base04a, fX, fY) or RectContainsCoords(gg_rct_Base04b, fX, fY) or RectContainsCoords(gg_rct_Base04c, fX, fY)
                endif
            endif
        endif


endif
 set flag = null
    return r

endfunction
 
Last edited:
Level 12
Joined
Dec 2, 2016
Messages
733
Ah, right, I forgot about the first if statement. The indentation is a bit confusing.
I checked again, I think this must be it, you're missing a call keyword:
JASS:
            if FirstOfGroup(grp) != null then
            DisplayTextToForce( attacker, "This base is claimed!" ) // <-- add "call" at the front
                call PauseUnit(attacker, true)
                call IssueImmediateOrder(attacker, "stop")
                call PauseUnit(attacker, false)
            else
         
            endif

For the first function, change it to this:

JASS:
function FlagInRegion takes nothing returns boolean
    local unit flag = GetFilterUnit()
    local real fX
    local real fY
    local boolean r = GetUnitTypeId(flag) == 'hFlg' and GetUnitState(flag, UNIT_STATE_LIFE) > 0
    local boolean base1
    local boolean base2
    local boolean base3
    local boolean base4

 

    if r then
        set fX = GetUnitX(flag)
        set fY = GetUnitY(flag)
        set base1 = RectContainsCoords(gg_rct_Base01a, fX, fY) or RectContainsCoords(gg_rct_Base01b, fX, fY) or RectContainsCoords(gg_rct_Base01c, fX, fY)
        set base2 = RectContainsCoords(gg_rct_Base02a, fX, fY) or RectContainsCoords(gg_rct_Base02b, fX, fY) or RectContainsCoords(gg_rct_Base02c, fX, fY) or RectContainsCoords(gg_rct_Base02d, fX, fY) or RectContainsCoords(gg_rct_Base02e, fX, fY)
        set base3 = RectContainsCoords(gg_rct_Base03a, fX, fY) or RectContainsCoords(gg_rct_Base03b, fX, fY)
        set base4 = RectContainsCoords(gg_rct_Base04a, fX, fY) or RectContainsCoords(gg_rct_Base04b, fX, fY) or RectContainsCoords(gg_rct_Base04c, fX, fY)
 
        set r = base1 or base2 or base3 or base4 // change "or" to "and" depending on your needs


endif
 set flag = null
    return r

endfunction

or better yet:

JASS:
function FlagInRegion takes nothing returns boolean
    local unit flag = GetFilterUnit()
    local real fX
    local real fY
    local boolean r = GetUnitTypeId(flag) == 'hFlg' and GetUnitState(flag, UNIT_STATE_LIFE) > 0

 

    if r then
        set fX = GetUnitX(flag)
        set fY = GetUnitY(flag)
        set r = RectContainsCoords(gg_rct_Base01a, fX, fY) or RectContainsCoords(gg_rct_Base01b, fX, fY) or RectContainsCoords(gg_rct_Base01c, fX, fY)
   
        // remove the "not" keywords if ALL bases must contain the flag
        if not r then
           set r = RectContainsCoords(gg_rct_Base02a, fX, fY) or RectContainsCoords(gg_rct_Base02b, fX, fY) or RectContainsCoords(gg_rct_Base02c, fX, fY) or RectContainsCoords(gg_rct_Base02d, fX, fY) or RectContainsCoords(gg_rct_Base02e, fX, fY)

            if not r then
                set r = RectContainsCoords(gg_rct_Base03a, fX, fY) or RectContainsCoords(gg_rct_Base03b, fX, fY)

                if not r then
                   set r = RectContainsCoords(gg_rct_Base04a, fX, fY) or RectContainsCoords(gg_rct_Base04b, fX, fY) or RectContainsCoords(gg_rct_Base04c, fX, fY)
                endif
            endif
        endif


endif
 set flag = null
    return r

endfunction

Yep that was the issue, and alright I'll do that thanks for the help!
 
No problem :)

Actually, this is probably a better way to write it (functionally pretty much the same but easier on the eyes):
JASS:
        set r = RectContainsCoords(gg_rct_Base01a, fX, fY) or RectContainsCoords(gg_rct_Base01b, fX, fY) or RectContainsCoords(gg_rct_Base01c, fX, fY)
        set r = r or RectContainsCoords(gg_rct_Base02a, fX, fY) or RectContainsCoords(gg_rct_Base02b, fX, fY) or RectContainsCoords(gg_rct_Base02c, fX, fY) or RectContainsCoords(gg_rct_Base02d, fX, fY) or RectContainsCoords(gg_rct_Base02e, fX, fY)
        set r = r or RectContainsCoords(gg_rct_Base03a, fX, fY) or RectContainsCoords(gg_rct_Base03b, fX, fY)
        set r = r or RectContainsCoords(gg_rct_Base04a, fX, fY) or RectContainsCoords(gg_rct_Base04b, fX, fY) or RectContainsCoords(gg_rct_Base04c, fX, fY)
 
Level 12
Joined
Dec 2, 2016
Messages
733
No problem :)

Actually, this is probably a better way to write it (functionally pretty much the same but easier on the eyes):
JASS:
        set r = RectContainsCoords(gg_rct_Base01a, fX, fY) or RectContainsCoords(gg_rct_Base01b, fX, fY) or RectContainsCoords(gg_rct_Base01c, fX, fY)
        set r = r or RectContainsCoords(gg_rct_Base02a, fX, fY) or RectContainsCoords(gg_rct_Base02b, fX, fY) or RectContainsCoords(gg_rct_Base02c, fX, fY) or RectContainsCoords(gg_rct_Base02d, fX, fY) or RectContainsCoords(gg_rct_Base02e, fX, fY)
        set r = r or RectContainsCoords(gg_rct_Base03a, fX, fY) or RectContainsCoords(gg_rct_Base03b, fX, fY)
        set r = r or RectContainsCoords(gg_rct_Base04a, fX, fY) or RectContainsCoords(gg_rct_Base04b, fX, fY) or RectContainsCoords(gg_rct_Base04c, fX, fY)


So I just tested it, it's all running but basically if the triggering unit is inside one of the base regions and the flag is not it will say "Base is claimed"
I guess the Flaginregion function isn't working properly.
 
Ah right, so I'm guessing you want it to return true only if the flag is in the same base as the triggering unit? In that case you will have to have to write a separate FlagInRegion function for each base.

JASS:
function FlagInBase1 takes nothing returns boolean
    local unit flag = GetFilterUnit()
    local real fX
    local real fY
    local boolean r = GetUnitTypeId(flag) == 'hFlg' and GetUnitState(flag, UNIT_STATE_LIFE) > 0

 

    if r then
        set fX = GetUnitX(flag)
        set fY = GetUnitY(flag)
        set r = RectContainsCoords(gg_rct_Base01a, fX, fY) or RectContainsCoords(gg_rct_Base01b, fX, fY) or RectContainsCoords(gg_rct_Base01c, fX, fY)
    endif

    set flag = null
    return r

endfunction

function FlagInBase2 takes nothing returns boolean
    local unit flag = GetFilterUnit()
    local real fX
    local real fY
    local boolean r = GetUnitTypeId(flag) == 'hFlg' and GetUnitState(flag, UNIT_STATE_LIFE) > 0

 

    if r then
        set fX = GetUnitX(flag)
        set fY = GetUnitY(flag)
        set r = RectContainsCoords(gg_rct_Base02a, fX, fY) or RectContainsCoords(gg_rct_Base02b, fX, fY) or RectContainsCoords(gg_rct_Base02c, fX, fY) or RectContainsCoords(gg_rct_Base02d, fX, fY) or RectContainsCoords(gg_rct_Base02e, fX, fY)
    endif

    set flag = null
    return r

endfunction
etc.
 
Status
Not open for further replies.
Top