• 🏆 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] Keep Unit's height same

Status
Not open for further replies.
Level 11
Joined
Sep 12, 2008
Messages
657
hey.. some of you might have experienced that whether you move a flying unit,
with height, you notice that whether it goes up a mountain, down a mountain,
a random terrain, or etc, it goes down/up with the terrain.
so that flying unit's in warcraft wont crush,

but is there are a good way to avoid it?

reason that i dont do:

JASS:
call SetUnitFlyHeight(Unit, GetUnitFlyHight - LocationZ, 0)

is that because that wont do.
if a unit goes down in terrain, it gets negative values and goes too much up.
if a unit goes up in terrain, it gets positive values,
but some times the positive value is less then the current unit height,
so it still brings me the negative value, and goes up/down.

is there any good way to do this.. i've tried allmost nothing, but gave up and started working on efficency/arc rather then this part of the code ^^

JASS:
        function GetUnitZ takes unit u returns real
            set x = GetUnitX(u)
            set y = GetUnitY(u)
            call MoveLocation(l, x, y)
                return GetLocationZ(l)
        endfunction
        
        function GetCoordinateZ takes real x, real y returns real
            call MoveLocation(l, x, y)
                return GetLocationZ(l)
        endfunction

this is how i got UnitZ, and coordinateZ, with 1 global loc that i reuse instead creating/destroying.
oh yeah x and y are globals aswell.


thanks in advance.
 
Level 6
Joined
Nov 3, 2008
Messages
117
What you want to do only works with units that have been made flying with the Raven Form hack. That means you have to add this to a Unit:
JASS:
function AddFlyHack takes unit u returns nothing
   call UnitAddAbility(u,'Amrf')
   call UnitRemoveAbility(u,'Amrf')
endfunction

With that and the use of this: call SetUnitFlyHeight(Unit, GetUnitFlyHight - LocationZ, 0)
It should normally work.
 
Level 11
Joined
Sep 12, 2008
Messages
657
.. you seriusly didnt read right? ;/
i sayd call SetUnitFlyHeight(Unit, GetUnitFlyHight - LocationZ, 0)

bugs heavly ( it doesnt support all heights/terrain loc z, and sometimes it goes negative)
, and i know how to use raven form bug..
 
Level 6
Joined
Nov 3, 2008
Messages
117
OK! one last thing. You want to move a flying Unit via triggers. So you know its current position and the position it will be after the next execution. Since GetUnitFlyHeight only returns the difference between the current Terrain height and the Units real flying height this won't work for sure. And that is why you get negative flying heights. But as you know the 2 positions just do this:
JASS:
function UpdateUnitHeight takes unit whichUnit, newX, newY returns nothing
    local real zfactor=GetLocationZ(newX,newY)-GetLocationZ(GetUnitX(whichUnit),GetUnitY(whichUnit))
    call SetUnitX(whichUnit,newX)
    call SetUnitY(whichUnit,newY)
    call SetUnitFlyHeight(whichUnit,GetUnitFlyHeight(whichUnit)-zfactor,0)
endfunction

Ofcourse you will get negative values sometimes aswell, but that only occurs when your unit hits the ground. But this will make your unit hit hills, which are higher than your units default flying height. But makes it fly over deep holes, valleys or abyss.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,468
I am going to torment you until you start indenting your code using the logical standard. If anything, the "return" statement aught to be unindented, but even that is a retarded way to do it (found commonly on wc3c.net).

JASS:
function GetUnitZ takes unit u returns real
    call MoveLocation(l, GetUnitX(u), GetUnitY(u))
    return GetLocationZ(l) + GetUnitFlyHeight(u)
endfunction

function GetCoordinateZ takes real x, real y returns real
    call MoveLocation(l, x, y)
    return GetLocationZ(l)
endfunction
 
Level 11
Joined
Sep 12, 2008
Messages
657
lol.. thats smart xD
anyways.. ill do that ;p

And another question.. is there a easy way to deflect missle from cliff/mountain?
i know how to check if its a cliff or a mountain,
but i cant find the way to caculate deflection angle..
its easy if i want it to deflect from a unit, (theres a code in TheHelper), but i cant find thru terrain..

thanks in advance =]
 
Level 11
Joined
Sep 12, 2008
Messages
657
well.. actually im making a projectile system..
and yeah, i saw you made a addon for berb's system =].

my system has many possibilities.. and the last 4 options are this:
1. deflect from units
2. deflect from terrain
3. bounce from units
4. bounce from terrain

deflect from units is easy.. bounce is.. ehh hard ;p

deflect from terrain is another problem.. cuz i have no idea how to find angle..
 
Level 19
Joined
Feb 4, 2009
Messages
1,313
you can get the terrain height with GetLocationZ
if you get the height at some different points around the impact area you can create a plane
and the angle of impact is equal to the angle the missile will fly back
BRDF_Diagram.png
 
Last edited:
Level 19
Joined
Feb 4, 2009
Messages
1,313
since you like JASS I made you a map with some JASS code so you have it easier to understand
it shows deflection of a missile on a line
you just have to expand it from 2d to 3d

  • Ini
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Custom script: set udg_lightning[0] = AddLightning("DRAM", true, 0, 0, 0, 0)
      • Custom script: set udg_lightning[1] = AddLightning("DRAM", true, 0, 0, 0, 0)
      • Custom script: set udg_lightning[2] = AddLightning("DRAL", true, 0, 0, 0, 0)
      • Set u[0] = Rifleman 0003 <gen>
      • Set u[1] = Footman 0006 <gen>
      • Set u[2] = Knight 0005 <gen>
      • Set u[3] = Mortar Team 0008 <gen>
      • Unit - Turn collision for u[0] Off
      • Unit - Turn collision for u[1] Off
      • Unit - Turn collision for u[2] Off
      • Unit - Turn collision for u[3] Off
JASS:
function deflect takes nothing returns nothing
    //Position of missile
    local real x0 = GetUnitX(udg_u[0])
    local real y0 = GetUnitY(udg_u[0])

    //Position of terrain
    local real x1 = GetUnitX(udg_u[1])
    local real y1 = GetUnitY(udg_u[1])
    local real x2 = GetUnitX(udg_u[2])
    local real y2 = GetUnitY(udg_u[2])

    //Point of impact
    local real x3 = (x1+x2)/2
    local real y3 = (y1+y2)/2

    //Get distance between collision point and missile
    local real distance = SquareRoot((x0-x3)*(x0-x3)+(y0-y3)*(y0-y3))

    //Angle from missile to collision point
    local real missile_angle = Atan2(y0-y3, x0-x3)

    //Angle from terrain point to another
    local real terrain_angle = Atan2(y2-y1, x2-x1)

    //Calculate deflect angle
    local real deflect_angle = 2 * terrain_angle + 3.14 - missile_angle

    //Calculate deflected missile position
    local real x4 = x3 + distance * Cos(deflect_angle)
    local real y4 = y3 + distance * Sin(deflect_angle)
    call SetUnitX(udg_u[3], x4)
    call SetUnitY(udg_u[3], y4)

    //Display stuff
    call ClearTextMessagesBJ(GetPlayersAll())
    call BJDebugMsg("Missile angle: " + R2S(missile_angle*bj_RADTODEG))
    call BJDebugMsg("Terrain angle: " + R2S(terrain_angle*bj_RADTODEG))
    call BJDebugMsg("Deflect angle: " + R2S(deflect_angle*bj_RADTODEG))

    call MoveLightning(udg_lightning[0], true, x3, y3, x0, y0)
    call MoveLightning(udg_lightning[1], true, x4, y4, x3, y3)
    call MoveLightning(udg_lightning[2], true, x1, y1, x2, y2)
endfunction

//===========================================================================
function InitTrig_Deflect takes nothing returns nothing
    set gg_trg_Deflect = CreateTrigger()
    call TriggerRegisterTimerEventPeriodic(gg_trg_Deflect, 0.03)
    call TriggerAddAction(gg_trg_Deflect, function deflect)
endfunction
edit:
calculations based on the attached picture (actually I had it on a piece of paper but I don't have a scanner so I drew it again :p)
90784d1286749828-keep-units-height-same-deflect.jpg
 

Attachments

  • Deflect.w3x
    13.8 KB · Views: 53
  • Deflect.jpg
    Deflect.jpg
    97.1 KB · Views: 155
Last edited:
Level 11
Joined
Sep 12, 2008
Messages
657
i need 4 reals for that =[ dam.. i hate using stuff that require many stuff as parabolic, etc..
but tell me if i got it correctly:
1 unit is the missle, (x0, y0)
another x/y is just another angle, while you used unit[3] to demonsrate.
another 2 x/y's are the terrain location?
i dont get the terrain location part..
why does it need more then 1 x/y?
 
Status
Not open for further replies.
Top