Hello. I have a little question about function Dmg_OnDmg. If i remember, Lehona make that function, but it's possible to edit magic damage with her? Because actually i have something like this:
And if i use scaling weapon damage with attribute i don't have any problem(all work great and correct). But if i try make scaling with ex. Icebolt spell, scaling not work. Example - if i have 400 mana and Icebolt deal 50 damage, after my change npc, who don't have any protection from magic, should get 450 clear dmg. But actually lose only 50(so my formula not work). It's possible to add scaling magic damage in this function or it need more work? I use Ikarus/Lego. Geyser and Breath of Death don't work too. Fire spell and Chargezap work in half.
I didn't fully read your code, but you have conditions such as
Code:
if (Npc_GetActiveSpell(oth) == SPL_IceBolt)
&& (Npc_GetLastHitSpellID(slf) == SPL_IceBolt)
1. You don't want to use Npc_GetActiveSpell, because it will return the currently active spell - this could be different if the hero changes equipped spell while a spell projectile is in flight.
2. I think Npc_GetLastHitSpellID only works under certain condition - if I remember correctly its when the spell causes (or can cause) a status/AI state such as Ice Cube. (not 100% sure)
You get the spell ID from the damage descriptor:
Code:
dmgDesc.spellId
And to save some headache you might want to do the following:
Code:
// If there is hitPfx but no spellId, probably AoE spell _SPREAD hitting other NPCs after a direct hit on NPC with the original projectile
if (dmgDesc.hitPfx && dmgDesc.spellId <= 0) {
var oCVisualFX hitPfx; hitPfx = _^(dmgDesc.hitPfx);
if (!attackerPtr) {
attackerPtr = hitPfx.inflictor;
};
};
If the attacker ptr is still missing after this, I would just return the damage as is... Alternatively you could use this fix: https://forum.worldofplayers.de/foru...1#post26707746 (fixes some other stuff too, e.g. with Large Firestorm)
You can also use weapon mode to figure out what the attack actually was
/// Calculate the damage, enhance it, ...
func int DMG_Calculate(var oSDamageDescriptor dmgDesc, var int dmg_IsHit, var c_npc attackerNpc, var c_npc victimNpc, var int spellId, var int spellLvl) {
var int dmg; dmg = 0;
var int curDmg; curDmg = 0;
var int prot;
var C_Item weaponItem; weaponItem = MEM_NullToInst();
// We add all the damage types to a sum of damage
repeat(i, DAM_INDEX_MAX); var int i;
if ( (dmgDesc.dmgMode & (1 << i)) == (1 << i)) {
curDmg = MEM_ReadStatArr(dmgDesc.dmgArray, i);
prot = MEM_ReadStatArr(victimNpc.protection, i);
if ((spellId > 0 && !dmgDesc.itemWeapon)
&& (i == DAM_INDEX_FIRE || i == DAM_INDEX_MAGIC)) {
// TODO:
Print("Spell hit");
if (spellID == 20)
{
curDmg = SPL_Damage_BreathOfDeath + hero.attribute[ATR_MANA_MAX];
};
// curDmg = Dmg_EnhanceMagicDamage(attackerNpc, victimNpc, curDmg, spellId, spellLvl);
};
if (dmgDesc.itemWeapon) {
// TODO:
// if (Hlp_Is_oCItem(dmgDesc.itemWeapon)) {
// weaponItem = MEM_PtrToInst(dmgDesc.itemWeapon);
// curDmg = Dmg_EnhanceWeaponDamage(attackerNpc, victimNpc, curDmg, dmg_IsHit, weaponItem);
// };
};
// Substract Protection from damage
curDmg = ( curDmg - prot );
if (curDmg > 0) {
dmg += curDmg;
PrintS_Extend(IntToString(curDmg), COL_Aqua);
};
};
end;
// If we did not achieve a "critical hit", reduce damage accordingly
if (!dmg_IsHit) {
dmg = dmg * NPC_MINIMAL_PERCENT / 100;
};
// We check if we actually got any damage done
if (dmg < 0) {
dmg = 0;
};
// Apply min-damage *only* if not spell attack
if ( (!dmgDesc.hitPfx) && (!dmgDesc.visualFX)) {
if (dmg < NPC_MINIMAL_DAMAGE) {
dmg = NPC_MINIMAL_DAMAGE;
};
};
return dmg;
};
func int DMG_OnDmg(var int victimPtr, var int attackerPtr, var int dmg, var int dmgDescriptorPtr, var int dmg_IsHit) {
if (!victimPtr) { return dmg; };
var oSDamageDescriptor dmgDesc; dmgDesc = MEM_PtrToInst(dmgDescriptorPtr);
// Just return falldamage
if (dmgDesc.dmgMode == DAM_FALL) {
return dmg;
};
var int dmgIsPFX; dmgIsPFX = FALSE;
var c_npc victimNpc; victimNpc = MEM_PtrToInst(victimPtr);
var int spellId; spellId = dmgDesc.spellID;
var int spellLvl; spellLvl = dmgDesc.spellLevel;
var oCVisualFX visFx;
if (!attackerptr) {
attackerptr = dmgDesc.attackerNpc;
};
if (dmgDesc.hitPfx && spellId <= 0) {
visFx = MEM_PtrToInst(dmgDesc.hitPfx);
// If we still have no attacker, try to take him from
// Pfx inflictor
if (!attackerptr) {
attackerptr = visFx.inflictor;
};
dmgIsPFX = TRUE;
};
if (attackerptr) {
var c_npc attackerNpc; attackerNpc = MEM_PtrToInst(attackerptr);
// Invoke customized damage calculation if it's not a particle effect
if (!dmgIsPFX) {
dmg = DMG_Calculate(dmgDesc, dmg_IsHit, attackerNpc, victimNpc, spellId, spellLvl);
};
};
return dmg;
};
func void_DMG_OnDmg_Post() {
const int dmgDesc = 0;
const int dmg_IsHit = 0;
dmg_IsHit = MEM_ReadInt((ESP + 640) - 356/* zBOOL bHasHit */);
dmgDesc = MEM_ReadInt((ESP + 640) + 4/* &oSDamageDescriptor */); // oCNpc :: OnDamage_Hit ( oSDamageDescriptor& descDamage )
EDI = DMG_OnDmg(EBP, MEM_ReadInt(dmgDesc+8), EDI, +dmgDesc, +dmg_IsHit);
};
func void InitDamage() {
HookEngineF(6736583/*0x66CAC7*/, 5, _DMG_OnDmg_Post);
};
Now Icebolt spell deal correct damage(if hero have 400 mana and target have 0 protection from magic, he deal 650 damage - if he have 50 protection, he deal 600[but i don't know if it work only for Hero or other NPC too). But after change my last formula i have another problem. How i can now add weapon scaling? I mean, if we had weapon, which need Dexterity to wear, i want add scaling like "Weapon damage + hero dexterity - protection". Example... if weapon like Betty deal 130 damage and need 110 dexterity to wear, i want something like "130/2 damage + 110/2 dexterity(from hero) = protection - 120 damage(if enemy have more prot than total damage = 300 - 120 = 180) or 130 damage(from weapon) + 110 dexterity(from hero) = 240 damage - protection/2, if enemy have less prot than total damage(240-140/2 = 170). I know it's stupid question, but thanks for your help anyway.