(63916eda9) Unstable v0.9.1001.0
This commit is contained in:
@@ -19,11 +19,14 @@ namespace Barotrauma
|
|||||||
var target = _selectedAiTarget ?? _lastAiTarget;
|
var target = _selectedAiTarget ?? _lastAiTarget;
|
||||||
if (target != null && target.Entity != null)
|
if (target != null && target.Entity != null)
|
||||||
{
|
{
|
||||||
var memory = GetTargetMemory(target);
|
var memory = GetTargetMemory(target, false);
|
||||||
Vector2 targetPos = memory.Location;
|
if (memory != null)
|
||||||
targetPos.Y = -targetPos.Y;
|
{
|
||||||
GUI.DrawLine(spriteBatch, pos, targetPos, Color.White * 0.5f, 0, 4);
|
Vector2 targetPos = memory.Location;
|
||||||
GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 60.0f, $"{target.Entity.ToString()} ({memory.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
|
targetPos.Y = -targetPos.Y;
|
||||||
|
GUI.DrawLine(spriteBatch, pos, targetPos, Color.White * 0.5f, 0, 4);
|
||||||
|
GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 60.0f, $"{target.Entity} ({memory.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (SelectedAiTarget?.Entity != null)
|
else if (SelectedAiTarget?.Entity != null)
|
||||||
@@ -43,7 +46,7 @@ namespace Barotrauma
|
|||||||
GUI.DrawRectangle(spriteBatch, wallTargetPos - new Vector2(10.0f, 10.0f), new Vector2(20.0f, 20.0f), Color.Orange, false);
|
GUI.DrawRectangle(spriteBatch, wallTargetPos - new Vector2(10.0f, 10.0f), new Vector2(20.0f, 20.0f), Color.Orange, false);
|
||||||
GUI.DrawLine(spriteBatch, pos, wallTargetPos, Color.Orange * 0.5f, 0, 5);
|
GUI.DrawLine(spriteBatch, pos, wallTargetPos, Color.Orange * 0.5f, 0, 5);
|
||||||
}
|
}
|
||||||
GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 60.0f, $"{SelectedAiTarget.Entity.ToString()} ({GetTargetMemory(SelectedAiTarget).Priority.FormatZeroDecimal()})", GUI.Style.Red, Color.Black);
|
GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 60.0f, $"{SelectedAiTarget.Entity} ({GetTargetMemory(SelectedAiTarget, false)?.Priority.FormatZeroDecimal()})", GUI.Style.Red, Color.Black);
|
||||||
GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 40.0f, $"({targetValue.FormatZeroDecimal()})", GUI.Style.Red, Color.Black);
|
GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 40.0f, $"({targetValue.FormatZeroDecimal()})", GUI.Style.Red, Color.Black);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -568,6 +568,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
LightSource.LightSprite.Depth = ActiveSprite.Depth;
|
LightSource.LightSprite.Depth = ActiveSprite.Depth;
|
||||||
}
|
}
|
||||||
|
if (LightSource.DeformableLightSprite != null)
|
||||||
|
{
|
||||||
|
LightSource.DeformableLightSprite.Sprite.Depth = ActiveSprite.Depth;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateSpriteStates(deltaTime);
|
UpdateSpriteStates(deltaTime);
|
||||||
@@ -625,7 +629,11 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
var deformation = SpriteDeformation.GetDeformation(Deformations, deformSprite.Size);
|
var deformation = SpriteDeformation.GetDeformation(Deformations, deformSprite.Size);
|
||||||
deformSprite.Deform(deformation);
|
deformSprite.Deform(deformation);
|
||||||
LightSource?.DeformableLightSprite?.Deform(deformation);
|
if (LightSource != null && LightSource.DeformableLightSprite != null)
|
||||||
|
{
|
||||||
|
deformation = SpriteDeformation.GetDeformation(Deformations, deformSprite.Size, dir == Direction.Left);
|
||||||
|
LightSource.DeformableLightSprite.Deform(deformation);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -438,11 +438,8 @@ namespace Barotrauma.Items.Components
|
|||||||
if (Voltage < MinVoltage) { return; }
|
if (Voltage < MinVoltage) { return; }
|
||||||
|
|
||||||
Rectangle velRect = new Rectangle(x + 20, y + 20, width - 40, height - 40);
|
Rectangle velRect = new Rectangle(x + 20, y + 20, width - 40, height - 40);
|
||||||
Vector2 displaySubPos = (-sonar.DisplayOffset * sonar.Zoom) / sonar.Range * sonar.DisplayRadius * sonar.Zoom;
|
Vector2 steeringOrigin = steerArea.Rect.Center.ToVector2();
|
||||||
displaySubPos.Y = -displaySubPos.Y;
|
|
||||||
displaySubPos = displaySubPos.ClampLength(velRect.Width / 2);
|
|
||||||
displaySubPos = steerArea.Rect.Center.ToVector2() + displaySubPos;
|
|
||||||
|
|
||||||
if (!AutoPilot)
|
if (!AutoPilot)
|
||||||
{
|
{
|
||||||
Vector2 unitSteeringInput = steeringInput / 100.0f;
|
Vector2 unitSteeringInput = steeringInput / 100.0f;
|
||||||
@@ -450,18 +447,18 @@ namespace Barotrauma.Items.Components
|
|||||||
Vector2 steeringInputPos = new Vector2(
|
Vector2 steeringInputPos = new Vector2(
|
||||||
steeringInput.X * (float)Math.Sqrt(1.0f - 0.5f * unitSteeringInput.Y * unitSteeringInput.Y),
|
steeringInput.X * (float)Math.Sqrt(1.0f - 0.5f * unitSteeringInput.Y * unitSteeringInput.Y),
|
||||||
-steeringInput.Y * (float)Math.Sqrt(1.0f - 0.5f * unitSteeringInput.X * unitSteeringInput.X));
|
-steeringInput.Y * (float)Math.Sqrt(1.0f - 0.5f * unitSteeringInput.X * unitSteeringInput.X));
|
||||||
steeringInputPos += displaySubPos;
|
steeringInputPos += steeringOrigin;
|
||||||
|
|
||||||
if (steeringIndicator != null)
|
if (steeringIndicator != null)
|
||||||
{
|
{
|
||||||
Vector2 dir = steeringInputPos - displaySubPos;
|
Vector2 dir = steeringInputPos - steeringOrigin;
|
||||||
float angle = (float)Math.Atan2(dir.Y, dir.X);
|
float angle = (float)Math.Atan2(dir.Y, dir.X);
|
||||||
steeringIndicator.Draw(spriteBatch, displaySubPos, Color.White, origin: steeringIndicator.Origin, rotate: angle,
|
steeringIndicator.Draw(spriteBatch, steeringOrigin, Color.White, origin: steeringIndicator.Origin, rotate: angle,
|
||||||
scale: new Vector2(dir.Length() / steeringIndicator.size.X, 1.0f));
|
scale: new Vector2(dir.Length() / steeringIndicator.size.X, 1.0f));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GUI.DrawLine(spriteBatch, displaySubPos, steeringInputPos, Color.LightGray);
|
GUI.DrawLine(spriteBatch, steeringOrigin, steeringInputPos, Color.LightGray);
|
||||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)steeringInputPos.X - 5, (int)steeringInputPos.Y - 5, 10, 10), Color.White);
|
GUI.DrawRectangle(spriteBatch, new Rectangle((int)steeringInputPos.X - 5, (int)steeringInputPos.Y - 5, 10, 10), Color.White);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -475,7 +472,7 @@ namespace Barotrauma.Items.Components
|
|||||||
Sonar sonar = item.GetComponent<Sonar>();
|
Sonar sonar = item.GetComponent<Sonar>();
|
||||||
if (sonar != null && controlledSub != null)
|
if (sonar != null && controlledSub != null)
|
||||||
{
|
{
|
||||||
Vector2 displayPosToMaintain = ((posToMaintain.Value - sonar.DisplayOffset * sonar.Zoom - controlledSub.WorldPosition)) / sonar.Range * sonar.DisplayRadius * sonar.Zoom;
|
Vector2 displayPosToMaintain = ((posToMaintain.Value - controlledSub.WorldPosition)) / sonar.Range * sonar.DisplayRadius * sonar.Zoom;
|
||||||
displayPosToMaintain.Y = -displayPosToMaintain.Y;
|
displayPosToMaintain.Y = -displayPosToMaintain.Y;
|
||||||
displayPosToMaintain = displayPosToMaintain.ClampLength(velRect.Width / 2);
|
displayPosToMaintain = displayPosToMaintain.ClampLength(velRect.Width / 2);
|
||||||
displayPosToMaintain = steerArea.Rect.Center.ToVector2() + displayPosToMaintain;
|
displayPosToMaintain = steerArea.Rect.Center.ToVector2() + displayPosToMaintain;
|
||||||
@@ -494,11 +491,11 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
if (maintainPosOriginIndicator != null)
|
if (maintainPosOriginIndicator != null)
|
||||||
{
|
{
|
||||||
maintainPosOriginIndicator.Draw(spriteBatch, displaySubPos, GUI.Style.Orange, scale: 0.5f * sonar.Zoom);
|
maintainPosOriginIndicator.Draw(spriteBatch, steeringOrigin, GUI.Style.Orange, scale: 0.5f * sonar.Zoom);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)displaySubPos.X - 5, (int)displaySubPos.Y - 5, 10, 10), GUI.Style.Orange);
|
GUI.DrawRectangle(spriteBatch, new Rectangle((int)steeringOrigin.X - 5, (int)steeringOrigin.Y - 5, 10, 10), GUI.Style.Orange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -508,20 +505,19 @@ namespace Barotrauma.Items.Components
|
|||||||
Vector2 steeringPos = new Vector2(
|
Vector2 steeringPos = new Vector2(
|
||||||
targetVelocity.X * 0.9f * (float)Math.Sqrt(1.0f - 0.5f * unitTargetVel.Y * unitTargetVel.Y),
|
targetVelocity.X * 0.9f * (float)Math.Sqrt(1.0f - 0.5f * unitTargetVel.Y * unitTargetVel.Y),
|
||||||
-targetVelocity.Y * 0.9f * (float)Math.Sqrt(1.0f - 0.5f * unitTargetVel.X * unitTargetVel.X));
|
-targetVelocity.Y * 0.9f * (float)Math.Sqrt(1.0f - 0.5f * unitTargetVel.X * unitTargetVel.X));
|
||||||
steeringPos += displaySubPos;
|
steeringPos += steeringOrigin;
|
||||||
|
|
||||||
|
|
||||||
if (steeringIndicator != null)
|
if (steeringIndicator != null)
|
||||||
{
|
{
|
||||||
Vector2 dir = steeringPos - displaySubPos;
|
Vector2 dir = steeringPos - steeringOrigin;
|
||||||
float angle = (float)Math.Atan2(dir.Y, dir.X);
|
float angle = (float)Math.Atan2(dir.Y, dir.X);
|
||||||
steeringIndicator.Draw(spriteBatch, displaySubPos, Color.Gray, origin: steeringIndicator.Origin, rotate: angle,
|
steeringIndicator.Draw(spriteBatch, steeringOrigin, Color.Gray, origin: steeringIndicator.Origin, rotate: angle,
|
||||||
scale: new Vector2(dir.Length() / steeringIndicator.size.X, 0.7f));
|
scale: new Vector2(dir.Length() / steeringIndicator.size.X, 0.7f));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GUI.DrawLine(spriteBatch,
|
GUI.DrawLine(spriteBatch,
|
||||||
displaySubPos,
|
steeringOrigin,
|
||||||
steeringPos,
|
steeringPos,
|
||||||
Color.CadetBlue, 0, 2);
|
Color.CadetBlue, 0, 2);
|
||||||
}
|
}
|
||||||
@@ -669,11 +665,7 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
if (PlayerInput.PrimaryMouseButtonHeld() && !CrewManager.IsCommandInterfaceOpen && !GameSession.IsTabMenuOpen)
|
if (PlayerInput.PrimaryMouseButtonHeld() && !CrewManager.IsCommandInterfaceOpen && !GameSession.IsTabMenuOpen)
|
||||||
{
|
{
|
||||||
Vector2 displaySubPos = (-sonar.DisplayOffset * sonar.Zoom) / sonar.Range * sonar.DisplayRadius * sonar.Zoom;
|
Vector2 inputPos = PlayerInput.MousePosition - steerArea.Rect.Center.ToVector2();
|
||||||
displaySubPos.Y = -displaySubPos.Y;
|
|
||||||
displaySubPos = steerArea.Rect.Center.ToVector2() + displaySubPos;
|
|
||||||
|
|
||||||
Vector2 inputPos = PlayerInput.MousePosition - displaySubPos;
|
|
||||||
inputPos.Y = -inputPos.Y;
|
inputPos.Y = -inputPos.Y;
|
||||||
if (AutoPilot && !LevelStartSelected && !LevelEndSelected)
|
if (AutoPilot && !LevelStartSelected && !LevelEndSelected)
|
||||||
{
|
{
|
||||||
@@ -848,7 +840,6 @@ namespace Barotrauma.Items.Components
|
|||||||
Vector2 newSteeringInput = steeringInput;
|
Vector2 newSteeringInput = steeringInput;
|
||||||
Vector2 newTargetVelocity = targetVelocity;
|
Vector2 newTargetVelocity = targetVelocity;
|
||||||
float newSteeringAdjustSpeed = steeringAdjustSpeed;
|
float newSteeringAdjustSpeed = steeringAdjustSpeed;
|
||||||
bool maintainPos = false;
|
|
||||||
Vector2? newPosToMaintain = null;
|
Vector2? newPosToMaintain = null;
|
||||||
bool headingToStart = false;
|
bool headingToStart = false;
|
||||||
|
|
||||||
@@ -859,8 +850,7 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
if (autoPilot)
|
if (autoPilot)
|
||||||
{
|
{
|
||||||
maintainPos = msg.ReadBoolean();
|
if (msg.ReadBoolean())
|
||||||
if (maintainPos)
|
|
||||||
{
|
{
|
||||||
newPosToMaintain = new Vector2(
|
newPosToMaintain = new Vector2(
|
||||||
msg.ReadSingle(),
|
msg.ReadSingle(),
|
||||||
|
|||||||
@@ -138,7 +138,15 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
partial void UpdateProjSpecific(float deltaTime)
|
partial void UpdateProjSpecific(float deltaTime)
|
||||||
{
|
{
|
||||||
FakeBrokenTimer -= deltaTime;
|
if (Character.Controlled == null || (Character.Controlled.CharacterHealth.GetAffliction("psychosis")?.Strength ?? 0.0f) <= 0.0f)
|
||||||
|
{
|
||||||
|
FakeBrokenTimer = 0.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FakeBrokenTimer -= deltaTime;
|
||||||
|
}
|
||||||
|
|
||||||
item.FakeBroken = FakeBrokenTimer > 0.0f;
|
item.FakeBroken = FakeBrokenTimer > 0.0f;
|
||||||
|
|
||||||
if (!GameMain.IsMultiplayer)
|
if (!GameMain.IsMultiplayer)
|
||||||
|
|||||||
@@ -147,9 +147,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
for (int i = 0; i < Prefab.BrokenSprites.Count;i++)
|
for (int i = 0; i < Prefab.BrokenSprites.Count;i++)
|
||||||
{
|
{
|
||||||
|
if (Prefab.BrokenSprites[i].FadeIn) { continue; }
|
||||||
float minCondition = i > 0 ? Prefab.BrokenSprites[i - i].MaxCondition : 0.0f;
|
float minCondition = i > 0 ? Prefab.BrokenSprites[i - i].MaxCondition : 0.0f;
|
||||||
if (condition <= minCondition ||
|
if (condition <= minCondition || condition <= Prefab.BrokenSprites[i].MaxCondition)
|
||||||
condition <= Prefab.BrokenSprites[i].MaxCondition && !Prefab.BrokenSprites[i].FadeIn)
|
|
||||||
{
|
{
|
||||||
activeSprite = Prefab.BrokenSprites[i].Sprite;
|
activeSprite = Prefab.BrokenSprites[i].Sprite;
|
||||||
break;
|
break;
|
||||||
@@ -232,6 +232,7 @@ namespace Barotrauma
|
|||||||
BrokenItemSprite fadeInBrokenSprite = null;
|
BrokenItemSprite fadeInBrokenSprite = null;
|
||||||
float fadeInBrokenSpriteAlpha = 0.0f;
|
float fadeInBrokenSpriteAlpha = 0.0f;
|
||||||
float displayCondition = FakeBroken ? 0.0f : condition;
|
float displayCondition = FakeBroken ? 0.0f : condition;
|
||||||
|
Vector2 drawOffset = Vector2.Zero;
|
||||||
if (displayCondition < Prefab.Health)
|
if (displayCondition < Prefab.Health)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < Prefab.BrokenSprites.Count; i++)
|
for (int i = 0; i < Prefab.BrokenSprites.Count; i++)
|
||||||
@@ -241,7 +242,7 @@ namespace Barotrauma
|
|||||||
float min = i > 0 ? Prefab.BrokenSprites[i - i].MaxCondition : 0.0f;
|
float min = i > 0 ? Prefab.BrokenSprites[i - i].MaxCondition : 0.0f;
|
||||||
float max = Prefab.BrokenSprites[i].MaxCondition;
|
float max = Prefab.BrokenSprites[i].MaxCondition;
|
||||||
fadeInBrokenSpriteAlpha = 1.0f - ((displayCondition - min) / (max - min));
|
fadeInBrokenSpriteAlpha = 1.0f - ((displayCondition - min) / (max - min));
|
||||||
if (fadeInBrokenSpriteAlpha > 0.0f && fadeInBrokenSpriteAlpha < 1.0f)
|
if (fadeInBrokenSpriteAlpha > 0.0f && fadeInBrokenSpriteAlpha <= 1.0f)
|
||||||
{
|
{
|
||||||
fadeInBrokenSprite = Prefab.BrokenSprites[i];
|
fadeInBrokenSprite = Prefab.BrokenSprites[i];
|
||||||
}
|
}
|
||||||
@@ -250,6 +251,7 @@ namespace Barotrauma
|
|||||||
if (displayCondition <= Prefab.BrokenSprites[i].MaxCondition)
|
if (displayCondition <= Prefab.BrokenSprites[i].MaxCondition)
|
||||||
{
|
{
|
||||||
activeSprite = Prefab.BrokenSprites[i].Sprite;
|
activeSprite = Prefab.BrokenSprites[i].Sprite;
|
||||||
|
drawOffset = Prefab.BrokenSprites[i].Offset.ToVector2() * Scale;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -271,9 +273,13 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (prefab.ResizeHorizontal || prefab.ResizeVertical)
|
if (prefab.ResizeHorizontal || prefab.ResizeVertical)
|
||||||
{
|
{
|
||||||
activeSprite.DrawTiled(spriteBatch, new Vector2(DrawPosition.X - rect.Width / 2, -(DrawPosition.Y + rect.Height / 2)), new Vector2(rect.Width, rect.Height), color: color,
|
Vector2 size = new Vector2(rect.Width, rect.Height);
|
||||||
|
activeSprite.DrawTiled(spriteBatch, new Vector2(DrawPosition.X - rect.Width / 2, -(DrawPosition.Y + rect.Height / 2)) + drawOffset,
|
||||||
|
size, color: color,
|
||||||
|
textureScale: Vector2.One * Scale,
|
||||||
depth: depth);
|
depth: depth);
|
||||||
fadeInBrokenSprite?.Sprite.DrawTiled(spriteBatch, new Vector2(DrawPosition.X - rect.Width / 2, -(DrawPosition.Y + rect.Height / 2)), new Vector2(rect.Width, rect.Height), color: color * fadeInBrokenSpriteAlpha,
|
fadeInBrokenSprite?.Sprite.DrawTiled(spriteBatch, new Vector2(DrawPosition.X - rect.Width / 2, -(DrawPosition.Y + rect.Height / 2)) + fadeInBrokenSprite.Offset.ToVector2() * Scale, size, color: color * fadeInBrokenSpriteAlpha,
|
||||||
|
textureScale: Vector2.One * Scale,
|
||||||
depth: depth - 0.000001f);
|
depth: depth - 0.000001f);
|
||||||
foreach (var decorativeSprite in Prefab.DecorativeSprites)
|
foreach (var decorativeSprite in Prefab.DecorativeSprites)
|
||||||
{
|
{
|
||||||
@@ -287,8 +293,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
activeSprite.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y), color, SpriteRotation, Scale, activeSprite.effects, depth);
|
activeSprite.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y) + drawOffset, color, SpriteRotation, Scale, activeSprite.effects, depth);
|
||||||
fadeInBrokenSprite?.Sprite.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y), color * fadeInBrokenSpriteAlpha, SpriteRotation, Scale, activeSprite.effects, depth - 0.000001f);
|
fadeInBrokenSprite?.Sprite.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y) + fadeInBrokenSprite.Offset.ToVector2() * Scale, color * fadeInBrokenSpriteAlpha, SpriteRotation, Scale, activeSprite.effects, depth - 0.000001f);
|
||||||
foreach (var decorativeSprite in Prefab.DecorativeSprites)
|
foreach (var decorativeSprite in Prefab.DecorativeSprites)
|
||||||
{
|
{
|
||||||
if (!spriteAnimState[decorativeSprite].IsActive) { continue; }
|
if (!spriteAnimState[decorativeSprite].IsActive) { continue; }
|
||||||
@@ -1270,6 +1276,14 @@ namespace Barotrauma
|
|||||||
inventory = container.Inventory;
|
inventory = container.Inventory;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (inventoryOwner == null)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError($"Failed to spawn item \"{(itemIdentifier ?? "null")}\" in the inventory of an entity with the ID {inventoryId} (entity not found)");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError($"Failed to spawn item \"{(itemIdentifier ?? "null")}\" in the inventory of \"{inventoryOwner} ({inventoryOwner.ID})\" (invalid entity, should be an item or a character)");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var item = new Item(itemPrefab, pos, sub)
|
var item = new Item(itemPrefab, pos, sub)
|
||||||
|
|||||||
@@ -14,12 +14,14 @@ namespace Barotrauma
|
|||||||
public readonly float MaxCondition;
|
public readonly float MaxCondition;
|
||||||
public readonly Sprite Sprite;
|
public readonly Sprite Sprite;
|
||||||
public readonly bool FadeIn;
|
public readonly bool FadeIn;
|
||||||
|
public readonly Point Offset;
|
||||||
|
|
||||||
public BrokenItemSprite(Sprite sprite, float maxCondition, bool fadeIn)
|
public BrokenItemSprite(Sprite sprite, float maxCondition, bool fadeIn, Point offset)
|
||||||
{
|
{
|
||||||
Sprite = sprite;
|
Sprite = sprite;
|
||||||
MaxCondition = MathHelper.Clamp(maxCondition, 0.0f, 100.0f);
|
MaxCondition = MathHelper.Clamp(maxCondition, 0.0f, 100.0f);
|
||||||
FadeIn = fadeIn;
|
FadeIn = fadeIn;
|
||||||
|
Offset = offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ namespace Barotrauma
|
|||||||
Stream = sound.Stream;
|
Stream = sound.Stream;
|
||||||
Range = element.GetAttributeFloat("range", 1000.0f);
|
Range = element.GetAttributeFloat("range", 1000.0f);
|
||||||
Volume = element.GetAttributeFloat("volume", 1.0f);
|
Volume = element.GetAttributeFloat("volume", 1.0f);
|
||||||
|
sound.DisableMuffle = element.GetAttributeBool("disablemuffle", false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1574,7 +1574,10 @@ namespace Barotrauma.Steam
|
|||||||
{
|
{
|
||||||
exists |= File.Exists(contentFilePath + ".dll");
|
exists |= File.Exists(contentFilePath + ".dll");
|
||||||
}
|
}
|
||||||
return contentFilePath;
|
if (exists)
|
||||||
|
{
|
||||||
|
return contentFilePath;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string[] splitPath = contentFilePath.Split('/');
|
string[] splitPath = contentFilePath.Split('/');
|
||||||
|
|||||||
@@ -120,13 +120,13 @@ namespace Barotrauma.Particles
|
|||||||
return CreateParticle(prefabName, position, new Vector2((float)Math.Cos(angle), (float)-Math.Sin(angle)) * speed, angle, hullGuess);
|
return CreateParticle(prefabName, position, new Vector2((float)Math.Cos(angle), (float)-Math.Sin(angle)) * speed, angle, hullGuess);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Particle CreateParticle(string prefabName, Vector2 position, Vector2 velocity, float rotation=0.0f, Hull hullGuess = null)
|
public Particle CreateParticle(string prefabName, Vector2 position, Vector2 velocity, float rotation = 0.0f, Hull hullGuess = null)
|
||||||
{
|
{
|
||||||
ParticlePrefab prefab = FindPrefab(prefabName);
|
ParticlePrefab prefab = FindPrefab(prefabName);
|
||||||
|
|
||||||
if (prefab == null)
|
if (prefab == null)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Particle prefab \"" + prefabName+"\" not found!");
|
DebugConsole.ThrowError("Particle prefab \"" + prefabName + "\" not found!");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,7 +135,7 @@ namespace Barotrauma.Particles
|
|||||||
|
|
||||||
public Particle CreateParticle(ParticlePrefab prefab, Vector2 position, Vector2 velocity, float rotation = 0.0f, Hull hullGuess = null, bool drawOnTop = false)
|
public Particle CreateParticle(ParticlePrefab prefab, Vector2 position, Vector2 velocity, float rotation = 0.0f, Hull hullGuess = null, bool drawOnTop = false)
|
||||||
{
|
{
|
||||||
if (particleCount >= MaxParticles || prefab == null) return null;
|
if (particleCount >= MaxParticles || prefab == null || prefab.Sprites.Count == 0) { return null; }
|
||||||
|
|
||||||
Vector2 particleEndPos = prefab.CalculateEndPosition(position, velocity);
|
Vector2 particleEndPos = prefab.CalculateEndPosition(position, velocity);
|
||||||
|
|
||||||
@@ -144,8 +144,8 @@ namespace Barotrauma.Particles
|
|||||||
|
|
||||||
Rectangle expandedViewRect = MathUtils.ExpandRect(cam.WorldView, MaxOutOfViewDist);
|
Rectangle expandedViewRect = MathUtils.ExpandRect(cam.WorldView, MaxOutOfViewDist);
|
||||||
|
|
||||||
if (minPos.X > expandedViewRect.Right || maxPos.X < expandedViewRect.X) return null;
|
if (minPos.X > expandedViewRect.Right || maxPos.X < expandedViewRect.X) { return null; }
|
||||||
if (minPos.Y > expandedViewRect.Y || maxPos.Y < expandedViewRect.Y - expandedViewRect.Height) return null;
|
if (minPos.Y > expandedViewRect.Y || maxPos.Y < expandedViewRect.Y - expandedViewRect.Height) { return null; }
|
||||||
|
|
||||||
if (particles[particleCount] == null) particles[particleCount] = new Particle();
|
if (particles[particleCount] == null) particles[particleCount] = new Particle();
|
||||||
|
|
||||||
|
|||||||
@@ -255,6 +255,11 @@ namespace Barotrauma.Particles
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Sprites.Count == 0)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError($"Particle prefab \"{Name}\" in the file \"{file}\" has no sprites defined!");
|
||||||
|
}
|
||||||
|
|
||||||
//if velocity change in water is not given, it defaults to the normal velocity change
|
//if velocity change in water is not given, it defaults to the normal velocity change
|
||||||
if (element.Attribute("velocitychangewater") == null)
|
if (element.Attribute("velocitychangewater") == null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -469,7 +469,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public static bool IsCtrlDown()
|
public static bool IsCtrlDown()
|
||||||
{
|
{
|
||||||
|
#if !OSX
|
||||||
return KeyDown(Keys.LeftControl) || KeyDown(Keys.RightControl);
|
return KeyDown(Keys.LeftControl) || KeyDown(Keys.RightControl);
|
||||||
|
#else
|
||||||
|
return KeyDown(Keys.LeftWindows) || KeyDown(Keys.RightWindows);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Update(double deltaTime)
|
public static void Update(double deltaTime)
|
||||||
|
|||||||
@@ -1245,7 +1245,8 @@ namespace Barotrauma
|
|||||||
string prevDir = Path.GetDirectoryName(Submarine.MainSub.Info.FilePath).CleanUpPath();
|
string prevDir = Path.GetDirectoryName(Submarine.MainSub.Info.FilePath).CleanUpPath();
|
||||||
string[] subDirs = prevDir.Split('/');
|
string[] subDirs = prevDir.Split('/');
|
||||||
bool forceToSubFolder = Steam.SteamManager.IsInitialized;
|
bool forceToSubFolder = Steam.SteamManager.IsInitialized;
|
||||||
if (forceToSubFolder && subDirs.Length>1 && subDirs[0].Equals("Mods", StringComparison.InvariantCultureIgnoreCase))
|
bool isInSubFolder = subDirs.Length > 0 && subDirs[0].Equals("Submarines", StringComparison.InvariantCultureIgnoreCase);
|
||||||
|
if (forceToSubFolder && subDirs.Length > 1 && subDirs[0].Equals("Mods", StringComparison.InvariantCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
string modName = subDirs[1];
|
string modName = subDirs[1];
|
||||||
ContentPackage contentPackage = ContentPackage.List.Find(p => p.Name.Equals(modName, StringComparison.InvariantCultureIgnoreCase));
|
ContentPackage contentPackage = ContentPackage.List.Find(p => p.Name.Equals(modName, StringComparison.InvariantCultureIgnoreCase));
|
||||||
@@ -1261,7 +1262,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
savePath = Path.Combine(forceToSubFolder ? SubmarineInfo.SavePath : prevDir, savePath).CleanUpPath();
|
savePath = Path.Combine(forceToSubFolder && !isInSubFolder ? SubmarineInfo.SavePath : prevDir, savePath).CleanUpPath();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -76,6 +76,8 @@ namespace Barotrauma.Sounds
|
|||||||
protected set;
|
protected set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool DisableMuffle { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// How many instances of the same sound clip can be playing at the same time
|
/// How many instances of the same sound clip can be playing at the same time
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -644,8 +644,12 @@ namespace Barotrauma
|
|||||||
|
|
||||||
float far = range ?? sound.BaseFar;
|
float far = range ?? sound.BaseFar;
|
||||||
|
|
||||||
if (Vector2.DistanceSquared(new Vector2(GameMain.SoundManager.ListenerPosition.X, GameMain.SoundManager.ListenerPosition.Y), position) > far * far) return null;
|
if (Vector2.DistanceSquared(new Vector2(GameMain.SoundManager.ListenerPosition.X, GameMain.SoundManager.ListenerPosition.Y), position) > far * far)
|
||||||
return sound.Play(volume ?? sound.BaseGain, far, position, muffle: ShouldMuffleSound(Character.Controlled, position, far, hullGuess));
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
bool muffle = !sound.DisableMuffle && ShouldMuffleSound(Character.Controlled, position, far, hullGuess);
|
||||||
|
return sound.Play(volume ?? sound.BaseGain, far, position, muffle: muffle);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void UpdateMusic(float deltaTime)
|
private static void UpdateMusic(float deltaTime)
|
||||||
|
|||||||
+2
-2
@@ -109,12 +109,12 @@ namespace Barotrauma.SpriteDeformations
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void GetDeformation(out Vector2[,] deformation, out float multiplier)
|
protected override void GetDeformation(out Vector2[,] deformation, out float multiplier, bool inverse)
|
||||||
{
|
{
|
||||||
deformation = Deformation;
|
deformation = Deformation;
|
||||||
multiplier = CustomDeformationParams.Frequency <= 0.0f ?
|
multiplier = CustomDeformationParams.Frequency <= 0.0f ?
|
||||||
CustomDeformationParams.Amplitude :
|
CustomDeformationParams.Amplitude :
|
||||||
(float)Math.Sin(phase) * CustomDeformationParams.Amplitude;
|
(float)Math.Sin(inverse ? -phase : phase) * CustomDeformationParams.Amplitude;
|
||||||
multiplier *= Params.Strength;
|
multiplier *= Params.Strength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ namespace Barotrauma.SpriteDeformations
|
|||||||
phase = Rand.Range(0.0f, MathHelper.TwoPi);
|
phase = Rand.Range(0.0f, MathHelper.TwoPi);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void GetDeformation(out Vector2[,] deformation, out float multiplier)
|
protected override void GetDeformation(out Vector2[,] deformation, out float multiplier, bool inverse)
|
||||||
{
|
{
|
||||||
deformation = this.deformation;
|
deformation = this.deformation;
|
||||||
multiplier = InflateParams.Frequency <= 0.0f ? InflateParams.Scale : (float)(Math.Sin(phase) + 1.0f) / 2.0f * InflateParams.Scale;
|
multiplier = InflateParams.Frequency <= 0.0f ? InflateParams.Scale : (float)(Math.Sin(phase) + 1.0f) / 2.0f * InflateParams.Scale;
|
||||||
|
|||||||
+1
-1
@@ -56,7 +56,7 @@ namespace Barotrauma.SpriteDeformations
|
|||||||
|
|
||||||
public JointBendDeformation(XElement element) : base(element, new JointBendDeformationParams(element)) { }
|
public JointBendDeformation(XElement element) : base(element, new JointBendDeformationParams(element)) { }
|
||||||
|
|
||||||
protected override void GetDeformation(out Vector2[,] deformation, out float multiplier)
|
protected override void GetDeformation(out Vector2[,] deformation, out float multiplier, bool inverse)
|
||||||
{
|
{
|
||||||
deformation = Deformation;
|
deformation = Deformation;
|
||||||
multiplier = 1.0f;// this.multiplier;
|
multiplier = 1.0f;// this.multiplier;
|
||||||
|
|||||||
+1
-1
@@ -47,7 +47,7 @@ namespace Barotrauma.SpriteDeformations
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void GetDeformation(out Vector2[,] deformation, out float multiplier)
|
protected override void GetDeformation(out Vector2[,] deformation, out float multiplier, bool inverse)
|
||||||
{
|
{
|
||||||
deformation = Deformation;
|
deformation = Deformation;
|
||||||
multiplier = NoiseDeformationParams.Amplitude * Params.Strength;
|
multiplier = NoiseDeformationParams.Amplitude * Params.Strength;
|
||||||
|
|||||||
+1
-1
@@ -100,7 +100,7 @@ namespace Barotrauma.SpriteDeformations
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void GetDeformation(out Vector2[,] deformation, out float multiplier)
|
protected override void GetDeformation(out Vector2[,] deformation, out float multiplier, bool inverse)
|
||||||
{
|
{
|
||||||
deformation = Deformation;
|
deformation = Deformation;
|
||||||
multiplier = 1.0f;
|
multiplier = 1.0f;
|
||||||
|
|||||||
+16
-7
@@ -195,11 +195,12 @@ namespace Barotrauma.SpriteDeformations
|
|||||||
Deformation = new Vector2[Params.Resolution.X, Params.Resolution.Y];
|
Deformation = new Vector2[Params.Resolution.X, Params.Resolution.Y];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void GetDeformation(out Vector2[,] deformation, out float multiplier);
|
protected abstract void GetDeformation(out Vector2[,] deformation, out float multiplier, bool inverse);
|
||||||
|
|
||||||
public abstract void Update(float deltaTime);
|
public abstract void Update(float deltaTime);
|
||||||
|
|
||||||
public static Vector2[,] GetDeformation(IEnumerable<SpriteDeformation> animations, Vector2 scale)
|
private static readonly List<int> yValues = new List<int>();
|
||||||
|
public static Vector2[,] GetDeformation(IEnumerable<SpriteDeformation> animations, Vector2 scale, bool inverseY = false)
|
||||||
{
|
{
|
||||||
foreach (SpriteDeformation animation in animations)
|
foreach (SpriteDeformation animation in animations)
|
||||||
{
|
{
|
||||||
@@ -221,8 +222,16 @@ namespace Barotrauma.SpriteDeformations
|
|||||||
Vector2[,] deformation = new Vector2[resolution.X, resolution.Y];
|
Vector2[,] deformation = new Vector2[resolution.X, resolution.Y];
|
||||||
foreach (SpriteDeformation animation in animations)
|
foreach (SpriteDeformation animation in animations)
|
||||||
{
|
{
|
||||||
animation.GetDeformation(out Vector2[,] animDeformation, out float multiplier);
|
yValues.Clear();
|
||||||
|
for (int y = 0; y < resolution.Y; y++)
|
||||||
|
{
|
||||||
|
yValues.Add(y);
|
||||||
|
}
|
||||||
|
if (inverseY && animation is CustomDeformation)
|
||||||
|
{
|
||||||
|
yValues.Reverse();
|
||||||
|
}
|
||||||
|
animation.GetDeformation(out Vector2[,] animDeformation, out float multiplier, inverseY);
|
||||||
for (int x = 0; x < resolution.X; x++)
|
for (int x = 0; x < resolution.X; x++)
|
||||||
{
|
{
|
||||||
for (int y = 0; y < resolution.Y; y++)
|
for (int y = 0; y < resolution.Y; y++)
|
||||||
@@ -230,13 +239,13 @@ namespace Barotrauma.SpriteDeformations
|
|||||||
switch (animation.Params.BlendMode)
|
switch (animation.Params.BlendMode)
|
||||||
{
|
{
|
||||||
case DeformationBlendMode.Override:
|
case DeformationBlendMode.Override:
|
||||||
deformation[x,y] = animDeformation[x,y] * scale * multiplier;
|
deformation[x, yValues[y]] = animDeformation[x, y] * scale * multiplier;
|
||||||
break;
|
break;
|
||||||
case DeformationBlendMode.Add:
|
case DeformationBlendMode.Add:
|
||||||
deformation[x, y] += animDeformation[x, y] * scale * multiplier;
|
deformation[x, yValues[y]] += animDeformation[x, y] * scale * multiplier;
|
||||||
break;
|
break;
|
||||||
case DeformationBlendMode.Multiply:
|
case DeformationBlendMode.Multiply:
|
||||||
deformation[x, y] *= animDeformation[x, y] * multiplier;
|
deformation[x, yValues[y]] *= animDeformation[x, y] * multiplier;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private static HashSet<StatusEffect> ActiveLoopingSounds = new HashSet<StatusEffect>();
|
private static HashSet<StatusEffect> ActiveLoopingSounds = new HashSet<StatusEffect>();
|
||||||
private static double LastMuffleCheckTime;
|
private static double LastMuffleCheckTime;
|
||||||
private List<RoundSound> sounds = new List<RoundSound>();
|
private readonly List<RoundSound> sounds = new List<RoundSound>();
|
||||||
private SoundSelectionMode soundSelectionMode;
|
private SoundSelectionMode soundSelectionMode;
|
||||||
private SoundChannel soundChannel;
|
private SoundChannel soundChannel;
|
||||||
private Entity soundEmitter;
|
private Entity soundEmitter;
|
||||||
@@ -76,7 +76,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int selectedSoundIndex = 0;
|
int selectedSoundIndex;
|
||||||
if (soundSelectionMode == SoundSelectionMode.ItemSpecific && entity is Item item)
|
if (soundSelectionMode == SoundSelectionMode.ItemSpecific && entity is Item item)
|
||||||
{
|
{
|
||||||
selectedSoundIndex = item.ID % sounds.Count;
|
selectedSoundIndex = item.ID % sounds.Count;
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DebugConsole.NewMessage($"Could not compress a texture because the dimensions are a multiple of 4 (path: {path ?? "null"}, size: {width}x{height})", Color.Orange);
|
DebugConsole.NewMessage($"Could not compress a texture because the dimensions aren't a multiple of 4 (path: {path ?? "null"}, size: {width}x{height})", Color.Orange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma</Product>
|
<Product>Barotrauma</Product>
|
||||||
<Version>0.9.1000.0</Version>
|
<Version>0.9.1001.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>Barotrauma</AssemblyName>
|
<AssemblyName>Barotrauma</AssemblyName>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma</Product>
|
<Product>Barotrauma</Product>
|
||||||
<Version>0.9.1000.0</Version>
|
<Version>0.9.1001.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>Barotrauma</AssemblyName>
|
<AssemblyName>Barotrauma</AssemblyName>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma</Product>
|
<Product>Barotrauma</Product>
|
||||||
<Version>0.9.1000.0</Version>
|
<Version>0.9.1001.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>Barotrauma</AssemblyName>
|
<AssemblyName>Barotrauma</AssemblyName>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma Dedicated Server</Product>
|
<Product>Barotrauma Dedicated Server</Product>
|
||||||
<Version>0.9.1000.0</Version>
|
<Version>0.9.1001.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>DedicatedServer</AssemblyName>
|
<AssemblyName>DedicatedServer</AssemblyName>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma Dedicated Server</Product>
|
<Product>Barotrauma Dedicated Server</Product>
|
||||||
<Version>0.9.1000.0</Version>
|
<Version>0.9.1001.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>DedicatedServer</AssemblyName>
|
<AssemblyName>DedicatedServer</AssemblyName>
|
||||||
|
|||||||
@@ -615,28 +615,45 @@ namespace Barotrauma
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ShowQuestionPrompt("Console command permissions to grant to \"" + client.Name + "\"? You may enter multiple commands separated with a space.", (commandsStr) =>
|
ShowQuestionPrompt("Console command permissions to grant to \"" + client.Name + "\"? You may enter multiple commands separated with a space, or \"all\" to allow using any console command.", (commandsStr) =>
|
||||||
{
|
{
|
||||||
string[] splitCommands = commandsStr.Split(' ');
|
string[] splitCommands = commandsStr.Split(' ');
|
||||||
|
bool giveAll = splitCommands.Length > 0 && splitCommands[0].Equals("all", StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
List<Command> grantedCommands = new List<Command>();
|
List<Command> grantedCommands = new List<Command>();
|
||||||
for (int i = 0; i < splitCommands.Length; i++)
|
if (giveAll)
|
||||||
{
|
{
|
||||||
splitCommands[i] = splitCommands[i].Trim().ToLowerInvariant();
|
grantedCommands.AddRange(commands);
|
||||||
Command matchingCommand = commands.Find(c => c.names.Contains(splitCommands[i]));
|
}
|
||||||
if (matchingCommand == null)
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < splitCommands.Length; i++)
|
||||||
{
|
{
|
||||||
ThrowError("Could not find the command \"" + splitCommands[i] + "\"!");
|
splitCommands[i] = splitCommands[i].Trim().ToLowerInvariant();
|
||||||
}
|
Command matchingCommand = commands.Find(c => c.names.Contains(splitCommands[i]));
|
||||||
else
|
if (matchingCommand == null)
|
||||||
{
|
{
|
||||||
grantedCommands.Add(matchingCommand);
|
ThrowError("Could not find the command \"" + splitCommands[i] + "\"!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
grantedCommands.Add(matchingCommand);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
client.GivePermission(ClientPermissions.ConsoleCommands);
|
client.GivePermission(ClientPermissions.ConsoleCommands);
|
||||||
client.SetPermissions(client.Permissions, client.PermittedConsoleCommands.Union(grantedCommands).Distinct().ToList());
|
client.SetPermissions(client.Permissions, client.PermittedConsoleCommands.Union(grantedCommands).Distinct().ToList());
|
||||||
GameMain.Server.UpdateClientPermissions(client);
|
GameMain.Server.UpdateClientPermissions(client);
|
||||||
NewMessage("Gave the client \"" + client.Name + "\" the permission to use console commands " + string.Join(", ", grantedCommands.Select(c => c.names[0])) + ".", Color.White);
|
if (giveAll)
|
||||||
|
{
|
||||||
|
NewMessage("Gave the client \"" + client.Name + "\" the permission to use all console commands.", Color.White);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NewMessage("Gave the client \"" + client.Name + "\" the permission to use console commands " + string.Join(", ", grantedCommands.Select(c => c.names[0])) + ".", Color.White);
|
||||||
|
}
|
||||||
|
|
||||||
}, args, 1);
|
}, args, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -101,6 +101,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (!prevItems.Contains(item) && !item.CanClientAccess(c))
|
if (!prevItems.Contains(item) && !item.CanClientAccess(c))
|
||||||
{
|
{
|
||||||
|
#if DEBUG || UNSTABLE
|
||||||
|
DebugConsole.NewMessage($"Client {c.Name} failed to pick up item \"{item}\" (parent inventory: {(item.ParentInventory?.Owner.ToString() ?? "null")}). No access.", Color.Yellow);
|
||||||
|
#endif
|
||||||
if (item.body != null && !c.PendingPositionUpdates.Contains(item))
|
if (item.body != null && !c.PendingPositionUpdates.Contains(item))
|
||||||
{
|
{
|
||||||
c.PendingPositionUpdates.Enqueue(item);
|
c.PendingPositionUpdates.Enqueue(item);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma Dedicated Server</Product>
|
<Product>Barotrauma Dedicated Server</Product>
|
||||||
<Version>0.9.1000.0</Version>
|
<Version>0.9.1001.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>DedicatedServer</AssemblyName>
|
<AssemblyName>DedicatedServer</AssemblyName>
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ namespace Barotrauma
|
|||||||
public void SelectTarget(AITarget target, float priority)
|
public void SelectTarget(AITarget target, float priority)
|
||||||
{
|
{
|
||||||
SelectedAiTarget = target;
|
SelectedAiTarget = target;
|
||||||
selectedTargetMemory = GetTargetMemory(target);
|
selectedTargetMemory = GetTargetMemory(target, true);
|
||||||
selectedTargetMemory.Priority = priority;
|
selectedTargetMemory.Priority = priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -439,7 +439,10 @@ namespace Barotrauma
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
LatchOntoAI?.Update(this, deltaTime);
|
if (!Character.AnimController.SimplePhysicsEnabled)
|
||||||
|
{
|
||||||
|
LatchOntoAI?.Update(this, deltaTime);
|
||||||
|
}
|
||||||
IsSteeringThroughGap = false;
|
IsSteeringThroughGap = false;
|
||||||
if (SwarmBehavior != null)
|
if (SwarmBehavior != null)
|
||||||
{
|
{
|
||||||
@@ -478,7 +481,7 @@ namespace Barotrauma
|
|||||||
if (target?.Entity != null && !target.Entity.Removed && PreviousState == AIState.Attack && Character.CurrentHull == null)
|
if (target?.Entity != null && !target.Entity.Removed && PreviousState == AIState.Attack && Character.CurrentHull == null)
|
||||||
{
|
{
|
||||||
// Keep heading to the last known position of the target
|
// Keep heading to the last known position of the target
|
||||||
var memory = GetTargetMemory(target);
|
var memory = GetTargetMemory(target, false);
|
||||||
if (memory != null)
|
if (memory != null)
|
||||||
{
|
{
|
||||||
var location = memory.Location;
|
var location = memory.Location;
|
||||||
@@ -908,7 +911,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
if (!Character.AnimController.SimplePhysicsEnabled && SelectedAiTarget.Entity.Submarine != null && Character.Submarine == null && (!canAttackDoors || !canAttackWalls || !AIParams.TargetOuterWalls))
|
if (!Character.AnimController.SimplePhysicsEnabled && SelectedAiTarget.Entity.Submarine != null && Character.Submarine == null && (!canAttackDoors || !canAttackWalls || !AIParams.TargetOuterWalls))
|
||||||
{
|
{
|
||||||
if (Vector2.Distance(Character.WorldPosition, attackWorldPos) < 2000 * 2000)
|
if (Vector2.DistanceSquared(Character.WorldPosition, attackWorldPos) < 2000 * 2000)
|
||||||
{
|
{
|
||||||
// Check that we are not bumping into a door or a wall
|
// Check that we are not bumping into a door or a wall
|
||||||
Vector2 rayStart = SimPosition;
|
Vector2 rayStart = SimPosition;
|
||||||
@@ -916,8 +919,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
rayStart -= SelectedAiTarget.Entity.Submarine.SimPosition;
|
rayStart -= SelectedAiTarget.Entity.Submarine.SimPosition;
|
||||||
}
|
}
|
||||||
Vector2 toTarget = SelectedAiTarget.WorldPosition - WorldPosition;
|
Vector2 dir = SelectedAiTarget.WorldPosition - WorldPosition;
|
||||||
Vector2 rayEnd = rayStart + toTarget.ClampLength(Character.AnimController.Collider.GetLocalFront().Length() * 2);
|
Vector2 rayEnd = rayStart + dir.ClampLength(Character.AnimController.Collider.GetLocalFront().Length() * 2);
|
||||||
Body closestBody = Submarine.CheckVisibility(rayStart, rayEnd, ignoreSubs: true);
|
Body closestBody = Submarine.CheckVisibility(rayStart, rayEnd, ignoreSubs: true);
|
||||||
if (Submarine.LastPickedFraction != 1.0f && closestBody != null &&
|
if (Submarine.LastPickedFraction != 1.0f && closestBody != null &&
|
||||||
(!AIParams.TargetOuterWalls || !canAttackWalls && closestBody.UserData is Structure s && s.Submarine != null || !canAttackDoors && closestBody.UserData is Item i && i.Submarine != null && i.GetComponent<Door>() != null))
|
(!AIParams.TargetOuterWalls || !canAttackWalls && closestBody.UserData is Structure s && s.Submarine != null || !canAttackDoors && closestBody.UserData is Item i && i.Submarine != null && i.GetComponent<Door>() != null))
|
||||||
@@ -933,25 +936,30 @@ namespace Barotrauma
|
|||||||
float distance = 0;
|
float distance = 0;
|
||||||
Limb attackTargetLimb = null;
|
Limb attackTargetLimb = null;
|
||||||
Character targetCharacter = SelectedAiTarget.Entity as Character;
|
Character targetCharacter = SelectedAiTarget.Entity as Character;
|
||||||
if (canAttack && !Character.AnimController.SimplePhysicsEnabled)
|
if (canAttack)
|
||||||
{
|
{
|
||||||
// Target a specific limb instead of the target center position
|
if (!Character.AnimController.SimplePhysicsEnabled)
|
||||||
if (wallTarget == null && targetCharacter != null)
|
|
||||||
{
|
{
|
||||||
var targetLimbType = AttackingLimb.Params.Attack.Attack.TargetLimbType;
|
// Target a specific limb instead of the target center position
|
||||||
attackTargetLimb = GetTargetLimb(AttackingLimb, targetCharacter, targetLimbType);
|
if (wallTarget == null && targetCharacter != null)
|
||||||
if (attackTargetLimb == null)
|
|
||||||
{
|
{
|
||||||
State = AIState.Idle;
|
var targetLimbType = AttackingLimb.Params.Attack.Attack.TargetLimbType;
|
||||||
IgnoreTarget(SelectedAiTarget);
|
attackTargetLimb = GetTargetLimb(AttackingLimb, targetCharacter, targetLimbType);
|
||||||
ResetAITarget();
|
if (attackTargetLimb == null)
|
||||||
return;
|
{
|
||||||
|
State = AIState.Idle;
|
||||||
|
IgnoreTarget(SelectedAiTarget);
|
||||||
|
ResetAITarget();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
attackWorldPos = attackTargetLimb.WorldPosition;
|
||||||
|
attackSimPos = Character.GetRelativeSimPosition(attackTargetLimb);
|
||||||
}
|
}
|
||||||
attackWorldPos = attackTargetLimb.WorldPosition;
|
|
||||||
attackSimPos = Character.GetRelativeSimPosition(attackTargetLimb);
|
|
||||||
}
|
}
|
||||||
// Check that we can reach the target
|
|
||||||
Vector2 toTarget = attackWorldPos - (Character.AnimController.SimplePhysicsEnabled ? Character.WorldPosition : AttackingLimb.WorldPosition);
|
Vector2 attackLimbPos = Character.AnimController.SimplePhysicsEnabled ? Character.WorldPosition : AttackingLimb.WorldPosition;
|
||||||
|
Vector2 toTarget = attackWorldPos - attackLimbPos;
|
||||||
|
// Add a margin when the target is moving away, because otherwise it might be difficult to reach it (the attack takes some time to perform)
|
||||||
if (wallTarget != null)
|
if (wallTarget != null)
|
||||||
{
|
{
|
||||||
if (wallTarget.Structure.Submarine != null)
|
if (wallTarget.Structure.Submarine != null)
|
||||||
@@ -962,7 +970,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else if (targetCharacter != null)
|
else if (targetCharacter != null)
|
||||||
{
|
{
|
||||||
// Add a margin when the target is moving away, because otherwise it might be difficult to reach it (the attack takes some time to perform)
|
|
||||||
Vector2 margin = CalculateMargin(targetCharacter.AnimController.Collider.LinearVelocity);
|
Vector2 margin = CalculateMargin(targetCharacter.AnimController.Collider.LinearVelocity);
|
||||||
toTarget += margin;
|
toTarget += margin;
|
||||||
}
|
}
|
||||||
@@ -982,6 +989,7 @@ namespace Barotrauma
|
|||||||
return ConvertUnits.ToDisplayUnits(targetVelocity) * AttackingLimb.attack.Duration * dot;
|
return ConvertUnits.ToDisplayUnits(targetVelocity) * AttackingLimb.attack.Duration * dot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check that we can reach the target
|
||||||
distance = toTarget.Length();
|
distance = toTarget.Length();
|
||||||
canAttack = distance < AttackingLimb.attack.Range;
|
canAttack = distance < AttackingLimb.attack.Range;
|
||||||
if (!canAttack && !IsCoolDownRunning)
|
if (!canAttack && !IsCoolDownRunning)
|
||||||
@@ -1366,7 +1374,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AITargetMemory targetMemory = GetTargetMemory(attacker.AiTarget);
|
AITargetMemory targetMemory = GetTargetMemory(attacker.AiTarget, true);
|
||||||
targetMemory.Priority += GetRelativeDamage(attackResult.Damage, Character.Vitality) * AggressionHurt;
|
targetMemory.Priority += GetRelativeDamage(attackResult.Damage, Character.Vitality) * AggressionHurt;
|
||||||
|
|
||||||
// Only allow to react once. Otherwise would attack the target with only a fraction of a cooldown
|
// Only allow to react once. Otherwise would attack the target with only a fraction of a cooldown
|
||||||
@@ -1409,7 +1417,7 @@ namespace Barotrauma
|
|||||||
var aiTarget = wallTarget.Structure.AiTarget;
|
var aiTarget = wallTarget.Structure.AiTarget;
|
||||||
if (aiTarget != null && SelectedAiTarget != aiTarget)
|
if (aiTarget != null && SelectedAiTarget != aiTarget)
|
||||||
{
|
{
|
||||||
SelectTarget(aiTarget, GetTargetMemory(SelectedAiTarget).Priority);
|
SelectTarget(aiTarget, GetTargetMemory(SelectedAiTarget, true).Priority);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IDamageable damageTarget = wallTarget != null ? wallTarget.Structure : SelectedAiTarget.Entity as IDamageable;
|
IDamageable damageTarget = wallTarget != null ? wallTarget.Structure : SelectedAiTarget.Entity as IDamageable;
|
||||||
@@ -1857,7 +1865,7 @@ namespace Barotrauma
|
|||||||
// -> just ignore the distance and attack whatever has the highest priority
|
// -> just ignore the distance and attack whatever has the highest priority
|
||||||
dist = Math.Max(dist, 100.0f);
|
dist = Math.Max(dist, 100.0f);
|
||||||
|
|
||||||
AITargetMemory targetMemory = GetTargetMemory(aiTarget);
|
AITargetMemory targetMemory = GetTargetMemory(aiTarget, true);
|
||||||
if (Character.CurrentHull != null && Math.Abs(toTarget.Y) > Character.CurrentHull.Size.Y)
|
if (Character.CurrentHull != null && Math.Abs(toTarget.Y) > Character.CurrentHull.Size.Y)
|
||||||
{
|
{
|
||||||
// Inside the sub, treat objects that are up or down, as they were farther away.
|
// Inside the sub, treat objects that are up or down, as they were farther away.
|
||||||
@@ -1938,12 +1946,15 @@ namespace Barotrauma
|
|||||||
return SelectedAiTarget;
|
return SelectedAiTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
private AITargetMemory GetTargetMemory(AITarget target)
|
private AITargetMemory GetTargetMemory(AITarget target, bool addIfNotFound)
|
||||||
{
|
{
|
||||||
if (!targetMemories.TryGetValue(target, out AITargetMemory memory))
|
if (!targetMemories.TryGetValue(target, out AITargetMemory memory))
|
||||||
{
|
{
|
||||||
memory = new AITargetMemory(target, 10);
|
if (addIfNotFound)
|
||||||
targetMemories.Add(target, memory);
|
{
|
||||||
|
memory = new AITargetMemory(target, 10);
|
||||||
|
targetMemories.Add(target, memory);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return memory;
|
return memory;
|
||||||
}
|
}
|
||||||
@@ -1958,8 +1969,11 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else if (CanPerceive(_selectedAiTarget, distSquared: Vector2.DistanceSquared(Character.WorldPosition, _selectedAiTarget.WorldPosition)))
|
else if (CanPerceive(_selectedAiTarget, distSquared: Vector2.DistanceSquared(Character.WorldPosition, _selectedAiTarget.WorldPosition)))
|
||||||
{
|
{
|
||||||
var memory = GetTargetMemory(_selectedAiTarget);
|
var memory = GetTargetMemory(_selectedAiTarget, false);
|
||||||
memory.Location = _selectedAiTarget.WorldPosition;
|
if (memory != null)
|
||||||
|
{
|
||||||
|
memory.Location = _selectedAiTarget.WorldPosition;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -42,6 +42,7 @@ namespace Barotrauma
|
|||||||
currSearchIndex = -1;
|
currSearchIndex = -1;
|
||||||
this.equip = equip;
|
this.equip = equip;
|
||||||
this.targetItem = targetItem;
|
this.targetItem = targetItem;
|
||||||
|
moveToTarget = targetItem?.GetRootInventoryOwner();
|
||||||
}
|
}
|
||||||
|
|
||||||
public AIObjectiveGetItem(Character character, string itemIdentifier, AIObjectiveManager objectiveManager, bool equip = true, bool checkInventory = true, float priorityModifier = 1)
|
public AIObjectiveGetItem(Character character, string itemIdentifier, AIObjectiveManager objectiveManager, bool equip = true, bool checkInventory = true, float priorityModifier = 1)
|
||||||
|
|||||||
+1
-1
@@ -61,7 +61,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
case "shutdown":
|
case "shutdown":
|
||||||
var powered = component?.Item.GetComponent<Powered>();
|
var powered = component?.Item.GetComponent<Powered>();
|
||||||
if (powered != null && powered.IsActive)
|
if (powered != null && !powered.IsActive)
|
||||||
{
|
{
|
||||||
Priority = 0;
|
Priority = 0;
|
||||||
return Priority;
|
return Priority;
|
||||||
|
|||||||
@@ -47,11 +47,15 @@ namespace Barotrauma
|
|||||||
base.Update(deltaTime, cam);
|
base.Update(deltaTime, cam);
|
||||||
|
|
||||||
if (!Enabled) { return; }
|
if (!Enabled) { return; }
|
||||||
if (IsDead || Vitality <= 0.0f || Stun > 0.0f || IsIncapacitated) { return; }
|
if (IsDead || Vitality <= 0.0f || Stun > 0.0f || IsIncapacitated)
|
||||||
|
{
|
||||||
|
//don't enable simple physics on dead/incapacitated characters
|
||||||
|
//the ragdoll controls the movement of incapacitated characters instead of the collider,
|
||||||
|
//but in simple physics mode the ragdoll would get disabled, causing the character to not move at all
|
||||||
|
AnimController.SimplePhysicsEnabled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//don't enable simple physics on dead/incapacitated characters
|
|
||||||
//the ragdoll controls the movement of incapacitated characters instead of the collider,
|
|
||||||
//but in simple physics mode the ragdoll would get disabled, causing the character to not move at all
|
|
||||||
if (!IsRemotePlayer && !(AIController is HumanAIController))
|
if (!IsRemotePlayer && !(AIController is HumanAIController))
|
||||||
{
|
{
|
||||||
float characterDist = float.MaxValue;
|
float characterDist = float.MaxValue;
|
||||||
|
|||||||
@@ -709,7 +709,7 @@ namespace Barotrauma
|
|||||||
float impactDamage = Math.Min((impact - ImpactTolerance) * ImpactDamageMultiplayer, character.MaxVitality * MaxImpactDamage);
|
float impactDamage = Math.Min((impact - ImpactTolerance) * ImpactDamageMultiplayer, character.MaxVitality * MaxImpactDamage);
|
||||||
|
|
||||||
character.LastDamageSource = null;
|
character.LastDamageSource = null;
|
||||||
character.AddDamage(impactPos, new List<Affliction>() { AfflictionPrefab.InternalDamage.Instantiate(impactDamage) }, 0.0f, true);
|
character.AddDamage(impactPos, AfflictionPrefab.ImpactDamage.Instantiate(impactDamage).ToEnumerable(), 0.0f, true);
|
||||||
strongestImpact = Math.Max(strongestImpact, impact - ImpactTolerance);
|
strongestImpact = Math.Max(strongestImpact, impact - ImpactTolerance);
|
||||||
character.ApplyStatusEffects(ActionType.OnImpact, 1.0f);
|
character.ApplyStatusEffects(ActionType.OnImpact, 1.0f);
|
||||||
//briefly disable impact damage
|
//briefly disable impact damage
|
||||||
|
|||||||
@@ -2469,7 +2469,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly float maxAIRange = 10000;
|
private readonly float maxAIRange = 20000;
|
||||||
private readonly float aiTargetChangeSpeed = 5;
|
private readonly float aiTargetChangeSpeed = 5;
|
||||||
|
|
||||||
private void UpdateSightRange(float deltaTime)
|
private void UpdateSightRange(float deltaTime)
|
||||||
@@ -2741,14 +2741,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
if (severed)
|
if (severed)
|
||||||
{
|
{
|
||||||
if (joint.LimbA == targetLimb)
|
Limb otherLimb = joint.LimbA == targetLimb ? joint.LimbB : joint.LimbA;
|
||||||
{
|
otherLimb.body.ApplyLinearImpulse(targetLimb.LinearVelocity * targetLimb.Mass);
|
||||||
joint.LimbB.body.LinearVelocity += targetLimb.LinearVelocity * 0.5f;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
joint.LimbA.body.LinearVelocity += targetLimb.LinearVelocity * 0.5f;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (wasSevered)
|
if (wasSevered)
|
||||||
|
|||||||
+7
@@ -189,6 +189,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static AfflictionPrefab InternalDamage;
|
public static AfflictionPrefab InternalDamage;
|
||||||
|
public static AfflictionPrefab ImpactDamage;
|
||||||
public static AfflictionPrefab Bleeding;
|
public static AfflictionPrefab Bleeding;
|
||||||
public static AfflictionPrefab Burn;
|
public static AfflictionPrefab Burn;
|
||||||
public static AfflictionPrefab OxygenLow;
|
public static AfflictionPrefab OxygenLow;
|
||||||
@@ -291,6 +292,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
CPRSettings.Unload();
|
CPRSettings.Unload();
|
||||||
InternalDamage = null;
|
InternalDamage = null;
|
||||||
|
ImpactDamage = null;
|
||||||
Bleeding = null;
|
Bleeding = null;
|
||||||
Burn = null;
|
Burn = null;
|
||||||
OxygenLow = null;
|
OxygenLow = null;
|
||||||
@@ -437,6 +439,9 @@ namespace Barotrauma
|
|||||||
case "internaldamage":
|
case "internaldamage":
|
||||||
InternalDamage = prefab;
|
InternalDamage = prefab;
|
||||||
break;
|
break;
|
||||||
|
case "blunttrauma":
|
||||||
|
ImpactDamage = prefab;
|
||||||
|
break;
|
||||||
case "bleeding":
|
case "bleeding":
|
||||||
Bleeding = prefab;
|
Bleeding = prefab;
|
||||||
break;
|
break;
|
||||||
@@ -456,6 +461,8 @@ namespace Barotrauma
|
|||||||
Stun = prefab;
|
Stun = prefab;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (ImpactDamage == null) { ImpactDamage = InternalDamage; }
|
||||||
|
|
||||||
if (prefab != null)
|
if (prefab != null)
|
||||||
{
|
{
|
||||||
Prefabs.Add(prefab, isOverride);
|
Prefabs.Add(prefab, isOverride);
|
||||||
|
|||||||
@@ -46,10 +46,10 @@ namespace Barotrauma
|
|||||||
[Serialize(false, false), Editable]
|
[Serialize(false, false), Editable]
|
||||||
public bool CanSpeak { get; set; }
|
public bool CanSpeak { get; set; }
|
||||||
|
|
||||||
[Serialize(100f, true, description: "How much noise the character makes when moving?"), Editable(minValue: 0f, maxValue: 10000f)]
|
[Serialize(100f, true, description: "How much noise the character makes when moving?"), Editable(minValue: 0f, maxValue: 100000f)]
|
||||||
public float Noise { get; set; }
|
public float Noise { get; set; }
|
||||||
|
|
||||||
[Serialize(100f, true, description: "How visible the character is?"), Editable(minValue: 0f, maxValue: 10000f)]
|
[Serialize(100f, true, description: "How visible the character is?"), Editable(minValue: 0f, maxValue: 100000f)]
|
||||||
public float Visibility { get; set; }
|
public float Visibility { get; set; }
|
||||||
|
|
||||||
[Serialize("blood", true), Editable]
|
[Serialize("blood", true), Editable]
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ namespace Barotrauma
|
|||||||
private readonly int minAmount, maxAmount;
|
private readonly int minAmount, maxAmount;
|
||||||
private List<Character> monsters;
|
private List<Character> monsters;
|
||||||
|
|
||||||
|
private readonly float scatter;
|
||||||
|
private readonly float offset;
|
||||||
|
|
||||||
private readonly bool spawnDeep;
|
private readonly bool spawnDeep;
|
||||||
|
|
||||||
private Vector2? spawnPos;
|
private Vector2? spawnPos;
|
||||||
@@ -72,6 +75,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
spawnDeep = prefab.ConfigElement.GetAttributeBool("spawndeep", false);
|
spawnDeep = prefab.ConfigElement.GetAttributeBool("spawndeep", false);
|
||||||
|
offset = prefab.ConfigElement.GetAttributeFloat("offset", 0);
|
||||||
|
scatter = Math.Clamp(prefab.ConfigElement.GetAttributeFloat("scatter", 1000), 0, 3000);
|
||||||
|
|
||||||
if (GameMain.NetworkMember != null)
|
if (GameMain.NetworkMember != null)
|
||||||
{
|
{
|
||||||
@@ -241,6 +246,28 @@ namespace Barotrauma
|
|||||||
spawnPos = spawnPoint.WorldPosition;
|
spawnPos = spawnPoint.WorldPosition;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (chosenPosition.PositionType == Level.PositionType.MainPath && offset > 0)
|
||||||
|
{
|
||||||
|
Vector2 dir;
|
||||||
|
var waypoints = WayPoint.WayPointList.FindAll(wp => wp.Submarine == null);
|
||||||
|
var nearestWaypoint = waypoints.OrderBy(wp => Vector2.DistanceSquared(wp.WorldPosition, spawnPos.Value)).FirstOrDefault();
|
||||||
|
if (nearestWaypoint != null)
|
||||||
|
{
|
||||||
|
int currentIndex = waypoints.IndexOf(nearestWaypoint);
|
||||||
|
var nextWaypoint = waypoints[Math.Min(currentIndex + 20, waypoints.Count - 1)];
|
||||||
|
dir = Vector2.Normalize(nextWaypoint.WorldPosition - nearestWaypoint.WorldPosition);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dir = new Vector2(1, Rand.Range(-1, 1));
|
||||||
|
}
|
||||||
|
Vector2 targetPos = spawnPos.Value + dir * offset;
|
||||||
|
var targetWaypoint = waypoints.OrderBy(wp => Vector2.DistanceSquared(wp.WorldPosition, targetPos)).FirstOrDefault();
|
||||||
|
if (targetWaypoint != null)
|
||||||
|
{
|
||||||
|
spawnPos = targetWaypoint.WorldPosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
spawnPending = true;
|
spawnPending = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -314,7 +341,7 @@ namespace Barotrauma
|
|||||||
//+1 because Range returns an integer less than the max value
|
//+1 because Range returns an integer less than the max value
|
||||||
int amount = Rand.Range(minAmount, maxAmount + 1);
|
int amount = Rand.Range(minAmount, maxAmount + 1);
|
||||||
monsters = new List<Character>();
|
monsters = new List<Character>();
|
||||||
float offsetAmount = spawnPosType == Level.PositionType.MainPath ? 1000 : 100;
|
float offsetAmount = spawnPosType == Level.PositionType.MainPath ? scatter : 100;
|
||||||
for (int i = 0; i < amount; i++)
|
for (int i = 0; i < amount; i++)
|
||||||
{
|
{
|
||||||
CoroutineManager.InvokeAfter(() =>
|
CoroutineManager.InvokeAfter(() =>
|
||||||
@@ -324,7 +351,22 @@ namespace Barotrauma
|
|||||||
|
|
||||||
System.Diagnostics.Debug.Assert(GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer, "Clients should not create monster events.");
|
System.Diagnostics.Debug.Assert(GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer, "Clients should not create monster events.");
|
||||||
|
|
||||||
monsters.Add(Character.Create(speciesName, spawnPos.Value + Rand.Vector(offsetAmount), Level.Loaded.Seed + i.ToString(), null, false, true, true));
|
Vector2 pos = spawnPos.Value + Rand.Vector(offsetAmount);
|
||||||
|
if (spawnPosType == Level.PositionType.MainPath)
|
||||||
|
{
|
||||||
|
if (Submarine.Loaded.Any(s => ToolBox.GetWorldBounds(s.Borders.Center, s.Borders.Size).ContainsWorld(pos)))
|
||||||
|
{
|
||||||
|
// Can't use the offset position, let's use the exact spawn position.
|
||||||
|
pos = spawnPos.Value;
|
||||||
|
}
|
||||||
|
else if (Level.Loaded.Ruins.Any(r => ToolBox.GetWorldBounds(r.Area.Center, r.Area.Size).ContainsWorld(pos)))
|
||||||
|
{
|
||||||
|
// Can't use the offset position, let's use the exact spawn position.
|
||||||
|
pos = spawnPos.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
monsters.Add(Character.Create(speciesName, pos, Level.Loaded.Seed + i.ToString(), null, false, true, true));
|
||||||
|
|
||||||
if (monsters.Count == amount)
|
if (monsters.Count == amount)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -70,6 +70,12 @@ namespace Barotrauma.Items.Components
|
|||||||
[Serialize(false, false, description: "Can the item repair things through holes in walls.")]
|
[Serialize(false, false, description: "Can the item repair things through holes in walls.")]
|
||||||
public bool RepairThroughHoles { get; set; }
|
public bool RepairThroughHoles { get; set; }
|
||||||
|
|
||||||
|
[Serialize(true, false, description: "Can the item hit broken doors.")]
|
||||||
|
public bool HitItems { get; set; }
|
||||||
|
|
||||||
|
[Serialize(false, false, description: "Can the item hit broken doors.")]
|
||||||
|
public bool HitBrokenDoors { get; set; }
|
||||||
|
|
||||||
[Serialize(0.0f, false, description: "The probability of starting a fire somewhere along the ray fired from the barrel (for example, 0.1 = 10% chance to start a fire during a second of use).")]
|
[Serialize(0.0f, false, description: "The probability of starting a fire somewhere along the ray fired from the barrel (for example, 0.1 = 10% chance to start a fire during a second of use).")]
|
||||||
public float FireProbability { get; set; }
|
public float FireProbability { get; set; }
|
||||||
|
|
||||||
@@ -445,7 +451,9 @@ namespace Barotrauma.Items.Components
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (targetBody.UserData is Item targetItem)
|
else if (targetBody.UserData is Item targetItem)
|
||||||
{
|
{
|
||||||
|
if (!HitItems) { return false; }
|
||||||
|
|
||||||
var levelResource = targetItem.GetComponent<LevelResource>();
|
var levelResource = targetItem.GetComponent<LevelResource>();
|
||||||
if (levelResource != null && levelResource.Attached &&
|
if (levelResource != null && levelResource.Attached &&
|
||||||
levelResource.requiredItems.Any() &&
|
levelResource.requiredItems.Any() &&
|
||||||
@@ -463,7 +471,15 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!targetItem.Prefab.DamagedByRepairTools) { return false; }
|
if (!targetItem.Prefab.DamagedByRepairTools) { return false; }
|
||||||
if (item.GetComponent<Door>() == null && item.Condition <= 0) { return false; }
|
|
||||||
|
if (HitBrokenDoors)
|
||||||
|
{
|
||||||
|
if (targetItem.GetComponent<Door>() == null && targetItem.Condition <= 0) { return false; }
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (targetItem.Condition <= 0) { return false; }
|
||||||
|
}
|
||||||
|
|
||||||
targetItem.IsHighlighted = true;
|
targetItem.IsHighlighted = true;
|
||||||
|
|
||||||
|
|||||||
@@ -486,6 +486,10 @@ namespace Barotrauma.Items.Components
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (target.Body.UserData is Item item)
|
||||||
|
{
|
||||||
|
if (item.Condition <= 0.0f) { return false; }
|
||||||
|
}
|
||||||
|
|
||||||
//ignore character colliders (the projectile only hits limbs)
|
//ignore character colliders (the projectile only hits limbs)
|
||||||
if (target.CollisionCategories == Physics.CollisionCharacter && target.Body.UserData is Character)
|
if (target.CollisionCategories == Physics.CollisionCharacter && target.Body.UserData is Character)
|
||||||
|
|||||||
@@ -309,11 +309,10 @@ namespace Barotrauma.Items.Components
|
|||||||
SkillSettings.Current.SkillIncreasePerRepair / Math.Max(characterSkillLevel, 1.0f),
|
SkillSettings.Current.SkillIncreasePerRepair / Math.Max(characterSkillLevel, 1.0f),
|
||||||
CurrentFixer.WorldPosition + Vector2.UnitY * 100.0f);
|
CurrentFixer.WorldPosition + Vector2.UnitY * 100.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
SteamAchievementManager.OnItemRepaired(item, CurrentFixer);
|
SteamAchievementManager.OnItemRepaired(item, CurrentFixer);
|
||||||
deteriorationTimer = Rand.Range(MinDeteriorationDelay, MaxDeteriorationDelay);
|
|
||||||
wasBroken = false;
|
|
||||||
}
|
}
|
||||||
|
deteriorationTimer = Rand.Range(MinDeteriorationDelay, MaxDeteriorationDelay);
|
||||||
|
wasBroken = false;
|
||||||
StopRepairing(CurrentFixer);
|
StopRepairing(CurrentFixer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Serialize(false, false, description: "Can the component communicate with wifi components in another team's submarine (e.g. enemy sub in Combat missions, respawn shuttle). Needs to be enabled on both the component transmitting the signal and the component receiving it.", alwaysUseInstanceValues: true)]
|
[Editable, Serialize(false, true, description: "Can the component communicate with wifi components in another team's submarine (e.g. enemy sub in Combat missions, respawn shuttle). Needs to be enabled on both the component transmitting the signal and the component receiving it.", alwaysUseInstanceValues: true)]
|
||||||
public bool AllowCrossTeamCommunication
|
public bool AllowCrossTeamCommunication
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
|
|||||||
@@ -707,7 +707,8 @@ namespace Barotrauma
|
|||||||
var brokenSprite = new BrokenItemSprite(
|
var brokenSprite = new BrokenItemSprite(
|
||||||
new Sprite(subElement, brokenSpriteFolder, lazyLoad: true),
|
new Sprite(subElement, brokenSpriteFolder, lazyLoad: true),
|
||||||
subElement.GetAttributeFloat("maxcondition", 0.0f),
|
subElement.GetAttributeFloat("maxcondition", 0.0f),
|
||||||
subElement.GetAttributeBool("fadein", false));
|
subElement.GetAttributeBool("fadein", false),
|
||||||
|
subElement.GetAttributePoint("offset", Point.Zero));
|
||||||
|
|
||||||
int spriteIndex = 0;
|
int spriteIndex = 0;
|
||||||
for (int i = 0; i < BrokenSprites.Count && BrokenSprites[i].MaxCondition < brokenSprite.MaxCondition; i++)
|
for (int i = 0; i < BrokenSprites.Count && BrokenSprites[i].MaxCondition < brokenSprite.MaxCondition; i++)
|
||||||
|
|||||||
@@ -292,10 +292,10 @@ namespace Barotrauma
|
|||||||
if (limb.WorldPosition != worldPosition && !MathUtils.NearlyEqual(force, 0.0f))
|
if (limb.WorldPosition != worldPosition && !MathUtils.NearlyEqual(force, 0.0f))
|
||||||
{
|
{
|
||||||
Vector2 limbDiff = Vector2.Normalize(limb.WorldPosition - worldPosition);
|
Vector2 limbDiff = Vector2.Normalize(limb.WorldPosition - worldPosition);
|
||||||
if (!MathUtils.IsValid(limbDiff)) limbDiff = Rand.Vector(1.0f);
|
if (!MathUtils.IsValid(limbDiff)) { limbDiff = Rand.Vector(1.0f); }
|
||||||
Vector2 impulse = limbDiff * distFactor * force;
|
Vector2 impulse = limbDiff * distFactor * force;
|
||||||
Vector2 impulsePoint = limb.SimPosition - limbDiff * limbRadius;
|
Vector2 impulsePoint = limb.SimPosition - limbDiff * limbRadius;
|
||||||
limb.body.ApplyLinearImpulse(impulse, impulsePoint, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
|
limb.body.ApplyLinearImpulse(impulse, impulsePoint, maxVelocity: NetConfig.MaxPhysicsBodyVelocity * 0.2f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ namespace Barotrauma
|
|||||||
currentCell.CellType = CellType.Path;
|
currentCell.CellType = CellType.Path;
|
||||||
pathCells.Add(currentCell);
|
pathCells.Add(currentCell);
|
||||||
|
|
||||||
int currentTargetIndex = 1;
|
int currentTargetIndex = 0;
|
||||||
|
|
||||||
int iterationsLeft = cells.Count;
|
int iterationsLeft = cells.Count;
|
||||||
|
|
||||||
|
|||||||
@@ -1600,6 +1600,7 @@ namespace Barotrauma
|
|||||||
int attemptsLeft = maxAttempts;
|
int attemptsLeft = maxAttempts;
|
||||||
bool success = false;
|
bool success = false;
|
||||||
Vector2 spawnPoint = Vector2.Zero;
|
Vector2 spawnPoint = Vector2.Zero;
|
||||||
|
var allCells = Loaded.GetAllCells();
|
||||||
while (attemptsLeft > 0)
|
while (attemptsLeft > 0)
|
||||||
{
|
{
|
||||||
if (attemptsLeft < maxAttempts)
|
if (attemptsLeft < maxAttempts)
|
||||||
@@ -1847,8 +1848,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
var cells = Loaded.GetAllCells().Where(c => c.Body != null && Vector2.DistanceSquared(pos, c.Center) <= maxDistance);
|
return cells.Any(c => c.Body != null && Vector2.DistanceSquared(pos, c.Center) <= maxDistance && c.BodyVertices.Any(v => bounds.ContainsWorld(v)));
|
||||||
return cells.Any(c => c.BodyVertices.Any(v => bounds.ContainsWorld(v)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
totalSW.Stop();
|
totalSW.Stop();
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Barotrauma.Networking;
|
using Barotrauma.Extensions;
|
||||||
|
using Barotrauma.Networking;
|
||||||
using FarseerPhysics;
|
using FarseerPhysics;
|
||||||
using FarseerPhysics.Collision;
|
using FarseerPhysics.Collision;
|
||||||
using FarseerPhysics.Common;
|
using FarseerPhysics.Common;
|
||||||
@@ -451,7 +452,9 @@ namespace Barotrauma
|
|||||||
private void UpdateDepthDamage(float deltaTime)
|
private void UpdateDepthDamage(float deltaTime)
|
||||||
{
|
{
|
||||||
if (Position.Y > DamageDepth) { return; }
|
if (Position.Y > DamageDepth) { return; }
|
||||||
|
#if CLIENT
|
||||||
|
if (GameMain.GameSession.GameMode is SubTestMode) { return; }
|
||||||
|
#endif
|
||||||
float depth = DamageDepth - Position.Y;
|
float depth = DamageDepth - Position.Y;
|
||||||
|
|
||||||
depthDamageTimer -= deltaTime;
|
depthDamageTimer -= deltaTime;
|
||||||
@@ -639,7 +642,7 @@ namespace Barotrauma
|
|||||||
float damageAmount = contactDot * Body.Mass / limb.character.Mass;
|
float damageAmount = contactDot * Body.Mass / limb.character.Mass;
|
||||||
limb.character.LastDamageSource = submarine;
|
limb.character.LastDamageSource = submarine;
|
||||||
limb.character.DamageLimb(ConvertUnits.ToDisplayUnits(collision.ImpactPos), limb,
|
limb.character.DamageLimb(ConvertUnits.ToDisplayUnits(collision.ImpactPos), limb,
|
||||||
new List<Affliction>() { AfflictionPrefab.InternalDamage.Instantiate(damageAmount) }, 0.0f, true, 0.0f);
|
AfflictionPrefab.ImpactDamage.Instantiate(damageAmount).ToEnumerable(), 0.0f, true, 0.0f);
|
||||||
|
|
||||||
if (limb.character.IsDead)
|
if (limb.character.IsDead)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (element.StartTimer > 0.0f) { continue; }
|
if (element.StartTimer > 0.0f) { continue; }
|
||||||
|
|
||||||
element.Parent.Apply(1.0f, element.Entity, element.Targets, element.WorldPosition);
|
element.Parent.Apply(deltaTime, element.Entity, element.Targets, element.WorldPosition);
|
||||||
DelayList.Remove(element);
|
DelayList.Remove(element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -193,44 +193,64 @@ namespace Barotrauma
|
|||||||
string[] readTags = valStr.Split(',');
|
string[] readTags = valStr.Split(',');
|
||||||
int matches = 0;
|
int matches = 0;
|
||||||
foreach (string tag in readTags)
|
foreach (string tag in readTags)
|
||||||
if (target is Item item && item.HasTag(tag)) matches++;
|
{
|
||||||
|
if (target is Item item && item.HasTag(tag))
|
||||||
|
{
|
||||||
|
matches++;
|
||||||
|
}
|
||||||
|
}
|
||||||
//If operator is == then it needs to match everything, otherwise if its != there must be zero matches.
|
//If operator is == then it needs to match everything, otherwise if its != there must be zero matches.
|
||||||
return Operator == OperatorType.Equals ? matches >= readTags.Length : matches <= 0;
|
return Operator == OperatorType.Equals ? matches >= readTags.Length : matches <= 0;
|
||||||
}
|
}
|
||||||
case ConditionType.HasStatusTag:
|
case ConditionType.HasStatusTag:
|
||||||
if (target == null) { return Operator == OperatorType.NotEquals; }
|
if (target == null) { return Operator == OperatorType.NotEquals; }
|
||||||
|
|
||||||
List<DurationListElement> durations = StatusEffect.DurationList.FindAll(d => d.Targets.Contains(target));
|
|
||||||
List<DelayedListElement> delays = DelayedEffect.DelayList.FindAll(d => d.Targets.Contains(target));
|
|
||||||
|
|
||||||
bool success = false;
|
bool success = false;
|
||||||
if (durations.Count > 0 || delays.Count > 0)
|
if (StatusEffect.DurationList.Any(d => d.Targets.Contains(target)) || DelayedEffect.DelayList.Any(d => d.Targets.Contains(target)))
|
||||||
{
|
{
|
||||||
string[] readTags = valStr.Split(',');
|
string[] readTags = valStr.Split(',');
|
||||||
foreach (DurationListElement duration in durations)
|
foreach (DurationListElement duration in StatusEffect.DurationList)
|
||||||
{
|
{
|
||||||
|
if (!duration.Targets.Contains(target)) { continue; }
|
||||||
int matches = 0;
|
int matches = 0;
|
||||||
foreach (string tag in readTags)
|
foreach (string tag in readTags)
|
||||||
if (duration.Parent.HasTag(tag)) matches++;
|
{
|
||||||
|
if (duration.Parent.HasTag(tag))
|
||||||
|
{
|
||||||
|
matches++;
|
||||||
|
}
|
||||||
|
}
|
||||||
success = Operator == OperatorType.Equals ? matches >= readTags.Length : matches <= 0;
|
success = Operator == OperatorType.Equals ? matches >= readTags.Length : matches <= 0;
|
||||||
if (cancelStatusEffect > 0 && success)
|
if (cancelStatusEffect > 0 && success)
|
||||||
|
{
|
||||||
StatusEffect.DurationList.Remove(duration);
|
StatusEffect.DurationList.Remove(duration);
|
||||||
if (cancelStatusEffect != 2) //cancelStatusEffect 1 = only cancel once, cancelStatusEffect 2 = cancel all of matching tags
|
}
|
||||||
|
if (cancelStatusEffect != 2)
|
||||||
|
{
|
||||||
|
//cancelStatusEffect 1 = only cancel once, cancelStatusEffect 2 = cancel all of matching tags
|
||||||
return success;
|
return success;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
foreach (DelayedListElement delay in delays)
|
foreach (DelayedListElement delay in DelayedEffect.DelayList)
|
||||||
{
|
{
|
||||||
|
if (!delay.Targets.Contains(target)) { continue; }
|
||||||
int matches = 0;
|
int matches = 0;
|
||||||
foreach (string tag in readTags)
|
foreach (string tag in readTags)
|
||||||
if (delay.Parent.HasTag(tag)) matches++;
|
{
|
||||||
|
if (delay.Parent.HasTag(tag))
|
||||||
|
{
|
||||||
|
matches++;
|
||||||
|
}
|
||||||
|
}
|
||||||
success = Operator == OperatorType.Equals ? matches >= readTags.Length : matches <= 0;
|
success = Operator == OperatorType.Equals ? matches >= readTags.Length : matches <= 0;
|
||||||
if (cancelStatusEffect > 0 && success)
|
if (cancelStatusEffect > 0 && success)
|
||||||
|
{
|
||||||
DelayedEffect.DelayList.Remove(delay);
|
DelayedEffect.DelayList.Remove(delay);
|
||||||
if (cancelStatusEffect != 2) //ditto
|
}
|
||||||
|
if (cancelStatusEffect != 2)
|
||||||
|
{
|
||||||
|
//ditto
|
||||||
return success;
|
return success;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Operator == OperatorType.NotEquals)
|
else if (Operator == OperatorType.NotEquals)
|
||||||
|
|||||||
@@ -318,7 +318,7 @@ namespace Barotrauma
|
|||||||
break;
|
break;
|
||||||
case "conditionalcomparison":
|
case "conditionalcomparison":
|
||||||
case "comparison":
|
case "comparison":
|
||||||
if (!Enum.TryParse(attribute.Value, out conditionalComparison))
|
if (!Enum.TryParse(attribute.Value, ignoreCase: true, out conditionalComparison))
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Invalid conditional comparison type \"" + attribute.Value + "\" in StatusEffect (" + parentDebugName + ")");
|
DebugConsole.ThrowError("Invalid conditional comparison type \"" + attribute.Value + "\" in StatusEffect (" + parentDebugName + ")");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,24 @@
|
|||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
v0.9.1001.0 (Unstable)
|
||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
- Overhauled level layouts and events (longer and more difficult levels).
|
||||||
|
- Added two new afflictions: medical items and poisons cause organ damage instead of internal damage and explosions cause deep tissue injuries. Both are functionally identical to internal damage, and treated with the same items.
|
||||||
|
- Always draw steering indicators at the center of the display instead of the center of the sub. Fixes indicators getting offset (sometimes even outside the display) during docking.
|
||||||
|
- Added option to give all command perms with the "givecommandperm" command by using "all" as the parameter.
|
||||||
|
- Non-raycast projectiles ignore destroyed items (= destroyed thalamus organs don't block harpoons).
|
||||||
|
- Fixed monsters staying invisible if they die far away from the camera view.
|
||||||
|
- Fixed very small limbs (mudraptor's mouth tentacles, husk appendages) launching off at a very high velocity, leading to glitchy physics behavior, when hit by a non-raycast projectile or an explosion.
|
||||||
|
- Allow subs to be saved to subdirectories of the "Submarines" folder (e.g. "Submarines/Downloaded").
|
||||||
|
- Fixed item deterioration delay not resetting when the item is repaired if the condition of the item wasn't below the repair threshold when starting to repair it.
|
||||||
|
- Fixed bots failing to use welding tools inside their toolbox when fixing leaks.
|
||||||
|
- Items that appear broken to psychotic characters revert back to normal immediately when the psychosis is healed or when switching to another character.
|
||||||
|
- Fixed wires connected to a wifi component getting moved from signal_out to set_channel in old subs.
|
||||||
|
- Fixed plasma cutter beam not going through broken doors.
|
||||||
|
- Fixed extinguishers getting blocked by broken doors.
|
||||||
|
- The explosive cargo mission that places a block of Volatile Compound N in one of the crates no longer requires delivering the volatile block to the destination.
|
||||||
|
- Disabled crush depth in the submarine test mode.
|
||||||
|
|
||||||
---------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------
|
||||||
v0.9.1000.0 (Unstable)
|
v0.9.1000.0 (Unstable)
|
||||||
---------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user