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

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

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

MDK G1

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
1.923
Благодарности
926
Баллы
275
вопросы по скриптам MDK G1
 

Вложения

  • Scripts_G1_MDK.zip
    1,5 MB · Просмотры: 1

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
1.923
Благодарности
926
Баллы
275
Daedalus:
 ***********************
// Geklaute Waffen checken
// ***********************

FUNC VOID B_CheckStolenEquipment ()
{
    var C_Item     melee;
    var C_Item     ranged;
    var C_ITEM    armor;
 
    melee     =     Npc_GetEquippedMeleeWeapon         (other);
    ranged     =     Npc_GetEquippedRangedWeapon     (other);
    armor    =    Npc_GetEquippedArmor             (other);
 
    if (Npc_OwnedByNpc (melee, self))
    {
        PrintDebugNpc (PD_ZS_CHECK,    "...SC trдgt Nahkampf-Waffe des NSCs offen!");
        self.aivar[AIV_WANTEDITEM] = Hlp_GetInstanceId (melee);
        if (!Npc_HasNews (self, NEWS_DEFEAT, other, self) && self.aivar [AIV_PCISSTRONGER] == 0)
        {
            PrintDebugNpc     (PD_ZS_CHECK,    "...NSC ist nicht vom SC besiegt worden & hat noch nicht danach gefragt!");
            Npc_ClearAIQueue( self);
            C_LookAtNpc     ( self, other);
            AI_TurnToNpc     ( self, other);
            AI_PointAtNpc     ( self, other);
            B_Say             ( self, other,"$THATSMYWEAPON");
            AI_StartState     ( self, ZS_GetBackBelongings, 1, "");
            return;
        };
    }
    else if (Npc_OwnedByNpc ( ranged, self))
    {
        PrintDebugNpc (PD_ZS_CHECK,    "...SC trдgt Fernkampf-Waffe des NSCs offen!");
        self.aivar[AIV_WANTEDITEM] = Hlp_GetInstanceId (ranged);
        if (!Npc_HasNews (self, NEWS_DEFEAT, other, self) && self.aivar [AIV_PCISSTRONGER] == 0)
        {
            Npc_ClearAIQueue( self);
            C_LookAtNpc     ( self, other);
            AI_TurnToNpc     ( self, other);
            AI_PointAtNpc     ( self, other);
            B_Say             ( self, other,"$THATSMYWEAPON");
            AI_StartState     ( self, ZS_GetBackBelongings, 1, "");
            return;
        };
    };
};

предупреждения в zSpy
Код:
48:28 Warn:  0 C:     SCRIPT: Npc_OwnedByNpc(): illegal param: "B_CHECKSTOLENEQUIPMENT.RANGED" is NULL. .... <oGameExternal.cpp,#252>
48:28 Warn:  0 C:     SCRIPT: last parser func-name: B_ASSESSSC .... <oGameExternal.cpp,#262>
я так понимаю что надо добавить проверку на то экипировано ли оружие у НПС
Daedalus:
    if (Npc_HasEquippedMeleeWeapon(other))
    {
        var C_Item     melee;
        melee = Npc_GetEquippedMeleeWeapon(other);
        if (Npc_OwnedByNpc(melee, self))
        {

...
...
...

    if (Npc_HasEquippedRangedWeapon(other))
    {
        var C_Item     ranged;
        ranged     =     Npc_GetEquippedRangedWeapon(other);
   
        if (Npc_OwnedByNpc(ranged, self))
        {



ElderGamer ты не переписывал эту функцию?
 
Последнее редактирование:

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.337
Благодарности
3.181
Баллы
525

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
1.923
Благодарности
926
Баллы
275
вот так переписал

Daedalus:
// ***********************
// Geklaute Waffen checken
// ***********************
func void B_CheckStolenEquipment_true(var c_npc slf, var c_npc oth)
{
    PrintDebugNpc     (PD_ZS_CHECK,    "...NSC ist nicht vom SC besiegt worden & hat noch nicht danach gefragt!");
    Npc_ClearAIQueue(slf);
    C_LookAtNpc     (slf, oth);
    AI_TurnToNpc     (slf, oth);
    AI_PointAtNpc     (slf, oth);
    B_Say             (slf, oth,"$THATSMYWEAPON");
    AI_StartState     (slf, ZS_GetBackBelongings, 1, "");
};           
            
            
//func void B_CheckStolenEquipment()
func int C_CheckStolenEquipment(var c_npc slf, var c_npc oth)
{
    // Выход, если:
    if (oth.id != hero.id)                      { return false; }; //  oth это не НПС которым управляет игрок
    if (Npc_HasNews(slf,NEWS_DEFEAT,oth,slf))   { return false; };
    if (slf.aivar[AIV_PCIsStronger])            { return false; };

    // heck оружия ближнего боя
    if (Npc_HasEquippedMeleeWeapon(oth))
    {
        var C_Item     melee;
        melee = Npc_GetEquippedMeleeWeapon(oth);
        if (Npc_OwnedByNpc(melee, slf))
        {
            PrintDebugNpc (PD_ZS_CHECK,    "...SC trдgt Nahkampf-Waffe des NSCs offen!");
            slf.aivar[AIV_WANTEDITEM] = Hlp_GetInstanceId (melee);

            B_CheckStolenEquipment_true(slf, oth);
            return true;
        };
    };
    
    // heck оружия дальнего боя
    if (Npc_HasEquippedRangedWeapon(oth))
    {
        var C_Item     ranged;
        ranged     =     Npc_GetEquippedRangedWeapon(oth);
    
        if (Npc_OwnedByNpc(ranged, slf))
        {
            PrintDebugNpc (PD_ZS_CHECK,    "...SC trдgt Fernkampf-Waffe des NSCs offen!");
            slf.aivar[AIV_WANTEDITEM] = Hlp_GetInstanceId(ranged);

            B_CheckStolenEquipment_true(slf, oth);
            return true;
        };
    };
    
    /*
    // heck брони :-D
    if (Npc_HasEquippedArmor(oth))
    {
        var C_ITEM    armor;        armor    =    Npc_GetEquippedArmor(oth);
        if (Npc_OwnedByNpc(armor, slf))
        {
            slf.aivar[AIV_WANTEDITEM] = Hlp_GetInstanceId(armor);

            B_CheckStolenEquipment_true(slf, oth)
            return true;
        };
    };
    */
    
    // у героя не экпипировинно оружие принадлежащее SELF
    return false;
};
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
1.923
Благодарности
926
Баллы
275
Daedalus:
//////////////////////////////////////////////////////////////////////////
//    ZS_PracticeSword
//    ================
//    Der NSC vollfьhrt eine Schwert-Kata auf der Stelle
//    (FP "FIGHTTRAINING")
//////////////////////////////////////////////////////////////////////////
func void ZS_PracticeSword ()
{
    PrintDebugNpc        (PD_TA_FRAME,"ZS_PracticeSword");
 
    B_SetPerception        (self);
    AI_SetWalkmode        (self,    NPC_WALK);
 
    if !(Hlp_StrCmp(self.wp,Npc_GetNearestWP(self)))
    {
        AI_GotoWP        (self, self.wp);               // Gehe zum Tagesablaufstart
    };
    AI_DrawWeapon        (self);
};

func void ZS_PracticeSword_Loop()
{
    PrintDebugNpc        (PD_TA_LOOP,    "ZS_PracticeSword_Loop");
 
    AI_PlayAni            (self,"T_1HSFREE");
    AI_GotoWP            (self, self.wp);
    AI_AlignToWP        (self);
};

func void ZS_PracticeSword_End ()
{
    PrintDebugNpc        (PD_TA_FRAME,    "ZS_PracticeSword_End");
 
    B_FullStop            (self);
    B_RemoveWeapon        (self);
};

AI_DrawWeapon по хорошему надо завернуть.


Daedalus:
func void B_DrawWeapon(var c_npc npc)
{
    if (Npc_HasReadiedMeleeWeapon(npc)) { return; }; // НПС и так уже достал оружие --> выход

    if (Npc_HasEquippedMeleeWeapon(npc) != 1)
    {
        // у НПС нет экипированного оружия --> Одеваем
        AI_EquipBestMeleeWeapon(npc);
        if (Npc_HasEquippedMeleeWeapon(npc) != 1)
        { 
            // у НПС всё равно нет оружия
            CreateInvItem(npc,ItMwPickaxe);
            AI_EquipBestMeleeWeapon(npc);
        };
    };
   
    AI_DrawWeapon(npc);
};

ElderGamer, подскажи пожалуйста а чем AI_DrawWeapon отличается от AI_ReadyMeleeWeapon ?
 
Последнее редактирование:

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.337
Благодарности
3.181
Баллы
525
чем AI_DrawWeapon отличается от AI_ReadyMeleeWeapon ?
Я не знаю, как работает AI_DrawWeapon, если у непися экипировано и оружие ближнего боя, и оружие дальнего боя. Наверное, какая-то разновидность оружия имеет более высокий приоритет.

Daedalus:
func void B_DrawWeapon(var c_npc npc)
{
    if (Npc_HasReadiedMeleeWeapon(npc)) { return; }; // НПС и так уже достал оружие --> выход

    if (Npc_HasEquippedMeleeWeapon(npc) != 1) // Первая проверка.
    {
        // у НПС нет экипированного оружия --> Одеваем
        AI_EquipBestMeleeWeapon(npc);
        if (Npc_HasEquippedMeleeWeapon(npc) != 1) // Вторая проверка.
        {
            // у НПС всё равно нет оружия
            CreateInvItem(npc,ItMwPickaxe);
            AI_EquipBestMeleeWeapon(npc);
        };
    };
  
    AI_DrawWeapon(npc);
};

Первая и вторая проверки в коде дадут абсолютно одинаковый результат. К моменту проведения второй проверки функция AI_EquipBestMeleeWeapon ещё не будет выполнена. Таким образом, если оружие есть в инвентаре, но не экипировано, оно не будет взято в руки.

Посмотри в скриптах мод-фикса, какие выкрутасы пришлось наворачивать ради такого случая. Это всё возможно сделать только в циклической части состояния.
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
1.923
Благодарности
926
Баллы
275
AI_EquipBestMeleeWeapon ещё не будет выполнена

тогда проще иметь какое то простое оружие в инвентаре. иначе придётся искать по слоту
Daedalus:
func void B_DrawWeapon(var c_npc npc)
{
    if (Npc_HasReadiedMeleeWeapon(npc))         { return; }; // НПС и так уже достал оружие --> выход

    if (Npc_HasEquippedMeleeWeapon(npc) != 1)
    {
        // у НПС нет экипированного оружия
        if !Npc_GetInvItem(npc,ItMwPickaxe)
        { 
            // создаём какое просто оружие на всякий случай
            // можно делать проверку на фракцию и в зависимости 
            // от неё создавать разное оружие.
            CreateInvItem(npc,ItMwPickaxe); 
        };
        item.ownerGuild = npc.guild; // если герой отожмёт оружие чужой фракции, то может получить в тыкву от товарищй npc

        AI_EquipBestMeleeWeapon(npc);
    };
    //AI_ReadyMeleeWeapon(npc); // используется в G2 MDK
    AI_DrawWeapon(npc);         // используется в G1 MDK
};

надо будет проверить будет ли НПС через AI_DrawWeapon доставать арбалет или лук.
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
1.923
Благодарности
926
Баллы
275
B_DrawSpell

Я так понимаю тут НПС ману увеличивают. но не могу понять на сколько. Что бы в итоге у него всегда было не меньше половины маны от максимальной?
MDKправки
Daedalus:
    //-------- "echte" Magier bekommen Mana dazugeschummelt --------
        var int manaLeft;    manaLeft = slf.attribute[ATR_MANA];
        var int manaMax;    manaMax     = slf.attribute[ATR_MANA_MAX];
        var int manaRefill;
        if ( manaLeft < (manaMax/2) )
        {
            PrintDebugInt        (PD_ZS_CHECK,    "...Mana ьbrig: ", manaLeft);
            manaRefill =        (manaMax/2) - manaLeft;
            Npc_ChangeAttribute    (slf,    ATR_MANA,    manaRefill);
            PrintDebugInt        (PD_ZS_CHECK,    "...Mana hinzugefьgt: ", manaRefill);
        };
Daedalus:
        var int manaLeft;   manaLeft = slf.attribute[ATR_MANA];
        var int manaMax;    manaMax     = slf.attribute[ATR_MANA_MAX];
        if ( manaLeft < (manaMax/2))
        {
            slf.attribute[ATR_MANA] = manaMax/2;
        };

Daedalus:
//////////////////////////////////////////////////////////////////////////
//    B_DrawSpell
//    ===========
//    Zieht den angegebenen Spruch unter Berьcksichtigung, daЯ eventuell
//    vorher ein AI_UnreadySpell durchgefьhrt werden muЯ.
//////////////////////////////////////////////////////////////////////////
func void B_DrawSpell(var C_NPC slf, var int spell, var int mana)
{
    PrintDebugNpc                (PD_ZS_FRAME,    "B_DrawSpell");

    if (Npc_IsInFightMode(slf, FMODE_MAGIC))
    {
        PrintDebugNpc            (PD_ZS_CHECK,    "...bereits im Magiemodus!");
        if (Npc_GetActiveSpell(slf) != spell)
        {
            PrintDebugNpc        (PD_ZS_CHECK,    "...dieser Zauber liegt noch nicht auf der Hand!");
            AI_UnreadySpell        (slf);
// Das folgende AI_ReadySpell() verursacht den Kollisionsbug
// "only one moving vob without collision..." wenn die Funktion
// zweimal hintereinander aufgerufen wird, ohne ein
// AI_UnreadySpell dawzischen. Genau das ist aber nцtig
// wenn der NSC die Stдrke des Zaubers дndern will ohne
// den Zauber wegzustecken und wieder hervorzuholen!
        };
        AI_ReadySpell            (slf, spell, mana);
    }
    else
    {
        if (Npc_IsInFightMode(slf, FMODE_MELEE)||Npc_IsInFightMode(slf, FMODE_FIST))
        {
            AI_RemoveWeapon        (slf);
        };
        if (Npc_IsInFightMode(slf, FMODE_FAR))
        {
            AI_StopAim            (slf);
            AI_RemoveWeapon        (slf);
        };
      
        PrintDebugNpc            (PD_ZS_CHECK,    "...noch nicht im Magiemodus!");
        AI_ReadySpell            (slf, spell, mana);
    };

    //-------- "echte" Magier bekommen Mana dazugeschummelt --------
    if (slf.fight_tactic == FAI_HUMAN_MAGE)
    {
        PrintDebugNpc            (PD_ZS_CHECK,    "...Magier-Kampftaktik!");

        var int manaLeft;    manaLeft = slf.attribute[ATR_MANA];
        var int manaMax;    manaMax     = slf.attribute[ATR_MANA_MAX];
        var int manaRefill;
        if ( manaLeft < (manaMax/2) )
        {
            PrintDebugInt        (PD_ZS_CHECK,    "...Mana ьbrig: ", manaLeft);
            manaRefill =        (manaMax/2) - manaLeft; 
            Npc_ChangeAttribute    (slf,    ATR_MANA,    manaRefill);
            PrintDebugInt        (PD_ZS_CHECK,    "...Mana hinzugefьgt: ", manaRefill);
        };
    };
 
    return;
};


***

ElderGamer подскажи плиз:
кодвопрос
Daedalus:
if(Npc_IsInFightMode(slf,FMODE_MAGIC))
{
// Имеет место проблема досрочного появления визуального  
// эффекта нового заклинания при его смене.
// Раздельная деактивация заклинания и активация другого решает проблему.
Daedalus:
         if(Npc_GetActiveSpell(slf) != spell)
        {
            AI_UnreadySpell(slf);
            if(!Npc_IsInState(slf,ZS_Attack)) // Для монстров-магов и орков.
            {
                AI_ReadySpell(slf,spell,mana);
            };
        }
у тебя тут только для нелюдей это проверка? то есть можно ли её заменить на проверку по GIL_SEPERATOR_HUM что бы привычнее было.
Daedalus:
        else
        {
            AI_ReadySpell(slf,spell,mana);
        };
    }
так же не понял зачем у тебя выполняется этот кусок.
фактически это же значит что НПС уже держит нужны спелл
Daedalus:
if(Npc_GetActiveSpell(slf) == spell)
{
AI_ReadySpell(slf,spell,mana);
};
 
Последнее редактирование:

ElderGamer


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

у тебя тут только для нелюдей это проверка? то есть можно ли её заменить на проверку по GIL_SEPERATOR_HUM что бы привычнее было.
Проверка для нелюдей, да. Но к использованию фрагментов отсюда следует подходить с осторожностью. Там вариант кода формировался постепенно, методом проб и ошибок, и работает это с учётом других фрагментов кода, например, состояний атаки, в которых пребывают неписи.

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

Иногда, кстати, встречались случаи, когда нужно было в коде дважды прописать одно и то же действие, чтобы оно сработало.
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
1.923
Благодарности
926
Баллы
275
ElderGamer, спасибо за развёрнутый ответ. всё таки скрипты Г1 на голову выше скриптов Г2.

в B_DrawSpell используется mana которую будет инвестировать НПС. через это в том числе будет определён уровень заклинания которое кастуется НПС. соотв. в готики 1 идёт проверка на расстояние от НПС до цели и после этого кастуется условно заклинания 1 уровня, среднего или максимального уровня.
 
Сверху Снизу