• 🏆 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] Illusion Loop Problem

Status
Not open for further replies.
Level 4
Joined
Apr 25, 2011
Messages
73
I need help with:

JASS:
function Trig_Illusion_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A002'
endfunction

function Trig_Illusion_Actions takes nothing returns nothing
    local unit t = GetSpellTargetUnit()
    local unit c = GetTriggerUnit()
    local integer i = GetUnitTypeId(t)
    local integer l = GetUnitAbilityLevel(c, 'A002' )
    local real x = GetUnitX(t)
    local real y = GetUnitY(t)
    local player p1 = GetOwningPlayer(c)
    local player p2 = GetOwningPlayer(t)
    
    local unit m =  CreateUnit( p1, i, x, y, bj_UNIT_FACING )
    
    call SetUnitColor( m, GetPlayerColor(p2) )
    call UnitAddAbility(m, 'Aloc')
    call UnitApplyTimedLife(m, 'BTLF', I2R(l))
    call SetUnitPathing( m, false )
    call SetUnitVertexColor(m, 100, 100, 100, 50)
    call SetUnitInvulnerable( m, true )
    loop
        call IssueTargetOrder( m, "attack" , t )    
        if GetUnitState( t , UNIT_STATE_LIFE) <= 0 then
            set m = null
        endif
        if GetUnitState( m , UNIT_STATE_LIFE) <= 0 then
            set m = null
        endif
        exitwhen m == null 
    endloop
    
    call RemoveUnit(m)
    set m = null
    set t = null
    set c = null
    set p1 = null
    set p2 = null

endfunction

//===========================================================================
function InitTrig_Illusion takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( t, Condition( function Trig_Illusion_Conditions ) )
    call TriggerAddAction( t, function Trig_Illusion_Actions )
endfunction

The problem is that it never goes into the "IF"s. So it won't leave the loop. And probably this means it leaks...
Anyway, when I cast it, it lags a little and then it works pretty well.

My main problems are:
1. The lag when I cast the spell.
2. The Illusion does not die / disappear if the Target is dead... And that is because it never gets the loop.

I seems that the lag goes away if I replace
JASS:
        if GetUnitState( m , UNIT_STATE_LIFE) <= 0 then
with
JASS:
        if GetUnitState( m , UNIT_STATE_LIFE) <= GetUnitState( m ,  UNIT_STATE_MAX_LIFE) then

But this method seems like it doesn't go through the loop at all...
I think I might need timers... But I'm not that good at timers...
If you guys have any idea how to get rid of the lag and get out of the loop please let me know...
 
Level 16
Joined
Dec 15, 2011
Messages
1,423
It is really funny but dead units don't exactly have negative life.

Actually, if the unit ever has negative life, Warcraft 3 will attempt to correct the error by adding a HUGE amount of life to it (iirc it is 2147483647). It feels kinda like some kind of insurance policy =P

For your problem, either go with IsUnitType(m, UNIT_TYPE_DEAD) or GetWidgetLife(u) < 0.405.

One more thing, the Remove and nulling of m below is kind unnecessary because the loop exits only when m is null.

edit

Oh and yeah, you will need a timer. Purge's post below clarifies it quite well.
 
You need timers. Right now, it is freezing because the unit is constantly issued an attack order. Keep in mind that loops don't take breaks (until they hit the op limit), they will continuously call the functions. Now, our computers can handle quite a bit--hundreds of thousands of operations at a time--but an infinite loop will freeze them up.

What you want instead is a timer that will check repeatedly if either of the units are dead. However, before we can help you, you need to give some info:
(1) What is your spell supposed to do?
(2) Do you have Jass NewGen Pack?
 
Level 4
Joined
Apr 25, 2011
Messages
73
~Doomlord~
This is how I thought of it. Since I only use "i" just one I though of getting it in the loop.
But the problem is the same... It lags less now (I think), but the unit still doesn't disappear...

JASS:
function Trig_Illusion_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A002'
endfunction

function Trig_Illusion_Actions takes nothing returns nothing
    local unit t = GetSpellTargetUnit()
    local unit c = GetTriggerUnit()
    local integer i = GetUnitTypeId(t)
    local integer l = GetUnitAbilityLevel(c, 'A002' )
    local real x = GetUnitX(t)
    local real y = GetUnitY(t)
    local player p1 = GetOwningPlayer(c)
    local player p2 = GetOwningPlayer(t)
    
    local unit m =  CreateUnit( p1, i, x, y, bj_UNIT_FACING )
    
    call SetUnitColor( m, GetPlayerColor(p2) )
    call UnitAddAbility(m, 'Aloc')
    call UnitApplyTimedLife(m, 'BTLF', I2R(l))
    call SetUnitPathing( m, false )
    call SetUnitVertexColor(m, 100, 100, 100, 50)
    call SetUnitInvulnerable( m, true )
    loop
        call IssueTargetOrder( m, "attack" , t )    
        if IsUnitType(t, UNIT_TYPE_DEAD) then
            set i = 2
        endif
        if IsUnitType(m, UNIT_TYPE_DEAD) then
            set i = 2
        endif
        exitwhen i == 2
    endloop
    
    call RemoveUnit(m)
    set t = null
    set c = null
    set p1 = null
    set p2 = null
    set m = null
endfunction

//===========================================================================
function InitTrig_Illusion takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( t, Condition( function Trig_Illusion_Conditions ) )
    call TriggerAddAction( t, function Trig_Illusion_Actions )
endfunction

~PurgeandFire~
1. Create a copy of the target and make the copy attack the target. (kind of Terror Blade's spell, without the slow and -damage; mine does full damage (I know that making the slow and -damage might be harder, but this is a little bit of originality))
2. I think I have it since I'm using NewGen WE.exe. But don't know exactly how to use it properly. (only using the function list)

So? What is the conclusion? Any idea? Will it work?
 
Level 16
Joined
Dec 15, 2011
Messages
1,423
~Doomlord~
This is how I thought of it. Since I only use "i" just one I though of getting it in the loop.
But the problem is the same... It lags less now (I think), but the unit still doesn't disappear...

JASS:
function Trig_Illusion_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A002'
endfunction

function Trig_Illusion_Actions takes nothing returns nothing
    local unit t = GetSpellTargetUnit()
    local unit c = GetTriggerUnit()
    local integer i = GetUnitTypeId(t)
    local integer l = GetUnitAbilityLevel(c, 'A002' )
    local real x = GetUnitX(t)
    local real y = GetUnitY(t)
    local player p1 = GetOwningPlayer(c)
    local player p2 = GetOwningPlayer(t)
    
    local unit m =  CreateUnit( p1, i, x, y, bj_UNIT_FACING )
    
    call SetUnitColor( m, GetPlayerColor(p2) )
    call UnitAddAbility(m, 'Aloc')
    call UnitApplyTimedLife(m, 'BTLF', I2R(l))
    call SetUnitPathing( m, false )
    call SetUnitVertexColor(m, 100, 100, 100, 50)
    call SetUnitInvulnerable( m, true )
    loop
        call IssueTargetOrder( m, "attack" , t )    
        if IsUnitType(t, UNIT_TYPE_DEAD) then
            set i = 2
        endif
        if IsUnitType(m, UNIT_TYPE_DEAD) then
            set i = 2
        endif
        exitwhen i == 2
    endloop
    
    call RemoveUnit(m)
    set t = null
    set c = null
    set p1 = null
    set p2 = null
    set m = null
endfunction

//===========================================================================
function InitTrig_Illusion takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( t, Condition( function Trig_Illusion_Conditions ) )
    call TriggerAddAction( t, function Trig_Illusion_Actions )
endfunction

The loop will not be stopped because i is never 2. You need a timer to overcome this issue.

Here is an example code. It is not indented so please don't follow this style :p

JASS:
function TimerCallback takes nothing returns nothing
    local timer t = GetExpiredTimer()

    // Load data here

    if IsUnitType(target, UNIT_TYPE_DEAD) then
        call KillUnit(dummy)

        call PauseTimer(t)
        call DestroyTimer(t)

    endif

    set t = null
endfunction

function Trig_Illusion_Actions takes nothing returns nothing
    // create some locals here
    local timer t = CreateTimer()

    // You pass data to the timer func by a hashtable or another method that you prefer.

    call TimerStart(t, 0.1, true, function TimerCallback)
 
Last edited by a moderator:
Level 20
Joined
Aug 13, 2013
Messages
1,696
Anyway, I know how to create that spell :goblin_yeah:. Simply go to OE (Object Editor) then to then Select "Items" find this to the Items named "Wand of Illusions". Then click that item, after that see the abilities of that Item then find that ability to the "Abilities" -->>> "Special" then find that ability. Make sure you create a custom item for Wand of Illusion and custom ability See the screenshots below: (because HARD to explain ^^.)

231860-albums6686-picture73309.png


231860-albums6686-picture73310.png
 
Level 4
Joined
Apr 25, 2011
Messages
73
~Doomlord~

JASS:
    // You pass data to the timer func by a hashtable or another method that you prefer.

That is the problem. Don't know how to do that.
I only know that function take something and return something. This is my only way to move this around functions and it seems timers don't take anything (or return)

~jakeZinc~
It might work... But I need the illusion to have Locust, be invulnerable, have 50% transparency and attack the target till one of them dies.
 
Level 16
Joined
Dec 15, 2011
Messages
1,423
~Doomlord~

JASS:
    // You pass data to the timer func by a hashtable or another method that you prefer.

That is the problem. Don't know how to do that.
I only know that function take something and return something. This is my only way to move this around functions and it seems timers don't take anything (or return)

Timer is a type of handle and all handles in Warcraft 3 have something called handle id. A handle id is a unique value that represents the handle itself and we manipulate stuffs using said value as a hashtable key.

I am going to presume that you know how to work with hashtables. Now you will use the handle id of the created timer (get it through GetHandleId(t)) as the parent key. Then we store datas like this (don't forget to initialize the hashtable beforehand with set udg_Hashtable = InitHashtable()). The following example will be saving the dummy and the target.

JASS:
call SaveUnitHandle(udg_Hashtable, GetHandleId(t), 0, dummy)
call SaveUnitHandle(udg_Hashtable, GetHandleId(t), 1, target)

Then we load it later with the corresponding functions. Once you are done, flush the child hashtable with call FlushChildHashtable(udg_Hashtable, GetHandleId(t)). This will free up space in the hashtable for later usage.

~jakeZinc~
It might work... But I need the illusion to have Locust, be invulnerable, have 50% transparency and attack the target till one of them dies.

I remember there is a way to detect an illusion's creation. You can catch that event, check some conditions and add those properties to the newly created illusion. Search around the forum for it~~
 
Last edited:
Level 4
Joined
Apr 25, 2011
Messages
73
I used hashtables. Once.
Anyway, it seems I don't find any Hashtable or Handle in the function list... Why's that?

Maybe you can help me with the spell by doing it, please? xD
Since I can't do it and you seem to have some experience with JASS.

About the other comment... I still need to remove the unit if the illusion or the target dies.
 
Level 20
Joined
Aug 13, 2013
Messages
1,696
I remember there is a way to detect when an illusion's creation. You can catch that event, check some conditions and add those properties to the newly created illusion. Search around the forum for it~~

Yes there is a Illusion System made by Robbepop ^^. You can see it below:

Doppelwalk Ability from DotA is the example of this system.
It says "Do anything with your last created illusion", If you want a 50% transparent then do it
JASS:
call SetUnitVertexColor(m, 100, 100, 100, 50)
I'm hoping it helps for you ^^:goblin_good_job:. Anyway If this helps for you give credit to Robbepop :goblin_yeah:.
JASS:
scope Windwalk initializer init

private function condition takes nothing returns boolean
    return GetSpellAbilityId() == 'AOwk'
endfunction

private function main takes nothing returns nothing
    //Create an Illusion
    call CreateIllusion(GetTriggerUnit(), 1., 1., 15.)

    //Do something with your created illusion!
    call SelectUnit(lastCreatedIllusion, true)
endfunction

private function init takes nothing returns nothing
    set gg_trg_test = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(gg_trg_test, EVENT_PLAYER_UNIT_SPELL_FINISH)
    call TriggerAddCondition(gg_trg_test, Condition(function condition))
    call TriggerAddAction(gg_trg_test, function main)
endfunction

endscope
 

Attachments

  • Illusion System.w3x
    25.6 KB · Views: 38
Level 16
Joined
Dec 15, 2011
Messages
1,423
I used hashtables. Once.
Anyway, it seems I don't find any Hashtable or Handle in the function list... Why's that?

Maybe you can help me with the spell by doing it, please? xD
Since I can't do it and you seem to have some experience with JASS.

About the other comment... I still need to remove the unit if the illusion or the target dies.

If you are using JNGP 1.5d or e, the hashtable functions won't be present in the function list, look around the forum for JNGP 2.0 beta. It is really stable imo ;)

Sorry but I don't really have time to do requests. You should ask someone else, most of them can create it in no time =P

Anyhow,

avatar213181_31.gif


^Just kidding ^^
 
Level 4
Joined
Apr 25, 2011
Messages
73
~jakeZinc~
Thanks, but I still have the problem with " kill / remove the illusion if one of them dies" ( well if the expiration timer expires, the illusion dies, but if the target dies then the illusion will start to attack nearby enemy units or (if there aren't any) will stay till the timer expires). Creating a illusion is not that hard... I just need to get rid of the illusion at the right time.

~Doomlord~
Ok ,I got JNGP beta ( I think). I can see handles and hashtables, now. But this doesn't change the fact that I can't use them properly.
 
Level 4
Joined
Apr 25, 2011
Messages
73
I need a spell. Like Terror Blade's.
Creates an illusion of the target and make the illusion attack the target till the timer of the illusion expires or till the target is dead. The first thing works well, but I can't remove the illusion when the target dies.

If anyone is good enough and has time, please make me the spell, if my trigger is wrong... or something...
 
Status
Not open for further replies.
Top