Урок по созданию мода.

0
Посетители
0
Новичок
Hds46
09:18, 24.05.2015
В прошлом уроке вы научились основам создания аддона,теперь я научу вас созданию полноценного мода.
Аддон-пример будет называться - "SandBox Player Classes" классы для игрока как в Team Fortress 2. 
Делаем все как в прошлом уроке - создадим папки и файлы.
Итак в папке server мы создадим lua файлик.
Теперь,собственно,приступим к кодингу.
Впишем в lua файл:
function SelectPlayerClasses( ply ) // Создадим новую функцию,которую будет использовать хук."ply" - Это игрок который подключился к игре. 
if engine.ActiveGamemode()=="sandbox" then // Создадим условие,чтобы этот мод работал только в игровом режиме "SandBox".
local mathx = math.random(1,11) // Создадим локальную переменную которая будет с помощью кода "math.random" случайно выбирать классы.
// Чтобы добавить еще классы вам нужно вместо 11 в math.random,вписать следующие числа.
if mathx == 1 then // Всего у нас будет 11 классов.При желании вы можете добавить ещё,нужно только добавить следующие числа.
ply:SetNWInt("ClassType",1)
elseif mathx == 2 then
ply:SetNWInt("ClassType",2)
elseif mathx == 3 then
ply:SetNWInt("ClassType",3)
elseif mathx == 4 then
ply:SetNWInt("ClassType",4)
elseif mathx == 5 then
ply:SetNWInt("ClassType",5)
elseif mathx == 6 then
ply:SetNWInt("ClassType",6)
elseif mathx == 7 then
ply:SetNWInt("ClassType",7)
elseif mathx == 8 then
ply:SetNWInt("ClassType",8)
elseif mathx == 9 then
ply:SetNWInt("ClassType",9)
elseif mathx == 10 then
ply:SetNWInt("ClassType",10)
elseif mathx == 11 then
ply:SetNWInt("ClassType",11) // Чтобы добавить больше классов,вам нужно вписать новое условие.Пример(Уберите кавычки если хотите добавить класс.):
// elseif mathx == 12 then 
// ply:SetNWInt("ClassType",12)
end
timer.Simple(14,function() // Создадим таймер который через 14 секунд после подключения игрока,выведет текст в чате.
if IsValid(ply) then // Условие для проверки существования игрока.Чтобы не вызывало ошибок.
ply:PrintMessage(HUD_PRINTTALK,"Приветствуем " .. ply:Nick() .. "! \nВаш класс:" .. ply:GetNWString("ClassName")) // Сообщение выводимое игроку через 14 секунд.
// Текст нужно вписать в кавычках,ply:Nick() - это ник игрока,ply:GetNWString("ClassName") -это название класса игрока.
// Чтобы в текст вписать значения из какого-нибудь кода,вам нужно закрыть текст кавычкой и затем вписать .. затем название кода.
end
end) // Функция закрытия таймера.Обязательно после end вписать скобку.
end
end
hook.Add( "PlayerInitialSpawn", "SelectPlayerClassesUniqueid", SelectPlayerClasses ) // Хук с событием "PlayerInitialSpawn" когда игрок подключается к серверу.

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

function SetPlayerClass( ply ) 
if engine.ActiveGamemode()=="sandbox" then 
timer.Simple(0.02,function() // Движок не сразу выдает оружие игроку.Поэтому нам нужно сделать таймер который активирует наш код через 0.02 секунд.
if IsValid(ply) then
local classtype = ply:GetNWInt("ClassType") // Находим класс игрока.Номер класса игрока мы выдали когда игрок подключился,в верхней функции.
ply:RemoveAllItems() // Удаляем все оружие и патроны игрока.
local name // Создадим локальную переменную которой присвоим название класса.Название класса будет выдаваться в функции класса.
if classtype == 1 then
name = Class.Gordon(ply)
elseif classtype == 2 then
name = Class.Healer(ply)
elseif classtype == 3 then
name = Class.Berserker(ply)
elseif classtype == 4 then
name = Class.Metropolice(ply)
elseif classtype == 5 then
name = Class.Soldier(ply)
elseif classtype == 6 then
name = Class.Elite(ply)
elseif classtype == 7 then
name = Class.Shotgunner(ply)
elseif classtype == 8 then
name = Class.Cowboy(ply)
elseif classtype == 9 then
name = Class.Demoman(ply)
elseif classtype == 10 then
name = Class.Rebel(ply)
elseif classtype == 11 then
name = Class.Trooper(ply) // Всего 11 классов по методу описанному выше,вы можете добавить еще.Надо вписать функцию класса.
end
ply:SetNWString("ClassName",tostring(name)) // Впишем сюда название класса.Этот код мы использовали в функции выше,где мы выводим текст.
ply:PrintMessage(HUD_PRINTTALK,"Ваш класс:" .. tostring(name)) // Выводим название класса игроку после его возрождения.
// tostring(name) - без него будут ошибки.Иногда переменная name будет выдаваться не в формате текста,поэтому нам нужен этот код.
end
end)
end
end
hook.Add( "PlayerSpawn", "SetPlayerClassUniqueid", SetPlayerClass ) // Хук с событием "PlayerSpawn" когда игрок возрождается.

Теперь приступим к созданию самих классов:

Class = {} // Создадим таблицу Class для наглядности.

function Arsenal(ply,wep) // Создадим функцию которую будем использовать для выдачи оружия классу.ply - игрок которому выдаем оружие.wep - название оружия.
ply:Give(wep) // Вот сам код выдачи оружия.
end

function Ammunition(ply,num,item) // Функция для выдачи патронов игроку.num - количество патрон.item - название патрон.
ply:GiveAmmo(num,item,true)
end

function Class.Gordon(ply) // Теперь создадим первый класс.
// И первым нашим классом будет Фриман.
local name = "Гордон Фриман" // Название класса,вписать в кавычках.
Arsenal(ply,"weapon_crowbar") // Вызываем функцию выдачи оружия которую мы написали выше.Название оружие вписать в кавычках.
Arsenal(ply,"weapon_physcannon")
Arsenal(ply,"weapon_bugbait")
Arsenal(ply,"item_battery") // Это понадобиться нам для брони.
Arsenal(ply,"item_battery")
return name // Это нам нужно для вывода названия класса игроку.
end

function Class.Healer(ply)
local name = "Доктор"
Arsenal(ply,"weapon_crowbar")
Arsenal(ply,"weapon_pistol")
Arsenal(ply,"weapon_medkit")
Ammunition(ply, 40, "Pistol") // Вызываем функцию выдачи патрон.Количество вписать без кавычек.Название патрон с кавычками.
return name
end

function Class.Berserker(ply)
local name = "Боец"
Arsenal(ply,"weapon_fists")
Arsenal(ply,"weapon_crowbar")
Arsenal(ply,"item_battery")
Arsenal(ply,"item_battery")
Arsenal(ply,"item_battery")
Arsenal(ply,"item_battery")
Arsenal(ply,"item_battery")
Arsenal(ply,"item_battery")
ply:SetWalkSpeed(ply:GetWalkSpeed() + 200) // Увеличим скорость ходьбы игроку.К начальной скорости добавим 200 единиц.
ply:SetRunSpeed(ply:GetWalkSpeed() + 450) // Увеличим скорость бега игроку.
return name
end

function Class.Metropolice(ply)
local name = "Полицейский"
Arsenal(ply,"weapon_stunstick")
Arsenal(ply,"weapon_pistol")
Arsenal(ply,"item_battery")
Ammunition(ply, 100, "Pistol")
// Вы также сможете указать свою модель игрока для класса.Для этого впишите в функцию класса - ply:SetModel("models/player/police.mdl") в кавычках название модели.
return name
end

function Class.Soldier(ply)
local name = "Солдат"
Arsenal(ply,"weapon_smg1")
Arsenal(ply,"weapon_frag")
Arsenal(ply,"weapon_frag")
Arsenal(ply,"item_battery")
Arsenal(ply,"item_battery")
Ammunition(ply, 200, "SMG1")
return name
end

function Class.Elite(ply)
local name = "Спецназ"
Arsenal(ply,"weapon_ar2")
Arsenal(ply,"weapon_frag")
Arsenal(ply,"item_battery")
Arsenal(ply,"item_battery")
Ammunition(ply, 200, "AR2")
Ammunition(ply, 1, "AR2AltFire")
return name
end

function Class.Shotgunner(ply)
local name = "Охотник"
Arsenal(ply,"weapon_shotgun")
Arsenal(ply,"weapon_frag")
Arsenal(ply,"item_battery")
Arsenal(ply,"item_battery")
Ammunition(ply, 40, "Buckshot")
return name
end

function Class.Cowboy(ply)
local name = "Ковбой"
Arsenal(ply,"weapon_pistol")
Arsenal(ply,"weapon_357")
Ammunition(ply, 60, "Pistol")
Ammunition(ply, 16, "357")
return name
end

function Class.Demoman(ply)
local name = "Подрывник"
Arsenal(ply,"weapon_frag")
Arsenal(ply,"weapon_slam")
Arsenal(ply,"weapon_slam")
Arsenal(ply,"weapon_rpg")
Ammunition(ply, 2, "RPG_Round")
Ammunition(ply, 2, "Grenade")
return name
end

function Class.Rebel(ply)
local name = "Повстанец"
Arsenal(ply,"weapon_crossbow")
Arsenal(ply,"weapon_crowbar")
Ammunition(ply, 10, "XBowBolt")
return name
end

function Class.Trooper(ply)
local name = "Кавалерист"
Arsenal(ply,"flechette_gun")
Arsenal(ply,"item_battery")
Arsenal(ply,"item_battery")
return name
end

Ну вот мы создали все 11 классов.
Теперь перейдем к консольным командам.
Создадим команду перевыбора классов для всех игроков,и которую будет вызывать только админ.
Команда будет называться - pc_repick_classes.

function Repick(ply) // ply - игрок который  использовал консольную команду.
if engine.ActiveGamemode()=="sandbox" then 
if ply:IsAdmin() then // Проверяем игрока на права админа.
for k,v in pairs(player.GetAll()) do // Находим всех игроков и перевыбираем им классы.Используем цикл.Где v  - это все игроки на сервере.
if IsValid(v) then
local mathp = math.random(1,11)
if mathp == 1 then
ply:SetNWInt("ClassType",1)
elseif mathp == 2 then
ply:SetNWInt("ClassType",2)
elseif mathp == 3 then
ply:SetNWInt("ClassType",3)
elseif mathp == 4 then
ply:SetNWInt("ClassType",4)
elseif mathp == 5 then
ply:SetNWInt("ClassType",5)
elseif mathp == 6 then
ply:SetNWInt("ClassType",6)
elseif mathp == 7 then
ply:SetNWInt("ClassType",7)
elseif mathp == 8 then
ply:SetNWInt("ClassType",8)
elseif mathp == 9 then
ply:SetNWInt("ClassType",9)
elseif mathp == 10 then
ply:SetNWInt("ClassType",10)
elseif mathp == 11 then
ply:SetNWInt("ClassType",11)
end
v:PrintMessage(HUD_PRINTTALK, "Все классы были перевыбраны.Возродитесь чтобы применить свой класс.") // Выводим текст всем игрокам.
end
end
ply:PrintMessage(HUD_PRINTTALK, "[Админ]Классы успешно перевыбраны!") // Выводим текст админу который ввел команду.
else
ply:PrintMessage(HUD_PRINTTALK, "Доступ запрещен!") // Выводим текст игроку без доступа админа.
end
end
end
concommand.Add( "pc_repick_classes", Repick, nil, nil) // Функция создания консольной команды.В кавычках вписать название команды.Затем название функции.

Теперь создадим команду для админа,которая сможет выбирать определенные классы для определенного игрока.
Примерное использование команды такое - pc_class_set Hds46 2.Где Hds46 - название игрока.Где 2 - название номера класса.

function SetClassForPlayer(ply,cmd,arg,argstr) // cmd - название команды.arg - название введенных значений.argstr - название значений в форме текста.
if engine.ActiveGamemode()=="sandbox" then 
if ply:IsAdmin() then
if arg[1] != nil then // Проверяем значение ника игрока на пустоту.
if arg[2] != nil then // Проверяем  значение номера класса на пустоту.
for k,v in pairs(player.GetAll()) do
if IsValid(v) then
if arg[1] == v:Nick() then // Проверка на значение ника игрока.Если такой игрок есть функция идет дальше. 
if IsValid(v) then
if (arg[2] == "1" or
arg[2] == "2" or
arg[2] == "3" or
arg[2] == "4" or
arg[2] == "5" or
arg[2] == "6" or
arg[2] == "7" or
arg[2] == "8" or
arg[2] == "9" or
arg[2] == "10" or
arg[2] == "11") then // Проверка на номера классов.У нас ведь всего одиннадцать классов.
v:SetNWInt("ClassType",tonumber(arg[2])) // Выдадим игроку определенный класс.tonumber(arg[2]) - выводим текст в номер.
 // Сообщение игроку получившего класс.
v:PrintMessage(HUD_PRINTTALK,"[Админ]" .. ply:Nick() .. " поменял вам класс. \nВозродитесь чтобы получить его.")
ply:PrintMessage(HUD_PRINTTALK,"[Админ]Вы успешно поменяли класс игроку " .. v:Nick() .. "!") // Вывод текста игроку который ввел команду.
else
ply:PrintMessage(HUD_PRINTTALK,"Номер класса не существует.") // Если номер класса определенный сверху нет,то выводим текст игроку.
end
end
end
end
end
else
ply:PrintMessage(HUD_PRINTTALK,"Нужно ввести номер класса.")  // Если игрок не ввел номер класса.
end
else
ply:PrintMessage(HUD_PRINTTALK,"Нужно ввести имя игрока.") // Если игрок не ввел ник игрока.
end
else
ply:PrintMessage(HUD_PRINTTALK,"Доступ запрещен!") // Если игрок не админ.
end
end
end
concommand.Add( "pc_class_set", SetClassForPlayer, nil, nil)

Ну вот.Вроде бы все,есть классы,консольные команды.
Но игроки спавнят оружие через спавн меню.
Тогда в папке autorun создадим папку client и там создадим lua файл.
В файле прописываем это.

local function DisallowSpawnMenu( )
if not LocalPlayer():IsAdmin() then
return false
end
end
 
hook.Add( "SpawnMenuOpen", "DisallowSpawnMenuCL", DisallowSpawnMenu)

Если игрок не админ,то он не может открыть спавнменю.

Чистый код можно скачать здесь.
Этот мод хорошо подходит для deathmatch'а и coop'а.
При наличии идей вы сможете создать много разнообразных классов.
Не забудьте преобразовать весь код в Utf-8(Без BOM) иначе русский текст не будет отображаться.



Также просмотрите мои прежние туториалы.
Туториал по созданию скриптового аддона.
Создаем оружие стреляющее пулями (SWEP )
Создание собственного оружия (SWEP).

Вы можете помочь мне материально по WebMoney.
Ru-Кошелек: R236462443208

Пишите в комментах если у вас появились ошибки или есть предложения.
Mega Upload.
Посетители
0
Заслуженный участник
Хороший гайд
Прикрепленная картинка

Секретный человек!
 
Доступ закрыт.
  • Вам запрещено отвечать в темах данного форума.