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

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

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

MaGoth

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

Вложения

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

Dimus

★★★★★★★★★
Супермодератор
Регистрация
19 Июл 2010
Сообщения
5.574
Благодарности
4.167
Баллы
915
В функции B_MM_AssessWarn() предусмотрены немного другие ситуации:
Код:
    if((self.guild == other.guild) && (self.aivar[AIV_MM_Packhunter] == TRUE))
    {
        if((self.guild == GIL_WOLF) && (victim.guild == GIL_WOLF) && Npc_IsPlayer(victim))
        {
            return;
        };
        if(Npc_IsInState(other,ZS_MM_Attack))
        {
            Npc_ClearAIQueue(self);
            Npc_SetTarget(self,victim);
            B_ClearPerceptions(self);
            AI_StartState(self,ZS_MM_Attack,0,"");
            return;
        };
        if(Npc_IsInState(other,ZS_MM_ThreatenEnemy))
        {
            AI_SetWalkMode(self,NPC_RUN);
            AI_GotoNpc(self,victim);
            return;
        };
    };
Т.е. указанный тобой фрагмент кода надо перенести в эту функцию, а заодно добавить в исключения кабанов (aivar[AIV_MM_REAL_ID] != ID_Keiler)?
 

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.407
Благодарности
3.232
Баллы
525
Т.е. указанный тобой фрагмент кода надо перенести в эту функцию, а заодно добавить в исключения кабанов (aivar[AIV_MM_REAL_ID] != ID_Keiler)?

Нет. Но нужно изменять функцию B_MM_AssessWarn и тестить, что выйдет.

Код:
    if((self.guild == other.guild) && (self.aivar[AIV_MM_Packhunter] == TRUE)) // Если атакует свой.
    {
        if((self.guild == GIL_WOLF) && (victim.guild == GIL_WOLF) && Npc_IsPlayer(victim)) // Если волк видит, как атакуют ГлавГероя в образе волка.
        {
            return;
        };
        if(Npc_IsInState(other,ZS_MM_Attack)) // Если атакующий находится в состоянии монстрячей атаки. Это не ГГ.
        {
            Npc_ClearAIQueue(self);
            Npc_SetTarget(self,victim);
            B_ClearPerceptions(self);
            AI_StartState(self,ZS_MM_Attack,0,""); // Атака жертвы. (!)
            return;
        };
        if(Npc_IsInState(other,ZS_MM_ThreatenEnemy))
        {
            AI_SetWalkMode(self,NPC_RUN);
            AI_GotoNpc(self,victim);
            return;
        };
    };

Думаю, происходит следующее. ГГ-волк атакует волка. Волк-спутник ГГ начинает атаковать атакованного ГлавГероем волка, то есть, переходит в режим монстрячей атаки. Волк-свидетель видит, что другой волк атакует кого-то и присоединяется к атаке. Нужно как-то ввести исключение, чтобы волк не реагировал на драку между другими волками, и ввести различие между волками и кабанами с помощью aivar[AIV_MM_REAL_ID].
 

Dimus

★★★★★★★★★
Супермодератор
Регистрация
19 Июл 2010
Сообщения
5.574
Благодарности
4.167
Баллы
915
Хорошо, проверю этот момент на молодых волках у перехода Хоринис - Миненталь, там как раз достаточно зверья, чтобы были жертвы и свидетели. А пока внёс кабанов в список исключений фишки "ГГ - вожак волчьей стаи".

Чтобы волки не реагировали на драку с другими волками, добавил дополнительные условия в функцию B_MM_AssessWarn():
Код:
    if((self.guild == other.guild) && (self.aivar[AIV_MM_Packhunter] == TRUE))
    {
        if(((self.guild == GIL_WOLF) && (self.aivar[AIV_MM_REAL_ID] != ID_Keiler) && (victim.guild == GIL_WOLF) && (victim.aivar[AIV_MM_REAL_ID] != ID_Keiler) && Npc_IsPlayer(victim)) || ((self.guild == GIL_WOLF) && (self.aivar[AIV_MM_REAL_ID] != ID_Keiler) && (victim.guild == GIL_WOLF) && (victim.aivar[AIV_MM_REAL_ID] != ID_Keiler) && (other.guild == GIL_WOLF) && (other.aivar[AIV_MM_REAL_ID] != ID_Keiler)))
        {
            return;
        };
        if(Npc_IsInState(other,ZS_MM_Attack))
        {
            Npc_ClearAIQueue(self);
            Npc_SetTarget(self,victim);
            B_ClearPerceptions(self);
            AI_StartState(self,ZS_MM_Attack,0,"");
            return;
        };
        if(Npc_IsInState(other,ZS_MM_ThreatenEnemy))
        {
            AI_SetWalkMode(self,NPC_RUN);
            AI_GotoNpc(self,victim);
            return;
        };
    };
P.S.: Вспомнил про высказанную в теме Gothic Mod Fix идею запрета нежити плавать вслед за ГГ. Может, лучше сделать как в G2: обычная нежить прекращает преследовать плывущего врага, а вызванная может плавать вслед за ГГ.
 
Последнее редактирование:

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.407
Благодарности
3.232
Баллы
525
Ещё один баг.
SkeletonMageTrouble.jpg

Проявляется он следующим образом. Неписи в состоянии магической атаки иногда зависают в попытке продвинуться вперёд и перестают реагировать на окружающих. Даже на повреждение не реагируют. Баг происходит, насколько я понимаю, при выполнении функции AI_Attack. Если маг не имеет прямой видимости с целью, движок предписывает ему эту видимость восстановить, то есть заставляет мага двигаться, проигрывать анимации перемещения. Вот здесь то и спряталась уязвимость.

Можно в качестве костыля изменить сценарий анимации движения, сняв зацикливание у состояния s_MagRunL в оверлее, накладываемом на мага:
aniAlias ("s_MagRunL" 1 "s_MagRunL" 0.0 0.0 M. "s_FistRunL" F)
aniAlias ("s_MagRunL" 1 "s_MagRun" 0.0 0.0 M. "s_FistRunL" F)

Но этот подход не слишком хорош. Есть побочные эффекты. Возможно, кто-то уже занимался этой проблемой. Есть ли какие-нибудь идеи, как исправить ситуацию?
 

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.407
Благодарности
3.232
Баллы
525
Вопрос, в первую, очередь к гуру, способным заглянуть в движок. Есть такая функция в скриптах InitPerceptions. Задаёт дальность работы пассивных восприятий. Но вот из скриптов эта функция не вызывается. Возможно, вызывается движком. Хотелось бы узнать, так ли это.

Пробовал изменять в ней расстояние одного восприятия (в Г1), но результат, как мне показалось, не меняется. Пробовал удалять функцию из скриптов - скрипты компилируются, игра запускается.
 

Gor

Участник форума
Регистрация
26 Дек 2009
Сообщения
977
Благодарности
546
Баллы
245
Я не гуру в Готике, но вызов этой функции в движке есть (gothicmod.exe)
Вот код на С++. На асме тебе не интересно я думаю.
Код:
void oCNpc::InitStatics() {
// инициализация NPC_ANGRY_TIME
zCPar_Symbol * psymbol = parser->GetSymbol(zSTRING("NPC_ANGRY_TIME"));
if(!psymbol) {
    int value;
    psymbol->GetValue(value, 0);
    NPC_ANGRY_TIME = (float) (value * 1000);
}
// инициализация percRange (массив из 33-ех float со значением 500.0)
for(int i = 0; i < 33; ++i ) 
    percRange[i] = 500.0;
// вызов функции INITPERCEPTIONS
int index = parser->GetIndex(zSTRING("INITPERCEPTIONS"));
if(index >= 0)
    parser->CallFunc(index);
else
    zerr->Report(2, 0, zSTRING(filepath), 0, 0, 0x38D3, errstr, 0);
// и так далее
oCNpc::InitFightAI();
...
}
char * errstr = "U: AI: Script-func InitPerceptions not found.";
char * filepath = "D:\dev\gothic\current_work\Gothic\_Ulf\oNPC.cpp";
 

ErikDK

Участник форума
Регистрация
11 Янв 2012
Сообщения
25
Благодарности
1
Баллы
165
Пробую научить гоблинов магии. Добавил им маны и дописал по примеру B_SelectSpell и C_NpcIsMonsterMage, но гоблины просто стоят и смотрят. Есть ещё какие то файлы, отвечающие за магию и требующие дописывания? Или может из-за отсутствия у гоблина соответствующей анимации он вообще не способен пользоваться рунами?
 

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.407
Благодарности
3.232
Баллы
525
Или может из-за отсутствия у гоблина соответствующей анимации он вообще не способен пользоваться рунами?
Да, у гоблина просто нет кучи анимаций, которые нужны для каста заклинаний, активации и деактивации заклинаний и перемещения с активированным заклинанием. Кроме этого, гильдии гоблинов, как и многим монстрячим гильдиям, в движке, по всей видимости, запрещена смена боевого режима.
 

Kreol Nekr

Участник форума
Регистрация
21 Ноя 2014
Сообщения
229
Благодарности
109
Баллы
190
Почему то у меня пишет " Неизвестный идентификатор" else в последней строке диалога при компиляции. Возможно добавленные функции нужно еще где то менять?

Добрый день! Вопрос такой возник, писал уже где то в другой теме, не помню где. Мне нужны константы на различные действия НПС, кто то может мне их дать?
И второе В данном случае мне необходимо прописать НПС действие использования руны телепорта, не могу найти константу данного действия:

instance DIA_None_103_Skorpio_TP(C_Info)
{
npc = none_103_skorpio;
nr = 2;
condition = DIA_None_103_Skorpio_TP_condition;
information = DIA_None_103_Skorpio_TP_info;
permanent = FALSE;
important = TRUE;
};


func int DIA_None_103_Skorpio_TP_condition()
{
if ((MIS_Skorpio == LOG_Running) && Hlp_StrCmp(Npc_GetNearestWP(self),"OC_MAGE_CENTER"))
{
return TRUE;
};
};

func void DIA_None_103_Skorpio_TP_info()
{
AI_Output(self,other,"DIA_None_103_Skorpio_TP_05_00"); //Отлично! У нас получилось! Ну ладно, времени у нас немного, покуда стража не заметила меня надо рвать когти. Пока, увидимся у прохода.
B_LogEntry(TOPIC_SKORPIO,"Кажется нам удалось миновать посты охраны в лагере, теперь медлить нельзя!");
AI_Output(other,self,"DIA_None_103_Skorpio_TP_15_01"); //Удачи, Скорпио!
AI_StopProcessInfos(self);

};
Подскажите, пожалуйста, что нужно написать.
 
Последнее редактирование модератором:

Vlad_Torop

Участник форума
Регистрация
2 Май 2014
Сообщения
870
Благодарности
499
Баллы
230
Мне нужны константы на различные действия НПС, кто то может мне их дать?
Не существует такого понятия как "константы на различные действия НПС".Есть функции работы с миром.Дать их может урок VAMа(если хорошо попросить:))
необходимо прописать НПС действие использования руны телепорта
Вообще,для того что бы НПС использовал предмет,находящийся у него в "рюкзаке" используется функция B_UseItem(self,инстанция предмета);.
И в зависимости от того,что прописано в scemeName в инстанции этого предмета,то НПС и будет делать(есть,пить,смотреть и тд)
Но в случае с рунами такой метод не прокатит.В твоем случае нужно просто телепортировать НПС с помощью функции AI_Teleport(Npc,"WP");.Но,что бы не было глюков,действовать надо через дополнительный выбор ответа,типа "конец".В твоем случае оконцовка будет примерно такая :
Код:
func void DIA_None_103_Skorpio_TP_info()
{
    AI_Output(self,other,"DIA_None_103_Skorpio_TP_05_00"); //Отлично! У нас получилось! Ну ладно, времени у     нас немного, покуда стража не заметила меня надо рвать когти. Пока, увидимся у прохода.
    B_LogEntry(TOPIC_SKORPIO,"Кажется нам удалось миновать посты охраны в лагере, теперь медлить            нельзя!");
    AI_Output(other,self,"DIA_None_103_Skorpio_TP_15_01"); //Удачи, Скорпио!
    Info_AddChoice(DIA_None_103_Skorpio_TP,"конец",DIA_None_103_Skorpio_TP_end);
};
func void DIA_None_103_Skorpio_TP_end()
{
    AI_StopProcessInfos(self);
    AI_Teleport(self,"НАЗВАНИЕ ВЕЙПОЙНТА");
};
 
Последнее редактирование:

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.407
Благодарности
3.232
Баллы
525
Мне нужны константы на различные действия НПС, кто то может мне их дать?
Об чём речь? Может, кто и подскажет чего, но объясни подробнее, что тебе нужно.

мне необходимо прописать НПС действие использования руны телепорта
Напрямую непись не сможет использовать руну телепорта, насколько я знаю. Но можно имитировать этот процесс с помощью проигрывания анимации и визуального эффекта. И в инстанции диалога такое не сделаешь, нужно создавать особое ZS-состояние для этого.
 

Kreol Nekr

Участник форума
Регистрация
21 Ноя 2014
Сообщения
229
Благодарности
109
Баллы
190
Не существует такого понятия как "константы на различные действия НПС".Есть функции работы с миром.Дать их может урок VAMа(если хорошо попросить:))

Вообще,для того что бы НПС использовал предмет,находящийся у него в "рюкзаке" используется функция B_UseItem(self,инстанция предмета);.
И в зависимости от того,что прописано в scemeName в инстанции этого предмета,то НПС и будет делать(есть,пить,смотреть и тд)
Но в случае с рунами такой метод не прокатит.В твоем случае нужно просто телепортировать НПС с помощью функции AI_Teleport(Npc,"WP");.Но,что бы не было глюков,действовать надо через дополнительный выбор ответа,типа "конец".В твоем случае оконцовка будет примерно такая :
Код:
func void DIA_None_103_Skorpio_TP_info()
{
    AI_Output(self,other,"DIA_None_103_Skorpio_TP_05_00"); //Отлично! У нас получилось! Ну ладно, времени у     нас немного, покуда стража не заметила меня надо рвать когти. Пока, увидимся у прохода.
    B_LogEntry(TOPIC_SKORPIO,"Кажется нам удалось миновать посты охраны в лагере, теперь медлить            нельзя!");
    AI_Output(other,self,"DIA_None_103_Skorpio_TP_15_01"); //Удачи, Скорпио!
    Info_AddChoice(DIA_None_103_Skorpio_TP,"конец",DIA_None_103_Skorpio_TP_end);
};
func void DIA_None_103_Skorpio_TP_end()
{
    AI_StopProcessInfos(self);
    AI_Teleport(self,"НАЗВАНИЕ ВЕЙПОЙНТА");
};
Благодарю Вас. Извините, если не точно выразился, мои познания в области скриптологии весьма скудны. Поэтому могу не достаточно точно оперировать понятиями. Но вот список функций видимо придется составлять самому методом тыка, я нашел в одном месте документ, но там без пол литра не разберешься. нету конкретики в нем. А что касается уроков, то я понятия не имею у кого и что просить, ибо я тут вообще второй день и никого не знаю.
 

cool_er

Участник форума
Регистрация
23 Мар 2015
Сообщения
118
Благодарности
42
Баллы
190
Благодарю Вас. Извините, если не точно выразился, мои познания в области скриптологии весьма скудны. Поэтому могу не достаточно точно оперировать понятиями. Но вот список функций видимо придется составлять самому методом тыка, я нашел в одном месте документ, но там без пол литра не разберешься. нету конкретики в нем. А что касается уроков, то я понятия не имею у кого и что просить, ибо я тут вообще второй день и никого не знаю.
Ну про уроки, я думаю вот это имелось в виду https://worldofplayers.ru/threads/37749/. Там-же есть функции для действий, вида "TA_ДействиеБезПриставкиZS_". Посмотреть доступные действия можно в "AI\Human\TA_Human"(если это касается распорядка дня НПС), а насчет действий во время диалога надо почитать в туториале, ибо я уже моддингом к готике не занимаюсь и некоторые(многие) моменты забыл. Во всяком случае - обращайся - поможем чем сможем.
tl;dr:Просто пройди по ссылке которую я указал выше и почитай.
 

Kreol Nekr

Участник форума
Регистрация
21 Ноя 2014
Сообщения
229
Благодарности
109
Баллы
190
Об чём речь? Может, кто и подскажет чего, но объясни подробнее, что тебе нужно.


Напрямую непись не сможет использовать руну телепорта, насколько я знаю. Но можно имитировать этот процесс с помощью проигрывания анимации и визуального эффекта. И в инстанции диалога такое не сделаешь, нужно создавать особое ZS-состояние для этого.
Спасибо, мне написали тут способ, я попробовал получилось, анимацию вставлю, эффект наложу. Насчет ZS-состояния я ничего не понял не владею сим знанием))) Но в диалоге это сделалось по методике изложенной выше. Вы мне скажите еще вот что: Может ли НПС переместиться в другую локацию или нужно там создавать его дублера?

Ну про уроки, я думаю вот это имелось в виду https://worldofplayers.ru/threads/37749/. Там-же есть функции для действий, вида "TA_ДействиеБезПриставкиZS_". Посмотреть доступные действия можно в "AI\Human\TA_Human"(если это касается распорядка дня НПС), а насчет действий во время диалога надо почитать в туториале, ибо я уже моддингом к готике не занимаюсь и некоторые(многие) моменты забыл. Во всяком случае - обращайся - поможем чем сможем.
tl;dr:Просто пройди по ссылке которую я указал выше и почитай.
Ясно хорошо!
 

Митяй

Почетный форумчанин
Регистрация
13 Авг 2010
Сообщения
14.336
Благодарности
6.144
Баллы
1.360
Даблпостинг запрещен. Сообщения объединил. Устное предупреждение на первый раз.
 
Последнее редактирование:

Vlad_Torop

Участник форума
Регистрация
2 Май 2014
Сообщения
870
Благодарности
499
Баллы
230
Может ли НПС переместиться в другую локацию или нужно там создавать его дублера?
Только клоны.Пример из оригинальных скриптов: Горн(pc_fighter_di.d, pc_fighter_djg.d,....),Диего(pc_thief_di.d, pc_thief_nw.d,.....).
PS И прекращай вот с этим:"Благодарю Вас. Извините, если не точно выразился,"
Мы здесь все простые,и очень душевные,не как вот этот --> :mad:.
 
Последнее редактирование:

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.407
Благодарности
3.232
Баллы
525
Но в диалоге это сделалось по методике изложенной выше.
Когда телепорт использует ГГ, то существует определённая последовательность событий (старт анимации, старт визуального и звукового эффектов, собственно телепортация). При телепортации из инстанции диалога непись на такие мелочи не заморачивается. Если наложишь эффекты, то правильная последовательность событий не гарантирована.

Насчет ZS-состояния я ничего не понял не владею сим знанием)))
ZS-состояние может содержать три функции - стартовую, циклическую и финальную. С помощью циклической части состояния можно отмерять интервалы времени и контролировать факт происхождения какого-нибудь события. Это то, что может быть полезным в данном случае.

Может ли НПС переместиться в другую локацию или нужно там создавать его дублера?
Дублёр рулит.
 

Kreol Nekr

Участник форума
Регистрация
21 Ноя 2014
Сообщения
229
Благодарности
109
Баллы
190
Когда телепорт использует ГГ, то существует определённая последовательность событий (старт анимации, старт визуального и звукового эффектов, собственно телепортация). При телепортации из инстанции диалога непись на такие мелочи не заморачивается. Если наложишь эффекты, то правильная последовательность событий не гарантирована.


ZS-состояние может содержать три функции - стартовую, циклическую и финальную. С помощью циклической части состояния можно отмерять интервалы времени и контролировать факт происхождения какого-нибудь события. Это то, что может быть полезным в данном случае.


Дублёр рулит.

Ладно. С клонами понятно, Но, куда девать оригинального НПС тогда? это первый вопрос. И второй: Может ли НПС переместиться в другую локацию, если ему написать Npc_ExchangeRoutine(self,"TOT"); ТОТ- это вайпоинт за частоколом орков в пещере, где бывало находился труп Диего.
Обьясню, что хочу сделать. Я хочу убрать двух НПС из башни Ксардаса в 5 ой главе. Я им написал следующее:


func int dia_none_102_kreol_Kap5_condition()
{
if(Kapitel == 5)
{
return TRUE;
};
};

func void dia_none_102_kreol_Kap5_info()
{
AI_StopProcessInfos(self);
Npc_ExchangeRoutine(self,"TOT");

};
Но они как стояли в башне, так и стоят, вернее кое кто им не дает просто стоять ))) и они вынуждены сопротивляться)
Ну, а Ксардас преспокойно телепортируется куда то... Его диалог пересмотрел 5 раз никаких функций, для перемещения или изменения распорядка не увидел. Напишите, что добавить и куда. Только по проще. Без всяких там ZS состояний и т п...)))
 

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.407
Благодарности
3.232
Баллы
525
Но, куда девать оригинального НПС тогда?
В "морг". Главное, правильно избрать способ отправки. Обычно это делается (изменяется распорядок у отправляемого в "морг" непися) в функции инициализации локации, которая вызывается каждый раз при вхождении в локацию или загрузке сохранения в ней. Чтобы не писать много букаф, посмотри, как это сделано с Диего, Горном, Мильтеном и т. д. в скриптах Г2.

Но они как стояли в башне, так и стоят
В твоём примере изменяется распорядок непися-владельца диалога. Но после состоявшегося диалога (реализация крайне неудачная) непись никуда не пойдёт, если к точке выполнения нового распорядка не ведут линии путевой сетки. Непись может быть телепортирован туда движким после отдаления от него на определённое расстояние.
 

Kreol Nekr

Участник форума
Регистрация
21 Ноя 2014
Сообщения
229
Благодарности
109
Баллы
190
В "морг". Главное, правильно избрать способ отправки. Обычно это делается (изменяется распорядок у отправляемого в "морг" непися) в функции инициализации локации, которая вызывается каждый раз при вхождении в локацию или загрузке сохранения в ней. Чтобы не писать много букаф, посмотри, как это сделано с Диего, Горном, Мильтеном и т. д. в скриптах Г2.


В твоём примере изменяется распорядок непися-владельца диалога. Но после состоявшегося диалога (реализация крайне неудачная) непись никуда не пойдёт, если к точке выполнения нового распорядка не ведут линии путевой сетки. Непись может быть телепортирован туда движким после отдаления от него на определённое расстояние.

Ладно, с удалением НПС из локации как нибудь разберусь может быть, но вот так и не понял я, что делать мне с теми двумя, которые в башне у Ксардаса остались, вы можете мне написать, то, что там должно быть по вашему мнению. Так я все равно ничего не пойму.
 
Сверху Снизу