Skip to content

Commit

Permalink
Fix Bone Spirit, adjust crit formula
Browse files Browse the repository at this point in the history
  • Loading branch information
kphoenix137 committed Feb 28, 2024
1 parent 505ed36 commit c51ef14
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 16 deletions.
25 changes: 16 additions & 9 deletions Source/missiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ bool Plr2PlrMHit(const Player &player, Player &target, int mindam, int maxdam, i

int dam;
if (mtype == MissileID::BoneSpirit) {
dam = target._pMaxHP / 3;
dam = player.isOnArenaLevel() ? target._pMaxHP / 3 : target._pHitPoints / 3;
} else {
dam = mindam + GenerateRnd(maxdam - mindam + 1);
if (missileData.isArrow() && damageType == DamageType::Physical)
Expand All @@ -393,8 +393,8 @@ bool Plr2PlrMHit(const Player &player, Player &target, int mindam, int maxdam, i
break;
case MissileID::Firebolt: // 100% (200% of default)
break;
case MissileID::FireWall: // 100% (200% of default)
dam = dam * 3 / 2; // 150% (300% of default)
case MissileID::FireWall: // 150% (300% of default)
dam = dam * 3 / 2;
case MissileID::FlameWave: // 200% (400% of default)
dam *= 2;
break;
Expand All @@ -418,17 +418,24 @@ bool Plr2PlrMHit(const Player &player, Player &target, int mindam, int maxdam, i

bool isOnArena = player.isOnArenaLevel();
int charLevel = player.getCharacterLevel();

// Error handling for critical hit calculation to avoid dividing by 0 in case of bad actor.
charLevel = std::clamp(charLevel, 1, static_cast<int>(GetMaximumCharacterLevel()));

bool isSpell = !missileData.isArrow();
int critChance = (charLevel * 2 + (isSpell ? player._pMagic : player._pDexterity)) / 10;
bool forcehit = false;
int crit = (isSpell ? player._pMagic : player._pDexterity) / (charLevel / 4);

crit = std::clamp(crit, 0, 50);

int critper = GenerateRnd(100);

// PVP REBALANCE: Crit chance for arrows and spells in arenas. Crits force hit recovery.
if (isOnArena && GenerateRnd(100) < critChance) {
if (isOnArena && critper < crit && mtype != MissileID::BoneSpirit) {
dam = isSpell ? dam * 5 / 4 : dam * 3 / 2; // Arrow: +50% damage, Spell: +25% damage
forcehit = true;
}

if (resper > 0 && mtype != MissileID::BoneSpirit) {
// PVP REBALANCE: Bone Spirit is unaffected by resistances on arena levels.
if (resper > 0 && (mtype != MissileID::BoneSpirit || !player.isOnArenaLevel())) {
dam -= (dam * resper) / 100;
if (&player == MyPlayer)
NetSendCmdDamage(true, target, dam, damageType);
Expand All @@ -442,7 +449,7 @@ bool Plr2PlrMHit(const Player &player, Player &target, int mindam, int maxdam, i
} else {
if (&player == MyPlayer)
NetSendCmdDamage(true, target, dam, damageType);
StartPlrHit(target, dam, forcehit);
StartPlrHit(target, dam, false);
}

return true;
Expand Down
19 changes: 12 additions & 7 deletions Source/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,6 @@ int GetSpellSkippedFrames(SpellID spl)
case SpellID::TownPortal:
return 4;
case SpellID::Flash:
return 1;
//case SpellID::StoneCurse:
// Page 3
case SpellID::Phasing:
Expand All @@ -336,6 +335,7 @@ int GetSpellSkippedFrames(SpellID spl)
case SpellID::Teleport:
return 1;
case SpellID::Apocalypse:
return 0;
case SpellID::BoneSpirit:
return 1;
case SpellID::BloodStar:
Expand Down Expand Up @@ -899,15 +899,20 @@ bool PlrHitPlr(Player &attacker, Player &target)

bool isOnArena = attacker.isOnArenaLevel();
int charLevel = attacker.getCharacterLevel();

// Error handling for critical hit calculation to avoid dividing by 0 in case of bad actor.
charLevel = std::clamp(charLevel, 1, static_cast<int>(GetMaximumCharacterLevel()));

int crit = isOnArena ? attacker._pStrength / (charLevel / 4) : charLevel;

crit = std::clamp(crit, 0, 50);

int critper = GenerateRnd(100);
HeroClass charClass = attacker._pClass;
int critChance = isOnArena ? (charLevel * 2 + attacker._pStrength) / 10 : charLevel;
bool forcehit = false;

// PVP REBALANCE: New crit chance formula for arenas. Crits always cause hit recovery.
if ((isOnArena || charClass == HeroClass::Warrior || charClass == HeroClass::Barbarian) && GenerateRnd(100) < critChance) {
if ((isOnArena || charClass == HeroClass::Warrior || charClass == HeroClass::Barbarian) && critper < crit) {
dam *= 2;
if (isOnArena)
forcehit = true;
}

int skdam = dam << 6;
Expand All @@ -926,7 +931,7 @@ bool PlrHitPlr(Player &attacker, Player &target)
if (&attacker == MyPlayer) {
NetSendCmdDamage(true, target, skdam, DamageType::Physical);
}
StartPlrHit(target, skdam, forcehit);
StartPlrHit(target, skdam, false);

return true;
}
Expand Down

0 comments on commit c51ef14

Please sign in to comment.