-- -- DELME -- local leader_no_command = 0 local leader_move = 1 local leader_stop = 2 local leader_speak = 3 local leader_speak_enable = 4 local leader_return = 5 local leader_free = 6 ---------------------------------------------------------------------------------------- class "evaluator_enabled" (property_evaluator) ------------- function evaluator_enabled:__init (name, storage) super (nil, name) self.a = storage end ------------- function evaluator_enabled:evaluate () return xr_logic.is_active (self.object, self.a) end ---------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------- class "evaluator_escape" (property_evaluator) ------------- function evaluator_escape:__init (name, storage) super (nil, name) self.a = storage end ------------- function evaluator_escape:evaluate () if self.a.escape_path == nil then return false end local size = #db.storage[self.object:id()].followers if size == 0 then return false end for count = 1, size, 1 do local npc_id = db.storage[self.object:id()].followers[count].npc_id local npc = db.storage[self.object:id()].followers[count].npc if is_object_online (npc_id) == false or npc == nil or npc:alive () == false then return true end end return false end ---------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------- class "evaluator_raid" (property_evaluator) ------------- function evaluator_raid:__init (name, storage) super (nil, name) self.a = storage end ------------- function evaluator_raid:evaluate () return self.a.raid_process end ---------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------- class "action_patrol" (action_base) ------------- function action_patrol:__init (name, storage) super (nil, name) self.a = storage self.move_mgr = move_mgr.move_mgr (storage.npc) self.stage = 0 self.sub_stage = 0 self.current_phrase = 0 end ------------- function action_patrol:initialize () action_base.initialize (self) self.move_mgr:initialize () self.object:set_node_evaluator() self.object:set_path_evaluator() self.object:set_desired_position() self.object:set_desired_direction() self:reset_scheme() self.stage = 0 local obj = self.object:object ("hand_radio") if obj ~= nil then --self.object:enable_attachable_item (true) --printf ("DISABLE RADIO 1") obj:enable_attachable_item (false) end self.sounds = { rnd = 100, maxidle = 1, sumidle = 0, themes = { "patrol_radio_1" }, last_num = 0 } self.sounds["seq_cnt"] = 0 end ------------- function action_patrol:execute () action_base.execute (self) if self.stage == 0 then self.move_mgr:update () --update soldier positions if self.a.raid_enabled == false then self:set_soldier_positions () else self:set_soldier_positions_raid () end --update soldier states if self.move_mgr.moving == true then self:set_command (leader_move) else self:set_command (leader_stop) end elseif self.stage == 1 then self:set_command (leader_stop) if self:process_radio () == true then self.move_mgr:update_movement_state () self.stage = 0 end end end ------------- function action_patrol:finalize () local obj = self.object:object ("hand_radio") if obj ~= nil then obj:enable_attachable_item (false) end self.move_mgr:finalize () action_base.finalize (self) end ------------- function action_patrol:reset_scheme () if self.a.path_walk_info == nil then self.a.path_walk_info = utils.path_parse_waypoints(self.a.patrol_path) end if self.a.path_look_info == nil then self.a.path_look_info = utils.path_parse_waypoints(self.a.patrol_look) end self.move_mgr:reset(self.a.patrol_path, self.a.path_walk_info, self.a.patrol_look, self.a.path_look_info, nil, nil, {obj = self, func = self.callback}) end ------------- function action_patrol:callback (mode, number) if number == 0 then self.object:clear_animations () self.object:set_movement_type (move.stand) self.object:add_animation ("raciya_0", true) self.object:add_animation ("raciya_1", true) self.object:add_animation ("raciya_2", true) self.object:set_movement_type (move.stand) printf("SET_SIGHT!!!action_patrol:callback") self.object:set_sight (look.path_dir, nil, 0) self.sub_stage = 0 self.current_phrase = 1 self.stage = 1 return true elseif number == 1 then local st = xr_gulag.isUnderFraction (self.object) if st ~= nil then xr_gulag.resetJob (st, self.object) self:set_command (leader_free) else local actor = level.actor() if actor then if xr_logic.try_switch_to_another_section (self.object, self.a, actor) then return end end end elseif number == 2 then self.a.raid_process = true end return false end ------------- function action_patrol:process_radio () local count = self.object:animation_count () if self.sub_stage == 0 and count == 2 then local obj = self.object:object ("hand_radio") if obj ~= nil then obj:enable_attachable_item (true) end end if self.sub_stage == 0 and count == 1 then self.sub_stage = 1 return false end if self.sub_stage == 1 then if count == 1 and self.sounds["seq_cnt"] < 8 then self.object:add_animation ("raciya_2", true) end if self.sounds["seq_cnt"] >= 7 then self.sub_stage = 2 self.object:clear_animations () self.object:add_animation ("raciya_3", true) self.object:add_animation ("raciya_4", true) else xr_sound.sound_update(self.object, self.sounds) end return false end if self.sub_stage == 2 and count == 1 then local obj = self.object:object ("hand_radio") if obj ~= nil then obj:enable_attachable_item (false) end end if count ~= 0 then return false end return true end ------------- function action_patrol:set_soldier_positions () local size = #db.storage[self.object:id()].followers if size == 0 then return end local dir = self.object:direction () dir.y = 0.0 dir:normalize () local step = 180.0 / size local angle = 90.0 for a = 1, size, 1 do if a == 1 then angle = angle + step * 0.5 else angle = angle + step end local vec = vector_rotate_y (dir, angle) db.storage[self.object:id()].followers[a].direction = vec db.storage[self.object:id()].followers[a].distance = 3.0 end end ------------- function action_patrol:set_soldier_positions_raid () local size = #db.storage[self.object:id()].followers if size == 0 then return end local dir = self.object:direction () dir.y = 0.0 dir:normalize () local dist = 5.0 local side = false local v = vector ():set (0, 0, 0) for count = 1, size, 1 do if side == false then v = vector_rotate_y (dir, -90.0) side = true else v = vector_rotate_y (dir, 90.0) side = false end db.storage[self.object:id()].followers[count].direction = v db.storage[self.object:id()].followers[count].distance = dist if count == 2 or count == 4 or count == 6 or count == 8 or count == 10 then dist = dist + dist end end end ------------- function action_patrol:set_command (command) local size = #db.storage[self.object:id()].followers if size == 0 then return end for a = 1, size, 1 do db.storage[self.object:id()].followers[a].leader_command = command end end --------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------- class "action_escape" (action_base) ------------- function action_escape:__init (name, storage) super (nil, name) self.a = storage end ------------- function action_escape:initialize () action_base.initialize (self) if self.a.escape_path == nil then utils.abort ("Escape path not defined for patrol soldier %s", self.object:name ()) end self.object:clear_animations () self.object:set_node_evaluator () self.object:set_path_evaluator () self.object:set_desired_position () self.object:set_desired_direction () self.object:set_item (object.activate, self.object:best_weapon ()) self.object:set_detail_path_type (move.line) self.object:set_body_state (move.standing) self.object:set_path_type (game_object.patrol_path) self.object:set_patrol_path (self.a.escape_path, patrol.nearest, patrol.continue, true) self.object:set_movement_type (move.run) self.object:set_mental_state (anim.danger) printf("SET_SIGHT!!!action_escape:initialize") self.object:set_sight (look.path_dir, nil, 0) self.object:set_callback (self, "move_callback", game_object.movement) end ------------- function action_escape:execute () action_base.execute (self) self:set_command (leader_return) end ------------- function action_escape:finalize () action_base.finalize (self) end ------------- function action_escape:move_callback (obj, action_type, index) if index == -1 then return end if patrol (self.object:patrol ()):flag (index, 0) == true then self.a.enabled = false local st = xr_gulag.isUnderFraction (self.object) if st ~= nil then xr_gulag.resetJob (st, self.object) end end end ---------------------------------------------------------------------------------------- function action_escape:set_command (command) local size = #db.storage[self.object:id()].followers if size == 0 then return end for a = 1, size, 1 do db.storage[self.object:id()].followers[a].leader_command = command end end --------------------------------------------------------------------------------------------------------------------- class "action_raid" (action_base) ------------- function action_raid:__init (name, storage) super (nil, name) self.a = storage self.move_mgr = move_mgr.move_mgr (storage.npc) end ------------- function action_raid:initialize () action_base.initialize (self) self.move_mgr:initialize () self.object:clear_animations () self.object:set_node_evaluator () self.object:set_path_evaluator () self.object:set_desired_position () self.object:set_desired_direction () self:reset_scheme () end ------------- function action_raid:execute () action_base.execute (self) self.move_mgr:update () end ------------- function action_raid:finalize () self.move_mgr:finalize () action_base.finalize (self) end ------------- function action_raid:reset_scheme () if self.a.raid_path == nil then return end if self.a.raid_walk_info == nil then self.a.raid_walk_info = utils.path_parse_waypoints(self.a.raid_path) end if self.a.raid_look_info == nil then self.a.raid_look_info = utils.path_parse_waypoints(self.a.raid_look) end self.move_mgr:reset(self.a.raid_path, self.a.raid_walk_info, self.a.raid_look, self.a.raid_look_info, self.a.team, nil, {obj = self, func = self.callback}) local id = self.object:id() local size = #db.storage[id].followers if size == 0 then return end for a = 1, size, 1 do db.storage[id].followers[a].raid_process = true --local npc = db.storage[self.object:id()].followers[a].npc --db.storage[npc:id ()].patrol.raid_process = true end end ------------- function action_raid:callback (mode, number) if number == 0 then self.a.raid_process = false self.a.raid_enabled = false return true end return false end ---------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------- function add_to_binder (npc, ini, scheme, section, storage) local operators = {} local properties = {} properties["enabled"] = xr_evaluators_id.sidor_ptr properties["escape"] = xr_evaluators_id.sidor_ptr + 1 properties["raid"] = xr_evaluators_id.sidor_ptr + 2 operators["patrol"] = xr_actions_id.sidor_act_ptr operators["escape"] = xr_actions_id.sidor_act_ptr + 1 operators["raid"] = xr_actions_id.sidor_act_ptr + 2 local manager = npc:motivation_action_manager() manager:add_evaluator (properties["enabled"], this.evaluator_enabled ("comm_ptr_enabled", storage)) manager:add_evaluator (properties["escape"], this.evaluator_escape ("comm_ptr_escape_enabled", storage)) manager:add_evaluator (properties["raid"], this.evaluator_raid ("comm_ptr_raid_enabled", storage)) local action = this.action_patrol ("patrol", storage) action:add_precondition (world_property(stalker_ids.property_alive, true)) action:add_precondition (world_property(stalker_ids.property_enemy, false)) action:add_precondition (world_property(properties["escape"], false)) action:add_precondition (world_property(properties["raid"], false)) action:add_precondition (world_property(properties["enabled"], true)) xr_motivator.addCommonPrecondition(action) action:add_effect (world_property(properties["enabled"], false)) manager:add_action (operators["patrol"], action) xr_logic.subscribe_action_for_events (npc, storage, action) action = this.action_escape ("escape", storage) action:add_precondition (world_property(stalker_ids.property_alive, true)) action:add_precondition (world_property(stalker_ids.property_enemy, false)) action:add_precondition (world_property(properties["escape"], true)) action:add_precondition (world_property(properties["raid"], false)) action:add_precondition (world_property(properties["enabled"], true)) xr_motivator.addCommonPrecondition(action) action:add_effect (world_property(properties["enabled"], false)) manager:add_action (operators["escape"], action) local action_new = this.action_raid ("raid", storage) action_new:add_precondition (world_property(stalker_ids.property_alive, true)) action_new:add_precondition (world_property(stalker_ids.property_enemy, false)) action_new:add_precondition (world_property(properties["raid"], true)) action_new:add_precondition (world_property(properties["enabled"], true)) xr_motivator.addCommonPrecondition(action_new) action_new:add_effect (world_property(properties["raid"], false)) manager:add_action (operators["raid"], action_new) xr_logic.subscribe_action_for_events (npc, storage, action_new) action = manager:action (xr_actions_id.alife) action:add_precondition (world_property(properties["enabled"], false)) --this.set_patrol (npc) 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.patrol_path = utils.cfg_get_string (ini, section, "patrol_path", npc, true, gulag_name) st.patrol_look = utils.cfg_get_string (ini, section, "patrol_look", npc, false, gulag_name) st.escape_path = utils.cfg_get_string (ini, section, "escape_path", npc, false, gulag_name) st.raid_enabled = utils.cfg_get_bool (ini, section, "raid_enabled",npc, false) st.raid_path = utils.cfg_get_string (ini, section, "raid_path", npc, false, gulag_name) st.raid_look = utils.cfg_get_string (ini, section, "raid_look", npc, false, gulag_name) st.team = utils.cfg_get_string (ini, section, "team", npc, false, gulag_name) st.path_walk_info = nil -- Будут инициализированы в reset(), сейчас пути могут еще st.path_look_info = nil -- быть не загружены. st.raid_walk_info = nil st.raid_look_info = nil st.raid_process = false end