private void GameMap_UnitMoveCompleted(object sender, UnitMoveCompletedEventArgs e) { _movingComplete = true; _moveUnitChangesContainer = e.MoveUnitChangeContainer; _gameMap.UnitMoveCompleted -= GameMap_UnitMoveCompleted; _gameBattle.AddInputState(_inputStateFactory.ResolveUnitSelectActionState(_unit)); }
//public async Task MoveUnitAsync(IGameUnit unit, IGameMapMovementRoute route) //{ // await MoveUnitCoroutine(unit, route); //} /// <summary> /// /// </summary> /// <param name="unit"></param> /// <param name="route"></param> /// <returns></returns> public IEnumerator MoveUnitCoroutine(IGameUnit unit, IGameMapMovementRoute route) { // Create a container for our move unit var moveUnitChangeContainer = new MoveUnitChangeContainer(unit); // Quick pre-calculation if we need to do walking damage var hasWalkingDamage = unit.GetAttribute(UnitAttribute.WalkingDamage) > 0; // Move the unit each step in the given route, excluding None direction steps foreach (var routeStep in route.Route.Where(x => x != Direction.None)) { var startPosition = unit.WorldPosition; var directionVector = DirectionHelper.GetDirectionVector(routeStep); var targetPosition = unit.WorldPosition + directionVector; // Animate the unit moving this step var duration = 0.15f; // 0.15f seconds var stepTime = 0f; while (stepTime < duration) { stepTime += Time.deltaTime; unit.WorldPosition = Vector3.Lerp(startPosition, targetPosition, stepTime / duration); yield return(null); } // Animation complete, set the unit position to be the end location unit.WorldPosition = targetPosition; var newX = unit.MapX; var newY = unit.MapY; DirectionHelper.ApplyDirection(routeStep, ref newX, ref newY); unit.MapX = newX; unit.MapY = newY; // Apply walking damage to the tiles the unit now occupies if (hasWalkingDamage) { ApplyWalkingDamage(unit, newX, newY, unit.TileWidth, unit.TileHeight, moveUnitChangeContainer); } } // Final snap the unit to their end map & unity location unit.MapX = route.EndX; unit.MapY = route.EndY; unit.WorldPosition = TranslateMapXYToUnityXY(unit.MapX, unit.MapY); // And tell them to consume movement for this route unit.AddRouteCost(route); // Trigger the MoveCompleted event now that we're done animating the move OnUnitMoveCompleted(moveUnitChangeContainer); }
public void TakeDamage(int damage, IGameUnit attackingUnit, MoveUnitChangeContainer moveUnitChangeContainer) { // Can't inflict damage to non-destructable tiles so check that first if (!MapTileData.Destructable || TileHealth <= 0) { return; } // For now only handle dealing positive damage if (damage <= 0) { return; } // Change tile health to inflict damage var startingHealth = TileHealth; TileHealth = Mathf.Clamp(TileHealth - damage, 0, MapTileData.TileMaxHealth); // Check if this tile has been destroyed aka HP = 0 if (tileHealth <= 0 && !IsDestroyed) { // Create a container for our state change var tileChange = new TileStateChangeContainer(this, IsDestroyed, startingHealth, MapTileData); moveUnitChangeContainer.TileChanges.Add(tileChange); // If we have an attacking unit then count our destruction value and body count towards them if (attackingUnit != null) { attackingUnit.IncrementStatistic(UnitStatistic.PropertyDamage, DestructionValue); moveUnitChangeContainer.ApplyStatisticOffset(UnitStatistic.PropertyDamage, DestructionValue); attackingUnit.IncrementStatistic(UnitStatistic.BodyCount, DestructionBodyCount); moveUnitChangeContainer.ApplyStatisticOffset(UnitStatistic.BodyCount, DestructionBodyCount); } // If we have a tile to become when we're destroyed then we'll change to that if (MapTileData.OnDestroyedTile != null) { // Update the backing map tile data for this tile, this should trigger a refresh of this tile ChangeMapTileData(MapTileData.OnDestroyedTile); } else { // Otherwise just flag this tile as destroyed IsDestroyed = true; } } }
public UnitMoveCompletedEventArgs(MoveUnitChangeContainer moveUnitChangeContainer) { MoveUnitChangeContainer = moveUnitChangeContainer; }
public void ApplyWalkingDamage(IGameUnit unit, int mapX, int mapY, int areaWidth, int areaHeight, MoveUnitChangeContainer moveUnitChangeContainer) { var damage = unit.GetAttribute(UnitAttribute.WalkingDamage); if (damage == 0) { return; } // Collect the tiles we're checking for (var x = mapX; x < mapX + areaWidth; x++) { for (var y = mapY; y < mapY + areaHeight; y++) { // Get the tile group in question var tileIndex = y * GameMapWidth + x; if (tileIndex < 0 || tileIndex >= GameMapTiles.Length || GameMapTiles[tileIndex] == null) { Debug.Log(String.Format("MovementCostForUnit tile index out of bounds or null: {0}. Map tile length: {1}", tileIndex, GameMapTiles.Length)); continue; } var tileGroup = GameMapTiles[tileIndex]; foreach (var tile in tileGroup.Tiles.Where(z => z != null)) { tile.TakeDamage(damage, unit, moveUnitChangeContainer); } } } }
public void OnUnitMoveCompleted(MoveUnitChangeContainer moveUnitChangeContainer) { UnitMoveCompleted?.Invoke(this, new UnitMoveCompletedEventArgs(moveUnitChangeContainer)); }