[SourcePawn] Урок 12 - methodmap

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #1
[SourcePawn] Урок 12 - methodmap

<- К содержанию

methodmap - Это структура описывающая методы для работы с определенным типом и свойства этого типа.

Рассмотрим пример для типа MyType (тип придумал):
PHP:
methodmap MyType // Указывает название типа.
{
    // Если в названии написано Тип < Базовый_тип (например MyType < Handle)
    // То это говорит о том, что наш тип является производным от базового типа
 
    // ****************************************
    // *************  МЕТОДЫ  *****************
    // ****************************************
 
    // Метод MyFunc1 имеет тип void, следовательно он просто выполняет какое-то действие.
    // Используем как и все методы MyObj.MyFunc1("arg");
    public void MyFunc1(const char[] szArg1)
    {
        // Реализация метода
    }
 
    // Метод MyFunc2 имеет тип int, значит что он возвращает целочисленное значение.
    // Ключевое слово native указывает на то что ф-я является внешней и реализуется в другом месте плагина или другим плагином или расширением
    public native int MyFunc2(int iArg1);
 
    // Метод MyFunc3
    // Ключевое слово static указывает что ф-я должна вызываться не от экземпляра типа, а от самого типа
    // Пример:
    //        MyType MyObj = CreateMyType();
    //         MyObj.MyFunc2(3); // Вызов ф-и экземпляром типа
    //         MyType.MyFunc3(7); // Вызов ф-и типом
    public static native bool MyFunc3(int iArg1);
 
    // Пример из реального типа
    // Это выражение уже устарело, но его всё еще можно встретить.
    // Оно указывает что тип, параметры и реализация метода идентичны указанной ф-и
    // Конкретно это выражение говорит:
    // WritePackCell(hDataPack, 8); // Использовали
    // hDataPack.WriteCell(8); // А теперь надо так
    public WriteCell() = WritePackCell;


    // ****************************************
    // *************  СВОЙСТА  *****************
    // ****************************************
 
    // Свойство Position
    property int Position
    {
        // Со свойствами работать просто. Им либо присваиваются значения, либо получают их значения.

        // Имя get говорит о том, что можно получать значение этого свойства
        public get()
        {
            // Возвращаем значение. Об this.Index расскажу позже
            return GetPosition(this.Index); // Ф-я GetPosition придумана
        }

        // Имя set говорит о том, что можно присваимать значение этому свойству
        public set(int iPos)
        {
            return SetPosition(iPos); // Ф-я SetPosition придумана
        }
    }
 
    // Так же устаревшая форма записи, которая использовалась только для перехода на новый синтаксис.
    property int Position
    {
        public get() = GetPackPosition;
        public set() = SetPackPosition;
    }
 
    // Подробнее об this.Index
    // В каждом metodmap есть скрытый параметр this
    // Он указывает на текущий объект
    // Например
    //        MyType MyObj = CreateMyType();
    //         MyObj.MyFunc2(3); // Вызов ф-и экземпляром типа
    // В любом свойстве или методе параметр this будет указывать на объект MyObj

    // Это свойство получает индекс объекта
    // Например, если у нас есть тип Player,
    // где каждый экземпляр это игрок,
    // то чтобы через объект получить индекс игрока
    // (по сути сам объект типа Player может быть равен индексу, или же serialid, или userid, или вообще использовать собсвтенный счетчик)
    // используется это свойство
    property int Index
    {
        // Свойство можно только получать
        public get()
        {
            // Приводим текущий объект к типу int
            return view_as<int>(this);
        }
    }
};
 
Последнее редактирование модератором:

White Wolf

🍉
Сообщения
2,382
Реакции
2,187
  • Команда форума
  • #2
@R1KO, считаю methodmap'ы пока что бесполезными, так как все свойства/методы у них публичные. Это равносильно обычным глобальным переменным/ф-циям.
 

Nekro

Терра инкогнита
Сообщения
4,042
Реакции
2,295
Найдётся добрый человек дать пример плагина с methodmap?
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,569
Реакции
5,071
@Nekro, вроде в дефолтных должно быть много примеров.
 

DENZEL519

Работаю с AI !
Сообщения
453
Реакции
242
@Nekro, Вот пример плагина для SourceMod, использующий MethodMap для создания объектно-ориентированного интерфейса для работы с игроками.

C-подобный:
#pragma semicolon 1
#pragma newdecls required

#include <sourcemod>

// Объявляем MethodMap для игрока
methodmap CPlayer {
    // Конструктор (принимает userid или client index)
    public CPlayer(int client) {
        return view_as<CPlayer>(client);
    }

    // Проверка, валиден ли игрок
    property bool IsValid {
        public get() {
            int client = view_as<int>(this);
            return (client > 0 && client <= MaxClients && IsClientInGame(client));
        }
    }

    // Получение ника игрока
    public void GetName(char[] buffer, int maxlen) {
        if (this.IsValid) {
            GetClientName(view_as<int>(this), buffer, maxlen);
        }
    }

    // Телепортация игрока к точке
    public void Teleport(float pos[3], float ang[3] = NULL_VECTOR) {
        if (this.IsValid) {
            TeleportEntity(view_as<int>(this), pos, ang, NULL_VECTOR);
        }
    }

    // Установка здоровья
    property int Health {
        public get() {
            return this.IsValid ? GetClientHealth(view_as<int>(this)) : -1;
        }
        public set(int value) {
            if (this.IsValid) {
                SetEntityHealth(view_as<int>(this), value);
            }
        }
    }
}

public Plugin myinfo = {
    name = "MethodMap Example",
    author = "DENZEl519&AI",
    description = "Пример использования MethodMap",
    version = "1.0",
};

public void OnPluginStart() {
    RegConsoleCmd("sm_test", Command_Test);
}

public Action Command_Test(int client, int args) {
    if (client == 0) {
        ReplyToCommand(client, "Команда доступна только в игре.");
        return Plugin_Handled;
    }

    CPlayer player = new CPlayer(client); // Создаем объект игрока

    char name[32];
    player.GetName(name, sizeof(name));

    float pos[3];
    GetClientAbsOrigin(client, pos);
    pos[2] += 50.0; // Поднимаем игрока на 50 единиц

    player.Teleport(pos); // Телепортируем
    player.Health = 100; // Устанавливаем здоровье

    ReplyToCommand(client, "Игрок %s телепортирован вверх!", name);

    return Plugin_Handled;
}

Что делает этот плагин?​

  1. Определяет MethodMap CPlayer – это "класс" для удобной работы с игроком.
  2. Имеет свойства и методы:
    • IsValid – проверка, жив ли игрок.
    • GetName() – получение ника.
    • Teleport() – телепортация игрока.
    • Health – геттер/сеттер для здоровья.
  3. Команда sm_test – демонстрирует работу MethodMap:
    • Поднимает игрока в воздух.
    • Восстанавливает здоровье.

Зачем использовать MethodMap?​

  • Удобство – инкапсуляция логики (например, проверка IsValid перед действиями).
  • Читаемость – код выглядит ООП-стилем (player.Health = 100 вместо SetEntityHealth(client, 100)).
  • Безопасность – можно встроить проверки прямо в методы.
 
Сверху Снизу