HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Line Spell

04-17-2009, 09:55 AM#1
wraithseeker
Collapse JASS:
scope TidalWave initializer Init

globals
    private constant integer SPELL = 'A008'
    private constant integer STOMP = 'A009'
    private constant string EFFECT = "Objects\\Spawnmodels\\Naga\\NagaDeath\\NagaDeath.mdl"
    private boolexpr b
endglobals

private struct data
    unit target
    timer t
    real velocityZ
    real gravity
    real positionZ

static method create takes nothing returns data
    local data d = data.allocate()
    set d.t = NewTimer()
    set d.gravity = -(1/2)
    set d.velocityZ = 35
    return d
endmethod

method onDestroy takes nothing returns nothing
    call ReleaseTimer(.t)
endmethod

endstruct

private function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == SPELL
endfunction

private function LineFilter takes nothing returns boolean
    return IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(GetTriggerUnit())) and GetWidgetLife(GetFilterUnit()) > 0.0451
endfunction

private function Heights takes nothing returns nothing
    local data d = data(GetTimerData(GetExpiredTimer()))
    local real height = GetUnitFlyHeight(d.target)
     set d.velocityZ = d.velocityZ+d.gravity
    set d.positionZ = d.positionZ + d.velocityZ
    set d.velocityZ = d.velocityZ + d.gravity
    call SetUnitFlyHeight(d.target,d.positionZ,0)
    if d.positionZ <= 0 then
        call SetUnitFlyHeight(d.target,0,0)
        call d.destroy()
    endif
endfunction

private function Actions takes nothing returns nothing
    local data d
    local unit caster = GetTriggerUnit()
    local location target = GetSpellTargetLoc()
    local unit dummy
    local group g = NewGroup()
    local group hitgroup = NewGroup()
    local integer i = 1
    local integer effects = 4
    local real dist = 600
    local real divdist = dist/effects
    local real cx = GetUnitX(caster)
    local real cy = GetUnitY(caster)
    local real tx = GetLocationX(target)
    local real ty = GetLocationY(target)
    local real angle = Atan2(ty-cy,tx-cx)
    local real dx = cx + 600 + Cos(angle)
    local real dy = cy + 600 + Sin(angle)
    local real x
    local real y
    local unit u
    local integer c = 150
    loop
        exitwhen i > effects
        call TriggerSleepAction(0.1)
        set x = GetUnitX(caster) + (divdist * i) * Cos(angle)
        set y = GetUnitY(caster) + (divdist * i) * Sin(angle)
        set dummy = CreateUnit(GetOwningPlayer(caster),DUMMY,x,y,GetUnitFacing(caster))
        call SetUnitScale(dummy,2,2,2)
        call StartTimedEffects(EFFECT,dummy,"origin",3)
        call StartTimedEffects(EFFECT,dummy,"overhead",3)
        call UnitAddAbility(dummy,STOMP)
        call SetUnitAbilityLevel(dummy,STOMP,GetUnitAbilityLevel(caster,SPELL))
        call IssueImmediateOrder(dummy,"stomp")
        call UnitApplyTimedLife(dummy,'BTLF',5)
        call GroupEnumUnitsInRangeOfSegment(g,cx,cy,dx,dy,c,b)
        loop
        set u = FirstOfGroup(g)
        exitwhen u == null
        if not IsUnitInGroup(u,hitgroup) then
         call GroupAddUnit(hitgroup,u)
        call UnitAddAbility(u,FLYID)
        call UnitRemoveAbility(u,FLYID)
        set d = data.create()
        set d.target = u
        call SetTimerData(d.t,d)
        call TimerStart(d.t,0.025,true,function Heights)
        call GroupRemoveUnit(g,u)
        endif
        endloop
        set i = i + 1
        set c = c + 150
    endloop
        set u = null
    set caster = null
    set dummy = null
    call RemoveLocation(target)
    call ReleaseGroup(g)
    call ReleaseGroup(hitgroup)
    set target = null
endfunction

//===========================================================================
private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddAction( t, function Actions )
    call TriggerAddCondition(t,Condition(function Conditions))
    set b = Filter(function LineFilter)
endfunction
endscope

Everything for this spell works fine except the flying part of the unit. The unit flies up and never comes down for some weird reason.

It uses GroupUtils and TimerUtils and TimedEffect which is not related to the problem.
04-17-2009, 12:07 PM#2
Anitarf
1/2 is an integer division and results in 0.

By the way, that's some really ugly code.
04-17-2009, 01:29 PM#3
wraithseeker
suggestions on making it better?
04-19-2009, 01:55 PM#4
Zerzax
Collapse JASS:
    
local real dx = cx + 600 * Cos(angle)
local real dy = cy + 600 * Sin(angle)

You had plus cos and plus sin before instead of times. I forgot how to highlight in red, gonna go check that.

Also, you make a loop inside a loop. I think it'd be better to make your boolexpr filter just parse through each unit and never accept them to a global group. Not only is it faster for enumeration, it makes your big loop look cleaner and somewhat less expensive. Now if you really wanted to keep that loop, indent it like you did the other one. Put some spaces here and there that signify a change in the "direction" your functions are taking.