예제 #1
0
        public bool CloseTo(string key)
        {
            if (string.IsNullOrEmpty(this.Key))
            {
                return(false);
            }

            string[]      sm = this.Key.Split(';');
            Vector2Ushort m  = new Vector2Ushort(Convert.ToUInt16(sm[0]), Convert.ToUInt16(sm[1]));

            string[]      sk = key.Split(';');
            Vector2Ushort k  = new Vector2Ushort(Convert.ToUInt16(sk[0]), Convert.ToUInt16(sk[1]));

            double maxTile     = 5.0;
            double maxTileTopY = 10.0;

            if (m.TileDistanceTo(k) <= maxTile)
            {
                return(true);
            }

            int xDistance    = Math.Abs(k.X - m.X);
            int yTopDistance = k.Y - m.Y;

            if (xDistance <= maxTile && yTopDistance > 0 && yTopDistance <= maxTileTopY)
            {
                return(true);
            }

            return(false);
        }
예제 #2
0
        public bool SharedIsTooFarToPlace(ICharacter character, Vector2Ushort targetPosition, bool logErrors)
        {
            if (targetPosition.TileDistanceTo(character.TilePosition)
                <= this.DeployDistanceMax)
            {
                return(false);
            }

            // distance exceeded - too far
            if (!logErrors)
            {
                return(true);
            }

            if (IsClient)
            {
                this.ClientShowCannotPlaceTooFarNotification();
            }
            else
            {
                Logger.Warning($"{character} cannot place {this} - too far");
                this.CallClient(character, _ => _.ClientRemote_CannotPlaceTooFar());
            }

            return(true);
        }
예제 #3
0
        public bool SharedValidatePlacement(ICharacter character, Vector2Ushort targetPosition, bool logErrors)
        {
            // check if there is a direct line of sight
            // check that there are no other objects on the way between them (defined by default layer)
            var physicsSpace      = character.PhysicsBody.PhysicsSpace;
            var characterCenter   = character.Position + character.PhysicsBody.CenterOffset;
            var worldObjectCenter = targetPosition.ToVector2D() + (0.5, 0.5);

            // local method for testing if there is an obstacle from current to the specified position
            bool TestHasObstacle(Vector2D toPosition)
            {
                using (var obstaclesOnTheWay = physicsSpace.TestLine(
                           characterCenter,
                           toPosition,
                           CollisionGroup.GetDefault(),
                           sendDebugEvent: false))
                {
                    foreach (var test in obstaclesOnTheWay)
                    {
                        var testPhysicsBody = test.PhysicsBody;
                        if (testPhysicsBody.AssociatedProtoTile != null)
                        {
                            // obstacle tile on the way
                            return(true);
                        }

                        var testWorldObject = testPhysicsBody.AssociatedWorldObject;
                        if (testWorldObject == character)
                        {
                            // not an obstacle - it's the character or world object itself
                            continue;
                        }

                        // obstacle object on the way
                        return(true);
                    }

                    // no obstacles
                    return(false);
                }
            }

            // let's test by casting rays from character center to the center of the planted bomb
            if (TestHasObstacle(worldObjectCenter))
            {
                // has obstacle
                if (logErrors)
                {
                    if (IsClient)
                    {
                        this.ClientShowCannotPlaceObstaclesOnTheWayNotification();
                    }
                    else
                    {
                        Logger.Warning($"{character} cannot place {this} - obstacles on the way");
                        this.CallClient(character, _ => _.ClientRemote_CannotPlaceObstacles());
                    }
                }

                return(false);
            }

            // validate distance to the character
            if (targetPosition.TileDistanceTo(character.TilePosition)
                > this.DeployDistanceMax)
            {
                // distance exceeded - too far
                if (logErrors)
                {
                    if (IsClient)
                    {
                        this.ClientShowCannotPlaceTooFarNotification();
                    }
                    else
                    {
                        Logger.Warning($"{character} cannot place {this} - too far");
                        this.CallClient(character, _ => _.ClientRemote_CannotPlaceTooFar());
                    }
                }

                return(false);
            }

            if (!this.ObjectExplosiveProto.CheckTileRequirements(targetPosition,
                                                                 character,
                                                                 logErrors))
            {
                // explosive static object placement requirements failed
                return(false);
            }

            return(true);
        }