mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 01:11:29 +00:00
Implement duration ramp and war cry with new AA system
Rampage also correctly does a full attack round for classes other than monk and ranger
This commit is contained in:
parent
d5098a56e0
commit
d34b4a786b
15
zone/aa.cpp
15
zone/aa.cpp
@ -1727,3 +1727,18 @@ void Mob::GrantAlternateAdvancementAbility(int aa_id, int points) {
|
|||||||
c->CalcBonuses();
|
c->CalcBonuses();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Mob::CheckAATimer(int timer)
|
||||||
|
{
|
||||||
|
if (timer >= aaTimerMax)
|
||||||
|
return false;
|
||||||
|
if (aa_timers[timer].Enabled()) {
|
||||||
|
if (aa_timers[timer].Check(false)) {
|
||||||
|
aa_timers[timer].Disable();
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|||||||
@ -5056,3 +5056,39 @@ void NPC::SetAttackTimer()
|
|||||||
TimerToUse->SetAtTrigger(std::max(RuleI(Combat, MinHastedDelay), speed), true, true);
|
TimerToUse->SetAtTrigger(std::max(RuleI(Combat, MinHastedDelay), speed), true, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::DoAttackRounds(Mob *target, int hand, bool IsFromSpell)
|
||||||
|
{
|
||||||
|
if (!target)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Attack(target, hand, false, false, IsFromSpell);
|
||||||
|
|
||||||
|
if (CanThisClassDoubleAttack()) {
|
||||||
|
CheckIncreaseSkill(SkillDoubleAttack, target, -10);
|
||||||
|
if (CheckDoubleAttack())
|
||||||
|
Attack(target, hand, false, false, IsFromSpell);
|
||||||
|
if (hand == MainPrimary && GetLevel() >= 60 &&
|
||||||
|
(GetClass() == MONK || GetClass() == WARRIOR || GetClass() == RANGER || GetClass() == BERSERKER) &&
|
||||||
|
CheckDoubleAttack(true))
|
||||||
|
Attack(target, hand, false, false, IsFromSpell);
|
||||||
|
}
|
||||||
|
if (hand == MainPrimary) {
|
||||||
|
auto flurrychance = aabonuses.FlurryChance + spellbonuses.FlurryChance + itembonuses.FlurryChance;
|
||||||
|
if (flurrychance && zone->random.Roll(flurrychance)) {
|
||||||
|
Message_StringID(MT_NPCFlurry, YOU_FLURRY);
|
||||||
|
Attack(target, hand, false, false, IsFromSpell);
|
||||||
|
Attack(target, hand, false, false, IsFromSpell);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto extraattackchance = aabonuses.ExtraAttackChance + spellbonuses.ExtraAttackChance + itembonuses.ExtraAttackChance;
|
||||||
|
if (extraattackchance) {
|
||||||
|
auto wpn = GetInv().GetItem(MainPrimary);
|
||||||
|
if (wpn && (wpn->GetItem()->ItemType == ItemType2HBlunt ||
|
||||||
|
wpn->GetItem()->ItemType == ItemType2HSlash ||
|
||||||
|
wpn->GetItem()->ItemType == ItemType2HPiercing))
|
||||||
|
if (zone->random.Roll(extraattackchance))
|
||||||
|
Attack(target, hand, false, false, IsFromSpell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -226,6 +226,7 @@ public:
|
|||||||
virtual int32 GetMeleeMitDmg(Mob *attacker, int32 damage, int32 minhit, float mit_rating, float atk_rating);
|
virtual int32 GetMeleeMitDmg(Mob *attacker, int32 damage, int32 minhit, float mit_rating, float atk_rating);
|
||||||
virtual void SetAttackTimer();
|
virtual void SetAttackTimer();
|
||||||
float GetQuiverHaste();
|
float GetQuiverHaste();
|
||||||
|
void DoAttackRounds(Mob *target, int hand, bool IsFromSpell = false);
|
||||||
|
|
||||||
void AI_Init();
|
void AI_Init();
|
||||||
void AI_Start(uint32 iMoveDelay = 0);
|
void AI_Start(uint32 iMoveDelay = 0);
|
||||||
|
|||||||
@ -391,74 +391,12 @@ bool Client::Process() {
|
|||||||
}
|
}
|
||||||
else if (auto_attack_target->GetHP() > -10) // -10 so we can watch people bleed in PvP
|
else if (auto_attack_target->GetHP() > -10) // -10 so we can watch people bleed in PvP
|
||||||
{
|
{
|
||||||
//old aa
|
|
||||||
//if(CheckAAEffect(aaEffectRampage))
|
|
||||||
//{
|
|
||||||
// entity_list.AEAttack(this, 30);
|
|
||||||
//} else {
|
|
||||||
Attack(auto_attack_target, MainPrimary); // Kaiyodo - added attacking hand to arguments
|
|
||||||
//}
|
|
||||||
ItemInst *wpn = GetInv().GetItem(MainPrimary);
|
ItemInst *wpn = GetInv().GetItem(MainPrimary);
|
||||||
TryWeaponProc(wpn, auto_attack_target, MainPrimary);
|
TryWeaponProc(wpn, auto_attack_target, MainPrimary);
|
||||||
|
|
||||||
bool tripleAttackSuccess = false;
|
DoAttackRounds(auto_attack_target, MainPrimary);
|
||||||
if( auto_attack_target && CanThisClassDoubleAttack() ) {
|
if (CheckAATimer(aaTimerRampage))
|
||||||
|
entity_list.AEAttack(this, 30);
|
||||||
CheckIncreaseSkill(SkillDoubleAttack, auto_attack_target, -10);
|
|
||||||
if(CheckDoubleAttack()) {
|
|
||||||
//should we allow rampage on double attack?
|
|
||||||
//if(CheckAAEffect(aaEffectRampage)) {
|
|
||||||
// entity_list.AEAttack(this, 30);
|
|
||||||
//} else {
|
|
||||||
Attack(auto_attack_target, MainPrimary, false);
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
//triple attack: rangers, monks, warriors, berserkers over level 60
|
|
||||||
if((((GetClass() == MONK || GetClass() == WARRIOR || GetClass() == RANGER || GetClass() == BERSERKER)
|
|
||||||
&& GetLevel() >= 60) || GetSpecialAbility(SPECATK_TRIPLE))
|
|
||||||
&& CheckDoubleAttack(true))
|
|
||||||
{
|
|
||||||
tripleAttackSuccess = true;
|
|
||||||
Attack(auto_attack_target, MainPrimary, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
//quad attack, does this belong here??
|
|
||||||
if(GetSpecialAbility(SPECATK_QUAD) && CheckDoubleAttack(true))
|
|
||||||
{
|
|
||||||
Attack(auto_attack_target, MainPrimary, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Live AA - Flurry, Rapid Strikes ect (Flurry does not require Triple Attack).
|
|
||||||
int16 flurrychance = aabonuses.FlurryChance + spellbonuses.FlurryChance + itembonuses.FlurryChance;
|
|
||||||
|
|
||||||
if (auto_attack_target && flurrychance)
|
|
||||||
{
|
|
||||||
if(zone->random.Int(0, 99) < flurrychance)
|
|
||||||
{
|
|
||||||
Message_StringID(MT_NPCFlurry, YOU_FLURRY);
|
|
||||||
Attack(auto_attack_target, MainPrimary, false);
|
|
||||||
Attack(auto_attack_target, MainPrimary, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int16 ExtraAttackChanceBonus = spellbonuses.ExtraAttackChance + itembonuses.ExtraAttackChance + aabonuses.ExtraAttackChance;
|
|
||||||
|
|
||||||
if (auto_attack_target && ExtraAttackChanceBonus) {
|
|
||||||
ItemInst *wpn = GetInv().GetItem(MainPrimary);
|
|
||||||
if(wpn){
|
|
||||||
if(wpn->GetItem()->ItemType == ItemType2HSlash ||
|
|
||||||
wpn->GetItem()->ItemType == ItemType2HBlunt ||
|
|
||||||
wpn->GetItem()->ItemType == ItemType2HPiercing )
|
|
||||||
{
|
|
||||||
if(zone->random.Int(0, 99) < ExtraAttackChanceBonus)
|
|
||||||
{
|
|
||||||
Attack(auto_attack_target, MainPrimary, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -500,22 +438,10 @@ bool Client::Process() {
|
|||||||
float random = zone->random.Real(0, 1);
|
float random = zone->random.Real(0, 1);
|
||||||
CheckIncreaseSkill(SkillDualWield, auto_attack_target, -10);
|
CheckIncreaseSkill(SkillDualWield, auto_attack_target, -10);
|
||||||
if (random < DualWieldProbability) { // Max 78% of DW
|
if (random < DualWieldProbability) { // Max 78% of DW
|
||||||
//if(CheckAAEffect(aaEffectRampage)) {
|
|
||||||
// entity_list.AEAttack(this, 30, MainSecondary);
|
|
||||||
//} else {
|
|
||||||
Attack(auto_attack_target, MainSecondary); // Single attack with offhand
|
|
||||||
//}
|
|
||||||
ItemInst *wpn = GetInv().GetItem(MainSecondary);
|
ItemInst *wpn = GetInv().GetItem(MainSecondary);
|
||||||
TryWeaponProc(wpn, auto_attack_target, MainSecondary);
|
TryWeaponProc(wpn, auto_attack_target, MainSecondary);
|
||||||
|
|
||||||
if( CanThisClassDoubleAttack() && CheckDoubleAttack()) {
|
DoAttackRounds(auto_attack_target, MainSecondary);
|
||||||
//if(CheckAAEffect(aaEffectRampage)) {
|
|
||||||
// entity_list.AEAttack(this, 30, MainSecondary);
|
|
||||||
//} else {
|
|
||||||
// if(auto_attack_target && auto_attack_target->GetHP() > -10)
|
|
||||||
Attack(auto_attack_target, MainSecondary); // Single attack with offhand
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -878,7 +878,7 @@ void EntityList::AEBardPulse(Mob *caster, Mob *center, uint16 spell_id, bool aff
|
|||||||
caster->CastToClient()->CheckSongSkillIncrease(spell_id);
|
caster->CastToClient()->CheckSongSkillIncrease(spell_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Dook- Rampage and stuff for clients.
|
// Rampage and stuff for clients. Normal and Duration rampages
|
||||||
//NPCs handle it differently in Mob::Rampage
|
//NPCs handle it differently in Mob::Rampage
|
||||||
void EntityList::AEAttack(Mob *attacker, float dist, int Hand, int count, bool IsFromSpell) {
|
void EntityList::AEAttack(Mob *attacker, float dist, int Hand, int count, bool IsFromSpell) {
|
||||||
//Dook- Will need tweaking, currently no pets or players or horses
|
//Dook- Will need tweaking, currently no pets or players or horses
|
||||||
@ -896,7 +896,10 @@ void EntityList::AEAttack(Mob *attacker, float dist, int Hand, int count, bool I
|
|||||||
&& curmob->GetRace() != 216 && curmob->GetRace() != 472 /* dont attack horses */
|
&& curmob->GetRace() != 216 && curmob->GetRace() != 472 /* dont attack horses */
|
||||||
&& (DistanceSquared(curmob->GetPosition(), attacker->GetPosition()) <= dist2)
|
&& (DistanceSquared(curmob->GetPosition(), attacker->GetPosition()) <= dist2)
|
||||||
) {
|
) {
|
||||||
|
if (!attacker->IsClient() || attacker->GetClass() == MONK || attacker->GetClass() == RANGER)
|
||||||
attacker->Attack(curmob, Hand, false, false, IsFromSpell);
|
attacker->Attack(curmob, Hand, false, false, IsFromSpell);
|
||||||
|
else
|
||||||
|
attacker->CastToClient()->DoAttackRounds(curmob, Hand, IsFromSpell);
|
||||||
hit++;
|
hit++;
|
||||||
if (count != 0 && hit >= count)
|
if (count != 0 && hit >= count)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -971,6 +971,7 @@ public:
|
|||||||
void CalcAABonuses(StatBonuses* newbon);
|
void CalcAABonuses(StatBonuses* newbon);
|
||||||
void ApplyAABonuses(const AA::Rank &rank, StatBonuses* newbon);
|
void ApplyAABonuses(const AA::Rank &rank, StatBonuses* newbon);
|
||||||
void GrantAlternateAdvancementAbility(int aa_id, int points);
|
void GrantAlternateAdvancementAbility(int aa_id, int points);
|
||||||
|
bool CheckAATimer(int timer);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void CommonDamage(Mob* other, int32 &damage, const uint16 spell_id, const SkillUseTypes attack_skill, bool &avoidable, const int8 buffslot, const bool iBuffTic);
|
void CommonDamage(Mob* other, int32 &damage, const uint16 spell_id, const SkillUseTypes attack_skill, bool &avoidable, const int8 buffslot, const bool iBuffTic);
|
||||||
|
|||||||
@ -638,42 +638,23 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
snprintf(effect_desc, _EDLEN, "Group Fear Immunity");
|
snprintf(effect_desc, _EDLEN, "Group Fear Immunity");
|
||||||
#endif
|
#endif
|
||||||
//Added client messages to give some indication this effect is active.
|
//Added client messages to give some indication this effect is active.
|
||||||
uint32 group_id_caster = 0;
|
// Is there a message generated? Too disgusted by raids.
|
||||||
uint32 time = spell.base[i]*10;
|
uint32 time = spell.base[i] * 10 * 1000;
|
||||||
if(caster->IsClient())
|
if (caster->IsClient()) {
|
||||||
{
|
if (caster->IsGrouped()) {
|
||||||
if(caster->IsGrouped())
|
auto group = caster->GetGroup();
|
||||||
{
|
for (int i = 0; i < 6; ++i)
|
||||||
group_id_caster = GetGroup()->GetID();
|
if (group->members[i])
|
||||||
}
|
group->members[i]->aa_timers[aaTimerWarcry].Start(time);
|
||||||
else if(caster->IsRaidGrouped())
|
} else if (caster->IsRaidGrouped()) {
|
||||||
{
|
auto raid = caster->GetRaid();
|
||||||
group_id_caster = (GetRaid()->GetGroup(CastToClient()) == 0xFFFF) ? 0 : (GetRaid()->GetGroup(CastToClient()) + 1);
|
uint32 gid = raid->GetGroup(caster->CastToClient());
|
||||||
|
if (gid < 12)
|
||||||
|
for (int i = 0; i < MAX_RAID_MEMBERS; ++i)
|
||||||
|
if (raid->members[i].member && raid->members[i].GroupNumber == gid)
|
||||||
|
raid->members[i].member->aa_timers[aaTimerWarcry].Start(time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//old aa
|
|
||||||
//if(group_id_caster){
|
|
||||||
// Group *g = entity_list.GetGroupByID(group_id_caster);
|
|
||||||
// uint32 time = spell.base[i]*10;
|
|
||||||
// if(g){
|
|
||||||
// for(int gi=0; gi < 6; gi++){
|
|
||||||
// if(g->members[gi] && g->members[gi]->IsClient())
|
|
||||||
// {
|
|
||||||
// g->members[gi]->CastToClient()->EnableAAEffect(aaEffectWarcry , time);
|
|
||||||
// if (g->members[gi]->GetID() != caster->GetID())
|
|
||||||
// g->members[gi]->Message(13, "You hear the war cry.");
|
|
||||||
// else
|
|
||||||
// Message(13, "You let loose a fierce war cry.");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//else{
|
|
||||||
// CastToClient()->EnableAAEffect(aaEffectWarcry , time);
|
|
||||||
// Message(13, "You let loose a fierce war cry.");
|
|
||||||
//}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2238,9 +2219,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
#ifdef SPELL_EFFECT_SPAM
|
#ifdef SPELL_EFFECT_SPAM
|
||||||
snprintf(effect_desc, _EDLEN, "Duration Rampage");
|
snprintf(effect_desc, _EDLEN, "Duration Rampage");
|
||||||
#endif
|
#endif
|
||||||
//if (caster && caster->IsClient()) { // will tidy this up later so that NPCs can duration ramp from spells too
|
aa_timers[aaTimerRampage].Start(effect_value * 10 * 1000); // Live bug, was suppose to be 1 second per value
|
||||||
// CastToClient()->DurationRampage(effect_value*12);
|
|
||||||
//}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4124,13 +4124,13 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//else if (IsClient() && CastToClient()->CheckAAEffect(aaEffectWarcry)) //old aa
|
else if (CheckAATimer(aaTimerWarcry))
|
||||||
//{
|
{
|
||||||
// Message(13, "Your are immune to fear.");
|
Message(13, "Your are immune to fear.");
|
||||||
// Log.Out(Logs::Detail, Logs::Spells, "Clients has WarCry effect, immune to fear!");
|
Log.Out(Logs::Detail, Logs::Spells, "Clients has WarCry effect, immune to fear!");
|
||||||
// caster->Message_StringID(MT_Shout, IMMUNE_FEAR);
|
caster->Message_StringID(MT_Shout, IMMUNE_FEAR);
|
||||||
// return true;
|
return true;
|
||||||
//}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(IsCharmSpell(spell_id))
|
if(IsCharmSpell(spell_id))
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user