Автору в помощь с кодом на отражение урона:
func void StExt_OnPostDamage()
{
var int reflectAllowed;
var int damageFlags;
var int dist;
StExt_PrintDebug("StExt_OnPostDamage()", "ENTER", StExt_AttackNpc, StExt_TargetNpc);
// Проверка входящих данных
if (Hlp_IsNULL(StExt_IncomingDamageInfo))
{
StExt_PrintDebug("StExt_OnPostDamage()", "StExt_IncomingDamageInfo instance is Null!", StExt_TargetNpc, StExt_AttackNpc);
return;
}
// Проверка валидности NPC
if (!Hlp_IsValidNpc(StExt_TargetNpc) || !Hlp_IsValidNpc(StExt_AttackNpc))
{
StExt_PrintDebug("StExt_OnPostDamage()", "Invalid NPC detected!", StExt_TargetNpc, StExt_AttackNpc);
return;
}
// Проверка актёров
if (!StExt_CheckDamageActors("StExt_OnPostDamage()"))
{
return;
}
StExt_PrintIncomingDamageDebug("STEXT_ONPOSTDAMAGE");
// Инициализация reflect
StExt_InitializeReflectDamage();
if (Hlp_IsNULL(StExt_ReflectDamageInfo))
{
StExt_PrintDebug("StExt_OnPostDamage()", "ReflectDamageInfo NULL!", StExt_TargetNpc, StExt_AttackNpc);
return;
}
// Получение флагов и типа урона
StExt_ReflectDamageInfo.DamageFlags = StExt_GetDamageFlags(
StExt_TargetNpc,
StExt_AttackNpc,
StExt_NullItem,
StExt_IncomingDamageInfo.SpellId
);
StExt_ReflectDamageInfo.DamageType = StExt_GetDamageType(
StExt_TargetNpc,
StExt_AttackNpc,
StExt_NullItem,
StExt_IncomingDamageInfo.SpellId
);
// Основной обработчик
StExt_PostDamageHandler(StExt_AttackNpc, StExt_TargetNpc, StExt_NullItem);
// Проверка дистанции
dist = npc_getdisttonpc(StExt_TargetNpc, StExt_AttackNpc);
damageFlags = StExt_IncomingDamageInfo.Flags;
// Проверка возможности reflect
reflectAllowed =
(
!StExt_ValueHasFlag(damageFlags, StExt_IncomingDamageFlag_Index_ReflectDamage) &&
!StExt_ValueHasFlag(damageFlags, StExt_IncomingDamageFlag_Index_Contextual) &&
StExt_ValueHasFlag(damageFlags, StExt_IncomingDamageFlag_Index_HasAttacker)
);
// Применение reflect
if (reflectAllowed && Hlp_IsValidNpc(StExt_AttackNpc) && (dist < 800))
{
// Ограничение максимальных целей
if (StExt_ReflectDamageInfo.MaxTargets > 8)
StExt_ReflectDamageInfo.MaxTargets = 8;
// Рассчёт AOE
StExt_ReflectDamageInfo.MaxTargets = StExt_CalcAoeTargets(
StExt_TargetNpc,
StExt_ReflectDamageInfo.DamageFlags,
StExt_ReflectDamageInfo.MaxTargets
);
StExt_ReflectDamageInfo.Radius = StExt_CalcAoeDistance(
StExt_TargetNpc,
StExt_ReflectDamageInfo.DamageFlags
);
// Применяем отражённый урон
StExt_ApplyReflectDamage(StExt_TargetNpc, StExt_AttackNpc);
// Суммирование отражённого урона с жёсткой защитой
int reflectDamage = 0;
if (!Hlp_IsNULL(StExt_ReflectDamageInfo.Damage) && !Hlp_IsNULL(StExt_ReflectDamageInfo.DotDamage))
{
for (int i = 0; i < StExt_ReflectDamageInfo.MaxTargets && i < 8; i++)
{
int dmg = StExt_ReflectDamageInfo.Damage
;
int dot = StExt_ReflectDamageInfo.DotDamage;
if (dmg > 10000) dmg = 10000;
if (dot > 5000) dot = 5000;
// Проверяем, что элементы не NULL и не отрицательные
if (dmg < 0) dmg = 0;
if (dot < 0) dot = 0;
reflectDamage += dmg + dot;
}
}
StExt_PrintDebug("StExt_OnPostDamage()", "Reflect Damage Total: " + reflectDamage, StExt_TargetNpc, StExt_AttackNpc);
}
else
{
StExt_PrintDebug(
"StExt_OnPostDamage()",
"Reflect not allowed",
StExt_TargetNpc,
StExt_AttackNpc
);
}
// Завершение reflect
StExt_FinalizeReflectDamage();
StExt_PrintDebug("StExt_OnPostDamage()", "EXIT", StExt_AttackNpc, StExt_TargetNpc);
};
Что делает код с отраженным уроном:
-
- Проверка на NULL массивов Damage и DotDamage.
- Каждый элемент проверяется на отрицательные значения.
- Жёсткие лимиты: Damage ≤ 10000, DotDamage ≤ 5000, MaxTargets ≤ 8.
[*]Защита от невалидных NPC и NULL входящих данных.
[*]Логирование суммы отражённого урона.