PDA

Просмотр полной версии : Создание дополнений



Gunslinger
26.10.2001, 18:31
Вот первая часть данной статьи. В ней еще нет руководства по созданию техники, но можно пока потренироваться с объектами и оружием. Все ваши вопросы и корректировки (особенно прошу обратить внимание на грамматические ошибки, т.к. я их не исправлял) здесь же. Позже будет продолжение.

Структура файоа Config.cpp

75% команд файла config.cpp до сих пор не известны.

Что такое config.cpp?

Дополнения помещаются в папку addons игры. Перед прочтение данного руководства рекомендуется распаковать (используя утилиту DePBO) и, если надо, раскодировать любое дополнение и посмотреть структура файла config.cpp. Данный файл является основой всех дополнений, все остальные файлы используются для хранения текстур, звуков и моделей.

Каждое дополнение использует файл config.cpp для описания своих возможностей. Каждый юнит в игре имеет свой собственный класс. Если вы захотите добавить в игру новую технику или оружие, вам также придется определить для них классы в файле config.cpp. Для каждого дополнения может быть только один такой файл.

Пока что мы не может изменять существующие и делать новые модели техники и оружия, но мы можем изменить их параметры, создав новый класс.

Данное руководсвто не сможет обучить вас всему, но полученные знания вполне можно будет использовать для создания собственных дополнений. Вначале рассмотрим пример дополнения с оружием, потом попробуем самостоятельно сделать дополнение на базе коллекции объектов Gunslinger`а. И, наконец, попробуем сделать дополнение с техникой, что гораздо сложнее, чем добавлять оружие или объекты.

СОдержание:

Определения (defines)
Класс CfgPatches
Предназначения классов
ДОбавление нового класса
СОздание дополнения с техникой
Использование класса CfgRecoils
Создание дополнения с объектом
Создание дополнения с техникой
Добавление новых групп
Добавление новых маркеров
Установка нового дополнения
Советы
Примеры

Определения

Определения находятся в самом начале файла config.cpp. Их не обязательно использовать, но это очень хорошая идея, нежели запоминать значения различных параметров. Они как константы в языках программирования, если вы один раз определите их, вы можете их в любом месте файла config.cpp, а не прописывать каждый раз их значения. Некоторые стандартные и общие для всех дополнений определения вы можете взять из примера, указанного ниже:

// Основные определения
#define TEast 0
#define TWest 1
#define TGuerrila 2
#define TCivilian 3
#define TSideUnknown 4
#define TEnemy 5
#define TFriendly 6
#define TLogic 7

#define true 1
#define false 0

// определения секретности
#define private 0
#define protected 1
#define public 2

Определения для дополнений с оружием:

#define WeaponNoSlot 0// мнимое оружие
#define WeaponSlotPrimary 1// основное оружие
#define WeaponSlotSecondary 16// вспомогательное оружие
#define WeaponSlotItem 256// вещи
#define WeaponSlotBinocular 4096// бинокль
#define WeaponHardMounted 65536

Определения для дополнений с техникой:

#define CanSeeRadar 1
#define CanSeeEye 2
#define CanSeeOptics 4
#define CanSeeEar 8
#define CanSeeCompass 16
#define CanSeeRadarC CanSeeRadar+CanSeeCompass
#define CanSeeAll 31

Замечание: существуют и другие определения, которые пока не известны.

Класс CfgPatches

У данного класса два назначений: определение дополнения и указание требуемой версии игры. Данный класс обязателен для каждого файла config.cpp. Синтаксис его следующий:

class CfgPatches
{
class //название дополнения
{
units[] = {название добавляемого юнита};
weapons[] = {название добавляемого оружия};
requiredVersion = требуемая версия игры;
};
};

Например, мы захотели создать дополнение, включающее новое оружие "Plasmarifle" и новый юнит "Terminator". Требуемая версия будет 1.20.

class CfgPatches
{
class Terminator
{
units[] = {Terminator};
weapons[] = {};
requiredVersion = 1.20;
};
class Plasmarifle
{
units[] = {};
weapons[] = {Plasmarifle};
requiredVersion = 1.20;
};
};

Замечание: мы прописали два класса, отдельно для юнита и оружия, т.к. мы хотим, чтобы они были раздельны. Если же вы захотите создать юнит Terminator уже вооруженного оружием Plasmarifle, то надо прописать:

class CfgPatches
{
class Terminator
{
units[] = {Terminator};
weapons[] = {Plasmarifle};
requiredVersion = 1.20;
};
};

Предназначения классов

Разница между дополнениями с оружием и техникой, что они требует определения различных классов. То есть если вы добавляете новое оружие, требуется определить классы CfgAmmo и CfgWeapons.

Если это новая техника, то классы будут следующими: CfgVehicles, CfgVehicleActions (не обязательно) и CfgMovesMC (не обязательно).

Общим классом для обоих типов дополнений является CfgNonAIVehicles.

Если вы захотите добавить дополнение с новыми лицами, используйте класс CfgFaces.

Файл config.cpp может содержать любоей количество и сочетание этих классов, например, добавив новое оружие (используя классы CfgAmmo и CfgWeapons), вы можете также добавить новый вид солдата (используя класс CfgVehicles), который будет экипирован этим оружием. Или же, добавив новый вертолет, можно создать для него новое вооружение в классе CfgVehicles. Но в начале давайте разберемся, как добавлять новый класс.

Добавление нового класса

Данный процесс схож с объектно-ориентированным программированием, т.е. имеется древовидная структура объектов и наследование свойств. Новый класс выглядит примерно так:

class CfgVehicles
{
class All {};
class AllVehicles: All {};
class Land: AllVehicles {};
class LandVehicle: Land {};
class Car: LandVehicle {};
class Jeep : Car {};
class HMMWV: Jeep
{

Конечным результатом данного кода является добавление новой техники (HMMWV) в игру. Выше определяется принадлежность класса новой техники к другим классам. Первое что мы определям, это принадлежность к классу All, абсолютно все объекты входят в него. Далее круг сужается. Т.к. мы добавляем технику, то надо использовать класс AllVehicles. Наша техника является наземной, значит прописываем ее в Land. В свою очередь в состав Land входить класс LandVehicle, точно указывающий на основные признаки техники. Так как у нас машина, а не танк, то прописываем ее в классе Car, в который в свою очередь входит класс Jeep. Добравших до основания дерева, мы и прописываем класс нашей новой машины.

Теперь необходимо определить аттрибуты техники, т.е. какими свойствами она обладает и как должна себя вести:

class HMMWV: Jeep
{
//здесь прописываются свойства хаммера
};

Замечание: свойства не обязательны, т.к. они наследуются у родительского класса. Т.е если ничего другого не указывать, джип хаммер будет иметь стандартные свойства класса Jeep.

Создание дополнения с оружием

Чтобы добавить новое оружие в игру, необходимо определить два класса: CfgAmmo и CfgWeapons.

CfgAmmo

Вначале необходимо определить параметры и свойства боеприпасов для нового оружия. Рассмотрим это на примере дополнения RPG-29:

class CfgAmmo
{
class default {};
class LAW : Default {};
class RPG : LAW {};
class RPG29ammo : RPG
{
hit=1520;
indirectHit=500;
indirectHitRange=5;

picture="\dtaext\equip\w\w_at4launcher.paa";
};
};

Можно заметить, что боеприпасы для РПГ (RPG29ammo), наследуют свойства класса RPG, который в свою очередь принадлежит классу LAW. В вершине данного дерева находится класс Default (описывающий стандартные характеристики для всех видов боеприпасов).

Для определения свойств боеприпасов используется 4 команды: hit (повреждения от прямого попадания), indirecthit (повреждения от взрывной волны и осколков), indirectHitRange (радиус поражения) и picture (изображение боеприпасов на экране задания). Опять же напомню, что мы решили изменить только эти параметры, а остальные остались такими же, как я для стандартного выстрела РПГ, благодаря наследованию родительских свойств.

CfgWeapons

Итак, мы определили боеприпасы, теперь нужно определить само оружие:

class CfgWeapons
{
class default {};
class LAWLauncher : default {};
class CarlGustavLauncher : LAWLauncher {};
class AT4Launcher : CarlGustavLauncher {};
class RPG29Launcher : AT4Launcher
{
model="\rpg29\rpg29.p3d";

picture="\dtaext\equip\m\m_at4Launcher.paa";
displayName = RPG29;
displayNameMagazine = RPG29;
shortNameMagazine = RPG29;

ammo = RPG29ammo;
initspeed=125;
count = 1;
maxLeadSpeed=150;
};
};

Вначале мы определили, что наше оружие будет наследовать свойства ПТУР АТ4 (класс AT4Launcher), который имеет свойства CarlGustavLauncher, унаследованные от LAWLauncher и принадлежит к классу default (общему для всего оружия).

Далее идет описание свойств оружия. Первым делом необходимо определить модель, которая будет использоваться (в данном случае это rpg29.p3d). Пока мы не можем создавать собственные модели, нам придется копировать уже существующие (rpg29.p3d является копией обычного РПГ). Указывая модель, необходимо прописать путь к ней, который является относительным либо к папке DTA (если используется стандартная модель), либо к папке ADDONS (если модель содержится в файле с дополнением).

Например, если модель находится в файле data3d.pbo (где находятся все стандартные модели) в папке DTA, путь будет следующим:

model=\data3d\modelname.p3d

Если же мы поместили модель в наше дополнение и назвали файл myaddon.pbo, то путь будет такой:

model=\myaddon\modelname.p3d

Далее определеям изображение оружия на экране с заданием и названия оружия и боеприпасов (displayName, displayNameMagazine и shortNameMagazine), которые будут использоваться в игре, например, при добавлении их командами AddWeapon и AddMagazine.

Следующая команда "ammo = RPG29ammo" приписывает в качестве боеприпасов данному оружию недавно созданный нами класс. То есть оружие RPG29Launcher будет заряжаться выстрелами RPG29ammo. Команда Initspeed определяет начальную скорость полета выстрела, а count - количество зарядов вообще или выстреливаемое за один раз. Значение maxLeadSpeed определяет предел скорости, которого может достигнуть выстрел в полете.

Вот и все, мы создали новое оружие. Но, как говорилось ранее, необходимо определить еще один класс, общий для дополнений с техникой и оружием:

class CfgNonAIVehicles
{
class ProxyWeapon {};
class ProxyRPG29: ProxyWeapon {};
};

Неизвестно, зачем нужен этот класс, но он обязателен, поэтому убедитесь, что вы его добавили в файл config.cpp.

Использование класса CfgRecoils

Данный класс отвечает за определение отдачи оружия. Вот как он выглядит:

class CfgRecoils
{
empty[]={};
impulse[]={0.050000,0.020000,0.200000,0.100000,0.030000,-0.100000,0.300000,0,0};
riffleSingle[]={0.050000,0.020000,0.040000,0.050000,0,0};
riffleSilenced[]={0.010000,0.004000,0.010000,0.050000,0,0};
LAWSingle[]={0.020000,0,0,0.050000,0.080000,0.030000,0.100000,0.030000,0.015000,0.200000,0,0};
sniperSingle[]={0.020000,0,0,0.050000,0.010000,0.020000,0.100000,0.008000,0.018000,0.200000,0,0};
riffleBurst3[]={0.050000,0.020000,0.040000,0.050000,0,0};
mgunBurst3[]={0.050000,0.020000,"0.04*1.35",0.050000,0.010000,"0.01*1.35",0.050000,0.030000,"0.04*1.35",0.050000,0.020000,"0.02*1.35",0.050000,0.040000,"0.04*1.35",0.010000,0,0};
};

В дополнениях можно изменять эти значения и создать свой собственных эффект отдачи. Итак, приступим:

class CfgRecoils
{
MyRecoil[]={1.00,0.5,0.7};
};

Данные строчки создают новый класс MyRecoil, который определяет для оружия отдачу в 0.5 единиц измерения игры назад, 0.7 вверх, и все это должно произойти в течение 1 секунды. То есть первое значение отвечает за длительность эффекта отдачи, вторая - за толчки назад и третья - вверх. Но это не все, можно прописать одновременно несколько таких последовательностей, создав массив отдачи, и, тем самым, разнообразив ее:

class CfgRecoils
{
shotgun[]={0.02,0,0.01,0.05,0.05,0.15,0.4,0,0};
};

Мы определили, что в первые 0.02 секунды оружие сдвинется на 0.01 единицу вверх, в следующие 0.05 секунд - на 0.05 назад и 0.15 вверх и под конец через 0.4 секунды,оружие вернется в нормальное положение (0,0). Обязательно следует возвращать оружие в прежнее положение, используя в конце массива значения 0,0, чтобы вся комбинация выглядела реалистично.

Для использования данной отдачи, пропишите в классе CfgWeapons следующие строчки:

recoil=shotgun;
recoilFixed=shotgun;

Команда recoil определяет отдачу при стрельбе стоя, на ходу, на бегу и фиксированную лежа.

Используя достаточно большие значения можно добиться интересных результатов...

Создание дополнения с объектом

В данном разделе мы будем основываться на дополнении Gunslinger`а, которое отлично показывает, как можно виртуально добавить любой объект в игру или же импортировать их в редактор.

На самом деле в дополнении Gunslinger`а почти не содержится каких-то новых объектов. Оно просто делает доступными все те объекты, которые уже были встроены в игру, но были недоступны в редакторе. Но есть и исключения - это мины и прочие объекты, которые Gunslinger сам добавлял, создавая их путем изменения свойств у уже существующих объектов.

Итак, рассмотрим имспользуемый в этом дополнении файл config.cpp. Не обращайте внимание на верхнюю часть файла. Кстати, эксперименты с дополнениями не активизируют FADE.

Структура дополнения Gunslinger`а

К этому моменту вам уже должна быть знакома общая структура дополнения. Вначале идут различные определения и класс CfgPatches, указание названия (EditorUpdate102) и требуемой версии игры (1.07).

Далее следует тело файла, начинающееся с описания класса cfgVehicles. Необходимо заметить, что все (любой объект, оружие и даже солдат) в игровой мире является техникой и входит в этот класс.

Примерно в первых 100 строчках автор указывает родительские классы для новых обхектов. Конечно же, все начинается с класса All, который подразделяется на два других класса: AllVehicles и Things. AllVehicles может включать классы Air, Land или Ship. Things в этом дополнеии состоит из классов BarrelHelper и ThingEffect.

И так далее каждый класс делится на множество других классов, которые более точно описывают игровые объекты (например, класс Land состоит из подклассов Man, LandVehicle и Static) и в конце концов достигают самих объектов.

Дополнение Gunslinger`а не содержит полный список всех игровых объектов, но модет быть использовано в качестве неплохого пособия по классовой иерархии и наследованию свойств объектами.

После указания названия объекта идет описание его свойств. Рассмотрим их на примере. Т.к. все эти объекты уже были в игре, автор создавал новый класс для каждого объекта используя уже существующие свойства, лишь изменяя серктность, делаяя их видымыми в редакторе, прописав в каждом классе строчку:
"scope=public;"

Добавление объекта

Объекты добавляется тем же способом, что и вся остальная техника:

class имя: родительский класс
{
свойства
};

Если взять классы AAA77Z и AAA805 (снаряд sabot round и плавучая мина), то можно увидеть множество свойств, которые необходимо определить. Вот некоторые для снаряда:

scope=public; //делает объект видимым для всех

setfuel=0; fuelCapacity=0; //удаляем все топливо (т.к. он принадлежит к классу helicopter).

hideUnitInfo=1; //позволяем отображать информацию об объекте

cost=0; //устанавливаем его цену (помните МОД Conquest с покупкой техники)

vehicleClass="Ammo"; //определяем группу для данного объекта, в которой он будет отображаться в редакторе, например Support, Ammo или Object

displayName="Explosive SabotShell"; //определяем текст, отображаемый в редакторе при выборе данного объекта

destrType=destructengine; //определяем метод уничтожения данного объекта, например, destructengine - со взрывом, destructno - неуничтожающийся, destructtree - как дерево и destructtent - как тент или здание

Данный снаряд принадлежит к классу helicopter не потому что он летает, а потому что он должен отделяться или выбрасываться и взрыватсья при столкновении с землей. По этой же причине удалено топливо и начальный урон почти равен 1 (т.е. малейшее столкновение приведет к взрыву).

Если же мы взглянем на плавучую мину, то поймем как автор смог заставить ее держаться на воде, сделав ее родительским классом BigShip (то есть корабля), и установив параметр canFloat в 1. Опять же начальный урон почти равен 1 и малейшее столкновение приведет к взрыву.

Добавление новых иконок в редактор

Это довольно просто. Параметр, который назначает объекту иконку в редакторе это:

icon=путь к иконке;

Gunslinger использовал папку icons для хранения своих иконок. Например, иконка для плавучей мины определяется так:

icon=\EditorUpgrade102\icons\mine.jpg;

Создание собственного дополнения

Допустим вы не хотите использовать дополнение Gunslinger`а, но вам по зарез нужны уличные фонари. Значит придется делать дополнение, содержащие данные лампы (и, конечно же, иконку для редактора), самим.

1. Создайте отдельную папку, например, folder.

2. Внутри этой папки создайте текстовый файл и назоваите его config.cpp.

3. Скопируйте в папку иконку lightpole.jpg из дополнения Gunslinger`а (распакуйте его вначале).

4. Откройте в текстовом редакторе созданный вами файл config.cpp.

5. Вначале пропишем в этом файле небольшое вступление, например, информацию об авторе и упоминание тех, кто вам помогал в создании дополнения или чьи работы вы в нем использовали. Для этого перед каждой строчкой кода должны стоять знаки "//" (без кавычек), что вся дальнейшая строка воспринималась игрой как комментарий и не обрабатывалась.

// streetlamp addon by Somebody
// cheers to Gunslinger for the icon

6. Теперь пропише в нем определения. Хотя они и не обязательны, но очень желательны, чтобы избежать простейших ошибок по невнимательности:

#define TEast 0
#define TWest 1
#define TGuerrila 2
#define TCivilian 3
#define TSideUnknown 4
#define TEnemy 5
#define TFriendly 6
#define TLogic 7

#define true 1
#define false 0

#define private 0
#define protected 1
#define public 2

7. Далее необходимо определить класс CfgPatches. В нем пропишем название нашего фонаря и требуемую версию игры.

class CfgPatches
{
class streetlamp
{
units[] = {streetlamp};
weapons[] = {};
requiredVersion = 1.10;
};
};

8. А теперь осталось самое главное - определить класс CfgVehicles, в котором и будет содержаться наше дополнение. Определим вначале родительские классы для нашего дополнения (чтобы фонарь имел свойства фонаря, а не вертолета или танка). Для этого можно просто вытащить данную часть кода из дополнения Gunslinger`а.

class CfgVehicles
{
class All {};
class AllVehicles: All {};
class Land: AllVehicles {};
class Static : Land {};
class Building : Static {};
class NonStrategic : Building {};
class Fence : NonStrategic {};
class WireFence: Fence {};

9. Осталось определить только класс с самим дополнением. Опять же копируем жанную часть кода из дополнения Gunslinger`а, чтобы ускорить процесс, однако вы можете изменить некоторые параметры. В самом конце стоит закрывающая фигурная скобка класса CfgVehicles. Она должна быть обязательно и обозначает, что это последний (а в нашем случае еще и первый) объект, который необходимо добавить.

class streetlamp: WireFence
{
//дополнение общедоступное
scope=public;

//будет находиться в меню support
vehicleClass="Support";

//как гражданский объект
side=TCivilian;

// с ценой
cost=1;

//на карте маленького размера
mapSize=1;

//уничтожаться так же, как и дерево
destrType=destructtree;

//с именем в редакторе StreetLamp
displayName="StreetLamp";

//и иконкой в редакторе
icon=\streetlamp\lightpole.jpg;

//используем стандартную модель (расширение .p3d можно не указывать)
model=\data3d\lampadrevo;
};
};

10. Теперь можно сохранять файл config.cpp и выходить из редактора. Пора заняться созданием .pbo файла. Запустите утилиту StuffPBO, кликните на кнопке "Set Input" и укажите созданную вами папку folder (где находится ваш файл config.cpp). Далее кликните на кнопке "Set OutPut" и укажите папку "addons" в директории с игрой, а в поле "File name:" введите название вашего дополнения (streetlamp). Кликайте на кнопке "Save" и "Stuff!".

Готово, вы сделали свое первое дополнение. Теперь можете запустить редактор, выбрать при добавлении нового юнита пункты меню civilian/support (для этого нужно указать, что юниты не может управляться игроком, то есть он nonplayble) и добавить в миссию ваше дополнение streetlamp.