Пример #1
0
        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();
                }
            }
        }
Пример #2
0
        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
                });
            }
        }
Пример #3
0
        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!");
            }
        }
Пример #4
0
        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);
                });
Пример #5
0
 private void Update(object sender, CombatData combatData)
 {
     main.Combat -= Update;
     enraged      = true;
     main.WriteConsole($"{Name} has become enraged!");
 }