Информация о статье
Статья предусматривает то, что Вы умеете создавать директории для модов, а также, что у Вас имеется Visual C++ 6.0 и он полностью настроен на работу с SDK.
Статья посвящена следующим вопросам:
- Добавление в редактор возможности задания здоровья врага;
- Добавление в редактор возможности выставить бессмертие врагам;
- Добавление в редактор возможности выставить невидимость врагам;
- Добавление в редактор возможности возможности выставить скорость передвижения врага;
- Добавление в редактор возможности выставить кол-во очков за смерть врага;
- Добавление в редактор возможности чтобы при каждом убийстве враги разлетались на куски;
- Добавление в редактор возможности выставить кол-во куском мяса с врага;
- Добавление в редактор возможности выставить снаряды врага(лазер, ракеты, гранаты...).
- Добавление в редактор возможности включить полосу жизни врага.
Модернизация врага
Рассмотрим модернизацию врага на примере Зорга, или же на английской версии - Grunt.
1) Для добавления здоровья в редактор, необходимо указать соответствующую переменную после кода:
properties:
1 enum GruntType m_gtType "Type" 'Y' = GT_SOLDIER,
2 INDEX fHealth "Health" = 40,
Здесь мы объявили целочисленную переменную с именем fHealth, задали как она будет называться в редакторе в двойных кавычках: "Health"и задали некое начальное значение равное 40. Переменная есть - теперь нужно ее связать с здоровьем. Опуститесь ниже и найдите главную функцию:
Main(EVoid)
Найдите строки:
SetHealth(40.0f);
m_fMaxHealth = 40.0f;
И замените их на:
SetHealth(fHealth);
m_fMaxHealth = fHealth;
Далее найдите строки:
SetHealth(60.0f);
m_fMaxHealth = 60.0f;
Замените на:
SetHealth(fHealth);
m_fMaxHealth = fHealth;
Мы установили здоровье равное значению переменной как и у зорга-солдата так и у зорга-командира. Теперь можно запросто выставлять здоровье через редактор:
2) Добавим остальные интересующие нас переменные как показано на рисунке:
(на номера строк во втором окне не смотреть, у Вас они будут совсем другие)
Вот эти строки:
3 BOOL invisible "Invisible" = FALSE,
4 FLOAT speed "Speed" = 6.5,
5 BOOL alwaysBlobUp "Always BlowUp" = FALSE,
6 INDEX scorePerKill "Score" = 500,
7 enum SoldierWeapon m_weapon "Soldier Weapon" = Laser,
8 BOOL invulnerability "Invulnerability" = FALSE,
9 INDEX bodyParts "Body Parts" = 4,
Даже не пробуйте сейчас компилировать! Мы еще не все объявили, что необходимо для работы этого кода. Теперь по одному разберем.
3 BOOL invisible "Invisible" = FALSE,
Означает, что параметр может иметь два значения - "Истина"(TRUE) или "Ложь"(FALSE). Этот параметр отвечает за невидимость врага. Поэтому поставим по умолчанию чтобы враги были видимы. Не нарушаем игровой баланс. Вы можете поставить и TRUE чтобы усложнить игру. Следующий параметр:
4 FLOAT speed "Speed" = 6.5,
Отвечают за скорость врага. Если поставить 20 и более то на пустой местности от 10 таких врагов будет не так уж и легко уйти. Далее идет параметр, отвечающий за то, необходимо ли нанести определенный урон врагу, чтобы он разлетелся или достаточно всего одного последнего выстрела хоть даже с пистолета:
5 BOOL alwaysBlobUp "Always BlowUp" = FALSE,
Имеет тип как и невидимость, поэтому на нем останавливаться не будем. За кол-во очков, заработанных за убийство монстра будет отвечать эта переменная:
6 INDEX scorePerKill "Score" = 500,
Через строку идет еще две переменных:
8 BOOL invulnerability "Invulnerability" = FALSE,
9 INDEX bodyParts "Body Parts" = 4,
Они отвечают за бессмертие врага и кол-во частей тела. Также на этом подробно останавливаться не будем - выше было рассмотрено объявление данных типов. Теперь нас интересует момент:
7 enum SoldierWeapon m_weapon "Soldier Weapon" = Laser,
Тип enum происходит от английского слова - enumeration(перечисление). Да, действительно этот тип представляет собою перечисление.
Вот как выглядит пример перечисления в редакторе:
Но в данном случае мы объявили всего лишь объект который будет хранить данные о выбранном типе оружия. Но сама структура перечисления должна быть описана ранее.
Вставьте следующий код в указанном месте, как на рисунке:
Вот этот код:
enum SoldierWeapon {
0 Laser "LASER",
1 Rocket "ROCKET",
};
Laser, Rocket - идентификаторы(Значения, которые может принимать переменная, в нашем случае -m_weapon). "LASER", "ROCKET" - текст, который будет отображаться в редакторе в меню выбора элемента перечисления.
Все, теперь можно скомпилировать код. Только еще не организовано главное - связь переменных и параметров. Об этом в следующем пункте.
3) Реализуем необходимый функционал для наших переменных. Для обеспечения неуязвимости вставим код как показано на картинке:
if (invulnerability==false){ CEnemyBase::ReceiveDamage(penInflictor, dmtType, fDamageAmmount, vHitPoint, vDirection);}
Данный код работает так если неуязвимость =ложь. То в таком случае код который отвечает за получение урона выполняется, в ином случае - нет. Немного опуститесь и вставьте участки кода в необходимые места, как это показано на картинке:
Код:
m_fAttackRunSpeed = FRnd() + speed;
Отвечает за скорость врага. Код:
m_fAttackDistance = 1000.0f;
Я поставил чтобы враги стреляли не только когда подбегут, а сразу же, когда увидели. Следующий момент также очень интересен:
if (alwaysBlobUp==FALSE)
{
m_fBlowUpAmount = 80.0f;
}
else
{
m_fBlowUpAmount = 0.1f;
}
Если переменная враги всегда разлетаюсь = ложь, то враг будет разлетаться только в случае, если ему нанесено 80 или более единиц урона, в ином случае - если менее 1 единицы урона. На следующем коде подробно останавливаться не будем, он представляет привязку здоровья и очков за врага к переменным:
m_iScore = scorePerKill;
SetHealth(fHealth);
m_fMaxHealth = fHealth;
При установке флага невидимости данный код обеспечивает прозрачность врага:
if (invisible==TRUE)
{
GetModelObject()->mo_colBlendColor = C_WHITE|0x25;
}
Подобным образом Вы можете описать параметры и для командира, можете улучшить их, так как это командир. Я написал такие же параметры:
4) Теперь разберемся с оружием врага. Будет стрелять он лазером или ракетами. Для этого отредактируйте как на картинке указанный участок кода:
StartModelAnim(GRUNT_ANIM_FIRE, 0);
if (m_weapon==Rocket){
ShootProjectile(PRT_WALKER_ROCKET, FIREPOS_SOLDIER, ANGLE3D(0, 0, 0));
}
else
{
ShootProjectile(PRT_GRUNT_PROJECTILE_SOL, FIREPOS_SOLDIER, ANGLE3D(0, 0, 0));
}
PlaySound(m_soFire1, SOUND_FIRE, SOF_3D);
autowait(0.15f + FRnd()*0.1f);
StartModelAnim(GRUNT_ANIM_FIRE, 0);
if (m_weapon==Rocket){
ShootProjectile(PRT_WALKER_ROCKET, FIREPOS_SOLDIER, ANGLE3D(0, 0, 0));
}
else
{
ShootProjectile(PRT_GRUNT_PROJECTILE_SOL, FIREPOS_SOLDIER, ANGLE3D(0, 0, 0));
}
Рассмотрим как стреляет зорг-солдат, он останавливается и с определенным интервалом выстреливает два раза. Вот этот промежуток времени между выстрелами:
autowait(0.15f + FRnd()*0.1f);
Далее снова идет анимация выстрела:
StartModelAnim(GRUNT_ANIM_FIRE, 0);
И сам выстрел -ShootProjectile. И в зависимости от того m_weapon=Rocket(равно ли?). Выполяется либо выстрел лазером, либо выстрел ракетой:
PRT_GRUNT_PROJECTILE_SOL
PRT_WALKER_ROCKET
Результат виден на снимке экрана:
5) Рассмотрим добавление полосы жизни врагам. Итак, начнем с того, что большинство врагов являются наследниками от класса EnemyBase, в котором есть поле:
144 BOOL m_bBoss = FALSE,// set for bosses (for health display)
Именно это поле и отвечает за отображение полосы здоровья. Но, к сожалению, не у каждого монстра есть возможность скорректировать данное свойство, а как следует из кода, то по умолчанию стоит значение FALSE, следовательно полоса здоровья отображаться не будет. Данную проблему легко решить следующим образом: добавляем в класс нашего монстра новую переменную логического типа(BOOL), которую потом будем использовать для установки значения m_bBoss. Пример добавления приведен на следующем снимке:
Результат виден на следующем снимке:
Заключение
На данный момент это вся информация, которую я хотел бы рассказать в данной статье. Подведем итоги.
Данная статья помогла:
* Расширить параметры врага. Это видно со следующего снимка:
А именно реализовать задачи, поставленные вначале.
* Улучшить навыки в поиске необходимого кода(разбираться в коде)
* Узнать больше о синтаксических конструкциях языка С++, а также о конструкциях, которые используются в SDK.
На момент написания статьи на сайте почти нет информации по SDK. Я надеюсь, что данная статья поможет новичку быстрей сориентироваться в коде и начать разработку своей модификации. А для тех, кто уже начал делать модификации данная статья может помочь немного повторить материал.
Программа для создания папок модификации:
http://serioussite.ru/load/ssfmodcreator_v1_0/26-1-0-722
См. также "Работа с полями настроек игры(сессии)":
http://serioussite.ru/publ/rabota_s_sdk_rabota_s_poljami_nastroek_igry_sessii/6-1-0-56
Удачи в создании модификаций!
Комментарии
монстор был за тебя???
(Как в Akazuki mod 11)
http://serioussite.ru/forum/5-447-6
Внимание! Ты не сможешь играть в сетевой игре с другими игроками, которые играют не с твоими библиотеками! Так, что лучше используй как модификацию, а папку bin в корневой директории игры оставь без изменений.
Молодец!
Может он это и имел ввиду, но был очень краток.
ZIM, спасибо
Некоторые моменты из статьи могут быть полезны и человеку, который уже разбирается в SDK. Чтобы не искать некоторые функции, которые дает эта статья, у классов врагов самостоятельно.
Отлично поработал!!!
10000000000000000000000++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++