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) 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 == == 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. 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. 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 //Only iterate through NPCs
LinkedListIterator<NPC*> iterator(npc_list); for (auto it = npc_list.begin(); it != npc_list.end(); ++it) {
for(iterator.Reset(); iterator.MoreElements(); iterator.Advance()) { NPC* mob = it->second;
NPC* mob = iterator.GetData();
//Since >90% of mobs will always be out of range, try to //Since >90% of mobs will always be out of range, try to
//catch them with simple bounding box checks first. These //catch them with simple bounding box checks first. These

View File

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

View File

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

View File

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

View File

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

View File

@ -696,31 +696,27 @@ bool Client::UseDiscipline(uint32 spell_id, uint32 target) {
return(true); return(true);
} }
void EntityList::AETaunt(Client* taunter, float range) { void EntityList::AETaunt(Client* taunter, float range)
LinkedListIterator<NPC*> iterator(npc_list); {
if (range == 0)
if(range == 0) {
range = 100; //arbitrary default... range = 100; //arbitrary default...
}
range = range * range; range = range * range;
iterator.Reset(); auto it = npc_list.begin();
while(iterator.MoreElements()) while (it != npc_list.end()) {
{ NPC *them = it->second;
NPC * them = iterator.GetData();
float zdiff = taunter->GetZ() - them->GetZ(); float zdiff = taunter->GetZ() - them->GetZ();
if (zdiff < 0) if (zdiff < 0)
zdiff *= -1; zdiff *= -1;
if (zdiff < 10 if (zdiff < 10
&& taunter->IsAttackAllowed(them) && taunter->IsAttackAllowed(them)
&& taunter->DistNoRootNoZ(*them) <= range) { && taunter->DistNoRootNoZ(*them) <= range) {
if (taunter->CheckLosFN(them)) { if (taunter->CheckLosFN(them)) {
taunter->Taunt(them, true); 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 // 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) void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster, int16 resist_adjust)
{ {
LinkedListIterator<Mob*> iterator(mob_list);
Mob *curmob; Mob *curmob;
float dist = caster->GetAOERange(spell_id); 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; const int MAX_TARGETS_ALLOWED = 4;
int iCounter = 0; int iCounter = 0;
for(iterator.Reset(); iterator.MoreElements(); iterator.Advance()) for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
{ curmob = it->second;
curmob = iterator.GetData(); if (curmob == center) //do not affect center
if(curmob == center) //do not affect center
continue; continue;
if(curmob == caster && !affect_caster) //watch for caster too if (curmob == caster && !affect_caster) //watch for caster too
continue; continue;
if(center->DistNoRoot(*curmob) > dist2) //make sure they are in range if (center->DistNoRoot(*curmob) > dist2) //make sure they are in range
continue; continue;
if(isnpc && curmob->IsNPC()) { //check npc->npc casting if (isnpc && curmob->IsNPC()) { //check npc->npc casting
FACTION_VALUE f = curmob->GetReverseFactionCon(caster); FACTION_VALUE f = curmob->GetReverseFactionCon(caster);
if(bad) { if (bad) {
//affect mobs that are on our hate list, or //affect mobs that are on our hate list, or
//which have bad faction with us //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; continue;
} else { } else {
//only affect mobs we would assist. //only affect mobs we would assist.
if( ! (f <= FACTION_AMIABLE)) if (!(f <= FACTION_AMIABLE))
continue; continue;
} }
} }
//finally, make sure they are within range //finally, make sure they are within range
if(bad) { if (bad) {
if(!caster->IsAttackAllowed(curmob, true)) if (!caster->IsAttackAllowed(curmob, true))
continue; continue;
if(!center->CheckLosFN(curmob)) if (!center->CheckLosFN(curmob))
continue; 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. // 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 // 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 // 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; continue;
if(caster->CheckAggro(curmob)) if (caster->CheckAggro(curmob))
continue; continue;
} }
//if we get here... cast the spell. //if we get here... cast the spell.
if(IsTargetableAESpell(spell_id) && bad) if (IsTargetableAESpell(spell_id) && bad) {
{ if (iCounter < MAX_TARGETS_ALLOWED) {
if(iCounter < MAX_TARGETS_ALLOWED)
{
caster->SpellOnTarget(spell_id, curmob, false, true, resist_adjust); caster->SpellOnTarget(spell_id, curmob, false, true, resist_adjust);
} }
} } else {
else
{
caster->SpellOnTarget(spell_id, curmob, false, true, resist_adjust); caster->SpellOnTarget(spell_id, curmob, false, true, resist_adjust);
} }
if(!isnpc) //npcs are not target limited... if (!isnpc) //npcs are not target limited...
iCounter++; iCounter++;
} }
} }
void EntityList::MassGroupBuff(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster) void EntityList::MassGroupBuff(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster)
{ {
LinkedListIterator<Mob*> iterator(mob_list);
Mob *curmob; Mob *curmob;
float dist = caster->GetAOERange(spell_id); 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); bool bad = IsDetrimentalSpell(spell_id);
for(iterator.Reset(); iterator.MoreElements(); iterator.Advance()) for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
{ curmob = it->second;
curmob = iterator.GetData(); if (curmob == center) //do not affect center
if(curmob == center) //do not affect center
continue; continue;
if(curmob == caster && !affect_caster) //watch for caster too if (curmob == caster && !affect_caster) //watch for caster too
continue; continue;
if(center->DistNoRoot(*curmob) > dist2) //make sure they are in range if (center->DistNoRoot(*curmob) > dist2) //make sure they are in range
continue; continue;
//Only npcs mgb should hit are client pets... //Only npcs mgb should hit are client pets...
if(curmob->IsNPC()) if (curmob->IsNPC()) {
{
Mob *owner = curmob->GetOwner(); Mob *owner = curmob->GetOwner();
if(owner) if (owner) {
{ if (!owner->IsClient()) {
if(!owner->IsClient())
{
continue; continue;
} }
} } else {
else
{
continue; continue;
} }
} }
if(bad) if (bad) {
{
continue; 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 // NPC spells will only affect other NPCs with compatible faction
void EntityList::AEBardPulse(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster) void EntityList::AEBardPulse(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster)
{ {
LinkedListIterator<Mob*> iterator(mob_list);
Mob *curmob; Mob *curmob;
float dist = caster->GetAOERange(spell_id); 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 bad = IsDetrimentalSpell(spell_id);
bool isnpc = caster->IsNPC(); bool isnpc = caster->IsNPC();
for(iterator.Reset(); iterator.MoreElements(); iterator.Advance()) for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
{ curmob = it->second;
curmob = iterator.GetData(); if (curmob == center) //do not affect center
if(curmob == center) //do not affect center
continue; continue;
if(curmob == caster && !affect_caster) //watch for caster too if (curmob == caster && !affect_caster) //watch for caster too
continue; continue;
if(center->DistNoRoot(*curmob) > dist2) //make sure they are in range if (center->DistNoRoot(*curmob) > dist2) //make sure they are in range
continue; continue;
if(isnpc && curmob->IsNPC()) { //check npc->npc casting if (isnpc && curmob->IsNPC()) { //check npc->npc casting
FACTION_VALUE f = curmob->GetReverseFactionCon(caster); FACTION_VALUE f = curmob->GetReverseFactionCon(caster);
if(bad) { if (bad) {
//affect mobs that are on our hate list, or //affect mobs that are on our hate list, or
//which have bad faction with us //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; continue;
} else { } else {
//only affect mobs we would assist. //only affect mobs we would assist.
if( ! (f <= FACTION_AMIABLE)) if (!(f <= FACTION_AMIABLE))
continue; continue;
} }
} }
//finally, make sure they are within range //finally, make sure they are within range
if(bad) { if (bad) {
if(!center->CheckLosFN(curmob)) if (!center->CheckLosFN(curmob))
continue; 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. // See notes in AESpell() above for more info.
if(caster->IsAttackAllowed(curmob, true)) if (caster->IsAttackAllowed(curmob, true))
continue; continue;
if(caster->CheckAggro(curmob)) if (caster->CheckAggro(curmob))
continue; continue;
} }
//if we get here... cast the spell. //if we get here... cast the spell.
curmob->BardPulse(spell_id, caster); curmob->BardPulse(spell_id, caster);
} }
if(caster->IsClient()) if (caster->IsClient())
caster->CastToClient()->CheckSongSkillIncrease(spell_id); caster->CastToClient()->CheckSongSkillIncrease(spell_id);
} }
@ -903,16 +881,15 @@ void EntityList::AEBardPulse(Mob *caster, Mob *center, uint16 spell_id, bool aff
//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
LinkedListIterator<Mob*> iterator(mob_list);
Mob *curmob; Mob *curmob;
float dist2 = dist * dist; float dist2 = dist * dist;
int hit = 0; int hit = 0;
for(iterator.Reset(); iterator.MoreElements(); iterator.Advance()) { for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
curmob = iterator.GetData(); curmob = it->second;
if(curmob->IsNPC() if (curmob->IsNPC()
&& curmob != attacker //this is not needed unless NPCs can use this && curmob != attacker //this is not needed unless NPCs can use this
&&(attacker->IsAttackAllowed(curmob)) &&(attacker->IsAttackAllowed(curmob))
&& curmob->GetRace() != 216 && curmob->GetRace() != 472 /* dont attack horses */ && curmob->GetRace() != 216 && curmob->GetRace() != 472 /* dont attack horses */
@ -920,7 +897,7 @@ void EntityList::AEAttack(Mob *attacker, float dist, int Hand, int count, bool I
) { ) {
attacker->Attack(curmob, Hand, false, false, IsFromSpell); attacker->Attack(curmob, Hand, false, false, IsFromSpell);
hit++; hit++;
if(count != 0 && hit >= count) if (count != 0 && hit >= count)
return; return;
} }
} }

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -230,44 +230,41 @@ void Client::RefreshGuildInfo()
void EntityList::SendGuildMOTD(uint32 guild_id) { void EntityList::SendGuildMOTD(uint32 guild_id) {
if(guild_id == GUILD_NONE) if(guild_id == GUILD_NONE)
return; return;
LinkedListIterator<Client*> iterator(client_list); auto it = client_list.begin();
iterator.Reset(); while (it != client_list.end()) {
while(iterator.MoreElements()) { Client *client = it->second;
Client* client = iterator.GetData();
if (client->GuildID() == guild_id) { if (client->GuildID() == guild_id) {
client->SendGuildMOTD(); client->SendGuildMOTD();
client->SendGuildURL(); client->SendGuildURL();
client->SendGuildChannel(); client->SendGuildChannel();
} }
iterator.Advance(); ++it;
} }
} }
void EntityList::SendGuildSpawnAppearance(uint32 guild_id) { void EntityList::SendGuildSpawnAppearance(uint32 guild_id) {
if(guild_id == GUILD_NONE) if(guild_id == GUILD_NONE)
return; return;
LinkedListIterator<Client*> iterator(client_list); auto it = client_list.begin();
iterator.Reset(); while (it != client_list.end()) {
while(iterator.MoreElements()) { Client *client = it->second;
Client* client = iterator.GetData();
if (client->GuildID() == guild_id) { if (client->GuildID() == guild_id) {
client->SendGuildSpawnAppearance(); client->SendGuildSpawnAppearance();
} }
iterator.Advance(); ++it;
} }
} }
void EntityList::RefreshAllGuildInfo(uint32 guild_id) { void EntityList::RefreshAllGuildInfo(uint32 guild_id) {
if(guild_id == GUILD_NONE) if(guild_id == GUILD_NONE)
return; return;
LinkedListIterator<Client*> iterator(client_list); auto it = client_list.begin();
iterator.Reset(); while (it != client_list.end()) {
while(iterator.MoreElements()) { Client *client = it->second;
Client* client = iterator.GetData();
if (client->GuildID() == guild_id) { if (client->GuildID() == guild_id) {
client->RefreshGuildInfo(); 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 //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. //and then keep swapping out the name in the packet on each send.
LinkedListIterator<Client*> iterator(client_list); auto it = client_list.begin();
iterator.Reset(); while (it != client_list.end()) {
while(iterator.MoreElements()) { Client *client = it->second;
Client* client = iterator.GetData();
if (client->GuildID() == guild_id) { if (client->GuildID() == guild_id) {
client->SendGuildMembers(); client->SendGuildMembers();
} }
iterator.Advance(); ++it;
} }
} }
void EntityList::SendGuildList() { void EntityList::SendGuildList() {
LinkedListIterator<Client*> iterator(client_list); auto it = client_list.begin();
iterator.Reset(); while (it != client_list.end()) {
while(iterator.MoreElements()) { Client *client = it->second;
Client* client = iterator.GetData();
client->SendGuildList(); 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 // the entity list, even after they have been destroyed. Use our memory pointer to remove the mob
// if our EntityID is 0. // if our EntityID is 0.
// //
if(GetID() > 0) /*if(GetID() > 0)
entity_list.RemoveMob(GetID()); entity_list.RemoveMob(GetID());
else else
entity_list.RemoveMob(this); entity_list.RemoveMob(this);*/
AI_Stop(); AI_Stop();
if (GetPet()) { if (GetPet()) {
@ -4907,11 +4907,8 @@ bool Mob::HasSpellEffect(int effectid)
} }
int Mob::GetSpecialAbility(int ability) { int Mob::GetSpecialAbility(int ability) {
auto iter = SpecialAbilities.find(ability); if (SpecialAbilities.count(ability))
if(iter != SpecialAbilities.end()) { return SpecialAbilities.at(ability).level;
return iter->second.level;
}
return 0; 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() NPC::~NPC()
{ {
entity_list.RemoveNPC(GetID()); //entity_list.RemoveNPC(GetID());
AI_Stop(); AI_Stop();
if(proximity != nullptr) { if(proximity != nullptr) {
@ -362,7 +362,7 @@ NPC::~NPC()
} }
//clear our spawn limit record if we had one. //clear our spawn limit record if we had one.
entity_list.LimitRemoveNPC(this); //entity_list.LimitRemoveNPC(this);
safe_delete(NPCTypedata_ours); safe_delete(NPCTypedata_ours);

View File

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