mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-16 18:52:22 +00:00
demonstar55's entity list changes (slightly modified) and a crash fix for the #repop command used in rapid succession.
This commit is contained in:
+2
-3
@@ -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
|
||||
|
||||
+47
-58
@@ -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;
|
||||
|
||||
|
||||
+1
-1
@@ -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());
|
||||
|
||||
+16
-25
@@ -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>";
|
||||
|
||||
|
||||
+1
-1
@@ -427,7 +427,7 @@ Client::~Client() {
|
||||
eqs->Close();
|
||||
eqs->ReleaseFromUse();
|
||||
|
||||
entity_list.RemoveClient(this);
|
||||
//entity_list.RemoveClient(this);
|
||||
UninitializeBuffSlots();
|
||||
}
|
||||
|
||||
|
||||
+61
-84
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+1977
-2652
File diff suppressed because it is too large
Load Diff
+83
-75
@@ -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
|
||||
|
||||
+20
-25
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-7
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -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);
|
||||
|
||||
|
||||
+8
-12
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user