root | Дата: Воскресенье, 03.02.2013, 00:33 | Сообщение # 1 |
Генералиссимус
Группа: Администраторы
Сообщений: 561
Статус: Offline
| output есть не у всех объектов, вот, например, у prop_dynamic :
Код OnAnimationBegun OnAnimationDone Вызывается, когда анимация начинается/заканчивается
OnIgnite Вызывается, когда этот объект загорелся.
OnBreak Вызывается, когда предмет ломается (удаляется) (activator is the breaker)
OnTakeDamage Объект получил повреждение
OnHealthChanged <float> Здоровье объекта изменилось
OnPhysCannonDetach OnPhysCannonAnimatePreStarted
Все эти названия обычно с префиксом On. Где их искать? Зайдите, например, сюда: https://developer.valvesoftware.com/wiki/Prop_dynamic И замените в конце ссылки Prop_dynamic на classname нужного вам объекта. Еще можете использовать это:
http://world-source.ru/datamaps.txt http://world-source.ru/netprops.txt
Вот функции, позволяющие ловить эти моменты:
HookSingleEntityOutput(entity, const String:output[], EntityOutput:callback , bool:once=false);
Код entity - индекс объекта output - output имя, например, OnIgnite callback - имя функции, которая будет вызвана bool:once - если true, то хук выполнится только 1 раз и произойдет UnHook
Так можно ловить только определенные объекты
HookEntityOutput(const String:classname[], const String:output[], EntityOutput:callback);
Здесь все то же самое, но вместо индекса объекта используется его имя класса (classname). Тут ловиться будет не 1 объект, как выше, а каждый, чей classname равен тому, что вы указали. Ниже примеры (позже).
После рождения игрока, рядом с ним появится предмет. Стреляйте по нему, пока не увидите сообщение в чате, после каждого выстрела будет добавлять вам + 1 hp. Потом прикоснитесь к предмету, он удалится и вам установится 1 hp. Это поможет вам понять, как работают эти Hook функции.
Код #include <sourcemod> #include <sdktools_entoutput> #include <sdktools_functions>
new Float:wS_Pos[3];
public OnPluginStart() { HookEvent("player_spawn", player_spawn); }
public OnMapStart() { PrecacheModel("models/props/cs_office/vending_machine.mdl", true); }
public player_spawn(Handle:event, const String:name[], bool:dontBroadcast) { CreateTimer(1.0, CreateEnt_Timer, GetClientOfUserId(GetEventInt(event, "userid"))); }
public Action:CreateEnt_Timer(Handle:timer, any:i) { GetClientAbsOrigin(i, wS_Pos);
// Немного изменяем координату 'x', чтобы предмет был создан рядом с игроком, а не на его месте wS_Pos[0] += 80.0;
new index = CreateEntityByName("prop_dynamic"); if (index > 0) { SetEntityModel(index, "models/props/cs_office/vending_machine.mdl"); DispatchKeyValueVector(index, "origin", wS_Pos);
// Если бы это не сделали, то через предмет можно было проходить (solid 0) и OnTakeDamage не работало бы DispatchKeyValue(index, "solid", "6");
DispatchSpawn(index); HookSingleEntityOutput(index, "OnTakeDamage", EntityOutput:OnTakeDamage_Func, false);
PrintToChat(i, "Стреляйте по предмету"); } }
public OnTakeDamage_Func(const String:output[], caller, activator, Float:delay) { if (activator > 0 && activator <= MaxClients && IsClientInGame(activator) && IsPlayerAlive(activator)) { // Добавляем игроку, который нанес повреждение предмету, 1 hp new hp = GetClientHealth(activator) + 1; SetEntProp(activator, Prop_Send, "m_iHealth", hp); // Если hp игрока 105 или больше, то.. if (hp > 104) { // Перестаем ловить момент, когда предмет получает повреждение UnhookSingleEntityOutput(caller, "OnTakeDamage", EntityOutput:OnTakeDamage_Func);
// Устанавливаем предмету флаг '16 : Break on Touch' DispatchKeyValue(caller, "spawnflags", "16");
// Ловим момент, когда игрок дотрагивается до предмета и он ломается HookSingleEntityOutput(caller, "OnBreak", EntityOutput:OnBreak_Func, true);
// Говорим игроку, чтобы дотронулся до предмета PrintToChat(activator, "Теперь дотроньтесь до предмета"); } } }
public OnBreak_Func(const String:output[], caller, activator, Float:delay) { if (activator > 0 && activator <= MaxClients) { // Предмет удалился, устанавливаем игроку 1 hp SetEntProp(activator, Prop_Send, "m_iHealth", 1); } }
UnHook нужно делать только тогда, когда предмет жив и вы не хотите больше ловить какой-то момент. После того, как объект удаляется (в течение раунда или из-за старта нового), все UnHook'и делаются сами.
Если вы хотите отлавливать OnTakeDamage у всех prop_dynamic, то лучше сделать так:
Код public OnPluginStart() { HookEntityOutput("prop_dynamic", "OnTakeDamage", EntityOutput:OnTakeDamage_Func); }
// Функция точно такая же:
public OnTakeDamage_Func(const String:output[], caller, activator, Float:delay) {
}
Если хотите перестать ловить момент, то:
Код UnhookEntityOutput("prop_dynamic", "OnTakeDamage", EntityOutput:OnTakeDamage_Func);
|
|
| |