• 🏆 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] Is this MUI & Leakless?

Status
Not open for further replies.
Level 6
Joined
Aug 1, 2009
Messages
159
JASS:
function Trig_Fire_Nova_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000'
endfunction

function Trig_Fire_Nova_Actions takes nothing returns nothing
    local unit Caster = GetTriggerUnit()
    local unit DummyUnit
    local location CasterLoc = GetUnitLoc(Caster)
    set bj_forLoopAIndex = 1
    set bj_forLoopAIndexEnd = 8
    loop
        exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
        set DummyUnit = CreateUnitAtLoc( GetOwningPlayer(Caster), 'h000' ,CasterLoc, 270.00 )
        call UnitAddAbilityBJ( 'A001', DummyUnit )
        call UnitApplyTimedLifeBJ( 1.00, 'BTLF', DummyUnit )
        set udg_PolarPoint = PolarProjectionBJ(CasterLoc, 200.00, ( 45.00 * I2R(GetForLoopIndexA()) ))
        call IssuePointOrderLocBJ( DummyUnit, "breathoffire", udg_PolarPoint )
        call RemoveLocation(udg_PolarPoint)
        set bj_forLoopAIndex = bj_forLoopAIndex + 1
    endloop
    call RemoveLocation(CasterLoc)
    set Caster = null
    set DummyUnit = null
endfunction

//===========================================================================
function InitTrig_Fire_Nova takes nothing returns nothing
    set gg_trg_Fire_Nova = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Fire_Nova, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Fire_Nova, Condition( function Trig_Fire_Nova_Conditions ) )
    call TriggerAddAction( gg_trg_Fire_Nova, function Trig_Fire_Nova_Actions )
endfunction

It works in game though, if you know how to set the PolarPoint variable to a local variable please tell me how.

JASS:
set udg_PolarPoint = PolarProjectionBJ(CasterLoc, 200.00, ( 45.00 * I2R(GetForLoopIndexA()) ))
 
Level 31
Joined
May 3, 2008
Messages
3,155
-use get unit x/y of the caster
-remove the bj
-use local integer

i don't have WE with me now.. but it was more like this

local real x = GetUnitX(caster)
local real y = GetUnitY(caster)
local integer int=1

exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd

replace this with

exitwhen int>8

call UnitAddAbilityBJ( 'A001', DummyUnit )

change it to

call UnitAddAbility( DummyUnit, 'A001' )

don't use location, use x/y coordinate as it was much faster.

It works in game though, if you know how to set the PolarPoint variable to a local variable please tell me how.

just make a local variable with the name Point, but leave the value blank. still, it would be better to use coordinate.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
I swear I saw a spell like this IDENTICAL to yours earlier today, only by a different name. And I fixed that guy's version, too.

EDIT: http://www.hiveworkshop.com/forums/triggers-scripts-269/check-one-d-167619/ That WAS you. What the heck, why did you post the same ugly trigger yet again instead of use the one I gave you?

JASS:
function Trig_Fire_Nova_Actions takes player p,unit u,unit d returns nothing
    local integer i = 1
    local real x = GetUnitX(u)
    local real y = GetUnitY(u)
    loop
        set d = CreateUnit(p,'h000',x,y,270.)
        call UnitAddAbility(d,'A001')
        call UnitApplyTimedLife(d,'BTLF',1.)
        call IssuePointOrder(d,"breathoffire",x+200.*Cos(i*0.7854),y+200.*Sin(i*0.7854))
        exitwhen i == 8
        set i = i + 1
    endloop
endfunction
 
function Trig_Fire_Nova_Conditions takes nothing returns boolean
    if GetSpellAbilityId() == 'A000' then
        call Trig_Fire_Nova_Actions(GetTriggerPlayer(),GetTriggerUnit(),null)
    endif
    return false
endfunction
 
//===========================================================================
function InitTrig_Fire_Nova takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( t, Condition( function Trig_Fire_Nova_Conditions ) )
endfunction
 
Level 6
Joined
Aug 1, 2009
Messages
159
@Bribe
I don't understand yours Bribe, I used yours but can you explain me how they work.
Edit : I do understand some, since I used it, but how can you get the
JASS:
x+200.*Cos(i*0.7854),y+200.*Sin(i*0.7854))
part?


Septimus I tried using yours, my problem is on the exitwhen int>8 when I edit it, it doesnt go around the caster, it just focuses on one point. and its left. And show me how to use those X, Y.
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
@Bribe
I don't understand yours Bribe, I used yours but can you explain me how they work.
Edit : I do understand some, since I used it, but how can you get the
JASS:
x+200.*Cos(i*0.7854),y+200.*Sin(i*0.7854))
part?


Septimus I tried using yours, my problem is on the exitwhen int>8 when I edit it, it doesnt go around the caster, it just focuses on one point. and its left. And show me how to use those X, Y.

The Sin and Cos-functions are used with radians.
So if you want to get the radians of an angle, you need to multiply it with pi/180 (pi/180 = 0.01745329).

Since your function uses the angles 360/i (where 0 < i < 9), you can multiply the pi/180 with 360/8 (because i can maximally be 8).
Then you get 0.7854.

The i * 0.7854 is because i is still a variable and is looped from 1 to 8, so the angle (in radians) has to change from 1 * 0.7854 (45º) to 8 * 0.7854 (360º).

I know I suck at explaining stuff, but this really is how it works xD


Usage of X and Y:

X and Y are coördinates.
You can calculate the coörds like this:

JASS:
X = GetUnitX(unit) + distance * Cos(Angle * 0.017453292)
Y = GetUnitY(unit) + distance * Sin(Angle * 0.017453292)
(Angle is in degrees)

So if you want to move a unit with an offset of 100 to an Angle degrees, then you need to get the current X of the unit and add '100 + Cos(Angle * 0.017453292)' to it (if you know some trigonometry, it's very basic).
You need to multiply the angle with 0.017453292 because we need to convert the angle from degrees to radians.
The Y is calculated the same, but then with the Sine.

This is usually always the same, though Bribe did make it more efficient in his trigger because only 8 preset angles are used.
 
Level 6
Joined
Aug 1, 2009
Messages
159
Thank you, about the loop part

JASS:
local integer i = 8
loop
exitwhen i>8
set i = i + i

im having problems with that part, the spells only shoots on one point, not in all directions when I edit that BJs to that.
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
Thank you, about the loop part

JASS:
local integer i = 8
loop
exitwhen i>8
set i = i + i

im having problems with that part, the spells only shoots on one point, not in all directions when I edit that BJs to that.
That's because you start the loop at 8 and end it when it's bigger than 8.

So the loop only accesses the value 8 or 9 (depending on whether the actions are before or after your 'set i = i+1').
If you set all actions inside the loop behind the i=i+1, then i will only be 9, otherwise it will only be 8.

use "local integer i = 0", set all actions you want to loop behind 'set i = i+1' and it should work.
 
Level 6
Joined
Aug 1, 2009
Messages
159
Still same results, can you show me in a JASS code? Im using Integer A and B shall I change it.

Anyways, tell me if I'm wrong.
JASS:
local integer i = 0
loop
    set i = i + 1
    //actions go here... :D
    exitwhen i>8

OR..................

JASS:
local integer i = 0
loop
    //actions go here... :D
    set i = i + 1
    exitwhen i>8

Here's my original version:

JASS:
    local integer i = 0
    local integer ii = 0
    loop
         set i = i + 1
         //actions
         loop
              set ii = ii + 1
              //actions
              exitwhen ii>12
         exitwhen i>8

Is this correct?
 
Level 6
Joined
Aug 1, 2009
Messages
159
They go around now, but only 1 circle. It should get 3 or 4 circles. but I only get 1 circle

This is what I got: (I posted the whole code of the loop to show you) and I also Included the part with the BJs

JASS:
    local integer i = 0
    local integer ii = 0
    // ----
    set DummyUnit = CreateUnitAtLoc(GetOwningPlayer(Caster),'h000',TargetLoc0,270.)
    call UnitApplyTimedLife(DummyUnit,'BTLF',3.)
    loop
        exitwhen i==3
        set i = i + 1
        set Nova_Formula = (Nova_Formula + (Nova_AoE / 2.))
        loop
            exitwhen ii==12
            set ii = ii+1
            set TargetLoc1 = PolarProjectionBJ(TargetLoc0,Nova_Formula,(30.*I2R(ii)))
            call DestroyEffect (AddSpecialEffectLoc("Abilities\\Spells\\Other\\FrostBolt\\FrostBoltMissile.mdl",TargetLoc1))
            call RemoveLocation(TargetLoc1)
            // ----------------------------------------------------
        endloop
    endloop

BJ PART......

JASS:
set bj_forLoopAIndex = 1
    set bj_forLoopAIndexEnd = 3
    loop
        exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
        set Nova_Formula = (Nova_Formula + (Nova_AoE / 2.))
        set bj_forLoopBIndex = 1
        set bj_forLoopBIndexEnd = 12
        loop
            exitwhen bj_forLoopBIndex > bj_forLoopBIndexEnd
            set TargetLoc1 = PolarProjectionBJ(TargetLoc0,Nova_Formula,(30.*I2R(GetForLoopIndexB())))
            call DestroyEffect (AddSpecialEffectLoc("Abilities\\Spells\\Other\\FrostBolt\\FrostBoltMissile.mdl",TargetLoc1))
            call RemoveLocation(TargetLoc1)
            // ----------------------------------------------------
            set bj_forLoopBIndex = bj_forLoopBIndex + 1
        endloop
        set bj_forLoopAIndex = bj_forLoopAIndex + 1
    endloop
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
Ayeee, that looks pretty bad actually.
It's like I said: use coördinates instead of locations.
The function "PolarProjectionBJ" is awful, try not to use it ^^

If you can show me the full code (with the integer variables, not the A/B's) so I know what 'TargetLoc0' is supposed to be, then I can help you.

It's probably going to look a bit like this:
JASS:
function SpecialEffects takes nothing returns nothing
    local integer i = 0
    local integer ii = 0
    local real x = GetLocationX(TargetLoc0)
    local real y = GetLocationY(TargetLoc0)
    local real X
    local real Y
    local unit Dummy = CreateUnit(GetOwningPlayer(Caster), 'h000', x, y, 270.)
    
    call UnitApplyTimedLife(Dummy, 'BTLF', 3.)
    loop
        exitwhen i==3
        set i = i+1
        set Nova_Formula = (Nova_Formula + (Nova_AoE / 2.))
        
        loop
            exitwhen ii==12
            set ii=ii+1
            set X = x + Nova_Formula * Cos(30.*I2R(ii)*0.017453292)
            set Y = y + Nova_Formula * Sin(30.*I2R(ii)*0.017453292)
            call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Other\\FrostBolt\\FrostBoltMissile.mdl", X, Y))
        endloop
    endloop
    
    set Dummy = null
endfunction

I know it looks huge, but in your function there are a lot of uncalled variables, that's mainly the thing that makes my function look bigger.
As you can see, I've used coörds instead of the location.

Now my primary concern is that I can only see a small part of your trigger.
I don't know where the Nova_Formula, Caster, TargetLoc, Nova_AoE and other variables come from...
 
Level 6
Joined
Aug 1, 2009
Messages
159
I know its bad, sorry...

JASS:
function Trig_Blizzaga_Start_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000'
endfunction

function Trig_Blizzaga_Start_Func008002003 takes nothing returns boolean
    local unit Caster = GetTriggerUnit()
    return ( IsUnitAliveBJ(Caster) == true )
endfunction

function Trig_Blizzaga_Start_Func013A takes nothing returns nothing
    local unit Caster = GetTriggerUnit()
    local real Nova_Damage = 300.
    call UnitDamageTargetBJ(Caster, GetEnumUnit(), Nova_Damage, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_COLD )
endfunction

function Trig_Blizzaga_Start_Actions takes nothing returns nothing
    local unit Caster = GetTriggerUnit()
    local unit Target = GetSpellTargetUnit()
    local unit DummyUnit
    local location TargetLoc0 = GetUnitLoc(Target)
    local location TargetLoc1
    // ---------------------------------------------------
    local real Nova_AoE = 400.
    local real Nova_Formula = 0.
    local integer i = 0
    local integer ii = 0
    local group Nova_Group
    set Nova_Group = GetUnitsInRangeOfLocMatching(Nova_AoE,TargetLoc0,Condition(function Trig_Blizzaga_Start_Func008002003))
    // ----
    set DummyUnit = CreateUnitAtLoc(GetOwningPlayer(Caster),'h000',TargetLoc0,270.)
    call UnitApplyTimedLife(DummyUnit,'BTLF',3.)
    loop
        exitwhen i==3
        set i = i + 1
        set Nova_Formula = (Nova_Formula + (Nova_AoE / 2.))
        loop
            exitwhen ii==12
            set ii = ii+1
            set TargetLoc1 = PolarProjectionBJ(TargetLoc0,Nova_Formula,(30.*I2R(ii)))
            call DestroyEffect (AddSpecialEffectLoc("Abilities\\Spells\\Other\\FrostBolt\\FrostBoltMissile.mdl",TargetLoc1))
            call RemoveLocation(TargetLoc1)
            // ----------------------------------------------------
        endloop
    endloop
    call ForGroupBJ(Nova_Group, function Trig_Blizzaga_Start_Func013A )
    call RemoveLocation(TargetLoc0)
    call DestroyGroup(Nova_Group)
endfunction

//===========================================================================
function InitTrig_Blizzaga_Start takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( t, Condition( function Trig_Blizzaga_Start_Conditions ) )
    call TriggerAddAction( t, function Trig_Blizzaga_Start_Actions )
endfunction

But why it doesn't work if I dont use X n Y coordinates?
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
Oww, converted GUI always hurts my eyes...

And I didn't say that loc don't work, locs just suck.
Try to use as few BJ's as possible (functions that call other functions).

I've done some quick fixes, but I cannot assure you that this works, nor is the most effecient method.
It's still better than you version though.


JASS:
//Condition
function Trig_Blizzaga_Start_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000'
endfunction

//Check whether the caster is alive
function Trig_Blizzaga_Start_CheckCaster takes nothing returns boolean
    local unit Caster = GetTriggerUnit()
    if GetUnitState(Caster, UNIT_STATE_LIFE) > 0 then
        return true
    endif
    return false
    set Caster = null
endfunction

//Deal damage
function Trig_Blizzaga_Start_Damage takes nothing returns nothing
    local unit Caster = GetTriggerUnit()
    local real Nova_Damage = 300.
    call UnitDamageTarget(Caster, GetEnumUnit(), Nova_Damage, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_COLD, WEAPON_TYPE_WHOKNOWS)
    set Caster = null
endfunction

//Main code
function Trig_Blizzaga_Start_Actions takes nothing returns nothing   
    local unit Caster = GetTriggerUnit()
    local unit Target = GetSpellTargetUnit()    
    local integer i = 0
    local integer ii = 0
    local real NovaAoE = 400.
    local real NovaFormula = 0.
    local real x = GetUnitX(Target)
    local real y = GetUnitY(Target)
    local real X
    local real Y
    local unit Dummy = CreateUnit(GetOwningPlayer(Caster), 'h000', x, y, 270.)
    local group NovaGroup = CreateGroup()
    
    call GroupEnumUnitsInRange(NovaGroup, x, y, NovaAoE, Condition(function Trig_Blizzaga_Start_CheckCaster))
    call UnitApplyTimedLife(Dummy, 'BTLF', 3.)

    loop
        exitwhen i==3
        set i = i+1
        set NovaFormula = (NovaFormula + (NovaAoE / 2.))
        
        loop
            exitwhen ii==12
            set ii=ii+1
            set X = x + NovaFormula * Cos(30.*I2R(ii)*0.017453292)
            set Y = y + NovaFormula * Sin(30.*I2R(ii)*0.017453292)
            call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Other\\FrostBolt\\FrostBoltMissile.mdl", X, Y))
        endloop

    endloop
    
    call ForGroup(NovaGroup, function Trig_Blizzaga_Start_Damage)
    call DestroyGroup(NovaGroup)
    set NovaGroup = null
    set Dummy = null
    set Caster = null
    set Target = null
endfunction

//Events
function InitTrig_Blizzaga_Start takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t, Condition( function Trig_Blizzaga_Start_Conditions))
    call TriggerAddAction(t, function Trig_Blizzaga_Start_Actions)
endfunction
 
Status
Not open for further replies.
Top