Перейти к контенту
Bak

AI additions

Рекомендуемые сообщения

27.10.2020 в 12:03, UriZzz сказал:

@андрей дронав, адаптация ai add есть, на счёт оружейного пака - учите матчасть.

Спасибо за добрый совет. Матчасть это совсем не моё. Уже пробовал. 

Ссылка на комментарий
09.03.2020 в 18:52, DarkSnowder сказал:

На АМК адаптацию ни видел ни разу.

У него же свое есть. По описанию - то же самое, и в комплекте, ЕМНИП.

Полезное... всегда храни при себе.


Подарки

  • Ссылка на комментарий

    So I found a fix for the flashlight bug, it was from OGSM. However I still do not know how to fix the NPC walking. Would anyone know where I should look to fix this? Here is a video of it: https://youtu.be/WRXSTGPG1II

    ---------------------

    Итак, я нашел исправление ошибки фонарика, оно было от OGSM. Однако я до сих пор не знаю, как исправить ходьбу NPC. Кто-нибудь знает, где я должен это исправить? Вот видео об этом:

    Изменено пользователем Опричник
    перевод
    Ссылка на комментарий

    @Bak 

    Несколько предложений по поводу исправления оригинальных недоработок схем AI.

    1) Неписи после потери цели из виду идут к тому месту, где последний раз ее видели, сбиваются в кучу и смотрят в стену/пол/потолок с криками: "Выходи, все равно найдем".

    Предложение: либо заставить нпс походить/побегать вокруг этого места, или включать что-то типа post-combat.

    2) Реагирование неписей на несуществующую (или уже несуществующую) или далекую опасность по типу компании Петрухи, когда они разбегаются по сторонам и сидят целясь куда-то, хотя рядом опасностей нет. Часто такое происходит после сохранения-загрузки.

    Не знаю, пофиксено ли это в AI additions 2.

    3) Неписи даже при получении урона не меняют позиции, не говоря уже при попадании рядом с ними.

    Предложение: был один мод на ЗП от Pavlov - Клондайк MOD, в нем была схема avoid headshot. С ней вражеские неписи отбегали в сторону, если им на голову навести прицел (курсор). Возможно на основе этой идеи можно улучшить схему боевки при перестрелке неписей с игроком. То есть, если непись видит игрока и игрок навел прицел на тушку непися, то нпс начинает маневрировать или уходить в укрытие. Хотя, по идее надо брать некоторый радуис вокруг прицела игрока.

    При перестрелке неписей с неписями, если правильно понимаю, просто проверка видят ли неписи друг друга и в зависимости от результатов - маневрировать, уходить в укрытие итд.

    В боевке ОГСЕ такие условия:

    Скрытый текст

    if (npc:see(be) and (be:see(npc) or raytrace_see)) or (is_armor(be) and get_armor_vis(be, npc)) then             -- если видим врага и он видит нас            -- стреляем, ищем укрытие
    ...
    elseif (npc:see(be) and not (be:see(npc) or raytrace_see)) or (is_armor(be) and not get_armor_vis(be, npc)) then        -- если видим врага и он НЕ видит нас        -- стреляем, маневрируя
    ...
    elseif not npc:see(be) and (be:see(npc) or raytrace_see) then        -- если НЕ видим врага и он видит нас        -- убегаем, ищем укрытие
    ...
    else                                            -- если НЕ видим врага и он НЕ видит нас    -- ищем врага


    ЗЫ Стоит ли ожидать доработки схем xr_camper, xr_danger итд из Prosectors Project в AI Additions? 

    • Согласен 1
    Ссылка на комментарий

    @=300zx= Немного несвоевременные предложения, с учетом последнего обновления в 2017 году. Ожидать нечего, разработка прекращена.


    Подарки

  • Ссылка на комментарий

    @=300zx= Я не использовал версию выше 25.10.2009, но сбивание неписей в кучу там вроде правится. Возможно грешит адаптация - либо конфликт с другой схемой аи.

    Ссылка на комментарий
    3 часа назад, gam сказал(а):

    25.10.2009

    Эта версия значительно уступает 2.0, как качеством исполнения, так и составом, и жива только потому, что 2.0 сложнее адаптируется. Дальнейшим развитием проекта потребовало движковых правок, что в конец убивало совместимость.

    Эволюция Ai Additions продолжилась в рамках Prosectors Project

    • Спасибо 2
    • Нравится 1
    • Полезно 1

    Подарки

  • Ссылка на комментарий
    17.01.2021 в 03:37, Bak сказал(а):

    Эта версия значительно уступает 2.0, как качеством исполнения, так и составом, и жива только потому, что 2.0 сложнее адаптируется. Дальнейшим развитием проекта потребовало движковых правок, что в конец убивало совместимость.

    Эволюция Ai Additions продолжилась в рамках Prosectors Project

    Конечно так и есть, а версии 2.ххх я использовал конечно - но исключительно для чистой ТЧ, и ради фана. Что касается версии от 25.10.2009, я просто еще давно проникся к ней симпатией и на мой взгляд свой фукционал она выполняет сполна и без особых нареканий. И спасибо, что подтолкнули скачать Prosectors Project, все руки никак не доходили, хотя с самого старта проекта хотелось попользоваться разработкой. Теперь попробую наконец-то.:)

     

    Адаптация адаптирована на мой взгляд без особого напряга для извилин.:)

    • Нравится 1
    Ссылка на комментарий
    16.01.2021 в 23:08, gam сказал(а):

    @=300zx= Я не использовал версию выше 25.10.2009, но сбивание неписей в кучу там вроде правится. Возможно грешит адаптация - либо конфликт с другой схемой аи.

    Это баг c оригинала ТЧ.

    @Bak , насчет адаптаций, в OGSM v2.4.3 в move_mgr.script есть правка от RED75 на проверку доступности хоть одной точки на пути. Совместима ли она с правками move_mgr из AI Additions 2?
     

    Скрытый текст
    
    -- Movement manager
    -- Created by: Andrey Fidrya (Zmey), af@svitonline.com
    
    function printf()
    end
    
    local dist_walk = 10 -- < dist_run
    local dist_run = 2500
    
    local walk_min_time = 3000
    local run_min_time = 2000
    
    local keep_state_min_time = 1500 -- переключившись в состояние (бег, ходьба, спринт), не переключаться в другое N ms
    
    local default_wait_time = 5000
    local default_state_standing = "guard"
    local default_state_moving1 = "patrol"
    local default_state_moving2 = "rush"
    local default_state_moving3 = "sprint"
    
    arrival_before_rotation = 0
    arrival_after_rotation = 1
    
    local state_none = 0
    local state_moving = 1
    local state_standing = 2
    
    local sync = {}
    -------------------------------------------------------------------------------------------------------------------------
    function choose_look_point(patrol_look, path_look_info, search_for)
    	local this_val -- значение флагов текущей точки
    	local pts_found_total_weight = 0 -- количество найденных точек (с нужными флагами)
    	local pt_chosen_idx = nil -- индекс выбранной точки
    	local r
    	local num_equal_pts = 0
    	for look_idx = 0, patrol_look:count() - 1 do
    		this_val = path_look_info[look_idx].flags
    		if this_val:equal(search_for) then
    			num_equal_pts = num_equal_pts + 1
    			-- Нашли точку с нужными флагами, но поскольку в пути могут быть еще такие-же
    			-- точки, возьмем текущую только с некоторой вероятностью:
    			-- Шанс, с которым на точку посмотрит персонаж:
    			local point_look_weight = path_look_info[look_idx]["p"]
    			if point_look_weight then
    				point_look_weight = tonumber(point_look_weight)
    			else
    				point_look_weight = 100 -- по умолчанию у всех точек вес = 100
    			end
    			pts_found_total_weight = pts_found_total_weight + point_look_weight
    			r = math.random(1, pts_found_total_weight)
    			if r <= point_look_weight then
    				pt_chosen_idx = look_idx
    			end
    		end
    	end
    	return pt_chosen_idx, num_equal_pts
    end
    
    -------------------------------------------------------------------------------------------------------------------------
    class "move_mgr"
    function move_mgr:__init(npc)
    	if npc == nil then
    		abort("move_mgr:__init() - npc is nil, please update the script")
    	end
    	self.object = npc
    end
    
    function move_mgr:initialize(npc)
    	if npc ~= nil then
    		abort("Wrong arguments passed to move_mgr:initialize(), please update the script")
    	end
    	--printf("move_mgr:initialize()")
    
    	self.object:set_callback(callback.patrol_path_in_point, self.waypoint_callback, self)
    end
    --' Удостоверяется, что пути и флажки на них проставлены корректно
    function move_mgr:validate_paths()
    	if self.no_validation then
    		return
    	end
    	local patrol_walk_count = self.patrol_walk:count()
    	if patrol_walk_count == 1 then
    		if self.path_walk_info[0].flags:get() == 0 then
    			abort("object '%s': path_walk '%s' has 1 waypoint, but has no flags",
    				self.object:name(), self.path_walk)
    		end
    	end
    end
    
    function move_mgr:extrapolate_callback(npc)
    	self.can_use_get_current_point_index = true
    	self.current_point_init_time = time_global()
    	self.current_point_index = self.object:get_current_point_index()
    end
    
    function move_mgr:standing_on_terminal_waypoint()
    	if self.patrol_walk ~= nil then 
    		for idx = 0, self.patrol_walk:count() - 1 do
    			if utils.stalker_at_waypoint(self.object, self.patrol_walk, idx) and
    		   	self.patrol_walk:terminal(idx) then
    				return true, idx
    			end
    		end
    	end
    	return false
    end
    
    --' Может быть вызвано внешним скриптом после вызова reset() и до вызова finalize()
    --' Возвращает true, если персонаж прибыл в конечную точку пути
    function move_mgr:at_terminal_waypoint()
    	return self.at_terminal_waypoint_flag
    end
    
    --' Из move_cb вернуть true, чтобы приостановить работу схемы. Чтобы продолжить движение,
    --' нужно вызвать метод set_movement_state, который включит перемещение по вейпоинтам с нужной
    --' скоростью.
    function move_mgr:reset(path_walk, path_walk_info, path_look, path_look_info, team, suggested_state, move_cb_info, no_validation, continue, use_default_sound)
    	--printf("move_mgr:reset() [%s]", self.object:name())
    
    	--' сколько ждать в точке, где играем анимацию 
    	self.pt_wait_time = default_wait_time
    
    	--' Запоминаем массив целиком на случай, если придется себя сбросить, повторно
    	--' вызвав reset():
    	self.suggested_state = suggested_state
    	--' После этого распарсиваем массив:
    	if not suggested_state then
    		self.default_state_standing = default_state_standing
    		self.default_state_moving1 = default_state_moving1
    		self.default_state_moving2 = default_state_moving2
    		self.default_state_moving3 = default_state_moving3
    	else
    		self.default_state_standing = if_then_else(suggested_state.standing, suggested_state.standing, default_state_standing)
    		self.default_state_moving1 = if_then_else(suggested_state.moving1, suggested_state.moving1, default_state_moving1)
    		self.default_state_moving2 = if_then_else(suggested_state.moving2, suggested_state.moving1, default_state_moving2)
    		self.default_state_moving3 = if_then_else(suggested_state.moving3, suggested_state.moving1, default_state_moving3)
    	end
    
    	--' С момента включения схемы должна пройти как минимум секунда, прежде чем
    	--' проверять состояние синхронизации с другими сталкерами (иначе после лоада
    	--' они могут не успеть заспавниться).
    	self.syn_signal_set_tm = time_global() + 1000
    	self.syn_signal = nil
    
    	self.move_cb_info = move_cb_info
    	 
    	--' Возможные изменения
    	--' Изменилась команда
    	if team ~= self.team then
    		self.team = team
    		if self.team then
    			local s = sync[self.team]
    			if not s then
    				sync[self.team] = {}
    				s = sync[self.team]
    			end
    			s[self.object:id()] = false -- not synchronized
    		end
    	end
    
    	--' Изменились пути
    	if self.path_walk ~= path_walk or self.path_look ~= path_look then
    
    		self.no_validation = no_validation
    		
    		self.path_walk = path_walk		
    		self.patrol_walk = patrol(path_walk)
    		if not self.patrol_walk then
    			abort("object '%s': unable to find path_walk '%s' on the map",
    				self.object:name(), path_walk)
    		end
    		if not path_walk_info then
    			abort("object '%s': path_walk ('%s') field was supplied, but path_walk_info field is nil",
    				self.object:name(), path_walk)
    		end
    		self.path_walk_info = path_walk_info
    
    		if path_look then
    			if not path_look_info then
    				abort("object '%s': path_look ('%s') field was supplied, but path_look_info field is nil",
    					self.object:name(), path_look)
    			end
    			self.patrol_look = patrol(path_look)
    			if not self.patrol_look then
    				abort("object '%s': unable to find path_look '%s' on the map",
    					self.object:name(), path_look)
    			end
    		else
    			self.patrol_look = nil
    		end		
    		self.path_look = path_look
    		self.path_look_info = path_look_info
    
    		self:validate_paths()
    
    		self.at_terminal_waypoint_flag = false
    
    		self.cur_state_standing = self.default_state_standing
    		self.cur_state_moving = self.default_state_moving1
    
    		self.retval_after_rotation = nil
    		self.sound_after_anim_start = nil
    
    		--' Пока этот флаг не станет true (он будет установлен в extrapolate_callback), нельзя использовать
    		--' значение, которое возвращает get_current_point_index().
    		self.can_use_get_current_point_index = false
    		self.current_point_index = nil
    		self.walk_until = time_global() + walk_min_time
    		self.run_until = time_global() + walk_min_time + run_min_time
    		self.keep_state_until = time_global()
    
    
    		self.last_index = nil
    		self.last_look_index = nil
    
    		self.use_default_sound = use_default_sound
    
    		self.object:patrol_path_make_inactual()
    	end
    	self:setup_movement_by_patrol_path()
    end
    
    -- Red75 --
    local safe_pp=
    {
      l01_escape="esc_specnaz_way3",
      l02_garbage="gar_psevdowounded_gar_way_spy"
    }
    
    -- Проверяем доступность хоть одной точки на пути. Иначе возвращаем другой путь
    function validate_accessibility(npc,ppname)
      local pp=patrol(ppname)
      local valid=false
      if pp then
        for i=0,pp:count()-1 do
          if npc:accessible(pp:level_vertex_id(i)) then
            valid=true
            break
          end
        end
      end
      if valid then
        return true,ppname
      else
        return false,safe_pp[level.name()] or "none"
      end
    end
    -- Red75 --
    
    --' продолжить движение со следующей точки, а не с ближайшей.
    --' состояние move manager-a не сбрасывается.
    function move_mgr:continue()
    	--printf("_bp: object '%s': continue moving", self.object:name())
    	self:setup_movement_by_patrol_path()
    end
    
    function move_mgr:setup_movement_by_patrol_path()
    -- Red75 --
      local valid=validate_accessibility(self.object,self.path_walk)
      if valid then
        self.object:set_path_type(game_object.patrol_path)
      else
        self.object:set_path_type(game_object.level_path)
      end
    	self.object:set_detail_path_type(move.line)
    
      if valid then
      	if self.current_point_index then
      		self.object:set_start_point(self.current_point_index)
      		self.object:set_patrol_path(self.path_walk, patrol.next,    patrol.continue, true)
      	else
      		self.object:set_patrol_path(self.path_walk, patrol.nearest, patrol.continue, true)
      	end
      else
        -- путь недоступен. отправляем в ближайшую доступную точку
        pp=patrol(self.path_walk)
        if pp and pp:count()>0 then
          utils.send_to_nearest_accessible_vertex(self.object,pp:level_vertex_id(0))
        end
      end
    -- Red75 --
    
    	self.state = state_moving
    
    	local is_term, idx = self:standing_on_terminal_waypoint()
    	if is_term then
    		--printf("_bp: object '%s': TERMINAL WAYPOINT", self.object:name())
    		-- Стоим на терминальной вершине пути  - сразу иммитировать прибытие
    		self:waypoint_callback(self.object, nil, idx)
    	else
    		-- Реально идем в вершину
    		self:update_movement_state()
    	end
    
    	local sect = self.object:section()
    
    	if self.use_default_sound then
    		self.default_sound = "state"
    
    		xr_sound.set_sound(self.object, self.default_sound)
    	else
    		self.default_sound = nil
    	end
    end
    
    function move_mgr:arrived_to_first_waypoint()
    	return self.last_index ~= nil
    end
    
    
    --' Проверка синхронизации с остальными солдатами на пути.
    --' Возвращает true, если дальнейшее движение разрешено.
    function move_mgr:sync_ok()
    	if self.team then
    		local s = sync[self.team]
    		local self_id = self.object:id()
    		
    		for k, v in pairs(s) do
    			local obj = level.object_by_id(k)
    			if obj and obj:alive() then
    				if v ~= true then
    					return false
    				end
    			else
    				sync[self.team][k] = nil
    			end
    		end
    	end
    	return true
    end
    
    function move_mgr:update()
    	--printf("move_mgr:update(self.state == %s)", utils.to_str(self.state))
    	--printf("move_mgr:update(self.object:anims == %d)", self.object:animation_count())
    	
    	if self.syn_signal and time_global() >= self.syn_signal_set_tm then
    		if self:sync_ok() then
    			self:scheme_set_signal(self.syn_signal)
    			self.syn_signal = nil
    		end
    	end
    	
    	if self.can_use_get_current_point_index and not self:arrived_to_first_waypoint() then
    		local t = time_global()
    		if t >= self.keep_state_until then
    			self.keep_state_until = t + keep_state_min_time
    
    			local cur_pt = self.current_point_index
    			-- self.patrol_walk здесь по идее то же самое, что вернет patrol(self.object:patrol()),
    			-- поэтому использую его для оптимизации.
    			local dist = self.object:position():distance_to(self.patrol_walk:point(cur_pt))
    			--printf("_bp: move_mgr: distance to destination waypoint: %d", dist)
    			if dist <= dist_walk or t < self.walk_until then
    				self.cur_state_moving = self.default_state_moving1
    			elseif dist <= dist_run or t < self.run_until then
    				self.cur_state_moving = self.default_state_moving2
    			else
    				self.cur_state_moving = self.default_state_moving3
    			end
    			self:update_movement_state()
    		end
    		return
    	end
    end
    
    function move_mgr:finalize(npc)
    	xr_sound.set_sound(self.object, nil)
    	if self.team then
    		sync[self.team][self.object:id()] = nil
    	end
    	-- чтобы избежать дальнейшего движения по пути при установке рестрикторов
    	self.object:set_path_type(game_object.level_path)
    end
    
    --'-----------------------------------------------------------------------------
    --' IMPLEMENTATION
    --'-----------------------------------------------------------------------------
    function move_mgr:update_movement_state()
    	--printf("%s UPDATE movement state", self.object:name())
    	state_mgr.set_state(self.object, self.cur_state_moving, nil, nil, nil)
    end
    
    function move_mgr:update_standing_state(look_pos, snd)
    	--printf("_bp [%s]: update_standing_state: snd='%s', pt_wait_time = %s", self.object:name(), utils.to_str(snd), utils.to_str(self.pt_wait_time))
    	state_mgr.set_state(self.object, self.cur_state_standing,
    		{ obj = self, func = self.time_callback, turn_end_func = self.turn_end_callback },
    		self.pt_wait_time,
    		{ look_position = look_pos },
    		nil,
    		snd )
    end
    
    function move_mgr:time_callback()
    	--printf("_bp [%s]: time_callback", self.object:name())
    	local sigtm = self.path_look_info[self.last_look_index]["sigtm"]
    	if sigtm then
    		self:scheme_set_signal(sigtm)
    	end
    	--' Если нет активной схемы - игнорировать.
    	if db.storage[self.object:id()].active_scheme == nil then
    		return
    	end
    	if self.last_index and self.patrol_walk:terminal(self.last_index) then
    		if utils.stalker_at_waypoint(self.object, self.patrol_walk, self.last_index) then
    			--' Если стоим на конечной точке пути и с нее никуда не сдвинулись,
    			--' сразу иммитируем callback на прибытие, чтобы включить look.
    			self:waypoint_callback(self.object, nil, self.last_index)
    			return
    		end
    		--' Стоим на конечной точке пути, но неточно. Чтобы вернуться на ближайшую
    		--' точку пути, сбрасываем схему. Обратите внимаине, что здесь нельзя
    		--' просто вызвать update_movement_state, потому что мы УЖЕ были в
    		--' конечной точке пути и дальше идти некуда, а reset_scheme сбросит
    		--' настройки movement manager-а и выберет ближайшую точку, куда и пойдет.
    		self:reset(self.path_walk, self.path_walk_info,
    			self.path_look, self.path_look_info,
    			self.team,
    			self.suggested_state,
    			self.move_cb_info,
    			self.no_validation)
    	else
    		self:update_movement_state() -- идти дальше
    		local syn = self.path_look_info[self.last_look_index]["syn"]
    		if syn then
    			abort("object '%s': path_walk '%s': syn flag used on non-terminal waypoint",
    				self.object:name(), self.path_walk)
    		end
    	end
    end
    
    function move_mgr:scheme_set_signal(sig)
    	local npc_id = self.object:id()
    	local stor = db.storage[npc_id]
    	--printf("_bp: object '%s': move_mgr: scheme_set_signal '%s', active scheme '%s'", self.object:name(), sig, utils.to_str(stor.active_scheme))
    	if stor ~= nil and stor[stor.active_scheme] ~= nil then
    		local signals = stor[stor.active_scheme].signals
    		if signals ~= nil then
    		   signals[sig] = true
    		end   
    	end	
    end
    
    function move_mgr:turn_end_callback()
    	local syn = self.path_look_info[self.last_look_index]["syn"]
    	if syn then
    		self.syn_signal = self.path_look_info[self.last_look_index]["sig"]
    		if not self.syn_signal then
    			abort("object '%s': path_look '%s': syn flag uset without sig flag", self.object:name(), self.path_look)
    		end
    
    		-- Отметить, что мы сами уже прибыли в точку синхронизации:		
    		if self.team then
    			sync[self.team][self.object:id()] = true
    		end
    
    	else
    		local sig = self.path_look_info[self.last_look_index]["sig"]
    		if sig then
    			self:scheme_set_signal(sig)
    		end
    	end
    
    	local anim_synced_snd = nil
    	if self.sound_after_anim_start then
    		-- Проиграть звук сразу после окончания поворота:
    		anim_synced_snd = self.sound_after_anim_start
    		self.sound_after_anim_start = nil
    	end
    
    	if self.retval_after_rotation then
    		if not self.move_cb_info then
    			abort("object '%s': path_look '%s': ret flag is set, but " ..
    				"callback function wasn't registered in move_mgr:reset()",
    				self.object:name(), self.path_look)
    		end
    		--' Отключаем таймер путем установки того же самого состояния, но без таймера,
    		--' затем вызываем callback.
    		--' Если callback вернул false, т.е. решил не вмешиваться в перемещение,
    		--' то включаем опять таймер.
    		--' Если callback вернул true - не восстанавливаем таймер т.к. это могли сделать в
    		--' самом callback-е.
    		
    		--' 1) Отключаем таймер
    		state_mgr.set_state(self.object, self.cur_state_standing, nil, nil, nil)
    		--' 2) Вызываем callback
    		if not self.move_cb_info then
    			abort("object '%s': path_look '%s': ret flag is set, but " ..
    				"callback function wasn't registered in move_mgr:reset()",
    				self.object:name(), self.path_look)
    		end
    
    		if self.move_cb_info.func(self.move_cb_info.obj, this.arrival_after_rotation, self.retval_after_rotation, self.last_index)
    		then
    			--' Callback решил перехватить управление перемещением, не восстанавливаем таймер
    			return
    		end
    		--' Callback не перехватил управление, нужно восстановить таймер:
    		local look_pos = self.patrol_look:point(self.last_look_index)
    		self:update_standing_state(look_pos, anim_synced_snd)
    	end
    end
    
    function move_mgr:waypoint_callback(obj, action_type, index)
    	--printf("move_mgr:waypoint_callback(): name=%s, index=%d", self.object:name(), index)
    	
    	if index == -1 or index == nil then
    		--printf("ERROR: move_mgr: waypoint_callback: index is -1 or nil")
    		return
    	end
    
    	self.last_index = index
    
    	if self.patrol_walk:terminal(index) then
    		self.at_terminal_waypoint_flag = true
    	end
    
    	--' <ЗВУК>
    	local suggested_snd = self.path_walk_info[index]["s"]
    	if suggested_snd then
    		local snd_prob = self.path_walk_info[index]["sp"]
    		if snd_prob then
    			snd_prob = tonumber(snd_prob)
    		else
    			snd_prob = 100
    		end
    	
    		if snd_prob == 100 or snd_prob >= math.random(1, 100) then
    			xr_sound.set_sound(self.object, suggested_snd)
    		else
    			xr_sound.set_sound(self.object, nil)
    		end
    	else
    		xr_sound.set_sound(self.object, self.default_sound)
    	end
    	--' </ЗВУК>
    
    	local suggested_state_moving = self.path_walk_info[index]["a"]
    	if suggested_state_moving then
    		self.cur_state_moving = suggested_state_moving
    	else
    		self.cur_state_moving = self.default_state_moving1
    	end
    
    	local retv = self.path_walk_info[index]["ret"]
    	if retv then
    		local retv_num = tonumber(retv)
    		
    		if not self.move_cb_info then
    			abort("object '%s': path_walk '%s': ret flag is set, but " ..
    				"callback function wasn't registered in move_mgr:reset()",
    				self.object:name(), self.path_walk)
    		end
    		if self.move_cb_info.func(self.move_cb_info.obj, this.arrival_before_rotation, retv_num, index) then
    			return
    		end
    	end
    
    	local sig = self.path_walk_info[index]["sig"]
    	if sig then
    		self:scheme_set_signal(sig)
    	end
    
    	local stop_probability = self.path_walk_info[index]["p"]
    	
    	if not self.patrol_look or
    	   (stop_probability and tonumber(stop_probability) < math.random(1, 100)) then
    		self:update_movement_state() --' идти дальше
    		return
    	end
    
    	-- Значение флагов точки, которую будем искать:
    	local search_for = self.path_walk_info[index].flags
    
    	if search_for:get() == 0 then
    		self:update_movement_state() --' идти дальше
    		return
    	end
    
    	local pt_chosen_idx, num_equal_pts = choose_look_point(self.patrol_look, self.path_look_info, search_for)
    	--printf("_bp [%s]: pt_chosen_idx = %s", self.object:name(), utils.to_str(pt_chosen_idx))
    	if pt_chosen_idx then
    		local suggested_anim_set = self.path_look_info[pt_chosen_idx]["a"]
    		if suggested_anim_set then
    			self.cur_state_standing = suggested_anim_set
    		else
    			self.cur_state_standing = self.default_state_standing
    		end
    
    		local suggested_wait_time = self.path_look_info[pt_chosen_idx]["t"]
    		if suggested_wait_time then
    			if suggested_wait_time == '*' then
    				self.pt_wait_time = nil -- -1
    			else
    				local tm = tonumber(suggested_wait_time)
    				if tm ~= 0 and (tm < 1000 or tm > 30000) then
    					abort("object '%s': path_look '%s': flag 't': incorrect time specified (* or number in interval [1000, 30000] is expected)",
    						self.object:name(), self.path_look)
    				end
    				self.pt_wait_time = tm
    			end
    		else
    			self.pt_wait_time = default_wait_time
    		end
    
    		local retv = self.path_look_info[pt_chosen_idx]["ret"]
    		if retv then
    			self.retval_after_rotation = tonumber(retv)
    		else
    			self.retval_after_rotation = nil
    		end
    
    		if not suggested_snd then -- в path_walk звук не задан, проверить, задан ли он на точке
    			suggested_snd = self.path_look_info[pt_chosen_idx]["s"]
    			if suggested_snd then
    				local snd_prob = self.path_look_info[pt_chosen_idx]["sp"]
    				if snd_prob then
    					snd_prob = tonumber(snd_prob)
    				else
    					snd_prob = 100
    				end
    				
    				if snd_prob == 100 or snd_prob >= math.random(1, 100) then
    					--xr_sound.set_sound(self.object, nil, true)
    					self.sound_after_anim_start = suggested_snd
    				else
    					self.sound_after_anim_start = nil
    				end
    			end
    		end
    
    		local look_pos = self.patrol_look:point(pt_chosen_idx)
    		self.last_look_index = pt_chosen_idx
    		self:update_standing_state(look_pos, self.sound_after_anim_start)
    
    		self.state = state_standing
    
    		--' Сразу же стартовать update, не ждать execute. Тогда, если мы уже смотрим
    		--' в нужную сторону - не будет паузы в несколько миллисекунд на поворот.
    		self:update()
    	else
    		abort("object '%s': path_walk '%s', index %d: cannot find corresponding point(s) on path_look '%s'",
    			self.object:name(), tostring(self.path_walk), tostring(index), tostring(self.path_look))
    	end
    end
    

     

     

    Ссылка на комментарий
    45 минут назад, =300zx= сказал(а):

    Это баг c оригинала ТЧ.

    100%.

    45 минут назад, =300zx= сказал(а):

    насчет адаптаций, в OGSM v2.4.3 в move_mgr.script есть правка от RED75

    ЕМНИП подработать необходимость есть - это для сталкеров на вышках для спасения от выброса.

    Изменено пользователем gam
    Ссылка на комментарий
    19.01.2021 в 23:35, gam сказал(а):

    ЕМНИП подработать необходимость есть - это для сталкеров на вышках для спасения от выброса.

    Подработка не требуется, извиняюсь что ввожу в заблуждение. В версии ai_add_shoc_2.0f4 неполадок с OGSM v2.4.3 нет.

    Ссылка на комментарий

    В общем пытался адаптировать на мод Апокалипсис. Но дело в том, что там стоит старая версия AI Additions. Надеюсь у кого-то получится.

    Ссылка на комментарий

    @Space.Marine Активировать легко - раскомментировать соответствующие строки в скрипте. Но работать будет только, если части будут лежать непосредственно в трупе животного, как в тч и чн.

    • Спасибо 1

    Подарки

  • Ссылка на комментарий
    25 минут назад, Bak сказал(а):

    соответствующие строки в скрипте

    xr_corpse_detection.script ?
     

    Скрытый текст

    Здесь ?
     

    local can_loot_mutant = false    -- = PR.loot_mutant and (not knife_req or npc:item_in_slot(knife_slot))

     

    Здесь ?

     

    --[=[
    function chik(npc,act)

    ..........

    и анимации:

     

    --    loot_monster = { [0] = { chik,"cr_all_7_attack_2",get_all_from_corpse }, bodystate = move.crouch, weapon = "strapped"},

    --    loot_monster_knife = { [0] = { chik,"cr_all_5_attack_1",chik,{"cr_all_5_attack_0","cr_all_5_attack_1"},"cr_all_7_attack_2",get_all_from_corpse }, bodystate = move.crouch, weapon = "knife"},

     

     

     

     

    Изменено пользователем Space.Marine
    Добавлено Bak,

    Да. И в ltx конфиге еще разрешить

    Ссылка на комментарий

    ТЧ 1.0006 на OGSR Engine с гитхаба. Заметил, что гранаты, которые кидают неписи не взрываются. В частности, нахожусь внутри помещения, неписи пытаются закидывать гранаты в окна, видимо не попадают и гранаты не взрываются. Наблюдал такое продолжительное время, было брошено не менее десятка грен и ни одного взрыва. Может кто сталкивался с подобным? Это фишка или баг? 

    • Смешно 1
    Ссылка на комментарий

    @Space.Marine точно не фишка. Скорее всего сбой произошёл при создании новой игры.

    Ссылка на комментарий
    48 минут назад, warwer сказал(а):

    точно не фишка.

    Просто, касаемо подствольных выстрелов - в моде же есть защита от "дурака", вот и подумал, что это как-то и к ручным гранатам относится.

    Ссылка на комментарий

    @Space.Marine,

    единственное, что я знаю про гранаты, так у них есть рандомная задержка на взрывание (к примеру, 3-5 сек), но есть ли она в работах этой темы, не знаю.

    Я так понимаю, что брошенные гранаты ты видел на земле? 

    ed_rez.gif

    c1f11b67ff360413e81b4e4dcf21eb41.jpg


    Подарки

  • 2
  • Ссылка на комментарий

    Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий

    Комментарии могут оставлять только зарегистрированные пользователи

    Создать аккаунт

    Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!

    Зарегистрировать новый аккаунт

    Войти

    Есть аккаунт? Войти.

    Войти
    • Недавно просматривали   0 пользователей

      Ни один зарегистрированный пользователь не просматривает эту страницу.

    AMK-Team.ru

    ×
    ×
    • Создать...