KASIMKA 0 Опубликовано 5 Сентября 2011 Доброго времени суток! Делал квест, неудачным завершением которого, была бы полная зачистка военными лагеря новичков на Кордоне. Столкнулся с проблемой: нпс не хотят заходить в некоторые дома дальше крыльца (пути много раз менял и перепроверял). Судя по имеющейся у меня информации - там нет ai-сетки. Возможно ли их туда провести, не прибегая к редактированию уровня? Видел, как некоторые люди сталкивались с "противоположной" проблемой: нпс ходили через стены, вроде как при указании неправильных level- и game- vertex'ов. Заранее спасибо! Поделиться этим сообщением Ссылка на сообщение
KASIMKA 0 Опубликовано 8 Сентября 2011 Доброго времени суток! Переписываю схему heli hunter: в функции evaluator_shoot:evaluate() делаю проверку на огневую мощь НПС, при выполнении условия отправляю их в укрытие. if self.fire_power < 3 then self.object:set_detail_path_type(move.line) self.object:set_path_type(game_object.level_path) local hide,lvid = nearest_hide(self.object) utils.send_to_nearest_accessible_vertex(self.object,lvid) state_mgr.set_state(self.object,"sprint") return false end --[[------------------------------------------------------------------------------------------------------------------ Схема "Охотник за вертолётами" Чугай Александр --------------------------------------------------------------------------------------------------------------------]] local def_attack_dist = 200 -- расстояние, на котором вертолёт может быть атакован local def_actor_dist = 50 -- расстояние, на котором игрок может быть атакован function get_nearest_heli(npc_position, attack_dist_sqr) -- print_table(db.heli) local heli = nil for k,v in pairs(db.heli) do if v:position():distance_to_sqr(npc_position) <= attack_dist_sqr and (heli == nil or v:position():distance_to_sqr(npc_position) < heli:position():distance_to_sqr(npc_position)) then heli = v end end return heli end --------------------------------------------------------------------------------------------------------------------- -- Эвалуатор свойства "можно пострелять по вертолёту" --------------------------------------------------------------------------------------------------------------------- local overrides class "evaluator_shoot" ( property_evaluator ) function evaluator_shoot:__init( name, a ) super( nil, name ) self.a = a end function evaluator_shoot:evaluate() if self.delay and self.delay >= time_global() then return false end self.a.heli = get_nearest_heli(self.object:position(), self.a.attack_dist_sqr) self.fire_power = heli_target.get_target_priority(self.object) if self.a.heli == nil then self.delay = time_global() + 500 return false end --проверка на группировку if db.storage[self.a.heli:id()].community ~= nil and (db.storage[self.a.heli:id()].community == self.object:character_community()) then return false end --Проверка на огневую мощь if self.fire_power < 3 then self.object:set_detail_path_type(move.line) self.object:set_path_type(game_object.level_path) hide,lvid,dist = blowout_scheme.nearest_hide(self.object) utils.send_to_nearest_accessible_vertex(self.object,lvid) state_mgr.set_state(self.object,"sprint") return false end -- Проверка на то, что вертолет еще живой. if not bind_heli.is_heli_alive(self.a.heli) then self.a.heli = nil return false end -- проверка не потерялся ли вертолет. -- if db.heli[self.a.heli:id()] ~= nil and -- printf( "dist=%d", self.a.heli:position():distance_to_sqr(self.object:position()) ) if self.a.heli:position():distance_to_sqr(self.object:position()) > self.a.attack_dist_sqr then self.a.heli = nil return false end -- Проверка на то, что враг-игрок не подошел слишком близко local best_enemy = self.object:best_enemy() if best_enemy and best_enemy:id() == db.actor:id() then if db.actor:position():distance_to_sqr(self.object:position()) < self.a.attack_actor_sqr then return false end end -- Проверка на то, что денжер-игрок не подошел слишком близко local best_danger = self.object:best_danger() if best_danger then local bd_object = best_danger:object() if bd_object ~= nil and bd_object:id() == db.actor:id() then if best_danger:position():distance_to_sqr(self.object:position()) < self.a.attack_actor_sqr then return false end end end return true end ---------------------------------------------------------------------------------------------------------------------- -- Действие "стрелять по вертолёту" ---------------------------------------------------------------------------------------------------------------------- class "action_shoot" ( action_base ) function action_shoot:__init( name, a ) super ( nil, name ) self.a = a end function action_shoot:initialize() action_base.initialize( self ) end function action_shoot:execute() action_base.execute( self ) state_mgr.set_state( self.object, "threat_fire", nil, nil, {look_object = self.a.heli}, nil, nil, {yaw_delta=10} ) end function action_shoot:finalize() action_base.finalize( self ) --self.fire_power = nil self.camp = nil self.need_cover = nil self.object:movement_enabled(true) end ---------------------------------------------------------------------------------------------------------------------- function add_to_binder( npc, ini, scheme, section, storage ) printf( "DEBUG: add_to_binder: scheme='%s'", scheme ) local manager = npc:motivation_action_manager() manager:add_evaluator( xr_evaluators_id.chugai_heli_hunter_base, evaluator_shoot( "heli_hunter", storage ) ) local action = this.action_shoot( "action_shoot", storage ) action:add_precondition( world_property(stalker_ids.property_alive, true ) ) action:add_precondition( world_property(xr_evaluators_id.chugai_heli_hunter_base, true ) ) action:add_effect ( world_property(xr_evaluators_id.chugai_heli_hunter_base, false ) ) manager:add_action( xr_actions_id.chugai_heli_hunter_base, action ) action = manager:action( xr_actions_id.alife ) action:add_precondition( world_property( xr_evaluators_id.chugai_heli_hunter_base, false ) ) action = manager:action( stalker_ids.action_combat_planner ) action:add_precondition( world_property( xr_evaluators_id.chugai_heli_hunter_base, false ) ) action = manager:action( stalker_ids.action_danger_planner ) action:add_precondition( world_property( xr_evaluators_id.chugai_heli_hunter_base, false ) ) end function set_scheme( npc, ini, scheme, section ) printf( "DEBUG: set_scheme: scheme='%s' section='%s'", scheme, utils.to_str(section) ) local a = xr_logic.assign_storage_and_bind( npc, ini, scheme, section ) a.attack_dist_sqr = math.pow( utils.cfg_get_number( ini, section, "dist", npc, false, def_attack_dist ), 2 ) a.attack_actor_sqr = math.pow( utils.cfg_get_number( ini, section, "actor_dist", npc, false, def_actor_dist ), 2 ) a.heli = nil a.enabled = true end function disable_scheme(npc, scheme) local st = db.storage[npc:id()][scheme] if st then st.enabled = false end end НПС бегут в укрытие, но когда вертолет улетает\взрывается НПС так и остаются там стоять пока с ними не поговоришь. Как вернуть НПС под свою изначальную логику (или что я делаю неправильно)? Поделиться этим сообщением Ссылка на сообщение
KASIMKA 0 Опубликовано 9 Сентября 2011 (изменено) Пытаюсь подредактировать схему heli hunter. В своем предыдущем посте я пытался вызвать реакцию НПС на вертолет прямо из эвалуатора. Т.к. это неправильно - перенес действия в action: если раньше они хотя бы убегали, то теперь стеляют по вертолету вообще игнорируя условия: --[[------------------------------------------------------------------------------------------------------------------ Схема "Охотник за вертолётами" Чугай Александр --------------------------------------------------------------------------------------------------------------------]] local def_attack_dist = 200 -- расстояние, на котором вертолёт может быть атакован local def_actor_dist = 50 -- расстояние, на котором игрок может быть атакован function get_nearest_heli(npc_position, attack_dist_sqr) -- print_table(db.heli) local heli = nil for k,v in pairs(db.heli) do if v:position():distance_to_sqr(npc_position) <= attack_dist_sqr and (heli == nil or v:position():distance_to_sqr(npc_position) < heli:position():distance_to_sqr(npc_position)) then heli = v end end return heli end --------------------------------------------------------------------------------------------------------------------- -- Эвалуатор свойства "можно пострелять по вертолёту" --------------------------------------------------------------------------------------------------------------------- local overrides class "evaluator_shoot" ( property_evaluator ) function evaluator_shoot:__init( name, a ) super( nil, name ) self.a = a end function evaluator_shoot:evaluate() if self.delay and self.delay >= time_global() then return false end self.a.heli = get_nearest_heli(self.object:position(), self.a.attack_dist_sqr) --провека на существование вертолета if self.a.heli == nil then self.delay = time_global() + 500 self.hide = nil return false end --проверка на группировку if db.storage[self.a.heli:id()].community ~= nil and (db.storage[self.a.heli:id()].community == self.object:character_community()) then return false end -- проверка на то, что вертолет еще живой. if not bind_heli.is_heli_alive(self.a.heli) then self.a.heli = nil return false end self.fire_power = heli_target.get_target_priority(self.object) --Проверка на огневую мощь if self.fire_power < 3 then self.hide = true --return false end -- проверка не потерялся ли вертолет. -- if db.heli[self.a.heli:id()] ~= nil and -- printf( "dist=%d", self.a.heli:position():distance_to_sqr(self.object:position()) ) if self.a.heli:position():distance_to_sqr(self.object:position()) > self.a.attack_dist_sqr then self.a.heli = nil return false end -- Проверка на то, что враг-игрок не подошел слишком близко local best_enemy = self.object:best_enemy() if best_enemy and best_enemy:id() == db.actor:id() then if db.actor:position():distance_to_sqr(self.object:position()) < self.a.attack_actor_sqr then return false end end -- Проверка на то, что денжер-игрок не подошел слишком близко local best_danger = self.object:best_danger() if best_danger then local bd_object = best_danger:object() if bd_object ~= nil and bd_object:id() == db.actor:id() then if best_danger:position():distance_to_sqr(self.object:position()) < self.a.attack_actor_sqr then return false end end end return true end ---------------------------------------------------------------------------------------------------------------------- -- Действие "стрелять по вертолёту" ---------------------------------------------------------------------------------------------------------------------- class "action_shoot" ( action_base ) function action_shoot:__init( name, a ) super ( nil, name ) self.a = a end function action_shoot:initialize() action_base.initialize( self ) end function action_shoot:execute() action_base.execute( self ) if self.hide == true then self.object:set_detail_path_type(move.line) self.object:set_path_type(game_object.level_path) hide,lvid,dist = blowout_scheme.nearest_hide(self.object) utils.send_to_nearest_accessible_vertex(self.object,lvid) state_mgr.set_state(self.object,"sprint") else state_mgr.set_state( self.object, "threat_fire", nil, nil, {look_object = self.a.heli}, nil, nil, {yaw_delta=10} ) end end function action_shoot:finalize() action_base.finalize( self ) self.fire_power = nil self.camp = nil self.hide = nil self.object:movement_enabled(true) end ---------------------------------------------------------------------------------------------------------------------- function add_to_binder( npc, ini, scheme, section, storage ) printf( "DEBUG: add_to_binder: scheme='%s'", scheme ) local manager = npc:motivation_action_manager() manager:add_evaluator( xr_evaluators_id.chugai_heli_hunter_base, evaluator_shoot( "heli_hunter", storage ) ) local action = this.action_shoot( "action_shoot", storage ) action:add_precondition( world_property(stalker_ids.property_alive, true ) ) action:add_precondition( world_property(xr_evaluators_id.chugai_heli_hunter_base, true ) ) action:add_effect ( world_property(xr_evaluators_id.chugai_heli_hunter_base, false ) ) manager:add_action( xr_actions_id.chugai_heli_hunter_base, action ) action = manager:action( xr_actions_id.alife ) action:add_precondition( world_property( xr_evaluators_id.chugai_heli_hunter_base, false ) ) action = manager:action( stalker_ids.action_combat_planner ) action:add_precondition( world_property( xr_evaluators_id.chugai_heli_hunter_base, false ) ) action = manager:action( stalker_ids.action_danger_planner ) action:add_precondition( world_property( xr_evaluators_id.chugai_heli_hunter_base, false ) ) end function set_scheme( npc, ini, scheme, section ) printf( "DEBUG: set_scheme: scheme='%s' section='%s'", scheme, utils.to_str(section) ) local a = xr_logic.assign_storage_and_bind( npc, ini, scheme, section ) a.attack_dist_sqr = math.pow( utils.cfg_get_number( ini, section, "dist", npc, false, def_attack_dist ), 2 ) a.attack_actor_sqr = math.pow( utils.cfg_get_number( ini, section, "actor_dist", npc, false, def_actor_dist ), 2 ) a.heli = nil a.enabled = true end function disable_scheme(npc, scheme) local st = db.storage[npc:id()][scheme] if st then st.enabled = false end end function get_target_priority(obj) if not obj then return 0 end --qqq(obj:section()) local prior = 1 if IsMonster(obj) then -- qqq("monster") prior = 1 elseif IsStalker(obj) then -- максимум - 5 local wpn = obj:item_in_slot(obj:active_slot()) if wpn then local ammo, fm if system_ini():line_exist(wpn:section(), "ammo_class") then ammo = system_ini():r_string(wpn:section(), "ammo_class") if (string.find(ammo, "9x18") -- пистолетные патроны or string.find(ammo, "9x19") or string.find(ammo, "7.62x25") or string.find(ammo, "11.43x23") or string.find(ammo, "357") or string.find(ammo, "samopal") -- + патроны к самопалу or string.find(ammo, "bolt") -- + арбалетные болты or string.find(ammo, "12x7")) -- + патроны для дробовиков then prior = prior + 1 elseif (string.find(ammo, "5.45x39") -- промежуточные патроны or string.find(ammo, "5.56x45") or string.find(ammo, "7.62x39") or string.find(ammo, "9x39")) then prior = prior + 2 elseif (string.find(ammo, "7.62x51") -- винтовочные патроны or string.find(ammo, "7.62x54") or string.find(ammo, "7.92x75")) then prior = prior + 3 else prior = prior + 4 end end if system_ini():line_exist(wpn:section(), "fire_modes") then fm = system_ini():r_string(wpn:section(), "fire_modes") if string.sub(fm,-2,-1) == "-1" then prior = prior + 1 -- автоматическое оружие - приоритет цели выше на 1 end end --qqq(wpn:section()) end elseif string.find(obj:name(),"btr") then prior = 6 elseif (string.find(obj:section(),"helicopter") or string.find(obj:section(),"mi2")) then prior = 7 end --qqq(prior) return prior end Или, если я неправильно выбрал путь решения проблемы - подскажите, как переключить НПС на схему выброса (без выброса) при виде вертолета, если у них нечем в него стрелять, т.е. чтобы НПС вели себя точно также как при выбросе, завидев вертолет? Заранее спасибо! Используйте тэги для вывода участков с кодами, дабы сохранялось форматирование (отступы) и не искажались иные символы --/ Artos Изменено 9 Сентября 2011 пользователем Artos Поделиться этим сообщением Ссылка на сообщение