v1.5.7.0 (Summer Update)

This commit is contained in:
Regalis11
2024-06-18 16:49:51 +03:00
parent 4a63dacbce
commit 230d1b6e78
263 changed files with 7792 additions and 2845 deletions
@@ -2,6 +2,7 @@
using Microsoft.Xna.Framework;
using System.Collections.Generic;
using System.Linq;
using Barotrauma.Items.Components;
namespace Barotrauma
{
@@ -13,17 +14,33 @@ namespace Barotrauma
protected override float TargetUpdateTimeMultiplier => 1.0f;
const float DefaultInspectDistance = 200.0f;
/// <summary>
/// How long the round must have ran before NPCs can start doing inspections
/// (prevents "unfair" inspections you have no chance to react to if you happen to spawn right next to a security NPC with stolen items on you)
/// </summary>
private const float DelayOnRoundStart = 30.0f;
private const float DefaultInspectDistance = 200.0f;
/// <summary>
/// Used when something is stolen and when the guards decide to inspect everyone.
/// </summary>
private const float ExtendedInspectDistance = 400.0f;
/// <summary>
/// Used when the target is tagged as a criminal (= suspective).
/// </summary>
private const float CriminalInspectDistance = 500.0f;
private const float CriminalInspectProbability = 1.0f;
/// <summary>
/// How close the NPC must be to the target to the inspect them? You can use high values to make the NPC
/// systematically go through targets no matter where they are, and low values to check targets they happen to come across.
/// </summary>
public float InspectDistance = DefaultInspectDistance;
private float inspectDistance = DefaultInspectDistance;
private float? overrideInspectProbability;
/// <summary>
/// Chance of inspecting a valid target. The NPC won't try to inspect that target again for <see cref="inspectionInterval"/>
/// Chance of inspecting a valid target. The NPC won't try to inspect that target again for <see cref="NormalInspectionInterval"/>
/// regardless if the target is inspected or not.
/// </summary>
public float InspectProbability
@@ -53,18 +70,25 @@ namespace Barotrauma
/// When did the character last inspect whether some other character has stolen items on them?
/// </summary>
private static readonly Dictionary<Character, double> lastInspectionTimes = new Dictionary<Character, double>();
private readonly float inspectionInterval = 120.0f;
private const float NormalInspectionInterval = 120.0f;
private const float CriminalInspectionInterval = 30.0f;
public AIObjectiveFindThieves(Character character, AIObjectiveManager objectiveManager, float priorityModifier = 1)
: base(character, objectiveManager, priorityModifier) { }
protected override bool Filter(Character target)
protected override bool IsValidTarget(Character target)
{
if (GameMain.GameSession is not { RoundDuration: > DelayOnRoundStart })
{
return false;
}
if (!IsValidTarget(target, character)) { return false; }
if (Vector2.DistanceSquared(target.WorldPosition, character.WorldPosition) > InspectDistance * InspectDistance) { return false; }
float inspectDist = target.IsCriminal ? CriminalInspectDistance : inspectDistance;
if (Vector2.DistanceSquared(target.WorldPosition, character.WorldPosition) > inspectDist * inspectDist) { return false; }
if (lastInspectionTimes.TryGetValue(target, out double lastInspectionTime))
{
float inspectionInterval = target.IsCriminal ? CriminalInspectionInterval : NormalInspectionInterval;
if (Timing.TotalTime < lastInspectionTime + inspectionInterval)
{
return false;
@@ -75,8 +99,14 @@ namespace Barotrauma
protected override IEnumerable<Character> GetList() => Character.CharacterList;
protected override float TargetEvaluation()
protected override float GetTargetPriority()
{
if (character.IsClimbing)
{
// Don't inspect while climbing, because cannot grab while holding the ladders.
// Can lead to abandoning the objective when we need to climb the ladders to get to the target, but I think that's acceptable.
return 0;
}
return subObjectives.Any() ? 50 : 0;
}
@@ -84,13 +114,14 @@ namespace Barotrauma
{
lastInspectionTimes.Clear();
overrideInspectProbability = 1.0f;
InspectDistance = DefaultInspectDistance * 2;
inspectDistance = ExtendedInspectDistance;
}
protected override AIObjective ObjectiveConstructor(Character target)
{
var checkStolenItemsObjective = new AIObjectiveCheckStolenItems(character, target, objectiveManager);
if (Rand.Range(0.0f, 1.0f, Rand.RandSync.Unsynced) >= InspectProbability)
float probabity = target.IsCriminal ? CriminalInspectProbability : InspectProbability;
if (Rand.Range(0.0f, 1.0f, Rand.RandSync.Unsynced) >= probabity)
{
checkStolenItemsObjective.ForceComplete();
lastInspectionTimes[target] = Timing.TotalTime;
@@ -104,26 +135,30 @@ namespace Barotrauma
public override void Update(float deltaTime)
{
base.Update(deltaTime);
if (checkVisibleStolenItemsTimer > 0.0f)
if (checkVisibleStolenItemsTimer > 0.0f || character.IsClimbing)
{
checkVisibleStolenItemsTimer -= deltaTime;
return;
}
if (character.SelectedSecondaryItem?.GetComponent<Controller>() != null)
{
// Might be e.g. sitting on a chair.
character.SelectedSecondaryItem = null;
}
foreach (var target in Character.CharacterList)
{
if (!IsValidTarget(target, character)) { continue; }
//if we spot someone wearing or holding stolen items, immediately check them (with 100% chance of spotting the stolen items)
if (target.Inventory.AllItems.Any(it => it.SpawnedInCurrentOutpost && !it.AllowStealing && target.HasEquippedItem(it)) &&
if (target.Inventory.AllItems.Any(it => it.Illegitimate && target.HasEquippedItem(it)) &&
character.CanSeeTarget(target, seeThroughWindows: true))
{
AIObjectiveCheckStolenItems? existingObjective =
objectiveManager.GetActiveObjectives<AIObjectiveCheckStolenItems>().FirstOrDefault(o => o.TargetCharacter == target);
objectiveManager.GetActiveObjectives<AIObjectiveCheckStolenItems>().FirstOrDefault(o => o.Target == target);
if (existingObjective == null)
{
objectiveManager.AddObjective(new AIObjectiveCheckStolenItems(character, target, objectiveManager));
lastInspectionTimes[target] = Timing.TotalTime;
}
}
}
checkVisibleStolenItemsTimer = CheckVisibleStolenItemsInterval;
@@ -140,7 +175,17 @@ namespace Barotrauma
if (target.Submarine != character.Submarine) { return false; }
//only player's crew can steal, ignore other teams
if (!target.IsOnPlayerTeam) { return false; }
if (target.IsArrested) { return false; }
if (target.IsHandcuffed) { return false; }
// Ignore targets that are climbing, because might need to use ladders to get to them.
if (target.IsClimbing) { return false; }
if (HumanAIController.IsTrueForAnyBotInTheCrew(bot =>
bot != HumanAIController &&
((bot.ObjectiveManager.GetActiveObjective() is AIObjectiveCheckStolenItems checkObj && checkObj.Target == target) ||
(bot.ObjectiveManager.GetActiveObjective() is AIObjectiveCombat combatObj && combatObj.Enemy == target))))
{
// Already being inspected by someone or fighting with someone in our team.
return false;
}
return true;
}
@@ -148,5 +193,11 @@ namespace Barotrauma
{
lastInspectionTimes[target] = Timing.TotalTime;
}
public override void OnDeselected()
{
base.OnDeselected();
character.DeselectCharacter();
}
}
}