Заказать Сервер Заказать Плагин Контакты Поиск

[ вход ]
[ последние сообщения ]

Страница 1 из 11
Форум » SourceMod - Counter Strike Source && CS GO » Уроки SourceMod (SourcePawn) Скриптинга » Работа с объектами (output) (HookSingleEntityOutput, HookEntityOutput)
Работа с объектами (output)
_wS_ Дата: Четверг, 15.03.2012, 18:46:46 | Сообщение # 1
output есть не у всех объектов, вот, например, у prop_dynamic :

Code
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);

Code
entity - индекс объекта
output - output имя, например, OnIgnite
callback - имя функции, которая будет вызвана
bool:once - если true, то хук выполнится только 1 раз и произойдет UnHook

Так можно ловить только определенные объекты


HookEntityOutput(const String:classname[], const String:output[], EntityOutput:callback);

Здесь все то же самое, но вместо индекса объекта используется его имя класса (classname). Тут ловиться будет не 1 объект, как выше, а каждый, чей classname равен тому, что вы указали. Ниже примеры (позже).
 
_wS_ Дата: Пятница, 16.03.2012, 12:08:50 | Сообщение # 2
После рождения игрока, рядом с ним появится предмет. Стреляйте по нему, пока не увидите сообщение в чате, после каждого выстрела будет добавлять вам + 1 hp. Потом прикоснитесь к предмету, он удалится и вам установится 1 hp. Это поможет вам понять, как работают эти Hook функции.

Code
#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, то лучше сделать так:

Code
public OnPluginStart()
{
     HookEntityOutput("prop_dynamic", "OnTakeDamage", EntityOutput:OnTakeDamage_Func);
}

// Функция точно такая же:

public OnTakeDamage_Func(const String:output[], caller, activator, Float:delay)
{

}


Если хотите перестать ловить момент, то:

Code
UnhookEntityOutput("prop_dynamic", "OnTakeDamage", EntityOutput:OnTakeDamage_Func);

Прикрепления: test.sp(3Kb)
 
Naykon Дата: Понедельник, 24.09.2012, 19:24:29 | Сообщение # 3
Сообщений: 439
Репутация: -5 [ +/- ]
Вот что мне нужно спс =)

Добавлено (22.09.2012, 13:01:31)
---------------------------------------------
ааааааа тревога))))

Code
#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);
      }
}


Перестало работать wS убедись сам.... после обновы фигня какаето((((((

Добавлено (23.09.2012, 04:34:48)
---------------------------------------------
Основывался на этом - http://world-source.ru/forum/128-2303-1#17094

Добавлено (24.09.2012, 19:24:29)
---------------------------------------------
Народ после обновы пример перестал работать у кого работает напишите каким metamod sourcemod sdkhooks вы пользуетесь??? ПОЖАЛУЙСТА НЕ ПОЛЕНИТЕСЬ ОЧЕНЬ НУЖНО 2 СУТКИ НЕ МОГУ ПОДОБРАТЬ НУЖНЫЕ ВЕРСИИ ПЛАГИНОВ((

 
scorpion2904 Дата: Понедельник, 24.09.2012, 20:58:19 | Сообщение # 4
Сообщений: 69
Репутация: 5 [ +/- ]
Quote (Naykon)
Народ после обновы пример перестал работать у кого работает напишите каким metamod sourcemod sdkhooks вы пользуетесь??? ПОЖАЛУЙСТА НЕ ПОЛЕНИТЕСЬ ОЧЕНЬ НУЖНО 2 СУТКИ НЕ МОГУ ПОДОБРАТЬ НУЖНЫЕ ВЕРСИИ ПЛАГИНОВ((

такая же проблема
 
_wS_ Дата: Вторник, 25.09.2012, 04:25:41 | Сообщение # 5
Я проверил, прекрасно работает этот пример, и sdkhooks не нужен здесь.
Бери последнюю версию SM от сюда.
 
Naykon Дата: Среда, 26.09.2012, 01:06:20 | Сообщение # 6
Сообщений: 439
Репутация: -5 [ +/- ]
на 74 проверь)) на 75 и у меня заработал)
 
Форум » SourceMod - Counter Strike Source && CS GO » Уроки SourceMod (SourcePawn) Скриптинга » Работа с объектами (output) (HookSingleEntityOutput, HookEntityOutput)
Страница 1 из 11
Поиск: