public Fire(int Turns, int Damage, Point Position, Point SpawnPosition, Map Map, MainGameWindow main) : base("Fire", SpawnPosition, Resources.Fire, Map, Turns, main, render: false) { //Can it actually exist? if (Map.map.Get(Position).type.FType == FieldType.water) { //Destroy it BaseDelete(); Delete(); return; } //Set position to actual position - to create effect that the mage created the fireball this.Position = Position; main.RenderMap(); damage = Damage; this.main.PlayerMoved += Main_PlayerMoved; //Check if put on position of entity List <Troop> f = Map.troops.Where(t => t.Position == Position).ToList(); if (f.Count != 0) { Player player = main.players.First(p => p.troop == f[0]); string playerName = player.Name; main.WriteConsole($"{playerName} has been put on fire!"); f[0].statuses.Add(new FireStatus(turns + 2, damage, main, player)); if (playerName == main.humanPlayer.Name) { main.UpdatePlayerView(); } } }
public override void PlayTurn(MainGameWindow main, bool singleTurn) { //Decrease spell cooldown foreach (Spell spell in spells) { spell.coolDown = spell.coolDown == 0 ? 0 : spell.coolDown - 1; } //Panic if he has been hit or player is close and he is on low health if (troop.health.Value != lastHealth || (AIUtility.Distance(troop.Position, enemies[0].troop.Position) < 4 && troop.health.Value != troop.health.MaxValue().Value)) { lastHealth = troop.health.Value; //If teleport spell is ready if (spells[1].Ready) { //Find heighest free space var HeightSorted = from field in map.map.Cast <MapTile>() where field.free where AIUtility.Distance(field.position, enemies[0].troop.Position) > 10 orderby field.Height descending select field; //Teleport spells[1].Activate(new SpellInformation() { positions = new List <Point>() { troop.Position, HeightSorted.Take(1).ToList()[0].position }, mage = this }); return; //Finish turn } else { main.WriteConsole("The wizard wimpers"); return; } } //Attack if (spells[0].Ready) { spells[0].Activate(new SpellInformation() { positions = new List <Point> { enemies[0].troop.Position }, mage = this }); } }
public void GainXP(int XP) { xp += XP; if (xp >= levelXP) { xp -= levelXP; storedLevelUps += 1; levelXP = Math.Max((int)(1.1 * levelXP), levelXP + 1); //Set Level up main.SetUpdateState(storedLevelUps > 0); //Immediate effect troop.health.RawValue = troop.health.MaxValue().Value; main.WriteConsole("Level Up! Healing to max hp!"); } }
public override void PlayTurn(MainGameWindow main, bool SingleTurn) { DistanceGraphCreator distanceGraph = new DistanceGraphCreator(this, troop.Position, map, true); Thread path = new Thread(distanceGraph.CreateGraph); DistanceGraphCreator eggGraph = new DistanceGraphCreator(this, troop.Position, map, true); Thread pathE = new Thread(eggGraph.CreateGraph); path.Start(); pathE.Start(); int damageDealt = 0; int dodged = 0; Point player = enemies[0].troop.Position; int playerDistance = AIUtility.Distance(player, troop.Position); if (!enraged && AIUtility.Distance(troop.Position, player) < 30 && AIUtility.Distance(egg, player) < 20) { enraged = true; main.WriteConsole($"{Name} has become enraged!"); main.Combat -= Update; } void AttackPlayer(bool continues = false) { bool attacked = false; //Check if it can attack player foreach (var weapon in troop.weapons) { if (playerDistance <= weapon.range && weapon.Attacks() > 0) { //Attack troop.activeWeapon = weapon; var(damage, killed, hit) = main.Attack(this, enemies[0]); damageDealt += damage; if (!hit) { dodged++; } if (killed) { map.overlayObjects.Add(new OverlayText(enemies[0].troop.Position.X * MapCreator.fieldSize, enemies[0].troop.Position.Y * MapCreator.fieldSize, Color.Red, $"-{damageDealt}")); main.PlayerDied($"You have been killed by {Name} using {weapon.name}!"); } actionPoints.RawValue--; weapon.UseWeapon(enemies[0], main); attacked = true; } } if (attacked) { AttackPlayer(true); } } if (enraged) { if (fireLineCoolDown == 0 && playerDistance > 5) { //Spew fire //Shoot fire line - will most likely not kill but be in the area Point end = new Point(player.X + (World.World.random.Next(0, 2) == 1 ? -2 : 2), player.Y + (World.World.random.Next(0, 2) == 1 ? -2 : 2)); Point diff = end.Sub(troop.Position); Point start = troop.Position.Add(diff.Div(5)); int diffX = diff.X; int diffY = diff.Y; int time = Math.Max(Math.Abs(diffX), Math.Abs(diffY)); main.actionOccuring = true; lock (map.RenderController) { for (int i = 0; i < time; i++) { Point position = new Point(Math.Max(start.X + (int)(((double)diffX / time) * i), 0), Math.Max(start.Y + (int)(((double)diffY / time) * i), 0)); new Fire(World.World.random.Next(5) + 2, 5, position, troop.Position, map, main); } } main.actionOccuring = false; fireLineCoolDown = maxFireLineCooldown; } else { fireLineCoolDown = fireLineCoolDown == 0 ? 0 : fireLineCoolDown - 1; } if (fireBombPlaces.Count != 0) { lock (map.RenderController) { main.actionOccuring = true; int appliedRadius = 2; //Fire real explosions foreach (var hit in fireBombPlaces) { for (int x = 0; x < appliedRadius * 2 + 1; x++) { for (int y = 0; y < appliedRadius * 2 + 1; y++) { //Check in bounds Point point = new Point(x + hit.X - appliedRadius, y + hit.Y - appliedRadius); if ((point.X < 0 || point.X >= map.map.GetUpperBound(0) - 1) || (point.Y < 0 || point.Y >= map.map.GetUpperBound(1) - 1)) { continue; } int dis = AIUtility.Distance(point, hit); if (dis <= appliedRadius) { //Damage fields new Fire(World.World.random.Next(0, 6), fireDamage, point, point, map, main); } } } } main.actionOccuring = false; } fireBombPlaces.Clear(); } if (fireBombCoolDown == 0) { //Summon fire explosions at certain positions - first one then ring int tries = 0; //Longerm: Create deterministic version while (tries != 100 && fireBombPlaces.Count < bombNumber) { Point test = new Point(World.World.random.Next(0, map.map.GetUpperBound(0)), World.World.random.Next(map.map.GetUpperBound(1))); if (AIUtility.Distance(test, player) < 20 && AIUtility.Distance(test, troop.Position) > 3) { fireBombPlaces.Add(test); } tries++; } if (tries == 100) { E.LogInfo("Did not find locations for fire bombs!"); } else { bombNumber++; } lock (map.RenderController) { foreach (var point in fireBombPlaces) { new Fire(World.World.random.Next(3, 8), fireDamage, point, troop.Position, map, main); } } fireBombCoolDown = maxFireBombCooldown; } else { fireBombCoolDown--; } AttackPlayer(); } //Find field to move to //If enraged go to player //If player is close to camp go to player //Else stay around camp if (actionPoints.Value == 0) { path.Abort(); pathE.Abort(); return; } Point closestField; path.Join(); pathE.Join(); DistanceGraphCreator graph = enraged || AIUtility.Distance(egg, player) < 8 ? distanceGraph : eggGraph; Point goalPos = enraged || AIUtility.Distance(egg, player) < 8 ? player : egg; if (jumpCooldown == 0 && enraged) { //Jump towards player and create earthquake closestField = AIUtility.FindClosestField(graph, goalPos, jumpDistance, map, (List <(Point point, double cost, double height)> list) => { list.Sort((o1, o2) => { double diffCost = o1.cost - o2.cost; double heightDiff = o1.height - o2.height; if (Math.Abs(diffCost) >= 1) //assume that using the weapon costs 1 action point { return(diffCost < 0 ? -1 : 1); } else if (heightDiff != 0) { return(diffCost < 0 ? -1 : 1); } return(0); }); return(list.First().point); });
private void Update(object sender, CombatData combatData) { main.Combat -= Update; enraged = true; main.WriteConsole($"{Name} has become enraged!"); }