(ac7ab10b0) Pass AIObjectiveManager reference in the constructors instead of methods so that we can always access it.

This commit is contained in:
Joonas Rikkonen
2019-05-16 05:14:20 +03:00
parent bec7aadfa9
commit 2ae54a01a5
40 changed files with 290 additions and 322 deletions

View File

@@ -37,16 +37,16 @@ namespace Barotrauma
var currentOrder = ObjectiveManager.CurrentOrder;
if (currentOrder != null)
{
GUI.DrawString(spriteBatch, pos + textOffset, $"ORDER: {currentOrder.DebugTag} ({currentOrder.GetPriority(ObjectiveManager).FormatZeroDecimal()})", Color.White, Color.Black);
GUI.DrawString(spriteBatch, pos + textOffset, $"ORDER: {currentOrder.DebugTag} ({currentOrder.GetPriority().FormatZeroDecimal()})", Color.White, Color.Black);
}
var currentObjective = ObjectiveManager.CurrentObjective;
if (currentObjective != null)
{
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(0, 20), $"OBJECTIVE: {currentObjective.DebugTag} ({currentObjective.GetPriority(ObjectiveManager).FormatZeroDecimal()})", Color.White, Color.Black);
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(0, 20), $"OBJECTIVE: {currentObjective.DebugTag} ({currentObjective.GetPriority().FormatZeroDecimal()})", Color.White, Color.Black);
var subObjective = currentObjective.CurrentSubObjective;
if (subObjective != null)
{
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(0, 40), $"SUBOBJECTIVE: {subObjective.DebugTag} ({subObjective.GetPriority(ObjectiveManager).FormatZeroDecimal()})", Color.White, Color.Black);
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(0, 40), $"SUBOBJECTIVE: {subObjective.DebugTag} ({subObjective.GetPriority().FormatZeroDecimal()})", Color.White, Color.Black);
}
}
}

View File

@@ -175,6 +175,14 @@ namespace Barotrauma
}
}
partial void UpdateLimbLightSource(Limb limb)
{
if (limb.LightSource != null)
{
limb.LightSource.Enabled = enabled;
}
}
private bool wasFiring;
/// <summary>

View File

@@ -233,6 +233,12 @@ namespace Barotrauma
Content = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.85f), InnerFrame.RectTransform, Anchor.Center)) { AbsoluteSpacing = 5 };
Tag = tag;
InnerFrame = new GUIFrame(new RectTransform(new Point(width, height), RectTransform, Anchor.Center) { IsFixedSize = false }, style: null);
GUI.Style.Apply(InnerFrame, "", this);
Content = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.85f), InnerFrame.RectTransform, Anchor.Center)) { AbsoluteSpacing = 5 };
Tag = tag;
if (height == 0)
{
string wrappedText = ToolBox.WrapText(text, Content.Rect.Width, GUI.Font);

View File

@@ -74,47 +74,12 @@ namespace Barotrauma
public CrewManager(XElement element, bool isSinglePlayer)
: this(isSinglePlayer)
{
guiFrame = new GUIFrame(new RectTransform(Vector2.One, GUICanvas.Instance), null, Color.Transparent)
if (!isSinglePlayer)
{
CanBeFocused = false
};
Point scrollButtonSize = new Point((int)(200 * GUI.Scale), (int)(30 * GUI.Scale));
crewArea = new GUIFrame(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.CrewArea, guiFrame.RectTransform), "", Color.Transparent)
{
CanBeFocused = false
};
toggleCrewButton = new GUIButton(new RectTransform(new Point((int)(30 * GUI.Scale), HUDLayoutSettings.CrewArea.Height), guiFrame.RectTransform)
{ AbsoluteOffset = HUDLayoutSettings.CrewArea.Location },
"", style: "UIToggleButton");
toggleCrewButton.OnClicked += (GUIButton btn, object userdata) =>
{
ToggleCrewAreaOpen = !ToggleCrewAreaOpen;
return true;
};
characterListBox = new GUIListBox(new RectTransform(new Point(100, (int)(crewArea.Rect.Height - scrollButtonSize.Y * 1.6f)), crewArea.RectTransform, Anchor.CenterLeft), false, Color.Transparent, null)
{
//Spacing = (int)(3 * GUI.Scale),
ScrollBarEnabled = false,
ScrollBarVisible = false,
CanBeFocused = false
};
scrollButtonUp = new GUIButton(new RectTransform(scrollButtonSize, crewArea.RectTransform, Anchor.TopLeft, Pivot.TopLeft), "", Alignment.Center, "GUIButtonVerticalArrow")
{
Visible = false,
UserData = -1,
OnClicked = ScrollCharacterList
};
scrollButtonDown = new GUIButton(new RectTransform(scrollButtonSize, crewArea.RectTransform, Anchor.BottomLeft, Pivot.BottomLeft), "", Alignment.Center, "GUIButtonVerticalArrow")
{
Visible = false,
UserData = 1,
OnClicked = ScrollCharacterList
};
scrollButtonDown.Children.ForEach(c => c.SpriteEffects = SpriteEffects.FlipVertically);
DebugConsole.ThrowError("Cannot add messages to single player chat box in multiplayer mode!\n" + Environment.StackTrace);
return;
}
if (string.IsNullOrEmpty(text)) { return; }
var characterInfo = new CharacterInfo(subElement);
characterInfos.Add(characterInfo);
@@ -125,66 +90,7 @@ namespace Barotrauma
break;
}
}
var reports = Order.PrefabList.FindAll(o => o.TargetAllCharacters && o.SymbolSprite != null);
reportButtonFrame = new GUILayoutGroup(new RectTransform(
new Point((HUDLayoutSettings.CrewArea.Height - (int)((reports.Count - 1) * 5 * GUI.Scale)) / reports.Count, HUDLayoutSettings.CrewArea.Height), guiFrame.RectTransform))
{
AbsoluteSpacing = (int)(5 * GUI.Scale),
UserData = "reportbuttons",
CanBeFocused = false
};
//report buttons
foreach (Order order in reports)
{
if (!order.TargetAllCharacters || order.SymbolSprite == null) continue;
var btn = new GUIButton(new RectTransform(new Point(reportButtonFrame.Rect.Width), reportButtonFrame.RectTransform), style: null)
{
OnClicked = (GUIButton button, object userData) =>
{
if (Character.Controlled == null || Character.Controlled.SpeechImpediment >= 100.0f) return false;
SetCharacterOrder(null, order, null, Character.Controlled);
HumanAIController.PropagateHullSafety(Character.Controlled, Character.Controlled.CurrentHull);
return true;
},
UserData = order,
ToolTip = order.Name
};
new GUIFrame(new RectTransform(new Vector2(1.5f), btn.RectTransform, Anchor.Center), "OuterGlow")
{
Color = Color.Red * 0.8f,
HoverColor = Color.Red * 1.0f,
PressedColor = Color.Red * 0.6f,
UserData = "highlighted",
CanBeFocused = false,
Visible = false
};
var img = new GUIImage(new RectTransform(Vector2.One, btn.RectTransform), order.Prefab.SymbolSprite, scaleToFit: true)
{
Color = order.Color,
HoverColor = Color.Lerp(order.Color, Color.White, 0.5f),
ToolTip = order.Name
};
}
screenResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
prevUIScale = GUI.Scale;
ToggleCrewAreaOpen = GameMain.Config.CrewMenuOpen;
}
#endregion
#region Character list management
public Rectangle GetCharacterListArea()
{
return characterListBox.Rect;
ChatBox.AddMessage(ChatMessage.Create(senderName, text, messageType, sender));
}
partial void InitProjectSpecific()
@@ -332,12 +238,27 @@ namespace Barotrauma
public IEnumerable<Character> GetCharacters()
{
return characters;
if (character?.Inventory == null) return null;
var radioItem = character.Inventory.Items.FirstOrDefault(it => it != null && it.GetComponent<WifiComponent>() != null);
if (radioItem == null) return null;
if (requireEquipped && !character.HasEquippedItem(radioItem)) return null;
return radioItem.GetComponent<WifiComponent>();
}
public IEnumerable<CharacterInfo> GetCharacterInfos()
{
return characterInfos;
if (GameMain.Client != null)
{
//let the server create random conversations in MP
return;
}
List<Character> availableSpeakers = Character.CharacterList.FindAll(c =>
c.AIController is HumanAIController &&
!c.IsDead &&
c.SpeechImpediment <= 100.0f);
pendingConversationLines.AddRange(NPCConversation.CreateRandom(availableSpeakers));
}
public void AddCharacter(Character character)
@@ -711,33 +632,9 @@ namespace Barotrauma
{
characterListBox.BarScroll = roundedPos;
}
}
public void AddCharacterInfo(CharacterInfo characterInfo)
{
if (characterInfos.Contains(characterInfo))
{
DebugConsole.ThrowError("Tried to add the same character info to CrewManager twice.\n" + Environment.StackTrace);
return;
}
characterInfos.Add(characterInfo);
}
/// <summary>
/// Remove the character from the crew (and crew menus).
/// </summary>
/// <param name="character">The character to remove</param>
/// <param name="removeInfo">If the character info is also removed, the character will not be visible in the round summary.</param>
public void RemoveCharacter(Character character, bool removeInfo = false)
{
if (character == null)
{
DebugConsole.ThrowError("Tried to remove a null character from CrewManager.\n" + Environment.StackTrace);
return;
}
characters.Remove(character);
if (removeInfo) characterInfos.Remove(character.Info);
soundIcon.Visible = !muted && !mutedLocally;
soundIconDisabled.Visible = muted || mutedLocally;
soundIconDisabled.ToolTip = TextManager.Get(mutedLocally ? "MutedLocally" : "MutedGlobally");
}
private IEnumerable<object> KillCharacterAnim(GUIComponent component)
@@ -938,23 +835,19 @@ namespace Barotrauma
}
}
}
character.SetOrder(order, option, orderGiver, speak: orderGiver != character);
if (IsSinglePlayer)
//only one target (or an order with no particular targets), just show options
else
{
orderGiver?.Speak(
order.GetChatMessage(character.Name, orderGiver.CurrentHull?.DisplayName, givingOrderToSelf: character == orderGiver, orderOption: option), null);
}
else if (orderGiver != null)
{
OrderChatMessage msg = new OrderChatMessage(order, option, order.TargetItemComponent?.Item, character, orderGiver);
if (GameMain.Client != null)
orderTargetFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.2f + order.Options.Length * 0.1f, 0.18f), GUI.Canvas)
{ AbsoluteOffset = new Point(orderButton.Rect.Center.X, orderButton.Rect.Bottom) },
isHorizontal: true, childAnchor: Anchor.BottomLeft)
{
GameMain.Client.SendChatMessage(msg);
}
}
DisplayCharacterOrder(character, order);
}
UserData = character,
Stretch = true
};
//line connecting the order button to the option buttons
//TODO: sprite
new GUIFrame(new RectTransform(new Vector2(0.5f, 1.0f), orderTargetFrame.RectTransform), style: null);
/// <summary>
/// Create the UI panel that's used to select the target and options for a given order

View File

@@ -22,6 +22,8 @@ namespace Barotrauma
private GUILayoutGroup subPreviewContainer;
private GUILayoutGroup subPreviewContainer;
private GUIButton loadGameButton;
public Action<Submarine, string, string> StartNewGame;

View File

@@ -1112,6 +1112,8 @@ namespace Barotrauma
private bool IsProperlyLatchedOnSub => LatchOntoAI != null && LatchOntoAI.IsAttachedToSub && SelectedAiTarget?.Entity == wallTarget?.Structure;
private bool IsProperlyLatchedOnSub => LatchOntoAI != null && LatchOntoAI.IsAttachedToSub && SelectedAiTarget?.Entity == wallTarget?.Structure;
//goes through all the AItargets, evaluates how preferable it is to attack the target,
//whether the Character can see/hear the target and chooses the most preferable target within
//sight/hearing range

View File

@@ -337,18 +337,18 @@ namespace Barotrauma
{
// Replace the old objective with the new.
ObjectiveManager.Objectives.Remove(combatObjective);
objectiveManager.AddObjective(new AIObjectiveCombat(Character, attacker, mode));
objectiveManager.AddObjective(new AIObjectiveCombat(Character, attacker, mode, objectiveManager));
}
}
else
{
if (delay > 0)
{
objectiveManager.AddObjective(new AIObjectiveCombat(Character, attacker, mode), delay);
objectiveManager.AddObjective(new AIObjectiveCombat(Character, attacker, mode, objectiveManager), delay);
}
else
{
objectiveManager.AddObjective(new AIObjectiveCombat(Character, attacker, mode));
objectiveManager.AddObjective(new AIObjectiveCombat(Character, attacker, mode, objectiveManager));
}
}
}

View File

@@ -17,8 +17,10 @@ namespace Barotrauma
protected readonly List<AIObjective> subObjectives = new List<AIObjective>();
public float Priority { get; set; }
public float PriorityModifier { get; private set; }
protected readonly Character character;
protected string option;
public readonly Character character;
public readonly AIObjectiveManager objectiveManager;
public string Option { get; protected set; }
protected bool abandon;
/// <summary>
@@ -36,16 +38,13 @@ namespace Barotrauma
protected HumanAIController HumanAIController => character.AIController as HumanAIController;
protected IndoorsSteeringManager PathSteering => HumanAIController.PathSteering;
protected SteeringManager SteeringManager => HumanAIController.SteeringManager;
public string Option
{
get { return option; }
}
public AIObjective(Character character, string option, float priorityModifier)
public AIObjective(Character character, AIObjectiveManager objectiveManager, float priorityModifier, string option = null)
{
this.objectiveManager = objectiveManager;
this.character = character;
this.option = option;
Option = option ?? string.Empty;
PriorityModifier = priorityModifier;
#if DEBUG
IsDuplicate(null);
@@ -100,22 +99,21 @@ namespace Barotrauma
public void AddSubObjective(AIObjective objective)
{
if (subObjectives.Any(o => o.IsDuplicate(objective))) return;
if (subObjectives.Any(o => o.IsDuplicate(objective))) { return; }
subObjectives.Add(objective);
}
public void SortSubObjectives(AIObjectiveManager objectiveManager)
public void SortSubObjectives()
{
if (subObjectives.None()) { return; }
subObjectives.Sort((x, y) => y.GetPriority(objectiveManager).CompareTo(x.GetPriority(objectiveManager)));
subObjectives.Sort((x, y) => y.GetPriority().CompareTo(x.GetPriority()));
CurrentSubObjective = SubObjectives.First();
CurrentSubObjective.SortSubObjectives(objectiveManager);
CurrentSubObjective.SortSubObjectives();
}
public virtual float GetPriority(AIObjectiveManager objectiveManager) => Priority * PriorityModifier;
public virtual float GetPriority() => Priority * PriorityModifier;
public virtual void Update(AIObjectiveManager objectiveManager, float deltaTime)
public virtual void Update(float deltaTime)
{
var subObjective = objectiveManager.CurrentObjective?.CurrentSubObjective;
if (objectiveManager.CurrentOrder == this)
@@ -127,7 +125,7 @@ namespace Barotrauma
Priority += Devotion * PriorityModifier * deltaTime;
}
Priority = MathHelper.Clamp(Priority, 0, 100);
subObjectives.ForEach(so => so.Update(objectiveManager, deltaTime));
subObjectives.ForEach(so => so.Update(deltaTime));
}
/// <summary>

View File

@@ -10,7 +10,8 @@ namespace Barotrauma
public override string DebugTag => "charge batteries";
private readonly IEnumerable<PowerContainer> batteryList;
public AIObjectiveChargeBatteries(Character character, string option) : base(character, option)
public AIObjectiveChargeBatteries(Character character, AIObjectiveManager objectiveManager, string option, float priorityModifier)
: base(character, objectiveManager, priorityModifier, option)
{
batteryList = Item.ItemList.Select(i => i.GetComponent<PowerContainer>()).Where(b => b != null);
}
@@ -23,15 +24,10 @@ namespace Barotrauma
protected override void FindTargets()
{
base.FindTargets();
if (targets.None())
if (targets.None() && objectiveManager.CurrentOrder == this)
{
character.Speak(TextManager.Get("DialogNoBatteries"), null, 4.0f, "nobatteries", 10.0f);
}
else
{
// Sorting should be handled by the objective manager, because the targets should be subobjectives.
//targets.Sort((x, y) => x.ChargePercentage.CompareTo(y.ChargePercentage));
}
}
protected override bool Filter(PowerContainer battery)
@@ -45,6 +41,8 @@ namespace Barotrauma
protected override float TargetEvaluation() => targets.Max(t => 100 - t.ChargePercentage);
protected override IEnumerable<PowerContainer> GetList() => batteryList;
protected override AIObjective ObjectiveConstructor(PowerContainer battery) => new AIObjectiveOperateItem(battery, character, Option, false, priorityModifier: PriorityModifier) { IsLoop = true };
protected override AIObjective ObjectiveConstructor(PowerContainer battery)
=> new AIObjectiveOperateItem(battery, character, objectiveManager, Option, false, priorityModifier: PriorityModifier) { IsLoop = true };
}
}

View File

@@ -58,11 +58,12 @@ namespace Barotrauma
public CombatMode Mode { get; private set; }
public AIObjectiveCombat(Character character, Character enemy, CombatMode mode, float priorityModifier = 1) : base(character, "", priorityModifier)
public AIObjectiveCombat(Character character, Character enemy, CombatMode mode, AIObjectiveManager objectiveManager, float priorityModifier = 1)
: base(character, objectiveManager, priorityModifier)
{
Enemy = enemy;
coolDownTimer = CoolDown;
findSafety = HumanAIController.ObjectiveManager.GetObjective<AIObjectiveFindSafety>();
findSafety = objectiveManager.GetObjective<AIObjectiveFindSafety>();
findSafety.Priority = 0;
findSafety.unreachable.Clear();
Mode = mode;
@@ -185,7 +186,7 @@ namespace Barotrauma
{
if (retreatObjective == null || retreatObjective.Target != retreatTarget)
{
retreatObjective = new AIObjectiveGoTo(retreatTarget, character, false, true);
retreatObjective = new AIObjectiveGoTo(retreatTarget, character, objectiveManager, false, true);
}
retreatObjective.TryComplete(deltaTime);
}
@@ -203,7 +204,7 @@ namespace Barotrauma
{
if (reloadWeaponObjective == null)
{
reloadWeaponObjective = new AIObjectiveContainItem(character, requiredItem.Identifiers, Weapon.GetComponent<ItemContainer>());
reloadWeaponObjective = new AIObjectiveContainItem(character, requiredItem.Identifiers, Weapon.GetComponent<ItemContainer>(), objectiveManager);
}
}
}
@@ -297,7 +298,7 @@ namespace Barotrauma
}
public override bool CanBeCompleted => !abandon && (reloadWeaponObjective == null || reloadWeaponObjective.CanBeCompleted) && (retreatObjective == null || retreatObjective.CanBeCompleted);
public override float GetPriority(AIObjectiveManager objectiveManager) => (Enemy != null && (Enemy.Removed || Enemy.IsDead)) ? 0 : Math.Min(100 * PriorityModifier, 100);
public override float GetPriority() => (Enemy != null && (Enemy.Removed || Enemy.IsDead)) ? 0 : Math.Min(100 * PriorityModifier, 100);
public override bool IsDuplicate(AIObjective otherObjective)
{

View File

@@ -27,7 +27,11 @@ namespace Barotrauma
public AIObjectiveContainItem(Character character, string itemIdentifier, ItemContainer container, float priorityModifier = 1) : this(character, new string[] { itemIdentifier }, container, priorityModifier) { }
public AIObjectiveContainItem(Character character, string[] itemIdentifiers, ItemContainer container, float priorityModifier = 1) : base (character, "", priorityModifier)
public AIObjectiveContainItem(Character character, string itemIdentifier, ItemContainer container, AIObjectiveManager objectiveManager, float priorityModifier = 1)
: this(character, new string[] { itemIdentifier }, container, objectiveManager, priorityModifier) { }
public AIObjectiveContainItem(Character character, string[] itemIdentifiers, ItemContainer container, AIObjectiveManager objectiveManager, float priorityModifier = 1)
: base (character, objectiveManager, priorityModifier)
{
this.itemIdentifiers = itemIdentifiers;
for (int i = 0; i < itemIdentifiers.Length; i++)
@@ -64,7 +68,7 @@ namespace Barotrauma
}
}
public override float GetPriority(AIObjectiveManager objectiveManager)
public override float GetPriority()
{
if (objectiveManager.CurrentOrder == this)
{
@@ -88,7 +92,7 @@ namespace Barotrauma
if (itemToContain == null)
{
getItemObjective = new AIObjectiveGetItem(character, itemIdentifiers)
getItemObjective = new AIObjectiveGetItem(character, itemIdentifiers, objectiveManager)
{
GetItemPriority = GetItemPriority,
ignoredContainerIdentifiers = ignoredContainerIdentifiers
@@ -111,7 +115,7 @@ namespace Barotrauma
{
if (container.Item.CurrentHull != character.CurrentHull || (Vector2.Distance(character.Position, container.Item.Position) > container.Item.InteractDistance && !container.Item.IsInsideTrigger(character.WorldPosition)))
{
goToObjective = new AIObjectiveGoTo(container.Item, character);
goToObjective = new AIObjectiveGoTo(container.Item, character, objectiveManager);
AddSubObjective(goToObjective);
return;
}

View File

@@ -21,16 +21,19 @@ namespace Barotrauma
private AIObjectiveGoTo goToObjective;
private Item targetItem;
public AIObjectiveDecontainItem(Character character, Item targetItem, ItemContainer container, float priorityModifier = 1) : base(character, "", priorityModifier)
public AIObjectiveDecontainItem(Character character, Item targetItem, ItemContainer container, AIObjectiveManager objectiveManager, float priorityModifier = 1)
: base(character, objectiveManager, priorityModifier)
{
this.targetItem = targetItem;
this.container = container;
}
public AIObjectiveDecontainItem(Character character, string itemIdentifier, ItemContainer container, float priorityModifier = 1) : this(character, new string[] { itemIdentifier }, container, priorityModifier) { }
public AIObjectiveDecontainItem(Character character, string itemIdentifier, ItemContainer container, AIObjectiveManager objectiveManager, float priorityModifier = 1)
: this(character, new string[] { itemIdentifier }, container, objectiveManager, priorityModifier) { }
public AIObjectiveDecontainItem(Character character, string[] itemIdentifiers, ItemContainer container, float priorityModifier = 1) : base(character, "", priorityModifier)
public AIObjectiveDecontainItem(Character character, string[] itemIdentifiers, ItemContainer container, AIObjectiveManager objectiveManager, float priorityModifier = 1)
: base(character, objectiveManager, priorityModifier)
{
this.itemIdentifiers = itemIdentifiers;
for (int i = 0; i < itemIdentifiers.Length; i++)
@@ -59,7 +62,7 @@ namespace Barotrauma
}
}
public override float GetPriority(AIObjectiveManager objectiveManager)
public override float GetPriority()
{
if (objectiveManager.CurrentOrder == this)
{
@@ -103,7 +106,7 @@ namespace Barotrauma
if (Vector2.Distance(character.Position, container.Item.Position) > container.Item.InteractDistance
&& !container.Item.IsInsideTrigger(character.WorldPosition))
{
goToObjective = new AIObjectiveGoTo(container.Item, character);
goToObjective = new AIObjectiveGoTo(container.Item, character, objectiveManager);
AddSubObjective(goToObjective);
return;
}

View File

@@ -20,12 +20,13 @@ namespace Barotrauma
private float useExtinquisherTimer;
public AIObjectiveExtinguishFire(Character character, Hull targetHull, float priorityModifier = 1) : base(character, "", priorityModifier)
public AIObjectiveExtinguishFire(Character character, Hull targetHull, AIObjectiveManager objectiveManager, float priorityModifier = 1)
: base(character, objectiveManager, priorityModifier)
{
this.targetHull = targetHull;
}
public override float GetPriority(AIObjectiveManager objectiveManager)
public override float GetPriority()
{
if (gotoObjective != null && !gotoObjective.CanBeCompleted) { return 0; }
// Vertical distance matters more than horizontal (climbing up/down is harder than moving horizontally)
@@ -61,7 +62,7 @@ namespace Barotrauma
if (getExtinguisherObjective == null)
{
character.Speak(TextManager.Get("DialogFindExtinguisher"), null, 2.0f, "findextinguisher", 30.0f);
getExtinguisherObjective = new AIObjectiveGetItem(character, "extinguisher", true);
getExtinguisherObjective = new AIObjectiveGetItem(character, "extinguisher", objectiveManager, equip: true);
}
else
{
@@ -105,7 +106,7 @@ namespace Barotrauma
//go to the first firesource
if (gotoObjective == null || !gotoObjective.CanBeCompleted || gotoObjective.IsCompleted())
{
gotoObjective = new AIObjectiveGoTo(ConvertUnits.ToSimUnits(fs.Position), character);
gotoObjective = new AIObjectiveGoTo(ConvertUnits.ToSimUnits(fs.Position), character, objectiveManager);
}
else
{

View File

@@ -10,14 +10,14 @@ namespace Barotrauma
public override bool ForceRun => true;
public override bool KeepDivingGearOn => true;
public AIObjectiveExtinguishFires(Character character, float priorityModifier = 1) : base(character, "", priorityModifier) { }
public AIObjectiveExtinguishFires(Character character, AIObjectiveManager objectiveManager, float priorityModifier = 1) : base(character, objectiveManager, priorityModifier) { }
protected override void FindTargets()
{
base.FindTargets();
if (targets.None())
if (targets.None() && objectiveManager.CurrentOrder == this)
{
character?.Speak(TextManager.Get("DialogNoFire"), null, 3.0f, "nofire", 30.0f);
character.Speak(TextManager.Get("DialogNoFire"), null, 3.0f, "nofire", 30.0f);
}
}
@@ -30,13 +30,13 @@ namespace Barotrauma
return true;
}
protected override float TargetEvaluation() => (HumanAIController.ObjectiveManager.CurrentObjective == this || HumanAIController.ObjectiveManager.CurrentOrder == this) ? 100 : targets.Sum(t => GetFireSeverity(t));
protected override float TargetEvaluation() => (objectiveManager.CurrentObjective == this || objectiveManager.CurrentOrder == this) ? 100 : targets.Sum(t => GetFireSeverity(t));
public static float GetFireSeverity(Hull hull) => hull.FireSources.Sum(fs => fs.Size.X);
public override bool IsDuplicate(AIObjective otherObjective) => otherObjective is AIObjectiveExtinguishFires;
protected override IEnumerable<Hull> GetList() => Hull.hullList;
protected override AIObjective ObjectiveConstructor(Hull target) => new AIObjectiveExtinguishFire(character, target, PriorityModifier);
protected override AIObjective ObjectiveConstructor(Hull target) => new AIObjectiveExtinguishFire(character, target, objectiveManager, PriorityModifier);
}
}

View File

@@ -29,7 +29,7 @@ namespace Barotrauma
return false;
}
public AIObjectiveFindDivingGear(Character character, bool needDivingSuit, float priorityModifier = 1) : base(character, "", priorityModifier)
public AIObjectiveFindDivingGear(Character character, bool needDivingSuit, AIObjectiveManager objectiveManager, float priorityModifier = 1) : base(character, objectiveManager, priorityModifier)
{
gearTag = needDivingSuit ? "divingsuit" : "diving";
}
@@ -43,7 +43,7 @@ namespace Barotrauma
if (!(subObjective is AIObjectiveGetItem))
{
character.Speak(TextManager.Get("DialogGetDivingGear"), null, 0.0f, "getdivinggear", 30.0f);
subObjective = new AIObjectiveGetItem(character, gearTag, true);
subObjective = new AIObjectiveGetItem(character, gearTag, objectiveManager, equip: true);
}
}
else
@@ -67,7 +67,7 @@ namespace Barotrauma
if (!(subObjective is AIObjectiveContainItem) || subObjective.IsCompleted())
{
character.Speak(TextManager.Get("DialogGetOxygenTank"), null, 0, "getoxygentank", 30.0f);
subObjective = new AIObjectiveContainItem(character, new string[] { "oxygentank", "oxygensource" }, item.GetComponent<ItemContainer>());
subObjective = new AIObjectiveContainItem(character, new string[] { "oxygentank", "oxygensource" }, item.GetComponent<ItemContainer>(), objectiveManager);
}
}
if (subObjective != null)
@@ -77,7 +77,7 @@ namespace Barotrauma
}
public override bool CanBeCompleted => subObjective == null || subObjective.CanBeCompleted;
public override float GetPriority(AIObjectiveManager objectiveManager) => MathHelper.Clamp(100 - character.OxygenAvailable, 0, 100);
public override float GetPriority() => MathHelper.Clamp(100 - character.OxygenAvailable, 0, 100);
public override bool IsDuplicate(AIObjective otherObjective) => otherObjective is AIObjectiveFindDivingGear;
}
}

View File

@@ -27,7 +27,7 @@ namespace Barotrauma
private AIObjectiveGoTo goToObjective;
private AIObjectiveFindDivingGear divingGearObjective;
public AIObjectiveFindSafety(Character character, float priorityModifier = 1) : base(character, "", priorityModifier) { }
public AIObjectiveFindSafety(Character character, AIObjectiveManager objectiveManager, float priorityModifier = 1) : base(character, objectiveManager, priorityModifier) { }
public override bool IsCompleted() => false;
public override bool CanBeCompleted => true;
@@ -41,7 +41,7 @@ namespace Barotrauma
bool hasEquipment = needsDivingSuit ? HumanAIController.HasDivingSuit(character) : HumanAIController.HasDivingGear(character);
if (!hasEquipment)
{
divingGearObjective = new AIObjectiveFindDivingGear(character, needsDivingSuit);
divingGearObjective = new AIObjectiveFindDivingGear(character, needsDivingSuit, objectiveManager);
}
}
if (divingGearObjective != null)
@@ -94,7 +94,7 @@ namespace Barotrauma
if (goToObjective.Target != bestHull)
{
// If we need diving gear, we should already have it, if possible.
goToObjective = new AIObjectiveGoTo(bestHull, character, getDivingGearIfNeeded: false)
goToObjective = new AIObjectiveGoTo(bestHull, character, objectiveManager, getDivingGearIfNeeded: false)
{
AllowGoingOutside = HumanAIController.HasDivingSuit(character)
};
@@ -102,7 +102,7 @@ namespace Barotrauma
}
else
{
goToObjective = new AIObjectiveGoTo(bestHull, character, getDivingGearIfNeeded: false)
goToObjective = new AIObjectiveGoTo(bestHull, character, objectiveManager, getDivingGearIfNeeded: false)
{
AllowGoingOutside = HumanAIController.HasDivingSuit(character)
};
@@ -255,7 +255,7 @@ namespace Barotrauma
return (otherObjective is AIObjectiveFindSafety);
}
public override void Update(AIObjectiveManager objectiveManager, float deltaTime)
public override void Update(float deltaTime)
{
if (character.CurrentHull == null)
{

View File

@@ -24,7 +24,7 @@ namespace Barotrauma
get { return leak; }
}
public AIObjectiveFixLeak(Gap leak, Character character, float priorityModifier = 1) : base (character, "", priorityModifier)
public AIObjectiveFixLeak(Gap leak, Character character, AIObjectiveManager objectiveManager, float priorityModifier = 1) : base (character, objectiveManager, priorityModifier)
{
this.leak = leak;
}
@@ -36,7 +36,7 @@ namespace Barotrauma
public override bool CanBeCompleted => !abandon && base.CanBeCompleted;
public override float GetPriority(AIObjectiveManager objectiveManager)
public override float GetPriority()
{
if (leak.Open == 0.0f) { return 0.0f; }
// Vertical distance matters more than horizontal (climbing up/down is harder than moving horizontally)
@@ -61,7 +61,7 @@ namespace Barotrauma
{
if (findDivingGear == null)
{
findDivingGear = new AIObjectiveFindDivingGear(character, true);
findDivingGear = new AIObjectiveFindDivingGear(character, true, objectiveManager);
AddSubObjective(findDivingGear);
}
else if (!findDivingGear.CanBeCompleted)
@@ -75,7 +75,7 @@ namespace Barotrauma
if (weldingTool == null)
{
AddSubObjective(new AIObjectiveGetItem(character, "weldingtool", true));
AddSubObjective(new AIObjectiveGetItem(character, "weldingtool", objectiveManager, true));
return;
}
else
@@ -86,7 +86,7 @@ namespace Barotrauma
var fuelTank = containedItems.FirstOrDefault(i => i.HasTag("weldingfueltank") && i.Condition > 0.0f);
if (fuelTank == null)
{
AddSubObjective(new AIObjectiveContainItem(character, "weldingfueltank", weldingTool.GetComponent<ItemContainer>()));
AddSubObjective(new AIObjectiveContainItem(character, "weldingfueltank", weldingTool.GetComponent<ItemContainer>(), objectiveManager));
return;
}
}
@@ -122,7 +122,7 @@ namespace Barotrauma
}
else
{
gotoObjective = new AIObjectiveGoTo(ConvertUnits.ToSimUnits(GetStandPosition()), character)
gotoObjective = new AIObjectiveGoTo(ConvertUnits.ToSimUnits(GetStandPosition()), character, objectiveManager)
{
CloseEnough = reach
};
@@ -137,7 +137,7 @@ namespace Barotrauma
{
if (operateObjective == null)
{
operateObjective = new AIObjectiveOperateItem(repairTool, character, "", true, leak);
operateObjective = new AIObjectiveOperateItem(repairTool, character, objectiveManager, option: "", requireEquip: true, operateTarget: leak);
AddSubObjective(operateObjective);
}
else if (!subObjectives.Contains(operateObjective))

View File

@@ -12,14 +12,12 @@ namespace Barotrauma
public override bool KeepDivingGearOn => true;
public override bool ForceRun => true;
public AIObjectiveFixLeaks(Character character, float priorityModifier = 1) : base(character, "", priorityModifier) { }
public AIObjectiveFixLeaks(Character character, AIObjectiveManager objectiveManager, float priorityModifier = 1) : base(character, objectiveManager, priorityModifier) { }
protected override void FindTargets()
{
base.FindTargets();
// Sorting should be handled by the objective manager, because the targets should be subobjectives.
//targets.Sort((x, y) => GetLeakFixPriority(y).CompareTo(GetLeakFixPriority(x)));
// TODO: Add a dialog when no leaks are found.
// TODO: Add a dialog when no leaks are found and the objective is an order
}
protected override bool Filter(Gap gap)
@@ -46,6 +44,6 @@ namespace Barotrauma
public override bool IsDuplicate(AIObjective otherObjective) => otherObjective is AIObjectiveFixLeaks;
protected override float TargetEvaluation() => targets.Max(t => GetLeakSeverity(t));
protected override IEnumerable<Gap> GetList() => Gap.GapList;
protected override AIObjective ObjectiveConstructor(Gap gap) => new AIObjectiveFixLeak(gap, character, PriorityModifier);
protected override AIObjective ObjectiveConstructor(Gap gap) => new AIObjectiveFixLeak(gap, character, objectiveManager, PriorityModifier);
}
}

View File

@@ -27,7 +27,7 @@ namespace Barotrauma
private bool canBeCompleted = true;
public override bool CanBeCompleted => canBeCompleted;
public override float GetPriority(AIObjectiveManager objectiveManager)
public override float GetPriority()
{
if (objectiveManager.CurrentOrder == this)
{
@@ -36,16 +36,19 @@ namespace Barotrauma
return 1.0f;
}
public AIObjectiveGetItem(Character character, Item targetItem, bool equip = false, float priorityModifier = 1) : base(character, "", priorityModifier)
public AIObjectiveGetItem(Character character, Item targetItem, AIObjectiveManager objectiveManager, bool equip = false, float priorityModifier = 1)
: base(character, objectiveManager, priorityModifier)
{
currSearchIndex = -1;
this.equip = equip;
this.targetItem = targetItem;
}
public AIObjectiveGetItem(Character character, string itemIdentifier, bool equip = false, float priorityModifier = 1) : this(character, new string[] { itemIdentifier }, equip, priorityModifier) { }
public AIObjectiveGetItem(Character character, string itemIdentifier, AIObjectiveManager objectiveManager, bool equip = false, float priorityModifier = 1)
: this(character, new string[] { itemIdentifier }, objectiveManager, equip, priorityModifier) { }
public AIObjectiveGetItem(Character character, string[] itemIdentifiers, bool equip = false, float priorityModifier = 1) : base(character, "", priorityModifier)
public AIObjectiveGetItem(Character character, string[] itemIdentifiers, AIObjectiveManager objectiveManager, bool equip = false, float priorityModifier = 1)
: base(character, objectiveManager, priorityModifier)
{
currSearchIndex = -1;
this.equip = equip;
@@ -99,7 +102,7 @@ namespace Barotrauma
FindTargetItem();
if (targetItem == null || moveToTarget == null)
{
HumanAIController.ObjectiveManager.GetObjective<AIObjectiveIdle>().Wander(deltaTime);
objectiveManager.GetObjective<AIObjectiveIdle>().Wander(deltaTime);
//SteeringManager.SteeringWander();
return;
}
@@ -157,7 +160,7 @@ namespace Barotrauma
(itemIdentifiers != null && (itemIdentifiers.Contains("diving") || itemIdentifiers.Contains("divingsuit")));
//don't attempt to get diving gear to reach the destination if the item we're trying to get is diving gear
goToObjective = new AIObjectiveGoTo(moveToTarget, character, false, !gettingDivingGear);
goToObjective = new AIObjectiveGoTo(moveToTarget, character, objectiveManager, repeat: false, getDivingGearIfNeeded: !gettingDivingGear);
}
goToObjective.TryComplete(deltaTime);

View File

@@ -26,7 +26,7 @@ namespace Barotrauma
public bool AllowGoingOutside = false;
public override float GetPriority(AIObjectiveManager objectiveManager)
public override float GetPriority()
{
if (FollowControlledCharacter && Character.Controlled == null) { return 0.0f; }
if (Target != null && Target.Removed) { return 0.0f; }
@@ -68,7 +68,7 @@ namespace Barotrauma
#if DEBUG
DebugConsole.NewMessage($"{character.Name}: Cannot reach the target: {(Target != null ? Target.ToString() : TargetPos.ToString())}", Color.Yellow);
#endif
if (HumanAIController.ObjectiveManager.CurrentOrder != null)
if (objectiveManager.CurrentOrder != null)
{
character.Speak(TextManager.Get("DialogCannotReach"), identifier: "cannotreach", minDurationBetweenSimilar: 10.0f);
}
@@ -84,7 +84,8 @@ namespace Barotrauma
public bool FollowControlledCharacter;
public AIObjectiveGoTo(Entity target, Character character, bool repeat = false, bool getDivingGearIfNeeded = true, float priorityModifier = 1) : base (character, "", priorityModifier)
public AIObjectiveGoTo(Entity target, Character character, AIObjectiveManager objectiveManager, bool repeat = false, bool getDivingGearIfNeeded = true, float priorityModifier = 1)
: base (character, objectiveManager, priorityModifier)
{
this.Target = target;
this.repeat = repeat;
@@ -95,7 +96,8 @@ namespace Barotrauma
}
public AIObjectiveGoTo(Vector2 simPos, Character character, bool repeat = false, bool getDivingGearIfNeeded = true, float priorityModifier = 1) : base(character, "", priorityModifier)
public AIObjectiveGoTo(Vector2 simPos, Character character, AIObjectiveManager objectiveManager, bool repeat = false, bool getDivingGearIfNeeded = true, float priorityModifier = 1)
: base(character, objectiveManager, priorityModifier)
{
this.targetPos = simPos;
this.repeat = repeat;
@@ -171,7 +173,7 @@ namespace Barotrauma
{
if (findDivingGear == null)
{
findDivingGear = new AIObjectiveFindDivingGear(character, true);
findDivingGear = new AIObjectiveFindDivingGear(character, true, objectiveManager);
AddSubObjective(findDivingGear);
}
else if (!findDivingGear.CanBeCompleted)

View File

@@ -29,7 +29,7 @@ namespace Barotrauma
private readonly List<Hull> targetHulls = new List<Hull>(20);
private readonly List<float> hullWeights = new List<float>(20);
public AIObjectiveIdle(Character character, float priorityModifier = 1) : base(character, "", priorityModifier)
public AIObjectiveIdle(Character character, AIObjectiveManager objectiveManager, float priorityModifier = 1) : base(character, objectiveManager, priorityModifier)
{
standStillTimer = Rand.Range(-10.0f, 10.0f);
walkDuration = Rand.Range(0.0f, 10.0f);
@@ -40,10 +40,8 @@ namespace Barotrauma
public override bool IsLoop { get => true; set => throw new System.Exception("Trying to set the value for IsLoop from: " + System.Environment.StackTrace); }
public override float GetPriority(AIObjectiveManager objectiveManager)
{
return 1.0f;
}
// TODO: take the initiative into account
public override float GetPriority() => 1;
protected override void Act(float deltaTime)
{

View File

@@ -17,7 +17,8 @@ namespace Barotrauma
protected virtual float IgnoreListClearInterval => 0;
protected virtual float TargetUpdateInterval => 2;
public AIObjectiveLoop(Character character, string option, float priorityModifier = 1) : base(character, option, priorityModifier)
public AIObjectiveLoop(Character character, AIObjectiveManager objectiveManager, float priorityModifier, string option = null)
: base(character, objectiveManager, priorityModifier, option)
{
Reset();
}
@@ -28,9 +29,9 @@ namespace Barotrauma
public override bool IsLoop { get => true; set => throw new System.Exception("Trying to set the value for IsLoop from: " + System.Environment.StackTrace); }
public override void Update(AIObjectiveManager objectiveManager, float deltaTime)
public override void Update(float deltaTime)
{
base.Update(objectiveManager, deltaTime);
base.Update(deltaTime);
if (IgnoreListClearInterval > 0)
{
if (ignoreListTimer > IgnoreListClearInterval)
@@ -87,7 +88,7 @@ namespace Barotrauma
}
}
public override float GetPriority(AIObjectiveManager objectiveManager)
public override float GetPriority()
{
if (character.Submarine == null) { return 0; }
if (targets.None()) { return 0; }

View File

@@ -51,8 +51,8 @@ namespace Barotrauma
public void CreateAutomaticObjectives()
{
Objectives.Clear();
AddObjective(new AIObjectiveFindSafety(character));
AddObjective(new AIObjectiveIdle(character));
AddObjective(new AIObjectiveFindSafety(character, this));
AddObjective(new AIObjectiveIdle(character, this));
foreach (var automaticOrder in character.Info.Job.Prefab.AutomaticOrders)
{
var orderPrefab = Order.PrefabList.Find(o => o.AITag == automaticOrder.aiTag);
@@ -96,7 +96,7 @@ namespace Barotrauma
{
var previousObjective = CurrentObjective;
var firstObjective = Objectives.FirstOrDefault();
if (CurrentOrder != null && firstObjective != null && CurrentOrder.GetPriority(this) > firstObjective.GetPriority(this))
if (CurrentOrder != null && firstObjective != null && CurrentOrder.GetPriority() > firstObjective.GetPriority())
{
CurrentObjective = CurrentOrder;
}
@@ -113,12 +113,12 @@ namespace Barotrauma
public float GetCurrentPriority()
{
return CurrentObjective == null ? 0.0f : CurrentObjective.GetPriority(this);
return CurrentObjective == null ? 0.0f : CurrentObjective.GetPriority();
}
public void UpdateObjectives(float deltaTime)
{
CurrentOrder?.Update(this, deltaTime);
CurrentOrder?.Update(deltaTime);
for (int i = 0; i < Objectives.Count; i++)
{
var objective = Objectives[i];
@@ -138,7 +138,7 @@ namespace Barotrauma
}
else
{
objective.Update(this, deltaTime);
objective.Update(deltaTime);
}
}
GetCurrentObjective();
@@ -148,9 +148,9 @@ namespace Barotrauma
{
if (Objectives.Any())
{
Objectives.Sort((x, y) => y.GetPriority(this).CompareTo(x.GetPriority(this)));
Objectives.Sort((x, y) => y.GetPriority().CompareTo(x.GetPriority()));
}
CurrentObjective?.SortSubObjectives(this);
CurrentObjective?.SortSubObjectives();
}
public void DoCurrentObjective(float deltaTime)
@@ -181,7 +181,7 @@ namespace Barotrauma
switch (order.AITag.ToLowerInvariant())
{
case "follow":
newObjective = new AIObjectiveGoTo(orderGiver, character, true, priorityModifier: priorityModifier)
newObjective = new AIObjectiveGoTo(orderGiver, character, this, repeat: true, priorityModifier: priorityModifier)
{
CloseEnough = 1.5f,
AllowGoingOutside = true,
@@ -190,38 +190,38 @@ namespace Barotrauma
};
break;
case "wait":
newObjective = new AIObjectiveGoTo(character, character, true, priorityModifier: priorityModifier)
newObjective = new AIObjectiveGoTo(character, character, this, repeat: true, priorityModifier: priorityModifier)
{
AllowGoingOutside = true
};
break;
case "fixleaks":
newObjective = new AIObjectiveFixLeaks(character, priorityModifier: priorityModifier);
newObjective = new AIObjectiveFixLeaks(character, this, priorityModifier);
break;
case "chargebatteries":
newObjective = new AIObjectiveChargeBatteries(character, option);
newObjective = new AIObjectiveChargeBatteries(character, this, option, priorityModifier);
break;
case "rescue":
newObjective = new AIObjectiveRescueAll(character, priorityModifier: priorityModifier);
newObjective = new AIObjectiveRescueAll(character, this, priorityModifier);
break;
case "repairsystems":
newObjective = new AIObjectiveRepairItems(character, priorityModifier: priorityModifier) { RequireAdequateSkills = option != "all" };
newObjective = new AIObjectiveRepairItems(character, this, priorityModifier) { RequireAdequateSkills = option != "all" };
break;
case "pumpwater":
newObjective = new AIObjectivePumpWater(character, option, priorityModifier: priorityModifier);
newObjective = new AIObjectivePumpWater(character, this, option, priorityModifier: priorityModifier);
break;
case "extinguishfires":
newObjective = new AIObjectiveExtinguishFires(character, priorityModifier: priorityModifier);
newObjective = new AIObjectiveExtinguishFires(character, this, priorityModifier: priorityModifier);
break;
case "steer":
var steering = (order?.TargetEntity as Item)?.GetComponent<Steering>();
if (steering != null) steering.PosToMaintain = steering.Item.Submarine?.WorldPosition;
if (order.TargetItemComponent == null) { return null; }
newObjective = new AIObjectiveOperateItem(order.TargetItemComponent, character, option, false, null, order.UseController, priorityModifier: priorityModifier) { IsLoop = true };
newObjective = new AIObjectiveOperateItem(order.TargetItemComponent, character, this, option, requireEquip: false, useController: order.UseController, priorityModifier: priorityModifier) { IsLoop = true };
break;
default:
if (order.TargetItemComponent == null) { return null; }
newObjective = new AIObjectiveOperateItem(order.TargetItemComponent, character, option, false, null, order.UseController, priorityModifier: priorityModifier) { IsLoop = true };
newObjective = new AIObjectiveOperateItem(order.TargetItemComponent, character, this, option, requireEquip: false, useController: order.UseController, priorityModifier: priorityModifier) { IsLoop = true };
break;
}
return newObjective;

View File

@@ -42,7 +42,7 @@ namespace Barotrauma
public ItemComponent Component => component;
public override float GetPriority(AIObjectiveManager objectiveManager)
public override float GetPriority()
{
if (gotoObjective != null && !gotoObjective.CanBeCompleted) { return 0; }
if (objectiveManager.CurrentOrder == this)
@@ -55,7 +55,8 @@ namespace Barotrauma
return MathHelper.Clamp(value, 0, max);
}
public AIObjectiveOperateItem(ItemComponent item, Character character, string option, bool requireEquip, Entity operateTarget = null, bool useController = false, float priorityModifier = 1) : base (character, option, priorityModifier)
public AIObjectiveOperateItem(ItemComponent item, Character character, AIObjectiveManager objectiveManager, string option, bool requireEquip, Entity operateTarget = null, bool useController = false, float priorityModifier = 1)
: base (character, objectiveManager, priorityModifier, option)
{
this.component = item ?? throw new System.ArgumentNullException("item", "Attempted to create an AIObjectiveOperateItem with a null target.");
this.requireEquip = requireEquip;
@@ -107,7 +108,7 @@ namespace Barotrauma
return;
}
AddSubObjective(gotoObjective = new AIObjectiveGoTo(target.Item, character));
AddSubObjective(gotoObjective = new AIObjectiveGoTo(target.Item, character, objectiveManager));
}
else
{
@@ -119,7 +120,7 @@ namespace Barotrauma
}
else if (!character.Inventory.Items.Contains(component.Item))
{
AddSubObjective(new AIObjectiveGetItem(character, component.Item, true));
AddSubObjective(new AIObjectiveGetItem(character, component.Item, objectiveManager, equip: true));
}
else
{

View File

@@ -11,7 +11,8 @@ namespace Barotrauma
public override bool KeepDivingGearOn => true;
private readonly IEnumerable<Pump> pumpList;
public AIObjectivePumpWater(Character character, string option, float priorityModifier = 1) : base(character, option, priorityModifier)
public AIObjectivePumpWater(Character character, AIObjectiveManager objectiveManager, string option, float priorityModifier = 1)
: base(character, objectiveManager, priorityModifier, option)
{
pumpList = character.Submarine.GetItems(true).Select(i => i.GetComponent<Pump>()).Where(p => p != null);
}
@@ -21,8 +22,9 @@ namespace Barotrauma
//availablePumps = allPumps.Where(p => !p.Item.HasTag("ballast") && p.Item.Connections.None(c => c.IsPower && p.Item.GetConnectedComponentsRecursive<Steering>(c).None())).ToList();
protected override void FindTargets()
{
if (option == null) { return; }
if (Option == null) { return; }
base.FindTargets();
// TODO: add dialog when no targets found and the objective is an order
}
protected override bool Filter(Pump pump)
@@ -31,7 +33,7 @@ namespace Barotrauma
if (pump.Item.Submarine == null) { return false; }
if (pump.Item.Submarine.TeamID != character.TeamID) { return false; }
if (character.Submarine != null && !character.Submarine.IsEntityFoundOnThisSub(pump.Item, true)) { return false; }
if (option == "stoppumping")
if (Option == "stoppumping")
{
if (!pump.IsActive || pump.FlowPercentage == 0.0f) { return false; }
}
@@ -43,7 +45,7 @@ namespace Barotrauma
return true;
}
protected override IEnumerable<Pump> GetList() => pumpList;
protected override AIObjective ObjectiveConstructor(Pump pump) => new AIObjectiveOperateItem(pump, character, Option, false) { IsLoop = true };
protected override AIObjective ObjectiveConstructor(Pump pump) => new AIObjectiveOperateItem(pump, character, objectiveManager, Option, false) { IsLoop = true };
protected override float TargetEvaluation() => targets.Max(t => MathHelper.Lerp(100, 0, t.CurrFlow / t.MaxFlow));
}
}

View File

@@ -19,12 +19,12 @@ namespace Barotrauma
private float previousCondition = -1;
public AIObjectiveRepairItem(Character character, Item item, float priorityModifier = 1) : base(character, "", priorityModifier)
public AIObjectiveRepairItem(Character character, Item item, AIObjectiveManager objectiveManager, float priorityModifier = 1) : base(character, objectiveManager, priorityModifier)
{
Item = item;
}
public override float GetPriority(AIObjectiveManager objectiveManager)
public override float GetPriority()
{
// TODO: priority list?
if (Item.Repairables.None()) { return 0; }
@@ -79,7 +79,7 @@ namespace Barotrauma
{
foreach (RelatedItem requiredItem in kvp.Value)
{
AddSubObjective(new AIObjectiveGetItem(character, requiredItem.Identifiers, true));
AddSubObjective(new AIObjectiveGetItem(character, requiredItem.Identifiers, objectiveManager, true));
}
}
return;
@@ -131,7 +131,7 @@ namespace Barotrauma
{
subObjectives.Remove(goToObjective);
}
goToObjective = new AIObjectiveGoTo(Item, character);
goToObjective = new AIObjectiveGoTo(Item, character, objectiveManager);
if (repairTool != null)
{
//goToObjective.CloseEnough = (HumanAIController.AnimController.ArmLength + ConvertUnits.ToSimUnits(repairTool.Range)) * 0.75f;

View File

@@ -15,10 +15,16 @@ namespace Barotrauma
/// </summary>
public bool RequireAdequateSkills;
public AIObjectiveRepairItems(Character character, float priorityModifier = 1) : base(character, "", priorityModifier) { }
public AIObjectiveRepairItems(Character character, AIObjectiveManager objectiveManager, float priorityModifier = 1) : base(character, objectiveManager, priorityModifier) { }
public override bool IsDuplicate(AIObjective otherObjective) => otherObjective is AIObjectiveRepairItems repairItems && repairItems.RequireAdequateSkills == RequireAdequateSkills;
protected override void FindTargets()
{
base.FindTargets();
// TODO: display a dialog when no targets found and the objective is an order
}
protected override void CreateObjectives()
{
foreach (var item in targets)
@@ -69,6 +75,6 @@ namespace Barotrauma
protected override float TargetEvaluation() => targets.Max(t => 100 - t.ConditionPercentage);
protected override IEnumerable<Item> GetList() => Item.ItemList;
protected override AIObjective ObjectiveConstructor(Item item) => new AIObjectiveRepairItem(character, item, PriorityModifier);
protected override AIObjective ObjectiveConstructor(Item item) => new AIObjectiveRepairItem(character, item, objectiveManager, PriorityModifier);
}
}

View File

@@ -37,7 +37,8 @@ namespace Barotrauma
}
}
public AIObjectiveRescue(Character character, Character targetCharacter, float priorityModifier = 1) : base(character, "", priorityModifier)
public AIObjectiveRescue(Character character, Character targetCharacter, AIObjectiveManager objectiveManager, float priorityModifier = 1)
: base(character, objectiveManager, priorityModifier)
{
Debug.Assert(character != targetCharacter);
this.targetCharacter = targetCharacter;
@@ -58,7 +59,7 @@ namespace Barotrauma
{
if (!character.CanInteractWith(targetCharacter))
{
AddSubObjective(goToObjective = new AIObjectiveGoTo(targetCharacter, character));
AddSubObjective(goToObjective = new AIObjectiveGoTo(targetCharacter, character, objectiveManager));
}
else
{
@@ -67,7 +68,7 @@ namespace Barotrauma
}
else
{
AddSubObjective(new AIObjectiveFindSafety(character));
AddSubObjective(new AIObjectiveFindSafety(character, objectiveManager));
}
return;
}
@@ -75,7 +76,7 @@ namespace Barotrauma
//target not in water -> we can start applying treatment
if (!character.CanInteractWith(targetCharacter))
{
AddSubObjective(goToObjective = new AIObjectiveGoTo(targetCharacter, character));
AddSubObjective(goToObjective = new AIObjectiveGoTo(targetCharacter, character, objectiveManager));
}
else
{
@@ -186,7 +187,7 @@ namespace Barotrauma
}
character.DeselectCharacter();
AddSubObjective(new AIObjectiveGetItem(character, suitableItemIdentifiers.ToArray(), true));
AddSubObjective(new AIObjectiveGetItem(character, suitableItemIdentifiers.ToArray(), objectiveManager, equip: true));
}
character.AnimController.Anim = AnimController.Animation.CPR;
@@ -228,7 +229,7 @@ namespace Barotrauma
return isCompleted || targetCharacter.IsDead;
}
public override float GetPriority(AIObjectiveManager objectiveManager)
public override float GetPriority()
{
// TODO: review
if (targetCharacter.AnimController.CurrentHull == null || targetCharacter.IsDead) { return 0.0f; }

View File

@@ -15,7 +15,7 @@ namespace Barotrauma
private List<Character> rescueTargets;
public AIObjectiveRescueAll(Character character, float priorityModifier = 1) : base (character, "", priorityModifier)
public AIObjectiveRescueAll(Character character, AIObjectiveManager objectiveManager, float priorityModifier = 1) : base(character, objectiveManager, priorityModifier)
{
rescueTargets = new List<Character>();
}
@@ -25,7 +25,7 @@ namespace Barotrauma
return true;
}
public override float GetPriority(AIObjectiveManager objectiveManager)
public override float GetPriority()
{
// TODO: review
if (character.Submarine == null) { return 0; }
@@ -56,7 +56,7 @@ namespace Barotrauma
{
foreach (Character target in rescueTargets)
{
AddSubObjective(new AIObjectiveRescue(character, target));
AddSubObjective(new AIObjectiveRescue(character, target, objectiveManager));
}
}

View File

@@ -2721,6 +2721,10 @@ namespace Barotrauma
GameMain.GameSession?.CrewManager?.RemoveCharacter(this);
#endif
#if CLIENT
GameMain.GameSession?.CrewManager?.RemoveCharacter(this);
#endif
#if CLIENT
GameMain.GameSession?.CrewManager?.RemoveCharacter(this);
#endif

View File

@@ -173,8 +173,8 @@ namespace Barotrauma
var spawnedCharacter = Character.Create(characterInfo, watchmanSpawnpoint.WorldPosition,
Level.Loaded.Seed + (outpost == Level.Loaded.StartOutpost ? "start" : "end"));
InitializeWatchman(spawnedCharacter);
(spawnedCharacter.AIController as HumanAIController)?.ObjectiveManager.SetOrder(
new AIObjectiveGoTo(watchmanSpawnpoint, spawnedCharacter, repeat: true, getDivingGearIfNeeded: false));
var objectiveManager = (spawnedCharacter.AIController as HumanAIController)?.ObjectiveManager;
objectiveManager?.SetOrder(new AIObjectiveGoTo(watchmanSpawnpoint, spawnedCharacter, objectiveManager, repeat: true, getDivingGearIfNeeded: false));
if (watchmanJob != null)
{
spawnedCharacter.GiveJobItems();

View File

@@ -126,6 +126,25 @@ namespace Barotrauma.Items.Components
}
}
if (targetItem.Prefab.DeconstructItems.Any())
{
inputContainer.Inventory.RemoveItem(targetItem);
Entity.Spawner.AddToRemoveQueue(targetItem);
MoveInputQueue();
PutItemsToLinkedContainer();
}
else
{
if (outputContainer.Inventory.Items.All(i => i != null))
{
targetItem.Drop(dropper: null);
}
else
{
outputContainer.Inventory.TryPutItem(targetItem, user: null, createNetworkEvent: true);
}
}
if (targetItem.Prefab.DeconstructItems.Any())
{
inputContainer.Inventory.RemoveItem(targetItem);

View File

@@ -499,7 +499,7 @@ namespace Barotrauma.Items.Components
//load more fuel if the current maximum output is only 50% of the current load
if (NeedMoreFuel(minimumOutputRatio: 0.5f))
{
var containFuelObjective = new AIObjectiveContainItem(character, new string[] { "fuelrod", "reactorfuel" }, item.GetComponent<ItemContainer>())
var containFuelObjective = new AIObjectiveContainItem(character, new string[] { "fuelrod", "reactorfuel" }, item.GetComponent<ItemContainer>(), objective.objectiveManager)
{
MinContainedAmount = item.ContainedItems.Count(i => i != null && i.Prefab.Identifier == "fuelrod" || i.HasTag("reactorfuel")) + 1,
GetItemPriority = (Item fuelItem) =>

View File

@@ -588,6 +588,19 @@ namespace Barotrauma.Items.Components
return true;
}
public override void OnItemLoaded()
{
sonar = item.GetComponent<Sonar>();
}
public override bool Select(Character character)
{
if (!CanBeSelected) return false;
user = character;
return true;
}
public override void Update(float deltaTime, Camera cam)
{
networkUpdateTimer -= deltaTime;

View File

@@ -415,7 +415,7 @@ namespace Barotrauma.Items.Components
if (batteryToLoad.RechargeSpeed < batteryToLoad.MaxRechargeSpeed * 0.4f)
{
objective.AddSubObjective(new AIObjectiveOperateItem(batteryToLoad, character, "", false));
objective.AddSubObjective(new AIObjectiveOperateItem(batteryToLoad, character, objective.objectiveManager, option: "", requireEquip: false));
return false;
}
}
@@ -454,11 +454,11 @@ namespace Barotrauma.Items.Components
if (container.Inventory.Items[0] != null && container.Inventory.Items[0].Condition <= 0.0f)
{
var removeShellObjective = new AIObjectiveDecontainItem(character, container.Inventory.Items[0], container);
var removeShellObjective = new AIObjectiveDecontainItem(character, container.Inventory.Items[0], container, objective.objectiveManager);
objective.AddSubObjective(removeShellObjective);
}
var containShellObjective = new AIObjectiveContainItem(character, container.ContainableItems[0].Identifiers[0], container);
var containShellObjective = new AIObjectiveContainItem(character, container.ContainableItems[0].Identifiers[0], container, objective.objectiveManager);
character?.Speak(TextManager.Get("DialogLoadTurret").Replace("[itemname]", item.Name), null, 0.0f, "loadturret", 30.0f);
containShellObjective.MinContainedAmount = usableProjectileCount + 1;
containShellObjective.ignoredContainerIdentifiers = new string[] { containerItem.prefab.Identifier };

View File

@@ -1204,6 +1204,10 @@ namespace Barotrauma
{
ApplyStatusEffects(!waterProof && inWater ? ActionType.InWater : ActionType.NotInWater, deltaTime);
}
if (!broken)
{
ApplyStatusEffects(!waterProof && inWater ? ActionType.InWater : ActionType.NotInWater, deltaTime);
}
ApplyStatusEffects(!waterProof && inWater ? ActionType.InWater : ActionType.NotInWater, deltaTime);
if (body == null || !body.Enabled || !inWater || ParentInventory != null || Removed) { return; }

View File

@@ -21,7 +21,7 @@ namespace Barotrauma
protected Vector2 position;
protected Vector2 size;
private bool removed;
protected bool removed;
protected bool removed;

View File

@@ -679,6 +679,25 @@ namespace Barotrauma
}
}
public string DisplayName
{
get;
private set;
}
private string roomName;
[Editable, Serialize("", true, translationTextTag: "RoomName.")]
public string RoomName
{
get { return roomName; }
set
{
if (roomName == value) { return; }
roomName = value;
DisplayName = TextManager.Get(roomName, returnNull: true) ?? roomName;
}
}
public override Rectangle Rect
{
get

View File

@@ -162,6 +162,21 @@ namespace Barotrauma
get { return binding; }
}
public void SetState()
{
hit = binding.IsHit();
if (hit) hitQueue = true;
held = binding.IsDown();
if (held) heldQueue = true;
}
#endif
public KeyOrMouse State
{
get { return binding; }
}
public void SetState()
{
hit = binding.IsHit();

View File

@@ -79,40 +79,6 @@ namespace Barotrauma
}
public static string Get(string textTag, bool returnNull = false)
{
if (!textPacks.ContainsKey(Language))
{
DebugConsole.ThrowError("No text packs available for the selected language (" + Language + ")! Switching to English...");
Language = "English";
if (!textPacks.ContainsKey(Language))
{
throw new Exception("No text packs available in English!");
}
}
}
public static string GetFormatted(string textTag, bool returnNull = false, params object[] args)
{
string text = Get(textTag, returnNull);
if (text == null || text.Length == 0)
{
if (returnNull)
{
return null;
}
else
{
DebugConsole.ThrowError("Text \"" + textTag + "\" not found.");
return textTag;
}
}
return string.Format(text, args);
}
// Format: ServerMessage.Identifier1/ServerMessage.Indentifier2~[variable1]=value~[variable2]=value
public static string GetServerMessage(string serverMessage)
{
if (!textPacks.ContainsKey(Language))
{