Создание скриптового мини-мода

Создание скриптового мини-мода

Итак давайте подведём обобщение, создадим что-то типа мини мода. В него будет входить 2 новых НПС, 1 задание, новое оружие,новое письмо.

Всё что будет приведено ниже делается с помощью программы Gothic Sourcer.

1) Давайте создадим новый меч.

Для этого заходим в DECOMPILED\_work\data\Scripts\_decompiled\Items и открываем файл IT_Melee_weapons, там создаём скрипт:

instance ItMw_2h_Sld_Sword2(C_Item)
{
	name 		= "Магический меч Тима";
 
	mainflag 	= ITEM_KAT_NF;
	flags 		= ITEM_2HD_SWD;
 
	material 	= MAT_METAL;
	wear 		= WEAR_EFFECT;
	effect 		= "SPELLFX_CROSSBOW";
 
	value 		= Value_Sld2hSchwert;
 
	damageTotal 	= Damage_Sld2hSchwert;
	damagetype 		= DAM_EDGE;
	range 			= Range_Sld2hSchwert;
 
	cond_atr[2] 	= ATR_STRENGTH;
	cond_value[2] 	= Condition_Sld2hSchwert;
 
	visual 		= "ItMw_035_2h_sld_sword_01.3DS";
 
	description = name;
 
	text[2] 	= NAME_Damage;
	count[2] 	= damageTotal;
	text[3] 	= NAME_Str_needed;
	count[3] 	= cond_value[ 2];
	text[4] 	= NAME_TwoHanded;
	text[5] 	= NAME_Value;
	count[5] 	= value;
};

Я думаю здесь комментировать не надо и так всё понятно, просто подмечу что эти 2 строчки

wear = WEAR_EFFECT;
effect = "SPELLFX_CROSSBOW";

означают что наш меч будет сверкать как магический арбалет.

2) Теперь создадим письмо.

заходим в DECOMPILED\_work\data\Scripts\_decompiled\Items и открываем файл IT_Addon_Written, там пишем скрипт нашего письма:

instance ITWr_Addon_Hinweis_05(C_Item)
{
	name = "Письмо Ксардасу"; // название письма
	mainflag = ITEM_KAT_DOCS;
	flags = ITEM_MISSION; // флаг
	value = 250; // сколько стоит
	visual = "ItWr_Scroll_01.3DS"; // как выглядит
	material = MAT_LEATHER;
	on_state[0] = Use_Hinweis_05;
	scemeName = "MAP";
	description = name;
	text[0] = "";
};
 
func void Use_Hinweis_05()
{
	var int nDocID;
	nDocID = Doc_Create();
	Doc_SetPages(nDocID,1);
	Doc_SetPage(nDocID,0,"letters.TGA",0);
	Doc_SetFont(nDocID,0,FONT_BookHeadline);
	Doc_SetMargins(nDocID,-1,50,50,50,50,1);
	Doc_PrintLine(nDocID,0,"");
	Doc_SetFont(nDocID,0,FONT_Book);
	Doc_PrintLine(nDocID,0,"");
	Doc_PrintLine(nDocID,0,"Парни,");
	Doc_PrintLines(nDocID,0,"");
	Doc_PrintLines(nDocID,0,"Привет мой старый друг,вот решил");
	Doc_PrintLines(nDocID,0,"тебя поведать");
	Doc_PrintLines(nDocID,0,"Давай встретимся в знакомом мне месте");
	Doc_PrintLines(nDocID,0,"Возле таверны мёртвая гарпия.");
	Doc_PrintLine(nDocID,0,"");
	Doc_PrintLine(nDocID,0,"Рухар");
	Doc_PrintLine(nDocID,0,"");
	Doc_Show(nDocID);
};

Ну а дальше идёт сам текст. Тут думаю всё понятно.

Теперь создаём скрипты 2 неписей:

Для этого заходим в DECOMPILED\_work\data\Scripts\_decompiled\Story\NPC и создаём там файл под названием VLK_666_Tim:

instance VLK_666_Tim(Npc_Default)
{
	name[ 0] = "Тим"; // имя
	guild = GIL_VLK; // Гильдия(в нашем случае горожанин)
	id = 666; // уникальный идентификатор.
	voice = 13; // голос персонажа
	flags = 0; // флаг (в нашем случае смертный)
	npcType = NPCTYPE_AMBIENT; // тип персонажа (несюжетный)
 
	// Ниже атрибуты,там всё понятно
 
	attribute[ATR_STRENGTH] = 150; 
	attribute[ATR_DEXTERITY] = 150; 
	attribute[ATR_MANA_MAX] = 110; 
	attribute[ATR_MANA] = 110; 
	attribute[ATR_HITPOINTS_MAX] = 250; 
	attribute[ATR_HITPOINTS] = 250;
 
	// Здесь таланты,оже понятно
 
	HitChance [NPC_TALENT_1H] = 100; 
	HitChance [NPC_TALENT_2H] = 100; 
	HitChance [NPC_TALENT_BOW] = 100; 
	HitChance [NPC_TALENT_CROSSBOW] = 100; 
 
	B_GiveNpcTalents(self);
	B_SetFightSkills(self,15);
	fight_tactic = FAI_HUMAN_COWARD; // владение оружием
 
	EquipItem(self, ItRw_Bow_M_04); // Лук одет
	B_CreateAmbientInv(self);
 
	B_SetNpcVisual(self,MALE,"Hum_Head_Bald",Face_N_NormalBart_Dusty,BodyTex_N, ITAR_VLK_L); // Внешность
	Mdl_SetModelFatness(self,1);
	Mdl_ApplyOverlayMds(self,"Humans_Relaxed.mds");
 
	daily_routine = Rtn_Start_666;
};
 
func void Rtn_Start_666()
{
	TA_Smoke_Joint (7,55,19,55,"NW_FARM1_OUT_01");
	TA_Smoke_Joint (19,55,7,15,"NW_FARM1_OUT_01");
};

Чувак стоит на ферме Лобарта и курит болотник.

Теперь создаём скрипт второго НПС под названием KDF_999_Ryxar:

instance KDF_999_Ryxar(Npc_Default)
{
	name [0] = "Рухар";
	guild = GIL_KDF;
	id = 999;
	voice = 13;
	flags = 0;
	npcType = NPCTYPE_AMBIENT;
 
	attribute[ATR_STRENGTH] = 50; 
	attribute[ATR_DEXTERITY] = 50; 
	attribute[ATR_MANA_MAX] = 1000; 
	attribute[ATR_MANA] = 1000; 
	attribute[ATR_HITPOINTS_MAX] = 1000; 
	attribute[ATR_HITPOINTS] = 1000;
 
	HitChance [NPC_TALENT_1H] = 100; 
	HitChance [NPC_TALENT_2H] = 100; 
	HitChance [NPC_TALENT_BOW] = 100; 
	HitChance [NPC_TALENT_CROSSBOW] = 100; 
 
	B_SetFightSkills(self,15);
	fight_tactic = FAI_HUMAN_COWARD;
 
	CreateInvItems(self,ItMw_2h_Sld_Sword2,1);
	EquipItem(self,ItMw_1h_Nov_Mace);
	B_CreateAmbientInv(self);
 
	B_SetNpcVisual(self,MALE,"Hum_Head_Bald",Face_N_NormalBart10,BodyTex_N, ItAr_KDF_L);
	Mdl_SetModelFatness(self,0);
	Mdl_ApplyOverlayMds(self,"Humans_Mage.mds");
 
	daily_routine = Rtn_Start_999;
};
 
func void Rtn_Start_999()
{
	TA_Practice_Magic (7,55,19,55,"NW_CITY_MERCHANT_TEMPLE_IN");
	TA_Practice_Magic (19,55,7,15,"NW_CITY_MERCHANT_TEMPLE_IN");
};

Я повторятся не буду, то же самое. Только этот НПС стоит в Городе возле Ватраса..

Теперь давайте создадим для них диалоги, сначала создадим диалог Тима:

Для этого заходим в DECOMPILED\_work\data\Scripts\_decompiled\Story\Dialoge и создаём файл под названием DIA_VLK_666_Tim, теперь его внутренность:

instance DIA_VLK_666_Tim_EXIT(C_Info)
{
	npc = VLK_666_Tim;
	nr = 999;
	condition = DIA_VLK_666_Tim_EXIT_Condition;
	information = DIA_VLK_666_Tim_EXIT_Info;
	permanent = TRUE;
	description = Dialog_Ende;
};
 
func int DIA_VLK_666_Tim_EXIT_Condition()
{
	return TRUE;
};
 
func void DIA_VLK_666_Tim_EXIT_Info()
{
	AI_StopProcessInfos(self);
};
 
// Вот эта часть чтобы можно было завершить диалог.
 
instance DIA_Tim_Hello(C_Info)
{
	npc = VLK_666_Tim;
	nr = 1;
	condition = DIA_Tim_Hello_Condition;
	information = DIA_Tim_Hello_Info;
	permanent = FALSE;
	important = TRUE; // НПС сам начинает разговор.
};
 
func int DIA_Tim_Hello_Condition()
{
	return TRUE;
};
 
func void DIA_Tim_Hello_Info()
{
	AI_Output(self,other,"DIA_Tim_Hello_14_00"); //Привет,у тебя есть время? 
	AI_Output(other,self,"DIA_Tim_Hello_15_01"); //Есть,а что?
	AI_Output(self,other,"DIA_Tim_Hello_14_01"); //Мне нужна твоя помощь, понимаешь меня ограбили какие-то бандиты, теперь ищи их свищи, а мне предстоит дальний путь не мог бы ты мне помочь? 
	Info_ClearChoices(DIA_Tim_Hello); //разветвление
	Info_AddChoice(DIA_Tim_Hello,"Конечно помогу.",DIA_Tim_Hello_yes); // Варианты ответов
	Info_AddChoice(DIA_Tim_Hello,"Извини но у меня нет времени.",DIA_Tim_Hello_no); // Варианты ответов
};
 
// Если говорим первый (помогаем),то
 
func void dia_Tim_Hello_yes () 
{ 
	AI_Output(other,self,"DIA_Tim_Hello_yes_15_00");//Конечно,но что я могу сделать? 
	AI_Output(self,other,"DIA_Tim_Hello_yes_03_01"); //Я знаю что в городе есть маг,может быть он смог бы сделать магическое оружия.
	AI_Output(other,self,"DIA_Tim_Hello_yes_15_01");//Хорошо,я посмотрю что можно сделать.
	MIS_Weapons = LOG_Running;
	Log_CreateTopic(TOPIC_Weapons ,LOG_MISSION); 
	Log_SetTopicStatus(TOPIC_Weapons,LOG_Running); // дневник
	B_LogEntry(TOPIC_Weapons,"Я согласился помочь одному страннику принести волшебный меч,в этом мне может помочь один Маг в городе"); // запись в дневник
	AI_StopProcessInfos (self); // после реплики сам выходит из диалога
};
 
// Если отказываемся,то
 
func void DIA_Tim_Hello_no () 
{ 
	AI_Output(other,self,"DIA_Tim_Hello_no _15_00"); //Извини,но у меня мало времени и я не смогу помочь тебе.
	AI_Output(self,other,"DIA_Tim_Hello_no _03_01"); //Ну ладно(тяжко вздыхает).
	AI_StopProcessInfos (self); // после реплики сам выходит из диалога
};
 
instance DIA_Tim_HI2(C_Info)
{
	npc = VLK_666_Tim;
	nr = 99;
	condition = DIA_Tim_HI2_Condition;
	information = DIA_Tim_HI2_Info;
	description = "Я принёс тебе то что ты просил.";//выбор диалога
};
 
func int DIA_Tim_HI2_Condition()
{
	if(Npc_HasItems(other,ItMw_2h_Sld_Sword2)>= 1) //Появляется,если у нас есть это оружия(скрипт выше)
	{
		return TRUE;
	};
};
 
func void DIA_Tim_HI2_Info()
{
	AI_Output(other,self,"DIA_Tim_HI2_15_00"); // Я принёс тебе то что ты просил.
	AI_Output(self,other,"DIA_Tim_HI2_04_01"); //Это замечательно,давай скорей
	AI_Output(other,self,"DIA_Tim_HI2_15_01"); //Вот он.
	b_giveinvitems(self,other,ItMw_2h_Sld_Sword2,1); //Отдаём меч
	AI_Output(self,other,"DIA_Tim_HI2_04_02"); //Я поздравляю ты прошёл проверку,поэтому я заканчиваю твою игру на этом этапе(смеётся).
	Log_SetTopicStatus(TOPIC_Weapons, LOG_SUCCESS); //заканчиваем мисию
	B_LogEntry(TOPIC_Weapons,"Когда я ему отдал он был в вострге."); //запись в дневнике
	B_Extro_Avi(); //А вот это попробуйте пропишите,увидите эффект.
};

Теперь скрипт Руфуса:

Для этого создаём файл под названием DIA_KDF_999_Ryxar (повторяться не буду, напишу то что не было написано выше):

instance DIA_KDF_999_Ryxar_EXIT(C_Info)
{
	npc = KDF_999_Ryxar;
	nr = 999;
	condition = DIA_KDF_999_Ryxar_EXIT_Condition;
	information = DIA_KDF_999_Ryxar_EXIT_Info;
	permanent = TRUE;
	description = Dialog_Ende;
};
 
func int DIA_KDF_999_Ryxar_EXIT_Condition()
{
	return TRUE;
};
 
func void DIA_KDF_999_Ryxar_EXIT_Info()
{
	AI_StopProcessInfos(self);
};
 
instance DIA_Ryxar_HI(C_Info)
{
	npc = KDF_999_Ryxar;
	nr = 99;
	condition = DIA_Ryxar_HI_Condition;
	information = DIA_Ryxar_HI_Info;
	description = "Привет.";
};
 
func int DIA_Ryxar_HI_Condition()
{
	return TRUE;
};
 
func void DIA_Ryxar_HI_Info()
{
	AI_Output(other,self,"DIA_Ryxar_HI_15_00"); //Привет. AI_Output(self,other,"DIA_Ryxar_HI_04_01"); //привет-привет.
	AI_Output(other,self,"DIA_Ryxar_HI_15_01"); //что ты здесь делаешь?
	AI_Output(self,other,"DIA_Ryxar_HI_04_02"); //извини,но это не твоё дело.
};
 
instance DIA_Ryxar_HI2(C_Info)
{
	npc = KDF_999_Ryxar;
	nr = 99;
	condition = DIA_Ryxar_HI2_Condition;
	information = DIA_Ryxar_HI2_Info;
	description = "Не мог бы ты мне помочь?";
};
 
func int DIA_Ryxar_HI2_Condition()
{
	if(MIS_Weapons == LOG_Running) //Диалог появится при условии что мы начали задание.
	{
		return TRUE;
	};
};
 
func void DIA_Ryxar_HI2_Info()
{
	AI_Output(other,self,"DIA_Ryxar_HI2_15_00"); //Не мог бы ты помочь? 
	AI_Output(self,other,"DIA_Ryxar_HI2_04_01"); //Ну это смотря в чём?
	AI_Output(other,self,"DIA_Ryxar_HI2_15_01"); //Мне нужно сделать магические меч.
	AI_Output(self,other,"DIA_Ryxar_HI2_04_02"); //А зачем он тебе?
	AI_Output(other,self,"DIA_Ryxar_HI2_15_02"); //Он нужен не мне просто я помогаю одному человеку.
	AI_Output(self,other,"DIA_Ryxar_HI2_04_03"); //Ты совершаешь заслуженный поступок я сделаю тебе магическое оружия,как раз у меня всё для этого есть,Но для этого ты должен отнести письмо Ксардасу,просто я плохо знаю эту местность.
	AI_Output(other,self,"DIA_Ryxar_HI2_15_03"); //Но откуда ты знаешь Ксардаса,он говорил что онём практичекси никто не знает или хотя бы думают что он умер.
	AI_Output(self,other,"DIA_Ryxar_HI2_04_04"); //Ксардас-мой друг и мне лучше знать жив он или нет,просто мы давно с ним не виделись я и приехал с ним поведаться.Вобщем передай эту записку.
	B_GivePlayerXP(250); //Получаем 250 опыта.
	b_giveinvitems(self,other,ITWr_Addon_Hinweis_05,1);
	B_LogEntry(TOPIC_Weapons,"Для того чтобы мне сделали волшебный меч,мне нужно передать записку Ксардасу."); 
};
 
instance DIA_Ryxar_HI3(C_Info)
{
	npc = KDF_999_Ryxar;
	nr = 99;
	condition = DIA_Ryxar_HI3_Condition;
	information = DIA_Ryxar_HI3_Info;
	description = "Я отдал записку.";
};
 
func int DIA_Ryxar_HI3_Condition()
{
	if(Npc_KnowsInfo(other, DIA_Xardas_HI3)) 
	{
		return TRUE;
	};
};
 
func void DIA_Ryxar_HI3_Info()
{
	AI_Output(other,self,"DIA_Ryxar_HI3_15_00"); //Я отдал записку Ксардасу.
	AI_Output(self,other,"DIA_Ryxar_HI3_04_01"); //Очень хорошо,наконец то я смогу встретится с другом.
	AI_Output(other,self,"DIA_Ryxar_HI3_15_01"); //Я выполнил свою часть,теперь дело за тобой.
	AI_Output(self,other,"DIA_Ryxar_HI3_04_02"); //Конечно.Я выполнил и свою часть,держи свой волшебный меч.
	B_GivePlayerXP(550);
	b_giveinvitems(self,other, ItMw_2h_Sld_Sword2,1);
	B_LogEntry(TOPIC_Weapons,"Я получил меч от мага,теперь осталось передать его Странику."); 
};

Ещё есть диалог Ксардаса, но там совсем легко,просто в конце его скрипта прописываем (none_100_xardas):

instance DIA_Xardas_HI3(C_Info)
{
	npc = NONE_100_Xardas;
	nr = 99;
	condition = DIA_Xardas_HI3_Condition;
	information = DIA_Xardas_HI3_Info;
	description = "У меня для тебя записка.";
};
 
func int DIA_Xardas_HI3_Condition()
{
	if(Npc_HasItems(other,ITWr_Addon_Hinweis_05)>= 1)
	{
		return TRUE;
	};
};
 
func void DIA_Xardas_HI3_Info()
{
	AI_Output(other,self,"DIA_Xardas_HI3_15_00"); // У меня для тебя записка.
	AI_Output(self,other,"DIA_Xardas_HI3_04_01"); //Очень интересно.
	AI_Output(other,self,"DIA_Xardas_HI3_15_01"); //Вот она
	B_GivePlayerXP(100);
	b_giveinvitems(other,self,ITWr_Addon_Hinweis_05,1);
	B_LogEntry(TOPIC_Weapons,"Я передал записку,тперь маг должен дать мне Волшебный меч."); 
};

Так эта часть закончена,осталась самая нудная это везде прописать, ну давайте сначала пропишем наших 2 неписей

Для этого заходим в DECOMPILED\_work\data\Scripts\_decompiled\Story и открываем файл Startup.d

Ищем там строчку

Wld_InsertNpc(VLK_439_Vatras,"NW_CITY_ENTRANCE_01");

и пишем после неё

Wld_InsertNpc(KDF_999_Ryxar," NW_CITY_MERCHANT_TEMPLE_IN ");

(это только первый НПС) теперь второй, ищем строчку

Wld_InsertNpc(BAU_950_Lobart,"NW_FARM1_OUT_01");

и после неё прописываем:

Wld_InsertNpc(VLK_666_Tim,"NW_FARM1_OUT_01");

Теперь заходим в файл Story_Globals и ищем строку

var int CurrentLevel;

(она почти в самом конце) и прописываем

var int MIS_Weapons;

Так дальше заходим в DECOMPILED\_work\data\Scripts\_decompiled\Story\Log_Entries и заходим в файл LOG_Constants_Yoly и в самом конце прописываем

const string TOPIC_Weapons = "Меч для тима";

(наша миссия).

Последний шаг,заходим в DECOMPILED\_work\data\Scripts\_decompiled и открываем файл gothic.SRC

Там прописываем в любом месте где НПС:

STORY\NPC\VLK_666_Tim.d
STORY\NPC\KDF_999_Ryxar.d

Ну и так же прописываем в любом месте где диалоги:

STORY\DIALOGE\DIA_VLK_666_Tim.d
STORY\DIALOGE\DIA_KDF_999_Ryxar.d

Ну а дальше компиляция.

У нас появляются 2 файла Gothic.dat и OU.BIN.

Gothic.dat вставляем в Gothic II\_work\Data\Scripts\_compiled

OU.BIN вставляем в Gothic II\_work\Data\Scripts\Content\Cutscene

Всё теперь заходим в Готику2 НВ и наслаждайтесь то что вы сделали.

Желаю всем новичкам удачи в модостроительстве.

Автор

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

/var/www/wogru_main/data/www/mod.worldofgothic.ru/data/pages/scripting/mini-mod.txt · Последние изменения: 09-01-2009 08:14 (внешнее изменение)

Проект портала World of Gothic RU. © 2005-2009 marazmus, MaGoth и команда World of Gothic RU.
Копирование материалов сайта разрешено только при явном согласии авторов материалов.
При копировании материалов прямая ссылка на сайт обязательна.

Rambler's Top100 Рейтинг Ролевых Ресурсов

SEO-аудит сайта: создание и раскрутка сайта - оптимизация сайта
модная одежда для полных красавиц
Круглосуточная продажа каминов в подмосковье
каталог faberlic онлайн