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

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

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

Gratt


Модостроитель
Регистрация
14 Ноя 2014
Сообщения
3.440
Благодарности
4.791
Баллы
625
  • Первое сообщение
  • #1
1767600363729.png

RU EN

 

MEG@VOLT

★★★★★★★★★
ТехАдмин
Регистрация
24 Мар 2006
Сообщения
10.711
Благодарности
7.442
Баллы
1.910
Скорей всего пользуетесь пиратской версией игры. Не корректно прописаны названия файлов и папок..
Обижаете. Я пытался ставить его и на стим лицензию, и на пиратку. Один как говориться...
Пост автоматически объединён:

Там скорее всего CRC exe файлов не совпадают.
Пусть попробует поставить на Г1 World of Gothic - Downloads - Gothic - Playerkit v1.08k
На Г2a (gothic2_fix-2.6.0.0-rev2.exe) World of Gothic - Downloads - Report-Versionen: Gothic2.exe
Да, действительно получилось. Правда у меня стоял стим фикс, и не понятно, вроде в стим фиксе уже есть плеер кит. Вопрос теперь в том, как установить юнион на сиквел. Я не уверен что плеер кит можно поставить на сиквел
 

Gratt


Модостроитель
Регистрация
14 Ноя 2014
Сообщения
3.440
Благодарности
4.791
Баллы
625
Flatcher0220, ехешники с неопределенным crc кидай мне в ЛС, для г2а их вариаций больше, чем в остальных трёх вместе взятых.
С сиквелом проще всего, существует только 4 ехешника и все они есть в базе.
 

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.377
Благодарности
7.864
Баллы
995
ехешники с неопределенным crc кидай мне в ЛС, для г2а их вариаций больше,
по г2 все лицензии у тебя также в базе есть, остальное либо пираченное либо патченное...
 

N1kX

Участник форума
Регистрация
13 Ноя 2009
Сообщения
6.614
Благодарности
6.224
Баллы
940
У поляк увидел, что пакет может не установиться, если в пути содержится спец символ (польский).
Пример из сообщения пользователя (перевел).
При установке последней версии у меня выскакивает ошибка:
Invalid path. Exclude characters:
__________ł____________________
Плохо устанавливается или что?

Папка в конце пути имеет вид
Gothic II Złota Edycja
Переименование в Gothic II Zlota Edycja, решает проблему.
 

Gratt


Модостроитель
Регистрация
14 Ноя 2014
Сообщения
3.440
Благодарности
4.791
Баллы
625
N1kX, нет, все хорошо установилось. Известно, что движок дружит только с латиницей. Поэтому если в пути имеются потенциально вредные символы, юнион при запуске выбивает сообщение, в котором указаны сами символы и их позиция в тексте.
ЗЫ Да, уже обсуждали, что юзеру этот мессаг неочевиден, я обещал его переделать в следующих сборках. Без него игра тупо уйдет в краш с неинформативным калстеком. А это ведь одна из самых распространенных ошибок игроков за все 20 лет существования игры *around the head*
 

N1kX

Участник форума
Регистрация
13 Ноя 2009
Сообщения
6.614
Благодарности
6.224
Баллы
940
OFFTOP

У меня доступа в закрытую тему по предложениям по SP/Union нет. Там недавно оставили сообщение от моего имени. Хотелось бы узнать, ошибка пошла из-за движка или из-за SP? А то неприятно и приходится переделывать столько переменных, инстанции и пр.

 

Slavemaster


Модостроитель
Регистрация
10 Июн 2019
Сообщения
1.147
Благодарности
2.023
Баллы
320
N1kX, если ты про неверный результат Npc_HasItems или подмену одних инстанций в инвентаре на другие, то это баг движка. Есть код на юне, который должен исправлять эту проблему:
C++:
    bool Compare(const char* x, const char* y, int len)
    {
        while (len)
        {
            if (*x != *y)
                return false;
            x += 1;
            y += 1;
            len -= 1;
        }
        return true;
    }

    int GetInt(const char* x, int len)
    {
        int num = 0;
        while (len--)
        {
            num = num * 10 + (*x - '0');
            x += 1;
        }
        return num;
    }

    struct TPackStrElem
    {
        int startIndex;
        int colonIndex;
        int endIndex;

        inline int GetAmount(const char* pStr) const
        {
            return GetInt(pStr + colonIndex + 1, endIndex - colonIndex);
        }

        inline bool HasName(const char* pStr, const char* name, int nLen) const
        {
            if (colonIndex - startIndex != nLen)
                return false;
            return Compare(pStr + startIndex, name, nLen);
        }

        inline int GetLen() const
        {
            return endIndex - startIndex + 1;
        }
    };

    void Parse(const char* pStr, int pLen, Array<TPackStrElem> & elems)
    {
        TPackStrElem elem;
        elem.startIndex = 0;
        elem.colonIndex = -1;

        for (int i = 0; i <= pLen; i++)
        {
            if (i == pLen && elem.colonIndex != -1 || pStr[i] == ',')
            {
                elem.endIndex = i - 1;
                elems.InsertEnd(elem);
                elem.startIndex = i + 1;
                elem.colonIndex = -1;
            }
            else if (pStr[i] == ':')
                elem.colonIndex = i;
        }
    }

    int __fastcall Hook_oCNpcInventory_GetPackedItemInfo(oCNpcInventory*, void*, zSTRING const&, int, int&, int&);
    CInvoke<int(__thiscall*)(oCNpcInventory*, zSTRING const&, int, int&, int&)> Ivk_oCNpcInventory_GetPackedItemInfo(ZenDef<TInstance>(0x0066FDF0, 0x0069D560, 0x006B1D60, 0x0070F8F0), &Hook_oCNpcInventory_GetPackedItemInfo, IvkEnabled(CurrentEngine));
    int __fastcall Hook_oCNpcInventory_GetPackedItemInfo(oCNpcInventory * _this, void* vtable, zSTRING const& name, int remove, int& amount, int& e)
    {
        if (!_this->packAbility)
            return 0;

        amount = 0;
        e = -1;

#if CurrentEngine == Engine_G1 || CurrentEngine == Engine_G1A
        for (int invNr = 0; invNr < INV_MAX; invNr++)
        {
            zSTRING& packString = _this->packString[invNr];
#else
            zSTRING& packString = _this->packString;
#endif

            const int pLen = packString.Length();
            if (!pLen)
#if CurrentEngine == Engine_G1 || CurrentEngine == Engine_G1A
                continue;
#else
                return 0;
#endif

            const char* pStr = packString.ToChar();
            const char* nStr = name.ToChar();
            const int nLen = name.Length();

            Array<TPackStrElem> elems;
            Parse(pStr, pLen, elems);

            Array<bool> remFlags;
            for (int i = 0; i < (int)elems.GetNum(); i++)
            {
                const TPackStrElem& e = elems[i];
                bool nameMatched = e.HasName(pStr, nStr, nLen);
                if (nameMatched)
                    amount += max(0, e.GetAmount(pStr));
                if (remove)
                    remFlags.InsertEnd(nameMatched);
            }

            if (remFlags.GetNum())
            {
                std::unique_ptr<char[]> newStr = std::make_unique<char[]>(pLen + 1);
                int newStrLen = 0;
                for (int i = 0; i < (int)elems.GetNum(); i++)
                {
                    const TPackStrElem& e = elems[i];
                    if (remFlags[i])
                        continue;
                    if (newStrLen)
                        newStr[newStrLen++] = ',';
                    CopyMemory(newStr.get() + newStrLen, pStr + e.startIndex, e.GetLen());
                    newStrLen += e.GetLen();
                }
                newStr[newStrLen++] = '\0';
                packString = newStr.get();
            }

#if CurrentEngine == Engine_G1 || CurrentEngine == Engine_G1A
        }
#endif

        return amount ? 1 : 0;
    }

    int __fastcall Hook_oCNpcInventory_GetAmount(oCNpcInventory*, void*, int);
    CInvoke<int(__thiscall*)(oCNpcInventory*, int)> Ivk_oCNpcInventory_GetAmount(ZenDef<TInstance>(0x0066CAC0, 0x0069A240, 0x006AEE80, 0x0070C970), &Hook_oCNpcInventory_GetAmount, IvkEnabled(CurrentEngine));
    int __fastcall Hook_oCNpcInventory_GetAmount(oCNpcInventory* _this, void* vtable, int instance)
    {
        if (instance < 0)
            return 0;
        int amount = 0;

#if CurrentEngine == Engine_G1 || CurrentEngine == Engine_G1A
        for (int invNr = 0; invNr < INV_MAX; invNr++)
        {
            const zCListSort<oCItem>& inventory = _this->inventory[invNr];
#else
            const zCListSort<oCItem>& inventory = _this->inventory;
#endif

            for (zCListSort<oCItem>* list = inventory.GetNextInList(); list; list = list->GetNextInList())
                if (list->GetData()->GetInstance() == instance)
                    amount += list->GetData()->amount;
#if CurrentEngine == Engine_G1 || CurrentEngine == Engine_G1A
        }
#endif

        if (!_this->packAbility)
            return amount;

        zCPar_Symbol* symbol = parser->GetSymbol(instance);
        if (!symbol)
            return amount;

        int packedAmount, e;
        if (_this->GetPackedItemInfo(symbol->name, false, packedAmount, e))
            amount += packedAmount;

        return amount;
    }
В качестве альтернативы, можно попробовать вызывать oCNpcInventory::UnpackAllItems() перед любым взаимодействием с инвентарем.
Исправление в виде плагина:
 

Вложения

  • Union_Experiment.dll.zip
    56 KB · Просмотры: 36
Последнее редактирование:

Vic7im

Участник форума
Регистрация
15 Мар 2016
Сообщения
49
Благодарности
18
Баллы
175
I have decided to give this a try, at least you guys had the courtesy to translate the instructions to english, something I, as a non-english user, thoroughly approve and endorse.
Thank you for this!
 

MEG@VOLT

★★★★★★★★★
ТехАдмин
Регистрация
24 Мар 2006
Сообщения
10.711
Благодарности
7.442
Баллы
1.910
Вот ещё вопрос. А как удалить юнион? Я для тестов поставил его туда, где он мне вообще не нужен
 

MEG@VOLT

★★★★★★★★★
ТехАдмин
Регистрация
24 Мар 2006
Сообщения
10.711
Благодарности
7.442
Баллы
1.910

N1kX

Участник форума
Регистрация
13 Ноя 2009
Сообщения
6.614
Благодарности
6.224
Баллы
940
Там нет инструкции для удаления... Я понятия не имею какие файлы добавляет менджер что бы удалять их в ручную
Удали в gothic (1/2)\system Union.patch, Union.ini, Vdfs32e.exe, Vdfs32g.exe
Из папки .backup скопируй сохраненные копии файлов с заменой в gothic (1/2)\system

Да, неплохо было бы сделать деинсталятор:)
 

Gratt


Модостроитель
Регистрация
14 Ноя 2014
Сообщения
3.440
Благодарности
4.791
Баллы
625
Flatcher0220, N1kX, поскольку это менеджер и заранее он не в курсе о ваших планах, он предложит действие только после выбора каталога. То бишь равно также, как при установке.

Если пакет уже был установлен, он спросит, что сделать дальше:
1584460135784.png

1584460119788.png

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

alexeich2019

Участник форума
Регистрация
28 Июн 2019
Сообщения
191
Благодарности
73
Баллы
175
Gratt, мб добавить опцию "Удалить пакет" по клику ПКМ на пакете? А то не совсем очевидно.
 

Gratt


Модостроитель
Регистрация
14 Ноя 2014
Сообщения
3.440
Благодарности
4.791
Баллы
625
alexeich2019, я то конечно могу добавить, но один фиг установочные пакеты - это скрипты на языке union'а (тоже самое, что .patch файлы). И менеджер в данном случае выступает инициатором их выполнения. Проще изменить локализацию менюшки 'выполнить' на 'установить/удалить', чем менять скрипт каждого пакета.
 

Vic7im

Участник форума
Регистрация
15 Мар 2016
Сообщения
49
Благодарности
18
Баллы
175
Gratt Sorry for the ping, but I get this error when adding zParserExtender plugin to Union:

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

Edit: Error message is: U: PAR: Expected '{' (line 143)

I have already installed other plugins and they all work correctly, this and the zTrollStoneThrowing are the only ones that are left (and I see that zTrollStoneThrowing uses zParserExtender to work).

Could you help me fix this issue? Thank you and wonderful work with Union. I have bashed my head so many times on Ikarus and LeGo crashes that I almost decided to give up modding for good. Thanks to Union, I think I can still do something for the awesome community this game still has.
 
Последнее редактирование:

Gratt


Модостроитель
Регистрация
14 Ноя 2014
Сообщения
3.440
Благодарности
4.791
Баллы
625
Vic7im, Hi, thanks for reports
You noticed correctly. The zTrollStoneThrowing really uses the zParserExtender, but modified version. After updating the parser plugin all problems will be fixed, but first I need to fix problems with the Resource Manager server. I recommend temporarily using these plugins separately (~week or a half). Sorry for the inconvenience.
 

TheKlayc

Участник форума
Регистрация
2 Янв 2018
Сообщения
40
Благодарности
13
Баллы
170
Есть у кого нибудь плагин, добавляющий свободное прицеливание? Заранее спасибо.
 
Сверху Снизу