public ActionInformation ShootFireball(Level level, AbilityDetails abilityDetails) { Func<Tile, ActionAnimationScript> actionScriptGenerator = (tile) => ShootFireballAction(level, abilityDetails, tile); TileSelector abilityRange = TileSelectorHelper.EnemyTileSelector(level, level.GetTileOfActor(this), Team, 5); Func<Tile, TileSelector> abilityAreaOfEffect = TileSelectorHelper.SingleTile; return new ActionInformation(actionScriptGenerator, abilityRange, abilityAreaOfEffect, ActionType.Attack); }
public override IList<DamageResult> CalculateDamages(Level level, Tile targeted) { if (targeted.ActorInTile == null) return DamageResult.Empty; var damageResult = new DamageResult() {DamageType = DamageType.Physical}; damageResult.AffectedActor = targeted.ActorInTile; damageResult.DamageReduced = 0; damageResult.NetDamage = 250; return new List<DamageResult>() {damageResult}; }
public static TileSelector EnemyTileSelector(Level level, Tile currentTile, int myTeam, int maxRange) { var candidateTileList = level.Tiles.Where(x => x.ActorInTile != null && x.ActorInTile.Team != myTeam).ToList(); var tileList = new List<Tile>(); foreach (var tile in candidateTileList) { if (Math.Abs(currentTile.XCoord - tile.XCoord) + Math.Abs(currentTile.YCoord - tile.YCoord) <= maxRange) { tileList.Add(tile); } } return new TileSelector(tileList); }
public static TileSelector CircularSelector(Level level, Tile currentTile, int radius) { var selector = new TileSelector(); for (int i = -radius; i <= radius; i++) { for (int j = -radius; j <= radius; j++) { if (Math.Abs(i) + Math.Abs(j) <= radius) { Tile t = level.GetTileAt(currentTile.XCoord + j, currentTile.YCoord + i); if (t != null) selector.AddValidTile(t); } } } return selector; }
public static IList<Tile> CalculateAStarPath(Tile start, Tile goal, Level level, ActorBase actor) { if (start == null || goal == null) return null; if (goal.ActorInTile != null) return null; var path = new List<Tile>(); var nodes = new Node[level.Length,level.Width]; for (int x = 0; x < level.Length; x++) { for (int y = 0; y < level.Width; y++) { nodes[x, y] = new Node(x, y); } } return CalculatePath(start, goal, level, nodes, actor); }
private ActionAnimationScript ShootFireballAction(Level level, AbilityDetails abilityDetails, Tile selectedTile) { // calculate damages var damageList = abilityDetails.CalculateDamages(level, selectedTile); // animation CurrentAnimation = ActorAnimationManager.Make("cacoshoot", ActorId); CurrentAnimation.OnComplete = Idle; var tilebox = selectedTile.CreateBoundingBox(); var average = tilebox.Min + (tilebox.Max - tilebox.Min) / 2.0f; Vector3 target = new Vector3(average.X, tilebox.Max.Y + Height / 2.0f, average.Z); BoundingBox targetBoundingBox = new BoundingBox(target - new Vector3(20, 20, 20), target + new Vector3(20, 20, 20)); Vector3 source = new Vector3(Position.X, Position.Y + Height / 3.0f, Position.Z); var direction = target - source; var velocity = Vector3.Normalize(direction) * 5.0f; var cacoFireball = ActorSpawnMethods.GetSpawnMethod(ActorType.CacoFireball).Invoke(source, velocity); var spawnEvent = new ActorEvent(DoomEventType.SpawnActor, cacoFireball); var soundEvent = new SoundEvent(DoomEventType.PlaySound, FireballShootSound); var script = new ActionAnimationScriptBuilder().Name(ActorId + "shootFireball") .Segment() .OnStart(() => { FacePoint(selectedTile.GetTopCenter(), false); MessagingSystem.DispatchEvent(spawnEvent, ActorId); MessagingSystem.DispatchEvent(soundEvent, ActorId); }) .EndCondition(() => targetBoundingBox.Contains(cacoFireball.Position) == ContainmentType.Contains) .OnComplete(() => { ApplyAndDisplayDamages(damageList); cacoFireball.Die(); }) .Segment() .EndOnEvent(DoomEventType.AnimationEnd, cacoFireball.ActorId) .OnComplete(() => MessagingSystem.DispatchEvent(new DespawnActorEvent(DoomEventType.DespawnActor, cacoFireball), ActorId) ) .Build(); return script; }
public override IList<DamageResult> CalculateDamages(Level level, Tile targeted) { if (targeted.ActorInTile == null) return DamageResult.Empty; var damageResults = new List<DamageResult>(); var aoe = TileSelectorHelper.CircularSelector(level, targeted, radius).ValidTiles(); foreach (var tile in aoe) { if (tile.ActorInTile != null) { var damageResult = new DamageResult() {DamageType = DamageType.Physical}; damageResult.AffectedActor = targeted.ActorInTile; damageResult.DamageReduced = 0; damageResult.NetDamage = 250; } } return damageResults; }
public override void MakeAIDecision(Level currentLevel, Action<ActionInformation, Tile> onComplete) { var enemyOrClosest = temp_GetEnemyInRangeOrClosest(currentLevel); var ability = AbilityList.Single(x => x.AbilityDetails.AbilityName == "Fireball"); if (CanAction() && enemyOrClosest.Item2 <= 5) { onComplete(ShootFireball(currentLevel, ability.AbilityDetails), currentLevel.GetTileOfActor(enemyOrClosest.Item1)); return; } if (CanAction() && enemyOrClosest.Item2 <= CurrentStats.MovementRange + 5) { Tile moveToTile = temp_GetTileClosestToEnemy(currentLevel, enemyOrClosest.Item1); if (moveToTile != null) { onComplete(MoveToTile(currentLevel), moveToTile); } return; } onComplete(Wait(Vector3.Zero), null); }
public static Level CreateLevel(ContentManager contentManager, LevelData levelData) { InitializeDictionary(); var level = new Level(levelData.TilesLong, levelData.TilesWide); for (int i = 0; i < level.Width; i++) { for (int j = 0; j < level.Length; j++) { int index = i*level.Length + j; var tileData = levelData.TileDatas[index]; var topTexture = contentManager.Load<Texture2D>(tileData.TopTextureName); var northTexture = contentManager.Load<Texture2D>(tileData.NorthTextureName); var southTexture = contentManager.Load<Texture2D>(tileData.SouthTextureName); var eastTexture = contentManager.Load<Texture2D>(tileData.EastTextureName); var westTexture = contentManager.Load<Texture2D>(tileData.WestTextureName); var tileTextures = new TileTextures(topTexture, northTexture, southTexture, eastTexture, westTexture); Vector3 tilePosition = new Vector3(j * 64.0f, tileData.VisualHeight, i * 64.0f); var tile = new Tile(tileTextures, tilePosition, tileData.VisualHeight, j, i, tileData.YPosition); level.Tiles[index] = tile; } } foreach (var info in levelData.ActorInfos) { var actor = MakeActor(info, levelData.TileDatas, levelData.TilesLong); actor.Team = info.Team; level.Actors.Add(actor); var tile = level.Tiles.Single(t => t.XCoord == info.TileX && t.YCoord == info.TileY); tile.SetActor(actor); } level.BackgroundImage = contentManager.Load<Texture2D>(levelData.BackgroundTextureName); return level; }
public static TileSelector StandardMovementTileSelector(Level level, Tile currentTile, ActorBase actor) { var selector = new TileSelector(); int movementRange = actor.CurrentStats.MovementRange; for (int i = -movementRange; i <= movementRange; i++) { for (int j = -movementRange; j <= movementRange; j++) { if (Math.Abs(i) + Math.Abs(j) <= movementRange) { Tile t = level.GetTileAt(currentTile.XCoord + j, currentTile.YCoord + i); if (t != null && t.ActorInTile == null) { if (AStar.CalculateAStarPath(currentTile, t, level, actor) != null) { selector.AddValidTile(t); } } } } } return selector; }
private static bool CanMoveToTile(ActorBase actor, Level level, int startX, int startY, int currentX, int currentY, int candidateX, int candidateY) { if (candidateX < 0 || candidateY < 0 || candidateX >= level.Length || candidateY >= level.Width || (candidateX == startX && candidateY == startY)) { return false; } var currentTile = level.GetTileAt(currentX, currentY); var candidateTile = level.GetTileAt(candidateX, candidateY); if (Math.Abs(currentTile.GameHeight - candidateTile.GameHeight) > actor.CurrentStats.MaximumHeightCanMove) return false; if (candidateTile.ActorInTile != null && candidateTile.ActorInTile.Team != actor.Team) return false; return true; }
private static IList<Tile> CalculatePath(Tile start, Tile goal, Level level, Node[,] nodes, ActorBase actor) { nodes[start.XCoord, start.YCoord].Cost = 0; nodes[start.XCoord, start.YCoord].Depth = 0; var open = new List<Node>(); var closed = new List<Node>(); var path = new List<Tile>(); int depth = 0; open.Add(nodes[start.XCoord, start.YCoord]); while (depth < MaximumSearchDistance && (open.Count != 0)) { Node current = open[0]; if (current == nodes[goal.XCoord, goal.YCoord]) { break; } open.RemoveAt(0); closed.Add(current); for (int x = -1; x <= 1; x++) { for (int y = -1; y <= 1; y++) { if (x == 0 && y == 0) continue; if (x != 0 && y != 0) continue; int candidateX = x + current.X; int candidateY = y + current.Y; if (CanMoveToTile(actor, level, start.XCoord, start.YCoord, current.X, current.Y, candidateX, candidateY)) { float nextStepCost = current.Cost + CalculateMovementCost(actor, level, current.X, current.Y, candidateX, candidateY); Node neighbor = nodes[candidateX, candidateY]; if (nextStepCost < neighbor.Cost) { if (open.Contains(neighbor)) { open.Remove(neighbor); } if (closed.Contains(neighbor)) { closed.Remove(neighbor); } } if (!open.Contains(neighbor) && !closed.Contains(neighbor)) { neighbor.Cost = nextStepCost; neighbor.Heuristic = GetHeuristicCost(actor, level.GetTileAt(candidateX, candidateY), goal); depth = Math.Max(depth, neighbor.SetParent(current)); open.Add(neighbor); open = open.OrderBy(o => o.TotalCost()).ToList(); } } } } } if (nodes[goal.XCoord, goal.YCoord].Parent == null) return null; Node target = nodes[goal.XCoord, goal.YCoord]; while (target != nodes[start.XCoord, start.YCoord]) { path.Insert(0, level.GetTileAt(target.X, target.Y)); target = target.Parent; } path.Insert(0, start); if (path.Count > actor.CurrentStats.MovementRange + 1) return null; return path; }
private static float CalculateMovementCost(ActorBase actor, Level level, int currentX, int currentY, int candidateX, int candidateY) { var currentTile = level.GetTileAt(currentX, currentY); var candidateTile = level.GetTileAt(candidateX, candidateY); return (float)Math.Abs(currentTile.GameHeight - candidateTile.GameHeight); }
public ActionInformation MoveToTile(Level level) { Func<Tile, ActionAnimationScript> scriptGenerator = (tile) => MoveToTileAction(tile, level); TileSelector abilityRange = TileSelectorHelper.StandardMovementTileSelector(level, level.GetTileOfActor(this), this); Func<Tile, TileSelector> areaOfEffect = TileSelectorHelper.SingleTile; return new ActionInformation(scriptGenerator, abilityRange, areaOfEffect, ActionType.Move); }
public virtual void MakeAIDecision(Level currentLevel, Action<ActionInformation, Tile> onComplete) { }
private Tuple<ActorBase, int> temp_GetEnemyInRangeOrClosest(Level currentLevel) { Tuple<ActorBase, int> closestEnemy = null; foreach (var enemy in currentLevel.Actors.Where(x => x.Team != this.Team && x.IsTargetable())) { Tile enemyTile = currentLevel.GetTileOfActor(enemy); Tile myTile = currentLevel.GetTileOfActor(this); int distance = MathUtils.DistanceBetweenTiles(myTile, enemyTile); if (closestEnemy == null || distance < closestEnemy.Item2) { closestEnemy = Tuple.Create(enemy, distance); } } return closestEnemy; }
private Tile temp_GetTileClosestToEnemy(Level currentLevel, ActorBase targetActor) { var candidateTiles = TileSelectorHelper.StandardMovementTileSelector(currentLevel, currentLevel.GetTileOfActor(this), this).ValidTiles(); Tile targetTile = currentLevel.GetTileOfActor(targetActor); int distance = Int16.MaxValue; Tile moveToTile = null; foreach (var candidateTile in candidateTiles) { int candidateDistance = MathUtils.DistanceBetweenTiles(candidateTile, targetTile); if (candidateDistance < distance) { distance = candidateDistance; moveToTile = candidateTile; } } return moveToTile; }
private void CreateLevelTemp(ContentManager contentManager) { //var tempLevelData = HardcodedTestLevel.CreateLevel(); var tempLevelData = HeightTestLevel.CreateLevel(); Level = LevelFactory.CreateLevel(contentManager, tempLevelData); }
public abstract IList<DamageResult> CalculateDamages(Level level, Tile targeted);
public static TileSelector UnoccupiedTileSelector(Level level) { var tileList = level.Tiles.Where(x => x.ActorInTile == null).ToList(); return new TileSelector(tileList); }
protected virtual ActionAnimationScript MoveToTileAction(Tile goalTile, Level level) { IList<Tile> path = AStar.CalculateAStarPath(level.GetTileOfActor(this), goalTile, level, this); var script = MoveToTileScript.MakeScript(path, this); return script; }
public static TileSelector OccupiedTileSelector(Level level, ActorBase exclude) { var tileList = level.Tiles.Where(x => x.ActorInTile != null && x.ActorInTile != exclude && x.ActorInTile.IsTargetable()).ToList(); return new TileSelector(tileList); }