From a2392121f0a8fed9f19ddadfa2880ed6f4691381 Mon Sep 17 00:00:00 2001 From: megamage Date: Thu, 19 Mar 2009 14:41:30 -0600 Subject: *Fix the bug that summon dbc is not read. Now creatures can be summoned. *Make minipet as tempsummon instead of pet. Make totem as tempsummon. --HG-- branch : trunk --- src/game/SpellEffects.cpp | 74 +++++++++++++---------------------------------- 1 file changed, 20 insertions(+), 54 deletions(-) (limited to 'src/game/SpellEffects.cpp') diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 8645d1ab7d4..eca088eba05 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -1166,7 +1166,7 @@ void Spell::EffectDummy(uint32 i) if(!unitTarget) return; - TemporarySummon* tempSummon = dynamic_cast(unitTarget); + TempSummon* tempSummon = dynamic_cast(unitTarget); if(!tempSummon) return; @@ -3333,11 +3333,6 @@ void Spell::EffectSummonType(uint32 i) case SUMMON_TYPE_SUMMON: EffectSummon(i); break; - case SUMMON_TYPE_CRITTER: - case SUMMON_TYPE_CRITTER2: - case SUMMON_TYPE_CRITTER3: - EffectSummonCritter(i); - break; case SUMMON_TYPE_TOTEM_SLOT1: case SUMMON_TYPE_TOTEM_SLOT2: case SUMMON_TYPE_TOTEM_SLOT3: @@ -3358,15 +3353,18 @@ void Spell::EffectSummonType(uint32 i) sLog.outError("EffectSummonType: Unhandled summon type %u", m_spellInfo->EffectMiscValueB[i]); return; } - switch(SummonProperties->Group) + switch(SummonProperties->Category) { default: - EffectSummonWild(i); + if(SummonProperties->Type == SUMMON_TYPE_MINIPET) + EffectSummonCritter(i); + else + EffectSummonWild(i); break; - case SUMMON_TYPE_POSSESSED: + case SUMMON_CATEGORY_POSSESSED: EffectSummonPossessed(i); break; - case SUMMON_TYPE_VEHICLE: + case SUMMON_CATEGORY_VEHICLE: EffectSummonVehicle(i); break; } @@ -6036,32 +6034,6 @@ void Spell::EffectSummonCritter(uint32 i) if(!pet_entry) return; - Pet* old_critter = player->GetMiniPet(); - - // for same pet just despawn - if(old_critter && old_critter->GetEntry() == pet_entry) - { - player->RemoveMiniPet(); - return; - } - - // despawn old pet before summon new - if(old_critter) - player->RemoveMiniPet(); - - // summon new pet - Pet* critter = new Pet(MINI_PET); - - Map *map = m_caster->GetMap(); - uint32 pet_number = objmgr.GeneratePetNumber(); - if(!critter->Create(objmgr.GenerateLowGuid(HIGHGUID_PET), map, m_caster->GetPhaseMask(), - pet_entry, pet_number)) - { - sLog.outError("Spell::EffectSummonCritter, spellid %u: no such creature entry %u", m_spellInfo->Id, pet_entry); - delete critter; - return; - } - float x,y,z; // If dest location if present if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) @@ -6072,40 +6044,32 @@ void Spell::EffectSummonCritter(uint32 i) } // Summon if dest location not present near caster else - m_caster->GetClosePoint(x,y,z,critter->GetObjectSize()); + m_caster->GetClosePoint(x,y,z,m_caster->GetObjectSize()); - critter->Relocate(x,y,z,m_caster->GetOrientation()); - - if(!critter->IsPositionValid()) - { - sLog.outError("ERROR: Pet (guidlow %d, entry %d) not summoned. Suggested coordinates isn't valid (X: %f Y: %f)", - critter->GetGUIDLow(), critter->GetEntry(), critter->GetPositionX(), critter->GetPositionY()); - delete critter; + int32 duration = GetSpellDuration(m_spellInfo); + TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN; + TempSummon *critter = m_caster->SummonCreature(pet_entry, x, y, z, m_caster->GetOrientation(), summonType, duration); + if(!critter) return; - } critter->SetOwnerGUID(m_caster->GetGUID()); critter->SetCreatorGUID(m_caster->GetGUID()); critter->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,m_caster->getFaction()); critter->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); - critter->AIM_Initialize(); - critter->InitPetCreateSpells(); // e.g. disgusting oozeling has a create spell as critter... + //critter->InitPetCreateSpells(); // e.g. disgusting oozeling has a create spell as critter... critter->SetMaxHealth(1); critter->SetHealth(1); critter->SetLevel(1); - // set timer for unsummon - int32 duration = GetSpellDuration(m_spellInfo); - if(duration > 0) - critter->SetDuration(duration); + critter->SetReactState(REACT_PASSIVE); + critter->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); std::string name = player->GetName(); - name.append(petTypeSuffix[critter->getPetType()]); + name.append(petTypeSuffix[3]); critter->SetName( name ); - player->SetMiniPet(critter); - map->Add((Creature*)critter); + critter->SetSummonProperties(sSummonPropertiesStore.LookupEntry(m_spellInfo->EffectMiscValueB[i])); } void Spell::EffectKnockBack(uint32 i) @@ -6787,6 +6751,8 @@ void Spell::EffectSummonVehicle(uint32 i) float x, y, z; m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE); Vehicle *vehicle = m_caster->SummonVehicle(entry, x, y, z, m_caster->GetOrientation()); + if(!vehicle) + return; vehicle->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); } -- cgit v1.2.3 From c6f3532ada2f7796e3a71cf12d318fdddcd07941 Mon Sep 17 00:00:00 2001 From: QAston Date: Thu, 19 Mar 2009 21:47:16 +0100 Subject: *Fix Area auras for target without a party. *Fix Improved soul leech and correct procflags for soul leech. --HG-- branch : trunk --- sql/updates/2021_world.sql | 6 +++++ sql/updates/CMakeLists.txt | 1 + src/game/Spell.cpp | 1 - src/game/SpellAuras.cpp | 2 +- src/game/SpellEffects.cpp | 18 +++++++++++++- src/game/Unit.cpp | 62 ++++++++++++++++++++++++++++++++++++++-------- src/game/Unit.h | 3 ++- 7 files changed, 79 insertions(+), 14 deletions(-) create mode 100644 sql/updates/2021_world.sql (limited to 'src/game/SpellEffects.cpp') diff --git a/sql/updates/2021_world.sql b/sql/updates/2021_world.sql new file mode 100644 index 00000000000..38e86847763 --- /dev/null +++ b/sql/updates/2021_world.sql @@ -0,0 +1,6 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (30293, 30295, 30296); +INSERT INTO `spell_proc_event` VALUES +-- Soul Leech +(30293, 0x00, 5, 0x00000381, 0x200C0, 0x00000000, 0x0000000, 0x0000000, 0.000000, 0.000000, 0), +(30295, 0x00, 5, 0x00000381, 0x200C0, 0x00000000, 0x0000000, 0x0000000, 0.000000, 0.000000, 0), +(30296, 0x00, 5, 0x00000381, 0x200C0, 0x00000000, 0x0000000, 0x0000000, 0.000000, 0.000000, 0); \ No newline at end of file diff --git a/sql/updates/CMakeLists.txt b/sql/updates/CMakeLists.txt index 83d237c5eb2..7412d137532 100644 --- a/sql/updates/CMakeLists.txt +++ b/sql/updates/CMakeLists.txt @@ -87,4 +87,5 @@ INSTALL(FILES 1939_word.sql 1957_word.sql 2013_world.sql +2021_world.sql DESTINATION share/trinity/sql/updates) \ No newline at end of file diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index dd699e32633..881a68e6c19 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -1524,7 +1524,6 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list &TagUnitMap) // TagUnitMap.push_back(target); //else m_caster->GetRaidMember(TagUnitMap, radius_f); - TagUnitMap.push_back(m_caster); break; } }break; diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 6415638169f..97112095d62 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -651,7 +651,7 @@ void AreaAura::Update(uint32 diff) caster->GetPartyMember(targets, m_radius); break; case AREA_AURA_RAID: - caster->GetRaidMember(targets, m_radius); + caster->GetRaidMember(targets, m_radius); break; case AREA_AURA_FRIEND: { diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index eca088eba05..5176bca920f 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -5099,6 +5099,22 @@ void Spell::EffectScriptEffect(uint32 effIndex) DoCreateItem( effIndex, itemtype ); return; } + // Everlasting Affliction + case 47422: + // Refresh corruption on target + Unit::AuraMap& auras = unitTarget->GetAuras(); + for(Unit::AuraMap::iterator itr = auras.begin(); itr != auras.end(); ++itr) + { + SpellEntry const *spellInfo = (*itr).second->GetSpellProto(); + if( spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && + spellInfo->SpellFamilyFlags[0] & 0x2 && + (*itr).second->GetCasterGUID() == m_caster->GetGUID()) + { + unitTarget->RefreshAurasByCasterSpell(spellInfo->Id, m_caster->GetGUID()); + return; + } + } + break; } break; } @@ -5120,7 +5136,7 @@ void Spell::EffectScriptEffect(uint32 effIndex) spellInfo->SpellFamilyFlags[0] & 0x8000 && (*itr).second->GetCasterGUID() == m_caster->GetGUID()) { - (*itr).second->RefreshAura(); + unitTarget->RefreshAurasByCasterSpell((*itr).second->GetId(), m_caster->GetGUID()); return; } } diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index abb8843efb6..e037c17bead 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -4134,6 +4134,23 @@ void Unit::RemoveAurasByCasterSpell(uint32 spellId, uint8 effindex, uint64 caste } } +void Unit::RefreshAurasByCasterSpell(uint32 spellId, uint64 casterGUID) +{ + // Lookup for auras already applied from spell + for(uint8 i = 0; i < 3; ++i) + { + spellEffectPair spair = spellEffectPair(spellId, i); + for(AuraMap::const_iterator itr = GetAuras().lower_bound(spair); itr != GetAuras().upper_bound(spair); ++itr) + { + if(itr->second->GetCasterGUID()==casterGUID) + { + itr->second->RefreshAura(); + break; + } + } + } +} + void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler) { for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end(); ) @@ -5641,6 +5658,23 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu case 30295: case 30296: { + // Improved Soul Leech + AuraList const& SoulLeechAuras = GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator i = SoulLeechAuras.begin();i != SoulLeechAuras.end(); ++i) + { + if ((*i)->GetId()==54117 || (*i)->GetId()==54118) + { + basepoints0 = int32((*i)->GetModifier()->m_amount); + if (target = GetPet()) + { + // regen mana for pet + CastCustomSpell(target,54607,&basepoints0,NULL,NULL,true,castItem,triggeredByAura); + } + // regen mana for caster + CastCustomSpell(this,59117,&basepoints0,NULL,NULL,true,castItem,triggeredByAura); + break; + } + } // health basepoints0 = int32(damage*triggerAmount/100); target = this; @@ -12658,7 +12692,7 @@ bool Unit::IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura* aura, SpellEntry con if(Player* modOwner = GetSpellModOwner()) { modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_CHANCE_OF_SUCCESS,chance); - modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_PROC_CHANCE,chance); + modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_PROC_PER_MINUTE,chance); } return roll_chance_f(chance); @@ -13378,17 +13412,25 @@ void Unit::GetRaidMember(std::list &nearMembers, float radius) return; Group *pGroup = owner->GetGroup(); - if(!pGroup) - return; - - for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) + if(pGroup) { - Player* Target = itr->getSource(); + for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player* Target = itr->getSource(); - // IsHostileTo check duel and controlled by enemy - if( Target && Target != this && Target->isAlive() - && IsWithinDistInMap(Target, radius) && !IsHostileTo(Target) ) - nearMembers.push_back(Target); + // IsHostileTo check duel and controlled by enemy + if( Target && Target != this && Target->isAlive() + && IsWithinDistInMap(Target, radius) && !IsHostileTo(Target) ) + nearMembers.push_back(Target); + } + } + else + { + if(owner->isAlive() && (owner == this || IsWithinDistInMap(owner, radius))) + nearMembers.push_back(owner); + if(Pet* pet = owner->GetPet()) + if(pet->isAlive() && (pet == this && IsWithinDistInMap(pet, radius))) + nearMembers.push_back(pet); } } diff --git a/src/game/Unit.h b/src/game/Unit.h index d3125aaff61..cee3a93339b 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -114,7 +114,7 @@ enum SpellModOp SPELLMOD_EFFECT3 = 23, SPELLMOD_SPELL_BONUS_DAMAGE = 24, // spellmod 25 - SPELLMOD_PROC_CHANCE = 26, + SPELLMOD_PROC_PER_MINUTE = 26, SPELLMOD_MULTIPLE_VALUE = 27, SPELLMOD_RESIST_DISPEL_CHANCE = 28, SPELLMOD_CRIT_DAMAGE_BONUS_2 = 29, //one not used spell @@ -1235,6 +1235,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject void RemoveAurasDueToItemSpell(Item* castItem,uint32 spellId); void RemoveAurasByCasterSpell(uint32 spellId, uint64 casterGUID, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT); void RemoveAurasByCasterSpell(uint32 spellId, uint8 effindex, uint64 casterGUID, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT); + void RefreshAurasByCasterSpell(uint32 spellId, uint64 casterGUID); void RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler); void RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer); void RemoveAurasDueToSpellByCancel(uint32 spellId); -- cgit v1.2.3 From 5b73a59f154b0748ba58e2039f52ee807fc9b5ec Mon Sep 17 00:00:00 2001 From: megamage Date: Thu, 19 Mar 2009 15:45:22 -0600 Subject: *Set totem slot to 4 but total summon slot to 6. *Fix build. --HG-- branch : trunk --- src/game/Level3.cpp | 41 ------------------------ src/game/Spell.h | 3 ++ src/game/SpellEffects.cpp | 81 ++++++++++++++--------------------------------- src/game/Unit.h | 3 +- 4 files changed, 29 insertions(+), 99 deletions(-) (limited to 'src/game/SpellEffects.cpp') diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index cd8da2cb7ca..5974e818361 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -2901,47 +2901,6 @@ bool ChatHandler::HandleListObjectCommand(const char* args) return true; } -bool ChatHandler::HandleGameObjectNearCommand(const char* args) -{ - float distance = (!*args) ? 10 : atol(args); - uint32 count = 0; - - Player* pl = m_session->GetPlayer(); - QueryResult *result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, map, " - "(POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ " - "FROM gameobject WHERE map='%u' AND (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) <= '%f' ORDER BY order_", - pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), - pl->GetMapId(),pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),distance*distance); - - if (result) - { - do - { - Field *fields = result->Fetch(); - uint32 guid = fields[0].GetUInt32(); - uint32 entry = fields[1].GetUInt32(); - float x = fields[2].GetFloat(); - float y = fields[3].GetFloat(); - float z = fields[4].GetFloat(); - int mapid = fields[5].GetUInt16(); - - GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(entry); - - if(!gInfo) - continue; - - PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid); - - ++count; - } while (result->NextRow()); - - delete result; - } - - PSendSysMessage(LANG_COMMAND_NEAROBJMESSAGE,distance,count); - return true; -} - bool ChatHandler::HandleGameObjectStateCommand(const char* args) { // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r diff --git a/src/game/Spell.h b/src/game/Spell.h index ac7106eaa62..0301f5537eb 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -598,6 +598,9 @@ class Spell void SpellDamageSchoolDmg(uint32 i); void SpellDamageWeaponDmg(uint32 i); void SpellDamageHeal(uint32 i); + + void GetSummonPosition(float &x, float &y, float &z, float radius = 0.0f, uint32 count = 0); + SpellCastResult CanOpenLock(uint32 effIndex, uint32 lockid, SkillType& skillid, int32& reqSkillValue, int32& skillValue); // ------------------------------------------- diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 5176bca920f..e363b2cb41e 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -3681,11 +3681,6 @@ void Spell::EffectSummonWild(uint32 i) } } - // select center of summon position - float center_x = m_targets.m_destX; - float center_y = m_targets.m_destY; - float center_z = m_targets.m_destZ; - float radius = GetSpellRadiusForHostile(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); int32 amount = damage > 0 ? damage : 1; @@ -3693,23 +3688,7 @@ void Spell::EffectSummonWild(uint32 i) for(int32 count = 0; count < amount; ++count) { float px, py, pz; - // If dest location if present - if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) - { - // Summon 1 unit in dest location - if (count == 0) - { - px = m_targets.m_destX; - py = m_targets.m_destY; - pz = m_targets.m_destZ; - } - // Summon in random point all other units if location present - else - m_caster->GetRandomPoint(center_x,center_y,center_z,radius,px,py,pz); - } - // Summon if dest location not present near caster - else - m_caster->GetClosePoint(px,py,pz,3.0f); + GetSummonPosition(px, py, pz, radius, count); int32 duration = GetSpellDuration(m_spellInfo); @@ -5586,10 +5565,8 @@ void Spell::EffectSummonTotem(uint32 i) return; } - float angle = slot < MAX_TOTEM ? M_PI/MAX_TOTEM - (slot*2*M_PI/MAX_TOTEM) : 0; - float x,y,z; - m_caster->GetClosePoint(x,y,z,pTotem->GetObjectSize(),2.0f,angle); + GetSummonPosition(x, y, z); // totem must be at same Z in case swimming caster and etc. if( fabs( z - m_caster->GetPositionZ() ) > 5 ) @@ -6051,16 +6028,7 @@ void Spell::EffectSummonCritter(uint32 i) return; float x,y,z; - // If dest location if present - if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) - { - x = m_targets.m_destX; - y = m_targets.m_destY; - z = m_targets.m_destZ; - } - // Summon if dest location not present near caster - else - m_caster->GetClosePoint(x,y,z,m_caster->GetObjectSize()); + GetSummonPosition(x, y, z); int32 duration = GetSpellDuration(m_spellInfo); TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN; @@ -6534,11 +6502,6 @@ void Spell::EffectSkill(uint32 /*i*/) void Spell::EffectSummonDemon(uint32 i) { - // select center of summon position - float center_x = m_targets.m_destX; - float center_y = m_targets.m_destY; - float center_z = m_targets.m_destZ; - float radius = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); int32 amount = damage > 0 ? damage : 1; @@ -6546,23 +6509,7 @@ void Spell::EffectSummonDemon(uint32 i) for(int32 count = 0; count < amount; ++count) { float px, py, pz; - // If dest location if present - if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) - { - // Summon 1 unit in dest location - if (count == 0) - { - px = m_targets.m_destX; - py = m_targets.m_destY; - pz = m_targets.m_destZ; - } - // Summon in random point all other units if location present - else - m_caster->GetRandomPoint(center_x,center_y,center_z,radius,px,py,pz); - } - // Summon if dest location not present near caster - else - m_caster->GetClosePoint(px,py,pz,3.0f); + GetSummonPosition(px, py, pz, radius, count); int32 duration = GetSpellDuration(m_spellInfo); @@ -6773,6 +6720,26 @@ void Spell::EffectSummonVehicle(uint32 i) vehicle->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); } +void Spell::GetSummonPosition(float &x, float &y, float &z, float radius, uint32 count) +{ + if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) + { + // Summon 1 unit in dest location + if (count == 0) + { + x = m_targets.m_destX; + y = m_targets.m_destY; + z = m_targets.m_destZ; + } + // Summon in random point all other units if location present + else + m_caster->GetRandomPoint(m_targets.m_destX,m_targets.m_destY,m_targets.m_destZ,radius,x,y,z); + } + // Summon if dest location not present near caster + else + m_caster->GetClosePoint(x,y,z,3.0f); +} + void Spell::EffectRenamePet(uint32 /*eff_idx*/) { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_UNIT || diff --git a/src/game/Unit.h b/src/game/Unit.h index cee3a93339b..f153c725edf 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -822,7 +822,8 @@ enum ReactiveType }; #define MAX_REACTIVE 3 -#define MAX_TOTEM 6 +#define MAX_TOTEM 4 +#define MAX_SUMMON_SLOT 6 struct AuraSlotEntry { -- cgit v1.2.3