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

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

@WinCap проблема оказалась весьма специфична. Когда мы грузим сейв, то xr_gulag сразу берёт на себя всех НПС, что были в работе гулага в момент сохранения. И сразу же выдаёт им работу при условии, что они не находятся дальше контрольной точки гулага больше чем на 50 игровых метров. В такмо случае все НПС в момент загрузки сейва моментально получают работу и начинают её выполнение, без возможности сдвинуться с места (за исключением патрульных, у которых зацикленный набор вейпоинтов). Пробовал отключать перехват xr_gulag'а, в таком случае нпс доходят до точных координат, но работу не начинают. Казалось бы - вот он, выход из ситуации, задать небольшой таймер, чтобы гулаг сразу не перехватывал неписей, а давал им возможность дойти до точной координаты, чтобы после красиво сесть на стульчик, например.

Но в таком случае все те НПС, которые сидели у костра, вдруг начинают одновременно ломиться в одну единственную точку, толпой. Видимо именно поэтому в ЧН были введены смарткаверы, которые, судя по всему, имели приоритет над работами гулагов типа, не знаю.

Эх

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

@_Sk8_AsTeR_ 

Откуда вообще уверенность, что перезапуск работы даст нужный результат? Ты ведь понятия не имеешь, как в движке работает алгоритм размещения моба на точке пути - что в приоритете: координата точки или аи-ноды, близкие этой координате. Точку пути ты в СДК ставил? Может она попала на границу двух аи-нод и движок периодически выбирает разные ноды для размещения объекта.

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

@AndreySol ну я проверял опытным путём. Там оказалось всё хитрее даже, чем я предполагал. Те НПС, которые приходят из вне гулага, они регистрируются и спокойно проходят к тем вейпоинтам, которые заданы в path_walk, анимация отыгрывается верно.

А вот если нпс уже занимался новой работой, мы сохранились и загрузились, то бывает такое что нпс по какой-то причине в момент загрузки сейва вдруг сместился на пару игровых метров в сторону. Но игра считает, то он стоит правильно и xr_gulag сразу же заставляет его работать ту работу, которой он занимался до сейвлоада.

Я просто ковырял хр_гулаг и отключал обработку нпс во время загрузки сейва. В этом случае тот нпс, который при загрузке сместился, действительно отправился строго в ту точку, которую я прописал в path_walk, я отслеживал этот момент прям с точностью до ноль-десятых координат с помощью g_vertex_debug (OGSR). 

Когда нпс приходит на точку он замирает, ожидая когда его обработает заранее мною отключенный xr_gulag. Ну, так и продолжает стоять. 

Выходит что именно xr_gulag и заставляет всех нпс во время загрузки сейва моментально и без вариантов сразу приниматься за работу, не давая неписям даже шаг в сторону сделать (за исключением тех нпс. у кого в path_walk цепь вейпоинтов).

Ну, по крайней мере я именно такое заключение для себя сделал, ковыряя всю эту систему. Если я где-то неправ, то поправь меня пожалуйста, буду очень признателен! :)

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

@_Sk8_AsTeR_ 

4 часа назад, _Sk8_AsTeR_ сказал(а):

в момент загрузки сейва вдруг сместился на пару игровых метров в сторону

Ну так ты должен понимать, что спавн объектов делает движок, а не xr_gulag. Соответственно бесполезно дрючить xr_gulag, пытаясь в нем разрулить движковую проблему.

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

@AndreySol Не спорю, что спавн объекта идет через движок, всё правильно. Но по поводу xr_gulag: из net_spawn при загрузке сейва идет вызов ф-ций в xr_gulag, после чего в этом же самом xr_gulag идет работа с нетпакетами, где проверяется работал ли НПС во время сейва. И если работал, то xr_gulag моментально заставляет этого НПС возобновить работату, не давая возможности сначала вернутсья на вейпоинт, если он немного сместился при сейв\лоаде. Вот что я наблюдал) 

То есть проблема именно в том, что xr_gulag просто не дает возможности НПС подойти вернуться к вейпоинту, моментально выдавая ему работу (нпс начинает играть анимацию).

Есть нпс, которые находятся вне логики гулага, а стоят на своих личных path_walk'ax и path_look'ах, прописанных в саму логику непися. Они всегда со 100% вероятностью будут правильно отыгрывать анимацию в строго заданных координатах, всегда. Если при загрузке сейва они сместятся, то они сначала вернутся на вейпоинт. Потому что их не обрабатывает xr_gulag :)

Опять таки, это всё лично мое наблюдение и мои выводы, которые я построил в результате экспериментов и изучения когда скрипта xr_gulag.

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

-- сохранения общего состояния гулага
function gulag:save_common( packet )
	packet:w_u8( self.casualities )
	packet:w_u8( self.state )
	utils.w_CTime( packet, self.stateBegin or smart_terrain.CTime_0 )

	packet:w_u8(self.population)
	packet:w_u8(self.population_comed)
	packet:w_u8(self.population_non_exclusive)

	packet:w_u8( #self.Job )

	for i, job in ipairs( self.Job ) do
		packet:w_u32( job.begin            or 0 )
		packet:w_u32( job.fill_idle        or 0 )
		packet:w_u32( job.idle_after_death_end or 0 )
	end
end

-- восстановление общего состояния гулага
function gulag:load_common( packet )
	self.casualities = packet:r_u8()
	self.state       = packet:r_u8()
	self.stateBegin  = utils.r_CTime( packet )

	self.population = packet:r_u8()
	self.population_comed = packet:r_u8()
	self.population_non_exclusive = packet:r_u8()

	local n = packet:r_u8()
	local job
	for i = 1, n do
		job = {}
		table_insert( self.JobLoaded, job )

		job.begin            = packet:r_u32()
		job.fill_idle        = packet:r_u32()
		job.idle_after_death_end = packet:r_u32()

		if job.fill_idle == 0 then job.fill_idle = nil end
		if job.idle_after_death_end == 0 then job.idle_after_death_end = nil end
	end
end

-- сохранение информации об объекте
function gulag:save_obj( packet, obj_id )
	packet:w_bool ( self.Object_begin_job[obj_id] )
	packet:w_bool ( self.Object_didnt_begin_job[obj_id] )
	packet:w_u8   ( self.ObjectJob[obj_id] or 0 )
end

-- восстановление информации об объекте
function gulag:load_obj( packet, obj_id )
	self.Object[obj_id] = true
	self.Object_begin_job[obj_id] = packet:r_bool()
	--self.Object_didnt_begin_job[obj_id] = packet:r_bool()
	local jobN = packet:r_u8()
	if jobN ~= 0 then
		self.ObjectJob[obj_id] = jobN
	end
end

 

 

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

@_Sk8_AsTeR_, а функции save_obj/load_obj из xr_gulag используются где-нибудь?

В них какой-то "непорядок" - сохраняются 3 переменные, а загружаются только 2.

Изменено пользователем WinCap

S.T.A.L.K.E.R. CoP Objects (upd 15.11.24)

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

@_Sk8_AsTeR_ , не там копаешь. Сохранение и загрузка гулага тут ни при чём. Неписи в баре сделаны с индивидуальной логикой, и они так же глючат порой. Тут либо вейпоинт-каллбэк рано срабатывает в move_mgr при загрузке, не давая неписю дойти до нужной точки, либо непись смещается уже после спавна на загрузке и срабатывания этого каллбэка. Или ещё что-то. В общем, в move_mgr смотреть надо.

Изменено пользователем naxac
  • Согласен 1
  • Полезно 2

Аддон для ОП-2.09.2: Яндекс/Google/GitHub

naxac.gif

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

Хотел добавить 2 кнопки при обыске трупов и ящиков! 1 кнопка выход(работает) в оригинале ее нету, 2 кнопка переместить всё из инвентаря ГГ в ящик\труп(не работает), нажимаю "переместить всё" результат 0 и вылетов нету. Может кто глянуть\посмотреть вот сам скрипт https://yadi.sk/d/dQ-plbh3CFkHSA

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

@Colder, в вашем скрипте:

1. Функция BodyAllclose - что это за переменная id?

2. Функция get_items_from_box - переменная box откуда?

  • Нравится 1

S.T.A.L.K.E.R. CoP Objects (upd 15.11.24)

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

Не получаеться( или мозгов не хватает!

Делаю так:

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

function transfer_all_to_box()
    local level_obj_by_id = level.object_by_id
    local box = level_obj_by_id(id)
    db.actor:iterate_inventory(function(actor, item)
    db.actor:transfer_item(item, box)
end,
    db.actor)
end

 

Звук есть что перекладывает, но не чего не происходит.

Изменено пользователем Colder
Ссылка на комментарий
7 часов назад, Colder сказал(а):

Хотел добавить 2 кнопки

Так в ЗП "взять всё" на кнопке Х забиндена, а в ТЧ легко в xml указывается кнопка на которой можно взять всё. Не проще ли посмотреть уже имеющееся в оригинале решение? Или это движковая фишка?

Изменено пользователем Space.Marine
Ссылка на комментарий

Здрасьте.

 

Задача: отсечь часть строки и преобразовать в число. При записи tonumber(str:gsub(…)) или tonumber(string.gsub(str, …)) вылет "bad argument #2 to 'tonumber' (base out of range)", при раздельной обработке ожидаемый результат – число. В чем причина?

Spoiler

local str = "abc_123"

local id = tonumber( str:gsub("abc_", "") )			-- вылет
local id = tonumber( string.gsub(str, "abc_", "") )		-- вылет

local id = str:gsub("abc_", "")
id = tonumber(id)						-- ок

 

 

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

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

Приветствую! Есть простой вопрос - как в скрипте получить сытость актора (ОП 2.1)?

- вариант 1: log(db.actor:get_satiety()) -- вызывает краш - нет такого метода!

- вариант 2: log(db.actor.satiety) -- тут всегда nil

- вариант 3: ?

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

@Norman Eisenherz , вторым аргументом в tonumber передаётся основание системы счисления (двоичная - 2, шестнадцатиричная -16 и т.д). string.gsub же вторым аргументом возвращает количество замен. Тут нужно отсечь второй аргумент, например так:

tonumber( (string.gsub(str, …)) )

  • Полезно 1

Аддон для ОП-2.09.2: Яндекс/Google/GitHub

naxac.gif

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

@phalcor Сытость – свойство, так что 2-й вариант правильный, но он не привязан в скриптах: в ТЧ/ЧН всегда дает nil, в ЗП всегда дает 1.

  • Спасибо 1

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

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

Есть у кого нибуть пример как вывести в гуи окне, полоску состояния оружия?

Есть вот такая фунция но незнаю как её использовать:

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

function repair_dialog:DrawConditionRemBar(de_item, x, y)
    if x == nil then x = 0 end
    if y == nil then y = 0 end
    local cond_rem_bar_width = 0
    if de_item then
    cond_rem_bar_width = (math.floor(de_item:condition()*100)*1.1)
    x = x - 55 --(cond_rem_bar_width/2)
    local c = self.cond_rem_bar
    if not c then
    self.cond_rem_bar = CUIStatic()
    c = self.cond_rem_bar
    c:SetWindowName("cond_rem_bar")
    c:SetAutoDelete(true)
    c:InitTexture("ui\\cop\\ui_cop_hint_wnd")
    c:SetOriginalRect(678,153,110,7)
    c:SetStretchTexture(true)
    self:AttachChild(c)
end
    if cond_rem_bar_width > 109 then cond_rem_bar_width = 109
    elseif cond_rem_bar_width <= 0 then cond_rem_bar_width = 1 end
    c:SetOriginalRect(677+cond_rem_bar_width,153,1,7)
    c:Init(x,y,cond_rem_bar_width,7)
    else
    c:Init(0,0,0,0)
end
end

 

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

@Colder мне кажется, лучше использовать уже готовое.

 

1. описать progress bar в xml. Например

  <bar_frame1 x="47" y="164" width="100" height="8" horz="1" min="0" max="100" pos="1">
    <background>
      <texture r="196" g="18" b="18">ui_mg_progress_efficiency_full</texture>
    </background>
    <progress>
      <texture>ui_mg_progress_efficiency_full</texture>
    </progress>
    <min_color r="41" g="203" b="60"/>
    <middle_color r="41" g="203" b="60"/>
    <max_color r="41" g="203" b="60"/>
  </bar_frame1>

 

2. инициализировать его. Например

  self.item1_progress = xml:InitProgressBar( "bar_frame1", self.item1 )

 

3. установить длину. Например

  self.item1_progress:SetProgressPos( self.item:condition() * 100 )

 

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

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

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

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

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

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

Войти

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

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

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