Триггеры средствами lua.

RecoveryIt

Активный
7 Май 2016
75
0
Итак, мы знаем что триггер можно создать непосредственно из Hammer'a (область которая бы реагировала на что-нибудь), но что если ты не знаешь какая именно область тебе нужна. Типа она все время меняется, как отследить такое? Нашел в доках валве функцию CreateTrigger, которая возвращает некий AABB trigger.
Код:
CreateTriggerRadiusApproximate	handle CreateTriggerRadiusApproximate(Vector Vector_1, float float_2)
Как я понял это и есть то что мне нужно, ибо можно создать триггер через юнита, взяв его AbsOrigin и некий радиус, но доступно всего 3 функции для работы с ним:
Код:
Disable	void Disable()	Disable the trigger
Enable	void Enable()	Enable the trigger
IsTouching	bool IsTouching(handle hEnt)	Checks whether the passed entity is touching the trigger.
Первые 2 как мы видим отвечают за включение/выключение триггера, а вот 3-я , как я понял, возвращает true/false если данный entity "дотронулся" триггера.
Перепробовал все, никак не получается. IsTouching() всегда возвращает false, даже если дать entity, на котором создаешь сам триггер, hundle триггера через DebugPrintTable() возвращает userdata в который никак не заглянуть. Может быть есть еще что то, что я упустил. Идеи?

На данный момент использую обычный триггер из хамера, и переношу его через SetAbsOrigin() туда куда мне нужно. Но хотелось бы автоматизировать это полностью(без создания ентити в хамере)
 
Последнее редактирование модератором:
Покажи userdata (что тебе в консоли выводит).
Разве она не таблица? Ключи и их значения не глянуть?
 
Покажи userdata (что тебе в консоли выводит).
Разве она не таблица? Ключи и их значения не глянуть?

Выводит лишь 1 значение, userdata. На сколько я знаю , в userdata нельзя заглянуть.
Но вроде можно попробовать перебором ключей типа так:
пусть переменная somevar наш userdata
somevar.name , somevar.id , somevar.count и т.д.
Хотя точно не помню, вроде я так с модификаторами делал ;D
 
Последнее редактирование модератором:
Вот вывод в консоль, и кстати я только что заметил что верхняя строчка которую выводит консоль, говорит нам о том что сервер не может запрекешить модель триггера с типом multiple (такой тип в хамере можно создать) мб модельку ему прифигачить через SetModel() ;D

Код:
[ W Entity System    ]: Attempting to precache model for entity 358 [trigger_multiple] at -515.44 -131.20 128.00, but model name is NULL
[  VScript       ]: table: 0x033817e0             ----------- это DebugPrint() триггера
[  VScript       ]: __self: userdata: 0x03381820	  ----------- это DebugPrintTable() триггера

Вот кстати один из созданых триггеров, как видно из параметров , он типо включен.
http://imgur.com/a/a2iys
 
Я не знаю, как у BMD реализован DebugPrint(), может там и есть то, что я тебе посоветую попробовать дальше, но попробуй глянуть так:

Код:
for k,v in pairs(userdata) do
  print(k,v)
end
 
[quote author=RecoveryIt link=topic=1359.msg8569#msg8569 date=1488275125]
Вот вывод в консоль, и кстати я только что заметил что верхняя строчка которую выводит консоль, говорит нам о том что сервер не может запрекешить модель триггера с типом multiple (такой тип в хамере можно создать) мб модельку ему прифигачить через SetModel() ;D
Вот кстати один из созданых триггеров, как видно из параметров , он типо включен.
http://imgur.com/a/a2iys
[/quote]
userdata не посмотреть, ты прав.
Попробуй такую штуку для проверки нахождения триггера
Код:
for _,thing in pairs( Entities:FindAllInSphere(unit:GetAbsOrigin(), 10 ) ) do
    if thing then
		print(thing)
		print(thing:GetName())
	end
  end
 
[quote author=Илья link=topic=1359.msg8571#msg8571 date=1488276948]
Я не знаю, как у BMD реализован DebugPrint(), может там и есть то, что я тебе посоветую попробовать дальше, но попробуй глянуть так:

Код:
for k,v in pairs(userdata) do
  print(k,v)
end
[/quote]

я пробовал это уже, в userdata нельзя заглянуть. даже когда я пишу вот так:
Код:
for h,j in pairs(trigger.__self) do
  print(h,j)
 end
Консоль мне говорит что значение в pairs должно быть таблицей, а я ему даю userdata. Из чего можно сделать вывод что это не таблица.
Код:
[  Developer      ]: ...me\dota_addons\game_custom\scripts\vscripts\hero_ability.lua:50: bad argument #1 to 'pairs' (table expected, got userdata)
[  Developer      ]: stack traceback:
[  Developer      ]: 	[C]: in function 'pairs'
[  Developer      ]: 	...me\dota_addons\game_custom\scripts\vscripts\hero_ability.lua:50: in function <...me\dota_addons\wog_rpg\scripts\vscripts\hero_ability.lua:1>
[ W VScript       ]: Script Runtime Error: ...me\dota_addons\game_custom\scripts\vscripts\hero_ability.lua:50: bad argument #1 to 'pairs' (table expected, got userdata)
[ W VScript       ]: stack traceback:
[ W VScript       ]: 	[C]: in function 'pairs'
[ W VScript       ]: 	...me\dota_addons\game_custom\scripts\vscripts\hero_ability.lua:50: in function <...me\dota_addons\wog_rpg\scripts\vscripts\hero_ability.lua:1>
 
Последнее редактирование модератором:
[quote author=CryDeS link=topic=1359.msg8572#msg8572 date=1488277129]
userdata не посмотреть, ты прав.
Попробуй такую штуку для проверки нахождения триггера
Код:
for _,thing in pairs( Entities:FindAllInSphere(unit:GetAbsOrigin(), 10 ) ) do
    if thing then
		print(thing)
		print(thing:GetName())
	end
  end
[/quote]

Зачем мне его искать если я вижу его в игре? Посмотри скрин выше. Он создается и даже пишит что включен, но как прикрутить срабатывание я не понимаю. Поэтому и спрашиваю тут.
 
Поверь, сделай проверку, как тебе предложил Cry. Может самой сущности нет, а какая-то оболочка присутствует (может это не триггер, а что-то другое).
 
Поверь, сделай проверку, как тебе предложил Cry. Может самой сущности нет, а какая-то оболочка присутствует (может это не триггер, а что-то другое).
Хотя я уверен что он создается сделал проверку для вас:

код:
Код:
local trigger = CreateTriggerRadiusApproximate(caster:GetAbsOrigin(), 300.0)
 for _,thing in pairs( Entities:FindAllInSphere(caster:GetAbsOrigin(), 10 ) ) do
    if thing then
     print(thing)
     print(thing:GetName())
    end
  end

Вывод:
Код:
[ W Entity System    ]: Attempting to precache model for entity 464 [trigger_multiple] at 63.61 569.31 128.00, but model name is NULL
[  VScript       ]: table: 0x033c8ec8
[  VScript       ]: 
[  VScript       ]: table: 0x033c9018
[  VScript       ]: 
[  VScript       ]: table: 0x033c9040
[  VScript       ]: 
[  VScript       ]: table: 0x033b7c00
[  VScript       ]: npc_dota_hero_axe

первый из них мой созданный триггер, проверил.
 
Последнее редактирование модератором:
К слову, в CBaseEntity есть функция
Код:
Trigger	void Trigger()	Fires off this entity's OnTrigger responses

что она делает, проверить не удалось, извращался как мог, но скорей всего в ней кроеется вся суть.
Реагирует на некоторые функции из CBaseEntity такие как GetCenter() , GetHealth(), что еще раз подтверждает ее нахождение в игре.
 
userdata не посмотреть, ты прав.
Попробуй такую штуку для проверки нахождения триггера
Я чутка идиот, не то посоветовал.
Код:
for _,thing in pairs( Entities:FindAllInSphere(unit:GetAbsOrigin(), 10 ) ) do
    if thing then
		print(thing)
		print(thing:GetClassname())
	end
  end
 
Последнее редактирование модератором:
[quote author=CryDeS link=topic=1359.msg8579#msg8579 date=1488278891]
Я чутка идиот, не то посоветовал.
Код:
for _,thing in pairs( Entities:FindAllInSphere(unit:GetAbsOrigin(), 10 ) ) do
    if thing then
		print(thing)
		print(thing:GetClassname())
	end
  end
[/quote]

Код:
[  VScript       ]: trigger_multiple
[  VScript       ]: dota_item_wearable
[  VScript       ]: dota_item_wearable
[  VScript       ]: npc_dota_hero_axe
[  VScript       ]: __self: userdata: 0x03328d00
 
[quote author=RecoveryIt link=topic=1359.msg8580#msg8580 date=1488278971]
Код:
[  VScript       ]: trigger_multiple
[  VScript       ]: dota_item_wearable
[  VScript       ]: dota_item_wearable
[  VScript       ]: npc_dota_hero_axe
[  VScript       ]: __self: userdata: 0x03328d00
[/quote]
Задача решена, не?
Код:
local trigger = (тут создаешь триггер)
local unit = (тут получаешь своего юнита как нибудь)

for _,thing in pairs( Entities:FindAllInSphere(unit:GetAbsOrigin(), 10 ) ) do
    if thing and trigger == thing then
		print("TOUCH")
	end
  end

UPD:
Что можно сделать гораздо удобнее так:
Код:
function CBaseTrigger:IsTouching(hUnit)
	for _,thing in pairs( Entities:FindAllInSphere(hUnit:GetAbsOrigin(), 10 ) ) do
 	   if thing and self == thing then
			return true
		end
	end
	return false
end
 
Последнее редактирование модератором:
Либо, можно вручную высчитать столкновение через координаты, благо CBaseTrigger наследуется от CBaseEntity, и имеет GetAbsOrigin и GetBoundingMaxs/GetBoundingMins.
 
[quote author=CryDeS link=topic=1359.msg8581#msg8581 date=1488279063]
Задача решена, не?
Код:
local trigger = (тут создаешь триггер)
local unit = (тут получаешь своего юнита как нибудь)

for _,thing in pairs( Entities:FindAllInSphere(unit:GetAbsOrigin(), 10 ) ) do
    if thing and trigger == thing then
		print("TOUCH")
	end
  end
[/quote]

Я незнаю в какой момент это произойдет, поэтому придется делать таймеры, для каждого триггера.
Ладно, буду делать как раньше.
 
Последнее редактирование модератором:
Я незнаю в какой момент это произойдет, поэтому придется делать таймеры, для каждого триггера.
Ладно, буду делать как раньше.
Так тебе нужно прикрепить эвент OnTouch? Это вроде нельзя сделать напрямую, ток костыли сильные.

UPD. Погугли, нашел на моддоте такую же проблему, что IsTouching() всегда возвращает false, но т.к это исправлено выше, попробуй сделать так:
trigger:ConnectOutput("OnStartTouch","MyFunctionName")
 
Последнее редактирование модератором:
[quote author=CryDeS link=topic=1359.msg8585#msg8585 date=1488279785]
Так тебе нужно прикрепить эвент OnTouch? Это вроде нельзя сделать напрямую, ток костыли сильные.
[/quote]

Да, именно это.
Кстати мб кто слышал о таком ивенте 'dota_unit_event' в BMD он есть ,но не работает.
Код:
ListenToGameEvent('dota_unit_event', Dynamic_Wrap(GameMode, 'OnDotaUnitEvent'), self)

Функции OnDotaUnitEvent нету, а когда создаешь свою c принтами , что бы узнать какие ключи передает, никак не срабатывает, пробовал делать очень много действий , от убийств крипов/героев , прокачка использование абилок и предметов , просто бегал, умирал. Ни при каких условиях ниразу не сработал.
 
[quote author=RecoveryIt link=topic=1359.msg8586#msg8586 date=1488280047]
Да, именно это.
Кстати мб кто слышал о таком ивенте 'dota_unit_event' в BMD он есть ,но не работает.
Код:
ListenToGameEvent('dota_unit_event', Dynamic_Wrap(GameMode, 'OnDotaUnitEvent'), self)

Функции OnDotaUnitEvent нету, а когда создаешь свою c принтами , что бы узнать какие ключи передает, никак не срабатывает, пробовал делать очень много действий , от убийств крипов/героев , прокачка использование абилок и предметов , просто бегал, умирал. Ни при каких условиях ниразу не сработал.
[/quote]
Я его не юзал, но есть большая вероятность что он банально не рабочий. Многие валвовские эвенты сломаны.
ps. глянь апдейт моего прошлого поста
 
Я его не юзал, но есть большая вероятность что он банально не рабочий. Многие валвовские эвенты сломаны.
ps. глянь апдейт моего прошлого поста

Вообщем погуглил, говорят триггер создается с классом trigger_multiple , который судя по всему не работает, либо работает как то иначе. Все же нужно создавать ентити в хаммере , после чего его можно спавнить там где нужно. Увы.
 
Последнее редактирование модератором:
Реклама: