• 🏆 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] Need help with making bullet ability

Status
Not open for further replies.
Level 19
Joined
Oct 29, 2007
Messages
1,184
I need help with calculating a bullet flight line for my third person shooter.

For the bullet itself I am using a unit. When a player fires a shot, the unit is created at the position of the firing player. And a trigger that runs every 0.01 seconds adjusts the flying height and position of the bullet. The players camera angle of attack should determine in which direction (Up/ Down) the bullet should go when the player fires a shot.

I am not sure how to calculate the flying height and the speed of the bullet with aiming up and down. Until now I didn't mind the flying height, so I just had the bullet moved every 0.04 seconds to another location.

I'm really not sure how to do this, that's why I am asking here. :p
 
Level 19
Joined
Oct 29, 2007
Messages
1,184
Really thanks! But what about the height changing? Got the math there? : >

I got this so far:

JASS:
function Trig_Shotgun_Bullet_Actions takes nothing returns nothing
    
    local integer i = 0
    local real x
    local real x1
    local real y
    local real y1
    local real z
    local real z1
    local real a
    local real aa
    
    loop 
        if ( GetLocalPlayer() == Player(i) ) then
            set aa = GetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK)
        endif
        set i = i + 1
        set x = GetUnitX(udg_Player[i])
        set y = GetUnitY(udg_Player[i])
        set z = GetLocationZ(Location(x, y))
        set a = GetUnitFacing(udg_shotgun_bullet[i])
        set x = GetUnitX(udg_shotgun_bullet[i])
        set y = GetUnitY(udg_shotgun_bullet[i])
        set x1 =  x + 64 / Cos(aa) * Cos(a* bj_DEGTORAD)
        set y1 = y + 64 / Cos(aa) * Sin(a* bj_DEGTORAD)
        set z1 = GetLocationZ(Location(x1, y1))
        call SetUnitFlyHeight(udg_shotgun_bullet[i], 128 + z - z1, 0)
        call SetUnitPosition(udg_shotgun_bullet[i], x1, y1)
        call SetUnitFacing(udg_shotgun_bullet[i], a)
        exitwhen (i == 4)
    endloop
    
endfunction

//===========================================================================

function InitTrig_Shotgun_Bullet takes nothing returns nothing
    set gg_trg_Shotgun_Bullet = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_Shotgun_Bullet, 0.01 )
    call TriggerAddAction( gg_trg_Shotgun_Bullet, function Trig_Shotgun_Bullet_Actions )
endfunction
 
Last edited:
Level 17
Joined
Sep 8, 2007
Messages
994
Uhm, I dunno really about the height maths stuff ... but just a tip:
You leak 2 locations in a trigger running each 0.01 seconds :p
JASS:
set z = GetLocationZ(Location(x, y))
//and this one:
set z1 = GetLocationZ(Location(x1, y1))

I suggest to change it to this:
JASS:
local location TempLoc
...
set TempLoc = Location(x, y)
set z = GetLocationZ(TempLoc)
...
call RemoveLocation(TempLoc)
set TempLoc = null
//same with the other

Wish you good luck for your project! =)
 
Level 19
Joined
Oct 29, 2007
Messages
1,184
I got this now... But I can't really say it works well. The bullet is just fired in a straight line even thought the camera angle of attack changes. : <

JASS:
function Trig_Shotgun_Bullet_Actions takes nothing returns nothing
    
    local integer i = 0
    local location l
    local real h
    local real x
    local real x1
    local real y
    local real y1
    local real z
    local real z1
    local real a
    local real aa
    
    loop 
        if ( GetLocalPlayer() == Player(i) ) then
            set aa = GetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK)
        endif
        set i = i + 1
        set x = GetUnitX(udg_Player[i])
        set y = GetUnitY(udg_Player[i])
        set l = Location(x, y)
        set z = GetLocationZ(l)
        call RemoveLocation(l)
        set a = GetUnitFacing(udg_shotgun_bullet[i])
        set x = GetUnitX(udg_shotgun_bullet[i])
        set y = GetUnitY(udg_shotgun_bullet[i])
        set x1 = x + 64 / Cos(aa) * Cos(a* bj_DEGTORAD)
        set y1 = y + 64 / Cos(aa) * Sin(a* bj_DEGTORAD)
        set l = Location(x1, y1)
        set z1 = GetLocationZ(l)
        call RemoveLocation(l)
        set h = z - z1 + (64 * Sin(aa))
        call SetUnitFlyHeight(udg_shotgun_bullet[i], h, 0)
        call SetUnitPosition(udg_shotgun_bullet[i], x1, y1)
        call SetUnitFacing(udg_shotgun_bullet[i], a)
        exitwhen (i == 4)
    endloop
    
    set l = null
    
endfunction

//===========================================================================

function InitTrig_Shotgun_Bullet takes nothing returns nothing
    set gg_trg_Shotgun_Bullet = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_Shotgun_Bullet, 0.01 )
    call TriggerAddAction( gg_trg_Shotgun_Bullet, function Trig_Shotgun_Bullet_Actions )
endfunction
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
Spherical coordinates:

RADIUS (distance) //derived from polar
THETA (planar angle) //derived from polar
PHI (tilt angle from the plane)

Rectilinear coordinates:

X = RADIUS * Cos(THETA) * Sin(PHI)
Y = RADIUS * Sin(THETA) * Sin(PHI)
Z = RADIUS * Cos(PHI)

--

This assumes the angle is measured as an angle of descent from the plane. If it is an angle of ascent (measured upwards rather than downwards from the plane), swap Sin(PHI) with Cos(PHI) and vice versa.
 
Status
Not open for further replies.
Top