Объявления
Поздравляем
Roman2211


Друзья, если не получается зарегистрироваться, напишите на почту vdv_forever@bk.ru.
Я оторву свою задницу от всех дел и обязательно Вас активирую! :smile10:
Добро пожаловать на геройский форум! :smile25:

Как создать плагин для HD мода

Герои Меча и Магии III: Возрождение Эрафии, Герои Меча и Магии III Дыхание Смерти, Герои Меча и Магии III Клинок Армагеддона, Герои Меча и Магии III Хроники Героев
offlineRoseKavalier  
Мастер
Мастер
 
Сообщения: 331
Зарегистрирован: 23 сен 2017, 17:00
Пол: Не указан
Поблагодарили: 234 раз.

Re: Как создать плагин для HD мода

Сообщение RoseKavalier » 09 июн 2019, 03:47

Код: Выделить всё
__asm call 004e6260h

is an invalid instruction, because ASM blocks are "written as they are", whereas this type of expression would require calculating offsets and whatnot, so it is not allowed. Actual reasoning and explanation might be provided by someone more knowledgeable!

There are two standard ways to do this:
1* use a global /static variable to store the address
Код: Выделить всё
static int my_addr = 0x4e6260

__asm CALL my_addr


2* use a register (EAX) for the call
Код: Выделить всё
MOV EAX, 0x4e6260
CALL EAX


#2 is what you get when you use the CALL_X macros.

Alternatively, there's nothing stopping you from adding a member function to _Hero_ that makes this call automatically, simply grab the _Hero_ from ebp+0x14, and test that it exists (if (hero)).
Код: Выделить всё
int __thiscall HeroSpellSpecialityEffect(_Hero_ *this, int spell, int heroLevel, signed int effect)


Finally, I'm far from certain but this line might not work either:
Код: Выделить всё
jz 00444d5ch

It's been a while since I've written code in plain assembly, I've gotten rusty (:
Вернуться к началу

offlineas239  
имя: Анатолий
Ветеран
Ветеран
 
Сообщения: 527
Зарегистрирован: 29 дек 2018, 14:17
Пол: Мужчина
Поблагодарили: 38 раз.

Re: Как создать плагин для HD мода

Сообщение as239 » 09 июн 2019, 05:21

А как в бою понять, что заклинание сколдовал отряд, например джинн, а не герой?
Вернуться к началу

offlineigrik  
Подмастерье
Подмастерье
 
Сообщения: 108
Зарегистрирован: 14 сен 2017, 12:35
Пол: Не указан
Поблагодарили: 84 раз.

Re: Как создать плагин для HD мода

Сообщение igrik » 09 июн 2019, 12:40

as239 писал(а):

А как в бою понять, что заклинание сколдовал отряд, например джинн, а не герой?

Ставишь хук на эту функцию и записываешь в свою какую-нить глобалную премененную результат casterKind.
Код: Выделить всё
0x5A0140 void *__thiscall CombatMan_CastSpell(_BattleMgr_ *bm, int spell, signed int pos, int casterKind, int pos2, int skillLevel, int spellPower)

casterKind:
   0 - герой (c вычетом маны и невозможностью каста в этом раунде битвы),
   1 - монстр
   2 - арт
   3 - герой (без вычета маны)
   4 - герой (без вычета маны + бистро бистро анимация)
Вернуться к началу

offlineigrik  
Подмастерье
Подмастерье
 
Сообщения: 108
Зарегистрирован: 14 сен 2017, 12:35
Пол: Не указан
Поблагодарили: 84 раз.

Re: Как создать плагин для HD мода

Сообщение igrik » 09 июн 2019, 12:47

Catastrophe писал(а):

Как получить id героя, который на данный момент ходит в бою / колдует заклинание?

Если в хуке в этой функции 0x444610, то

Код: Выделить всё
int hero_id = -1;
_Hero_* hero = (_Hero_*)(c->ebp +0x14);
if (hero) {
  hero_id = hero->id;
}


B вообще, зачем тебе в этой функции понадобился ASM?
Вернуться к началу

offlineas239  
имя: Анатолий
Ветеран
Ветеран
 
Сообщения: 527
Зарегистрирован: 29 дек 2018, 14:17
Пол: Мужчина
Поблагодарили: 38 раз.

Re: Как создать плагин для HD мода

Сообщение as239 » 09 июн 2019, 13:35

Цитата:
Ставишь хук на эту функцию и записываешь в свою какую-нить глобалную премененную результат casterKind.


Спасибо! То что нужно, здесь же правильно будет и само заклинание запоминать.
Вот так вроде работает, все верно с вызовами HiHook?

Код: Выделить всё
_PI->WriteHiHook(0x5A0140, SPLICE_, EXTENDED_, THISCALL_, RememberLastBattleCast);
.....
void __stdcall RememberLastBattleCast( HiHook* hook,_BattleMgr_ *bm, int spell, signed int pos, int casterKind, int pos2, int skillLevel, int spellPower)
{
   _Hero_* hero[] = {o_BattleMgr->hero[ATTACKER], o_BattleMgr->hero[DEFENDER]};
   bool IsHeroCast = ( casterKind != 1 && casterKind != 2 );
   if ( hero[ATTACKER] && hero[DEFENDER] && IsHeroCast )
   {
      LastBattleCast[1-o_BattleMgr->current_side] = spell;
   }
   CALL_7( void, __thiscall, hook->GetDefaultFunc(), bm, spell, pos, casterKind, pos2,  skillLevel,  spellPower );
}


Еще не могу найти функцию, в которой можно было бы по определенному условию увеличить здоровье (HP) отряда.
Вернуться к началу

offlineАватара пользователя
Catastrophe  
имя: Alex
Посвященный
Посвященный
 
Сообщения: 88
Зарегистрирован: 07 мар 2019, 11:50
Пол: Мужчина
Поблагодарили: 22 раз.

Re: Как создать плагин для HD мода

Сообщение Catastrophe » 09 июн 2019, 23:30

RoseKavalier писал(а):

There are two standard ways to do this:
1* use a global /static variable to store the address
Код: Выделить всё
static int my_addr = 0x4e6260
__asm CALL my_addr

2* use a register (EAX) for the call
Код: Выделить всё
MOV EAX, 0x4e6260
CALL EAX

Still getting "improper operand type" error! Since jz doesn't give an error, maybe the problem lies in "call" opcode?

Цитата:
B вообще, зачем тебе в этой функции понадобился ASM?

По другому не получается, стал пробовать копипаст, но даже так не работает, обидно...

В homm3.h нашел вот такое, как это можно использовать?
Код: Выделить всё
// Получение бонуса к эффекту заклинания за специализацию.
 _int_ GetSpell_Specialisation_Bonuses(_int_ Spell_id, _int_ Creature_level, _int_ BaseMidif)
 {
   return CALL_4(_int_, __thiscall, 0x4E6260, this, Spell_id, Creature_level, BaseMidif);
 }
Быстрее всего смогу ответить вам в Telegram: @PleaseAndThankYou
Вернуться к началу

offlineRoseKavalier  
Мастер
Мастер
 
Сообщения: 331
Зарегистрирован: 23 сен 2017, 17:00
Пол: Не указан
Поблагодарили: 234 раз.

Re: Как создать плагин для HD мода

Сообщение RoseKavalier » 10 июн 2019, 02:10

If using Visual Studio, hexadecimal should be written with 0xABCDEF, not ABCDEFh.
In general, I agree with igrik: you should try to avoid mixing assembly with C++ as much as possible when there are other alternatives.
It also makes it much easier to read back and modify later))

Код: Выделить всё
int __stdcall c_spec_spell_mirth(LoHook *h, HookContext *c)
{
    _Hero_* hero = *(_Hero_**)(c->ebp +0x14);
    if (hero) // if () has same effect as jz 00444d5ch, original code will be run if there is no hero
    {
        int spell = IntAt(c->ebp+8);
        c->edi = hero->GetSpell_Specialisation_Bonuses(spell, hero->level, c->edi);
        // or if not set up as I think it is...
        // c->edi = CALL_4(int, __thiscall, 0x4E6260, hero, spell, hero->level, c->edi);   
    }
    return EXEC_DEFAULT;
}
 
...

pi->WriteLoHook(0x444967, c_spec_spell_mirth); // writing hook here lets you change EDI directly
Вернуться к началу

offlineАватара пользователя
Catastrophe  
имя: Alex
Посвященный
Посвященный
 
Сообщения: 88
Зарегистрирован: 07 мар 2019, 11:50
Пол: Мужчина
Поблагодарили: 22 раз.

Re: Как создать плагин для HD мода

Сообщение Catastrophe » 10 июн 2019, 03:56

Thank you for your amazing work. It only has two very small flaws.
1) We're calculating a bonus, so c->edi should have += instead of =
2) In call, third argument is the target creature level, not hero level
 Works for me (1 initial + 3 as bonus for 1-2 lvl creatures)
Изображение

Код: Выделить всё
#homm3.h

int __stdcall c_spec_spell_util(LoHook *h, HookContext *c)
{
    _Hero_* hero = *(_Hero_**)(c->ebp +0x14); // get hero id
    if (hero)
    {
        int spell = IntAt(c->ebp+8); // get spell id
      int jedn = IntAt(c->esi +0x78); // get creature level
      c->edi += CALL_4(int, __thiscall, 0x4E6260, hero, spell, jedn, c->edi);   
    }
    return EXEC_DEFAULT;
}

// dllmain

         _PI->WriteLoHook(0x444967, c_spec_spell_util); // mirth
         _PI->WriteLoHook(0x444972, c_spec_spell_util); // sorrow
         _PI->WriteLoHook(0x4449A7, c_spec_spell_util); // misfortune

This also requires my spec table edits from prev pages:
Код: Выделить всё
         _PI->WriteHexPatch(0x4E6291, "8D 46 E5"); // lea eax, [esi-13] -> lea eax, [esi-27]
         // spell spec table is limited to 43 entries + it skips first 13 entries (non-battle ones)
         // spells which are not included in this table will use id 06 (default damage formula)
         // this change makes the game skip first 27 entries instead of 13, to include ALL spells
         _PI->WriteByte(0x4E6296, 69); // spells with id more than 42 -> 69 are not included

         // spell spec table - looks like it only enables fire shield specialty
         _PI->WriteHexPatch(0x4E6358, "00 00 00 00 00 00 00 00 00 01 00 01 01 01 01 01 02 02 02 02 02 02 02 02 02 02 02 00 05 01 00 00 00 01 00 00 00 00 00 01 01 01 01");
Быстрее всего смогу ответить вам в Telegram: @PleaseAndThankYou
Вернуться к началу

offlineАватара пользователя
Catastrophe  
имя: Alex
Посвященный
Посвященный
 
Сообщения: 88
Зарегистрирован: 07 мар 2019, 11:50
Пол: Мужчина
Поблагодарили: 22 раз.

Re: Как создать плагин для HD мода

Сообщение Catastrophe » 11 июн 2019, 06:04

How hard is it to add a new spell? For example, I want to replace Disguise spell with a Lightning Bolt with differerent effects. What I need to do?

I think many people know about "Fear" spell, that got removed from RoE, but does anyone know about "Spontaneous Combustion" spell?
Even wondered why "Fireball" spell sounds like something different? Even wondered why Xarfax specialty icon shows not fireball, but a flaming corpse? Изображение

Because Fireball was a replacement spell. What did he replace? Let's ask h3maped.exe with IDA:
Изображение

Fear spell preserved its icon, but lost gfx and sfx. Spontaneous Combustion is just the opposite. His only icon is Xarfax 44x44px specialty one.
However, his sound is preserved (fireball uses it), and graphic is still in the game archives - it's the C13SPF0.def in h3sprite.lod:

Изображение

It was probably a single-target direct damage spell, maybe that's why it got replaced with fireball.
Быстрее всего смогу ответить вам в Telegram: @PleaseAndThankYou
Вернуться к началу

offlineas239  
имя: Анатолий
Ветеран
Ветеран
 
Сообщения: 527
Зарегистрирован: 29 дек 2018, 14:17
Пол: Мужчина
Поблагодарили: 38 раз.

Re: Как создать плагин для HD мода

Сообщение as239 » 12 июн 2019, 05:33

@RoseKavalier
Can I ask you 2 things from SOD SP, which will be very useful for multiplayer game?
Вернуться к началу

Пред.След.

Вернуться в Общий раздел

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex [bot] и гости: 2

cron