/// <inheritdoc/>
        public void RemoveObject(ILocateable obj)
        {
            if (obj is IHasBucketInformation bucketInfo)
            {
                bucketInfo.CurrentBucket = null;
            }

            if (!this.Map[obj.X, obj.Y].Remove(obj))
            {
                return;
            }

            if (obj is IBucketMapObserver observingPlayer)
            {
                foreach (var bucket in observingPlayer.ObservingBuckets)
                {
                    bucket.ItemAdded   -= observingPlayer.LocateableAdded;
                    bucket.ItemRemoved -= observingPlayer.LocateableRemoved;
                }

                // TODO: Check if this is really neccessary. It may be that the client automatically removes all objects when you change a map or go back to character select
                if (observingPlayer.ObservingBuckets.Any(b => b.Count > 0))
                {
                    observingPlayer.LocateablesOutOfScope(observingPlayer.ObservingBuckets.SelectMany(o => o));
                }

                observingPlayer.ObservingBuckets.Clear();
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Adds the locateable to the map.
        /// </summary>
        /// <param name="locateable">The locateable object.</param>
        public void Add(ILocateable locateable)
        {
            switch (locateable)
            {
            case DroppedItem droppedItem:
                droppedItem.Id = (ushort)this.dropIdGenerator.GetId();
                Log.DebugFormat("{0}: Added drop {1}, {2}", this.Definition, droppedItem.Id, droppedItem.Item);
                break;

            case Player player:
                player.Id = (ushort)this.objectIdGenerator.GetId();
                Log.DebugFormat("{0}: Added player {1}, {2}, ", this.Definition, player.Id, player);
                Interlocked.Increment(ref this.playerCount);
                break;

            case NonPlayerCharacter npc:
                npc.Id = (ushort)this.objectIdGenerator.GetId();
                Log.DebugFormat("{0}: Added npc {1}, {2}", this.Definition, npc.Id, npc.Definition.Designation);
                break;

            case ISupportIdUpdate idUpdate:
                idUpdate.Id = (ushort)this.objectIdGenerator.GetId();
                Log.DebugFormat("{0}: Added {1}", this.Definition, locateable);
                break;

            default:
                throw new ArgumentException($"Adding an object of type {locateable.GetType()} is not supported.");
            }

            this.objectsInMap.Add(locateable.Id, locateable);
            this.areaOfInterestManager.AddObject(locateable);
            this.ObjectAdded?.Invoke(this, new GameMapEventArgs(this, locateable));
        }
Esempio n. 3
0
        /// <summary>
        /// Adds the locateable to the map.
        /// </summary>
        /// <param name="locateable">The locateable object.</param>
        public void Add(ILocateable locateable)
        {
            switch (locateable)
            {
            case DroppedItem droppedItem:
                droppedItem.Id = (ushort)this.dropIdGenerator.GetId();
                break;

            case DroppedMoney droppedMoney:
                droppedMoney.Id = (ushort)this.dropIdGenerator.GetId();
                break;

            case Player player:
                player.Id = (ushort)this.objectIdGenerator.GetId();
                Interlocked.Increment(ref this.playerCount);
                break;

            case NonPlayerCharacter npc:
                npc.Id = (ushort)this.objectIdGenerator.GetId();
                break;

            case ISupportIdUpdate idUpdate:
                idUpdate.Id = (ushort)this.objectIdGenerator.GetId();
                break;

            default:
                throw new ArgumentException($"Adding an object of type {locateable.GetType()} is not supported.");
            }

            this.objectsInMap.Add(locateable.Id, locateable);
            this.areaOfInterestManager.AddObject(locateable);
            this.ObjectAdded?.Invoke(this, new GameMapEventArgs(this, locateable));
        }
Esempio n. 4
0
        /// <inheritdoc/>
        public void ObjectMoved(ILocateable obj, MoveType type)
        {
            if (type == MoveType.Instant)
            {
                this.connection.Send(new byte[] { 0xC1, 0x08, (byte)PacketType.Teleport, obj.Id.GetHighByte(), obj.Id.GetLowByte(), obj.X, obj.Y, 0 });
            }
            else
            {
                IList <Direction> steps = null;
                var supportWalk         = obj as ISupportWalk;
                if (supportWalk != null)
                {
                    steps = supportWalk.NextDirections.Select(d => d.Direction).ToList();
                }

                var    stepsSize  = (steps?.Count / 2) + 1 ?? 1;
                byte[] walkPacket = new byte[7 + stepsSize];
                walkPacket.SetValues <byte>(0xC1, (byte)walkPacket.Length, (byte)PacketType.Walk, obj.Id.GetHighByte(), obj.Id.GetLowByte(), supportWalk?.WalkTarget.X ?? obj.X, supportWalk?.WalkTarget.Y ?? obj.Y);
                if (steps != null)
                {
                    for (int step = 0; step < steps.Count; step += 2)
                    {
                        var index      = 7 + (step / 2);
                        var firstStep  = steps[step];
                        var secondStep = steps.Count > step + 2 ? steps[step + 2] : Direction.Undefined;
                        walkPacket[index] = (byte)((int)firstStep << 4 | (int)secondStep);
                    }
                }

                this.connection.Send(walkPacket);
            }
        }
        /// <inheritdoc/>
        public void ObjectMoved(ILocateable movedObject, MoveType moveType)
        {
            Point  targetPoint = movedObject.Position;
            object steps       = null;
            int    walkDelay   = 0;

            if (movedObject is ISupportWalk walker && moveType == MoveType.Walk)
            {
                targetPoint = walker.WalkTarget;
                walkDelay   = (int)walker.StepDelay.TotalMilliseconds;
                Span <WalkingStep> walkingSteps = new WalkingStep[16];
                var stepCount = walker.GetSteps(walkingSteps);
                var walkSteps = walkingSteps.Slice(0, stepCount).ToArray().Select(step => new { x = step.To.X, y = step.To.Y, direction = step.Direction }).ToList();

                var lastStep = walkSteps.LastOrDefault();
                if (lastStep != null)
                {
                    var lastPoint     = new Point(lastStep.x, lastStep.y);
                    var lastDirection = lastPoint.GetDirectionTo(targetPoint);
                    if (lastDirection != Direction.Undefined)
                    {
                        walkSteps.Add(new { x = targetPoint.X, y = targetPoint.Y, direction = lastDirection });
                    }
                }

                steps = walkSteps;
            }

            this.clientProxy.SendAsync("ObjectMoved", movedObject.Id, targetPoint.X, targetPoint.Y, moveType, walkDelay, steps);
        }
Esempio n. 6
0
 /// <summary>
 /// Gets the distance to the specified coordinates.
 /// </summary>
 /// <param name="objectFrom">The object from which the distance is calculated.</param>
 /// <param name="x">The x coordinate of the point to which the distance is calculated.</param>
 /// <param name="y">The y coordinate of the point to which the distance is calculated.</param>
 /// <returns>The distance between this and the specified coordinates.</returns>
 public static double GetDistanceTo(this ILocateable objectFrom, byte x, byte y)
 {
     return
         (Math.Sqrt(
              Math.Pow(objectFrom.X - x, 2) +
              Math.Pow(objectFrom.Y - y, 2)));
 }
Esempio n. 7
0
        /// <summary>
        /// Adds the locateable to the map.
        /// </summary>
        /// <param name="locateable">The locateable object.</param>
        public void Add(ILocateable locateable)
        {
            if (locateable is DroppedItem droppedItem)
            {
                droppedItem.Id = (ushort)this.objectIdGenerator.GetId();
                Log.DebugFormat("{0}: Added drop {1}, {2}", this.Definition, droppedItem.Id, droppedItem.Item);
            }

            if (locateable is Player player)
            {
                player.Id = (ushort)this.objectIdGenerator.GetId();
                Log.DebugFormat("{0}: Added player {1}, {2}, ", this.Definition, player.Id, player);
                Interlocked.Increment(ref this.playerCount);
                this.stateObserver?.PlayerCountChanged(this.MapId, this.playerCount);
            }

            if (locateable is NonPlayerCharacter npc)
            {
                npc.Id = (ushort)this.objectIdGenerator.GetId();
                Log.DebugFormat("{0}: Added npc {1}, {2}", this.Definition, npc.Id, npc.Definition.Designation);
            }

            this.objectsInMap.Add(locateable.Id, locateable);
            this.areaOfInterestManager.AddObject(locateable);
            this.ObjectAdded?.Invoke(this, new GameMapEventArgs(this, locateable));
        }
        /// <inheritdoc/>
        public void RemoveObject(ILocateable obj)
        {
            if (obj is IHasBucketInformation bucketInfo)
            {
                bucketInfo.OldBucket = this.Map[obj.X, obj.Y];
                bucketInfo.NewBucket = null;
            }

            if (!this.Map[obj.X, obj.Y].Remove(obj))
            {
                return;
            }

            if (obj is IBucketMapObserver observingPlayer)
            {
                foreach (var bucket in observingPlayer.ObservingBuckets)
                {
                    bucket.ItemAdded   -= observingPlayer.LocateableAdded;
                    bucket.ItemRemoved -= observingPlayer.LocateableRemoved;
                }

                if (observingPlayer.ObservingBuckets.Any(b => b.Count > 0))
                {
                    observingPlayer.LocateablesOutOfScope(observingPlayer.ObservingBuckets.SelectMany(o => o));
                }

                observingPlayer.ObservingBuckets.Clear();
            }
        }
Esempio n. 9
0
        /// <summary>
        /// An object moved on the map.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="movedObject">The moved object.</param>
        /// <param name="moveType">Type of the move.</param>
        public void ObjectMoved(WorldObserverToHubAdapter sender, ILocateable movedObject, MoveType moveType)
        {
            byte   x, y;
            object steps     = null;
            int    walkDelay = 0;

            if (movedObject is ISupportWalk walkable && moveType == MoveType.Walk)
            {
                x         = walkable.WalkTarget.X;
                y         = walkable.WalkTarget.Y;
                walkDelay = (int)walkable.StepDelay.TotalMilliseconds;
                var walkSteps = walkable.NextDirections.Select(step => new { x = step.To.Y, y = step.To.Y, direction = step.Direction }).ToList();

                // TODO: Can errors happen here when NextDirection changes in the meantime?
                var lastStep = walkable.NextDirections.LastOrDefault();
                if (!Equals(lastStep, default(WalkingStep)))
                {
                    var lastDirection = lastStep.To.GetDirectionTo(walkable.WalkTarget);
                    if (lastDirection != Direction.Undefined)
                    {
                        walkSteps.Add(new { x, y, direction = lastDirection });
                    }
                }

                steps = walkSteps;
            }
        /// <inheritdoc/>
        /// <remarks>
        /// This needs to take into account, that the <see cref="Walker"/> might change the <see cref="ILocateable.X"/> and <see cref="ILocateable.Y"/>,
        /// but not updating the buckets. So accessing the bucket of the current coordinates might not be the current bucket!
        /// </remarks>
        public void RemoveObject(ILocateable obj)
        {
            if (obj is IHasBucketInformation bucketInfo)
            {
                // we remove the object from all known buckets and set old/new bucket to null
                bucketInfo.NewBucket?.Remove(obj);
                bucketInfo.OldBucket?.Remove(obj);
                bucketInfo.OldBucket = null;
                bucketInfo.NewBucket = null;
            }
            else
            {
                this.Map[obj.X, obj.Y].Remove(obj);
            }

            if (obj is IBucketMapObserver observingPlayer)
            {
                foreach (var bucket in observingPlayer.ObservingBuckets)
                {
                    bucket.ItemAdded   -= observingPlayer.LocateableAdded;
                    bucket.ItemRemoved -= observingPlayer.LocateableRemoved;
                }

                if (observingPlayer.ObservingBuckets.Any(b => b.Count > 0))
                {
                    observingPlayer.LocateablesOutOfScope(observingPlayer.ObservingBuckets.SelectMany(o => o));
                }

                observingPlayer.ObservingBuckets.Clear();
            }
        }
Esempio n. 11
0
        /// <summary>
        /// Returns wether the given location has the given terrain characteristics
        /// </summary>
        public bool IsTerrain(ILocateable loc, Terrain terrain)
        {
            switch (terrain)
            {
            case Terrain.InEnemyRange:
                return(this.EnemyAttackMap.HasDangerousPiratesInAttackRange(loc));

            case Terrain.EnemyLocation:
                // check for a current enemy
                Pirate p = this.GetPirateOn(loc);
                if (p != null && p.Owner != Owner.Me)
                {
                    return(true);
                }
                // check for an enemy spawning
                p = this.GetPirateSpawnOn(loc);
                if (p != null && p.TurnsToRevive == 1 && p.Owner != Owner.Me)
                {
                    return(true);
                }
                // else, there is no enemy there
                return(false);

            case Terrain.CurrentTreasureLocation:
                return(this.GetTreasuresOn(loc).Count > 0);

            default:
                return(false);
            }
        }
Esempio n. 12
0
 /// <summary>
 /// Returns a list of pirates that are within attack range of "loc", and their state is "state"
 /// </summary>
 public List <Pirate> GetPiratesInAttackRange(ILocateable loc, PirateState state)
 {
     if (!this.map.InMap(loc))
     {
         return(null);
     }
     return(new List <Pirate>(this.attackRangeMap[loc.GetLocation().Row, loc.GetLocation().Collumn, (int)state]));
 }
Esempio n. 13
0
 /// <summary>
 /// Tries to add a taken location to the ResourcesPack
 /// </summary>
 /// <returns>Was the addition successful</returns>
 public bool AddTakenLocation(ILocateable l)
 {
     if (l == null || l.GetLocation() == null)
     {
         return(false);
     }
     return(this.takenLocations.Add(l.GetLocation()));
 }
Esempio n. 14
0
        //////////Methods//////////

        /// <summary>
        /// Creates a new sail command
        /// </summary>
        /// <param name="pirate">The pirate that will sail</param>
        /// <param name="immediateDestionation">The IMMEDIATE destination of the pirate</param>
        public SailCommand(Pirate pirate, ILocateable immediateDestionation)
            : base(pirate)
        {
            this.Pirate = pirate;
            this.ImmediateDestination = immediateDestionation.GetLocation();

            this.distance = Game.ManhattanDistance(this.Pirate, this.ImmediateDestination);
        }
Esempio n. 15
0
 /// <summary>
 /// Tries to add a freed-up location to the ResourcesPack
 /// </summary>
 /// <returns>Was the addition successful</returns>
 public bool AddFreedLocation(ILocateable l)
 {
     if (l == null || l.GetLocation() == null)
     {
         return(false);
     }
     return(this.freedUpLocations.Add(l.GetLocation()));
 }
Esempio n. 16
0
        /// <summary>
        /// Returns wether the location given is inside the map
        /// </summary>
        public bool InMap(ILocateable l)
        {
            Location loc = l.GetLocation();

            return(loc.Row >= 0 &&
                   loc.Row < this.Rows &&
                   loc.Collumn >= 0 &&
                   loc.Collumn < this.Collumns);
        }
Esempio n. 17
0
        /// <summary>
        /// Returns wether there are pirates whose state is "state", that are in attack range of "loc"
        /// </summary>
        public bool HasPiratesInAttackRange(ILocateable loc, PirateState state)
        {
            if (!this.map.InMap(loc))
            {
                return(false);
            }

            return(this.attackRangeMap[loc.GetLocation().Row, loc.GetLocation().Collumn, (int)state].Count > 0);
        }
Esempio n. 18
0
        /// <summary>
        /// Removes the locateable from the map.
        /// </summary>
        /// <param name="locateable">The locateable.</param>
        public void Remove(ILocateable locateable)
        {
            if (this.objectsInMap.Remove(locateable.Id) && locateable.Id != 0 && locateable is DroppedItem)
            {
                this.freeDropIds.Add(locateable.Id);
            }

            this.areaOfInterestManager.RemoveObject(locateable);
        }
Esempio n. 19
0
        /// <summary>
        /// Returns a list of all the pirates which have one of the "states" given, ordered by their manhattan distance to "location"
        /// </summary>
        public List <Pirate> GetClosestPirates(ILocateable location, params PirateState[] states)
        {
            if (location == null || location.GetLocation() == null)
            {
                return(new List <Pirate>());
            }

            return(this.GetPirates(states).OrderBy(pirate => Map.ManhattanDistance(pirate, location)).ToList());
        }
Esempio n. 20
0
        /// <summary>
        /// Returns a list of pirates that actually CAN attack, that are in attack range of loc
        /// </summary>
        public List <Pirate> GetDangerousPiratesInAttackRange(ILocateable loc)
        {
            if (!this.map.InMap(loc))
            {
                return(null);
            }

            return(this.attackRangeMap[loc.GetLocation().Row, loc.GetLocation().Collumn, (int)PirateState.Free].FindAll(p => p.CanAttack));
        }
Esempio n. 21
0
        /// <summary>
        /// Returns if the given locations are in (euclidean) range of each other
        /// </summary>
        public static bool InEuclideanRange(ILocateable a, ILocateable b, double range)
        {
            if (a == null || a.GetLocation() == null ||
                b == null || b.GetLocation() == null)
            {
                return(false);
            }

            return(Map.EuclideanDistance(a, b) <= range);
        }
Esempio n. 22
0
 /// <summary>
 /// Creates a map object for the given locateable object.
 /// </summary>
 /// <param name="locateable">The locateable object.</param>
 /// <returns>The created map object.</returns>
 public static MapObject CreateMapObject(this ILocateable locateable)
 {
     return(new MapObject
     {
         Direction = (locateable as IRotatable)?.Rotation ?? default,
         Id = locateable.Id,
         MapId = locateable.CurrentMap?.MapId ?? 0,
         Name = locateable.ToString() ?? string.Empty,
         X = locateable.Position.X,
         Y = locateable.Position.Y,
     });
Esempio n. 23
0
        //////////Methods//////////

        /// <summary>
        /// Creates a new treasure with the parameters given.
        /// carryingPirate can be null.
        /// </summary>
        public Treasure(int id, ILocateable location, TreasureState state, Pirate carryingPirate, int value)
        {
            this.Id = id;
            this.InitialLocation = location.GetLocation();
            this.location        = this.InitialLocation;
            this.state           = state;
            this.carryingPirate  = carryingPirate;
            this.Value           = value;

            this.nativeObject = null;
        }
Esempio n. 24
0
        /// <summary>
        /// Determines whether the object is at the safezone of his current map.
        /// </summary>
        /// <param name="obj">The object.</param>
        /// <returns>True, if it is on the safezone of his current map; Otherwise, false.</returns>
        public static bool IsAtSafezone(this ILocateable obj)
        {
            var map = obj.CurrentMap;

            if (map == null)
            {
                return(true);
            }

            return(map.Terrain.SafezoneMap[obj.X, obj.Y]);
        }
Esempio n. 25
0
        /// <summary>
        /// Returns a list of neighbors in-map of the location given, that are away from the location as specified
        /// </summary>
        public List <Location> GetNeighbors(ILocateable l, int manhattanDistance)
        {
            if (l == null || l.GetLocation() == null ||
                manhattanDistance < 0 || manhattanDistance >= this.neighbors.GetLength(2) ||
                !this.InMap(l))
            {
                return(null);
            }

            return(new List <Location> (this.neighbors[l.GetLocation().Row, l.GetLocation().Collumn, manhattanDistance]));
        }
Esempio n. 26
0
 /// <summary>
 /// Returns the treasure whose initial location is on the location given, or null if one does not exist
 /// </summary>
 public Treasure GetTreasureSpawnOn(ILocateable loc)
 {
     if (loc == null)
     {
         return(null);
     }
     if (this.treasuresSpawnOnMap.ContainsKey(loc.GetLocation()))
     {
         return(this.treasuresSpawnOnMap[loc.GetLocation()]);
     }
     return(null);
 }
Esempio n. 27
0
 /// <summary>
 /// Returns the pirate whose initial location is on the location given, or null if one does not exist
 /// </summary>
 public Pirate GetPirateSpawnOn(ILocateable loc)
 {
     if (loc == null)
     {
         return(null);
     }
     if (this.piratesSpawnOnMap.ContainsKey(loc.GetLocation()))
     {
         return(this.piratesSpawnOnMap[loc.GetLocation()]);
     }
     return(null);
 }
Esempio n. 28
0
 /// <summary>
 /// Returns the treasures which are on the location given
 /// </summary>
 public List <Treasure> GetTreasuresOn(ILocateable loc)
 {
     if (loc == null)
     {
         return(null);
     }
     if (this.treasuresOnMap.ContainsKey(loc.GetLocation()))
     {
         return(this.treasuresOnMap[loc.GetLocation()]);
     }
     return(new List <Treasure>());
 }
Esempio n. 29
0
        /// <inheritdoc/>
        public void ObjectMoved(ILocateable obj, MoveType type)
        {
            var objectId = obj.GetId(this.player);

            if (type == MoveType.Instant)
            {
                this.connection.Send(new byte[] { 0xC1, 0x08, (byte)PacketType.Teleport, objectId.GetHighByte(), objectId.GetLowByte(), obj.X, obj.Y, 0 });
            }
            else
            {
                IList <Direction> steps = null;
                var       x             = obj.X;
                var       y             = obj.Y;
                Direction rotation      = Direction.Undefined;
                if (obj is ISupportWalk supportWalk)
                {
                    if (this.SendWalkDirections)
                    {
                        steps = supportWalk.NextDirections.Select(d => d.Direction).ToList();

                        // The last one is the rotation
                        rotation = steps.LastOrDefault();
                        steps.RemoveAt(steps.Count - 1);
                    }

                    if (obj is IRotateable rotateable)
                    {
                        rotation = rotateable.Rotation.RotateLeft();
                    }

                    x = supportWalk.WalkTarget.X;
                    y = supportWalk.WalkTarget.Y;
                }

                var    stepsSize  = (steps?.Count / 2) + 2 ?? 1;
                byte[] walkPacket = new byte[7 + stepsSize];
                walkPacket.SetValues <byte>(0xC1, (byte)walkPacket.Length, (byte)PacketType.Walk, objectId.GetHighByte(), objectId.GetLowByte(), x, y, (byte)((steps?.Count ?? 0) | ((byte)rotation) << 4));
                if (steps != null)
                {
                    walkPacket[7] = (byte)((int)steps.First() << 4 | (int)steps.Count);
                    for (int i = 0; i < steps.Count; i += 2)
                    {
                        var index      = 8 + (i / 2);
                        var firstStep  = steps[i];
                        var secondStep = steps.Count > i + 2 ? steps[i + 2] : Direction.Undefined;
                        walkPacket[index] = (byte)((int)firstStep << 4 | (int)secondStep);
                    }
                }

                this.connection.Send(walkPacket);
            }
        }
Esempio n. 30
0
        /// <inheritdoc/>
        public void AddObject(ILocateable obj)
        {
            this.Map[obj.X, obj.Y].Add(obj);
            if (obj is IHasBucketInformation bucketInfo)
            {
                bucketInfo.CurrentBucket = this.Map[obj.X, obj.Y];
            }

            if (obj is IBucketMapObserver observingPlayer)
            {
                this.UpdateObservingBuckets(obj.X, obj.Y, observingPlayer);
            }
        }