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

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

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

Union - мини плагины

Slavemaster


Модостроитель
Регистрация
10 Июн 2019
Сообщения
1.043
Благодарности
1.826
Баллы
240
  • Первое сообщение
  • #1
Здесь будут собираться плагины, создание отдельной темы для которых было бы излишним.


Плагины, распространяемые с помощью exe-инсталлятора, можно деинсталлировать им же.
Плагины, распространяемые в виде vdf тома, следует помещать в папку Data/Plugins/.
Каждый плагин, если не указано иного, должен работать на любых версиях игры: Gothic I Classic (G1), Gothic I Sequel (G1A), Gothic II Classic (G2), Gothic II Addon (G2A).
Код плагинов и сами плагины, автором которых являюсь я, можно распространять и использовать без ограничений.


При наличии нескольких одноименных вложений в одном посте следует скачивать последнее. Удалять старые вложения прав нет.

  1. Плагин zNoFocusFlag (Автор: Slavemaster). Для модостроителей. Делает NPC с флагом NPC_FLAG_NFOCUS полностью прозрачными для фокуса ГГ.
  2. Плагин AlterDamage (Автор: Slavemaster). Есть проблемы с совместимостью. Меняет формулы урона. Добавляет всплывающие сообщения о нанесённом уроне.
  3. Плагин zSavesBackuper (Автор: Slavemaster). Осуществляет резервное копирование сделанных сохранений.
  4. Плагин Union_Hotbar_1.0k (Автор: Haart). Добавляет панель быстрого доступа для предметов из инвентаря.
  5. Плагин QuickLoot (Автор: Slavemaster). Быстрый сбор предметов при помощи правой кнопки мыши.
  6. Плагин MarvinHelper (Автор: Slavemaster). Дополнительные возможности для консоли разработчика.
  7. Плагин MunitionInfo (Автор: Xeдин). Отображает кол-во стрел/болтов в инвентаре.
  8. Плагин zAsyncSaveLoad. (Автор: Slavemaster).Плагин делает окно игры отзывчивым к сочетанию Alt+Tab во время загрузки, сохранения и просмотра видео.
  9. Плагин Union_SaveLoadManager_i (Автор: Haart). Позволяет сохраняться в разные слоты без лишних усилий.
  10. Плагин zBugFixes (Автор: Slavemaster). Плагин содержит исправления некоторых ошибок движка Готики.
  11. Плагин zTorchControl (Автор: Slavemaster). Плагин предотвращает удаление горящих факелов при загрузке, а также позволяет их использовать по горячей клавише.
  12. Плагин zMarkItems (Автор: Slavemaster).Плагин осуществляет маркировку предметов внутри ячеек инвентаря.
  13. Плагин zMiscUtils (Автор: Slavemaster). Плагин реализует множество функций, не объединённых единой тематикой.
  14. Плагин SimpleRegen (Автор: Xeдин). Плагин реализует простой алгоритм регенерации жизни и/или маны.
  15. Плагин Union_Thief_Helper (Автор: Xeдин). Помощник вора. Маркировка не обворованных и обворованных NPC и подсказки при взломе.
  16. Плагин Union_XP_Bar (Автор: Xeдин). Плагин для отображения полоски опыта.
  17. Плагин OdyAlt (Автор: N1kX). Подробное многостраничное меню навыков для мода Одиссея 2.6.4.
  18. Плагин OdyAltMenu (Автор: N1kX). Подробное многостраничное меню навыков для мода Одиссея 2.7.0+.
  19. Плагин zUtilities (Автор: Franisz). Несколько удобных функций.
  20. Плагин oDamageHelper (Автор: Gratt). Для модостроителей. Позволяет менять наносимый урон с помощью скриптов.
  21. Плагин Union_DamageInfo (Автор: Xeдин). Плагин выводит урон по врагам и по главному герою.
  22. Плагин Union_RandomRainDX11 (Автор: Haart). При использовании с DX11 дождь будет начинаться в случайное время суток.
  23. Плагин Union_Ext_Stat (Автор: Xeдин). Небольшая дополнительная статистика по количеству убитых, выпитых зелий, квестам и времени игры.
  24. Плагин Union_Show_FPS (Автор: Xeдин). Простенький плагин на показ FPS для всех версий Готики, с возможностью отключения в меню и задания позиции отображения.
  25. Плагин zImprovedLegacyFrying (Автор: Slavemaster). Добавляет диалоги жарки мяса для костра и плиты.
  26. Плагин Union_Keep_Last_Save (Авторы: Gratt, Xeдин). Плагин для удобной работы с последним слотом записи.
  27. Плагин EquippedWeapon (Автор: MEG@VOLT). Для модостроителей. Добавляет функции экипировки / деэкипировки оружия.
  28. Плагин TradeMissItems (Автор: MEG@VOLT). Плагин создан для защиты от случайной продажи квестовых предметов.
  29. Плагин zUnstuckSlidingPlayer (Автор: Slavemaster). Автоматическая телепортация игрока при длительном скольжении.
  30. Плагин KillMeatBugs (Автор: MEG@VOLT). Позволяет затаптывать мясных жуков.
  31. Плагин ezFistMode (Автор: fyryNy). Хоткей для перехода в режим кулачного боя.
 
Последнее редактирование:

MEG@VOLT

★★★★★★★★★
ТехАдмин
Регистрация
24 Мар 2006
Сообщения
9.228
Благодарности
6.204
Баллы
1.565
4YBAK, Эм, а разве обыный функционал это же самое не делает? Клавиша F ?
 

Gratt


Модостроитель
Регистрация
14 Ноя 2014
Сообщения
3.288
Благодарности
4.585
Баллы
625
4YBAK, только если у тебя очень хороший вестибулярный аппарат.
 

Xeдин


Модостроитель
Регистрация
3 Дек 2008
Сообщения
1.358
Благодарности
1.894
Баллы
335
Еще небольшой апдейт "Помощник вора". Union_Thief_Helper_04_07_2022.vdf
- добавлена своя логика показа для Гильдий 1.5
- добавлены параметры (stealShiftRedByX, stealShiftRedByY, stealShiftGreenByX, stealShiftGreenByY) для кастомного сдвига иконок. Сдвиг от центра имени.
bagSize=40 (уменьшенный размер)
stealShiftRedByX=-40
stealShiftRedByY=200
stealShiftGreenByX=40
stealShiftGreenByY=200

th1.jpg

Отдельно еще выложил альтернативные текстуры для иконок. (Union_Thief_Helper_Alternative_Textures.vdf). Там кружки вместо мешочков.
Все доступно по ссылке на гугльдиск в посте https://worldofplayers.ru/threads/41521/page-19#post-1119695

Update. Union_Thief_Helper_04_07_2022_v2.vdf
- добавил проверку для наемников орков и орков.
 
Последнее редактирование:

4YBAK

Участник форума
Регистрация
27 Окт 2009
Сообщения
154
Благодарности
81
Баллы
300
4YBAK, Эм, а разве обыный функционал это же самое не делает? Клавиша F ?
Тела то нет, как и оружия. Да и с читом firstperson аналогично, только на сей раз оружие и предметы видно, без тела, но камера максимально статична и смотрит только вперëд.
4YBAK, только если у тебя очень хороший вестибулярный аппарат.
Играл в GTA 5 от первого лица со всеми настройками на реализм - полëты с крыши без парашюта или падения с мотоцикла просто фееричны))
 

Gratt


Модостроитель
Регистрация
14 Ноя 2014
Сообщения
3.288
Благодарности
4.585
Баллы
625
Играл в GTA 5 от первого лица со всеми настройками на реализм - полëты с крыши без парашюта или падения с мотоцикла просто фееричны))
Не смеши меня:) В гта при виде от первого лица используется альтернативная схема поведения персонажа и камеры. Если ты правда хочешь поиграть в блевотрон, я могу приаттачить камеру к кости головы. Но тебя хватит минут на 10.
 

KirTheSeeker

Участник форума
Регистрация
18 Авг 2017
Сообщения
1.903
Благодарности
537
Баллы
275
Не смеши меня:) В гта при виде от первого лица используется альтернативная схема поведения персонажа и камеры. Если ты правда хочешь поиграть в блевотрон, я могу приаттачить камеру к кости головы. Но тебя хватит минут на 10.
Если не очень сложно, я прошу просто добавить в стандартный вид от первого лица перекрестье для более чёткого подбора объекта взаимодействия? Думаю, там оно будет вполне востребовано.
 

4YBAK

Участник форума
Регистрация
27 Окт 2009
Сообщения
154
Благодарности
81
Баллы
300
Не смеши меня:) В гта при виде от первого лица используется альтернативная схема поведения персонажа и камеры. Если ты правда хочешь поиграть в блевотрон, я могу приаттачить камеру к кости головы. Но тебя хватит минут на 10.
То есть будет повторять движения кости? Был бы очень благодарен)
 

Gratt


Модостроитель
Регистрация
14 Ноя 2014
Сообщения
3.288
Благодарности
4.585
Баллы
625
4YBAK, блин меняж посадят если ты откинешься прямо перед монитором. Хотя бы не кушай час перед игрой.

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

Вложения

  • zAchem.zip
    116 KB · Просмотры: 32

SuperDave500

Участник форума
Регистрация
26 Янв 2021
Сообщения
51
Благодарности
29
Баллы
55
Еще небольшой апдейт "Помощник вора". Union_Thief_Helper_04_07_2022.vdf
- добавлена своя логика показа для Гильдий 1.5
- добавлены параметры (stealShiftRedByX, stealShiftRedByY, stealShiftGreenByX, stealShiftGreenByY) для кастомного сдвига иконок. Сдвиг от центра имени.
bagSize=40 (уменьшенный размер)
stealShiftRedByX=-40
stealShiftRedByY=200
stealShiftGreenByX=40
stealShiftGreenByY=200

Посмотреть вложение 107896

Отдельно еще выложил альтернативные текстуры для иконок. (Union_Thief_Helper_Alternative_Textures.vdf). Там кружки вместо мешочков.
Все доступно по ссылке на гугльдиск в посте https://worldofplayers.ru/threads/41521/page-19#post-1119695

Update. Union_Thief_Helper_04_07_2022_v2.vdf
- добавил проверку для наемников орков и орков.

Благодарю вас!

Не могли бы вы дать возможность каждому значку (красному и зеленому) разместить его слева или справа от имени.

Очень сложно попытаться правильно настроить их смещениями.
 
Последнее редактирование:

Xeдин


Модостроитель
Регистрация
3 Дек 2008
Сообщения
1.358
Благодарности
1.894
Баллы
335
SuperDave500, добавил параметр откуда центрировать иконки, так будет проще. (Union_Thief_Helper_05_07_2022.vdf)
stealShiftGreenMode=MIDDLE // MIDDLE/LEFT/RIGHT.
stealShiftRedMode=MIDDLE // MIDDLE/LEFT/RIGHT.
bagSize=70
stealShiftRedByX=-100
stealShiftRedByY=0
stealShiftGreenByX=-180
stealShiftGreenByY=0
stealShiftGreenMode=LEFT
stealShiftRedMode=LEFT
1.jpg
bagSize=70
stealShiftRedByX=30
stealShiftRedByY=0
stealShiftGreenByX=110
stealShiftGreenByY=0
stealShiftGreenMode=RIGHT
stealShiftRedMode=RIGHT
2.jpg
 

SuperDave500

Участник форума
Регистрация
26 Янв 2021
Сообщения
51
Благодарности
29
Баллы
55
SuperDave500, добавил параметр откуда центрировать иконки, так будет проще. (Union_Thief_Helper_05_07_2022.vdf)
stealShiftGreenMode=MIDDLE // MIDDLE/LEFT/RIGHT.
stealShiftRedMode=MIDDLE // MIDDLE/LEFT/RIGHT.

Спасибо за старания. Я думаю, что вы должны включить объяснение, что ЛЕВЫЙ, СРЕДНИЙ и ПРАВЫЙ «режимы» — это положение, в котором значок прикреплен к имени нпс. Любые значения в полях «сдвиг» сместят значок из этого места. Также, что если в полях "shift" нет значений, мод поставит значки в исходное положение независимо от того, что вы поставили в качестве "mode". Нормальному человеку будет сложно разобраться в этом без посторонней помощи. Я ненормальный, и мне потребовалось некоторое время, чтобы разобраться во всем этом самостоятельно.

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

Должен ли rob/not robbed работать с Готикой 1? Я не могу заставить значки отображаться независимо от того, что я делаю. Остальные функции мода работают в Готике 1.
 

Xeдин


Модостроитель
Регистрация
3 Дек 2008
Сообщения
1.358
Благодарности
1.894
Баллы
335
Нормальному человеку будет сложно разобраться в этом без посторонней помощи.
Кастомные настройки не для обычных людей))

Должен ли rob/not robbed работать с Готикой 1?
В оригинальной Г1 должно работать, в модах и фиксах может не работать

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

SuperDave500

Участник форума
Регистрация
26 Янв 2021
Сообщения
51
Благодарности
29
Баллы
55
SuperDave500,
В оригинальной Г1 должно работать, в модах и фиксах может не работать
Я выполнил чистую установку Gothic 1, Union 1.0l и Union_Thief_Helper_06_07_2022.vdf. Никаких других модов, никаких текстурпаков, ничего больше.

Я оставил все на значениях по умолчанию. Я дал себе мастер карманных краж и 500 dex с помощью консоли. Я могу обворовывать NPC, но ни красной, ни зеленой сумки не появляется.
 

Xeдин


Модостроитель
Регистрация
3 Дек 2008
Сообщения
1.358
Благодарности
1.894
Баллы
335
SuperDave500, ок, для оригинала Г1 перепроверю, постараюсь поправить.
Пост автоматически объединён:

Да, в оригинале как раз и не работает, там же другая схема, через инвентарь. Я похоже Г1 проверял там, где через диалоги сделано. В общем будет работать, если есть кража через диалоги, для кражи через инвентарь как будет побольше времени подумаю что можно сделать.
 
Последнее редактирование:

SuperDave500

Участник форума
Регистрация
26 Янв 2021
Сообщения
51
Благодарности
29
Баллы
55
Кто-нибудь здесь имеет какое-либо отношение к этому моду или знает автора этого очень полезного мода? Union / Юнион - Квиклут, Квиксейв и прочее. (Г2 и моды). Я спрашиваю здесь, потому что я думаю, что автор приходит сюда время от времени, и я безрезультатно пытался привлечь внимание авторов мода на двух разных веб-сайтах, где размещен мод.

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

SuperDave500

Участник форума
Регистрация
26 Янв 2021
Сообщения
51
Благодарности
29
Баллы
55
4YBAK, блин меняж посадят если ты откинешься прямо перед монитором. Хотя бы не кушай час перед игрой.

Не рекомендуется беременным детям и впечатлительным старикам.
Возможные побочные эффекты:
- головокружение
- тошнота
- онемение
- тахикардия
- ухудшение зрения
- раздражительность
- потеря сознания
- эпилепсия
Ха-ха. От этого глаза болят через несколько минут. Хотя это довольно забавно. Можно ли взломать камеру от первого лица из Готики 2 и использовать ее в Готике 1? Просто любопытно.
 

4YBAK

Участник форума
Регистрация
27 Окт 2009
Сообщения
154
Благодарности
81
Баллы
300
Ха-ха. От этого глаза болят через несколько минут. Хотя это довольно забавно. Можно ли взломать камеру от первого лица из Готики 2 и использовать ее в Готике 1? Просто любопытно.
Ну, я не для полноценной игры использую, а для машинимы с вручную написанными с нуля плавными анимациями, потому глаза у зрителя болеть уже не будут)
А так боëвка от первого лица выглядит очень даже, и приятнее играется, чем простое передвижение)
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
1.932
Благодарности
929
Баллы
275
  1. Плагин oDamageHelper (Автор: @Gratt). Для модостроителей. Позволяет менять наносимый урон с помощью скриптов.

примеры использования:
Daedalus:
// self - атакующий
// victim - атакуемый
// item - орудие убийства (может быть null)

 func int ITEM_RPR (var C_Item ItMw)
    {
        var int weaponInstance;
        weaponInstance = Hlp_GetInstanceID(ItMw);

        if (weaponInstance == ItMw_1h_Vlk_Sword)
        {
            Hlp_PrintConsole ("Оружие ItMw_1h_Vlk_Sword");
            return true;
        };
        
        if (weaponInstance == ItMw_Rapier)
        {
            Hlp_PrintConsole ("Оружие ItMw_Rapier");
            return true;
        };   
        
        if (weaponInstance == ItMw_Meisterdegen)
        {
            Hlp_PrintConsole ("Оружие ItMw_Rapier");
            return true;
        };
        
        return false;
    };

    func int OnDamage_Hit(var int OldDamageTota)
    {

        if    ITEM_RPR (item)
        {
            Hlp_PrintConsole ("Оружие ITEM_RPR");
            
            var int DamageTotal_ITEM_RPR;

        //    DamageTotal_ITEM_RPR = DAM-WEAP (собственный урон оружия)
        //+ [ATR_STR_Total (полное значение силы со всеми бонусами от колец и т.п.) * 0.4]
        //+ [ATR_DEX_Total (полное значение ловкости со всеми бонусами от колец и т.п.) * 0.6]

            DamageTotal_ITEM_RPR =    item.damageTotal;                              // орон самого оружия       
            DamageTotal_ITEM_RPR += (self.attribute[ATR_DEXTERITY] * 6 / 10) ;     // доп урон от ловокости
            DamageTotal_ITEM_RPR += (self.attribute[ATR_STRENGTH] * 4 / 10) ;     // доп урон от силы
    
            //    далее можно прописать влияние навыка на урон 1h
            //    то есть будет ли урон полным или критическим или неполным в зависиости от баланса игры.
            // например
            //DamageTotal_ITEM_RPR = DamageTotal_ITEM_RPR * self.HitChance[NPC_TALENT_1H] / 100 ;
            
            /*
            // отладка
            var string msg;
            msg = Str_Format("DamageTotal_ITEM_RPR = %i", DamageTotal_ITEM_RPR);
            Hlp_PrintConsole (msg);
            */


            //    обработка после удара, например для спецэффектов, отравлений и прочего
            //Npc_PercEnable      (victim,    PERC_ASSESSDAMAGE,    B_AssessDamage_ITEM_RPR);
            return DamageTotal_ITEM_RPR;
        };

        return OldDamageTota;
    };


Daedalus:
func int OnDamage_Hit(var int damageTotal)
{

    var C_Item ReadiedWeapon;      

    ReadiedWeapon = Npc_GetReadiedWeapon(self);

    if    C_NpcIsEvil(victim) == TRUE
    {
        if        Hlp_IsItem(ReadiedWeapon , ItMw_1H_Blessed_01) == TRUE
        ||        Hlp_IsItem(ReadiedWeapon , ItMw_2H_Blessed_01) == TRUE
        {
            //damageTotal += SPL_Damage_PalHolyBolt;
        }
        else if Hlp_IsItem(ReadiedWeapon , ItMw_1H_Blessed_02) == TRUE
        ||        Hlp_IsItem(ReadiedWeapon , ItMw_2H_Blessed_02) == TRUE
        {
            //damageTotal += SPL_Damage_PalRepelEvil;
        }
        else if Hlp_IsItem(ReadiedWeapon , ItMw_1H_Blessed_03) == TRUE
        ||        Hlp_IsItem(ReadiedWeapon , ItMw_2H_Blessed_03) == TRUE
        {
            Npc_PercEnable      (victim,    PERC_ASSESSDAMAGE,    B_AssessDamage_Blessed_03);
        };
    };

    return damageTotal;
};



func void B_AssessDamage_Blessed_03 ()
{
    Npc_ClearAIQueue    (self);
    B_ClearPerceptions    (self);
    if    Npc_IsDead       (self)
    {
        return;
    };
 
    B_MagicHurtNpc (hero,self,(SPL_Damage_PalRepelEvil - self.protection[PROT_MAGIC]) );
    Wld_PlayEffect        ("spellFX_PalRepelEvil_COLLIDE", self, self, 0, 0, DAM_MAGIC, FALSE);
    //AI_StartState        (self, ZS_Blessed, 0, "");
    };

в примерах код отличается, так как один пример писало левое полушарие, а другой правое ;-)
 
Последнее редактирование:

.Unreal

Участник форума
Регистрация
21 Июн 2012
Сообщения
659
Благодарности
89
Баллы
210
Отдельные патчи
Патч - текстовый файл с расширением .patch, который необходимо создать в папке System.​
Исправляет баг, когда информации о заклинании теряется при эффектах урона по площади, а также передаются неверные параметры в C_CanNpcCollideWithSpell. Только для G2A.
Union:
#engine [G2A]
#patch [zSpellCollisionFix]
MemSet(0x004924E6, '90', 6) // disable "level = 1" reset in oCVisualFX::Init
HEX @0x00495B9A = '8B 74 24 14 90 90' // mov esi, dword ptr [esp+0x14] (use vobHit instead of target)
INT @0x00495C76 = 0x4AC // offset: use origin instead of inflictor in C_CanNpcCollideWithSpell call
#assembler [0x00495B29]
mov eax, dword ptr [ebp+0x4A8] ; origin
push eax
mov eax, dword ptr [esp+0x18] ; vobHit
push eax
lea eax, [ebp+0x278] ; emFXCollDyn_S
push eax
mov ecx, ebp ; this
call 0x0048EE80 ; oCVisualFX::CreateAndCastFX
mov esi, eax
test esi, esi
jz 0x00495B9A
#/assembler [0x00495B84]
#/patch
#/engine
Убирает прыжок с правой кнопки мыши. Только для G1.

Обнаружил, что подобный патч уже публиковался: https://worldofplayers.ru/threads/40376/page-55#post-1094951
Union:
#engine [G1]
#patch [zNoRMBJump]
HEX @0x004C8092 = 'EB'
#/patch
#/engine
Позволяет менять положение стандартного окна текстовых сообщений. Только для G1 и G2A.
Union:
#engine [G1]
#patch [zTextViewPos]
INT PosX = 2048
INT PosY = 0
INT SizeX = 4096
INT SizeY = 128

#assembler [0x00638CBA]
push $PosY
push $PosX
orgcode+2
#/assembler

#assembler [0x00638CDB]
pop eax
push $SizeY
push $SizeX
orgcode+1
#/assembler
#/patch
#/engine

#engine [G2A]
#patch [zTextViewPos]
INT PosX = 2048
INT PosY = 0
INT SizeX = 4096
INT SizeY = 1024

#assembler [0x006C2E6A]
push $PosY
push $PosX
orgcode+2
#/assembler

#assembler [0x006C2E8B]
pop eax
push $SizeY
push $SizeX
orgcode+1
#/assembler
#/patch
#/engine
Позволяет нормально стрелять даже с запредельным ускорением анимаций. Только для G2A.
Union:
#engine [G2A]
#patch [zAimDoEvents]
// engine specific
INT g1_start = ZenDef(0x0, 0x0, 0x0, 0x00696183)
INT g2_start = ZenDef(0x0, 0x0, 0x0, 0x006965BF)
INT field_oCAniCtrl_Human_npc = ZenDef(0x0, 0x0, 0x0, 0x12C)
INT vfunc_oCNpc_DoDoAniEvents = ZenDef(0x0, 0x0, 0x0, 0xD8)
// end of engine specific

#assembler [g1_start]
mov edx, [ecx]
call [edx+$vfunc_oCNpc_DoDoAniEvents]
mov ecx, [esi+$field_oCAniCtrl_Human_npc]
orgcode
#/assembler

#assembler [g2_start]
mov edx, [ecx]
call [edx+$vfunc_oCNpc_DoDoAniEvents]
mov ecx, [esi+$field_oCAniCtrl_Human_npc]
orgcode
#/assembler
#/patch
#/engine
Патч убирающий ходьбу/бег с клавиши CapsLock
Union:
#engine [G1, G2A]
#patch [zDisableWalkOnCaps]
// engine specific
INT text_oCAIHuman_PC_SlowMove_jz_capslock = ZenDef(0x00614265, 0x00000000, 0x00000000, 0x0069A39B)
// end of engine specific

HEX @text_oCAIHuman_PC_SlowMove_jz_capslock = 'EB'
#/patch
#/engine
Патч для любителей создавать "новые" шрифты путём переименования .FNT файлов. Теперь именем шрифта всегда будет считаться имя файла, а не строка, записанная туда.
Union:
#engine [G1, G1A, G2, G2A]
#patch [zDoNotLoadFontName]
// engine specific
INT asm_start = ZenDef(0x006E005F, 0x00718625, 0x0072990B, 0x0078934B)
// end of engine specific

INT dummyName = CreateMemString("")

#assembler [asm_start]
add esp, 4
push $dummyName
orgcode
#/assembler
#/patch
#/engine
Патч, убирающий анимацию тетивы при доставании/убирании лука. Только для G2A
Union:
#engine [G2A]
#patch [zBowRelaxFix]
#assembler [0x007395E4]
add esp, 12
#/assembler
#/patch
#/engine
Следующие патчи буду предлагать добавить в следующую тестовую версию Union. Эти патчи также доступны в виде единого архива.
Установка: поместить папку Patches из архива в директорию System
Убирает баг, когда событие смены слота в анимации не обнуляет корректно исходный слот (пропажа предметов в LoA).
Union:
#engine [G1, G1A, G2, G2A]
#patch [zExchangeInteractItemFix]
// engine specific
INT asm_start = ZenDef(0x006AECD9, 0x006E2549, 0x006F5969, 0x0075479B)
INT field_oCNpc_TNpcSlot_tmplevel = 0x18
// end of engine specific

#assembler [asm_start]
mov dword ptr [ebx+$field_oCNpc_TNpcSlot_tmplevel], 0
orgcode
#/assembler
#/patch
#/engine
Исправляет неограниченный рост счётчиков использования для элементов меню сохранения. Если хотите воспроизвести связанный с этим критический баг, откройте меню сохранения 2.2 миллиарда раз *trollface* .
Union:
#engine [G1, G1A, G2, G2A]
#patch [zSaveMenuItemLeakFix]
// engine specific
INT asm_start = ZenDef(0x0042D5FB, 0x00430847, 0x0042FB3E, 0x0042FE5E)

INT field_zCMenuItem_m_item_PlayTime = 0xCD8
INT field_zCMenuItem_m_item_DateTime = 0xCDC
INT field_zCMenuItem_m_item_WorldName = 0xCE0
INT field_zCMenuItem_m_item_GameTime = 0xCE4
// end of engine specific

IF ZenDef(1, 2, 3, 4) <= 2
INT field_zCMenuItem_m_iRefCtr = 0x358
INT field_zCMenuItem_registeredCPP = 0x3CC
INT vfunc_zCMenuItem_scalar_destructor = 0x20

#assembler [zCMenuItem_Release]
mov eax, [ecx+$field_zCMenuItem_m_iRefCtr]
dec eax
test eax, eax
mov [ecx+$field_zCMenuItem_m_iRefCtr], eax
jg return

mov eax, [ecx+$field_zCMenuItem_registeredCPP]
test eax, eax
jnz return

mov eax, [eax]
push 1
call [eax+$vfunc_zCMenuItem_scalar_destructor]

return:
ret

#/assembler

#assembler [asm_start]
orgcode

m_item_PlayTime:
mov ecx, [ebp+$field_zCMenuItem_m_item_PlayTime]
test ecx, ecx
jz m_item_DateTime
call $zCMenuItem_Release
mov [ebp+$field_zCMenuItem_m_item_PlayTime], esi

m_item_DateTime:
mov ecx, [ebp+$field_zCMenuItem_m_item_DateTime]
test ecx, ecx
jz m_item_WorldName
call $zCMenuItem_Release
mov [ebp+$field_zCMenuItem_m_item_DateTime], esi

m_item_WorldName:
mov ecx, [ebp+$field_zCMenuItem_m_item_WorldName]
test ecx, ecx
jz m_item_GameTime
call $zCMenuItem_Release
mov [ebp+$field_zCMenuItem_m_item_WorldName], esi

m_item_GameTime:
mov ecx, [ebp+$field_zCMenuItem_m_item_GameTime]
test ecx, ecx
jz return
call $zCMenuItem_Release
mov [ebp+$field_zCMenuItem_m_item_GameTime], esi

return:
#/assembler
ELSE
INT func_zCMenuItem_Release = ZenDef(0x0, 0x0, 0x0047C150, 0x0047D620)

#assembler [asm_start]
orgcode

m_item_PlayTime:
mov ecx, [esi+$field_zCMenuItem_m_item_PlayTime]
test ecx, ecx
jz m_item_DateTime
call $func_zCMenuItem_Release
mov [esi+$field_zCMenuItem_m_item_PlayTime], edi

m_item_DateTime:
mov ecx, [esi+$field_zCMenuItem_m_item_DateTime]
test ecx, ecx
jz m_item_WorldName
call $func_zCMenuItem_Release
mov [esi+$field_zCMenuItem_m_item_DateTime], edi

m_item_WorldName:
mov ecx, [esi+$field_zCMenuItem_m_item_WorldName]
test ecx, ecx
jz m_item_GameTime
call $func_zCMenuItem_Release
mov [esi+$field_zCMenuItem_m_item_WorldName], edi

m_item_GameTime:
mov ecx, [esi+$field_zCMenuItem_m_item_GameTime]
test ecx, ecx
jz return
call $func_zCMenuItem_Release
mov [esi+$field_zCMenuItem_m_item_GameTime], edi

return:
#/assembler
END
#/patch
#/engine
Исправляет баг, когда переход в небоевой режим с помощью хоткея карты не сбрасывал режим фокусировки объектов и камеры.
Union:
#engine [G1, G1A, G2, G2A]
#patch [zSetWeaponModeFix]
// engine specific
INT asm_start = ZenDef(0x00696596, 0x006C80F1, 0x006DB246, 0x00739986)
INT field_oCNpc_human_ai = ZenDef(0x9B4, 0x9BC, 0x8E8, 0x97C)
INT offset_CamModNormal = ZenDef(0x0086A108, 0x008AFA48, 0x008C0390, 0x008CE9F0)

INT func_oCAIHuman_SetCamMode = ZenDef(0x0060FE40, 0x00632AD0, 0x00639390, 0x00695A60)
INT func_oCNpc_SetFocusMode = ZenDef(0x00634E60, 0x0065AFF0, 0x00662290, 0x006BEC20)
// end of engine specific

#assembler [asm_start]
orgcode
test eax, eax
jnz return

mov ecx, [esi+$field_oCNpc_human_ai]
cmp ecx, edi
je focus

push edi
push $offset_CamModNormal
call $func_oCAIHuman_SetCamMode

focus:
push 0
call $func_oCNpc_SetFocusMode
add esp, 4
pop edi
pop esi
ret 4

return:
#/assembler
#/patch
#/engine
Устраняет вылет при появлении трансформированной сущности в воде.
Union:
#engine [G1, G1A, G2, G2A]
#patch [zTrafoInWaterFix]
// engine specific
INT asm_start = ZenDef(0x004FEE84, 0x00512316, 0x0050BC44, 0x0050E9F4)
INT asm_away = ZenDef(0x004FF788, 0x00512CA8, 0x0050C4B2, 0x0050F268)

INT field_zCVob_homeWorld = ZenDef(0xA8, 0xA8, 0xB8, 0xB8)
// end of engine specific

#assembler [asm_start]
push ecx
mov ecx, [ecx+$field_zCVob_homeWorld]
test ecx, ecx
pop ecx
jz $asm_away
orgcode
#/assembler
#/patch
#/engine
Известно, что при открытом дневнике или окне характеристик игровой интерфейс (в движке известен как PlayerStatus) не должен отображаться. Поэтому при открытии дневника или окна характеристик сначала запоминается, отображается ли интерфейс, затем он принудительно скрывается. После закрытия меню отображение интерфейса возвращается к исходному запомненному состоянию.

Однако, при открытии дневника или окна характеристик игровой мир живёт как обычно 1 кадр и лишь только потом наступает полноценная пауза. Во время этого кадра интерфейс может снова появиться (например, если за время этого кадра закончился диалог), что не желательно. Ещё хуже, что после закрытия меню, интерфейс снова исчезнет (так как меню было открыто во время диалога, когда интерфейс не отображался) и будет отсутствовать до, например, окончания следующего диалога.

Данный патч призван решить эту проблему.
Во-первых, все попытки изменить состояние интерфейса во время отображения окна характеристик или дневника будут проигнорированы, но запомнены.
Во-вторых, при закрытии вышеуказанных меню интерфейс начнёт отображаться не только если это было до его открытия, но и если последняя проигнорированная попытка изменить статус отображения интерфейса была попыткой включить его.
Union:
#engine [G1, G1A, G2, G2A]
#patch [zMenuIgnorePlayerStatus]
// engine specific
INT set_show_player_status_start = ZenDef(0x00638BE6, 0x0065F136, 0x00666296, 0x006C2D96)
INT set_show_player_status_epilogue = ZenDef(0x00638C3A, 0x0065F18A, 0x006662EA, 0x006C2DEA)

INT log_start = ZenDef(0x0069A299, 0x006CC203, 0x006DF004, 0x0073D824)
INT status_start = ZenDef(0x0069A9D1, 0x006CC97D, 0x006DF705, 0x0073DF25)
// end of engine specific

INT ignore_set_show_player_status = 0
INT last_value_set_show_player_status = 0

#assembler [set_show_player_status_start]
mov [$last_value_set_show_player_status], edi
mov eax, [$ignore_set_show_player_status]
test eax, eax
jnz $set_show_player_status_epilogue
orgcode
#/assembler

IF ZenDef(1, 2, 3, 4) <= 2
#assembler [log_start]
mov eax, [$ignore_set_show_player_status]
inc eax
mov [$ignore_set_show_player_status], eax

xor eax, eax
mov [$last_value_set_show_player_status], eax

orgcode

mov eax, [$ignore_set_show_player_status]
dec eax
mov [$ignore_set_show_player_status], eax

test eax, eax
jnz return

mov eax, [$last_value_set_show_player_status]
or esi, eax

return:
#/assembler
ELSE
#assembler [log_start]
mov eax, [$ignore_set_show_player_status]
inc eax
mov [$ignore_set_show_player_status], eax

xor eax, eax
mov [$last_value_set_show_player_status], eax

orgcode

mov eax, [$ignore_set_show_player_status]
dec eax
mov [$ignore_set_show_player_status], eax

test eax, eax
jnz return

mov eax, [$last_value_set_show_player_status]
or edi, eax

return:
#/assembler
END

#assembler [status_start]
mov eax, [$ignore_set_show_player_status]
inc eax
mov [$ignore_set_show_player_status], eax

xor eax, eax
mov [$last_value_set_show_player_status], eax

orgcode

mov eax, [$ignore_set_show_player_status]
dec eax
mov [$ignore_set_show_player_status], eax

test eax, eax
jnz return

mov eax, [$last_value_set_show_player_status]
or edi, eax

return:
#/assembler
#/patch
#/engine
Проблемы, которые решает данный патч:
  1. NPC продолжают поворачиваться во время паузы. Решено путём отключения обработки ИИ при нулевом времени кадра.
  2. Может пропускаться обработка событий связанных с каким-либо vob-ом. Одно из проявлений: из руки не исчезает напиток после употребления.
Union:
#engine [G1, G1A, G2, G2A]
#patch [zCEventManager_DoFrameActivity_Fix]
// engine specific
INT loop_begin = ZenDef(0x006DCC8F, 0x00714E3F, 0x0072653F, 0x00785F7F)
INT loop_end = ZenDef(0x006DCCB2, 0x00714E62, 0x00726562, 0x00785FA2)

INT offset_zCEventManager_activeEM = ZenDef(0x008DC704, 0x00924940, 0x00984504, 0x00AB39BC)
INT offset_zCEventManager_activeEM_parray = offset_zCEventManager_activeEM
INT offset_zCEventManager_activeEM_numinarray = offset_zCEventManager_activeEM + 0x8
INT offset_ztimer = ZenDef(0x008CF1E8, 0x009150C0, 0x00974C7C, 0x0099B3D4)
INT offset_ztimer_frameTimeFloat = offset_ztimer + 0x4

INT field_zCObject_refCtr = 0x4
INT field_zCEventManager_active = 0x28

INT func_zCObject_Release = ZenDef(0x0042AC30, 0x0042DB30, 0x0040C310, 0x0040C310)

INT vfunc_zCEventManager_ProcessMessageList = 0x64
// end of engine specific

#assembler [loop_begin]
orgcode

mov ecx, $offset_ztimer_frameTimeFloat
mov ecx, [ecx]
test ecx, ecx
jz return

mov ecx, $offset_zCEventManager_activeEM_parray
mov ecx, [ecx]

copy_loop:
test eax, eax
jz process
dec eax

mov edx, [ecx+eax*0x4]
push edx

test edx, edx
jz copy_loop

push ecx
mov ecx, [edx+$field_zCObject_refCtr]
inc ecx
mov [edx+$field_zCObject_refCtr], ecx
pop ecx

jmp copy_loop

process:
mov eax, $offset_zCEventManager_activeEM_numinarray
mov eax, [eax]

process_loop:
dec eax

pop ecx
test ecx, ecx
jz process_continue

push eax
push ecx
call $func_zCObject_Release
pop ecx
test eax, eax
pop eax
jle process_continue

mov edx, [ecx+$field_zCEventManager_active]
test edx, edx
jz process_continue

push eax
mov edx, [ecx]
call [edx+$vfunc_zCEventManager_ProcessMessageList]
pop eax

process_continue:
test eax, eax
jnz process_loop

return:
pop esi
ret
#/assembler [loop_end]
#/patch
#/engine
Патч адресован ситуации, когда посторонний NPC прерывая свою реплику мог закрыть основное диалоговое окно (субтитры). С патчем же, только NPC в состоянии ZS_TALK будет способен на такое.
Union:
#engine [G1, G1A, G2, G2A]
#patch [zCloseConversationFix]
// engine specific
INT init_begin = ZenDef(0x006338C8, 0x00659738, 0x006608BD, 0x006BD24D)
INT init_end = init_begin + 6

INT close_view_begin = ZenDef(0x00633947, 0x006597B5, 0x00660957, 0x006BD2E7)
INT close_view_end = close_view_begin + 5

INT offset_parser = ZenDef(0x008DCE08, 0x00925048, 0x00984C08, 0x00AB40C0)
INT offset_ptr_player = ZenDef(0x008DBBB0, 0x00923134, 0x009831DC, 0x00AB2684)

INT func_zCParser_GetIndex = ZenDef(0x006EA0C0, 0x00723120, 0x00733A30, 0x00793470)
INT func_oCNpc_States_IsInState = ZenDef(0x006C4C90, 0x006FA3C0, 0x0070CAE0, 0x0076C040)

INT field_oCNpc_state = ZenDef(0x470, 0x470, 0x4FC, 0x588)
// end of engine specific

INT gothic_version = ZenDef(1, 2, 3, 4)

INT zs_talk = CreateMemString("ZS_TALK")
INT zs_talk_index = -2

INT zs_tria = CreateMemString("ZS_TRIA")
INT zs_tria_index = -2

IF gothic_version <= 2
#assembler [init_begin]
orgcode

mov eax, [$zs_talk_index]
mov edx, -2
cmp eax, edx
jne $init_end

push $zs_talk
mov ecx, $offset_parser
call $func_zCParser_GetIndex
mov [$zs_talk_index], eax

push $zs_tria
mov ecx, $offset_parser
call $func_zCParser_GetIndex
mov [$zs_tria_index], eax

mov ecx, edi
#/assembler [init_end]

#assembler [close_view_begin]
mov eax, $offset_ptr_player
mov eax, [eax]
cmp eax, edi
je close_view

mov eax, [$zs_talk_index]
test eax, eax
jl check_tria

push ecx
lea ecx, [edi+$field_oCNpc_state]
push eax
call $func_oCNpc_States_IsInState
test eax, eax
pop ecx
jnz close_view

check_tria:
mov eax, [$zs_tria_index]
test eax, eax
jl $close_view_end

push ecx
lea ecx, [edi+$field_oCNpc_state]
push eax
call $func_oCNpc_States_IsInState
test eax, eax
pop ecx
jz $close_view_end

close_view:
orgcode
#/assembler [close_view_end]
ELSE
INT archolos_sym_name = CreateMemString("KURT_ARCHOLOS_HISTORY")
INT is_archolos_mod = 0

#assembler [init_begin]
orgcode

mov eax, [$zs_talk_index]
mov edx, -2
cmp eax, edx
jne $init_end

push $zs_talk
mov ecx, $offset_parser
call $func_zCParser_GetIndex
mov [$zs_talk_index], eax

push $zs_tria
mov ecx, $offset_parser
call $func_zCParser_GetIndex
mov [$zs_tria_index], eax

mov eax, $gothic_version
cmp eax, 4
jne restore_ecx

push $archolos_sym_name
mov ecx, $offset_parser
call $func_zCParser_GetIndex
test eax, eax
jl restore_ecx

mov dword ptr [$is_archolos_mod], 1

restore_ecx:
mov ecx, ebx
#/assembler [init_end]

#assembler [close_view_begin]
mov eax, [$is_archolos_mod]
test eax, eax
jnz close_view

mov eax, $offset_ptr_player
mov eax, [eax]
cmp eax, ebx
je close_view

mov eax, [$zs_talk_index]
test eax, eax
jl check_tria

push ecx
lea ecx, [ebx+$field_oCNpc_state]
push eax
call $func_oCNpc_States_IsInState
test eax, eax
pop ecx
jnz close_view

check_tria:
mov eax, [$zs_tria_index]
test eax, eax
jl $close_view_end

push ecx
lea ecx, [ebx+$field_oCNpc_state]
push eax
call $func_oCNpc_States_IsInState
test eax, eax
pop ecx
jz $close_view_end

close_view:
orgcode
#/assembler [close_view_end]
END
#/patch
#/engine
Исправляет баг, из-за которого все NPC, включая игрока, не могли убрать оружие при ходьбе в глубокой воде. Подобный фикс входит в состав плагина zBugFixes, но здесь более бесшовная реализация с помощью патча.

Также назначает корректные анимации убирания оружия, когда персонаж стоит (G2 & G2A).
Union:
// When you remove weapon during water walk the AI starves.
//
// Also in EV_RemoveWeapon the stand animations are mistakenly tested so the animations
// for moving may be mistakenly started while the character is standing.
// Occurs, for example, if you press '1' to remove a weapon.

#engine [G2, G2A]
#patch [zRemoveWeaponFix]
// engine specific
INT text_EV_RemoveWeapon_check_s_run = ZenDef(0x00000000, 0x00000000, 0x006EEEE1, 0x0074DC98)
INT text_EV_RemoveWeapon_check_s_run_final_test = ZenDef(0x00000000, 0x00000000, 0x006EEEF8, 0x0074DCAF)

INT text_EV_RemoveWeapon_check_s_walk = ZenDef(0x00000000, 0x00000000, 0x006EF017, 0x0074DDCE)
INT text_EV_RemoveWeapon_fail_check_s_walk = ZenDef(0x00000000, 0x00000000, 0x006EF036, 0x0074DDED)

INT text_EV_RemoveWeapon_check_s_sneak = ZenDef(0x00000000, 0x00000000, 0x006EF1C6, 0x0074DF9D)
INT text_EV_RemoveWeapon_fail_check_s_sneak = ZenDef(0x00000000, 0x00000000, 0x006EF206, 0x0074DFD7)

INT func_zCModel_GetAniFromAniID = ZenDef(0x0046D1E0, 0x00475680, 0x00471E30, 0x00472F50)
INT func_zCModel_IsAniActive = ZenDef(0x0046D220, 0x004756D0, 0x00471E70, 0x00472F90)

INT field_oCAniCtrl_Human_s_walkwl = 0xFD8
// end of engine specific

#assembler [text_EV_RemoveWeapon_check_s_run]
mov eax, [edi+$field_oCAniCtrl_Human_s_walkwl]
push eax
mov ecx, esi
call $func_zCModel_GetAniFromAniID

push eax
mov ecx, esi
call $func_zCModel_IsAniActive
#/assembler [text_EV_RemoveWeapon_check_s_run_final_test]

JMP(text_EV_RemoveWeapon_check_s_walk, text_EV_RemoveWeapon_fail_check_s_walk)
JMP(text_EV_RemoveWeapon_check_s_sneak, text_EV_RemoveWeapon_fail_check_s_sneak)
#/patch
#/engine
При наложении/удаления оверлея боевые анимации персонажа обновляются мгновенно.
Union:
#engine [G1, G1A, G2, G2A]
#patch [zAlwaysSetFightAnis]
// engine specific
INT text_oCAniCtrl_Human_InitAnimations_call_InitAllAnis = ZenDef(0x0061C6D5, 0x0064016F, 0x00648475, 0x006A4CF5)

INT field_oCAniCtrl_Human_npc = 0x12C

INT func_oCNpc_GetWeaponMode = ZenDef(0x00695820, 0x006C7230, 0x006DA500, 0x00738C40)
INT func_oCAniCtrl_Human_SetFightAnis = ZenDef(0x00622400, 0x00646AF0, 0x0064E1C0, 0x006AAA40)
// end of engine specific

#assembler [text_oCAniCtrl_Human_InitAnimations_call_InitAllAnis]
orgcode

mov ecx, [esi+$field_oCAniCtrl_Human_npc]
test ecx, ecx
jz return

call $func_oCNpc_GetWeaponMode

push eax
mov ecx, esi
call $func_oCAniCtrl_Human_SetFightAnis

return:
#/assembler
#/patch
#/engine
Варианты диалога будут выбираться начиная с клавиши 1, а не с клавиши 0.
Union:
#engine [G1, G1A, G2, G2A]
#patch [zDialogChoiceStartKey]
// engine specific
INT text_zCViewDialogChoice_cmp_eax_9 = ZenDef(0x00758B0E, 0x0079B0C6, 0x007A59D4, 0x0068EC64)
INT text_zCViewDialogChoice_return_true = ZenDef(0x00758B3C, 0x0079B0F4, 0x007A5A2E, 0x0068EC92)
INT text_zCViewDialogChoice_return_false = ZenDef(0x00758A7A, 0x0079AFDA, 0x007A592A, 0x0068EBBA)

INT func_zCViewDialogChoice_Select = ZenDef(0x007592C0, 0x0079B870, 0x007A61A0, 0x0068F440)
// end of engine specific

#assembler [text_zCViewDialogChoice_cmp_eax_9]
cmp eax, 9
jg $text_zCViewDialogChoice_return_false

cmp eax, 0
jl $text_zCViewDialogChoice_return_false

mov edx, eax
mov ecx, esi
call $func_zCViewDialogChoice_Select
jmp $text_zCViewDialogChoice_return_true
#/assembler
#/patch
#/engine
undefined
Slavemaster, а отдельные патчи с расширением .patch типо zBowRelaxFix нужно поместить просто в папку System? А те, что из папки Patches - в папку System\Patches, да? И где можно скачать обновленный архив патчей (папку Patches), если такой есть? Что-то не вижу ссылки на архив патчей. Или подразумевалось самому делать все патчики?
 
Сверху Снизу