diff --git a/OpenRA.Mods.RA/AI/AttackOrFleeFuzzy.cs b/OpenRA.Mods.RA/AI/AttackOrFleeFuzzy.cs index 273f02739f..0e61d7a633 100644 --- a/OpenRA.Mods.RA/AI/AttackOrFleeFuzzy.cs +++ b/OpenRA.Mods.RA/AI/AttackOrFleeFuzzy.cs @@ -20,22 +20,12 @@ namespace OpenRA.Mods.RA.AI class AttackOrFleeFuzzy { MamdaniFuzzySystem fuzzyEngine; - Dictionary result; public AttackOrFleeFuzzy() { InitializateFuzzyVariables(); } - public bool CanAttack - { - get - { - var attackChance = result[fuzzyEngine.OutputByName("AttackOrFlee")]; - return !double.IsNaN(attackChance) && attackChance < 30.0; - } - } - protected void AddFuzzyRule(string rule) { fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule(rule)); @@ -166,7 +156,7 @@ namespace OpenRA.Mods.RA.AI "then AttackOrFlee is Flee"); } - public void CalculateFuzzy(IEnumerable ownUnits, IEnumerable enemyUnits) + public bool CanAttack(IEnumerable ownUnits, IEnumerable enemyUnits) { var inputValues = new Dictionary(); inputValues.Add(fuzzyEngine.InputByName("OwnHealth"), (double)NormalizedHealth(ownUnits, 100)); @@ -174,7 +164,9 @@ namespace OpenRA.Mods.RA.AI inputValues.Add(fuzzyEngine.InputByName("RelativeAttackPower"), (double)RelativePower(ownUnits, enemyUnits)); inputValues.Add(fuzzyEngine.InputByName("RelativeSpeed"), (double)RelativeSpeed(ownUnits, enemyUnits)); - result = fuzzyEngine.Calculate(inputValues); + var result = fuzzyEngine.Calculate(inputValues); + var attackChance = result[fuzzyEngine.OutputByName("AttackOrFlee")]; + return !double.IsNaN(attackChance) && attackChance < 30.0; } protected float NormalizedHealth(IEnumerable actors, float normalizeByValue) diff --git a/OpenRA.Mods.RA/AI/HackyAI.cs b/OpenRA.Mods.RA/AI/HackyAI.cs index 4d46d71a39..535d6cd579 100644 --- a/OpenRA.Mods.RA/AI/HackyAI.cs +++ b/OpenRA.Mods.RA/AI/HackyAI.cs @@ -622,8 +622,7 @@ namespace OpenRA.Mods.RA.AI var enemys = world.FindActorsInCircle(b.CenterPosition, WRange.FromCells(15)) .Where(unit => p.Stances[unit.Owner] == Stance.Enemy && unit.HasTrait()).ToList(); - rushFuzzy.CalculateFuzzy(ownUnits, enemys); - if (rushFuzzy.CanAttack) + if (rushFuzzy.CanAttack(ownUnits, enemys)) { var target = enemys.Any() ? enemys.Random(random) : b; var rush = GetSquadOfType(SquadType.Rush); diff --git a/OpenRA.Mods.RA/AI/States/GroundStates.cs b/OpenRA.Mods.RA/AI/States/GroundStates.cs index 28574ff43d..212085f79b 100644 --- a/OpenRA.Mods.RA/AI/States/GroundStates.cs +++ b/OpenRA.Mods.RA/AI/States/GroundStates.cs @@ -18,14 +18,8 @@ namespace OpenRA.Mods.RA.AI { protected virtual bool MayBeFlee(Squad owner) { - return base.MayBeFlee(owner, (enemyAroundUnit) => - { - owner.attackOrFleeFuzzy.CalculateFuzzy(owner.units, enemyAroundUnit); - if (!owner.attackOrFleeFuzzy.CanAttack) - return true; - - return false; - }); + return base.MayBeFlee(owner, enemyAroundUnit => + !owner.attackOrFleeFuzzy.CanAttack(owner.units, enemyAroundUnit)); } } @@ -47,14 +41,14 @@ namespace OpenRA.Mods.RA.AI var enemyUnits = owner.world.FindActorsInCircle(owner.Target.CenterPosition, WRange.FromCells(10)) .Where(unit => owner.bot.p.Stances[unit.Owner] == Stance.Enemy).ToList(); - if (enemyUnits.Any()) + if (enemyUnits.Any()) { - owner.attackOrFleeFuzzy.CalculateFuzzy(owner.units, enemyUnits); - if (owner.attackOrFleeFuzzy.CanAttack) + if (owner.attackOrFleeFuzzy.CanAttack(owner.units, enemyUnits)) { - foreach(var u in owner.units) + foreach (var u in owner.units) owner.world.IssueOrder(new Order("AttackMove", u, false) { TargetLocation = owner.Target.CenterPosition.ToCPos() }); + // We have gathered sufficient units. Attack the nearest enemy unit. owner.fsm.ChangeState(owner, new GroundUnitsAttackMoveState(), true); return;