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

[JASS] Unable to allocate id for an object of type bla bla bla

Status
Not open for further replies.
Level 3
Joined
Feb 25, 2010
Messages
25
I made spell that named Diamond Storm, which summons many diamond to strike enemies (like stampede) but with additional effect

But when i cast it it about 100 times
It shows this text

attachment.php


This is my trigger spell :

JASS:
scope DiamondStorm initializer init

globals
    private constant integer SID = 'A01V'
    private constant integer BID = 'Asl2'
    private constant integer DID = 'nn42'
    private constant real SPEED = 20.
    private constant real AOE = 35.
    private constant real MAXDIST = 350.
    private constant real DAMAGE = 50.
    private constant real INTERVAL = .03
    private constant string TFX = "Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl"
    private constant attacktype AT = udg_T1
    private constant damagetype DT = DAMAGE_TYPE_MAGIC
    
    private constant string PRELOAD_MDL = "war3mapImported\\Diamond.mdx"
endglobals
    
private struct data
    unit c
    unit array p[75]
    integer pc
    real array px[75]
    real array py[75]
    real array pd[75]
    real cx
    real cy
    real angle
    boolean channel
endstruct

globals
    private constant group Group = CreateGroup()
    private constant timer Tim = CreateTimer()
    private integer total = 0
    private integer totalcast = 0
    //private player cp
    private unit u
    private unit picked
    private data array queue
endglobals

private function Skill_Filter takes nothing returns boolean
    return filter(u,GetFilterUnit()) // i made a function to filter enemy for faster coding
endfunction

private function Timer takes nothing returns nothing
    local data d
    local integer i = 1
    local integer j = 0
    local real dist
    local real cx
    local real cy
    local real x
    local real y
   // call BJDebugMsg("TIMER")
 //   call BJDebugMsg("|cffffcc00" + I2S(total) + "|r")
    loop
        set x = 0
        set y = 0
        exitwhen i > total
       // call DisplayTimedTextToPlayer(Player(0), 0.,0., 0.01, "Process : " + I2S(i))
        set d = queue[i]
        //set cp = GetOwningPlayer(d.c)
        set u = d.c
       //call BJDebugMsg("TIMERLOOP1")
        //call KillUnit(d.c)
        if d.channel == true then
            set cx = GetUnitX(d.c)
            set cy = GetUnitY(d.c)
            set dist = GetRandomReal(0.,200.)
            //call BJDebugMsg("TIMERIF")
            //call KillUnit(d.c)
            //call KillUnit(u)
            if GetRandomInt(1,2) == 1 then
                set x = cx + dist * Cos((d.angle + 90.) * bj_DEGTORAD)
                set y = cy + dist * Sin((d.angle + 90.) * bj_DEGTORAD)
            else
                set x = cx + dist * Cos((d.angle - 90.) * bj_DEGTORAD)
                set y = cy + dist * Sin((d.angle - 90.) * bj_DEGTORAD)
            endif
//            call CreateTextTagCrit(I2S(i),Location(GetUnitX(d.c),GetUnitY(d.c)))
            set d.p[d.pc] = CreateUnit(GetOwningPlayer(d.c),DID,x,y,d.angle)
            set d.pd[d.pc] = MAXDIST
            set d.px[d.pc] = x
            set d.py[d.pc] = y
            call SetUnitFlyHeight(d.p[d.pc],GetRandomReal(0.,200.),0.)
            set d.pc = d.pc + 1
            //===\\
            set j = 0
            loop
                set x = 0
                set y = 0
                exitwhen j >= d.pc
                if d.p[j] != null then
                    set x = d.px[j] + SPEED * Cos(d.angle * bj_DEGTORAD)
                    set y = d.py[j] + SPEED * Sin(d.angle * bj_DEGTORAD)
                    call GroupClear(Group)
                    call GroupEnumUnitsInRange(Group,x,y,AOE,Filter(function Skill_Filter))
                    set picked = FirstOfGroup(Group)
                    if picked != null then
                        call DestroyEffect(AddSpecialEffectTarget(TFX,picked,"chest"))
                        call DummyCastTarget(d.c,picked,BID,"slow") // i make a quick dummy cast function
                        call UnitDamageTarget(d.c,picked,DAMAGE,false,false,AT,DT,null)
                        call RemoveUnit(d.p[j])
                        set d.p[j] = null
                    else
                        if d.pd[j] > 0. then
                            call SetUnitPosition(d.p[j],x,y)
                            set d.px[j] = x
                            set d.py[j] = y
                            set d.pd[j] = d.pd[j] - SPEED
                        else
                            call RemoveUnit(d.p[j])
                            set d.p[j] = null
                        endif
                    endif                    
            endif
            set j = j + 1
            endloop
 //           call BJDebugMsg("|cff00ff00" + I2S(total) + "|r")
        else
            set j = 0
            loop
                exitwhen j >= d.pc
                call RemoveUnit(d.p[j])
                set d.p[j] = null
                set j = j + 1
            endloop
            set d.c = null 
//            call BJDebugMsg("|cff0000ff" + I2S(total) + "|r")
            set queue[i] = queue[total]
            set total = total - 1
//            call BJDebugMsg("|cffffff00" + I2S(total) + "|r")
            set i = i - 1
            if total==0 then
                call PauseTimer(Tim)
            endif
         

        endif
    set i = i + 1
    endloop
   // call BJDebugMsg(I2S(total))
  //  if total == 0 then
  //     call PauseTimer(Tim)
  //  endif
endfunction

private function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == SID
endfunction

private function Stop_Actions takes nothing returns nothing
    local integer i = 0
    local data d
    loop
        exitwhen i > total
        set d = queue[i]
        if GetTriggerUnit() == d.c then
            //call DestroyEffect(AddSpecialEffectTarget(TFX,d.c,"chest"))
            set d.channel = false
        endif
        set i = i + 1
    endloop
endfunction

private function Actions takes nothing returns nothing
    local data d = data.create()
    local location t = GetSpellTargetLoc()
    local real tx = GetLocationX(t)
    local real ty = GetLocationY(t)

    set totalcast = totalcast + 1
        call BJDebugMsg(I2S(totalcast)) // this why i know about 100x
    set d.c = GetTriggerUnit()
    set d.cx = GetUnitX(d.c)
    set d.cy = GetUnitY(d.c)
    set d.angle = bj_RADTODEG * Atan2(ty - d.cy, tx - d.cx)
    set d.channel = true
    if total == 0 then
        call TimerStart(Tim,INTERVAL,true,function Timer)
    endif
    set total = total + 1
    set queue[total] = d
    call RemoveLocation(t)
    set t = null
endfunction

private constant function AntiLeak takes nothing returns boolean
    return true
endfunction

private function init takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    local trigger stop = CreateTrigger( )
    local filterfunc f = Filter(function AntiLeak)
    local integer i = 0
    loop
        call TriggerRegisterPlayerUnitEvent(t,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,f)
        call TriggerRegisterPlayerUnitEvent(stop,Player(i),EVENT_PLAYER_UNIT_SPELL_ENDCAST,f)
        set i = i + 1
        exitwhen i == bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition( t, Condition(function Conditions))
    call TriggerAddAction( t, function Actions)
    call TriggerAddCondition( stop, Condition(function Conditions))
    call TriggerAddAction( stop, function Stop_Actions)
    call Preload(TFX)
    call Preload(PRELOAD_MDL)
    call DestroyFilter(f)
    set t = null
    set f = null
endfunction
    
endscope

Anyone can fix this or make a better ones ?

Thanks :goblin_good_job:
 

Attachments

  • problem.jpg
    problem.jpg
    12.9 KB · Views: 234
Level 37
Joined
Mar 6, 2006
Messages
9,240
You give the arrays initial size, 75. I guess the game engine won't allocate more indexes when it hits the max size.

You don't need to set the size at all.

JASS:
unit array p
is all you need. That way you can cast it 8091 times.

You need to recycle the indexes for unlimited uses. When you don't need an index, make it available for usage again. You should keep track on how many indexes you're using.
 
Status
Not open for further replies.
Top