mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 21:01:29 +00:00
Rework combat to make use of a struct to fix some bugs
This commit is contained in:
parent
e300f82c28
commit
37e87e8cef
@ -392,15 +392,12 @@ RULE_BOOL(Spells, NPCInnateProcOverride, true) // NPC innate procs override the
|
|||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Combat)
|
RULE_CATEGORY(Combat)
|
||||||
RULE_INT(Combat, MeleeBaseCritChance, 0) //The base crit chance for non warriors, NOTE: This will apply to NPCs as well
|
RULE_INT(Combat, PetBaseCritChance, 0) // Pet Base crit chance
|
||||||
RULE_INT(Combat, WarBerBaseCritChance, 3) //The base crit chance for warriors and berserkers, only applies to clients
|
|
||||||
RULE_INT(Combat, BerserkBaseCritChance, 6) //The bonus base crit chance you get when you're berserk
|
|
||||||
RULE_INT(Combat, NPCBashKickLevel, 6) //The level that npcs can KICK/BASH
|
RULE_INT(Combat, NPCBashKickLevel, 6) //The level that npcs can KICK/BASH
|
||||||
RULE_INT(Combat, NPCBashKickStunChance, 15) //Percent chance that a bash/kick will stun
|
RULE_INT(Combat, NPCBashKickStunChance, 15) //Percent chance that a bash/kick will stun
|
||||||
RULE_INT(Combat, RogueCritThrowingChance, 25) //Rogue throwing crit bonus
|
RULE_INT(Combat, MeleeCritDifficulty, 8900) // lower is easier
|
||||||
RULE_INT(Combat, RogueDeadlyStrikeChance, 80) //Rogue chance throwing from behind crit becomes a deadly strike
|
RULE_INT(Combat, ArcheryCritDifficulty, 3400) // lower is easier
|
||||||
RULE_INT(Combat, RogueDeadlyStrikeMod, 2) //Deadly strike modifier to crit damage
|
RULE_INT(Combat, ThrowingCritDifficulty, 1100) // lower is easier
|
||||||
RULE_INT(Combat, ClientBaseCritChance, 0) //The base crit chance for all clients, this will stack with warrior's/zerker's crit chance.
|
|
||||||
RULE_BOOL(Combat, UseIntervalAC, true)
|
RULE_BOOL(Combat, UseIntervalAC, true)
|
||||||
RULE_INT(Combat, PetAttackMagicLevel, 30)
|
RULE_INT(Combat, PetAttackMagicLevel, 30)
|
||||||
RULE_BOOL(Combat, EnableFearPathing, true)
|
RULE_BOOL(Combat, EnableFearPathing, true)
|
||||||
|
|||||||
@ -77,6 +77,8 @@ app.controller('MainCtrl', function($scope, $interval) {
|
|||||||
$scope.stop();
|
$scope.stop();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var damage_mods = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
|
||||||
|
|
||||||
function getRandomInt(min, max) {
|
function getRandomInt(min, max) {
|
||||||
min = Math.ceil(min);
|
min = Math.ceil(min);
|
||||||
max = Math.floor(max);
|
max = Math.floor(max);
|
||||||
@ -94,45 +96,20 @@ app.controller('MainCtrl', function($scope, $interval) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function doCombatRound() {
|
function doCombatRound() {
|
||||||
var offense = $scope.offense;
|
var offense = getRandomInt(0, $scope.offense + 5);
|
||||||
var mitigation = $scope.mitigation;
|
var mitigation = getRandomInt(0, $scope.mitigation + 5);
|
||||||
mitigation = mitigation - ((mitigation - offense) / 2.0);
|
var avg = parseInt(($scope.offense + $scope.mitigation + 10) / 2);
|
||||||
var diff = offense - mitigation;
|
var index = parseInt((offense - mitigation) + (avg / 2));
|
||||||
var mean = 0.0;
|
if (index < 0) {
|
||||||
var mult1 = 0.0;
|
index = 0;
|
||||||
var mult2 = 0.0;
|
|
||||||
|
|
||||||
if (offense > 30.0) {
|
|
||||||
mult1 = offense / 200.0 + 25.75;
|
|
||||||
if ((mitigation / offense) < 0.35) {
|
|
||||||
mult1 = mult1 + 1.0;
|
|
||||||
} else if ((mitigation / offense) > 0.65) {
|
|
||||||
mult1 = mult1 - 1.0;
|
|
||||||
}
|
}
|
||||||
mult2 = offense / 140 + 18.5;
|
index = parseInt((index * 20) / avg);
|
||||||
} else {
|
if (index >= 20)
|
||||||
mult1 = 11.5 + offense / 2.0;
|
index = 19;
|
||||||
mult2 = 14.0 + offense / 6.0;
|
if (index < 0)
|
||||||
}
|
index = 0;
|
||||||
|
var roll = damage_mods[index];
|
||||||
if (offense > mitigation) {
|
addRoll(roll);
|
||||||
mean = diff / offense * mult1;
|
|
||||||
} else if (mitigation > offense) {
|
|
||||||
mean = diff / mitigation * mult2;
|
|
||||||
}
|
|
||||||
|
|
||||||
var stddev = 8.8;
|
|
||||||
var theta = 2 * Math.PI * getRandom(0.0, 1.0);
|
|
||||||
var rho = Math.sqrt(-2 * Math.log(1 - getRandom(0.0, 1.0)));
|
|
||||||
var d = mean + stddev * rho * Math.cos(theta);
|
|
||||||
|
|
||||||
if (d < -9.5) {
|
|
||||||
d = -9.5;
|
|
||||||
} else if (d > 9.5) {
|
|
||||||
d = 9.5;
|
|
||||||
}
|
|
||||||
d = d + 11;
|
|
||||||
addRoll(parseInt(d));
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
662
zone/attack.cpp
662
zone/attack.cpp
File diff suppressed because it is too large
Load Diff
@ -1313,8 +1313,9 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case SE_HeadShotLevel: {
|
case SE_HeadShotLevel: {
|
||||||
if (newbon->HSLevel < base1)
|
if (newbon->HSLevel[0] < base1)
|
||||||
newbon->HSLevel = base1;
|
newbon->HSLevel[0] = base1;
|
||||||
|
newbon->HSLevel[1] = base2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1327,8 +1328,10 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case SE_AssassinateLevel: {
|
case SE_AssassinateLevel: {
|
||||||
if (newbon->AssassinateLevel < base1)
|
if (newbon->AssassinateLevel[0] < base1) {
|
||||||
newbon->AssassinateLevel = base1;
|
newbon->AssassinateLevel[0] = base1;
|
||||||
|
newbon->AssassinateLevel[1] = base2;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1386,7 +1389,7 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case SE_MeleeMitigation:
|
case SE_MeleeMitigation:
|
||||||
newbon->MeleeMitigationEffect -= base1;
|
newbon->MeleeMitigationEffect += base1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_ATK:
|
case SE_ATK:
|
||||||
@ -1929,8 +1932,8 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_MeleeMitigation:
|
case SE_MeleeMitigation:
|
||||||
//for some reason... this value is negative for increased mitigation
|
// This value is negative because it counteracts another SPA :P
|
||||||
new_bonus->MeleeMitigationEffect -= effect_value;
|
new_bonus->MeleeMitigationEffect += effect_value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_CriticalHitChance:
|
case SE_CriticalHitChance:
|
||||||
@ -3026,8 +3029,10 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
|||||||
|
|
||||||
case SE_HeadShotLevel:
|
case SE_HeadShotLevel:
|
||||||
{
|
{
|
||||||
if(new_bonus->HSLevel < effect_value)
|
if(new_bonus->HSLevel[0] < effect_value) {
|
||||||
new_bonus->HSLevel = effect_value;
|
new_bonus->HSLevel[0] = effect_value;
|
||||||
|
new_bonus->HSLevel[1] = base2;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3042,8 +3047,10 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
|||||||
|
|
||||||
case SE_AssassinateLevel:
|
case SE_AssassinateLevel:
|
||||||
{
|
{
|
||||||
if(new_bonus->AssassinateLevel < effect_value)
|
if(new_bonus->AssassinateLevel[0] < effect_value) {
|
||||||
new_bonus->AssassinateLevel = effect_value;
|
new_bonus->AssassinateLevel[0] = effect_value;
|
||||||
|
new_bonus->AssassinateLevel[1] = base2;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4649,9 +4656,12 @@ void Mob::NegateSpellsBonuses(uint16 spell_id)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_HeadShotLevel:
|
case SE_HeadShotLevel:
|
||||||
spellbonuses.HSLevel = effect_value;
|
spellbonuses.HSLevel[0] = effect_value;
|
||||||
aabonuses.HSLevel = effect_value;
|
aabonuses.HSLevel[0] = effect_value;
|
||||||
itembonuses.HSLevel = effect_value;
|
itembonuses.HSLevel[0] = effect_value;
|
||||||
|
spellbonuses.HSLevel[1] = effect_value;
|
||||||
|
aabonuses.HSLevel[1] = effect_value;
|
||||||
|
itembonuses.HSLevel[1] = effect_value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_Assassinate:
|
case SE_Assassinate:
|
||||||
@ -4664,9 +4674,12 @@ void Mob::NegateSpellsBonuses(uint16 spell_id)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_AssassinateLevel:
|
case SE_AssassinateLevel:
|
||||||
spellbonuses.AssassinateLevel = effect_value;
|
spellbonuses.AssassinateLevel[0] = effect_value;
|
||||||
aabonuses.AssassinateLevel = effect_value;
|
aabonuses.AssassinateLevel[0] = effect_value;
|
||||||
itembonuses.AssassinateLevel = effect_value;
|
itembonuses.AssassinateLevel[0] = effect_value;
|
||||||
|
spellbonuses.AssassinateLevel[1] = effect_value;
|
||||||
|
aabonuses.AssassinateLevel[1] = effect_value;
|
||||||
|
itembonuses.AssassinateLevel[1] = effect_value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_FinishingBlow:
|
case SE_FinishingBlow:
|
||||||
|
|||||||
147
zone/bot.cpp
147
zone/bot.cpp
@ -3701,24 +3701,24 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
|
|||||||
|
|
||||||
// calculate attack_skill and skillinuse depending on hand and weapon
|
// calculate attack_skill and skillinuse depending on hand and weapon
|
||||||
// also send Packet to near clients
|
// also send Packet to near clients
|
||||||
EQEmu::skills::SkillType skillinuse;
|
DamageHitInfo my_hit;
|
||||||
AttackAnimation(skillinuse, Hand, weapon);
|
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, skillinuse);
|
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
|
/// Now figure out damage
|
||||||
int damage = 0;
|
my_hit.damage_done =0;
|
||||||
uint8 mylevel = GetLevel() ? GetLevel() : 1;
|
uint8 mylevel = GetLevel() ? GetLevel() : 1;
|
||||||
uint32 hate = 0;
|
uint32 hate = 0;
|
||||||
if (weapon)
|
if (weapon)
|
||||||
hate = (weapon->GetItem()->Damage + weapon->GetItem()->ElemDmgAmt);
|
hate = (weapon->GetItem()->Damage + weapon->GetItem()->ElemDmgAmt);
|
||||||
|
|
||||||
int weapon_damage = GetWeaponDamage(other, weapon, &hate);
|
my_hit.base_damage = GetWeaponDamage(other, weapon, &hate);
|
||||||
if (hate == 0 && weapon_damage > 1)
|
if (hate == 0 && my_hit.base_damage > 1)
|
||||||
hate = weapon_damage;
|
hate = my_hit.base_damage;
|
||||||
|
|
||||||
//if weapon damage > 0 then we know we can hit the target with this weapon
|
//if weapon damage > 0 then we know we can hit the target with this weapon
|
||||||
//otherwise we cannot and we set the damage to -5 later on
|
//otherwise we cannot and we set the damage to -5 later on
|
||||||
if(weapon_damage > 0) {
|
if (my_hit.base_damage > 0) {
|
||||||
int min_damage = 0;
|
my_hit.min_damage = 0;
|
||||||
|
|
||||||
// ***************************************************************
|
// ***************************************************************
|
||||||
// *** Calculate the damage bonus, if applicable, for this hit ***
|
// *** Calculate the damage bonus, if applicable, for this hit ***
|
||||||
@ -3736,7 +3736,7 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
|
|||||||
// Damage bonuses apply only to hits from the main hand (Hand == MainPrimary) by characters level 28 and above
|
// Damage bonuses apply only to hits from the main hand (Hand == MainPrimary) by characters level 28 and above
|
||||||
// who belong to a melee class. If we're here, then all of these conditions apply.
|
// who belong to a melee class. If we're here, then all of these conditions apply.
|
||||||
ucDamageBonus = GetWeaponDamageBonus(weapon ? weapon->GetItem() : (const EQEmu::ItemData*) nullptr);
|
ucDamageBonus = GetWeaponDamageBonus(weapon ? weapon->GetItem() : (const EQEmu::ItemData*) nullptr);
|
||||||
min_damage = ucDamageBonus;
|
my_hit.min_damage = ucDamageBonus;
|
||||||
hate += ucDamageBonus;
|
hate += ucDamageBonus;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -3744,55 +3744,29 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
|
|||||||
if (Hand == EQEmu::inventory::slotSecondary) {
|
if (Hand == EQEmu::inventory::slotSecondary) {
|
||||||
if (aabonuses.SecondaryDmgInc || itembonuses.SecondaryDmgInc || spellbonuses.SecondaryDmgInc){
|
if (aabonuses.SecondaryDmgInc || itembonuses.SecondaryDmgInc || spellbonuses.SecondaryDmgInc){
|
||||||
ucDamageBonus = GetWeaponDamageBonus(weapon ? weapon->GetItem() : (const EQEmu::ItemData*) nullptr);
|
ucDamageBonus = GetWeaponDamageBonus(weapon ? weapon->GetItem() : (const EQEmu::ItemData*) nullptr);
|
||||||
min_damage = ucDamageBonus;
|
my_hit.min_damage = ucDamageBonus;
|
||||||
hate += ucDamageBonus;
|
hate += ucDamageBonus;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int min_cap = (weapon_damage * GetMeleeMinDamageMod_SE(skillinuse) / 100);
|
Log.Out(Logs::Detail, Logs::Combat, "Damage calculated: base %d min damage %d skill %d", my_hit.base_damage, my_hit.min_damage, my_hit.skill);
|
||||||
|
|
||||||
Log.Out(Logs::Detail, Logs::Combat, "Damage calculated to %d (bonus %d, base %d, str %d, skill %d, DMG %d, lv %d)",
|
my_hit.offense = offense(my_hit.skill);
|
||||||
damage, min_damage, weapon_damage, GetSTR(), GetSkill(skillinuse), weapon_damage, mylevel);
|
my_hit.hand = Hand;
|
||||||
|
|
||||||
auto offense = this->offense(skillinuse);
|
|
||||||
|
|
||||||
if (opts) {
|
if (opts) {
|
||||||
weapon_damage *= opts->damage_percent;
|
my_hit.base_damage *= opts->damage_percent;
|
||||||
weapon_damage += opts->damage_flat;
|
my_hit.base_damage += opts->damage_flat;
|
||||||
hate *= opts->hate_percent;
|
hate *= opts->hate_percent;
|
||||||
hate += opts->hate_flat;
|
hate += opts->hate_flat;
|
||||||
}
|
}
|
||||||
|
|
||||||
//check to see if we hit..
|
DoAttack(other, my_hit, opts);
|
||||||
if (other->AvoidDamage(this, damage, Hand)) {
|
|
||||||
if (!FromRiposte && !IsStrikethrough) {
|
Log.Out(Logs::Detail, Logs::Combat, "Final damage after all reductions: %d", my_hit.damage_done);
|
||||||
int strike_through = itembonuses.StrikeThrough + spellbonuses.StrikeThrough + aabonuses.StrikeThrough;
|
|
||||||
if(strike_through && zone->random.Roll(strike_through)) {
|
|
||||||
Message_StringID(MT_StrikeThrough, STRIKETHROUGH_STRING); // You strike through your opponents defenses!
|
|
||||||
Attack(other, Hand, false, true); // Strikethrough only gives another attempted hit
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (damage == -3 && !FromRiposte) {
|
|
||||||
DoRiposte(other);
|
|
||||||
if (HasDied())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (other->CheckHitChance(this, skillinuse)) {
|
my_hit.damage_done = DMG_INVULNERABLE;
|
||||||
other->MeleeMitigation(this, damage, weapon_damage, offense, skillinuse, opts);
|
|
||||||
if (damage > 0) {
|
|
||||||
ApplyDamageTable(damage, offense);
|
|
||||||
CommonOutgoingHitSuccess(other, damage, min_damage, min_cap, skillinuse, opts);
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
damage = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Log.Out(Logs::Detail, Logs::Combat, "Final damage after all reductions: %d", damage);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
damage = -5;
|
|
||||||
|
|
||||||
// Hate Generation is on a per swing basis, regardless of a hit, miss, or block, its always the same.
|
// Hate Generation is on a per swing basis, regardless of a hit, miss, or block, its always the same.
|
||||||
// If we are this far, this means we are atleast making a swing.
|
// If we are this far, this means we are atleast making a swing.
|
||||||
@ -3801,14 +3775,14 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
|
|||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
////// Send Attack Damage
|
////// Send Attack Damage
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
other->Damage(this, damage, SPELL_UNKNOWN, skillinuse);
|
other->Damage(this, my_hit.damage_done, SPELL_UNKNOWN, my_hit.skill);
|
||||||
|
|
||||||
if (GetHP() < 0)
|
if (GetHP() < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
MeleeLifeTap(damage);
|
MeleeLifeTap(my_hit.damage_done);
|
||||||
|
|
||||||
if (damage > 0)
|
if (my_hit.damage_done > 0)
|
||||||
CheckNumHitsRemaining(NumHit::OutgoingHitSuccess);
|
CheckNumHitsRemaining(NumHit::OutgoingHitSuccess);
|
||||||
|
|
||||||
CommonBreakInvisibleFromCombat();
|
CommonBreakInvisibleFromCombat();
|
||||||
@ -3816,9 +3790,9 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
|
|||||||
BuffFadeByEffect(SE_NegateIfCombat);
|
BuffFadeByEffect(SE_NegateIfCombat);
|
||||||
|
|
||||||
if(GetTarget())
|
if(GetTarget())
|
||||||
TriggerDefensiveProcs(other, Hand, true, damage);
|
TriggerDefensiveProcs(other, Hand, true, my_hit.damage_done);
|
||||||
|
|
||||||
if (damage > 0)
|
if (my_hit.damage_done > 0)
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
@ -4699,16 +4673,16 @@ int Bot::GetHandToHandDamage(void) {
|
|||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bot::TryFinishingBlow(Mob *defender, EQEmu::skills::SkillType skillinuse, int &damage)
|
bool Bot::TryFinishingBlow(Mob *defender, int &damage)
|
||||||
{
|
{
|
||||||
if (!defender)
|
if (!defender)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (aabonuses.FinishingBlow[1] && !defender->IsClient() && defender->GetHPRatio() < 10) {
|
if (aabonuses.FinishingBlow[1] && !defender->IsClient() && defender->GetHPRatio() < 10) {
|
||||||
int chance = (aabonuses.FinishingBlow[0] / 10);
|
int chance = aabonuses.FinishingBlow[0];
|
||||||
int fb_damage = aabonuses.FinishingBlow[1];
|
int fb_damage = aabonuses.FinishingBlow[1];
|
||||||
int levelreq = aabonuses.FinishingBlowLvl[0];
|
int levelreq = aabonuses.FinishingBlowLvl[0];
|
||||||
if (defender->GetLevel() <= levelreq && (chance >= zone->random.Int(0, 1000))) {
|
if (defender->GetLevel() <= levelreq && (chance >= zone->random.Int(1, 1000))) {
|
||||||
Log.Out(Logs::Detail, Logs::Combat, "Landed a finishing blow: levelreq at %d, other level %d",
|
Log.Out(Logs::Detail, Logs::Combat, "Landed a finishing blow: levelreq at %d, other level %d",
|
||||||
levelreq, defender->GetLevel());
|
levelreq, defender->GetLevel());
|
||||||
entity_list.MessageClose_StringID(this, false, 200, MT_CritMelee, FINISHING_BLOW, GetName());
|
entity_list.MessageClose_StringID(this, false, 200, MT_CritMelee, FINISHING_BLOW, GetName());
|
||||||
@ -4849,36 +4823,29 @@ void Bot::DoSpecialAttackDamage(Mob *who, EQEmu::skills::SkillType skill, int32
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int min_cap = max_damage * GetMeleeMinDamageMod_SE(skill) / 100;
|
DamageHitInfo my_hit;
|
||||||
int hand = EQEmu::inventory::slotPrimary;
|
my_hit.base_damage = max_damage;
|
||||||
int damage = 0;
|
my_hit.min_damage = min_damage;
|
||||||
auto offense = this->offense(skill);
|
my_hit.damage_done = 0;
|
||||||
|
|
||||||
|
my_hit.skill = skill;
|
||||||
|
my_hit.offense = offense(my_hit.skill);
|
||||||
|
my_hit.tohit = GetTotalToHit(my_hit.skill, 0);
|
||||||
|
my_hit.hand = EQEmu::inventory::slotPrimary;
|
||||||
|
|
||||||
if (skill == EQEmu::skills::SkillThrowing || skill == EQEmu::skills::SkillArchery)
|
if (skill == EQEmu::skills::SkillThrowing || skill == EQEmu::skills::SkillArchery)
|
||||||
hand = EQEmu::inventory::slotRange;
|
my_hit.hand = EQEmu::inventory::slotRange;
|
||||||
if (who->AvoidDamage(this, damage, hand)) {
|
|
||||||
if (damage == -3)
|
DoAttack(who, my_hit);
|
||||||
DoRiposte(who);
|
|
||||||
} else {
|
|
||||||
if (HitChance || who->CheckHitChance(this, skill)) {
|
|
||||||
if (max_damage > 0)
|
|
||||||
who->MeleeMitigation(this, damage, max_damage, offense, skill);
|
|
||||||
if (damage > 0) {
|
|
||||||
ApplyDamageTable(damage, offense);
|
|
||||||
CommonOutgoingHitSuccess(who, damage, min_damage, min_cap, skill);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
damage = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
who->AddToHateList(this, hate);
|
who->AddToHateList(this, hate);
|
||||||
|
|
||||||
who->Damage(this, damage, SPELL_UNKNOWN, skill, false);
|
who->Damage(this, my_hit.damage_done, SPELL_UNKNOWN, skill, false);
|
||||||
|
|
||||||
if(!GetTarget() || HasDied())
|
if(!GetTarget() || HasDied())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (damage > 0)
|
if (my_hit.damage_done > 0)
|
||||||
CheckNumHitsRemaining(NumHit::OutgoingHitSuccess);
|
CheckNumHitsRemaining(NumHit::OutgoingHitSuccess);
|
||||||
|
|
||||||
//[AA Dragon Punch] value[0] = 100 for 25%, chance value[1] = skill
|
//[AA Dragon Punch] value[0] = 100 for 25%, chance value[1] = skill
|
||||||
@ -4894,7 +4861,7 @@ void Bot::DoSpecialAttackDamage(Mob *who, EQEmu::skills::SkillType skill, int32
|
|||||||
if (HasSkillProcs())
|
if (HasSkillProcs())
|
||||||
TrySkillProc(who, skill, (ReuseTime * 1000));
|
TrySkillProc(who, skill, (ReuseTime * 1000));
|
||||||
|
|
||||||
if (damage > 0 && HasSkillProcSuccess())
|
if (my_hit.damage_done > 0 && HasSkillProcSuccess())
|
||||||
TrySkillProc(who, skill, (ReuseTime * 1000), true);
|
TrySkillProc(who, skill, (ReuseTime * 1000), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5030,7 +4997,6 @@ void Bot::DoClassAttacks(Mob *target, bool IsRiposte) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
float HasteModifier = (GetHaste() * 0.01f);
|
float HasteModifier = (GetHaste() * 0.01f);
|
||||||
int32 dmg = 0;
|
|
||||||
uint16 skill_to_use = -1;
|
uint16 skill_to_use = -1;
|
||||||
int level = GetLevel();
|
int level = GetLevel();
|
||||||
int reuse = (TauntReuseTime * 1000);
|
int reuse = (TauntReuseTime * 1000);
|
||||||
@ -5084,18 +5050,14 @@ void Bot::DoClassAttacks(Mob *target, bool IsRiposte) {
|
|||||||
if(skill_to_use == -1)
|
if(skill_to_use == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
int dmg = GetBaseSkillDamage(static_cast<EQEmu::skills::SkillType>(skill_to_use), GetTarget());
|
||||||
|
|
||||||
if (skill_to_use == EQEmu::skills::SkillBash) {
|
if (skill_to_use == EQEmu::skills::SkillBash) {
|
||||||
if (target != this) {
|
if (target != this) {
|
||||||
DoAnim(animTailRake);
|
DoAnim(animTailRake);
|
||||||
if (GetWeaponDamage(target, GetBotItem(EQEmu::inventory::slotSecondary)) <= 0 && GetWeaponDamage(target, GetBotItem(EQEmu::inventory::slotShoulders)) <= 0)
|
if (GetWeaponDamage(target, GetBotItem(EQEmu::inventory::slotSecondary)) <= 0 && GetWeaponDamage(target, GetBotItem(EQEmu::inventory::slotShoulders)) <= 0)
|
||||||
dmg = -5;
|
dmg = DMG_INVULNERABLE;
|
||||||
else {
|
|
||||||
if (!target->CheckHitChance(this, EQEmu::skills::SkillBash, 0))
|
|
||||||
dmg = 0;
|
|
||||||
else {
|
|
||||||
dmg = GetBaseSkillDamage(EQEmu::skills::SkillBash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reuse = (BashReuseTime * 1000);
|
reuse = (BashReuseTime * 1000);
|
||||||
DoSpecialAttackDamage(target, EQEmu::skills::SkillBash, dmg, 0, -1, reuse);
|
DoSpecialAttackDamage(target, EQEmu::skills::SkillBash, dmg, 0, -1, reuse);
|
||||||
did_attack = true;
|
did_attack = true;
|
||||||
@ -5104,14 +5066,13 @@ void Bot::DoClassAttacks(Mob *target, bool IsRiposte) {
|
|||||||
|
|
||||||
if (skill_to_use == EQEmu::skills::SkillFrenzy) {
|
if (skill_to_use == EQEmu::skills::SkillFrenzy) {
|
||||||
int AtkRounds = 3;
|
int AtkRounds = 3;
|
||||||
int32 max_dmg = GetBaseSkillDamage(EQEmu::skills::SkillFrenzy);
|
|
||||||
DoAnim(anim2HSlashing);
|
DoAnim(anim2HSlashing);
|
||||||
|
|
||||||
reuse = (FrenzyReuseTime * 1000);
|
reuse = (FrenzyReuseTime * 1000);
|
||||||
did_attack = true;
|
did_attack = true;
|
||||||
while(AtkRounds > 0) {
|
while(AtkRounds > 0) {
|
||||||
if (GetTarget() && (AtkRounds == 1 || zone->random.Int(0, 100) < 75)) {
|
if (GetTarget() && (AtkRounds == 1 || zone->random.Int(0, 100) < 75)) {
|
||||||
DoSpecialAttackDamage(GetTarget(), EQEmu::skills::SkillFrenzy, max_dmg, 0, max_dmg, reuse, true);
|
DoSpecialAttackDamage(GetTarget(), EQEmu::skills::SkillFrenzy, dmg, 0, dmg, reuse, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
AtkRounds--;
|
AtkRounds--;
|
||||||
@ -5122,14 +5083,8 @@ void Bot::DoClassAttacks(Mob *target, bool IsRiposte) {
|
|||||||
if(target != this) {
|
if(target != this) {
|
||||||
DoAnim(animKick);
|
DoAnim(animKick);
|
||||||
if (GetWeaponDamage(target, GetBotItem(EQEmu::inventory::slotFeet)) <= 0)
|
if (GetWeaponDamage(target, GetBotItem(EQEmu::inventory::slotFeet)) <= 0)
|
||||||
dmg = -5;
|
dmg = DMG_INVULNERABLE;
|
||||||
else {
|
|
||||||
if (!target->CheckHitChance(this, EQEmu::skills::SkillKick, 0))
|
|
||||||
dmg = 0;
|
|
||||||
else {
|
|
||||||
dmg = GetBaseSkillDamage(EQEmu::skills::SkillKick);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reuse = (KickReuseTime * 1000);
|
reuse = (KickReuseTime * 1000);
|
||||||
DoSpecialAttackDamage(target, EQEmu::skills::SkillKick, dmg, 0, -1, reuse);
|
DoSpecialAttackDamage(target, EQEmu::skills::SkillKick, dmg, 0, -1, reuse);
|
||||||
did_attack = true;
|
did_attack = true;
|
||||||
|
|||||||
@ -239,7 +239,7 @@ public:
|
|||||||
uint16 BotGetSpellPriority(int spellslot) { return AIspells[spellslot].priority; }
|
uint16 BotGetSpellPriority(int spellslot) { return AIspells[spellslot].priority; }
|
||||||
virtual float GetProcChances(float ProcBonus, uint16 hand);
|
virtual float GetProcChances(float ProcBonus, uint16 hand);
|
||||||
virtual int GetHandToHandDamage(void);
|
virtual int GetHandToHandDamage(void);
|
||||||
virtual bool TryFinishingBlow(Mob *defender, EQEmu::skills::SkillType skillinuse, int &damage);
|
virtual bool TryFinishingBlow(Mob *defender, int &damage);
|
||||||
virtual void DoRiposte(Mob* defender);
|
virtual void DoRiposte(Mob* defender);
|
||||||
inline virtual int32 GetATK() const { return ATK + itembonuses.ATK + spellbonuses.ATK + ((GetSTR() + GetSkill(EQEmu::skills::SkillOffense)) * 9 / 10); }
|
inline virtual int32 GetATK() const { return ATK + itembonuses.ATK + spellbonuses.ATK + ((GetSTR() + GetSkill(EQEmu::skills::SkillOffense)) * 9 / 10); }
|
||||||
inline virtual int32 GetATKBonus() const { return itembonuses.ATK + spellbonuses.ATK; }
|
inline virtual int32 GetATKBonus() const { return itembonuses.ATK + spellbonuses.ATK; }
|
||||||
|
|||||||
@ -35,6 +35,13 @@
|
|||||||
#define CON_YELLOW 15
|
#define CON_YELLOW 15
|
||||||
#define CON_RED 13
|
#define CON_RED 13
|
||||||
|
|
||||||
|
#define DMG_BLOCKED -1
|
||||||
|
#define DMG_PARRIED -2
|
||||||
|
#define DMG_RIPOSTED -3
|
||||||
|
#define DMG_DODGED -4
|
||||||
|
#define DMG_INVULNERABLE -5
|
||||||
|
#define DMG_RUNE -6
|
||||||
|
|
||||||
//Spell specialization parameters, not sure of a better place for them
|
//Spell specialization parameters, not sure of a better place for them
|
||||||
#define SPECIALIZE_FIZZLE 11 //% fizzle chance reduce at 200 specialized
|
#define SPECIALIZE_FIZZLE 11 //% fizzle chance reduce at 200 specialized
|
||||||
#define SPECIALIZE_MANA_REDUCE 12 //% mana cost reduction at 200 specialized
|
#define SPECIALIZE_MANA_REDUCE 12 //% mana cost reduction at 200 specialized
|
||||||
@ -464,9 +471,9 @@ struct StatBonuses {
|
|||||||
int8 CriticalMend; // chance critical monk mend
|
int8 CriticalMend; // chance critical monk mend
|
||||||
int32 ImprovedReclaimEnergy; // Modifies amount of mana returned from reclaim energy
|
int32 ImprovedReclaimEnergy; // Modifies amount of mana returned from reclaim energy
|
||||||
uint32 HeadShot[2]; // Headshot AA (Massive dmg vs humaniod w/ archery) 0= ? 1= Dmg
|
uint32 HeadShot[2]; // Headshot AA (Massive dmg vs humaniod w/ archery) 0= ? 1= Dmg
|
||||||
uint8 HSLevel; // Max Level Headshot will be effective at.
|
uint8 HSLevel[2]; // Max Level Headshot will be effective at. and chance mod
|
||||||
uint32 Assassinate[2]; // Assassinate AA (Massive dmg vs humaniod w/ assassinate) 0= ? 1= Dmg
|
uint32 Assassinate[2]; // Assassinate AA (Massive dmg vs humaniod w/ assassinate) 0= ? 1= Dmg
|
||||||
uint8 AssassinateLevel; // Max Level Assassinate will be effective at.
|
uint8 AssassinateLevel[2]; // Max Level Assassinate will be effective at.
|
||||||
int32 PetMeleeMitigation; // Add AC to owner's pet.
|
int32 PetMeleeMitigation; // Add AC to owner's pet.
|
||||||
bool IllusionPersistence; // Causes illusions not to fade.
|
bool IllusionPersistence; // Causes illusions not to fade.
|
||||||
uint16 extra_xtargets; // extra xtarget entries
|
uint16 extra_xtargets; // extra xtarget entries
|
||||||
@ -644,5 +651,17 @@ struct DamageTable {
|
|||||||
int32 minusfactor; // difficulty of rolling
|
int32 minusfactor; // difficulty of rolling
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct DamageHitInfo {
|
||||||
|
//uint16 attacker; // id
|
||||||
|
//uint16 defender; // id
|
||||||
|
int base_damage;
|
||||||
|
int min_damage;
|
||||||
|
int damage_done;
|
||||||
|
int offense;
|
||||||
|
int tohit;
|
||||||
|
int hand;
|
||||||
|
EQEmu::skills::SkillType skill;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -1270,12 +1270,6 @@ void Lua_Mob::DoSpecialAttackDamage(Lua_Mob other, int skill, int max_damage, in
|
|||||||
self->DoSpecialAttackDamage(other, static_cast<EQEmu::skills::SkillType>(skill), max_damage, min_damage, hate_override, reuse_time);
|
self->DoSpecialAttackDamage(other, static_cast<EQEmu::skills::SkillType>(skill), max_damage, min_damage, hate_override, reuse_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Lua_Mob::DoSpecialAttackDamage(Lua_Mob other, int skill, int max_damage, int min_damage, int hate_override, int reuse_time,
|
|
||||||
bool hit_chance) {
|
|
||||||
Lua_Safe_Call_Void();
|
|
||||||
self->DoSpecialAttackDamage(other, static_cast<EQEmu::skills::SkillType>(skill), max_damage, min_damage, hate_override, reuse_time, hit_chance);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Lua_Mob::DoThrowingAttackDmg(Lua_Mob other) {
|
void Lua_Mob::DoThrowingAttackDmg(Lua_Mob other) {
|
||||||
Lua_Safe_Call_Void();
|
Lua_Safe_Call_Void();
|
||||||
self->DoThrowingAttackDmg(other);
|
self->DoThrowingAttackDmg(other);
|
||||||
@ -2218,7 +2212,6 @@ luabind::scope lua_register_mob() {
|
|||||||
.def("DoSpecialAttackDamage", (void(Lua_Mob::*)(Lua_Mob,int,int,int))&Lua_Mob::DoSpecialAttackDamage)
|
.def("DoSpecialAttackDamage", (void(Lua_Mob::*)(Lua_Mob,int,int,int))&Lua_Mob::DoSpecialAttackDamage)
|
||||||
.def("DoSpecialAttackDamage", (void(Lua_Mob::*)(Lua_Mob,int,int,int,int))&Lua_Mob::DoSpecialAttackDamage)
|
.def("DoSpecialAttackDamage", (void(Lua_Mob::*)(Lua_Mob,int,int,int,int))&Lua_Mob::DoSpecialAttackDamage)
|
||||||
.def("DoSpecialAttackDamage", (void(Lua_Mob::*)(Lua_Mob,int,int,int,int,int))&Lua_Mob::DoSpecialAttackDamage)
|
.def("DoSpecialAttackDamage", (void(Lua_Mob::*)(Lua_Mob,int,int,int,int,int))&Lua_Mob::DoSpecialAttackDamage)
|
||||||
.def("DoSpecialAttackDamage", (void(Lua_Mob::*)(Lua_Mob,int,int,int,int,int,bool))&Lua_Mob::DoSpecialAttackDamage)
|
|
||||||
.def("DoThrowingAttackDmg", (void(Lua_Mob::*)(Lua_Mob))&Lua_Mob::DoThrowingAttackDmg)
|
.def("DoThrowingAttackDmg", (void(Lua_Mob::*)(Lua_Mob))&Lua_Mob::DoThrowingAttackDmg)
|
||||||
.def("DoThrowingAttackDmg", (void(Lua_Mob::*)(Lua_Mob,Lua_ItemInst))&Lua_Mob::DoThrowingAttackDmg)
|
.def("DoThrowingAttackDmg", (void(Lua_Mob::*)(Lua_Mob,Lua_ItemInst))&Lua_Mob::DoThrowingAttackDmg)
|
||||||
.def("DoThrowingAttackDmg", (void(Lua_Mob::*)(Lua_Mob,Lua_ItemInst,Lua_Item))&Lua_Mob::DoThrowingAttackDmg)
|
.def("DoThrowingAttackDmg", (void(Lua_Mob::*)(Lua_Mob,Lua_ItemInst,Lua_Item))&Lua_Mob::DoThrowingAttackDmg)
|
||||||
|
|||||||
@ -267,7 +267,6 @@ public:
|
|||||||
void DoSpecialAttackDamage(Lua_Mob other, int skill, int max_damage, int min_damage);
|
void DoSpecialAttackDamage(Lua_Mob other, int skill, int max_damage, int min_damage);
|
||||||
void DoSpecialAttackDamage(Lua_Mob other, int skill, int max_damage, int min_damage, int hate_override);
|
void DoSpecialAttackDamage(Lua_Mob other, int skill, int max_damage, int min_damage, int hate_override);
|
||||||
void DoSpecialAttackDamage(Lua_Mob other, int skill, int max_damage, int min_damage, int hate_override, int reuse_time);
|
void DoSpecialAttackDamage(Lua_Mob other, int skill, int max_damage, int min_damage, int hate_override, int reuse_time);
|
||||||
void DoSpecialAttackDamage(Lua_Mob other, int skill, int max_damage, int min_damage, int hate_override, int reuse_time, bool hit_chance);
|
|
||||||
void DoThrowingAttackDmg(Lua_Mob other);
|
void DoThrowingAttackDmg(Lua_Mob other);
|
||||||
void DoThrowingAttackDmg(Lua_Mob other, Lua_ItemInst range_weapon);
|
void DoThrowingAttackDmg(Lua_Mob other, Lua_ItemInst range_weapon);
|
||||||
void DoThrowingAttackDmg(Lua_Mob other, Lua_ItemInst range_weapon, Lua_Item item);
|
void DoThrowingAttackDmg(Lua_Mob other, Lua_ItemInst range_weapon, Lua_Item item);
|
||||||
|
|||||||
@ -4426,15 +4426,10 @@ void Merc::DoClassAttacks(Mob *target) {
|
|||||||
if(zone->random.Int(0, 100) > 25) //tested on live, warrior mobs both kick and bash, kick about 75% of the time, casting doesn't seem to make a difference.
|
if(zone->random.Int(0, 100) > 25) //tested on live, warrior mobs both kick and bash, kick about 75% of the time, casting doesn't seem to make a difference.
|
||||||
{
|
{
|
||||||
DoAnim(animKick);
|
DoAnim(animKick);
|
||||||
int32 dmg = 0;
|
int32 dmg = GetBaseSkillDamage(EQEmu::skills::SkillKick);
|
||||||
|
|
||||||
if (GetWeaponDamage(target, (const EQEmu::ItemData*)nullptr) <= 0){
|
if (GetWeaponDamage(target, (const EQEmu::ItemData*)nullptr) <= 0)
|
||||||
dmg = -5;
|
dmg = DMG_INVULNERABLE;
|
||||||
}
|
|
||||||
else{
|
|
||||||
if (target->CheckHitChance(this, EQEmu::skills::SkillKick, 0))
|
|
||||||
dmg = GetBaseSkillDamage(EQEmu::skills::SkillKick, GetTarget());
|
|
||||||
}
|
|
||||||
|
|
||||||
reuse = KickReuseTime * 1000;
|
reuse = KickReuseTime * 1000;
|
||||||
DoSpecialAttackDamage(target, EQEmu::skills::SkillKick, dmg, 1, -1, reuse);
|
DoSpecialAttackDamage(target, EQEmu::skills::SkillKick, dmg, 1, -1, reuse);
|
||||||
@ -4443,15 +4438,10 @@ void Merc::DoClassAttacks(Mob *target) {
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
DoAnim(animTailRake);
|
DoAnim(animTailRake);
|
||||||
int32 dmg = 0;
|
int32 dmg = GetBaseSkillDamage(EQEmu::skills::SkillBash);
|
||||||
|
|
||||||
if (GetWeaponDamage(target, (const EQEmu::ItemData*)nullptr) <= 0){
|
if (GetWeaponDamage(target, (const EQEmu::ItemData*)nullptr) <= 0)
|
||||||
dmg = -5;
|
dmg = DMG_INVULNERABLE;
|
||||||
}
|
|
||||||
else{
|
|
||||||
if (target->CheckHitChance(this, EQEmu::skills::SkillBash, 0))
|
|
||||||
dmg = GetBaseSkillDamage(EQEmu::skills::SkillBash, GetTarget());
|
|
||||||
}
|
|
||||||
|
|
||||||
reuse = BashReuseTime * 1000;
|
reuse = BashReuseTime * 1000;
|
||||||
DoSpecialAttackDamage(target, EQEmu::skills::SkillBash, dmg, 1, -1, reuse);
|
DoSpecialAttackDamage(target, EQEmu::skills::SkillBash, dmg, 1, -1, reuse);
|
||||||
|
|||||||
27
zone/mob.h
27
zone/mob.h
@ -162,21 +162,22 @@ public:
|
|||||||
// 13 = Primary (default), 14 = secondary
|
// 13 = Primary (default), 14 = secondary
|
||||||
virtual bool Attack(Mob* other, int Hand = EQEmu::inventory::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false,
|
virtual bool Attack(Mob* other, int Hand = EQEmu::inventory::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false,
|
||||||
bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr) = 0;
|
bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr) = 0;
|
||||||
|
void DoAttack(Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts = nullptr);
|
||||||
int MonkSpecialAttack(Mob* other, uint8 skill_used);
|
int MonkSpecialAttack(Mob* other, uint8 skill_used);
|
||||||
virtual void TryBackstab(Mob *other,int ReuseTime = 10);
|
virtual void TryBackstab(Mob *other,int ReuseTime = 10);
|
||||||
bool AvoidDamage(Mob* attacker, int &damage, int hand);
|
bool AvoidDamage(Mob *attacker, DamageHitInfo &hit);
|
||||||
int compute_tohit(EQEmu::skills::SkillType skillinuse);
|
int compute_tohit(EQEmu::skills::SkillType skillinuse);
|
||||||
int GetTotalToHit(EQEmu::skills::SkillType skill, int chance_mod); // compute_tohit + spell bonuses
|
int GetTotalToHit(EQEmu::skills::SkillType skill, int chance_mod); // compute_tohit + spell bonuses
|
||||||
int compute_defense();
|
int compute_defense();
|
||||||
int GetTotalDefense(); // compute_defense + spell bonuses
|
int GetTotalDefense(); // compute_defense + spell bonuses
|
||||||
bool CheckHitChance(Mob* attacker, EQEmu::skills::SkillType skillinuse, int chance_mod = 0);
|
bool CheckHitChance(Mob* attacker, DamageHitInfo &hit);
|
||||||
virtual void TryCriticalHit(Mob *defender, uint16 skill, int &damage, int min_damage, ExtraAttackOptions *opts = nullptr);
|
void TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions *opts = nullptr);
|
||||||
void TryPetCriticalHit(Mob *defender, uint16 skill, int &damage);
|
void TryPetCriticalHit(Mob *defender, DamageHitInfo &hit);
|
||||||
virtual bool TryFinishingBlow(Mob *defender, EQEmu::skills::SkillType skillinuse, int &damage);
|
virtual bool TryFinishingBlow(Mob *defender, int &damage);
|
||||||
int TryHeadShot(Mob* defender, EQEmu::skills::SkillType skillInUse);
|
int TryHeadShot(Mob* defender, EQEmu::skills::SkillType skillInUse);
|
||||||
int TryAssassinate(Mob* defender, EQEmu::skills::SkillType skillInUse, uint16 ReuseTime);
|
int TryAssassinate(Mob* defender, EQEmu::skills::SkillType skillInUse);
|
||||||
virtual void DoRiposte(Mob* defender);
|
virtual void DoRiposte(Mob* defender);
|
||||||
void ApplyMeleeDamageBonus(uint16 skill, int &damage,ExtraAttackOptions *opts = nullptr);
|
void ApplyMeleeDamageMods(uint16 skill, int &damage, Mob * defender = nullptr, ExtraAttackOptions *opts = nullptr);
|
||||||
int ACSum();
|
int ACSum();
|
||||||
int offense(EQEmu::skills::SkillType skill);
|
int offense(EQEmu::skills::SkillType skill);
|
||||||
void CalcAC() { mitigation_ac = ACSum(); }
|
void CalcAC() { mitigation_ac = ACSum(); }
|
||||||
@ -184,12 +185,12 @@ public:
|
|||||||
double GetSoftcapReturns();
|
double GetSoftcapReturns();
|
||||||
int GetClassRaceACBonus();
|
int GetClassRaceACBonus();
|
||||||
inline int GetMitigationAC() { return mitigation_ac; }
|
inline int GetMitigationAC() { return mitigation_ac; }
|
||||||
void MeleeMitigation(Mob *attacker, int &damage, int base_damage, int offense, EQEmu::skills::SkillType, ExtraAttackOptions *opts = nullptr);
|
void MeleeMitigation(Mob *attacker, DamageHitInfo &hit, ExtraAttackOptions *opts = nullptr);
|
||||||
double RollD20(double offense, double mitigation); // CALL THIS FROM THE DEFENDER
|
double RollD20(int offense, int mitigation); // CALL THIS FROM THE DEFENDER
|
||||||
bool CombatRange(Mob* other);
|
bool CombatRange(Mob* other);
|
||||||
virtual inline bool IsBerserk() { return false; } // only clients
|
virtual inline bool IsBerserk() { return false; } // only clients
|
||||||
void RogueEvade(Mob *other);
|
void RogueEvade(Mob *other);
|
||||||
void CommonOutgoingHitSuccess(Mob* defender, int &damage, int min_damage, int min_mod, EQEmu::skills::SkillType skillInUse, ExtraAttackOptions *opts = nullptr);
|
void CommonOutgoingHitSuccess(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions *opts = nullptr);
|
||||||
void BreakInvisibleSpells();
|
void BreakInvisibleSpells();
|
||||||
virtual void CancelSneakHide();
|
virtual void CancelSneakHide();
|
||||||
void CommonBreakInvisible();
|
void CommonBreakInvisible();
|
||||||
@ -794,7 +795,7 @@ public:
|
|||||||
|
|
||||||
uint8 GetWeaponDamageBonus(const EQEmu::ItemData* weapon, bool offhand = false);
|
uint8 GetWeaponDamageBonus(const EQEmu::ItemData* weapon, bool offhand = false);
|
||||||
const DamageTable &GetDamageTable() const;
|
const DamageTable &GetDamageTable() const;
|
||||||
void ApplyDamageTable(int &damage, int offense);
|
void ApplyDamageTable(DamageHitInfo &hit);
|
||||||
virtual int GetHandToHandDamage(void);
|
virtual int GetHandToHandDamage(void);
|
||||||
|
|
||||||
bool CanThisClassDoubleAttack(void) const;
|
bool CanThisClassDoubleAttack(void) const;
|
||||||
@ -817,7 +818,7 @@ public:
|
|||||||
int32 AffectMagicalDamage(int32 damage, uint16 spell_id, const bool iBuffTic, Mob* attacker);
|
int32 AffectMagicalDamage(int32 damage, uint16 spell_id, const bool iBuffTic, Mob* attacker);
|
||||||
int32 ReduceAllDamage(int32 damage);
|
int32 ReduceAllDamage(int32 damage);
|
||||||
|
|
||||||
void DoSpecialAttackDamage(Mob *who, EQEmu::skills::SkillType skill, int base_damage, int min_damage = 0, int32 hate_override = -1, int ReuseTime = 10, bool CheckHitChance = false, bool CanAvoid = true);
|
void DoSpecialAttackDamage(Mob *who, EQEmu::skills::SkillType skill, int base_damage, int min_damage = 0, int32 hate_override = -1, int ReuseTime = 10);
|
||||||
virtual void DoThrowingAttackDmg(Mob* other, const EQEmu::ItemInstance* RangeWeapon = nullptr, const EQEmu::ItemData* AmmoItem = nullptr, uint16 weapon_damage = 0, int16 chance_mod = 0, int16 focus = 0, int ReuseTime = 0, uint32 range_id = 0, int AmmoSlot = 0, float speed = 4.0f);
|
virtual void DoThrowingAttackDmg(Mob* other, const EQEmu::ItemInstance* RangeWeapon = nullptr, const EQEmu::ItemData* AmmoItem = nullptr, uint16 weapon_damage = 0, int16 chance_mod = 0, int16 focus = 0, int ReuseTime = 0, uint32 range_id = 0, int AmmoSlot = 0, float speed = 4.0f);
|
||||||
void DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, EQEmu::skills::SkillType skillinuse, int16 chance_mod = 0, int16 focus = 0, bool CanRiposte = false, int ReuseTime = 0);
|
void DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, EQEmu::skills::SkillType skillinuse, int16 chance_mod = 0, int16 focus = 0, bool CanRiposte = false, int ReuseTime = 0);
|
||||||
virtual void DoArcheryAttackDmg(Mob* other, const EQEmu::ItemInstance* RangeWeapon = nullptr, const EQEmu::ItemInstance* Ammo = nullptr, uint16 weapon_damage = 0, int16 chance_mod = 0, int16 focus = 0, int ReuseTime = 0, uint32 range_id = 0, uint32 ammo_id = 0, const EQEmu::ItemData *AmmoItem = nullptr, int AmmoSlot = 0, float speed = 4.0f);
|
virtual void DoArcheryAttackDmg(Mob* other, const EQEmu::ItemInstance* RangeWeapon = nullptr, const EQEmu::ItemInstance* Ammo = nullptr, uint16 weapon_damage = 0, int16 chance_mod = 0, int16 focus = 0, int ReuseTime = 0, uint32 range_id = 0, uint32 ammo_id = 0, const EQEmu::ItemData *AmmoItem = nullptr, int AmmoSlot = 0, float speed = 4.0f);
|
||||||
@ -1187,8 +1188,6 @@ protected:
|
|||||||
void ExecWeaponProc(const EQEmu::ItemInstance* weapon, uint16 spell_id, Mob *on, int level_override = -1);
|
void ExecWeaponProc(const EQEmu::ItemInstance* weapon, uint16 spell_id, Mob *on, int level_override = -1);
|
||||||
virtual float GetProcChances(float ProcBonus, uint16 hand = EQEmu::inventory::slotPrimary);
|
virtual float GetProcChances(float ProcBonus, uint16 hand = EQEmu::inventory::slotPrimary);
|
||||||
virtual float GetDefensiveProcChances(float &ProcBonus, float &ProcChance, uint16 hand = EQEmu::inventory::slotPrimary, Mob *on = nullptr);
|
virtual float GetDefensiveProcChances(float &ProcBonus, float &ProcChance, uint16 hand = EQEmu::inventory::slotPrimary, Mob *on = nullptr);
|
||||||
virtual float GetSpecialProcChances(uint16 hand);
|
|
||||||
virtual float GetAssassinateProcChances(uint16 ReuseTime);
|
|
||||||
virtual float GetSkillProcChances(uint16 ReuseTime, uint16 hand = 0); // hand = MainCharm?
|
virtual float GetSkillProcChances(uint16 ReuseTime, uint16 hand = 0); // hand = MainCharm?
|
||||||
uint16 GetWeaponSpeedbyHand(uint16 hand);
|
uint16 GetWeaponSpeedbyHand(uint16 hand);
|
||||||
int GetWeaponDamage(Mob *against, const EQEmu::ItemData *weapon_item);
|
int GetWeaponDamage(Mob *against, const EQEmu::ItemData *weapon_item);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user