mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-17 03:08:26 +00:00
Implemented SPA 498 and 499 (extra attack chance effects) (#1475)
* Implemented SPA 498 and 499 Implemented SE_AddExtraAttackPct_1h_Primary 498 , gives your double attacks a percent chance to perform an extra attack with 1-handed primary weapon, base: chance, limit: amt attacks max: none SE_AddExtraAttackPct_1h_Secondary 499 gives your double attacks a percent chance to perform an extra attack with 1-handed secondary weapon, base: chance, limit: amt attacks max: none Added limit functionality to similar effect SPA 266 SPA 266 will now be calculated to take highest percent value when applying bonus. (was additive, which does not seem correct based on AA data) * Update attack.cpp code update * Update bonuses.cpp code update * Update spdat.h added commas * Update spell_effects.cpp fix to remove unknown spa message Co-authored-by: Michael Cook (mackal) <mcook@mackal.net>
This commit is contained in:
+33
-6
@@ -5483,13 +5483,40 @@ void Client::DoAttackRounds(Mob *target, int hand, bool IsFromSpell)
|
||||
CheckIncreaseSkill(EQ::skills::SkillDoubleAttack, target, -10);
|
||||
if (CheckDoubleAttack()) {
|
||||
Attack(target, hand, false, false, IsFromSpell);
|
||||
|
||||
// Modern AA description: Increases your chance of ... performing one additional hit with a 2-handed weapon when double attacking by 2%.
|
||||
|
||||
if (hand == EQ::invslot::slotPrimary) {
|
||||
auto extraattackchance = aabonuses.ExtraAttackChance + spellbonuses.ExtraAttackChance +
|
||||
itembonuses.ExtraAttackChance;
|
||||
if (extraattackchance && HasTwoHanderEquipped() && zone->random.Roll(extraattackchance))
|
||||
Attack(target, hand, false, false, IsFromSpell);
|
||||
|
||||
if (HasTwoHanderEquipped()) {
|
||||
auto extraattackchance = aabonuses.ExtraAttackChance[0] + spellbonuses.ExtraAttackChance[0] +
|
||||
itembonuses.ExtraAttackChance[0];
|
||||
if (extraattackchance && zone->random.Roll(extraattackchance)) {
|
||||
auto extraattackamt = std::max({ aabonuses.ExtraAttackChance[1], spellbonuses.ExtraAttackChance[1], itembonuses.ExtraAttackChance[1] });
|
||||
for (int i = 0; i < extraattackamt; i++) {
|
||||
Attack(target, hand, false, false, IsFromSpell);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
auto extraattackchance_primary = aabonuses.ExtraAttackChancePrimary[0] + spellbonuses.ExtraAttackChancePrimary[0] +
|
||||
itembonuses.ExtraAttackChancePrimary[0];
|
||||
if (extraattackchance_primary && zone->random.Roll(extraattackchance_primary)) {
|
||||
auto extraattackamt_primary = std::max({ aabonuses.ExtraAttackChancePrimary[1], spellbonuses.ExtraAttackChancePrimary[1], itembonuses.ExtraAttackChancePrimary[1] });
|
||||
for (int i = 0; i < extraattackamt_primary; i++) {
|
||||
Attack(target, hand, false, false, IsFromSpell);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hand == EQ::invslot::slotSecondary) {
|
||||
auto extraattackchance_secondary = aabonuses.ExtraAttackChanceSecondary[0] + spellbonuses.ExtraAttackChanceSecondary[0] +
|
||||
itembonuses.ExtraAttackChanceSecondary[0];
|
||||
if (extraattackchance_secondary && zone->random.Roll(extraattackchance_secondary)) {
|
||||
auto extraattackamt_secondary = std::max({ aabonuses.ExtraAttackChanceSecondary[1], spellbonuses.ExtraAttackChanceSecondary[1], itembonuses.ExtraAttackChanceSecondary[1] });
|
||||
for (int i = 0; i < extraattackamt_secondary; i++) {
|
||||
Attack(target, hand, false, false, IsFromSpell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// you can only triple from the main hand
|
||||
|
||||
+81
-8
@@ -860,9 +860,6 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
||||
case SE_MaxBindWound:
|
||||
newbon->MaxBindWound += base1;
|
||||
break;
|
||||
case SE_ExtraAttackChance:
|
||||
newbon->ExtraAttackChance += base1;
|
||||
break;
|
||||
case SE_SeeInvis:
|
||||
newbon->SeeInvis = base1;
|
||||
break;
|
||||
@@ -984,7 +981,6 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
||||
case SE_BlockBehind:
|
||||
newbon->BlockBehind += base1;
|
||||
break;
|
||||
|
||||
case SE_StrikeThrough:
|
||||
case SE_StrikeThrough2:
|
||||
newbon->StrikeThrough += base1;
|
||||
@@ -1572,6 +1568,34 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
||||
newbon->Pet_Add_Atk += base1;
|
||||
break;
|
||||
|
||||
case SE_ExtraAttackChance:
|
||||
{
|
||||
if (newbon->ExtraAttackChance[0] < base1) {
|
||||
newbon->ExtraAttackChance[0] = base1;
|
||||
newbon->ExtraAttackChance[1] = base2 ? base2 : 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_AddExtraAttackPct_1h_Primary:
|
||||
{
|
||||
if (newbon->ExtraAttackChancePrimary[0] < base1) {
|
||||
newbon->ExtraAttackChancePrimary[0] = base1;
|
||||
newbon->ExtraAttackChancePrimary[1] = base2 ? base2 : 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_AddExtraAttackPct_1h_Secondary:
|
||||
{
|
||||
|
||||
if (newbon->ExtraAttackChanceSecondary[0] < base1) {
|
||||
newbon->ExtraAttackChanceSecondary[0] = base1;
|
||||
newbon->ExtraAttackChanceSecondary[1] = base2 ? base2 : 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// to do
|
||||
case SE_PetDiscipline:
|
||||
break;
|
||||
@@ -2382,8 +2406,45 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
||||
}
|
||||
|
||||
case SE_ExtraAttackChance:
|
||||
new_bonus->ExtraAttackChance += effect_value;
|
||||
{
|
||||
if (AdditiveWornBonus) {
|
||||
new_bonus->ExtraAttackChance[0] += effect_value;
|
||||
new_bonus->ExtraAttackChance[1] = base2 ? base2 : 1;
|
||||
}
|
||||
if (new_bonus->ExtraAttackChance[0] < effect_value) {
|
||||
new_bonus->ExtraAttackChance[0] = effect_value;
|
||||
new_bonus->ExtraAttackChance[1] = base2 ? base2 : 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_AddExtraAttackPct_1h_Primary:
|
||||
{
|
||||
if (AdditiveWornBonus) {
|
||||
new_bonus->ExtraAttackChancePrimary[0] += effect_value;
|
||||
new_bonus->ExtraAttackChancePrimary[1] = base2 ? base2 : 1;
|
||||
}
|
||||
|
||||
if (new_bonus->ExtraAttackChancePrimary[0] < effect_value) {
|
||||
new_bonus->ExtraAttackChancePrimary[0] = effect_value;
|
||||
new_bonus->ExtraAttackChancePrimary[1] = base2 ? base2 : 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_AddExtraAttackPct_1h_Secondary:
|
||||
{
|
||||
if (AdditiveWornBonus) {
|
||||
new_bonus->ExtraAttackChanceSecondary[0] += effect_value;
|
||||
new_bonus->ExtraAttackChanceSecondary[1] = base2 ? base2 : 1;
|
||||
}
|
||||
|
||||
if (new_bonus->ExtraAttackChanceSecondary[0] < effect_value) {
|
||||
new_bonus->ExtraAttackChanceSecondary[0] = effect_value;
|
||||
new_bonus->ExtraAttackChanceSecondary[1] = base2 ? base2 : 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_PercentXPIncrease:
|
||||
{
|
||||
@@ -4302,9 +4363,21 @@ void Mob::NegateSpellsBonuses(uint16 spell_id)
|
||||
break;
|
||||
|
||||
case SE_ExtraAttackChance:
|
||||
spellbonuses.ExtraAttackChance = effect_value;
|
||||
aabonuses.ExtraAttackChance = effect_value;
|
||||
itembonuses.ExtraAttackChance = effect_value;
|
||||
spellbonuses.ExtraAttackChance[0] = effect_value;
|
||||
aabonuses.ExtraAttackChance[0] = effect_value;
|
||||
itembonuses.ExtraAttackChance[0] = effect_value;
|
||||
break;
|
||||
|
||||
case SE_AddExtraAttackPct_1h_Primary:
|
||||
spellbonuses.ExtraAttackChancePrimary[0] = effect_value;
|
||||
aabonuses.ExtraAttackChancePrimary[0] = effect_value;
|
||||
itembonuses.ExtraAttackChancePrimary[0] = effect_value;
|
||||
break;
|
||||
|
||||
case SE_AddExtraAttackPct_1h_Secondary:
|
||||
spellbonuses.ExtraAttackChanceSecondary[0] = effect_value;
|
||||
aabonuses.ExtraAttackChanceSecondary[0] = effect_value;
|
||||
itembonuses.ExtraAttackChanceSecondary[0] = effect_value;
|
||||
break;
|
||||
|
||||
case SE_PercentXPIncrease:
|
||||
|
||||
+3
-1
@@ -446,7 +446,9 @@ struct StatBonuses {
|
||||
int32 MinDamageModifier[EQ::skills::HIGHEST_SKILL + 2]; //i
|
||||
int32 ProcChance; // ProcChance/10 == % increase i = CombatEffects
|
||||
int32 ProcChanceSPA; // ProcChance from spell effects
|
||||
int32 ExtraAttackChance;
|
||||
int32 ExtraAttackChance[2]; // base chance(w/ 2H weapon)=0, amt of extra attacks=1
|
||||
int32 ExtraAttackChancePrimary[2]; // base chance=0, , amt of extra attacks=1
|
||||
int32 ExtraAttackChanceSecondary[2]; // base chance=0, , amt of extra attacks=1
|
||||
int32 DoTShielding;
|
||||
int32 DivineSaveChance[2]; // Second Chance (base1 = chance, base2 = spell on trigger)
|
||||
uint32 DeathSave[4]; // Death Pact [0](value = 1 partial 2 = full) [1]=slot [2]=LvLimit [3]=HealAmt
|
||||
|
||||
@@ -572,7 +572,7 @@ int32 Lua_StatBonuses::GetProcChanceSPA() const {
|
||||
|
||||
int32 Lua_StatBonuses::GetExtraAttackChance() const {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->ExtraAttackChance;
|
||||
return self->ExtraAttackChance[0];
|
||||
}
|
||||
|
||||
int32 Lua_StatBonuses::GetDoTShielding() const {
|
||||
|
||||
+1
-1
@@ -1624,7 +1624,7 @@ void Merc::AI_Process() {
|
||||
}
|
||||
}
|
||||
|
||||
int16 ExtraAttackChanceBonus = spellbonuses.ExtraAttackChance + itembonuses.ExtraAttackChance + aabonuses.ExtraAttackChance;
|
||||
int16 ExtraAttackChanceBonus = spellbonuses.ExtraAttackChance[0] + itembonuses.ExtraAttackChance[0] + aabonuses.ExtraAttackChance[0];
|
||||
|
||||
if (GetTarget() && ExtraAttackChanceBonus) {
|
||||
if(zone->random.Roll(ExtraAttackChanceBonus))
|
||||
|
||||
@@ -3214,6 +3214,8 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
case SE_Fc_Cast_Spell_On_Land:
|
||||
case SE_Ff_CasterClass:
|
||||
case SE_Ff_Same_Caster:
|
||||
case SE_AddExtraAttackPct_1h_Primary:
|
||||
case SE_AddExtraAttackPct_1h_Secondary:
|
||||
case SE_Skill_Base_Damage_Mod:
|
||||
{
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user