This code makes the missile a bit smarter. If the distance and angle relative to the target indicate that an orbit lock is likely, it will disable turning until it has enough distance on the target to get lined up on it.
Note that I'm still using the xz plane here. The yaw rotational functions are available without the need for bodges, and the EntityYaw function returns more sensible values than the 'get value' functions for the other axiis.
This code can be used for open space combat, where there's no ground plane for the smart missile to worry about
This code can be used for ground based combat, where you don't want the missile plowing into the ground plane. The missile only disables turning if it is facing 'upwards'.
Note that I'm still using the xz plane here. The yaw rotational functions are available without the need for bodges, and the EntityYaw function returns more sensible values than the 'get value' functions for the other axiis.
This code can be used for open space combat, where there's no ground plane for the smart missile to worry about
; The number of logic updates per second. Const C_LOGIC_FREQUENCY = 50 ; The interval (in milliseconds) between logic updates. Const C_LOGIC_INTERVAL# = 1000.0 / C_LOGIC_FREQUENCY ; Unused. Const C_SMART_MISSILE_TEST_DISTANCE# = 10.0 Const C_SMART_MISSILE_TEST_ANGLE# = 60.0 Const C_SMART_MISSILE_NO_TURN_DISTANCE# = 15.0 Global timer = CreateTimer( C_LOGIC_FREQUENCY ) Graphics3D 800, 600, 0, 2 SetBuffer BackBuffer() SeedRnd MilliSecs() Global cam = CreateCamera() CameraZoom cam, 1.6 MoveEntity cam, 0.0, 60.0, 0.0 TurnEntity cam, 90.0, 0.0, 0.0 Global light = CreateLight() Global cone = CreateCone() RotateMesh cone, 90.0, 0.0, 0.0 UpdateNormals cone PositionEntity cone, 0.0, 0.0, -20.0 Global cube = CreateCube() UpdateNormals cube ;PositionEntity cube, 40.0, 0.0, 20.0 PositionEntity cube, Rnd( -5.0, 5.0 ), 0.0, Rnd( -5.0, 5.0 ) Global dist# While Not KeyHit( 1 ) dist# = EntityDistance( cone, cube ) If allow_turn If dist# < C_SMART_MISSILE_TEST_DISTANCE# If Abs( DeltaYaw( cone, cube ) ) > C_SMART_MISSILE_TEST_ANGLE# allow_turn = False EndIf EndIf Else If dist# > C_SMART_MISSILE_NO_TURN_DISTANCE# Then allow_turn = True EndIf If allow_turn Then YawToEntity cone, cube, 3.0 MoveEntity cone, 0.0, 0.0, 0.5 If dist# < 2.0 PositionEntity cube, Rnd( -5.0, 5.0 ), 0.0, Rnd( -5.0, 5.0 ) EndIf UpdateWorld RenderWorld Flip WaitTimer( timer ) Wend End Function YawToEntity( src_entity, dest_entity, rate# ) ; Turns 'src_entity' to point at 'dest_entity' at the rotation rate specified by 'rate#'. Local target_yaw# = DeltaYaw( src_entity, dest_entity ) ; If the required correction amount is less than the correction amount to be applied... If Abs( target_yaw# ) < rate# ; Point 'src_entity' directly at 'dest_entity' to prevent jittering. TurnEntity src_entity, 0.0, target_yaw#, 0.0 Else ; Turn 'src_entity' gradually towards 'dest_entity'. TurnEntity src_entity, 0.0, rate# * Sgn( target_yaw# ), 0.0 EndIf End Function
This code can be used for ground based combat, where you don't want the missile plowing into the ground plane. The missile only disables turning if it is facing 'upwards'.
; The number of logic updates per second. Const C_LOGIC_FREQUENCY = 50 ; The interval (in milliseconds) between logic updates. Const C_LOGIC_INTERVAL# = 1000.0 / C_LOGIC_FREQUENCY ; Unused. Const C_SMART_MISSILE_TEST_DISTANCE# = 10.0 Const C_SMART_MISSILE_TEST_ANGLE# = 60.0 Const C_SMART_MISSILE_NO_TURN_DISTANCE# = 20.0 Global timer = CreateTimer( C_LOGIC_FREQUENCY ) Graphics3D 800, 600, 0, 2 SetBuffer BackBuffer() SeedRnd MilliSecs() Global cam = CreateCamera() CameraZoom cam, 1.6 MoveEntity cam, 0.0, 60.0, 0.0 TurnEntity cam, 90.0, 0.0, 0.0 Global light = CreateLight() Global cone = CreateCone() RotateMesh cone, 90.0, 0.0, 0.0 UpdateNormals cone PositionEntity cone, 0.0, 0.0, -20.0 Global cube = CreateCube() UpdateNormals cube PositionEntity cube, Rnd( -5.0, 5.0 ), 0.0, Rnd( -5.0, 5.0 ) Global dist#, allow_turn = True, disable_allow_turn_when_pointing_up = False While Not KeyHit( 1 ) dist# = EntityDistance( cone, cube ) If allow_turn If dist# < C_SMART_MISSILE_TEST_DISTANCE# If Abs( DeltaYaw( cone, cube ) ) > C_SMART_MISSILE_TEST_ANGLE# disable_allow_turn_when_pointing_up = True EndIf EndIf Else If dist# > C_SMART_MISSILE_NO_TURN_DISTANCE# Then allow_turn = True EndIf If disable_allow_turn_when_pointing_up If Abs( EntityYaw( cone ) ) < 89.0 ; Note: 89 degrees is used so that the missile will turn upwards. allow_turn = False disable_allow_turn_when_pointing_up = False EndIf EndIf If allow_turn Then YawToEntity cone, cube, 3.0 MoveEntity cone, 0.0, 0.0, 0.5 If dist# < 2.0 PositionEntity cube, Rnd( -5.0, 5.0 ), 0.0, Rnd( -5.0, 5.0 ) EndIf UpdateWorld RenderWorld Flip WaitTimer( timer ) Wend End Function YawToEntity( src_entity, dest_entity, rate# ) ; Turns 'src_entity' to point at 'dest_entity' at the rotation rate specified by 'rate#'. Local target_yaw# = DeltaYaw( src_entity, dest_entity ) ; If the required correction amount is less than the correction amount to be applied... If Abs( target_yaw# ) < rate# ; Point 'src_entity' directly at 'dest_entity' to prevent jittering. TurnEntity src_entity, 0.0, target_yaw#, 0.0 Else ; Turn 'src_entity' gradually towards 'dest_entity'. TurnEntity src_entity, 0.0, rate# * Sgn( target_yaw# ), 0.0 EndIf End Function