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

[CoP] Ковыряемся в файлах


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

@SWEAW просто мало активных специалистов по ЗП осталось, вот сюда никто и не заглядывает, а кто заглядывает - мало пишет.

Попробую сузить тебе задачу вдвое. trade_manager вообще не обновляет список продаваемых товаров. Всё, что он делает - это раз в какое-то время вычитывает из конфигурации текущий тип списка товаров, примерно такого вида: current_buy_supplies = supplies_generic, а потом методом npc:buy_supplies() передаёт его движку. Внутри движка и происходит взвешивание вероятностей появления того или иного объекта в продаже и составление конечного списка.

Могу ошибаться, конечно, но это то, как я сейчас сумел наискосок понять написанное в менеджере торговли и других связанных с этим скриптах. И если прав, то без модификации движка смену после загрузки из сейва списка торгуемых предметов не побороть.

Что же касается вывода в лог, добавь себе в _g.script в самом его конце что-то такое:

local console
to_log = function(fmt,...)
	if not console then console = get_console() end
	console:execute("load ~:"..string.format(fmt,...))
end

-- пример записи (в любом скрипте)
local st = "test"
to_log("Message: %s", st) -- где %s - место подстановки значения твоей строковой (числовой, булевой) переменной

Пример использования также приведён.

После чего смотри, чему у тебя при торговле становятся равны всякие tt.update_time, tt.resuply_time и иже с ними и думай, почему не срабатывает то, что ты делаешь.

Да, и соглашусь с @abramcumner, без логов сразу понять, что происходит, можно только в редких случаях. Поэтому прежде чем что-то под себя править, научись логировать.

  • Полезно 1
Ссылка на комментарий
6 часов назад, Kirgudu сказал:

Всё, что он делает - это раз в какое-то время вычитывает из конфигурации текущий тип списка товаров, примерно такого вида: current_buy_supplies = supplies_generic, а потом методом npc:buy_supplies() передаёт его движку.

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

Правда, если привязка к сейв-лоаду зашита в движок, то это фиаско, ибо смысл всех манипуляций с временными периодами по сути обнуляется. Я конечно читал поверхностно, что, имея исходники, можно их изменить и в visual studio скомпилить в "измененный" движок, но, во-первых, исходников OpenX-Ray я не нашел (есть репозиторий на гитхабе, но то ли он неполный, то ли его как-то особенно скачивать надо через шаманство), а во-вторых, без хоть каких-то ориентиров на где и что добавлять, тем более, с нулевыми знаниями, лезть туда будет идеей не самой светлой.

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

Хотел еще уточнить насчет примера использования логирования, вот, допустим, часть кода пресловутого trade_manager:

if tt.update_time ~= nil and tt.update_time < time_global() then
		return
	end
	tt.update_time = time_global() + 3600000

Чтобы залогировать tt.update_time должно быть так:
 

    if tt.update_time ~= nil and tt.update_time < time_global() then
        return
    end
    tt.update_time = time_global() + 3600000

    to_log("Message: %s", tt.update_time)

?

И в каком именно месте скрипта можно это прописать, конкретно вот в таких местах манипуляции с нужными переменными, или в любом месте до последнего end, кроме всяких if и for?

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

@SWEAW, пример приведён верно, но это, конечно, только один из возможных вариантов. Обычно, если хотят посмотреть, что происходит с переменной, то смотрят её значение (читай логируют) непосредственно до изменения и сразу после, перед сравнением (if) с другой переменной и перед любым использованием. Это если брать по максимуму. Естественно, если такое логирование будет в update функции, файл лога забьётся однотипными строками, но это не страшно.

А вообще, хочешь заниматься этим - экспериментируй, мы все делаем это в той или иной степени.

  • Спасибо 1
  • Согласен 1
Ссылка на комментарий
9 часов назад, SWEAW сказал:

Правда, если привязка к сейв-лоаду зашита в движок

tt.resuply_time явно движковый параметр, в скриптах он задан как= time_global() + 24*3600000 ,т.е. раз в 24 часа обновляется ассортимент , в с сейв он пишется как (tt.resuply_time - текущее время), а при лоаде к этому значению сохранённом наоборот добавляется текущее время, хотя я не помню в ЗП же вроде как и в ТЧ все равно этот баг/фича остался, что ассортимент все равно полностью обновляется при сейв-лоаде.

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

@WinCap я помню в некоторых модах на ЗП делали так что ассортимент не менялся по несколько дней в том же Дед Эйре

31 минуту назад, WinCap сказал:

Дополнительно отмечу, что причина, по которой ПЫСы закомментировали этот код, неизвестна

наверно потому и закоментили потому что это вызывало  "Если отойти подальше и сделать save/load, то он обновится", а отходить там есть куда локи то Юпитер, Затон большие

Ссылка на комментарий
2 часа назад, WinCap сказал:

И, может быть, его активация вызовет ещё какие-нибудь ошибки.

Чтобы обезопасить себя от теоретически возможных ошибок, но при этом сохранить значения таймаутов хотя бы для находящихся в онлайне торговцев, можно записать переинициализацию таблицы примерно так:

--'	if trade_manager[npc:id()] == nil then
		-- trade_manager[npc:id()] = {} -- вместо этой строки пишем нижеследующую
		trade_manager[npc:id()] = trade_manager[npc:id()] and { update_time = trade_manager[npc:id()].update_time, resuply_time = trade_manager[npc:id()].resuply_time } or {}
--'	end

 

  • Нравится 2
  • Полезно 1
Ссылка на комментарий

@WinCap спасибо за очень подробное разжевывание, попробую и это протестить.

 

А за дистанцию перехода в оффлайн\онлайн,

 

4 часа назад, WinCap сказал:

только для тех торговцев кто online. Если отойти подальше

 

насколько я помню, отвечает же радиус а-лайфа, вроде и параметр похоже называется и меняется где-то одной строчкой? Только это, как я слышал, чревато проблемами с производительностью?

 

Но если сугубо теоретически - можно же на относительно небольшой локации разместить торгаша так, чтобы при увеличенном радиусе а-лайфа и нормально работающем скрипте он и не обновлялся на ф5-ф9 в пределах уровня, и игра бы работала удобоваримо?

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

Только это, как я слышал, чревато проблемами с производительностью?

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

И на современных производительных ПК, (И я сейчас не про свой. Скромнее), сталкер в таком режиме работает даже лучше, т.к. нет лагов на загрузке объектов в онлайн, они все всегда в онлайне.

Для торговцев можно отдельным флагом серверного объекта дописать, что они должны быть в онлайне всегда, и это в любом случае проблем с производительностью не вызовет никаких, для игры это просто 1 npc.

  • Полезно 2

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

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

Не знаю, интересны ли эти попытки в "исследования", но считаю нужным подержать в курсе о том, что (не) получается в результате манипуляций.

 

9 часов назад, WinCap сказал:

Можно раскомментировать условие

 

В общем, сделал по совету, это

 

6 часов назад, Kirgudu сказал:

можно записать переинициализацию таблицы примерно так:

 

тоже добавил, логи выставил сначала только на конечные значения переменных с "_time", плюс изначально в скрипте были printf на некоторые параметры сохранения\загрузки, еще заменил-таки time_global() на game.time(), потому что эмпирическим путем получилось, что ведут они себя абсолютно одинаково (не работают и ни на что не влияют, по крайней мере исходя из конечных цифр). Потом еще зачем-то выставил логи на buy_supplies и ей подобные, хотя их значения вообще, как оказалось, про другое.

 

По итогу, скриптовая мешанина (цифры в логировании после переменных в логировании задумывались, чтобы разделить "допакетные" изменения от "пакетных", получилось.. что получилось):

 

Скрытый текст
local trade_manager = {}

function trade_init(npc, cfg)
	printf("TRADE INIT[%s]", npc:name())
	if trade_manager[npc:id()] == nil then
		trade_manager[npc:id()] = trade_manager[npc:id()] and { update_time = trade_manager[npc:id()].update_time, resuply_time = trade_manager[npc:id()].resuply_time } or {}
	end

	trade_manager[npc:id()].cfg_ltx = cfg
	trade_manager[npc:id()].config = ini_file(cfg)

	-- коэфициенты покупки
	local str = utils.cfg_get_string(trade_manager[npc:id()].config, "trader", "buy_condition", npc, true, "")
	if str == nil then
		abort("Incorrect trader settings. Cannot find buy_condition. [%s]->[%s]", npc:name(), cfg)
	end
	trade_manager[npc:id()].buy_condition = xr_logic.parse_condlist(npc, "trade_manager", "buy_condition", str)

	-- коэфициенты продажи
	str = utils.cfg_get_string(trade_manager[npc:id()].config, "trader", "sell_condition", npc, true, "")
	if str == nil then
		abort("Incorrect trader settings. Cannot find sell_condition. [%s]->[%s]", npc:name(), cfg)
	end
	trade_manager[npc:id()].sell_condition = xr_logic.parse_condlist(npc, "trade_manager", "sell_condition", str)

	-- список закупки
	str = utils.cfg_get_string(trade_manager[npc:id()].config, "trader", "buy_supplies", npc, false, "")
	if str ~= nil then
		trade_manager[npc:id()].buy_supplies = xr_logic.parse_condlist(npc, "trade_manager", "buy_supplies", str)
	end
	to_log("Definition of trade_manager[npc:id()].buy_supplies 1: %s", trade_manager[npc:id()].buy_supplies)

-- buy_item_condition_factor
	str = utils.cfg_get_string(trade_manager[npc:id()].config, "trader", "buy_item_condition_factor", npc, false, "", "0.7")
	if str ~= nil then
		trade_manager[npc:id()].buy_item_condition_factor = xr_logic.parse_condlist(npc, "trade_manager", "buy_item_condition_factor", str)
	end
end


function update(npc)
	local tt = trade_manager[npc:id()]

	if tt == nil then
		printf("TRADE [%s]:  tt is nil", npc:name())
		return
	end

	if tt.update_time ~= nil and tt.update_time < game.time() then
		return
	end
	
	tt.update_time = game.time() + 60000
	to_log("Definition of tt.update_time 1: %s", tt.update_time)

	local str = xr_logic.pick_section_from_condlist(db.actor, npc, tt.buy_condition)
	if(str=="" or str==nil) then
		abort("Wrong section in buy_condition condlist for npc [%s]!", npc:name())
	end
	if tt.current_buy_condition ~= str then
		--'printf("TRADE [%s]: buy condition = %s", npc:name(), str)
		npc:buy_condition(tt.config, str)
		tt.current_buy_condition = str
	end

	str = xr_logic.pick_section_from_condlist(db.actor, npc, tt.sell_condition)
	if(str=="" or str==nil) then
		abort("Wrong section in buy_condition condlist for npc [%s]!", npc:name())
	end
	if tt.current_sell_condition ~= str then
		printf("TRADE [%s]: sell condition = %s", npc:name(), str)
		npc:sell_condition(tt.config, str)
		tt.current_sell_condition = str
	else
		printf("TRADE [%s]: current = %s   sell = %s", npc:name(), tostring(tt.current_sell_condition), tostring(str))
	end

	str = tonumber(xr_logic.pick_section_from_condlist(db.actor, npc, tt.buy_item_condition_factor))
	if tt.current_buy_item_condition_factor ~= str then
		npc:buy_item_condition_factor(str)
		tt.current_buy_item_condition_factor = str
	end

	if tt.buy_supplies == nil then
		return
	end

	str = xr_logic.pick_section_from_condlist(db.actor, npc, tt.buy_supplies)
	if(str=="" or str==nil) then
		abort("Wrong section in buy_condition condlist for npc [%s]!", npc:name())
	end
	if tt.current_buy_supplies ~= str then
		if tt.resuply_time ~= nil and tt.resuply_time < game.time() then
			return
		end
		--'printf("TRADE [%s]: buy_supplies = %s", npc:name(), str)
		npc:buy_supplies(tt.config, str)
		tt.current_buy_supplies = str
		to_log("Definition of tt.current_buy_supplies 1 %s", tt.current_buy_supplies)
		tt.resuply_time = game.time() + 120000
		to_log("Definition of tt.resuply_time 1 %s", tt.resuply_time)
	end
end


function save(obj, packet)
	local tt = trade_manager[obj:id()]
	set_save_marker(packet, "save", false, "trade_manager")
	--' Сохраняем присутствует ли инициализированная торговля в принципе.
	if tt == nil then
		printf("TRADE SAVE [%s]: ignored", obj:name())
		packet:w_bool(false)
		return
	else
		packet:w_bool(true)
	end

	packet:w_stringZ(tt.cfg_ltx)

	printf("TRADE SAVE [%s]: current_buy_condition = %s", obj:name(), tostring(tt.current_buy_condition))
	if tt.current_buy_condition == nil then
		packet:w_stringZ("")
	else
		packet:w_stringZ(tt.current_buy_condition)
	end

	printf("TRADE SAVE [%s]: current_sell_condition = %s", obj:name(), tostring(tt.current_sell_condition))
	if tt.current_sell_condition == nil then
		packet:w_stringZ("")
	else
		packet:w_stringZ(tt.current_sell_condition)
	end

	printf("TRADE SAVE [%s]: current_buy_supplies = %s", obj:name(), tostring(tt.current_buy_supplies))
	if tt.current_buy_supplies == nil then
		packet:w_stringZ("")
	else
		packet:w_stringZ(tt.current_buy_supplies)
	end

	local cur_tm = game.time()

	if tt.update_time == nil then
		packet:w_s32(-1)
	else
	 	packet:w_s32(tt.update_time - cur_tm)
	end

	if tt.resuply_time == nil then
		packet:w_s32(-1)
	else
	 	packet:w_s32(tt.resuply_time - cur_tm)
	end
	set_save_marker(packet, "save", true, "trade_manager")
end

function load(obj, packet)
	set_save_marker(packet, "load", false, "trade_manager")
	local a = packet:r_bool()
	if a == false then
		printf("TRADE LOAD [%s]: ignored", obj:name())
		return
	end

	trade_manager[obj:id()] = {}

	local tt = trade_manager[obj:id()]

	tt.cfg_ltx = packet:r_stringZ()
	printf("TRADE LOAD [%s]: cfg_ltx = %s", obj:name(), tostring(tt.cfg_ltx))

	tt.config = ini_file(tt.cfg_ltx)

	a = packet:r_stringZ()
	printf("TRADE LOAD [%s]: current_buy_condition = %s", obj:name(), tostring(a))
	if a ~= "" then
		tt.current_buy_condition = a
		obj:buy_condition(tt.config, a)
	end

	a = packet:r_stringZ()
	printf("TRADE LOAD [%s]: current_sell_condition = %s", obj:name(), tostring(a))
	if a ~= "" then
		tt.current_sell_condition = a
		obj:sell_condition(tt.config, a)
	end

	a = packet:r_stringZ()
	printf("TRADE LOAD [%s]: current_buy_supplies = %s", obj:name(), tostring(a))
	if a ~= "" then
		tt.current_buy_supplies = a
		to_log("Definition of tt.current_buy_supplies 2: %s", tt.current_buy_supplies)
	end

	local cur_tm = game.time()

	a = packet:r_s32()
	if a ~= -1 then
		tt.update_time = cur_tm + a
	end
	
	to_log("Definition of tt.update_time 2: %s", tt.update_time)

	a = packet:r_s32()
	if a ~= -1 then
		tt.resuply_time = cur_tm + a
	end
	
	to_log("Definition of tt.resuply_time 2: %s", tt.resuply_time)
	
	set_save_marker(packet, "load", true, "trade_manager")
end
----------- NOT TO DELETE!!!!!!!!! called from engine
function get_buy_discount(npc_id)
	local str = utils.cfg_get_string(trade_manager[npc_id].config, "trader", "discounts", nil, false, "", "")
	if(str=="") then
		return 1
	end

	local sect = xr_logic.pick_section_from_condlist(db.actor, nil, xr_logic.parse_condlist(nil, "trade_manager", "discounts", str))
	str = utils.cfg_get_number(trade_manager[npc_id].config, sect, "buy", nil, false, 1)
		return str
end
----------- NOT TO DELETE!!!!!!!!! called from engine
function get_sell_discount(npc_id)
	local str = utils.cfg_get_string(trade_manager[npc_id].config, "trader", "discounts", nil, false, "", "")
	if(str=="") then
		return 1
	end

	local sect = xr_logic.pick_section_from_condlist(db.actor, nil, xr_logic.parse_condlist(npc, "trade_manager", "discounts", str))
	str = utils.cfg_get_number(trade_manager[npc_id].config, sect, "sell", nil, false, 1)

	return str
end

 

 

И примерно спустя часа полтора чистки 50к+ строк лога от лишней инфы, которая не касается Бороды, с которым все и проверялось (троеточия как раз заменяют не относящиеся к делу логи или бесконечные увеличения tt.update_time 1):

 

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

--Загрузка игры

--...

[LUA]  filling npc_info for obj [zat_a2_stalker_barmen2464]

--...

[LUA]  registering stalker zat_a2_stalker_barmen2464

--...

[LUA]  _objectzat_a2_stalker_barmen2464: set load marker: 299
[LUA]  _objectzat_a2_stalker_barmen2464: LOAD DIF: 239
[LUA]  _trade_manager: set load marker: 540
[LUA]  TRADE LOAD [zat_a2_stalker_barmen2464]: cfg_ltx = misc\trade\trade_zat_a2_barmen.ltx
[LUA]  TRADE LOAD [zat_a2_stalker_barmen2464]: current_buy_condition = trade_generic_buy
[LUA]  TRADE LOAD [zat_a2_stalker_barmen2464]: current_sell_condition = trade_generic_sell
[LUA]  TRADE LOAD [zat_a2_stalker_barmen2464]: current_buy_supplies = supplies_start
! Cannot find saved game ~:Definition of tt.current_buy_supplies 2: supplies_start
! Cannot find saved game ~:Definition of tt.update_time 2: 4261173416
! Cannot find saved game ~:Definition of tt.resuply_time 2: 4261853856
[LUA]  _trade_manager: LOAD DIF: 96

--...

[LUA]  TRADE INIT[zat_a2_stalker_barmen2464]
! Cannot find saved game ~:Definition of trade_manager[npc:id()].buy_supplies 1: table: 0x071d64a29c40

--...

--Постоянно увеличивающийся tt.update_time 1

[LUA]  TRADE [zat_a2_stalker_barmen2464]: current = trade_generic_sell   sell = trade_generic_sell
! Cannot find saved game ~:Definition of tt.update_time 1: 4261207416

--...

[LUA]  TRADE [zat_a2_stalker_barmen2464]: current = trade_generic_sell   sell = trade_generic_sell
! Cannot find saved game ~:Definition of tt.update_time 1: 4261209646

--...

--Первое сохранение

[LUA]  _motivator_binder: set save marker: 4502
[LUA]  _objectzat_a2_stalker_barmen2464: set save marker: 4502
[LUA]  _objectzat_a2_stalker_barmen2464: SAVE DIF: 239
[LUA]  _trade_manager: set save marker: 4743
[LUA]  TRADE SAVE [zat_a2_stalker_barmen2464]: current_buy_condition = trade_generic_buy
[LUA]  TRADE SAVE [zat_a2_stalker_barmen2464]: current_sell_condition = trade_generic_sell
[LUA]  TRADE SAVE [zat_a2_stalker_barmen2464]: current_buy_supplies = supplies_start
[LUA]  _trade_manager: SAVE DIF: 96

--Закупка припасов

[LUA]  on_item_take [vodka]
item place [3]
[LUA]  on_item_take [vodka]
item place [3]
[LUA]  on_item_take [vodka]
item place [3]
[LUA]  on_item_take [kolbasa]
item place [3]
[LUA]  on_item_take [kolbasa]
item place [3]
[LUA]  on_item_take [kolbasa]
item place [3]
[LUA]  on_item_take [kolbasa]
item place [3]
[LUA]  on_item_take [bread]
item place [3]
[LUA]  on_item_take [bread]
item place [3]
[LUA]  on_item_take [energy_drink]
item place [3]

--Второе сохранение

[LUA]  _objectzat_a2_stalker_barmen2464: set save marker: 4502
[LUA]  _objectzat_a2_stalker_barmen2464: SAVE DIF: 239
[LUA]  _trade_manager: set save marker: 4743
[LUA]  TRADE SAVE [zat_a2_stalker_barmen2464]: current_buy_condition = trade_generic_buy
[LUA]  TRADE SAVE [zat_a2_stalker_barmen2464]: current_sell_condition = trade_generic_sell
[LUA]  TRADE SAVE [zat_a2_stalker_barmen2464]: current_buy_supplies = supplies_start
[LUA]  _trade_manager: SAVE DIF: 96

--Загрузка второго сохранение для проверки обновления ассортимента: не обновился

[LUA]  _motivator_binder: set load marker: 399
[LUA]  _objectzat_a2_stalker_barmen2464: set load marker: 399
[LUA]  _objectzat_a2_stalker_barmen2464: LOAD DIF: 239
[LUA]  _trade_manager: set load marker: 640
[LUA]  TRADE LOAD [zat_a2_stalker_barmen2464]: cfg_ltx = misc\trade\trade_zat_a2_barmen.ltx
[LUA]  TRADE LOAD [zat_a2_stalker_barmen2464]: current_buy_condition = trade_generic_buy
[LUA]  TRADE LOAD [zat_a2_stalker_barmen2464]: current_sell_condition = trade_generic_sell
[LUA]  TRADE LOAD [zat_a2_stalker_barmen2464]: current_buy_supplies = supplies_start
! Cannot find saved game ~:Definition of tt.current_buy_supplies 2: supplies_start
! Cannot find saved game ~:Definition of tt.update_time 2: 4261479076
! Cannot find saved game ~:Definition of tt.resuply_time 2: 4261907516
[LUA]  _trade_manager: LOAD DIF: 96

--...

[LUA]  TRADE INIT[zat_a2_stalker_barmen2464]
! Cannot find saved game ~:Definition of trade_manager[npc:id()].buy_supplies 1: table: 0x071d55c0af00

--Отбежал далеко от Скадовска, сделал третий сейв, прибежал обратно проверить обновление: не обновилось

[LUA]  TRADE INIT[zat_a2_stalker_barmen2464]
! Cannot find saved game ~:Definition of trade_manager[npc:id()].buy_supplies 1: table: 0x071d66c89a00

--Загрузил третий сейв, снова прибежал на Скадовск: ассортимент обновился

[LUA]  TRADE INIT[zat_a2_stalker_barmen2464]
! Cannot find saved game ~:Definition of trade_manager[npc:id()].buy_supplies 1: table: 0x071d654a1f40

--...

--Здесь единожды за весь лог всплыла tt.resuply_time 1

[LUA]  TRADE [zat_a2_stalker_barmen2464]: sell condition = trade_generic_sell
! Cannot find saved game ~:Definition of tt.current_buy_supplies 1 supplies_start
! Cannot find saved game ~:Definition of tt.resuply_time 1 4262900846
! Cannot find saved game ~:Definition of tt.update_time 1: 4262000846

--...

--Контрольная закупка, контрольный четвертый сейв

[LUA]  _motivator_binder: set save marker: 4805
[LUA]  _objectzat_a2_stalker_barmen2464: set save marker: 4805
[LUA]  _objectzat_a2_stalker_barmen2464: SAVE DIF: 239
[LUA]  _trade_manager: set save marker: 5046
[LUA]  TRADE SAVE [zat_a2_stalker_barmen2464]: current_buy_condition = trade_generic_buy
[LUA]  TRADE SAVE [zat_a2_stalker_barmen2464]: current_sell_condition = trade_generic_sell
[LUA]  TRADE SAVE [zat_a2_stalker_barmen2464]: current_buy_supplies = supplies_start
[LUA]  _trade_manager: SAVE DIF: 96

--Загрузка четвертого сейва, ассортимент: не обновился

[LUA]  _motivator_binder: set load marker: 349
[LUA]  _objectzat_a2_stalker_barmen2464: set load marker: 349
[LUA]  _objectzat_a2_stalker_barmen2464: LOAD DIF: 239
[LUA]  _trade_manager: set load marker: 590
[LUA]  TRADE LOAD [zat_a2_stalker_barmen2464]: cfg_ltx = misc\trade\trade_zat_a2_barmen.ltx
[LUA]  TRADE LOAD [zat_a2_stalker_barmen2464]: current_buy_condition = trade_generic_buy
[LUA]  TRADE LOAD [zat_a2_stalker_barmen2464]: current_sell_condition = trade_generic_sell
[LUA]  TRADE LOAD [zat_a2_stalker_barmen2464]: current_buy_supplies = supplies_start
! Cannot find saved game ~:Definition of tt.current_buy_supplies 2: supplies_start
! Cannot find saved game ~:Definition of tt.update_time 2: 4262320966
! Cannot find saved game ~:Definition of tt.resuply_time 2: 4262963126
[LUA]  _trade_manager: LOAD DIF: 96

--...

[LUA]  TRADE INIT[zat_a2_stalker_barmen2464]
! Cannot find saved game ~:Definition of trade_manager[npc:id()].buy_supplies 1: table: 0x071d4b5214c0

 

 

Ну и после этого я снова уперся в дно своего понимания происходящего, ибо лог-то и значения вижу, а закономерность между ними и кодом скрипта, по крайней мере, сходу, не нахожу, хоть убей. Единственное, что удалось увидеть - это что обновление произошло, когда единственный раз всплыло допакетное значение tt.resuply_time, но куда от этого плясать - не понимаю, ведь оно равно update_time 1, которое постоянно увеличивается.

Ссылка на комментарий
1 час назад, SWEAW сказал:

В общем, сделал по совету, это

Не правильно. Нужно было ИЛИ раскоментировать стандартный код ИЛИ изменить его, как посоветовал @Kirgudu.

Посмотри внимательно, как написано в его посте.

 

В функции "trade_manager.update" в условиях для переменных "tt.update_time" и "tt.resuply_time" нужно поменять знак сравнения на "больше" - ">".

При использовании "game.time()" значения времени 60000 и 120000 чрезвычайно малы.

Изменено пользователем WinCap
  • Нравится 1

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

Ссылка на комментарий
01.06.2024 в 01:01, WinCap сказал:

Нужно было ИЛИ раскоментировать стандартный код

 

01.06.2024 в 01:01, WinCap сказал:

В функции "trade_manager.update" в условиях для переменных "tt.update_time" и "tt.resuply_time" нужно поменять знак сравнения на "больше" - ">".

 

Это сделал, касаемо этого:

 

01.06.2024 в 01:01, WinCap сказал:

При использовании "game.time()" значения времени 60000 и 120000 чрезвычайно малы.

 

специально ставил малые значения (игровую минуту и 2 соответственно), чтобы было быстрее проверять, что меняется. Поменял на игровой час и два соответственно, но по итогу с этим кодом:

 

Скрытый текст
local trade_manager = {}


function trade_init(npc, cfg)
	printf("TRADE INIT[%s]", npc:name())
	if trade_manager[npc:id()] == nil then
		trade_manager[npc:id()] = {}
	end

	trade_manager[npc:id()].cfg_ltx = cfg
	trade_manager[npc:id()].config = ini_file(cfg)

	-- коэфициенты покупки
	local str = utils.cfg_get_string(trade_manager[npc:id()].config, "trader", "buy_condition", npc, true, "")
	if str == nil then
		abort("Incorrect trader settings. Cannot find buy_condition. [%s]->[%s]", npc:name(), cfg)
	end
	trade_manager[npc:id()].buy_condition = xr_logic.parse_condlist(npc, "trade_manager", "buy_condition", str)

	-- коэфициенты продажи
	str = utils.cfg_get_string(trade_manager[npc:id()].config, "trader", "sell_condition", npc, true, "")
	if str == nil then
		abort("Incorrect trader settings. Cannot find sell_condition. [%s]->[%s]", npc:name(), cfg)
	end
	trade_manager[npc:id()].sell_condition = xr_logic.parse_condlist(npc, "trade_manager", "sell_condition", str)

	-- список закупки
	str = utils.cfg_get_string(trade_manager[npc:id()].config, "trader", "buy_supplies", npc, false, "")
	if str ~= nil then
		trade_manager[npc:id()].buy_supplies = xr_logic.parse_condlist(npc, "trade_manager", "buy_supplies", str)
	end
	to_log("Definition of trade_manager[npc:id()].buy_supplies 1: %s", trade_manager[npc:id()].buy_supplies)

-- buy_item_condition_factor
	str = utils.cfg_get_string(trade_manager[npc:id()].config, "trader", "buy_item_condition_factor", npc, false, "", "0.7")
	if str ~= nil then
		trade_manager[npc:id()].buy_item_condition_factor = xr_logic.parse_condlist(npc, "trade_manager", "buy_item_condition_factor", str)
	end
end


function update(npc)
	local tt = trade_manager[npc:id()]

	if tt == nil then
		printf("TRADE [%s]:  tt is nil", npc:name())
		return
	end

	if tt.update_time ~= nil and tt.update_time > game.time() then
		return
	end
	
	tt.update_time = game.time() + 3600000
	to_log("Definition of tt.update_time 1: %s", tt.update_time)

	local str = xr_logic.pick_section_from_condlist(db.actor, npc, tt.buy_condition)
	if(str=="" or str==nil) then
		abort("Wrong section in buy_condition condlist for npc [%s]!", npc:name())
	end
	if tt.current_buy_condition ~= str then
		--'printf("TRADE [%s]: buy condition = %s", npc:name(), str)
		npc:buy_condition(tt.config, str)
		tt.current_buy_condition = str
	end

	str = xr_logic.pick_section_from_condlist(db.actor, npc, tt.sell_condition)
	if(str=="" or str==nil) then
		abort("Wrong section in buy_condition condlist for npc [%s]!", npc:name())
	end
	if tt.current_sell_condition ~= str then
		printf("TRADE [%s]: sell condition = %s", npc:name(), str)
		npc:sell_condition(tt.config, str)
		tt.current_sell_condition = str
	else
		printf("TRADE [%s]: current = %s   sell = %s", npc:name(), tostring(tt.current_sell_condition), tostring(str))
	end

	str = tonumber(xr_logic.pick_section_from_condlist(db.actor, npc, tt.buy_item_condition_factor))
	if tt.current_buy_item_condition_factor ~= str then
		npc:buy_item_condition_factor(str)
		tt.current_buy_item_condition_factor = str
	end

	if tt.buy_supplies == nil then
		return
	end

	str = xr_logic.pick_section_from_condlist(db.actor, npc, tt.buy_supplies)
	if(str=="" or str==nil) then
		abort("Wrong section in buy_condition condlist for npc [%s]!", npc:name())
	end
	if tt.current_buy_supplies ~= str then
		if tt.resuply_time ~= nil and tt.resuply_time > game.time() then
			return
		end
		--'printf("TRADE [%s]: buy_supplies = %s", npc:name(), str)
		npc:buy_supplies(tt.config, str)
		tt.current_buy_supplies = str
		to_log("Definition of tt.current_buy_supplies 1 %s", tt.current_buy_supplies)
		tt.resuply_time = game.time() + 7200000
		to_log("Definition of tt.resuply_time 1 %s", tt.resuply_time)
	end
end


function save(obj, packet)
	local tt = trade_manager[obj:id()]
	set_save_marker(packet, "save", false, "trade_manager")
	--' Сохраняем присутствует ли инициализированная торговля в принципе.
	if tt == nil then
		printf("TRADE SAVE [%s]: ignored", obj:name())
		packet:w_bool(false)
		return
	else
		packet:w_bool(true)
	end

	packet:w_stringZ(tt.cfg_ltx)

	printf("TRADE SAVE [%s]: current_buy_condition = %s", obj:name(), tostring(tt.current_buy_condition))
	if tt.current_buy_condition == nil then
		packet:w_stringZ("")
	else
		packet:w_stringZ(tt.current_buy_condition)
	end

	printf("TRADE SAVE [%s]: current_sell_condition = %s", obj:name(), tostring(tt.current_sell_condition))
	if tt.current_sell_condition == nil then
		packet:w_stringZ("")
	else
		packet:w_stringZ(tt.current_sell_condition)
	end

	printf("TRADE SAVE [%s]: current_buy_supplies = %s", obj:name(), tostring(tt.current_buy_supplies))
	if tt.current_buy_supplies == nil then
		packet:w_stringZ("")
	else
		packet:w_stringZ(tt.current_buy_supplies)
	end

	local cur_tm = game.time()

	if tt.update_time == nil then
		packet:w_s32(-1)
	else
	 	packet:w_s32(tt.update_time - cur_tm)
	end

	if tt.resuply_time == nil then
		packet:w_s32(-1)
	else
	 	packet:w_s32(tt.resuply_time - cur_tm)
	end
	set_save_marker(packet, "save", true, "trade_manager")
end

function load(obj, packet)
	set_save_marker(packet, "load", false, "trade_manager")
	local a = packet:r_bool()
	if a == false then
		printf("TRADE LOAD [%s]: ignored", obj:name())
		return
	end

	trade_manager[obj:id()] = {}

	local tt = trade_manager[obj:id()]

	tt.cfg_ltx = packet:r_stringZ()
	printf("TRADE LOAD [%s]: cfg_ltx = %s", obj:name(), tostring(tt.cfg_ltx))

	tt.config = ini_file(tt.cfg_ltx)

	a = packet:r_stringZ()
	printf("TRADE LOAD [%s]: current_buy_condition = %s", obj:name(), tostring(a))
	if a ~= "" then
		tt.current_buy_condition = a
		obj:buy_condition(tt.config, a)
	end

	a = packet:r_stringZ()
	printf("TRADE LOAD [%s]: current_sell_condition = %s", obj:name(), tostring(a))
	if a ~= "" then
		tt.current_sell_condition = a
		obj:sell_condition(tt.config, a)
	end

	a = packet:r_stringZ()
	printf("TRADE LOAD [%s]: current_buy_supplies = %s", obj:name(), tostring(a))
	if a ~= "" then
		tt.current_buy_supplies = a
		to_log("Definition of tt.current_buy_supplies 2: %s", tt.current_buy_supplies)
	end

	local cur_tm = game.time()

	a = packet:r_s32()
	if a ~= -1 then
		tt.update_time = cur_tm + a
	end
	
	to_log("Definition of tt.update_time 2: %s", tt.update_time)

	a = packet:r_s32()
	if a ~= -1 then
		tt.resuply_time = cur_tm + a
	end
	
	to_log("Definition of tt.resuply_time 2: %s", tt.resuply_time)
	
	set_save_marker(packet, "load", true, "trade_manager")
end
----------- NOT TO DELETE!!!!!!!!! called from engine
function get_buy_discount(npc_id)
	local str = utils.cfg_get_string(trade_manager[npc_id].config, "trader", "discounts", nil, false, "", "")
	if(str=="") then
		return 1
	end

	local sect = xr_logic.pick_section_from_condlist(db.actor, nil, xr_logic.parse_condlist(nil, "trade_manager", "discounts", str))
	str = utils.cfg_get_number(trade_manager[npc_id].config, sect, "buy", nil, false, 1)
		return str
end
----------- NOT TO DELETE!!!!!!!!! called from engine
function get_sell_discount(npc_id)
	local str = utils.cfg_get_string(trade_manager[npc_id].config, "trader", "discounts", nil, false, "", "")
	if(str=="") then
		return 1
	end

	local sect = xr_logic.pick_section_from_condlist(db.actor, nil, xr_logic.parse_condlist(npc, "trade_manager", "discounts", str))
	str = utils.cfg_get_number(trade_manager[npc_id].config, sect, "sell", nil, false, 1)

	return str
end

 

 

с прошлого раза ничего не изменилось. Ну как, лог теперь перестал бесконечно спамить обновлением tt.update_time 1, потому что она перестала бесконечно изменяться, и tt.resupply_time 1 перестал обновляться вообще, только, как и до этого, после сейв-лоада с торгашом в оффлайне. Но какие бы значения прибавки времени я не выставлял, хоть минута, хоть десять, хоть час - Бороде вообще плевать. Просто стоял около него ждал, пробовал много дней проспать (на случай, если все-таки размерность времени не мс, а больше), ждал и отбегал в оффлайн/прибегал обратно, спал по той же схеме - ноль эмоций, как с последней покупки было товаров, так и осталось, не обновляется. Возвращал реальное время вместо игрового - те же результаты.

 

А реально ли вообще принудительно вызывать функцию npc:buy_supplies(tt.config, str) через on_game_timer в сочетании с инфопоршнями? Условно:

 

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

1. Игра на старте загрузила Бороду, обновила/загрузила его ассортимент

2. Выдаем инфопоршень типа wait_for_update

3. Оборачиваем вызов npc:buy_supplies в условия:

Если поршня wait_for_update нет, то

     Вызываем npc:buy_supplies

     give_alife_info (или просто give_ifo, как-то так) поршень wait_for_update

     иначе ничего не делать

енд

4. Делаем еще один поршень, чтобы таймер постоянно не обновлялся в цикле

Если wait_for_update есть И timer_started нет, то

      give_alife_info timer_started

      on_game_timer допустим 172800 (2 суток, вроде как этот таймер использует игровые секунды) disable_info wait_for_update и timer_started

      иначе ничего не делать

енд

 

Или эти функции исключительно для файлов логики/диалогов работают?

Ссылка на комментарий
23 минуты назад, SWEAW сказал:

Но какие бы значения прибавки времени я не выставлял, ... - Бороде вообще плевать. ... как с последней покупки было товаров, так и осталось, не обновляется.

Всё дело в этом кусочке кода из функции "trade_manager.update":

Скрытый текст
str = xr_logic.pick_section_from_condlist(db.actor, npc, tt.buy_supplies)
if(str=="" or str==nil) then
	abort("Wrong section in buy_condition condlist for npc [%s]!", npc:name())
end
if tt.current_buy_supplies ~= str then			-- "Собака" зарыта тут
	if tt.resuply_time ~= nil and tt.resuply_time > game.time() then
		return
	end

 

Обновление ассортимента произойдёт после истечения времени "tt.resuply_time", но только после того как изменится текущая секция в конфигурационном файле торговца.

 

Можно попробовать изменить эту часть на примерно такую:

Скрытый текст
str = xr_logic.pick_section_from_condlist(db.actor, npc, tt.buy_supplies)
if(str=="" or str==nil) then
	abort("Wrong section in buy_condition condlist for npc [%s]!", npc:name())
end
if (tt.current_buy_supplies ~= str) or
   (tt.resuply_time == nil) or
   (tt.resuply_time < game.time()) then
	--'printf("TRADE [%s]: buy_supplies = %s", npc:name(), str)
	npc:buy_supplies(tt.config, str)
	tt.current_buy_supplies = str
	to_log("Definition of tt.current_buy_supplies 1 %s", tt.current_buy_supplies)
	tt.resuply_time = game.time() + 7200000
	to_log("Definition of tt.resuply_time 1 %s", tt.resuply_time)
end

 

 

Изменено пользователем WinCap
  • Спасибо 1
  • Нравится 1

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

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

Приветствую, имеется вопрос как можно удалить строку "Сетевая игра" из главного меню CoP? 

Потому что при удалении ее в ui_mm_main_16 выдает следующую ошибку:

 

Expression    : assertion failed
Function      : CUIMMShniaga::CreateList
File          : D:\prog_repository\sources\trunk\xrGame\ui\UIMMShniaga.cpp
Line          : 114
Description   : pF

Кто может подсказать?

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

Всем привет. Как мы знаем, в Чистом небе, когда НПС стоит на месте, то рандомно проигрывает дополнительные анимации: прикладывает руку ко лбу, разминает спину, чешет пятую точку и т.д. В КОКе, да и в обычном Зове Припяти, все НПС просто стоят, и все. Можно ли как нибудь восстановить доп. анимации покоя для них? Знаю лишь то, что это логику править надо, только вот как?

Добавлено  Опричник,

Перемещено.

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

Возможно там в way-point прописаны анимации типа ward, guard, поэтому он их и проигрывает? Такое и в ЗП можно сделать.

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

Недавно начал играть первый раз в жизни вообще в аномали (в принципе моды никогда не ставил и ни капли в этом не понимаю). Вообщем отыграл часов 5, побегал по кордону и свалке, в итоге в один прекрасный момент начинает вылетать с этой ошибкой 

Expression    : dx10BufferUtils::CreateIndexBuffer(&p_rm_Indices, data->pointer(), iCount*2)
Function      : Fvisual::Load
File          : ..\xrRender\FVisual.cpp
Line          : 188

Экземпляр устройства GPU приостановлен. Для определения соответствующего действия используйте GetDeviceRemovedReason.


stack trace:

 пробовал найти какую-то логику в настройках графики, загружать более ранние сохранки, после загрузки бегом на другую локацию, эффект один и тот же - минут 7 игры максимум и вылет, один раз даже сохранка не загрузилась.

Добавлено  Купер,

Перемещено.

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

Здравствуйте уважаемый форумчане!
Столкнулся с проблемой при переносе оружия (как я понимаю с 3д прицелом голографическим) из BAS в мою микромодификацию на основе COP Sigerous 1.7
Собственно в оригинале BAS есть одна world модель для оружия и для худа, и по модели на каждый вид прицела, я же хотел реализовать условный уникальный ствол где 1 ворлд модель и 1 модель худа с прицелом Eotech.
Проблема заключается в том что у оружия в руках одна линза как-бы отображается в воздухе рядом с оружием, при прицеливании она отображается по центру оружия, но без перекрестия
4d3665f387753d5dcbb341099ba2f093.png
f06bf494eef420062165839d1cca751c.png
(надеюсь я правильно прикреплю скриншоты)
Отмечу что,
1) в конфиге оружия scope_status  = 0 и scope_zoom_factor  = 50
2) в логах ничего нет об отсутствии каких-либо текстур
3) шейдеры я вроде как тоже не забыл перенести (при отсутствии шейдеров игра вылетала)
Наверняка я не единственный кто сталкивался с подобным, но к сожалению я не смог нагуглить решение проблемы
Может быть кто-то из вас знает возможные причины такого эффекта, или поделится ссылкой где уже решали подобную проблему?

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

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

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

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

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

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

Войти

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

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

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