Physgun Wiki

Как добавить профессию

Профессии не регистрируются кодом напрямую: sh_registrator.lua при старте сканирует папку jobs/ и сам вызывает player_manager.RegisterPlayerClass для каждого найденного файла. Чтобы добавить профессию, достаточно создать один файл.

1. Файл профессии

gamemodes/darkrp/gamemode/jobs/police.lua. ID профессии берётся из имени файла (police), сам файл выполняется через include с глобальной таблицей JOB, а не return. Набор полей, как в jobs/citizen.lua:

JOB.DisplayName = "Полицейский" JOB.Description = "Патрулирует город и следит за порядком" JOB.Color = Color(60, 90, 200) JOB.Team = TEAM_GOVERNMENT JOB.MaxPlayers = -1 JOB.MaxHealth = 100 JOB.StartHealth = 100 JOB.StartArmor = 25 JOB.Salary = 0 JOB.Flags = {} JOB.Model = { "models/player/police.mdl" }

JOB.Team обязателен и должен быть объявлен раньше в teams.lua (TEAM_CITIZEN, TEAM_GOVERNMENT или своя команда через team.SetUp). JOB.Model — таблица моделей: базовый класс выберет случайную при спавне.

Регистратор не транслирует поля: весь JOB становится классом player_manager напрямую (наследуется от rp_player из sh_jobs.lua), поэтому реально влияют только поля, которые что-то с ними делает: Team (rp_player:Init вызывает SetTeam) и Model (rp_player:SetModel, вызывается GMod-хуком PlayerSetModel). MaxHealth, StartHealth, StartArmor, Salary, Description, Color, Flags, MaxPlayers объявлены и хранятся на классе, но rp_player:Spawn() пустой и их не применяет.

Флаги

JOB.Flags — массив констант из sh_jobs.lua:

Флаг Значение
JOB_FLAG_UNDISMISSABLE 1
JOB_FLAG_NEED_VOTE 2
JOB_FLAG_NONRP 3
JOB_FLAG_CANT_BUY_DOOR 4

Как и остальные необрабатываемые поля JOB, флаги пока только объявлены: ни один системный код их не читает.

2. Регистрация

Ничего больше делать не нужно: sh_registrator.lua при загрузке геймода сам находит файл и вызывает player_manager.RegisterPlayerClass(job.ID, job, 'rp_player').

3. Профессия по умолчанию

Игрок при первом заходе получает профессию из Config.Defaults.Job (GM:PlayerInitialSpawn вызывает player_manager.SetPlayerClass).

4. Переопределение поведения геймода

Базовый класс rp_player объявляет пустые методы-перехватчики (CanBuyDoor, CanSellDoor, CanOpenDoor, CanDropMoney, CanTransferMoney, CheckBuildLimit и их пары On*), которые дёргает player_manager.RunClass из соответствующих GM-хуков до дефолтной логики геймода. Профессия может переопределить любой из них прямо в своём файле:

-- jobs/police.lua function JOB:CanBuyDoor(door) return false -- полицейским двери покупать нельзя end

Если метод вернул не-nil, это решение побеждает; вернул nil (или не определён) — используется дефолт геймода, см. соответствующий хук в справочнике (например, OnPlayerBuyDoor).

5. Двери для профессии

Привязка двери к профессии по её ID, один раз при настройке карты, через SetDoorJob:

hook.Add("InitPostEntity", "SetupPoliceDoors", function() local door = ents.FindByClass("prop_door_rotating")[1] if IsValid(door) then door:SetDoorJob("police") end end)

Игроки профессии police получат доступ к замку двери через CanBeOpenedBy без покупки: двери с назначенной профессией нельзя купить (см. PLAYER:BuyDoor).