(ce8e185aa) Merge branch 'dev' of https://github.com/Regalis11/Barotrauma-development into dev
This commit is contained in:
@@ -12,6 +12,8 @@ namespace Barotrauma
|
||||
{
|
||||
partial class EnemyAIController : AIController
|
||||
{
|
||||
public static bool DisableEnemyAI;
|
||||
|
||||
class WallTarget
|
||||
{
|
||||
public Vector2 Position;
|
||||
@@ -249,7 +251,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public TargetingPriority GetTargetingPriority(string targetTag)
|
||||
private TargetingPriority GetTargetingPriority(string targetTag)
|
||||
{
|
||||
if (targetingPriorities.TryGetValue(targetTag, out TargetingPriority priority))
|
||||
{
|
||||
@@ -485,7 +487,7 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!IsProperlyLatched)
|
||||
if (!IsProperlyLatchedOnSub)
|
||||
{
|
||||
UpdateWallTarget();
|
||||
}
|
||||
@@ -1001,7 +1003,7 @@ namespace Barotrauma
|
||||
|
||||
private void UpdateEating(float deltaTime)
|
||||
{
|
||||
if (SelectedAiTarget == null)
|
||||
if (SelectedAiTarget == null) //SelectedAiTarget.Entity is Character c && !c.IsDead
|
||||
{
|
||||
State = AIState.Idle;
|
||||
return;
|
||||
@@ -1038,14 +1040,14 @@ namespace Barotrauma
|
||||
|
||||
#region Targeting
|
||||
|
||||
private bool IsProperlyLatched => LatchOntoAI != null && LatchOntoAI.IsAttached && 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
|
||||
public AITarget UpdateTargets(Character character, out TargetingPriority priority)
|
||||
{
|
||||
if (IsProperlyLatched)
|
||||
if (IsProperlyLatchedOnSub)
|
||||
{
|
||||
// If attached to a valid target, just keep the target.
|
||||
// Priority not used in this case.
|
||||
|
||||
@@ -267,7 +267,7 @@ namespace Barotrauma
|
||||
if (GameMain.GameSession?.CrewManager != null && GameMain.GameSession.CrewManager.AddOrder(newOrder, newOrder.FadeOutTime))
|
||||
{
|
||||
Character.Speak(
|
||||
newOrder.GetChatMessage("", Character.CurrentHull?.RoomName, givingOrderToSelf: false), ChatMessageType.Order);
|
||||
newOrder.GetChatMessage("", Character.CurrentHull?.DisplayName, givingOrderToSelf: false), ChatMessageType.Order);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -286,7 +286,7 @@ namespace Barotrauma
|
||||
|
||||
if (Character.PressureTimer > 50.0f && Character.CurrentHull != null)
|
||||
{
|
||||
Character.Speak(TextManager.Get("DialogPressure").Replace("[roomname]", Character.CurrentHull.RoomName), null, 0, "pressure", 30.0f);
|
||||
Character.Speak(TextManager.Get("DialogPressure").Replace("[roomname]", Character.CurrentHull.DisplayName), null, 0, "pressure", 30.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -388,6 +388,18 @@ namespace Barotrauma
|
||||
buttonPressCooldown = ButtonPressInterval;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!door.HasRequiredItems(character, false) && shouldBeOpen)
|
||||
{
|
||||
currentPath.Unreachable = true;
|
||||
return;
|
||||
}
|
||||
|
||||
door.Item.TryInteract(character, false, true, true);
|
||||
buttonPressCooldown = ButtonPressInterval;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -414,20 +426,12 @@ namespace Barotrauma
|
||||
if (!nextNode.Waypoint.ConnectedDoor.HasRequiredItems(character, false)) { return null; }
|
||||
}
|
||||
|
||||
if (!canBreakDoors)
|
||||
{
|
||||
//door closed and the character can't open doors -> node can't be traversed
|
||||
if (!canOpenDoors || character.LockHands) return null;
|
||||
|
||||
var doorButtons = nextNode.Waypoint.ConnectedDoor.Item.GetConnectedComponents<Controller>();
|
||||
if (!doorButtons.Any()) return null;
|
||||
|
||||
foreach (Controller button in doorButtons)
|
||||
{
|
||||
if (Math.Sign(button.Item.Position.X - nextNode.Waypoint.Position.X) !=
|
||||
Math.Sign(node.Position.X - nextNode.Position.X)) continue;
|
||||
Math.Sign(node.Position.X - nextNode.Position.X)) { continue; }
|
||||
|
||||
if (!button.HasRequiredItems(character, false)) return null;
|
||||
if (!button.HasRequiredItems(character, false)) { return null; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,8 @@ namespace Barotrauma
|
||||
get { return attachJoints.Count > 0; }
|
||||
}
|
||||
|
||||
public bool IsAttachedToSub => IsAttached && attachTargetBody?.UserData is Entity entity && (entity is Submarine sub || entity?.Submarine != null);
|
||||
|
||||
public LatchOntoAI(XElement element, EnemyAIController enemyAI)
|
||||
{
|
||||
attachToWalls = element.GetAttributeBool("attachtowalls", false);
|
||||
@@ -207,10 +209,10 @@ namespace Barotrauma
|
||||
break;
|
||||
}
|
||||
|
||||
if (attachTargetBody != null && deattachTimer < 0.0f)
|
||||
if (IsAttached && attachTargetBody != null && deattachTimer < 0.0f)
|
||||
{
|
||||
Entity entity = attachTargetBody.UserData as Entity;
|
||||
Submarine attachedSub = entity is Submarine ? (Submarine)entity : entity?.Submarine;
|
||||
Submarine attachedSub = entity is Submarine sub ? sub : entity?.Submarine;
|
||||
if (attachedSub != null)
|
||||
{
|
||||
float velocity = attachedSub.Velocity == Vector2.Zero ? 0.0f : attachedSub.Velocity.Length();
|
||||
|
||||
@@ -44,6 +44,7 @@ namespace Barotrauma
|
||||
private AIObjectiveContainItem reloadWeaponObjective;
|
||||
private Hull retreatTarget;
|
||||
private AIObjectiveGoTo retreatObjective;
|
||||
private AIObjectiveFindSafety findSafety;
|
||||
|
||||
private float coolDownTimer;
|
||||
|
||||
@@ -60,7 +61,9 @@ namespace Barotrauma
|
||||
{
|
||||
Enemy = enemy;
|
||||
coolDownTimer = CoolDown;
|
||||
HumanAIController.ObjectiveManager.GetObjective<AIObjectiveFindSafety>().Priority = 0;
|
||||
findSafety = HumanAIController.ObjectiveManager.GetObjective<AIObjectiveFindSafety>();
|
||||
findSafety.Priority = 0;
|
||||
findSafety.unreachable.Clear();
|
||||
Mode = mode;
|
||||
if (Enemy == null)
|
||||
{
|
||||
@@ -175,7 +178,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (retreatTarget == null || (retreatObjective != null && !retreatObjective.CanBeCompleted))
|
||||
{
|
||||
retreatTarget = HumanAIController.ObjectiveManager.GetObjective<AIObjectiveFindSafety>().FindBestHull(new List<Hull>() { character.CurrentHull });
|
||||
retreatTarget = findSafety.FindBestHull(new List<Hull>() { character.CurrentHull });
|
||||
}
|
||||
if (retreatTarget != null)
|
||||
{
|
||||
@@ -235,6 +238,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (Vector2.DistanceSquared(character.Position, Enemy.Position) <= meleeWeapon.Range * meleeWeapon.Range)
|
||||
{
|
||||
character.SetInput(InputType.Shoot, false, true);
|
||||
Weapon.Use(deltaTime, character);
|
||||
}
|
||||
}
|
||||
@@ -264,6 +268,7 @@ namespace Barotrauma
|
||||
}
|
||||
if (target != null && target == Enemy)
|
||||
{
|
||||
character.SetInput(InputType.Shoot, false, true);
|
||||
Weapon.Use(deltaTime, character);
|
||||
}
|
||||
}
|
||||
@@ -275,7 +280,6 @@ namespace Barotrauma
|
||||
{
|
||||
abandon = true;
|
||||
SteeringManager.Reset();
|
||||
//HumanAIController.ObjectiveManager.GetObjective<AIObjectiveFindSafety>().Priority = 100;
|
||||
}
|
||||
|
||||
public override bool IsCompleted()
|
||||
|
||||
+16
-5
@@ -18,7 +18,7 @@ namespace Barotrauma
|
||||
const float SearchHullInterval = 3.0f;
|
||||
const float clearUnreachableInterval = 30;
|
||||
|
||||
private List<Hull> unreachable = new List<Hull>();
|
||||
public readonly List<Hull> unreachable = new List<Hull>();
|
||||
|
||||
private float currenthullSafety;
|
||||
private float unreachableClearTimer;
|
||||
@@ -60,11 +60,16 @@ namespace Barotrauma
|
||||
else
|
||||
{
|
||||
divingGearObjective = null;
|
||||
// Reset the timer so that we get a safe hull target.
|
||||
searchHullTimer = 0;
|
||||
// Reduce the timer so that we get a safe hull target faster.
|
||||
searchHullTimer = Math.Min(1, searchHullTimer);
|
||||
}
|
||||
}
|
||||
|
||||
if (currenthullSafety < HumanAIController.HULL_SAFETY_THRESHOLD)
|
||||
{
|
||||
searchHullTimer = Math.Min(1, searchHullTimer);
|
||||
}
|
||||
|
||||
if (unreachableClearTimer > 0)
|
||||
{
|
||||
unreachableClearTimer -= deltaTime;
|
||||
@@ -188,10 +193,17 @@ namespace Barotrauma
|
||||
float dist = Math.Abs(character.WorldPosition.X - hull.WorldPosition.X) + Math.Abs(character.WorldPosition.Y - hull.WorldPosition.Y) * 2.0f;
|
||||
float distanceFactor = MathHelper.Lerp(1, 0.9f, MathUtils.InverseLerp(0, 10000, dist));
|
||||
hullSafety *= distanceFactor;
|
||||
//skip the hull if the safety is already less than the best hull
|
||||
//(no need to do the expensive pathfinding if we already know we're not going to choose this hull)
|
||||
if (hullSafety < bestValue) { continue; }
|
||||
// Each unsafe node reduces the hull safety value.
|
||||
// Ignore current hull, because otherwise the would block all paths from the current hull to the target hull.
|
||||
var path = PathSteering.PathFinder.FindPath(character.SimPosition, hull.SimPosition);
|
||||
if (path.Unreachable) { continue; }
|
||||
if (path.Unreachable)
|
||||
{
|
||||
unreachable.Add(hull);
|
||||
continue;
|
||||
}
|
||||
int unsafeNodes = path.Nodes.Count(n => n.CurrentHull != character.CurrentHull && HumanAIController.UnsafeHulls.Contains(n.CurrentHull));
|
||||
hullSafety /= 1 + unsafeNodes;
|
||||
// If the target is not inside a friendly submarine, considerably reduce the hull safety.
|
||||
@@ -219,7 +231,6 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Huge preference for closer targets
|
||||
float distance = Vector2.DistanceSquared(character.WorldPosition, hull.WorldPosition);
|
||||
float distanceFactor = MathHelper.Lerp(1, 0.2f, MathUtils.InverseLerp(0, MathUtils.Pow(100000, 2), distance));
|
||||
|
||||
@@ -26,6 +26,9 @@ namespace Barotrauma
|
||||
private float standStillTimer;
|
||||
private float walkDuration;
|
||||
|
||||
private readonly List<Hull> targetHulls = new List<Hull>(20);
|
||||
private readonly List<float> hullWeights = new List<float>(20);
|
||||
|
||||
public AIObjectiveIdle(Character character) : base(character, "")
|
||||
{
|
||||
standStillTimer = Rand.Range(-10.0f, 10.0f);
|
||||
@@ -106,7 +109,7 @@ namespace Barotrauma
|
||||
if (isCurrentHullOK)
|
||||
{
|
||||
// Check that there is no unsafe or forbidden hulls on the way to the target
|
||||
// Only do this when the current hull is ok, because otherwise the would block all paths from the current hull to the target hull.
|
||||
// Only do this when the current hull is ok, because otherwise would block all paths from the current hull to the target hull.
|
||||
var path = PathSteering.PathFinder.FindPath(character.SimPosition, randomHull.SimPosition);
|
||||
if (path.Unreachable ||
|
||||
path.Nodes.Any(n => HumanAIController.UnsafeHulls.Contains(n.CurrentHull) || IsForbidden(n.CurrentHull)))
|
||||
@@ -128,8 +131,8 @@ namespace Barotrauma
|
||||
character.AIController.SelectTarget(currentTarget.AiTarget);
|
||||
string errorMsg = null;
|
||||
#if DEBUG
|
||||
bool isRoomNameFound = currentTarget.RoomName != null;
|
||||
errorMsg = "(Character " + character.Name + " idling, target " + (isRoomNameFound ? currentTarget.RoomName : currentTarget.ToString()) + ")";
|
||||
bool isRoomNameFound = currentTarget.DisplayName != null;
|
||||
errorMsg = "(Character " + character.Name + " idling, target " + (isRoomNameFound ? currentTarget.DisplayName : currentTarget.ToString()) + ")";
|
||||
#endif
|
||||
var path = PathSteering.PathFinder.FindPath(character.SimPosition, currentTarget.SimPosition, errorMsg);
|
||||
PathSteering.SetPath(path);
|
||||
@@ -230,13 +233,9 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private readonly List<Hull> targetHulls = new List<Hull>(20);
|
||||
private readonly List<float> hullWeights = new List<float>(20);
|
||||
|
||||
private void FindTargetHulls()
|
||||
{
|
||||
bool isCurrentHullOK = !HumanAIController.UnsafeHulls.Contains(character.CurrentHull) && !IsForbidden(character.CurrentHull);
|
||||
|
||||
targetHulls.Clear();
|
||||
hullWeights.Clear();
|
||||
foreach (var hull in Hull.hullList)
|
||||
@@ -266,7 +265,6 @@ namespace Barotrauma
|
||||
hullWeights.Add(weight);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private bool IsForbidden(Hull hull)
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace Barotrauma
|
||||
if (character.SelectedCharacter == null)
|
||||
{
|
||||
character?.Speak(TextManager.Get("DialogFoundUnconsciousTarget")
|
||||
.Replace("[targetname]", targetCharacter.Name).Replace("[roomname]", character.CurrentHull.RoomName),
|
||||
.Replace("[targetname]", targetCharacter.Name).Replace("[roomname]", character.CurrentHull.DisplayName),
|
||||
null, 1.0f,
|
||||
"foundunconscioustarget" + targetCharacter.Name, 60.0f);
|
||||
}
|
||||
|
||||
@@ -527,7 +527,12 @@ namespace Barotrauma
|
||||
|
||||
Limb leftLeg = GetLimb(LimbType.LeftLeg);
|
||||
Limb rightLeg = GetLimb(LimbType.RightLeg);
|
||||
|
||||
|
||||
float limpAmount =
|
||||
character.CharacterHealth.GetAfflictionStrength("damage", leftFoot, true) +
|
||||
character.CharacterHealth.GetAfflictionStrength("damage", rightFoot, true);
|
||||
limpAmount = MathHelper.Clamp(limpAmount / 100.0f, 0.0f, 1.0f);
|
||||
|
||||
float walkCycleMultiplier = 1.0f;
|
||||
if (Stairs != null)
|
||||
{
|
||||
@@ -556,13 +561,17 @@ namespace Barotrauma
|
||||
|
||||
float walkPosX = (float)Math.Cos(WalkPos);
|
||||
float walkPosY = (float)Math.Sin(WalkPos);
|
||||
|
||||
|
||||
|
||||
Vector2 stepSize = StepSize.Value;
|
||||
stepSize.X *= walkPosX;
|
||||
stepSize.Y *= walkPosY;
|
||||
stepSize.Y *= walkPosY;
|
||||
|
||||
float footMid = colliderPos.X;// (leftFoot.SimPosition.X + rightFoot.SimPosition.X) / 2.0f;
|
||||
float footMid = colliderPos.X;
|
||||
if (limpAmount > 0.0f)
|
||||
{
|
||||
//make the footpos oscillate when limping
|
||||
footMid += ((float)Math.Max(Math.Abs(walkPosX) * limpAmount, 0.0f) * 0.3f);
|
||||
}
|
||||
|
||||
movement = overrideTargetMovement == Vector2.Zero ?
|
||||
MathUtils.SmoothStep(movement, TargetMovement, movementLerp) :
|
||||
@@ -576,7 +585,7 @@ namespace Barotrauma
|
||||
movement.Y = 0.0f;
|
||||
|
||||
if (torso == null) { return; }
|
||||
|
||||
|
||||
bool isNotRemote = true;
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) isNotRemote = !character.IsRemotePlayer;
|
||||
|
||||
@@ -680,7 +689,7 @@ namespace Barotrauma
|
||||
|
||||
//make the character limp if the feet are damaged
|
||||
float footAfflictionStrength = character.CharacterHealth.GetAfflictionStrength("damage", foot, true);
|
||||
footPos *= MathHelper.Lerp(1.0f, 0.5f, MathHelper.Clamp(footAfflictionStrength / 100.0f, 0.0f, 1.0f));
|
||||
footPos.X *= MathHelper.Lerp(1.0f, 0.75f, MathHelper.Clamp(footAfflictionStrength / 50.0f, 0.0f, 1.0f));
|
||||
|
||||
if (onSlope && Stairs == null)
|
||||
{
|
||||
|
||||
+1
@@ -84,6 +84,7 @@ namespace Barotrauma
|
||||
var folder = XMLExtensions.TryLoadXml(Character.GetConfigFile(speciesName))?.Root?.Element("ragdolls")?.GetAttributeString("folder", string.Empty);
|
||||
if (string.IsNullOrEmpty(folder) || folder.ToLowerInvariant() == "default")
|
||||
{
|
||||
//DebugConsole.NewMessage("[RagollParams] Using the default folder.");
|
||||
folder = GetDefaultFolder(speciesName);
|
||||
}
|
||||
return folder;
|
||||
|
||||
@@ -692,7 +692,7 @@ namespace Barotrauma
|
||||
ImpactProjSpecific(impact, f1.Body);
|
||||
}
|
||||
|
||||
public void SeverLimbJoint(LimbJoint limbJoint)
|
||||
public void SeverLimbJoint(LimbJoint limbJoint, bool playSound = true)
|
||||
{
|
||||
if (!limbJoint.CanBeSevered || limbJoint.IsSevered)
|
||||
{
|
||||
@@ -721,7 +721,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
partial void SeverLimbJointProjSpecific(LimbJoint limbJoint);
|
||||
partial void SeverLimbJointProjSpecific(LimbJoint limbJoint, bool playSound = true);
|
||||
|
||||
private void GetConnectedLimbs(List<Limb> connectedLimbs, List<LimbJoint> checkedJoints, Limb limb)
|
||||
{
|
||||
|
||||
@@ -1103,14 +1103,14 @@ namespace Barotrauma
|
||||
if (leftFoot != null)
|
||||
{
|
||||
float footAfflictionStrength = CharacterHealth.GetAfflictionStrength("damage", leftFoot, true);
|
||||
speed *= MathHelper.Lerp(1.0f, 0.25f, MathHelper.Clamp(footAfflictionStrength / 100.0f, 0.0f, 1.0f));
|
||||
speed *= MathHelper.Lerp(1.0f, 0.4f, MathHelper.Clamp(footAfflictionStrength / 80.0f, 0.0f, 1.0f));
|
||||
}
|
||||
|
||||
var rightFoot = AnimController.GetLimb(LimbType.RightFoot);
|
||||
if (rightFoot != null)
|
||||
{
|
||||
float footAfflictionStrength = CharacterHealth.GetAfflictionStrength("damage", rightFoot, true);
|
||||
speed *= MathHelper.Lerp(1.0f, 0.25f, MathHelper.Clamp(footAfflictionStrength / 100.0f, 0.0f, 1.0f));
|
||||
speed *= MathHelper.Lerp(1.0f, 0.4f, MathHelper.Clamp(footAfflictionStrength / 80.0f, 0.0f, 1.0f));
|
||||
}
|
||||
|
||||
return speed;
|
||||
|
||||
@@ -231,7 +231,8 @@ namespace Barotrauma
|
||||
: afflictions.Concat(limbHealths.SelectMany(lh => lh.Afflictions.Where(limbHealthFilter)));
|
||||
}
|
||||
|
||||
private LimbHealth GetMathingLimbHealth(Affliction affliction) => limbHealths[Character.AnimController.GetLimb(affliction.Prefab.IndicatorLimb).HealthIndex];
|
||||
private LimbHealth GetMatchingLimbHealth(Limb limb) => limbHealths[limb.HealthIndex];
|
||||
private LimbHealth GetMathingLimbHealth(Affliction affliction) => GetMatchingLimbHealth(Character.AnimController.GetLimb(affliction.Prefab.IndicatorLimb));
|
||||
|
||||
/// <summary>
|
||||
/// Returns the limb afflictions and non-limbspecific afflictions that are set to be displayed on this limb.
|
||||
|
||||
Reference in New Issue
Block a user