v0.19.8.0

This commit is contained in:
Juan Pablo Arce
2022-09-28 21:30:52 -03:00
parent fec8131243
commit 3ca584f2fc
152 changed files with 1931 additions and 1071 deletions
@@ -466,7 +466,12 @@ namespace Barotrauma
}
}
}
steeringManager.Update(Character.AnimController.GetCurrentSpeed(run && Character.CanRun));
//if someone is grabbing the bot and the bot isn't trying to run anywhere, let them keep dragging and "control" the bot
if (Character.SelectedBy == null || run)
{
steeringManager.Update(Character.AnimController.GetCurrentSpeed(run && Character.CanRun));
}
bool ignorePlatforms = Character.AnimController.TargetMovement.Y < -0.5f && (-Character.AnimController.TargetMovement.Y > Math.Abs(Character.AnimController.TargetMovement.X));
if (steeringManager == insideSteering)
@@ -913,11 +913,14 @@ namespace Barotrauma
private void RemoveFollowTarget()
{
if (arrestingRegistered)
if (followTargetObjective != null)
{
followTargetObjective.Completed -= OnArrestTargetReached;
if (arrestingRegistered)
{
followTargetObjective.Completed -= OnArrestTargetReached;
}
RemoveSubObjective(ref followTargetObjective);
}
RemoveSubObjective(ref followTargetObjective);
arrestingRegistered = false;
}
@@ -595,6 +595,10 @@ namespace Barotrauma
{
return c.CurrentHull;
}
else if (target is Structure structure)
{
return Hull.FindHull(structure.Position, useWorldCoordinates: false);
}
else if (target is Gap g)
{
return g.FlowTargetHull;
@@ -54,7 +54,7 @@ namespace Barotrauma
if (ValidContainableItemIdentifiers.None())
{
#if DEBUG
DebugConsole.ShowError($"No valid containable item identifiers found for the Load Item objective targeting {Container}");
DebugConsole.LogError($"No valid containable item identifiers found for the Load Item objective targeting {Container}");
#endif
Abandon = true;
return;
@@ -250,7 +250,7 @@ namespace Barotrauma
catch (NotImplementedException)
{
#if DEBUG
DebugConsole.ShowError($"Unexpected target condition \"{TargetItemCondition}\" in local function GetConditionBasedProperty");
DebugConsole.LogError($"Unexpected target condition \"{TargetItemCondition}\" in local function GetConditionBasedProperty");
#endif
return 0.0f;
}
@@ -90,7 +90,7 @@ namespace Barotrauma
catch (NotImplementedException)
{
#if DEBUG
DebugConsole.ShowError($"Unexpected target condition \"{targetCondition}\" in AIObjectiveLoadItems.ItemMatchesTargetCondition");
DebugConsole.LogError($"Unexpected target condition \"{targetCondition}\" in AIObjectiveLoadItems.ItemMatchesTargetCondition");
#endif
return false;
}
@@ -37,6 +37,8 @@ namespace Barotrauma
public Func<bool> completionCondition;
private bool isDoneOperating;
public float? OverridePriority = null;
protected override float GetPriority()
{
bool isOrder = objectiveManager.IsOrder(this);
@@ -52,7 +54,11 @@ namespace Barotrauma
}
else
{
if (isOrder)
if (OverridePriority.HasValue)
{
Priority = OverridePriority.Value;
}
else if (isOrder)
{
Priority = objectiveManager.GetOrderPriority(this);
}
@@ -135,7 +141,7 @@ namespace Barotrauma
float value = CumulatedDevotion + (max * PriorityModifier);
Priority = MathHelper.Clamp(value, 0, max);
}
else
else if (!OverridePriority.HasValue)
{
float value = CumulatedDevotion + (AIObjectiveManager.LowestOrderPriority * PriorityModifier);
float max = AIObjectiveManager.LowestOrderPriority - 1;
@@ -204,8 +210,15 @@ namespace Barotrauma
{
if (!character.IsClimbing && character.CanInteractWith(target.Item, out _, checkLinked: false))
{
HumanAIController.FaceTarget(target.Item);
if (character.SelectedItem != target.Item)
if (target.Item.GetComponent<Controller>() is not Controller { ControlCharacterPose: true })
{
HumanAIController.FaceTarget(target.Item);
}
else
{
HumanAIController.SteeringManager.Reset();
}
if (character.SelectedItem != target.Item && character.SelectedSecondaryItem != target.Item)
{
target.Item.TryInteract(character, forceSelectKey: true);
}
@@ -278,7 +278,7 @@ namespace Barotrauma
float cprSuitability = targetCharacter.Oxygen < 0.0f ? -targetCharacter.Oxygen * 100.0f : 0.0f;
//find which treatments are the most suitable to treat the character's current condition
targetCharacter.CharacterHealth.GetSuitableTreatments(currentTreatmentSuitabilities, normalize: false, predictFutureDuration: 10.0f);
targetCharacter.CharacterHealth.GetSuitableTreatments(currentTreatmentSuitabilities, user: character, normalize: false, predictFutureDuration: 10.0f);
//check if we already have a suitable treatment for any of the afflictions
foreach (Affliction affliction in GetSortedAfflictions(targetCharacter))
@@ -3,9 +3,8 @@ using Barotrauma.Items.Components;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Xml.Linq;
using System.Linq;
using System.Collections.Immutable;
using System.Linq;
namespace Barotrauma
{
@@ -151,7 +150,7 @@ namespace Barotrauma
public OrderPrefab(ContentXElement orderElement, OrdersFile file) : base(file, orderElement.GetAttributeIdentifier("identifier", ""))
{
Name = TextManager.Get($"OrderName.{Identifier}");
ContextualName = TextManager.Get($"OrderNameContextual.{Identifier}");
ContextualName = TextManager.Get($"OrderNameContextual.{Identifier}").Fallback(Name);
string targetItemType = orderElement.GetAttributeString("targetitemtype", "");
if (!string.IsNullOrWhiteSpace(targetItemType))
@@ -435,7 +434,7 @@ namespace Barotrauma
}
catch (NotImplementedException e)
{
DebugConsole.ShowError($"Error creating a new Order instance: unexpected target type \"{targetType}\".\n{e.StackTrace.CleanupStackTrace()}");
DebugConsole.LogError($"Error creating a new Order instance: unexpected target type \"{targetType}\".\n{e.StackTrace.CleanupStackTrace()}");
return null;
}
}
@@ -336,7 +336,7 @@ namespace Barotrauma
{
ApplyTestPose();
}
else
else if (character.SelectedBy == null)
{
if (character.LockHands)
{
@@ -356,7 +356,7 @@ namespace Barotrauma
HandIK(rightHand, midPos, CurrentAnimationParams.ArmIKStrength, CurrentAnimationParams.HandIKStrength);
HandIK(leftHand, midPos, CurrentAnimationParams.ArmIKStrength, CurrentAnimationParams.HandIKStrength);
}
if (Anim != Animation.UsingItem && character.SelectedBy == null)
if (Anim != Animation.UsingItem)
{
if (Anim != Animation.UsingItemWhileClimbing)
{
@@ -1716,9 +1716,17 @@ namespace Barotrauma
}
else if (target is AICharacter && target != Character.Controlled)
{
target.AnimController.TargetDir = WorldPosition.X > target.WorldPosition.X ? Direction.Right : Direction.Left;
Vector2 movement = (character.SimPosition + Vector2.UnitX * 0.5f * Dir) - target.SimPosition;
target.AnimController.TargetMovement = movement.LengthSquared() > 0.01f ? movement : Vector2.Zero;
if (target.AnimController.Dir > 0 == WorldPosition.X > target.WorldPosition.X)
{
target.AnimController.LockFlippingUntil = (float)Timing.TotalTime + 0.5f;
}
else
{
target.AnimController.TargetDir = WorldPosition.X > target.WorldPosition.X ? Direction.Right : Direction.Left;
}
//make the target stand 0.5 meters away from this character, on the side they're currently at
Vector2 movement = (character.SimPosition + Vector2.UnitX * 0.5f * Math.Sign(target.SimPosition.X - character.SimPosition.X)) - target.SimPosition;
target.AnimController.TargetMovement = movement.LengthSquared() > 0.01f ? movement : Vector2.Zero;
}
}
}
@@ -402,9 +402,8 @@ namespace Barotrauma
}
else
{
string afflictionIdentifier = subElement.GetAttributeString("identifier", "").ToLowerInvariant();
afflictionPrefab = AfflictionPrefab.Prefabs[afflictionIdentifier];
if (afflictionPrefab == null)
Identifier afflictionIdentifier = subElement.GetAttributeIdentifier("identifier", "");
if (!AfflictionPrefab.Prefabs.TryGet(afflictionIdentifier, out afflictionPrefab))
{
DebugConsole.ThrowError("Error in Attack (" + parentDebugName + ") - Affliction prefab \"" + afflictionIdentifier + "\" not found.");
continue;
@@ -430,15 +429,13 @@ namespace Barotrauma
Afflictions.Clear();
foreach (var subElement in element.GetChildElements("affliction"))
{
AfflictionPrefab afflictionPrefab;
Affliction affliction;
Identifier afflictionIdentifier = subElement.GetAttributeIdentifier("identifier", "");
if (!AfflictionPrefab.Prefabs.ContainsKey(afflictionIdentifier))
if (!AfflictionPrefab.Prefabs.TryGet(afflictionIdentifier, out AfflictionPrefab afflictionPrefab))
{
DebugConsole.ThrowError($"Error in an Attack defined in \"{parentDebugName}\" - could not find an affliction with the identifier \"{afflictionIdentifier}\".");
continue;
}
afflictionPrefab = AfflictionPrefab.Prefabs[afflictionIdentifier];
affliction = afflictionPrefab.Instantiate(0.0f);
affliction.Deserialize(subElement);
//backwards compatibility
@@ -549,6 +549,10 @@ namespace Barotrauma
set
{
lockHandsTimer = MathHelper.Clamp(lockHandsTimer + (value ? 1.0f : -0.5f), 0.0f, 10.0f);
if (value)
{
SelectedCharacter = null;
}
#if CLIENT
HintManager.OnHandcuffed(this);
#endif
@@ -599,13 +603,10 @@ namespace Barotrauma
get { return selectedCharacter; }
set
{
if (value == selectedCharacter) return;
if (selectedCharacter != null)
selectedCharacter.selectedBy = null;
if (value == selectedCharacter) { return; }
if (selectedCharacter != null) { selectedCharacter.selectedBy = null; }
selectedCharacter = value;
if (selectedCharacter != null)
selectedCharacter.selectedBy = this;
if (selectedCharacter != null) {selectedCharacter.selectedBy = this; }
#if CLIENT
CharacterHealth.SetHealthBarVisibility(value == null);
#endif
@@ -707,6 +708,14 @@ namespace Barotrauma
get { return CurrentHull == null || CurrentHull.LethalPressure > 5.0f; }
}
/// <summary>
/// Can be used by status effects
/// </summary>
public AnimController.Animation Anim
{
get { return AnimController?.Anim ?? AnimController.Animation.None; }
}
public const float KnockbackCooldown = 5.0f;
public float KnockbackCooldownTimer;
@@ -2620,7 +2629,7 @@ namespace Barotrauma
if (!AllowInput)
{
FocusedCharacter = null;
if (SelectedCharacter != null) DeselectCharacter();
if (SelectedCharacter != null) { DeselectCharacter(); }
return;
}
}
@@ -3636,7 +3645,7 @@ namespace Barotrauma
string modifiedMessage = ChatMessage.ApplyDistanceEffect(message.Message, message.MessageType.Value, this, Controlled);
if (!string.IsNullOrEmpty(modifiedMessage))
{
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(info.Name, modifiedMessage, message.MessageType.Value, this);
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(Name, modifiedMessage, message.MessageType.Value, this);
}
}
#endif
@@ -4020,6 +4029,7 @@ namespace Barotrauma
if (newStun > 0.0f)
{
SelectedItem = SelectedSecondaryItem = null;
if (SelectedCharacter != null) { DeselectCharacter(); }
}
HealthUpdateInterval = 0.0f;
}
@@ -1,8 +1,9 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using Barotrauma.Items.Components;
using Barotrauma.Networking;
using Barotrauma.Networking;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
namespace Barotrauma
{
@@ -25,9 +26,10 @@ namespace Barotrauma
UpdateSkills = 12,
UpdateMoney = 13,
UpdatePermanentStats = 14,
RemoveFromCrew = 15,
MinValue = 0,
MaxValue = 14
MaxValue = 15
}
private interface IEventData : NetEntityEvent.IData
@@ -133,18 +135,30 @@ namespace Barotrauma
public EventType EventType => EventType.TeamChange;
}
[NetworkSerialize]
public readonly record struct ItemTeamChange(CharacterTeamType TeamId, ImmutableArray<UInt16> ItemIds) : INetSerializableStruct;
public struct AddToCrewEventData : IEventData
{
public EventType EventType => EventType.AddToCrew;
public readonly CharacterTeamType TeamType;
public readonly ImmutableArray<Item> InventoryItems;
public readonly ItemTeamChange ItemTeamChange;
public AddToCrewEventData(CharacterTeamType teamType, IEnumerable<Item> inventoryItems)
{
TeamType = teamType;
InventoryItems = inventoryItems.ToImmutableArray();
ItemTeamChange = new ItemTeamChange(teamType, inventoryItems.Select(it => it.ID).ToImmutableArray());
}
}
public struct RemoveFromCrewEventData : IEventData
{
public EventType EventType => EventType.RemoveFromCrew;
public readonly ItemTeamChange ItemTeamChange;
public RemoveFromCrewEventData(CharacterTeamType teamType, IEnumerable<Item> inventoryItems)
{
ItemTeamChange = new ItemTeamChange(teamType, inventoryItems.Select(it => it.ID).ToImmutableArray());
}
}
public struct UpdateExperienceEventData : IEventData
@@ -82,10 +82,10 @@ namespace Barotrauma
public UInt16 networkUpdateID;
}
private List<NetInputMem> memInput = new List<NetInputMem>();
private readonly List<NetInputMem> memInput = new List<NetInputMem>();
private List<CharacterStateInfo> memState = new List<CharacterStateInfo>();
private List<CharacterStateInfo> memLocalState = new List<CharacterStateInfo>();
private readonly List<CharacterStateInfo> memState = new List<CharacterStateInfo>();
private readonly List<CharacterStateInfo> memLocalState = new List<CharacterStateInfo>();
public float healthUpdateTimer;
@@ -1038,7 +1038,7 @@ namespace Barotrauma
/// <param name="treatmentSuitability">A dictionary where the key is the identifier of the item and the value the suitability</param>
/// <param name="normalize">If true, the suitability values are normalized between 0 and 1. If not, they're arbitrary values defined in the medical item XML, where negative values are unsuitable, and positive ones suitable.</param>
/// <param name="predictFutureDuration">If above 0, the method will take into account how much currently active status effects while affect the afflictions in the next x seconds.</param>
public void GetSuitableTreatments(Dictionary<Identifier, float> treatmentSuitability, bool normalize, Limb limb = null, bool ignoreHiddenAfflictions = false, float predictFutureDuration = 0.0f)
public void GetSuitableTreatments(Dictionary<Identifier, float> treatmentSuitability, bool normalize, Character user, Limb limb = null, bool ignoreHiddenAfflictions = false, float predictFutureDuration = 0.0f)
{
//key = item identifier
//float = suitability
@@ -1062,7 +1062,18 @@ namespace Barotrauma
}
if (strength <= affliction.Prefab.TreatmentThreshold) { continue; }
if (ignoreHiddenAfflictions && strength < affliction.Prefab.ShowIconThreshold) { continue; }
if (ignoreHiddenAfflictions)
{
if (user == Character)
{
if (strength < affliction.Prefab.ShowIconThreshold) { continue; }
}
else
{
if (strength < affliction.Prefab.ShowIconToOthersThreshold) { continue; }
}
}
foreach (KeyValuePair<Identifier, float> treatment in affliction.Prefab.TreatmentSuitability)
{
@@ -1153,10 +1164,10 @@ namespace Barotrauma
msg.WriteRangedSingle(
MathHelper.Clamp(affliction.Strength, 0.0f, affliction.Prefab.MaxStrength),
0.0f, affliction.Prefab.MaxStrength, 8);
msg.WriteByte((byte)affliction.Prefab.PeriodicEffects.Count());
msg.WriteByte((byte)affliction.Prefab.PeriodicEffects.Count);
foreach (AfflictionPrefab.PeriodicEffect periodicEffect in affliction.Prefab.PeriodicEffects)
{
msg.WriteRangedSingle(affliction.PeriodicEffectTimers[periodicEffect], periodicEffect.MinInterval, periodicEffect.MaxInterval, 8);
msg.WriteRangedSingle(affliction.PeriodicEffectTimers[periodicEffect], 0, periodicEffect.MaxInterval, 8);
}
}
@@ -1178,7 +1189,7 @@ namespace Barotrauma
msg.WriteRangedSingle(
MathHelper.Clamp(affliction.Strength, 0.0f, affliction.Prefab.MaxStrength),
0.0f, affliction.Prefab.MaxStrength, 8);
msg.WriteByte((byte)affliction.Prefab.PeriodicEffects.Count());
msg.WriteByte((byte)affliction.Prefab.PeriodicEffects.Count);
foreach (AfflictionPrefab.PeriodicEffect periodicEffect in affliction.Prefab.PeriodicEffects)
{
msg.WriteRangedSingle(affliction.PeriodicEffectTimers[periodicEffect], periodicEffect.MinInterval, periodicEffect.MaxInterval, 8);
@@ -86,6 +86,28 @@ namespace Barotrauma
{
DebugConsole.ThrowError("Error in DamageModifier config (" + parentDebugName + ") - define afflictions using identifiers or types instead of names.");
}
foreach (var afflictionType in parsedAfflictionTypes)
{
if (!AfflictionPrefab.Prefabs.Any(p => p.AfflictionType == afflictionType))
{
createWarningOrError($"Potentially invalid damage modifier in \"{parentDebugName}\". Could not find any afflictions of the type \"{afflictionType}\". Did you mean to use an affliction identifier instead?");
}
}
foreach (var afflictionIdentifier in parsedAfflictionIdentifiers)
{
if (!AfflictionPrefab.Prefabs.ContainsKey(afflictionIdentifier))
{
createWarningOrError($"Potentially invalid damage modifier in \"{parentDebugName}\". Could not find any afflictions with the identifier \"{afflictionIdentifier}\". Did you mean to use an affliction type instead?");
}
}
static void createWarningOrError(string msg)
{
#if DEBUG
DebugConsole.ThrowError(msg);
#else
DebugConsole.AddWarning(msg);
#endif
}
}
private void ParseAfflictionTypes()
@@ -1,8 +1,4 @@
using Barotrauma.Items.Components;
using Microsoft.Xna.Framework;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Microsoft.Xna.Framework;
namespace Barotrauma.Abilities
{
@@ -31,7 +27,7 @@ namespace Barotrauma.Abilities
}
}
if (!SelectedItemHasTag(closestCharacter)) { return; }
if (closestCharacter == null || !SelectedItemHasTag(closestCharacter)) { return; }
if (closestDistance < squaredMaxDistance)
{