|
@@ -798,6 +798,9 @@ int8 Entity::DetermineHit(Spawn* victim, int8 type, int8 damage_type, float ToHi
|
|
|
Entity* entity_victim = (Entity*)victim;
|
|
|
float chance = 80 + bonus; //80% base chance that the victim will get hit (plus bonus)
|
|
|
sint16 roll_chance = 100;
|
|
|
+ if(is_caster_spell) {
|
|
|
+ chance += CalculateLevelStatBonus(GetWis());
|
|
|
+ }
|
|
|
if(skill)
|
|
|
roll_chance -= skill->current_val / 10;
|
|
|
|
|
@@ -874,6 +877,7 @@ int8 Entity::DetermineHit(Spawn* victim, int8 type, int8 damage_type, float ToHi
|
|
|
|
|
|
skill = entity_victim->GetSkillByName("Defense", true);
|
|
|
|
|
|
+ // calculated in Entity::CalculateBonuses
|
|
|
float dodgeChance = entity_victim->GetInfoStruct()->get_avoidance_base();
|
|
|
if(dodgeChance > 0.0f)
|
|
|
{
|
|
@@ -888,11 +892,11 @@ int8 Entity::DetermineHit(Spawn* victim, int8 type, int8 damage_type, float ToHi
|
|
|
return DAMAGE_PACKET_RESULT_MISS; //successfully avoided
|
|
|
}
|
|
|
else{
|
|
|
- skill = entity_victim->GetSkillByName("Spell Avoidance", true);
|
|
|
- if(skill)
|
|
|
- chance -= skill->current_val / 10;
|
|
|
-
|
|
|
- LogWrite(COMBAT__DEBUG, 9, "Combat", "SpellAvoidChance: fchance %f", chance);
|
|
|
+ float focus_skill_with_bonus = entity_victim->CalculateSkillWithBonus("Spell Avoidance", ITEM_STAT_SPELL_AVOIDANCE, true);
|
|
|
+ int16 effective_level = entity_victim->GetInfoStruct()->get_effective_level() != 0 ? entity_victim->GetInfoStruct()->get_effective_level() : entity_victim->GetLevel();
|
|
|
+ focus_skill_with_bonus += entity_victim->CalculateLevelStatBonus(entity_victim->GetWis());
|
|
|
+ chance -= ((focus_skill_with_bonus)/10);
|
|
|
+ LogWrite(COMBAT__DEBUG, 9, "Combat", "SpellAvoidChance: fchance %f, focus with skill bonus %f", chance, focus_skill_with_bonus);
|
|
|
if(rand()%roll_chance >= chance) {
|
|
|
return DAMAGE_PACKET_RESULT_RESIST; //successfully resisted
|
|
|
}
|
|
@@ -1599,7 +1603,7 @@ float Entity::CalculateAttackSpeedMod(){
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
-void Entity::AddProc(int8 type, float chance, Item* item, LuaSpell* spell) {
|
|
|
+void Entity::AddProc(int8 type, float chance, Item* item, LuaSpell* spell, int8 damage_type, int8 hp_ratio, bool below_health, bool target_health, bool extended_version) {
|
|
|
if (type == 0) {
|
|
|
LogWrite(COMBAT__ERROR, 0, "Proc", "Entity::AddProc called with an invalid type.");
|
|
|
return;
|
|
@@ -1616,6 +1620,11 @@ void Entity::AddProc(int8 type, float chance, Item* item, LuaSpell* spell) {
|
|
|
proc->item = item;
|
|
|
proc->spell = spell;
|
|
|
proc->spellid = spell->spell->GetSpellID();
|
|
|
+ proc->health_ratio = hp_ratio;
|
|
|
+ proc->below_health = below_health;
|
|
|
+ proc->damage_type = damage_type;
|
|
|
+ proc->target_health = target_health;
|
|
|
+ proc->extended_version = extended_version;
|
|
|
m_procList[type].push_back(proc);
|
|
|
MProcList.releasewritelock(__FUNCTION__, __LINE__);
|
|
|
}
|
|
@@ -1663,8 +1672,12 @@ bool Entity::CastProc(Proc* proc, int8 type, Spawn* target) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- lua_getglobal(state, "proc");
|
|
|
-
|
|
|
+ if(proc->extended_version) {
|
|
|
+ lua_getglobal(state, "proc_ext");
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ lua_getglobal(state, "proc");
|
|
|
+ }
|
|
|
if (item_proc) {
|
|
|
num_args++;
|
|
|
lua_interface->SetItemValue(state, proc->item);
|
|
@@ -1673,6 +1686,7 @@ bool Entity::CastProc(Proc* proc, int8 type, Spawn* target) {
|
|
|
lua_interface->SetSpawnValue(state, this);
|
|
|
lua_interface->SetSpawnValue(state, target);
|
|
|
lua_interface->SetInt32Value(state, type);
|
|
|
+ lua_interface->SetInt32Value(state, proc->damage_type);
|
|
|
|
|
|
/*
|
|
|
Add spell data from db in case of a spell proc here...
|
|
@@ -1722,20 +1736,31 @@ void Entity::CheckProcs(int8 type, Spawn* target) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- float roll = MakeRandomFloat(0, 100);
|
|
|
-
|
|
|
vector<Proc*> tmpList;
|
|
|
|
|
|
MProcList.readlock(__FUNCTION__, __LINE__);
|
|
|
for (int8 i = 0; i < m_procList[type].size(); i++) {
|
|
|
+ // roll per proc, not overall
|
|
|
+ float roll = MakeRandomFloat(0, 100);
|
|
|
Proc* proc = m_procList[type].at(i);
|
|
|
- if (roll <= proc->chance)
|
|
|
+ if (roll <= proc->chance &&
|
|
|
+ ((!proc->extended_version || proc->health_ratio == 0) ||
|
|
|
+ (proc->below_health && !proc->target_health && proc->health_ratio < (int8)GetIntHPRatio()) ||
|
|
|
+ (!proc->below_health && !proc->target_health && proc->health_ratio >= (int8)GetIntHPRatio()) ||
|
|
|
+ (target && proc->below_health && proc->target_health && proc->health_ratio < (int8)target->GetIntHPRatio()) ||
|
|
|
+ (target && !proc->below_health && proc->target_health && proc->health_ratio >= (int8)target->GetIntHPRatio()))
|
|
|
+ )
|
|
|
{
|
|
|
Proc* tmpProc = new Proc();
|
|
|
tmpProc->chance = proc->chance;
|
|
|
tmpProc->item = proc->item;
|
|
|
tmpProc->spell = proc->spell;
|
|
|
tmpProc->spellid = proc->spellid;
|
|
|
+ tmpProc->damage_type = proc->damage_type;
|
|
|
+ tmpProc->health_ratio = proc->health_ratio;
|
|
|
+ tmpProc->below_health = proc->below_health;
|
|
|
+ tmpProc->target_health = proc->target_health;
|
|
|
+ tmpProc->extended_version = proc->extended_version;
|
|
|
tmpList.push_back(tmpProc);
|
|
|
}
|
|
|
}
|
|
@@ -1834,7 +1859,7 @@ sint32 Entity::CalculateDamageAmount(Spawn* target, sint32 damage, int8 base_typ
|
|
|
Spell double cast: A straight damage modifier, the more you can get the better. You won't be able to get very much of this.
|
|
|
Makes the spell cast twice with some limitations.
|
|
|
**/
|
|
|
-
|
|
|
+ damage = damage + damage * CalculateLevelStatBonus(GetInt()); // lvl 70 * 1200 int = 84000, log10f(84000) = 4.924 / 50.0f = 0.09848
|
|
|
damage = CalculateFormulaByStat(damage, ITEM_STAT_SPELL_DAMAGE);
|
|
|
}
|
|
|
|
|
@@ -1855,8 +1880,9 @@ sint32 Entity::CalculateDamageAmount(Spawn* target, sint32 damage, int8 base_typ
|
|
|
}
|
|
|
|
|
|
// combat abilities only bonus
|
|
|
- if(damage_type <= DAMAGE_PACKET_DAMAGE_TYPE_PIERCE)
|
|
|
+ if(damage_type <= DAMAGE_PACKET_DAMAGE_TYPE_PIERCE) {
|
|
|
damage = CalculateFormulaByStat(damage, ITEM_STAT_TAUNT_AND_COMBAT_ART_DAMAGE);
|
|
|
+ }
|
|
|
|
|
|
// Potency mod
|
|
|
damage = CalculateFormulaByStat(damage, ITEM_STAT_POTENCY);
|