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)
return 0;
int ret = 0;
std::list<uint32> id_list;
auto iterator = list.begin();
while (iterator != list.end())
{
struct_HateList *h = (*iterator);
++iterator;
if (h && h->entity_on_hatelist && h->entity_on_hatelist != caster)
{
if (caster->CombatRange(h->entity_on_hatelist))
{
id_list.push_back(h->entity_on_hatelist->GetID());
++ret;
int hit_count = 0;
auto it = list.begin();
while (it != list.end() && hit_count < count) {
struct_HateList *h = (*it);
if (h && h->entity_on_hatelist && h->entity_on_hatelist != caster) {
if (caster->CombatRange(h->entity_on_hatelist)) {
++hit_count;
caster->ProcessAttackRounds(h->entity_on_hatelist, opts);
}
}
++it;
}
std::list<uint32>::iterator iter = id_list.begin();
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;
return hit_count;
}
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 DoOffHandAttackRounds(Mob *target, ExtraAttackOptions *opts = nullptr);
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
void SendLevelAppearance();

View File

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