---------------------------------------------------------------------------------------------------- -- Sleeper ---------------------------------------------------------------------------------------------------- -- Разработчик: Руслан Диденко (Stohe) ---------------------------------------------------------------------------------------------------- -- 27.12.2004 - [Zmey] Перевел схему на использование move manager. local sounds = {} local state_walking = 0 local state_sleeping = 1 --------------------------------------------------------------------------------------------------------------------- --Evaluators ---------------------------------------------------------------------------------------------------------------------- -- Константа class "evaluator_need_sleeper" (property_evaluator) function evaluator_need_sleeper:__init(name, storage) super (nil, name) self.st = storage end function evaluator_need_sleeper:evaluate () return xr_logic.is_active(self.object, self.st) end ---------------------------------------------------------------------------------------------------------------------- --Actions ---------------------------------------------------------------------------------------------------------------------- -- Обычное поведение class "action_sleeper_activity" (action_base) function action_sleeper_activity:__init (npc, action_name, storage) super(nil, action_name) self.st = storage self.move_mgr = db.storage[npc:id()].move_mgr self.was_reset = false end function action_sleeper_activity:initialize() action_base.initialize(self) -- self.object:set_node_evaluator() -- self.object:set_path_evaluator() self.object:set_desired_position() self.object:set_desired_direction() --self.state = 0 self:reset_scheme() end function action_sleeper_activity:reset_scheme() self.timer = { begin = nil, idle = nil, maxidle = 10, sumidle = 20, random = 50 } self.st.signals = {} self.state = state_walking if self.st.path_walk_info == nil then local patrol_main = patrol(self.st.path_main) if not patrol_main then abort("object '%s': unable to find path_main '%s' on the map", self.object:name(), self.st.path_main) end local num_wayp = patrol_main:count() if num_wayp == 1 then self.st.path_walk = self.st.path_main self.st.path_walk_info = utils.path_parse_waypoints_from_arglist(self.st.path_main, 1, { 0, "wp00|ret=1" } ) self.st.path_look = nil self.st.path_look_info = nil elseif num_wayp == 2 then self.st.path_walk = self.st.path_main self.st.path_walk_info = utils.path_parse_waypoints_from_arglist(self.st.path_main, 2, { 1, "wp00" }, { 0, "wp01" } ) self.st.path_look = self.st.path_main self.st.path_look_info = utils.path_parse_waypoints_from_arglist(self.st.path_main, 2, { 0, "wp00" }, { 1, "wp01|ret=1" } ) else abort("object '%s': path_main '%s' contains %d waypoints, while 1 or 2 were expected", self.object:name(), self.st.path_main, num_wayp) end end -- Последний параметр (true) отключает валидацию путей, чтобы не возникало ошибки из-за использования -- одноточечного path_walk пути без соответствующего path_look. self.move_mgr:reset(self.st.path_walk, self.st.path_walk_info, self.st.path_look, self.st.path_look_info, nil, nil, { obj = self, func = self.callback }, true ) self.was_reset = true end function action_sleeper_activity:activate_scheme() self.was_reset = false end function action_sleeper_activity:callback(mode, number) self.state = state_sleeping local position = nil if patrol(self.st.path_main):count() == 2 then position = patrol(self.st.path_main):point(1) end if self.st.wakeable then state_mgr.set_state(self.object, "sit", nil, nil, {look_position = position}) else state_mgr.set_state(self.object, "sleep", nil, nil, {look_position = position}) end return true end function action_sleeper_activity:execute() action_base.execute(self) if not self.was_reset then self:reset_scheme() end if self.state == state_walking then self.move_mgr:update() return end if self.state == state_sleeping then -- xr_sound.set_sound(self.object, "sleep") end end function action_sleeper_activity:finalize() -- xr_sound.set_sound(self.object, nil) self.move_mgr:finalize() action_base.finalize(self) end -- DEBUG --function action_sleeper_activity:deactivate() -- printf( "xr_sleeper: action_sleeper_activity: deactivate" ) --end ---------------------------------------------------------------------------------------------------------------------- --Sleeper binder ---------------------------------------------------------------------------------------------------------------------- function add_to_binder(npc, ini, scheme, section, storage) local operators = {} local properties = {} local manager = npc:motivation_action_manager() properties["need_sleeper"] = xr_evaluators_id.zmey_sleeper_base + 1 properties["state_mgr_logic_active"] = xr_evaluators_id.state_mgr + 4 operators["action_sleeper"] = xr_actions_id.zmey_sleeper_base + 1 -- -- evaluators manager:add_evaluator (properties["need_sleeper"], this.evaluator_need_sleeper ("sleeper_need_sleep", db.storage[npc:id()].sleeper)) local action = this.action_sleeper_activity(npc, "action_sleeper_activity", db.storage[npc:id()].sleeper) action:add_precondition (world_property(stalker_ids.property_alive, true)) action:add_precondition (world_property(stalker_ids.property_danger, false)) action:add_precondition (world_property(stalker_ids.property_enemy, false)) action:add_precondition (world_property(stalker_ids.property_anomaly,false)) action:add_precondition (world_property(properties["need_sleeper"], true)) xr_motivator.addCommonPrecondition(action) action:add_effect(world_property(properties["need_sleeper"], false)) action:add_effect (world_property(properties["state_mgr_logic_active"], false)) manager:add_action(operators["action_sleeper"], action) -- Зарегистрировать все actions, в которых должен быть вызван метод reset_scheme при изменении настроек схемы: xr_logic.subscribe_action_for_events(npc, storage, action) action = manager:action(xr_actions_id.alife) action:add_precondition(world_property(properties["need_sleeper"], false)) end function set_scheme(npc, ini, scheme, section, gulag_name) local st = xr_logic.assign_storage_and_bind(npc, ini, scheme, section) st.logic = xr_logic.cfg_get_switch_conditions(ini, section, npc) st.path_main = utils.cfg_get_string(ini, section, "path_main", npc, true, gulag_name) st.wakeable = utils.cfg_get_bool(ini, section, "wakeable", npc, false) st.path_walk = nil -- Будут инициализированы в reset(), сейчас пути могут быть еще не загружены. st.path_walk_info = nil st.path_look = nil st.path_look_info = nil end function is_npc_asleep(npc) return db.storage[npc:id()].state_mgr.animstate.current_state == "sleep" end