diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/game/BattleGround.cpp | 9 | ||||
-rw-r--r-- | src/game/BattleGroundHandler.cpp | 2 | ||||
-rw-r--r-- | src/game/ChatHandler.cpp | 36 | ||||
-rw-r--r-- | src/game/GameObject.cpp | 26 | ||||
-rw-r--r-- | src/game/Group.cpp | 104 | ||||
-rw-r--r-- | src/game/Group.h | 2 | ||||
-rw-r--r-- | src/game/GroupHandler.cpp | 40 | ||||
-rw-r--r-- | src/game/Item.h | 9 | ||||
-rw-r--r-- | src/game/ItemPrototype.h | 3 | ||||
-rw-r--r-- | src/game/Level3.cpp | 13 | ||||
-rw-r--r-- | src/game/PetAI.cpp | 5 | ||||
-rw-r--r-- | src/game/PetAI.h | 1 | ||||
-rw-r--r-- | src/game/Player.cpp | 274 | ||||
-rw-r--r-- | src/game/Player.h | 8 | ||||
-rw-r--r-- | src/game/Spell.cpp | 7 | ||||
-rw-r--r-- | src/game/SpellAuras.cpp | 29 | ||||
-rw-r--r-- | src/game/SpellEffects.cpp | 4 | ||||
-rw-r--r-- | src/game/SpellMgr.h | 5 | ||||
-rw-r--r-- | src/game/Unit.cpp | 62 | ||||
-rw-r--r-- | src/game/Unit.h | 2 |
20 files changed, 390 insertions, 251 deletions
diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp index cdaeb5546ae..1cc510a35f2 100644 --- a/src/game/BattleGround.cpp +++ b/src/game/BattleGround.cpp @@ -1167,10 +1167,15 @@ void BattleGround::AddOrSetPlayerToCorrectBgGroup(Player *plr, uint64 plr_guid, if(group->IsMember(plr_guid)) { uint8 subgroup = group->GetMemberGroup(plr_guid); - plr->SetGroup(group, subgroup); + plr->SetBattleGroundRaid(group, subgroup); } else - GetBgRaid(team)->AddMember(plr_guid, plr->GetName()); + { + group->AddMember(plr_guid, plr->GetName()); + if( Group* originalGroup = plr->GetOriginalGroup() ) + if( originalGroup->IsLeader(plr_guid) ) + group->ChangeLeader(plr_guid); + } } } diff --git a/src/game/BattleGroundHandler.cpp b/src/game/BattleGroundHandler.cpp index 6dc1d9785a3..f3be835e0f2 100644 --- a/src/game/BattleGroundHandler.cpp +++ b/src/game/BattleGroundHandler.cpp @@ -432,8 +432,6 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data ) _player->GetMotionMaster()->MovementExpired(); _player->m_taxi.ClearTaxiDestinations(); } - //TODO FIX ME this call must be removed! - _player->RemoveFromGroup(); sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType()); _player->GetSession()->SendPacket(&data); diff --git a/src/game/ChatHandler.cpp b/src/game/ChatHandler.cpp index 0fc6500e736..ba4be69e1b0 100644 --- a/src/game/ChatHandler.cpp +++ b/src/game/ChatHandler.cpp @@ -234,13 +234,15 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) if(msg.empty()) break; - Group *group = GetPlayer()->GetGroup(); - if(!group) + // if player is in battleground, he cannot say to battleground members by /p + Group *group = GetPlayer()->GetOriginalGroup(); + // so if player hasn't OriginalGroup and his player->GetGroup() is BG raid, then return + if( !group && (!(group = GetPlayer()->GetGroup()) || group->isBGGroup()) ) return; WorldPacket data; ChatHandler::FillMessageData(&data, this, CHAT_MSG_PARTY, lang, NULL, 0, msg.c_str(),NULL); - group->BroadcastPacket(&data, group->GetMemberGroup(GetPlayer()->GetGUID())); + group->BroadcastPacket(&data, false, group->GetMemberGroup(GetPlayer()->GetGUID())); } break; case CHAT_MSG_GUILD: @@ -314,13 +316,15 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) if(msg.empty()) break; - Group *group = GetPlayer()->GetGroup(); - if(!group || !group->isRaidGroup() || group->isBGGroup()) + // if player is in battleground, he cannot say to battleground members by /ra + Group *group = GetPlayer()->GetOriginalGroup(); + // so if player hasn't OriginalGroup and his player->GetGroup() is BG raid or his group isn't raid, then return + if( !group && !(group = GetPlayer()->GetGroup()) || group->isBGGroup() || !group->isRaidGroup() ) return; WorldPacket data; ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID, lang, "", 0, msg.c_str(),NULL); - group->BroadcastPacket(&data); + group->BroadcastPacket(&data, false); } break; case CHAT_MSG_RAID_LEADER: { @@ -340,13 +344,14 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) if(msg.empty()) break; - Group *group = GetPlayer()->GetGroup(); - if(!group || !group->isRaidGroup() || !group->IsLeader(GetPlayer()->GetGUID()) || group->isBGGroup()) + // if player is in battleground, he cannot say to battleground members by /ra + Group *group = GetPlayer()->GetOriginalGroup(); + if( !group && !(group = GetPlayer()->GetGroup()) || group->isBGGroup() || !group->isRaidGroup() || !group->IsLeader(GetPlayer()->GetGUID())) return; WorldPacket data; ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID_LEADER, lang, "", 0, msg.c_str(),NULL); - group->BroadcastPacket(&data); + group->BroadcastPacket(&data, false); } break; case CHAT_MSG_RAID_WARNING: { @@ -365,8 +370,9 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) return; WorldPacket data; + //in battleground, raid warning is sent only to players in battleground - code is ok ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID_WARNING, lang, "", 0, msg.c_str(),NULL); - group->BroadcastPacket(&data); + group->BroadcastPacket(&data, false); } break; case CHAT_MSG_BATTLEGROUND: @@ -381,13 +387,14 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) if(msg.empty()) break; + //battleground raid is always in Player->GetGroup(), never in GetOriginalGroup() Group *group = GetPlayer()->GetGroup(); - if(!group || !group->isRaidGroup() || !group->isBGGroup()) + if(!group || !group->isBGGroup()) return; WorldPacket data; ChatHandler::FillMessageData(&data, this, CHAT_MSG_BATTLEGROUND, lang, "", 0, msg.c_str(),NULL); - group->BroadcastPacket(&data); + group->BroadcastPacket(&data, false); } break; case CHAT_MSG_BATTLEGROUND_LEADER: @@ -402,13 +409,14 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) if(msg.empty()) break; + //battleground raid is always in Player->GetGroup(), never in GetOriginalGroup() Group *group = GetPlayer()->GetGroup(); - if(!group || !group->isRaidGroup() || !group->IsLeader(GetPlayer()->GetGUID()) || !group->isBGGroup()) + if(!group || !group->isBGGroup() || !group->IsLeader(GetPlayer()->GetGUID())) return; WorldPacket data; ChatHandler::FillMessageData(&data, this, CHAT_MSG_BATTLEGROUND_LEADER, lang, "", 0, msg.c_str(),NULL); - group->BroadcastPacket(&data); + group->BroadcastPacket(&data, false); } break; case CHAT_MSG_CHANNEL: diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index 583bcab36c4..95a83ce6819 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -1364,8 +1364,28 @@ void GameObject::Use(Unit* user) spell->prepare(&targets); } -void GameObject::CastSpell(Unit* target, uint32 spell) +void GameObject::CastSpell(Unit* target, uint32 spellId) { + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); + if(!spellInfo) + return; + + bool self = false; + for(int i = 0; i < 3; ++i) + { + if(spellInfo->EffectImplicitTargetA[i] == TARGET_UNIT_CASTER) + { + self = true; + break; + } + } + + if(self) + { + target->CastSpell(target, spellInfo, true); + return; + } + //summon world trigger Creature *trigger = SummonTrigger(GetPositionX(), GetPositionY(), GetPositionZ(), 0, 1); if(!trigger) return; @@ -1374,12 +1394,12 @@ void GameObject::CastSpell(Unit* target, uint32 spell) if(Unit *owner = GetOwner()) { trigger->setFaction(owner->getFaction()); - trigger->CastSpell(target, spell, true, 0, 0, owner->GetGUID()); + trigger->CastSpell(target, spellInfo, true, 0, 0, owner->GetGUID()); } else { trigger->setFaction(14); - trigger->CastSpell(target, spell, true, 0, 0, target->GetGUID()); + trigger->CastSpell(target, spellInfo, true, 0, 0, target->GetGUID()); } //trigger->setDeathState(JUST_DIED); //trigger->RemoveCorpse(); diff --git a/src/game/Group.cpp b/src/game/Group.cpp index 1a2301a0fb7..f4a977c3d7c 100644 --- a/src/game/Group.cpp +++ b/src/game/Group.cpp @@ -203,7 +203,8 @@ void Group::ConvertToRaid() _initRaidSubGroupsCounter(); - if(!isBGGroup()) CharacterDatabase.PExecute("UPDATE groups SET isRaid = 1 WHERE leaderGuid='%u'", GUID_LOPART(m_leaderGuid)); + if(!isBGGroup()) + CharacterDatabase.PExecute("UPDATE groups SET isRaid = 1 WHERE leaderGuid='%u'", GUID_LOPART(m_leaderGuid)); SendUpdate(); // update quest related GO states (quest activity dependent from raid membership) @@ -214,7 +215,12 @@ void Group::ConvertToRaid() bool Group::AddInvite(Player *player) { - if(!player || player->GetGroupInvite() || player->GetGroup()) + if( !player || player->GetGroupInvite() ) + return false; + Group* group = player->GetGroup(); + if( group && group->isBGGroup() ) + group = player->GetOriginalGroup(); + if( group ) return false; RemoveInvite(player); @@ -327,9 +333,17 @@ uint32 Group::RemoveMember(const uint64 &guid, const uint8 &method) player->GetSession()->SendPacket( &data ); } - data.Initialize(SMSG_GROUP_LIST, 24); - data << uint64(0) << uint64(0) << uint64(0); - player->GetSession()->SendPacket(&data); + //we already removed player from group and in player->GetGroup() is his original group! + if( Group* group = player->GetGroup() ) + { + group->SendUpdate(); + } + else + { + data.Initialize(SMSG_GROUP_LIST, 24); + data << uint64(0) << uint64(0) << uint64(0); + player->GetSession()->SendPacket(&data); + } _homebindIfInstance(player); } @@ -338,7 +352,7 @@ uint32 Group::RemoveMember(const uint64 &guid, const uint8 &method) { WorldPacket data(SMSG_GROUP_SET_LEADER, (m_memberSlots.front().name.size()+1)); data << m_memberSlots.front().name; - BroadcastPacket(&data); + BroadcastPacket(&data, true); } SendUpdate(); @@ -361,7 +375,7 @@ void Group::ChangeLeader(const uint64 &guid) WorldPacket data(SMSG_GROUP_SET_LEADER, slot->name.size()+1); data << slot->name; - BroadcastPacket(&data); + BroadcastPacket(&data, true); SendUpdate(); } @@ -375,13 +389,23 @@ void Group::Disband(bool hideDestroy) if(!player) continue; - player->SetGroup(NULL); + //we cannot call _removeMember because it would invalidate member iterator + //if we are removing player from battleground raid + if( isBGGroup() ) + player->RemoveFromBattleGroundRaid(); + else + { + //we can remove player who is in battleground from his original group + if( player->GetOriginalGroup() == this ) + player->SetOriginalGroup(NULL); + else + player->SetGroup(NULL); + } // quest related GO state dependent from raid membership if(isRaidGroup()) player->UpdateForQuestsGO(); - if(!player->GetSession()) continue; @@ -392,9 +416,17 @@ void Group::Disband(bool hideDestroy) player->GetSession()->SendPacket(&data); } - data.Initialize(SMSG_GROUP_LIST, 24); - data << uint64(0) << uint64(0) << uint64(0); - player->GetSession()->SendPacket(&data); + //we already removed player from group and in player->GetGroup() is his original group, send update + if( Group* group = player->GetGroup() ) + { + group->SendUpdate(); + } + else + { + data.Initialize(SMSG_GROUP_LIST, 24); + data << uint64(0) << uint64(0) << uint64(0); + player->GetSession()->SendPacket(&data); + } _homebindIfInstance(player); } @@ -842,7 +874,7 @@ void Group::SetTargetIcon(uint8 id, uint64 guid) data << (uint8)0; data << id; data << guid; - BroadcastPacket(&data); + BroadcastPacket(&data, true); } void Group::GetDataForXPAtKill(Unit const* victim, uint32& count,uint32& sum_level, Player* & member_with_max_level, Player* & not_gray_member_with_max_level) @@ -895,7 +927,7 @@ void Group::SendUpdate() for(member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) { player = objmgr.GetPlayer(citr->guid); - if(!player || !player->GetSession()) + if(!player || !player->GetSession() || player->GetGroup() != this ) continue; // guess size WorldPacket data(SMSG_GROUP_LIST, (1+1+1+1+8+4+GetMembersCount()*20)); @@ -909,11 +941,14 @@ void Group::SendUpdate() { if(citr->guid == citr2->guid) continue; + Player* member = objmgr.GetPlayer(citr2->guid); + uint8 onlineState = (member) ? MEMBER_STATUS_ONLINE : MEMBER_STATUS_OFFLINE; + onlineState = onlineState | ((isBGGroup()) ? MEMBER_STATUS_PVP : 0); data << citr2->name; data << (uint64)citr2->guid; // online-state - data << (uint8)(objmgr.GetPlayer(citr2->guid) ? 1 : 0); + data << (uint8)(onlineState); data << (uint8)(citr2->group); // groupid data << (uint8)(citr2->assistant?0x01:0); // 0x2 main assist, 0x4 main tank } @@ -947,12 +982,12 @@ void Group::UpdatePlayerOutOfRange(Player* pPlayer) } } -void Group::BroadcastPacket(WorldPacket *packet, int group, uint64 ignore) +void Group::BroadcastPacket(WorldPacket *packet, bool ignorePlayersInBGRaid, int group, uint64 ignore) { for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next()) { Player *pl = itr->getSource(); - if(!pl || (ignore != 0 && pl->GetGUID() == ignore)) + if(!pl || (ignore != 0 && pl->GetGUID() == ignore) || (ignorePlayersInBGRaid && pl->GetGroup() != this) ) continue; if (pl->GetSession() && (group==-1 || itr->getSubGroup()==group)) @@ -1031,7 +1066,15 @@ bool Group::_addMember(const uint64 &guid, const char* name, bool isAssistant, u if(player) { player->SetGroupInvite(NULL); - player->SetGroup(this, group); + //if player is in group and he is being added to BG raid group, then call SetBattleGroundRaid() + if( player->GetGroup() && isBGGroup() ) + player->SetBattleGroundRaid(this, group); + //if player is in bg raid and we are adding him to normal group, then call SetOriginalGroup() + else if ( player->GetGroup() ) + player->SetOriginalGroup(this, group); + //if player is not in group, then call set group + else + player->SetGroup(this, group); // if the same group invites the player back, cancel the homebind timer InstanceGroupBind *bind = GetBoundInstance(player->GetMapId(), player->GetDifficulty()); if(bind && bind->save->GetInstanceId() == player->GetInstanceId()) @@ -1058,7 +1101,17 @@ bool Group::_removeMember(const uint64 &guid) Player *player = objmgr.GetPlayer(guid); if (player) { - player->SetGroup(NULL); + //if we are removing player from battleground raid + if( isBGGroup() ) + player->RemoveFromBattleGroundRaid(); + else + { + //we can remove player who is in battleground from his original group + if( player->GetOriginalGroup() == this ) + player->SetOriginalGroup(NULL); + else + player->SetGroup(NULL); + } } _removeRolls(guid); @@ -1250,12 +1303,17 @@ void Group::ChangeMembersGroup(Player *player, const uint8 &group) return; if(_setMembersGroup(player->GetGUID(), group)) { - uint8 prevSubGroup; - prevSubGroup = player->GetSubGroup(); - + uint8 prevSubGroup = player->GetSubGroup(); + if( player->GetGroup() == this ) + player->GetGroupRef().setSubGroup(group); + //if player is in BG raid, it is possible that he is also in normal raid - and that normal raid is stored in m_originalGroup reference + else + { + prevSubGroup = player->GetOriginalSubGroup(); + player->GetOriginalGroupRef().setSubGroup(group); + } SubGroupCounterDecrease(prevSubGroup); - player->GetGroupRef().setSubGroup(group); SendUpdate(); } } diff --git a/src/game/Group.h b/src/game/Group.h index 939f240a7e2..d09ef616897 100644 --- a/src/game/Group.h +++ b/src/game/Group.h @@ -293,7 +293,7 @@ class TRINITY_DLL_SPEC Group void SendUpdate(); void UpdatePlayerOutOfRange(Player* pPlayer); // ignore: GUID of player that will be ignored - void BroadcastPacket(WorldPacket *packet, int group=-1, uint64 ignore=0); + void BroadcastPacket(WorldPacket *packet, bool ignorePlayersInBGRaid, int group=-1, uint64 ignore=0); void BroadcastReadyCheck(WorldPacket *packet); void OfflineReadyCheck(); diff --git a/src/game/GroupHandler.cpp b/src/game/GroupHandler.cpp index a3f719c640f..df9f0fc0a1a 100644 --- a/src/game/GroupHandler.cpp +++ b/src/game/GroupHandler.cpp @@ -57,12 +57,6 @@ void WorldSession::HandleGroupInviteOpcode( WorldPacket & recv_data ) std::string membername; recv_data >> membername; - if(_player->InBattleGround()) - { - SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_INVITE_RESTRICTED); - return; - } - // attempt add selected player // cheating @@ -105,15 +99,20 @@ void WorldSession::HandleGroupInviteOpcode( WorldPacket & recv_data ) return; } + Group *group = GetPlayer()->GetGroup(); + if( group && group->isBGGroup() ) + group = GetPlayer()->GetOriginalGroup(); + + Group *group2 = player->GetGroup(); + if( group2 && group2->isBGGroup() ) + group2 = player->GetOriginalGroup(); // player already in another group or invited - if(player->GetGroup() || player->GetGroupInvite() ) + if( group2 || player->GetGroupInvite() ) { SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_ALREADY_IN_GROUP); return; } - Group *group = GetPlayer()->GetGroup(); - if(group) { // not have permissions for invite @@ -122,7 +121,6 @@ void WorldSession::HandleGroupInviteOpcode( WorldPacket & recv_data ) SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_YOU_NOT_LEADER); return; } - // not have place if(group->IsFull()) { @@ -193,28 +191,19 @@ void WorldSession::HandleGroupAcceptOpcode( WorldPacket & /*recv_data*/ ) Player* leader = objmgr.GetPlayer(group->GetLeaderGUID()); - if(leader && leader->InBattleGround()) - { - SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_INVITE_RESTRICTED); - return; - } - // forming a new group, create it if(!group->IsCreated()) { - if(leader) group->RemoveInvite(leader); + if( leader ) + group->RemoveInvite(leader); group->Create(group->GetLeaderGUID(), group->GetLeaderName()); objmgr.AddGroup(group); } - // everything's fine, do it + // everything's fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!! if(!group->AddMember(GetPlayer()->GetGUID(), GetPlayer()->GetName())) return; - uint8 subgroup = group->GetMemberGroup(GetPlayer()->GetGUID()); - - GetPlayer()->SetGroup(group, subgroup); - group->BroadcastGroupUpdate(); } @@ -434,7 +423,7 @@ void WorldSession::HandleMinimapPingOpcode(WorldPacket& recv_data) data << GetPlayer()->GetGUID(); data << x; data << y; - GetPlayer()->GetGroup()->BroadcastPacket(&data, -1, GetPlayer()->GetGUID()); + GetPlayer()->GetGroup()->BroadcastPacket(&data, true, -1, GetPlayer()->GetGUID()); } void WorldSession::HandleRandomRollOpcode(WorldPacket& recv_data) @@ -461,7 +450,7 @@ void WorldSession::HandleRandomRollOpcode(WorldPacket& recv_data) data << roll; data << GetPlayer()->GetGUID(); if(GetPlayer()->GetGroup()) - GetPlayer()->GetGroup()->BroadcastPacket(&data); + GetPlayer()->GetGroup()->BroadcastPacket(&data, false); else SendPacket(&data); } @@ -522,6 +511,7 @@ void WorldSession::HandleGroupChangeSubGroupOpcode( WorldPacket & recv_data ) { CHECK_PACKET_SIZE(recv_data,1+1); + // we will get correct pointer for group here, so we don't have to check if group is BG raid Group *group = GetPlayer()->GetGroup(); if(!group) return; @@ -626,7 +616,7 @@ void WorldSession::HandleRaidReadyCheckOpcode( WorldPacket & recv_data ) // everything's fine, do it WorldPacket data(MSG_RAID_READY_CHECK, 8); data << GetPlayer()->GetGUID(); - group->BroadcastPacket(&data, -1); + group->BroadcastPacket(&data, false, -1); group->OfflineReadyCheck(); } diff --git a/src/game/Item.h b/src/game/Item.h index f30fb8dd461..824375cea8d 100644 --- a/src/game/Item.h +++ b/src/game/Item.h @@ -287,13 +287,10 @@ class TRINITY_DLL_SPEC Item : public Object uState = state; } - bool hasQuest(uint32 quest_id) const - { - ItemPrototype const *itemProto = GetProto(); - return itemProto && itemProto->StartQuest == quest_id; - } + bool hasQuest(uint32 quest_id) const { return GetProto()->StartQuest == quest_id; } bool hasInvolvedQuest(uint32 /*quest_id*/) const { return false; } - + bool IsPotion() const { return GetProto()->IsPotion(); } + bool IsConjuredConsumable() const { return GetProto()->IsConjuredConsumable(); } private: uint8 m_slot; Bag *m_container; diff --git a/src/game/ItemPrototype.h b/src/game/ItemPrototype.h index d7e923a2b77..b8150b48c52 100644 --- a/src/game/ItemPrototype.h +++ b/src/game/ItemPrototype.h @@ -658,6 +658,9 @@ struct ItemPrototype } return 0; } + + bool IsPotion() const { return Class==ITEM_CLASS_CONSUMABLE && SubClass==ITEM_SUBCLASS_POTION; } + bool IsConjuredConsumable() const { return Class == ITEM_CLASS_CONSUMABLE && (Flags & ITEM_FLAGS_CONJURED); } }; struct ItemLocale diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index bbf6f47d949..7ca960775a6 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -4761,6 +4761,14 @@ bool ChatHandler::HandleSet32Bit(const char* args) if(!*args) return false; + Unit* target = getSelectedUnit(); + if(!target) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + char* px = strtok((char*)args, " "); char* py = strtok(NULL, " "); @@ -4774,9 +4782,10 @@ bool ChatHandler::HandleSet32Bit(const char* args) sLog.outDebug(GetTrinityString(LANG_SET_32BIT), Opcode, Value); - m_session->GetPlayer( )->SetUInt32Value( Opcode , 2^Value ); + uint32 iValue = Value ? 1 << (Value - 1) : 0; + target->SetUInt32Value( Opcode , iValue); - PSendSysMessage(LANG_SET_32BIT_FIELD, Opcode,1); + PSendSysMessage(LANG_SET_32BIT_FIELD, Opcode, iValue); return true; } diff --git a/src/game/PetAI.cpp b/src/game/PetAI.cpp index b85d675e6a4..925f68f7eec 100644 --- a/src/game/PetAI.cpp +++ b/src/game/PetAI.cpp @@ -38,7 +38,7 @@ int PetAI::Permissible(const Creature *creature) return PERMIT_BASE_NO; } -PetAI::PetAI(Creature *c) : CreatureAI(c), i_pet(*c), i_tracker(TIME_INTERVAL_LOOK), inCombat(false) +PetAI::PetAI(Creature *c) : CreatureAI(c), i_pet(*c), i_tracker(TIME_INTERVAL_LOOK) { m_AllySet.clear(); UpdateAllies(); @@ -59,7 +59,6 @@ bool PetAI::_needToStop() const void PetAI::_stopAttack() { - inCombat = false; if( !i_pet.isAlive() ) { DEBUG_LOG("Creature stoped attacking cuz his dead [guid=%u]", i_pet.GetGUIDLow()); @@ -126,6 +125,8 @@ void PetAI::UpdateAI(const uint32 diff) if (i_pet.GetGlobalCooldown() == 0 && !i_pet.hasUnitState(UNIT_STAT_CASTING)) { + bool inCombat = me->getVictim(); + //Autocast for (uint8 i = 0; i < i_pet.GetPetAutoSpellSize(); i++) { diff --git a/src/game/PetAI.h b/src/game/PetAI.h index 056a9efa205..be38e03e13c 100644 --- a/src/game/PetAI.h +++ b/src/game/PetAI.h @@ -47,7 +47,6 @@ class TRINITY_DLL_DECL PetAI : public CreatureAI void UpdateAllies(); Creature &i_pet; - bool inCombat; TimeTracker i_tracker; std::set<uint64> m_AllySet; uint32 m_updateAlliesTimer; diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 0e4c90aa50c..b45527b9401 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -814,9 +814,9 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8 } // if this is ammo then use it - uint8 msg = CanUseAmmo( pItem->GetProto()->ItemId ); + uint8 msg = CanUseAmmo( pItem->GetEntry() ); if( msg == EQUIP_ERR_OK ) - SetAmmo( pItem->GetProto()->ItemId ); + SetAmmo( pItem->GetEntry() ); } } } @@ -11252,60 +11252,60 @@ void Player::DestroyItem( uint8 bag, uint8 slot, bool update ) void Player::DestroyItemCount( uint32 item, uint32 count, bool update, bool unequip_check) { sLog.outDebug( "STORAGE: DestroyItemCount item = %u, count = %u", item, count); - Item *pItem; - ItemPrototype const *pProto; uint32 remcount = 0; // in inventory for(int i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++) { - pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); - if( pItem && pItem->GetEntry() == item ) + if (Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i )) { - if( pItem->GetCount() + remcount <= count ) + if (pItem->GetEntry() == item) { - // all items in inventory can unequipped - remcount += pItem->GetCount(); - DestroyItem( INVENTORY_SLOT_BAG_0, i, update); + if (pItem->GetCount() + remcount <= count) + { + // all items in inventory can unequipped + remcount += pItem->GetCount(); + DestroyItem( INVENTORY_SLOT_BAG_0, i, update); - if(remcount >=count) + if (remcount >=count) + return; + } + else + { + ItemRemovedQuestCheck( pItem->GetEntry(), count - remcount ); + pItem->SetCount( pItem->GetCount() - count + remcount ); + if (IsInWorld() & update) + pItem->SendUpdateToPlayer( this ); + pItem->SetState(ITEM_CHANGED, this); return; - } - else - { - pProto = pItem->GetProto(); - ItemRemovedQuestCheck( pItem->GetEntry(), count - remcount ); - pItem->SetCount( pItem->GetCount() - count + remcount ); - if( IsInWorld() & update ) - pItem->SendUpdateToPlayer( this ); - pItem->SetState(ITEM_CHANGED, this); - return; + } } } } for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++) { - pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); - if( pItem && pItem->GetEntry() == item ) + if (Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i )) { - if( pItem->GetCount() + remcount <= count ) + if (pItem->GetEntry() == item) { - // all keys can be unequipped - remcount += pItem->GetCount(); - DestroyItem( INVENTORY_SLOT_BAG_0, i, update); + if (pItem->GetCount() + remcount <= count) + { + // all keys can be unequipped + remcount += pItem->GetCount(); + DestroyItem( INVENTORY_SLOT_BAG_0, i, update); - if(remcount >=count) + if (remcount >=count) + return; + } + else + { + ItemRemovedQuestCheck( pItem->GetEntry(), count - remcount ); + pItem->SetCount( pItem->GetCount() - count + remcount ); + if (IsInWorld() & update) + pItem->SendUpdateToPlayer( this ); + pItem->SetState(ITEM_CHANGED, this); return; - } - else - { - pProto = pItem->GetProto(); - ItemRemovedQuestCheck( pItem->GetEntry(), count - remcount ); - pItem->SetCount( pItem->GetCount() - count + remcount ); - if( IsInWorld() & update ) - pItem->SendUpdateToPlayer( this ); - pItem->SetState(ITEM_CHANGED, this); - return; + } } } } @@ -11317,27 +11317,28 @@ void Player::DestroyItemCount( uint32 item, uint32 count, bool update, bool uneq { for(uint32 j = 0; j < pBag->GetBagSize(); j++) { - pItem = pBag->GetItemByPos(j); - if( pItem && pItem->GetEntry() == item ) + if(Item* pItem = pBag->GetItemByPos(j)) { - // all items in bags can be unequipped - if( pItem->GetCount() + remcount <= count ) + if (pItem->GetEntry() == item) { - remcount += pItem->GetCount(); - DestroyItem( i, j, update ); + // all items in bags can be unequipped + if (pItem->GetCount() + remcount <= count) + { + remcount += pItem->GetCount(); + DestroyItem( i, j, update ); - if(remcount >=count) + if (remcount >=count) + return; + } + else + { + ItemRemovedQuestCheck( pItem->GetEntry(), count - remcount ); + pItem->SetCount( pItem->GetCount() - count + remcount ); + if (IsInWorld() && update) + pItem->SendUpdateToPlayer( this ); + pItem->SetState(ITEM_CHANGED, this); return; - } - else - { - pProto = pItem->GetProto(); - ItemRemovedQuestCheck( pItem->GetEntry(), count - remcount ); - pItem->SetCount( pItem->GetCount() - count + remcount ); - if( IsInWorld() && update ) - pItem->SendUpdateToPlayer( this ); - pItem->SetState(ITEM_CHANGED, this); - return; + } } } } @@ -11347,29 +11348,30 @@ void Player::DestroyItemCount( uint32 item, uint32 count, bool update, bool uneq // in equipment and bag list for(int i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_BAG_END; i++) { - pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); - if( pItem && pItem->GetEntry() == item ) + if (Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i )) { - if( pItem->GetCount() + remcount <= count ) + if (pItem && pItem->GetEntry() == item) { - if(!unequip_check || CanUnequipItem(INVENTORY_SLOT_BAG_0 << 8 | i,false) == EQUIP_ERR_OK ) + if (pItem->GetCount() + remcount <= count) { - remcount += pItem->GetCount(); - DestroyItem( INVENTORY_SLOT_BAG_0, i, update); + if (!unequip_check || CanUnequipItem(INVENTORY_SLOT_BAG_0 << 8 | i,false) == EQUIP_ERR_OK ) + { + remcount += pItem->GetCount(); + DestroyItem( INVENTORY_SLOT_BAG_0, i, update); - if(remcount >=count) - return; + if (remcount >=count) + return; + } + } + else + { + ItemRemovedQuestCheck( pItem->GetEntry(), count - remcount ); + pItem->SetCount( pItem->GetCount() - count + remcount ); + if (IsInWorld() & update) + pItem->SendUpdateToPlayer( this ); + pItem->SetState(ITEM_CHANGED, this); + return; } - } - else - { - pProto = pItem->GetProto(); - ItemRemovedQuestCheck( pItem->GetEntry(), count - remcount ); - pItem->SetCount( pItem->GetCount() - count + remcount ); - if( IsInWorld() & update ) - pItem->SendUpdateToPlayer( this ); - pItem->SetState(ITEM_CHANGED, this); - return; } } } @@ -11381,40 +11383,28 @@ void Player::DestroyZoneLimitedItem( bool update, uint32 new_zone ) // in inventory for(int i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++) - { - Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); - if( pItem && pItem->IsLimitedToAnotherMapOrZone(GetMapId(),new_zone) ) - DestroyItem( INVENTORY_SLOT_BAG_0, i, update); - } + if (Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i )) + if (pItem->IsLimitedToAnotherMapOrZone(GetMapId(),new_zone)) + DestroyItem( INVENTORY_SLOT_BAG_0, i, update); + for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++) - { - Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); - if( pItem && pItem->IsLimitedToAnotherMapOrZone(GetMapId(),new_zone) ) - DestroyItem( INVENTORY_SLOT_BAG_0, i, update); - } + if (Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i )) + if (pItem->IsLimitedToAnotherMapOrZone(GetMapId(),new_zone)) + DestroyItem( INVENTORY_SLOT_BAG_0, i, update); // in inventory bags for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) - { - Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i ); - if( pBag ) - { + if (Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i )) for(uint32 j = 0; j < pBag->GetBagSize(); j++) - { - Item* pItem = pBag->GetItemByPos(j); - if( pItem && pItem->IsLimitedToAnotherMapOrZone(GetMapId(),new_zone) ) - DestroyItem( i, j, update); - } - } - } + if (Item* pItem = pBag->GetItemByPos(j)) + if (pItem->IsLimitedToAnotherMapOrZone(GetMapId(),new_zone)) + DestroyItem( i, j, update); // in equipment and bag list for(int i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_BAG_END; i++) - { - Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); - if( pItem && pItem->IsLimitedToAnotherMapOrZone(GetMapId(),new_zone) ) - DestroyItem( INVENTORY_SLOT_BAG_0, i, update); - } + if (Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i )) + if (pItem->IsLimitedToAnotherMapOrZone(GetMapId(),new_zone)) + DestroyItem( INVENTORY_SLOT_BAG_0, i, update); } void Player::DestroyConjuredItems( bool update ) @@ -11425,40 +11415,23 @@ void Player::DestroyConjuredItems( bool update ) // in inventory for(int i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++) - { - Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); - if( pItem && pItem->GetProto() && - (pItem->GetProto()->Class == ITEM_CLASS_CONSUMABLE) && - (pItem->GetProto()->Flags & ITEM_FLAGS_CONJURED) ) - DestroyItem( INVENTORY_SLOT_BAG_0, i, update); - } + if (Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i )) + if (pItem->IsConjuredConsumable()) + DestroyItem( INVENTORY_SLOT_BAG_0, i, update); // in inventory bags for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) - { - Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i ); - if( pBag ) - { + if (Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i )) for(uint32 j = 0; j < pBag->GetBagSize(); j++) - { - Item* pItem = pBag->GetItemByPos(j); - if( pItem && pItem->GetProto() && - (pItem->GetProto()->Class == ITEM_CLASS_CONSUMABLE) && - (pItem->GetProto()->Flags & ITEM_FLAGS_CONJURED) ) - DestroyItem( i, j, update); - } - } - } + if (Item* pItem = pBag->GetItemByPos(j)) + if (pItem->IsConjuredConsumable()) + DestroyItem( i, j, update); // in equipment and bag list for(int i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_BAG_END; i++) - { - Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); - if( pItem && pItem->GetProto() && - (pItem->GetProto()->Class == ITEM_CLASS_CONSUMABLE) && - (pItem->GetProto()->Flags & ITEM_FLAGS_CONJURED) ) - DestroyItem( INVENTORY_SLOT_BAG_0, i, update); - } + if (Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i )) + if (pItem->IsConjuredConsumable()) + DestroyItem( INVENTORY_SLOT_BAG_0, i, update); } void Player::DestroyItemCount( Item* pItem, uint32 &count, bool update ) @@ -12590,7 +12563,7 @@ void Player::SendNewItem(Item *item, uint32 count, bool received, bool created, data << GetItemCount(item->GetEntry()); // count of items in inventory if (broadcast && GetGroup()) - GetGroup()->BroadcastPacket(&data); + GetGroup()->BroadcastPacket(&data, true); else GetSession()->SendPacket(&data); } @@ -17382,7 +17355,14 @@ void Player::VehicleSpellInitialize() for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i) { uint32 spellId = ((Creature*)charm)->m_spells[i]; - if(IsPassiveSpell(spellId)) + if(!spellId) + continue; + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); + if(!spellInfo) + continue; + + if(IsPassiveSpell(spellId) || spellInfo->activeIconID == 2158) //flight { charm->CastSpell(charm, spellId, true); data << uint16(0) << uint8(0) << uint8(i+8); @@ -18936,7 +18916,8 @@ void Player::ClearComboPoints() void Player::SetGroup(Group *group, int8 subgroup) { - if(group == NULL) m_group.unlink(); + if(group == NULL) + m_group.unlink(); else { // never use SetGroup without a subgroup unless you specify NULL for group @@ -20052,6 +20033,41 @@ PartyResult Player::CanUninviteFromGroup() const return PARTY_RESULT_OK; } +void Player::SetBattleGroundRaid(Group* group, int8 subgroup) +{ + //we must move references from m_group to m_originalGroup + SetOriginalGroup(GetGroup(), GetSubGroup()); + + m_group.unlink(); + m_group.link(group, this); + m_group.setSubGroup((uint8)subgroup); +} + +void Player::RemoveFromBattleGroundRaid() +{ + //remove existing reference + m_group.unlink(); + if( Group* group = GetOriginalGroup() ) + { + m_group.link(group, this); + m_group.setSubGroup(GetOriginalSubGroup()); + } + SetOriginalGroup(NULL); +} + +void Player::SetOriginalGroup(Group *group, int8 subgroup) +{ + if( group == NULL ) + m_originalGroup.unlink(); + else + { + // never use SetOriginalGroup without a subgroup unless you specify NULL for group + assert(subgroup >= 0); + m_originalGroup.link(group, this); + m_originalGroup.setSubGroup((uint8)subgroup); + } +} + void Player::UpdateUnderwaterState( Map* m, float x, float y, float z ) { LiquidData liquid_status; diff --git a/src/game/Player.h b/src/game/Player.h index dd64ce5c7d0..10b31632415 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -2166,6 +2166,13 @@ class TRINITY_DLL_SPEC Player : public Unit void SetAuraUpdateMaskForRaid(uint8 slot) { m_auraRaidUpdateMask |= (uint64(1) << slot); } Player* GetNextRandomRaidMember(float radius); PartyResult CanUninviteFromGroup() const; + // BattleGround Group System + void SetBattleGroundRaid(Group *group, int8 subgroup = -1); + void RemoveFromBattleGroundRaid(); + Group * GetOriginalGroup() { return m_originalGroup.getTarget(); } + GroupReference& GetOriginalGroupRef() { return m_originalGroup; } + uint8 GetOriginalSubGroup() const { return m_originalGroup.getSubGroup(); } + void SetOriginalGroup(Group *group, int8 subgroup = -1); GridReference<Player> &GetGridRef() { return m_gridRef; } MapReference &GetMapRef() { return m_mapRef; } @@ -2407,6 +2414,7 @@ class TRINITY_DLL_SPEC Player : public Unit // Groups GroupReference m_group; + GroupReference m_originalGroup; Group *m_groupInvite; uint32 m_groupUpdateMask; uint64 m_auraRaidUpdateMask; diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 3d1011eb306..fb80819fcc0 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -2454,12 +2454,11 @@ void Spell::SendSpellCooldown() Player* _player = (Player*)m_caster; - // mana/health potions, disabled by client - if (m_spellInfo->Category==SPELLCATEGORY_HEALTH_MANA_POTIONS) + // mana/health/etc potions, disabled by client (until combat out as declarate) + if (m_CastItem && m_CastItem->IsPotion()) { // need in some way provided data for Spell::finish SendCooldownEvent - if(m_CastItem) - _player->SetLastPotionId(m_CastItem->GetEntry()); + _player->SetLastPotionId(m_CastItem->GetEntry()); return; } diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 98f49ed127d..b4bedebbfe9 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -1043,7 +1043,13 @@ void Aura::_RemoveAura() ProcCaster = PROC_FLAG_SUCCESSFUL_NEGATIVE_SPELL_HIT; ProcVictim = PROC_FLAG_TAKEN_NEGATIVE_SPELL_HIT; } - caster->ProcDamageAndSpell(m_target,ProcCaster, ProcVictim, PROC_EX_AURA_REMOVE, 0, BASE_ATTACK, m_spellProto); + uint32 procEx=0; + if (m_removeMode == AURA_REMOVE_BY_DISPEL) + procEx = PROC_EX_AURA_REMOVE_DISPEL; + else if (m_removeMode == AURA_REMOVE_BY_DEFAULT) + procEx = PROC_EX_AURA_REMOVE_EXPIRE; + + caster->ProcDamageAndSpell(m_target,ProcCaster, ProcVictim, procEx, m_modifier.m_amount, BASE_ATTACK, m_spellProto); } } } @@ -2051,9 +2057,10 @@ void Aura::HandleAuraDummy(bool apply, bool Real) // Living Bomb if (m_spellProto->SpellFamilyFlags[1] & 0x20000) { - if(!m_target || !caster || !(m_removeMode == AURA_REMOVE_BY_DISPEL || m_removeMode == AURA_REMOVE_BY_DEFAULT)) + if(!m_target || !(m_removeMode == AURA_REMOVE_BY_DISPEL || m_removeMode == AURA_REMOVE_BY_DEFAULT)) return; - caster->CastSpell(m_target, GetModifier()->m_amount, true, NULL, NULL, GetCasterGUID()); + Unit* target=NULL; + m_target->CastSpell(m_target, GetModifier()->m_amount, true, NULL, NULL, GetCasterGUID()); return; } break; @@ -3238,7 +3245,7 @@ void Aura::HandleFeignDeath(bool apply, bool Real) m_target->addUnitState(UNIT_STAT_DIED); m_target->CombatStop(); - m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_UNATTACKABLE); + m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_STEALTH); // prevent interrupt message if(m_caster_guid==m_target->GetGUID() && m_target->m_currentSpells[CURRENT_GENERIC_SPELL]) @@ -3322,7 +3329,7 @@ void Aura::HandleModStealth(bool apply, bool Real) if(Real && m_target->GetTypeId()==TYPEID_PLAYER) { // drop flag at stealth in bg - m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_UNATTACKABLE); + m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_STEALTH); // remove player from the objective's active player count at stealth if(OutdoorPvP * pvp = ((Player*)m_target)->GetOutdoorPvP()) @@ -3392,7 +3399,7 @@ void Aura::HandleInvisibility(bool apply, bool Real) { m_target->m_invisibilityMask |= (1 << m_modifier.m_miscvalue); - m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_UNATTACKABLE); + m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_STEALTH); if(Real && m_target->GetTypeId()==TYPEID_PLAYER) { @@ -3850,7 +3857,7 @@ void Aura::HandleAuraModStateImmunity(bool apply, bool Real) void Aura::HandleAuraModSchoolImmunity(bool apply, bool Real) { if(apply && m_modifier.m_miscvalue == SPELL_SCHOOL_MASK_NORMAL) - m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_UNATTACKABLE); + m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_STEALTH); m_target->ApplySpellImmune(GetId(),IMMUNITY_SCHOOL,m_modifier.m_miscvalue,apply); @@ -5232,9 +5239,15 @@ void Aura::HandleAuraAllowFlight(bool apply, bool Real) // allow fly WorldPacket data; if(apply) + { data.Initialize(SMSG_MOVE_SET_CAN_FLY, 12); + m_target->SetByteFlag(UNIT_FIELD_BYTES_1, 3, 0x02); + } else + { data.Initialize(SMSG_MOVE_UNSET_CAN_FLY, 12); + m_target->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, 0x02); + } data.append(m_target->GetPackGUID()); data << uint32(0); // unk m_target->SendMessageToSet(&data, true); @@ -5336,7 +5349,7 @@ void Aura::HandleModUnattackable( bool Apply, bool Real ) if(Real && Apply) { m_target->CombatStop(); - m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_UNATTACKABLE); + m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_STEALTH); } m_target->ApplyModFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE,Apply); diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 16a2efef8b3..9400f61917b 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -5045,10 +5045,10 @@ void Spell::EffectScriptEffect(uint32 effIndex) // Emblazon Runeblade case 51770: { - if(!unitTarget) + if(!m_originalCaster) return; - unitTarget->CastSpell(unitTarget,51771,false); + m_originalCaster->CastSpell(m_originalCaster, damage, false); break; } // Death Gate diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 45e88abe4de..f0bebd5718a 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -603,9 +603,8 @@ enum ProcFlagsEx PROC_EX_ABSORB = 0x0000400, PROC_EX_REFLECT = 0x0000800, PROC_EX_INTERRUPT = 0x0001000, // Melee hit result can be Interrupt (not used) - PROC_EX_AURA_REMOVE = 0x0002000, - PROC_EX_RESERVED2 = 0x0004000, - PROC_EX_RESERVED3 = 0x0008000, + PROC_EX_AURA_REMOVE_DISPEL = 0x0002000, + PROC_EX_AURA_REMOVE_EXPIRE = 0x0004000, PROC_EX_EX_TRIGGER_ALWAYS = 0x0010000, // If set trigger always ( no matter another flags) used for drop charges PROC_EX_EX_ONE_TIME_TRIGGER = 0x0020000 // If set trigger always but only one time (not used) }; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index eb20ee91845..48e7aec78c8 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -2181,7 +2181,7 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe { if ((*i)->GetModifier()->m_amount<=0) { - pVictim->RemoveAurasDueToSpell((*i)->GetId()); + pVictim->RemoveAurasByCasterSpell((*i)->GetId(), (*i)->GetCasterGUID()); i = vSchoolAbsorb.begin(); } else @@ -3475,12 +3475,15 @@ void Unit::InterruptSpell(uint32 spellType, bool withDelayed) { assert(spellType < CURRENT_MAX_SPELL); - if(m_currentSpells[spellType] && (withDelayed || m_currentSpells[spellType]->getState() != SPELL_STATE_DELAYED) ) + Spell *spell = m_currentSpells[spellType]; + if(spell && (withDelayed || spell->getState() != SPELL_STATE_DELAYED) ) { // for example, do not let self-stun aura interrupt itself - if(!m_currentSpells[spellType]->IsInterruptable()) + if(!spell->IsInterruptable()) return; + m_currentSpells[spellType] = NULL; + // send autorepeat cancel message for autorepeat spells if (spellType == CURRENT_AUTOREPEAT_SPELL) { @@ -3488,10 +3491,9 @@ void Unit::InterruptSpell(uint32 spellType, bool withDelayed) ((Player*)this)->SendAutoRepeatCancel(); } - if (m_currentSpells[spellType]->getState() != SPELL_STATE_FINISHED) - m_currentSpells[spellType]->cancel(); - m_currentSpells[spellType]->SetReferencedFromCurrent(false); - m_currentSpells[spellType] = NULL; + if (spell->getState() != SPELL_STATE_FINISHED) + spell->cancel(); + spell->SetReferencedFromCurrent(false); } } @@ -3521,36 +3523,39 @@ bool Unit::IsNonMeleeSpellCasted(bool withDelayed, bool skipChanneled, bool skip void Unit::InterruptNonMeleeSpells(bool withDelayed, uint32 spell_id) { // generic spells are interrupted if they are not finished or delayed - if (m_currentSpells[CURRENT_GENERIC_SPELL] && (!spell_id || m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->Id==spell_id)) + Spell *spell = m_currentSpells[CURRENT_GENERIC_SPELL]; + if (spell && (!spell_id || spell->m_spellInfo->Id==spell_id)) { - if ( (m_currentSpells[CURRENT_GENERIC_SPELL]->getState() != SPELL_STATE_FINISHED) && - (withDelayed || m_currentSpells[CURRENT_GENERIC_SPELL]->getState() != SPELL_STATE_DELAYED) ) - m_currentSpells[CURRENT_GENERIC_SPELL]->cancel(); - m_currentSpells[CURRENT_GENERIC_SPELL]->SetReferencedFromCurrent(false); m_currentSpells[CURRENT_GENERIC_SPELL] = NULL; + + if ( (spell->getState() != SPELL_STATE_FINISHED) && + (withDelayed || spell->getState() != SPELL_STATE_DELAYED) ) + spell->cancel(); + spell->SetReferencedFromCurrent(false); } + spell = m_currentSpells[CURRENT_AUTOREPEAT_SPELL]; // autorepeat spells are interrupted if they are not finished or delayed - if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL] && (!spell_id || m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id==spell_id)) + if (spell && (!spell_id || spell->m_spellInfo->Id==spell_id)) { + m_currentSpells[CURRENT_AUTOREPEAT_SPELL] = NULL; // send disable autorepeat packet in any case if(GetTypeId()==TYPEID_PLAYER) ((Player*)this)->SendAutoRepeatCancel(); - - if ( (m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->getState() != SPELL_STATE_FINISHED) && - (withDelayed || m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->getState() != SPELL_STATE_DELAYED) ) - m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->cancel(); - m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->SetReferencedFromCurrent(false); - m_currentSpells[CURRENT_AUTOREPEAT_SPELL] = NULL; + if ( (spell->getState() != SPELL_STATE_FINISHED) && + (withDelayed || spell->getState() != SPELL_STATE_DELAYED) ) + spell->cancel(); + spell->SetReferencedFromCurrent(false); } // channeled spells are interrupted if they are not finished, even if they are delayed - if (m_currentSpells[CURRENT_CHANNELED_SPELL] && (!spell_id || m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->Id==spell_id)) + spell = m_currentSpells[CURRENT_CHANNELED_SPELL]; + if (spell && (!spell_id || spell->m_spellInfo->Id==spell_id)) { - if (m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() != SPELL_STATE_FINISHED) - m_currentSpells[CURRENT_CHANNELED_SPELL]->cancel(); - m_currentSpells[CURRENT_CHANNELED_SPELL]->SetReferencedFromCurrent(false); m_currentSpells[CURRENT_CHANNELED_SPELL] = NULL; + if (spell->getState() != SPELL_STATE_FINISHED) + spell->cancel(); + spell->SetReferencedFromCurrent(false); } } @@ -5376,6 +5381,17 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu triggered_spell_id = 29077; break; } + // Shattered Barrier + if (dummySpell->SpellIconID == 2945) + { + // only on dispel/remove aura by sestroy + if (procEx & PROC_EX_AURA_REMOVE_EXPIRE && damage) + return false; + target = NULL; + triggered_spell_id = 55080; + CastSpell(target, triggered_spell_id, true); + return true; + } // Hot Streak if (dummySpell->SpellIconID == 2999) { diff --git a/src/game/Unit.h b/src/game/Unit.h index 85f8a60409e..c53da84acd1 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -80,7 +80,7 @@ enum SpellAuraInterruptFlags AURA_INTERRUPT_FLAG_MOUNT = 0x00020000, // 17 misdirect, aspect, swim speed AURA_INTERRUPT_FLAG_NOT_SEATED = 0x00040000, // 18 removed by standing up AURA_INTERRUPT_FLAG_CHANGE_MAP = 0x00080000, // 19 leaving map/getting teleported - AURA_INTERRUPT_FLAG_UNATTACKABLE = 0x00100000, // 20 invulnerable or stealth + AURA_INTERRUPT_FLAG_IMMUNE_OR_STEALTH = 0x00100000, // 20 removed when player on himself casts immunity spell or vanish? AURA_INTERRUPT_FLAG_UNK21 = 0x00200000, // 21 AURA_INTERRUPT_FLAG_TELEPORTED = 0x00400000, // 22 AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT = 0x00800000, // 23 removed by entering pvp combat |