AI operating reactors & railguns, misc AI improvements
This commit is contained in:
@@ -255,31 +255,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
linkedGap.Open = 1.0f;
|
||||
}
|
||||
|
||||
public List<Controller> GetButtons()
|
||||
{
|
||||
ConnectionPanel connectionPanel = Item.GetComponent<ConnectionPanel>();
|
||||
if (connectionPanel == null) return new List<Controller>();
|
||||
|
||||
List<Controller> buttons = new List<Controller>();
|
||||
|
||||
foreach (Connection c in connectionPanel.Connections)
|
||||
{
|
||||
foreach (Wire w in c.Wires)
|
||||
{
|
||||
if (w == null) continue;
|
||||
var otherConnection = w.OtherConnection(c);
|
||||
|
||||
if (otherConnection.Item == Item || otherConnection == null) continue;
|
||||
|
||||
var controller = otherConnection.Item.GetComponent<Controller>();
|
||||
if (controller != null) buttons.Add(controller);
|
||||
}
|
||||
}
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
|
||||
public override void Draw(SpriteBatch spriteBatch, bool editing)
|
||||
{
|
||||
Color color = (item.IsSelected) ? Color.Green : Color.White;
|
||||
|
||||
@@ -38,8 +38,7 @@ namespace Barotrauma.Items.Components
|
||||
/// <summary>
|
||||
/// The base class for components holding the different functionalities of the item
|
||||
/// </summary>
|
||||
class
|
||||
ItemComponent : IPropertyObject
|
||||
class ItemComponent : IPropertyObject
|
||||
{
|
||||
protected Item item;
|
||||
|
||||
@@ -400,6 +399,13 @@ namespace Barotrauma.Items.Components
|
||||
/// <param name="modifier"> A vector that can be used to pass additional information to the components</param>
|
||||
public virtual void ItemActivate(Item item, Vector2 modifier) { }
|
||||
|
||||
|
||||
/// <returns>true if the operation was completed</returns>
|
||||
public virtual bool AIOperate(float deltaTime, Character character, AIObjective objective)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//called when isActive is true and condition > 0.0f
|
||||
public virtual void Update(float deltaTime, Camera cam) { }
|
||||
|
||||
|
||||
@@ -86,6 +86,11 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
private int slotsPerRow;
|
||||
|
||||
public List<RelatedItem> ContainableItems
|
||||
{
|
||||
get { return containableItems; }
|
||||
}
|
||||
|
||||
public ItemContainer(Item item, XElement element)
|
||||
: base (item, element)
|
||||
{
|
||||
|
||||
@@ -311,12 +311,44 @@ namespace Barotrauma.Items.Components
|
||||
new Vector2(10, 40 * (temperature / 10000.0f)), new Color(temperature / 10000.0f, 1.0f - (temperature / 10000.0f), 0.0f, 1.0f), true);
|
||||
}
|
||||
|
||||
public override bool AIOperate(float deltaTime, Character character, AIObjective objective)
|
||||
{
|
||||
switch (objective.Option.ToLower())
|
||||
{
|
||||
case "power up":
|
||||
float tempDiff = load - temperature;
|
||||
|
||||
bool valueChanged = false;
|
||||
shutDownTemp = Math.Min(load + 1000.0f, 7500.0f);
|
||||
|
||||
//temperature too high/low
|
||||
if (Math.Abs(tempDiff)>500.0f)
|
||||
{
|
||||
autoTemp = false;
|
||||
FissionRate += deltaTime * 100.0f * Math.Sign(tempDiff);
|
||||
CoolingRate -= deltaTime * 100.0f * Math.Sign(tempDiff);
|
||||
}
|
||||
//temperature OK
|
||||
else
|
||||
{
|
||||
autoTemp = true;
|
||||
}
|
||||
|
||||
break;
|
||||
case "shutdown":
|
||||
|
||||
shutDownTemp = 0.0f;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
|
||||
{
|
||||
IsActive = true;
|
||||
|
||||
bool valueChanged = false;
|
||||
|
||||
int width = GuiFrame.Rect.Width, height = GuiFrame.Rect.Height;
|
||||
int x = GuiFrame.Rect.X;
|
||||
@@ -398,7 +430,6 @@ namespace Barotrauma.Items.Components
|
||||
if (valueChanged)
|
||||
{
|
||||
item.NewComponentEvent(this, true, false);
|
||||
valueChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -156,6 +156,13 @@ namespace Barotrauma.Items.Components
|
||||
voltage = 0.0f;
|
||||
}
|
||||
|
||||
public override bool AIOperate(float deltaTime, Character character, AIObjective objective)
|
||||
{
|
||||
RechargeSpeed = maxRechargeSpeed * 0.5f;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Draw(SpriteBatch spriteBatch, bool editing)
|
||||
{
|
||||
base.Draw(spriteBatch);
|
||||
|
||||
@@ -127,67 +127,161 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (reload > 0.0f) return false;
|
||||
|
||||
Projectile projectileComponent = null;
|
||||
//search for a projectile from linked containers
|
||||
Item projectile = null;
|
||||
Item projectileContainer = null;
|
||||
foreach (MapEntity e in item.linkedTo)
|
||||
{
|
||||
projectileContainer = e as Item;
|
||||
if (projectileContainer == null) continue;
|
||||
|
||||
ItemContainer containerComponent = projectileContainer.GetComponent<ItemContainer>();
|
||||
if (containerComponent == null) continue;
|
||||
|
||||
for (int i = 0; i < containerComponent.inventory.Items.Length; i++)
|
||||
{
|
||||
if (containerComponent.inventory.Items[i] == null) continue;
|
||||
if ((projectileComponent = containerComponent.inventory.Items[i].GetComponent<Projectile>()) != null)
|
||||
{
|
||||
projectile = containerComponent.inventory.Items[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (projectileComponent != null) break;
|
||||
}
|
||||
|
||||
if (projectile == null || projectileComponent == null) return false;
|
||||
var projectiles = GetLoadedProjectiles(true);
|
||||
if (projectiles.Count == 0) return false;
|
||||
|
||||
if (GetAvailablePower() < currPowerConsumption) return false;
|
||||
|
||||
var batteries = item.GetConnectedComponents<PowerContainer>();
|
||||
|
||||
float availablePower = 0.0f;
|
||||
//List<PowerContainer> batteries = new List<PowerContainer>();
|
||||
foreach (Connection c in item.Connections)
|
||||
foreach (PowerContainer battery in batteries)
|
||||
{
|
||||
foreach (Connection c2 in c.Recipients)
|
||||
{
|
||||
if (c2 == null || c2.Item == null) continue;
|
||||
float batteryPower = Math.Min(battery.Charge, battery.MaxOutPut);
|
||||
float takePower = Math.Min(currPowerConsumption - availablePower, batteryPower);
|
||||
|
||||
PowerContainer batteryComponent = c2.Item.GetComponent<PowerContainer>();
|
||||
if (batteryComponent == null) continue;
|
||||
|
||||
float batteryPower = Math.Min(batteryComponent.Charge, batteryComponent.MaxOutPut);
|
||||
float takePower = Math.Min(currPowerConsumption - availablePower, batteryPower);
|
||||
|
||||
batteryComponent.Charge -= takePower;
|
||||
availablePower += takePower;
|
||||
}
|
||||
battery.Charge -= takePower;
|
||||
}
|
||||
|
||||
reload = reloadTime;
|
||||
|
||||
if (availablePower < currPowerConsumption) return false;
|
||||
|
||||
reload = reloadTime;
|
||||
|
||||
Item projectile = projectiles[0].Item;
|
||||
|
||||
projectile.body.ResetDynamics();
|
||||
projectile.body.Enabled = true;
|
||||
projectile.SetTransform(ConvertUnits.ToSimUnits(new Vector2(item.Rect.X + barrelPos.X, item.Rect.Y - barrelPos.Y)), -rotation);
|
||||
|
||||
projectileComponent.Use(deltaTime);
|
||||
projectileContainer.RemoveContained(projectile);
|
||||
projectiles[0].Use(deltaTime);
|
||||
if (projectile.container != null) projectile.container.RemoveContained(projectile);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool AIOperate(float deltaTime, Character character, AIObjective objective)
|
||||
{
|
||||
var projectiles = GetLoadedProjectiles();
|
||||
|
||||
if (projectiles.Count==0 || (projectiles.Count==1 && objective.Option.ToLower()=="hold fire"))
|
||||
{
|
||||
ItemContainer container = null;
|
||||
foreach (MapEntity e in item.linkedTo)
|
||||
{
|
||||
var containerItem = e as Item;
|
||||
if (containerItem == null) continue;
|
||||
|
||||
container = containerItem.GetComponent<ItemContainer>();
|
||||
if (container != null) break;
|
||||
}
|
||||
|
||||
if (container == null || container.ContainableItems.Count==0) return true;
|
||||
|
||||
objective.AddSubObjective(new AIObjectiveContainItem(character, container.ContainableItems[0].Names[0], container));
|
||||
return false;
|
||||
}
|
||||
else if (GetAvailablePower() < powerConsumption)
|
||||
{
|
||||
var batteries = item.GetConnectedComponents<PowerContainer>();
|
||||
|
||||
float lowestCharge = 0.0f;
|
||||
PowerContainer batteryToLoad = null;
|
||||
foreach (PowerContainer battery in batteries)
|
||||
{
|
||||
if (batteryToLoad==null || battery.Charge < lowestCharge)
|
||||
{
|
||||
batteryToLoad = battery;
|
||||
lowestCharge = battery.Charge;
|
||||
}
|
||||
}
|
||||
|
||||
if (batteryToLoad == null) return true;
|
||||
|
||||
if (batteryToLoad.RechargeSpeed < batteryToLoad.MaxRechargeSpeed*0.4f)
|
||||
{
|
||||
objective.AddSubObjective(new AIObjectiveOperateItem(batteryToLoad, character, ""));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//enough shells and power
|
||||
|
||||
Character closestEnemy = null;
|
||||
float closestDist = 3000.0f;
|
||||
foreach (Character enemy in Character.CharacterList)
|
||||
{
|
||||
//ignore humans and characters that are inside the sub
|
||||
if (enemy.IsDead || enemy.SpeciesName == "human" || enemy.AnimController.CurrentHull != null) continue;
|
||||
|
||||
float dist = Vector2.Distance(enemy.Position, item.Position);
|
||||
if (dist < closestDist)
|
||||
{
|
||||
closestEnemy = enemy;
|
||||
closestDist = dist;
|
||||
}
|
||||
}
|
||||
|
||||
if (closestEnemy == null) return false;
|
||||
|
||||
character.CursorPosition = closestEnemy.Position;
|
||||
SecondaryUse(deltaTime, character);
|
||||
|
||||
float enemyAngle = MathUtils.VectorToAngle(closestEnemy.Position-item.Position);
|
||||
float turretAngle = -(rotation - MathHelper.TwoPi);
|
||||
|
||||
if (Math.Abs(enemyAngle - turretAngle) > 0.01f) return false;
|
||||
|
||||
var pickedBody = Submarine.PickBody(item.SimPosition, closestEnemy.SimPosition, null);
|
||||
if (pickedBody != null && pickedBody.UserData as Limb == null) return false;
|
||||
|
||||
Use(deltaTime, character);
|
||||
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
private float GetAvailablePower()
|
||||
{
|
||||
var batteries = item.GetConnectedComponents<PowerContainer>();
|
||||
|
||||
float availablePower = 0.0f;
|
||||
foreach (PowerContainer battery in batteries)
|
||||
{
|
||||
float batteryPower = Math.Min(battery.Charge, battery.MaxOutPut);
|
||||
|
||||
availablePower += batteryPower;
|
||||
}
|
||||
|
||||
return availablePower;
|
||||
}
|
||||
|
||||
private List<Projectile> GetLoadedProjectiles(bool returnFirst = false)
|
||||
{
|
||||
List<Projectile> projectiles = new List<Projectile>();
|
||||
|
||||
foreach (MapEntity e in item.linkedTo)
|
||||
{
|
||||
var projectileContainer = e as Item;
|
||||
if (projectileContainer == null) continue;
|
||||
|
||||
var containedItems = projectileContainer.ContainedItems;
|
||||
if (containedItems == null) continue;
|
||||
|
||||
for (int i = 0; i < containedItems.Length; i++)
|
||||
{
|
||||
var projectileComponent = containedItems[i].GetComponent<Projectile>();
|
||||
if (projectileComponent != null)
|
||||
{
|
||||
projectiles.Add(projectileComponent);
|
||||
if (returnFirst) return projectiles;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return projectiles;
|
||||
}
|
||||
|
||||
public override void ReceiveSignal(string signal, Connection connection, Item sender, float power)
|
||||
{
|
||||
switch (connection.Name)
|
||||
|
||||
Reference in New Issue
Block a user