[CoP] Ковыряемся в файлах - Страница 386 - Скрипты / конфиги / движок - AMK Team
Перейти к контенту

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


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

Здравствуйте.

Подскажите, пожалуйста, как реализовать схему для зомби, когда они лежат на земле, как бы мёртвые, а при подходе ГГ встают и атакуют?

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

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

как реализовать схему для зомби

С ТЧ берёшь mob_fake_death.script, дополняешь modules.script, блок - Загрузка модулей монстров:

load_scheme("mob_fake_death", "mob_fake_death", stype_mobile)

 

В gulag_general.script находишь блок local job_type_by_scheme и добавляешь:

["mob_fake_death"] = "point_job",


Логика:

[mob_fake_death]
on_info = {=dist_to_actor_le(4)} mob_home@zombie или mob_walker@zombie


Ещё есть движ. правка, отключает их видимость (как врагов), когда они в этой схеме.

https://bitbucket.org/sv3nk/la-code/commits/67b6d5ea63424d9bacee9e93e34a4e8be759d258

  • Спасибо 1
  • Полезно 2

Здравствуйте.
Помогите разобраться с очередной аномалией Зоны.
Я как-то вдруг заметил, что при переходе в секцию "walker" из любой другой, NPC идут не на первую точку пути, а на ближайшую к ним. Подскажите, пожалуйста, так всегда было, с оригинальной игры, или это я чего-то "накосячил"?
 

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

@WinCap, судя по скриптам, так оно и в оригинале.
Смотрим xr_walker.script:
action_walker_activity:activate_scheme(loading, npc) --> action_walker_activity:reset_scheme(loading, npc) --> self.move_mgr:reset(...)
Далее в move_mgr.script:

move_mgr:reset(...) --> сброс self.current_point_index = nil (плюс self.can_use_get_current_point_index = false до окончания экстраполяции в extrapolate_callback) --> move_mgr:setup_movement_by_patrol_path()

где видим такую развилочку:

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

 

  • Спасибо 1
  • Нравится 1

Свои работы и совместные проекты: ИнструментOGSM CSFinal StrokeHARDWARMOD

Полезное: модули АртосаXML парсер

56 минут назад, Kirgudu сказал:

так оно и в оригинале.

где видим такую развилочку:

 

Я правильно понимаю, что это, скорее всего, сделано, чтобы находясь в середине пути NPC, после save/load’а, продолжил путь с ближайшей точки, а не топал на самое начало?

 

Надо как-то выкручиваться. Придётся поставить в начале пути ещё один одноточечный путь и промежуточную секцию логики.

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

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

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

находясь в середине пути NPC, после save/load’а, продолжил путь с ближайшей точки

Точную причину мы, не общаясь с разработчиками, не узнаем, но очень похоже на правду. Я бы тоже так сделал.

  • Согласен 2

Свои работы и совместные проекты: ИнструментOGSM CSFinal StrokeHARDWARMOD

Полезное: модули АртосаXML парсер

Господа, подскажите гайд / инструкцию, который можно почитать, как добавить в игру, в данном случае в ЗП, новые боеприпасы? Ну, как новые, 12х76 "Дротик" вырезанный хочу в игру добавить, для начала. И улучшенный 7,62х54 7Н14 из ТЧ/ЧН. Для обучения, я думаю, пойдёт.

ЗЫ. от А до Я, начиная от модели, иконки и описания, до настройки в конфиге, прописке этого патрона в нужных файлах, чтобы игра его читала и не вылетала, прописке торговцам, в тайники и т.д. Ибо полный нуб в этом.

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

По образу и подобию ТЧ: искать в [config\] и [meshes\] упоминания ammo_12x76_dart, делать так же. Для совместимости с ЗП можно скопировать все файлы и настройки обычной дроби, а после задать buck_shot = 1 (одна пуля) и поправить иконку/текст/текстуру.

Это не даст точного понятия, что за что отвечает (надо читать справочник или выяснять методом тыка), но это позволит добавить патроны в игру.

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

Шпаргалка

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

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

@bsanek628 Ну очевидно надо добавить секцию патрона в список боеприпасов соответствующих конфигов оружия.
Подсветку оттуда же из этих списков сам подтянет движок. А по торговцам и тайникам надо спецов по ЗП дождаться, я им не являюсь.

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на 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.

Искать упоминания похожих патронов в конфигах со словами trade и treasure (ЗП: secret) в названии. В этом плане игра не отличается от ТЧ: все данные введены вручную, без рандома и часто одинаковыми простынями "не продается / продается по одной цене для всех NPC" – ссылочные секции есть только в настройках лута в [death_generic.ltx] и входящих файлах.

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

Шпаргалка

Там только один нюанс: CoP движок рассчитан на два типа боеприпасов на калибр. Баги полезут, емнип, "по мелочёвке". Вроде неправильной иконки на HUD-e etc.

  • Согласен 1

@bsanek628 В ЗП ввиду спавна тайников россыпью конфиг является текстовым описанием, хотя и не совсем отделен от объектов в игре: с одной стороны, новые предметы не учитываются без правок [all.spawn] и добавления секции [secret] в custom_data каждого объекта; с другой стороны, изменение количества предметов или удаление имеющихся секций конфига в текущей игре все же приводит к пересчету, хотя и по неизвестной логике – 4 предмета, если в конфиге один, два предмета при указании трех и т. п.

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

Шпаргалка

Всем привет. Подскажите, пожалуйста, как изменить trade_manager.script, чтобы торговцы обновляли ассортимент не раз в реальные сутки, а раз в несколько игровых, и, не менее важно, чтобы обновление ассортимента не вызывалось сейв-лоадом (потому что это по сути своей абуз). Знаю, что то ли в ОП-2.2, то ли в ОГСР, в Аномали и ее производных есть такие фичи, но грамотно их оттуда выдернуть, даже покурив несколько гайдов и уроков, не получается, там несколько другие файлы и их структура. Сам пытался заменить упоминания time_global() в вышеописанном скрипте на game.time():

 

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

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

-- 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

    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
        tt.resuply_time = game.time() + 24*3600000

    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
    end

    local cur_tm = game.time()

    a = packet:r_s32()
    if a ~= -1 then
        tt.update_time = cur_tm + a
    end

    a = packet:r_s32()
    if a ~= -1 then
        tt.resuply_time = cur_tm + a
    end
    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

 

Cуть и размерность вроде одинаковая, только одна для времени ИРЛ, вторая для игрового. Но в игре обновление перестало происходить вообще, хотя и вылетов не было.

 

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

5 часов назад, SWEAW сказал:

Два-три дня уже над этим сижу

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

 

Стырь откуда-нибудь функцию log/dbglog/...

Добавь в найденные тобой места вывод в лог времени, чисел, записываемых/читаемых из нет-пакета, и прочего.

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

В принципе в этот момент, ты уже будешь знать решение.

Если нет, возвращайся с логом.

 

Ровно также и с заменой на игровое время. Не должно быть ситуации "но в игре обновление перестало происходить вообще, хотя и вылетов не было". С помощью логов ты легко увидишь, почему обновление перестало проиходить.

  • Согласен 1
2 часа назад, abramcumner сказал:

Стырь откуда-нибудь функцию log/dbglog/...

Добавь в найденные тобой места вывод в лог времени, чисел, записываемых/читаемых из нет-пакета, и прочего.

 

Мне и этот дефолтный ЗПшный скрипт не поддается, потому что ни опыта в скриптинге, ни достаточного времени на изучения LuA, ни энтузиазма/понимания по отношению к любому виду программирования нет. Ресурсов хватает пока лишь на попытки адаптаций того, что уже в шаблонном или похожем виде где-то было или есть, собственно за этим я сюда и обратился, возможно, изначально некорректно обозначив просьбу: я ищу код или файлы скриптов из разных модов, где реализованы описанные механики (отвязка ассортимента торговли от сейв-лоада и его обновление по игровому времени). Скачивать целиком моды по 20-30-40 гигабайт ради поиска нескольких текстовых файлов - времязатратно и нерационально. Если ни у кого таких файлов под рукой нет, то ищу указания на ошибку в коде или его дополнения от тех, кто уже с подобным сталкивался/имеет достаточный опыт в этом деле, ведь, как мне кажется, для них это будет на несколько порядков проще, чем мне еще больше пытаться усложнять (добавлять функции) и так плохо воспринимаемую информацию без гарантии по итогу найти решение самостоятельно.

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

@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

Свои работы и совместные проекты: ИнструментOGSM CSFinal StrokeHARDWARMOD

Полезное: модули АртосаXML парсер

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

Свои работы и совместные проекты: ИнструментOGSM CSFinal StrokeHARDWARMOD

Полезное: модули АртосаXML парсер

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

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

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

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

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

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

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

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

Войти

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

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

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