HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

math problems..

01-13-2008, 09:36 PM#1
StRoNgFoE_2000
Hi everyone, I've been trying to create a spell called mana beam, which is nothing fancy, just shoots a beam. To better visualize it, I'm using a dummy unit with a large scaling value and the Avatar of Vengeance model. I'm using a timer to move it really fast by setting a new position as opposed to ordering it. There's no actual damage going on yet in the script, I didn't implement any yet. Trying to get the visual down first....

Here it is, it kinda works, but it shoots the beam in a random direction instead of where I'm casting it. The beam has to reach the target location (point of cast) + 1000 in order to be removed, so the map crashes after about 5-10 times casting as well. At least I think thats what's causing the crashes. Anyway, I've been staring at this for awhile, pretty tired atm and was wondering if anyone can point out where my math fails or could give me some advice on how to make this work, because I can't find my error. Thanks.

Edit.. Boy I feel like a fool.. I fixed it with this new function.. I was using DistanceBetweenCoords where I should have been using Coords2Angle ..

Collapse JASS:
function Coords2Angle takes real x1, real y1, real x2, real y2 returns real
     return bj_RADTODEG * Atan2(y2 - y1, x2 - x1)
endfunction
function DistanceBetweenCoords takes real x1, real y1, real x2, real y2 returns real
    return SquareRoot((x2-x1) * (x2-x1) + (y2-y1) * (y2-y1))
endfunction
struct manabeam
    timer    t  =  CreateTimer()
    unit     u                      // Caster
    unit     v                      // Mana Beam
    player   p                      // Owner of Caster
    location e                      // End destination (Point of Cast)
    real     a                      // Angle
    static method create takes nothing returns manabeam
        local manabeam data = manabeam.allocate()
        set data.u = GetSpellAbilityUnit()
        set data.p = GetOwningPlayer(data.u)
        set data.e = GetSpellTargetLoc()
        set data.v = CreateUnit(data.p, 'h009', GetUnitX(data.u), GetUnitY(data.u), 270)
        set data.a = Coords2Angle(GetUnitX(data.v), GetUnitY(data.v), GetLocationX(data.e), GetLocationY(data.e))
        return data
    endmethod
    method onDestroy takes nothing returns nothing
        call RemoveUnit(.v)
        call FlushHandleLocals(.t)
        call PauseTimer(.t)
        call DestroyTimer(.t)
        call RemoveLocation(.e)
    endmethod
endstruct
function MageManaBeamCond takes nothing returns boolean
    return GetSpellAbilityId() == 'A00E'
endfunction
function StartBeam takes nothing returns nothing
    local timer      t      =  GetExpiredTimer()
    local manabeam   data   =  GetHandleInt(t, "beam")
    local real       BeamX  =  GetUnitX(data.v)
    local real       BeamY  =  GetUnitY(data.v)
    local real       NewX   =  BeamX + 8 * Cos(data.a * bj_DEGTORAD)
    local real       NewY   =  BeamY + 8 * Sin(data.a * bj_DEGTORAD)
    local real       Dist   =  DistanceBetweenCoords(NewX, NewY, GetLocationX(data.e) + 1000, GetLocationY(data.e) + 1000)
    call SetUnitPosition(data.v, NewX, NewY)
    if Dist <= 100 then
        call data.destroy()
    endif
    set t = null
endfunction   
function MageManaBeam takes nothing returns nothing
    local manabeam data = manabeam.create()
    call SetHandleInt(data.t, "beam", data)
    call TimerStart(data.t, .003, true, function StartBeam)
endfunction
function InitTrig_MageManaBeam takes nothing returns nothing
    set gg_trg_MageManaBeam = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(gg_trg_MageManaBeam, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(gg_trg_MageManaBeam, Condition(function MageManaBeamCond))
    call TriggerAddAction(gg_trg_MageManaBeam, function MageManaBeam)
endfunction
01-13-2008, 10:12 PM#2
TaintedReality
Collapse JASS:
local real       Dist   =  Coords2Angle (NewX, NewY, GetLocationX(data.e), GetLocationY(data.e))

Didn't really see anything wrong with your angles, at least that would cause it to work incorrectly (plenty of ways to optimize though). But you're setting Distance to an angle, then checking if it's less than 100 o.o.
01-13-2008, 11:27 PM#3
StRoNgFoE_2000
Well I finally finished it and it actually works like i envisioned it. I do have one concern, something I still do not know about structs. There are two places I retrieve a struct from a handle, one a timer another a trigger. But, I only have destroy one time, because if I destroy it in the trigger then everything stops working. My questions are, am I destroying the structs properly, and is anything leaking here?

Collapse JASS:
library MageManaBeam initializer ManaVars
    globals
        integer array MANADMG
    endglobals
    function ManaVars takes nothing returns nothing
        set MANADMG[1]  =  320
        set MANADMG[2]  =  680
        set MANADMG[3]  =  925
        set MANADMG[4]  =  1460
    endfunction
endlibrary

function Coords2Angle takes real x1, real y1, real x2, real y2 returns real
     local real x = x2 - x1
     local real y = y2 - y1
     return bj_RADTODEG * Atan2(y, x)
endfunction
function DistanceBetweenCoords takes real x1, real y1, real x2, real y2 returns real
    local real x = x2 - x1
    local real y = y2 - y1
    return SquareRoot(x * x + y * y)
endfunction

struct manabeam
    timer    t  =  CreateTimer()
    trigger  z  =  CreateTrigger()
    unit     u                      // Caster
    unit     v                      // Mana Beam
    player   p                      // Owner of Caster
    location e                      // End destination (Point of Cast)
    real     a                      // Angle
    real     x                      // X of location e
    real     y                      // Y of location e
    integer  i                      // Level of Ability
    boolean  b                      // Allows the dying special effect only once.
    static method create takes nothing returns manabeam
        local manabeam data = manabeam.allocate()
        set data.b = true
        set data.u = GetSpellAbilityUnit()
        set data.p = GetOwningPlayer(data.u)
        set data.i = GetUnitAbilityLevel(data.u, 'A00E')
        set data.e = GetSpellTargetLoc()
        set data.x = GetLocationX(data.e)
        set data.y = GetLocationY(data.e)
        set data.v = CreateUnit(data.p, 'h009', GetUnitX(data.u), GetUnitY(data.u), 270)
        set data.a = Coords2Angle(GetUnitX(data.v), GetUnitY(data.v), data.x, data.y)
        return data
    endmethod
    method onDestroy takes nothing returns nothing
        call RemoveUnit(.v)
        call DestroyTrigger(.z)
        call FlushHandleLocals(.t)
        call PauseTimer(.t)
        call DestroyTimer(.t)
        call RemoveLocation(.e)
    endmethod
endstruct

function MageManaBeamCond takes nothing returns boolean
    return GetSpellAbilityId() == 'A00E'
endfunction
function ManaBeamDamage takes nothing returns nothing
    local trigger    t      =  GetTriggeringTrigger()
    local manabeam   data   =  GetHandleInt(t, "beam")
    local unit       u      =  GetTriggerUnit()
    if IsUnitEnemy(u, data.p) then
        call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\ManaFlare\\ManaFlareBoltImpact.mdl", u, "origin"))
        call UnitDamageTarget(data.v, u, MANADMG[data.i], true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS) 
    endif
    set t = null
    set u = null
endfunction
function StartBeam takes nothing returns nothing
    local timer      t      =  GetExpiredTimer()
    local manabeam   data   =  GetHandleInt(t, "beam")
    local real       BeamX  =  GetUnitX(data.v)
    local real       BeamY  =  GetUnitY(data.v)
    local real       NewX   =  BeamX + 8 * Cos(data.a * bj_DEGTORAD)
    local real       NewY   =  BeamY + 8 * Sin(data.a * bj_DEGTORAD)
    local real       Dist   =  DistanceBetweenCoords(NewX, NewY, data.x, data.y)
    call SetUnitPosition(data.v, NewX, NewY)
  // Very cheesy attempt to try to line up the explode effect with beam death.
    if Dist <= 400 and data.b then
        call DestroyEffect(AddSpecialEffect("Units\\NightElf\\Wisp\\WispExplode.mdl", data.x, data.y))
        set data.b = false
    endif
    if Dist <= 10 then
        call data.destroy()
    endif
    set t = null
endfunction   
function MageManaBeam takes nothing returns nothing
    local manabeam data = manabeam.create()
    local trigger t = CreateTrigger()
    call SetHandleInt(data.t, "beam", data)
    call SetHandleInt(data.z, "beam", data)
    call TriggerRegisterUnitInRange(data.z, data.v, 250, null)
    call TriggerAddAction(data.z, function ManaBeamDamage)
    call TimerStart(data.t, .004, true, function StartBeam)
    set t = null
endfunction
function InitTrig_MageManaBeam takes nothing returns nothing
    set gg_trg_MageManaBeam = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(gg_trg_MageManaBeam, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(gg_trg_MageManaBeam, Condition(function MageManaBeamCond))
    call TriggerAddAction(gg_trg_MageManaBeam, function MageManaBeam)
endfunction