(81244db07) Implement AIObjectiveFightIntruders.

This commit is contained in:
Joonas Rikkonen
2019-05-16 05:21:03 +03:00
parent 88de435487
commit 1e200722ae
15 changed files with 194 additions and 228 deletions
@@ -189,7 +189,7 @@ namespace Barotrauma
}
}
}
if (!(ObjectiveManager.CurrentOrder is AIObjectiveExtinguishFires) && !(ObjectiveManager.CurrentObjective is AIObjectiveExtinguishFires) && !(ObjectiveManager.CurrentObjective is AIObjectiveExtinguishFire))
if (!ObjectiveManager.IsCurrentObjective<AIObjectiveExtinguishFires>() && !ObjectiveManager.IsCurrentObjective<AIObjectiveExtinguishFire>())
{
var extinguisherItem = Character.Inventory.FindItemByIdentifier("extinguisher") ?? Character.Inventory.FindItemByTag("extinguisher");
if (extinguisherItem != null && Character.HasEquippedItem(extinguisherItem))
@@ -206,7 +206,7 @@ namespace Barotrauma
{
unequip = item.AllowedSlots.Contains(InvSlotType.RightHand | InvSlotType.LeftHand);
}
else if (!(ObjectiveManager.CurrentObjective is AIObjectiveCombat))
else if (!ObjectiveManager.IsCurrentObjective<AIObjectiveCombat>() && !ObjectiveManager.IsCurrentObjective<AIObjectiveFightIntruders>())
{
unequip = item.GetComponent<RangedWeapon>() != null || item.GetComponent<MeleeWeapon>() != null;
}
@@ -315,6 +315,7 @@ namespace Barotrauma
{
float damage = attackResult.Damage;
if (damage <= 0) { return; }
if (ObjectiveManager.CurrentObjective is AIObjectiveFightIntruders) { return; }
if (attacker == null || attacker.IsDead || attacker.Removed)
{
// Ignore damage from falling etc that we shouldn't react to.
@@ -468,10 +469,10 @@ namespace Barotrauma
public float GetHullSafety(Hull hull)
{
if (hull == null) { return 0; }
bool ignoreFire = ObjectiveManager.CurrentObjective is AIObjectiveExtinguishFire || ObjectiveManager.CurrentObjective is AIObjectiveExtinguishFires || ObjectiveManager.CurrentOrder is AIObjectiveExtinguishFires;
bool ignoreFire = ObjectiveManager.IsCurrentObjective<AIObjectiveExtinguishFires>() || ObjectiveManager.IsCurrentObjective<AIObjectiveExtinguishFire>();
bool ignoreWater = HasDivingSuit(Character);
bool ignoreOxygen = ignoreWater || HasDivingGear(Character);
bool ignoreEnemies = ObjectiveManager.CurrentObjective is AIObjectiveCombat || ObjectiveManager.CurrentOrder is AIObjectiveCombat;
bool ignoreEnemies = !ObjectiveManager.IsCurrentObjective<AIObjectiveFightIntruders>();
return GetHullSafety(hull, Character, ignoreWater, ignoreOxygen, ignoreFire, ignoreEnemies);
}
@@ -12,6 +12,7 @@ namespace Barotrauma
{
public override string DebugTag => "combat";
public override bool KeepDivingGearOn => true;
public bool useCoolDown = true;
const float CoolDown = 10.0f;
@@ -77,7 +78,10 @@ namespace Barotrauma
protected override void Act(float deltaTime)
{
coolDownTimer -= deltaTime;
if (useCoolDown)
{
coolDownTimer -= deltaTime;
}
if (abandon) { return; }
Arm(deltaTime);
Move(deltaTime);
@@ -373,7 +377,7 @@ namespace Barotrauma
public override bool IsCompleted()
{
bool completed = (Enemy != null && (Enemy.Removed || Enemy.IsDead)) || coolDownTimer <= 0;
bool completed = (Enemy != null && (Enemy.Removed || Enemy.IsDead)) || (useCoolDown && coolDownTimer <= 0);
if (completed)
{
if (Weapon != null)
@@ -31,7 +31,7 @@ namespace Barotrauma
return true;
}
protected override float TargetEvaluation() => (objectiveManager.CurrentObjective == this || objectiveManager.CurrentOrder == this) ? 100 : targets.Sum(t => GetFireSeverity(t));
protected override float TargetEvaluation() => objectiveManager.CurrentObjective == this ? 100 : targets.Sum(t => GetFireSeverity(t));
public static float GetFireSeverity(Hull hull) => hull.FireSources.Sum(fs => fs.Size.X);
@@ -0,0 +1,43 @@
using Barotrauma.Items.Components;
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
namespace Barotrauma
{
class AIObjectiveFightIntruders : AIObjectiveLoop<Character>
{
public override string DebugTag => "fight intruders";
public override bool KeepDivingGearOn => true;
public AIObjectiveFightIntruders(Character character, AIObjectiveManager objectiveManager, float priorityModifier = 1)
: base(character, objectiveManager, priorityModifier) { }
public override bool IsDuplicate(AIObjective otherObjective) => otherObjective is AIObjectiveFightIntruders && otherObjective.Option == Option;
protected override void FindTargets()
{
if (Option == null) { return; }
base.FindTargets();
// TODO: add dialog when no targets found and the objective is an order
}
protected override bool Filter(Character target)
{
if (target == null || target.IsDead || target.Removed) { return false; }
if (HumanAIController == null || HumanAIController.IsFriendly(target)) { return false; }
if (target.Submarine != character.Submarine) { return false; }
if (target.CurrentHull == null && character.Submarine != null) { return false; }
return true;
}
protected override IEnumerable<Character> GetList() => Character.CharacterList;
protected override AIObjective ObjectiveConstructor(Character target) => new AIObjectiveCombat(character, target, AIObjectiveCombat.CombatMode.Offensive, objectiveManager, PriorityModifier) { useCoolDown = false };
protected override float TargetEvaluation()
{
// TODO: sorting criteria
return 90;
}
}
}
@@ -82,6 +82,7 @@ namespace Barotrauma
public override void OnSelected()
{
base.OnSelected();
if (HumanAIController.ObjectiveManager.CurrentOrder == this)
{
Reset();
@@ -14,7 +14,7 @@ namespace Barotrauma
// Constantly increases the priority of the selected objective, unless overridden
public const float baseDevotion = 2;
public List<AIObjective> Objectives { get; private set; }
public List<AIObjective> Objectives { get; private set; } = new List<AIObjective>();
private Character character;
@@ -26,10 +26,11 @@ namespace Barotrauma
public AIObjective CurrentOrder { get; private set; }
public AIObjective CurrentObjective { get; private set; }
public bool IsCurrentObjective<T>() where T : AIObjective => CurrentObjective is T;
public AIObjectiveManager(Character character)
{
this.character = character;
Objectives = new List<AIObjective>();
CreateAutomaticObjectives();
}
@@ -56,6 +57,7 @@ namespace Barotrauma
foreach (var automaticOrder in character.Info.Job.Prefab.AutomaticOrders)
{
var orderPrefab = Order.PrefabList.Find(o => o.AITag == automaticOrder.aiTag);
if (orderPrefab == null) { throw new Exception("Could not find a matching prefab by ai tag: " + automaticOrder.aiTag); }
// TODO: Similar code is used in CrewManager:815-> DRY
var matchingItems = orderPrefab.ItemIdentifiers.Any() ?
Item.ItemList.FindAll(it => orderPrefab.ItemIdentifiers.Contains(it.Prefab.Identifier) || it.HasTag(orderPrefab.ItemIdentifiers)) :
@@ -174,8 +176,6 @@ namespace Barotrauma
}
}
// TODO: attack enemies : new AIObjectiveCombat(Character, attacker, AIObjectiveCombat.CombatMode.Offensive, objectiveManager);
public AIObjective CreateObjective(Order order, string option, Character orderGiver, float priorityModifier = 1)
{
if (order == null) { return null; }
@@ -213,7 +213,10 @@ namespace Barotrauma
newObjective = new AIObjectivePumpWater(character, this, option, priorityModifier: priorityModifier);
break;
case "extinguishfires":
newObjective = new AIObjectiveExtinguishFires(character, this, priorityModifier: priorityModifier);
newObjective = new AIObjectiveExtinguishFires(character, this, priorityModifier);
break;
case "fightintruders":
newObjective = new AIObjectiveFightIntruders(character, this, priorityModifier);
break;
case "steer":
var steering = (order?.TargetEntity as Item)?.GetComponent<Steering>();
@@ -544,6 +544,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);
@@ -874,6 +874,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;
@@ -1292,6 +1292,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; }
@@ -455,6 +455,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
@@ -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();