public override void OnUse(Session session) { global::ACE.Server.Entity.Player.ConsumableBuffType buffType; if (Food) { switch (BoostEnum) { case (int)global::ACE.Server.Entity.Player.ConsumableBuffType.Health: buffType = global::ACE.Server.Entity.Player.ConsumableBuffType.Health; break; case (int)global::ACE.Server.Entity.Player.ConsumableBuffType.Mana: buffType = global::ACE.Server.Entity.Player.ConsumableBuffType.Mana; break; default: buffType = global::ACE.Server.Entity.Player.ConsumableBuffType.Stamina; break; } } else { buffType = global::ACE.Server.Entity.Player.ConsumableBuffType.Spell; } session.Player.ApplyComsumable(Name, SolidOrLiquid(), buffType, (uint)Boost, SpellDID); session.Player.HandleActionRemoveItemFromInventory(Guid.Full, session.Player.Guid.Full, 1); var sendUseDoneEvent = new GameEventUseDone(session); session.Network.EnqueueSend(sendUseDoneEvent); }
/// <summary> /// This is raised by Player.HandleActionUseItem.<para /> /// The item should be in the players possession. /// </summary> public override void UseItem(Player player) { Player.ConsumableBuffType buffType; //if (Food) //{ switch (BoostEnum) { case (int)Player.ConsumableBuffType.Health: buffType = Player.ConsumableBuffType.Health; break; case (int)Player.ConsumableBuffType.Mana: buffType = Player.ConsumableBuffType.Mana; break; default: buffType = Player.ConsumableBuffType.Stamina; break; } //} //else // buffType = WorldObjects.Player.ConsumableBuffType.Spell; player.ApplyConsumable(Name, GetSoundDid(), buffType, (uint)Boost, SpellDID); player.TryRemoveItemFromInventoryWithNetworkingWithDestroy(this, 1); var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(sendUseDoneEvent); }
public override void HandleActionOnUse(ObjectGuid playerId) { ActionChain chain = new ActionChain(); CurrentLandblock.ChainOnObject(chain, playerId, (WorldObject wo) => { Player player = wo as Player; if (player == null) { return; } ////if (playerDistanceTo >= 2500) ////{ //// var sendTooFarMsg = new GameEventDisplayStatusMessage(player.Session, StatusMessageType1.Enum_0037); //// player.Session.Network.EnqueueSend(sendTooFarMsg, sendUseDoneEvent); //// return; ////} if (!player.IsWithinUseRadiusOf(this)) { player.DoMoveTo(this); } else { ActionChain checkDoorChain = new ActionChain(); checkDoorChain.AddAction(this, () => { if (!IsLocked) { if (!IsOpen) { Open(playerId); } else { Close(playerId); } // Create Door auto close timer ActionChain autoCloseTimer = new ActionChain(); autoCloseTimer.AddDelaySeconds(ResetInterval); autoCloseTimer.AddAction(this, () => Reset()); autoCloseTimer.EnqueueChain(); } else { CurrentLandblock.EnqueueBroadcastSound(this, Sound.OpenFailDueToLock); } var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(sendUseDoneEvent); }); checkDoorChain.EnqueueChain(); } }); chain.EnqueueChain(); }
public override void HandleActionOnUse(ObjectGuid playerId) { ActionChain chain = new ActionChain(); CurrentLandblock.ChainOnObject(chain, playerId, (WorldObject wo) => { Player player = wo as Player; if (player == null) { return; } if (!player.IsWithinUseRadiusOf(this)) { player.DoMoveTo(this); } else { // TODO: to be removed once physics collisions are implemented HandleActionOnCollide(playerId); // always send useDone event var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(sendUseDoneEvent); } }); // Run on the player chain.EnqueueChain(); }
/// <summary> /// This is raised by Player.HandleActionUseItem, and is wrapped in ActionChain. /// </summary> public override void DoActionUseItem(Session session) { Player.ConsumableBuffType buffType; //if (Food) //{ switch (BoostEnum) { case (int)WorldObjects.Player.ConsumableBuffType.Health: buffType = WorldObjects.Player.ConsumableBuffType.Health; break; case (int)WorldObjects.Player.ConsumableBuffType.Mana: buffType = WorldObjects.Player.ConsumableBuffType.Mana; break; default: buffType = WorldObjects.Player.ConsumableBuffType.Stamina; break; } //} //else // buffType = WorldObjects.Player.ConsumableBuffType.Spell; session.Player.ApplyComsumable(Name, GetSoundDid(), buffType, (uint)Boost, SpellDID); session.Player.RemoveItemFromInventory(Guid.Full, session.Player.Guid.Full, 1); var sendUseDoneEvent = new GameEventUseDone(session); session.Network.EnqueueSend(sendUseDoneEvent); }
public override void ActOnUse(ObjectGuid playerId) { Player player = CurrentLandblock.GetObject(playerId) as Player; if (player == null) { return; } ////if (playerDistanceTo >= 2500) ////{ //// var sendTooFarMsg = new GameEventDisplayStatusMessage(player.Session, StatusMessageType1.Enum_0037); //// player.Session.Network.EnqueueSend(sendTooFarMsg, sendUseDoneEvent); //// return; ////} if (!player.IsWithinUseRadiusOf(this)) { player.DoMoveTo(this); } else { if (AllowedActivator == null) { Activate(playerId); } var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(sendUseDoneEvent); } }
public override void OnUse(Player player) { string serverMessage = null; // validate within use range, taking into account the radius of the model itself, as well SetupModel csetup = SetupModel.ReadFromDat(this.PhysicsData.CSetup); float radiusSquared = (this.GameData.UseRadius + csetup.Radius) * (this.GameData.UseRadius + csetup.Radius); var motionSanctuary = new UniversalMotion(MotionStance.Standing, new MotionItem(MotionCommand.Sanctuary)); var animationEvent = new GameMessageUpdateMotion(player, player.Session, motionSanctuary); // This event was present for a pcap in the training dungeon.. Why? The sound comes with animationEvent... var soundEvent = new GameMessageSound(this.Guid, Sound.LifestoneOn, 1); if (player.Location.SquaredDistanceTo(this.Location) >= radiusSquared) { serverMessage = "You wandered too far to attune with the Lifestone!"; } else { player.SetCharacterPosition(PositionType.Sanctuary, player.Location); // create the outbound server message serverMessage = "You have attuned your spirit to this Lifestone. You will resurrect here after you die."; player.EnqueueMovementEvent(motionSanctuary, player.Guid); player.Session.Network.EnqueueSend(soundEvent); } var lifestoneBindMessage = new GameMessageSystemChat(serverMessage, ChatMessageType.Magic); // always send useDone event var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(lifestoneBindMessage, sendUseDoneEvent); }
/// <summary> /// This is raised by Player.HandleActionUseItem.<para /> /// The item should be in the players possession. /// </summary> public override void UseItem(Player player) { var buffType = Player.ConsumableBuffType.Stamina; if (BoostEnum != null) { switch (BoostEnum) { case (int)Player.ConsumableBuffType.Health: buffType = Player.ConsumableBuffType.Health; break; case (int)Player.ConsumableBuffType.Mana: buffType = Player.ConsumableBuffType.Mana; break; case (int)Player.ConsumableBuffType.Spell: buffType = Player.ConsumableBuffType.Spell; break; } } player.ApplyConsumable(Name, GetSoundDid(), buffType, (uint)Boost, SpellDID); player.TryConsumeFromInventoryWithNetworking(this, 1); var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(sendUseDoneEvent); }
public override void OnUse(Player player) { string serverMessage = null; // validate within use range, taking into account the radius of the model itself, as well SetupModel csetup = SetupModel.ReadFromDat(PhysicsData.CSetup); float radiusSquared = (GameData.UseRadius + csetup.Radius) * (GameData.UseRadius + csetup.Radius); if (player.Location.SquaredDistanceTo(Location) >= radiusSquared) { serverMessage = "Your way to far away to trust, come closer and buy something or leave me alone!"; } else { // create the outbound server message serverMessage = "You Break it, you bought it!"; } // give player starting money var money = new GameMessagePrivateUpdatePropertyInt(player.Session, PropertyInt.CoinValue, 5000); player.Session.Network.EnqueueSend(money); var welcomemsg = new GameMessageSystemChat(serverMessage, ChatMessageType.Tell); // always send useDone event var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(welcomemsg, sendUseDoneEvent); player.Session.Network.EnqueueSend(new GameEventApproachVendor(player.Session, this.Guid.Full)); }
public override void OnUse(Player player) { // TODO: implement auto close timer, check if door is locked, send locked soundfx if locked and fail to open. if (this.PhysicsData.CurrentMotionState == motionStateClosed) { Open(player); } else { Close(player); } var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(sendUseDoneEvent); }
public override void HandleActionOnUse(ObjectGuid playerId) { // All data on a lifestone is constant -- therefore we just run in context of player ActionChain chain = new ActionChain(); CurrentLandblock.ChainOnObject(chain, playerId, (WorldObject wo) => { Player player = wo as Player; string serverMessage = null; // validate within use range, taking into account the radius of the model itself, as well SetupModel csetup = SetupModel.ReadFromDat(SetupTableId.Value); float radiusSquared = (UseRadius.Value + csetup.Radius) * (UseRadius.Value + csetup.Radius); // Run this animation... // Player Enqueue: var motionSanctuary = new UniversalMotion(MotionStance.Standing, new MotionItem(MotionCommand.Sanctuary)); var animationEvent = new GameMessageUpdateMotion(player.Guid, player.Sequences.GetCurrentSequence(Network.Sequence.SequenceType.ObjectInstance), player.Sequences, motionSanctuary); // This event was present for a pcap in the training dungeon.. Why? The sound comes with animationEvent... var soundEvent = new GameMessageSound(Guid, Sound.LifestoneOn, 1); if (player.Location.SquaredDistanceTo(Location) >= radiusSquared) { serverMessage = "You wandered too far to attune with the Lifestone!"; } else { player.SetCharacterPosition(PositionType.Sanctuary, player.Location); // create the outbound server message serverMessage = "You have attuned your spirit to this Lifestone. You will resurrect here after you die."; player.HandleActionMotion(motionSanctuary); player.Session.Network.EnqueueSend(soundEvent); } var lifestoneBindMessage = new GameMessageSystemChat(serverMessage, ChatMessageType.Magic); // always send useDone event var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(lifestoneBindMessage, sendUseDoneEvent); }); chain.EnqueueChain(); }
/// <summary> /// This is raised by Player.HandleActionUseItem, and is wrapped in ActionChain.<para /> /// The actor of the ActionChain is the item being used.<para /> /// The item does not exist in the players possession.<para /> /// If the item was outside of range, the player will have been commanded to move using DoMoveTo before ActOnUse is called.<para /> /// When this is called, it should be assumed that the player is within range. /// </summary> public override void ActOnUse(Player player) { ////if (playerDistanceTo >= 2500) ////{ //// var sendTooFarMsg = new GameEventDisplayStatusMessage(player.Session, StatusMessageType1.Enum_0037); //// player.Session.Network.EnqueueSend(sendTooFarMsg, sendUseDoneEvent); //// return; ////} if (AllowedActivator == null) { Activate(player.Guid); } var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(sendUseDoneEvent); }
public override void HandleActionOnUse(ObjectGuid playerId) { ActionChain chain = new ActionChain(); CurrentLandblock.ChainOnObject(chain, playerId, (WorldObject wo) => { Player player = wo as Player; if (player == null) { return; } ////if (playerDistanceTo >= 2500) ////{ //// var sendTooFarMsg = new GameEventDisplayStatusMessage(player.Session, StatusMessageType1.Enum_0037); //// player.Session.Network.EnqueueSend(sendTooFarMsg, sendUseDoneEvent); //// return; ////} if (!player.IsWithinUseRadiusOf(this)) { player.DoMoveTo(this); } else { ActionChain useObjectChain = new ActionChain(); useObjectChain.AddAction(this, () => { if (AllowedActivator == null) { Activate(playerId); } var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(sendUseDoneEvent); }); useObjectChain.EnqueueChain(); } }); chain.EnqueueChain(); }
/*public AceObject SnapShotOfAceObject(bool clearDirtyFlags = false) * { * AceObject snapshot = (AceObject)AceObject.Clone(); * if (clearDirtyFlags) * AceObject.ClearDirtyFlags(); * return snapshot; * }*/ public virtual void ActOnUse(ObjectGuid playerId) { // Do Nothing by default if (CurrentLandblock != null) { Player player = CurrentLandblock.GetObject(playerId) as Player; if (player == null) { return; } #if DEBUG var errorMessage = new GameMessageSystemChat($"Default HandleActionOnUse reached, this object ({Name}) not programmed yet.", ChatMessageType.System); player.Session.Network.EnqueueSend(errorMessage); #endif var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(sendUseDoneEvent); } }
// FIXME(ddevec): I broke vendors -- I need to think about how to reimplement this cleanly public override void OnUse(ObjectGuid playerId) { ActionChain chain = new ActionChain(); CurrentLandblock.ChainOnObject(chain, playerId, (WorldObject wo) => { Player player = wo as Player; if (player == null) { return; } string serverMessage = null; // validate within use range, taking into account the radius of the model itself, as well SetupModel csetup = SetupModel.ReadFromDat(PhysicsData.CSetup); float radiusSquared = (GameData.UseRadius + csetup.Radius) * (GameData.UseRadius + csetup.Radius); // We're static, so this is safe -- our Location is never written if (player.Location.SquaredDistanceTo(Location) >= radiusSquared) { serverMessage = "Your way to far away to trust, come closer and buy something or leave me alone!"; } else { // create the outbound server message serverMessage = "You Break it, you bought it!"; } // give player starting money var money = new GameMessagePrivateUpdatePropertyInt(player.Session, PropertyInt.CoinValue, 5000); player.Session.Network.EnqueueSend(money); var welcomemsg = new GameMessageSystemChat(serverMessage, ChatMessageType.Tell); // always send useDone event var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(welcomemsg, sendUseDoneEvent); player.Session.Network.EnqueueSend(new GameEventApproachVendor(player.Session, Guid)); }); chain.EnqueueChain(); }
/// <summary> /// This is the OnUse method. This is just an initial implemention. I have put in the turn to action at this point. /// If we are out of use radius, move to the object. Once in range, let's turn the creature toward us and get started. /// Note - we may need to make an NPC class vs monster as using a monster does not make them turn towrad you as I recall. Og II /// Also, once we are reading in the emotes table by weenie - this will automatically customize the behavior for creatures. /// </summary> /// <param name="playerId">Identity of the player we are interacting with</param> public override void ActOnUse(ObjectGuid playerId) { Player player = CurrentLandblock.GetObject(playerId) as Player; if (player == null) { return; } if (!player.IsWithinUseRadiusOf(this)) { player.DoMoveTo(this); } else { OnAutonomousMove(player.Location, this.Sequences, MovementTypes.TurnToObject, playerId); GameEventUseDone sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(sendUseDoneEvent); } }
public override void ActOnUse(ObjectGuid playerId) { Player player = CurrentLandblock.GetObject(playerId) as Player; if (player == null) { return; } if (!player.IsWithinUseRadiusOf(this)) { player.DoMoveTo(this); } else { // TODO: to be removed once physics collisions are implemented HandleActionOnCollide(playerId); // always send useDone event var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(sendUseDoneEvent); } }
/// <summary> /// This is the OnUse method. This is just an initial implemention. I have put in the turn to action at this point. /// If we are out of use radius, move to the object. Once in range, let's turn the creature toward us and get started. /// Note - we may need to make an NPC class vs monster as using a monster does not make them turn towrad you as I recall. Og II /// Also, once we are reading in the emotes table by weenie - this will automatically customize the behavior for creatures. /// </summary> /// <param name="playerId">Identity of the player we are interacting with</param> public override void HandleActionOnUse(ObjectGuid playerId) { ActionChain chain = new ActionChain(); CurrentLandblock.ChainOnObject(chain, playerId, wo => { Player player = wo as Player; if (player == null) { return; } if (!player.IsWithinUseRadiusOf(this)) { player.DoMoveTo(this); } else { ActionChain turnToChain = new ActionChain(); turnToChain.AddAction(this, () => { OnAutonomousMove(wo.Location, this.Sequences, MovementTypes.TurnToObject, playerId); }); turnToChain.EnqueueChain(); ActionChain doneChain = new ActionChain(); doneChain.AddAction(this, () => { GameEventUseDone sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(sendUseDoneEvent); }); doneChain.EnqueueChain(); } }); chain.EnqueueChain(); }
public override void OnUse(Session session) { ushort origStackSize = (ushort)StackSize; Entity.Player.ConsumableBuffType buffType; if (Food == true) { switch (BoostEnum) { case (uint)Entity.Player.ConsumableBuffType.Health: buffType = Entity.Player.ConsumableBuffType.Health; break; case (uint)Entity.Player.ConsumableBuffType.Mana: buffType = Entity.Player.ConsumableBuffType.Mana; break; default: buffType = Entity.Player.ConsumableBuffType.Stamina; break; } } else { buffType = Entity.Player.ConsumableBuffType.Spell; } session.Player.DoEatOrDrink(Name, FoodOrDrink(Name), buffType, (uint)Boost, SpellDID); session.Player.HandleActionRemoveItemFromInventory(Guid.Full, session.Player.Guid.Full, 1); var sendUseDoneEvent = new GameEventUseDone(session); session.Network.EnqueueSend(sendUseDoneEvent); }
/// <summary> /// One function to handle both Player.OnUse and Landblock.HandleACtionOnUse functions /// </summary> /// <param name="session"></param> private void BookUseHandler(Session session) { uint maxChars = MaxCharactersPerPage ?? 1000; uint maxPages = MaxPages ?? 1; string authorName; if (ScribeName != null) { authorName = ScribeName; } else { authorName = ""; } string authorAccount; if (ScribeAccount != null) { authorAccount = ScribeAccount; } else { authorAccount = ""; } uint authorID = Scribe ?? 0xFFFFFFFF; List <PageData> pageData = new List <PageData>(); foreach (KeyValuePair <uint, AceObjectPropertiesBook> p in PropertiesBook) { PageData newPage = new PageData(); newPage.AuthorID = p.Value.AuthorId; newPage.AuthorName = p.Value.AuthorName; newPage.AuthorAccount = p.Value.AuthorAccount; pageData.Add(newPage); } bool ignoreAuthor = IgnoreAuthor ?? false; string inscription; if (Inscription != null) { inscription = Inscription; } else { inscription = ""; } var bookDataResponse = new GameEventBookDataResponse(session, Guid.Full, maxChars, maxPages, pageData, inscription, authorID, authorName, ignoreAuthor); session.Network.EnqueueSend(bookDataResponse); var sendUseDoneEvent = new GameEventUseDone(session); session.Network.EnqueueSend(sendUseDoneEvent); }
public override void OnCollide(Player player) { // validate within use range :: set to a fixed value as static Portals are normally OnCollide usage float rangeCheck = 5.0f; if (player.Location.SquaredDistanceTo(Location) < rangeCheck) { if (portalDestination != null) { if ((player.Level >= portalMinLvl) && ((player.Level <= portalMaxLvl) || (portalMaxLvl == 0))) { Position portalDest = portalDestination; switch (WeenieClassid) { /// <summary> /// Setup correct racial portal destination for the Central Courtyard in the Training Academy /// </summary> case (ushort)SpecialPortalWCID.CentralCourtyard: { uint playerLandblockId = player.Location.LandblockId.Raw; switch (playerLandblockId) { case (uint)SpecialPortalLandblockID.ShoushiCCLaunch: // Shoushi { portalDest.LandblockId = new LandblockId((uint)SpecialPortalLandblockID.ShoushiCCLanding); break; } case (uint)SpecialPortalLandblockID.YaraqCCLaunch: // Yaraq { portalDest.LandblockId = new LandblockId((uint)SpecialPortalLandblockID.YaraqCCLanding); break; } case (uint)SpecialPortalLandblockID.SanamarCCLaunch: // Sanamar { portalDest.LandblockId = new LandblockId((uint)SpecialPortalLandblockID.SanamarCCLanding); break; } default: // Holtburg { portalDest.LandblockId = new LandblockId((uint)SpecialPortalLandblockID.HoltburgCCLanding); break; } } portalDest.PositionX = portalDestination.PositionX; portalDest.PositionY = portalDestination.PositionY; portalDest.PositionZ = portalDestination.PositionZ; portalDest.RotationX = portalDestination.RotationX; portalDest.RotationY = portalDestination.RotationY; portalDest.RotationZ = portalDestination.RotationZ; portalDest.RotationW = portalDestination.RotationW; break; } /// <summary> /// Setup correct racial portal destination for the Outer Courtyard in the Training Academy /// </summary> case (ushort)SpecialPortalWCID.OuterCourtyard: { uint playerLandblockId = player.Location.LandblockId.Raw; switch (playerLandblockId) { case (uint)SpecialPortalLandblockID.ShoushiOCLaunch: // Shoushi { portalDest.LandblockId = new LandblockId((uint)SpecialPortalLandblockID.ShoushiOCLanding); break; } case (uint)SpecialPortalLandblockID.YaraqOCLaunch: // Yaraq { portalDest.LandblockId = new LandblockId((uint)SpecialPortalLandblockID.YaraqOCLanding); break; } case (uint)SpecialPortalLandblockID.SanamarOCLaunch: // Sanamar { portalDest.LandblockId = new LandblockId((uint)SpecialPortalLandblockID.SanamarOCLanding); break; } default: // Holtburg { portalDest.LandblockId = new LandblockId((uint)SpecialPortalLandblockID.HoltburgOCLanding); break; } } portalDest.PositionX = portalDestination.PositionX; portalDest.PositionY = portalDestination.PositionY; portalDest.PositionZ = portalDestination.PositionZ; portalDest.RotationX = portalDestination.RotationX; portalDest.RotationY = portalDestination.RotationY; portalDest.RotationZ = portalDestination.RotationZ; portalDest.RotationW = portalDestination.RotationW; break; } /// <summary> /// All other portals don't need adjustments. /// </summary> default: { break; } } player.Session.Player.Teleport(portalDest); // If the portal just used is able to be recalled to, // save the destination coordinates to the LastPortal character position save table if (Convert.ToBoolean(portalIsRecallable) == true) { player.SetCharacterPosition(PositionType.LastPortal, portalDest); } // always send useDone event var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(sendUseDoneEvent); } else if ((player.Level > portalMaxLvl) && (portalMaxLvl != 0)) { // You are too powerful to interact with that portal! var usePortalMessage = new GameEventDisplayStatusMessage(player.Session, StatusMessageType1.Enum_04AC); // always send useDone event var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(usePortalMessage, sendUseDoneEvent); } else { // You are not powerful enough to interact with that portal! var usePortalMessage = new GameEventDisplayStatusMessage(player.Session, StatusMessageType1.Enum_04AB); // always send useDone event var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(usePortalMessage, sendUseDoneEvent); } } else { string serverMessage = "Portal destination for portal ID " + this.WeenieClassid + " not yet implemented!"; var usePortalMessage = new GameMessageSystemChat(serverMessage, ChatMessageType.System); // always send useDone event var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(usePortalMessage, sendUseDoneEvent); } } else { // always send useDone event var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(sendUseDoneEvent); } }
private void HandleGameAction(QueuedGameAction action, Player player) { switch (action.ActionType) { case GameActionType.TalkDirect: { // TODO: remove this hack (using TalkDirect) ASAP var g = new ObjectGuid(action.ObjectId); WorldObject obj = (WorldObject)player; if (worldObjects.ContainsKey(g)) { obj = worldObjects[g]; } DeathMessageArgs d = new DeathMessageArgs(action.ActionBroadcastMessage, new ObjectGuid(action.ObjectId), new ObjectGuid(action.SecondaryObjectId)); HandleDeathMessage(obj, d); break; } case GameActionType.TeleToHouse: case GameActionType.TeleToLifestone: case GameActionType.TeleToMansion: case GameActionType.TeleToMarketPlace: case GameActionType.TeleToPkArena: case GameActionType.TeleToPklArena: { player.Teleport(action.ActionLocation); break; } case GameActionType.ApplyVisualEffect: { var g = new ObjectGuid(action.ObjectId); WorldObject obj = (WorldObject)player; if (worldObjects.ContainsKey(g)) { obj = worldObjects[g]; } var particleEffect = (PlayScript)action.SecondaryObjectId; HandleParticleEffectEvent(obj, particleEffect); break; } case GameActionType.ApplySoundEffect: { var g = new ObjectGuid(action.ObjectId); WorldObject obj = (WorldObject)player; if (worldObjects.ContainsKey(g)) { obj = worldObjects[g]; } var soundEffect = (Sound)action.SecondaryObjectId; HandleSoundEvent(obj, soundEffect); break; } case GameActionType.IdentifyObject: { // TODO: Throttle this request. The live servers did this, likely for a very good reason, so we should, too. var g = new ObjectGuid(action.ObjectId); WorldObject obj = (WorldObject)player; if (worldObjects.ContainsKey(g)) { obj = worldObjects[g]; } var identifyResponse = new GameEventIdentifyObjectResponse(player.Session, action.ObjectId, obj); player.Session.Network.EnqueueSend(identifyResponse); break; } case GameActionType.Buy: { // todo: lots, need vendor list, money checks, etc. var money = new GameMessagePrivateUpdatePropertyInt(player.Session, PropertyInt.CoinValue, 4000); var sound = new GameMessageSound(player.Guid, Sound.PickUpItem, 1); var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(money, sound, sendUseDoneEvent); // send updated vendor inventory. player.Session.Network.EnqueueSend(new GameEventApproachVendor(player.Session, action.ObjectId)); // this is just some testing code for now. foreach (ItemProfile item in action.ProfileItems) { // todo: something with vendor id and profile list... iid list from vendor dbs. // todo: something with amounts.. if (item.Iid == 5) { while (item.Amount > 0) { item.Amount--; WorldObject loot = LootGenerationFactory.CreateTestWorldObject(5090); LootGenerationFactory.AddToContainer(loot, player); player.TrackObject(loot); } var rudecomment = "Who do you think you are, Johny Apple Seed ?"; var buyrudemsg = new GameMessageSystemChat(rudecomment, ChatMessageType.Tell); player.Session.Network.EnqueueSend(buyrudemsg); } else if (item.Iid == 10) { while (item.Amount > 0) { item.Amount--; WorldObject loot = LootGenerationFactory.CreateTestWorldObject(30537); LootGenerationFactory.AddToContainer(loot, player); player.TrackObject(loot); } var rudecomment = "That smells awful, Enjoy eating it!"; var buyrudemsg = new GameMessageSystemChat(rudecomment, ChatMessageType.Tell); player.Session.Network.EnqueueSend(buyrudemsg); } } break; } case GameActionType.PutItemInContainer: { var playerGuid = new ObjectGuid(action.ObjectId); var inventoryGuid = new ObjectGuid(action.SecondaryObjectId); // Has to be a player so need to check before I make the cast. // If he is not a player, something is bad wrong. Og II if (playerGuid.IsPlayer()) { var aPlayer = (Player)GetWorldObject(playerGuid); var inventoryItem = GetWorldObject(inventoryGuid); float arrivedRadiusSquared = 0.00f; bool validGuids; if (WithinUseRadius(playerGuid, inventoryGuid, out arrivedRadiusSquared, out validGuids)) { aPlayer.NotifyAndAddToInventory(inventoryItem); } else { if (validGuids) { aPlayer.SetDestinationInformation(inventoryItem.PhysicsData.Position, arrivedRadiusSquared); aPlayer.BlockedGameAction = action; aPlayer.OnAutonomousMove(inventoryItem.PhysicsData.Position, aPlayer.Sequences, MovementTypes.MoveToObject, inventoryGuid); } } } break; } case GameActionType.DropItem: { var g = new ObjectGuid(action.ObjectId); if (worldObjects.ContainsKey(g)) { var playerId = new ObjectGuid(action.ObjectId); var inventoryId = new ObjectGuid(action.SecondaryObjectId); if (playerId.IsPlayer()) { var aPlayer = (Player)worldObjects[playerId]; aPlayer.NotifyAndDropItem(inventoryId); } } break; } case GameActionType.MovementEvent: { var g = new ObjectGuid(action.ObjectId); WorldObject obj = (WorldObject)player; if (worldObjects.ContainsKey(g)) { obj = worldObjects[g]; } var motion = action.Motion; HandleMovementEvent(obj, motion); break; } case GameActionType.ObjectCreate: { AddWorldObject(action.WorldObject); break; } case GameActionType.ObjectDelete: { RemoveWorldObject(action.WorldObject.Guid, false); break; } case GameActionType.QueryHealth: { if (action.ObjectId == 0) { // Deselect the formerly selected Target player.SelectedTarget = 0; break; } object target = null; var targetId = new ObjectGuid(action.ObjectId); // Remember the selected Target player.SelectedTarget = action.ObjectId; // TODO: once items are implemented check if there are items that can trigger // the QueryHealth event. So far I believe it only gets triggered for players and creatures if (targetId.IsPlayer() || targetId.IsCreature()) { if (worldObjects.ContainsKey(targetId)) { target = worldObjects[targetId]; } if (target == null) { // check adjacent landblocks for the targetId foreach (var block in adjacencies) { if (block.Value != null) { if (block.Value.worldObjects.ContainsKey(targetId)) { target = block.Value.worldObjects[targetId]; } } } } if (target != null) { float healthPercentage = 0; if (targetId.IsPlayer()) { Player tmpTarget = (Player)target; healthPercentage = (float)tmpTarget.Health.Current / (float)tmpTarget.Health.MaxValue; } if (targetId.IsCreature()) { Creature tmpTarget = (Creature)target; healthPercentage = (float)tmpTarget.Health.Current / (float)tmpTarget.Health.MaxValue; } var updateHealth = new GameEventUpdateHealth(player.Session, targetId.Full, healthPercentage); player.Session.Network.EnqueueSend(updateHealth); } } break; } case GameActionType.Use: { var g = new ObjectGuid(action.ObjectId); if (worldObjects.ContainsKey(g)) { WorldObject obj = worldObjects[g]; if ((obj.DescriptionFlags & ObjectDescriptionFlag.LifeStone) != 0) { (obj as Lifestone).OnUse(player); } else if ((obj.DescriptionFlags & ObjectDescriptionFlag.Portal) != 0) { // TODO: When Physics collisions are implemented, this logic should be switched there, as normal portals are not onUse. (obj as Portal).OnCollide(player); } else if ((obj.DescriptionFlags & ObjectDescriptionFlag.Door) != 0) { (obj as Door).OnUse(player); } else if ((obj.DescriptionFlags & ObjectDescriptionFlag.Vendor) != 0) { (obj as Vendor).OnUse(player); } // switch (obj.Type) // { // case Enum.ObjectType.Portal: // { // // TODO: When Physics collisions are implemented, this logic should be switched there, as normal portals are not onUse. // // (obj as Portal).OnCollide(player); // // break; // } // case Enum.ObjectType.LifeStone: // { // (obj as Lifestone).OnUse(player); // break; // } // } } break; } } }
private void HandleGameAction(QueuedGameAction action, Player player) { switch (action.ActionType) { case GameActionType.TalkDirect: { // TODO: remove this hack (using TalkDirect) ASAP var g = new ObjectGuid(action.ObjectId); WorldObject obj = (WorldObject)player; if (worldObjects.ContainsKey(g)) { obj = worldObjects[g]; } DeathMessageArgs d = new DeathMessageArgs(action.ActionBroadcastMessage, new ObjectGuid(action.ObjectId), new ObjectGuid(action.SecondaryObjectId)); HandleDeathMessage(obj, d); break; } case GameActionType.TeleToHouse: case GameActionType.TeleToLifestone: case GameActionType.TeleToMansion: case GameActionType.TeleToMarketPlace: case GameActionType.TeleToPkArena: case GameActionType.TeleToPklArena: { player.Teleport(action.ActionLocation); break; } case GameActionType.ApplyVisualEffect: { var g = new ObjectGuid(action.ObjectId); WorldObject obj = (WorldObject)player; if (worldObjects.ContainsKey(g)) { obj = worldObjects[g]; } var particleEffect = (PlayScript)action.SecondaryObjectId; HandleParticleEffectEvent(obj, particleEffect); break; } case GameActionType.ApplySoundEffect: { var g = new ObjectGuid(action.ObjectId); WorldObject obj = (WorldObject)player; if (worldObjects.ContainsKey(g)) { obj = worldObjects[g]; } var soundEffect = (Sound)action.SecondaryObjectId; HandleSoundEvent(obj, soundEffect); break; } case GameActionType.PutItemInContainer: { var playerId = new ObjectGuid(action.ObjectId); var inventoryId = new ObjectGuid(action.SecondaryObjectId); if (playerId.IsPlayer()) { Player aPlayer = null; WorldObject inventoryItem = null; if (worldObjects.ContainsKey(playerId) && worldObjects.ContainsKey(inventoryId)) { aPlayer = (Player)worldObjects[playerId]; inventoryItem = worldObjects[inventoryId]; } if ((aPlayer != null) && (inventoryItem != null)) { var motion = new GeneralMotion(MotionStance.Standing); motion.MovementData.ForwardCommand = (ushort)MotionCommand.Pickup; aPlayer.Session.Network.EnqueueSend(new GameMessageUpdatePosition(aPlayer), new GameMessageUpdateMotion(aPlayer, aPlayer.Session, motion), new GameMessageSound(aPlayer.Guid, Sound.PickUpItem, (float)1.0)); // Add to the inventory list. aPlayer.AddToInventory(inventoryItem); LandblockManager.RemoveObject(inventoryItem); motion = new GeneralMotion(MotionStance.Standing); aPlayer.Session.Network.EnqueueSend(new GameMessagePrivateUpdatePropertyInt(aPlayer.Session, PropertyInt.EncumbVal, aPlayer.GameData.Burden), new GameMessagePutObjectInContainer(aPlayer.Session, aPlayer, inventoryId), new GameMessageUpdateMotion(aPlayer, aPlayer.Session, motion), new GameMessageUpdateInstanceId(inventoryId, playerId), new GameMessagePickupEvent(aPlayer.Session, inventoryItem)); aPlayer.TrackObject(inventoryItem); } } break; } case GameActionType.DropItem: { var g = new ObjectGuid(action.ObjectId); // ReSharper disable once InconsistentlySynchronizedField if (worldObjects.ContainsKey(g)) { var playerId = new ObjectGuid(action.ObjectId); var inventoryId = new ObjectGuid(action.SecondaryObjectId); if (playerId.IsPlayer()) { Player aPlayer = null; WorldObject inventoryItem = null; if (worldObjects.ContainsKey(playerId)) { aPlayer = (Player)worldObjects[playerId]; inventoryItem = aPlayer.GetInventoryItem(inventoryId); aPlayer.RemoveFromInventory(inventoryId); } if ((aPlayer != null) && (inventoryItem != null)) { var targetContainer = new ObjectGuid(0); aPlayer.Session.Network.EnqueueSend( new GameMessagePrivateUpdatePropertyInt( aPlayer.Session, PropertyInt.EncumbVal, (uint)aPlayer.Session.Player.GameData.Burden)); var motion = new GeneralMotion(MotionStance.Standing); motion.MovementData.ForwardCommand = (ushort)MotionCommand.Pickup; aPlayer.Session.Network.EnqueueSend( new GameMessageUpdateMotion(aPlayer, aPlayer.Session, motion), new GameMessageUpdateInstanceId(inventoryId, targetContainer)); motion = new GeneralMotion(MotionStance.Standing); aPlayer.Session.Network.EnqueueSend( new GameMessageUpdateMotion(aPlayer, aPlayer.Session, motion), new GameMessagePutObjectIn3d(aPlayer.Session, aPlayer, inventoryId), new GameMessageSound(aPlayer.Guid, Sound.DropItem, (float)1.0), new GameMessageUpdateInstanceId(inventoryId, targetContainer)); // This is the sequence magic - adds back into 3d space seem to be treated like teleport. inventoryItem.Sequences.GetNextSequence(SequenceType.ObjectTeleport); inventoryItem.Sequences.GetNextSequence(SequenceType.ObjectVector); LandblockManager.AddObject(inventoryItem); aPlayer.Session.Network.EnqueueSend(new GameMessageUpdatePosition(inventoryItem)); } } } break; } case GameActionType.MovementEvent: { var g = new ObjectGuid(action.ObjectId); WorldObject obj = (WorldObject)player; if (worldObjects.ContainsKey(g)) { obj = worldObjects[g]; } var motion = action.Motion; HandleMovementEvent(obj, motion); break; } case GameActionType.ObjectCreate: { this.AddWorldObject(action.WorldObject); break; } case GameActionType.ObjectDelete: { this.RemoveWorldObject(action.WorldObject.Guid, false); break; } case GameActionType.QueryHealth: { if (action.ObjectId == 0) { // Deselect the formerly selected Target player.SelectedTarget = 0; break; } object target = null; var targetId = new ObjectGuid(action.ObjectId); // Remember the selected Target player.SelectedTarget = action.ObjectId; // TODO: once items are implemented check if there are items that can trigger // the QueryHealth event. So far I believe it only gets triggered for players and creatures if (targetId.IsPlayer() || targetId.IsCreature()) { if (this.worldObjects.ContainsKey(targetId)) { target = this.worldObjects[targetId]; } if (target == null) { // check adjacent landblocks for the targetId foreach (var block in adjacencies) { if (block.Value != null) { if (block.Value.worldObjects.ContainsKey(targetId)) { target = block.Value.worldObjects[targetId]; } } } } if (target != null) { float healthPercentage = 0; if (targetId.IsPlayer()) { Player tmpTarget = (Player)target; healthPercentage = (float)tmpTarget.Health.Current / (float)tmpTarget.Health.MaxValue; } if (targetId.IsCreature()) { Creature tmpTarget = (Creature)target; healthPercentage = (float)tmpTarget.Health.Current / (float)tmpTarget.Health.MaxValue; } var updateHealth = new GameEventUpdateHealth(player.Session, targetId.Full, healthPercentage); player.Session.Network.EnqueueSend(updateHealth); } } break; } case GameActionType.Use: { var g = new ObjectGuid(action.ObjectId); if (worldObjects.ContainsKey(g)) { WorldObject obj = worldObjects[g]; switch (obj.Type) { case Enum.ObjectType.Portal: { // validate within use range :: set to a fixed value as static Portals are normally OnCollide usage float rangeCheck = 5.0f; if (player.Location.SquaredDistanceTo(obj.Location) < rangeCheck) { PortalDestination portalDestination = DatabaseManager.World.GetPortalDestination(obj.WeenieClassid); if (portalDestination != null) { player.Session.Player.Teleport(portalDestination.Position); // always send useDone event var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(sendUseDoneEvent); } else { string serverMessage = "Portal destination for portal ID " + obj.WeenieClassid + " not yet implemented!"; var usePortalMessage = new GameMessageSystemChat(serverMessage, ChatMessageType.System); // always send useDone event var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(usePortalMessage, sendUseDoneEvent); } } else { // always send useDone event var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(sendUseDoneEvent); } break; } case Enum.ObjectType.LifeStone: { string serverMessage = null; // validate within use range float radiusSquared = obj.GameData.UseRadius * obj.GameData.UseRadius; var motionSanctuary = new GeneralMotion(MotionStance.Standing, new MotionItem(MotionCommand.Sanctuary)); var animationEvent = new GameMessageUpdateMotion(player, player.Session, motionSanctuary); // This event was present for a pcap in the training dungeon.. Why? The sound comes with animationEvent... var soundEvent = new GameMessageSound(obj.Guid, Sound.LifestoneOn, 1); if (player.Location.SquaredDistanceTo(obj.Location) >= radiusSquared) { serverMessage = "You wandered too far to attune with the Lifestone!"; } else { player.SetCharacterPosition(PositionType.Sanctuary, player.Location); // create the outbound server message serverMessage = "You have attuned your spirit to this Lifestone. You will resurrect here after you die."; player.EnqueueMovementEvent(motionSanctuary, player.Guid); player.Session.Network.EnqueueSend(soundEvent); } var lifestoneBindMessage = new GameMessageSystemChat(serverMessage, ChatMessageType.Magic); // always send useDone event var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(lifestoneBindMessage, sendUseDoneEvent); break; } } } break; } } }
public override void OnUse(Session session) { bool success = true; string failReason = "You are unable to read the scroll."; switch (Power) { // research: http://asheron.wikia.com/wiki/Announcements_-_2002/06_-_Castling case spellLevel2: // Level 2 case spellLevel3: // Level 3 case spellLevel4: // Level 4 case spellLevel5: // Level 5 case spellLevel6: // Level 6 if (session.Player.CanReadScroll(School, Power)) { success = true; } else { success = false; failReason = "You are not skilled enough in the inscribed spell's school of magic to understand the writing on this scroll."; } break; default: // Level 1 or Level 7+ never fail success = true; break; } if (!session.Player.UnknownSpell(SpellId)) { success = false; failReason = "You already know the spell inscribed upon this scroll."; } ActionChain readScrollChain = new ActionChain(); readScrollChain.AddAction(session.Player, () => session.Player.HandleActionMotion(motionReading)); readScrollChain.AddDelaySeconds(2); if (success) { readScrollChain.AddAction(session.Player, () => session.Player.LearnSpell(SpellId)); readScrollChain.AddAction(session.Player, () => session.Player.HandleActionMotion(motionReady)); var removeObjMessage = new GameMessageRemoveObject(this); var destroyMessage = new GameMessageSystemChat("The scroll is destroyed.", ChatMessageType.Magic); readScrollChain.AddAction(session.Player, () => session.Network.EnqueueSend(destroyMessage, removeObjMessage)); readScrollChain.AddAction(session.Player, () => session.Player.RemoveWorldObjectFromInventory(Guid)); } else { readScrollChain.AddDelaySeconds(2); readScrollChain.AddAction(session.Player, () => session.Player.HandleActionMotion(motionReady)); var failMessage = new GameMessageSystemChat($"{failReason}", ChatMessageType.Magic); readScrollChain.AddAction(session.Player, () => session.Network.EnqueueSend(failMessage)); } var sendUseDoneEvent = new GameEventUseDone(session.Player.Session); readScrollChain.AddAction(session.Player, () => session.Network.EnqueueSend(sendUseDoneEvent)); readScrollChain.EnqueueChain(); }
/// <summary> /// One function to handle both Player.OnUse and Landblock.HandleACtionOnUse functions /// </summary> /// <param name="session"></param> private void BookUseHandler(Session session) { int maxChars = Biota.BiotaPropertiesBook.MaxNumCharsPerPage; int maxPages = Biota.BiotaPropertiesBook.MaxNumPages; string authorName; if (ScribeName != null) { authorName = ScribeName; } else { authorName = ""; } string authorAccount; if (ScribeAccount != null) { authorAccount = ScribeAccount; } else { authorAccount = ""; } //uint authorID = ScribeIID ?? 0xFFFFFFFF; uint authorID = (ScribeIID.HasValue) ? (uint)ScribeIID : 0xFFFFFFFF; List <PageData> pageData = new List <PageData>(); foreach (var p in Biota.BiotaPropertiesBookPageData) { PageData newPage = new PageData(); newPage.AuthorID = p.AuthorId; newPage.AuthorName = p.AuthorName; newPage.AuthorAccount = p.AuthorAccount; newPage.PageText = p.PageText; newPage.IgnoreAuthor = p.IgnoreAuthor; pageData.Add(newPage); } bool ignoreAuthor = IgnoreAuthor ?? false; string inscription; if (Inscription != null) { inscription = Inscription; } else { inscription = ""; } var bookDataResponse = new GameEventBookDataResponse(session, Guid.Full, maxChars, maxPages, pageData, inscription, authorID, authorName, ignoreAuthor); session.Network.EnqueueSend(bookDataResponse); var sendUseDoneEvent = new GameEventUseDone(session); session.Network.EnqueueSend(sendUseDoneEvent); }
public void HandleActionUseOnTarget(Player player, WorldObject target) { ActionChain chain = new ActionChain(); chain.AddAction(player, () => { if (player == null) { return; } if (!player.IsWithinUseRadiusOf(target)) { player.DoMoveTo(target); } else { var sendUseDoneEvent = new GameEventUseDone(player.Session); if (target.WeenieType == WeenieType.Door) { Door door = target as Door; Door.UnlockDoorResults results = door.UnlockDoor(KeyCode); switch (results) { case Entity.Door.UnlockDoorResults.UnlockSuccess: Structure--; if (Structure < 1) { // Remove item from players player.DestroyInventoryItem(this); // Clean up the shard database. DatabaseManager.Shard.DeleteObject(SnapShotOfAceObject(), null); } player.Session.Network.EnqueueSend(sendUseDoneEvent); player.Session.Network.EnqueueSend(new GameMessagePublicUpdatePropertyInt(this.Sequences, Guid, PropertyInt.Structure, (uint)Structure)); break; case Entity.Door.UnlockDoorResults.DoorOpen: var messageDoorOpen = new GameEventDisplayStatusMessage(player.Session, StatusMessageType1.Enum_0481); // TODO: Messages are not quiet right. Need to find right one. player.Session.Network.EnqueueSend(sendUseDoneEvent, messageDoorOpen); break; case Entity.Door.UnlockDoorResults.AlreadyUnlocked: var messageAlreadyUnlocked = new GameEventDisplayStatusMessage(player.Session, StatusMessageType1.Enum_04B2); // TODO: Messages are not quiet right. Need to find right one. player.Session.Network.EnqueueSend(sendUseDoneEvent, messageAlreadyUnlocked); break; default: var messageIncorrectKey = new GameEventDisplayStatusMessage(player.Session, StatusMessageType1.Enum_04B2); player.Session.Network.EnqueueSend(sendUseDoneEvent, messageIncorrectKey); break; } } else if (target.WeenieType == WeenieType.Chest) { var message = new GameMessageSystemChat($"Unlocking {target.Name} has not been implemented, yet!", ChatMessageType.System); player.Session.Network.EnqueueSend(sendUseDoneEvent, message); } else { var message = new GameEventDisplayStatusMessage(player.Session, StatusMessageType1.Enum_0480); player.Session.Network.EnqueueSend(sendUseDoneEvent, message); } } }); chain.EnqueueChain(); }
public void HandleActionUseOnTarget(Player player, WorldObject target) { ActionChain chain = new ActionChain(); var keyCode = GetProperty(PropertyString.KeyCode); chain.AddAction(player, () => { if (player == null) { return; } if (!player.IsWithinUseRadiusOf(target)) { player.DoMoveTo(target); } else { var sendUseDoneEvent = new GameEventUseDone(player.Session); if (target.WeenieType == WeenieType.Door) { Door door = target as Door; Door.UnlockDoorResults results = door.UnlockDoor(keyCode); switch (results) { case WorldObjects.Door.UnlockDoorResults.UnlockSuccess: Structure--; if (Structure < 1) { player.RemoveItemFromInventory(Guid.Full, player.Guid.Full, 1); } player.Session.Network.EnqueueSend(sendUseDoneEvent); player.Session.Network.EnqueueSend(new GameMessagePublicUpdatePropertyInt(Sequences, Guid, PropertyInt.Structure, (int)Structure)); break; case WorldObjects.Door.UnlockDoorResults.DoorOpen: var messageDoorOpen = new GameEventDisplayStatusMessage(player.Session, StatusMessageType1.YouCannotLockWhatIsOpen); // TODO: Messages are not quiet right. Need to find right one. player.Session.Network.EnqueueSend(sendUseDoneEvent, messageDoorOpen); break; case WorldObjects.Door.UnlockDoorResults.AlreadyUnlocked: var messageAlreadyUnlocked = new GameEventDisplayStatusMessage(player.Session, StatusMessageType1.KeyDoesntFitThisLock); // TODO: Messages are not quiet right. Need to find right one. player.Session.Network.EnqueueSend(sendUseDoneEvent, messageAlreadyUnlocked); break; default: var messageIncorrectKey = new GameEventDisplayStatusMessage(player.Session, StatusMessageType1.KeyDoesntFitThisLock); player.Session.Network.EnqueueSend(sendUseDoneEvent, messageIncorrectKey); break; } } else if (target.WeenieType == WeenieType.Chest) { var message = new GameMessageSystemChat($"Unlocking {target.Name} has not been implemented, yet!", ChatMessageType.System); player.Session.Network.EnqueueSend(sendUseDoneEvent, message); } else { var message = new GameEventDisplayStatusMessage(player.Session, StatusMessageType1.YouCannotLockOrUnlockThat); player.Session.Network.EnqueueSend(sendUseDoneEvent, message); } } }); chain.EnqueueChain(); }
public override void HandleActionOnUse(ObjectGuid playerId) { string serverMessage; // validate within use range :: set to a fixed value as static Portals are normally OnCollide usage var rangeCheck = 5.0f; ActionChain chain = new ActionChain(); CurrentLandblock.ChainOnObject(chain, playerId, (WorldObject wo) => { Player player = wo as Player; if (player == null) { return; } // Can check location by guid // NOTE: Must use CurrentLandblock.GetPosition() for the portal's position... if (CurrentLandblock.GetPosition(Guid).SquaredDistanceTo(player.Location) < rangeCheck) { if (Destination != null) { #if DEBUG serverMessage = "Checking requirements for " + this.Name; var usePortalMessage = new GameMessageSystemChat(serverMessage, ChatMessageType.System); player.Session.Network.EnqueueSend(usePortalMessage); #endif // Check player level -- requires remote query to player (ugh)... if ((player.Level >= MinimumLevel) && ((player.Level <= MaximumLevel) || (MaximumLevel == 0))) { Position portalDest = Destination; switch (WeenieClassId) { /// <summary> /// Setup correct racial portal destination for the Central Courtyard in the Training Academy /// </summary> case (ushort)SpecialPortalWCID.CentralCourtyard: { uint playerLandblockId = player.Location.LandblockId.Raw; switch (playerLandblockId) { case (uint)SpecialPortalLandblockID.ShoushiCCLaunch: // Shoushi { portalDest.LandblockId = new LandblockId((uint)SpecialPortalLandblockID.ShoushiCCLanding); break; } case (uint)SpecialPortalLandblockID.YaraqCCLaunch: // Yaraq { portalDest.LandblockId = new LandblockId((uint)SpecialPortalLandblockID.YaraqCCLanding); break; } case (uint)SpecialPortalLandblockID.SanamarCCLaunch: // Sanamar { portalDest.LandblockId = new LandblockId((uint)SpecialPortalLandblockID.SanamarCCLanding); break; } default: // Holtburg { portalDest.LandblockId = new LandblockId((uint)SpecialPortalLandblockID.HoltburgCCLanding); break; } } portalDest.PositionX = Destination.PositionX; portalDest.PositionY = Destination.PositionY; portalDest.PositionZ = Destination.PositionZ; portalDest.RotationX = Destination.RotationX; portalDest.RotationY = Destination.RotationY; portalDest.RotationZ = Destination.RotationZ; portalDest.RotationW = Destination.RotationW; break; } /// <summary> /// Setup correct racial portal destination for the Outer Courtyard in the Training Academy /// </summary> case (ushort)SpecialPortalWCID.OuterCourtyard: { uint playerLandblockId = player.Location.LandblockId.Raw; switch (playerLandblockId) { case (uint)SpecialPortalLandblockID.ShoushiOCLaunch: // Shoushi { portalDest.LandblockId = new LandblockId((uint)SpecialPortalLandblockID.ShoushiOCLanding); break; } case (uint)SpecialPortalLandblockID.YaraqOCLaunch: // Yaraq { portalDest.LandblockId = new LandblockId((uint)SpecialPortalLandblockID.YaraqOCLanding); break; } case (uint)SpecialPortalLandblockID.SanamarOCLaunch: // Sanamar { portalDest.LandblockId = new LandblockId((uint)SpecialPortalLandblockID.SanamarOCLanding); break; } default: // Holtburg { portalDest.LandblockId = new LandblockId((uint)SpecialPortalLandblockID.HoltburgOCLanding); break; } } portalDest.PositionX = Destination.PositionX; portalDest.PositionY = Destination.PositionY; portalDest.PositionZ = Destination.PositionZ; portalDest.RotationX = Destination.RotationX; portalDest.RotationY = Destination.RotationY; portalDest.RotationZ = Destination.RotationZ; portalDest.RotationW = Destination.RotationW; break; } /// <summary> /// All other portals don't need adjustments. /// </summary> default: { break; } } #if DEBUG serverMessage = "Portal sending player to destination"; usePortalMessage = new GameMessageSystemChat(serverMessage, ChatMessageType.System); player.Session.Network.EnqueueSend(usePortalMessage); #endif player.Session.Player.Teleport(portalDest); // If the portal just used is able to be recalled to, // save the destination coordinates to the LastPortal character position save table if (IsRecallable) { player.SetCharacterPosition(PositionType.LastPortal, portalDest); } // always send useDone event var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(sendUseDoneEvent); } else if ((player.Level > MaximumLevel) && (MaximumLevel != 0)) { // You are too powerful to interact with that portal! var failedUsePortalMessage = new GameEventDisplayStatusMessage(player.Session, StatusMessageType1.Enum_04AC); // always send useDone event var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(failedUsePortalMessage, sendUseDoneEvent); } else { // You are not powerful enough to interact with that portal! var failedUsePortalMessage = new GameEventDisplayStatusMessage(player.Session, StatusMessageType1.Enum_04AB); // always send useDone event var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(failedUsePortalMessage, sendUseDoneEvent); } } else { serverMessage = "Portal destination for portal ID " + this.WeenieClassId + " not yet implemented!"; var failedUsePortalMessage = new GameMessageSystemChat(serverMessage, ChatMessageType.System); // always send useDone event var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(failedUsePortalMessage, sendUseDoneEvent); } } else { // always send useDone event var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(sendUseDoneEvent); } }); // Run on the player chain.EnqueueChain(); }