• Уважаемые гости и новички, приветствуем Вас на нашем форуме
    Здесь вы можете найти ответы практически на все свои вопросы о серии игр «Готика» (в том числе различных модах на нее), «Ведьмак», «Ризен», «Древние свитки», «Эра дракона» и о многих других играх. Можете также узнать свежие новости о разработке новых проектов, восхититься творчеством наших форумчан, либо самим показать, что вы умеете. Ну и наконец, можете обсудить общие увлечения или просто весело пообщаться с посетителями «Таверны».

    Чтобы получить возможность писать на форуме, оставьте сообщение в этой теме.
    Удачи!
  • Друзья, доброго времени суток! Спешите принять участие в конкурсе "Таинственные миры" 2024!
    Ждем именно вас!

    Ссылка на конкурсную тему - тык

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

Статус
В этой теме нельзя размещать новые ответы.

MEG@VOLT

★★★★★★★★★
ТехАдмин
Регистрация
24 Мар 2006
Сообщения
9.158
Благодарности
6.138
Баллы
1.565
Итак давайте подведём обобщение, создадим что-то типа мини мода. В него будет входить 2 новых НПС, 1 задание, новое оружие,новое письмо.
Всё что будет приведено ниже делается с помощью программы [[programs:gothic-sourcer|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.
 
Статус
В этой теме нельзя размещать новые ответы.
Сверху Снизу