HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Please help me with this JASS trigger

05-09-2006, 03:17 PM#1
grupoapunte
Hello well i have a problem with this trigger which is not working as it should, ok fist of all ill explain some concepts i have:

1. when an event triggers a trigger will run as we all know (if there is one)
2. if that event happends again while the first trigger is still runing as far as i know a copy of that trigger (thread) will handle the event, ok here we have 2 equal triggers runing (an example would be a hero revive trigger with a polledwait so that there will only be 1 trigger (typed) to handle all the heros, so it will copy itself if it must revive another one while its already reviving one )

Ok my trigger is based on those concepts, when a player goes over certain region the trigger checks the conditions and starts a CUSTOM polledwait which checks every 0.10 secs "bj_POLLED_WAIT_INTERVAL" if the unit stills in that region and after 15 secs it gives all the units in the region to that player's team.

The map has 4 bases which can be taken, and the trigger handles them all and it should be able to run more threads if someone else steps on another base, but for some reason it can only handle 1 at the time.

In the trigger you will see a few globals which are just counters that shouldnt be a problem, and a few conditions (some are mixed but thats not a problem, small mistake i wont fix yet) that control that the base is not already owned by that player, that the player is a hero, and that he is the only one trying to take that base.

This is the trigger:

Collapse JASS:

//===========================================================================
// Trigger: Take Base
//===========================================================================
function Trig_Take_Base_Conditions takes nothing returns boolean
    if ( IsUnitType(GetTriggerUnit(), UNIT_TYPE_HERO) == true ) then
        return true
    endif
    return false
endfunction

function TakeBaseTimer takes unit u, rect r, real duration, string str returns boolean
    local timer t = CreateTimer()
    local timerdialog tw = CreateTimerDialogBJ(t, str)
    local real timeRemaining
    local location l = GetRectCenter(r)
    
    call PingMinimapLocForForceEx( udg_Players, l, 2.00, bj_MINIMAPPINGSTYLE_ATTACK, 100, 0.00, 0.00 )
    call RemoveLocation(l)
    set l = null
    call TimerStart(t, duration, false, null)
    
    loop
        set timeRemaining = TimerGetRemaining(t)
        exitwhen timeRemaining <= 0
        
        call TriggerSleepAction(0.10)
        
        if (RectContainsUnit(r, u) == false) then
            call PauseTimer(t)
            call DestroyTimer(t)
            call DestroyTimerDialogBJ(tw)
            set t = null
            set tw = null
            return false
        endif
    endloop
    
    call PauseTimer(t)
    call DestroyTimer(t)
    call DestroyTimerDialogBJ(tw)
    set t = null
    set tw = null
    return true
endfunction

function FilterFunc takes nothing returns boolean
    return ( IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == true )
endfunction

function GroupActions takes nothing returns nothing
    call SetUnitOwner( GetEnumUnit(), Player((udg_Team_Of_Player[GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))] * 6)-1), true )
endfunction

function Trig_Take_Base_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local integer playerNum = GetConvertedPlayerId(GetOwningPlayer(u))
    local integer baseNum
    local rect baseTakeRect
    local rect baseUnitsRect
    local group g
    local boolean bool
    local string str
    local conditionfunc filt = null 
    
    if (RectContainsUnit(gg_rct_Base1, u) == true) then
        set baseTakeRect = gg_rct_Base1
        set baseUnitsRect = gg_rct_Base1_Units
        set baseNum = 1
        set str = "|c00ff0000LS Base|r"
        call DisplayTextToForce( udg_Players, ( "|c00ffff00" + GetPlayerName(GetOwningPlayer(u)) + " is trying to take the left side base!|r" ) )
    endif
    if (RectContainsUnit(gg_rct_Base2, u) == true) then
        set baseTakeRect = gg_rct_Base2
        set baseUnitsRect = gg_rct_Base2_Units
        set baseNum = 2
        set str = "|c00ff0000LM Base|r"
        call DisplayTextToForce( udg_Players, ( "|c00ffff00" + GetPlayerName(GetOwningPlayer(u)) + " is trying to take the lower middle base!|r" ) )
    endif
    if (RectContainsUnit(gg_rct_Base3, u) == true) then
        set baseTakeRect = gg_rct_Base3
        set baseUnitsRect = gg_rct_Base3_Units
        set baseNum = 3
        set str = "|c00ff0000UM Base|r"
        call DisplayTextToForce( udg_Players, ( "|c00ffff00" + GetPlayerName(GetOwningPlayer(u)) + " is trying to take the upper middle base!|r" ) )
    endif
    if (RectContainsUnit(gg_rct_Base4, u) == true) then
        set baseTakeRect = gg_rct_Base4
        set baseUnitsRect = gg_rct_Base4_Units
        set baseNum = 4
        set str = "|c00ff0000RS Base|r"
        call DisplayTextToForce( udg_Players, ( "|c00ffff00" + GetPlayerName(GetOwningPlayer(u)) + " is trying to take the right side base!|r" ) )
    endif
    
    set g = GetUnitsInRectAll(baseTakeRect)
    if ((CountUnitsInGroup(g) == 1) and (udg_Team_Of_Player[playerNum] != udg_TeamBaseOwner[baseNum])) then
        set bool = TakeBaseTimer(u, baseTakeRect, 15.00, str)
    endif
    
    call DestroyGroup(g)
    
    if (bool == true) then
        set udg_TeamBaseOwner[baseNum] = udg_Team_Of_Player[playerNum]
        set filt = Condition(function FilterFunc)
        set g = GetUnitsInRectMatching(baseUnitsRect, filt)
        
        call ForGroupBJ( g, function GroupActions )
        
        call AdjustPlayerStateBJ( 250, GetOwningPlayer(u), PLAYER_STATE_RESOURCE_GOLD )
        call DisplayTextToForce( udg_Players, ( "|c00ffff00" + GetPlayerName(GetOwningPlayer(u)) + " has the base under control! plus 250 gold for taking it!|r" ) )
        if ( playerNum <= 6 ) then
            set udg_BasesLight = ( udg_BasesLight + 1 )
            set udg_BasesDark = ( udg_BasesDark - 1 )
        else
            set udg_BasesLight = ( udg_BasesLight - 1 )
            set udg_BasesDark = ( udg_BasesDark + 1 )
        endif
        set udg_Ladder_BasesTaken[playerNum] = ( udg_Ladder_BasesTaken[playerNum] + 1 )
        
        call DestroyGroup(g)
        call DestroyCondition(filt)
        set g = null
        set filt = null
    endif
    
    set u = null
    set baseTakeRect = null
    set baseUnitsRect = null
endfunction

//===========================================================================
function InitTrig_Take_Base takes nothing returns nothing
    set gg_trg_Take_Base = CreateTrigger(  )
    call TriggerRegisterEnterRectSimple( gg_trg_Take_Base, gg_rct_Base1 )
    call TriggerRegisterEnterRectSimple( gg_trg_Take_Base, gg_rct_Base2 )
    call TriggerRegisterEnterRectSimple( gg_trg_Take_Base, gg_rct_Base3 )
    call TriggerRegisterEnterRectSimple( gg_trg_Take_Base, gg_rct_Base4 )
    call TriggerAddCondition( gg_trg_Take_Base, Condition( function Trig_Take_Base_Conditions ) )
    call TriggerAddAction( gg_trg_Take_Base, function Trig_Take_Base_Actions )
endfunction


I made a test trigger to see if it works, what i do is order 4 diferent units to go one to each base (the units match the conditions needed) but the screen shows only one timer

Thanks a lot, if you need extra info just ask ill be refreshing the thread every 5 or 10 minutes

EDIT:

Also if i missed to fix a memory leak plz tell me, thanks
05-15-2006, 11:43 AM#2
grupoapunte
At least tell me if my concepts are right:

1. when an event triggers a trigger will run as we all know (if there is one)
2. if that event happends again while the first trigger is still runing as far as i know a copy of that trigger (thread) will handle the event, ok here we have 2 equal triggers runing (an example would be a hero revive trigger with a polledwait so that there will only be 1 trigger (typed) to handle all the heros, so it will copy itself if it must revive another one while its already reviving one )

Thanks

Edited by Blade.dk. Reason: Double posting.