[Spells] Updates and fixes to Target Locked Pets (#1932)

* start of rework

* reworked v2 no timer

* fix

* more mechanics

* Update pets.cpp

* move to pet.cpp

* [Spells] Updates and fixes to Target Locked Pets

* [Spells] Updates and fixes to Target Locked Pets
This commit is contained in:
KayenEQ 2022-01-18 21:48:36 -05:00 committed by GitHub
parent 176bfc8524
commit 71c53cb18b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 71 additions and 42 deletions

View File

@ -168,6 +168,7 @@
#define SPELL_ILLUSION_TREE 601 #define SPELL_ILLUSION_TREE 601
#define SPELL_ILLUSION_FEMALE 1731 #define SPELL_ILLUSION_FEMALE 1731
#define SPELL_ILLUSION_MALE 1732 #define SPELL_ILLUSION_MALE 1732
#define SPELL_UNSUMMON_SELF 892
//spellgroup ids //spellgroup ids
#define SPELLGROUP_FRENZIED_BURNOUT 2754 #define SPELLGROUP_FRENZIED_BURNOUT 2754

View File

@ -151,10 +151,14 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u
//give the pets somebody to "love" //give the pets somebody to "love"
if (targ != nullptr) { if (targ != nullptr) {
swarm_pet_npc->AddToHateList(targ, 1000, 1000); swarm_pet_npc->AddToHateList(targ, 1000, 1000);
if (RuleB(Spells, SwarmPetTargetLock) || sticktarg) if (RuleB(Spells, SwarmPetTargetLock) || sticktarg) {
swarm_pet_npc->GetSwarmInfo()->target = targ->GetID(); swarm_pet_npc->GetSwarmInfo()->target = targ->GetID();
else swarm_pet_npc->SetPetTargetLockID(targ->GetID());
swarm_pet_npc->SetSpecialAbility(IMMUNE_AGGRO, 1);
}
else {
swarm_pet_npc->GetSwarmInfo()->target = 0; swarm_pet_npc->GetSwarmInfo()->target = 0;
}
} }
//we allocated a new NPC type object, give the NPC ownership of that memory //we allocated a new NPC type object, give the NPC ownership of that memory
@ -255,10 +259,14 @@ void Mob::TypesTemporaryPets(uint32 typesid, Mob *targ, const char *name_overrid
if(targ != nullptr){ if(targ != nullptr){
swarm_pet_npc->AddToHateList(targ, 1000, 1000); swarm_pet_npc->AddToHateList(targ, 1000, 1000);
if (RuleB(Spells, SwarmPetTargetLock) || sticktarg) if (RuleB(Spells, SwarmPetTargetLock) || sticktarg) {
swarm_pet_npc->GetSwarmInfo()->target = targ->GetID(); swarm_pet_npc->GetSwarmInfo()->target = targ->GetID();
else swarm_pet_npc->SetPetTargetLockID(targ->GetID());
swarm_pet_npc->SetSpecialAbility(IMMUNE_AGGRO, 1);
}
else {
swarm_pet_npc->GetSwarmInfo()->target = 0; swarm_pet_npc->GetSwarmInfo()->target = 0;
}
} }
//we allocated a new NPC type object, give the NPC ownership of that memory //we allocated a new NPC type object, give the NPC ownership of that memory

View File

@ -509,12 +509,8 @@ void NPC::SetTarget(Mob* mob) {
if(mob == GetTarget()) //dont bother if they are allready our target if(mob == GetTarget()) //dont bother if they are allready our target
return; return;
//This is not the default behavior for swarm pets, must be specified from quest functions or rules value. if (GetPetTargetLockID()) {
if(GetSwarmInfo() && GetSwarmInfo()->target && GetTarget() && (GetTarget()->GetHP() > 0)) { TryDepopTargetLockedPets(mob);
Mob *targ = entity_list.GetMob(GetSwarmInfo()->target);
if(targ != mob){
return;
}
} }
if (mob) { if (mob) {
@ -847,6 +843,10 @@ bool NPC::Process()
SpellProcess(); SpellProcess();
if (swarm_timer.Check()) {
DepopSwarmPets();
}
if (mob_close_scan_timer.Check()) { if (mob_close_scan_timer.Check()) {
entity_list.ScanCloseMobs(close_mobs, this, IsMoving()); entity_list.ScanCloseMobs(close_mobs, this, IsMoving());
} }
@ -3091,28 +3091,6 @@ void NPC::DepopSwarmPets()
Depop(); Depop();
return; return;
} }
if (GetSwarmInfo()->target) {
Mob *targMob = entity_list.GetMob(GetSwarmInfo()->target);
if(!targMob || (targMob && targMob->IsCorpse())){
Mob* owner = entity_list.GetMobID(GetSwarmInfo()->owner_id);
if (owner) {
owner->SetTempPetCount(owner->GetTempPetCount() - 1);
}
Depop();
return;
}
}
}
if (IsPet() && GetPetType() == petTargetLock && GetPetTargetLockID()){
Mob *targMob = entity_list.GetMob(GetPetTargetLockID());
if(!targMob || (targMob && targMob->IsCorpse())){
Kill();
return;
}
} }
} }

View File

@ -260,6 +260,7 @@ public:
uint32 GetSwarmTarget(); uint32 GetSwarmTarget();
void SetSwarmTarget(int target_id = 0); void SetSwarmTarget(int target_id = 0);
void DepopSwarmPets(); void DepopSwarmPets();
void TryDepopTargetLockedPets(Mob* current_target);
void PetOnSpawn(NewSpawn_Struct* ns); void PetOnSpawn(NewSpawn_Struct* ns);
void SignalNPC(int _signal_id); void SignalNPC(int _signal_id);

View File

@ -387,20 +387,64 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower,
SetPetID(npc->GetID()); SetPetID(npc->GetID());
// We need to handle PetType 5 (petHatelist), add the current target to the hatelist of the pet // We need to handle PetType 5 (petHatelist), add the current target to the hatelist of the pet
if (record.petcontrol == petTargetLock) if (record.petcontrol == petTargetLock)
{ {
Mob* target = GetTarget(); Mob* m_target = GetTarget();
if (target){ bool activiate_pet = false;
npc->AddToHateList(target, 1); if (m_target && m_target->GetID() != GetID()) {
npc->SetPetTargetLockID(target->GetID());
if (spells[spell_id].target_type == ST_Self) {
float distance = CalculateDistance(m_target->GetX(), m_target->GetY(), m_target->GetZ());
if (distance <= 200) { //Live distance on targetlock pets that self cast. No message is given if not in range.
activiate_pet = true;
}
}
else {
activiate_pet = true;
}
}
if (activiate_pet){
npc->AddToHateList(m_target, 1);
npc->SetPetTargetLockID(m_target->GetID());
npc->SetSpecialAbility(IMMUNE_AGGRO, 1); npc->SetSpecialAbility(IMMUNE_AGGRO, 1);
} }
else else {
npc->Kill(); //On live casts spell 892 Unsummon (Kayen - Too limiting to use that for emu since pet can have more than 20k HP) npc->CastSpell(SPELL_UNSUMMON_SELF, npc->GetID()); //Live like behavior, damages self for 20K
if (!npc->HasDied()) {
npc->Kill(); //Ensure pet dies if over 20k HP.
}
}
} }
} }
void NPC::TryDepopTargetLockedPets(Mob* current_target) {
if (!current_target || (current_target && (current_target->GetID() != GetPetTargetLockID()) || current_target->IsCorpse())) {
//Use when swarmpets are set to auto lock from quest or rule
if (GetSwarmInfo() && GetSwarmInfo()->target) {
Mob* owner = entity_list.GetMobID(GetSwarmInfo()->owner_id);
if (owner) {
owner->SetTempPetCount(owner->GetTempPetCount() - 1);
}
Depop();
return;
}
//Use when pets are given petype 5
if (IsPet() && GetPetType() == petTargetLock && GetPetTargetLockID()) {
CastSpell(SPELL_UNSUMMON_SELF, GetID()); //Live like behavior, damages self for 20K
if (!HasDied()) {
Kill(); //Ensure pet dies if over 20k HP.
}
return;
}
}
}
/* This is why the pets ghost - pets were being spawned too far away from its npc owner and some /* 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 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.*/ 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.*/

View File

@ -136,9 +136,6 @@ void Mob::SpellProcess()
void NPC::SpellProcess() void NPC::SpellProcess()
{ {
Mob::SpellProcess(); Mob::SpellProcess();
if (swarm_timer.Check()) {
DepopSwarmPets();
}
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////