Files
OpenRA/OpenRA.Mods.Common/AI/States/StateBase.cs
Saulius Menkevičius e1fa6af954 HackyAI can now build buildings with new MCV
There was an issue where HackyAI would try to build buildings
at old base location and would fail, unless it was placed at the
same place where the old MCV was.
2015-03-12 20:10:08 +02:00

97 lines
2.7 KiB
C#

#region Copyright & License Information
/*
* Copyright 2007-2015 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 OpenRA.Mods.Common.Activities;
using OpenRA.Mods.Common.Traits;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.AI
{
abstract class StateBase
{
protected const int DangerRadius = 10;
protected static void GoToRandomOwnBuilding(Squad squad)
{
var loc = RandomBuildingLocation(squad);
foreach (var a in squad.Units)
squad.World.IssueOrder(new Order("Move", a, false) { TargetLocation = loc });
}
protected static CPos RandomBuildingLocation(Squad squad)
{
var location = squad.Bot.GetRandomBaseCenter();
var buildings = squad.World.ActorsWithTrait<Building>()
.Where(a => a.Actor.Owner == squad.Bot.Player).Select(a => a.Actor).ToList();
if (buildings.Count > 0)
location = buildings.Random(squad.Random).Location;
return location;
}
protected static bool BusyAttack(Actor a)
{
if (a.IsIdle)
return false;
var type = a.GetCurrentActivity().GetType();
if (type == typeof(Attack) || type == typeof(FlyAttack))
return true;
var next = a.GetCurrentActivity().NextActivity;
if (next == null)
return false;
var nextType = a.GetCurrentActivity().NextActivity.GetType();
if (nextType == typeof(Attack) || nextType == typeof(FlyAttack))
return true;
return false;
}
protected static bool CanAttackTarget(Actor a, Actor target)
{
if (!a.HasTrait<AttackBase>())
return false;
var targetable = target.TraitOrDefault<ITargetable>();
if (targetable == null)
return false;
var arms = a.TraitsImplementing<Armament>();
foreach (var arm in arms)
if (arm.Weapon.ValidTargets.Intersect(targetable.TargetTypes).Any())
return true;
return false;
}
protected virtual bool ShouldFlee(Squad squad, Func<IEnumerable<Actor>, bool> flee)
{
if (!squad.IsValid)
return false;
var u = squad.Units.Random(squad.Random);
var units = squad.World.FindActorsInCircle(u.CenterPosition, WRange.FromCells(DangerRadius)).ToList();
var ownBaseBuildingAround = units.Where(unit => unit.Owner == squad.Bot.Player && unit.HasTrait<Building>());
if (ownBaseBuildingAround.Any())
return false;
var enemyAroundUnit = units.Where(unit => squad.Bot.Player.Stances[unit.Owner] == Stance.Enemy && unit.HasTrait<AttackBase>());
if (!enemyAroundUnit.Any())
return false;
return flee(enemyAroundUnit);
}
}
}