Wake of Gods Forum | Форум Во Имя Богов
Исследование героев - Printable Version

+- Wake of Gods Forum | Форум Во Имя Богов (http://wforum.heroes35.net)
+-- Forum: Герои Меча и Магии 3.5 WoG/ERA (/forumdisplay.php?fid=99)
+--- Forum: Библиотека по моддингу (/forumdisplay.php?fid=186)
+--- Thread: Исследование героев (/showthread.php?tid=862)


Исследование героев - Дьякон - 27.10.2009 21:49

http://wog.nxt.ru/diakon/tutorial_1.html

Задаем вопросы.


RE: Исследование героев - Дьякон - 27.10.2009 22:24

инструмент к туториалу от Корвина ))
http://letitbit.net/download/0532.c028e3281ecbead9ab5c2ad32/Tutor.rar.html


RE: Исследование героев - SAG - 26.11.2009 13:52

очень полезно! ждем примеров динамического патчинга, желательно под Era. В примерах под Era кажется было что то похожее, однако, чем больше примеров тем понятнее!


RE: Исследование героев - NIKr0m@nceR - 12.12.2009 17:13

ссылка на летитбит не канает


RE: Исследование героев - Дьякон - 26.12.2009 16:39

По просьбе трудящихся, небольшой туториал по подгрузке длл в процесс:

http://wog.nxt.ru/diakon/patchexe.rar (размер 364 кб)

Патч в архиве только для ЕХЕ героев (жестко прошит адрес LoadLibrary в таблице импорта). Подправлю выложу, для любого ехе, если кому-то понадобится


RE: Исследование героев - MOP - 05.02.2010 15:34

(27.10.2009 22:24)Дьякон Wrote:  инструмент к туториалу от Корвина ))
http://letitbit.net/download/0532.c028e3281ecbead9ab5c2ad32/Tutor.rar.html
Ссылка сдохла.


RE: Исследование героев - Дьякон - 06.02.2010 00:43

Инструменты можно в инете свободно найти


RE: Исследование героев - MOP - 07.02.2010 10:07

Знаю. Просто интернетного времени у меня очень мало, чтобы быстро всё сразу найти.
Ладно, как-нибудь найду...


RE: Исследование героев - ZURG - 07.02.2010 10:55

Ida pro есть на torrents.ru. OllyDbg на cracklab.ru и wasm.ru


RE: Исследование героев - etoprostoya - 07.02.2010 10:58

Кстати, вот ИДА Про http://forum.df2.ru/index.php?showtopic=933&pid=376276&st=80&#entry376276


RE: Исследование героев - MOP - 07.02.2010 12:57

Спасибо за помощь! Sm
Только ИДА огромна... не ожидал. Траффик (тем более не мой) скачать пока не позволяет.


RE: Исследование героев - etoprostoya - 07.02.2010 13:14

В ИДА включена поддержка множества различных редких платформ, потому и огромна.


RE: Исследование героев - Дьякон - 07.02.2010 20:37

MOP для начала вполне хватит Оли. Там в принципе все что нужно. Иду конечно тоже не плохо иметь. Но думаю тебе и Оли хватит пока. Тем более если ты все через артмани находишь )))))


RE: Исследование героев - feanor - 08.02.2010 01:14

http://cbn.narod.ru/arm.html

Сильно обкорнанная ида допотопной версии Sm
wintel вроде не урезали, впрочем.


RE: Исследование героев - etoprostoya - 08.02.2010 01:17

(08.02.2010 01:14)feanor Wrote:  http://cbn.narod.ru/arm.html

Сильно обкорнанная ида допотопной версии Sm
wintel вроде не урезали, впрочем.

Там написано, что это для АРМ. Уверен что там х86 есть?


RE: Исследование героев - feanor - 08.02.2010 01:47

PE-шники открывает и дизасм вроде показывает. Хотя да, я её в основном для ARM юзал.


RE: Исследование героев - MOP - 11.02.2010 14:17

(07.02.2010 20:37)Дьякон Wrote:  Иду конечно тоже не плохо иметь. Но думаю тебе и Оли хватит пока.
Отвечая в столь же романтическом ключе: эту девушку я снял. Поизвращаемся, если она согласна. 148 Тем более, есть несколько вполне чётких целей...


RE: Исследование героев - SAG - 20.02.2010 23:48

создал dll позволяющую расширить список стартовых героев за счет добавления героев из кампаний. Пока добавляются Мюллих и Катерина и банятся Сильвия и Саня. Потом доделаю, чтобы список динамически расширялся.
Большое спасибо Сергею Роженко, ASM, Дьякон, Берсеркер за большую помощь в создании этой dll.
Скачать можно здесь: http://www.heroes-iii.com/files/sag_dll_v1.zip


RE: Исследование героев - Berserker - 21.02.2010 00:33

SAG, для паблика более интересен адрес массива с героями и принцип.


RE: Исследование героев - SAG - 23.02.2010 17:05

массив по адресу $699538)^+$4DF18
исходники (меняются Оррин Валеска) http://collabedit.com/display?id=15964


RE: Исследование героев - feanor - 23.02.2010 21:26

Благодарю!


RE: Исследование героев - GhostManSD - 01.09.2010 11:57

После того, как увидел то, что можно творить через !!UN:C, очень хочется научиться творить такое самому. В наличии имеются Ida Pro, MASM, Asm_Ed, CodeView, Hiew, OllyDbg, Peid, QuickUnpack. Есть, как видите, многое, но навыка - ноль. Подскажите, пожалуйста, полезную литературу по данному вопросу, поскольку здесь я - даже больший нуб, чем в ERM.
Через АртМани, а потом !!UN:C уже умею менять кое-какие тексты и данные (спасибо огромное MOP'у и gamecreator'у за ценные советы). Однако этого явно недостаточно. Хочется иметь куда большие возможности. В частности, интересует методика создания новых триггеров.


RE: Исследование героев - Sav - 01.09.2010 12:45

Quote:В частности, интересует методика создания новых
триггеров.
Мне тоже это очень хотелось бы знать. Там вроде надо что-то менять в коде, но как найти, где и понять на что?


RE: Исследование героев - GhostManSD - 01.09.2010 12:53

Насколько я понял из исходника dll для Эры, который мне предоставил MOP, отлавливается адрес и при обращении к этому адресу выполняются нужные действия.


RE: Исследование героев - Berserker - 01.09.2010 15:04

Так и есть. Достаточно выучить азы ассемблера. Руководства можно найти на wasm.ru, как и весь нужный интрументарий.
Суть создания "нового триггера" в Эре - это в нужном месте кода героев/вога:
  • Прописать прыжок на свою функцию
  • Сохранить контекст исполнения
  • Сохранить параметры нового события, чтобы их можно было достать через SN:X
  • Вызвать функцию вога: CallFunc с номером функции
  • Вызов приведёт к вызову функции ЕРМ и т.д.
  • Восстановить контекст исполнения (регистры, флаги, чаще всего только регистры через POPAD)
  • Выполнить код героев/вог, затёртый нашим перехватчиком
  • Совершить прыжок на продолжение кода



RE: Исследование героев - MOP - 01.09.2010 15:15

*Чувствует себя змеем-искусителем*

Вот длл с более подробным (откомментированным) исходником. Создаёт триггер на лечение Палаткой.
Константы взяты из исходников ЭРЫ, ибо так удобнее. Авторская процедура - HOOK_tent.
Как пользоваться триггером - написано здесь.


RE: Исследование героев - GhostManSD - 01.09.2010 15:38

Bers, огромное спасибо! А как это же через !!UN:C?


RE: Исследование героев - MOP - 01.09.2010 16:04

Научил плохому...
Через UN:C это фактически и не делается. Просто я для тех, у кого даже ЭРА не стоит, делаю новые события с помощью записи командой UN:C в неиспользуемые игрой участки памяти того же самого ассемблерного кода. Вот те два события (пост-HL и вход в экран города) я записал, кажется, в неиспользуемую после загрузки exe сод-таблицу Трансформатора Скелетов.
Ответ: учить асм, больше никак.


RE: Исследование героев - Berserker - 01.09.2010 16:38

MOP, спасибо за пример. Довольно чётко. Разве что "PTR DS:" лишние...


RE: Исследование героев - GhostManSD - 01.09.2010 17:06

Через dll даже лучше. Но здесь нужны доп. программы. Я пытался скомпилировать исходник MOP'а, заменив номера функций, но мои Турбо и Визуал Паскали выдали ошибку: ТП - что пропущен бегин, ВП -что нет файла win.vpi (ошибка 15). Может, надо через что-то еще? Хотя для файла с расширением pas что еще может быть...


RE: Исследование героев - Berserker - 01.09.2010 17:22

GhostManSD, Virtual Pascal из папки Эры запускал?
/попробуй команду Make вместо Compile.


RE: Исследование героев - MOP - 01.09.2010 18:20

(01.09.2010 16:38)Berserker Wrote:  MOP, спасибо за пример. Довольно чётко. Разве что "PTR DS:" лишние...
Учту. Я просто скопировал комментарий из исходника к бинарнику. Себе-то длл-ок пока не делаю - для этого мне нужна какая-то... глобальная задумка, что ли (как для тебя - ЭРА). А пока всё в exe...


RE: Исследование героев - Sav - 01.09.2010 18:29

(01.09.2010 15:04)Berserker Wrote:  Суть создания "нового триггера" в Эре - это в нужном месте кода героев/вога:
...

Как можно найти это нужное место?


RE: Исследование героев - MOP - 01.09.2010 18:29

А вот это самое сложное и трудозатратное...
Пример есть в туториале Дьякона. Игра по ходу выполнения кода обращается к ресурсам - картинкам, дефам, звукам, текстам. Поставив брейкпойнт на указатель к этому ресурсу, находим примерный интересующий нас участок кода и рассматриваем его. Я, например, вышел к лечению Палаткой через указатель на звук regener.wav.
Но далеко не всегда так просто. Порой надо обладать чутьём, представлять, в каком виде могут храниться данные. Почти интуиция.


RE: Исследование героев - Sav - 01.09.2010 18:38

MOP Wrote:... в туториале Дьякона
Это который должен быть по ссылке в первом посте темы? Ссылка не работает.


RE: Исследование героев - feanor - 01.09.2010 18:38

Не портите нервы связкой паскаля и асма, припудренной милыми досовскими средами.
Портите нервы связкой С и асма.
Quote:Как можно найти это нужное место?
Тут надо предметно смотреть - в каждом конкретном случае вопрос особый.
На палатку я бы выходил через давно записанный на бумажке адрес свитча на действия юнитов в бою. Этот свитч я нашел через функцию каста заклинаний. А её я нашел, кажется, через функцию проигрывания звука.


RE: Исследование героев - gamecreator - 01.09.2010 19:23

MOP, а если в том неиспользуемом участке патч какой-то записался? получится каша.


RE: Исследование героев - MOP - 01.09.2010 19:30

+ ещё одна причина делать это по-человечески, а не UN:C.
Но не буду же я объяснять простому человеку, как поставить ЭРУ или прилепить длл к экзешнику.


RE: Исследование героев - Berserker - 01.09.2010 19:30

Quote:Портите нервы связкой С и асма.
Ничем не лучше, если не считать, что из-за крайней низкоуровневости, что-то большое писать без ошибок нереально. По поводу среды - использую Delphi, но не его IDE, а notepad++. Писать можно в чём нравится и как нравится, а компилировать хоть через командную строку. И как сказал ZVS на ag.ru, это не досовское окно, а полноценное win-32 приложение.

Quote:брейкпойнт
Перевожу: точка останова.

Quote:свитча
Перевожу: разветвление/переключатель (серия подряд идущих если..то).


RE: Исследование героев - feanor - 01.09.2010 19:58

Quote:Перевожу: точка останова.
Кстати, о бряках.
В той же оле есть три вида бряков: Int3, Memory и Hardware.

Первый ставится на код и срабатывает, что характерно, при проходе про коду.
Второй ставится на память и срабатывает при чтении\записи в память.
Третий может ставиться и на код, и на память, но имеет ряд ограничений - типа, только четыре бряка такого типа, брячится только до четырех байт (и то, зависит от фактического адреса).

Дык вот..для бряков на код лучше использовать первые.
А вот для бряков на память - третьи, несмотря на все их ограничения.


RE: Исследование героев - Berserker - 01.09.2010 20:11

Аппаратные точки останова обрабатывает процессор (регистры Dr0-Dr3). А Olly реализует это дело через VirtualProtect с нулевыми правами на всю страницу памяти и перехват-обработку исключений. Если доступ к странице нужен редко, то в принципе, терпимо, если постоянно, то тормоза будут существенные.


RE: Исследование героев - GhostManSD - 01.09.2010 20:27

О Боже... Х_Х


RE: Исследование героев - feanor - 01.09.2010 20:32

Quote:если постоянно, то тормоза будут существенные.
если обращения чаще, чем примерно раз в секунду - герои нафиг повисают. Приходится ставить-снимать паузу.
Так что, скажем, изменялку параметров героя с меморибряками выявить удастся только при достаточном терпении.
Quote:О Боже... Х_Х
ась? Все оказалось несколько сложнее, чем представлялось?)
Дык на самом деле все сложнее, чем на самом деле.


RE: Исследование героев - Berserker - 01.09.2010 21:22

Quote:О Боже... Х_Х
Я бы начал с обычного: wasm.ru Введение в крекинг с нуля. Хотя может МОР что посоветует, он вроде как обходился без азов программирования.


RE: Исследование героев - Berserker - 01.09.2010 21:45

Quote:или чистотой языка
В отличие от жаргона корректный литературный перевод уже несёт 90% смысла даже для человека непосвящённого. В СССР было понятие АВОСТ - аварийного останова. Это самый нормальный перевод для halt, например. Тоже самое и с breakpoint. Это и есть точка останова программы. И человек сразу вникает в суть дела. А жаргон используют все, но не везде же и среди тех, кто понимает.

feanor, по твоему уже удалённому посту. 6[a] в си тоже массив, как и 256[a]{b} и т.д. Но это не полноценный массив с двумя/более измерениями, а просто синтаксический сахар для вычисления адреса (собственно, нельзя создать тип-многомерный массив, массив можно использовать как переменную или одномерный и никакого контроля над границами тоже нет). Касаемо передачи параметра для изменения, это был не юмор. Введённая в Алголе60 конструкция VAR означает, что внутри функции работа с переменной/массивом/структурой вполне прозрачна, но реально компилятор имеет дело со ссылкой. Тем не менее проверка типов остаётся жёсткой. В СИ нет возможности передать аргумент для изменения иначе как использованием низкоуровневого средства ссылки. Именно поэтому, несмотря на тотальную популярность СИ-семейства, я бы не советовал людям формировать своё мировоззрение в сфере программирования, начиная с языка, чей основой является близость к ассемблеру и минимальная типизация. И тем более, если нужно что-то реализовать, а навыков нет. И конечно же, не посоветовал начинать с монстров класса СИ++, Ада, на прочтение одной лишь спецификации по которым уйдёт пол жизни, а остальная половина на знакомство с особенностями компиляторов.

P.S В посте была ошибка. Передача аргумента в качестве изменяемой переменной, а не по значению.


RE: Исследование героев - MOP - 01.09.2010 21:57

(01.09.2010 21:22)Berserker Wrote:  Хотя может МОР что посоветует, он вроде как обходился без азов программирования.
Ну... что я делал без азов программирования? Баловался с Артмани и только. Правда, мне удалось увеличить кол-во монстров и артефактов, но ведь это и не требовало знаний асма. Просто перенаправление указателей, перенесение таблиц и увеличение максимального кол-ва по некоторым адресам. Что к чему лежит и что представляют собой циферки в окошке АртМани - оставалось тёмным лесом.
А первое, что я сделал в Olly - отключил Маскировку и передал контроль её колдовства ERM-функции. Просто подсмотрел, как такое проделал Феанор с книжкой колдовства Сказочного Дракона. На тот момент единственной мне понятной командой асма была jmp.


RE: Исследование героев - gamecreator - 01.09.2010 22:00

(01.09.2010 21:45)Berserker Wrote:  на прочтение одной лишь спецификации по которым уйдёт пол жизни
а можно мне эту спецификацию? хоть раз в жизни почитаю.


RE: Исследование героев - Berserker - 01.09.2010 22:06

Страуструп "Язык программирования C++"
Стандарты СИ 89, 99



RE: Исследование героев - GhostManSD - 01.09.2010 22:13

(01.09.2010 21:22)Berserker Wrote:  
Quote:О Боже... Х_Х
Я бы начал с обычного: wasm.ru Введение в крекинг с нуля. Хотя может МОР что посоветует, он вроде как обходился без азов программирования.

Bers, самое интересное, что я с этого и начал. Ab Нравится, хорошее руководство, и впрямь для чайников. А то с Калашниковым как-то не пошло...


RE: Исследование героев - Berserker - 01.09.2010 22:18

Я в своё время Калашникова прочитал, только тольку-то? ДОС уже мёртв, как и 16-битный режим. Фактически, под винду совсем другой ассемблер. Ещё можно глянуть туториалы Изелона. Там, правда, основной упор на WinApi, это чуть позже.


RE: Исследование героев - MOP - 01.09.2010 22:27

У меня тоже Калашников есть. Sm Тоже читал... засыпая над одной и той же главой. То есть, обучение получилось чисто практическое - OllyDbg + справка по командам ассемблера.


RE: Исследование героев - feanor - 01.09.2010 22:37

Собственно, для реверсинженеринга нужен именно язык с близостью к ассемблеру и минимальной типизацией. Паскалевские указатели наводят на меня тоску, необходимость явного приведения типов чуть ли не при перегоне из символа в число - напрягает.
___________________
Я реверсинженерингом Героев занялся после успешной сдачи экзамена по АЭВМ (ну то бишь по основам ассемблера).
До этого правда был небольшой опыт ковыряния дампов мобильников
(брр..отсутствие толковых отладчиков, любая ошибка в коде роняет все к чертям собачьим, никакая плавающая арифметика - короче, адЪ кромешный)
, но ARM таки несколько отличается от x86 :D


RE: Исследование героев - gamecreator - 01.09.2010 22:43

(01.09.2010 22:06)Berserker Wrote:  Страуструп "Язык программирования C++"
Стандарты СИ 89, 99
и что там такого страшного?



RE: Исследование героев - Berserker - 01.09.2010 22:51

Quote:Собственно, для реверсинженеринга нужен

   Для обратного инжиниринга нужен отладчкик и/или дизассемблер. А вот писать плагины и серьёзные вещи нужно как раз-таки на безопасных языках. Ассемблер в паскале толковый, приведение типов нужно редко (и уж точно не для перевода символ-код для которых везде есть функции ord/chr), а когда нужно - делается осознанно и остаётся при этом низкоуровневым. Символ ^ - дело привычки. Выглядит не элегантно, но не так ужасно, как, простите, уродливая перегрузка математического оператора "*" или СИ++ вариант перегрузки СИ++ операции И "&". Впрочем, ко всему привыкаешь, я синтаксиса специально не касался.
   Тот, кто пишет часто на динамических языках, понимает, насколько сильно важна строгая типизация для создания хоть сколько-нибудь надёжных систем. Мой опыт программирования на PHP и JavaScript твердит, что даже эмуляция типизации позволяет словить орду ошибок ещё на ранних стадиях выполнения. Иначе мы имеем дело с уже известным законом, что написание кода отнимает 10% времени, отладка 90% + никакой гарантии, что код корректен или в будущем не обвалится.
   В общем всё это субъективный опыт, так что лучше вернёмся к предмету темы.
Добавлено:
Quote:и что там такого страшного?
Ничего, кроме over 1100 страниц текста + бесконечного упоминания, что реализация той или иной фичи зависит от компилятора.



RE: Исследование героев - GhostManSD - 01.09.2010 22:54

Как-то содержание темы немного стало выходить за пределы "Героев". Ab


RE: Исследование героев - GhostManSD - 02.09.2010 01:19

Пфф, прочитал и почти полностью осилил первые 4 статьи из "Введения в крэкинг с нуля". На сегодня хорош, а завтра повторим.



RE: Исследование героев - GhostManSD - 02.09.2010 11:44

Сразу большая просьба к тем, кто давно этим занимается: было бы, наверное, неплохо составить список адресов - какой адрес за что отвечает. И отправить этот список, например, в первый пост. Первое, что привожу на данную тему, - адрес, найденный Сергроем:

0x4DAF06 - после повышения уровня любого героя


RE: Исследование героев - feanor - 02.09.2010 12:30

http://forum.df2.ru/index.php?showtopic=6803


RE: Исследование героев - GhostManSD - 04.09.2010 10:53

Камрады, пожалуйста, подскажите, какой адресок отвечает за активацию/деактивацию кнопки "Журнал" на карте приключений. Или, что тоже неплохо, подскажите способ поиска этого адреса. Искать пробовал так: ставил герою 999 копейщиков, ставил штук 20 стражей прохода с требованием принести 1 копейщика и, подходя к очередному стражу, отдавал или не отдавал копейщика. В артмани искал неизвестное значение, и, в зависимости от отдачи или невыдачи копейщика и изменения кнопки "Журнал" (всегда старался, чтобы в журнале было максимум одно задание), нажимал "Отсеять -> значение изменилось/не изменилось". Не нашел. Впрочем, тут и способ дурной.


RE: Исследование героев - MOP - 04.09.2010 10:59

Простейший способ - сменить id кнопки на какой-нибудь незаюзанный:
Кнопка теперь будет иметь CM:I = 50, станет нажимаемой всегда, но утратит свою функцию и подсказки по ПКМ и наведении мыши. Но это, думаю, то, что тебе и надо.


RE: Исследование героев - GhostManSD - 04.09.2010 11:05

MOP, подскажи, пожалуйста, как ты узнал, что для этого нужен адрес 4200424(dec).


RE: Исследование героев - MOP - 04.09.2010 11:08

Попросту вбил "iam004" (деф кнопки) в поиск по дизассемблеру. Сразу пришёл к указателю. А параметры отрисовки элементов диалогов мне как бы уже знакомы - следующим параметром за дефом в функцию идёт id.

Дополнил код выше. Второй адрес - для раскраски кнопки в цвета игрока. Его я не находил - мне Бараторч подсказал.


RE: Исследование героев - GhostManSD - 04.09.2010 13:26

А если изменить указатель, изменится и деф?


RE: Исследование героев - MOP - 04.09.2010 13:27

Аха. Так, например, в TPM сделали (major, наверное).


RE: Исследование героев - GhostManSD - 04.09.2010 18:57

MOP, спасибо огромное!


RE: Исследование героев - GhostManSD - 04.09.2010 20:24

А можно вопрос от нуба? Где в OllyDbg вбивать "iam004" для поиска?


RE: Исследование героев - Berserker - 04.09.2010 20:41

Search - references to text strings - ctrl + L


RE: Исследование героев - gamecreator - 04.09.2010 22:37

в районе 0х01481680 в памяти начинается массив героев (это так, к слову).


RE: Исследование героев - feanor - 04.09.2010 23:53

Quote:в памяти начинается массив героев
Динамические адреса давать таки не гуд.
К тому же адрес этого массива структур уже известен:
[699538h] + 21620h+492h*hero_num


RE: Исследование героев - gamecreator - 05.09.2010 01:30

он статический. по крайней мере, на хл.


RE: Исследование героев - Berserker - 05.09.2010 02:32

gamecreator, он динамический по определению. У тебя неверное представление об организации памяти и структур.


RE: Исследование героев - gamecreator - 05.09.2010 10:42

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


RE: Исследование героев - GhostManSD - 05.09.2010 23:17

Как инвертировать число -1 в десятичной и получить обратное ему?


RE: Исследование героев - Sav - 05.09.2010 23:27

Инвентировать - в смысле заменить биты на противоположные? 0 будет, вроде.


RE: Исследование героев - GhostManSD - 05.09.2010 23:50

Берс, можешь объяснить суть триггеров входа в окно героя и выхода из оного?
Интересует второй из них. Можешь объяснить, что происходит в строках
Quote:PUSH General.C_ERA_EVENT_HEROSCREEN_EXIT
CALL General.GenerateCustomErmEvent
?
Добавлено:
И как выглядел бы код без обращения к General?
Добавлено:
Поясняю: нужно сделать подобное с



RE: Исследование героев - Berserker - 05.09.2010 23:54

Quote:Берс, можешь объяснить суть триггеров входа в окно героя и выхода из оного?
Тебя интересует, как это юзать в Эре или почему именно так реализовано?


RE: Исследование героев - GhostManSD - 05.09.2010 23:55

Ну, меня интересует, можно ли таким же образом состряпать функцию для кода из второго спойлера. Ab
Добавлено:
Для функции 90002.


RE: Исследование героев - Berserker - 06.09.2010 00:52

C_FUNC_ZVS_CALLFU = $74CE30; // void FUCall(int n)
Я использовал константу для адреса функции обработки события вызова ЕРМ-функции. А феанор тебе просто дал числовое значение адреса, что одно и то же.

У тебя следующие ошибки:
1) Имена экспортируемых в кавычках должны быть.
2) Функции не нужно вызывать, просто пиши ЕРМ обработчики !?FU90001; ...
3) Секция exports должна быть одна и находиться до BEGIN Hook... END.
4) В секции записи друг от друга отделяются ",", а лишь в конце ";"

Code:
EXPORTS
    HOOK_Trigger_TownEnter NAME 'Trigger_TownEnter',
    HOOK_PostTrigger_HeroLevel NAME 'PostTrigger_HeroLevel',
    HOOK_Trigger_RecruitingTroops NAME 'Trigger_RecruitingTroops';



RE: Исследование героев - GhostManSD - 06.09.2010 02:11

Bers, спасибо огромное! Всё работает!


RE: Исследование героев - GhostManSD - 06.09.2010 02:51

Подскажите, пожалуйста, вот какую штуку. Есть желание сделать триггер при найме существ. Нашел деф кнопки "нанять максимум существ", ввел в поиск по ссылкам, попал в ту часть кода, где эта кнопка создается и помещается. Теперь - главное: как выйти от момента создания кнопки в диалоговом окне к тому самому моменту, когда происходит первый запрос на создание диалогового окна?
Иными словами - как выйти на тот адрес, на который и нужно ставить ловушку?
Добавлено:
Кстати, значение адреса 0x74CE30 дал мне не feanor, а MOP, за что ему тысячу раз спасибо!


RE: Исследование героев - Berserker - 06.09.2010 11:29

Там где создаётся, открой стёк вызовов. Либо в этой же функции, либо в одной из родительских генерируется действие.


RE: Исследование героев - GhostManSD - 06.09.2010 11:44

Теперь практически обратный вопрос: адрес выхода из окна искать так же? Иными словами, искать адрес, к которому обращается игра при закрытии окна, нужно так же?

Вот есть, например, окошко найма существ. Нужно найти три адреса: один - если игрок нажал кнопку покупки и успешно купил существ, другой - если игрок нажал кнопку покупки, а купить не смог (а-ля не хватает провизии), третий - если игрок нажал кнопку отмены. Порядок действий таков (например, хотя можно наверняка и иначе):
1. Найти в ссылках деф кнопки "нанять всех".
2. Открыть стек вызовов.
3. Поставить точку останова на все вызовы и по одному отсеивать их, снимая эти точки останова, пока не найду нужные.

Я правильно понял?


RE: Исследование героев - Berserker - 06.09.2010 14:59

Не правильно. Узнать купил или не купил можно в пост триггере, сравнив армию до и после. Так что нужно делать один перехватчик вызова функции диалога найма героя. Сперва генерируешь событие открытия, затем выполняешь геройскую функцию, затем событие закрытия. После этого возвращаешь управление игре.


RE: Исследование героев - GhostManSD - 06.09.2010 15:15

А события открытия/закрытия искать в Олли в стеке вызовов? Ставя точки останова на каждом из этих адресов?
Добавлено:
И что имеется в виду под пост-триггером? !$FU%номер функции для открытия окна диалога%?


RE: Исследование героев - Berserker - 06.09.2010 15:18

GhostManSD, не могу помочь, не так много времени. Читай литературу, разбирайся сам по-тихоньку, всё ведь не всегда однозначно, чтобы 100%-ый рецепт выписать. Научившись трассировать программы по шагам, смотреть дамп и состояние переменных, легко сможешь определять то, что тебе нужно. А иначе вопросы будут постоянно.


RE: Исследование героев - feanor - 06.09.2010 18:22

Quote:третий - если игрок нажал кнопку отмены.
ищешь обработчик нажатий кнопок в диалоге. В конкретно данном случае искать легко - через бряк на 4F6C00 (показ сообщения). Кнопка с номером 30721 (дес.) - кнопка закрытия диалога.


RE: Исследование героев - GhostManSD - 06.09.2010 19:39

Номер получен путем опытов или интуитивно (кнопка ОК в CM:I - 30720)?


RE: Исследование героев - GhostManSD - 07.09.2010 03:10

Правильно ли я понял по поводу дефа той или иной кнопки, что данные располагаются в общем и целом примерно так (жирным выделена строка, к которой прихожу по поиску дефа):
Не мог бы кто-нибудь объяснить суть команд, стыдливо прикрытых знаками "???"? Я пробовал поиграться со значением, но вроде ничего не изменилось.
Осталось теперь понять, как от всего этого великолепия выйти к моменту создания самого диалога.


RE: Исследование героев - gamecreator - 07.09.2010 09:26

(07.09.2010 03:10)GhostManSD Wrote:  Не мог бы кто-нибудь объяснить суть команд, стыдливо прикрытых знаками "???"?
там может быть адрес обработчика нажатия (4 байта)


RE: Исследование героев - GhostManSD - 07.09.2010 10:49

Там вроде какие-то маленькие значения в духе 20, 40, 1, 2, etc. Некоторые интересные для меня адреса я нашел в call functions, ставя по очереди на них бряки:
1. Нажатие в окне найма "нанять" или "отмена". Действует почему-то лишь на экране города, в жилище действует лишь "отмена". Не там ищу?
2. Нажатие при заходе в жилище кнопки "ОК" при вопросе "хотите ли вы нанять...?".
3. Адрес перед высвечиванием диалога.

Нужен хук именно на кнопку "нанять".


RE: Исследование героев - GhostManSD - 07.09.2010 10:56

Причем хук на ее нажатие именно в окне жилища. В замке все равно все в гарнизон нанимается. А герою все равно уже туда не попасть. Ab


RE: Исследование героев - feanor - 07.09.2010 21:57

Quote:???
???
положение x -- вероятно, в пикселях
положение y -- вероятно, в пикселях
3 и 4 параметры - ширина и высота нажимаемой области.


RE: Исследование героев - GhostManSD - 07.09.2010 22:55

feanor, спасибо!


RE: Исследование героев - baratorch - 08.09.2010 01:36

Я обычно делаю так:
1. по названию дефа нахожу функцию создающую диалог с этой кнопкой.
2. запоминаю ID кнопки, он PUSHится прямо рядом с PUSHом имени дефа.
3. Ищу функцию обработки сообщений этого диалогового окна, ставя бряк на известную мне функцию, которая точно вызывается и з этого обработчика (например функция показа сообщения)
4. в функции обработки сообщений окна нахожу место где идет проверка на равенство ID нажатой кнопки тому который запомнил и вуаля.

Но не представляю сколько времени потребуется чтобы все это осуществить только с помощью Олли.
HexRays в ИДЕ - это моё всё.


RE: Исследование героев - gamecreator - 08.09.2010 01:57

(08.09.2010 01:36)baratorch Wrote:  Но не представляю сколько времени потребуется чтобы все это осуществить только с помощью Олли.
дилетантам типа меня или GhostManSD - около 15 минут.
Добавлено:
это, конечно, если использовать артмани для поиска текста


RE: Исследование героев - GhostManSD - 08.09.2010 02:29




RE: Исследование героев - Sav - 08.09.2010 17:21

GhostManSD Wrote:Вот ищу я славный момент, когда же у нас
запускается окошко найма существ во внешнем жилище.
Иду этим путем. И что же? Результат для точек останова
сразу на три или четыре адреса - один: при первом же
запросе к окошку срабатывает точка останова. И бес его
знает, какой из адресов мне нужен.
Если тебе надо сделать что-то, не связанное непосредственно с диалогом, наверное, подойдёт любой.
Только лучше проверять на нескольких разных жилищах.


RE: Исследование героев - GhostManSD - 08.09.2010 19:33

Вопрос адресован в первую очередь baratorch. По поводу отлова адреса, где нажимается кнопка. Взять то же окошко найма, например. Ищем деф кнопки покупки. Нашли. Переходим на адрес (например, по адресу AAAAAA). Чуть ниже (по адресу AAAAAB) - то, что я называю BID (button id). BID=7802. Снова иду на строчку дефа, нажимаю стек вызова. Появляется окошко с вызовами, под каждым из вызовов идут строки в духе "[адрес]argument1=x", "[адрес]argument2=y", etc. Вместо x и y написаны адреса. Я так понимаю, мне нужно найти случай, где "argument#=[адрес, где расположен BID]", и поставить на него ловушку. Я верно понял твой способ? Поскольку нигде нет данных типа "если x=7802, прыгнем-ка мы туда...".


RE: Исследование героев - gamecreator - 08.09.2010 19:51

ну как же... сразу после того, как функция, которой передается ид кнопки, отработает, идет проверка возвращаемых значений что-нибудь типа cmp eax,1E7Ah


RE: Исследование героев - GhostManSD - 08.09.2010 20:07

Вот я именно это и имел в виду. Значит, угадал: сравнивается не BID, а его адрес. Спасибо.


RE: Исследование героев - gamecreator - 08.09.2010 22:19

какой еще адрес? сравнивается код кнопки!


RE: Исследование героев - GhostManSD - 08.09.2010 22:48

То есть для кнопки с кодом ID=7802 должно быть cmp eax, 7802?


RE: Исследование героев - GhostManSD - 08.09.2010 23:44

Подскажите, пожалуйста, за что отвечает этот адрес: 0x42437D.
Более подробная информация - здесь.


RE: Исследование героев - gamecreator - 08.09.2010 23:46

(08.09.2010 22:48)GhostManSD Wrote:  То есть для кнопки с кодом ID=7802 должно быть cmp eax, 7802?
я так и написал. но в олли ты увидишь только шестнадцатеричные значения, поэтому для тебя я перевел 7802: будет 1E7A. а буква h в конце значит что число записано в шестнадцатеричной системе исчисления.


RE: Исследование героев - GhostManSD - 08.09.2010 23:51

Quote:для тебя я перевел 7802: будет 1E7A
Лол, мы просто друг друга не поняли. Ab Я и написал в hex, так, как отображается в окне Olly.



RE: Исследование героев - gamecreator - 08.09.2010 23:55

а, так надо ж было или 7802h написать, или 0x7802



RE: Исследование героев - GhostManSD - 09.09.2010 00:56

Каков аналог NOP для команды UN:C?


RE: Исследование героев - Berserker - 09.09.2010 00:59

Опкод нопа - 90h = 144


RE: Исследование героев - baratorch - 09.09.2010 03:12

(08.09.2010 22:48)GhostManSD Wrote:  То есть для кнопки с кодом ID=7802 должно быть cmp eax, 7802?
в большинстве случаев проверяемые ID элементов окна в функции-обработчике находятся внутри switch-ей, поэтому ситуация cmp <ID>, 0x7777 встречается редко.


RE: Исследование героев - gamecreator - 09.09.2010 09:39

так свич - это и есть последовательность сравнений и прыжки на соотв. позиции.


RE: Исследование героев - GhostManSD - 09.09.2010 10:14

Bers, спасибо! Т.е. если я хочу забить адрес NOP-ами, то я должен ввести !!UN:C[адрес] / [размер адреса] / 144;? А где размер адреса смотреть? Артмани подойдет?


RE: Исследование героев - Berserker - 09.09.2010 14:55

nop - однобайтовая команда, а смотреть в оле, там слева от команд пишутся байты опкодов: e7 12345678 - 5 байт, 5 nop-ов нужно по одному.


RE: Исследование героев - feanor - 09.09.2010 19:57

Quote:так свич - это и есть последовательность сравнений и прыжки на соотв. позиции.
не всегда. Скажем, для свитчей на свойства существ используются две таблицы - таблица существ и таблица адресов обработчиков того или иного свитча. А итоговый код выглядит так:
Code:
CPU Disasm
Address   Hex dump          Command                                  Comments
00440906  |.  83C0 C1       ADD EAX,-3F                             ; Switch (cases 3F..87, 6 exits)
00440909  |.  83F8 86       CMP EAX,-7A
0044090C  |.  0F87 99090000 JA 004412AB
00440912  |.  33C9          XOR ECX,ECX
00440914  |.  8A88 4C7A7900 MOV CL,BYTE PTR DS:[EAX+797A4C]
0044091A  |.  FF248D C01244 JMP DWORD PTR DS:[ECX*4+4412C0]
3F - номер первого существа (артефакта, заклинания) в таблице соответствий.
797A4C - адрес таблицы соответствий (хранит номера ветвей-кейсов)
4412C0 - адрес таблицы обработчиков (хранит адреса ветвей-кейсов)


RE: Исследование героев - gamecreator - 09.09.2010 20:33

хм, интересно


RE: Исследование героев - etoprostoya - 09.09.2010 21:01

Таблица NOP'ов с разным числом байт. (Макрос для MS VC)



RE: Исследование героев - gamecreator - 09.09.2010 23:24

db size dup(90h)


RE: Исследование героев - etoprostoya - 09.09.2010 23:41

(09.09.2010 23:24)gamecreator Wrote:  db size dup(90h)
Так не интересно. Ab Хотя, конечно, читается лучше.


RE: Исследование героев - gamecreator - 10.09.2010 01:10

зато сразу видно где забитые байты


RE: Исследование героев - GhostManSD - 10.09.2010 03:12

Подскажите, пожалуйста, как найти адрес стандартного триггера WoG. Например, !?HE.

Кажись, вник. В комментариях - ошибки на неправильный синтаксис. Будем копать оттуда.


RE: Исследование героев - GhostManSD - 10.09.2010 04:09

Нашел место, где сравниваются данные из EBP и номер героя (ввел специально неправильную команду !?HE-1). Вопрос: что теперь делать, чтобы присвоить -1 значение типа "если x=-1, то выполнять для каждого значения от 0 до 156"? Куды иттить, то бишь, где этот гребаный x искать?


RE: Исследование героев - feanor - 10.09.2010 10:47

Quote:+) Добавлено новое событие 77010: Any Hero Interruction (аналог !?HE для всех героев). Параметры события: Герой-Инициатор, Герой-Цель.
Событие, как и оригинальное !?HL, возникает дважды: до и после взаимодействия.
Пример:
!?FU77010;
!!SN:X?y1/?y2;
!!IF:M^Initiator: %Y1, Target: %Y2^;
Не то?


RE: Исследование героев - GhostManSD - 10.09.2010 13:39

Гм, откуда это? Из Era.chm? Мне сейчас интересна не сама функция, а принцип поиска нужных значений для самой функции и ее создание. Пытаюсь учиться.


RE: Исследование героев - Berserker - 10.09.2010 15:28

Из хэлпа по изменениям в Эре 1.8. А так верно идёшь, находишь триггер !?HE ZVS, там он генерит событие в зависимости от нового героя. Ищешь, в каких регистрах герой-источник, герой-приёмник и пишешь свою реализацию. Код из Эры:

Code:
PROCEDURE Hook_HeroesMeet_Call; ASSEMBLER; {$FRAME-}
ASM
    // Если триггер - !?OB, то возвращаемся
    CMP DWORD [EBP+$1C], 34
    JNE @@Exit
    // Получаем номер героя-инициатора
    MOV EAX, [$69CCFC]
    MOV EAX, [EAX+4]
    MOV DWORD [General.EventParams], EAX
    // Получаем номер цели
    LEA ECX, [ECX-30100]
    MOV DWORD [General.EventParams+4], ECX
    // Генерируем ЕРМ-событие
    PUSHAD
    PUSH General.C_ERA_EVENT_HEROMEET
    CALL General.GenerateCustomErmEvent
    POPAD
    // Возвращаем управление ZVS
    @@Exit:
    PUSH $74D760
    PUSH $74C816
END; // .procedure Hook_HeroesMeet_Call

// Патчим вызов триггера !?HE
General.HookCode(POINTER($74D75B), @Hook_HeroesMeet_Call, General.C_HOOKTYPE_JUMP, 5);



RE: Исследование героев - GhostManSD - 10.09.2010 19:20

Bers, я сейчас писал, что я нашел место, где сравнивается номер героя с 0 и со 155. Но это для того, чтобы игра знала, выдавать или не выдавать сообщение об ошибке в духе "баран, героя номер -1 в природе не существует!!111". А мне теперь нужно от этого перейти непосредственно к триггеру !?HE... Вот это-то и представляет сложность: я не знаю соли.


RE: Исследование героев - Sav - 10.09.2010 20:47

Что-то я не понял, как вообще написать dll для создания триггера?

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


RE: Исследование героев - GhostManSD - 10.09.2010 20:48

См. исходник MoP'a. Мне вот куда интереснее, как найти адрес для хука.



RE: Исследование героев - Sav - 10.09.2010 20:52

GhostManSD Wrote:См. исходник MoPa.
Там есть какие-то непонятные мне константы.
А когда я попробовал просто заменить адрес и код на свой, это работать отказалось.


RE: Исследование героев - GhostManSD - 10.09.2010 21:02

Так адрес не любой нужен, а тот, что нарыт в ассемблере.


RE: Исследование героев - Sav - 10.09.2010 21:03

Так я и нарыл.


RE: Исследование героев - GhostManSD - 10.09.2010 21:06

Посмотри ещё исходники Эры.


RE: Исследование героев - Sav - 10.09.2010 22:44

Всё, получилось.


RE: Исследование героев - GhostManSD - 11.09.2010 00:12

Так, ошибку при чтении игрой команды "!?HE-1;" затёр. Если кому нужно, вот исходник. Код, на самом-то деле, ничтожен, но приятно, что хоть это сумел...
Подскажите, пожалуйста, как всё-таки искать оригинальный триггер !?HE. Часа четыре пытался что-нибудь сообразить, но никак.


RE: Исследование героев - Berserker - 11.09.2010 00:37

GhostManSD, такие вещи проще и универсальнее через бинарные патчи делать. Например, нужно занопить 5 байт: адрес 9090909090.


RE: Исследование героев - GhostManSD - 11.09.2010 00:52

Berserker, спасибо! Осталось теперь узнать, как это делать...
Добавлено:
А с поиском триггера никто не подскажет?


RE: Исследование героев - Berserker - 11.09.2010 01:14

Quote:Осталось теперь узнать, как это делать...
Создаёшь txt файл, в котором пишешь: адрес байты в хекс-формате. Далее BinGen.exe file.txt => file.bin. Бинарный файл просто кидаешь в папку EraPlugins.


RE: Исследование героев - GhostManSD - 12.09.2010 20:56

Долго думал, куда кинуть. Сперва хотел в тему по ERM, но, думаю, лучше сюда.
Функция для изменения типа и количества существ в армии героя. Зачем это нужно? Ну, например, это позволяет без ритуальных плясок устанавливать отрицательное количество существ.

Code:
; Функция для изменения существ в армии героя
; x1 - номер героя
; x2 - номер слота
; x3 - тип существ
; x4 - кол-во существ

!?FU80001;
!!VRy1:S1170 *x1; Указать номер героя
!!VRy2:S4 *x2; Указать номер слота
!!VRy3:S71112441 +y1 +y2; Вычислить адрес типа существ
!!VRy4:S71112469 +y1 +y2; Вычислить адрес количества существ
!!UN:Cy3/4/x3; Установить новый тип
!!UN:Cy4/4/x4; Установить новое кол-во
Исходные адреса в hex:
[[43D16F9]+492*x1+4*x2] - тип существ
[[43D1715]+492*x1+4*x2] - количество существ


RE: Исследование героев - GhostManSD - 12.09.2010 22:35

Обновил функцию. Теперь в x3 устанавливается тип существ, в x4 - количество.


RE: Исследование героев - feanor - 13.09.2010 20:43

Quote:43D16F9
адрес динамический. У меня, к примеру, там FFFFFFFF.
Расово кошерный православного вида указатель на структуру героя:
[699538]+21620+492*<hero>


RE: Исследование героев - Sav - 13.09.2010 21:00

Прошу прощения за тупой вопрос: динамический адрес может меняться при нескольких запусках программы на одном компьютере или только на разных компьютерах? И вообще, может кто-нибудь дать мне точное определение этого понятия?


RE: Исследование героев - GhostManSD - 13.09.2010 21:00

feanor, а теперь, пожалуйста, расшифруй. Ab Это такой же указатель, как те, в которых меняется текст?
Ну, например, раньше я в артмани искал, например, текст "Лорд", менял значения для всех по возрастанию, смотрел нужный адрес и искал по нему указатель. Находил нужный и уже адрес самого указателя использовал в функциях.


RE: Исследование героев - baratorch - 14.09.2010 15:57

Статическая память - это секция данных в экзешнике. Эта память выделяется сразу при запуске экзешника. Для самого экзешника адрес этой памяти (и следовательно всех данных в этой памяти) всегда один и тот же (от запуска к запуску и во время выполнения ехе) и всегда существует (пока экзешник работает).
(Например массивы свойств существ, видео, координат строений в городе хранятся в статической памяти, так как длина этих массивов и размер их элементов (да и содержание тоже кстати) не меняется в процессе выполнения программы.

Динамическая память выделяется/освобождается под те или иные нужды в процессе выполнения екзе в зависимости от тех или иных событий. То есть адрес такой памяти (выделенной под какие-то определенные данные) может менятся не только от запуска к запуску, но и от выделения к выделению в процессе выполнения программы.(Например для списков запущенных диалоговых окон и списков элементов этих диалоговых окон память выделяется динамически, так как длина этих списков и размер элементов этих списков меняется в процессе выполнения программы)
Поэтому запоминать такой адрес не имеет смысла, так как при следующем запуске или даже например при старте другого сценария по этому адресу могут находится совершенно другие данные или вообще память недоступная для чтения/записи для этого процесса и тогда при попытке обращения к памяти по этому адесу мы получим крах программы с сообщением о "насилии над доступом" и что "память не может быть Read(Write)".


RE: Исследование героев - GhostManSD - 16.09.2010 01:50

Появилось три вопроса.

1. Как можно узнать статический адрес? Например, для того же динамического 43D16F9 пробовал искать указатель в Артмани - не находит. И вообще у меня этот адрес не меняется никогда и всегда хранит одну и ту же информацию, а именно - тип существ в первом слоте Оррина. Может, он и не динамический вовсе?

2. Если я добавлю деф в h3sprite.lod, для него появится свой адрес? Иными словами, смогу ли я обращаться к дефу в дизассемблере? Например, менять деф кнопки на MYDEF.DEF?

3. Самое важное. Я поставил хук на какой-либо адрес. Добавил функцию 90004. Как мне сделать, чтобы, если x1=0, эта функция меняла содержимое адреса на одно значение, а если x1=1, то меняла ла бы содержимое того же адреса на другое значение?


RE: Исследование героев - Prayer - 16.09.2010 08:38

Чем defки лучше смотреть?


RE: Исследование героев - Sav - 16.09.2010 11:27

Quote:Я поставил хук на какой-либо адрес.
Добавил функцию 90004. Как мне сделать, чтобы, если
x1=0, эта функция меняла содержимое адреса на одно
значение, а если x1=1, то меняла ла бы содержимое того
же адреса на другое значение?

Это после вызова функции, но перед popad.

mov ax, [$91DA38]
cmp ax, 0
jne @@m1
mov bx, zn1;Если x1=0, помещаем 1 значение в регистр.
@@m1:
mov bx, zn2;Если x1<>0, помещаем 2 значение в регистр.
mov perem, bx;Записываем нужное значение в переменную.


RE: Исследование героев - Дьякон - 16.09.2010 11:55

(16.09.2010 01:50)GhostManSD Wrote:  1. Как можно узнать статический адрес? Например, для того же динамического 43D16F9 пробовал искать указатель в Артмани - не находит. И вообще у меня этот адрес не меняется никогда и всегда хранит одну и ту же информацию, а именно - тип существ в первом слоте Оррина. Может, он и не динамический вовсе?
На твоей машине просто совпадает. На многих других работать не будет. Если ищешь через артмани то попробуй искать указатели на начало блока. А если через отладчик или дизассемблер, то в коде часто видно как идет обращение к этому адресу. Либо перехватывай все memalloc и смотри куда записывается указатель на выделенный блок.

(16.09.2010 01:50)GhostManSD Wrote:  2. Если я добавлю деф в h3sprite.lod, для него появится свой адрес? Иными словами, смогу ли я обращаться к дефу в дизассемблере? Например, менять деф кнопки на MYDEF.DEF?

Вообще мутный какой-то вопрос. Более четкую задачу поставь. Менять деф кнопки можно не заморачиваясь с кодом, если эта кнопка уже существует. А вот если хочешь добавить новый деф и кнопку тогда...

(16.09.2010 01:50)GhostManSD Wrote:  3. Самое важное. Я поставил хук на какой-либо адрес. Добавил функцию 90004. Как мне сделать, чтобы, если x1=0, эта функция меняла содержимое адреса на одно значение, а если x1=1, то меняла ла бы содержимое того же адреса на другое значение?
Ммм... берем справочник по нужному тебе языку программирования и смотрим условные операторы.


RE: Исследование героев - feanor - 16.09.2010 12:49

Quote:Как можно узнать статический адрес?
Самый грубый способ - шестизначные - статические, семизначные - динамические.
Quote: А если через отладчик или дизассемблер, то в коде часто видно как идет обращение к этому адресу.
Хардвер брякпойнт на чтение интересующих байтов. Когда сработает - смотреть в брякнувшем участке кода, как происходит обращение.


RE: Исследование героев - Дьякон - 16.09.2010 13:34

(16.09.2010 12:49)feanor Wrote:  Самый грубый способ - шестизначные - статические, семизначные - динамические.
Есть и 6-е не статические.

(16.09.2010 12:49)feanor Wrote:  Хардвер брякпойнт на чтение интересующих байтов. Когда сработает - смотреть в брякнувшем участке кода, как происходит обращение.
Иногда указатель кочует из процедуры в процедуру в виде аргументов. Поэтому докопаться до истины не всегда так просто.


RE: Исследование героев - feanor - 16.09.2010 18:06

Quote:Иногда указатель кочует из процедуры в процедуру в виде аргументов. Поэтому докопаться до истины не всегда так просто.
Знаю. В таком случае идем по вызвавшим процедурам. Ну и параллельно смотрим код в HexRays'e


RE: Исследование героев - Sav - 16.09.2010 18:30

Quote:Ну и параллельно смотрим код в HexRays'e
Что такое Hex Rays?Ab


RE: Исследование героев - etoprostoya - 16.09.2010 19:47

(16.09.2010 08:38)Prayer Wrote:  Чем defки лучше смотреть?
Def Preview. http://wogarchive.ru/files/%D1%EE%F4%F2/%C3%F0%E0%F4%E8%EA%E0/DefPreview%201.1.rar
А вообще, вопрос не по теме.


RE: Исследование героев - Дьякон - 16.09.2010 20:11

(16.09.2010 18:30)Sav Wrote:  
Quote:Ну и параллельно смотрим код в HexRays'e
Что такое Hex Rays?Ab
Это страшная вещь Fie. Это Шестнадцатиричные Лучи ))) разрушающие оболочку головного мозга.

А вообще гугл в помощь. Это дополнение к ИДА с С-подобным синтаксисом.


RE: Исследование героев - gamecreator - 16.09.2010 20:28

легче всего можно узнать статичность адреса, если исследовать секцию памяти, куда указывает адрес. секции можно смотреть в артмани и олли.


RE: Исследование героев - feanor - 17.09.2010 12:08

Quote:Что такое Hex Rays?
Плагин к Иде, декомпилятор.


RE: Исследование героев - GhostManSD - 18.09.2010 22:56

Спасибо, с динамическими и статическими адресами вроде разобрался.
NB: по адресу 0x67D86C+40*hero_class находится название класса героя.


RE: Исследование героев - GhostManSD - 18.09.2010 23:23

Подскажите, пожалуйста, как выйти на адрес, отлавливающий движение мыши по карте... Не координаты x/y/l (их я уже вроде нашел), а при любом движении.


RE: Исследование героев - GhostManSD - 19.09.2010 03:09

Блин, так и не выходит. Вот есть у меня адрес "71112441(dec)", нахожу два указателя - 42149612(dec) и 42149612(dec). Ни один из них не работает, а вот при обращении по прямой все отлично.


RE: Исследование героев - Дьякон - 19.09.2010 11:05

GetCursorPos и ScreenToClient
Добавлено:
Чтоб не было лишних вопросов - дополню. Вероятнее всего оконная процедура героев реагирует на событие WM_MOUSEMOVE (или чет типа того. Лень лезть в MSDN). Т.е. при изменении положения мыши хоть на пиксель вызывается участок кода ответственный за обработку данного события и вызываются вышеуказанные процедуры. Хочешь иметь координаты мыши перехватывай процедуры. Координаты хранятся в локальных переменных, поэтому не найдешь ты адреса никакого.


RE: Исследование героев - gamecreator - 20.09.2010 21:19

а еще лучше подключить длл и поставить винапишный хук на сообщения мыши. это если надо движения мыши перехватывать.


RE: Исследование героев - GhostManSD - 20.09.2010 21:32

Надо отображать в подсказке координаты (как по ПКМ, так и в строке).


RE: Исследование героев - gamecreator - 20.09.2010 21:37

а, ну тогда хз


RE: Исследование героев - feanor - 20.09.2010 23:08

Координаты мыши или координаты на карте?

И да, если надо найти функцию вывода хинтов - то ставь бряк на чтение указателя на какую-нить хинтовую строку и лови через него.


RE: Исследование героев - GhostManSD - 20.09.2010 23:10

Координаты на карте. Спасибо, завтра попробую.


RE: Исследование героев - feanor - 21.09.2010 00:08

Quote:Координаты на карте. Спасибо, завтра попробую.
Quote:!!UN:C6916632/4/9; (698A18: 09)
включает указание координат в подсказке для почвы/объектов.
я это..энтузиазм не убиваю?


RE: Исследование героев - GhostManSD - 21.09.2010 23:07

feanor, да нет, скорее, наоборот! Ab Спасибо!

Подскажите, пожалуйста, каков код в Virtual Pascal для того, чтобы сохранить в функции 90005 (которая является ловушкой для одного адреса) x1=[значение адреса A], а x2=[значение адреса B]? Дабы можно было выполнять, например, вот такое:

!?FU90005;
!!IF:M^%X1 %X2^;


RE: Исследование героев - feanor - 21.09.2010 23:27

Ассемблер или паскаль?
MOV EAX,DWORD PTR DS:[address A]
MOV DWORD PTR DS:[91DA38],EAX //x1
MOV EAX,DWORD PTR DS:[address B]
MOV DWORD PTR DS:[91DA3C],EAX //x2

как-то так в общем, ассемблер я благополучно позабыл Bad


RE: Исследование героев - GhostManSD - 22.09.2010 00:08

(21.09.2010 23:07)GhostManSD Wrote:  Подскажите, пожалуйста, каков код в Virtual Pascal



RE: Исследование героев - Berserker - 22.09.2010 00:25

И? Ты же триггер скорее всего в асме вызываешь? Где код события?


RE: Исследование героев - GhostManSD - 22.09.2010 00:40

Тьфу ты. Все, я включился. Сильно завис. Спасибо!



RE: Исследование героев - GhostManSD - 25.09.2010 15:43

Подскажите, пожалуйста, адрес, где располагается номер текущего города.
А-ля !!CA-1:U.


RE: Исследование героев - Sav - 25.09.2010 15:54

Поищи в ArtMoney.

С помощью, скажем:
!?CM1;
!!CA-1:U?y-1;
!!IF:M^%Y-1^;
Определяешь номер текущего города и ищешь его в ArtMoney.
Затем заходишь в другой город и отсеиваешь по его номеру.


RE: Исследование героев - GhostManSD - 25.09.2010 15:58

Sav, да пробовал я. С типом города адрес нашел сразу же, а вот с номером как-то лаговато выходит.
Code:
!?CM1;
!!CM:S?y1 F?y2 I?y3 P?y4/?y5/?y6 H?y7/?y8; Запомнить подтип клика, флаг для клика, место клика, позицию в x/y/l и номера героев
!!CA-1:U?y9 T?y10;
!!IF&y1=12/y2=0/y3=123:M^Номер - %Y9, тип - %Y10^;



RE: Исследование героев - Sav - 25.09.2010 16:07

В смысле лаговато?
Может быть надо ещё поискать указатели на эти адреса - не думаю, что они статичные.


RE: Исследование героев - GhostManSD - 25.09.2010 16:22

Лаговато - значит, не находится.
В процессе изысканий обнаружил забавную вещь: у нас есть адрес 0x043D0B57. Он вроде как равен номеру города, который выбран активным в списке справа на экране приключений. Выберите город номер 0. Ставьте заморозку. Попробуйте зайти в город с другим номером. Итог: независимо от того, в какой город вы пытаетесь зайти, будет отображаться экран города 0.



RE: Исследование героев - GhostManSD - 25.09.2010 16:44

Понял частично, в чем дело: AM отыскивает не номер текущего города, а номер города, который был последним выбран нажатием мышки в окошке города.
Если перемещаться между экранами города по стрелкам "Вверх" и "Вниз", то AM упорно отказывается искать номер текущего города.


RE: Исследование героев - feanor - 25.09.2010 23:36

Указатель на структуру текущего города -
[69954C]+38.
Первый байт в ней похож на номер города.


RE: Исследование героев - GhostManSD - 26.09.2010 01:22

Как изменять количество существ в армии игрока, я вроде бы нашел. Возможно ли отключить отображение количества существ в нужном слоте вообще? Помогите, пожалуйста, с составлением функции в духе
!!FU90004:Px1/x2/x3, где
x1 - номер героя
x2 - номер слота
x3 - включить/выключить (1/0) отображение количества


RE: Исследование героев - feanor - 26.09.2010 01:27

Ищи отрисовку диалога, в ней отрисовку этого искомого числа, и правь, скажем, координаты.


RE: Исследование героев - GhostManSD - 26.09.2010 03:37

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


RE: Исследование героев - GhostManSD - 26.09.2010 20:41

Разъясните, пожалуйста, как найти адрес закрытия диалога форта в городе. Адрес открытия окна форта - 5D8AF0h (на платформе ERA, по крайней мере). Нужно найти тот адрес, который задействуется при выходе из диалога. Или при нажатии "ОК".


RE: Исследование героев - GhostManSD - 27.09.2010 01:23

Сразу вопрос вдогонку: могу ли я как-то при посещении объекта показать диалог из числа стандартных? Например, тот же диалог захода в форт города номер 0.


RE: Исследование героев - Sav - 04.10.2010 01:15

Частенько в коде Героев встречаются команды типа:
lea eax, [eax + 8*eax]
.

Я правильно понимаю, что они нужны для упрощения написания вычислений (вместо:
push ebx
push edx
mov ebx, eax
mov edx, 0
mov eax, 8
mul ebx
add eax, ebx
pop edx
pop ebx
)?

При выполнении есть ли разница между этими командами?


И такой тупой вопрос: можно ли в Иде изменять команды не через Hex-view и как?


RE: Исследование героев - etoprostoya - 04.10.2010 01:39

Да, примерно так и есть. Разница очевидна - с командой LEA ты не изменяешь другие регистры и не работаешь со стеком.


RE: Исследование героев - Sav - 04.10.2010 01:48

А когда процессор одинаково быстро выполняет эту lea-команду и "нормальный" код?


RE: Исследование героев - etoprostoya - 04.10.2010 16:32

LEA-команды выполняются за один такт обычно или даже две-три такие команды за такт, а "нормальный код", который ты привёл, во много раз дольше, в лучшем случае в пять-десять раз.


RE: Исследование героев - Sav - 04.10.2010 17:49

Но процессору всё равно же надо вычислить, чему равно, eax+8*eax, он что, как-то по-особому вычисляет это в lea-команде?


RE: Исследование героев - etoprostoya - 04.10.2010 19:38

Именно по-особому.
К тому же в твоём "нормальном" примере изменяются три регистра, а значит их нельзя использовать в других командах, что замедляет выполнение программы (регистры-то часто используемые). Используется стек, то есть идёт обращение к кеш-памяти, на что отводятся дополнительные такты процессора, а в случае с полным кешем, этот кеш нужно выгружать в оперативную память (десятки тактов). Используются три подряд команды mov, что полностью блокирует на несколько тактов блок ввода-вывода, хотя это и не важно, так как дальше идёт длительная команда MUL. Эта команда MUL сама по себе плохая, особенно если в твоём случае блокирует использование сразу трёх регистров и все конвееры процессора или ядра останавливаются, ожидая завершения этой команды.

А команда LEA специально оптимизирована для вычисления формул вида
REG = REG+REG*2N+CONST.
Современные процессоры вычисляют за такт несколько таких команд.


RE: Исследование героев - Sav - 04.10.2010 20:08

Тогда понятно и то, почему там eax+8*eax вместо 9*eax.
Спасибо.


RE: Исследование героев - ZVS - 05.10.2010 00:51

Если память мне не изменяет, то множители (2^N) могут быть только 2, 4 и 8. Этот модификатор команды появился только с i386. Ну и понятно, что умножение на 2^N суть сдвиг на N битов влево. Т.е. *9 и *8 две большие разницы (должно быть). Хотя современные процессоры и умножают уже за 1-2 такта.


RE: Исследование героев - etoprostoya - 05.10.2010 14:03

(05.10.2010 00:51)ZVS Wrote:  Если память мне не изменяет, то множители (2^N) могут быть только 2, 4 и 8.
Ну, может быть и 1. То есть РЕГ = РЕГ + РЕГ. Ноль не считается.

Не знаю как самые-самые последние процессоры, но пару лет назад умножение было не меньше 3-4 тактов. Правда могло проходить сразу два умножения параллельно. Это про 32-разрядное умножение.


RE: Исследование героев - ZVS - 05.10.2010 14:56

РЕГ+РЕГ - это стандартный модификатор, который был еще в 80x86, а множители появились, начиная с i386 специально для быстрого обращения к элементам массивов.


RE: Исследование героев - Sav - 16.10.2010 17:02

Может, кому-нибудь пригодится:

по адресу [6919480]+1170n+137020, где n - номер героя,
находится байт, в котором хранится 1, если герой спит (кнопка "Усыпить/разбудить героя" на карте приключений), иначе - 0.


RE: Исследование героев - SAG - 24.10.2010 12:36

(01.09.2010 15:15)MOP Wrote:  Вот длл с более подробным (откомментированным) исходником. Создаёт триггер на лечение Палаткой.
большая просьба прислать мне почтой на randommaps (@) yandex (.) ru. ибо период полураспада файлообменников очень мал и сцылка уже нерабочая


RE: Исследование героев - Sav - 24.10.2010 15:50

Вот исходник:

Я уже отправил SAG-у файл на почту.



RE: Исследование героев - GhostManSD - 24.10.2010 21:48

Подскажите, пожалуйста, как затереть/вызвать определенное диалоговое окно (алгоритм). Например, дабы вместо окна таверны вызывалось окно рынка.


RE: Исследование героев - Дьякон - 24.10.2010 22:57

Элементарно. Менять таблицу jmp-ов для case - а идентификатора зданий.


RE: Исследование героев - GhostManSD - 24.10.2010 23:11

Вопрос не в здании... Эт я как пример. Хочется иметь возможность в любом триггере вызвать нужный диалог.


RE: Исследование героев - feanor - 25.10.2010 00:10

В любом не получится. Тот же диалог оставления войск (HE:C) не вызвать в окне города.

Для городских зданий - http://forum.df2.ru/index.php?s=&showtopic=6813&view=findpost&p=452636
Адреса функций показа разных и хороших диалогов лежат в обработчике кликов (0x5D3640). Как правило, они thiscall'овские, от townManager'a


RE: Исследование героев - GhostManSD - 25.10.2010 02:10

Возможно ли узнать адрес стандартных триггеров? Например, !?TM1 и !?TM2.
feanor, спасибо! Буду разбираться!


RE: Исследование героев - GhostManSD - 25.10.2010 02:19

С тем, как искать диалог по кнопке, разобрался. А как найти диалог по тексту?
P.S. Объясните, пожалуйста (если не сложно), как дауну, - пошагово. Потому что иначе не пойму. :-(


RE: Исследование героев - SAG - 29.10.2010 13:12

кто из гуру может подсказать: как создать статический текст на карте приключений (типа количества ресурсов внизу экрана).
по идее это не должно быть сложно


RE: Исследование героев - Sav - 03.11.2010 21:21

Каковы адреса v-переменных?


RE: Исследование героев - Berserker - 03.11.2010 22:32

0x887668


RE: Исследование героев - Sav - 03.11.2010 22:35

Спасибо.


RE: Исследование героев - Berserker - 03.11.2010 23:45

Мы рады потенциальным клиентам Rolleyes


RE: Исследование героев - GhostManSD - 08.11.2010 00:27

Подскажите, пожалуйста, по какому адресу находится тип заклинания у Альянса Ангелов.


RE: Исследование героев - feanor - 08.11.2010 10:50

0x464FEF


RE: Исследование героев - Sav - 14.11.2010 21:48

Кто-нибудь может сказать, с чем может быть связано то, что Герои (Era 1.8) сами по себе нормально работают с моей dll-кой, а при отладке (с такими же скриптами и т. п.) работают по-другому и неправильно?


RE: Исследование героев - Berserker - 14.11.2010 22:04

Как по-другому и как не правильно? С какой длл и в чём заключается отладка?


RE: Исследование героев - Sav - 14.11.2010 22:22

Я делаю dll для передачи erm управления ударами в бою. В ней я сделал, условно говоря, режим, в котором она восстанавливает изначальный код (т. е. фактически ничего не модифицирует), включённость этого режима зависит от бита v-переменной.

Если запустить игру со скриптом, устанавливающим этот бит на включение режима, действительно ничего не изменится и всё будет работать так же, как и без dll.

Если же запустить тот же экзешник (с теми же скриптами и т. п., той же dll, включённым режимом немодифицирования) через отладчик Иды (в моём случае Windbg debugger), то в определённом месте будет попытка считать что-то из недоступного участка памяти (чего нет при обычном запуске). Если удалить dll и запустить Герои через отладчик, всё будет нормально.


RE: Исследование героев - Дьякон - 14.11.2010 23:08

Тут без экспертого навыка экстросенсорики и пол литра не разобраться. С кодом длл и принтскрином ошибки как-то проще бы было.


RE: Исследование героев - Sav - 14.11.2010 23:25

Без проблем.

Ошибка по адресу 0x004417A4 (MOV EAX, [ESI+34h]) - попытка прочесть память по адресу 34h.
Ещё - отклонение, вызвавшее, скорее всего, эту ошибку - неправильная работа функции sub_5242E0, вызванной по адресу 0x00440064. Там идёт работа со стеком напрямую и извлекается неверное значение (по адресу 0x0052430F (MOV EBX, [EBP+arg_0]; arg_0 = 8])).

Но фишка-то в том, что всё это только при отладке. Просто в игре ничего такого нет.

P.S. Без включенного режима немодифицируемости (отключить - 32-й бит переменной v9501 = 1) ошибка будет в любом случае (правда, разная в игре и отладчике), но с этим я как-нибудь сам разберусь.


RE: Исследование героев - Дьякон - 15.11.2010 00:08

@@Exit:
    TEST ECX, EAX//Восстанавливаем испорченную команду.
    PUSH $440057

Духи говорят, что чего-то здесь не хватает.


RE: Исследование героев - Sav - 15.11.2010 00:13

А чего именно, они не говорят?


RE: Исследование героев - Дьякон - 15.11.2010 00:15

Говорят ))))

00440052 |. 8B4D 08 |MOV ECX,DWORD PTR SS:[ARG.1]


RE: Исследование героев - Sav - 15.11.2010 00:27

...
    JNZ @@Modify

    //Восстановление изначального кода: получение всех позиций рядом, на которых кто-то стоит побитно (Запись в ECX).
    MOV ECX, [EBP+8]
    JMP @@Exit
   
    //Модифицирование кода: запись 0 (будто на всех клетках рядом кто-то стоит) в возвращаемый результат.
    @@Modify:
    MOV ECX, 0
   
    @@Exit:
...

Эта функция, для того и нужна, чтобы либо выполнить MOV ECX,DWORD PTR SS:[ARG.1], что, как я понял равно MOV ECX, [EBP+8], либо поместить в ECX 0.
В моём случае она всегда выполняет первое.


RE: Исследование героев - Дьякон - 15.11.2010 00:56

А данная проца тоже мутная

PROCEDURE Damage_stack; ASSEMBLER; {$FRAME-}
ASM
    //Если 32-й бит в v9501 = 1, модифицируем.
    MOV EAX, DWORD PTR DS:[$890AD8]
    SHR EAX, 31
    TEST EAX, EAX
    JNZ @@Modify
   
    //Восстановление изначального кода: вызов функции, вычисляющей адрес конструкций для атакованного на определённой позиции (запись в EAX).
    MOV EAX, $4E7230
    CALL EAX
    JMP @@Exit
   
    //Модифицирование кода: проверка, надо ли атаковать текущий стек и запись адреса его конструкций или 0 в EAX.
    @@Modify:
    //Проверяем, какой стороне принадлежит проверяемый стек.
    CMP EBX, 21
    JAE @@Def_st
   
    //Если стек принадлежит атакующей стороне, помещаем в EAX соответствующий стеку бит из v9501.
    MOV EAX, DWORD PTR DS:[$890AD8]
    MOV CL, BL
    SHR EAX, CL
    JMP @@All_st
   
    //Если стек принадлежит защищающейся стороне, помещаем в EAX соответствующий стеку бит из v9502.
    @@Def_st:
    MOV EAX, DWORD PTR DS:[$890ADC]
    SUB EBX, 21
    MOV CL, BL
    SHR EAX, CL
    ADD EBX, 21

    //Оставляем в EAX 0 или помещаем в него адрес конструкций стека (в зависимости от начального значкния EAX, т. е. бита v-переменной).
    @@All_st:
    AND EAX, 1
    JZ @@Exit
    //EAX = $699420 + 1352*EBX + 21708.
    LEA ECX, DS:0[EBX*8]
    SUB ECX, EBX
    LEA EDX, [ECX+ECX*2]
    MOV ECX, DWORD PTR DS:[$699420]
    LEA EAX, [EBX+EDX*8]
    LEA EAX, [ECX+EAX*8+21708]
   
    @@Exit:
    PUSH $44009A
END;

Затирается вызов процедуры. Если переходим по JNZ @@Modify то там черт ногу сломит. Однозначно могу сказать только одно: если что-то не работает после твоего вмешательства, значит сам виноват. Проверяй код отладчиком.


RE: Исследование героев - Sav - 15.11.2010 01:30

Всё, что в modify сейчас не важно (на самом деле там выполняестся часть затёртой функции, но номер стека берётся не от адреса инфы о гексе, а из EBX), там действительно, возможно, есть ошибки, но на данном этапе всегда выполняется то, что не modify.


Проблема в том, что если я запущу игру с этой dll-кой, то всё будет работать. А при отладке - выдавать ошибку.
Короче, попробую отлаживать в Olly.


RE: Исследование героев - Berserker - 15.11.2010 02:57

Без отладчика может работать, имея скрытые дефекты, нарушения целостности структур. А под отладчиком диапазон выделяемых адресов сдвигается и лажа даёт о себе знать.


RE: Исследование героев - Sav - 15.11.2010 11:24

Berserker Wrote:А под
отладчиком диапазон выделяемых адресов
сдвигается
Это как?


RE: Исследование героев - Дьякон - 15.11.2010 20:27

BEGIN
    HookCode(POINTER($440052), @Damage_ability, C_HOOKTYPE_JUMP);
    HookCode(POINTER($440064), @Damage_position, C_HOOKTYPE_JUMP);
    HookCode(POINTER($440095), @Damage_stack, C_HOOKTYPE_JUMP);
    HookCode(POINTER($440194), @Damage_target, C_HOOKTYPE_JUMP);
END.

Из всех врезок оставляй по одной и смотри при какой вылетает, а потом мудри.


RE: Исследование героев - Sav - 15.11.2010 22:03

Да, это мне стоило сделать с самого начала.Sm


RE: Исследование героев - Berserker - 16.11.2010 00:06

Quote:Это как?
Отладчик выделяет память в процессе для своих нужд. Динамическую. То есть если без отладчика Angel.dll грузилась по адресу $3000000, то с отладчикаом запросто может по $300F000.


RE: Исследование героев - Sav - 21.11.2010 00:22

На участке кода:
Code:
.text:0044008E                 lea     ecx, [ecx+edx+1C4h]
.text:00440095                 call    sub_4E7230
.text:0044009A
.text:0044009A loc_44009A:
.text:0044009A
.text:0044009A                 mov     esi, eax
не должно меняться ESP.

Если же я делаю так:
то ESP послее выполнения выходит уменьшенным на 4. Почему?


RE: Исследование героев - Berserker - 21.11.2010 02:20

На вид всё корректно. В упор не вижу ошибки. Попробуй трассировать по шагам.


RE: Исследование героев - etoprostoya - 21.11.2010 12:16

SHR EAX, 31
    TEST EAX, EAX
    JNZ @@Modify

=>
    TEST EAX, EAX
    JS @@Modify

А вообще, мне не нравится, когда в одной процедуре стоят PUSH'и без POP'ов. Зачем так сделали?


RE: Исследование героев - Berserker - 21.11.2010 15:26

Quote:А вообще, мне не нравится, когда в одной процедуре стоят PUSH'и без POP'ов. Зачем так сделали?
RET всегда идёт в конце асмовской процедуры. PUSH + RET = JMP


RE: Исследование героев - Дьякон - 21.11.2010 16:17

PROCEDURE Damage_stack; ASSEMBLER; {$FRAME-}

Приведи вид данной процедуры в отладчике


RE: Исследование героев - Berserker - 21.11.2010 16:54

Code:
код процедуры на асме, указанный в сорцах
RET



RE: Исследование героев - GhostManSD - 21.11.2010 19:17

Подскажите, пожалуйста, такую вот вещь: в DL кнока с номером 30721 реагирует на нажатие Esc, закрывая окно. Возможно ли сделать так, чтобы кнопка с номером 30720 реагировала так же на Enter?


RE: Исследование героев - Дьякон - 21.11.2010 20:08

(21.11.2010 16:54)Berserker Wrote:  
Code:
код процедуры на асме, указанный в сорцах
RET

тогда что с esp ?


RE: Исследование героев - Sav - 21.11.2010 20:23

Вот так выглядит место, где он вызывается:
Code:
.text:0044008E lea     ecx, [ecx+edx+1C4h]
.text:00440095 loc_440095:
.text:00440095 call    loc_3C91070
.text:0044009A loc_44009A:
.text:0044009A mov     esi, eax
Вот как выглядит сам код:
Code:
Damage_s:03C91070 loc_3C91070:
Damage_s:03C91070 mov     eax, ds:dword_890AD8
Damage_s:03C91075 shr     eax, 1Fh
Damage_s:03C91078 test    eax, eax
Damage_s:03C9107A jnz     short loc_3C91085
Damage_s:03C9107C mov     eax, offset sub_4E7230
Damage_s:03C91081 call    eax ; sub_4E7230
Damage_s:03C91083 jmp     short $+2
Damage_s:03C91085
Damage_s:03C91085 loc_3C91085:
Damage_s:03C91085 push    offset loc_44009A
Damage_s:03C9108A retn

Перед вызовом ESP = 0x00228CF0, а после 0x00228CEC.


RE: Исследование героев - Berserker - 21.11.2010 20:28

Выложи dll.


RE: Исследование героев - Sav - 21.11.2010 20:32

Исходник: (Click to View)
Скомпилированная: удалено за ненадобностью.


RE: Исследование героев - Дьякон - 21.11.2010 21:20

ну так блин
call loc_3C91070

C_HOOKTYPE_JUMP


RE: Исследование героев - Sav - 21.11.2010 21:30

А как это исправить?
Я не умею создавать "каркас" dll - его я тупо скопировал с MoP-овского исходника.

Code:
HookCode(POINTER($440095), @Damage_stack, C_HOOKTYPE_JUMP);
Тут и так C_HOOKTYPE_JUMP. И он равен False, как и в исходниках Эры.


RE: Исследование героев - Berserker - 21.11.2010 21:33

Quote:ну так блин
call loc_3C91070
C_HOOKTYPE_JUMP
Раньше был вызов, а перехват сделан прыжком - всё верно.

Sav, я попробую сейчас в отладчике выяснить.


RE: Исследование героев - Дьякон - 21.11.2010 21:35

та нифига перехват сделан call - ом

раньше было
.text:00440095 call sub_4E7230

а стало

call loc_3C91070

почувствуй разницу. откуда в геройской секции такие адреса могут быть?


RE: Исследование героев - Berserker - 21.11.2010 21:43

У меня функция вообще не получает управления. Пробовал обычными монстрами и гидрами хаоса. Как вызвать событие?


RE: Исследование героев - Sav - 21.11.2010 21:45

Должна вызываться при ударе существа с флагом "бить всех вокруг". У меня при ударе горыныча вызывалась.


RE: Исследование героев - Дьякон - 21.11.2010 21:46

Не пойму откуда call взялся. В исходниках вроде все правильно.


RE: Исследование героев - Berserker - 21.11.2010 21:47

Понял, в чём проблема события. У тебя и МОРа установка заплаток происходит по сто раз )))
Сейчас ищу ошибку стёка.
Добавлено:
Ответ: под нормальным отладчиком всё чисто.


RE: Исследование героев - Berserker - 21.11.2010 21:53

Quote:почувствуй разницу. откуда в геройской секции такие адреса могут быть?
А у меня JMP в оле)


RE: Исследование героев - Дьякон - 21.11.2010 21:56

Sav, признайся ты специально? 108:D


RE: Исследование героев - Sav - 21.11.2010 21:56

В Иде, если через другой отладчик тоже jmp, оказывается. Но этот другой виснет после 3-х повторяющихся breakpoint-ов, поэтому я его не использовал.


RE: Исследование героев - Berserker - 21.11.2010 21:58

Поправить исходники нужно:
USES Win, Utils, SysUtils, VPUtils; => USES Win;

BEGIN
    [hooks...]
END.

=>

BEGIN
    Win.DisableThreadLibraryCalls(Win.GetModuleHandle('Damage_s.dll'));
    [hooks...]
END.

Код запретит вызывать основую процедуру DLL, которая иначе будет при создании и удалении потоков в программе заново устанавливать хуки, тем самым перезаписывая точки останова в отладчике.
Добавлено:
И точку останова можно ставить только после выполнения кода инициализации Эры, иначе она будет переписана хуком. Зы, точка останова = запись 0xCC по адресу, если что.


RE: Исследование героев - Sav - 21.11.2010 22:08

Теперь всё нормально.
Большое спасибо!


RE: Исследование героев - Sav - 21.11.2010 22:48

Quote:USES Win, Utils, SysUtils, VPUtils;
Это, видимо, было сделано специально - иначе файл получается слишком маленький и на него ругается антивирус (Avira, по крайней мере).


RE: Исследование героев - Berserker - 21.11.2010 22:54

Quote:Теперь всё нормально.
Большое спасибо!
Не за что.

Quote:Это, видимо, было сделано специально - иначе файл получается слишком маленький и на него ругается антивирус (Avira, по крайней мере).
Нет. Просто эти модули у тебя и МОРа вообще не используются, а в Эре использовались.
А ругаться на маленький файл глупо. Меньше размер - лучше компилятор.


RE: Исследование героев - Sav - 21.11.2010 23:23

Berserker Wrote:А ругаться на маленький файл глупо. Меньше размер - лучше компилятор.
Авире скажи.Sm
Мне проще включить туда эти модули, чем разбираться с антивирусом. Поставлю только туда комментарий-напоминание, чтобы не забыть, если что, что можно убрать это.


RE: Исследование героев - Berserker - 21.11.2010 23:54

Sav, скорее всего её эвристику смущает не размер, а твой код, не похожий на код обычного приложения. А если подключить модули, то появляется много чего на вид нормального.


RE: Исследование героев - Sav - 22.11.2010 00:00

Здесь уже сталкивались подобной проблемой: http://forum.df2.ru/index.php?s=&showtopic=15700&view=findpost&p=381860.
Поэтому я и подумал именно на размер.


RE: Исследование героев - Berserker - 22.11.2010 00:07

Такой подход даже эвристикой назвать сложно.


RE: Исследование героев - MOP - 27.12.2010 16:42

Помогите заполнить пробел в знании ассемблера: как работать с командами fild, fstp, fld, fmul, fdivr, fstp и прочими «f…»? Я понимаю, что они предназначены для операций над float – числами с плавающей запятой (как переменные e и e- в ERM). Но что конкретно они делают, что в каких регистрах/ячейках памяти должно находиться и куда возвращается результат – не знаю.


RE: Исследование героев - etoprostoya - 27.12.2010 16:59

Небольшой хэлп по операциям с плавающей точкой x86:
http://zalil.ru/30233173
Собственно не хэлп, а описание операций.
Ещё рекомендую почитать мануалы от Agner'а http://www.agner.org/optimize/
И от Intel http://www.intel.com/design/pentiumii/manuals/245127.htm

А так, если ввести ограничение на неиспользование процессоров ниже Пентиум 3 или Пентиум 4, то лучше использовать гораздо более удобные регистровые инструкции SSE и SSE2 и забить на стековые операции.


RE: Исследование героев - MOP - 27.12.2010 17:06

(21.11.2010 21:58)Berserker Wrote:  Поправить исходники нужно:
USES Win, Utils, SysUtils, VPUtils; => USES Win;
О, кстати. Я этот пост не видел, а как-то сам допёр, когда делал dwellings.dll. Просто меня озадачило, что длл-ки Феанора весят почти в два раза меньше, а делают больше. Подумал: язык тут вряд ли играет особую роль, значит, что-то явно лишнее. Поубирал последовательно используемые средства - длл отказалась компилироваться только без win, а с ней одной работает нормально.
Такой вот метод тыка. 96-copy

etoprostoya, спасибо!


RE: Исследование героев - GhostManSD - 16.01.2011 02:21

Подскажите, как быть. Нашел временный адрес, где хранится нужное значение. В АМ на него более 200 указателей. И как узнать, какой из них нужен?
В Олли щелкал по тому же адресу references, нашел опять-таки за 200 адресов. Но как там искать нужное - тем более не знаю.


RE: Исследование героев - Sav - 16.01.2011 20:00

Найди участок кода, где используется адрес и посмотри там, с помощью какого указателя он получен.


RE: Исследование героев - GhostManSD - 28.01.2011 01:37

Как при обращении к адресу A (на который стоит хук) заменить процедуру в адресе B? Например, изначально в адресе B стоит "MOV ECX 4", а надо, чтобы было "MOV 8". Имеется в виду код в Паскале.


RE: Исследование героев - Berserker - 28.01.2011 01:45

Посмотри в Оле, сколько байтов занимает сама команда, а сколько константа. Например, если 2 байта команда, то прибавь к адресу 2, а затем напиши: PINTEGER(адрес)^:=8. Если константа однобайтовая, то PBYTE(адрес)^:=4;


RE: Исследование героев - etoprostoya - 28.01.2011 01:56

Ссылка в первом сообщении темы не работает.


RE: Исследование героев - GhostManSD - 28.01.2011 02:37

Berserker, можно подробнее для идиота?
1. Что подразумевается под константой? Адрес хука?
2. Где смотреть, что сколько байт занимает?
Простите, если мои вопросы кажутся непроходимо тупыми...


RE: Исследование героев - Berserker - 28.01.2011 03:43

Для идиота смысла нет, а умному человеку почему бы не объяснить? Sm
Image: original.jpg
Видишь, B9 - байт-команда = MOV ECX, SomeConst, а сама константа занимает 4 байта и находится, естественно, байтом правее от адреса команды. Соответственно, нужно записать по адресу 701001(в моём случае) 8.
PINTEGER($701001)^:=8.

Однако это только для кода вога, для которого разрешена запись. Для остального нужно использовать процедуру:

Code:
PROCEDURE WriteAtCode (Addr: POINTER; Buf: POINTER; Count: INTEGER);
VAR
    OldPageProtect:    INTEGER;

BEGIN
    {!} ASSERT(CodeAddr <> NIL);
    {!} ASSERT(Buf <> NIL);
    {!} ASSERT(Count > 0);
    Windows.VirtualProtect(CodeAddr, Count, PAGE_READWRITE, @OldPageProtect);
    MOVE(Buf^, CodeAddr^, Count);
    Windows.VirtualProtect(CodeAddr, Count, OldPageProtect, NIL);
END; // .PROCEDURE WriteAtCode

Вызывать так.

Code:
VAR
  Patch: INTEGER;

Patch:=8;
WriteAtCode(Ptr(адрес), @Patch, 4);



RE: Исследование героев - feanor - 28.01.2011 17:19

Quote:Однако это только для кода вога, для которого разрешена запись.
А разве то ли в ТЕ, то ли в Эре защита со всех секций не снята?
___________
Где хранятся записи о требованиях к отстройке? Раскуривание CD:B результатов не дало.


RE: Исследование героев - Berserker - 28.01.2011 19:17

Не снята. Просто воговская часть имеет флаг на запись и расценивается как данные. А вот содовская, как и ранее, сгенерит исключение.


RE: Исследование героев - feanor - 28.01.2011 19:45

Quote:А вот содовская, как и ранее, сгенерит исключение.
Хм..у меня не генерит, не смотря на то, что я делаю, скажем, так:
Code:
*(int*)(0x59F898+1) = CREATURE_ENERGY_ELEM;



RE: Исследование героев - Berserker - 28.01.2011 19:47

Перепроверил. Был не прав. Очень странно. Выходит теперь любая ошибка запросто портит код, а когда уже будет исключение, анализировать будет нечего.


RE: Исследование героев - GhostManSD - 03.02.2011 06:08

Подскажите, пожалуйста, каков адрес x-переменных функций? Возможно ли вывести какую-нибудь общую формулу в духе [адрес функции 1 * номер функции] + [адрес x1 * номер x]?


RE: Исследование героев - Prayer - 03.02.2011 10:25

Здравствуйте!
Никто случаем не занимался изменением главного меню игры? Меня интересует дизабил некоторых кнопок. Как, например, это реализовано, если ваш компьютер клиент в сетевой игре:

Image: 8397f4f51de37314eb76b6f63954a254.jpeg

Позарез нужно отключить или убрать из меню вообще кнопку "Показать дополнительные опции", чтоб на серваке ее тоже нельзя было использовать. Нашел дефку кнопки - gspbutt.def, текста на ней в genrltxt.txt.

Почитал данную ветку, полез на wasm.ru начал читать "Крекинг с нуля" 141, скачал Olly. Даже бряк поставил на gspbutt.def 147
И только потом понял, что я вообще не соображаю, что дальше делать105 Видать в моем возрасте уже позновато с нуля начать програмировать, при том что общие навыки в этом деле + знание языков = 0,000108


RE: Исследование героев - GhostManSD - 03.02.2011 13:46

На фига бряк-то? Смещай координаты просто за пределы экрана.

Или забей нопами отрисовку.


RE: Исследование героев - GhostManSD - 03.02.2011 15:12

Мастера, подскажите, пожалуйста, как по умному сделать. Нужно, чтобы при хуке на адресе A:
1) сравнивалось значение по адресу B с -1 (CMP DWORD [адресB], -1);
2) если по адресу B и вправду -1, то команда по адресу C будет MOV ECX, DWORD [EDX*4+$68A36C];
3) если по адресу B отличное от -1 значение, то команда по адресу C будет MOV ECX, DWORD [адресB*4+$68A36C].

Я пробовал менять опкод и аргумент через PINTEGER, но у меня выходит хрень какая-то. Помогите, пожалуйста!


RE: Исследование героев - Sav - 03.02.2011 15:37

По-моему, лучше в хуке по адресу A запомнить значение по-адресу B, а проверять в хуке по адресу C, если я правильно понял, что тебе надо.


RE: Исследование героев - Prayer - 03.02.2011 20:13

(03.02.2011 13:46)GhostManSD Wrote:  На фига бряк-то? Смещай координаты просто за пределы экрана.

Или забей нопами отрисовку.
Хммм... А это как? Где искать координаты? Отрисовку?
Я же писал что делитант...


RE: Исследование героев - GhostManSD - 03.02.2011 20:31

Нашел свою кнопку? Перейди на адрес, где она прописывается (в Олли: search > text references > твоя кнопка.def. Нажимаешь на ней лкм. Ты попадешь в CPU. Там рядом с названием кнопки будут прочие аргументы. Координаты находятся на пару строчек ниже (2 адреса: отступ сверху и отступ слева). Они - в шестнадцатеричном формате. Для перевода используй калькулятор Windows в инженерном режиме. Поставь большие координаты, чтобы кнопка "уехала" за пределы экрана. Вроде все.


RE: Исследование героев - GhostManSD - 03.02.2011 20:37

Sav, попробую. Мне тоже приходила в голову такая мысль, но я думал, есть способ сделать без второго хука.


RE: Исследование героев - Дьякон - 03.02.2011 21:57

покажи код


RE: Исследование героев - GhostManSD - 04.02.2011 00:00

Адреса для хука (точнее, для хука - верхний, а остальные прописываю для восстановления оригинальных команд); при хуке происходит вызов функции 90003 (это я уже прописал в плагине).
Code:
005CCD80  /$ 55                PUSH EBP
005CCD81  |. 8BEC              MOV EBP, ESP
005CCD83  |. 6A FF             PUSH -1
005CCD85  |. 68 575F6300       PUSH 00635F57                            ;  SE handler installation

Следующий код - тип подложки гильдии магов. Вычисляется здесь.
Code:
005CCEC5  |. 8B15 4C956900  MOV EDX, DWORD PTR DS:[69954C]
005CCECB  |. 68 00080000    PUSH 800                                 ; /Arg7 = 00000800
005CCED0  |. 8B4A 38        MOV ECX, DWORD PTR DS:[EDX+38]           ; |
005CCED3  |. 0FBE51 04      MOVSX EDX, BYTE PTR DS:[ECX+4]           ; |
005CCED7  |. 8B0C95 6CA3680>MOV ECX, DWORD PTR DS:[EDX*4+68A36C]     ; |
005CCEDE  |. 51             PUSH ECX                                 ; |Arg6

В функции 90003 игрок может установить параметр SN:X1 от -1 до 8. Если X1=-1, то значение ECX из кода №2 остается неизменным и соответствует реальному типу города. Если 0<X1<8, то устанавливается подложка соответствующего типа города.

Было бы еще здорово узнать, как эти параметры выставлять. При попытке прописать в своей dll нечто в духе MOV DWORD General.EventParams, 1 Паскаль говорит, что никакого General в природе нет.


RE: Исследование героев - Sav - 04.02.2011 00:07

Здесь Берс показывал мне, как использовать для передачи и приёма параметров SN:X.


RE: Исследование героев - Дьякон - 04.02.2011 00:08

ты мне свой код выложи


RE: Исследование героев - GhostManSD - 04.02.2011 00:22

Code:
PROCEDURE MageGuildBackground; ASSEMBLER; {$FRAME-}
    ASM
    PUSHAD// Push all registers
    CMP DWORD [$887668], -1 // Compare -1 with v1
    JZ @@Leave
    MOV EAX, DWORD [$887668] // Move v1 to EAX
    MOV DWORD [$5CCED7], $8B0C85 // Change opcode
    MOV DWORD [$5CCED8], $68A36C // Change parameter
    POPAD // Restore all registers
    @@Leave:
    POPAD // Restore all registers

PROCEDURE HOOK_MageGuildEnter; ASSEMBLER; {$FRAME-}
    ASM
    PUSHAD // Push all registers
    CALL MageGuildBackground
    PUSH 90003 // Push function number
    MOV EAX, $74CE30 // Move $74CE30 to EAX
    CALL EAX // Call ERM-function
    ADD ESP, 4 // Add 4 to ESP
    POPAD // Restore all registers
    PUSH EBP // Push EBP
    MOV EBP, ESP // Move ESP to EBP
    PUSH -1 // Push -1
    PUSH $5CCD85 // Push $5CCD85
END; // .PROCEDURE HOOK_MageGuildEnter

BEGIN
    HookCode(POINTER($5CCD80), @HOOK_MageGuildEnter, C_HOOKTYPE_JUMP); // 90003
END.


До этого вместо MOV устанавливал через PINTEGER таким же образом значения по адресам.


RE: Исследование героев - etoprostoya - 04.02.2011 01:36

А что у тебя подряд два POPAD в MageGuildBackground? Причём один то выполняется, то нет.


RE: Исследование героев - GhostManSD - 04.02.2011 01:51

Ну так вроде же надо восстанавливать регистры независимо от итога. Хотя во втором случае никакие регистры вроде не меняются, так что там и правда нет нужды. Но проблема-то не в этом.
Гм. Сейчас вот на свежую голову все это посмотрел и увидел, что если вручную в Олли поменять процедуру в нужном мне адресе, получается вот что:
БЫЛО
Code:
005CCED7     8B0C95 6CA36800     MOV ECX, DWORD PTR DS:[EDX*4+68A36C]
005CCEDE     51                  PUSH ECX
005CCEDF  |. 6A 01               PUSH 1
СТАЛО
Code:
005CCED7     3E:8B0C85 6CA36800  MOV ECX, DWORD PTR DS:[EAX*4+68A36C]
005CCEDF  |. 6A 01               PUSH 1
Выходит, происходит сдвиг, и команда PUSH ECX затирается. Как бороться?


RE: Исследование героев - Sav - 04.02.2011 02:02

Если что-то затирается, надо в конце процедуры хука push-ить адрес первой незатираемой команды, а все затираемые выполнять в процедуре.


В процедуре MageBuildBackgroung убери popad перед "@@leave:" - другой popad и так будет выполняться всегда.


RE: Исследование героев - etoprostoya - 04.02.2011 02:07

Если у тебя
Code:
JZ @@Leave
выполняется, то идёт один POPAD, иначе - два. Ты уверен, что так и должно быть?


RE: Исследование героев - GhostManSD - 04.02.2011 03:16

Попробовал поменять код. Вместо двух процедур сделал одну.
Code:
PROCEDURE HOOK_MageGuildEnter; ASSEMBLER; {$FRAME-}
    ASM
    PUSHAD // Push all registers
    PUSH 90003 // Push function number
    MOV EAX, $74CE30 // Move $74CE30 to EAX
    CALL EAX // Call ERM-function
    ADD ESP, 4 // Add 4 to ESP
    POPAD // Restore all registers
    MOV EDX, DWORD [$69954C]
    PUSH 800
    MOV ECX, DWORD [EDX+$38]
    MOVSX EDX, BYTE [ECX+4]
    CMP DWORD [$887668], -1
    JNZ @@Change
    PUSH ECX
    PUSH $5CCEDF
    @@Change:
    MOV EAX, DWORD [$887668]
    MOV ECX, DWORD [EAX*4+$68A36C]
END; // .PROCEDURE HOOK_MageGuildEnter
Ошибка, чсх, все так же вылазит. Выкладываю ее в спойлере.
Используемый код в ERM:
!?FU90003;
!!VRv1:S-1;


RE: Исследование героев - etoprostoya - 04.02.2011 03:45

Ты вообще в курсе, что PUSH(AD) и POP(AD) изменяют значение ESP?


RE: Исследование героев - GhostManSD - 04.02.2011 04:00

В курсе. Но стандартный метод вроде такой:
1. При срабатывании хука - PUSHAD.
2. Далее прописать вызов функции.
3. POPAD.
4. Выполнить затертые команды.

Может, проблема в том, что у меня выполняется больше команд, чем я затираю?


RE: Исследование героев - Sav - 04.02.2011 12:17

Затёртые команды и push адреса должны выполняться в любом случае (т. е. стоять в конце кода после всех меток). У тебя же не так.


RE: Исследование героев - etoprostoya - 04.02.2011 12:24

(04.02.2011 04:00)GhostManSD Wrote:  В курсе.
Тогда ты должен быть в курсе, что такие конструкции, как у тебя:
Code:
CMP DWORD [$887668], -1
    JNZ @@Change
    PUSH ECX
    PUSH $5CCEDF
    @@Change:
    MOV EAX, DW
    ...
    MOV REG, [ESP+OFFSET]
Будут работать совершенно по-разному, в зависимости от первого CMP. В одном случае возьмётся одно значение из стека, а в другом - другое. И так для всего кода программы, то есть ты делаешь ВЕСЬ код неправильным.
Нужно сделать так, чтобы ESP на метке @@Change был одинаков, независимо от проверки.


RE: Исследование героев - GhostManSD - 04.02.2011 14:40

Как? MOV EBP, ESP; затем в нужном месте (после метки) - MOV ESP, EBP?


RE: Исследование героев - Sav - 04.02.2011 15:08

ESP - регистр, отвечающий за заполненность стека.
Чтобы он не сбивался, надо, чтобы push было столько же, сколько и pop вне зависимости от, того, как будет выполняться код.
Как-то так, хотя я не понимаю, что делает push 800 в таоём коде.

PROCEDURE HOOK_MageGuildEnter; ASSEMBLER; {$FRAME-}
    ASM
    PUSHAD // Push all registers
    PUSH 90003 // Push function number
    MOV EAX, $74CE30 // Move $74CE30 to EAX
    CALL EAX // Call ERM-function
    ADD ESP, 4 // Add 4 to ESP
    POPAD // Restore all registers
    MOV EDX, DWORD [$69954C]
    PUSH 800
    MOV ECX, DWORD [EDX+$38]
    MOVSX EDX, BYTE [ECX+4]
    CMP DWORD [$887668], -1
    JE @@L
    MOV EAX, DWORD [$887668]
    MOV ECX, DWORD [EAX*4+$68A36C]
    @@L:
    PUSH ECX
    PUSH $5CCEDF
END; // .PROCEDURE HOOK_MageGuildEnter


RE: Исследование героев - MOP - 04.02.2011 15:29

(13.09.2010 21:00)Sav Wrote:  Прошу прощения за тупой вопрос: динамический адрес может меняться при нескольких запусках программы на одном компьютере или только на разных компьютерах? И вообще, может кто-нибудь дать мне точное определение этого понятия?
Что-то никто не дал нормальный ответ. Теперь попробую я.
Для этого маленького исследования потребуется (из прог, которые мне знакомы):
либо PE Explorer,
либо не так давно найденная мной замечательная и очень компактная программка LordPE,
либо супермаленькая прога Икзелиона, некогда выложенная Дьяконом в приложение к одному из туториалов,
да почти любой дизасм.
В любом случае, нужна программа, позволяющая посмотреть сегментацию экзешника, его деление на секции. В принципе, подходит та же IDA, только там почему-то не видна секция .rsrc (видимо, за ненадобностью).
Мне лично нравится отображение секций в PE Explorer. Поэтому приведу скрин с него:
Image: 7d6cfc22c277.jpg
Size of Raw Data – размер секции непосредственно в файле.
Virtual Size – размер секции во время работы приложения. Включает в себя Raw Size.
Virtual Adress – адрес начала секции в запущенном приложении.
Pointer of Raw Data – адрес начала секции в файле.
Нетрудно заметить, что для сод-секций Virtual Adress = Pointer of Raw Data + 400000h, а для вог-секций Virtual Adress = Pointer of Raw Data + 465000h.
Для записи/чтения требуется знать только статическое виртуальное пространство, подходящее для этих целей. Достаточно нескольких минут, чтобы понять, что есть три НЕподходящих области:
1. < 401000h. В этих адресах работает система, поддерживая работу запущенного приложения. Также там находится стек. Запись/чтение там просто бесполезны и могут убить приложение.
2. >=6AD000/<701000. Иначе говоря, вся секция .rsrc. Этой секции просто не выставлены флаги Readable/Writeable, поэтому никаких операций с ней не выйдет и всё закончится вылетом (хотя можно выставить флаги и юзать, но лучше уж добавить новую секцию). Львиную долю её занимают иконки экзешника, также там информация о файле, менюшка, доступная в оконном режиме, и прочее.
3. >=293512Ch (21AE12C + 787000). Основная динамическая память. Сюда подгружаются библиотеки, здесь создаёт свои аллоки экзешник.
Существует закономерность: чем больше размер буфера, выделяемого в динамической памяти, тем больше шансов, что его адрес будет более статичен. Отюда многие заблуждения и принятие динамических адресов за статические. Достаточно запустить игру под отладчиком, подгрузить дополнительную длл или ресурс, запустить exe на другой системе или машине – и адрес окажется вовсе не таким.

Вот и всё.
Дополнения и уточнения принимаются, так как этот пост написан на основе личного практического знания.


RE: Исследование героев - GhostManSD - 04.02.2011 16:09

(04.02.2011 15:08)Sav Wrote:  Как-то так, хотя я не понимаю, что делает push 800 в таоём коде.
Code:
MOV EDX, DWORD [$69954C]
    PUSH 800
    MOV ECX, DWORD [EDX+$38]
    MOVSX EDX, BYTE [ECX+4]
Эти строки - оригинальный код. В т.ч. PUSH 800.
Попробовал твой код, Sav. Тоже вылет, только ошибка другая. А причина одна - безблагодатность. Ab Прикладываю crashlog.



RE: Исследование героев - Sav - 04.02.2011 17:29

Если у тебя хук на 5CCDD7, то эти строчки не затираются, а значит - убери их. Лишний mov может и не страшно, а вот лишний push - страшно почти всегда.


RE: Исследование героев - Дьякон - 05.02.2011 00:23

MOP, динамическая память - это память выделенная в процессе выполнения программы, такими функциями как GlobalAlloc, VirtualAlloc и др. Все секции exe являются статическими.


RE: Исследование героев - Дьякон - 05.02.2011 00:34

MOV DWORD [$5CCED7], $8B0C85 // Change opcode
    MOV DWORD [$5CCED8], $68A36C // Change parameter

ты меняешь смещение на 1 байт а записываешь по 4 байта - определись.


RE: Исследование героев - GhostManSD - 05.02.2011 18:17

Дьякон, спасибо!
Теперь новый вопрос (скорее всего, к Берсу). В коде делаю вот так...

MOV EAX, DWORD [Адрес]
MOV DWORD [EventsParam], EAX

...и, по идее, код

!?FU90003;
!!SN:X?v1;
!!IF:M^%V1^;

должен выдавать сохраненное значение. Но ни фига, выдает какую-то постороннюю чушь. А если занести то же в v1...

MOV EAX, DWORD [Адрес]
MOV DWORD [$887668]

...и код прописать вот такой...

!?FU90003;
!!IF:M^%V1^;

...все выдается верно. Что я делаю не так?


RE: Исследование героев - Berserker - 05.02.2011 18:43

Code:
TYPE
    PEventParams    =    ^TEventParams;
    TEventParams    =    ARRAY[0..63] OF INTEGER;

VAR
  EventParams:        PEventParams;

BEGIN
    EventParams    :=    Win.GetProcAddr(Win.GetModuleHandle('Angel.dll'), 'EventParams');
END.
Не забыл про это?

MOV EAX, [Адрес]
MOV ECX, [EventParams]
MOV [ECX], EAX

EventParams - только указатель на массив, а не сам массив.


RE: Исследование героев - MOP - 05.02.2011 19:16

(05.02.2011 00:23)Дьякон Wrote:  MOP, динамическая память - это память выделенная в процессе выполнения программы, такими функциями как GlobalAlloc, VirtualAlloc и др. Все секции exe являются статическими.
А я что-то другое написал?


RE: Исследование героев - GhostManSD - 05.02.2011 21:56

Берс, спасибо огромное! Тысячный раз уже выручаешь! Вот только есть одна такая вот нехорошая штука... Как быть, если мне нужно поместить значение в X1 в одном хуке, а считывать - с другого? Например, в одном из адресов вычисляется что-то и заносится в EAX.
Hook1
    mov ecx, [EventParams]
    mov [ecx], eax
.Hook1

Hook2
    [моя функция]
.Hook2

При попытке считать SN:X он выдает всякую хрень. Как быть? В хуке 1 сохранять в левый адрес (типа v1) значение параметра, а в хуке 2 - передавать из этого адреса?


RE: Исследование героев - Berserker - 05.02.2011 22:19

Считывание:
mov ecx, [EventParams]
mov eax, [ecx] // eax = X1


RE: Исследование героев - Sav - 05.02.2011 22:33

Quote:TEventParams = ARRAY[0..63]
Я смотрел в исходниках Эры, там только 16.

GhostManSD Wrote:Как быть, если мне нужно поместить значение в X1 в одном хуке, а считывать - с другого?
Лучше завести отдельную переменную: мало ли как может использоваться SN:X между хуками (даже если не используется - ради совместимости с потенциальными другими модами).


RE: Исследование героев - Berserker - 05.02.2011 22:47

Quote:Я смотрел в исходниках Эры, там только 16.
Извиняюсь, скопировал с черновика 2.0.


RE: Исследование героев - GhostManSD - 05.02.2011 22:53

Берс, не о том речь, хотя это тоже пригодится.
Вот что я имел в виду... (Click to View)

Sav, попробую сейчас.

Верно ли я понял суть? (Click to View)



RE: Исследование героев - Berserker - 05.02.2011 23:13

Вроде бы да.


RE: Исследование героев - Дьякон - 06.02.2011 03:11

(04.02.2011 15:29)MOP Wrote:  3. >=293512Ch (21AE12C + 787000). Основная динамическая память.

еще раз. Все секции - статические.


RE: Исследование героев - GhostManSD - 06.02.2011 07:42

Подскажите, пожалуйста, где ошибка (в X1 не появляются нужные параметры)...



RE: Исследование героев - Sav - 06.02.2011 09:57

Когда ты используешь переменную, не надо ставить квадратные скобки:
mov var, eax
mov ecx, var


RE: Исследование героев - Дьякон - 06.02.2011 14:41

квадратные скобки играют роль только для регистров.


RE: Исследование героев - GhostManSD - 06.02.2011 16:49

Не выходит, хоть убей. Все время по запросу !!SN:X?v1 выдается 139. Хук стоит на $5C6C70.



RE: Исследование героев - Berserker - 06.02.2011 16:59

Выложи библиотеку.


RE: Исследование героев - GhostManSD - 06.02.2011 19:01

GMSDLib.dll
GMSDLib.pas
Спасибо большое!


RE: Исследование героев - GhostManSD - 07.02.2011 01:01

Спасибо большое, проблему решил самостоятельно, что радует еще больше. Ab


RE: Исследование героев - Berserker - 07.02.2011 02:13

Хорошо. Я уже как раз разобрался с остальными делами и собирался проверить dll в отладчике. А что было не так?


RE: Исследование героев - GhostManSD - 07.02.2011 02:23

Code:
MOV EAX, [$6AAAB8]
MOV ECX, EventParams
MOV [ECX], EAX
вместо
(05.02.2011 18:43)Berserker Wrote:  MOV EAX, [Адрес]
MOV ECX, [EventParams]
MOV [ECX], EAX



RE: Исследование героев - GhostManSD - 07.02.2011 02:35

Все это, конечно, здорово. Но указатель порой находится далеко от места, на которое срабатывает хард брейкпойнт. Допустим, я никак не могу найти адрес типа текущего города, хотя знаю, что в момент срабатывания бряка по адресу $741B7C тип города заносится в ECX. Можно ли мне быстро найти место, где значение заносится в ECX? Я листал долго, но ничего в духе MOV ECX, [Адрес] не обнаружил. Нашел MOV ECX, [EBP-8], но где ставится EBP, найти не могу. Quod autem facere, то бишь, делать-то что?


RE: Исследование героев - Дьякон - 07.02.2011 10:00

А чем тебя ecx не устраивает? Полистай код, найди процедуру, в которую передается тип города, в зависимости от твоих потребностей, и меняй себе на здоровье.


RE: Исследование героев - GhostManSD - 07.02.2011 20:55

Дьякон, я не совсем понял, что ты имеешь в виду. Можешь пояснить или привести примерный код?


RE: Исследование героев - Дьякон - 07.02.2011 23:48

приведи код и поставь задачу


RE: Исследование героев - GhostManSD - 08.02.2011 00:40

Опять нашел ответы на свои вопросы. Ab Размещаю здесь, авось кому пригодится.
Code:
[$6AAAB8] - номер города
[[$69954C]+$110] - тип города


Дьякон, спасибо, уже не надо. Ab Научился вроде искать указатели. АртМани тут и впрямь не помощник.


RE: Исследование героев - GhostManSD - 08.02.2011 02:58

Мне может кто-нибудь объяснить, что означает эта команда?
Code:
MOV DWORD PTR FS:[0], ECX
При попытке поставить хук в ту область, где она выполняется, происходит вылет при записи.


RE: Исследование героев - Berserker - 08.02.2011 03:03

Установка обработчика структурных исключений. Если очень хочется мозголома, то гугл: Structured Exceptions Handling.
Обычно тебе этот код не должен быть нужен.


RE: Исследование героев - GhostManSD - 08.02.2011 03:37

Берс, уже поставил хук на другое место. Но почитаю, спасибо. Хотя вряд ли пойму, если даже ты говоришь, что мозголом.


RE: Исследование героев - GhostManSD - 08.02.2011 16:52

Такой вот вопрос: когда заклинания Гильдии магов добавляются герою? Если нет книги, то, по идее, сразу после покупки оной. А если есть книга, то при заходе в город?


RE: Исследование героев - SAG - 09.02.2011 18:04

подозреваю, что если портануться в город, но зайти в город не двойным кликом а через Управление королевством, то могут не добавиться. не проверял


RE: Исследование героев - GhostManSD - 09.02.2011 22:36

SAG, проверю.
Товарищи, поставил хук на получение уровня и после получения уровня (огромное спасибо MOP). Есть один досадный минус: почему-то лишь раз показывается окошко получения нового уровня (независимо от опыта), а уровень героя приравнивается к 34. Помогите отыскать жука.



RE: Исследование героев - Berserker - 09.02.2011 23:51

Quote:на получение уровня
!?HL?
X1 - Erm x1?


RE: Исследование героев - GhostManSD - 09.02.2011 23:52

Да. Но только для любого героя.


RE: Исследование героев - GhostManSD - 10.02.2011 00:43

(09.02.2011 23:51)Berserker Wrote:  
Quote:на получение уровня
!?HL?
X1 - Erm x1?
Угу. Ибо с EventParams у меня опять какая-то херь выходит. Потом поменяю, пока что хватает и этого. Так, код
Code:
!?FU90000;
!!IF:M^%X1 - герой, %X2 - уровень^;
выводит все правильно.

А код
Code:
!?FU90001;
!!HEx1:Ed/x2;
не работает.


RE: Исследование героев - Berserker - 10.02.2011 01:11

Установить уровень в x2?

Quote:Да. Но только для любого героя.
!?HL-1;


RE: Исследование героев - Sav - 10.02.2011 01:16

Так в HE:E при установке уровня окна и не должны вроде появляться.


Откуда появляются значения в переменных LevelUp_HeroNumber и LevelUp_HeroLevel?


RE: Исследование героев - Berserker - 10.02.2011 01:18

Quote:Так в HE:E при установке уровня окна и не должны вроде появляться.
Конечно не должны. А в x2 - мусор по ходу.


RE: Исследование героев - GhostManSD - 10.02.2011 03:35

Sav, ты не понял. Не о том речь. При срабатывании хука все переменные перемещаются нормально и выдают верные значения. Но отображается лишь одно окно (даже если герой получил 3 уровня) и герою накидываются уровни до 34.

(10.02.2011 01:16)Sav Wrote:  Откуда появляются значения в переменных LevelUp_HeroNumber и LevelUp_HeroLevel?
Из указателей. Дело не в этом.


RE: Исследование героев - GhostManSD - 10.02.2011 04:05

(10.02.2011 01:18)Berserker Wrote:  
Quote:Так в HE:E при установке уровня окна и не должны вроде появляться.
Конечно не должны. А в x2 - мусор по ходу.

Почему же мусор? Показывает, какого уровня достиг герой.


RE: Исследование героев - Sav - 10.02.2011 14:04

Уровни до 34 накидываются всегда или только при использовании HE:E?


RE: Исследование героев - GhostManSD - 10.02.2011 14:49

Всегда. А HE:E было призвано исправить ситуацию, сменив уровень героя на тот, которого он достигает. Но ситуация не меняется. Я бы пошел иным путем: устанавливал бы значение в ассемблере, но я никак не могу найти указатель на реальный уровень героя (а не получаемый).
При вводе чита woggandalfwhite все проходит нормально, кстати. Получаемый уровень соответствует реальному.


RE: Исследование героев - Sav - 10.02.2011 15:03

А зачем ты восстанавливаешь так много кода? Хуку же одного call хватает, чтобы больше ничего не затирать.


RE: Исследование героев - GhostManSD - 10.02.2011 15:13

Sav, не понял. Можешь пояснить? Или показать, как должен выглядеть мой код?


RE: Исследование героев - Sav - 10.02.2011 15:41

    HookCode(POINTER($4DAC9B), @HookTrigger_LevelUp, C_HOOKTYPE_JUMP); // 90000
***
    // Restore default code
    MOV DataTemp, $59A890
    CALL DataTemp
    MOV EAX, DWORD PTR DS:[$69959C]
    MOVSX ECX, AX
***
    PUSH $4DACA7

Можно было бы сделать адресом хука адрес call-а и не восстанавливать ничего, кроме него.
И push-ить адрес call-а + 5.
Как это точно сделать - не знаю (нет кода игры перед глазами).
Здесь не видно связи с твоей ошибкой, но иногда при исправлении понятных недочётов исправляются и непонятные ошибки


RE: Исследование героев - GhostManSD - 10.02.2011 18:07

Sav, спасибо, помогло. Теперь всегда буду ставить хук на CALL.
З.Ы. X2 - и впрямь мусор. Точнее, не совсем мусор, но не то, что нужно. Не совсем то я искал. Ab

(10.02.2011 18:07)GhostManSD Wrote:  З.Ы. X2 - и впрямь мусор. Точнее, не совсем мусор, но не то, что нужно. Не совсем то я искал. Ab

Извиняюсь, таки соврал. Нужное. Это уровень, которого достигнет герой, когда закончит щелкать по окошкам, выбирая новые навыки. Ab


RE: Исследование героев - GhostManSD - 10.02.2011 23:55

Допустим, в адресе A идет значение (по дампу) [01 00 00 04 00 08 1F 00]. Могу ли я загнать в EAX только начало этого значения, т.е. (в данном случае) 01?


RE: Исследование героев - Sav - 11.02.2011 00:31

mov eax, byte ptr [A]


RE: Исследование героев - GhostManSD - 11.02.2011 00:38

А если надо закинуть второй байт? mov eax, byte ptr [A+1]?

Error 45: Operand types do not match.


RE: Исследование героев - Sav - 11.02.2011 00:45

Да. Кроме того можно использовать не весь eax (4 байта), а только его четвертинку al:
mov al, [A]


RE: Исследование героев - Berserker - 11.02.2011 01:08

A - константа?


RE: Исследование героев - GhostManSD - 11.02.2011 01:09

Sav, спасибо, работает!


RE: Исследование героев - etoprostoya - 11.02.2011 01:28

Лучше
MOVZX EAX, [A];
Потому что команда
MOV AL, [A];
не изменяет старшие 24 бита и если там что-то было, то так и останется.
EAX = 0x12345678; MOV AL, BYTE PTR [A]; => EAX = 0x12345601;
EAX = 0x12345678; MOVZX EAX, BYTE PTR [A]; => EAX = 0x00000001;


RE: Исследование героев - GhostManSD - 11.02.2011 01:37

(11.02.2011 01:08)Berserker Wrote:  A - константа?
Нет. Вычисляется из указателя.


RE: Исследование героев - Sav - 11.02.2011 01:51

etoprostoya Wrote:MOVZX EAX, [A];
А для word есть аналогичная?


RE: Исследование героев - GhostManSD - 11.02.2011 01:51

etoprostoya, исправил и взял на заметку. Ab

Sav, похоже, есть: http://faydoc.tripod.com/cpu/movzx.htm


RE: Исследование героев - Sav - 11.02.2011 01:59

А управлять через ассемблер как? Код разный, а команда одна и та же.
movzx eax, x
где x - переменная запишет в eax байт или слово?


RE: Исследование героев - GhostManSD - 11.02.2011 02:17

Думаю, MOVZX EAX, BYTE [x] // MOVZX EAX, WORD [x] // MOVZX EAX, DWORD [x].


RE: Исследование героев - etoprostoya - 11.02.2011 02:17

Quote:0F B6 / r MOVZX r16,r/m8 Move byte to word with zero-extension
0F B6 / r MOVZX r32,r/m8 Move byte to doubleword, zero-extension
0F B7 / r MOVZX r32,r/m16 Move word to doubleword, zero-extension
MOVZX EAX, BYTE PTR [MEM]
и
MOVZX EAX, WORD PTR [MEM]
имеют разный код в 32-битном моде.

(11.02.2011 02:17)GhostManSD Wrote:  Думаю, MOVZX EAX, BYTE [x] // MOVZX EAX, WORD [x] // MOVZX EAX, DWORD [x].

Смысл последнего? Ab Нет такого


RE: Исследование героев - Sav - 11.02.2011 10:51

movzx eax, word ptr x

mov eax, word ptr x

Разница, выгода первого?


RE: Исследование героев - etoprostoya - 11.02.2011 12:30

Выгода первого в том, что компилятор его правильно обработает, так как для второго выдаст ошибку - команды MOV eax, word ptr x не существует.


RE: Исследование героев - Sav - 11.02.2011 13:30

Понятно, спасибо.


RE: Исследование героев - MOP - 12.02.2011 17:11

(06.02.2011 03:11)Дьякон Wrote:  
(04.02.2011 15:29)MOP Wrote:  3. >=293512Ch (21AE12C + 787000). Основная динамическая память.
еще раз. Все секции - статические.
Ещё раз - а я что-то другое написал? Rolleyes
21AE12C + 787000 = 293512C = конец секции .data ВОГа, последней секции экзешника. Здесь кончается определённость и начинается динамический хаос.
Ладно, проехали.


RE: Исследование героев - GrayFace - 13.02.2011 00:31

(03.02.2011 10:25)Prayer Wrote:  Позарез нужно отключить или убрать из меню вообще кнопку "Показать дополнительные опции", чтоб на серваке ее тоже нельзя было использовать. Нашел дефку кнопки - gspbutt.def, текста на ней в genrltxt.txt.
Лучше для этого спользовать IDA (на IsoHunt можно взять). Там в Shift+F12 найти gspbutt.def, по xrefs перейти на место, где используется. Потом нажми Tab. Там же будут передаваться и координаты, и горячая клавиша, правда коды клавишь в Героях свои. Можно занулить её и сделть запредельными координаты, а лучше полностью перепрыгнуть код по созданию кнопки. Чтобы эти изменения внести, нужно сделать патч для Эры.


RE: Исследование героев - GrayFace - 14.02.2011 00:40

Это тоже не совсем правильно называть дин. памятью - это свободная память, в которой как выделяется динамическая память, так и грузятся всякие dll.

(13.09.2010 21:00)Sav Wrote:  Прошу прощения за тупой вопрос: динамический адрес может меняться при нескольких запусках программы на одном компьютере или только на разных компьютерах?
Может. На одном компе он часто остается одинаковым от запуска к запуску, но если, например, установить другой антивирус и т.п., легко может поменяться.

(04.02.2011 15:29)MOP Wrote:  1. < 401000h. В этих адресах работает система, поддерживая работу запущенного приложения. Также там находится стек. Запись/чтение там просто бесполезны и могут убить приложение.
Система на низком уровне использует адреса >7fffffffh (хотя может использовать только половину, если выставить это в манифесте ехе), системные библиотеки грузятся по адресам ниже 7fffffffh, но близким к этой границе. Адреса от 10000h до 401000h могут использоваться, у меня патч к редактору какое-то время, пока не вырос в размере, грузился по адресу 320000h - в этот адрес его поставил сам загрузчик Винды, я так и выставил. Только что для интереса сделал базовый адрес проги 30000h, где обычно стек - стек получился по адресу A0000h.

Подробнее про память и другие интересные вещи можно почитать у Рихтера: http://rouse.drkb.ru/books/rihter_2008.zip

По Асму вот эта книга должна быть хорошей: http://rouse.drkb.ru/books/marek.zip


RE: Исследование героев - GhostManSD - 14.02.2011 19:09

GrayFace, спасибо огромное!


RE: Исследование героев - MOP - 20.02.2011 16:55

GhostManSD Wrote:005CCED7 8B0C95 6CA36800 MOV ECX, DWORD PTR DS:[EDX*4+68A36C]
005CCEDE 51 PUSH ECX
005CCEDF |. 6A 01 PUSH 1
СТАЛО
Код:
005CCED7 3E:8B0C85 6CA36800 MOV ECX, DWORD PTR DS:[EAX*4+68A36C]
005CCEDF |. 6A 01 PUSH 1
Во избежание дальнейших недоразумений...
Если кодишь в Олли, да и не только в ней - не указывай лишних данных. В данном случае надо было убрать "DWORD PTR DS:", но ты указал Олли эту дополнительную ненужную инфу. В результате смысл команды не изменился, но машкод её вырос на 1 байт и затёр "PUSH ECX".
То есть, в затирании ты сам виноват. Внимательнее.


RE: Исследование героев - GhostManSD - 26.02.2011 07:09

Подскажите, пожалуйста, реально ли заставить WoG обращаться к текстовому файлу. Выглядит примерно так...
Сам файл (Click to View)
Формат файла (Click to View)

Например, чтобы при !!SN:X0/3/25/78 в переменную z78 подставлялось значение из строки №25 раздела №3 файла GMSDData...
...а при !!SN:X1/5/78/25 значение переменной z78 подставлялось в строку №25 раздела №5.


RE: Исследование героев - Sav - 26.02.2011 10:25

Думаю, можно, только алгоритм обращения к файлу и поиска строки придётся писать самому.


RE: Исследование героев - Berserker - 26.02.2011 18:39

ini-вариант не катит? Уже встроен в ЕРМ.


RE: Исследование героев - Sav - 26.02.2011 18:44

В смысле встроен?


RE: Исследование героев - Berserker - 26.02.2011 19:13

Команда есть в UN для чтения и записи в/из ini.


RE: Исследование героев - etoprostoya - 26.02.2011 21:06

Quote:!!UN:N5/#1/#2/#3/#4
Записать z-переменную в общую секцию файла wog.ini
Quote:!!UN:N6/#1/#2//#3/#4
Прочитать z-переменную из общей секции файла wog.ini
Quote:Так, для записи переменной z-1, названной "Главная_переменная", в файл "Мой.var" в папку GAMES (секция "MyLocalSettings") с опцией 4, используйте:
!!VRy1:S4;
!!VRz-1:S^Главная_переменная^;
!!VRz-2:S^MyLocalSettings^;
!!VRz-3:S^GAMES\My.var^;
!!UN:N5/z-1/y1/-2/-3;



RE: Исследование героев - MOP - 28.02.2011 16:33

Это что вообще?
Code:
Вог-хук №301:
00619BB1   E8 FA2E1600                        CALL mop.0077CAB0
00619BB6   90                                 NOP

0077CAB0   8B7424 0C                          MOV ESI,DWORD PTR SS:[ESP+C]
0077CAB4   8935 C4389302                      MOV DWORD PTR DS:[29338C4],ESI
0077CABA   60                                 PUSHAD
0077CABB   B8 00007000                        MOV EAX,mop.00700000
0077CAC0   3BC6                               CMP EAX,ESI
0077CAC2   77 11                              JA SHORT mop.0077CAD5
0077CAC4   8D05 C0389302                      LEA EAX,DWORD PTR DS:[29338C0]
0077CACA   3BF0                               CMP ESI,EAX
0077CACC   77 07                              JA SHORT mop.0077CAD5
0077CACE   33C0                               XOR EAX,EAX
0077CAD0   A3 C4389302                        MOV DWORD PTR DS:[29338C4],EAX
0077CAD5   61                                 POPAD
0077CAD6   8B35 C4389302                      MOV ESI,DWORD PTR DS:[29338C4]
0077CADC   85F6                               TEST ESI,ESI
0077CADE   C3                                 RETN
У меня из-за этого хука жёсткий баг прямо на старте игры, причём только тогда, если включены wav-звуки, а скрипт создаёт аллоки с помощью erautils.dll.
Если выпилить хук и восстановить ориг. код – всё абсолютно нормально.


RE: Исследование героев - baratorch - 02.07.2011 23:55

Хочу сделать для оффлайна заказ героя в таверне (герой который будет появляться в таверне после нанятого).
В связи с этим вопрос: как узнать какие герои доступны/недоступны для появления в таверне у игрока?
Может подскажет кто?


RE: Исследование героев - Berserker - 03.07.2011 01:11

Может.


RE: Исследование героев - gamecreator - 03.07.2011 01:26

Очевидно, проверить владельца и разрешение на карте.


RE: Исследование героев - baratorch - 03.07.2011 01:48

Berserker, спасибо.


RE: Исследование героев - Berserker - 03.07.2011 03:09

Тебе спасибо 118


RE: Исследование героев - MOP - 06.08.2011 17:12

(28.02.2011 16:33)MOP Wrote:  Это что вообще?
Code:
Вог-хук №301:
00619BB1   E8 FA2E1600                        CALL mop.0077CAB0
00619BB6   90                                 NOP

0077CAB0   8B7424 0C                          MOV ESI,DWORD PTR SS:[ESP+C]
0077CAB4   8935 C4389302                      MOV DWORD PTR DS:[29338C4],ESI
0077CABA   60                                 PUSHAD
0077CABB   B8 00007000                        MOV EAX,mop.00700000
0077CAC0   3BC6                               CMP EAX,ESI
0077CAC2   77 11                              JA SHORT mop.0077CAD5
0077CAC4   8D05 C0389302                      LEA EAX,DWORD PTR DS:[29338C0]
0077CACA   3BF0                               CMP ESI,EAX
0077CACC   77 07                              JA SHORT mop.0077CAD5
0077CACE   33C0                               XOR EAX,EAX
0077CAD0   A3 C4389302                        MOV DWORD PTR DS:[29338C4],EAX
0077CAD5   61                                 POPAD
0077CAD6   8B35 C4389302                      MOV ESI,DWORD PTR DS:[29338C4]
0077CADC   85F6                               TEST ESI,ESI
0077CADE   C3                                 RETN
У меня из-за этого хука жёсткий баг прямо на старте игры, причём только тогда, если включены wav-звуки, а скрипт создаёт аллоки с помощью erautils.dll.
Если выпилить хук и восстановить ориг. код – всё абсолютно нормально.
Так что, никто не знает?
Это хотя бы нужная вещь?


RE: Исследование героев - Berserker - 06.08.2011 17:17




RE: Исследование героев - kostya_76 - 10.12.2011 13:18

Может кто-нибудь подсказать, как правильно скомпилировать эту длл MoP'а в Дельфи7?

Quote:

Изменяю название библиотеки Win на Windows, остальные вроде не нужны, но можно и оставить, кроме VPUtils.
Еще не понятно, что такое {$FRAME-} в строке: PROCEDURE HOOK_tent; ASSEMBLER; {$FRAME-}, чтобы компилятор не ругался, приходится убирать.
Пробовал в разных папках компилить, в том числе и в папке с Эрой.

Компилится нормально, но адрес в созданном хуке получается левый - соответственно вылет при обращении. Если в Olly адрес перехода на функцию HOOK_tent поменять на нормальный - все работает.


RE: Исследование героев - Berserker - 10.12.2011 13:50

kostya_76, скомпилировал на VirtualPascal:
http://wikisend.com/download/110454/Tent.dll

FRAME соответствует опции W в Delphi. Utils не нужен.


RE: Исследование героев - kostya_76 - 10.12.2011 16:07

Berserker, спасибо, скачал, работает.
Только цель как-бы в другом: получить работоспособный пример-шаблон подключения длл к Эре. Причем на удобной для меня платформе. В этом смысле больше бы подошел билдерAb, но хотя-бы на дельфи для начала.
Пробовал скомпилировать эту длл в Virtual Pascal v2.1 - вообще ничего не получилось. Да и после попыток работы с ним вообще всякое желание пропадает этим заниматься.

Добавил эту самую директиву W- вместо FRAME- - не помогло.
Хотя бы знать в каком направлении копать Sm.
Имеет ли смысл пытаться в отладчике докопаться до алгоритма получения этого адреса: @HOOK_tent? Думаю, это не самый верный путь.


RE: Исследование героев - Berserker - 10.12.2011 16:22

Quote:получить работоспособный пример-шаблон подключения длл к Эре
Есть пример для GNU C++ и для Delphi.

В Эре 1.9+ Tools\Era\SDK


RE: Исследование героев - kostya_76 - 10.12.2011 17:35

Berserker, Так в примере подключение через длл ЕРМ-инструкций, я естественно смотрел этот пример и пробовал подключать.
Но интересует именно встраивание хуков, в частности создание с их помощью триггеров, как в примере МоР'а. Поэтому и хочу разобраться, почему не получается.

Или вот прикладной пример: нужно встраивать программу создания зеркальной карты для подмены исходной карты, созданной генератором прямо в игре. Может когда-нибудь до этого доберусь.


RE: Исследование героев - Berserker - 10.12.2011 18:53

Попробуйте посмотреть в Era\Tools\Era\Sources\Era 1.9 Delphi:
triggers.pas

А вообще, создание нового события - вещь не тривиальная. Нужно сперва в дизассемблере определить параметры, место перехвата и после уже писать сам перехват. Если вы для примера укажите адрес в коде игры, в который хотите вставить перехватчик, я приведу код для перехвата. При этом важно знать, в каких регистрах и адресах памяти на момент перехвата лежат нужные вам данные.


RE: Исследование героев - Berserker - 18.12.2011 21:42

Обновим тень перемещения:
493350 - F (0, 1); THISCALL;

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


RE: Исследование героев - Al_Mualim - 23.12.2011 02:04

(10.12.2011 13:50)Berserker Wrote:  kostya_76, скомпилировал на VirtualPascal:
http://wikisend.com/download/110454/Tent.dll
What this dll do?


RE: Исследование героев - Berserker - 23.12.2011 02:17

New !?FU29500 trigger for tent I suppose.


RE: Исследование героев - MOP - 10.02.2012 18:26

Уже несколько человек спрашивало…
Code:
; Обновить экран встречи героев
!!UN:C6962576/4/?y1; [6A3D90h] - swapManager
!!SN:E5957888/2/y1;
Не помню, но артефакты в слотах, вроде, обновляются отдельно.


RE: Исследование героев - kostya_76 - 12.02.2012 00:26

(10.12.2011 16:22)Berserker Wrote:  
Quote:получить работоспособный пример-шаблон подключения длл к Эре
Есть пример для GNU C++ и для Delphi.

В Эре 1.9+ Tools\Era\SDK
Как создать хук с помощью этого инструмента я понял. Вот только в Делфи у меня не получается создать форму в длл. Вылетает игра. В книгах обычно примеры создания форм в длл с вызовом из приложения, также написанного на Делфи .

В билдере получается форму создавать, в Делфи - хуки)

А код для GNU С++ в билдере не компилится.

Есть длл с хуком для подмены файла карты. После генерации карты, до загрузки. Подменял под отладчиком - работает.
Создаю форму. Вызываю Form1.Show(); хоть в обработчике хука, хоть при загрузке длл - вылет.
Так тоже не получается:
VAR AOwner: TComponent;
Form1 := TForm1.Create(AOwner);
Form1.Show();

Хотя в любом случае, программа для обработки карты написана на С++, и подключать ее в Делфи - это извращение.


RE: Исследование героев - kostya_76 - 12.02.2012 00:54

(12.02.2012 00:33)GreyGhost Wrote:  делфи это всего навсего расширение паскаля
Я как-бы в курсе)


(12.02.2012 00:33)GreyGhost Wrote:  а вот создание FORM(окна) для перехвата функции - это извращение.

   
Откуда такое смелое предположение о цели создания формы?
Кроме как для организации интерфейса, она мне не нужна)
В приведенном мною примере особой связи между хуком и созданием формы нет.

А вообще, спасибо за содержательный комментарий.


RE: Исследование героев - Berserker - 12.02.2012 13:16

GreyGhost, да брось. И чего ты пост потёр из Кино/Сериалы? )
kostya_76, а какие ошибки в билдере?


RE: Исследование героев - gamecreator - 12.02.2012 14:08

(12.02.2012 00:26)kostya_76 Wrote:  В билдере получается форму создавать, в Делфи - хуки)
так сделай две библиотеки Sm и вызывай одну из другой


RE: Исследование героев - kostya_76 - 12.02.2012 15:10

(12.02.2012 13:16)Berserker Wrote:  kostya_76, а какие ошибки в билдере?

Вот такие:
Я вообще не понимаю, что означает после подстановки строка:
typedef __declspec(align(1)) struct TTxtFile
А именно - что такое (align(1))

gamecreator Wrote:так сделай две библиотеки Sm и вызывай одну из другой

Если бы знал как, то наверное и хук смог бы написать на С++ без использования SDK.


RE: Исследование героев - Berserker - 12.02.2012 15:29

kostya_76, запрещает выравнивание полей в структуре по границе в 4 байта или более. Для билдера попробуй убрать мой макрос и обернуть эти структуры в:
Code:
#pragma pack(1)
...описание типа...
#pragma pack()



RE: Исследование героев - kostya_76 - 12.02.2012 16:10

Berserker, Так?
Ошибки указывают на строки с закрывающими фигурными скобками структур


RE: Исследование героев - gamecreator - 12.02.2012 16:33

обернуть - значит вложить в открывающую и закрывающую конструкцию
Code:
#pragma pack(1)
struct foobar
{
int foo;
double bar;
};
#pragma pack()


и вообще, почему там typedef?


RE: Исследование героев - Berserker - 12.02.2012 16:46

сишный стиль объявления.


RE: Исследование героев - gamecreator - 12.02.2012 16:53

не может того быть. нет typedef с одним параметром.


RE: Исследование героев - Berserker - 12.02.2012 17:45

Может.
http://stackoverflow.com/questions/612328/difference-between-struct-and-typedef-struct-in-c


RE: Исследование героев - gamecreator - 12.02.2012 18:13

там у typedef 2 параметра.


RE: Исследование героев - AVS - 12.02.2012 18:16

Интересно насколько сложно полностью перехватить создание случайных карт? (=встроить свой генератор, если я его допишу всетаки %) )


RE: Исследование героев - Sav - 12.02.2012 18:44

Если ты действительно напишешь хороший генератор, думаю желающие его встроить найдутся.


RE: Исследование героев - kostya_76 - 12.02.2012 20:08

Berserker, Еще ошибку выдает:



RE: Исследование героев - AVS - 12.02.2012 20:15

(12.02.2012 00:26)kostya_76 Wrote:  Создаю форму. Вызываю Form1.Show(); хоть в обработчике хука, хоть при загрузке длл - вылет.
Так тоже не получается:
VAR AOwner: TComponent;
Form1 := TForm1.Create(AOwner);
Form1.Show();

И не получится. Убери формы вообще и все связи с VCL.

Хотя в теории подружить VCL с героями возможно (но формы будут открываться отдельно от окна героев), а вот встроить их внутрь интерфейса нереально (если бы у окон героев были оконные хендлы, а их там AFAIK нет, то можно было бы вообще вставлять праактически любой виджет из VCL прямо на любое окно в игре)


RE: Исследование героев - kostya_76 - 12.02.2012 20:40

(12.02.2012 20:15)AVS Wrote:  И не получится. Убери формы вообще и все связи с VCL.

Хотя в теории подружить VCL с героями возможно (но формы будут открываться отдельно от окна героев), а вот встроить их внутрь интерфейса нереально (если бы у окон героев были оконные хендлы, а их там AFAIK нет, то можно было бы вообще вставлять праактически любой виджет из VCL прямо на любое окно в игре)

Само-собой это окно отдельно от окна героев должно открываться.


RE: Исследование героев - Berserker - 12.02.2012 21:02

Реквизит встроила VCL-ые формы в игру. zvslib1 использует формы билдера для новых воговских диалогов. Я, к сожалению, добился только глючного модального запуска и бросил.
kostya_76, замените __stdcall на WINAPI.


RE: Исследование героев - kostya_76 - 12.02.2012 21:10

Berserker, Не помогает - такое сообщение об ошибке.
Собственно, мне пока нужен только хук, попробую сейчас функцию
typedef __stdcall void (*THook) (void* HandlerAddr, int HookType, int PatchSize, void* CodeAddr);


RE: Исследование героев - AVS - 12.02.2012 21:22

(12.02.2012 20:40)kostya_76 Wrote:  Само-собой это окно отдельно от окна героев должно открываться.

Тогда при запуске в хуке Application.Initialize. Еще возможно необходимо установить Application.Handle на реальный хендл героев.
Формы создавать Tform1.Create(nil) и ставить FreeOnRelease. Уже это должно работать.

(12.02.2012 21:02)Berserker Wrote:  Реквизит встроила VCL-ые формы в игру.

Ну если хукнуть главный цикл и "подсунуть под" окно героев VCL форму (чтобы окно героев было дочерним) потом наверное переписав обрабтку мыши и клавиатуры может и получится.

(12.02.2012 21:02)Berserker Wrote:  zvslib1 использует формы билдера для новых воговских диалогов. Я, к сожалению, добился только глючного модального запуска и бросил.

Увы я только мельком поглядел на исходники самого вога - этой либы в них нет - а в самом воге диалоги реализованы через грязные хаки с VMT классов внурти движка героев.


RE: Исследование героев - baratorch - 12.02.2012 21:43

kostya_76
__stdcall void замени на void __stdcall


RE: Исследование героев - kostya_76 - 12.02.2012 22:01

(12.02.2012 21:43)baratorch Wrote:  kostya_76
__stdcall void замени на void __stdcall

Да, теперь копмилится. правда кучу предупреждений выдает:
При загрузке длл вот такая штука выскакивает:
Хотя и работает впоследствии: обЪекты удаляются в игре.


RE: Исследование героев - kostya_76 - 13.02.2012 00:39

А при попытке создания хука ошибки линковщика:



RE: Исследование героев - Sav - 13.02.2012 00:54

Мне для работы пришлось переименовать era.cpp в era.h.


RE: Исследование героев - kostya_76 - 13.02.2012 18:25

(13.02.2012 00:54)Sav Wrote:  Мне для работы пришлось переименовать era.cpp в era.h.

От появления предупреждений при линковке это действительно избавило. Но не более того.

От ошибок линковщика, приведенных на последнем скрине удалось избавиться, убрав галочки "Use VCL" и "Multi Threaded" при создании шаблона библиотеки мастером.
Но хук не создается, и вообще секции этой длл в памяти не появляются.

В предыдущем примере с удалением объектов с помощью ЕРМ-инструкций также в памяти длл не видно, но тем не менее объекты удаляются.


RE: Исследование героев - Berserker - 13.02.2012 20:45

Я залью сегодня обновлённый вариант.


RE: Исследование героев - Berserker - 13.02.2012 22:50

http://wikisend.com/download/364322/SDK.rar
Переписан заголовочный файл, обновлён пример, добавлена демонстрация установки перехватчика.

Code:
#include <windows.h>
#include "Era.h"
  
using namespace Era;
  
const int ADV_MAP   = 37;
const int CTRL_LMB  = 4;
const int LMB_PUSH  = 12;

void __stdcall OnAdventureMapLeftMouseClick (TEvent* Event)
{
  ExecErmCmd("CM:I?y1 F?y2 S?y3;");
  if ((y[1] == ADV_MAP) && (y[2] == CTRL_LMB) && (y[3] == LMB_PUSH))
  {
    ExecErmCmd("CM:R0 P?y1/?y2/?y3;");
    ExecErmCmd("UN:Ey1/y2/y3;");
    if (f[1])
    {
      ExecErmCmd("UN:Oy1/y2/y3/1;");
      ExecErmCmd("IF:L^{~red}Object was deleted!{~}^;");
    }
  }
}

BOOL __stdcall Hook_BattleMouseHint (THookContext* Context)
{
  ExecErmCmd("IF:L^{~gold}This is a battle hint!{~}^;");
  return EXEC_DEF_CODE;
}

extern "C" __declspec(dllexport) BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID lpReserved)
{
  if (reason == DLL_PROCESS_ATTACH)
  {
    ConnectEra();
    RegisterHandler(OnAdventureMapLeftMouseClick, "OnAdventureMapLeftMouseClick");
    ApiHook((void*) Hook_BattleMouseHint, HOOKTYPE_BRIDGE, (void*) 0x74fd1e);
  }
  return TRUE;
};



RE: Исследование героев - kostya_76 - 14.02.2012 00:12

Berserker, Все равно не получается )
В смысле, компилится нормально, только это предупреждение также осталось:
[C++ Warning] Era.h(130): W8058 Cannot create pre-compiled header: initialized data in header
При запуске то же сообщение:
И в памяти, соответственно , длл не появляется.
Может я что-то не так делаю? Бросаю созданную длл в папку EraPlagins. Все остальные плагины работают.


RE: Исследование героев - Berserker - 14.02.2012 01:38

Плагин должен иметь расширение *.era. Ну а предупреждение компилятора нормальное.


RE: Исследование героев - kostya_76 - 14.02.2012 16:03

(14.02.2012 01:38)Berserker Wrote:  Плагин должен иметь расширение *.era. Ну а предупреждение компилятора нормальное.

На работоспособные длл изменение расширения на .era никак не влияет: работают и так и так.
А вот в данном примере смена расширения приводит к вылету после сообщения об исключении.
Если в DllMain оставить только вызов ConnectEra() , тогда нормально загружается.

Berserker, а ты пробовал сам скомпилировать и запустить этот пример? Работает?


RE: Исследование героев - Berserker - 14.02.2012 17:02

kostya_76, да, причём как часы. 20 КБ размер выходит.

Quote:На работоспособные длл изменение расширения на .era никак не влияет: работают и так и так.
Не так. *.dll - это старые плагины, *.era - новые. Новые грузятся ДО вога и основаны на системе событий.

А вы вообще на какой версии эры экспериментируете? Я видел в пути WT.


RE: Исследование героев - kostya_76 - 14.02.2012 17:20

(14.02.2012 17:02)Berserker Wrote:  kostya_76, да, причём как часы. 20 КБ размер выходит.

Это, я так понимаю, в GNU компилилось , а не в билдере? У меня весит 9 КБ.

(14.02.2012 17:02)Berserker Wrote:  Не так. *.dll - это старые плагины, *.era - новые. Новые грузятся ДО вога и основаны на системе событий.
В данном примере это принципиально? Пример на Делфи прекрасно работает без переименований.

(14.02.2012 17:02)Berserker Wrote:  А вы вообще на какой версии эры экспериментируете? Я видел в пути WT.
Era 1.9, экзешник насколько помню потом еще отдельно скачивал.
А установлено в папку с WT.


RE: Исследование героев - Berserker - 14.02.2012 17:52

Я не знаю, что там чудим билдер, но суть проста. Era.dll загружается, получаются адреса её функций и вызываются. Если мне предоставится возможность проверить на билдере, я попробую. Дома его нет.


RE: Исследование героев - kostya_76 - 14.02.2012 18:20

(14.02.2012 17:52)Berserker Wrote:  Я не знаю, что там чудим билдер, но суть проста. Era.dll загружается, получаются адреса её функций и вызываются. Если мне предоставится возможность проверить на билдере, я попробую. Дома его нет.

Для меня это не так уж просто) Попробую еще поковыряться в опциях. Можно еще мап-файл поизучать)


RE: Исследование героев - kostya_76 - 16.02.2012 02:56

Berserker, Если поменять hEra = (HINSTANCE) v[1]; на hEra = LoadLibrary("era.dll");,
то все работает, кроме функции ApiHook - Вероятно ее нет в библиотеке)
А Функция Hook работает, ну и остальные вроде тоже.

Адрес hEra указывал куда-то в середину секции, и в результата все GetProcAddress возвращали нули.


RE: Исследование героев - Berserker - 16.02.2012 12:11

ApiHook в Эре 2)


RE: Исследование героев - totkotoriy - 19.02.2012 13:00

Может у кого есть рабочий код на с++ какого-либо хука, который затем передает управление ERM триггеру?


RE: Исследование героев - gamecreator - 19.02.2012 13:22

так в Эре вроде есть функция, выполняющая ерм. вот с помощью нее и вызвать триггер.


RE: Исследование героев - totkotoriy - 19.02.2012 13:24

(19.02.2012 13:22)gamecreator Wrote:  так в Эре вроде есть функция, выполняющая ерм. вот с помощью нее и вызвать триггер.
Как?


RE: Исследование героев - Sav - 19.02.2012 13:27

ExecErmCmd ("FUxxxx:P;");


RE: Исследование героев - totkotoriy - 19.02.2012 14:01

(19.02.2012 13:27)Sav Wrote:  ExecErmCmd ("FUxxxx:P;");
Дык можете рабочий пример написать? А то я так долго мучатся буду. Что эта функция делает? Вызывает хук и запускает по нему триггер?


RE: Исследование героев - gamecreator - 19.02.2012 14:26

функция выполняет ЕРМ-код. рабочий пример:
ExecErmCmd ("FU12345:P;");
выполнит ЕРМ-код !!FU12345:P;


RE: Исследование героев - gamecreator - 19.02.2012 14:36

http://wforum.heroes35.net/showthread.php?tid=3155&pid=62813#pid62813


RE: Исследование героев - totkotoriy - 19.02.2012 14:43

(19.02.2012 14:26)gamecreator Wrote:  функция выполняет ЕРМ-код. рабочий пример:
ExecErmCmd ("FU12345:P;");
выполнит ЕРМ-код !!FU12345:P;
А где взять era.cpp тогда? И надо ли восстанавливать данные затертого хука?


RE: Исследование героев - gamecreator - 19.02.2012 14:58

причем тут era.cpp? причем тут хук? это не хук вообще, это блокирующая функция, которая выполняет команду ерм


RE: Исследование героев - Sav - 19.02.2012 14:59

totkotoriy, не пойму, что тебе нужно. Я создавал триггер на паскале, но основная часть там - ассемблер, поэтому я могу без особых затрат времени перевести его на c++ и показать тебе код. Нужно?


RE: Исследование героев - totkotoriy - 19.02.2012 15:51

(19.02.2012 14:59)Sav Wrote:  totkotoriy, не пойму, что тебе нужно. Я создавал триггер на паскале, но основная часть там - ассемблер, поэтому я могу без особых затрат времени перевести его на c++ и показать тебе код. Нужно?
Да, я про это и говорю. Код хука на С++ я уже написал, мне нужен теперь рабочий код на ассемблере для вызова триггера в ERM.


RE: Исследование героев - gamecreator - 19.02.2012 16:21

что и откуда ты вообще хочешь вызвать?


RE: Исследование героев - Sav - 19.02.2012 18:45

totkotoriy, смотри там: http://wforum.heroes35.net/showthread.php?tid=2587


RE: Исследование героев - kostya_76 - 19.02.2012 19:21

(19.02.2012 15:51)totkotoriy Wrote:  Да, я про это и говорю. Код хука на С++ я уже написал, мне нужен теперь рабочий код на ассемблере для вызова триггера в ERM.

Я ж тебе показывал пример. Весь код создания триггера это 4 строчки:

PUSH 29500 //номер ERM-функции. Меняйте на любой доступный.
MOV EAX, 0x74CE30
CALL EAX //вызываем C_FUNC_ZVS_CALLFU
ADD ESP, 4

Просто в примере с палаткой добавлены дополнительные операции по вызову параметров для использования в создаваемом триггере.

Вот пример, работающий с адресом 4074AC, который ты давал:
Добавил в скрипт триггер - срабатывает где-то после генерации карты.
Только хук в этом примере создан с помощью Эры 1.9. То есть еще файл Era.h нужен. Немного выше есть ссылка на него от Берсеркера.


RE: Исследование героев - totkotoriy - 22.02.2012 17:38

(19.02.2012 19:21)kostya_76 Wrote:  файл Era.h нужен. Немного выше есть ссылка на него от Берсеркера.
Спасибо, но я не могу нигде найти эту библиотеку.

И еще хотел спросить что за адрес 6992D0 в этой команде mov eax,DWORD PTR DS:[0X6992D0]? Он для другого хука будет такой же?
Костян, и можешь еще прислать скомпилиный этот код? я скомпилил его чуть по другому (без era.h) и у меня все равно в игре вылетает(


RE: Исследование героев - MOP - 22.02.2012 19:30

(22.02.2012 17:38)totkotoriy Wrote:  И еще хотел спросить что за адрес 6992D0 в этой команде mov eax,DWORD PTR DS:[0X6992D0]? Он для другого хука будет такой же?
heroWindowManager.
Для каждого хука свой затираемый этим хуком код.


RE: Исследование героев - Sav - 22.02.2012 21:48

era.h, которую точно принимает MSVC++ 9.0 прилагается к тому, что я делал выше.

totkotoriy, если ты не осилил плагин, которыя я для тебя переписал, вот упрощённый и чуть более плотно прокомментированный вариант. Тут создаётся триггер, в него передаются и из него принимаются параметры !!SN:X. Разумеется, тут ничего особенного не происходит, но триггер вызывается.
Это код на MSVC++ 9.0, по идее должен компилироваться, если положить рядом era.h, расширение плагина для работоспособности нужно изменять на "era" после компиляции.



RE: Исследование героев - Berserker - 22.02.2012 22:22

//DisableThreadLibraryCalls(hInst);
Автоматом вызывается для *.era модулей.


RE: Исследование героев - Sav - 22.02.2012 22:39

Да, я отстал от жизни, и SDK у меня там для 1.9. Sm Ну, впрочем это непринципиально, старое, по крайней мере, то, что я использовал, не менялось.


RE: Исследование героев - kostya_76 - 22.02.2012 23:14

(22.02.2012 17:38)totkotoriy Wrote:  Костян, и можешь еще прислать скомпилиный этот код? я скомпилил его чуть по другому (без era.h) и у меня все равно в игре вылетает(

Вот
Только работать будет лишь под Эрой, коль скоро функция оттуда вызывается.

Кстати, имена людей коверкать нехорошо Moral


RE: Исследование героев - totkotoriy - 23.02.2012 13:37

(22.02.2012 21:48)Sav Wrote:  totkotoriy, если ты не осилил плагин, которыя я для тебя переписал, вот упрощённый...
Попробуй тут осилить когда кто на чем пишет, а ты ни того не другого не знаешь... Спасибо, будем разбираться...

(22.02.2012 23:14)kostya_76 Wrote:  
(22.02.2012 17:38)totkotoriy Wrote:  Костян, и можешь еще прислать скомпилиный этот код? я скомпилил его чуть по другому (без era.h) и у меня все равно в игре вылетает(

Вот
Только работать будет лишь под Эрой, коль скоро функция оттуда вызывается.

Кстати, имена людей коверкать нехорошо Moral
По мне так Костян - это ещё уважительнее чем просто Костя...
Спасибо, всё работает, наверное я ещё и неправильно код на С++ в прошлый раз написал.
Может ещё обясните как вычесляется адрес (например 0X6992D0), который затирается хуком?


RE: Исследование героев - Sav - 23.02.2012 14:27

totkotoriy Wrote:Может ещё обясните как вычесляется адрес (например 0X6992D0), который затирается хуком?
Эм, смотрится в дизассемблере, что находится по адресу, куда будет ставиться хук и дописывается в начало или конец кода хука.


RE: Исследование героев - Sav - 04.03.2012 12:37

Кто-нибудь может дать описание всем полям из cranim.txt или хотя бы некоторым (кроме x-смещения прямоугольника с количеством существ, периода между проигрываниями анимации кривляния и периода анимации движения)? В принципе я и сам разберусь, но если кто это уже сделал, не хотелось бы зря тратить время.


RE: Исследование героев - totkotoriy - 06.03.2012 23:51

(10.02.2012 18:26)MOP Wrote:  Уже несколько человек спрашивало…
Code:
; Обновить экран встречи героев
!!UN:C6962576/4/?y1; [6A3D90h] - swapManager
!!SN:E5957888/2/y1;
Не помню, но артефакты в слотах, вроде, обновляются отдельно.
А может подскажите тогда ещё как обновлять отряды у героев в экране встречи? А то почему-то они таки не обновляются 33...


RE: Исследование героев - Sav - 09.03.2012 21:29

Раз никто не знает насчёт cranim.txt, вот я разобрал структуру, к которой это сводится в игре:


Такие структуры хранятся для каждого существа по адресу, записанному в 0x67FF74, а так же входят в структуру стеков в бою по смещению 110h.


RE: Исследование героев - Berserker - 09.03.2012 21:30

Ценное исследование, спасибо!


RE: Исследование героев - Berserker - 20.03.2012 15:13

В оконном режиме без ХД:
1) Нажать на усыпить героя.
2) Свернуть окно мышкой
3) Развернуть
4) Панель ресурсов и статистики героя пустая - неперерисованнная.

Правый щелчок на карте приключений красит кнопку усыпления в зелёный цвет и правильно обновляет экран.


RE: Исследование героев - Berserker - 20.03.2012 15:21

Домик вместо кнопки "усыпить".


RE: Исследование героев - Sav - 20.03.2012 16:24

Структура стрелковой башни в бою.

Хранится в виде 3-элементного массива структур в структуре BattleMgr (*(0x699420)) по смещению 81272. Индекс башни в массиве определяется dword`ом по +38h в структуре её стека (для остальных стеков это поле - позиция на поле боя). 254 - индекс 0, 251 - индекс 1, 255 - индекс 2.


RE: Исследование героев - Berserker - 20.03.2012 16:30

Quote:254 - индекс 0, 251 - индекс 1, 255 - индекс 2.
Угу, где-то писал об этом. Тоже хак.


RE: Исследование героев - Sav - 20.03.2012 23:18

Функция, рассчитывающая бонус к урону для башни.

Code:
double __thiscall A0_Battle_Stack_Get_ArrowTower_DamageBonus_To_sub_443AB0(struct_BattleStack *this, char IsShot)
{
  double Shild_Spells_Mult_v2; // st7@3
  int Controller_v3; // eax@10
  int Hero_v4; // eax@12
  double Base_mult_v6; // [sp+0h] [bp-8h]@1

  *(_QWORD *)&Base_mult_v6 = 0x3FF0000000000000ui64;// double 1.0
  if ( IsShot )
  {
    if ( !this->Spells_Lengths_adword198[28] )  // Воздушный щит
      goto CHECK_STONE_SPELL_L7;
    Shild_Spells_Mult_v2 = this->AirShieldSpell_Modif_dword4BC;
  }
  else
  {
    if ( !this->Spells_Lengths_adword198[27] )  // Щит
      goto CHECK_STONE_SPELL_L7;
    Shild_Spells_Mult_v2 = this->ShieldSpell_Modif_dword4B8;
  }
  Base_mult_v6 = Shild_Spells_Mult_v2;
CHECK_STONE_SPELL_L7:
  if ( this->Spells_Lengths_adword198[70] )     // Окаменение
    Base_mult_v6 = Base_mult_v6 * 0.5;
  if ( this->Spells_Lengths_adword198[60] )     // Гипноз
    Controller_v3 = 1 - this->Owner_dwordF4;
  else
    Controller_v3 = this->Owner_dwordF4;
  Hero_v4 = *(_DWORD *)(A0_BattleMgr_dword_699420 + 4 * Controller_v3 + 21452);
  if ( Hero_v4 )
    Base_mult_v6 = A0_Hero_GetDefense_SecSkill_sub_4E4580(Hero_v4) * Base_mult_v6;
  return Base_mult_v6;
}

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

Так же несложно заметить, что в функции рассчитывается всего 3 вещи - воздушный щит (IsShot во всех стандартных вызовах = 1), окаменение и вторичный навык Защита (со специализацией) героя-хозяина цели. Ни атака (а ведь у башни заявлено 10 атаки) с защитой, ни вторичные навыки героя-хозяина башни не учитываются.

Для Хоты я заменил все 3 вызова этой функции на нормальную A0_Battle_Stack_CalcDamageModifs_sub_443C60 (пришлось искать недостающие параметры, но это несложно). Это и исправит баги, и несколько усилит башни (учитывающиеся 10 атаки - не так мало + учёт атаки обороняющегося героя).


RE: Исследование героев - Berserker - 20.03.2012 23:26

Хотелось бы в Эру по умолчанию встроить. Двоичной заплаткой не обойтись?


RE: Исследование героев - Sav - 20.03.2012 23:28

Могу дать код, но он основан на Patcher_x86. Там несколько хуков.
Да, и он на C++.


RE: Исследование героев - Berserker - 20.03.2012 23:59

Давай.


RE: Исследование героев - etoprostoya - 21.03.2012 00:36

(20.03.2012 23:18)Sav Wrote:  Функция, рассчитывающая бонус к урону для башни.

Code:
double __thiscall A0_Battle_Stack_Get_ArrowTower_DamageBonus_To_sub_443AB0(struct_BattleStack *this, char IsShot)
{
  double Shild_Spells_Mult_v2; // st7@3
  int Controller_v3; // eax@10
  int Hero_v4; // eax@12
  double Base_mult_v6; // [sp+0h] [bp-8h]@1

  *(_QWORD *)&Base_mult_v6 = 0x3FF0000000000000ui64;// double 1.0
...

А там точно double, а не float? Раньше думал, что в игре используется только float32.


RE: Исследование героев - Sav - 21.03.2012 00:52

Code:
// При подсчёте бонуса к урону стрелковой башни...
int __stdcall HookOn_ArrowTowerCalcDamageBonuses(LoHook* h, HookContext* c)
{
  // Вызываем общую функцию подсчёта урона.
  c->eax = (*(_BattleStack_**)(c->ebp - 36))->Calc_Damage_Bonuses((_BattleStack_*)(c->ebx), *(_int32_*)(c->ebp + 8), TRUE, FALSE, 0, 0);
  
  c->return_address = 0x46594B;
  
  return NO_EXEC_DEFAULT;
}



// При подсчёте бонуса к урону стрелковой башни ИИ (1)...
int __stdcall HookOn_ArrowTowerCalcDamageBonusesAI1(LoHook* h, HookContext* c)
{
  // Выполняем затёртую команду.
  c->edi = c->esi - 688;
  
  // Вызываем общую функцию подсчёта урона.
  c->eax = ((*(_BattleMgr_**)(c->ebp - 16))->stack[(*(_BattleMgr_**)(c->ebp - 16))->current_side][(*(_BattleMgr_**)(c->ebp - 16))->current_stack_ix]).Calc_Damage_Bonuses((_BattleStack_*)(c->edi), *(_int32_*)(c->ebp + 16), TRUE, TRUE, 0, 0);
  
  c->return_address = 0x41E3AB;
  
  return NO_EXEC_DEFAULT;
}


// При подсчёте бонуса к урону стрелковой башни ИИ (2)...
int __stdcall HookOn_ArrowTowerCalcDamageBonusesAI2(LoHook* h, HookContext* c)
{
  // Выполняем затёртую команду.
  c->edi = c->esi - 688;
  
  // Вызываем общую функцию подсчёта урона.
  c->eax = ((*(_BattleMgr_**)(c->ebp - 16))->stack[(*(_BattleMgr_**)(c->ebp - 16))->current_side][(*(_BattleMgr_**)(c->ebp - 16))->current_stack_ix]).Calc_Damage_Bonuses((_BattleStack_*)(c->edi), *(_int32_*)(c->ebp + 16), TRUE, TRUE, 0, 0);
  
  c->return_address = 0x41E4E7;
  
  return NO_EXEC_DEFAULT;
}
Code:
Patcher* _P = GetPatcher();
PatcherInstance* _PI = _P->CreateInstance("Choose_Name");
Code:
// При подсчёте бонуса к урону стрелковой башни...
_PI->WriteLoHook(0x465934, HookOn_ArrowTowerCalcDamageBonuses);

// При подсчёте бонуса к урону стрелковой башни ИИ (1)...
_PI->WriteLoHook(0x41E38E, HookOn_ArrowTowerCalcDamageBonusesAI1);

// При подсчёте бонуса к урону стрелковой башни ИИ (2)...
_PI->WriteLoHook(0x41E4CA, HookOn_ArrowTowerCalcDamageBonusesAI2);

Не хочу менять сам код (наделаю синтаксических ошибок ещё), поэтому поясню отдельно: _int32_ = int; TRUE = 1; FALSE = 0.
Code:
struct _BattleStack_
{
...
    // Подсчёт добавок к наносимому урону (возвращается новый урон).
    // Enemy - указатель на атакуемый стек.
    // BaseDamage - начальный урон.
    // IsShot - является ли атака выстрелом (TRUE - является).
    // Virtual - является ли подсчёт производимым ИИ (TRUE - является).
    // WayLength - пройденный путь до цели (для расчёта кавалерийского бонуса).
    // out_FireshieldDamage - указатель на переменную, в которую в результате работы функции запишется урон от огненного щита (0 - не подсчитывать).
    inline _int32_ Calc_Damage_Bonuses(_BattleStack_* Enemy, _int32_ BaseDamage, _bool8_ IsShot, _bool8_ Virtual, _int32_ WayLength, _int32_* out_FireshieldDamage)
    {
      return CALL_7(_int32_, __thiscall, 0x443C60, this, Enemy, BaseDamage, IsShot, Virtual, WayLength, out_FireshieldDamage);
    }
...
}
_BattleMgr_.stack = +21708, массив 2 на 21 стеков (каждый - по 1352 байта).
_BattleMgr_.curr_stack_ix = +78524
_BattleMgr_.current_side = +78528


Так же, как видно, для получения стека башни ИИ приходится брать текущий стек. Но если эта ИИ-функцкци вызывается только стандартно из геройского кода, то это заведомо правильный способ.

etoprostoya Wrote:А там точно double, а не float? Раньше думал, что в игре используется только float32.
64 тоже используется, в основном в промежуточных вычислениях. Хотя конкретно в этом случае не знаю, но, думаю, Ида правильно определила, тем более в такой маленькой функции.


RE: Исследование героев - etoprostoya - 21.03.2012 10:58

Понятно. Ида просто не может отличить код для double от кода для float, если это не SSEx. Код для 64- и 32- битных плавающих числе отличается только в инициализации.


RE: Исследование героев - kostya_76 - 21.03.2012 23:33

Подскажет кто-нибудь, почему триггер в данной функции срабатывает только со второй генерации случайной карты?

Врезка идет сразу после нажатия кнопки "начать" перед генерацией карты по адресу 0x5863ba.
Если то же самое сделать с помощью функции Эры ExecErmCmd, то срабатывает нормально - при первой же генерации.

В данном случае нужно получить значение одной из ВОГ-опций.
Это можно попробовать сделать и без ЕРМ, но возни много.
И, самое главное, что дальше после генерации карты нужно будет организовать интерфейс с помощью ВОГ-диалога, там уже по любому ЕРМ нужен.

Зависимость от Эры не устраивает, т.к. скорее всего программа будет использоваться в ТЕ/WT.


RE: Исследование героев - gamecreator - 22.03.2012 01:12

кто-нибудь знает как получить указатель на массив героев?


RE: Исследование героев - Sav - 22.03.2012 11:43

Разная инфа хранится в разных массивах. Основной: *(_ptr_*)0x699538 + 0x21620 (размер элемента: 1170 байт).


RE: Исследование героев - Sav - 28.03.2012 16:37

В начале 2^32 - 1 раунда все непризванные стеки на поле боя погибнут (призванные сделают это в начале 2^32 - 1 раунда, считая с момента призыва). Это связано с полем, отвечающим за оставшиеся раунды жизни клонов, которое при инициализации -1, для клона отдельно устанавливается, и при уменьшении которого нет никаких проверок.


RE: Исследование героев - Algor - 28.03.2012 18:20

(28.03.2012 16:37)Sav Wrote:  В начале 2^32 - 1 раунда все непризванные стеки на поле боя погибнут
От черт.... значит нельзя бесконечно смотреть на 2х дерущихся троллей 118
Я кстати на df2 упоминал о подобном "переполнении" при споре, можно ли гарпией ведьмой при определенном сочетании препятствий на поле боя завалить 100500 бегемотов. Хотя, за миллиард ходов конкретно 100500 бегемотов лягут...


RE: Исследование героев - Sav - 28.03.2012 19:25

Ну, бегемоты-то всё равно умрут в результате. Sm


RE: Исследование героев - gamecreator - 29.03.2012 21:36

(28.03.2012 18:20)Algor Wrote:  От черт.... значит нельзя бесконечно смотреть на 2х дерущихся троллей 118
даже если раунд будет занимать 1 секунду, тебе хватит раундов для непрерывного просмотра в течении 136 лет Sm


RE: Исследование героев - Sav - 29.03.2012 23:06

Возможно, быстрая битва не предусматривает другого выхода из подобных ситуаций.


RE: Исследование героев - Berserker - 01.04.2012 15:55

Sav, надеюсь это корректно, я просто 3 байта меняю для башен, превращая 3 деления в три умножения.
В битве работает.


RE: Исследование героев - Sav - 01.04.2012 18:00

Это корректно, но в этом случае не учитывается атака башен (заявленная как 10 и на самом деле такая) и защита цели.


RE: Исследование героев - kostya_76 - 01.04.2012 21:15

Есть у кого мысли по поводу этого вопроса?
Не стесняемся, если кто подскажет, тому за это ничего не будет )

А то подключение программы зеркалирования карт практически готово, только вышеозначенная проблема возникла.
Пробовал разобраться, как в Эре реализована функция ExecErmCmd, но слишком сложно для меня, да и нет необходимости ее повторять. Нужно как-то инициировать выполнение ЕРМ кода из скрипта.


RE: Исследование героев - Berserker - 01.04.2012 21:32

Quote:Это корректно, но в этом случае не учитывается атака башен (заявленная как 10 и на самом деле такая) и защита цели.
Так она и без нас, по ходу, не считается. Просто деление на умножение вернуть уже достаточно. А ещё микробонус от разницы между атакой и защитой считать....имхо не стоит.

kostya_76, вы закомментировали получение опции, поэтому в v1 у вас мусор. Найдите адрес массива опций и обращайтесь к нему напрямую.


RE: Исследование героев - kostya_76 - 01.04.2012 21:59

(01.04.2012 21:32)Berserker Wrote:  kostya_76, вы закомментировали получение опции, поэтому в v1 у вас мусор. Найдите адрес массива опций и обращайтесь к нему напрямую.

Да нет, это я закомментировал строчку с функцией Эры, чтобы показать, что с ней работает с первого раза. А получение опции идет с помощью той же ЕРМ команды, расположенной в скрипте в функции 29501, вызов которой есть в коде.
Все работает, но только со второй генерации после загрузки героев.

А адрес опции найти-то нетрудно, но обращение к ней нужно делать так, чтобы это работало впоследствии при любом изменении количества ВОГ-опций. Что у меня с ходу не получилось. Не знаю, как по номеру опции найти адрес.

И дело не в ВОГ-опции, это как пример - дальше мне нужен ВОГ-диалог для бана героев, ввода еще некоторых параметров.

Может быть загрузка скриптов идет только после загрузки карты?
Тогда получается нужно все-таки делать аналог ExecErmCmd из Эры?
Или может быть как-то инициировать загрузку скриптов до загрузки карты?


RE: Исследование героев - Berserker - 01.04.2012 23:10

Quote:Может быть загрузка скриптов идет только после загрузки карты?
Да.

Quote:Тогда получается нужно все-таки делать аналог ExecErmCmd из Эры?
Да. При чём скорее всего ещё и вызывать процедуры очистки и инициализации ЕРМ. Только диалог - это ещё и события, а события - уже Эра или полноценно загруженный скрипт.

Quote:Или может быть как-то инициировать загрузку скриптов до загрузки карты?
Думал уже над этим не раз, но на деле воговская процедура FindErm очень уж привязана к карте/сохранёнке.


RE: Исследование героев - kostya_76 - 01.04.2012 23:59

(01.04.2012 23:10)Berserker Wrote:  Да. При чём скорее всего ещё и вызывать процедуры очистки и инициализации ЕРМ. Только диалог - это ещё и события, а события - уже Эра или полноценно загруженный скрипт.

А события для чего? Вот пример скрипта выбора героев:
Тут вроде нет событий никаких.

А Эру к WT подключить можно как-нибудь?

Иначе остается вариант все-таки вызывать свое окно, от чего хотелось уйти, либо оставлять необходимость предварительной загрузки любой карты.


RE: Исследование героев - Sav - 02.04.2012 00:05

Berserker Wrote:Так она и без нас, по ходу, не считается. А ещё микробонус от разницы между атакой и защитой считать....имхо не стоит.
Да, не считается. Но это ошибка, иначе бы не писалось в описании по ПКМ, что у башен атака 10.
Бонус не такой уж и мелкий, по слабым существам на треть вполне урон может увеличить. А если есть опыт башен и т. п., то уж и тем более. Кроме того, в общей функции теоретически могут срабатывать какие-нибудь новые защитные способности существ, поэтому её следует использовать, чтобы башня их не ломала. Разницы в скорости я не заметил.
Ну, во всяком случае, в Хоте я реализовал так, как считаю нужным. А в Эре, учитывая, что перед ней изначально не ставились задачи модификации геймплея, и мини-исправления может быть вполне достаточно.


RE: Исследование героев - Berserker - 02.04.2012 20:39

Quote:А события для чего?
Trigger = событие. Список событий формируется при загрузки скриптов уже после загрузки карты.

Quote:А Эру к WT подключить можно как-нибудь?
Без понятия, как там Асм сделал.


RE: Исследование героев - Sav - 03.04.2012 20:07

Кто-нибудь знает, чем занимается IFC20.dll, функции CImmProject__CreateEffect, CImmCompoundEffect__Start (вызовы в функции 0x4B6750)? У меня они вроде бы вообще не выполняются из-за неуспешного вызова инциализации этого CImmProject, поэтому я не могу так определить, что они делают.


RE: Исследование героев - Sav - 04.04.2012 19:50

Похоже, IFC - это Immersion Foundation Classes, 20 - видимо, версия 2.0. Но что это всё же такое по сути, я так и не смог разобрать.


RE: Исследование героев - solitaire345 - 04.04.2012 23:30

IFC library is responsible for kinetic feedback on gamepads/wheels and other game controllers. Quite strange that it is used for turn-based game. I managed to trigger that function on spell casting and hovering mouse on town buildings.

The branch that calls IFC functions is never executed because dword at 0x00696DD4 is always null and the function returns immediately to not dereference that pointer. 0x00696DD4 is probably pointer to device that supports Immersion Foundation Classes.
Trying to jump to other branch results in access violation.


RE: Исследование героев - Sav - 05.04.2012 00:44

Thank you for explanation.


RE: Исследование героев - Sav - 05.05.2012 23:34

Кто-нибудь знает, зачем нужно поле setup (первые 4 байта) у структур, таких, как банк существ, и зачем в конструкторе этому полю присваивается значение неинициализированной стековой переменной?


RE: Исследование героев - Berserker - 06.05.2012 00:17

Не знаю, но твоё сообщение напомнило мне об одной мысли, что хотел сказать по поводу твоего последнего модуля. Универсальный интерфейс делается в Си-стиле. Пишется обёртка над объектом в следующем виде:

typedef void* TObject;
...
TObject Create (x, y, z, frames, colors, wtf, ...);
void Draw (TObject Obj, args...);
void Move (TObject Obj, args...);

То есть все методы - это функции, принимающие сам объект (указатель) в качестве одного из параметров. Для внешнего кода ссылка на твой объект - это чёрный ящик.


RE: Исследование героев - Sav - 06.05.2012 00:31

Тогда надо писать методы для доступа к каждому полю. Мне не жалко того, что структура объекта открыта, я бы и код открыл, если бы он содержал только мои исследования (кстати, адреса устанавливающихся хуков можно считать открытыми - их элементарно посмотреть извне, используя patcher_x86). Пусть пользователь делает с объектом что хочет, а о том, что трогать не надо, я предупредил, и эти поля объявлены как private. Или закрытость структуры должна быть более удобной пользователю? В этом случае сделаю так.


RE: Исследование героев - Berserker - 06.05.2012 00:59

В текущем варианте ты ограничил применение языком Си++. К другим даже обёртки не сделать.


RE: Исследование героев - Sav - 06.05.2012 01:09

Т. е. чтобы не ограничивать надо обязательно создать такие функции? Хорошо, тогда я сделаю это.


RE: Исследование героев - Berserker - 06.05.2012 01:13

Да. Тогда я их прямо экспортирую в целевом языке программирования и используя, абсолютно не интересуясь двоичной структурой объекта (для меня это указатель).


RE: Исследование героев - Berserker - 18.05.2012 22:43

solitaire345 Wrote:I found a table which holds setup of arrow towers. It is located at 0x63CF88 and stores the following values:

Code:
00000000 CreatureID      dd ?                    ; base 10
00000004 MainTowerX      dd ?                    ; base 10
00000008 MainTowerY      dd ?                    ; base 10
0000000C LowTowerX       dd ?                    ; base 10
00000010 LowTowerY       dd ?                    ; base 10
00000014 UpTowerX        dd ?                    ; base 10
00000018 UpTowerY        dd ?                    ; base 10
0000001C MissileName  dd ?                    ; offset (00000000)

Here's a function to change graphics of any town. The paremeters are:
x1 - town type; x2 - shooter ID; x3-x8 - X; Y coordinates for turrets (middle, lower, upper); x9 - pointer to missile def.

A value of -1 means "do not change"

Code:
!?FU1;
!!FU&x1<0|x1>8:E;
!!VRv1:S4*8*x1+6541192; 0x63CF88

!!if&x2<>-1;
  !!MA:Xx2/?v2;
  !!VRv2:&4;
  !!IF&v2<>4:M^Trying to set nonshoting creature as arrow tower. Exiting to avoid crash^;
  !!FU&v2<>4:E;
  !!UN:Cv1/4/x2;
!!en;
!!VRv1:+4; !!UN&x3<>-1:Cv1/4/x3;
!!VRv1:+4; !!UN&x4<>-1:Cv1/4/x4;
!!VRv1:+4; !!UN&x5<>-1:Cv1/4/x5;
!!VRv1:+4; !!UN&x6<>-1:Cv1/4/x6;
!!VRv1:+4; !!UN&x7<>-1:Cv1/4/x7;
!!VRv1:+4; !!UN&x8<>-1:Cv1/4/x8;
!!VRv1:+4; !!UN&x9<>-1:Cv1/4/x9;

The pointers to missile names (parameter 9) are these (use numbers from the first column):

Code:
6686972 (0x6608FC) titan's bolt
6686984 (0x660908) Ice elemental's shard
6686996 (ox660914) Mage's missile
6687008 (0x660920) Catapult's rock
6687020 (0x66092C) Ballista's bolt
6687032 (0x660938) lizardman's arrow
6687044 (0x660944) Cyclop's boulder
6687056 (0x660950) orc's axe
6687068 (0x66095C) Medusa's arrow
6687080 (0x660968) lich's missile
6687092 (0x660974) Gog's fireball
6687104 (0x660980) Halfling's stone
6687116 (0x66098C) Gremlin's ball
6687128 (0x660998) Elf's arrow
6687140 (0x6609A4) Zealot's missile
6687152 (0x6609B0) Crosbowman's arrow
8002324 (0x7A1B14) Dracolich's missile

Notes:
1. There is no backup, so once changed, the setup will remain until h3era.exe is restarted.
2. Changing creature does not affect the power of arrow towers.
3. Using this function after BA0 trigger will have no effect in battle, because that table is copied to temporary location for the duration of combat.
4. creature images are cropped, so some creatures will look wrong (like this).



RE: Исследование героев - Berserker - 11.06.2012 17:54

solitaire345 Wrote:0x642EA0 - Table of creatures displayed in blacksmith screen. Gold cost is also taken from that creature.
0x6AAA60 - Table of artifacts that are sold in blacksmith. Stangely this table has two ints per town (second is always -1 and changing it has no effect).



RE: Исследование героев - Berserker - 16.06.2012 14:11

63BD18 - таблица урона от рвов.

Code:
5a7bf0 - расчёт урона от заклинания
  базовый урон: включает силу магии и уровень навыка,
  номер заклинания,
  структура колдующего героя,
  структура героя монстра или 0,
  структура целевого монстра,
  одиночная выборочная цель? (0, 1)
ecx = combat manager



RE: Исследование героев - Berserker - 16.06.2012 21:47

fastcall
44A1A0 (spell, creature id, resist table?, 0)


Code:
thiscall (combatman)
Получить спротивление как у Гномов
5a83a0 (заклинание, 0, структура монстра, 0, 1, 0): сопротивление (0.0..1.0)



RE: Исследование героев - Sav - 17.06.2012 01:10

Берс, а ты отписываешься здесь каждый раз, когда что-то находишь или отбираешь по каким-то приципам? Просто многие из этих, смежных, да и вообще различных функций мной исследованы, но я не знаю, есть ли какой-то толк их выкладывать.


RE: Исследование героев - Berserker - 17.06.2012 02:22

Да, если нахожу что-то по просьбе или для Эры.
Толк есть. В своё время я все сообщения обошёл, вычленяя то, что можно использовать или довести до ума.


RE: Исследование героев - Sav - 17.06.2012 12:04

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




RE: Исследование героев - GrayFace - 17.06.2012 13:23

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


RE: Исследование героев - Sav - 17.06.2012 13:56

Я перепроверю, но вроде тем же. Анимация самого выстрела проигрывается отдельно, а вот получения урона от него - этим.


RE: Исследование героев - Berserker - 17.06.2012 15:49

Sav, нехило 118


RE: Исследование героев - Sav - 17.06.2012 21:50

Посмотрел, DrawAction_Play вызывается и для любого удара, и для стрельбы.

Удар (Enemy_Gex_Around_Stack - номер атакуемого гекса вокруг стека - т. е. 0-6 (0-8), с учётом того, что гексы, окружающие стек, пронумерованы по определённому принципу):
PHP Code:
char __thiscall A0_Battle_Stack_MakeHit_sub_441330(_BattleStack_ *this_BattleStack_ *Enemyint Enemy_Gex_Around_Stack)
{
  
int Enemy_Gex_Around_Stack_v3// ebx@1
  
_BattleStack_ *this_v4// esi@1
  
char v5// al@6
  
char v6// zf@6
  
int v7// edx@7
  
int v8// edi@9
  
int v9// edx@10
  
signed int SomeGexNum_v10// eax@14
  
signed int EnemyGex_Num_v11// eax@14
  
_BattleStack_ *GexStack_v12// eax@16
  
int v13// ebx@20
  
int v14// edi@20
  
_BattleMgr_ *BattleMgr_v15// ebx@23
  
int v16// eax@24
  
signed int *v17// ebx@25
  
int v18// eax@29
  
unsigned int v19// edx@31
  
_BattleStack_ *v20// ebx@32
  
_BattleStack_ *Enemy_v21// edi@32
  
int v22// ecx@33
  
int v23// edi@33
  
int v24// ebx@37
  
int v25// edi@37
  
signed int v26// eax@41
  
_BattleStack_ *Enemy_v27// eax@44
  
int Damage_v28// eax@45
  
int v29// eax@49
  
int v30// eax@50
  
void *v31// eax@59
  
void *v32// eax@66
  
void *v33// eax@72
  
int v34// eax@82
  
char *Attacker_Name_v35// eax@85
  
int Attacker_type_v36// eax@89
  
char result// al@100
  
int Attacker_count_v38// [sp-10h] [bp-40h]@88
  
int v39// [sp-Ch] [bp-3Ch]@3
  
int Damage_v40// [sp-Ch] [bp-3Ch]@88
  
int Type_v41// [sp-8h] [bp-38h]@3
  
_BattleStack_ *Enemy_v42// [sp-8h] [bp-38h]@88
  
int Dead_v43// [sp-4h] [bp-34h]@88
  
signed int a5// [sp+Ch] [bp-24h]@9
  
int v45// [sp+10h] [bp-20h]@25
  
int v46// [sp+14h] [bp-1Ch]@31
  
_BattleStack_ *Enemy_v47// [sp+18h] [bp-18h]@31
  
int v48// [sp+1Ch] [bp-14h]@5
  
signed int a3// [sp+20h] [bp-10h]@31
  
int Num// [sp+24h] [bp-Ch]@31
  
_BattleStack_ *DragonBreathAttackedStack_v51// [sp+28h] [bp-8h]@1
  
char v52// [sp+2Fh] [bp-1h]@6

  
this_v4 this;
  
DragonBreathAttackedStack_v51 0;
  
A0_Battle_ClearStacksWereHitted_sub_465BC0(A0_BattleMgr_dword_699420);
  
Enemy_Gex_Around_Stack_v3 Enemy_Gex_Around_Stack;
  if ( (
this_v4->Creature_29dword74.Flags_dword10 >> 19) & )// Атакует всех врагов вокруг
  
{
    if ( 
this_v4->Spells_Lengths_adword198[59] )// Берсерк
    
{
      
Type_v41 2;
      
v39 this_v4->GexNum_dword38;
    }
    else
    {
      
Type_v41 1;
      
v39 this_v4->GexNum_dword38;
    }
    
v48 sub_524010(this_v4v39Type_v41, -1);
    if ( 
this_v4->CreatureType_dword34 == 47 )  // Цербер
    
{
      
v5 this_v4->Creature_29dword74.Flags_dword10 1;
      
v6 = (this_v4->Creature_29dword74.Flags_dword10 1) == 0;
      
v52 this_v4->Creature_29dword74.Flags_dword10 1;
      if ( 
v6 )
      {
        
v7 = (Enemy_Gex_Around_Stack_v3 5) % 6;
        
v5 v52;
      }
      else
      {
        
v7 dword_660898[(dword_660878[Enemy_Gex_Around_Stack_v3] + 7) % 8];
      }
      
a5 1;
      
v8 = ~(<< v7) & (unsigned __int8)~(unsigned __int8)(<< Enemy_Gex_Around_Stack_v3);
      if ( 
v5 )
        
v9 dword_660898[(dword_660878[Enemy_Gex_Around_Stack_v3] + 1) % 8];
      else
        
v9 = (Enemy_Gex_Around_Stack_v3 1) % 6;
      
v48 |= v8 & ~(<< v9);
    }
  }
  else
  {
    
Enemy->IsTarget_OfNonRoundHit_byteF0 1;
    if ( (
this_v4->Creature_29dword74.Flags_dword10 >> 3) & )// Атакующий стек обладает драконьим дыханием
    
{
      
EnemyGex_Num_v11 A0_Battle_Stack_Get_AroungGexNum_sub_5242E0(
                           
this_v4,
                           
this_v4->GexNum_dword38,
                           
Enemy_Gex_Around_Stack_v3);
      
SomeGexNum_v10 sub_524280(this_v4EnemyGex_Num_v11Enemy_Gex_Around_Stack_v3);
      if ( 
SomeGexNum_v10 >= )
      {
        if ( 
SomeGexNum_v10 187 )
        {
          
GexStack_v12 A0_Battle_get_StackByGex_sub_4E7230((int)&A0_BattleMgr_dword_699420->hex[SomeGexNum_v10]);
          
DragonBreathAttackedStack_v51 GexStack_v12;
          if ( 
GexStack_v12 )
          {
            if ( 
GexStack_v12->IsTarget_OfNonRoundHit_byteF0 )
              
DragonBreathAttackedStack_v51 0;
            else
              
GexStack_v12->IsTarget_OfNonRoundHit_byteF0 1;
          }
        }
      }
    }
  }
  
A0_Battle_ClearRedrawNeeds_sub_493290(A0_BattleMgr_dword_699420);
  
v14 this_v4->Owner_dwordF4;
  
v13 this_v4->StackNum_dwordF8;
  if ( 
A0_BattleMgr_dword_699420->stack[0][v13 14 v14 v14].CreatureType_dword34 == 149 )// Стрелковая башня
    
A0_Battle_SetArrowTowerRedraw_sub_46A040(
      
A0_BattleMgr_dword_699420,
      (
_BattleStack_ *)A0_BattleMgr_dword_699420->stack v13 14 v14 v14);
  else
    *(&
A0_BattleMgr_dword_699420->field_0[* (v14 20480)] + v13) = 1;
  
this_v4->CurrAttack_Is_Lucky_dword70 0;
  
BattleMgr_v15 A0_BattleMgr_dword_699420;
  if ( 
A0_BattleMgr_dword_699420->hero[A0_Battle_Stack_Get_Controller_sub_43FE60(this_v4)] )
  {
    
v16 this_v4->Luck_dword4EC;
    if ( 
v16 )
    {
      
v45 this_v4->Luck_dword4EC;
      
a5 3;
      
v17 = &a5;
      if ( 
v16 <= )
        
v17 = &v45;
      if ( 
A0_Rand_Int_sub_50C7C0(124) <= *v17 )
      {
        
this_v4->CurrAttack_Is_Lucky_dword70 1;
        if ( !
A0_Battle_ShouldNotRenderBattle_sub_46A080((int)A0_BattleMgr_dword_699420) )
        {
          
A0_StartAndPlaySample_Parallel_sub_59A890("goodluck.82m", -13);
          
v18 = (int)A0_Get_CreatureName_by_Type_adn_Count_sub_43FE20(
                       
this_v4->CreatureType_dword34,
                       
this_v4->Count_dword4C);
          
sprintf((int)A0_TempText_unk_697428, *(char **)(*((_DWORD *)off_6A5DC4 8) + 184), v18);
          
A0_Battle_MessageToLog_sub_4729D0(A0_BattleMgr_dword_699420->dlgA0_TempText_unk_69742810);
          
A0_Battle_Play_Std_BattleAnimation_sub_4963C0(A0_BattleMgr_dword_69942018this_v41000);
        }
      }
      
BattleMgr_v15 A0_BattleMgr_dword_699420;
    }
  }
  
v19 this_v4->Creature_29dword74.Flags_dword10;
  
a3 0;
  
Num 0;
  
v45 0;
  
v46 0;
  
Enemy_v47 0;
  
a5 0;
  if ( (
v19 >> 19) & )
  {
    
A0_Battle_Stack_RoundHit_MakeDamage_sub_440030(this_v4v48, &a3, &Num, (int)&Enemy_v47);
    
Enemy_v21 Enemy;
    
v20 DragonBreathAttackedStack_v51;
  }
  else
  {
    
v23 Enemy->Owner_dwordF4;
    
v22 Enemy->StackNum_dwordF8;
    if ( 
BattleMgr_v15->stack[0][v22 14 v23 v23].CreatureType_dword34 == 149 )
      
A0_Battle_SetArrowTowerRedraw_sub_46A040(
        
BattleMgr_v15,
        (
_BattleStack_ *)BattleMgr_v15->stack v22 14 v23 v23);
    else
      *(&
BattleMgr_v15->field_0[* (v23 20480)] + v22) = 1;
    if ( 
DragonBreathAttackedStack_v51 )
    {
      
v25 DragonBreathAttackedStack_v51->Owner_dwordF4;
      
v24 DragonBreathAttackedStack_v51->StackNum_dwordF8;
      if ( 
A0_BattleMgr_dword_699420->stack[0][v24 14 v25 v25].CreatureType_dword34 == 149 )
        
A0_Battle_SetArrowTowerRedraw_sub_46A040(
          
A0_BattleMgr_dword_699420,
          (
_BattleStack_ *)A0_BattleMgr_dword_699420->stack v24 14 v25 v25);
      else
        *(&
A0_BattleMgr_dword_699420->field_0[* (v25 20480)] + v24) = 1;
    }
    
Enemy_v21 Enemy;
    if ( (
Enemy->Creature_29dword74.Flags_dword10 >> 23) & )
      
v26 1;
    else
      
v26 Enemy->Count_dword4C Enemy->Creature_29dword74.Health_dword4C Enemy->HealthLoses_dword58;
    
a5 v26;
    
Enemy 0;
    if ( 
Enemy_v21 )
    {
      
Damage_v28 A0_Battle_Stack_CalcDamage_sub_442E80((int)this_v40);
      
a3 A0_Battle_Stack_CalcDamageModifs_sub_443C60(
             
this_v4,
             
Enemy_v21,
             
Damage_v28,
             
0,
             
0,
             
this_v4->GexesWay_Length_dword490,
             (
int *)&Enemy);
      
Num A0_Battle_Stack_MakeDamage_sub_443DB0(Enemy_v21a3);
      
Enemy_v27 Enemy;
      
this_v4->CurrAttack_Is_Lucky_dword70 0;
    }
    else
    {
      
Enemy_v27 0;
    }
    
Enemy_v47 Enemy_v27;
    if ( (
signed int)Enemy_v27 )
      
Enemy_v21->CurrHit_WasDamagedByFireshield_byteE8 1;
    
v20 DragonBreathAttackedStack_v51;
    if ( 
DragonBreathAttackedStack_v51 )
    {
      
Enemy 0;
      
v29 A0_Battle_Stack_CalcDamage_sub_442E80((int)this_v40);
      
v45 A0_Battle_Stack_CalcDamageModifs_sub_443C60(
              
this_v4,
              
v20,
              
v29,
              
0,
              
0,
              
this_v4->GexesWay_Length_dword490,
              (
int *)&Enemy);
      
v46 A0_Battle_Stack_MakeDamage_sub_443DB0(v20v45);
      
this_v4->CurrAttack_Is_Lucky_dword70 0;
    }
  }
  
A0_Battle_Set_RedrawBorders_sub_495770((int)A0_BattleMgr_dword_699420);
  
v30 this_v4->CreatureType_dword34;
  
this_v4->CurrDrawAct_IsAttacker_byte0 1;
  if ( 
v30 == 110 || v30 == 111 || A0_Battle_ShouldNotRenderBattle_sub_46A080((int)A0_BattleMgr_dword_699420) )// Гидра, гидра хаоса.
    
goto LABEL_78;
  if ( 
Enemy_Gex_Around_Stack != && Enemy_Gex_Around_Stack != && Enemy_Gex_Around_Stack )
  {
    if ( 
Enemy_Gex_Around_Stack != && Enemy_Gex_Around_Stack != )
    {
      if ( 
v20 && (v31 this_v4->Def_dword164, *((_DWORD *)v31 10) > 19) && *(_DWORD *)(*((_DWORD *)v31 11) + 76) )
      {
        
this_v4->CurrDrawAct_AttackAnimFrameSection_byte2 19;
      }
      else
      {
        if ( 
this_v4->CreatureType_dword34 == 146 )// Баллиста.
          
this_v4->CurrDrawAct_AttackAnimFrameSection_byte2 16;
        else
          
this_v4->CurrDrawAct_AttackAnimFrameSection_byte2 13;
      }
      goto 
LABEL_79;
    }
    if ( 
v20 )
    {
      
v32 this_v4->Def_dword164;
      if ( *((
_DWORD *)v32 10) > 18 )
      {
        if ( *(
_DWORD *)(*((_DWORD *)v32 11) + 72) )
        {
          
this_v4->CurrDrawAct_AttackAnimFrameSection_byte2 18;
          goto 
LABEL_79;
        }
      }
    }
    if ( 
this_v4->CreatureType_dword34 == 146 // Баллиста.
    
{
      
this_v4->CurrDrawAct_AttackAnimFrameSection_byte2 15;
      goto 
LABEL_79;
    }
LABEL_78:
    
this_v4->CurrDrawAct_AttackAnimFrameSection_byte2 12;
    goto 
LABEL_79;
  }
  if ( 
v20 && (v33 this_v4->Def_dword164, *((_DWORD *)v33 10) > 17) && *(_DWORD *)(*((_DWORD *)v33 11) + 68) )
  {
    
this_v4->CurrDrawAct_AttackAnimFrameSection_byte2 17;
  }
  else
  {
    if ( 
this_v4->CreatureType_dword34 == 146 // Баллиста.
      
this_v4->CurrDrawAct_AttackAnimFrameSection_byte2 14;
    else
      
this_v4->CurrDrawAct_AttackAnimFrameSection_byte2 11;
  }
LABEL_79:
  
Enemy->CurrDrawAct_AnimFrameSection_byte3 A0_Battle_Stack_After_Hit_Spells_sub_440220(this_v4Enemy_v21);// Глюк, это другая переменная
  
A0_Battle_DrawAction_Play_sub_468570(A0_BattleMgr_dword_699420, -10);
  if ( !((
this_v4->Creature_29dword74.Flags_dword10 >> 19) & 1) )// Атакует всех вогруг
  
{
    if ( 
v20 && v20->CreatureType_dword34 != Enemy_v21->CreatureType_dword34 )
    {
      
v34 this_v4->CreatureType_dword34;
      if ( 
v34 || v34 150 )
      {
        
Attacker_Name_v35 A0_Empty_dword_691260;
      }
      else
      {
        if ( 
this_v4->Count_dword4C == )
          
Attacker_Name_v35 = (*Main_MonsersTable_off_6747B0)[v34].NameSingle_dword14;
        else
          
Attacker_Name_v35 = (*Main_MonsersTable_off_6747B0)[v34].NameMulti_dword18;
      }
      
Dead_v43 Num v46;
      
Enemy_v42 0;
      
Damage_v40 a3 v45;
      
Attacker_count_v38 this_v4->Count_dword4C;
    }
    else
    {
      
Attacker_type_v36 this_v4->CreatureType_dword34;
      if ( 
Attacker_type_v36 || Attacker_type_v36 150 )
      {
        
Attacker_Name_v35 A0_Empty_dword_691260;
      }
      else
      {
        if ( 
this_v4->Count_dword4C == )
          
Attacker_Name_v35 = (*Main_MonsersTable_off_6747B0)[Attacker_type_v36].NameSingle_dword14;
        else
          
Attacker_Name_v35 = (*Main_MonsersTable_off_6747B0)[Attacker_type_v36].NameMulti_dword18;
      }
      
Dead_v43 Num;
      
Enemy_v42 Enemy_v21;
      
Damage_v40 a3;
      
Attacker_count_v38 this_v4->Count_dword4C;
    }
    
A0_Battle_Attacking_Log_Message_sub_469670(
      (int)
A0_BattleMgr_dword_699420,
      (
char)Attacker_Name_v35,
      
Attacker_count_v38,
      
Damage_v40,
      
Enemy_v42,
      
Dead_v43);
  }
  
A0_Battle_After_Attack_Abilities_sub_4408E0(this_v4Enemy_v21a3Numa5);
  if ( (
signed int)Enemy_v47 )
    
A0_Battle_Stack_GetFireshieldDamage_sub_4406E0(this_v4Enemy_v47);
  if ( !
Enemy_v21->CurrHit_IsBlinded_byte4C0 || (result 1Enemy_v21->BlindSpell_Modif_dword49C != 0.0) )
    
result Enemy->CurrDrawAct_AnimFrameSection_byte3;// Глюк, это другая переменная
  
return result;


Выстрел:
PHP Code:
void __thiscall A0_Battle_Stack_MakeShot_sub_43F620(_BattleStack_ *thisint Enemy)
{
  
int v2// ebx@1
  
_BattleStack_ *this_v3// esi@1
  
int v4// eax@2
  
int *v5// edi@3
  
int v6// eax@7
  
_Hero_ *Hero_v7// ecx@8
  
_BattleStack_ *Enemy_v8// edi@8
  
int CreatureType_v9// eax@11
  
int v10// ecx@14
  
int v11// ebx@14
  
int v12// edi@16
  
int v13// ecx@16
  
int v14// eax@19
  
signed int v15// edi@24
  
int v16// eax@26
  
int v17// ecx@28
  
char v18// al@30
  
char *v19// eax@31
  
_BattleStack_ *Stack_v20// edi@31
  
int v21// ebx@31
  
int v22// ebx@37
  
int v23// eax@37
  
_BattleStack_ *v24// ecx@44
  
int v25// eax@46
  
char *v26// eax@49
  
int v27// ebx@56
  
int v28// eax@56
  
int v29// eax@58
  
char *v30// eax@61
  
int v31// esi@66
  
int v32// ebx@68
  
int v33// ecx@70
  
int v34// ebx@70
  
int v35// edi@72
  
int v36// ecx@72
  
int v37// eax@75
  
int v38// eax@82
  
int v39// ecx@84
  
char v40// al@86
  
int v41// ebx@87
  
_BattleStack_ *v42// edi@87
  
char *v43// eax@89
  
int v44// eax@91
  
unsigned __int8 v45// sf@96
  
unsigned __int8 v46// of@96
  
int v47// eax@100
  
char *v48// eax@103
  
int v49// [sp+Ch] [bp-20h]@37
  
int v50// [sp+10h] [bp-1Ch]@37
  
int v51// [sp+14h] [bp-18h]@31
  
int v52// [sp+18h] [bp-14h]@3
  
int v53// [sp+1Ch] [bp-10h]@3
  
int v54// [sp+20h] [bp-Ch]@24
  
_BattleStack_ *v55// [sp+24h] [bp-8h]@24
  
_BattleStack_ *v56// [sp+28h] [bp-4h]@24

  
this_v3 this;
  
v2 0;
  
this->CurrAttack_Is_Lucky_dword70 0;
  if ( 
A0_BattleMgr_dword_699420->hero[A0_Battle_Stack_Get_Controller_sub_43FE60(this)] )
  {
    
v4 this_v3->Luck_dword4EC;
    if ( 
v4 )
    {
      
v53 this_v3->Luck_dword4EC;
      
v52 3;
      
v5 = &v52;
      if ( 
v4 <= )
        
v5 = &v53;
      if ( 
A0_Rand_Int_sub_50C7C0(124) <= *v5 )
      {
        
this_v3->CurrAttack_Is_Lucky_dword70 1;
        if ( !
A0_Battle_ShouldNotRenderBattle_sub_46A080((int)A0_BattleMgr_dword_699420) )
        {
          
A0_StartAndPlaySample_Parallel_sub_59A890("goodluck.82m", -13);
          
v6 = (int)A0_Get_CreatureName_by_Type_adn_Count_sub_43FE20(
                      
this_v3->CreatureType_dword34,
                      
this_v3->Count_dword4C);
          
sprintf((int)A0_TempText_unk_697428, *(char **)(*((_DWORD *)off_6A5DC4 8) + 184), v6);
          
A0_Battle_MessageToLog_sub_4729D0(A0_BattleMgr_dword_699420->dlgA0_TempText_unk_69742810);
          
A0_Battle_Play_Std_BattleAnimation_sub_4963C0(A0_BattleMgr_dword_69942018this_v31000);
        }
      }
    }
  }
  
Enemy_v8 = (_BattleStack_ *)Enemy;
  
A0_Battle_Stack_DrawShot_Bullet_sub_43EFE0(this_v3, (_BattleStack_ *)Enemy);
  
Hero_v7 A0_BattleMgr_dword_699420->hero[this_v3->Owner_dwordF4];
  if ( !
Hero_v7 || !A0_Hero_Check_Has_Artifact_Weared_sub_4D9460(Hero_v75) )// Повода с боеприпасами
    
--this_v3->Creature_29dword74.Ammo_dword64;
  
CreatureType_v9 this_v3->CreatureType_dword34;
  if ( 
CreatureType_v9 == 45 )                  // Магог
  
{
    
v52 off_687FA8[716];
    if ( 
v52 != -)
    {
      if ( !
A0_Battle_ShouldNotRenderBattle_sub_46A080((int)A0_BattleMgr_dword_699420) )
      {
        
A0_StartAndPlaySample_Parallel_sub_59A890((char *)off_687FA8[715], -13);
        
v11 A0_Load_Def_sub_55C9C0(A0_BattleAnims_off_641E18[v52]);
        
Enemy = (int)((char *)A0_BattleMgr_dword_699420 112 Enemy_v8->GexNum_dword38);
        
v10 = *(_WORD *)(Enemy 452);
        if ( 
Enemy_v8->Creature_29dword74.Flags_dword10 )
          
v10 += (Enemy_v8->Orientation_dword44 != 0x2C 0) - 22;
        
v53 v10 - *(_DWORD *)(v11 48) / 2;
        
v13 = *(_WORD *)(Enemy 454) - Enemy_v8->CreatureImageHeight_dword16C - *(_DWORD *)(v11 52) / 2;
        
v12 0;
        
Enemy v13;
        while ( 
)
        {
          
v14 = *(_DWORD *)(v11 40) > && **(_DWORD **)(v11 44) ? ***(_DWORD ***)(v11 28) : 0;
          if ( 
v12 >= v14 )
            break;
          
A0_Battle_Draw_sub_493FC0((int)A0_BattleMgr_dword_6994200005011);
          
A0_Battle_DrawOrSetBorders_TranparentDef_sub_494F30(
            (int)
A0_BattleMgr_dword_699420,
            
v11,
            
v12,
            
v53,
            
Enemy,
            
0,
            
0);
          
A0_FlipBattle_sub_493300((int)A0_BattleMgr_dword_699420);
          ++
v12;
        }
        
A0_Battle_Draw_sub_493FC0((int)A0_BattleMgr_dword_699420100010);
        (*(
void (__thiscall **)(int))(*(_DWORD *)v11 4))(v11);
        
v2 0;
      }
    }
    
A0_Battle_Clear_Stacks_Redraw_Needs_sub_5A69C0(A0_BattleMgr_dword_699420);
    
v15 0;
    
v53 v2;
    
v55 = (_BattleStack_ *)v2;
    
v56 = (_BattleStack_ *)v2;
    
BYTE3(Enemy) = 0;
    
v54 0;
    do
    {
      if ( 
v15 == )
        
v16 this_v3->Attacked_Or_MoveTarget_Gex_Num_dword1C;
      else
        
v16 sub_524370(this_v3->Attacked_Or_MoveTarget_Gex_Num_dword1Cv15);
      
v17 = (int)&A0_BattleMgr_dword_699420->hex[v16];
      if ( 
v16 >= )
      {
        if ( 
v16 187 )
        {
          
v18 A0_BattleMgr_dword_699420->hex[v16].bstack_side;
          if ( 
v18 >= )
          {
            
v51 = *(_BYTE *)(v17 25);
            
v21 v18;
            
Stack_v20 A0_Battle_get_StackByGex_sub_4E7230(v17);
            
v19 = &A0_BattleMgr_dword_699420->field_53D4[20 v21 168] + v51;
            if ( !*
v19 )
            {
              *
v19 1;
              if ( 
v56 )
              {
                if ( 
v56->CreatureType_dword34 != Stack_v20->CreatureType_dword34 )
                  
BYTE3(Enemy) = 1;
              }
              else
              {
                
v56 Stack_v20;
              }
              
v51 0;
              if ( 
Stack_v20 )
              {
                
v23 A0_Battle_Stack_CalcDamage_sub_442E80((int)this_v30);
                
v22 A0_Battle_Stack_CalcDamageModifs_sub_443C60(
                        
this_v3,
                        
Stack_v20,
                        
v23,
                        
1,
                        
0,
                        
this_v3->GexesWay_Length_dword490,
                        &
v51);
                
v50 v22;
                
v49 A0_Battle_Stack_MakeDamage_sub_443DB0(Stack_v20v22);
                
this_v3->CurrAttack_Is_Lucky_dword70 0;
              }
              else
              {
                
v22 v50;
              }
              
v55 = (_BattleStack_ *)((char *)v55 v22);
              
v53 += v49;
            }
            
v15 v54;
          }
        }
      }
      ++
v15;
      
v54 v15;
    }
    while ( 
v15 );
    if ( (
signed int)v55 )
    {
      if ( 
BYTE3(Enemy) )
        
v24 0;
      else
        
v24 v56;
      
v25 this_v3->CreatureType_dword34;
      if ( 
v25 || v25 150 )
      {
        
v26 A0_Empty_dword_691260;
      }
      else
      {
        if ( 
this_v3->Count_dword4C == )
          
v26 = (*Main_MonsersTable_off_6747B0)[v25].NameSingle_dword14;
        else
          
v26 = (*Main_MonsersTable_off_6747B0)[v25].NameMulti_dword18;
      }
      
A0_Battle_Attacking_Log_Message_sub_469670(
        (int)
A0_BattleMgr_dword_699420,
        (
char)v26,
        
this_v3->Count_dword4C,
        (int)
v55,
        
v24,
        
v53);
      
A0_Battle_DrawAction_Play_sub_468570(A0_BattleMgr_dword_699420v521);
    }
  }
  else
  {
    if ( 
CreatureType_v9 == 64 || CreatureType_v9 == 65 )// Лич, могущественный лич
    
{
      
v32 off_687FA8[2586];
      if ( 
v32 != -)
      {
        if ( !
A0_Battle_ShouldNotRenderBattle_sub_46A080((int)A0_BattleMgr_dword_699420) )
        {
          
A0_StartAndPlaySample_Parallel_sub_59A890((char *)off_687FA8[2585], -13);
          
v34 A0_Load_Def_sub_55C9C0(A0_BattleAnims_off_641E18[v32]);
          
Enemy = (int)((char *)A0_BattleMgr_dword_699420 112 Enemy_v8->GexNum_dword38);
          
v33 = *(_WORD *)(Enemy 452);
          if ( 
Enemy_v8->Creature_29dword74.Flags_dword10 )
            
v33 += (Enemy_v8->Orientation_dword44 != 0x2C 0) - 22;
          
v49 v33 - *(_DWORD *)(v34 48) / 2;
          
v36 = *(_WORD *)(Enemy 454) - Enemy_v8->CreatureImageHeight_dword16C - *(_DWORD *)(v34 52) / 2;
          
v35 0;
          
Enemy v36;
          while ( 
)
          {
            
v37 = *(_DWORD *)(v34 40) > && **(_DWORD **)(v34 44) ? ***(_DWORD ***)(v34 28) : 0;
            if ( 
v35 >= v37 )
              break;
            
A0_Battle_Draw_sub_493FC0((int)A0_BattleMgr_dword_69942000010011);
            
A0_Battle_DrawOrSetBorders_TranparentDef_sub_494F30(
              (int)
A0_BattleMgr_dword_699420,
              
v34,
              
v35,
              
v49,
              
Enemy,
              
0,
              
0);
            
A0_FlipBattle_sub_493300((int)A0_BattleMgr_dword_699420);
            ++
v35;
          }
          
A0_Battle_Draw_sub_493FC0((int)A0_BattleMgr_dword_699420100010);
          (*(
void (__thiscall **)(int))(*(_DWORD *)v34 4))(v34);
        }
      }
      
A0_Battle_Clear_Stacks_Redraw_Needs_sub_5A69C0(A0_BattleMgr_dword_699420);
      
v53 0;
      
v54 0;
      
v55 0;
      
BYTE3(Enemy) = 0;
      
v56 0;
      do
      {
        if ( 
v56 == (_BattleStack_ *))
          
v38 this_v3->Attacked_Or_MoveTarget_Gex_Num_dword1C;
        else
          
v38 sub_524370(this_v3->Attacked_Or_MoveTarget_Gex_Num_dword1Cv56);
        
v39 = (int)&A0_BattleMgr_dword_699420->hex[v38];
        if ( 
v38 >= )
        {
          if ( 
v38 187 )
          {
            
v40 A0_BattleMgr_dword_699420->hex[v38].bstack_side;
            if ( 
v40 >= )
            {
              
v49 = *(_BYTE *)(v39 25);
              
v41 v40;
              
v42 A0_Battle_get_StackByGex_sub_4E7230(v39);
              if ( 
v56 == (_BattleStack_ *)|| (v42->Creature_29dword74.Flags_dword10 >> 4) & )
              {
                
v43 = &A0_BattleMgr_dword_699420->field_53D4[20 v41 168] + v49;
                if ( !*
v43 )
                {
                  *
v43 1;
                  
v49 0;
                  if ( 
v42 )
                  {
                    
v44 A0_Battle_Stack_CalcDamage_sub_442E80((int)this_v30);
                    
v50 A0_Battle_Stack_CalcDamageModifs_sub_443C60(
                            
this_v3,
                            
v42,
                            
v44,
                            
1,
                            
0,
                            
this_v3->GexesWay_Length_dword490,
                            &
v49);
                    
v51 A0_Battle_Stack_MakeDamage_sub_443DB0(v42v50);
                    
this_v3->CurrAttack_Is_Lucky_dword70 0;
                  }
                  
v54 += v50;
                  
v53 += v51;
                  if ( 
v55 )
                  {
                    if ( 
v55->CreatureType_dword34 != v42->CreatureType_dword34 )
                      
BYTE3(Enemy) = 1;
                  }
                  else
                  {
                    
v55 v42;
                  }
                }
              }
            }
          }
        }
        
v46 __SETO__(&v56->CurrDrawAct_IsShooter_byte17);
        
v45 = (signed int)((char *)v56 6) < 0;
        
v56 = (_BattleStack_ *)((char *)v56 1);
      }
      while ( 
v45 v46 );
      if ( 
v54 )
      {
        if ( 
BYTE3(Enemy) )
          
v55 0;
        
v47 this_v3->CreatureType_dword34;
        if ( 
v47 || v47 150 )
        {
          
v48 A0_Empty_dword_691260;
        }
        else
        {
          if ( 
this_v3->Count_dword4C == )
            
v48 = (*Main_MonsersTable_off_6747B0)[v47].NameSingle_dword14;
          else
            
v48 = (*Main_MonsersTable_off_6747B0)[v47].NameMulti_dword18;
        }
        
A0_Battle_Attacking_Log_Message_sub_469670(
          (int)
A0_BattleMgr_dword_699420,
          (
char)v48,
          
this_v3->Count_dword4C,
          
v54,
          
v55,
          
v53);
        
A0_Battle_DrawAction_Play_sub_468570(A0_BattleMgr_dword_699420, -11);
      }
    }
    else
    {
      
Enemy 0;
      if ( 
Enemy_v8 )
      {
        
v28 A0_Battle_Stack_CalcDamage_sub_442E80((int)this_v30);
        
v27 A0_Battle_Stack_CalcDamageModifs_sub_443C60(
                
this_v3,
                
Enemy_v8,
                
v28,
                
1,
                
0,
                
this_v3->GexesWay_Length_dword490,
                &
Enemy);
        
Enemy A0_Battle_Stack_MakeDamage_sub_443DB0(Enemy_v8v27);
        
this_v3->CurrAttack_Is_Lucky_dword70 0;
      }
      else
      {
        
v27 Enemy;
      }
      
A0_Battle_DrawAction_Play_sub_468570(A0_BattleMgr_dword_699420, -10);
      
v29 this_v3->CreatureType_dword34;
      if ( 
v29 || v29 150 )
      {
        
v30 A0_Empty_dword_691260;
      }
      else
      {
        if ( 
this_v3->Count_dword4C == )
          
v30 = (*Main_MonsersTable_off_6747B0)[v29].NameSingle_dword14;
        else
          
v30 = (*Main_MonsersTable_off_6747B0)[v29].NameMulti_dword18;
      }
      
A0_Battle_Attacking_Log_Message_sub_469670(
        (int)
A0_BattleMgr_dword_699420,
        (
char)v30,
        
this_v3->Count_dword4C,
        
v27,
        
Enemy_v8,
        
Enemy);
      if ( !
A0_Battle_ShouldNotRenderBattle_sub_46A080((int)A0_BattleMgr_dword_699420) )
      {
        if ( !
A0_Battle_ShouldNotRenderBattle_sub_46A080((int)A0_BattleMgr_dword_699420) )
        {
          
v31 = (int)this_v3->Shot_Sound_dword17C;
          if ( 
v31 )
            
A0_Wait_Sample_sub_59A1C0((void *)A0_SoundMgr_dword_699414, *(_DWORD *)(v31 28), -1);
        }
      }
    }
  }


Тут всё далеко не так хорошо описано, но код здесь и без этого можно понять, благо ссылки на структуры без смещений.


RE: Исследование героев - Sav - 06.07.2012 18:30

Отрисовка текста на изображение.



RE: Исследование героев - Berserker - 21.08.2012 15:42

Sav Wrote:
Berserker Wrote:Sav, а вот это уже интересно. Как сделать деф, чтобы при замене дефа страха он проигрывался полупрозрачным?
Специального дефа не нужно, полупрозрачность работает с любым. Это параметр у функции, которая отрисовывает анимации, (0x47BA90) любую анимацию можно отрисовывать полупрозрачно. Ну, разумеется, полупрозрачность не регулируемая, одинакова для каждого пикселя.

Вот, как устроена таблица боевых анимаций.
PHP Code:
// Структура боевой анимации.
NOALIGN struct _BattleAnim_
{
  
_cstr_ DefName// Имя def`а анимации
  
_cstr_ TouchEffect_Name// Имя тактильного эффекта анимации (для его воспроизведения на нестандартных элементах управления с помощью IFC20.dll)
  
_dword_ Properties// Свойства боевой анимации (по несколько битов)
  // ***
  // Начало описания свойств анимации
  // ***
    // (сдвиг - размер в битах - значение) 
    // 0 - 4 - Позиция отображения (0 - от земли на стеке или гексе, 1 - посередине гекса или стека, 2 - выше стека, 3 - перед стеком, 4 - с нижней и левой границы гекса, -1 - нет позиции)
    // 4 - 4 - Не используется
    // 8 - 1 - Прозрачность (0 - нет, 1 - есть)
    // 9 - 23 - Не используется
  // ***
  // Конец описания свойств анимации
  // ***
}; 
PHP Code:
_BattleAnim_o_BattleAnimation = ((_BattleAnim_*)0x641E18);

_int_ BattleAnims_Count 83
В Воге таблица, перенесена на адрес 0x7B6980. Номера анимаций соответствую номерам в таблице BM:V в ERM-help. С помощью UN:C можно легко на время изменить параметры любой анимации.



RE: ERA II - MOP - 21.09.2012 19:54

Вот ещё 1-байтец, убирающий видимость Мин и Зыбучих Песков на родной земле:

463C3D 00


RE: ERA II - Berserker - 21.09.2012 20:42

Родной для кого? И это точно баг?


RE: ERA II - Sav - 21.09.2012 22:59

Родной земле замка, к которому принадлежит существо. Это явно не баг, т. к. там вполне конкретно проверяется наличие у стороны стека с соотв. родной землёй.


RE: ERA II - MOP - 24.09.2012 09:04

(21.09.2012 20:42)Berserker Wrote:  И это точно баг?
(21.09.2012 22:59)Sav Wrote:  Это явно не баг
Я и не говорил ни разу, что это баг. Однако данная содовская "фишка" делает Мины и Зыбучий Песок ещё более УГ-заклинаниями, чем они могли бы быть. И я не разу не слышал, чтобы кто-то был против её устранения. Наоборот, всё орали: "Уберите!".


RE: ERA II - Berserker - 24.09.2012 13:48

Да, соглашусь с МОР-ом. Для модов будет полезно.


RE: Исследование героев - Berserker - 11.12.2012 21:17

feanor Wrote:
Quote:10. Нейтральные герои, с магией
А в чем тут проблема? Нейтральных (минус первого игрока) героев как неподвижных стражей вытащить можно без особого изврата. Я где-то писал команду, чтоб они отображались на карте..

Quote:004100B5: 90909090 90909090
00410285: 90909090 90909090

Отрисовка героев -1ого игрока. Без флага.

То же в ERM.
!!UN:C4260021/4/2425393296;
!!UN:C4260025/4/2425393296;
!!UN:C4260485/4/2425393296;
!!UN:C4260489/4/2425393296;



RE: Исследование героев - Berserker - 28.02.2013 21:38

Кто-нибудь знает, зачем в структуре кадра дефа поля frame_top/left?

Code:
NOALIGN struct _DefFrame_ : public _BinTreeItem_
{
    _dword_        frm_size; // + 28
    _dword_        buf_size;
    _dword_        compression_type;
    _dword_        def_width;
    _dword_        def_height;
    _dword_        frame_width;
    _dword_        frame_height;
    _dword_        frame_left;
    _dword_        frame_top;
    _dword_        unknown_40;
    _ptr_        buffer;

    // my
    _dword_ DrawInterfaceToPcx16(_Pcx_* dst_pcx16, _int_ dst_x, _int_ dst_y, _Palette16_* palette16)
    {
        return CALL_14(_dword_, __thiscall, 0x47BE90, this, 0, 0, def_width, def_height, dst_pcx16->buffer, dst_x, dst_y, dst_pcx16->width, dst_pcx16->height, dst_pcx16->scanline_size, palette16, 0, 1);
    }
};



RE: Исследование героев - Sav - 28.02.2013 23:58

У кадров иногда обрезается лишняя прозрачная площадь по краям. Вероятно, эти поля показывают, где в кадре начинается, собственно, изображение.


RE: Исследование героев - AVS - 01.03.2013 00:19

Раз там есть поле compression_type, значит кадр хранится сжатым, тогда Sav прав.


RE: Исследование героев - Berserker - 01.03.2013 23:22

Что-то похожее видел в коде. Участвует в расчёте итогового смещения для отрисовки (ака dx, dy).


RE: Исследование героев - etoprostoya - 02.03.2013 11:38

Правильно Сав сказал. Я специально вёл логи отрисовки монстров и ни разу не было случая, что бы рисовался полный кадр, который, как известно имеет размер 450*400 пикселей.


RE: Иные Герои - Ivor - 15.04.2013 14:37

(14.04.2013 19:02)Ivor Wrote:  MoP сделал патчик, запрещающий получение экспертной школы без экспертной мудрости
(14.04.2013 19:13)Berserker Wrote:  Судя по всему, ассемблерной вставкой.
Ага
Code:
; При повышении уровня: раскачка магического навыка до экспертного требует экспертной Мудрости
; модификация воговской вставки:
74DA24 55;                     PUSH EBP
74DA25 8BEC;                   MOV EBP,ESP
74DA27 53;                     PUSH EBX
74DA28 8915C0497302;           MOV DWORD PTR DS:[27349C0],EDX
74DA2E 890DECAAA400;           MOV DWORD PTR DS:[A4AAEC],ECX
74DA34 8BD9;                   MOV EBX,ECX
74DA36 837D0CFF;               CMP DWORD PTR SS:[EBP+C],-1
74DA3A 7510;                   JNZ SHORT MoP.0074DA4C
74DA3C 833D2C358A00FE;         CMP DWORD PTR DS:[8A352C],-2
74DA43 7417;                   JE SHORT MoP.0074DA5C
74DA45 A12C358A00;             MOV EAX,DWORD PTR DS:[8A352C]
74DA4A EB56;                   JMP SHORT MoP.0074DAA2
74DA4C 833D30358A00FE;         CMP DWORD PTR DS:[8A3530],-2
74DA53 7407;                   JE SHORT MoP.0074DA5C
74DA55 A130358A00;             MOV EAX,DWORD PTR DS:[8A3530]
74DA5A EB46;                   JMP SHORT MoP.0074DAA2
74DA5C FFB3D7000000;           PUSH DWORD PTR DS:[EBX+D7] - сохранить уровни школ героя в стеке
74DA62 FF750C;                 PUSH DWORD PTR SS:[EBP+C]
74DA65 FF7508;                 PUSH DWORD PTR SS:[EBP+8]
74DA68 8B15C0497302;           MOV EDX,DWORD PTR DS:[27349C0]
74DA6E 8BCB;                   MOV ECX,EBX
74DA70 E8FBD4D8FF;             CALL MoP.004DAF70 - генерация навыка
74DA75 83F80E;                 CMP EAX,0E - проверка на школы
74DA78 7C22;                   JL SHORT MoP.0074DA9C
74DA7A 83F811;                 CMP EAX,11 - проверка на школы
74DA7D 7F1D;                   JG SHORT MoP.0074DA9C
74DA7F 80BC18C900000002;       CMP BYTE PTR DS:[EAX+EBX+C9],2 - если навык продвинут и готовится прокачаться до эксперта
74DA87 7513;                   JNZ SHORT MoP.0074DA9C
74DA89 80BBD000000003;         CMP BYTE PTR DS:[EBX+D0],3 - а Мудрость ещё не экспертна
74DA90 7D0A;                   JGE SHORT MoP.0074DA9C
74DA92 C68418C900000003;       MOV BYTE PTR DS:[EAX+EBX+C9],3 - тогда якобы повышаем навык до эксперта и запускаем генерацию снова
74DA9A EBC6;                   JMP SHORT MoP.0074DA62
74DA9C 8F83D7000000;           POP DWORD PTR DS:[EBX+D7] - а после возвращаем скиллы обратно
74DAA2 5B;                     POP EBX
74DAA3 5D;                     POP EBP
74DAA4 C20800;                 RETN 8
http://yadi.sk/d/qiKYucT043auR


RE: Исследование героев - gamecreator - 06.05.2013 00:45

подскажите где хранятся ценности объектов для генератора карт


RE: Исследование героев - Sav - 06.05.2013 01:01

Таблицы нет, прямо в коде через непосредственные операнды присваиваются.

Если интересует только для того, чтобы посмотреть, то вот, я собирал всё в кучу: http://forum.df2.ru/index.php?s=&showtopic=2342&view=findpost&p=559149
И вот пост со ссылками на всю связанную с этим инфу: http://forum.heroesworld.ru/showpost.php?p=642650&postcount=30


RE: Исследование героев - gamecreator - 06.05.2013 10:44

интересует изменить эти ценности или вообще забанить некоторые объекты.


RE: Исследование героев - Sav - 06.05.2013 16:53

В idb ZVS смотри функцию RMG_00539000.
Не знаю, правда, модифицирует ли там что-то Вог.


RE: Исследование героев - gamecreator - 06.05.2013 20:29

спасибо


RE: Исследование героев - Berserker - 25.05.2013 19:43

Обновить окно встречи героев.


RE: Исследование героев - totkotoriy - 25.05.2013 20:23

(25.05.2013 19:43)Berserker Wrote:  Обновить окно встречи героев.
Ты это только сейчас сделал? Или нашел где-то?...
В любом случае огромное спасибо!... сейчас буду проверять.


RE: Исследование героев - Berserker - 25.05.2013 21:09

Сел, нашёл. Исходники, отладчик, ЕРМ, ArtMoney — всё штатно.


RE: Исследование героев - totkotoriy - 25.05.2013 21:37

(25.05.2013 21:09)Berserker Wrote:  Сел, нашёл. Исходники, отладчик, ЕРМ, ArtMoney — всё штатно.
По крайней мере в триггере 66666 не работает. А так же в этом триггере нельзя узнать номера встретившихся героев. Приходиться узнавать их в CM3 (то есть можно узнать номера только при нажатии какой-либо кнопки в окне встречи, но не новой) и передавать в 66666. Обновляется только когда нажимаешь куда нибудь еще, но не на новую кнопку (так кстати и было раньше). Даже не знаю что и делать...

ID кнопки в этом триггере находится в значении x1 - на всякий случай.

И еще заметил: после того как сработал триггер CM3 в триггере 66666 можно узнать номера героев.
Может симитировать командой нажатие кнопки по пустому месту в начале и в конце триггера 66666?


RE: Исследование героев - Berserker - 26.05.2013 17:32

Сделал нормальный CM3, перехватывающий абсолютно всё.
Жаль, подводит Делфи меня, некорректно обрабатывает ассемблерные блоки, ну да ладно.
Era 2.45 dll
Buttons.dll for Mods\WoG\EraPlugins


RE: Исследование героев - totkotoriy - 26.05.2013 18:22

Перехватывает, но экран всё также не обновляется :_(
Может что-то не так делаю?


RE: Исследование героев - Berserker - 26.05.2013 19:05

Обновляется (проверял на отрядах, не артах).
Что именно ты делаешь?


RE: Исследование героев - totkotoriy - 26.05.2013 21:01

Так например делаю...


RE: Исследование героев - Berserker - 26.05.2013 21:25

Подтверждаю отложенное обновление при щелчке на кнопке именно. Исследую дальше.
IF:L в том же месте обновляет экран, нужно глянуть как.


RE: Исследование героев - Berserker - 26.05.2013 21:54




RE: Исследование героев - totkotoriy - 27.05.2013 10:07

Ура! Спасибо! Наконец-то работает!
Надо сказать еще Bes"у и Valery, тоже давно хотели такие кнопки...


RE: Исследование героев - Berserker - 27.05.2013 17:22

Спасибо за тестирование.


RE: Исследование героев - Berserker - 31.05.2013 00:59




RE: Исследование героев - Berserker - 12.07.2013 14:42

solitaire345 Wrote:The town creature list is at memory 0x6747B4. The formula to calculate the address for particular dwelling is ((int *)0x6747B4+7*2*TownType+7*IsUpgraded+DwellingLevel)


   The town incomes are integers stored at these addresses:
   0x5BFA1A+1 - basic (500)
   0x5BFA2D+1 - town hall (1000)
   0x5BFA48+1 - city hall (2000)
   0x5BFA63+1 - capitol (4000)
   0x5BFABD+1 - grail bonus (5000)

   Also you can add bonus to gold income given by resource silo:
   The table of integers is at 0x688F04. There are 7 ints per town, corresponing to different resources. The last one is the value for gold.



RE: Исследование героев - hippocamus - 12.08.2013 00:19

Кто знает:
- что за лоды прописаны в экзешнике героев h3psprit и h3pbitma?
- они реально подгружаются или нет?


RE: Исследование героев - AKuHAK - 16.08.2013 01:39

Это лоды из патча 1.3 возрождения эрафии. Да они в те далёкие времена так назывались. И да все лоды грузятся до сих пор (порядок точный уже не помню). Если возникают ещё вопросы по поводу древних лодов милости просим под спойлеры в этой теме.
p - значит патч ))
Например в патче 2.1 добавились h3abp_sp.lod и h3abp_bm.lod


RE: Исследование героев - Berserker - 27.12.2013 23:09

4E2C70 - thiscall (*hero) (*art => 8 bytes, slot or -1) - equip art
4E2E40 - thiscall (*hero) (slot) - unequip art
4E2AB0 - thiscall (*hero) (art, slot) - check if artifact can be put in the slot



RE: Исследование героев - Berserker - 27.12.2013 23:39

Валерий напомнил мою старую функцию. Не помню, как работает.



RE: Исследование героев - Valery - 28.12.2013 08:55

(27.12.2013 23:09)Berserker Wrote:  ; x2 - art type
; x3 - art subtype or -1 (usually for non-scrolls)

Meh, this made me lose 1 hour and doubt about the state of my brain Tease

Artifact type should be read artifact number or ID, as type is always 5, is the subtype/number which changes. So I couldn't make the artifacts be equipped again until I found the trick.

; x2 - art ID
; x3 - art subtype or -1 (usually for non-scrolls) -this is not clear for me what it means, for now I leave it -1, works like that.

Combos switch work perfectly. Everything is perfect, joy.


RE: Исследование героев - Berserker - 28.12.2013 16:18

You always missunderstand the meaning of word "type". Not "object type" (where 5 for artifacts would be ok) but artifact type. Type is a matter of classification )


RE: Исследование героев - Valery - 28.12.2013 16:20

Well usually I know where to put type and subtype, but those SN:E I have no clue how they work, so I took your words as God's bible. Still not sure what the second is about, the -1. It works with so I don't worry for now.


RE: Исследование героев - Berserker - 03.01.2014 22:21

Перенаправление папки карт.
006755AC 68326D70
006772D0 68326D70
00794153 68326D70
007A4C0F 68326D70
007A4D7B 68326D70
007A4D87 68326D70
007A4D92 68326D70
007A4D9A 68326D70
007A5F38 68326D70
68326D70 = "h2mp", новое имя папки карт


RE: ERA II - igrik - 23.01.2014 17:34

код для отключения абилки суккубов и зверей
Code:
; НАЗВАНИЕ: Removes commanders disbalance abilities
; ВЕРСИЯ: 1.0
; АВТОР: Berserker
; ОПИСАНИЕ: Убирает у Суккубов присоединение монстров, а у Зверей - золото после боя
; EXE: TE

; 76CC35:
;    JNZ SHORT 0076CC3C => NOP(2)
307C35 9090

; 769A28:
;    JNZ SHORT 00769A2C => NOP(2)
304A28 9090



RE: ERA II - Berserker - 26.01.2014 01:03

Заплатка, умоляющая Хотовские карты пощадить старика ВоГа. Роешные карты могут пошаливать при этом, не проверял.


RE: ERA II - Berserker - 26.01.2014 01:20

Отключить способность Астрального духа


RE: Исследование героев - Berserker - 06.02.2014 19:24

feanor Wrote:;Replace standart terrains for towns

;0 Грязь Dirt
;1 Песок Beach
;2 Трава Grass
;3 Снег Snow
;4 Болото Swamp
;5 Скалы Desert (former Rough)
;6 Подземелье Wasteland (former Underground)
;7 Лава Lava
;8 Вода Water (will cause bugs when placed as native)
;9 Пропасть Rock (will cause bugs when placed as native)

;02;Knight
;02;Sorc
;03;Wizard
;07;Heretic
;00;Necromancer
;06;Warlock
;05;Barb
;04;Witch
;02;Gypsy

;Units' native terrains
006436A8 02;Knight
006436AC 02;Sorc
006436B0 03;Wizard
006436B4 07;Heretic
006436B8 00;Necromancer
006436BC 01;Warlock
006436C0 06;Barb
006436C4 04;Witch
006436C8 05;Gypsy

;RMG native terrains
006408D8 02;Knight
006408DC 02;Sorc
006408E0 03;Wizard
006408E4 07;Heretic
006408E8 00;Necromancer
006408EC 01;Warlock
006408F0 06;Barb
006408F4 04;Witch
006408F8 05;Gypsy

;Sand corridors
53300E 01; replacement of UG wasteland with sand

;Redirect some spec checks for wasteland to sand
532FB8 01
532FE8 01

;No wasteland battles at Z=1
464044 EB

;RMG preferences for neutral zones
; Default
;006824A0 00 00 00 00 01 00 00 00 04 00 00 00 FF FF FF FF;Dirt -> Castle, Rapart, Necropolis
;006824B0 06 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00;Sand -> Stronghold
;006824C0 00 00 00 00 01 00 00 00 FF FF FF FF 00 00 00 00;Grass -> Castle, Rampart
;006824D0 02 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00;Snow -> Tower
;006824E0 07 00 00 00 04 00 00 00 FF FF FF FF 00 00 00 00;Swamp -> Necr, Fort
;006824F0 06 00 00 00 08 00 00 00 FF FF FF FF 00 00 00 00;Rough -> Citadel, Conflux (instead of Forge)
;00682500 05 00 00 00 03 00 00 00 04 00 00 00 FF FF FF FF;UG -> Inferno, Necr, Dungeon
;00682510 03 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00;Lava -> Inferno
;00682520 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00;Water -> None

006824A0 0400000000000000FFFFFFFFFFFFFFFF;Dirt -> Necr, Knight
006824B0 030000000400000005000000FFFFFFFF;Beach(UG)-> Inferno, Necromancer, Warlock
006824C0 0100000000000000FFFFFFFFFFFFFFFF;Grass -> Sorc, Knight
006824D0 02000000FFFFFFFFFFFFFFFFFFFFFFFF;Snow -> Wizard
006824E0 0500000007000000FFFFFFFFFFFFFFFF;Swamp -> Warlock, Witch
006824F0 08000000FFFFFFFFFFFFFFFFFFFFFFFF;Desert -> Gypsy
00682500 06000000FFFFFFFFFFFFFFFFFFFFFFFF;Waste -> Barb
00682510 03000000FFFFFFFFFFFFFFFFFFFFFFFF;Lava -> Inferno
00682520 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;Water -> None



RE: Исследование героев - orzie - 06.02.2014 20:22

Ты бы поменял названия классов и террейнов на классические, а то у людей, что не знакомы с SW Mod может когнитивный диссонанс произойти)


RE: Исследование героев - Berserker - 23.05.2014 17:44

©GrayFace
Адрес текущего диалога
u4[u4[0x6992D0] + 0x54]


RE: Исследование героев - Bes - 12.06.2014 20:47

взято из Knightmare Commanders
Quote:Brute gets 250% exp as gold
Code:
769a45 14

commanders get stack experience
Code:
76ba75 C1

disable commander 4SS limit
Code:
769363 06

Disable old astral spirit Speciality
Code:
76cf3e 9090
76d1d0 9090

Paladin gets 250% experience
Code:
76968d FA



RE: Исследование героев - Berserker - 13.06.2014 23:44

Неплохо, особенно Паладин.


RE: Исследование героев - igrik - 25.06.2014 22:47

Quote:©GrayFace
Адрес текущего диалога
u4[u4[0x6992D0] + 0x54]

как правильно прочитать адрес?
6918864 это 6918864 в десятичной, а что с 0x54?
В итоге считать UN:C[0x6992D0]/4/?y1; или UN:C([0x6992D0] + 0x54])/4/?y1


RE: Исследование героев - Berserker - 26.06.2014 00:22

0x54 = 84.



RE: Исследование героев - gamecreator - 26.06.2014 01:10

0x - традиционно обозначение 16-й системы.


RE: Исследование героев - Berserker - 27.06.2014 01:36

Реализация альтерветок от МОРа (Click to View)



RE: Исследование героев - baratorch - 09.12.2014 12:29

Работа с опытом существ в ХД:



RE: Исследование героев - Berserker - 09.12.2014 21:23

Спасибо, полезно.


RE: Исследование героев - major - 03.03.2015 12:10

Подскажите, где найти функцию регенерации эликсира жизни. В воге/эре она подменяет стандартную, и вместо 50 хп регенит какой-то мусор, как мне кажется.


RE: Исследование героев - Algor - 03.03.2015 12:31

major Wrote:и вместо 50 хп регенит какой-то мусор, как мне кажется.

А разве должно 50 хп восстанавливаться?
FizMiG Wrote:Все войска героя (кроме undead, горгулий, големов и элементалей) получают 25% прибавку в HP и регенерируют до полного HP перед каждым ходом.



RE: Исследование героев - major - 03.03.2015 14:29

В соде 50 хп регенерируют, хотелось бы так и оставить.


RE: Исследование героев - Berserker - 03.03.2015 15:08

Полный реген делает бессмертными командиров и оруженосцев. Это фича! )


RE: Исследование героев - Ivor - 03.03.2015 19:14

(03.03.2015 15:08)Berserker Wrote:  Полный реген делает бессмертными командиров и оруженосцев.
Поэтому я предпочитал в качестве оруженосца брать привидение ))


RE: Баланс Heroes 3 HD Edition - Дьякон - 04.03.2015 15:41

Вот кстати адреса для СоДа, хотя может уже кто-то и выкладывал:

63AC58 - 5% урон за каждую единицу атаки
63AC28 - 300% - максимальный урон от базового
63B8C0 - 2.5% снижение урона за каждую единицу защиты
63AC50 - 100% база для вычитания урона
63B8B8 - 30% минимальный урон

все данные типа dq


RE: Исследование героев - Berserker - 04.03.2015 21:27

У приведения не полный реген, а очков 35, кажется.

Дьякон Wrote:Вот кстати адреса для СоДа, хотя может уже кто-то и выкладывал:

63AC58 - 5% урон за каждую единицу атаки
63AC28 - 300% - максимальный урон от базового
63B8C0 - 2.5% снижение урона за каждую единицу защиты
63AC50 - 100% база для вычитания урона
63B8B8 - 30% минимальный урон



RE: Исследование героев - gamecreator - 04.03.2015 23:57

(03.03.2015 12:10)major Wrote:  Подскажите, где найти функцию регенерации эликсира жизни. В воге/эре она подменяет стандартную, и вместо 50 хп регенит какой-то мусор, как мне кажется.
Посмотри, по адресу 0x446BD6 вызывается какая-то. Это подменяет Вог. После подмены там натуральный реген + опыт отрядов.


RE: Исследование героев - major - 05.03.2015 19:21

(04.03.2015 23:57)gamecreator Wrote:  
(03.03.2015 12:10)major Wrote:  Подскажите, где найти функцию регенерации эликсира жизни. В воге/эре она подменяет стандартную, и вместо 50 хп регенит какой-то мусор, как мне кажется.
Посмотри, по адресу 0x446BD6 вызывается какая-то. Это подменяет Вог. После подмены там натуральный реген + опыт отрядов.
Да, это я и нашел, а вот чем это подменяет вог, не могу найти.


RE: Исследование героев - gamecreator - 05.03.2015 19:49

Так запусти Вог, он и подменит этот вызов на свой. Ничего искать тут не надо.
Если надо, то можно бинарный патч сделать, который бы это отключал.


RE: Исследование героев - major - 09.03.2015 15:09

Спасибо, более-менее разобрался.
Такой вопрос. Никогда не писал dll. Может кто-нибудь показать на простом примере, как это делается? Допустим, расширить список существ с атакой-возвратом. Т.е. не расширить на всех существ, а просто добавить доп. проверки.
Code:
2F9059 CMP EAX,48
2F905C JE SHORT 2F90BB
2F905E CMP EAX,49
2F9061 JE SHORT 2F90BB
2F9063 CMP EAX,9B
2F9068 JE SHORT 2F908B
Добавить сюда проверку на 44h и 45h.
Или, через ерм_хукер.


RE: Исследование героев - gamecreator - 09.03.2015 15:43

Проще расширить на всех существ. Думаю, даже поместится вместо оригинального кода. Что-то типа
Code:
cmp [таблица+eax], 0
je short 2f908b
Перезаписываешь это в DLL_PROCESS_ATTACH или OnAfterWog.


RE: Исследование героев - feanor - 09.03.2015 18:27

У меня сделано как-то так

Code:
#include "targetver.h"

#include <windows.h>
#include <stdlib.h>
#include <stdio.h>

#include "..\..\include\patcher_x86_commented.hpp"
#include "..\..\include\HotA\HoMM3.h"
#include "..\..\include\era.h"

Patcher * globalPatcher;
PatcherInstance *patcher;

int __stdcall StrikeAndReturn (LoHook* h, HookContext* c)
{
    int unit = c->eax;


    if (advanced_properties[unit].strike_n_ret)
    {
        if(o_CreatureInfo[unit].flags &1)
            c->return_address = 0x75E08B;
        else
            c->return_address = 0x75E0BB;
    }
    else
    {
        c->return_address = 0x75E06A;
    }
    return NO_EXEC_DEFAULT;
}


int __stdcall StrikeAndReturnButton (LoHook* h, HookContext* c)
{
    int unit = *(int*)(c->ebp-4);
    if(advanced_properties[unit].strike_n_ret)
    {
        c->return_address = 0x762969;
    }
    else
    {
        c->return_address = 0x762955;
    }
    return NO_EXEC_DEFAULT;
}


void __stdcall PatchIt (PEvent e)
{
        patcher->WriteLoHook(0x75E059,(void*)StrikeAndReturn);
        patcher->WriteLoHook(0x762940,(void*)StrikeAndReturnButton);
}

BOOL APIENTRY DllMain( HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
    if (ul_reason_for_call == DLL_PROCESS_ATTACH)
    {
        globalPatcher = GetPatcher();
        patcher =  globalPatcher->CreateInstance("h2sw_creatures");
        ConnectEra();
        RegisterHandler(PatchIt,"OnAfterCreateWindow");
    }
    return TRUE;
}

правда, я еще не проверял))


RE: Исследование героев - major - 09.03.2015 19:04

Для таблицы же тоже место выделить надо в экзешнике? Что значит DLL_PROCESS_ATTACH, т.е. каким образом это сделать?


RE: Исследование героев - gamecreator - 09.03.2015 19:10

Не обязательно в экзешнике, в твоей длл тоже можно. Что такое DLL_PROCESS_ATTACH у feanorа в примере очень понятно написано.


RE: Исследование героев - Дьякон - 10.03.2015 18:51

Процедура расчета для дипломатии:
0x4A73B0

Коэффициенты для расчета Power_Factor из ФизМига (см. со стр. 303)
63E500 - 7
63AC50 - 1
63B9E0 - 2
63AC70 - 0,5
63E4F8 - 0,333


RE: Исследование героев - major - 11.03.2015 13:51

В коде феанора все более-менее понятно, но есть пара вопросов.
1. advanced_properties[unit].strike_n_ret - это свойство юнита определено где-то ранее?
2.
Code:
#include "targetver.h"

#include <windows.h>
#include <stdlib.h>
#include <stdio.h>

#include "..\..\include\patcher_x86_commented.hpp"
#include "..\..\include\HotA\HoMM3.h"
#include "..\..\include\era.h"
Чтобы скомпилировать, нужны все эти файлы?


RE: Исследование героев - gamecreator - 11.03.2015 14:08

Судя по всему, advanced_properties - просто новый массив из Хоты. Если тебе не хочется ничего расширять, то напиши свою проверку в условии, без массивов.


RE: Исследование героев - feanor - 11.03.2015 15:12

Quote:1. advanced_properties[unit].strike_n_ret - это свойство юнита определено где-то ранее?
да

Quote:Чтобы скомпилировать, нужны все эти файлы?
где-то я уже выкладывал свою папку с инклудами
https://dl.dropboxusercontent.com/u/61759222/HoMM/include.zip

а, и заодно сам пример (MSVS 2008)
https://dl.dropboxusercontent.com/u/61759222/HoMM/sample.zip

единственно что, я его написал, но еще не проверял в работе))


RE: Исследование героев - gamecreator - 11.03.2015 15:56

Вообще польза от использования патчера в этом конкретном случае достаточно сомнительна. Если два мода независимо добавляют атаку с возвратом, то никакой патчер их совместимыми не сделает.


RE: Исследование героев - feanor - 11.03.2015 16:00

Quote:Вообще польза от использования патчера в этом конкретном случае достаточно сомнительна.

Чтоб не на ассемблере писать, тащемта


RE: Исследование героев - gamecreator - 11.03.2015 17:37

Ну это уже личный выбор каждого.


RE: Исследование героев - major - 13.03.2015 21:30

Вроде бы немного разобрался, спасибо.


RE: Исследование героев - major - 15.03.2015 19:16

Немного переделал регенерацию.
Code:
// dllmain.cpp: определяет точку входа для приложения DLL.
#include "stdafx.h"

#include "..\..\include\patcher_x86_commented.hpp"
#include "..\..\include\HotA\HoMM3.h"
#include "..\..\include\era.h"

Patcher * globalPatcher;
PatcherInstance *patcher;

int __stdcall RegenerationCheck (LoHook* h, HookContext* c)
{
    if (((_BattleStack_*)c->esi)->count_current < ((_BattleStack_*)c->esi)->count_at_start)
    {
    c->return_address = 0x446BD3;
    }
    else
    {
        if (((_BattleStack_*)c->esi)->lost_hp > 0)
        {
        c->return_address = 0x446BD3;
        }
        else
        {
        c->return_address = 0x446DF1;
        }
    }
    return NO_EXEC_DEFAULT;
}

int __stdcall RegenerationFull (LoHook* h, HookContext* c)
{
    int regen = *(int*)0x2846BC8;
    int number = ((_BattleStack_*)c->esi)->count_current;
    int bnumber = ((_BattleStack_*)c->esi)->count_at_start;
    int lowhp = ((_BattleStack_*)c->esi)->lost_hp;
    int hp = ((_BattleStack_*)c->esi)->full_hp;
    if (regen <= lowhp)
    {
        lowhp -= regen;
        ((_BattleStack_*)c->esi)->lost_hp = lowhp;
    }
    else
    {
        regen -= lowhp;
        int count = 1;
        while (regen > hp)
        {
            regen -= hp;
            count += 1;
        }
        number += count;
        if (number > bnumber)
        {
            number = bnumber;
            lowhp = 0;
        }
        else
        {
            lowhp = hp - regen;
        }
        ((_BattleStack_*)c->esi)->lost_hp = lowhp;
        ((_BattleStack_*)c->esi)->count_current = number;
    }

    c->return_address = 0x446C3F;
    return NO_EXEC_DEFAULT;
}

int __stdcall Regeneration (LoHook* h, HookContext* c)
{
    int unit = c->eax;
    int regenhp = 0;
    if (unit == 4 || unit == 46 || unit == 47 || unit == 61)
    {
        regenhp += 40;
    }
    if (unit == 5)
    {
        regenhp += 50;
    }
    if (unit == 60)
    {
        regenhp += 30;
    }
    if (unit == 80 || unit == 81 || unit == 144)
    {
        regenhp += 80;
    }
    if (unit == 110 || unit == 193)
    {
        regenhp += 100;
    }
    if (unit == 111 || unit == 168)
    {
        regenhp += 150;
    }
    if (unit == 157)
    {
        regenhp += 200;
    }
//    if (unit == 159)
//    {
//        regenhp += 40;
//    }
    if (regenhp > 0)
    {
        *(int*)0x2846BC8 = regenhp;
        c->return_address = 0x75DF2A;
    }
    else
    {
        c->return_address = 0x75DE8E;
    }
    return NO_EXEC_DEFAULT;
}

void __stdcall PatchIt (PEvent e)
{
        patcher->WriteLoHook(0x75DE66,(void*)Regeneration);
        patcher->WriteLoHook(0x446BCD,(void*)RegenerationCheck);
        patcher->WriteLoHook(0x446C2B,(void*)RegenerationFull);
}

BOOL APIENTRY DllMain( HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
    if (ul_reason_for_call == DLL_PROCESS_ATTACH)
    {
        globalPatcher = GetPatcher();
        patcher =  globalPatcher->CreateInstance("abilities");
        ConnectEra();
        RegisterHandler(PatchIt,"OnAfterCreateWindow");
    }
    return TRUE;
}
Подскажите по двум вопросам.
1. Как добавить проверку на эликсир жизни, чтоб он добавлял еще 50 хп к регену.
2. Регенерация от опыта существ работает как-то по-другому? Этот хук не срабатывает, реген проходит без воскрешения. Как это можно исправить?


RE: Исследование героев - feanor - 15.03.2015 19:30

Quote:1. Как добавить проверку на эликсир жизни, чтоб он добавлял еще 50 хп к регену.

o_BattleMgr->hero[((_BattleStack_*)c->esi)->side]->DoesWearArtifact(ID), как-то так


RE: Исследование героев - gamecreator - 15.03.2015 20:15

1. Что-то типа (с указанием героя, конечно)
Code:
Era::ExecErmCmd("HE:A2/131/?v1/?v1;");
if (Era::v[1]>0) ...
2. Выдержка из исходников Вога:
Code:
void IsTroll(void)
{
  __asm{
    mov    IT_Mon,esi
    mov    edx,50 // умолчательное восстановление здоровья
    mov    IT_Edx,edx
    cmp    eax,0x3C
    je     l_Ok
    cmp    eax,0x3D
    je     l_Ok
    cmp    eax,0x90
    je     l_Ok
    cmp    eax,157 // гидра
    je     l_Ok_check
//    jmp   l_Exit
    pusha
  }
  __asm mov IDummy,eax
  #include "templ.h"
  IT_Ret=CanNPCRegenerate(IDummy,IT_Mon);
  if(IT_Ret!=-1){
    IT_Ret=CrExpBon::Regenerate(IT_Mon,*(int *)&IT_Mon[0x58]);
    if(IT_Ret==0){ // no reg
      IT_Ret=0;
    }else{ // yes
      IT_Edx=IT_Ret;
      IT_Ret=-1;
    }
  }
  STOP
  __asm{
     popa
     mov    eax,IT_Ret
//    je    _Ok_check
     jmp    l_Exit
  }
l_Ok_check:
  CalcRand100();
  __asm{
    cmp    eax,40  // 40%
    ja     l_Exit
  }
l_Ok:
  __asm mov    eax,-1
l_Exit:
  __asm mov    edx,IT_Edx
}
Это та функция, что перезаписывается по 0x446BD6.
CrExpBon::Regenerate - это стандартная регенерация от опыта.


RE: Исследование героев - feanor - 17.03.2015 03:41

Как можно перебрать все объекты определенного типа/подтипа кодом?
ну, то бишь, как это делает Вог в UN:U?)

..эм
пробегать всю карту каждый раз? серьезно?


RE: Исследование героев - Дьякон - 17.03.2015 12:56

feanor, думаю серьезно.
------------------------------------------------------------------
63E9B8 - % для навыков некромантии/чародейства (массив из 4 dword)
476DA0 - воскрешение нечести после боя
4E3F40 - расчет % чародейства(некромантии) с учетом артефактов и специальностей


RE: Исследование героев - gamecreator - 17.03.2015 13:36

Конечно же, если нужны не сами объекты, а только их структуры (если есть), то тут уже можно найти их список.


RE: Исследование героев - Algor - 17.03.2015 16:47

(17.03.2015 12:56)Дьякон Wrote:  63E9B8 - % для навыков некромантии/чародейства (массив из 4 dword)
476DA0 - воскрешение нечести после боя
4E3F40 - расчет % чародейства(некромантии) с учетом артефактов и специальностей
А как при помощи ERM отключить навык Некромантии (со всеми артефактами, ПКН'ами и пр. усилителями некромантии)?


RE: Исследование героев - Дьякон - 17.03.2015 17:06

Через UN:C забиваешь для всех уровней некромантии 0, соответственно воскрешаться никто не будет.


Хотя не, нужно еще артефакты все отключать, т.к. там абсолютное приращение идет к %. Если нужно, то найду и выложу все адреса по некромантии.


RE: Исследование героев - Дьякон - 17.03.2015 17:20

Code:
0x63EAE4 - амулет гробовщика 5%
0x63B8D0 - мантия и усилители 10%
0x63EB28 - сапоги 15%
0x63B8B4 - грааль 20%
0x63EB24 - плащ 30%
Все обнулить и по идее будет счастье

Хотя можно сделать еще проще. Задать максимальный % воскресших 0%, который сейчас 100%. Но возможно с ним могут быть проблемы, т.к. данная константа может использоваться и в других расчетах, например как 0x63B8D0 одновременно отвечает и за мантию и за усилители.


RE: Исследование героев - Дьякон - 17.03.2015 17:40

Вот так будет (должно) работать и не нужно трогать константы:


И да константы универсальные и их правка не рекомендуется.


RE: Исследование героев - Algor - 18.03.2015 01:15

Спасибо, проверю на днях.


RE: Исследование героев - Дьякон - 19.03.2015 15:16

4A7530 - jmp определяющий вступят в бой или другие условия присоединиться. Отключение jmp - отключает дипломатию,т.е.



RE: Исследование героев - Дьякон - 24.03.2015 17:22

Подскажите адрес указателя на распакованную текущую карту, если таковой имеется?


RE: Исследование героев - igrik - 24.03.2015 17:36

может что то типо этого или где-то тут, а может и нет....



RE: Исследование героев - feanor - 24.03.2015 18:09

Quote:Подскажите адрес указателя на распакованную текущую карту, если таковой имеется?
что конкретно интересует?

Code:
#define o_GameMgr (*(_GameMgr_**)0x699538)

в нем поля
  
  // Заголовочная информация карты игры.
  _MapHeader_ map_header; // +1F86Ch
  // Карта игры.
  _GameMap_ Map; // +1FB70h



RE: Исследование героев - Дьякон - 25.03.2015 18:08

Вот, что я искал - функции генератора карт:
54AE02 - вызов функции, которая устанавливает доступные артефакты. arg1 - колво байт, arg2 - буфер
54AF1B - вызов функции, которая устанавливает доступные заклинания. arg1 - колво байт, arg2 - буфер
54AF6E - вызов функции, которая устанавливает доступные вторичные навыки. arg1 - колво байт, arg2 - буфер

arg1 - указывает сколько байт будет считано из буфера (указатель arg2). В буфере хранится побитовая маска доступных артефактов/заклинаний/навыков.

Т.е. подменяя буфер, можно заставить рандомный генератор карт создавать карты с необходимой спецификацией. (например выкинуть имбалансные арты, или ненужные/редко используемые навыки)


RE: Исследование героев - Algor - 25.03.2015 19:48

Дьякон Wrote:например выкинуть имбалансные арты, или ненужные/редко используемые навыки
Водные артефакты/Навигацию на безводных картах. В ХотА вроде есть такое, у меня в ES скриптом сделано. Но отдельный бинарный фикс будет лучше, имхо.
Что касается остальных артов/навыков, то их надо править и балансировать вместо того, чтобы вырезать.


RE: Исследование героев - Дьякон - 25.03.2015 20:11

(25.03.2015 19:48)Algor Wrote:  Водные артефакты/Навигацию на безводных картах. В ХотА вроде есть такое, у меня в ES скриптом сделано. Но отдельный бинарный фикс будет лучше, имхо.
Что касается остальных артов/навыков, то их надо править и балансировать вместо того, чтобы вырезать.
В СоДе скриптов нет, а балансить можно и со временем. Сначала выкинуть все, что мешает, а там видно будет. Вообще конечно можно вставить код и менять спецификацию перед началом карты как в скриптах, например. Но все же мне кажется настроить генератор как-то более правильным что ли. Хотя разницы практически никакой.


RE: Исследование героев - SyDr - 25.03.2015 23:07

Подскажите, плиз, какой формат имеет файл с настройками (.dat)? Каким образом его лучше всего сжать?


RE: Исследование героев - Berserker - 26.03.2015 00:37

Эм, 1000 настроек по 4 байта каждая со значением 0 или 1? ))) Сжать можно чем угодно: Проще всего преобразовать в массив битов, тогда это будет 125 байт. Если много, тогда кодирование бегущих длин или как там RLE )


RE: Исследование героев - SyDr - 26.03.2015 08:34

Ага. Только там ещё 2 и 3 переодически встречаются. Короче, что-то типа RLE вполне пойдёт (мне нужно в текст жать):



RE: Исследование героев - Berserker - 27.03.2015 01:29

Уже не помню, 2 и 3 м.б опции множественного выбора (radio-кнопки)?

Да, сойдёт.


RE: Исследование героев - igrik - 30.03.2015 23:17

Обновляет весь диалог и при любом разрешении экрана (с HD и без него). В том числе и арты
PS: не без помощи Berserker'a


RE: Исследование героев - Berserker - 30.03.2015 23:20

Здорово. Нужно будет обязательно включить в Эру, обновив SN:D.


RE: Исследование героев - gamecreator - 30.03.2015 23:36

А есть ли шанс, что ExecErmCmd начнёт корректно обрабатывать IF:M?


RE: Исследование героев - Valery - 30.03.2015 23:41

20

Thanks, will test. Do I need to add Mop function?


RE: Исследование героев - igrik - 30.03.2015 23:44

No, it is not necessary.


RE: Исследование героев - Valery - 30.03.2015 23:47

I think I will remove from HMS mod the total swap of backpacks (19-82 slots at once), it creates some bugs: all okay, I switch a lot between heroes, then later in game, sometimes it says backpack full, but is not; then when searching with erm, there are empty slots, probably conflict, no clue why. I will add instead this swap, alt+click, like in HD mod.


RE: Исследование героев - igrik - 30.03.2015 23:51

Ок. Ты организатор мода и тебе решать


RE: Исследование героев - Valery - 31.03.2015 00:41

But for faster switch of backpacks, maybe a better idea would be shift+right/left-click directly from backpack when backpack open, what you think? You did the backpack script, do you think such thing could be possible?




RE: Исследование героев - Berserker - 31.03.2015 00:42

gamecreator, так вроде бы и раньше работала IF:M. Какой конкретно код?
Valery, I thought I fixed artifact deletion function. It had bugs in 3.58, not decrementing artifacts counter, thus one day you see "no space" message. But after fixing in Phoenix there is not more any problem for years. Which code did you use to delete artifact?


RE: Исследование героев - Valery - 31.03.2015 00:51

We used your code to delete artifacts from equipped slots. I used my script for deleting all artifacts from hero x backpack and transfer them all to hero y. As it worked okay, we didn't check if your function is necessary also for backpack, but after testing several games, I get sometimes message "backpack full" (only when trying to discard an equipped artifact) while is not. But I don't know what causes it and can't reproduce the error.

Last part of the script (deleting adding artis):
   



RE: Исследование героев - Berserker - 31.03.2015 01:39

RightHeroGlobalStorage, em, how do you control this counter when player simple drops/equips/unequips artifact? Maybe just count real artifacts by looping all 64 slots?


RE: Исследование героев - feanor - 31.03.2015 01:42

из структуры героя
Code:
_Artifact_ doll_art[19]; // +301
_byte_ free_add_slots; // +453
_byte_ locked_slot[14]; // +454
_Artifact_ backpack_art[64]; // +468
_byte_ backpack_arts_count; // +980
может быть, что-то с эим?


RE: Исследование героев - Valery - 31.03.2015 01:46

Up to date storage is checked when CM3 trigger:




RE: Исследование героев - gamecreator - 31.03.2015 02:42

(31.03.2015 00:42)Berserker Wrote:  gamecreator, так вроде бы и раньше работала IF:M. Какой конкретно код?
Я уже и не помню. Сходу воспроизвести баг не удалось, посмотрю ещё. Теперь я даже сомневаюсь, был ли он вообще.


RE: Исследование героев - Valery - 31.03.2015 15:32

igrik, done, works ok.
Ybackpack.erm

There is a last problem and I don't know how to solve or if it is solvable.

All works well, but if I have two of same artifacts consecutive in backpack, it deletes the previous one when clicking on second (if left to right). This is because the erm code is searching for first artifact of that kind in backpack. Result is correct but visually is weird. Don't know a solution.


RE: Исследование героев - igrik - 31.03.2015 16:05

В конце появилось три печатки, а было две. Баг?


RE: Исследование героев - Valery - 31.03.2015 16:07

No, I don't think so, I had a double click (can be heard) and left hero had more than 5 gloves. Result is correct, but it looks weird. erm code is searching from left to right.


RE: Исследование героев - Berserker - 31.03.2015 23:55

Not a big problem it is )


RE: Исследование героев - Algor - 03.04.2015 01:13

(17.03.2015 17:06)Дьякон Wrote:  Через UN:C забиваешь для всех уровней некромантии 0, соответственно воскрешаться никто не будет.


Не те адреса, похоже. Есть верные для установки своих значений (не обнуления)?


RE: Исследование героев - feanor - 03.04.2015 02:34

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

http://forum.df2.ru/index.php?showtopic=6139


RE: Исследование героев - Дьякон - 03.04.2015 10:41

(03.04.2015 01:13)Algor Wrote:  Не те адреса, похоже. Есть верные для установки своих значений (не обнуления)?
Адреса те. Почитай несколько постов ниже после этого сообщения. Я писал, что кроме навыка некромантии на воскрешение влияет и прочие артефакты и строения.. Вот еще раз код



RE: Исследование героев - Дьякон - 03.04.2015 10:46

(03.04.2015 02:34)feanor Wrote:  Все украдено до нас же.
Причем настолько давно, что никто уже и не помнит.

http://forum.df2.ru/index.php?showtopic=6139
Я помнил, только не нашел. Пришлось самому искать.


RE: Исследование героев - Algor - 03.04.2015 11:33

(03.04.2015 10:41)Дьякон Wrote:  Адреса те. Почитай несколько постов ниже после этого сообщения. Я писал, что кроме навыка некромантии на воскрешение влияет и прочие артефакты и строения.. Вот еще раз код

Algor Wrote:Есть верные для установки своих значений (не обнуления)?

Очевидно, я где-то торможу... но это
и это
даже при отсутствии прочих артефактов и строений дают одинаковый результат, подозрительно похожий на штатную работу Некромантии...

PS: да, и попытка прочитать по этим адресам также возвращает что-то неожиданное (точных цифр не помню, дома вчера было). Собсно, поэтому и усомнился в их правильности.


RE: Исследование героев - Дьякон - 03.04.2015 14:17

Там данные в формате float и там не прокатит такое
15, 30,50 в формате флоат - стремится к нулю.
Мое упущение что не написал. Будет так

Не знаю может конечно в ерм есть перевод в флоат, если нет то нужно либо конвертор писать либо на калькуляторе переводить.


RE: Исследование героев - Berserker - 03.04.2015 15:30




RE: Исследование героев - Дьякон - 03.04.2015 17:10

Algor, и еще да ты прав на счет адресов, они явно идут не по порядку. Не знаю как я считал. Только первый адрес правильный.



RE: Исследование героев - Algor - 03.04.2015 22:40

(03.04.2015 17:10)Дьякон Wrote:  Algor, и еще да ты прав на счет адресов, они явно идут не по порядку. Не знаю как я считал. Только первый адрес правильный.

Чёт ты опять как-то не так посчитал: 15 -> 1097859072

!!SN:Xe1 X?y1; работает отлично.

Дьякон, Берс, спасибо 132


RE: Исследование героев - Berserker - 03.04.2015 23:09

На здоровье Ab


RE: Исследование героев - gamecreator - 03.04.2015 23:13

(03.04.2015 22:40)Algor Wrote:  Чёт ты опять как-то не так посчитал: 15 -> 1097859072
15%, а не 1500% же. Там значение не в процентах.


RE: Исследование героев - Algor - 04.04.2015 00:38

(03.04.2015 23:13)gamecreator Wrote:  
(03.04.2015 22:40)Algor Wrote:  Чёт ты опять как-то не так посчитал: 15 -> 1097859072
15%, а не 1500% же. Там значение не в процентах.
Блин, точно... И тебе спасибо ))


RE: Исследование героев - Algor - 04.04.2015 01:52

(03.04.2015 17:10)Дьякон Wrote:  Algor, и еще да ты прав на счет адресов, они явно идут не по порядку. Не знаю как я считал. Только первый адрес правильный.

Вы будете смеяться... но практика показывает что верные адреса эти:
Это действительно так, или это мои глюки при попытке писать "на сухую"? Экспериментировал без артов/строений/специализаций, если что.

*Пошел в холодильник за пивом*


RE: Исследование героев - Berserker - 04.04.2015 02:19

По-моему все эти адреса уже сто лет как были найдены Демиургом и оформлены в функцию. И да, там по три числа с плавающей запятой подряд идут.


RE: Исследование героев - gamecreator - 04.04.2015 03:11

В теме Демиург говорил о возможности менять силу навыка на нулевом уровне. Так что вполне возможно, что там по четыре числа подряд.


RE: Исследование героев - Дьякон - 04.04.2015 10:52

(04.04.2015 01:52)Algor Wrote:  Это действительно так, или это мои глюки при попытке писать "на сухую"? Экспериментировал без артов/строений/специализаций, если что.
Да это так. Там 4 значения. Первое нулевое. Да и пользуйся функцией Демиурга, т.к. проверять данные не входит в мои привычки ))))


RE: Исследование героев - Berserker - 04.04.2015 15:18

Более того, я эту функцию перевёл под Эру и опубликовал здесь и на HC. Эх, всё хочу сделать ресурс, где такая информация хранилась бы отдельными записями. Неужели плодить подфорум и темы?


RE: Исследование героев - Algor - 04.04.2015 15:37

Berserker Wrote:Более того, я эту функцию перевёл под Эру и опубликовал здесь и на HC...
Не видел. А в эровском хэлпе про нее что-нить сказано?


RE: Исследование героев - Berserker - 04.04.2015 15:58

Оригинал: http://forum.df2.ru/index.php?showtopic=6139


RE: Исследование героев - Berserker - 25.04.2015 01:01

(30.03.2015 23:17)igrik Wrote:  
Обновляет весь диалог и при любом разрешении экрана (с HD и без него). В том числе и арты
PS: не без помощи Berserker'a

Игрик, я верно твою функцию преобразовал?

Code:
MOV ECX, [$6A3D90]
PUSH 0
MOV EAX, $5AF4E0
CALL EAX

MOV ECX, [$6A3D90]
PUSH 1
MOV EAX, $5AF4E0
CALL EAX

MOV ECX, [$6A3D90]
MOV EAX, $5B1200
CALL EAX

MOV ECX, [$6A3D90]
MOV ECX, [ECX + 56]
MOV EAX, [ECX]
MOV EAX, [EAX + 20]
PUSH $0000FFFF
PUSH $FFFF0001
PUSH 0
CALL EAX

MOV ECX, [$6992D0]
PUSH DWORD [$40144F] // 600
PUSH DWORD [$401448] // 800
PUSH 0
PUSH 0
MOV EAX, $603190
CALL EAX



RE: Исследование героев - igrik - 27.05.2015 13:44

ток увидел сообщение Bad
Я не знаю, Берс. Я в этом не шарю

thx gamecreator


RE: Исследование героев - Berserker - 27.05.2015 19:30

Я уже проверил, вроде бы работает )


RE: Исследование героев - gamecreator - 15.08.2015 18:53

float thiscall hero->0x4e3f40(bool capAt1) - получить силу некромантии героя
Результат возвращается в стеке FPU.

int thiscall hero->0x4e3ed0() - получить поднимаемое некромантией этого героя существо


RE: Исследование героев - gamecreator - 25.08.2015 01:40

Кто-нибудь имеет список BM:G хаков для изменения разнообразных скрытых параметров? Или описание структуры отряда в битве. Буду благодарен.


RE: Исследование героев - feanor - 26.08.2015 01:08

Code:
NOALIGN struct _BattleStack_ : public _Struct_ // размер 0x548
{
    _byte_ already_attack;    // +0 ?
    _byte_ field_01;        // +1 ?
    _byte_ field_02;        // +2 ?
    _byte_ field_03;        // +3 ?
    _byte_ field_04[4];        // +4 ?

    _int32_ all_stacks_count; // +8  //полное число стеков у игрока

    _byte_ field_0C[4];        // +12 0x0C
    _dword_ field_10;        // +16 0x10  //=-1 после атаки и/или ответа(????)
    _byte_ field_14[8];        // +20 0x14  ?

    _int32_ aim_to_move_or_shoot; // 28 +0x1C  //позиция на поле боя (куда бежать/стрелять)
    _byte_ fireshield;        // +32 0x20 // огненный щит

    _byte_ field_21[7];        // +33 0x21  ?

    _int32_ clone_index;    // +40 0x28 //номер стэка клона этого

    _byte_ field_2C[4];        // +44 0x2C  ?
    _dword_ field_30;        // +48 0x30  ?

    _int32_ creature_id;                // +52 0x34 // тип монстра
    _int32_ hex_ix;            // +56 0x38  //позиция на поле боя
    _int32_ def_group_ix;    // +60 0x3C
    _int32_ def_frame_ix;    // +64 0x40

    _dword_ second_hex_is_right;        // +68 0x44 //(=1) сдвиг в сторону второй занятой клетки для монстра с двумя клетками
    _dword_ field_48;        // +72 0x48 ?

    _int32_ count_current;    // +76 0x4C // число монстров
    _int32_ count_before_attack; // +80 +0x50 // число монстров до удара по ним в тек. атаку
    
    _dword_ field_54;        // +84 0x54 ?
    
    _int32_ lost_hp;        // +88 0x58 потери здоровья последнего монстра
    _int32_ army_slot_ix;    // +92 0x5C номер слота of _Army_ (0...6), -1 - будет удален после битвы
    _int32_ count_at_start;    // +96 0x60 число монстров в начале битвы
    
    _dword_ field_64;        // +100 0x64 ?
    
    _dword_ anim_value;        // +104 0x68 = cranim.f[15] при инициализации
    _int32_ full_hp;        // +108 0x6C полное здоровье (исп. как база для лечения)
    
    _bool32_ field_70;        // +112 0x70 ?

//////////////////////////////////////////////////////////////////////////////////
    _CreatureInfo_ creature;
//////////////////////////////////////////////////////////////////////////////////
    //_int_ town;        //+116 0x74
    //_int_ level;        //+120 0x78
    //_char_* sound_name;        //+124 0x7C
    //_char_* def_name;        //+128 0x80
    //_int_ flags;        //+132 0x84
    //_char_* name_single;        //+136 0x88
    //_char_* name_plural;        //+140 0x8C
    //_char_* specification_description;        //+144 0x90
    //_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
    //_int_ cost_gold;        //+172 0xAC
    //_int_ fight_value;        //+176 0xB0
    //_int_ AI_value;        //+180 0xB4
    //_int_ growth;        //+184 0xB8
    //_int_ horde_growth;        //+188 0xBC
    //_int_ hit_points;        //+192 0xC0
    //_int_ speed;        //+196 0xC4            
    //_int_ attack;        //+200 0xC8
    //_int_ defence;        //+204 0xCC
    //_int_ damage_min;        //+208 0xD0
    //_int_ damage_max;        //+212 0xD4
    //_int_ shots;        //+216 0xD8
    //_int_ spells_count;        //+220 0xDC
    //_int_ advmap_low;        //+224 0xE0
    //_int_ advmap_high;        //+228 0xE4
///////////////////////////////////////////////////////////////////////////////

    _byte_ field_E8;        // +232 0xE8  ?

    _bool8_ is_1_killed;    // +233 0xE9   =1, если умирал хоть один
    _bool8_ is_killed;        // +234 0xEA   =1, если был убит весь стэк

    _byte_ field_EB;        // +235 0xEB  ?

    _int32_ current_creatures_spell_id; // +236 0xEC  номер заклинания существа в тек раунде 0x50 Acid breath
    
    _int32_ field_F0;        // +240 0xF0  _byte_=1 перед атакой на него 441434
    
    _int32_ side;            // +244 0xF4  0 - attacker, 1 - defender
    
    _dword_ index_on_side;                // +248 F8 dd = номер стэка у стороны на поле боя
    _dword_ field_FC;        // +252 FC dd = ? что-то с магией
    _dword_ field_100;        // +256 100 dd 43DEA4
    _dword_ field_104;        // +260 104 dd 43DEAD
    _dword_ field_108;        // +264 108 dd
    _dword_ field_10C;        // +268 10C dd
    
    _CreatureAnim_ cr_anim;    // +272 0x110
    _Def_* def;                // +356 0x164 def монстра, загрузка: 43DA8E
    _Def_* def_shot;        // +360 0x168 def выстрела, загрузка: 43DA8E
    _dword_ field_16C;        // +364 0x16С ?
    _Wav_* wav_move;        // +368 0x170 звук перемещения (move), загрузка: 43DA8E
    _Wav_* wav_attack;        // +372 0x174 звук атаки (attk/wnce/shot), загрузка: 43DA8E
    _Wav_* wav_wnce;        // +376 0x178 звук 'колдует' (wnce), загрузка: 43DA8E
    _Wav_* wav_shot;        // +380 0x17C звук выстрела (shot), загрузка: 43DA8E
    _Wav_* wav_kill;        // +384 0x180 звук смерти (kill), загрузка: 43DA8E
    _Wav_* wav_defend;        // +388 0x184 звук обороны (wnce/dfnd), загрузка: 43DA8E
    _Wav_* wav_ext1;        // +392 0x188 звук дополнительный 1 (ext1), загрузка: 43DA8E
    _Wav_* wav_ext2;        // +396 0x18С звук дополнительный 2 (ext2), загрузка: 43DA8E
    
    _dword_ field_190;        // +400 0x190 ?
    
    _int32_ active_spells_count; // +404 0x194 dd = количество уже наложенных заклинаний
    _int32_ active_spell_duration[81]; // +408 0x198  есть заклинание (длительность) или нет
    _int32_ active_spells_power[81]; // +732 0x2DC (сила действия заклинания)
    
    _byte_ field_420[52];    // +1056 0x420 ?
    
    _int32_ retaliations;    // +1108 0x454 // 441B17 (кол-во ответов на атаку 0= не отв. на атаку)// настройка для грифонов 46D6A0
    _int32_ bless_value;    // +1112 0x458 Bless добавка к Max. Damage
    _int32_ curse_value;    // +1116 0x45C Curse убавка к Min. Damage
    _int32_ field_460;        // +1120 0x460 ?
    _int32_ bloodlast_value;// +1124 0x464 Bloodlast добавка к Атаке с бонусами
    _int32_ precision_value;// +1128 0x468 Precision добавка к Атаке с бонусами
    
    _byte_ field_46C[32];    // +1132 0x46C ?
    
    _int32_ king_type;        // +1164 0x48C dd KING_123 тип (1=KING_1,2=KING_2,3=KING_3) //   исп для расчета Slayer. Бонус 8 к Атаке: 0x4421D2    
    _int32_ field_490;        // +1168 0x490 dd номер атакера по порядку??? уже атаковал??? (сбрасывается после первого удара)
    _int32_ counerstrike_retaliations; // +1172 0x494 dd кол. доп. ответов на атаку, добавленных Counerstrike заклом
    
    _byte_ field_498[40];    // +1176 0x498 ?
    
    _bool8_ blinded;            // +1216 0x4C0 db Blinded - снизить защиту (сбросить после?) при атаке на него (уст. перед ударом)
    _bool8_ paralized;            // +1217 0x4C1 db Paralized - снизить защиту (сбросить после?) при атаке на него (уст. перед ударом)
    _bool8_ forgetfulness;        // +1218 0x4C2 dd Forgetfulness - уровень (>2 - не может стрелять)
    
    _byte_ field_4C3[25];        // +1219 0x4C3 ?
    
    _int32_ defend_bonus;        // +1244 0x4DC dd = величина бонуса при выборе защиты
    _int32_ faerie_dragon_spell;// +1248 0x4E0 dd заклинание для сказ дракона

    _byte_ field_4E4[100];

                     // +4EC dd 44152A
                     // +4F1 db 43DF88

                     // +514 dd
                     // +518 dd -> dd first \ adjusted stacks pointers
                     // +51C dd -> dd last  /

                     // +524 dd
                     // +528 dd -> dd first \ adjusted to wich stacks pointers
                     // +52C dd -> dd last  /

};



RE: Исследование героев - gamecreator - 26.08.2015 10:16

Большое спасибо.


RE: Исследование героев - igrik - 10.09.2015 18:17

Изменение координат отображения WoG диалогов DL
thanks gamecreator, sergroj.



RE: Исследование героев - Algor - 10.09.2015 18:38

igrik, т.е. можно показывать диалог не по центру?
Если да, то очень большое спасибо. Я хотел такое в BH сделать, но прямо и без артефактов не получалось.


RE: Исследование героев - igrik - 10.09.2015 18:41

да, ты сам можешь динамически изменять координаты, НО перед вызовом диалога. Как обновлять/перерисовывать диалог на лету я так и не разобрался
(17.07.2015 16:11)gamecreator Wrote:  Ну и не забыть перерисовать диалог:
hdlg->0x7299FD(-1
!!SN:E7510525/1/-1; вызывает у меня вылет, тут видимо я не так что-то понял

upd: Algor, если будут вопросы или нужна помощь по этой функции, обращайся. Например можно ее дописать, чтобы прилеплять диалог к правому/ левому/нижнему/верхнему бокам экрана


RE: Исследование героев - Bes - 10.09.2015 19:30

igrik, может тут есть что-то для обновления?



RE: Исследование героев - igrik - 10.09.2015 19:40

жаль, но нет


RE: Исследование героев - Bes - 10.09.2015 19:47

igrik, а обновлять такой смещённый диалог через DL:S уже не помогает?
ведь это и есть обновление, если грубо Unsure


RE: Исследование героев - igrik - 10.09.2015 22:24

Нет, DL:S тоже не помогает

ппц, не прошло и года с того момента, как мне нужна была эта функция



RE: Исследование героев - gamecreator - 11.09.2015 01:08

(10.09.2015 18:41)igrik Wrote:  Как обновлять/перерисовывать диалог на лету я так и не разобрался
(17.07.2015 16:11)gamecreator Wrote:  Ну и не забыть перерисовать диалог:
hdlg->0x7299FD(-1
!!SN:E7510525/1/-1; вызывает у меня вылет, тут видимо я не так что-то понял
-> - это же thiscall, а слева от стрелки - this.


RE: Исследование героев - igrik - 11.09.2015 09:38

хех, клевое обозначение...
Но всё равно не работает. Скорее всего адрес не тот, либо нужны доп. параметры


RE: Исследование героев - gamecreator - 11.09.2015 11:53

А можно пример кода и диалога? Потому что вникать что такое DL, если честно, сейчас не хочется.


RE: Исследование героев - igrik - 11.09.2015 12:22

Запаковано в виде мода. Скачать
Это диалоговое окно выбора режима битвы. Нападешь на монстра - появится это окно. На нажатие клавиши "7" происходит отрисовка диалога в других координатах. Клавиша "5" просто информация.


RE: Исследование героев - gamecreator - 11.09.2015 15:11

А где вариант с thiscall, который не работает?


RE: Исследование героев - igrik - 11.09.2015 15:17

там же. строка 054. Записана так:

upd, и да, я пробовал и так !!SN:E7510525/2/-1; результат тот же = вылет
а еще:



RE: Исследование героев - gamecreator - 11.09.2015 15:24

Ну это я увидел. А где вариант с thiscall? Напоминаю:
Quote: E #1 / #2 / ... up to 62 parameters; Execute external function
#1 = function address
#2 = calling conversion

0 - Pascal (use for all Angel.dll functions)
1 - Cdecl or Stdcall (use for WinAPI and the majority of other functions)
2 - ThisCall (use it only if you know, what you are doing)
3 - FastCall (the same as above, try to avoid)
Первый аргумент - this (третий аргумент команды соответственно).
Что конкретно неясно?

К слову, исправил на thiscall и всё заработало. Только старое изображение диалога осталось, наверное надо экран перерисовать сперва.


RE: Исследование героев - igrik - 11.09.2015 15:31

я исправил на thiscall, и у меня не работало, ни тогда, ни сейчас.
Почему я и обратился к тебе за помощью. У меня вылетает, и перепробовал я все что только мог, в том числе и thiscall


RE: Исследование героев - gamecreator - 11.09.2015 15:36

(11.09.2015 15:17)igrik Wrote:  upd, и да, я пробовал и так !!SN:E7510525/2/-1; результат тот же = вылет
а еще:
Теперь понятно. Поясняю: thiscall - это вызов метода объекта (если ты знаком с ООП). Функции такого типа принимают дополнительный параметр this, указатель на сам объект. Синтаксис вызова thiscall:
Смотрим в описание функции:
(17.07.2015 16:11)gamecreator Wrote:  hdlg->0x7299FD(-1)
Функция имеет один параметр, но в дополнение является методом объекта диалога. Значит нужно передать ей адрес этого объекта. Смотрим снова в описание, как же получить сам диалог, тоесть объект:
(17.07.2015 16:11)gamecreator Wrote:  Получить адрес диалога можно по номеру диалога:
hdlg = cdecl 0х729AD3(int32 id)
Или получить последний (текущий?) отображаемый диалог:
hdlg = [0x887650]

Понятно?


RE: Исследование героев - igrik - 11.09.2015 15:39

йок-макарёк. Теперь понятно. Спасибо!!!

Quote:Теперь понятно. Поясняю: thiscall - это вызов метода объекта (если ты знаком с ООП). Функции такого типа принимают дополнительный параметр this, указатель на сам объект. Синтаксис вызова thiscall:
!!SN:Eфункция/2/this/параметры;
не знал. Получилось. Естественно осталось старое изображение диалога. Буду искать способы решения.


RE: Исследование героев - Bes - 11.09.2015 16:16

(11.09.2015 15:39)igrik Wrote:  йок-макарёк.
ёк же?! не?



RE: Исследование героев - igrik - 11.09.2015 16:25

да)))) :D



RE: Исследование героев - igrik - 23.10.2015 18:57

gamecreator | feanor, подскажите плиз:
что такое "mip = int a4" и как его получить. Вообще въехать не могу блин!
Code:
0х00408ABF Enter2ObjectGamer(v2, a5, mip);
0х00408ABF car__thiscall Enter2ObjectGamer(int AdvManager, signed int a3, int a4)

и аналогичный вопрос по "__int64 PosMixed"
Code:
0x004A8160 void __thiscall Enter2ObjectMain(int AvdManager, _Hero_ *Hero, signed int Par1, __int64 PosMixed)



RE: Исследование героев - gamecreator - 23.10.2015 19:34

А, это. Это координаты.
Code:
inline int PackCoords(int x, int y, int l)
{
    return (x & 0x3FF) + ((y & 0x3FF) << 16) + ((l & 0xF) << 26);
}

inline void UnpackCoords(int coords, int& x, int& y, int& l)
{
    x = coords & 0x3FF;
    y = (coords >> 16) & 0x3FF;
    l = (coords >> 26) & 0xF;
}

Почему они у тебя внезапно int64 - не знаю.


RE: Исследование героев - feanor - 23.10.2015 19:37

Щас посмотрю.
Есть mip, который указатель на тайл клетки, а есть пакованные координаты.

//здесь - да, пакованные координаты


RE: Исследование героев - igrik - 23.10.2015 23:51

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


RE: Исследование героев - gamecreator - 24.10.2015 00:32

Разве ты с флагами существ не работал?
Вообще у Миханика хорошо рассказано, в предисловии к справке по значениям OB:C. Недавно мелькала тут ссылка на дф2.


RE: Исследование героев - igrik - 24.10.2015 00:56

работал, но я всё равно не вижу связи. Ты хочешь сказать, что это вроде проверки &16 или |16?


RE: Исследование героев - gamecreator - 24.10.2015 01:55

Да. Вот смотри, есть у тебя int:
Code:
□□□□ □□□□ □□□□ □□□□ □□□□ □□□□ □□□□ □□□□
Всего 32 двоичных цифры (то есть 32 бита).
Число твоё - это сумма: (x & 0x3FF) + ((y & 0x3FF) << 16) + ((l & 0xF) << 26).
0x3FF = 11 1111 1111 (10 бит)
0xF = 1111 (4 бита)
Это обычная маска, как в твоём &16.
Теперь смотришь на сдвиг. Значение сдвинуто влево на несколько бит, то есть все его цифры переместились на более старшие позиции. Если сдвинуто влево на 1 бит, то 0-й бит будет пустым, а значение будет начинаться с 1-го бита. Если сдвинуто на 2, то 0-й и 1-й биты пустые, значение начинается со 2-го и т.д.
Значит x начинается с 0-го бита, y - с 16-го, l - с 26-го:
Code:
- □□□□ □□□□ □□□□ □□□□ □□□□ □□□□ □□□□ □□□□
x                            11 1111 1111
y        11 1111 1111
l   11 11
Как видишь, они не пересекаются. Каждое значение на своём месте:
Code:
□□ll llyy yyyy yyyy □□□□ □□xx xxxx xxxx



RE: Исследование героев - igrik - 24.10.2015 02:21

я въехал!!! Огромное, огромное мерси! И теперь знаю как это применить...
Ведь int = 4 байта = 32 бита жеж. Вуаля))


RE: Исследование героев - igrik - 09.11.2015 19:09

Окно найма существ/боевых машин героем
Отписываюсь и там и там, ибо df2 имеет свойство не работать



RE: Исследование героев - igrik - 12.11.2015 03:53

Дополним триггер !?CM
Code:
!?CM0 - вызывается при клике ПКМ на карте приключений
!?CM1 - вызывается при клике в окне замка
!?CM2 - вызывается при клике в окне героя
!?CM3 - вызывается при клике в окне обмена между героями
!?CM4 - вызывается при клике на поле боя
!?CM5 !?CM9 - вызываются при клике ЛКМ на карте приключений
!?CM6 - вызывается при одевании артефакта
!?CM7 - при движение мышью в бою
!?CM8 - при движении мышью в городе
!?CM11 - после покупки здания (видимо при обновлении/прорисовке окна города и карты приключений, окна боя), посещение любого объекта на карте,
!?CM12 - при открытии книги заклинаний на карте приключений через кнопку
!?CM13 - при закрытии книги заклинаний на карте приключений через кнопку
!?CM14 - вход в окно покупки зданий в городе
!?CM15 - выход из окна покупки в городе
!?CM30 - открытие окна командира
!?CM31 - закрытие окна командира
триггеры CM10, 16...21 пока не нашёл


RE: Исследование героев - feanor - 12.11.2015 04:29

о_О
шо, правда?


RE: Исследование героев - feanor - 12.11.2015 04:36

А, отставить офигевать.

Сравни с списком (erm.cpp)
Quote:// 30310 mouse click на карте (правый) !?CM0
// 30311 mouse click в Городе !?CM1
// 30312 mouse click in hero screen !?CM2
// 30313 mouse click it two heroes screen !?CM3
// 30314 mouse click in battlefield !?CM4
// 30315 игрок снял артифакт
// 30316 игрок одел артифакт
// 30317 mouse move over battlefield
// 30318 mouse move over townscreen
// 30319 mouse click на карте (левый) !?CM5
// 30320 MP3 music
// 30321 WAV and M82 Sound 3.58
// 30322 Magic cast (adv. map) (pre-trigger)
// 30323 Magic cast (adv. map) (post-trigger)
// 30324 Go to Town Hall Screen 3.58 !?TH0
// 30325 Leave Town Hall Screen 3.58 !?TH1
// 30330 MP before sending data before battle
// 30331 MP after receiving data before battle
// 30332 MP before sending data after battle
// 30333 MP after receiving data after battle
// 30334 MP received data during a battle
// 30340 CO Перед открытием диалога Командира
// 30341 CO После закрытия диалога Командира
// 30342 CO После покупки Командира в городе
// 30343 CO После воскрешения Командира в городе



RE: Исследование героев - igrik - 12.11.2015 23:48

млинн, точно!


RE: Исследование героев - igrik - 04.12.2015 17:34

Что то не могу найти в exe: по какому адресу лежит "avwphx.def".
Да и вообще с подменой дефа феникса жуткие траблы. Не меняются дефы, хоть убей. Приходится изменять название через патч экзешника. С основным дефом и озвучкой разобрался. Но вот деф на карте не могу найти

или что такое?
_int_ advmap_low;
_int_ advmap_high;


RE: Исследование героев - feanor - 05.12.2015 00:18

Дефы на карте в объектных текстовиках.


RE: Ваши вопросы по ERM-скриптам - feanor - 25.12.2015 14:06

Генерация рандомных артов - это 004C9190

(25.12.2015 02:34)Algor Wrote:  Кто в курсе, как разрешить генерацию WoG-артефактов, например, артефактов командира, на карте (на месте случайных артефактов...)?
(25.12.2015 12:18)igrik Wrote:  Может можно через UN:C расширить кол-во артов. Мож там функция типа "_random[7,125]" и можно ее сделать "_random[7,255]"?

да, там надо в двух местах поправить константу (=144) на сколько надо.
Там есть нюанс - оно заодно обращается к двум таблицам (запрета артов и уже наличествующих артов), которые имеют фиксированный размер и, что хуже, лежат в очень динамической памяти


RE: Исследование героев - igrik - 06.02.2016 03:35

На DF2 зашел разговор о телекинезе, делать было нечего, поэтому начал накидывать, но потом что-то стало влом.
Короче, функция посещения героем любого объекта удалённо (даже самого себя):



RE: Исследование героев - igrik - 06.02.2016 03:48

А эта без указания номера героя.



RE: Исследование героев - Algor - 06.02.2016 13:01

igrik, триггер (и пост-триггер) посещения объекта таким образом срабатывают?


RE: Исследование героев - igrik - 16.02.2016 17:57

(06.02.2016 13:01)Algor Wrote:  igrik, триггер (и пост-триггер) посещения объекта таким образом срабатывают?
Да: и триггер и пост-триггер, и с HD тоже работает.


RE: Исследование героев - gamecreator - 17.04.2016 17:23

Может у кого и структура def в памяти случайно есть?


RE: Исследование героев - feanor - 17.04.2016 21:27

Из HD (кстати, по какой причине те сорцы были выпилены?)
Code:
NOALIGN struct _BinTreeItem_ : public _Struct_ // size = 28
{
    _ptr_*    v_table; // + 0
    _char_    name[12]; // + 4
    _dword_    name_end; // + 16
    _dword_    type; // + 20
    _int_    ref_count; // + 24

    void DerefOrDestruct() { CALL_1(void, __thiscall, this->v_table[1], this); }

};


NOALIGN struct _Def_ : public _BinTreeItem_
{
    _DefGroup_**    groups; // + 28
    _Palette16_*    palette16;
    _Palette24_*    palette24;
    _dword_            groups_count;
    _ptr_            active_groups;
    _dword_            width;
    _dword_            height;
};


NOALIGN struct _DefGroup_
{
    _dword_        frames_count;
    _dword_        frames_size;
    _DefFrame_** frames;

};



NOALIGN struct _DefFrame_ : public _BinTreeItem_
{
    _dword_        frm_size; // + 28
    _dword_        buf_size;
    _dword_        compression_type;
    _dword_        def_width;
    _dword_        def_height;
    _dword_        frame_width;
    _dword_        frame_height;
    _dword_        frame_left;
    _dword_        frame_top;
    _dword_        unknown_40;
    _ptr_        buffer;
};



RE: Исследование героев - gamecreator - 18.04.2016 13:59

Благодарю. Я и не знал, что сорцы HD выкладывались в открытый доступ.


RE: Исследование героев - igrik - 17.10.2016 11:35

Как же труден и неудобен ERM в таких вещах, просто жуть.
Image: JRI49eeCzz4.jpg



RE: Исследование героев - Berserker - 17.10.2016 14:52

Здоровская примочка! Жаль, что вылетает на третьем.
Соглашусь, ЕРМ неудобен для такого кода.


RE: Исследование героев - igrik - 21.03.2017 17:45

Накопал я довольно таки интересную вещь в сетевом режиме (LAN). Итак, при генерации карты в триггере !?PI, пользуясь функцией удаления объекта (при замене оных) мы получаем гарантированный вылет. Это происходит вследствие того, что в геройской функции удаления объектов есть функция "звукового сопровождения". Если ее занопить на момент генерации карты, то вылета игры не будет. А т.к. на этот момент передача сетевых данных еще не происходит, то мы получаем рабочий код замены объектов, не требующий использования таймеров и других плюх. Плюс при показе карты приключений как на стороне сервера, так и на стороне клиента мы уже имеем замененные объекты. Т.е. 1 часть рассинхрона мы вылечили (остается еще решить рассинхрон в битве. Тут у меня уже тоже есть кое-какие наблюдения и как это лечить).
Код выглядит так (на примере замены двусторонних монолитов на мельницы) (Click to View)
И ещё, я не использовал функцию UN:U [сосчитать все объекты на карте], потому что при передаче хода от клиента серверу происходит непонятный вылет, связанный с библиотекой "kernel32.dll" и не связанный с этим патчем.


RE: Исследование героев - Bes - 25.03.2017 17:25

хм, очень интересно.
Т.е. по сути можно уже щас взять оф.скрипты из WoG и "вылечить" их, обозвав это тестингом на стабильность и выложить для массового тестинга людям?

P.S.
(21.03.2017 17:45)igrik Wrote:  И ещё, я не использовал функцию UN:U [сосчитать все объекты на карте], потому что при передаче хода от клиента серверу происходит непонятный вылет, связанный с библиотекой "kernel32.dll" и не связанный с этим патчем.
а ты не проверял этот момент на разных ОС (Xp, win7+)
вдруг там будут разные "грабли"?


RE: Исследование героев - igrik - 26.03.2017 14:03

(25.03.2017 17:25)Bes Wrote:  хм, очень интересно.
Т.е. по сути можно уже щас взять оф.скрипты из WoG и "вылечить" их, обозвав это тестингом на стабильность и выложить для массового тестинга людям?
а ты не проверял этот момент на разных ОС (Xp, win7+)
вдруг там будут разные "грабли"?
Проверял на XP и на Win7_x64.
Да, можно. И я бы даже сказал - что нужно. Но у меня совершенно нет желания перелопачивать тонну оф.скриптов. Вообще.


RE: Исследование героев - Bes - 26.03.2017 16:51

igrik, могу потихоньку начать... по порядку.
я правильно понял, что эту махинацию надо делать каждый раз при замене объкта на карте в скрипте (или удалении)?

буду не спеша, чтобы лишних багов не натворить по невнимательности.
в отдельной теме выкладывать До и ПОСЛЕ файл с описанием что заменял.
дабы была и сторонняя модерация подмены кода.


RE: Исследование героев - igrik - 27.03.2017 13:03

(26.03.2017 16:51)Bes Wrote:  igrik, могу потихоньку начать... по порядку.
я правильно понял, что эту махинацию надо делать каждый раз при замене объкта на карте в скрипте (или удалении)?
Не совсем. Этот код расчитан только на момент действия триггера !?PI. Вся суть заключается в том, что (для LAN):
1. Хост нажимает кнопку "Начать"
2. Происходит генерация (для случайных) а потом загрузка карты.
2а. Тут вызывается триггер !?PI и в данном случае наша подмена объектов
3. Происходит передача сетевых данных клиенту, в том числе и карты (в нашем случае уже с измененными объектами).
В итоге: у обоих игроков при первом показе карты приключений все объекты идентичны.
Данный скрипт актуален для всех скриптов, которые заменяют объекты только в первый день. Например: замены картографов, улиев, и весь комплекс опций от "Замена объектов во время WoG'ификации.
На счет замены в другие игровые дни не скажу. Да и сейчас для этого нет достаточного запаса времени.
(26.03.2017 16:51)Bes Wrote:  буду не спеша, чтобы лишних багов не натворить по невнимательности.
в отдельной теме выкладывать До и ПОСЛЕ файл с описанием что заменял.
дабы была и сторонняя модерация подмены кода.
Было бы конечно отлично, но спрошу ещё раз: стоит ли игра свечь?


RE: Исследование героев - Bes - 27.03.2017 13:16

igrik, я на больничный пошёл... могу сидеть смотреть сериалы, порно кино, или же таки открыть скрипты и прогнать всю эту тему по мере возможного.
вроде бы замена wog'ификацией идёт в теле таймера... не?


RE: Исследование героев - gamecreator - 27.03.2017 14:57

(27.03.2017 13:16)Bes Wrote:  вроде бы замена wog'ификацией идёт в теле таймера... не?
Так о том и речь. Если замена в начале игры, то перенести её в !?PI.


RE: Исследование героев - igrik - 27.03.2017 16:33

(27.03.2017 13:16)Bes Wrote:  вроде бы замена wog'ификацией идёт в теле таймера... не?
В том и дело, что все те замены которые идут в теле таймера (только для первого дня) следует перенести в тело !?PI;
И раньше мы получали гарантированный вылет, сейчас - нет.


RE: Исследование героев - hippocamus - 03.04.2017 05:46

Вот всегда инстересовал вопрос - почему многие ресиверы нормально обрабатываются в ?!PI, но не работают в качестве инструкций #! ?
Что вообще допустимо в инструкциях?

(да, у вас переставлены местами символы ? и !. старого ермиста не проведёшь!)


RE: Исследование героев - igrik - 03.04.2017 11:35

(03.04.2017 05:46)hippocamus Wrote:  Вот всегда инстересовал вопрос - почему многие ресиверы нормально обрабатываются в ?!PI, но не работают в качестве инструкций #! ?
Что вообще допустимо в инструкциях?
Немного странный вопрос если честно. Это же разные участки кода, куда поставлены хуки триггеров и инструкции.
(03.04.2017 05:46)hippocamus Wrote:  (да, у вас переставлены местами символы ? и !. старого ермиста не проведёшь!)
Зачем его пытаться провести, когда он сам это делает с успехом. Либо кто-то уже совсем старый в этом деле, и кое-что успел подзабыть. 96-copy


RE: Исследование героев - RoseKavalier - 12.08.2017 05:18

Hello
Привет!

Sorry for English! I will try to translate with Yandex...
Извините за английский! Я попытаюсь перевести с Яндекс...

Is it possible to link these includes that were previously available here ?
Можно ли связать эти включает в себя, которые ранее были доступны здесь ?

Would be very nice for making plugins)
Было бы очень хорошо для создание плагинов)

Code:
#include "targetver.h"

#include <windows.h>
#include <stdlib.h>
#include <stdio.h>

#include "..\..\include\patcher_x86_commented.hpp"
#include "..\..\include\HotA\HoMM3.h"
#include "..\..\include\era.h"



RE: Исследование героев - feanor - 17.08.2017 09:59

Dropbox changed link formats :[

https://www.dropbox.com/s/o7wkof3hgpz8jh6/include.zip?dl=0
https://www.dropbox.com/s/tujvdltnduw260g/sample.zip?dl=0


RE: Исследование героев - RoseKavalier - 18.08.2017 00:20

Thank you)
Спасибо)

By any chance, you wouldn't happen to have an example of creating a custom dialog? I understand how to use 0x4F6C00 but I can't figure how to make one from scratch ..
Вы случайно не пример создания пользовательского диалогового окна? Я понимаю, как использовать 0x4F6C00, но я не могу понять, как сделать один с нуля 105


RE: Исследование героев - feanor - 18.08.2017 01:57

No, I haven't.
If I'll need it someday, probably I will use !!DL and ExecErm.


RE: Исследование героев - igrik - 18.08.2017 15:39

(18.08.2017 00:20)RoseKavalier Wrote:  By any chance, you wouldn't happen to have an example of creating a custom dialog? I understand how to use 0x4F6C00 but I can't figure how to make one from scratch ..
Уфф!!! И у меня наконец-то что-то начало получаться:
Code:
void AdvMgr_ShowTestDlg(int x, int y)
{
    int cx = 256;    // ширина (width)
    int cy = 106;    // высота (height)
    int zx = 22;    // отступ по x
    int zy = 55;    // отступ по y

    _Dlg_* dlg = _CustomDlg_::Create(-1, -1, cx, cy, DF_SCREENSHOT | DF_SHADOW, NULL);                                // создали диалог
    dlg->AddItemByZOrder(_DlgStdBackground_::Create(0,0,dlg->width,dlg->height, 0, 0, o_GameMgr->GetMeID()), 0);    // рамка в цвете игрока
    // dlg->AddItem(_DlgBlueBackground_::Create(0,0, dlg->width, dlg->height, o_GameMgr->GetMeID()));                // синяя рамка как в HD
    dlg->AddItem(_DlgStaticText_::Create(0, 20, dlg->width, 42, "Вы действительно хотите выйти?", "medfont.fnt", 1, 0, ALIGN_H_CENTER | ALIGN_V_TOP, 0)); // заголовок
        
    // делаем кнопку ок
    dlg->AddItem(_DlgStaticPcx8_::Create(zx, dlg->height -zy, 0, "Box64x30.pcx"));
    dlg->AddItem(_DlgButton_::Create(zx +1, dlg->height -zy +1, 64, 30, 30722, "iOkay.def", 0, 1, 0, 28, 2));
    // dlg->GetItem(30722)->SetEnabled(0); отключенная кнопка ok

    // делаем кнопку отмена
    dlg->AddItem(_DlgStaticPcx8_::Create(dlg->width - zx -64, dlg->height -zy, 0, "Box64x30.pcx"));
    dlg->AddItem(_DlgButton_::Create(dlg->width - zx -64 +1, dlg->height -zy +1, 64, 30, 30721, "iCancel.def", 0, 1, 0, 1, 2));

    dlg->Run();
    dlg->Destroy(TRUE);
}



RE: Исследование героев - RoseKavalier - 18.08.2017 17:24

@feanor
Sadly, cannot use ERM for what I want (SoD).

@igrik
Very nice!
I will try it and see if I can get some more things figured out and share back results)


RE: Исследование героев - RoseKavalier - 02.09.2017 08:13

I've not managed to discover much except about this:
   
Right-click window message on item
Code:
_DlgItem_* it;
it = dlg->GetItem(7);
it->full_tip_text = "This is right-click popup message.";

Dialog only open during right-click
Code:
//dlg->Run(); // don't use this
//dlg->Destroy(TRUE); // don't use this
dlg->RMC_Show();

Some work done... not sure if I should make it available to public even with multiplayer checks. I don't mind sharing code, just don't want it to fall in wrong hands, opinions? 105


Some things I'm interested in (if anyone knows) :
  1. assign a variable/function to a clicked item (not only button, also defs - see 4/5)
  2. read text in the edit dialog
  3. make edit dialog numbers/text only
  4. make the highlighted cadre when clicking an item (like level-up skills)
  5. changing defs (like HWrulez button)

I think some of these may be connected to each other but I could not figure it out so far.

4:
Image: y37dzBk.png
5:
Image: U8Ge7fJ.png

Any help greatly appreciated)


RE: Исследование героев - Valery - 02.09.2017 14:18

Can't add a check if game is MP or single, as cheat codes? Then I see no problem with releasing the code, btw great job132


RE: Исследование героев - igrik - 02.09.2017 14:28

Code:
1. int __stdcall Y_HeroLvlUp_3x_Proc(HiHook* hook, _Struct_* dlg, _EventMsg_* msg)
{
    if (msg->type == MT_MOUSEBUTTON)
    {
        if (msg->subtype == MST_LBUTTONCLICK)
        {
            if (msg->item_id == 7012)
            {    
                dlg->GetItem(2012)->SendCommand(6, 4); dlg->GetItem(2012)->Draw();
                dlg->GetItem(2013)->SendCommand(6, 4); dlg->GetItem(2013)->Draw();
                dlg->GetItem(7013)->SendCommand(5, 4); dlg->GetItem(7013)->Draw();
                dlg->GetItem(30722)->SetEnabled(1);
                dlg->Redraw(TRUE);                
            }
    return CALL_2(int, __thiscall, hook->GetDefaultFunc(), dlg, msg);
}

2, 3.     sprintf(o_TextBuffer, "%s либо %s %s.", ((_DlgStaticText_*)dlg->GetItem(2005))->text, *(int*)((*(int*)((*(int*)0x6A7F68) +32)) + 4*hero->second_skill[SSkill]), *(int*)(*(int*)0x67DCF0 + SSkill*16) );
    ((_DlgStaticText_*)dlg->GetItem(2005))->SetText(o_TextBuffer);

4.     dlg->AddItem(CALL_8 (_DlgItem_*, __thiscall, 0x44FE00, o_New(56), 257, 325, 46, 46, 7013, *(int*)(*(int*)0x6AAD18 + 118), 1024));
    dlg->GetItem(7013)->SendCommand(5, 4);

5. ((_DlgStaticDef_*)dlg->GetItem(7012))->def_frame_index = your_number;

Image: YK78FzIHOww.jpg


RE: Исследование героев - RoseKavalier - 02.09.2017 19:17

(02.09.2017 14:18)Valery Wrote:  Can't add a check if game is MP or single, as cheat codes? Then I see no problem with releasing the code, btw great job132
Merci, I think the inspiration should look familiar to you!
Of course, almost all my code has no-multiplayer check, but anyone with a little knowledge and bad intentions could circumvent it - hence my hesitation.

(02.09.2017 14:28)igrik Wrote:  

Fantastic, it seems you've figured most of it already) :D 132

Another question: how about "mouse-over text"?
Code:
dlg->AddItemByZOrder(_DlgStdBackground_::Create(x, y, w, h, id, bottom_bar=TRUE, player_id), 0);
[...]
dlg->GetItem(some_id)->short_tip_text = "Text to show in bottom bar."

//guess you need text in bottom bar
dlg->AddItem(_DlgStaticText_::Create(x, y, w, h, ?messageText?, font, color, id, ALIGN_H_CENTER | ALIGN_V_TOP, bkcolor));

Image: mG2HQae.png


RE: Исследование героев - Valery - 02.09.2017 20:20

(02.09.2017 19:17)RoseKavalier Wrote:     but anyone with a little knowledge and bad intentions could circumvent it - hence my hesitation.

If a player is motivated enough to change your code in order to cheat, it already means he can already cheat by using other obvious tools, as playing the autosaves on another device and find how split works anyway.


RE: Исследование героев - igrik - 03.09.2017 01:15

(02.09.2017 19:17)RoseKavalier Wrote:  Another question: how about "mouse-over text"?
Смотри тут. Это недописанное окно командира.
Code:
_DlgStaticDef_* CommDef;
_DlgStaticTextPcx8ed_* statbar = NULL;

// показ сообщения по ПКМ на первичных навыках командира
void Y_New_CommanderDlg_ShowPreSkill_RMC(int npc_id, int skill)
{
    int skill_power = *(int*)(0x28620C0 + 296 * npc_id + 56 + skill*4); // получить силу скила
    char* text = "";
    int sizeX, sizeY;

    bool art_npc_155 = false;    
    for (char i = 0; i < 6; ++i ){
        if (o_Npc[npc_id].arts[i][0] == 155 )
            art_npc_155 = true;    
    }
    if ( !art_npc_155 || skill_power > 1 )
    {
        text = Get_ITxt(skill_power + 136 + skill *6, 1);        // получить строку в текстовике в зависимости от силы скила
        sizeX = 560; sizeY = 440;
    }
    else
    {
        text = Get_ITxt(skill + 236, 1);
        sizeX = 340; sizeY = 220;
    }

    _Dlg_* dlg = _CustomDlg_::Create(-1, -1, sizeX, sizeY, DF_SCREENSHOT | DF_SHADOW, NULL);                            
    dlg->AddItemByZOrder(_DlgStdBackground_::Create(0, 0, dlg->width, dlg->height, 0, 0, o_GameMgr->GetMeID()), 0);
    
    dlg->AddItem(_DlgStaticDef_::Create(dlg->width/2 -35, 25, 70, 70, 2, "ComSkls2.def", skill_power + skill*7 + 6*art_npc_155, 0, 0x12));          
    dlg->AddItem(_DlgStaticText_::Create(25, 95, dlg->width -50, dlg->height -25 -95, text, "medfont.fnt", 1, 3, ALIGN_H_CENTER | ALIGN_V_TOP, 0));

    dlg->RMC_Show();
}

int __stdcall Y_New_CommanderDlg_Proc(_Dlg_* dlg_Npc, _EventMsg_* msg)
{
    int r = dlg_Npc->DefProc(msg);

    int npc_id = dlg_Npc->field_64; // получаем номер командира/героя
    _Npc_* npc = GetNpc(npc_id); // получаем структуру командира
    _Hero_* hero = o_GameMgr->GetHero(npc_id); // структура героя
    int temp_1, temp_2; // временная переменная

    // обновление подсказки при движении мыши (id = 10)
    if (msg->type == MT_MOUSEOVER)
        {
            _DlgItem_* it = dlg_Npc->FindItem(msg->x_abs, msg->y_abs);
            char* text = "";
            if (it)    
            {
                switch (it->id)
                {
                    case 3:     text = Get_ITxt(263, 1); break; // подсказка Уволить командира
                    case 4:     text = Get_ITxt(273, 1); break; // подсказка для просмотра биографии
                    case 6:  text = Get_ITxt(npc->type + 10, 1); break; // подсказка первого спец_умения
                    case 7:  text = Get_ITxt(npc->type + 10, 2); break; // подсказка второго спец_умения
                    case 11: text = Get_ITxt(259, 1); break; // подсказка Имя командира

                    case 12: text = Get_ITxt(npc->lvl_attack + 100, 1);      break; // подсказка дефа навыка атаки
                    case 13: text = Get_ITxt(npc->lvl_defence + 106, 1);     break; // подсказка дефа навыка защиты
                    case 14: text = Get_ITxt(npc->lvl_hit_points + 112, 1);  break; // подсказка дефа навыка здоровья
                    case 15: text = Get_ITxt(npc->lvl_damage + 118, 1);       break; // подсказка дефа навыка урона
                    case 16: text = Get_ITxt(npc->lvl_spell_power + 124, 1); break; // подсказка дефа навыка силы магии
                    case 17: text = Get_ITxt(npc->lvl_speed + 130, 1);       break; // подсказка дефа навыка скорости

                    case 31: case 61: sprintf(o_TextBuffer, "%s%d", Get_ITxt(264, 1), npc->now_level +1); text = o_TextBuffer; break;// подсказка уровня командира
                    case 32: case 33: text = Get_ITxt(242, 1);       break; // подсказка класса командира
                    case 34: case 35: sprintf(o_TextBuffer, "%s%s", Get_ITxt(266, 1), hero->name); text = o_TextBuffer; break;// подсказка хозяина героя
                    case 36: case 37: sprintf(o_TextBuffer, "%s%d", Get_ITxt(267, 1), npc->now_expa); text = o_TextBuffer; break;// подсказка текущего опыта
                    case 38: case 39: sprintf(o_TextBuffer, "%s%d", Get_ITxt(268, 1), CALL_1(int, __thiscall, 0x769260, npc)); text = o_TextBuffer; break;// подсказка следующего опыта

                    case 40: text = Get_ITxt(269, 1); break; // подсказка навыки класса
                    case 41: text = Get_ITxt(270, 1); break; // подсказка артефакты
                    case 42: text = Get_ITxt(271, 1); break; // подсказка основные навыки
                    case 43: text = Get_ITxt(272, 1); break; // подсказка вторичные навыки

                    case 45: temp_1 = Get_NpcSkillPower(npc, 0); temp_2 = hero->attack;
                             if ( npc->type == 7 ) temp_2 += (temp_2/2);
                             sprintf(o_TextBuffer, Get_ITxt(275, 2), temp_1 + temp_2); text = o_TextBuffer; break;                                            // подсказка атака
                    case 46: temp_1 = Get_NpcSkillPower(npc, 1); temp_2 = hero->defence;
                             if ( npc->type == 7 ) temp_2 += (temp_2/2);
                             sprintf(o_TextBuffer, Get_ITxt(276, 2), temp_1 + temp_2); text = o_TextBuffer; break;                                            // подсказка защита

                    case 47: sprintf(o_TextBuffer, Get_ITxt(277, 2), Get_NpcSkillPower(npc, 2)); text = o_TextBuffer; break;                                // подсказка здоровье
                    case 48: sprintf(o_TextBuffer, Get_ITxt(278, 2), Get_NpcSkillPower(npc, 3)/2, Get_NpcSkillPower(npc, 3)); text = o_TextBuffer; break;    // подсказка сила урон
                    case 49: sprintf(o_TextBuffer, Get_ITxt(279, 2), Get_NpcSkillPower(npc, 4)); text = o_TextBuffer; break;                                // подсказка сила магии
                    case 50: sprintf(o_TextBuffer, Get_ITxt(280, 2), Get_NpcSkillPower(npc, 6)); text = o_TextBuffer; break;                                // подсказка сопротивление
                    case 51: sprintf(o_TextBuffer, Get_ITxt(281, 2), ((npc->specBon[0] & 0x10) ? 24 : 0)); text = o_TextBuffer; break;                        // подсказка боезапас
                    case 52: sprintf(o_TextBuffer, Get_ITxt(282, 2), Get_NpcSkillPower(npc, 5)); text = o_TextBuffer; break;                                // подсказка скорость

                    case 30722:    text = Get_ITxt(261, 1); break; // Ok Выход
                    default: text = "";    break;
                }
            statbar->SetText(text);
            statbar->Draw();
            statbar->RedrawScreen();
            }
        }


    if (msg->type == MT_MOUSEBUTTON)
            {
                if (msg->subtype == MST_RBUTTONDOWN) // клик ПКМ
                {
                    switch (msg->item_id)
                    {
                        case 3: b_MsgBox(Get_ITxt(201, 1), MBX_RMC);            break;  // Уволить командира
                        case 4: case 11: b_MsgBox(Get_ITxtBio(npc_id, 1), MBX_RMC);            break;  // ПКМ для просмотра биографи
                        case 6: b_MsgBox(Get_ITxt(npc->type + 19, 1), MBX_RMC);        break;  // ПКМ первого спец_умения
                        case 7: b_MsgBox(Get_ITxt(npc->type + 19, 2), MBX_RMC);        break;  // ПКМ второго спец_умения

                        case 12: Y_New_CommanderDlg_ShowPreSkill_RMC(npc_id, 0);     break; // ПКМ дефа навыка атаки
                        case 13: Y_New_CommanderDlg_ShowPreSkill_RMC(npc_id, 1);     break; // ПКМ дефа навыка защиты
                        case 14: Y_New_CommanderDlg_ShowPreSkill_RMC(npc_id, 2);     break; // ПКМ дефа навыка здоровья
                        case 15: Y_New_CommanderDlg_ShowPreSkill_RMC(npc_id, 3);     break; // ПКМ дефа навыка урона
                        case 16: Y_New_CommanderDlg_ShowPreSkill_RMC(npc_id, 4);     break; // ПКМ дефа навыка силы магии
                        case 17: Y_New_CommanderDlg_ShowPreSkill_RMC(npc_id, 5);     break; // ПКМ дефа навыка скорости

                        case 32: case 33: b_MsgBox(Get_ITxt(npc->type + 186, 1), MBX_RMC);        break;  // ПКМ на описании класса

                        case 30722: b_MsgBox(Get_ITxt(261, 2), MBX_RMC); break; // ПКМ Ok Выход
                    }
                }
            }
    return r;
}
// новое диалоговое окно командира для ERA (0x0076A46E)
int Y_New_CommanderDlg_Show(int NHero_id, bool lvl_up)
{
    _Npc_* npc = GetNpc(NHero_id); // получаем структуру командира
    _Hero_* hero = o_GameMgr->GetHero(NHero_id); // структура героя
    int sizeX, sizeY;
    char* name_pcx;
    
    if (!lvl_up)    {
        name_pcx = "DlgCom0.pcx";    
        sizeX = 634; sizeY = 505;
    }
    else {
        name_pcx = "DlgCom1.pcx";    
        sizeX = 634; sizeY = 600;    
    }

    _Dlg_* dlg = _CustomDlg_::Create(-1, -1, sizeX, sizeY, DF_SCREENSHOT | DF_SHADOW, Y_New_CommanderDlg_Proc);

    // деф командира
    dlg->field_64 = NHero_id; // сохраняем номер командира в структуре диалога для Dlg_Proc
    dlg->AddItem(_DlgStaticPcx8_::Create(20, 70, 100, 130, 4, "CRBKGNEU.pcx")); // фон замка под дефом командира нейтральный (id = 4)
    dlg->AddItem(CommDef = _DlgStaticDef_::Create(-130, -80, 100, 130, 5, o_CreatureInfo[npc->type + 174].def_name, 0, 0, 0x12)); // шагающий деф командира (id = 5)

    // задник диалога под цвет игрока (id = 1)
    _DlgStaticPcx8_* fonPcx;
    dlg->AddItem(fonPcx = b_DlgStaticPcx8_Create(0, 0, dlg->width, dlg->height, 1, name_pcx, 2048));
    fonPcx->Colorize(o_GameMgr->GetMeID());

    // кнопки ок и уволить
    dlg->AddItem(_DlgButton_::Create(285, dlg->height -76, 64, 30, 30722, "iOkay.def", 0, 1, 1, 28, 2)); // кнопка ok (id = 30722)
    dlg->AddItem(_DlgButton_::Create(564, dlg->height -76, 51, 35, 3, "hsbtns2.def", 0, 1, 1, 28, 2));   // кнопка удалить командира (id = 3)
    CALL_3 (void, __thiscall, 0x50CEA0, o_MouseMgr, 0, 0);  // установить курсор(0,0)

    dlg->AddItem(_DlgStaticText_::Create(20, 70, 100, 130, "", "medfont.fnt", 1, 4, ALIGN_H_CENTER | ALIGN_V_CENTER, 0));  // подсказка на дефе (пустышка, но по ней ПКМ определяет id и выдает окно биографии)
    
    // дефы спец_умений командира
    dlg->AddItem(_DlgStaticDef_::Create(395, 113, 43, 43, 6, "ComSkls.def", npc->type *2, 0, 0x12));    // первый деф спец_умений (id = 6)
    dlg->AddItem(_DlgStaticDef_::Create(504, 113, 43, 43, 7, "ComSkls.def", npc->type *2 +1, 0, 0x12)); // первый деф спец_умений (id = 7)

    // подсказка в статус баре    
    statbar = _DlgStaticTextPcx8ed_::Create(8, dlg->height -18 -8, dlg->width - 16, 18, "Подсказка", "smalfont.fnt", "HD_TStat.pcx", 1, 10, ALIGN_H_CENTER | ALIGN_V_CENTER);
    dlg->AddItem(statbar);

    dlg->AddItem(_DlgStaticText_::Create(131, 18, 370, 17, npc->name, "medfont.fnt", 7, 11, ALIGN_H_CENTER | ALIGN_V_CENTER, 0)); // имя командира (id = 11)

    // артефакты (id 20...25)
    bool art_npc_155 = false;
    for (char i = 0; i < 6; ++i ){
        if (npc->arts[i][0] > 0 )
            dlg->AddItem(_DlgStaticDef_::Create(330 +48*i, 184, 45, 45, 20, "artifact.def", npc->arts[i][0], 0, 0x12));
        if (npc->arts[i][0] == 155 )
            art_npc_155 = true;            
    }

    // скилы (id 12...17)
    for (char i = 0; i < 6; ++i ){
        int art_freme_skill = *(int*)(0x28620C0 +296*NHero_id +56 +4*i);
        if (art_freme_skill < 2 && art_npc_155)
            art_freme_skill = 6;
        dlg->AddItem(_DlgStaticDef_::Create(40 +96*i, 270, 70, 70, 12+i, "ComSkls2.def", art_freme_skill +7*i, 0, 0x12));
    }

    dlg->AddItem(_DlgStaticText_::Create(22, 46, 96, 18, Get_ITxt(264, 1), "medfont.fnt", 7, 31, ALIGN_H_LEFT | ALIGN_V_CENTER, 0)); // уровень_текст (id = 31)
    sprintf(o_TextBuffer, "%d", npc->now_level +1);
    dlg->AddItem(_DlgStaticText_::Create(22, 46, 96, 18, o_TextBuffer, "medfont.fnt", 1, 61, ALIGN_H_RIGHT | ALIGN_V_CENTER, 0)); // уровень_число (id = 61)

    dlg->AddItem(_DlgStaticText_::Create(16, 205, 104, 18, Get_ITxt(265, 1), "medfont.fnt", 7, 32, ALIGN_H_CENTER | ALIGN_V_TOP, 0)); // класс_текст1 (id = 32)
    dlg->AddItem(_DlgStaticText_::Create(16, 220, 104, 18, Get_ITxt(npc->type +216, 1), "medfont.fnt", 1, 33, ALIGN_H_CENTER | ALIGN_V_TOP, 0)); // класс_текст2 (id = 33)

    dlg->AddItem(_DlgStaticText_::Create(128, 46, 192, 18, Get_ITxt(266, 1), "medfont.fnt", 7, 34, ALIGN_H_LEFT | ALIGN_V_CENTER, 0)); // Хозяин_текст (id = 34)
    dlg->AddItem(_DlgStaticText_::Create(128, 46, 192, 18, hero->name, "medfont.fnt", 1, 35, ALIGN_H_RIGHT | ALIGN_V_CENTER, 0)); // Хозяин_имя (id = 35)
    
    dlg->AddItem(_DlgStaticText_::Create(330, 46, 284, 18, Get_ITxt(267, 1), "medfont.fnt", 7, 36, ALIGN_H_LEFT | ALIGN_V_CENTER, 0)); // Текущий_опыт_текст (id = 36)
    sprintf(o_TextBuffer, "%d", o_Npc[NHero_id].now_expa);
    dlg->AddItem(_DlgStaticText_::Create(330, 46, 284, 18, o_TextBuffer, "medfont.fnt", 1, 37, ALIGN_H_RIGHT | ALIGN_V_CENTER, 0)); // Текущий_опыт_число (id = 37)    

    dlg->AddItem(_DlgStaticText_::Create(330, 68, 284, 18, Get_ITxt(268, 1), "medfont.fnt", 7, 38, ALIGN_H_LEFT | ALIGN_V_CENTER, 0)); // Следующий_уровень_текст (id = 38)

    sprintf(o_TextBuffer, "%d", CALL_1(int, __thiscall, 0x769260, npc));
    dlg->AddItem(_DlgStaticText_::Create(330, 68, 284, 18, o_TextBuffer, "medfont.fnt", 1, 39, ALIGN_H_RIGHT | ALIGN_V_CENTER, 0));   // Следующий_уровень_число (id = 39)    

    dlg->AddItem(_DlgStaticText_::Create(377, 91, 192, 18, Get_ITxt(269, 1), "medfont.fnt", 7, 40, ALIGN_H_CENTER | ALIGN_V_CENTER, 0)); // Навыки_класса_текст (id = 40)
    dlg->AddItem(_DlgStaticText_::Create(377, 160, 192, 18, Get_ITxt(270, 1), "medfont.fnt", 7, 41, ALIGN_H_CENTER | ALIGN_V_CENTER, 0)); // Артефакты_текст (id = 41)

    dlg->AddItem(_DlgStaticText_::Create(133, 247, 366, 18, Get_ITxt(271, 1), "medfont.fnt", 7, 42, ALIGN_H_CENTER | ALIGN_V_CENTER, 0)); // Основные_навыки_текст (id = 42)
    dlg->AddItem(_DlgStaticText_::Create(133, 344, 366, 18, Get_ITxt(272, 1), "medfont.fnt", 7, 43, ALIGN_H_CENTER | ALIGN_V_CENTER, 0)); // Вторичные_навыки_текст (id = 43)
    
    int temp_1, temp_2; // временные переменные

    temp_1 = Get_NpcSkillPower(npc, 0);     temp_2 = hero->attack;
    if ( npc->type == 7 ) temp_2 += (temp_2/2);
    sprintf(o_TextBuffer, "%d (%d)", temp_1, temp_1 + temp_2);
    dlg->AddItem(_DlgStaticText_::Create(128, 69, 192, 18, o_TextBuffer, "medfont.fnt", 1, 65, ALIGN_H_RIGHT | ALIGN_V_CENTER, 0));    // Атака_число (id = 65)
    dlg->AddItem(_DlgStaticText_::Create(128, 69, 192, 18, Get_ITxt(275, 1), "medfont.fnt", 7, 45, ALIGN_H_LEFT | ALIGN_V_CENTER, 0)); // Атака_текст (id = 45)

    temp_1 = Get_NpcSkillPower(npc, 1);     temp_2 = hero->defence;
    if ( npc->type == 7 ) temp_2 += (temp_2/2);
    sprintf(o_TextBuffer, "%d (%d)", temp_1, temp_1 + temp_2);
    dlg->AddItem(_DlgStaticText_::Create(128, 91, 192, 18, o_TextBuffer, "medfont.fnt", 1, 66, ALIGN_H_RIGHT | ALIGN_V_CENTER, 0));    // Защита_число (id = 66)
    dlg->AddItem(_DlgStaticText_::Create(128, 91, 192, 18, Get_ITxt(276, 1), "medfont.fnt", 7, 46, ALIGN_H_LEFT | ALIGN_V_CENTER, 0)); // Защита_текст (id = 46)

    sprintf(o_TextBuffer, "%d", Get_NpcSkillPower(npc, 2));
    dlg->AddItem(_DlgStaticText_::Create(128, 113, 192, 18, o_TextBuffer, "medfont.fnt", 1, 67, ALIGN_H_RIGHT | ALIGN_V_CENTER, 0));    // Здоровье_число (id = 67)
    dlg->AddItem(_DlgStaticText_::Create(128, 113, 192, 18, Get_ITxt(277, 1), "medfont.fnt", 7, 47, ALIGN_H_LEFT | ALIGN_V_CENTER, 0)); // Здоровье_текст (id = 47)

    temp_1 = Get_NpcSkillPower(npc, 3);
    sprintf(o_TextBuffer, "%d - %d", temp_1/2, temp_1);
    dlg->AddItem(_DlgStaticText_::Create(128, 135, 192, 18, o_TextBuffer, "medfont.fnt", 1, 68, ALIGN_H_RIGHT | ALIGN_V_CENTER, 0));    // Урон_число (id = 68)
    dlg->AddItem(_DlgStaticText_::Create(128, 135, 192, 18, Get_ITxt(278, 1), "medfont.fnt", 7, 48, ALIGN_H_LEFT | ALIGN_V_CENTER, 0)); // Урон_текст (id = 48)

    sprintf(o_TextBuffer, "%d", Get_NpcSkillPower(npc, 4));
    dlg->AddItem(_DlgStaticText_::Create(128, 157, 192, 18, o_TextBuffer, "medfont.fnt", 1, 69, ALIGN_H_RIGHT | ALIGN_V_CENTER, 0));    // Сила_магии_число (id = 69)
    dlg->AddItem(_DlgStaticText_::Create(128, 157, 192, 18, Get_ITxt(279, 1), "medfont.fnt", 7, 49, ALIGN_H_LEFT | ALIGN_V_CENTER, 0)); // Сила_магии_текст (id = 49)

    sprintf(o_TextBuffer, "%d%%", Get_NpcSkillPower(npc, 6));
    dlg->AddItem(_DlgStaticText_::Create(128, 179, 192, 18, o_TextBuffer, "medfont.fnt", 1, 70, ALIGN_H_RIGHT | ALIGN_V_CENTER, 0));    // Сопротивление_число (id = 70)
    dlg->AddItem(_DlgStaticText_::Create(128, 179, 192, 18, Get_ITxt(280, 1), "medfont.fnt", 7, 50, ALIGN_H_LEFT | ALIGN_V_CENTER, 0)); // Сопротивление_текст (id = 70)

    sprintf(o_TextBuffer, "%d", (npc->specBon[0] & 0x10 ? 24 : 0));
    dlg->AddItem(_DlgStaticText_::Create(128, 201, 192, 18, o_TextBuffer, "medfont.fnt", 1, 71, ALIGN_H_RIGHT | ALIGN_V_CENTER, 0));    // Боезапас_число (id = 71)
    dlg->AddItem(_DlgStaticText_::Create(129, 201, 192, 18, Get_ITxt(281, 1), "medfont.fnt", 7, 51, ALIGN_H_LEFT | ALIGN_V_CENTER, 0)); // Боезапас_текст (id = 51)

    sprintf(o_TextBuffer, "%d", Get_NpcSkillPower(npc, 5));
    dlg->AddItem(_DlgStaticText_::Create(128, 223, 192, 18, o_TextBuffer, "medfont.fnt", 1, 72, ALIGN_H_RIGHT | ALIGN_V_CENTER, 0));    // Скорость_число (id = 72)
    dlg->AddItem(_DlgStaticText_::Create(128, 223, 192, 18, Get_ITxt(282, 1), "medfont.fnt", 7, 52, ALIGN_H_LEFT | ALIGN_V_CENTER, 0)); // Скорость_текст (id = 52)

    dlg->Run();
    dlg->Destroy(TRUE);

    return 1;
}

Структура командира:
Code:
#define o_Npc ((_Npc_*)0x28620C0)         // получение структуры командира

struct _Npc_;

// Структура командира 0x128h (296)
NOALIGN struct _Npc_
{
_dword_ on;               // 0x00     +0    Доступность
_dword_ alive;            // 0x04     +4    Жив_или_мёртв  
_dword_ id;               // 0x08     +8    Номер_героя_хозяина (ну и номер командира)
_dword_ type;             // 0x0C     +12   Тип_командира
_dword_ type_Hero;        // 0x10     +16   Тип_героя
_dword_ LastExpaInBattle; // 0x14     +20   Опыт в прошлых битвах
_dword_ CustomPrimary;    // 0x18     +24   Если вы установить 1 (вкл), первичные навыки не будут изменяться с продвижением командира по уровням
                           //                Если установить 0, то здоровье и урон  будут автоматически прибавляться вместе с уровнем командира (из ERM Help = CO:P)
_dword_ attack;           // 0x1C     +28   Атака
_dword_ defence;          // 0x20     +32   Защита
_dword_ hit_points;       // 0x24     +36   Здоровье
_dword_ damage;           // 0x28     +40   Урон
_dword_ spell_power;      // 0x2C     +44   Сила_магии
_dword_ speed;            // 0x30     +48   Скорость
_dword_ resistance;       // 0x34     +52   Сопротивление

_dword_ lvl_attack;       // 0x38     +56   Уровень_Атаки
_dword_ lvl_defence;      // 0x3C     +60   Уровень_Защиты
_dword_ lvl_hit_points;   // 0x40     +64   Уровень_Здоровья
_dword_ lvl_damage;       // 0x44     +68   Уровень_Урона
_dword_ lvl_spell_power;  // 0x48     +72   Уровень_Сила_магии
_dword_ lvl_speed;        // 0x4C     +76   Уровень_Скорости
_dword_ lvl_resistance;   // 0x50     +80   Уровень_Сопротивления

_word_ arts[10][8];       // 0x54     +84   Номер_артефакта; Кол-во проведённых с ним битв
_char_ name[32];          // 0xF4     +244  Имя
_dword_ old_expa;         // 0x114    +276  Старый_опыт_героя
_dword_ now_expa;         // 0x118    +280  Текущий_опыт
_dword_ now_level;        // 0x11C    +284  Текущий_уровень (при отображении добавляем +1)
_dword_ specBon[2];       // 0x120    +288  Особые_бонусы(сумма_битов); Запрещенные_бонусы(сумма_битов)
};

// функция получения адреса структуры командира
inline _Npc_*  GetNpc(_int_ hero_id) {return ((_Npc_ *)(0x28620C0 + 296 * hero_id));}
// функция получения строк из командирского текстовика "znpc00.txt"
inline char* Get_ITxt(int StrNum, int ItemNum) {return CALL_3 (char*, __cdecl, 0x77710B, StrNum, ItemNum, 0x2860724);}
// функция получения строк из командирского текстовика "znpc01.txt" Имена и биографии
inline char* Get_ITxtBio(int StrNum, int ItemNum) {return CALL_3 (char*, __cdecl, 0x77710B, StrNum, ItemNum, 0x286072C);}
// функция получения силы первичного командирского навыка
inline int Get_NpcSkillPower(_Npc_* npc, int skill_id) {return CALL_2 (int, __thiscall, 0x769460, npc, skill_id);}
Image: B9WQ3qs.jpg


RE: Исследование героев - RoseKavalier - 03.09.2017 18:39

Очень приятно, спасибо еще раз за помощь)

EDIT:
Modified to use with short_tip_text. Works great, thanks x2
Code:
int __stdcall show_text_hint(_Dlg_* this_, _EventMsg_* msg)
{
    int r = this_->DefProc(msg);
    char* text;
    text = "";
    if (msg->type == MT_MOUSEOVER) {
        _DlgItem_* it = this_->FindItem(msg->x_abs, msg->y_abs);        
        if (it) {
            if (it->short_tip_text != NULL)
                text = it->short_tip_text;
        }
        statbar->SetText(text);
        statbar->Draw();
        statbar->RedrawScreen();
    }        
    return r;
}



RE: Исследование героев - RoseKavalier - 07.09.2017 04:06

I read conversation at DF2 (don't have account there...) and your solution below.
Я читал разговор на DF2 (нет аккаунта там...) и ваше решение ниже.
Graphic mode

It seems bug is related to different graphic mode,
32-bit GDI ok
True not ok
Image: tFuHLND.png

By any chance, could there be updated versions of dialog files?
Случайно, может быть обновленных версий диалоговые файлы?

If not, is there a way to make Set_DlgStdBackground() more... dynamic and less "one-size fits all". Seems to increment in +64
Если нет, есть ли способ, чтобы сделать Set_DlgStdBackground() в более... динамичным и менее "одну гребенку". Кажется, прирост в +64

Спасибо за ваше время)

Code:
width = 272;
dlg->AddItemByZOrder(_DlgStdBackground_::Create(0, 0, d_w, d_h, 0, 0, o_GameMgr->GetMeID()), 0);
Image: vzITrz1.png

Code:
width = 250
Set_DlgStdBackground (dlg);
Image: KR3sUij.png

Code:
width = 260
Set_DlgStdBackground (dlg);
Image: EMrhDFS.png


RE: Исследование героев - igrik - 07.09.2017 13:41

(07.09.2017 04:06)RoseKavalier Wrote:  By any chance, could there be updated versions of dialog files?
Случайно, может быть обновленных версий диалоговые файлы?

If not, is there a way to make Set_DlgStdBackground() more... dynamic and less "one-size fits all". Seems to increment in +64
Если нет, есть ли способ, чтобы сделать Set_DlgStdBackground() в более... динамичным и менее "одну гребенку". Кажется, прирост в +64
Обновленных версий нет.

Да, там проиходит увеличение дилогового окна на +64.
Если хотите сделать более динамичным, то вам необходимо исследовать функцию 0x48FA80 и перед показом диалога изменять все "64" на нужное увеличение размера, а потом возвращать этот параметр (=64).
Я бы сделал так.


RE: Исследование героев - RoseKavalier - 08.09.2017 04:00

Отличный ответ, спасибо!

EDIT: good news ---
you can place any custom *.pcx, *.def, *.bmp inside your plugin folder and it can be used directly.
вы можете разместить любой заказ, *.pcx, *.def, *.bmp ..., внутри папки плагинов и его можно использовать напрямую.

Image: mdDrR8w.png

EDIT2: after some thinking... started making a function for dynamic background.
Lacks color but maybe that can be fixed...
после некоторых размышлений, я начал делать функцию для динамического фона.

It works will all graphic modes as far as I could tell.
Code:
int create_standard_background(_Dlg_* dlg, int status_bar)
{
    //dlg->AddItem(_DlgStaticPcx8_::Create(0, 0, min(dlg->width,256), min(dlg->height,256), 0, "DiBoxBck.pcx"));
    
    int current_x, remaining_x, current_y, remaining_y, horizontal_row;

    current_x = 0;
    remaining_x = dlg->width;
    current_y = 0;
    remaining_y = dlg->height;
    horizontal_row = 0;

    if (remaining_x < 64 || remaining_y < 64)
        return 0;

    while (TRUE) {        
        while (TRUE) { // do horizontal pass first
            if (remaining_x > 0) {
                dlg->AddItem(_DlgStaticPcx8_::Create(current_x, horizontal_row * 256, min(remaining_x, 256), min(remaining_y, 256), 0, "DiBoxBck.pcx"));
                current_x = current_x + 256;
                remaining_x = remaining_x - 256;
            }
            else break;
        }        
        current_x = 0;        // reset x position to 0        
        remaining_x = dlg->width; // reset length of horizontal line
        remaining_y = remaining_y - 256; // update remaining y since we're done with horizontal pass
        horizontal_row = horizontal_row + 1;    // we might be working on a new row soon if condition below is met        
        if (remaining_y <= 0)
            break;        // no more rows to add
    }

    int top_left = 0;
    int top_right = 1;
    int bottom_left = 2;
    int bottom_right = 3;
    int left_middle = 4;
    int right_middle = 5;
    int top_middle = 6;
    int bottom_middle = 7;

    if (status_bar) {
        bottom_left = 8;
        bottom_right = 9;
        bottom_middle = 10;
    }

    // add horizontal borders    
    current_x = 0;
    remaining_x = dlg->width;
    while (remaining_x >= 64) {
        dlg->AddItem(_DlgStaticDef_::Create(current_x, 0, 0, "dialgbox.def", top_middle, 0, 0));
        dlg->AddItem(_DlgStaticDef_::Create(current_x, dlg->height - 64, 0, "dialgbox.def", bottom_middle, 0, 0));
        current_x += 64;
        remaining_x -= 64;
    }
    // add vertical borders
    current_y = 0;
    remaining_y = dlg->height;
    while (remaining_y >= 64) {
        dlg->AddItem(_DlgStaticDef_::Create(0, current_y, 0, "dialgbox.def", left_middle, 0, 0));
        dlg->AddItem(_DlgStaticDef_::Create(dlg->width - 64, current_y, 0, "dialgbox.def", right_middle, 0, 0));
        current_y += 64;
        remaining_y -= 64;
    }

    // add four corners
    dlg->AddItem(_DlgStaticDef_::Create(0, 0, 0, "dialgbox.def", top_left, 0, 0));
    dlg->AddItem(_DlgStaticDef_::Create(0, dlg->height - 64, 0, "dialgbox.def", bottom_left, 0, 0));
    dlg->AddItem(_DlgStaticDef_::Create(dlg->width - 64, 0, 0, "dialgbox.def", top_right, 0, 0));    
    dlg->AddItem(_DlgStaticDef_::Create(dlg->width - 64, dlg->height - 64, 0, "dialgbox.def", bottom_right, 0, 0));
}
Image: HWByect.png


RE: Исследование героев - igrik - 08.09.2017 11:16

(08.09.2017 04:00)RoseKavalier Wrote:  EDIT2: after some thinking... started making a function for dynamic background.
Lacks color but maybe that can be fixed...
после некоторых размышлений, я начал делать функцию для динамического фона.

It works will all graphic modes as far as I could tell.
Wow nice!!
Add a repainted dialogue to the player's color. Like this
Code:
// add color this player
CALL_5 (int, __thiscall, 0x5FF400, dlg, 512, 13, 0, o_GameMgr->GetMeID());

// add four corners
dlg->AddItem(_DlgStaticDef_::Create(0, 0, 0, "dialgbox.def", top_left, 0, 0));
dlg->AddItem(_DlgStaticDef_::Create(0, dlg->height - 64, 0, "dialgbox.def", bottom_left, 0, 0));
dlg->AddItem(_DlgStaticDef_::Create(dlg->width - 64, 0, 0, "dialgbox.def", top_right, 0, 0));    
dlg->AddItem(_DlgStaticDef_::Create(dlg->width - 64, dlg->height - 64, 0, "dialgbox.def", bottom_right, 0, 0));
}
Image: Q5zoYrS.jpg


RE: Исследование героев - RoseKavalier - 08.09.2017 17:36

(08.09.2017 11:16)igrik Wrote:  Wow nice!!
Add a repainted dialogue to the player's color. Like this
Code:
// add color this player
CALL_5 (int, __thiscall, 0x5FF400, dlg, 512, 13, 0, o_GameMgr->GetMeID());
Image: Q5zoYrS.jpg

!!!!!

Я не знаю, почему и как это работает, но это **** невероятно! Огромное спасибо)

109

Ed: same logic, blue background.
же логику, синий фон.

Code:
int create_blue_background(_Dlg_* dlg)
{
    int current_x, remaining_x, current_y, remaining_y, horizontal_row;

    current_x = 0;
    remaining_x = dlg->width;
    current_y = 0;
    remaining_y = dlg->height;
    horizontal_row = 0;

    if (remaining_x < 42 || remaining_y < 42)
        return 0;

    while (TRUE) {
        while (TRUE) { // do horizontal pass first
            if (remaining_x > 0) {
                dlg->AddItem(_DlgStaticPcx8_::Create(current_x, horizontal_row * 256, min(remaining_x, 256), min(remaining_y, 256), 0, "DlgBluBk.bmp"));
                current_x += 256;
                remaining_x -= 256;
            }
            else break;
        }
        current_x = 0;        // reset x position to 0        
        remaining_x = dlg->width; // reset length of horizontal line
        remaining_y = remaining_y - 256; // update remaining y since we're done with horizontal pass
        horizontal_row = horizontal_row + 1;    // we might be working on a new row soon if condition below is met        
        if (remaining_y <= 0)
            break;        // no more rows to add
    }

    int top_left = 0;
    int top_right = 1;
    int bottom_left = 2;
    int bottom_right = 3;
    int left_middle = 4;
    int right_middle = 5;
    int top_middle = 6;
    int bottom_middle = 7;

    // add horizontal borders    
    current_x = 0;
    remaining_x = dlg->width;
    while (remaining_x >= 42) {
        dlg->AddItem(_DlgStaticDef_::Create(current_x, 0, 0, "DlgBluBo.def", top_middle, 0, 0));
        dlg->AddItem(_DlgStaticDef_::Create(current_x, dlg->height - 42, 0, "DlgBluBo.def", bottom_middle, 0, 0));
        current_x += 42;
        remaining_x -= 42;
    }
    // add vertical borders
    current_y = 0;
    remaining_y = dlg->height;
    while (remaining_y >= 42) {
        dlg->AddItem(_DlgStaticDef_::Create(0, current_y, 0, "DlgBluBo.def", left_middle, 0, 0));
        dlg->AddItem(_DlgStaticDef_::Create(dlg->width - 42, current_y, 0, "DlgBluBo.def", right_middle, 0, 0));
        current_y += 42;
        remaining_y -= 42;
    }

    // add four corners
    dlg->AddItem(_DlgStaticDef_::Create(0, 0, 0, "DlgBluBo.def", top_left, 0, 0));
    dlg->AddItem(_DlgStaticDef_::Create(0, dlg->height - 42, 0, "DlgBluBo.def", bottom_left, 0, 0));
    dlg->AddItem(_DlgStaticDef_::Create(dlg->width - 42, 0, 0, "DlgBluBo.def", top_right, 0, 0));
    dlg->AddItem(_DlgStaticDef_::Create(dlg->width - 42, dlg->height - 42, 0, "DlgBluBo.def", bottom_right, 0, 0));
}



RE: Исследование героев - RoseKavalier - 18.09.2017 05:05

Small modification for create_standard_background(...) to prevent border appearance in status bar... actually would be slightly more efficient starting from (dlg->height - 64) and working back but this works fine)
Небольшая модификация для create_standard_background(...) для предотвращения появления границы в строке состояния...

Code:
    // add vertical borders
    current_y = 0;
    remaining_y = dlg->height;
    while (remaining_y >= 64) {
        if (remaining_y - 64 <= 37)
            current_y = dlg->height - 64 - 37; // hide a bit for status bar
        dlg->AddItem(_DlgStaticDef_::Create(0, current_y, 0, "dialgbox.def", left_middle, 0, 0));
        dlg->AddItem(_DlgStaticDef_::Create(dlg->width - 64, current_y, 0, "dialgbox.def", right_middle, 0, 0));
        current_y += 64;
        remaining_y -= 64;
    }

~~~~~

Are there structures available for Quest Guards / Seer Huts? Only thing I could find is QU receiver from ERA but no structure... I could probably map these myself but if someone has and is willing to share, would be quite helpful!
Имеющиеся конструкции для охранников квеста / хижины Провидца? Единственное, что я мог найти, это QU приемник от эпохи, но не структура... Я мог бы сопоставить его сам, но если кто-то имеет и готов поделиться, это было бы очень полезно!

e.g.
struct + 0x3C = deadline / крайний срок


RE: Исследование героев - gamecreator - 18.09.2017 20:55

(18.09.2017 05:05)RoseKavalier Wrote:  Are there structures available for Quest Guards / Seer Huts? Only thing I could find is QU receiver from ERA but no structure... I could probably map these myself but if someone has and is willing to share, would be quite helpful!
Link updated. It has the sources you need.


RE: Исследование героев - RoseKavalier - 19.09.2017 05:14

Wonderful, much appreciated. What a great community!


RE: Исследование героев - RoseKavalier - 26.09.2017 09:02

Hello... another question I can't seem to solve.
Привет ... другой вопрос, который я не могу решить.

Code:
dlg->AddItem(_DlgTextEdit_::Create(50, 360, 400, 60, 13, "1234", "medfont.fnt", 1, 1, "DlgBluBk.PCX", 5, 4, 0, 0));

// _DlgTextEdit_* Create(int x, int y, int width, int height, int max_len, char* text, char* font_name, _dword_ text_color, _dword_ text_align, char* bkground_pcx8_name, int id, _bool_ has_border, int border_width, int border_height)

Is there an easy way to restrict which characters can be input in _DlgTextEdit_?
e.g. digits only
Есть ли простой способ ограничить, какие символы могут быть введены в _DlgTextEdit_?
например только цифры
Image: zFCZDEQ.png


RE: Исследование героев - Valery - 26.09.2017 11:08

Is there some restriction from HD for that? Because I can't anymore input any digits in that box and I can't find any tweak about in HD.

@Edit: I found, HD requires ctrl hold to change digits.


RE: Исследование героев - igrik - 26.09.2017 18:08

(26.09.2017 09:02)RoseKavalier Wrote:  Hello... another question I can't seem to solve.
Is there an easy way to restrict which characters can be input in _DlgTextEdit_?
I do not know how to do it yet. But I'll figure it out.


RE: Исследование героев - RoseKavalier - 27.09.2017 08:35

@Valery
You don't need to press Control, just click in the area and you can type numbers. This is not a HD feature, it is available with regular HoMM3 - or at the very least it worked on my 4.0 copy without HDmod.

@igrik
Thanks)
I looked at function that does for creatures but I got lost.
0x5BB000 (process command)
0x5FF3A0 (load correct text to 0x697428)

Alternatively, I thought of reading text from edit and removing unwanted characters - then load back text without unwanted characters to edit.

Спасибо)
Я смотрел на функцию, которая делает для существ, но я потерялся.
0x5BB000 (команда процесса)
0x5FF3A0 (загрузить правильный текст в 0x697428)

В качестве альтернативы, я думал о чтении текста из редактирования и удалении нежелательных символов, а затем загружать текст без ненужных символов для редактирования.
Code:
proc:
    (print to buffer) ((_DlgTextEdit_*)dlg->GetItem(edit_id))->text;
    (remove non-digits from buffer);
    ((_DlgTextEdit_*)dlg->GetItem(edit_id))->text = buffer;

I have not had time to try and code it and test so no idea if it could/would work.


RE: Исследование героев - Valery - 27.09.2017 15:50

Nope, typing directly digits has no effect, need to hold control key in HD mod. Without HD is ok.


RE: Исследование героев - RoseKavalier - 29.09.2017 22:28

(27.09.2017 15:50)Valery Wrote:  Nope, typing directly digits has no effect, need to hold control key in HD mod. Without HD is ok.
I tried on 4.208, few 5.0s and control key is not needed?
Anyhow, not really important.

@igrik
I tried my idea from previous post... it kind of works. It's not perfect but in the end only digits remain. 105
Я попробовал то, что написал в предыдущем посте... Это работает. Это не идеально, но в конце концов только цифры.

Code:
int __stdcall edit_text_proc(_Dlg_* dlg, _EventMsg_* msg)
{
    int r = dlg->DefProc(msg);

    if (msg->type == MT_KEYDOWN || msg->type == MT_KEYUP || msg->type == MT_MOUSEBUTTON) {            // not absolutely necessary, less cpu intensive
        _DlgTextEdit_ *edit = (_DlgTextEdit_*)(dlg->GetItem(55));    // id of _DlgTextEdit_
        char edit_text[25];                                            // _DlgTextEdit_ max_len
        sprintf(edit_text, edit->text);                                // copy _DlgTextEdit_ text
        keep_digits(edit_text);                                        // keep only '0123456789' in string (with !is_digit())
        if (edit_text[0] == 0) {                                    // strlen == 0
            edit_text[0] = '0';                                        // put '0' as default
            edit_text[1] = 0;                                        // terminate string
        }
        sprintf(edit->text, edit_text);                                // replace _DlgTextEdit_ text
        dlg->Redraw();                                                // redraw
    }
    return r;
}

EDIT:
Got it working nice and fine 109

Add this also when creating. Noticed it was happening with creature dialog.
Code:
_DlgTextEdit_* edit= (_DlgTextEdit_*)(dlg->GetItem(#EDIT_ID#));
edit->redraw_actions = FALSE;

In proc, have keep_digits(edit_text) return 1 / 0 depending whether a non-digit was found e.g.
Code:
int keep_digits(char* input)
{
    char* dest = input;
    char* src = input;
    int non_digit = 0;

    while (*src)
    {
        if (!isdigit(*src)) {
            non_digit = 1;
            src++;
            continue;
        }
        *dest++ = *src++;
    }
    *dest = '\0';
    return non_digit;
}

If true, decrease position of cursor "caret".
Code:
if (keep_digits(edit_text))    
    edit->caret_pos--;

Only "slight" bug is CTRL-V "paste"... cursor "caret" vanishes with non-digits.
...don't care too much about that one.


RE: ERA II - baratorch - 29.12.2017 05:26

насчет загрузки и отрисовки полноцветных изображений.
и проблемы c этим в 32-bit True режимах ХД.

Почему не использовать оригинальный геройский _Pcx24_ ???

А если уж так надо получить именно _Pcx16_ (_Pcx32_), то можно воспользоваться оригинальной геройской функцией

рисующей _Pcx24_ на _Pcx16_ (_Pcx32_)

при этом не надо запариваться какая там битность и что там внутри _Pcx16_ (_Pcx32_) при каком режиме.

Конструктор новой _Pcx24_: 44EA20
- этот конструктор заполняет буфер из указанного источника, поэтому лучше написать свой конструктор пустой _Pcx24_
(сканлайн = ширина * 3, размер буфера = сканлайн * высота. пиксель в формате RGB888)
Конструктор новой _Pcx16_: 0x44DD20
Функция рисующая _Pcx24_ на _Pcx16_: 0x44ECA0

Именно так, через загрузку _Pcx24_ и его отрисовку на _Pcx16_
загружаются в менеджере ресурсов полноцветные pcx в оригинале.


RE: ERA II - Berserker - 29.12.2017 15:54

baratorch, спасибо за ценную информацию!


RE: Исследование героев - Berserker - 09.04.2018 02:17

Изучение некромантии в университете героями любых классов:
http://wforum.heroes35.net/showthread.php?tid=3585&pid=99678#pid99678


RE: Исследование героев - igrik - 12.07.2018 18:30

Наконец, то я разобрался с этой хренью
скрин (Click to View)

Всё для того, чтобы полноценно и нормально запилить кастующих монстров (link UN:C)


RE: Исследование героев - igrik - 08.11.2018 17:25

Интересная недокументированная особенность.

Все мы прекрасно знаем, что описания Джедита и Нагаша в Воге всегда были на английском языке.
На самом деле, русский язык для описания специальностей тоже предусмотрен. В коде WOG'a даже есть переменная, отвечающая за русскую или английскую локализацию.
Code:
// тип игры 0-английская, 1-русская
int WoGType=0; // для ERA 0x80321C

0x703F28 void FileLoader(void) - это функция, которая инициализирует некоторые воговские параметры и заодно устанавливает английский или русский язык в переменную WoGType.
Вот выдержка кода, отвечающая за установку типа локализации:
Code:
if(LoadTXT("ZMESS00.TXT",&Strings)) Exit(); // не может загрузить TXT
  // выносим внутренние сообщения в файл наружу
  TxtOutOfExe();
  // тип локализации
  switch(ITxt(0,0,&Strings)[0]){ // считываем первый символ ZMESS00.TXT
    case 'R': WoGType=1; break;  // русский язык
    default : WoGType=0;         // иначе английский язык
  }
Суммарно русских строк в коде немного: менее десяти наберется. В том числе и описания специализаций героев Джедита и Нагаша
Так вот, видимо при переводе на русский язык о данной особенности не знали. А всё что нужно было сделать для инициализации русских строк и описания специальностей, это в файле "ZMESS00.TXT" первый символ в моде "WoG Rus" изменить с E на R

ENG Wrote:E All New Messages are to be placed below.
RUS Wrote:R All New Messages are to be placed below.




RE: Исследование героев - Algor - 09.11.2018 13:13

Berserker'у в ЛС продублируй, чтоб не забылось до подготовки следующего русификатора.


RE: База для IDA и исходники последней Славиной версии ВоГа - feanor - 23.11.2018 20:07

Как вытащить гильдии 4- и 5-ого уровней для городов, где они заблокированы изначально:
Для вытаскивания ГМ4-5 вообще никаких особенных хитростей не надо, но делать это реально удобнее плагинами: слишком много всего происходит до старта ERM.

https://pastebin.com/1cNdDE7Q buildups
https://pastebin.com/Cx9T9wGT towns

1. Нам надо сделать ГМ4-5 как строение на экране.
Для этого надо добавить его в таблицу приоритетов зданий; задать ему координаты, имя дефа, имя маски. Это делается в плагине, который towns. У нас - в конфиге, который я когда-нибудь обязательно преобразую в геройскую текстовую таблицу, конфиг в моде, прикладывать поленился, впрочем, там и так понятно.
2. Надо сделать ГМ4-5 как отстраиваемое строение.
Для этого нужно тем или иным способом задать ему требования отстройки. Я делал это вот в этой замечательной таблице, которая Dependencies. Её правка работает _только_ до реального старта игры, ерм - поздно, по-моему, даже OnAfterWoG поздно. Если надо править после старта, то либо ERM (какой-то из ресиверов в СА, уже не помню, CA:B вроде), либо надо найти структуру, в которую эти списки преобразуются. Там битовое поле, ищется несложно, но зачем, если есть такой замечательный гибрид между человеко- и машино- читаемым видом. Сразу говорю, копировать из приведенного кода не надо, там все деревья тсвшные. Лучше из экзешника.
Не помню, надо ли править текстовики для цен и описаний. Наверное, надо.
2.5. Надо сделать ГМ отстраиваемым в таунхолле.
Это, соответственно, одна из трех строк.
Code:
*(unsigned short*)4591590 = 37008; //cstl skip

    *(char*)0x460FAA = 0x40; //barb id
    *(char*)0x460FAE = 0x40; //wtch id
замок, барб, фортресс, соответственно.
Да, это разные методы, в одном патчится условный переход, в другом правится индекс. Не помню.
3. Надо додать заклинаний в ГМ.
А вот это делается чисто текстовиками. В sptraits или как там его прописана нулевая вероятность выпадения спеллов соответствующего уровня у недомагических замков: если додать какую надо - будут прекрасно генерироваться.
4. ИИ править не надо, он ГМ строить будет и так.
5. Редактор карт - надо, забыл приложить быстрофикс.
https://pastebin.com/ctahgjTh


RE: Карта-мод STALKER для ERA 2.7.7 - feanor - 26.03.2019 16:41

Указатель на таблицу заклинаний лежит по 0х687FA8, формат записи -
Code:
struct _Spell_{ // size:88h
  int   FRposNOzerENneg; // +0 -1=enemy, 0=square/global/area, 1=friend
  char *SoundFileName;   // +4
  int   DefIndex;        // +8 used to get DefName
  int   Flags;            // +C
//0x00000001 - BF spell
//0x00000002 - MAP spell
//0x00000004 - Has a time scale (3 rounds or so)
//0x00000008 - Creature Spell
//0x00000010 - target - single stack
//0x00000020 - target - single shooting stack (???)
//0x00000040 - has a mass version at expert level
//0x00000080 - target - any location
//0x00000100 -
//0x00000200 -
//0x00000400 - Mind spell
//0x00000800 - friendly and has mass version
//0x00001000 - cannot be cast on SIEGE_WEAPON
//0x00002000 - Spell from Artifact
//0x00004000 -
//0x00008000 - AI
//0x00010000 - AI area effect
//0x00020000 - AI
//0x00040000 - AI
//0x00080000 - AI number/ownership of stacks may be changed
//0x00100000 - AI
  char  *Name;            // +10h
  char  *AbbrName;        // +14h
  int    Level;           // +18h
  int    SchoolBits;      // +1Ch Air=1,Fire=2,Water=4,Earth=8
  int    Cost[4];         // +20h cost mana per skill level
  int    Eff_Power;       // +30h
  int    Effect[4];       // +34h effect per skill level
  int    Chance2GetVar[9];// +44h chance per class
  int    AIValue[4];      // +68h
  char  *Descript[4];     // +78h
};



RE: Ваши вопросы по ERM-скриптам - XEPOMAHT - 13.05.2019 00:58

Quote:можно ли выдернуть готовый скрипт с игры на артефакт "топор свирепости лорда варваров". Если можно, то как это сделать?

1. В функции BuildUpNewComboArts:

Code:
    int Arts[10]={10,16,22,28};
    BuildUpCombo(158,12,4,Arts);

2. Ассемблерный код на сам артефакт:




RE: Исследование героев - igrik - 06.06.2019 23:15

Так. Как я понимаю - для некоторых - о давно наболевшем.

Отключение ТЮРЕМ (скачать)
Файл класть в папку "EraPlugins\AfterWoG" любого активного мода.
Вообще, наверное, нужно включить в официальную эру эту заплатку в отключенном состоянии. ИМХО

Это bin файл, позволяющий отключать генерацию тюрем на случайных картах.
Одно уточнение: я оставил генерацию тюрем только с героями 1 уровня. Тюрьмы с героями 5, 15, 30 уровней вырезаны.
Еще раз: данная фича работает только для случайных карт, поэтому за авторские карты можно не беспокоиться.

Code:
// вырезаем генерацию тюрем
JMP отсюда         0x53A317    (5481239)        тюрьмы все
... или ...
JMP отсюда         0x53A363    (5481315)        тюрьмы с опытом >= 5000
... и ...
JMP сюда           0x53A48E    (5481614)        создание объекта с №63

ИТОГО КОД ЗАПЛАТКИ: 0053A363 E926010000  (0x53A363 JMP 0053A48E)



RE: Исследование героев - igrik - 02.07.2019 11:51

Решение проблемы отображения некоторых строк (в русской локализации) в диалоге экспы монстров.
Суть в подмене типа копирования символов со знакового на беззнаковое ( MOVSX -> MOVZX )

Image: 111.jpg


Полный код для заплатки: (скачать)
Code:
0071F3FC B6
0071F5BA B6
0071F5D3 B6
00723657 B6
00723219 B6
007238D8 B6
007217BB B6
00723CBD B6
00721B03 B6
00722792 B6
00723ACB B6
00723F1C B6


Сравнение отображения линий в диалоге:

Image: Dlg_Expo.gif

На сколько я знаю, MoP уже давно решил эту проблему, но как он это сделал я нигде не встречал.


RE: Исследование героев - Berserker - 02.07.2019 12:36

igrik, отличная заплатка, спасибо!


RE: Исследование героев - XEPOMAHT - 02.07.2019 13:34

(02.07.2019 11:51)igrik Wrote:  MoP уже давно решил эту проблему, но как он это сделал я нигде не встречал.

Если интересно, то вот код из исходников:

Code:
; настраиваем тексты и подсказки способностей:
        xor ebx, ebx
      .repeat
        mov eax, [ebx*4+840E40h]
       .if eax
        ChangeDlgItem esi, addr ebx + 1100, 3, eax
        fn Настройка_подсказки_к_элементу_игрового_диалога, esi, addr ebx + 1100, dword [ebx*4+85D308h]
        mov edi, ebx
        imul edi, 100h
        fn Настройка_подсказки_к_элементу_игрового_диалога, esi, addr ebx + 1300, addr edi + 845B00h
        add edi, 85DB48h
        mov dword [ebp-8], 0
         .repeat
        imul eax, ebx, 11
        add eax, [ebp-8]
        add eax, 1116
        xchg byte [edi+8], bh; обнуляем конец строки
        ChangeDlgItem esi, eax, 3, edi
        xchg byte [edi+8], bh; возвращаем исходный символ
        add edi, 8
        inc dword [ebp-8]
         .until signed dword [ebp-8] > 10
       .endif
        inc ebx
      .until signed ebx > 15

Соответственно, сам воговский код этого дела в MoP заглушен и, скорее всего, затёрт.


RE: Исследование героев - daemon_n - 18.07.2019 04:59

Не знаю, как часто поднималась данная тема, потому спрошу с опаской:
были ли попытки научить ИИ пользоваться рюкзаком? А то все эти попытки его усилить скриптами упростились, научись он просто грамотно подбирать арты к бою и на ночь.166


RE: Исследование героев - XEPOMAHT - 18.07.2019 11:20

(18.07.2019 04:59)daemon_n Wrote:  научись он просто грамотно подбирать арты к бою и на ночь.166

Возьми да сделай скрипт, переодевающий куклу героев ИИ перед боем и на ночь. Самое сложное там - решить какие артефакты должен одевать ИИ, а какие снимать (т.е. для каждого артефакта нужно будет как-то высчитывать AI value, по которому они все будут приоритетны для ИИ в той или иной степени, но такой готовой таблицы для Третьих Героев никто никогда не делал, хотя сделать её может любой опытный игрок - желания нет ни у кого, увы 105).


RE: Исследование героев - daemon_n - 18.07.2019 12:57

XEPOMAHT, таблицу, мб, подумаю на досуге, если опыт позволит)
Однако вопрос именно в моментальном переодевании, чтобы ии, получив книгу земли, смог сразу использовать и спастись либо напасть.


RE: Исследование героев - XEPOMAHT - 18.07.2019 15:04

(18.07.2019 12:57)daemon_n Wrote:  Однако вопрос именно в моментальном переодевании, чтобы ии, получив книгу земли, смог сразу использовать и спастись либо напасть.

В триггере пост-посещения артефакта проверяешь ИИ-чность, если ИИ, то ищешь артефакт в сумке, если артефакт найден в сумке, то читаешь номер слота из структуры артефакта и AI value артефакта и проверяешь в слотах куклы героя те же AI value, а затем сравниваешь их. Если AI value подобранного на карте артефакта больше уже одетого, то меняешь их местами.

Перед битвой так же можно сравнивать всю куклу героя с рюкзаком на AI value, т.к. артефакты у героев могут появляться в любой момент времени и это затратно отслеживать (т.к. особые функции при этом не нужны, достаточно просто изменить байт в структуре героя).


RE: Исследование героев - MOP - 19.07.2019 15:25

Слишком много факторов учитывать надо. К примеру, Сферу Земли когда ИИ надевать? Когда у него есть полезные заклинания этой школы. Когда они полезнее заклинаний других школ. Когда колдовство не запрещено полностью (Сфера Запрещения) или частично (Проклятая Земля), но не запрещается колдовство наиболее полезных заклов. Когда нужные заклинания изучены. Когда есть книга заклинаний. Как прокачана мудрость и сила магии. Есть ли свободный слот. Каковы свойства заклинаний. Нет ли надетого артефакта, который нивелирует свойства Сферы. Иммунитеты существ - своих и чужих. Наконец, не надет ли более полезный артефакт или дублирующий свойства Сферы. И еще невесть какие факторы, о которых вспомнишь только в игре.
И это условия полезности лишь для одного артефакта. Какая ещё таблица AI value, когда всё так ситуативно?


RE: Исследование героев - daemon_n - 19.07.2019 15:40

MOP, вот поэтому он будет среди последних)


RE: Исследование героев - XEPOMAHT - 19.07.2019 16:16

(19.07.2019 15:25)MOP Wrote:  Какая ещё таблица AI value, когда всё так ситуативно?

С точки зрения заядлого игрока, знающего все вышеперечисленные особенности - да, использование AI value не приведёт ИИ до уровня эксперта по игре. Тогда для и монстров давайте тоже перестанем использовать AI value по той же причине ситуативности (вроде в игре работает норм, даже в MoP с почти удвоенным их количеством).

Например как играю я: поднимаю с карты ту же Сферу Земли, помещаю на куклу героя взамен какого-нибудь барахла и играю дальше, не думая ни о каких-то факторах (на Героях мозг обычно должен отдохнуть, это развлечение). Конечно, можно сказать, что хардкорщиков-задротов сейчас наверное большинство (от того и рулят моды, не содержащие коренных изменений игрового процесса), но я бы всё всё равно предложил для ИИ схему по-проще (например, в MoP уже больше 400 артефактов, сложную схему для ИИ сделать жизни не хватит).


RE: Исследование героев - MOP - 19.07.2019 19:30

Ну если упрощённо, то такая система AI value уже есть в игре - градация по классам артефактов. И она худо-бедно работает - потому что и создана для ИИ. Вот только лучше бы вместо классов в качестве value была выбрана стоимость в золоте - иными словами, не четыре ступени ценности, а неограниченный ценностный диапазон.


RE: Исследование героев - daemon_n - 22.07.2019 14:58

(19.07.2019 19:30)MOP Wrote:  Ну если упрощённо, то такая система AI value уже есть в игре - градация по классам артефактов. И она худо-бедно работает - потому что и создана для ИИ. Вот только лучше бы вместо классов в качестве value была выбрана стоимость в золоте - иными словами, не четыре ступени ценности, а неограниченный ценностный диапазон.

Но это только если Артефакт подбирается с земли.


RE: Ваши вопросы по ERM-скриптам - igrik - 17.12.2019 14:44

(17.12.2019 12:42)Algor Wrote:  Как вариант, конечно, раскопать какую-нить функцию типа "мощь армии королевства" из обзора королевства, но не уверен, что там будет именно то, что нужно.
Отдельно взятой такой функции нет. Есть только участок кода внутри функции, но его никак нельзя использовать через ERM
Проще скриптом запилить...
Но есть проблема: никакой ERM переменной не хватит для хранения таких чисел.


RE: Ваши вопросы по ERM-скриптам - Berserker - 17.12.2019 16:17

Quote:Но есть проблема: никакой ERM переменной не хватит для хранения таких чисел.
e2?


RE: Ваши вопросы по ERM-скриптам - Algor - 17.12.2019 17:56

(17.12.2019 16:17)Berserker Wrote:  
Quote:Но есть проблема: никакой ERM переменной не хватит для хранения таких чисел.
e2?
Даже если не хватит, я не думаю, что облагаться налогом будет каждая единица FV 118


RE: Исследование героев - igrik - 13.02.2020 16:06

(13.02.2020 15:49)Berserker Wrote:  I will need to send generator state over net on online PvP battle. ~3 KB for Mersenne Twister.

Передача данных по сети:
Code:
// структура передачи данных по сети
struct _NetData_
{
_int_ recipient_id;  // +0   (номер игрока кому передаётся. (-1 = всем) )
_int_ field_04;      // +4
_int_ msg_id;        // +8   (id данных)
_int_ size;          // +12  (размер _NetData_ = 20 + sizeof(Data) )
_int_ field_10;      // +16
_int_ Data[];        // +20  (передаваемые данные (массив))


inline _int32_ SendData() {return CALL_4(_int32_, __fastcall, 0x5549E0, this, 127, 0, 1);}
inline _int32_ SendShortData() {return CALL_1(_int32_, __thiscall, 0x481CB0, this);}
};

Принимать и обрабатывать данные (рядом с этими адресами):
Code:
0x405E81 [карта приключений]
0x473D5E [битва]
0x588AC3 [меню выбора карт]



RE: Вопросы по моддингу - Bes - 21.07.2020 00:27

вопрос только один - что за адрес используется нестандартный 6933756 ?
я почему-то ожидал здесь адрес основного игрового менеджера (6919480)... есть у кого объяснение? Unsure


RE: Вопросы по моддингу - Berserker - 21.07.2020 00:38

69CCFC - структура текущего игрока

Code:
Byte *GamerStruc(int hn)
{
  #include "templ.h"
  if(hn==-1){
    __asm mov eax,0x69CCFC
    __asm mov eax,[eax]
    __asm mov BPDummy,eax
    RETURN(BPDummy)



RE: Исследование героев - Berserker - 09.08.2020 21:34

Выбор и кэширование зацикленных звуков объектов вблизи активного героя.
PHP Code:
00000000 AdvMgr              struc ; (sizeof=0x258mappedto_380)
00000000 field_0             db 548 dup(?)                           ; string(C)
00000224 cachedLoopsSoundsMask dd ?                                  ; DEPRECATED
00000228 cachedLoopSounds    HeroClosestLoopSound 4 dup
(?)
00000248 cachedLoopSoundWavs dd 4 dup(?)                             ; offset
00000258 AdvMgr              ends
00000258
00000000 
; ---------------------------------------------------------------------------
00000000
00000000 HeroClosestLoopSound struc 
; (sizeof=0x8mappedto_381)     ; XREFAdvMgr/r
00000000 loopSoundId         dd 
?
00000004 distance            dd ?
00000008 HeroClosestLoopSound ends

418B70 void __thiscall MapItem_Start_Loop_Sound
(AdvMgr *advMgrint xint yint zint distanceint allowCaching)
{
  
AdvMgr *self// esi
  
signed int determinedLoopSoundId// edi
  
AdvMgrConsts cachedLoopSoundIndex// eax
  
HeroClosestLoopSound *cachedLoopSound// ecx
  
int farthestDistance// edx
  
signed int newLoopSoundIndex// ebx
  
AdvMgrConsts i// eax
  
int prevLoopSoundId// eax
  
int *soundDistanceToCheck// [esp+14h] [ebp+8h]

  
self advMgr;
  if ( 
>= && >= && >= && MapSizeX && MapSizeY )
  {
    
determinedLoopSoundId AdvMgr_MapItem_Determine_Sound(xyz);
    if ( 
determinedLoopSoundId != -)
    {
      
cachedLoopSoundIndex 0;
      
cachedLoopSound self->cachedLoopSounds;
      while ( 
cachedLoopSound->loopSoundId != determinedLoopSoundId )
      {
        ++
cachedLoopSoundIndex;
        ++
cachedLoopSound;
        if ( 
cachedLoopSoundIndex >= MAX_CACHED_LOOP_SOUNDS )// Such looped sound not found in cache
        
{
          if ( 
allowCaching != )
          {
            
farthestDistance distance;
            
newLoopSoundIndex = -1;
            
0;
            
soundDistanceToCheck = &self->cachedLoopSounds[0].distance;
            do
            {
              if ( *
soundDistanceToCheck farthestDistance )
              {
                
farthestDistance = *soundDistanceToCheck;
                
newLoopSoundIndex i;
              }
              ++
i;
              
soundDistanceToCheck += 2;
            }
            while ( 
MAX_CACHED_LOOP_SOUNDS );
            if ( 
newLoopSoundIndex != -)
            {
              
prevLoopSoundId self->cachedLoopSounds[newLoopSoundIndex].loopSoundId;
              if ( 
prevLoopSoundId != -)
                
StopBINKVideo_AIL(o_SoundMgr, *(self->cachedLoopSoundWavs[prevLoopSoundId] + 7));
              
self->cachedLoopSounds[newLoopSoundIndex].loopSoundId determinedLoopSoundId;
              
self->cachedLoopSounds[newLoopSoundIndex].distance distance;
              if ( 
determinedLoopSoundId > -1
                
&& determinedLoopSoundId 70
                
&& !self->cachedLoopSoundWavs[determinedLoopSoundId] )
              {
                
Dlg_KingdomOverviewPrepare(self4);
                
self->cachedLoopSoundWavs[determinedLoopSoundId] = LoadWAV2((&off_0065F794)[determinedLoopSoundId]);
              }
              *(
self->cachedLoopSoundWavs[determinedLoopSoundId] + 11) = dword_0063A64C[distance];
              *(
self->cachedLoopSoundWavs[determinedLoopSoundId] + 12) = 0;
              *(
self->cachedLoopSoundWavs[determinedLoopSoundId] + 10) = 3;
              
NotifyPlayerWithBINKandSound(o_SoundMgrself->cachedLoopSoundWavs[determinedLoopSoundId]);
              
self->cachedLoopsSoundsMask ^= << self->cachedLoopSounds[newLoopSoundIndex].loopSoundId;
            }
          }
          return;
        }
      }
      if ( 
self->cachedLoopSounds[cachedLoopSoundIndex].distance distance )
      {
        
self->cachedLoopSounds[cachedLoopSoundIndex].distance distance;
        
self->cachedLoopsSoundsMask |= << self->cachedLoopSounds[cachedLoopSoundIndex].loopSoundId;
      }
    }
  }




RE: Исследование героев - Bes - 22.11.2020 01:05

Список идентификаторов игровых диалогов (получены в ERA2)
Code:
4205280 - карта приключений (КП)
    5755920 - окно сохранения
    5884864 - книга заклинаний
    4789216 - режим "дверь измерений"
    4790240 - режим "затопить корабль"
    6039360 - окно выбор города (без HD; для закла ГП или через врата Инферно)
    5217680 - окно повышения уровня героя
    5378592 - окно обзора королевства
    5976864 - окно настроек КП
    4216352 - окно действий на КП
    6275296 - обзор мира (включая заклы Просмотр земли/воздуха)
    5425744 - карта-загадка
    6068832 - гильдия воров
    5675664 - инфо по сценарию
    6100112 - окно гарнизона
    6099296 - окно оставления существ (включая шахты)
    5570288 - жилища существ/фабрика машин
    5637600 - жертвенный алтарь
    6228784 - университет
    6105344 - верфь
    6183568 - чёрный рынок/торговец артефактами (покупка)
    6167072 - рынок (обмен ресурсами)
    6175376 - рынок (передача ресурсов игроку)
    6241984 - окно статистики монстра/отряда
    5144224 - форт на холме
    6201472 - гильдия наёмников
    6126720 - таверна
** (одноимённые диалоги вне КП имеют те же ID и ниже не упоминаются)

4662240 - окно битвы
    4649504 - окно настроек в битве
    4658576 - статистика боя

5117840 - окно героя
    4304960 - окно командира (с WND)
    5432976 - окно журнала (без плагина на новый диалог)
    4304960 - окно журнала (с плагином на новый диалог)

6053040 - окно города
    6087968 - гильдия магов
    6081760 - зал совета
        6119232 - инфо о постройке
    6147920 - форт/замок
    6102528 - кузница
    5661104 - преобразователь скелетов
    6193120 - торговец артефактами (продажа)

5957344 - окно встечи героев

4782512 - прочие диалоги (включая IF:M/IF:Q; и все новые от HD)
4304960 - WoG-диалоги (с WND: опыт существ, сфинкс, проклятья, IF:G/IF:B и пр.)
- - -     WoG-диалоги без WND не пропускают (OnKeyPressed), потому хз как их пощупать



RE: Исследование героев - daemon_n - 22.01.2021 03:25

Итак. Снова сутки за героями, но исследовал вот что:

Вопросы, что я себе задал, мол, как поймать "фазу ожидания" существа (Click to View)
А вот и ответ, который пришёл мне в голову - прошу подтвердить:
Есть флаг ожидания у существа
!!BM0:F?i; записать значения флагов первого стека в переменную i
!!VRi:&33554432; проверить на ожидание
!!IF&i>0:M^Стек ждет лучшего момента для действия^;
   
Но он возвращает "истину", пока нет всеобщей фазы ожидания, которая определяется через:
!!UN:C6919200/4/?y10;
!!VRy11:Sy10 +81380;
!!UN:Cy11/1/?y8;

То есть, чтобы узнать, в ожидании отряд или нет, когда настала всеобщая фаза ожидания, надо сделать проверку на саму фазу, сделать проверку на флаг "завершённое действие" и на флаг "защиты". То есть флаг &33554432 проверять надо всегда с нюансамиYes


RE: Исследование героев - Berserker - 22.01.2021 15:23

Quote:!!UN:C6919200/4/?y10;
!!VRy11:Sy10 +81380;
!!UN:Cy11/1/?y8; проверка на фазу ожидание
Спасибо за исследование! В Эре 3.3 можно будет написать так:
!!UN:C(COMBAT_MANAGER)/(UNC_INT)/?(combatMan:y) C(combatMan)/(STRUCT_COMBATMAN_IS_WAITING_PHASE)/(UNC_UINT8)/?(isWaitingPhase:y);


RE: Ваши вопросы по ERM-скриптам - RoseKavalier - 12.02.2021 22:39

(10.02.2021 19:34)XEPOMAHT Wrote:  Теперь знаю что такое SPLICE_, спасибо что объяснили.

Show, don't tell)

LoHook - register access (HookContext)
Image: kkmLLpM.png

Hihook - arguments access, no register access
Image: xzDUJrR.png

Image: 8gbMkaB.png

Image: ZqmbkSe.png

Image: y2isiLk.png


RE: Вопросы по моддингу - Raistlin - 13.02.2021 18:40

Друзья, подскажите пожалуйста, где можно узнать в каком "статусе" находятся стены? Изначально у них статус 2 (возможно, кстати, не у всех), если наполовину поломаны - 1, если можно пройти - 0.
Неактуально, я все нашел сам. Оставлю информацию здесь, чтобы другие могли найти тоже.

Смещения в менеджере битвы:
Code:
INT32 fortWallsHp[18]; // +13F60 (hit points of town walls)
INT32 fortWallsAlive[18];// +13FA8



RE: Вопросы по моддингу - Raistlin - 21.02.2021 01:32

Нашел я в исходниках вога вот такой вот интересный список патчей, как думаете, имеет смысл попытаться на его основе добавить героев?
Code:
{0x40247D+1,DS0(0x5534),2},{0x40247D+3,DS0(HMTable),4},{0x40315B+1,DS0(0x553C),2​},{0x40315B+3,DS0(HMTable),4},
  {0x4035DF+1,DS0(0x551C),2},{0x4035DF+3,DS0(HMTable),4},{0x40625B+1,DS0(0x45​0C),2},{0x40625B+3,DS0(HMTable),4},
  {0x406284+1,DS0(0x450C),2},{0x406284+3,DS0(HMTable),4},{0x4062A6+1,DS0(0x45​0C),2},{0x4062A6+3,DS0(HMTable),4},
  {0x4062BB+1,DS0(0x450C),2},{0x4062BB+3,DS0(HMTable),4},{0x407B19+1,DS0(0x45​34),2},{0x407B19+3,DS0(HMTable),4},
  {0x407FFA+1,DS0(0x4504),2},{0x407FFA+3,DS0(HMTable),4},{0x4080EC+1,DS0(0x4D​0C),2},{0x4080EC+3,DS0(HMTable),4},
  {0x408BFA+1,DS0(0x453C),2},{0x408BFA+3,DS0(HMTable),4},{0x408E2B+1,DS0(0x45​3C),2},{0x408E2B+3,DS0(HMTable),4},
  {0x408EA2+1,DS0(0x4504),2},{0x408EA2+3,DS0(HMTable),4},{0x409097+1,DS0(0x55​0C),2},{0x409097+3,DS0(HMTable),4},
  {0x409261+1,DS0(0x4504),2},{0x409261+3,DS0(HMTable),4},{0x409A8A+1,DS0(0x45​04),2},{0x409A8A+3,DS0(HMTable),4},
  {0x409B7C+1,DS0(0x4504),2},{0x409B7C+3,DS0(HMTable),4},{0x40A7F4+1,DS0(0x45​1C),2},{0x40A7F4+3,DS0(HMTable),4},
  {0x40A9C9+1,DS0(0x4504),2},{0x40A9C9+3,DS0(HMTable),4},{0x40AF7C+1,DS0(0x4D​0C),2},{0x40AF7C+3,DS0(HMTable),4},
  {0x40AFF5+1,DS0(0x4D0C),2},{0x40AFF5+3,DS0(HMTable),4},{0x40B126+1,DS0(0x55​34),2},{0x40B126+3,DS0(HMTable),4},
  {0x40BBD4+1,DS0(0x4534),2},{0x40BBD4+3,DS0(HMTable),4},{0x40DF86+1,DS0(0x45​04),2},{0x40DF86+3,DS0(HMTable),4},
  {0x40E0F4+1,DS0(0x553C),2},{0x40E0F4+3,DS0(HMTable),4},{0x40E4AD+1,DS0(0x45​04),2},{0x40E4AD+3,DS0(HMTable),4},
  {0x40E583+1,DS0(0x4514),2},{0x40E583+3,DS0(HMTable),4},{0x40E607+1,DS0(0x4D​3C),2},{0x40E607+3,DS0(HMTable),4},
  {0x40E9A4+1,DS0(0x5504),2},{0x40E9A4+3,DS0(HMTable),4},{0x40EC31+1,DS0(0x45​3C),2},{0x40EC31+3,DS0(HMTable),4},
  {0x40F10B+1,DS0(0x4D0C),2},{0x40F10B+3,DS0(HMTable),4},{0x40FCA8+1,DS0(0x4D​0C),2},{0x40FCA8+3,DS0(HMTable),4},
  {0x40FDBA+1,DS0(0x4D34),2},{0x40FDBA+3,DS0(HMTable),4},{0x41024A+1,DS0(0x4D​34),2},{0x41024A+3,DS0(HMTable),4},
  {0x412CE0+1,DS0(0x4504),2},{0x412CE0+3,DS0(HMTable),4},{0x413784+1,DS0(0x45​14),2},{0x413784+3,DS0(HMTable),4},
  {0x414555+1,DS0(0x4534),2},{0x414555+3,DS0(HMTable),4},{0x41652D+1,DS0(0x45​34),2},{0x41652D+3,DS0(HMTable),4},
  {0x4165BA+1,DS0(0x551C),2},{0x4165BA+3,DS0(HMTable),4},{0x4167DF+1,DS0(0x55​1C),2},{0x4167DF+3,DS0(HMTable),4},
  {0x4168D0+1,DS0(0x4D04),2},{0x4168D0+3,DS0(HMTable),4},{0x416FAB+1,DS0(0x55​1C),2},{0x416FAB+3,DS0(HMTable),4},
  {0x41711D+1,DS0(0x4D34),2},{0x41711D+3,DS0(HMTable),4},{0x41763E+1,DS0(0x4D​3C),2},{0x41763E+3,DS0(HMTable),4},
  {0x417B74+1,DS0(0x4D3C),2},{0x417B74+3,DS0(HMTable),4},{0x418DE1+1,DS0(0x45​1C),2},{0x418DE1+3,DS0(HMTable),4},
  {0x418E4C+1,DS0(0x4D04),2},{0x418E4C+3,DS0(HMTable),4},{0x419182+1,DS0(0x55​04),2},{0x419182+3,DS0(HMTable),4},
  {0x4192D4+1,DS0(0x4D04),2},{0x4192D4+3,DS0(HMTable),4},{0x41943D+1,DS0(0x4D​04),2},{0x41943D+3,DS0(HMTable),4},
  {0x4199F5+1,DS0(0x450C),2},{0x4199F5+3,DS0(HMTable),4},{0x41C4EE+1,DS0(0x55​34),2},{0x41C4EE+3,DS0(HMTable),4},
  {0x41C63C+1,DS0(0x4D34),2},{0x41C63C+3,DS0(HMTable),4},{0x41C6B2+1,DS0(0x55​34),2},{0x41C6B2+3,DS0(HMTable),4},
  {0x41C7A4+1,DS0(0x4D34),2},{0x41C7A4+3,DS0(HMTable),4},{0x41C862+1,DS0(0x55​34),2},{0x41C862+3,DS0(HMTable),4},
  {0x41C943+1,DS0(0x4534),2},{0x41C943+3,DS0(HMTable),4},{0x41CA56+1,DS0(0x45​1C),2},{0x41CA56+3,DS0(HMTable),4},
  {0x41D034+1,DS0(0x4534),2},{0x41D034+3,DS0(HMTable),4},{0x41D259+1,DS0(0x55​34),2},{0x41D259+3,DS0(HMTable),4},
  {0x41D544+1,DS0(0x5534),2},{0x41D544+3,DS0(HMTable),4},{0x428175+1,DS0(0x4D​34),2},{0x428175+3,DS0(HMTable),4},
  {0x429807+1,DS0(0x5504),2},{0x429807+3,DS0(HMTable),4},{0x42986C+1,DS0(0x55​04),2},{0x42986C+3,DS0(HMTable),4},
  {0x42B13F+1,DS0(0x4504),2},{0x42B13F+3,DS0(HMTable),4},{0x42BB00+1,DS0(0x45​1C),2},{0x42BB00+3,DS0(HMTable),4},
  {0x42DEE8+1,DS0(0x4534),2},{0x42DEE8+3,DS0(HMTable),4},{0x42EFB6+1,DS0(0x45​04),2},{0x42EFB6+3,DS0(HMTable),4},
  {0x42F6F7+1,DS0(0x4534),2},{0x42F6F7+3,DS0(HMTable),4},{0x43145A+1,DS0(0x45​04),2},{0x43145A+3,DS0(HMTable),4},
  {0x4315CA+1,DS0(0x5504),2},{0x4315CA+3,DS0(HMTable),4},{0x431633+1,DS0(0x55​0C),2},{0x431633+3,DS0(HMTable),4},
  {0x4316EA+1,DS0(0x450C),2},{0x4316EA+3,DS0(HMTable),4},{0x4317EB+1,DS0(0x45​04),2},{0x4317EB+3,DS0(HMTable),4},
  {0x431EE9+1,DS0(0x4D04),2},{0x431EE9+3,DS0(HMTable),4},{0x432048+1,DS0(0x55​0C),2},{0x432048+3,DS0(HMTable),4},
  {0x4331A3+1,DS0(0x4504),2},{0x4331A3+3,DS0(HMTable),4},{0x433B02+1,DS0(0x4D​0C),2},{0x433B02+3,DS0(HMTable),4},
  {0x4518D1+1,DS0(0x451C),2},{0x4518D1+3,DS0(HMTable),4},{0x453193+1,DS0(0x4D​0C),2},{0x453193+3,DS0(HMTable),4},
  {0x4534D6+1,DS0(0x450C),2},{0x4534D6+3,DS0(HMTable),4},{0x453552+1,DS0(0x4D​04),2},{0x453552+3,DS0(HMTable),4},
  {0x47F11D+1,DS0(0x4D0C),2},{0x47F11D+3,DS0(HMTable),4},{0x47F1DB+1,DS0(0x45​3C),2},{0x47F1DB+3,DS0(HMTable),4},
  {0x47F4B9+1,DS0(0x451C),2},{0x47F4B9+3,DS0(HMTable),4},{0x47F69A+1,DS0(0x55​3C),2},{0x47F69A+3,DS0(HMTable),4},
  {0x47FB87+1,DS0(0x4D0C),2},{0x47FB87+3,DS0(HMTable),4},{0x47FF58+1,DS0(0x45​34),2},{0x47FF58+3,DS0(HMTable),4},
  {0x4801BA+1,DS0(0x4D0C),2},{0x4801BA+3,DS0(HMTable),4},{0x4803CA+1,DS0(0x4D​0C),2},{0x4803CA+3,DS0(HMTable),4},
  {0x480644+1,DS0(0x4D0C),2},{0x480644+3,DS0(HMTable),4},{0x4806D2+1,DS0(0x45​04),2},{0x4806D2+3,DS0(HMTable),4},
  {0x480B0A+1,DS0(0x4D0C),2},{0x480B0A+3,DS0(HMTable),4},{0x480FFA+1,DS0(0x45​0C),2},{0x480FFA+3,DS0(HMTable),4},
  {0x48124A+1,DS0(0x4D34),2},{0x48124A+3,DS0(HMTable),4},{0x4812E5+1,DS0(0x55​0C),2},{0x4812E5+3,DS0(HMTable),4},
  {0x4814CC+1,DS0(0x4D04),2},{0x4814CC+3,DS0(HMTable),4},{0x4817CA+1,DS0(0x55​04),2},{0x4817CA+3,DS0(HMTable),4},
  {0x48181C+1,DS0(0x453C),2},{0x48181C+3,DS0(HMTable),4},{0x48190E+1,DS0(0x4D​0C),2},{0x48190E+3,DS0(HMTable),4},
  {0x48197E+1,DS0(0x4504),2},{0x48197E+3,DS0(HMTable),4},{0x481AAC+1,DS0(0x55​1C),2},{0x481AAC+3,DS0(HMTable),4},
  {0x483C46+1,DS0(0x4D0C),2},{0x483C46+3,DS0(HMTable),4},{0x483C89+1,DS0(0x55​04),2},{0x483C89+3,DS0(HMTable),4},
  {0x483CCE+1,DS0(0x5534),2},{0x483CCE+3,DS0(HMTable),4},{0x483F8B+1,DS0(0x45​04),2},{0x483F8B+3,DS0(HMTable),4},
  {0x4860E8+1,DS0(0x451C),2},{0x4860E8+3,DS0(HMTable),4},{0x486BB0+1,DS0(0x55​34),2},{0x486BB0+3,DS0(HMTable),4},
  {0x487652+1,DS0(0x550C),2},{0x487652+3,DS0(HMTable),4},{0x4896AC+1,DS0(0x45​04),2},{0x4896AC+3,DS0(HMTable),4},
  {0x48971B+1,DS0(0x5504),2},{0x48971B+3,DS0(HMTable),4},{0x49A2EA+1,DS0(0x4D​04),2},{0x49A2EA+3,DS0(HMTable),4},
  {0x49B0DD+1,DS0(0x4D04),2},{0x49B0DD+3,DS0(HMTable),4},{0x49D446+1,DS0(0x4D​04),2},{0x49D446+3,DS0(HMTable),4},
  {0x49D4AC+1,DS0(0x5504),2},{0x49D4AC+3,DS0(HMTable),4},{0x49E03F+1,DS0(0x55​04),2},{0x49E03F+3,DS0(HMTable),4},
  {0x49E088+1,DS0(0x550C),2},{0x49E088+3,DS0(HMTable),4},{0x4A249F+1,DS0(0x4D​34),2},{0x4A249F+3,DS0(HMTable),4},
  {0x4A3CAC+1,DS0(0x5534),2},{0x4A3CAC+3,DS0(HMTable),4},{0x4AA735+1,DS0(0x4D​3C),2},{0x4AA735+3,DS0(HMTable),4},
  {0x4AAD33+1,DS0(0x4D14),2},{0x4AAD33+3,DS0(HMTable),4},{0x4AAE0C+1,DS0(0x55​1C),2},{0x4AAE0C+3,DS0(HMTable),4},
  {0x4AAF6D+1,DS0(0x551C),2},{0x4AAF6D+3,DS0(HMTable),4},{0x4AAFFB+1,DS0(0x55​1C),2},{0x4AAFFB+3,DS0(HMTable),4},
  {0x4B262B+1,DS0(0x4504),2},{0x4B262B+3,DS0(HMTable),4},{0x4B9CCB+1,DS0(0x45​3C),2},{0x4B9CCB+3,DS0(HMTable),4},
  {0x4BA767+1,DS0(0x5534),2},{0x4BA767+3,DS0(HMTable),4},{0x4BA7BB+1,DS0(0x4D​34),2},{0x4BA7BB+3,DS0(HMTable),4},
  {0x4BA8C6+1,DS0(0x4514),2},{0x4BA8C6+3,DS0(HMTable),4},{0x4BA939+1,DS0(0x55​14),2},{0x4BA939+3,DS0(HMTable),4},
  {0x4BA99F+1,DS0(0x450C),2},{0x4BA99F+3,DS0(HMTable),4},{0x4BAA05+1,DS0(0x4D​0C),2},{0x4BAA05+3,DS0(HMTable),4},
  {0x4BC922+1,DS0(0x451C),2},{0x4BC922+3,DS0(HMTable),4},{0x4BFDA7+1,DS0(0x45​04),2},{0x4BFDA7+3,DS0(HMTable),4},
  {0x4BFF35+1,DS0(0x4D0C),2},{0x4BFF35+3,DS0(HMTable),4},{0x4C0044+1,DS0(0x45​34),2},{0x4C0044+3,DS0(HMTable),4},
  {0x4C676F+1,DS0(0x550C),2},{0x4C676F+3,DS0(HMTable),4},{0x4C709C+1,DS0(0x4D​3C),2},{0x4C709C+3,DS0(HMTable),4},
  {0x4C70EF+1,DS0(0x5534),2},{0x4C70EF+3,DS0(HMTable),4},{0x4C7160+1,DS0(0x45​34),2},{0x4C7160+3,DS0(HMTable),4},
  {0x4C76D6+1,DS0(0x550C),2},{0x4C76D6+3,DS0(HMTable),4},{0x4C7767+1,DS0(0x4D​0C),2},{0x4C7767+3,DS0(HMTable),4},
  {0x4C8036+1,DS0(0x4D34),2},{0x4C8036+3,DS0(HMTable),4},{0x4C809E+1,DS0(0x55​34),2},{0x4C809E+3,DS0(HMTable),4},
  {0x4C8178+1,DS0(0x4504),2},{0x4C8178+3,DS0(HMTable),4},{0x4C81C2+1,DS0(0x45​04),2},{0x4C81C2+3,DS0(HMTable),4},
  {0x4C820A+1,DS0(0x4504),2},{0x4C820A+3,DS0(HMTable),4},{0x4C8247+1,DS0(0x45​04),2},{0x4C8247+3,DS0(HMTable),4},
  {0x4C82A5+1,DS0(0x553C),2},{0x4C82A5+3,DS0(HMTable),4},{0x4C839F+1,DS0(0x4D​04),2},{0x4C839F+3,DS0(HMTable),4},
  {0x4C8830+1,DS0(0x551C),2},{0x4C8830+3,DS0(HMTable),4},{0x4C9EA5+1,DS0(0x55​0C),2},{0x4C9EA5+3,DS0(HMTable),4},
  {0x4CAB9E+1,DS0(0x4D34),2},{0x4CAB9E+3,DS0(HMTable),4},{0x4CAC54+1,DS0(0x45​0C),2},{0x4CAC54+3,DS0(HMTable),4},
  {0x4DE57C+1,DS0(0x4504),2},{0x4DE57C+3,DS0(HMTable),4},{0x4DE61A+1,DS0(0x55​0C),2},{0x4DE61A+3,DS0(HMTable),4},
  {0x4E18C5+1,DS0(0x4504),2},{0x4E18C5+3,DS0(HMTable),4},{0x4E1AD7+1,DS0(0x45​14),2},{0x4E1AD7+3,DS0(HMTable),4},
  {0x4E7715+1,DS0(0x4D0C),2},{0x4E7715+3,DS0(HMTable),4},{0x4E7FB5+1,DS0(0x4D​14),2},{0x4E7FB5+3,DS0(HMTable),4},
  {0x4E86D8+1,DS0(0x550C),2},{0x4E86D8+3,DS0(HMTable),4},{0x4E87BC+1,DS0(0x4D​0C),2},{0x4E87BC+3,DS0(HMTable),4},
  {0x4E87D6+1,DS0(0x553C),2},{0x4E87D6+3,DS0(HMTable),4},{0x4E8ABF+1,DS0(0x4D​0C),2},{0x4E8ABF+3,DS0(HMTable),4},
  {0x4E8AD9+1,DS0(0x553C),2},{0x4E8AD9+3,DS0(HMTable),4},{0x4F1A4B+1,DS0(0x45​0C),2},{0x4F1A4B+3,DS0(HMTable),4},
  {0x4F26A6+1,DS0(0x5504),2},{0x4F26A6+3,DS0(HMTable),4},{0x4F313A+1,DS0(0x55​04),2},{0x4F313A+3,DS0(HMTable),4},
  {0x4F318F+1,DS0(0x4D0C),2},{0x4F318F+3,DS0(HMTable),4},{0x4F4A11+1,DS0(0x4D​1C),2},{0x4F4A11+3,DS0(HMTable),4},
  {0x4F53B3+1,DS0(0x4D34),2},{0x4F53B3+3,DS0(HMTable),4},{0x4F540C+1,DS0(0x55​34),2},{0x4F540C+3,DS0(HMTable),4},
  {0x4F5481+1,DS0(0x5534),2},{0x4F5481+3,DS0(HMTable),4},{0x4FD243+1,DS0(0x45​04),2},{0x4FD243+3,DS0(HMTable),4},
  {0x4FD2A5+1,DS0(0x4504),2},{0x4FD2A5+3,DS0(HMTable),4},{0x4FD2F3+1,DS0(0x45​04),2},{0x4FD2F3+3,DS0(HMTable),4},
  {0x4FD37E+1,DS0(0x4504),2},{0x4FD37E+3,DS0(HMTable),4},{0x4FD4A1+1,DS0(0x45​04),2},{0x4FD4A1+3,DS0(HMTable),4},
  {0x50609B+1,DS0(0x4504),2},{0x50609B+3,DS0(HMTable),4},{0x5060EC+1,DS0(0x4D​1C),2},{0x5060EC+3,DS0(HMTable),4},
  {0x513AC9+1,DS0(0x4504),2},{0x513AC9+3,DS0(HMTable),4},{0x513CE7+1,DS0(0x45​04),2},{0x513CE7+3,DS0(HMTable),4},
  {0x51C90D+1,DS0(0x4D34),2},{0x51C90D+3,DS0(HMTable),4},{0x51CBB3+1,DS0(0x45​34),2},{0x51CBB3+3,DS0(HMTable),4},
  {0x51D5B6+1,DS0(0x4514),2},{0x51D5B6+3,DS0(HMTable),4},{0x51F3C0+1,DS0(0x55​34),2},{0x51F3C0+3,DS0(HMTable),4},
  {0x51F687+1,DS0(0x450C),2},{0x51F687+3,DS0(HMTable),4},{0x51FA10+1,DS0(0x45​0C),2},{0x51FA10+3,DS0(HMTable),4},
  {0x51FAAD+1,DS0(0x4504),2},{0x51FAAD+3,DS0(HMTable),4},{0x51FB29+1,DS0(0x55​04),2},{0x51FB29+3,DS0(HMTable),4},
  {0x52137B+1,DS0(0x5534),2},{0x52137B+3,DS0(HMTable),4},{0x52163E+1,DS0(0x45​0C),2},{0x52163E+3,DS0(HMTable),4},
  {0x521741+1,DS0(0x5534),2},{0x521741+3,DS0(HMTable),4},{0x5217A9+1,DS0(0x45​34),2},{0x5217A9+3,DS0(HMTable),4},
  {0x52189C+1,DS0(0x4504),2},{0x52189C+3,DS0(HMTable),4},{0x5218D4+1,DS0(0x45​04),2},{0x5218D4+3,DS0(HMTable),4},
  {0x52210B+1,DS0(0x550C),2},{0x52210B+3,DS0(HMTable),4},{0x5222BD+1,DS0(0x45​0C),2},{0x5222BD+3,DS0(HMTable),4},
  {0x52297F+1,DS0(0x4D04),2},{0x52297F+3,DS0(HMTable),4},{0x522AD7+1,DS0(0x4D​0C),2},{0x522AD7+3,DS0(HMTable),4},
  {0x525741+1,DS0(0x5504),2},{0x525741+3,DS0(HMTable),4},{0x5257FB+1,DS0(0x45​34),2},{0x5257FB+3,DS0(HMTable),4},
  {0x525950+1,DS0(0x4D04),2},{0x525950+3,DS0(HMTable),4},{0x525E87+1,DS0(0x4D​04),2},{0x525E87+3,DS0(HMTable),4},
  {0x526526+1,DS0(0x5514),2},{0x526526+3,DS0(HMTable),4},{0x5267F5+1,DS0(0x55​04),2},{0x5267F5+3,DS0(HMTable),4},
  {0x526C00+1,DS0(0x4504),2},{0x526C00+3,DS0(HMTable),4},{0x526F42+1,DS0(0x45​04),2},{0x526F42+3,DS0(HMTable),4},
  {0x526FC0+1,DS0(0x4534),2},{0x526FC0+3,DS0(HMTable),4},{0x5270E7+1,DS0(0x45​34),2},{0x5270E7+3,DS0(HMTable),4},
  {0x527E84+1,DS0(0x450C),2},{0x527E84+3,DS0(HMTable),4},{0x52A1C9+1,DS0(0x45​34),2},{0x52A1C9+3,DS0(HMTable),4},
  {0x52A8AD+1,DS0(0x4D04),2},{0x52A8AD+3,DS0(HMTable),4},{0x52B1A4+1,DS0(0x55​14),2},{0x52B1A4+3,DS0(HMTable),4},
  {0x52B36F+1,DS0(0x551C),2},{0x52B36F+3,DS0(HMTable),4},{0x52B48F+1,DS0(0x4D​1C),2},{0x52B48F+3,DS0(HMTable),4},
  {0x52B5D7+1,DS0(0x451C),2},{0x52B5D7+3,DS0(HMTable),4},{0x557096+1,DS0(0x55​04),2},{0x557096+3,DS0(HMTable),4},
  {0x5683A6+1,DS0(0x4D1C),2},{0x5683A6+3,DS0(HMTable),4},{0x569DB0+1,DS0(0x45​34),2},{0x569DB0+3,DS0(HMTable),4},
  {0x56A896+1,DS0(0x450C),2},{0x56A896+3,DS0(HMTable),4},{0x56E478+1,DS0(0x45​04),2},{0x56E478+3,DS0(HMTable),4},
  {0x56E579+1,DS0(0x453C),2},{0x56E579+3,DS0(HMTable),4},{0x56E9A4+1,DS0(0x45​3C),2},{0x56E9A4+3,DS0(HMTable),4},
  {0x5721A8+1,DS0(0x4504),2},{0x5721A8+3,DS0(HMTable),4},{0x5722A9+1,DS0(0x45​3C),2},{0x5722A9+3,DS0(HMTable),4},
  {0x572471+1,DS0(0x4514),2},{0x572471+3,DS0(HMTable),4},{0x582654+1,DS0(0x55​1C),2},{0x582654+3,DS0(HMTable),4},
  {0x582866+1,DS0(0x451C),2},{0x582866+3,DS0(HMTable),4},{0x5AEEFB+1,DS0(0x55​0C),2},{0x5AEEFB+3,DS0(HMTable),4},
  {0x5AEF23+1,DS0(0x550C),2},{0x5AEF23+3,DS0(HMTable),4},{0x5BE40F+1,DS0(0x45​04),2},{0x5BE40F+3,DS0(HMTable),4},
  {0x5BE4A8+1,DS0(0x550C),2},{0x5BE4A8+3,DS0(HMTable),4},{0x5BE689+1,DS0(0x45​04),2},{0x5BE689+3,DS0(HMTable),4},
  {0x5BE7BE+1,DS0(0x4D0C),2},{0x5BE7BE+3,DS0(HMTable),4},{0x5BE7EF+1,DS0(0x55​0C),2},{0x5BE7EF+3,DS0(HMTable),4},
  {0x5BE87B+1,DS0(0x450C),2},{0x5BE87B+3,DS0(HMTable),4},{0x5BE89B+1,DS0(0x45​3C),2},{0x5BE89B+3,DS0(HMTable),4},
  {0x5BE9A6+1,DS0(0x4D0C),2},{0x5BE9A6+3,DS0(HMTable),4},{0x5BF5A7+1,DS0(0x45​04),2},{0x5BF5A7+3,DS0(HMTable),4},
  {0x5BF5EE+1,DS0(0x5504),2},{0x5BF5EE+3,DS0(HMTable),4},{0x5BFD42+1,DS0(0x55​04),2},{0x5BFD42+3,DS0(HMTable),4},
  {0x5BFD69+1,DS0(0x4D0C),2},{0x5BFD69+3,DS0(HMTable),4},{0x5BFE0F+1,DS0(0x45​0C),2},{0x5BFE0F+3,DS0(HMTable),4},
  {0x5C173D+1,DS0(0x4D0C),2},{0x5C173D+3,DS0(HMTable),4},{0x5C17D2+1,DS0(0x45​14),2},{0x5C17D2+3,DS0(HMTable),4},
  {0x5C188B+1,DS0(0x4504),2},{0x5C188B+3,DS0(HMTable),4},{0x5C69E5+1,DS0(0x55​04),2},{0x5C69E5+3,DS0(HMTable),4},
  {0x5C6A12+1,DS0(0x5504),2},{0x5C6A12+3,DS0(HMTable),4},{0x5C7253+1,DS0(0x4D​3C),2},{0x5C7253+3,DS0(HMTable),4},
  {0x5C7291+1,DS0(0x5514),2},{0x5C7291+3,DS0(HMTable),4},{0x5C7373+1,DS0(0x55​3C),2},{0x5C7373+3,DS0(HMTable),4},
  {0x5C76A1+1,DS0(0x4504),2},{0x5C76A1+3,DS0(HMTable),4},{0x5C76C1+1,DS0(0x45​04),2},{0x5C76C1+3,DS0(HMTable),4},
  {0x5C7E0A+1,DS0(0x4D04),2},{0x5C7E0A+3,DS0(HMTable),4},{0x5C7EED+1,DS0(0x45​04),2},{0x5C7EED+3,DS0(HMTable),4},
  {0x5C9BED+1,DS0(0x4504),2},{0x5C9BED+3,DS0(HMTable),4},{0x5CE99D+1,DS0(0x45​3C),2},{0x5CE99D+3,DS0(HMTable),4},
  {0x5CE9C1+1,DS0(0x553C),2},{0x5CE9C1+3,DS0(HMTable),4},{0x5D1D62+1,DS0(0x45​34),2},{0x5D1D62+3,DS0(HMTable),4},
  {0x5D2238+1,DS0(0x550C),2},{0x5D2238+3,DS0(HMTable),4},{0x5D31E6+1,DS0(0x45​04),2},{0x5D31E6+3,DS0(HMTable),4},
  {0x5D3209+1,DS0(0x5504),2},{0x5D3209+3,DS0(HMTable),4},{0x5D3238+1,DS0(0x45​04),2},{0x5D3238+3,DS0(HMTable),4},
  {0x5D33DD+1,DS0(0x4504),2},{0x5D33DD+3,DS0(HMTable),4},{0x5D34EF+1,DS0(0x45​34),2},{0x5D34EF+3,DS0(HMTable),4},
  {0x5D3513+1,DS0(0x5534),2},{0x5D3513+3,DS0(HMTable),4},{0x5D4499+1,DS0(0x4D​04),2},{0x5D4499+3,DS0(HMTable),4},
  {0x5D4516+1,DS0(0x4504),2},{0x5D4516+3,DS0(HMTable),4},{0x5D7DA9+1,DS0(0x4D​04),2},{0x5D7DA9+3,DS0(HMTable),4},
  {0x5D7E84+1,DS0(0x5534),2},{0x5D7E84+3,DS0(HMTable),4},{0x5D80C3+1,DS0(0x45​0C),2},{0x5D80C3+3,DS0(HMTable),4},
  {0x5D843F+1,DS0(0x550C),2},{0x5D843F+3,DS0(HMTable),4},{0x5D8480+1,DS0(0x55​04),2},{0x5D8480+3,DS0(HMTable),4},
  {0x5D84F3+1,DS0(0x4504),2},{0x5D84F3+3,DS0(HMTable),4},{0x5D853E+1,DS0(0x55​0C),2},{0x5D853E+3,DS0(HMTable),4},
  {0x5D8773+1,DS0(0x553C),2},{0x5D8773+3,DS0(HMTable),4},{0x5D8862+1,DS0(0x45​04),2},{0x5D8862+3,DS0(HMTable),4},
  {0x5D89D6+1,DS0(0x4D0C),2},{0x5D89D6+3,DS0(HMTable),4},{0x5D8AAB+1,DS0(0x55​04),2},{0x5D8AAB+3,DS0(HMTable),4},
  {0x5DE4AB+1,DS0(0x553C),2},{0x5DE4AB+3,DS0(HMTable),4},{0x5DE50D+1,DS0(0x45​04),2},{0x5DE50D+3,DS0(HMTable),4},
  {0x5DEF1D+1,DS0(0x4504),2},{0x5DEF1D+3,DS0(HMTable),4},{0x5DF3DF+1,DS0(0x45​34),2},{0x5DF3DF+3,DS0(HMTable),4},
  {0x5DF460+1,DS0(0x550C),2},{0x5DF460+3,DS0(HMTable),4},{0x5EA231+1,DS0(0x45​0C),2},{0x5EA231+3,DS0(HMTable),4},
  {0x5EA3AE+1,DS0(0x450C),2},{0x5EA3AE+3,DS0(HMTable),4},{0x5EA4A8+1,DS0(0x4D​14),2},{0x5EA4A8+3,DS0(HMTable),4},
  {0x5F1B9D+1,DS0(0x4D3C),2},{0x5F1B9D+3,DS0(HMTable),4},{0x5F1D0B+1,DS0(0x4D​0C),2},{0x5F1D0B+3,DS0(HMTable),4},
  {0x5F1DE1+1,DS0(0x453C),2},{0x5F1DE1+3,DS0(HMTable),4},{0x5F1F68+1,DS0(0x45​04),2},{0x5F1F68+3,DS0(HMTable),4},
  {0x5F7835+1,DS0(0x5504),2},{0x5F7835+3,DS0(HMTable),4},{0x5F78DA+1,DS0(0x55​34),2},{0x5F78DA+3,DS0(HMTable),4},
  {0x5F7CDA+1,DS0(0x5534),2},{0x5F7CDA+3,DS0(HMTable),4},

  {0x40E5FB+2,DS0(0x4D04),2},{0x40E5FB+4,DS0(&HMTable[0].y),4},
  {0x417B7B+2,DS0(0x4D0C),2},{0x417B7B+4,DS0(HMTable),4},
  {0x4199ED+2,DS0(0x4514),2},{0x4199ED+4,DS0(HMTable),4},
  {0x4814D3+1,DS0(0x4D04),2},{0x4814D3+3,DS0(&HMTable[0].RefData1),4},
  {0x483C3E+2,DS0(0x4D04),2},{0x483C3E+4,DS0(&HMTable[0].Owner),4},
//  {0x4B6638+2,DS0(0x45C3),2},{0x4B8638+4,DS0(&HMTable[0].Owner),4},
  {0x4B8AC4+1,DS0(0x3D),1},{0x4B8AC4+2,DS0(&HMTable[0].Owner),4},
  {0x4BB183+1,DS0(0x1D),1},{0x4BB183+2,DS0(&HMTable[0].Spec),4}, //BB183 Spec
  {0x4BB305+1,DS0(0x05),1},{0x4BB305+2,DS0(&HMTable[0].Spec),4}, //BB305 Spec
  {0x4BB49C+1,DS0(0x05),1},{0x4BB49C+2,DS0(&HMTable[0].Spec),4}, //BB49C Spec
  {0x4BD0AB+1,DS0(0x3D),1},{0x4BD0AB+2,DS0(HMTable),4},
  {0x4BE501+1,DS0(0x3D),1},{0x4BE501+2,DS0(HMTable),4},
  {0x4BEF6E+1,DS0(0x05),1},{0x4BEF6E+2,DS0(HMTable),4},
  {0x4BF5A6+2,DS0(0x05),1},{0x4BF5A6+3,DS0(&HMTable[0].y),4},
  {0x4BF860+1,DS0(0x05),1},{0x4BF860+2,DS0(&HMTable[0].y),4},
  {0x4BF946+2,DS0(0x4504),2},{0x4BF946+4,DS0(&HMTable[0].Owner),4},
  {0x4BFB47+1,DS0(0x35),1},{0x4BFB47+2,DS0(HMTable),4},
  {0x4C6D0F+1,DS0(0x4D04),2},{0x4C6D0F+3,DS0(&HMTable[0].RefData1),4},
  {0x4C6D16+1,DS0(0x4D0C),2},{0x4C6D16+3,DS0(&HMTable[0].RefData1),4},
  {0x4C7920+1,DS0(0x3D),1},{0x4C7920+2,DS0(&HMTable[0].Owner),4}, // ?
  {0x4C7D8F+1,DS0(0x05),1},{0x4C7D8F+2,DS0(&HMTable[0].RefData1),4},
  {0x4C7EF7+1,DS0(0x35),1},{0x4C7EF7+2,DS0(&HMTable[0].SpPoints),4},
  {0x4C83D4,DS0(0x90C003),3},
// не надо! {0x4C83DA+1,DS0(0x0D),1},
    {0x4C83DA+2,DS0(HMTable),4},
// не надо! {0x4C83E0,DS0(0xA0),1},
    {0x4C83E0+1,DS0(&HMTable[0].PSkill[3]),4},
// не надо! C8422
    {0x4C8422+3,DS0(&HMTable[0].SpPoints),4},
  {0x4C89DF+1,DS0(0x05),1},{0x4C89DF+2,DS0(&HMTable[0].RefData1),4},
  {0x4C9408+1,DS0(0x1C),1},
  {0x4C9415,DS0(0x90DB03),3},
// не надо! C941D
    {0x4C941D+2,DS0(&HMTable[0].Ct[0]),4},
// не надо! {0x4C94BD+1,DS0(0x0D),1},
    {0x4C94BD+2,DS0(HMTable),4},
// не надо! {0x4C94E3+1,DS0(0x0D),1},
    {0x4C94E3+2,DS0(HMTable),4},
  {0x4CD8E6+2,DS0(0x4504),2},{0x4CD8E6+4,DS0(&HMTable[0].Owner),4},
  {0x4CD9D2+2,DS0(0x4D0C),2},{0x4CD9D2+4,DS0(&HMTable[0].Owner),4},
  {0x4CDE34+1,DS0(0x05),1},{0x4CDE34+2,DS0(HMTable),4},
  {0x4CE4F9+1,DS0(0x15),1},{0x4CE4F9+2,DS0(HMTable),4},
  {0x4DA466+1,DS0(0x5D04),2},{0x4DA466+3,DS0(&HMTable[0].RefData2),4},
  {0x4F4ED8+1,DS0(0x4514),2},{0x4F4ED8+3,DS0(&HMTable[0].Ct[0]),4},
  {0x526FC7+1,DS0(0x4504),2},{0x526FC7+3,DS0(&HMTable[0].Movement),4},
  {0x58D579+1,DS0(0x5504),2},{0x58D579+3,DS0(&HMTable[0].Name[0]),4},
  {0x58D697+1,DS0(0x4504),2},{0x58D697+3,DS0(&HMTable[0].Name[0]),4},
  {0x5BE681+2,DS0(0x4514),2},{0x5BE681+4,DS0(&HMTable[0].Owner),4},
  {0x62C9C3,DS0(0xB8),1},{0x62C9C3+1,DS0(HMTable),4},
  {0x62CB5F,DS0(0xB8),1},{0x62CB5F+1,DS0(HMTable),4},


  {0x4BB1EC+2,DS0(HERNUM),4},{0x4BB252+2,DS0(HERNUM),4},{0x4BB36F+2,DS0(HERNU​M),4},
  {0x4BB500+2,DS0(HERNUM),4},{0x4BD1CB+3,DS0(HERNUM),4},{0x4BE51D+1,DS0(HERNU​M),4},
  {0x4BE597+3,DS0(HERNUM),4},{0x4BEF9A+2,DS0(HERNUM),4},{0x4BF61E+2,DS0(HERNU​M),4},
  {0x4BF8D8+2,DS0(HERNUM),4},{0x4BFBA1+2,DS0(HERNUM),4}, // 4C2CCF 4CAADB инициализация из _THero_
  {0x4C81DE+2,DS0(HERNUM),4},{0x4C8222+2,DS0(HERNUM),4},{0x4C825F+2,DS0(HERNU​M),4},
  {0x4C89E5+1,DS0(HERNUM),4},{0x4CDE53+3,DS0(HERNUM),4},



RE: Вопросы по моддингу - XEPOMAHT - 21.02.2021 19:00

(21.02.2021 01:32)Raistlin Wrote:  Нашел я в исходниках вога вот такой вот интересный список патчей, как думаете, имеет смысл попытаться на его основе добавить героев?

Попытайся. Он под чистый SoD без модов, если что.


RE: Вопросы по моддингу - Raistlin - 21.02.2021 20:24

XEPOMAHT, хорошо )


RE: Вопросы по моддингу - feanor - 21.02.2021 22:36

Насчет героев вообще была умеренно всратая идея: у нас же в игре все равно не может быть больше 8*8 + 2*8 + 48 героев (8 в поле каждой фракции, 48 в гарнизонах замков, 2*8 в тавернах)

Так вот, зачем нам их добавлять актуально, убиваясь о все возможные битмапы (в хоте перенос между кампаниями фиксили чуть ли не до 1.4), допструктуры вога и все такое, если можно сделать пул и менять их динамически?


RE: Вопросы по моддингу - XEPOMAHT - 22.02.2021 00:15

(21.02.2021 22:36)feanor Wrote:  Так вот, зачем нам их добавлять актуально, убиваясь о все возможные битмапы (в хоте перенос между кампаниями фиксили чуть ли не до 1.4), допструктуры вога и все такое, если можно сделать пул и менять их динамически?

Это уже кастыли, затруднительно сказать, какие при этом повылазят глюки. Проще расширением существующих структур (что уже было сделано ещё в WoG 3.59 и портировано на все текущие троешные геройские платформы) и полной адаптацией кривостей воговского кода с воговскими скриптами (что давно пора сделать, а не заниматься тем, что уже кем-то сделано).


RE: Вопросы по моддингу - Дьякон - 26.06.2021 14:29

Сюда продублирую. Структуры сноса строений при постройках:
0x839AA8 - имеет два dworda на каждое строение. Адрес для ЭРЫ.


RE: Ваши вопросы по ERM-скриптам - Berserker - 09.07.2021 01:11

Щиты снайперов и иже с ним прочие wog-способности

Code:
static void _SetUpBeforeBattle2(void)
{
  #include "templ.h"
  int       i,j,tp;
  Byte     *bm=(Byte *)SUBB_BatMan;
  Byte     *mon;
//  _Hero_   *hp1=(_Hero_ *)*(Dword *)&bm[0x53CC];
//  _Hero_   *hp2=(_Hero_ *)*(Dword *)&bm[0x53D0];
  NMT_First=0; // Сброс для Санта Гремлина и других, кто иниц. после тактики
///////////  PlaceNPCAtBattleStart(bm);
//  CrExpBon::PrepareBFExpStructure(bm);
//  if(bm[0x13D68]==0){  // NO tactic phase
    *(int *)&((Byte *)bm)[0x13D6C]=0; // clear the turn index
//  }
  for(i=0;i<(21*2);i++){
    mon=&bm[0x54CC+0x548*i];
    *(int *)&mon[0x288]=0; // not being hypnotized
    *(int *)&mon[0xF4] =i/21; // initial side
    // 3.58 Tower skip
    if(i==20) continue; // 3.58
    if(i==41) continue; // 3.58
    mon=&bm[0x54CC+0x548*i];
//    AdjustStackParams(/*bm,*/mon,0); // 3.58 Creature experience
    CrExpBon::Apply(mon);
    tp=*(int *)&mon[0x34];
    if((tp>=174)&&(tp<=191)){
       AddMagic2NPC(mon,bm);
    }
    if(tp==152){ // титан
      SetMonMagic(mon,28,1000,3,0); // воздушный щит
    }
    if(tp==156){ // чудище
      *(int *)&mon[0x454]=2;
    }
    if(tp==158){ // феникс
      SetMonMagic(mon,0x1D,1000,1,0); // огненный щит
      SetMonMagic(mon,55,1000,3,0); // палач
    }
    if(tp==195){ // Hell Steed (fire horse)
      SetMonMagic(mon,0x1D,1000,1,0); // огненный щит
    }
    if((tp>=GODMONTSTRT)&&(tp<(GODMONTSTRT+GODMONTNUM))){ // бог
      *(int *)&mon[0x454]=0; // не отвечает на атаку
    }
    if(tp==164){ // огненный голем
      SetMonMagic(mon,31,1000,3,0); // защита от огня
    }
    if(tp==165){ // огненный голем
      SetMonMagic(mon,33,1000,3,0); // защита от земли
    }
    if(tp==166){ // огненный голем
      SetMonMagic(mon,30,1000,3,0); // защита от воздуха
    }
    if(tp==167){ // огненный голем
      SetMonMagic(mon,32,1000,3,0); // защита от воды
    }
    if(tp==169){ // белый монах
      SetMonMagic(mon,36,1000,3,0); // волшебное зеркало
    }
    if(tp==170){ // белый шутер
      SetMonMagic(mon,28,1000,3,0); // воздушный щит
    }
    if(tp==171){ // красный шутер
      SetMonMagic(mon,0x1D,1000,1,0); // огненный щит
    }
    if(tp==192){ // Centaur-Elf
      SetMonMagic(mon,49,1000,3,0); // Mirth
    }
    for(j=0;j<100;j++){
      if(MonsterOfWeek[j]==-1) break;
      if(tp==MonsterOfWeek[j]){ // монстр недели
        SetMonMagic(mon,48,1000,3,0); // воздушный щит
      }
    }
    CrExpBon::ApplySpell(mon,bm);
//    CrExpBon::ApplyMassSpell(mon);
    if(tp==0x95){        // башня
      _CastleSetup_ *cp;
      cp=(_CastleSetup_ *)*(Dword *)&bm[0x53C8];
      if(IsCastleSetup(cp)==1){ // замок
        SetTowerBunus(cp,mon);
/*
        int side=*(int *)&mon[0xF4]; // сторона
        _Hero_   *htmp;
        _Hero_   *hpo=(_Hero_ *)*(Dword *)&bm[0x53CC];
        _Hero_   *hpe=(_Hero_ *)*(Dword *)&bm[0x53D0];
        if(side!=0){ htmp=hpo; hpo=hpe; hpe=htmp; }
        if((hpo!=0)&&(HeroHasArt(hpo,0x8E))){ // свой
//          *(int *)&mon[0x4C]=99;
        }
*/
      }
    }

Code:
static void  _SetUpNewRound(void)
{
  #include "templ.h"
  int j;
  Byte *sgp,*bmp=(Byte *)SUNR_BatMan;
  Byte *mon=(Byte *)SUNR_Mon;
  int   tp=*(int *)&mon[0x34];
//  Byte     *bm=(Byte *)SUNR_BatMan;
//  _Hero_   *hp1=(_Hero_ *)*(Dword *)&bm[0x53CC];
//  _Hero_   *hp2=(_Hero_ *)*(Dword *)&bm[0x53D0];
  if((tp>=174)&&(tp<=191)){
     AddMagic2NPC(mon,bmp);
  }
  CrExpBon::Apply2(mon);
  if(tp==152){ // титан
    SetMonMagic(mon,28,1000,3,0); // воздушный щит
  }
  if(tp==156){ // чудище
    *(int *)&mon[0x454]=2; // отвечает дважды
  }
  if(tp==158){ // феникс
    SetMonMagic(mon,0x1D,1000,1,0); // огненный щит
    SetMonMagic(mon,55,1000,3,0); // палач
  }
  if(tp==195){ // Hell Steed (fire horse)
    SetMonMagic(mon,0x1D,1000,1,0); // огненный щит
  }
  for(j=0;j<100;j++){
    if(MonsterOfWeek[j]==-1) break;
    if(tp==MonsterOfWeek[j]){ // монстр недели
      SetMonMagic(mon,48,1000,3,0); // воздушный щит
    }
  }
  if((tp>=GODMONTSTRT)&&(tp<(GODMONTSTRT+GODMONTNUM))){ // бог
    *(int *)&mon[0x454]=0; // не отвечает на атаку
  }
  if(tp==164){ // огненный голем
    SetMonMagic(mon,31,1000,3,0); // защита от огня
  }
  if(tp==165){ // огненный голем
    SetMonMagic(mon,33,1000,3,0); // защита от земли
  }
  if(tp==166){ // огненный голем
    SetMonMagic(mon,30,1000,3,0); // защита от воздуха
  }
  if(tp==167){ // огненный голем
    SetMonMagic(mon,32,1000,3,0); // защита от воды
  }
  if(tp==169){ // белый монах
    SetMonMagic(mon,36,1000,3,0); // волшебное зеркало
  }
  if(tp==170){ // белый шутер
    SetMonMagic(mon,28,1000,3,0); // воздушный щит
  }
  if(tp==171){ // красный шутер
    SetMonMagic(mon,0x1D,1000,1,0); // огненный щит
  }
  if(tp==192){ // Centaur-Elf
    SetMonMagic(mon,49,1000,3,0); // Mirth
  }
  CrExpBon::ApplySpell(mon,bmp);
  for(j=0;j<SG_GuardsSet;j++){
   if(SG_GuardsSetUp[j].own_stack!=-1){
     sgp=&bmp[0x54CC+0x548*SG_GuardsSetUp[j].sg_stack];
     if((*(int *)&sgp[0x4C])<=0){
       sgp=&bmp[0x54CC+0x548*SG_GuardsSetUp[j].own_stack];
       *(int *)&sgp[0xC4]=SG_GuardsSetUp[j].own_speed;
     }
   }
}

Двоичные патчи для BinMagic:

Отключить щиты у арктического и лавового снайперов в начале боя
75E99C 0000007F
75E9BC 0000007F

Отключить щиты у арктического и лавового снайперов в начале каждого раунда
760854 0000007F
760874 0000007F


RE: ERM-Справочник v2.9.x - Berserker - 12.09.2021 02:22

Флаг 29 у отряда на поле боя говорит, что на отряде анимация жажды крови, а потому деф нужно отрисовывать с палитрой, смещённой к красному.
По смещению 1104 в структуре отряда лежит float (вещественное число) от 0 до 1.0, которое говорит, насколько нужно сдвинуть цвет каждого пикселя в цветовой модели HSV ближе к красному. 0 — ни на сколько, 0.8 — на 80%, 1.0 — полностью красный. Яркость и насыщенность тоже увеличиваются с увеличением значения поля. Если флаг установлен, то при отрисовке уже не проверяется флаг окаменения или клона. Потому при колдовстве жажды крови на клоне, клон временно рисуется без синих тонов.

Upd.
Флаг 30 означает коррекцию насыщенности в модели HSV. Если поле в структуре отряда 0x450 (float, 4 байта) < 1.0 значит умножение (*0 - полностью в серый тонах, на 0.5 — потерять половину насыщенности). Если > 1.0, то новая насыщенность = 1 - ((1 - старая насыщенность) / значение_поля)).

Если стоит флаг 29, то флаг 30 не обрабатывается.

В оригинале во время анимации окаменения значения изменяются от 1.0 до 0.0 с шагом 0.1 (шаг 0.1 и в жажде крови)


RE: Исследование героев - Bes - 07.11.2021 16:44

Quote:Так, если в теле триггера !?MF1 считывать из памяти по адресу 42149568 значения (число, 4 байта), то мы сможем узнать какой именно тип физического повреждения наносится стеку.

Перечень данных для различных типов физ.повреждения:
Code:
4454752    Урон огненным шаром
4455011    Урон от стрельбы
4455746    Урон от смертельного облака
4456676    Урон от круговой атаки (включая атаку Церберами)
4458589    Урон от огненного щита
4460149    Урон от смертельного взгляда
4460621    Удар молнии
4461137    Урон от кислотной атаки
4462398    Урон от рукопашной
4462479    Урон дракона
4610404    Урон от стрелковых башен
4627096    Урон от рва
5902442    Урон от волны смерти
Странно, что здесь есть помимо всего прочего и урон от Волны смерти... исходя из этого есть предположение, что кто-то изначально в игре должен был ей атаковать, как монстро-абилкой. Unsure


RE: Era AI Edition 32bit - void_17 - 16.12.2021 18:31

Ребят, я тут выложил в своем треде базу HD Edition:
http://wforum.heroes35.net/showthread.php?tid=6419
Там халявная дебажная инфа есть и можно восстановить код в тех местах, где загружается и обрабатывается новая графика HD Edition.
   Я скоро восстановлю RoE-вские типы и, впринципе, перед нами уже будет готовый код HD Edition. Можно написать плагин по этому коду, добавить перерисованных нейросетью файлов SoD или даже WoG и кинуть куда надо, чтобы плагин грузил. Как вам идея?

"Перенесено в корректную тему" @Администратор


RE: Стандартизированная база героев 3 - void_17 - 16.12.2021 18:40

Отличия оригинальных типов между RoE и HD Edition есть. Пока не могу сказать какие, но точно это связано с интерфейсом.


RE: Исследование героев - XEPOMAHT - 16.12.2021 21:05

(16.12.2021 17:40)void_17 Wrote:  Например, army::TSampleID.
Image: hex.png
здесь видно константы прямо над названием перечисления. Значение константы лежит по 2 байта слева от нее.
Таким образом, получаем:

Пока как-то больше похоже на гадание на кофейной гуще. Например, army::TSampleID - функция-конструктор, инициализирующая структуру звуков отрядов на поле боя, имена - названия переменных (стековая память), которая потом копируется в структуру _ARMY_ (воговский стиль именования структур, т.к. к нему привыкли за 20 лет), открываем в исходниках WERD, и сразу находим:

Code:
;загруженная копия army::TSampleID
    Загруженный_звук_перемещения dd ?;    170 - WALK_SAMPLE
    Загруженный_звук_атаки dd ?;        174 - ATTACK_SAMPLE
    Загруженный_звук_урона dd ?;        178 - WINCE_SAMPLE
    Загруженный_звук_выстрела dd ?;        17C - SHOOT_SAMPLE
    Загруженный_звук_смерти dd ?;        180 - DIE_SAMPLE
    Загруженный_звук_защиты dd ?;        184 - DEFEND_SAMPLE
    Загруженный_звук_телепорта_вход dd ?;    188 - PRE_WALK_SAMPLE
    Загруженный_звук_телепорта_выход dd ?;    18C - POST_WALK_SAMPLE
    Количество_загруженных_звуков dd ?;    190 - MAX_SAMPLE
;конец копии

Можно компилировать в ассемблере и применять в модах.


RE: Исследование героев - void_17 - 16.12.2021 21:24

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

И да, я не совсем понял о каком конструкторе идет речь. Может дадите адрес? Дримкаст база и моя база больше соответствуют реальности и могут дать более точный ответ. А вообще, army::TSampleID это именно перечисление(enum). Не путайте с массивом из 8 char*-указателей, enum army::TSampleID это просто перечисление для удобства, не структура. По крайней мере так у NWC.


RE: Стандартизированная база героев 3 - XEPOMAHT - 16.12.2021 21:30

(16.12.2021 18:40)void_17 Wrote:  Отличия оригинальных типов между RoE и HD Edition есть. Пока не могу сказать какие, но точно это связано с интерфейсом.

У дримкаста интерфейс тоже значительно перелопачен по сравнению с ПК. Куча новых юбисофтских функций, некоторые кстати перекочевали с дримкаста в порт 2015 года (что подтверждает гипотизу о том, что разорившийся 3DO не передал исходные коды после покупки, поэтому для HD-переиздания использовали то, что откопали в закромах самого Юбисофта, а именно, исходники RoE 0.99). Более-менее достоверно можно восстановить оригинальные имена игрового кода.


RE: Стандартизированная база героев 3 - void_17 - 16.12.2021 21:39

Я знаю об этом. Постоянно сижу в этой самой дримкаст базе, собственно мы этим и занимаемся, что переносим дебажную информацию из дримкаст в "дикий" SoD, некогда воговскую базу. Могу сказать лишь то, что в интерфейсе дримкаста из самих типов не особо поменялось по сравнению с ПК билдом RoE. Говорю просто из опыта работы с базой. Типы не меняются, меняются там лишь аргументы функций да всякие таблицы и прочее.

Кстати есть в дримкасте функции, которых нет в RoE ПК просто из ненадобности. Ну например для переноса камеры на поле боя, так как она не вмещается полностью.


RE: Era AI Edition 32bit - XEPOMAHT - 16.12.2021 21:50

(16.12.2021 18:31)void_17 Wrote:  Я скоро восстановлю RoE-вские типы и, впринципе, перед нами уже будет готовый код HD Edition. Можно написать плагин по этому коду, добавить перерисованных нейросетью файлов SoD или даже WoG и кинуть куда надо, чтобы плагин грузил. Как вам идея?

Не имеет смысла. Дополнение Клинок Армагеддона всё равно сложно будет реализовать в HD-переиздании, т.к. там изменений вагон. SoD больше тянет на DLC, изменений там совсем немного (т.к. SoD запланирован не был, тут в дело вмешался издатель с первым намереньем заработать на игроках с минимальными затратами программисто-часов).


RE: Might and Magic. Heroes III — HD Edition - void_17 - 16.12.2021 21:55

Вы не поняли меня. Применяя код HD Edition, сделать плагин для SoD или даже WoG, чтобы работала графика как в HD Edition.


RE: Исследование героев - XEPOMAHT - 16.12.2021 22:15

(16.12.2021 21:24)void_17 Wrote:  Все развивается так быстро, что даже этот гайд устарел. RoseKavalier написал скрипты и сейчас пытается дампать всю эту информацию. AlexSpl обнаружил еще оригинальные названия параметров функций.
Как только RoseKavalier отправит мне дампы, я вручную все обработаю(по-другому к сожалению никае) по сути у нас будут готовы все игровые типы и enum-ы.

Если это как-то поможет моддерам, то будет замечательно, а если так и останется "на бумаге", тогда смысл? Основная проблема - доступность простым смертным, если они ничего не поймут, тогда что есть, что нет - больше модов от этого не станет. Лично я от RoseKavalier ничего не использую, т.к. он делает слишком много вложений в структурах, что совершенно неудобно при их чтении и анализе, редко его комментарии в самих структурах полезны, т.к. программисткий жаргон мне понимать тяжело, ну а самое главное - я работаю с русифицированными структурами, т.к. английский совершенно не знаю.

До сих пор использую структуры Мастера, замиксованные с разными структурами из параллельных проектов. Самые понятные для меня - наработки по структурам из WoG 3.59, т.к. сделаны явно непрограммистами для непрограммистов. 148

(16.12.2021 21:24)void_17 Wrote:  Может дадите адрес? Дримкаст база и моя база больше соответствуют реальности и могут дать более точный ответ. А вообще, army::TSampleID это именно перечисление(enum). Не путайте с массивом из 8 char*-указателей, enum army::TSampleID это просто перечисление для удобства, не структура. По крайней мере так у NWC.

У меня ваша база не открывается, ничего по ней сказать не могу, у меня дримкастный исполняемый файл был диассемблирован IDA 6, с чем потом я пытался работать, потом забросил. Что такое указатели и перечисления - не знаю. Программисткий жаргон не понимаю. 105

В самой игре это просто кусок памяти на 24h байта, адресующийся в виде dword-значений. Просто и понятно, без изысков.


RE: Might and Magic. Heroes III — HD Edition - XEPOMAHT - 16.12.2021 22:33

(16.12.2021 21:55)void_17 Wrote:  Применяя код HD Edition, сделать плагин для SoD или даже WoG, чтобы работала графика как в HD Edition.

Это ещё дольше и сложнее, чем портирование всех дополнений на HD Edition, т.к. потребуется полностью заменить весь графический движок игры. Да и смысла так же в этом нет, т.к. затраты несоизмеримы с тем, что получится в итоге.


RE: Might and Magic. Heroes III — HD Edition - void_17 - 17.12.2021 07:38

(16.12.2021 22:33)XEPOMAHT Wrote:  
(16.12.2021 21:55)void_17 Wrote:  Применяя код HD Edition, сделать плагин для SoD или даже WoG, чтобы работала графика как в HD Edition.

Это ещё дольше и сложнее, чем портирование всех дополнений на HD Edition, т.к. потребуется полностью заменить весь графический движок игры. Да и смысла так же в этом нет, т.к. затраты несоизмеримы с тем, что получится в итоге.

Я изначально запостил это в теме, в которой ребята этим по-сути и занимались. Я таким образом хотел им подсказать, мне лично это не надо и неинтересно. Админ перенес пост зачем-то. И да, в HD Edition графика работает по принципу надстройки, т.е. там не очень-то и сложно. Главное алгоритмы понять.


Администратор (igrik): вернул сообщения в надлежащую тему
Я тоже не понимаю, зачем сообщения нужно было отсюда переносить.



RE: Исследование героев - void_17 - 17.12.2021 07:48

Quote:Если это как-то поможет моддерам, то будет замечательно
Понятное дело, что поможет. Разработчики игры оставили информацию о всех типах enum, битовым полям и даже параметрам функций де-факто в открытом доступе. Остается лишь это систематизировать и перед нами.. Рай для моддеров!

Quote:а если так и останется "на бумаге", тогда смысл?
ничего не останется на бумаге. https://handbookhmm.ru/forum/viewtopic.php?f=56&t=968&start=330 мы активно работаем, можете наблюдать за процессом.

Quote:Основная проблема - доступность простым смертным, если они ничего не поймут, тогда что есть, что нет - больше модов от этого не станет.

Этим самым "смертным" порой достаточно пару чисел поменять, они уже в шоке от того, что можно менять стартовые ресурсы сложности, им хватает этого вполне. Можно сделать гайд, как это делать. Вот я в вк пытаюсь. Для моддеров тем не менее это невероятно полезная информация, мы сейчас всю работу сделаем и пользуйтесь наздоровье. Моддинг удобнее гораздо станет, ведь вместо безликих sub_XXXXXX и прочего у нас 100% точная информация обо всем прямо от разработчиков игры.

Quote:Лично я от RoseKavalier ничего не использую, т.к. он делает слишком много вложений в структурах, что совершенно неудобно при их чтении и анализе, редко его комментарии в самих структурах полезны

А это здесь причем вообще? Ну я тоже не пользуюсь H3API, тоже она мне не нравится, ну не значит это, что нужно вообще человека бойкотировать. Он с нами в команде работает и приносит только пользу, дампая информацию. Мне остается ее лишь вручную обработать, т.к. скриптов для этого нет.

Quote:т.к. программисткий жаргон мне понимать тяжело, ну а самое главное - я работаю с русифицированными структурами, т.к. английский совершенно не знаю.
До сих пор использую структуры Мастера, замиксованные с разными структурами из параллельных проектов. Самые понятные для меня - наработки по структурам из WoG 3.59, т.к. сделаны явно непрограммистами для непрограммистов.

Я тоже ни разу не программист. Я буквально этой весной не знал как поставить хук и что такое структура и классы. Я вообще на инженера учусь. Мне ничего не мешало изучить по-тихоньку это дело, тем более для моих институтских проектов это мне помогает хорошо, поэтому лично для меня все героями не ограничивается.

Quote:У меня ваша база не открывается, ничего по ней сказать не могу, у меня дримкастный исполняемый файл был диассемблирован IDA 6, с чем потом я пытался работать, потом забросил. Что такое указатели и перечисления - не знаю. Программисткий жаргон не понимаю. 105

А IDA 7.6 у вас не работает? Тогда ничем не могу помочь, кроме как порекоммендовать виндовс обновить хотя бы до 7-ки.


RE: Исследование героев - XEPOMAHT - 17.12.2021 10:41

(17.12.2021 07:48)void_17 Wrote:  Понятное дело, что поможет. Разработчики игры оставили информацию о всех типах enum, битовым полям и даже параметрам функций де-факто в открытом доступе. Остается лишь это систематизировать и перед нами.. Рай для моддеров!

Смотрел, там каша отладочной информации, у меня просто духу не хватило глубоко разбираться в ней. Моддинг считаю превыше.

(17.12.2021 07:48)void_17 Wrote:  https://handbookhmm.ru/forum/viewtopic.php?f=56&t=968&start=330 мы активно работаем, можете наблюдать за процессом.

Наблюдаю, кое что беру на карандаш. Спасибо.

(17.12.2021 07:48)void_17 Wrote:  Этим самым "смертным" порой достаточно пару чисел поменять, они уже в шоке от того, что можно менять стартовые ресурсы сложности, им хватает этого вполне. Можно сделать гайд, как это делать. Вот я в вк пытаюсь. Для моддеров тем не менее это невероятно полезная информация, мы сейчас всю работу сделаем и пользуйтесь наздоровье. Моддинг удобнее гораздо станет, ведь вместо безликих sub_XXXXXX и прочего у нас 100% точная информация обо всем прямо от разработчиков игры.

Появится у тех, кто сможет открыть базу. Далеко не у всех есть IDA, для многих изменение данных в структурах с помощью UN:C - потолок, поэтому списки имён к функциям с адресами и сами структуры рекомендую всё же публиковать отдельно в текстовом виде, чтобы этими данными мог воспользоваться любой у кого установлен Блокнот на ПК.

(17.12.2021 07:48)void_17 Wrote:  А это здесь причем вообще? Ну я тоже не пользуюсь H3API, тоже она мне не нравится, ну не значит это, что нужно вообще человека бойкотировать. Он с нами в команде работает и приносит только пользу, дампая информацию. Мне остается ее лишь вручную обработать, т.к. скриптов для этого нет.

Не бойкотирую, а только намекаю, что у Кавалериста слишком сложно описаны данные, нужно быть проще.

(17.12.2021 07:48)void_17 Wrote:  А IDA 7.6 у вас не работает? Тогда ничем не могу помочь, кроме как порекоммендовать виндовс обновить хотя бы до 7-ки.

IDA 6.5 - максимальная версия для Windows 2003. У Windows 7 слишком высокие системные требования.


RE: Исследование героев - void_17 - 17.12.2021 12:29

Удалось дампануть автоматически всю дебажную информацию RoE. Вот, дерзайте. (большой txt файл): https://drive.google.com/file/d/1f33j57Ypv_d0JpUnPfjp-uYlXqlPoaMr/view?usp=sharing
Справка для чтения дампа: https://drive.google.com/file/d/13SoqW6r0QnlDYMfO8q6N5a-J1h98mojE/view?usp=sharing

Здесть есть:
! Оригинальные названия функций и методов !
! Оригинальные названия параметров функций !
! Оригинальные названия всех типов !
! Оригинальные названия всех констант перечислений !
и многое другое.

Огромное количество полезной информации, актуальной в т.ч. и для SoD/WoG. Некоторые типы вообще не менялись из версий в версию, некоторые слегка видоизменялись в соответствии с нововведениями.


RE: Исследование героев - Berserker - 17.12.2021 21:20

void_17, спасибо!


RE: Исследование героев - Suft - 22.01.2022 10:16

void_17, Проблема в том что нужно чем то обработать всю недостающую графику для Wog и Сопряжения - что толку от половины работы?, там нужно еще менять настройки сжатия всех кадров ибо они хранятся в х3 размере, так как нам нужно чтобы отображалось как в оригинальной игре а не как в переиздании в увеличенном размере


RE: Исследование героев - void_17 - 23.01.2022 12:45

(22.01.2022 10:16)suftfree Wrote:  void_17, Проблема в том что нужно чем то обработать всю недостающую графику для Wog и Сопряжения - что толку от половины работы?, там нужно еще менять настройки сжатия всех кадров ибо они хранятся в х3 размере, так как нам нужно чтобы отображалось как в оригинальной игре а не как в переиздании в увеличенном размере

Ну у вас же получается Topaz-ом обрабатывать. Я уверен, убейсофт так и делали, чутка подкорректировал в фотошопе.
Осталось изучить код HD Edition, благо там есть сигнатуры и иногда assert-ы с полезной информацией.


RE: Исследование героев - Suft - 24.01.2022 13:22

void_17, Поля битвы при обработке топазом очень похожи на HD Edition - даже местами лучше
Они какой-то другой (похожей) программой обрабатывали
Кстати вот наводка - HD Edition хранят весь интерфейс с не перекраской цветов (синего как в оригинале) а отдельно изображения с другим цветом


RE: Исследование героев - void_17 - 24.01.2022 15:02

Практически полностью разобрал combatManager, кроме полей, которые находятся по смещению от 0x13304 до 0x133CC.
upd.: Не обращайте внимания, я опять невнимательно посмотрел...
Завтра посмотрю, для чего поле unknown1.
Структура :
Code:
class combatManager : baseManager
{
  CNetMsgHandlerPause *netMsgHandlerPause;
  int iNextAction;
  int iNextActionExtra;
  int iNextActionGridIndex;
  int iNextActionGridIndex2;
  uchar iLastDrawGridShade[187];
  uchar iCurDrawGridShade[187];
  struct hexcell cell[187];
  int combatTerrain;
  int combatFringe;
  int iCombatCycleType;
  int iElevationOverlay;
  int iDoorStatus;
  uchar bMoatOn;
  uchar moatIsWide;
  Bitmap16Bit *SaveScreenPreGrid;
  Bitmap16Bit *SaveScreenPostGrid;
  Bitmap16Bit *combatMouseBackground;
  int bBackgroundDrawn;
  NewmapCell *EventCell;
  uchar OnMagicPlains;
  uchar OnCursedGround;
  uchar OnAntiMagicGarrison;
  uchar IsSurrounded;
  uchar OnBoats;
  uchar OnBeach;
  struct town *combatTown;
  struct hero *Heroes[2];
  int iSideSpellPower[2];
  uchar PlayDoh[2];
  uchar PlayYeah[2];
  uchar DohPlayedThisRound[2];
  uchar YeahPlayedThisRound[2];
  int cmbtHeroFrameType[2];
  int cmbtHeroFrameIndex[2];
  int cmbtHeroDataSet[2];
  ulong cmbtHeroLastFidgetTime[2];
  CSprite *cmbtHero[2];
  CSprite *cmbtHeroFlag[2];
  int cmbtHeroFlagFrame[2];
  SLimitData sCmbtHeroLimitData[2];
  SLimitData sCmbtHeroFlagLimitData[2];
  std::vector< SpellID > EagleEyeSpellLearned[2];
  uchar ArmyEffected[2][20];
  bool IsHuman[2];
  bool IsLocalHuman[2];
  int iPlayer[2];
  bool bArtifactCast[2];
  int bSpellsCast[2];
  int numArmies[2];
  armyGroup *ArmyGroups[2];
  army Armies[2][21];
///////////////////////
  int unknown1;
//////////////////////
  int turnSinceLastEnchanter[2];
  bool OnNativeTerrain[2];
  enum TCreatureType SummonedElemental[2];
  int SideRetreated;
  int currArmyGroup;
  int currArmyIndex;
  int currControl;
  int autoCombatOn;
  army *currTroop;
  uchar selectorOn;
  int selectorIndex;
  int highlighterOn;
  int highlighterIndex;
  int lastMoveToIndex;
  int lastCommand;
  int combatCommand;
  CSprite *CurLoadedSpellIcon;
  int CurLoadedSpellEffect;
  int CurSpellEffectFrame;
  TFortificationLevel fortificationLevel;
  int bBattleOver;
  TCombatWindow *mainWindow;
  int bCombatShowIt;
  iconWidget * iconWidgetWL[ 25 ];
  textWidget * textWidgetWL[ 25 ];
  enum type_combat_cursor attack_cursor[ 12 ];
  int attack_hex[ 12 ];
  enum type_combat_cursor last_attack_cursor;
  int iTtlCombatDirections;
  int iBackgroundFrame;
  bool bCreatureIsDead[2][20];
  bool bSomeCreaturesVanish;
  const char *cBkgName;
  combatManager::adjacency_array AdjacentIndex[187];
  uchar SaveBiggestExtent;
  int LimitToExtent;
  int ComputeExtentOnly;
  SLimitData Extent;
  int winner;
  int SkeletonsCreated;
  enum TCreatureType skeleton_type;
  Bitmap816 *NumberWindow;
  std::vector< combatManager::TObstacle > Obstacles;
  bool InPlacementPhase;
  int turn_number;
  int BattleTacticsAdvantage;
  bool DebugNoSpellLimit;
  bool DebugShowHiddenObjects;
  bool DebugShowBlockedHexes;
  combatManager::TArcher Archers[3];
  bool in_second_phase;
  int OriginalAttackSkill;
  int OriginalDefenseSkill;
  int OriginalPowerSkill;
  int original_mana;
  Bitmap816 *wallImages[18][5];
  int wallLevel[18];
  int wall_frame[18];
  type_point map_point;
  Bitmap816 *CombatCellGrid;
  Bitmap816 *CombatCellShaded;
  int ObstacleAnimationFrame;
  bool bCreatureEffect[2][20];
  bool bHeroEffect[2];
  bool bFlagEffect[2];
  bool bArcherEffect[3];
  bool any_action_taken;
  uchar creaturePath[187];
};



RE: Исследование героев - RoseKavalier - 24.01.2022 15:18

Code:
iconWidget* iconWidgetWL[25]; // 76244
textWidget* textWidgetWL[25]; // 76344



RE: Исследование героев - void_17 - 24.01.2022 15:38

Ну и тупанул же я! Rolleyes

Действительно, я почему-то проморгал эти поля, хотя они очевидно там были.

Получается, combatManager разобран абсолютно полностью(кроме поля unknown1). Спустя стольких лет..


RE: Исследование героев - Berserker - 24.01.2022 17:23

void_17, прекрасная работа!


RE: Исследование героев - Ben - 07.07.2022 11:26

А нет ли у кого-нибудь IDA версии 6.3 ?


RE: Исследование героев - igrik - 08.07.2022 01:23

Почему именно 6.3? Где ты такие раздачи то видел?


RE: Исследование героев - Ben - 08.07.2022 08:02

Вопрос не про то, кто какие раздачи видел. Поэтому если есть такая версия - то хорошо (и тогда можно и поговорить, зачем это нужно), остальные же разговоры - бессмыслица.


RE: Исследование героев - igrik - 08.07.2022 09:03

Мда... Не всё то виндовс, что висит...


RE: Исследование героев - daemon_n - 08.07.2022 20:23

igrik, 85