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

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

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

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

MaGoth

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

Вложения

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

Xeдин


Модостроитель
Регистрация
3 Дек 2008
Сообщения
1.358
Благодарности
1.894
Баллы
335
MEG@VOLT, добавь
parser->DefineExternal("RX_DiaAddNpc", RX_DiaAddNpc, zPAR_TYPE_VOID, zPAR_TYPE_INSTANCE, 0);

Ликер ее в список не включил))

1698924396619.png
 

MEG@VOLT

★★★★★★★★★
ТехАдмин
Регистрация
24 Мар 2006
Сообщения
9.228
Благодарности
6.204
Баллы
1.565
Ликер ее в список не включил))
Ошибка пропала, но...
Если сделать вот так Вопросы по скриптингу
То получится полностью одно и тоже))
У второго непися текст выводится в 4й диалоговый бар, и непись, как и ГГ, не поворачиваются друг к другу ))
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
1.932
Благодарности
929
Баллы
275
MEG@VOLT, в скриптах RX_DiaAddNpc нужно отдавать ссылка на НПС. то есть сначала надо сделать гетнпс. или в скриптах завернуть эту функцию, добавив так же проверки на валид и деад.

скинь свежий dll
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
1.932
Благодарности
929
Баллы
275
Daedalus:
func void B_RX_DiaAddNpc (var int npcInstance)
{
    var C_Npc npc;
    npc = Hlp_GetNpc(npcInstance);
    if(Hlp_IsValidNpc(npc) && !Npc_IsDead(npc))
    {
        RX_DiaAddNpc(npc);
        ...
        ...
 

N1kX


Модостроитель
Регистрация
13 Ноя 2009
Сообщения
5.866
Благодарности
5.303
Баллы
910
Не думаю, что ликер делал эти доп проверки. Вот пример диалога с его функцией из Нового Баланса.
Код:
instance mil_miliz_sleep(NPC_DEFAULT)
instance vlk_fisher_sleeploc(NPC_DEFAULT)
instance pc_psionicquest_templatedialog_685(C_INFO)
{
    npc = Vlk_Fisher_Sleeploc;
    condition = pc_psionicquest_templatedialog_685_condition;
    information = pc_psionicquest_templatedialog_685_info;
    important = FALSE;
    permanent = TRUE;
    description = "Ты рыбак?";
};

func int pc_psionicquest_templatedialog_685_condition()
{
    return TRUE;
};

func void pc_psionicquest_templatedialog_685_info()
{
    var int rnd;
    rnd = Hlp_Random(2);
    rx_diaaddnpc(mil_miliz_sleep);
    rx_diastart(TRUE);
    AI_Output(other, self, "DIA_Addon_Farim_Hallo_15_00"); //Ты рыбак?
    if (rx_sl_fisherknowshero && rx_getchance(35))
    {
        if (rnd == 0)
        {
            rx_diasetactive(vlk_fisher_sleeploc);
            AI_Output(self, other, "DIA_FARIM_SL_EXACTLY"); //Именно так.
            rx_diastop();
            if (!rx_sleepfishdialog_0)
            {
                rx_sleepfishdialog_0 = TRUE;
                B_GivePlayerXP(50);
            };
            return;
        }
        else if (rnd == 1)
        {
            rx_diasetactive(vlk_fisher_sleeploc);
            AI_Output(self, other, "DIA_Addon_Farim_Add_11_01"); //А, это снова ты!
            AI_Output(self, other, "DIA_FARIM_FISHSOLO"); //Рыба!
            rx_diastop();
            if (!rx_sleepfishdialog_1)
            {
                rx_sleepfishdialog_1 = TRUE;
                B_GivePlayerXP(50);
            };
            return;
        };
    };
    rx_diasetactive(mil_miliz_sleep);
    AI_TurnToNpc(self, other);
    AI_Output(self, other, "DIA_FARIM_HEISFISHER"); //Он - рыбак!
    rx_diasetactive(vlk_fisher_sleeploc);
    if (!rx_sl_fisherknowshero)
    {
        AI_Output(self, other, "DIA_FARIM_KABAK"); //Эх, пойду-ка я в кабак.
    }
    else if (rnd == 0)
    {
        AI_Output(self, other, "DIA_FARIM_FISHSOLO"); //Рыба!
        if (!rx_sleepfishdialog_2) {
            rx_sleepfishdialog_2 = TRUE;
            B_GivePlayerXP(50);
        };
    }
    else if (rnd == 1)
    {
        AI_Output(self, other, "DIA_FARIM_KABAK"); // Эх, пойду-ка я в кабак.
        if (!rx_sleepfishdialog_3)
        {
            rx_sleepfishdialog_3 = TRUE;
            B_GivePlayerXP(50);
        };
    };
    rx_sl_fisherknowshero = TRUE;
    rx_diastop();
};
 
Последнее редактирование:

Xeдин


Модостроитель
Регистрация
3 Дек 2008
Сообщения
1.358
Благодарности
1.894
Баллы
335
У второго непися текст выводится в 4й диалоговый бар, и непись, как и ГГ, не поворачиваются друг к другу ))
Думаю лучше Ликера спросить, может что-то не хватает еще в логике.
 

MEG@VOLT

★★★★★★★★★
ТехАдмин
Регистрация
24 Мар 2006
Сообщения
9.228
Благодарности
6.204
Баллы
1.565
Добавилд в код RX_DiaStart();, не RX_DiaStart(TRUE/FALSE);
Потому что ругалось именно на TRUE/FALSE
Заработало почти как надо, у второго непися текст начал выводиться в первый диалоговый бар. Но поворота друг к другу нет...
 

MEG@VOLT

★★★★★★★★★
ТехАдмин
Регистрация
24 Мар 2006
Сообщения
9.228
Благодарности
6.204
Баллы
1.565
Ага.
parser->DefineExternal("RX_DiaStart", RX_DiaStart, zPAR_TYPE_VOID, 0); заменил на parser->DefineExternal("RX_DiaStart", RX_DiaStart, zPAR_TYPE_VOID, zPAR_TYPE_INT, 0);
На TRUE/FALSE рагуться перестало. Камера между неписями летать начала. Но не поворачиваются друг к другу. Но я думаю это фигня, можно и стандартными средствами обойтись.
Всем спасибо!
 

MEG@VOLT

★★★★★★★★★
ТехАдмин
Регистрация
24 Мар 2006
Сообщения
9.228
Благодарности
6.204
Баллы
1.565
там поворот закомментирован был. видимо специально.
Вроде нет))
1698927352688.png

Union:
    void oCNpc::AI_TurnToNPC(oCNpc* npc) {
        if (npc) {
            this->GetEM(FALSE)->OnMessage(new oCMsgMovement(oCMsgMovement::EV_TURNTOVOB, npc), this);
        }
    }
 

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.339
Благодарности
3.183
Баллы
525
проверки на валид и деад.
Думаю, этот список нужно расширить, поскольку ум игрока пытлив и непредсказуем. Потенциальный второй (третий и т. д.) собеседник может:
- лежать без сознания, побитый ГГ или кем-то другим;
- находиться в состоянии магического сна;
- удрать с места событий под воздействием магии или просто испугавшись ГГ;
- быть замороженным в глыбу льда и т. д. и т. п.
 

MEG@VOLT

★★★★★★★★★
ТехАдмин
Регистрация
24 Мар 2006
Сообщения
9.228
Благодарности
6.204
Баллы
1.565
ElderGamer, протестировал:
- лежать без сознания, побитый ГГ или кем-то другим;
Резко вскакивает
- находиться в состоянии магического сна;
Просыпается, вскакивает не резко.
- удрать с места событий под воздействием магии или просто испугавшись ГГ;
ГГ поворачивается по направлению к убегающему неписю, ничего не слышно, ничего на экран не выводится, проходит стандартные 5 секунд, поворачиваемся к следующему НПС, который не под воздействием.
- быть замороженным в глыбу льда и т. д. и т. п.
Резко оттаивает.
Если непись мертвый, то ГГ к нему поворачивается, и тут же отворачивается, диалог продолжает следующий непись.
 

RPD

Участник форума
Регистрация
13 Ноя 2023
Сообщения
76
Благодарности
2
Баллы
20
Такой вопрос. Я пытался добавить новое восприятие, чтобы определенный НПС всегда добивал ГГ, добавил также восприятие в нормальный и минимальный набор восприятий, но не работает. Также не очень понятно, как конкретно работают в восприятиях other и victim
Пост автоматически объединён:

Вообще у меня много вопросов накопилось :) Например, я уже все испробовал, но так и не допер, почему НПС не кастует заклинание. Даешь ему руну, пишешь readyspell, а дальше? Дальше он просто берет в руки заклинание, а затем сразу переключается на милишку)
Пост автоматически объединён:

Также я добавил новые SVM аудио, новый voice. Все работает, кроме звука смерти и звуков получения урона, тоже непонятно почему.
 

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.339
Благодарности
3.183
Баллы
525
Также я добавил новые SVM аудио, новый voice. Все работает, кроме звука смерти и звуков получения урона, тоже непонятно почему.
Есть звуки, которые прописаны в сценариях соответствующих анимаций. Инстанции для таких звуков прописаны в скриптах звуковых эффектов SFX.DAT. SVM - это звуки, воспроизводимые из скриптов.

Я пытался добавить новое восприятие, чтобы определенный НПС всегда добивал ГГ
Звучит дико, но, возможно, ты просто неправильно описал свои действия. Приведи пример того, что ты сделал.

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

почему НПС не кастует заклинание
Опять же, приведи пример своего кода. Если тебе нужен непись-маг, делай его по образцу других магов. Но, судя по всему, у тебя другая задача.
 

RPD

Участник форума
Регистрация
13 Ноя 2023
Сообщения
76
Благодарности
2
Баллы
20
Есть звуки, которые прописаны в сценариях соответствующих анимаций. Инстанции для таких звуков прописаны в скриптах звуковых эффектов SFX.DAT. SVM - это звуки, воспроизводимые из скриптов.
За это большое спасибо, еще поковыряюсь.
Звучит дико, но, возможно, ты просто неправильно описал свои действия. Приведи пример того, что ты сделал.
Уже решил проблему, просто добавил проверку в Z_Attack , что если непись == мой конкретный, то он обязательно протыкает жертву вне зависимости от причины атаки.
В планах добавить такую же проверку к остальным проявлениям. Единственное, что интересно - как заставить нпс нападать первым, причем на всех абсолютно при их виде. Пока была идея просто создать новую гильдию и сделать враждебной ко всем остальным, но может есть способ легче? просто для конкретного нпс прописать такое
Произошло событие - один персонаж ударил другого персонажа. Производится посылка восприятия всем неписям в некотором радиусе от точки события. В этой посылке other - это тот, кто ударил, victim - это тот, кого ударили.
Опять же спасибо!
Опять же, приведи пример своего кода. Если тебе нужен непись-маг, делай его по образцу других магов. Но, судя по всему, у тебя другая задача.
Нет, нужен просто нпс, который будет только кастовать определенную руну. (ну может чередовать с милишкой, но это сложнее). По факту это все.
Я сделал следующее:
1699912165241.png

Ну и вот после B_ReadySpell() нпс берет руну в руки и стоит на месте, втыкает.
 
Последнее редактирование:

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
1.932
Благодарности
929
Баллы
275
Нет, нужен просто нпс, который будет только кастовать определенную руну
тебе лучше этого НПС прописать в B_SelectSpell
1699926209583.png
Daedalus:
func int B_SelectSpell (var C_NPC slf, var C_NPC oth)
{
        ...
        if (Hlp_GetInstanceID(slf) == Hlp_GetInstanceID(Gil_666_Nikita)) // это новый НПС
        {
            if (Npc_HasItems (slf, ItRu_Firerain) == 0)
            {
                CreateInvItems (slf, ItRu_Firerain, 1);
            };
            B_ReadySpell (slf, SPL_FireRain, 0); // не будет отнимать ману
            return TRUE;
        }
        ...
}
тогда при при атаке кого либо у Gil_666_Nikita будет срабатывать активация заклинания внутри цикла ZS_Attack_Loop , то есть

ZS_Attack(ZS_Attack_Loop) --> B_SelectWeapon --> B_SelectSpell

твоему новому нпс в инстанцию лучше прописать аивер

Daedalus:
aivar[AIV_MagicUser] = MAGIC_ALWAYS;

p.s.

посмотрел сейчас на ZS_Attack_Loop и плакать захотелось от "планов внутри планов".
«Планы внутри планов, и в них опять планы, и в них — новые планы, — подумала Джессика. — Не стали ли мы теперь сами частью чьих-то планов
Daedalus:
unc int ZS_Attack_Loop ()
{

    ...
 
    if (C_BodyStateContains(slf,BS_FALL))
    || (C_BodyStateContains(slf,BS_SWIM))
    || (C_BodyStateContains(slf,BS_DIVE))
    {
        // НПС НЕ НАДО пытаться достать оружие или СПЕЛЛ
    }
    else if B_SelectSpell(slf, oth)
    {
        // НПС достал СПЕЛЛ
    }
    else
    {
        // НПС будет пытаться достать оружие
        B_SelectWeapon(slf, oth);
    };
 
    ...
 
Последнее редактирование:

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
1.932
Благодарности
929
Баллы
275
p.s.s.
можно и такую конструкцию использовать что бы сократить код и исключить опечатки беря необходимые данные напрямую из инстанции руны/свитка.

Daedalus:
func int B_ReadyRune(var C_NPC slf, var int rune)
{
    if (!Npc_GetInvItem(slf, rune))
    {
        CreateInvItem(slf, rune);
    };
    // Hlp_PrintConsole(Str_Format("  B_ReadyRune[%s.%i]  --> rune %s", slf.name, slf.id,item.description));
    // можно еще проверить хватает ли круга магии
    var int SpellId;    SpellId = item.spell;
    var int SpellMana;  SpellMana = item.COUNT[1]; // для ночь ворона лучше использовать 0, так как мана НПС увеличивается в соседней функции
 
    B_ReadySpell(slf, SpellId, SpellMana);
    return TRUE;
};

тогда

Daedalus:
func int B_SelectSpell (var C_NPC slf, var C_NPC oth)
{
        ...
        if (Hlp_GetInstanceID(slf) == Hlp_GetInstanceID(Gil_666_Nikita)) // это новый НПС
        {
            return B_ReadyRune(slf, ItRu_Firerain); // B_ReadyRune возвращает true
        };
        ...
};
 
Последнее редактирование:

RPD

Участник форума
Регистрация
13 Ноя 2023
Сообщения
76
Благодарности
2
Баллы
20
p.s.s.
можно и такую конструкцию использовать что бы сократить код и исключить опечатки беря необходимые данные напрямую из инстанции руны/свитка.

Daedalus:
func int B_ReadyRune(var C_NPC slf, var int rune)
{
    if (!Npc_GetInvItem(slf, rune))
    {
        CreateInvItem(slf, rune);
    };
    // Hlp_PrintConsole(Str_Format("  B_ReadyRune[%s.%i]  --> rune %s", slf.name, slf.id,item.description));
    // можно еще проверить хватает ли круга магии
    var int SpellId;    SpellId = item.spell;
    var int SpellMana;  SpellMana = item.COUNT[1]; // для ночь ворона лучше использовать 0, так как мана НПС увеличивается в соседней функции
 
    B_ReadySpell(slf, SpellId, SpellMana);
    return TRUE;
};

тогда

Daedalus:
func int B_SelectSpell (var C_NPC slf, var C_NPC oth)
{
        ...
        if (Hlp_GetInstanceID(slf) == Hlp_GetInstanceID(Gil_666_Nikita)) // это новый НПС
        {
            return B_ReadyRune(slf, ItRu_Firerain); // B_ReadyRune возвращает true
        };
        ...
};
Спасибо. Теперь НПС действительно кастует заклы, но появилась другая проблема - при других восприятиях, по типу реакции на урон или поднятый меч - нпс стоит и тупит после проигрывания всех фраз, не атакует
[/QUOTE]
Пост автоматически объединён:

Спасибо. Теперь НПС действительно кастует заклы, но появилась другая проблема - при других восприятиях, по типу реакции на урон или поднятый меч - нпс стоит и тупит после проигрывания всех фраз, не атакует
 
Сверху Снизу