Полная версия этой страницы:
Мод на ХотА
AlexSpl
12 Dec 2016, 21:52
А как игра будет знать, что нужно вычесть эти +2 после боя?
Насколько я помню (по Героям 1 и 2), мораль считается примерно так:
- бонус за армию (сводится к 2 - [кол-во фракций в отряде героя*]);
- бонус героя;
- бонусы за арты;
- бонусы за посещённые объекты.
При кол-ве разных отрядов больше 1
Или +282 - это совокупный временный бонус, который после битвы обнуляется?
А игра и не знает как их вычесть. На сколько я понял из кода. Она просто после боя вызывает функцию 0x4E3C3C, в которой заново пересчитывает мораль (+282) в следующей последовательности:
- проверили лидерство (и навык и специализацию)
- проверили арты (108, 49, 50, 51)
- проверили есть ли грааль в Замке
и потом вернули результат.
В любом случае, добавочные временные показатели после боя вычитаются/обнуляются корректно.
PS: да да. расчет специализации "Лидерство" в коде имеет место быть. Я как то изощрялся и знаю, что герой 32767 уровня (последний вообще возможный уровень) являющийся специалистом по лидерству имеет +4915 ед. боевого духа))
AlexSpl
12 Dec 2016, 22:19
Цитата
А игра и не знает как их вычесть. На сколько я понял из кода. Она просто после боя вызывает функцию 0x4E3C3C
Не знаю, как в Тройке, но в Г1-2 подобная функция пересчитывает мораль по каждому чиху (например, если просто зайти в окно героя). Так понимаю, на экране героя 2 птички не исчезают? А что в описании по ПКМ?
На столько глубоко я не копал. Поэтому точно не знаю. Предпологаю, что после битвы где-то происходит обнуление морали, а потом вывзов этой функции. Знаю, что приведенный мной код работает правильно. В Г3 эта функция вызывается тоже довольно таки часто и я увидел разницу только в последнем параметре (0 или 1).
Да, 2 птички не исчезают, а пишет, что "+х временно до следующей битвы".
AlexSpl
12 Dec 2016, 22:38
Интересная инфа. Спасибо. Начинаю припоминать, что ведь ивенты тоже мораль могут давать, так что действительно имеет смысл не пересчитывать.
DedMorozzz
14 Dec 2016, 16:25
igrik, завелось. Спасибо. Вот сдвига мне и не хватало (хм...как-то странно звучит, ну да ладно)
Сам адресс функци вроде нашел, а вот +282 не нашел де пишется
Терь хочу убрать возможность коннекта юнитов, при наличии дипломатии.
Как я понимаю это достаточно сложно. Ибо нужна ф-я которая проводит всё расчёты:
Аля сила войска, что бы понять убегать нейтралам или нет. Насколько паков делить войска и т.д.
И в ней (как я это себе вижу). Будет проверка, если дипломатия имеется, и прошло сравнение силы войск, тогда мол присоедениться..
Как я понимаю, сразу в ней и можно "увеличить" силу армии на 5/10/15%, в зависимости от навыка дипломатии..
Соотв. вопрос - как отключить присоединение войск, какая ф-я это, что бы её обнулить
Проблема в том, что таковой функции нет. Расчет присоединения прописан в 2-х так называемых местах: ПКМ на монстре и при атаке монстров. Первое feanor описал
тут, второе же нигде пока не было описано (а происходит приблизительно в 0x4A704A). Но это такая дикая муть. Лично я пока не знаю приемлемого решения по данному вопросу.
Но, насколько мне известно, данный вопрос решил только
MoP. Каким именно способом - я не знаю, хотя склоняюсь к такому варианту: еженедельный перебор всех монстров на карте с изменением параметра агрессии на "выше нуля".
Можно конечно и при нападении менять этот параметр агрессии, но тогда остается нерешенным косяк с ПКМ. В общем я пока хз, но попробую покопать.
AlexSpl
14 Dec 2016, 19:32
Самый простой способ - при старте карты генерировать всех монстров с агрессией равной 10 (её значение не меняется по ходу игры). Но нужно ещё учесть месяц существ. Инициализация рандомных объектов происходит в цикле 4C0A24h (для SoD 3.2). Там и кол-во монстров в отрядах нейтралов генерируется, если, конечно, не указано их точное кол-во автором карты. Этот случай отдельно смотреть надо.
Агрессия 10 - монстры никогда не присоединятся. Так делать нельзя, ведь нужно оставить возможность присоединения за деньги
AlexSpl
14 Dec 2016, 19:41
Цитата
Агрессия 10 - монстры никогда не присоединятся. Так делать нельзя, ведь нужно оставить возможность присоединения за деньги
Цитата
Соотв. вопрос - как отключить присоединение войск, какая ф-я это, что бы её обнулить
Тогда нужно менять саму функцию присоединения. У меня где-то была база с разобранной Дипломатией (правда, для СоД).
Ну если отключить, то тогда да. Но это решение совсем не приемлемое, ИМХО.
На счет базы - было бы отлично ее увидеть. Уверен, что в данном месте в коде нет разницы для SoD/HotA/WoG/Era
MasterOfPuppets
14 Dec 2016, 19:59
Я вроде делал плагин для ЭРЫ DiplomacyCorrect.bin, разрешающий присоединение только за деньги. Лежал три года на сервере mop-drew.ru. Если ни у кого не сохранился - завтра найду.
А, впрочем, уже нашёл:
Код
; НАЗВАНИЕ: DiplomacyCorrect
; ВЕРСИЯ: 1.0
; АВТОР: MoP
; ОПИСАНИЕ: разрешает присоединение монстров только за деньги
; EXE: TE
; 4A755D:
; JG SHORT 004A75A3 => JMP SHORT 004A75A3
A755D EB
AlexSpl
14 Dec 2016, 20:07
В HotA это функция sub_4A73B0. Вот тут теория:
http://heroescommunity.com/viewthread.php3?TID=28341Цитата
; JG SHORT 004A75A3 => JMP SHORT 004A75A3
В данном случае этот джамп на безусловный поменять:
Код
.text:004A7530 jle short loc_4A7550
Т.е. jle short loc_4A7550 на jmp short loc_4A7532
DedMorozzz
14 Dec 2016, 20:12
на самом деле да. Цель убрать вообще возможность присоединения.
Повторюсь, основная цель сбалансить игру для джебуса. А насчёт "недели монстра", я за лет 7-8 опыта игры в Г3 не припомню игры больше чем 4я неделя)
Потому и хочу сделать навык более балансным. Убрать одно, а дать другое. Вот туда и библиотека, сила армии в глазах монстров, возможность откупаться от монстров (мб с ценойв 10% от армии) .. Что бы навык был полезным. Но работал немного по другому
В принципе агрессия == 10, кастыль, но вполне себе решение

Но как я понимаю, это изменение генератора, а не смена функи..
Тогда весь патч будет иметь вид (отключение только бесплатного присоединения)
Код
_PI->WriteDword((0x417236 + 1), 3); // при ПКМ
_PI->WriteHexPatch((0x4A755D), "EB"); // при нападении на монстров
Но на работоспособность я не проверял.Кстати, возможно где-то еще есть расчет для AI.
upd: проверил на хоте. Работает.
AlexSpl
14 Dec 2016, 20:33
Лучше jle short loc_4A7550 на jmp short loc_4A7532 (см. мой пост выше).
UPD Хотя нет, тогда монстры сбегать перестанут

Попробуйте так:
Код
_PI->WriteHexPatch((0x4A755D), "EB"); // проходим мимо бесплатного присоединения
_PI->WriteHexPatch((0x4A75A9), "EB"); // проходим мимо платного присоединения
DedMorozzz
14 Dec 2016, 22:41
Монстры больше не присоединяются, это вышло! Хоть и не понял откуда вы эти адреса получили)
И что такое параметр "ЕВ"?
А вот это не завелось:
Код
_PI->WriteDword((0x417236 + 1), 3); // при ПКМ
Всё равно пишется что присоединятся, а по факту сбегают (я так понимаю, что и нападают тоже..)
Пробовал вместо +1, делать +2. Или 3 на большие числа менять - ошибка
Так же поискал силу армии. Поучитал темку
http://heroescommunity.com/viewthread.php3?TID=28341Цель - всё та же дипломатия. Силу армии при наличии навыка, для монстров считать выше на 5/10/15%
Искал по Power (ничё не нашел) и по Army
Нашел такое: 0044A950 ; int __fastcall GetArmyAIValue(_MonArr_ *MonArr)
Т.к. не нашел силы армии героя. Думаю понижу расчёт силы армии монстров.. решил задать просто число. Валится игра
Делал так:
Код
_PI->WriteLoHook(0x44A950, getArmyValue);
В функе это
Код
c->return_address = 0x63EAE4; // тут 0.05 хранится
return NO_EXEC_DEFAULT;
Каким образом усилить свою армию или ослабить армию нейтралов, при расчёте побега или на сколько пачек делать войска?
AlexSpl
14 Dec 2016, 22:59
EB - это опкод ближнего безусловного джампа (jmp short).
Я вот что порекомендую. Откройте базу IDA, перейдите по адресу 4A73B0h (клавиша G, в окошко введите адрес: 4A73B0). Поставьте брейкпоинт (клавиша F2). Теперь запустите игру, выставьте оконный режим и загрузите карту. Далее, в IDA выберите пункт меню Debugger -> Attach to process... В списке процессов найдите HotA. Игра будет приостановлена. Самое время ставить hardware брейкпоинты. Но сейчас ничего не нужно делать, просто нажмите F9. В игре нападите на монстра. После этого сработает брейкпоинт. Переключитесь в графический режим (блок-схемы, клавиша Space) и последовательно нажимайте F8 (Step over), чтобы пошагово выполнять инструкции. Наблюдайте, что происходит

Надоест - снова жмите F9.
Смысл сего мероприятия в том, чтобы попытаться понять логику работы функции (в данном случае sub_4A73B0). В этой функции как раз таки присутствует вызов (call) другой функции, которая и считает силу армии. А возвращаемое значение уже можно вертеть, как угодно.
Цитата
... Валится игра
Это будет происходить очень часто, пока не поймёте, как устроен код.
P.S.
Цитата
Силу армии при наличии навыка, для монстров считать выше на 5/10/15%
А смысл? На что это будет влиять, если монстры не будут присоединяться?
Ага...
Цитата
Каким образом усилить свою армию или ослабить армию нейтралов, при расчёте побега или на сколько пачек делать войска?
ОК, условие побега действительно зависит от силы армии. Поэтому, после того, как она будет подсчитана, Вам нужно добавить собственный код, который в зависимости от уровня Дипломатии будет умножать её на 1.05, 1.10 или 1.15. Тут двумя строчками уже не отделаешься

Насчёт деления на стеки. Это уже совсем другая функция, но принцип тот же: после расчёта силы армии модифицируем значение собственным кодом.
DedMorozzz
17 Dec 2016, 16:56
Вот что получилось найти:
ф-я при нападении на юнитов (4A73B0):
Суммарно вызывается 3 ф-ии: sub_00427650, sub_004A7230, sub_004A68D0/sub_004A6A60
1я (sub_00427650). Как я понимаю именно тут расчёт армии и происходит. Ибо вызывается в ней и функу которую кидал выше, монстрВелью и Hero_GetAttackDefCoef (004E5670)
2я (sub_004A7230). По коду только несколько кейсов. Скорее всего решает в какой блок кинуть дальше (см. пункт 3)
3я sub_004A68D0. Тут как я понял идёт рассчёт насколько стаков делить и будет ли пачка улучшеных юнитов. Т.е. уже начало боя
или если армия сильнее, тогда это:
sub_004A6A60 (тут вопрос, нападать или дать сбежать)
Т.о. Увеличить "вес" армии надо или в 1й (скорее всего) или 2й ф-ии.
Редачил вызовы из 1й ф-ии. Пробовал менять Hero_GetAttackDefCoef (как я понимаю, увеличение силы армии, от статов) что бы возвращала всегда 1/1000/0.05 даже 20-49 триглодитов нападают на 50 архов, при любом из этих значений
Как всё же увеличить вес своей армии, при расчёт побега на 20%? Снова таки, под дипломатию и цифры сам подгоню...
Ибо понимаю, что вроде нашел что надо. Но что с этим дальше делать, пока что не представляю
AlexSpl
17 Dec 2016, 20:03
"Чистую" силу армии героя ("альфу") считает функция sub_44A950 (в цикле проходит по всем слотам). Функция sub_427650 возвращает уже полную силу армии (с учётом атаки и защиты героя) в регистре eax, а именно умножает "альфу" на sqrt((1 + 0.05 * HeroAttack) * (1 + 0.05 * HeroDefense)). Но для Вашей задачи, если сильно не заморачиваться на округлении, модифицировать можно полную силу, так как 1.2 (увеличение на 20%) - просто ещё один множитель.
Поэтому перед выполнением инструкции по адресу 4A7441h необходимо выполнить собственный код, который будет умножать значение регистра eax на 1.2 (или на коэффициент, зависящий от уровня Дипломатии). Затем вернуть управление по адресу 4A7441h.
DedMorozzz
17 Dec 2016, 20:30
это я и понял, что надо сделать. Выше описал примерно. А вот КАК это сделать - хз. Могу переписывать ф-ю по адресу, это понимаю как. Но как словить входные параметры. Их отредачить и вызвать оригинал - хз как
AlexSpl
17 Dec 2016, 20:46
Вот, что пишет
baratorch:
Цитата
LoHook - это, соответственно, "низкоуровневый" хук. Его мы можем поставить вообще на любое место в коде. При этом мы получаем возможность работать с регистрами процессора как с переменными, используя их в нашем (допустим С++) коде и можем менять адрес возврата.
LoHook - гораздо более мощный и универсальный инструмент, в сравнение с HiHook'ом. Им можно решать любые задачи (даже те что решают SPLICE_ и CALL_ хайхуки).
DedMorozzz
17 Dec 2016, 22:55
мне это ничем не помогло. Я понимаю ЧТО надо сделать, я не понимаю как. А именно как получить результат работы ф-ии и изменить этот результат. И передать его куда-то дальше
AlexSpl
17 Dec 2016, 23:52
Проверить не могу, так что
псевдокод:
Код
int __stdcall ModifyPower(LoHook* h, HookContext* c) {
c->eax *= 1.2f;
return EXEC_DEFAULT;
}
Код
_PI->WriteLoHook(0x4A7441, (void*)ModifyPower);
feanor
18 Dec 2016, 01:00
Нет, не так.
Надо использовать хайхук со сплайсом.
AlexSpl
18 Dec 2016, 01:12
2feanor: а как же это:
Цитата
LoHook - гораздо более мощный и универсальный инструмент, в сравнение с HiHook'ом. Им можно решать любые задачи (даже те что решают SPLICE_ и CALL_ хайхуки).
feanor
18 Dec 2016, 01:33
Ну да.
Но это не значит, что им нужно пользоваться и тогда, когда есть специализированные и более приспособленные инструменты.
AlexSpl
18 Dec 2016, 01:41
А как решается задача с помощью хайхука со сплайсом? И где мы выигрываем?
feanor
18 Dec 2016, 15:03
опять же, условный код, пока нет времени вникать в тред (единственно что могу сказать, что дробные результаты емнип не через eax возвращаются, а через st0)
Код
int __stdcall OnFunc(HiHook* h, int pam, int param, int pararam)
{
param = some_tuning(param);
int ret = CALL_3(int, __thiscall, h->GetOriginalFunc(), pam, param, pararam);
ret = do_something(ret);
return ret;
}
...
h->WriteHiHook(0x4567890, SPLICE_, EXTENDED_, THISCALL_, (void*)OnFunc);
Еще можно CALL_, непосредственно на вызовы, если надо только в каких-то конкретных случаях механику менять.
Выигрываем, во-первых, в высокоуровневости и дальнейшей читаемости кода, во-вторых, в одном хуке вместо нескольких (лоухуков надо на каждый ret + еще один для снятия параметров на старте функции, да еще и глобальные переменные заводить)
AlexSpl
18 Dec 2016, 16:14
Цитата
единственно что могу сказать, что дробные результаты емнип не через eax возвращаются, а через st0
Там не дробный результат возвращается: eax (силу армии) умножаем на 1.2, а затем отбрасываем дробную часть.
DedMorozzz
18 Dec 2016, 18:41
ни 1й, ни 2й вариант не завёлся.
1й:
Код
int __stdcall setArmyValue(LoHook* h, HookContext* c)
{
if (*(char*)(c->esi + 201 + 4) > 0) {
c->eax *= 20;
}
return EXEC_DEFAULT;
}
...
_PI->WriteLoHook(0x4A7441, setArmyValue);
При дипломатии умножаю силу в 20 раз. Что бы проверить, что от копейщиков убегают сильные войска.. Вылетает
Пробовал и делить на 100, с округлением. Что бы на 50 ангелов нападали гоблины. Так же вылетает при нападении
2й вариант:
Код
int __stdcall ModifyPower(HiHook* h, int pam, int param, int pararam)
{
int ret = CALL_3(int, __thiscall, h->GetOriginalFunc(), pam, param, pararam);
// if (*(char*)(c->esi + 201 + 4) > 1) {
ret = floor(ret * 0.2); //ослабить армию в 5 раз
// }
return ret;
}
...
_PI->WriteHiHook(0x4A7441, SPLICE_, EXTENDED_, THISCALL_, ModifyPower);
Тут проблема в том, что c (HookContext) нету. А как без него получить уровень дипломатии не знаю
AlexSpl
18 Dec 2016, 18:51
А так вылетает?
Код
int __stdcall setArmyValue(LoHook* h, HookContext* c)
{
if (*(char*)(c->esi + 201 + 4) > 0) {
// c->eax *= 20;
}
return EXEC_DEFAULT;
}
...
_PI->WriteLoHook(0x4A7441, (void*)setArmyValue);
DedMorozzz
18 Dec 2016, 18:58
Цитата(AlexSpl @ 18 Dec 2016, 17:51)

А так вылетает?
Неа, слабые убегают, сильные - нападают.. т.е. работает в штатном режиме
AlexSpl
18 Dec 2016, 19:01
Т.е. если раскомментировать, вылет?
DedMorozzz
18 Dec 2016, 19:04
Цитата(AlexSpl @ 18 Dec 2016, 18:01)

Т.е. если раскомментировать, вылет?
верно. Была идея, что сликом большие цифры делаю (сомнительно но всё же...).
Усилил в 2 раза (c->eax *= 2;) Так же вылетает
Может чёт не то правлю?
AlexSpl
18 Dec 2016, 19:11
А вот это работает?
Код
int __stdcall setArmyValue(LoHook* h, HookContext* c)
{
int Power = c->eax;
return EXEC_DEFAULT;
}
...
_PI->WriteLoHook(0x4A7441, (void*)setArmyValue);
DedMorozzz
18 Dec 2016, 19:16
Цитата(AlexSpl @ 18 Dec 2016, 18:11)

А вот это работает?
да. Точно так же, слабые сбегают, сильные нападают
AlexSpl
18 Dec 2016, 19:20
Наверное, я не понимаю, что такое контекст в LoHook. Он что, read-only? Вот ещё вариант:
Код
int __stdcall setArmyValue(LoHook* h, HookContext* c)
{
(int)c->eax = (int)c->eax * 20;
return EXEC_DEFAULT;
}
...
_PI->WriteLoHook(0x4A7441, (void*)setArmyValue);
На ассемблере всё работало бы. Идея перехватить код до выполнения инструкции по адресу 4A7441h, модифицировать регистр eax, и вернуть управление обратно.
DedMorozzz
18 Dec 2016, 19:34
Да, так работает. Слабые убегают, сильные убегают. Очень сильные - нападают
Но, предпросмотр пишет не правду. Пишут что мобы нападут. При нападении на них - они сбегают
Выходит для пред просмотра отдельная ф-я вызывается?
AlexSpl
18 Dec 2016, 19:41
Да, предпросмотр - в отдельной функции. Функция sub_426750 вызывается из 4-х мест в коде. Установите курсор на sub_427650 и нажмите X. IDA покажет все кроссреференсы (xref). Ставим LoHook на следующую за вызовом функции инструкцию и модифицируем eax.
Только, если я правильно понимаю, контекст локальный, поэтому это: *(char*)(c->esi + 201 + 4) не будет возвращать уровень Дипломатии.
DedMorozzz
18 Dec 2016, 20:13
Цитата(AlexSpl @ 18 Dec 2016, 18:41)

Только, если я правильно понимаю, контекст локальный, поэтому это: *(char*)(c->esi + 201 + 4) не будет возвращать уровень Дипломатии.
Угу, стоит обернуть в проверку дипломатии, и сразу падает игра. При этом просто (*(char*)(c->esi + 201 + 4) >0 ) { //тут пусто} не падает

Каким образом в данном контексте дипломатию получить?
Метода аля "гетКаррентХиро" не вижу
PS: хотя странно. Для текущего же героя беру силу армии. Вот для текущего героя и хочу получить дипломатию. Не понятно чего не будет её возвращать..
AlexSpl
18 Dec 2016, 20:34
В нашем случае:
Код
*(char*)(c->edi + 205)
Код
int __stdcall setArmyValue(LoHook* h, HookContext* c)
{
char DiploLevel = *(char*)(c->edi + 205);
switch ( DiploLevel ) {
case 1: (int)c->eax = (int)c->eax * 1.05f;
case 2: (int)c->eax = (int)c->eax * 1.10f;
case 3: (int)c->eax = (int)c->eax * 1.15f;
}
return EXEC_DEFAULT;
}
...
_PI->WriteLoHook(0x4A7441, (void*)setArmyValue);
Или так:
Код
int __stdcall setArmyValue(LoHook* h, HookContext* c)
{
char DiploLevel = *(char*)(c->edi + 205);
float Mod;
switch ( DiploLevel ) {
case 1: Mod = 1.05;
case 2: Mod = 1.10;
case 3: Mod = 1.15;
}
(int)c->eax = (int)c->eax * Mod;
return EXEC_DEFAULT;
}
...
_PI->WriteLoHook(0x4A7441, (void*)setArmyValue);
DedMorozzz
18 Dec 2016, 20:37
Получилось! Вот код:
Код
int __stdcall setArmyValue(LoHook* h, HookContext* c)
{
int diplomatyLevel = (int)(*(char*)(c->edi + 205));
if (diplomatyLevel > 0) {
if (diplomatyLevel == 1) {
(int)c->eax = (int)c->eax * 1.1;
}
if (diplomatyLevel == 2) {
(int)c->eax = (int)c->eax * 1.15;
}
if (diplomatyLevel == 3) {
(int)c->eax = (int)c->eax * 1.2;
}
}
return EXEC_DEFAULT;
}
Почему тут edi юзать? И чем от esi отличается?
PS: Ага, вижу обновлёный пост со свичем... покрасивее будет. И решил 10-15-20 сделать

и DiploLevel это же инт. Я у себя в коде интом обозвал его и работает
AlexSpl
18 Dec 2016, 20:43
А так работает?
Код
int __stdcall setArmyValue(LoHook* h, HookContext* c)
{
char DiploLevel = *(char*)(c->edi + 205);
float Mod;
switch ( DiploLevel ) {
case 1: Mod = 1.05;
case 2: Mod = 1.10;
case 3: Mod = 1.15;
}
(int)c->eax *= Mod;
return EXEC_DEFAULT;
}
...
_PI->WriteLoHook(0x4A7441, (void*)setArmyValue);
Цитата
Почему тут edi юзать? И чем от esi отличается?
Потому что в данном контексте указатель на стуктуру героя хранится в регистре edi.
DedMorozzz
18 Dec 2016, 20:52
Цитата(AlexSpl @ 18 Dec 2016, 19:43)

А так работает?
Цитата
Почему тут edi юзать? И чем от esi отличается?
Потому что в данном контексте указатель на стуктуру героя хранится в регистре edi.
Да, так работает тоже. Финальный вариант кода:
Код
int __stdcall setArmyValue(LoHook* h, HookContext* c)
{
int diplomatyLevel = (int)(*(char*)(c->edi + 201 + 4));
if (diplomatyLevel > 0) {
float armyModificator = 1;
switch (diplomatyLevel) {
case 1: armyModificator = 1.1;
case 2: armyModificator = 1.15;
case 3: armyModificator = 1.2;
}
(int)c->eax *= armyModificator;
}
return EXEC_DEFAULT;
}
Ибо в коде выше (не проверял, без дипломатии) но по логике если дипломатии нету, то модификатор будет пустым. И на пустоту умножу текущую силу армии, не уверен что это то что надо

А насчёт edi/esi как понять когда что нужно? Пока что логика не ясна
AlexSpl
18 Dec 2016, 20:57
Цитата
Ибо в коде выше (не проверял, без дипломатии) но по логике если дипломатии нету, то модификатор будет пустым. И на пустоту умножу текущую силу армии, не уверен что это то что надо
В свитче default пропиши.
Цитата
А насчёт edi/esi как понять когда что нужно? Пока что логика не ясна
esi и edi - это регистры процессора (просто контейнеры). Адрес героя мог бы и в ecx храниться. Всё зависит от контекста. Конкретно в каждом случае нужно код смотреть.
Код
int __stdcall setArmyValue(LoHook* h, HookContext* c)
{
char DiploLevel = *(char*)(c->edi + 205);
float Mod;
switch ( DiploLevel ) {
case 1: {
Mod = 1.05;
break;
}
case 2: {
Mod = 1.10;
break;
}
case 3: {
Mod = 1.15;
break;
}
default: Mod = 1.00;
}
(int)c->eax *= Mod;
return EXEC_DEFAULT;
}
...
_PI->WriteLoHook(0x4A7441, (void*)setArmyValue);
DedMorozzz
18 Dec 2016, 21:03
Цитата(AlexSpl @ 18 Dec 2016, 19:57)

В свитче default пропиши.
Не нужно уже

Я заходить буду в блок пересчёта силы армии, только при наличии дипломатии.
Но для понимания "дефолтного" значения при объявлении переменой присвоил ей еденицу.
В принципе и комментом можно было это сделать
DedMorozzz
18 Dec 2016, 21:30
Предпросмотр не завёлся
Нашел метод предпросмотра (скорее всего нашел

)
_PI->WriteLoHook(0x4171DB, setArmyValue); - тут в Dlg_MonsterRMHint вызывается sub_426750
Пробовал и на адреса ниже, по аналогии с 0x4A7441 ибо меняли 0x4A7441, а метод вызывается на 2 строчки выше (004A7439)
Итого пробовал вот эти адреса ещё:
_PI->WriteLoHook(0x4171E0, setArmyValue);
_PI->WriteLoHook(0x4171E6, setArmyValue);
Везде ошибка, при ПКМ на монстре. При этом нападаю если - всё работает штатно
PS: и да, брейки в код добавил
AlexSpl
18 Dec 2016, 21:35
Цитата
_PI->WriteLoHook(0x4171DB, setArmyValue);
Ставь LoHook на следующую инструкцию после call: 4171E0h
DedMorozzz
18 Dec 2016, 21:39
Цитата(AlexSpl @ 18 Dec 2016, 20:35)

Цитата
_PI->WriteLoHook(0x4171DB, setArmyValue);
Ставь LoHook на следующую инструкцию после call: 4171E0h
Следующая строчка это "4171E6"
Для неё тоже пробовал, в посте выше есть этот адрес
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.