IPB

Здравствуйте, гость ( Вход | Регистрация )

29 страниц V  « < 17 18 19 20 21 > »   
Reply to this topicStart new topic
> Мод на ХотА
DedMorozzz
сообщение 28 Dec 2016, 23:53 (Сообщение отредактировал DedMorozzz - 28 Dec 2016, 23:56)
Сообщение #361

God
Сообщений: 267
Спасибо сказали: 25 раз




Цитата(AlexSpl @ 28 Dec 2016, 22:46) *
Можно ещё так.

Указатель на героя у нас тоже есть, значит, мы знаем

Цитата
// miu = map_item under hero
_dword_ miu_object_type; // +12


Т.е.
Код
if ( *(int*)(c->ecx + 12) == _банк_ ) { ... }


Непонял пока что, что в _банк_ находится?))

Так же не пойму как взять скорость юнита (своего)
Этот код отвечает за новый раунд
Код
.text:00446E40; void __thiscall combatMonster_SetUpNewRound(_CombatMonster_ *this)


Пробовал разные варианты, включая все закоменченые (и ещё несколько дополнительно):
Код
int __stdcall resetTacticsUnitSpeedBonus(LoHook* h, HookContext* c)
{
    //ecx+52
    //*(int*)(c->esi+80) += 5;
    //*(int*)(c->esi+80+1224) += 5;
    //*(int*)(c->esi+52) += 5;
    //ebx, eax
    //*(int*)(c->eax+1224) += 5;
    //*(int*)(c->ebx+1224) += 5;

    int cmAddr = *(int*)0x699420;
    int x = *(int*)(cmAddr + 0x132B8);
    int y = *(int*)(cmAddr + 0x132BC); // или наоборот ))
    int creatureAddr = cmAddr + 1352 * (x + 21 * y) + 21708;
    *(int*)(creatureAddr + 1224) +=5;
    

    return EXEC_DEFAULT;
}

Не работает
Хук на адрес: 0x446E40
Go to the top of the pageAdd Nick
 
+Quote Post
igrik
сообщение 29 Dec 2016, 00:09
Сообщение #362

Immortal
Сообщений: 589
Спасибо сказали: 891 раз




Цитата(AlexSpl @ 28 Dec 2016, 23:34) *
Интересно, как узнать, что бой в банке проходит?

if ( (*(char*)(0x699420 + 0x53C5)) == 1 )


--------------------


Спасибо сказали:
Go to the top of the pageAdd Nick
 
+Quote Post
AlexSpl
сообщение 29 Dec 2016, 00:14
Сообщение #363

Immortal
Сообщений: 798
Спасибо сказали: 555 раз




Ну, я потестил, если битва в сокровищнице (не знаю, любой ли), то см. мой предыдущий пост. Тестил на консерве и гномятне.

Цитата
if ( (*(char*)(0x699420 + 0x53C5)) == 1 )

Это условие выполняется, только когда юниты вокруг нашей армии становятся?
Go to the top of the pageAdd Nick
 
+Quote Post
DedMorozzz
сообщение 29 Dec 2016, 00:16
Сообщение #364

God
Сообщений: 267
Спасибо сказали: 25 раз




Цитата(igrik @ 28 Dec 2016, 23:09) *
Цитата(AlexSpl @ 28 Dec 2016, 23:34) *
Интересно, как узнать, что бой в банке проходит?

if ( (*(char*)(0x699420 + 0x53C5)) == 1 )

Проверил, не работает ):
Go to the top of the pageAdd Nick
 
+Quote Post
AlexSpl
сообщение 29 Dec 2016, 00:16
Сообщение #365

Immortal
Сообщений: 798
Спасибо сказали: 555 раз




Наверное, так правильно:

Код
if ( *(char*)(*(int*)0x699420 + 0x53C5) == 1 )
?


Спасибо сказали:
Go to the top of the pageAdd Nick
 
+Quote Post
DedMorozzz
сообщение 29 Dec 2016, 00:18
Сообщение #366

God
Сообщений: 267
Спасибо сказали: 25 раз




Цитата(AlexSpl @ 28 Dec 2016, 23:16) *
Наверное, так правильно:

Код
if ( *(char*)(*(int*)0x699420 + 0x53C5) == 1 )
?

Да, так работает
Go to the top of the pageAdd Nick
 
+Quote Post
igrik
сообщение 29 Dec 2016, 00:24
Сообщение #367

Immortal
Сообщений: 589
Спасибо сказали: 891 раз




Цитата(AlexSpl @ 29 Dec 2016, 00:14) *
Это условие выполняется, только когда юниты вокруг нашей армии становятся?

Да, от этого зависит расстановка стеков защищающейся стороны (функция 0x4631E0).
Адреса позиций прописаны тут:
0x63D0A8 - обычная битва;
0x63D0E0 - битва в банке.


--------------------


Спасибо сказали:
Go to the top of the pageAdd Nick
 
+Quote Post
DedMorozzz
сообщение 29 Dec 2016, 00:34 (Сообщение отредактировал DedMorozzz - 29 Dec 2016, 00:43)
Сообщение #368

God
Сообщений: 267
Спасибо сказали: 25 раз




Как с функой нового раунда быть.
Каким образом там изменить скорость юнитов? Чуть выше писал что пробовал, что нашел, но пока что без результата
Если я правильно понимаю необходимо 3 критерия:
1. скорость своих юнитов
2. сам герой (что бы проверку на тактику добавить)
3. получить номер раунда

Раунд скорее всего смогу найти (перебрав параметры, которые перед функцией), а вот 2 других - не знаю как
Go to the top of the pageAdd Nick
 
+Quote Post
igrik
сообщение 29 Dec 2016, 11:30
Сообщение #369

Immortal
Сообщений: 589
Спасибо сказали: 891 раз




Цитата(DedMorozzz @ 29 Dec 2016, 00:34) *
2. сам герой (что бы проверку на тактику добавить)

так же понятнее:
Код
char heroAtt_Tactic = o_BattleMgr->hero[0]->second_skill[HSS_TACTICS];

чем так:
Код
char heroAtt_Tactic = *(char*)(*(int*)(*(int*)0x699420 + 0x53CC) + 201 + 19);

это код навскидку, я его не проверял.


--------------------


Спасибо сказали:
Go to the top of the pageAdd Nick
 
+Quote Post
igrik
сообщение 29 Dec 2016, 14:16
Сообщение #370

Immortal
Сообщений: 589
Спасибо сказали: 891 раз




Цитата(DedMorozzz @ 29 Dec 2016, 00:34) *
1. скорость своих юнитов

Что-то в таком духе
Код
for (char i = 0; i < 21; i++) // только для стеков атакующей стороны (стеки № 0...20)
{
    if(o_BattleMgr->stack[0][i].count_current > 0)  // если стек жив
    {
        o_BattleMgr->stack[0][i].creature.speed += 2; // увеличить его скорость
    }
}



--------------------
Go to the top of the pageAdd Nick
 
+Quote Post
DedMorozzz
сообщение 29 Dec 2016, 15:18 (Сообщение отредактировал DedMorozzz - 29 Dec 2016, 15:26)
Сообщение #371

God
Сообщений: 267
Спасибо сказали: 25 раз




Цитата(igrik @ 29 Dec 2016, 10:30) *
Цитата(DedMorozzz @ 29 Dec 2016, 00:34) *
2. сам герой (что бы проверку на тактику добавить)

так же понятнее:
Код
char heroAtt_Tactic = o_BattleMgr->hero[0]->second_skill[HSS_TACTICS];

чем так:
Код
char heroAtt_Tactic = *(char*)(*(int*)(*(int*)0x699420 + 0x53CC) + 201 + 19);

это код навскидку, я его не проверял.


Всё накрылось так, если подключил HotA/homm3.h
Код
1>.\dllmain.cpp(391) : error C2227: left of '->ecx' must point to class/struct/union/generic type
1>.\dllmain.cpp(391) : error C2027: use of undefined type 'HookContext'


Всё надо переписывать... Так что пока что отключил

А вот так, спасибо, завелось:
Код
char heroLevel = *(char*)(*(int*)(*(int*)0x699420 + 0x53CC) + 85);
проверял на том что легко отследить, уровень героя

Функа combatMonster_SetUpNewRound вызывается столько раз, сколько юнитов.
Так что как-то по другому надо ловить 1й раунд. Ну или сильно усложнять логику. Аля проверять наличие артов (+скорость) что бы их не отнять
Да и в целом побрутфорсил многие параметры, не подошло под "номер раунда" ничего.

Зато реализовал бонусы к статам от артиллерии и первой помощи в банках. Суммарно функа боя в банке выглядит так:

Код
int __stdcall setBankUnitBonus(LoHook* h, HookContext* c)
{
    if ( *(char*)(*(int*)0x699420 + 0x53C5) == 1) { // проверка что бой в банке существ
        if(*(int*)(c->ecx + 201 + 19) > 0) { // проверка натиктику
            *(int*)(c->esi+80) += 2;
        }

        if(*(int*)(c->ecx + 201 + 20) > 0) { //проверка на артиллерию
            if ( *(int*)(c->ecx + 301 + (13 << 3)) == 4 ) { //13 - слот на кукле для баллисты. 4 - айди баллисты
                *(int*)(c->esi + 84) += *(int*)(c->ecx + 201 + 20);
            }
        }

        if(*(int*)(c->ecx + 201 + 27) > 0) { //проверка на палатку
            if ( *(int*)(c->ecx + 301 + (15 << 3)) == 6 ) { //15 - слот на кукле для палатки. 6 - айди палатки
                *(int*)(c->esi + 88) += *(int*)(c->ecx + 201 + 27) * 2;
            }
        }
    }

    return EXEC_DEFAULT;
}

Код
_PI->WriteLoHook(0x4E666A, setBankUnitBonus);


Руководстовался следующей логикой: есть навыки которые дают бонус в бою. Но в банке, в силу определёных обстоятельств этих бонусов нету
Т.о. выдаю альтернативные. Для артилерии +1/2/3 атаки. Для палатки +2/4/6 защиты
А для тактики +1/2/3 скорости. В идеале на 1й раунд только (т.к. тактика в обычном бою действует только в начале). Но пока что всегда +2 сделал

PS: вот тут Феаноровский архив пригодился! Как базу знаний использовал. Повытягивал из него смещения для атаки/защиты монстров. Хоть там и не верные смещения для первичных навыков героя
Go to the top of the pageAdd Nick
 
+Quote Post
AlexSpl
сообщение 29 Dec 2016, 17:11 (Сообщение отредактировал AlexSpl - 29 Dec 2016, 18:03)
Сообщение #372

Immortal
Сообщений: 798
Спасибо сказали: 555 раз




Не знаю, что это за поле такое: *(int*)(cmAddr + 0x132A0), но увеличивается в начале каждого раунда на 1. Причём стартовое значение у меня равно 30000.

База IDA от sergroj не открывается. Похоже, работает только в версии 6.5.

Цитата
Функа combatMonster_SetUpNewRound вызывается столько раз, сколько юнитов.
Так что как-то по другому надо ловить 1й раунд.

Если по смещению 0х132A0 всегда находится (номер_раунда - 30000), то

Код
int cmAddr =  *(int*)0x699420;
int roundNumber = *(int*)(cmAddr + 0x132A0) - 30000; // начиная с 0.
if ( roundNumber == 0 ) { // дать бонус скорости }
if ( roundNumber == 1 ) { // отнять бонус скорости }


* * *
Проверил. Инициализируется счётчик здесь:
Код
.text:004636F0 mov     dword ptr [ebx+0DDF8h], 30000


Затем увеличивается на 1 после каждого раунда. Проблема только с тактикой (счётчик работает в тактической фазе тоже), поэтому перед первым раундом нужно читать его стартовое значение.
Go to the top of the pageAdd Nick
 
+Quote Post
DedMorozzz
сообщение 29 Dec 2016, 18:14
Сообщение #373

God
Сообщений: 267
Спасибо сказали: 25 раз




Код
0х132A0
не хватает 1го символа. не верный адрес
А если смешение, то оно аж ‭78496‬ получается. Не слишком большое?

Проверил код выше с хуком на 004636F0 - не работает.

Что касается тактической фазы - дык её в банках нету же
Go to the top of the pageAdd Nick
 
+Quote Post
AlexSpl
сообщение 29 Dec 2016, 18:21 (Сообщение отредактировал AlexSpl - 29 Dec 2016, 18:38)
Сообщение #374

Immortal
Сообщений: 798
Спасибо сказали: 555 раз




Т.е. код примерно такой. Убрать старый хук на скорость и поставить новый на 475A42h (а лучше до: 475A3Dh). Так мы только по по отрядам с ID != -1 проходить будем.

Цитата
Что касается тактической фазы - дык её в банках нету же

Тогда проще:
Код
{
   int cmAddr =  *(int*)0x699420;
   int roundNumber = *(int*)(cmAddr + 0x132A0) - 30000;
   if ( roundNumber == 0 ) *(int*)(с->ecx + 80) += 2;
   if ( roundNumber == 1 ) *(int*)(c->ecx + 80) -= 2;
   return EXEC_DEFAULT;
}


Все характеристики отрядов и героев доступны из combatManager.

UPD Обновил пост. Попробуйте пока без героя. Просто дайте +2 скорости и посмотрите, что будет во 2-м раунде.
Go to the top of the pageAdd Nick
 
+Quote Post
DedMorozzz
сообщение 29 Dec 2016, 18:36 (Сообщение отредактировал DedMorozzz - 29 Dec 2016, 18:38)
Сообщение #375

God
Сообщений: 267
Спасибо сказали: 25 раз




Скорости нету. Пропускаю ход и звук яда. И сообщение в логе боя "ангел пропускает ход, получая +8 защиты, корчась от боли, пока яд растекается по венам"
Дерусь против триглодитов... и вылетает через какое-то время
PS: убрал всё лишнее - вроде яда нету... хз откуда он взялся. Но бонуса тоже нет (и не отняло ничего в след. раундах)
Go to the top of the pageAdd Nick
 
+Quote Post
AlexSpl
сообщение 29 Dec 2016, 18:39
Сообщение #376

Immortal
Сообщений: 798
Спасибо сказали: 555 раз




Я обновил пост. Попробуйте точно такой код написать.
Go to the top of the pageAdd Nick
 
+Quote Post
DedMorozzz
сообщение 29 Dec 2016, 18:41 (Сообщение отредактировал DedMorozzz - 29 Dec 2016, 18:44)
Сообщение #377

God
Сообщений: 267
Спасибо сказали: 25 раз




Цитата(AlexSpl @ 29 Dec 2016, 17:39) *
Я обновил пост. Попробуйте точно такой код написать.

я именноего и пробовал. В условиях увеличил 0 до 1, а 1 до 2х, снова яд был! Чушь какая-то
Go to the top of the pageAdd Nick
 
+Quote Post
AlexSpl
сообщение 29 Dec 2016, 18:43
Сообщение #378

Immortal
Сообщений: 798
Спасибо сказали: 555 раз




Старый хук на скорость убрали? Напиши Ваш код (вместе с хуком).
Go to the top of the pageAdd Nick
 
+Quote Post
DedMorozzz
сообщение 29 Dec 2016, 18:44
Сообщение #379

God
Сообщений: 267
Спасибо сказали: 25 раз





Код:
Код
int __stdcall setBankUnitBonus(LoHook* h, HookContext* c)
{
    if ( *(char*)(*(int*)0x699420 + 0x53C5) == 1) { // проверка что бой в банке существ
        if(*(int*)(c->ecx + 201 + 19) > 0) { // проверка натиктику
            //*(int*)(c->esi+80) += 2;
        }

        if(*(int*)(c->ecx + 201 + 20) > 0) { //проверка на артиллерию
            if ( *(int*)(c->ecx + 301 + (13 << 3)) == 4 ) { //13 - слот на кукле для баллисты. 4 - айди баллисты
                *(int*)(c->esi + 84) += *(int*)(c->ecx + 201 + 20);
            }
        }

        if(*(int*)(c->ecx + 201 + 27) > 0) { //проверка на палатку
            if ( *(int*)(c->ecx + 301 + (15 << 3)) == 6 ) { //15 - слот на кукле для палатки. 6 - айди палатки
                *(int*)(c->esi + 88) += *(int*)(c->ecx + 201 + 27) * 2;
            }
        }
    }

    return EXEC_DEFAULT;
}

int __stdcall resetTacticsUnitSpeedBonus(LoHook* h, HookContext* c)
{
    int cmAddr =  *(int*)0x699420;
    int roundNumber = *(int*)(cmAddr + 0x132A0) - 30000;
    if ( roundNumber == 2 ) *(int*)(c->ecx + 80) += 2;
    if ( roundNumber == 1 ) *(int*)(c->ecx + 80) -= 2;

    return EXEC_DEFAULT;
}


Код
_PI->WriteLoHook(0x4E666A, setBankUnitBonus);
_PI->WriteLoHook(0x475A42, resetTacticsUnitSpeedBonus);
Go to the top of the pageAdd Nick
 
+Quote Post
AlexSpl
сообщение 29 Dec 2016, 18:56 (Сообщение отредактировал AlexSpl - 29 Dec 2016, 18:58)
Сообщение #380

Immortal
Сообщений: 798
Спасибо сказали: 555 раз




Ага, кажется, понятно. (int*)(c->ecx + 80) не указывает на скорость. Счас гляну.

Код
int __stdcall resetTacticsUnitSpeedBonus(LoHook* h, HookContext* c)
{
    int cmAddr =  *(int*)0x699420;
    int roundNumber = *(int*)(cmAddr + 0x132A0) - 30000;
    if ( roundNumber == 1 ) *(int*)(c->ecx + 196) -= 2;

    return EXEC_DEFAULT;
}

...
_PI->WriteLoHook(0x4E666A, setBankUnitBonus);
_PI->WriteLoHook(0x475A3D /* ! */, resetTacticsUnitSpeedBonus);


UPD Поправил. Ведь хук срабатывает в конце раунда, так что старый тоже нужно оставить: он инициализирует скорость.


Спасибо сказали:
Go to the top of the pageAdd Nick
 
+Quote Post

29 страниц V  « < 17 18 19 20 21 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



Текстовая версия Сейчас: 10 October 2025 - 14:04
Copyright by Алексей Крючков
Strategy Gamez by GrayMage
Programming by Degtyarev Dmitry
  Яндекс.Метрика