HackyAI: builds defense now. rally points are rechosen so units are more scattered in the base. builds only e1-3 and 1-3tnks.

This commit is contained in:
rasco
2010-10-06 01:44:02 +02:00
committed by Chris Forbes
parent cecdd73e08
commit cfc74a6dee

View File

@@ -45,12 +45,29 @@ namespace OpenRA.Mods.RA
int2 baseCenter; int2 baseCenter;
XRandom random = new XRandom(); //we do not use the synced random number generator. XRandom random = new XRandom(); //we do not use the synced random number generator.
Dictionary<string, float> unitsToBuild = new Dictionary<string, float>
{
{"e1", .0f},
{"e2", .0f},
{"e3", .0f},
{"1tnk", .0f},
{"2tnk", .0f},
{"3tnk", .0f}
};
Dictionary<string, float> buildingFractions = new Dictionary<string, float> Dictionary<string, float> buildingFractions = new Dictionary<string, float>
{ {
{ "proc", .2f }, { "proc", .3f },
{ "barr", .05f }, { "barr", .05f },
{ "tent", .05f }, { "tent", .05f },
{ "weap", .05f }, { "weap", .05f },
{ "pbox", .05f },
{ "hbox", .05f },
{ "gun", .05f },
{ "tsla", .05f },
{ "ftur", .05f },
{ "agun", .01f },
{ "sam", .01f },
{ "atek", .01f }, { "atek", .01f },
{ "stek", .01f }, { "stek", .01f },
{ "silo", .05f }, { "silo", .05f },
@@ -71,7 +88,8 @@ namespace OpenRA.Mods.RA
const int MaxBaseDistance = 15; const int MaxBaseDistance = 15;
BuildState state = BuildState.WaitForFeedback; BuildState bstate = BuildState.WaitForFeedback;
BuildState dstate = BuildState.WaitForFeedback;
/* called by the host's player creation code */ /* called by the host's player creation code */
public void Activate(Player p) public void Activate(Player p)
@@ -123,7 +141,8 @@ namespace OpenRA.Mods.RA
var myBuildings = p.World.Queries.OwnedBy[p].WithTrait<Building>() var myBuildings = p.World.Queries.OwnedBy[p].WithTrait<Building>()
.Select( a => a.Actor.Info.Name ).ToArray(); .Select( a => a.Actor.Info.Name ).ToArray();
foreach (var frac in buildingFractions) foreach (var frac in buildingFractions)
if (buildableThings.Any(b => b.Name == frac.Key)) if (buildableThings.Any(b => b.Name == frac.Key))
if (myBuildings.Count(a => a == frac.Key) < frac.Value * myBuildings.Length) if (myBuildings.Count(a => a == frac.Key) < frac.Value * myBuildings.Length)
@@ -132,6 +151,21 @@ namespace OpenRA.Mods.RA
return null; return null;
} }
ActorInfo ChooseDefenseToBuild(ProductionQueue queue)
{
var buildableThings = queue.BuildableItems();
var myBuildings = p.World.Queries.OwnedBy[p].WithTrait<Building>()
.Select(a => a.Actor.Info.Name).ToArray();
foreach (var frac in buildingFractions)
if (buildableThings.Any(b => b.Name == frac.Key))
if (myBuildings.Count(a => a == frac.Key) < frac.Value * myBuildings.Length)
return Rules.Info[frac.Key];
return null;
}
int2? ChooseBuildLocation(ProductionItem item) int2? ChooseBuildLocation(ProductionItem item)
{ {
var bi = Rules.Info[item.Item].Traits.Get<BuildingInfo>(); var bi = Rules.Info[item.Item].Traits.Get<BuildingInfo>();
@@ -174,7 +208,7 @@ namespace OpenRA.Mods.RA
BuildBuildings(); BuildBuildings();
//build Defense BuildDefense();
//build Ship //build Ship
} }
@@ -212,10 +246,10 @@ namespace OpenRA.Mods.RA
/* Create an attack force when we have enough units around our base. */ /* Create an attack force when we have enough units around our base. */
// (don't bother leaving any behind for defense.) // (don't bother leaving any behind for defense.)
if (unitsHangingAroundTheBase.Count > 5) if (unitsHangingAroundTheBase.Count > 8)
{ {
Game.Debug("Launch an attack."); Game.Debug("Launch an attack.");
int2 attackTarget = Game.world.WorldActor.Trait<MPStartLocations>().Start int2 attackTarget = Game.world.WorldActor.Trait<MPStartLocations>().Start
.Where(kv => kv.Key != p) .Where(kv => kv.Key != p)
.Select(kv => kv.Value) .Select(kv => kv.Value)
@@ -231,12 +265,15 @@ namespace OpenRA.Mods.RA
{ {
var newProdBuildings = self.World.Queries.OwnedBy[p] var newProdBuildings = self.World.Queries.OwnedBy[p]
.Where(a => (a.TraitOrDefault<RallyPoint>() != null .Where(a => (a.TraitOrDefault<RallyPoint>() != null
&& !activeProductionBuildings.Contains(a))).ToArray(); //&& !activeProductionBuildings.Contains(a)
)).ToArray();
foreach (var a in newProdBuildings) foreach (var a in newProdBuildings)
{ {
activeProductionBuildings.Add(a); activeProductionBuildings.Add(a);
int2 newRallyPoint = ChooseRallyLocationNear(a.Location); int2 newRallyPoint = ChooseRallyLocationNear(a.Location);
newRallyPoint.X += 4;
newRallyPoint.Y += 4;
Game.IssueOrder(new Order("SetRallyPoint", a, newRallyPoint)); Game.IssueOrder(new Order("SetRallyPoint", a, newRallyPoint));
} }
} }
@@ -244,10 +281,11 @@ namespace OpenRA.Mods.RA
//won't work for shipyards... //won't work for shipyards...
private int2 ChooseRallyLocationNear(int2 startPos) private int2 ChooseRallyLocationNear(int2 startPos)
{ {
foreach (var t in Game.world.FindTilesInCircle(startPos, 6)) Random r = new Random();
if (Game.world.IsCellBuildable(t, false) && t != startPos) foreach (var t in Game.world.FindTilesInCircle(startPos, 8))
if (Game.world.IsCellBuildable(t, false) && t != startPos && r.Next(64) == 0)
return t; return t;
return startPos; // i don't know where to put it. return startPos; // i don't know where to put it.
} }
@@ -303,17 +341,30 @@ namespace OpenRA.Mods.RA
return; return;
var unit = ChooseRandomUnitToBuild(queue); var unit = ChooseRandomUnitToBuild(queue);
if (unit != null) Boolean found = false;
{ if (unit != null)
Game.IssueOrder(Order.StartProduction(queue.self, unit.Name, 1)); {
} foreach (var un in unitsToBuild)
{
if (un.Key == unit.Name)
{
found = true;
break;
}
}
if (found == true)
{
Game.IssueOrder(Order.StartProduction(queue.self, unit.Name, 1));
}
}
} }
private void BuildBuildings() private void BuildBuildings()
{ {
// Pick a free queue // Pick a free queue
var queue = Game.world.Queries.WithTraitMultiple<ProductionQueue>() var queue = Game.world.Queries.WithTraitMultiple<ProductionQueue>()
.Where(a => a.Actor.Owner == p && a.Trait.Info.Type == "Building") .Where(a => a.Actor.Owner == p && a.Trait.Info.Type == "Building")
.Select(a => a.Trait) .Select(a => a.Trait)
.FirstOrDefault(); .FirstOrDefault();
@@ -321,19 +372,20 @@ namespace OpenRA.Mods.RA
return; return;
var currentBuilding = queue.CurrentItem(); var currentBuilding = queue.CurrentItem();
switch (state) switch (bstate)
{ {
case BuildState.ChooseItem: case BuildState.ChooseItem:
{ {
var item = ChooseBuildingToBuild(queue); var item = ChooseBuildingToBuild(queue);
if (item == null) if (item == null)
{ {
state = BuildState.WaitForFeedback; bstate = BuildState.WaitForFeedback;
lastThinkTick = ticks; lastThinkTick = ticks;
} }
else else
{ {
state = BuildState.WaitForProduction; Game.Debug("AI: Starting production of {0}".F(item.Name));
bstate = BuildState.WaitForProduction;
Game.IssueOrder(Order.StartProduction(queue.self, item.Name, 1)); Game.IssueOrder(Order.StartProduction(queue.self, item.Name, 1));
} }
} }
@@ -346,7 +398,7 @@ namespace OpenRA.Mods.RA
Game.IssueOrder(Order.PauseProduction(queue.self, currentBuilding.Item, false)); Game.IssueOrder(Order.PauseProduction(queue.self, currentBuilding.Item, false));
else if (currentBuilding.Done) else if (currentBuilding.Done)
{ {
state = BuildState.WaitForFeedback; bstate = BuildState.WaitForFeedback;
lastThinkTick = ticks; lastThinkTick = ticks;
/* place the building */ /* place the building */
@@ -365,7 +417,69 @@ namespace OpenRA.Mods.RA
case BuildState.WaitForFeedback: case BuildState.WaitForFeedback:
if (ticks - lastThinkTick > feedbackTime) if (ticks - lastThinkTick > feedbackTime)
state = BuildState.ChooseItem; bstate = BuildState.ChooseItem;
break;
}
}
private void BuildDefense()
{
// Pick a free queue
var queue = Game.world.Queries.WithTraitMultiple<ProductionQueue>()
.Where(a => a.Actor.Owner == p && a.Trait.Info.Type == "Defense")
.Select(a => a.Trait)
.FirstOrDefault();
if (queue == null)
return;
var currentBuilding = queue.CurrentItem();
switch (dstate)
{
case BuildState.ChooseItem:
{
var item = ChooseDefenseToBuild(queue);
if (item == null)
{
dstate = BuildState.WaitForFeedback;
lastThinkTick = ticks;
}
else
{
Game.Debug("AI: Starting production of {0}".F(item.Name));
dstate = BuildState.WaitForProduction;
Game.IssueOrder(Order.StartProduction(queue.self, item.Name, 1));
}
}
break;
case BuildState.WaitForProduction:
if (currentBuilding == null) return; /* let it happen.. */
else if (currentBuilding.Paused)
Game.IssueOrder(Order.PauseProduction(queue.self, currentBuilding.Item, false));
else if (currentBuilding.Done)
{
dstate = BuildState.WaitForFeedback;
lastThinkTick = ticks;
/* place the building */
var location = ChooseBuildLocation(currentBuilding);
if (location == null)
{
Game.Debug("AI: Nowhere to place {0}".F(currentBuilding.Item));
Game.IssueOrder(Order.CancelProduction(queue.self, currentBuilding.Item));
}
else
{
Game.IssueOrder(new Order("PlaceBuilding", p.PlayerActor, location.Value, currentBuilding.Item));
}
}
break;
case BuildState.WaitForFeedback:
if (ticks - lastThinkTick > feedbackTime)
dstate = BuildState.ChooseItem;
break; break;
} }
} }