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

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

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

Не стесняюсь спросить....

cool_er

Участник форума
Регистрация
23 Мар 2015
Сообщения
118
Благодарности
42
Баллы
190
Почему об этом никто слова не описал в справке?
Потому что это справка - а не "как создать Лебедеву мод".
Лень мозгами подумать.
Я думаю ты это про себя?

Вы просили продолжение распорядка для НПС? Мы тебе показали. Любые претензии уже к твоей реализации, которую мы не увидели.
 

Лебедев

Участник форума
Регистрация
3 Сен 2005
Сообщения
595
Благодарности
77
Баллы
225
Потому что это справка - а не "как создать Лебедеву мод".

Я думаю ты это про себя?

Вы просили продолжение распорядка для НПС? Мы тебе показали. Любые претензии уже к твоей реализации, которую мы не увидели.

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

Сейчас тебе специально сырую сборку соберу и вышлю.
 

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.371
Благодарности
7.803
Баллы
995

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.339
Благодарности
3.183
Баллы
525
AI_ContinueRoutine - не продолжает анимацию, а её по новой запускает. (действия вызываемые командой из справки отличаются от написанного в справке)
Npc_ExchangeRoutine - продолжает анимацию.

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

В инстанциях диалогов для непися-владельца диалога можно использовать Npc_ExchangeRoutine. По окончании диалога напись приступит к выполнению нового распорядка. Для третьих лиц нужно использовать связку Npc_ExchangeRoutine и AI_ContinueRoutine или скриптовую функцию, где эта связка уже присутствует.
 

Лебедев

Участник форума
Регистрация
3 Сен 2005
Сообщения
595
Благодарности
77
Баллы
225
Эмм, не понял, о какой анимации речь.
AI_ContinueRoutine - непись продолжит (или начнёт) выполнение назначенного ему распорядка.
Npc_ExchangeRoutine - один распорядок заменится другим, но выполнение этого другого распорядка начнётся только после того, как непись будет проинициализирован или поступит команда AI_ContinueRoutine.

В инстанциях диалогов для непися-владельца диалога можно использовать Npc_ExchangeRoutine. По окончании диалога напись приступит к выполнению нового распорядка. Для третьих лиц нужно использовать связку Npc_ExchangeRoutine и AI_ContinueRoutine или скриптовую функцию, где эта связка уже присутствует.

Пример: Bau_900_Onar.d

Анимация TA_Sit_Throne

Если пишем AI_ContinueRoutine(Bau_900_Onar); - при подряд втором вызове диалога получаем не успевание игры закончить прошлую анимацию и из диалога не выходит игра.
Если пишем Npc_ExchangeRoutine(Bau_900_Onar,"START"); - игра при любом вызове диалога успевает выходить из диалога, но анимация получается рваной.
Если пишем AI_ContinueRoutine(self); - пока анимация не будет проиграна вызов нового диалога не возможен.
Если пишем Npc_ExchangeRoutine(self,"START"); - вызов диалога в любой момент возможен и не ограничен. Анимация полностью работает. Продолжается и по новой запускается.

Всё писалось после указанного места:

instance DIA_Onar_EXIT(C_Info)
{
npc = Bau_900_Onar;
nr = 999;
condition = DIA_Onar_EXIT_Condition;
information = DIA_Onar_EXIT_Info;
permanent = TRUE;
description = Dialog_Ende;
};


func int DIA_Onar_EXIT_Condition()
{
return TRUE;
};

func void DIA_Onar_EXIT_Info()
{
AI_StopProcessInfos(self);
};
 

cool_er

Участник форума
Регистрация
23 Мар 2015
Сообщения
118
Благодарности
42
Баллы
190
Попрошу Вас не оскорблять меня.
AI_ContinueRoutine - не продолжает анимацию, а её по новой запускает. (действия вызываемые командой из справки отличаются от написанного в справке)
Npc_ExchangeRoutine - продолжает анимацию.

Сейчас тебе специально сырую сборку соберу и вышлю.
Прошу простить. Просто с утра таким злым проснулся (соседи целую ночь музыку слушали, но сегодня так на них наорал что наверно они меня будут смотреть как на психа).
cool_er,

Эмм, ты попал, "как кур во щи", сейчас тебе вышлют, а завтра к тебе выедут.. *lol*
А через полгода в списке авторов мода Лебедева будет числится моё имя? *trollface*
 

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.371
Благодарности
7.803
Баллы
995

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.339
Благодарности
3.183
Баллы
525
Всё писалось после указанного места:
А зачем вообще лезть в это "указанное место"? Не, в особых случаях тут, конечно, можно что-то приписать. Сам пару раз так делал. Но уверен ли ты, что твой случай особенный?

Если пишем AI_ContinueRoutine(Bau_900_Onar); - при подряд втором вызове диалога получаем не успевание игры закончить прошлую анимацию и из диалога не выходит игра.
А если вообще ничего не писать? Этот баг тоже имеет место?
 

Лебедев

Участник форума
Регистрация
3 Сен 2005
Сообщения
595
Благодарности
77
Баллы
225
А зачем вообще лезть в это "указанное место"? Не, в особых случаях тут, конечно, можно что-то приписать. Сам пару раз так делал. Но уверен ли ты, что твой случай особенный?


А если вообще ничего не писать? Этот баг тоже имеет место?

Если ставить выше AI_StopProcessInfos(self); у Вас не будет завершаться диалог.
Если совсем ничего не писать имеем NPC который таращится на ГГ пока ГГ из его диапазона чувств не пропадёт.

А если ГГ не принадлежит определённой гильдии которая в данном помещении прописана, любой распорядок дня автоматически блокируется и NPC переходит в режим наблюдения за ГГ.

А любая AI_StopProcessInfos(self); следующая в других instance после EXIT-instance диалога автоматически проходит через EXIT-instance диалог. (И не нужно костылей использовать, Пираньи всё заложили заранее)

До всех подробностей Vam не добирался. А вот мододелы данного ресурса должны были за 10 лет всё разобрать.
 

Defman

Участник форума
Регистрация
26 Май 2013
Сообщения
3.165
Благодарности
245
Баллы
300

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.339
Благодарности
3.183
Баллы
525
Если совсем ничего не писать имеем NPC который таращится на ГГ пока ГГ из его диапазона чувств не пропадёт.

Добрался до компа, посмотрел поведение Онара в оригинале. Ничего не глючит. Даже если повторный диалог инициировать сразу же, пока он не успел сесть, анимация не прерывается, он садится, но диалог не подвисает. И на ГГ он НЕ ТАРАЩИТСЯ. Если у тебя не так, ищи отличие своих скриптов от оригинала.

А если ГГ не принадлежит определённой гильдии которая в данном помещении прописана, любой распорядок дня автоматически блокируется и NPC переходит в режим наблюдения за ГГ.

Про это уже написали тебе. Это вполне естественное поведение. Если ГГ забрёл в чужое помещение, то за ним наблюдают, кабы чего не стащил.
 

Лебедев

Участник форума
Регистрация
3 Сен 2005
Сообщения
595
Благодарности
77
Баллы
225
Добрался до компа, посмотрел поведение Онара в оригинале. Ничего не глючит. Даже если повторный диалог инициировать сразу же, пока он не успел сесть, анимация не прерывается, он садится, но диалог не подвисает. И на ГГ он НЕ ТАРАЩИТСЯ. Если у тебя не так, ищи отличие своих скриптов от оригинала.



Про это уже написали тебе. Это вполне естественное поведение. Если ГГ забрёл в чужое помещение, то за ним наблюдают, кабы чего не стащил.

пропиши так
AI_ContinueRoutine(Bau_900_Onar);
AI_StopProcessInfos(self);
и посмотри пожалуйста результат

и пропиши так
AI_ContinueRoutine(self);
AI_StopProcessInfos(self);
и посмотри пожалуйста результат

и пропиши так
AI_StopProcessInfos(self);
AI_ContinueRoutine(self);
и посмотри пожалуйста результат

и пропиши так
AI_StopProcessInfos(self);
AI_ContinueRoutine(Bau_900_Onar);
и посмотри пожалуйста результат

Пример почему после AI_StopProcessInfos(self); ставлю можно увидеть в файлах диалогах Ночи Ворона NPC.

А также VLK_427_Buergerin у Боспера гражданка почему до разговора с ней (она жарит мясо), когда её спрашиваешь и EXIT выбираешь, но она продолжает смотреть на ГГ? (хотя достаточно одного Боспера, чтобы за ГГ смотреть. А её задача продолжать распорядок дня т.е. жарку мяса)

Да он не таращится, просто головой за ГГ вертит.

Еще пережевать и вам в рот положить? г-н Лебедев, вам НИКТО ничего не должен. Подобного рода работа - чистый энтузиазм.

Да на данном форуме существую только я. Спасибо за ваши слова.

Вот Вам видео из сырой версии, как у меня работает:
http://my.mail.ru/inbox/nabor2014/video/_myvideo/7.html
Без всяких костылей, достаточно обычных скриптов.
 
Последнее редактирование:

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.339
Благодарности
3.183
Баллы
525
Во-первых, я не занимаюсь моддингом Г2, во-вторых, помощь, как я наивно полагал, нужна тебе, а не мне... Оно мне нужно? ;)

К тому же, твой способ имеет существенный изъян. Многие диалоги завершаются не через EXIT-инстацию.

А также VLK_427_Buergerin у Боспера гражданка почему до разговора с ней (она жарит мясо), когда её спрашиваешь и EXIT выбираешь, но она продолжает смотреть на ГГ?

Вчера по ряду причин перепутал и протестил не Онара, а Секоба. Сегодня протестил и Онара, и указанную дамочку. Оба непися переходят в состояние ZS_ObservePlayer, как и предусмотрено скриптами и авторской задумкой. Можешь, как тебе советовали, отключить переход в это состояние в функции ZS_Talk_End. А можешь и поправить состояние ZS_ObservePlayer так, как считаешь нужным. Вот это будет ПРАВИЛЬНЫЙ подход.

Код:
func int ZS_ObservePlayer_Loop()
{
   if(C_BodyStateContains(other,BS_SNEAK) && (Player_SneakerComment == FALSE))
   {
     Player_SneakerComment = TRUE;
     AI_PointAtNpc(self,other);
     B_Say(self,other,"$WHATSTHISSUPPOSEDTOBE");
     AI_StopPointAt(self);
     Npc_SendPassivePerc(self,PERC_ASSESSWARN,self,other);
   };

// Задание рандомного таймера 1-3 секунды
   if(Npc_GetStateTime(self) > self.aivar[AIV_StateTime])
   {
     if(!C_BodyStateContains(self,BS_SIT))
     {
       B_TurnToNpc(self,other);
     };
     self.aivar[AIV_StateTime] = Hlp_Random(2) + 1;
     Npc_SetStateTime(self,0);
   };

// Условие выхода из состояния
   if(Npc_GetDistToNpc(self,other) > PERC_DIST_INTERMEDIAT)
   {
     Npc_ClearAIQueue(self);
     return LOOP_END;
   }
   else
   {
     return LOOP_CONTINUE;
   };
};

Можешь поставить выход из состояния после первого же цикла. Можешь организовать счётчик циклов в секции с установкой таймера и заканчивать состояние через 2-3 цикла (2-9 секунд). Можешь изменить расстояние между неписем и ГГ, на котором происходит выход (PERC_DIST_INTERMEDIAT = 1000). Можешь ввести в условие выхода проверку видит ли непись ГГ (Npc_CanSeeNpcFreeLOS), иначе ГГ может уйти за стену, а непись будет смотреть на него сквозь стену. Можешь учесть ещё что-то или комбинировать названные факторы... ;)
 

Лебедев

Участник форума
Регистрация
3 Сен 2005
Сообщения
595
Благодарности
77
Баллы
225
Написать расписание "Жарки для Нпс", которое активируется после передачи жареного мяса, нет ?!

У меня более проще реализовано. Используются NPC которые всегда в игре жарят мясо, для жарки от 10 до 100 кусков мяса сразу (за деньги) и не нужно переделывать все плиты в игре.

Ответ в твоем же вопросе: Если есть шаманы у Орков.., то что мешает тебе посмотреть что для них используется и сделать по аналогии с ними?
Если Гоблинец не может пользоваться магией из-за ограничений движка, то пробуем прописать ему гильдию Орка или Человека, либо править через костыли..

Гоблинам блокирована магия т.к. достаточно гоблину добавить магию и он зависает на месте. (даже если прописать гильдию орка)

Во-первых, я не занимаюсь моддингом Г2, во-вторых, помощь, как я наивно полагал, нужна тебе, а не мне... Оно мне нужно? ;)

К тому же, твой способ имеет существенный изъян. Многие диалоги завершаются не через EXIT-инстацию.



Вчера по ряду причин перепутал и протестил не Онара, а Секоба. Сегодня протестил и Онара, и указанную дамочку. Оба непися переходят в состояние ZS_ObservePlayer, как и предусмотрено скриптами и авторской задумкой. Можешь, как тебе советовали, отключить переход в это состояние в функции ZS_Talk_End. А можешь и поправить состояние ZS_ObservePlayer так, как считаешь нужным. Вот это будет ПРАВИЛЬНЫЙ подход.

Код:
func int ZS_ObservePlayer_Loop()
{
   if(C_BodyStateContains(other,BS_SNEAK) && (Player_SneakerComment == FALSE))
   {
     Player_SneakerComment = TRUE;
     AI_PointAtNpc(self,other);
     B_Say(self,other,"$WHATSTHISSUPPOSEDTOBE");
     AI_StopPointAt(self);
     Npc_SendPassivePerc(self,PERC_ASSESSWARN,self,other);
   };

// Задание рандомного таймера 1-3 секунды
   if(Npc_GetStateTime(self) > self.aivar[AIV_StateTime])
   {
     if(!C_BodyStateContains(self,BS_SIT))
     {
       B_TurnToNpc(self,other);
     };
     self.aivar[AIV_StateTime] = Hlp_Random(2) + 1;
     Npc_SetStateTime(self,0);
   };

// Условие выхода из состояния
   if(Npc_GetDistToNpc(self,other) > PERC_DIST_INTERMEDIAT)
   {
     Npc_ClearAIQueue(self);
     return LOOP_END;
   }
   else
   {
     return LOOP_CONTINUE;
   };
};

Можешь поставить выход из состояния после первого же цикла. Можешь организовать счётчик циклов в секции с установкой таймера и заканчивать состояние через 2-3 цикла (2-9 секунд). Можешь изменить расстояние между неписем и ГГ, на котором происходит выход (PERC_DIST_INTERMEDIAT = 1000). Можешь ввести в условие выхода проверку видит ли непись ГГ (Npc_CanSeeNpcFreeLOS), иначе ГГ может уйти за стену, а непись будет смотреть на него сквозь стену. Можешь учесть ещё что-то или комбинировать названные факторы... ;)

Большое спасибо, Ваш вариант (Npc_CanSeeNpcFreeLOS) уже используется.
Т.к. в стандартной готике наблюдается: ГГ уходит за стену, а NPC продолжает смотреть на ГГ сквозь стену.

Более правильный вариант: объединение вашего варианта и моего т.к. каждый правит только свою часть. А нужно 99% вариантов поведений, чтобы было исправлено.

P.S. Я не против помощи, мною проверились все возможные варианты постановки кода и до этого были указаны 4 варианта при которых случаются наибольшее число глюков. (хотя в справке Vam было указано, что AI_ContinueRoutine панацея от всех бед. Но AI_ContinueRoutine в Exit-instance ведёт себя по другому, чем описал Vam. Значит Vam всем дал основы, остальное узнавайте сами, что я и делаю.)
 
Последнее редактирование:

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.371
Благодарности
7.803
Баллы
995
У меня более проще реализовано. Используются NPC которые всегда в игре жарят мясо, для жарки от 10 до 100 кусков мяса сразу (за деньги) и не нужно переделывать все плиты в игре.
А кто говорил про переделку плит?

Гоблинам блокирована магия т.к. достаточно гоблину добавить магию и он зависает на месте. (даже если прописать гильдию орка)
Читать нужно до конца, а не то что хочется..

хотя в справке Vam было указано, что AI_ContinueRoutine панацея от всех бед. Но AI_ContinueRoutine в Exit-instance ведёт себя по другому, чем описал Vam. Значит Vam всем дал основы, остальное узнавайте сами, что я и делаю.
Ну вот потом распишешь тутор для остальных, что сам понял что другие подсказали по этой части, думаю народу будет полезно.. *peace*
 

Лебедев

Участник форума
Регистрация
3 Сен 2005
Сообщения
595
Благодарности
77
Баллы
225
Доброй ночи. Кто-то может пояснить. Добавлен волкодав в Хоринисе работает, в Минентале не отслеживает NPC к которым привязан, к Яркендаре вовсе пропадает.

func void zs_mm_rtn_kosfollow()
{
Perception_Set_Monster_Rtn();
Npc_ClearAIQueue(self);
Npc_SetPercTime(self,1);
Perception_Set_Monster_Rtn();
Npc_PercEnable(self,PERC_ASSESSPLAYER,B_MM_AssessPlayer);
Npc_PercEnable(self,PERC_ASSESSENEMY,B_MM_AssessEnemy);
Npc_PercEnable(self,PERC_ASSESSMAGIC,B_AssessMagic);
Npc_PercEnable(self,PERC_ASSESSDAMAGE,B_MM_AssessDamage);
Npc_PercEnable(self,PERC_ASSESSFIGHTSOUND,B_MM_AssessOthersDamage);
Npc_PercEnable(self,PERC_ASSESSTALK,B_AssessTalk);
B_SetAttitude(self,ATT_FRIENDLY);
AI_Standup(self);
AI_SetWalkMode(self,NPC_RUN);
B_MM_DeSynchronize();
};

func int zs_mm_rtn_kosfollow_loop()
{
var int randomMove;
if(S12 == 0)
{
if(Npc_GetDistToWP(a_nap_001,"NAP_003") > 500)
{
if(Npc_GetDistToNpc(self,a_nap_001) > 500)
{
AI_GotoNpc(self,a_nap_001);
}
else
{
AI_TurnToNPC(self,a_nap_001);
self.wp = Npc_GetNearestWP(self);
};
}
else
{
randomMove = Hlp_Random(3);
if(randomMove == 0)
{
AI_PlayAni(self,"R_ROAM1");
};
if(randomMove == 1)
{
AI_PlayAni(self,"R_ROAM2");
};
if(randomMove == 2)
{
AI_PlayAni(self,"R_ROAM3");
};
};
return LOOP_CONTINUE;
};
if(S12 == 1)
{
if(self.aivar[AIV_PARTYMEMBER] == TRUE)
{
if(Npc_GetDistToWP(hero,"NAP_003") > 500)
{
if(Npc_GetDistToNpc(self,hero) > 500)
{
AI_GotoNpc(self,hero);
}
else
{
AI_TurnToNPC(self,hero);
self.wp = Npc_GetNearestWP(self);
};
}
else
{
randomMove = Hlp_Random(3);
if(randomMove == 0)
{
AI_PlayAni(self,"R_ROAM1");
};
if(randomMove == 1)
{
AI_PlayAni(self,"R_ROAM2");
};
if(randomMove == 2)
{
AI_PlayAni(self,"R_ROAM3");
};
};
};
return LOOP_CONTINUE;
};
};

func void zs_mm_rtn_kosfollow_end()
{
};

func void zs_mm_rtn_kosfollow1()
{
Perception_Set_Monster_Rtn();
Npc_ClearAIQueue(self);
Npc_SetPercTime(self,1);
Perception_Set_Monster_Rtn();
Npc_PercEnable(self,PERC_ASSESSPLAYER,B_MM_AssessPlayer);
Npc_PercEnable(self,PERC_ASSESSENEMY,B_MM_AssessEnemy);
Npc_PercEnable(self,PERC_ASSESSMAGIC,B_AssessMagic);
Npc_PercEnable(self,PERC_ASSESSDAMAGE,B_MM_AssessDamage);
Npc_PercEnable(self,PERC_ASSESSFIGHTSOUND,B_MM_AssessOthersDamage);
Npc_PercEnable(self,PERC_ASSESSTALK,B_AssessTalk);
B_SetAttitude(self,ATT_FRIENDLY);
AI_Standup(self);
AI_SetWalkMode(self,NPC_RUN);
B_MM_DeSynchronize();
};

func int zs_mm_rtn_kosfollow_loop1()
{
var int randomMove1;
if(S13 == 0)
{
if(Npc_GetDistToNpc(self,a_nap_002o) > 500)
{
AI_GotoNpc(self,a_nap_002o);
}
else
{
AI_TurnToNPC(self,a_nap_002o);
self.wp = Npc_GetNearestWP(self);
};
}
else
{
randomMove1 = Hlp_Random(3);
if(randomMove1 == 0)
{
AI_PlayAni(self,"R_ROAM1");
};
if(randomMove1 == 1)
{
AI_PlayAni(self,"R_ROAM2");
};
if(randomMove1 == 2)
{
AI_PlayAni(self,"R_ROAM3");
};
};
return LOOP_CONTINUE;
if(S13 == 1)
{
if(self.aivar[AIV_PARTYMEMBER] == TRUE)
{
if(Npc_GetDistToNpc(self,hero) > 500)
{
AI_GotoNpc(self,hero);
}
else
{
AI_TurnToNPC(self,hero);
self.wp = Npc_GetNearestWP(self);
};
}
else
{
randomMove1 = Hlp_Random(3);
if(randomMove1 == 0)
{
AI_PlayAni(self,"R_ROAM1");
};
if(randomMove1 == 1)
{
AI_PlayAni(self,"R_ROAM2");
};
if(randomMove1 == 2)
{
AI_PlayAni(self,"R_ROAM3");
};
};
return LOOP_CONTINUE;
};
};

func void zs_mm_rtn_kosfollow_end1()
{
};

func void zs_mm_rtn_kosfollow2()
{
Perception_Set_Monster_Rtn();
Npc_ClearAIQueue(self);
Npc_SetPercTime(self,1);
Perception_Set_Monster_Rtn();
Npc_PercEnable(self,PERC_ASSESSPLAYER,B_MM_AssessPlayer);
Npc_PercEnable(self,PERC_ASSESSENEMY,B_MM_AssessEnemy);
Npc_PercEnable(self,PERC_ASSESSMAGIC,B_AssessMagic);
Npc_PercEnable(self,PERC_ASSESSDAMAGE,B_MM_AssessDamage);
Npc_PercEnable(self,PERC_ASSESSFIGHTSOUND,B_MM_AssessOthersDamage);
Npc_PercEnable(self,PERC_ASSESSTALK,B_AssessTalk);
B_SetAttitude(self,ATT_FRIENDLY);
AI_Standup(self);
AI_SetWalkMode(self,NPC_RUN);
B_MM_DeSynchronize();
};

func int zs_mm_rtn_kosfollow_loop2()
{
var int randomMove2;
if(S14 == 0)
{
if(Npc_GetDistToWP(a_nap_002a,"BOBIKA") > 500)
{
if(Npc_GetDistToNpc(self,a_nap_002a) > 500)
{
AI_GotoNpc(self,a_nap_002a);
}
else
{
AI_TurnToNPC(self,a_nap_002a);
self.wp = Npc_GetNearestWP(self);
};
}
else
{
randomMove2 = Hlp_Random(3);
if(randomMove2 == 0)
{
AI_PlayAni(self,"R_ROAM1");
};
if(randomMove2 == 1)
{
AI_PlayAni(self,"R_ROAM2");
};
if(randomMove2 == 2)
{
AI_PlayAni(self,"R_ROAM3");
};
};
return LOOP_CONTINUE;
};
if(S14 == 1)
{
if(self.aivar[AIV_PARTYMEMBER] == TRUE)
{
if(Npc_GetDistToWP(hero,"BOBIKA") > 500)
{
if(Npc_GetDistToNpc(self,hero) > 500)
{
AI_GotoNpc(self,hero);
}
else
{
AI_TurnToNPC(self,hero);
self.wp = Npc_GetNearestWP(self);
};
}
else
{
randomMove2 = Hlp_Random(3);
if(randomMove2 == 0)
{
AI_PlayAni(self,"R_ROAM1");
};
if(randomMove2 == 1)
{
AI_PlayAni(self,"R_ROAM2");
};
if(randomMove2 == 2)
{
AI_PlayAni(self,"R_ROAM3");
};
};
};
return LOOP_CONTINUE;
};
};

func void zs_mm_rtn_kosfollow_end2()
{
};

Инициализация всех волкодавов идёт через
start_aistate = zs_mm_rtn_kosfollow;
start_aistate = zs_mm_rtn_kosfollow1;
start_aistate = zs_mm_rtn_kosfollow2;
Но в Хоринисе всё работает, в двух других локациях не работает.

В Яркендаре даже зацикленный триггер не срабатывает на возврат волкодава, но в Хоринисе срабатывает:

S12 - Хоринис
S14 - Яркендар

if((S12 == 0) && Per1 >= 1)
{
if(Npc_GetDistToNpc(NONE_998_BOBIK,a_nap_001) > 500)
{
AI_StartState(NONE_998_BOBIK,ZS_MM_Rtn_Roam1,1,"NAP_003");
};
};
if((S12 == 1) && Per1 >= 1)
{
if(Npc_GetDistToNpc(NONE_998_BOBIK,hero) > 500)
{
AI_StartState(NONE_998_BOBIK,ZS_MM_Rtn_Roam1,1,"NAP_003");
};
};
if((S14 == 0) && Per3 >= 1)
{
if(Npc_GetDistToNpc(NONE_996_BOBIKA,a_nap_002a) > 500)
{
AI_StartState(NONE_996_BOBIKA,ZS_MM_Rtn_Roam3,1,"BOBIKA");
};
};
if((S14 == 1) && Per3 >= 1)
{
if(Npc_GetDistToNpc(NONE_996_BOBIKA,hero) > 500)
{
AI_StartState(NONE_996_BOBIKA,ZS_MM_Rtn_Roam3,1,"BOBIKA");
};
};

Может движок блокировать?
 
Последнее редактирование:

НастасьСанна

Участник форума
Регистрация
6 Дек 2012
Сообщения
351
Благодарности
521
Баллы
325
В Минентале ошибка в цикле: первый return LOOP_CONTINUE; должен стоять на строчку выше, до }; Сейчас он просто обрубает дальнейшее выполнение тела цикла.

Пропадание NPC часто бывает из-за того, что они привязаны к несуществующему WP. Волкодав вообще не появляется или в какой-то момент пропадает? Он вообще в мире присутствует, Марвином удается к нему телепортироваться (goto waypoint NONE_996_BOBIKA)?
 

Лебедев

Участник форума
Регистрация
3 Сен 2005
Сообщения
595
Благодарности
77
Баллы
225
В Минентале ошибка в цикле: первый return LOOP_CONTINUE; должен стоять на строчку выше, до }; Сейчас он просто обрубает дальнейшее выполнение тела цикла.

Пропадание NPC часто бывает из-за того, что они привязаны к несуществующему WP. Волкодав вообще не появляется или в какой-то момент пропадает? Он вообще в мире присутствует, Марвином удается к нему телепортироваться (goto waypoint NONE_996_BOBIKA)?

func void zs_mm_rtn_kosfollow1()
{
Perception_Set_Monster_Rtn();
Npc_PercEnable(self,PERC_ASSESSPLAYER,B_MM_AssessPlayer);
Npc_PercEnable(self,PERC_ASSESSENEMY,B_MM_AssessEnemy);
Npc_PercEnable(self,PERC_ASSESSMAGIC,B_AssessMagic);
Npc_PercEnable(self,PERC_ASSESSDAMAGE,B_MM_AssessDamage);
Npc_PercEnable(self,PERC_ASSESSFIGHTSOUND,B_MM_AssessOthersDamage);
Npc_PercEnable(self,PERC_ASSESSTALK,B_AssessTalk);
B_SetAttitude(self,ATT_FRIENDLY);
AI_Standup(self);
AI_SetWalkMode(self,NPC_RUN);
};

func int zs_mm_rtn_kosfollow_loop1()
{
var int randomMove1;
if(S13 == 0)
{
B_MM_WispDetect();
if(Npc_GetDistToNpc(self,a_nap_002o) > 500)
{
AI_GotoNpc(self,a_nap_002o);
};
if(Npc_CanSeeNpc(self,a_nap_002o))
{
randomMove1 = Hlp_Random(3);
if(randomMove1 == 0)
{
AI_PlayAni(self,"R_ROAM1");
};
if(randomMove1 == 1)
{
AI_PlayAni(self,"R_ROAM2");
};
if(randomMove1 == 2)
{
AI_PlayAni(self,"R_ROAM3");
};
};
};
if(S13 == 1)
{
B_MM_WispDetect();
if(self.aivar[AIV_PARTYMEMBER] == TRUE)
{
if(Npc_GetDistToNpc(self,hero) > 500)
{
AI_GotoNpc(self,hero);
};
};
if(Npc_CanSeeNpc(self,hero))
{
randomMove1 = Hlp_Random(3);
if(randomMove1 == 0)
{
AI_PlayAni(self,"R_ROAM1");
};
if(randomMove1 == 1)
{
AI_PlayAni(self,"R_ROAM2");
};
if(randomMove1 == 2)
{
AI_PlayAni(self,"R_ROAM3");
};
};
};
self.wp = Npc_GetNearestWP(self);
return LOOP_CONTINUE;
};

func void zs_mm_rtn_kosfollow_end1()
{
};

Вот новый вариант волкодава в Минентале (в Хоринисе работает)

func void B_SummonedAssessTalk()
{
Npc_ChangeAttribute(self,ATR_HITPOINTS,-self.attribute[ATR_HITPOINTS_MAX]);
};

func void ZS_MM_Rtn_Summoned()
{
Npc_SetPercTime(self,1);
Npc_PercEnable(self,PERC_ASSESSPLAYER,B_MM_AssessPlayer);
Npc_PercEnable(self,PERC_ASSESSENEMY,B_MM_AssessEnemy);
Npc_PercEnable(self,PERC_ASSESSMAGIC,B_AssessMagic);
Npc_PercEnable(self,PERC_ASSESSDAMAGE,B_MM_AssessDamage);
Npc_PercEnable(self,PERC_ASSESSFIGHTSOUND,B_MM_AssessOthersDamage);
if(Hlp_GetInstanceID(self) == Hlp_GetInstanceID(Wisp_Detector))
{
Npc_PercEnable(self,PERC_ASSESSTALK,B_AssessTalk);
}
else
{
Npc_PercEnable(self,PERC_ASSESSTALK,B_SummonedAssessTalk);
};
B_SetAttitude(self,ATT_FRIENDLY);
self.aivar[AIV_PARTYMEMBER] = TRUE;
AI_Standup(self);
AI_SetWalkMode(self,NPC_RUN);
};

func int ZS_MM_Rtn_Summoned_Loop()
{
B_MM_WispDetect();
if(Npc_GetDistToNpc(self,hero) > 500)
{
AI_GotoNpc(self,hero);
}
else if(Npc_GetStateTime(self) >= 1)
{
if(!Npc_CanSeeNpc(self,hero))
{
AI_TurnToNPC(self,hero);
};
self.aivar[AIV_SummonTime] = self.aivar[AIV_SummonTime] + Npc_GetStateTime(self);
if(self.aivar[AIV_SummonTime] >= MONSTER_SUMMON_TIME)
{
Npc_ChangeAttribute(self,ATR_HITPOINTS,-self.attribute[ATR_HITPOINTS_MAX]);
};
Npc_SetStateTime(self,0);
};
self.wp = Npc_GetNearestWP(self);
return LOOP_CONTINUE;
};

func void ZS_MM_Rtn_Summoned_End()
{
};

Вот призывной волк который в Минентале работает.

Призывной волк работает, волкодав нет.

WP уже трижды менялся, результат нулевой (или игнорируется в Startup.d или что-то иное). WP существует и в координатную сетку Яркендара входят.

UPD: В Минентале всё заработало, не блокировка движка оказалось:
func void zs_mm_rtn_kosfollow1()
{
Perception_Set_Monster_Rtn();
Npc_PercEnable(self,PERC_ASSESSPLAYER,B_MM_AssessPlayer);
Npc_PercEnable(self,PERC_ASSESSENEMY,B_MM_AssessEnemy);
Npc_PercEnable(self,PERC_ASSESSMAGIC,B_AssessMagic);
Npc_PercEnable(self,PERC_ASSESSDAMAGE,B_MM_AssessDamage);
Npc_PercEnable(self,PERC_ASSESSFIGHTSOUND,B_MM_AssessOthersDamage);
Npc_PercEnable(self,PERC_ASSESSTALK,B_AssessTalk);
B_SetAttitude(self,ATT_FRIENDLY);
AI_Standup(self);
AI_SetWalkMode(self,NPC_RUN);
};

func int zs_mm_rtn_kosfollow_loop1()
{
var int randomMove1;
if(S13 == 0)
{
B_MM_WispDetect();
if(Npc_GetDistToNpc(self,a_nap_002o) > 500)
{
AI_GotoNpc(self,a_nap_002o);
};
if(Npc_CanSeeNpc(self,a_nap_002o))
{
randomMove1 = Hlp_Random(3);
if(randomMove1 == 0)
{
AI_PlayAni(self,"R_ROAM1");
};
if(randomMove1 == 1)
{
AI_PlayAni(self,"R_ROAM2");
};
if(randomMove1 == 2)
{
AI_PlayAni(self,"R_ROAM3");
};
};
};
if(S13 == 1)
{
B_MM_WispDetect();
if(self.aivar[AIV_PARTYMEMBER] == TRUE)
{
if(Npc_GetDistToNpc(self,hero) > 500)
{
AI_GotoNpc(self,hero);
};
};
if(Npc_CanSeeNpc(self,hero))
{
randomMove1 = Hlp_Random(3);
if(randomMove1 == 0)
{
AI_PlayAni(self,"R_ROAM1");
};
if(randomMove1 == 1)
{
AI_PlayAni(self,"R_ROAM2");
};
if(randomMove1 == 2)
{
AI_PlayAni(self,"R_ROAM3");
};
};
};
self.wp = Npc_GetNearestWP(self);
return LOOP_CONTINUE;
};

func void zs_mm_rtn_kosfollow_end1()
{
};

Не там цифры стояли. 4 раза всё переписывалось в поисках ошибки.

goto waypoint NONE_996_BOBIK переносит меня на точку волкодава в Яркендаре. Попытаюсь поменять точку дальше от магов воды, может зона против существ в движке прописана.

Если прописать ADW_ENTRANCE_PLATEAU_01 и 02 и т.д. любой монстр не относящийся к GIL_SEPERATOR_HUM не появляется. (если монстра прописать через Startup.d)
А вот на точке ADW_ENTRANCE_PLATEAU_16 любой монстр появляется, в том числе и волкодав. (если прописать через Startup.d)

Вопрос: почему никто это не описал до сих пор?
 
Последнее редактирование:

cool_er

Участник форума
Регистрация
23 Мар 2015
Сообщения
118
Благодарности
42
Баллы
190
Вопрос: почему никто это не описал до сих пор?
Возможно потому что никто не пытался призвать монстра именно в этом месте? Хотя я не помня точно, но вроде в возвращении когда инвазия орков в Яркендаре - то они вроде на месте магов воды спавнятся вроде. Может вейпоинты частично под землёй и любой монстр проваливается вниз(у меня такое было)? Попробуй заспавнить волкодава на месте появления гг при входе в Яркендар.
 

Лебедев

Участник форума
Регистрация
3 Сен 2005
Сообщения
595
Благодарности
77
Баллы
225
Возможно потому что никто не пытался призвать монстра именно в этом месте? Хотя я не помня точно, но вроде в возвращении когда инвазия орков в Яркендаре - то они вроде на месте магов воды спавнятся вроде. Может вейпоинты частично под землёй и любой монстр проваливается вниз(у меня такое было)? Попробуй заспавнить волкодава на месте появления гг при входе в Яркендар.

Доброе утро. Человек на этих местах нормально появляется (ADW_ENTRANCE_PLATEAU_01 и ADW_ENTRANCE_PLATEAU_02 и т.д.), а вот волкодав нет. Пришлось перебирать точки.
Орк не полностью относится к монстрам.
 
Последнее редактирование:
Сверху Снизу