aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/game/BattleGround.cpp9
-rw-r--r--src/game/BattleGroundHandler.cpp2
-rw-r--r--src/game/ChatHandler.cpp36
-rw-r--r--src/game/GameObject.cpp26
-rw-r--r--src/game/Group.cpp104
-rw-r--r--src/game/Group.h2
-rw-r--r--src/game/GroupHandler.cpp40
-rw-r--r--src/game/Item.h9
-rw-r--r--src/game/ItemPrototype.h3
-rw-r--r--src/game/Level3.cpp13
-rw-r--r--src/game/PetAI.cpp5
-rw-r--r--src/game/PetAI.h1
-rw-r--r--src/game/Player.cpp274
-rw-r--r--src/game/Player.h8
-rw-r--r--src/game/Spell.cpp7
-rw-r--r--src/game/SpellAuras.cpp29
-rw-r--r--src/game/SpellEffects.cpp4
-rw-r--r--src/game/SpellMgr.h5
-rw-r--r--src/game/Unit.cpp62
-rw-r--r--src/game/Unit.h2
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