mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 01:11:29 +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:
parent
a50663e0a4
commit
78b15a0214
@ -609,7 +609,7 @@ typedef enum {
|
||||
#define SE_TradeSkillMastery 263 // implemented - lets you raise more than one tradeskill above master.
|
||||
#define SE_HastenedAASkill 264 // implemented
|
||||
#define SE_MasteryofPast 265 // implemented[AA] - Spells less than effect values level can not be fizzled
|
||||
#define SE_ExtraAttackChance 266 // implemented - increase chance to score an extra attack with a 2-Handed Weapon.
|
||||
#define SE_ExtraAttackChance 266 // implemented, @OffBonus, gives your double attacks a percent chance to perform an extra attack with 2-handed primary weapon, base: chance, limit: amt attacks, max: none
|
||||
#define SE_AddPetCommand 267 // implemented - sets command base2 to base1
|
||||
#define SE_ReduceTradeskillFail 268 // implemented - reduces chance to fail with given tradeskill by a percent chance
|
||||
#define SE_MaxBindWound 269 // implemented[AA] - Increase max HP you can bind wound.
|
||||
@ -841,8 +841,8 @@ typedef enum {
|
||||
//#define SE_Ff_DurationMax 495 //
|
||||
#define SE_Critical_Melee_Damage_Mod_Max 496 // implemented - increase or decrease by percent critical damage (not stackable)
|
||||
//#define SE_Ff_FocusCastProcNoBypass 497 //
|
||||
//#define SE_AddExtraAttackPct_1h_Primary 498 //
|
||||
//#define SE_AddExtraAttackPct_1h_Secondary 499 //
|
||||
#define SE_AddExtraAttackPct_1h_Primary 498 // implemented, @OffBonus, gives your double attacks a percent chance to perform an extra attack with 1-handed primary weapon, base: chance, limit: amt attacks, max: none
|
||||
#define SE_AddExtraAttackPct_1h_Secondary 499 //implemented, @OffBonus, gives your double attacks a percent chance to perform an extra attack with 1-handed secondary weapon, base: chance, limit: amt attacks, max: none
|
||||
//#define SE_Fc_CastTimeMod2 500 //
|
||||
//#define SE_Fc_CastTimeAmt 501 //
|
||||
#define SE_Fearstun 502 // implemented - Stun with a max level limit. Normal stun restrictions don't apply.
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user