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; }
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::WakeTheDead(uint16 spell_id, Mob *target, uint32 duration) { Corpse *CorpseToUse = nullptr; CorpseToUse = entity_list.GetClosestCorpse(this, nullptr); if (!CorpseToUse) return; //assuming we have pets in our table; we take the first pet as a base type. const NPCType *base_type = database.GetNPCType(500); NPCType *make_npc = new NPCType; memcpy(make_npc, base_type, sizeof(NPCType)); //combat stats make_npc->AC = ((GetLevel() * 7) + 550); make_npc->ATK = GetLevel(); make_npc->max_dmg = (GetLevel() * 4) + 2; make_npc->min_dmg = 1; //base stats make_npc->cur_hp = (GetLevel() * 55); make_npc->max_hp = (GetLevel() * 55); make_npc->STR = 85 + (GetLevel() * 3); make_npc->STA = 85 + (GetLevel() * 3); make_npc->DEX = 85 + (GetLevel() * 3); make_npc->AGI = 85 + (GetLevel() * 3); make_npc->INT = 85 + (GetLevel() * 3); make_npc->WIS = 85 + (GetLevel() * 3); make_npc->CHA = 85 + (GetLevel() * 3); make_npc->MR = 25; make_npc->FR = 25; make_npc->CR = 25; make_npc->DR = 25; make_npc->PR = 25; //level class and gender make_npc->level = GetLevel(); make_npc->class_ = CorpseToUse->class_; make_npc->race = CorpseToUse->race; make_npc->gender = CorpseToUse->gender; make_npc->loottable_id = 0; //name char NewName[64]; sprintf(NewName, "%s`s Animated Corpse", GetCleanName()); strcpy(make_npc->name, NewName); //appearance make_npc->beard = CorpseToUse->beard; make_npc->beardcolor = CorpseToUse->beardcolor; make_npc->eyecolor1 = CorpseToUse->eyecolor1; make_npc->eyecolor2 = CorpseToUse->eyecolor2; make_npc->haircolor = CorpseToUse->haircolor; make_npc->hairstyle = CorpseToUse->hairstyle; make_npc->helmtexture = CorpseToUse->helmtexture; make_npc->luclinface = CorpseToUse->luclinface; make_npc->size = CorpseToUse->size; make_npc->texture = CorpseToUse->texture; //cast stuff.. based off of PEQ's if you want to change //it you'll have to mod this code, but most likely //most people will be using PEQ style for the first //part of their spell list; can't think of any smooth //way to do this //some basic combat mods here too since it's convienent switch (CorpseToUse->class_) { case CLERIC: make_npc->npc_spells_id = 1; break; case WIZARD: make_npc->npc_spells_id = 2; break; case NECROMANCER: make_npc->npc_spells_id = 3; break; case MAGICIAN: make_npc->npc_spells_id = 4; break; case ENCHANTER: make_npc->npc_spells_id = 5; break; case SHAMAN: make_npc->npc_spells_id = 6; break; case DRUID: make_npc->npc_spells_id = 7; break; case PALADIN: //SPECATK_TRIPLE strcpy(make_npc->special_abilities, "6,1"); make_npc->cur_hp = make_npc->cur_hp * 150 / 100; make_npc->max_hp = make_npc->max_hp * 150 / 100; make_npc->npc_spells_id = 8; break; case SHADOWKNIGHT: strcpy(make_npc->special_abilities, "6,1"); make_npc->cur_hp = make_npc->cur_hp * 150 / 100; make_npc->max_hp = make_npc->max_hp * 150 / 100; make_npc->npc_spells_id = 9; break; case RANGER: strcpy(make_npc->special_abilities, "7,1"); make_npc->cur_hp = make_npc->cur_hp * 135 / 100; make_npc->max_hp = make_npc->max_hp * 135 / 100; make_npc->npc_spells_id = 10; break; case BARD: strcpy(make_npc->special_abilities, "6,1"); make_npc->cur_hp = make_npc->cur_hp * 110 / 100; make_npc->max_hp = make_npc->max_hp * 110 / 100; make_npc->npc_spells_id = 11; break; case BEASTLORD: strcpy(make_npc->special_abilities, "7,1"); make_npc->cur_hp = make_npc->cur_hp * 110 / 100; make_npc->max_hp = make_npc->max_hp * 110 / 100; make_npc->npc_spells_id = 12; break; case ROGUE: strcpy(make_npc->special_abilities, "7,1"); make_npc->max_dmg = make_npc->max_dmg * 150 / 100; make_npc->cur_hp = make_npc->cur_hp * 110 / 100; make_npc->max_hp = make_npc->max_hp * 110 / 100; break; case MONK: strcpy(make_npc->special_abilities, "7,1"); make_npc->max_dmg = make_npc->max_dmg * 150 / 100; make_npc->cur_hp = make_npc->cur_hp * 135 / 100; make_npc->max_hp = make_npc->max_hp * 135 / 100; break; case WARRIOR: strcpy(make_npc->special_abilities, "7,1"); make_npc->max_dmg = make_npc->max_dmg * 150 / 100; make_npc->cur_hp = make_npc->cur_hp * 175 / 100; make_npc->max_hp = make_npc->max_hp * 175 / 100; break; default: make_npc->npc_spells_id = 0; break; } make_npc->loottable_id = 0; make_npc->merchanttype = 0; make_npc->d_melee_texture1 = 0; make_npc->d_melee_texture2 = 0; NPC* npca = new NPC(make_npc, 0, GetPosition(), FlyMode3); if (!npca->GetSwarmInfo()){ AA_SwarmPetInfo* nSI = new AA_SwarmPetInfo; npca->SetSwarmInfo(nSI); npca->GetSwarmInfo()->duration = new Timer(duration * 1000); } else{ npca->GetSwarmInfo()->duration->Start(duration * 1000); } npca->GetSwarmInfo()->owner_id = GetID(); //give the pet somebody to "love" if (target != nullptr){ npca->AddToHateList(target, 100000); npca->GetSwarmInfo()->target = target->GetID(); } //gear stuff, need to make sure there's //no situation where this stuff can be duped for (int x = EmuConstants::EQUIPMENT_BEGIN; x <= EmuConstants::EQUIPMENT_END; x++) // (< 21) added MainAmmo { uint32 sitem = 0; sitem = CorpseToUse->GetWornItem(x); if (sitem){ const Item_Struct * itm = database.GetItem(sitem); npca->AddLootDrop(itm, &npca->itemlist, 1, 1, 127, true, true); } } //we allocated a new NPC type object, give the NPC ownership of that memory if (make_npc != nullptr) npca->GiveNPCTypeData(make_npc); entity_list.AddNPC(npca, true, true); //the target of these swarm pets will take offense to being cast on... if (target != nullptr) target->AddToHateList(this, 1, 0); }