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

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

Страница 1 из 11
Форум » SourceMod - Counter Strike Source && CS GO » Уроки SourceMod (SourcePawn) Скриптинга » Создание/Поиск объектов (entity)
Создание/Поиск объектов (entity)
_wS_ Дата: Пятница, 13.01.2012, 09:44:51 | Сообщение # 1
Каждая карта состоит из множества объектов (entity), многие из которых можно изменять/добавлять/удалять.
Информацию о многих объектах можете найти здесь:

https://developer.valvesoftware.com/wiki/Category:Entities

Например, func_buyzone, weapon_awp, player, env_beam - всё это объекты, их довольно много. У каждого из них есть свои параметры, подробнее узнать о которых вы можете благодаря этим ссылкам:

http://world-source.ru/datamaps.txt
http://world-source.ru/netprops.txt

Пример создания weapon_awp:

Code
#include <sourcemod>
#include <sdktools>

new Float:wS_Pos[3];

public OnPluginStart()
{
     HookEvent("player_say", player_say);
}

public player_say(Handle:event, const String:name[], bool:dontBroadcast)
{
     new client = GetClientOfUserId(GetEventInt(event, "userid"));
     decl String:f[5];
     GetEventString(event, "text", f, 5);
     if (StrEqual(f, "1"))
     {
        GetClientAbsOrigin(client, wS_Pos);
        wS_Pos[2] += 55.0;
        PrintToChat(client, "Координаты получены. Введите 2 чтобы создать awp.");
     }
     else if (StrEqual(f, "2")) CreateEnt();
}

CreateEnt()
{
     new index = CreateEntityByName("weapon_awp");
     if (index < 1)
     {
        LogError("Ошибка при создании weapon_awp");
        return;
     }
     DispatchKeyValueVector(index, "origin", wS_Pos);
     DispatchKeyValue(index, "spawnflags", "1");
     DispatchSpawn(index);
}

Сначала введите в чат 1, чтобы сохранить позицию, затем отойдите и введите 2, чтобы создать awp.
spawnflags - флаги. Перейдите по ЭТОЙ ссылке и найдите 'Flags'. Вот что там:

Code
1 : Start Constrained    
Prevents the model from moving.

Это значит, что если установить флаг 1, то awp не будет двигаться. Часто есть несколько флагов у объектов и бывает нужно установить несколько сразу. Для это нужно просто сложить числа нужных вам флагов.

Если вы знаете, что на карте есть только 1 какой-либо объект, и вы хотите узнать его индекс, то вам поможет команда FindEntityByClassname, которая может найти индекс по classname объекта. Например, после установки бомбы это уже не weapon_c4, а planted_c4, вот как легко можно получить индекс:

Code
new index = FindEntityByClassname(-1, "planted_c4");

Если индекс не был получен, то будет возвращено -1 (просто делайте проверку, если index > 0, значит это то, что нужно).

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

Code
new index = -1;
while ((index = FindEntityByClassname(index, "func_buyzone")) > 0)
{
     PrintToServer("Найден индекс: %d", index);
}

FindEntityByClassname(index - это индекс объекта, после которого будем искать func_buyzone.
Чтобы начать поиск с самого начала, пишут -1 (0 это worldspawn).

CreateEntityByName(const String:classname[], ForceEdictIndex=-1);

Создаёт объект (но не рождает, см. DispatchSpawn) и возвращает его индекс, или -1, если не удалось создать.
ForceEdictIndex - индекс, который будет у этого объекта (игнорируется в Orangebox).

bool:DispatchKeyValue(entity, const String:keyName[], const String:value[]);
Настройка параметров объекта, например, origin и angles (у всех), BoltWidth и Radius у env_beam (см. datamaps.txt)

bool:DispatchKeyValueFloat(entity, const String:keyName[], Float:value);
То же самое, только устанавливаемое значение это Float

bool:DispatchKeyValueVector(entity, const String:keyName[], const Float:vector[3]);
Устанавливает вектор

bool:DispatchSpawn(entity_index); - создает (оживляет) объект на карте в origin позиции.
ActivateEntity(entity_index); - активация (CBaseAnimating :: Activate)

SetEntityModel(entity, const String:model[]); - установить модель.
Указывается полный путь models/...mdl, но перед этим, модель должна быть кэширована - обычно в OnMapStart().

Code
PrecacheModel("models/...mdl", true);
 
Санчоус Дата: Среда, 08.08.2012, 03:00:24 | Сообщение # 2
Сообщений: 1
Репутация: 0 [ +/- ]
Скажите пожалуйста, как сделать чтобы энтити удалялось не у всех а выборочно?

Code
new Kills[MAXPLAYERS+1];

public OnPluginStart()
{
   HookEvent("player_spawn", player_spawn);
   HookEvent("player_death", player_death);
}

public Action:Command_Trail(client)
{
   CreateTimer(10.0, Kill_Effects, client);
   дальше спавн трейла
}

public Action:Kill_Effects(Handle:timer, any:client)
{
   new index = -1;
   while ((index = FindEntityByClassname(index, "env_spritetrail")) > 0)
   {
     AcceptEntityInput(index, "Kill"); // вот здесь он убивает все трейлы
   }
}

public player_spawn(Handle:event, const String:name[], bool:dontBroadcast)
{
   new client = GetClientOfUserId(GetEventInt(event, "userid"));
   CreateTimer(0.1, Kill_Effects, client);
}

public player_death(Handle:event, const String:name[], bool:dontBroadcast)
{
   new h_attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
   if (h_attacker > 0 && GetClientTeam(h_attacker) != GetClientTeam(h_victim))
   {
     Kills[h_attacker] += 1;
   }
   if (Kills[h_attacker] == 3)
   {
     Command_Trail(h_attacker);
    }
}


*** Кое-что вырезал
Если сделать 3 кила вызывается трейл на 10 секунд. После смерти трейл остается, мне его нужно убрать, для этого делаю CreateTimer(0.1, Kill_Effects, client) - это работает, но трейлы убираются все, то есть убитый тобой человек вызовет этот таймер и убъет сразу тебе трейл. Как сделать чтобы убиралось только на том, кого убили? =)
Набыдлокодил, конечно, но, надеюсь, понятно объяснил - хочу научиться, активно читаю тут уроки. Помогите исправить, пожалуйста!


Сообщение отредактировал Санчоус - Среда, 08.08.2012, 03:02:00
 
_wS_ Дата: Среда, 08.08.2012, 03:54:16 | Сообщение # 3
Сохраняй индекс trail'а игрока в глобальной переменной.
И когда он умирает, покидает сервер, переходит в spec - убивай его trail.

Code
new MyTrail[MAXPLAYERS+1];

new index = CreateEntityByName("env_spritetrail");
// .......
MyTrail[client] = index;

player_spawn
{
     MyTrail[client] = 0;
}

Хотя может есть и проще вариант. Например, сделать родителем (parent) trail'а нож игрока, чтобы нож удалялся вместе с trail'ом - вроде нож убивается в случае смерти/выхода/перехода в спек и тд - нужно тестировать.
 
Naykon Дата: Вторник, 09.10.2012, 19:47:13 | Сообщение # 4
Сообщений: 439
Репутация: -5 [ +/- ]
А можно на карте без зоны покупак создать зону покупок???
 
scorpion2904 Дата: Суббота, 17.11.2012, 10:48:12 | Сообщение # 5
Сообщений: 69
Репутация: 5 [ +/- ]
А можно сделать, чтобы объект исчезал при нажатии на него?
 
Nailain Дата: Четверг, 14.02.2013, 13:44:41 | Сообщение # 6
Сообщений: 19
Репутация: 1 [ +/- ]
А как найти индекс объекта не по classname а по его имени?


Сообщение отредактировал Nailain - Четверг, 14.02.2013, 13:45:31
 
king(rus) Дата: Понедельник, 04.11.2013, 16:19:56 | Сообщение # 7
Сообщений: 109
Репутация: 2 [ +/- ]
_wS_, как на счет того, чтоб вводя 1, мог создавать предмет, допустим props/cs_office/vending_machine.mdl?
 
dron216 Дата: Четверг, 23.01.2014, 18:57:40 | Сообщение # 8
Сообщений: 152
Репутация: 18 [ +/- ]
Цитата Nailain ()
А как найти индекс объекта не по classname а по его имени?

Знает кто? Тоже интересует этот вопрос...
 
tolik1231 Дата: Пятница, 13.01.2017, 12:54:58 | Сообщение # 9
Сообщений: 46
Репутация: 0 [ +/- ]
CreateEntityByName("info_particle_system"); - пожалуйста расскажите поподробней по этому Обьекту.
 
Форум » SourceMod - Counter Strike Source && CS GO » Уроки SourceMod (SourcePawn) Скриптинга » Создание/Поиск объектов (entity)
Страница 1 из 11
Поиск: