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

    Чтобы получить возможность писать на форуме, оставьте сообщение в этой теме.
    Удачи!
    Скрыть объявление
  2. Форум аддона "Возвращение" 2.0:
    — Обсудить игру, почитать о прохождениях и/или разрешить свои вопросы по игре вы можете в одной из тем одноименного форума. Посетить...
    — Прочитать историю изменения и/или скачать последнюю версию аддона "Возвращение", вы можете на страницах наших ресурсов. Скачать...
    Скрыть объявление

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

Тема в разделе "Скриптинг", создана пользователем MEG@VOLT, 11 июл 2013.

Статус темы:
Закрыта.
  1. MEG@VOLT

    MEG@VOLT ★★★★★★★
    Модератор

    Регистрация:
    24 мар 2006
    Сообщения:
    1.733
    Благодарности:
    761
    Баллы:
    290
    Итак давайте подведём обобщение, создадим что-то типа мини мода. В него будет входить 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.
     
    Грек73, Валера и Alliat поблагодарили.
Статус темы:
Закрыта.

Поделиться этой страницей