private void RefreshLineOfSight(ILineOfSightEntity lineOfSightEntity, int needRefreshBits) { if (!lineOfSightEntity.LineOfSightActive) { return; } MajorEmpire majorEmpire = lineOfSightEntity.Empire as MajorEmpire; if (majorEmpire == null) { return; } short num = (short)(majorEmpire.Bits | lineOfSightEntity.EmpireInfiltrationBits); if ((needRefreshBits & (int)num) == 0) { return; } lineOfSightEntity.LineOfSightDirty = false; if (!lineOfSightEntity.WorldPosition.IsValid) { return; } WorldParameters worldParameters = this.world.WorldParameters; int lineOfSightVisionRange = lineOfSightEntity.LineOfSightVisionRange; int lineOfSightVisionHeight = lineOfSightEntity.LineOfSightVisionHeight; int num2 = 0; if (lineOfSightEntity.LineOfSightData == null) { lineOfSightEntity.LineOfSightData = new LineOfSightData(); } LineOfSightData lineOfSightData = lineOfSightEntity.LineOfSightData; if (lineOfSightVisionRange < 0) { return; } short num3 = (short)lineOfSightVisionRange; if (this.tempRect == null) { this.tempRect = new WorldRect(lineOfSightEntity.WorldPosition, WorldOrientation.East, num3, num3, num3, num3, worldParameters); } else { this.tempRect.Update(lineOfSightEntity.WorldPosition, WorldOrientation.East, num3, num3, num3, num3, worldParameters); } this.rectVirtualPositions.Clear(); this.tempRect.FillVirtualWorldPositions(ref this.rectVirtualPositions); VisibilityController.Position position = new VisibilityController.Position(WorldPosition.Invalid, WorldPosition.Invalid, -1); for (int i = 0; i < this.rectVirtualPositions.Count; i++) { if (lineOfSightEntity.WorldPosition == WorldPosition.GetValidPosition(this.rectVirtualPositions[i], worldParameters)) { position = new VisibilityController.Position(this.rectVirtualPositions[i], lineOfSightEntity.WorldPosition, 0); break; } } Diagnostics.Assert(position.ValidWorldPosition.IsValid); this.potentialPositions.Clear(); for (int j = 0; j < this.rectVirtualPositions.Count; j++) { WorldPosition worldPosition = this.rectVirtualPositions[j]; WorldPosition validPosition = WorldPosition.GetValidPosition(worldPosition, worldParameters); if (validPosition.IsValid) { int distance = WorldPosition.GetDistance(position.ValidWorldPosition, validPosition, worldParameters.IsCyclicWorld, worldParameters.Columns); if (distance <= lineOfSightVisionRange) { this.potentialPositions.Add(new VisibilityController.Position(worldPosition, validPosition, distance)); } } } this.potentialPositions.Sort((VisibilityController.Position position1, VisibilityController.Position position2) => position1.Distance.CompareTo(position2.Distance)); lineOfSightData.Arcs.Clear(); float radius = ((float)lineOfSightVisionRange + 0.1f) * 2f * Hexagon.One.Radius; lineOfSightData.Arcs.AddFirst(new Arc(position.GeometryPosition, 0f, 6.28308535f, radius)); bool flag = this.EnableDetection; if (flag) { num2 = lineOfSightEntity.LineOfSightDetectionRange; flag &= (num2 > 0); } for (int k = 0; k < this.potentialPositions.Count; k++) { VisibilityController.Position obstaclePosition = this.potentialPositions[k]; bool flag2 = obstaclePosition.Distance > lineOfSightVisionRange || this.IsWorldPositionObstructingVision(position.ValidWorldPosition, obstaclePosition.ValidWorldPosition, lineOfSightVisionHeight, lineOfSightEntity.IgnoreFog); if (flag && obstaclePosition.Distance > num2) { flag = false; } LinkedListNode <Arc> linkedListNode = lineOfSightData.Arcs.First; while (linkedListNode != null) { Arc value = linkedListNode.Value; linkedListNode = linkedListNode.Next; if (flag2) { if (Helper.IsHexagonIntersectArc(value, obstaclePosition.GeometryPosition)) { this.SplitArc(lineOfSightData, value, obstaclePosition); this.SetWorldPositionAsExplored(obstaclePosition.ValidWorldPosition, majorEmpire, num); } } else if (value.Contains(obstaclePosition.GeometryPosition)) { if (flag) { this.SetWorldPositionAsDetected(obstaclePosition.ValidWorldPosition, majorEmpire, num, lineOfSightEntity.VisibilityAccessibilityLevel); break; } this.SetWorldPositionAsVisible(obstaclePosition.ValidWorldPosition, majorEmpire, num, lineOfSightEntity.VisibilityAccessibilityLevel); break; } } } }
private void SplitArc(LineOfSightData data, Arc arc, VisibilityController.Position obstaclePosition) { float num = float.PositiveInfinity; for (int i = 0; i < this.hexagonPointsBuffer.Length; i++) { this.hexagonPointsBuffer[i] = Hexagon.One.Points[i] + obstaclePosition.GeometryPosition; Vector2 vector = new Vector2(this.hexagonPointsBuffer[i].x - arc.Center.x, this.hexagonPointsBuffer[i].y - arc.Center.y); this.hexagonPointAnglesBuffer[i] = Helper.GetPositiveAngle(Mathf.Atan2(vector.y, vector.x)); if (vector.sqrMagnitude < num) { num = vector.sqrMagnitude; } } float num2; float num3; Helper.GetAngleExtremities(this.hexagonPointAnglesBuffer, out num2, out num3); if (arc.EndAngleInRad <= num2 || arc.StartAngleInRad >= num3) { return; } for (int j = 0; j < this.tempNewArcs.Length; j++) { this.tempNewArcs[j] = null; } float num4 = Mathf.Sqrt(num); bool flag = Helper.IsAngleBewteen(num2, num3, arc.StartAngleInRad); bool flag2 = Helper.IsAngleBewteen(num2, num3, arc.EndAngleInRad); if (arc.StartAngleInRad < num2) { this.tempNewArcs[0] = new Arc(arc.Center, arc.StartAngleInRad, num2, (!flag) ? arc.Radius : num4); if (arc.EndAngleInRad <= num3) { this.tempNewArcs[1] = new Arc(arc.Center, num2, arc.EndAngleInRad, (!flag2) ? arc.Radius : num4); } else if (arc.EndAngleInRad > num3) { this.tempNewArcs[1] = new Arc(arc.Center, num2, num3, (!flag2) ? num4 : arc.Radius); this.tempNewArcs[2] = new Arc(arc.Center, num3, arc.EndAngleInRad, (!flag2) ? arc.Radius : num4); } } else if (arc.StartAngleInRad >= num2) { if (arc.EndAngleInRad <= num3) { this.tempNewArcs[0] = new Arc(arc.Center, arc.StartAngleInRad, arc.EndAngleInRad, (!flag2) ? arc.Radius : num4); } else if (arc.EndAngleInRad > num3) { this.tempNewArcs[0] = new Arc(arc.Center, arc.StartAngleInRad, num3, (!flag) ? arc.Radius : num4); this.tempNewArcs[1] = new Arc(arc.Center, num3, arc.EndAngleInRad, (!flag2) ? arc.Radius : num4); } } LinkedListNode <Arc> node = data.Arcs.Find(arc); for (int k = 0; k < this.tempNewArcs.Length; k++) { Arc arc2 = this.tempNewArcs[k]; if (arc2 != null && arc2.AngleInRad > 0f) { data.Arcs.AddBefore(node, arc2); } } data.Arcs.Remove(node); }