• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[vJass]Pulsing, following knockback Frostnova

Status
Not open for further replies.
Level 13
Joined
Mar 16, 2008
Messages
941
This version is pulsing around the position of the caster and doesn't follows him (for sure it doesnt', but it pulses)

JASS:
scope FrostnovaScope

public struct FrostnovaData
    unit caster = GetTriggerUnit()
    unit array missle [36]

    group enemys = CreateGroup()
    real maxdist = 500
    real mindist = 100
    real damage
    real move = 400.0*0.035
    real cx
    real cy
    real array x [36]
    real array y [36]
    real array dist [36]
    real array cos [36]
    real array sin [36]
    integer out = 0
endstruct

globals
    timer FrostnovaTimer = CreateTimer()
    FrostnovaData array Frostnova
    integer FrostnovaMax = 0
    private integer tempint = 0
endglobals

function Frostnova_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00Z'
endfunction

function Frostnova_Enemys takes nothing returns boolean
    local FrostnovaData data = Frostnova[tempint]
    return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(data.caster)) and not IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) and GetWidgetLife(GetFilterUnit()) > 0.405
endfunction

function Frostnova_Movement takes nothing returns nothing
    local FrostnovaData data
    local unit enemy
    local group enemys
    local player owner
    local real x
    local real y
    local integer i = 0
    local integer j = 0

    loop
        exitwhen i >= FrostnovaMax
        set data = Frostnova[i]

        loop
            exitwhen j >= 36
            if (data.dist[j] <= data.maxdist and data.out == 0) then
                set data.dist[j] = data.dist[j]+data.move
                set data.x[j] = data.x[j]+data.move*data.cos[j]
                set data.y[j] = data.y[j]+data.move*data.sin[j]
                call SetUnitPosition(data.missle[j], data.x[j], data.y[j])

                set enemys = CreateGroup()
                set tempint = i
                call GroupEnumUnitsInRange(enemys, data.x[j], data.y[j], 50, Condition(function Frostnova_Enemys))

                loop
                    set enemy = FirstOfGroup(enemys)
                    exitwhen enemy == null

                    call IssueImmediateOrder(enemy, "stop")
                    call SetUnitPosition(enemy, GetUnitX(enemy)+data.move*data.cos[j], GetUnitY(enemy)+data.move*data.sin[j])

                    if(not IsUnitInGroup(enemy, data.enemys)) then
                        call UnitDamageTarget(data.caster, enemy, data.damage, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_COLD, WEAPON_TYPE_WHOKNOWS)
                        call GroupAddUnit(data.enemys, enemy)
                    endif

                    call GroupRemoveUnit(enemys, enemy)
                endloop
            elseif (data.dist[j] >= data.mindist) then
                set data.dist[j] = data.dist[j]-data.move
                set data.x[j] = data.x[j]-data.move*data.cos[j]
                set data.y[j] = data.y[j]-data.move*data.sin[j]
                call SetUnitPosition(data.missle[j], data.x[j], data.y[j])
                set data.out = 1
            else
                set data.out = 0
                loop
                   set enemy = FirstOfGroup(data.enemys)
                   exitwhen enemy == null
                   call GroupRemoveUnit(enemys, enemy)
                endloop
            endif

            set j = j+1
        endloop

        set j = 0
        set i = i+1
    endloop
endfunction

function Frostnova_Actions takes nothing returns nothing
    local FrostnovaData data = FrostnovaData.create()
    local player owner
    local real x
    local real y
    local real angle = 0
    local integer loopindex = 0

    set owner = GetOwningPlayer(data.caster)
    set data.damage = GetUnitAbilityLevel(data.caster, 'A00Z')*75
    set x = GetUnitX(data.caster)
    set y = GetUnitY(data.caster)

    loop
        exitwhen loopindex >= 36
        set data.cos[loopindex] = Cos(angle*bj_DEGTORAD)
        set data.sin[loopindex] = Sin(angle*bj_DEGTORAD)
        set data.x[loopindex] = x+data.mindist*data.cos[loopindex]
        set data.y[loopindex] = y+data.mindist*data.sin[loopindex]
        set data.missle[loopindex] = CreateUnit(owner, 'n01D', data.x[loopindex], data.y[loopindex], 0)
        set data.dist[loopindex] = 0
        set loopindex = loopindex+1
        set angle = angle+10
    endloop

    set Frostnova[FrostnovaMax] = data
    set FrostnovaMax = FrostnovaMax+1

    if (FrostnovaMax == 1) then
        call TimerStart(FrostnovaTimer, 0.035, true, function Frostnova_Movement)
    endif
endfunction

//===========================================================================
function InitTrig_Frostnova takes nothing returns nothing
    set gg_trg_Frostnova = CreateTrigger( )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Frostnova, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Frostnova, Condition( function Frostnova_Conditions ) )
    call TriggerAddAction( gg_trg_Frostnova, function Frostnova_Actions )
endfunction

endscope

THIS version neither pulses nor follows the caster, why?

JASS:
scope FrostnovaScope

public struct FrostnovaData
    unit caster = GetTriggerUnit()
    unit array missle [36]

    group enemys = CreateGroup()
    real maxdist = 500
    real mindist = 100
    real damage
    real move = 400.0*0.035
    real cx
    real cy
    real array x [36]
    real array y [36]
    real array dist [36]
    real array cos [36]
    real array sin [36]
    integer out = 0
endstruct

globals
    timer FrostnovaTimer = CreateTimer()
    FrostnovaData array Frostnova
    integer FrostnovaMax = 0
    private integer tempint = 0
endglobals

function Frostnova_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00Z'
endfunction

function Frostnova_Enemys takes nothing returns boolean
    local FrostnovaData data = Frostnova[tempint]
    return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(data.caster)) and not IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) and GetWidgetLife(GetFilterUnit()) > 0.405
endfunction

function Frostnova_Movement takes nothing returns nothing
    local FrostnovaData data
    local unit enemy
    local group enemys
    local player owner
    local real x
    local real y
    local integer i = 0
    local integer j = 0

    set data.cx = GetUnitX(data.caster) //new
    set data.cy = GetUnitY(data.caster) //new

    loop
        exitwhen i >= FrostnovaMax
        set data = Frostnova[i]

        loop
            exitwhen j >= 36
            if (data.dist[j] <= data.maxdist and data.out == 0) then
                set data.dist[j] = data.dist[j]+data.move
                set data.x[j] = data.cx+data.dist[j]*data.cos[j] //changed
                set data.y[j] = data.cy+data.dist[j]*data.sin[j] //changed
                call SetUnitPosition(data.missle[j], data.x[j], data.y[j]) //changed

                set enemys = CreateGroup()
                set tempint = i
                call GroupEnumUnitsInRange(enemys, data.x[j], data.y[j], 50, Condition(function Frostnova_Enemys))

                loop
                    set enemy = FirstOfGroup(enemys)
                    exitwhen enemy == null

                    call IssueImmediateOrder(enemy, "stop")
                    call SetUnitPosition(enemy, GetUnitX(enemy)+data.move*data.cos[j], GetUnitY(enemy)+data.move*data.sin[j])

                    if(not IsUnitInGroup(enemy, data.enemys)) then
                        call UnitDamageTarget(data.caster, enemy, data.damage, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_COLD, WEAPON_TYPE_WHOKNOWS)
                        call GroupAddUnit(data.enemys, enemy)
                    endif

                    call GroupRemoveUnit(enemys, enemy)
                endloop
            elseif (data.dist[j] >= data.mindist) then
                set data.dist[j] = data.dist[j]-data.move
                set data.x[j] = data.x[j]-data.move*data.cos[j]
                set data.y[j] = data.y[j]-data.move*data.sin[j]
                call SetUnitPosition(data.missle[j], data.x[j], data.y[j])
                set data.out = 1
            else
                set data.out = 0
                loop
                   set enemy = FirstOfGroup(data.enemys)
                   exitwhen enemy == null
                   call GroupRemoveUnit(enemys, enemy)
                endloop
            endif

            set j = j+1
        endloop

        set j = 0
        set i = i+1
    endloop
endfunction

function Frostnova_Actions takes nothing returns nothing
    local FrostnovaData data = FrostnovaData.create()
    local player owner
    local real x
    local real y
    local real angle = 0
    local integer loopindex = 0

    set owner = GetOwningPlayer(data.caster)
    set data.damage = GetUnitAbilityLevel(data.caster, 'A00Z')*75
    set x = GetUnitX(data.caster)
    set y = GetUnitY(data.caster)

    loop
        exitwhen loopindex >= 36
        set data.cos[loopindex] = Cos(angle*bj_DEGTORAD)
        set data.sin[loopindex] = Sin(angle*bj_DEGTORAD)
        set data.x[loopindex] = x+data.mindist*data.cos[loopindex]
        set data.y[loopindex] = y+data.mindist*data.sin[loopindex]
        set data.missle[loopindex] = CreateUnit(owner, 'n01D', data.x[loopindex], data.y[loopindex], 0)
        set data.dist[loopindex] = 0
        set loopindex = loopindex+1
        set angle = angle+10
    endloop

    set Frostnova[FrostnovaMax] = data
    set FrostnovaMax = FrostnovaMax+1

    if (FrostnovaMax == 1) then
        call TimerStart(FrostnovaTimer, 0.035, true, function Frostnova_Movement)
    endif
endfunction

//===========================================================================
function InitTrig_Frostnova takes nothing returns nothing
    set gg_trg_Frostnova = CreateTrigger( )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Frostnova, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Frostnova, Condition( function Frostnova_Conditions ) )
    call TriggerAddAction( gg_trg_Frostnova, function Frostnova_Actions )
endfunction

endscope

Hope you can help me :sad:

Greets, Justify
 
Last edited:
Level 29
Joined
Jul 29, 2007
Messages
5,174
Might you reveal to the non-intelligent people (I.E: everyone other then you) whats this spell of awesomeness is supposed to do ?

And by the way, using arrays inside structs isn't recommended.
When using an array inside a struct it cuts off the number of instances of that struct you can have at the same time by this formula: 8192 / array number.
Now I'm not sure if those 36 adds but even if not, its just not recommended. lol.
 
Level 13
Joined
Mar 16, 2008
Messages
941
I don't know if they stack, if not 227 instances are enough, if they stack 38 instances of an ultimate are also enough, since this doesn't even has to be MUI, but I made it because I don't know what will happen to this spell later (at the moment its an ultimate, but I don't know what wil be possible in new gamemodes of my map :) ).

Then, I thought the title tells enough:
It is (or it should be... >.< )a pulsing knockback nova, so a ring (of units) around the caster is pulsing in and out, knocking all units back (in this case just while pulsing out).
I want it to follow the caster, but the second one is neither pulsing nor following, and I just don't get why :(
Oh by the way, I know that my version will NEVER end, I just want to get it working, destroying is easy enough later :)

Greets, Justify
 
Level 9
Joined
Mar 25, 2005
Messages
252
I found something in the second version:
JASS:
function Frostnova_Movement takes nothing returns nothing
    local FrostnovaData data
    local unit enemy
    local group enemys
    local player owner
    local real x
    local real y
    local integer i = 0
    local integer j = 0
    
    // Data is uninitialized at this point!
    set data.cx = GetUnitX(data.caster) //new
    set data.cy = GetUnitY(data.caster) //new

    //...
 
Status
Not open for further replies.
Top