demonstar55's entity list changes (slightly modified) and a crash fix for the #repop command used in rapid succession.

This commit is contained in:
SecretsOTheP 2014-02-10 10:39:12 -05:00
parent 75663774fe
commit f074ead7f6
13 changed files with 2226 additions and 2945 deletions

View File

@ -1,5 +1,9 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50)
-------------------------------------------------------
== 02/10/2014 ==
demonstar55 (Secrets): Re-wrote the entity list to be a std::map. This should be used for direct entityID lookups and is noticably faster performance-wise. Also should result in less nil pointers potentially.
Secrets: Fixed a crash issue that could occur on #repop related to quest timers.
== 02/09/2014 ==
Sorvani: Added new spawn condition onchange action: DoRepopIfReady. Choosing this will not repop mobs when the spawn condition is enabled if they have an existing respawn timer. Additionally, this condition will not even attempt repop when the condition is is changed to disabled. Will be in use on PEQ for: Cragbeast Queen in Natimbi.
Secrets: Fixed a weird crash issue with deletion of pointers if task loading fails.

View File

@ -371,9 +371,8 @@ bool EntityList::AICheckCloseBeneficialSpells(NPC* caster, uint8 iChance, float
//Only iterate through NPCs
LinkedListIterator<NPC*> iterator(npc_list);
for(iterator.Reset(); iterator.MoreElements(); iterator.Advance()) {
NPC* mob = iterator.GetData();
for (auto it = npc_list.begin(); it != npc_list.end(); ++it) {
NPC* mob = it->second;
//Since >90% of mobs will always be out of range, try to
//catch them with simple bounding box checks first. These

View File

@ -32,23 +32,18 @@ extern Zone* zone;
//#define LOSDEBUG 6
//look around a client for things which might aggro the client.
void EntityList::CheckClientAggro(Client *around) {
LinkedListIterator<Mob*> iterator(mob_list);
for(iterator.Reset(); iterator.MoreElements(); iterator.Advance()) {
Mob* mob = iterator.GetData();
if(mob->IsClient()) //also ensures that mob != around
void EntityList::CheckClientAggro(Client *around)
{
for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
Mob *mob = it->second;
if (mob->IsClient()) //also ensures that mob != around
continue;
if(mob->CheckWillAggro(around)) {
if(mob->IsEngaged())
{
if (mob->CheckWillAggro(around)) {
if (mob->IsEngaged())
mob->AddToHateList(around);
}
else
{
mob->AddToHateList(around, mob->GetLevel());
}
}
}
}
@ -84,23 +79,21 @@ void EntityList::DescribeAggro(Client *towho, NPC *from_who, float d, bool verbo
towho->Message(0, ".. I am on faction %s (%d)\n", namebuf, my_primary);
}
LinkedListIterator<Mob*> iterator(mob_list);
for(iterator.Reset(); iterator.MoreElements(); iterator.Advance()) {
Mob* mob = iterator.GetData();
if(mob->IsClient()) //also ensures that mob != around
for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
Mob *mob = it->second;
if (mob->IsClient()) //also ensures that mob != around
continue;
if(mob->DistNoRoot(*from_who) > d2)
if (mob->DistNoRoot(*from_who) > d2)
continue;
if(engaged) {
if (engaged) {
uint32 amm = from_who->GetHateAmount(mob);
if(amm == 0) {
if (amm == 0)
towho->Message(0, "... %s is not on my hate list.", mob->GetName());
} else {
else
towho->Message(0, "... %s is on my hate list with value %lu", mob->GetName(), (unsigned long)amm);
}
} else if(!check_npcs && mob->IsNPC()) {
} else if (!check_npcs && mob->IsNPC()) {
towho->Message(0, "... %s is an NPC and my npc_aggro is disabled.", mob->GetName());
} else {
from_who->DescribeAggro(towho, mob, verbose);
@ -369,59 +362,57 @@ Mob* EntityList::AICheckCloseAggro(Mob* sender, float iAggroRange, float iAssist
#ifdef REVERSE_AGGRO
//with reverse aggro, npc->client is checked elsewhere, no need to check again
LinkedListIterator<NPC*> iterator(npc_list);
auto it = npc_list.begin();
while (it != npc_list.end()) {
#else
LinkedListIterator<Mob*> iterator(mob_list);
auto it = mob_list.begin();
while (it != mob_list.end()) {
#endif
iterator.Reset();
//float distZ;
while(iterator.MoreElements()) {
Mob* mob = iterator.GetData();
Mob *mob = it->second;
if(sender->CheckWillAggro(mob)) {
return(mob);
}
iterator.Advance();
if (sender->CheckWillAggro(mob))
return mob;
++it;
}
//LogFile->write(EQEMuLog::Debug, "Check aggro for %s no target.", sender->GetName());
return(nullptr);
return nullptr;
}
int EntityList::GetHatedCount(Mob *attacker, Mob *exclude) {
int EntityList::GetHatedCount(Mob *attacker, Mob *exclude)
{
// Return a list of how many non-feared, non-mezzed, non-green mobs, within aggro range, hate *attacker
if(!attacker) return 0;
if (!attacker)
return 0;
int Count = 0;
LinkedListIterator<NPC*> iterator(npc_list);
for (auto it = npc_list.begin(); it != npc_list.end(); ++it) {
NPC *mob = it->second;
if (!mob || (mob == exclude))
continue;
for(iterator.Reset(); iterator.MoreElements(); iterator.Advance()) {
if (!mob->IsEngaged())
continue;
NPC* mob = iterator.GetData();
if (mob->IsFeared() || mob->IsMezzed())
continue;
if(!mob || (mob == exclude)) continue;
if (attacker->GetLevelCon(mob->GetLevel()) == CON_GREEN)
continue;
if(!mob->IsEngaged()) continue;
if(mob->IsFeared() || mob->IsMezzed()) continue;
if(attacker->GetLevelCon(mob->GetLevel()) == CON_GREEN) continue;
if(!mob->CheckAggro(attacker)) continue;
if (!mob->CheckAggro(attacker))
continue;
float AggroRange = mob->GetAggroRange();
// Square it because we will be using DistNoRoot
AggroRange = AggroRange * AggroRange;
AggroRange *= AggroRange;
if(mob->DistNoRoot(*attacker) > AggroRange) continue;
if (mob->DistNoRoot(*attacker) > AggroRange)
continue;
Count++;
}
return Count;
@ -434,13 +425,11 @@ void EntityList::AIYellForHelp(Mob* sender, Mob* attacker) {
if (sender->GetPrimaryFaction() == 0 )
return; // well, if we dont have a faction set, we're gonna be indiff to everybody
LinkedListIterator<NPC*> iterator(npc_list);
for(iterator.Reset(); iterator.MoreElements(); iterator.Advance()) {
NPC* mob = iterator.GetData();
if(!mob){
for (auto it = npc_list.begin(); it != npc_list.end(); ++it) {
NPC *mob = it->second;
if (!mob)
continue;
}
float r = mob->GetAssistRange();
r = r * r;

View File

@ -2294,7 +2294,7 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
uint16 emoteid = this->GetEmoteID();
Corpse* corpse = new Corpse(this, &itemlist, GetNPCTypeID(), &NPCTypedata,level>54?RuleI(NPC,MajorNPCCorpseDecayTimeMS):RuleI(NPC,MinorNPCCorpseDecayTimeMS));
entity_list.LimitRemoveNPC(this);
entity_list.AddCorpse(corpse, this->GetID());
entity_list.AddCorpse(corpse, GetID());
entity_list.UnMarkNPC(GetID());
entity_list.RemoveNPC(GetID());

View File

@ -16185,17 +16185,14 @@ Mob* EntityList::GetMobByBotID(uint32 botID) {
Mob* Result = 0;
if(botID > 0) {
LinkedListIterator<Mob*> iterator(mob_list);
auto it = mob_list.begin();
iterator.Reset();
while(iterator.MoreElements()) {
if(iterator.GetData()->IsBot() && iterator.GetData()->CastToBot()->GetBotID() == botID) {
Result = iterator.GetData();
for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
if(!it->second) continue;
if(it->second->IsBot() && it->second->CastToBot()->GetBotID() == botID) {
Result = it->second;
break;
}
iterator.Advance();
}
}
@ -16263,7 +16260,7 @@ void EntityList::AddBot(Bot *newBot, bool SendSpawnPacket, bool dontqueue) {
bot_list.push_back(newBot);
mob_list.Insert(newBot);
mob_list.insert(std::pair<uint16, Mob*>(newBot->GetID(), newBot));
}
}
@ -16284,10 +16281,9 @@ std::list<Bot*> EntityList::GetBotsByBotOwnerCharacterID(uint32 botOwnerCharacte
void EntityList::BotPickLock(Bot* rogue)
{
LinkedListIterator<Doors*> iterator(door_list);
iterator.Reset();
while(iterator.MoreElements()) {
Doors *cdoor = iterator.GetData();
auto it = door_list.begin();
for (auto it = door_list.begin(); it != door_list.end(); ++it) {
Doors *cdoor = it->second;
if(cdoor && !cdoor->IsDoorOpen()) {
float zdiff = rogue->GetZ() - cdoor->GetZ();
if(zdiff < 0)
@ -16326,7 +16322,6 @@ void EntityList::BotPickLock(Bot* rogue)
}
}
}
iterator.Advance();
}
}
@ -16356,18 +16351,17 @@ void EntityList::ShowSpawnWindow(Client* client, int Distance, bool NamedOnly) {
std::string WindowText;
int LastCon = -1;
int CurrentCon = 0;
Mob* curMob = NULL;
uint32 array_counter = 0;
LinkedListIterator<Mob*> iterator(mob_list);
iterator.Reset();
auto it = mob_list.begin();
while(iterator.MoreElements())
{
if (iterator.GetData() && (iterator.GetData()->DistNoZ(*client)<=Distance))
{
if(iterator.GetData()->IsTrackable()) {
Mob* cur_entity = iterator.GetData();
for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
curMob = it->second;
if (curMob && curMob->DistNoZ(*client)<=Distance) {
if(curMob->IsTrackable()) {
Mob* cur_entity = curMob;
int Extras = (cur_entity->IsBot() || cur_entity->IsPet() || cur_entity->IsFamiliar() || cur_entity->IsClient());
const char *const MyArray[] = {
"a_","an_","Innkeep_","Barkeep_",
@ -16409,7 +16403,6 @@ void EntityList::ShowSpawnWindow(Client* client, int Distance, bool NamedOnly) {
const char *CurEntityName = cur_entity->GetName(); //Call function once
for (int Index = 0; Index < MyArraySize; Index++) {
if (!strncasecmp(CurEntityName, MyArray[Index], strlen(MyArray[Index])) || (Extras)) {
iterator.Advance();
ContinueFlag = true;
break; //From Index for
};
@ -16466,8 +16459,6 @@ void EntityList::ShowSpawnWindow(Client* client, int Distance, bool NamedOnly) {
}
}
}
iterator.Advance();
}
WindowText += "</c>";

View File

@ -427,7 +427,7 @@ Client::~Client() {
eqs->Close();
eqs->ReleaseFromUse();
entity_list.RemoveClient(this);
//entity_list.RemoveClient(this);
UninitializeBuffSlots();
}

View File

@ -696,31 +696,27 @@ bool Client::UseDiscipline(uint32 spell_id, uint32 target) {
return(true);
}
void EntityList::AETaunt(Client* taunter, float range) {
LinkedListIterator<NPC*> iterator(npc_list);
if(range == 0) {
void EntityList::AETaunt(Client* taunter, float range)
{
if (range == 0)
range = 100; //arbitrary default...
}
range = range * range;
iterator.Reset();
while(iterator.MoreElements())
{
NPC * them = iterator.GetData();
auto it = npc_list.begin();
while (it != npc_list.end()) {
NPC *them = it->second;
float zdiff = taunter->GetZ() - them->GetZ();
if (zdiff < 0)
zdiff *= -1;
if (zdiff < 10
&& taunter->IsAttackAllowed(them)
&& taunter->DistNoRootNoZ(*them) <= range) {
&& taunter->IsAttackAllowed(them)
&& taunter->DistNoRootNoZ(*them) <= range) {
if (taunter->CheckLosFN(them)) {
taunter->Taunt(them, true);
}
}
iterator.Advance();
++it;
}
}
@ -729,7 +725,6 @@ void EntityList::AETaunt(Client* taunter, float range) {
// NPC spells will only affect other NPCs with compatible faction
void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster, int16 resist_adjust)
{
LinkedListIterator<Mob*> iterator(mob_list);
Mob *curmob;
float dist = caster->GetAOERange(spell_id);
@ -740,66 +735,59 @@ void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_
const int MAX_TARGETS_ALLOWED = 4;
int iCounter = 0;
for(iterator.Reset(); iterator.MoreElements(); iterator.Advance())
{
curmob = iterator.GetData();
if(curmob == center) //do not affect center
for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
curmob = it->second;
if (curmob == center) //do not affect center
continue;
if(curmob == caster && !affect_caster) //watch for caster too
if (curmob == caster && !affect_caster) //watch for caster too
continue;
if(center->DistNoRoot(*curmob) > dist2) //make sure they are in range
if (center->DistNoRoot(*curmob) > dist2) //make sure they are in range
continue;
if(isnpc && curmob->IsNPC()) { //check npc->npc casting
if (isnpc && curmob->IsNPC()) { //check npc->npc casting
FACTION_VALUE f = curmob->GetReverseFactionCon(caster);
if(bad) {
if (bad) {
//affect mobs that are on our hate list, or
//which have bad faction with us
if( ! (caster->CheckAggro(curmob) || f == FACTION_THREATENLY || f == FACTION_SCOWLS) )
if (!(caster->CheckAggro(curmob) || f == FACTION_THREATENLY || f == FACTION_SCOWLS) )
continue;
} else {
//only affect mobs we would assist.
if( ! (f <= FACTION_AMIABLE))
if (!(f <= FACTION_AMIABLE))
continue;
}
}
//finally, make sure they are within range
if(bad) {
if(!caster->IsAttackAllowed(curmob, true))
if (bad) {
if (!caster->IsAttackAllowed(curmob, true))
continue;
if(!center->CheckLosFN(curmob))
if (!center->CheckLosFN(curmob))
continue;
}
else { // check to stop casting beneficial ae buffs (to wit: bard songs) on enemies...
} else { // check to stop casting beneficial ae buffs (to wit: bard songs) on enemies...
// This does not check faction for beneficial AE buffs..only agro and attackable.
// I've tested for spells that I can find without problem, but a faction-based
// check may still be needed. Any changes here should also reflect in BardAEPulse() -U
if(caster->IsAttackAllowed(curmob, true))
if (caster->IsAttackAllowed(curmob, true))
continue;
if(caster->CheckAggro(curmob))
if (caster->CheckAggro(curmob))
continue;
}
//if we get here... cast the spell.
if(IsTargetableAESpell(spell_id) && bad)
{
if(iCounter < MAX_TARGETS_ALLOWED)
{
if (IsTargetableAESpell(spell_id) && bad) {
if (iCounter < MAX_TARGETS_ALLOWED) {
caster->SpellOnTarget(spell_id, curmob, false, true, resist_adjust);
}
}
else
{
} else {
caster->SpellOnTarget(spell_id, curmob, false, true, resist_adjust);
}
if(!isnpc) //npcs are not target limited...
if (!isnpc) //npcs are not target limited...
iCounter++;
}
}
void EntityList::MassGroupBuff(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster)
{
LinkedListIterator<Mob*> iterator(mob_list);
Mob *curmob;
float dist = caster->GetAOERange(spell_id);
@ -807,35 +795,28 @@ void EntityList::MassGroupBuff(Mob *caster, Mob *center, uint16 spell_id, bool a
bool bad = IsDetrimentalSpell(spell_id);
for(iterator.Reset(); iterator.MoreElements(); iterator.Advance())
{
curmob = iterator.GetData();
if(curmob == center) //do not affect center
for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
curmob = it->second;
if (curmob == center) //do not affect center
continue;
if(curmob == caster && !affect_caster) //watch for caster too
if (curmob == caster && !affect_caster) //watch for caster too
continue;
if(center->DistNoRoot(*curmob) > dist2) //make sure they are in range
if (center->DistNoRoot(*curmob) > dist2) //make sure they are in range
continue;
//Only npcs mgb should hit are client pets...
if(curmob->IsNPC())
{
if (curmob->IsNPC()) {
Mob *owner = curmob->GetOwner();
if(owner)
{
if(!owner->IsClient())
{
if (owner) {
if (!owner->IsClient()) {
continue;
}
}
else
{
} else {
continue;
}
}
if(bad)
{
if (bad) {
continue;
}
@ -848,7 +829,6 @@ void EntityList::MassGroupBuff(Mob *caster, Mob *center, uint16 spell_id, bool a
// NPC spells will only affect other NPCs with compatible faction
void EntityList::AEBardPulse(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster)
{
LinkedListIterator<Mob*> iterator(mob_list);
Mob *curmob;
float dist = caster->GetAOERange(spell_id);
@ -857,45 +837,43 @@ void EntityList::AEBardPulse(Mob *caster, Mob *center, uint16 spell_id, bool aff
bool bad = IsDetrimentalSpell(spell_id);
bool isnpc = caster->IsNPC();
for(iterator.Reset(); iterator.MoreElements(); iterator.Advance())
{
curmob = iterator.GetData();
if(curmob == center) //do not affect center
for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
curmob = it->second;
if (curmob == center) //do not affect center
continue;
if(curmob == caster && !affect_caster) //watch for caster too
if (curmob == caster && !affect_caster) //watch for caster too
continue;
if(center->DistNoRoot(*curmob) > dist2) //make sure they are in range
if (center->DistNoRoot(*curmob) > dist2) //make sure they are in range
continue;
if(isnpc && curmob->IsNPC()) { //check npc->npc casting
if (isnpc && curmob->IsNPC()) { //check npc->npc casting
FACTION_VALUE f = curmob->GetReverseFactionCon(caster);
if(bad) {
if (bad) {
//affect mobs that are on our hate list, or
//which have bad faction with us
if( ! (caster->CheckAggro(curmob) || f == FACTION_THREATENLY || f == FACTION_SCOWLS) )
if (!(caster->CheckAggro(curmob) || f == FACTION_THREATENLY || f == FACTION_SCOWLS) )
continue;
} else {
//only affect mobs we would assist.
if( ! (f <= FACTION_AMIABLE))
if (!(f <= FACTION_AMIABLE))
continue;
}
}
//finally, make sure they are within range
if(bad) {
if(!center->CheckLosFN(curmob))
if (bad) {
if (!center->CheckLosFN(curmob))
continue;
}
else { // check to stop casting beneficial ae buffs (to wit: bard songs) on enemies...
} else { // check to stop casting beneficial ae buffs (to wit: bard songs) on enemies...
// See notes in AESpell() above for more info.
if(caster->IsAttackAllowed(curmob, true))
if (caster->IsAttackAllowed(curmob, true))
continue;
if(caster->CheckAggro(curmob))
if (caster->CheckAggro(curmob))
continue;
}
//if we get here... cast the spell.
curmob->BardPulse(spell_id, caster);
}
if(caster->IsClient())
if (caster->IsClient())
caster->CastToClient()->CheckSongSkillIncrease(spell_id);
}
@ -903,24 +881,23 @@ void EntityList::AEBardPulse(Mob *caster, Mob *center, uint16 spell_id, bool aff
//NPCs handle it differently in Mob::Rampage
void EntityList::AEAttack(Mob *attacker, float dist, int Hand, int count, bool IsFromSpell) {
//Dook- Will need tweaking, currently no pets or players or horses
LinkedListIterator<Mob*> iterator(mob_list);
Mob *curmob;
float dist2 = dist * dist;
int hit = 0;
for(iterator.Reset(); iterator.MoreElements(); iterator.Advance()) {
curmob = iterator.GetData();
if(curmob->IsNPC()
&& curmob != attacker //this is not needed unless NPCs can use this
&&(attacker->IsAttackAllowed(curmob))
&& curmob->GetRace() != 216 && curmob->GetRace() != 472 /* dont attack horses */
&& (curmob->DistNoRoot(*attacker) <= dist2)
for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
curmob = it->second;
if (curmob->IsNPC()
&& curmob != attacker //this is not needed unless NPCs can use this
&&(attacker->IsAttackAllowed(curmob))
&& curmob->GetRace() != 216 && curmob->GetRace() != 472 /* dont attack horses */
&& (curmob->DistNoRoot(*attacker) <= dist2)
) {
attacker->Attack(curmob, Hand, false, false, IsFromSpell);
hit++;
if(count != 0 && hit >= count)
if (count != 0 && hit >= count)
return;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -17,6 +17,8 @@
*/
#ifndef ENTITY_H
#define ENTITY_H
#include <unordered_map>
#include <queue>
#include "../common/types.h"
#include "../common/linked_list.h"
@ -75,25 +77,25 @@ public:
virtual bool Save() { return true; }
virtual void Depop(bool StartSpawnTimer = false) {}
Client* CastToClient();
NPC* CastToNPC();
Mob* CastToMob();
Merc* CastToMerc();
Corpse* CastToCorpse();
Object* CastToObject();
Doors* CastToDoors();
Trap* CastToTrap();
Beacon* CastToBeacon();
Client *CastToClient();
NPC *CastToNPC();
Mob *CastToMob();
Merc *CastToMerc();
Corpse *CastToCorpse();
Object *CastToObject();
Doors *CastToDoors();
Trap *CastToTrap();
Beacon *CastToBeacon();
const Client* CastToClient() const;
const NPC* CastToNPC() const;
const Mob* CastToMob() const;
const Merc* CastToMerc() const;
const Corpse* CastToCorpse() const;
const Object* CastToObject() const;
const Doors* CastToDoors() const;
const Trap* CastToTrap() const;
const Beacon* CastToBeacon() const;
const Client *CastToClient() const;
const NPC *CastToNPC() const;
const Mob *CastToMob() const;
const Merc *CastToMerc() const;
const Corpse *CastToCorpse() const;
const Object *CastToObject() const;
const Doors *CastToDoors() const;
const Trap *CastToTrap() const;
const Beacon *CastToBeacon() const;
inline const uint16& GetID() const { return id; }
@ -108,7 +110,7 @@ public:
protected:
friend class EntityList;
virtual void SetID(uint16 set_id);
inline virtual void SetID(uint16 set_id) { id = set_id; }
uint32 pDBAsyncWorkID;
private:
uint16 id;
@ -129,45 +131,51 @@ public:
~EntityList();
Entity* GetID(uint16 id);
Mob* GetMob(uint16 id);
inline Mob* GetMobID(uint16 id) { return(GetMob(id)); } //for perl
Mob* GetMob(const char* name);
Mob* GetMobByNpcTypeID(uint32 get_id);
Mob* GetTargetForVirus(Mob* spreader);
NPC* GetNPCByID(uint16 id);
NPC* GetNPCByNPCTypeID(uint32 npc_id);
Merc* GetMercByID(uint16 id);
Client* GetClientByName(const char *name);
Client* GetClientByAccID(uint32 accid);
Client* GetClientByID(uint16 id);
Client* GetClientByCharID(uint32 iCharID);
Client* GetClientByWID(uint32 iWID);
Client* GetClient(uint32 ip, uint16 port);
Client* GetRandomClient(float x, float y, float z, float Distance, Client *ExcludeClient = nullptr);
Group* GetGroupByMob(Mob* mob);
Group* GetGroupByClient(Client* client);
Group* GetGroupByID(uint32 id);
Group* GetGroupByLeaderName(const char* leader);
Raid* GetRaidByMob(Mob* mob);
Raid* GetRaidByClient(Client* client);
Raid* GetRaidByID(uint32 id);
Raid* GetRaidByLeaderName(const char *leader);
Mob *GetMob(uint16 id);
inline Mob *GetMobID(uint16 id) { return(GetMob(id)); } //for perl
Mob *GetMob(const char* name);
Mob *GetMobByNpcTypeID(uint32 get_id);
Mob *GetTargetForVirus(Mob* spreader);
inline NPC *GetNPCByID(uint16 id)
{ return npc_list.count(id) ? npc_list.at(id) : nullptr; }
NPC *GetNPCByNPCTypeID(uint32 npc_id);
inline Merc *GetMercByID(uint16 id)
{ return merc_list.count(id) ? merc_list.at(id) : nullptr; }
Client *GetClientByName(const char *name);
Client *GetClientByAccID(uint32 accid);
inline Client *GetClientByID(uint16 id)
{ return client_list.count(id) ? client_list.at(id) : nullptr; }
Client *GetClientByCharID(uint32 iCharID);
Client *GetClientByWID(uint32 iWID);
Client *GetClient(uint32 ip, uint16 port);
Client *GetRandomClient(float x, float y, float z, float Distance, Client *ExcludeClient = nullptr);
Group *GetGroupByMob(Mob* mob);
Group *GetGroupByClient(Client* client);
Group *GetGroupByID(uint32 id);
Group *GetGroupByLeaderName(const char* leader);
Raid *GetRaidByMob(Mob* mob);
Raid *GetRaidByClient(Client* client);
Raid *GetRaidByID(uint32 id);
Raid *GetRaidByLeaderName(const char *leader);
Corpse* GetCorpseByOwner(Client* client);
Corpse* GetCorpseByOwnerWithinRange(Client* client, Mob* center, int range);
Corpse* GetCorpseByID(uint16 id);
Corpse* GetCorpseByDBID(uint32 dbid);
Corpse* GetCorpseByName(const char* name);
Corpse *GetCorpseByOwner(Client* client);
Corpse *GetCorpseByOwnerWithinRange(Client* client, Mob* center, int range);
inline Corpse *GetCorpseByID(uint16 id)
{ return corpse_list.count(id) ? corpse_list.at(id) : nullptr; }
Corpse *GetCorpseByDBID(uint32 dbid);
Corpse *GetCorpseByName(const char* name);
Spawn2* GetSpawnByID(uint32 id);
Client* FindCorpseDragger(const char *CorpseName);
Object* GetObjectByID(uint16 id);
Object* GetObjectByDBID(uint32 id);
Doors* GetDoorsByID(uint16 id);
Doors* GetDoorsByDoorID(uint32 id);
Doors* GetDoorsByDBID(uint32 id);
inline Object *GetObjectByID(uint16 id)
{ return object_list.count(id) ? object_list.at(id) : nullptr; }
Object *GetObjectByDBID(uint32 id);
inline Doors *GetDoorsByID(uint16 id)
{ return door_list.count(id) ? door_list.at(id) : nullptr; }
Doors *GetDoorsByDoorID(uint32 id);
Doors *GetDoorsByDBID(uint32 id);
void RemoveAllCorpsesByCharID(uint32 charid);
void RemoveCorpseByDBID(uint32 dbid);
int RezzAllCorpsesByCharID(uint32 charid);
@ -195,8 +203,8 @@ public:
void ClearAreas();
void ProcessProximitySay(const char *Message, Client *c, uint8 language = 0);
void SendAATimer(uint32 charid,UseAA_Struct* uaa);
Doors* FindDoor(uint8 door_id);
Object* FindObject(uint32 object_id);
Doors *FindDoor(uint8 door_id);
Object *FindObject(uint32 object_id);
Object* FindNearbyObject(float x, float y, float z, float radius);
bool MakeDoorSpawnPacket(EQApplicationPacket* app, Client *client);
bool MakeTrackPacket(Client* client);
@ -242,15 +250,15 @@ public:
void RemoveAllLocalities();
void RemoveAllRaids();
void DestroyTempPets(Mob *owner);
Entity* GetEntityMob(uint16 id);
Entity* GetEntityMob(const char *name);
Entity* GetEntityMerc(uint16 id);
Entity* GetEntityDoor(uint16 id);
Entity* GetEntityObject(uint16 id);
Entity* GetEntityCorpse(uint16 id);
Entity* GetEntityCorpse(const char *name);
Entity* GetEntityTrap(uint16 id);
Entity* GetEntityBeacon(uint16 id);
Entity *GetEntityMob(uint16 id);
Entity *GetEntityMerc(uint16 id);
Entity *GetEntityDoor(uint16 id);
Entity *GetEntityObject(uint16 id);
Entity *GetEntityCorpse(uint16 id);
Entity *GetEntityTrap(uint16 id);
Entity *GetEntityBeacon(uint16 id);
Entity *GetEntityMob(const char *name);
Entity *GetEntityCorpse(const char *name);
void DescribeAggro(Client *towho, NPC *from_who, float dist, bool verbose);
@ -419,20 +427,20 @@ private:
uint32 NumSpawnsOnQueue;
LinkedList<NewSpawn_Struct*> SpawnQueue;
LinkedList<Client*> client_list;
LinkedList<Mob*> mob_list;
LinkedList<NPC*> npc_list;
LinkedList<Merc *> merc_list;
std::list<Group*> group_list;
LinkedList<Corpse*> corpse_list;
LinkedList<Object*> object_list;
LinkedList<Doors*> door_list;
LinkedList<Trap*> trap_list;
LinkedList<Beacon*> beacon_list;
std::list<NPC*> proximity_list;
std::unordered_map<uint16, Client *> client_list;
std::unordered_map<uint16, Mob *> mob_list;
std::unordered_map<uint16, NPC *> npc_list;
std::unordered_map<uint16, Merc *> merc_list;
std::unordered_map<uint16, Corpse *> corpse_list;
std::unordered_map<uint16, Object *> object_list;
std::unordered_map<uint16, Doors *> door_list;
std::unordered_map<uint16, Trap *> trap_list;
std::unordered_map<uint16, Beacon *> beacon_list;
std::list<NPC *> proximity_list;
std::list<Group *> group_list;
std::list<Raid *> raid_list;
std::list<Area> area_list;
uint16 last_insert_id;
std::queue<uint16> free_ids;
// Please Do Not Declare Any EntityList Class Members After This Comment
#ifdef BOTS

View File

@ -230,44 +230,41 @@ void Client::RefreshGuildInfo()
void EntityList::SendGuildMOTD(uint32 guild_id) {
if(guild_id == GUILD_NONE)
return;
LinkedListIterator<Client*> iterator(client_list);
iterator.Reset();
while(iterator.MoreElements()) {
Client* client = iterator.GetData();
auto it = client_list.begin();
while (it != client_list.end()) {
Client *client = it->second;
if (client->GuildID() == guild_id) {
client->SendGuildMOTD();
client->SendGuildURL();
client->SendGuildChannel();
}
iterator.Advance();
++it;
}
}
void EntityList::SendGuildSpawnAppearance(uint32 guild_id) {
if(guild_id == GUILD_NONE)
return;
LinkedListIterator<Client*> iterator(client_list);
iterator.Reset();
while(iterator.MoreElements()) {
Client* client = iterator.GetData();
auto it = client_list.begin();
while (it != client_list.end()) {
Client *client = it->second;
if (client->GuildID() == guild_id) {
client->SendGuildSpawnAppearance();
}
iterator.Advance();
++it;
}
}
void EntityList::RefreshAllGuildInfo(uint32 guild_id) {
if(guild_id == GUILD_NONE)
return;
LinkedListIterator<Client*> iterator(client_list);
iterator.Reset();
while(iterator.MoreElements()) {
Client* client = iterator.GetData();
auto it = client_list.begin();
while (it != client_list.end()) {
Client *client = it->second;
if (client->GuildID() == guild_id) {
client->RefreshGuildInfo();
}
iterator.Advance();
++it;
}
}
@ -278,24 +275,22 @@ void EntityList::SendGuildMembers(uint32 guild_id) {
//this could be optimized a bit to only build the member's packet once
//and then keep swapping out the name in the packet on each send.
LinkedListIterator<Client*> iterator(client_list);
iterator.Reset();
while(iterator.MoreElements()) {
Client* client = iterator.GetData();
auto it = client_list.begin();
while (it != client_list.end()) {
Client *client = it->second;
if (client->GuildID() == guild_id) {
client->SendGuildMembers();
}
iterator.Advance();
++it;
}
}
void EntityList::SendGuildList() {
LinkedListIterator<Client*> iterator(client_list);
iterator.Reset();
while(iterator.MoreElements()) {
Client* client = iterator.GetData();
auto it = client_list.begin();
while (it != client_list.end()) {
Client *client = it->second;
client->SendGuildList();
iterator.Advance();
++it;
}
}

View File

@ -389,11 +389,11 @@ Mob::~Mob()
// the entity list, even after they have been destroyed. Use our memory pointer to remove the mob
// if our EntityID is 0.
//
if(GetID() > 0)
/*if(GetID() > 0)
entity_list.RemoveMob(GetID());
else
entity_list.RemoveMob(this);
entity_list.RemoveMob(this);*/
AI_Stop();
if (GetPet()) {
@ -4907,11 +4907,8 @@ bool Mob::HasSpellEffect(int effectid)
}
int Mob::GetSpecialAbility(int ability) {
auto iter = SpecialAbilities.find(ability);
if(iter != SpecialAbilities.end()) {
return iter->second.level;
}
if (SpecialAbilities.count(ability))
return SpecialAbilities.at(ability).level;
return 0;
}

View File

@ -353,7 +353,7 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float
NPC::~NPC()
{
entity_list.RemoveNPC(GetID());
//entity_list.RemoveNPC(GetID());
AI_Stop();
if(proximity != nullptr) {
@ -362,7 +362,7 @@ NPC::~NPC()
}
//clear our spawn limit record if we had one.
entity_list.LimitRemoveNPC(this);
//entity_list.LimitRemoveNPC(this);
safe_delete(NPCTypedata_ours);

View File

@ -203,16 +203,14 @@ void Trap::Trigger(Mob* trigger)
}
Trap* EntityList::FindNearbyTrap(Mob* searcher, float max_dist) {
LinkedListIterator<Trap*> iterator(trap_list);
iterator.Reset();
float dist = 999999;
Trap* current_trap = nullptr;
float max_dist2 = max_dist*max_dist;
Trap *cur;
while(iterator.MoreElements())
{
cur = iterator.GetData();
auto it = trap_list.begin();
while (it != trap_list.end()) {
cur = it->second;
if(!cur->disarmed) {
float curdist = 0;
float tmp = searcher->GetX() - cur->x;
@ -228,23 +226,21 @@ Trap* EntityList::FindNearbyTrap(Mob* searcher, float max_dist) {
current_trap = cur;
}
}
iterator.Advance();
++it;
}
return current_trap;
}
Mob* EntityList::GetTrapTrigger(Trap* trap) {
LinkedListIterator<Client*> iterator(client_list);
Mob* savemob = 0;
iterator.Reset();
float xdiff, ydiff, zdiff;
float maxdist = trap->radius * trap->radius;
while(iterator.MoreElements()) {
Client* cur = iterator.GetData();
auto it = client_list.begin();
while (it != client_list.end()) {
Client* cur = it->second;
zdiff = cur->GetZ() - trap->z;
if(zdiff < 0)
zdiff = 0 - zdiff;
@ -259,7 +255,7 @@ Mob* EntityList::GetTrapTrigger(Trap* trap) {
else
savemob = cur;
}
iterator.Advance();
++it;
}
return savemob;
}