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

AI additions


Bak

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

Для адаптации AI Additions на OGSM ТЧ, насколько я понимаю, нужно еще операторам в новых модулях прописать следующие предусловия:

    if ogsm_hideout then
        action:add_precondition(world_property(ogsm_hideout.property_blowout, false))
        action:add_precondition(world_property(ogsm_hideout.property_hideout_lost, false))
        action:add_precondition(world_property(ogsm_hideout.property_inhide, false))
        action:add_precondition(world_property(ogsm_hideout.property_psyzoned, false))
    end

    if anomaly_evader then
        action:add_precondition (world_property(1099,false))
    end

Только вот вопрос, для всех ли операторов это нужно прописывать?

Изменено пользователем =300zx=
  • Полезно 1

Поделиться этим сообщением


Ссылка на сообщение
04.08.2020 в 20:31, UriZzz сказал:

@=300zx=, ну не знаю, я адаптировал аи адд и мод на выбросы, они друг другу не мешали. Во всяком случае у меня при тестах проблем выявлено не было:508:

Явных проблем может и не будет, но для каких-то action возможно стоит добавить эти предусловия. Например, чтобы непись во время выброса не шел лутать итд.

 

В оригинальных модулях AI Additions есть закоментированные строчки для АМК-выброса:

--    if blowout_scheme and blowout_scheme.evid_outside then
--        action:add_precondition(world_property(blowout_scheme.evid_outside,false))
--    end

В OGSE, например в файле rx_gl.script, есть такие строчки:

    local action = action_launch_grenade(npc,"act_launch_grenade",storage)
    ...
    action:add_precondition(world_property(ogsm_hideout.property_blowout, false))
    action:add_precondition(world_property(ogsm_hideout.property_hideout_lost, false))
    action:add_precondition(world_property(ogsm_hideout.property_psyzoned, false))

Но в OGSE используется предыдущая версия AI Additions и не такая схема обхода аномалий как в OGSM.

  • Полезно 2

Поделиться этим сообщением


Ссылка на сообщение

@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

Поделиться этим сообщением


Ссылка на сообщение
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

 

 

Поделиться этим сообщением


Ссылка на сообщение
  • Недавно просматривали   0 пользователей

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