- Joined
- Nov 30, 2007
- Messages
- 1,202
Count Living Units in (UnitGoup) of Type? 
Does killed units eventually get removed from the UnitGroup?

Does killed units eventually get removed from the UnitGroup?
Pick units that are alive and of type X and an integer "count units in group" will let you know.
globals
integer count = 0
group var = CreateGroup()
group iter = CreateGroup()
group temp
endglobals
function CountUnitsIntGroup takes nothing returns integer
local unit u
set count = 0
loop
set u = FirstOfGroup(var)
exitwhen u == null
if ( IsUnitAlive(u) ) then
set count = count + 1
endif
call GroupRemoveUnit(var, u)
call GroupAddUnit(iter, u)
endloop
set temp = var
set var = iter
set iter = temp
return count
endfunction
Sorry for "Banner". ^^ Why it fails if you work with an backup group? And yes, he wants to filter unitType, that's why integer parameter would make sense, it was just a suggestion for your example.First, it's not Banner but Bannar. Second, your approach with group as parameter fails, leaving group empty after procedure - and thats what we do not want to do.
In place of "IsUnitAlive" (which doesn't really exist) he should place any filter he wants![]()
You could use a vector or table structure instead. Use 1D index as typeId and a 2D one as actual count.
function AddStructureTechDummy takes nothing returns nothing
endfunctin
function RemoveStructureTechDummy takes nothing returns nothing
endfunction
function Completed_Destroyed_Structure takes nothing returns boolean
local unit u = GetTriggerUnit()
local integer p_num = GetPlayerId(GetOwningPlayer(u))
if (IsUnitType((u), UNIT_TYPE_STRUCTURE) == true) then
set u = GetConstructedStructure()
if (u != null) then // STRUCTURE COMPLETED
if (IsUnitInGroup(u), udg_CityGroup[udg_BuilderCurCity[p_num]]) == true) then
// SEARCH FOR TECH AND ADD IF NOT FOUND
endif
else // STRUCTURE DIED
set u = GetTriggerUnit()
if (IsUnitInGroup(u), udg_CityGroup[udg_BuilderCurCity[p_num]]) == true) then
// SEARCH FOR TECH AND REMOVE IF FOUND
endif
endif
endif
set u = null
return false
endfunction
//===========================================================================
function InitTrig_Completed_or_Destroyed_Structure takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DEATH )
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_CONSTRUCT_FINISH)
call TriggerAddCondition(t, Condition( function Completed_Destroyed_Structure))
set t = null
endfunction
//NOTE!: if you have JNGP, you can uncomment the following block
//globals
//integer udg_countUnitsCounter = 0
//integer udg_countUnitsTypeId = 0
//endglobals
//If you dont have JNGP, you should create global
//variable with name "countUnitsCounter", which should be of type Integer
//variable with anme "countUnitsTypeId", which should be of type Integer
function CountUnitsLooper134 takes nothing returns boolean
local unit u = GetEnumUnit()
if IsUnitType(u, UNIT_TYPE_ALIVE) and GetUnitTypeId(u) == udg_countUnitsTypeId then //I know there are better ways, but meh
set udg_countUnitsCounter = udg_countUnitsCounter + 1
endif
set u = null
endfunction
function CountLivingUnits takes group g, integer ofType returns integer
set udg_countUnitsCounter = 0
set udg_countUnitsTypeId = ofType
call ForGroup(g, function CountUnitsLooper134)
return udg_countUnitsCounter
endfunction
Could u show me? Make two types: Peasant and footmen for two payers Player red and blue.
JASS:function Completed_Destroyed_Structure takes nothing returns boolean local unit u = GetTriggerUnit() if (IsUnitType((u), UNIT_TYPE_STRUCTURE) == true) then set u = GetConstructedStructure() if (u != null) then // STRUCTURE COMPLETED //ADD UNIT TO TECH_LIST IF MATCHING TOWN IS CURRENTLY BEING SELECTED else // STRUCTURE DIED //REMOVE UNIT TO TECH_LIST IF MATCHING TOWN IS CURRENTLY BEING SELECTED endif endif set u = null return false endfunction //=========================================================================== function InitTrig_Completed_or_Destroyed_Structure takes nothing returns nothing local trigger t = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DEATH ) call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_CONSTRUCT_FINISH) call TriggerAddCondition(t, Condition( function Completed_Destroyed_Structure)) set t = null endfunction
If what you say works I should be able to hook it up with this.
if GetTriggerEventId() == EVENT_PLAYER_UNIT_DEATH then
//actions
else
//alternative actions
endif
My solution also doesn't modify group and, is much quicker than ForGroup because it doesn't start new threads, as you probably now.
However, it might not be as easy to use.
function StartCancelConstruction takes nothing returns boolean
local unit u = GetTriggerUnit()
local integer p_num = GetPlayerId(GetTriggerPlayer())
local integer i = 0
local integer owningCity
local integer u_id
local integer countLast
local integer count
if (IsUnitType(u, UNIT_TYPE_STRUCTURE) == true) then
loop
exitwhen udg_BuildingOrder[i] == null
if (GetUnitTypeId(u) == udg_BuildingType[i]) then
set u_id = GetUnitUserData(u)
set owningCity = udg_City_BuildingOwner[u_id]
// Count here: set countLast = Unit Group (udg_City_ConstructionGroup)
if (GetTriggerEventId() == EVENT_PLAYER_UNIT_CONSTRUCT_START) then
set udg_City_BuildingOwner[u_id] = owningCity
call GroupAddUnit(udg_City_Group[owningCity], u)
call GroupAddUnit(udg_City_ConstructionGroup[owningCity], u)
elseif (GetTriggerEventId() == EVENT_PLAYER_UNIT_CONSTRUCT_CANCEL) then
call GroupRemoveUnit(udg_City_ConstructionGroup[udg_City_BuildingOwner[u_id]], u)
elseif (GetTriggerEventId() == EVENT_PLAYER_UNIT_CONSTRUCT_FINISH) then
call GroupRemoveUnit(udg_City_ConstructionGroup[owningCity], u)
elseif (GetTriggerEventId() == EVENT_PLAYER_UNIT_DEATH and IsUnitInGroup(u, udg_City_ConstructionGroup[owningCity]) == true ) then
call GroupRemoveUnit(udg_City_ConstructionGroup[owningCity], u)
endif
// Count here: set count = Unit Group (udg_City_ConstructionGroup)
if (count >= udg_City_ConstructingLimit) then
elseif (countLast >= 5 and count < 5) then
endif
endif
set i = i + 1
endloop
endif
set u = null
return false
endfunction
//===========================================================================
function InitTrig_CC_Start_Cancel_Finnish_Death takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_CONSTRUCT_CANCEL)
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_CONSTRUCT_START)
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_CONSTRUCT_FINISH)
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DEATH)
call TriggerAddCondition( t, Condition( function StartCancelConstruction) )
set t = null
endfunction
"var" is your group of units.
JASS:globals integer count = 0 group var = CreateGroup() group iter = CreateGroup() group temp endglobals function CountUnitsIntGroup takes nothing returns integer local unit u set count = 0 loop set u = FirstOfGroup(var) exitwhen u == null if ( IsUnitAlive(u) ) then set count = count + 1 endif call GroupRemoveUnit(var, u) call GroupAddUnit(iter, u) endloop set temp = var set var = iter set iter = temp return count endfunction
library Setup initializer init
globals
group array CityBuildingGroup
group array CityGroup_being_built
integer array CityBuilding_type
private timer t
endglobals
private function run takes nothing returns nothing
local integer i = 0
call PauseTimer(t)
call DestroyTimer(t)
set t = null
set CityBuildingGroup[0] = CreateGroup()
call GroupAddGroup( GetUnitsInRectAll(GetPlayableMapRect()), CityBuildingGroup[0])
set CityBuilding_type[0] = 'hhou' // farm
set CityBuilding_type[1] = 'halt' // altar
set CityBuilding_type[2] = 'hbar' // Baracks
set CityBuilding_type[3] = 'hlum' // lumber mill
loop
exitwhen CityBuilding_type[i] == null
call BJDebugMsg(UnitId2StringBJ(CityBuilding_type[i]) + " = " + I2S(CountBuildings(0,i)))
set i = i + 1
endloop
endfunction
private function init takes nothing returns nothing
set t = CreateTimer()
call TimerStart(t, 0.1, false, function run)
endfunction
endlibrary
library CountBuildings initializer init
function CountBuildings takes integer city_num, integer b_type_num returns integer
local unit u
local integer count = 0
local group g1 = CreateGroup()
set g1 = CityBuildingGroup[city_num]
loop
set u = FirstOfGroup(g1)
exitwhen u == null
if (GetUnitTypeId(u) == CityBuilding_type[b_type_num] and IsUnitInGroup(u, CityGroup_being_built[city_num]) == false) then
set count = count + 1
endif
call GroupRemoveUnit(g1, u)
endloop
call DestroyGroup(g1)
set u = null
return count
endfunction
private function init takes nothing returns nothing
endfunction
endlibrary
library CountBuildings initializer init
function CountBuildings takes integer city_num, integer b_type_num returns integer
local unit u
local integer count = 0
local group iter = CreateGroup()
local group temp = CreateGroup()
loop
set u = FirstOfGroup(CityBuildingGroup[city_num])
exitwhen u == null
if (GetUnitTypeId(u) == CityBuilding_type[b_type_num] and IsUnitInGroup(u, CityGroup_being_built[city_num]) == false) then
set count = count + 1
endif
call GroupRemoveUnit(CityBuildingGroup[city_num], u)
call GroupAddUnit(iter, u)
endloop
set temp = CityBuildingGroup[city_num]
set CityBuildingGroup[city_num] = iter
set iter = temp
return count
endfunction
private function init takes nothing returns nothing
endfunction
endlibrary