diff options
author | maximius <none@none> | 2009-10-17 15:35:07 -0700 |
---|---|---|
committer | maximius <none@none> | 2009-10-17 15:35:07 -0700 |
commit | 26b5e033ffde3d161382fc9addbfa99738379641 (patch) | |
tree | a344f369ca32945f787a02dee35c3dbe342bed7e /src/game/SpellHandler.cpp | |
parent | f21f47005dcb6b76e1abc9f35fbcd03eed191bff (diff) |
*Massive cleanup (\n\n -> \n, *\n -> \n, cleanup for(...) to for (...), and some other cleanups by hand)
*Fix a possible crash in Spell::DoAllEffectOnTarget
--HG--
branch : trunk
Diffstat (limited to 'src/game/SpellHandler.cpp')
-rw-r--r-- | src/game/SpellHandler.cpp | 111 |
1 files changed, 4 insertions, 107 deletions
diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp index b8aa4469472..31eb05ae802 100644 --- a/src/game/SpellHandler.cpp +++ b/src/game/SpellHandler.cpp @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "Common.h" #include "DBCStores.h" #include "WorldPacket.h" @@ -32,61 +31,50 @@ #include "TemporarySummon.h" #include "SpellAuras.h" #include "CreatureAI.h" - void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) { // TODO: add targets.read() check Player* pUser = _player; - // ignore for remote control state if(pUser->m_mover != pUser) return; - uint8 bagIndex, slot; uint8 unk_flags; // flags (if 0x02 - some additional data are received) uint8 cast_count; // next cast if exists (single or not) uint64 item_guid; uint32 glyphIndex; // something to do with glyphs? uint32 spellid; // casted spell id - recvPacket >> bagIndex >> slot >> cast_count >> spellid >> item_guid >> glyphIndex >> unk_flags; - Item *pItem = pUser->GetUseableItemByPos(bagIndex, slot); if(!pItem) { pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); return; } - if(pItem->GetGUID() != item_guid) { pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); return; } - sLog.outDetail("WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, cast_count: %u, spellid: %u, Item: %u, glyphIndex: %u, unk_flags: %u, data length = %i", bagIndex, slot, cast_count, spellid, pItem->GetEntry(), glyphIndex, unk_flags, (uint32)recvPacket.size()); - ItemPrototype const *proto = pItem->GetProto(); if(!proto) { pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL ); return; } - // some item classes can be used only in equipped state if(proto->InventoryType != INVTYPE_NON_EQUIP && !pItem->IsEquipped()) { pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL ); return; } - uint8 msg = pUser->CanUseItem(pItem); if( msg != EQUIP_ERR_OK ) { pUser->SendEquipError( msg, pItem, NULL ); return; } - // only allow conjured consumable, bandage, poisons (all should have the 2^21 item flag set in DB) if( proto->Class == ITEM_CLASS_CONSUMABLE && !(proto->Flags & ITEM_FLAGS_USEABLE_IN_ARENA) && @@ -95,7 +83,6 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH,pItem,NULL); return; } - if (pUser->isInCombat()) { for(int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) @@ -110,7 +97,6 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) } } } - // check also BIND_WHEN_PICKED_UP and BIND_QUEST_ITEM for .additem or .additemset case by GM (not binded at adding to inventory) if( pItem->GetProto()->Bonding == BIND_WHEN_USE || pItem->GetProto()->Bonding == BIND_WHEN_PICKED_UP || pItem->GetProto()->Bonding == BIND_QUEST_ITEM ) { @@ -120,31 +106,26 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) pItem->SetBinding( true ); } } - SpellCastTargets targets; if (!targets.read(&recvPacket, pUser)) return; - targets.Update(pUser); - if (!pItem->IsTargetValidForItemUse(targets.getUnitTarget())) { // free gray item after use fail pUser->SendEquipError(EQUIP_ERR_NONE, pItem, NULL); - // send spell error if (SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid)) { - // for implicit area/coord target spells + // for implicit area/coord target spells if(!targets.getUnitTarget()) Spell::SendCastResult(_player,spellInfo,cast_count,SPELL_FAILED_NO_VALID_TARGETS); - // for explicit target spells + // for explicit target spells else - Spell::SendCastResult(_player,spellInfo,cast_count,SPELL_FAILED_BAD_TARGETS); + Spell::SendCastResult(_player,spellInfo,cast_count,SPELL_FAILED_BAD_TARGETS); } return; } - //Note: If script stop casting it must send appropriate data to client to prevent stuck item in gray state. if(!Script->ItemUse(pUser,pItem,targets)) { @@ -152,59 +133,46 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) pUser->CastItemUseSpell(pItem,targets,cast_count,glyphIndex); } } - #define OPEN_CHEST 11437 #define OPEN_SAFE 11535 #define OPEN_CAGE 11792 #define OPEN_BOOTY_CHEST 5107 #define OPEN_STRONGBOX 8517 - void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket) { sLog.outDetail("WORLD: CMSG_OPEN_ITEM packet, data length = %i",(uint32)recvPacket.size()); - Player* pUser = _player; - // ignore for remote control state if(pUser->m_mover != pUser) return; - uint8 bagIndex, slot; - recvPacket >> bagIndex >> slot; - sLog.outDetail("bagIndex: %u, slot: %u",bagIndex,slot); - Item *pItem = pUser->GetItemByPos(bagIndex, slot); if(!pItem) { pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); return; } - ItemPrototype const *proto = pItem->GetProto(); if(!proto) { pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL ); return; } - if(!pUser->GetSession()->HandleOnItemOpen(pItem)) return; - // locked item uint32 lockId = proto->LockID; if(lockId) { LockEntry const *lockInfo = sLockStore.LookupEntry(lockId); - if (!lockInfo) { pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, pItem, NULL ); sLog.outError( "WORLD::OpenItem: item [guid = %u] has an unknown lockId: %u!", pItem->GetGUIDLow() , lockId); return; } - // required picklocking if(lockInfo->Skill[1] || lockInfo->Skill[0]) { @@ -212,7 +180,6 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket) return; } } - if(pItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED))// wrapped? { QueryResult *result = CharacterDatabase.PQuery("SELECT entry, flags FROM character_gifts WHERE item_guid = '%u'", pItem->GetGUIDLow()); @@ -221,7 +188,6 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket) Field *fields = result->Fetch(); uint32 entry = fields[0].GetUInt32(); uint32 flags = fields[1].GetUInt32(); - pItem->SetUInt64Value(ITEM_FIELD_GIFTCREATOR, 0); pItem->SetEntry(entry); pItem->SetUInt32Value(ITEM_FIELD_FLAGS, flags); @@ -239,51 +205,36 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket) else pUser->SendLoot(pItem->GetGUID(),LOOT_CORPSE); } - void WorldSession::HandleGameObjectUseOpcode( WorldPacket & recv_data ) { uint64 guid; - recv_data >> guid; - sLog.outDebug( "WORLD: Recvd CMSG_GAMEOBJ_USE Message [guid=%u]", GUID_LOPART(guid)); - // ignore for remote control state if(_player->m_mover != _player) return; - GameObject *obj = GetPlayer()->GetMap()->GetGameObject(guid); - if(!obj) return; - if (Script->GOHello(_player, obj)) return; - obj->Use(_player); } - void WorldSession::HandleGameobjectReportUse(WorldPacket& recvPacket) { uint64 guid; recvPacket >> guid; - sLog.outDebug( "WORLD: Recvd CMSG_GAMEOBJ_REPORT_USE Message [in game guid: %u]", GUID_LOPART(guid)); - // ignore for remote control state if(_player->m_mover != _player) return; - GameObject* go = GetPlayer()->GetMap()->GetGameObject(guid); if(!go) return; - if(!go->IsWithinDistInMap(_player,INTERACTION_DISTANCE)) return; - _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT, go->GetEntry()); } - void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) { uint32 spellId; @@ -291,7 +242,6 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) recvPacket >> cast_count; recvPacket >> spellId; recvPacket >> unk_flags; // flags (if 0x02 - some additional data are received) - // ignore for remote control state (for player case) Unit* mover = _player->m_mover; if(mover != _player && mover->GetTypeId()==TYPEID_PLAYER) @@ -299,19 +249,15 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet return; } - sLog.outDebug("WORLD: got cast spell packet, spellId - %u, cast_count: %u, unk_flags %u, data length = %i", spellId, cast_count, unk_flags, (uint32)recvPacket.size()); - SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId ); - if(!spellInfo) { sLog.outError("WORLD: unknown spell id %u", spellId); recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet return; } - if(mover->GetTypeId()==TYPEID_PLAYER) { // not have spell in spellbook or spell passive and not casted by client @@ -332,17 +278,14 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) return; } } - // Client is resending autoshot cast opcode when other spell is casted during shoot rotation // Skip it to prevent "interrupt" message if (IsAutoRepeatRangedSpell(spellInfo) && _player->GetCurrentSpell(CURRENT_AUTOREPEAT_SPELL) && _player->GetCurrentSpell(CURRENT_AUTOREPEAT_SPELL)->m_spellInfo == spellInfo) return; - // can't use our own spells when we're in possession of another unit, if(_player->isPossessing()) return; - // client provided targets SpellCastTargets targets; if(!targets.read(&recvPacket,mover)) @@ -350,7 +293,6 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet return; } - // some spell cast packet including more data (for projectiles?) if (unk_flags & 0x02) { @@ -361,46 +303,36 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) MovementInfo movementInfo; ReadMovementInfo(recvPacket, &movementInfo); } - // auto-selection buff level base at target level (in spellInfo) if(targets.getUnitTarget()) { SpellEntry const *actualSpellInfo = spellmgr.SelectAuraRankForPlayerLevel(spellInfo,targets.getUnitTarget()->getLevel()); - // if rank not found then function return NULL but in explicit cast case original spell can be casted and later failed with appropriate error message if(actualSpellInfo) spellInfo = actualSpellInfo; } - Spell *spell = new Spell(mover, spellInfo, false); spell->m_cast_count = cast_count; // set count of casts spell->prepare(&targets); } - void WorldSession::HandleCancelCastOpcode(WorldPacket& recvPacket) { uint32 spellId; - recvPacket.read_skip<uint8>(); // counter, increments with every CANCEL packet, don't use for now recvPacket >> spellId; - if(_player->IsNonMeleeSpellCasted(false)) _player->InterruptNonMeleeSpells(false,spellId,false); } - void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket) { uint32 spellId; recvPacket >> spellId; - SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); if (!spellInfo) return; - // not allow remove non positive spells and spells with attr SPELL_ATTR_CANT_CANCEL if(!IsPositiveSpell(spellId) || (spellInfo->Attributes & SPELL_ATTR_CANT_CANCEL)) return; - // channeled spell case (it currently casted then) if (IsChanneledSpell(spellInfo)) { @@ -409,124 +341,96 @@ void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket) _player->InterruptSpell(CURRENT_CHANNELED_SPELL); return; } - // non channeled case // maybe should only remove one buff when there are multiple? _player->RemoveAurasDueToSpell(spellId, 0, AURA_REMOVE_BY_CANCEL); } - void WorldSession::HandlePetCancelAuraOpcode( WorldPacket& recvPacket) { uint64 guid; uint32 spellId; - recvPacket >> guid; recvPacket >> spellId; - SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId ); if(!spellInfo) { sLog.outError("WORLD: unknown PET spell id %u", spellId); return; } - Creature* pet=ObjectAccessor::GetCreatureOrPetOrVehicle(*_player,guid); - if(!pet) { sLog.outError( "Pet %u not exist.", uint32(GUID_LOPART(guid)) ); return; } - if(pet != GetPlayer()->GetGuardianPet() && pet != GetPlayer()->GetCharm()) { sLog.outError( "HandlePetCancelAura.Pet %u isn't pet of player %s", uint32(GUID_LOPART(guid)),GetPlayer()->GetName() ); return; } - if(!pet->isAlive()) { pet->SendPetActionFeedback(FEEDBACK_PET_DEAD); return; } - pet->RemoveAurasDueToSpell(spellId); - pet->AddCreatureSpellCooldown(spellId); } - void WorldSession::HandleCancelGrowthAuraOpcode( WorldPacket& /*recvPacket*/) { // nothing do } - void WorldSession::HandleCancelAutoRepeatSpellOpcode( WorldPacket& /*recvPacket*/) { // may be better send SMSG_CANCEL_AUTO_REPEAT? // cancel and prepare for deleting _player->InterruptSpell(CURRENT_AUTOREPEAT_SPELL); } - void WorldSession::HandleCancelChanneling( WorldPacket & recv_data) { recv_data.read_skip<uint32>(); // spellid, not used - // ignore for remote control state (for player case) Unit* mover = _player->m_mover; if(mover != _player && mover->GetTypeId()==TYPEID_PLAYER) return; - mover->InterruptSpell(CURRENT_CHANNELED_SPELL); } - void WorldSession::HandleTotemDestroyed( WorldPacket& recvPacket) { // ignore for remote control state if(_player->m_mover != _player) return; - uint8 slotId; - recvPacket >> slotId; - ++slotId; if (slotId >= MAX_TOTEM_SLOT) return; - if(!_player->m_SummonSlot[slotId]) return; - Creature* totem = GetPlayer()->GetMap()->GetCreature(_player->m_SummonSlot[slotId]); // Don't unsummon sentry totem if(totem && totem->isTotem() && totem->GetEntry() != SENTRY_TOTEM_ENTRY) ((Totem*)totem)->UnSummon(); } - void WorldSession::HandleSelfResOpcode( WorldPacket & /*recv_data*/ ) { sLog.outDebug("WORLD: CMSG_SELF_RES"); // empty opcode - if(_player->GetUInt32Value(PLAYER_SELF_RES_SPELL)) { SpellEntry const *spellInfo = sSpellStore.LookupEntry(_player->GetUInt32Value(PLAYER_SELF_RES_SPELL)); if(spellInfo) _player->CastSpell(_player,spellInfo,false,0); - _player->SetUInt32Value(PLAYER_SELF_RES_SPELL, 0); } } - void WorldSession::HandleSpellClick( WorldPacket & recv_data ) { uint64 guid; recv_data >> guid; - // this will get something not in world. crash Creature *unit = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, guid); - if(!unit) return; - // TODO: Unit::SetCharmedBy: 28782 is not in world but 0 is trying to charm it! -> crash if(!unit->IsInWorld()) { @@ -534,7 +438,6 @@ void WorldSession::HandleSpellClick( WorldPacket & recv_data ) assert(false); return; } - SpellClickInfoMapBounds clickPair = objmgr.GetSpellClickInfoMapBounds(unit->GetEntry()); for(SpellClickInfoMap::const_iterator itr = clickPair.first; itr != clickPair.second; ++itr) { @@ -546,19 +449,15 @@ void WorldSession::HandleSpellClick( WorldPacket & recv_data ) caster->CastSpell(target, itr->second.spellId, true, NULL, NULL, origCasterGUID); } } - if(unit->IsVehicle()) _player->EnterVehicle(unit); - unit->AI()->DoAction(EVENT_SPELLCLICK); } - void WorldSession::HandleMirrrorImageDataRequest( WorldPacket & recv_data ) { sLog.outDebug("WORLD: CMSG_GET_MIRRORIMAGE_DATA"); uint64 guid; recv_data >> guid; - // Get unit for which data is needed by client Unit *unit = ObjectAccessor::GetObjectInWorld(guid, (Unit*)NULL); if(!unit) @@ -577,14 +476,12 @@ void WorldSession::HandleMirrrorImageDataRequest( WorldPacket & recv_data ) data << (uint8)pCreator->getGender(); data << (uint8)pCreator->getClass(); data << (uint8)pCreator->GetByteValue(PLAYER_BYTES, 0); // skin - data << (uint8)pCreator->GetByteValue(PLAYER_BYTES, 1); // face data << (uint8)pCreator->GetByteValue(PLAYER_BYTES, 2); // hair data << (uint8)pCreator->GetByteValue(PLAYER_BYTES, 3); // haircolor data << (uint8)pCreator->GetByteValue(PLAYER_BYTES_2, 0); // facialhair - data << (uint32)pCreator->GetGuildId(); // unk - static const EquipmentSlots ItemSlots[] = + static const EquipmentSlots ItemSlots[] = { EQUIPMENT_SLOT_HEAD, EQUIPMENT_SLOT_SHOULDERS, |