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

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

@Labadal конкретно телепортировать - это зависит от используемого движка. В общем OGSR - можно. Но ведь в любом случае, даже используя оригинальный движок, можно удалить на старом месте и создать на новом.

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

Доброго дня!
Есть оригинальный каллбэк на смерть физических объектов (ящиков и т.п.): function generic_physics_binder:death_callback(victim, who)

Хочу идентифицировать, КТО "убил" ящик, но who:id(), who.id, who:section(), who:section_name() и т.д. вызывают вылет - нет такого метода.

Подскажите, кто знает, как же можно идентифицировать who?

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

В оригинале, видимо, только через костыли. В Anomaly есть какие-то правки и рабочее испытание "разбить 200 ящиков" с проверкой who:id() = db.actor:id().

 

Есть вариант зацепиться за событие спавна лута в [xr_box.script] и перебрать db.storage на предмет живых объектов рядом с ящиком, но это не позволит точно определить, кто именно разбил ящик гранатой в перестрелке.

  • Полезно 1

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

Шпаргалка

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

В оригинале, видимо, только через костыли.

Самое интересное, что в том же generic_physics_binder:hit_callback(obj, amount, local_direction, who, bone_index)

прекрасно работает who:id(), и тогда я  сделал там сохранение своей глобальной переменной kto_ubil = who, чтобы потом в death_callback её читать, но тут снова затык: если hit убивает ящик, то нет вызова hit_callback, а сразу - death_callback :blink: 
Ладно, будем искать...  :0blackhole:

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

Добрый день, возможно как-то получить количество определённых вещей на поясе? (Например, количество медуз) Спасибо

God save Hatsune Miku!

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

[ТЧ 1.0006]
Правка "отдавать артефакты сначала из инвентаря, потом с пояса".

 

Spoiler
[scripts\dialogs.script]
function relocate_item_section(victim, section, type)
	
		elseif type == "out" then
(–)
			db.actor:transfer_item(db.actor:object(section), victim)
(+)
			local inv_item = db.actor:object(section)

			db.actor:inventory_for_each(
				function(item)
					if item:section() == section then
						inv_item = item
						break
					end
				end
			)

			db.actor:transfer_item(inv_item, victim)

 

 

Безлоговый вылет при остановке перебора через break. В движке перебор описан как for(it =  item_list.begin(); item_list.end() != it; ++it) – такой цикл должен быть совместим с break. Или нет?
Как правильно остановить перебор инвентаря при обнаружении одного предмета?

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

Шпаргалка

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

@Norman Eisenherz я не знаток С++, но скорее всего break внутри выполняемой функции работает только в контексте этой функции, а поскольку никакого цикла в ней нет, такая команда приводит к исключению.

Более того, поскольку в нет и обработки и возвращаемого из functor значения (можно было бы вернуть true или false для остановки, как это сделано, например, в level.add_call для проверки выполнения условия), то и этот метод не пойдёт.
Отсюда ответ - никак.

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

local inv_item = nil
db.actor:inventory_for_each(function(item)
	if inv_item == nil and item:section() == section then inv_item = item end
end)
if inv_item then db.actor:transfer_item(inv_item, victim) end

 

  • Нравится 2
  • Согласен 1
  • Полезно 2
Ссылка на комментарий
30.05.2023 в 16:25, phalcor сказал:

function generic_physics_binder:death_callback(victim, who)

Хочу идентифицировать, КТО "убил" ящик, но who:id(), who.id, who:section(), who:section_name() и т.д. вызывают вылет - нет такого метода.

Подскажите, кто знает, как же можно идентифицировать who?

Так вы бы и разбирались для начала, передан ли вообще who, и что он из себя представляет.

Вылет происходит когда вы дергаете методы не удостоверившись в их наличии, а также наличии самого объекта.

if who and type(who) == 'userdata' then
	if type(who.id) == 'number' then
		log("who - серверный объект") -- НЕ КЛИЕНТСКИЙ!
		-- Здесь можно смело использовать who.id, who:section_name(), и другие методы и свойства СЕРВЕРНОГО объекта.
		
	elseif type(who.id) == 'function' then
		log("who - клиентский объект") -- НЕ СЕРВЕРНЫЙ!
		-- Здесь можно смело использовать who:id(), who:section(), и другие методы и свойства КЛИЕНТСКОГО объекта
    
	else
		log("who - объект, но не серверный и не клиентский. Вообще непонятно что.")
    	-- Такого скорее всего не произойдет никогда. Ну, или почти.
	end
else
	log("who not found") -- Объект не был передан.
end
-- Главное не путайте серверные и клиентские объекты между собой.

 

  • Полезно 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.

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

Если в трех скриптах [bind_stalker / bind_monster / xr_motivator] это работает одинаково, то первым действием в четвертом скрипте будет все же повтор, а не проверка – какой смысл пенять новичкам, что они не знают ВСЕГО и не предполагают наличия кочки на ровном месте?

 

Проверили: userdata неизвестного класса – та самая неведома зверушка, которая не должна существовать, но выдается при каждом срабатывании скрипта в момент разрушения ящика. Как скриптовыми методами определить класс такого объекта?

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

Шпаргалка

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

та самая неведома зверушка, которая не должна существовать, но выдается при каждом срабатывании скрипта

А подскажите какой точно движок вы используете?

Методы биндера вызывает именно движок, и если есть его код то смотреть надо там.

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

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

Движок ТЧ 1.0006


Есть некоторая разница в ссылке на объект who при убийстве живого объекта и ящика. В случае с ящиком выдается, видимо, чистый класс CGameObject.

Spoiler
[xrGame\DestroyablePhysicsObject.cpp]
void CDestroyablePhysicsObject::Destroy()
	
	const CGameObject *who_object = smart_cast<const CGameObject*>(FatalHit().initiator());
	callback(GameObject::eDeath)(lua_game_object(),who_object  ? who_object : 0);


[xrGame\entity_alive.cpp]
void CEntityAlive::Die	(CObject* who)
	
	const CGameObject *who_object = smart_cast<const CGameObject*>(who);
	callback(GameObject::eDeath)(lua_game_object(), who_object ? who_object->lua_game_object() : 0);

 

 

Методов чистого класса всего ничего:

Spoiler
C++ class CGameObject : DLL_Pure,ISheduled,ICollidable,IRenderable {
    CGameObject ();

    function Visual();
    function getEnabled() const;
    function _construct();
    function net_Import(net_packet&);
    function getVisible() const;
    function net_Export(net_packet&);
    function net_Spawn(cse_abstract*);
    function use(CGameObject*);
};

 

 

Как добраться до id или секции объекта? Например, who:Visual() выдает не путь до модели, а что-то с типом userdata – видимо, саму модель, но применение к этой "модели" методов visual-классов дает вылет "нет такого метода для данного класса".

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

Шпаргалка

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

Ну баг движка значит.

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

Как добраться до id или секции объекта?

Передать в колбек нормальный lua_game_object, собрать движок.

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

ТЧ 1.0006

А лучше не заниматься странной фигней и взять OGSR например.

Там эта строчка была в порядке еще в 2019 году.

  • Согласен 1
  • Полезно 1

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

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

[ТЧ 1.0006]

 

Если я ничего не путаю, функция, запускаемая через level.client_spawn_manager():add(…, fx), должна срабатывать после выхода заданного объекта в онлайн.

При спавне объекта в инвентарь и проверке его наличия получается nil, при повторном спавне определяется только один объект и так далее с отставанием в один шаг – только что созданный объект не ловится.

Объект выходит в онлайн, но не успевает получить привязку родительского объекта (ГГ)?

Spoiler
local sect = "wpn_fn2000_arena"

function test()
	local spawn = alife():create(sect, vector(), 0, 0, 0)
	level.client_spawn_manager():add(spawn.id, -1, check)
end

function check(id, obj)
	if db.actor:object(sect) then
		_utils.sms(1)
	end
end

 

 

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

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

Шпаргалка

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

@Norman Eisenherz я б сказал, что родительский объект не успевает получить информацию об этой привязке.

Сама привязка существует уже в момент спавна; достаточно после выхода нового объекта в онлайн проверить свойство parent_id (серверное) - оно будет равным id контейнера (актора). Но это единственное свойство, которое изменяется при помещении одного объекта внутрь другого.

Поскольку методы поиска дочернего объекта (:object(), :iterate_inventory() и :inventory_for_each()) работают не со всеми объектами игры - это было бы неоправданно долго, а с динамической коллекцией подчинённых объектов контейнера, требуется, чтобы эта коллекция также обновилась на клиенте. А это происходит, очевидно, на апдейте уже после выхода созданного дочернего объекта в онлайн.

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

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

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

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

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

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

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

Войти

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

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

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