adding new ai functional

This commit is contained in:
Matthias Mailänder
2013-03-06 11:17:02 +01:00
parent 3f56e00173
commit e0b7242f1b
15 changed files with 1722 additions and 177 deletions

View File

@@ -85,6 +85,7 @@ namespace OpenRA.Traits
public int DisplayCash;
public int DisplayOre;
public bool AlertSilo;
public int Earned;
public int Spent;
@@ -158,8 +159,13 @@ namespace OpenRA.Traits
if (--nextSiloAdviceTime <= 0)
{
if (Ore > 0.8*OreCapacity)
if (Ore > 0.8 * OreCapacity)
{
Sound.PlayNotification(Owner, "Speech", "SilosNeeded", Owner.Country.Race);
AlertSilo = true;
}
else
AlertSilo = false;
nextSiloAdviceTime = AdviceInterval;
}

View File

@@ -0,0 +1,250 @@
#region Copyright & License Information
/*
* Copyright 2007-2012 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenRA.Mods.RA.Move;
using OpenRA.Traits;
using AI.Fuzzy.Library;
namespace OpenRA.Mods.RA.AI
{
class AttackOrFleeFuzzy
{
protected MamdaniFuzzySystem fuzzyEngine;
protected Dictionary<FuzzyVariable, double> result;
public bool CanAttack
{
get
{
//not sure that this will happen (NaN), it's for the safety of
if (result[fuzzyEngine.OutputByName("AttackOrFlee")].ToString() != "NaN")
return result[fuzzyEngine.OutputByName("AttackOrFlee")] < 30.0;
return false;
}
}
public AttackOrFleeFuzzy()
{
InitializateFuzzyVariables();
}
protected void InitializateFuzzyVariables()
{
fuzzyEngine = new MamdaniFuzzySystem();
FuzzyVariable playerHealthFuzzy = new FuzzyVariable("OwnHealth", 0.0, 100.0);
playerHealthFuzzy.Terms.Add(new FuzzyTerm("NearDead", new TrapezoidMembershipFunction(0, 0, 20, 40)));
playerHealthFuzzy.Terms.Add(new FuzzyTerm("Injured", new TrapezoidMembershipFunction(30, 50, 50, 70)));
playerHealthFuzzy.Terms.Add(new FuzzyTerm("Normal", new TrapezoidMembershipFunction(50, 80, 100, 100)));
fuzzyEngine.Input.Add(playerHealthFuzzy);
FuzzyVariable enemyHealthFuzzy = new FuzzyVariable("EnemyHealth", 0.0, 100.0);
enemyHealthFuzzy.Terms.Add(new FuzzyTerm("NearDead", new TrapezoidMembershipFunction(0, 0, 20, 40)));
enemyHealthFuzzy.Terms.Add(new FuzzyTerm("Injured", new TrapezoidMembershipFunction(30, 50, 50, 70)));
enemyHealthFuzzy.Terms.Add(new FuzzyTerm("Normal", new TrapezoidMembershipFunction(50, 80, 100, 100)));
fuzzyEngine.Input.Add(enemyHealthFuzzy);
FuzzyVariable relativeAttackPowerFuzzy = new FuzzyVariable("RelativeAttackPower", 0.0, 1000.0);
relativeAttackPowerFuzzy.Terms.Add(new FuzzyTerm("Weak", new TrapezoidMembershipFunction(0, 0, 70, 90)));
relativeAttackPowerFuzzy.Terms.Add(new FuzzyTerm("Equal", new TrapezoidMembershipFunction(85, 100, 100, 115)));
relativeAttackPowerFuzzy.Terms.Add(new FuzzyTerm("Strong", new TrapezoidMembershipFunction(110, 150, 150, 1000)));
fuzzyEngine.Input.Add(relativeAttackPowerFuzzy);
FuzzyVariable relativeSpeedFuzzy = new FuzzyVariable("RelativeSpeed", 0.0, 1000.0);
relativeSpeedFuzzy.Terms.Add(new FuzzyTerm("Slow", new TrapezoidMembershipFunction(0, 0, 70, 90)));
relativeSpeedFuzzy.Terms.Add(new FuzzyTerm("Equal", new TrapezoidMembershipFunction(85, 100, 100, 115)));
relativeSpeedFuzzy.Terms.Add(new FuzzyTerm("Fast", new TrapezoidMembershipFunction(110, 150, 150, 1000)));
fuzzyEngine.Input.Add(relativeSpeedFuzzy);
FuzzyVariable attackOrFleeFuzzy = new FuzzyVariable("AttackOrFlee", 0.0, 50.0);
attackOrFleeFuzzy.Terms.Add(new FuzzyTerm("Attack", new TrapezoidMembershipFunction(0, 15, 15, 30)));
attackOrFleeFuzzy.Terms.Add(new FuzzyTerm("Flee", new TrapezoidMembershipFunction(25, 35, 35, 50)));
fuzzyEngine.Output.Add(attackOrFleeFuzzy);
AddingRulesForNormalOwnHealth();
AddingRulesForInjuredOwnHealth();
AddingRulesForNearDeadOwnHealth();
}
protected virtual void AddingRulesForNormalOwnHealth()
{
//1 OwnHealth is Normal
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if ((OwnHealth is Normal) " +
"and ((EnemyHealth is NearDead) or (EnemyHealth is Injured) or (EnemyHealth is Normal)) " +
"and ((RelativeAttackPower is Weak) or (RelativeAttackPower is Equal) or (RelativeAttackPower is Strong)) " +
"and ((RelativeSpeed is Slow) or (RelativeSpeed is Equal) or (RelativeSpeed is Fast))) " +
"then AttackOrFlee is Attack"));
}
protected virtual void AddingRulesForInjuredOwnHealth()
{
//OwnHealth is Injured
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if ((OwnHealth is Injured) " +
"and (EnemyHealth is NearDead) " +
"and ((RelativeAttackPower is Weak) or (RelativeAttackPower is Equal) or (RelativeAttackPower is Strong)) " +
"and ((RelativeSpeed is Slow) or (RelativeSpeed is Equal) or (RelativeSpeed is Fast))) " +
"then AttackOrFlee is Attack"));
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if ((OwnHealth is Injured) " +
"and ((EnemyHealth is Injured) or (EnemyHealth is Normal)) " +
"and ((RelativeAttackPower is Equal) or (RelativeAttackPower is Strong)) " +
"and ((RelativeSpeed is Slow) or (RelativeSpeed is Equal) or (RelativeSpeed is Fast))) " +
"then AttackOrFlee is Attack"));
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if ((OwnHealth is Injured) " +
"and ((EnemyHealth is Injured) or (EnemyHealth is Normal)) " +
"and (RelativeAttackPower is Weak) " +
"and (RelativeSpeed is Slow)) " +
"then AttackOrFlee is Attack"));
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if ((OwnHealth is Injured) " +
"and ((EnemyHealth is Injured) or (EnemyHealth is Normal)) " +
"and (RelativeAttackPower is Weak) " +
"and ((RelativeSpeed is Equal) or (RelativeSpeed is Fast))) " +
"then AttackOrFlee is Flee"));
//2
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if ((OwnHealth is Injured) " +
"and ((EnemyHealth is NearDead) or (EnemyHealth is Injured) or (EnemyHealth is Normal)) " +
"and ((RelativeAttackPower is Weak) or (RelativeAttackPower is Equal) or (RelativeAttackPower is Strong)) " +
"and (RelativeSpeed is Slow)) " +
"then AttackOrFlee is Attack"));
}
protected virtual void AddingRulesForNearDeadOwnHealth()
{
//3 OwnHealth is NearDead
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if ((OwnHealth is NearDead) " +
"and (EnemyHealth is Injured) " +
"and (RelativeAttackPower is Equal) " +
"and ((RelativeSpeed is Slow) or (RelativeSpeed is Equal))) " +
"then AttackOrFlee is Attack"));
//4
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if ((OwnHealth is NearDead) " +
"and (EnemyHealth is NearDead) " +
"and (RelativeAttackPower is Weak) " +
"and ((RelativeSpeed is Equal) or (RelativeSpeed is Fast))) " +
"then AttackOrFlee is Flee"));
//5
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if ((OwnHealth is NearDead) " +
"and (EnemyHealth is Injured) " +
"and (RelativeAttackPower is Weak) " +
"and ((RelativeSpeed is Equal) or (RelativeSpeed is Fast))) " +
"then AttackOrFlee is Flee"));
//6
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if ((OwnHealth is NearDead) " +
"and (EnemyHealth is Normal) " +
"and (RelativeAttackPower is Weak) " +
"and ((RelativeSpeed is Equal) or (RelativeSpeed is Fast))) " +
"then AttackOrFlee is Flee"));
//7
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if (OwnHealth is NearDead) " +
"and (EnemyHealth is Normal) " +
"and (RelativeAttackPower is Equal) " +
"and (RelativeSpeed is Fast) " +
"then AttackOrFlee is Flee"));
//8
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if (OwnHealth is NearDead) " +
"and (EnemyHealth is Normal) " +
"and (RelativeAttackPower is Strong) " +
"and (RelativeSpeed is Fast) " +
"then AttackOrFlee is Flee"));
//9
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if (OwnHealth is NearDead) " +
"and (EnemyHealth is Injured) " +
"and (RelativeAttackPower is Equal) " +
"and (RelativeSpeed is Fast) " +
"then AttackOrFlee is Flee"));
}
public void CalculateFuzzy(List<Actor> ownUnits, List<Actor> enemyUnits)
{
Dictionary<FuzzyVariable, double> inputValues = new Dictionary<FuzzyVariable, double>();
inputValues.Add(fuzzyEngine.InputByName("OwnHealth"), (double)NormalizedHealth(ownUnits, 100));
inputValues.Add(fuzzyEngine.InputByName("EnemyHealth"), (double)NormalizedHealth(enemyUnits, 100));
inputValues.Add(fuzzyEngine.InputByName("RelativeAttackPower"), (double)RelativePower(ownUnits, enemyUnits));
inputValues.Add(fuzzyEngine.InputByName("RelativeSpeed"), (double)RelativeSpeed(ownUnits, enemyUnits));
result = fuzzyEngine.Calculate(inputValues);
}
protected float NormalizedHealth(List<Actor> actors, float normalizeByValue)
{
int sumOfMaxHp = 0;
int sumOfHp = 0;
foreach (var a in actors)
if (a.HasTrait<Health>())
{
sumOfMaxHp += a.Trait<Health>().MaxHP;
sumOfHp += a.Trait<Health>().HP;
}
if (sumOfMaxHp == 0) return 0.0f;
return (sumOfHp * normalizeByValue) / sumOfMaxHp;
}
protected float RelativePower(List<Actor> own, List<Actor> enemy)
{
return RelativeValue(own, enemy, 100, SumOfValues<AttackBase>, (Actor a) =>
{
int sumOfDamage = 0;
foreach (var weap in a.Trait<AttackBase>().Weapons)
if (weap.Info.Warheads[0] != null)
sumOfDamage += weap.Info.Warheads[0].Damage;
return sumOfDamage;
});
}
protected float RelativeSpeed(List<Actor> own, List<Actor> enemy)
{
return RelativeValue(own, enemy, 100, Average<Mobile>, (Actor a) => a.Trait<Mobile>().Info.Speed);
}
protected float RelativeValue(List<Actor> own, List<Actor> enemy, float normalizeByValue,
Func<List<Actor>, Func<Actor, int>, float> relativeFunc, Func<Actor, int> getValue)
{
if (enemy.Count == 0)
return 999.0f;
if (own.Count == 0)
return 0.0f;
float relative = (relativeFunc(own, getValue) / relativeFunc(enemy, getValue)) * normalizeByValue;
return relative.Clamp(0.0f, 999.0f);
}
protected float SumOfValues<Trait>(List<Actor> actors, Func<Actor, int> getValue)
{
int sum = 0;
foreach (var a in actors)
if (a.HasTrait<Trait>())
sum += getValue(a);
return sum;
}
protected float Average<Trait>(List<Actor> actors, Func<Actor, int> getValue)
{
int sum = 0;
int countActors = 0;
foreach (var a in actors)
if (a.HasTrait<Trait>())
{
sum += getValue(a);
countActors++;
}
if (countActors == 0) return 0.0f;
return sum / countActors;
}
}
}

View File

@@ -74,7 +74,13 @@ namespace OpenRA.Mods.RA.AI
lastThinkTick = ai.ticks;
/* place the building */
var location = ai.ChooseBuildLocation(currentBuilding.Item);
BuildingType type = BuildingType.Building;
if(Rules.Info[currentBuilding.Item].Traits.Contains<AttackBaseInfo>())
type = BuildingType.Defense;
else if(Rules.Info[currentBuilding.Item].Traits.Contains<OreRefineryInfo>())
type = BuildingType.Refinery;
var location = ai.ChooseBuildLocation(currentBuilding.Item, type);
if (location == null)
{
HackyAI.BotDebug("AI: Nowhere to place {0}".F(currentBuilding.Item));

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,39 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AI.Fuzzy.Library;
namespace OpenRA.Mods.RA.AI
{
class RushFuzzy : AttackOrFleeFuzzy
{
public RushFuzzy() : base() { }
protected override void AddingRulesForNormalOwnHealth()
{
//1 OwnHealth is Normal
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if ((OwnHealth is Normal) " +
"and ((EnemyHealth is NearDead) or (EnemyHealth is Injured) or (EnemyHealth is Normal)) " +
"and (RelativeAttackPower is Strong) " +
"and ((RelativeSpeed is Slow) or (RelativeSpeed is Equal) or (RelativeSpeed is Fast))) " +
"then AttackOrFlee is Attack"));
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if ((OwnHealth is Normal) " +
"and ((EnemyHealth is NearDead) or (EnemyHealth is Injured) or (EnemyHealth is Normal)) " +
"and ((RelativeAttackPower is Weak) or (RelativeAttackPower is Equal)) " +
"and ((RelativeSpeed is Slow) or (RelativeSpeed is Equal) or (RelativeSpeed is Fast))) " +
"then AttackOrFlee is Flee"));
}
}
}

View File

@@ -0,0 +1,79 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
namespace OpenRA.Mods.RA.AI
{
class StateMachine
{
//a pointer to the agent that owns this instance
private Squad owner;
private IState currentState;
//a record of the last state the agent was in
private IState previousState;
public StateMachine(Squad owner)
{
this.owner = owner;
}
public IState CurrentState
{
get { return currentState; }
set { currentState = value; }
}
public IState PreviousState
{
get { return previousState; }
set { previousState = value; }
}
//call this to update the FSM
public void UpdateFsm()
{
currentState.Execute(owner);
}
//change to a new state
//boolean variable isSaveCurrentState respons on save or not current state
public void ChangeState(IState newState, bool saveCurrentState)
{
if (saveCurrentState)
//keep a record of the previous state
previousState = currentState;
//call the exit method of the existing state
if(currentState != null)
currentState.Exit(owner);
//change state to the new state
if (newState != null)
currentState = newState;
//call the entry method of the new state
currentState.Enter(owner);
}
//change state back to the previous state
public void RevertToPreviousState(bool saveCurrentState)
{
ChangeState(previousState, saveCurrentState);
}
}
interface IState
{
void Enter(Squad bot);
void Execute(Squad bot);
void Exit(Squad bot);
}
}

View File

@@ -229,7 +229,22 @@ namespace OpenRA.Mods.RA.Move
public CPos NearestMoveableCell(CPos target, int minRange, int maxRange)
{
return NearestCell(target, CanEnterCell, minRange, maxRange);
if (CanEnterCell(target))
return target;
var searched = new List<CPos>();
// Limit search to a radius of 10 tiles
for (int r = minRange; r < maxRange; r++)
foreach (var tile in self.World.FindTilesInCircle(target, r).Except(searched))
{
if (CanEnterCell(tile))
return tile;
searched.Add(tile);
}
// Couldn't find a cell
return target;
}
public CPos NearestCell(CPos target, Func<CPos, bool> check, int minRange, int maxRange)
@@ -237,10 +252,16 @@ namespace OpenRA.Mods.RA.Move
if (check(target))
return target;
foreach (var tile in self.World.FindTilesInCircle(target, maxRange))
var searched = new List<CPos>();
for (int r = minRange; r < maxRange; r++)
foreach (var tile in self.World.FindTilesInCircle(target, r).Except(searched))
{
if (check(tile))
return tile;
searched.Add(tile);
}
// Couldn't find a cell
return target;
}

View File

@@ -58,6 +58,9 @@
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="FuzzyLogicLibrary">
<HintPath>..\thirdparty\FuzzyLogicLibrary.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
@@ -69,6 +72,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="AI\AttackOrFleeFuzzy.cs" />
<Compile Include="AI\BaseBuilder.cs" />
<Compile Include="AI\HackyAI.cs" />
<Compile Include="AcceptsSupplies.cs" />
@@ -120,6 +124,8 @@
<Compile Include="Air\ReturnOnIdle.cs" />
<Compile Include="Air\ReturnToBase.cs" />
<Compile Include="Air\TargetableAircraft.cs" />
<Compile Include="AI\RushFuzzy.cs" />
<Compile Include="AI\StateMachine.cs" />
<Compile Include="AnnounceOnBuild.cs" />
<Compile Include="AnnounceOnKill.cs" />
<Compile Include="AppearsOnRadar.cs" />

View File

@@ -0,0 +1,57 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using System.Collections.Generic;
using System.Drawing;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Mods.RA.Orders
{
class SetChronoTankDestination : IOrderGenerator
{
public readonly Actor self;
public SetChronoTankDestination(Actor self)
{
this.self = self;
}
public IEnumerable<Order> Order(World world, CPos xy, MouseInput mi)
{
if (mi.Button == MouseButton.Left)
{
world.CancelInputMode();
yield break;
}
var queued = mi.Modifiers.HasModifier(Modifiers.Shift);
if (world.LocalPlayer.Shroud.IsExplored(xy))
yield return new Order("ChronoshiftSelf", self, queued) { TargetLocation = xy };
}
public void Tick( World world ) { }
public void RenderAfterWorld( WorldRenderer wr, World world )
{
wr.DrawSelectionBox(self, Color.White);
}
public void RenderBeforeWorld( WorldRenderer wr, World world ) { }
public string GetCursor(World world, CPos xy, MouseInput mi)
{
if (!world.LocalPlayer.Shroud.IsExplored(xy))
return "move-blocked";
var movement = self.TraitOrDefault<IMove>();
return (movement.CanEnterCell(xy)) ? "chrono-target" : "move-blocked";
}
}
}

View File

@@ -1,4 +1,4 @@
#region Copyright & License Information
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
@@ -24,13 +24,15 @@ namespace OpenRA.Mods.RA
public class RallyPoint : IIssueOrder, IResolveOrder, ISync
{
[Sync] public CPos rallyPoint;
[Sync]
public CPos rallyPoint;
public int nearEnough = 1;
public RallyPoint(Actor self, RallyPointInfo info)
public RallyPoint(Actor self)
{
var info = self.Info.Traits.Get<RallyPointInfo>();
rallyPoint = self.Location + new CVec(info.RallyPoint[0], info.RallyPoint[1]);
self.World.AddFrameEndTask(w => w.Add(new Effects.RallyPoint(self, info.IndicatorPalettePrefix)));
self.World.AddFrameEndTask(w => w.Add(new Effects.RallyPoint(self)));
}
public IEnumerable<IOrderTargeter> Orders

View File

@@ -14,6 +14,7 @@ TRAN:
Selectable:
Bounds: 41,41
Helicopter:
RearmBuildings: hpad
LandWhenIdle: true
ROT: 5
Speed: 15
@@ -54,6 +55,7 @@ HELI:
Selectable:
Bounds: 30,24
Helicopter:
RearmBuildings: hpad
ROT: 4
Speed: 20
Health:
@@ -100,6 +102,7 @@ ORCA:
Selectable:
Bounds: 30,24
Helicopter:
RearmBuildings: hpad
ROT: 4
Speed: 20
Health:

View File

@@ -49,6 +49,68 @@ Player:
htnk: 50%
heli: 5%
orca: 5%
SquadSize: 15
HackyAI@Normal:
Name:Normal AI
BuildingGeneralNames:
ConstructionYard: fact
Refinery: proc
Power: nuke,nuk2
Barracks: pyle,hand
VehiclesFactory: weap,afld
Silo: silo
UnitsGeneralNames:
Mcv: mcv
BuildingLimits:
proc: 4
pyle: 2
hand: 2
hq: 1
weap: 2
afld: 2
hpad: 1
eye: 1
tmpl: 1
fix: 1
BuildingFractions:
proc: 17%
nuke: 1%
pyle: 2%
hand: 2%
hq: 1%
nuk2: 18%
weap: 5%
afld: 5%
hpad: 4%
gtwr: 5%
gun: 5%
atwr: 9%
obli: 7%
eye: 1%
tmpl: 1%
sam: 7%
silo: 7%
fix: 1%
UnitsToBuild:
e1: 30% #gdi, nod
e2: 30% #gdi
e3: 30% #gdi, nod
e4: 30% #nod
e5: 30% #nod
harv: 1%
bggy: 10%
ftnk: 10%
arty: 40%
bike: 10%
heli: 10%
ltnk: 40%
stnk: 40%
orca: 10%
msam: 50%
htnk: 50%
jeep: 20%
mtnk: 50%
SquadSize: 15
PlayerColorPalette:
BasePalette: terrain
RemapIndex: 176, 178, 180, 182, 184, 186, 189, 191, 177, 179, 181, 183, 185, 187, 188, 190

View File

@@ -52,6 +52,42 @@ Player:
Name:Omnius
UnitQueues: Infantry, Vehicle, Armor, Starport
RallypointTestBuilding: conyarda
BuildingGeneralNames:
ConstructionYard: conyarda,conyardh,conyardo
Refinery: refa,refh,refo
Power: pwra,pwrh,pwro
VehiclesFactory: lighta,lighth,lighto,heavya,heavyh,heavyo
Silo: siloa, siloh, siloo
UnitsGeneralNames:
Mcv: mcva,mcvh,mcvo
BuildingLimits:
refa: 4
refh: 4
refo: 4
barra: 1
barrh: 1
barro: 1
lighta: 1
lighth: 1
lighto: 1
heavya: 1
heavyh: 1
heavyo: 1
researcha: 1
researchh: 1
researcho: 1
repaira: 1
repairh: 1
repairo: 1
radara: 1
radaro: 1
radarh: 1
hightecha: 1
hightechh: 1
hightecho: 1
palacea: 1
palaceh: 1
palaceo: 1
BuildingFractions:
refa: 20.1%
refh: 20.1%

View File

@@ -67,24 +67,30 @@ Player:
2tnk: 25%
3tnk: 50%
SquadSize: 20
HackyAI@HardAI:
Name:Hard AI
HackyAI@NormalAI:
Name:Normal AI
BuildingFractions:
proc: 30%
powr: 35%
proc: 10%
powr: 1%
apwr: 30%
tent: 1%
barr: 1%
weap: 1%
weap: 6%
hpad: 4%
spen: 1%
syrd: 1%
afld: 4%
pbox.e1: 7%
gun: 7%
ftur: 10%
tsla: 5%
fix: 0.1%
dome: 10%
fix: 1%
dome: 1%
agun: 5%
sam: 1%
atek: 1%
stek: 1%
mslo: 1%
UnitsToBuild:
e1: 50%
e3: 10%
@@ -95,7 +101,110 @@ Player:
1tnk: 70%
2tnk: 25%
3tnk: 50%
heli: 30%
hind: 30%
mig: 30%
yak: 30%
ss: 10%
msub: 10%
dd: 10%
ca: 10%
pt: 10%
SquadSize: 40
HackyAI@HardAI:
Name:Hard AI
BuildingFractions:
proc: 30%
powr: 1%
apwr: 30%
tent: 1%
barr: 1%
weap: 3%
hpad: 2%
spen: 1%
syrd: 1%
pbox.e1: 7%
gun: 7%
ftur: 10%
tsla: 5%
fix: 0.1%
dome: 10%
agun: 5%
sam: 1%
atek: 1%
stek: 1%
mslo: 1%
UnitsToBuild:
e1: 50%
e3: 10%
harv: 10%
apc: 30%
jeep: 40%
ftrk: 50%
1tnk: 70%
2tnk: 25%
3tnk: 50%
heli: 30%
hind: 30%
mig: 30%
yak: 30%
ss: 10%
msub: 10%
dd: 10%
ca: 10%
pt: 10%
SquadSize: 10
HackyAI@TestAI:
Name:Test AI
BuildingFractions:
proc: 29%
powr: 1%
apwr: 24%
# tent: 3%
# barr: 3%
# weap: 5%
hpad: 5%
afld: 5%
spen: 1%
syrd: 1%
pbox.e1: 12%
gun: 12%
ftur: 12%
tsla: 12%
fix: 1%
dome: 1%
agun: 5%
sam: 5%
atek: 1%
stek: 1%
mslo: 1%
UnitsToBuild:
e1: 4%
e2: 4% #s
e3: 8%
e4: 4% #s
shok: 3%
harv: 1%
apc: 3% #s
jeep: 5%
ftrk: 8% #s
1tnk: 9% #a
2tnk: 20% #a
3tnk: 10% #s
4tnk: 14% #s
ttnk: 8% #s
arty: 15%
v2rl: 10%
heli: 7%
hind: 7%
mig: 10%
yak: 1%
ss: 7%
msub: 5%
dd: 8%
ca: 8%
pt: 8%
SquadSize: 15
HackyAI@OptiAI:
Name:Eisenhower AI
BuildingFractions:

BIN
thirdparty/FuzzyLogicLibrary.dll vendored Normal file

Binary file not shown.