[Performance] Fixed a large overhead issue where every single NPC in a zone was checking to depop themselves

as a swarm pet every 3ms regardless of being a swarm pet or not. Swarm pets now check to depop only when their timer is up
This commit is contained in:
Akkadius
2017-03-28 02:30:06 -05:00
parent 4b6ce1c19e
commit bf45a5a44f
7 changed files with 86 additions and 73 deletions
+55 -51
View File
@@ -47,20 +47,20 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u
return;
PetRecord record;
if(!database.GetPetEntry(spells[spell_id].teleport_zone, &record))
if (!database.GetPetEntry(spells[spell_id].teleport_zone, &record))
{
Log.Out(Logs::General, Logs::Error, "Unknown swarm pet spell id: %d, check pets table", spell_id);
Message(13, "Unable to find data for pet %s", spells[spell_id].teleport_zone);
return;
}
AA_SwarmPet pet;
SwarmPet_Struct pet;
pet.count = 1;
pet.duration = 1;
for(int x = 0; x < MAX_SWARM_PETS; x++)
for (int x = 0; x < MAX_SWARM_PETS; x++)
{
if(spells[spell_id].effectid[x] == SE_TemporaryPets)
if (spells[spell_id].effectid[x] == SE_TemporaryPets)
{
pet.count = spells[spell_id].base[x];
pet.duration = spells[spell_id].max[x];
@@ -74,14 +74,14 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u
NPCType *made_npc = nullptr;
const NPCType *npc_type = database.LoadNPCTypesData(pet.npc_id);
if(npc_type == nullptr) {
if (npc_type == nullptr) {
//log write
Log.Out(Logs::General, Logs::Error, "Unknown npc type for swarm pet spell id: %d", spell_id);
Message(0,"Unable to find pet!");
Message(0, "Unable to find pet!");
return;
}
if(name_override != nullptr) {
if (name_override != nullptr) {
//we have to make a custom NPC type for this name change
made_npc = new NPCType;
memcpy(made_npc, npc_type, sizeof(NPCType));
@@ -92,7 +92,7 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u
int summon_count = 0;
summon_count = pet.count;
if(summon_count > MAX_SWARM_PETS)
if (summon_count > MAX_SWARM_PETS)
summon_count = MAX_SWARM_PETS;
static const glm::vec2 swarmPetLocations[MAX_SWARM_PETS] = {
@@ -101,59 +101,61 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u
glm::vec2(8, 8), glm::vec2(-8, 8), glm::vec2(8, -8), glm::vec2(-8, -8)
};
while(summon_count > 0) {
while (summon_count > 0) {
int pet_duration = pet.duration;
if(duration_override > 0)
if (duration_override > 0)
pet_duration = duration_override;
//this is a little messy, but the only way to do it right
//it would be possible to optimize out this copy for the last pet, but oh well
NPCType *npc_dup = nullptr;
if(made_npc != nullptr) {
if (made_npc != nullptr) {
npc_dup = new NPCType;
memcpy(npc_dup, made_npc, sizeof(NPCType));
}
NPC* npca = new NPC(
(npc_dup!=nullptr)?npc_dup:npc_type, //make sure we give the NPC the correct data pointer
0,
GetPosition() + glm::vec4(swarmPetLocations[summon_count], 0.0f, 0.0f),
FlyMode3);
NPC* swarm_pet_npc = new NPC(
(npc_dup != nullptr) ? npc_dup : npc_type, //make sure we give the NPC the correct data pointer
0,
GetPosition() + glm::vec4(swarmPetLocations[summon_count], 0.0f, 0.0f),
FlyMode3);
if (followme)
npca->SetFollowID(GetID());
swarm_pet_npc->SetFollowID(GetID());
if(!npca->GetSwarmInfo()){
auto nSI = new AA_SwarmPetInfo;
npca->SetSwarmInfo(nSI);
npca->GetSwarmInfo()->duration = new Timer(pet_duration*1000);
if (!swarm_pet_npc->GetSwarmInfo()) {
auto nSI = new SwarmPet;
swarm_pet_npc->SetSwarmInfo(nSI);
swarm_pet_npc->GetSwarmInfo()->duration = new Timer(pet_duration * 1000);
}
else{
npca->GetSwarmInfo()->duration->Start(pet_duration*1000);
else {
swarm_pet_npc->GetSwarmInfo()->duration->Start(pet_duration * 1000);
}
swarm_pet_npc->StartSwarmTimer(pet_duration * 1000);
//removing this prevents the pet from attacking
npca->GetSwarmInfo()->owner_id = GetID();
swarm_pet_npc->GetSwarmInfo()->owner_id = GetID();
//give the pets somebody to "love"
if(targ != nullptr){
npca->AddToHateList(targ, 1000, 1000);
if (targ != nullptr) {
swarm_pet_npc->AddToHateList(targ, 1000, 1000);
if (RuleB(Spells, SwarmPetTargetLock) || sticktarg)
npca->GetSwarmInfo()->target = targ->GetID();
swarm_pet_npc->GetSwarmInfo()->target = targ->GetID();
else
npca->GetSwarmInfo()->target = 0;
swarm_pet_npc->GetSwarmInfo()->target = 0;
}
//we allocated a new NPC type object, give the NPC ownership of that memory
if(npc_dup != nullptr)
npca->GiveNPCTypeData(npc_dup);
if (npc_dup != nullptr)
swarm_pet_npc->GiveNPCTypeData(npc_dup);
entity_list.AddNPC(npca, true, true);
entity_list.AddNPC(swarm_pet_npc, true, true);
summon_count--;
}
//the target of these swarm pets will take offense to being cast on...
if(targ != nullptr)
if (targ != nullptr)
targ->AddToHateList(this, 1, 0);
// The other pointers we make are handled elsewhere.
@@ -162,7 +164,7 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u
void Mob::TypesTemporaryPets(uint32 typesid, Mob *targ, const char *name_override, uint32 duration_override, bool followme, bool sticktarg) {
AA_SwarmPet pet;
SwarmPet_Struct pet;
pet.count = 1;
pet.duration = 1;
@@ -211,42 +213,44 @@ void Mob::TypesTemporaryPets(uint32 typesid, Mob *targ, const char *name_overrid
memcpy(npc_dup, made_npc, sizeof(NPCType));
}
NPC* npca = new NPC(
NPC* swarm_pet_npc = new NPC(
(npc_dup!=nullptr)?npc_dup:npc_type, //make sure we give the NPC the correct data pointer
0,
GetPosition() + glm::vec4(swarmPetLocations[summon_count], 0.0f, 0.0f),
FlyMode3);
if (followme)
npca->SetFollowID(GetID());
swarm_pet_npc->SetFollowID(GetID());
if(!npca->GetSwarmInfo()){
auto nSI = new AA_SwarmPetInfo;
npca->SetSwarmInfo(nSI);
npca->GetSwarmInfo()->duration = new Timer(pet_duration*1000);
if(!swarm_pet_npc->GetSwarmInfo()){
auto nSI = new SwarmPet;
swarm_pet_npc->SetSwarmInfo(nSI);
swarm_pet_npc->GetSwarmInfo()->duration = new Timer(pet_duration*1000);
}
else{
npca->GetSwarmInfo()->duration->Start(pet_duration*1000);
else {
swarm_pet_npc->GetSwarmInfo()->duration->Start(pet_duration*1000);
}
swarm_pet_npc->StartSwarmTimer(pet_duration * 1000);
//removing this prevents the pet from attacking
npca->GetSwarmInfo()->owner_id = GetID();
swarm_pet_npc->GetSwarmInfo()->owner_id = GetID();
//give the pets somebody to "love"
if(targ != nullptr){
npca->AddToHateList(targ, 1000, 1000);
swarm_pet_npc->AddToHateList(targ, 1000, 1000);
if (RuleB(Spells, SwarmPetTargetLock) || sticktarg)
npca->GetSwarmInfo()->target = targ->GetID();
swarm_pet_npc->GetSwarmInfo()->target = targ->GetID();
else
npca->GetSwarmInfo()->target = 0;
swarm_pet_npc->GetSwarmInfo()->target = 0;
}
//we allocated a new NPC type object, give the NPC ownership of that memory
if(npc_dup != nullptr)
npca->GiveNPCTypeData(npc_dup);
swarm_pet_npc->GiveNPCTypeData(npc_dup);
entity_list.AddNPC(npca, true, true);
entity_list.AddNPC(swarm_pet_npc, true, true);
summon_count--;
}
@@ -404,7 +408,7 @@ void Mob::WakeTheDead(uint16 spell_id, Mob *target, uint32 duration)
auto npca = new NPC(make_npc, 0, GetPosition(), FlyMode3);
if(!npca->GetSwarmInfo()){
auto nSI = new AA_SwarmPetInfo;
auto nSI = new SwarmPet;
npca->SetSwarmInfo(nSI);
npca->GetSwarmInfo()->duration = new Timer(duration*1000);
}
@@ -793,21 +797,21 @@ void Client::RefundAA() {
SendAlternateAdvancementStats();
}
AA_SwarmPetInfo::AA_SwarmPetInfo()
SwarmPet::SwarmPet()
{
target = 0;
owner_id = 0;
duration = nullptr;
}
AA_SwarmPetInfo::~AA_SwarmPetInfo()
SwarmPet::~SwarmPet()
{
target = 0;
owner_id = 0;
safe_delete(duration);
}
Mob *AA_SwarmPetInfo::GetOwner()
Mob *SwarmPet::GetOwner()
{
return entity_list.GetMobID(owner_id);
}