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

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

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

MaGoth

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

Вложения

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

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.003
Благодарности
973
Баллы
295
отсутствует общая целостная концепция с вытекающими из неё правилами. каждый новый частный случай ты пытаешь заново объяснить. в конечном итоге на уровне скриптов это приведёт к конфликту и всё начнёт сыпаться, так скрипты базируются на правилах, а не на исключениях из них. после каждого нового случая ты будешь вводить новые правила(уточняя прошлые) и это приведёт к конфликту.
самый простой пример это реализация бонусов от колец в готики 2 классик, что привело в итоге к появлению в аддоне у каждого(!) нпс истинных параметров, то есть те что не учитывают бонус от бижутерии. сделано это было не в рамках какой то новой концепции что кольца как то иначе работают, а именно для того что бы закрыть баг с бонусами от колец которые ломались при использование свитков превращениях и иных механик игры, из-за чего атрибуты героя навсегда изменялись. это правка пираней вызвала череду новых правок в различных модах и как следствие спекуляций на тему того что вот кольца/скрижали должны или не влиять на стоимость прокачки учителей или не учитываться при чём то там и так далее и тому подобное, потому что на самом деле они бла бла.
т.е. фактически изначально речь шла о фиксе бага, а следствие этого можно наблюдать и в архолос и в твоём проекте. что приводит к увеличению множеств и взаимных конфликтам уже на уровне скриптов. это если кратко. отсюда простой вывод: делай описание своего баланса и закономерности выноси в правила. иначе это всё будет "фикситься" и переписываться и снова и снова.

ATR_PermBonus[...] и т.д. прописаны именно в B_NewTalentSystem.d.
они прописаны в другом файле.
тут я ошибся. должно быть.
if C_NpcIsHero(npc)
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.003
Благодарности
973
Баллы
295
в своём файле вот это
Daedalus:
func int sPerm_Attr_KTS_Hero_talent(var int talent, var int percent)
{
    // Значение силы ГГ без учёта бонусов от надетых колец и амулета.
    var int sPerm_STR_KTS;
    sPerm_STR_KTS = ATR_Training[ATR_STRENGTH] + ATR_PermBonus[ATR_STRENGTH];
    
    var int sPerm_DEX_KTS;
    sPerm_DEX_KTS = ATR_Training[ATR_DEXTERITY] + ATR_PermBonus[ATR_DEXTERITY];
замени на

Daedalus:
func int sPerm_Attr_KTS_Hero_talent(var int talent, var int percent)
{
   
    b_sPerm_Attr_KTS_Hero();
 

KirTheSeeker

Участник форума
Регистрация
18 Авг 2017
Сообщения
1.928
Благодарности
558
Баллы
275
Приветствую всех, давно не виделись.
Вопрос по скриптам неоф. обновления Г2НВ. Подскажите, пожалуйста, в какой из функций данных скриптов прописано прерывание взаимодействия с закрытым замком, когда ГГ израсходовал запас отмычек?
Daedalus:
func void G_PickLock(var int bSuccess,var int bBrokenOpen)
{
    var int rnd;
    if(bSuccess)
    {
        if(bBrokenOpen)
        {
            TotalLocksPicked += 1;
            //Snd_Play3d(self,"PICKLOCK_UNLOCK");
            //Print(PRINT_PICKLOCK_UNLOCK);
        }
        else
        {
            Snd_Play3d(self,"PICKLOCK_SUCCESS");
            Print(PRINT_PICKLOCK_SUCCESS);
        };
    }
    else if(bBrokenOpen)
    {
        Snd_Play3d(self,"PICKLOCK_BROKEN");
        Print(PRINT_PICKLOCK_BROKEN);
        rnd = Hlp_Random(100);
        if(rnd <= 25)
        {
            Npc_SendPassivePerc(hero,PERC_ASSESSQUIETSOUND,hero,hero);
        };
    }
    else
    {
        Snd_Play3d(self,"PICKLOCK_FAILURE");
        Print(PRINT_PICKLOCK_FAILURE);
    };
};
Daedalus:
func void player_mob_missing_key_or_lockpick()
{
    Print(PRINT_Picklock_or_KeyMissing);
    AI_PlayAni(self,"T_DONTKNOW");
    B_Say_Overlay(self,self,"$PICKLOCKORKEYMISSING");
};

func void player_mob_missing_key()
{
    var int rnd;
    rnd = Hlp_Random(2);
    AI_PlayAni(self,"T_DONTKNOW");
    if(rnd == 0)
    {
        Print(PRINT_KeyMissing);
        B_Say_Overlay(self,self,"$KEYMISSING");
    }
    else if(rnd == 1)
    {
        Print("Здесь мне нужен ключ...");
        B_Say_Overlay(self,self,"$NEEDKEY");
    };
};

func void player_mob_missing_lockpick()
{
    var int rnd;
    if(!Npc_GetTalentSkill(hero,NPC_TALENT_PICKLOCK))
    {
        Print(PRINT_NoPicklockTalent);
        AI_PlayAni(self,"T_DONTKNOW");
        B_Say_Overlay(self,self,"$NOPICKLOCKTALENT");
    }
    else
    {
        AI_PlayAni(self,"T_DONTKNOW");
        rnd = Hlp_Random(2);
        if(rnd == 0)
        {
            Print(PRINT_PicklockMissing);
            B_Say_Overlay(self,self,"$PICKLOCKMISSING");
        }
        else if(rnd == 1)
        {
            Print("У меня больше нет отмычек!");
            B_Say_Overlay(self,self,"$NOMOREPICKS");
        };
    };
};

func void player_mob_never_open()
{
    Print(PRINT_NeverOpen);
    AI_PlayAni(self,"T_DONTKNOW");
    B_Say_Overlay(self,self,"$NEVEROPEN");
};

func void player_mob_missing_item()
{
    Print(PRINT_MissingItem);
    AI_PlayAni(self,"T_DONTKNOW");
    B_Say_Overlay(self,self,"$MISSINGITEM");
};

func void player_mob_another_is_using()
{
    Print(PRINT_AnotherUser);
    AI_PlayAni(self,"T_DONTKNOW");
};

func void player_mob_too_far_away()
{
    Print(PRINT_Toofar_Away);
    AI_PlayAni(self,"T_DONTKNOW");
};

func void player_mob_wrong_side()
{
    Print(PRINT_WrongSide);
    AI_PlayAni(self,"T_DONTKNOW");
};

func void player_trade_not_enough_gold()
{
    Print(PRINT_Trade_Not_Enough_Gold);
};
 
Последнее редактирование:

ElderGamer


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

KirTheSeeker

Участник форума
Регистрация
18 Авг 2017
Сообщения
1.928
Благодарности
558
Баллы
275
Само прерывание взаимодействия инициирует движок. Он же должен был инициировать проигрывание анимации пинка сундука. Но в оригинале это вырезано.
Тогда что прописано здесь?:
Daedalus:
func void player_mob_missing_lockpick()
{
    var int rnd;
    if(!Npc_GetTalentSkill(hero,NPC_TALENT_PICKLOCK))
    {
        Print(PRINT_NoPicklockTalent);
        AI_PlayAni(self,"T_DONTKNOW");
        B_Say_Overlay(self,self,"$NOPICKLOCKTALENT");
    }
    else
    {
        AI_PlayAni(self,"T_DONTKNOW");
        rnd = Hlp_Random(2);
        if(rnd == 0)
        {
            Print(PRINT_PicklockMissing);
            B_Say_Overlay(self,self,"$PICKLOCKMISSING");
        }
        else if(rnd == 1)
        {
            Print("У меня больше нет отмычек!");
            B_Say_Overlay(self,self,"$NOMOREPICKS");
        };
    };
};
Если конкретнее, мне нужно придумать куда вставлять сопоставление общей ловкости ГГ и количества комбинаций закрытого замка.
Лучше всего кажется впихнуть эту проверку туда же, где прерывание взаимодействия, при сломе последней отмычки, т.е. ГГ присаживается к замку, оценивает его, и встаёт обратно (взаимодействие прерывается), если не проходит проверку по ловкости.
 

ElderGamer


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

Если конкретнее, мне нужно придумать куда вставлять сопоставление общей ловкости ГГ и количества комбинаций закрытого замка.
В мод-фиксе это сделано с помошью правок в файле игрового мира. Каждому запертому сундуку и каждой запертой двери в свойствах прописан вызов соответствующей скриптовой функции. А в этой функции уже происходит анализ навыка ГГ, способен ли он открыть данный замок.
 

KirTheSeeker

Участник форума
Регистрация
18 Авг 2017
Сообщения
1.928
Благодарности
558
Баллы
275
В мод-фиксе это сделано с помощью правок в файле игрового мира. Каждому запертому сундуку и каждой запертой двери в свойствах прописан вызов соответствующей скриптовой функции. А в этой функции уже происходит анализ навыка ГГ, способен ли он открыть данный замок.
Хвала Хедину, он написал Union-плагин, отслеживающий кол-во комб-й, при взаимодействии с замком:
Union:
var int UnionPickLockStrNum; 

func event GameLoop()
{
     if(UnionPickLockStrNum){
         Hlp_PrintConsole(Str_Format("UnionPickLockStrNum: %i", UnionPickLockStrNum));
     };
};
Отсюда имеем числовую var int UnionPickLockStrNum.
б) имея навык, но не имея отмычек в инвентаре. Функция автоматически вызывается движком в этих случаях.
Как можно грамотно втиснуть туда сравнение общей ловкости ГГ и var int UnionPickLockStrNum ?
Я имею в виду что-то типа:
Daedalus:
var int UnionPickLockStrNum;

else if(rnd == 1)
    {
        //Проверка на общую ловкость ГГ (с учётом всех бонусов) и количества комбинаций замка
        if (UnionPickLockStrNum >= (hero.attr[DEXTERITY]/10))
        {
        //Каждый поворот отмычки требует 10 ед. ловкости. Если длина комбинации превышает 10% ловкости, то взаимодействие прерывается
            return TRUE;
        };
    };
 

Lorddemonik

★★★★★
Редактор раздела
Регистрация
17 Дек 2011
Сообщения
1.113
Благодарности
581
Баллы
350
KirTheSeeker,
Daedalus:
var int UnionPickLockStrNum;

func event GameLoop()
{
else if(rnd == 1)
    {
        //Проверка на общую ловкость ГГ (с учётом всех бонусов) и количества комбинаций замка
        if (UnionPickLockStrNum >= (hero.attr[DEXTERITY]/10))
        {
        //Каждый поворот отмычки требует 10 ед. ловкости. Если длина комбинации превышает 10% ловкости, то взаимодействие прерывается
            return TRUE;
        };
    };
Как то так. В теории просто заменяешь вывод информации на свой скрипт. Если конечно "Hlp_PrintConsole" у автора не отвечает за что-либо еще
 

KirTheSeeker

Участник форума
Регистрация
18 Авг 2017
Сообщения
1.928
Благодарности
558
Баллы
275
Типа такого:
Daedalus:
func void player_mob_missing_lockpick()

var int UnionPickLockStrNum;

{
    var int rnd;
    if(!Npc_GetTalentSkill(hero,NPC_TALENT_PICKLOCK))
    {
        Print(PRINT_NoPicklockTalent);
        AI_PlayAni(self,"T_DONTKNOW");
        B_Say_Overlay(self,self,"$NOPICKLOCKTALENT");
    }
    else
    {
        AI_PlayAni(self,"T_DONTKNOW");
        rnd = Hlp_Random(2);
        if(rnd == 0)
        {
            Print(PRINT_PicklockMissing);
            B_Say_Overlay(self,self,"$PICKLOCKMISSING");
        }
      func event GameLoop()
      else if(rnd == 1)
    {
        //Проверка на общую ловкость ГГ (с учётом всех бонусов) и количества комбинаций замка
        if (UnionPickLockStrNum >= (hero.attr[DEXTERITY]/10))
        {
        //Каждый поворот отмычки требует 10 ед. ловкости. Если длина комбинации превышает 10% ловкости, то взаимодействие прерывается
            return TRUE;
        };
    };
        else if(rnd == 2)
        {
            Print("У меня больше нет отмычек!");
            B_Say_Overlay(self,self,"$NOMOREPICKS");
        };
    };
};
?

Кажется, что нет, но я не знаю как правильно вставить эту func event GameLoop().

А, стоп, имеется в виду поместить проверку в Union-плагин?
 

Xeдин


Модостроитель
Регистрация
3 Дек 2008
Сообщения
1.450
Благодарности
1.977
Баллы
365
gameloop я для теста дал, что мог увидеть как работает UnionPickLockStrNum. Используй его где хочешь без gameloop.
-1 у сундука нет комбинации, если больше 0, то это кол-во поворотов необходимых для вскрытия.
Пост автоматически объединён:

твоя задача объявить у себя где-нибудь var int UnionPickLockStrNum; и тогда плагин будет его обновлять
 

KirTheSeeker

Участник форума
Регистрация
18 Авг 2017
Сообщения
1.928
Благодарности
558
Баллы
275
gameloop я для теста дал, что мог увидеть как работает UnionPickLockStrNum.
Я проверил, возвращает значение корректно, если верить консоли.

Используй его где хочешь без gameloop.
Тогда какую часть кода плагина нужно убрать?
 

Xeдин


Модостроитель
Регистрация
3 Дек 2008
Сообщения
1.450
Благодарности
1.977
Баллы
365
Тогда какую часть кода плагина нужно убрать?
мой тестовый .d для теста только, удали его. Тебе надо использовать dll в Autorun, а переменную UnionPickLockStrNum у себя объявляй где хочешь.
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.003
Благодарности
973
Баллы
295
в скриптах есть штатная функция G_PickLock. вот в неё и можно добавить проверку .
 

Oxbow

Участник форума
Регистрация
22 Дек 2017
Сообщения
265
Благодарности
33
Баллы
200
Подскажите пожалуйста почему не работает заклинание. ГГ просто садится на одно колено и все. Заклинание превращение в вепря.

Daedalus:
const int SPL_ConcussionBolt = 63;
const int SPL_SummonBoar = 64;//Призыв вепря
const int SPL_TrfBoar = 65;//Превращение в вепря-вожака
const int SPL_Reserved_66 = 66;
//////////////////
    "Concussionbolt",
    "SummonBoar",//Призыв вепря
    "Transform",//Прверащение в вепря-вожака
    "Light",
    /////////////////
    "FBT",
    "SUM",//Призыв вепря
    "TRF",//Превращение в вепря-вожака
    "XXX",

Daedalus:
    "TXT_SPL_CONCUSSIONBOLT",
    "Вызов вепря",
    "Вепрь-вожак",
    "TXT_SPL_RESERVED_66",
//////////////
const string NAME_SPL_ConcussionBolt = "NAME_SPL_CONCUSSIONBOLT";
const string NAME_SPL_SummonBoar = "Призыв вепря";
const string NAME_SPL_TrfBoar = "Превращение в вепря-вожака";
const string NAME_SPL_Reserved_66 = "NAME_SPL_RESERVED_66";

Daedalus:
    if(activeSpell == SPL_TrfBoar)
    {
        return Spell_Logic_TransformBoar(manaInvested);
    };

Daedalus:
const int SPL_Cost_TransformBoar = 40;

instance Spell_TransformBoar(C_Spell_Proto)
{
    time_per_mana = 0;
    targetCollectAlgo = TARGET_COLLECT_NONE;
};


func int Spell_Logic_TransformBoar(var int manaInvested)
{
    if(Npc_GetActiveSpellIsScroll(self) && (self.attribute[ATR_MANA] >= SPL_Cost_Scroll))
    {
        return SPL_SENDCAST;
    }
    else if(self.attribute[ATR_MANA] >= SPL_Cost_TransformBoar)
    {
        return SPL_SENDCAST;
    }
    else
    {
        return SPL_SENDSTOP;
    };
};

func void Spell_Cast_TransformBoar()
{
    if(Npc_GetActiveSpellIsScroll(self))
    {
        self.attribute[ATR_MANA] = self.attribute[ATR_MANA] - SPL_Cost_Scroll;
    }
    else
    {
        self.attribute[ATR_MANA] = self.attribute[ATR_MANA] - SPL_Cost_TransformBoar;
    };
    Npc_SetActiveSpellInfo(self,Keiler);
    self.aivar[AIV_SelectSpell] += 1;
};

Daedalus:
instance ItSc_TrfBoar(C_Item)
{
    name = NAME_Spruchrolle;
    mainflag = ITEM_KAT_RUNE;
    flags = ITEM_MULTI;
    value = Value_Sc_TrfBoar;
    visual = "ItSc_TrfBoar4.3DS";
    material = MAT_LEATHER;
    spell = SPL_TrfBoar;
    cond_atr[2] = ATR_MANA_MAX;
    cond_value[2] = SPL_Cost_Scroll;
    wear = WEAR_EFFECT;
    effect = "SPELLFX_WEAKGLIMMER";
    description = NAME_SPL_TrfWolf;
    text[0] = NAME_MageScroll;
    text[1] = NAME_Mana_needed;
    count[1] = SPL_Cost_Scroll;
    text[5] = NAME_Value;
    count[5] = value;
};

П.С. Подскажите почему призванный зверь пропадает при трансформации, и можно это как-то исправить?
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.003
Благодарности
973
Баллы
295
Подскажите пожалуйста почему не работает заклинание. ГГ просто садится на одно колено и все. Заклинание превращение в вепря.
по моему под превращения надо использовать конкретный диапазон. проще новые заклинания делать на https://worldofplayers.ru/threads/42126/page-2#post-1165663
 
Сверху Снизу