[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Форум » Форум » Уроки SourceMod (SourcePawn) Скриптинга » Работа с объектами (output) (HookSingleEntityOutput, HookEntityOutput Взято с world-sourc)
Работа с объектами (output)
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);
 
Форум » Форум » Уроки SourceMod (SourcePawn) Скриптинга » Работа с объектами (output) (HookSingleEntityOutput, HookEntityOutput Взято с world-sourc)
  • Страница 1 из 1
  • 1
Поиск: