How to Check if Unit already exists?

Status
Not open for further replies.
For a unit-type, you enumerate through the entire map and see if it exists.
JASS:
call GroupEnumUnitsInRect(g, bj_mapInitialPlayableArea, null)
loop
    set u = FirstOfGroup(g)
    exitwhen (u == null)

    if (GetUnitTypeId(u) == unittype you are looking for) then
        // unit exists
    endif
 
    call GroupRemoveUnit(g, u)
endloop

The same method can be applied for a specific unit variable.
 
Level 9
Joined
Jun 13, 2008
Messages
350
@KILLCIDE although your solution is the exactly what I needed and made it work in my thing I still couldn't fix my main problem unfortunately:\

basically I have a loop that generates units in certain period of time. But the thing is, I don't want it to create a specific type of unit if that already exists. But, I also want it to generate it for once if it's not already created.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,246
With your unit type array (used for spawning the units) you also make a boolean array (has_spawned). When you select a unit type and spawn it you set has_spawned at that index to true. If has_spawned is true then you do not spawn the unit.

If you want the unit type to spawn again you will need another trigger (possibly on death, or at the end of a wave etc) to reset all has_spawned variables to false.
 
Level 9
Joined
Jun 13, 2008
Messages
350
I tried to implement what Cataract said, this are the codes now;
JASS:
local boolean rare = LoadBoolean( udg_DPHash, GetHandleId(portal), 3 )

    if rare then
        set rand = GetRandomInt(2, 100)
    else
        set rand = GetRandomInt(1, 100)                                                    
    endif
    loop
        exitwhen temp < 1
        if rand <= udg_DPChance[temp] and bool == false then
            set bool = true
            if rand == 1 then
          
                call SaveBoolean( udg_DPHash, GetHandleId(portal), 3, true )
                set summon = CreateUnit( GetOwningPlayer(portal), udg_DPSummons[temp], x+48*Cos(angle), y+48*Sin(angle), (angle*180/3.14159) )
                //pausing the timer to keep it in sync with the cinematic. yes,theres a cinematic for this //special unit
                call SaveTimerHandle( udg_DPHash, GetHandleId(summon), 0, t )
                call PauseTimer(t)
              
                set summon = null
          
            else
                set summon = CreateUnit( GetOwningPlayer(portal), udg_DPSummons[temp], x+48*Cos(angle), y+48*Sin(angle), (angle*180/3.14159) )
                set summon = null
            endif
        endif
        set temp = temp - 1
    endloop

I have an array for unit types and an another array that defines spawn chances for those units. DPChance[9]=1 means that It will spawn that unique unit. It may seem that with that bool variable called rare I could've solved this problem without killcide's unit type enumeration control thanks to hashtables but no, its like it completely ignores it and always sees

JASS:
set rand = GetRandomInt(1, 100)

because it keep summoning my unique unit. Once that summoned(if getrandom returnes->1) I want my program to see only

JASS:
set rand = GetRandomInt(2, 100)
afterwards. since that unit creation happens at certain period of time I need to check everytime for that "rand" right? So I put it inside the loop too but also didn't work.

need your godlike problem solving skills guys:\​
 
Last edited:
Well just like what title says. I need a way, a method to check if a specific unit/variable is already created/exists in the map.

Helps are appreciated. I'm a noob jasser.
you said specific, so it will be enough
JASS:
function IsUnitAlive takes unit u returns boolean
  return not (GetUnitTypeId(u) == 0 or IsUnitType(u, UNIT_TYPE_DEAD))
endfunction
 
Level 9
Joined
Jun 13, 2008
Messages
350
GetHandleId() returns an id representing the specific unit. What you need is GetUnitTypeId().
I have to do that for both portal unit and the summoned unit?
Edit: @Emm-A- Its already initialized.
@ZiBitheWand3r3r I did it like this but it says it cannot convert int to unit:\ I put it in the loop so it could always check if that hero already exists.

JASS:
 loop     
        exitwhen temp < 1
        if IsUnitAlive(udg_DPSummons[temp])==true then
            set rand = GetRandomInt(2,100)
        else
            set rand = GetRandomInt(1,100)
        endif

        if rand <= udg_DPChance[temp] and bool == false then
            set bool = true
            if rand == 1 then
             
                call SaveBoolean( udg_DPHash, GetHandleId(portal), 3, true )
                set summon = CreateUnit( GetOwningPlayer(portal), udg_DPSummons[temp], x+48*Cos(angle), y+48*Sin(angle), (angle*180/3.14159) )
 
Last edited:
Level 14
Joined
Jul 1, 2008
Messages
1,314
JASS:
if IsUnitAlive(udg_DPSummons[temp])==true then

this is not valid. You have to enter a unit, not a unit type here. Just store your unique unit in a permanent global variable and put it where you put DPSummons, and it will work.
 
Level 9
Joined
Jun 13, 2008
Messages
350
can you post the whole code?
there it is..its gonna be long:\

JASS:
//===========================================================================
//==========Jass Configurables===============================================
//===========================================================================

//Add the raw code of your Portal ability here.
constant function PortalAbilityId takes nothing returns integer
    return 'A000'
endfunction

//Add the Portal unit's raw code here.
constant function PortalUnitType takes nothing returns integer
    return 'hprt'
endfunction

//Special effect model you want to be played when a unit is summoned.
//Note the double backslashes
constant function PortalSummonSFX takes nothing returns string
    return "Abilities\\Spells\\Other\\HowlOfTerror\\HowlCaster.mdl"
endfunction



//===========================================================================
//==========Summoning System=================================================
//===========================================================================
function IsUnitAlive takes unit u returns boolean
  return not (GetUnitTypeId(u) == 'Uwar' or IsUnitType(u, UNIT_TYPE_DEAD))
endfunction

function Demonic_Portal_Jass_End takes timer watch returns nothing
    call PauseTimer(watch)
    call DestroyTimer(watch)
    call FlushChildHashtable( udg_DPHash, GetHandleId(watch) )
endfunction

function Demonic_Portal_Jass_Sound takes string filename, unit portal returns nothing
    local sound audio = CreateSound( filename, false, true, true, 10, 10, "DefaultEAXON")
    call SetSoundChannel( audio, 0 )
    call SetSoundDistances( audio, 500.00, 5000.00 )
    call SetSoundDistanceCutoff( audio, 2500.00)
    call SetSoundDuration( audio, GetSoundFileDuration(filename) )
    call SetSoundVolume( audio, 256 )
    call SetSoundConeAngles( audio, 0.0, 0.0, 127 )
    call SetSoundConeOrientation( audio, 0.0, 0.0, 0.0 )
    call SetSoundPitch( audio, 1.0 )
    call AttachSoundToUnit( audio, portal )
    call StartSound( audio )
    call KillSoundWhenDone( audio )
    set audio = null
endfunction

function Demonic_Portal_Jass_Timer takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer tick = LoadInteger( udg_DPHash, GetHandleId(t), 0 ) + 1
    local unit portal = LoadUnitHandle( udg_DPHash, GetHandleId(t), 1 )
    local unit summon
    local item stash
    local real angle = LoadReal( udg_DPHash, GetHandleId(portal), 1 ) - 3.14159
    local real x = GetUnitX(portal)
    local real y = GetUnitY(portal)
    local integer rand
    local integer temp = udg_DPSummonsMax
    local integer i = 1
    local boolean bool = false
    local unit unit2= udg_DPSummons[9]
   
   // local boolean rare = LoadBoolean( udg_DPHash, GetHandleId(portal), 3 )

    /*if rare then
        set rand = GetRandomInt(2,100)
    else
        set rand = GetRandomInt(1,100)
    endif*/
    loop       
        exitwhen temp < 1
        if IsUnitAlive(udg_DPSummons[temp])==true then
            set rand = GetRandomInt(2,100)
        else
            set rand = GetRandomInt(1,100)
        endif

        if rand <= udg_DPChance[temp] and bool == false then
            set bool = true
            if rand == 1 then
               
                call SaveBoolean( udg_DPHash, GetHandleId(portal), 3, true )
                set summon = CreateUnit( GetOwningPlayer(portal), udg_DPSummons[temp], x+48*Cos(angle), y+48*Sin(angle), (angle*180/3.14159) )
                call SetHeroLevel( summon, 10, false )
                call SelectHeroSkill( summon, 'ANrc' )
                call SelectHeroSkill( summon, 'ANdp' )
                call SelectHeroSkill( summon, 'AHbh' )
                call SelectHeroSkill( summon, 'ANfd' )
                call SetUnitAbilityLevel( summon, 'ANrc', 3 )
                call SetUnitAbilityLevel( summon, 'ANdp', 3 )
                call SetUnitAbilityLevel( summon, 'AHbh', 3 )
                call SetUnitAbilityLevel( summon, 'ANfd', 1 )
                call UnitModifySkillPoints( summon, -6 )
                loop
                    exitwhen i == 7
                    set stash = CreateItem( udg_DPSummonsHeroItem[i], x, y )
                    call UnitAddItem( summon, stash )
                    set stash = null
                    set i = i + 1
                endloop
                //Plays the DarkSummoningTarget1 sound instead of the Howl of Terror special effect.
                //call DestroyEffect( AddSpecialEffect( PortalSummonSFX(), x, y ) )
                call Demonic_Portal_Jass_Sound("Abilities\\Spells\\Undead\\DarkSummoning\\DarkSummoningTarget1.wav",portal)
                call IssuePointOrder( summon, "move", x+200*Cos(angle), y+200*Sin(angle) )

                //Pauses the timer to keep it in sync with the cinematic.
                call SaveTimerHandle( udg_DPHash, GetUnitTypeId(summon), 0, t )
                call PauseTimer(t)
                   
                set summon = null
               
            else
               
                set summon = CreateUnit( GetOwningPlayer(portal), udg_DPSummons[temp], x+48*Cos(angle), y+48*Sin(angle), (angle*180/3.14159) )
                //Plays the DarkSummoningTarget1 sound instead of the Howl of Terror special effect.
                //call DestroyEffect( AddSpecialEffect( PortalSummonSFX(), x, y ) )
                call Demonic_Portal_Jass_Sound("Sound\\Ambient\\DoodadEffects\\ShimmeringPortalEntrance.wav",portal)
                call IssuePointOrder( summon, "move", x+300*Cos(angle), y+300*Sin(angle) )
                set summon = null
            endif
        endif
        set temp = temp - 1
    endloop
    if tick == 3 then
        call KillUnit(portal)
    else
        call SaveInteger( udg_DPHash, GetHandleId(t), 0, tick )
    endif
    set t = null
    set portal = null
endfunction

function Demonic_Portal_Jass_Delay takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local timer clock = LoadTimerHandle( udg_DPHash, GetHandleId(t), 2 )
    local unit portal = LoadUnitHandle( udg_DPHash, GetHandleId(t), 1 )
    call SetUnitInvulnerable( portal, false )
    call TimerStart( clock, udg_DPSummonsInterval, true, function Demonic_Portal_Jass_Timer )
    call SaveInteger( udg_DPHash, GetHandleId(clock), 0, 0 )                             //Saved to clock
    call SaveUnitHandle( udg_DPHash, GetHandleId(clock), 1, portal )                     //Saved to clock
    call SaveTimerHandle( udg_DPHash, GetHandleId(portal), 0, clock )                    //Saved to portal
    call Demonic_Portal_Jass_End(t)
    set t = null
    set clock = null
    set portal = null
endfunction

function Demonic_Portal_Jass_Actions takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local real x = GetSpellTargetX()
    local real y = GetSpellTargetY()
    local real angle = Atan2( y - GetUnitY(caster), x - GetUnitX(caster) )
    local unit portal = CreateUnit( GetOwningPlayer(caster), PortalUnitType(), x, y, angle * (180/3.14159) - 180 )
    local timer watch = CreateTimer()
    local timer clock = CreateTimer()
    call SaveReal( udg_DPHash, GetHandleId(portal), 1, angle )                           //Saved to portal
    call SaveBoolean( udg_DPHash, GetHandleId(portal), 3, false )                        //Saved to portal
    if udg_DPBoolDelayPortal then
        call SetUnitInvulnerable( portal, true )
        call SetUnitAnimation( portal, "birth" )

        //Sound function: Change birth sound filename here.
        call Demonic_Portal_Jass_Sound("Sound\\Ambient\\DoodadEffects\\ShimmeringPortalBirth.wav",portal)

        call TimerStart( watch, udg_DPPortalDelayTime, false, function Demonic_Portal_Jass_Delay )
        call SaveUnitHandle( udg_DPHash, GetHandleId(watch), 1, portal )                 //Saved to watch
        call SaveTimerHandle( udg_DPHash, GetHandleId(watch), 2, clock )                 //Saved to watch
    else
        call TimerStart( clock, udg_DPSummonsInterval, true, function Demonic_Portal_Jass_Timer )
        call SaveInteger( udg_DPHash, GetHandleId(clock), 0, 0 )                         //Saved to clock
        call SaveUnitHandle( udg_DPHash, GetHandleId(clock), 1, portal )                 //Saved to clock
        call SaveTimerHandle( udg_DPHash, GetHandleId(portal), 0, clock )                //Saved to portal
    endif

    set caster = null
    set portal = null
    set watch = null
    set clock = null
endfunction

function Demonic_Portal_Jass_Conditions takes nothing returns boolean
    local unit portal = GetTriggerUnit()
    local timer t
    if GetTriggerEventId() == EVENT_PLAYER_UNIT_SPELL_EFFECT and GetSpellAbilityId() == PortalAbilityId() then
        call Demonic_Portal_Jass_Actions()
    elseif GetTriggerEventId() == EVENT_PLAYER_UNIT_DEATH and GetUnitTypeId(portal) == PortalUnitType() then
        set t = LoadTimerHandle( udg_DPHash, GetHandleId(portal), 0 )

        //Sound function: Change death sound filename here.
        call Demonic_Portal_Jass_Sound("Sound\\Ambient\\DoodadEffects\\ShimmeringPortalDeath.wav",portal)

        call Demonic_Portal_Jass_End(t)
        call FlushChildHashtable( udg_DPHash, GetHandleId(portal) )
        set t = null
    endif
    set portal = null
    return false
endfunction

//===========================================================================
//==========Init Function====================================================
//===========================================================================
function InitTrig_Demonic_Portal_Jass takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( t, Condition( function Demonic_Portal_Jass_Conditions ) )
    set t = null
endfunction

There are also triggers for inital configurations and some cinematic for the rare unit once its summoned.
 
Level 4
Joined
May 25, 2009
Messages
100
Why do you use the unittype 'Uwar' in IsUnitAlive()?
And you have to store the created unit back into the unitarray
"set udg_DPSummons[temp] = summon"

And for a "noob jasser" this is a nice piece of code^^ keep this on
 
Level 9
Joined
Jun 13, 2008
Messages
350
Why do you use the unittype 'Uwar' in IsUnitAlive()?
And you have to store the created unit back into the unitarray
"set udg_DPSummons[temp] = summon"

And for a "noob jasser" this is a nice piece of code^^ keep this on
I know this code isn't working right now. I thought you guys would just tell me what I should do here. Btw shouldn't I make the control before no unit is created? With what u said I must create my rare unit first and then assign it to zibithe's function.

I made that global unit variable in configuration step and I assigned (random unit from unit group(unit type of (my rare hero))) to it and then used that variable in function. I Made the function control inside the loop but I still get multiple times of my rare hero when I cast the spell billion times.
Some advanced shit is going on and figuring this out simply surpasses my skill:<
 
Level 14
Joined
Jul 1, 2008
Messages
1,314
I dont think there is advanced stuff going on there. Just take a step back, remake this trigger, and insert debug messages to see what is going on.

The problem is very easy, I think you just do too complicated stuff. Just try the array solution that doctor super good suggested.

If you still want to go with your solution, insert debug messages to see if rare is true/false etc. Will try to help you later with the code, if I got time
 
please don't modify IsUnitalive func I gave you, its universal to check if a unit is alive/dead/removed/not yet created. As addition do KILLCIDE solution I can suggest native native GetPlayerUnitTypeCount takes player p, integer unitid returns integer
I made examples for you how to easy do that:
JASS:
native GetPlayerUnitTypeCount takes player p, integer unitid returns integer
//counts only alive units/heroes/structures
//counts also units during training; counts also buildings under construction
//counts building during upgrade (like upgrade/in progres/ town hall-..to..-->keep, counts as keep)
//counts also heroes during revieving, in altar etc

globals
  integer array  SummonedId
  integer  SummonQuantity
endglobals

function YouWontGetTheSameUnitTwiceWholeGame takes nothing returns nothing
  local integer x
  local unit u
  // random system for hemmedo
  if SummonQuantity>=1 then //protection
    set x = GetRandomInt(1, SummonQuantity)
    set u = CreateUnit(Player(0), SummonedId[x], 0.00, 0.00, 0.00)
    set SummonedId[x] = SummonedId[SummonQuantity]
    set SummonQuantity = SummonQuantity - 1
  endif
endfunction

function CreateRandomSummonVersion2 takes nothing returns nothing
  local integer x=1
  local integer rand
  local unit u
   
  loop //protecting loop
    exitwhen x>SummonQuantity
    if GetPlayerUnitTypeCount(Player(0), SummonedId[x]) == 0 then
   
      loop //main loop
        set rand = GetRandomInt(1, SummonQuantity)
        if GetPlayerUnitTypeCount(Player(0), SummonedId[rand]) == 0 then
          set u = CreateUnit(Player(0), SummonedId[rand], 0.00, 0.00, 0.00)
          exitwhen true
        endif
      endloop

      exitwhen true
    endif
    set x=x+1
  endloop
endfunction



//=============================================
function InitTrig_Untitled_Trigger_001_Copy takes nothing returns nothing
// run it at map init:
  set SummonedId[1] = 'hpea'
  set SummonedId[2] = 'hfoo'
  set SummonedId[3] = 'hrif'
  set SummonedId[4] = 'hgyr'
  set SummonedId[5] = 'hgry'
  //...
  //...
  set SummonedId[20] = 'hkni'
  set SummonQuantity = 20

endfunction
 
Level 9
Joined
Jun 13, 2008
Messages
350
please don't modify IsUnitalive func I gave you, its universal to check if a unit is alive/dead/removed/not yet created. As addition do KILLCIDE solution I can suggest native native GetPlayerUnitTypeCount takes player p, integer unitid returns integer
I made examples for you how to easy do that:
JASS:
native GetPlayerUnitTypeCount takes player p, integer unitid returns integer
//counts only alive units/heroes/structures
//counts also units during training; counts also buildings under construction
//counts building during upgrade (like upgrade/in progres/ town hall-..to..-->keep, counts as keep)
//counts also heroes during revieving, in altar etc

globals
  integer array  SummonedId
  integer  SummonQuantity
endglobals

function YouWontGetTheSameUnitTwiceWholeGame takes nothing returns nothing
  local integer x
  local unit u
  // random system for hemmedo
  if SummonQuantity>=1 then //protection
    set x = GetRandomInt(1, SummonQuantity)
    set u = CreateUnit(Player(0), SummonedId[x], 0.00, 0.00, 0.00)
    set SummonedId[x] = SummonedId[SummonQuantity]
    set SummonQuantity = SummonQuantity - 1
  endif
endfunction

function CreateRandomSummonVersion2 takes nothing returns nothing
  local integer x=1
  local integer rand
  local unit u
 
  loop //protecting loop
    exitwhen x>SummonQuantity
    if GetPlayerUnitTypeCount(Player(0), SummonedId[x]) == 0 then
 
      loop //main loop
        set rand = GetRandomInt(1, SummonQuantity)
        if GetPlayerUnitTypeCount(Player(0), SummonedId[rand]) == 0 then
          set u = CreateUnit(Player(0), SummonedId[rand], 0.00, 0.00, 0.00)
          exitwhen true
        endif
      endloop

      exitwhen true
    endif
    set x=x+1
  endloop
endfunction



//=============================================
function InitTrig_Untitled_Trigger_001_Copy takes nothing returns nothing
// run it at map init:
  set SummonedId[1] = 'hpea'
  set SummonedId[2] = 'hfoo'
  set SummonedId[3] = 'hrif'
  set SummonedId[4] = 'hgyr'
  set SummonedId[5] = 'hgry'
  //...
  //...
  set SummonedId[20] = 'hkni'
  set SummonQuantity = 20

endfunction
I'm gonna try to implement this solution to my thing right now. Thanks mate. Does it also prevent the summoning of that rare unit from different players too? That unit must be global. There can't be like 2 Arthas in the same map for example, even if its summoned by different unit or player. So I think this breaks the MUI rule though but thats how I need it to be.
 
There can't be like 2 Arthas in the same map for example, even if its summoned by different unit or player
native GetPlayerUnitTypeCount takes player p, integer unitid returns integer is a good alternative to GroupEnumUnitsInRect but it counts units owned by player p. So you have to loop over all players and add values, then create Arthas only if you get zero from addition.
Also please note that 2 example function I send can't be mixed, you can't use them alternately cause 1st function changes your integer array.
 
Level 9
Joined
Jun 13, 2008
Messages
350
native GetPlayerUnitTypeCount takes player p, integer unitid returns integer is a good alternative to GroupEnumUnitsInRect but it counts units owned by player p. So you have to loop over all players and add values, then create Arthas only if you get zero from addition.
Also please note that 2 example function I send can't be mixed, you can't use them alternately cause 1st function changes your integer array.
The way you use GetRandomInt is different than mine I guess. Take a look at my inits and you'll see;
  • Actions
    • -------- Spell Configurables --------
    • Set DPBoolDelayPortal = True
    • Set DPPortalDelayTime = 7.50
    • Set DPSummonsInterval = 10.00
    • -------- Summon Unit Types --------
    • Set DPSummons[1] = Bloodfiend
    • Set DPSummons[2] = Fel Stalker
    • Set DPSummons[3] = Overlord
    • Set DPSummons[4] = Eredar Diabolist
    • Set DPSummons[5] = Fel Ravager
    • Set DPSummons[6] = Infernal
    • Set DPSummons[7] = Doom Guard
    • Set DPSummons[8] = Eredar Warlock
    • Set DPSummons[9] = Archimonde
    • Set DPSummonsMax = 9
    • -------- Summon Chance --------
    • Set DPChance[1] = 100
    • Set DPChance[2] = 75
    • Set DPChance[3] = 55
    • Set DPChance[4] = 40
    • Set DPChance[5] = 25
    • Set DPChance[6] = 15
    • Set DPChance[7] = 10
    • Set DPChance[8] = 5
    • Set DPChance[9] = 1
    • -------- Archimonde Items --------
    • Set DPSummonsHeroItem[1] = Belt of Giant Strength +6
    • Set DPSummonsHeroItem[2] = Boots of Quel'Thalas +6
    • Set DPSummonsHeroItem[3] = Crown of Kings +5
    • Set DPSummonsHeroItem[4] = Gem of True Seeing
    • Set DPSummonsHeroItem[5] = Ring of Protection +5
    • Set DPSummonsHeroItem[6] = Robe of the Magi +6
Edit: Yeah so after understanding your codes I noticed that you didn't count summon chances for the units. That's why it was hard for me to adapt your codes into my spell:\
 
Last edited:
JASS:
//--------------------------------------------------------------------------------
function GetUnitTypeCount takes integer unitId returns integer
  local integer i=0
  local integer count=0
  loop
    exitwhen i==bj_MAX_PLAYER_SLOTS
    set count = count + GetPlayerUnitTypeCount(Player(i), unitId)
    set i=i+1
  endloop
  return count
endfunction
//-------------------------------------------------------------------------------
function CreateRandomSummonVersion3 takes nothing returns nothing
  local integer x=SummonQuantity
  local integer random = GetRandomInt(0, 100)
  local unit u  
  loop
    exitwhen x<1
    if GetUnitTypeCount(SummonedId[x]) == 0 and random<=summonChance[x] then
      set u = CreateUnit(Player(0), SummonedId[x], 0.00, 0.00, 0.00)
      exitwhen true
    endif
    set x=x-1
  endloop
endfunction


//=============================================
function InitTrig_Untitled_Trigger_001_Copy takes nothing returns nothing

  set SummonedId[1] = 'hpea'
  set SummonedId[2] = 'hfoo'
  set SummonedId[3] = 'hrif'
  set SummonedId[4] = 'hgyr'
  set SummonedId[5] = 'hgry'
  //...
  //...
  set SummonedId[6] = 'hkni' //strongest unit
  set SummonQuantity = 6
  set summonChance[1] = 100
  set summonChance[2] = 75
  set summonChance[3] = 55
  set summonChance[4] = 40
  set summonChance[5] = 25
  set summonChance[6] = 10
  

endfunction
 
Level 14
Joined
Jul 1, 2008
Messages
1,314
sorry guys, I still dont get why you want to do more than you need to do. I mean, of course, if you got more units that can only be spawned one time, ZiBi's solution should be used.

You could even make it a bit more configurable by giving a certain amount to each unit type, that can be spawned. Not only 1 ...

I mean, obviously ZiBi's code is better but, if you want to keep your original trigger, just use one global variable udg_DontSpawnArchimonedAnymore (init=false) for example:

JASS:
function Demonic_Portal_Jass_Timer takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer tick = LoadInteger( udg_DPHash, GetHandleId(t), 0 ) + 1
    local unit portal = LoadUnitHandle( udg_DPHash, GetHandleId(t), 1 )
    local unit summon
    local item stash
    local real angle = LoadReal( udg_DPHash, GetHandleId(portal), 1 ) - 3.14159
    local real x = GetUnitX(portal)
    local real y = GetUnitY(portal)
    local integer rand = 2
    local integer temp = udg_DPSummonsMax
    local integer i = 1
    local boolean bool = false
    local unit unit2= udg_DPSummons[9]
  
if
udg_DontSpawnArchimonedAnymore
then
        set rand = GetRandomInt(2,100)
    else
        set rand = GetRandomInt(1,100)
    endif*/
    loop      
        exitwhen temp < 1

        if rand <= udg_DPChance[temp] and not bool then
            set bool = true
            if rand == 1 and not udg_DontSpawnArchimonedAnymore then
              
                // this prevents rand == 1 from now on for the rest of the game, same as your hashtable entry should have done before.
                set udg_DontSpawnArchimonedAnymore = true

                set summon = CreateUnit( GetOwningPlayer(portal), udg_DPSummons[temp], x+48*Cos(angle), y+48*Sin(angle), (angle*180/3.14159) )
                call SetHeroLevel( summon, 10, false )
                call SelectHeroSkill( summon, 'ANrc' )
                call SelectHeroSkill( summon, 'ANdp' )
                call SelectHeroSkill( summon, 'AHbh' )
                call SelectHeroSkill( summon, 'ANfd' )
                call SetUnitAbilityLevel( summon, 'ANrc', 3 )
                call SetUnitAbilityLevel( summon, 'ANdp', 3 )
                call SetUnitAbilityLevel( summon, 'AHbh', 3 )
                call SetUnitAbilityLevel( summon, 'ANfd', 1 )
                call UnitModifySkillPoints( summon, -6 )
                loop
                    exitwhen i == 7
                    set stash = CreateItem( udg_DPSummonsHeroItem[i], x, y )
                    call UnitAddItem( summon, stash )
                    set stash = null
                    set i = i + 1
                endloop
                //Plays the DarkSummoningTarget1 sound instead of the Howl of Terror special effect.
                //call DestroyEffect( AddSpecialEffect( PortalSummonSFX(), x, y ) )
                call Demonic_Portal_Jass_Sound("Abilities\\Spells\\Undead\\DarkSummoning\\DarkSummoningTarget1.wav",portal)
                call IssuePointOrder( summon, "move", x+200*Cos(angle), y+200*Sin(angle) )

                //Pauses the timer to keep it in sync with the cinematic.
                call SaveTimerHandle( udg_DPHash, GetUnitTypeId(summon), 0, t )
                call PauseTimer(t)
                  
                set summon = null
              
            else
              
                set summon = CreateUnit( GetOwningPlayer(portal), udg_DPSummons[temp], x+48*Cos(angle), y+48*Sin(angle), (angle*180/3.14159) )
                //Plays the DarkSummoningTarget1 sound instead of the Howl of Terror special effect.
                //call DestroyEffect( AddSpecialEffect( PortalSummonSFX(), x, y ) )
                call Demonic_Portal_Jass_Sound("Sound\\Ambient\\DoodadEffects\\ShimmeringPortalEntrance.wav",portal)
                call IssuePointOrder( summon, "move", x+300*Cos(angle), y+300*Sin(angle) )
                set summon = null
            endif
        endif
        set temp = temp - 1
    endloop
    if tick == 3 then
        call KillUnit(portal)
    else
        call SaveInteger( udg_DPHash, GetHandleId(t), 0, tick )
    endif
    set t = null
    set portal = null
endfunction
Like this, it would be still your own thing but it should work. There is no way that Archimonde will be spawned more than once like this.
 
Level 9
Joined
Jun 13, 2008
Messages
350
I changed timerhandle's getunittypeId to GetHandleId, figured it would fix the portal problem and it did. And I still get only one Archimonde, too.

I appreciated all of your help, noticed my mistakes and learned new things thanks to you guys, especially @ZiBitheWand3r3r and @Emm-A- , +rep to all. Topic can be closed.
 
Status
Not open for further replies.
Top