Уважаемые гости и новички, приветствуем Вас на нашем форуме
Здесь вы можете найти ответы практически на все свои вопросы о серии игр «Готика» (в том числе различных модах на нее), «Ведьмак», «Ризен», «Древние свитки», «Эра дракона» и о многих других играх. Можете также узнать свежие новости о разработке новых проектов, восхититься творчеством наших форумчан, либо самим показать, что вы умеете. Ну и наконец, можете обсудить общие увлечения или просто весело пообщаться с посетителями «Таверны».
Чтобы получить возможность писать на форуме, оставьте сообщение в этой теме.
Не уверен, что я понял, о чём ты спрашиваешь. Возможно, вопрос об объекте игрового мира (не помню название), который наносит урон при пересечении его поверхности. Такие объекты действительно работают ненадёжно, по крайней мере в Г1. Если вопрос об этом, то можно попробовать активировать у объекта повторное нанесение урона. В свойствах объекта можно установить интервал времени, через который будет наноситься новая порция урона.
не в vdf? Я хочу один доспех из Архолоса вытащить, я правильно понял, что теперь искать его в файлах KM_Anims и KM_Textures? Приложение скачал, с помощью него и открываю эти vdf
Не подскажешь, где хранятся данные получаемого опыта за убийство мобов?
А то в исправленных скриптах, у ряда мобов, опыт несколько порезан и хотелось бы восстановить справедливость, так сказать.
В XP_Constans.b не увидел инфы, например, о том же молодом волке, другого файла со схожим названием найти не удалось.
// Indicator.cpp#include"UnionAfx.h"namespace Gothic_I_Classic {//***************************************// Макросы (для удобства понимания кода)//***************************************// Преобразование пикселей в виртуальные координаты относительно заданного объекта "pView"#define PixelToVirtualX(pView, value) pView->anx(value) // по оси Х#define PixelToVirtualY(pView, value) pView->any(value) // по оси У// Преобразование виртуальных координат в пиксели относительно заданного объекта "pView"#define VirtualToPixelX(pView, value) pView->nax(value) // по оси Х#define VirtualToPixelY(pView, value) pView->nay(value) // по оси У// указатель на индикатор (по умолчанию не задан)
oCViewStatusBar* pNewBar =NULL;// Текстура полоски индикатораconst zSTRING newBar_bar ="BAR_NEW.TGA";// обновление позиции и размеров нового индикатораvoidnewBar_UpdatePosAndSizes(){// размеры берём от хп бара или же указываем своиif(ogame && ogame->hpBar && pNewBar){int sx, sy;// получаем размеры индикатора здоровья
ogame->hpBar->GetSize(sx, sy);// устанавливаем такие же размеры для нового индикатора
pNewBar->SetSize(sx, sy);int x, y;// получаем позицию индикатора здоровья
ogame->hpBar->GetPos(x, y);// устанавливаем позицию нового индикатора (по оси Х - такую же как и у индикатора здоровья,// а по оси У - отступив от верхнего края индикатора здоровья сам размер индикатора и 10 пикселей,// т.о. создав зазор между индикаторами в 10 пикселей)
pNewBar->SetPos(x, y - sy -PixelToVirtualY(screen,10));}}// обновление значения индикатораvoidnewBar_UpdateValue(){// проверяем указателиif(pNewBar && player){
pNewBar->SetValue(player->GetAttribute(NPC_ATR_HITPOINTS));
pNewBar->SetMaxRange(0, player->GetAttribute(NPC_ATR_HITPOINTSMAX));
pNewBar->SetRange(0, player->GetAttribute(NPC_ATR_HITPOINTSMAX));}}//******************************************************************// Перехват функции смены режима отображения индикаторов (вкл/выкл)//******************************************************************//0x00638BE0 public: void __thiscall oCGame::SetShowPlayerStatus(int)staticvoid __fastcall Game_SetShowPlayerStatus(oCGame* _this,void* vt, BOOL bShow);static CInvoke <void(__thiscall*)(oCGame*, BOOL)>pGame_SetShowPlayerStatus(0x00638BE0, Game_SetShowPlayerStatus, IVK_AUTO);staticvoid __fastcall Game_SetShowPlayerStatus(oCGame* _this,void* vt, BOOL bShow){// если указатель на вьюпорт и на новый индикатор есть, а также задана команда "скрыть индикаторы"// (например, при вызове главного меню)if(screen && pNewBar &&!bShow)// удаляем индикатор из вьюпорта
screen->RemoveItem(pNewBar);// и вызываем оригинальную функциюpGame_SetShowPlayerStatus(_this, bShow);}//***************************************************// Перехват функции обновления значений индикаторов//***************************************************//0x00638F90 public: void __thiscall oCGame::UpdatePlayerStatus(void)staticvoid __fastcall Game_UpdatePlayerStatus(oCGame* _this);static CInvoke <void(__thiscall*)(oCGame*)>pGame_UpdatePlayerStatus(0x00638F90, Game_UpdatePlayerStatus, IVK_AUTO);staticvoid __fastcall Game_UpdatePlayerStatus(oCGame* _this){// вызываем оригинальную функциюpGame_UpdatePlayerStatus(_this);// если указателя на игровую сессию нет или запрещено показывать индикаторыif(!_this ||!_this->showPlayerStatus)// выходимreturn;// если индикатор не созданif(!pNewBar){// создаём новый индикатор
pNewBar =newoCViewStatusBar();// если вьюпорт есть и индикатор созданif(screen && pNewBar){// добавляем индикатор на экран
screen->InsertItem(pNewBar, FALSE);// инициализируем индикатор в нулевых координатах и в масштабе х1
pNewBar->Init(0,0,1.0);// задаём текстуры для индикатора
pNewBar->SetTextures("BAR_BACK.TGA","BAR_TEMPMAX.TGA", newBar_bar);// обновляем позицию и размеры нового индикатораnewBar_UpdatePosAndSizes();// после инициализации удаляем индикатор из вьюпорта
screen->RemoveItem(pNewBar);}}// если указатели на вьюпорт и индикатор существуютif(screen && pNewBar){// удаляем индикатор из вьюпорта
screen->RemoveItem(pNewBar);// вставляем индикатор во вьюпорт, тем сымым ставя его на передний план во время рендера zCView элементов
screen->InsertItem(pNewBar, FALSE);// обновляем значение индикатораnewBar_UpdateValue();}}//*******************************************************************************************************// Перехват функции обновления позиций и размеров различных индикаторов при изменении разрешения экрана//*******************************************************************************************************//0x00638C50 public: void __thiscall oCGame::UpdateScreenResolution(void)staticvoid __fastcall Game_UpdateScreenResolution(oCGame* _this);static CInvoke <void(__thiscall*)(oCGame*)>pGame_UpdateScreenResolution(0x00638C50, Game_UpdateScreenResolution);staticvoid __fastcall Game_UpdateScreenResolution(oCGame* _this){// вызываем оригинальную функциюpGame_UpdateScreenResolution(_this);// если указатели на вьюпорт и индикатор существуютif(screen && pNewBar){// добавляем индикатор на экран
screen->InsertItem(pNewBar, FALSE);// инициализируем индикатор в нулевых координатах и в масштабе х1
pNewBar->Init(0,0,1.0);// обновляем позицию и размеры нового индикатораnewBar_UpdatePosAndSizes();// после инициализации удаляем индикатор из вьюпорта
screen->RemoveItem(pNewBar);}}}
И снова здравствуйте, пользуюсь VS17 еле как разобрался со сборкой плагина, т.к. не могу поставить SDK v(100), но вроде работает как-то, на компиляторе v(141_xp)
пытался понять как работает этот перехватчик, но так и не уловил сути, в игре, по данному примеру -ничего не меняется. Прикинул, что функции перехватчика надо прописывать в Plagin.cpp через состояния, но абсолютно не понимаю, что надо прописать в аргументах. Как же оно всё-таки работает?
PS: G2Addon
1) Если тебе нужен компилятор (v100), то нужно установить ещё и Visual Studio 2010.
Название образа VS 2010: "ru_visual_studio_2010_professional_x86_528367.iso", ну либо то, что найдёшь в сети.
2) По поводу перехватчиков. Они работают по адресам функций. Например:
Здесь "pGame_SetShowPlayerStatus" - это указатель на оригинальную перехватываемую функцию,
"Game_SetShowPlayerStatus" - это та функция, в которую будет перенаправлен вызов.
Если в своём проекте ты откроешь файл: "Engine SDK\1. Gothic I\Names_G1.hpp", и с помощью поиска(Ctrl+F) найдёшь в нём адрес 0x00638BE0, то он укажет на функцию:
В каждом движке свои адреса функций. И то есть, используя адреса Г1 из того примера, но уже в движке Г2а, ты можешь попасть на случайную функцию или область памяти, которые могут иметь непредсказуемые последствия или просто вылет, при условии что конфигурация решения была для Г2а. А чтобы этого не произошло, тебе нужно поменять все адреса перехватчиков в коде.
Ищешь и подставляешь всё аналогичным образом:
Заходишь в файл: "Engine SDK\4. Gothic II NoTR\Names_G2A.hpp", находишь в нём интересующую функцию по названию:
Но будь внимателен при переносе функций, т.к. для разных движков они могут выглядеть по разному:
Поэтому сверяй:
- тип: void
- соглашение о вызовах: __thiscall
- принадлежность к классу: oCGame::SetShowPlayerStatus
- и аргументы: (int)
В зависимости от этого может меняться код перехватчика.
Ну и естественно, для работы с G2a, необходимо выбрать другую конфигурацию решения "G2A MD Release":
Сейчас популярен другой метод перехвата функций, с помощью так называемой связки HOOK-AS.
Более подробно эту реализацию можешь изучить в других готовых проектах разных форумчан (кто этим занимался, например:
Gratt, Xeдин, Slavemaster ).
Есть ли способ проследить открыт ли инвентарь на экране? хочу записать его состояние в условие. Так же на будущее, как с ним работать, ничего толкового не нашёл
мне бы через union sdk понять как это сделать, думаю тут замешано oCViewDialogInventory, но хотелось бы и другой путь узнать, может я просмотрел. искал через player->, но что-то всё не то
Народ. Как мне мои скрипты написанные на .d запаковать в .vdf формат ? Просто видел некоторые vdf файлы, при распаковке которых (с помощью GothicVDFS) были не dat файлы, а .d (.d скрипты находились в : SYSTEM\AUTORUN). Хотя в уроках писали что нельзя запаковать .d в .vdf...
mas0raksh, Если прям скрипты-скрипты, то лучше пихать их в DAT. и потом уже упаковывать в VDF(MOD).
Если это скриптовые патчи, сделанные на union, то можно просто пихать их в том VDF(MOD).
DAMROCK, чем тебе через player не понравилось? Там есть объект inentory2 (oCNpcInventory → oCItemContainer). Поиском по Gothic API можно найти список s_openContainers, вот в нем будут лежать все открытые в данный момент контейнеры. Если твой player->inventory2 является частью этого списка, то значит инвентарь игрока открыт.
DAMROCK, чем тебе через player не понравилось? Там есть объект inentory2 (oCNpcInventory → oCItemContainer). Поиском по Gothic API можно найти список s_openContainers, вот в нем будут лежать все открытые в данный момент контейнеры. Если твой player->inventory2 является частью этого списка, то значит инвентарь игрока открыт.
Спасибо за разъяснение.
Возник такой вопрос о барах: хочу реализовать вертикальный бар, можно ли как-то переключить направление сжатия текстуры с x на y?
На данном сайте используются файлы cookie, чтобы персонализировать контент и сохранить Ваш вход в систему, если Вы зарегистрируетесь.
Продолжая использовать этот сайт, Вы соглашаетесь на использование наших файлов cookie.