Управление ближним ударом стека - Sav - 27.11.2010 23:12
Dll модифицирует код определения целей при ближнем ударе существ.
Для Era 1.9 и выше.
Damage.era (v1.02).
Исходник (MSVC++).
1. Новый триггер "перед ударом" (вызывается перед нанесением урона, один раз для каждого ближнего удара, визуально - во время срабатывания удачи).
2. Возможность в этом триггере получить информацию о том: 1) Какие стеки являются целями атаки; 2) Какой стек является основной целью атаки (тот, на который игрок нажал при направлении на атаку, на который будет наложено заклинание при атаке и который будет наносить ответный удар); 3) Какой стек является атакующим в данный момент.
3. Возможность в этом триггере изменить цели атаки (целей может быть любое количество, ими могут быть дружественные существа; вся анимация, вычисления, лог и прочее правильно работают для всех целей, триггер !?MF вызывается для каждой цели).
Файл dll (с расширением "era") должен лежать в папке "EraPlugins".
Триггер "Перед ударом" - !?FU78001;.
Вы можете получить информацию об атаке в триггере "перед ударом" при помощи !!SN:X.
Code:
!!SN:X?v2/?v3/?v4/?v5;Теперь в v2 хранятся цели среди атакующих существ, в v3 - цели среди защищающихся, в v4 - номер основной цели, в v5 - номер атакующего стека.
Передать изменённые цели можно тоже через !!SN:X.
Code:
!!SN:Xv2/v3;Передача новых целей.
Вы можете также передать основную цель и атакующего, но это ни на что не повлияет.
Основая цель и атакующий стек передаются в виде номера стека (0-41).
Цели атаки разделены на две переменные - в первой хранится информация о том, какие стеки среди атакующих являются целями, а во второй - какие из защищающихся.
Информация в этих переменных хранится побитно: в каждой из них 1-21 бит хранит информацию о том, будет ли атаковано соответствующий стек соответствующей стороны (1 - будет атакован, 0 - нет).
Code:
!!VRv1:S0;Для атакующего: нет атакованных.
!!VRv2:S6;Для защищающегося: 6 = 2 + 4 = 2^1 + 2^2 - 1-ый и 2-ой (считая с нуля) по номерам стеки.
!!SN:Xv1/v2;В результате будут атакованы стеки с номерами 22 и 23 (номера 1 и 2 у защищающегося).
При получении информации о целях используется та же система.
1. Выполняется код нанесения удара, но модифицированный - вместо нанесения урона в эти моменты записываются цели которые должны получить урон.
2. Вызывается триггер "перед ударом", туда передаётся вся информация.
3. Если пользователь не изменил цели атаки, модификация отключается и повторно выполняется код удара (уже наносящий урон).
Иначе - включается модификация и выполняется модифицированный код удара: 1) Все проверки на флаг "бить всех вокруг" модифицируются так, что для любого удара выполняется код удара с флагом "бить всех вокруг". 2) Совершается цикл: для каждого номера стека проверяется по переменным целей, должен ли он быть атакован, если должен, ему наносится урон (без анимации), иначе - нет.
4. Дальше идёт неизменённый код - анимация, запись в лог и т. д.
Можно атаковать самого себя, при этом не будет анимации получения урона и гибели. Может даже закончиться бой, а существо останется стоять.
Можно атаковать мёртвые и несуществующие стеки. Скорее всего, не случится ничего, но могут быть и неприятные последствия.
Если не выбрана ни одна цель (или все они мёртвые или несуществующие) удар будет нанесён "в воздух", а в логе будет написано "X нанасли 0 урона."
ZVSE
!?FU78001;Перед ударом существа (триггер Damage.dll)... !!VRy-1:Sv2;Сохраняем значение глобальной переменной. !!VRy-2:Sv3;Сохраняем значение глобальной переменной. !!VRy-3:Sv4;Сохраняем значение глобальной переменной. !!VRy-4:Sv5;Сохраняем значение глобальной переменной. !!SN:X?v2/?v3/?v4/?v5;Считываем переданные параметры. !!BMv5:T?y-5;Считываем тип существ действующего стека. !!FU&y-5<>195:E;Если удар производят не пожары, выходим из триггера. !!BMv5:I?y-6;Считываем номер стороны - хозяина пожаров. !!VRy-7:S1-y-6;Вычисляем номер не ходящей стороны. !!VRy-8:Sy-7*21;Вычисляем номер первого стека не ходящей стороны. !!VRy-9:Sy-8+20;Вычисляем номер последнего стека не ходящей стороны. !!VRy-10:S1;Устанавливаем переменную бита в 1 (первый бит). !!VRy-7:+2;Вычисляем номер переменной целей для не ходящей стороны. !!DO9499/y-8/y-9/1:P=y-10/?y-10/y-7;Запускаем цикл, проходящийся по всем стекам стороны и устанавливающий биты существующих из них в переменной целей в 1 (то есть делающий их целями атаки). !!SN:Xv2/v3/v4/v5;Передаём переменные-параметры. !!VRv5:Sy-4;Возвращаем значение глобальной переменной. !!VRv4:Sy-3;Возвращаем значение глобальной переменной. !!VRv3:Sy-2;Возвращаем значение глобальной переменной. !!VRv2:Sy-1;Возвращаем значение глобальной переменной.
;Функции определения существующих целей.
!?FU9499;Функция проверки существования стека и установки его бита в переменной целей. !!BMx16:N?y2;Считываем количество существ в текущем проверяемом стеке. !!VRvx3&y2>0:|x1;Если в текущем проверяемом стеке есть существа, устанавливаем его бит в соответствующей переменной целей в 1. !!VRx2:Sx1*2;Переходим к следующему биту (умножаем переменную бита на 2).
RE: Управление ближним ударом стека - Berserker - 28.11.2010 00:35
Sav, есть предложение параметры устанавливать через SN:X (как - покажу). Второе предложение - номер пост-триггера назначить на 78ххх, то есть следующая тысяча после Эры. Более универсально и логически правильно будет, IMHO.
RE: Управление ближним ударом стека - Sav - 28.11.2010 00:58
Berserker Wrote:Sav , есть предложение параметры устанавливать через SN:X ( как - покажу ).
Дело в том, что между установкой параметров и их использованием может выполниться немаленький кусок кода. Кроме того, как только цель вычисляется, по ней сразу же наносится удар с вызовом !?MF, а лишь потом вычисляется следующая цель (с использованием параметров, естественно).
Если переданные через !!SN:X параметры сохранятся после всего этого, то, конечно, лучше передавать через них и не занимать переменные.
Berserker Wrote:Второе предложение -
номер пост- триггера назначить на 78 ххх, то есть
следующая тысяча после Эры. Более универсально
и логически правильно будет , IMHO.
Без проблем.
RE: Управление ближним ударом стека - Berserker - 28.11.2010 01:09
Quote:Кроме того, как только цель вычисляется, по ней сразу же наносится удар с вызовом !?MF, а лишь потом вычисляется следующая цель (с использованием параметров, естественно).
Если переданные через !!SN:X параметры сохранятся после всего этого, то, конечно, лучше передавать через них и не занимать переменные.
Можно ли сделать триггер на начало удара?
RE: Управление ближним ударом стека - Sav - 28.11.2010 01:45
Вот как условно выглядит сруктура кода после модификации:
Code:
...
for(i = 0; i < 41; i++)
{
1. Проверка бита v-переменной для текущего стека (i), если 0, то continue.
2. Вычисление адреса конструкций стека (что конкретно находится по этому адресу, я ещё не разбирал, но это используется при нанесении урона).
3. Нанесение урона (с вызовом !?MF).
}
...
Триггер здесь можно вствить куда угодно, будет ли от него толк - другой вопрос.
RE: Управление ближним ударом стека - Berserker - 28.11.2010 02:28
Триггер нужно поставить до входа в цикл.
В модуле:
Code:
TYPE
PEventParams = ^TEventParams;
TEventParams = ARRAY[0..63] OF INTEGER;
VAR
EventsParam: PEventParams;
LeftSideBits: INTEGER;
RightSideBits: INTEGER;
BEGIN
EventsParam := Win.GetProcAddr(Win.GetModuleHandle('Angel.dll'), 'EventParams');
END.
EventsParam будет указывать на массив из 64 параметров SN:X. В триггере до входа в цикл нужно лишь обнулить первые два значения, вызвать ЕРМ-функции, сохранить два значения в LeftSideBits и RightSideBits. А в самом цикле использовать их, а не v-ки.
RE: Управление ближним ударом стека - Sav - 28.11.2010 18:55
Спасибо. Переделал.
RE: Управление ближним ударом стека - Sav - 01.01.2011 20:19
Обновил dll - теперь она модифицирует и удар без флага бить всех вокруг (через вмешательство в проверки на этот флаг).
RE: Управление ближним ударом стека - Sav - 03.01.2011 17:11
Обновил dll.
Теперь она перед вызовом dll определяет, какие цели должны быть у удара, если его не модифицировать.
Теперь и исходник не стыдно выложить.
RE: Управление ближним ударом стека - Berserker - 03.01.2011 17:25
Отлично. Тестил на надёжность?
//Переенная битов целей атакующей стороны (1-й - 21-й биты) и включённости модификации (32-й бит).
//Если старые цели не совпадают с новыми, записываем новые цели в переменные целей и включаем модмфицирование.
Quote:Damage_ch_shit
RE: Управление ближним ударом стека - Sav - 03.01.2011 18:53
Спасибо за орфографию.
Berserker Wrote:Тестил на надёжность?
Да, тестил на пожарах, лазурных драконах, горынычах и церберах - ошибок нет.
Не могу 100% гарантировать, что всегда будет нормально (всё-таки из-за проверки 2 раза выполняется большой кусок кода с записями в стек и пр.), но судя по тестам, все типы ближних ударов работают.
Quote:Damage_ch_shit
Это standart hit. Я не специально.
RE: Управление ближним ударом стека - Sav - 03.01.2011 22:20
Обновил dll. Теперь в ней можно получить (изменить нельзя) номер основной цели (той, на которую игрок нажал мышкой при ударе) и номер атакующего стека. Последнее наконец-то даёт возможность нормально использовать эту dll.
Скрипт в примере теперь полностью рабочий и не обладает побочными эффектами.
RE: Управление ближним ударом стека - Sav - 07.06.2011 17:25
Исправил ошибку с адресом, из-за которой удар со сработавшим дыханием дракона блокировался.
RE: Управление ближним ударом стека - izrukvruki - 07.06.2011 18:31
я плакаЛь (плакающий смайл есть у нас?), вспоминая те времена, когда каждый мод снабжался примерчиком (была такая практика), на котором каждый смертный мог видеть, что дает данный мод...
RE: Управление ближним ударом стека - Sav - 07.06.2011 22:53
Вот такой есть: .
Только у меня "что даёт" написано отдельно, а пример, скорее, для "как использовать".
RE: Управление ближним ударом стека - Sav - 19.02.2012 18:45
Переписал на C++.
RE: Управление ближним ударом стека - igrik - 19.06.2014 14:45
Sav, верни жизнь ссылкам. И на исходники тоже
RE: Управление ближним ударом стека - Sav - 20.06.2014 21:07
https://www.dropbox.com/s/4pc8c41b657yt17/Damage.era
https://www.dropbox.com/s/5cap0hqjiezynst/Damage.zip
Правда в исходниках там сплошной ассемблер, и я не помню, какая версия Эры нужна и не знаю, работает ли на текущей.
|