August 6, 2023

Методы Функции и аргументы в Glua Garrys Mod Lua API

Вступление:

В контексте Garry's Mod Lua API, термины "методы" и "функции" имеют те же основные определения, что и в общем программировании. Однако, в Garry's Mod Lua API они имеют некоторые специфические особенности:

Методы:

  • Методы в Garry's Mod Lua API являются функциями, которые связаны с определенными объектами или классами, предоставляемыми API.
  • Методы могут быть вызваны на конкретных объектах или экземплярах классов, чтобы выполнить определенные действия или получить доступ к свойствам объекта.
  • Методы могут иметь специальные параметры, такие как self, который ссылается на текущий объект, на котором вызывается метод.

Пример метода из Garry's Mod Lua API:

```lua
-- Создание нового игрока
local player = Player(1)
-- Вызов метода GetPos() на объекте player
local position = player:GetPos()
```

Функции:

  • Функции в Garry's Mod Lua API являются самостоятельными блоками кода, которые выполняют определенные действия или возвращают результаты.
  • Функции могут быть определены в любом месте кода и вызываться из других частей программы.
  • Функции могут принимать аргументы и возвращать значения.

Пример функции из Garry's Mod Lua API:

```lua
-- Функция для создания нового пропа
local function SpawnProp(model, position, angle)
    local prop = ents.Create("prop_physics")
    prop:SetModel(model)
    prop:SetPos(position)
    prop:SetAngles(angle)
    prop:Spawn()
    return prop
end
-- Вызов функции для создания пропа
local prop = SpawnProp("models/props_c17/oildrum001.mdl", Vector(0, 0, 0), Angle(0, 0, 0))
```

В общем, методы в Garry's Mod Lua API связаны с объектами или классами, предоставляемыми API, и могут быть вызваны на конкретных объектах. Функции в Garry's Mod Lua API являются самостоятельными блоками кода, которые могут быть вызваны из любой части программы.


используется self в классик функциях ?

В Garrys Mod Lua API, в классической функции, обычно не используется "self". Вместо этого, функции могут принимать параметры, которые передаются при вызове функции.

Например, в следующем коде функция myFunction принимает два параметра param1 и param2, которые могут быть использованы внутри функции:

function myFunction(param1, param2)
    print(param1 + param2)
end
myFunction(10, 20) -- Выводит 30


Методы с "ENT:"

В Garry's Mod Lua API, "function ENT:ddd()" описывает метод "ddd()" для объекта ENT (Entity). В этом контексте "ENT" представляет сущность или объект в игре, такой как игрок, предмет, NPC и т. д. Метод "ddd()" является пользовательским методом, который можно определить для расширения функциональности объекта ENT.

Приведенный ниже пример кода демонстрирует определение метода `ddd()` для объекта ENT:

```lua
function ENT:ddd()
    -- Код метода ddd()
end
```

Это позволяет вызывать метод `ddd()` на объектах ENT. Например:

```lua
local myEnt = ents.Create("my_entity")
myEnt:ddd()
```

Метод "ddd()" может содержать любую логику и действия, необходимые для объекта ENT. Важно помнить, что методы, определенные в ENT, должны быть определены с использованием двоеточия (`:`) вместо точки (`.`), чтобы передать объект ENT в качестве первого аргумента метода.

То есть - "ENT:" ставится в создаваемый метод где используется в аргументах Entity или класс - пример кода вам на глаз !

Пример кода.

аргумент "npcEntities" - является "Entity".

-- Внутри файла dv.lua

-- Определяем метод AttackIfVisible для класса dv
function ENT:AttackIfVisible(npcEntities, weaponClass)
    -- Проходимся по каждому объекту dm
    for _, npcEntity in pairs(npcEntities) do
        -- Проверяем видимость между текущим объектом dv и объектом dm
        if self:Visible(npcEntity) then
            -- Проверяем, если dm является NPC
            if npcEntity:IsNPC() then
                self:Give(weaponClass)
                self:SelectWeapon(weaponClass)

                -- Проверяем расстояние между dv и dm
                if self:GetPos():Distance(npcEntity:GetPos()) > 100 then
                    self:SetLastPosition(npcEntity:GetPos())
                    self:SetSchedule(SCHED_FORCED_GO_RUN)
                else
                    self:AttackTarget(npcEntity)
                end
            else
                -- Обработка, если dm не является NPC
                -- ...
            end
        end
    end
end


Что такое Аргументы:

  1. В программировании, аргументы относятся к значениям или переменным, которые передаются в функцию при ее вызове. Аргументы предоставляют данные, с которыми функция будет работать или на основе которых будет выполнять определенные операции.
  2. В Garry's Mod Lua API, аргументы относятся к значениям, которые передаются в функцию при ее вызове. Аргументы предоставляют данные, с которыми функция будет работать или на основе которых будет выполнять определенные операции.

Например, в следующем коде функции MyFunction(arg1, arg2) имеются два аргумента arg1 и arg2:

function MyFunction(arg1, arg2)
    -- Код функции
end

При вызове этой функции необходимо передать значения для аргументов arg1 и arg2. Например:

MyFunction(value1, value2)

Внутри функции MyFunction можно использовать переданные аргументы для выполнения нужных операций.

Источник: wiki.facepunch

Аргументы в Garry's Mod Lua API могут быть различных типов данных, таких как числа, строки, булевы значения или даже другие объекты из API. В зависимости от функции и ее назначения, аргументы могут иметь различные значения и использоваться для разных целей.

Например, в функции ents.Create(classname, position, angles, frozen) из Garry's Mod Lua API есть четыре аргумента:

  • classname (строка) - имя класса объекта, который будет создан.
  • position (вектор) - позиция, в которой будет создан объект.
  • angles (угол) - углы поворота объекта.
  • frozen (булево значение) - указывает, будет ли объект заморожен в начальном состоянии.
local myEnt = ents.Create("my_entity", Vector(0, 0, 0), Angle(0, 0, 0), true)

В приведенном примере мы создаем объект с классом "my_entity" на позиции (0, 0, 0) с нулевыми углами поворота и замороженным состоянием.

Источник: wiki.facepunch



Варианты self

в термине self есть 2 вида обращения или отсылки. "self." - это обращение к переменной, в простой функции или таблице, где может быть функция.

А "self:" - это обращение исключительно к методу, который может быть в функции или в таблице.


self.

Строка кода "self.health = self.health - amount" в Garry's Mod Lua API используется для вычитания значения "amount" из поля "health" текущего объекта или таблицы.

Вот пошаговое объяснение этой строки:

  1. "self.health" обращается к полю "health" текущего объекта или таблицы. "self" является ссылкой на текущий объект или таблицу, а оператор точки "." используется для доступа к их полям.
  2. Оператор минус "-" вычитает значение "amount" из текущего значения "self.health".
  3. Не забывайте "self.health" это отсылка к переменной "health = 100" в следующем коде.
  4. Результат вычитания затем присваивается обратно в поле "health" текущего объекта или таблицы с помощью оператора присваивания "=".

Проще говоря, эта строка кода обновляет поле "health" текущего объекта или таблицы, вычитая из него значение "amount".

Вот пример, иллюстрирующий использование этой строки кода:

```lua
local myObject = {
    health = 100,
    
    TakeDamage = function(self, amount)
        self.health = self.health - amount
        print("Здоровье: " .. self.health)
    end
}
myObject:TakeDamage(20) -- Вывод: Здоровье: 80
```

В этом примере вызывается метод "TakeDamage" таблицы "myObject" с аргументом 20. Строка "self.health = self.health - amount" вычитает 20 из начального значения "health" (100), что приводит к новому значению 80. Обновленное значение "health" затем выводится на экран.


self:

Когда вы видите "self:" перед методом, это означает, что вы вызываете метод на текущем объекте, но передаете его в качестве первого аргумента. Это позволяет вам явно указать, что метод вызывается на объекте "self". Например, если у вас есть метод "SetName" и вы хотите вызвать его на объекте "player" с аргументом "John", вы можете использовать "self:SetName("John")".


Циклы:

#--Цикл while
local i = 1  -- Инициализируем переменную i со значением 1
while i <= 5 do  -- Пока i меньше или равно 5, выполняем следующий блок кода
    print("Цикл while: ", i)  -- Выводим значение переменной i
    i = i + 1  -- Увеличиваем значение переменной i на 1    
end

===================================================================================================================

#--Цикл for
for j = 1, 5 do  -- Итерируемся от 1 до 5 с шагом 1
    print("Цикл for: ", j)  -- Выводим значение переменной j
end

===================================================================================================================

#--Цикл repeat...until
local k = 1  -- Инициализируем переменную k со значением 1
repeat  -- слово repeat обозначает "повторять".
    print("Цикл repeat...until: ", k)  -- Выводим значение переменной k
    k = k + 1  -- Увеличиваем значение переменной k на 1
until k > 5  -- Повторяем цикл, пока k не станет больше 5


Цикл For:

Цикл for: Этот цикл используется для итерации через коллекции или задания диапазона значений.

#--Итерация по таблице
local players = {"Player1", "Player2", "Player3"}  -- Создаем таблицу players с элементами "Player1", "Player2" и "Player3"
for i, player in ipairs(players) do  -- Итерируемся по таблице players, присваивая индекс элемента переменной i и значение элемента переменной player
    print(i, player)  -- Выводим индекс и значение элемента таблицы
end

#--Итерация по диапазону значений
for i = 1, 10, 2 do  -- Итерируемся от 1 до 10 с шагом 2
    print(i)  -- Выводим значение переменной i
end

В первом примере цикл for будет выполняться для каждого элемента таблицы players, выводя индекс и значение элемента. Во втором примере цикл for будет выводить нечетные числа от 1 до 10.

Скобки для группировки условий:

Если вы используете методы объектов с помощью двоеточия (:), такие как riot:GetClass(), то скобки вокруг всего условного выражения не требуются. Однако, если вы хотите добавить несколько условий с использованием логических операторов, таких как and, or, то для улучшения читаемости кода рекомендуется использовать скобки для группировки условий. Это особенно полезно, когда условия становятся сложнее и включают в себя несколько логических операторов.

Вот пример кода с использованием скобок для группировки условий:

if (riot:GetClass() == "vj_riot" and spak:IsValid()) then -- Ваш код здесь 
end

Скобки здесь используются для того, чтобы было ясно, что условие spak:IsValid() должно быть выполнено вместе с условием riot:GetClass() == "vj_riot". Если бы вы опустили скобки, то порядок выполнения условий мог бы измениться, что может привести к непредсказуемым результатам.


Будем использовать нейросеть Phind для создания метода.

  • Пиши слово "пиши по русский" - вы зададите диалог на русском языке.
Phind
Конечно, я могу писать по-русски. Чем могу помочь?
  • Пиши - "будем создавать метод на Garrys Mod Lua API. С использованием "ENT:", self и аргументов."
Phind
Хорошо, мы будем создавать метод на Garrys Mod Lua API с использованием "ENT:", self и аргументов. Что именно должен делать этот метод? Нужно ли вам объяснить, как работает Garrys Mod Lua API или вы уже знакомы с ним?

Пиши - "entity - "weapon_pist" является огнестрельным оружием которое должно применяться против entity - "NPCgude"."

Phind SOLVE
final task: Создайте метод, который будет использовать оружие 'weapon_pist' для атаки сущности 'NPCgude'.

Phind
Хорошо, чтобы создать метод, который будет использовать оружие 'weapon_pist' для атаки сущности 'NPCgude', мы можем использовать метод 'ENT:FireBullets()' в Garrys Mod Lua API, чтобы стрелять пулями с оружия.
Вам понадобится определить этот метод внутри своей сущности (Entity) и передать как аргументы используемое оружие и цель для атаки.
Вот пример, как выглядит метод, который вы можете использовать:
function ENT:AttackNPCgude()
    local weapon = self:GetWeapon("weapon_pist") -- Получить ссылку на оружие 'weapon_pist'
    local target = ents.FindByClass("NPCgude")[1] -- Найти первую сущность класса 'NPCgude'

    if IsValid(weapon) and IsValid(target) then
        local bullet = {}
        bullet.Num = 1 -- Количество пуль
        bullet.Src = self:GetShootPos() -- Позиция выстрела из оружия
        bullet.Dir = (target:GetPos() - self:GetShootPos()):GetNormalized() -- Направление стрельбы
        bullet.Spread = Vector(0, 0, 0) -- Разброс пуль
        bullet.Tracer = 1 -- Включить трассировку
        bullet.Force = 10 -- Сила пули
        bullet.Damage = 10 -- Урон пули

        weapon:FireBullets(bullet) -- Выстрелить пулями
    end
end
В этом примере мы используем метод 'self:GetWeapon()' для получения ссылки на оружие 'weapon_pist', а также метод 'ents.FindByClass()' для поиска первой сущности класса 'NPCgude'. Затем настраиваем параметры пули и используем метод 'weapon:FireBullets()' для стрельбы.
Вы можете вызвать этот метод из другой части кода своей сущности, как например из метода 'ENT:Think()', чтобы атаковать 'NPCgude' с помощью оружия 'weapon_pist'.
Надеюсь, это помогает вам создать метод для вашей задачи. Если у вас есть ещё вопросы, не стесняйтесь задавать.


Итог в фото: