• 🏆 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] Height & missile problems (missile engine)

Status
Not open for further replies.
Level 17
Joined
Nov 13, 2006
Messages
1,814
Problems:

1. if i dont declare atleast 1 point to variable in map init then dont work the GetLocationZ(variable name), coz allways return with 0, if i declare example center of playable map in map init then work, but its leak too, no?

2. i failed so hard on make missile homming with parabola, 1st i tryed find functions what let me declare the the height where missile stop, so endZ but every formula was wrong t me because: or missile was above the unit, or on lower height than unit, or just made a whole parabola

overall now crashing sometimes the map when i try the homing missile, sometimes the missile going away or jump to sky etc :D

after i tryed every formule i decided , use parabola function and when only short left then i just decrease unit height step by step till he reach the target but this dont solved nothing, same problem about sometimes missile go to sky or somewhere else

3. first i tryed this functions (bottom\/) with vex dummy unit (after i made this http://www.wc3c.net/showthread.php?t=105830) but if i lock to target when missile do parabola, the missile angle is weird because lets say parabola is max height is higher than target unit height, arrow look to target direction even still arrow flying up.

same problem when dummy arrow flying up, if i focus to target location then also unrealistic when its fly up or on way :/

JASS:
// To make the dummy face a 2 dimensional orientation instantly:
function SetDummyFacing takes unit u, real angle returns nothing
    call SetUnitLookAt(u, "Bone_Head", u, Cos(angle) * 1000000., Sin(angle) * 1000000., 0.)
endfunction

// To make the dummy face a 3 dimensional orientation instantly:
function SetDummyOrientation takes unit u, real x, real y, real z returns nothing
    call SetUnitLookAt(u, "Bone_Head", u, x * 1000000., y * 1000000., z * 1000000.)
endfunction

//To make the dummy always face a particular unit, for homing missiles:
function SetDummyHomingTarget takes unit u, unit target returns nothing
    call SetUnitLookAt(u, "Bone_Head", target, 0., 0., 0.)
endfunction

function DummyRecycle takes unit u returns nothing
    if udg_Dummy_Index < udg_Dummy_Max and GetUnitTypeId(u)=='h000' then
        set udg_Dummy_Index = udg_Dummy_Index + 1
        set udg_Dummy_Unit[udg_Dummy_Index] = u
        call ShowUnit(u, false)
    endif
endfunction


Jass triggers \/

called functions

JASS:
function DummyRecycle takes unit u returns nothing
    if udg_Dummy_Index < udg_Dummy_Max and GetUnitTypeId(u)=='h000' then
        set udg_Dummy_Index = udg_Dummy_Index + 1
        set udg_Dummy_Unit[udg_Dummy_Index] = u
        call ShowUnit(u, false)
    endif
endfunction

function GetNewDummy takes real x1, real y1, real ang returns unit
    if udg_Dummy_Unit[1] == null then
        set udg_unit = udg_Dummy_Unit[1]
        set udg_unit = CreateUnit(Player(15), 'h000', x1, y1, ang)
        call UnitAddAbility( udg_unit, 'Arav' )
        call UnitRemoveAbility( udg_unit, 'Arav' )
    else
        set udg_unit = udg_Dummy_Unit[1]
        call ShowUnit(udg_unit, true)
        set udg_Dummy_Unit[1] = udg_Dummy_Unit[udg_Dummy_Index]
        set udg_Dummy_Unit[udg_Dummy_Index] = null
        set udg_Dummy_Index = udg_Dummy_Index - 1
    endif
    return udg_unit
endfunction

function Missile takes unit launcher, unit target, string sfx1, string sfx2, real collision, real x1, real y1, real x2, real y2, real startheight, real speed, real maxspeed, real accelerate, real arc, real arcdist, boolean parabola, real height, real dmg1, real dmg2, real aoe, real dmg3, boolean homing, boolean heightlock returns nothing
    local integer i
    local real dx = x2 - x1
    local real dy = y2 - y1
    local real r
    local real launcherheight = GetUnitFlyHeight(launcher) + startheight
    set udg_MS_Index = udg_MS_Index + 1
    set i = udg_MS_Index

    set udg_MS_X[i] = x1
    set udg_MS_Y[i] = y1
    set udg_MS_Angle[i] = Atan2(y2 - y1, x2 - x1)
    set udg_MS_CurDist[i] = 0
    set udg_MS_MaxDist[i] = SquareRoot(dx * dx + dy * dy)
    set udg_MS_Speed[i] = speed
    set udg_MS_Launcher[i] = launcher
                
    if arc != 0 then
        set udg_MS_ArcDist[i] = arcdist
        set udg_MS_ArcAngle[i] = udg_MS_Angle[i] + arc
        set udg_MS_Arc[i] = true
    else
        set udg_MS_ArcDist[i] = 0
        set udg_MS_ArcAngle[i] = 0
        set udg_MS_Arc[i] = false
    endif

    if parabola then
        set udg_MS_MaxHeight[i] = height
        set udg_MS_Parabola[i] = true
    else
        set udg_MS_MaxHeight[i] = 0
        set udg_MS_Parabola[i] = false
    endif

    if speed != maxspeed then
        set udg_MS_MaxSpeed[i] = maxspeed
        set udg_MS_Accelerate[i] = accelerate
        set udg_MS_SpeedUp[i] = true
    else
        set udg_MS_SpeedUp[i] = false
        set udg_MS_MaxSpeed[i] = 0
        set udg_MS_Accelerate[i] = 0
    endif

    if dmg1 != 0 then
        set udg_MS_Dmg_On[i] = true
        set udg_MS_Dmg[i] = dmg1
        set udg_MS_Collision[i] = collision
    else
        set udg_MS_Dmg_On[i] = false
        set udg_MS_Dmg[i] = 0
        set udg_MS_Collision[i] = 0
    endif

    if dmg2 != 0 then
        set udg_MS_Dmg_Ex_On[i] = true
        set udg_MS_Aoe_Dmg[i] = dmg2
        set udg_MS_Dmg_Area[i] = aoe
    else
        set udg_MS_Dmg_Ex_On[i] = false
        set udg_MS_Aoe_Dmg[i] = 0
        set udg_MS_Dmg_Area[i] = 0
    endif

    set udg_MS_Dmg_Ex[i] = dmg3

    if homing then
        set udg_MS_Homing_Target[i] = target
        set udg_MS_Suicide[i] = true
        set udg_MS_StartZ[i] = launcherheight
        set r = GetUnitMoveSpeed(target) * 0.03
        if speed < r then
            set udg_MS_Speed[i] = r + 1
        endif
        if maxspeed < r then
            set udg_MS_MaxSpeed[i] = r + 1
        endif
    else
        set udg_MS_Homing_Target[i] = null
        set udg_MS_Suicide[i] = false
    endif

    if heightlock then
        call MoveLocation(udg_p, x1 , y1)
        set udg_MS_Height[i] = launcherheight + GetLocationZ(udg_p)
        set udg_MS_LockedHeight[i] = true
    else
        set udg_MS_LockedHeight[i] = false
    endif

    set udg_MS_Player[i] = GetOwningPlayer(launcher)
    set udg_MS_Homing[i] = homing
    set udg_MS_Unit[i] = GetNewDummy(x1, x2, udg_MS_Angle[i])

    if heightlock then
call SetUnitUserData(udg_MS_Unit[i],100)

endif
    call AddSpecialEffectTarget(sfx1, udg_MS_Unit[i], "overhead")
    if sfx1 != null then
         set udg_MS_SFX[i] = AddSpecialEffectTarget(sfx1, udg_MS_Unit[i], "overhead")
    endif
    if sfx2 != null then
         set udg_MS_SFX_Hit[i] = sfx2
    endif
    set udg_MS_Height[i] = GetUnitFlyHeight(udg_MS_Unit[i])
    call SetUnitFlyHeight( udg_MS_Unit[i], launcherheight, 0.00 )
    if homing then

        call SetDummyHomingTarget(udg_MS_Unit[i], udg_MS_Homing_Target[i])
    else
        call SetDummyFacing (udg_MS_Unit[i], udg_MS_Angle[i])
    endif

endfunction


timer trigger


JASS:
function Trig_Missile_Timer takes nothing returns nothing
    local integer i = 1
    local real x
    local real y
    local real dx
    local real dy
    local real h
    local real r1
    local real ang

    loop
        exitwhen i > udg_MS_Index

        if udg_MS_CurDist[i] >= udg_MS_MaxDist[i] then
            call DummyRecycle(udg_MS_Unit[i])
            call DisplayTextToForce( GetPlayersAll(), "|cffffff00Recycleable Dummy units on stock: "+I2S(udg_Dummy_Index) +"|r")
            if udg_MS_SFX[i] != null then
                call DestroyEffect(udg_MS_SFX[i])
            endif
            if i != udg_MS_Index then
                set udg_MS_SFX_Hit[i] = udg_MS_SFX_Hit[udg_MS_Index]
                set udg_MS_SFX[i] = udg_MS_SFX[udg_MS_Index]
                set udg_MS_Unit[i] = udg_MS_Unit[udg_MS_Index]
                set udg_MS_Homing_Target[i] = udg_MS_Homing_Target[udg_MS_Index]
                set udg_MS_Launcher[i] = udg_MS_Launcher[udg_MS_Index]
                set udg_MS_Player[i] = udg_MS_Player[udg_MS_Index]
                set udg_MS_X[i] = udg_MS_X[udg_MS_Index]
                set udg_MS_Y[i] = udg_MS_Y[udg_MS_Index]
                set udg_MS_Homing[i] = udg_MS_Homing[udg_MS_Index]
                set udg_MS_LockedHeight[i] = udg_MS_LockedHeight[udg_MS_Index]
                set udg_MS_Height[i] = udg_MS_Height[udg_MS_Index]
                set udg_MS_MaxHeight[i] = udg_MS_MaxHeight[udg_MS_Index]
                set udg_MS_SpeedUp[i] = udg_MS_SpeedUp[udg_MS_Index]
                set udg_MS_Accelerate[i] = udg_MS_Accelerate[udg_MS_Index]
                set udg_MS_Speed[i] = udg_MS_Speed[udg_MS_Index]
                set udg_MS_MaxSpeed[i] = udg_MS_MaxSpeed[udg_MS_Index]
                set udg_MS_CurDist[i] = udg_MS_CurDist[udg_MS_Index]
                set udg_MS_MaxDist[i] = udg_MS_MaxDist[udg_MS_Index]
                set udg_MS_Arc[i] = udg_MS_Arc[udg_MS_Index]
                set udg_MS_Parabola[i] = udg_MS_Parabola[udg_MS_Index]
                set udg_MS_ArcAngle[i] = udg_MS_ArcAngle[udg_MS_Index]
                set udg_MS_Angle[i] = udg_MS_Angle[udg_MS_Index]
                set udg_MS_Collision[i] = udg_MS_Collision[udg_MS_Index]
                set udg_MS_Suicide[i] = udg_MS_Suicide[udg_MS_Index]
                set udg_MS_Dmg_Ex_On[i] = udg_MS_Dmg_Ex_On[udg_MS_Index]
                set udg_MS_Dmg_On[i] = udg_MS_Dmg_On[udg_MS_Index]
                set udg_MS_Dmg[i] = udg_MS_Dmg[udg_MS_Index]
                set udg_MS_Dmg_Area[i] = udg_MS_Dmg_Area[udg_MS_Index]
                set udg_MS_Dmg_Ex[i] = udg_MS_Dmg_Ex[udg_MS_Index]
                set udg_MS_Dmg_Ex[i] = udg_MS_Dmg_Ex[udg_MS_Index]
                set udg_MS_StartZ[i] = udg_MS_StartZ[udg_MS_Index]
            endif

            set i = i - 1
            set udg_MS_Index = udg_MS_Index - 1

        else

            set x = GetUnitX(udg_MS_Unit[i])
            set y = GetUnitY(udg_MS_Unit[i])

            if udg_MS_SpeedUp[i] and udg_MS_Accelerate[i]!=0 then
                if udg_MS_Accelerate[i] > 0 and udg_MS_MaxSpeed[i] > udg_MS_Speed[i] then
                    set udg_MS_Speed[i] = udg_MS_Speed[i] + udg_MS_Accelerate[i]
                elseif udg_MS_Accelerate[i] < 0 and udg_MS_MaxSpeed[i] < udg_MS_Speed[i] then
                    set udg_MS_Speed[i] = udg_MS_Speed[i] + udg_MS_Accelerate[i]
                endif

            endif

            if udg_MS_Homing[i] then
                set dx = GetUnitX(udg_MS_Homing_Target[i]) - x
                set dy = GetUnitY(udg_MS_Homing_Target[i]) - y
                set udg_MS_CurDist[i] = udg_MS_MaxDist[i] + 50 - SquareRoot(dx * dx + dy * dy)
                set udg_MS_Angle[i] = Atan2(dy, dx)
            else
                set udg_MS_CurDist[i] = udg_MS_CurDist[i] + udg_MS_Speed[i]
            endif

            set dx = x + 50 * Cos(udg_MS_Angle[i])
            set dy = y + 50 * Sin(udg_MS_Angle[i])
           
            if dx > udg_MapMinX and dx < udg_MapMaxX and dy > udg_MapMinY and dy < udg_MapMaxY then
    
                if udg_MS_Arc[i] then
                    set r1 = ( 4 * udg_MS_ArcDist[i] / udg_MS_MaxDist[i] ) * ( udg_MS_MaxDist[i] - udg_MS_CurDist[i] ) * ( udg_MS_CurDist[i] / udg_MS_MaxDist[i] / 2 )
                    set x = udg_MS_X[i] + udg_MS_Speed[i] * Cos(udg_MS_Angle[i])
                    set y = udg_MS_Y[i] + udg_MS_Speed[i] * Sin(udg_MS_Angle[i])
                    set x = x + r1 * Cos(udg_MS_ArcAngle[i])
                    set y = y + r1 * Sin(udg_MS_ArcAngle[i])
                    call SetUnitX(udg_MS_Unit[i], x)
                    call SetUnitY(udg_MS_Unit[i], y)
                    set ang = Atan2(y - udg_MS_Y[i], x - udg_MS_X[i])
                    call SetUnitFacing(udg_MS_Unit[i], ang)
                    set udg_MS_X[i] = udg_MS_X[i] + udg_MS_Speed[i] * Cos(udg_MS_Angle[i])
                    set udg_MS_Y[i] = udg_MS_Y[i] + udg_MS_Speed[i] * Sin(udg_MS_Angle[i])
                else
                    call SetUnitX(udg_MS_Unit[i], (x + udg_MS_Speed[i] * Cos(udg_MS_Angle[i])))
                    call SetUnitY(udg_MS_Unit[i], (y + udg_MS_Speed[i] * Sin(udg_MS_Angle[i])))
                endif
            
                if udg_MS_LockedHeight[i] then
                    call MoveLocation(udg_p, x, y)
                    set r1 = udg_MS_Height[i] - GetLocationZ(udg_p)
                    call SetUnitFlyHeight( udg_MS_Unit[i], r1, 0.00 )
           call DisplayTextToForce( GetPlayersAll(), "r1-"+R2S(r1)+" h-: "+R2S(udg_MS_Height[i]) )

                    set dx = x + 50 * Cos(udg_MS_Angle[i])
                    set dy = y + 50 * Sin(udg_MS_Angle[i])
                    call MoveLocation(udg_p, dx, dy)
                    set r1 = udg_MS_Height[i] - GetLocationZ(udg_p)
           call DisplayTextToForce( GetPlayersAll(), "r1"+R2S(r1)+" h: "+R2S(udg_MS_Height[i]) )
              
                    if r1 > udg_MS_Height[i] then
                        set udg_MS_CurDist[i] = udg_MS_MaxDist[i]
                    endif
                      
                else

                    if udg_MS_Parabola[i] then
                        if udg_MS_Homing[i] then

                            set udg_MS_Height[i] = ( 4 * udg_MS_MaxHeight[i] / udg_MS_MaxDist[i] ) * ( udg_MS_MaxDist[i] - udg_MS_CurDist[i] ) * ( udg_MS_CurDist[i] / udg_MS_MaxDist[i] )
                            set r1 = (udg_MS_MaxDist[i] - udg_MS_CurDist[i]) / udg_MS_Speed[i]
                            if r1 < 20 then
                                set h = (GetUnitFlyHeight(udg_MS_Homing_Target[i]) - udg_MS_Height[i]) / ((udg_MS_MaxDist[i] - udg_MS_CurDist[i]) / udg_MS_Speed[i])
                                set udg_MS_Height[i] = udg_MS_Height[i] + h

                            else
                                set udg_MS_Height[i] = ( 4 * udg_MS_MaxHeight[i] / udg_MS_MaxDist[i] ) * ( udg_MS_MaxDist[i] - udg_MS_CurDist[i] ) * ( udg_MS_CurDist[i] / udg_MS_MaxDist[i] )

                            endif
                            //set udg_MS_Height[i] = ParabolaZ(udg_MS_StartZ[i], GetUnitFlyHeight(udg_MS_Homing_Target[i]), 500, udg_MS_CurDist[i], udg_MS_MaxDist[i])
                            //set udg_MS_Height[i] = ParabolaZ(udg_MS_StartZ[i], GetUnitFlyHeight(udg_MS_Homing_Target[i]), 500, udg_MS_CurDist[i], udg_MS_MaxDist[i])
                        else
                         set udg_MS_Height[i] = ( 4 * udg_MS_MaxHeight[i] / udg_MS_MaxDist[i] ) * ( udg_MS_MaxDist[i] - udg_MS_CurDist[i] ) * ( udg_MS_CurDist[i] / udg_MS_MaxDist[i] )

                        endif
                       // call DisplayTextToForce( GetPlayersAll(), "Dummy["+I2S(i)+"] height: "+R2S(udg_MS_Height[i]) )
                        call SetUnitFlyHeight( udg_MS_Unit[i], udg_MS_Height[i], 0.00 )
                    endif
                endif
                if udg_MS_Dmg_On[i] then
                    call GroupEnumUnitsInRange(udg_UG, x, y, udg_MS_Collision[i], null)
                    loop
                        set udg_unit = FirstOfGroup(udg_UG)
                        exitwhen (udg_unit==null)
                        if IsUnitEnemy(udg_unit, udg_MS_Player[i]) then
                            set r1 = GetUnitFlyHeight(udg_unit)
                            if r1 > (udg_MS_Height[i] - udg_MS_Collision[i] / 2) and r1 < (udg_MS_Height[i] + udg_MS_Collision[i] / 2) then
                               if udg_MS_SFX_Hit[i] != null then
                                call DestroyEffect(AddSpecialEffectTarget(udg_MS_SFX_Hit[i],udg_unit,"chest"))
                                endif
                                call UnitDamageTarget(udg_MS_Launcher[i], udg_unit, udg_MS_Dmg[i], true, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, null)
                                if udg_MS_Suicide[i] then
                                    call GroupClear(udg_UG)
                                    set udg_MS_CurDist[i] = udg_MS_MaxDist[i]
                                endif
                            endif
                        endif
                        call GroupRemoveUnit(udg_UG, udg_unit)
                    endloop
                endif
            else
                set udg_MS_CurDist[i] = udg_MS_MaxDist[i]
            endif

        endif

        set i = i + 1
    endloop

endfunction

//===========================================================================
function InitTrig_Missile_Timer takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterTimerEvent( t, 0.03, true)
    call TriggerAddAction( t, function Trig_Missile_Timer )
endfunction

test trigger

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

function Trig_Test_Actions takes nothing returns nothing
local unit u = GetTriggerUnit()
local player p = GetTriggerPlayer()
local real x1 = GetUnitX(u)
local real y1 = GetUnitY(u)
local real x2 = GetSpellTargetX()
local real y2 = GetSpellTargetY()
local real dx = x2 - x1
local real dy = y2 - y1
local real startheight = 0
local real maxheight = 500
local real arcdist = 100
local real dmg1 = 100
local real dmg2 = 100
local real dmgt = 100
local real aoe = 100
local real collision = 80
local real speed = 1
local real maxspeed = 20
local real accelerate = .1
local real arc = 90
local boolean parabola = true
local boolean lockedheight = false
local boolean homing = false
local string sfx1 = "Abilities\\Weapons\\Arrow\\ArrowMissile.mdl"
local string sfx2 = "Objects\\Spawnmodels\\Human\\HumanBlood\\HumanBloodPeasant.mdl"
local integer i
 


call Missile (u, null, sfx1, sfx2, collision, x1,y1, x2, y2, startheight, speed, maxspeed, accelerate, arc, arcdist, parabola, maxheight, dmg1,dmg2, aoe, dmgt, homing, lockedheight)
call Missile (u, null, sfx1, sfx2, collision, x1,y1, x2, y2, startheight, speed, maxspeed, accelerate, arc, arcdist + 50,  parabola,maxheight-20, dmg1,dmg2, aoe, dmgt, homing, lockedheight)
call Missile (u, null, sfx1, sfx2, collision, x1,y1, x2, y2, startheight, speed, maxspeed, accelerate, arc, arcdist + 100, parabola, maxheight-40, dmg1,dmg2, aoe, dmgt, homing, lockedheight)
call Missile (u, null, sfx1, sfx2, collision, x1,y1, x2, y2, startheight, speed, maxspeed, accelerate, arc, arcdist + 150, parabola, maxheight-60,dmg1,dmg2, aoe, dmgt, homing, lockedheight)

call Missile (u, null, sfx1, sfx2, collision, x1,y1, x2, y2, startheight, speed, maxspeed, accelerate, arc-180, arcdist, parabola, maxheight, dmg1,dmg2, aoe, dmgt, homing, lockedheight)
call Missile (u, null, sfx1, sfx2, collision, x1,y1, x2, y2, startheight, speed, maxspeed, accelerate, arc-180, arcdist + 50,  parabola,maxheight-20, dmg1,dmg2, aoe, dmgt, homing, lockedheight)
call Missile (u, null, sfx1, sfx2, collision, x1,y1, x2, y2, startheight, speed, maxspeed, accelerate, arc-180, arcdist + 100, parabola, maxheight-40, dmg1,dmg2, aoe, dmgt, homing, lockedheight)
call Missile (u, null, sfx1, sfx2, collision, x1,y1, x2, y2, startheight, speed, maxspeed, accelerate, arc-180, arcdist + 150, parabola, maxheight-60,dmg1,dmg2, aoe, dmgt, homing, lockedheight)


call Missile (u, null, sfx1, sfx2, collision, x1,y1, x2, y2, 100, speed, maxspeed, accelerate, arc, arcdist + 300, false, 0,dmg1,dmg2, aoe, dmgt, homing, true)

    call DisplayTextToForce( GetPlayersAll(), "angle " + R2S(udg_MS_Angle[i]) + " distance "+R2S(udg_MS_MaxDist[i]))

call IssueImmediateOrder(u,"stop")

endfunction

//===========================================================================
function InitTrig_Test takes nothing returns nothing
    set gg_trg_Test = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Test, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Test, Condition( function Trig_Test_Conditions ) )
    call TriggerAddAction( gg_trg_Test, function Trig_Test_Actions )
endfunction
 

Attachments

  • Missile.w3x
    43.6 KB · Views: 61
Last edited:
Level 17
Joined
Nov 13, 2006
Messages
1,814
You can set udg_p = Location(0,0) at map init for example, using MoveLocation afterwards for p won't leak.

u knwo the answer to 2 and 3rd point too?

i watched in your project the missile facing to right direction, (another question, u made with attack animation+launch missile that effect or have something trick how to replace the normal attack to your projectile?)
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
1. It's only a leak if you have no way to get rid of it, so no, it technically won't leak (although it will obviously take up memory).

2. Yeah, making a homing missile curve nicely is actually a much harder problem than you'd think. There's a reason wc3 doesn't bother to do it.

3. So point it in the angle it's traveling rather than locking it on the target? Don't understand what the issue is here.
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
1. It's only a leak if you have no way to get rid of it, so no, it technically won't leak (although it will obviously take up memory).

2. Yeah, making a homing missile curve nicely is actually a much harder problem than you'd think. There's a reason wc3 doesn't bother to do it.

3. So point it in the angle it's traveling rather than locking it on the target? Don't understand what the issue is here.

2. really , must be a solution for it :/

3. problem i cant set the arrow facing coorrectly:

example i tryed facing a unit (1st picture), if i dont set unit facing (2nd pic), and correct way what i dont know how to do (3rd picture)
 

Attachments

  • 1.jpg
    1.jpg
    12.8 KB · Views: 107
  • 2.JPG
    2.JPG
    10.9 KB · Views: 90
  • 3.JPG
    3.JPG
    10.4 KB · Views: 105
Level 17
Joined
Nov 13, 2006
Messages
1,814
tryed but dont worked

check the map in 1st post

JASS:
//x=GetUnitX,y=GetUnitY
    set dx = x + 50 * Cos(udg_MS_Angle[i])
                        set dy = y + 50 * Sin(udg_MS_Angle[i])

                        call SetDummyOrientation (udg_MS_Unit[i], dx, dy, ( 4 * udg_MS_MaxHeight[i] / udg_MS_MaxDist[i] ) * ( udg_MS_MaxDist[i] - (udg_MS_CurDist[i] + 50) ) * ( (udg_MS_CurDist[i] + 50) / udg_MS_MaxDist[i] ))

JASS:
// To make the dummy face a 2 dimensional orientation instantly:
function SetDummyFacing takes unit u, real angle returns nothing
    call SetUnitLookAt(u, "Bone_Head", u, Cos(angle) * 1000000., Sin(angle) * 1000000., 0.)
endfunction

// To make the dummy face a 3 dimensional orientation instantly:
function SetDummyOrientation takes unit u, real x, real y, real z returns nothing
    call SetUnitLookAt(u, "Bone_Head", u, x * 1000000., y * 1000000., z * 1000000.)
endfunction

//To make the dummy always face a particular unit, for homing missiles:
function SetDummyHomingTarget takes unit u, unit target returns nothing
    call SetUnitLookAt(u, "Bone_Head", target, 0., 0., 0.)
endfunction
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
Oh. You know what it looks like a problem with your dummy unit. I had a similar problem.

Go into the Object Editor and make sure of these few things:
  • Animation Blend Time is set to 0 so that when you set a new facing it doesn't take any amount of time to update that new visual.
  • Make sure Maximum Pitch/Roll are set to 0 so that terrain variations do not affect the orientation of the projectile.
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
bump
[update] - a bit optimized for shorter core timer

pls somebody can tell me why work well everything with 1st projectile wave (when i fire out alot projectile with small interval) then when later everything will be screwed up

(same angle problem with jump, after x useage its ignore the unit faceing angle and start jump to somewhere else.)

i mean missile 2nd time dont get the correct height, also going back to unit who laucjed it before reach the target (but weird because not every missile)

pls somebody can help me? :/
 

Attachments

  • Missile2.w3x
    47.2 KB · Views: 43
Level 18
Joined
Jan 21, 2006
Messages
2,552
I do not have the time at the moment to look over this. If it isn't solved when I have the time then I'll take a look. I see your bumps every time.

Also just so you know, there is a reason I made my system. It's so that you don't have to do essentially the same thing just to obtain the same functionality.

Also it is incredibly hard to read through what you've got because you're not using vJass for something relatively complicated. It looks like a gigantic wall of variable names and function calls it isn't very clear or easy to read.

JASS:
                        set udg_MS_Angle[i] = Atan2(dy, dx)
                        call SetUnitFacing(udg_MS_Unit[i], udg_MS_Angle[i])

First mistake. You're using a radian value for a degree parameter. For all I know you could have hundreds of these low level mistakes and that is going to make it incredibly difficult for anybody to tell you what your problem is. You haven't even reviewed the syntax to make sure of things like this.

So I've read through about half of what you've got and nothing here screams the necessity of a projectile system at all. The entire purpose of this code is to simply have one unit go in an "arc" to a location and then deal damage to units. Since you don't allow any real interaction with the projectiles the functionality you're "creating" already exists by default in Warcraft 3.

I mean, how do you know its not ReleaseDummy that is causing some of these problems? It seems probable considering you have problems once you have attempted to use this, but I doubt you've tested this before cramming all of this code together.

By commenting out the first if-statement (the part that recycles units, I guess...) I solved your problem of the projectiles moving back to the caster. So clearly this is a source of error.
 
Last edited:
Level 17
Joined
Nov 13, 2006
Messages
1,814
I do not have the time at the moment to look over this. If it isn't solved when I have the time then I'll take a look. I see your bumps every time.

Also just so you know, there is a reason I made my system. It's so that you don't have to do essentially the same thing just to obtain the same functionality.

Also it is incredibly hard to read through what you've got because you're not using vJass for something relatively complicated. It looks like a gigantic wall of variable names and function calls it isn't very clear or easy to read.



First mistake. You're using a radian value for a degree parameter. For all I know you could have hundreds of these low level mistakes and that is going to make it incredibly difficult for anybody to tell you what your problem is. You haven't even reviewed the syntax to make sure of things like this.

So I've read through about half of what you've got and nothing here screams the necessity of a projectile system at all. The entire purpose of this code is to simply have one unit go in an "arc" to a location and then deal damage to units. Since you don't allow any real interaction with the projectiles the functionality you're "creating" already exists by default in Warcraft 3.

I mean, how do you know its not ReleaseDummy that is causing some of these problems? It seems probable considering you have problems once you have attempted to use this, but I doubt you've tested this before cramming all of this code together.

By commenting out the first if-statement (the part that recycles units, I guess...) I solved your problem of the projectiles moving back to the caster. So clearly this is a source of error.

about radian thing, i allways was bad in math, just i noticed when i converte point with oilar offset then there i must do something like this (bj_DEGTORAD*bj_RADTODEG*angle),so i removed every constant :D

i got 1 place where really i dont used the degtorad, so at jumping i use GetUnitFacing then i used the *degtorad in cos/sin for move forward. so this fixed

i changed at arc if but there if i change then its wrong coz show wrong unit facing, so if i keep without radtodeg then its work well in parabola + arc projectiles, atleast with first wave but a weird thing, if i change the unit flying height(example to 200) then its wrong with exactly same unit facing than was previously when unit was on ground.

i tryed disable the put dumy unit to group but that dont worked, only way was for stop unit for going back to caster is the removeing the unit

just a question, if i set the movement speed to 0 then i cant attach arrow special effect to dummy unit, why?
if i hold alt then i see the missile going on right way coz of his health bar but its got no effect but if i change move speed to atleast 1 then arrow effect work well.(ofc movement type is none and i added removed Arav also i use setunitx/y and like i said the parabola/arc work well everything except attachment)

here the release function (the return value is used for decrease i by 1 if unit is released because when i do this udg_MS = udg_MS[maxindex] then the new arrow what got the i index dont will be checked until loop not done, so i > maxindex)

JASS:
function ReleaseDummy takes integer i returns integer
    if udg_Dummy_Index < udg_Dummy_Max and GetUnitTypeId(udg_MS_Unit[i]) == udg_MS_Unit_Type then
        set udg_Dummy_Index = udg_Dummy_Index + 1
        set udg_Dummy_Unit[udg_Dummy_Index] = udg_MS_Unit[i]
        call SetUnitAnimationByIndex(udg_MS_Unit[i], 90 )
        call ShowUnit(udg_MS_Unit[i], false)
    endif
//    call RemoveUnit(udg_MS_Unit[i])
    call DisplayTextToForce( GetPlayersAll(), "|cffffff00Recycleable Dummy units on stock: " + I2S(udg_Dummy_Index) + "|r")
    if udg_MS_SFX[i] != null then
        call DestroyEffect(udg_MS_SFX[i])
    endif
    if i != udg_MS_Index then
        set udg_MS_End[i] = udg_MS_End[udg_MS_Index]
        set udg_MS_SFX_Hit[i] = udg_MS_SFX_Hit[udg_MS_Index]
        set udg_MS_SFX[i] = udg_MS_SFX[udg_MS_Index]
        set udg_MS_SFX_Aoe[i] = udg_MS_SFX_Aoe[udg_MS_Index]
        set udg_MS_SFX_Aoe_Ex[i] = udg_MS_SFX_Aoe_Ex[udg_MS_Index]
        set udg_MS_Unit[i] = udg_MS_Unit[udg_MS_Index]
        set udg_MS_Homing_Target[i] = udg_MS_Homing_Target[udg_MS_Index]
        set udg_MS_Launcher[i] = udg_MS_Launcher[udg_MS_Index]
        set udg_MS_Player[i] = udg_MS_Player[udg_MS_Index]
        set udg_MS_DeathTime[i] = udg_MS_DeathTime[udg_MS_Index]
        set udg_MS_X[i] = udg_MS_X[udg_MS_Index]
        set udg_MS_Y[i] = udg_MS_Y[udg_MS_Index]
        set udg_MS_Z[i] = udg_MS_Z[udg_MS_Index]
        set udg_MS_StartX[i] = udg_MS_StartX[udg_MS_Index]
        set udg_MS_StartY[i] = udg_MS_StartY[udg_MS_Index]
        set udg_MS_StartZ[i] = udg_MS_StartZ[udg_MS_Index]
        set udg_MS_Homing[i] = udg_MS_Homing[udg_MS_Index]
        set udg_MS_LockedHeight[i] = udg_MS_LockedHeight[udg_MS_Index]
        set udg_MS_Height[i] = udg_MS_Height[udg_MS_Index]
        set udg_MS_MaxHeight[i] = udg_MS_MaxHeight[udg_MS_Index]
        set udg_MS_SpeedUp[i] = udg_MS_SpeedUp[udg_MS_Index]
        set udg_MS_Accelerate[i] = udg_MS_Accelerate[udg_MS_Index]
        set udg_MS_Falling[i] = udg_MS_Falling[udg_MS_Index]
        set udg_MS_Speed[i] = udg_MS_Speed[udg_MS_Index]
        set udg_MS_MinSpeed[i] = udg_MS_MinSpeed[udg_MS_Index]
        set udg_MS_MaxSpeed[i] = udg_MS_MaxSpeed[udg_MS_Index]
        set udg_MS_CurDist[i] = udg_MS_CurDist[udg_MS_Index]
        set udg_MS_MaxDist[i] = udg_MS_MaxDist[udg_MS_Index]
        set udg_MS_Knockback[i] = udg_MS_Knockback[udg_MS_Index]
        set udg_MS_Jump[i] = udg_MS_Jump[udg_MS_Index]
        set udg_MS_Arc[i] = udg_MS_Arc[udg_MS_Index]
        set udg_MS_Parabola[i] = udg_MS_Parabola[udg_MS_Index]
        set udg_MS_ArcAngle[i] = udg_MS_ArcAngle[udg_MS_Index]
        set udg_MS_Angle[i] = udg_MS_Angle[udg_MS_Index]
        set udg_MS_Collision[i] = udg_MS_Collision[udg_MS_Index]
        set udg_MS_Suicide[i] = udg_MS_Suicide[udg_MS_Index]
        set udg_MS_Aoe_Dmg[i] = udg_MS_Aoe_Dmg[udg_MS_Index]
        set udg_MS_Dmg_Ex_Aoe[i] = udg_MS_Dmg_Ex_Aoe[udg_MS_Index]
        set udg_MS_Dmg_On[i] = udg_MS_Dmg_On[udg_MS_Index]
        set udg_MS_Dmg[i] = udg_MS_Dmg[udg_MS_Index]
        set udg_MS_Dmg_Ex_Area[i] = udg_MS_Dmg_Ex_Area[udg_MS_Index]
        set udg_MS_Dmg_Ex[i] = udg_MS_Dmg_Ex[udg_MS_Index]
        set udg_MS_Dmg_Type[i] = udg_MS_Dmg_Type[udg_MS_Index]
        set udg_MS_TargetX[i] = udg_MS_TargetX[udg_MS_Index]
        set udg_MS_TargetY[i] = udg_MS_TargetY[udg_MS_Index]
        set udg_MS_TargetZ[i] = udg_MS_TargetZ[udg_MS_Index]
        set udg_MS_DeathTime[i] = udg_MS_DeathTime[udg_MS_Index]
    endif
    set udg_MS_Index = udg_MS_Index - 1
    return i - 1
endfunction


function GetNewDummy takes real x1, real y1, real ang returns unit
    if udg_Dummy_Unit[1] == null then
        set udg_unit = udg_Dummy_Unit[1]
        set udg_unit = CreateUnit(Player(15), 'h000', x1, y1, ang)
        call UnitAddAbility( udg_unit, 'Arav' )
        call UnitRemoveAbility( udg_unit, 'Arav' )
        call SetUnitPathing(udg_unit, false)
        call SetUnitAnimationByIndex(udg_unit, 90 )
    else
        set udg_unit = udg_Dummy_Unit[1]
        call SetUnitX(udg_unit, x1)
        call SetUnitY(udg_unit, y1)
        call SetUnitFlyHeight( udg_unit, 0, 0.00 )
        set udg_Dummy_Unit[1] = udg_Dummy_Unit[udg_Dummy_Index]
        set udg_Dummy_Unit[udg_Dummy_Index] = null
        set udg_Dummy_Index = udg_Dummy_Index - 1
        call ShowUnit(udg_unit, true)
    endif
    return udg_unit
endfunction

So I've read through about half of what you've got and nothing here screams the necessity of a projectile system at all. The entire purpose of this code is to simply have one unit go in an "arc" to a location and then deal damage to units. Since you don't allow any real interaction with the projectiles the functionality you're "creating" already exists by default in Warcraft 3.

when i started then i thinked to make a more eye candy missile than firebolt what going ahead only

so i tryed maked arc+parabola for boost the missile go ahead thing

another reason is i want make a single timer for every knockback, jump, missile thing because nearly all of them based on 0.03 periodic timer

i got no ideea how to make relation with wc3 projectile things, and reason why i dont use a template/vjass system is i want make in jass also i want understand how its work, else damn annoying when i use something and i dont know how its work :/
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
just a question, if i set the movement speed to 0 then i cant attach arrow special effect to dummy unit, why?
if i hold alt then i see the missile going on right way coz of his health bar but its got no effect but if i change move speed to atleast 1 then arrow effect work well.(ofc movement type is none and i added removed Arav also i use setunitx/y and like i said the parabola/arc work well everything except attachment)

You are using SetUnitPosition which has absolutely no effect if the unit is unable to Move. I'm pretty sure that SetUnitX and SetUnitY still work though. Not sure.

The bar of health can be removed with the Locust ability but I have no idea why you're unable to attach a special effect.

also i want understand how its work, else damn annoying when i use something and i dont know how its work :/

I would say that vJass code is a thousand times easier to understand at a fundamental level than a bunch of JASS arrays.

*Edit*

Not sure exactly why the unit isn't moving when there is no movement speed, but I remember there being some correlation between SetUnitPosition and a unit's movement speed. I can't seem to duplicate your bug though, the unit moves regardless of whether its movement speed is 0 or its 'Amov' ability is removed.
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
You are using SetUnitPosition which has absolutely no effect if the unit is unable to Move. I'm pretty sure that SetUnitX and SetUnitY still work though. Not sure.

The bar of health can be removed with the Locust ability but I have no idea why you're unable to attach a special effect.



I would say that vJass code is a thousand times easier to understand at a fundamental level than a bunch of JASS arrays.

*Edit*

Not sure exactly why the unit isn't moving when there is no movement speed, but I remember there being some correlation between SetUnitPosition and a unit's movement speed. I can't seem to duplicate your bug though, the unit moves regardless of whether its movement speed is 0 or its 'Amov' ability is removed.

about dummy recycler, right if i remove the unit with call RemoveUnit then its allways work well, else have problem, sometimes with angle and effect after die event i do this in recycler part:
JASS:
        call SetUnitVertexColor(udg_Dummy_Unit[udg_Dummy_Index], 255, 255, 255, 255)
        call SetUnitAnimationByIndex(udg_Dummy_Unit[udg_Dummy_Index], 90)
        call SetUnitScale(udg_Dummy_Unit[udg_Dummy_Index], 1, 0, 0)
        //i tryed any number for set unit x but that effect still noticeable
        call SetUnitX(udg_Dummy_Unit[udg_Dummy_Index], GetRandomReal(0, 1000))
        call SetUnitY(udg_Dummy_Unit[udg_Dummy_Index], GetRandomReal(0, 1000))
        call ShowUnit(udg_Dummy_Unit[udg_Dummy_Index], false)
        call PauseUnit(udg_Dummy_Unit[udg_Dummy_Index], true)

still i see craps after missile
 

Attachments

  • 1.jpg
    1.jpg
    196.9 KB · Views: 89
  • 2.jpg
    2.jpg
    198.8 KB · Views: 111
  • Missile3.w3x
    52.4 KB · Views: 48
Level 17
Joined
Nov 13, 2006
Messages
1,814
Bump

got problem with parameters, coz i reached a limit and cant use more parameter for 1 function.

need help with recycler problem what is in previous post, i can do anything but if i dont remove the unit then allways show weird animations or missile going back to start coord.

in map now i guess work the:
-normal missile
-homming (bounceing dont work yet :/)
-vertical/horizontal/vertical+horizontal arc
-falling missile (also work if missile go up)
(exclude fall, then acceleration work)

i need usefull info's about how can i connect it with unit normal attack, if u have patience for teach me about missile system then i am happy :)

the core

JASS:
function Trig_Missile_Timer takes nothing returns nothing
    local integer i = 1
    local real x
    local real y
    local real dx
    local real dy
    local real h1
    local real h2
    local real h3

    loop
        exitwhen i > udg_MS_Index
   
        if udg_MS_End[i] then
            if udg_MS_Homing[i] and udg_MS_BounceLeft[i] > 0 then
                set udg_MS_End[i] = false

                call GroupEnumUnitsInRange(udg_UG, x, y, 600, null)
                loop
                    set udg_unit = FirstOfGroup(udg_UG)
                    exitwhen udg_unit == null or (udg_unit != udg_MS_Homing_Target[i] and IsUnitEnemy(udg_unit, udg_MS_Player[i]))
                    call GroupRemoveUnit(udg_UG, udg_unit)
                endloop
                call DisplayTextToForce( GetPlayersAll(), "|cffffff00" + I2S(udg_MS_BounceLeft[i]) + "|r " + GetUnitName(udg_unit))

                set udg_MS_BounceLeft[i] = udg_MS_BounceLeft[i] - 1

                if udg_unit != null and udg_unit != udg_MS_Homing_Target[i] then
                    set udg_MS_Homing_Target[i] = udg_unit
                else
                    set udg_MS_End[i] = true
                    set udg_MS_BounceLeft[i] = 0

                endif
            else
                call DisplayTextToForce( GetPlayersAll(), "|cffffff00" + R2S(udg_MS_DeathTime[i]) + "|r " )

                set udg_MS_DeathTime[i] = udg_MS_DeathTime[i] - 0.03
                if udg_MS_DeathTime[i] < 0 then
                    call AoeDamage(i, GetUnitX(udg_MS_Unit[i]), GetUnitY(udg_MS_Unit[i]))
                    set i = ReleaseDummy(i)
                endif
            endif
        else

            // here the action
            set x = GetUnitX(udg_MS_Unit[i])
            set y = GetUnitY(udg_MS_Unit[i])
            call MoveLocation(udg_p, x , y)
            set udg_MS_Z[i] = GetLocationZ(udg_p)
            
            if udg_MS_Falling[i] then
             //   if udg_MS_SpeedUp[i] and udg_MS_Accelerate[i] != 0 then
             //       if udg_MS_Accelerate[i] > udg_MS_MinSpeed[i] and udg_MS_MaxSpeed[i] > udg_MS_FallRate[i] then
             //           set udg_MS_FallRate[i] = udg_MS_FallRate[i] + udg_MS_Accelerate[i] / 0.03
             //       elseif udg_MS_Accelerate[i] < 0 and udg_MS_MaxSpeed[i] < udg_MS_FallRate[i] then
             //           set udg_MS_FallRate[i] = udg_MS_FallRate[i] + udg_MS_Accelerate[i] / 0.03
             //       endif
             //   endif
            else
                if udg_MS_SpeedUp[i] and udg_MS_Accelerate[i] != 0 then
                    if udg_MS_Accelerate[i] > udg_MS_MinSpeed[i] and udg_MS_MaxSpeed[i] > udg_MS_Speed[i] then
                        set udg_MS_Speed[i] = udg_MS_Speed[i] + udg_MS_Accelerate[i]
                    elseif udg_MS_Accelerate[i] < 0 and udg_MS_MaxSpeed[i] < udg_MS_Speed[i] then
                        set udg_MS_Speed[i] = udg_MS_Speed[i] + udg_MS_Accelerate[i]
                    endif
                endif
            endif
            set dx = x + 50 * Cos(udg_MS_Angle[i])
            set dy = y + 50 * Sin(udg_MS_Angle[i])
           
            if dx < udg_MapMinX or dx > udg_MapMaxX or dy < udg_MapMinY or dy > udg_MapMaxY then
                set udg_MS_End[i] = true
            endif
            if udg_MS_Knockback[i] then
                if udg_MS_KillTree[i] then
                    set udg_MS_A = i
                    set udg_MS_Rect = Rect(dx - udg_MS_Collision[i], dy - udg_MS_Collision[i], dx + udg_MS_Collision[i], dy + udg_MS_Collision[i])
                    call EnumDestructablesInRect(udg_MS_Rect, null, function DestroyDestructibles)
                    call RemoveRect(udg_MS_Rect)
                endif
                set dx = x + udg_MS_Speed[i] * Cos(udg_MS_Angle[i])
                set dy = y + udg_MS_Speed[i] * Sin(udg_MS_Angle[i])
                call SetUnitPosition (udg_MS_Unit[i], dx, dy)
                set udg_MS_CurDist[i] = udg_MS_CurDist[i] + udg_MS_Speed[i]
                if udg_MS_CurDist[i] > udg_MS_MaxDist[i] then
                    set udg_MS_End[i] = true
                endif
            elseif udg_MS_Jump[i] then
                set udg_MS_Height[i] = GetUnitFlyHeight(udg_MS_Unit[i]) - udg_MS_Z[i] + udg_MS_StartZ[i]
                if GetUnitFlyHeight(udg_MS_Unit[i]) < udg_MS_Speed[i] and udg_MS_CurDist[i] > udg_MS_Speed[i] then
                    set udg_MS_End[i] = true
                else
                    set udg_MS_CurDist[i] = udg_MS_CurDist[i] + udg_MS_Speed[i]
                    set udg_MS_Height[i] = ( 4 * udg_MS_MaxHeight[i] / udg_MS_MaxDist[i] ) * ( udg_MS_MaxDist[i] - udg_MS_CurDist[i] ) * ( udg_MS_CurDist[i] / udg_MS_MaxDist[i] )
                    call SetUnitX (udg_MS_Unit[i], x + udg_MS_Speed[i] * Cos(udg_MS_Angle[i]))
                    call SetUnitY (udg_MS_Unit[i], y + udg_MS_Speed[i] * Sin(udg_MS_Angle[i]))
                    call SetUnitFlyHeight( udg_MS_Unit[i], udg_MS_Height[i] , 0.00 )
                endif
            else
                if udg_MS_Exp_Timer[i] != -1 then
                    set udg_MS_Exp_Timer[i] = udg_MS_Exp_Timer[i] - 0.03
                    if udg_MS_Exp_Timer[i] < 0.2 then
                        set udg_MS_End[i] = true
                    endif
                endif


//call DisplayTextToForce( GetPlayersAll(), "|cffffff00====" + R2S(udg_MS_Height[i]) + "|r " + "|cffffff00" + R2S(GetUnitFlyHeight(udg_MS_Homing_Target[i])) + "|r " )

                  if (((udg_MS_Height[i] + udg_MS_StartZ[i] - udg_MS_Z[i]) < 30 and udg_MS_CurDist[i] > udg_MS_MaxDist[i] / 2) or (udg_MS_CurDist[i] > udg_MS_MaxDist[i])) and not udg_MS_Homing[i] then
                        set udg_MS_End[i] = true
                    else
                        set udg_TR2 = Cos(udg_MS_Angle[i])
                        set udg_TR3 = Sin(udg_MS_Angle[i])
                        set udg_MS_CurDist[i] = udg_MS_CurDist[i] + udg_MS_Speed[i]
  
//---------------------------------------------------------------------------------------
//                               Set the damage
//--------------------------------------------------------------------------------------- 
                      
                        if udg_MS_Dmg_On[i] then
                            call CollDamage(i, x, y)
                        endif

//---------------------------------------------------------------------------------------
//                               Set the unitXY and unit facing angle
//--------------------------------------------------------------------------------------- 
                      
                         if udg_MS_Homing[i] then
                            if not IsUnitType(udg_MS_Homing_Target[i], UNIT_TYPE_DEAD) then
                                set dx = GetUnitX(udg_MS_Homing_Target[i]) - udg_MS_X[i]
                                set dy = GetUnitY(udg_MS_Homing_Target[i]) - udg_MS_Y[i]
 
                                set udg_MS_CurDist[i] = SquareRoot(dx * dx + dy * dy)
                                set udg_MS_Angle[i] = Atan2(dy, dx)
                                set udg_MS_X[i] = x + udg_MS_Speed[i] * Cos(udg_MS_Angle[i])
                                set udg_MS_Y[i] = y + udg_MS_Speed[i] * Sin(udg_MS_Angle[i])
                                call SetUnitX(udg_MS_Unit[i], udg_MS_X[i])
                                call SetUnitY(udg_MS_Unit[i], udg_MS_Y[i])
                                call SetUnitFacing(udg_MS_Unit[i], udg_MS_Angle[i] * bj_RADTODEG)
       
                   
                                if udg_MS_CurDist[i] < 50 then
                                    if udg_MS_SFX_Hit[i] != null then
                                        call DestroyEffect(AddSpecialEffectTarget(udg_MS_SFX_Hit[i], udg_MS_Homing_Target[i], "chest"))
                                    endif
                                    set udg_DamageEventType = udg_MS_Dmg_Type[i]
                                    call UnitDamageTarget(udg_MS_Launcher[i], udg_MS_Homing_Target[i], udg_MS_Dmg[i], true, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, null)
                                    set udg_MS_BounceLeft[i] = udg_MS_BounceLeft[i] - 1
                                    set udg_MS_End[i] = true
                                endif

                            else
                                set udg_MS_End[i] = true
                            endif
                        elseif udg_MS_Arc[i] then
 
                            set udg_TR1 = GetArc (udg_MS_CurDist[i], udg_MS_MaxDist[i], udg_MS_ArcDist[i])
                            set x = udg_MS_X[i] + udg_MS_Speed[i] * udg_TR2
                            set y = udg_MS_Y[i] + udg_MS_Speed[i] * udg_TR3
                            set h3 = GetArc ((udg_MS_CurDist[i] - udg_MS_Speed[i]), udg_MS_MaxDist[i], udg_MS_ArcDist[i])
                            set h1 = udg_MS_X[i]
                            set h2 = udg_MS_Y[i]

                            set h1 = h1 + h3 * Cos(udg_MS_ArcAngle[i])
                            set h2 = h2 + h3 * Sin(udg_MS_ArcAngle[i])
                            set x = x + udg_TR1 * Cos(udg_MS_ArcAngle[i])
                            set y = y + udg_TR1 * Sin(udg_MS_ArcAngle[i])
                            call SetUnitX(udg_MS_Unit[i], x)
                            call SetUnitY(udg_MS_Unit[i], y)
                            set udg_MS_X[i] = udg_MS_X[i] + udg_MS_Speed[i] * udg_TR2
                            set udg_MS_Y[i] = udg_MS_Y[i] + udg_MS_Speed[i] * udg_TR3
                            call SetUnitFacing(udg_MS_Unit[i], bj_RADTODEG * Atan2(y - h2, x - h1))
                            
                        else

                            set udg_MS_X[i] = x + udg_MS_Speed[i] * udg_TR2
                            set udg_MS_Y[i] = y + udg_MS_Speed[i] * udg_TR3
                            call SetUnitFacing(udg_MS_Unit[i], udg_MS_Angle[i] * bj_RADTODEG)
                            call SetUnitX(udg_MS_Unit[i], udg_MS_X[i])
                            call SetUnitY(udg_MS_Unit[i], udg_MS_Y[i])
                        endif

//---------------------------------------------------------------------------------------
//                               Set the flying height and z-angle
//---------------------------------------------------------------------------------------                       
                        if udg_MS_Falling[i] then
                            set udg_MS_Height[i] = udg_MS_Height[i] + udg_MS_FallRate[i]
                            set h3 =  bj_RADTODEG * Atan2(udg_MS_TargetZ[i]-udg_MS_StartZ[i], udg_MS_MaxDist[i])
                            call SetUnitFlyHeight( udg_MS_Unit[i], udg_MS_Height[i] , 0.00 )

                            if udg_MS_FallRate[i] < 0 then
                                if udg_MS_Height[i] < udg_MS_TargetZ[i] then
                                    set udg_MS_End[i] = true
                                endif

                            else
                                if udg_MS_TargetZ[i] < udg_MS_Height[i] then
                                    set udg_MS_End[i] = true
                                endif
                            endif
                                call SetUnitAnimationByIndex(udg_MS_Unit[i], R2I(h3+90) )
                        elseif udg_MS_Parabola[i] then
                            set udg_MS_Height[i] = GetArc (udg_MS_CurDist[i], udg_MS_MaxDist[i], udg_MS_MaxHeight[i])
                            call SetUnitFlyHeight( udg_MS_Unit[i], udg_MS_Height[i] - udg_MS_Z[i] + udg_MS_StartZ[i], 0.00 )
                            set h1 = GetArc ((udg_MS_CurDist[i] - udg_MS_Speed[i]), udg_MS_MaxDist[i], udg_MS_MaxHeight[i])
                            set h2 = GetArc (udg_MS_CurDist[i], udg_MS_MaxDist[i], udg_MS_MaxHeight[i])
                            set h3 = bj_RADTODEG * Atan2(h2 - h1, udg_MS_Speed[i])
                            call SetUnitAnimationByIndex(udg_MS_Unit[i], R2I(h3 + 90) )
                        elseif udg_MS_Homing[i] then
                            set udg_MS_Height[i] = udg_MS_Height[i] + (GetUnitFlyHeight(udg_MS_Homing_Target[i]) - udg_MS_Height[i]) / ( udg_MS_CurDist[i] / udg_MS_Speed[i])
                            call SetUnitFlyHeight( udg_MS_Unit[i], udg_MS_Height[i] - udg_MS_Z[i] + udg_MS_StartZ[i], 0.00 )
                        else
                            call SetUnitFlyHeight( udg_MS_Unit[i], udg_MS_StartZ[i] - udg_MS_Z[i], 0.00 )
                            if udg_MS_CurDist[i] > udg_MS_MaxDist[i] then
                                set udg_MS_DeathTime[i] = 0
                                set udg_MS_End[i] = true
                            endif
                        endif
//---------------------------------------------------------------------------------------
//                               vertical settings end
//---------------------------------------------------------------------------------------                       
 
                    endif
            endif
        endif

        set i = i + 1
    endloop

endfunction

//===========================================================================
function InitTrig_Missile_Timer_Core takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterTimerEvent( t, 0.03, true)
    call TriggerAddAction( t, function Trig_Missile_Timer )
endfunction
 

Attachments

  • Missile6.w3x
    59.9 KB · Views: 74
Status
Not open for further replies.
Top