Различные примеры простых кодов для новичков в Source Pawn

Узнали ли вы что либо новое для себя?


  • Всего проголосовало
    86

Satan

Участник
Сообщения
159
Реакции
338
По настроению буду здесь выкладывать простые примеры для новичков в Source Pawn.



Это полезно в первую очередь для новичков!
Для "продвинутых" юзеров на мой взгляд пост не актуален


Пример №1 : Плагин для добавления возможности играть только за КТ

Исходник:
PHP:
/**
	Данный скрип является ознакомительным;
	
	Обновления и т.д. не будет;
	
	За возможные варианты обхода не несу ответственности;
	
	Можете использовать любую часть кода в своих целях.
	
	P.s. Если есть какие то ошибки, извиняйте. Писал за 3 минуты :)
	
	P.s.s. Оптимальнее отлавливать не player_spawn а player_team ... но это уже в другой раз 
	
**/

// include
#include <sourcemod>
#include <cstrike>


// Информация о авторе плагина
public Plugin:myinfo =
{
	name 	= 	"",
	author 	=	"",
	version = 	"1.0"
};

public OnPluginStart()
{
	// Регистрация момента попытки перехода в другую команду
	AddCommandListener(ChooseTeam, "jointeam");
	//  Отлов события "ВОЗРОЖДЕНИЕ ИГРОКА"
	HookEvent("player_spawn", 		OnPlayerSpawn);
}


// Действие при при переходе
public Action:ChooseTeam(client, const String:command[], args)  
{
	if (client == 0)
		return Plugin_Continue;
	
	decl String:teamString[3];
	GetCmdArg(1, teamString, sizeof(teamString));
	new Target_Team = StringToInt(teamString);
	
	// Предотвращение выбора команды Т
	if (Target_Team == CS_TEAM_T)
	{
		// Сообщение игроку в Hint [Область подсказок]
		PrintHintText(client, "Вы можете играть только за КТ!" );
		// Сообщение игроку в чате
		PrintToChat(client, "\x05[SM]\x04 Можно играть только за КТ");
		// Повторное открытие панели выбора команды
		ShowVGUIPanel(client, "team");
		return Plugin_Handled;
	}
	return Plugin_Continue; 
}


// Событие респауна игрока
public Action:OnPlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast)
{
	// Узнаем id игрока на сервере
	new client = GetClientOfUserId(GetEventInt(event, "userid"));

	 
	// Проверяем клиента:
	// !IsFakeClient - клиент не должен быть ботом
	// GetClientTeam(client) == CS_TEAM_T  - Команда клиента должна быть Т
	if (!IsFakeClient(client) && GetClientTeam(client) == CS_TEAM_T)
	{
		// Меняем команду клиенту с Т на КТ
		CS_SwitchTeam(client, CS_TEAM_CT);
		// Возрождаем клинта
		CS_RespawnPlayer(client);
		// Выводим в чат сообщение для клиента
		PrintToChat(client, "\x05[SM]\x04 Вы были автоматический перенесены в команду КТ.");
	}
	return Plugin_Continue;
}


Пример №2 "Отлов" события "РАУНД СТАРТ", вывод текста всем игрокам в чат при этом событии. Открытие вашего сайта в окне motd игроку, который ввел некую команду в чат


Исходник:
PHP:
// include
#include <sourcemod>
#include <cstrike>


public OnPluginStart()
{
	// Отлов события РАУНД СТАРТ
	HookEvent("round_start", 		OnRoundStart);
	
	// Регистрация консольной команды (+ чат команды)
	RegConsoleCmd("hlmod", CommandSay);
}


// Событие РАУД СТАРТ
public Action:OnRoundStart(Handle:event, const String:name[], bool:dontBroadcast)
{
	// В начале каждого раунда выводим в чат всем игрокам сообщение
	PrintToChatAll("\x05[SM] \x04Напишите в чате \x03!hlmod\x04, чтобы посетить наш сайт");
}

// Действие при отлове команды
public Action:CommandSay(client, args) 
{
	// Открываем окно motd, и отображаем там сайт
	ShowMOTDPanel(client,"Сообщество администраторов игровых серверов", "http://hlmod.ru/", MOTDPANEL_TYPE_URL);
	// Возвращаем остановку плагина (Чтобы не писало в консоли unknown command)
	return Plugin_Handled;
}


Пример №3 "Отлов" события "ВОЗРОЖДЕНИЕ ИГРОКА", Удаление всего оружия у игрока через 1.0 сек после данного события
P.s Полезен сам stock RemoveAllWeapons

Исходник:
PHP:
 /**
	1)	Данный образец плагина удаляет у всех игроков ВСЕ оружие через 1.0 секунду после возрождения
	
	2)	Вы можете использовать stock Remove All Weapons в других событиях и условиях.
	
	2)	Этот образец НЕ предотвращает покупку и поднятие оружия. 
		Т.е. если на карте есть оружие или зона закупки игроки смогут купить себе оружие
**/

// include
#include <sourcemod>
#include <sdktools>
#include <sdkhooks>

public OnPluginStart()
{
	//	Отлов события ВОЗРОЖДЕНИЕ ИГРОКА
	HookEvent("player_spawn", OnPlayerSpawn);
}


//	Событие спавна игрока
public OnPlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast) 
{
	//	Узнаем id игрока на сервере
	new client = GetClientOfUserId(GetEventInt(event, "userid"));
	
	// Запускаем таймер для клиента (в 1.0 сек)
	CreateTimer(1.0, TimerPlayerSpawn, client);
}


// Действие при срабатывании таймера 
public Action:TimerPlayerSpawn(Handle:timer, any:client)
{	
	//	Проверяем игрока:
	// IsClientInGame(client) - Клиент должен быть в игре
	// IsPlayerAlive(client) - клиент должен быть жив
	// && -оба условия должны выполняться
	if (IsClientInGame(client) && IsPlayerAlive(client))
	{
		// Выполняем на клиенте stock RemoveAllWeapons
		RemoveAllWeapons(client);
		
		// Проверка игрока:
		// !IsFakeClient(client) - клиент НЕ должен быть ботом
		if (!IsFakeClient(client))
			// Если клиент не бот, то выводим ему текст в чат
			PrintToChat(client, "\x05[SM]\x04 Все ваше оружие было удалено.");
	}
}


// С stock сами разбирайтесь :)
stock RemoveAllWeapons(client) 
{
    
    if(!IsClientInGame(client) || !IsPlayerAlive(client) || !Client_IsPlayer(client) || !IsValidEdict(client))
        return -1;
    
    new String:clientNetClass[64];
    
    if(!GetEntityNetClass(client,clientNetClass,sizeof(clientNetClass))){
        return -1;
    }
    
    new offset_PlayerWeapons = FindSendPropOffs(clientNetClass, "m_hMyWeapons");
    
    if(offset_PlayerWeapons == -1){
        LogError("[SMLIB] Error: Can't get m_hMyWeapons from client '%N' clientindex: %d offset: %d. Wrong playernetclass? PlayerNetClass is: %s",client,offset_PlayerWeapons,clientNetClass);
        return -1;
    }
    
    new entity;
    new removedweapons = 0;
    new bool:success;
    
    for (new offset=0;offset<128;offset+=4){
        
        entity = GetEntDataEnt2(client, offset_PlayerWeapons+offset);
        
        if (IsValidEdict(entity) && IsValidEntity(entity)){
            
            success = RemovePlayerItem(client,entity);
            if(!success){continue;}
            RemoveEdict(entity);
            removedweapons++;
        }
    }
    
    return removedweapons;
}

stock bool:Client_IsPlayer(entity) 
{
    
    if (entity > GetMaxEntities()) 
	{
        entity = EntRefToEntIndex(entity);
    }

    if (entity >= 1 && entity <= MaxClients) {
        if (IsValidEntity(entity) && IsClientInGame(entity)) 
		{
            return true;
        }
    }
    
    return false;
}


Пример №4 "Отлов" события "СМЕРТЬ ИГРОКА", Вывод сообщения игроку которого убили с ником его убийцы из файла перевода
P.s Описание к коду завтра дополню ибо щас ухожу.


Исходник:
PHP:
// 	include
#include <sourcemod>
#include <sdktools>



public OnPluginStart() 
{
	//	Отлов события СМЕРТЬ ИГРОКА		( EventHookMode_Post означает, что событие сработает с задержкой, а не одновременно со смертью игрока )
	HookEvent("player_death", OnPlayerDeath, EventHookMode_Post);
	
	// Загружаем файл перевода (в кавычках его название без расширения .txt)
	LoadTranslations("test.phrases");
}


//	Событие СМЕРТЬ ИГРОКА
public Action:OnPlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
	//    Узнаем id игрока, которого убили, на сервере
	new victim   = 	GetClientOfUserId(GetEventInt(event, "userid"));
	
	//    Узнаем id игрока на сервере который убил
	new client 	 = 	GetClientOfUserId(GetEventInt(event, "attacker"));
	
	// Проверяем индекс клиента
	if (!(client != victim && client != 0))
		return Plugin_Continue;
		
		
	//	Получаем ник игрока
	decl String:Name[32];
	GetClientName(client, Name, sizeof(Name));
	
	//	Выводим сообщение игроку, которого убили, о том, кто его убил
	//	victim - выводим сообщение игроку КОТОРОГО убили

	PrintToChat(victim, "\x05[SM]\x04 %t %s", "TEST", Name);
	
	// Возвращаем продолжение работы плагина
	return Plugin_Continue;
}

Содержимое test.phrases.txt

PHP:
"Phrases"
{
	"TEST"
	{
		"en"			"you killed a player:"
		"ru"			"Вас убил игрок:"
	}
}


P.S. Уважайте чужое время и труд.

Данные коды являются примерами. Если вы обнаружите ошибки просьба сообщить о них в комментариях
 

Вложения

  • Lock_T_team.sp
    2.8 КБ · Просмотры: 17
  • Motd.sp
    1.1 КБ · Просмотры: 26
  • AllWeaponRemove.sp
    3.5 КБ · Просмотры: 20
  • PrintToChat.zip
    3.1 КБ · Просмотры: 31
Последнее редактирование:

S1deX

Скриптер ;)
Сообщения
129
Реакции
204
Re: Пример кода для предотвращения перехода в какую либо команду

Молодец, плюс за старания. Лови критику ;)

Замечания:
1) Выделение памяти под g_bEnabled, когда она по сути не юзается.
2) Смотри логику:
Событие player_spawn вызывается когда? При "оживании" игрока. Зачем проверка на не "мертвость"? Да, есть прикол у сорс движка, что при заходе на серв евент тоже вызывается. Но ведь ты позже жестко проверяешь команду игрока. Так что эта проверка - лишняя операция.
3) Да, я понимаю, в официальном вики примеры по отлавливанию команд написаны с помощью RegConsoleCmd. Но все же форум тоже нужно почитывать. Для отлова уже существующих команд лучше использовать AddCommandListener, который, в отличии от RegConsoleCmd, создает легкий хук на команду, а не фактически регистрирует ее заново.
Пруф линки на AddCommandListener:
Так называемые Tips'n'Tricks
AddCommandListener в API
Callback для AddCommandLstener
 

Satan

Участник
Сообщения
159
Реакции
338
Re: Пример кода для предотвращения перехода в какую либо команду

S1deX

1) Выделение памяти под g_bEnabled, когда она по сути не юзается.
Убрал

Зачем проверка на не "мертвость"? Да, есть прикол у сорс движка, что при заходе на серв евент тоже вызывается. Но ведь ты позже жестко проверяешь команду игрока. Так что эта проверка - лишняя операция.
Просмотрел, исправил.

Для отлова уже существующих команд лучше использовать AddCommandListener, который, в отличии от RegConsoleCmd
Заменил

Спасибо за подсказки
 

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #4
Такс.. почистил тему от старых и не нужных постов. Пожалуй апну её, а по возможности буду обновлять.
"Новички", напишите примеры чего написать.
 

White Wolf

🍉
Сообщения
2,382
Реакции
2,187
  • Команда форума
  • #5
R1KO, работу с methodmap напиши :)
 

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #6
Ок. еще пару предложений будет и напишу сразу все.
 
Сверху Снизу