(1a1137b26) Charybdis now also targets the walls. Tweak Charybdis' attacks and priorities. Fix targeting walls for non-aggressiveboarders. Don't double the wall priority.
This commit is contained in:
@@ -88,13 +88,13 @@ namespace Barotrauma
|
|||||||
Collider.AngularVelocity = newAngularVelocity;
|
Collider.AngularVelocity = newAngularVelocity;
|
||||||
|
|
||||||
float distSqrd = Vector2.DistanceSquared(newPosition, Collider.SimPosition);
|
float distSqrd = Vector2.DistanceSquared(newPosition, Collider.SimPosition);
|
||||||
float errorTolerance = character.AllowInput ? 0.01f : 0.2f;
|
float errorTolerance = character.AllowInput ? 0.01f : 0.1f;
|
||||||
if (distSqrd > errorTolerance)
|
if (distSqrd > errorTolerance)
|
||||||
{
|
{
|
||||||
if (distSqrd > 10.0f || !character.AllowInput)
|
if (distSqrd > 10.0f || !character.AllowInput)
|
||||||
{
|
{
|
||||||
Collider.TargetRotation = newRotation;
|
Collider.TargetRotation = newRotation;
|
||||||
SetPosition(newPosition, lerp: distSqrd < 5.0f);
|
SetPosition(newPosition, lerp: distSqrd < 1.0f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -108,15 +108,8 @@ namespace Barotrauma
|
|||||||
// -> we need to correct it manually
|
// -> we need to correct it manually
|
||||||
if (!character.AllowInput)
|
if (!character.AllowInput)
|
||||||
{
|
{
|
||||||
float mainLimbDistSqrd = Vector2.DistanceSquared(MainLimb.PullJointWorldAnchorA, Collider.SimPosition);
|
MainLimb.PullJointWorldAnchorB = Collider.SimPosition;
|
||||||
float mainLimbErrorTolerance = 0.1f;
|
MainLimb.PullJointEnabled = true;
|
||||||
//if the main limb is roughly at the correct position and the collider isn't moving (much at least),
|
|
||||||
//don't attempt to correct the position.
|
|
||||||
if (mainLimbDistSqrd > mainLimbErrorTolerance || Collider.LinearVelocity.LengthSquared() > 0.05f)
|
|
||||||
{
|
|
||||||
MainLimb.PullJointWorldAnchorB = Collider.SimPosition;
|
|
||||||
MainLimb.PullJointEnabled = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
character.MemLocalState.Clear();
|
character.MemLocalState.Clear();
|
||||||
|
|||||||
@@ -656,13 +656,6 @@ namespace Barotrauma
|
|||||||
msg.Timer -= deltaTime;
|
msg.Timer -= deltaTime;
|
||||||
msg.Pos += msg.Velocity * deltaTime;
|
msg.Pos += msg.Velocity * deltaTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (GUIMessage msg in messages)
|
|
||||||
{
|
|
||||||
if (!msg.WorldSpace) continue;
|
|
||||||
msg.Timer -= deltaTime;
|
|
||||||
msg.Pos += msg.Velocity * deltaTime;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
messages.RemoveAll(m => m.Timer <= 0.0f);
|
messages.RemoveAll(m => m.Timer <= 0.0f);
|
||||||
|
|||||||
@@ -44,9 +44,7 @@ namespace Barotrauma.Items.Components
|
|||||||
private float displayScale;
|
private float displayScale;
|
||||||
|
|
||||||
private float zoomSqrt;
|
private float zoomSqrt;
|
||||||
|
|
||||||
private float showDirectionalIndicatorTimer;
|
|
||||||
|
|
||||||
//Vector2 = vector from the ping source to the position of the disruption
|
//Vector2 = vector from the ping source to the position of the disruption
|
||||||
//float = strength of the disruption, between 0-1
|
//float = strength of the disruption, between 0-1
|
||||||
List<Pair<Vector2, float>> disruptedDirections = new List<Pair<Vector2, float>>();
|
List<Pair<Vector2, float>> disruptedDirections = new List<Pair<Vector2, float>>();
|
||||||
@@ -147,7 +145,6 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
OnMoved = (scrollbar, scroll) =>
|
OnMoved = (scrollbar, scroll) =>
|
||||||
{
|
{
|
||||||
showDirectionalIndicatorTimer = 1.0f;
|
|
||||||
float pingAngle = MathHelper.Lerp(0.0f, MathHelper.TwoPi, scroll);
|
float pingAngle = MathHelper.Lerp(0.0f, MathHelper.TwoPi, scroll);
|
||||||
pingDirection = new Vector2((float)Math.Cos(pingAngle), (float)Math.Sin(pingAngle));
|
pingDirection = new Vector2((float)Math.Cos(pingAngle), (float)Math.Sin(pingAngle));
|
||||||
if (GameMain.Client != null)
|
if (GameMain.Client != null)
|
||||||
@@ -178,7 +175,6 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
public override void UpdateHUD(Character character, float deltaTime, Camera cam)
|
public override void UpdateHUD(Character character, float deltaTime, Camera cam)
|
||||||
{
|
{
|
||||||
showDirectionalIndicatorTimer -= deltaTime;
|
|
||||||
if (GameMain.Client != null)
|
if (GameMain.Client != null)
|
||||||
{
|
{
|
||||||
if (unsentChanges)
|
if (unsentChanges)
|
||||||
@@ -382,13 +378,12 @@ namespace Barotrauma.Items.Components
|
|||||||
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);
|
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);
|
||||||
}
|
}
|
||||||
|
|
||||||
float directionalPingVisibility = useDirectionalPing && IsActive ? 1.0f : showDirectionalIndicatorTimer;
|
if (useDirectionalPing && IsActive)
|
||||||
if (directionalPingVisibility > 0.0f)
|
|
||||||
{
|
{
|
||||||
Vector2 sector1 = MathUtils.RotatePointAroundTarget(pingDirection * DisplayRadius, Vector2.Zero, DirectionalPingSector * 0.5f);
|
Vector2 sector1 = MathUtils.RotatePointAroundTarget(pingDirection * DisplayRadius, Vector2.Zero, DirectionalPingSector * 0.5f);
|
||||||
Vector2 sector2 = MathUtils.RotatePointAroundTarget(pingDirection * DisplayRadius, Vector2.Zero, -DirectionalPingSector * 0.5f);
|
Vector2 sector2 = MathUtils.RotatePointAroundTarget(pingDirection * DisplayRadius, Vector2.Zero, -DirectionalPingSector * 0.5f);
|
||||||
GUI.DrawLine(spriteBatch, center, center + sector1, Color.LightCyan * 0.2f * directionalPingVisibility, width: 3);
|
GUI.DrawLine(spriteBatch, center, center + sector1, Color.LightCyan * 0.2f, width: 3);
|
||||||
GUI.DrawLine(spriteBatch, center, center + sector2, Color.LightCyan * 0.2f * directionalPingVisibility, width: 3);
|
GUI.DrawLine(spriteBatch, center, center + sector2, Color.LightCyan * 0.2f, width: 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GameMain.DebugDraw)
|
if (GameMain.DebugDraw)
|
||||||
|
|||||||
@@ -726,7 +726,8 @@ namespace Barotrauma
|
|||||||
if (!canAttack && !IsCoolDownRunning)
|
if (!canAttack && !IsCoolDownRunning)
|
||||||
{
|
{
|
||||||
// If not, reset the attacking limb, if the cooldown is not running
|
// If not, reset the attacking limb, if the cooldown is not running
|
||||||
AttackingLimb = null;
|
// Don't use the property, because we don't want cancel reversing, if we are reversing.
|
||||||
|
_attackingLimb = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -797,7 +798,6 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
UpdateLimbAttack(deltaTime, AttackingLimb, attackSimPos, distance);
|
UpdateLimbAttack(deltaTime, AttackingLimb, attackSimPos, distance);
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool SteerThroughGap(Structure wall, WallSection section, Vector2 targetWorldPos, float deltaTime)
|
private bool SteerThroughGap(Structure wall, WallSection section, Vector2 targetWorldPos, float deltaTime)
|
||||||
@@ -1133,6 +1133,49 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (targetCharacter.Submarine != null && Character.Submarine == null)
|
else if (targetCharacter.Submarine != null && Character.Submarine == null)
|
||||||
|
{
|
||||||
|
targetingTag = "dead";
|
||||||
|
if (targetCharacter.Submarine != Character.Submarine)
|
||||||
|
{
|
||||||
|
// In a different sub or the target is outside when we are inside or vice versa -> Ignore the target
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (targetCharacter.CurrentHull != Character.CurrentHull)
|
||||||
|
{
|
||||||
|
// In the same sub, halve the priority, if not in the same hull.
|
||||||
|
valueModifier = 0.5f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (targetCharacter.AIController is EnemyAIController enemy)
|
||||||
|
{
|
||||||
|
if (enemy.combatStrength > combatStrength)
|
||||||
|
{
|
||||||
|
targetingTag = "stronger";
|
||||||
|
}
|
||||||
|
else if (enemy.combatStrength < combatStrength)
|
||||||
|
{
|
||||||
|
targetingTag = "weaker";
|
||||||
|
}
|
||||||
|
if (State == AIState.Escape && targetingTag == "stronger")
|
||||||
|
{
|
||||||
|
// Frightened
|
||||||
|
valueModifier = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (targetCharacter.Submarine != Character.Submarine)
|
||||||
|
{
|
||||||
|
// In a different sub or the target is outside when we are inside or vice versa -> Ignore the target
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (targetCharacter.CurrentHull != Character.CurrentHull)
|
||||||
|
{
|
||||||
|
// In the same sub, halve the priority, if not in the same hull.
|
||||||
|
valueModifier = 0.5f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (targetCharacter.Submarine != null && Character.Submarine == null)
|
||||||
{
|
{
|
||||||
//target inside, AI outside -> we'll be attacking a wall between the characters so use the priority for attacking rooms
|
//target inside, AI outside -> we'll be attacking a wall between the characters so use the priority for attacking rooms
|
||||||
targetingTag = "room";
|
targetingTag = "room";
|
||||||
@@ -1169,15 +1212,15 @@ namespace Barotrauma
|
|||||||
else if (target.Entity is Structure s)
|
else if (target.Entity is Structure s)
|
||||||
{
|
{
|
||||||
targetingTag = "wall";
|
targetingTag = "wall";
|
||||||
|
if (!s.HasBody)
|
||||||
|
{
|
||||||
|
// Ignore structures that doesn't have a body (not walls)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Ignore walls when inside.
|
||||||
|
valueModifier = character.CurrentHull == null ? 1 : 0;
|
||||||
if (aggressiveBoarding)
|
if (aggressiveBoarding)
|
||||||
{
|
{
|
||||||
// Ignore walls when inside.
|
|
||||||
valueModifier = character.CurrentHull == null ? 2 : 0;
|
|
||||||
if (valueModifier > 0)
|
|
||||||
{
|
|
||||||
// Ignore structures that doesn't have a body (not walls)
|
|
||||||
valueModifier *= s.HasBody ? 1 : 0;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < s.Sections.Length; i++)
|
for (int i = 0; i < s.Sections.Length; i++)
|
||||||
{
|
{
|
||||||
var section = s.Sections[i];
|
var section = s.Sections[i];
|
||||||
@@ -1194,6 +1237,23 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Ignore disabled walls
|
||||||
|
bool isDisabled = true;
|
||||||
|
for (int i = 0; i < s.Sections.Length; i++)
|
||||||
|
{
|
||||||
|
if (!s.SectionBodyDisabled(i))
|
||||||
|
{
|
||||||
|
isDisabled = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isDisabled)
|
||||||
|
{
|
||||||
|
valueModifier = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1216,65 +1276,11 @@ namespace Barotrauma
|
|||||||
valueModifier = isOutdoor ? 1 : 0;
|
valueModifier = isOutdoor ? 1 : 0;
|
||||||
valueModifier *= isOpen ? 5 : 1;
|
valueModifier *= isOpen ? 5 : 1;
|
||||||
}
|
}
|
||||||
}
|
for (int i = 0; i < s.Sections.Length; i++)
|
||||||
}
|
|
||||||
else if (targetCharacter.Submarine != null && Character.Submarine == null)
|
|
||||||
{
|
|
||||||
//target inside, AI outside -> we'll be attacking a wall between the characters so use the priority for attacking rooms
|
|
||||||
targetingTag = "room";
|
|
||||||
}
|
|
||||||
else if (targetingPriorities.ContainsKey(targetCharacter.SpeciesName.ToLowerInvariant()))
|
|
||||||
{
|
|
||||||
targetingTag = targetCharacter.SpeciesName.ToLowerInvariant();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (target.Entity != null)
|
|
||||||
{
|
|
||||||
//skip the target if it's a room and the character is already inside a sub
|
|
||||||
if (character.CurrentHull != null && target.Entity is Hull) continue;
|
|
||||||
|
|
||||||
Door door = null;
|
|
||||||
if (target.Entity is Item item)
|
|
||||||
{
|
|
||||||
targetingTag = "dead";
|
|
||||||
if (targetCharacter.Submarine != Character.Submarine)
|
|
||||||
{
|
|
||||||
// In a different sub or the target is outside when we are inside or vice versa -> Ignore the target
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (targetCharacter.CurrentHull != Character.CurrentHull)
|
|
||||||
{
|
|
||||||
// In the same sub, halve the priority, if not in the same hull.
|
|
||||||
valueModifier = 0.5f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (targetCharacter.AIController is EnemyAIController enemy)
|
|
||||||
{
|
|
||||||
if (enemy.combatStrength > combatStrength)
|
|
||||||
{
|
|
||||||
targetingTag = "stronger";
|
|
||||||
}
|
|
||||||
else if (enemy.combatStrength < combatStrength)
|
|
||||||
{
|
|
||||||
targetingTag = "weaker";
|
|
||||||
}
|
|
||||||
if (State == AIState.Escape && targetingTag == "stronger")
|
|
||||||
{
|
|
||||||
// Frightened
|
|
||||||
valueModifier = 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (targetCharacter.Submarine != Character.Submarine)
|
|
||||||
{
|
{
|
||||||
valueModifier = isOutdoor ? 0 : 1;
|
valueModifier = isOutdoor ? 0 : 1;
|
||||||
valueModifier *= isOpen ? 0 : 1;
|
valueModifier *= isOpen ? 0 : 1;
|
||||||
}
|
}
|
||||||
else if (targetCharacter.CurrentHull != Character.CurrentHull)
|
|
||||||
{
|
|
||||||
// In the same sub, halve the priority, if not in the same hull.
|
|
||||||
valueModifier = 0.5f;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (isOpen) //ignore broken and open doors
|
else if (isOpen) //ignore broken and open doors
|
||||||
{
|
{
|
||||||
@@ -1297,6 +1303,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
valueModifier *= targetingPriorities[targetingTag].Priority;
|
valueModifier *= targetingPriorities[targetingTag].Priority;
|
||||||
|
|
||||||
|
if (targetingTag == null) continue;
|
||||||
|
if (!targetingPriorities.ContainsKey(targetingTag)) continue;
|
||||||
|
|
||||||
|
valueModifier *= targetingPriorities[targetingTag].Priority;
|
||||||
|
|
||||||
if (valueModifier == 0.0f) continue;
|
if (valueModifier == 0.0f) continue;
|
||||||
|
|
||||||
Vector2 toTarget = target.WorldPosition - character.WorldPosition;
|
Vector2 toTarget = target.WorldPosition - character.WorldPosition;
|
||||||
|
|||||||
@@ -538,6 +538,7 @@ namespace Barotrauma.Items.Components
|
|||||||
GameAnalyticsManager.AddErrorEventOnce("ItemComponent.DegreeOfSuccess:CharacterNull", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
GameAnalyticsManager.AddErrorEventOnce("ItemComponent.DegreeOfSuccess:CharacterNull", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
float average = skillSuccessSum / requiredSkills.Count;
|
||||||
|
|
||||||
float skillSuccessSum = 0.0f;
|
float skillSuccessSum = 0.0f;
|
||||||
for (int i = 0; i < requiredSkills.Count; i++)
|
for (int i = 0; i < requiredSkills.Count; i++)
|
||||||
@@ -734,13 +735,15 @@ namespace Barotrauma.Items.Components
|
|||||||
private void OverrideRequiredItems(XElement element)
|
private void OverrideRequiredItems(XElement element)
|
||||||
{
|
{
|
||||||
var prevRequiredItems = new Dictionary<RelatedItem.RelationType, List<RelatedItem>>(requiredItems);
|
var prevRequiredItems = new Dictionary<RelatedItem.RelationType, List<RelatedItem>>(requiredItems);
|
||||||
requiredItems.Clear();
|
bool overrideRequiredItems = false;
|
||||||
|
|
||||||
foreach (XElement subElement in element.Elements())
|
foreach (XElement subElement in element.Elements())
|
||||||
{
|
{
|
||||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||||
{
|
{
|
||||||
case "requireditem":
|
case "requireditem":
|
||||||
|
if (!overrideRequiredItems) requiredItems.Clear();
|
||||||
|
overrideRequiredItems = true;
|
||||||
|
|
||||||
RelatedItem newRequiredItem = RelatedItem.Load(subElement, item.Name);
|
RelatedItem newRequiredItem = RelatedItem.Load(subElement, item.Name);
|
||||||
if (newRequiredItem == null) continue;
|
if (newRequiredItem == null) continue;
|
||||||
|
|
||||||
|
|||||||
@@ -818,6 +818,39 @@ namespace Barotrauma
|
|||||||
|
|
||||||
AllowedLinks = element.GetAttributeStringArray("allowedlinks", new string[0], convertToLowerInvariant: true).ToList();
|
AllowedLinks = element.GetAttributeStringArray("allowedlinks", new string[0], convertToLowerInvariant: true).ToList();
|
||||||
|
|
||||||
|
if (sprite == null)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Item \"" + Name + "\" has no sprite!");
|
||||||
|
#if SERVER
|
||||||
|
sprite = new Sprite("", Vector2.Zero);
|
||||||
|
sprite.SourceRect = new Rectangle(0, 0, 32, 32);
|
||||||
|
#else
|
||||||
|
sprite = new Sprite(TextureLoader.PlaceHolderTexture, null, null)
|
||||||
|
{
|
||||||
|
Origin = TextureLoader.PlaceHolderTexture.Bounds.Size.ToVector2() / 2
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
size = sprite.size;
|
||||||
|
sprite.EntityID = identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!category.HasFlag(MapEntityCategory.Legacy) && string.IsNullOrEmpty(identifier))
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError(
|
||||||
|
"Item prefab \"" + name + "\" has no identifier. All item prefabs have a unique identifier string that's used to differentiate between items during saving and loading.");
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrEmpty(identifier))
|
||||||
|
{
|
||||||
|
MapEntityPrefab existingPrefab = List.Find(e => e.Identifier == identifier);
|
||||||
|
if (existingPrefab != null)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError(
|
||||||
|
"Map entity prefabs \"" + name + "\" and \"" + existingPrefab.Name + "\" have the same identifier!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AllowedLinks = element.GetAttributeStringArray("allowedlinks", new string[0], convertToLowerInvariant: true).ToList();
|
||||||
|
|
||||||
List.Add(this);
|
List.Add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user