Fix CA1851
This commit is contained in:
@@ -196,8 +196,8 @@ namespace OpenRA.Mods.Common.Activities
|
||||
|
||||
// Update ranges. Exclude paused armaments except when ALL weapons are paused
|
||||
// (e.g. out of ammo), in which case use the paused, valid weapon with highest range.
|
||||
var activeArmaments = armaments.Where(x => !x.IsTraitPaused);
|
||||
if (activeArmaments.Any())
|
||||
var activeArmaments = armaments.Where(x => !x.IsTraitPaused).ToList();
|
||||
if (activeArmaments.Count != 0)
|
||||
{
|
||||
minRange = activeArmaments.Max(a => a.Weapon.MinRange);
|
||||
maxRange = activeArmaments.Min(a => a.MaxRange());
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Lint
|
||||
@@ -21,8 +20,8 @@ namespace OpenRA.Mods.Common.Lint
|
||||
{
|
||||
foreach (var actorInfo in rules.Actors)
|
||||
{
|
||||
var selectable = actorInfo.Value.TraitInfos<SelectableInfo>().Count();
|
||||
var interactable = actorInfo.Value.TraitInfos<InteractableInfo>().Count();
|
||||
var selectable = actorInfo.Value.TraitInfos<SelectableInfo>().Count;
|
||||
var interactable = actorInfo.Value.TraitInfos<InteractableInfo>().Count;
|
||||
if (selectable > 0 && selectable != interactable)
|
||||
emitWarning($"Actor `{actorInfo.Value.Name}` defines both Interactable and Selectable traits. This may cause unexpected results.");
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace OpenRA.Mods.Common.Lint
|
||||
try
|
||||
{
|
||||
var visibilityTypes = actorInfo.Value.TraitInfos<IDefaultVisibilityInfo>();
|
||||
var count = visibilityTypes.Count();
|
||||
var count = visibilityTypes.Count;
|
||||
|
||||
if (count == 0)
|
||||
emitError($"Actor type `{actorInfo.Key}` does not define a default visibility type.");
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Server;
|
||||
using OpenRA.Traits;
|
||||
@@ -41,7 +40,7 @@ namespace OpenRA.Mods.Common.Lint
|
||||
continue;
|
||||
|
||||
var hitShapes = actorInfo.Value.TraitInfos<HitShapeInfo>();
|
||||
if (!hitShapes.Any())
|
||||
if (hitShapes.Count == 0)
|
||||
emitError($"Actor type `{actorInfo.Key}` has a Health trait but no HitShape trait.");
|
||||
}
|
||||
catch (InvalidOperationException e)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Server;
|
||||
@@ -32,12 +33,15 @@ namespace OpenRA.Mods.Common.Lint
|
||||
static void Run(Action<string> emitError, Ruleset rules)
|
||||
{
|
||||
var worldActor = rules.Actors[SystemActors.World];
|
||||
var locomotorInfos = worldActor.TraitInfos<LocomotorInfo>().ToArray();
|
||||
foreach (var li in locomotorInfos)
|
||||
foreach (var otherLocomotor in locomotorInfos)
|
||||
if (li != otherLocomotor && li.Name == otherLocomotor.Name)
|
||||
emitError($"More than one Locomotor exists with the name `{li.Name}`.");
|
||||
var locomotorNames = worldActor.TraitInfos<LocomotorInfo>().Select(li => li.Name).ToList();
|
||||
var duplicateNames = locomotorNames
|
||||
.GroupBy(name => name)
|
||||
.Where(g => g.Count() > 1)
|
||||
.Select(g => g.Key);
|
||||
foreach (var duplicateName in duplicateNames)
|
||||
emitError($"More than one Locomotor exists with the name `{duplicateName}`.");
|
||||
|
||||
var locomotorNamesSet = locomotorNames.ToHashSet();
|
||||
foreach (var actorInfo in rules.Actors)
|
||||
{
|
||||
foreach (var traitInfo in actorInfo.Value.TraitInfos<TraitInfo>())
|
||||
@@ -51,16 +55,16 @@ namespace OpenRA.Mods.Common.Lint
|
||||
if (string.IsNullOrEmpty(locomotor))
|
||||
continue;
|
||||
|
||||
CheckLocomotors(actorInfo.Value, emitError, locomotorInfos, locomotor);
|
||||
CheckLocomotors(actorInfo.Value, emitError, locomotorNamesSet, locomotor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void CheckLocomotors(ActorInfo actorInfo, Action<string> emitError, LocomotorInfo[] locomotorInfos, string locomotor)
|
||||
static void CheckLocomotors(ActorInfo actorInfo, Action<string> emitError, HashSet<string> locomotorNames, string locomotor)
|
||||
{
|
||||
if (!locomotorInfos.Any(l => l.Name == locomotor))
|
||||
if (!locomotorNames.Contains(locomotor))
|
||||
emitError($"Actor `{actorInfo.Name}` defines Locomotor `{locomotor}` not found on World actor.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,10 +32,12 @@ namespace OpenRA.Mods.Common.Lint
|
||||
{
|
||||
foreach (var actorInfo in rules.Actors)
|
||||
{
|
||||
var wsbs = actorInfo.Value.TraitInfos<WithSpriteBodyInfo>();
|
||||
foreach (var wsb in wsbs)
|
||||
if (wsbs.Any(w => w != wsb && w.Name == wsb.Name))
|
||||
emitError($"Actor type `{actorInfo.Key}` has more than one *SpriteBody with Name: {wsb.Name}.");
|
||||
var duplicateNames = actorInfo.Value.TraitInfos<WithSpriteBodyInfo>()
|
||||
.GroupBy(wsb => wsb.Name)
|
||||
.Where(g => g.Count() > 1)
|
||||
.Select(g => g.Key);
|
||||
foreach (var duplicateName in duplicateNames)
|
||||
emitError($"Actor type `{actorInfo.Key}` has more than one *SpriteBody with Name: {duplicateName}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,13 +50,13 @@ namespace OpenRA.Mods.Common.Orders
|
||||
.Where(o => o != null)
|
||||
.ToList();
|
||||
|
||||
var actorsInvolved = orders.Select(o => o.Actor).Distinct();
|
||||
if (!actorsInvolved.Any())
|
||||
var actorsInvolved = orders.Select(o => o.Actor).Distinct().ToArray();
|
||||
if (actorsInvolved.Length == 0)
|
||||
yield break;
|
||||
|
||||
// HACK: This is required by the hacky player actions-per-minute calculation
|
||||
// TODO: Reimplement APM properly and then remove this
|
||||
yield return new Order("CreateGroup", actorsInvolved.First().Owner.PlayerActor, false, actorsInvolved.ToArray());
|
||||
yield return new Order("CreateGroup", actorsInvolved.First().Owner.PlayerActor, false, actorsInvolved);
|
||||
|
||||
foreach (var o in orders)
|
||||
yield return CheckSameOrder(o.Order, o.Trait.IssueOrder(o.Actor, o.Order, o.Target, mi.Modifiers.HasModifier(Modifiers.Shift)));
|
||||
@@ -165,7 +165,8 @@ namespace OpenRA.Mods.Common.Orders
|
||||
var orders = self.TraitsImplementing<IIssueOrder>()
|
||||
.SelectMany(trait => trait.Orders.Select(x => new { Trait = trait, Order = x }))
|
||||
.Select(x => x)
|
||||
.OrderByDescending(x => x.Order.OrderPriority);
|
||||
.OrderByDescending(x => x.Order.OrderPriority)
|
||||
.ToList();
|
||||
|
||||
for (var i = 0; i < 2; i++)
|
||||
{
|
||||
|
||||
@@ -245,7 +245,7 @@ namespace OpenRA.Mods.Common.Scripting
|
||||
foreach (var actorType in actorTypes.Distinct())
|
||||
typeToQueueMap.Add(actorType, GetBuildableInfo(actorType).Queue.First());
|
||||
|
||||
var queueTypes = typeToQueueMap.Values.Distinct();
|
||||
var queueTypes = typeToQueueMap.Values.Distinct().ToList();
|
||||
|
||||
if (queueTypes.Any(t => !queues.ContainsKey(t) || productionHandlers.ContainsKey(t)))
|
||||
return false;
|
||||
|
||||
@@ -748,10 +748,11 @@ namespace OpenRA.Mods.Common.Server
|
||||
teamCount = teamCount.Clamp(0, maxTeams);
|
||||
var clients = server.LobbyInfo.Slots
|
||||
.Select(slot => server.LobbyInfo.ClientInSlot(slot.Key))
|
||||
.Where(c => c != null && !server.LobbyInfo.Slots[c.Slot].LockTeam);
|
||||
.Where(c => c != null && !server.LobbyInfo.Slots[c.Slot].LockTeam)
|
||||
.ToList();
|
||||
|
||||
var assigned = 0;
|
||||
var clientCount = clients.Count();
|
||||
var clientCount = clients.Count;
|
||||
foreach (var player in clients)
|
||||
{
|
||||
// Free for all
|
||||
|
||||
@@ -41,8 +41,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
else
|
||||
{
|
||||
var owner = map.PlayerDefinitions.Single(p => s.Get<OwnerInit>().InternalName == p.Value.Nodes.Last(k => k.Key == "Name").Value.Value);
|
||||
var colorValue = owner.Value.Nodes.Where(n => n.Key == "Color");
|
||||
var ownerColor = colorValue.Any() ? colorValue.First().Value.Value : "FFFFFF";
|
||||
var colorValue = owner.Value.Nodes.FirstOrDefault(n => n.Key == "Color");
|
||||
var ownerColor = colorValue?.Value.Value ?? "FFFFFF";
|
||||
Color.TryParse(ownerColor, out color);
|
||||
}
|
||||
|
||||
|
||||
@@ -445,15 +445,15 @@ namespace OpenRA.Mods.Common.Traits
|
||||
modifiers |= TargetModifiers.ForceAttack;
|
||||
|
||||
var forceAttack = modifiers.HasModifier(TargetModifiers.ForceAttack);
|
||||
var armaments = ab.ChooseArmamentsForTarget(target, forceAttack);
|
||||
if (!armaments.Any())
|
||||
return false;
|
||||
|
||||
// Use valid armament with highest range out of those that have ammo
|
||||
// If all are out of ammo, just use valid armament with highest range
|
||||
armaments = armaments.OrderByDescending(x => x.MaxRange());
|
||||
var a = armaments.FirstOrDefault(x => !x.IsTraitPaused);
|
||||
a ??= armaments.First();
|
||||
var a = ab.ChooseArmamentsForTarget(target, forceAttack)
|
||||
.OrderBy(x => x.IsTraitPaused)
|
||||
.ThenByDescending(x => x.MaxRange())
|
||||
.FirstOrDefault();
|
||||
if (a == null)
|
||||
return false;
|
||||
|
||||
var outOfRange = !target.IsInRange(self.CenterPosition, a.MaxRange()) ||
|
||||
(!forceAttack && target.Type == TargetType.FrozenActor && !ab.Info.TargetFrozenActors);
|
||||
@@ -482,15 +482,15 @@ namespace OpenRA.Mods.Common.Traits
|
||||
return false;
|
||||
|
||||
var target = Target.FromCell(self.World, location);
|
||||
var armaments = ab.ChooseArmamentsForTarget(target, true);
|
||||
if (!armaments.Any())
|
||||
return false;
|
||||
|
||||
// Use valid armament with highest range out of those that have ammo
|
||||
// If all are out of ammo, just use valid armament with highest range
|
||||
armaments = armaments.OrderByDescending(x => x.MaxRange());
|
||||
var a = armaments.FirstOrDefault(x => !x.IsTraitPaused);
|
||||
a ??= armaments.First();
|
||||
var a = ab.ChooseArmamentsForTarget(target, true)
|
||||
.OrderBy(x => x.IsTraitPaused)
|
||||
.ThenByDescending(x => x.MaxRange())
|
||||
.FirstOrDefault();
|
||||
if (a == null)
|
||||
return false;
|
||||
|
||||
cursor = !target.IsInRange(self.CenterPosition, a.MaxRange())
|
||||
? ab.Info.OutsideRangeCursor ?? a.Info.OutsideRangeCursor
|
||||
|
||||
@@ -163,7 +163,7 @@ namespace OpenRA.Mods.Common.Traits.BotModules.Squads
|
||||
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule(rule));
|
||||
}
|
||||
|
||||
public bool CanAttack(IEnumerable<Actor> ownUnits, IEnumerable<Actor> enemyUnits)
|
||||
public bool CanAttack(IReadOnlyCollection<Actor> ownUnits, IReadOnlyCollection<Actor> enemyUnits)
|
||||
{
|
||||
double attackChance;
|
||||
var inputValues = new Dictionary<FuzzyVariable, double>();
|
||||
@@ -201,7 +201,7 @@ namespace OpenRA.Mods.Common.Traits.BotModules.Squads
|
||||
return (int)((long)sumOfHp * normalizeByValue / sumOfMaxHp);
|
||||
}
|
||||
|
||||
static float RelativePower(IEnumerable<Actor> own, IEnumerable<Actor> enemy)
|
||||
static float RelativePower(IReadOnlyCollection<Actor> own, IReadOnlyCollection<Actor> enemy)
|
||||
{
|
||||
return RelativeValue(own, enemy, 100, SumOfValues<AttackBaseInfo>, a =>
|
||||
{
|
||||
@@ -225,18 +225,18 @@ namespace OpenRA.Mods.Common.Traits.BotModules.Squads
|
||||
});
|
||||
}
|
||||
|
||||
static float RelativeSpeed(IEnumerable<Actor> own, IEnumerable<Actor> enemy)
|
||||
static float RelativeSpeed(IReadOnlyCollection<Actor> own, IReadOnlyCollection<Actor> enemy)
|
||||
{
|
||||
return RelativeValue(own, enemy, 100, Average<MobileInfo>, (Actor a) => a.Info.TraitInfo<MobileInfo>().Speed);
|
||||
}
|
||||
|
||||
static float RelativeValue(IEnumerable<Actor> own, IEnumerable<Actor> enemy, float normalizeByValue,
|
||||
Func<IEnumerable<Actor>, Func<Actor, int>, float> relativeFunc, Func<Actor, int> getValue)
|
||||
static float RelativeValue(IReadOnlyCollection<Actor> own, IReadOnlyCollection<Actor> enemy, float normalizeByValue,
|
||||
Func<IReadOnlyCollection<Actor>, Func<Actor, int>, float> relativeFunc, Func<Actor, int> getValue)
|
||||
{
|
||||
if (!enemy.Any())
|
||||
if (enemy.Count == 0)
|
||||
return 999.0f;
|
||||
|
||||
if (!own.Any())
|
||||
if (own.Count == 0)
|
||||
return 0.0f;
|
||||
|
||||
var relative = relativeFunc(own, getValue) / relativeFunc(enemy, getValue) * normalizeByValue;
|
||||
|
||||
@@ -22,9 +22,9 @@ namespace OpenRA.Mods.Common.Traits.BotModules.Squads
|
||||
|
||||
protected const int MissileUnitMultiplier = 3;
|
||||
|
||||
protected static int CountAntiAirUnits(IEnumerable<Actor> units)
|
||||
protected static int CountAntiAirUnits(IReadOnlyCollection<Actor> units)
|
||||
{
|
||||
if (!units.Any())
|
||||
if (units.Count == 0)
|
||||
return 0;
|
||||
|
||||
var missileUnitsCount = 0;
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace OpenRA.Mods.Common.Traits.BotModules.Squads
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual bool ShouldFlee(Squad squad, Func<IEnumerable<Actor>, bool> flee)
|
||||
protected virtual bool ShouldFlee(Squad squad, Func<IReadOnlyCollection<Actor>, bool> flee)
|
||||
{
|
||||
if (!squad.IsValid)
|
||||
return false;
|
||||
@@ -95,8 +95,10 @@ namespace OpenRA.Mods.Common.Traits.BotModules.Squads
|
||||
if (u.Owner == squad.Bot.Player && u.Info.HasTraitInfo<BuildingInfo>())
|
||||
return false;
|
||||
|
||||
var enemyAroundUnit = units.Where(unit => squad.SquadManager.IsPreferredEnemyUnit(unit) && unit.Info.HasTraitInfo<AttackBaseInfo>());
|
||||
if (!enemyAroundUnit.Any())
|
||||
var enemyAroundUnit = units
|
||||
.Where(unit => squad.SquadManager.IsPreferredEnemyUnit(unit) && unit.Info.HasTraitInfo<AttackBaseInfo>())
|
||||
.ToList();
|
||||
if (enemyAroundUnit.Count == 0)
|
||||
return false;
|
||||
|
||||
return flee(enemyAroundUnit);
|
||||
|
||||
@@ -172,17 +172,18 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
ActorInfo ChooseUnitToBuild(ProductionQueue queue)
|
||||
{
|
||||
var buildableThings = queue.BuildableItems();
|
||||
if (!buildableThings.Any())
|
||||
var buildableThings = queue.BuildableItems().Select(b => b.Name).ToHashSet();
|
||||
if (buildableThings.Count == 0)
|
||||
return null;
|
||||
|
||||
var myUnits = player.World
|
||||
.ActorsHavingTrait<IPositionable>()
|
||||
.Where(a => a.Owner == player)
|
||||
.Select(a => a.Info.Name).ToList();
|
||||
.Select(a => a.Info.Name)
|
||||
.ToList();
|
||||
|
||||
foreach (var unit in Info.UnitsToBuild.Shuffle(world.LocalRandom))
|
||||
if (buildableThings.Any(b => b.Name == unit.Key))
|
||||
if (buildableThings.Contains(unit.Key))
|
||||
if (myUnits.Count(a => a == unit.Key) * 100 < unit.Value * myUnits.Count)
|
||||
if (HasAdequateAirUnitReloadBuildings(world.Map.Rules.Actors[unit.Key]))
|
||||
return world.Map.Rules.Actors[unit.Key];
|
||||
|
||||
@@ -80,9 +80,6 @@ namespace OpenRA.Mods.Common.Traits
|
||||
return null;
|
||||
|
||||
var allOfType = Exits(actor, productionType);
|
||||
if (!allOfType.Any())
|
||||
return null;
|
||||
|
||||
foreach (var g in allOfType.GroupBy(e => e.Info.Priority))
|
||||
{
|
||||
var shuffled = g.Shuffle(world.SharedRandom);
|
||||
|
||||
@@ -54,13 +54,15 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public override void RulesetLoaded(Ruleset rules, ActorInfo ai)
|
||||
{
|
||||
var locomotorInfos = rules.Actors[SystemActors.World].TraitInfos<LocomotorInfo>();
|
||||
LocomotorInfo = locomotorInfos.FirstOrDefault(li => li.Name == Locomotor);
|
||||
if (LocomotorInfo == null)
|
||||
var locomotorInfos = rules.Actors[SystemActors.World].TraitInfos<LocomotorInfo>()
|
||||
.Where(li => li.Name == Locomotor).ToList();
|
||||
if (locomotorInfos.Count == 0)
|
||||
throw new YamlException($"A locomotor named '{Locomotor}' doesn't exist.");
|
||||
else if (locomotorInfos.Count(li => li.Name == Locomotor) > 1)
|
||||
else if (locomotorInfos.Count > 1)
|
||||
throw new YamlException($"There is more than one locomotor named '{Locomotor}'.");
|
||||
|
||||
LocomotorInfo = locomotorInfos[0];
|
||||
|
||||
base.RulesetLoaded(rules, ai);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,23 +113,32 @@ namespace OpenRA.Mods.Common.Traits
|
||||
void INotifyParachute.OnLanded(Actor self)
|
||||
{
|
||||
// Check whether the crate landed on anything
|
||||
var landedOn = self.World.ActorMap.GetActorsAt(self.Location)
|
||||
.Where(a => a != self);
|
||||
|
||||
if (!landedOn.Any())
|
||||
return;
|
||||
|
||||
var collector = landedOn.FirstOrDefault(a =>
|
||||
var anyOtherActors = false;
|
||||
Actor collector = null;
|
||||
foreach (var otherActor in self.World.ActorMap.GetActorsAt(self.Location))
|
||||
{
|
||||
if (self == otherActor)
|
||||
continue;
|
||||
|
||||
anyOtherActors = true;
|
||||
|
||||
// Mobile is (currently) the only trait that supports crushing
|
||||
var mi = a.Info.TraitInfoOrDefault<MobileInfo>();
|
||||
var mi = otherActor.Info.TraitInfoOrDefault<MobileInfo>();
|
||||
if (mi == null)
|
||||
return false;
|
||||
continue;
|
||||
|
||||
// Make sure that the actor can collect this crate type
|
||||
// Crate can only be crushed if it is not in the air.
|
||||
return self.IsAtGroundLevel() && mi.LocomotorInfo.Crushes.Contains(info.CrushClass);
|
||||
});
|
||||
if (self.IsAtGroundLevel() && mi.LocomotorInfo.Crushes.Contains(info.CrushClass))
|
||||
{
|
||||
collector = otherActor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// The crate can land unhindered.
|
||||
if (!anyOtherActors)
|
||||
return;
|
||||
|
||||
// Destroy the crate if none of the units in the cell are valid collectors
|
||||
if (collector != null)
|
||||
@@ -148,10 +157,11 @@ namespace OpenRA.Mods.Common.Traits
|
||||
self.Dispose();
|
||||
collected = true;
|
||||
|
||||
if (crateActions.Any())
|
||||
var shares = crateActions
|
||||
.Select(a => (Action: a, Shares: a.GetSelectionSharesOuter(crusher)))
|
||||
.ToList();
|
||||
if (shares.Count != 0)
|
||||
{
|
||||
var shares = crateActions.Select(a => (Action: a, Shares: a.GetSelectionSharesOuter(crusher)));
|
||||
|
||||
var totalShares = shares.Sum(a => a.Shares);
|
||||
var n = self.World.SharedRandom.Next(totalShares);
|
||||
|
||||
|
||||
@@ -76,7 +76,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
void GrantCondition(Actor actor)
|
||||
{
|
||||
var externals = actor.TraitsImplementing<ExternalCondition>()
|
||||
.Where(t => t.Info.Condition == info.Condition);
|
||||
.Where(t => t.Info.Condition == info.Condition)
|
||||
.ToList();
|
||||
|
||||
ExternalCondition external = null;
|
||||
for (var n = 0; n < info.Levels; n++)
|
||||
|
||||
@@ -104,13 +104,15 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public override void RulesetLoaded(Ruleset rules, ActorInfo ai)
|
||||
{
|
||||
var locomotorInfos = rules.Actors[SystemActors.World].TraitInfos<LocomotorInfo>();
|
||||
LocomotorInfo = locomotorInfos.FirstOrDefault(li => li.Name == Locomotor);
|
||||
if (LocomotorInfo == null)
|
||||
var locomotorInfos = rules.Actors[SystemActors.World].TraitInfos<LocomotorInfo>()
|
||||
.Where(li => li.Name == Locomotor).ToList();
|
||||
if (locomotorInfos.Count == 0)
|
||||
throw new YamlException($"A locomotor named '{Locomotor}' doesn't exist.");
|
||||
else if (locomotorInfos.Count(li => li.Name == Locomotor) > 1)
|
||||
else if (locomotorInfos.Count > 1)
|
||||
throw new YamlException($"There is more than one locomotor named '{Locomotor}'.");
|
||||
|
||||
LocomotorInfo = locomotorInfos[0];
|
||||
|
||||
// We need to reset the reference to the locomotor between each worlds, otherwise we are reference the previous state.
|
||||
locomotor = null;
|
||||
|
||||
|
||||
@@ -133,15 +133,15 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public override TraitPair<Production> MostLikelyProducer()
|
||||
{
|
||||
var productionActors = self.World.ActorsWithTrait<Production>()
|
||||
var productionActor = self.World.ActorsWithTrait<Production>()
|
||||
.Where(x => x.Actor.Owner == self.Owner
|
||||
&& !x.Trait.IsTraitDisabled && x.Trait.Info.Produces.Contains(Info.Type))
|
||||
.OrderByDescending(x => x.Actor.IsPrimaryBuilding())
|
||||
.OrderBy(x => x.Trait.IsTraitPaused)
|
||||
.ThenByDescending(x => x.Actor.IsPrimaryBuilding())
|
||||
.ThenByDescending(x => x.Actor.ActorID)
|
||||
.ToList();
|
||||
.FirstOrDefault();
|
||||
|
||||
var unpaused = productionActors.FirstOrDefault(a => !a.Trait.IsTraitPaused);
|
||||
return unpaused.Trait != null ? unpaused : productionActors.FirstOrDefault();
|
||||
return productionActor;
|
||||
}
|
||||
|
||||
protected override bool BuildUnit(ActorInfo unit)
|
||||
@@ -159,14 +159,10 @@ namespace OpenRA.Mods.Common.Traits
|
||||
.OrderByDescending(x => x.Actor.IsPrimaryBuilding())
|
||||
.ThenByDescending(x => x.Actor.ActorID);
|
||||
|
||||
if (!producers.Any())
|
||||
{
|
||||
CancelProduction(unit.Name, 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
var anyProducers = false;
|
||||
foreach (var p in producers)
|
||||
{
|
||||
anyProducers = true;
|
||||
if (p.Trait.IsTraitPaused)
|
||||
continue;
|
||||
|
||||
@@ -184,6 +180,12 @@ namespace OpenRA.Mods.Common.Traits
|
||||
}
|
||||
}
|
||||
|
||||
if (!anyProducers)
|
||||
{
|
||||
CancelProduction(unit.Name, 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -83,15 +83,15 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public override TraitPair<Production> MostLikelyProducer()
|
||||
{
|
||||
var productionActors = self.World.ActorsWithTrait<Production>()
|
||||
var productionActor = self.World.ActorsWithTrait<Production>()
|
||||
.Where(x => x.Actor.Owner == self.Owner
|
||||
&& !x.Trait.IsTraitDisabled && x.Trait.Info.Produces.Contains(Info.Type))
|
||||
.OrderByDescending(x => x.Actor.IsPrimaryBuilding())
|
||||
.OrderBy(x => x.Trait.IsTraitPaused)
|
||||
.ThenByDescending(x => x.Actor.IsPrimaryBuilding())
|
||||
.ThenByDescending(x => x.Actor.ActorID)
|
||||
.ToList();
|
||||
.FirstOrDefault();
|
||||
|
||||
var unpaused = productionActors.FirstOrDefault(a => !a.Trait.IsTraitPaused);
|
||||
return unpaused.Trait != null ? unpaused : productionActors.FirstOrDefault();
|
||||
return productionActor;
|
||||
}
|
||||
|
||||
protected override bool BuildUnit(ActorInfo unit)
|
||||
@@ -109,14 +109,10 @@ namespace OpenRA.Mods.Common.Traits
|
||||
.OrderByDescending(x => x.Actor.IsPrimaryBuilding())
|
||||
.ThenByDescending(x => x.Actor.ActorID);
|
||||
|
||||
if (!producers.Any())
|
||||
{
|
||||
CancelProduction(unit.Name, 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
var anyProducers = false;
|
||||
foreach (var p in producers)
|
||||
{
|
||||
anyProducers = true;
|
||||
if (p.Trait.IsTraitPaused)
|
||||
continue;
|
||||
|
||||
@@ -134,6 +130,12 @@ namespace OpenRA.Mods.Common.Traits
|
||||
}
|
||||
}
|
||||
|
||||
if (!anyProducers)
|
||||
{
|
||||
CancelProduction(unit.Name, 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -81,13 +81,14 @@ namespace OpenRA.Mods.Common.Traits
|
||||
return;
|
||||
|
||||
var myTeam = self.World.LobbyInfo.ClientWithIndex(self.Owner.ClientIndex).Team;
|
||||
var teams = self.World.Players.Where(p => !p.NonCombatant && p.Playable)
|
||||
var victoriousTeam = self.World.Players.Where(p => !p.NonCombatant && p.Playable)
|
||||
.Select(p => (Player: p, PlayerStatistics: p.PlayerActor.TraitOrDefault<PlayerStatistics>()))
|
||||
.OrderByDescending(p => p.PlayerStatistics?.Experience ?? 0)
|
||||
.GroupBy(p => (self.World.LobbyInfo.ClientWithIndex(p.Player.ClientIndex) ?? new Session.Client()).Team)
|
||||
.OrderByDescending(g => g.Sum(gg => gg.PlayerStatistics?.Experience ?? 0));
|
||||
.OrderByDescending(g => g.Sum(gg => gg.PlayerStatistics?.Experience ?? 0))
|
||||
.First();
|
||||
|
||||
if (teams.First().Key == myTeam && (myTeam != 0 || teams.First().First().Player == self.Owner))
|
||||
if (victoriousTeam.Key == myTeam && (myTeam != 0 || victoriousTeam.First().Player == self.Owner))
|
||||
{
|
||||
mo.MarkCompleted(self.Owner, objectiveID);
|
||||
return;
|
||||
|
||||
@@ -594,9 +594,11 @@ namespace OpenRA.Mods.Common.Traits
|
||||
// Returns the actor/trait that is most likely (but not necessarily guaranteed) to produce something in this queue
|
||||
public virtual TraitPair<Production> MostLikelyProducer()
|
||||
{
|
||||
var traits = productionTraits.Where(p => !p.IsTraitDisabled && p.Info.Produces.Contains(Info.Type));
|
||||
var unpaused = traits.FirstOrDefault(a => !a.IsTraitPaused);
|
||||
return new TraitPair<Production>(Actor, unpaused ?? traits.FirstOrDefault());
|
||||
var trait = productionTraits
|
||||
.Where(p => !p.IsTraitDisabled && p.Info.Produces.Contains(Info.Type))
|
||||
.OrderBy(p => p.IsTraitPaused)
|
||||
.FirstOrDefault();
|
||||
return new TraitPair<Production>(Actor, trait);
|
||||
}
|
||||
|
||||
// Builds a unit from the actor that holds this queue (1 queue per building)
|
||||
|
||||
@@ -89,13 +89,21 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (!self.Owner.NonCombatant && self.Owner.HasNoRequiredUnits(shortGame))
|
||||
mo.MarkFailed(self.Owner, objectiveID);
|
||||
|
||||
var others = self.World.Players.Where(p => !p.NonCombatant
|
||||
&& !p.IsAlliedWith(self.Owner));
|
||||
var allOthersLost = true;
|
||||
var anyOtherWon = false;
|
||||
foreach (var other in self.World.Players)
|
||||
{
|
||||
if (other.NonCombatant || other.IsAlliedWith(self.Owner))
|
||||
continue;
|
||||
|
||||
if (others.All(p => p.WinState == WinState.Lost))
|
||||
allOthersLost = allOthersLost && other.WinState == WinState.Lost;
|
||||
anyOtherWon = anyOtherWon || other.WinState == WinState.Won;
|
||||
}
|
||||
|
||||
if (allOthersLost)
|
||||
mo.MarkCompleted(player, objectiveID);
|
||||
|
||||
if (others.Any(p => p.WinState == WinState.Won))
|
||||
if (anyOtherWon)
|
||||
mo.MarkFailed(player, objectiveID);
|
||||
|
||||
// See if any of the conditions are met to increase the count
|
||||
@@ -119,13 +127,14 @@ namespace OpenRA.Mods.Common.Traits
|
||||
return;
|
||||
|
||||
var myTeam = self.World.LobbyInfo.ClientWithIndex(self.Owner.ClientIndex).Team;
|
||||
var teams = self.World.Players.Where(p => !p.NonCombatant && p.Playable)
|
||||
var victoriousTeam = self.World.Players.Where(p => !p.NonCombatant && p.Playable)
|
||||
.Select(p => (Player: p, PlayerStatistics: p.PlayerActor.TraitOrDefault<PlayerStatistics>()))
|
||||
.OrderByDescending(p => p.PlayerStatistics?.Experience ?? 0)
|
||||
.GroupBy(p => (self.World.LobbyInfo.ClientWithIndex(p.Player.ClientIndex) ?? new Session.Client()).Team)
|
||||
.OrderByDescending(g => g.Sum(gg => gg.PlayerStatistics?.Experience ?? 0));
|
||||
.OrderByDescending(g => g.Sum(gg => gg.PlayerStatistics?.Experience ?? 0))
|
||||
.First();
|
||||
|
||||
if (teams.First().Key == myTeam && (myTeam != 0 || teams.First().First().Player == self.Owner))
|
||||
if (victoriousTeam.Key == myTeam && (myTeam != 0 || victoriousTeam.First().Player == self.Owner))
|
||||
{
|
||||
mo.MarkCompleted(self.Owner, objectiveID);
|
||||
return;
|
||||
|
||||
@@ -44,10 +44,19 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (rejectsOrdersTraits.Length == 0)
|
||||
return true;
|
||||
|
||||
var reject = rejectsOrdersTraits.SelectMany(t => t.Reject);
|
||||
var except = rejectsOrdersTraits.SelectMany(t => t.Except);
|
||||
foreach (var rejectsOrdersTrait in rejectsOrdersTraits)
|
||||
if (rejectsOrdersTrait.Except.Contains(orderString))
|
||||
return true;
|
||||
|
||||
return except.Contains(orderString) || (reject.Any() && !reject.Contains(orderString));
|
||||
var anyRejects = false;
|
||||
foreach (var rejectsOrdersTrait in rejectsOrdersTraits)
|
||||
{
|
||||
anyRejects = anyRejects || rejectsOrdersTrait.Reject.Count > 0;
|
||||
if (rejectsOrdersTrait.Reject.Contains(orderString))
|
||||
return false;
|
||||
}
|
||||
|
||||
return anyRejects;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,29 +51,27 @@ namespace OpenRA.Mods.Common.Traits.Render
|
||||
if (IsTraitDisabled)
|
||||
return r;
|
||||
|
||||
var renderables = r.ToList();
|
||||
var height = self.World.Map.DistanceAboveTerrain(self.CenterPosition).Length;
|
||||
var shadowSprites = r.Where(s => !s.IsDecoration && s is IModifyableRenderable)
|
||||
var shadowSprites = renderables.Where(s => !s.IsDecoration && s is IModifyableRenderable)
|
||||
.Select(ma => ((IModifyableRenderable)ma).WithTint(shadowColor, ((IModifyableRenderable)ma).TintModifiers | TintModifiers.ReplaceColor)
|
||||
.WithAlpha(shadowAlpha)
|
||||
.OffsetBy(info.Offset - new WVec(0, 0, height))
|
||||
.WithZOffset(ma.ZOffset + height + info.ZOffset)
|
||||
.AsDecoration());
|
||||
|
||||
return shadowSprites.Concat(r);
|
||||
return shadowSprites.Concat(renderables);
|
||||
}
|
||||
|
||||
IEnumerable<Rectangle> IRenderModifier.ModifyScreenBounds(Actor self, WorldRenderer wr, IEnumerable<Rectangle> bounds)
|
||||
{
|
||||
foreach (var r in bounds)
|
||||
yield return r;
|
||||
|
||||
if (IsTraitDisabled)
|
||||
yield break;
|
||||
return bounds;
|
||||
|
||||
var boundsList = bounds.ToList();
|
||||
var height = self.World.Map.DistanceAboveTerrain(self.CenterPosition).Length;
|
||||
var offset = wr.ScreenPxOffset(info.Offset - new WVec(0, 0, height));
|
||||
foreach (var r in bounds)
|
||||
yield return new Rectangle(r.X + offset.X, r.Y + offset.Y, r.Width, r.Height);
|
||||
return boundsList.Concat(boundsList.Select(r => new Rectangle(r.X + offset.X, r.Y + offset.Y, r.Width, r.Height)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,8 +205,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
actorShouldBeRemoved = removeActorPosition.Contains;
|
||||
|
||||
LargestActorRadius = map.Rules.Actors.SelectMany(a => a.Value.TraitInfos<HitShapeInfo>()).Max(h => h.Type.OuterRadius);
|
||||
var blockers = map.Rules.Actors.Where(a => a.Value.HasTraitInfo<IBlocksProjectilesInfo>());
|
||||
LargestBlockingActorRadius = blockers.Any() ? blockers.SelectMany(a => a.Value.TraitInfos<HitShapeInfo>()).Max(h => h.Type.OuterRadius) : WDist.Zero;
|
||||
var blockers = map.Rules.Actors.Where(a => a.Value.HasTraitInfo<IBlocksProjectilesInfo>()).ToList();
|
||||
LargestBlockingActorRadius = blockers.Count != 0 ? blockers.SelectMany(a => a.Value.TraitInfos<HitShapeInfo>()).Max(h => h.Type.OuterRadius) : WDist.Zero;
|
||||
}
|
||||
|
||||
void INotifyCreated.Created(Actor self)
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
/// </summary>
|
||||
void ICreatePlayersInfo.CreateServerPlayers(MapPreview map, Session lobbyInfo, List<GameInformation.Player> players, MersenneTwister playerRandom)
|
||||
{
|
||||
var factions = map.WorldActorInfo.TraitInfos<FactionInfo>().ToArray();
|
||||
var factions = map.WorldActorInfo.TraitInfos<FactionInfo>();
|
||||
var assignSpawnLocations = map.WorldActorInfo.TraitInfoOrDefault<IAssignSpawnPointsInfo>();
|
||||
var spawnState = assignSpawnLocations?.InitializeState(map, lobbyInfo);
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
}
|
||||
|
||||
// Create the regular playable players.
|
||||
var bots = map.PlayerActorInfo.TraitInfos<IBotInfo>().ToArray();
|
||||
var bots = map.PlayerActorInfo.TraitInfos<IBotInfo>();
|
||||
|
||||
foreach (var kv in lobbyInfo.Slots)
|
||||
{
|
||||
|
||||
@@ -178,7 +178,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
return reference.GetOrDefault<T>(info);
|
||||
}
|
||||
|
||||
public IEnumerable<T> GetInits<T>() where T : ActorInit
|
||||
public IReadOnlyCollection<T> GetInits<T>() where T : ActorInit
|
||||
{
|
||||
return reference.GetAll<T>();
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public readonly LongBitSet<PlayerBitMask> Crushable;
|
||||
public readonly CellFlag CellFlag;
|
||||
|
||||
public CellCache(LongBitSet<PlayerBitMask> immovable, CellFlag cellFlag, LongBitSet<PlayerBitMask> crushable = default)
|
||||
public CellCache(LongBitSet<PlayerBitMask> immovable, CellFlag cellFlag, LongBitSet<PlayerBitMask> crushable)
|
||||
{
|
||||
Immovable = immovable;
|
||||
Crushable = crushable;
|
||||
@@ -459,26 +459,17 @@ namespace OpenRA.Mods.Common.Traits
|
||||
using (new PerfSample("locomotor_cache"))
|
||||
{
|
||||
var cache = blockingCache[cell.Layer];
|
||||
|
||||
var actors = actorMap.GetActorsAt(cell);
|
||||
var cellFlag = CellFlag.HasFreeSpace;
|
||||
|
||||
if (!actors.Any())
|
||||
{
|
||||
cache[cell] = new CellCache(default, cellFlag);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sharesCell && actorMap.HasFreeSubCell(cell))
|
||||
{
|
||||
cache[cell] = new CellCache(default, cellFlag);
|
||||
return;
|
||||
}
|
||||
|
||||
var cellImmovablePlayers = default(LongBitSet<PlayerBitMask>);
|
||||
var cellCrushablePlayers = world.AllPlayersMask;
|
||||
|
||||
foreach (var actor in actors)
|
||||
if (sharesCell && actorMap.HasFreeSubCell(cell))
|
||||
{
|
||||
cache[cell] = new CellCache(cellImmovablePlayers, cellFlag, cellCrushablePlayers);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var actor in actorMap.GetActorsAt(cell))
|
||||
{
|
||||
var actorImmovablePlayers = world.AllPlayersMask;
|
||||
var actorCrushablePlayers = world.NoPlayersMask;
|
||||
@@ -493,11 +484,10 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (isTransitOnly)
|
||||
cellFlag |= CellFlag.HasTransitOnlyActor;
|
||||
|
||||
if (crushables.Any())
|
||||
foreach (var crushable in crushables)
|
||||
{
|
||||
cellFlag |= CellFlag.HasCrushableActor;
|
||||
foreach (var crushable in crushables)
|
||||
actorCrushablePlayers = actorCrushablePlayers.Union(crushable.CrushableBy(actor, Info.Crushes));
|
||||
actorCrushablePlayers = actorCrushablePlayers.Union(crushable.CrushableBy(actor, Info.Crushes));
|
||||
}
|
||||
|
||||
if (isMoving)
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace OpenRA.Mods.Common.UpdateRules.Rules
|
||||
{
|
||||
@@ -24,7 +23,7 @@ namespace OpenRA.Mods.Common.UpdateRules.Rules
|
||||
|
||||
public override IEnumerable<string> AfterUpdate(ModData modData)
|
||||
{
|
||||
if (locations.Any())
|
||||
if (locations.Count != 0)
|
||||
yield return "Icon overlay logic has been split from ProducibleWithLevel to WithProductionIconOverlay trait.\n" +
|
||||
"If you have been using VeteranProductionIconOverlay trait, add WithProductionIconOverlay to following actors:\n" +
|
||||
UpdateUtils.FormatMessageList(locations);
|
||||
|
||||
@@ -45,16 +45,16 @@ namespace OpenRA.Mods.Common.UpdateRules.Rules
|
||||
foreach (var sequenceNode in imageNode.Value.Nodes)
|
||||
{
|
||||
var useTilesetExtensionNode = sequenceNode.LastChildMatching("UseTilesetExtension");
|
||||
if (useTilesetExtensionNode != null && !tilesetExtensions.Any())
|
||||
if (useTilesetExtensionNode != null && tilesetExtensions.Count == 0)
|
||||
requiredMetadata.Add("TilesetExtensions");
|
||||
|
||||
var useTilesetCodeNode = sequenceNode.LastChildMatching("UseTilesetCode");
|
||||
if (useTilesetCodeNode != null && !tilesetCodes.Any())
|
||||
if (useTilesetCodeNode != null && tilesetCodes.Count == 0)
|
||||
requiredMetadata.Add("TilesetCodes");
|
||||
}
|
||||
}
|
||||
|
||||
if (requiredMetadata.Any())
|
||||
if (requiredMetadata.Count != 0)
|
||||
{
|
||||
yield return $"The ExplicitSequenceFilenames rule requires {requiredMetadata.JoinWith(", ")}\n" +
|
||||
"to be defined under the SpriteSequenceFormat definition in mod.yaml.\n" +
|
||||
@@ -317,7 +317,7 @@ namespace OpenRA.Mods.Common.UpdateRules.Rules
|
||||
if (allSequencesHaveTilesetFilenames)
|
||||
sequenceNode.RemoveNodes("TilesetFilenames");
|
||||
|
||||
if (!sequenceNode.Value.Nodes.Any())
|
||||
if (sequenceNode.Value.Nodes.Count == 0)
|
||||
imageNode.RemoveNode(sequenceNode);
|
||||
}
|
||||
|
||||
@@ -328,13 +328,13 @@ namespace OpenRA.Mods.Common.UpdateRules.Rules
|
||||
sequenceNode.RemoveNodes("TilesetFilenames");
|
||||
|
||||
var tilesetFilenamesNode = sequenceNode.LastChildMatching("TilesetFilenames");
|
||||
if (allSequencesHaveTilesetFilenames && tilesetFilenamesNode != null && !tilesetFilenamesNode.Value.Nodes.Any())
|
||||
if (allSequencesHaveTilesetFilenames && tilesetFilenamesNode != null && tilesetFilenamesNode.Value.Nodes.Count == 0)
|
||||
sequenceNode.RemoveNode(tilesetFilenamesNode);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var sequenceNode in imageNode.Value.Nodes.ToList())
|
||||
if (implicitInheritedSequences.Contains(sequenceNode.Key) && !sequenceNode.Value.Nodes.Any())
|
||||
if (implicitInheritedSequences.Contains(sequenceNode.Key) && sequenceNode.Value.Nodes.Count == 0)
|
||||
imageNode.RemoveNode(sequenceNode);
|
||||
}
|
||||
|
||||
@@ -424,7 +424,7 @@ namespace OpenRA.Mods.Common.UpdateRules.Rules
|
||||
if (overrideNode.Value.Value == filenameNode.Value.Value)
|
||||
tilesetFilenamesNode.Value.Nodes.Remove(overrideNode);
|
||||
|
||||
if (!tilesetFilenamesNode.Value.Nodes.Any())
|
||||
if (tilesetFilenamesNode.Value.Nodes.Count == 0)
|
||||
sequenceNode.RemoveNode(tilesetFilenamesNode);
|
||||
|
||||
sequenceNode.Value.Nodes.Insert(0, filenameNode);
|
||||
|
||||
@@ -114,7 +114,7 @@ namespace OpenRA.Mods.Common.UpdateRules
|
||||
}),
|
||||
};
|
||||
|
||||
public static IEnumerable<UpdateRule> FromSource(ObjectCreator objectCreator, string source, bool chain = true)
|
||||
public static IReadOnlyCollection<UpdateRule> FromSource(ObjectCreator objectCreator, string source, bool chain = true)
|
||||
{
|
||||
// Use reflection to identify types
|
||||
var namedType = objectCreator.FindType(source);
|
||||
@@ -143,12 +143,12 @@ namespace OpenRA.Mods.Common.UpdateRules
|
||||
this.chainToSource = chainToSource;
|
||||
}
|
||||
|
||||
IEnumerable<UpdateRule> Rules(bool chain = true)
|
||||
IReadOnlyCollection<UpdateRule> Rules(bool chain = true)
|
||||
{
|
||||
if (chainToSource != null && chain)
|
||||
{
|
||||
var child = Paths.First(p => p.source == chainToSource);
|
||||
return rules.Concat(child.Rules(chain));
|
||||
return rules.Concat(child.Rules(chain)).ToList();
|
||||
}
|
||||
|
||||
return rules;
|
||||
|
||||
@@ -271,7 +271,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
if (isActivity)
|
||||
Console.WriteLine(" --- *Queued Activity*");
|
||||
|
||||
if (requiredTraits.Any())
|
||||
if (requiredTraits.Length != 0)
|
||||
Console.WriteLine($" --- **Requires {(requiredTraits.Length == 1 ? "Trait" : "Traits")}:** {requiredTraits.Select(GetDocumentationUrl).JoinWith(", ")}");
|
||||
|
||||
if (memberInfo is MethodInfo methodInfo)
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
if (folder.OpenPackage(args[1], modData.ModFiles) is not IReadWritePackage package)
|
||||
throw new FileNotFoundException(args[1]);
|
||||
|
||||
IEnumerable<UpdateRule> rules = null;
|
||||
IReadOnlyCollection<UpdateRule> rules = null;
|
||||
if (args.Length > 2)
|
||||
rules = UpdatePath.FromSource(modData.ObjectCreator, args[2]);
|
||||
|
||||
@@ -77,9 +77,10 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
}
|
||||
|
||||
var other = UpdatePath.KnownRules(modData.ObjectCreator)
|
||||
.Where(r => !ruleGroups.Values.Any(g => g.Contains(r)));
|
||||
.Where(r => !ruleGroups.Values.Any(g => g.Contains(r)))
|
||||
.ToList();
|
||||
|
||||
if (other.Any())
|
||||
if (other.Count != 0)
|
||||
{
|
||||
Console.WriteLine(" Other:");
|
||||
foreach (var r in other)
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
// HACK: The engine code assumes that Game.modData is set.
|
||||
var modData = Game.ModData = utility.ModData;
|
||||
|
||||
IEnumerable<UpdateRule> rules = null;
|
||||
IReadOnlyCollection<UpdateRule> rules = null;
|
||||
if (args.Length > 1)
|
||||
rules = UpdatePath.FromSource(modData.ObjectCreator, args[1]);
|
||||
|
||||
@@ -71,9 +71,10 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
}
|
||||
|
||||
var other = UpdatePath.KnownRules(modData.ObjectCreator)
|
||||
.Where(r => !ruleGroups.Values.Any(g => g.Contains(r)));
|
||||
.Where(r => !ruleGroups.Values.Any(g => g.Contains(r)))
|
||||
.ToList();
|
||||
|
||||
if (other.Any())
|
||||
if (other.Count != 0)
|
||||
{
|
||||
Console.WriteLine(" Other:");
|
||||
foreach (var r in other)
|
||||
@@ -111,9 +112,9 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
PrintSummary(rules, args.Contains("--detailed"));
|
||||
}
|
||||
|
||||
public static void PrintSummary(IEnumerable<UpdateRule> rules, bool detailed)
|
||||
public static void PrintSummary(IReadOnlyCollection<UpdateRule> rules, bool detailed)
|
||||
{
|
||||
var count = rules.Count();
|
||||
var count = rules.Count;
|
||||
if (count == 1)
|
||||
Console.WriteLine("Found 1 API change:");
|
||||
else
|
||||
|
||||
@@ -60,9 +60,9 @@ namespace OpenRA.Mods.Common.Warheads
|
||||
|
||||
if (RandomClusterCount != 0)
|
||||
{
|
||||
var randomTargetCells = CellsMatching(targetCell, true);
|
||||
var clusterCount = RandomClusterCount < 0 ? randomTargetCells.Count() : RandomClusterCount;
|
||||
if (randomTargetCells.Any())
|
||||
var randomTargetCells = CellsMatching(targetCell, true).ToList();
|
||||
var clusterCount = RandomClusterCount < 0 ? randomTargetCells.Count : RandomClusterCount;
|
||||
if (randomTargetCells.Count != 0)
|
||||
for (var i = 0; i < clusterCount; i++)
|
||||
FireProjectileAtCell(map, firedBy, target, randomTargetCells.Random(firedBy.World.SharedRandom), args);
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
var actors = new List<KeyValuePair<ActorInfo, EncyclopediaInfo>>();
|
||||
foreach (var actor in modData.DefaultRules.Actors.Values)
|
||||
{
|
||||
if (!actor.TraitInfos<IRenderActorPreviewSpritesInfo>().Any())
|
||||
if (actor.TraitInfos<IRenderActorPreviewSpritesInfo>().Count == 0)
|
||||
continue;
|
||||
|
||||
var statistics = actor.TraitInfoOrDefault<UpdatesPlayerStatisticsInfo>();
|
||||
|
||||
@@ -113,7 +113,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
.Select(p => (Player: p, PlayerStatistics: p.PlayerActor.TraitOrDefault<PlayerStatistics>()))
|
||||
.OrderByDescending(p => p.PlayerStatistics?.Experience ?? 0)
|
||||
.GroupBy(p => (world.LobbyInfo.ClientWithIndex(p.Player.ClientIndex) ?? new Session.Client()).Team)
|
||||
.OrderByDescending(g => g.Sum(gg => gg.PlayerStatistics?.Experience ?? 0));
|
||||
.OrderByDescending(g => g.Sum(gg => gg.PlayerStatistics?.Experience ?? 0))
|
||||
.ToList();
|
||||
|
||||
void KickAction(Session.Client client)
|
||||
{
|
||||
@@ -133,7 +134,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
|
||||
foreach (var t in teams)
|
||||
{
|
||||
if (teams.Count() > 1)
|
||||
if (teams.Count > 1)
|
||||
{
|
||||
var teamHeader = ScrollItemWidget.Setup(teamTemplate, () => false, () => { });
|
||||
var team = t.Key > 0
|
||||
|
||||
@@ -114,9 +114,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
.GroupBy(p => (world.LobbyInfo.ClientWithIndex(p.Player.ClientIndex) ?? new Session.Client()).Team)
|
||||
.OrderBy(g => g.Key);
|
||||
|
||||
var noTeams = teams.Count() == 1;
|
||||
var teamsList = teams.ToList();
|
||||
var noTeams = teamsList.Count == 1;
|
||||
var totalPlayers = 0;
|
||||
foreach (var t in teams)
|
||||
foreach (var t in teamsList)
|
||||
{
|
||||
totalPlayers += t.Count();
|
||||
var label = noTeams ? TranslationProvider.GetString(Players) : t.Key > 0
|
||||
@@ -209,12 +210,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
if (e.Key >= Keycode.NUMBER_0 && e.Key <= Keycode.NUMBER_9)
|
||||
{
|
||||
var key = (int)e.Key - (int)Keycode.NUMBER_0;
|
||||
var team = teams.Where(t => t.Key == key).SelectMany(s => s);
|
||||
if (!team.Any())
|
||||
var team = teams.Where(t => t.Key == key).SelectMany(s => s).ToList();
|
||||
if (team.Count == 0)
|
||||
return false;
|
||||
|
||||
if (e.Modifiers == Modifiers.Shift)
|
||||
team = team.Reverse();
|
||||
team.Reverse();
|
||||
|
||||
selected = team.SkipWhile(t => t.Player != selected.Player).Skip(1).FirstOrDefault() ?? team.FirstOrDefault();
|
||||
selected.OnClick();
|
||||
|
||||
@@ -183,7 +183,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
selectedPackages = availablePackages.ToDictionary(x => x.Identifier, y => y.Required);
|
||||
|
||||
// Ignore source if content is already installed
|
||||
if (availablePackages.Any())
|
||||
if (availablePackages.Length != 0)
|
||||
{
|
||||
Game.RunAfterTick(() =>
|
||||
{
|
||||
@@ -218,10 +218,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
|
||||
var options = new Dictionary<string, IEnumerable<string>>();
|
||||
|
||||
if (gameSources.Any())
|
||||
if (gameSources.Count != 0)
|
||||
options.Add(TranslationProvider.GetString(GameSources), gameSources);
|
||||
|
||||
if (digitalInstalls.Any())
|
||||
if (digitalInstalls.Count != 0)
|
||||
options.Add(TranslationProvider.GetString(DigitalInstalls), digitalInstalls);
|
||||
|
||||
Game.RunAfterTick(() =>
|
||||
|
||||
@@ -322,18 +322,19 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
if (!int.TryParse(mapFilter, out var playerCountFilter))
|
||||
playerCountFilter = -1;
|
||||
|
||||
var validMaps = tabMaps[tab]
|
||||
var maps = tabMaps[tab]
|
||||
.Where(m => category == null || m.Categories.Contains(category))
|
||||
.Where(m => mapFilter == null ||
|
||||
(m.Title != null && m.Title.Contains(mapFilter, StringComparison.CurrentCultureIgnoreCase)) ||
|
||||
(m.Author != null && m.Author.Contains(mapFilter, StringComparison.CurrentCultureIgnoreCase)) ||
|
||||
m.PlayerCount == playerCountFilter);
|
||||
|
||||
IOrderedEnumerable<MapPreview> maps;
|
||||
if (orderByFunc == null)
|
||||
maps = validMaps.OrderBy(m => m.Title);
|
||||
maps = maps.OrderBy(m => m.Title);
|
||||
else
|
||||
maps = validMaps.OrderBy(orderByFunc).ThenBy(m => m.Title);
|
||||
maps = maps.OrderBy(orderByFunc).ThenBy(m => m.Title);
|
||||
|
||||
maps = maps.ToList();
|
||||
|
||||
scrollpanels[tab].RemoveChildren();
|
||||
foreach (var loop in maps)
|
||||
|
||||
@@ -715,10 +715,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
|
||||
var players = replay.GameInfo.Players
|
||||
.GroupBy(p => p.Team)
|
||||
.OrderBy(g => g.Key);
|
||||
.OrderBy(g => g.Key)
|
||||
.ToList();
|
||||
|
||||
var teams = new Dictionary<string, IEnumerable<GameInformation.Player>>();
|
||||
var noTeams = players.Count() == 1;
|
||||
var noTeams = players.Count == 1;
|
||||
foreach (var p in players)
|
||||
{
|
||||
var label = noTeams ? TranslationProvider.GetString(Players) : p.Key > 0
|
||||
|
||||
@@ -572,10 +572,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
var players = server.Clients
|
||||
.Where(c => !c.IsSpectator)
|
||||
.GroupBy(p => p.Team)
|
||||
.OrderBy(g => g.Key);
|
||||
.OrderBy(g => g.Key)
|
||||
.ToList();
|
||||
|
||||
var teams = new Dictionary<string, IEnumerable<GameClient>>();
|
||||
var noTeams = players.Count() == 1;
|
||||
var noTeams = players.Count == 1;
|
||||
foreach (var p in players)
|
||||
{
|
||||
var label = noTeams ? TranslationProvider.GetString(Players) : p.Key > 0
|
||||
|
||||
@@ -183,9 +183,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
{
|
||||
var typesInGroup = hg.Value;
|
||||
var keysInGroup = modData.Hotkeys.Definitions
|
||||
.Where(hd => IsHotkeyVisibleInFilter(hd) && hd.Types.Overlaps(typesInGroup));
|
||||
.Where(hd => IsHotkeyVisibleInFilter(hd) && hd.Types.Overlaps(typesInGroup))
|
||||
.ToList();
|
||||
|
||||
if (!keysInGroup.Any())
|
||||
if (keysInGroup.Count == 0)
|
||||
continue;
|
||||
|
||||
var header = headerTemplate.Clone();
|
||||
|
||||
@@ -102,14 +102,15 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
|
||||
var queues = world.ActorsWithTrait<ProductionQueue>()
|
||||
.Where(a => a.Actor.Owner == player)
|
||||
.Select((a, i) => new { a.Trait, i });
|
||||
.Select(a => a.Trait)
|
||||
.ToList();
|
||||
|
||||
foreach (var queue in queues)
|
||||
if (!clocks.ContainsKey(queue.Trait))
|
||||
clocks.Add(queue.Trait, new Animation(world, ClockAnimation));
|
||||
if (!clocks.ContainsKey(queue))
|
||||
clocks.Add(queue, new Animation(world, ClockAnimation));
|
||||
|
||||
var currentItemsByItem = queues
|
||||
.Select(a => a.Trait.CurrentItem())
|
||||
.Select(q => q.CurrentItem())
|
||||
.Where(pi => pi != null)
|
||||
.GroupBy(pr => pr.Item)
|
||||
.OrderBy(g => g.First().Queue.Info.DisplayOrder)
|
||||
|
||||
@@ -183,9 +183,9 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
var tabs = Groups[queueGroup].Tabs.Where(t => t.Queue.BuildableItems().Any());
|
||||
var tabs = Groups[queueGroup].Tabs.Where(t => t.Queue.BuildableItems().Any()).ToList();
|
||||
|
||||
if (!tabs.Any())
|
||||
if (tabs.Count == 0)
|
||||
return;
|
||||
|
||||
var rb = RenderBounds;
|
||||
|
||||
Reference in New Issue
Block a user