diff --git a/zone/MobAI.cpp b/zone/MobAI.cpp index ca25b8fd9..7a1405656 100644 --- a/zone/MobAI.cpp +++ b/zone/MobAI.cpp @@ -491,7 +491,7 @@ void Mob::AI_Start(uint32 iMoveDelay) { pAggroRange = 70; if (GetAssistRange() == 0) pAssistRange = 70; - hate_list.Wipe(); + hate_list.clear(); delta_heading = 0; delta_x = 0; @@ -548,7 +548,7 @@ void Mob::AI_Stop() { safe_delete(AItarget_check_timer) safe_delete(AIscanarea_timer); safe_delete(AIfeignremember_timer); - hate_list.Wipe(); + hate_list.clear(); } void NPC::AI_Stop() { @@ -784,12 +784,12 @@ void Client::AI_Process() if (engaged) { if (IsRooted()) - SetTarget(hate_list.GetClosest(this)); + SetTarget(hate_list.getClosest(this)); else { if(AItarget_check_timer->Check()) { - SetTarget(hate_list.GetTop(this)); + SetTarget(hate_list.getHighestHate(this)); } } @@ -1057,18 +1057,18 @@ void Mob::AI_Process() { if (engaged) { if (IsRooted()) - SetTarget(hate_list.GetClosest(this)); + SetTarget(hate_list.getClosest(this)); else { if(AItarget_check_timer->Check()) { if (IsFocused()) { if (!target) { - SetTarget(hate_list.GetTop(this)); + SetTarget(hate_list.getHighestHate(this)); } } else { if (!ImprovedTaunt()) - SetTarget(hate_list.GetTop(this)); + SetTarget(hate_list.getHighestHate(this)); } } @@ -1334,7 +1334,7 @@ void Mob::AI_Process() { //underwater stuff only works with water maps in the zone! if(IsNPC() && CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) { if(!zone->watermap->InLiquid(target->GetX(), target->GetY(), target->GetZ())) { - Mob *tar = hate_list.GetTop(this); + Mob *tar = hate_list.getHighestHate(this); if(tar == target) { WipeHateList(); Heal(); diff --git a/zone/attack.cpp b/zone/attack.cpp index 26d879fc2..ff9b1f965 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -1553,7 +1553,7 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes att } entity_list.RemoveFromTargets(this); - hate_list.RemoveEnt(this); + hate_list.clear(this); RemoveAutoXTargets(); @@ -2142,12 +2142,12 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack if (killerMob) { if(GetClass() != LDON_TREASURE) - hate_list.Add(killerMob, damage); + hate_list.add(killerMob, damage); } safe_delete(app); - Mob *give_exp = hate_list.GetDamageTop(this); + Mob *give_exp = hate_list.getHighestDamage(this); if(give_exp == nullptr) give_exp = killer; @@ -2526,7 +2526,7 @@ void Mob::AddToHateList(Mob* other, int32 hate, int32 damage, bool iYellForHelp, && other && (buffs[spellbonuses.ImprovedTaunt[2]].casterid != other->GetID())) hate = (hate*spellbonuses.ImprovedTaunt[1])/100; - hate_list.Add(other, hate, damage, bFrenzy, !iBuffTic); + hate_list.add(other, hate, damage, bFrenzy, !iBuffTic); if(other->IsClient()) other->CastToClient()->AddAutoXTarget(this); @@ -2537,8 +2537,8 @@ void Mob::AddToHateList(Mob* other, int32 hate, int32 damage, bool iYellForHelp, AddFeignMemory(other->CastToMerc()->GetMercOwner()->CastToClient()); } else { - if(!hate_list.IsOnHateList(other->CastToMerc()->GetMercOwner())) - hate_list.Add(other->CastToMerc()->GetMercOwner(), 0, 0, false, true); + if(!hate_list.isHated(other->CastToMerc()->GetMercOwner())) + hate_list.add(other->CastToMerc()->GetMercOwner(), 0, 0, false, true); } } //MERC @@ -2553,7 +2553,7 @@ void Mob::AddToHateList(Mob* other, int32 hate, int32 damage, bool iYellForHelp, // owner must get on list, but he's not actually gained any hate yet if(!owner->GetSpecialAbility(IMMUNE_AGGRO)) { - hate_list.Add(owner, 0, 0, false, !iBuffTic); + hate_list.add(owner, 0, 0, false, !iBuffTic); if(owner->IsClient()) owner->CastToClient()->AddAutoXTarget(this); } @@ -2562,10 +2562,10 @@ void Mob::AddToHateList(Mob* other, int32 hate, int32 damage, bool iYellForHelp, if (mypet && (!(GetAA(aaPetDiscipline) && mypet->IsHeld()))) { // I have a pet, add other to it if(!mypet->IsFamiliar() && !mypet->GetSpecialAbility(IMMUNE_AGGRO)) - mypet->hate_list.Add(other, 0, 0, bFrenzy); + mypet->hate_list.add(other, 0, 0, bFrenzy); } else if (myowner) { // I am a pet, add other to owner if it's NPC/LD if (myowner->IsAIControlled() && !myowner->GetSpecialAbility(IMMUNE_AGGRO)) - myowner->hate_list.Add(other, 0, 0, bFrenzy); + myowner->hate_list.add(other, 0, 0, bFrenzy); } if (!wasengaged) { if(IsNPC() && other->IsClient() && other->CastToClient()) diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 3804293a5..7320bbabb 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -3550,7 +3550,7 @@ void Client::Handle_OP_DeleteSpawn(const EQApplicationPacket *app) entity_list.QueueClients(this, outapp, false); safe_delete(outapp); - hate_list.RemoveEnt(this->CastToMob()); + hate_list.clear(this->CastToMob()); Disconnect(); return; diff --git a/zone/hate_list.cpp b/zone/hate_list.cpp index d158b258d..b559c7c83 100644 --- a/zone/hate_list.cpp +++ b/zone/hate_list.cpp @@ -31,122 +31,112 @@ extern Zone *zone; -HateList::HateList() +HateList::HateList() : mOwner(nullptr) { } +HateList::~HateList() { } + + +void HateList::clear() { - owner = nullptr; -} - -HateList::~HateList() -{ -} - - -void HateList::Wipe() -{ - auto iterator = list.begin(); - - while(iterator != list.end()) + auto i = mEntries.begin(); + while(i != mEntries.end()) { - Mob* m = (*iterator)->ent; + Mob* m = (*i)->mMOB; if(m) { - parse->EventNPC(EVENT_HATE_LIST, owner->CastToNPC(), m, "0", 0); + parse->EventNPC(EVENT_HATE_LIST, mOwner->CastToNPC(), m, "0", 0); if(m->IsClient()) m->CastToClient()->DecrementAggroCount(); } - delete (*iterator); - iterator = list.erase(iterator); - + delete (*i); + i = mEntries.erase(i); } } -bool HateList::IsOnHateList(Mob *mob) +bool HateList::isHated(Mob* pMOB) { - if(Find(mob)) - return true; - return false; + return find(pMOB) != nullptr; } -tHateEntry *HateList::Find(Mob *ent) +HateEntry* HateList::find(Mob* pMOB) { - auto iterator = list.begin(); - while(iterator != list.end()) - { - if((*iterator)->ent == ent) - return (*iterator); - ++iterator; - } + for (auto i = mEntries.begin(); i != mEntries.end(); i++) + if ((*i)->mMOB == pMOB) return *i; return nullptr; } -void HateList::Set(Mob* other, uint32 in_hate, uint32 in_dam) +void HateList::set(Mob* pMob, uint32 pHate, uint32 pDamage) { - tHateEntry *p = Find(other); - if(p) + HateEntry *entry = find(pMob); + if (entry) { - if(in_dam > 0) - p->damage = in_dam; - if(in_hate > 0) - p->hate = in_hate; + if(pDamage > 0) + entry->mDamage = pDamage; + if(pHate > 0) + entry->mHate = pHate; } } -Mob* HateList::GetDamageTop(Mob* hater) +Mob* HateList::getHighestDamage(Mob* hater) { + /* + This is called in NPC::Death + It calls this on it's own HateList, passing itself as the hater parameter. + -- Under the circumstances where there were 40 people in a raid it would calculate the total raid damage 80 times. + */ Mob* current = nullptr; Group* grp = nullptr; Raid* r = nullptr; uint32 dmg_amt = 0; - auto iterator = list.begin(); - while(iterator != list.end()) + auto iterator = mEntries.begin(); + while(iterator != mEntries.end()) { grp = nullptr; r = nullptr; - if((*iterator)->ent && (*iterator)->ent->IsClient()){ - r = entity_list.GetRaidByClient((*iterator)->ent->CastToClient()); + if((*iterator)->mMOB && (*iterator)->mMOB->IsClient()){ + r = entity_list.GetRaidByClient((*iterator)->mMOB->CastToClient()); } - grp = entity_list.GetGroupByMob((*iterator)->ent); + grp = entity_list.GetGroupByMob((*iterator)->mMOB); - if((*iterator)->ent && r){ + if((*iterator)->mMOB && r){ if(r->GetTotalRaidDamage(hater) >= dmg_amt) { - current = (*iterator)->ent; + current = (*iterator)->mMOB; dmg_amt = r->GetTotalRaidDamage(hater); } } - else if ((*iterator)->ent != nullptr && grp != nullptr) + else if ((*iterator)->mMOB != nullptr && grp != nullptr) { if (grp->GetTotalGroupDamage(hater) >= dmg_amt) { - current = (*iterator)->ent; + current = (*iterator)->mMOB; dmg_amt = grp->GetTotalGroupDamage(hater); } } - else if ((*iterator)->ent != nullptr && (uint32)(*iterator)->damage >= dmg_amt) + else if ((*iterator)->mMOB != nullptr && (uint32)(*iterator)->mDamage >= dmg_amt) { - current = (*iterator)->ent; - dmg_amt = (*iterator)->damage; + current = (*iterator)->mMOB; + dmg_amt = (*iterator)->mDamage; } ++iterator; } return current; } -Mob* HateList::GetClosest(Mob *hater) { +Mob* HateList::getClosest(Mob *hater) { Mob* close = nullptr; float closedist = 99999.9f; float thisdist; - auto iterator = list.begin(); - while(iterator != list.end()) { - thisdist = (*iterator)->ent->DistNoRootNoZ(*hater); - if((*iterator)->ent != nullptr && thisdist <= closedist) { + auto iterator = mEntries.begin(); + while(iterator != mEntries.end()) { + thisdist = (*iterator)->mMOB->DistNoRootNoZ(*hater); + if((*iterator)->mMOB != nullptr && thisdist <= closedist) { closedist = thisdist; - close = (*iterator)->ent; + close = (*iterator)->mMOB; } ++iterator; } @@ -157,78 +147,65 @@ Mob* HateList::GetClosest(Mob *hater) { return close; } -void HateList::Add(Mob *ent, int32 in_hate, int32 in_dam, bool bFrenzy, bool iAddIfNotExist) +void HateList::add(Mob* pMOB, int32 pHate, int32 pDamage, bool pFrenzy, bool iAddIfNotExist) { - if(!ent) - return; + if (!pMOB) return; - if(ent->IsCorpse()) - return; + // Do not add corpses to HateList. + if (pMOB->IsCorpse()) return; - if(ent->IsClient() && ent->CastToClient()->IsDead()) - return; + // Do not add dead dead players to HateList. + if (pMOB->IsClient() && pMOB->CastToClient()->IsDead()) return; - tHateEntry *p = Find(ent); - if (p) + // Where pMOB is already on the HateList, increase Hate/Damage values. + HateEntry *entry = find(pMOB); + if (entry) { - p->damage+=(in_dam>=0)?in_dam:0; - p->hate+=in_hate; - p->bFrenzy = bFrenzy; + entry->mDamage += (pDamage >= 0) ? pDamage : 0; + entry->mHate += pHate; + entry->mFrenzy = pFrenzy; } + // Where pMOB is not on the HateList, add it. else if (iAddIfNotExist) { - p = new tHateEntry; - p->ent = ent; - p->damage = (in_dam>=0)?in_dam:0; - p->hate = in_hate; - p->bFrenzy = bFrenzy; - list.push_back(p); - parse->EventNPC(EVENT_HATE_LIST, owner->CastToNPC(), ent, "1", 0); + entry = new HateEntry(pMOB, (pDamage >= 0) ? pDamage : 0, pHate, pFrenzy); + mEntries.push_back(entry); + parse->EventNPC(EVENT_HATE_LIST, mOwner->CastToNPC(), pMOB, "1", 0); - if(ent->IsClient()) - ent->CastToClient()->IncrementAggroCount(); + // Where pMOB is client, update 'Aggro Count'. + if (pMOB->IsClient()) + pMOB->CastToClient()->IncrementAggroCount(); } } -bool HateList::RemoveEnt(Mob *ent) +bool HateList::clear(Mob* pMOB) { - if (!ent) - return false; + if (!pMOB) return false; - bool found = false; - auto iterator = list.begin(); - - while(iterator != list.end()) - { - if((*iterator)->ent == ent) - { - if(ent) - parse->EventNPC(EVENT_HATE_LIST, owner->CastToNPC(), ent, "0", 0); - found = true; - - - if(ent && ent->IsClient()) - ent->CastToClient()->DecrementAggroCount(); - - delete (*iterator); - iterator = list.erase(iterator); + for (auto i = mEntries.begin(); i != mEntries.end(); i++) { + if ((*i)->mMOB == pMOB) { + parse->EventNPC(EVENT_HATE_LIST, mOwner->CastToNPC(), pMOB, "0", 0); + pMOB->CastToClient()->DecrementAggroCount(); + // Clean up. + delete *i; + mEntries.erase(i); + return true; } - else - ++iterator; } - return found; + + return false; } void HateList::DoFactionHits(int32 nfl_id) { if (nfl_id <= 0) return; - auto iterator = list.begin(); - while(iterator != list.end()) + auto iterator = mEntries.begin(); + while(iterator != mEntries.end()) { Client *p; - if ((*iterator)->ent && (*iterator)->ent->IsClient()) - p = (*iterator)->ent->CastToClient(); + if ((*iterator)->mMOB && (*iterator)->mMOB->IsClient()) + p = (*iterator)->mMOB->CastToClient(); else p = nullptr; @@ -238,26 +215,18 @@ void HateList::DoFactionHits(int32 nfl_id) { } } -int HateList::SummonedPetCount(Mob *hater) { - - //Function to get number of 'Summoned' pets on a targets hate list to allow calculations for certian spell effects. - //Unclear from description that pets are required to be 'summoned body type'. Will not require at this time. - int petcount = 0; - auto iterator = list.begin(); - while(iterator != list.end()) { - - if((*iterator)->ent != nullptr && (*iterator)->ent->IsNPC() && ((*iterator)->ent->CastToNPC()->IsPet() || ((*iterator)->ent->CastToNPC()->GetSwarmOwner() > 0))) - { - ++petcount; - } - - ++iterator; +int HateList::getSummonedPetCount() { + int count = 0; + for (auto i = mEntries.begin(); i != mEntries.end(); i++) { + Mob* entryMOB = (*i)->mMOB; + if (entryMOB && entryMOB->IsNPC() && (entryMOB->CastToNPC()->IsPet() || (entryMOB->CastToNPC()->GetSwarmOwner() > 0))) + count++; } - return petcount; + return count; } -Mob *HateList::GetTop(Mob *center) +Mob *HateList::getHighestHate(Mob *center) { Mob* top = nullptr; int32 hate = -1; @@ -270,10 +239,10 @@ Mob *HateList::GetTop(Mob *center) int32 hateClientTypeInRange = -1; int skipped_count = 0; - auto iterator = list.begin(); - while(iterator != list.end()) + auto iterator = mEntries.begin(); + while(iterator != mEntries.end()) { - tHateEntry *cur = (*iterator); + HateEntry *cur = (*iterator); int16 aggroMod = 0; if(!cur){ @@ -281,48 +250,48 @@ Mob *HateList::GetTop(Mob *center) continue; } - if(!cur->ent){ + if(!cur->mMOB){ ++iterator; continue; } if(center->IsNPC() && center->CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) { - if(!zone->watermap->InLiquid(cur->ent->GetX(), cur->ent->GetY(), cur->ent->GetZ())) { + if(!zone->watermap->InLiquid(cur->mMOB->GetX(), cur->mMOB->GetY(), cur->mMOB->GetZ())) { skipped_count++; ++iterator; continue; } } - if(cur->ent->DivineAura() || cur->ent->IsMezzed() || cur->ent->IsFeared()){ + if(cur->mMOB->DivineAura() || cur->mMOB->IsMezzed() || cur->mMOB->IsFeared()){ if(hate == -1) { - top = cur->ent; + top = cur->mMOB; hate = 0; } ++iterator; continue; } - int32 currentHate = cur->hate; + int32 currentHate = cur->mHate; - if(cur->ent->IsClient()){ + if(cur->mMOB->IsClient()){ - if(cur->ent->CastToClient()->IsSitting()){ + if(cur->mMOB->CastToClient()->IsSitting()){ aggroMod += RuleI(Aggro, SittingAggroMod); } if(center){ - if(center->GetTarget() == cur->ent) + if(center->GetTarget() == cur->mMOB) aggroMod += RuleI(Aggro, CurrentTargetAggroMod); if(RuleI(Aggro, MeleeRangeAggroMod) != 0) { - if(center->CombatRange(cur->ent)){ + if(center->CombatRange(cur->mMOB)){ aggroMod += RuleI(Aggro, MeleeRangeAggroMod); - if(currentHate > hateClientTypeInRange || cur->bFrenzy){ + if(currentHate > hateClientTypeInRange || cur->mFrenzy){ hateClientTypeInRange = currentHate; - topClientTypeInRange = cur->ent; + topClientTypeInRange = cur->mMOB; } } } @@ -331,18 +300,18 @@ Mob *HateList::GetTop(Mob *center) } else{ if(center){ - if(center->GetTarget() == cur->ent) + if(center->GetTarget() == cur->mMOB) aggroMod += RuleI(Aggro, CurrentTargetAggroMod); if(RuleI(Aggro, MeleeRangeAggroMod) != 0) { - if(center->CombatRange(cur->ent)){ + if(center->CombatRange(cur->mMOB)){ aggroMod += RuleI(Aggro, MeleeRangeAggroMod); } } } } - if(cur->ent->GetMaxHP() != 0 && ((cur->ent->GetHP()*100/cur->ent->GetMaxHP()) < 20)){ + if(cur->mMOB->GetMaxHP() != 0 && ((cur->mMOB->GetHP()*100/cur->mMOB->GetMaxHP()) < 20)){ aggroMod += RuleI(Aggro, CriticallyWoundedAggroMod); } @@ -350,9 +319,9 @@ Mob *HateList::GetTop(Mob *center) currentHate += (currentHate * aggroMod / 100); } - if(currentHate > hate || cur->bFrenzy){ + if(currentHate > hate || cur->mFrenzy){ hate = currentHate; - top = cur->ent; + top = cur->mMOB; } ++iterator; @@ -381,23 +350,23 @@ Mob *HateList::GetTop(Mob *center) } } else{ - auto iterator = list.begin(); + auto iterator = mEntries.begin(); int skipped_count = 0; - while(iterator != list.end()) + while(iterator != mEntries.end()) { - tHateEntry *cur = (*iterator); + HateEntry *cur = (*iterator); if(center->IsNPC() && center->CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) { - if(!zone->watermap->InLiquid(cur->ent->GetX(), cur->ent->GetY(), cur->ent->GetZ())) { + if(!zone->watermap->InLiquid(cur->mMOB->GetX(), cur->mMOB->GetY(), cur->mMOB->GetZ())) { skipped_count++; ++iterator; continue; } } - if(cur->ent != nullptr && ((cur->hate > hate) || cur->bFrenzy )) + if(cur->mMOB != nullptr && ((cur->mHate > hate) || cur->mFrenzy )) { - top = cur->ent; - hate = cur->hate; + top = cur->mMOB; + hate = cur->mHate; } ++iterator; } @@ -409,18 +378,18 @@ Mob *HateList::GetTop(Mob *center) return nullptr; } -Mob *HateList::GetMostHate(){ +Mob *HateList::getMostHate(){ Mob* top = nullptr; int32 hate = -1; - auto iterator = list.begin(); - while(iterator != list.end()) + auto iterator = mEntries.begin(); + while(iterator != mEntries.end()) { - tHateEntry *cur = (*iterator); - if(cur->ent != nullptr && (cur->hate > hate)) + HateEntry *cur = (*iterator); + if(cur->mMOB != nullptr && (cur->mHate > hate)) { - top = cur->ent; - hate = cur->hate; + top = cur->mMOB; + hate = cur->mHate; } ++iterator; } @@ -428,57 +397,62 @@ Mob *HateList::GetMostHate(){ } -Mob *HateList::GetRandom() +Mob *HateList::getRandom() { - int count = list.size(); + int count = mEntries.size(); if(count == 0) //If we don't have any entries it'll crash getting a random 0, -1 position. return NULL; if(count == 1) //No need to do all that extra work if we only have one hate entry { - if(*list.begin()) // Just in case tHateEntry is invalidated somehow... - return (*list.begin())->ent; + if(*mEntries.begin()) // Just in case tHateEntry is invalidated somehow... + return (*mEntries.begin())->mMOB; return NULL; } - auto iterator = list.begin(); + auto iterator = mEntries.begin(); int random = MakeRandomInt(0, count - 1); for (int i = 0; i < random; i++) ++iterator; - return (*iterator)->ent; + return (*iterator)->mMOB; } -int32 HateList::GetEntHate(Mob *ent, bool damage) +int32 HateList::getHate(Mob* pMOB, bool pDamage) { - tHateEntry *p; + HateEntry* entry = find(pMOB); + if (entry) { + if (pDamage) return entry->mDamage; + return entry->mHate; + } - p = Find(ent); - - if ( p && damage) - return p->damage; - else if (p) - return p->hate; - else - return 0; + return 0; } -//looking for any mob with hate > -1 -bool HateList::IsEmpty() { - return(list.size() == 0); + +int32 HateList::getDamage(Mob* pMOB) +{ + HateEntry* entry = find(pMOB); + if (entry) return entry->mDamage; + + return 0; +} + +bool HateList::isEmpty() { + return mEntries.size() == 0; } // Prints hate list to a client void HateList::PrintToClient(Client *c) { - auto iterator = list.begin(); - while (iterator != list.end()) + auto iterator = mEntries.begin(); + while (iterator != mEntries.end()) { - tHateEntry *e = (*iterator); + HateEntry *e = (*iterator); c->Message(0, "- name: %s, damage: %d, hate: %d", - (e->ent && e->ent->GetName()) ? e->ent->GetName() : "(null)", - e->damage, e->hate); + (e->mMOB && e->mMOB->GetName()) ? e->mMOB->GetName() : "(null)", + e->mDamage, e->mHate); ++iterator; } @@ -491,16 +465,16 @@ int HateList::AreaRampage(Mob *caster, Mob *target, int count, ExtraAttackOption int ret = 0; std::list id_list; - auto iterator = list.begin(); - while (iterator != list.end()) + auto iterator = mEntries.begin(); + while (iterator != mEntries.end()) { - tHateEntry *h = (*iterator); + HateEntry *h = (*iterator); ++iterator; - if(h && h->ent && h->ent != caster) + if(h && h->mMOB && h->mMOB != caster) { - if(caster->CombatRange(h->ent)) + if(caster->CombatRange(h->mMOB)) { - id_list.push_back(h->ent->GetID()); + id_list.push_back(h->mMOB->GetID()); ++ret; } } @@ -535,20 +509,20 @@ void HateList::SpellCast(Mob *caster, uint32 spell_id, float range) //So keep a list of entity ids and look up after std::list id_list; range = range * range; - auto iterator = list.begin(); - while (iterator != list.end()) + auto iterator = mEntries.begin(); + while (iterator != mEntries.end()) { - tHateEntry *h = (*iterator); + HateEntry *h = (*iterator); if(range > 0) { - if(caster->DistNoRoot(*h->ent) <= range) + if(caster->DistNoRoot(*h->mMOB) <= range) { - id_list.push_back(h->ent->GetID()); + id_list.push_back(h->mMOB->GetID()); } } else { - id_list.push_back(h->ent->GetID()); + id_list.push_back(h->mMOB->GetID()); } ++iterator; } diff --git a/zone/hate_list.h b/zone/hate_list.h index 4fd00ff73..2d907938a 100644 --- a/zone/hate_list.h +++ b/zone/hate_list.h @@ -19,11 +19,16 @@ #ifndef HATELIST_H #define HATELIST_H -struct tHateEntry +class Mob; +// TODO: Later fix pre-declarations. There is some crazy shit going on with include order in other files obviously. + +struct HateEntry { - Mob *ent; - int32 damage, hate; - bool bFrenzy; + HateEntry(Mob* pMOB, int32 pDamage, int32 pHate, bool pFrenzy) : mMOB(pMOB), mDamage(pDamage), mHate(pHate), mFrenzy(pFrenzy) {} + Mob *mMOB; + int32 mDamage; + int32 mHate; + bool mFrenzy; }; class HateList @@ -32,52 +37,68 @@ public: HateList(); ~HateList(); - // adds a mob to the hatelist - void Add(Mob *ent, int32 in_hate=0, int32 in_dam=0, bool bFrenzy = false, bool iAddIfNotExist = true); - // sets existing hate - void Set(Mob *other, uint32 in_hate, uint32 in_dam); - // removes mobs from hatelist - bool RemoveEnt(Mob *ent); - // Remove all - void Wipe(); - // ??? - void DoFactionHits(int32 nfl_id); - // Gets Hate amount for mob - int32 GetEntHate(Mob *ent, bool damage = false); - // gets top hated mob - Mob *GetTop(Mob *center); - // gets any on the list - Mob *GetRandom(); - // get closest mob or nullptr if list empty - Mob *GetClosest(Mob *hater); - // gets top mob or nullptr if hate list empty - Mob *GetDamageTop(Mob *hater); - // used to check if mob is on hatelist - bool IsOnHateList(Mob *); + // Set the owner of the HateList. + void setOwner(Mob* pOwner) { mOwner = pOwner; } + + // Returns whether the HateList is empty. + bool isEmpty(); + + // Returns the number of pets on the HateList. + int getSummonedPetCount(); + + // Removes a specific MOB from the HateList. + bool clear(Mob* pMOB); + + // Removes all MOBs from the HateList. + void clear(); + + // Adds a MOB to the HateList. + // TODO: Look more into parameter 'iAddIfNotExist' .. I can't think of circumstances where this would be needed. + void add(Mob* pMOB, int32 pHate = 0, int32 pDamage = 0, bool pFrenzy = false, bool iAddIfNotExist = true); + + // Sets a MOBs hate. + void set(Mob* pMOB, uint32 pHate, uint32 pDamage); + + // Returns the hate value of a specific MOB. (Or Damage for fun under some circumstances...) + // TODO: Remove the 'damage' parameter and use getDamage where appropriate. + int32 getHate(Mob * pMOB, bool damage = false); + + // Returns the damage value of a specific MOB. + int32 getDamage(Mob* pMOB); + + // Returns the MOB with the highest hate value or null if none. + Mob *getHighestHate(Mob* pCenter); + + // Returns the MOB with the highest damage value or null if none. + Mob *getHighestDamage(Mob* pHater); + + // Returns a random MOB on the HateList. + Mob* getRandom(); + + // Returns the closest MOB. + Mob* getClosest(Mob* pHater); + + // Returns whether the specific MOB is on the HateList. + bool isHated(Mob * pMOB); //Gets the target with the most hate regardless of things like frenzy etc. - Mob* GetMostHate(); - // Count 'Summoned' pets on hatelist - int SummonedPetCount(Mob *hater); - - int AreaRampage(Mob *caster, Mob *target, int count, ExtraAttackOptions *opts); - - void SpellCast(Mob *caster, uint32 spell_id, float range); - - bool IsEmpty(); - void PrintToClient(Client *c); + Mob* getMostHate(); //For accessing the hate list via perl; don't use for anything else - std::list& GetHateList() { return list; } + std::list& GetHateList() { return mEntries; } - //setting owner - void SetOwner(Mob *newOwner) { owner = newOwner; } - -protected: - tHateEntry* Find(Mob *ent); + // TODO: Remove, this functionality does not belong here. + void DoFactionHits(int32 nfl_id); + // TODO: Remove, this functionality does not belong here. + int AreaRampage(Mob *caster, Mob *target, int count, ExtraAttackOptions *opts); + // TODO: Remove, this functionality does not belong here. + void SpellCast(Mob *caster, uint32 spell_id, float range); + // TODO: Remove, this functionality does not belong here. + void PrintToClient(Client *c); private: - std::list list; - Mob *owner; + HateEntry* find(Mob* pMOB); + std::list mEntries; + Mob* mOwner; }; #endif diff --git a/zone/lua_hate_list.cpp b/zone/lua_hate_list.cpp index edca6ee11..9ffbea3a7 100644 --- a/zone/lua_hate_list.cpp +++ b/zone/lua_hate_list.cpp @@ -12,42 +12,42 @@ Lua_Mob Lua_HateEntry::GetEnt() { Lua_Safe_Call_Class(Lua_Mob); - return Lua_Mob(self->ent); + return Lua_Mob(self->mMOB); } void Lua_HateEntry::SetEnt(Lua_Mob e) { Lua_Safe_Call_Void(); - self->ent = e; + self->mMOB = e; } int Lua_HateEntry::GetDamage() { Lua_Safe_Call_Int(); - return self->damage; + return self->mDamage; } void Lua_HateEntry::SetDamage(int value) { Lua_Safe_Call_Void(); - self->damage = value; + self->mDamage = value; } int Lua_HateEntry::GetHate() { Lua_Safe_Call_Int(); - return self->hate; + return self->mHate; } void Lua_HateEntry::SetHate(int value) { Lua_Safe_Call_Void(); - self->hate = value; + self->mHate = value; } int Lua_HateEntry::GetFrenzy() { Lua_Safe_Call_Int(); - return self->bFrenzy; + return self->mFrenzy; } void Lua_HateEntry::SetFrenzy(bool value) { Lua_Safe_Call_Void(); - self->bFrenzy = value; + self->mFrenzy = value; } luabind::scope lua_register_hate_entry() { diff --git a/zone/lua_hate_list.h b/zone/lua_hate_list.h index 4dc6502f3..ef6d3bb9d 100644 --- a/zone/lua_hate_list.h +++ b/zone/lua_hate_list.h @@ -5,17 +5,17 @@ #include "lua_ptr.h" class Lua_Mob; -struct tHateEntry; +struct HateEntry; luabind::scope lua_register_hate_entry(); luabind::scope lua_register_hate_list(); -class Lua_HateEntry : public Lua_Ptr +class Lua_HateEntry : public Lua_Ptr { - typedef tHateEntry NativeType; + typedef HateEntry NativeType; public: Lua_HateEntry() : Lua_Ptr(nullptr) { } - Lua_HateEntry(tHateEntry *d) : Lua_Ptr(d) { } + Lua_HateEntry(HateEntry *d) : Lua_Ptr(d) { } virtual ~Lua_HateEntry() { } Lua_Mob GetEnt(); diff --git a/zone/merc.cpp b/zone/merc.cpp index 3bcc9d577..a35cfce17 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -1498,7 +1498,7 @@ void Merc::AI_Process() { rest_timer.Disable(); if(IsRooted()) - SetTarget(hate_list.GetClosest(this)); + SetTarget(hate_list.getClosest(this)); else FindTarget(); @@ -2552,11 +2552,11 @@ void Merc::CheckHateList() { Mob* groupMember = g->members[counter]; if(groupMember) { if(npc->IsOnHatelist(groupMember)) { - if(!hate_list.IsOnHateList(npc)) { + if(!hate_list.isHated(npc)) { float range = g->HasRole(groupMember, RolePuller) ? RuleI(Mercs, AggroRadiusPuller) : RuleI(Mercs, AggroRadius); range *= range; if(npc->DistNoRootNoZ(*this) < range) { - hate_list.Add(npc, 1); + hate_list.add(npc, 1); } } } @@ -4751,7 +4751,7 @@ bool Merc::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attac Save(); - Mob *give_exp = hate_list.GetDamageTop(this); + Mob *give_exp = hate_list.getHighestDamage(this); Client *give_exp_client = nullptr; if(give_exp && give_exp->IsClient()) diff --git a/zone/mob.cpp b/zone/mob.cpp index d034253fb..bd7afc63b 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -375,7 +375,7 @@ Mob::Mob(const char* in_name, PathingRouteUpdateTimerLong = new Timer(RuleI(Pathing, RouteUpdateFrequencyLong)); DistractedFromGrid = false; PathingTraversedNodes = 0; - hate_list.SetOwner(this); + hate_list.setOwner(this); m_AllowBeneficial = false; m_DisableMelee = false; @@ -2443,8 +2443,8 @@ bool Mob::RemoveFromHateList(Mob* mob) bool bFound = false; if(IsEngaged()) { - bFound = hate_list.RemoveEnt(mob); - if(hate_list.IsEmpty()) + bFound = hate_list.clear(mob); + if(hate_list.isEmpty()) { AI_Event_NoLongerEngaged(); zone->DelAggroMob(); @@ -2452,7 +2452,7 @@ bool Mob::RemoveFromHateList(Mob* mob) } if(GetTarget() == mob) { - SetTarget(hate_list.GetTop(this)); + SetTarget(hate_list.getHighestHate(this)); } return bFound; @@ -2462,12 +2462,12 @@ void Mob::WipeHateList() { if(IsEngaged()) { - hate_list.Wipe(); + hate_list.clear(); AI_Event_NoLongerEngaged(); } else { - hate_list.Wipe(); + hate_list.clear(); } } @@ -3283,7 +3283,7 @@ void Mob::TryTriggerOnValueAmount(bool IsHP, bool IsMana, bool IsEndur, bool IsP } else if (IsPet){ - int count = hate_list.SummonedPetCount(this); + int count = hate_list.getSummonedPetCount(); if ((base2 >= 220 && base2 <= 250) && count >= (base2 - 220)){ use_spell = true; } diff --git a/zone/mob.h b/zone/mob.h index 1df559d16..e1313c81a 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -427,16 +427,16 @@ public: virtual void AddToHateList(Mob* other, int32 hate = 0, int32 damage = 0, bool iYellForHelp = true, bool bFrenzy = false, bool iBuffTic = false); bool RemoveFromHateList(Mob* mob); - void SetHate(Mob* other, int32 hate = 0, int32 damage = 0) { hate_list.Set(other,hate,damage);} + void SetHate(Mob* other, int32 hate = 0, int32 damage = 0) { hate_list.set(other,hate,damage);} void HalveAggro(Mob *other) { uint32 in_hate = GetHateAmount(other); SetHate(other, (in_hate > 1 ? in_hate / 2 : 1)); } void DoubleAggro(Mob *other) { uint32 in_hate = GetHateAmount(other); SetHate(other, (in_hate ? in_hate * 2 : 1)); } - uint32 GetHateAmount(Mob* tmob, bool is_dam = false) { return hate_list.GetEntHate(tmob,is_dam);} - uint32 GetDamageAmount(Mob* tmob) { return hate_list.GetEntHate(tmob, true);} - Mob* GetHateTop() { return hate_list.GetTop(this);} - Mob* GetHateDamageTop(Mob* other) { return hate_list.GetDamageTop(other);} - Mob* GetHateRandom() { return hate_list.GetRandom();} - Mob* GetHateMost() { return hate_list.GetMostHate();} - bool IsEngaged() { return(!hate_list.IsEmpty()); } + uint32 GetHateAmount(Mob* tmob, bool is_dam = false) { return hate_list.getHate(tmob,is_dam);} + uint32 GetDamageAmount(Mob* tmob) { return hate_list.getHate(tmob, true);} + Mob* GetHateTop() { return hate_list.getHighestHate(this);} + Mob* GetHateDamageTop(Mob* other) { return hate_list.getHighestDamage(other);} + Mob* GetHateRandom() { return hate_list.getRandom();} + Mob* GetHateMost() { return hate_list.getMostHate();} + bool IsEngaged() { return(!hate_list.isEmpty()); } bool HateSummon(); void FaceTarget(Mob* MobToFace = 0); void SetHeading(float iHeading) { if(heading != iHeading) { pLastChange = Timer::GetCurrentTime(); @@ -446,7 +446,7 @@ public: void RemoveFromFeignMemory(Client* attacker); void ClearFeignMemory(); void PrintHateListToClient(Client *who) { hate_list.PrintToClient(who); } - std::list& GetHateList() { return hate_list.GetHateList(); } + std::list& GetHateList() { return hate_list.GetHateList(); } bool CheckLosFN(Mob* other); bool CheckLosFN(float posX, float posY, float posZ, float mobSize); inline void SetChanged() { pLastChange = Timer::GetCurrentTime(); } @@ -748,7 +748,7 @@ public: void ProcessFlee(); void CheckFlee(); - inline bool CheckAggro(Mob* other) {return hate_list.IsOnHateList(other);} + inline bool CheckAggro(Mob* other) {return hate_list.isHated(other);} float CalculateHeadingToTarget(float in_x, float in_y); bool CalculateNewPosition(float x, float y, float z, float speed, bool checkZ = false); virtual bool CalculateNewPosition2(float x, float y, float z, float speed, bool checkZ = true); diff --git a/zone/npc.h b/zone/npc.h index ae444c099..e49e475d0 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -234,8 +234,8 @@ public: inline int32 GetNPCFactionID() const { return npc_faction_id; } inline int32 GetPrimaryFaction() const { return primary_faction; } - int32 GetNPCHate(Mob* in_ent) {return hate_list.GetEntHate(in_ent);} - bool IsOnHatelist(Mob*p) { return hate_list.IsOnHateList(p);} + int32 GetNPCHate(Mob* in_ent) {return hate_list.getHate(in_ent);} + bool IsOnHatelist(Mob*p) { return hate_list.isHated(p);} void SetNPCFactionID(int32 in) { npc_faction_id = in; database.GetFactionIdsForNPC(npc_faction_id, &faction_list, &primary_faction); } diff --git a/zone/perl_hateentry.cpp b/zone/perl_hateentry.cpp index fa65e8b39..156cb6c7a 100644 --- a/zone/perl_hateentry.cpp +++ b/zone/perl_hateentry.cpp @@ -40,19 +40,19 @@ XS(XS_HateEntry_GetEnt) if (items != 1) Perl_croak(aTHX_ "Usage: HateEntry::GetData(THIS)"); { - tHateEntry * THIS; + HateEntry * THIS; Mob * RETVAL; if (sv_derived_from(ST(0), "HateEntry")) { IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(tHateEntry *,tmp); + THIS = INT2PTR(HateEntry *,tmp); } else Perl_croak(aTHX_ "THIS is not of type tHateEntry"); if(THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - RETVAL = THIS->ent; + RETVAL = THIS->mMOB; ST(0) = sv_newmortal(); sv_setref_pv(ST(0), "Mob", (void*)RETVAL); } @@ -66,20 +66,20 @@ XS(XS_HateEntry_GetHate) if (items != 1) Perl_croak(aTHX_ "Usage: HateEntry::GetHate(THIS)"); { - tHateEntry * THIS; + HateEntry * THIS; int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "HateEntry")) { IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(tHateEntry *,tmp); + THIS = INT2PTR(HateEntry *,tmp); } else Perl_croak(aTHX_ "THIS is not of type tHateEntry"); if(THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - RETVAL = THIS->hate; + RETVAL = THIS->mHate; XSprePUSH; PUSHi((IV)RETVAL); } XSRETURN(1); @@ -92,20 +92,20 @@ XS(XS_HateEntry_GetDamage) if (items != 1) Perl_croak(aTHX_ "Usage: HateEntry::GetDamage(THIS)"); { - tHateEntry * THIS; + HateEntry * THIS; int32 RETVAL; dXSTARG; if (sv_derived_from(ST(0), "HateEntry")) { IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(tHateEntry *,tmp); + THIS = INT2PTR(HateEntry *,tmp); } else Perl_croak(aTHX_ "THIS is not of type tHateEntry"); if(THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - RETVAL = THIS->damage; + RETVAL = THIS->mDamage; XSprePUSH; PUSHi((IV)RETVAL); } XSRETURN(1); diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index 86cf58981..f0ceb57bd 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -6581,7 +6581,7 @@ XS(XS_Mob_GetHateList) while(iter != hate_list.end()) { - tHateEntry *entry = (*iter); + HateEntry *entry = (*iter); ST(0) = sv_newmortal(); sv_setref_pv(ST(0), "HateEntry", (void*)entry); XPUSHs(ST(0)); diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 8731dfaab..4db33f91f 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -6006,7 +6006,7 @@ bool Mob::PassCastRestriction(bool UseCastRestriction, int16 value, bool IsDama //Limit to amount of pets if (value >= 221 && value <= 249){ - int count = hate_list.SummonedPetCount(this); + int count = hate_list.getSummonedPetCount(); for (int base2_value = 221; base2_value <= 249; ++base2_value){ if (value == base2_value){