• 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.

[JASS] Missile Air Stabilization

Status
Not open for further replies.
Level 11
Joined
Aug 25, 2006
Messages
971
I'm making a missile system for a FPS I'm working on. It uses RTC from THW's project section, so if you'd like to test my map your going to need that.

Ok here is my problem. My missiles are 3d. Funny enough, physics in warcraft aren't. I'm trying to make it so when you fire a projectile over a wall, the height stays constant. It doesn't bump over the wall.

JASS:
    function Chess_Game_Forward takes nothing returns nothing
    local Missile Star = LL_First_Missile
    local unit u
    local boolean DestroyS = false
    local integer Je
    local real RelativeHeight
    local real CurrenZ
    local Weapon Na
        loop
        exitwhen Star == -1
            set DestroyS = false
            if Star.IsDead == false then
                    set Star.CurX = Star.CurX + Star.AddX 
                    set Star.CurY = Star.CurY + Star.AddY
                    set Star.CurZ = Star.CurZ + Star.AddZ
                call SetUnitX(Star.Mis,Star.CurX)
                call SetUnitY(Star.Mis,Star.CurY)
                call SetUnitFlyHeight(Star.Mis,Star.CurZ,0)
                //Begin 3d terrain collisions
                set CurrenZ = GetUnitZ(Star.Mis)
                set RelativeHeight =  Star.CurZ + CurrenZ
                //Star.GroundHeight
                if CurrenZ > Star.CurZ then
                    set DestroyS = true
                else
                    if not (Star.GroundHeight == CurrenZ) then //Sloping or rising ground! Attempt to remain constant height
                        set Star.CurZ = Star.CurZ + Star.GroundHeight - CurrenZ
                        call BJDebugMsg("Ground = " + R2S(CurrenZ) + " Air = " + R2S(Star.CurZ))
                        //call BJDebugMsg("Compensation = " + R2S(Star.GroundHeight - CurrenZ))
                        call BJDebugMsg("Current Height = " + R2S(RelativeHeight) + " Compensation = " + R2S(Star.GroundHeight - CurrenZ) + " Normal Gain Per Cycle = " + R2S(Star.AddZ))
                        call SetUnitFlyHeight(Star.Mis,Star.CurZ,0)
                    endif
                endif
                set Star.GroundHeight = CurrenZ
                
            endif
            if (Star.IsDead == false) and (DestroyS == false) then
                set Star.CurDist = Star.CurDist + Star.Sped
                if Star.CurDist > MAXDIST then
                    set DestroyS = true
                endif
            endif
//            if Star.IsDead == false then
//                if (GetUnitZ(Star.Mis) + HEIGHT_THRESHOLD < Star.StartZ) or (GetUnitZ(Star.Mis) - HEIGHT_THRESHOLD > Star.StartZ) then
//                    set DestroyS = true
//                    //call BJDebugMsg("Actual = " + R2S(GetUnitZ(Star.Mis) + HEIGHT_THRESHOLD) + " Current = " + R2S(Star.CurZ))
//                endif
            //endif
            if (Star.IsDead == false) and (DestroyS == false) then //If I use an and statement it will still evaluate the second function if the first is false! Thats a waste of comp power
                if EnemyContact(Star.CurX,Star.CurY,COLLISION_RADIUS,Star.Firer) then //x_Violator
                    set Na = Star.Wep
                    set DestroyS = true
                    call DamageUnitByTypes(Star.Mis,x_Violator,Na.Damage,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_UNIVERSAL)
                endif
            endif 
            if (Star.IsDead == false) and (DestroyS == true) then
                set Star.IsDead = true
                call DestroyEffect(Star.Mdlx)
            endif
            if Star.IsDead == true then
                set Star.FExtinme = Star.FExtinme - TimerCycle
                if Star.FExtinme <= 0 then
                    call RemoveUnit(Star.Mis)
                    set Je = Star.NextStruct
                    call MissileDestroy(Star)
                    set Star = Je
                else
                    set Star = Star.NextStruct
                endif
            else
                set Star = Star.NextStruct
            endif
        endloop
        set u = null    
    endfunction
Thats the main loop responsible for projectile movement.
Look for //Begin 3d terrain collisions. Thats where I attempt to compensate for height changes. Unfortunetly it doesn't. According to the debug message, the numbers are staying constant, however the visual says differently.

I also attached the map if you'd like to test it. When you start the game just turn around (using mouse) and hit 'v' a couple of times at the wall. (While looking over it) The keys 'wasd' control movement.

So far the system is not done yet, so please don't try to use it. Most of its done, but expect several total restructures of the missile system before its done. (Its kind of sluggish right now, my comp maxed at about 250 projectiles. Then it got slow)
BTW, hindyhat, I sent you a pm about this yesterday. Its just theres so many factors to creating a working missile system I decided to post a thread.
 

Attachments

  • HpSP2.w3x
    1.5 MB · Views: 43
Last edited:
Level 11
Joined
Aug 25, 2006
Messages
971
Hey guys, I know that custom natives are mysterious and everything, but I really need your help. Just download it, open my map with it, save it, and hit the test button. I really need help. This is such an aggravating problem.

If you have any time hindyhat I'd really appreciate a push in the right direction.

P.S. Sorry for the double post.
 
Level 11
Joined
Aug 25, 2006
Messages
971
You don't know how much I thank you for helping me with this stupid problem. Nothing I do seems to make it better. According to the numbers I get, everything works fine. The visual however does not look fine. Any help at all would be appreciated.
 
Level 20
Joined
Apr 22, 2007
Messages
1,960
Okay, here's what I do with my Entity Engine:

JASS:
function Loop takes nothing returns nothing
    local real z
    local Entity e=GetTheEntitySomehow()
//
    // Refreshing Velocity based on Acceleration
    set e.Velocityx=e.Velocityx+e.Accelx
    set e.Velocityy=e.Velocityy+e.Accely
    set e.Velocityz=e.Velocityz+e.Accelz
//
    call MoveLocation(TempLoc,e.Positionx+e.Velocityx,e.Positiony+e.Velocityy) // Preparing for GetLocationZ()
    set z=GetLocationZ(TempLoc) // Getting the terrain height at Position+Velocity for future use
//
    //This is the condition for the entity colliding with the ground/cliff.
    if e.Positionz+e.Velocityz-e.Data.Radius<=z then
        // Do whatever you do during ground collisions
    endif
//
    // Now comes Entity collisions, but I'll skip that.
//
    //Updating the Position based on Velocity.
    set e.Positionx=e.Positionx+e.Velocityx
    set e.Positiony=e.Positiony+e.Velocityy
    set e.Positionz=e.Positionz+e.Velocityz
//
    // Finally setting the position/height
    call SetUnitX(e.Unit,e.Positionx)
    call SetUnitY(e.Unit,e.Positiony)
    call SetUnitFlyHeight(e.Unit,e.Positionz-z,0.)
endfunction
I don't know how you do it, but you should do it that way.
 
Level 11
Joined
Aug 25, 2006
Messages
971
Ok so I changed my wall/floor detection system to this:
JASS:
                set CurrenZ = GetLocZ(Star.CurX + Star.AddX,Star.CurY + Star.AddY)
                if Star.CurZ + Star.AddZ - COLLISION_RADIUS <= CurrenZ then
                    set DestroyS = true
                    call BJDebugMsg("Dead! = " + R2S(Star.CurZ - COLLISION_RADIUS) + " x " + R2S(CurrenZ))
                endif
                if not DestroyS then
                    set Star.CurX = Star.CurX + Star.AddX 
                    set Star.CurY = Star.CurY + Star.AddY
                    set Star.CurZ = Star.CurZ + Star.AddZ
                    call SetUnitX(Star.Mis,Star.CurX)
                    call SetUnitY(Star.Mis,Star.CurY)
                    call SetUnitFlyHeight(Star.Mis,Star.CurZ - CurrenZ,0)
                endif
The units still 'bump' over cliffs. Should they not be 'flying' units?
I looked at your map and you set their movment type to 'none' which doesn't seem to fly.

As I further looked I found something a little unusual.
JASS:
            call UnitAddAbility(e.Unit,'Amrf')
            call UnitRemoveAbility(e.Unit,'Amrf')
When I added that to my code, my problems magically dissapeared. Thanks so much Hindyhat!
 
Level 11
Joined
Aug 25, 2006
Messages
971
Somehow it makes the units not affected by what ground is under them? I really don't know. In vexorian's system it says something about a glitch with crow form. All I know is that it works!
 
Status
Not open for further replies.
Top