Часть четвёртаяВ этой части мы изменим эффект заклинания "Проклятие", а именно сделаем так, чтобы воины в проклятом отряде наносили лишь половину своего минимального урона.
Для начала сделаем код, отвечающий за определение базового урона отряда, более понятным, дав осмысленные имена локальным переменным.
Для того, чтобы переименовать локальную переменную, щёлкните по ней и нажмите клавишу 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. Почему этого не делает игра, для меня остаётся загадкой.
Аналогичным образом дело обстоит и с подсчётом базового урона отряда под "Проклятием". И лишь в последнем, третьем, случае цикл оправдан: урон каждого (!) воина в отряде имеет значение, и это здорово, на самом деле, т.к. распределение вероятностей выпадения урона в Двойке получается просто шикарным (в отличие от той же Тройки)
Продолжение следует...