/// <summary> /// Calculate a circular list of <see cref="GridPosition"/>s around /// the passed <see cref="center"/> with a passed radius. The returned /// list is sorted by distance from <see cref="center"/> /// </summary> /// <param name="radius">Radius of circle (in grid units)</param> /// <param name="center">Center of circle in world space</param> /// <param name="length">Length of grid squares</param> /// <returns></returns> public static List <GridPosition> GetTilePositionsFromRadius(int radius, Vector2 center, int length) { int xPos = Mathf.RoundToInt(center.x / length); int zPos = Mathf.RoundToInt(center.y / length); SortedList <float, GridPosition> result = new SortedList <float, GridPosition>(25); for (var zCircle = -radius; zCircle <= radius; zCircle++) { for (var xCircle = -radius; xCircle <= radius; xCircle++) { if (xCircle * xCircle + zCircle * zCircle < radius * radius) { var newPos = new GridPosition(xPos + xCircle, zPos + zCircle); var distance = newPos.Distance(new GridPosition(xPos, zPos)); while (result.ContainsKey(distance)) { distance++; } result.Add(distance, newPos); } } } var normResult = new List <GridPosition>(result.Count); normResult.AddRange(result.Values); return(normResult); }
/// <summary> /// Gets the grid square preview color based on which LOD /// level it falls within. /// </summary> /// <returns></returns> private Color GetLodPreviewColor(GridPosition position) { if (Generator == null || Generator.Lod == null) { return(Color.white); } bool isCenter00 = !Application.isPlaying && Application.isEditor || Generator.TrackedObject == null; Vector3 worldXYZ = isCenter00 ? Vector3.zero : Generator.TrackedObject.transform.position; Vector3 worldXZ = new Vector2(worldXYZ.x, worldXYZ.z); var lod = Generator.Lod; var tileLength = Generator.Length; var lvlType = lod.GetLevelTypeForRadius((int)position.Distance(new GridPosition(worldXZ, tileLength))); switch (lvlType) { case LodData.LodLevelType.High: return(Color.green); case LodData.LodLevelType.Medium: return(Color.yellow); case LodData.LodLevelType.Low: return(Color.red); } return(Color.white); }
protected virtual void Update() { if (_endTurn) { _endTurn = false; BlockUI = true; StartCoroutine(FinishTurn()); } foreach (var livingEntity in Entities.OfType <LivingEntity>()) { if (_selectedEntity == null || livingEntity.Side == PlayerSide || BlockUI) { livingEntity.UI.EnableTargetMarker(false); livingEntity.UI.EnableBoardMarker(false); } else { var range = GridPosition.Distance(_selectedEntity.Position, livingEntity.Position); livingEntity.UI.EnableTargetMarker(_selectedEntity.CanAttack && range <= _selectedEntity.Weapon.Range); livingEntity.UI.EnableBoardMarker(_selectedEntity.CanBoard && range == 1); } } if (_selectedEntity != null && _selectedEntity.CanMove && !BlockUI) { var obstacles = new HashSet <GridPosition>(Entities .Where(entity => entity.IsObstacle(PlayerSide)) .Select(entity => entity.Position)); var entities = new HashSet <GridPosition>(Entities.Select(entity => entity.Position)); var destinations = _astar.GetDestinations(_selectedEntity.Position, obstacles, entities, _selectedEntity.MovementRange); var markers = new Queue <GameObject>(_destinationMarkers); _destinationMarkers.Clear(); foreach (var destination in destinations) { var marker = markers.Any() ? markers.Dequeue() : Instantiate(DestinationMarkerPrefab); if (marker != null) { marker.transform.position = GridPosition.ToVector3(destination); marker.transform.SetParent(transform); _destinationMarkers.Add(marker); } } while (markers.Any()) { Destroy(markers.Dequeue()); } } else { foreach (var destinationMarker in _destinationMarkers) { Destroy(destinationMarker); } } }
// Token: 0x06003788 RID: 14216 RVA: 0x000F9B94 File Offset: 0x000F7D94 public void Start(BattleActor actor0, BattleActor actor1, ConfigDataSkillInfo heroSkillInfo0, ConfigDataSkillInfo heroSkillInfo1, int randomSeed) { if (!BJLuaObjHelper.IsSkipLuaHotfix && this.TryInitHotFix("") && this.m_StartBattleActorBattleActorConfigDataSkillInfoConfigDataSkillInfoInt32_hotfix != null) { this.m_StartBattleActorBattleActorConfigDataSkillInfoConfigDataSkillInfoInt32_hotfix.call(new object[] { this, actor0, actor1, heroSkillInfo0, heroSkillInfo1, randomSeed }); return; } BJLuaObjHelper.IsSkipLuaHotfix = false; this.Clear(); this.m_randomNumber.SetSeed(randomSeed); this.m_startCountdown = Combat.MillisecondToFrame1(this.ConfigDataLoader.UtilityGetConfigableConst(ConfigableConstId.ConfigableConstId_Combat_StartDelay) + 250) + 1; this.m_state = CombatState.Ready; this.m_isPaused = false; this.m_combatGridDistance = GridPosition.Distance(actor0.Position, actor1.Position); this.SetupTeam(0, actor0, heroSkillInfo0); this.SetupTeam(1, actor1, heroSkillInfo1); foreach (CombatTeam combatTeam in this.m_teams) { combatTeam.EnterCombat(); } }
// Token: 0x06003A34 RID: 14900 RVA: 0x00109EA8 File Offset: 0x001080A8 public int GetGoalHeuristic(Pathfinder pathfinder) { if (!BJLuaObjHelper.IsSkipLuaHotfix && this.TryInitHotFix("") && this.m_GetGoalHeuristicPathfinder_hotfix != null) { return(Convert.ToInt32(this.m_GetGoalHeuristicPathfinder_hotfix.call(new object[] { this, pathfinder }))); } BJLuaObjHelper.IsSkipLuaHotfix = false; return(GridPosition.Distance(pathfinder.GoalNode.m_position, this.m_position)); }
private static LivingEntity GetNearestEnemy(Entity self, IEnumerable <LivingEntity> enemies) { int minDistance = int.MaxValue; LivingEntity closest = null; foreach (var enemy in enemies) { var distance = GridPosition.Distance(self.Position, enemy.Position); if (distance < minDistance) { minDistance = distance; closest = enemy; } } return(closest); }
/// <summary> /// Gets the LOD level for this tile based off of its <see cref="GridPosition"/>'s /// distance from the tracked object. If no tracked object is specified, the level /// is determined by the <see cref="GridPosition"/>'s distance from [0, 0]. The returned /// LOD level may not be equal to this Tile's <see cref="LodLevel"/> as it could have changed /// since initialization. /// </summary> /// <returns>LOD level</returns> private LodData.LodLevel GetLodLevel() //todo change to reflect description { GameObject tracked = Config.Generator.TrackedObject; if (tracked == null) { int radius = (int)GridPosition.Distance(new GridPosition(0, 0)); return(Config.Generator.Lod.GetLevelForRadius(radius)); } else { float length = Config.Generator.Length; Vector2 worldXZ = new Vector2(tracked.transform.position.x, tracked.transform.position.z); GridPosition gp = new GridPosition(worldXZ, length); int radius = (int)gp.Distance(GridPosition); return(Config.Generator.Lod.GetLevelForRadius(radius)); } }
public void Interact(GridPosition gridPosition) { if (_selectedEntity == null) { return; } var clickedEntity = Entities.FirstOrDefault(entity => entity.Position == gridPosition); if (clickedEntity == null) { if (_selectedEntity.CanMove) { var obstacles = Entities .Where(entity => entity.IsObstacle(PlayerSide)) .Select(entity => entity.Position) .ToList(); var path = _astar.Calculate(_selectedEntity.Position, gridPosition, obstacles); if (path != null && path.Count <= _selectedEntity.MovementRange + 1) { BlockUI = true; StartCoroutine(Move(_selectedEntity, path)); } } } else { if (_selectedEntity.CanAttack) { var target = clickedEntity as LivingEntity; if (target != null && target.Side != PlayerSide) { var range = GridPosition.Distance(_selectedEntity.Position, target.Position); if (range <= _selectedEntity.Weapon.Range) { BlockUI = true; StartCoroutine(Attack(_selectedEntity, target)); } } } } }
public IEnumerator Attack(LivingEntity target, float salvoFlightTime) { var range = GridPosition.Distance(Position, target.Position); if (!CanAttack) { throw new InvalidOperationException($"The entity '{this}' cannot attack."); } if (range > Weapon.Range) { throw new InvalidOperationException($"The target '{target}' is out of range."); } CanAttack = false; UI.EnableCanFireMarker(CanAttack); if (target.Weapon != null && range <= target.Weapon.Range && Random.Range(0, 10) >= 7) { yield return(FireSalvo(target, this, salvoFlightTime)); if (IsAlive) { yield return(FireSalvo(this, target, salvoFlightTime)); } } else { yield return(FireSalvo(this, target, salvoFlightTime)); if (target.IsAlive && target.Weapon != null && range <= target.Weapon.Range) { yield return(FireSalvo(target, this, salvoFlightTime)); } } }
public void FindAStarPathBetween(Vector3 startPosition, Vector3 endPosition) //has to be seperate!! { if (GridMap.isBusy) { Debug.Log("isbusy"); return; } GridMap.isBusy = true; var currentTime = DateTime.Now; //ScanGridMap(); need a better solution! GridPosition start = GetGridPosition(startPosition); GridPosition end = GetGridPosition(endPosition); Dictionary <GridPosition, Node> closedNodes = new Dictionary <GridPosition, Node>(); Dictionary <GridPosition, Node> openNodes = new Dictionary <GridPosition, Node>(); Dictionary <GridPosition, Node> allNodes = new Dictionary <GridPosition, Node>(); Node startNode = new Node(); startNode.Fcost = end.Distance(start); startNode.Gcost = 0f; allNodes.Add(start, startNode); openNodes.Add(start, startNode); while (openNodes.Count > 0) { if ((DateTime.Now - currentTime).Milliseconds > maxPathFindTime) { break; } KeyValuePair <GridPosition, Node> best = openNodes.Aggregate((a, b) => a.Value.Fcost < b.Value.Fcost ? a : b); //find cheapest node openNodes.Remove(best.Key); closedNodes.Add(best.Key, best.Value); //add node to move to to closed list //AssertIfEndGridIsFoundAndBackTrack!! if (best.Key.Equals(end)) { Debug.Log("found end!"); List <Vector3> path = new List <Vector3>(); Node bestNode = best.Value; path.Add(endPosition); //backtrack! while (bestNode != null && !bestNode.parentGridPosition.Equals(GridPosition.Zero)) { path.Insert(0, GetWorldPosition(bestNode.parentGridPosition)); bestNode = allNodes[bestNode.parentGridPosition]; if (drawOverlay) { GameObject gcOverlay = (GameObject)GameObject.Instantiate(gridCellOverlay, GetWorldPosition(bestNode.parentGridPosition), Quaternion.identity); gcOverlay.GetComponentInChildren <SpriteRenderer>().color = Color.red; gcOverlay.transform.parent = GameObject.Find("Paths").transform; overlay.Add(gcOverlay); } } Debug.Log("took : " + (DateTime.Now - currentTime).Milliseconds + "ms to generate a path!"); DispatchMessage("OnPathFound", path); GridMap.isBusy = false; } //LoopThroughWalkablewNeighBours foreach (GridPosition gridPosition in GetNeighbours(best.Key).Where(gc => GetCell(gc).walkable)) { Node alreadyExistingNode; if (closedNodes.TryGetValue(gridPosition, out alreadyExistingNode)) { continue; } float tenativeGcost = best.Value.Gcost + 1; Node currentNode; if (!openNodes.TryGetValue(gridPosition, out currentNode)) //AddNodeToOpenAndAllIfNotAlreadyAdded { currentNode = new Node(); allNodes.Add(gridPosition, currentNode); openNodes.Add(gridPosition, currentNode); } if (tenativeGcost < currentNode.Gcost) //AssertIfNodeGCostIsLowerThanTenativeGCost { currentNode.Gcost = tenativeGcost; currentNode.parentGridPosition = best.Key; currentNode.Fcost = tenativeGcost + gridPosition.Distance(end); } } } GridMap.isBusy = false; }
private static float GetCost(GridPosition start, GridPosition goal) { return(GridPosition.Distance(start, goal)); }
private static float HeuristicCostEstimate([NotNull] Node start, [NotNull] Node goal) { return(GridPosition.Distance(start.Position, goal.Position)); }
protected override void Execute(List <InputEntity> entities) { if (!_contexts.input.isPointerHolding) { return; } var position = _contexts.input.pointerHoldingPosition.value.ToGridPosition(); var horizontalBounded = position.x >= 0 && position.x < _contexts.config.mapSize.value.x; var verticalBounded = position.y >= 0 && position.y < _contexts.config.mapSize.value.y; if (horizontalBounded && verticalBounded) { var entityUnderPointer = _contexts.game.GetEntityWithPosition(position); if (entityUnderPointer == null) { return; } if (entityUnderPointer.isBlock) { return; } if (entityUnderPointer.isSelected) { return; } var lastSelectedId = _contexts.gameState.lastSelected.value; if (lastSelectedId == -1) { entityUnderPointer.isSelected = true; entityUnderPointer.ReplaceSelectionId(0); _contexts.gameState.ReplaceLastSelected(entityUnderPointer.id.value); _contexts.gameState.ReplaceMaxSelectedElement(0); } else { var lastSelected = _contexts.game.GetEntityWithId(lastSelectedId); if (lastSelected.hasElementType && entityUnderPointer.hasElementType) { if (lastSelected.elementType.value == entityUnderPointer.elementType.value) { if (GridPosition.Distance(lastSelected.position.value, entityUnderPointer.position.value) < 1.25f) { var selectionId = _contexts.gameState.maxSelectedElement.value; selectionId++; entityUnderPointer.isSelected = true; entityUnderPointer.ReplaceSelectionId(selectionId); _contexts.gameState.ReplaceLastSelected(entityUnderPointer.id.value); _contexts.gameState.ReplaceMaxSelectedElement(selectionId); } } } } } }
public IEnumerator CalculateTurn(List <Entity> entities, Astar astar, Side side, float movementSpeed, float salvoFlightTime) { var ownEntities = entities.OfType <LivingEntity>().Where(entity => entity.Side == side).ToList(); var enemyShips = entities.OfType <LivingEntity>().Where(entity => entity.Side != side).ToList(); foreach (var own in ownEntities) { if (!own.CanAttack) { continue; } var blackList = new List <LivingEntity>(); bool selectNewEnemy; do { selectNewEnemy = false; var enemy = GetNearestEnemy(own, enemyShips.Except(blackList)); if (GridPosition.Distance(own.Position, enemy.Position) <= own.Weapon.Range) { yield return(own.Attack(enemy, salvoFlightTime)); } else { var obstacles = entities .Except(ownEntities) .Where(entity => entity != enemy) .Select(entity => entity.Position) .ToList(); var destinations = GetDestinations(enemy.Position, own.Weapon.Range) .Except(entities.Select(entity => entity.Position)) .Distinct(); IList <GridPosition> shortestPath = null; foreach (var destination in destinations) { var path = astar.Calculate(own.Position, destination, obstacles); if (shortestPath == null || path.Count < shortestPath.Count) { shortestPath = path; } } if (shortestPath != null) { var path = shortestPath.Count > own.MovementRange + 2 ? shortestPath.Take(own.MovementRange + 1).ToList() : shortestPath; yield return(own.Move(path, movementSpeed)); if (GridPosition.Distance(own.Position, enemy.Position) <= own.Weapon.Range) { yield return(own.Attack(enemy, salvoFlightTime)); } } else { blackList.Add(enemy); selectNewEnemy = true; } } } while (selectNewEnemy && blackList.Count < enemyShips.Count); } }