(aea5053bf) Fix wall target position not updated when the submarine moves. Fix latchontoai attach positions and distance checks. Detaching should also work both when the characters can get in and when the submarine velocity is enough to detach the characters. Still not synced, but re-enabled for testing.

This commit is contained in:
Joonas Rikkonen
2019-03-26 14:06:55 +02:00
parent ccd496b769
commit 14832e2040
15 changed files with 76 additions and 188 deletions
@@ -288,7 +288,7 @@ namespace Barotrauma
}
else
{
var targetingPriority = UpdateTargets(Character);
UpdateTargets(Character, out TargetingPriority targetingPriority);
updateTargetsTimer = UpdateTargetsInterval;
if (SelectedAiTarget == null)
@@ -299,7 +299,7 @@ namespace Barotrauma
{
State = AIState.Escape;
}
else
else if (targetingPriority != null)
{
State = targetingPriority.State;
}
@@ -472,7 +472,10 @@ namespace Barotrauma
}
else
{
UpdateWallTarget();
if (!IsProperlyLatched)
{
UpdateWallTarget();
}
raycastTimer = RaycastInterval;
}
@@ -496,6 +499,10 @@ namespace Barotrauma
if (wallTarget != null)
{
attackWorldPos = wallTarget.Position;
if (wallTarget.Structure.Submarine != null)
{
attackWorldPos += wallTarget.Structure.Submarine.Position;
}
attackSimPos = ConvertUnits.ToSimUnits(attackWorldPos);
}
else
@@ -839,12 +846,7 @@ namespace Barotrauma
attachTargetNormal = new Vector2(Math.Sign(WorldPosition.X - wall.WorldPosition.X), 0.0f);
sectionPos.X += (wall.BodyWidth <= 0.0f ? wall.Rect.Width : wall.BodyWidth) / 2 * attachTargetNormal.X;
}
latchOntoAI?.SetAttachTarget(wall.Submarine.PhysicsBody.FarseerBody, wall.Submarine, sectionPos, attachTargetNormal);
if (wall.Submarine != null)
{
sectionPos += wall.Submarine.Position;
}
latchOntoAI?.SetAttachTarget(wall.Submarine.PhysicsBody.FarseerBody, wall.Submarine, ConvertUnits.ToSimUnits(sectionPos), attachTargetNormal);
wallTarget = new WallTarget(sectionPos, wall, sectionIndex);
}
}
@@ -967,18 +969,27 @@ namespace Barotrauma
steeringManager.SteeringSeek(attackSimPosition - (mouthPos - SimPosition));
}
}
#endregion
#region Targeting
private bool IsProperlyLatched => latchOntoAI != null && latchOntoAI.IsAttached && 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 TargetingPriority UpdateTargets(Character character)
public AITarget UpdateTargets(Character character, out TargetingPriority priority)
{
if (IsProperlyLatched)
{
// If attached to a valid target, just keep the target.
// Priority not used in this case.
priority = null;
return SelectedAiTarget;
}
AITarget newTarget = null;
TargetingPriority targetingPriority = null;
priority = null;
selectedTargetMemory = null;
targetValue = 0.0f;
@@ -1177,7 +1188,7 @@ namespace Barotrauma
{
newTarget = target;
selectedTargetMemory = targetMemory;
targetingPriority = targetingPriorities[targetingTag];
priority = targetingPriorities[targetingTag];
targetValue = valueModifier;
}
}
@@ -1187,7 +1198,7 @@ namespace Barotrauma
{
wallTarget = null;
}
return targetingPriority;
return SelectedAiTarget;
}
private AITargetMemory GetTargetMemory(AITarget target)
@@ -193,7 +193,7 @@ namespace Barotrauma
// is not attached or is attached to something else
if (!IsAttached || IsAttached && attachJoints[0].BodyB == attachTargetBody)
{
if (Vector2.DistanceSquared(ConvertUnits.ToDisplayUnits(transformedAttachPos), enemyAI.AttackingLimb.WorldPosition) < enemyAI.AttackingLimb.attack.Range * enemyAI.AttackingLimb.attack.Range)
if (Vector2.DistanceSquared(ConvertUnits.ToDisplayUnits(transformedAttachPos), enemyAI.AttackingLimb.WorldPosition) < enemyAI.AttackingLimb.attack.DamageRange * enemyAI.AttackingLimb.attack.DamageRange)
{
AttachToBody(character.AnimController.Collider, attachLimb, attachTargetBody, transformedAttachPos);
}
@@ -528,7 +528,7 @@ namespace Barotrauma
}
else
{
// If the attack is aimed to a character but hits a structure, the hit is blocked.
// If there is nothing between, the hit is successful
wasHit = structureBody == null;
}
}
@@ -103,6 +103,12 @@ namespace Barotrauma
if (missionType == MissionType.Random)
{
allowedMissions.AddRange(MissionPrefab.List);
#if SERVER
if (GameMain.Server != null)
{
allowedMissions.RemoveAll(mission => !GameMain.Server.ServerSettings.AllowedRandomMissionTypes.Contains(mission.type));
}
#endif
}
else if (missionType == MissionType.None)
{
@@ -211,14 +211,14 @@ namespace Barotrauma
set { spriteColor = value; }
}
[Serialize("1.0,1.0,1.0,1.0", true), Editable]
[Serialize("1.0,1.0,1.0,1.0", false), Editable]
public Color InventoryIconColor
{
get;
protected set;
}
[Serialize("1.0,1.0,1.0,1.0", true), Editable(ToolTip = "Changes the color of the item this item is contained inside. Only has an effect if either of the UseContainedSpriteColor or UseContainedInventoryIconColor property of the container is set to true.")]
[Serialize("1.0,1.0,1.0,1.0", false), Editable(ToolTip = "Changes the color of the item this item is contained inside. Only has an effect if either of the UseContainedSpriteColor or UseContainedInventoryIconColor property of the container is set to true.")]
public Color ContainerColor
{
get;
@@ -33,7 +33,7 @@ namespace Barotrauma
get
{
CheckMissionCompleted();
for (int i = availableMissions.Count; i < Connections.Count * 2; i++)
{
int seed = (ToolBox.StringToInt(BaseName) + MissionsCompleted * 10 + i) % int.MaxValue;
@@ -47,7 +47,7 @@ namespace Barotrauma
if (availableMissions.Any(m => m.Prefab == mission.Prefab)) { continue; }
if (GameSettings.VerboseLogging && mission != null)
{
DebugConsole.NewMessage("Generated a new mission for a location (location: " + Name + ", seed: " + seed.ToString("X") + ", missions completed: " + MissionsCompleted + ", type: " + mission.Name + ")", Color.White);
DebugConsole.NewMessage("Generated a new mission for a location connection (seed: " + seed.ToString("X") + ", type: " + mission.Name + ")", Color.White);
}
availableMissions.Add(mission);
}
@@ -100,16 +100,7 @@ namespace Barotrauma
public void ChangeType(LocationType newType)
{
if (newType == Type) { return; }
//clear missions from this and adjacent locations (they may be invalid now)
availableMissions.Clear();
foreach (LocationConnection connection in Connections)
{
connection.OtherLocation(this)?.availableMissions.Clear();
}
DebugConsole.Log("Location " + baseName + " changed it's type from " + Type + " to " + newType);
if (newType == Type) return;
Type = newType;
Name = Type.NameFormats[nameFormatIndex % Type.NameFormats.Count].Replace("[name]", baseName);
@@ -121,7 +112,6 @@ namespace Barotrauma
{
if (mission.Completed)
{
DebugConsole.Log("Mission \"" + mission.Name + "\" completed in \"" + Name + "\".");
MissionsCompleted++;
}
}
@@ -32,7 +32,6 @@ namespace Barotrauma
public static void SaveGame(string filePath)
{
DebugConsole.Log("Saving the game to: " + filePath);
Directory.CreateDirectory(TempPath);
try
{
@@ -112,7 +111,6 @@ namespace Barotrauma
public static XDocument LoadGameSessionDoc(string filePath)
{
DebugConsole.Log("Loading game session doc: " + filePath);
try
{
DecompressToDirectory(filePath, TempPath, null);
@@ -403,18 +401,18 @@ namespace Barotrauma
}
}
public static void ClearFolder(string FolderName, string[] ignoredFileNames = null)
public static void ClearFolder(string FolderName, string[] ignoredFiles = null)
{
DirectoryInfo dir = new DirectoryInfo(FolderName);
foreach (FileInfo fi in dir.GetFiles())
{
if (ignoredFileNames != null)
if (ignoredFiles != null)
{
bool ignore = false;
foreach (string ignoredFile in ignoredFileNames)
foreach (string ignoredFile in ignoredFiles)
{
if (Path.GetFileName(fi.FullName).Equals(Path.GetFileName(ignoredFile)))
if (Path.GetFullPath(fi.FullName).Equals(Path.GetFullPath(ignoredFile)))
{
ignore = true;
break;