public override bool Attack(DirectionVector direction) { if (_shootTimer == null) { _shootTimer = new ExpirationTimer(_skillSet.ShootDeltaTime); _shootTimer.OnExpiredTimer += AttackAction; } if (_shootTimer.ExpirationTime != _skillSet.ShootDeltaTime) { _shootTimer.ExpirationTime = _skillSet.ShootDeltaTime; } if (_isCanAttack) { Projectile projectile = ObjectsAPI.SpawnObject(_projectile.gameObject).GetComponent <Projectile>(); float rotation = direction.Value.VectorAngle(); float projectileSpeed = _skillSet.ProjectileSpeed; projectile.Shoot(transform.position, rotation, 1, direction.Value * projectileSpeed, _damageSkill.DamageValue, _classInformation.CurrentFraction); _isCanAttack = false; _shootTimer.Start(); return(true); } return(false); }
/// <summary> /// Gets the neighbour grid component in the given direction, if one exists. /// The predefined directions on the <see cref="DirectionVector"/> can be combined for more combinations. /// </summary> /// <param name="grid">The grid.</param> /// <param name="direction">The direction.</param> /// <returns>The neighbouring grid, or null if no neighbour exists</returns> public static GridComponent GetNeighbourGrid(this GridComponent grid, DirectionVector direction) { var bounds = grid.bounds; var pos = bounds.center + ((bounds.extents + Vector3.one) * direction); return(GridManager.instance.GetGridComponent(pos)); }
void rotate(Vector3 velocity) { if (specialDirection != Vector3.zero) { velocity += DirectionVector.getVector(this.direction) * 2f; } velocity.y = 0f; Quaternion lookRotation = Quaternion.identity; if (velocity != Vector3.zero) { lookRotation = Quaternion.LookRotation(velocity); } float angle = lookRotation.y - this.transform.rotation.y; if (this.lastLookRotation != lookRotation) { this.rotating = 0f; this.lastRotation = this.transform.rotation; this.lastLookRotation = lookRotation; } else if (this.rotating != 1f) { this.rotating += Time.deltaTime * this.speed; } if (this.rotating > 1f) { this.rotating = 1f; } this.transform.rotation = Quaternion.Lerp(lastRotation, lookRotation, this.rotating * 2f); }
public ColumnPortion(int x, DirectionVector bottom, DirectionVector top) : this() { X = x; BottomVector = bottom; TopVector = top; }
private static DirectionVector FindDirectionVector(Vector3 startPosition, Vector3 endPosition) { var result = new DirectionVector(); var start_x = startPosition.x; var start_z = startPosition.z; var end_x = endPosition.x; var end_z = endPosition.z; var positive_x = end_x > start_x; var positive_z = end_z > start_z; result.yDirection = endPosition.y >= startPosition.y ? Direction.Up : Direction.Down; if (positive_x) { result.xDirection = Direction.East; } else { result.xDirection = Direction.West; } if (positive_z) { result.zDirection = Direction.North; } else { result.zDirection = Direction.South; } return(result); }
public ColumnPortion(int x, DirectionVector bottom, DirectionVector top) : this() { this.X = x; this.BottomVector = bottom; this.TopVector = top; }
public virtual void MakeSchemaCompliant() { DirectionVector.MakeSchemaCompliant(); DirectionDescription.MakeSchemaCompliant(); DirectionKeyword.MakeSchemaCompliant(); DirectionString.MakeSchemaCompliant(); }
public void TestNext() { DirectionVector direction = new DirectionVector(); direction.Next(); Assert.AreEqual(direction.Dx == 1 && direction.Dy == 0, true, "Direction Next doesn't work correctly!"); }
public override void MoveSnake(object source, ElapsedEventArgs e) { RotateBy(Rotation); DirectionVector.Normalize(); CurrentPosition += DirectionVector; Console.WriteLine("X: " + CurrentPosition.X + " Y: " + CurrentPosition.Y + " R: " + Rotation); }
public void DirectionTest2() { var dir = new DirectionVector(1, 0); dir.RotateBy(-90); dir.X.Should().Be(0); dir.Y.Should().Be(-1); }
public override bool GetControl(out DirectionVector direction) { if (_currentController == null) { direction = DirectionVector.Zero; return(false); } return(_currentController.GetControl(out direction)); }
public override bool GetControl(out DirectionVector direction) { if (_pursued == null) { _pursued = GameManager.Instance.Player.GetLevelObjectComponent <Mover>(); } direction = new DirectionVector(_pursued.Position - _mover.Position); return(true); }
void debug() { Debug.DrawLine(this.transform.position, this.transform.position + DirectionVector.getVector(this.direction) * 2f, Color.red); this.debugLines.Add(this.transform.position); for (int i = 1; i < this.debugLines.Count; i++) { Debug.DrawLine(this.debugLines[i - 1], this.debugLines[i], Color.blue); } }
public void TestNextRevertion() { DirectionVector direction = new DirectionVector(); for (int i = 0; i < DirectionVector.DirectionsCount; i++) { direction.Next(); } Assert.AreEqual(direction.Dx == 1 && direction.Dy == 1, true, "Direction Next doesn't reverts correctly!"); }
public override bool IsElement(Point2D point) { if (DirectionVector.Equals(Vector2D.NullVector)) { return(PositionVector.Equals(point)); } Vector2D vec = point - PositionVector / DirectionVector; return(vec.X == vec.Y); }
public override bool GetControl(out DirectionVector direction) { if (!_isRunning) { _isRunning = true; _coroutine = StartCoroutine(ChangeDirection()); } direction = _currentDirection.ToDirectionVector(); return(_isRunning); }
/// <summary> /// Sets the v 1 /// </summary> /// <param name="v1">The </param> /// <param name="v2">The </param> public void Set(Vec2 v1, Vec2 v2) { Vertex1 = v1; Vertex2 = v2; DirectionVector = Vertex2 - Vertex1; Length = DirectionVector.Normalize(); NormalVector = Vec2.Cross(DirectionVector, 1.0f); Corner1Vector = NormalVector; Corner2Vector = -1.0f * NormalVector; }
public override bool GetControl(out DirectionVector direction) { bool result = false; if (_moveDirection == null) { _moveDirection = new MoveDirection(); } result = InputManager.Instance.GetIsControl(InputAttributesSet.Walk, _moveDirection); direction = _moveDirection.Direction; return(result); }
public override bool IsElement(Point3D point) { if (DirectionVector.Equals(Vector3D.NullVector)) { return(PositionVector.Equals((Vector3D)point)); } Vector3D vec = point - PositionVector; vec = vec / DirectionVector; return(vec.EqualsXY() || vec.EqualsXZ() || vec.EqualsYZ()); }
public override bool GetControl(out DirectionVector direction) { if (_pursued == null) { direction = DirectionVector.Zero; return(false); } if (_transform == null) { _transform = transform; } direction = new DirectionVector(_pursued.position - _transform.position); return(true); }
public override void Update(GameTime gameTime) { var keyboardState = Keyboard.GetState(); var mouseState = Mouse.GetState(); VelocityGoal = Vector2.Zero; var vector = Camera.GetWorldPosition(new Vector2(mouseState.X, mouseState.Y)); DirectionGoalVector.X = vector.X - BoundingBox.Center.X; DirectionGoalVector.Y = vector.Y - BoundingBox.Center.Y; DirectionGoalVector.Normalize(); Rotation = (float)DirectionVector.GetRotationFromVector(); if (mouseState.LeftButton == ButtonState.Pressed && gameTime.TotalGameTime.TotalMilliseconds > LastFire + 200) { LastFire = gameTime.TotalGameTime.TotalMilliseconds; Fire(); } if (keyboardState.IsKeyDown(Keys.W)) { CreateExhaustParticles(); VelocityGoal = (DirectionVector) * Speed; } if (keyboardState.IsKeyDown(Keys.S)) { CreateSideExhaustParticles(DirectionVector, new Vector2(position.X + texture.Width / 2f, position.Y)); VelocityGoal += (DirectionVector) * (Speed * (-SideThrust)); } if (keyboardState.IsKeyDown(Keys.D)) { var right = new Vector2(-DirectionVector.Y, DirectionVector.X); CreateSideExhaustParticles(-right, new Vector2(position.X, position.Y + texture.Height / 2f)); VelocityGoal += right * (Speed * (SideThrust)); } else if (keyboardState.IsKeyDown(Keys.A)) { var left = new Vector2(DirectionVector.Y, -DirectionVector.X); CreateSideExhaustParticles(-left, new Vector2(position.X + texture.Width, position.Y + texture.Height / 2f)); VelocityGoal += left * (Speed * (SideThrust)); } DirectionVector = Vector2.Lerp(DirectionGoalVector, DirectionVector, RotationSpeed); Velocity = Vector2.Lerp(VelocityGoal, Velocity, 0.99f); //scale = Vector2.Lerp(scaleGoal,scale,0.995f); base.Update(gameTime); }
public override void Update(GameTime gameTime) { //DEBUGGING HELP var keyboardState = Keyboard.GetState(); var mouseState = Mouse.GetState(); if (keyboardState.IsKeyDown(Keys.Space)) { var mouseWorldPosition = Camera.GetWorldPosition(new Vector2(mouseState.X, mouseState.Y)); Seek(mouseWorldPosition); } if (keyboardState.IsKeyDown(Keys.G)) { var mouseWorldPosition = Camera.GetWorldPosition(new Vector2(mouseState.X, mouseState.Y)); Flee(mouseWorldPosition, 2000f); } //END DEBUGGING HELP Vector2 steering = Vector2.Zero; if (_shipBehaviour == ShipBehaviour.Seek) { steering += SeekBehaviour(); } if (_shipBehaviour == ShipBehaviour.Wander) { steering += WanderBehaviour(gameTime); } if (_shipBehaviour == ShipBehaviour.Flee) { steering += FleeBehaviour(); } steering = Vector2.Normalize(steering); steering = steering * maxForce; steering = steering / Mass; DirectionGoalVector = Vector2.Normalize(steering); DirectionVector = Vector2.Lerp(DirectionGoalVector, DirectionVector, 0.99f); Velocity = DirectionVector * Speed; //Debug.WriteLine(DirectionVector); Rotation = (float)DirectionVector.GetRotationFromVector(); _healthBar.Update(gameTime); CheckIfDestroyed(); base.Update(gameTime); }
IEnumerator LaserCoroutine(GameMap.BlockInstance instance) { var obj = Instantiate(LaserPrefab); obj.name = "Laser"; var laser = obj.GetComponent <FX.Laser>(); laser.BlockInstance = instance; laser.transform.parent = instance.transform; laser.transform.position = instance.transform.position + DirectionVector.ToVector3() * .5f; laser.transform.rotation = Quaternion.FromToRotation(Vector3.right, DirectionVector); laser.OnTrigger += (collider) => { var player = collider.attachedRigidbody?.GetComponent <Player>(); if (player) { player.Kill(); } }; if (ActiveOnAwake) { laser.PowerOn(0.05f); foreach (var t in Utility.FixedTimer(ActiveTime)) { yield return(new WaitForFixedUpdate()); } laser.ShutDown(0.2f); } while (true) { foreach (var t in Utility.FixedTimer(SleepTime)) { yield return(new WaitForFixedUpdate()); } laser.PowerOn(0.05f); foreach (var t in Utility.FixedTimer(ActiveTime)) { yield return(new WaitForFixedUpdate()); } laser.ShutDown(0.2f); } }
public override bool GetControl(out DirectionVector direction) { Vector3 globalPositon = LevelAPIs.CurrentRoom.Shape.Rectangle.center + _position; var distance = globalPositon - _mover.Position; var distRotate = Quaternion.Euler(0, 0, 90) * distance; if (distance.magnitude <= _radius) { distance = Vector3.zero; } var res = distance + distRotate; direction = new DirectionVector(res); return(true); }
private static void ComputeFoVColumnPortion(int x, DirectionVector topVector, DirectionVector bottomVector, Func <int, int, bool> isOpaque, Action <int, int> setFieldOfView, int radius, Queue <ColumnPortion> queue) { int topY = x * topVector.X / topVector.Y; int bottomY = x * bottomVector.X / bottomVector.Y; int quotient = ((2 * x + 1) * topVector.Y) / (2 * topVector.X); int remainder = ((2 * x + 1) * topVector.Y) % (2 * topVector.X); bool?wasLastCellOpaque = null; for (int y = topY; y >= bottomY; --y) { bool inRadius = isInRadius(x, y, radius); if (inRadius) { //the current cell is in the view. setFieldOfView(x, y); } bool currentIsOpaque = !inRadius || isOpaque(x, y); if (wasLastCellOpaque != null) { if (currentIsOpaque) { if (!wasLastCellOpaque.Value) { queue.Enqueue(new ColumnPortion(x + 1, new DirectionVector(x * 2 - 1, y * 2 + 1), topVector)); } } else if (wasLastCellOpaque.Value) { topVector = new DirectionVector(x + 2 + 1, y * 2 + 1); } } wasLastCellOpaque = currentIsOpaque; } if (wasLastCellOpaque != null && !wasLastCellOpaque.Value) { queue.Enqueue(new ColumnPortion(x + 1, bottomVector, topVector)); } }
private static List <Direction> GetDirectionsLeft(int x, int y, int z, DirectionVector directions) { var result = new List <Direction>(); if (x > 0) { result.Add(directions.xDirection); } if (y > 0) { result.Add(directions.yDirection); } if (z > 0) { result.Add(directions.zDirection); } return(result); }
public override void Execute(GameObject actor) { if (_transform == null) { _transform = transform; } if (_rigidbody == null) { _rigidbody = GetComponent <Rigidbody2D>(); } var actorMover = actor.GetLevelObjectComponent <Mover>(); if (actorMover != null) { DirectionVector direction = new DirectionVector() { Value = _useVelocity ? (Vector3)_rigidbody.velocity : (actor.transform.position - _transform.position) }; actorMover.AddForce(direction.Value * _force); } }
public static GuiWidget CreatePropertyEditor(EditableProperty property, UndoBuffer undoBuffer, PPEContext context, ThemeConfig theme) { var object3D = property.Item; var propertyGridModifier = property.Item as IPropertyGridModifier; GuiWidget rowContainer = null; // Get reflected property value once, then test for each case below var propertyValue = property.Value; // create a double editor if (propertyValue is double doubleValue) { var field = new DoubleField(); field.Initialize(0); field.DoubleValue = doubleValue; field.ValueChanged += (s, e) => { property.SetValue(field.DoubleValue); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties, undoBuffer)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; void RefreshField(object s, InvalidateArgs e) { if (e.InvalidateType == InvalidateType.Properties) { double newValue = (double)property.Value; if (newValue != field.DoubleValue) { field.DoubleValue = newValue; } } } object3D.Invalidated += RefreshField; field.Content.Closed += (s, e) => object3D.Invalidated -= RefreshField; rowContainer = CreateSettingsRow(property, field); } else if (propertyValue is Vector2 vector2) { var field = new Vector2Field(); field.Initialize(0); field.Vector2 = vector2; field.ValueChanged += (s, e) => { property.SetValue(field.Vector2); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties, undoBuffer)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; rowContainer = CreateSettingsColumn(property, field); } else if (propertyValue is Vector3 vector3) { var field = new Vector3Field(); field.Initialize(0); field.Vector3 = vector3; field.ValueChanged += (s, e) => { property.SetValue(field.Vector3); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties, undoBuffer)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; rowContainer = CreateSettingsColumn(property, field); } else if (propertyValue is DirectionVector directionVector) { var field = new DirectionVectorField(theme); field.Initialize(0); field.SetValue(directionVector); field.ValueChanged += (s, e) => { property.SetValue(field.DirectionVector); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties, undoBuffer)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; rowContainer = CreateSettingsRow(property, field); } else if (propertyValue is DirectionAxis directionAxis) { rowContainer = CreateSettingsColumn(property); var newDirectionVector = new DirectionVector() { Normal = directionAxis.Normal }; var row1 = CreateSettingsRow("Axis".Localize()); var field1 = new DirectionVectorField(theme); field1.Initialize(0); field1.SetValue(newDirectionVector); row1.AddChild(field1.Content); rowContainer.AddChild(row1); // the direction axis // the distance from the center of the part // create a double editor var field2 = new Vector3Field(); field2.Initialize(0); field2.Vector3 = directionAxis.Origin - property.Item.Children.First().GetAxisAlignedBoundingBox().Center; var row2 = CreateSettingsColumn("Offset", field2); // update this when changed EventHandler <InvalidateArgs> updateData = (s, e) => { field2.Vector3 = ((DirectionAxis)property.Value).Origin - property.Item.Children.First().GetAxisAlignedBoundingBox().Center; }; property.Item.Invalidated += updateData; field2.Content.Closed += (s, e) => { property.Item.Invalidated -= updateData; }; // update functions field1.ValueChanged += (s, e) => { property.SetValue(new DirectionAxis() { Normal = field1.DirectionVector.Normal, Origin = property.Item.Children.First().GetAxisAlignedBoundingBox().Center + field2.Vector3 }); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties, undoBuffer)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; field2.ValueChanged += (s, e) => { property.SetValue(new DirectionAxis() { Normal = field1.DirectionVector.Normal, Origin = property.Item.Children.First().GetAxisAlignedBoundingBox().Center + field2.Vector3 }); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties, undoBuffer)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; rowContainer.AddChild(row2); } else if (propertyValue is ChildrenSelector childSelector) { var showAsList = property.PropertyInfo.GetCustomAttributes(true).OfType <ShowAsListAttribute>().FirstOrDefault() != null; if (showAsList) { UIField field = new ChildrenSelectorListField(property, theme); field.Initialize(0); field.ValueChanged += (s, e) => { property.SetValue(new ChildrenSelector() { field.Value }); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties, undoBuffer)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; rowContainer = CreateSettingsRow(property, field); } else // show the subtarct editor for boolean subtract and subtract and replace { rowContainer = CreateSettingsColumn(property); rowContainer.AddChild(CreateSelector(childSelector, property.Item, theme)); } } else if (propertyValue is ImageBuffer imageBuffer) { rowContainer = CreateSettingsColumn(property); rowContainer.AddChild(CreateImageDisplay(imageBuffer, property.Item, theme)); } #if !__ANDROID__ else if (propertyValue is List <string> stringList) { var selectedItem = ApplicationController.Instance.DragDropData.SceneContext.Scene.SelectedItem; var field = new SurfacedEditorsField(theme, selectedItem); field.Initialize(0); field.ListValue = stringList; field.ValueChanged += (s, e) => { property.SetValue(field.ListValue); }; rowContainer = CreateSettingsColumn(property, field); rowContainer.Descendants <HorizontalSpacer>().FirstOrDefault()?.Close(); } #endif // create a int editor else if (propertyValue is int intValue) { var field = new IntField(); field.Initialize(0); field.IntValue = intValue; field.ValueChanged += (s, e) => { property.SetValue(field.IntValue); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties, undoBuffer)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; void RefreshField(object s, InvalidateArgs e) { if (e.InvalidateType == InvalidateType.Properties) { int newValue = (int)property.Value; if (newValue != field.IntValue) { field.IntValue = newValue; } } } object3D.Invalidated += RefreshField; field.Content.Closed += (s, e) => object3D.Invalidated -= RefreshField; rowContainer = CreateSettingsRow(property, field); } // create a bool editor else if (propertyValue is bool boolValue) { var field = new ToggleboxField(theme); field.Initialize(0); field.Checked = boolValue; field.ValueChanged += (s, e) => { property.SetValue(field.Checked); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties, undoBuffer)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; rowContainer = CreateSettingsRow(property, field); } // create a string editor else if (propertyValue is string stringValue) { var field = new TextField(); field.Initialize(0); field.SetValue(stringValue, false); field.Content.HAnchor = HAnchor.Stretch; field.ValueChanged += (s, e) => { property.SetValue(field.Value); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties, undoBuffer)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; rowContainer = CreateSettingsRow(property, field); var label = rowContainer.Children.First(); if (field is TextField) { var spacer = rowContainer.Children.OfType <HorizontalSpacer>().FirstOrDefault(); spacer.HAnchor = HAnchor.Absolute; spacer.Width = Math.Max(0, 100 - label.Width); } } // create a char editor else if (propertyValue is char charValue) { var field = new CharField(); field.Initialize(0); field.SetValue(charValue.ToString(), false); field.ValueChanged += (s, e) => { property.SetValue(Convert.ToChar(field.Value)); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties, undoBuffer)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; rowContainer = CreateSettingsRow(property, field); } // create an enum editor else if (property.PropertyType.IsEnum) { UIField field; var iconsAttribute = property.PropertyInfo.GetCustomAttributes(true).OfType <IconsAttribute>().FirstOrDefault(); if (iconsAttribute != null) { field = new IconEnumField(property, iconsAttribute, theme) { InitialValue = propertyValue.ToString() }; } else { field = new EnumField(property, theme); } field.Initialize(0); field.ValueChanged += (s, e) => { property.SetValue(Enum.Parse(property.PropertyType, field.Value)); object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties, undoBuffer)); propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name)); }; rowContainer = CreateSettingsRow(property, field); } // Use known IObject3D editors else if (propertyValue is IObject3D item && ApplicationController.Instance.GetEditorsForType(property.PropertyType)?.FirstOrDefault() is IObject3DEditor iObject3DEditor) { rowContainer = iObject3DEditor.Create(item, theme); } // remember the row name and widget context.editRows.Add(property.PropertyInfo.Name, rowContainer); return(rowContainer); }
public abstract bool Attack(DirectionVector direction);
public RayPoint(Vector3 position, DirectionVector directionVector) { _position = position; _directionVector = directionVector; }
private List<Address> checkColumn(ColumnPortion cp, Address origin, Map map, Queue<ColumnPortion> queue, int octant, int range) { List<Address> result = new List<Address>(); DirectionVector topVector = cp.TopVector; DirectionVector bottomVector = cp.BottomVector; int x = cp.X; int topY; if (cp.X == 0) topY = 0; else { int quotient = (2 * cp.X + 1) * cp.TopVector.Y / (2 * cp.TopVector.X); int remainder = (2 * cp.X + 1) * cp.TopVector.Y % (2 * cp.TopVector.X); topY = quotient; if (remainder > cp.TopVector.X) topY = quotient++; } int bottomY; if (cp.X == 0) bottomY = 0; else { int quotient = (2 * cp.X - 1) * cp.BottomVector.Y / (2 * cp.BottomVector.X); int remainder = (2 * cp.X - 1) * cp.BottomVector.Y % (2 * cp.BottomVector.X); bottomY = quotient; if (remainder >= cp.BottomVector.X) bottomY = quotient++; } bool? wasLastCellOpaque = null; for (int y = topY; y >= bottomY; --y) { bool inRadius = IsInRadius(x, y, range); if (inRadius) { Address temp = TranslateOctant(new Address(x, y), octant); // The current cell is in the field of view. result.Add(new Address(origin.x + temp.x, origin.y + temp.y)); } // A cell that was too far away to be seen is effectively // an opaque cell; nothing "above" it is going to be visible // in the next column, so we might as well treat it as // an opaque cell and not scan the cells that are also too // far away in the next column. bool currentIsOpaque = !inRadius || isOpaque(map, origin, x, y, octant); if (wasLastCellOpaque != null) { if (currentIsOpaque) { // We've found a boundary from transparent to opaque. Make a note // of it and revisit it later. if (!wasLastCellOpaque.Value) { // The new bottom vector touches the upper left corner of // opaque cell that is below the transparent cell. queue.Enqueue(new ColumnPortion( x + 1, new DirectionVector(x * 2 - 1, y * 2 + 1), topVector)); } } else if (wasLastCellOpaque.Value) { // We've found a boundary from opaque to transparent. Adjust the // top vector so that when we find the next boundary or do // the bottom cell, we have the right top vector. // // The new top vector touches the lower right corner of the // opaque cell that is above the transparent cell, which is // the upper right corner of the current transparent cell. topVector = new DirectionVector(x * 2 + 1, y * 2 + 1); } } wasLastCellOpaque = currentIsOpaque; } // Make a note of the lowest opaque-->transparent transition, if there is one. if (wasLastCellOpaque != null && !wasLastCellOpaque.Value) queue.Enqueue(new ColumnPortion(x + 1, bottomVector, topVector)); return result; }