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

266 lines
9.6 KiB
Text

--[[----------------------------------------------------------------------------------------------------------
Áîåâàÿ ñõåìà ñòàëêåðîâ ãðóïïèðîâêè "Ìîíîëèò"
×óãàé Àëåêñàíäð
------------------------------------------------------------------------------------------------------------]]
local base = xr_evaluators_id.combat_monolith_base
local prop_enable = base + 0
local prop_see = base + 1
local prop_close = base + 2
local prop_on_pos = base + 3
base = xr_actions_id.combat_monolith_base
local act_fight_close = base + 0
local act_fight_far = base + 1
local act_look_around = base + 2
local act_go_to_pos = base + 3
--------------------------------------------------------------------------------------------------------------
class "evaluator_combat_monolith" ( property_evaluator )
function evaluator_combat_monolith:__init( name, storage ) super ( nil, name )
self.st = storage
end
function evaluator_combat_monolith:evaluate()
return db.storage[self.object:id()].script_combat_type == "monolith"
end
--------------------------------------------------------------------------------------------------------------
class "evaluator_see" ( property_evaluator )
function evaluator_see:__init( name, storage ) super ( nil, name )
self.st = storage
end
function evaluator_see:evaluate()
local be = self.object:best_enemy()
if self.object:alive() and be and self.object:see( be ) then
self.st.last_seen_vert_id = be:level_vertex_id()
return true
else
return false
end
end
--------------------------------------------------------------------------------------------------------------
class "evaluator_close" ( property_evaluator )
function evaluator_close:__init( name, storage ) super ( nil, name )
self.st = storage
self.close_dist_sqr = math.random( 20*20, 35*35 )
end
function evaluator_close:evaluate()
local be = self.object:best_enemy()
return be ~= nil and self.object:position():distance_to_sqr( be:position() ) < self.close_dist_sqr
end
--------------------------------------------------------------------------------------------------------------
class "evaluator_on_pos" ( property_evaluator )
function evaluator_on_pos:__init( name, storage ) super ( nil, name )
self.st = storage
end
function evaluator_on_pos:evaluate()
local r = self.object:level_vertex_id() == self.st.last_seen_vert_id
--printf( tostring( r ) )
return r
end
--------------------------------------------------------------------------------------------------------------
class "action_fight_close" ( action_base )
function action_fight_close:__init( name, storage ) super ( nil, name )
self.st = storage
end
function action_fight_close:initialize()
action_base.initialize( self )
state_mgr.set_state( self.object, "hide_fire", nil, nil, { look_object = self.object:best_enemy() } )
end
function action_fight_close:execute()
action_base.execute( self )
end
function action_fight_close:finalize()
action_base.finalize( self )
end
-- Âíèìàíèå: âûçûâàåòñÿ âî âñåõ actions
function action_fight_close:hit_callback( obj, amount, local_direction, who, bone_index )
if who == nil then
return
end
local be = self.object and self.object:best_enemy()
-- åñëè ïîëó÷èëè õèò îò òåêóùåãî âðàãà, òî ìû çíàåì, ãäå îí
if be and who:id() == be:id() then
self.st.last_seen_vert_id = be:level_vertex_id()
end
end
--------------------------------------------------------------------------------------------------------------
class "action_fight_far" ( action_base )
function action_fight_far:__init( name, storage ) super ( nil, name )
self.st = storage
end
function action_fight_far:initialize()
action_base.initialize( self )
-- self.object:set_node_evaluator ()
-- self.object:set_path_evaluator ()
self.object:set_desired_direction ()
self.object:set_desired_position ()
self.object:set_detail_path_type ( move.line )
self.object:set_path_type ( game_object.level_path )
state_mgr.set_state( self.object, "assault_fire", nil, nil, { look_object = self.object:best_enemy() } )
end
function action_fight_far:execute()
action_base.execute( self )
utils.send_to_nearest_accessible_vertex( self.object, self.object:best_enemy():level_vertex_id() )
end
function action_fight_far:finalize()
action_base.finalize( self )
end
--------------------------------------------------------------------------------------------------------------
class "action_look_around" ( action_base )
function action_look_around:__init( name, storage ) super ( nil, name )
self.st = storage
end
function action_look_around:initialize()
action_base.initialize( self )
self.forget_time = time_global() + 30000
self.change_dir_time = 0
end
function action_look_around:execute()
action_base.execute( self )
if self.forget_time < time_global() then
printf("pl:Disabling_memory_object[9]")
-- self.object:enable_memory_object( self.object:best_enemy(), false )
self.st.last_seen_vert_id = nil
return
end
if self.change_dir_time < time_global() then
self.change_dir_time = time_global() + math.random( 1000, 2000 )
local ang = math.rad( math.random( 0, 359 ) )
local pos = self.object:position():add( vector():set( math.cos( ang ), 0, math.sin( ang ) ) )
state_mgr.set_state( self.object, "hide", nil, nil, { look_position = pos } )
end
end
function action_look_around:finalize()
action_base.finalize( self )
end
--------------------------------------------------------------------------------------------------------------
class "action_go_to_pos" ( action_base )
function action_go_to_pos:__init( name, storage ) super ( nil, name )
self.st = storage
self.t = {}
end
function action_go_to_pos:initialize()
action_base.initialize( self )
if not self.st.last_seen_vert_id then
self.st.last_seen_vert_id = self.object:best_enemy():level_vertex_id()
end
-- self.object:set_node_evaluator ()
-- self.object:set_path_evaluator ()
self.object:set_desired_direction ()
self.object:set_desired_position ()
self.object:set_detail_path_type ( move.line )
self.object:set_path_type ( game_object.level_path )
state_mgr.set_state( self.object, "assault" )
self.cached_id = -1
end
function action_go_to_pos:execute()
action_base.execute( self )
if self.st.last_seen_vert_id ~= self.cached_id then
self.cached_id = self.st.last_seen_vert_id
self.st.last_seen_vert_id = utils.send_to_nearest_accessible_vertex( self.object, self.cached_id )
end
end
function action_go_to_pos:finalize()
action_base.finalize( self )
end
--------------------------------------------------------------------------------------------------------------
function add_to_binder( npc, ini, st, planner )
--[[ planner:add_evaluator( xr_evaluators_id.combat_monolith_base, evaluator_combat_monolith( "combat_monolith", st ) )
local action = action_zombie_shoot( "action_zombie_shoot", st )
action:add_precondition( world_property( xr_evaluators_id.combat_monolith_base, true ) )
action:add_effect ( world_property( stalker_ids.property_enemy, false ) )
planner:add_action( xr_actions_id.combat_monolith_base, action )]]
planner:add_evaluator( prop_enable, evaluator_combat_monolith( "combat_monolith", st ) )
planner:add_evaluator( prop_see, evaluator_see ( "combat_monolith_see", st ) )
planner:add_evaluator( prop_close, evaluator_close ( "combat_monolith_close", st ) )
planner:add_evaluator( prop_on_pos, evaluator_on_pos ( "combat_monolith_on_pos", st ) )
local action = action_fight_close( "combat_monolith_fight_close", st )
action:add_precondition( world_property( stalker_ids.property_alive, true ) )
action:add_precondition( world_property( stalker_ids.property_enemy, true ) )
action:add_precondition( world_property( stalker_ids.property_anomaly, false ) )
action:add_precondition( world_property( xr_evaluators_id.script_combat, true ) )
action:add_precondition( world_property( prop_enable, true ) )
action:add_precondition( world_property( prop_see, true ) )
action:add_precondition( world_property( prop_close, true ) )
action:add_effect ( world_property( stalker_ids.property_enemy, false ) )
planner:add_action( act_fight_close, action )
-- ïîäïèñûâàåì îäèí, ðàáîòàåò âî âñåõ!
xr_logic.subscribe_action_for_events( npc, st, action )
action = action_fight_far( "combat_monolith_fight_far", st )
action:add_precondition( world_property( stalker_ids.property_anomaly, false ) )
action:add_precondition( world_property( prop_close, false ) )
action:add_precondition( world_property( prop_see, true ) )
action:add_effect ( world_property( prop_close, true ) )
planner:add_action( act_fight_far, action )
action = action_look_around( "combat_monolith_look_around", st )
action:add_precondition( world_property( stalker_ids.property_anomaly, false ) )
action:add_precondition( world_property( prop_on_pos, true ) )
action:add_precondition( world_property( prop_see, false ) )
action:add_effect ( world_property( prop_see, true ) )
planner:add_action( act_look_around, action )
action = action_go_to_pos( "combat_monolith_go_to_pos", st )
action:add_precondition( world_property( stalker_ids.property_anomaly, false ) )
action:add_precondition( world_property( prop_on_pos, false ) )
action:add_effect ( world_property( prop_on_pos, true ) )
planner:add_action( act_go_to_pos, action )
end