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

    Чтобы получить возможность писать на форуме, оставьте сообщение в этой теме.
    Удачи!

Вопросы по скриптингу

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.367
Благодарности
7.815
Баллы
995
  • Первое сообщение
  • #1
Прежде чем задавать вопросы, ознакомьтесь с документацией..
1) Читать онлайн
2) Архив с офлайн-версией(chm) во вложении
 

Вложения

  • Vam_tutor.rar
    171,6 KB · Просмотры: 572
Последнее редактирование модератором:

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.367
Благодарности
7.815
Баллы
995
Кстати, интересно, в В2 убрали мусор связанный с выносливостью и ее отображением? Я в Ребалансе2.1 перекинул ее на триггер, но кучу оставшегося мусора так и не вынес, лень было.
Не знаю, я же пишу не занимаюсь им..
Но вроде как слышал что там все вычистили и переделали иначе.. ::)
 

Leonion

Участник форума
Регистрация
31 Мар 2008
Сообщения
249
Благодарности
154
Баллы
195
Leonion сейчас пытается заниматься, вот пусть и попробует сравнить работу горения через триггер и оригинал.

Leonion отзанимался.=)
Сейчас идет тестирование мода (если вдруг будет интересно, см. Resident на модострое.ру).
Ссылку не даю, так как правила форума не читал не уверен, что не запретят.

///////
Оффтоп в сторону, кто-нибудь когда-нибудь сталкивался с раздвоением личности у непися?) Если точнее, он не понимает отсылки к self в одном из диалогов.

Я уже писал про него. Когда я пытался в разговоре прописать ему переодевание и смену рутины через self, ничего не работало.
Потом прописал все (кроме AI_StopProcessInfos(self);) через глобаловское NiclasNW, все заработало, но отказывался прекращаться диалог, в результате чего Никлас так и отправлялся бежать по своим делам во время диалога, хотя задолго до смены рутины ему был прописан стоппроцессинфос (и последняя реплика в диалоге была его - вроде это имеет значение).
В итоге не придумал ничего лучше как убрать из диалога стоппроцесс инфос и смену рутины, добавить в конце NiclasUPainInTheAss = TRUE;
а в exit-диалоге впихнуть после стоппроцесинфоса:
if (NiclasUPainInTheAss == TRUE)
{
B_StartOtherRoutine(NiclasNW,"DTBeforeTrollHunt");
NiclasUPainInTheAss = FALSE;
};
Ничего другое не помогало. Причем вроде диалог как диалог (полный вариант под спойлером в старой версии).
instance Dia_Niclas_LetsGoHunting(C_Info)
{
npc = BAU_984_Niclas;
nr = 18;
condition = Dia_Niclas_LetsGoHunting_Condition;
information = Dia_Niclas_LetsGoHunting_Info;
permanent = FALSE;
important = TRUE;
};

func int Dia_Niclas_LetsGoHunting_Condition()
{
if ((Npc_KnowsInfo(other,Dia_Niclas_AllReadyForHunt)) && ((DayBeforeTrollHunt + 1) == Wld_GetDay()))
{
return TRUE;
};
};

func void Dia_Niclas_LetsGoHunting_Info()
{
AI_Output(self,other,"Dia_Niclas_LetsGoHunting_01_00"); //Вот и ты! Остальные парни уже ждут тебя. Ты готов?
AI_Output(other,self,"Dia_Niclas_LetsGoHunting_15_01"); //Да. Можем выдвигаться.
AI_Output(self,other,"Dia_Niclas_LetsGoHunting_01_02"); //Отлично, следуй за мной.
AI_StopProcessInfos(self);
(... - тут куча переодеваний и смен рутин для других неписей)
CreateInvItems(NiclasNW,ItMw_Morgenstern,1);
AI_EquipBestMeleeWeapon(NiclasNW);
if (JanRecruitedDT == TRUE)
{
CreateInvItems(NiclasNW,ITAR_DJG_L,1);
AI_EquipBestArmor(NiclasNW);
};
B_StartOtherRoutine(NiclasNW,"DTBeforeTrollHunt");
};
 

Dimmell

Участник форума
Регистрация
23 Ноя 2008
Сообщения
2.899
Благодарности
111
Баллы
285
Оффтоп в сторону, кто-нибудь когда-нибудь сталкивался с раздвоением личности у непися?) Если точнее, он не понимает отсылки к self в одном из диалогов.

Про эти странности я уже писал когда-то, повторю пример.
Вот пример диалога с Лестером из Ребаланса после которого он телепортируется к Ксардасу. Ремарками пометил куда примерно можно вставить переодевание и т.д.
instance DIA_Lester_BACKINTOWN(C_Info)
{
npc = PC_Psionic;
nr = 2;
condition = DIA_Lester_BACKINTOWN_Condition;
information = DIA_Lester_BACKINTOWN_Info;
important = TRUE;
};


func int DIA_Lester_BACKINTOWN_Condition()
{
if((Npc_GetDistToWP(self,"LEVELCHANGE") <= 500) && (Kapitel == 3))
{
return TRUE;
};
};

func void DIA_Lester_BACKINTOWN_Info()
{
AI_Output(self,other,"DIA_Lester_BACKINTOWN_13_00"); //Эй, ты вернулся, наконец! Ты должен немедленно увидеться с Ксардасом. Возникли проблемы.
AI_Output(other,self,"DIA_Lester_BACKINTOWN_15_01"); //В это я готов поверить.
AI_Output(self,other,"DIA_Lester_BACKINTOWN_13_02"); //После того, как ты ушел, здесь начался ад кромешный.
// Между любыми строками можно переодеть любых НПС и изменить им рутины КРОМЕ того, с кем говорит ГГ
AI_Output(self,other,"DIA_Lester_BACKINTOWN_13_03"); //Поговори с Ксардасом, он ждет тебя!
AI_Output(self,other,"DIA_Lester_BACKINTOWN_13_04"); //Передал мне эту руну для тебя. Она поможет тебе добраться до него побыстрее. Увидимся там.
AI_Output(self,other,"DIA_Lester_BACKINTOWN_13_05"); //Я тоже телепортируюсь. На дорогах слишком опасно.
CreateInvItems(self,ItRu_TeleportXardas,1);
B_GiveInvItems(self,other,ItRu_TeleportXardas,1);
// Добавляем пустой диалог-заглушку чтобы движок не сваливал в кучу все функции и не обрабатывал их как ему вздумается
Info_ClearChoices(DIA_Lester_BACKINTOWN);
Info_AddChoice(DIA_Lester_BACKINTOWN,"...(Закончить разговор)",DIA_Lester_BACKINTOWN_end);
};

func void DIA_Lester_BACKINTOWN_end()
{
// Здесь можно переодеть собеседника (у меня Лестера), хотя возможно лучше переодеть в предыдущем блоке перед "Закончить диалог"
Wld_PlayEffect("SPELLFX_TELEPORT",self,self,0,0,0,FALSE);
AI_StopProcessInfos(self);
Npc_ExchangeRoutine(PC_Psionic,"XardasTow"); // Здесь меняем рутину собеседнику ГГ, ссылка на НПС - глобальная
AI_Teleport(PC_Psionic,"NW_XARDAS_TOWER_LESTER");
self.aivar[AIV_INVINCIBLE] = FALSE; // убираем невидимость на всякий случай после прерывания диалога, ГГ мог остаться в режиме диалога после телепорта.
other.aivar[AIV_INVINCIBLE] = FALSE;
};

Нормально телепорт отрабатывал только в такой последовательности. Если менял местами строки в ***_end(), то или визуала телепорта не было (Лестер просто исчезал), или Лестер шел вообще пешком без телепорта.
 

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.407
Благодарности
3.232
Баллы
525
переодевание и смену рутины

Насколько я понимаю, владельцу диалога распорядок менять нужно через Npc_ExchangeRoutine(self,"XXXXXX"), поскольку в скриптовых функциях происходит помимо смены распорядка ещё и очистка очереди AI-команд, что приводит к неправильной работе диалога.

он телепортируется к Ксардасу

Также столкнулся с тем, что в процессе диалога нельзя телепортировать собеседника, это приводит к невозможности нормально завершить диалог. Мне в случае с телепортацией Лестера из пещеры с горой руды в Г1 пришлось сочинять для этого особое ZS-состояние. После диалога стартует это состояние, в результате чего происходит телепорт.
 

Leonion

Участник форума
Регистрация
31 Мар 2008
Сообщения
249
Благодарности
154
Баллы
195
Насколько я понимаю, владельцу диалога распорядок менять нужно через Npc_ExchangeRoutine(self,"XXXXXX"), поскольку в скриптовых функциях происходит помимо смены распорядка ещё и очистка очереди AI-команд, что приводит к неправильной работе диалога.

Разве? Там же вроде основная разница лишь в наличие проверки dead/не-dead и игнорировании приказа сменить рутину, если непись мертв.

Код:
func void B_StartOtherRoutine(var C_Npc slf,var string newRoutine)
{
    if(Hlp_GetInstanceID(self) != Hlp_GetInstanceID(slf))
    {
        if(Hlp_IsValidNpc(slf))
        {
            if(Npc_IsDead(slf) == FALSE)
            {
                AI_Standup(slf);
                Npc_ExchangeRoutine(slf,newRoutine);
                AI_ContinueRoutine(slf);
            };
        };
    }
    else if(Npc_IsDead(slf) == FALSE)
    {
        AI_Standup(slf);
        Npc_ExchangeRoutine(slf,newRoutine);
    };
};

Хотя эксчендж я вроде тоже пробовал, разницы не было...
 

Мільтен

Участник форума
Регистрация
27 Июн 2008
Сообщения
862
Благодарности
427
Баллы
265
Хотя эксчендж я вроде тоже пробовал, разницы не было...

Скажу так, как я это понимаю, по-простому.
B_StartOtherRoutine - игнорит состояние диалога. Непись меняет распорядок дня прямо в процессе беседы.
NpcExchangeRoutine - меняет распорядок дня по завершению диалога.

У меня, если память мне не изменяет, всегда эти функции работали именно так.
К слову, если есть надобность выполнить некие действия строго после окончания диалога, то в конце диалога присваиваем некой переменной Х значение TRUE, а потом идем в Zs_Talk и в секцию Zs_Talk_End (кажется, так называется) дописать условие, что-то вроде:

Код:
if(Hlp_GetInstanceId(self) == Hlp_GetInstanceId(инстанция_непися)) && (X == TRUE)
{
выполняем действия
X = FALSE;
}

P.S. почитал про твой мод, звучит неплохо. Только жаль, что идет на основе Возвращения и Гильдий, а не на основе твоего собственного или любого другого мода. Так бы поиграл.
 
Последнее редактирование:

Dimmell

Участник форума
Регистрация
23 Ноя 2008
Сообщения
2.899
Благодарности
111
Баллы
285
пришлось сочинять для этого особое ZS-состояние. После диалога стартует это состояние, в результате чего происходит телепорт.

Можно и отдельным состоянием, можно и как Мільтен предложил через Zs_Talk, можно вообще присвоить переменную в диалоге (типа готов) и через циклический триггер с задержкой по времени запустить новую рутину, визуал телеорта и сам телепорт (даже красивше реализовано будет). Разница только в том, что все это будет прописываться в разных местах скриптов. А я ленивый, чем потом искать и вспоминать что, где и почему - мне проще все прописать в одном месте.


почитал про твой мод, звучит неплохо. Только жаль, что идет на основе Возвращения и Гильдий, а не на основе твоего собственного или любого другого мода.
тоже почитал, поддерживаю. Лучше бы мод был на основе ванили или если лень самому заморачиваться с начальными статами НПС/монстров - то на основе Кузнеца СМ (можно и без финальных развязок). Возвращение/гильдии и так слишком перегружены, особенно 1-2 глава, а основной сюжет в моде начинается только с 3 как я понял. Наигрывать под 100 часов чтобы добраться до нового сюжета не каждый осилит.
 

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.367
Благодарности
7.815
Баллы
995
Если уж и делать что-то на основе "ванили", то сразу на Димусовых скриптах вычещенных оригиналов. Прочие моды тут лесом идут..
 

Leonion

Участник форума
Регистрация
31 Мар 2008
Сообщения
249
Благодарности
154
Баллы
195
Мне советовали на основе оригинала, но лично для меня самого просто Готика без "Возвращения" больше не воспринимается как что-то, во что стоит играть. "Возвращение" стало must, ну а "Гильдии" с виду - наиболее далеко пошедшее ответвление (больше всего дополнений).
Слишком много в "Возвращении" новых плюшек, добавлений, персонажей, квестов, чтобы просто взять, плюнуть на них и вернуться к оригиналу.)
Поэтому только так.

Наигрывать под 100 часов чтобы добраться до нового сюжета не каждый осилит.
:eek:
Если играть с мыслями "ох как же надоело все старое, ох достало, ох ненавижу, ох не могууу больше, ну гдеееее-же уже новое?!", то зачем играть? :)
Цель мода (как бы это высокомерно не звучало) - не только добавить новинку, о которой я мечтал, но и постараться доделать ветку "Гильдий", в которой оставался ряд багов и моментов, имхо, требующих корректировки. Т.е. сделать так, чтобы те, кому в очередной раз захочется перепройти "Возвращение" => "Гильдии" (просто из-за желания сыграть во что-то, не из-за желания чего-то нового), смогли при желании воспользоваться моим вариантом с поправленными скриптами + приятным бонусом в виде новой квестовой ветки.
Вот. Как-то так.

Шоб совсем оффтопом не казалось:

К слову, если есть надобность выполнить некие действия строго после окончания диалога, то в конце диалога присваиваем некой переменной Х значение TRUE, а потом идем в Zs_Talk и в секцию Zs_Talk_End (кажется, так называется) дописать условие, что-то вроде:

Код:
if(Hlp_GetInstanceId(self) == Hlp_GetInstanceId(инстанция_непися)) && (X == TRUE)
{
выполняем действия
X = FALSE;
}

Тогда уж проще как я сделал - за счет "загрязнения" exit-диалога нужного нам непися, чем трогать целое состояние.)
 
Последнее редактирование:

Phantom95

Участник форума
Регистрация
31 Июл 2014
Сообщения
2.227
Благодарности
1.910
Баллы
370
Блин , не знаю как так может быть , но в архиве гильдии 0,1.2 , нет файла с доспехами , знаю что должен быть файл armor.d но его там нет , а доспехи в игре с новыми параметрами ....
 

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.367
Благодарности
7.815
Баллы
995
Блин , не знаю как так может быть , но в архиве гильдии 0,1.2 , нет файла с доспехами , знаю что должен быть файл armor.d но его там нет , а доспехи в игре с новыми параметрами ....
Если декомпилил, то смотри его в папке _misk_, там могут быть файлы *.d, не обязательно с тем самым названием которое тебе нужно, в одном из них точно будут прописаны доспехи...
 

Phantom95

Участник форума
Регистрация
31 Июл 2014
Сообщения
2.227
Благодарности
1.910
Баллы
370
Если декомпилил, то смотри его в папке _misk_, там могут быть файлы *.d, не обязательно с тем самым названием которое тебе нужно, в одном из них точно будут прописаны доспехи...
Действительно , странно почему не находится в папке items ведь доспехи это предмет
 

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.367
Благодарности
7.815
Баллы
995
Потому что читать надо документацию/справку к проге Сурсер, при декомпиляции идет внутренняя нумерация и построение списка функций и инстанций, то что определяется правильно выводится туда куда следует, а то что было не определено, отправляется в миск.
Но при этом, порядок следования компиляции и позиционирование функций по срц файлу, нарушено не будет.
 

Phantom95

Участник форума
Регистрация
31 Июл 2014
Сообщения
2.227
Благодарности
1.910
Баллы
370
А где файл story_globals?
 

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.367
Благодарности
7.815
Баллы
995
Должен быть здесь: ..\PrjGOTHIC\Story
Читай тутор Вама.
 

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
444
Благодарности
264
Баллы
230
Интересно, а есть ли способ увеличить "скорость морфинга"?
Поясню в чём смысл. Например, есть визуальный эффект:
VisualFXInst.d:
Код:
instance TEST_FOV_01(CFX_BASE)
{
    visname_s = "morph.fov";
    emfxlifespan = -1;
    userstring[2] = "20";
    userstring[3] = "15";
};
В настоящее время такой эффект достигает своего пика искажения изображения примерно за 4 сек, что довольно-таки долго. Так вот, каким образом можно увеличить скорость достижения конечного состояния изображения в результате проигрывания данного эффекта?
 

redleha


Модостроитель
Регистрация
26 Фев 2008
Сообщения
735
Благодарности
665
Баллы
245
Интересно, а есть ли способ увеличить "скорость морфинга"?
Поясню в чём смысл. Например, есть визуальный эффект:
VisualFXInst.d:
Код:
instance TEST_FOV_01(CFX_BASE)
{
    visname_s = "morph.fov";
    emfxlifespan = -1;
    userstring[2] = "20";
    userstring[3] = "15";
};
А этими переменными баловался?:
userstring[0] = "0.8";
userstring[1] = "1.0";
userstring[2] = "120";
userstring[3] = "90";
 
Сверху Снизу