• 🏆 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] Can this code be further optimized?

Status
Not open for further replies.
Level 9
Joined
Mar 6, 2012
Messages
64
Warcraft 3 modding community led me to take Computer Science course and I am really thankful for it. I was like 11 or 12 when I created my first spell and posted it on here (dont look it up, its really bad) and now I'm back for reforged.

I'm using Jass now and created a physics and missile system for my map and I'm wondering if my code can further be optimized

JASS:
struct physics
    unit Target
    real dist=0
    real vel=0
    real friction=0
    real velZ=0
    real z=0
    real sin=0
    real cos=0
    boolean affGrav =true
    //string animation
    //string effect
endstruct

struct effectMissile
    effect model
    real x
    real y
    real z = 60
    real tx
    real ty
    real tz
    real angle
    real dis
    real vel
    real turnrate = 1
    //damage
    unit owner
    unit target
    real damage
    damagetype dmgtype
    ////for Altair, melee = 0; defend = 1; missile = 2
    integer state
    // if missile deals aoe damage
    real HitZ = 60
    boolean areaEffect = false
    boolean homing = true
    //first unit hit = FUHit
    boolean FUHit
endstruct

struct Altair
    unit caster
    //swords that will encircle/defend Altair
    effectMissile array sword[20]
    integer swordCount
endstruct

globals
    timer pArTimer = CreateTimer()
    physics array pAr
    Altair array altair
    effectMissile array missile
    integer misTotal = 0
    integer altTotal = 0
    integer pArTotal = 0
    constant real knockbackFricPerc = 0.0
    constant real knockbackFricReal = 0.0
    constant real TimerInterval = 0.0165
    constant real gravity = 9.8*200
endglobals

function Physics takes integer i, physics p returns nothing
    local real nextZ
    local real x
    local real y
    //knockback
       set x = GetUnitX(p.Target) +  p.vel* p.cos
    set y = GetUnitY(p.Target) +  p.vel* p.sin
    if p.dist > 0 and x>GetRectMinX(GetPlayableMapRect()) and x<GetRectMaxX(GetPlayableMapRect()) and y>GetRectMinY(GetPlayableMapRect()) and y<GetRectMaxY(GetPlayableMapRect()) then
        call SetUnitX(p.Target,x)
        call SetUnitY(p.Target,y)
    endif
    set p.dist = p.dist - p.vel
    set p.vel = p.vel - (p.vel*p.friction)
    if p.vel <= 2 then
        set p.vel = 2
    endif

    //set final flying height
    //set p.z = GetUnitFlyHeight(p.Target)+BlzGetLocalUnitZ(p.Target)
    //knockup
    set nextZ = p.z + p.velZ*TimerInterval
    if (nextZ - BlzGetLocalUnitZ(p.Target)) >0 then
        call UnitAddAbilityBJ( 'Amrf', p.Target )
        call SetUnitFlyHeight( p.Target , nextZ-BlzGetLocalUnitZ(p.Target), 999999.00 )
        call UnitRemoveAbilityBJ( 'Amrf', p.Target )
        if p.affGrav == true then
            set p.velZ = p.velZ - gravity*TimerInterval
        endif
        set p.z = nextZ
    else
        set p.velZ = 0
        set p.z = GetUnitFlyHeight(p.Target)+BlzGetLocalUnitZ(p.Target)
    endif
    //finish
    if (nextZ-BlzGetLocalUnitZ(p.Target)) <= 0 and p.dist <= 0 then
        set pAr[i] = pAr[pArTotal - 1]
        set pArTotal = pArTotal - 1
        call p.destroy()
    endif
endfunction

function MissileSystem takes integer i, effectMissile m returns nothing
    local real angle = m.angle + 360
    local real angleto
    local real pitch = RAbsBJ(Atan2((m.tz-m.z),m.dis))
    set m.x = m.x + Cos(angle * bj_DEGTORAD)*m.vel
    set m.y = m.y + Sin(angle * bj_DEGTORAD)*m.vel
    if m.homing then
        set m.dis = SquareRoot(((m.tx-m.x)*(m.tx-m.x))+((m.ty-m.y)*(m.ty-m.y)))
    endif
    set m.z = m.z + ((m.tz-m.z)/((m.dis*0.1)+1))
    if m.z <= 0 then
        set m.z = 60
    endif
    set angleto = Atan2BJ((m.ty-m.y),(m.tx-m.x))
   
    ///////////////calculate angle ////////////////////////////
    if not ((m.angle >0 and angleto>0)or(m.angle <0 and angleto<0)) then
        if angleto<0 then
            if RAbsBJ(m.angle -(angleto+360))< RAbsBJ(m.angle - angleto) then
                if RAbsBJ(m.angle -(angleto+360)) >= m.turnrate then
                set m.angle =m.angle + m.turnrate
                else
                set m.angle = angleto
                endif
            else
                if RAbsBJ(m.angle - angleto) >= m.turnrate then
                set m.angle =m.angle - m.turnrate
                else
                set m.angle = angleto
                endif
            endif
        else
        if RAbsBJ(angleto-(m.angle+360))< RAbsBJ(angleto - m.angle) then
            if RAbsBJ(angleto-(m.angle+360)) >= m.turnrate then
            set m.angle =m.angle - m.turnrate
            else
            set m.angle = angleto
            endif
        else
            if RAbsBJ(angleto-m.angle) >= m.turnrate then
            set m.angle =m.angle + m.turnrate
            else
            set m.angle = angleto
            endif
        endif
        endif
    else
        if RAbsBJ(m.angle-angleto)>= m.turnrate then
        if m.angle<angleto then
            set m.angle = m.angle + m.turnrate
        else
            set m.angle = m.angle - m.turnrate
        endif
        else
            set m.angle = angleto
        endif
    endif
   
    if m.angle > 180 then
        set m.angle = m.angle -360
    else
    if m.angle <-180 then
        set m.angle = m.angle +360
    endif
    endif
    //////////////////////////////////////////////
   
       //call DisplayTextToForce( GetPlayersAll(), R2S(m.y) )
    //move missile
    call BlzSetSpecialEffectOrientation(m.model,0,pitch,m.angle* bj_DEGTORAD)
    call BlzSetSpecialEffectPosition(m.model,m.x,m.y,m.z)
    //finish
    ///damage
    if m.areaEffect then
        if m.dis<=0 then
            set missile[i] = missile[misTotal - 1]
            set misTotal = misTotal - 1
            call DestroyEffect(m.model)
            call m.destroy()
        endif
        set m.tx = GetUnitX(m.target)
        set m.ty = GetUnitY(m.target)
        set m.tz = GetUnitFlyHeight(m.target)+BlzGetLocalUnitZ(m.target)
    else
    if m.homing then
        if m.dis<=50 then
            set missile[i] = missile[misTotal - 1]
            set misTotal = misTotal - 1
            call DestroyEffect(m.model)
            call m.destroy()
        else
            set m.tx = GetUnitX(m.target)
            set m.ty = GetUnitY(m.target)
            set m.tz = GetUnitFlyHeight(m.target)+BlzGetLocalUnitZ(m.target)
        endif
    endif
    endif   
endfunction

function AltairSystem takes integer i, Altair a returns nothing
   
endfunction

function Loop takes nothing returns nothing
    //declare locals here
    local physics p
    local effectMissile m
    local Altair a
    ////Physics
    local integer i = 0
    loop
        exitwhen i>=pArTotal
        set p = pAr[i]
        call Physics(i,p)
        set i = i+1
    endloop
    ////EndPhysics
    ////Missile
    set i = 0
    loop
        exitwhen i >= misTotal
        set m = missile[i]
        call MissileSystem(i,m)
        set i = i+1
    endloop
    ////EndMissile
    ////Altair
    set i = 0
    loop
        exitwhen i>=altTotal
        set a = altair[i]
        call AltairSystem(i,a)
        set i = i+1
    endloop
    ///EndAltair
    if pArTotal == 0 and misTotal == 0 then
        call PauseTimer(pArTimer)
    endif
endfunction

/////////////////////////////////////////////////////////////////////////////////
function CheckUnitPhysics takes unit Target returns integer
    local integer i = 0
    local integer r = -1
    loop
        exitwhen i >= pArTotal
        if pAr[i].Target == Target then
            set r = i
        endif
        set i = i + 1
    endloop
    return r
endfunction

function ApplyForceDis takes unit target, real dist, real angle returns nothing
       
endfunction

function ApplyForceDisFric takes unit target, real dist, real vel, real angle, real fric returns nothing
    local physics p = physics.create()
    local real initZ = GetUnitFlyHeight(target)+BlzGetLocalUnitZ(target)

    local integer r = CheckUnitPhysics(target)
    if r == -1 then
        //setthing for p
        set p.Target = target
        set p.vel = vel
        set p.friction = fric
        set p.dist = dist
        set p.sin = Sin(angle * bj_DEGTORAD)
        set p.cos = Cos(angle * bj_DEGTORAD)
        set p.z = initZ
        //startphysics
        if pArTotal == 0 and misTotal == 0 then
        call TimerStart(pArTimer,TimerInterval,true,function Loop)
        endif
        set pAr[pArTotal] = p
        set pArTotal = pArTotal + 1
    else
        set pAr[r].vel = vel
        set pAr[r].friction = fric
        set pAr[r].dist = dist
        set pAr[r].sin = Sin(angle * bj_DEGTORAD)
        set pAr[r].cos = Cos(angle * bj_DEGTORAD)
        set pAr[r].z = initZ
    endif
endfunction


function ApplyForceZheightAdd takes unit target, real maxheight returns nothing
    local physics p = physics.create()
    local real initZ = GetUnitFlyHeight(target)+BlzGetLocalUnitZ(target)
    local real initvel =  SquareRoot(2*gravity*maxheight)

    local integer r = CheckUnitPhysics(target)
    if r == -1 then
        //setthing for p
        set p.Target = target
        set p.velZ = initvel
        set p.z = initZ
        //startphysics
        if pArTotal == 0 and misTotal == 0 then
        call TimerStart(pArTimer,TimerInterval,true,function Loop)
        endif
        set pAr[pArTotal] = p
        set pArTotal = pArTotal + 1
    else
        call DisplayTextToForce( GetPlayersAll(), I2S(r) )
        set pAr[r].velZ = initvel
        set pAr[r].z = initZ
    endif
endfunction

function ApplyForceZheight takes unit target, real maxheight returns nothing
    local physics p = physics.create()
    local real initZ = GetUnitFlyHeight(target)+BlzGetLocalUnitZ(target)
    local real initvel =  SquareRoot(2*gravity*(maxheight-initZ))
   
    local integer r = CheckUnitPhysics(target)
    if r == -1 then
        //setthing for p
        set p.Target = target
        set p.velZ = initvel
        set p.z = initZ
        //startphysics
        if pArTotal == 0 and misTotal == 0 then
        call TimerStart(pArTimer,TimerInterval,true,function Loop)
        endif
        set pAr[pArTotal] = p
        set pArTotal = pArTotal + 1
    else
        call DisplayTextToForce( GetPlayersAll(), "found" )
        set pAr[r].velZ = initvel
        set pAr[r].z = initZ
    endif
   
endfunction
/////////////////////////////////////////////////////////////////////////////////

function AltairSwordCircle takes unit caster returns nothing
endfunction

function AltairSwordAdd takes unit caster returns nothing
endfunction


function FireMissile takes effectMissile m returns nothing
    if pArTotal == 0 and misTotal == 0 then
    call TimerStart(pArTimer,TimerInterval,true,function Loop)
    endif
    set missile[misTotal] = m
    set misTotal = misTotal + 1
endfunction

function CreateMissileHomingTR takes unit owner, unit target, string model, location loc, real angle, real velocity, real turnrate returns nothing
    local effectMissile m = effectMissile.create()
    call AddSpecialEffectLocBJ( loc, model )
    set m.model = GetLastCreatedEffectBJ()
    set m.x = GetLocationX(loc)
    set m.y = GetLocationY(loc)
    set m.z = GetUnitFlyHeight(owner)+BlzGetLocalUnitZ(owner)+60
    call RemoveLocation(loc)
    set m.owner = owner
    set m.target = target
    set m.turnrate = turnrate*TimerInterval
    set m.angle = angle
    set m.vel = velocity
    set m.homing = true
   
    set m.tx = GetUnitX(m.target)
    set m.ty = GetUnitY(m.target)
    set m.tz = GetUnitFlyHeight(m.target)+BlzGetLocalUnitZ(m.target)
    call FireMissile(m)
endfunction

As you can see, my physics system is somehow similar to Quillnez rigid body physics except that it doesn't work in upward slope (For balance purposes)
 
Status
Not open for further replies.
Top