Browse Source

AddWard updates in support of Issue #115

Helps address issue #115

two new arguments added:
AddWard(dmg,keepWard,wardType,damageTypes,dmgAbsorptionPct,dmgAbsorptionMaxHealthPct)

dmgAbsorptionPct - max percentage of the damage that can be absorbed per hit (eg 100 damage, 50% absorption, 50 absorbed, 50 damage left)
dmgAbsorptionMaxHealthPct - Max absorption percentage against the targets total hp, eg 1000 hp 50% absorption, if the hit is 500 dmg or more, then no damage absorbed
Image 3 years ago
parent
commit
b3ffa77c42

+ 29 - 4
EQ2/source/WorldServer/Entity.cpp

@@ -1285,9 +1285,32 @@ int32 Entity::CheckWards(int32 damage, int8 damage_type) {
 
 		spell = ward->Spell;
 
-		if (damage >= ward->DamageLeft) {
+		int32 damageToAbsorb = 0;
+		if (ward->DamageAbsorptionPercentage > 0)
+			damageToAbsorb = (int32)(double)damage * ((double)ward->DamageAbsorptionPercentage/100.0);
+		else
+			damageToAbsorb = damage;
+
+		int32 maxDamageAbsorptionAllowed = 0;
+
+		// spells like Divine Aura have caps on health, eg. anything more than 50% damage is not absorbed
+		if (ward->DamageAbsorptionMaxHealthPercent > 0)
+			maxDamageAbsorptionAllowed = (int32)(double)GetTotalHP() * ((double)ward->DamageAbsorptionMaxHealthPercent / 100.0);
+
+		if (maxDamageAbsorptionAllowed > 0 && damageToAbsorb >= maxDamageAbsorptionAllowed)
+			damageToAbsorb = 0; // its over or equal to 50% of the total hp allowed, thus this damage is not absorbed
+
+		int32 baseDamageRemaining = damage - damageToAbsorb;
+
+		if (damageToAbsorb >= ward->DamageLeft) {
 			// Damage is greater than or equal to the amount left on the ward
-			damage -= ward->DamageLeft;
+
+			// remove what damage we can absorb 
+			damageToAbsorb -= ward->DamageLeft;
+
+			// move back what couldn't be absorbed to the base dmg and apply to the overall damage
+			baseDamageRemaining += damageToAbsorb;
+			damage = baseDamageRemaining;
 			ward->DamageLeft = 0;
 			spell->damage_remaining = 0;
 			GetZone()->SendHealPacket(spell->caster, this, HEAL_PACKET_TYPE_ABSORB, ward->DamageLeft, spell->spell->GetName());
@@ -1298,12 +1321,14 @@ int32 Entity::CheckWards(int32 damage, int8 damage_type) {
 		}
 		else {
 			// Damage is less then the amount left on the ward
-			ward->DamageLeft -= damage;
+			ward->DamageLeft -= damageToAbsorb;
 			spell->damage_remaining = ward->DamageLeft;
 			if (spell->caster->IsPlayer())
 				ClientPacketFunctions::SendMaintainedExamineUpdate(GetZone()->GetClientBySpawn(spell->caster), spell->slot_pos, ward->DamageLeft, 1);
 			GetZone()->SendHealPacket(ward->Spell->caster, this, HEAL_PACKET_TYPE_ABSORB, damage, spell->spell->GetName());
-			damage = 0;
+
+			// remaining damage not absorbed by percentage must be set
+			damage = baseDamageRemaining;
 		}
 
 		// Reset ward pointer

+ 2 - 0
EQ2/source/WorldServer/Entity.h

@@ -255,6 +255,8 @@ struct WardInfo {
 	int8		WardType;
 	int8		DamageType;
 	bool		keepWard;
+	int8		DamageAbsorptionPercentage;
+	int8		DamageAbsorptionMaxHealthPercent;
 };
 
 #define WARD_TYPE_ALL 0

+ 12 - 0
EQ2/source/WorldServer/LuaFunctions.cpp

@@ -4933,6 +4933,8 @@ int EQ2Emu_lua_AddWard(lua_State* state) {
 	bool keepWard = (lua_interface->GetInt8Value(state, 2) == 1);
 	int8 wardType = lua_interface->GetInt8Value(state, 3);
 	int8 damageTypes = lua_interface->GetInt8Value(state, 4);
+	int8 damageAbsorptionPercent = lua_interface->GetInt8Value(state, 5);
+	int8 damageAbsorptionMaxHealthPercent = lua_interface->GetInt8Value(state, 6);
 
 	LuaSpell* spell = lua_interface->GetCurrentSpell(state);
 
@@ -4956,6 +4958,16 @@ int EQ2Emu_lua_AddWard(lua_State* state) {
 			ward->DamageLeft = damage;
 			ward->keepWard = keepWard;
 			ward->WardType = wardType;
+			if (damageAbsorptionPercent > 100)
+				damageAbsorptionPercent = 100;
+
+			ward->DamageAbsorptionPercentage = damageAbsorptionPercent;
+
+			if (damageAbsorptionMaxHealthPercent > 100)
+				damageAbsorptionMaxHealthPercent = 100;
+
+			ward->DamageAbsorptionMaxHealthPercent = damageAbsorptionMaxHealthPercent;
+
 			if (wardType == WARD_TYPE_MAGICAL)
 				ward->DamageType = damageTypes;