コード例 #1
0
        public void MoveCharacter(IClientConnection clientConnection, MovementDirection direction)
        {
            if (clientConnection.Character.State != CharacterState.Normal)
            {
                return;
            }

            var oldLocation = clientConnection.Location;

            string newXyz;

            switch (direction)
            {
            case MovementDirection.North when oldLocation.Exits.Contains(MovementDirection.North):
                newXyz = $"{oldLocation.XCoord},{oldLocation.YCoord - 1},{oldLocation.ZCoord}";

                break;

            case MovementDirection.East when oldLocation.Exits.Contains(MovementDirection.East):
                newXyz = $"{oldLocation.XCoord + 1},{oldLocation.YCoord},{oldLocation.ZCoord}";

                break;

            case MovementDirection.South when oldLocation.Exits.Contains(MovementDirection.South):
                newXyz = $"{oldLocation.XCoord},{oldLocation.YCoord + 1},{oldLocation.ZCoord}";

                break;

            case MovementDirection.West when oldLocation.Exits.Contains(MovementDirection.West):
                newXyz = $"{oldLocation.XCoord - 1},{oldLocation.YCoord},{oldLocation.ZCoord}";

                break;

            default:
                clientConnection.InvokeMessageReceived(new LocalEventMessage("There is no exit in that direction."));
                return;
            }


            if (!_world.Locations.TryGet(newXyz, out var newLocation))
            {
                newLocation = GetRandomLocation(newXyz);
                _world.Locations.AddOrUpdate(newLocation.XYZ, newLocation);
            }
            else
            {
                AddLogicalExits(newLocation.Exits, _world, newXyz);
            }

            oldLocation.LastAccessed = DateTimeOffset.Now;
            newLocation.LastAccessed = DateTimeOffset.Now;
            oldLocation.RemoveCharacter(clientConnection.Character);
            newLocation.AddCharacter(clientConnection.Character);
            clientConnection.Location = newLocation;
            clientConnection.Character.Stats.FarthestDistanceTravelled = (long)Calculator.GetDistanceBetween(0, 0, newLocation.XCoord, newLocation.YCoord);

            _clientManager.SendToOtherLocals(clientConnection, oldLocation,
                                             new LocalEventMessage($"{clientConnection.Character.Name} left to the {direction}."));

            _clientManager.SendToOtherLocals(clientConnection, newLocation,
                                             new LocalEventMessage($"{clientConnection.Character.Name} entered from the {GetOppositeDirection(direction)}."));
            clientConnection.InvokeMessageReceived(MessageBase.LocationChanged);

            if (!newLocation.NpcsAlive.Any(x => x.AggressionModel > AggressionModel.OnAttacked))
            {
                _encounterService.SpawnNpcs(clientConnection, TimeSpan.FromSeconds(3), 1);
            }

            // If character is party leader, have members follow.
            if (clientConnection.Character?.Party is Party party &&
                party.Leader == clientConnection.Character)
            {
                var membersNearby = oldLocation.PlayersAlive
                                    .Except(new[] { clientConnection.Character })
                                    .Where(x => party.Members.Contains(x));

                foreach (var member in membersNearby)
                {
                    if (member.Settings.AutoFollowPartyLeader)
                    {
                        MoveCharacter(_clientManager.FindConnection(member), direction);
                    }
                }
            }
        }