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

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

@Zander_driver 

1. В OGSE есть обработчик [m_net_utils.script] – это те самые "модули Артоса"?

2. Я ни в коем случае не пытаюсь освоить современное программирование ковырянием игры 2007 года – я пытаюсь уменьшить количество "кочек" в игре, в которой приятно убивать время, для чего перебираю существующие моды и пытаюсь их повторить в той мере, в которой это подходит для моих целей. Готовые решения уровня "электросамокат с гироскопом, GPS и подсветкой дороги" не годятся, если мне нужна просто табуретка. Опять же, даже чужие функции надо изучить, чтобы понять причину ошибок и вылетов.

@dsh

1. Ссылка на [m_netpk.script] на GitHub у меня есть, но так как из этих черных ящиков под названием "нетпакеты" я пока докопался до начинки только одного, 3,5к строк кода я буду изучать долго.

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

 

Теперь практика: проверка состояния фонарика и ПНВ

Spoiler

function net_cse_alife_item_torch:__init(obj,mode)

self.st_props = {}
self.up_props = {
        { name = 'torch_flags',   type = 'u8',  default = -1 },


    _G.torch_flags = { --/ torch
        Active            = 1,
        NightVisionActive = 2,
        Attached          = 4

 

Вывод: переменная состояния фонарика имеет тип u8 и находится в начале раздела UPDATE.

 

Spoiler

    local item = db.actor:item_in_slot(9)
    if item then
        local sobj = alife():object(item:id())
        local pk = net_packet()
        sobj:UPDATE_Write(pk)
        pk:r_seek(0)
        local v = pk:r_u8()
        news_manager.send_tip(db.actor, v)
    end

 

Результат: 0 в любом состоянии.

 

Эксперимент: читаю аналогичное значение от конца раздела UPDATE через сдвиг pk:r_seek(pk:w_tell() -1). Результат: все выключено – 4, фонарик – 5, ПНВ – 6, все вместе – 7. Я не знаю, что именно я прочитал, но это точно переменная размером 1 байт, которая меняется при переключении режима фонарика и остается на указанном значении до следующего переключения. Ну и как сие понимать?

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

Шпаргалка

Ссылка на комментарий
8 минут назад, Norman Eisenherz сказал:

Ну и как сие понимать?

Прекратить заниматься ерундой и использовать таки m_netpk.script :)

 

Вывод: переменная состояния фонарика имеет тип

u8 и находится в начале раздела UPDATE.

Вывод неверный. Перед блоком переменных фонарика идут блоки переменных классов родителей.

  • Согласен 1
  • Полезно 1
Ссылка на комментарий
2 часа назад, Norman Eisenherz сказал:

3,5к строк кода я буду изучать долго.

Ну, на здоровье.

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

2 часа назад, Norman Eisenherz сказал:

2. Как вскрывали нет-пакеты на момент выхода игры? Вслепую перебирали тип данных для каждого параметра, потом так же вслепую сравнивали полученные значения с данными в игре, чтобы определить переменную?

Похоже, для вас совет dsh подойдет. Читайте темы в этом разделе, от корки до корки. На этот вопрос, ответы найдете.

 

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

Да, зачастую так оно и делалось. Хотите все это повторить - удачи и упорства вам.

 

  • Согласен 1

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

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

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

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

@Norman Eisenherz,

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

function get_torch_state()
	local torch = db.actor:object("device_torch")
	local s_obj = alife():object(torch:id())
	local pk = get_netpk(s_obj, 2)
	if pk:isOk() then
		local data = pk:get()
		return bit_and(data.upd.torch_flags, torch_flags.Active) ~= 0
	end
end

 

Что я сделал? Взял готовый модуль из https://www.amk-team.ru/forum/topic/13216-sborochnyy-ceh/?do=findComment&comment=971137, пробежал глазами скрипт на предмет того, где именно в нет-пакете лежат флаги фонарика согласно его классу - up_props, значит в update части нет-пакета, вспомнил по приложенной инструкции, как именно читать только update часть, и как в результатах она будет называться, накидал базовый скрипт для чтения текущего флага и сравнения его с флагом включения.

Естественно, ещё и модуль подключить надо, но на это есть исчерпывающие сведения в посте по вышеприведённой ссылке, как инструкция Артоса, так и дополнения к ней.

На всё потребовалось не больше 10 минут. Куда меньше, чем глубокое изучение трёх с половиной килострок кода.

Не изобретай велосипед - его уже вылизали со всех сторон за эти годы.

Изменено пользователем Kirgudu
  • Согласен 1
Ссылка на комментарий

Здрасьте.

 

Задача: записать текущее состояние STATE/UPDATE-пакетов оружия в слоте, удалить оружие, через несколько секунд (по инфо-поршню) отспавнить его снова и прочитать состояние. STATE-пакет успешно читается, пока объект переходит в онлайн, UPDATE-пакет не читается, поэтому режим стрельбы и все, что связано с гранатометом, грузится в состоянии по умолчанию.

Spoiler

		if item then
			local sect = item:section()
			local sobj = alife():object(item:id())
	-- запись данных в STATE- и UPDATE-пакеты
			local pk = net_packet()
			sobj:STATE_Write(pk)
			local pku = net_packet()
			sobj:UPDATE_Write(pku)
	-- переспавн
			alife():release(sobj)
			local act = db.actor
			local pos = act:position()
			pos.x = pos.x + 1
			local nobj = alife():create(sect, pos, act:level_vertex_id(), act:game_vertex_id())
			local id = nobj.id
	-- чтение данных из STATE-пакета
			local size = pk:w_tell()
			pk:r_seek(0)
			nobj:STATE_Read(pk, size)
				-- news_manager.send_tip(db.actor, "pk: " .. size)
	-- чтение данных из UPDATE-пакета
			local size = pku:w_tell()
			pku:r_seek(0)
			nobj:UPDATE_Read(pku)
				-- news_manager.send_tip(db.actor, "pku: " .. size)

	-- отслеживание ввода в онлайн и перенос
			local function online()
				return level.object_by_id(id)
			end

			local function pick()
				local item = level.object_by_id(id)
				db.actor:transfer_item(item, db.actor)
			end

			level.add_call(online, pick)
		end

 

 

Попадалось упоминание о том, что данные из обоих пакетов пишутся в объект при выходе последнего в онлайн, то есть и UPDATE-пакет надо писать в серверный объект, а клиентский объект получит данные из него. Ставил функцию UPDATE_Read и до, и после выхода объекта в онлайн – никакого эффекта. Проверял содержимое исходного UPDATE-пакета – данные записываются правильно: например, grenade_mode = 1 (r_u8 от позиции 0), если был выбран подствольник.

 

Как правильно переносить данные UPDATE-пакета?

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

Шпаргалка

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

Для начала попробуй после строк:

            local nobj = alife():create(sect, pos, act:level_vertex_id(), act:game_vertex_id())
            local id = nobj.id

вставить строку:

nobj = alife():object(id)

alife():create возвращает объект типа чуть ли не cse_abstract, и методы State_Read/Update_Read вызываются для этого типа.

alife():object возвращает реальный тип, какой-нибудь cse_alife_weapon_magazined_wgl. Соответственно State_Read/Update_Read вызовутся от него и заполнят grenade_mode.

Изменено пользователем abramcumner
  • Полезно 2
Ссылка на комментарий

@abramcumner Проверил clsid с указанными изменениями и без: определяется как "127", то есть "wpn_groza_s" – гранатомет уже должен быть. На чтении UPDATE-пакета изменения не сказались.

 

Еще вопрос: если требуется изменить одну переменную в конце нетпакета, обязательно ли читать его весь или можно как-то сдвигать позицию записи не только от начала через w_begin(), но и от конца пакета?

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

Шпаргалка

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

 

11 часов назад, Norman Eisenherz сказал:

можно как-то сдвигать позицию записи не только от начала через w_begin(), но и от конца пакета?

Нет. Сдвигать только через r/w_seek() от текущей позиции чтения/записи. w_begin() - это поставить позицию записи в начало пакета и записать два байта.

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

naxac.gif

Ссылка на комментарий
В 25.02.2020 в 18:19, Norman Eisenherz сказал:

все, что связано с гранатометом, грузится в состоянии по умолчанию

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

В серверном, есть только переменная grenade_mode и в клиентский она передается, но её применение к оружию происходит, если я не ошибаюсь, только когда оно в руках.

В приведенном примере section объекта одинаковая, может его не release/create, а transfer'ить в какой-нибудь секретный ящик и обратно?

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

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

@WinCap

1. Это как раз текущая реализация мода: на время торговли/обыска оружие как оно есть улетает во временный ящик. С правильно расставленными отсрочками предметы не теряются на полпути, даже если окно обыска было случайно закрыто через долю секунды, но переспавн, если верить форуму, занимает всего около 20 циклов, тогда как с ящиком и переносом требуется не меньше 100, иначе вылет с потерянным родителем в логе.

2. Есть все-таки в игре рабочий метод переноса данных из UPDATE-пакета в объект или нет?

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

Шпаргалка

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

По прошлой теме: посмотрел OGSE 0.6.9.3. с патчами от февраля 2018 года – при замене прицела на оружии с гранатометом режим стрельбы сбрасывается на "авто", режим гранатомета отключается, гранаты и патроны в качестве "костыля" переспавниваются в инвентарь. Видимо, ответ на вопрос № 2 отрицательный…

 

Другая задача: есть способ создания виртуального LTX-файла через create_ini_file(string). Сам файл создать получается, прочитать из него выбранные строки – тоже, но при попытке создать предмет на основе указанной в файле секции случается вылет с ошибкой "секция не найдена". Идея в том, чтобы временно получить броню со статусом quest_item = true, не прописывая новую секцию для каждого вида брони вручную. Как правильно сослаться на виртуальный LTX-файл и возможен ли такой спавн в принципе?

Spoiler

		local item = db.actor:item_in_slot(6)
		if item then
			local sect = item:section()

			local strings = {
				"#include \"misc\\outfit.ltx\"",
				"[" .. sect .. "_q]:" .. sect,
				"description = test",
				"quest_item = true"
					}

			local text = table.concat(strings, "\n")
			local ini = create_ini_file(text)

			local act = db.actor
			local pos = act:position()
			pos.x = pos.x + 1
			local spawn = alife():create(sect .. "_q", pos, act:level_vertex_id(), act:game_vertex_id())
		end

 

 

Изменено пользователем Norman Eisenherz
  • Смешно 1

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

Шпаргалка

Ссылка на комментарий
только что, Norman Eisenherz сказал:

от февраля 2018 года

Даже стесняюсь спросить, а какой же год у нас на дворе...

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

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

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

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

@Zander_driver, не всем можется и, главное, хочется ковыряться в движке.

 

@Norman Eisenherz, функция create_ini_file создаёт объект в памяти, к которому можно применять все методы этого класса, такие как ini:line_count(), ini:r_bool() и др. Но это не значит, что этот объект автоматически подключён в качестве игрового ресурса аналогично инклюдам в system.ltx.

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

@Kirgudu То, что файл хранится без привязки к system.ltx – ожидаемо, но вроде бы такой виртуальный файл можно сохранить на жестком диске. Как это сделать?

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

Шпаргалка

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

не всем можется

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

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

  • Согласен 1

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

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

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

Ссылка на комментарий
6 часов назад, Norman Eisenherz сказал:

но вроде бы такой виртуальный файл можно сохранить на жестком диске. Как это сделать?

local file = io.open() / file:write() / file:close() - для ЧН/ЗП. Для ТЧ я такого способа не знаю. В любом случае сохранение на лету скорее всего не даст автоматического подключения к ресурсам, а сохранение с целью последующего чтения при запуске игры равносильно формированию нужного конфига заранее.

 

Но соглашусь с @Zander_driver. Совершенно непонятны цели данных усилий. Если для самообразования - это похвально, вот только начинать (и продолжать) тогда нужно с того, что страницей раньше написал @dsh: чтения этой и соседних (справочник, общие вопросы) тем от начала и до конца. В противном случае лучше таки обратить своё внимание на доработанные движки или модули Артоса. Ведь они и вправду "из коробки" обеспечат то, что ты пытаешься сделать.

  • Согласен 1
Ссылка на комментарий
34 минуты назад, Kirgudu сказал:

В любом случае сохранение на лету скорее всего не даст автоматического подключения к ресурсам

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

  • Согласен 1

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

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

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

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

@Kirgudu Какая функция [lua_helper] или [m_netpk] должна помочь в изменении квестового статуса надетой брони?

 

(Снова по старой теме) Подключил [m_netpk], скопировал данные автомата в руках, отспавнил новый, перенес данные, результат ровно тот же: все параметры UPDATE-пакета в состоянии по умолчанию (гранатомет выключен, в стволе один патрон согласно данным STATE-пакета). Где я ошибся?

Spoiler

local item = db.actor:item_in_slot(2)	-- автомат + пгм
	if item then
		local sect = item:section()
		local sobj = alife():object(item:id())
	
		local pk = get_netpk(sobj)
		local data = pk:get()
	
		alife():release(sobj)
		local act = db.actor
		local pos = act:position()
		pos.x = pos.x + 1
		local nobj = alife():create(sect, pos, act:level_vertex_id(), act:game_vertex_id())
	
		local npk = get_netpk(nobj)
		npk:set(data)
	end

 

 

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

Шпаргалка

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

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

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

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

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

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

Войти

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

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

AMK-Team.ru

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