private void RasterLine(int x0, int y0, int x1, int y1, ref BoardCellDynamicArray cells, out int flatDist, out int diagDist) { int num = (x1 <= x0) ? -1 : 1; int num2 = (x1 - x0) * num; int num3 = (y1 <= y0) ? -1 : 1; int num4 = (y1 - y0) * num3; flatDist = 0; diagDist = 0; if (num2 > num4) { int num5 = num4 * 2 - num2; int num6 = num4 * 2; int num7 = (num4 - num2) * 2; int num8 = x0; int num9 = y0; while (num8 != x1) { if (num5 <= 0) { num5 += num6; num8 += num; flatDist++; } else { num5 += num7; num8 += num; num9 += num3; diagDist++; } this.AddCell(num8, num9, ref cells); } } else { int num10 = num2 * 2 - num4; int num11 = num2 * 2; int num12 = (num2 - num4) * 2; int num13 = x0; int num14 = y0; while (num14 != y1) { if (num10 <= 0) { num10 += num11; num14 += num3; flatDist++; } else { num10 += num12; num13 += num; num14 += num3; diagDist++; } this.AddCell(num13, num14, ref cells); } } }
public static List <SmartEntity> TraverseSpiralToFindTargets(int radius, int centerX, int centerZ, TargetingController.TargetValidator validator, object caller, bool returnFirstFound) { BoardCellDynamicArray boardCellDynamicArray = GameUtils.TraverseSpiral(radius, centerX, centerZ); List <SmartEntity> list = new List <SmartEntity>(); for (int i = 0; i < boardCellDynamicArray.Length; i++) { BoardCell boardCell = boardCellDynamicArray.Array[i]; if (boardCell.Children != null) { foreach (BoardItem current in boardCell.Children) { if (validator((SmartEntity)current.Data, caller)) { list.Add((SmartEntity)current.Data); if (returnFirstFound) { return(list); } } } } } return(list); }
private void SmoothThePath(ref BoardCellDynamicArray rawTurns, ref BoardCellDynamicArray pathCells, ref BoardCellDynamicArray turns, List <int> turnDistances) { if (rawTurns.Length == 0) { Service.Logger.Error("SmoothThePath: Not expecting empty path!"); return; } pathCells.Add(rawTurns.Array[0]); turns.Add(rawTurns.Array[0]); turnDistances.Add(0); if (rawTurns.Length == 1) { return; } if (rawTurns.Length == 2) { this.AddTurn(rawTurns.Array[0], rawTurns.Array[1], ref pathCells, ref turns, turnDistances); return; } BoardCell boardCell = rawTurns.Array[0]; BoardCell boardCell2 = rawTurns.Array[1]; for (int i = 2; i < rawTurns.Length; i++) { BoardCell boardCell3 = rawTurns.Array[i]; if (!BoardUtils.HasLineOfClearance(this.board, boardCell.X, boardCell.Z, boardCell3.X, boardCell3.Z, this.TroopWidth)) { this.AddTurn(boardCell, boardCell2, ref pathCells, ref turns, turnDistances); boardCell = boardCell2; } boardCell2 = boardCell3; } this.AddTurn(boardCell, boardCell2, ref pathCells, ref turns, turnDistances); }
private void AddTurn(BoardCell legStart, BoardCell legEnd, ref BoardCellDynamicArray pathCells, ref BoardCellDynamicArray turns, List <int> turnDistances) { turns.Add(legEnd); int num = 0; int num2 = 0; this.RasterLine(legStart.X, legStart.Z, legEnd.X, legEnd.Z, ref pathCells, out num, out num2); turnDistances.Add(num * 1000 + num2 * 1414); }
private void AddCell(int x, int y, ref BoardCellDynamicArray cells) { x += 23; if (x >= 0 && x < 46) { y += 23; if (y >= 0 && y < 46) { BoardCell element = this.board.Cells[x, y]; cells.Add(element); } } }
public bool FindValidDropShipTroopPlacementCell(IntPosition boardPosition, TeamType teamType, int troopWidth, out IntPosition newBoardPosition) { BoardCellDynamicArray boardCellDynamicArray = GameUtils.TraverseSpiral(2, boardPosition.x, boardPosition.z); newBoardPosition = IntPosition.Zero; this.boardController.Board.RefreshClearanceMap(); for (int i = 0; i < boardCellDynamicArray.Length; i++) { BoardCell boardCell = boardCellDynamicArray.Array[i]; if (boardCell != null && boardCell.Clearance >= troopWidth && !boardCell.CollidesWith(CollisionFilters.TROOP)) { newBoardPosition = new IntPosition(boardCell.X, boardCell.Z); return(true); } } return(false); }
public Path(BoardCell fromCell, BoardCell toCell, BoardCell targetAt, int maxLength, PathTroopParams troopParams, PathBoardParams boardParams) { this.pathCells = new BoardCellDynamicArray(64); this.scratchCells = new BoardCellDynamicArray(64); this.turns = new BoardCellDynamicArray(64); this.turnDistances = new List <int>(64); BoardController boardController = Service.BoardController; this.board = boardController.Board; this.pathingManager = Service.PathingManager; this.startCell = fromCell; this.destCell = toCell; this.targetCell = targetAt; this.NoWall = (boardParams.IgnoreWall || troopParams.CrushesWalls); this.crushesWalls = troopParams.CrushesWalls; this.destructible = boardParams.Destructible; this.isHealer = troopParams.IsHealer; this.TroopWidth = troopParams.TroopWidth; this.damagePerSecond = troopParams.DPS; this.maxShooterRange = troopParams.MaxRange; this.targetInRangeModifier = troopParams.TargetInRangeModifier; if (this.isHealer && this.maxShooterRange > troopParams.SupportRange) { this.maxShooterRange = troopParams.SupportRange; } this.minShooterRange = troopParams.MinRange; this.maxSpeed = troopParams.MaxSpeed; this.heristicMultiplier = (int)troopParams.PathSearchWidth; this.maxPathLength = ((!this.isHealer) ? maxLength : -1); this.melee = troopParams.IsMelee; this.overWalls = troopParams.IsOverWall; this.projectileType = troopParams.ProjectileType; this.isTargetShield = troopParams.IsTargetShield; this.openCells = new HeapPriorityQueue(boardController.GetPriorityQueueSize()); this.curPathingCell = this.pathingManager.GetPathingCell(); this.curPathingCell.Cell = this.startCell; this.startCell.PathInfo = this.curPathingCell; this.curPathingCell.InRange = this.InRangeOfTarget(this.startCell); this.curPathingCell.RemainingCost = this.HeuristicDiagonal(this.startCell, this.destCell); this.curPathingCell.PathLength = 0; this.curPathingCell.PastCost = 0; this.curPathingCell.InClosedSet = true; }
public BoardCellDynamicArray GetCellsInSquare(int distFromCenter, int centerX, int centerZ) { BoardCellDynamicArray result = new BoardCellDynamicArray(distFromCenter * distFromCenter); int num = centerX - distFromCenter; int num2 = centerX + distFromCenter; int num3 = centerZ - distFromCenter; int num4 = centerZ + distFromCenter; for (int i = num; i <= num2; i++) { for (int j = num3; j <= num4; j++) { BoardCell cellAt = this.GetCellAt(i, j); if (cellAt != null) { result.Add(cellAt); } } } return(result); }
private void ImpactAreaWithSplash(Bullet bullet) { int targetBoardX = bullet.TargetBoardX; int targetBoardZ = bullet.TargetBoardZ; int splashRadius = bullet.SplashVO.SplashRadius; BoardCellDynamicArray cellsInSquare = Service.BoardController.Board.GetCellsInSquare(splashRadius, targetBoardX, targetBoardZ); Dictionary <Entity, bool> dictionary = new Dictionary <Entity, bool>(); Vector3 targetWorldLocation = bullet.TargetWorldLocation; for (int i = 0; i < cellsInSquare.Length; i++) { BoardCell boardCell = cellsInSquare.Array[i]; int chessboardDistance = BoardUtils.GetChessboardDistance(boardCell.X, boardCell.Z, targetBoardX, targetBoardZ); int splashDamagePercent = bullet.SplashVO.GetSplashDamagePercent(chessboardDistance); if (splashDamagePercent != 0) { ShieldGeneratorComponent activeShieldAffectingBoardPos = Service.ShieldController.GetActiveShieldAffectingBoardPos(boardCell.X, boardCell.Z); if (activeShieldAffectingBoardPos != null && !bullet.ProjectileType.PassThroughShield && activeShieldAffectingBoardPos.Entity.Get <TeamComponent>().TeamType != bullet.OwnerTeam) { TransformComponent transformComponent = activeShieldAffectingBoardPos.Entity.Get <TransformComponent>(); Vector3 targetPos = new Vector3(Units.BoardToWorldX(transformComponent.CenterX()), transformComponent.CenterX(), Units.BoardToWorldZ(transformComponent.CenterZ())); Vector3 zero = Vector3.zero; if (Service.ShieldController.GetRayShieldIntersection(targetWorldLocation, targetPos, activeShieldAffectingBoardPos, out zero)) { bullet.SetTargetWorldLocation(zero); } this.ImpactTargetFromSplashDamage((SmartEntity)activeShieldAffectingBoardPos.ShieldBorderEntity, bullet, splashDamagePercent, ref dictionary); } else if (boardCell.Children != null) { LinkedListNode <BoardItem> next; for (LinkedListNode <BoardItem> linkedListNode = boardCell.Children.First; linkedListNode != null; linkedListNode = next) { next = linkedListNode.Next; this.ImpactTargetFromSplashDamage((SmartEntity)linkedListNode.Value.Data, bullet, splashDamagePercent, ref dictionary); } } } } }
private BoardCellDynamicArray FindTheTurns(ref BoardCellDynamicArray path) { BoardCellDynamicArray result = new BoardCellDynamicArray(64); int length = path.Length; result.Add(path.Array[length - 1]); for (int i = length - 2; i > 0; i--) { BoardCell boardCell = path.Array[i]; BoardCell boardCell2 = path.Array[i + 1]; BoardCell boardCell3 = path.Array[i - 1]; if (boardCell.X - boardCell2.X != boardCell3.X - boardCell.X || boardCell.Z - boardCell2.Z != boardCell3.Z - boardCell.Z) { result.Add(boardCell); } } if (length >= 2) { result.Add(path.Array[0]); } return(result); }
private bool ImpactBeamTargets(Bullet bullet) { BoardCellDynamicArray beamNearbyCells = bullet.GetBeamNearbyCells(); if (beamNearbyCells.Array == null) { return(false); } for (int i = 0; i < beamNearbyCells.Length; i++) { BoardCell boardCell = beamNearbyCells.Array[i]; if (boardCell.Children != null) { int beamDamagePercent = bullet.GetBeamDamagePercent(boardCell.X, boardCell.Z); if (beamDamagePercent != 0) { for (LinkedListNode <BoardItem> linkedListNode = boardCell.Children.First; linkedListNode != null; linkedListNode = linkedListNode.Next) { SmartEntity target = (SmartEntity)linkedListNode.Value.Data; bullet.ApplyBeamDamagePercent(target, beamDamagePercent); } } } } foreach (BeamTarget current in bullet.BeamTargets.Values) { if (current.HitThisSegment) { bullet.SetTarget(current.Target); this.ImpactSingleTarget(bullet, current.CurDamagePercent, false, true); bullet.SetTarget(null); } current.OnBeamAdvance(); } bullet.AdvanceBeam(); return(true); }
private void CreateSpawnMesh() { Board board = Service.BoardController.Board; if (this.meshCells.Array == null) { this.meshCells = new BoardCellDynamicArray(16); } IState currentState = Service.GameStateMachine.CurrentState; bool flag = currentState is HomeState || currentState is EditBaseState || currentState is ApplicationLoadState; int i = 0; int boardSize = board.BoardSize; while (i < boardSize) { for (int j = 0; j < boardSize; j++) { BoardCell cellAt = board.GetCellAt(i, j, true); if ((cellAt.Flags & 4u) != 0u || (!flag && (cellAt.Flags & 16u) != 0u)) { this.meshCells.Add(cellAt); } } i++; } int num = 23; int num2 = 47; int quadCount = this.meshCells.Length + num2 * 4; Vector3[] vertices; Vector2[] uv; int[] triangles; UnityUtils.SetupVerticesForQuads(quadCount, out vertices, out uv, out triangles); int num3 = 0; int k = 0; int length = this.meshCells.Length; while (k < length) { BoardCell boardCell = this.meshCells.Array[k]; this.SetGridQuadVertices(boardCell.X, boardCell.Z, num3++, vertices); k++; } this.meshCells.Clear(); int num4 = -num - 1; int num5 = num; int l = 0; int num6 = num4; int num7 = num5; while (l < num2) { this.SetGridQuadVertices(num4, num6, num3++, vertices); this.SetGridQuadVertices(num6, num5, num3++, vertices); this.SetGridQuadVertices(num5, num7, num3++, vertices); this.SetGridQuadVertices(num7, num4, num3++, vertices); l++; num6++; num7--; } this.mesh = UnityUtils.CreateMeshWithVertices(vertices, uv, triangles); }
public LinkedList <Entity> GetBlockingEntities(uint targetId, out LinkedList <Entity> wallListForCrushing) { HashSet <uint> entityIds = new HashSet <uint>(); LinkedList <Entity> linkedList = new LinkedList <Entity>(); LinkedList <Entity> linkedList2 = new LinkedList <Entity>(); BoardCellDynamicArray boardCellDynamicArray = new BoardCellDynamicArray(64); for (int i = 0; i < this.pathCells.Length; i++) { BoardCell boardCell = this.pathCells.Array[i]; int num = (!this.NoWall || this.crushesWalls) ? boardCell.Clearance : boardCell.ClearanceNoWall; if (num < this.TroopWidth) { int x; int y; if (i == 0) { if (this.pathCells.Length <= 1) { break; } x = boardCell.X * 2 - this.pathCells.Array[1].X; y = boardCell.Z * 2 - this.pathCells.Array[1].Z; } else { x = this.pathCells.Array[i - 1].X; y = this.pathCells.Array[i - 1].Z; } this.RasterCrossSection(x, y, boardCell.X, boardCell.Z, this.TroopWidth, ref boardCellDynamicArray); } } for (int j = 0; j < boardCellDynamicArray.Length; j++) { this.AddEntitiesOnCellToBlockingList(boardCellDynamicArray.Array[j], targetId, entityIds, linkedList, linkedList2, true); } if (!this.melee) { boardCellDynamicArray.Clear(); int num2 = 0; int num3 = 0; int halfWidthForOffset = BoardUtils.GetHalfWidthForOffset(this.TroopWidth); BoardCell boardCell2 = this.pathCells.Array[this.pathCells.Length - 1]; int num4 = boardCell2.X + halfWidthForOffset; int num5 = boardCell2.Z + halfWidthForOffset; SmartEntity smartEntity = null; bool flag = true; if (this.isTargetShield) { foreach (BoardItem current in this.targetCell.Children) { if (GameUtils.IsEntityShieldGenerator((SmartEntity)current.Data)) { smartEntity = (SmartEntity)current.Data; break; } } if (smartEntity == null) { Service.Logger.Error("Pathing believes target is shield generator, however targetCell does not have shield generator entity."); } else { flag = Service.ShieldController.IsPositionUnderShield(num4, num5, smartEntity); } } this.RasterLine(num4, num5, this.targetCell.X, this.targetCell.Z, ref boardCellDynamicArray, out num2, out num3); for (int k = 0; k < boardCellDynamicArray.Length - 1; k++) { if (this.isTargetShield && !flag && Service.ShieldController.IsPositionUnderShield(boardCellDynamicArray.Array[k].X, boardCellDynamicArray.Array[k].Z, smartEntity)) { break; } this.AddEntitiesOnCellToBlockingList(boardCellDynamicArray.Array[k], targetId, entityIds, linkedList, linkedList2, false); } } wallListForCrushing = linkedList2; return(linkedList); }
private int RasterCrossSection(int x0, int y0, int x1, int y1, int size, ref BoardCellDynamicArray cells) { if (size == 1) { this.AddCell(x1, y1, ref cells); return(1); } int num = x1 - x0; int num2 = y1 - y0; if (num > 0 && num2 == 0) { int i = y1; int num3 = y1 + size; while (i < num3) { this.AddCell(x1 + 1, i, ref cells); i++; } return(size); } if (num < 0 && num2 == 0) { int j = y1; int num4 = y1 + size; while (j < num4) { this.AddCell(x1, j, ref cells); j++; } return(size); } if (num == 0 && num2 > 0) { int k = x1; int num5 = x1 + size; while (k < num5) { this.AddCell(k, y1 + 1, ref cells); k++; } return(size); } if (num == 0 && num2 < 0) { int l = x1; int num6 = x1 + size; while (l < num6) { this.AddCell(l, y1, ref cells); l++; } return(size); } if (num > 0 && num2 < 0) { int num7 = 1; int num8 = x1; int num9 = y1 + size - 1; int num10 = x1 + size - 1; while (num8 < num10 && num9 > y1) { this.AddCell(num8, y1, ref cells); this.AddCell(x1 + 1, num9, ref cells); num7 += 2; num8++; num9--; } this.AddCell(x1 + 1, y1, ref cells); return(num7); } if (num < 0 && num2 < 0) { int num7 = 1; int num11 = x1 + size - 1; int num12 = y1 + size - 1; while (num11 > x1 && num12 > y1) { this.AddCell(num11, y1, ref cells); this.AddCell(x1, num12, ref cells); num7 += 2; num11--; num12--; } this.AddCell(x1, y1, ref cells); return(num7); } if (num < 0 && num2 > 0) { int num7 = 1; int num13 = x1 + size - 1; int num14 = y1; int num15 = y1 + size - 1; while (num13 > x1 && num14 < num15) { this.AddCell(num13, y1 + 1, ref cells); this.AddCell(x1, num14, ref cells); num7 += 2; num13--; num14++; } this.AddCell(x1, y1 + 1, ref cells); return(num7); } if (num > 0 && num2 > 0) { int num7 = 1; int num16 = x1; int num17 = y1; int num18 = y1 + size - 1; while (num16 < x1 + size - 1 && num17 < num18) { this.AddCell(num16, y1 + 1, ref cells); this.AddCell(x1 + 1, num17, ref cells); num7 += 2; num16++; num17++; } this.AddCell(x1 + 1, y1 + 1, ref cells); return(num7); } return(0); }
private int CostToNeighbor(BoardCell fromCell, BoardCell toCell, ref BoardCellDynamicArray cells) { int num; if (fromCell.X != toCell.X && fromCell.Z != toCell.Z) { num = 1414; } else { num = 1000; } int num2 = num * 10 / this.maxSpeed; int num3 = this.TroopWidth - ((!this.NoWall) ? toCell.Clearance : toCell.ClearanceNoWall); if (num3 > 0) { int num4 = this.RasterCrossSection(fromCell.X, fromCell.Z, toCell.X, toCell.Z, this.TroopWidth, ref cells); for (int i = 0; i < num4; i++) { BoardCell boardCell = cells.Array[i]; uint flags = boardCell.Flags; if ((flags & 3u) != 0u) { if (!this.NoWall || (flags & 1u) != 0u) { if ((flags & 64u) != 0u || this.isHealer) { num2 = 2147483647; break; } HealthComponent buildingHealth = boardCell.BuildingHealth; if (buildingHealth != null && this.damagePerSecond != 0) { ArmorType armorType = buildingHealth.ArmorType; int num5 = 100; if (this.projectileType != null) { int num6 = this.projectileType.DamageMultipliers[(int)armorType]; if (num6 >= 0) { num5 = num6; } else { Service.Logger.ErrorFormat("ArmorType {0} not found in ProjectileType {1}", new object[] { armorType, this.projectileType.Uid }); } } int num7 = this.damagePerSecond * num5 / 100; if (num7 <= 0) { num2 = 2147483647; break; } num2 += buildingHealth.Health * 1000 / num7; } } } } cells.Clear(); } return(num2); }
private void CalculatePath(out bool found, ref BoardCellDynamicArray scratchCells) { int num = 46 - this.TroopWidth; while (!this.curPathingCell.InRange) { if (this.maxPathLength < 0 || this.curPathingCell.PathLength < this.maxPathLength) { BoardCell cell = this.curPathingCell.Cell; int x = cell.X; int z = cell.Z; for (int i = 0; i < 8; i++) { int num2 = x + Path.dirX[i]; if (num2 >= 0 && num2 <= num) { int num3 = z + Path.dirY[i]; if (num3 >= 0 && num3 <= num) { BoardCell boardCell = this.board.Cells[num2, num3]; if ((boardCell.Flags & 64u) == 0u) { if (!this.destructible) { int num4 = (!this.NoWall) ? boardCell.Clearance : boardCell.ClearanceNoWall; if (this.TroopWidth > num4) { goto IL_29A; } } int num5 = this.CostToNeighbor(cell, boardCell, ref scratchCells); if (num5 != 2147483647) { int num6 = this.curPathingCell.PastCost + num5; int pathLength = this.curPathingCell.PathLength + 1; PathfindingCellInfo pathfindingCellInfo = boardCell.PathInfo; if (pathfindingCellInfo != null && pathfindingCellInfo.PoolIndex < this.pathingManager.FreeCellIndex) { if (!pathfindingCellInfo.InClosedSet) { if (!this.openCells.Contains(pathfindingCellInfo)) { Service.Logger.ErrorFormat("Allocated cell not in close/open sets,PoolIndex:{0}, FreeIndex:{1}", new object[] { pathfindingCellInfo.PoolIndex, this.pathingManager.FreeCellIndex }); } else if (num6 < pathfindingCellInfo.PastCost) { pathfindingCellInfo.PastCost = num6; pathfindingCellInfo.PathLength = pathLength; this.openCells.UpdatePriority(pathfindingCellInfo, pathfindingCellInfo.PastCost + pathfindingCellInfo.RemainingCost); } } } else { pathfindingCellInfo = this.pathingManager.GetPathingCell(); pathfindingCellInfo.PrevCell = this.curPathingCell; if (boardCell.PathInfo != null) { PathfindingCellInfo pathInfo = boardCell.PathInfo; pathInfo.Cell = null; } pathfindingCellInfo.Cell = boardCell; boardCell.PathInfo = pathfindingCellInfo; pathfindingCellInfo.InRange = this.InRangeOfTarget(boardCell); pathfindingCellInfo.RemainingCost = this.HeuristicDiagonal(boardCell, this.destCell); pathfindingCellInfo.PastCost = num6; pathfindingCellInfo.PathLength = pathLength; this.openCells.Enqueue(pathfindingCellInfo, pathfindingCellInfo.PastCost + pathfindingCellInfo.RemainingCost); } } } } } IL_29A :; } } if (this.openCells.Count == 0) { this.pathingManager.RecycleAllPathingCells(); this.openCells = null; found = false; scratchCells.Clear(); return; } this.curPathingCell = this.openCells.Dequeue(); this.curPathingCell.InClosedSet = true; } if (!this.curPathingCell.InRange) { this.pathingManager.RecycleAllPathingCells(); this.openCells = null; found = false; scratchCells.Clear(); return; } do { scratchCells.Add(this.curPathingCell.Cell); this.curPathingCell = this.curPathingCell.PrevCell; }while (this.curPathingCell != null); int length = scratchCells.Length; if (length == 0) { Service.Logger.ErrorFormat("Empth Path from {0} to {1} within range {2}", new object[] { this.startCell, this.destCell, this.maxShooterRange }); } if (scratchCells.Array[length - 1] != this.startCell) { Service.Logger.ErrorFormat("First cell doesn't match: {0} and {1}", new object[] { this.startCell, scratchCells.Array[length - 1] }); } BoardCellDynamicArray boardCellDynamicArray = this.FindTheTurns(ref scratchCells); this.SmoothThePath(ref boardCellDynamicArray, ref this.pathCells, ref this.turns, this.turnDistances); this.pathingManager.RecycleAllPathingCells(); this.openCells = null; found = true; scratchCells.Clear(); }