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

    Чтобы получить возможность писать на форуме, оставьте сообщение в этой теме.
    Удачи!
  • Друзья, доброго времени суток!
    Стартовал новый литературный конкурс от "Ордена Хранителей" - "Пираты Миртанского моря".
    Каждый может принять в нём участие и снискать славу и уважение, а в случае занятия призового места ещё и получить награду. Дерзайте
  • Дорогие друзья, год подходит к концу, и пришло время подвести его итоги и наградить достойных

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

В разработке... Union. Пожелания насчёт плагинов

Vain

Участник форума
Регистрация
19 Сен 2008
Сообщения
395
Благодарности
122
Баллы
205
1. Факел потухает во время дождя
2. Факел потухает при соприкосновении с водой (озеро, река, море)
3. ГГ может использовать анимацию "мытья из бочки" если стоит у воды либо в воде.
4. Изменение урона в зависимости о погоды. К примеру: Огонь-дождь - уменьшение урона и уменьшение времени горения
5. Заклинания на погоду
6. Изменение радиуса агра для мобов в зависимости о погоды [к примеру - туман]
7. Левитация aka R1
8. Возможность самому создавать кастомные формулы урона. К примеру мы имеем конфиг-файл где можно использовать параметры S - сила, Z - защита моба, W - урон оружия
ну и пишем конструкцию типа:
1h (
if (Z<W) U = Z - W + S*0.5
else U = 1 + S*0.1
)
 

Vic7im

Участник форума
Регистрация
15 Мар 2016
Сообщения
49
Благодарности
18
Баллы
175
Reviving the thread with a request:

Armor worn influences movement and animation speed.

Since I'm rusty on animations, I assume that regular Gothic animations are played at 25 FPS (by memory).
Given this, I suggest to divide armor in 3 categories:
Light/No Armor: 29-30 FPS
Medium Armor: 25 FPS
Heavy Armor: 20-21 FPS

IE: If I am wearing a Paladin Armor (heavy or medium), the hero would play all animations slowly (not much slowly, but to reflect the bulk of the armor), whereas wearing no armor or very light armor would actually increase the FPS by little.

As a general rule of thumb I would use the PROT_EDGE > X as an indication of the armor being considered "heavy".

Would be interesting to influence hero speed parameter as well, but I don't think there is a "speed" parameter to animations. Oh well, food for thought.


What do you guys think? Would this be possible given the possibilities of Union?
 

Slavemaster


Модостроитель
Регистрация
10 Июн 2019
Сообщения
1.086
Благодарности
1.909
Баллы
320
Vic7im, for hero only it can be easily done with zParserExtender. Just install it and add a script file:
Daedalus:
func void GameLoop()
{
    var C_ITEM armor;
    armor = Npc_GetEquippedArmor(hero);
    
    var float fps;
    fps    = 30;
    
    if Hlp_IsValidItem(armor)
    {
        if armor.protection[2] > 50
        {
            fps = 25;
        };
        
        if armor.protection[2] > 100
        {
            fps = 20;
        };
    };
    
    Mdl_SetAllAnimationsFPS(hero, fps);
};
 

Gratt


Модостроитель
Регистрация
14 Ноя 2014
Сообщения
3.301
Благодарности
4.641
Баллы
625
Slavemaster, Mdl_SetAnimationFPS работает с моделью персонажа, а значит анимации одинаковых прототипов нпс имеют идентичные указатели. Если менять скорость таким образом, то другие хуманоиды тоже изменят скорость. Для изменения скорости конкретного нрс используй Mdl_SetNpcSpeedMultiplier. Изменение скорости происходит следующим образом.
 

KirTheSeeker

Участник форума
Регистрация
18 Авг 2017
Сообщения
1.931
Благодарности
560
Баллы
275
Приветствую всех.
Возможно ли , с помощью Union, сделать плагин, перекраивающий HP у ГГ, а также механику его наращивания?
Если конкретнее:
1) При повышении уровня, здоровье ГГ увеличивается на 1 ед., вместо оригинальных 12.
2) При повышении перманентного значения силы (прокачкой/едой/зельями/скрижалями/квестовыми бонусами, как от Эрола, и т.п.), здоровье ГГ увеличивается на 2 ед. за каждое очко силы. Т.е. прокачав силу на 10 ед., ГГ также увеличит и ХП на 20 ед. Разумеется, это НЕ касается силы, получаемой от ношения амулетов и т.п.
3) При повышении перманентного значения ловкости (прокачкой/едой/зельями/скрижалями/квестовыми бонусами, как от Ренгару, и т.п.), здоровье ГГ увеличивается на 1 ед. за каждое очко ловкости. Т.е. прокачав ловкость на 10 ед., ГГ также увеличит и ХП на 10 ед.
Таким образом, уровень здоровья привязывается к атрибутам ГГ. И в начале оригинальной игры мы будем иметь НЕ 40 "дефолтных" ед. здоровья, а 30, исходя из начальных 10 силы и 10 ловкости персонажа.
Данный плагин интересен в плане балансировки прокачки, при игре за разные специализации. Я понимаю, что он будет перебивать настройки прокачки здоровья других модов, но для оригинальной игры это может быть интересным решением, особенно если добавить к плагину ini, где все эти значения будут настраиваться.
Например:
Прибавка к здоровью за перманентную ед. "хак-ки S" = Х;
Прибавка к здоровью за повышение уровня ГГ = Y; и т.д.
 

D36


Модостроитель
Регистрация
3 Дек 2014
Сообщения
2.222
Благодарности
3.449
Баллы
485
Возможно ли , с помощью Union, сделать плагин, перекраивающий HP у ГГ, а также механику его наращивания?
Предлагаю не плагин, а дополнение к неофициальному обновлению версии 26. Копируется в папку Data/ModVDF. Требуется начало новой игры:
 

Вложения

  • g2a_nr_scriptpatch_v26_hotfix.zip
    2,8 MB · Просмотры: 29

KirTheSeeker

Участник форума
Регистрация
18 Авг 2017
Сообщения
1.931
Благодарности
560
Баллы
275
Предлагаю не плагин, а дополнение к неофициальному обновлению версии 26.
Благодарю! Опробуем.
Это здорово, но хотелось бы попробовать и настраиваемый плагин, который можно подключить к любому другому моду, например "Gothic 2 Mod Fix" или "Пробуждение".

Фикс работает отлично! Мне нравится.
D36, а можно этот VDF-фикс отвязать от скрипт-патча, сделав универсальным?
 
Последнее редактирование:

KirTheSeeker

Участник форума
Регистрация
18 Авг 2017
Сообщения
1.931
Благодарности
560
Баллы
275
Почему "разумеется"?
Ради баланса, в первую очередь, чтобы те же амулеты/кольца и т.п., дающие прибавку к жизни, не становились ненужными, при наличии амулетов/колец и т.п. "на силу".
Также это видится мне логичнее - здоровье ГГ растёт при естественной тренировке своего тела, либо от "принятия внутрь естественных (в рамках мира Готики) источников энергии", которые, по сути, катализируют те же самые естественные процессы в теле.
А вот магические "бусты", раз уж в игре они строго разделяются (сила/ловкость/типы защиты), действуют по какому-то иному принципу, так что их я бы просто не трогал.
Примерно такое обоснование.
 

Slavemaster


Модостроитель
Регистрация
10 Июн 2019
Сообщения
1.086
Благодарности
1.909
Баллы
320
в первую очередь, чтобы те же амулеты/кольца и т.п., дающие прибавку к жизни, не становились ненужными, при наличии амулетов/колец и т.п. "на силу"
Это имеет смысл.

Попробуй с модами скрипт для zParserExtender и плагин.
Daedalus:
func void zKirTheSeeker_OnEvent(var int event, var int end)
{
    const int onDialog = 0;
    const int onEquip = 1;
    const int onUseItem = 2;
    const int newGame = 3;
    
    if event == onEquip
    {
        return;
    };
    
    if event == newGame
    {
        hero.attribute[1] = 30 + hero.attribute[4] * 2 + hero.attribute[5];
        hero.attribute[0] = hero.attribute[1];
        return;
    };
    
    var int attribute[6];

    if end
    {
        var int dAttribute[6];
        
        dAttribute[0] = hero.attribute[0] - attribute[0];
        dAttribute[1] = hero.attribute[1] - attribute[1];
        dAttribute[2] = hero.attribute[2] - attribute[2];
        dAttribute[3] = hero.attribute[3] - attribute[3];
        dAttribute[4] = hero.attribute[4] - attribute[4];
        dAttribute[5] = hero.attribute[5] - attribute[5];
        
        var int bonusHp;
        bonusHp = dAttribute[4] * 2 + dAttribute[5];
        
        hero.attribute[0] += bonusHp;
        hero.attribute[1] += bonusHp;
        
        return;
    };

    attribute[0] = hero.attribute[0];
    attribute[1] = hero.attribute[1];
    attribute[2] = hero.attribute[2];
    attribute[3] = hero.attribute[3];
    attribute[4] = hero.attribute[4];
    attribute[5] = hero.attribute[5];
};

func void B_GivePlayerXP(var int xp)
{
    var int level;
    var int hitpoints;
    var int hitpointsMax;
    
    level = hero.level;
    hitpoints = hero.attribute[0];
    hitpointsMax = hero.attribute[1];
    
    B_GivePlayerXP_Old(xp);
    
    if (hero.level == level)
    {
        return;
    };
    
    var int bonusHp;
    bonusHp = hero.level - level;
    
    hero.attribute[1] = hitpointsMax + bonusHp;
    hero.attribute[0] = hitpoints + bonusHp;
};
 

Вложения

  • zKirTheSeeker.vdf.zip
    33,6 KB · Просмотры: 20
Последнее редактирование:

Slavemaster


Модостроитель
Регистрация
10 Июн 2019
Сообщения
1.086
Благодарности
1.909
Баллы
320

KirTheSeeker

Участник форума
Регистрация
18 Авг 2017
Сообщения
1.931
Благодарности
560
Баллы
275
Так, начисление бонусов при прокачке идёт корректно, как при новой игре, так и на текущем сохранении.
НО не пересчитывается изначальное значение ХП, при начале новой игры - остаётся 40 ед. Возможно ли это поправить?
А в идеале, если это не слишком сложно и долго, - ввести полный перерасчёт значения ХП, отталкиваясь от уровня персонажа?
Например, мой текущий персонаж имеет текущее макс. ХП = 251 [HPcurrent], при начальном ХП =40 [HPstart], а также:
Уровень = 10 [Lv]
Сила = 35 [Str]
Ловкость = 18 [Agl]
В оригинале я качал по 12 ед. жизни за уровень, а остальное - бонусы. Значит, корректное ХП [HPresult] будет:
HPresult = (HPcurrent - (Lv*12 + HPstart)) + (Str*2) + Agl + Lv = (251 - (10*12 +40)) + (35*2) + 18 + 10 = 189 ед.

Ещё лучше, наверное, поставить вместо 12 - установленное в данном конкретном прохождении значение ХП, получаемое за новый уровень. Если такое вообще можно настроить, конечно.
 
Последнее редактирование:

Slavemaster


Модостроитель
Регистрация
10 Июн 2019
Сообщения
1.086
Благодарности
1.909
Баллы
320
НО не пересчитывается изначальное значение ХП, при начале новой игры - остаётся 40 ед. Возможно ли это поправить?
Перезалил плагин и текст скрипта.
А в идеале, если это не слишком сложно и долго, - ввести полный перерасчёт значения ХП, отталкиваясь от уровня персонажа?
Перерасчёт делать не буду.
 

KirTheSeeker

Участник форума
Регистрация
18 Авг 2017
Сообщения
1.931
Благодарности
560
Баллы
275
Перерасчёт делать не буду.
Вообще, да, лишнее предложение, с моей стороны, ведь текущее значение можно просто поменять через консоль.

Приветствую всех вновь.
Можно ли, с помощью Union, создать плагин/патч, который уберёт i-фреймы (кадры неуязвимости), при отскоке назад с оружием?
Чтобы нельзя было просто так "пропускать сквозь себя" кулаки тех же троллей.
 
Последнее редактирование:

Slavemaster


Модостроитель
Регистрация
10 Июн 2019
Сообщения
1.086
Благодарности
1.909
Баллы
320
Идея для плагина: задействовать анимации *_USE_LOCKED для сундуков с замками. При успешном взломе или использовании ключа проигрывается анимация открытия замка и он остается визуально открытым в дальнейшем:

Это ещё не всё. Разрабами были предусмотрены ещё анимации ГГ и сундука в случае, когда у ГГ ломается последняя отмычка. ГГ не просто прекращает взлом и встаёт, но и с досады лупит сундук ногой (t_CHESTBIG_S0_Try). Сундук при этом подпрыгивает. Кажется, камрад Керракс это восстанавливал в Генжине.
Есть демо. Задумка такая:
  1. Вместо того чтобы резко встать из-за сломанной отмычки, персонаж будет вставать плавно
  2. Если персонаж встаёт из-за сломанной отмычки не в состоянии подкрадывания, то он пинает сундук, а тот трясётся
  3. При отпирании сундука проигрываются соответствующие анимации замка и персонажа
  4. Если персонаж закрывает сундук от которого у него есть ключ, то он запирает сундук с проигрыванием соответствующих анимаций
  5. При загрузке мира для всех незапертых сундуков мгновенно проигрывается анимация отпирания замка
 

Вложения

  • zPicklockAnis.vdf
    134,5 KB · Просмотры: 201
Последнее редактирование:

D36


Модостроитель
Регистрация
3 Дек 2014
Сообщения
2.222
Благодарности
3.449
Баллы
485
Вместо того чтобы резко встать из-за сломанной отмычки, персонаж будет вставать плавно
Применимо только к Г1? Вроде в Г2 это и так было.

Если персонаж закрывает сундук от которого у него есть ключ, то он запирает сундук с проигрыванием соответсвующих анимаций
Не совсем понятно, зачем опять автоматически запирать на ключ такие сундуки. Лучше оставить как в оригинале - замок открыли, сундук разблокирован навсегда, ключ можно выбросить (или удалить плагином). А так нужно будет все ключи от сундуков носить с собой.

При загрузке мира для всех незапертых сундуков мгновенно проигрывается анимация отпирания замка
См. выше - сундуки с "ключными" замками остаются запертыми, т.к. после каждого открытия ГГ опять их запирает. И визуально они тоже остаются запертыми, хотя ГГ уже их открыл, обчистил и выбросил ключ за ненадобностью.
 

Slavemaster


Модостроитель
Регистрация
10 Июн 2019
Сообщения
1.086
Благодарности
1.909
Баллы
320
Применимо только к Г1? Вроде в Г2 это и так было.
Персонаж резко встаёт после каждой сломанной отмычки (Г1) или после последней сломанной (Г2).
ключ можно выбросить (или удалить плагином)
Если ключ будет удалён до закрытия сундука, то сундук не будет запираться
Не совсем понятно, зачем опять автоматически запирать на ключ такие сундуки.
Просто захотелось. Убрать не долго. Впрочем, в эпоху квиклутов и той дополнительной секунде анимаций при отпирании замка многие не обрадуются.
 

Slavemaster


Модостроитель
Регистрация
10 Июн 2019
Сообщения
1.086
Благодарности
1.909
Баллы
320
Очень интересно.
У меня это так выглядит:
C++:
Sub loadUnlocked(ZSUB(GameEvent::LoadEnd), []()
    {
        VobTraverser traverser;

        traverser.handle = [](zCVob* vob)
        {
            oCMobContainer* const chest = vob->CastTo<oCMobContainer>();
            ASSERTRETURN(chest && !chest->locked);

            zCModel* const model = chest->GetModel();
            ASSERTRETURN(model);

            const int aniId = model->GetAniIDFromAniName("T_S0_UNLOCK");
            ASSERTRETURN(aniId != Invalid);

            model->StartAni(aniId, zCModel::zMDL_STARTANI_DEFAULT);
            zCModelAniActive* const activeAni = model->GetActiveAni(aniId);
            ASSERTRETURN(activeAni && activeAni->protoAni);

            if (activeAni->advanceDir > 0)
            {
                activeAni->actFrame = activeAni->protoAni->numFrames - 1;
                activeAni->actAniEvent = activeAni->protoAni->numFrames;
            }
            else
            {
                activeAni->actFrame = 0;
                activeAni->actAniEvent = -1;
            }

            auto scope = AssignTemp(ztimer->factorMotion, 0.0f);
            model->AdvanceAnis();
        };

        traverser.TraverseVobList();
    });
 
Сверху Снизу