Fix some issues with Rampage/AE Ramp

This commit is contained in:
Michael Cook (mackal) 2015-07-05 02:27:51 -04:00
parent 22efe33f9b
commit fe97af4d89
3 changed files with 30 additions and 34 deletions

View File

@ -535,37 +535,20 @@ int HateList::AreaRampage(Mob *caster, Mob *target, int count, ExtraAttackOption
if (!target || !caster) if (!target || !caster)
return 0; return 0;
int ret = 0; int hit_count = 0;
std::list<uint32> id_list; auto it = list.begin();
auto iterator = list.begin(); while (it != list.end() && hit_count < count) {
while (iterator != list.end()) struct_HateList *h = (*it);
{ if (h && h->entity_on_hatelist && h->entity_on_hatelist != caster) {
struct_HateList *h = (*iterator); if (caster->CombatRange(h->entity_on_hatelist)) {
++iterator; ++hit_count;
if (h && h->entity_on_hatelist && h->entity_on_hatelist != caster) caster->ProcessAttackRounds(h->entity_on_hatelist, opts);
{
if (caster->CombatRange(h->entity_on_hatelist))
{
id_list.push_back(h->entity_on_hatelist->GetID());
++ret;
} }
} }
++it;
} }
std::list<uint32>::iterator iter = id_list.begin(); return hit_count;
while (iter != id_list.end())
{
Mob *cur = entity_list.GetMobID((*iter));
if (cur)
{
for (int i = 0; i < count; ++i) {
caster->Attack(cur, MainPrimary, false, false, false, opts);
}
}
iter++;
}
return ret;
} }
void HateList::SpellCast(Mob *caster, uint32 spell_id, float range, Mob* ae_center) void HateList::SpellCast(Mob *caster, uint32 spell_id, float range, Mob* ae_center)

View File

@ -170,6 +170,16 @@ public:
void DoMainHandAttackRounds(Mob *target, ExtraAttackOptions *opts = nullptr); void DoMainHandAttackRounds(Mob *target, ExtraAttackOptions *opts = nullptr);
void DoOffHandAttackRounds(Mob *target, ExtraAttackOptions *opts = nullptr); void DoOffHandAttackRounds(Mob *target, ExtraAttackOptions *opts = nullptr);
virtual bool CheckDoubleAttack(bool tripleAttack = false); // mob version doesn't use this flag virtual bool CheckDoubleAttack(bool tripleAttack = false); // mob version doesn't use this flag
// inline process for places where we need to do them outside of the AI_Process
void ProcessAttackRounds(Mob *target, ExtraAttackOptions *opts = nullptr)
{
if (target) {
DoMainHandAttackRounds(target, opts);
if (CanThisClassDualWield())
DoOffHandAttackRounds(target, opts);
}
return;
}
//Appearance //Appearance
void SendLevelAppearance(); void SendLevelAppearance();

View File

@ -1103,6 +1103,7 @@ void Mob::AI_Process() {
if(attack_timer.Check()) { if(attack_timer.Check()) {
DoMainHandAttackRounds(target); DoMainHandAttackRounds(target);
bool specialed = false; // NPCs can only do one of these a round
if (GetSpecialAbility(SPECATK_FLURRY)) { if (GetSpecialAbility(SPECATK_FLURRY)) {
int flurry_chance = GetSpecialAbilityParam(SPECATK_FLURRY, 0); int flurry_chance = GetSpecialAbilityParam(SPECATK_FLURRY, 0);
flurry_chance = flurry_chance > 0 ? flurry_chance : RuleI(Combat, NPCFlurryChance); flurry_chance = flurry_chance > 0 ? flurry_chance : RuleI(Combat, NPCFlurryChance);
@ -1134,6 +1135,7 @@ void Mob::AI_Process() {
opts.crit_flat = cur; opts.crit_flat = cur;
Flurry(&opts); Flurry(&opts);
specialed = true;
} }
} }
@ -1154,7 +1156,7 @@ void Mob::AI_Process() {
} }
} }
if (GetSpecialAbility(SPECATK_RAMPAGE)) if (GetSpecialAbility(SPECATK_RAMPAGE) && !specialed)
{ {
int rampage_chance = GetSpecialAbilityParam(SPECATK_RAMPAGE, 0); int rampage_chance = GetSpecialAbilityParam(SPECATK_RAMPAGE, 0);
rampage_chance = rampage_chance > 0 ? rampage_chance : 20; rampage_chance = rampage_chance > 0 ? rampage_chance : 20;
@ -1190,10 +1192,11 @@ void Mob::AI_Process() {
opts.crit_flat = cur; opts.crit_flat = cur;
} }
Rampage(&opts); Rampage(&opts);
specialed = true;
} }
} }
if (GetSpecialAbility(SPECATK_AREA_RAMPAGE)) if (GetSpecialAbility(SPECATK_AREA_RAMPAGE) && !specialed)
{ {
int rampage_chance = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 0); int rampage_chance = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 0);
rampage_chance = rampage_chance > 0 ? rampage_chance : 20; rampage_chance = rampage_chance > 0 ? rampage_chance : 20;
@ -1230,6 +1233,7 @@ void Mob::AI_Process() {
} }
AreaRampage(&opts); AreaRampage(&opts);
specialed = true;
} }
} }
} }
@ -1974,14 +1978,14 @@ bool Mob::Rampage(ExtraAttackOptions *opts)
if (m_target == GetTarget()) if (m_target == GetTarget())
continue; continue;
if (CombatRange(m_target)) { if (CombatRange(m_target)) {
Attack(m_target, MainPrimary, false, false, false, opts); ProcessAttackRounds(m_target, opts);
index_hit++; index_hit++;
} }
} }
} }
if (RuleB(Combat, RampageHitsTarget) && index_hit < rampage_targets) if (RuleB(Combat, RampageHitsTarget) && index_hit < rampage_targets)
Attack(GetTarget(), MainPrimary, false, false, false, opts); ProcessAttackRounds(GetTarget(), opts);
return true; return true;
} }
@ -1999,9 +2003,8 @@ void Mob::AreaRampage(ExtraAttackOptions *opts)
rampage_targets = rampage_targets > 0 ? rampage_targets : 1; rampage_targets = rampage_targets > 0 ? rampage_targets : 1;
index_hit = hate_list.AreaRampage(this, GetTarget(), rampage_targets, opts); index_hit = hate_list.AreaRampage(this, GetTarget(), rampage_targets, opts);
if(index_hit == 0) { if(index_hit == 0)
Attack(GetTarget(), MainPrimary, false, false, false, opts); ProcessAttackRounds(GetTarget(), opts);
}
} }
uint32 Mob::GetLevelCon(uint8 mylevel, uint8 iOtherLevel) { uint32 Mob::GetLevelCon(uint8 mylevel, uint8 iOtherLevel) {