Объявления
Поздравляем
Roman2211


Друзья, если не получается зарегистрироваться, напишите на почту vdv_forever@bk.ru.
Я оторву свою задницу от всех дел и обязательно Вас активирую! :smile10:
Добро пожаловать на геройский форум! :smile25:

Редактирование ресурсов и кода игры

Не запускается игра? Проблемы со звуком? Где, в конце концов, взять игру, скачать патчи, приложения и карты? Как установить все это? Все проблемы обсуждаем в этом разделе
offlinelimiltless123  
Подмастерье
Подмастерье
 
Сообщения: 108
Зарегистрирован: 09 апр 2014, 15:28
Пол: Не указан
Поблагодарили: 15 раз.

Re: Heroes2 - вставляем свои аватары

Сообщение limiltless123 » 21 апр 2014, 22:28

Нет, вот мы дошли до этого места. Пока мне всё понятно и я уже знаю три типа команды ассемблера add, cmp, jz и jnz :D
Я только сейчас вроде начал что то понимать. Просто я никогда до этого не видили ни С, ни ассемблера, ни понятия машинные команды,
ни всего этого софта что мы использовали.

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

Например можно начать с того, что - после того, как мы сделали дамб оперативки в WinHex, отыскали строку с минимальным уроном и нашли ее в ИДЕ -нам открылась блоксхема - чего ? (я про то что на рисунке)
и в ней синий строкой в каком то блоке выделено что ?
Вложения
124.jpg
124.jpg (25.44 КБ) Просмотров: 541
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2185 раз.

Re: Heroes2 - вставляем свои аватары

Сообщение AlexSpl » 21 апр 2014, 22:49

Цитата:
Например можно начать с того что - после того как мы сделали дамб оперативки в Hex-редакторе, отыскали строку с минимальным уроном и нашли ее в ИДЕ -нам открылась блоксхема - чего ? (я про то что на рисунке)

На картинке Вы видите блок-схему функции (процедуры), отвечающей за определение (расчёт) урона, который отряд нанесёт противнику при атаке или на ответке. Эта функция выполняет расчёт урона от и до. Нас пока интересует лишь небольшой фрагмент этой функции, который Вы заскринили ранее. Именно этот фрагмент отвечает за нахождение базового урона отряда, а именно: в этом фрагменте программа (игра) находит базовый урон отряда, т.е. чистый урон (без всяких модификаторов), путём суммирования базовых уронов каждого воина в отряде.
Цитата:
и в ней синий строкой в каком то блоке выделено что ?

Выделена инструкция, которая будет выполнена следующей. Вы прервали выполнение программы (игры) в некотором месте, а именно в момент подсчёта базового урона. А ещё точнее - после того, как игра прочитала значение минимального урона из оперативной памяти командой movsx ecx, byte ptr [eax+0C8h]. Нажимая теперь F8, Вы сможете выполнять инструкции вручную (по шагам). При обычной работе программы эти инструкции с огромной скоростью автоматически выполняются процессором.

P. S. Книги по ассемблеру можно скачать здесь.
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2185 раз.

Re: Heroes2 - вставляем свои аватары

Сообщение AlexSpl » 22 апр 2014, 17:14

Часть четвёртая

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

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

Для того, чтобы переименовать локальную переменную, щёлкните по ней и нажмите клавишу N. В появившееся окошко "Please enter a string" введите новое имя переменной.

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

Перейдите по адресу 41D902 и переименуйте локальную переменную var_14 в base_dmg. Как Вы уже догадались, эта переменная предназначена для хранения базового урона отряда. Далее, переименуйте var_10 в i. Это счётчик цикла (итератор). Переменную var_28 переименуйте в combatManager. В этой переменной хранится адрес "менеджера битвы", переданный функции расчёта урона через регистр ecx. Теперь перейдите по адресу 41D942 и измените var_2C на dmg_bless, в блоке справа аналогичным образом поменяйте var_30 на dmg_curse, а в самом правом блоке - var_34 на dmg. Теперь код читается гораздо легче.

Изображение

 Важное уточнение
На самом деле, в переменной var_28 хранится не сам адрес "менеджера битвы", а адрес структуры внутри combatManager, хранящей сведения об отряде, производящем атаку, поэтому логичнее было бы переименовать переменную var_28 не в combatManager, а, например, в AttackerAddr.


Давайте вернёмся к первой инструкции цикла, т.е. перейдём по адресу 41D925. Там Вы увидите четыре инструкции:

Код: Выделить всё
mov ecx, [ebp+combatManager]
mov edx, [ebp+i]
cmp edx, [ecx+96h]
jge short loc_41D9AB


Первая инструкция загружает в регистр ecx адрес "менеджера битвы". Вторая - в регистр edx текущее значение счётчика цикла, которое вначале равно 0 (см. инструкцию mov [ebp+i], 0 чуть выше), третья сравнивает значение регистра edx с количеством воинов в отряде, для которого находится базовый урон, четвёртая передаёт управление левой ветке (зелёная стрелка), если значение счётчика цикла оказывается больше либо равно количеству воинов в отряде, а иначе управление передаётся правой ветке (красная стрелка). Таким образом, пока значение счётчика будет меньше количества воинов в отряде, будет выполняться правая ветка кода, в которой базовый урон очередного воина добавляется к общей сумме base_dmg. Эта ветка будет выполнена ровно N раз, где N - количество воинов в отряде :) Собственно, я только что описал принцип работы простейшего цикла, в котором i является переменной цикла (счётчиком), а правая ветка кода - телом цикла.

В теле цикла присутствуют два условия (две проверки флага), которые разбивают задачу подсчёта урона на три более простые подзадачи. Действительно, чтобы найти базовый урон отряда, необходимо рассмотреть три различных случая:

1) когда отряд находится под действием заклинания "Благословение";
2) когда отряд находится под действием заклинания "Проклятие";
3) когда отряд не находится под действием заклинаний "Благословение" или "Проклятие".

Чтобы найти базовый урон отряда в первом случае, необходимо просуммировать максимальные уроны каждого воина в отряде. Во втором случае необходимо просуммировать уже минимальные уроны каждого воина в отряде, а в третьем - случайные уроны из диапазона [минимальный_урон .. максимальный_урон]. Всё это и делают инструкции в трёх верхних блоках. Затем управление передаётся по адресу 41D91C, где значение счётчика увеличивается на 1, и расчёты повторяются для следующего воина в отряде.

Приведённый код расчёта базового урона отряда, мягко говоря, не совсем оптимизирован :) Например, чтобы посчитать базовый урон отряда, состоящего из 1000 горгулий, на который было направлено заклинание "Благословение", игра выполнит тысячу сложений:

3 + 3 + ... + 3 (тремя точками обозначенены недостающие 997 троек). Попробуйте-ка найти эту сумму в уме :) Наверное, Вы не будете складывать тройки тысячу раз подряд, а просто найдёте результат произведения 3 * 1000 = 3000. Почему этого не делает игра, для меня остаётся загадкой.

Аналогичным образом дело обстоит и с подсчётом базового урона отряда под "Проклятием". И лишь в последнем, третьем, случае цикл оправдан: урон каждого (!) воина в отряде имеет значение, и это здорово, на самом деле, т.к. распределение вероятностей выпадения урона в Двойке получается просто шикарным (в отличие от той же Тройки) :)

Продолжение следует...
Последний раз редактировалось AlexSpl 01 май 2014, 16:38, всего редактировалось 2 раз(а).
Вернуться к началу

offlinelimiltless123  
Подмастерье
Подмастерье
 
Сообщения: 108
Зарегистрирован: 09 апр 2014, 15:28
Пол: Не указан
Поблагодарили: 15 раз.

Re: Heroes2 - вставляем свои аватары

Сообщение limiltless123 » 22 апр 2014, 20:51

Так, вот я тоже повесил брейкпоинт на строку с dmg_curse, запустил игру и когда гаргули(под проклятием) атаковали - брейкпоинт сработал
Так) дальше что ... :P
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2185 раз.

Re: Heroes2 - вставляем свои аватары

Сообщение AlexSpl » 22 апр 2014, 21:01

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

offlinelimiltless123  
Подмастерье
Подмастерье
 
Сообщения: 108
Зарегистрирован: 09 апр 2014, 15:28
Пол: Не указан
Поблагодарили: 15 раз.

Re: Heroes2 - вставляем свои аватары

Сообщение limiltless123 » 22 апр 2014, 21:11

Я брошу монетку 8-) выпало - переписывать весь цикл целиком)
Но! мне вполне хватило бы - простого деления на 2
На самом деле - вам решать)
Последний раз редактировалось limiltless123 22 апр 2014, 21:14, всего редактировалось 1 раз.
Вернуться к началу

offlinelimiltless123  
Подмастерье
Подмастерье
 
Сообщения: 108
Зарегистрирован: 09 апр 2014, 15:28
Пол: Не указан
Поблагодарили: 15 раз.

Re: Heroes2 - вставляем свои аватары

Сообщение limiltless123 » 22 апр 2014, 21:13

я вот только думаю что лучше будет если нечетные числа будут округлятся в меньшую сторону, хотя хз
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2185 раз.

Re: Heroes2 - вставляем свои аватары

Сообщение AlexSpl » 22 апр 2014, 21:16

Так тому и быть. На самом деле, если мы перепишем весь цикл, потребность в округлении промежуточных результатов деления на два не возникнет. Достаточно будет перемножить количество воинов в отряде и минимальный урон одного воина из этого отряда, а затем поделить полученный результат на два. Аналогично нужно будет поступить с "Благословением" (его действие нужно модифицировать, кстати?).
Вернуться к началу

offlinelimiltless123  
Подмастерье
Подмастерье
 
Сообщения: 108
Зарегистрирован: 09 апр 2014, 15:28
Пол: Не указан
Поблагодарили: 15 раз.

Re: Heroes2 - вставляем свои аватары

Сообщение limiltless123 » 22 апр 2014, 21:27

AlexSpl писал(а):

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



Почему не надо будет округлять .. Допустим у меня три война в отряде и минимальный урон равен 3 Получается 3*3/2 = 4.5
Про благословение - ну я бы повысил его эффективность любым удобным способом тоже. Так как я переименовал эту магию, чтобы к ней проявился новый интерес, и она бы не пылилась как раньше.
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2185 раз.

Re: Heroes2 - вставляем свои аватары

Сообщение AlexSpl » 22 апр 2014, 21:35

Цитата:
Почему не надо будет округлять .. Допустим у меня три война в отряде и минимальный урон равен 3 Получается 3*3/2 = 4.5

Урон (base_dmg) хранится как дробное число одинарной точности (4 байта). Поэтому значение 4.5 будет участвовать во всех последующих расчётах, и лишь конечный результат (результирующий урон) будет округлён в меньшую сторону.

Цитата:
ну я бы повысил его эффективность любым удобным способом тоже.

Как бы уже "Жажда крови" урон поднимает нехило. Получится заклинание-двойник тогда.
Вернуться к началу

Пред.След.

Вернуться в Техническая часть

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3