Пример #1
0
        /// <summary>
        /// Mets à jour l'aggro de la tour.
        /// </summary>
        void UpdateAggro()
        {
            EntityCollection entitiesInRange = GameServer.GetMap().Entities.GetAliveEntitiesInRange(this.Position, TowerRange).GetEntitiesInSight(Type);


            // Buff d'armure si pas de virus ennemis en vue.
            EntityType       eVirus   = EntityTypeConverter.ToAbsolute(EntityTypeRelative.EnnemyVirus, this.Type & (EntityType.Team1 | EntityType.Team2));
            EntityCollection eViruses = entitiesInRange.GetEntitiesByType(eVirus);
            var cst = GameServer.GetScene().Constants.Towers;

            if (eViruses.Count == 0)
            {
                BaseArmor       = cst.BuffedArmor;
                BaseMagicResist = cst.BuffedMagicResist;
            }
            else
            {
                BaseArmor       = cst.Armor;
                BaseMagicResist = cst.MagicResist;
            }


            // Si la cible sort de l'aggro : on annule l'agro.
            if (m_currentAgro != null)
            {
                if (m_currentAgro.IsDead || Vector2.DistanceSquared(m_currentAgro.Position, Position) > TowerRange * TowerRange)
                {
                    m_currentAgro = null;
                }
            }

            // Si la tour n'a pas d'aggro : on cherche la première unité Virus en range
            if (m_currentAgro == null)
            {
                EntityType ennemyVirus        = EntityTypeConverter.ToAbsolute(EntityTypeRelative.EnnemyVirus, this.Type & (EntityType.Team1 | EntityType.Team2));
                EntityBase nearestEnnemyVirus = entitiesInRange.GetEntitiesByType(ennemyVirus).NearestFrom(this.Position);
                m_currentAgro = nearestEnnemyVirus;
            }
            // Si on n'en trouve pas : on cherche le premier héros en range.
            if (m_currentAgro == null)
            {
                EntityType       ennemyHero        = EntityTypeConverter.ToAbsolute(EntityTypeRelative.EnnemyPlayer, this.Type & (EntityType.Team1 | EntityType.Team2));
                EntityCollection ennemyHeroes      = entitiesInRange.GetEntitiesByType(ennemyHero);
                EntityBase       nearestEnnemyHero = ennemyHeroes.NearestFrom(this.Position);
                m_currentAgro = nearestEnnemyHero;
            }

            if (m_currentAgro != null && !m_currentAgro.Type.HasFlag(EntityType.Player))
            {
                // Si la cible a déjà l'aggro sur quelqu'un et que ce n'est pas un héros,
                // on vérifie qu'un des alliés n'est pas attaqué par un héros adverse.
                // Si un allié est attaqué par un héros, la tour aggro le héros qui l'a attaquée.
                EntityType       allyHeroType   = EntityTypeConverter.ToAbsolute(EntityTypeRelative.AllyPlayer, this.Type & (EntityType.Team1 | EntityType.Team2));
                EntityType       ennemyHeroType = EntityTypeConverter.ToAbsolute(EntityTypeRelative.EnnemyPlayer, this.Type & (EntityType.Team1 | EntityType.Team2));
                EntityCollection allyHeroes     = entitiesInRange.GetEntitiesByType(allyHeroType);

                // Pour tous les héros alliés, on regarde s'ils n'ont pas été attaqués recemment par des héros
                // ennemis.
                foreach (var kvp in allyHeroes)
                {
                    EntityBase       allyHero        = kvp.Value;
                    EntityCollection aggressiveHeros = allyHero.GetRecentlyAgressiveEntities(1.0f).GetEntitiesByType(ennemyHeroType);
                    if (aggressiveHeros.Count != 0)
                    {
                        EntityBase aggressiveHero = aggressiveHeros.First().Value;
                        m_currentAgro = aggressiveHero;
                    }
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Mets à jour l'aggro du Virus.
        /// </summary>
        void UpdateAggro(GameTime time)
        {
            // Vérification du délai d'update
            // Ce délai est mis en place pour des questions de performances.
            __updateAgroDelay -= (float)time.ElapsedGameTime.TotalSeconds;
            if (__updateAgroDelay > 0)
            {
                return;
            }

            // Mise à jour du délai d'update
            float margin = AggroUpdateDelay * AggroUpdateDelayMargin;

            __updateAgroDelay = AggroUpdateDelay + ((float)s_random.NextDouble() - 0.5f) * margin;


            // Commencement de l'update.
            EntityCollection entitiesInRange = GameServer.GetMap().Entities.GetAliveEntitiesInRange(this.Position, AttackRange).GetEntitiesInSight(Type & EntityType.Teams);
            EntityBase       oldAggro        = m_currentAgro;

            if (m_currentAgro != null && (m_currentAgro.IsDead || !HasSightOn(m_currentAgro)))
            {
                m_currentAgro = null;
            }

            // Si la Virus n'a pas d'aggro : on cherche la première unité Virus en range
            EntityType ennemyVirusType    = EntityTypeConverter.ToAbsolute(EntityTypeRelative.EnnemyVirus, this.Type & (EntityType.Team1 | EntityType.Team2));
            EntityBase nearestEnnemyVirus = entitiesInRange.GetEntitiesByType(ennemyVirusType).NearestFrom(this.Position);

            if (nearestEnnemyVirus != null)
            {
                m_currentAgro = nearestEnnemyVirus;
            }

            // S'il n'y a pas de Virus ennemi en range, on regarde si il y a une tour en range.
            EntityType ennemyTower  = EntityTypeConverter.ToAbsolute(EntityTypeRelative.EnnemyTower, this.Type & (EntityType.Team1 | EntityType.Team2));
            EntityBase nearestTower = entitiesInRange.GetEntitiesByType(ennemyTower).NearestFrom(this.Position);

            if (nearestTower != null)
            {
                m_currentAgro = nearestTower;
            }

            // Datacenter
            EntityType ennemyDatacenter  = EntityTypeConverter.ToAbsolute(EntityTypeRelative.EnnemyDatacenter, this.Type & (EntityType.Team1 | EntityType.Team2));
            EntityBase nearestDatacenter = entitiesInRange.GetEntitiesByType(ennemyDatacenter).NearestFrom(this.Position);

            if (nearestDatacenter != null)
            {
                m_currentAgro = nearestDatacenter;
            }

            // Si on n'en trouve pas : on cherche le premier héros en range.
            EntityType ennemyHero        = EntityTypeConverter.ToAbsolute(EntityTypeRelative.EnnemyPlayer, this.Type & (EntityType.Team1 | EntityType.Team2));
            EntityBase nearestEnnemyHero = entitiesInRange.GetEntitiesByType(ennemyHero).NearestFrom(this.Position);

            if (nearestEnnemyHero != null)
            {
                m_currentAgro = nearestEnnemyHero;
            }

            // Avance au checkpoint suivant si on a atteint le précédent ou qu'on a rien trouvé à aggro.
            if (m_currentAgro == null || (m_currentAgro.Type.HasFlag(EntityType.Checkpoint) && HasReachedPosition(m_currentAgro.Position, time, GetMoveSpeed())))
            {
                //bool __debugPositionReached = HasReachedPosition(m_currentAgro.Position, time, GetMoveSpeed());
                EntityType       allycp      = EntityTypeConverter.ToAbsolute(EntityTypeRelative.AllyCheckpoint, this.Type);
                EntityCollection checkpoints = GameServer.GetMap().Entities.GetEntitiesByType(allycp);

                // Obtient le checkpoint suivant le plus proche.
                float      minDistanceSqr = float.MaxValue;
                EntityBase next           = m_currentAgro;
                foreach (var kvp in checkpoints)
                {
                    EntityCheckpoint cp = (EntityCheckpoint)kvp.Value;

                    // On ne considère pas les checkpoints qui ne sont pas dans notre rangée.
                    if (cp.CheckpointRow != Row)
                    {
                        continue;
                    }

                    // On prend le + proche des checkpoints suivants.
                    float dstSqr = Vector2.DistanceSquared(cp.Position, Position);
                    if ((cp.CheckpointID > m_currentCheckpointId ||
                         (m_currentAgro == null && cp.CheckpointID >= m_currentCheckpointId)) &&
                        dstSqr < minDistanceSqr)
                    {
                        minDistanceSqr = dstSqr;
                        next           = cp;
                    }
                }
                if (next != null)
                {
                    m_currentCheckpointId = ((EntityCheckpoint)next).CheckpointID;
                }
                m_currentAgro = next;
            }


            // Si l'aggro bouge, on recalcule l'A*.
            if (m_currentAgro != null && Vector2.DistanceSquared(m_currentAgro.Position, m_currentAggroOldPos) > 1)
            {
                m_currentAggroOldPos = m_currentAgro.Position;
                ComputePath();
            }

            // Si on change d'aggro, retourne le chemin vers la tour la plus proche.
            if (m_currentAgro != oldAggro)
            {
                ComputePath();
            }
        }