A Brand New Custom Hero Limitation System.

Level 13
Joined
Jun 15, 2016
Messages
743
I want to ask if anyone can create a good trigger (for one race) and post it here which meets all these following requirements:

1. Each player can only have maximum 3 heroes for training and must be trained using Altars* (Not Tavern).
2. Each player before can upgrade the main building to new tier, must train at least one hero for each tier. For Human example, before upgrade to Keep building, one hero must be summoned or before upgrade to Castle building, two heroes must be summoned.
3. Each player can buy only one bonus hero in Tavern which can freely buy anytime without relying on any requirements.

4.***This system do not use "Dependency Equivalent - Hero" in "Game-play Constant"***.
5.***This system do not use "Techtree- Requirements - Tier ?" under each Hero"***.
6.***This system only use GUI trigger***.

And make sure that "NO" problem leaking happens such as:
1. Player can tricky train one hero if they try to build new main building even when they upgraded a main building or trained all 3 heroes.
 
Level 8
Joined
Jun 13, 2012
Messages
345
You don't need triggers for those thing i think.You just need to edit units and their building requirements i think but i will check it out now.

wanted to say first one is by default but then i read the third one xD yeah i think i can make smth out of it ;p brb
 
Last edited:
Level 13
Joined
Jun 15, 2016
Messages
743
You don't need triggers for those thing i think.You just need to edit units and their building requirements i think but i will check it out now.

wanted to say first one is by default but then i read the third one xD yeah i think i can make smth out of it ;p brb

Thank you, I appreciate all helps. To be honest, i would like to see many options and opinions from different people and choose the best.
 
Level 8
Joined
Jun 13, 2012
Messages
345
Last edited:
Level 17
Joined
Nov 21, 2012
Messages
836
It will be more comfortable for me to post code and description here;]
I learn from Unregret that there is hero limit in gamplay Constants: 52 heroes. Yesterday I wrote this system that basically replaced this:
  • init
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Player - Limit training of Heroes to 3 for Player 1 (Red)
for a mapper who wants to use more then 52 heroes.

how it works:
it uses dummy unit as a requirement for all heroes /one dummy per player/, called "max3heroes"
to block availability I change dummy owner to neutral passive player,
to allow train a hero I change back dummy owner to player,
system tracks for each player: number of heroes, tier2/tier3/altars structures, begins/cancles/finishes training a hero, events: unit sold, unit finishes construction, finishes an upgrade, structure dies

how to use:
  1. copy unit "max3heroes"
  2. copy 2 triggers
  3. set variable "HeroLimit_dummyId" inside Variables (Ctrl+B) to unit-type "max3heroes"
  4. in Gameplay Constants Techtree-Dependency Equivalents-Hero remove all heroes except one hero that won't be used in game
  5. add list of: altars/tier2/tier3 structures in configuration gui trigger
  6. in Object Editor to all heroes add in field "Techtree-Requirements" unit named "max3heroes"
configuration:
  • HeroLimitSystemConfig
    • Events
    • Map initialization
    • Conditions
    • Actions
    • -------- - 4 following lines are for create variables only, do not enable them - --------
    • Set HeroLimit_dummy[1] = No unit
    • Set HeroLimit_heroCount[1] = 0
    • Set HeroLimit_tier2Group[12] = (Units in (Playable map area))
    • Set HeroLimit_tier3Group[12] = (Units in (Playable map area))
    • Set HeroLimit_workingAltars[12] = (Units in (Playable map area))
    • -------- Limitations: all Altars are suppose to train heroes only --------
    • -------- ---------- --------
    • -------- Installation: --------
    • -------- copy this trigger and HeroLimitSystem trigger --------
    • -------- copy dummy unit named: "max3heroes" --------
    • -------- - "max3heroes" is a dummy unit used to emulate avialability of heroes - --------
    • -------- set Unit-Type variable "HeroLimit_dummyId" inside Variables (Ctrl+B) to unit-type "max3heroes" --------
    • -------- ---------- --------
    • -------- from Gameplay Constants Techtree-Dependency Equivalents-Hero -->remove<-- all heroes --------
    • -------- from Gameplay Constants Techtree-Dependency Equivalents-Hero -->add<--one hero that you are not going to use --------
    • -------- in Object Editor to all heroes add in field "Techtree-Requirements" unit named "max3heroes" --------
    • -------- ---------- --------
    • -------- add all Altars (hero train structures) here --------
    • Set HeroLimit_altar[1] = Altar of Kings
    • Set HeroLimit_altar[2] = Altar of Storms
    • Set HeroLimit_altar[3] = Altar of Darkness
    • -------- ---------- --------
    • -------- - add all tier2 buildings here - --------
    • Set HeroLimit_tier2[1] = Keep
    • Set HeroLimit_tier2[2] = Stronghold
    • Set HeroLimit_tier2[3] = Halls of the Dead
    • Set HeroLimit_tier2[4] = Tree of Ages
    • -------- ---------- --------
    • -------- - add all tier3 buildings here - --------
    • Set HeroLimit_tier3[1] = Castle
    • Set HeroLimit_tier3[2] = Fortress
    • Set HeroLimit_tier3[3] = Black Citadel
    • Set HeroLimit_tier3[4] = Tree of Eternity
    • -------- ---------- --------
    • Custom script: call ExecuteFunc("HeroLimit_CheckPreplaced")
    • -------- ---------- --------
JASS:
//-------------------------------------------------------------------------------
function SetHeroAvailability takes integer i returns nothing
    local integer tier2 = CountUnitsInGroup(udg_HeroLimit_tier2Group[i])
    local integer tier3 = CountUnitsInGroup(udg_HeroLimit_tier3Group[i])   
    if udg_HeroLimit_heroCount[i] == 3 then
        call SetUnitOwner( udg_HeroLimit_dummy[i], Player(15), false )
    elseif udg_HeroLimit_heroCount[i]==2 then
        if tier3==0 then
            call SetUnitOwner( udg_HeroLimit_dummy[i], Player(15), false )
        else
            call SetUnitOwner( udg_HeroLimit_dummy[i], Player(i), false )
        endif
    elseif udg_HeroLimit_heroCount[i]==1 then
        if tier2==0 then
            call SetUnitOwner( udg_HeroLimit_dummy[i], Player(15), false )
        else
            call SetUnitOwner( udg_HeroLimit_dummy[i], Player(i), false )
        endif
    elseif udg_HeroLimit_heroCount[i]==0 then
        call SetUnitOwner( udg_HeroLimit_dummy[i], Player(i), false )
    endif
endfunction
//-------------------------------------------------------------------------------
function IsAnAltar takes integer unitId returns boolean
    local integer a=1
    loop
        exitwhen udg_HeroLimit_altar[a] == null
        if unitId == udg_HeroLimit_altar[a] then
            return true
        endif
        set a=a+1
    endloop
    return false
endfunction
//-------------------------------------------------------------------------------
function IsTier2 takes integer unitId returns boolean
    local integer a=1
    loop
        exitwhen udg_HeroLimit_tier2[a] == null
        if unitId == udg_HeroLimit_tier2[a] then
            return true
        endif
        set a=a+1
    endloop
    return false
endfunction
//-------------------------------------------------------------------------------
function IsTier3 takes integer unitId returns boolean
    local integer a=1
    loop
        exitwhen udg_HeroLimit_tier3[a] == null
        if unitId == udg_HeroLimit_tier3[a] then
            return true
        endif
        set a=a+1
    endloop
    return false
endfunction
//--------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------
function Trig_Training_Actions takes nothing returns nothing
    local integer h = GetHandleId(GetTriggerEventId())
    local unit u = GetTriggerUnit()
    local integer unitId = GetUnitTypeId(u)
    local integer playerId = GetPlayerId(GetOwningPlayer(u))
    // [32]begins ------------------------------------------------------------
    if h==32 and IsAnAltar(unitId) then
        call SetUnitOwner(udg_HeroLimit_dummy[playerId], Player(15), false) //block, change to passive owner
        set udg_HeroLimit_heroDuringTrain[playerId] = udg_HeroLimit_heroDuringTrain[playerId] + 1
        call GroupAddUnit(udg_HeroLimit_workingAltars[playerId], u)
    // [33]cancels --------------------------------------------------------
    elseif h==33 and IsAnAltar(unitId) then
        set udg_HeroLimit_heroDuringTrain[playerId] = udg_HeroLimit_heroDuringTrain[playerId] - 1
        call GroupRemoveUnit(udg_HeroLimit_workingAltars[playerId], GetTriggerUnit())
        call SetHeroAvailability(playerId)   
    // [34]finishes -------------------------------------------------------
    elseif h==34 and IsUnitType(GetTrainedUnit(), UNIT_TYPE_HERO) then
        set udg_HeroLimit_heroCount[playerId] = udg_HeroLimit_heroCount[playerId] + 1
        set udg_HeroLimit_heroDuringTrain[playerId] = udg_HeroLimit_heroDuringTrain[playerId] - 1
        call GroupRemoveUnit(udg_HeroLimit_workingAltars[playerId], GetTriggerUnit())
        call SetHeroAvailability(playerId)
    endif   
    set u=null
endfunction
//--------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------
function Trig_SoldConstructedUpgradesDies_Act takes nothing returns boolean
    local integer h = GetHandleId(GetTriggerEventId())
    local unit u = null
    local integer unitId
    local integer playerId
   
    if h==269 then // [269]unit sells a unit (tavern) ---------------------------------------------
        set u = GetSoldUnit()
        set playerId = GetPlayerId(GetOwningPlayer(u))
        if IsUnitType(u, UNIT_TYPE_HERO) then
            set udg_HeroLimit_heroCount[playerId] = udg_HeroLimit_heroCount[playerId] + 1
            call SetHeroAvailability(playerId)
        endif
       
    elseif h==28 then // [28]finishes construction ---------------------------------------------
        set u = GetConstructedStructure()
        set unitId = GetUnitTypeId(u)
        set playerId = GetPlayerId(GetOwningPlayer(u))
        if IsTier2(unitId) then
            call GroupAddUnit(udg_HeroLimit_tier2Group[playerId], u)
            if udg_HeroLimit_heroDuringTrain[playerId] == 0 then
                call SetHeroAvailability(playerId)
            endif
        elseif IsTier3(unitId) then
            call GroupAddUnit(udg_HeroLimit_tier3Group[playerId], u)
            if udg_HeroLimit_heroDuringTrain[playerId] == 0 then
                call SetHeroAvailability(playerId)
            endif
        endif       
       
    elseif h==31 then // [31]finishes an upgrade -----------------------------------------------
        set u = GetTriggerUnit()
        set unitId = GetUnitTypeId(u)
        set playerId = GetPlayerId(GetOwningPlayer(u))
        if IsTier2(unitId) then
            call GroupAddUnit(udg_HeroLimit_tier2Group[playerId], u)
            if udg_HeroLimit_heroDuringTrain[playerId] == 0 then
                call SetHeroAvailability(playerId)
            endif
        elseif IsTier3(unitId) then
            call GroupAddUnit(udg_HeroLimit_tier3Group[playerId], u)
            if udg_HeroLimit_heroDuringTrain[playerId] == 0 then
                call SetHeroAvailability(playerId)
            endif
        endif
   
    elseif h==20 then // [20]structures dies -----------------------------------------------   
        set u = GetDyingUnit()
        set playerId = GetPlayerId(GetOwningPlayer(u))
        if IsUnitInGroup(u, udg_HeroLimit_tier2Group[playerId]) or IsUnitInGroup(u, udg_HeroLimit_tier3Group[playerId]) then
            call GroupRemoveUnit(udg_HeroLimit_tier2Group[playerId], u)
            call GroupRemoveUnit(udg_HeroLimit_tier3Group[playerId], u)
            call SetHeroAvailability(playerId)           
        elseif IsUnitInGroup(u, udg_HeroLimit_workingAltars[playerId]) then
            set udg_HeroLimit_heroDuringTrain[playerId] = udg_HeroLimit_heroDuringTrain[playerId] - 1
            call GroupRemoveUnit(udg_HeroLimit_workingAltars[playerId], GetTriggerUnit())
            call SetHeroAvailability(playerId)
        endif
    endif
    set u=null
    return false
endfunction
//===========================================
//look for preplaced heroes and structures:
function HeroLimit_CheckPreplaced takes nothing returns nothing
    local group ug = CreateGroup()
    local unit u = null
    local integer a=0
    loop // 12 players:
        exitwhen a==bj_MAX_PLAYERS //12
        //---   
        call GroupEnumUnitsOfPlayer(ug, Player(a), null)   
        loop
            set u = FirstOfGroup(ug)
            exitwhen u == null
            if IsUnitType(u, UNIT_TYPE_HERO) then
                set udg_HeroLimit_heroCount[a] = udg_HeroLimit_heroCount[a] + 1
            elseif IsTier2(GetUnitTypeId(u)) then
                call GroupAddUnit(udg_HeroLimit_tier2Group[a], u)
            elseif IsTier3(GetUnitTypeId(u)) then
                call GroupAddUnit(udg_HeroLimit_tier3Group[a], u)
            endif
            call GroupRemoveUnit(ug, u)
        endloop
        call GroupClear (ug)
        call SetHeroAvailability(a)
        //---
        set a=a+1
    endloop   
    call DestroyGroup(ug)
    set ug=null
    set u=null
endfunction
//==================================================================
//==================================================================
function InitTrig_HeroLimitSystem takes nothing returns nothing   
    local integer a=0
    local trigger t1 = CreateTrigger()
    local trigger t2 = CreateTrigger()
   
    loop
        exitwhen a==bj_MAX_PLAYERS
        set udg_HeroLimit_dummy[a] = CreateUnit(Player(a), udg_HeroLimit_dummyId, 0.00, 0.00, 0.00)
        set udg_HeroLimit_heroCount[a] = 0
        set udg_HeroLimit_heroDuringTrain[a] = 0
        set a=a+1
    endloop
   
    call TriggerRegisterAnyUnitEventBJ(t1, EVENT_PLAYER_UNIT_TRAIN_START ) //begins training a unit
    call TriggerRegisterAnyUnitEventBJ(t1, EVENT_PLAYER_UNIT_TRAIN_CANCEL ) // cancels training a unit
    call TriggerRegisterAnyUnitEventBJ(t1, EVENT_PLAYER_UNIT_TRAIN_FINISH ) // finishes training a unit
    call TriggerAddAction(t1, function Trig_Training_Actions)
   
    call TriggerRegisterAnyUnitEventBJ(t2, EVENT_PLAYER_UNIT_SELL ) // unit sells a unit
    call TriggerRegisterAnyUnitEventBJ(t2, EVENT_PLAYER_UNIT_CONSTRUCT_FINISH ) // unit finishes construction
    call TriggerRegisterAnyUnitEventBJ(t2, EVENT_PLAYER_UNIT_UPGRADE_FINISH ) // finishes an upgrade
    call TriggerRegisterAnyUnitEventBJ(t2, EVENT_PLAYER_UNIT_DEATH ) // structure dies
    call TriggerAddCondition(t2, Condition( function Trig_SoldConstructedUpgradesDies_Act))

    set t2=null
    set t1=null
endfunction
 
Level 13
Joined
Jun 15, 2016
Messages
743
It will be more comfortable for me to post code and description here;]
I learn from Unregret that there is hero limit in gamplay Constants: 52 heroes. Yesterday I wrote this system that basically replaced this:
  • init
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Player - Limit training of Heroes to 3 for Player 1 (Red)
for a mapper who wants to use more then 52 heroes.

how it works:
it uses dummy unit as a requirement for all heroes /one dummy per player/, called "max3heroes"
to block availability I change dummy owner to neutral passive player,
to allow train a hero I change back dummy owner to player,
system tracks for each player: number of heroes, tier2/tier3/altars structures, begins/cancles/finishes training a hero, events: unit sold, unit finishes construction, finishes an upgrade, structure dies

how to use:
  1. copy unit "max3heroes"
  2. copy 2 triggers
  3. set variable "HeroLimit_dummyId" inside Variables (Ctrl+B) to unit-type "max3heroes"
  4. in Gameplay Constants Techtree-Dependency Equivalents-Hero remove all heroes except one hero that won't be used in game
  5. add list of: altars/tier2/tier3 structures in configuration gui trigger
  6. in Object Editor to all heroes add in field "Techtree-Requirements" unit named "max3heroes"
configuration:
  • HeroLimitSystemConfig
    • Events
    • Map initialization
    • Conditions
    • Actions
    • -------- - 4 following lines are for create variables only, do not enable them - --------
    • Set HeroLimit_dummy[1] = No unit
    • Set HeroLimit_heroCount[1] = 0
    • Set HeroLimit_tier2Group[12] = (Units in (Playable map area))
    • Set HeroLimit_tier3Group[12] = (Units in (Playable map area))
    • Set HeroLimit_workingAltars[12] = (Units in (Playable map area))
    • -------- Limitations: all Altars are suppose to train heroes only --------
    • -------- ---------- --------
    • -------- Installation: --------
    • -------- copy this trigger and HeroLimitSystem trigger --------
    • -------- copy dummy unit named: "max3heroes" --------
    • -------- - "max3heroes" is a dummy unit used to emulate avialability of heroes - --------
    • -------- set Unit-Type variable "HeroLimit_dummyId" inside Variables (Ctrl+B) to unit-type "max3heroes" --------
    • -------- ---------- --------
    • -------- from Gameplay Constants Techtree-Dependency Equivalents-Hero -->remove<-- all heroes --------
    • -------- from Gameplay Constants Techtree-Dependency Equivalents-Hero -->add<--one hero that you are not going to use --------
    • -------- in Object Editor to all heroes add in field "Techtree-Requirements" unit named "max3heroes" --------
    • -------- ---------- --------
    • -------- add all Altars (hero train structures) here --------
    • Set HeroLimit_altar[1] = Altar of Kings
    • Set HeroLimit_altar[2] = Altar of Storms
    • Set HeroLimit_altar[3] = Altar of Darkness
    • -------- ---------- --------
    • -------- - add all tier2 buildings here - --------
    • Set HeroLimit_tier2[1] = Keep
    • Set HeroLimit_tier2[2] = Stronghold
    • Set HeroLimit_tier2[3] = Halls of the Dead
    • Set HeroLimit_tier2[4] = Tree of Ages
    • -------- ---------- --------
    • -------- - add all tier3 buildings here - --------
    • Set HeroLimit_tier3[1] = Castle
    • Set HeroLimit_tier3[2] = Fortress
    • Set HeroLimit_tier3[3] = Black Citadel
    • Set HeroLimit_tier3[4] = Tree of Eternity
    • -------- ---------- --------
    • Custom script: call ExecuteFunc("HeroLimit_CheckPreplaced")
    • -------- ---------- --------
JASS:
//-------------------------------------------------------------------------------
function SetHeroAvailability takes integer i returns nothing
    local integer tier2 = CountUnitsInGroup(udg_HeroLimit_tier2Group[i])
    local integer tier3 = CountUnitsInGroup(udg_HeroLimit_tier3Group[i])
    if udg_HeroLimit_heroCount[i] == 3 then
        call SetUnitOwner( udg_HeroLimit_dummy[i], Player(15), false )
    elseif udg_HeroLimit_heroCount[i]==2 then
        if tier3==0 then
            call SetUnitOwner( udg_HeroLimit_dummy[i], Player(15), false )
        else
            call SetUnitOwner( udg_HeroLimit_dummy[i], Player(i), false )
        endif
    elseif udg_HeroLimit_heroCount[i]==1 then
        if tier2==0 then
            call SetUnitOwner( udg_HeroLimit_dummy[i], Player(15), false )
        else
            call SetUnitOwner( udg_HeroLimit_dummy[i], Player(i), false )
        endif
    elseif udg_HeroLimit_heroCount[i]==0 then
        call SetUnitOwner( udg_HeroLimit_dummy[i], Player(i), false )
    endif
endfunction
//-------------------------------------------------------------------------------
function IsAnAltar takes integer unitId returns boolean
    local integer a=1
    loop
        exitwhen udg_HeroLimit_altar[a] == null
        if unitId == udg_HeroLimit_altar[a] then
            return true
        endif
        set a=a+1
    endloop
    return false
endfunction
//-------------------------------------------------------------------------------
function IsTier2 takes integer unitId returns boolean
    local integer a=1
    loop
        exitwhen udg_HeroLimit_tier2[a] == null
        if unitId == udg_HeroLimit_tier2[a] then
            return true
        endif
        set a=a+1
    endloop
    return false
endfunction
//-------------------------------------------------------------------------------
function IsTier3 takes integer unitId returns boolean
    local integer a=1
    loop
        exitwhen udg_HeroLimit_tier3[a] == null
        if unitId == udg_HeroLimit_tier3[a] then
            return true
        endif
        set a=a+1
    endloop
    return false
endfunction
//--------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------
function Trig_Training_Actions takes nothing returns nothing
    local integer h = GetHandleId(GetTriggerEventId())
    local unit u = GetTriggerUnit()
    local integer unitId = GetUnitTypeId(u)
    local integer playerId = GetPlayerId(GetOwningPlayer(u))
    // [32]begins ------------------------------------------------------------
    if h==32 and IsAnAltar(unitId) then
        call SetUnitOwner(udg_HeroLimit_dummy[playerId], Player(15), false) //block, change to passive owner
        set udg_HeroLimit_heroDuringTrain[playerId] = udg_HeroLimit_heroDuringTrain[playerId] + 1
        call GroupAddUnit(udg_HeroLimit_workingAltars[playerId], u)
    // [33]cancels --------------------------------------------------------
    elseif h==33 and IsAnAltar(unitId) then
        set udg_HeroLimit_heroDuringTrain[playerId] = udg_HeroLimit_heroDuringTrain[playerId] - 1
        call GroupRemoveUnit(udg_HeroLimit_workingAltars[playerId], GetTriggerUnit())
        call SetHeroAvailability(playerId)
    // [34]finishes -------------------------------------------------------
    elseif h==34 and IsUnitType(GetTrainedUnit(), UNIT_TYPE_HERO) then
        set udg_HeroLimit_heroCount[playerId] = udg_HeroLimit_heroCount[playerId] + 1
        set udg_HeroLimit_heroDuringTrain[playerId] = udg_HeroLimit_heroDuringTrain[playerId] - 1
        call GroupRemoveUnit(udg_HeroLimit_workingAltars[playerId], GetTriggerUnit())
        call SetHeroAvailability(playerId)
    endif
    set u=null
endfunction
//--------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------
function Trig_SoldConstructedUpgradesDies_Act takes nothing returns boolean
    local integer h = GetHandleId(GetTriggerEventId())
    local unit u = null
    local integer unitId
    local integer playerId

    if h==269 then // [269]unit sells a unit (tavern) ---------------------------------------------
        set u = GetSoldUnit()
        set playerId = GetPlayerId(GetOwningPlayer(u))
        if IsUnitType(u, UNIT_TYPE_HERO) then
            set udg_HeroLimit_heroCount[playerId] = udg_HeroLimit_heroCount[playerId] + 1
            call SetHeroAvailability(playerId)
        endif
 
    elseif h==28 then // [28]finishes construction ---------------------------------------------
        set u = GetConstructedStructure()
        set unitId = GetUnitTypeId(u)
        set playerId = GetPlayerId(GetOwningPlayer(u))
        if IsTier2(unitId) then
            call GroupAddUnit(udg_HeroLimit_tier2Group[playerId], u)
            if udg_HeroLimit_heroDuringTrain[playerId] == 0 then
                call SetHeroAvailability(playerId)
            endif
        elseif IsTier3(unitId) then
            call GroupAddUnit(udg_HeroLimit_tier3Group[playerId], u)
            if udg_HeroLimit_heroDuringTrain[playerId] == 0 then
                call SetHeroAvailability(playerId)
            endif
        endif 
 
    elseif h==31 then // [31]finishes an upgrade -----------------------------------------------
        set u = GetTriggerUnit()
        set unitId = GetUnitTypeId(u)
        set playerId = GetPlayerId(GetOwningPlayer(u))
        if IsTier2(unitId) then
            call GroupAddUnit(udg_HeroLimit_tier2Group[playerId], u)
            if udg_HeroLimit_heroDuringTrain[playerId] == 0 then
                call SetHeroAvailability(playerId)
            endif
        elseif IsTier3(unitId) then
            call GroupAddUnit(udg_HeroLimit_tier3Group[playerId], u)
            if udg_HeroLimit_heroDuringTrain[playerId] == 0 then
                call SetHeroAvailability(playerId)
            endif
        endif

    elseif h==20 then // [20]structures dies -----------------------------------------------
        set u = GetDyingUnit()
        set playerId = GetPlayerId(GetOwningPlayer(u))
        if IsUnitInGroup(u, udg_HeroLimit_tier2Group[playerId]) or IsUnitInGroup(u, udg_HeroLimit_tier3Group[playerId]) then
            call GroupRemoveUnit(udg_HeroLimit_tier2Group[playerId], u)
            call GroupRemoveUnit(udg_HeroLimit_tier3Group[playerId], u)
            call SetHeroAvailability(playerId)     
        elseif IsUnitInGroup(u, udg_HeroLimit_workingAltars[playerId]) then
            set udg_HeroLimit_heroDuringTrain[playerId] = udg_HeroLimit_heroDuringTrain[playerId] - 1
            call GroupRemoveUnit(udg_HeroLimit_workingAltars[playerId], GetTriggerUnit())
            call SetHeroAvailability(playerId)
        endif
    endif
    set u=null
    return false
endfunction
//===========================================
//look for preplaced heroes and structures:
function HeroLimit_CheckPreplaced takes nothing returns nothing
    local group ug = CreateGroup()
    local unit u = null
    local integer a=0
    loop // 12 players:
        exitwhen a==bj_MAX_PLAYERS //12
        //---
        call GroupEnumUnitsOfPlayer(ug, Player(a), null)
        loop
            set u = FirstOfGroup(ug)
            exitwhen u == null
            if IsUnitType(u, UNIT_TYPE_HERO) then
                set udg_HeroLimit_heroCount[a] = udg_HeroLimit_heroCount[a] + 1
            elseif IsTier2(GetUnitTypeId(u)) then
                call GroupAddUnit(udg_HeroLimit_tier2Group[a], u)
            elseif IsTier3(GetUnitTypeId(u)) then
                call GroupAddUnit(udg_HeroLimit_tier3Group[a], u)
            endif
            call GroupRemoveUnit(ug, u)
        endloop
        call GroupClear (ug)
        call SetHeroAvailability(a)
        //---
        set a=a+1
    endloop
    call DestroyGroup(ug)
    set ug=null
    set u=null
endfunction
//==================================================================
//==================================================================
function InitTrig_HeroLimitSystem takes nothing returns nothing
    local integer a=0
    local trigger t1 = CreateTrigger()
    local trigger t2 = CreateTrigger()

    loop
        exitwhen a==bj_MAX_PLAYERS
        set udg_HeroLimit_dummy[a] = CreateUnit(Player(a), udg_HeroLimit_dummyId, 0.00, 0.00, 0.00)
        set udg_HeroLimit_heroCount[a] = 0
        set udg_HeroLimit_heroDuringTrain[a] = 0
        set a=a+1
    endloop

    call TriggerRegisterAnyUnitEventBJ(t1, EVENT_PLAYER_UNIT_TRAIN_START ) //begins training a unit
    call TriggerRegisterAnyUnitEventBJ(t1, EVENT_PLAYER_UNIT_TRAIN_CANCEL ) // cancels training a unit
    call TriggerRegisterAnyUnitEventBJ(t1, EVENT_PLAYER_UNIT_TRAIN_FINISH ) // finishes training a unit
    call TriggerAddAction(t1, function Trig_Training_Actions)

    call TriggerRegisterAnyUnitEventBJ(t2, EVENT_PLAYER_UNIT_SELL ) // unit sells a unit
    call TriggerRegisterAnyUnitEventBJ(t2, EVENT_PLAYER_UNIT_CONSTRUCT_FINISH ) // unit finishes construction
    call TriggerRegisterAnyUnitEventBJ(t2, EVENT_PLAYER_UNIT_UPGRADE_FINISH ) // finishes an upgrade
    call TriggerRegisterAnyUnitEventBJ(t2, EVENT_PLAYER_UNIT_DEATH ) // structure dies
    call TriggerAddCondition(t2, Condition( function Trig_SoldConstructedUpgradesDies_Act))

    set t2=null
    set t1=null
endfunction

Fantastic, very simple, easy to import and ultimately, no problem leaking so far. +Rep for you. About Jass part, i have no idea how to copy that :confused:

Edit: This one satisfied all requirements, except the 3rd but that is totally acceptable.
Edit2 : Something in the Jass code make it impossible to copy into new map: 16 compile errors
 
Last edited:
Level 22
Joined
Feb 27, 2007
Messages
3,784
Edit2 : in the Jass code make it impossible to copy into new map: 16 compile errors
You first need to have all of the relevant variables created, which ZiBitheWand3r3r didn't mention but his trigger should have automatically created them. They are:

Name
typearray?
HeroLimit_dummyIntegerYes
HeroLimit_heroCountintegeryes
HeroLimit_tier2Groupgroupyes
HeroLimit_tier3Groupgroupyes
HeroLimit_workingAltarsgroupyes

Then you need to have the triggers in the right order. Someone correct me if I'm wrong but I think to use the "ExecuteFunc("HeroLimit_CheckPrePlaced")" the trigger with that function needs to be placed above the trigger that is calling it.

Also your triggers need to have the right name or the WE will have a shitfest about it. So after you've added the HeroLimitSystemConfig trigger, you need to make another one called (exactly this name, no quotes) "HeroLimitSystem" and place it above the HeroLimitSystemConfig trigger in the trigger list. Then convert it to custom text, delete everything in the trigger, and paste in the JASS code. This should compile with no errors.
 
Level 13
Joined
Jun 15, 2016
Messages
743
You first need to have all of the relevant variables created, which ZiBitheWand3r3r didn't mention but his trigger should have automatically created them. They are:

Name
typearray?
HeroLimit_dummyIntegerYes
HeroLimit_heroCountintegeryes
HeroLimit_tier2Groupgroupyes
HeroLimit_tier3Groupgroupyes
HeroLimit_workingAltarsgroupyes

Then you need to have the triggers in the right order. Someone correct me if I'm wrong but I think to use the "ExecuteFunc("HeroLimit_CheckPrePlaced")" the trigger with that function needs to be placed above the trigger that is calling it.

Also your triggers need to have the right name or the WE will have a shitfest about it. So after you've added the HeroLimitSystemConfig trigger, you need to make another one called (exactly this name, no quotes) "HeroLimitSystem" and place it above the HeroLimitSystemConfig trigger in the trigger list. Then convert it to custom text, delete everything in the trigger, and paste in the JASS code. This should compile with no errors.

Actually, there are two variables you should have to manually create yourself (HeroLimit_dummyLd and HeroLimit_heroDuringTrain). He forgot to add the testing map so here i re-upload here for someone who need to do the same:
 

Attachments

  • unregret.w3x
    23.5 KB · Views: 59
Top