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

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

Union SDK - Инструменты разработчика

Gratt


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


Union SDK

инструменты разработчика

Тема находится в состоянии наполнения



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

Рекомендуется смотреть на YouTube, поскольку там имеется сегментированный таймлайн.






Схемы классов движка
1600263933953.png
1600263981919.png
1600264017579.png
 

Вложения

  • sizeof.xlsx
    896,7 KB · Просмотры: 73
  • Union_SDK_1_0m.zip
    20,6 MB · Просмотры: 88
Последнее редактирование:

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.003
Благодарности
973
Баллы
295
реализация отключения возможности сохранения это полезное дело. иногда нужно дать возможность игроку прочувствовать и пострадать какие то моменты в игре :)
 

MEG@VOLT

★★★★★★★★★
ТехАдмин
Регистрация
24 Мар 2006
Сообщения
9.879
Благодарности
6.761
Баллы
1.625
@MEG@VOLT, кодд в студию :)

C++:
  zCMenuItem* pMenuResume;
  void Game_Loop() {  
        if (kakatoperemennaya == true) {
            pMenuResume = zCMenuItem::GetByName("MENUITEM_MAIN_SAVEGAME_SAVE");
            pMenuResume->m_parItemFlags |= IT_DISABLED;
            pMenuResume->DrawFront();
            // тут что-то происходит
            pMenuResume->m_parItemFlags &= ~IT_DISABLED;
            pMenuResume->DrawFront();
            ogame->s_bUseQuickSave = 1;
            kakatoperemennaya = false;
            return;
        }
  }

Позови когда он код скинет, я за плетью пошёл *gigi*
1703517428154.jpeg
 
Последнее редактирование:

Slavemaster


Модостроитель
Регистрация
10 Июн 2019
Сообщения
1.085
Благодарности
1.903
Баллы
320
Нестандартный синтаксис, но суть должна быть понятна:
C++:
int __fastcall Hook_CGameManager_MenuEnabled(CGameManager*, void*, int&);
Hook<int(__thiscall*)(CGameManager*, int&)> Ivk_CGameManager_MenuEnabled(ZENFOR(0x00429140, 0x0042BDF0, 0x0042A7D0, 0x0042AAF0), &Hook_CGameManager_MenuEnabled, HookMode::Patch);
int __fastcall Hook_CGameManager_MenuEnabled(CGameManager* _this, void* vtable, int& a0)
{
    int result = Ivk_CGameManager_MenuEnabled(_this, a0);

    a0 = a0 && allowSave;

    return result;
}
pMenuResume = zCMenuItem::GetByName("MENUITEM_MAIN_SAVEGAME_SAVE");
После этой функции надо ->Release() вызывать в конце
 

MEG@VOLT

★★★★★★★★★
ТехАдмин
Регистрация
24 Мар 2006
Сообщения
9.879
Благодарности
6.761
Баллы
1.625
MEG@VOLT, поставь любой плагин квиксейва нормальный, например Хаарта и проверь как у тебя работает его запрет. :)
Ок, погляжу.
После этой функции надо ->Release() вызывать в конце
Угу, оно у меня есть)
 

MEG@VOLT

★★★★★★★★★
ТехАдмин
Регистрация
24 Мар 2006
Сообщения
9.879
Благодарности
6.761
Баллы
1.625
Xeдин, с плагином Хаарта, как и ожидалось - не сканало)
я правильно хукнул?
C++:
    CInvoke<void(*)()> Hook_CGameManager_Write_Save(&CGameManager::Write_Savegame, &CGameManager::Write_Savegame_Union);
    void CGameManager::Write_Savegame_Union(int) {
        // тут что-нить выводим на экран
        if (kakatoperemennaya == true) { return; }
    }
Если да, то не хочет хукаться, на экран не выводится, на переменную пофиг...
 

Xeдин


Модостроитель
Регистрация
3 Дек 2008
Сообщения
1.461
Благодарности
1.983
Баллы
365
MEG@VOLT,
C++:
    HOOK Ivk_CGameManager_Write_Savegame_MyPlugin   PATCH(&CGameManager::Write_Savegame, &CGameManager::Write_Savegame_MyPlugin);
    void CGameManager::Write_Savegame_MyPlugin(int key) {
        if (твое условие) {
             //выводим сообщение
            return;
        }
        THISCALL(Ivk_CGameManager_Write_Savegame_MyPlugin)(key);
    }

В CGameManager.inl
void Write_Savegame_MyPlugin(int);
 

MEG@VOLT

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

N1kX


Модостроитель
Регистрация
13 Ноя 2009
Сообщения
6.160
Благодарности
5.665
Баллы
910
Отлично работает. Спасибо!


А вот про это даже не подозревал. Ни в CInvoke.h ни в уроках об этом не написано((
Бум знать)
Это добавлено недавно. Это значит что хук будет сделан безопасный, позволяя работать плагинам, патчам, немецким патчам и их хукам, которые обращаются в это место, а то было кто первый, тот и босс..
 

MEG@VOLT

★★★★★★★★★
ТехАдмин
Регистрация
24 Мар 2006
Сообщения
9.879
Благодарности
6.761
Баллы
1.625
И снова я с вопросами))
Удаление предметов из инвентаря:
C++:
        zCParser* par = zCParser::GetParser();
        oCNpc* pNpc;
        pNpc = (oCNpc*)parser->GetInstance();
        if (!pNpc->inventory2.contents->GetNextInList()) { return false; }
        zCListSort<oCItem>* list = pNpc->inventory2.contents->GetNextInList();
        while (list) {
            if (!pNpc->inventory2.contents->GetNextInList()) { break; }
            if (oCItem* item = pNpc->inventory2.contents->GetNextInList()->GetData())
                    pNpc->RemoveFromInv(item, item->amount);
                    if (!list->GetNextInList()) { break; }
            }
        }

"Все" отлично работает. Но нужно исключить используемые.
Если добавляю условие одетого предмета:

C++:
 zCParser* par = zCParser::GetParser();
        oCNpc* pNpc;
        pNpc = (oCNpc*)parser->GetInstance();
        if (!pNpc->inventory2.contents->GetNextInList()) { return false; }
        zCListSort<oCItem>* list = pNpc->inventory2.contents->GetNextInList();
        while (list) {
            if (!pNpc->inventory2.contents->GetNextInList()) { break; }
            if (oCItem* item = pNpc->inventory2.contents->GetNextInList()->GetData()) {
                    if (item->HasFlag(ITM_FLAG_ACTIVE)) {
                        continue;
                    }
                    pNpc->RemoveFromInv(item, item->amount);
                    if (!list->GetNextInList()) { break; }
            }
        }

То функция зацикливается постоянно спотыкаясь об одетый предмет.
Как заставить код забыть про одетый предмет?

UPD. Заметка: мне нужно не просто очистить инвентарь. Мне нужно перебрать все предметы по очереди, забыть про одетые, и удалить не одетые.
 
Последнее редактирование:

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.003
Благодарности
973
Баллы
295
UPD. Заметка: мне нужно не просто очистить инвентарь. Мне нужно перебрать все предметы по очереди, забыть про одетые, и удалить не одетые.
ты же это можешь делать штатными функциями без юнион плагина. или ты хочешь именно на юнион?
 

MEG@VOLT

★★★★★★★★★
ТехАдмин
Регистрация
24 Мар 2006
Сообщения
9.879
Благодарности
6.761
Баллы
1.625
MW 7, Npc_RemoveInvItem(s) ?
Чур меня... Для одной инстанции это еще подходит, а если их тыщи, да и если инвентарь не постоянный....
 

Gratt


Модостроитель
Регистрация
14 Ноя 2014
Сообщения
3.301
Благодарности
4.636
Баллы
625
С телефона напишу псевдокод. Дальше сам попробуй. Тут мало удалить, надо ещё правильно понижать количество ссылок на объекты. Иначе будут утечки
C++:
array<oCItem*> usedItems;
list<oCItem>* it = npc.inv.con.next;
while (it) {
  oCItem* item = it.data;
  it = it.next;

  if (item.hasFlag(active)) {
    usedItems.insert(item);
    npc.inv.con.remove(item);
  }
}

npc.inv.clear();
for (item : usedItems)
  npc.inv.con.insert(item);
 

MEG@VOLT

★★★★★★★★★
ТехАдмин
Регистрация
24 Мар 2006
Сообщения
9.879
Благодарности
6.761
Баллы
1.625
Gratt, по поводу записи предметов в массив я понял. Вроде как записывает. Но вот как выдернуть из массива не понял.
Не понимаю как нужно прописывать цикл сравнения((

UPD.
zCArray<oCItem*> usedItems не имеет begin и end

1706693790875.png


пытаюсь написать через std::begin - тоже фигня какая-то

1706693898931.png
 
Последнее редактирование:

Gratt


Модостроитель
Регистрация
14 Ноя 2014
Сообщения
3.301
Благодарности
4.636
Баллы
625
Так с движковым массивом только православный for( int i=0; i<usedItems.GetNum(); i++)
 

RPD

Участник форума
Регистрация
13 Ноя 2023
Сообщения
118
Благодарности
3
Баллы
40
Вопрос: наткнулся на статью на Gothic modding community о внешних функциях (external functions). Я правильно понимаю, что это не равно созданию кастомных функций, которые потом можно будет вызывать из скриптов daedalus? Если нет, то возможно ли это вообще?
 

MEG@VOLT

★★★★★★★★★
ТехАдмин
Регистрация
24 Мар 2006
Сообщения
9.879
Благодарности
6.761
Баллы
1.625
Я правильно понимаю
На половину. Это не простые фукнции, которые написаны на дедале. Это функции которые написаны на C, и потом уже вызваны в дедале.
 

RPD

Участник форума
Регистрация
13 Ноя 2023
Сообщения
118
Благодарности
3
Баллы
40
На половину. Это не простые фукнции, которые написаны на дедале. Это функции которые написаны на C, и потом уже вызваны в дедале.
Отлично, тогда такие вопросы.

1)После компиляции dll с внешней функцией его также кидать в autorun?
2)Компилятор будет ругаться?

И еще: Для работы над диалоговыми окнами (редактирование, добавление новых пустых), а также редактированием и форматированием текста мы используем ZСView?
 

MEG@VOLT

★★★★★★★★★
ТехАдмин
Регистрация
24 Мар 2006
Сообщения
9.879
Благодарности
6.761
Баллы
1.625
1)После компиляции dll с внешней функцией его также кидать в autorun?
Да.
2)Компилятор будет ругаться?
Смотря какой. Если GS - да. И по этому вопросу, прочитай шапку Gothic Sourcer v3.16 В частности пункт 6.
Для работы над диалоговыми окнами (редактирование, добавление новых пустых), а также редактированием и форматированием текста мы используем ZСView?
А вот тут не подскажу. Ждем более опытных.
 

RPD

Участник форума
Регистрация
13 Ноя 2023
Сообщения
118
Благодарности
3
Баллы
40
Да.

Смотря какой. Если GS - да. И по этому вопросу, прочитай шапку Gothic Sourcer v3.16 В частности пункт 6.

А вот тут не подскажу. Ждем более опытных.
Насчет внешних функций: Понимаю как это должно работать, но оно не работает.
Чисто ради теста:
На плюсах все расписал по примеру, скомпилировал dll, все без ошибок.
Написал в externals.d:
Daedalus:
func int PowNums(var int FirstArgument, var int SecondArgument){};
при компиляции ошибка: функция должна возвращать значение.
 
Сверху Снизу