void SendSpiritResurrect() { GetPlayer().ResurrectPlayer(0.5f, true); GetPlayer().DurabilityLossAll(0.25f, true); // get corpse nearest graveyard WorldSafeLocsRecord corpseGrave = null; WorldLocation corpseLocation = GetPlayer().GetCorpseLocation(); if (GetPlayer().HasCorpse()) { corpseGrave = Global.ObjectMgr.GetClosestGraveYard(corpseLocation, GetPlayer().GetTeam(), GetPlayer()); } // now can spawn bones GetPlayer().SpawnCorpseBones(); // teleport to nearest from corpse graveyard, if different from nearest to player ghost if (corpseGrave != null) { WorldSafeLocsRecord ghostGrave = Global.ObjectMgr.GetClosestGraveYard(GetPlayer(), GetPlayer().GetTeam(), GetPlayer()); if (corpseGrave != ghostGrave) { GetPlayer().TeleportTo(corpseGrave.MapID, corpseGrave.Loc.X, corpseGrave.Loc.Y, corpseGrave.Loc.Z, GetPlayer().GetOrientation()); } } }
public void SetBattlegroundEntryPoint() { // Taxi path store if (!m_taxi.empty()) { m_bgData.mountSpell = 0; m_bgData.taxiPath[0] = m_taxi.GetTaxiSource(); m_bgData.taxiPath[1] = m_taxi.GetTaxiDestination(); // On taxi we don't need check for dungeon m_bgData.joinPos = new WorldLocation(GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation()); } else { m_bgData.ClearTaxiPath(); // Mount spell id storing if (IsMounted()) { var auras = GetAuraEffectsByType(AuraType.Mounted); if (!auras.Empty()) { m_bgData.mountSpell = auras[0].GetId(); } } else { m_bgData.mountSpell = 0; } // If map is dungeon find linked graveyard if (GetMap().IsDungeon()) { WorldSafeLocsRecord entry = Global.ObjectMgr.GetClosestGraveYard(GetPositionX(), GetPositionY(), GetPositionZ(), GetMapId(), GetTeam()); if (entry != null) { m_bgData.joinPos = new WorldLocation(entry.MapID, entry.Loc.X, entry.Loc.Y, entry.Loc.Z, 0.0f); } else { Log.outError(LogFilter.Player, "SetBattlegroundEntryPoint: Dungeon map {0} has no linked graveyard, setting home location as entry point.", GetMapId()); } } // If new entry point is not BG or arena set it else if (!GetMap().IsBattlegroundOrArena()) { m_bgData.joinPos = new WorldLocation(GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation()); } } if (m_bgData.joinPos.GetMapId() == 0xFFFFFFFF) // In error cases use homebind position { m_bgData.joinPos = new WorldLocation(GetHomebind()); } }
public override WorldSafeLocsRecord GetClosestGraveYard(Player player) { int teamIndex = GetTeamIndexByTeamId(player.GetTeam()); // Is there any occupied node for this team? List <byte> nodes = new List <byte>(); for (byte i = 0; i < BattlegroundNodes.DynamicNodesCount; ++i) { if (m_Nodes[i] == NodeStatus.Occupied + (int)teamIndex) { nodes.Add(i); } } WorldSafeLocsRecord good_entry = null; // If so, select the closest node to place ghost on if (!nodes.Empty()) { float plr_x = player.GetPositionX(); float plr_y = player.GetPositionY(); float mindist = 999999.0f; for (byte i = 0; i < nodes.Count; ++i) { WorldSafeLocsRecord entry = CliDB.WorldSafeLocsStorage.LookupByKey(GraveyardIds[nodes[i]]); if (entry == null) { continue; } float dist = (entry.Loc.X - plr_x) * (entry.Loc.X - plr_x) + (entry.Loc.Y - plr_y) * (entry.Loc.Y - plr_y); if (mindist > dist) { mindist = dist; good_entry = entry; } } nodes.Clear(); } // If not, place ghost on starting location if (good_entry == null) { good_entry = CliDB.WorldSafeLocsStorage.LookupByKey(GraveyardIds[teamIndex + 5]); } return(good_entry); }
static bool HandleGoGraveyardCommand(StringArguments args, CommandHandler handler) { Player player = handler.GetSession().GetPlayer(); if (args.Empty()) { return(false); } uint graveyardId = args.NextUInt32(); if (graveyardId == 0) { return(false); } WorldSafeLocsRecord gy = CliDB.WorldSafeLocsStorage.LookupByKey(graveyardId); if (gy == null) { handler.SendSysMessage(CypherStrings.CommandGraveyardnoexist, graveyardId); return(false); } if (!GridDefines.IsValidMapCoord(gy.MapID, gy.Loc.X, gy.Loc.Y, gy.Loc.Z)) { handler.SendSysMessage(CypherStrings.InvalidTargetCoord, gy.Loc.X, gy.Loc.Y, gy.MapID); return(false); } // stop flight if need if (player.IsInFlight()) { player.GetMotionMaster().MovementExpired(); player.CleanupAfterTaxiFlight(); } // save only in non-flight case else { player.SaveRecallPosition(); } player.TeleportTo(gy.MapID, gy.Loc.X, gy.Loc.Y, gy.Loc.Z, (gy.Facing * MathFunctions.PI) / 180); // Orientation is initially in degrees return(true); }
public void LoadBattlegroundTemplates() { uint oldMSTime = Time.GetMSTime(); _BattlegroundMapTemplates.Clear(); _BattlegroundTemplates.Clear(); // 0 1 2 3 4 5 6 7 8 9 SQLResult result = DB.World.Query("SELECT ID, MinPlayersPerTeam, MaxPlayersPerTeam, MinLvl, MaxLvl, AllianceStartLoc, HordeStartLoc, StartMaxDist, Weight, ScriptName FROM battleground_template"); if (result.IsEmpty()) { Log.outError(LogFilter.ServerLoading, "Loaded 0 Battlegrounds. DB table `Battleground_template` is empty."); return; } uint count = 0; do { BattlegroundTypeId bgTypeId = (BattlegroundTypeId)result.Read <uint>(0); if (Global.DisableMgr.IsDisabledFor(DisableType.Battleground, (uint)bgTypeId, null)) { continue; } // can be overwrite by values from DB BattlemasterListRecord bl = CliDB.BattlemasterListStorage.LookupByKey(bgTypeId); if (bl == null) { Log.outError(LogFilter.Battleground, "Battleground ID {0} not found in BattlemasterList.dbc. Battleground not created.", bgTypeId); continue; } BattlegroundTemplate bgTemplate = new BattlegroundTemplate(); bgTemplate.Id = bgTypeId; bgTemplate.MinPlayersPerTeam = result.Read <ushort>(1); bgTemplate.MaxPlayersPerTeam = result.Read <ushort>(2); bgTemplate.MinLevel = result.Read <byte>(3); bgTemplate.MaxLevel = result.Read <byte>(4); float dist = result.Read <float>(7); bgTemplate.StartMaxDist = dist * dist; bgTemplate.Weight = result.Read <byte>(8); bgTemplate.scriptId = Global.ObjectMgr.GetScriptId(result.Read <string>(9)); bgTemplate.BattlemasterEntry = bl; if (bgTemplate.MaxPlayersPerTeam == 0 || bgTemplate.MinPlayersPerTeam > bgTemplate.MaxPlayersPerTeam) { Log.outError(LogFilter.Sql, "Table `Battleground_template` for Id {0} has bad values for MinPlayersPerTeam ({1}) and MaxPlayersPerTeam({2})", bgTemplate.Id, bgTemplate.MinPlayersPerTeam, bgTemplate.MaxPlayersPerTeam); continue; } if (bgTemplate.MinLevel == 0 || bgTemplate.MaxLevel == 0 || bgTemplate.MinLevel > bgTemplate.MaxLevel) { Log.outError(LogFilter.Sql, "Table `Battleground_template` for Id {0} has bad values for LevelMin ({1}) and LevelMax({2})", bgTemplate.Id, bgTemplate.MinLevel, bgTemplate.MaxLevel); continue; } if (bgTemplate.Id != BattlegroundTypeId.AA && bgTemplate.Id != BattlegroundTypeId.RB) { uint startId = result.Read <uint>(5); if (CliDB.WorldSafeLocsStorage.ContainsKey(startId)) { WorldSafeLocsRecord start = CliDB.WorldSafeLocsStorage.LookupByKey(startId); bgTemplate.StartLocation[TeamId.Alliance] = new Position(start.Loc.X, start.Loc.Y, start.Loc.Z, (start.Facing + MathFunctions.PI) / 180); } else { Log.outError(LogFilter.Sql, "Table `Battleground_template` for Id {0} has a non-existed WorldSafeLocs.dbc id {1} in field `AllianceStartLoc`. BG not created.", bgTemplate.Id, startId); continue; } startId = result.Read <uint>(6); if (CliDB.WorldSafeLocsStorage.ContainsKey(startId)) { WorldSafeLocsRecord start = CliDB.WorldSafeLocsStorage.LookupByKey(startId); bgTemplate.StartLocation[TeamId.Horde] = new Position(start.Loc.X, start.Loc.Y, start.Loc.Z, result.Read <float>(8)); } else { Log.outError(LogFilter.Sql, "Table `Battleground_template` for Id {0} has a non-existed WorldSafeLocs.dbc id {1} in field `HordeStartLoc`. BG not created.", bgTemplate.Id, startId); continue; } } if (!CreateBattleground(bgTemplate)) { continue; } _BattlegroundTemplates[bgTypeId] = bgTemplate; if (bgTemplate.BattlemasterEntry.MapId[1] == -1) // in this case we have only one mapId { _BattlegroundMapTemplates[(uint)bgTemplate.BattlemasterEntry.MapId[0]] = _BattlegroundTemplates[bgTypeId]; } ++count; }while (result.NextRow()); Log.outInfo(LogFilter.ServerLoading, "Loaded {0} Battlegrounds in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime)); }
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.RemoveByteFlag(UnitFields.Bytes2, UnitBytes2Offsets.PvpFlag, UnitBytes2Flags.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) { WorldSafeLocsRecord 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 = CliDB.WorldSafeLocsStorage.LookupByKey(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 = CliDB.WorldSafeLocsStorage.LookupByKey(instanceSave.GetEntranceLocation()); } } if (entranceLocation != null) { player.TeleportTo(entranceLocation.MapID, entranceLocation.Loc.X, entranceLocation.Loc.Y, entranceLocation.Loc.Z, (float)(entranceLocation.Facing * Math.PI / 180), TeleportToOptions.NotLeaveTransport); } else { player.TeleportTo(at.target_mapId, at.target_X, at.target_Y, at.target_Z, at.target_Orientation, TeleportToOptions.NotLeaveTransport); } } }