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

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

В разработке... useWithItem и ConditionFunc для MobInter

Бене Гессерит это


  • Всего проголосовало
    8

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.000
Благодарности
968
Баллы
295
  • Первое сообщение
  • #1
MobInter содержит «вшитую» проверку на предмет необходимый герою для взаимодействия с Mob'ом. Данный плагин «отвязывает» проверку на WithItem , осуществляя перехват функции разрешающий взаимодействие с объектом в новой общей Condition функции вызываемой из скриптов.

Спасибо ElderGamer за идею, спасибо Xeдин за реализацию, спасибо Gratt за то что лишил нас костылей, спасибо Slavemaster за то что делает Юнион совершенным.

***

После установки плагина на уровне скриптов надо добавить две функции:
  • G_MobInter_CanInteractWith – разрешает / запрещает взаимодействие с моб объектом.
  • G_MobInter_UseWithItem – заменяет Item(при необходимости)
  • G_MobInter_SendCallOnStateFunc - заменяет StateFunc функции(при необходимости)
Функция G_MobInter_CanInteractWith "общая" для всех МОБ'ов. В ней можно прописать вызов отдельных кондишен функцию для конктерных МОБ объектов с которыми взаимодействует герой.
Daedalus:
// функция вызывается движком если НПС - герой
func int G_MobInter_CanInteractWith(var string sceme, var int useWithItem)
{
    Hlp_PrintConsole(Str_Format("   G_MobInter_CanInteractWith:  sceme: %s useWithItem (%i)", sceme, useWithItem));
 
    if  (Hlp_StrCmp(sceme,"LAB"))       {   return C_Hero_GetInv_MobInterItem(ItMi_Flask);  };
    //if  (Hlp_StrCmp(sceme,"RMAKER"))    {    return hero_RMaker_Condition(useWithItem);   };// это рунный стол, делаем проверку внутри HERO_ALCHEMY_CONDITION
 
    if  (useWithItem == -1)              {   return true;    }; // Item не требуется
 
    return C_Hero_GetInv_MobInterItem(useWithItem);             // вроверка на наличие у героя Item
};
Внутри функции кондишион моба можно делать проверку на необходимые условия для взаимодействием с данным мобом, как в оригинальных скриптах: наличие у героя каких то вещей , навыков, времени суток, наличие друзей / врагов рядом и так далее.

Для прочих объектов я написал черновик универсальной функции C_Hero_GetInv_MobInterItem.
Daedalus:
func int C_Hero_GetInv_MobInterItem(var int useWithItem)
{
    if (Npc_GetInvItem(hero,useWithItem))
    {
        return true;    // у героя есть предмет -- > взаимодействие
    };
 
    // создаём красивый отказ от взаимодействия
    CreateInvItem(hero,useWithItem);
 
    var string msg;
    msg = ConcatStrings("Для использования необдим: ", item.name) ;
    PrintDialog( 1, msg , -1, -1, FONT_ScreenSmall, 2);
    AI_PlayAni(hero,"T_DONTKNOW");
 
    Npc_RemoveInvItem(hero,useWithItem);
 
    return false;
};
В ней проверяется есть ли у героя предмет для взаимодействия с МОБом, если его нет то выводится какое-то сообщение и/или герой машет руками и/или герой что то говорит. То есть данная функция дописывается/настраивается согласно тому как автор видит данное событие.
1686181406672.png
1686181427399.png

***

Из бонусов:
  • теперь предмет необходимый для взаимодействия с мобом не будет удалять у героя движок. То есть в диалоге выхода из производства не придётся создавать «неиспользованную» руну/колбу/заготовку.
  • в функции C_MobInter_UseWithItem можно заменить item который герой будет использовать при взаимодействие с МОБ'ом.

Daedalus:
// функция вызывается движком  если НПС - герой
func int G_MobInter_UseWithItem(var string sceme, var int useWithItem)
{
    Hlp_PrintConsole(Str_Format(" call G_MobInter_UseWithItem sceme: %s, useWithItem: %i", sceme, useWithItem));
 
    if (Hlp_StrCmp(sceme,"LAB"))    { return C_MobInter_UseNewItem(ItMi_Flask_fake); };
 
    // возвращаем оригинальную инстанцию
    return useWithItem;
};


***
Daedalus:
func int G_MobInter_SendCallOnStateFunc(var string sceme, var int state)
{
    Hlp_PrintConsole(Str_Format(" call G_MobInter_SendCallOnStateFunc sceme: %s, state: %i", sceme, state));
};
 

Вложения

  • 2023_06_16_zMobInet.zip
    92,9 KB · Просмотры: 3
Последнее редактирование:

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.000
Благодарности
968
Баллы
295
ElderGamer, скинь файл скрипта
 

ElderGamer


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

Вложения

  • __WORK.d
    7,8 KB · Просмотры: 2

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.000
Благодарности
968
Баллы
295
у тебя в G_MobInter_CanInteractWith нет проверки на то есть ли у героя сырое мясо. у меня такая же ситуация была. после того как прописал проверки такой баг пропал.
 
Последнее редактирование:

ElderGamer


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

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

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.000
Благодарности
968
Баллы
295
Проблема не в том, что предмета, необходимого для взаимодействия, нет в инвентаре.
можно конечно этот вопрос обсуждать в академическом формате. но я повторюсь, что
у меня такая же ситуация была. после того как прописал проверки такой баг пропал.
 

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.407
Благодарности
3.232
Баллы
525
Введение проверки не защищает от описанного выше бага, поскольку он происходит и при наличии сырого мяса в инвентаре.
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.000
Благодарности
968
Баллы
295
тогда надо будет доделать плагин на уровне юнион. что бы перед вызовом G_MobInter_CanInteractWith проходила оригинальная проверка которая не дала бы произойти такой ситуации.
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.000
Благодарности
968
Баллы
295
ElderGamer, извини. я пишу на ощупь и для меня какие то базовые/элементарные вещи ещё не очевидны.

Обновил файл

***


Тестирую сковородку в каком то иностранном моде, что бы получить на выходе "автономный" код подходящий для любой версии игры.
 

Вложения

  • zMobInet.zip
    92,9 KB · Просмотры: 3
Последнее редактирование:

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.000
Благодарности
968
Баллы
295
я что то написал. но как обычно в процессе увлёкся не тем чем следовало бы :-/
Daedalus:
//*************************************************//
//              жарить мясо
//*************************************************//
instance PC_Mobsi_Pan_Mutton5(PRT_Mobsi_Pan)    { condition = PC_Mobsi_Pan_MuttonRaw_condition5; information = PC_Mobsi_Pan_Mutton5_info; };
instance PC_Mobsi_Pan_Mutton1(PRT_Mobsi_Pan)    { condition = PC_Mobsi_Pan_MuttonRaw_condition1; information = PC_Mobsi_Pan_Mutton1_info; };

func int PC_Mobsi_Pan_MuttonRaw_condition5()    { return PC_Mobsi_Pan_AllProduct_condition(ItFoMuttonRaw,PC_Mobsi_Pan_Mutton5,5);  };
func int PC_Mobsi_Pan_MuttonRaw_condition1()    { return PC_Mobsi_Pan_AllProduct_condition(ItFoMuttonRaw,PC_Mobsi_Pan_Mutton1,1);  };

func void PC_Mobsi_Pan_Mutton5_info()           { B_PAN_fried_amount(ItFoMuttonRaw,ItFoMutton,5);  };
func void PC_Mobsi_Pan_Mutton1_info()           { B_PAN_fried_amount(ItFoMuttonRaw,ItFoMutton,1);  };

//*************************************************//
//              жарить рыбу
//*************************************************//
instance PC_Mobsi_Pan_Fish5(PRT_Mobsi_Pan)      { condition = PC_Mobsi_Pan_Fish_condition5; information = PC_Mobsi_Pan_Fish5_info;  };
instance PC_Mobsi_Pan_Fish1(PRT_Mobsi_Pan)      { condition = PC_Mobsi_Pan_Fish_condition1; information = PC_Mobsi_Pan_Fish1_info; };

func int PC_Mobsi_Pan_Fish_condition5()         {   return PC_Mobsi_Pan_AllProduct_condition(ItFo_Fish,PC_Mobsi_Pan_Fish5,5);  };
func int PC_Mobsi_Pan_Fish_condition1()         {   return PC_Mobsi_Pan_AllProduct_condition(ItFo_Fish,PC_Mobsi_Pan_Fish1,1);  };

func void PC_Mobsi_Pan_Fish5_info()             { B_PAN_fried_amount(ItFo_Fish,ItFo_Fishfried,5);  };
func void PC_Mobsi_Pan_Fish1_info()             { B_PAN_fried_amount(ItFo_Fish,ItFo_Fishfried,1);  };

в целом всё работает. тестил в польском "моде" где нет ни рыбы ни интерактива со сковородкой :)
1686937391211.png
 

Вложения

  • 2023_06_16_zMobInet.zip
    92,9 KB · Просмотры: 5
  • Dia_MOBSI_PAN.rar
    3,6 KB · Просмотры: 3

Slavemaster


Модостроитель
Регистрация
10 Июн 2019
Сообщения
1.081
Благодарности
1.901
Баллы
320
Выложу свои сырые попытки, сделать чудо-сковороду.
Во-первых, сделал плагин zCallScriptEventTag, который позволяет пользоваться тегом DEF_CALL_SCRIPT (проверял только с Г2).
Во-вторых, расширил плагин zOrcHunter:
1689621469556.png

Npc_SetInteractItem использует предметы из инвентаря (если не хватает, то сперва их создаёт)
В-третьих, для собственного удобства сделал плагин zSuperpans, который меняет (пока установлен) все сковородки следующим образом:
1689621638899.png

В-четвёртых, написал новые скрипты (все скрипты только для Г2) анимаций.
События в скриптах понадобились, по сути, только для неигровых персонажей.
Daedalus:
ani            ("t_SuperPan_Stand_2_S0"            1    "s_SuperPan_S0"        0.1    0.0    M.    "Hum_CookForMe_M01.asc"        F    0    24)
{
    *eventTag    (0    "DEF_CALL_SCRIPT"    "SuperPan_SetRawMeat")
}
ani            ("s_SuperPan_S0"                    1    "s_SuperPan_S0"        0.0    0.0    M.    "Hum_CookForMe_M01.asc"        F    25    25)
{
   
}
ani         ("t_SuperPan_S0_2_Stand"            1    ""                0.0    0.2    M.    "Hum_CookForMe_M01.asc"            R    0    24)
{
   
}

ani            ("t_SuperPan_S0_2_S1"            1    "s_SuperPan_S1"        0.0    0.0    M.    "Hum_CookForMe_M01.asc"        F    26    34)
{
    *eventTag    (26    "DEF_INSERT_ITEM"    "ZS_RIGHTHAND")
}
ani            ("s_SuperPan_S1"                    1    "s_SuperPan_S1"        0.0    0.0    M.    "Hum_CookForMe_M01.asc"        F    35    84)
{
    *eventSFX    (36    "PAN_FRYING"    R:1000    EMPTY_SLOT    )
}
ani            ("t_SuperPan_S1_2_S0"            1    "s_SuperPan_S0"        0.0    0.0    M.    "Hum_CookForMe_M01.asc"        R    26    34)
{
    *eventTag    (26    "DEF_REMOVE_ITEM")
    *eventTag    (34    "DEF_CALL_SCRIPT"    "SuperPan_ExchangeItem")
}
Ну и в-пятых, написал трешёвые диалоги с отладкой:
Daedalus:
const int EV_INSERTINTERACTITEM = 6;
const int EV_REMOVEINTERACTITEM = 7;
const int EV_CREATEINTERACTITEM = 8;
const int EV_DESTROYINTERACTITEM = 9;
const int EV_PLACEINTERACTITEM = 10;
const int EV_EXCHANGEINTERACTITEM = 11;

func void LogName(var string name)
{
    Print(name);
    Hlp_PrintConsole(name);
};

func void Dia_Fry_Info(var int rawItem, var int amount)
{
    Npc_SetInteractItem(self, rawItem, amount);
    AI_PlayAni(self, "T_SUPERPAN_S1_2_S0");
    AI_TriggerAniEvent(self, EV_INSERTINTERACTITEM, "ZS_RIGHTHAND", 0);
    AI_PlayAni(self, "T_SUPERPAN_S0_2_S1");
    AI_Wait(self, 1.5);
    AI_CallScript("SuperPan_ExchangeItem", self, self);
    AI_Wait(self, 0.5);
    AI_PlayAni(self, "T_SUPERPAN_S1_2_S0");
    AI_TriggerAniEvent(self, EV_REMOVEINTERACTITEM, "ZS_RIGHTHAND", 0);
    AI_PlayAni(self, "T_SUPERPAN_S0_2_S1");
};

// =============================

instance Dia_Fry_Exit(C_INFO)
{
    npc = PC_Hero;
    nr = 999;
    condition = Dia_Fry_Exit_Condition;
    information = Dia_Fry_Exit_Info;
    permanent = True;
    description = Dialog_Ende;
};

func int Dia_Fry_Exit_Condition()
{
    return True;
};

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

// =============================

instance Dia_Fry_Meat(C_INFO)
{
    npc = PC_Hero;
    nr = 1;
    condition = Dia_Fry_Meat_Condition;
    information = Dia_Fry_Meat_Info;
    permanent = True;
   
    description = Str_GetLocalizedString(
        "Жарить мясо",
        "Fry meat",
        "Fry meat",
        "Fry meat"
    );
};

func int Dia_Fry_Meat_Condition()
{
    return Npc_HasItems(self, ItFoMuttonRaw) >= 1;
};

func void Dia_Fry_Meat_Info()
{
    Dia_Fry_Info(ItFoMuttonRaw, 1);
};

// =============================

instance Dia_Fry_Apple(C_INFO)
{
    npc = PC_Hero;
    nr = 2;
    condition = Dia_Fry_Apple_Condition;
    information = Dia_Fry_Apple_Info;
    permanent = True;
   
    description = Str_GetLocalizedString(
        "Жарить 5 яблок",
        "Fry 5 apples",
        "Fry 5 apples",
        "Fry 5 apples"
    );
};

func int Dia_Fry_Apple_Condition()
{
    return Npc_HasItems(self, ItFo_Apple) >= 5;
};

func void Dia_Fry_Apple_Info()
{
    Dia_Fry_Info(ItFo_Apple, 5);
};

// =============================

func int SuperPan_Condition()
{
    LogName("Condition");
    return !Npc_IsPlayer(self) || Npc_HasItems(self, ItFoMuttonRaw);
};

func void SuperPan_S0()
{
    LogName("S0");
};

func void SuperPan_S1()
{
    LogName("S1");
   
    if Npc_IsPlayer(self)
    {
        AI_ProcessInfos(self);
    };
};

func void SuperPan_ExchangeItem()
{
    LogName("Exchange");
   
    var int friedItem;
    friedItem = 0;
   
    var C_ITEM interactItem;
    interactItem = Npc_GetInteractItem(self);
   
    var int friedAmount;
    friedAmount = Item_GetAmount(interactItem);
   
    if Hlp_IsItem(interactItem, ItFoMuttonRaw)
    {
        friedItem = ItFo_Bread;
    } else if Hlp_IsItem(interactItem, ItFo_Apple)
    {
        friedItem = ItFo_Beer;
    };
   
    if friedItem
    {
        Npc_TriggerAniEvent(self, EV_EXCHANGEINTERACTITEM, "ZS_RIGHTHAND", friedItem);
       
        if friedAmount > 1
        {
            CreateInvItems(self, friedItem, friedAmount - 1);
        };
    };
};

func void SuperPan_SetRawMeat()
{
    LogName("SetRawMeat");
   
    if !Npc_IsPlayer(self)
    {
        Npc_SetInteractItem(self, ItFoMuttonRaw, 1);
    };
};
 

Вложения

  • zSuperpans.zip
    141,4 KB · Просмотры: 9
Последнее редактирование:

Slavemaster


Модостроитель
Регистрация
10 Июн 2019
Сообщения
1.081
Благодарности
1.901
Баллы
320
Видео добавил, если кому лень в игре это смотреть.

zSuperpans перезалил на гугл-диск
 
Последнее редактирование:
Сверху Снизу