• 🏆 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] Don't know what's wrong..

Status
Not open for further replies.
Level 10
Joined
Sep 6, 2007
Messages
440
JASS:
function Conditions takes nothing returns boolean
   return GetSpellAbilityId() == 'A005'
endfunction 

function AndConditions takes nothing returns boolean
    return GetBooleanAnd(IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false, IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) == true)
endfunction

function Attract takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer i = GetHandleInt(t, "i") + 1
    local real X
    local real Y
    local unit S
    local unit V
    local unit U
    local group G
    if i == 10 then
        call GetHandleUnit(t, "s")
        call RemoveUnit(S)
        call FlushHandleLocals(t)
        call DestroyTimer(t)
    else
        call SetHandleInt(t, "i", i + 1)
        set S = GetHandleUnit(t, "s")
        set X = GetHandleReal(t, "x")
        set Y = GetHandleReal(t, "y")
        set G = GetHandleGroup(t, "g")
        set U = GetHandleUnit(t, "u")
        call GroupEnumUnitsInRangeOfLoc(G, Location(X, Y), I2R(GetUnitAbilityLevel(U, 'A004') * 300), Condition(function AndConditions))
        set V = GetFilterUnit()
        call UnitDamageTarget(S, V, R2I(GetUnitState(V, UNIT_STATE_MANA) * 5), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MIND, WEAPON_TYPE_WHOKNOWS)
        call SetUnitState(V, UNIT_STATE_MANA, R2I(GetUnitState(V, UNIT_STATE_MANA) - 20))
    endif
set t = null
endfunction

function Twisted_Mind takes nothing returns nothing
   local location L = GetSpellTargetLoc()
   local unit U = GetSpellAbilityUnit()
   local group G = GetUnitsInRangeOfLocMatching(I2R(GetUnitAbilityLevel(U, 'A004') * 300), L, Condition(function AndConditions)) 
   local unit S
   local timer t = CreateTimer()
   local real X = GetLocationX(L)
   local real Y = GetLocationY(L)
   call CreateNUnitsAtLoc(1, 'h001', GetOwningPlayer(U), L, 270.)
   set S = GetLastCreatedUnit()
   call UnitAddAbility(S, 'A003')
   call UnitRemoveAbility(S, 'A003')
   call SetUnitFlyHeight(S, -770.00, 400.00)
   call SetHandleHandle(t, "g", G)
   call SetHandleHandle(t, "s", S)
   call SetHandleHandle(t, "u", U)
   call SetHandleReal(t, "x", X)
   call SetHandleReal(t, "y", Y)
   call TimerStart(t, 1., true, function Attract)
endfunction

function InitTrig_Twisted_Mind takes nothing returns nothing
   set gg_trg_Twisted_Mind = CreateTrigger()
   call TriggerRegisterAnyUnitEventBJ(gg_trg_Twisted_Mind, EVENT_PLAYER_UNIT_SPELL_EFFECT)
   call TriggerAddCondition(gg_trg_Twisted_Mind, Condition(function Conditions))
   call TriggerAddAction(gg_trg_Twisted_Mind, function Twisted_Mind)
endfunction

What I'm trying to do here is, a unit casts a spell at a point, then it will create a dummy unit and then for every sec for 10 seconds at total, this will deal damage to units in range of caster's ability level * 300. But it's not working. I think problem lies with the group... What should I do here?
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
call UnitAddAbility(S, 'A003')
call UnitRemoveAbility(S, 'A003')

Why do you remove it?

Also note that using the Handle Variable system will allow you to attach only 255 'things' unless using multiple caches or a struct system.
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
I am not 100% sure but I think it is the other way around.
Only 255 attachments to a game cache.
If you edit the system a little you can have unlimited number of game caches.
 
Level 11
Joined
Feb 18, 2004
Messages
394
I am not 100% sure but I think it is the other way around.
Only 255 attachments to a game cache.
If you edit the system a little you can have unlimited number of game caches.
No, it'll only let you use 255 caches. It has an apparently unlimited amount that you can store in one cache.

Griffen is correct, you are not.
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
Thank you PurplePoot :)

Yes I notice a couple of other strange things:
Why is this line missing
call SetHandleInteger(t,"i",0)
in the action function(Twisted_Mind)? Shouldn't you first set it before getting it?
Also
call GetHandleUnit(t, "s")
call RemoveUnit(S)
Should be:
set S=GetHandleUnit(t, "s")
call RemoveUnit(S)
Also
local integer i = GetHandleInt(t, "i") + 1
call SetHandleInt(t, "i", i + 1)
This will cause the timer to run 5 times, actually not sure how many times in the current state(fixing the above will fix this) as the condition is i==10 if the initial value of i is 0 or another even number the timer will run forever.
Also I think pausing a timer before destroying it is advisable.
 
Level 10
Joined
Sep 6, 2007
Messages
440
Oh, those are good advices to improve my code. However, the problem is still not solved. As I said before, I'm trying to pick people in a predefined range every second and decrease their mana. As I said before, the problem lies with the group. What should I use there?
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
Yeap :)
But is that the case with Handle variables?
I found the problem :D


JASS:
function Conditions takes nothing returns boolean
   return GetSpellAbilityId() == 'A005'
endfunction

function AndConditions takes nothing returns boolean
    return GetBooleanAnd(IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false, IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) == true)
endfunction


function Attract takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer i = GetHandleInt(t, "i") + 1//this is changed
    local location L=GetHandleHandle(t,"l")//this is changed
    local group G=GetUnitsInRangeOfLocMatching(I2R(GetUnitAbilityLevel(GetHandleUnit(t,"u"), 'A004') * 300), L, Condition(function AndConditions))//this is changed
    local unit pikced
    if i == 10 then
        call RemoveUnit(GetHandleUnit(t, "s"))//Thank to PurplePoot
        call FlushHandleLocals(t)
        call PauseTimer(t)//this is new
        call DestroyTimer(t)
     else
        set picked=FirstOfGroup(G)
        loop
            exitwhen picked=null
            call UnitDamageTarget(GetHandleUnit(t,"u"), picked, GetUnitState(picked, UNIT_STATE_MANA) * 5, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MIND, WEAPON_TYPE_WHOKNOWS)
            call SetUnitState(picked, UNIT_STATE_MANA, GetUnitState(picked, UNIT_STATE_MANA) - 20)
            call GroupRemoveUnit(G,picked)
            picked=FirstOfGroup(G)
        endloop
        call SetHandleInt(t, "i", i)//this is changed
    endif
    call DestroyGroup(G)//cleanup
    call RemoveLocation(L)//cleanup
    set t = null//cleanup
endfunction

function Twisted_Mind takes nothing returns nothing
   local location L = GetSpellTargetLoc()
   local unit U = GetSpellAbilityUnit()
   local group G = GetUnitsInRangeOfLocMatching(I2R(GetUnitAbilityLevel(U, 'A004') * 300), L, Condition(function AndConditions))
   local unit S
   local timer t = CreateTimer()
   call CreateNUnitsAtLoc(1, 'h001', GetOwningPlayer(U), L, 270.)
   set S = GetLastCreatedUnit()
   call UnitAddAbility(S, 'A003')
   call UnitRemoveAbility(S, 'A003')
   call SetUnitFlyHeight(S, -770.00, 400.00)
   call SetHandleHandle(t, "g", G)
   call SetHandleHandle(t, "s", S)
   call SetHandleHandle(t, "u", U)
   call SetHandleHandle(t, "l", L)//this is changed
   call TimerStart(t, 1., true, function Attract)
   call RemoveLocation(L)//cleanup
   call DestroyGroup(G)//cleanup
   set S=null
endfunction

To put it simple your problem was the ForGroup you tried to make.
I am not sure if my code has no mistakes, not tested and I have some doubts.
This way of picking up all the units in the group is the best suited for this job I could think of (and offcorse there is another way of doing the damaging part but this seems fine to me)
The leak clean ups are my doubts as I am not sure where do you have to remove/destroy things that have been attached.
Someone else should correct me there :D
Aside from that I do not know how to optimize it more.
 
Last edited:
Level 10
Joined
Sep 6, 2007
Messages
440
"SET" picked=FirstOfGroup(G)
BTW, what's function EFFECT? Probably The looping function right? And what does FirstOfGroupDo? Is it just to define the picked unit? And you can't call locations like that. Earth Fury told me to use it as two different reals and then from a location in the other one. I may do those little edits... I'll test it tomorrow.
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
Ops, that one slipped.
It was from an earlier stage. I have removed the line from the post(the whole call ForGroup(G, function Effect)). As I stated above I did not test this at all.
Well yes, 2 reals are better than one location. But you still have to make a local Location it is just like local location L=Lococation(GetHandleReal(t,"X"),GetHandleReal(t,"Y")) (offcourse you have to erase the SetHandleHandle(t,"l",L) and add SetHandleReal(t,"X",GetLocX(L)) and SetHandleReal(t,"X",GetLocY(L)). As I said I was not sure if that would work or not.
Yes. I used FirstOFGroup as a way to pick a unit from the group also picking a rondom unit from the group is a option, but this is faster(because of the random integer function in the Random unit function :D )
 
Level 5
Joined
Jan 15, 2007
Messages
199
Several Fixes/Changes to spwin's code:
Note - spwin's code will not work.

JASS:
function Conditions takes nothing returns boolean
   return GetSpellAbilityId() == 'A005'
endfunction

function Attract takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer i = GetHandleInt(t, "i") + 1
    local location L=GetHandleHandle(t,"l")
    local unit u = GetHandleUnit( t, "u" )
    local group g = CreateGroup()
    local unit enum
    if i == 10 then

        call RemoveUnit( GetHandleUnit(t, "s") )
        call FlushHandleLocals( t )
        call PauseTimer( t )
        call RemoveLocation( L )
        call DestroyTimer(t)

     else
        call GroupEnumUnitsInRange( g, GetLocationX( L ), GetLocationY( L ), 300 * GetUnitAbilityLevel( u, 'A005' ), null )
        //Could replace null with a global true filter if you have one in you map. null filters in group enums may leak?

        loop
            set enum = FirstOfGroup( g )
            exitwhen enum == null
            if ( not IsUnitType( enum, UNIT_TYPE_STRUCTURE ) ) and IsUnitEnemy( enum, GetOwningPlayer( u ) then
                call UnitDamageTarget(u, enum, GetUnitState( enum, UNIT_STATE_MANA ) * 5, true, true, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MIND, null )
                call SetUnitState( enum, UNIT_STATE_MANA, GetUnitState( enum, UNIT_STATE_MANA ) - 20 )
            endif
            call GroupRemoveUnit( g, enum )
        endloop

        call SetHandleInt(t, "i", i)
    endif

    call DestroyGroup( g )
    set g = null
    set l = null
    set t = null
    set u = null
endfunction

function Twisted_Mind takes nothing returns nothing
   local location l = GetSpellTargetLoc()
   local unit u = GetSpellAbilityUnit()
   local unit s = CreateUnitAtLoc( GetOwningPlayer( u ), 'h001', L, 270.)
   local timer t = CreateTimer()
   call UnitAddAbility(S, 'A003')
   call UnitRemoveAbility(S, 'A003')
   call SetUnitFlyHeight(S, -770.00, 400.00 )
   call SetHandleHandle( t, "s", s )
   call SetHandleHandle( t, "u", u )
   call SetHandleHandle( t, "l", l )
   call SetHandleInt( t, "i", 0 )
   call TimerStart(t, 1., true, function Attract)
   set l = null
   set s = null
endfunction

Also random unit is horribly slow, because it looks through the group, assigns each one a number, then randomly chooses a number. Each call of it would be slower than the rest of the whole group enum and looping through it combined.
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
Here is the updated, optimized, tested, working code.
JASS:
function AndConditions takes nothing returns boolean
    return IsUnitType( GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false
endfunction


function Attract takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer i = GetHandleInt(t, "i") + 1
    local group G= CreateGroup()
    local unit S=GetHandleUnit(t,"s")
    local unit picked
    if i == 10 then
        call RemoveUnit(S)
        call FlushHandleLocals(t)
        call PauseTimer(t)
        call DestroyTimer(t)
     else
        call GroupEnumUnitsInRange( G, GetHandleReal(t,"X"), GetHandleReal(t,"Y"), 300 * GetHandleInt(t,"l"), Condition(function AndConditions)) 
        loop
            set picked=FirstOfGroup(G)
            exitwhen picked==null
            if(IsUnitAlly(picked, GetOwningPlayer(S))==false) then
            call UnitDamageTarget(S, picked, GetUnitState(picked, UNIT_STATE_MANA) * 5, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MIND, WEAPON_TYPE_WHOKNOWS)
            call SetUnitState(picked, UNIT_STATE_MANA, GetUnitState(picked, UNIT_STATE_MANA) - 20)
            endif
            call GroupRemoveUnit(G,picked)
        endloop
        call SetHandleInt(t, "i", i)
    endif
    call DestroyGroup(G)
    set t = null
endfunction

function Twisted_Mind takes nothing returns nothing
   local location L = GetSpellTargetLoc()
   local real X=GetLocationX(L)
   local real Y=GetLocationY(L)
   local unit S=CreateUnit(GetOwningPlayer(GetTriggerUnit()),'h001',X,Y,270)
   local timer t = CreateTimer()
   call RemoveLocation(L)
   call UnitAddAbility(S, 'A003')
   call UnitRemoveAbility(S, 'A003')
   call SetUnitFlyHeight(S, -770.00, 400.00)
   call SetHandleHandle(t, "s", S)
   call SetHandleInt(t, "i", 0)
   call SetHandleInt(t, "l",GetUnitAbilityLevel( GetSpellAbilityUnit(), 'A005' ))
   call SetHandleReal(t, "X", X)
   call SetHandleReal(t, "Y", Y)
   call TimerStart(t, 1., true, function Attract)
   set S=null
endfunction
function InitTrig_Twisted_Mind takes nothing returns nothing
   set gg_trg_Twisted_Mind = CreateTrigger()
   call TriggerRegisterAnyUnitEventBJ(gg_trg_Twisted_Mind, EVENT_PLAYER_UNIT_SPELL_EFFECT)
   call TriggerAddCondition(gg_trg_Twisted_Mind, Condition(function Conditions))
   call TriggerAddAction(gg_trg_Twisted_Mind, function Twisted_Mind)
endfunction
Here is an example map(I did not play around with the created unit):

Here it is again quite optimized but it is still not as fast as possible as X and Y are Attached(Handle Variables use game cache which is rather slow, so using it as little as possible is recommended), instead of just the location.

And can be even further optimized by using a ForGroup instead of a loop, but that requires a global variable for the unit that does the damaging.
P.s.Bobo_The_Kodo you got my nick wrong :angry:
 

Attachments

  • abv.w3x
    20.8 KB · Views: 35
Last edited:
Level 5
Joined
Jan 15, 2007
Messages
199
w/e.. anyways spiwn..

Your trigger leaks. You need several of the variables in Twisted_Mind

Read things that leak

edit: oh and in the Attract you leak as well.. look at the code i posted

edit2: and u removed the condition for the spellid???? but still called it in the init??

edit3: if you already have an if statement in teh loop, it is more efficient to use an and operator with what you put in AndConditions, seeing as it dosnt have to run another cond

editagain: it looks neater if you use lowercase for single char variable names

editagain2: and mine is basically the same as urs but dosnt leak and is neater
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
I never said my code was leakless.
I said it was working, which is hard to say for the one you posted.
If you want the leakless version here it is:

JASS:
function Conditions takes nothing returns boolean
   return GetSpellAbilityId() == 'A005'
endfunction

function Attract takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer i = GetHandleInt(t, "i") + 1
    local group G= CreateGroup()
    local unit S=GetHandleUnit(t,"s")
    local unit picked
    if i == 10 then
        call RemoveUnit(S)
        call FlushHandleLocals(t)
        call PauseTimer(t)
        call DestroyTimer(t)
     else
        call GroupEnumUnitsInRange( G, GetHandleReal(t,"X"), GetHandleReal(t,"Y"), 300 * GetHandleInt(t,"l"),null)
        loop
            set picked=FirstOfGroup(G)
            exitwhen picked==null
            if(IsUnitAlly(picked, GetOwningPlayer(S))==false and IsUnitType( GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false) then
            call UnitDamageTarget(S, picked, GetUnitState(picked, UNIT_STATE_MANA) * 5, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MIND, WEAPON_TYPE_WHOKNOWS)
            call SetUnitState(picked, UNIT_STATE_MANA, GetUnitState(picked, UNIT_STATE_MANA) - 20)
            endif
            call GroupRemoveUnit(G,picked)
        endloop
        call SetHandleInt(t, "i", i)
    endif
    call DestroyGroup(G)
    set G=null
    set S=null
    set t=null
endfunction

function Twisted_Mind takes nothing returns nothing
   local location L = GetSpellTargetLoc()
   local real X=GetLocationX(L)
   local real Y=GetLocationY(L)
   local unit S=CreateUnit(GetOwningPlayer(GetTriggerUnit()),'h001',X,Y,270)
   local timer t = CreateTimer()
   call RemoveLocation(L)
   call UnitAddAbility(S, 'A003')
   call UnitRemoveAbility(S, 'A003')
   call SetUnitFlyHeight(S, -770.00, 400.00)
   call SetHandleHandle(t, "s", S)
   call SetHandleInt(t, "i", 0)
   call SetHandleInt(t, "l",GetUnitAbilityLevel( GetSpellAbilityUnit(), 'A005' ))
   call SetHandleReal(t, "X", X)
   call SetHandleReal(t, "Y", Y)
   call TimerStart(t, 1, true, function Attract)
   set S=null
   set L=null
   set t=null
endfunction
function InitTrig_Twisted_Mind takes nothing returns nothing
   set gg_trg_Twisted_Mind = CreateTrigger()
   call TriggerRegisterAnyUnitEventBJ(gg_trg_Twisted_Mind, EVENT_PLAYER_UNIT_SPELL_EFFECT)
   call TriggerAddCondition(gg_trg_Twisted_Mind, Condition(function Conditions))
   call TriggerAddAction(gg_trg_Twisted_Mind, function Twisted_Mind)
endfunction

No I haven't removed the condition for the ability ID it is just not in code I posted(map was included, and as far as I know no one was or is going to make any changes to that thing so why should we post it except maybe if the the posting user likes long posts).
About upper or lower case - a matter of personal opinion.
 

Attachments

  • abv.w3x
    20.8 KB · Views: 29
Status
Not open for further replies.
Top