/* Angelox: This is why the pets ghost - pets were being spawned too far away from its npc owner and some into walls or objects (+10), this sometimes creates the "ghost" effect. I changed to +2 (as close as I could get while it still looked good). I also noticed this can happen if an NPC is spawned on the same spot of another or in a related bad spot.*/ Pet::Pet(NPCType *type_data, Mob *owner, PetType type, int16 spell_id, sint16 power) : NPC(type_data, 0, owner->GetX()+2, owner->GetY()+2, owner->GetZ(), owner->GetHeading(), FlyMode3) { GiveNPCTypeData(type_data); typeofpet = type; petpower = power; SetOwnerID(owner->GetID()); SetPetSpellID(spell_id); taunting = true; }
/* This is why the pets ghost - pets were being spawned too far away from its npc owner and some into walls or objects (+10), this sometimes creates the "ghost" effect. I changed to +2 (as close as I could get while it still looked good). I also noticed this can happen if an NPC is spawned on the same spot of another or in a related bad spot.*/ Pet::Pet(NPCType *type_data, Mob *owner, PetType type, uint16 spell_id, int16 power) : NPC(type_data, 0, owner->GetPosition() + glm::vec4(2.0f, 2.0f, 0.0f, 0.0f), FlyMode3) { GiveNPCTypeData(type_data); typeofpet = type; petpower = power; SetOwnerID(owner->GetID()); SetPetSpellID(spell_id); taunting = true; // Class should use npc constructor to set light properties }
Aura::Aura(NPCType *type_data, Mob *owner, AuraRecord &record) : NPC(type_data, 0, owner->GetPosition(), GravityBehavior::Flying), spell_id(record.spell_id), distance(record.distance), remove_timer(record.duration), movement_timer(100), process_timer(100), aura_id(-1) { GiveNPCTypeData(type_data); // we will delete this later on m_owner = owner->GetID(); if (record.cast_time) { cast_timer.SetTimer(record.cast_time); cast_timer.Disable(); // we don't want to be enabled yet } if (record.aura_type < static_cast<int>(AuraType::Max)) type = static_cast<AuraType>(record.aura_type); else type = AuraType::OnAllGroupMembers; if (record.spawn_type < static_cast<int>(AuraSpawns::Max)) spawn_type = static_cast<AuraSpawns>(record.spawn_type); else spawn_type = AuraSpawns::GroupMembers; if (record.movement < static_cast<int>(AuraMovement::Max)) movement_type = static_cast<AuraMovement>(record.movement); else movement_type = AuraMovement::Follow; switch (type) { case AuraType::OnAllFriendlies: process_func = &Aura::ProcessOnAllFriendlies; break; case AuraType::OnAllGroupMembers: process_func = &Aura::ProcessOnAllGroupMembers; break; case AuraType::OnGroupMembersPets: process_func = &Aura::ProcessOnGroupMembersPets; break; case AuraType::Totem: process_func = &Aura::ProcessTotem; break; case AuraType::EnterTrap: process_func = &Aura::ProcessEnterTrap; break; case AuraType::ExitTrap: process_func = &Aura::ProcessExitTrap; break; default: process_func = nullptr; } }
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.LoadNPCTypesData(500); auto 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->current_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->current_hp = make_npc->current_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->current_hp = make_npc->current_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->current_hp = make_npc->current_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->current_hp = make_npc->current_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->current_hp = make_npc->current_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->current_hp = make_npc->current_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->current_hp = make_npc->current_hp * 135 / 100; make_npc->max_hp = make_npc->max_hp * 135 / 100; break; case WARRIOR: case BERSERKER: strcpy(make_npc->special_abilities, "7,1"); make_npc->max_dmg = make_npc->max_dmg * 150 /100; make_npc->current_hp = make_npc->current_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; auto npca = new NPC(make_npc, 0, GetPosition(), GravityBehavior::Water); if(!npca->GetSwarmInfo()){ auto nSI = new SwarmPet; npca->SetSwarmInfo(nSI); npca->GetSwarmInfo()->duration = new Timer(duration*1000); } else{ npca->GetSwarmInfo()->duration->Start(duration*1000); } npca->StartSwarmTimer(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 = EQEmu::invslot::EQUIPMENT_BEGIN; x <= EQEmu::invslot::EQUIPMENT_END; x++) { uint32 sitem = 0; sitem = CorpseToUse->GetWornItem(x); if(sitem){ const EQEmu::ItemData * itm = database.GetItem(sitem); npca->AddLootDrop(itm, &npca->itemlist, 1, 1, 255, 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); }