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

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

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

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

MaGoth

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

Вложения

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

neromont


Модостроитель
Регистрация
12 Мар 2011
Сообщения
674
Благодарности
655
Баллы
245
Вставляем ГГ в зону действия триггера и в ней выполняем анимацию?
 

MEG@VOLT

★★★★★★★★★
ТехАдмин
Регистрация
24 Мар 2006
Сообщения
9.174
Благодарности
6.153
Баллы
1.565
Вставляем ГГ в зону действия триггера и в ней выполняем анимацию?
Да, ток не в зону. Триггер можно хоть куда вставить.
Просто в стартапе пропиши выполнение этого тригера
 

MEG@VOLT

★★★★★★★★★
ТехАдмин
Регистрация
24 Мар 2006
Сообщения
9.174
Благодарности
6.153
Баллы
1.565
Ну, либо в том же стартапе, еще одну функцию, где и аниму пропиши*sorry*
 

neromont


Модостроитель
Регистрация
12 Мар 2011
Сообщения
674
Благодарности
655
Баллы
245
Ну, либо в том же стартапе, еще одну функцию, где и аниму пропиши*sorry*

Да я вроде пробовал анимацию для ГГ вынести в отдельную функцию, но что-то не пошло.
Ну попробуем снова.
 

N1kX


Модостроитель
Регистрация
13 Ноя 2009
Сообщения
5.847
Благодарности
5.274
Баллы
910
Для теста попробуй сделать триггер-скрипт с вызовов тестовой функции
Daedalus:
func void TESTANI()
{
    Print("Анимация начата");
    Npc_PlayAni(hero,"T_1HSFREE");
};

Ну и в консоле вызвать ztrigger Имя триггер-скрипта


Если анимация будет запущена, создавай циклический триггер-скрипт, где будешь однократно вызывать свою анимацию при начале новой игры.
Можно ещё свободный aivar добавить, который обезопасит от сейф/лоад и будет присваиваться только при начале новой игры.
 

Test Level

Участник форума
Регистрация
1 Ноя 2011
Сообщения
1.771
Благодарности
557
Баллы
275
Можно глянуть на примере землетрясения, после определенных фраз в диалогах, только юзать аним.
 

Test Level

Участник форума
Регистрация
1 Ноя 2011
Сообщения
1.771
Благодарности
557
Баллы
275
А, ну я уж и не помню, хотя когда-то именно там и глядел.
 

Raven25

Участник форума
Регистрация
18 Дек 2018
Сообщения
186
Благодарности
74
Баллы
190
Здрасьте. Проблема такова, при старте игры все нпс держат оружие как новички, хотя я прописал им уровень боец, даже для проверки мастера делал но как назло проблема не исчезает, но после того как сохранился и загрузился персонаж начинает использовать анимация владения оружия которую я прописал. Болванку скриптов я использовал от Нефариуса.
 

N1kX


Модостроитель
Регистрация
13 Ноя 2009
Сообщения
5.847
Благодарности
5.274
Баллы
910
Используй либо этот B_AddfightSkill
Daedalus:
func void B_AddFightSkill(var C_Npc slf,var int talent,var int percent)
{
    if(talent == NPC_TALENT_1H)
    {
        slf.HitChance[NPC_TALENT_1H] += percent;
        if(slf.HitChance[NPC_TALENT_1H] >= 60)
        {
            Npc_SetTalentSkill(slf,NPC_TALENT_1H,2);
            Mdl_ApplyOverlayMds(slf,"humans_1hST2.mds");
        }
        else if(slf.HitChance[NPC_TALENT_1H] >= 30)
        {
            Npc_SetTalentSkill(slf,NPC_TALENT_1H,1);
            Mdl_ApplyOverlayMds(slf,"humans_1hST1.mds");
        }
        else
        {
            Npc_SetTalentSkill(slf,NPC_TALENT_1H,0);
            Mdl_RemoveOverlayMds(slf,"humans_1hST1.MDS");
            Mdl_RemoveOverlayMds(slf,"humans_1hST2.MDS");
        };
    };
    if(talent == NPC_TALENT_2H)
    {
        slf.HitChance[NPC_TALENT_2H] += percent;
        if(slf.HitChance[NPC_TALENT_2H] >= 60)
        {
            Npc_SetTalentSkill(slf,NPC_TALENT_2H,2);
            Mdl_ApplyOverlayMds(slf,"humans_2hST2.mds");
        }
        else if(slf.HitChance[NPC_TALENT_2H] >= 30)
        {
            Npc_SetTalentSkill(slf,NPC_TALENT_2H,1);
            Mdl_ApplyOverlayMds(slf,"humans_2hST1.mds");
        }
        else
        {
            Npc_SetTalentSkill(slf,NPC_TALENT_2H,0);
            Mdl_RemoveOverlayMds(slf,"humans_2hST1.MDS");
            Mdl_RemoveOverlayMds(slf,"humans_2hST2.MDS");
        };
    };
    if(talent == NPC_TALENT_BOW)
    {
        slf.HitChance[NPC_TALENT_BOW] += percent;
        if(slf.HitChance[NPC_TALENT_BOW] >= 60)
        {
            Npc_SetTalentSkill(slf,NPC_TALENT_BOW,2);
            Mdl_ApplyOverlayMds(slf,"humans_bowT2.mds");
        }
        else if(slf.HitChance[NPC_TALENT_BOW] >= 30)
        {
            Npc_SetTalentSkill(slf,NPC_TALENT_BOW,1);
            Mdl_ApplyOverlayMds(slf,"humans_bowT1.mds");
        }
        else
        {
            Npc_SetTalentSkill(slf,NPC_TALENT_BOW,0);
            Mdl_RemoveOverlayMds(slf,"humans_bowT1.MDS");
            Mdl_RemoveOverlayMds(slf,"humans_bowT2.MDS");
        };
    };
    if(talent == NPC_TALENT_CROSSBOW)
    {
        slf.HitChance[NPC_TALENT_CROSSBOW] += percent;
        if(slf.HitChance[NPC_TALENT_CROSSBOW] >= 60)
        {
            Npc_SetTalentSkill(slf,NPC_TALENT_CROSSBOW,2);
            Mdl_ApplyOverlayMds(slf,"humans_cbowT2.mds");
        }
        else if(slf.HitChance[NPC_TALENT_CROSSBOW] >= 30)
        {
            Npc_SetTalentSkill(slf,NPC_TALENT_CROSSBOW,1);
            Mdl_ApplyOverlayMds(slf,"humans_cbowT1.mds");
        }
        else
        {
            Npc_SetTalentSkill(slf,NPC_TALENT_CROSSBOW,0);
            Mdl_RemoveOverlayMds(slf,"humans_cbowT1.MDS");
            Mdl_RemoveOverlayMds(slf,"humans_cbowT2.MDS");
        };
    };
};
или обновленный от NicoDE (Один из авторов G2MDK)
Daedalus:
func void B_AddFightSkill(var C_NPC npc, var int tal, var int add)
{
    var int hit;
    var string mds;
    mds = "HUMANS";  //FIXME: NPCs mit anderem Modell als HUMANS.MDS
    if (tal == NPC_TALENT_1H) {
        npc.HitChance[NPC_TALENT_1H] += add;
        hit = npc.HitChance[NPC_TALENT_1H];
        mds = ConcatStrings(mds, "_1HST");
    } else if (tal == NPC_TALENT_2H) {
        npc.HitChance[NPC_TALENT_2H] += add;
        hit = npc.HitChance[NPC_TALENT_2H];
        mds = ConcatStrings(mds, "_2HST");
    } else if (tal == NPC_TALENT_BOW) {
        npc.HitChance[NPC_TALENT_BOW] += add;
        hit = npc.HitChance[NPC_TALENT_BOW];
        mds = ConcatStrings(mds, "_BOWT");
    } else if (tal == NPC_TALENT_CROSSBOW) {
        npc.HitChance[NPC_TALENT_CROSSBOW] += add;
        hit = npc.HitChance[NPC_TALENT_CROSSBOW];
        mds = ConcatStrings(mds, "_CBOWT");
    } else {
        return;
    };
    var int old;
    var int val;
    old = Npc_GetTalentSkill(npc, tal);
    if (hit >= 60) {
        val = 2;
    } else if (hit >= 30) {
        val = 1;
    } else {
        val = 0;
    };
    if (val < old) {
        // Beim Verlernen aktives Overlay entfernen.
        mds = ConcatStrings(mds, IntToString(old));
        mds = ConcatStrings(mds, ".MDS");
    //    PrintScreen(ConcatStrings("remove ", mds), -1, -1, "", 3);
        Mdl_RemoveOverlayMds(npc, mds);
    };
    Npc_SetTalentSkill(npc, tal, val);
};
В Union вроде сброс оверлеев пофикшен.
 

Raven25

Участник форума
Регистрация
18 Дек 2018
Сообщения
186
Благодарности
74
Баллы
190
B_AddfightSkill() есть, В_SetFightSkills() вызывает -> B_RaiseFightTalent() -> B_AddFightSkill()
Пост автоматически объединён:

вот пример кода
instance BAU_01_GANZA(Npc_Default)
{
name[0] = "Γΰνηΰ";
guild = GIL_BAU;
npcType = npctype_main;
flags = 0;
id = 1;
level = 20;
voice = 5;
attribute[ATR_STRENGTH] = 40;
attribute[ATR_DEXTERITY] = 40;
attribute[ATR_MANA_MAX] = 10;
attribute[ATR_MANA] = 10;
attribute[ATR_HITPOINTS_MAX] = 100;
attribute[ATR_HITPOINTS] = 100;
fight_tactic = FAI_HUMAN_STRONG;
EquipItem(self,ItMw_Nagelknueppel);
EquipItem(self,ItRw_Sld_Bow);
EquipItem(self,ItMi_Lute);
CreateInvItems(self,ItRw_Arrow,40);
Mdl_SetModelFatness(self,1.15);
Mdl_ApplyOverlayMds(self,"Humans_Militia.mds");
B_SetNpcVisual(self,MALE,"Hum_Head_Thief",Face_N_Fingers,BodyTex_N,itar_test_02);
B_SetFightSkills(self,50);
daily_routine = rtn_start_01;
};
 

N1kX


Модостроитель
Регистрация
13 Ноя 2009
Сообщения
5.847
Благодарности
5.274
Баллы
910
Оригинальный не подходит, потому что функция Npc_SetTalentSkill тупит при присвоении нужного оверлея (срабатывает после сейф-лоад или через какое-то время), поэтому либо назначается принудительно, или правильной функцией. Замени ее у себя и убедись в этом
 

neromont


Модостроитель
Регистрация
12 Мар 2011
Сообщения
674
Благодарности
655
Баллы
245
Напиши прим
Оригинальный не подходит, потому что функция Npc_SetTalentSkill тупит при присвоении нужного оверлея (срабатывает после сейф-лоад или через какое-то время), поэтому либо назначается принудительно, или правильной функцией. Замени ее у себя и убедись в этом

А в оригинале ведь работает. Или к тому времени как доходим до первого Npc все прогружается?

P.S. Нужно будет дополнить статью этой информацией.
 

N1kX


Модостроитель
Регистрация
13 Ноя 2009
Сообщения
5.847
Благодарности
5.274
Баллы
910
Если идти честно в Г2 от башни Ксардаса до Кавалорна/Лестера то успевает все сработать. Если ТП к ним, то в драке они будут сражаться как новички. Через какое-то игровое время (я не считал), им присваиваются нормальные оверлеи.
Подробнее, а также пост от NicoDE есть тут
 

Vlad_Torop

Участник форума
Регистрация
2 Май 2014
Сообщения
868
Благодарности
498
Баллы
230
Оригинальный не подходит, потому что функция Npc_SetTalentSkill тупит при присвоении нужного оверлея (срабатывает после сейф-лоад или через какое-то время), поэтому либо назначается принудительно, или правильной функцией. Замени ее у себя и убедись в этом
Я тут немного недопонял. NpcSetTalentSkill лучше вообще не использовать? Даже в инстанциях нпс?
 

neromont


Модостроитель
Регистрация
12 Мар 2011
Сообщения
674
Благодарности
655
Баллы
245
Да все работает. Только через определенное время. Можешь скрипт немного переписать чтобы "насильственно" применять нужный оверлей.
Обычно в начале игры редко появляются сильные Npc.
 

N1kX


Модостроитель
Регистрация
13 Ноя 2009
Сообщения
5.847
Благодарности
5.274
Баллы
910
Хм, заинтересовал вопрос.
У класса C_NPC есть поле flags, в этом поле в скриптах может добавляться 3 значения
0
NPC_FLAG_IMMORTAL
NPC_FLAG_GHOST
Так вот, в скриптах много где, при смене флага у НПС делается так (Например)
npc.flags = 0;

А не правильнее делать это битовыми операциями? Движок же может присваивать свои флаги, которые не прописаны в константах
npc.flags = 0; - по сути обнуляет все флаги с этого НПС, а может НПС был ещё призраком? Тогда эффект призрака спадет

Правильно думается мне надо делать так (подправьте если что)
npc.flags = npc.flags & ~NPC_FLAG_IMMORTAL; - удалить флаг бессмертия (Остаются движковые флаги и НПС смертен)
npc.flags = npc.flags | NPC_FLAG_IMMORTAL; - добавить флаг бессмертия (Остаются движковые флаги и НПС бессмертен)
Тогда и проверки должны выглядеть вот так
(npc.flags & ~NPC_FLAG_IMMORTAL) != NPC_FLAG_IMMORTAL;

Имеет ли смысл заморачиваться и что-то там делать?
 

MEG@VOLT

★★★★★★★★★
ТехАдмин
Регистрация
24 Мар 2006
Сообщения
9.174
Благодарности
6.153
Баллы
1.565
N1kX, не, я с этими флагами игрался в свое время.
npc.flag=0 дает нормальный результат, т.е. НПС становится смертным, если ранее был френдом-имморталом, или френдом-гёстем, или просто имморталом или гёстом...
т.е. 2 флага не повесить, ну по крайней мере 10 лет назад у меня не получилось))
 

N1kX


Модостроитель
Регистрация
13 Ноя 2009
Сообщения
5.847
Благодарности
5.274
Баллы
910
Daedalus:
instance NONE_ADDON_111_Quarhodron(Npc_Default)
{
    name[0] = "Куархадрон";
    guild = GIL_NONE;
    id = 111;
    voice = 11;
    flags = NPC_FLAG_GHOST | NPC_FLAG_IMMORTAL;
    npcType = NPCTYPE_FRIEND;
    aivar[AIV_ToughGuy] = TRUE;
    aivar[AIV_ToughGuyNewsOverride] = TRUE;
    aivar[AIV_IGNORE_Murder] = TRUE;
    aivar[AIV_IGNORE_Theft] = TRUE;
    aivar[AIV_IGNORE_Sheepkiller] = TRUE;
    aivar[AIV_IgnoresArmor] = TRUE;
    aivar[AIV_NoFightParker] = TRUE;
    B_SetAttributesToChapter(self,6);
    fight_tactic = FAI_HUMAN_MASTER;
    B_SetNpcVisual(self,MALE,"Hum_Head_Psionic",Face_N_Corristo,BodyTex_N,ITAR_Raven_Addon);
    Mdl_SetModelFatness(self,2);
    Mdl_ApplyOverlayMds(self,"Humans_Arrogance.mds");
    B_GiveNpcTalents(self);
    B_SetFightSkills(self,80);
    aivar[AIV_MagicUser] = MAGIC_ALWAYS;
    daily_routine = Rtn_Start_111;
};
У призрачных знакомых 2 флага и такое снятие снимает все флаги, а не те, которые нужны.
 

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.371
Благодарности
7.802
Баллы
995
MEG@VOLT, любые значения, логически обоснованные, и присваиваемые чему любо могут быть навешаны через запись разделяемую вертикальной чертой.
это правило верно и применимо для всего скриптового движка..
 
Сверху Снизу