void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, uint32 duration_override, bool followme, bool sticktarg) { //It might not be a bad idea to put these into the database, eventually.. //Dook- swarms and wards PetRecord 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; pet.count = 1; pet.duration = 1; for(int x = 0; x < MAX_SWARM_PETS; x++) { if(spells[spell_id].effectid[x] == SE_TemporaryPets) { pet.count = spells[spell_id].base[x]; pet.duration = spells[spell_id].max[x]; } } pet.duration += GetFocusEffect(focusSwarmPetDuration, spell_id) / 1000; pet.npc_id = record.npc_type; NPCType *made_npc = nullptr; const NPCType *npc_type = database.LoadNPCTypesData(pet.npc_id); 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!"); return; } 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)); strcpy(made_npc->name, name_override); npc_type = made_npc; } int summon_count = 0; summon_count = pet.count; if(summon_count > MAX_SWARM_PETS) summon_count = MAX_SWARM_PETS; static const glm::vec2 swarmPetLocations[MAX_SWARM_PETS] = { glm::vec2(5, 5), glm::vec2(-5, 5), glm::vec2(5, -5), glm::vec2(-5, -5), glm::vec2(10, 10), glm::vec2(-10, 10), glm::vec2(10, -10), glm::vec2(-10, -10), glm::vec2(8, 8), glm::vec2(-8, 8), glm::vec2(8, -8), glm::vec2(-8, -8) }; while(summon_count > 0) { int pet_duration = pet.duration; 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) { 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); if (followme) npca->SetFollowID(GetID()); if(!npca->GetSwarmInfo()){ auto nSI = new AA_SwarmPetInfo; npca->SetSwarmInfo(nSI); npca->GetSwarmInfo()->duration = new Timer(pet_duration*1000); } else{ npca->GetSwarmInfo()->duration->Start(pet_duration*1000); } //removing this prevents the pet from attacking npca->GetSwarmInfo()->owner_id = GetID(); //give the pets somebody to "love" if(targ != nullptr){ npca->AddToHateList(targ, 1000, 1000); if (RuleB(Spells, SwarmPetTargetLock) || sticktarg) npca->GetSwarmInfo()->target = targ->GetID(); else npca->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); entity_list.AddNPC(npca, true, true); summon_count--; } //the target of these swarm pets will take offense to being cast on... if(targ != nullptr) targ->AddToHateList(this, 1, 0); // The other pointers we make are handled elsewhere. delete made_npc; }
void Mob::TypesTemporaryPets(uint32 typesid, Mob *targ, const char *name_override, uint32 duration_override, bool followme, bool sticktarg) { AA_SwarmPet pet; pet.count = 1; pet.duration = 1; pet.npc_id = typesid; NPCType *made_npc = nullptr; const NPCType *npc_type = database.LoadNPCTypesData(typesid); if(npc_type == nullptr) { //log write Log.Out(Logs::General, Logs::Error, "Unknown npc type for swarm pet type id: %d", typesid); Message(0,"Unable to find pet!"); return; } 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)); strcpy(made_npc->name, name_override); npc_type = made_npc; } int summon_count = 0; summon_count = pet.count; if(summon_count > MAX_SWARM_PETS) summon_count = MAX_SWARM_PETS; static const glm::vec2 swarmPetLocations[MAX_SWARM_PETS] = { glm::vec2(5, 5), glm::vec2(-5, 5), glm::vec2(5, -5), glm::vec2(-5, -5), glm::vec2(10, 10), glm::vec2(-10, 10), glm::vec2(10, -10), glm::vec2(-10, -10), glm::vec2(8, 8), glm::vec2(-8, 8), glm::vec2(8, -8), glm::vec2(-8, -8) };; while(summon_count > 0) { int pet_duration = pet.duration; 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) { 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); if (followme) npca->SetFollowID(GetID()); if(!npca->GetSwarmInfo()){ auto nSI = new AA_SwarmPetInfo; npca->SetSwarmInfo(nSI); npca->GetSwarmInfo()->duration = new Timer(pet_duration*1000); } else{ npca->GetSwarmInfo()->duration->Start(pet_duration*1000); } //removing this prevents the pet from attacking npca->GetSwarmInfo()->owner_id = GetID(); //give the pets somebody to "love" if(targ != nullptr){ npca->AddToHateList(targ, 1000, 1000); if (RuleB(Spells, SwarmPetTargetLock) || sticktarg) npca->GetSwarmInfo()->target = targ->GetID(); else npca->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); entity_list.AddNPC(npca, true, true); summon_count--; } // The other pointers we make are handled elsewhere. delete made_npc; }