Exemplo n.º 1
0
        /// <summary>
        /// Is this space object hidden from view of an empire due to cloaking?
        /// Space objects are hidden from view if they have at least one cloaking ability, and
        /// all cloaking abilities they possess outrank the appropriate sensors possessed by the empire in the system.
        /// However a space object must possess at least one cloaking ability to actually be cloaked.
        /// </summary>
        /// <remarks>
        /// Unlike in SE4, where cloaks must outrank sensors in five specific sight types,
        /// in FrEee, sight types are just custom strings in the data files, so cloaks must only outrank sensors
        /// in sight types that the viewing empire actually possesses in the system.
        /// Thus, a level 2 temporal cloak will hide you from enemy sight on its own, even if you don't have a
        /// level 2 psychic cloak or a level 2 foobar cloak or whatever. However if the enemy has a level 2 temporal
        /// sensor, or a level 1 sensor of any type but temporal, then they can see you.
        /// </remarks>
        /// <param name="sobj"></param>
        /// <param name="emp"></param>
        /// <returns></returns>
        public static bool IsHiddenFrom(this ISpaceObject sobj, Empire emp)
        {
            var sys     = sobj.StarSystem;
            var sec     = sobj.Sector;
            var sensors = sys.EmpireAbilities(emp).Where(a => a.Rule.Name == "Sensor Level");
            var cloaks  = sobj.Abilities().Where(a => a.Rule.Name == "Cloak Level");
            var joined  = from sensor in sensors
                          join cloak in cloaks on sensor.Value1.Value equals cloak.Value1.Value into gj
                          from subcloak in gj.DefaultIfEmpty()
                          select new
            {
                SightType   = sensor.Value1.Value,
                SensorLevel = sensor.Value2.Value.ToInt(),
                CloakLevel  = subcloak == null ? 0 : subcloak.Value2.Value.ToInt(),
            };

            int obscurationLevel = 0;

            if (sobj.CanBeObscured)
            {
                if (sobj.StarSystem.Name == "Citronelle")
                {
                }
                var so = sys.GetEmpireAbilityValue(sobj.Owner, "System - Sight Obscuration");
                obscurationLevel = new[]
                {
                    sys.GetAbilityValue("System - Sight Obscuration"),
                    so,
                    sec.GetAbilityValue("Sector - Sight Obscuration"),
                    sec.GetEmpireAbilityValue(sobj.Owner, "Sector - Sight Obscuration"),
                }.Max(a => a.ToInt());
            }
            return((cloaks.Any() || obscurationLevel > 0) && joined.All(j => j.CloakLevel > j.SensorLevel || obscurationLevel > j.SensorLevel));
        }