(8025561da) Implement offensive combat.

This commit is contained in:
Joonas Rikkonen
2019-05-16 05:19:31 +03:00
parent 363eb0540a
commit bcd18aab4e
9 changed files with 419 additions and 83 deletions
@@ -4,6 +4,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using Barotrauma.Extensions;
using FarseerPhysics;
namespace Barotrauma
{
@@ -46,13 +47,14 @@ namespace Barotrauma
private Hull retreatTarget;
private AIObjectiveGoTo retreatObjective;
private AIObjectiveFindSafety findSafety;
private AIObjectiveGoTo followTargetObjective;
private float coolDownTimer;
public enum CombatMode
{
Defensive,
Offensive, // Not implemented
Offensive,
Retreat
}
@@ -77,10 +79,17 @@ namespace Barotrauma
{
coolDownTimer -= deltaTime;
if (abandon) { return; }
Arm(deltaTime);
Move(deltaTime);
}
private void Arm(float deltaTime)
{
switch (Mode)
{
case CombatMode.Offensive:
case CombatMode.Defensive:
if (Weapon != null && character.Inventory.Items.Contains(_weapon))
if (Weapon != null && !character.Inventory.Items.Contains(_weapon) || _weaponComponent != null && !_weaponComponent.HasRequiredContainedItems(false))
{
Weapon = null;
}
@@ -99,15 +108,31 @@ namespace Barotrauma
Attack(deltaTime);
}
}
// When defensive, try to retreat to safety. TODO: in offsensive mode, engage the target
Retreat(deltaTime);
else
{
Mode = CombatMode.Retreat;
}
break;
case CombatMode.Retreat:
break;
default:
throw new NotImplementedException();
}
}
private void Move(float deltaTime)
{
switch (Mode)
{
case CombatMode.Offensive:
Engage(deltaTime);
break;
case CombatMode.Defensive:
case CombatMode.Retreat:
Retreat(deltaTime);
break;
case CombatMode.Offensive:
default:
throw new System.NotImplementedException();
throw new NotImplementedException();
}
}
@@ -202,8 +227,7 @@ namespace Barotrauma
}
else
{
//couldn't equip the item, escape
//Abandon(deltaTime);
//couldn't equip the item -> escape
return false;
}
}
@@ -212,6 +236,7 @@ namespace Barotrauma
private void Retreat(float deltaTime)
{
followTargetObjective = null;
if (retreatTarget == null || (retreatObjective != null && !retreatObjective.CanBeCompleted))
{
retreatTarget = findSafety.FindBestHull(new List<Hull>() { character.CurrentHull });
@@ -220,12 +245,44 @@ namespace Barotrauma
{
if (retreatObjective == null || retreatObjective.Target != retreatTarget)
{
retreatObjective = new AIObjectiveGoTo(retreatTarget, character, objectiveManager, false, true);
retreatObjective = new AIObjectiveGoTo(retreatTarget, character, objectiveManager, false, true, priorityModifier: PriorityModifier);
}
retreatObjective.TryComplete(deltaTime);
}
}
private void Engage(float deltaTime)
{
retreatTarget = null;
retreatObjective = null;
if (followTargetObjective == null)
{
followTargetObjective = new AIObjectiveGoTo(Enemy, character, objectiveManager, repeat: true, getDivingGearIfNeeded: true, priorityModifier: PriorityModifier)
{
AllowGoingOutside = true,
IgnoreIfTargetDead = true
};
}
if (WeaponComponent is RangedWeapon)
{
followTargetObjective.CloseEnough = 3;
}
else if (WeaponComponent is MeleeWeapon mw)
{
followTargetObjective.CloseEnough = ConvertUnits.ToSimUnits(mw.Range);
}
else if (WeaponComponent is RepairTool rt)
{
followTargetObjective.CloseEnough = ConvertUnits.ToSimUnits(rt.Range);
}
if (retreatTarget != null)
{
SteeringManager.Reset();
Mode = CombatMode.Retreat;
}
followTargetObjective.TryComplete(deltaTime);
}
private bool Reload(float deltaTime)
{
if (WeaponComponent != null && WeaponComponent.requiredItems.ContainsKey(RelatedItem.RelationType.Contained))
@@ -251,6 +308,7 @@ namespace Barotrauma
}
else if (!reloadWeaponObjective.CanBeCompleted)
{
SteeringManager.Reset();
Mode = CombatMode.Retreat;
}
else
@@ -312,12 +370,6 @@ namespace Barotrauma
}
}
private void Abandon(float deltaTime)
{
abandon = true;
SteeringManager.Reset();
}
public override bool IsCompleted()
{
bool completed = (Enemy != null && (Enemy.Removed || Enemy.IsDead)) || coolDownTimer <= 0;
@@ -449,6 +449,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);
@@ -809,6 +809,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;
@@ -1272,6 +1272,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; }
@@ -360,6 +360,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,21 +162,6 @@ 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();