add game&rawdata
This commit is contained in:
parent
0133cd976c
commit
49b34b5546
45731 changed files with 709831 additions and 0 deletions
775
gamedata/scripts/heli_combat.script
Normal file
775
gamedata/scripts/heli_combat.script
Normal file
|
|
@ -0,0 +1,775 @@
|
|||
--[[------------------------------------------------------------------------------------------------
|
||||
Óíèâåðñàëüíàÿ áîåâàÿ ñõåìà âåðòîë¸òà
|
||||
×óãàé Àëåêñàíäð
|
||||
|
||||
 îòëè÷èå îò ñòàëêåðîâ áîåâàÿ ñõåìà íå ÿâëÿåòñÿ îòäåëüíûì äåéñòâèåì, à âûçûâàåòñÿ èç äðóãèõ ñõåì.
|
||||
--------------------------------------------------------------------------------------------------]]
|
||||
|
||||
local combat_type_flyby = 0 -- àòàêà ïðîë¸òàìè íàä öåëüþ
|
||||
local combat_type_round = 1 -- êðóæåíèå âîêðóã ïîçèöèè, àòàêà êðóæàñü âîêðóã öåëè
|
||||
local combat_type_search = 2 -- ïîèñê âðàãà, êðóæåíèå âîêðóã òî÷êè, ãäå ïîñëåäíèé ðàç âèäåë, àòàêà êðóæàñü âîêðóã öåëè
|
||||
local combat_type_retreat = 3 -- óë¸ò çà ïðåäåëû óðîâíÿ
|
||||
|
||||
local flyby_state_to_attack_dist = 0
|
||||
local flyby_state_to_enemy = 1
|
||||
|
||||
local combat_type_change_delay = 5000
|
||||
local visibility_delay = 3000
|
||||
local search_shoot_delay = 2000
|
||||
local round_shoot_delay = 2000
|
||||
|
||||
local dummy_vector = vector()
|
||||
|
||||
local debug_combat_type
|
||||
|
||||
function debug_switch_combat_type()
|
||||
if debug_combat_type == combat_type_flyby then
|
||||
debug_combat_type = combat_type_search
|
||||
else
|
||||
debug_combat_type = combat_type_flyby
|
||||
end
|
||||
end
|
||||
|
||||
function distance_2d( a, b )
|
||||
return math.sqrt( (b.x-a.x)^2 + (b.z-a.z)^2 )
|
||||
end
|
||||
|
||||
-- ïåðåñå÷åíèå ëó÷à è êðóãà.
|
||||
-- p - òî÷êà íà÷àëà ëó÷à, v - íàïðàâëåíèå ëó÷à (îðò), o - öåíòð êðóãà, r - ðàäèóñ êðóãà
|
||||
-- òî÷êà p äîëæíà áûòü âíóòðè êðóãà
|
||||
function cross_ray_circle( p, v, o, r )
|
||||
local po = vector():set( o ):sub( p )
|
||||
local vperp = vector():set( -v.z, 0, v.x )
|
||||
local l = math.sqrt( ( r ^ 2 ) - ( vector():set( po ):dotproduct( vperp ) ^ 2 ) )
|
||||
return vector():set( p ):add( vector():set( v ):mul( vector():set( po ):dotproduct( v ) + l ) )
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------------------
|
||||
class "heli_combat"
|
||||
|
||||
function heli_combat:__init( object, heliObject )
|
||||
self.st = db.storage[object:id()]
|
||||
self.object = object
|
||||
self.heliObject = heliObject
|
||||
self.initialized = false
|
||||
|
||||
self.level_max_y = level.get_bounding_volume().max.y
|
||||
|
||||
local ltx = system_ini()
|
||||
|
||||
self.flyby_attack_dist = utils.cfg_get_number( ltx, "helicopter", "flyby_attack_dist", self.object, true )
|
||||
self.search_attack_dist = utils.cfg_get_number( ltx, "helicopter", "search_attack_dist", self.object, true )
|
||||
self.default_safe_altitude = utils.cfg_get_number( ltx, "helicopter", "safe_altitude", self.object, true ) + self.level_max_y
|
||||
self.m_max_mgun_dist = utils.cfg_get_number( ltx, "helicopter", "max_mgun_attack_dist", self.object, true )
|
||||
|
||||
self.default_velocity = utils.cfg_get_number( ltx, "helicopter", "velocity", self.object, true )
|
||||
self.search_velocity = utils.cfg_get_number( ltx, "helicopter", "search_velocity", self.object, true )
|
||||
self.round_velocity = utils.cfg_get_number( ltx, "helicopter", "round_velocity", self.object, true )
|
||||
|
||||
self.vis_time_quant = utils.cfg_get_number( ltx, "helicopter", "vis_time_quant", self.object, true )
|
||||
self.vis_threshold = utils.cfg_get_number( ltx, "helicopter", "vis_threshold", self.object, true )
|
||||
self.vis_inc = utils.cfg_get_number( ltx, "helicopter", "vis_inc", self.object, true ) * self.vis_time_quant * 0.001
|
||||
self.vis_dec = utils.cfg_get_number( ltx, "helicopter", "vis_dec", self.object, true ) * self.vis_time_quant * 0.001
|
||||
self.vis = 0
|
||||
self.vis_next_time = 0
|
||||
|
||||
self.forget_timeout = utils.cfg_get_number( ltx, "helicopter", "forget_timeout", self.object, true ) * 1000
|
||||
|
||||
self.flame_start_health = utils.cfg_get_number( ltx, "helicopter", "flame_start_health", self.object, true )
|
||||
|
||||
self.attack_before_retreat = false
|
||||
self.enemy_forgetable = true
|
||||
self.section_changed = false
|
||||
debug_combat_type = nil
|
||||
end
|
||||
|
||||
function heli_combat:read_custom_data( ini, section )
|
||||
self.combat_use_rocket = utils.cfg_get_bool ( ini, section, "combat_use_rocket", self.object, false, true )
|
||||
self.combat_use_mgun = utils.cfg_get_bool ( ini, section, "combat_use_mgun", self.object, false, true )
|
||||
-- self.combat_ignore = utils.cfg_get_bool ( ini, section, "combat_ignore", self.object, false, false )
|
||||
|
||||
local combat_ignore = utils.cfg_get_string( ini, section, "combat_ignore", self.object, false, "", nil )
|
||||
if combat_ignore then
|
||||
self.combat_ignore = xr_logic.parse_condlist( self.object, section, "combat_ignore", combat_ignore )
|
||||
else
|
||||
self.combat_ignore = nil
|
||||
end
|
||||
|
||||
local combat_enemy = utils.cfg_get_string( ini, section, "combat_enemy", self.object, false, "", nil )
|
||||
self:set_enemy_from_custom_data( combat_enemy )
|
||||
|
||||
self.max_velocity = utils.cfg_get_number( ini, section, "combat_velocity", self.object, false, self.default_velocity )
|
||||
self.safe_altitude = utils.cfg_get_number( ini, section, "combat_safe_altitude", self.object, false,
|
||||
self.default_safe_altitude ) + self.level_max_y
|
||||
|
||||
self.section_changed = true
|
||||
end
|
||||
|
||||
-- óñòàíîâêà âðàãà ïî custom data
|
||||
-- åñëè âðàã óñòàíîâèëñÿ ýòîé ôóíêöèåé, òî îí íå áóäåò çàáûâàòüñÿ ïðè äëèòåëüíîé ïîòåðå âèäèìîñòè!
|
||||
-- åñëè óñòàíîâèëñÿ íîâûé âðàã, òî combat áóäåò ïåðåèíèöèàëèçèðîâàí
|
||||
function heli_combat:set_enemy_from_custom_data( combat_enemy )
|
||||
if combat_enemy == nil then
|
||||
self.enemy_forgetable = true
|
||||
else
|
||||
if combat_enemy == "actor" then
|
||||
if db.actor then
|
||||
self.enemy_id = db.actor:id()
|
||||
else
|
||||
self:forget_enemy()
|
||||
end
|
||||
elseif combat_enemy == "nil" then
|
||||
self:forget_enemy()
|
||||
else
|
||||
self.enemy_id = id_by_sid( tonumber( combat_enemy ) )
|
||||
end
|
||||
|
||||
if self.enemy_id then
|
||||
self.enemy_forgetable = false
|
||||
self.initialized = false
|
||||
else
|
||||
self.enemy_forgetable = true
|
||||
self:forget_enemy()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function heli_combat:set_combat_type( new_combat_type )
|
||||
if new_combat_type ~= self.combat_type then
|
||||
self.flyby_initialized = false
|
||||
self.round_initialized = false
|
||||
self.search_initialized = false
|
||||
|
||||
self.combat_type = new_combat_type
|
||||
end
|
||||
end
|
||||
|
||||
function heli_combat:initialize()
|
||||
self.enemy_last_seen_pos = self.enemy:position()
|
||||
self.enemy_last_seen_time = 0
|
||||
self.enemy_last_spot_time = nil
|
||||
self.can_forget_enemy = false
|
||||
self.section_changed = true
|
||||
|
||||
-- self:set_combat_type( combat_type_flyby )
|
||||
-- self:set_combat_type( combat_type_search )
|
||||
self.combat_type = combat_type_flyby
|
||||
self.change_combat_type_time = nil
|
||||
self.change_combat_type_allowed = true
|
||||
|
||||
self.heliObject.m_max_mgun_dist = self.m_max_mgun_dist
|
||||
|
||||
self.flyby_states_for_one_pass = 2
|
||||
|
||||
self.object:set_fastcall( self.fastcall, self )
|
||||
|
||||
self.initialized = true
|
||||
end
|
||||
|
||||
function heli_combat:save( packet )
|
||||
-- packet:w_bool( self.retreat_already )
|
||||
set_save_marker(packet, "save", false, "heli_combat")
|
||||
printf( "heli_combat:save level_changing=%s", tostring( utils.level_changing() ) )
|
||||
|
||||
if utils.level_changing() then
|
||||
packet:w_bool( false )
|
||||
set_save_marker(packet, "save", true, "heli_combat")
|
||||
return
|
||||
end
|
||||
|
||||
packet:w_bool( self.initialized )
|
||||
|
||||
if self.initialized then
|
||||
local t = time_global()
|
||||
|
||||
packet:w_s16 ( self.enemy_id )
|
||||
packet:w_u32 ( t - self.enemy_last_seen_time )
|
||||
packet:w_bool( self.can_forget_enemy )
|
||||
packet:w_bool( self.enemy_forgetable )
|
||||
packet:w_vec3( self.enemy_last_seen_pos )
|
||||
|
||||
packet:w_u8 ( self.combat_type )
|
||||
|
||||
if self.combat_type == combat_type_search then
|
||||
packet:w_u32 ( self.change_dir_time - t )
|
||||
packet:w_u32 ( self.change_pos_time - t )
|
||||
packet:w_bool( self.flight_direction )
|
||||
packet:w_vec3( self.center_pos )
|
||||
|
||||
elseif self.combat_type == combat_type_flyby then
|
||||
packet:w_s16( self.flyby_states_for_one_pass )
|
||||
end
|
||||
end
|
||||
set_save_marker(packet, "save", true, "heli_combat")
|
||||
end
|
||||
|
||||
function heli_combat:load( packet )
|
||||
|
||||
printf( "heli_combat:LOAD level_changing=%s", tostring( utils.level_changing() ) )
|
||||
-- self.retreat_already = packet:r_bool()
|
||||
set_save_marker(packet, "load", false, "heli_combat")
|
||||
|
||||
|
||||
self.initialized = packet:r_bool()
|
||||
printf("initialized = [%s]", tostring(self.initialized))
|
||||
|
||||
if self.initialized then
|
||||
local t = time_global()
|
||||
printf("t = [%s]", tostring(t))
|
||||
self.enemy_last_seen_pos = vector()
|
||||
|
||||
self.enemy_id = packet:r_s16()
|
||||
printf("self.enemy_id = [%s]", tostring(self.enemy_id))
|
||||
self.enemy_last_seen_time = t - packet:r_u32()
|
||||
printf("self.enemy_last_seen_time = [%s]", tostring(self.enemy_last_seen_time))
|
||||
self.can_forget_enemy = packet:r_bool()
|
||||
printf("self.can_forget_enemy = [%s]", tostring(self.can_forget_enemy))
|
||||
self.enemy_forgetable = packet:r_bool()
|
||||
printf("self.enemy_forgetable = [%s]", tostring(self.enemy_forgetable))
|
||||
packet:r_vec3( self.enemy_last_seen_pos )
|
||||
printf("self.enemy_last_seen_pos = [%s]", vec_to_str(self.enemy_last_seen_pos))
|
||||
self.combat_type = packet:r_u8()
|
||||
printf("self.combat_type = [%s]", tostring(self.combat_type))
|
||||
|
||||
if self.combat_type == combat_type_search then
|
||||
self.center_pos = vector()
|
||||
|
||||
self.change_dir_time = packet:r_u32() + t
|
||||
printf("self.change_dir_time = [%s]", tostring(self.change_dir_time))
|
||||
self.change_pos_time = packet:r_u32() + t
|
||||
printf("self.change_pos_time = [%s]", tostring(self.change_pos_time))
|
||||
self.flight_direction = packet:r_bool()
|
||||
printf("self.flight_direction = [%s]", tostring(self.flight_direction))
|
||||
packet:r_vec3( self.center_pos )
|
||||
printf("self.center_pos = [%s]", vec_to_str(self.center_pos))
|
||||
|
||||
elseif self.combat_type == combat_type_flyby then
|
||||
self.flyby_states_for_one_pass = packet:r_s16()
|
||||
printf("self.flyby_states_for_one_pass = [%s]", tostring(self.flyby_states_for_one_pass))
|
||||
end
|
||||
end
|
||||
set_save_marker(packet, "load", true, "heli_combat")
|
||||
end
|
||||
|
||||
function heli_combat:waypoint_callback()
|
||||
if self.enemy_id and not self:combat_ignore_check() then
|
||||
self.was_callback = true
|
||||
printf( "heli_combat:waypoint_callback" )
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
-- Îáíîâëåíèå ïàðàìåòðîâ âåðòîë¸òà, çàäàâàåìûõ â custom data.
|
||||
-- Íóæíî äåëàòü íà êàæäîì îáíîâëåíèè íà ñëó÷àé, åñëè âî âðåìÿ áîÿ ëîãèêà ïåðåêëþ÷èëàñü íà äðóãóþ ñåêöèþ.
|
||||
function heli_combat:update_custom_data_settings()
|
||||
if self.section_changed then
|
||||
self.heliObject.m_use_rocket_on_attack = self.combat_use_rocket
|
||||
self.heliObject.m_use_mgun_on_attack = self.combat_use_mgun
|
||||
|
||||
if self.combat_type == combat_type_flyby then
|
||||
printf( "heli_combat:update_custom_data_settings SetMaxVelocity=%d", self.max_velocity )
|
||||
self.heliObject:SetMaxVelocity( self.max_velocity )
|
||||
end
|
||||
|
||||
self.section_changed = false
|
||||
end
|
||||
end
|
||||
|
||||
function heli_combat:update_enemy_visibility()
|
||||
self.object:info_add( "vis=" .. self.vis )
|
||||
|
||||
if self.vis >= self.vis_threshold then
|
||||
self.enemy_last_seen_time = time_global()
|
||||
self.enemy_last_seen_pos = self.enemy:position()
|
||||
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function heli_combat:forget_enemy()
|
||||
self.enemy_id = nil
|
||||
self.enemy = nil
|
||||
|
||||
self.initialized = false
|
||||
end
|
||||
|
||||
function heli_combat:update_forgetting()
|
||||
if ( ( self.enemy_forgetable and self.can_forget_enemy ) and
|
||||
( time_global() - self.enemy_last_seen_time > self.forget_timeout ) ) or not self.enemy:alive()
|
||||
then
|
||||
self:forget_enemy()
|
||||
end
|
||||
end
|
||||
|
||||
function heli_combat:update_combat_type( see_enemy )
|
||||
-- do return combat_type_flyby end
|
||||
|
||||
-- DEBUG
|
||||
if debug_combat_type ~= nil then
|
||||
self:set_combat_type( debug_combat_type )
|
||||
return
|
||||
end
|
||||
--------
|
||||
|
||||
local ct = self.combat_type
|
||||
|
||||
-- printf( "flyby_states_for_one_pass=%d", self.flyby_states_for_one_pass )
|
||||
|
||||
if self.combat_type == combat_type_flyby then
|
||||
if self.flyby_states_for_one_pass <= 0 then
|
||||
if self.attack_before_retreat then
|
||||
ct = combat_type_retreat
|
||||
else
|
||||
ct = combat_type_round
|
||||
end
|
||||
end
|
||||
|
||||
elseif self.combat_type == combat_type_round then
|
||||
if see_enemy then
|
||||
if distance_2d( self.object:position(), self.enemy:position() ) > self.flyby_attack_dist + 70 --and
|
||||
-- not self.flyby_pass_finished
|
||||
then
|
||||
ct = combat_type_flyby
|
||||
end
|
||||
else
|
||||
ct = combat_type_search
|
||||
end
|
||||
|
||||
if bind_heli.get_heli_health( self.heliObject, self.st ) < self.flame_start_health then
|
||||
self.attack_before_retreat = true
|
||||
|
||||
self.heliObject.m_use_rocket_on_attack = true
|
||||
|
||||
ct = combat_type_flyby
|
||||
end
|
||||
|
||||
elseif self.combat_type == combat_type_search then
|
||||
if see_enemy then
|
||||
if distance_2d( self.object:position(), self.enemy:position() ) > self.flyby_attack_dist then
|
||||
ct = combat_type_flyby
|
||||
else
|
||||
ct = combat_type_round
|
||||
end
|
||||
end
|
||||
|
||||
if bind_heli.get_heli_health( self.heliObject, self.st ) < self.flame_start_health then
|
||||
self.attack_before_retreat = true
|
||||
|
||||
self.heliObject.m_use_rocket_on_attack = true
|
||||
|
||||
ct = combat_type_flyby
|
||||
end
|
||||
end
|
||||
|
||||
-- printf( "combat_type = %s", tostring( self.combat_type ) )
|
||||
self:set_combat_type( ct )
|
||||
-- printf( "combat_type = %s", tostring( self.combat_type ) )
|
||||
end
|
||||
|
||||
-- íóæíî ëè èãíîðèðîâàòü âðàãà
|
||||
function heli_combat:combat_ignore_check()
|
||||
return self.combat_ignore ~= nil and xr_logic.pick_section_from_condlist( db.actor, self.object, self.combat_ignore ) ~= nil
|
||||
end
|
||||
|
||||
-- ÷àñòîå îáíîâëåíèå.
|
||||
-- íóæíî äëÿ îòñëåæèâàíèÿ âèäèìîñòè âðàãà
|
||||
function heli_combat:fastcall()
|
||||
if self.initialized then
|
||||
if self.vis_next_time < time_global() then
|
||||
self.vis_next_time = time_global() + self.vis_time_quant
|
||||
|
||||
if self.heliObject:isVisible( self.enemy ) then
|
||||
self.vis = self.vis + self.vis_inc
|
||||
|
||||
if self.vis > 100 then
|
||||
self.vis = 100
|
||||
end
|
||||
else
|
||||
self.vis = self.vis - self.vis_dec
|
||||
|
||||
if self.vis < 0 then
|
||||
self.vis = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
-- Îáíîâëåíèå áîåâîé ñõåìû. Âûçûâàåòñÿ èç îáíîâëåíèé ñõåì ëîãèêè âåðòîë¸òà.
|
||||
-- âîçâðàùàåò true, åñëè áîé àêòèâåí (òî åñòü íåòó combat_ignore è åñòü âðàã)
|
||||
function heli_combat:update()
|
||||
if self.enemy_id then
|
||||
self.enemy = level.object_by_id( self.enemy_id )
|
||||
if not self.enemy then
|
||||
self:forget_enemy()
|
||||
return false
|
||||
end
|
||||
else
|
||||
return false
|
||||
end
|
||||
|
||||
if self:combat_ignore_check() then
|
||||
return false
|
||||
end
|
||||
|
||||
self:update_custom_data_settings()
|
||||
|
||||
if not self.initialized then
|
||||
self:initialize()
|
||||
end
|
||||
|
||||
local see_enemy = self:update_enemy_visibility()
|
||||
|
||||
self:update_combat_type( see_enemy )
|
||||
-- FIXME
|
||||
-- self.heliObject:GetSpeedInDestPoint(0)
|
||||
|
||||
if self.combat_type == combat_type_search then
|
||||
self:search_update( see_enemy )
|
||||
elseif self.combat_type == combat_type_round then
|
||||
self:round_update( see_enemy )
|
||||
elseif self.combat_type == combat_type_flyby then
|
||||
self:flyby_update( see_enemy )
|
||||
elseif self.combat_type == combat_type_retreat then
|
||||
self:retreat_update()
|
||||
end
|
||||
|
||||
self:update_forgetting()
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-- ïîñ÷èòàòü òî÷êó íà çàäàííîì ðàäèóñå îò ïîñëåäíåé âèäèìîé ïîçèöèè âðàãà â òåêóùåì íàïðàâëåíèè ñêîðîñòè âåðòîë¸òà
|
||||
function heli_combat:calc_position_in_radius( r )
|
||||
local p = self.object:position()
|
||||
p.y = 0
|
||||
|
||||
local v = self.heliObject:GetCurrVelocityVec()
|
||||
v.y = 0
|
||||
v:normalize()
|
||||
|
||||
local o = self.enemy_last_seen_pos
|
||||
o.y = 0
|
||||
|
||||
local ret = cross_ray_circle( p, v, o, r )
|
||||
ret.y = self.safe_altitude
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------------
|
||||
-- Ôóíöèèè êðóæàùåãî áîÿ
|
||||
----------------------------------------------------------------------------------------------
|
||||
function heli_combat:round_initialize()
|
||||
self.change_dir_time = 0
|
||||
self.change_pos_time = 0
|
||||
self.center_pos = self.enemy_last_seen_pos
|
||||
self.flight_direction = random_choice( true, false )
|
||||
self.change_combat_type_allowed = true
|
||||
self.round_begin_shoot_time = 0
|
||||
|
||||
|
||||
printf( "heli_combat:round_initialize SetMaxVelocity=%d", self.round_velocity )
|
||||
self.heliObject:SetMaxVelocity( self.round_velocity )
|
||||
self.heliObject:SetSpeedInDestPoint( self.round_velocity )
|
||||
self.heliObject:UseFireTrail( false )
|
||||
|
||||
self.round_initialized = true
|
||||
|
||||
self:round_setup_flight( self.flight_direction )
|
||||
end
|
||||
|
||||
function heli_combat:round_setup_flight( direction )
|
||||
self.center_pos = self.enemy_last_seen_pos
|
||||
self.center_pos.y = self.safe_altitude
|
||||
|
||||
printf( "heli_combat:round_setup_flight GoPatrolByRoundPath" )
|
||||
self.heliObject:GoPatrolByRoundPath( self.center_pos, self.search_attack_dist, direction )
|
||||
self.heliObject:LookAtPoint( self.enemy:position(), true )
|
||||
end
|
||||
|
||||
function heli_combat:round_update_shooting( see_enemy )
|
||||
if see_enemy then
|
||||
if self.round_begin_shoot_time then
|
||||
if self.round_begin_shoot_time < time_global() then
|
||||
self.heliObject:SetEnemy( self.enemy )
|
||||
end
|
||||
else
|
||||
self.round_begin_shoot_time = time_global() + round_shoot_delay
|
||||
end
|
||||
else
|
||||
self.heliObject:ClearEnemy()
|
||||
|
||||
self.round_begin_shoot_time = nil
|
||||
end
|
||||
end
|
||||
|
||||
function heli_combat:round_update_flight( see_enemy )
|
||||
-- ìåíÿòü âðåìÿ îò âðåìåíè íàïðàâëåíèå îáë¸òà
|
||||
--[[ if self.change_dir_time < time_global() then
|
||||
local t
|
||||
|
||||
if see_enemy then
|
||||
t = math.random( 6000, 10000 )
|
||||
else
|
||||
t = math.random( 15000, 20000 )
|
||||
end
|
||||
|
||||
self.change_dir_time = time_global() + t --+ 1000000
|
||||
|
||||
printf( "heli_combat: going by round path, t=%d", t )
|
||||
|
||||
self.flight_direction = not self.flight_direction
|
||||
self:round_setup_flight( self.flight_direction )
|
||||
|
||||
return
|
||||
end
|
||||
]]
|
||||
-- ïåðèîäè÷åñêè ïðîâåðòü, íå ïåðåìåñòèëñÿ ëè âðàã è äîñòàòî÷íî ëè ó âåðòîë¸òà çäîðîâüÿ
|
||||
if self.change_pos_time < time_global() then
|
||||
self.change_pos_time = time_global() + 2000
|
||||
|
||||
if not self.can_forget_enemy and
|
||||
distance_2d( self.object:position(), self.enemy_last_seen_pos ) <= self.search_attack_dist
|
||||
then
|
||||
self.can_forget_enemy = true
|
||||
end
|
||||
|
||||
if distance_2d( self.center_pos, self.enemy_last_seen_pos ) > 10 then
|
||||
printf( "heli_combat: enemy has changed his position" )
|
||||
|
||||
self:round_setup_flight( self.flight_direction )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function heli_combat:round_update( see_enemy )
|
||||
if not self.round_initialized then
|
||||
self:round_initialize()
|
||||
end
|
||||
|
||||
-- printf( "heli_combat: round_update" )
|
||||
|
||||
self:round_update_shooting( see_enemy )
|
||||
self:round_update_flight ( see_enemy )
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------------
|
||||
-- Ôóíöèèè äëÿ ïîèñêà âðàãà (ñêîïèðîâàíî ñ êðóæàùåãî áîÿ)
|
||||
----------------------------------------------------------------------------------------------
|
||||
function heli_combat:search_initialize()
|
||||
self.change_speed_time = time_global() + math.random( 5000, 7000 ) --+ 1000000
|
||||
self.speed_is_0 = true
|
||||
|
||||
self.change_pos_time = 0
|
||||
self.center_pos = self.enemy_last_seen_pos
|
||||
|
||||
self.flight_direction = random_choice( true, false )
|
||||
self.change_combat_type_allowed = true
|
||||
self.search_begin_shoot_time = 0
|
||||
|
||||
self.heliObject:UseFireTrail( false )
|
||||
|
||||
self.search_initialized = true
|
||||
|
||||
self:search_setup_flight()
|
||||
end
|
||||
|
||||
function heli_combat:search_setup_flight()
|
||||
self.center_pos = self.enemy_last_seen_pos
|
||||
self.center_pos.y = self.safe_altitude
|
||||
|
||||
local v
|
||||
if self.speed_is_0 then
|
||||
v = 0
|
||||
else
|
||||
v = self.search_velocity
|
||||
end
|
||||
|
||||
printf( "heli_combat:search_setup_flight SetMaxVelocity=%d", v )
|
||||
self.heliObject:SetMaxVelocity( v )
|
||||
self.heliObject:SetSpeedInDestPoint( v )
|
||||
|
||||
printf( "heli_combat:search_setup_flight GoPatrolByRoundPath" )
|
||||
self.heliObject:GoPatrolByRoundPath( self.center_pos, self.search_attack_dist, self.flight_direction )
|
||||
self.heliObject:LookAtPoint( self.enemy:position(), true )
|
||||
end
|
||||
|
||||
function heli_combat:search_update_shooting( see_enemy )
|
||||
if see_enemy then
|
||||
if self.search_begin_shoot_time then
|
||||
if self.search_begin_shoot_time < time_global() then
|
||||
self.heliObject:SetEnemy( self.enemy )
|
||||
end
|
||||
else
|
||||
self.search_begin_shoot_time = time_global() + search_shoot_delay
|
||||
end
|
||||
else
|
||||
self.heliObject:ClearEnemy()
|
||||
|
||||
self.search_begin_shoot_time = nil
|
||||
end
|
||||
end
|
||||
|
||||
function heli_combat:search_update_flight( see_enemy )
|
||||
-- îñòàíàâëèâàòüñÿ è âîçîáíîâëÿòü äâèæåíèå âðåìÿ îò âðåìåíè
|
||||
if self.change_speed_time < time_global() then
|
||||
local t
|
||||
t = math.random( 8000, 12000 )
|
||||
self.change_speed_time = time_global() + t
|
||||
|
||||
self.speed_is_0 = not self.speed_is_0
|
||||
|
||||
-- self.flight_direction = not self.flight_direction
|
||||
self:search_setup_flight( self.flight_direction )
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
-- ïåðèîäè÷åñêè ïðîâåðòü, íå ïåðåìåñòèëñÿ ëè âðàã è äîñòàòî÷íî ëè ó âåðòîë¸òà çäîðîâüÿ
|
||||
if self.change_pos_time < time_global() then
|
||||
self.change_pos_time = time_global() + 2000
|
||||
|
||||
if not self.can_forget_enemy and
|
||||
distance_2d( self.object:position(), self.enemy_last_seen_pos ) <= self.search_attack_dist
|
||||
then
|
||||
self.can_forget_enemy = true
|
||||
end
|
||||
|
||||
if distance_2d( self.center_pos, self.enemy_last_seen_pos ) > 10 then
|
||||
printf( "heli_combat: enemy has changed his position" )
|
||||
|
||||
self:search_setup_flight( self.flight_direction )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function heli_combat:search_update( see_enemy )
|
||||
if not self.search_initialized then
|
||||
self:search_initialize()
|
||||
end
|
||||
|
||||
-- printf( "heli_combat: search_update" )
|
||||
|
||||
self:search_update_shooting( see_enemy )
|
||||
self:search_update_flight ( see_enemy )
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------------
|
||||
-- Ôóíöèèè äëÿ áîÿ ñ ïðîë¸òàìè íàä öåëüþ
|
||||
----------------------------------------------------------------------------------------------
|
||||
function heli_combat:flyby_initialize()
|
||||
self:flyby_set_initial_state()
|
||||
|
||||
self.state_initialized = false
|
||||
self.was_callback = false
|
||||
self.flyby_states_for_one_pass = 2
|
||||
self.flyby_initialized = true
|
||||
|
||||
printf( "heli_combat:flyby_initialize SetMaxVelocity=%d", self.max_velocity )
|
||||
self.heliObject:SetMaxVelocity( self.max_velocity )
|
||||
self.heliObject:SetSpeedInDestPoint( self.max_velocity )
|
||||
self.heliObject:LookAtPoint( dummy_vector, false )
|
||||
end
|
||||
|
||||
function heli_combat:flyby_set_initial_state()
|
||||
-- if self.object:position():distance_to( self.enemy_last_seen_pos ) < self.flyby_attack_dist then
|
||||
if distance_2d( self.object:position(), self.enemy_last_seen_pos ) < self.flyby_attack_dist then
|
||||
-- self.heliObject:LookAtPoint( dummy_vector, false )
|
||||
|
||||
self.state = flyby_state_to_attack_dist
|
||||
else
|
||||
-- self.heliObject:LookAtPoint( self.enemy:position(), true )
|
||||
|
||||
self.state = flyby_state_to_enemy
|
||||
end
|
||||
end
|
||||
|
||||
function heli_combat:flyby_update_flight( see_enemy )
|
||||
if self.was_callback then
|
||||
if self.state == flyby_state_to_attack_dist then
|
||||
printf( "switch state -> ENEMY" )
|
||||
self.state = flyby_state_to_enemy
|
||||
|
||||
elseif self.state == flyby_state_to_enemy then
|
||||
printf( "switch state -> DIST" )
|
||||
self.state = flyby_state_to_attack_dist
|
||||
end
|
||||
|
||||
self.was_callback = false
|
||||
self.state_initialized = false
|
||||
end
|
||||
|
||||
if self.state == flyby_state_to_attack_dist then
|
||||
if not self.state_initialized then
|
||||
local p = self:calc_position_in_radius( self.flyby_attack_dist )
|
||||
-- printf( "heli_combat:flyby_update_flight 1 SetDestPosition %f %f %f", p.x, p.y, p.z )
|
||||
self.heliObject:SetDestPosition( p )
|
||||
|
||||
self.heliObject:ClearEnemy()
|
||||
|
||||
self.change_combat_type_allowed = false
|
||||
|
||||
self.state_initialized = true
|
||||
end
|
||||
|
||||
elseif self.state == flyby_state_to_enemy then
|
||||
if not self.state_initialized then
|
||||
self.heliObject:SetEnemy( self.enemy )
|
||||
self.heliObject:UseFireTrail( true )
|
||||
|
||||
self.flyby_states_for_one_pass = self.flyby_states_for_one_pass - 1
|
||||
|
||||
self.state_initialized = true
|
||||
end
|
||||
|
||||
local p = self.enemy_last_seen_pos
|
||||
p:set( p.x, self.safe_altitude, p.z )
|
||||
|
||||
self.change_combat_type_allowed = distance_2d( self.object:position(), p ) > self.search_attack_dist
|
||||
|
||||
-- printf( "heli_combat:flyby_update_flight 2 SetDestPosition %f %f %f", p.x, p.y, p.z )
|
||||
self.heliObject:SetDestPosition( p )
|
||||
end
|
||||
end
|
||||
|
||||
function heli_combat:flyby_update( see_enemy )
|
||||
if not self.flyby_initialized then
|
||||
self:flyby_initialize()
|
||||
end
|
||||
|
||||
-- printf( "heli_combat: flyby_update" )
|
||||
|
||||
self:flyby_update_flight( see_enemy )
|
||||
|
||||
-- printf( "speed in dest point %d", self.heliObject:GetSpeedInDestPoint(0) )
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------------
|
||||
-- Ôóíöèèè äëÿ óëåòàíèÿ çà ïðåäåëû óðîâíÿ
|
||||
----------------------------------------------------------------------------------------------
|
||||
function heli_combat:retreat_initialize()
|
||||
self.retreat_initialized = true
|
||||
|
||||
self.heliObject:SetMaxVelocity( self.max_velocity )
|
||||
self.heliObject:SetSpeedInDestPoint( self.max_velocity )
|
||||
self.heliObject:LookAtPoint( dummy_vector, false )
|
||||
self.heliObject:SetDestPosition( self:calc_position_in_radius( 5000 ) )
|
||||
self.heliObject:ClearEnemy()
|
||||
end
|
||||
|
||||
function heli_combat:retreat_update()
|
||||
if not self.retreat_initialized then
|
||||
self:retreat_initialize()
|
||||
end
|
||||
|
||||
-- printf( "heli_combat: retreat_update" )
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue