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); }
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); }
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); }