![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() ![]() |
![]() |
![]()
Сообщение
#141
|
|
![]() God Сообщений: 267 Спасибо сказали: 25 раз ![]() |
Только, если я правильно понимаю, контекст локальный, поэтому это: *(char*)(c->esi + 201 + 4) не будет возвращать уровень Дипломатии. Угу, стоит обернуть в проверку дипломатии, и сразу падает игра. При этом просто (*(char*)(c->esi + 201 + 4) >0 ) { //тут пусто} не падает ![]() Каким образом в данном контексте дипломатию получить? Метода аля "гетКаррентХиро" не вижу PS: хотя странно. Для текущего же героя беру силу армии. Вот для текущего героя и хочу получить дипломатию. Не понятно чего не будет её возвращать.. |
|
|
![]()
Сообщение
#142
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз ![]() |
В нашем случае:
Код *(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); |
|
|
![]()
Сообщение
#143
|
|
![]() God Сообщений: 267 Спасибо сказали: 25 раз ![]() |
Получилось! Вот код:
Код 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 это же инт. Я у себя в коде интом обозвал его и работает |
|
|
![]()
Сообщение
#144
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз ![]() |
А так работает?
Код 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. |
|
|
![]()
Сообщение
#145
|
|
![]() God Сообщений: 267 Спасибо сказали: 25 раз ![]() |
А так работает? Цитата Почему тут 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 как понять когда что нужно? Пока что логика не ясна |
|
|
![]()
Сообщение
#146
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз ![]() |
Цитата Ибо в коде выше (не проверял, без дипломатии) но по логике если дипломатии нету, то модификатор будет пустым. И на пустоту умножу текущую силу армии, не уверен что это то что надо В свитче 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); |
|
|
![]()
Сообщение
#147
|
|
![]() God Сообщений: 267 Спасибо сказали: 25 раз ![]() |
|
|
|
![]()
Сообщение
#148
|
|
![]() God Сообщений: 267 Спасибо сказали: 25 раз ![]() |
Предпросмотр не завёлся
Нашел метод предпросмотра (скорее всего нашел ![]() _PI->WriteLoHook(0x4171DB, setArmyValue); - тут в Dlg_MonsterRMHint вызывается sub_426750 Пробовал и на адреса ниже, по аналогии с 0x4A7441 ибо меняли 0x4A7441, а метод вызывается на 2 строчки выше (004A7439) Итого пробовал вот эти адреса ещё: _PI->WriteLoHook(0x4171E0, setArmyValue); _PI->WriteLoHook(0x4171E6, setArmyValue); Везде ошибка, при ПКМ на монстре. При этом нападаю если - всё работает штатно PS: и да, брейки в код добавил |
|
|
![]()
Сообщение
#149
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз ![]() |
Цитата _PI->WriteLoHook(0x4171DB, setArmyValue); Ставь LoHook на следующую инструкцию после call: 4171E0h |
|
|
![]()
Сообщение
#150
|
|
![]() God Сообщений: 267 Спасибо сказали: 25 раз ![]() |
|
|
|
![]()
Сообщение
#151
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз ![]() |
Предпросмотр который? Visions?
Замени edi на esi. Код char DiploLevel = *(char*)(c->esi + 205); Хук на 4171E0h или 4171E6h - не важно. |
|
|
![]()
Сообщение
#152
|
|
![]() God Сообщений: 267 Спасибо сказали: 25 раз ![]() |
Предпросмотр который? Visions? Замени edi на esi. Да! Так работает. Вообще не ясна логика когда что юзать... кроме как наугад менять И как вот эту штуку сделать рабочей Цитата Код _PI->WriteDword((0x417236 + 1), 3); // при ПКМ Ибо показывает что присоеденятся при предпросмотре (да-да, Vision), а по факту убегают/нападают |
|
|
![]()
Сообщение
#153
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз ![]() |
Цитата Да! Так работает. Вообще не ясна логика когда что юзать... кроме как наугад менять Ставь брейкпоинт на 4171E6h и смотри в каком регистре хранится указатель на героя. Т.е. G[o] -> 4171E6, F2, кастуем Visions, ПКМ, срабатывает брейкпоит, анализируем код. Цитата И как вот эту штуку сделать рабочей Просто убери. Там другой патч нужен. Попробуй так: Код _PI->WriteHexPatch(0x417234, "EB"); // проходим мимо бесплатного присоединения _PI->WriteHexPatch(0x417246, "EB"); // проходим мимо платного присоединения HiHook на sub_4170B0. |
|
|
![]()
Сообщение
#154
|
|
![]() God Сообщений: 267 Спасибо сказали: 25 раз ![]() |
Цитата Да! Так работает. Вообще не ясна логика когда что юзать... кроме как наугад менять Ставь брейкпоинт на 4171E6h и смотри в каком регистре хранится указатель на героя. Т.е. G[o] -> 4171E6, F2, кастуем Visions, ПКМ, срабатывает брейкпоит, анализируем код. https://sc-cdn.scaleengine.net/i/fbe739dbe6...02d39ddd287.png Прошелся по коду. Там этих edi/esi уйма. И все подряд идут) Попробуй так: Код _PI->WriteHexPatch(0x417234, "EB"); // проходим мимо бесплатного присоединения _PI->WriteHexPatch(0x417246, "EB"); // проходим мимо платного присоединения Работает ![]() Кстати новый код что бы не дублировать логику для дипломатии, для нападения и для Вижина (20 для теста юзаю): Код float __stdcall getArmyValueModificator(int diplomatyLevel) { float armyModificator = 1; if (diplomatyLevel > 0) { switch (diplomatyLevel) { case 1: { armyModificator = 1.1; break; } case 2: { armyModificator = 1.15; break; } case 3: { armyModificator = 20; break; } } } return armyModificator; } int __stdcall setArmyValue(LoHook* h, HookContext* c) { int diplomatyLevel = (int)(*(char*)(c->edi + 201 + 4)); float armyModificator = getArmyValueModificator(diplomatyLevel); (int)c->eax *= armyModificator; return EXEC_DEFAULT; } int __stdcall setArmyValuePreview(LoHook* h, HookContext* c) { int diplomatyLevel = (int)(*(char*)(c->esi + 201 + 4)); float armyModificator = getArmyValueModificator(diplomatyLevel); (int)c->eax *= armyModificator; return EXEC_DEFAULT; } |
|
|
![]()
Сообщение
#155
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз ![]() |
Только в этом:
Код if (diplomatyLevel > 0) нет смысла, т.к. дефолтный float armyModificator = 1; уже прописан. Я рекомендую всё-таки прописать его в default. P.S. Разве не стоит цель оптимизировать. Но в этом случае вообще от свитча уходить нужно ![]() Код float armyModificator[4] = {1.00, 1.10, 1.15, 20.00};
return ( (diplomacyLevel >= 0) && (diplomacyLevel <= 3) ? armyModificator[diplomacyLevel] : ERROR_CODE ); |
|
|
![]()
Сообщение
#156
|
|
![]() God Сообщений: 267 Спасибо сказали: 25 раз ![]() |
Только в этом: Код if (diplomatyLevel > 0) нет смысла, т.к. дефолтный float armyModificator = 1; уже прописан. Я рекомендую всё-таки прописать его в default. хм. Не соглашусь.. Без этой проверки свич/кейс будет выполняться всегда. Даже когда дипломатия отсутствует P.S. Разве не стоит цель оптимизировать. Но в этом случае вообще от свитча уходить нужно ![]() Код float armyModificator[4] = {1.00, 1.10, 1.15, 20.00}; return armyModificator[diplomacyLevel]; Тоже верно. Но если потребуется чуть расширить, кроме как модификатор изменить, тогда массив не пойдёт уже) Но на кейсы можно будет переделать, когда потребуется. Сейчас действительно через массив сделаю И ещё вопрос по теме дипломатии: Где проверка можно ли сдаться стоит? Хочу сделать при наличии навыка дипломатии - возможность сдаваться мобам. С ценой 30-20-10%. В зависимости от левела навыка... |
|
|
![]()
Сообщение
#157
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз ![]() |
Можно так:
Код float armyModificator[4] = {1.00, 1.10, 1.15, 20.00}; return ( (diplomacyLevel >= 0) && (diplomacyLevel <= 3) ? armyModificator[diplomacyLevel] : ERROR_CODE ); Хотя у нас char, тогда ещё проще: Код float armyModificator[4] = {1.00, 1.10, 1.15, 20.00};
return ( diplomacyLevel < 4 ? armyModificator[diplomacyLevel] : ERROR_CODE ); |
|
|
![]()
Сообщение
#158
|
|
![]() God Сообщений: 267 Спасибо сказали: 25 раз ![]() |
Можно так: Код float armyModificator[4] = {1.00, 1.10, 1.15, 20.00}; return ( (diplomacyLevel >= 0) && (diplomacyLevel <= 3) ? armyModificator[diplomacyLevel] : ERROR_CODE ); Хотя у нас char, тогда ещё проще: Код float armyModificator[4] = {1.00, 1.10, 1.15, 20.00}; return ( diplomacyLevel < 4 ? armyModificator[diplomacyLevel] : ERROR_CODE ); Да, так вообще кратко вышло) хз есть ли эксепшины тут, но на эррор код - ругается. Вставил еденицу И кстати да, Diplomacy верно, а не Diplomaty, спасибо, позаменял в коде) И я ещё забыл разбивку по пакам сделать. Пока что при "равной" силе, с модификатором х20, когда нападаешь делит на 7 пачек. Думаю дето в этой функе это логика sub_004A68D0. Поковыряю, отпишусь, если найду |
|
|
![]()
Сообщение
#159
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз ![]() |
Цитата И кстати да, Diplomacy верно, а не Diplomaty, спасибо, позаменял в коде) Это я инстинктивно исправил. Но если идти дальше, то правильно armyModifier ![]() Цитата И я ещё забыл разбивку по пакам сделать. Пока что при "равной" силе, с модификатором х20, когда нападаешь делит на 7 пачек. Тот же LoHook, но на "альфу". Когда игра разбивает нейтралов на стеки, роляет только "альфа". |
|
|
![]()
Сообщение
#160
|
|
![]() God Сообщений: 267 Спасибо сказали: 25 раз ![]() |
Цитата И я ещё забыл разбивку по пакам сделать. Пока что при "равной" силе, с модификатором х20, когда нападаешь делит на 7 пачек. Тот же LoHook, но на "альфу". Когда игра разбивает нейтралов на стеки, роляет только "альфа". 0x4AC35E 0x4AC361 0x427662 0x427664 0x4A6B00 0x4AC34F Для каждого из этих адрессов, пробовал вызывать LoHook. Как для "setArmyValue" так и для "setArmyValuePreview" Т.е. _PI->WriteLoHook(0x4AC35E, setArmyValue); не работает, пробую это: _PI->WriteLoHook(0x4AC35E, setArmyValuePreview); В общем не завелось не для какого адресса. Всегда 7 пачек. Какой адрес правильный? |
|
|
![]() ![]() |
Текстовая версия | Сейчас: 3 October 2025 - 17:45 |
Copyright by Алексей Крючков
![]() Programming by Degtyarev Dmitry |
|