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

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

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

MaGoth

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

Вложения

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

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.074
Благодарности
1.030
Баллы
315
Всем привет! Хотел спросить , а можно ли использовать Wld_DetectNpcEx для hero?

Код:
Wld_DetectNpcEx(hero,-1, NOFUNC, -1, 0)
 

MEG@VOLT

★★★★★★★★★
ТехАдмин
Регистрация
24 Мар 2006
Сообщения
10.220
Благодарности
7.061
Баллы
1.850
MW 7, а чем тебе просто Wld_DetectNpc не нравится?
 

D36


Модостроитель
Регистрация
3 Дек 2014
Сообщения
2.304
Благодарности
3.605
Баллы
565

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.506
Благодарности
3.318
Баллы
525
Я так понимаю, речь о том, будет ли работать функция, если в качестве детектирующего персонажа указан персонаж под управлением ГГ. И ответ на этот вопрос не так очевиден, ведь для персонажа под управлением игрока многое работает иначе, нежели для прочих неписей. Думаю, тут нужно экспериментировать. Это нетипичное использование функции, и шансы на то, что кто-то уже задавался этим же вопросом, невелики.
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.074
Благодарности
1.030
Баллы
315
@MW 7, а чем тебе просто Wld_DetectNpc не нравится?
а она будет работать с героем? :)

***

тогда давайте проще: hero сел на табурет, хочу получить ссылку на нпс который рядом с ним. что можно использовать?
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.074
Благодарности
1.030
Баллы
315
MEG@VOLT,
1) в other может быть что угодно. особенно в городе.
2) Npc_GetNearestWP(other) - даст просто WP

или это намёк на что то? :)


***


у меня изначально задумка была такая

Daedalus:
func int C_DetectNpc_Follow_Player()
{
    //Hlp_PrintConsole(Str_Format("C_DetectNpc_Follow_Player = [%s]", other.name));
   // Npc_PerceiveAll(hero);
   // if Wld_DetectNpcEx(hero,-1, NOFUNC, -1, 0)
    if Wld_DetectNpcEx(hero,-1, ZS_Follow_Player, -1, 0)
    {
        Hlp_PrintConsole(Str_Format("   C_DetectNpc_Follow_Player = [%s]", other.name));

        B_SJ_FP_start(other); // новый ZS_
     
        return C_DetectNpc_Follow_Player();
    };
 
    return false;
};
 

MEG@VOLT

★★★★★★★★★
ТехАдмин
Регистрация
24 Мар 2006
Сообщения
10.220
Благодарности
7.061
Баллы
1.850
или это намёк на что то? :)
Почти. Сейчас просто по моей склерозной логике:

Daedalus:
if(Hlp_StrCmp(Wld_DetectNpc(hero,-1,NOFUNC,-1),Npc_IsNear(other,hero))
{
  return true;
};
//NOFUNC = (ZS_)функция сидения, не помню как точно
либо
Daedalus:
if(Wld_DetectNpc(hero,-1,NOFUNC,-1))
{
  if(Hlp_StrCmp(Npc_GetNearestWP(hero),other.wp) == FALSE)
  {
    return true;
  };
};
//NOFUNC = (ZS_)функция сидения, не помню как точно
Естессно надо проверять)
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.074
Благодарности
1.030
Баллы
315
Естессно надо проверять)
так мы и возвращаемся к моему первоначальному вопросу на который дал развёрнутый ответ Элдер ;-) не фурычит Wld_DetectNpc с Hero


***

в итоге решил сделать через AI_SetNpcsToState TA Overlay
 
Последнее редактирование:

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.506
Благодарности
3.318
Баллы
525
Если тебе нужна ссылка на персонажа в состоянии следования за ГГ, то, наверное, имеет смысл, чтобы персонаж сам создавал эту ссылку. Идея заключается в следующем. Заводишь ссылку класса C_Npc, например, slave. Когда непись входит в состояние следования за ГГ, он инициирует эту ссылку ссылкой на себя. Нужно попробовать, работает ли конструкция
Daedalus:
slave = Hlp_GetNpc(self);

За ГГ могут следовать несколько персонажей. Поэтому следует сочинить некий стек ссылок slave и систему управления этим стеком. :oops:
 

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.506
Благодарности
3.318
Баллы
525
hero сел на табурет, хочу получить ссылку на нпс который рядом с ним
Если я правильно понял, ссылка нужна тебе для того, чтобы заставить непися в состоянии следования за ГГ что-то сделать. Если да, то в этом случае можно (и нужно) использовать посылку восприятия PERC_NPCCOMMAND и функцию-обработчик этого восприятия. В Г2 оно имеется, только зона действия ограничена 100 см. Это можно изменить в скриптах в функции InitPerceptions. Алгоритм действий таков.

1. У непися в состоянии следования за ГГ активируется восприятие PERC_NPCCOMMAND и назначается функция-обработчик.
2. В нужный момент производится посылка восприятия функцией Npc_SendPassivePerc(hero,PERC_NPCCOMMAND,hero,hero); Восприятие сработает у неписей в радиусе действия восприятиия, у которых оно активировано. Вызывается функция обработчик. Что в ней может проверяться, и какие действия могут предписываться неписю - это на твоё усмотрение.
3. Если предполагаются разные команды в разных ситуациях, то можно перед вызовом функции Npc_SendPassivePerc изменить значение некой переменной, а в функции-обработчике проверить значение этой переменной. В мод-фиксе так происходит взаимодействие неписей в составе конвоя, когда лидер конвоя отдаёт неписям команды остановиться, продолжить движение и другие.
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.074
Благодарности
1.030
Баллы
315
ElderGamer, спасибо, именно то что надо. тест прошёл успешно

Daedalus:
func void B_NpcCommand ()
{  
    Hlp_PrintConsole(Str_Format("   B_NpcCommand[%s]:  ", self.name));
};

func void ZS_Follow_Player()
{
    Npc_PercEnable (self, PERC_NPCCOMMAND   , B_NpcCommand);
    ZS_Follow_Player_old();
};

func event GameLoop()
{  
    if Hlp_KeyToggled(KEY_NUMPAD0)
    //if hero.aivar[AIV_INVINCIBLE] == true
    {
        Npc_SendPassivePerc(hero,PERC_NPCCOMMAND,hero,hero);
    };
};
 

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.506
Благодарности
3.318
Баллы
525
где (в скриптах?) прописываются настройки определённых порталов и какие же отличия имеют те же P:_OWCAVE, P:_HWALD, P:_HÜTTE и т.д.

Принадлежность территории, ограниченной порталами, определяется в скриптах функциями Wld_AssignRoomToGuild и Wld_AssignRoomToNpc. Пример:

Daedalus:
Wld_AssignRoomToGuild("NLHU26",GIL_SLD);

NLHU26 - это территория, находящаяся за порталом P:_NLHU26.

Обычно это делается в функциях инициализации игрового мира. в Startup.d.
 

π'yavka

Участник форума
Регистрация
21 Мар 2025
Сообщения
29
Благодарности
2
Баллы
15
Здравствуйте, подскажите, пожалуйста. Возможно ли перенести какие-то AI константы из Готики 2 в Готику 1. В квесте очень потребовалась константа [AIV_KilledByPlayer] для проверки того, что моба убил ГГ, а не другой персонаж. Если перенос не возможен, можно ли реализовать проверку на имеющихся константах или функциях Г1?
Также подскажите. Есть ли константа проверки нападения на моба/НПС? Возвращающая значение если бы определенный персонаж нападал на другого.
И куда прописывать скрипт для того, чтобы после убийства моба (монстра) запускалась запись в дневник, другой скрипт и т.д. ?
 
Последнее редактирование:

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.074
Благодарности
1.030
Баллы
315
И подскажите. Куда прописывать скрипт для того, чтобы после убийства моба (монстра) запускалась запись в дневник, другой скрипт и т.д. ?
внутри B_CheckDeadMissionNPCs

Здравствуйте, подскажите, пожалуйста. Возможно ли перенести какие-то AI константы из Готики 2 в Готику 1. В квесте очень потребовалась константа [AIV_KilledByPlayer] для проверки того, что моба убил ГГ, а не другой персонаж. Если перенос не возможен, можно ли реализовать проверку на имеющихся константах или функциях Г1?
добавь новую константу
const int AIV_KilledByPlayer = AIV_DEALDAY ; // 41. не нужна мёртвому НПС

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

π'yavka

Участник форума
Регистрация
21 Мар 2025
Сообщения
29
Благодарности
2
Баллы
15
добавь новую константу
const int AIV_KilledByPlayer = AIV_DEALDAY ; // 41. не нужна мёртвому НПС
но имей ввиду, что ты сможешь сделать проверку только если НПС есть в мире. если НПС был удалён из мира то ты проверку через аивер не сделаешь, так как она хранится в инстанции нпс, а нпс нет в мире ;-) в таком случае тебе лучше использовать какую то переменную
Спасибо за ответ. Добавил константу в Ai_constans, как вы написали - к сожалению не работает. Считается ли убийство удалением из мира?
Вот так я её прописал в диалоге:
Код:
if(MOBNEW.aivar[AIV_KilledByPlayer] == TRUE)

внутри B_CheckDeadMissionNPCs
Прописал скрипт по примеру убийства Лефти, но он никак не реагирует - после убийства запись в дневник не ведётся:
Код:
func void B_CheckDeadMissionNPCsMOBNEW()
{
    if(Hlp_GetInstanceID(MOBNEW) == Hlp_GetInstanceID(self))
    {
    B_LogEntry(TOPIC_MOBNEWINFO,"TEXT.");
    };
};

Также, я был бы благодарен, если бы мне помогли разобраться почему не работает проверка здоровья в диалоге:
Код:
if((hero.attribute[ATR_HITPOINTS]) = (hero.attribute[ATR_HITPOINTS_MAX]))
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.074
Благодарности
1.030
Баллы
315
π'yavka, какая инстанция НПС ?


Добавил константу в Ai_constans, как вы написали - к сожалению не работает.
а в zs_dead добавил?
Daedalus:
func void ZS_Dead ()
{ 
    PrintDebugNpc    (PD_ZS_FRAME, "ZS_Dead" );     
    PrintGlobals    (PD_ZS_CHECK);

    C_ZSInit();

    self.aivar[AIV_PLUNDERED] = FALSE;
  
    //-------- Erfahrungspunkte fьr den Spieler ? --------
    //SN: VORSICHT, auch in B_MagicHurtNpc() vorhanden!
    if    Npc_IsPlayer   (other)
    ||    (C_NpcIsHuman  (other) && other.aivar[AIV_PARTYMEMBER])
    ||    (C_NpcIsMonster(other) && other.aivar[AIV_MM_PARTYMEMBER])
    {
        B_DeathXP();    // vergibt XP an SC
    };
  
    if    C_NpcIsMonster(self)
    {
        B_GiveDeathInv ();     // fьr Monster
    };
    B_CheckDeadMissionNPCs ();
    B_Respawn (self);   
  
    if (Npc_IsPlayer(other))
    {
        self.aivar[AIV_KilledByPlayer] = TRUE;
    };
};

Также, я был бы благодарен, если бы ты помог разобраться почему не работает проверка здоровья в диалоге:
Код:
if ((hero.attribute[ATR_HITPOINTS]) == (hero.attribute[ATR_HITPOINTS_MAX]))
 
Последнее редактирование:

π'yavka

Участник форума
Регистрация
21 Мар 2025
Сообщения
29
Благодарности
2
Баллы
15
π'yavka, какая инстанция НПС ?
Немного не понимаю конкретно про что идёт речь.

а в zs_dead добавил?
Точно, в ZS не добавил - сейчас сделаю.


Спасибо, что-то "записался" я... :D
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.074
Благодарности
1.030
Баллы
315
Немного не понимаю конкретно про что идёт речь.
MOBNEW это у тебя что? инстанция НПС? покажи как у тебя в файлах скриптах прописано.

Точно, в ZS не добавил - сейчас сделаю.
тоже покажи файл zs_dead у тебя выглядит и файл B_CheckDeadMissionNPCs
 

π'yavka

Участник форума
Регистрация
21 Мар 2025
Сообщения
29
Благодарности
2
Баллы
15
Только что проверил - константа и проверки работают! Спасибо большое!

MOBNEW это у тебя что? инстанция НПС? покажи как у тебя в файлах скриптах прописано
Код:
instance MOBNEW(Mst_Default_Molerat)
{
    name[0] = "Старый кротокрыс";
    level = 5;
    Set_Molerat_Visuals();
    Npc_SetToFistMode(self);
    CreateInvItems(self,ItFoMuttonRaw,1);
};

и файл B_CheckDeadMissionNPCs
Код:
func void B_CheckDeadMissionNPCs()
{
    if(Hlp_GetInstanceID(Org_844_Lefty) == Hlp_GetInstanceID(self))
    {
        if(Lefty_Mission == LOG_RUNNING)
        {
            B_LogEntry(CH1_CarryWater,"Теперь, когда Лефти мертв, вопрос с водой можно считать закрытым. Честно говоря, мне этот парень никогда не нравился.");
            Log_SetTopicStatus(CH1_CarryWater,LOG_SUCCESS);
            LeftyDead = TRUE;
        };
    };
};

func void B_CheckDeadMissionNPCsMOBNEW()
{
    if(Hlp_GetInstanceID(MOBNEW) == Hlp_GetInstanceID(self))
    {
    B_LogEntry(MOBNEWINFO,"TEXT");
    };
};
 
Сверху Снизу