diff --git a/changelog.txt b/changelog.txt index b80128505..d72b4ca23 100644 --- a/changelog.txt +++ b/changelog.txt @@ -2,6 +2,10 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- == 11/13/2014 == Kayen: Implemented target type (44) 'Beams' (which projects an AE infront of caster with a specified length and width). +Kayen: Implemented target type (32) AE Target HateList +Kayen: Implemented target type (36) Area Client Only +Kayen: Implemented target type (37) Area PC Only +Kayen: Implemented target type (39) Group No Pet == 11/12/2014 == Uleat: Changed 'GMTrainee' struct to reflect the actual client hard-coded max skill count (100) - applies to all currently supported clients (6.2->RoF) diff --git a/common/spdat.h b/common/spdat.h index b71b3c2ad..da2e4486c 100644 --- a/common/spdat.h +++ b/common/spdat.h @@ -119,7 +119,7 @@ typedef enum { /* 29 */ // NOT USED /* 30 */ // NOT USED /* 31 */ // NOT USED -/* 32 */ ST_AECaster2 = 0x20, //ae caster hatelist maybe? +/* 32 */ ST_AETargetHateList = 0x20, /* 33 */ ST_HateList = 0x21, /* 34 */ ST_LDoNChest_Cursed = 0x22, /* 35 */ ST_Muramite = 0x23, //only works on special muramites diff --git a/zone/effects.cpp b/zone/effects.cpp index 9888258d9..16024c169 100644 --- a/zone/effects.cpp +++ b/zone/effects.cpp @@ -766,6 +766,10 @@ void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_ continue; if (spells[spell_id].targettype == ST_TargetAENoPlayersPets && curmob->IsPetOwnerClient()) continue; + if (spells[spell_id].targettype == ST_AreaClientOnly && !curmob->IsClient()) + continue; + if (spells[spell_id].targettype == ST_AreaNPCOnly && !curmob->IsNPC()) + continue; if (spells[spell_id].targettype == ST_Ring) { dist_targ = curmob->DistNoRoot(caster->GetTargetRingX(), caster->GetTargetRingY(), caster->GetTargetRingZ()); diff --git a/zone/groups.cpp b/zone/groups.cpp index e80650f08..ae51f51c9 100644 --- a/zone/groups.cpp +++ b/zone/groups.cpp @@ -693,7 +693,7 @@ void Group::CastGroupSpell(Mob* caster, uint16 spell_id) { if(members[z] == caster) { caster->SpellOnTarget(spell_id, caster); #ifdef GROUP_BUFF_PETS - if(caster->GetPet() && caster->HasPetAffinity() && !caster->GetPet()->IsCharmed()) + if(spells[spell_id].targettype != ST_GroupNoPets && caster->GetPet() && caster->HasPetAffinity() && !caster->GetPet()->IsCharmed()) caster->SpellOnTarget(spell_id, caster->GetPet()); #endif } @@ -704,7 +704,7 @@ void Group::CastGroupSpell(Mob* caster, uint16 spell_id) { members[z]->CalcSpellPowerDistanceMod(spell_id, distance); caster->SpellOnTarget(spell_id, members[z]); #ifdef GROUP_BUFF_PETS - if(members[z]->GetPet() && members[z]->HasPetAffinity() && !members[z]->GetPet()->IsCharmed()) + if(spells[spell_id].targettype != ST_GroupNoPets && members[z]->GetPet() && members[z]->HasPetAffinity() && !members[z]->GetPet()->IsCharmed()) caster->SpellOnTarget(spell_id, members[z]->GetPet()); #endif } else diff --git a/zone/hate_list.cpp b/zone/hate_list.cpp index e9117db98..2ee904453 100644 --- a/zone/hate_list.cpp +++ b/zone/hate_list.cpp @@ -557,12 +557,15 @@ int HateList::AreaRampage(Mob *caster, Mob *target, int count, ExtraAttackOption return ret; } -void HateList::SpellCast(Mob *caster, uint32 spell_id, float range) +void HateList::SpellCast(Mob *caster, uint32 spell_id, float range, Mob* ae_center) { if(!caster) - { return; - } + + Mob* center = caster; + + if (ae_center) + center = ae_center; //this is slower than just iterating through the list but avoids //crashes when people kick the bucket in the middle of this call @@ -578,7 +581,7 @@ void HateList::SpellCast(Mob *caster, uint32 spell_id, float range) tHateEntry *h = (*iterator); if(range > 0) { - dist_targ = caster->DistNoRoot(*h->ent); + dist_targ = center->DistNoRoot(*h->ent); if(dist_targ <= range && dist_targ >= min_range2) { id_list.push_back(h->ent->GetID()); diff --git a/zone/hate_list.h b/zone/hate_list.h index a3e6c6a88..4ea8d0bd6 100644 --- a/zone/hate_list.h +++ b/zone/hate_list.h @@ -63,7 +63,7 @@ public: int AreaRampage(Mob *caster, Mob *target, int count, ExtraAttackOptions *opts); - void SpellCast(Mob *caster, uint32 spell_id, float range); + void SpellCast(Mob *caster, uint32 spell_id, float range, Mob *ae_center = nullptr); bool IsEmpty(); void PrintToClient(Client *c); diff --git a/zone/raids.cpp b/zone/raids.cpp index 041b92ad4..d1e8db464 100644 --- a/zone/raids.cpp +++ b/zone/raids.cpp @@ -478,7 +478,7 @@ void Raid::CastGroupSpell(Mob* caster, uint16 spellid, uint32 gid) if(members[x].member == caster) { caster->SpellOnTarget(spellid, caster); #ifdef GROUP_BUFF_PETS - if(caster->GetPet() && caster->HasPetAffinity() && !caster->GetPet()->IsCharmed()) + if(spells[spellid].targettype != ST_GroupNoPets && caster->GetPet() && caster->HasPetAffinity() && !caster->GetPet()->IsCharmed()) caster->SpellOnTarget(spellid, caster->GetPet()); #endif } @@ -489,7 +489,7 @@ void Raid::CastGroupSpell(Mob* caster, uint16 spellid, uint32 gid) if(distance <= range2){ caster->SpellOnTarget(spellid, members[x].member); #ifdef GROUP_BUFF_PETS - if(members[x].member->GetPet() && members[x].member->HasPetAffinity() && !members[x].member->GetPet()->IsCharmed()) + if(spells[spellid].targettype != ST_GroupNoPets && members[x].member->GetPet() && members[x].member->HasPetAffinity() && !members[x].member->GetPet()->IsCharmed()) caster->SpellOnTarget(spellid, members[x].member->GetPet()); #endif } diff --git a/zone/spells.cpp b/zone/spells.cpp index e6cab8422..5b8bfef39 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -1611,7 +1611,45 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce break; } + case ST_AETargetHateList: + { + if (spells[spell_id].range > 0) + { + if(!spell_target) + return false; + + ae_center = spell_target; + CastAction = AETarget; + } + else { + spell_target = nullptr; + ae_center = this; + CastAction = CAHateList; + } + break; + } + + case ST_AreaClientOnly: + case ST_AreaNPCOnly: + { + if (spells[spell_id].range > 0) + { + if(!spell_target) + return false; + + ae_center = spell_target; + CastAction = AETarget; + } + else { + spell_target = nullptr; + ae_center = this; + CastAction = AECaster; + } + break; + } + case ST_UndeadAE: //should only affect undead... + case ST_SummonedAE: case ST_TargetAETap: case ST_AETarget: case ST_TargetAENoPlayersPets: @@ -1630,6 +1668,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce // Group spells case ST_GroupTeleport: case ST_Group: + case ST_GroupNoPets: { if(IsClient() && CastToClient()->TGB() && IsTGBCompatibleSpell(spell_id)) { if( (!target) || @@ -2043,15 +2082,28 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16 } else { // regular PB AE or targeted AE spell - spell_target is null if PB if(spell_target) // this must be an AETarget spell - { + { + bool cast_on_target = true; + if (spells[spell_id].targettype == ST_TargetAENoPlayersPets && spell_target->IsPetOwnerClient()) + cast_on_target = false; + if (spells[spell_id].targettype == ST_AreaClientOnly && !spell_target->IsClient()) + cast_on_target = false; + if (spells[spell_id].targettype == ST_AreaNPCOnly && !spell_target->IsNPC()) + cast_on_target = false; + // affect the target too - SpellOnTarget(spell_id, spell_target, false, true, resist_adjust); + if (cast_on_target) + SpellOnTarget(spell_id, spell_target, false, true, resist_adjust); } if(ae_center && ae_center == this && IsBeneficialSpell(spell_id)) SpellOnTarget(spell_id, this); bool affect_caster = !IsNPC(); //NPC AE spells do not affect the NPC caster - entity_list.AESpell(this, ae_center, spell_id, affect_caster, resist_adjust); + + if (spells[spell_id].targettype == ST_AETargetHateList) + hate_list.SpellCast(this, spell_id, spells[spell_id].aoerange, ae_center); + else + entity_list.AESpell(this, ae_center, spell_id, affect_caster, resist_adjust); } break; } @@ -2109,7 +2161,7 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16 SpellOnTarget(spell_id, this); #ifdef GROUP_BUFF_PETS //pet too - if (GetPet() && HasPetAffinity() && !GetPet()->IsCharmed()) + if (spells[spell_id].targettype != ST_GroupNoPets && GetPet() && HasPetAffinity() && !GetPet()->IsCharmed()) SpellOnTarget(spell_id, GetPet()); #endif } @@ -2117,7 +2169,7 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16 SpellOnTarget(spell_id, spell_target); #ifdef GROUP_BUFF_PETS //pet too - if (spell_target->GetPet() && HasPetAffinity() && !spell_target->GetPet()->IsCharmed()) + if (spells[spell_id].targettype != ST_GroupNoPets && spell_target->GetPet() && HasPetAffinity() && !spell_target->GetPet()->IsCharmed()) SpellOnTarget(spell_id, spell_target->GetPet()); #endif }