Human AI improvements & fixes:
- Replaced item name comparisons with Prefab.NameMatches (-> item names can be changed without breaking the AIs). - Having an AIObjective set as the current order of the character doesn't automatically cause it to have a high priority. For example, the order to fix leaks has a low priority if there are no leaks to fix. - AIObjectiveFixLeaks makes sure the character is wearing a diving suit before going to fix a leak. The characters used to run in and out of flooded rooms because the AIObjectiveFindSafety objective would become active as soon as the character entered the room, causing the character to run out, and then immediately run back because they are no longer in immediate danger of drowning, making the FixLeaks objective the most high-priority one. - Characters attempt to find a room with no water in AIObjectiveIdle even if the character is wearing a diving suit. - AIObjectiveFindSafety considers flooded rooms dangerous even if the character is wearing a diving suit (-> the character attempts to go into a more dry room instead of happily idling in the flooded one). - Distance to a hull doesn't decrease its desirability nearly as much in AIObjectiveFindSafety (-> fixes characters not bothering to move into a non-flooded room if it's far away). - AIObjectiveOperateItem makes sure the item is equipped before using it (-> characters can't weld leaks with the welder in their inventory).
This commit is contained in:
@@ -64,7 +64,7 @@ namespace Barotrauma
|
|||||||
protected override Vector2 DoSteeringSeek(Vector2 target, float speed = 1)
|
protected override Vector2 DoSteeringSeek(Vector2 target, float speed = 1)
|
||||||
{
|
{
|
||||||
//find a new path if one hasn't been found yet or the target is different from the current target
|
//find a new path if one hasn't been found yet or the target is different from the current target
|
||||||
if (currentPath == null || Vector2.Distance(target, currentTarget)>1.0f || findPathTimer < -5.0f)
|
if (currentPath == null || Vector2.Distance(target, currentTarget) > 1.0f || findPathTimer < -1.0f)
|
||||||
{
|
{
|
||||||
if (findPathTimer > 0.0f) return Vector2.Zero;
|
if (findPathTimer > 0.0f) return Vector2.Zero;
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ namespace Barotrauma
|
|||||||
if (character != null && character.Submarine == null)
|
if (character != null && character.Submarine == null)
|
||||||
{
|
{
|
||||||
var targetHull = Hull.FindHull(FarseerPhysics.ConvertUnits.ToDisplayUnits(target), null, false);
|
var targetHull = Hull.FindHull(FarseerPhysics.ConvertUnits.ToDisplayUnits(target), null, false);
|
||||||
if (targetHull!=null && targetHull.Submarine != null)
|
if (targetHull != null && targetHull.Submarine != null)
|
||||||
{
|
{
|
||||||
pos -= targetHull.SimPosition;
|
pos -= targetHull.SimPosition;
|
||||||
}
|
}
|
||||||
@@ -81,7 +81,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
currentPath = pathFinder.FindPath(pos, target);
|
currentPath = pathFinder.FindPath(pos, target);
|
||||||
|
|
||||||
findPathTimer = Rand.Range(1.0f,1.2f);
|
findPathTimer = Rand.Range(1.0f, 1.2f);
|
||||||
|
|
||||||
return DiffToCurrentNode();
|
return DiffToCurrentNode();
|
||||||
}
|
}
|
||||||
@@ -104,7 +104,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private Vector2 DiffToCurrentNode()
|
private Vector2 DiffToCurrentNode()
|
||||||
{
|
{
|
||||||
if (currentPath == null || currentPath.Finished || currentPath.Unreachable) return Vector2.Zero;
|
if (currentPath == null || currentPath.Unreachable) return Vector2.Zero;
|
||||||
|
|
||||||
if (currentPath.Finished)
|
if (currentPath.Finished)
|
||||||
{
|
{
|
||||||
@@ -114,7 +114,7 @@ namespace Barotrauma
|
|||||||
//todo: take multiple subs into account
|
//todo: take multiple subs into account
|
||||||
pos2 -= CurrentPath.Nodes.Last().Submarine.SimPosition;
|
pos2 -= CurrentPath.Nodes.Last().Submarine.SimPosition;
|
||||||
}
|
}
|
||||||
return currentTarget-pos2;
|
return currentTarget - pos2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canOpenDoors && !character.LockHands) CheckDoorsInPath();
|
if (canOpenDoors && !character.LockHands) CheckDoorsInPath();
|
||||||
|
|||||||
@@ -4,21 +4,13 @@ using System.Linq;
|
|||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
class AIObjective
|
abstract class AIObjective
|
||||||
{
|
{
|
||||||
protected List<AIObjective> subObjectives;
|
protected readonly List<AIObjective> subObjectives;
|
||||||
|
|
||||||
protected float priority;
|
protected float priority;
|
||||||
|
protected readonly Character character;
|
||||||
protected Character character;
|
|
||||||
|
|
||||||
protected string option;
|
protected string option;
|
||||||
|
|
||||||
public virtual bool IsCompleted()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual bool CanBeCompleted
|
public virtual bool CanBeCompleted
|
||||||
{
|
{
|
||||||
get { return true; }
|
get { return true; }
|
||||||
@@ -29,13 +21,10 @@ namespace Barotrauma
|
|||||||
get { return option; }
|
get { return option; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public AIObjective(Character character, string option)
|
public AIObjective(Character character, string option)
|
||||||
{
|
{
|
||||||
subObjectives = new List<AIObjective>();
|
subObjectives = new List<AIObjective>();
|
||||||
|
|
||||||
this.character = character;
|
this.character = character;
|
||||||
|
|
||||||
this.option = option;
|
this.option = option;
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
@@ -60,8 +49,6 @@ namespace Barotrauma
|
|||||||
Act(deltaTime);
|
Act(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void Act(float deltaTime) { }
|
|
||||||
|
|
||||||
public void AddSubObjective(AIObjective objective)
|
public void AddSubObjective(AIObjective objective)
|
||||||
{
|
{
|
||||||
if (subObjectives.Any(o => o.IsDuplicate(objective))) return;
|
if (subObjectives.Any(o => o.IsDuplicate(objective))) return;
|
||||||
@@ -69,19 +56,20 @@ namespace Barotrauma
|
|||||||
subObjectives.Add(objective);
|
subObjectives.Add(objective);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual float GetPriority(Character character)
|
public AIObjective GetCurrentSubObjective()
|
||||||
{
|
{
|
||||||
return 0.0f;
|
AIObjective currentSubObjective = this;
|
||||||
|
while (currentSubObjective.subObjectives.Count > 0)
|
||||||
|
{
|
||||||
|
currentSubObjective = subObjectives[0];
|
||||||
|
}
|
||||||
|
return currentSubObjective;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool IsDuplicate(AIObjective otherObjective)
|
protected abstract void Act(float deltaTime);
|
||||||
{
|
|
||||||
#if DEBUG
|
|
||||||
throw new NotImplementedException();
|
|
||||||
#else
|
|
||||||
return (this.GetType() == otherObjective.GetType());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
public abstract bool IsCompleted();
|
||||||
|
public abstract float GetPriority(AIObjectiveManager objectiveManager);
|
||||||
|
public abstract bool IsDuplicate(AIObjective otherObjective);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
coolDownTimer = CoolDown;
|
coolDownTimer = CoolDown;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Act(float deltaTime)
|
protected override void Act(float deltaTime)
|
||||||
@@ -42,16 +41,23 @@ namespace Barotrauma
|
|||||||
|
|
||||||
var weapon = character.Inventory.FindItem("weapon");
|
var weapon = character.Inventory.FindItem("weapon");
|
||||||
|
|
||||||
if (weapon==null)
|
if (weapon == null)
|
||||||
{
|
{
|
||||||
Escape(deltaTime);
|
Escape(deltaTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
//TODO: make sure the weapon is ready to use (projectiles/batteries loaded)
|
||||||
if (!character.SelectedItems.Contains(weapon))
|
if (!character.SelectedItems.Contains(weapon))
|
||||||
{
|
{
|
||||||
character.Inventory.TryPutItem(weapon, 3, false, character);
|
if (character.Inventory.TryPutItem(weapon, 3, false, character))
|
||||||
weapon.Equip(character);
|
{
|
||||||
|
weapon.Equip(character);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
character.CursorPosition = enemy.Position;
|
character.CursorPosition = enemy.Position;
|
||||||
character.SetInput(InputType.Aim, false, true);
|
character.SetInput(InputType.Aim, false, true);
|
||||||
@@ -99,8 +105,13 @@ namespace Barotrauma
|
|||||||
return enemy.IsDead || coolDownTimer <= 0.0f;
|
return enemy.IsDead || coolDownTimer <= 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override float GetPriority(Character character)
|
public override float GetPriority(AIObjectiveManager objectiveManager)
|
||||||
{
|
{
|
||||||
|
if (objectiveManager.CurrentOrder == this)
|
||||||
|
{
|
||||||
|
return AIObjectiveManager.OrderPriority;
|
||||||
|
}
|
||||||
|
|
||||||
//clamp the strength to the health of this character
|
//clamp the strength to the health of this character
|
||||||
//(it doesn't make a difference whether the enemy does 200 or 600 damage, it's one hit kill anyway)
|
//(it doesn't make a difference whether the enemy does 200 or 600 damage, it's one hit kill anyway)
|
||||||
|
|
||||||
|
|||||||
+10
-9
@@ -19,15 +19,6 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
this.itemName = itemName;
|
this.itemName = itemName;
|
||||||
this.container = container;
|
this.container = container;
|
||||||
|
|
||||||
//check if the container has room for more items
|
|
||||||
//canBeCompleted = false;
|
|
||||||
//foreach (Item contained in container.inventory.Items)
|
|
||||||
//{
|
|
||||||
// if (contained != null) continue;
|
|
||||||
// canBeCompleted = true;
|
|
||||||
// break;
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool IsCompleted()
|
public override bool IsCompleted()
|
||||||
@@ -35,6 +26,16 @@ namespace Barotrauma
|
|||||||
return isCompleted || container.Inventory.FindItem(itemName)!=null;
|
return isCompleted || container.Inventory.FindItem(itemName)!=null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override float GetPriority(AIObjectiveManager objectiveManager)
|
||||||
|
{
|
||||||
|
if (objectiveManager.CurrentOrder == this)
|
||||||
|
{
|
||||||
|
return AIObjectiveManager.OrderPriority;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
protected override void Act(float deltaTime)
|
protected override void Act(float deltaTime)
|
||||||
{
|
{
|
||||||
if (isCompleted) return;
|
if (isCompleted) return;
|
||||||
|
|||||||
+8
-5
@@ -15,7 +15,7 @@ namespace Barotrauma
|
|||||||
if (item == null) return false;
|
if (item == null) return false;
|
||||||
|
|
||||||
var containedItems = item.ContainedItems;
|
var containedItems = item.ContainedItems;
|
||||||
var oxygenTank = Array.Find(containedItems, i => i.Name == "Oxygen Tank" && i.Condition > 0.0f);
|
var oxygenTank = Array.Find(containedItems, i => i.Prefab.NameMatches("Oxygen Tank") && i.Condition > 0.0f);
|
||||||
return oxygenTank != null;
|
return oxygenTank != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ namespace Barotrauma
|
|||||||
if (containedItems == null) return;
|
if (containedItems == null) return;
|
||||||
|
|
||||||
//check if there's an oxygen tank in the mask
|
//check if there's an oxygen tank in the mask
|
||||||
var oxygenTank = Array.Find(containedItems, i => i.Name == "Oxygen Tank");
|
var oxygenTank = Array.Find(containedItems, i => i.Prefab.NameMatches("Oxygen Tank"));
|
||||||
|
|
||||||
if (oxygenTank != null)
|
if (oxygenTank != null)
|
||||||
{
|
{
|
||||||
@@ -66,15 +66,18 @@ namespace Barotrauma
|
|||||||
if (subObjective != null)
|
if (subObjective != null)
|
||||||
{
|
{
|
||||||
subObjective.TryComplete(deltaTime);
|
subObjective.TryComplete(deltaTime);
|
||||||
|
|
||||||
//isCompleted = subObjective.IsCompleted();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override float GetPriority(Character character)
|
public override float GetPriority(AIObjectiveManager objectiveManager)
|
||||||
{
|
{
|
||||||
if (character.AnimController.CurrentHull == null) return 100.0f;
|
if (character.AnimController.CurrentHull == null) return 100.0f;
|
||||||
|
|
||||||
|
if (objectiveManager.CurrentOrder == this)
|
||||||
|
{
|
||||||
|
return AIObjectiveManager.OrderPriority;
|
||||||
|
}
|
||||||
|
|
||||||
return 100.0f - character.Oxygen;
|
return 100.0f - character.Oxygen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+37
-39
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using Microsoft.Xna.Framework;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
@@ -27,40 +28,24 @@ namespace Barotrauma
|
|||||||
unreachable = new List<Hull>();
|
unreachable = new List<Hull>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool IsCompleted()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
protected override void Act(float deltaTime)
|
protected override void Act(float deltaTime)
|
||||||
{
|
{
|
||||||
|
|
||||||
var currentHull = character.AnimController.CurrentHull;
|
var currentHull = character.AnimController.CurrentHull;
|
||||||
|
|
||||||
currenthullSafety = OverrideCurrentHullSafety == null ?
|
currenthullSafety = OverrideCurrentHullSafety == null ?
|
||||||
GetHullSafety(currentHull, character) : (float)OverrideCurrentHullSafety;
|
GetHullSafety(currentHull, character) : (float)OverrideCurrentHullSafety;
|
||||||
|
|
||||||
if (currentHull != null)
|
if (NeedsDivingGear())
|
||||||
{
|
{
|
||||||
if (NeedsDivingGear())
|
if (!FindDivingGear(deltaTime)) return;
|
||||||
{
|
|
||||||
if (!FindDivingGear(deltaTime)) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currenthullSafety > MinSafety)
|
|
||||||
{
|
|
||||||
if (Math.Abs(currentHull.WorldPosition.X - character.WorldPosition.X) > 100.0f)
|
|
||||||
{
|
|
||||||
character.AIController.SteeringManager.SteeringSeek(currentHull.SimPosition, 0.5f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
character.AIController.SteeringManager.Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
character.AIController.SelectTarget(null);
|
|
||||||
|
|
||||||
goToObjective = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (searchHullTimer > 0.0f)
|
if (searchHullTimer > 0.0f)
|
||||||
{
|
{
|
||||||
searchHullTimer -= deltaTime;
|
searchHullTimer -= deltaTime;
|
||||||
@@ -79,7 +64,7 @@ namespace Barotrauma
|
|||||||
if (goToObjective != null)
|
if (goToObjective != null)
|
||||||
{
|
{
|
||||||
var pathSteering = character.AIController.SteeringManager as IndoorsSteeringManager;
|
var pathSteering = character.AIController.SteeringManager as IndoorsSteeringManager;
|
||||||
if (pathSteering!=null && pathSteering.CurrentPath!= null &&
|
if (pathSteering != null && pathSteering.CurrentPath != null &&
|
||||||
pathSteering.CurrentPath.Unreachable && !unreachable.Contains(goToObjective.Target))
|
pathSteering.CurrentPath.Unreachable && !unreachable.Contains(goToObjective.Target))
|
||||||
{
|
{
|
||||||
unreachable.Add(goToObjective.Target as Hull);
|
unreachable.Add(goToObjective.Target as Hull);
|
||||||
@@ -92,7 +77,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private bool FindDivingGear(float deltaTime)
|
private bool FindDivingGear(float deltaTime)
|
||||||
{
|
{
|
||||||
if (divingGearObjective==null)
|
if (divingGearObjective == null)
|
||||||
{
|
{
|
||||||
divingGearObjective = new AIObjectiveFindDivingGear(character, false);
|
divingGearObjective = new AIObjectiveFindDivingGear(character, false);
|
||||||
}
|
}
|
||||||
@@ -113,8 +98,9 @@ namespace Barotrauma
|
|||||||
if (hull == character.AnimController.CurrentHull || unreachable.Contains(hull)) continue;
|
if (hull == character.AnimController.CurrentHull || unreachable.Contains(hull)) continue;
|
||||||
|
|
||||||
float hullValue = GetHullSafety(hull, character);
|
float hullValue = GetHullSafety(hull, character);
|
||||||
hullValue -= (float)Math.Sqrt(Math.Abs(character.Position.X - hull.Position.X));
|
//slight preference over hulls that are closer
|
||||||
hullValue -= (float)Math.Sqrt(Math.Abs(character.Position.Y - hull.Position.Y) * 2.0f);
|
hullValue -= (float)Math.Sqrt(Math.Abs(character.Position.X - hull.Position.X)) * 0.1f;
|
||||||
|
hullValue -= (float)Math.Sqrt(Math.Abs(character.Position.Y - hull.Position.Y)) * 0.2f;
|
||||||
|
|
||||||
if (bestHull == null || hullValue > bestValue)
|
if (bestHull == null || hullValue > bestValue)
|
||||||
{
|
{
|
||||||
@@ -144,7 +130,7 @@ namespace Barotrauma
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override float GetPriority(Character character)
|
public override float GetPriority(AIObjectiveManager objectiveManager)
|
||||||
{
|
{
|
||||||
if (character.Oxygen < 80.0f)
|
if (character.Oxygen < 80.0f)
|
||||||
{
|
{
|
||||||
@@ -172,7 +158,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (NeedsDivingGear())
|
if (NeedsDivingGear())
|
||||||
{
|
{
|
||||||
if (divingGearObjective != null && !divingGearObjective.IsCompleted()) priority += 20.0f;
|
if (divingGearObjective != null && !divingGearObjective.IsCompleted()) priority += 20.0f;
|
||||||
@@ -185,11 +170,28 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (hull == null) return 0.0f;
|
if (hull == null) return 0.0f;
|
||||||
|
|
||||||
|
float safety = 100.0f;
|
||||||
|
|
||||||
float waterPercentage = (hull.WaterVolume / hull.Volume) * 100.0f;
|
float waterPercentage = (hull.WaterVolume / hull.Volume) * 100.0f;
|
||||||
|
if (hull.LethalPressure > 0.0f && character.PressureProtection <= 0.0f)
|
||||||
|
{
|
||||||
|
safety -= 100.0f;
|
||||||
|
}
|
||||||
|
else if (character.OxygenAvailable <= 0.0f)
|
||||||
|
{
|
||||||
|
safety -= waterPercentage;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
safety -= waterPercentage * 0.1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hull.OxygenPercentage < 30.0f) safety -= (30.0f - hull.OxygenPercentage) * 5.0f;
|
||||||
|
|
||||||
|
if (safety <= 0.0f) return 0.0f;
|
||||||
|
|
||||||
float fireAmount = 0.0f;
|
float fireAmount = 0.0f;
|
||||||
|
|
||||||
var nearbyHulls = hull.GetConnectedHulls(3);
|
var nearbyHulls = hull.GetConnectedHulls(3);
|
||||||
|
|
||||||
foreach (Hull hull2 in nearbyHulls)
|
foreach (Hull hull2 in nearbyHulls)
|
||||||
{
|
{
|
||||||
foreach (FireSource fireSource in hull2.FireSources)
|
foreach (FireSource fireSource in hull2.FireSources)
|
||||||
@@ -204,13 +206,9 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
safety -= fireAmount;
|
||||||
|
|
||||||
float safety = 100.0f - fireAmount;
|
return MathHelper.Clamp(safety, 0.0f, 100.0f);
|
||||||
|
|
||||||
if (waterPercentage > 30.0f && character.OxygenAvailable <= 0.0f) safety -= waterPercentage;
|
|
||||||
if (hull.OxygenPercentage < 30.0f) safety -= (30.0f - hull.OxygenPercentage) * 5.0f;
|
|
||||||
|
|
||||||
return safety;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
class AIObjectiveFixLeak : AIObjective
|
class AIObjectiveFixLeak : AIObjective
|
||||||
{
|
{
|
||||||
private Gap leak;
|
private readonly Gap leak;
|
||||||
|
|
||||||
|
private AIObjectiveGoTo gotoObjective;
|
||||||
|
|
||||||
public Gap Leak
|
public Gap Leak
|
||||||
{
|
{
|
||||||
@@ -20,15 +22,20 @@ namespace Barotrauma
|
|||||||
this.leak = leak;
|
this.leak = leak;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override float GetPriority(Character character)
|
public override bool IsCompleted()
|
||||||
|
{
|
||||||
|
return leak.Open <= 0.0f || leak.Removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override float GetPriority(AIObjectiveManager objectiveManager)
|
||||||
{
|
{
|
||||||
if (leak.Open == 0.0f) return 0.0f;
|
if (leak.Open == 0.0f) return 0.0f;
|
||||||
|
|
||||||
float leakSize = (leak.IsHorizontal ? leak.Rect.Height : leak.Rect.Width) * Math.Max(leak.Open, 0.1f);
|
float leakSize = (leak.IsHorizontal ? leak.Rect.Height : leak.Rect.Width) * Math.Max(leak.Open, 0.1f);
|
||||||
|
|
||||||
float dist = Vector2.DistanceSquared(character.SimPosition, leak.SimPosition);
|
float dist = Vector2.DistanceSquared(character.SimPosition, leak.SimPosition);
|
||||||
dist = Math.Max(dist/100.0f, 1.0f);
|
dist = Math.Max(dist / 100.0f, 1.0f);
|
||||||
return Math.Min(leakSize/dist, 40.0f);
|
return Math.Min(leakSize / dist, 40.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool IsDuplicate(AIObjective otherObjective)
|
public override bool IsDuplicate(AIObjective otherObjective)
|
||||||
@@ -44,7 +51,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (weldingTool == null)
|
if (weldingTool == null)
|
||||||
{
|
{
|
||||||
subObjectives.Add(new AIObjectiveGetItem(character, "Welding Tool", true));
|
AddSubObjective(new AIObjectiveGetItem(character, "Welding Tool", true));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -52,25 +59,31 @@ namespace Barotrauma
|
|||||||
var containedItems = weldingTool.ContainedItems;
|
var containedItems = weldingTool.ContainedItems;
|
||||||
if (containedItems == null) return;
|
if (containedItems == null) return;
|
||||||
|
|
||||||
var fuelTank = Array.Find(containedItems, i => i.Name == "Welding Fuel Tank" && i.Condition > 0.0f);
|
var fuelTank = Array.Find(containedItems, i => i.Prefab.NameMatches("Welding Fuel Tank") && i.Condition > 0.0f);
|
||||||
|
|
||||||
if (fuelTank == null)
|
if (fuelTank == null)
|
||||||
{
|
{
|
||||||
AddSubObjective(new AIObjectiveContainItem(character, "Welding Fuel Tank", weldingTool.GetComponent<ItemContainer>()));
|
AddSubObjective(new AIObjectiveContainItem(character, "Welding Fuel Tank", weldingTool.GetComponent<ItemContainer>()));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var repairTool = weldingTool.GetComponent<RepairTool>();
|
var repairTool = weldingTool.GetComponent<RepairTool>();
|
||||||
if (repairTool == null) return;
|
if (repairTool == null) return;
|
||||||
|
|
||||||
if (Vector2.Distance(character.WorldPosition, leak.WorldPosition) > 300.0f)
|
Vector2 standPosition = GetStandPosition();
|
||||||
|
|
||||||
|
if (Vector2.DistanceSquared(character.WorldPosition, leak.WorldPosition) > 100.0f * 100.0f)
|
||||||
{
|
{
|
||||||
AddSubObjective(new AIObjectiveGoTo(ConvertUnits.ToSimUnits(GetStandPosition()), character));
|
var gotoObjective = new AIObjectiveGoTo(ConvertUnits.ToSimUnits(standPosition), character);
|
||||||
}
|
if (!gotoObjective.IsCompleted())
|
||||||
else
|
{
|
||||||
{
|
AddSubObjective(gotoObjective);
|
||||||
AddSubObjective(new AIObjectiveOperateItem(repairTool, character, "", leak));
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AddSubObjective(new AIObjectiveOperateItem(repairTool, character, "", true, leak));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Vector2 GetStandPosition()
|
private Vector2 GetStandPosition()
|
||||||
|
|||||||
@@ -7,38 +7,80 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
class AIObjectiveFixLeaks : AIObjective
|
class AIObjectiveFixLeaks : AIObjective
|
||||||
{
|
{
|
||||||
const float UpdateGapListInterval = 10.0f;
|
const float UpdateGapListInterval = 5.0f;
|
||||||
|
|
||||||
private float updateGapListTimer;
|
private double lastGapUpdate;
|
||||||
|
|
||||||
private AIObjectiveIdle idleObjective;
|
private AIObjectiveIdle idleObjective;
|
||||||
|
|
||||||
|
private AIObjectiveFindDivingGear findDivingGear;
|
||||||
|
|
||||||
private List<AIObjectiveFixLeak> objectiveList;
|
private List<AIObjectiveFixLeak> objectiveList;
|
||||||
|
|
||||||
public AIObjectiveFixLeaks(Character character)
|
public AIObjectiveFixLeaks(Character character)
|
||||||
: base (character, "")
|
: base (character, "")
|
||||||
{
|
{
|
||||||
objectiveList = new List<AIObjectiveFixLeak>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool IsCompleted()
|
public override bool IsCompleted()
|
||||||
{
|
{
|
||||||
return false;
|
if (Timing.TotalTime > lastGapUpdate + UpdateGapListInterval || objectiveList == null)
|
||||||
|
{
|
||||||
|
UpdateGapList();
|
||||||
|
lastGapUpdate = Timing.TotalTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
return objectiveList.Count == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override float GetPriority(AIObjectiveManager objectiveManager)
|
||||||
|
{
|
||||||
|
if (Timing.TotalTime > lastGapUpdate + UpdateGapListInterval || objectiveList == null)
|
||||||
|
{
|
||||||
|
UpdateGapList();
|
||||||
|
lastGapUpdate = Timing.TotalTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
float priority = 0.0f;
|
||||||
|
foreach (AIObjectiveFixLeak fixObjective in objectiveList)
|
||||||
|
{
|
||||||
|
//gaps from outside to inside significantly increase the priority
|
||||||
|
if (!fixObjective.Leak.IsRoomToRoom)
|
||||||
|
{
|
||||||
|
priority = Math.Max(priority + fixObjective.Leak.Open * 100.0f, 50.0f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
priority += fixObjective.Leak.Open * 10.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priority >= 100.0f) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.Min(priority, 100.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Act(float deltaTime)
|
protected override void Act(float deltaTime)
|
||||||
{
|
{
|
||||||
updateGapListTimer -= deltaTime;
|
if (Timing.TotalTime > lastGapUpdate + UpdateGapListInterval || objectiveList == null)
|
||||||
|
|
||||||
if (updateGapListTimer<=0.0f)
|
|
||||||
{
|
{
|
||||||
UpdateGapList();
|
UpdateGapList();
|
||||||
|
lastGapUpdate = Timing.TotalTime;
|
||||||
updateGapListTimer = UpdateGapListInterval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (objectiveList.Any())
|
if (objectiveList.Any())
|
||||||
{
|
{
|
||||||
|
if (!objectiveList[objectiveList.Count - 1].Leak.IsRoomToRoom)
|
||||||
|
{
|
||||||
|
if (findDivingGear == null) findDivingGear = new AIObjectiveFindDivingGear(character, true);
|
||||||
|
|
||||||
|
if (!findDivingGear.IsCompleted() && findDivingGear.CanBeCompleted)
|
||||||
|
{
|
||||||
|
findDivingGear.TryComplete(deltaTime);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
objectiveList[objectiveList.Count - 1].TryComplete(deltaTime);
|
objectiveList[objectiveList.Count - 1].TryComplete(deltaTime);
|
||||||
|
|
||||||
if (!objectiveList[objectiveList.Count - 1].CanBeCompleted ||
|
if (!objectiveList[objectiveList.Count - 1].CanBeCompleted ||
|
||||||
@@ -56,6 +98,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void UpdateGapList()
|
private void UpdateGapList()
|
||||||
{
|
{
|
||||||
|
if (objectiveList == null) objectiveList = new List<AIObjectiveFixLeak>();
|
||||||
objectiveList.Clear();
|
objectiveList.Clear();
|
||||||
|
|
||||||
foreach (Gap gap in Gap.GapList)
|
foreach (Gap gap in Gap.GapList)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -26,6 +27,16 @@ namespace Barotrauma
|
|||||||
get { return canBeCompleted; }
|
get { return canBeCompleted; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override float GetPriority(AIObjectiveManager objectiveManager)
|
||||||
|
{
|
||||||
|
if (objectiveManager.CurrentOrder == this)
|
||||||
|
{
|
||||||
|
return AIObjectiveManager.OrderPriority;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
public AIObjectiveGetItem(Character character, Item targetItem, bool equip = false)
|
public AIObjectiveGetItem(Character character, Item targetItem, bool equip = false)
|
||||||
: base(character, "")
|
: base(character, "")
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -18,6 +18,16 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private bool getDivingGearIfNeeded;
|
private bool getDivingGearIfNeeded;
|
||||||
|
|
||||||
|
public override float GetPriority(AIObjectiveManager objectiveManager)
|
||||||
|
{
|
||||||
|
if (objectiveManager.CurrentOrder == this)
|
||||||
|
{
|
||||||
|
return AIObjectiveManager.OrderPriority;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
public override bool CanBeCompleted
|
public override bool CanBeCompleted
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -93,7 +103,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Vector2.Distance(currTargetPos, character.SimPosition) < 1.0f)
|
if (Vector2.DistanceSquared(currTargetPos, character.SimPosition) < 0.5f * 0.5f)
|
||||||
{
|
{
|
||||||
character.AIController.SteeringManager.Reset();
|
character.AIController.SteeringManager.Reset();
|
||||||
character.AnimController.TargetDir = currTargetPos.X > character.SimPosition.X ? Direction.Right : Direction.Left;
|
character.AnimController.TargetDir = currTargetPos.X > character.SimPosition.X ? Direction.Right : Direction.Left;
|
||||||
@@ -104,7 +114,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
var indoorsSteering = character.AIController.SteeringManager as IndoorsSteeringManager;
|
var indoorsSteering = character.AIController.SteeringManager as IndoorsSteeringManager;
|
||||||
|
|
||||||
if (indoorsSteering.CurrentPath==null || indoorsSteering.CurrentPath.Unreachable)
|
if (indoorsSteering.CurrentPath == null || indoorsSteering.CurrentPath.Unreachable)
|
||||||
{
|
{
|
||||||
indoorsSteering.SteeringWander();
|
indoorsSteering.SteeringWander();
|
||||||
}
|
}
|
||||||
@@ -130,7 +140,7 @@ namespace Barotrauma
|
|||||||
if (item.IsInsideTrigger(character.WorldPosition)) completed = true;
|
if (item.IsInsideTrigger(character.WorldPosition)) completed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
completed = completed || Vector2.Distance(target != null ? target.SimPosition : targetPos, character.SimPosition) < allowedDistance;
|
completed = completed || Vector2.DistanceSquared(target != null ? target.SimPosition : targetPos, character.SimPosition) < allowedDistance * allowedDistance;
|
||||||
|
|
||||||
if (completed) character.AIController.SteeringManager.Reset();
|
if (completed) character.AIController.SteeringManager.Reset();
|
||||||
|
|
||||||
|
|||||||
@@ -9,15 +9,21 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
const float WallAvoidDistance = 150.0f;
|
const float WallAvoidDistance = 150.0f;
|
||||||
|
|
||||||
AITarget currentTarget;
|
private AITarget currentTarget;
|
||||||
private float newTargetTimer;
|
private float newTargetTimer;
|
||||||
|
|
||||||
|
private AIObjectiveFindSafety findSafety;
|
||||||
|
|
||||||
public AIObjectiveIdle(Character character) : base(character, "")
|
public AIObjectiveIdle(Character character) : base(character, "")
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override float GetPriority(Character character)
|
public override bool IsCompleted()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override float GetPriority(AIObjectiveManager objectiveManager)
|
||||||
{
|
{
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
}
|
}
|
||||||
@@ -32,6 +38,14 @@ namespace Barotrauma
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (character.AnimController.InWater)
|
||||||
|
{
|
||||||
|
//attempt to find a safer place if in water
|
||||||
|
if (findSafety == null) findSafety = new AIObjectiveFindSafety(character);
|
||||||
|
findSafety.TryComplete(deltaTime);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (newTargetTimer <= 0.0f)
|
if (newTargetTimer <= 0.0f)
|
||||||
{
|
{
|
||||||
currentTarget = FindRandomTarget();
|
currentTarget = FindRandomTarget();
|
||||||
@@ -93,16 +107,9 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (character.AnimController.InWater)
|
character.AIController.SteeringManager.SteeringWander();
|
||||||
{
|
//reset vertical steering to prevent dropping down from platforms etc
|
||||||
character.AIController.SteeringManager.SteeringManual(deltaTime, new Vector2(0.0f, 0.5f));
|
character.AIController.SteeringManager.ResetY();
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
character.AIController.SteeringManager.SteeringWander();
|
|
||||||
//reset vertical steering to prevent dropping down from platforms etc
|
|
||||||
character.AIController.SteeringManager.ResetY();
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,15 +11,17 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private Character character;
|
private Character character;
|
||||||
|
|
||||||
private AIObjective currentObjective;
|
private AIObjective currentOrder;
|
||||||
|
|
||||||
|
public AIObjective CurrentOrder
|
||||||
|
{
|
||||||
|
get { return currentOrder; }
|
||||||
|
}
|
||||||
|
|
||||||
public AIObjective CurrentObjective
|
public AIObjective CurrentObjective
|
||||||
{
|
{
|
||||||
get
|
get;
|
||||||
{
|
private set;
|
||||||
if (currentObjective != null) return currentObjective;
|
|
||||||
return objectives.Any() ? objectives[0] : null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public AIObjectiveManager(Character character)
|
public AIObjectiveManager(Character character)
|
||||||
@@ -47,8 +49,13 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public float GetCurrentPriority(Character character)
|
public float GetCurrentPriority(Character character)
|
||||||
{
|
{
|
||||||
if (currentObjective != null) return OrderPriority;
|
if (CurrentOrder != null &&
|
||||||
return (CurrentObjective == null) ? 0.0f : CurrentObjective.GetPriority(character);
|
(objectives.Count == 0 || currentOrder.GetPriority(this) > objectives[0].GetPriority(this)))
|
||||||
|
{
|
||||||
|
return CurrentOrder.GetPriority(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return objectives.Count == 0 ? 0.0f : objectives[0].GetPriority(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateObjectives()
|
public void UpdateObjectives()
|
||||||
@@ -59,43 +66,46 @@ namespace Barotrauma
|
|||||||
objectives = objectives.FindAll(o => !o.IsCompleted() && o.CanBeCompleted);
|
objectives = objectives.FindAll(o => !o.IsCompleted() && o.CanBeCompleted);
|
||||||
|
|
||||||
//sort objectives according to priority
|
//sort objectives according to priority
|
||||||
objectives.Sort((x, y) => y.GetPriority(character).CompareTo(x.GetPriority(character)));
|
objectives.Sort((x, y) => y.GetPriority(this).CompareTo(x.GetPriority(this)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DoCurrentObjective(float deltaTime)
|
public void DoCurrentObjective(float deltaTime)
|
||||||
{
|
{
|
||||||
if (currentObjective != null && (!objectives.Any() || objectives[0].GetPriority(character) < OrderPriority))
|
if (currentOrder != null && (!objectives.Any() || objectives[0].GetPriority(this) < currentOrder.GetPriority(this)))
|
||||||
{
|
{
|
||||||
currentObjective.TryComplete(deltaTime);
|
CurrentObjective = currentOrder;
|
||||||
|
currentOrder.TryComplete(deltaTime);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!objectives.Any()) return;
|
if (!objectives.Any()) return;
|
||||||
objectives[0].TryComplete(deltaTime);
|
objectives[0].TryComplete(deltaTime);
|
||||||
|
|
||||||
|
CurrentObjective = objectives[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetOrder(Order order, string option)
|
public void SetOrder(Order order, string option)
|
||||||
{
|
{
|
||||||
if (order == null) return;
|
if (order == null) return;
|
||||||
|
|
||||||
currentObjective = null;
|
currentOrder = null;
|
||||||
|
|
||||||
switch (order.Name.ToLowerInvariant())
|
switch (order.Name.ToLowerInvariant())
|
||||||
{
|
{
|
||||||
case "follow":
|
case "follow":
|
||||||
currentObjective = new AIObjectiveGoTo(Character.Controlled, character, true);
|
currentOrder = new AIObjectiveGoTo(Character.Controlled, character, true);
|
||||||
break;
|
break;
|
||||||
case "wait":
|
case "wait":
|
||||||
currentObjective = new AIObjectiveGoTo(character, character, true);
|
currentOrder = new AIObjectiveGoTo(character, character, true);
|
||||||
break;
|
break;
|
||||||
case "fixleaks":
|
case "fixleaks":
|
||||||
case "fix leaks":
|
case "fix leaks":
|
||||||
currentObjective = new AIObjectiveFixLeaks(character);
|
currentOrder = new AIObjectiveFixLeaks(character);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (order.TargetItem == null) return;
|
if (order.TargetItem == null) return;
|
||||||
|
|
||||||
currentObjective = new AIObjectiveOperateItem(order.TargetItem, character, option, null, order.UseController);
|
currentOrder = new AIObjectiveOperateItem(order.TargetItem, character, option, false, null, order.UseController);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
+53
-3
@@ -1,5 +1,6 @@
|
|||||||
using Barotrauma.Items.Components;
|
using Barotrauma.Items.Components;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
@@ -14,6 +15,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private bool canBeCompleted;
|
private bool canBeCompleted;
|
||||||
|
|
||||||
|
private bool requireEquip;
|
||||||
|
|
||||||
public override bool CanBeCompleted
|
public override bool CanBeCompleted
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -27,11 +30,21 @@ namespace Barotrauma
|
|||||||
get { return operateTarget; }
|
get { return operateTarget; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public AIObjectiveOperateItem(ItemComponent item, Character character, string option, Entity operateTarget = null, bool useController = false)
|
public override float GetPriority(AIObjectiveManager objectiveManager)
|
||||||
:base (character, option)
|
{
|
||||||
|
if (objectiveManager.CurrentOrder == this)
|
||||||
|
{
|
||||||
|
return AIObjectiveManager.OrderPriority;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AIObjectiveOperateItem(ItemComponent item, Character character, string option, bool requireEquip, Entity operateTarget = null, bool useController = false)
|
||||||
|
: base (character, option)
|
||||||
{
|
{
|
||||||
this.component = item;
|
this.component = item;
|
||||||
|
this.requireEquip = requireEquip;
|
||||||
this.operateTarget = operateTarget;
|
this.operateTarget = operateTarget;
|
||||||
|
|
||||||
if (useController)
|
if (useController)
|
||||||
@@ -72,6 +85,43 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (requireEquip && !character.HasEquippedItem(component.Item))
|
||||||
|
{
|
||||||
|
//the item has to be equipped before using it if it's holdable
|
||||||
|
var holdable = component.Item.GetComponent<Holdable>();
|
||||||
|
if (holdable == null)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("AIObjectiveOperateItem failed - equipping item " + component.Item + " is required but the item has no Holdable component");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < CharacterInventory.limbSlots.Length; i++)
|
||||||
|
{
|
||||||
|
if (CharacterInventory.limbSlots[i] == InvSlotType.Any ||
|
||||||
|
!holdable.AllowedSlots.Any(s => s.HasFlag(CharacterInventory.limbSlots[i])))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//equip slot already taken
|
||||||
|
if (character.Inventory.Items[i] != null)
|
||||||
|
{
|
||||||
|
//try to put the item in an Any slot, and drop it if that fails
|
||||||
|
if (!character.Inventory.Items[i].AllowedSlots.Contains(InvSlotType.Any) ||
|
||||||
|
!character.Inventory.TryPutItem(character.Inventory.Items[i], character, new List<InvSlotType>() { InvSlotType.Any }))
|
||||||
|
{
|
||||||
|
character.Inventory.Items[i].Drop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (character.Inventory.TryPutItem(component.Item, i, true, character))
|
||||||
|
{
|
||||||
|
component.Item.Equip(character);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (component.AIOperate(deltaTime, character, this)) isCompleted = true;
|
if (component.AIOperate(deltaTime, character, this)) isCompleted = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using System.Diagnostics;
|
|||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
class AIObjectiveRescue : AIObjective
|
/*class AIObjectiveRescue : AIObjective
|
||||||
{
|
{
|
||||||
private readonly Character targetCharacter;
|
private readonly Character targetCharacter;
|
||||||
|
|
||||||
@@ -30,5 +30,5 @@ namespace Barotrauma
|
|||||||
return targetCharacter.IsDead ? 1000.0f / distance : 10000.0f / distance;
|
return targetCharacter.IsDead ? 1000.0f / distance : 10000.0f / distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using System.Linq;
|
|||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
class AIObjectiveRescueAll : AIObjective
|
/*class AIObjectiveRescueAll : AIObjective
|
||||||
{
|
{
|
||||||
private List<Character> rescueTargets;
|
private List<Character> rescueTargets;
|
||||||
|
|
||||||
@@ -44,5 +44,5 @@ namespace Barotrauma
|
|||||||
AddSubObjective(new AIObjectiveRescue(character, target));
|
AddSubObjective(new AIObjectiveRescue(character, target));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,10 +104,6 @@ namespace Barotrauma.Items.Components
|
|||||||
if (character == null) return false;
|
if (character == null) return false;
|
||||||
if (!character.IsKeyDown(InputType.Aim)) return false;
|
if (!character.IsKeyDown(InputType.Aim)) return false;
|
||||||
|
|
||||||
//if (DoesUseFail(Character)) return false;
|
|
||||||
|
|
||||||
//targetPosition = targetPosition.X, -targetPosition.Y);
|
|
||||||
|
|
||||||
float degreeOfSuccess = DegreeOfSuccess(character)/100.0f;
|
float degreeOfSuccess = DegreeOfSuccess(character)/100.0f;
|
||||||
|
|
||||||
if (Rand.Range(0.0f, 0.5f) > degreeOfSuccess)
|
if (Rand.Range(0.0f, 0.5f) > degreeOfSuccess)
|
||||||
|
|||||||
@@ -258,9 +258,9 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
if (batteryToLoad == null) return true;
|
if (batteryToLoad == null) return true;
|
||||||
|
|
||||||
if (batteryToLoad.RechargeSpeed < batteryToLoad.MaxRechargeSpeed*0.4f)
|
if (batteryToLoad.RechargeSpeed < batteryToLoad.MaxRechargeSpeed * 0.4f)
|
||||||
{
|
{
|
||||||
objective.AddSubObjective(new AIObjectiveOperateItem(batteryToLoad, character, ""));
|
objective.AddSubObjective(new AIObjectiveOperateItem(batteryToLoad, character, "", false));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user