diff --git a/common/skills.cpp b/common/skills.cpp index 8fe5cf3f2..4720cb470 100644 --- a/common/skills.cpp +++ b/common/skills.cpp @@ -148,6 +148,33 @@ int32 EQEmu::skills::GetBaseDamage(SkillType skill) } } +bool EQEmu::skills::IsMeleeDmg(SkillType skill) +{ + switch (skill) { + case Skill1HBlunt: + case Skill1HSlashing: + case Skill2HBlunt: + case Skill2HSlashing: + case SkillBackstab: + case SkillBash: + case SkillDragonPunch: + case SkillEagleStrike: + case SkillFlyingKick: + case SkillHandtoHand: + case SkillKick: + case Skill1HPiercing: + case SkillRiposte: + case SkillRoundKick: + case SkillThrowing: + case SkillTigerClaw: + case SkillFrenzy: + case Skill2HPiercing: + return true; + default: + return false; + } +} + const std::map& EQEmu::skills::GetSkillTypeMap() { /* VS2013 code diff --git a/common/skills.h b/common/skills.h index 572b8c59f..43a31ed15 100644 --- a/common/skills.h +++ b/common/skills.h @@ -167,6 +167,7 @@ namespace EQEmu bool IsBardInstrumentSkill(SkillType skill); bool IsCastingSkill(SkillType skill); int32 GetBaseDamage(SkillType skill); + bool IsMeleeDmg(SkillType skill); extern const std::map& GetSkillTypeMap(); diff --git a/zone/attack.cpp b/zone/attack.cpp index 608d43139..98cd8785b 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -866,11 +866,9 @@ void Mob::MeleeMitigation(Mob *attacker, DamageHitInfo &hit, ExtraAttackOptions auto roll = RollD20(hit.offense, mitigation); - // +0.5 for rounding - hit.damage_done = static_cast(roll * static_cast(hit.base_damage) + 0.5); + // +0.5 for rounding, min to 1 dmg + hit.damage_done = std::max(static_cast(roll * static_cast(hit.base_damage) + 0.5), 1); - if (hit.damage_done < 0) - hit.damage_done = 0; Log.Out(Logs::Detail, Logs::Attack, "mitigation %d vs offense %d. base %d rolled %f damage %d", mitigation, hit.offense, hit.base_damage, roll, hit.damage_done); } @@ -1207,7 +1205,7 @@ void Mob::DoAttack(Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts) if (strike_through && zone->random.Roll(strike_through)) { Message_StringID(MT_StrikeThrough, STRIKETHROUGH_STRING); // You strike through your opponents defenses! - hit.damage_done = 0; // set to zero, we will check this to continue + hit.damage_done = 1; // set to one, we will check this to continue } // I'm pretty sure you can riposte a riposte if (hit.damage_done == DMG_RIPOSTED) { @@ -1218,7 +1216,7 @@ void Mob::DoAttack(Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts) Log.Out(Logs::Detail, Logs::Combat, "Avoided/strikethrough damage with code %d", hit.damage_done); } - if (hit.damage_done == 0) { + if (hit.damage_done >= 0) { if (other->CheckHitChance(this, hit)) { other->MeleeMitigation(this, hit, opts); if (hit.damage_done > 0) { @@ -1297,7 +1295,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b Log.Out(Logs::Detail, Logs::Combat, "Attacking with %s in slot %d using skill %d", weapon?weapon->GetItem()->Name:"Fist", Hand, my_hit.skill); // Now figure out damage - my_hit.damage_done = 0; + my_hit.damage_done = 1; my_hit.min_damage = 0; uint8 mylevel = GetLevel() ? GetLevel() : 1; uint32 hate = 0; @@ -1437,13 +1435,15 @@ void Client::Damage(Mob* other, int32 damage, uint16 spell_id, EQEmu::skills::Sk // cut all PVP spell damage to 2/3 // Blasting ourselfs is considered PvP //Don't do PvP mitigation if the caster is damaging himself + //should this be applied to all damage? comments sound like some is for spell DMG + //patch notes on PVP reductions only mention archery/throwing ... not normal dmg if(other && other->IsClient() && (other != this) && damage > 0) { int PvPMitigation = 100; - if (attack_skill == EQEmu::skills::SkillArchery) + if (attack_skill == EQEmu::skills::SkillArchery || attack_skill == EQEmu::skills::SkillThrowing) PvPMitigation = 80; else PvPMitigation = 67; - damage = (damage * PvPMitigation) / 100; + damage = std::max((damage * PvPMitigation) / 100, 1); } if(!ClientFinishedLoading()) @@ -1784,7 +1784,7 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool DamageHitInfo my_hit; my_hit.skill = EQEmu::skills::SkillHandtoHand; my_hit.hand = Hand; - my_hit.damage_done = 0; + my_hit.damage_done = 1; if (Hand == EQEmu::inventory::slotPrimary) { my_hit.skill = static_cast(GetPrimSkill()); OffHandAtk(false); @@ -3199,7 +3199,7 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const if (!ignore_invul && (GetInvul() || DivineAura())) { Log.Out(Logs::Detail, Logs::Combat, "Avoiding %d damage due to invulnerability.", damage); - damage = -5; + damage = DMG_INVULNERABLE; } if( spell_id != SPELL_UNKNOWN || attacker == nullptr ) @@ -4465,6 +4465,10 @@ void Mob::ApplyDamageTable(DamageHitInfo &hit) if (hit.offense < 115) return; + // things that come out to 1 dmg seem to skip this (ex non-bash slam classes) + if (hit.damage_done < 2) + return; + auto &damage_table = GetDamageTable(); if (zone->random.Roll(damage_table.chance)) diff --git a/zone/bot.cpp b/zone/bot.cpp index bdb8cd627..6ce4210b3 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -3919,9 +3919,9 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b DamageHitInfo my_hit; AttackAnimation(my_hit.skill, Hand, weapon); Log.Out(Logs::Detail, Logs::Combat, "Attacking with %s in slot %d using skill %d", weapon?weapon->GetItem()->Name:"Fist", Hand, my_hit.skill); - + // Now figure out damage - my_hit.damage_done = 0; + my_hit.damage_done = 1; my_hit.min_damage = 0; uint8 mylevel = GetLevel() ? GetLevel() : 1; uint32 hate = 0; @@ -5046,7 +5046,7 @@ void Bot::DoSpecialAttackDamage(Mob *who, EQEmu::skills::SkillType skill, int32 DamageHitInfo my_hit; my_hit.base_damage = max_damage; my_hit.min_damage = min_damage; - my_hit.damage_done = 0; + my_hit.damage_done = 1; my_hit.skill = skill; my_hit.offense = offense(my_hit.skill); diff --git a/zone/command.cpp b/zone/command.cpp index 307b4e949..2a22bc82c 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -10686,7 +10686,7 @@ void command_logs(Client *c, const Seperator *sep){ /* We use a general 'is_category_enabled' now, let's update when we update any output settings This is used in hot places of code to check if its enabled in any way before triggering logs */ - if (sep->arg[4] > 0){ + if (atoi(sep->arg[4]) > 0){ Log.log_settings[atoi(sep->arg[3])].is_category_enabled = 1; } else{ diff --git a/zone/special_attacks.cpp b/zone/special_attacks.cpp index e38ffb04d..adcf09aaf 100644 --- a/zone/special_attacks.cpp +++ b/zone/special_attacks.cpp @@ -94,6 +94,8 @@ int Mob::GetBaseSkillDamage(EQEmu::skills::SkillType skill, Mob *target) } if (inst) ac_bonus = inst->GetItemArmorClass(true) / 25.0f; + else + return 0; // return 0 in cases where we don't have an item if (ac_bonus > skill_bonus) ac_bonus = skill_bonus; return static_cast(base + ac_bonus + skill_bonus); @@ -142,7 +144,7 @@ void Mob::DoSpecialAttackDamage(Mob *who, EQEmu::skills::SkillType skill, int32 return; DamageHitInfo my_hit; - my_hit.damage_done = 0; + my_hit.damage_done = 1; // min 1 dmg my_hit.base_damage = base_damage; my_hit.min_damage = min_damage; my_hit.skill = skill; @@ -843,7 +845,7 @@ void Mob::DoArcheryAttackDmg(Mob *other, const EQEmu::ItemInstance *RangeWeapon, DamageHitInfo my_hit; my_hit.base_damage = MaxDmg; my_hit.min_damage = 0; - my_hit.damage_done = 0; + my_hit.damage_done = 1; my_hit.skill = EQEmu::skills::SkillArchery; my_hit.offense = offense(my_hit.skill); @@ -1175,7 +1177,7 @@ void NPC::DoRangedAttackDmg(Mob* other, bool Launch, int16 damage_mod, int16 cha DamageHitInfo my_hit; my_hit.base_damage = MaxDmg; my_hit.min_damage = MinDmg; - my_hit.damage_done = 0; + my_hit.damage_done = 1; my_hit.skill = skill; my_hit.offense = offense(my_hit.skill); @@ -1356,7 +1358,7 @@ void Mob::DoThrowingAttackDmg(Mob *other, const EQEmu::ItemInstance *RangeWeapon DamageHitInfo my_hit; my_hit.base_damage = WDmg; my_hit.min_damage = 0; - my_hit.damage_done = 0; + my_hit.damage_done = 1; my_hit.skill = EQEmu::skills::SkillThrowing; my_hit.offense = offense(my_hit.skill); @@ -2113,7 +2115,7 @@ void Mob::DoMeleeSkillAttackDmg(Mob *other, uint16 weapon_damage, EQEmu::skills: DamageHitInfo my_hit; my_hit.base_damage = weapon_damage; my_hit.min_damage = 0; - my_hit.damage_done = 0; + my_hit.damage_done = 1; my_hit.skill = skillinuse; my_hit.offense = offense(my_hit.skill);