/// <summary> /// Handles the contents of a network message. /// </summary> /// <param name="message">The message to handle.</param> /// <param name="connection">A reference to the connection from where this message is comming from, for context.</param> /// <returns>A collection of <see cref="IResponsePacket"/>s that compose that synchronous response, if any.</returns> public override IEnumerable <IResponsePacket> HandleRequest(INetworkMessage message, IConnection connection) { var itemUseInfo = message.ReadItemUseInfo(); if (!(this.Context.CreatureFinder.FindCreatureById(connection.PlayerId) is IPlayer player)) { return(null); } // Before actually using the item, check if we're close enough to use it. if (itemUseInfo.FromLocation.Type == LocationType.Map) { // Turn to the item if it's not exactly the location. if (player.Location != itemUseInfo.FromLocation) { var directionToThing = player.Location.DirectionTo(itemUseInfo.FromLocation); this.ScheduleNewOperation( this.Context.OperationFactory.Create( OperationType.Turn, new TurnToDirectionOperationCreationArguments(player, directionToThing))); } var locationDiff = itemUseInfo.FromLocation - player.Location; if (locationDiff.Z != 0) { // it's on a different floor... return(new TextMessagePacket(MessageType.StatusSmall, "There is no way.").YieldSingleItem()); } } return(this.UseItemAt(player, itemUseInfo.ItemClientId, itemUseInfo.FromLocation, itemUseInfo.Index)); }
/// <summary> /// Handles the contents of a network message. /// </summary> /// <param name="message">The message to handle.</param> /// <param name="connection">A reference to the connection from where this message is comming from, for context.</param> /// <returns>A value tuple with a value indicating whether the handler intends to respond, and a collection of <see cref="IOutgoingPacket"/>s that compose that response.</returns> public override (bool IntendsToRespond, IEnumerable <IOutgoingPacket> ResponsePackets) HandleRequest(INetworkMessage message, IConnection connection) { var itemUseInfo = message.ReadItemUseInfo(); var responsePackets = new List <IOutgoingPacket>(); if (!(this.CreatureFinder.FindCreatureById(connection.PlayerId) is IPlayer player)) { return(false, null); } // player.ClearPendingActions(); // Before actually using the item, check if we're close enough to use it. if (itemUseInfo.FromLocation.Type == LocationType.Map) { // Turn to the item if it's not exactly the location. if (player.Location != itemUseInfo.FromLocation) { var directionToThing = player.Location.DirectionTo(itemUseInfo.FromLocation); this.Game.PlayerRequest_TurnToDirection(player, directionToThing); } var locationDiff = itemUseInfo.FromLocation - player.Location; if (locationDiff.Z != 0) { // it's on a different floor... responsePackets.Add(new TextMessagePacket(MessageType.StatusSmall, "There is no way.")); } else if (locationDiff.MaxValueIn2D > 1) { // Too far away to move it. //var directions = this.Game.Pathfind(player.Location, itemMoveInfo.FromLocation, out Location retryLoc).ToArray(); //player.SetPendingAction(new MoveItemPlayerAction(player, itemMoveInfo, retryLoc)); //if (directions.Length > 0) //{ // player.AutoWalk(directions); //} //else // we found no way... //{ // responsePackets.Add(new TextMessagePacket(MessageType.StatusSmall, "There is no way.")); //} responsePackets.Add(new TextMessagePacket(MessageType.StatusSmall, "Too far away, auto walk is not implemented yet.")); } } if (!responsePackets.Any() && !this.Game.PlayerRequest_UseItem(player, itemUseInfo.ItemClientId, itemUseInfo.FromLocation, itemUseInfo.FromStackPos, itemUseInfo.Index)) { responsePackets.Add(new TextMessagePacket(MessageType.StatusSmall, "Sorry, not possible.")); } return(responsePackets.Any(), responsePackets); }