(a00338777) v0.9.2.1

This commit is contained in:
Joonas Rikkonen
2019-08-26 19:58:19 +03:00
parent 0f63da27b2
commit 80698b58b0
311 changed files with 11763 additions and 4507 deletions
@@ -14,11 +14,6 @@ namespace Barotrauma
get;
private set;
}
/// <summary>
/// Use as a minimum or static sight range.
/// </summary>
public static float StaticSightRange = 3000;
private float soundRange;
private float sightRange;
@@ -75,7 +70,7 @@ namespace Barotrauma
public bool Enabled = true;
public float MinSoundRange, MinSightRange;
public float MaxSoundRange = float.MaxValue, MaxSightRange = float.MaxValue;
public float MaxSoundRange = 100000, MaxSightRange = 100000;
public TargetType Type { get; private set; }
@@ -128,8 +123,8 @@ namespace Barotrauma
{
SightRange = element.GetAttributeFloat("sightrange", 0.0f);
SoundRange = element.GetAttributeFloat("soundrange", 0.0f);
MinSightRange = element.GetAttributeFloat("minsightrange", SightRange);
MinSoundRange = element.GetAttributeFloat("minsoundrange", SoundRange);
MinSightRange = element.GetAttributeFloat("minsightrange", 0f);
MinSoundRange = element.GetAttributeFloat("minsoundrange", 0f);
MaxSightRange = element.GetAttributeFloat("maxsightrange", SightRange);
MaxSoundRange = element.GetAttributeFloat("maxsoundrange", SoundRange);
FadeOutTime = element.GetAttributeFloat("fadeouttime", FadeOutTime);
@@ -142,15 +137,9 @@ namespace Barotrauma
}
}
public AITarget(Entity e, float sightRange = -1, float soundRange = 0)
public AITarget(Entity e)
{
Entity = e;
if (sightRange < 0)
{
sightRange = StaticSightRange;
}
SightRange = sightRange;
SoundRange = soundRange;
List.Add(this);
}
@@ -109,9 +109,9 @@ namespace Barotrauma
private Dictionary<AITarget, AITargetMemory> targetMemories;
//the eyesight of the NPC (0.0 = blind, 1.0 = sees every target within sightRange)
private float sight;
public float sight;
//how far the NPC can hear targets from (0.0 = deaf, 1.0 = hears every target within soundRange)
private float hearing;
public float hearing;
private float colliderSize;
@@ -270,11 +270,14 @@ namespace Barotrauma
return null;
}
public override void SelectTarget(AITarget target)
public override void SelectTarget(AITarget target) => SelectTarget(target, 100);
public void SelectTarget(AITarget target, float priority)
{
SelectedAiTarget = target;
selectedTargetMemory = GetTargetMemory(target);
targetValue = 100.0f;
selectedTargetMemory.Priority = priority;
targetValue = priority;
}
public override void Update(float deltaTime)
@@ -985,7 +988,7 @@ namespace Barotrauma
var aiTarget = wallTarget.Structure.AiTarget;
if (aiTarget != null && SelectedAiTarget != aiTarget)
{
SelectTarget(aiTarget);
SelectTarget(aiTarget, GetTargetMemory(SelectedAiTarget).Priority);
}
}
if (SelectedAiTarget.Entity is IDamageable damageTarget)
@@ -370,7 +370,7 @@ namespace Barotrauma
if (item.CurrentHull != hull) { continue; }
if (AIObjectiveRepairItems.IsValidTarget(item, Character))
{
if (item.Repairables.All(r => item.Condition > r.ShowRepairUIThreshold)) { continue; }
if (item.Repairables.All(r => item.ConditionPercentage > r.ShowRepairUIThreshold)) { continue; }
AddTargets<AIObjectiveRepairItems, Item>(Character, item);
if (newOrder == null)
{
@@ -640,7 +640,7 @@ namespace Barotrauma
if (item.CurrentHull != hull) { continue; }
if (AIObjectiveRepairItems.IsValidTarget(item, character))
{
if (item.Repairables.All(r => item.Condition > r.ShowRepairUIThreshold)) { continue; }
if (item.Repairables.All(r => item.ConditionPercentage > r.ShowRepairUIThreshold)) { continue; }
AddTargets<AIObjectiveRepairItems, Item>(character, item);
}
}
@@ -142,6 +142,9 @@ namespace Barotrauma
IsPathDirty = false;
}
public Func<PathNode, bool> startNodeFilter;
public Func<PathNode, bool> endNodeFilter;
protected override Vector2 DoSteeringSeek(Vector2 target, float weight)
{
bool needsNewPath = currentPath != null && currentPath.Unreachable || Vector2.DistanceSquared(target, currentTarget) > 1;
@@ -164,7 +167,7 @@ namespace Barotrauma
}
}
var newPath = pathFinder.FindPath(pos, target, character.Submarine, "(Character: " + character.Name + ")");
var newPath = pathFinder.FindPath(pos, target, character.Submarine, "(Character: " + character.Name + ")", startNodeFilter, endNodeFilter);
bool useNewPath = currentPath == null || needsNewPath;
if (!useNewPath && currentPath != null && currentPath.CurrentNode != null && newPath.Nodes.Any() && !newPath.Unreachable)
{
@@ -14,7 +14,9 @@ namespace Barotrauma
private float waitUntilPathUnreachable;
private bool getDivingGearIfNeeded;
public Func<bool> customCondition;
public Func<bool> requiredCondition;
public Func<PathNode, bool> startNodeFilter;
public Func<PathNode, bool> endNodeFilter;
public bool followControlledCharacter;
public bool mimic;
@@ -137,7 +139,12 @@ namespace Barotrauma
currTargetSimPos -= diff;
}
}
character.AIController.SteeringManager.SteeringSeek(currTargetSimPos);
if (PathSteering != null)
{
PathSteering.startNodeFilter = startNodeFilter;
PathSteering.endNodeFilter = endNodeFilter;
}
SteeringManager.SteeringSeek(currTargetSimPos);
if (SteeringManager != PathSteering)
{
SteeringManager.SteeringAvoid(deltaTime, lookAheadDistance: 5, weight: 1, heading: VectorExtensions.Forward(character.AnimController.Collider.Rotation));
@@ -191,7 +198,7 @@ namespace Barotrauma
}
else if (closeEnough)
{
if (customCondition == null || customCondition())
if (requiredCondition == null || requiredCondition())
{
if (Target is Item item)
{
@@ -218,7 +225,7 @@ namespace Barotrauma
private void CalculateCloseEnough()
{
float interactionDistance = Target is Item i ? i.InteractDistance * 0.9f : 0;
float interactionDistance = Target is Item i ? i.InteractDistance + Math.Max(i.Rect.Width, i.Rect.Height) / 2 : 0;
CloseEnough = Math.Max(interactionDistance, CloseEnough);
}
@@ -149,7 +149,14 @@ namespace Barotrauma
character?.Speak(TextManager.GetWithVariable("DialogCannotRepair", "[itemname]", Item.Name, true), null, 0.0f, "cannotrepair", 10.0f);
}
}
repairable.CurrentFixer = abandon && repairable.CurrentFixer == character ? null : character;
if (abandon)
{
repairable.StopRepairing(character);
}
else
{
repairable.StartRepairing(character, Repairable.FixActions.Repair);
}
break;
}
}
@@ -161,7 +168,11 @@ namespace Barotrauma
constructor: () =>
{
previousCondition = -1;
var objective = new AIObjectiveGoTo(Item, character, objectiveManager);
var objective = new AIObjectiveGoTo(Item, character, objectiveManager)
{
// Don't stop in ladders, because we can't interact with other items while holding the ladders.
endNodeFilter = node => node.Waypoint.Ladders == null
};
if (repairTool != null)
{
objective.CloseEnough = repairTool.Range * 0.75f;
@@ -43,7 +43,7 @@ namespace Barotrauma
if (Character.CharacterList.Any(c => c.CurrentHull == item.CurrentHull && !HumanAIController.IsFriendly(c))) { return false; }
if (!Objectives.ContainsKey(item))
{
if (item.Repairables.All(r => item.Condition > r.ShowRepairUIThreshold)) { return false; }
if (item.Repairables.All(r => item.ConditionPercentage > r.ShowRepairUIThreshold)) { return false; }
}
if (RequireAdequateSkills)
{
@@ -157,12 +157,13 @@ namespace Barotrauma
}
}
public SteeringPath FindPath(Vector2 start, Vector2 end, Submarine hostSub = null, string errorMsgStr = null)
public SteeringPath FindPath(Vector2 start, Vector2 end, Submarine hostSub = null, string errorMsgStr = null, Func<PathNode, bool> startNodeFilter = null, Func<PathNode, bool> endNodeFilter = null)
{
float closestDist = 0.0f;
PathNode startNode = null;
foreach (PathNode node in nodes)
{
if (startNodeFilter != null && !startNodeFilter(node)) { continue; }
Vector2 nodePos = node.Position;
if (hostSub != null)
{
@@ -219,6 +220,7 @@ namespace Barotrauma
PathNode endNode = null;
foreach (PathNode node in nodes)
{
if (endNodeFilter != null && !endNodeFilter(node)) { continue; }
Vector2 nodePos = node.Position;
if (hostSub != null)
{
@@ -96,8 +96,8 @@ namespace Barotrauma
public virtual AnimationType AnimationType { get; protected set; }
public static string GetDefaultFileName(string speciesName, AnimationType animType) => $"{speciesName.CapitaliseFirstInvariant()}{animType.ToString()}";
public static string GetDefaultFile(string speciesName, AnimationType animType, ContentPackage contentPackage = null) =>
$"{GetFolder(speciesName, contentPackage)}{GetDefaultFileName(speciesName, animType)}.xml";
public static string GetDefaultFile(string speciesName, AnimationType animType, ContentPackage contentPackage = null)
=> Path.Combine(GetFolder(speciesName, contentPackage), $"{GetDefaultFileName(speciesName, animType)}.xml");
public static string GetFolder(string speciesName, ContentPackage contentPackage = null)
{
@@ -66,7 +66,8 @@ namespace Barotrauma
.Concat(Joints.Select(j => j as RagdollSubParams)));
public static string GetDefaultFileName(string speciesName) => $"{speciesName.CapitaliseFirstInvariant()}DefaultRagdoll";
public static string GetDefaultFile(string speciesName, ContentPackage contentPackage = null) => $"{GetFolder(speciesName, contentPackage)}{GetDefaultFileName(speciesName)}.xml";
public static string GetDefaultFile(string speciesName, ContentPackage contentPackage = null)
=> Path.Combine(GetFolder(speciesName, contentPackage), $"{GetDefaultFileName(speciesName)}.xml");
private static readonly object[] dummyParams = new object[]
{
@@ -1324,7 +1324,7 @@ namespace Barotrauma
private void CheckBodyInRest(float deltaTime)
{
if (Collider.LinearVelocity.LengthSquared() > 0.01f || character.SelectedBy != null || !character.IsDead)
if (InWater || Collider.LinearVelocity.LengthSquared() > 0.01f || character.SelectedBy != null || !character.IsDead)
{
bodyInRestTimer = 0.0f;
foreach (Limb limb in Limbs)
@@ -1383,10 +1383,12 @@ namespace Barotrauma
private bool CheckValidity(PhysicsBody body)
{
string errorMsg = null;
string bodyName = body.UserData is Limb ? "Limb" : "Collider";
string bodyName = body.UserData is Limb limb ?
"Limb (" + limb.type + ")" :
"Collider";
if (!MathUtils.IsValid(body.SimPosition) || Math.Abs(body.SimPosition.X) > 1e10f || Math.Abs(body.SimPosition.Y) > 1e10f)
{
errorMsg = bodyName+ " position invalid (" + body.SimPosition + ", character: " + character.Name + "), resetting the ragdoll.";
errorMsg = bodyName + " position invalid (" + body.SimPosition + ", character: " + character.Name + "), resetting the ragdoll.";
}
else if (!MathUtils.IsValid(body.LinearVelocity) || Math.Abs(body.LinearVelocity.X) > 1000f || Math.Abs(body.LinearVelocity.Y) > 1000f)
{
@@ -1426,10 +1428,10 @@ namespace Barotrauma
{
Collider.SetTransform(Vector2.Zero, 0.0f);
}
foreach (Limb limb in Limbs)
foreach (Limb otherLimb in Limbs)
{
limb.body.SetTransform(Collider.SimPosition, 0.0f);
limb.body.ResetDynamics();
otherLimb.body.SetTransform(Collider.SimPosition, 0.0f);
otherLimb.body.ResetDynamics();
}
SetInitialLimbPositions();
return false;
@@ -104,6 +104,9 @@ namespace Barotrauma
public readonly bool IsHumanoid;
public bool IsTraitor;
public string TraitorCurrentObjective = "";
//the name of the species (e.q. human)
public readonly string SpeciesName;
@@ -1515,12 +1518,12 @@ namespace Barotrauma
bool leftHand = Inventory.IsInLimbSlot(item, InvSlotType.LeftHand);
bool selected = false;
if (rightHand && SelectedItems[0] == null)
if (rightHand && (SelectedItems[0] == null || SelectedItems[0] == item))
{
selectedItems[0] = item;
selected = true;
}
if (leftHand && SelectedItems[1] == null)
if (leftHand && (SelectedItems[1] == null || SelectedItems[1] == item))
{
selectedItems[1] = item;
selected = true;
@@ -1839,7 +1842,7 @@ namespace Barotrauma
{
DeselectCharacter();
}
else if (focusedCharacter != null && IsKeyHit(InputType.Grab) && FocusedCharacter.CanInventoryBeAccessed)
else if (focusedCharacter != null && IsKeyHit(InputType.Grab) && FocusedCharacter.CanBeDragged)
{
SelectCharacter(focusedCharacter);
}
@@ -1954,6 +1957,10 @@ namespace Barotrauma
//disable AI characters that are far away from the sub and the controlled character
float distSqr = Vector2.DistanceSquared(Submarine.MainSub.WorldPosition, c.WorldPosition);
if (Controlled != null)
{
distSqr = Math.Min(distSqr, Vector2.DistanceSquared(Controlled.WorldPosition, c.WorldPosition));
}
else
{
distSqr = Math.Min(distSqr, Vector2.DistanceSquared(GameMain.GameScreen.Cam.GetPosition(), c.WorldPosition));
}
@@ -2198,16 +2205,15 @@ namespace Barotrauma
private void UpdateSightRange()
{
if (aiTarget == null) { return; }
// TODO: the formula might need some tweaking
float range = (float)Math.Sqrt(Mass) * 1000.0f + AnimController.Collider.LinearVelocity.Length() * 500.0f;
aiTarget.SightRange = MathHelper.Clamp(range, 0, 15000.0f);
float range = (float)Math.Sqrt(Mass) * 250 + AnimController.Collider.LinearVelocity.Length() * 500;
aiTarget.SightRange = MathHelper.Clamp(range, 0, 10000);
}
private void UpdateSoundRange()
{
if (aiTarget == null) { return; }
float range = Mass / 5 * AnimController.TargetMovement.Length() * Noise;
aiTarget.SoundRange = MathHelper.Clamp(range, 0f, 5000f);
float range = ((float)Math.Sqrt(Mass) / 3) * (AnimController.TargetMovement.Length() * 2) * Noise;
aiTarget.SoundRange = MathHelper.Clamp(range, 0, 10000);
}
public void SetOrder(Order order, string orderOption, Character orderGiver, bool speak = true)
@@ -2598,6 +2604,7 @@ namespace Barotrauma
{
if (selectedItems[i] != null) selectedItems[i].Drop(this);
}
SelectedConstruction = null;
AnimController.ResetPullJoints();
@@ -21,7 +21,7 @@ namespace Barotrauma
/// <summary>
/// Probability for the affliction to be applied. Used by attacks.
/// </summary>
public float ApplyProbability;
public float ApplyProbability = 1.0f;
/// <summary>
/// Which character gave this affliction
@@ -9,6 +9,10 @@ namespace Barotrauma
{
private float invertControlsCooldown = 60.0f;
private float stunCoolDown = 60.0f;
private float invertControlsTimer;
private float invertControlsToggleTimer;
public AfflictionSpaceHerpes(AfflictionPrefab prefab, float strength) : base(prefab, strength)
{
}
@@ -25,10 +29,29 @@ namespace Barotrauma
//invert controls every 126-234 seconds when strength is close to 0
//every 56-104 seconds when strength is close to 100
invertControlsCooldown = (180.0f - Strength) * Rand.Range(0.7f, 1.3f);
var invertControlsAffliction = AfflictionPrefab.List.Find(ap => ap.Identifier == "invertcontrols");
float invertControlsDuration = MathHelper.Lerp(10.0f, 60.0f, Strength / 100.0f) * Rand.Range(0.7f, 1.3f);
characterHealth.ApplyAffliction(null, new Affliction(invertControlsAffliction, invertControlsDuration));
invertControlsTimer = MathHelper.Lerp(10.0f, 60.0f, Strength / 100.0f) * Rand.Range(0.7f, 1.3f);
}
else if (invertControlsTimer > 0.0f)
{
//randomly toggle inverted controls on/off every 5 seconds
invertControlsToggleTimer -= deltaTime;
if (invertControlsToggleTimer <= 0.0f)
{
invertControlsToggleTimer = 5.0f;
if (Rand.Range(0.0f, 1.0f) < 0.5f)
{
characterHealth.ReduceAffliction(null, "invertcontrols", 100);
}
else
{
var invertControlsAffliction = AfflictionPrefab.List.Find(ap => ap.Identifier == "invertcontrols");
characterHealth.ApplyAffliction(null, new Affliction(invertControlsAffliction, 5.0f));
}
}
invertControlsTimer -= deltaTime;
}
if (Strength > 50.0f)
{
@@ -1,9 +1,9 @@
using Lidgren.Network;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Barotrauma.Networking;
namespace Barotrauma
{
@@ -732,14 +732,14 @@ namespace Barotrauma
return allAfflictions;
}
public void ServerWrite(NetBuffer msg)
public void ServerWrite(IWriteMessage msg)
{
List<Affliction> activeAfflictions = afflictions.FindAll(a => a.Strength > 0.0f && a.Strength >= a.Prefab.ActivationThreshold);
msg.Write((byte)activeAfflictions.Count);
foreach (Affliction affliction in activeAfflictions)
{
msg.WriteRangedInteger(0, AfflictionPrefab.List.Count - 1, AfflictionPrefab.List.IndexOf(affliction.Prefab));
msg.WriteRangedIntegerDeprecated(0, AfflictionPrefab.List.Count - 1, AfflictionPrefab.List.IndexOf(affliction.Prefab));
msg.WriteRangedSingle(
MathHelper.Clamp(affliction.Strength, 0.0f, affliction.Prefab.MaxStrength),
0.0f, affliction.Prefab.MaxStrength, 8);
@@ -758,8 +758,8 @@ namespace Barotrauma
msg.Write((byte)limbAfflictions.Count);
foreach (var limbAffliction in limbAfflictions)
{
msg.WriteRangedInteger(0, limbHealths.Count - 1, limbHealths.IndexOf(limbAffliction.First));
msg.WriteRangedInteger(0, AfflictionPrefab.List.Count - 1, AfflictionPrefab.List.IndexOf(limbAffliction.Second.Prefab));
msg.WriteRangedIntegerDeprecated(0, limbHealths.Count - 1, limbHealths.IndexOf(limbAffliction.First));
msg.WriteRangedIntegerDeprecated(0, AfflictionPrefab.List.Count - 1, AfflictionPrefab.List.IndexOf(limbAffliction.Second.Prefab));
msg.WriteRangedSingle(
MathHelper.Clamp(limbAffliction.Second.Strength, 0.0f, limbAffliction.Second.Prefab.MaxStrength),
0.0f, limbAffliction.Second.Prefab.MaxStrength, 8);
@@ -144,6 +144,15 @@ namespace Barotrauma
#if SERVER
if (GameMain.Server != null && Entity.Spawner != null)
{
if (GameMain.Server.EntityEventManager.UniqueEvents.Any(ev => ev.Entity == item))
{
string errorMsg = $"Error while spawning job items. Item {item.Name} created network events before the spawn event had been created.";
DebugConsole.ThrowError(errorMsg);
GameAnalyticsManager.AddErrorEventOnce("Job.InitializeJobItem:EventsBeforeSpawning", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
GameMain.Server.EntityEventManager.UniqueEvents.RemoveAll(ev => ev.Entity == item);
GameMain.Server.EntityEventManager.Events.RemoveAll(ev => ev.Entity == item);
}
Entity.Spawner.CreateNetworkEvent(item, false);
}
#endif