Berserker
Posts: 16657
|
|
24.11.2020 22:30 |
|
RoseKavalier
Posts: 118
|
(24.11.2020 22:09)Raistlin Wrote: Получается, с помощью данного кода можно полностью перейти на pcx, обойдя при этом все проблемы с совместимостью?
Depends on the def type really, for example pcx has no specification to draw shadows, semi-transparent, flag colour etc. A bit more work is needed, in my opinion it becomes simpler to make your own format - I had looked at this a few months back and got pretty far just never managed to finish.
On the other hand, pcx can almost directly be used for interface format, provided you do not use colours 1-9. Colour 0 can be considered transparent through function argument.
|
|
25.11.2020 02:32 |
|
daemon_n
Posts: 4343
|
вот ещё парочка багов и хотелок
; (+1;+1) for each button
0046B2CE 04; buyout - button y
0046B2D0 37; x
0046B353 04; escape y
0046B355 6A; x
0046B3D8 04; menu y
0046B3DA 04; x
0046B45D 04; auto y
0046B45F 9D; x
0046B4E5 04; spellbook y
0046B4E7 86020000;
0046B56D 04; wait y
0046B56F B9020000; x
0046B5F5 04; def y
0046B5F7 EC020000; x
0046B87D 04; arrow up y
0046B87F 71020000; x
0046B916 17; arrow down y
0046B918 71020000; x -) Опция "пригласить героя" показывает неверный портрет, если портрет героя был настроен в редакторе карт. ( Если не ошибаюсь, у сод/хота так же)
+) Плюс хотелось бы добавить уровень героя в хинт диалога приглашения
Новейший Heroes Launcher
|
|
25.11.2020 05:13 |
|
baratorch
Posts: 197
|
(22.11.2020 18:34)Berserker Wrote: Quote:Один хороший модер очень просит возможность получить функцию загрузки сохранённой игры прямо с карты приключений без сторонних диалогов. Возможно ли?
Это просто теоретический вопрос. Если можно сразу же загрузить игру без промежуточных диалогов, то такая функция была бы востребована весьма. Именно программно.
Code:
void _LoadGame(char* filename)
{
int v[4];
CALL_2(void, __thiscall, 0x558320, v, 1);
v[3] = 0;
CALL_4(void, __thiscall, 0x4BEFF0, o_GameMgr, filename, 0, 1);
CALL_1(void, __thiscall, 0x558360, v);
v[3] = -1;
CALL_1(void, __thiscall, 0x558360, v);
}
filename - короткое имя сейва, который будет браться из папки Games
Таким образом можно загружать ТОЛЬКО сейв той же игры, что идет.
Такая загрузка проходит без экрана прогресса загрузки.
Я не пробовал загружать таким образом сейвы не текущей игры, но, уверен, если так сделать - все поломается.
(This post was last modified: 25.11.2020 11:51 by baratorch.)
|
|
25.11.2020 11:50 |
|
baratorch
Posts: 197
|
(22.11.2020 18:34)Berserker Wrote: Поддержку цветного текста для режимов 32 бита делал RoseKavalier, но там он динамически патчит код HD. Хотелось бы более цивилизованно.
Сейчас Эра перехватывает следующие адреса:
Core.Hook(@Hook_HandleTags, Core.HOOKTYPE_BRIDGE, 7, Ptr($4B509B));
Core.Hook(@Hook_GetCharColor, Core.HOOKTYPE_BRIDGE, 8, Ptr($4B4F74));
Core.Hook(@Hook_BeginParseText, Core.HOOKTYPE_BRIDGE, 6, Ptr($4B5255));
В BeginParseText весь текст парсится на блоки (пробельные символы игнорируются). Запоминаются размеры блоков и цвета. Сами цвета вырезаются, остаются только фигурные скобки.
В Hook_GetCharColor возвращает цвет из текущего блока и текущей позиции.
В Hook_HandleTags увеличивается позиция для непробельных символов, смена блока при необходимости и обработка "{", "}"
В 32-бит режиме ХД полностью переписана функция N_font_DrawCharacter_4B4F00, внутри которой эра пытается изменить цвет символа.
Почему-то сразу не пришло в голову решение (оно уже есть):
Эре нужно создать глобальную переменную типа WORD (16 бит беззнаковое целое) - пусть CharColor. взять адрес этой переменной и выполнить с ним в качестве аргумента функцию патчера:
_P->VarInit("HotA.FontColor", (_dword_)&CharColor);
а дальше, каждый раз когда меняется цвет символа менять и CharColor.
Если так сделать, то цветной текст заработает с любой версией ХД.
Надеюсь понятно объяснил, и перевести описанное из с++ в паскаль/делфи не составит труда.
|
|
25.11.2020 12:10 |
|
igrik
Posts: 2819
|
(25.11.2020 17:26)baratorch Wrote: А вот баг вога - не знаю... м.б. будет настроение - придумаю решение.
Мне кажется, это задача Берса в рамках ЭРЫ.
Либо моя в рамках game bug fixes extended.dll
Я почему то даже и не подумал, что это баг Вога. Просто проблема не проявлялась без быстрого управления армий, и поэтому интуитивно думалось, что это недочёт HD (я сейчас не говорю о потере опыта и артефакта).
game bug fixes extended.dll || My Plugins || My GitHub
|
|
25.11.2020 17:37 |
|
baratorch
Posts: 197
|
(25.11.2020 17:37)igrik Wrote: (25.11.2020 17:26)baratorch Wrote: А вот баг вога - не знаю... м.б. будет настроение - придумаю решение.
Мне кажется, это задача Берса в рамках ЭРЫ.
Либо моя в рамках game bug fixes extended.dll
Я почему то даже и не подумал, что это баг Вога. Просто проблема не проявлялась без быстрого управления армий, и поэтому интуитивно думалось, что это недочёт HD (я сейчас не говорю о потере опыта и артефакта).
Вот код для эры, который делает отображение значков опыта и артов в полоске героя в этом диалоге присоединения существ:
Code:
_PI->WriteLoHook(0x7653C1, [](LoHook* h, HookContext* c) -> int
{
c->ecx = IntAt(0x803300);
if (c->ecx == 0 && o_ActivePlayer && o_ActivePlayer->selected_hero_id != -1)
{
c->ecx = (int)o_GameMgr->GetHero(o_ActivePlayer->selected_hero_id);
}
return SKIP_DEFAULT;
});
Ну а сделать нормальную работу с опытом с верхней полоской в этом диалоге, гораздо сложнее, конечно. Но я приблизительно представляю как...
(This post was last modified: 25.11.2020 18:48 by baratorch.)
|
|
25.11.2020 18:46 |
|
baratorch
Posts: 197
|
(24.11.2020 01:26)daemon_n Wrote: Ооо, я вспомнил
+) Не хватает твика для выбора найма сразу всех существа в диалоге набора существ, как это сделано для сод/хота. Было что-то типа
<UI.RecruitDlg.AutoSet> = 1
<UI.RecruitDlg.AutoSet.Max> = 1
Очень удобная фишка, которой не хватает
Этот функционал есть. Надо ручками добавить эти записи в твики. Но в обнове сделаю так чтобы эти записи были по-умолчанию.
|
|
25.11.2020 19:41 |
|
igrik
Posts: 2819
|
(25.11.2020 18:46)baratorch Wrote: Вот код для эры, который делает отображение значков опыта и артов в полоске героя в этом диалоге присоединения существ:
Code:
_PI->WriteLoHook(0x7653C1, [](LoHook* h, HookContext* c) -> int
{
c->ecx = IntAt(0x803300);
if (c->ecx == 0 && o_ActivePlayer && o_ActivePlayer->selected_hero_id != -1)
{
c->ecx = (int)o_GameMgr->GetHero(o_ActivePlayer->selected_hero_id);
}
return SKIP_DEFAULT;
});
Ну а сделать нормальную работу с опытом с верхней полоской в этом диалоге, гораздо сложнее, конечно. Но я приблизительно представляю как...
Круто! Реально работает))
Я так понимаю, для верхней полоски нужно создать свою структуру опыта стеков для "гарнизон и шахты - хозяин" (при создании конструктора армий 0x5D15F7 call Army_Constuct ), и поять же поставить перехват на отображение " гарнизон и шахты - хозяин"
game bug fixes extended.dll || My Plugins || My GitHub
|
|
25.11.2020 19:50 |
|
igrik
Posts: 2819
|
Какой же треш в этих исходниках опыта монстров. Просто ахтунг. Ну нахрена так именовать функции и переменные.
Как выловить то конструктор CrExpo()?
По хорошему, создать бы свой тип 0 #define CE_NONE 0 ( как #define CE_HERO 1 ) и через этот тип получать свой RealType, RealNum, SetN, а потом использовать в M2MCrExp(0)
game bug fixes extended.dll || My Plugins || My GitHub
|
|
26.11.2020 02:04 |
|
Berserker
Posts: 16657
|
|
26.11.2020 02:07 |
|
Berserker
Posts: 16657
|
|
26.11.2020 08:00 |
|
baratorch
Posts: 197
|
Berserker, в коде класса TPatcher сразу после виртуального абстрактного метода MemCopyCodeEx добавь
Code:
// метод VarInit
// инициализирует "переменную" с именем name и устанавливает ее значение равным value
// если переменная с таким именем уже существует, то просто устанавливает ее значение равным value
// возвращает переменную в случае успеха и nil в противном случае
function VarInit(name: PAnsiChar; value: _dword_): TVariable; virtual; stdcall; abstract;
// метод VarFind
// возвращает переменную с именем name, если такая была инициализирована
// если нет, возвращает nil
function VarFind(name: PAnsiChar): TVariable; virtual; stdcall; abstract;
тип TVariable:
Code:
//тип "переменная" используется для возвращаемых методами TPatcher.VarInit
// и TPatcher.VarFind значений
TVariable = packed class
// возвращает значение "переменной" (потокобезопасное обращение)
function GetValue: _dword_; virtual; stdcall; abstract;
// устанавливает значение "переменной" (потокобезопасное обращение)
procedure SetValue(value: _dword_) virtual; stdcall; abstract;
// возвращает указатель на значение "переменной" (обращение к значению "переменной" через указатеь непотокобезопасно)
function GetPValue: Pointer; virtual; stdcall; abstract;
end;
|
|
26.11.2020 09:30 |
|
Berserker
Posts: 16657
|
Спасибо, подключил.
Quote:_P->VarInit("HotA.FontColor", (_dword_)&CharColor);
а дальше, каждый раз когда меняется цвет символа менять и CharColor.
Мне часто нужно, если вне тегов, использовать цвет по умолчанию. То есть не менять его. Цвет по умолчанию — тот, что задан для элемента в диалоге, может быть не белый. Что посоветуешь здесь? HD-мод сам устанавливает HotA.FontColor динамически? Раньше, если нужно выводить символ с цветом по умолчанию, я просто выполнял код по умолчанию:
Code:
function Hook_GetCharColor (Context: Core.PHookContext): longbool; stdcall;
begin
result := TextBlocks[TextBlockInd].Color16 = DEF_COLOR;
if not result then begin
Context.EAX := TextBlocks[TextBlockInd].Color16;
end;
end;
Скачать Герои 3 Эра и всё, что с ней связано / ERA 2.46f для старых модов
Поддержать проект
|
|
26.11.2020 09:47 |
|