Здравствуйте, гость ( Вход | Регистрация )
![]() ![]() |
26 Jan 2017, 00:15
(Сообщение отредактировал igrik - 26 Jan 2017, 00:21)
Сообщение
#521
|
|
![]() Immortal Сообщений: 589 Спасибо сказали: 891 раз |
И ф-я sub_004A7A50 находится.. чёт не так делаю? Ну нажми ты "Tab" или "F5" в конце концов. И да, ошибся я. Школа войны это функция sub_004A76B0. 109 это водяное колесо. Код case 107:
sub_004A76B0((void *)v6, (int)Hero, v5, SBYTE4(PosMixed)); return; case 108: sub_004A78A0(Hero, (void *)v5, SBYTE4(PosMixed)); return; case 109: sub_004A7A50((int)Hero, (void *)v5, SBYTE4(PosMixed)); return; case 110: sub_004A7B10((void *)v6, (int)Hero, v5, SBYTE4(PosMixed)); return; case 112: sub_004A7C30((int)Hero, (void *)v5, SBYTE4(PosMixed)); -------------------- |
|
|
|
26 Jan 2017, 00:50
(Сообщение отредактировал AlexSpl - 26 Jan 2017, 00:43)
Сообщение
#522
|
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз |
Код //_int_ cost_wood; //+148 0x94 //_int_ cost_mercury; //+152 0x98 //_int_ cost_ore; //+156 0x9C //_int_ cost_sulfur; //+160 0xA0 //_int_ cost_crystal; //+164 0xA4 //_int_ cost_jems; //+168 0xA8 Такой вопрос. Понятно, что в бою вышеприведённые поля структуры _CreatureInfo_ стека не используются (перед боем, я полагаю, они просто копируются в _BattleStack_). А после боя? Копируются ли они обратно? Если нет, то у нас есть целых 6 полей, которые можно использовать для своих нужд. На тот же "щит здоровья". Тогда реализация "щита здоровья" была бы элементарной (без визуальной части, естественно). Хук на хил. При соблюдении определённых условий (уровень First Aid и т.п.) пишем хп щита в одно из этих полей. Далее, второй хук на получение урона (или несколько, если дамаг в нескольких местах учитывается). Там просто вычитаем дамаг из щита. Единственное, нужна визуализация, иначе получится, что отряд ударили, а он не потерял HP. Нужно хотя бы в логе писать типа "%d hit points absorbed by Divine Shield" |
|
|
|
26 Jan 2017, 01:00
(Сообщение отредактировал DedMorozzz - 26 Jan 2017, 01:01)
Сообщение
#523
|
|
![]() God Сообщений: 267 Спасибо сказали: 25 раз |
Не понятно ток как можно будет понять что на юните висит щит. И сколько он поглотит урона. Эти же хар-ки не пишутся в стеке юнита
Хоть это и не самая большая проблема, если в логе это отображать |
|
|
|
26 Jan 2017, 01:11
Сообщение
#524
|
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз |
Можно в окне информации об отряде в скобках отображать (рядом с текущими хитами, например).
Код палатки: Код int __stdcall setFirstAidShield(LoHook* h, HookContext* c) { *(int*)(c->esi + 0x94) += hpShieldBonus; return EXEC_DEFAULT; } Код на дамаг посложнее будет. Ещё при инициализации стека сбрасывать древесину на 0 |
|
|
|
26 Jan 2017, 01:11
(Сообщение отредактировал DedMorozzz - 26 Jan 2017, 01:16)
Сообщение
#525
|
|
![]() God Сообщений: 267 Спасибо сказали: 25 раз |
т.е. там строка а не число?
но в целом ок идея. По аналогии с макс хп, когда в скобках пишется текущее хп, после яда или старения Да.. вполне информативно должно получится. Но для начала надо будет проверить как вообще этот щит сделать. Вывод информации это уже самый последний этап PS: код на дамаг, по сути то же самое. ток в начале добавися такой код: 1. получить значение щита 2. сравнить что больше щит или урон 2.1 если урон то из урона вычесть значение щита. Щит обнулить 2.2 если щит, то из щита вычесть значение урона. Значение урона сделать = 1 2.3 если одинаково, то обнулить щит и урон сделать = 1 урон = 1 для того что бы была анимация получения урона и избежать возможных проблем слогикой |
|
|
|
26 Jan 2017, 01:16
Сообщение
#526
|
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз |
Попробуйте сначала этот хук. Посмотрите, не появилась ли у отряда стоимость в древесине после боя. Если нет, всё ОК, и можно продолжать
|
|
|
|
26 Jan 2017, 01:23
Сообщение
#527
|
|
![]() God Сообщений: 267 Спасибо сказали: 25 раз |
Попробуйте сначала этот хук. Посмотрите, не появилась ли у отряда стоимость в древесине после боя. Если нет, всё ОК, и можно продолжать Проверил, хил на ангеле отработал. После боя никаких изменений не увидел Пробовал этот код: Код int __stdcall setFirstAidShield(LoHook* h, HookContext* c) { *(int*)(c->esi + 0x94) += 50; return EXEC_DEFAULT; } Хук на этот адрес: Код _PI->WriteLoHook(0x478552, setFirstAidShield);
|
|
|
|
26 Jan 2017, 01:43
(Сообщение отредактировал AlexSpl - 26 Jan 2017, 01:45)
Сообщение
#528
|
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз |
Значит, всё ОК. Юнитов, которые требуют дерево, нет. Даже если бы и были, можно сбрасывать стоимость на 0, но это уже второстепенно. Теперь ставьте брейкпоинт с предыдущей страницы и ловите урон.
Короче, вот: sub_443DB0. Хук на 443DBBh. c->ecx - урон, c->esi - указатель на стек. Осталось только Ваш алгоритм реализовать Цитата 1. получить значение щита 2. сравнить что больше щит или урон 2.1 если урон то из урона вычесть значение щита. Щит обнулить 2.2 если щит, то из щита вычесть значение урона. Значение урона сделать = 1 2.3 если одинаково, то обнулить щит и урон сделать = 1 урон = 1 для того что бы была анимация получения урона и избежать возможных проблем слогикой Это милишный урон, если есть разница. Но если есть, для тестов попробуйте пока это: Код int __stdcall absorbDamage(LoHook* h, HookContext* c)
{ // code here return EXEC_DEFAULT; } |
|
|
|
26 Jan 2017, 02:04
(Сообщение отредактировал AlexSpl - 26 Jan 2017, 02:19)
Сообщение
#529
|
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз |
Ну и сразу мысли наперёд:
1. Нужно исключить abuse палатки. Она будет добавлять щит, пока у отряда есть потерянные HP, причём даже тогда, когда щит уже висит. Посему нужно исключить повторное наложение щита в предыдущем хуке (оставить только лечение, если щит > 0). 2. Аккуратно с этим: Цитата урон = 1 для того что бы была анимация получения урона и избежать возможных проблем слогикой Эта единица должна отниматься и от текущих хп. Т.е. если щит толще, чем урон, урон отнимается от щита, а 1-ца - от текущих хитов отряда. Код if ( c->ecx <= *(int*)(c->esi + 0x94) ) {
*(int*)(c->esi + 0x94) -= c->ecx; c->ecx = 1; }; else { c->ecx -= *(int*)(c->esi + 0x94); *(int*)(c->esi + 0x94) = 0; } |
|
|
|
26 Jan 2017, 23:15
(Сообщение отредактировал DedMorozzz - 26 Jan 2017, 23:22)
Сообщение
#530
|
|
![]() God Сообщений: 267 Спасибо сказали: 25 раз |
Круто, работает!
Терь надо силу щита менять в зависимости от левела юнитов. Что бы на 1е левела щит кидало слабее, на топ левела сильнее Пока что думаю так 25*левел = щит Какие нить гнолы получаю 25 абсорба. Ангел - 175 Нашел такую штуку - _int32_ creature_id; // +52 0x34 // тип монстра Но это скорее всего айди юнита, аля гарпия, гнол, ифрит... А как левел отряда получить? Потенциально можно самому таблицу составить по ЕРМ хелперу, чёт думается можно и проще И да.. как менять описание? Что бы к текущему хп добавить в скобках(в идеале квадратных []) размер щита? Понравилась эта идея) PS: а насчёта абуза, то я думаю щит не прибавлять, а всегда делать новый. И хоть 100 раз на юнита кастануть щит, он больше не поглотит |
|
|
|
26 Jan 2017, 23:41
(Сообщение отредактировал DedMorozzz - 26 Jan 2017, 23:42)
Сообщение
#531
|
|
![]() God Сообщений: 267 Спасибо сказали: 25 раз |
---------------------------------------------
Придумал как. Юниты идут по порядку. Сперва замок, далее оплот и так далее Взять айди юнита и разделить на 14 и взять целую часть. Далее умножаем 14 на эту целую часть и это число вычитаем из айди отряда добавив еденицу. Еденица нужна т.к. начинается отсчёт с 0 Пример. айди = 16. Это гном 16 делим на 14 получаем 1+ Далее 16+1 - 14 = 3 Значит это 3й юнит по списку. Далее делю ещё раз на 2 (улучшеных и не улучшеных что бы пропустить) и округляю в большую сторону - это и есть левел отряда в данном случа 3/2 = 1+. После округления = 2 Это конечно не будет работать как надо со спец юнитами, ну и чёрт с ними) |
|
|
|
26 Jan 2017, 23:42
(Сообщение отредактировал AlexSpl - 26 Jan 2017, 23:43)
Сообщение
#532
|
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз |
Цитата А как левел отряда получить? Потенциально можно самому таблицу составить по ЕРМ хелперу, чёт думается можно и проще Код //_int_ level; //+120 0x78 *(int*)(c->esi + 0x78). Цитата И да.. как менять описание? Что бы к текущему хп добавить в скобках(в идеале квадратных []) размер щита? Понравилась эта идея) Тут брейкпоинт на чтение нужно ставить на потерянные HP (cmAddr + 21708 + 88). Цитата PS: а насчёта абуза, то я думаю щит не прибавлять, а всегда делать новый. И хоть 100 раз на юнита кастануть щит, он больше не поглотит Да. Наверное, это оптимальное решение. |
|
|
|
27 Jan 2017, 00:15
(Сообщение отредактировал AlexSpl - 27 Jan 2017, 00:45)
Сообщение
#533
|
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз |
По поводу отображения щита. Хук на 5F64AFh. Для начала проверьте, будет ли работать такой код:
Код { sprintf((char*)0x697428, "%d [%d]", *(int*)(c->ebp + 8), *(int*)(c->ebp + 8)); c->return_address = 0x5F64C2; return NO_EXEC_DEFAULT; } Должен отображать остаток здоровья. Например, 300 [300]. Адрес щита из combatManager получить можно. * * * Ага, мы же можем кликнуть правой кнопкой на любой отряд. Тогда адрес отряда лучше из стека забирать: Код {
int unitAddr = *(int*)(c->ebp - 0x20); sprintf( (char*)0x697428, "%d [%d]", *(int*)(c->ebp + 8), *(int*)(unitAddr + 0x94) ); c->return_address = 0x5F64C2; return NO_EXEC_DEFAULT; } |
|
|
|
27 Jan 2017, 00:51
(Сообщение отредактировал AlexSpl - 27 Jan 2017, 00:59)
Сообщение
#534
|
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз |
Можно сделать, чтобы когда щита нет, здоровье отображалось, как обычно:
Код {
int unitAddr = *(int*)(c->ebp - 0x20); // получаем адрес отряда, чьё информационное окно смотрим int hpShieldValue = *(int*)(unitAddr + 0x94); // получаем значение щита if ( hpShieldValue > 0 ) { sprintf( (char*)0x697428, "%d [%d]", *(int*)(c->ebp + 8), hpShieldValue ); // отображаем остаток_здоровья [щит] }; else return EXEC_DEFAULT; // отображаем по умолчанию: остаток_здоровья c->return_address = 0x5F64C2; return NO_EXEC_DEFAULT; } |
|
|
|
27 Jan 2017, 01:13
Сообщение
#535
|
|
![]() God Сообщений: 267 Спасибо сказали: 25 раз |
Цитата 1>.\dllmain.cpp(578) : error C3861: 'sprintf': identifier not found такая штука. Как я понял разные форматы в вижуал студии юзаются. Пробую плфиксать |
|
|
|
27 Jan 2017, 01:18
Сообщение
#536
|
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз |
Попробуйте добавить инклуд #include "stdafx.h"
|
|
|
|
27 Jan 2017, 01:24
(Сообщение отредактировал DedMorozzz - 27 Jan 2017, 01:27)
Сообщение
#537
|
|
![]() God Сообщений: 267 Спасибо сказали: 25 раз |
то же самое
Не хватало - #include <stdio.h> PS: но вылетет при просмотре юнита после хила |
|
|
|
27 Jan 2017, 01:30
Сообщение
#538
|
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз |
A если sprintf закомментить?
|
|
|
|
27 Jan 2017, 01:33
Сообщение
#539
|
|
![]() God Сообщений: 267 Спасибо сказали: 25 раз |
всё равно вылетает.
Попробова задать hpShieldValue = 10. Вылетет тоже. Походу из-за c->return_address = 0x5F64C2; |
|
|
|
27 Jan 2017, 01:52
Сообщение
#540
|
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз |
Я на SoD смотрел. Счас HotA гляну.
А так вылетает? Код {
int unitAddr = *(int*)(c->ebp - 0x20); // получаем адрес отряда, чьё информационное окно смотрим int hpShieldValue = *(int*)(unitAddr + 0x94); // получаем значение щита sprintf( (char*)0x697428, "%d", *(int*)(c->ebp + 8) ); c->return_address = 0x5F64C2; return NO_EXEC_DEFAULT; } |
|
|
|
![]() ![]() |
| Текстовая версия | Сейчас: 13 November 2025 - 15:39 |
|
Copyright by Алексей Крючков
Programming by Degtyarev Dmitry |
|