e4s-sdk/gamedata/scripts/heli_fly.script
2026-06-17 23:06:51 +03:00

180 lines
No EOL
6.4 KiB
Text

--[[------------------------------------------------------------------------------------------------
Helicopter movement
Àíäðóùåíêî Èâàí
--------------------------------------------------------------------------------------------------]]
local heli_flyer = {}
function get_heli_flyer(obj)
if heli_flyer[obj:id()] == nil then
heli_flyer[obj:id()] = heli_fly(obj)
end
return heli_flyer[obj:id()]
end
class "heli_fly"
function heli_fly:__init(obj)
self.obj = obj
self.block_flook = false
self.dist_by_look = 0
self.heliLAccFW = 6
self.heliLAccBW = 4
self.max_velocity = 0
self.point_arr = {}
self.dest_point = nil
self.point_by_look = vector():set(0,0,0)
end
function heli_fly:fly_on_point_with_vector(dest_point, dest_direction, dest_velocity, flag_to_wp_callback, flag_by_null_velocity)
--' printf("fly_on_point_with_vector()")
local heli = self.obj:get_helicopter()
local curr_heli_position = self.obj:position() -- òåêóùàÿ ïîçèöèÿ
local curr_heli_direction = self.obj:direction() -- åäèíè÷íûé âåêòîð òåêóùåãî íàïðàâëåíèÿ
local curr_heli_velocity = heli:GetCurrVelocity() -- òåêóùàÿ ñêîðîñòü
dest_velocity = dest_velocity * 1000 / 3600
if not flag_to_wp_callback then
--------------Ðàñ÷åòû------------------------------------------------------------------------------------------------------------------------------------------------------
local a_speed = 0
local time_by_fly = 0
local rez_point = vector():set(0,0,0) -- òî÷êà, ÷åðåç êîòîðóþ ïðîëåòèì, ÷òî-áû ïîïàñòü â çàäàííóþ òî÷êó, è âûéòè íà çàäàííóþ ñêîðîñòü
local d_path -- d_path - äîïóñê ðàññòîÿíèÿ ïîïàäàíèÿ â òî÷êó
-------------------------------------------------------------
if dest_velocity >= curr_heli_velocity then
-------------------------------------------------------------
a_speed= self.heliLAccFW -- óñêîðåíèå ðàçãîíà, áåðåì èç helicopter.ltx
d_path = curr_heli_velocity * 2 / a_speed
-------------------------------------------------------------
else
-------------------------------------------------------------
a_speed= - self.heliLAccBW -- óñêîðåíèå òîðìîæåíèÿ, áåðåì èç helicopter.ltx
d_path = - curr_heli_velocity * 2 / a_speed
-------------------------------------------------------------
end
time_by_fly = (dest_velocity - curr_heli_velocity)/a_speed -- t=(v2-v1)/a -- t - âðåìÿ, çà êîòîðîå çàòîðìîçèì/ðàçãîíèìñÿ. a - óñêîðåíèå òîðìîæåíèÿ/ðàçãîíà, áåðåì èç helicopter.ltx
local delta = curr_heli_velocity * time_by_fly + a_speed * time_by_fly * time_by_fly / 2 -- ðàññòîÿíèå äëÿ âûõîäà íà çàäàííóþ ñêîðîñòü s=v0t+(at^2)/2
if delta >= d_path then
self.point_arr[0] = curr_heli_position
self.point_arr[1] = dest_point
self.point_arr[2] = curr_heli_direction
rez_point = self:calc_point()
if not self.block_flook then
rez_point.x = rez_point.x + curr_heli_direction.x * delta / 2
rez_point.z = rez_point.z + curr_heli_direction.z * delta / 2
end
flag_to_wp_callback = true
else
rez_point = dest_point
flag_to_wp_callback = false
end
self.dest_point = rez_point
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
else
self.dest_point = dest_point
flag_to_wp_callback = false
end
heli:SetDestPosition( self.dest_point )
self:correct_velocity()
if flag_by_null_velocity then
heli:SetSpeedInDestPoint(0)
else
heli:SetSpeedInDestPoint(heli:GetMaxVelocity())
end
return flag_to_wp_callback
end
function heli_fly:get_block_flook()
return self.block_flook
end
function heli_fly:calc_point()
local rez_point = vector():set(0,0,0)
local xxArr = {}
xxArr[0] = self.point_arr[0].x
xxArr[1] = self.point_arr[1].x
xxArr[2] = self.point_arr[2].x
local yyArr = {}
yyArr[0] = self.point_arr[0].y
yyArr[1] = self.point_arr[1].y
yyArr[2] = self.point_arr[2].y
local zzArr = {}
zzArr[0] = self.point_arr[0].z
zzArr[1] = self.point_arr[1].z
zzArr[2] = self.point_arr[2].z
rez_point.y = (self.point_arr[0].y + self.point_arr[1].y)/2
if rez_point.y == self.point_arr[0].y then
rez_point.z = (self.point_arr[0].z + self.point_arr[1].z)/2
if rez_point.z == self.point_arr[0].z then
rez_point.x = (self.point_arr[0].x + self.point_arr[1].x)/2
rez_point.z = self:lagrange(rez_point.x, xxArr, zzArr)
else
rez_point.x = self:lagrange(rez_point.z, zzArr, xxArr)
end
else
rez_point.x = self:lagrange(rez_point.y, yyArr, xxArr)
rez_point.z = self:lagrange(rez_point.y, yyArr, zzArr)
end
--' printf("fly_point[x=%d; y=%d; z=%d;]",rez_point.x, rez_point.y, rez_point.z);
return rez_point
end
function heli_fly:lagrange(x, xArr, yArr)
local i, j
local m, s
s = 0
for i=0,2 do
m = yArr[i]
for j=0,2 do
if j ~= i then
m = m * (x - xArr[j]) / (xArr[i] - xArr[j])
end
end
s = s + m
end
return s
end
function heli_fly:correct_velocity()
local heli = self.obj:get_helicopter()
local curr_heli_velocity = heli:GetCurrVelocity() --' òåêóùàÿ ñêîðîñòü
local dist_to_dest_point = heli:GetDistanceToDestPosition()
local a_speed = self.heliLAccFW
local dest_velocity
dest_velocity = ((2*a_speed*dist_to_dest_point + curr_heli_velocity^2)/3)^(1/2)
if self.max_velocity*1000/3600 < dest_velocity then
dest_velocity = self.max_velocity*1000/3600
end
heli:SetMaxVelocity(dest_velocity)
--' printf("dist_to_dest_point %s", dist_to_dest_point);
--' printf("dest_velocity end = %d", dest_velocity);
end
function heli_fly:look_at_position()
if self.block_flook then
local heli = self.obj:get_helicopter()
heli:LookAtPoint( self.point_by_look, true )
end
end
function heli_fly:set_block_flook(fl_block)
self.block_flook = fl_block
end
function heli_fly:set_look_point(l_point)
self.point_by_look = l_point
end