Berserker
Posts: 16477
|
|
16.01.2024 17:53 |
|
major
Posts: 130
|
Как можно вывести изображение и текст, например количество опыта, в окно состояния на карте приключений, как это делает HD мод?
|
|
09.02.2024 17:02 |
|
igrik
Posts: 2814
|
(09.02.2024 17:02)major Wrote: Как можно вывести изображение и текст, например количество опыта, в окно состояния на карте приключений, как это делает HD мод?
HD-mod делает так:
Code:
int __stdcall sub_10086090(const char *text, int type, int subtype, int deley)
{
*(_DWORD *)(MEMORY[0x6992B8] + 920) = 6;
v4 = (_DWORD *)(MEMORY[0x6992B8] + 924);
*v4 = deley + MEMORY[0x4F8970]();
*(_DWORD *)(MEMORY[0x6992B8] + 928) = type; // type смотри !!IF:N
*(_DWORD *)(MEMORY[0x6992B8] + 932) = subtype;// subtype смотри !!IF:N
MEMORY[0x404180](MEMORY[0x6992B8] + 936, text, strlen(text));
return MEMORY[0x415D40](MEMORY[0x6992B8], 1, 1, 1);
}
game bug fixes extended.dll || My Plugins || My GitHub
|
|
10.02.2024 19:54 |
|
major
Posts: 130
|
(10.02.2024 19:54)igrik Wrote: HD-mod делает так:
Жаль, что я так не могу
(10.02.2024 19:54)igrik Wrote:
Code:
int __stdcall sub_10086090(const char *text, int type, int subtype, int deley)
{
*(_DWORD *)(MEMORY[0x6992B8] + 920) = 6;
v4 = (_DWORD *)(MEMORY[0x6992B8] + 924);
*v4 = deley + MEMORY[0x4F8970]();
*(_DWORD *)(MEMORY[0x6992B8] + 928) = type; // type смотри !!IF:N
*(_DWORD *)(MEMORY[0x6992B8] + 932) = subtype;// subtype смотри !!IF:N
MEMORY[0x404180](MEMORY[0x6992B8] + 936, text, strlen(text));
return MEMORY[0x415D40](MEMORY[0x6992B8], 1, 1, 1);
}
Я так понимаю, нельзя просто так взять и вызвать эту функцию?
У меня AdvMgr (MEMORY[0x6992B8]) по этим смещениям не разобран. Ок, добавил ему в структуру
Code:
_dword_ info_type; // +920
_dword_ info_delay; // +924
_dword_ info_pic_type; // +928
_dword_ info_pic_subtype; // +932
_dword_ info_text; // +936
и переписал функцию
Code:
int test_message(const char* text, int type, int subtype, int deley)
{
//*(_DWORD*)(MEMORY[0x6992B8] + 920) = 6;
o_AdvMgr->info_type = 6;
//*(_DWORD*)(MEMORY[0x6992B8] + 924) = deley + MEMORY[0x4F8970]();
o_AdvMgr->info_delay = deley + CALL_0(_dword_, __cdecl, 0x4F8970);
//*(_DWORD*)(MEMORY[0x6992B8] + 928) = type; // type смотри !!IF:N
o_AdvMgr->info_pic_type = type;
//*(_DWORD*)(MEMORY[0x6992B8] + 932) = subtype;// subtype смотри !!IF:N
o_AdvMgr->info_pic_subtype = subtype;
//MEMORY[0x404180](MEMORY[0x6992B8] + 936, text, strlen(text));
CALL_3(void, __thiscall, 0x404180, &o_AdvMgr->info_text, text, strlen(text));
//return MEMORY[0x415D40](MEMORY[0x6992B8], 1, 1, 1);
return CALL_4(int, __thiscall, 0x415D40, o_AdvMgr, 1, 1, 1);
}
Ну и при вызове test_message(o_TextBuffer, 17, experience, 5000); очевидно получаю краш.
|
|
13.02.2024 04:36 |
|
XEPOMAHT
Posts: 2265
|
(13.02.2024 04:36)major Wrote: Жаль, что я так не могу
Так и я не могу. Моддерам к интерфейсу окна приключений закрыт из-за совместимости с HD-модом (даже радар не перекрасить в цвета радуги).
(13.02.2024 04:36)major Wrote: Я так понимаю, нельзя просто так взять и вызвать эту функцию?
Функция полностью перехвачена HD-модом. Библиотекой _HD3_.dll, насколько помню. Адрес функции - там же можно накопать, если диассемблировать HD-мод. Лично я давно забил на вывод информации в окно состояния в рамках ERA+, т.к. писать собственные функции, с дублированием кода HD-мода на Ассемблере с сохранением обратной совместимости, чтобы работало и с HD-модом, и без него, поленился.
(13.02.2024 04:36)major Wrote: MEMORY[0x6992B8] + 936, text, strlen(text)
Там крошечный текстовый буфер, ты зачем туда пытаешься строку пропихнуть??? Текст туда надо копировать и не забыть записать и размер строки тоже (функция FMes_ExpandAndCopy). Если буфер забит мусором - почистить перед копированием (функция FMes_Clean). И то, и то лучше делать содовскими функциями. Наколько помню, в MoP я выводил текст в окне напрямую из воговской Z-переменной в обход копирования текста в _AdvMng_ + 936, т.к. работать с этим буфером у меня тоже тогда не получалось. А там самое главное, чтобы текст во время показа не менялся, т.е. текстовая переменная была уникальная. Помню, была такая фича в MoP - бегущая строка с анимированным def и музыкальным сопровождением в этом окне, но пришлось всё это убрать из MoP, т.к. вело к хаотическим утечкам памяти.
(This post was last modified: 13.02.2024 09:06 by XEPOMAHT.)
|
|
13.02.2024 08:01 |
|
igrik
Posts: 2814
|
Вот оригиальная функция по показу кол-ва ресурсов (и только ресурсов!)
Code:
sprintf(o_TextBuffer, "AdvMgrInfo: %d", 666);
o_AdvMgr->Field<_dword_>(+940) = 0; // очищаем длину строки
CALL_4(void, __thiscall, 0x415FC0, o_AdvMgr, o_TextBuffer, 6 (Золото), 5000);
UPD: А вылетает не из-за размера текста и буфера, а потому что базово "окно состояния на карте приключений" может показывать только типы 0-8.
Code:
enum AdvManager::EBottomViewType
{
BVTYPE_NONE = 0,
BVTYPE_NEW_TURN = 1,
BVTYPE_KINGDOM = 2,
BVTYPE_HERO = 3,
BVTYPE_TOWN = 4,
BVTYPE_ENEMY_TURN = 5,
BVTYPE_RESOURCE_MESSAGE = 6,
BVTYPE_MESSAGE = 7,
BVTYP
В дополнение, я выложил полностью разобранную структуру менеджера карты приключений
game bug fixes extended.dll || My Plugins || My GitHub
|
|
13.02.2024 09:11 |
|
major
Posts: 130
|
igrik, спасибо за структуры, помню, что видел твой пост, но потом забыл про него.
В общем, поковырявшись ещё час-полтора, понял, что IF:L не такой уж плохой вариант.
Ну, а серьезно, там ограничение не только в показе определенных типов. Ничто же не мешает воспользоваться старыми-добрыми костылями и запихать нужную картинку в деф к ресурсам и показывать её. Но проблема-таки в том, что нельзя показать картинку за мифрилом, игра крашится.
По коду так и не смог понять, почему. Там дальше и деф погружается и нужный кадр должен отрисовываться, а почему краш не понятно.
Хотя мне достаточно того, что мифрил отображается, мне он все равно не нужен, можно смело поменять на опыт.
|
|
14.02.2024 12:37 |
|
Berserker
Posts: 16477
|
В IF:L можно выводить любые изображения
Code:
[+] Added support for displaying inline def-images right in texts as a part of Era Markup Language (EML).
To embed image in text use the following tags:
{~>def_name.def} Will display the first frame from the first group of def_name.def image in place of text cursor.
{~>def_name.def:frame_index} Will display specified frame from the first group of def_name.def image or nothing if index is invalid.
{~>def_name.def:group_index:frame_index} Will display specified frame from specified group of def_name.def image or nothing if index is invalid.
Frames and frame groups are counted from 0. Frames are automatically trimmed.
By default images are rendered "inline". It means, that they are treated as non-wrapping sequence of white space characters. Images do not allocate
vertical space except the height of current font. But they automatically allocate necessary width.
Images can be aligned vertically using the following attribute: valign=top|middle|bottom.
Examples:
{~>ava0037.def valign=bottom}
{~>smalres.def:5}
Vertical alignment modes:
- 'top'. Image is drawn from the top left pixel of current character box.
- 'middle'. Image is vertically centered relative to current text line height. This is the default mode for inline images.
- 'bottom'. Image is drawn so, that it's bottom edge matches current text line bottom edge.
It's possible to display image in a horizontally mirrored form. Just add "mirror" attribute.
Example: {~>ava0037.def mirror}
Тегами ставим нужный цвет текста, полупрозрачность и картинку.
Скачать Герои 3 Эра и всё, что с ней связано / ERA 2.46f для старых модов
Поддержать проект
|
|
14.02.2024 16:46 |
|
major
Posts: 130
|
Подскажите, очень нужна помощь. Несколько дней изучаю многофайловые сборки, но нормальных примеров так и не встретил. Пытаюсь разбить свой "проект" на несколько файлов, и есть некоторые трудности по части компиляции и ошибках линковщика. Visual Studio, C++.
1. Почитал, что в хедерах прописываются только объявления переменных и прототипы функций. Непонятно, почему, объявляя переменную в хедере
Code:
#pragma once
#ifndef _GLOBALS_H_
#define _GLOBALS_H_
int param;
#endif
и подключая этот хедер к другим файлам .cpp я получаю ошибку линковщика по типу множественного определения. Ведь переменную я еще не определил, только объявил.
Каким образом можно создать переменную, которая будет использоваться в разных .cpp файлах проекта?
Пример для наглядности, переменных много, как и функций, поэтому хотелось вынести все это по разным файлам.
2. Как можно подключить хедер Эры era.h к разных файлам .cpp? Здесь тоже тонна ошибок множественного определения.
|
|
23.03.2024 21:21 |
|