Example #1
0
        private List <TDEntity> GetTowersInRange(TDLocation loc, int Radius, bool IncludeTowers, bool IncludeAttackers)
        {
            List <TDEntity> towersInRange = new List <TDEntity>();

            if (IncludeAttackers)
            {
                foreach (TDAttacker a in TDSession.thisSession.CurrentLevel.Attackers)
                {
                    if (TDMath.PointInRange(loc, a.Location, Radius))
                    {
                        towersInRange.Add(a);
                    }
                }
            }
            if (IncludeTowers)
            {
                foreach (TDTower t in TDSession.thisSession.CurrentLevel.Towers)
                {
                    if (TDMath.PointInRange(loc, t.Location, Radius))
                    {
                        towersInRange.Add(t);
                    }
                }
            }

            return(towersInRange);
        }
Example #2
0
        private AttackerTypes GetWeightedAttackerType(bool AllowBoss)
        {
            int d = TDMath.D(100);

            if (d < 25)
            {
                return(AttackerTypes.Goblin);
            }
            else if (d < 50)
            {
                return(AttackerTypes.GoblinArcher);
            }
            else if (d < 75)
            {
                return(AttackerTypes.Orc);
            }
            else if (d < 95 || (AllowBoss == false)) // boss number will default to troll
            {
                return(AttackerTypes.Troll);
            }
            else // d >= 95
            {
                return(AttackerTypes.Boss);
            }
        }
Example #3
0
        public bool isTowerOnPath(TDTower t)
        {
            // first check if intersting any corner
            TDPathPoint lastPoint = null;

            foreach (TDPath p in this.Paths)
            {
                foreach (TDPathPoint pp in p.PathPoints)
                {
                    if (TDMath.Intersects(t.Location, t.Size, pp.Location, GridSize))
                    {
                        return(true);
                    }
                    else
                    {
                        // check intersecting any line
                        if (lastPoint != null)
                        {
                            if (TDMath.Intersects(t, pp, lastPoint))
                            {
                                return(true);
                            }
                        }

                        lastPoint = pp;
                    }
                }
            }

            return(false);
        }
Example #4
0
        private TDEntity GetTowerAtPoint(Point point)
        {
            if (TDSession.thisSession == null ||
                TDSession.thisSession.CurrentLevel == null)
            {
                return(null);
            }

            TDLocation p = new TDLocation(point.X, point.Y);

            foreach (TDAttacker a in TDSession.thisSession.CurrentLevel.Attackers)
            {
                if (TDMath.PointOnPoint(a.Location, p, a.Size))
                {
                    return(a);
                }
            }

            foreach (TDTower t in TDSession.thisSession.CurrentLevel.Towers)
            {
                if (TDMath.PointOnPoint(t.Location, p, t.Size))
                {
                    return(t);
                }
            }

            // if not a tower or attacker, then nothing
            return(null);
        }
Example #5
0
        internal bool isTowerOnTowers(TDTower target)
        {
            foreach (TDTower t in this.Towers)
            {
                if (TDMath.Intersects(target.Location, target.Size, t.Location, t.Size))
                {
                    return(true);
                }
            }

            return(false);
        }
Example #6
0
        public void Update()
        {
            // if on target
            if (this.Seeking &&
                TDMath.PointOnPoint(this.CurrentLocation, target.Location, (int)(this.speed * TDSession.SpeedFactor)))
            {
                HitTarget(target as TDEntity);
            }
            else
            {
                // if on any target type
                if (target is TDAttacker)
                {
                    // hit any target
                    for (int i = 0; i < TDSession.thisSession.CurrentLevel.Attackers.Count; i++)
                    {
                        if (TDSession.thisSession.CurrentLevel.Attackers[i] != this.source &&
                            TDMath.PointOnPoint(this.CurrentLocation,
                                                TDSession.thisSession.CurrentLevel.Attackers[i].Location,
                                                TDSession.thisSession.CurrentLevel.Attackers[i].Size))
                        {
                            HitTarget(TDSession.thisSession.CurrentLevel.Attackers[i] as TDEntity);
                            break;
                        }
                    }
                }
                else // if target is TDTower
                {
                    // hit any tower
                    for (int i = 0; i < TDSession.thisSession.CurrentLevel.Towers.Count; i++)
                    {
                        if (TDMath.PointOnPoint(this.CurrentLocation,
                                                TDSession.thisSession.CurrentLevel.Towers[i].Location,
                                                TDSession.thisSession.CurrentLevel.Towers[i].Size))
                        {
                            HitTarget(TDSession.thisSession.CurrentLevel.Towers[i] as TDEntity);
                            break;
                        }
                    }
                }

                // move toward target
                MoveToward(target.Location);
            }
        }
Example #7
0
        private TDAttacker GetFarAttacker(List <TDAttacker> atts)
        {
            TDAttacker result        = atts[0];
            double     farthestRange = 0;
            double     rangeToThis   = 0;

            foreach (TDAttacker a in atts)
            {
                rangeToThis = TDMath.RangeToTarget(this.Location, a.Location);
                if (rangeToThis > farthestRange)
                {
                    farthestRange = rangeToThis;
                    result        = a;
                }
            }

            return(result);
        }
Example #8
0
        private TDAttacker GetCloseAttacker(List <TDAttacker> atts)
        {
            TDAttacker result       = atts[0];
            double     closestRange = 0;
            double     rangeToThis  = 0;

            foreach (TDAttacker a in atts)
            {
                rangeToThis = TDMath.RangeToTarget(this.Location, a.Location);
                if (closestRange == 0 ||
                    rangeToThis < closestRange)
                {
                    closestRange = rangeToThis;
                    result       = a;
                }
            }

            return(result);
        }
Example #9
0
        private void HitTarget(TDEntity entity)
        {
            #region splash
            if (this.SplashRadius > 0)
            {
                DamageRadius(target.Location, this.SplashRadius);

                // spawn a new explosion
                TDSession.thisSession.CurrentLevel.Explosions.Add(new TDExplosion(entity.Location, this.SplashRadius));
            }
            #endregion
            else // not splash
            {
                entity.HPCurrent -= this.damage;

                // apply any effects
                if (this.Effects != null &&
                    this.Effects.Count > 0)
                {
                    foreach (TDEffect e in this.Effects)
                    {
                        entity.Effects.Add(new TDEffect(e.Effect, e.Power, e.Duration, true));
                    }
                }
            }

            #region Chaining
            if (this.ChainCount > 0)
            {
                // find the next closest attacker, not the source
                List <TDEntity> newTargets = GetTowersInRange(entity.Location, this.ChainDist, false, true);

                // don't hit this source.
                if (newTargets.Contains(this.source))
                {
                    newTargets.Remove(this.source);
                }

                // and don't hit this new target itself
                if (newTargets.Contains(entity))
                {
                    newTargets.Remove(entity);
                }

                if (newTargets.Count > 0)
                {
                    // get a random target within this range
                    TDEntity newTarget = newTargets[TDMath.D(newTargets.Count) - 1];

                    // make a new ammo from this one,
                    TDAmmo newAmmo = new TDAmmo(entity, newTarget); // start from this target hit

                    // reduce the chain count
                    newAmmo.ChainDist  = this.ChainDist;
                    newAmmo.ChainCount = this.ChainCount - 1;
                    newAmmo.damage     = Math.Max(1, this.damage - 1); // override the damage with the chain decline
                    TDSession.thisSession.CurrentLevel.Ammo.Add(newAmmo);
                }
            }
            #endregion

            // since ammo dies automatically
            this.DeleteMe = true;
        }
Example #10
0
        private void GenerateAttackersForLevel(int lvl, List <TDPath> Paths)
        {
            // waves
            this._WaveCount = 9 + (lvl);

            if (testing)
            {
                _WaveCount = 0;
            }

            // wave attacker type
            bool mixed = (TDMath.D(100) > 70); // 30% mixed

            // attackers per wave
            int attPerWave = 5 + TDMath.D(10 * lvl);

            if (testing)
            {
                attPerWave = 0;
            }

            // if 80, then betwen 41 and 80;
            int ThisWaveDelay = (WaveDelay / 2) + TDMath.D(WaveDelay / 2);

            if (testing)
            {
                ThisWaveDelay = WaveDelay;
            }

            int MaxDelay = 0;

            // for each wave
            for (int i = 0; i < this._WaveCount; i++)
            {
                // set the type and path for this wave
                AttackerTypes t = GetWeightedAttackerType(false);
                TDPath        p = Paths[TDMath.D(Paths.Count) - 1];

                // vary the attacker separation for this wave (between 1/2 and full value)
                int AttackerDelayWithinThisWave = (AttackerDelayWithinWave / 2) + TDMath.D((AttackerDelayWithinWave / 2));

                if (testing)
                {
                    AttackerDelayWithinThisWave = AttackerDelayWithinWave;
                }

                for (int j = 0; j < attPerWave; j++)
                {
                    // check for mixed attacker type
                    if (mixed && lvl > 3) // don't mix until lvl 4+
                    {
                        // randomized the type for the next attacker
                        t = GetWeightedAttackerType(true);
                        p = Paths[TDMath.D(Paths.Count) - 1];
                    }

                    // generate the new attacker
                    TDAttacker a = new TDAttacker(t, lvl);
                    a.WaveIndex = i + 1;

                    int delayMS = Math.Max(1, (i * ThisWaveDelay) + (j * AttackerDelayWithinThisWave)); // slightly stagger each attacker within the wave (j)
                    a.Effects.Add(new TDEffect(TDEffectTypes.WaveDelay, 0, new TimeSpan(0, 0, 0, 0, delayMS), false));
                    a.SetPath(p);

                    this.Attackers.Add(a);

                    // remember the MaxDelay for the Boss
                    MaxDelay = Math.Max(MaxDelay, delayMS);
                }
            }

            // and finally, add the level boss
            TDAttacker boss = new TDAttacker(AttackerTypes.Boss, lvl + 10);

            boss.Size     += 4;
            boss.HPMax     = boss.HPMax * 6;
            boss.HPCurrent = boss.HPMax;
            int AdditionalBossDelay = 500;

            if (testing)
            {
                AdditionalBossDelay = 10000;
            }
            boss.Effects.Add(new TDEffect(TDEffectTypes.WaveDelay, 0, new TimeSpan(0, 0, 0, 0, MaxDelay + AdditionalBossDelay), false)); // 1/2 second after last attacker
            TDPath pBoss = Paths[TDMath.D(Paths.Count) - 1];

            boss.SetPath(pBoss);
            this.Attackers.Add(boss);
        }
Example #11
0
 private bool AttackerrWithinRange(TDAttacker a)
 {
     return(TDMath.PointInRange(this.Location, a.Location, this.Range));
 }
Example #12
0
 private bool TowerWithinRange(TDTower tower)
 {
     return(TDMath.PointInRange(this.Location, tower.Location, this.Range));
 }
Example #13
0
 private bool OnPoint(TDLocation L1, TDLocation L2)
 {
     return(TDMath.PointOnPoint(L1, L2, (int)Math.Max(1, this.SpeedCurrent * TDSession.SpeedFactor)));
 }
Example #14
0
 public double DistanceToNextPoint()
 {
     return(TDMath.RangeToTarget(this.Location, this.Path.PathPoints[NextPoint].Location));
 }
Example #15
0
        public override void Update()
        {
            if (this.CanStart && this.Immune)
            {
                this.Immune = false;
                // update the next wave to be at least this index.
                TDSession.thisSession.CurrentLevel.WaveStarted = Math.Max(this.WaveIndex, TDSession.thisSession.CurrentLevel.WaveStarted);
            }

            // apply any effects
            if (this.Effects != null &&
                this.Effects.Count > 0)
            {
                foreach (TDEffect e in this.Effects)
                {
                    if (e.Effect == TDEffectTypes.WaveDelay)
                    {
                        if (e.State == TDEffect.TDTimerState.Finished)
                        {
                            e.HasBeenApplied = true;
                            this.CanStart    = true;
                        }
                        else if (e.State == TDEffect.TDTimerState.Running && e.DurationRemaining.TotalMilliseconds < 0)
                        {
                            e.State = TDEffect.TDTimerState.Finished;
                            return;
                        }
                        else
                        {
                            // if we have not finished this effect, then we can't start yet. (or do anything else).
                            return;
                        }
                    }

                    #region Slow
                    if (e.Effect == TDEffectTypes.Slow)
                    {
                        if (e.State == TDEffect.TDTimerState.Running)
                        {
                            // slow only applies once
                            if (!e.HasBeenApplied)
                            {
                                // change current speed to effect.
                                this.SpeedCurrent = (this.SpeedMax * (100 - (double)e.Power) / 100);
                                e.HasBeenApplied  = true;
                            }
                        }
                        else if (e.State == TDEffect.TDTimerState.Finished)
                        {
                            // only edit if the effect is still applied
                            if (e.HasBeenApplied)
                            {
                                // set the speed back to normal
                                this.SpeedCurrent = this.SpeedMax;
                                // tell the system we have undid the speed change
                                e.HasBeenApplied = false;
                            }
                        }
                    } // end slow
                    #endregion
                }
            }

            // next point
            if (OnPoint(this.Location, this.Path.PathPoints[NextPoint].Location))
            {
                // change destination to the next point on the path.
                NextPoint++;

                // if on last point, then damage lvl HP
                if (NextPoint >= Path.PathPoints.Count)
                {
                    TDSession.thisSession.CurrentLevel.HPRemaining -= this.HPCurrent;
                    this.Cost = 0; // no loot for an enemy crashing into your base!
                    DeleteMe  = true;
                    return;
                }
            }

            // move toward point
            MoveToward(this.Path.PathPoints[NextPoint].Location);

            // check cooldown to see if can fire
            if (DateTime.Now > this.LastFire + new TimeSpan(0, 0, 0, 0, (int)(this.Cooldown.TotalMilliseconds / TDSession.SpeedFactor)))
            {
                // we can, so see if any towers in range
                List <TDTower> towersInRange = GetTowersInRange();

                // check towers in range to fire at
                if (towersInRange.Count == 0)
                {
                    // do nothing - no towers
                }
                else
                {
                    // only have a chance to shoot this update (makes the firing more random)
                    if (TDMath.D(100) > 97)
                    {
                        if (towersInRange.Count == 1)
                        {
                            // if one is the destination tower, hit it
                            ShootAtTower(towersInRange[0]);
                        }
                        else if (towersInRange.Count > 1)
                        {
                            // if multiples
                            // future: pick a tower (weakest, strongest, first?)

                            // for now, just shoot the first one
                            ShootAtTower(towersInRange[0]);
                        }

                        LastFire = DateTime.Now;
                    }
                } // end else - are towers in range
            }
        }