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

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

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

MaGoth

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

Вложения

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

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.002
Благодарности
971
Баллы
295
попробуй просто создать его в инстанции нпс без экипировки
 

neromont


Модостроитель
Регистрация
12 Мар 2011
Сообщения
675
Благодарности
662
Баллы
245
попробуй просто создать его в инстанции нпс без экипировки
Нет. Также эффект остается неактивным.

+ любое изменение времени ведет к отключению эффекта, т.е. Wld_SetTime() использовать нельзя. Тут 100% движок.

В общем пока решил так:

В инициализацию состояний распорядка дня вставил функции экипировки и снятия оружия.
Иногда происходит задержка, пока NPC не доберется до нужного WP, потом поковыряюсь в движке :)
 
Последнее редактирование:

neromont


Модостроитель
Регистрация
12 Мар 2011
Сообщения
675
Благодарности
662
Баллы
245
Как сделать так, чтобы на PC также срабатывало восприятие PERC_ASSESSDAMAGE?

Из-за этого, например, коготь Белиара не работает со стороны NPC, но работает, если его использует PC (я имею ввиду визуальные эффекты).

Что-то мне подсказывает, что также нужно залазить в движок.
 

D36


Модостроитель
Регистрация
3 Дек 2014
Сообщения
2.190
Благодарности
3.373
Баллы
485
Что-то мне подсказывает, что также нужно залазить в движок.
Ага.

Также эффект остается неактивным.
Копай в сторону самого эффекта. Лучше попробовать создать новый, на примере оригинального эффекта посоха:
Daedalus:
instance SPELLFX_MAGESTAFF1(CFX_BASE_PROTO)
{
    visname_s = "MAGESTAFF1";
    visalpha = 1;
    emtrjmode_s = "FIXED";
    emadjustshptoorigin = 1;
};
 

ILoveGothicII

Участник форума
Регистрация
9 Сен 2009
Сообщения
102
Благодарности
1
Баллы
165
подскажите, пожалуйста, чем декомпилировать и компилировать стимовскую Г2 (и Г1 тоже)? я пытался gothic sourcer 3.15, но он выдает ошибки, даже без изменений файлов
 

MEG@VOLT

★★★★★★★★★
ТехАдмин
Регистрация
24 Мар 2006
Сообщения
9.860
Благодарности
6.740
Баллы
1.625
подскажите, пожалуйста, чем декомпилировать и компилировать стимовскую Г2 (и Г1 тоже)? я пытался gothic sourcer 3.15, но он выдает ошибки, даже без изменений файлов
Оригинальные скрипты с ошибками.
Без правок они будут с ощибками компилироваться.
 

KirTheSeeker

Участник форума
Регистрация
18 Авг 2017
Сообщения
1.928
Благодарности
558
Баллы
275
Приветствую всех.
Прошу совета по внедрению данных плюшек в игру.
Добавил скрипт G_Wld_GetTime соответствующего содержания.
Daedalus:
// Функции определения времени от Nodrog //

func int Wld_GetMinute(var int Hour,var int from,var int till)
{
    if(from >= 60)
    {
        return -1;
    };
    if(Wld_IsTime(Hour,from+1,Hour,till))
    {
        return Wld_GetMinute(Hour,from+1,till);
    }
    else
    {
        return from;         
    };
    return from;
};

func int Wld_GetHour(var int from,var int till)
{
    if(from >= 24)
    {
        return -1;
    };
    if(Wld_IsTime(from+1,0,till,0))
    {
        return Wld_GetHour(from+1,till);
    }
    else
    {
        return from;
    };
    return from;
};

func int Wld_GetTime()
{
    var int h;
    //h = Wld_GetHour(0,23);
    //h = h*60 + Wld_GetMinute(h,0,59);
    //h = Wld_GetHour(0,24);
    //h = h*60 + Wld_GetMinute(h,0,60);
    h = Wld_GetHour(0,25);
    h = h*60 + Wld_GetMinute(h,0,61);
    h = h + Wld_GetDay() * 1440;
    return h;
};

Но далее мне непонятно как корректно добавить их применение в B_TeachAttributePoints.d ?
Daedalus:
func int B_TeachAttributePoints(var C_Npc slf,var C_Npc oth,var int attrib,var int points,var int teacherMAX)
{
    var string concatText;
    var int kosten;
    var int currentAttribute;
    var int t;
    if((attrib != ATR_STRENGTH) && (attrib != ATR_DEXTERITY) && (attrib != ATR_MANA_MAX))
    {
        Print(PRINT_WrongParameter);
        return FALSE;
    };
    currentAttribute = VisibleAttributeValue(attrib);
    if(currentAttribute == teacherMAX)
    {
        concatText = ConcatStrings(PRINT_NoLearnOverPersonalMAX,IntToString(teacherMAX));
        PrintScreen(concatText,-1,-1,FONT_Screen,2);
        B_Say(slf,oth,"$NOLEARNYOUREBETTER");
        return FALSE;
    };
    if(currentAttribute > teacherMAX)
    {
        concatText = ConcatStrings(PRINT_NoLearnOverPersonalMAX,IntToString(teacherMAX));
        PrintScreen(concatText,-1,-1,FONT_Screen,2);
        B_Say(slf,oth,"$YOULEARNEDSOMETHING");
        return FALSE;
    };
    if((currentAttribute + points) > teacherMAX)
    {
        concatText = ConcatStrings(PRINT_NoLearnOverPersonalMAX,IntToString(teacherMAX));
        PrintScreen(concatText,-1,-1,FONT_Screen,2);
        B_Say(slf,oth,"$NOLEARNOVERPERSONALMAX");
        return FALSE;
    };
    kosten = B_GetLearnCostAttribute(attrib,points);
    if(oth.lp < kosten)
    {
        PrintScreen(PRINT_NotEnoughLP,-1,-1,FONT_Screen,2);
        B_Say(slf,oth,"$NOLEARNNOPOINTS");
        return FALSE;
    };
    if(PremiumTeachersEnabled == TRUE)
    {
        if(!B_GiveInvItems(oth,slf,ItMi_Gold,kosten * PremiumTeachersPrice))
        {
            PrintScreen(Print_NotEnoughGold,-1,-1,FONT_Screen,2);
            DIA_Common_WeWillGetToThatLater();
            return FALSE;
        };
    };
    oth.lp -= kosten;
    B_RaiseAttributeByTraining(oth,attrib,points);
    // Вызов функции меняющей время в игре на + минут в зависимости от значения points
    t= Wld_GetMinute(0,25) + 60; // плюс один час

    if (!Wld_IsTime(0,0,t,0))
    {
        t = t + 24;
    };
    Wld_SetTime(t,0);
    return TRUE;
};
Текущий вариант не работает. Как корректно прописать изменение времени при обучении?
 

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.407
Благодарности
3.232
Баллы
525
Текущий вариант не работает.
Поскольку вставка в нём отличается от того, что посоветовал тебе MW 7. Ты зачем-то заменил одну функцию на другую. ;)

Daedalus:
Wld_SetTime(h,m);
В функции установки времени h - устанавливаемое значение часа, m - устанавливаемое значение минут.

Daedalus:
Wld_SetTime(16,5);
В таком варианте будет установлено 16:05 текущего дня.

Daedalus:
Wld_SetTime(40,5);
В таком варианте будет установлено 16:05 следующего дня (40 = 24 + 16).
 
Последнее редактирование:

KirTheSeeker

Участник форума
Регистрация
18 Авг 2017
Сообщения
1.928
Благодарности
558
Баллы
275
Поскольку вставка в нём отличается от того, что посоветовал тебе MW 7. Ты зачем-то заменил одну функцию на другую. ;)

Daedalus:
Wld_SetTime(h,m);
В функции установки времени h - устанавливаемое значение часа, m - устанавливаемое значение минут.

Daedalus:
Wld_SetTime(16,5);
В таком варианте будет установлено 16:05 текущего дня.

Daedalus:
Wld_SetTime(40,5);
В таком варианте будет установлено 16:05 следующего дня (40 = 24 + 16).

Я всё равно не понял. Мне нужно прописать, чтобы текущее время, при выборе прокачки атрибута на 1/5 ед., увеличивалось на 0.5/2 часа соответственно. Значит, функция должна выглядеть примерно так:
Wld_SetTime(h,m) = Wld_GetMinute + 30 [для 1 ед.]
Wld_SetTime(h,m) = Wld_GetHour + 2 [для 5 ед.]
Или как-то иначе?
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.002
Благодарности
971
Баллы
295
KirTheSeeker, что бы понять нужно двигаться от простой задачи к более сложной. нас так учили в школе, что сначало ты решаешь задачу медленно и тупо в пять действий, а когда уже набил руку начинаешь срезать углы и уменьшать кол-во действий. Пробуй сначала просто изменить время на 1 час. Это если ты хочешь понять, а если просто хочешь сделать не понимая, тут требуется другой набор слов ;-)
я вот например постоянно пытался что то объяснить, но итог всегда один: всё пропустить и попытаться сделать топорно методом тыка:) лучше определись что ты хочешь :) хочешь что бы за тебя писали код, заведи топик "напишите мне скрипт" и перестань бомбить топик с "вопросами по скрипту". я например по настроению могу продолжить что то пописывать :-D
 
Последнее редактирование:

KirTheSeeker

Участник форума
Регистрация
18 Авг 2017
Сообщения
1.928
Благодарности
558
Баллы
275
лучше определись что ты хочешь :)
Хочу, чтобы указанные функции работали чётко и грамотно. И не важно кем они будут написаны. Разумеется, желательно, чтобы код мог написать даже я. Потому и прошу максимально простых и прямых наставлений, для рядовых пользователей. Насколько понимаю, форум и нужен для того, чтобы люди могли доносить друг другу полезную информацию, облегчая процесс для всех в целом.

Поскольку вставка в нём отличается от того, что посоветовал тебе @MW 7. Ты зачем-то заменил одну функцию на другую. ;)
Если просто вставить, указанную функцию, то выдаёт ошибку:
3.png

Что тут не так?

В функции установки времени h - устанавливаемое значение часа, m - устанавливаемое значение минут.
Если эта установка конкретного времени, то где там определяется и указывается текущее?
Пост автоматически объединён:

Если просто вставить, указанную функцию, то выдаёт ошибку:
А, стоп, наверное нужно G_Wld_GetTime.d переместить по выше в списке загрузки. Сейчас попробую...

Нет, не помогло:
3.png

Что не так? Нужно дописать перед последней закрывающей скобкой "return"?
Нет, не похоже.
 
Последнее редактирование:

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.002
Благодарности
971
Баллы
295
Daedalus:
func int B_TeachAttributePoints(var C_Npc slf,var C_Npc oth,var int attrib,var int points,var int teacherMAX)
{
...
    oth.lp -= kosten;
    B_RaiseAttributeByTraining(oth,attrib,points);
    return TRUE;
};
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.002
Благодарности
971
Баллы
295
а эти две проверки будут давать один и тот де результат?
if (Hlp_GetInstanceID(self) == Hlp_GetInstanceID(hero)) if (Npc_IsPlayer(self) == true)
 

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.407
Благодарности
3.232
Баллы
525
Вроде бы, да. Только вот случаев, когда идентификатор self указывает на персонажа под управлением игрока, не очень много. А там, где это имеет место, иногда требуется проверить не то, что self указывает на персонажа под управлением игрока, а то, что персонаж под управлением игрока является главным героем в образе человека, то есть нужно проверить соответствие инстанции self с инстанцией главного героя PC_Hero.
 

MEG@VOLT

★★★★★★★★★
ТехАдмин
Регистрация
24 Мар 2006
Сообщения
9.860
Благодарности
6.740
Баллы
1.625
Они ни чем не отличаются.
Во время диалога - это одно и тоже.
Если игрок трансформирован - это одно и тоже.
Если игрок держит в руках какой-нить ножик - это одно и тоже.
Без разницы, игрок - это PC_plaeyr или другой непись.
В первой готе, может быть и по другому. Я проверял на Г2А:
Daedalus:
instance DIA_Sentenza_test(C_Info)
{
    npc = SLD_814_Sentenza;
    nr = 998;
    condition = DIA_Sentenza_test_Condition;
    information = DIA_Sentenza_test_Info;
    permanent = TRUE;
    description = "Кто я?";
};


func int DIA_Sentenza_test_Condition()
{
    return TRUE;
};

func void DIA_Sentenza_test_Info()
{
    if(Npc_HasItems(other,ItMw_BeliarWeapon_1H_01) == 0)
    {
        CreateInvItem(other,ItMw_BeliarWeapon_1H_01);
    };
    if (Hlp_GetInstanceID(other) == Hlp_GetInstanceID(hero))
    {
        Hlp_PrintConsole("-->  Dialog --> other == hero");
    };
    if (Npc_IsPlayer(other) == true)
    {
        Hlp_PrintConsole("-->  Dialog --> Npc_IsPlayer");
    };
    Hlp_PrintConsole("-->  End Dialog");
};

func void B_BeliarsWeaponSpecialDamage(var C_Npc oth,var C_Npc slf)
{
    var int DamageRandy;
    DamageRandy = 1;
    if(Hlp_GetInstanceID(oth) == Hlp_GetInstanceID(hero))
    {
        Hlp_PrintConsole("-->  B_BeliarsWeaponSpecialDamage --> other == hero");
        if(C_ScHasReadiedBeliarsWeapon() && (DamageRandy <= BeliarDamageChance))
        {
            if(slf.aivar[AIV_MM_REAL_ID] == ID_DRAGON_UNDEAD)
            {
                Wld_PlayEffect("spellFX_BELIARSRAGE",oth,oth,0,0,0,FALSE);
                B_MagicHurtNpc(slf,oth,100);
            }
            else if(slf.flags != NPC_FLAG_IMMORTAL)
            {
                Wld_PlayEffect("spellFX_BELIARSRAGE",slf,slf,0,0,0,FALSE);
                B_MagicHurtNpc(oth,slf,100);
            };
            Wld_PlayEffect("spellFX_BELIARSRAGE_COLLIDE",hero,hero,0,0,0,FALSE);
        };
        if(C_ScHasReadiedBeliarsWeapon() && (DamageRandy <= 50))
        {
            Wld_PlayEffect("spellFX_BELIARSRAGE_COLLIDE",hero,hero,0,0,0,FALSE);
        };
    };
    if(Npc_IsPlayer(oth) == true)
    {
        Hlp_PrintConsole("-->  B_BeliarsWeaponSpecialDamage --> Npc_IsPlayer");
        DamageRandy = Hlp_Random(1);
        if(C_ScHasReadiedBeliarsWeapon() && (DamageRandy <= BeliarDamageChance))
        {
            if(slf.aivar[AIV_MM_REAL_ID] == ID_DRAGON_UNDEAD)
            {
                Wld_PlayEffect("spellFX_INCOVATION_WHITE",oth,oth,0,0,0,FALSE);
                B_MagicHurtNpc(slf,oth,100);
            }
            else if(slf.flags != NPC_FLAG_IMMORTAL)
            {
                Wld_PlayEffect("spellFX_INCOVATION_WHITE",slf,slf,0,0,0,FALSE);
                B_MagicHurtNpc(oth,slf,100);
            };
            Wld_PlayEffect("spellFX_INCOVATION_WHITE",hero,hero,0,0,0,FALSE);
        };
        if(C_ScHasReadiedBeliarsWeapon() && (DamageRandy <= 50))
        {
            Wld_PlayEffect("spellFX_INCOVATION_WHITE",hero,hero,0,0,0,FALSE);
        };
    };
    Hlp_PrintConsole("-->  End SpecialDamage");
};
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.002
Благодарности
971
Баллы
295
Lorddemonik, не знаю где ты нашел это сообщение, но судя по всему этот сказочник обманул законы физики :) Не имеет значения константа или переменная - технически это одно и тоже. Суть тут в другом. Символ с данным именем действительно используется движком, но лишь один раз в момент инициализации множителя. Можно попробовать обойти эту систему оптимизации и вынудить движок считать значение каждый раз, добавив небольшой .patch файл в каталог игры.
Union:
#engine [G2A]
  #patch [Dynamic trade multiplier]
    HEX @0x00704719 = '90 90 90 90 90 90'
  #/patch
#/engine
а это он будет брать значение при загрузки мира? или во время торговли? или при инициализации торговли?
 

Gratt


Модостроитель
Регистрация
14 Ноя 2014
Сообщения
3.301
Благодарности
4.636
Баллы
625
При отрисовке стоимости на экран (каждый кадр) и передаче предмета.
 

Gratt


Модостроитель
Регистрация
14 Ноя 2014
Сообщения
3.301
Благодарности
4.636
Баллы
625
Значит движок не тот или смотришь цену торговца.
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.002
Благодарности
971
Баллы
295
движок Готика 2 аддон
Код:
func void DIA_TradeNPC_Info()
{
    Hlp_PrintConsole("DIA_TradeNPC_Info..");
    TRADE_VALUE_MULTIPLIER  = 1;
 
Сверху Снизу