void HandleBattlemasterJoinArena(BattlemasterJoinArena packet) { // ignore if we already in BG or BG queue if (GetPlayer().InBattleground()) { return; } ArenaTypes arenatype = (ArenaTypes)ArenaTeam.GetTypeBySlot(packet.TeamSizeIndex); //check existence Battleground bg = Global.BattlegroundMgr.GetBattlegroundTemplate(BattlegroundTypeId.AA); if (!bg) { Log.outError(LogFilter.Network, "Battleground: template bg (all arenas) not found"); return; } if (Global.DisableMgr.IsDisabledFor(DisableType.Battleground, (uint)BattlegroundTypeId.AA, null)) { GetPlayer().SendSysMessage(CypherStrings.ArenaDisabled); return; } BattlegroundTypeId bgTypeId = bg.GetTypeID(); BattlegroundQueueTypeId bgQueueTypeId = Global.BattlegroundMgr.BGQueueTypeId(bgTypeId, arenatype); PvpDifficultyRecord bracketEntry = Global.DB2Mgr.GetBattlegroundBracketByLevel(bg.GetMapId(), GetPlayer().getLevel()); if (bracketEntry == null) { return; } Group grp = GetPlayer().GetGroup(); // no group found, error if (!grp) { return; } if (grp.GetLeaderGUID() != GetPlayer().GetGUID()) { return; } uint ateamId = GetPlayer().GetArenaTeamId(packet.TeamSizeIndex); // check real arenateam existence only here (if it was moved to group.CanJoin .. () then we would ahve to get it twice) ArenaTeam at = Global.ArenaTeamMgr.GetArenaTeamById(ateamId); if (at == null) { GetPlayer().GetSession().SendNotInArenaTeamPacket(arenatype); return; } // get the team rating for queuing uint arenaRating = at.GetRating(); uint matchmakerRating = at.GetAverageMMR(grp); // the arenateam id must match for everyone in the group if (arenaRating <= 0) { arenaRating = 1; } BattlegroundQueue bgQueue = Global.BattlegroundMgr.GetBattlegroundQueue(bgQueueTypeId); uint avgTime = 0; GroupQueueInfo ginfo = null; ObjectGuid errorGuid; var err = grp.CanJoinBattlegroundQueue(bg, bgQueueTypeId, (uint)arenatype, (uint)arenatype, true, packet.TeamSizeIndex, out errorGuid); if (err == 0) { Log.outDebug(LogFilter.Battleground, "Battleground: arena team id {0}, leader {1} queued with matchmaker rating {2} for type {3}", GetPlayer().GetArenaTeamId(packet.TeamSizeIndex), GetPlayer().GetName(), matchmakerRating, arenatype); ginfo = bgQueue.AddGroup(GetPlayer(), grp, bgTypeId, bracketEntry, arenatype, true, false, arenaRating, matchmakerRating, ateamId); avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry.GetBracketId()); } for (GroupReference refe = grp.GetFirstMember(); refe != null; refe = refe.next()) { Player member = refe.GetSource(); if (!member) { continue; } if (err != 0) { BattlefieldStatusFailed battlefieldStatus; Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatus, bg, GetPlayer(), 0, arenatype, err, errorGuid); member.SendPacket(battlefieldStatus); continue; } // add to queue uint queueSlot = member.AddBattlegroundQueueId(bgQueueTypeId); BattlefieldStatusQueued battlefieldStatusQueued; Global.BattlegroundMgr.BuildBattlegroundStatusQueued(out battlefieldStatusQueued, bg, member, queueSlot, ginfo.JoinTime, avgTime, arenatype, true); member.SendPacket(battlefieldStatusQueued); Log.outDebug(LogFilter.Battleground, "Battleground: player joined queue for arena as group bg queue type {0} bg type {1}: GUID {2}, NAME {3}", bgQueueTypeId, bgTypeId, member.GetGUID().ToString(), member.GetName()); } Global.BattlegroundMgr.ScheduleQueueUpdate(matchmakerRating, arenatype, bgQueueTypeId, bgTypeId, bracketEntry.GetBracketId()); }
void HandleBattlemasterJoin(BattlemasterJoin battlemasterJoin) { bool isPremade = false; Group grp = null; BattlefieldStatusFailed battlefieldStatusFailed; uint bgTypeId_ = (uint)(battlemasterJoin.QueueID & 0xFFFF); if (!CliDB.BattlemasterListStorage.ContainsKey(bgTypeId_)) { Log.outError(LogFilter.Network, "Battleground: invalid bgtype ({0}) received. possible cheater? player guid {1}", bgTypeId_, GetPlayer().GetGUID().ToString()); return; } if (Global.DisableMgr.IsDisabledFor(DisableType.Battleground, bgTypeId_, null)) { GetPlayer().SendSysMessage(CypherStrings.BgDisabled); return; } BattlegroundTypeId bgTypeId = (BattlegroundTypeId)bgTypeId_; // can do this, since it's Battleground, not arena BattlegroundQueueTypeId bgQueueTypeId = Global.BattlegroundMgr.BGQueueTypeId(bgTypeId, 0); BattlegroundQueueTypeId bgQueueTypeIdRandom = Global.BattlegroundMgr.BGQueueTypeId(BattlegroundTypeId.RB, 0); // ignore if player is already in BG if (GetPlayer().InBattleground()) { return; } // get bg instance or bg template if instance not found Battleground bg = Global.BattlegroundMgr.GetBattlegroundTemplate(bgTypeId); if (!bg) { return; } // expected bracket entry PvpDifficultyRecord bracketEntry = Global.DB2Mgr.GetBattlegroundBracketByLevel(bg.GetMapId(), GetPlayer().getLevel()); if (bracketEntry == null) { return; } GroupJoinBattlegroundResult err = GroupJoinBattlegroundResult.None; // check queue conditions if (!battlemasterJoin.JoinAsGroup) { if (GetPlayer().isUsingLfg()) { Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatusFailed, bg, GetPlayer(), 0, 0, GroupJoinBattlegroundResult.LfgCantUseBattleground); SendPacket(battlefieldStatusFailed); return; } // check Deserter debuff if (!GetPlayer().CanJoinToBattleground(bg)) { Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatusFailed, bg, GetPlayer(), 0, 0, GroupJoinBattlegroundResult.Deserters); SendPacket(battlefieldStatusFailed); return; } if (GetPlayer().GetBattlegroundQueueIndex(bgQueueTypeIdRandom) < SharedConst.MaxPlayerBGQueues) { // player is already in random queue Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatusFailed, bg, GetPlayer(), 0, 0, GroupJoinBattlegroundResult.InRandomBg); SendPacket(battlefieldStatusFailed); return; } if (GetPlayer().InBattlegroundQueue() && bgTypeId == BattlegroundTypeId.RB) { // player is already in queue, can't start random queue Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatusFailed, bg, GetPlayer(), 0, 0, GroupJoinBattlegroundResult.InNonRandomBg); SendPacket(battlefieldStatusFailed); return; } // check if already in queue if (GetPlayer().GetBattlegroundQueueIndex(bgQueueTypeId) < SharedConst.MaxPlayerBGQueues) { return; // player is already in this queue } // check if has free queue slots if (!GetPlayer().HasFreeBattlegroundQueueId()) { Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatusFailed, bg, GetPlayer(), 0, 0, GroupJoinBattlegroundResult.TooManyQueues); SendPacket(battlefieldStatusFailed); return; } // check Freeze debuff if (_player.HasAura(9454)) { return; } BattlegroundQueue bgQueue = Global.BattlegroundMgr.GetBattlegroundQueue(bgQueueTypeId); GroupQueueInfo ginfo = bgQueue.AddGroup(GetPlayer(), null, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0); uint avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry.GetBracketId()); uint queueSlot = GetPlayer().AddBattlegroundQueueId(bgQueueTypeId); BattlefieldStatusQueued battlefieldStatusQueued; Global.BattlegroundMgr.BuildBattlegroundStatusQueued(out battlefieldStatusQueued, bg, GetPlayer(), queueSlot, ginfo.JoinTime, avgTime, ginfo.ArenaType, false); SendPacket(battlefieldStatusQueued); Log.outDebug(LogFilter.Battleground, "Battleground: player joined queue for bg queue type {0} bg type {1}: GUID {2}, NAME {3}", bgQueueTypeId, bgTypeId, GetPlayer().GetGUID().ToString(), GetPlayer().GetName()); } else { grp = GetPlayer().GetGroup(); if (!grp) { return; } if (grp.GetLeaderGUID() != GetPlayer().GetGUID()) { return; } ObjectGuid errorGuid; err = grp.CanJoinBattlegroundQueue(bg, bgQueueTypeId, 0, bg.GetMaxPlayersPerTeam(), false, 0, out errorGuid); isPremade = (grp.GetMembersCount() >= bg.GetMinPlayersPerTeam()); BattlegroundQueue bgQueue = Global.BattlegroundMgr.GetBattlegroundQueue(bgQueueTypeId); GroupQueueInfo ginfo = null; uint avgTime = 0; if (err == 0) { Log.outDebug(LogFilter.Battleground, "Battleground: the following players are joining as group:"); ginfo = bgQueue.AddGroup(GetPlayer(), grp, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0); avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry.GetBracketId()); } for (GroupReference refe = grp.GetFirstMember(); refe != null; refe = refe.next()) { Player member = refe.GetSource(); if (!member) { continue; // this should never happen } if (err != 0) { BattlefieldStatusFailed battlefieldStatus; Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatus, bg, GetPlayer(), 0, 0, err, errorGuid); member.SendPacket(battlefieldStatus); continue; } // add to queue uint queueSlot = member.AddBattlegroundQueueId(bgQueueTypeId); BattlefieldStatusQueued battlefieldStatusQueued; Global.BattlegroundMgr.BuildBattlegroundStatusQueued(out battlefieldStatusQueued, bg, member, queueSlot, ginfo.JoinTime, avgTime, ginfo.ArenaType, true); member.SendPacket(battlefieldStatusQueued); Log.outDebug(LogFilter.Battleground, "Battleground: player joined queue for bg queue type {0} bg type {1}: GUID {2}, NAME {3}", bgQueueTypeId, bgTypeId, member.GetGUID().ToString(), member.GetName()); } Log.outDebug(LogFilter.Battleground, "Battleground: group end"); } Global.BattlegroundMgr.ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, bracketEntry.GetBracketId()); }
void HandleLootMoney(LootMoney lootMoney) { Player player = GetPlayer(); foreach (var lootView in player.GetAELootView()) { ObjectGuid guid = lootView.Value; Loot loot = null; bool shareMoney = true; switch (guid.GetHigh()) { case HighGuid.GameObject: { GameObject go = player.GetMap().GetGameObject(guid); // do not check distance for GO if player is the owner of it (ex. fishing bobber) if (go && ((go.GetOwnerGUID() == player.GetGUID() || go.IsWithinDistInMap(player, SharedConst.InteractionDistance)))) { loot = go.loot; } break; } case HighGuid.Corpse: // remove insignia ONLY in BG { Corpse bones = ObjectAccessor.GetCorpse(player, guid); if (bones && bones.IsWithinDistInMap(player, SharedConst.InteractionDistance)) { loot = bones.loot; shareMoney = false; } break; } case HighGuid.Item: { Item item = player.GetItemByGuid(guid); if (item) { loot = item.loot; shareMoney = false; } break; } case HighGuid.Creature: case HighGuid.Vehicle: { Creature creature = player.GetMap().GetCreature(guid); bool lootAllowed = creature && creature.IsAlive() == (player.GetClass() == Class.Rogue && creature.loot.loot_type == LootType.Pickpocketing); if (lootAllowed && creature.IsWithinDistInMap(player, AELootCreatureCheck.LootDistance)) { loot = creature.loot; if (creature.IsAlive()) { shareMoney = false; } } else { player.SendLootError(lootView.Key, guid, lootAllowed ? LootError.TooFar : LootError.DidntKill); } break; } default: continue; // unlootable type } if (loot == null) { continue; } loot.NotifyMoneyRemoved(); if (shareMoney && player.GetGroup() != null) //item, pickpocket and players can be looted only single player { Group group = player.GetGroup(); List <Player> playersNear = new(); for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next()) { Player member = refe.GetSource(); if (!member) { continue; } if (player.IsAtGroupRewardDistance(member)) { playersNear.Add(member); } } ulong goldPerPlayer = (ulong)(loot.gold / playersNear.Count); foreach (var pl in playersNear) { ulong goldMod = MathFunctions.CalculatePct(goldPerPlayer, pl.GetTotalAuraModifierByMiscValue(AuraType.ModMoneyGain, 1)); pl.ModifyMoney((long)(goldPerPlayer + goldMod)); pl.UpdateCriteria(CriteriaTypes.LootMoney, goldPerPlayer); LootMoneyNotify packet = new(); packet.Money = goldPerPlayer; packet.MoneyMod = goldMod; packet.SoleLooter = playersNear.Count <= 1 ? true : false; pl.SendPacket(packet); } } else { ulong goldMod = MathFunctions.CalculatePct(loot.gold, player.GetTotalAuraModifierByMiscValue(AuraType.ModMoneyGain, 1)); player.ModifyMoney((long)(loot.gold + goldMod)); player.UpdateCriteria(CriteriaTypes.LootMoney, loot.gold); LootMoneyNotify packet = new(); packet.Money = loot.gold; packet.MoneyMod = goldMod; packet.SoleLooter = true; // "You loot..." SendPacket(packet); } loot.gold = 0; // Delete the money loot record from the DB if (!loot.containerID.IsEmpty()) { Global.LootItemStorage.RemoveStoredMoneyForContainer(loot.containerID.GetCounter()); } // Delete container if empty if (loot.IsLooted() && guid.IsItem()) { player.GetSession().DoLootRelease(guid); } } }
public void DoLootRelease(ObjectGuid lguid) { Player player = GetPlayer(); Loot loot; if (player.GetLootGUID() == lguid) { player.SetLootGUID(ObjectGuid.Empty); } player.SendLootRelease(lguid); player.RemoveAELootedWorldObject(lguid); player.RemoveUnitFlag(UnitFlags.Looting); if (!player.IsInWorld) { return; } if (lguid.IsGameObject()) { GameObject go = player.GetMap().GetGameObject(lguid); // not check distance for GO in case owned GO (fishing bobber case, for example) or Fishing hole GO if (!go || ((go.GetOwnerGUID() != player.GetGUID() && go.GetGoType() != GameObjectTypes.FishingHole) && !go.IsWithinDistInMap(player, SharedConst.InteractionDistance))) { return; } loot = go.loot; if (go.GetGoType() == GameObjectTypes.Door) { // locked doors are opened with spelleffect openlock, prevent remove its as looted go.UseDoorOrButton(); } else if (loot.IsLooted() || go.GetGoType() == GameObjectTypes.FishingNode) { if (go.GetGoType() == GameObjectTypes.FishingHole) { // The fishing hole used once more go.AddUse(); // if the max usage is reached, will be despawned in next tick if (go.GetUseCount() >= go.GetGoValue().FishingHole.MaxOpens) { go.SetLootState(LootState.JustDeactivated); } else { go.SetLootState(LootState.Ready); } } else { go.SetLootState(LootState.JustDeactivated); } loot.Clear(); } else { // not fully looted object go.SetLootState(LootState.Activated, player); // if the round robin player release, reset it. if (player.GetGUID() == loot.roundRobinPlayer) { loot.roundRobinPlayer.Clear(); } } } else if (lguid.IsCorpse()) // ONLY remove insignia at BG { Corpse corpse = ObjectAccessor.GetCorpse(player, lguid); if (!corpse || !corpse.IsWithinDistInMap(player, SharedConst.InteractionDistance)) { return; } loot = corpse.loot; if (loot.IsLooted()) { loot.Clear(); corpse.RemoveCorpseDynamicFlag(CorpseDynFlags.Lootable); } } else if (lguid.IsItem()) { Item pItem = player.GetItemByGuid(lguid); if (!pItem) { return; } ItemTemplate proto = pItem.GetTemplate(); // destroy only 5 items from stack in case prospecting and milling if (pItem.loot.loot_type == LootType.Prospecting || pItem.loot.loot_type == LootType.Milling) { pItem.m_lootGenerated = false; pItem.loot.Clear(); uint count = pItem.GetCount(); // >=5 checked in spell code, but will work for cheating cases also with removing from another stacks. if (count > 5) { count = 5; } player.DestroyItemCount(pItem, ref count, true); } else { if (pItem.loot.IsLooted() || !proto.GetFlags().HasAnyFlag(ItemFlags.HasLoot)) // Only delete item if no loot or money (unlooted loot is saved to db) { player.DestroyItem(pItem.GetBagSlot(), pItem.GetSlot(), true); } } return; // item can be looted only single player } else { Creature creature = player.GetMap().GetCreature(lguid); bool lootAllowed = creature && creature.IsAlive() == (player.GetClass() == Class.Rogue && creature.loot.loot_type == LootType.Pickpocketing); if (!lootAllowed || !creature.IsWithinDistInMap(player, AELootCreatureCheck.LootDistance)) { return; } loot = creature.loot; if (loot.IsLooted()) { creature.RemoveDynamicFlag(UnitDynFlags.Lootable); // skip pickpocketing loot for speed, skinning timer reduction is no-op in fact if (!creature.IsAlive()) { creature.AllLootRemovedFromCorpse(); } loot.Clear(); } else { // if the round robin player release, reset it. if (player.GetGUID() == loot.roundRobinPlayer) { loot.roundRobinPlayer.Clear(); Group group = player.GetGroup(); if (group) { if (group.GetLootMethod() != LootMethod.MasterLoot) { group.SendLooter(creature, null); } } // force dynflag update to update looter and lootable info creature.m_values.ModifyValue(creature.m_objectData).ModifyValue(creature.m_objectData.DynamicFlags); creature.ForceUpdateFieldChange(); } } } //Player is not looking at loot list, he doesn't need to see updates on the loot list loot.RemoveLooter(player.GetGUID()); }
void HandleSetRaidDifficulty(SetRaidDifficulty setRaidDifficulty) { DifficultyRecord difficultyEntry = CliDB.DifficultyStorage.LookupByKey(setRaidDifficulty.DifficultyID); if (difficultyEntry == null) { Log.outDebug(LogFilter.Network, "WorldSession.HandleSetDungeonDifficulty: {0} sent an invalid instance mode {1}!", GetPlayer().GetGUID().ToString(), setRaidDifficulty.DifficultyID); return; } if (difficultyEntry.InstanceType != MapTypes.Raid) { Log.outDebug(LogFilter.Network, "WorldSession.HandleSetDungeonDifficulty: {0} sent an non-dungeon instance mode {1}!", GetPlayer().GetGUID().ToString(), difficultyEntry.Id); return; } if (!difficultyEntry.Flags.HasAnyFlag(DifficultyFlags.CanSelect)) { Log.outDebug(LogFilter.Network, "WorldSession.HandleSetDungeonDifficulty: {0} sent unselectable instance mode {1}!", GetPlayer().GetGUID().ToString(), difficultyEntry.Id); return; } if (((int)(difficultyEntry.Flags & DifficultyFlags.Legacy) >> 5) != setRaidDifficulty.Legacy) { Log.outDebug(LogFilter.Network, "WorldSession.HandleSetDungeonDifficulty: {0} sent not matching legacy difficulty {1}!", GetPlayer().GetGUID().ToString(), difficultyEntry.Id); return; } Difficulty difficultyID = (Difficulty)difficultyEntry.Id; if (difficultyID == (setRaidDifficulty.Legacy != 0 ? GetPlayer().GetLegacyRaidDifficultyID() : GetPlayer().GetRaidDifficultyID())) { return; } // cannot reset while in an instance Map map = GetPlayer().GetMap(); if (map && map.IsDungeon()) { Log.outDebug(LogFilter.Network, "WorldSession:HandleSetRaidDifficulty: player (Name: {0}, {1} tried to reset the instance while inside!", GetPlayer().GetName(), GetPlayer().GetGUID().ToString()); return; } Group group = GetPlayer().GetGroup(); if (group) { if (group.IsLeader(GetPlayer().GetGUID())) { for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next()) { Player groupGuy = refe.GetSource(); if (!groupGuy) { continue; } if (!groupGuy.IsInMap(groupGuy)) { return; } if (groupGuy.GetMap().IsRaid()) { Log.outDebug(LogFilter.Network, "WorldSession:HandleSetRaidDifficulty: player {0} tried to reset the instance while inside!", GetPlayer().GetGUID().ToString()); return; } } // the difficulty is set even if the instances can't be reset group.ResetInstances(InstanceResetMethod.ChangeDifficulty, true, setRaidDifficulty.Legacy != 0, GetPlayer()); if (setRaidDifficulty.Legacy != 0) { group.SetLegacyRaidDifficultyID(difficultyID); } else { group.SetRaidDifficultyID(difficultyID); } } } else { GetPlayer().ResetInstances(InstanceResetMethod.ChangeDifficulty, true, setRaidDifficulty.Legacy != 0); if (setRaidDifficulty.Legacy != 0) { GetPlayer().SetLegacyRaidDifficultyID(difficultyID); } else { GetPlayer().SetRaidDifficultyID(difficultyID); } GetPlayer().SendRaidDifficulty(setRaidDifficulty.Legacy != 0); } }
void HandleSetDungeonDifficulty(SetDungeonDifficulty setDungeonDifficulty) { DifficultyRecord difficultyEntry = CliDB.DifficultyStorage.LookupByKey(setDungeonDifficulty.DifficultyID); if (difficultyEntry == null) { Log.outDebug(LogFilter.Network, "WorldSession.HandleSetDungeonDifficulty: {0} sent an invalid instance mode {1}!", GetPlayer().GetGUID().ToString(), setDungeonDifficulty.DifficultyID); return; } if (difficultyEntry.InstanceType != MapTypes.Instance) { Log.outDebug(LogFilter.Network, "WorldSession.HandleSetDungeonDifficulty: {0} sent an non-dungeon instance mode {1}!", GetPlayer().GetGUID().ToString(), difficultyEntry.Id); return; } if (!difficultyEntry.Flags.HasAnyFlag(DifficultyFlags.CanSelect)) { Log.outDebug(LogFilter.Network, "WorldSession.HandleSetDungeonDifficulty: {0} sent unselectable instance mode {1}!", GetPlayer().GetGUID().ToString(), difficultyEntry.Id); return; } Difficulty difficultyID = (Difficulty)difficultyEntry.Id; if (difficultyID == GetPlayer().GetDungeonDifficultyID()) { return; } // cannot reset while in an instance Map map = GetPlayer().GetMap(); if (map && map.IsDungeon()) { Log.outDebug(LogFilter.Network, "WorldSession:HandleSetDungeonDifficulty: player (Name: {0}, {1}) tried to reset the instance while player is inside!", GetPlayer().GetName(), GetPlayer().GetGUID().ToString()); return; } Group group = GetPlayer().GetGroup(); if (group) { if (group.IsLeader(GetPlayer().GetGUID())) { for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next()) { Player groupGuy = refe.GetSource(); if (!groupGuy) { continue; } if (!groupGuy.IsInMap(groupGuy)) { return; } if (groupGuy.GetMap().IsNonRaidDungeon()) { Log.outDebug(LogFilter.Network, "WorldSession:HandleSetDungeonDifficulty: {0} tried to reset the instance while group member (Name: {1}, {2}) is inside!", GetPlayer().GetGUID().ToString(), groupGuy.GetName(), groupGuy.GetGUID().ToString()); return; } } // the difficulty is set even if the instances can't be reset //_player.SendDungeonDifficulty(true); group.ResetInstances(InstanceResetMethod.ChangeDifficulty, false, false, GetPlayer()); group.SetDungeonDifficultyID(difficultyID); } } else { GetPlayer().ResetInstances(InstanceResetMethod.ChangeDifficulty, false, false); GetPlayer().SetDungeonDifficultyID(difficultyID); GetPlayer().SendDungeonDifficulty(); } }
void HandleAreaTrigger(AreaTriggerPkt packet) { Player player = GetPlayer(); if (player.IsInFlight()) { Log.outDebug(LogFilter.Network, "HandleAreaTriggerOpcode: Player '{0}' (GUID: {1}) in flight, ignore Area Trigger ID:{2}", player.GetName(), player.GetGUID().ToString(), packet.AreaTriggerID); return; } AreaTriggerRecord atEntry = CliDB.AreaTriggerStorage.LookupByKey(packet.AreaTriggerID); if (atEntry == null) { Log.outDebug(LogFilter.Network, "HandleAreaTriggerOpcode: Player '{0}' (GUID: {1}) send unknown (by DBC) Area Trigger ID:{2}", player.GetName(), player.GetGUID().ToString(), packet.AreaTriggerID); return; } if (packet.Entered && !player.IsInAreaTriggerRadius(atEntry)) { Log.outDebug(LogFilter.Network, "HandleAreaTriggerOpcode: Player '{0}' ({1}) too far, ignore Area Trigger ID: {2}", player.GetName(), player.GetGUID().ToString(), packet.AreaTriggerID); return; } if (player.IsDebugAreaTriggers) { player.SendSysMessage(packet.Entered ? CypherStrings.DebugAreatriggerEntered : CypherStrings.DebugAreatriggerLeft, packet.AreaTriggerID); } if (Global.ScriptMgr.OnAreaTrigger(player, atEntry, packet.Entered)) { return; } if (player.IsAlive()) { List <uint> quests = Global.ObjectMgr.GetQuestsForAreaTrigger(packet.AreaTriggerID); if (quests != null) { foreach (uint questId in quests) { Quest qInfo = Global.ObjectMgr.GetQuestTemplate(questId); if (qInfo != null && player.GetQuestStatus(questId) == QuestStatus.Incomplete) { foreach (QuestObjective obj in qInfo.Objectives) { if (obj.Type == QuestObjectiveType.AreaTrigger && !player.IsQuestObjectiveComplete(obj)) { player.SetQuestObjectiveData(obj, 1); player.SendQuestUpdateAddCreditSimple(obj); break; } } if (player.CanCompleteQuest(questId)) { player.CompleteQuest(questId); } } } } } if (Global.ObjectMgr.IsTavernAreaTrigger(packet.AreaTriggerID)) { // set resting flag we are in the inn player.GetRestMgr().SetRestFlag(RestFlag.Tavern, atEntry.Id); if (Global.WorldMgr.IsFFAPvPRealm()) { player.RemovePvpFlag(UnitPVPStateFlags.FFAPvp); } return; } Battleground bg = player.GetBattleground(); if (bg) { bg.HandleAreaTrigger(player, packet.AreaTriggerID, packet.Entered); } OutdoorPvP pvp = player.GetOutdoorPvP(); if (pvp != null) { if (pvp.HandleAreaTrigger(player, packet.AreaTriggerID, packet.Entered)) { return; } } AreaTriggerStruct at = Global.ObjectMgr.GetAreaTrigger(packet.AreaTriggerID); if (at == null) { return; } bool teleported = false; if (player.GetMapId() != at.target_mapId) { EnterState denyReason = Global.MapMgr.PlayerCannotEnter(at.target_mapId, player, false); if (denyReason != 0) { bool reviveAtTrigger = false; // should we revive the player if he is trying to enter the correct instance? switch (denyReason) { case EnterState.CannotEnterNoEntry: Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' attempted to enter map with id {1} which has no entry", player.GetName(), at.target_mapId); break; case EnterState.CannotEnterUninstancedDungeon: Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' attempted to enter dungeon map {1} but no instance template was found", player.GetName(), at.target_mapId); break; case EnterState.CannotEnterDifficultyUnavailable: { Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' attempted to enter instance map {1} but the requested difficulty was not found", player.GetName(), at.target_mapId); MapRecord entry = CliDB.MapStorage.LookupByKey(at.target_mapId); if (entry != null) { player.SendTransferAborted(entry.Id, TransferAbortReason.Difficulty, (byte)player.GetDifficultyID(entry)); } } break; case EnterState.CannotEnterNotInRaid: Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' must be in a raid group to enter map {1}", player.GetName(), at.target_mapId); player.SendRaidGroupOnlyMessage(RaidGroupReason.Only, 0); reviveAtTrigger = true; break; case EnterState.CannotEnterCorpseInDifferentInstance: player.SendPacket(new AreaTriggerNoCorpse()); Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' does not have a corpse in instance map {1} and cannot enter", player.GetName(), at.target_mapId); break; case EnterState.CannotEnterInstanceBindMismatch: { MapRecord entry = CliDB.MapStorage.LookupByKey(at.target_mapId); if (entry != null) { string mapName = entry.MapName[player.GetSession().GetSessionDbcLocale()]; Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' cannot enter instance map '{1}' because their permanent bind is incompatible with their group's", player.GetName(), mapName); // is there a special opcode for this? // @todo figure out how to get player localized difficulty string (e.g. "10 player", "Heroic" etc) player.SendSysMessage(CypherStrings.InstanceBindMismatch, mapName); } reviveAtTrigger = true; } break; case EnterState.CannotEnterTooManyInstances: player.SendTransferAborted(at.target_mapId, TransferAbortReason.TooManyInstances); Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' cannot enter instance map {1} because he has exceeded the maximum number of instances per hour.", player.GetName(), at.target_mapId); reviveAtTrigger = true; break; case EnterState.CannotEnterMaxPlayers: player.SendTransferAborted(at.target_mapId, TransferAbortReason.MaxPlayers); reviveAtTrigger = true; break; case EnterState.CannotEnterZoneInCombat: player.SendTransferAborted(at.target_mapId, TransferAbortReason.ZoneInCombat); reviveAtTrigger = true; break; default: break; } if (reviveAtTrigger) // check if the player is touching the areatrigger leading to the map his corpse is on { if (!player.IsAlive() && player.HasCorpse()) { if (player.GetCorpseLocation().GetMapId() == at.target_mapId) { player.ResurrectPlayer(0.5f); player.SpawnCorpseBones(); } } } return; } Group group = player.GetGroup(); if (group) { if (group.IsLFGGroup() && player.GetMap().IsDungeon()) { teleported = player.TeleportToBGEntryPoint(); } } } if (!teleported) { WorldSafeLocsEntry entranceLocation = null; InstanceSave instanceSave = player.GetInstanceSave(at.target_mapId); if (instanceSave != null) { // Check if we can contact the instancescript of the instance for an updated entrance location Map map = Global.MapMgr.FindMap(at.target_mapId, player.GetInstanceSave(at.target_mapId).GetInstanceId()); if (map) { InstanceMap instanceMap = map.ToInstanceMap(); if (instanceMap != null) { InstanceScript instanceScript = instanceMap.GetInstanceScript(); if (instanceScript != null) { entranceLocation = Global.ObjectMgr.GetWorldSafeLoc(instanceScript.GetEntranceLocation()); } } } // Finally check with the instancesave for an entrance location if we did not get a valid one from the instancescript if (entranceLocation == null) { entranceLocation = Global.ObjectMgr.GetWorldSafeLoc(instanceSave.GetEntranceLocation()); } } if (entranceLocation != null) { player.TeleportTo(entranceLocation.Loc, TeleportToOptions.NotLeaveTransport); } else { player.TeleportTo(at.target_mapId, at.target_X, at.target_Y, at.target_Z, at.target_Orientation, TeleportToOptions.NotLeaveTransport); } } }
void HandlePartyInvite(PartyInviteClient packet) { Player player = Global.ObjAccessor.FindPlayerByName(packet.TargetName); // no player if (!player) { SendPartyResult(PartyOperation.Invite, packet.TargetName, PartyResult.BadPlayerNameS); return; } // player trying to invite himself (most likely cheating) if (player == GetPlayer()) { SendPartyResult(PartyOperation.Invite, player.GetName(), PartyResult.BadPlayerNameS); return; } // restrict invite to GMs if (!WorldConfig.GetBoolValue(WorldCfg.AllowGmGroup) && !GetPlayer().IsGameMaster() && player.IsGameMaster()) { SendPartyResult(PartyOperation.Invite, player.GetName(), PartyResult.BadPlayerNameS); return; } // can't group with if (!GetPlayer().IsGameMaster() && !WorldConfig.GetBoolValue(WorldCfg.AllowTwoSideInteractionGroup) && GetPlayer().GetTeam() != player.GetTeam()) { SendPartyResult(PartyOperation.Invite, player.GetName(), PartyResult.PlayerWrongFaction); return; } if (GetPlayer().GetInstanceId() != 0 && player.GetInstanceId() != 0 && GetPlayer().GetInstanceId() != player.GetInstanceId() && GetPlayer().GetMapId() == player.GetMapId()) { SendPartyResult(PartyOperation.Invite, player.GetName(), PartyResult.TargetNotInInstanceS); return; } // just ignore us if (player.GetInstanceId() != 0 && player.GetDungeonDifficultyID() != GetPlayer().GetDungeonDifficultyID()) { SendPartyResult(PartyOperation.Invite, player.GetName(), PartyResult.IgnoringYouS); return; } if (player.GetSocial().HasIgnore(GetPlayer().GetGUID())) { SendPartyResult(PartyOperation.Invite, player.GetName(), PartyResult.IgnoringYouS); return; } if (!player.GetSocial().HasFriend(GetPlayer().GetGUID()) && GetPlayer().getLevel() < WorldConfig.GetIntValue(WorldCfg.PartyLevelReq)) { SendPartyResult(PartyOperation.Invite, player.GetName(), PartyResult.InviteRestricted); return; } Group group = GetPlayer().GetGroup(); if (group && group.isBGGroup()) { group = GetPlayer().GetOriginalGroup(); } Group group2 = player.GetGroup(); if (group2 && group2.isBGGroup()) { group2 = player.GetOriginalGroup(); } PartyInvite partyInvite; // player already in another group or invited if (group2 || player.GetGroupInvite()) { SendPartyResult(PartyOperation.Invite, player.GetName(), PartyResult.AlreadyInGroupS); if (group2) { // tell the player that they were invited but it failed as they were already in a group partyInvite = new PartyInvite(); partyInvite.Initialize(GetPlayer(), packet.ProposedRoles, false); player.SendPacket(partyInvite); } return; } if (group) { // not have permissions for invite if (!group.IsLeader(GetPlayer().GetGUID()) && !group.IsAssistant(GetPlayer().GetGUID())) { SendPartyResult(PartyOperation.Invite, "", PartyResult.NotLeader); return; } // not have place if (group.IsFull()) { SendPartyResult(PartyOperation.Invite, "", PartyResult.GroupFull); return; } } // ok, but group not exist, start a new group // but don't create and save the group to the DB until // at least one person joins if (!group) { group = new Group(); // new group: if can't add then delete if (!group.AddLeaderInvite(GetPlayer())) { return; } if (!group.AddInvite(player)) { group.RemoveAllInvites(); return; } } else { // already existed group: if can't add then just leave if (!group.AddInvite(player)) { return; } } partyInvite = new PartyInvite(); partyInvite.Initialize(GetPlayer(), packet.ProposedRoles, true); player.SendPacket(partyInvite); SendPartyResult(PartyOperation.Invite, player.GetName(), PartyResult.Ok); }
void HandlePartyInviteResponse(PartyInviteResponse packet) { Group group = GetPlayer().GetGroupInvite(); if (!group) { return; } if (packet.Accept) { // Remove player from invitees in any case group.RemoveInvite(GetPlayer()); if (group.GetLeaderGUID() == GetPlayer().GetGUID()) { Log.outError(LogFilter.Network, "HandleGroupAcceptOpcode: player {0} ({1}) tried to accept an invite to his own group", GetPlayer().GetName(), GetPlayer().GetGUID().ToString()); return; } // Group is full if (group.IsFull()) { SendPartyResult(PartyOperation.Invite, "", PartyResult.GroupFull); return; } Player leader = Global.ObjAccessor.FindPlayer(group.GetLeaderGUID()); // Forming a new group, create it if (!group.IsCreated()) { // This can happen if the leader is zoning. To be removed once delayed actions for zoning are implemented if (!leader) { group.RemoveAllInvites(); return; } // If we're about to create a group there really should be a leader present Cypher.Assert(leader); group.RemoveInvite(leader); group.Create(leader); Global.GroupMgr.AddGroup(group); } // Everything is fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!! if (!group.AddMember(GetPlayer())) { return; } group.BroadcastGroupUpdate(); } else { // Remember leader if online (group will be invalid if group gets disbanded) Player leader = Global.ObjAccessor.FindPlayer(group.GetLeaderGUID()); // uninvite, group can be deleted GetPlayer().UninviteFromGroup(); if (!leader || leader.GetSession() == null) { return; } // report GroupDecline decline = new GroupDecline(GetPlayer().GetName()); leader.SendPacket(decline); } }