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

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

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

MaGoth

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

Вложения

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

Диккен

Участник форума
Регистрация
12 Июн 2004
Сообщения
469
Благодарности
127
Баллы
210
Объясните, вот скрипт, к. позволяет мне пожарить по 10 кусков мяса, но при варианте:

Print(ConcatStrings(ItFoMuttonRaw.name,IntToString(Npc_HasItems(hero,ItFoMuttonRaw))));
Print(ConcatStrings(ItFoMutton.name,IntToString(Npc_HasItems(hero,ItFoMutton))));

после 1го цикла прожарки, где все нормально, на экране отсутствует строка ItFoMutton.name, пришлось вбивать её вручную. Причина? Я не совсем понимаю

Код:
func void player_hotkey_lame_heal()

{
    if(Npc_IsInState(hero,ZS_Dead) == FALSE)
    {
        if((Wld_GetMobState(hero,"STOVE") == 1) && (Npc_HasItems(hero,ItFoMuttonRaw) > 10))
        {
            if(Npc_HasItems(hero,ItFoMuttonRaw) >= 10)
            {
                Npc_RemoveInvItems(hero,ItFoMuttonRaw,10);
                CreateInvItems(hero,ItFoMutton,10);
          
                Print(ConcatStrings(ItFoMuttonRaw.name,IntToString(Npc_HasItems(hero,ItFoMuttonRaw))));
                Print(ConcatStrings("Жареное мясо ",IntToString(Npc_HasItems(hero,ItFoMutton))));
            }
            else
            {
                Print(ConcatStrings(PRINT_ProdItemsMissing,ItFoMuttonRaw.name));
                AI_UseMob(hero,"STOVE",-1);
            };
            return;
        };
 

ElderGamer


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

Диккен

Участник форума
Регистрация
12 Июн 2004
Сообщения
469
Благодарности
127
Баллы
210
Возможно, причина в том, что следует использовать временные переменные для хранения результатов объединения строк.
Этот вариант тоже не работает, мало того вывод текста по запросу Print(ItFoMutton.name); тоже не работает, другие инстанции доступны, кроме жаренного мяса, аномалия блин :)
 

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.367
Благодарности
7.815
Баллы
995
Этот вариант тоже не работает, мало того вывод текста по запросу Print(ItFoMutton.name); тоже не работает, другие инстанции доступны, кроме жаренного мяса, аномалия блин
Хм, как-то странно, это в Г1 ?!
Попробуй с конкатенацией строк, примерно так по аналогии:
Код:
{
    var string concatText;
    var string itemname;
        ...
        {
            concatText = ConcatStrings(IntToString(amount),PRINT_GoldErhalten);
            Print(concatText);
        }
        ...
        {
            concatText = ConcatStrings(itemname,PRINT_Addon_erhalten);
            Print(concatText);
        }
        else
        {
            concatText = ConcatStrings(IntToString(amount),PRINT_ItemsErhalten);
            concatText = ConcatStrings(concatText," (");
            concatText = ConcatStrings(concatText,itemname);
            concatText = ConcatStrings(concatText,")");
            Print(concatText);
        };
};

Иначе, используй функцию PrintScreen.
 

Диккен

Участник форума
Регистрация
12 Июн 2004
Сообщения
469
Благодарности
127
Баллы
210
Причина найдена, все работает как и положено по скрипту. Запустил новую игру, там все нормально, в старых сохранениях нет, а причина в том, что мне надоело прокручивать список до мяса и я присвоил ему метку напитков в середине игры, короче сам виноват.

name = "Жареное мясо ";
//mainflag = ITEM_KAT_FOOD;
mainflag = ITEM_KAT_POTIONS;

Хм, тоже не работает, ОДИН раз отображает после старта игры, потом пустота.

Хм, как-то странно, это в Г1 ?!
Да нет же, жарим у ПЛИТЫ, в 1й части только костер =))
 
Последнее редактирование:

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.367
Благодарности
7.815
Баллы
995
Ну да, со скриптами всегда новая игра желательна..
Если конечно ты предварительно в проект пустышек вариэйблов не заложил, для переменных и функций.. :)
Тогда можно и на сейвах сидеть, но не во всех 100% случаев..
 

Saturas


Модостроитель
Регистрация
11 Фев 2009
Сообщения
2.512
Благодарности
1.334
Баллы
315
Ужас, как страшно жить.
Код:
// получить ссылку на предмет, который имеет НПС npc с номером instanceItem.
func C_ITEM Npc_GetInvItem(var C_NPC npc, var int instanceItem);
Юзай эту функцию, чтоб получить ссылку на СУЩЕСТВУЮЩИЙ ПРЕДМЕТ, ибо ты получаешь ссылку почти всегда на рандомную область памяти.
 

Диккен

Участник форума
Регистрация
12 Июн 2004
Сообщения
469
Благодарности
127
Баллы
210
Юзай эту функцию, чтоб получить ссылку на СУЩЕСТВУЮЩИЙ ПРЕДМЕТ, ибо ты получаешь ссылку почти всегда на рандомную область памяти.
Точнее, в момент загрузки мира и до первого обращения к инстанции предмета через движок, в данном случае на плите используется жаренное мясо это была функция CreateInvItems(hero,ItFoMutton,10);, можно получить ссылку на искомую переменную, потом рандом.

Код:
Npc_GetInvItem(hero,ItFoMuttonRaw);
Print(ConcatStrings(item.name,IntToString(Npc_HasItems(hero,ItFoMuttonRaw))));
Npc_GetInvItem(hero,ItFoMutton);
Print(ConcatStrings(item.name,IntToString(Npc_HasItems(hero,ItFoMutton))));
 
Последнее редактирование:

Phantom95

Участник форума
Регистрация
31 Июл 2014
Сообщения
2.227
Благодарности
1.910
Баллы
370
Что нужно сделать, чтобы при нажатии на шифт активировалась функция mdsapplyoverlay(hero,"Humans_Sprint") , а при отпускании шифта она деактивировалась
 

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.407
Благодарности
3.232
Баллы
525
Вопрос к тем, кто, возможно, уже копался в этой области или имеет возможность заглянуть в функции движка. Чем отличаются функции Npc_SetAttitude и Npc_SetTempAttitude? Походу, и постоянное и временное отношение сбрасывается после загрузки сохранения. За основу принимается отношение между гильдиями. Так в чём фишка?
 

cool_er

Участник форума
Регистрация
23 Мар 2015
Сообщения
118
Благодарности
42
Баллы
190
Вопрос к тем, кто, возможно, уже копался в этой области или имеет возможность заглянуть в функции движка. Чем отличаются функции Npc_SetAttitude и Npc_SetTempAttitude? Походу, и постоянное и временное отношение сбрасывается после загрузки сохранения. За основу принимается отношение между гильдиями. Так в чём фишка?
Ну из явного могу сказать что отличаются они только изменяемыми переменными. Npc_SetAttitude модифицирует переменную с индексом 505, а Npc_SetTempAttitude с индексом 506. Если получится еще чего-нибудь узнать то добавлю здесь, или скину в личку.
 

Saturas


Модостроитель
Регистрация
11 Фев 2009
Сообщения
2.512
Благодарности
1.334
Баллы
315
Все обстоит немножко иначе.
По функциям выше:

Npc_SetAttitude - устанавливает постоянное отношение между нпс(когда гг становится врагом какой либо фракции, так сделано с монстрами например)
Npc_SetTempAttitude - устанавливает временное отношение, например мы украли что либо у непися, и он нас начинает бить, но через время(не помню по какому событию) оно сбрасывается.
Дальше, в случае загрузки сохранения все эти отношения сбрасываются, поскольку происходит повторная инициализация таблицы отношений между гильдиями.
На вопрос почему это работает с монстрами ответ очень прост, ибо отношения сними устанавливаются при каждой загрузке игры.
 

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.407
Благодарности
3.232
Баллы
525
но через время(не помню по какому событию) оно сбрасывается
Поэкспериментировал немного. Похоже, логика тут такая: примерно через 120 секунд после изменения временное отношение синхронизируется с постоянным (в Г1). Авторская задумка понятна. Жаль, что всё портит сохранение/загрузка. :(
 

Saturas


Модостроитель
Регистрация
11 Фев 2009
Сообщения
2.512
Благодарности
1.334
Баллы
315
Ну, это да, но можно через инит секцию сделать, и все ок будет.
 

ElderGamer


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

Можно, конечно, завести специальную аиврину для запоминания постоянного отношения и использовать её для восстановления отношения на уровне скриптовых функций ИИ. :confused:
 

Saturas


Модостроитель
Регистрация
11 Фев 2009
Сообщения
2.512
Благодарности
1.334
Баллы
315

Lorddemonik

★★★★★
Редактор раздела
Регистрация
17 Дек 2011
Сообщения
1.111
Благодарности
580
Баллы
350
А как изменить порог очков обучения ( силы,ловкости, управление оружием)когда с 1 очка за единицу навыка начинает требовать 2, 3 и т.д.
 

Dimus

★★★★★★★★★
Супермодератор
Регистрация
19 Июл 2010
Сообщения
5.574
Благодарности
4.167
Баллы
915
@lorddemonik1:
Надо изменить эти пороги в функциях B_GetLearnCostAttribute(var C_Npc oth,var int attribut) и B_GetLearnCostTalent(var C_Npc oth,var int talent,var int skill).
 

Lorddemonik

★★★★★
Редактор раздела
Регистрация
17 Дек 2011
Сообщения
1.111
Благодарности
580
Баллы
350
В процессе правки очков обучения, когда дошел до кругов наблюдал такую картину
func int b_getlearncosttalent_magic_circle(var C_Npc other,var int talent,var int skill)
{
var int kosten;
kosten = 0;
if(talent == NPC_TALENT_MAGE)
{
if(skill == 1)
{
if(XP_PER_MONSTERS == 10)
{
kosten = 5;
};
if(XP_PER_MONSTERS == 6)
{
kosten = 10;
};
}
else if(skill == 2)
{
if(XP_PER_MONSTERS == 10)
{
kosten = 10;
};
if(XP_PER_MONSTERS == 6)
{
kosten = 20;
};
}
else if(skill == 3)
{
if(XP_PER_MONSTERS == 10)
{
kosten = 15;
};
if(XP_PER_MONSTERS == 6)
{
kosten = 30;
};
}
else if(skill == 4)
{
if(XP_PER_MONSTERS == 10)
{
kosten = 20;
};
if(XP_PER_MONSTERS == 6)
{
kosten = 40;
};
}
else if(skill == 5)
{
if(XP_PER_MONSTERS == 10)
{
kosten = 25;
};
if(XP_PER_MONSTERS == 6)
{
kosten = 50;
};
}
else if(skill == 6)
{
if(XP_PER_MONSTERS == 10)
{
kosten = 30;
};
if(XP_PER_MONSTERS == 6)
{
kosten = 60;
};
};
};
return kosten;
};
Почему там 2 варианта требования очков обучения?
И зачем добавлять каждый раз файл ou.bin когда собираешь .mod?
 

Ziptar

Участник форума
Регистрация
13 Июл 2007
Сообщения
682
Благодарности
53
Баллы
200
В процессе правки очков обучения, когда дошел до кругов наблюдал такую картину
Почему там 2 варианта требования очков обучения?
И зачем добавлять каждый раз файл ou.bin когда собираешь .mod?
в ou.bin хранится текст диалогов

Про очки обучения - декомпил скриптов ребуса какого-нибудь? Я так понимаю XP_PER_MONSTERS == 10 это эквивалент уровня сложности.
Если я не прав - то поиск по всем файлам переменной XP_PER_MONSTERS и анализ контекста мест, где эта переменная встречается :)


Если ребус и именно декомпил - не забудь пофиксить скрипты для нормальной работы выноса.
 
Последнее редактирование:
Сверху Снизу