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

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

    Ссылка на конкурсную тему - тык
    Ссылка на тему с работами участников- тык

В разработке... Клон Торговца

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
1.923
Благодарности
926
Баллы
275
Спасибо Gratt за то что Юнион лишил нас костылей.
Клон Торговца
Использование Клона Торговца, решает следующие задачи:
  • настоящего торговца нельзя будет избить и забрать все товары(Г1);​
  • после избиения настоящего торговца не пропадут все товары(Г2);​
  • торговец не оденет оружие из ассортимента товаров;​
  • торговец не начнёт продавать свои собственные вещи, например руны(Г1);​
  • не получится бесконечно продавать предметы с флагом "миссия"/​
Замена торговца будет происходить в диалоге перед начало торговли, для этого используется новая внешняя функция NPC_SetTrader находящееся в плагине Externals_MW7.dll
Daedalus:
func void NPC_SetTrader(var c_npc newnpc)

***

инстанция клона торговца
Для клона торговца по хорошему надо создать отдельный прототип. Я не знаю какой минимальный набор должен быть для подобных болванчиков и хотел бы попросить ElderGamer подсказать в этой части.
Daedalus:
prototype Npc_CloneTrader(C_NPC)
{
    id             =   666; // можно ли использовать значение "-1" ? или вообще оставить пустым?
    flags       =   NPC_FLAG_IMMORTAL;
 
    //-------- abilities --------
    attribute    [ATR_STRENGTH]             =    1;
    attribute    [ATR_DEXTERITY]         =    1;
    attribute    [ATR_MANA_MAX]             =    1;
    attribute    [ATR_MANA]                 =    1;
    attribute    [ATR_HITPOINTS_MAX]     =    666;
    attribute    [ATR_HITPOINTS]         =    666;


    // ------ Grund-Schadensresistenzen: Keine ------
    protection    [PROT_EDGE]                = -1;
    protection    [PROT_BLUNT]            = -1;
    protection    [PROT_POINT]            = -1;
    protection    [PROT_FIRE]                = -1;
    protection    [PROT_MAGIC]            = -1;
 
    // ------ Schdenstyp im Faustkampf ------
    damagetype                             = DAM_BLUNT;

    //-------- senses --------
    //senses            =    SENSE_HEAR | SENSE_SEE ;
    //senses_range    =    2000;        //SN: am 30.11.00 von 15m auf 20m erhцht (WICHTIG fьr Profilings!)

    start_aistate                = ZS_Drained_YBerion; // нужен наверное какой аналог?
    //или вообще start_aistate                в данном случае не нужен?
};

Daedalus:
instance KDW_604_Cronos_Trader(Npc_CloneTrader)
{
    Mdl_SetVisual        (self,"HUMANS.MDS");
};

вставка клона торговца в мир и замена торговца
в данном примере я решил вставлять в мир клона торговца непосредственно перед торговлей, поэтому я добавил проверку на наличие в мире и вставку непосредственно перед вызовом NPC_SetTrader
Daedalus:
// slf - оригинальный торговец
// npcClone - клон
func void B_NPC_SetTrader(var c_npc slf, var int intClone)
{
    var C_NPC npcClone; npcClone = Hlp_GetNpc(intClone); // !!! берём ссылку на НПС !!!

    if (!Hlp_IsValidNpc(npcClone))
    {
        // нпс в мире нет ->  вставляем
        Wld_InsertNpc   (intClone,"OC1");
        npcClone = Hlp_GetNpc(intClone);            // !!! берём ссылку на НПС !!!
    };
    npcClone.name = slf.name;  // даём клону имя хозяина
   // перезаписать ещё какие то данные?
 
    NPC_SetTrader(npcClone);   // !!! сама замена торговца !!!

    Hlp_PrintConsole(Str_Format("B_NPC_SetTrader slf=%s :: npcClone=%s", slf.name, npcClone.name));
};

ассортимент торговца
Необходимо будет так же поменять НПС который будет "получать" товары каждую главу. на примере B_Give_CronosChapter я оключил оригинальные функции и добавил новые, немного их поправив. весь файл в скрепке.
Daedalus:
func void B_Give_CronosChapter(var int intnpc)
{
    var C_NPC npc; npc = Hlp_GetNpc(intnpc);
 
    if (Hlp_IsValidNpc(npc))   // нпс есть в мире
    {
        B_Give_CronosChapter0(npc);     // "возобновляемый" лут
        if (Kapitel >= 1)   { B_Give_CronosChapter1(npc,1); };
        if (Kapitel >= 2)   { B_Give_CronosChapter2(npc,2); };
        if (Kapitel >= 3)   { B_Give_CronosChapter3(npc,3); };
        if (Kapitel >= 4)   { B_Give_CronosChapter4(npc,4); };
        if (Kapitel >= 5)   { B_Give_CronosChapter5(npc,5); };
        //if (Kapitel >= 6) { B_Give_CronosChapter6(npc,6); };
    };
};


диалог с торговцем
теперь когда подготовительная работа проведена, остаётся просто вызвать функции в диалоге с торговцем
Daedalus:
func void  KDW_604_Cronos_SELLSTUFF_Info()
{
    AI_Output(hero, self,"KDW_604_Cronos_SELLSTUFF_Info_15_01");
    //Ich mцchte Schriften ьber Magie erwerben.
    B_NPC_SetTrader(self,KDW_604_Cronos_Trader);
    B_Give_CronosChapter(KDW_604_Cronos_Trader);
};

p.s.
Данный вариант я тестил: сохранял / загружал игру и менял мир. Вроде всё работает. Возможно какие то нюансы вылезут в будущем. Если кто то хочет потестировать в своём моде, пишите, поможем собрать тестовую сборку.
 

Вложения

  • B_Give_CronosChapterrune.zip
    1,7 KB · Просмотры: 1
Последнее редактирование:

Gratt


Модостроитель
Регистрация
14 Ноя 2014
Сообщения
3.281
Благодарности
4.581
Баллы
625
Спасибо @Gratt за то что Юнион лишил нас костылей.
Тем временем тема поста - скрытый торговец *gigi*
Давай уж тогда скажем прямо. Костыли стало писать куда проще)))
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
1.923
Благодарности
926
Баллы
275
Тем временем тема поста - скрытый торговец *gigi*
не факт что скрытый. ведь скрытый это считай что секретный ;-)

Давай уж тогда скажем прямо. Костыли стало писать куда проще)))
если читать MDK G1 потом MDK G2 потом MDK G1 потом MDK G2 с комментариями, то начинает казаться что там одни костыли :-D
 
Последнее редактирование:

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
1.923
Благодарности
926
Баллы
275
p.s.s.
npcClone.name = slf.name; // даём клону имя хозяина
тут опять же "клон" может хранить общий ассортимент нескольких торговцев.
например: есть условно какая то гильдия/лагерь/лавка в котором есть торговец, и по сюжету/расписанию он меняется или их два и они работают посменно или по сюжету одного торговца закрывают в тюрьму или условно один торговец на рынке, а второй в лавке при этом ассортимент у них общий.
 

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.337
Благодарности
3.181
Баллы
525
Для клона торговца по хорошему надо создать отдельный прототип.
А зачем? Чтобы сэкономить на количестве строк в инстанциях клонов? В мод-фиксе для создания клона я брал инстанцию торговца и менял в ней некоторые вещи. Только и всего.

id = 666; // можно ли использовать значение "-1" ? или вообще оставить пустым?
Ну, если у клона будет полноценный распорядок, то он должен обладать уникальным id.

//senses = SENSE_HEAR | SENSE_SEE ;
//senses_range = 2000;
Если клон будет использовать стандартный распорядок с активированными восприятиями, а "морг" будет располагаться недалеко от доступной игроку области игрового мира, то здесь, наверное, лучше поставить нули.

start_aistate = ZS_Drained_YBerion; // нужен наверное какой аналог?
Думаю, достаточно самого примитивного состояния с отключенными восприятиями.
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
1.923
Благодарности
926
Баллы
275
А зачем? Чтобы сэкономить на количестве строк в инстанциях клонов?
что бы мозг не напрягать и при необходимости править один прототип, а не инстанции всех клонов:)

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

Думаю, достаточно самого примитивного состояния с отключенными восприятиями.
есть пример? :)

а "морг" будет располагаться
я что то пока не понял нужно ли их помещать в морг. а есть команда марвина которая позволит переместиться к указанном НПС? то есть если я вставил НПС в точку "OC1" то где он будет фактически находится с учётом того что у НПС нет распорядка дня.
 

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.337
Благодарности
3.181
Баллы
525
Daedalus:
func void ZS_FakeTrader()
{
};

func void ZS_FakeTrader_Loop()
{
};

func void ZS_FakeTrader_End()
{
};

где он будет фактически находится с учётом того что у НПС нет распорядка дня.
В точке вставки, думаю. Все или почти все клоны в игре так вставляются.
 
Сверху Снизу