Показать сообщение отдельно
Старый 14.06.2005, 09:08   #442
marazmus
A.G.F.C.
 
Регистрация: 02.09.2005
Сообщений: 6
marazmus вне форума

По умолчанию Re: Скриптинг в Готике

Уважаемые Готы.
Предлагаю небольшой "разбор" скриптов диалогов для начинающих.
В частности, скрипт простого диалога с "повторным" выбором.
На примере диалога с Ларесом.
Если неактуально, просьба сильно не пинать  :)

[pre]
// Основное - ПУНКТ ДИАЛОГА

instance DIA_Lares_Kap1_EXIT(C_Info)

                                         // Instance означает ввод нового пункта иалога

{
     npc = VLK_449_Lares;                        // Кто формирует этот пункт
     nr = 999;                              // Чем больше NR, тем ниже в списке будет показан данный пункт
     condition = DIA_Lares_Kap1_EXIT_Condition;      // Имя фунции, которая проверят, можно ли показывать этот пункт
     information = DIA_Lares_Kap1_EXIT_Info;            // Имя функции, в теле которой программируется реакция на выбор этого пункта
     permanent = TRUE;                        // Если TRUE, то пункт показывается постоянно, если FALSE, то "одноразовый"

     important = FALSE;                        // Если TRUE, то NPC сам начнет разговор

     description = Dialog_Ende;                  // Что будет написано в строке списка пунктов
                                         // В данном случае подставляется строковая константа
                                         // Можно просто написать:  = "Закончить диалог";
};

func int DIA_Lares_Kap1_EXIT_Condition()            
                                         // Функция проверяет, можно ли показывать этот пункт меню,
                                         // если можно, возвращает TRUE
{
     if(Kapitel == 1)                        // Условие проверки: в данном случае - герой должен быть в 1 главе
     {
           return TRUE;
     };
};

func void DIA_Lares_Kap1_EXIT_Info()
                                         // Функция, в которой программируется реакция на выбор этого пункта диалога
{
     AI_StopProcessInfos(self);                  // Закончить диалог
};


// *************************************************
// Скрипты с "постоянным" выбором - обучение и т.п.
// *************************************************

// Почти всегда скрипты этого типа используют переменные, для того, чтобы узнать,
// в каком пункте меню сейчас мы находимся

var int Lares_MerkeDEX;                         // Эти переменные нужны для того, чтобы Ларе мог сказать после обучения,
var int Lares_MerkeSTR;                              // изменились сила или ловкость ГГ или нет

instance DIA_Lares_TEACH(C_Info)                  // Формируем пункт диалога "Тренировка"
{
     npc = VLK_449_Lares;                        //
     nr = 20;
     condition = DIA_Lares_TEACH_Condition;            // В этой функции проверим, спрашивал ли ГГ еще об обучении или нет
     information = DIA_Lares_TEACH_Info;            // Здесь будет реакция на выбор этого пункта
     permanent = TRUE;                        // Пункт постоянный (не "одноразовый")
     description = "Научи меня чему-нибудь. ";      // Текст пункта
};


func int DIA_Lares_TEACH_Condition()
{
     if(Lares_TeachDEX == TRUE)                  // Эта переменная становится TRUE чуть выше в скриптах,
                                         // когда ГГ српашивает Лареса, не может ли тот научить чему-либо
     {
           return TRUE;                        // Если спрашивал, то пункт диалога "Тренировка" можно показать
     };
};

func void DIA_Lares_TEACH_Info()                  // Реагируем на выбор пункта диалога "Тренировка"
{
     AI_Output(other,self,"DIA_Addon_Lares_Teach_15_00 ");      //Научи меня чему-нибудь.
                                         
                                         // Говорим что-либо от имени ГГ (конструкция other,self)
                                         
     Lares_MerkeDEX = other.attribute[ATR_DEXTERITY];// Запоминаем текущую силу и ловкость ГГ
     Lares_MerkeSTR = other.attribute[ATR_STRENGTH];      //

     Info_ClearChoices(DIA_Lares_TEACH);            // На случай, если эти пункты выбора уже показывались,
                                         // очищаем список, чтобы не было дублей

                                         // AddChoice формирует список выбора снизу вверх,
                                         // т.е. пункт "Назад" будет самым нижним и т.д.
     Info_AddChoice(DIA_Lares_TEACH,Dialog_Back,DIA_La res_TEACH_BACK);
     
     Info_AddChoice  (      
                 DIA_Lares_TEACH,            // Пункт диалога, к которому относится данный пункт выбора

                                         // Что печатаем в данном пункте выбора; в данном случае это функция
                                         // B_BuildLearnString, которая формирует текстовую строку типа
                                         // Тренировать Ловкость (1 очко обучения)
                 B_BuildLearnString      (      
                                   PRINT_LearnDEX1,      
                                   B_GetLearnCostAttribute(other,ATR_DEXTERITY)
                                   ),      
                                         
                 DIA_Lares_TEACH_1            // Функция, которая вызывается при выборе данного пункта
                 );                        
     
     Info_AddChoice      (
                 DIA_Lares_TEACH,
                 B_BuildLearnString      (
                                   PRINT_LearnDEX5,
                                   B_GetLearnCostAttribute(other,ATR_DEXTERITY) * 5 // Тренировать Ловкость (5 очков обучения)
                                   ),
                 DIA_Lares_TEACH_5);
     
     Info_AddChoice(DIA_Lares_TEACH,B_BuildLearnString (PRINT_LearnSTR1,B_GetLea
rnCostAttribute(other,ATR_STRENGTH)),DIA_Lares_TEA CHSTR_1);
     Info_AddChoice(DIA_Lares_TEACH,B_BuildLearnString (PRINT_LearnSTR5,B_GetLea
rnCostAttribute(other,ATR_STRENGTH) * 5),DIA_Lares_TEACHSTR_5);
};

// Функция, вызываемая при выборе пункта "Назад"

func void DIA_Lares_TEACH_BACK()
{
     if(other.attribute[ATR_DEXTERITY] > Lares_MerkeDEX)                  // Если переменная изменилась, то есть научились чему-то
     {
           AI_Output(self,other,"DIA_Lares_TEACH_BACK_09_00" );            // (оценивающе) Твоя ловкость увеличилась.
     };
     if(other.attribute[ATR_STRENGTH] > Lares_MerkeSTR)
     {
           AI_Output(self,other,"DIA_Addon_Lares_TEACH_BACK_ Add_09_00");      //(оценивающе) Твоя сила увеличилась.
     };
     Info_ClearChoices(DIA_Lares_TEACH);
};

// Функция, вызываемая при выборе пункта "Тренировать ловкость (1 очко обучения)"
func void DIA_Lares_TEACH_1()
{
     // Вызываем функцию, которая учит ГГ (self, other)
     // self в данном случае - Ларес
     // other - ГГ
     // T_MED - константа из Story\Story_Globals.d ("потолок" учителя)
     
     B_TeachAttributePoints(self,other,ATR_DEXTERITY,1 ,T_MED);
     
     // !! ВАЖНО !!
     // Так как пункт выбора, сформированный функцией Info_AddChoice, при выборе ИСЧЕЗАЕТ из списка,
     // то список нужно формировать ЗАНОВО, предварительно очистив "использованный" список
     // Этим достигается "ЦИКЛИЧНОСТЬ" списка пунктов выбора
     
     // Чистим "использованный" список
     Info_ClearChoices(DIA_Lares_TEACH);
     
     // Формируем список заново
     Info_AddChoice(DIA_Lares_TEACH,Dialog_Back,DIA_La res_TEACH_BACK);
     Info_AddChoice(DIA_Lares_TEACH,B_BuildLearnString (PRINT_LearnDEX1,B_GetLea
rnCostAttribute(other,ATR_DEXTERITY)),DIA_Lares_TE ACH_1);
     Info_AddChoice(DIA_Lares_TEACH,B_BuildLearnString (PRINT_LearnDEX5,B_GetLea
rnCostAttribute(other,ATR_DEXTERITY) * 5),DIA_Lares_TEACH_5);
     Info_AddChoice(DIA_Lares_TEACH,B_BuildLearnString (PRINT_LearnSTR1,B_GetLea
rnCostAttribute(other,ATR_STRENGTH)),DIA_Lares_TEA CHSTR_1);
     Info_AddChoice(DIA_Lares_TEACH,B_BuildLearnString (PRINT_LearnSTR5,B_GetLea
rnCostAttribute(other,ATR_STRENGTH) * 5),DIA_Lares_TEACHSTR_5);
};

// Вкратце, алгоритм для формирования пункта ДИАЛОГА с разворачивающимся списком пунктов ВЫБОРА такой:
//
//       1.       Формируем пункт ДИАЛОГА через Instance
//                  Например, instance DIA_Lares_TEACH(C_Info) { ... }
//            Формируем для него функции int _Condition (Проверка на отображение) и void _Info (Реакция на выбор)
//
//       2.       Список пунктов ВЫБОРА формируется в функции void _Info с помощью функции Info_AddChoice
//            Эта функция ссылается на:       а) instance Родителя
//                                          Например, instance DIA_Lares_TEACH      
//                                    б) Функцию реакции
//                                          Например, void DIA_Lares_TEACH_1
//            Здесь важный момент:
//
//            Если цикличность списка пунктов ВЫБОРА не важна, в фукнции реакции не надо делать Info_ClearChoices / Info_AddChoice,
//            так как пункт выбора, сформированный функцией Info_AddChoice, при выборе ИСЧЕЗАЕТ из списка,
//            достаточно запрограммировать только реакцию
//      
//            Если же нужно зациклить список пунктов ВЫБОРА, то в функции реакции нужно сделать последовательно:
//                  Info_ClearChoices( ... instance Родителя ...)
//                        - очистить "использованный" список
//                  Info_AddChoice ( ... instance Родителя ... функция реакции)
//                        - сформировать список снова, возможно, в том же виде (copy / paste :-)
//                  !! В функции Info_AddChoice получается что-то вроде рекурсии (вызова самой себя)
//            Здесь важно не забыть сделать (желательно первым) Info_AddChoice для пункта выбора "НАЗАД",
//            иначе можно зациклить список "намертво", без возможности выхода
//            В функции реакции на выбор пункта "НАЗАД" достаточно сделать Info_ClearChoices (... instance Родителя ...),
//            это вернет нас к пункту ДИАЛОГА "Родителя".


[/pre]
Отправить личное сообщение для Ответить с цитированием