Создание нового заклинания

По скольку я не видел ни одного НОРМАЛЬНОГО тутора по заклам, то пришлось писать свой. И сразу перейду к делу, начнем мы с создания визуального «эффекта» Т.к. Эффект это одна из немаловажных составляющих, нового заклинания.

Расписывать что и кчему в скрипте эффекта не буду, так как это уже есть тут.

И так приступим, создайте новое решение в Готик Сорсере(Далее ГС). И назовите его к примеру VFX_Mgic(Включите в решение файлы ParticleFX.src,VisualFX.src лежат ?:Gothic II→_work→data→Scripts→System).

Далее выбираем проект ParticleFX Проект → Задать активный проект → ParticleFX открываем файл PfxInstMagic.d идем в конец этого файла и пишем туда следующее:

// Внимание! Имя Эффекта должно быть ПОЛНОСТЬЮ идентичным имени в файле Constants.d  **SPL_Новое_заклинание**
//если имя эффекта NewSpell то и константа должна называтся SPL_NewSpell. Если  это условие не соблюдено то
//заклинание работать не будет, а если и будет то не правильно!!!
 
//Инициализация заклинания
INSTANCE MFX_NewSpell_INIT (C_PARTICLEFX)
{
     ppsvalue = 80; // Кол-во создаваемых частиц сделаем 80
     ppsscalekeys_s = "5";
     ppsislooping = 1;
     ppsissmooth = 1;
     ppsfps = 12;
     shptype_s = "SPHERE"; //тип излучения ну скажем Сфера
     shpfor_s = "object";
     shpoffsetvec_s = "0 0 0";
     shpdistribtype_s = "RAND";
//     shpdistribwalkspeed = 0.100000001;
     shpdim_s = "5"; //Размер поверхности на которой будут "рождаться" частицы поставим 8
     shpscalekeys_s = "1";
     shpscaleislooping = 1;
     shpscaleissmooth = 1;
     shpscalefps = 2;
     dirmode_s = "RAND";
     dirfor_s = "object";
     dirmodetargetfor_s = "OBJECT";
     dirmodetargetpos_s = "0 0 0";
     dirangleheadvar = 180;
     dirangleelevvar = 180;
     velavg = 0.00800000038;
     velvar = 0.0299999993;
     lsppartavg = 300;
     flygravity_s = "0 0 0";
     visname_s = "pfx_abs_03.tga"; //Текстуру я поставлю свою текстуру из моего мода
     visorientation_s = "VELO";
     vistexisquadpoly = 1;
     vistexanifps = 18;
     vistexaniislooping = 1;
     vistexcolorstart_s = "0 100 255"; //начальный цвет будет синий
     vistexcolorend_s = "0 100 255";   //конечный будет зеленым
     vissizestart_s = "3 3";//Размер частиц при рождении поставим по 4
     vissizeendscale = 5;
     visalphafunc_s = "ADD";
     visalphastart = 255;//Альфа-Функция будет ADD
     useemittersfor = 1;
};
 
//Скастованое заклинание(Когда летит в цель)
//Тут уже объяснять не буду делайте по аналогии Инита
INSTANCE MFX_NewSpell_CAST (C_PARTICLEFX)
{
     ppsvalue = 80;
     ppsscalekeys_s = "5";
     ppsislooping = 1;
     ppsissmooth = 1;
     ppsfps = 12;
     shptype_s = "SPHERE";
     shpfor_s = "object";
     shpoffsetvec_s = "0 0 0";
     shpdistribtype_s = "RAND";
//     shpdistribwalkspeed = 0.100000001;
     shpdim_s = "15";
     shpscalekeys_s = "1";
     shpscaleislooping = 1;
     shpscaleissmooth = 1;
     shpscalefps = 2;
     dirmode_s = "RAND";
     dirfor_s = "object";
     dirmodetargetfor_s = "OBJECT";
     dirmodetargetpos_s = "0 0 0";
     dirangleheadvar = 180;
     dirangleelevvar = 180;
     velavg = 0.00800000038;
     velvar = 0.0299999993;
     lsppartavg = 300;
     flygravity_s = "0 0 0";
     visname_s = "pfx_abs_03.tga";
     visorientation_s = "VELO";
     vistexisquadpoly = 1;
     vistexanifps = 18;
     vistexaniislooping = 1;
     vistexcolorstart_s = "140 252 255"; //начальный цвет будет синевато белый 
     vistexcolorend_s = "0 255 56";   //конечный будет зеленым
     vissizestart_s = "4 4";
     vissizeendscale = 10;
     visalphafunc_s = "ADD";
     visalphastart = 255;
     useemittersfor = 1;
};
//И столкновение заклинания с объектом/целью 
INSTANCE MFX_NewSpell_COLLIDE (C_PARTICLEFX)
{
     ppsvalue = 20;
     ppsfps = 30;
     shptype_s = "SPHERE";
     shpfor_s = "object";
     shpoffsetvec_s = "0 0 0";
     shpdistribtype_s = "RAND";
     shpisvolume = 1;
     shpdim_s = "8";
     shpscalekeys_s = "1";
     shpscaleislooping = 1;
     shpscaleissmooth = 1;
     shpscalefps = 2.000000000;
     dirmode_s = "TARGET";
     dirfor_s = "object";
     dirmodetargetfor_s = "OBJECT";
     dirmodetargetpos_s = "0 0 0";
     dirangleheadvar = 180.000000000;
     dirangleelevvar = 180.000000000;
     velavg = 0.079999998;
     velvar = 0.020000000;
     lsppartavg = 500.000000000;
     flygravity_s = "0 0 0";
     flycolldet_b = 2;
     visname_s = "pfx_abs_03.tg";
     visorientation_s = "VELO";
     vistexisquadpoly = 1;
     vistexanifps = 18.000000000;
     vistexaniislooping = 1;
     vistexcolorstart_s = "140 252 255"; //начальный цвет будет синевато белый 
     vistexcolorend_s = "0 255 56";   //конечный будет зеленым
     vissizestart_s = "10 10";
     vissizeendscale = 10.000000000;
     visalphafunc_s = "ADD";
     visalphastart = 255.000000000;
};
//Ну и еще я решил добавить чтобы при попадании разлетались искры
INSTANCE MFX_NewSpell_COLLIDE_SPARKS (C_PARTICLEFX)
{
     ppsvalue = 600.000000000;
     ppsscalekeys_s = "1";
     ppsissmooth = 1;
     ppsfps = 10.000000000;
     shptype_s = "POINT";
     shpfor_s = "OBJECT";
     shpoffsetvec_s = "0 0 0";
     shpdistribtype_s = "RAND";
     shpisvolume = 1;
     shpdim_s = "50";
     shpscalekeys_s = "1";
     shpscaleislooping = 1;
     shpscaleissmooth = 1;
     shpscalefps = 2.000000000;
     dirmode_s = "RAND";
     dirfor_s = "object";
     dirmodetargetfor_s = "OBJECT";
     dirmodetargetpos_s = "0 0 0";
     dirangleheadvar = 180.000000000;
     dirangleelevvar = 180.000000000;
     velavg = 0.200000003;
     velvar = 0.050000001;
     lsppartavg = 5000.000000000;
     flygravity_s = "0 -0.0005 0";
     flycolldet_b = 1;
     visname_s = "MFX_SLEEP_STAR.TGA";
     visorientation_s = "NONE";
     vistexisquadpoly = 1;
     vistexanifps = 18.000000000;
     vistexaniislooping = 1;
     vistexcolorstart_s = "140 252 255"; //начальный цвет будет синевато белый 
     vistexcolorend_s = "0 255 56";   //конечный будет зеленым
     vissizestart_s = "30 30";
     vissizeendscale = 0.100000001;
     visalphafunc_s = "ADD";
     visalphastart = 255.000000000;
     visalphaend = 255.000000000;
};
//Извините за не полное разъяснение

Дальше жмем «Компилирывать» и переходим в проект VisualFX Вот тут я раскажу по более так как тутора по этому нету и так тут также действует условии что и в пред-идущем файле имя нада NewSpell. И перейдем к скрипту.

INSTANCE spellFX_NewSpell	(CFx_Base_Proto)
        {
 
     	visname_S 				= "MFX_NewSpell_INIT"; //Инициализация заклинания(То что в руке гг)
     	emtrjmode_s 			= "FIXED";   //???
	emTrjOriginNode 		= "ZS_RIGHTHAND"; //Инит в правой руке гг
     	emtrjtargetnode 		= "BIP01 FIRE";   //Будет лететь в точку BIP01 FIRE
     	emtrjloopmode_s 		= "NONE";  //???
     	emtrjeasefunc_s 		= "LINEAR"; //???
     	emActionCollStat_S		= "COLLIDE CREATE"; //Будет воспринемать Статичные объкты при стокновении(Будет сталкиваться если убрать то пролетать)
     	emActionCollDyn_S 		= "COLLIDE CREATEONCE"; //Будет воспринемать Динамические объкты при стокновении(Будет сталкиваться если убрать то пролетать)
	emFXCollStat_S	   		= "spellFX_NewSpell_COLLIDE"; //Колизия при Стат. Объекте.
	emFXCollDyn_S     		= "spellFX_NewSpell_COLLIDEDYNFX"; //Колизия при Дин. Объекте.
	emTrjTargetRange	 	= 20;  //???
	emTrjTargetElev 		= 0;   //???
	emTrjDynUpdateDelay		= 20000;  //???
 
	//visAlpha				= 0;
 
	};
//открытие Ключа иницияализации
	INSTANCE spellFX_NewSpell_KEY_INIT (C_ParticleFXEmitKey)
	{
	visname_S 			= "MFX_NewSpell_INIT";       //Эффект Инита
	scaleDuration		= 0.5;
	};
// Открытие ключа кастования
	INSTANCE spellFX_NewSpell_KEY_CAST (C_ParticleFXEmitKey)
	{
	visname_S 				= "MFX_NewSpell_CAST";    //Эффект каста
	emtrjmode_s 			= "TARGET";               //Должно лететь в цель
        emtrjeasevel 			= 1600.;  //???
	sfxid					= "MFX_Thunderbolt_Cast"; //Звуковой эффект при касте
	emCheckCollision		= 1;
	//emCreateFXID 			= "FX_CAST2";
	};
// Открытие ключа столкновения 
	INSTANCE spellFX_NewSpell_KEY_COLLIDE (C_ParticleFXEmitKey)
	{
        pfx_flygravity_s		= "0 0.0002 0";
	emtrjeasevel 			= 0.000001;  //???
	emCheckCollision		= 0;    //вроде выбор колизии но трагать не станем
        };
//эффект при столкновении со статикой
        instance spellFX_NewSpell_COLLIDE		(CFx_Base_Proto)
        {
	visname_S 		= "MFX_NewSpell_Collide"; //Название эфекта столкновения
	visAlpha		= 1; //чтото связанное с Альфа-каналом
	emtrjmode_s 	= "FIXED"; //до конца не врубился
	sfxid			= "Torch_Enlight"; //звуковой эффект при столкновении
        };
//Искры при столкновении со статикой
        INSTANCE spellFX_NewSpell_COLLIDE_KEY_INVEST_1	(C_ParticleFXEmitKey)
        {
	visname_S 	= "MFX_NewSpell_COLLIDE_SPARKS";
        };
//эффект при столкновении с динамикой
        instance spellFX_NewSpell_COLLIDEDYNFX		(CFx_Base_Proto)
        {
	visname_S 		= "MFX_NewSpell_Collide"; //Название эфекта столкновения
	visAlpha		= 1; //чтото связанное с Альфа-каналом
	emtrjmode_s 	= "FIXED"; //до конца не врубился
	sfxid			= "Torch_Enlight"; //звуковой эффект при столкновении 
        };
//Искры при столкновении с динамикой
	INSTANCE spellFX_NewSpell_COLLIDEDYNFX_KEY_INVEST_1	(C_ParticleFXEmitKey)
        {
	visname_S 	= "MFX_NewSpell_COLLIDE_SPARKS";
};

На этом создание эффекта завершено, теперь переходим к написанию скрипта заклинания. Открываем файл _intern→Constants.d в нем объявляем константу нашего заклинания

const int SPL_NewSpell           = 69;   //NewSpell

Также присвоим заклинанию наш Эффект тоже в файле _intern→Constants.d в массиве spellFxInstanceNames

//Заменим Light названием нашего эффекта NewSpell
   "Light",                // 69   SPL_Reserved_69
   "Thunderstorm",         // 70   SPL_Thunderstorm //НЕ трогать дал чисто для того чтобы легче было найти нужную строку

Присвоим анимацию кастования в том-же файле, а именно _intern→Constants.d в массиве spellFxAniLetters

//Заменим ХХХ на FBT вроде анимация каста огненного шара
   "XXX",                  // 69   SPL_Reserved_69
   "STM",                  // 70   SPL_Thunderstorm

Дальше идем в файл AI→Magic→Spell_ProcessMana.d в нем обрабатываются процесы инвестирования маны и тд в функции Spell_ProcessMana вписываем это

if(activeSpell == SPL_NewSpell	    	) 	{	return	Spell_Logic_NewSpell		(manaInvested);	};

Теперь создадим файл, а в нем скрипт непосредственно самого заклинания. AI→Magic→Spells→Spell_NewSpell.d ВНИМАНИЕ!!! Файл Spell_NewSpell.d нужно ставить ПЕРЕД файлом Spell_ProcessMana.d ТК в нем объявляется Spell_Logic_NewSpell

// стоимость заклинания
const int SPL_Cost_NewSpell	= 40;
 
//Повреждение от заклинания
const int SPL_Damage_NewSpell	= 65;
 
 
// объявление заклинания с инициализацией
INSTANCE Spell_NewSpell(C_Spell_Proto)
{
	time_per_mana			= 0;
	damage_per_level		= SPL_Damage_NewSpell;
};
 
// Функция инвестирования маны.
func int Spell_Logic_NewSpell(var int manaInvested)
{
	// если активное заклинание свиток и есть требуемое кол-во маны
	if(Npc_GetActiveSpellIsScroll(self) && (self.attribute[ATR_MANA] >= SPL_Cost_Scroll))
	{
		// старт заклинания
		return SPL_SENDCAST;
	}
	// иначе, если руна и есть требуемое кол-во маны
	else if(self.attribute[ATR_MANA] >= SPL_Cost_NewSpell)
	{	
		// старт заклинания
		return SPL_SENDCAST;
	}
	else // мало маны
	{
		// отмена заклинания
		return SPL_SENDSTOP;
	};
return SPL_SENDSTOP;
};
 
// Вызов заклинания
func void Spell_Cast_NewSpell()
{
	// если свиток
	if(Npc_GetActiveSpellIsScroll(self))
	{
		// уменьшение маны на стоимость свитков
		self.attribute[ATR_MANA] = self.attribute[ATR_MANA] - SPL_Cost_Scroll;
	}
	else // руна 
	{
		// уменьшение маны на фактическую стоимость заклинания
		self.attribute[ATR_MANA] = self.attribute[ATR_MANA] - SPL_Cost_NewSpell;
	};
	// изменить случайное число выбора заклинаний
	self.aivar[AIV_SelectSpell] += 1;
};

Все заклинание готово осталось внести последние штрихи, а именно создать Руну и свиток с данным заклинанием идем в файл ItemsIT_Runen.d или ItemsIT_Runes.d у кого как у меня IT_Runen.d и пишем в нем следующий скрипт:

//Создадим Руну
INSTANCE ItRu_NewSpell (C_Item)
{
	name 				=	NAME_Rune; //Имя из файла Text.d "Руна"
 
	mainflag 			=	ITEM_KAT_RUNE; //тип Руна
	flags 				=	0;
 
	value 				=	100; //Цена
 
	visual				=	"ItRu_Water04.3DS"; //Визуальный 3DS объект
	material			=	MAT_STONE;  //Материал Камень
 
	spell				= 	SPL_NewSpell;  //наше заклинание
	mag_circle			=	2; //Круг магии можно убрать
 
	wear				= 	WEAR_EFFECT; 
	effect				=	"SPELLFX_WEAKGLIMMER_BLUE"; //синее свечение руны
 
	description			=	NAME_SPL_NewSpell; //Название нашего заклинания в файле Text.d
 
	TEXT	[0]			=	NAME_Mag_Circle;		
	COUNT	[0]			=	mag_circle; //Круг
 
	TEXT	[1]			=	NAME_Manakosten;			
	COUNT	[1]			=	SPL_Cost_NewSpell; //Стоит маны
 
	TEXT	[2]			=	NAME_Damage;			
	COUNT	[2]			=	SPL_DAMAGE_NewSpell; //повреждение
 
	TEXT	[5]			=	NAME_Value;					
	COUNT	[5]			=	value;  //цена
};
//Теперь создадим свиток заклинания
INSTANCE ItSc_NewSpell (C_Item)
{
	name 				=	"Свиток";
 
	mainflag 			=	ITEM_KAT_RUNE; 
	flags 				=	ITEM_MULTI;
 
	value 				=	100; //цена
 
	visual				=	"ItSc_Water02.3DS";
	material			=	MAT_LEATHER;
 
	spell				= 	SPL_NewSpell; //наше заклинание
	cond_atr[2]   		        =	ATR_MANA_MAX;
	cond_value[2]  		        =	SPL_Cost_Scroll; //стоимость свитка
 
	wear				= 	WEAR_EFFECT;
	effect				=	"SPELLFX_WEAKGLIMMER";
 
	description			=	NAME_SPL_NewSpell; //Заклинание магов Воды
 
	TEXT	[0]			=	Name_MageScroll;
 
	TEXT	[1]			=	NAME_Mana_needed;			
	COUNT	[1]			=	SPL_Cost_Scroll; //нада маны
 
	TEXT	[5]			=	NAME_Value;					
	COUNT	[5]			=	value; //цена
};

Чуть не забыл надо еще прописать имяя заклинанию в файле Text.d в массиве TXT_SPELLS пишем на месте «TXT_SPL_RESERVED_69» Пишем «Заклинание Мага Воды» далее в том-же файле ищем строку NAME_SPL_Reserved_69 = «NAME_SPL_RESERVED_69»; и заменяем ее NAME_SPL_NewSpell = «Заклинание Мага Воды»;

Вот и все наше заклинание готово! Вот текстура эффекта pfx_abs_03.tga Всем пока, до новых встречь!;-)

Автор

Автор статьи - Saturas.