RU/Writing Gamemodes

From Multi Theft Auto: Wiki

Это руководство попробует в общих чертах обрисовать процесс написания правильного игрового режима (мода). Если вы только что начали программировать в MTA, то вам, может быть, для начала захочется взглянуть на другие руководства по скриптингу: они располагаются на Главной странице.

Вступление

Мод - ресурс, который при старте берет под контроль весь игровой процесс. Это может подразумевать сообщение игрокам о том, что им следует делать, респавн игроков, создание команд, объявление того, что игрокам нужно делать для победы или получения очков, и многое другое. Примеры - Race и Deathmatch.

Что значит "правильный мод"?

Говоря простым языком, правильный мод - это такой, который полноценно использует MTA'шную .map-файловую систему. Это значит, что код мода не несет в себе никаких фиксированных специфических картам данных, таких как позиции игроков или машин. Вместо этого, мод должен мочь загружать .map-файлы, которые как раз именно это и содержат. Таким образом мод сможет иметь множество карт; люди же смогут создавать .map-файлы для мода с помощью MTA'шного редактора карт, который намного более удобен для данных целей, нежели программирование.

Очевидным примером "правильного мода" служит Race. Он поддерживает созданные пользователями карт с кучей возможностей, кроющимися внутри .map-файла. А для изменения точек респавна, объектов и т.д. пользователю не нужно редактировать сам мод.

Map-файлы

Map-файлы по существу являются XML-документами с расширением .map. Они определяют внутриигровую среду одного или более конкретных модов. Они не предполагают изменения правил игры, которые, в свою очередь, зависят от мода.

Каждый элемент карты соответствует узлу в .map-файле. Для обыденных вещей типа точек респана, объектов и транспортных средств имеется стандартный синтаксис; как бы то ни было, для "особой", специфической моду информации вам понадобится придумывать свой собственный.

Пример

В качестве примера возьмем мод Capture the Flag. Карте для данного мода нужны обязательно обозначенные точки респавна и местоположения флагов, а уже потом объекты и транспортные средства. Упрощенный файл карты может выглядеть как-то так:

<map>
    <spawnpoint id="spawnpoint1" posX="1959.5487060547" posY="-1714.4613037109" posZ="877.25219726563" rot="63.350006103516" model="0"/>
    <pickup id="Armor 1" posX="1911.083984375" posY="-1658.8798828125" posZ="885.40216064453" type="armor" health="50" respawn="60000"/>
    <flag posX="1959.5487060547" posY="-1714.4613037109" posZ="877.25219726563" team="blue" />
    ...
</map>

Здесь вы можете видеть два MTA-элемента - точку респавна и пикап. Но что более важно, этот .map имеет собственный узел "flag", который определяет позицию и цвет флага. Точка респавна и пикап могут регулироваться существующими извне ресурсами, когда собственные элементы должны быть обработаны самим модом.

Суммируя, мы хотим массового притока мапперов, как это было в MTA:Race. Пользователем не нужно прикасаться к самому скрипту мода вообще.

Пример получения информации из .map-файла

Как сказано выше, вашему моду нужно извлечь собственные элементы, указанные в map-файле, и обрабатывать их. Это достаточно просто, что и показано ниже.

-- извлекает таблицу со всеми элементами типа flag
local flagElements = getElementsByType ( "flag" )
-- просматриваем их
for key, value in pairs(flagElements) do
	-- получаем нашу информацию
	local posX = getElementData ( value, "posX" )
	local posY = getElementData ( value, "posY" )
	local posZ = getElementData ( value, "posZ" )
	local team = getElementData ( value, "team" )
	-- создаем объект, сославшись на позицию флага
	createObject ( 1337, posX, posY, posZ )
	-- выводим команду, для которой мы создали базу
	outputChatBox ( "База для команды " .. team .. " создана" )
end

Функция getElementsByType возвращает таблицу всех элементов определенного типа (тип соответствует названию узла в .map-файле). Это работает и для своих собственных, и для встроенных в MTA типов (вроде "vehicle" или "player"). getElementData может быть использована для извлечения xml-атрибутов, заданных в .map-файле. В данном простом примере на месте флага создается объект и в чат выводится сообщение. На самом деле, вам, конечно, понадобится проделать большее во время загрузки карты, а в данном случае - установить колшейпы (collision shapes) для обнаружения игроков, берущих флаг.


Map manager

После прочтения секции выше должно быть понятно, что мод всегда должен состоять из двух частей:

  • Ресурса-мода, который (почти) всегда остается неизменным
  • Множества различных ресурсов-карт, которые дают моду специфичную картам информацию

Сейчас вместо написания загрузчика карт для кадого мода в отдельности, можно воспользоваться map manger, который предоставляет функции для загрузки модов и карт. Проще говоря, когда вы вводите соответствующую команду (например, 'gamemode ctf ctf-italy'), он стартанет оба ресурса: и 'ctf', и 'ctf-italy', а одновременно с тем еще и вызовет срабатывание события (onGamemodeMapStart), говорящее ресурсу 'ctf' о произошедшей загрузке карты. Ресурс 'ctf' затем сможет получить доступ к информации, которую содержит 'ctf-italy', начать спавнить игроков и т.д.

Как использовать mapmanager

Чтобы воспользоваться услугами mapmanager'а, ваш ресурс-мод должен быть для начала соответствующе отмечен. А именно, вам нужно будет установить атрибут "type" тегу <info> внутри meta.xml на значение "gamemode". Также вы можете установить атрибут "name" на "дружелюбное название" (типа "Capture the flag"), который будет показываться в ASE вместо названия ресурса.

<!-- meta.xml в моде "cowcatapult" -->
<meta>
    <info type="gamemode" name="Cow catapulting 2.0"/>
</meta>

Если ваш мод будет загружать собственные карты, вам следует добавить обработчики для

  • onGamemodeMapStart
  • onGamemodeMapStop (если необходима какая-либо выгрузка)

Они срабатывают, когда карта вашего мода стартует или останавливается, и передают ресурс-карту в качестве параметра. С функциями-обработчиками, прикрепленными к данным событиям, вы можете извлекать всю нужную вам из map- и конфигурационных файлов ресурса информацию.

Пример

function startCtfMap( startedMap ) -- startedMap содержит указатель на ресурс-карту
    local mapRoot = getResourceRootElement( startedMap )        -- получаем root (корневой) узел запущенной карты
    local flagElements = getElementsByType ( "flag" , mapRoot ) -- получаем все флаги карты и сохраняем их в таблице
    -- продолжаем загружать информацию как в примере выше
    -- спавним игроков и т.д.
end
addEventHandler("onGamemodeMapStart", getRootElement(), startCtfMap)

Делаем карты совместимыми

Карты - отдельные ресурсы. Так сделано чтобы для создания собственной карты и впомине не требовалось никакого редактирования ресурса-мода, а также это позволяет вам с картой упаковывать специфичные ей конфигурационные файлы/скрипты.

Чтобы сделать карту совместимой с вашим модом, откройте meta.xml ее ресурса и затем отметьте его: атрибут "type" должен быть установлен на "map", а атрибут "gamemodes" должен быть списком из разделенных запятой названий ресурсов-модов (без пробелов), с которыми данная карта работает.

<!--meta.xml карты-->
<meta>
    <info type="map" gamemodes="cowcatapult,assault,tdm"/>
</meta>

Когда вы уже все настроили, администраторы смогут использовать данные две команды для запуска/остановки модов: /gamemode названиеМода [названиеКарты] (опциональный параметр позволяет выбрать начальную карту, по умолчанию ее нет) /changemap названиеКарты [названиеМода] (опциональный параметр указывает мод, с которым запускать карту, по умолчанию она запустится на текущем)

На самом деле map manager экспортирует несколько больше функций ограниченного доступа, которые вам знать необязательно, но они могут оказаться полезными.

Что вам также следует сделать

Есть несколько других ресурсов, которые следует использовать модам (или хотя бы быть с ними совместимыми).

Helpmanager

Helpmanager предназначен быть стандартным интерфейсом для предоставления игроку помощи. Если вы используете helpmanager для отображения справки по своему моду, каждый игрок, использовавший helpmanager ранее (напр. на других модах) незамедлительно поймет, как ему до него добраться. Он также отображает справку по различным запущенным ресурсам в одном окне, если нужно.

По сути имеются два способа использования helpmanager:

  • Предоставить простой текст, объясняющий как использовать ваш мод
  • Запросить GUI-элемент helpmanager'а, который будет отображаться в своей собственной вкладке окна helpmanager и позволит вам добавлять в него любые GUI-элементы. Этот способ рекомендуется модам, которым нужно отображать усложненную справку, и которым вследствие этого нужен свой собственный GUI.

Прочитайте страницу helpmanager для получения подробностей по воплощению.

Scoreboard

Scoreboard отображает игроков, находящихся в данный момент на севрере, и их команды. Добавляйте в него свои собственные колонки для предоставления специфичной карте информации. Например, колонка 'points' (очки) в моде 'ctf' означает очки игрока, которые он заработал через убийства и захват флага. Как всегда, для подробностей смотрите страницу помощи самого ресурса scoreboard.

Map cycler

Map cycler контролирует, какие моды и карты играются на сервере. Вы можете указать, например, сколько раз подряд можно будет сыграть определенную карту, пока ее не сменит следующая. Чтобы его задействовать, вам понадобится сообщать map cycler'у о том, когда действие мода закончено (напр. по окончании раунда).