• 🏆 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] Opinion and help about spells

Status
Not open for further replies.
Hi guys, well, recently i decided to convert all my GUI spells into JASS, for greater efficiency. However it being more complicated than i expected ... to start i have this spell:

  • Frost Nova
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Frost Nova
    • Actions
      • Set FrostNovaLevel = (Level of Frost Nova for (Triggering unit))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • FrostNovaLevel Equal to 1
        • Then - Actions
          • For each (Integer A) from 1 to 16, do (Actions)
            • Loop - Actions
              • Unit - Create 1 Frost Nova Caster for (Owner of (Triggering unit)) at (Position of (Triggering unit)) facing Default building facing degrees
              • Unit - Set level of Frost nova wave (Neutral Hostile) for (Last created unit) to FrostNovaLevel
              • Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
              • Unit - Order (Last created unit) to Undead Crypt Lord - Impale ((Position of (Triggering unit)) offset by 100.00 towards PointofTargetNova degrees)
              • Set PointofTargetNova = (PointofTargetNova + 25.00)
        • Else - Actions
          • Do nothing
Jass converted version

JASS:
function Trig_Ice_Force_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A022' ) ) then
        return false
    endif
    return true
endfunction

function Trig_Ice_Force_Func002C takes nothing returns boolean
    if ( not ( udg_FrostNovaLevel == 1 ) ) then
        return false
    endif
    return true
endfunction

function Trig_Ice_Force_Actions takes nothing returns nothing
    set udg_FrostNovaLevel = GetUnitAbilityLevelSwapped('A022', GetTriggerUnit())
    if ( Trig_Ice_Force_Func002C() ) then
        set bj_forLoopAIndex = 1
        set bj_forLoopAIndexEnd = 16
        loop
            exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
            call CreateNUnitsAtLoc( 1, 'h01B', GetOwningPlayer(GetTriggerUnit()), GetUnitLoc(GetTriggerUnit()), bj_UNIT_FACING )
            call SetUnitAbilityLevelSwapped( 'A021', GetLastCreatedUnit(), udg_FrostNovaLevel )
            call UnitApplyTimedLifeBJ( 2.00, 'BTLF', GetLastCreatedUnit() )
            call IssuePointOrderLocBJ( GetLastCreatedUnit(), "impale", PolarProjectionBJ(GetUnitLoc(GetTriggerUnit()), 100.00, udg_Point_Nova_Spell) )
            set udg_Point_Nova_Spell = ( udg_Point_Nova_Spell + 25.00 )
            set bj_forLoopAIndex = bj_forLoopAIndex + 1
        endloop
    else
        call DoNothing(  )
    endif
endfunction

//===========================================================================
function InitTrig_Ice_Force takes nothing returns nothing
    set gg_trg_Ice_Force = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Ice_Force, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Ice_Force, Condition( function Trig_Ice_Force_Conditions ) )
    call TriggerAddAction( gg_trg_Ice_Force, function Trig_Ice_Force_Actions )
endfunction

This is the GUi version .... which i don't even know if it is MUI... and leaks like hell(that i am sure).

Now here is my version of the same spell:

JASS:
function IceForce_Conds takes nothing returns boolean
    return GetSpellAbilityId() == 'A022'
endfunction
//==========================================================================
function IceForce_Acts takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local unit dum
    local location loc = GetUnitLoc(caster) 
    set bj_forLoopAIndex = 1
    set bj_forLoopAIndexEnd = 16
    loop
        exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
        set dum = CreateUnit(GetOwningPlayer(caster), 'h01B', GetUnitX(caster), GetUnitY(caster), 0)
        call SetUnitAbilityLevel(dum, 'A021', 1)
        call UnitApplyTimedLife(dum, 'BTLF', 2.00)
        call IssuePointOrderLoc(dum, "impale", PolarProjectionBJ(loc), 100.00, udg_Point_Nova_Spell) ) 
        set udg_Point_Nova_Spell = ( udg_Point_Nova_Spell + 25.00 )
        set bj_forLoopAIndex = bj_forLoopAIndex + 1
    endloop
endfunction
//===========================================================================
function InitTrig_Ice_Force takes nothing returns nothing
    local trigger IceForce = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( IceForce, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( IceForce, Condition( function IceForce_Conds ) )
    call TriggerAddAction( IceForce, function IceForce_Acts )
    set IceForce = null
endfunction

A lot smaller but there is something wrong ... So, could you guys help me ???
For now i just want to improve the GUI spell, and see if my JASS version works .. =S



Another spell i found is this knock back spell:
JASS:
constant function BloodyPile_SpellId takes nothing returns integer
    return 'A000' //Rawcode of the BloodyPile Ability
endfunction   

constant function BloodyPile_SlideDuration takes nothing returns real
    return 0.60 //Defines the slide duration of target
endfunction

constant function BloodyPile_SpellDemage takes integer level returns real
    return level*90.00
    //This formula adds 90 demage per level of the spell
    //Starting from 90
endfunction 

constant function BloodyPile_TargetConditions takes unit Caster, unit Target returns boolean
    return (Target != Caster) and ( IsPlayerEnemy(GetOwningPlayer(Target), GetOwningPlayer(Caster)) ) and not(IsUnitType(Target, UNIT_TYPE_STRUCTURE)) and not(IsUnitType(Target,UNIT_TYPE_DEAD)) and not(IsUnitType(Target, UNIT_TYPE_MAGIC_IMMUNE))
    //Defines the targetable units which will get demage from unit sliding effect
endfunction

// This spell is playing target units death animation while sliding
// This gives a pain effect but if you use units which has no fleshy
// body animation modify this function

constant function BloodyPile_DeathAnimation takes nothing returns boolean
    return true //Make this "false" to disable targets death animation.
endfunction
//===================================================================================================

function BloodyPile_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == BloodyPile_SpellId()
endfunction

//Kills Picked Destructables near target when sliding
function BloodyPile_KillTreesOnTheWay takes nothing returns nothing
    call KillDestructable( GetEnumDestructable() )
endfunction

//Makes target unit slide and demage nearby units and throw them avay from it
function BloodyPile_SlideUnit takes nothing returns nothing    
    local timer Loop = GetExpiredTimer() 
    local unit Target = H2U(GetHandleHandle(Loop, "Target"))
    local unit Caster = H2U(GetHandleHandle(Loop, "Caster"))
    local unit PickedUnit
    local group UnitsInRange
    local real Angle = GetHandleReal(Loop, "Angle")
    local real AngleSmall
    local location TargetPoint = GetUnitLoc(Target)
    local location TargetPointSmall
    local location MovePoint = PolarProjectionBJ(TargetPoint,20.00,Angle)
    local location MovePointSmall
    local effect MiniEffect

    call SetUnitPositionLoc(Target, MovePoint)
    set MiniEffect = AddSpecialEffectTarget("Abilities\\Weapons\\FrostWyrmMissile\\FrostWyrmMissile.mdl",Target,"origin")
    call DestroyEffect(MiniEffect)
    call EnumDestructablesInCircleBJ( 200.00, TargetPoint, function BloodyPile_KillTreesOnTheWay )
    set UnitsInRange = GetUnitsInRangeOfLocAll(250, TargetPoint)
    call GroupRemoveUnit(UnitsInRange,Target)
    set PickedUnit = FirstOfGroup(UnitsInRange)

    loop
        exitwhen PickedUnit==null
        set PickedUnit = FirstOfGroup(UnitsInRange)
        call GroupRemoveUnit(UnitsInRange,PickedUnit)
        if (BloodyPile_TargetConditions(Caster, PickedUnit)) then            
            set TargetPointSmall = GetUnitLoc(PickedUnit)
            set AngleSmall = AngleBetweenPoints(TargetPoint,TargetPointSmall)
            set MovePointSmall = PolarProjectionBJ(TargetPointSmall,80,AngleSmall)
            call SetUnitPositionLoc(PickedUnit, MovePointSmall)
            call UnitDamageTarget(Caster,PickedUnit,25*GetUnitAbilityLevel(Caster, BloodyPile_SpellId()),false,false,null,null,null)

            call RemoveLocation(TargetPointSmall)
            call RemoveLocation(MovePointSmall)
        endif
    endloop      
  
    call RemoveLocation(MovePoint)
    call RemoveLocation(TargetPoint)
    call DestroyGroup(UnitsInRange)    
    set Caster = null
    set Target = null
endfunction

function BloodyPile_Actions takes nothing returns nothing
    local timer Loop = CreateTimer()
    local effect StunEffect
    local unit Target = GetSpellTargetUnit()
    local unit Caster = GetSpellAbilityUnit()
    local location TargetPoint = GetUnitLoc(Target)
    local location CasterPoint = GetUnitLoc(Caster)
    local real Angle = AngleBetweenPoints(CasterPoint, TargetPoint)
    local real Demage = BloodyPile_SpellDemage(GetUnitAbilityLevel(Caster, BloodyPile_SpellId()))
    local real Duration = BloodyPile_SlideDuration()

 
    call SetHandleHandle(Loop, "Target", Target) 
    call SetHandleHandle(Loop, "Caster", Caster)
    call SetHandleReal(Loop, "Angle", Angle)
    call SetUnitFacingToFaceUnitTimed( Target, Caster, 0 )
    call PauseUnit(Target,true)
    
    if (BloodyPile_DeathAnimation()) then
        call SetUnitAnimation( Target, "death" )
    endif
    
    call UnitDamageTarget(Caster,Target,Demage,false,false,null,null,null)
    call TimerStart(Loop, 0.03, true, function BloodyPile_SlideUnit)    
    call TriggerSleepAction( Duration )
    call PauseTimer(Loop) 
    call FlushHandleLocals(Loop)
    call DestroyTimer(Loop) 

    if not (IsUnitType(Target,UNIT_TYPE_DEAD)) then
        set StunEffect = AddSpecialEffectTarget( "Abilities\\Spells\\Human\\Thunderclap\\ThunderclapTarget.mdl", Target, "overhead")        
        call TriggerSleepAction( 1.25 * GetUnitAbilityLevel(Caster, BloodyPile_SpellId()))
        call DestroyEffectBJ( StunEffect )
    endif
    call PauseUnit(Target,false)

    call RemoveLocation(TargetPoint)
    call RemoveLocation(CasterPoint)
    set Caster = null
    set Target = null    
endfunction

// ===========================================================================
function InitTrig_BloodyPile takes nothing returns nothing
    local trigger gg_trg_BloodyPile = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( gg_trg_BloodyPile, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_BloodyPile, Condition( function BloodyPile_Conditions ) )
    call TriggerAddAction( gg_trg_BloodyPile, function BloodyPile_Actions )
endfunction

It is really cool, it knockback units destroys trees, creates a nice smooth effect and plays the unit death animation.
Still my JASS editor finds some errors ... However the spell seems to work fine... Which leads me to the question, is this spell MUI and leak free ??? Why are the errors here ??

Errors:
41-46 Undeclared function GetHandleHandle; Undeclared function H2U
46 Cannot convert null to real
96-97 Undeclared function SetHandleHandle
98 Undeclared function SetHandleReal
100 Undeclared function FlushHandleLocals

10 errors total

I know about handles, but i don't know why the jasscraft sees them as an error ... is there anything wrong with the spell ???? Or is my program going nuts ?

plx help =S
 
Last edited:
Level 20
Joined
Apr 22, 2007
Messages
1,960
Gah, use coordinates please. loc is leaking.

Also, you closed the parenthesis on PolarProjectionBJ(loc). It should be: PolarProjectionBJ(loc, 100.00, udg_Point_Nova_Spell).

You could also use a local integer for the loop count. No need to use bj globals.

Finally, why don't you use a local for udg_Point_Nova_Spell? Here's how I would do it:
JASS:
function IceForce_Conds takes nothing returns boolean
    return GetSpellAbilityId() == 'A022'
endfunction
//========================================================
function IceForce_Acts takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local unit dum
    local real x=GetUnitX(caster)
    local real y=GetUnitY(caster)
    local integer i=1
    loop
        exitwhen i>16
        set dum = CreateUnit(GetOwningPlayer(caster), 'h01B',x,y, 0)
        call SetUnitAbilityLevel(dum, 'A021', 1)
        call UnitApplyTimedLife(dum, 'BTLF', 2.00)
        call IssuePointOrder(dum, "impale",x+Cos(22.5*i*bj_DEGTORAD)*100,y+Sin(22.5*i*bj_DEGTORAD)*100)
        call UnitAddAbility(dum,'Aloc')
        set i=i+1
    endloop
    set caster=null
    set dum=null
endfunction
//========================================================
function InitTrig_Ice_Force takes nothing returns nothing
    set gg_trg_Ice_Force = CreateTrigger( )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Ice_Force, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Ice_Force, Condition( function IceForce_Conds ) )
    call TriggerAddAction( gg_trg_Ice_Force, function IceForce_Acts )
endfunction
Tested and works fine.
 
Exactly my point, i knew my version had something wrong .. just forgot to destroy the loc and nullify it ... but i was going to do it ....

The main reason why i had so many problems was because i didn't understand the use of so many globals =S it just overloads my brain ..
thx for help

Still
JASS:
x+Cos(22.5*i*bj_DEGTORAD)*100,y+Sin(22.5*i*bj_DEGTORAD)*100)
HOLYMACAROLY !! what the h*** is this ... BJ's are bad, but you use them ... also where does that formula come from !? Thx anyway, please reply back.

Also any ideas about my seconds spell !??!!? why is it wrong or something !??!? guys plz ??
 
Level 20
Joined
Apr 22, 2007
Messages
1,960
Got into trigonometry yet? Basically, what I did is polar projection using coordinates.

Cos A = a/c
Sin A = b/c
Where c is the hypotenuse of a right triangle, and a is the side opposite to the angle A. b is the adjacent side. You can use x + Cos(direction)*length to project an x coordinate, and y + Sin(direction)*length to project a y coordinate. Or course, the direction angle is in radians, so I used bj_DEGTORAD*22.5 to convert it that way. I could have used CosBJ, but that's a BJ function = bad.

I'm not using BJ functions, I'm using bj globals, which aren't bad at all. You could still use this (which is somewhat better and shorter). Here, use this line if you don't want to use the bj globals:
JASS:
call IssuePointOrder(dum, "impale",x+Cos(i*3.14159/8)*100,y+Sin(i*3.14159/8)*100)
I'll check up your other spell.

EDIT: Found the bugs and I'm overall optimizing it. I'll post it up when I'm done.

EDIT2: Remaking it completely.
 
Last edited:
MMmmm, i didn't know the other spell i posted was such a mess =S

Anyway, thx by the tips on the first spell. I changed some stuff as you will notice, and removed some locals to speed up the process.
About the polarprojectionBJ, well, i guess there there are things i will never understand ... this is the second time i can't understand what you guys do =S
Anyway, really thx by the help, i have also added some rep points to you =)

Improved spell:
JASS:
function IceForce_Conds takes nothing returns boolean  
    return GetSpellAbilityId() == 'A022' 
endfunction 
//======================================================== 
function IceForce_Acts takes nothing returns nothing  
    local unit caster = GetTriggerUnit()  
    local unit dum  
    local integer i=1 
    loop  
        exitwhen i>16 
        set dum = CreateUnit(GetOwningPlayer(caster), 'h01B',GetUnitX(caster),GetUnitY(caster), 0)  
        call UnitAddAbility(dum,'Aloc')
        call SetUnitAbilityLevel(dum, 'A021', 1)  
        call UnitApplyTimedLife(dum, 'BTLF', 2.00)  
        call IssuePointOrder(dum, "impale",GetUnitX(caster)+Cos(i*3.14159/8)*100,GetUnitY(caster)+Sin(i*3.14159/8)*100)
        set i=i+1 
    endloop  
    set caster=null  
    set dum=null 
endfunction 
//======================================================== 
function InitTrig_Ice_Force takes nothing returns nothing  
    local trigger IceForce = CreateTrigger( )  
    local integer index = 0
    loop
        exitwhen index == 16
        call TriggerRegisterPlayerUnitEvent(IceForce, Player(index), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
        set index = index + 1 
    endloop
    call TriggerAddCondition( IceForce, Condition( function IceForce_Conds ) )  
    call TriggerAddAction( IceForce, function IceForce_Acts ) 
    set IceForce = null
endfunction
 
Level 20
Joined
Apr 22, 2007
Messages
1,960
Here, I'm done with fixing up the knockback spell. If you would use JNGP, it would be easier to make, but blah.
JASS:
constant function BloodyPile_SpellId takes nothing returns integer
    return 'AHtb' //Rawcode of the BloodyPile Ability
endfunction
constant function BloodyPile_SpellDemage takes integer level returns real
    return level*90.00
    //This formula adds 90 demage per level of the spell
    //Starting from 90
endfunction
constant function BloodyPile_KnockPower takes nothing returns real
    return 40.
endfunction
constant function BloodyPile_TargetConditions takes unit Caster, unit Target returns boolean
    return (Target != Caster) and (Target!=bj_ghoul[100]) and ( IsPlayerEnemy(GetOwningPlayer(Target), GetOwningPlayer(Caster)) ) and not(IsUnitType(Target, UNIT_TYPE_STRUCTURE)) and not(IsUnitType(Target,UNIT_TYPE_DEAD)) and not(IsUnitType(Target, UNIT_TYPE_MAGIC_IMMUNE))
    //Defines the targetable units which will get demage from unit sliding effect
endfunction
// This spell is playing target units death animation while sliding
// This gives a pain effect but if you use units which has no fleshy
// body animation modify this function
constant function BloodyPile_DeathAnimation takes nothing returns boolean
    return true //Make this "false" to disable targets death animation.
endfunction
//===================================================================================================
function BloodyPile_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == BloodyPile_SpellId()
endfunction
//Kills Picked Destructables near target when sliding
function BloodyPile_KillTreesOnTheWay takes nothing returns nothing
    call KillDestructable( GetEnumDestructable() )
endfunction
function CheckPathabilityTrickGet takes nothing returns nothing
    set bj_rescueChangeColorUnit = bj_rescueChangeColorUnit or (GetEnumItem()!=bj_itemRandomCurrentPick)
endfunction
function CheckPathabilityTrick takes item p, real x, real y returns boolean
    local integer i=30
    local rect r
    call SetItemPosition(p,x,y)
    if ((Pow(GetItemX(p)-x,2)+Pow(GetItemY(p)-y,2))<=100) then
        return true
    endif
    set r=Rect(x-i,y-i,x+i,y+i)
    set bj_itemRandomCurrentPick=p
    set bj_rescueChangeColorUnit=false
    call EnumItemsInRect(r,null,function CheckPathabilityTrickGet)
    call RemoveRect(r)
    set r=null
    return bj_rescueChangeColorUnit
endfunction
function CheckPathability takes real x, real y returns boolean
    local item it = CreateItem('ciri',x,y)
    local boolean b = CheckPathabilityTrick(it,x,y)
    call SetItemVisible(it,false)
    call RemoveItem(it)
    set it=null
    return b
endfunction
function TrueFilter takes nothing returns boolean
    return true
endfunction
function DestroyEffectEx takes nothing returns nothing
    local effect StunEffect = AddSpecialEffectTarget( "Abilities\\Spells\\Human\\Thunderclap\\ThunderclapTarget.mdl", bj_ghoul[101], "overhead")
    local unit target=bj_ghoul[101]
    call PolledWait( 1.25 * GetUnitAbilityLevel(bj_ghoul[100], BloodyPile_SpellId()))
    call DestroyEffect( StunEffect )
    call PauseUnit(target,false)
    set StunEffect=null
endfunction
function BloodyPile_SlideUnit takes nothing returns nothing
    local timer t=GetExpiredTimer()
    local unit target=GetHandleUnit(t,"target")
    local unit caster=GetHandleUnit(t,"caster")
    local real radians=GetHandleReal(t,"angle")
    local real power=GetHandleReal(t,"power")
    local real x=GetUnitX(target)+power*Cos(radians)
    local real y=GetUnitY(target)+power*Sin(radians)
    local group g=CreateGroup()
    local unit u
    local real r
    local real x2
    local real y2
    local rect r2=Rect(x-100,y-100,x+100,y+100)
    set bj_ghoul[100]=target
    call EnumDestructablesInRect(r2,Filter(function TrueFilter),function BloodyPile_KillTreesOnTheWay)
    call GroupEnumUnitsInRange(g,x,y,100.,Filter(function TrueFilter))
    loop
        set u=FirstOfGroup(g)
        exitwhen u==null
        if BloodyPile_TargetConditions(caster,u) then
            set r=Atan2(GetUnitY(u)-GetUnitY(target),GetUnitX(u)-GetUnitX(target))
            call UnitDamageTarget(caster,u,25*GetUnitAbilityLevel(caster, BloodyPile_SpellId()),false,false,null,null,null)
            set x2=GetUnitX(u)+Cos(r)*40
            set y2=GetUnitY(u)+Sin(r)*40
            if CheckPathability(x2,y2) then
                call SetUnitX(u,x2)
                call SetUnitY(u,y2)
            endif
        endif
        call GroupRemoveUnit(g,u)
    endloop
    if CheckPathability(x,y) then
        call SetUnitX(target,x)
        call SetUnitY(target,y)
    endif
    set power=power-GetHandleReal(t,"totalpower")*0.1
    if power<=0 then
        call PauseTimer(t)
        call DestroyTimer(t)
        call FlushHandleLocals(t)
        if GetUnitState(target,UNIT_STATE_LIFE)>0 then
            set bj_ghoul[101]=target
            set bj_ghoul[100]=caster
            call ExecuteFunc("DestroyEffectEx")
        endif
    else
        call SetHandleReal(t,"power",power)
    endif
    call RemoveRect(r2)
    call DestroyGroup(g)
    set g=null
    set target=null
    set caster=null
    set u=null
    set r2=null
endfunction
function BloodyPile_Actions takes nothing returns nothing
    local timer t=CreateTimer()
    local unit caster=GetTriggerUnit()
    local unit target=GetSpellTargetUnit()
    local real angle=Atan2(GetUnitY(target)-GetUnitY(caster),GetUnitX(target)-GetUnitX(caster))
    call SetHandleHandle(t, "target", target)
    call SetHandleHandle(t, "caster", caster)
    call SetHandleReal(t, "angle", angle)
    call SetHandleReal(t,"totalpower",BloodyPile_KnockPower())
    call SetHandleReal(t,"power",BloodyPile_KnockPower())
    call SetUnitFacing(caster,angle*180/3.14159)
    call PauseUnit(target,true)
    if (BloodyPile_DeathAnimation()) then
        call SetUnitAnimation( target, "death" )
    endif
    call UnitDamageTarget(caster,target,BloodyPile_SpellDemage(GetUnitAbilityLevel(caster, BloodyPile_SpellId())),false,false,null,null,null)
    call TimerStart(t, 0.03, true, function BloodyPile_SlideUnit)
endfunction
// ===========================================================================
function InitTrig_BloodyPile takes nothing returns nothing
    set gg_trg_BloodyPile = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( gg_trg_BloodyPile, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_BloodyPile, Condition( function BloodyPile_Conditions ) )
    call TriggerAddAction( gg_trg_BloodyPile, function BloodyPile_Actions )
endfunction

IMO it looks nicer this way.

EDIT: Thanks for the rep :D. +REP @ you!

Here are some things you should be aware of. There's no need to make local triggers in your InitTrig function, because the global trigger variable IS in the map, and you can't take it off (unless you delete the trigger). You're just using up more map memory. Might aswell use the global trigger while it's there.

Here's an explanation of polar projections. Lemme look up the polar projection function in JassCraft...
JASS:
function PolarProjectionBJ takes location source, real dist, real angle returns location
    local real x = GetLocationX(source) + dist * Cos(angle * bj_DEGTORAD)
    local real y = GetLocationY(source) + dist * Sin(angle * bj_DEGTORAD)
    return Location(x, y)
endfunction
See? It's doing the exact same thing I did: x + Cos(angle)*length, y + Sin(angle)*length.

Here I'll try to explain using math... Lets say you have a right triangle (a triangle with a 90 degree angle). The side opposite to that angle is called the hypotenuse, which is often referred to as h, or c, in trigonometry. The other two sides of the triangle can have inversed names. I call them a, and b. Some other people call the, a (for adjacent) and o (for opposite). Usually, the angle that is opposite to a side is the variable letter of the side, in capital letters.

Heard about the Pythagorean theorem? One of the most important trigonometric equations. It states that a^2 + b^2 = c^2. The sum of the length of the sides of a right triangle, squared, equals the hypotenuse of that triangle squared. Other important equations:
sin A = a/c
cos A = b/c
tan A = a/b
Works in the other way too:
sin B = b/c
cos B = a/c
tan B = b/a
To get the angle value, we use the inverse functions:
cos(-1) b/c = A
sin(-1) a/c = A
tan(-1) a/b = A
And they work in the other way too.

Now, the use of the sine and cosine functions in Warcraft III. Well, Warcraft III works sort of like a 3 dimensional graph... with the X, Y and Z axis. Let's just use the X and Y axis for now. Let's say you have a point on the map, (0,0). You want to 'project' that point towards a direction:
triguf1.jpg


I don't know if you understand... I suck at explaining stuff. If you still don't understand, ask me a direct question about exactly what that you don't get, or www.wikipedia.org :D.
 
Last edited:
Very impressive explication =) I am very familiar with maths and i understand very well the trign stuff Triangles are easy for me as well as formulas. You also skipped some important maths formulas, that use cos, sin and tan.
sin^2+cos^2 = 1 ( I think don't remember very well).
and more formulas that i will soon post if you want or need.

But anyway i have 2 questions for you.
1 - How do i add the HandleVars into the memory of JAssCraft so it can access it for syntax checks ??
2 - The second question is about your explication. Personally in my opinion you did a great job in your mini-tutorial, however i didn't understood 2 things.
Those 2 things i will tell you tomorrow, because i don't have time right now, i am just making a quick reply.

Also, about the rep points, you are the one who deserves them, check out the logic:
1 - You help people > they give you a reward
2 - I ask for help > i am helped > I get a reward without doing anything (well, i asked of help, that can count =p)

So thx by the rep points but in my opinion, you deserve them more than i do =)
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
Those formulae have nothing to do with the math used here, though - that's for algebra stuff with no practical use within warcraft 3 (that I can think of)

1 - How do i add the HandleVars into the memory of JAssCraft so it can access it for syntax checks ??
Put it into a .j file, then View -- Options -- Jass Enchantments -- Add (under the Native Files category)

No, I don't mean "Jass Enhancements", JassCraft calls it "Enchantments" for some reason -.-
 
Level 20
Joined
Apr 22, 2007
Messages
1,960
I know that there are loads of other formulas, but I only pasted the important ones used in Warcraft III.

To add the handle vars script to JassCraft syntax, make a notepad file with the functions used in handle vars. Change the extension to .j, and place it in the jasscraft folder. Then open jasscraft and go to options, and check the handle vars .j file at the syntax checking tab.

I'm just returning the favor about rep :D. You rep me, I rep you.

EDIT: GAH poot, responded faster than me.
 
OOk, so, to start what is the file i must add to jasscraft ?? Which script is it ??. Do i have to add that script in the headers of my map too if i use the spell ?
My map already has a script in it's header ... can it have more than 1 ?

Also, my questions about polarbj:

What i mainly don't understand is the formula you guys use ...

Here's an explanation of polar projections. Lemme look up the polar projection function in JassCraft...
JASS:
function PolarProjectionBJ takes location source, real dist, real angle returns location 
    local real x = GetLocationX(source) + dist * Cos(angle * bj_DEGTORAD) 
    local real y = GetLocationY(source) + dist * Sin(angle * bj_DEGTORAD) 
    return Location(x, y) 
endfunction

and you have:
real x = x + Cos(angle)*length
real y = y + Sin(angle)*length

Where it should be:
real x = x + dist*Cos(angle*(3.14159/180.0))
real y = y + dist*Sin(angle*(3.14159/180.0))

So, to start, we don't know the "distance" value, the length value seems to be in the wrong place and the bj_degtorad just ran away ... This is my main first problem ... not understanding how you people use the formula.

The other question i have is about how warcraft uses it.

Now, the use of the sine and cosine functions in Warcraft III. Well, Warcraft III works sort of like a 3 dimensional graph... with the X, Y and Z axis. Let's just use the X and Y axis for now. Let's say you have a point on the map, (0,0). You want to 'project' that point towards a direction:
image

The image is pretty good, but how can we consider a 2 axis system in a formula, when warcraft has a 3 axis system ??
To make that work the Z value would have to be 0 ... but that value doesn't show up in polarprojectionBJ. Also the Z axis would have to be the something else besides the sin, cos and tan.

Please explain these 3 questions ... very messed up ? =S
 
Level 20
Joined
Apr 22, 2007
Messages
1,960
Okay here goes.

The file you add is a .j script of Handle Vars. Just paste the handle vars script into jasscraft and save it as a .j and put it in your jasscraft folder (then follow poot's directives). You don't have to add it twice in your map (that would make loads of syntax errors).

See, I used radians instead of degrees. Most Warcraft III functions work with radians. Like the CosBJ function takes a degree value, and here's what it does:
JASS:
function CosBJ takes real degrees returns real
    return Cos(degrees * bj_DEGTORAD)
endfunction
Which is stupid, since we could directly run the Cos function using radian angles. bj_DEGTORAD is simply 3.14159/180, and bj_RADTODEG is 180/3.14159. The PolarProjectionBJ function takes degree values, that's why they are using bj_DEGTORAD as a factor in the Cos and Sin functions.

Okay here you've got it wrong. Example: Let's say you have this equation:
x = 2 + 4 * 3
Based on the order of equations and stuff, the multiplication always goes before the addition, so it would be the same thing as:
x = 3 * 4 + 2
No matter how much you mess it up, if 3 and 4 are next to eachother, it will work.

The Z axis is changed using:
JASS:
native          SetUnitFlyHeight    takes unit whichUnit, real newHeight, real rate returns nothing
But before using that, if the unit is not a flying one, you have to do this:
JASS:
call UnitAddAbility(yourunit, 'Amrf')
call UnitRemoveAbility(yourunit, 'Amrf')

Warcraft III just follows the height of the location you moved the unit to, + the height of the unit.

Hope you understand... :/
 
mmmm, more two question ... first
The file you add is a .j script of Handle Vars. Just paste the handle vars script into jasscraft and save it as a .j and put it in your jasscraft folder (then follow poot's directives). You don't have to add it twice in your map (that would make loads of syntax errors).

I already know HOW to do it, i just don't know with WHICH script i have to use to do that ...

Also
and you have:
real x = x + Cos(angle)*length
real y = y + Sin(angle)*length

Where it should be:
real x = x + dist*Cos(angle*(3.14159/180.0))
real y = y + dist*Sin(angle*(3.14159/180.0))

well, you explacation about signals is not a new to me ... My problem is the values you have !!

like:
GetLocationX(source) = x
dist = ?
bj_DEGTORAD = 3.14159/180.0
angle = ?
cos = well if i don't kno1 value i can't know the other one

and you use a different method (i think):
GetLocationX(source) = x
length = what is this !?
angle = how do i know it !?
cos = blarg ..

About he Z axis, if you are in a 3d world, don't you also have to give a Z value to the polar projection ??? Imagine that i want to do a vertical ray, i have to do give it a Z value ...



Also, i have some question about one of my spells.

JASS:
function AnimalAura_Acts takes nothing returns nothing
    local unit Killer = GetKillingUnit()
    local unit dead = GetDyingUnit()
    local unit dum
    local integer AAchance
    if GetUnitAbilityLevel(GetKillingUnit(), 'B019' ) > 0 and GetRandomInt(1, 100) <= AAchance then
        set AAchance = 5
        set dum = CreateUnit(GetOwningPlayer(Killer), 'h01H', GetUnitX(dead), GetUnitY(dead), 0.00)
        call UnitAddAbility(dum, 'A04V')
        call SetUnitAbilityLevel(dum, 'A04V', 1)
        call IssuePointOrder(dum, "darkportal", GetUnitX(dead), GetUnitY(dead)) 
        call UnitApplyTimedLife(dum, 'BTLF', 3.00)
        set Killer = null
        set dum = null
        set dead = null
    endif
    if GetUnitAbilityLevel(GetKillingUnit(), 'B01A' )>0 and GetRandomInt(1, 100) <= AAchance then
        set AAchance = 10
        set dum = CreateUnit(GetOwningPlayer(Killer), 'h01H', GetUnitX(dead), GetUnitY(dead), 0.00)
        call UnitAddAbility(dum, 'A04V')
        call SetUnitAbilityLevel(dum, 'A04V', 2)
        call IssuePointOrder(dum, "darkportal", GetUnitX(dead), GetUnitY(dead)) 
        call UnitApplyTimedLife(dum, 'BTLF', 3.00)
        set Killer = null
        set dum = null
        set dead = null
    endif
    if GetUnitAbilityLevel(GetKillingUnit(), 'B01B' )>0 and GetRandomInt(1, 100) <= AAchance then
        set AAchance = 15
        set dum = CreateUnit(GetOwningPlayer(Killer), 'h01H', GetUnitX(dead), GetUnitY(dead), 0.00)
        call UnitAddAbility(dum, 'A04V')
        call SetUnitAbilityLevel(dum, 'A04V', 2)
        call IssuePointOrder(dum, "darkportal", GetUnitX(dead), GetUnitY(dead)) 
        call UnitApplyTimedLife(dum, 'BTLF', 3.00)
        set Killer = null
        set dum = null
        set dead = null
    endif
endfunction
//===========================================================================
function InitTrig_Animal_Aura takes nothing returns nothing
    local trigger AnimalAura = CreateTrigger(  )
    local integer index = 0
    loop
        exitwhen index == 16
        call TriggerRegisterPlayerUnitEvent(AnimalAura, Player(index), EVENT_PLAYER_UNIT_DEATH, null)
        set index = index +1
    endloop
    call TriggerAddAction( AnimalAura, function AnimalAura_Acts )
    set AnimalAura = null
endfunction

does this work ??? i mean, i really am confused with the AAchance local because of the chances ... shouldn't i set the variable before the If ???
 
Well somehow, i knew it didn't work... dam ... i knew it ....

About local triggers i don't understand why they are so bad !!!
You guys highly recommend them in your JASS tutorial !!!

Example:
JASS:
function Condition_Function takes nothing returns boolean  
    return GetTriggerPlayer() == Player(0) 
endfunction 
function InitTrig_JASSTrigger takes nothing returns nothing  
    local trigger myTrigger = CreateTrigger()  
    call TriggerRegisterPlayerEvent(myTrigger, Player(0), EVENT_PLAYER_END_CINEMATIC)  
    call TriggerAddCondition(myTrigger, Condition(function Condition_Function))  
    call TriggerAddAction(myTrigger, function MyFunction)  
    set myTrigger = null 
endfunction

Visit this link Beginning JJASS Tutorial Series

If local triggers are so bad, why don't you change the tutorial !!! It has 5 starts .... jesus, i start to think that tutorial is crap .... It is the second error ... (ya, lesson 4 is a mess....)
and so i have to put the AAchances before ... dam ... that will be bad for me ...=S

About JassCraft, it means that i have to add this file rit ???
 
Level 20
Joined
Apr 22, 2007
Messages
1,960
There's no use to make a local trigger, when you ALREADY have the global! The global won't get away. The only use for local triggers in this case would be 1 major trigger that would initialize all other triggers, like some sort of Map Init. But that could be sooooo messy.

Us guys? wyrmlord recommends it.

About JassCraft, yes that's it.
 
There's no use to make a local trigger, when you ALREADY have the global! The global won't get away. The only use for local triggers in this case would be 1 major trigger that would initialize all other triggers, like some sort of Map Init. But that could be sooooo messy.

Us guys? wyrmlord recommends it.

MMm well, then it probably means 2 things:
1 - Using global triggers is more efficient and fast than using local ones (rit ?)
2 - Wyrmlord is not as good Jasser as he seems to be ... or as he says he is ...
3 - lot's of tutorials need to be corrected here =S
 
Level 20
Joined
Apr 22, 2007
Messages
1,960
1. Actually I've heard that locals work faster than globals, but that's not the problem. The problem is that you're using up memory for nothing.
2. No, he's good.
3. Maybe, I haven't checked them.

Stick with the local triggers if you want to, but IMO it's better to keep the globals.
 
Well, i have two problems ....
I will now post the first one, and explain the second later.
the first problem i have is with your spell ....it simply doesn't work in my WE...
JassCraft says it is ok, but my WE doesn't run it.

Here is the error my WE points out:

Image1.jpg

So i don't get what is the dam problem .... I also placed this script at my map's header:
JASS:
// ===========================
function H2I takes handle h returns integer
    return h
    return 0
endfunction

// ===========================
function LocalVars takes nothing returns gamecache
    // Replace InitGameCache("jasslocalvars.w3v") with a global variable!!
    return InitGameCache("jasslocalvars.w3v")
endfunction

function SetHandleHandle takes handle subject, string name, handle value returns nothing
    if value==null then
        call FlushStoredInteger(LocalVars(),I2S(H2I(subject)),name)
    else
        call StoreInteger(LocalVars(), I2S(H2I(subject)), name, H2I(value))
    endif
endfunction

function SetHandleInt takes handle subject, string name, integer value returns nothing
    if value==0 then
        call FlushStoredInteger(LocalVars(),I2S(H2I(subject)),name)
    else
        call StoreInteger(LocalVars(), I2S(H2I(subject)), name, value)
    endif
endfunction

function SetHandleBoolean takes handle subject, string name, boolean value returns nothing
    if value==false then
        call FlushStoredBoolean(LocalVars(),I2S(H2I(subject)),name)
    else
        call StoreBoolean(LocalVars(), I2S(H2I(subject)), name, value)
    endif
endfunction

function SetHandleReal takes handle subject, string name, real value returns nothing
    if value==0 then
        call FlushStoredReal(LocalVars(), I2S(H2I(subject)), name)
    else
        call StoreReal(LocalVars(), I2S(H2I(subject)), name, value)
    endif
endfunction

function SetHandleString takes handle subject, string name, string value returns nothing
    if value==null then
        call FlushStoredString(LocalVars(), I2S(H2I(subject)), name)
    else
        call StoreString(LocalVars(), I2S(H2I(subject)), name, value)
    endif
endfunction

function GetHandleHandle takes handle subject, string name returns handle
    return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
    return null
endfunction
function GetHandleInt takes handle subject, string name returns integer
    return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
endfunction
function GetHandleBoolean takes handle subject, string name returns boolean
    return GetStoredBoolean(LocalVars(), I2S(H2I(subject)), name)
endfunction
function GetHandleReal takes handle subject, string name returns real
    return GetStoredReal(LocalVars(), I2S(H2I(subject)), name)
endfunction
function GetHandleString takes handle subject, string name returns string
    return GetStoredString(LocalVars(), I2S(H2I(subject)), name)
endfunction

function GetHandleUnit takes handle subject, string name returns unit
    return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
    return null
endfunction
function GetHandleTimer takes handle subject, string name returns timer
    return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
    return null
endfunction
function GetHandleTrigger takes handle subject, string name returns trigger
    return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
    return null
endfunction
function GetHandleEffect takes handle subject, string name returns effect
    return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
    return null
endfunction
function GetHandleGroup takes handle subject, string name returns group
    return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
    return null
endfunction
function GetHandleLightning takes handle subject, string name returns lightning
    return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
    return null
endfunction
function GetHandleWidget takes handle subject, string name returns widget
    return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
    return null
endfunction

function FlushHandleLocals takes handle subject returns nothing
    call FlushStoredMission(LocalVars(), I2S(H2I(subject)) )
endfunction

So, this is kn of bad ... this is my first issue, please help =S
 
Guys, is the spell Ok now ??

JASS:
function AnimalAura_Conds takes nothing returns boolean
    local integer AAchance 
    if GetUnitAbilityLevel(GetKillingUnit(), 'B019' )>0 then
        set AAchance = 5
    elseif GetUnitAbilityLevel(GetKillingUnit(), 'B01A' )>0 then
        set AAchance = 10
    elseif GetUnitAbilityLevel(GetKillingUnit(), 'B01B' )>0 then        
        set AAchance = 15
    endif
    return GetRandomInt(1, 100) <= AAchance 
endfunction
//===================================================================================
function AnimalAura_Acts takes nothing returns nothing
    local unit Killer = GetKillingUnit()
    local unit dead = GetDyingUnit()
    local unit dum
    if GetUnitAbilityLevel(GetKillingUnit(), 'B019' ) > 0 then
        set dum = CreateUnit(GetOwningPlayer(Killer), 'h01H', GetUnitX(dead), GetUnitY(dead), 0.00)
        call UnitAddAbility(dum, 'A04V')
        call SetUnitAbilityLevel(dum, 'A04V', 1)
        call IssuePointOrder(dum, "darkportal", GetUnitX(dead), GetUnitY(dead)) 
        call UnitApplyTimedLife(dum, 'BTLF', 3.00)
        set Killer = null
        set dum = null
        set dead = null
    endif
    if GetUnitAbilityLevel(GetKillingUnit(), 'B01A' )>0 then
        set dum = CreateUnit(GetOwningPlayer(Killer), 'h01H', GetUnitX(dead), GetUnitY(dead), 0.00)
        call UnitAddAbility(dum, 'A04V')
        call SetUnitAbilityLevel(dum, 'A04V', 2)
        call IssuePointOrder(dum, "darkportal", GetUnitX(dead), GetUnitY(dead)) 
        call UnitApplyTimedLife(dum, 'BTLF', 3.00)
        set Killer = null
        set dum = null
        set dead = null
    endif
    if GetUnitAbilityLevel(GetKillingUnit(), 'B01B' )>0 then
        set dum = CreateUnit(GetOwningPlayer(Killer), 'h01H', GetUnitX(dead), GetUnitY(dead), 0.00)
        call UnitAddAbility(dum, 'A04V')
        call SetUnitAbilityLevel(dum, 'A04V', 2)
        call IssuePointOrder(dum, "darkportal", GetUnitX(dead), GetUnitY(dead)) 
        call UnitApplyTimedLife(dum, 'BTLF', 3.00)
        set Killer = null
        set dum = null
        set dead = null
    endif
endfunction
//===========================================================================
function InitTrig_Animal_Aura takes nothing returns nothing
    local trigger AnimalAura = CreateTrigger(  )
    local integer index = 0
    loop
        exitwhen index == 16
        call TriggerRegisterPlayerUnitEvent(AnimalAura, Player(index), EVENT_PLAYER_UNIT_DEATH, null)
        set index = index +1
    endloop
    call TriggerAddCondition( AnimalAura, Condition( function AnimalAura_Conds ) )
    call TriggerAddAction( AnimalAura, function AnimalAura_Acts )
    set AnimalAura = null
endfunction
 
Level 20
Joined
Apr 22, 2007
Messages
1,960
Looks okay. Here's a bit of optimizn'

JASS:
function AnimalAura_Conds takes nothing returns boolean
    local integer AAchance=0
    local unit u=GetKillingUnit()
    if GetUnitAbilityLevel(u, 'B019' )>0 then
        set AAchance = 5
    elseif GetUnitAbilityLevel(u, 'B01A' )>0 then
        set AAchance = 10
    elseif GetUnitAbilityLevel(u, 'B01B' )>0 then
        set AAchance = 15
    endif
    set u=null
    return GetRandomInt(1, 100) <= AAchance
endfunction
//===================================================================================
function AnimalAura_Acts takes nothing returns nothing
    local unit Killer = GetKillingUnit()
    local unit dead = GetTriggerUnit()
    local unit dum
    if GetUnitAbilityLevel(Killer, 'B019' ) > 0 then
        set dum = CreateUnit(GetOwningPlayer(Killer), 'h01H', GetUnitX(dead), GetUnitY(dead), 0.00)
        call UnitAddAbility(dum, 'A04V')
        call SetUnitAbilityLevel(dum, 'A04V', 1)
        call IssuePointOrder(dum, "darkportal", GetUnitX(dead), GetUnitY(dead))
        call UnitApplyTimedLife(dum, 'BTLF', 3.00)
    endif
    if GetUnitAbilityLevel(Killer, 'B01A' )>0 then
        set dum = CreateUnit(GetOwningPlayer(Killer), 'h01H', GetUnitX(dead), GetUnitY(dead), 0.00)
        call UnitAddAbility(dum, 'A04V')
        call SetUnitAbilityLevel(dum, 'A04V', 2)
        call IssuePointOrder(dum, "darkportal", GetUnitX(dead), GetUnitY(dead))
        call UnitApplyTimedLife(dum, 'BTLF', 3.00)
    endif
    if GetUnitAbilityLevel(Killer, 'B01B' )>0 then
        set dum = CreateUnit(GetOwningPlayer(Killer), 'h01H', GetUnitX(dead), GetUnitY(dead), 0.00)
        call UnitAddAbility(dum, 'A04V')
        call SetUnitAbilityLevel(dum, 'A04V', 2)
        call IssuePointOrder(dum, "darkportal", GetUnitX(dead), GetUnitY(dead))
        call UnitApplyTimedLife(dum, 'BTLF', 3.00)
    endif
    set Killer = null
    set dum = null
    set dead = null
endfunction
//===========================================================================
function InitTrig_Animal_Aura takes nothing returns nothing
    local integer index = 0
    set gg_trg_Animal_Aura = CreateTrigger()
    loop
        exitwhen index == 16
        call TriggerRegisterPlayerUnitEvent(gg_trg_Animal_Aura, Player(index), EVENT_PLAYER_UNIT_DEATH, null)
        set index = index +1
    endloop
    call TriggerAddCondition( gg_trg_Animal_Aura, Condition( function AnimalAura_Conds ) )
    call TriggerAddAction( gg_trg_Animal_Aura, function AnimalAura_Acts )
endfunction

Please... stop using local triggers.
 
This particular spell is an Aura with 3 buffs for each level.
Every time a unit dies, if the killer has the buff, a dummy unit will be created and a spell will be cast.
As i said there are 3 different buffs for each level. I will try to make 1 buff with 3 levels (perhaps it is more efficient) but i don't know yet.

EDIT: After evaluating my spell i concluded that there is no need for me to replace the 3 different auras by 1 aura with 3 levels. The script wouldn't change in a significant way.
 
Ok, guys, i have another problem with one of my spells.
When evaluating my map i can easily find GUI spells that do give a lot of trouble... they leak a lot and stuff like that ...
But now that i know JASS i can change that! (or i am trying too). I am an expert at making any kind of GUI auras, problem is that they leak and sometimes they are not MUI .... Now because my map is for multiplayer i need them to be MUI ...

Anyway, here is an aura which i called IcyAura.

It was one of my first aura spells, so i made 1 trigger for each level:
  • Icy Aura Lv1
    • Events
      • Time - Every 2.00 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in (Random 1 units from (Units in (Playable map area) matching (((Matching unit) has buff Icy Aura (Lv1)) Equal to True))) and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • 10 Greater than or equal to (Random integer number between 1 and 100)
            • Then - Actions
              • Unit - Create 1 Frsot Trap for Player 1 (Red) at (Position of (Picked unit)) facing Default building facing degrees
              • Unit - Add a 3.00 second Generic expiration timer to (Last created unit)
              • Unit - Create 1 Icy Aura for Player 1 (Red) at (Position of (Picked unit)) facing Default building facing degrees
              • Unit - Add Icy Aura (Dummy Spell Lv1) to (Last created unit)
              • Unit - Order (Last created unit) to Human Mountain King - Storm Bolt (Picked unit)
              • Unit - Add a 3.00 second Generic expiration timer to (Last created unit)
            • Else - Actions
              • Do nothing
This is for level 1 ... I have 2 other triggers for level 2 and 3, but i will not post them now.

Here is the same trigger in converted JASS:
JASS:
function Trig_Icy_Aura_Lv1_Func001001002002 takes nothing returns boolean
    return ( UnitHasBuffBJ(GetFilterUnit(), 'B01G') == true )
endfunction

function Trig_Icy_Aura_Lv1_Func001Func001C takes nothing returns boolean
    if ( not ( 10 >= GetRandomInt(1, 100) ) ) then
        return false
    endif
    return true
endfunction

function Trig_Icy_Aura_Lv1_Func001A takes nothing returns nothing
    if ( Trig_Icy_Aura_Lv1_Func001Func001C() ) then
        call CreateNUnitsAtLoc( 1, 'h01N', Player(0), GetUnitLoc(GetEnumUnit()), bj_UNIT_FACING )
        call UnitApplyTimedLifeBJ( 3.00, 'BTLF', GetLastCreatedUnit() )
        call CreateNUnitsAtLoc( 1, 'h01M', Player(0), GetUnitLoc(GetEnumUnit()), bj_UNIT_FACING )
        call UnitAddAbilityBJ( 'A02K', GetLastCreatedUnit() )
        call IssueTargetOrderBJ( GetLastCreatedUnit(), "thunderbolt", GetEnumUnit() )
        call UnitApplyTimedLifeBJ( 3.00, 'BTLF', GetLastCreatedUnit() )
    else
        call DoNothing(  )
    endif
endfunction

function Trig_Icy_Aura_Lv1_Actions takes nothing returns nothing
    call ForGroupBJ( GetRandomSubGroup(1, GetUnitsInRectMatching(GetPlayableMapRect(), Condition(function Trig_Icy_Aura_Lv1_Func001001002002))), function Trig_Icy_Aura_Lv1_Func001A )
endfunction

//===========================================================================
function InitTrig_Icy_Aura_Lv1 takes nothing returns nothing
    set gg_trg_Icy_Aura_Lv1 = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_Icy_Aura_Lv1, 2 )
    call TriggerAddAction( gg_trg_Icy_Aura_Lv1, function Trig_Icy_Aura_Lv1_Actions )
endfunction

Well, pretty messed up ...

And now here is my JASS trigger i tried to create for ALL 3 levels:
JASS:
function IcyAura_Conds takes nothing returns boolean
    local integer ICchance
    local integer lv = GetUnitAbilityLevel(GetFilterUnit(), 'B01G') > 0
    if lv == 1 then
        set ICchance = 5
    elseif lv == 2 then
        set ICchance = 10
    elseif lv == 3 then 
        set ICchance = 15
    endif
    return lv > 0 and GetRandomInt(1, 100) <= ICchance 
endfunction
//==========================================================================
function IcyAura_Acts takes nothing returns nothing
    local effect e
    local unit en
    local unit dum 
    local integer lvl = GetUnitAbilityLevel(GetFilterUnit(), 'B01G') > 0
    call ForGroupBJ( GetRandomSubGroup(1, GetUnitsInRectAll(GetPlayableMapRect(),null )))
    if lvl == 1 then 
        set en = GetEnumUnit()
        call AddSpecialEffect("Doodads\\Cinematic\\FrostTrapUp\\FrostTrapUp.mdl", GetUnitX(en), GetUnitY(en))
        set dum = CreateUnit(Player(0), 'h01H', GetUnitX(en), GetUnitY(en), 0)
        call UnitApplyTimedLife(dum, 'BTLF', 2.00)
        call UnitAddAbility(dum, 'A02K')
        call SetUnitAbilityLevel(dum, 'A02K', 1) 
        call IssueTargetOrder(dum, "thunderbolt", en)
        call TriggerSleepAction(3.0)
        call DestroyEffect(e)
    elseif lvl == 2 then
        set en = GetEnumUnit()
        call AddSpecialEffect("Doodads\\Cinematic\\FrostTrapUp\\FrostTrapUp.mdl", GetUnitX(en), GetUnitY(en))
        set dum = CreateUnit(Player(0), 'h01H', GetUnitX(en), GetUnitY(en), 0)
        call UnitApplyTimedLife(dum, 'BTLF', 2.00)
        call UnitAddAbility(dum, 'A02K')
        call SetUnitAbilityLevel(dum, 'A02K', 2) 
        call IssueTargetOrder(dum, "thunderbolt", en)
        call TriggerSleepAction(3.0)
        call DestroyEffect(e)
    elseif lvl == 3 then
        set en = GetEnumUnit()
        call AddSpecialEffect("Doodads\\Cinematic\\FrostTrapUp\\FrostTrapUp.mdl", GetUnitX(en), GetUnitY(en))
        set dum = CreateUnit(Player(0), 'h01H', GetUnitX(en), GetUnitY(en), 0)
        call UnitApplyTimedLife(dum, 'BTLF', 2.00)
        call UnitAddAbility(dum, 'A02K')
        call SetUnitAbilityLevel(dum, 'A02K', 3) 
        call IssueTargetOrder(dum, "thunderbolt", en)
        call TriggerSleepAction(3.0)
        call DestroyEffect(e)
    endif
    set e = null
    set en = null
    set dum = null   
endfunction
//===========================================================================
function InitTrig_Icy_Aura takes nothing returns nothing
    local trigger IcyAura = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( IcyAura, 2 )
    call TriggerAddCondition(IcyAura, Condition(function IcyAura_Conds))
    call TriggerAddAction( IcyAura, function IcyAura_Acts )
    set IcyAura = null
endfunction

However i do have some problems with the "pick all unit is map that have the buff" part and because of that i need your help ...
can you guys help me improve this script please ?
 
Blarg ... i tried to do that function thing i it didn't work ... i definitly need one more tip on how to fix this dam spell .. please i will soon post here what i did.

Done, this is the best i could do to fix the problem, however i still get errors and it still doesn't work properly ... Any more suggestions ???

JASS:
function IcyAura_Conds takes nothing returns boolean
    local integer ICchance
    local integer lv = GetUnitAbilityLevel(GetFilterUnit(), 'B01G') > 0
    if lv == 1 then
        set ICchance = 5
    elseif lv == 2 then
        set ICchance = 10
    elseif lv == 3 then 
        set ICchance = 15
    endif
    return lv > 0 and GetRandomInt(1, 100) <= ICchance 
endfunction
//==========================================================================
function Icy_Aura_GroupCall takes nothing returns nothing
    call ForGroupBJ( GetRandomSubGroup(1, GetUnitsInRectMatching(GetPlayableMapRect())), Condition(function IcyAura_Conds), function IcyAura_Acts )
endfunction
//==========================================================================
function IcyAura_Acts takes nothing returns nothing
    local effect e
    local unit en
    local unit dum 
    local integer lvl = GetUnitAbilityLevel(GetFilterUnit(), 'B01G') > 0
    if lvl == 1 then 
        set en = GetEnumUnit()
        call AddSpecialEffect("Doodads\\Cinematic\\FrostTrapUp\\FrostTrapUp.mdl", GetUnitX(en), GetUnitY(en))
        set dum = CreateUnit(Player(0), 'h01H', GetUnitX(en), GetUnitY(en), 0)
        call UnitApplyTimedLife(dum, 'BTLF', 2.00)
        call UnitAddAbility(dum, 'A02K')
        call SetUnitAbilityLevel(dum, 'A02K', 1) 
        call IssueTargetOrder(dum, "thunderbolt", en)
        call TriggerSleepAction(3.0)
        call DestroyEffect(e)
    elseif lvl == 2 then
        set en = GetEnumUnit()
        call AddSpecialEffect("Doodads\\Cinematic\\FrostTrapUp\\FrostTrapUp.mdl", GetUnitX(en), GetUnitY(en))
        set dum = CreateUnit(Player(0), 'h01H', GetUnitX(en), GetUnitY(en), 0)
        call UnitApplyTimedLife(dum, 'BTLF', 2.00)
        call UnitAddAbility(dum, 'A02K')
        call SetUnitAbilityLevel(dum, 'A02K', 2) 
        call IssueTargetOrder(dum, "thunderbolt", en)
        call TriggerSleepAction(3.0)
        call DestroyEffect(e)
    elseif lvl == 3 then
        set en = GetEnumUnit()
        call AddSpecialEffect("Doodads\\Cinematic\\FrostTrapUp\\FrostTrapUp.mdl", GetUnitX(en), GetUnitY(en))
        set dum = CreateUnit(Player(0), 'h01H', GetUnitX(en), GetUnitY(en), 0)
        call UnitApplyTimedLife(dum, 'BTLF', 2.00)
        call UnitAddAbility(dum, 'A02K')
        call SetUnitAbilityLevel(dum, 'A02K', 3) 
        call IssueTargetOrder(dum, "thunderbolt", en)
        call TriggerSleepAction(3.0)
        call DestroyEffect(e)
    endif
    set e = null
    set en = null
    set dum = null   
endfunction
//===========================================================================
function InitTrig_Icy_Aura takes nothing returns nothing
    local trigger IcyAura = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( IcyAura, 2 )
    call TriggerAddCondition(IcyAura, Condition(function IcyAura_Conds))
    call TriggerAddAction( IcyAura, function Icy_Aura_GroupCall )
    set IcyAura = null
endfunction
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
There are still flaws, I just made it work;

JASS:
function IcyAura_Conds takes nothing returns boolean
    local integer ICchance
    local integer lv = GetUnitAbilityLevel(GetFilterUnit(), 'B01G')
    if lv == 1 then
        set ICchance = 5
    elseif lv == 2 then
        set ICchance = 10
    elseif lv == 3 then 
        set ICchance = 15
    endif
    return lv > 0 and GetRandomInt(1, 100) <= ICchance 
endfunction
//==========================================================================
function IcyAura_Acts takes nothing returns nothing
    local effect e
    local unit en
    local unit dum 
    local integer lvl = GetUnitAbilityLevel(GetFilterUnit(), 'B01G')
    if lvl == 1 then 
        set en = GetEnumUnit()
        call AddSpecialEffect("Doodads\\Cinematic\\FrostTrapUp\\FrostTrapUp.mdl", GetUnitX(en), GetUnitY(en))
        set dum = CreateUnit(Player(0), 'h01H', GetUnitX(en), GetUnitY(en), 0)
        call UnitApplyTimedLife(dum, 'BTLF', 2.00)
        call UnitAddAbility(dum, 'A02K')
        call SetUnitAbilityLevel(dum, 'A02K', 1) 
        call IssueTargetOrder(dum, "thunderbolt", en)
        call TriggerSleepAction(3.0)
        call DestroyEffect(e)
    elseif lvl == 2 then
        set en = GetEnumUnit()
        call AddSpecialEffect("Doodads\\Cinematic\\FrostTrapUp\\FrostTrapUp.mdl", GetUnitX(en), GetUnitY(en))
        set dum = CreateUnit(Player(0), 'h01H', GetUnitX(en), GetUnitY(en), 0)
        call UnitApplyTimedLife(dum, 'BTLF', 2.00)
        call UnitAddAbility(dum, 'A02K')
        call SetUnitAbilityLevel(dum, 'A02K', 2) 
        call IssueTargetOrder(dum, "thunderbolt", en)
        call TriggerSleepAction(3.0)
        call DestroyEffect(e)
    elseif lvl == 3 then
        set en = GetEnumUnit()
        call AddSpecialEffect("Doodads\\Cinematic\\FrostTrapUp\\FrostTrapUp.mdl", GetUnitX(en), GetUnitY(en))
        set dum = CreateUnit(Player(0), 'h01H', GetUnitX(en), GetUnitY(en), 0)
        call UnitApplyTimedLife(dum, 'BTLF', 2.00)
        call UnitAddAbility(dum, 'A02K')
        call SetUnitAbilityLevel(dum, 'A02K', 3) 
        call IssueTargetOrder(dum, "thunderbolt", en)
        call TriggerSleepAction(3.0)
        call DestroyEffect(e)
    endif
    set e = null
    set en = null
    set dum = null   
endfunction
//==========================================================================
function Icy_Aura_GroupCall takes nothing returns nothing
    call ForGroup( GetRandomSubGroup(1, GetUnitsInRectMatching(GetPlayableMapRect(), Condition(function IcyAura_Conds))), function IcyAura_Acts )
endfunction
//===========================================================================
function InitTrig_Icy_Aura takes nothing returns nothing
    local trigger IcyAura = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( IcyAura, 2 )
    call TriggerAddCondition(IcyAura, Condition(function IcyAura_Conds))
    call TriggerAddAction( IcyAura, function Icy_Aura_GroupCall )
    set IcyAura = null
endfunction
 
mmm thx by the help. But i still have 1 error.

JASS:
function IcyAura_Conds takes nothing returns boolean
    local integer ICchance
    local integer lv = GetUnitAbilityLevel(GetFilterUnit(), 'B01G')
    if lv == 1 then
        set ICchance = 5
    elseif lv == 2 then
        set ICchance = 10
    elseif lv == 3 then 
        set ICchance = 15
    endif
    return lv > 0 and GetRandomInt(1, 100) <= ICchance 
endfunction
//==========================================================================
function Icy_Aura_GroupCall takes nothing returns nothing
    call ForGroup( GetRandomSubGroup(1, GetUnitsInRectMatching(GetPlayableMapRect(), Condition(function IcyAura_Conds))), function IcyAura_Acts )
endfunction
//==========================================================================
function IcyAura_Acts takes nothing returns nothing
    local effect e
    local unit en
    local unit dum 
    local integer lvl = GetUnitAbilityLevel(GetFilterUnit(), 'B01G')
    if lvl == 1 then 
        set en = GetEnumUnit()
        call AddSpecialEffect("Doodads\\Cinematic\\FrostTrapUp\\FrostTrapUp.mdl", GetUnitX(en), GetUnitY(en))
        set dum = CreateUnit(Player(0), 'h01H', GetUnitX(en), GetUnitY(en), 0)
        call UnitApplyTimedLife(dum, 'BTLF', 2.00)
        call UnitAddAbility(dum, 'A02K')
        call SetUnitAbilityLevel(dum, 'A02K', 1) 
        call IssueTargetOrder(dum, "thunderbolt", en)
        call TriggerSleepAction(3.0)
        call DestroyEffect(e)
    elseif lvl == 2 then
        set en = GetEnumUnit()
        call AddSpecialEffect("Doodads\\Cinematic\\FrostTrapUp\\FrostTrapUp.mdl", GetUnitX(en), GetUnitY(en))
        set dum = CreateUnit(Player(0), 'h01H', GetUnitX(en), GetUnitY(en), 0)
        call UnitApplyTimedLife(dum, 'BTLF', 2.00)
        call UnitAddAbility(dum, 'A02K')
        call SetUnitAbilityLevel(dum, 'A02K', 2) 
        call IssueTargetOrder(dum, "thunderbolt", en)
        call TriggerSleepAction(3.0)
        call DestroyEffect(e)
    elseif lvl == 3 then
        set en = GetEnumUnit()
        call AddSpecialEffect("Doodads\\Cinematic\\FrostTrapUp\\FrostTrapUp.mdl", GetUnitX(en), GetUnitY(en))
        set dum = CreateUnit(Player(0), 'h01H', GetUnitX(en), GetUnitY(en), 0)
        call UnitApplyTimedLife(dum, 'BTLF', 2.00)
        call UnitAddAbility(dum, 'A02K')
        call SetUnitAbilityLevel(dum, 'A02K', 3) 
        call IssueTargetOrder(dum, "thunderbolt", en)
        call TriggerSleepAction(3.0)
        call DestroyEffect(e)
    endif
    set e = null
    set en = null
    set dum = null   
endfunction
//===========================================================================
function InitTrig_Icy_Aura takes nothing returns nothing
    local trigger IcyAura = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( IcyAura, 2 )
    call TriggerAddCondition(IcyAura, Condition(function IcyAura_Conds))
    call TriggerAddAction( IcyAura, function Icy_Aura_GroupCall )
    set IcyAura = null
endfunction

In
JASS:
function Icy_Aura_GroupCall takes nothing returns nothing
    call ForGroup( GetRandomSubGroup(1, GetUnitsInRectMatching(GetPlayableMapRect(), Condition(function IcyAura_Conds))), function IcyAura_Acts )
endfunction
It says i have an undefined function ... what is that supposed to mean !?
 
arrghhh now i understand what i did wrong !!! i can't believe i did such a basic error lol ... thx for help =) Maybe soon i will post some really complicated spells, that i need to make MUI.

EDIT it seems that the aura doesn't work at all now ... i will have a better look on that soon.

EDIT EDIT: The aura doesn't work now (again lol) ... It seems that the computer doesn't know who has the buff ... How do i change that ??? use booleans instead of intergers ?? i may post a solution soon for you to evaluate. plz.
 
Last edited:
Status
Not open for further replies.
Top