--[[---------------------------------------------------------------------------------------------------------- Боевая схема кемпера, оторванная от поведенческой схемы кемпера. Просто сидеть и стрелять, если враг дальше какого-то расстояния Чугай Александр ------------------------------------------------------------------------------------------------------------]] local base = xr_evaluators_id.combat_camper_base local prop_enable = base + 0 local prop_see = base + 1 base = xr_actions_id.combat_camper_base local act_shoot = base + 0 local act_look_around = base + 1 -------------------------------------------------------------------------------------------------------------- class "evaluator_combat_camper" ( property_evaluator ) function evaluator_combat_camper:__init( name, storage ) super ( nil, name ) self.st = storage end function evaluator_combat_camper:evaluate() return db.storage[self.object:id()].script_combat_type == "camper" 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_pos = be:position() return true else return false end end -------------------------------------------------------------------------------------------------------------- class "action_shoot" ( action_base ) function action_shoot:__init( name, storage ) super ( nil, name ) self.st = storage end function action_shoot:initialize() action_base.initialize( self ) state_mgr.set_state( self.object, "hide_fire", nil, nil, { look_object = self.object:best_enemy() } ) self.st.camper_combat_action = true end function action_shoot:execute() action_base.execute( self ) end function action_shoot:finalize() action_base.finalize( self ) self.st.camper_combat_action = false 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.st.camper_combat_action = true self:reset() end function action_look_around:reset() self.forget_time = device():time_global() + 30000 self.change_dir_time = device():time_global() + 15000 -- если врага мы ещё не видели вообще, то всё равно повернуться к нему if not self.st.last_seen_pos and self.object:best_enemy() ~= nil then self.st.last_seen_pos = self.object:best_enemy():position() end state_mgr.set_state( self.object, "hide", nil, nil, { look_position = self.st.last_seen_pos } ) end function action_look_around:execute() action_base.execute( self ) if self.forget_time < device():time_global() then printf("pl:Disabling_memory_object[8]") -- self.object:enable_memory_object( self.object:best_enemy(), false ) self.st.last_seen_pos = nil return end if self.change_dir_time < device():time_global() then self.change_dir_time = device():time_global() + math.random( 2000, 4000 ) local ang = math.random( 0, 120 ) - 60 if self.st.last_seen_pos == nil then abort("report this error to STALKER-829 bug [%s]", self.object:name()) end local dir = vector():set( self.st.last_seen_pos ):sub( self.object:position() ) dir = vector_rotate_y( dir, ang ) state_mgr.set_state( self.object, "hide", nil, nil, { look_position = self.object:position():add( dir ) } ) end end function action_look_around:finalize() action_base.finalize( self ) self.st.last_seen_pos = nil self.st.camper_combat_action = false end -- Внимание: вызывается во всех actions function action_look_around:hit_callback( obj, amount, local_direction, who, bone_index ) if who == nil or not self.st.camper_combat_action then return end local be = self.object and self.object:best_enemy() -- если получили хит от текущего врага, то мы знаем, где он; поворачивамся к нему if be and who:id() == be:id() then -- printf( "HIT CALLBACK!!!!!!!!!" ) self.st.last_seen_pos = be:position() self:reset() end end -------------------------------------------------------------------------------------------------------------- function add_to_binder( npc, ini, st, planner ) local properties = {} properties["state_mgr_logic_active"] = xr_evaluators_id.state_mgr + 4 planner:add_evaluator( prop_enable, evaluator_combat_camper( "combat_camper", st ) ) planner:add_evaluator( prop_see, evaluator_see ( "combat_camper_see", st ) ) local action = action_shoot( "combat_camper_shoot", 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_effect ( world_property( stalker_ids.property_enemy, false ) ) action:add_effect (world_property(properties["state_mgr_logic_active"], false)) planner:add_action( act_shoot, action ) action = action_look_around( "combat_camper_look_around", st ) 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, false ) ) action:add_effect ( world_property( prop_see, true ) ) action:add_effect (world_property(properties["state_mgr_logic_active"], false)) planner:add_action( act_look_around, action ) -- подписываем один, работает во всех! xr_logic.subscribe_action_for_events( npc, st, action ) st.camper_combat_action = false end