Unstable 0.1300.0.3
This commit is contained in:
@@ -37,7 +37,7 @@ namespace Barotrauma
|
|||||||
public float MinZoom
|
public float MinZoom
|
||||||
{
|
{
|
||||||
get { return minZoom;}
|
get { return minZoom;}
|
||||||
set { minZoom = MathHelper.Clamp(value, 0.01f, 10.0f); }
|
set { minZoom = MathHelper.Clamp(value, 0.001f, 10.0f); }
|
||||||
}
|
}
|
||||||
|
|
||||||
private float maxZoom = 2.0f;
|
private float maxZoom = 2.0f;
|
||||||
@@ -51,8 +51,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private float zoom;
|
private float zoom;
|
||||||
|
|
||||||
private float offsetAmount;
|
|
||||||
|
|
||||||
private Matrix transform, shaderTransform, viewMatrix;
|
private Matrix transform, shaderTransform, viewMatrix;
|
||||||
private Vector2 position;
|
private Vector2 position;
|
||||||
private float rotation;
|
private float rotation;
|
||||||
@@ -68,15 +66,8 @@ namespace Barotrauma
|
|||||||
private Vector2 shakePosition;
|
private Vector2 shakePosition;
|
||||||
private float shakeTimer;
|
private float shakeTimer;
|
||||||
|
|
||||||
//the area of the world inside the camera view
|
|
||||||
private Rectangle worldView;
|
|
||||||
|
|
||||||
private float globalZoomScale = 1.0f;
|
private float globalZoomScale = 1.0f;
|
||||||
|
|
||||||
private Point resolution;
|
|
||||||
|
|
||||||
private Vector2 targetPos;
|
|
||||||
|
|
||||||
//used to smooth out the movement when in freecam
|
//used to smooth out the movement when in freecam
|
||||||
private float targetZoom;
|
private float targetZoom;
|
||||||
private Vector2 velocity;
|
private Vector2 velocity;
|
||||||
@@ -89,10 +80,10 @@ namespace Barotrauma
|
|||||||
zoom = MathHelper.Clamp(value, GameMain.DebugDraw ? 0.01f : MinZoom, MaxZoom);
|
zoom = MathHelper.Clamp(value, GameMain.DebugDraw ? 0.01f : MinZoom, MaxZoom);
|
||||||
|
|
||||||
Vector2 center = WorldViewCenter;
|
Vector2 center = WorldViewCenter;
|
||||||
float newWidth = resolution.X / zoom;
|
float newWidth = Resolution.X / zoom;
|
||||||
float newHeight = resolution.Y / zoom;
|
float newHeight = Resolution.Y / zoom;
|
||||||
|
|
||||||
worldView = new Rectangle(
|
WorldView = new Rectangle(
|
||||||
(int)(center.X - newWidth / 2.0f),
|
(int)(center.X - newWidth / 2.0f),
|
||||||
(int)(center.Y + newHeight / 2.0f),
|
(int)(center.Y + newHeight / 2.0f),
|
||||||
(int)newWidth,
|
(int)newWidth,
|
||||||
@@ -122,29 +113,20 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float OffsetAmount
|
public float OffsetAmount { get; set; }
|
||||||
{
|
|
||||||
get { return offsetAmount; }
|
|
||||||
set { offsetAmount = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Point Resolution
|
public Point Resolution { get; private set; }
|
||||||
{
|
|
||||||
get { return resolution; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Rectangle WorldView
|
//the area of the world inside the camera view
|
||||||
{
|
public Rectangle WorldView { get; private set; }
|
||||||
get { return worldView; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vector2 WorldViewCenter
|
public Vector2 WorldViewCenter
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return new Vector2(
|
return new Vector2(
|
||||||
worldView.X + worldView.Width / 2.0f,
|
WorldView.X + WorldView.Width / 2.0f,
|
||||||
worldView.Y - worldView.Height / 2.0f);
|
WorldView.Y - WorldView.Height / 2.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,12 +153,13 @@ namespace Barotrauma
|
|||||||
UpdateTransform(false);
|
UpdateTransform(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector2 TargetPos
|
~Camera()
|
||||||
{
|
{
|
||||||
get { return targetPos; }
|
GameMain.Instance.ResolutionChanged -= CreateMatrices;
|
||||||
set { targetPos = value; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vector2 TargetPos { get; set; }
|
||||||
|
|
||||||
public Vector2 GetPosition()
|
public Vector2 GetPosition()
|
||||||
{
|
{
|
||||||
return position;
|
return position;
|
||||||
@@ -204,21 +187,29 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void SetResolution(Point res)
|
public void SetResolution(Point res)
|
||||||
{
|
{
|
||||||
resolution = res;
|
Resolution = res;
|
||||||
|
|
||||||
worldView = new Rectangle(0, 0, res.X, res.Y);
|
WorldView = new Rectangle(0, 0, res.X, res.Y);
|
||||||
viewMatrix = Matrix.CreateTranslation(new Vector3(res.X / 2.0f, res.Y / 2.0f, 0));
|
viewMatrix = Matrix.CreateTranslation(new Vector3(res.X / 2.0f, res.Y / 2.0f, 0));
|
||||||
globalZoomScale = (float)Math.Pow(new Vector2(GUI.UIWidth, resolution.Y).Length() / GUI.ReferenceResolution.Length(), 2);
|
float newGlobalZoomScale = (float)new Vector2(GUI.UIWidth, Resolution.Y).Length() / GUI.ReferenceResolution.Length();
|
||||||
|
if (globalZoomScale > 0.0f)
|
||||||
|
{
|
||||||
|
Zoom *= newGlobalZoomScale / globalZoomScale;
|
||||||
|
targetZoom *= newGlobalZoomScale / globalZoomScale;
|
||||||
|
prevZoom *= newGlobalZoomScale / globalZoomScale;
|
||||||
|
}
|
||||||
|
globalZoomScale = newGlobalZoomScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateTransform(bool interpolate = true)
|
public void UpdateTransform(bool interpolate = true, bool updateListener = true)
|
||||||
{
|
{
|
||||||
Vector2 interpolatedPosition = interpolate ? Timing.Interpolate(prevPosition, position) : position;
|
Vector2 interpolatedPosition = interpolate ? Timing.Interpolate(prevPosition, position) : position;
|
||||||
|
|
||||||
float interpolatedZoom = interpolate ? Timing.Interpolate(prevZoom, zoom) : zoom;
|
float interpolatedZoom = interpolate ? Timing.Interpolate(prevZoom, zoom) : zoom;
|
||||||
|
|
||||||
worldView.X = (int)(interpolatedPosition.X - worldView.Width / 2.0);
|
WorldView = new Rectangle((int)(interpolatedPosition.X - WorldView.Width / 2.0),
|
||||||
worldView.Y = (int)(interpolatedPosition.Y + worldView.Height / 2.0);
|
(int)(interpolatedPosition.Y + WorldView.Height / 2.0),
|
||||||
|
WorldView.Width, WorldView.Height);
|
||||||
|
|
||||||
transform = Matrix.CreateTranslation(
|
transform = Matrix.CreateTranslation(
|
||||||
new Vector3(-interpolatedPosition.X, interpolatedPosition.Y, 0)) *
|
new Vector3(-interpolatedPosition.X, interpolatedPosition.Y, 0)) *
|
||||||
@@ -227,19 +218,22 @@ namespace Barotrauma
|
|||||||
|
|
||||||
shaderTransform = Matrix.CreateTranslation(
|
shaderTransform = Matrix.CreateTranslation(
|
||||||
new Vector3(
|
new Vector3(
|
||||||
-interpolatedPosition.X - resolution.X / interpolatedZoom / 2.0f,
|
-interpolatedPosition.X - Resolution.X / interpolatedZoom / 2.0f,
|
||||||
-interpolatedPosition.Y - resolution.Y / interpolatedZoom / 2.0f, 0)) *
|
-interpolatedPosition.Y - Resolution.Y / interpolatedZoom / 2.0f, 0)) *
|
||||||
Matrix.CreateScale(new Vector3(interpolatedZoom, interpolatedZoom, 1)) *
|
Matrix.CreateScale(new Vector3(interpolatedZoom, interpolatedZoom, 1)) *
|
||||||
|
|
||||||
viewMatrix * Matrix.CreateRotationZ(-rotation);
|
viewMatrix * Matrix.CreateRotationZ(-rotation);
|
||||||
|
|
||||||
if (Character.Controlled == null)
|
if (updateListener)
|
||||||
{
|
{
|
||||||
GameMain.SoundManager.ListenerPosition = new Vector3(WorldViewCenter.X, WorldViewCenter.Y, -(100.0f / zoom));
|
if (Character.Controlled == null)
|
||||||
}
|
{
|
||||||
else
|
GameMain.SoundManager.ListenerPosition = new Vector3(WorldViewCenter.X, WorldViewCenter.Y, -(100.0f / zoom));
|
||||||
{
|
}
|
||||||
GameMain.SoundManager.ListenerPosition = new Vector3(Character.Controlled.WorldPosition.X, Character.Controlled.WorldPosition.Y, -(100.0f / zoom));
|
else
|
||||||
|
{
|
||||||
|
GameMain.SoundManager.ListenerPosition = new Vector3(Character.Controlled.WorldPosition.X, Character.Controlled.WorldPosition.Y, -(100.0f / zoom));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -257,7 +251,7 @@ namespace Barotrauma
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Freeze { get; set; }
|
public bool Freeze { get; set; }
|
||||||
|
|
||||||
public void MoveCamera(float deltaTime, bool allowMove = true, bool allowZoom = true, Rectangle? overrideMouseOn = null)
|
public void MoveCamera(float deltaTime, bool allowMove = true, bool allowZoom = true)
|
||||||
{
|
{
|
||||||
prevPosition = position;
|
prevPosition = position;
|
||||||
prevZoom = zoom;
|
prevZoom = zoom;
|
||||||
@@ -265,7 +259,7 @@ namespace Barotrauma
|
|||||||
float moveSpeed = 20.0f / zoom;
|
float moveSpeed = 20.0f / zoom;
|
||||||
|
|
||||||
Vector2 moveCam = Vector2.Zero;
|
Vector2 moveCam = Vector2.Zero;
|
||||||
if (targetPos == Vector2.Zero)
|
if (TargetPos == Vector2.Zero)
|
||||||
{
|
{
|
||||||
Vector2 moveInput = Vector2.Zero;
|
Vector2 moveInput = Vector2.Zero;
|
||||||
if (allowMove && !Freeze)
|
if (allowMove && !Freeze)
|
||||||
@@ -294,7 +288,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allowZoom && (GUI.MouseOn == null || (overrideMouseOn?.Contains(PlayerInput.MousePosition) ?? false)))
|
if (allowZoom)
|
||||||
{
|
{
|
||||||
Vector2 mouseInWorld = ScreenToWorld(PlayerInput.MousePosition);
|
Vector2 mouseInWorld = ScreenToWorld(PlayerInput.MousePosition);
|
||||||
Vector2 diffViewCenter;
|
Vector2 diffViewCenter;
|
||||||
@@ -318,14 +312,14 @@ namespace Barotrauma
|
|||||||
else if (allowMove)
|
else if (allowMove)
|
||||||
{
|
{
|
||||||
Vector2 mousePos = PlayerInput.MousePosition;
|
Vector2 mousePos = PlayerInput.MousePosition;
|
||||||
Vector2 offset = mousePos - resolution.ToVector2() / 2;
|
Vector2 offset = mousePos - Resolution.ToVector2() / 2;
|
||||||
offset.X = offset.X / (resolution.X * 0.4f);
|
offset.X = offset.X / (Resolution.X * 0.6f);
|
||||||
offset.Y = -offset.Y / (resolution.Y * 0.3f);
|
offset.Y = -offset.Y / (Resolution.Y * 0.6f);
|
||||||
if (offset.LengthSquared() > 1.0f) offset.Normalize();
|
if (offset.LengthSquared() > 1.0f) offset.Normalize();
|
||||||
offset *= offsetAmount;
|
offset *= OffsetAmount;
|
||||||
// Freeze the camera movement by default, when the cursor is on top of an ui element.
|
// Freeze the camera movement by default, when the cursor is on top of an ui element.
|
||||||
// Setting a positive value to the OffsetAmount, will override this behaviour.
|
// Setting a positive value to the OffsetAmount, will override this behaviour.
|
||||||
if (GUI.MouseOn != null && offsetAmount > 0)
|
if (GUI.MouseOn != null && OffsetAmount > 0)
|
||||||
{
|
{
|
||||||
Freeze = true;
|
Freeze = true;
|
||||||
}
|
}
|
||||||
@@ -343,25 +337,21 @@ namespace Barotrauma
|
|||||||
previousOffset = offset;
|
previousOffset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
//how much to zoom out (zoom completely out when offset is 1000)
|
//TODO: remove magic numbers
|
||||||
float zoomOutAmount = GetZoomAmount(offset);
|
float minMultiplier = OffsetAmount > 0f ? ((DefaultZoom * 8f * 250f) / OffsetAmount) : 15f;
|
||||||
//zoom amount when resolution is not taken into account
|
|
||||||
float unscaledZoom = MathHelper.Lerp(DefaultZoom, MinZoom, zoomOutAmount);
|
|
||||||
//zoom with resolution taken into account (zoom further out on smaller resolutions)
|
|
||||||
float scaledZoom = unscaledZoom * globalZoomScale;
|
|
||||||
|
|
||||||
//an ad-hoc way of allowing the players to have roughly the same maximum view distance regardless of the resolution,
|
//how much to zoom out (0.0 = Default zoom, 1.0 = zoom completely out)
|
||||||
//while still keeping the zoom around 1.0 when not looking further away (because otherwise we'd always be downsampling
|
float zoomOutAmount = GetZoomAmount(offset);
|
||||||
//on lower resolutions, which doesn't look that good)
|
float newZoom = MathHelper.Lerp(DefaultZoom, MinZoom * minMultiplier, zoomOutAmount) * globalZoomScale;
|
||||||
float newZoom = MathHelper.Lerp(unscaledZoom, scaledZoom,
|
//zoom in further if zoomOutAmount is low and resolution is lower than reference
|
||||||
(GameMain.Config == null || GameMain.Config.EnableMouseLook) ? (float)Math.Sqrt(zoomOutAmount) : 0.3f);
|
newZoom *= MathHelper.Lerp(0.5f * (1f - Math.Min(globalZoomScale, 1f)), 0f, zoomOutAmount) + 1f;
|
||||||
|
|
||||||
Zoom += (newZoom - zoom) / ZoomSmoothness;
|
Zoom += (newZoom - zoom) / ZoomSmoothness;
|
||||||
|
|
||||||
//force targetzoom to the current zoom value, so the camera stays at the same zoom when switching to freecam
|
//force targetzoom to the current zoom value, so the camera stays at the same zoom when switching to freecam
|
||||||
targetZoom = Zoom;
|
targetZoom = Zoom;
|
||||||
|
|
||||||
Vector2 diff = (targetPos + offset) - position;
|
Vector2 diff = (TargetPos + offset) - position;
|
||||||
|
|
||||||
moveCam = diff / MoveSmoothness;
|
moveCam = diff / MoveSmoothness;
|
||||||
}
|
}
|
||||||
@@ -426,7 +416,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private float GetZoomAmount(Vector2 offset)
|
private float GetZoomAmount(Vector2 offset)
|
||||||
{
|
{
|
||||||
return Math.Min(offset.Length() / 1000.0f, 1.0f);
|
return Math.Min(offset.Length() / Math.Max(1f, OffsetAmount), 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float GetZoomAmountFromPrevious()
|
public float GetZoomAmountFromPrevious()
|
||||||
|
|||||||
@@ -224,8 +224,7 @@ namespace Barotrauma
|
|||||||
float targetOffsetAmount = 0.0f;
|
float targetOffsetAmount = 0.0f;
|
||||||
if (moveCam)
|
if (moveCam)
|
||||||
{
|
{
|
||||||
if (NeedsAir &&
|
if (NeedsAir && !IsProtectedFromPressure() &&
|
||||||
pressureProtection < 80.0f &&
|
|
||||||
(AnimController.CurrentHull == null || AnimController.CurrentHull.LethalPressure > 0.0f))
|
(AnimController.CurrentHull == null || AnimController.CurrentHull.LethalPressure > 0.0f))
|
||||||
{
|
{
|
||||||
float pressure = AnimController.CurrentHull == null ? 100.0f : AnimController.CurrentHull.LethalPressure;
|
float pressure = AnimController.CurrentHull == null ? 100.0f : AnimController.CurrentHull.LethalPressure;
|
||||||
@@ -382,13 +381,38 @@ namespace Barotrauma
|
|||||||
|
|
||||||
partial void KillProjSpecific(CauseOfDeathType causeOfDeath, Affliction causeOfDeathAffliction, bool log)
|
partial void KillProjSpecific(CauseOfDeathType causeOfDeath, Affliction causeOfDeathAffliction, bool log)
|
||||||
{
|
{
|
||||||
|
HintManager.OnCharacterKilled(this);
|
||||||
|
|
||||||
if (GameMain.NetworkMember != null && controlled == this)
|
if (GameMain.NetworkMember != null && controlled == this)
|
||||||
{
|
{
|
||||||
string chatMessage = CauseOfDeath.Type == CauseOfDeathType.Affliction ?
|
string chatMessage = CauseOfDeath.Type == CauseOfDeathType.Affliction ?
|
||||||
CauseOfDeath.Affliction.SelfCauseOfDeathDescription :
|
CauseOfDeath.Affliction.SelfCauseOfDeathDescription :
|
||||||
TextManager.Get("Self_CauseOfDeathDescription." + CauseOfDeath.Type.ToString(), fallBackTag: "Self_CauseOfDeathDescription.Damage");
|
TextManager.Get("Self_CauseOfDeathDescription." + CauseOfDeath.Type.ToString(), fallBackTag: "Self_CauseOfDeathDescription.Damage");
|
||||||
|
|
||||||
if (GameMain.Client != null) chatMessage += " " + TextManager.Get("DeathChatNotification");
|
if (GameMain.Client != null) { chatMessage += " " + TextManager.Get("DeathChatNotification"); }
|
||||||
|
|
||||||
|
if (GameMain.GameSession?.GameMode is CampaignMode && GameMain.NetworkMember.RespawnManager != null && Level.Loaded?.Type != LevelData.LevelType.Outpost)
|
||||||
|
{
|
||||||
|
CoroutineManager.InvokeAfter(() =>
|
||||||
|
{
|
||||||
|
if (controlled != null || (!(GameMain.GameSession?.IsRunning ?? false))) { return; }
|
||||||
|
var respawnPrompt = new GUIMessageBox(
|
||||||
|
TextManager.Get("tutorial.tryagainheader"), TextManager.Get("respawnquestionprompt"),
|
||||||
|
new string[] { TextManager.Get("respawnquestionpromptrespawn"), TextManager.Get("respawnquestionpromptwait") });
|
||||||
|
respawnPrompt.Buttons[0].OnClicked += (btn, userdata) =>
|
||||||
|
{
|
||||||
|
GameMain.Client?.SendRespawnPromptResponse(waitForNextRoundRespawn: false);
|
||||||
|
respawnPrompt.Close();
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
respawnPrompt.Buttons[1].OnClicked += (btn, userdata) =>
|
||||||
|
{
|
||||||
|
GameMain.Client?.SendRespawnPromptResponse(waitForNextRoundRespawn: true);
|
||||||
|
respawnPrompt.Close();
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}, delay: 5.0f);
|
||||||
|
}
|
||||||
|
|
||||||
GameMain.NetworkMember.AddChatMessage(chatMessage, ChatMessageType.Dead);
|
GameMain.NetworkMember.AddChatMessage(chatMessage, ChatMessageType.Dead);
|
||||||
GameMain.LightManager.LosEnabled = false;
|
GameMain.LightManager.LosEnabled = false;
|
||||||
|
|||||||
@@ -100,7 +100,22 @@ namespace Barotrauma
|
|||||||
Color textColor = Color.White * (0.5f + skill.Level / 200.0f);
|
Color textColor = Color.White * (0.5f + skill.Level / 200.0f);
|
||||||
|
|
||||||
var skillName = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), skillsArea.RectTransform), TextManager.Get("SkillName." + skill.Identifier), textColor: textColor, font: font) { Padding = Vector4.Zero };
|
var skillName = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), skillsArea.RectTransform), TextManager.Get("SkillName." + skill.Identifier), textColor: textColor, font: font) { Padding = Vector4.Zero };
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 1.0f), skillName.RectTransform), ((int)skill.Level).ToString(), textColor: textColor, font: font, textAlignment: Alignment.CenterRight);
|
|
||||||
|
float modifiedSkillLevel = skill.Level;
|
||||||
|
if (Character != null)
|
||||||
|
{
|
||||||
|
modifiedSkillLevel = Character.GetSkillLevel(skill.Identifier);
|
||||||
|
}
|
||||||
|
if (!MathUtils.NearlyEqual(MathF.Round(modifiedSkillLevel), MathF.Round(skill.Level)))
|
||||||
|
{
|
||||||
|
int skillChange = (int)MathF.Round(modifiedSkillLevel - skill.Level);
|
||||||
|
string changeText = $"{(skillChange > 0 ? "+" : "") + skillChange}";
|
||||||
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 1.0f), skillName.RectTransform), $"{(int)skill.Level} ({changeText})", textColor: textColor, font: font, textAlignment: Alignment.CenterRight);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 1.0f), skillName.RectTransform), ((int)skill.Level).ToString(), textColor: textColor, font: font, textAlignment: Alignment.CenterRight);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Character != null && Character.IsDead)
|
else if (Character != null && Character.IsDead)
|
||||||
|
|||||||
@@ -330,6 +330,8 @@ namespace Barotrauma
|
|||||||
GameMain.Client.HasSpawned = true;
|
GameMain.Client.HasSpawned = true;
|
||||||
GameMain.Client.Character = this;
|
GameMain.Client.Character = this;
|
||||||
GameMain.LightManager.LosEnabled = true;
|
GameMain.LightManager.LosEnabled = true;
|
||||||
|
GameMain.LightManager.LosAlpha = 1f;
|
||||||
|
GameMain.Client.WaitForNextRoundRespawn = null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -516,6 +518,7 @@ namespace Barotrauma
|
|||||||
if (!character.IsDead) { Controlled = character; }
|
if (!character.IsDead) { Controlled = character; }
|
||||||
|
|
||||||
GameMain.LightManager.LosEnabled = true;
|
GameMain.LightManager.LosEnabled = true;
|
||||||
|
GameMain.LightManager.LosAlpha = 1f;
|
||||||
|
|
||||||
character.memInput.Clear();
|
character.memInput.Clear();
|
||||||
character.memState.Clear();
|
character.memState.Clear();
|
||||||
|
|||||||
@@ -997,8 +997,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
cprButton.Visible =
|
cprButton.Visible =
|
||||||
Character == Character.Controlled?.SelectedCharacter
|
Character == Character.Controlled?.SelectedCharacter
|
||||||
&& (Character.IsUnconscious || Character.Stun > 0.0f)
|
|
||||||
&& !Character.IsDead
|
&& !Character.IsDead
|
||||||
|
&& Character.IsKnockedDown
|
||||||
&& openHealthWindow == this;
|
&& openHealthWindow == this;
|
||||||
cprButton.IgnoreLayoutGroups = !cprButton.Visible;
|
cprButton.IgnoreLayoutGroups = !cprButton.Visible;
|
||||||
cprButton.Selected =
|
cprButton.Selected =
|
||||||
|
|||||||
@@ -1247,6 +1247,7 @@ namespace Barotrauma
|
|||||||
GameMain.DebugDraw = false;
|
GameMain.DebugDraw = false;
|
||||||
GameMain.LightManager.LightingEnabled = true;
|
GameMain.LightManager.LightingEnabled = true;
|
||||||
GameMain.LightManager.LosEnabled = true;
|
GameMain.LightManager.LosEnabled = true;
|
||||||
|
GameMain.LightManager.LosAlpha = 1f;
|
||||||
}
|
}
|
||||||
NewMessage(HumanAIController.debugai ? "AI debug info visible" : "AI debug info hidden", Color.White);
|
NewMessage(HumanAIController.debugai ? "AI debug info visible" : "AI debug info hidden", Color.White);
|
||||||
});
|
});
|
||||||
|
|||||||
+10
-4
@@ -14,10 +14,7 @@ namespace Barotrauma
|
|||||||
base.State = value;
|
base.State = value;
|
||||||
if (state == HostagesKilledState && !string.IsNullOrEmpty(hostagesKilledMessage))
|
if (state == HostagesKilledState && !string.IsNullOrEmpty(hostagesKilledMessage))
|
||||||
{
|
{
|
||||||
new GUIMessageBox(string.Empty, hostagesKilledMessage, buttons: new string[0], type: GUIMessageBox.Type.InGame, icon: Prefab.Icon, parseRichText: true)
|
CreateMessageBox(string.Empty, hostagesKilledMessage);
|
||||||
{
|
|
||||||
IconColor = Prefab.IconColor
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -44,6 +41,15 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Item.ReadSpawnData(msg);
|
Item.ReadSpawnData(msg);
|
||||||
}
|
}
|
||||||
|
if (character.Submarine != null && character.AIController is EnemyAIController enemyAi)
|
||||||
|
{
|
||||||
|
enemyAi.UnattackableSubmarines.Add(character.Submarine);
|
||||||
|
enemyAi.UnattackableSubmarines.Add(Submarine.MainSub);
|
||||||
|
foreach (Submarine sub in Submarine.MainSub.DockedTo)
|
||||||
|
{
|
||||||
|
enemyAi.UnattackableSubmarines.Add(sub);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (characters.Contains(null))
|
if (characters.Contains(null))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Barotrauma.Networking;
|
using Barotrauma.Networking;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
@@ -7,6 +8,19 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
abstract partial class Mission
|
abstract partial class Mission
|
||||||
{
|
{
|
||||||
|
private readonly List<string> shownMessages = new List<string>();
|
||||||
|
public IEnumerable<string> ShownMessages
|
||||||
|
{
|
||||||
|
get { return shownMessages; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color GetDifficultyColor()
|
||||||
|
{
|
||||||
|
int v = Difficulty ?? MissionPrefab.MinDifficulty;
|
||||||
|
float t = MathUtils.InverseLerp(MissionPrefab.MinDifficulty, MissionPrefab.MaxDifficulty, v);
|
||||||
|
return ToolBox.GradientLerp(t, GUI.Style.Green, GUI.Style.Orange, GUI.Style.Red);
|
||||||
|
}
|
||||||
|
|
||||||
public string GetMissionRewardText()
|
public string GetMissionRewardText()
|
||||||
{
|
{
|
||||||
string rewardText = TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", Reward));
|
string rewardText = TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", Reward));
|
||||||
@@ -71,6 +85,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
protected void CreateMessageBox(string header, string message)
|
protected void CreateMessageBox(string header, string message)
|
||||||
{
|
{
|
||||||
|
shownMessages.Add(message);
|
||||||
new GUIMessageBox(header, message, buttons: new string[0], type: GUIMessageBox.Type.InGame, icon: Prefab.Icon, parseRichText: true)
|
new GUIMessageBox(header, message, buttons: new string[0], type: GUIMessageBox.Type.InGame, icon: Prefab.Icon, parseRichText: true)
|
||||||
{
|
{
|
||||||
IconColor = Prefab.IconColor
|
IconColor = Prefab.IconColor
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
|
|||||||
@@ -565,34 +565,26 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string guiScaleString = $"GUI.Scale: {Scale}";
|
string[] strings = new string[]
|
||||||
string guixScaleString = $"GUI.xScale: {xScale}";
|
{
|
||||||
string guiyScaleString = $"GUI.yScale: {yScale}";
|
$"GUI.Scale: {Scale}",
|
||||||
string relativeHorizontalAspectRatioString = $"RelativeHorizontalAspectRatio: {RelativeHorizontalAspectRatio}";
|
$"GUI.xScale: {xScale}",
|
||||||
string relativeVerticalAspectRatioString = $"RelativeVerticalAspectRatio: {RelativeVerticalAspectRatio}";
|
$"GUI.yScale: {yScale}",
|
||||||
Vector2 guiScaleStringSize = SmallFont.MeasureString(guiScaleString);
|
$"RelativeHorizontalAspectRatio: {RelativeHorizontalAspectRatio}",
|
||||||
Vector2 guixScaleStringSize = SmallFont.MeasureString(guixScaleString);
|
$"RelativeVerticalAspectRatio: {RelativeVerticalAspectRatio}",
|
||||||
Vector2 guiyScaleStringSize = SmallFont.MeasureString(guiyScaleString);
|
$"Cam.Zoom: {Screen.Selected.Cam?.Zoom ?? 0f}",
|
||||||
Vector2 relativeHorizontalAspectRatioStringSize = SmallFont.MeasureString(relativeHorizontalAspectRatioString);
|
};
|
||||||
Vector2 relativeVerticalAspectRatioStringSize = SmallFont.MeasureString(relativeVerticalAspectRatioString);
|
|
||||||
|
|
||||||
int padding = IntScale(10);
|
int padding = IntScale(10);
|
||||||
int yPos = padding;
|
int yPos = padding;
|
||||||
|
|
||||||
DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - (int)guiScaleStringSize.X - padding, yPos), guiScaleString, Color.LightGreen, Color.Black, 0, SmallFont);
|
foreach (string str in strings)
|
||||||
yPos += (int)guiScaleStringSize.Y + padding / 2;
|
{
|
||||||
|
Vector2 stringSize = SmallFont.MeasureString(str);
|
||||||
|
|
||||||
DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - (int)guixScaleStringSize.X - padding, yPos), guixScaleString, Color.LightGreen, Color.Black, 0, SmallFont);
|
DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - (int)stringSize.X - padding, yPos), str, Color.LightGreen, Color.Black, 0, SmallFont);
|
||||||
yPos += (int)guixScaleStringSize.Y + padding / 2;
|
yPos += (int)stringSize.Y + padding / 2;
|
||||||
|
}
|
||||||
DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - (int)guiyScaleStringSize.X - padding, yPos), guiyScaleString, Color.LightGreen, Color.Black, 0, SmallFont);
|
|
||||||
yPos += (int)guiyScaleStringSize.Y + padding / 2;
|
|
||||||
|
|
||||||
DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - (int)relativeHorizontalAspectRatioStringSize.X - padding, yPos), relativeHorizontalAspectRatioString, Color.LightGreen, Color.Black, 0, SmallFont);
|
|
||||||
yPos += (int)relativeHorizontalAspectRatioStringSize.Y + padding / 2;
|
|
||||||
|
|
||||||
DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - (int)relativeVerticalAspectRatioStringSize.X - padding, yPos), relativeVerticalAspectRatioString, Color.LightGreen, Color.Black, 0, SmallFont);
|
|
||||||
yPos += (int)relativeVerticalAspectRatioStringSize.Y + padding / 2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -194,6 +194,8 @@ namespace Barotrauma
|
|||||||
public bool ScrollBarEnabled { get; set; } = true;
|
public bool ScrollBarEnabled { get; set; } = true;
|
||||||
public bool KeepSpaceForScrollBar { get; set; }
|
public bool KeepSpaceForScrollBar { get; set; }
|
||||||
|
|
||||||
|
public bool CanTakeKeyBoardFocus { get; set; } = true;
|
||||||
|
|
||||||
public bool ScrollBarVisible
|
public bool ScrollBarVisible
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -891,7 +893,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If one of the children is the subscriber, we don't want to register, because it will unregister the child.
|
// If one of the children is the subscriber, we don't want to register, because it will unregister the child.
|
||||||
if (takeKeyBoardFocus && RectTransform.GetAllChildren().None(rt => rt.GUIComponent == GUI.KeyboardDispatcher.Subscriber))
|
if (takeKeyBoardFocus && CanTakeKeyBoardFocus && RectTransform.GetAllChildren().None(rt => rt.GUIComponent == GUI.KeyboardDispatcher.Subscriber))
|
||||||
{
|
{
|
||||||
Selected = true;
|
Selected = true;
|
||||||
GUI.KeyboardDispatcher.Subscriber = this;
|
GUI.KeyboardDispatcher.Subscriber = this;
|
||||||
|
|||||||
@@ -261,7 +261,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public readonly List<RichTextData> RichTextData = null;
|
public readonly List<RichTextData> RichTextData = null;
|
||||||
|
|
||||||
private readonly bool hasColorHighlight = false;
|
public bool HasColorHighlight => RichTextData != null;
|
||||||
|
|
||||||
public struct ClickableArea
|
public struct ClickableArea
|
||||||
{
|
{
|
||||||
@@ -295,7 +295,6 @@ namespace Barotrauma
|
|||||||
if (parseRichText)
|
if (parseRichText)
|
||||||
{
|
{
|
||||||
RichTextData = Barotrauma.RichTextData.GetRichTextData(text, out text);
|
RichTextData = Barotrauma.RichTextData.GetRichTextData(text, out text);
|
||||||
hasColorHighlight = RichTextData != null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//if the text is in chinese/korean/japanese and we're not using a CJK-compatible font,
|
//if the text is in chinese/korean/japanese and we're not using a CJK-compatible font,
|
||||||
@@ -326,7 +325,6 @@ namespace Barotrauma
|
|||||||
: this(rectT, text, textColor, font, textAlignment, wrap, style, color, playerInput)
|
: this(rectT, text, textColor, font, textAlignment, wrap, style, color, playerInput)
|
||||||
{
|
{
|
||||||
this.RichTextData = richTextData;
|
this.RichTextData = richTextData;
|
||||||
hasColorHighlight = richTextData != null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CalculateHeightFromText(int padding = 0, bool removeExtraSpacing = false)
|
public void CalculateHeightFromText(int padding = 0, bool removeExtraSpacing = false)
|
||||||
@@ -634,7 +632,7 @@ namespace Barotrauma
|
|||||||
currentTextColor = selectedTextColor;
|
currentTextColor = selectedTextColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasColorHighlight)
|
if (!HasColorHighlight)
|
||||||
{
|
{
|
||||||
string textToShow = Censor ? censoredText : (Wrap ? wrappedText : text);
|
string textToShow = Censor ? censoredText : (Wrap ? wrappedText : text);
|
||||||
Color colorToShow = currentTextColor * (currentTextColor.A / 255.0f);
|
Color colorToShow = currentTextColor * (currentTextColor.A / 255.0f);
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Point maxPoint = new Point(int.MaxValue, int.MaxValue);
|
public readonly static Point MaxPoint = new Point(int.MaxValue, int.MaxValue);
|
||||||
private Point? maxSize;
|
private Point? maxSize;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -103,7 +103,7 @@ namespace Barotrauma
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Point MaxSize
|
public Point MaxSize
|
||||||
{
|
{
|
||||||
get { return maxSize ?? maxPoint; }
|
get { return maxSize ?? MaxPoint; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (maxSize == value) { return; }
|
if (maxSize == value) { return; }
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace Barotrauma
|
|||||||
private static UISprite spectateIcon, disconnectedIcon;
|
private static UISprite spectateIcon, disconnectedIcon;
|
||||||
private static Sprite ownerIcon, moderatorIcon;
|
private static Sprite ownerIcon, moderatorIcon;
|
||||||
|
|
||||||
private enum InfoFrameTab { Crew, Mission, Reputation, MyCharacter, Traitor };
|
private enum InfoFrameTab { Crew, Mission, Reputation, MyCharacter, Traitor, Submarine };
|
||||||
private static InfoFrameTab selectedTab;
|
private static InfoFrameTab selectedTab;
|
||||||
private GUIFrame infoFrame, contentFrame;
|
private GUIFrame infoFrame, contentFrame;
|
||||||
|
|
||||||
@@ -181,77 +181,79 @@ namespace Barotrauma
|
|||||||
infoFrame = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas, Anchor.Center), style: null);
|
infoFrame = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas, Anchor.Center), style: null);
|
||||||
new GUIFrame(new RectTransform(GUI.Canvas.RelativeSize, infoFrame.RectTransform, Anchor.Center), style: "GUIBackgroundBlocker");
|
new GUIFrame(new RectTransform(GUI.Canvas.RelativeSize, infoFrame.RectTransform, Anchor.Center), style: "GUIBackgroundBlocker");
|
||||||
|
|
||||||
Vector2 contentFrameSize = selectedTab switch
|
//this used to be a switch expression but i changed it because it killed enc :(
|
||||||
|
Vector2 contentFrameSize;
|
||||||
|
switch (selectedTab)
|
||||||
{
|
{
|
||||||
InfoFrameTab.MyCharacter => new Vector2(0.33f, 0.5f),
|
case InfoFrameTab.MyCharacter:
|
||||||
_ => new Vector2(0.33f, 0.667f)
|
contentFrameSize = new Vector2(0.45f, 0.5f);
|
||||||
};
|
break;
|
||||||
|
default:
|
||||||
|
contentFrameSize = new Vector2(0.45f, 0.667f);
|
||||||
|
break;
|
||||||
|
}
|
||||||
contentFrame = new GUIFrame(new RectTransform(contentFrameSize, infoFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter) { RelativeOffset = new Vector2(0.025f, 0.12f) });
|
contentFrame = new GUIFrame(new RectTransform(contentFrameSize, infoFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter) { RelativeOffset = new Vector2(0.025f, 0.12f) });
|
||||||
|
|
||||||
var innerLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.958f, 0.943f), contentFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter) { AbsoluteOffset = new Point(0, GUI.IntScale(17.5f)) })
|
var horizontalLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.958f, 0.943f), contentFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter) { AbsoluteOffset = new Point(0, GUI.IntScale(25f)) }, isHorizontal: true)
|
||||||
{
|
|
||||||
RelativeSpacing = 0.01f,
|
|
||||||
Stretch = true
|
|
||||||
};
|
|
||||||
var buttonArea = new GUILayoutGroup(new RectTransform(new Point(innerLayoutGroup.Rect.Width, GUI.IntScale(25f)), parent: innerLayoutGroup.RectTransform), isHorizontal: true)
|
|
||||||
{
|
{
|
||||||
RelativeSpacing = 0.01f
|
RelativeSpacing = 0.01f
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var buttonArea = new GUILayoutGroup(new RectTransform(new Vector2(0.07f, 1f), parent: horizontalLayoutGroup.RectTransform), isHorizontal: false)
|
||||||
|
{
|
||||||
|
AbsoluteSpacing = GUI.IntScale(5f)
|
||||||
|
};
|
||||||
|
var innerLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.92f, 1f), horizontalLayoutGroup.RectTransform))
|
||||||
|
{
|
||||||
|
RelativeSpacing = 0.01f,
|
||||||
|
Stretch = true
|
||||||
|
};
|
||||||
|
|
||||||
float absoluteSpacing = innerLayoutGroup.RelativeSpacing * innerLayoutGroup.Rect.Height;
|
float absoluteSpacing = innerLayoutGroup.RelativeSpacing * innerLayoutGroup.Rect.Height;
|
||||||
int multiplier = GameMain.GameSession?.GameMode is CampaignMode ? 2 : 1;
|
int multiplier = GameMain.GameSession?.GameMode is CampaignMode ? 2 : 1;
|
||||||
int infoFrameHolderHeight = Math.Min((int)(0.926f * innerLayoutGroup.Rect.Height), (int)(innerLayoutGroup.Rect.Height - multiplier * (GUI.IntScale(25f) + absoluteSpacing)));
|
int infoFrameHolderHeight = Math.Min((int)(0.97f * innerLayoutGroup.Rect.Height), (int)(innerLayoutGroup.Rect.Height - multiplier * (GUI.IntScale(15f) + absoluteSpacing)));
|
||||||
infoFrameHolder = new GUIFrame(new RectTransform(new Point(innerLayoutGroup.Rect.Width, infoFrameHolderHeight), parent: innerLayoutGroup.RectTransform), style: null);
|
infoFrameHolder = new GUIFrame(new RectTransform(new Point(innerLayoutGroup.Rect.Width, infoFrameHolderHeight), parent: innerLayoutGroup.RectTransform), style: null);
|
||||||
|
|
||||||
var crewButton = new GUIButton(new RectTransform(new Vector2(0.245f, 1.0f), buttonArea.RectTransform), TextManager.Get("Crew"), style: "GUITabButton")
|
GUIButton createTabButton(InfoFrameTab tab, string textTag)
|
||||||
{
|
{
|
||||||
UserData = InfoFrameTab.Crew,
|
var newButton = new GUIButton(new RectTransform(Vector2.One, buttonArea.RectTransform, scaleBasis: ScaleBasis.BothWidth), style: $"InfoFrameTabButton.{tab}")
|
||||||
OnClicked = SelectInfoFrameTab
|
{
|
||||||
};
|
UserData = tab,
|
||||||
tabButtons.Add(crewButton);
|
ToolTip = TextManager.Get(textTag),
|
||||||
|
OnClicked = SelectInfoFrameTab
|
||||||
|
};
|
||||||
|
tabButtons.Add(newButton);
|
||||||
|
return newButton;
|
||||||
|
}
|
||||||
|
|
||||||
var missionButton = new GUIButton(new RectTransform(new Vector2(0.245f, 1.0f), buttonArea.RectTransform), TextManager.Get("Mission"), style: "GUITabButton")
|
var crewButton = createTabButton(InfoFrameTab.Crew, "crew");
|
||||||
{
|
|
||||||
UserData = InfoFrameTab.Mission,
|
var missionButton = createTabButton(InfoFrameTab.Mission, "mission");
|
||||||
OnClicked = SelectInfoFrameTab
|
|
||||||
};
|
|
||||||
tabButtons.Add(missionButton);
|
|
||||||
|
|
||||||
if (GameMain.GameSession?.GameMode is CampaignMode campaignMode)
|
if (GameMain.GameSession?.GameMode is CampaignMode campaignMode)
|
||||||
{
|
{
|
||||||
var reputationButton = new GUIButton(new RectTransform(new Vector2(0.245f, 1.0f), buttonArea.RectTransform), TextManager.Get("reputation"), style: "GUITabButton")
|
var reputationButton = createTabButton(InfoFrameTab.Reputation, "reputation");
|
||||||
{
|
|
||||||
UserData = InfoFrameTab.Reputation,
|
|
||||||
OnClicked = SelectInfoFrameTab
|
|
||||||
};
|
|
||||||
tabButtons.Add(reputationButton);
|
|
||||||
|
|
||||||
var balanceFrame = new GUIFrame(new RectTransform(new Point(buttonArea.RectTransform.NonScaledSize.X, (int)(buttonArea.RectTransform.NonScaledSize.Y * 1.5f)), parent: innerLayoutGroup.RectTransform), style: "InnerFrame");
|
var submarineButton = createTabButton(InfoFrameTab.Submarine, "submarine");
|
||||||
|
|
||||||
|
var balanceFrame = new GUIFrame(new RectTransform(new Point(innerLayoutGroup.Rect.Width, innerLayoutGroup.Rect.Height - infoFrameHolderHeight), parent: innerLayoutGroup.RectTransform), style: "InnerFrame");
|
||||||
new GUITextBlock(new RectTransform(Vector2.One, balanceFrame.RectTransform), "", textAlignment: Alignment.Right, parseRichText: true)
|
new GUITextBlock(new RectTransform(Vector2.One, balanceFrame.RectTransform), "", textAlignment: Alignment.Right, parseRichText: true)
|
||||||
{
|
{
|
||||||
TextGetter = () => TextManager.GetWithVariable("campaignmoney", "[money]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", campaignMode.Money))
|
TextGetter = () => TextManager.GetWithVariable("campaignmoney", "[money]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", campaignMode.Money))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
else
|
||||||
bool isTraitor = GameMain.Client?.Character?.IsTraitor ?? false;
|
|
||||||
if (isTraitor && GameMain.Client.TraitorMission != null)
|
|
||||||
{
|
{
|
||||||
var traitorButton = new GUIButton(new RectTransform(new Vector2(0.245f, 1.0f), buttonArea.RectTransform), TextManager.Get("tabmenu.traitor"), style: "GUITabButton")
|
bool isTraitor = GameMain.Client?.Character?.IsTraitor ?? false;
|
||||||
|
if (isTraitor && GameMain.Client.TraitorMission != null)
|
||||||
{
|
{
|
||||||
UserData = InfoFrameTab.Traitor,
|
var traitorButton = createTabButton(InfoFrameTab.Traitor, "tabmenu.traitor");
|
||||||
OnClicked = SelectInfoFrameTab
|
}
|
||||||
};
|
|
||||||
tabButtons.Add(traitorButton);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GameMain.NetworkMember != null)
|
if (GameMain.NetworkMember != null)
|
||||||
{
|
{
|
||||||
var myCharacterButton = new GUIButton(new RectTransform(new Vector2(0.245f, 1.0f), buttonArea.RectTransform), TextManager.Get("tabmenu.character"), style: "GUITabButton")
|
var myCharacterButton = createTabButton(InfoFrameTab.MyCharacter, "tabmenu.character");
|
||||||
{
|
|
||||||
UserData = InfoFrameTab.MyCharacter,
|
|
||||||
OnClicked = SelectInfoFrameTab
|
|
||||||
};
|
|
||||||
tabButtons.Add(myCharacterButton);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,6 +290,9 @@ namespace Barotrauma
|
|||||||
if (GameMain.NetworkMember == null) { return false; }
|
if (GameMain.NetworkMember == null) { return false; }
|
||||||
GameMain.NetLobbyScreen.CreatePlayerFrame(infoFrameHolder);
|
GameMain.NetLobbyScreen.CreatePlayerFrame(infoFrameHolder);
|
||||||
break;
|
break;
|
||||||
|
case InfoFrameTab.Submarine:
|
||||||
|
CreateSubmarineInfo(infoFrameHolder, Submarine.MainSub);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -879,13 +884,16 @@ namespace Barotrauma
|
|||||||
UserData = line
|
UserData = line
|
||||||
};
|
};
|
||||||
textBlock.CalculateHeightFromText();
|
textBlock.CalculateHeightFromText();
|
||||||
foreach (var data in textBlock.RichTextData)
|
if (textBlock.HasColorHighlight)
|
||||||
{
|
{
|
||||||
textBlock.ClickableAreas.Add(new GUITextBlock.ClickableArea()
|
foreach (var data in textBlock.RichTextData)
|
||||||
{
|
{
|
||||||
Data = data,
|
textBlock.ClickableAreas.Add(new GUITextBlock.ClickableArea()
|
||||||
OnClick = GameMain.NetLobbyScreen.SelectPlayer
|
{
|
||||||
});
|
Data = data,
|
||||||
|
OnClick = GameMain.NetLobbyScreen.SelectPlayer
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -930,27 +938,38 @@ namespace Barotrauma
|
|||||||
foreach (Mission mission in GameMain.GameSession.Missions)
|
foreach (Mission mission in GameMain.GameSession.Missions)
|
||||||
{
|
{
|
||||||
GUIFrame missionDescriptionHolder = new GUIFrame(new RectTransform(Vector2.One, missionList.Content.RectTransform), style: null);
|
GUIFrame missionDescriptionHolder = new GUIFrame(new RectTransform(Vector2.One, missionList.Content.RectTransform), style: null);
|
||||||
GUILayoutGroup missionTextGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.744f, 0f), missionDescriptionHolder.RectTransform, Anchor.CenterLeft) { RelativeOffset = new Vector2(0.225f, 0f) }, false, childAnchor: Anchor.TopLeft);
|
GUILayoutGroup missionTextGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.744f, 0f), missionDescriptionHolder.RectTransform, Anchor.CenterLeft) { RelativeOffset = new Vector2(0.225f, 0f) }, false, childAnchor: Anchor.TopLeft)
|
||||||
|
{
|
||||||
|
AbsoluteSpacing = GUI.IntScale(5)
|
||||||
|
};
|
||||||
|
string descriptionText = mission.Description;
|
||||||
|
foreach (string missionMessage in mission.ShownMessages)
|
||||||
|
{
|
||||||
|
descriptionText += "\n\n" + missionMessage;
|
||||||
|
}
|
||||||
string rewardText = mission.GetMissionRewardText();
|
string rewardText = mission.GetMissionRewardText();
|
||||||
string reputationText = mission.GetReputationRewardText(mission.Locations[0]);
|
string reputationText = mission.GetReputationRewardText(mission.Locations[0]);
|
||||||
|
|
||||||
var missionNameRichTextData = RichTextData.GetRichTextData(mission.Name, out string missionNameString);
|
var missionNameRichTextData = RichTextData.GetRichTextData(mission.Name, out string missionNameString);
|
||||||
var missionDescriptionRichTextData = RichTextData.GetRichTextData(mission.Description, out string missionDescriptionString);
|
|
||||||
var missionRewardRichTextData = RichTextData.GetRichTextData(rewardText, out string missionRewardString);
|
var missionRewardRichTextData = RichTextData.GetRichTextData(rewardText, out string missionRewardString);
|
||||||
var missionReputationRichTextData = RichTextData.GetRichTextData(reputationText, out string missionReputationString);
|
var missionReputationRichTextData = RichTextData.GetRichTextData(reputationText, out string missionReputationString);
|
||||||
|
var missionDescriptionRichTextData = RichTextData.GetRichTextData(descriptionText, out string missionDescriptionString);
|
||||||
|
|
||||||
missionNameString = ToolBox.WrapText(missionNameString, missionTextGroup.Rect.Width, GUI.LargeFont);
|
missionNameString = ToolBox.WrapText(missionNameString, missionTextGroup.Rect.Width, GUI.LargeFont);
|
||||||
missionDescriptionString = ToolBox.WrapText(missionDescriptionString, missionTextGroup.Rect.Width, GUI.Font);
|
|
||||||
missionRewardString = ToolBox.WrapText(missionRewardString, missionTextGroup.Rect.Width, GUI.Font);
|
missionRewardString = ToolBox.WrapText(missionRewardString, missionTextGroup.Rect.Width, GUI.Font);
|
||||||
missionReputationString = ToolBox.WrapText(missionReputationString, missionTextGroup.Rect.Width, GUI.Font);
|
missionReputationString = ToolBox.WrapText(missionReputationString, missionTextGroup.Rect.Width, GUI.Font);
|
||||||
|
missionDescriptionString = ToolBox.WrapText(missionDescriptionString, missionTextGroup.Rect.Width, GUI.Font);
|
||||||
|
|
||||||
Vector2 missionNameSize = GUI.LargeFont.MeasureString(missionNameString);
|
Vector2 missionNameSize = GUI.LargeFont.MeasureString(missionNameString);
|
||||||
Vector2 missionDescriptionSize = GUI.Font.MeasureString(missionDescriptionString);
|
Vector2 missionDescriptionSize = GUI.Font.MeasureString(missionDescriptionString);
|
||||||
Vector2 missionRewardSize = GUI.Font.MeasureString(missionRewardString);
|
Vector2 missionRewardSize = GUI.Font.MeasureString(missionRewardString);
|
||||||
Vector2 missionReputationSize = GUI.Font.MeasureString(missionReputationString);
|
Vector2 missionReputationSize = GUI.Font.MeasureString(missionReputationString);
|
||||||
|
|
||||||
missionDescriptionHolder.RectTransform.NonScaledSize = new Point(missionDescriptionHolder.RectTransform.NonScaledSize.X, (int)(missionNameSize.Y + missionDescriptionSize.Y + missionRewardSize.Y + missionReputationSize.Y));
|
float ySize = missionNameSize.Y + missionDescriptionSize.Y + missionRewardSize.Y + missionReputationSize.Y + missionTextGroup.AbsoluteSpacing * 4;
|
||||||
|
bool displayDifficulty = mission.Difficulty.HasValue;
|
||||||
|
if (displayDifficulty) { ySize += missionRewardSize.Y; }
|
||||||
|
|
||||||
|
missionDescriptionHolder.RectTransform.NonScaledSize = new Point(missionDescriptionHolder.RectTransform.NonScaledSize.X, (int)ySize);
|
||||||
missionTextGroup.RectTransform.NonScaledSize = new Point(missionTextGroup.RectTransform.NonScaledSize.X, missionDescriptionHolder.RectTransform.NonScaledSize.Y);
|
missionTextGroup.RectTransform.NonScaledSize = new Point(missionTextGroup.RectTransform.NonScaledSize.X, missionDescriptionHolder.RectTransform.NonScaledSize.Y);
|
||||||
|
|
||||||
if (mission.Prefab.Icon != null)
|
if (mission.Prefab.Icon != null)
|
||||||
@@ -960,10 +979,38 @@ namespace Barotrauma
|
|||||||
int iconHeight = Math.Max(missionTextGroup.RectTransform.NonScaledSize.Y, (int)(iconWidth * iconAspectRatio));
|
int iconHeight = Math.Max(missionTextGroup.RectTransform.NonScaledSize.Y, (int)(iconWidth * iconAspectRatio));
|
||||||
Point iconSize = new Point(iconWidth, iconHeight);
|
Point iconSize = new Point(iconWidth, iconHeight);
|
||||||
|
|
||||||
new GUIImage(new RectTransform(iconSize, missionDescriptionHolder.RectTransform), mission.Prefab.Icon, null, true) { Color = mission.Prefab.IconColor, CanBeFocused = false };
|
new GUIImage(new RectTransform(iconSize, missionDescriptionHolder.RectTransform), mission.Prefab.Icon, null, true)
|
||||||
|
{
|
||||||
|
Color = mission.Prefab.IconColor,
|
||||||
|
HoverColor = mission.Prefab.IconColor,
|
||||||
|
SelectedColor = mission.Prefab.IconColor,
|
||||||
|
CanBeFocused = false
|
||||||
|
};
|
||||||
}
|
}
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionNameRichTextData, missionNameString, font: GUI.LargeFont);
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionNameRichTextData, missionNameString, font: GUI.LargeFont);
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionRewardRichTextData, missionRewardString);
|
GUILayoutGroup difficultyIndicatorGroup = null;
|
||||||
|
if (displayDifficulty)
|
||||||
|
{
|
||||||
|
difficultyIndicatorGroup = new GUILayoutGroup(new RectTransform(new Point(missionTextGroup.Rect.Width, (int)missionRewardSize.Y), parent: missionTextGroup.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
||||||
|
{
|
||||||
|
AbsoluteSpacing = 1
|
||||||
|
};
|
||||||
|
var difficultyColor = mission.GetDifficultyColor();
|
||||||
|
for (int i = 0; i < mission.Difficulty.Value; i++)
|
||||||
|
{
|
||||||
|
new GUIImage(new RectTransform(Vector2.One, difficultyIndicatorGroup.RectTransform, scaleBasis: ScaleBasis.Smallest), "DifficultyIndicator", scaleToFit: true)
|
||||||
|
{
|
||||||
|
CanBeFocused = false,
|
||||||
|
Color = difficultyColor
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var rewardTextBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionRewardRichTextData, missionRewardString);
|
||||||
|
if (difficultyIndicatorGroup != null)
|
||||||
|
{
|
||||||
|
difficultyIndicatorGroup.RectTransform.Resize(new Point((int)(difficultyIndicatorGroup.Rect.Width - rewardTextBlock.Padding.X - rewardTextBlock.Padding.Z), difficultyIndicatorGroup.Rect.Height));
|
||||||
|
difficultyIndicatorGroup.RectTransform.AbsoluteOffset = new Point((int)rewardTextBlock.Padding.X, 0);
|
||||||
|
}
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionReputationRichTextData, missionReputationString);
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionReputationRichTextData, missionReputationString);
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionDescriptionRichTextData, missionDescriptionString);
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionDescriptionRichTextData, missionDescriptionString);
|
||||||
}
|
}
|
||||||
@@ -1004,5 +1051,84 @@ namespace Barotrauma
|
|||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionNameString, font: GUI.LargeFont);
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionNameString, font: GUI.LargeFont);
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionDescriptionString);
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionDescriptionString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CreateSubmarineInfo(GUIFrame infoFrame, Submarine sub)
|
||||||
|
{
|
||||||
|
GUIFrame subInfoFrame = new GUIFrame(new RectTransform(Vector2.One, infoFrame.RectTransform, Anchor.TopCenter), style: "GUIFrameListBox");
|
||||||
|
GUIFrame paddedFrame = new GUIFrame(new RectTransform(Vector2.One * 0.97f, subInfoFrame.RectTransform, Anchor.Center), style: null);
|
||||||
|
|
||||||
|
var previewButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.43f), paddedFrame.RectTransform), style: null)
|
||||||
|
{
|
||||||
|
OnClicked = (btn, obj) => { SubmarinePreview.Create(sub.Info); return false; },
|
||||||
|
};
|
||||||
|
|
||||||
|
var previewImage = sub.Info.PreviewImage ?? SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.Name.Equals(sub.Info.Name, StringComparison.OrdinalIgnoreCase))?.PreviewImage;
|
||||||
|
if (previewImage == null)
|
||||||
|
{
|
||||||
|
new GUITextBlock(new RectTransform(Vector2.One, previewButton.RectTransform), TextManager.Get("SubPreviewImageNotFound"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var submarinePreviewBackground = new GUIFrame(new RectTransform(Vector2.One, previewButton.RectTransform), style: null)
|
||||||
|
{
|
||||||
|
Color = Color.Black,
|
||||||
|
HoverColor = Color.Black,
|
||||||
|
SelectedColor = Color.Black,
|
||||||
|
PressedColor = Color.Black,
|
||||||
|
CanBeFocused = false,
|
||||||
|
};
|
||||||
|
new GUIImage(new RectTransform(new Vector2(0.98f), submarinePreviewBackground.RectTransform, Anchor.Center), previewImage, scaleToFit: true) { CanBeFocused = false };
|
||||||
|
new GUIFrame(new RectTransform(Vector2.One, submarinePreviewBackground.RectTransform), "InnerGlow", color: Color.Black) { CanBeFocused = false };
|
||||||
|
}
|
||||||
|
|
||||||
|
new GUIFrame(new RectTransform(Vector2.One * 0.12f, previewButton.RectTransform, anchor: Anchor.BottomRight, pivot: Pivot.BottomRight, scaleBasis: ScaleBasis.BothHeight)
|
||||||
|
{
|
||||||
|
AbsoluteOffset = new Point((int)(0.03f * previewButton.Rect.Height))
|
||||||
|
},
|
||||||
|
"ExpandButton", Color.White)
|
||||||
|
{
|
||||||
|
Color = Color.White,
|
||||||
|
HoverColor = Color.White,
|
||||||
|
PressedColor = Color.White
|
||||||
|
};
|
||||||
|
|
||||||
|
var subInfoTextLayout = new GUILayoutGroup(new RectTransform(Vector2.One, paddedFrame.RectTransform));
|
||||||
|
|
||||||
|
string className = !sub.Info.HasTag(SubmarineTag.Shuttle) ? TextManager.Get($"submarineclass.{sub.Info.SubmarineClass}") : TextManager.Get("shuttle");
|
||||||
|
|
||||||
|
int nameHeight = (int)GUI.LargeFont.MeasureString(sub.Info.DisplayName, true).Y;
|
||||||
|
int classHeight = (int)GUI.SubHeadingFont.MeasureString(className).Y;
|
||||||
|
|
||||||
|
var submarineNameText = new GUITextBlock(new RectTransform(new Point(subInfoTextLayout.Rect.Width, nameHeight + HUDLayoutSettings.Padding / 2), subInfoTextLayout.RectTransform), sub.Info.DisplayName, textAlignment: Alignment.CenterLeft, font: GUI.LargeFont) { CanBeFocused = false };
|
||||||
|
submarineNameText.RectTransform.MinSize = new Point(0, (int)submarineNameText.TextSize.Y);
|
||||||
|
var submarineClassText = new GUITextBlock(new RectTransform(new Point(subInfoTextLayout.Rect.Width, classHeight), subInfoTextLayout.RectTransform), className, textAlignment: Alignment.CenterLeft, font: GUI.SubHeadingFont) { CanBeFocused = false };
|
||||||
|
submarineClassText.RectTransform.MinSize = new Point(0, (int)submarineClassText.TextSize.Y);
|
||||||
|
|
||||||
|
if (GameMain.GameSession?.GameMode is CampaignMode campaign)
|
||||||
|
{
|
||||||
|
var upgradeRootLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.57f), paddedFrame.RectTransform, Anchor.BottomLeft, Pivot.BottomLeft), true);
|
||||||
|
|
||||||
|
var upgradeCategoryPanel = UpgradeStore.CreateUpgradeCategoryList(new RectTransform(new Vector2(0.4f, 1f), upgradeRootLayout.RectTransform));
|
||||||
|
upgradeCategoryPanel.HideChildrenOutsideFrame = true;
|
||||||
|
UpgradeStore.UpdateCategoryList(upgradeCategoryPanel, campaign, sub, UpgradeStore.GetApplicableCategories(sub).ToArray());
|
||||||
|
GUIComponent[] toRemove = upgradeCategoryPanel.Content.FindChildren(c => !c.Enabled).ToArray();
|
||||||
|
toRemove.ForEach(c => upgradeCategoryPanel.RemoveChild(c));
|
||||||
|
|
||||||
|
var upgradePanel = new GUIListBox(new RectTransform(new Vector2(0.6f, 1f), upgradeRootLayout.RectTransform));
|
||||||
|
upgradeCategoryPanel.OnSelected = (component, userData) =>
|
||||||
|
{
|
||||||
|
upgradePanel.ClearChildren();
|
||||||
|
if (userData is UpgradeStore.CategoryData categoryData && Submarine.MainSub != null)
|
||||||
|
{
|
||||||
|
foreach (UpgradePrefab prefab in categoryData.Prefabs)
|
||||||
|
{
|
||||||
|
var frame = UpgradeStore.CreateUpgradeFrame(prefab, categoryData.Category, campaign, new RectTransform(new Vector2(1f, 0.3f), upgradePanel.Content.RectTransform), addBuyButton: false);
|
||||||
|
UpgradeStore.UpdateUpgradeEntry(frame, prefab, categoryData.Category, campaign);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
internal class UpgradeStore
|
internal class UpgradeStore
|
||||||
{
|
{
|
||||||
private readonly struct CategoryData
|
public readonly struct CategoryData
|
||||||
{
|
{
|
||||||
public readonly UpgradeCategory Category;
|
public readonly UpgradeCategory Category;
|
||||||
public readonly List<UpgradePrefab> Prefabs;
|
public readonly List<UpgradePrefab> Prefabs;
|
||||||
@@ -125,7 +125,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (component.UserData is CategoryData data)
|
if (component.UserData is CategoryData data)
|
||||||
{
|
{
|
||||||
UpdateUpgradeEntry(component, data.SinglePrefab, data.Category);
|
UpdateUpgradeEntry(component, data.SinglePrefab, data.Category, Campaign);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,29 +133,35 @@ namespace Barotrauma
|
|||||||
// update the small indicator icons on the list
|
// update the small indicator icons on the list
|
||||||
if (currentStoreLayout?.Parent != null)
|
if (currentStoreLayout?.Parent != null)
|
||||||
{
|
{
|
||||||
foreach (GUIComponent component in currentStoreLayout.Content.Children)
|
UpdateCategoryList(currentStoreLayout, Campaign, drawnSubmarine, applicableCategories);
|
||||||
{
|
}
|
||||||
if (!(component.UserData is CategoryData data)) { continue; }
|
}
|
||||||
if (component.FindChild("indicators", true) is { } indicators)
|
|
||||||
{
|
|
||||||
UpdateCategoryIndicators(indicators, component, data.Prefabs, data.Category);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// reset the order first
|
//TODO: move this somewhere else
|
||||||
foreach (UpgradeCategory category in UpgradeCategory.Categories)
|
public static void UpdateCategoryList(GUIListBox categoryList, CampaignMode campaign, Submarine drawnSubmarine, IEnumerable<UpgradeCategory> applicableCategories)
|
||||||
|
{
|
||||||
|
foreach (GUIComponent component in categoryList.Content.Children)
|
||||||
|
{
|
||||||
|
if (!(component.UserData is CategoryData data)) { continue; }
|
||||||
|
if (component.FindChild("indicators", true) is { } indicators)
|
||||||
{
|
{
|
||||||
GUIComponent component = currentStoreLayout.Content.FindChild(c => c.UserData is CategoryData categoryData && categoryData.Category == category);
|
UpdateCategoryIndicators(indicators, component, data.Prefabs, data.Category, campaign, drawnSubmarine, applicableCategories);
|
||||||
component?.SetAsLastChild();
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// send the disabled components to the bottom
|
// reset the order first
|
||||||
List<GUIComponent> lastChilds = currentStoreLayout.Content.Children.Where(component => !component.Enabled).ToList();
|
foreach (UpgradeCategory category in UpgradeCategory.Categories)
|
||||||
|
{
|
||||||
|
GUIComponent component = categoryList.Content.FindChild(c => c.UserData is CategoryData categoryData && categoryData.Category == category);
|
||||||
|
component?.SetAsLastChild();
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var lastChild in lastChilds)
|
// send the disabled components to the bottom
|
||||||
{
|
List<GUIComponent> lastChilds = categoryList.Content.Children.Where(component => !component.Enabled).ToList();
|
||||||
lastChild.SetAsLastChild();
|
|
||||||
}
|
foreach (var lastChild in lastChilds)
|
||||||
|
{
|
||||||
|
lastChild.SetAsLastChild();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -511,9 +517,10 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateUpgradeTab()
|
//TODO: put this somewhere else
|
||||||
|
public static GUIListBox CreateUpgradeCategoryList(RectTransform rectTransform)
|
||||||
{
|
{
|
||||||
currentStoreLayout = new GUIListBox(rectT(1.0f, 1.5f, storeLayout), style: null)
|
var upgradeCategoryList = new GUIListBox(rectTransform, style: null)
|
||||||
{
|
{
|
||||||
AutoHideScrollBar = false,
|
AutoHideScrollBar = false,
|
||||||
ScrollBarVisible = false,
|
ScrollBarVisible = false,
|
||||||
@@ -548,7 +555,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
foreach (var (category, prefabs) in upgrades)
|
foreach (var (category, prefabs) in upgrades)
|
||||||
{
|
{
|
||||||
var frameChild = new GUIFrame(rectT(1, 0.15f, currentStoreLayout.Content), style: "UpgradeUIFrame")
|
var frameChild = new GUIFrame(rectT(1, 0.15f, upgradeCategoryList.Content), style: "UpgradeUIFrame")
|
||||||
{
|
{
|
||||||
UserData = new CategoryData(category, prefabs),
|
UserData = new CategoryData(category, prefabs),
|
||||||
GlowOnSelect = true
|
GlowOnSelect = true
|
||||||
@@ -565,8 +572,8 @@ namespace Barotrauma
|
|||||||
* |-----------------------------|--------------------------|
|
* |-----------------------------|--------------------------|
|
||||||
*/
|
*/
|
||||||
GUILayoutGroup contentLayout = new GUILayoutGroup(rectT(0.9f, 0.85f, frameChild, Anchor.Center));
|
GUILayoutGroup contentLayout = new GUILayoutGroup(rectT(0.9f, 0.85f, frameChild, Anchor.Center));
|
||||||
var itemCategoryLabel = new GUITextBlock(rectT(1, 1, contentLayout), category.Name, font: GUI.SubHeadingFont) { CanBeFocused = false };
|
var itemCategoryLabel = new GUITextBlock(rectT(1, 1, contentLayout), category.Name, font: GUI.SubHeadingFont) { CanBeFocused = false };
|
||||||
GUILayoutGroup indicatorLayout = new GUILayoutGroup(rectT(0.5f, 0.25f, contentLayout, Anchor.BottomRight), isHorizontal: true, childAnchor: Anchor.TopRight) { UserData = "indicators", IgnoreLayoutGroups = true, RelativeSpacing = 0.01f };
|
GUILayoutGroup indicatorLayout = new GUILayoutGroup(rectT(0.5f, 0.25f, contentLayout, Anchor.BottomRight), isHorizontal: true, childAnchor: Anchor.TopRight) { UserData = "indicators", IgnoreLayoutGroups = true, RelativeSpacing = 0.01f };
|
||||||
|
|
||||||
foreach (var prefab in prefabs)
|
foreach (var prefab in prefabs)
|
||||||
{
|
{
|
||||||
@@ -582,6 +589,13 @@ namespace Barotrauma
|
|||||||
indicatorLayout.Recalculate();
|
indicatorLayout.Recalculate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return upgradeCategoryList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CreateUpgradeTab()
|
||||||
|
{
|
||||||
|
currentStoreLayout = CreateUpgradeCategoryList(rectT(1.0f, 1.5f, storeLayout));
|
||||||
|
|
||||||
selectedUpgradeCategoryLayout = new GUIFrame(rectT(GUI.IsFourByThree() ? 0.3f : 0.25f, 1, mainStoreLayout), style: null) { CanBeFocused = false };
|
selectedUpgradeCategoryLayout = new GUIFrame(rectT(GUI.IsFourByThree() ? 0.3f : 0.25f, 1, mainStoreLayout), style: null) { CanBeFocused = false };
|
||||||
|
|
||||||
RefreshUpgradeList();
|
RefreshUpgradeList();
|
||||||
@@ -637,7 +651,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateUpgradeEntry(UpgradePrefab prefab, UpgradeCategory category, GUIComponent parent, List<Item> itemsOnSubmarine)
|
public static GUIFrame CreateUpgradeFrame(UpgradePrefab prefab, UpgradeCategory category, CampaignMode campaign, RectTransform rectTransform, bool addBuyButton = true)
|
||||||
{
|
{
|
||||||
/* UPGRADE PREFAB ENTRY
|
/* UPGRADE PREFAB ENTRY
|
||||||
* |------------------------------------------------------------------|
|
* |------------------------------------------------------------------|
|
||||||
@@ -648,8 +662,8 @@ namespace Barotrauma
|
|||||||
* | | progress bar | x / y | |
|
* | | progress bar | x / y | |
|
||||||
* |------------------------------------------------------------------|
|
* |------------------------------------------------------------------|
|
||||||
*/
|
*/
|
||||||
GUIFrame prefabFrame = new GUIFrame(rectT(1f, 0.25f, parent), style: "ListBoxElement") { SelectedColor = Color.Transparent, UserData = new CategoryData(category, prefab) };
|
GUIFrame prefabFrame = new GUIFrame(rectTransform, style: "ListBoxElement") { SelectedColor = Color.Transparent, UserData = new CategoryData(category, prefab) };
|
||||||
GUILayoutGroup prefabLayout = new GUILayoutGroup(rectT(0.98f,0.95f, prefabFrame, Anchor.Center), isHorizontal: true);
|
GUILayoutGroup prefabLayout = new GUILayoutGroup(rectT(0.98f, 0.95f, prefabFrame, Anchor.Center), isHorizontal: true) { Stretch = true };
|
||||||
GUILayoutGroup imageLayout = new GUILayoutGroup(rectT(new Point(prefabLayout.Rect.Height, prefabLayout.Rect.Height), prefabLayout), childAnchor: Anchor.Center);
|
GUILayoutGroup imageLayout = new GUILayoutGroup(rectT(new Point(prefabLayout.Rect.Height, prefabLayout.Rect.Height), prefabLayout), childAnchor: Anchor.Center);
|
||||||
var icon = new GUIImage(rectT(0.9f, 0.9f, imageLayout), prefab.Sprite, scaleToFit: true) { CanBeFocused = false };
|
var icon = new GUIImage(rectT(0.9f, 0.9f, imageLayout), prefab.Sprite, scaleToFit: true) { CanBeFocused = false };
|
||||||
GUILayoutGroup textLayout = new GUILayoutGroup(rectT(0.8f - imageLayout.RectTransform.RelativeSize.X, 1, prefabLayout));
|
GUILayoutGroup textLayout = new GUILayoutGroup(rectT(0.8f - imageLayout.RectTransform.RelativeSize.X, 1, prefabLayout));
|
||||||
@@ -659,9 +673,13 @@ namespace Barotrauma
|
|||||||
GUILayoutGroup progressLayout = new GUILayoutGroup(rectT(1, 0.25f, textLayout), isHorizontal: true, childAnchor: Anchor.CenterLeft) { UserData = "progressbar" };
|
GUILayoutGroup progressLayout = new GUILayoutGroup(rectT(1, 0.25f, textLayout), isHorizontal: true, childAnchor: Anchor.CenterLeft) { UserData = "progressbar" };
|
||||||
new GUIProgressBar(rectT(0.8f, 0.75f, progressLayout), 0.0f, GUI.Style.Orange);
|
new GUIProgressBar(rectT(0.8f, 0.75f, progressLayout), 0.0f, GUI.Style.Orange);
|
||||||
new GUITextBlock(rectT(0.2f, 1, progressLayout), string.Empty, font: GUI.SmallFont, textAlignment: Alignment.Center) { Padding = Vector4.Zero };
|
new GUITextBlock(rectT(0.2f, 1, progressLayout), string.Empty, font: GUI.SmallFont, textAlignment: Alignment.Center) { Padding = Vector4.Zero };
|
||||||
GUILayoutGroup buyButtonLayout = new GUILayoutGroup(rectT(0.2f, 1, prefabLayout), childAnchor: Anchor.TopCenter) { UserData = "buybutton" };
|
GUILayoutGroup buyButtonLayout = null;
|
||||||
new GUITextBlock(rectT(1, 0.4f, buyButtonLayout), FormatCurrency(prefab.Price.GetBuyprice(Campaign.UpgradeManager.GetUpgradeLevel(prefab, category), Campaign.Map?.CurrentLocation)), textAlignment: Alignment.Center) { Padding = Vector4.Zero };
|
if (addBuyButton)
|
||||||
|
{
|
||||||
|
buyButtonLayout = new GUILayoutGroup(rectT(0.2f, 1, prefabLayout), childAnchor: Anchor.TopCenter) { UserData = "buybutton" };
|
||||||
|
new GUITextBlock(rectT(1, 0.4f, buyButtonLayout), FormatCurrency(prefab.Price.GetBuyprice(campaign.UpgradeManager.GetUpgradeLevel(prefab, category), campaign.Map?.CurrentLocation)), textAlignment: Alignment.Center) { Padding = Vector4.Zero };
|
||||||
var buyButton = new GUIButton(rectT(0.7f, 0.5f, buyButtonLayout), string.Empty, style: "UpgradeBuyButton") { Enabled = false };
|
var buyButton = new GUIButton(rectT(0.7f, 0.5f, buyButtonLayout), string.Empty, style: "UpgradeBuyButton") { Enabled = false };
|
||||||
|
}
|
||||||
|
|
||||||
description.CalculateHeightFromText();
|
description.CalculateHeightFromText();
|
||||||
// cut the description if it overflows and add a tooltip to it
|
// cut the description if it overflows and add a tooltip to it
|
||||||
@@ -677,14 +695,33 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Recalculate everything to prevent jumping
|
// Recalculate everything to prevent jumping
|
||||||
if (parent is GUILayoutGroup group) { group.Recalculate(); }
|
if (rectTransform.Parent.GUIComponent is GUILayoutGroup group) { group.Recalculate(); }
|
||||||
|
|
||||||
descriptionLayout.Recalculate();
|
descriptionLayout.Recalculate();
|
||||||
prefabLayout.Recalculate();
|
prefabLayout.Recalculate();
|
||||||
imageLayout.Recalculate();
|
imageLayout.Recalculate();
|
||||||
textLayout.Recalculate();
|
textLayout.Recalculate();
|
||||||
progressLayout.Recalculate();
|
progressLayout.Recalculate();
|
||||||
buyButtonLayout.Recalculate();
|
buyButtonLayout?.Recalculate();
|
||||||
|
|
||||||
|
return prefabFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CreateUpgradeEntry(UpgradePrefab prefab, UpgradeCategory category, GUIComponent parent, List<Item> itemsOnSubmarine)
|
||||||
|
{
|
||||||
|
GUIFrame prefabFrame = CreateUpgradeFrame(prefab, category, Campaign, rectT(1f, 0.25f, parent));
|
||||||
|
var prefabLayout = prefabFrame.GetChild<GUILayoutGroup>();
|
||||||
|
GUILayoutGroup[] childLayouts = prefabLayout.GetAllChildren<GUILayoutGroup>().ToArray();
|
||||||
|
var imageLayout = childLayouts[0];
|
||||||
|
var icon = imageLayout.GetChild<GUIImage>();
|
||||||
|
var textLayout = childLayouts[1];
|
||||||
|
var name = textLayout.GetChild<GUITextBlock>();
|
||||||
|
GUILayoutGroup[] textChildLayouts = textLayout.GetAllChildren<GUILayoutGroup>().ToArray();
|
||||||
|
var descriptionLayout = textChildLayouts[0];
|
||||||
|
var description = descriptionLayout.GetChild<GUITextBlock>();
|
||||||
|
var progressLayout = textChildLayouts[1];
|
||||||
|
var buyButtonLayout = childLayouts[2];
|
||||||
|
var buyButton = buyButtonLayout.GetChild<GUIButton>();
|
||||||
|
|
||||||
if (!HasPermission || itemsOnSubmarine != null && !itemsOnSubmarine.Any(it => category.CanBeApplied(it, prefab)))
|
if (!HasPermission || itemsOnSubmarine != null && !itemsOnSubmarine.Any(it => category.CanBeApplied(it, prefab)))
|
||||||
{
|
{
|
||||||
@@ -713,7 +750,7 @@ namespace Barotrauma
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
UpdateUpgradeEntry(prefabFrame, prefab, category);
|
UpdateUpgradeEntry(prefabFrame, prefab, category, Campaign);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateItemTooltip(MapEntity entity)
|
private void CreateItemTooltip(MapEntity entity)
|
||||||
@@ -778,6 +815,18 @@ namespace Barotrauma
|
|||||||
static string CreateListEntry(string name, int level) => TextManager.GetWithVariables("upgradeuitooltip.upgradelistelement", new[] { "[upgradename]", "[level]" }, new[] { name, $"{level}" });
|
static string CreateListEntry(string name, int level) => TextManager.GetWithVariables("upgradeuitooltip.upgradelistelement", new[] { "[upgradename]", "[level]" }, new[] { name, $"{level}" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<UpgradeCategory> GetApplicableCategories(Submarine drawnSubmarine)
|
||||||
|
{
|
||||||
|
Item[] entitiesOnSub = drawnSubmarine.GetItems(true).Where(i => drawnSubmarine.IsEntityFoundOnThisSub(i, true)).ToArray();
|
||||||
|
foreach (UpgradeCategory category in UpgradeCategory.Categories)
|
||||||
|
{
|
||||||
|
if (entitiesOnSub.Any(item => category.CanBeApplied(item, null)))
|
||||||
|
{
|
||||||
|
yield return category;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void UpdateSubmarinePreview(float deltaTime, GUICustomComponent parent)
|
private void UpdateSubmarinePreview(float deltaTime, GUICustomComponent parent)
|
||||||
{
|
{
|
||||||
if (!parent.Children.Any() || Submarine.MainSub != null && Submarine.MainSub != drawnSubmarine || GameMain.GraphicsWidth != screenResolution.X || GameMain.GraphicsHeight != screenResolution.Y)
|
if (!parent.Children.Any() || Submarine.MainSub != null && Submarine.MainSub != drawnSubmarine || GameMain.GraphicsWidth != screenResolution.X || GameMain.GraphicsHeight != screenResolution.Y)
|
||||||
@@ -789,16 +838,8 @@ namespace Barotrauma
|
|||||||
CreateSubmarinePreview(drawnSubmarine, parent);
|
CreateSubmarinePreview(drawnSubmarine, parent);
|
||||||
CreateHullBorderVerticies(drawnSubmarine, parent);
|
CreateHullBorderVerticies(drawnSubmarine, parent);
|
||||||
|
|
||||||
List<Item> entitiesOnSub = drawnSubmarine.GetItems(true).Where(i => drawnSubmarine.IsEntityFoundOnThisSub(i, true)).ToList();
|
|
||||||
applicableCategories.Clear();
|
applicableCategories.Clear();
|
||||||
|
applicableCategories.AddRange(GetApplicableCategories(drawnSubmarine));
|
||||||
foreach (UpgradeCategory category in UpgradeCategory.Categories)
|
|
||||||
{
|
|
||||||
if (entitiesOnSub.Any(item => category.CanBeApplied(item, null)))
|
|
||||||
{
|
|
||||||
applicableCategories.Add(category);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
screenResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
|
screenResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
|
||||||
@@ -1002,9 +1043,9 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateUpgradeEntry(GUIComponent prefabFrame, UpgradePrefab prefab, UpgradeCategory category)
|
public static void UpdateUpgradeEntry(GUIComponent prefabFrame, UpgradePrefab prefab, UpgradeCategory category, CampaignMode campaign)
|
||||||
{
|
{
|
||||||
int currentLevel = Campaign.UpgradeManager.GetUpgradeLevel(prefab, category);
|
int currentLevel = campaign.UpgradeManager.GetUpgradeLevel(prefab, category);
|
||||||
|
|
||||||
string progressText = TextManager.GetWithVariables("upgrades.progressformat", new[] { "[level]", "[maxlevel]" }, new[] { currentLevel.ToString(), prefab.MaxLevel.ToString() });
|
string progressText = TextManager.GetWithVariables("upgrades.progressformat", new[] { "[level]", "[maxlevel]" }, new[] { currentLevel.ToString(), prefab.MaxLevel.ToString() });
|
||||||
if (prefabFrame.FindChild("progressbar", true) is { } progressParent)
|
if (prefabFrame.FindChild("progressbar", true) is { } progressParent)
|
||||||
@@ -1023,7 +1064,7 @@ namespace Barotrauma
|
|||||||
if (prefabFrame.FindChild("buybutton", true) is { } buttonParent)
|
if (prefabFrame.FindChild("buybutton", true) is { } buttonParent)
|
||||||
{
|
{
|
||||||
GUITextBlock priceLabel = buttonParent.GetChild<GUITextBlock>();
|
GUITextBlock priceLabel = buttonParent.GetChild<GUITextBlock>();
|
||||||
int price = prefab.Price.GetBuyprice(Campaign.UpgradeManager.GetUpgradeLevel(prefab, category), Campaign.Map?.CurrentLocation);
|
int price = prefab.Price.GetBuyprice(campaign.UpgradeManager.GetUpgradeLevel(prefab, category), campaign.Map?.CurrentLocation);
|
||||||
|
|
||||||
if (priceLabel != null && !WaitForServerUpdate)
|
if (priceLabel != null && !WaitForServerUpdate)
|
||||||
{
|
{
|
||||||
@@ -1038,7 +1079,7 @@ namespace Barotrauma
|
|||||||
if (button != null)
|
if (button != null)
|
||||||
{
|
{
|
||||||
button.Enabled = currentLevel < prefab.MaxLevel;
|
button.Enabled = currentLevel < prefab.MaxLevel;
|
||||||
if (WaitForServerUpdate || !HasPermission || price > Campaign.Money)
|
if (WaitForServerUpdate || !campaign.AllowedToManageCampaign() || price > campaign.Money)
|
||||||
{
|
{
|
||||||
button.Enabled = false;
|
button.Enabled = false;
|
||||||
}
|
}
|
||||||
@@ -1046,7 +1087,14 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateCategoryIndicators(GUIComponent indicators, GUIComponent parent, List<UpgradePrefab> prefabs, UpgradeCategory category)
|
private static void UpdateCategoryIndicators(
|
||||||
|
GUIComponent indicators,
|
||||||
|
GUIComponent parent,
|
||||||
|
List<UpgradePrefab> prefabs,
|
||||||
|
UpgradeCategory category,
|
||||||
|
CampaignMode campaign,
|
||||||
|
Submarine drawnSubmarine,
|
||||||
|
IEnumerable<UpgradeCategory> applicableCategories)
|
||||||
{
|
{
|
||||||
// Disables the parent and only re-enables if the submarine contains valid items
|
// Disables the parent and only re-enables if the submarine contains valid items
|
||||||
if (!category.IsWallUpgrade && drawnSubmarine != null)
|
if (!category.IsWallUpgrade && drawnSubmarine != null)
|
||||||
@@ -1078,13 +1126,13 @@ namespace Barotrauma
|
|||||||
GUIComponentStyle dimStyle = styles["upgradeindicatordim"];
|
GUIComponentStyle dimStyle = styles["upgradeindicatordim"];
|
||||||
GUIComponentStyle offStyle = styles["upgradeindicatoroff"];
|
GUIComponentStyle offStyle = styles["upgradeindicatoroff"];
|
||||||
|
|
||||||
if (Campaign.UpgradeManager.GetUpgradeLevel(prefab, category) >= prefab.MaxLevel)
|
if (campaign.UpgradeManager.GetUpgradeLevel(prefab, category) >= prefab.MaxLevel)
|
||||||
{
|
{
|
||||||
// we check this to avoid flickering from re-applying the same style
|
// we check this to avoid flickering from re-applying the same style
|
||||||
if (image.Style == onStyle) { continue; }
|
if (image.Style == onStyle) { continue; }
|
||||||
image.ApplyStyle(onStyle);
|
image.ApplyStyle(onStyle);
|
||||||
}
|
}
|
||||||
else if (Campaign.UpgradeManager.GetUpgradeLevel(prefab, category) > 0)
|
else if (campaign.UpgradeManager.GetUpgradeLevel(prefab, category) > 0)
|
||||||
{
|
{
|
||||||
if (image.Style == dimStyle) { continue; }
|
if (image.Style == dimStyle) { continue; }
|
||||||
image.ApplyStyle(dimStyle);
|
image.ApplyStyle(dimStyle);
|
||||||
|
|||||||
@@ -1229,13 +1229,19 @@ namespace Barotrauma
|
|||||||
base.OnExiting(sender, args);
|
base.OnExiting(sender, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ShowOpenUrlInWebBrowserPrompt(string url)
|
public void ShowOpenUrlInWebBrowserPrompt(string url, string promptExtensionTag = null)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(url)) { return; }
|
if (string.IsNullOrEmpty(url)) { return; }
|
||||||
if (GUIMessageBox.VisibleBox?.UserData as string == "verificationprompt") { return; }
|
if (GUIMessageBox.VisibleBox?.UserData as string == "verificationprompt") { return; }
|
||||||
|
|
||||||
var msgBox = new GUIMessageBox("", TextManager.GetWithVariable("openlinkinbrowserprompt", "[link]", url),
|
string text = TextManager.GetWithVariable("openlinkinbrowserprompt", "[link]", url);
|
||||||
new string[] { TextManager.Get("Yes"), TextManager.Get("No") })
|
string extensionText = TextManager.Get(promptExtensionTag, returnNull: true, useEnglishAsFallBack: false);
|
||||||
|
if (!string.IsNullOrEmpty(extensionText))
|
||||||
|
{
|
||||||
|
text += $"\n\n{extensionText}";
|
||||||
|
}
|
||||||
|
|
||||||
|
var msgBox = new GUIMessageBox("", text, new string[] { TextManager.Get("Yes"), TextManager.Get("No") })
|
||||||
{
|
{
|
||||||
UserData = "verificationprompt"
|
UserData = "verificationprompt"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -168,6 +168,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
chatBox.ToggleButton = new GUIButton(new RectTransform(new Point((int)(182f * GUI.Scale * 0.4f), (int)(99f * GUI.Scale * 0.4f)), chatBox.GUIFrame.Parent.RectTransform), style: "ChatToggleButton")
|
chatBox.ToggleButton = new GUIButton(new RectTransform(new Point((int)(182f * GUI.Scale * 0.4f), (int)(99f * GUI.Scale * 0.4f)), chatBox.GUIFrame.Parent.RectTransform), style: "ChatToggleButton")
|
||||||
{
|
{
|
||||||
|
ToolTip = TextManager.Get("chat"),
|
||||||
ClampMouseRectToParent = false
|
ClampMouseRectToParent = false
|
||||||
};
|
};
|
||||||
chatBox.ToggleButton.RectTransform.AbsoluteOffset = new Point(0, HUDLayoutSettings.ChatBoxArea.Height - chatBox.ToggleButton.Rect.Height);
|
chatBox.ToggleButton.RectTransform.AbsoluteOffset = new Point(0, HUDLayoutSettings.ChatBoxArea.Height - chatBox.ToggleButton.Rect.Height);
|
||||||
@@ -289,19 +290,7 @@ namespace Barotrauma
|
|||||||
new RectTransform(crewListEntrySize, parent: crewList.Content.RectTransform, anchor: Anchor.TopRight),
|
new RectTransform(crewListEntrySize, parent: crewList.Content.RectTransform, anchor: Anchor.TopRight),
|
||||||
style: "CrewListBackground")
|
style: "CrewListBackground")
|
||||||
{
|
{
|
||||||
UserData = character,
|
UserData = character
|
||||||
OnSecondaryClicked = (comp, data) =>
|
|
||||||
{
|
|
||||||
if (data == null) { return false; }
|
|
||||||
|
|
||||||
var client = GameMain.NetworkMember?.ConnectedClients?.Find(c => c.Character == data);
|
|
||||||
if (client != null)
|
|
||||||
{
|
|
||||||
CreateModerationContextMenu(PlayerInput.MousePosition.ToPoint(), client);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var iconRelativeWidth = (float)crewListEntrySize.Y / background.Rect.Width;
|
var iconRelativeWidth = (float)crewListEntrySize.Y / background.Rect.Width;
|
||||||
@@ -379,7 +368,17 @@ namespace Barotrauma
|
|||||||
background.RectTransform),
|
background.RectTransform),
|
||||||
style: null)
|
style: null)
|
||||||
{
|
{
|
||||||
UserData = character
|
UserData = character,
|
||||||
|
OnSecondaryClicked = (comp, data) =>
|
||||||
|
{
|
||||||
|
if (data == null) { return false; }
|
||||||
|
if (GameMain.NetworkMember?.ConnectedClients?.Find(c => c.Character == data) is Client client)
|
||||||
|
{
|
||||||
|
CreateModerationContextMenu(PlayerInput.MousePosition.ToPoint(), client);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
SetCharacterButtonTooltip(characterButton);
|
SetCharacterButtonTooltip(characterButton);
|
||||||
|
|
||||||
@@ -389,7 +388,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
characterButton.CanBeFocused = false;
|
|
||||||
characterButton.CanBeSelected = false;
|
characterButton.CanBeSelected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1089,7 +1087,8 @@ namespace Barotrauma
|
|||||||
public void CreateModerationContextMenu(Point mousePos, Client client)
|
public void CreateModerationContextMenu(Point mousePos, Client client)
|
||||||
{
|
{
|
||||||
if (GUIContextMenu.CurrentContextMenu != null) { return; }
|
if (GUIContextMenu.CurrentContextMenu != null) { return; }
|
||||||
if (IsSinglePlayer || client == null || (!GameMain.Client?.PreviouslyConnectedClients?.Contains(client) ?? true)) { return; }
|
if (IsSinglePlayer || client == null || ((!GameMain.Client?.PreviouslyConnectedClients?.Contains(client)) ?? true)) { return; }
|
||||||
|
|
||||||
|
|
||||||
bool hasSteam = client.SteamID > 0 && SteamManager.IsInitialized,
|
bool hasSteam = client.SteamID > 0 && SteamManager.IsInitialized,
|
||||||
canKick = GameMain.Client.HasPermission(ClientPermissions.Kick),
|
canKick = GameMain.Client.HasPermission(ClientPermissions.Kick),
|
||||||
@@ -1638,7 +1637,8 @@ namespace Barotrauma
|
|||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (Character.Controlled == null) { return true; }
|
if (Character.Controlled == null) { return true; }
|
||||||
#endif
|
#endif
|
||||||
return Character.Controlled != null && characters.Any(c => c != Character.Controlled && c.CanHearCharacter(Character.Controlled));
|
return Character.Controlled != null &&
|
||||||
|
(characters.Any(c => c != Character.Controlled && c.CanHearCharacter(Character.Controlled)) || GetOrderableFriendlyNPCs().Any(c => c != Character.Controlled && c.CanHearCharacter(Character.Controlled)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Entity FindEntityContext()
|
private Entity FindEntityContext()
|
||||||
|
|||||||
@@ -124,22 +124,22 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
var backgroundSprite = GUI.Style.GetComponentStyle("CommandBackground").GetDefaultSprite();
|
var backgroundSprite = GUI.Style.GetComponentStyle("CommandBackground").GetDefaultSprite();
|
||||||
Vector2 centerPos = new Vector2(GameMain.GraphicsWidth, GameMain.GraphicsHeight) / 2;
|
Vector2 centerPos = new Vector2(GameMain.GraphicsWidth, GameMain.GraphicsHeight) / 2;
|
||||||
|
string wrappedText = ToolBox.WrapText(overlayText, GameMain.GraphicsWidth / 3, GUI.Font);
|
||||||
|
Vector2 textSize = GUI.Font.MeasureString(wrappedText);
|
||||||
|
Vector2 textPos = centerPos - textSize / 2;
|
||||||
backgroundSprite.Draw(spriteBatch,
|
backgroundSprite.Draw(spriteBatch,
|
||||||
centerPos,
|
centerPos,
|
||||||
Color.White * (overlayTextColor.A / 255.0f),
|
Color.White * (overlayTextColor.A / 255.0f),
|
||||||
origin: backgroundSprite.size / 2,
|
origin: backgroundSprite.size / 2,
|
||||||
rotate: 0.0f,
|
rotate: 0.0f,
|
||||||
scale: new Vector2(1.5f, 0.7f) * (GameMain.GraphicsWidth / 3 / backgroundSprite.size.X));
|
scale: new Vector2(GameMain.GraphicsWidth / 2 / backgroundSprite.size.X, textSize.Y / backgroundSprite.size.Y * 1.5f));
|
||||||
|
|
||||||
string wrappedText = ToolBox.WrapText(overlayText, GameMain.GraphicsWidth / 3, GUI.Font);
|
|
||||||
Vector2 textSize = GUI.Font.MeasureString(wrappedText);
|
|
||||||
Vector2 textPos = centerPos - textSize / 2;
|
|
||||||
GUI.DrawString(spriteBatch, textPos + Vector2.One, wrappedText, Color.Black * (overlayTextColor.A / 255.0f));
|
GUI.DrawString(spriteBatch, textPos + Vector2.One, wrappedText, Color.Black * (overlayTextColor.A / 255.0f));
|
||||||
GUI.DrawString(spriteBatch, textPos, wrappedText, overlayTextColor);
|
GUI.DrawString(spriteBatch, textPos, wrappedText, overlayTextColor);
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(overlayTextBottom))
|
if (!string.IsNullOrEmpty(overlayTextBottom))
|
||||||
{
|
{
|
||||||
Vector2 bottomTextPos = centerPos + new Vector2(0.0f, textSize.Y + 30 * GUI.Scale) - GUI.Font.MeasureString(overlayTextBottom) / 2;
|
Vector2 bottomTextPos = centerPos + new Vector2(0.0f, textSize.Y / 2 + 40 * GUI.Scale) - GUI.Font.MeasureString(overlayTextBottom) / 2;
|
||||||
GUI.DrawString(spriteBatch, bottomTextPos + Vector2.One, overlayTextBottom, Color.Black * (overlayTextColor.A / 255.0f));
|
GUI.DrawString(spriteBatch, bottomTextPos + Vector2.One, overlayTextBottom, Color.Black * (overlayTextColor.A / 255.0f));
|
||||||
GUI.DrawString(spriteBatch, bottomTextPos, overlayTextBottom, overlayTextColor);
|
GUI.DrawString(spriteBatch, bottomTextPos, overlayTextBottom, overlayTextColor);
|
||||||
}
|
}
|
||||||
@@ -152,7 +152,7 @@ namespace Barotrauma
|
|||||||
if (ReadyCheckButton != null) { ReadyCheckButton.Visible = false; }
|
if (ReadyCheckButton != null) { ReadyCheckButton.Visible = false; }
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Submarine.MainSub == null) { return; }
|
if (Submarine.MainSub == null || Level.Loaded == null) { return; }
|
||||||
|
|
||||||
endRoundButton.Visible = false;
|
endRoundButton.Visible = false;
|
||||||
var availableTransition = GetAvailableTransition(out _, out Submarine leavingSub);
|
var availableTransition = GetAvailableTransition(out _, out Submarine leavingSub);
|
||||||
@@ -211,6 +211,7 @@ namespace Barotrauma
|
|||||||
HintManager.OnAvailableTransition(availableTransition);
|
HintManager.OnAvailableTransition(availableTransition);
|
||||||
//opening the campaign map pauses the game and prevents HintManager from running -> update it manually to get the hint to show up immediately
|
//opening the campaign map pauses the game and prevents HintManager from running -> update it manually to get the hint to show up immediately
|
||||||
HintManager.Update();
|
HintManager.Update();
|
||||||
|
Map.SelectLocation(-1);
|
||||||
endRoundButton.OnClicked(EndRoundButton, null);
|
endRoundButton.OnClicked(EndRoundButton, null);
|
||||||
prevCampaignUIAutoOpenType = availableTransition;
|
prevCampaignUIAutoOpenType = availableTransition;
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-6
@@ -239,11 +239,20 @@ namespace Barotrauma
|
|||||||
timer = Math.Min(timer + CoroutineManager.DeltaTime, textDuration);
|
timer = Math.Min(timer + CoroutineManager.DeltaTime, textDuration);
|
||||||
yield return CoroutineStatus.Running;
|
yield return CoroutineStatus.Running;
|
||||||
}
|
}
|
||||||
|
var outpost = GameMain.GameSession.Level.StartOutpost;
|
||||||
|
var borders = outpost.GetDockedBorders();
|
||||||
|
borders.Location += outpost.WorldPosition.ToPoint();
|
||||||
|
GameMain.GameScreen.Cam.Position = new Vector2(borders.X + borders.Width / 2, borders.Y - borders.Height / 2);
|
||||||
|
float startZoom = 0.8f /
|
||||||
|
((float)Math.Max(borders.Width, borders.Height) / (float)GameMain.GameScreen.Cam.Resolution.X);
|
||||||
|
GameMain.GameScreen.Cam.MinZoom = Math.Min(startZoom, GameMain.GameScreen.Cam.MinZoom);
|
||||||
var transition = new CameraTransition(prevControlled, GameMain.GameScreen.Cam,
|
var transition = new CameraTransition(prevControlled, GameMain.GameScreen.Cam,
|
||||||
null, null,
|
null, null,
|
||||||
fadeOut: false,
|
fadeOut: false,
|
||||||
duration: 5,
|
losFadeIn: true,
|
||||||
startZoom: 1.5f, endZoom: 1.0f)
|
waitDuration: 1,
|
||||||
|
panDuration: 5,
|
||||||
|
startZoom: startZoom, endZoom: 1.0f)
|
||||||
{
|
{
|
||||||
AllowInterrupt = true,
|
AllowInterrupt = true,
|
||||||
RemoveControlFromCharacter = false
|
RemoveControlFromCharacter = false
|
||||||
@@ -274,7 +283,8 @@ namespace Barotrauma
|
|||||||
var transition = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam,
|
var transition = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam,
|
||||||
null, null,
|
null, null,
|
||||||
fadeOut: false,
|
fadeOut: false,
|
||||||
duration: 5,
|
losFadeIn: true,
|
||||||
|
panDuration: 5,
|
||||||
startZoom: 0.5f, endZoom: 1.0f)
|
startZoom: 0.5f, endZoom: 1.0f)
|
||||||
{
|
{
|
||||||
AllowInterrupt = true,
|
AllowInterrupt = true,
|
||||||
@@ -327,7 +337,7 @@ namespace Barotrauma
|
|||||||
var endTransition = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam, null,
|
var endTransition = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam, null,
|
||||||
Alignment.Center,
|
Alignment.Center,
|
||||||
fadeOut: false,
|
fadeOut: false,
|
||||||
duration: EndTransitionDuration);
|
panDuration: EndTransitionDuration);
|
||||||
GameMain.Client.EndCinematic = endTransition;
|
GameMain.Client.EndCinematic = endTransition;
|
||||||
|
|
||||||
Location portraitLocation = Map?.SelectedLocation ?? Map?.CurrentLocation ?? Level.Loaded?.StartLocation;
|
Location portraitLocation = Map?.SelectedLocation ?? Map?.CurrentLocation ?? Level.Loaded?.StartLocation;
|
||||||
@@ -335,7 +345,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
overlaySprite = portraitLocation.Type.GetPortrait(portraitLocation.PortraitId);
|
overlaySprite = portraitLocation.Type.GetPortrait(portraitLocation.PortraitId);
|
||||||
}
|
}
|
||||||
float fadeOutDuration = endTransition.Duration;
|
float fadeOutDuration = endTransition.PanDuration;
|
||||||
float t = 0.0f;
|
float t = 0.0f;
|
||||||
while (t < fadeOutDuration || endTransition.Running)
|
while (t < fadeOutDuration || endTransition.Running)
|
||||||
{
|
{
|
||||||
@@ -498,7 +508,7 @@ namespace Barotrauma
|
|||||||
var transition = new CameraTransition(endObject ?? Submarine.MainSub, GameMain.GameScreen.Cam,
|
var transition = new CameraTransition(endObject ?? Submarine.MainSub, GameMain.GameScreen.Cam,
|
||||||
null, Alignment.Center,
|
null, Alignment.Center,
|
||||||
fadeOut: true,
|
fadeOut: true,
|
||||||
duration: 10,
|
panDuration: 10,
|
||||||
startZoom: null, endZoom: 0.2f);
|
startZoom: null, endZoom: 0.2f);
|
||||||
|
|
||||||
while (transition.Running)
|
while (transition.Running)
|
||||||
|
|||||||
+17
-14
@@ -298,11 +298,20 @@ namespace Barotrauma
|
|||||||
timer = Math.Min(timer + CoroutineManager.DeltaTime, textDuration);
|
timer = Math.Min(timer + CoroutineManager.DeltaTime, textDuration);
|
||||||
yield return CoroutineStatus.Running;
|
yield return CoroutineStatus.Running;
|
||||||
}
|
}
|
||||||
|
var outpost = GameMain.GameSession.Level.StartOutpost;
|
||||||
|
var borders = outpost.GetDockedBorders();
|
||||||
|
borders.Location += outpost.WorldPosition.ToPoint();
|
||||||
|
GameMain.GameScreen.Cam.Position = new Vector2(borders.X + borders.Width / 2, borders.Y - borders.Height / 2);
|
||||||
|
float startZoom = 0.8f /
|
||||||
|
((float)Math.Max(borders.Width, borders.Height) / (float)GameMain.GameScreen.Cam.Resolution.X);
|
||||||
|
GameMain.GameScreen.Cam.MinZoom = Math.Min(startZoom, GameMain.GameScreen.Cam.MinZoom);
|
||||||
var transition = new CameraTransition(prevControlled, GameMain.GameScreen.Cam,
|
var transition = new CameraTransition(prevControlled, GameMain.GameScreen.Cam,
|
||||||
null, null,
|
null, null,
|
||||||
fadeOut: false,
|
fadeOut: false,
|
||||||
duration: 5,
|
losFadeIn: true,
|
||||||
startZoom: 1.5f, endZoom: 1.0f)
|
waitDuration: 1,
|
||||||
|
panDuration: 5,
|
||||||
|
startZoom: startZoom, endZoom: 1.0f)
|
||||||
{
|
{
|
||||||
AllowInterrupt = true,
|
AllowInterrupt = true,
|
||||||
RemoveControlFromCharacter = false
|
RemoveControlFromCharacter = false
|
||||||
@@ -327,19 +336,13 @@ namespace Barotrauma
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
ISpatialEntity transitionTarget;
|
ISpatialEntity transitionTarget;
|
||||||
if (prevControlled != null)
|
transitionTarget = (ISpatialEntity)prevControlled ?? Submarine.MainSub;
|
||||||
{
|
|
||||||
transitionTarget = prevControlled;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
transitionTarget = Submarine.MainSub;
|
|
||||||
}
|
|
||||||
|
|
||||||
var transition = new CameraTransition(transitionTarget, GameMain.GameScreen.Cam,
|
var transition = new CameraTransition(transitionTarget, GameMain.GameScreen.Cam,
|
||||||
null, null,
|
null, null,
|
||||||
fadeOut: false,
|
fadeOut: false,
|
||||||
duration: 5,
|
losFadeIn: prevControlled != null,
|
||||||
|
panDuration: 5,
|
||||||
startZoom: 0.5f, endZoom: 1.0f)
|
startZoom: 0.5f, endZoom: 1.0f)
|
||||||
{
|
{
|
||||||
AllowInterrupt = true,
|
AllowInterrupt = true,
|
||||||
@@ -409,13 +412,13 @@ namespace Barotrauma
|
|||||||
var endTransition = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam, null,
|
var endTransition = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam, null,
|
||||||
transitionType == TransitionType.LeaveLocation ? Alignment.BottomCenter : Alignment.Center,
|
transitionType == TransitionType.LeaveLocation ? Alignment.BottomCenter : Alignment.Center,
|
||||||
fadeOut: false,
|
fadeOut: false,
|
||||||
duration: EndTransitionDuration);
|
panDuration: EndTransitionDuration);
|
||||||
|
|
||||||
GUI.ClearMessages();
|
GUI.ClearMessages();
|
||||||
|
|
||||||
Location portraitLocation = Map.SelectedLocation ?? Map.CurrentLocation;
|
Location portraitLocation = Map.SelectedLocation ?? Map.CurrentLocation;
|
||||||
overlaySprite = portraitLocation.Type.GetPortrait(portraitLocation.PortraitId);
|
overlaySprite = portraitLocation.Type.GetPortrait(portraitLocation.PortraitId);
|
||||||
float fadeOutDuration = endTransition.Duration;
|
float fadeOutDuration = endTransition.PanDuration;
|
||||||
float t = 0.0f;
|
float t = 0.0f;
|
||||||
while (t < fadeOutDuration || endTransition.Running)
|
while (t < fadeOutDuration || endTransition.Running)
|
||||||
{
|
{
|
||||||
@@ -509,7 +512,7 @@ namespace Barotrauma
|
|||||||
var transition = new CameraTransition(endObject ?? Submarine.MainSub, GameMain.GameScreen.Cam,
|
var transition = new CameraTransition(endObject ?? Submarine.MainSub, GameMain.GameScreen.Cam,
|
||||||
null, Alignment.Center,
|
null, Alignment.Center,
|
||||||
fadeOut: true,
|
fadeOut: true,
|
||||||
duration: 10,
|
panDuration: 10,
|
||||||
startZoom: null, endZoom: 0.2f);
|
startZoom: null, endZoom: 0.2f);
|
||||||
|
|
||||||
while (transition.Running)
|
while (transition.Running)
|
||||||
|
|||||||
+1
-1
@@ -614,7 +614,7 @@ namespace Barotrauma.Tutorials
|
|||||||
GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
|
GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
|
||||||
GameMain.LightManager.LosEnabled = false;
|
GameMain.LightManager.LosEnabled = false;
|
||||||
|
|
||||||
var cinematic = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam, Alignment.CenterLeft, Alignment.CenterRight, duration: 5.0f);
|
var cinematic = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam, Alignment.CenterLeft, Alignment.CenterRight, panDuration: 5.0f);
|
||||||
|
|
||||||
while (cinematic.Running)
|
while (cinematic.Running)
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-1
@@ -288,7 +288,7 @@ namespace Barotrauma.Tutorials
|
|||||||
|
|
||||||
yield return new WaitForSeconds(waitBeforeFade);
|
yield return new WaitForSeconds(waitBeforeFade);
|
||||||
|
|
||||||
var endCinematic = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam, null, Alignment.Center, duration: fadeOutTime);
|
var endCinematic = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam, null, Alignment.Center, panDuration: fadeOutTime);
|
||||||
currentTutorialCompleted = Completed = true;
|
currentTutorialCompleted = Completed = true;
|
||||||
while (endCinematic.Running) yield return null;
|
while (endCinematic.Running) yield return null;
|
||||||
Stop();
|
Stop();
|
||||||
|
|||||||
@@ -40,56 +40,82 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private GUILayoutGroup topLeftButtonGroup;
|
private GUILayoutGroup topLeftButtonGroup;
|
||||||
private GUIButton crewListButton, commandButton, tabMenuButton;
|
private GUIButton crewListButton, commandButton, tabMenuButton;
|
||||||
private GUILayoutGroup TopLeftButtonGroup
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (topLeftButtonGroup == null)
|
|
||||||
{
|
|
||||||
topLeftButtonGroup = new GUILayoutGroup(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.ButtonAreaTop, GUI.Canvas), isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
|
||||||
{
|
|
||||||
AbsoluteSpacing = HUDLayoutSettings.Padding,
|
|
||||||
CanBeFocused = false
|
|
||||||
};
|
|
||||||
|
|
||||||
int buttonHeight = GUI.IntScale(40);
|
private GUIComponent respawnInfoFrame, respawnButtonContainer;
|
||||||
Vector2 buttonSpriteSize = GUI.Style.GetComponentStyle("CrewListToggleButton").GetDefaultSprite().size;
|
private GUITextBlock respawnInfoText;
|
||||||
int buttonWidth = (int)((buttonHeight / buttonSpriteSize.Y) * buttonSpriteSize.X);
|
private GUITickBox respawnTickBox;
|
||||||
Point buttonSize = new Point(buttonWidth, buttonHeight);
|
private GUILayoutGroup TopLeftButtonGroup;
|
||||||
// Crew list button
|
private void CreateTopLeftButtons()
|
||||||
crewListButton = new GUIButton(new RectTransform(buttonSize, parent: topLeftButtonGroup.RectTransform), style: "CrewListToggleButton")
|
{
|
||||||
{
|
if (topLeftButtonGroup != null)
|
||||||
ToolTip = TextManager.GetWithVariable("hudbutton.crewlist", "[key]", GameMain.Config.KeyBindText(InputType.CrewOrders)),
|
{
|
||||||
OnClicked = (GUIButton btn, object userdata) =>
|
topLeftButtonGroup.RectTransform.Parent = null;
|
||||||
{
|
topLeftButtonGroup = null;
|
||||||
if (CrewManager == null) { return false; }
|
crewListButton = commandButton = tabMenuButton = null;
|
||||||
CrewManager.IsCrewMenuOpen = !CrewManager.IsCrewMenuOpen;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// Command interface button
|
|
||||||
commandButton = new GUIButton(new RectTransform(buttonSize, parent: topLeftButtonGroup.RectTransform),style: "CommandButton")
|
|
||||||
{
|
|
||||||
ToolTip = TextManager.GetWithVariable("hudbutton.commandinterface", "[key]", GameMain.Config.KeyBindText(InputType.Command)),
|
|
||||||
OnClicked = (button, userData) =>
|
|
||||||
{
|
|
||||||
if (CrewManager == null) { return false; }
|
|
||||||
CrewManager.ToggleCommandUI();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// Tab menu button
|
|
||||||
tabMenuButton = new GUIButton(new RectTransform(buttonSize, parent: topLeftButtonGroup.RectTransform), style: "TabMenuButton")
|
|
||||||
{
|
|
||||||
ToolTip = TextManager.GetWithVariable("hudbutton.tabmenu", "[key]", GameMain.Config.KeyBindText(InputType.InfoTab)),
|
|
||||||
OnClicked = (button, userData) =>
|
|
||||||
{
|
|
||||||
return ToggleTabMenu();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return topLeftButtonGroup;
|
|
||||||
}
|
}
|
||||||
|
topLeftButtonGroup = new GUILayoutGroup(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.ButtonAreaTop, GUI.Canvas), isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
||||||
|
{
|
||||||
|
AbsoluteSpacing = HUDLayoutSettings.Padding,
|
||||||
|
CanBeFocused = false
|
||||||
|
};
|
||||||
|
topLeftButtonGroup.RectTransform.ParentChanged += (_) =>
|
||||||
|
{
|
||||||
|
GameMain.Instance.ResolutionChanged -= CreateTopLeftButtons;
|
||||||
|
};
|
||||||
|
int buttonHeight = GUI.IntScale(40);
|
||||||
|
Vector2 buttonSpriteSize = GUI.Style.GetComponentStyle("CrewListToggleButton").GetDefaultSprite().size;
|
||||||
|
int buttonWidth = (int)((buttonHeight / buttonSpriteSize.Y) * buttonSpriteSize.X);
|
||||||
|
Point buttonSize = new Point(buttonWidth, buttonHeight);
|
||||||
|
crewListButton = new GUIButton(new RectTransform(buttonSize, parent: topLeftButtonGroup.RectTransform), style: "CrewListToggleButton")
|
||||||
|
{
|
||||||
|
ToolTip = TextManager.GetWithVariable("hudbutton.crewlist", "[key]", GameMain.Config.KeyBindText(InputType.CrewOrders)),
|
||||||
|
OnClicked = (GUIButton btn, object userdata) =>
|
||||||
|
{
|
||||||
|
if (CrewManager == null) { return false; }
|
||||||
|
CrewManager.IsCrewMenuOpen = !CrewManager.IsCrewMenuOpen;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
commandButton = new GUIButton(new RectTransform(buttonSize, parent: topLeftButtonGroup.RectTransform), style: "CommandButton")
|
||||||
|
{
|
||||||
|
ToolTip = TextManager.GetWithVariable("hudbutton.commandinterface", "[key]", GameMain.Config.KeyBindText(InputType.Command)),
|
||||||
|
OnClicked = (button, userData) =>
|
||||||
|
{
|
||||||
|
if (CrewManager == null) { return false; }
|
||||||
|
CrewManager.ToggleCommandUI();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
tabMenuButton = new GUIButton(new RectTransform(buttonSize, parent: topLeftButtonGroup.RectTransform), style: "TabMenuButton")
|
||||||
|
{
|
||||||
|
ToolTip = TextManager.GetWithVariable("hudbutton.tabmenu", "[key]", GameMain.Config.KeyBindText(InputType.InfoTab)),
|
||||||
|
OnClicked = (button, userData) =>
|
||||||
|
{
|
||||||
|
return ToggleTabMenu();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
GameMain.Instance.ResolutionChanged += CreateTopLeftButtons;
|
||||||
|
|
||||||
|
respawnInfoFrame = new GUIFrame(new RectTransform(new Vector2(0.5f, 1.0f), parent: topLeftButtonGroup.RectTransform)
|
||||||
|
{ MaxSize = new Point(HUDLayoutSettings.ButtonAreaTop.Width / 3, int.MaxValue) }, style: null)
|
||||||
|
{
|
||||||
|
Visible = false
|
||||||
|
};
|
||||||
|
respawnInfoText = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), respawnInfoFrame.RectTransform), "", wrap: true);
|
||||||
|
respawnButtonContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1.0f), respawnInfoFrame.RectTransform, Anchor.CenterRight), isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
||||||
|
{
|
||||||
|
AbsoluteSpacing = HUDLayoutSettings.Padding,
|
||||||
|
Stretch = true
|
||||||
|
};
|
||||||
|
respawnTickBox = new GUITickBox(new RectTransform(Vector2.One * 0.9f, respawnButtonContainer.RectTransform, Anchor.Center), TextManager.Get("respawnquestionpromptrespawn"))
|
||||||
|
{
|
||||||
|
ToolTip = TextManager.Get("respawnquestionprompt"),
|
||||||
|
OnSelected = (tickbox) =>
|
||||||
|
{
|
||||||
|
GameMain.Client?.SendRespawnPromptResponse(waitForNextRoundRespawn: !tickbox.Selected);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddToGUIUpdateList()
|
public void AddToGUIUpdateList()
|
||||||
@@ -101,20 +127,15 @@ namespace Barotrauma
|
|||||||
if ((!(GameMode is CampaignMode campaign) || (!campaign.ForceMapUI && !campaign.ShowCampaignUI)) &&
|
if ((!(GameMode is CampaignMode campaign) || (!campaign.ForceMapUI && !campaign.ShowCampaignUI)) &&
|
||||||
!CoroutineManager.IsCoroutineRunning("LevelTransition") && !CoroutineManager.IsCoroutineRunning("SubmarineTransition"))
|
!CoroutineManager.IsCoroutineRunning("LevelTransition") && !CoroutineManager.IsCoroutineRunning("SubmarineTransition"))
|
||||||
{
|
{
|
||||||
if (crewListButton != null)
|
if (topLeftButtonGroup == null)
|
||||||
{
|
{
|
||||||
crewListButton.Selected = CrewManager != null && CrewManager.IsCrewMenuOpen;
|
CreateTopLeftButtons();
|
||||||
}
|
}
|
||||||
if (commandButton != null)
|
crewListButton.Selected = CrewManager != null && CrewManager.IsCrewMenuOpen;
|
||||||
{
|
commandButton.Selected = CrewManager.IsCommandInterfaceOpen;
|
||||||
commandButton.Selected = CrewManager.IsCommandInterfaceOpen;
|
commandButton.Enabled = CrewManager.CanIssueOrders;
|
||||||
commandButton.Enabled = CrewManager.CanIssueOrders;
|
tabMenuButton.Selected = IsTabMenuOpen;
|
||||||
}
|
topLeftButtonGroup.AddToGUIUpdateList();
|
||||||
if (tabMenuButton != null)
|
|
||||||
{
|
|
||||||
tabMenuButton.Selected = IsTabMenuOpen;
|
|
||||||
}
|
|
||||||
TopLeftButtonGroup.AddToGUIUpdateList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GameMain.NetworkMember != null)
|
if (GameMain.NetworkMember != null)
|
||||||
@@ -130,7 +151,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (tabMenu == null)
|
if (tabMenu == null)
|
||||||
{
|
{
|
||||||
if (PlayerInput.KeyHit(InputType.InfoTab) && GUI.KeyboardDispatcher.Subscriber is GUITextBox == false)
|
if (PlayerInput.KeyHit(InputType.InfoTab) && !(GUI.KeyboardDispatcher.Subscriber is GUITextBox))
|
||||||
{
|
{
|
||||||
ToggleTabMenu();
|
ToggleTabMenu();
|
||||||
}
|
}
|
||||||
@@ -138,8 +159,8 @@ namespace Barotrauma
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
tabMenu.Update();
|
tabMenu.Update();
|
||||||
|
if ((PlayerInput.KeyHit(InputType.InfoTab) || PlayerInput.KeyHit(Microsoft.Xna.Framework.Input.Keys.Escape)) &&
|
||||||
if (PlayerInput.KeyHit(InputType.InfoTab) && GUI.KeyboardDispatcher.Subscriber is GUITextBox == false)
|
!(GUI.KeyboardDispatcher.Subscriber is GUITextBox))
|
||||||
{
|
{
|
||||||
ToggleTabMenu();
|
ToggleTabMenu();
|
||||||
}
|
}
|
||||||
@@ -167,6 +188,17 @@ namespace Barotrauma
|
|||||||
HintManager.Update();
|
HintManager.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetRespawnInfo(bool visible, string text, Color textColor, bool buttonsVisible, bool waitForNextRoundRespawn)
|
||||||
|
{
|
||||||
|
if (topLeftButtonGroup == null) { return; }
|
||||||
|
respawnInfoFrame.Visible = visible;
|
||||||
|
if (!visible) { return; }
|
||||||
|
respawnInfoText.Text = text;
|
||||||
|
respawnInfoText.TextColor = textColor;
|
||||||
|
respawnButtonContainer.Visible = buttonsVisible;
|
||||||
|
respawnTickBox.Selected = !waitForNextRoundRespawn;
|
||||||
|
}
|
||||||
|
|
||||||
public void Draw(SpriteBatch spriteBatch)
|
public void Draw(SpriteBatch spriteBatch)
|
||||||
{
|
{
|
||||||
GameMode?.Draw(spriteBatch);
|
GameMode?.Draw(spriteBatch);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Barotrauma.IO;
|
using Barotrauma.Extensions;
|
||||||
|
using Barotrauma.IO;
|
||||||
using Barotrauma.Items.Components;
|
using Barotrauma.Items.Components;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using System;
|
using System;
|
||||||
@@ -21,41 +22,16 @@ namespace Barotrauma
|
|||||||
private static GUIMessageBox ActiveHintMessageBox { get; set; }
|
private static GUIMessageBox ActiveHintMessageBox { get; set; }
|
||||||
private static Action OnUpdate { get; set; }
|
private static Action OnUpdate { get; set; }
|
||||||
private static double TimeStoppedInteracting { get; set; }
|
private static double TimeStoppedInteracting { get; set; }
|
||||||
|
private static double TimeRoundStarted { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Seconds before any reminders can be shown
|
/// Seconds before any reminders can be shown
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static int TimeBeforeReminders { get; set; }
|
private static int TimeBeforeReminders { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Seconds before another reminder can be shown
|
/// Seconds before another reminder can be shown
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static int ReminderCooldown { get; set; }
|
private static int ReminderCooldown { get; set; }
|
||||||
|
|
||||||
private static double TimeReminderLastDisplayed { get; set; }
|
private static double TimeReminderLastDisplayed { get; set; }
|
||||||
|
|
||||||
private static Queue<HintInfo> HintQueue { get; } = new Queue<HintInfo>();
|
|
||||||
|
|
||||||
public struct HintInfo
|
|
||||||
{
|
|
||||||
public string Identifier { get; }
|
|
||||||
public string Text { get; }
|
|
||||||
public Sprite Icon { get; }
|
|
||||||
public Color? IconColor { get; }
|
|
||||||
public Action OnDisplay { get; }
|
|
||||||
public Action OnUpdate { get; }
|
|
||||||
|
|
||||||
public HintInfo(string hintIdentifier, string text, Sprite icon, Color? iconColor, Action onDisplay, Action onUpdate)
|
|
||||||
{
|
|
||||||
Identifier = hintIdentifier;
|
|
||||||
Text = text;
|
|
||||||
Icon = icon;
|
|
||||||
IconColor = iconColor;
|
|
||||||
OnDisplay = onDisplay;
|
|
||||||
OnUpdate = onUpdate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static HashSet<Hull> BallastHulls { get; } = new HashSet<Hull>();
|
private static HashSet<Hull> BallastHulls { get; } = new HashSet<Hull>();
|
||||||
|
|
||||||
public static void Init()
|
public static void Init()
|
||||||
@@ -127,15 +103,6 @@ namespace Barotrauma
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (HintQueue.TryDequeue(out var hint))
|
|
||||||
{
|
|
||||||
ActiveHintMessageBox = new GUIMessageBox(hint.Identifier, hint.Text, hint.Icon);
|
|
||||||
if (hint.IconColor.HasValue) { ActiveHintMessageBox.IconColor = hint.IconColor.Value; }
|
|
||||||
OnUpdate = hint.OnUpdate;
|
|
||||||
ActiveHintMessageBox.InnerFrame.Flash(color: hint.IconColor ?? Color.Orange, flashDuration: 0.75f);
|
|
||||||
SoundPlayer.PlayUISound(GUISoundType.UIMessage);
|
|
||||||
hint.OnDisplay?.Invoke();
|
|
||||||
}
|
|
||||||
|
|
||||||
CheckIsInteracting();
|
CheckIsInteracting();
|
||||||
CheckIfDivingGearOutOfOxygen();
|
CheckIfDivingGearOutOfOxygen();
|
||||||
@@ -166,21 +133,21 @@ namespace Barotrauma
|
|||||||
// onstartedinteracting.brokenitem
|
// onstartedinteracting.brokenitem
|
||||||
if (item.Repairables.Any(r => item.ConditionPercentage < r.RepairThreshold))
|
if (item.Repairables.Any(r => item.ConditionPercentage < r.RepairThreshold))
|
||||||
{
|
{
|
||||||
if (EnqueueHint($"{hintIdentifierBase}.brokenitem")) { return; }
|
if (DisplayHint($"{hintIdentifierBase}.brokenitem")) { return; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// onstartedinteracting.lootingisstealing
|
// onstartedinteracting.lootingisstealing
|
||||||
if (item.Submarine?.Info?.Type == SubmarineType.Outpost &&
|
if (item.Submarine?.Info?.Type == SubmarineType.Outpost &&
|
||||||
item.ContainedItems.Any(i => i.SpawnedInOutpost))
|
item.ContainedItems.Any(i => i.SpawnedInOutpost))
|
||||||
{
|
{
|
||||||
if (EnqueueHint($"{hintIdentifierBase}.lootingisstealing")) { return; }
|
if (DisplayHint($"{hintIdentifierBase}.lootingisstealing")) { return; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// onstartedinteracting.turretperiscope
|
// onstartedinteracting.turretperiscope
|
||||||
if (item.HasTag("periscope") &&
|
if (item.HasTag("periscope") &&
|
||||||
item.GetConnectedComponents<Turret>().FirstOrDefault(t => t.Item.HasTag("turret")) is Turret)
|
item.GetConnectedComponents<Turret>().FirstOrDefault(t => t.Item.HasTag("turret")) is Turret)
|
||||||
{
|
{
|
||||||
if (EnqueueHint($"{hintIdentifierBase}.turretperiscope",
|
if (DisplayHint($"{hintIdentifierBase}.turretperiscope",
|
||||||
variableTags: new string[] { "[shootkey]", "[deselectkey]", },
|
variableTags: new string[] { "[shootkey]", "[deselectkey]", },
|
||||||
variableValues: new string[] { GameMain.Config.KeyBindText(InputType.Shoot), GameMain.Config.KeyBindText(InputType.Deselect) }))
|
variableValues: new string[] { GameMain.Config.KeyBindText(InputType.Shoot), GameMain.Config.KeyBindText(InputType.Deselect) }))
|
||||||
{ return; }
|
{ return; }
|
||||||
@@ -193,7 +160,7 @@ namespace Barotrauma
|
|||||||
if (!hintIdentifier.StartsWith(hintIdentifierBase)) { continue; }
|
if (!hintIdentifier.StartsWith(hintIdentifierBase)) { continue; }
|
||||||
if (!HintTags.TryGetValue(hintIdentifier, out var hintTags)) { continue; }
|
if (!HintTags.TryGetValue(hintIdentifier, out var hintTags)) { continue; }
|
||||||
if (!item.HasTag(hintTags)) { continue; }
|
if (!item.HasTag(hintTags)) { continue; }
|
||||||
if (EnqueueHint(hintIdentifier)) { return; }
|
if (DisplayHint(hintIdentifier)) { return; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,7 +173,7 @@ namespace Barotrauma
|
|||||||
Character.Controlled.SelectedConstruction.OwnInventory?.AllItems is IEnumerable<Item> containedItems &&
|
Character.Controlled.SelectedConstruction.OwnInventory?.AllItems is IEnumerable<Item> containedItems &&
|
||||||
containedItems.Count(i => i.HasTag("reactorfuel")) > 1)
|
containedItems.Count(i => i.HasTag("reactorfuel")) > 1)
|
||||||
{
|
{
|
||||||
if (EnqueueHint("onisinteracting.reactorwithextrarods")) { return; }
|
if (DisplayHint("onisinteracting.reactorwithextrarods")) { return; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,6 +181,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
// Make sure everything's been reset properly, OnRoundEnded() isn't always called when exiting a game
|
// Make sure everything's been reset properly, OnRoundEnded() isn't always called when exiting a game
|
||||||
Reset();
|
Reset();
|
||||||
|
TimeRoundStarted = GameMain.GameScreen.GameTime;
|
||||||
|
|
||||||
var initRoundHandle = CoroutineManager.StartCoroutine(InitRound(), "HintManager.InitRound");
|
var initRoundHandle = CoroutineManager.StartCoroutine(InitRound(), "HintManager.InitRound");
|
||||||
if (!CanDisplayHints(requireGameScreen: false, requireControllingCharacter: false)) { return; }
|
if (!CanDisplayHints(requireGameScreen: false, requireControllingCharacter: false)) { return; }
|
||||||
@@ -252,10 +220,15 @@ namespace Barotrauma
|
|||||||
|
|
||||||
OnStartedControlling();
|
OnStartedControlling();
|
||||||
|
|
||||||
|
while (ActiveHintMessageBox != null)
|
||||||
|
{
|
||||||
|
yield return CoroutineStatus.Running;
|
||||||
|
}
|
||||||
|
|
||||||
if (!GameMain.GameSession.GameMode.IsSinglePlayer &&
|
if (!GameMain.GameSession.GameMode.IsSinglePlayer &&
|
||||||
GameMain.Config.VoiceSetting == GameSettings.VoiceMode.Disabled)
|
GameMain.Config.VoiceSetting == GameSettings.VoiceMode.Disabled)
|
||||||
{
|
{
|
||||||
EnqueueHint("onroundstarted.voipdisabled", onUpdate: () =>
|
DisplayHint("onroundstarted.voipdisabled", onUpdate: () =>
|
||||||
{
|
{
|
||||||
if (GameMain.Config.VoiceSetting == GameSettings.VoiceMode.Disabled) { return; }
|
if (GameMain.Config.VoiceSetting == GameSettings.VoiceMode.Disabled) { return; }
|
||||||
ActiveHintMessageBox.Close();
|
ActiveHintMessageBox.Close();
|
||||||
@@ -281,7 +254,6 @@ namespace Barotrauma
|
|||||||
ActiveHintMessageBox = null;
|
ActiveHintMessageBox = null;
|
||||||
}
|
}
|
||||||
OnUpdate = null;
|
OnUpdate = null;
|
||||||
HintQueue.Clear();
|
|
||||||
HintsIgnoredThisRound.Clear();
|
HintsIgnoredThisRound.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,7 +264,7 @@ namespace Barotrauma
|
|||||||
if (spottedCharacter == null || spottedCharacter.Removed || spottedCharacter.IsDead) { return; }
|
if (spottedCharacter == null || spottedCharacter.Removed || spottedCharacter.IsDead) { return; }
|
||||||
if (Character.Controlled.SelectedConstruction != sonar) { return; }
|
if (Character.Controlled.SelectedConstruction != sonar) { return; }
|
||||||
if (HumanAIController.IsFriendly(Character.Controlled, spottedCharacter)) { return; }
|
if (HumanAIController.IsFriendly(Character.Controlled, spottedCharacter)) { return; }
|
||||||
EnqueueHint("onsonarspottedenemy");
|
DisplayHint("onsonarspottedenemy");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void OnAfflictionDisplayed(Character character, List<Affliction> displayedAfflictions)
|
public static void OnAfflictionDisplayed(Character character, List<Affliction> displayedAfflictions)
|
||||||
@@ -305,7 +277,8 @@ namespace Barotrauma
|
|||||||
if (affliction.Prefab.IsBuff) { continue; }
|
if (affliction.Prefab.IsBuff) { continue; }
|
||||||
if (affliction.Prefab == AfflictionPrefab.OxygenLow) { continue; }
|
if (affliction.Prefab == AfflictionPrefab.OxygenLow) { continue; }
|
||||||
if (affliction.Prefab == AfflictionPrefab.RadiationSickness && (GameMain.GameSession.Map?.Radiation?.IsEntityRadiated(character) ?? false)) { continue; }
|
if (affliction.Prefab == AfflictionPrefab.RadiationSickness && (GameMain.GameSession.Map?.Radiation?.IsEntityRadiated(character) ?? false)) { continue; }
|
||||||
EnqueueHint("onafflictiondisplayed",
|
if (affliction.Strength < affliction.Prefab.ShowIconThreshold) { continue; }
|
||||||
|
DisplayHint("onafflictiondisplayed",
|
||||||
variableTags: new string[1] { "[key]" },
|
variableTags: new string[1] { "[key]" },
|
||||||
variableValues: new string[1] { GameMain.Config.KeyBindText(InputType.Health) },
|
variableValues: new string[1] { GameMain.Config.KeyBindText(InputType.Health) },
|
||||||
icon: affliction.Prefab.Icon,
|
icon: affliction.Prefab.Icon,
|
||||||
@@ -325,12 +298,13 @@ namespace Barotrauma
|
|||||||
if (character != Character.Controlled) { return; }
|
if (character != Character.Controlled) { return; }
|
||||||
if (character.SelectedConstruction != null || character.FocusedItem != null) { return; }
|
if (character.SelectedConstruction != null || character.FocusedItem != null) { return; }
|
||||||
if (item == null || !item.IsShootable || !item.RequireAimToUse) { return; }
|
if (item == null || !item.IsShootable || !item.RequireAimToUse) { return; }
|
||||||
if (GUI.MouseOn != null) { return; }
|
|
||||||
if (TimeStoppedInteracting + 1 > Timing.TotalTime) { return; }
|
if (TimeStoppedInteracting + 1 > Timing.TotalTime) { return; }
|
||||||
|
if (GUI.MouseOn != null) { return; }
|
||||||
|
if (Character.Controlled.Inventory?.visualSlots != null && Character.Controlled.Inventory.visualSlots.Any(s => s.InteractRect.Contains(PlayerInput.MousePosition))) { return; }
|
||||||
string hintIdentifier = "onshootwithoutaiming";
|
string hintIdentifier = "onshootwithoutaiming";
|
||||||
if (!HintTags.TryGetValue(hintIdentifier, out var tags)) { return; }
|
if (!HintTags.TryGetValue(hintIdentifier, out var tags)) { return; }
|
||||||
if (!item.HasTag(tags)) { return; }
|
if (!item.HasTag(tags)) { return; }
|
||||||
EnqueueHint(hintIdentifier,
|
DisplayHint(hintIdentifier,
|
||||||
variableTags: new string[1] { "[key]" },
|
variableTags: new string[1] { "[key]" },
|
||||||
variableValues: new string[1] { GameMain.Config.KeyBindText(InputType.Aim) },
|
variableValues: new string[1] { GameMain.Config.KeyBindText(InputType.Aim) },
|
||||||
onUpdate: () =>
|
onUpdate: () =>
|
||||||
@@ -347,14 +321,14 @@ namespace Barotrauma
|
|||||||
if (!CanDisplayHints()) { return; }
|
if (!CanDisplayHints()) { return; }
|
||||||
if (character != Character.Controlled) { return; }
|
if (character != Character.Controlled) { return; }
|
||||||
if (door == null || door.Stuck < 20.0f) { return; }
|
if (door == null || door.Stuck < 20.0f) { return; }
|
||||||
EnqueueHint("onweldingdoor");
|
DisplayHint("onweldingdoor");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void OnTryOpenStuckDoor(Character character)
|
public static void OnTryOpenStuckDoor(Character character)
|
||||||
{
|
{
|
||||||
if (!CanDisplayHints()) { return; }
|
if (!CanDisplayHints()) { return; }
|
||||||
if (character != Character.Controlled) { return; }
|
if (character != Character.Controlled) { return; }
|
||||||
EnqueueHint("ontryopenstuckdoor");
|
DisplayHint("ontryopenstuckdoor");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void OnShowCampaignInterface(CampaignMode.InteractionType interactionType)
|
public static void OnShowCampaignInterface(CampaignMode.InteractionType interactionType)
|
||||||
@@ -362,36 +336,34 @@ namespace Barotrauma
|
|||||||
if (!CanDisplayHints()) { return; }
|
if (!CanDisplayHints()) { return; }
|
||||||
if (interactionType == CampaignMode.InteractionType.None) { return; }
|
if (interactionType == CampaignMode.InteractionType.None) { return; }
|
||||||
string hintIdentifier = $"onshowcampaigninterface.{interactionType.ToString().ToLowerInvariant()}";
|
string hintIdentifier = $"onshowcampaigninterface.{interactionType.ToString().ToLowerInvariant()}";
|
||||||
EnqueueHint(hintIdentifier,
|
DisplayHint(hintIdentifier, onUpdate: () =>
|
||||||
onUpdate: () =>
|
{
|
||||||
{
|
|
||||||
|
|
||||||
if (!(GameMain.GameSession?.Campaign is CampaignMode campaign) ||
|
if (!(GameMain.GameSession?.Campaign is CampaignMode campaign) ||
|
||||||
(!campaign.ShowCampaignUI && !campaign.ForceMapUI) ||
|
(!campaign.ShowCampaignUI && !campaign.ForceMapUI) ||
|
||||||
campaign.CampaignUI?.SelectedTab != CampaignMode.InteractionType.Map)
|
campaign.CampaignUI?.SelectedTab != CampaignMode.InteractionType.Map)
|
||||||
{
|
{
|
||||||
ActiveHintMessageBox.Close();
|
ActiveHintMessageBox.Close();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void OnShowCommandInterface()
|
public static void OnShowCommandInterface()
|
||||||
{
|
{
|
||||||
IgnoreReminder("commandinterface");
|
IgnoreReminder("commandinterface");
|
||||||
if (!CanDisplayHints()) { return; }
|
if (!CanDisplayHints()) { return; }
|
||||||
EnqueueHint("onshowcommandinterface",
|
DisplayHint("onshowcommandinterface", onUpdate: () =>
|
||||||
onUpdate: () =>
|
{
|
||||||
{
|
if (CrewManager.IsCommandInterfaceOpen) { return; }
|
||||||
if (CrewManager.IsCommandInterfaceOpen) { return; }
|
ActiveHintMessageBox.Close();
|
||||||
ActiveHintMessageBox.Close();
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void OnShowHealthInterface()
|
public static void OnShowHealthInterface()
|
||||||
{
|
{
|
||||||
if (!CanDisplayHints()) { return; }
|
if (!CanDisplayHints()) { return; }
|
||||||
if (CharacterHealth.OpenHealthWindow == null) { return; }
|
if (CharacterHealth.OpenHealthWindow == null) { return; }
|
||||||
EnqueueHint("onshowhealthinterface", onUpdate: () =>
|
DisplayHint("onshowhealthinterface", onUpdate: () =>
|
||||||
{
|
{
|
||||||
if (CharacterHealth.OpenHealthWindow != null) { return; }
|
if (CharacterHealth.OpenHealthWindow != null) { return; }
|
||||||
ActiveHintMessageBox.Close();
|
ActiveHintMessageBox.Close();
|
||||||
@@ -408,7 +380,7 @@ namespace Barotrauma
|
|||||||
if (!CanDisplayHints()) { return; }
|
if (!CanDisplayHints()) { return; }
|
||||||
if (character != Character.Controlled) { return; }
|
if (character != Character.Controlled) { return; }
|
||||||
if (item == null || !item.SpawnedInOutpost || !item.StolenDuringRound) { return; }
|
if (item == null || !item.SpawnedInOutpost || !item.StolenDuringRound) { return; }
|
||||||
EnqueueHint("onstoleitem", onUpdate: () =>
|
DisplayHint("onstoleitem", onUpdate: () =>
|
||||||
{
|
{
|
||||||
if (item == null || item.Removed || item.GetRootInventoryOwner() != character)
|
if (item == null || item.Removed || item.GetRootInventoryOwner() != character)
|
||||||
{
|
{
|
||||||
@@ -421,7 +393,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (!CanDisplayHints()) { return; }
|
if (!CanDisplayHints()) { return; }
|
||||||
if (character != Character.Controlled || !character.LockHands) { return; }
|
if (character != Character.Controlled || !character.LockHands) { return; }
|
||||||
EnqueueHint("onhandcuffed", onUpdate: () =>
|
DisplayHint("onhandcuffed", onUpdate: () =>
|
||||||
{
|
{
|
||||||
if (character != null && !character.Removed && character.LockHands) { return; }
|
if (character != null && !character.Removed && character.LockHands) { return; }
|
||||||
ActiveHintMessageBox.Close();
|
ActiveHintMessageBox.Close();
|
||||||
@@ -434,7 +406,7 @@ namespace Barotrauma
|
|||||||
if (reactor == null) { return; }
|
if (reactor == null) { return; }
|
||||||
if (reactor.Item.Submarine?.Info?.Type != SubmarineType.Player || reactor.Item.Submarine.TeamID != Character.Controlled.TeamID) { return; }
|
if (reactor.Item.Submarine?.Info?.Type != SubmarineType.Player || reactor.Item.Submarine.TeamID != Character.Controlled.TeamID) { return; }
|
||||||
if (!HasValidJob("engineer")) { return; }
|
if (!HasValidJob("engineer")) { return; }
|
||||||
EnqueueHint("onreactoroutoffuel", onUpdate: () =>
|
DisplayHint("onreactoroutoffuel", onUpdate: () =>
|
||||||
{
|
{
|
||||||
if (reactor?.Item != null && !reactor.Item.Removed && reactor.AvailableFuel < 1) { return; }
|
if (reactor?.Item != null && !reactor.Item.Removed && reactor.AvailableFuel < 1) { return; }
|
||||||
ActiveHintMessageBox.Close();
|
ActiveHintMessageBox.Close();
|
||||||
@@ -445,7 +417,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (!CanDisplayHints()) { return; }
|
if (!CanDisplayHints()) { return; }
|
||||||
if (transitionType == CampaignMode.TransitionType.None) { return; }
|
if (transitionType == CampaignMode.TransitionType.None) { return; }
|
||||||
EnqueueHint($"onavailabletransition.{transitionType.ToString().ToLowerInvariant()}");
|
DisplayHint($"onavailabletransition.{transitionType.ToString().ToLowerInvariant()}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void OnShowSubInventory(Item item)
|
public static void OnShowSubInventory(Item item)
|
||||||
@@ -462,12 +434,31 @@ namespace Barotrauma
|
|||||||
IgnoreReminder("characterchange");
|
IgnoreReminder("characterchange");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void OnCharacterUnconscious(Character character)
|
||||||
|
{
|
||||||
|
if (!CanDisplayHints()) { return; }
|
||||||
|
if (character != Character.Controlled) { return; }
|
||||||
|
if (character.IsDead) { return; }
|
||||||
|
if (character.CharacterHealth != null && character.Vitality < character.CharacterHealth.MinVitality) { return; }
|
||||||
|
DisplayHint("oncharacterunconscious");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void OnCharacterKilled(Character character)
|
||||||
|
{
|
||||||
|
if (!CanDisplayHints()) { return; }
|
||||||
|
if (character != Character.Controlled) { return; }
|
||||||
|
if (GameMain.IsMultiplayer) { return; }
|
||||||
|
if (GameMain.GameSession?.CrewManager == null) { return; }
|
||||||
|
if (GameMain.GameSession.CrewManager.GetCharacters().None(c => !c.IsDead)) { return; }
|
||||||
|
DisplayHint("oncharacterkilled");
|
||||||
|
}
|
||||||
|
|
||||||
private static void OnStartedControlling()
|
private static void OnStartedControlling()
|
||||||
{
|
{
|
||||||
if (Level.IsLoadedOutpost) { return; }
|
if (Level.IsLoadedOutpost) { return; }
|
||||||
if (Character.Controlled?.Info?.Job?.Prefab == null) { return; }
|
if (Character.Controlled?.Info?.Job?.Prefab == null) { return; }
|
||||||
string hintIdentifier = $"onstartedcontrolling.job.{Character.Controlled.Info.Job.Prefab.Identifier}";
|
string hintIdentifier = $"onstartedcontrolling.job.{Character.Controlled.Info.Job.Prefab.Identifier}";
|
||||||
EnqueueHint(hintIdentifier,
|
DisplayHint(hintIdentifier,
|
||||||
icon: Character.Controlled.Info.Job.Prefab.Icon,
|
icon: Character.Controlled.Info.Job.Prefab.Icon,
|
||||||
iconColor: Character.Controlled.Info.Job.Prefab.UIColor,
|
iconColor: Character.Controlled.Info.Job.Prefab.UIColor,
|
||||||
onDisplay: () =>
|
onDisplay: () =>
|
||||||
@@ -500,7 +491,7 @@ namespace Barotrauma
|
|||||||
if (!steering.SteeringPath.Finished && steering.SteeringPath.NextNode != null) { return; }
|
if (!steering.SteeringPath.Finished && steering.SteeringPath.NextNode != null) { return; }
|
||||||
if (steering.LevelStartSelected && (Level.Loaded.StartOutpost == null || !steering.Item.Submarine.AtStartExit)) { return; }
|
if (steering.LevelStartSelected && (Level.Loaded.StartOutpost == null || !steering.Item.Submarine.AtStartExit)) { return; }
|
||||||
if (steering.LevelEndSelected && (Level.Loaded.EndOutpost == null || !steering.Item.Submarine.AtEndExit)) { return; }
|
if (steering.LevelEndSelected && (Level.Loaded.EndOutpost == null || !steering.Item.Submarine.AtEndExit)) { return; }
|
||||||
EnqueueHint("onautopilotreachedoutpost");
|
DisplayHint("onautopilotreachedoutpost");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void OnStatusEffectApplied(ItemComponent component, ActionType actionType, Character character)
|
public static void OnStatusEffectApplied(ItemComponent component, ActionType actionType, Character character)
|
||||||
@@ -509,7 +500,7 @@ namespace Barotrauma
|
|||||||
if (character != Character.Controlled) { return; }
|
if (character != Character.Controlled) { return; }
|
||||||
// Could make this more generic if there will ever be any other status effect related hints
|
// Could make this more generic if there will ever be any other status effect related hints
|
||||||
if (!(component is Repairable) || actionType != ActionType.OnFailure) { return; }
|
if (!(component is Repairable) || actionType != ActionType.OnFailure) { return; }
|
||||||
EnqueueHint("onrepairfailed");
|
DisplayHint("onrepairfailed");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CheckIfDivingGearOutOfOxygen()
|
private static void CheckIfDivingGearOutOfOxygen()
|
||||||
@@ -517,12 +508,12 @@ namespace Barotrauma
|
|||||||
if (!CanDisplayHints()) { return; }
|
if (!CanDisplayHints()) { return; }
|
||||||
var divingGear = Character.Controlled.GetEquippedItem("diving");
|
var divingGear = Character.Controlled.GetEquippedItem("diving");
|
||||||
if (divingGear?.OwnInventory == null) { return; }
|
if (divingGear?.OwnInventory == null) { return; }
|
||||||
if (divingGear.GetContainedItemConditionPercentage() > 0.05f) { return; }
|
if (divingGear.GetContainedItemConditionPercentage() > 0.0f) { return; }
|
||||||
EnqueueHint("ondivinggearoutofoxygen", onUpdate: () =>
|
DisplayHint("ondivinggearoutofoxygen", onUpdate: () =>
|
||||||
{
|
{
|
||||||
if (divingGear == null || divingGear.Removed ||
|
if (divingGear == null || divingGear.Removed ||
|
||||||
Character.Controlled == null || !Character.Controlled.HasEquippedItem(divingGear) ||
|
Character.Controlled == null || !Character.Controlled.HasEquippedItem(divingGear) ||
|
||||||
divingGear.GetContainedItemConditionPercentage() > 0.05f)
|
divingGear.GetContainedItemConditionPercentage() > 0.0f)
|
||||||
{
|
{
|
||||||
ActiveHintMessageBox.Close();
|
ActiveHintMessageBox.Close();
|
||||||
}
|
}
|
||||||
@@ -535,15 +526,21 @@ namespace Barotrauma
|
|||||||
if (Character.Controlled.CurrentHull == null) { return; }
|
if (Character.Controlled.CurrentHull == null) { return; }
|
||||||
foreach (var gap in Character.Controlled.CurrentHull.ConnectedGaps)
|
foreach (var gap in Character.Controlled.CurrentHull.ConnectedGaps)
|
||||||
{
|
{
|
||||||
if (!gap.IsRoomToRoom) { continue; }
|
|
||||||
if (gap.ConnectedDoor == null || gap.ConnectedDoor.Impassable) { continue; }
|
if (gap.ConnectedDoor == null || gap.ConnectedDoor.Impassable) { continue; }
|
||||||
if (Vector2.DistanceSquared(Character.Controlled.WorldPosition, gap.ConnectedDoor.Item.WorldPosition) > 400 * 400) { continue; }
|
if (Vector2.DistanceSquared(Character.Controlled.WorldPosition, gap.ConnectedDoor.Item.WorldPosition) > 400 * 400) { continue; }
|
||||||
|
if (!gap.IsRoomToRoom)
|
||||||
|
{
|
||||||
|
if (!(Character.Controlled.GetEquippedItem("deepdiving") is Item)) { continue; }
|
||||||
|
if (Character.Controlled.IsProtectedFromPressure()) { continue; }
|
||||||
|
if (DisplayHint("divingsuitwarning", extendTextTag: false)) { return; }
|
||||||
|
continue;
|
||||||
|
}
|
||||||
foreach (var me in gap.linkedTo)
|
foreach (var me in gap.linkedTo)
|
||||||
{
|
{
|
||||||
if (me == Character.Controlled.CurrentHull) { continue; }
|
if (me == Character.Controlled.CurrentHull) { continue; }
|
||||||
if (!(me is Hull adjacentHull)) { continue; }
|
if (!(me is Hull adjacentHull)) { continue; }
|
||||||
if (adjacentHull.LethalPressure > 5.0f && EnqueueHint("onadjacenthull.highpressure")) { return; }
|
if (adjacentHull.LethalPressure > 5.0f && DisplayHint("onadjacenthull.highpressure")) { return; }
|
||||||
if (adjacentHull.WaterPercentage > 75 && !BallastHulls.Contains(adjacentHull) && EnqueueHint("onadjacenthull.highwaterpercentage")) { return; }
|
if (adjacentHull.WaterPercentage > 75 && !BallastHulls.Contains(adjacentHull) && DisplayHint("onadjacenthull.highwaterpercentage")) { return; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -552,23 +549,23 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (!CanDisplayHints()) { return; }
|
if (!CanDisplayHints()) { return; }
|
||||||
if (Level.Loaded == null) { return; }
|
if (Level.Loaded == null) { return; }
|
||||||
if (Timing.TotalTime < GameMain.GameSession.RoundStartTime + TimeBeforeReminders) { return; }
|
if (GameMain.GameScreen.GameTime < TimeRoundStarted + TimeBeforeReminders) { return; }
|
||||||
if (Timing.TotalTime < TimeReminderLastDisplayed + ReminderCooldown) { return; }
|
if (GameMain.GameScreen.GameTime < TimeReminderLastDisplayed + ReminderCooldown) { return; }
|
||||||
|
|
||||||
string hintIdentifierBase = "reminder";
|
string hintIdentifierBase = "reminder";
|
||||||
|
|
||||||
if (GameMain.GameSession.GameMode.IsSinglePlayer)
|
if (GameMain.GameSession.GameMode.IsSinglePlayer)
|
||||||
{
|
{
|
||||||
if (EnqueueHint($"{hintIdentifierBase}.characterchange"))
|
if (DisplayHint($"{hintIdentifierBase}.characterchange"))
|
||||||
{
|
{
|
||||||
TimeReminderLastDisplayed = Timing.TotalTime;
|
TimeReminderLastDisplayed = GameMain.GameScreen.GameTime;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Level.Loaded.Type != LevelData.LevelType.Outpost)
|
if (Level.Loaded.Type != LevelData.LevelType.Outpost)
|
||||||
{
|
{
|
||||||
if (EnqueueHint($"{hintIdentifierBase}.commandinterface",
|
if (DisplayHint($"{hintIdentifierBase}.commandinterface",
|
||||||
variableTags: new string[] { "[commandkey]" },
|
variableTags: new string[] { "[commandkey]" },
|
||||||
variableValues: new string[] { GameMain.Config.KeyBindText(InputType.Command) },
|
variableValues: new string[] { GameMain.Config.KeyBindText(InputType.Command) },
|
||||||
onUpdate: () =>
|
onUpdate: () =>
|
||||||
@@ -577,12 +574,12 @@ namespace Barotrauma
|
|||||||
ActiveHintMessageBox.Close();
|
ActiveHintMessageBox.Close();
|
||||||
}))
|
}))
|
||||||
{
|
{
|
||||||
TimeReminderLastDisplayed = Timing.TotalTime;
|
TimeReminderLastDisplayed = GameMain.GameScreen.GameTime;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EnqueueHint($"{hintIdentifierBase}.tabmenu",
|
if (DisplayHint($"{hintIdentifierBase}.tabmenu",
|
||||||
variableTags: new string[] { "[infotabkey]" },
|
variableTags: new string[] { "[infotabkey]" },
|
||||||
variableValues: new string[] { GameMain.Config.KeyBindText(InputType.InfoTab) },
|
variableValues: new string[] { GameMain.Config.KeyBindText(InputType.InfoTab) },
|
||||||
onUpdate: () =>
|
onUpdate: () =>
|
||||||
@@ -591,21 +588,21 @@ namespace Barotrauma
|
|||||||
ActiveHintMessageBox.Close();
|
ActiveHintMessageBox.Close();
|
||||||
}))
|
}))
|
||||||
{
|
{
|
||||||
TimeReminderLastDisplayed = Timing.TotalTime;
|
TimeReminderLastDisplayed = GameMain.GameScreen.GameTime;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Character.Controlled.Inventory?.GetItemInLimbSlot(InvSlotType.Bag)?.Prefab?.Identifier == "toolbelt")
|
if (Character.Controlled.Inventory?.GetItemInLimbSlot(InvSlotType.Bag)?.Prefab?.Identifier == "toolbelt")
|
||||||
{
|
{
|
||||||
if (EnqueueHint($"{hintIdentifierBase}.toolbelt"))
|
if (DisplayHint($"{hintIdentifierBase}.toolbelt"))
|
||||||
{
|
{
|
||||||
TimeReminderLastDisplayed = Timing.TotalTime;
|
TimeReminderLastDisplayed = GameMain.GameScreen.GameTime;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool EnqueueHint(string hintIdentifier, string[] variableTags = null, string[] variableValues = null, Sprite icon = null, Color? iconColor = null, Action onDisplay = null, Action onUpdate = null)
|
private static bool DisplayHint(string hintIdentifier, bool extendTextTag = true, string[] variableTags = null, string[] variableValues = null, Sprite icon = null, Color? iconColor = null, Action onDisplay = null, Action onUpdate = null)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(hintIdentifier)) { return false; }
|
if (string.IsNullOrEmpty(hintIdentifier)) { return false; }
|
||||||
if (!HintIdentifiers.Contains(hintIdentifier)) { return false; }
|
if (!HintIdentifiers.Contains(hintIdentifier)) { return false; }
|
||||||
@@ -613,7 +610,7 @@ namespace Barotrauma
|
|||||||
if (HintsIgnoredThisRound.Contains(hintIdentifier)) { return false; }
|
if (HintsIgnoredThisRound.Contains(hintIdentifier)) { return false; }
|
||||||
|
|
||||||
string text;
|
string text;
|
||||||
string textTag = $"hint.{hintIdentifier}";
|
string textTag = extendTextTag ? $"hint.{hintIdentifier}" : hintIdentifier;
|
||||||
if (variableTags != null && variableTags != null && variableTags.Length > 0 && variableTags.Length == variableValues.Length)
|
if (variableTags != null && variableTags != null && variableTags.Length > 0 && variableTags.Length == variableValues.Length)
|
||||||
{
|
{
|
||||||
text = TextManager.GetWithVariables(textTag, variableTags, variableValues, returnNull: true);
|
text = TextManager.GetWithVariables(textTag, variableTags, variableValues, returnNull: true);
|
||||||
@@ -631,9 +628,16 @@ namespace Barotrauma
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var hint = new HintInfo(hintIdentifier, text, icon, iconColor, onDisplay, onUpdate);
|
|
||||||
HintQueue.Enqueue(hint);
|
|
||||||
HintsIgnoredThisRound.Add(hintIdentifier);
|
HintsIgnoredThisRound.Add(hintIdentifier);
|
||||||
|
|
||||||
|
ActiveHintMessageBox = new GUIMessageBox(hintIdentifier, text, icon);
|
||||||
|
if (iconColor.HasValue) { ActiveHintMessageBox.IconColor = iconColor.Value; }
|
||||||
|
OnUpdate = onUpdate;
|
||||||
|
|
||||||
|
SoundPlayer.PlayUISound(GUISoundType.UIMessage);
|
||||||
|
ActiveHintMessageBox.InnerFrame.Flash(color: iconColor ?? Color.Orange, flashDuration: 0.75f);
|
||||||
|
onDisplay?.Invoke();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -678,6 +682,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (HintIdentifiers == null) { return false; }
|
if (HintIdentifiers == null) { return false; }
|
||||||
if (GameMain.Config.DisableInGameHints) { return false; }
|
if (GameMain.Config.DisableInGameHints) { return false; }
|
||||||
|
if (ActiveHintMessageBox != null) { return false; }
|
||||||
if (requireControllingCharacter && Character.Controlled == null) { return false; }
|
if (requireControllingCharacter && Character.Controlled == null) { return false; }
|
||||||
var gameMode = GameMain.GameSession?.GameMode;
|
var gameMode = GameMain.GameSession?.GameMode;
|
||||||
if (!(gameMode is CampaignMode || gameMode is MissionMode)) { return false; }
|
if (!(gameMode is CampaignMode || gameMode is MissionMode)) { return false; }
|
||||||
|
|||||||
@@ -266,7 +266,9 @@ namespace Barotrauma
|
|||||||
displayedMission.Description;
|
displayedMission.Description;
|
||||||
GUIImage missionIcon = new GUIImage(new RectTransform(new Point((int)(missionContentHorizontal.Rect.Height)), missionContentHorizontal.RectTransform), displayedMission.Prefab.Icon, scaleToFit: true)
|
GUIImage missionIcon = new GUIImage(new RectTransform(new Point((int)(missionContentHorizontal.Rect.Height)), missionContentHorizontal.RectTransform), displayedMission.Prefab.Icon, scaleToFit: true)
|
||||||
{
|
{
|
||||||
Color = displayedMission.Prefab.IconColor
|
Color = displayedMission.Prefab.IconColor,
|
||||||
|
HoverColor = displayedMission.Prefab.IconColor,
|
||||||
|
SelectedColor = displayedMission.Prefab.IconColor
|
||||||
};
|
};
|
||||||
missionIcon.RectTransform.MinSize = new Point((int)(missionContentHorizontal.Rect.Height * 0.9f));
|
missionIcon.RectTransform.MinSize = new Point((int)(missionContentHorizontal.Rect.Height * 0.9f));
|
||||||
if (selectedMissions.Contains(displayedMission))
|
if (selectedMissions.Contains(displayedMission))
|
||||||
@@ -278,8 +280,27 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
RelativeSpacing = 0.05f
|
RelativeSpacing = 0.05f
|
||||||
};
|
};
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
|
var missionNameTextBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
|
||||||
displayedMission.Name, font: GUI.SubHeadingFont);
|
displayedMission.Name, font: GUI.SubHeadingFont);
|
||||||
|
if (displayedMission.Difficulty.HasValue)
|
||||||
|
{
|
||||||
|
var groupSize = missionNameTextBlock.Rect.Size;
|
||||||
|
groupSize.X -= (int)(missionNameTextBlock.Padding.X + missionNameTextBlock.Padding.Z);
|
||||||
|
var indicatorGroup = new GUILayoutGroup(new RectTransform(groupSize, missionTextContent.RectTransform) { AbsoluteOffset = new Point((int)missionNameTextBlock.Padding.X, 0) },
|
||||||
|
isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
||||||
|
{
|
||||||
|
AbsoluteSpacing = 1
|
||||||
|
};
|
||||||
|
var difficultyColor = displayedMission.GetDifficultyColor();
|
||||||
|
for (int i = 0; i < displayedMission.Difficulty; i++)
|
||||||
|
{
|
||||||
|
new GUIImage(new RectTransform(Vector2.One, indicatorGroup.RectTransform, scaleBasis: ScaleBasis.Smallest) { IsFixedSize = true }, "DifficultyIndicator", scaleToFit: true)
|
||||||
|
{
|
||||||
|
CanBeFocused = false,
|
||||||
|
Color = difficultyColor
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
|
||||||
missionMessage, wrap: true, parseRichText: true);
|
missionMessage, wrap: true, parseRichText: true);
|
||||||
if (selectedMissions.Contains(displayedMission) && displayedMission.Completed && displayedMission.Reward > 0)
|
if (selectedMissions.Contains(displayedMission) && displayedMission.Completed && displayedMission.Reward > 0)
|
||||||
@@ -430,7 +451,7 @@ namespace Barotrauma
|
|||||||
Faction unlockFaction = null;
|
Faction unlockFaction = null;
|
||||||
if (!string.IsNullOrEmpty(unlockEvent.UnlockPathFaction))
|
if (!string.IsNullOrEmpty(unlockEvent.UnlockPathFaction))
|
||||||
{
|
{
|
||||||
unlockFaction = GameMain.GameSession.Campaign.Factions.Find(f => f.Prefab.Identifier == unlockEvent.UnlockPathFaction);
|
unlockFaction = GameMain.GameSession.Campaign.Factions.Find(f => f.Prefab.Identifier.Equals(unlockEvent.UnlockPathFaction, StringComparison.OrdinalIgnoreCase));
|
||||||
unlockReputation = unlockFaction?.Reputation;
|
unlockReputation = unlockFaction?.Reputation;
|
||||||
}
|
}
|
||||||
float normalizedUnlockReputation = MathUtils.InverseLerp(unlockReputation.MinReputation, unlockReputation.MaxReputation, unlockEvent.UnlockPathReputation);
|
float normalizedUnlockReputation = MathUtils.InverseLerp(unlockReputation.MinReputation, unlockReputation.MaxReputation, unlockEvent.UnlockPathReputation);
|
||||||
|
|||||||
@@ -160,13 +160,6 @@ namespace Barotrauma
|
|||||||
CreateSlots();
|
CreateSlots();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void RemoveItem(Item item)
|
|
||||||
{
|
|
||||||
if (!Contains(item)) { return; }
|
|
||||||
base.RemoveItem(item);
|
|
||||||
CreateSlots();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void CreateSlots()
|
public override void CreateSlots()
|
||||||
{
|
{
|
||||||
if (visualSlots == null) { visualSlots = new VisualSlot[capacity]; }
|
if (visualSlots == null) { visualSlots = new VisualSlot[capacity]; }
|
||||||
|
|||||||
@@ -381,15 +381,11 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
private void DrawOutputOverLay(SpriteBatch spriteBatch, GUICustomComponent overlayComponent)
|
private void DrawOutputOverLay(SpriteBatch spriteBatch, GUICustomComponent overlayComponent)
|
||||||
{
|
{
|
||||||
if (!outputContainer.Inventory.IsEmpty()) { return; }
|
|
||||||
|
|
||||||
overlayComponent.RectTransform.SetAsLastChild();
|
overlayComponent.RectTransform.SetAsLastChild();
|
||||||
|
|
||||||
FabricationRecipe targetItem = fabricatedItem ?? selectedItem;
|
FabricationRecipe targetItem = fabricatedItem ?? selectedItem;
|
||||||
if (targetItem != null)
|
if (targetItem != null)
|
||||||
{
|
{
|
||||||
var itemIcon = targetItem.TargetItem.InventoryIcon ?? targetItem.TargetItem.sprite;
|
|
||||||
|
|
||||||
Rectangle slotRect = outputContainer.Inventory.visualSlots[0].Rect;
|
Rectangle slotRect = outputContainer.Inventory.visualSlots[0].Rect;
|
||||||
|
|
||||||
if (fabricatedItem != null)
|
if (fabricatedItem != null)
|
||||||
@@ -402,11 +398,15 @@ namespace Barotrauma.Items.Components
|
|||||||
GUI.Style.Green * 0.5f, isFilled: true);
|
GUI.Style.Green * 0.5f, isFilled: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
itemIcon.Draw(
|
if (outputContainer.Inventory.IsEmpty())
|
||||||
spriteBatch,
|
{
|
||||||
slotRect.Center.ToVector2(),
|
var itemIcon = targetItem.TargetItem.InventoryIcon ?? targetItem.TargetItem.sprite;
|
||||||
color: targetItem.TargetItem.InventoryIconColor * 0.4f,
|
itemIcon.Draw(
|
||||||
scale: Math.Min(slotRect.Width / itemIcon.size.X, slotRect.Height / itemIcon.size.Y) * 0.9f);
|
spriteBatch,
|
||||||
|
slotRect.Center.ToVector2(),
|
||||||
|
color: targetItem.TargetItem.InventoryIconColor * 0.4f,
|
||||||
|
scale: Math.Min(slotRect.Width / itemIcon.size.X, slotRect.Height / itemIcon.size.Y) * 0.9f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tooltip != null)
|
if (tooltip != null)
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
Default,
|
Default,
|
||||||
Disruption,
|
Disruption,
|
||||||
Destructible
|
Destructible,
|
||||||
|
LongRange
|
||||||
}
|
}
|
||||||
|
|
||||||
private PathFinder pathFinder;
|
private PathFinder pathFinder;
|
||||||
@@ -69,6 +70,9 @@ namespace Barotrauma.Items.Components
|
|||||||
private const float DisruptionUpdateInterval = 0.2f;
|
private const float DisruptionUpdateInterval = 0.2f;
|
||||||
private float disruptionUpdateTimer;
|
private float disruptionUpdateTimer;
|
||||||
|
|
||||||
|
private const float LongRangeUpdateInterval = 10.0f;
|
||||||
|
private float longRangeUpdateTimer;
|
||||||
|
|
||||||
private float showDirectionalIndicatorTimer;
|
private float showDirectionalIndicatorTimer;
|
||||||
|
|
||||||
private readonly List<LevelObject> nearbyObjects = new List<LevelObject>();
|
private readonly List<LevelObject> nearbyObjects = new List<LevelObject>();
|
||||||
@@ -122,6 +126,10 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
BlipType.Destructible,
|
BlipType.Destructible,
|
||||||
new Color[] { Color.TransparentBlack, new Color(74, 113, 75) * 0.8f, new Color(151, 236, 172) * 0.8f, new Color(153, 217, 234) * 0.8f }
|
new Color[] { Color.TransparentBlack, new Color(74, 113, 75) * 0.8f, new Color(151, 236, 172) * 0.8f, new Color(153, 217, 234) * 0.8f }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
BlipType.LongRange,
|
||||||
|
new Color[] { Color.TransparentBlack, Color.TransparentBlack, new Color(254, 68, 19) * 0.8f, Color.TransparentBlack }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -674,7 +682,6 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
disruptionUpdateTimer -= deltaTime;
|
disruptionUpdateTimer -= deltaTime;
|
||||||
|
|
||||||
for (var pingIndex = 0; pingIndex < activePingsCount; ++pingIndex)
|
for (var pingIndex = 0; pingIndex < activePingsCount; ++pingIndex)
|
||||||
{
|
{
|
||||||
var activePing = activePings[pingIndex];
|
var activePing = activePings[pingIndex];
|
||||||
@@ -684,12 +691,44 @@ namespace Barotrauma.Items.Components
|
|||||||
pingRadius, activePing.PrevPingRadius, displayScale, range / zoom, passive: false, pingStrength: 2.0f);
|
pingRadius, activePing.PrevPingRadius, displayScale, range / zoom, passive: false, pingStrength: 2.0f);
|
||||||
activePing.PrevPingRadius = pingRadius;
|
activePing.PrevPingRadius = pingRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (disruptionUpdateTimer <= 0.0f)
|
if (disruptionUpdateTimer <= 0.0f)
|
||||||
{
|
{
|
||||||
disruptionUpdateTimer = DisruptionUpdateInterval;
|
disruptionUpdateTimer = DisruptionUpdateInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
longRangeUpdateTimer -= deltaTime;
|
||||||
|
if (longRangeUpdateTimer <= 0.0f)
|
||||||
|
{
|
||||||
|
foreach (Character c in Character.CharacterList)
|
||||||
|
{
|
||||||
|
if (c.AnimController.CurrentHull != null || !c.Enabled) { continue; }
|
||||||
|
if (c.Params.HideInSonar) { continue; }
|
||||||
|
|
||||||
|
if (!c.IsUnconscious && c.Params.DistantSonarRange > 0.0f &&
|
||||||
|
((c.WorldPosition - transducerCenter) * displayScale).LengthSquared() > DisplayRadius * DisplayRadius)
|
||||||
|
{
|
||||||
|
float dist = Vector2.Distance(c.WorldPosition, transducerCenter);
|
||||||
|
Vector2 targetDir = (c.WorldPosition - transducerCenter) / dist;
|
||||||
|
int blipCount = (int)MathHelper.Clamp(c.Mass, 50, 200);
|
||||||
|
for (int i = 0; i < blipCount; i++)
|
||||||
|
{
|
||||||
|
float angle = Rand.Range(-0.5f, 0.5f);
|
||||||
|
Vector2 blipDir = MathUtils.RotatePoint(targetDir, angle);
|
||||||
|
Vector2 invBlipDir = MathUtils.RotatePoint(targetDir, -angle);
|
||||||
|
var longRangeBlip = new SonarBlip(transducerCenter + blipDir * Range * 0.9f, Rand.Range(1.9f, 2.1f), Rand.Range(1.0f, 1.5f), BlipType.LongRange)
|
||||||
|
{
|
||||||
|
Velocity = -invBlipDir * (MathUtils.Round(Rand.Range(8000.0f, 15000.0f), 2000.0f) - Math.Abs(angle * angle * 10000.0f)),
|
||||||
|
Rotation = (float)Math.Atan2(-invBlipDir.Y, invBlipDir.X),
|
||||||
|
Alpha = MathUtils.Pow2((c.Params.DistantSonarRange - dist) / c.Params.DistantSonarRange)
|
||||||
|
};
|
||||||
|
longRangeBlip.Size.Y *= 5.0f;
|
||||||
|
sonarBlips.Add(longRangeBlip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
longRangeUpdateTimer = LongRangeUpdateInterval;
|
||||||
|
}
|
||||||
|
|
||||||
if (currentMode == Mode.Active && currentPingIndex != -1)
|
if (currentMode == Mode.Active && currentPingIndex != -1)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -946,6 +985,19 @@ namespace Barotrauma.Items.Components
|
|||||||
if (connectedSubs.Contains(sub)) { continue; }
|
if (connectedSubs.Contains(sub)) { continue; }
|
||||||
if (sub.WorldPosition.Y > Level.Loaded.Size.Y) { continue; }
|
if (sub.WorldPosition.Y > Level.Loaded.Size.Y) { continue; }
|
||||||
|
|
||||||
|
if (item.Submarine != null)
|
||||||
|
{
|
||||||
|
//hide enemy team
|
||||||
|
if (sub.TeamID == CharacterTeamType.Team1 && (item.Submarine.TeamID == CharacterTeamType.Team2 || Character.Controlled?.TeamID == CharacterTeamType.Team2))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (sub.TeamID == CharacterTeamType.Team2 && (item.Submarine.TeamID == CharacterTeamType.Team1 || Character.Controlled?.TeamID == CharacterTeamType.Team1))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DrawMarker(spriteBatch,
|
DrawMarker(spriteBatch,
|
||||||
sub.Info.DisplayName,
|
sub.Info.DisplayName,
|
||||||
sub.Info.HasTag(SubmarineTag.Shuttle) ? "shuttle" : "submarine",
|
sub.Info.HasTag(SubmarineTag.Shuttle) ? "shuttle" : "submarine",
|
||||||
@@ -1045,15 +1097,17 @@ namespace Barotrauma.Items.Components
|
|||||||
foreach (DockingPort dockingPort in DockingPort.List)
|
foreach (DockingPort dockingPort in DockingPort.List)
|
||||||
{
|
{
|
||||||
if (Level.Loaded != null && dockingPort.Item.Submarine.WorldPosition.Y > Level.Loaded.Size.Y) { continue; }
|
if (Level.Loaded != null && dockingPort.Item.Submarine.WorldPosition.Y > Level.Loaded.Size.Y) { continue; }
|
||||||
|
|
||||||
if (dockingPort.Item.Submarine == null) { continue; }
|
if (dockingPort.Item.Submarine == null) { continue; }
|
||||||
if (dockingPort.Item.Submarine.Info.IsWreck) { continue; }
|
if (dockingPort.Item.Submarine.Info.IsWreck) { continue; }
|
||||||
|
|
||||||
//don't show the docking ports of the opposing team on the sonar
|
//don't show the docking ports of the opposing team on the sonar
|
||||||
if (item.Submarine != null)
|
if (item.Submarine != null)
|
||||||
{
|
{
|
||||||
if ((dockingPort.Item.Submarine.TeamID == CharacterTeamType.Team1 && item.Submarine.TeamID == CharacterTeamType.Team2) ||
|
if (dockingPort.Item.Submarine.TeamID == CharacterTeamType.Team1 && (item.Submarine.TeamID == CharacterTeamType.Team2 || Character.Controlled?.TeamID == CharacterTeamType.Team2))
|
||||||
(dockingPort.Item.Submarine.TeamID == CharacterTeamType.Team2 && item.Submarine.TeamID == CharacterTeamType.Team1))
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (dockingPort.Item.Submarine.TeamID == CharacterTeamType.Team2 && (item.Submarine.TeamID == CharacterTeamType.Team1 || Character.Controlled?.TeamID == CharacterTeamType.Team1))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1555,12 +1609,12 @@ namespace Barotrauma.Items.Components
|
|||||||
float scale = (strength + 3.0f) * blip.Scale * blipScale;
|
float scale = (strength + 3.0f) * blip.Scale * blipScale;
|
||||||
Color color = ToolBox.GradientLerp(strength, blipColorGradient[blip.BlipType]);
|
Color color = ToolBox.GradientLerp(strength, blipColorGradient[blip.BlipType]);
|
||||||
|
|
||||||
sonarBlip.Draw(spriteBatch, center + pos, color, sonarBlip.Origin, blip.Rotation ?? MathUtils.VectorToAngle(pos),
|
sonarBlip.Draw(spriteBatch, center + pos, color * blip.Alpha, sonarBlip.Origin, blip.Rotation ?? MathUtils.VectorToAngle(pos),
|
||||||
blip.Size * scale * 0.5f, SpriteEffects.None, 0);
|
blip.Size * scale * 0.5f, SpriteEffects.None, 0);
|
||||||
|
|
||||||
pos += Rand.Range(0.0f, 1.0f) * dir + Rand.Range(-scale, scale) * normal;
|
pos += Rand.Range(0.0f, 1.0f) * dir + Rand.Range(-scale, scale) * normal;
|
||||||
|
|
||||||
sonarBlip.Draw(spriteBatch, center + pos, color * 0.5f, sonarBlip.Origin, 0, scale, SpriteEffects.None, 0);
|
sonarBlip.Draw(spriteBatch, center + pos, color * 0.5f * blip.Alpha, sonarBlip.Origin, 0, scale, SpriteEffects.None, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawMarker(SpriteBatch spriteBatch, string label, string iconIdentifier, object targetIdentifier, Vector2 worldPosition, Vector2 transducerPosition, float scale, Vector2 center, float radius,
|
private void DrawMarker(SpriteBatch spriteBatch, string label, string iconIdentifier, object targetIdentifier, Vector2 worldPosition, Vector2 transducerPosition, float scale, Vector2 center, float radius,
|
||||||
@@ -1778,6 +1832,7 @@ namespace Barotrauma.Items.Components
|
|||||||
public float? Rotation;
|
public float? Rotation;
|
||||||
public Vector2 Size;
|
public Vector2 Size;
|
||||||
public Sonar.BlipType BlipType;
|
public Sonar.BlipType BlipType;
|
||||||
|
public float Alpha = 1.0f;
|
||||||
|
|
||||||
public SonarBlip(Vector2 pos, float fadeTimer, float scale, Sonar.BlipType blipType = Sonar.BlipType.Default)
|
public SonarBlip(Vector2 pos, float fadeTimer, float scale, Sonar.BlipType blipType = Sonar.BlipType.Default)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -727,7 +727,19 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pressureWarningText.Visible = item.Submarine != null && item.Submarine.AtDamageDepth && Timing.TotalTime % 1.0f < 0.8f;
|
pressureWarningText.Visible = item.Submarine != null && Timing.TotalTime % 1.0f < 0.8f;
|
||||||
|
float depthEffectThreshold = 500.0f;
|
||||||
|
if (Level.Loaded != null && pressureWarningText.Visible &&
|
||||||
|
item.Submarine.RealWorldDepth > Level.Loaded.RealWorldCrushDepth - depthEffectThreshold && item.Submarine.RealWorldDepth > item.Submarine.RealWorldCrushDepth - depthEffectThreshold)
|
||||||
|
{
|
||||||
|
pressureWarningText.Visible = true;
|
||||||
|
pressureWarningText.Text = item.Submarine.AtDamageDepth ? TextManager.Get("SteeringDepthWarning") : TextManager.Get("SteeringDepthWarningLow").Replace("[crushdepth]", ((int)item.Submarine.RealWorldCrushDepth).ToString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pressureWarningText.Visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
iceSpireWarningText.Visible = item.Submarine != null && !pressureWarningText.Visible && showIceSpireWarning && Timing.TotalTime % 1.0f < 0.8f;
|
iceSpireWarningText.Visible = item.Submarine != null && !pressureWarningText.Visible && showIceSpireWarning && Timing.TotalTime % 1.0f < 0.8f;
|
||||||
|
|
||||||
if (Vector2.DistanceSquared(PlayerInput.MousePosition, steerArea.Rect.Center.ToVector2()) < steerRadius * steerRadius)
|
if (Vector2.DistanceSquared(PlayerInput.MousePosition, steerArea.Rect.Center.ToVector2()) < steerRadius * steerRadius)
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Barotrauma.Networking;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework;
|
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -28,15 +27,7 @@ namespace Barotrauma.Items.Components
|
|||||||
int x = panelRect.X, y = panelRect.Y;
|
int x = panelRect.X, y = panelRect.Y;
|
||||||
int width = panelRect.Width, height = panelRect.Height;
|
int width = panelRect.Width, height = panelRect.Height;
|
||||||
|
|
||||||
Vector2 scale = new Vector2(GUI.Scale);
|
Vector2 scale = GetScale(panel.GuiFrame.RectTransform.MaxSize, panel.GuiFrame.Rect.Size);
|
||||||
if (panel.GuiFrame.RectTransform.MaxSize.X < int.MaxValue)
|
|
||||||
{
|
|
||||||
scale.X = panel.GuiFrame.RectTransform.MaxSize.X / panel.GuiFrame.Rect.Width;
|
|
||||||
}
|
|
||||||
if (panel.GuiFrame.RectTransform.MaxSize.Y < int.MaxValue)
|
|
||||||
{
|
|
||||||
scale.Y = panel.GuiFrame.RectTransform.MaxSize.Y / panel.GuiFrame.Rect.Height;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool mouseInRect = panelRect.Contains(PlayerInput.MousePosition);
|
bool mouseInRect = panelRect.Contains(PlayerInput.MousePosition);
|
||||||
|
|
||||||
@@ -66,15 +57,15 @@ namespace Barotrauma.Items.Components
|
|||||||
//two passes: first the connector, then the wires to get the wires to render in front
|
//two passes: first the connector, then the wires to get the wires to render in front
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
Vector2 rightPos = new Vector2(x + width - 80 * scale.X, y + 60 * scale.Y);
|
Vector2 rightPos = GetRightPos(x, y, width, scale);
|
||||||
Vector2 leftPos = new Vector2(x + 80 * scale.X, y + 60 * scale.Y);
|
Vector2 leftPos = GetLeftPos(x, y, scale);
|
||||||
|
|
||||||
Vector2 rightWirePos = new Vector2(x + width - 5 * scale.X, y + 30 * scale.Y);
|
Vector2 rightWirePos = new Vector2(x + width - 5 * scale.X, y + 30 * scale.Y);
|
||||||
Vector2 leftWirePos = new Vector2(x + 5 * scale.X, y + 30 * scale.Y);
|
Vector2 leftWirePos = new Vector2(x + 5 * scale.X, y + 30 * scale.Y);
|
||||||
|
|
||||||
int wireInterval = (height - (int)(20 * scale.Y)) / Math.Max(totalWireCount, 1);
|
int wireInterval = (height - (int)(20 * scale.Y)) / Math.Max(totalWireCount, 1);
|
||||||
int connectorIntervalLeft = (height - (int)(100 * scale.Y)) / Math.Max(panel.Connections.Count(c => c.IsOutput), 1);
|
int connectorIntervalLeft = GetConnectorIntervalLeft(height, scale, panel);
|
||||||
int connectorIntervalRight = (height - (int)(100 * scale.Y)) / Math.Max(panel.Connections.Count(c => !c.IsOutput), 1);
|
int connectorIntervalRight = GetConnectorIntervalRight(height, scale, panel);
|
||||||
|
|
||||||
foreach (Connection c in panel.Connections)
|
foreach (Connection c in panel.Connections)
|
||||||
{
|
{
|
||||||
@@ -101,15 +92,12 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
{
|
{
|
||||||
c.DrawConnection(spriteBatch, panel, rightPos,
|
c.DrawConnection(spriteBatch, panel, rightPos, GetOutputLabelPosition(rightPos, panel, c), scale);
|
||||||
new Vector2(rightPos.X - GUI.SmallFont.MeasureString(c.DisplayName.ToUpper()).X - 25 * panel.Scale, rightPos.Y + 5 * panel.Scale),
|
|
||||||
scale);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
c.DrawWires(spriteBatch, panel, rightPos, rightWirePos, mouseInRect, equippedWire, wireInterval);
|
c.DrawWires(spriteBatch, panel, rightPos, rightWirePos, mouseInRect, equippedWire, wireInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
rightPos.Y += connectorIntervalLeft;
|
rightPos.Y += connectorIntervalLeft;
|
||||||
rightWirePos.Y += c.Wires.Count(w => w != null) * wireInterval;
|
rightWirePos.Y += c.Wires.Count(w => w != null) * wireInterval;
|
||||||
}
|
}
|
||||||
@@ -117,15 +105,12 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
{
|
{
|
||||||
c.DrawConnection(spriteBatch, panel, leftPos,
|
c.DrawConnection(spriteBatch, panel, leftPos, GetInputLabelPosition(leftPos, panel, c), scale);
|
||||||
new Vector2(leftPos.X + 25 * panel.Scale, leftPos.Y - 5 * panel.Scale - GUI.SmallFont.MeasureString(c.DisplayName.ToUpper()).Y),
|
|
||||||
scale);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
c.DrawWires(spriteBatch, panel, leftPos, leftWirePos, mouseInRect, equippedWire, wireInterval);
|
c.DrawWires(spriteBatch, panel, leftPos, leftWirePos, mouseInRect, equippedWire, wireInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
leftPos.Y += connectorIntervalRight;
|
leftPos.Y += connectorIntervalRight;
|
||||||
leftWirePos.Y += c.Wires.Count(w => w != null) * wireInterval;
|
leftWirePos.Y += c.Wires.Count(w => w != null) * wireInterval;
|
||||||
}
|
}
|
||||||
@@ -215,14 +200,11 @@ namespace Barotrauma.Items.Components
|
|||||||
private void DrawConnection(SpriteBatch spriteBatch, ConnectionPanel panel, Vector2 position, Vector2 labelPos, Vector2 scale)
|
private void DrawConnection(SpriteBatch spriteBatch, ConnectionPanel panel, Vector2 position, Vector2 labelPos, Vector2 scale)
|
||||||
{
|
{
|
||||||
string text = DisplayName.ToUpper();
|
string text = DisplayName.ToUpper();
|
||||||
Vector2 textSize = GUI.SmallFont.MeasureString(text);
|
|
||||||
|
|
||||||
//nasty
|
//nasty
|
||||||
var labelSprite = GUI.Style.GetComponentStyle("ConnectionPanelLabel")?.Sprites.Values.First().First();
|
if (GUI.Style.GetComponentStyle("ConnectionPanelLabel")?.Sprites.Values.First().First() is UISprite labelSprite)
|
||||||
if (labelSprite != null)
|
|
||||||
{
|
{
|
||||||
Rectangle labelArea = new Rectangle(labelPos.ToPoint(), textSize.ToPoint());
|
Rectangle labelArea = GetLabelArea(labelPos, text, scale);
|
||||||
labelArea.Inflate(10 * scale.X, 3 * scale.Y);
|
|
||||||
labelSprite.Draw(spriteBatch, labelArea, IsPower ? GUI.Style.Red : Color.SteelBlue);
|
labelSprite.Draw(spriteBatch, labelArea, IsPower ? GUI.Style.Red : Color.SteelBlue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -390,5 +372,115 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool CheckConnectionLabelOverlap(ConnectionPanel panel, out Point newRectSize)
|
||||||
|
{
|
||||||
|
Rectangle panelRect = panel.GuiFrame.Rect;
|
||||||
|
int x = panelRect.X, y = panelRect.Y;
|
||||||
|
Vector2 scale = GetScale(panel.GuiFrame.RectTransform.MaxSize, panel.GuiFrame.Rect.Size);
|
||||||
|
Vector2 rightPos = GetRightPos(x, y, panelRect.Width, scale);
|
||||||
|
Vector2 leftPos = GetLeftPos(x, y, scale);
|
||||||
|
int connectorIntervalLeft = GetConnectorIntervalLeft(panelRect.Height, scale, panel);
|
||||||
|
int connectorIntervalRight = GetConnectorIntervalRight(panelRect.Height, scale, panel);
|
||||||
|
newRectSize = panelRect.Size;
|
||||||
|
var labelAreas = new List<Rectangle>();
|
||||||
|
for (int i = 0; i < 100; i++)
|
||||||
|
{
|
||||||
|
labelAreas.Clear();
|
||||||
|
foreach (var c in panel.Connections)
|
||||||
|
{
|
||||||
|
if (c.IsOutput)
|
||||||
|
{
|
||||||
|
var labelArea = GetLabelArea(GetOutputLabelPosition(rightPos, panel, c), c.DisplayName.ToUpper(), scale);
|
||||||
|
labelAreas.Add(labelArea);
|
||||||
|
rightPos.Y += connectorIntervalLeft;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var labelArea = GetLabelArea(GetInputLabelPosition(leftPos, panel, c), c.DisplayName.ToUpper(), scale);
|
||||||
|
labelAreas.Add(labelArea);
|
||||||
|
leftPos.Y += connectorIntervalRight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool foundOverlap = false;
|
||||||
|
for (int j = 0; j < labelAreas.Count; j++)
|
||||||
|
{
|
||||||
|
for (int k = 0; k < labelAreas.Count; k++)
|
||||||
|
{
|
||||||
|
if (k == j) { continue; }
|
||||||
|
if (!labelAreas[j].Intersects(labelAreas[k])) { continue; }
|
||||||
|
newRectSize += new Point(10);
|
||||||
|
Point maxSize = new Point(
|
||||||
|
Math.Max(panel.GuiFrame.RectTransform.MaxSize.X, newRectSize.X),
|
||||||
|
Math.Max(panel.GuiFrame.RectTransform.MaxSize.Y, newRectSize.Y));
|
||||||
|
scale = GetScale(maxSize, newRectSize);
|
||||||
|
rightPos = GetRightPos(x, y, newRectSize.X, scale);
|
||||||
|
leftPos = GetLeftPos(x, y, scale);
|
||||||
|
connectorIntervalLeft = GetConnectorIntervalLeft(newRectSize.Y, scale, panel);
|
||||||
|
connectorIntervalRight = GetConnectorIntervalRight(newRectSize.Y, scale, panel);
|
||||||
|
foundOverlap = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!foundOverlap) { break; }
|
||||||
|
}
|
||||||
|
return newRectSize.X != panel.GuiFrame.Rect.Width || newRectSize.Y > panel.GuiFrame.Rect.Height;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Vector2 GetScale(Point maxSize, Point size)
|
||||||
|
{
|
||||||
|
Vector2 scale = new Vector2(GUI.Scale);
|
||||||
|
if (maxSize.X < int.MaxValue)
|
||||||
|
{
|
||||||
|
scale.X = maxSize.X / size.X;
|
||||||
|
}
|
||||||
|
if (maxSize.Y < int.MaxValue)
|
||||||
|
{
|
||||||
|
scale.Y = maxSize.Y / size.Y;
|
||||||
|
}
|
||||||
|
return scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Vector2 GetInputLabelPosition(Vector2 connectorPosition, ConnectionPanel panel, Connection connection)
|
||||||
|
{
|
||||||
|
return new Vector2(
|
||||||
|
connectorPosition.X + 25 * panel.Scale,
|
||||||
|
connectorPosition.Y - 5 * panel.Scale - GUI.SmallFont.MeasureString(connection.DisplayName.ToUpper()).Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Vector2 GetOutputLabelPosition(Vector2 connectorPosition, ConnectionPanel panel, Connection connection)
|
||||||
|
{
|
||||||
|
return new Vector2(
|
||||||
|
connectorPosition.X - 25 * panel.Scale - GUI.SmallFont.MeasureString(connection.DisplayName.ToUpper()).X,
|
||||||
|
connectorPosition.Y + 5 * panel.Scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Rectangle GetLabelArea(Vector2 labelPos, string text, Vector2 scale)
|
||||||
|
{
|
||||||
|
Vector2 textSize = GUI.SmallFont.MeasureString(text);
|
||||||
|
Rectangle labelArea = new Rectangle(labelPos.ToPoint(), textSize.ToPoint());
|
||||||
|
labelArea.Inflate(10 * scale.X, 3 * scale.Y);
|
||||||
|
return labelArea;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Vector2 GetLeftPos(int x, int y, Vector2 scale)
|
||||||
|
{
|
||||||
|
return new Vector2(x + 80 * scale.X, y + 60 * scale.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Vector2 GetRightPos(int x, int y, int width, Vector2 scale)
|
||||||
|
{
|
||||||
|
return new Vector2(x + width - 80 * scale.X, y + 60 * scale.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int GetConnectorIntervalLeft(int height, Vector2 scale, ConnectionPanel panel)
|
||||||
|
{
|
||||||
|
return (height - (int)(100 * scale.Y)) / Math.Max(panel.Connections.Count(c => c.IsOutput), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int GetConnectorIntervalRight(int height, Vector2 scale, ConnectionPanel panel)
|
||||||
|
{
|
||||||
|
return (height - (int)(100 * scale.Y)) / Math.Max(panel.Connections.Count(c => !c.IsOutput), 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+34
-2
@@ -24,9 +24,15 @@ namespace Barotrauma.Items.Components
|
|||||||
get { return GuiFrame.Rect.Width / 400.0f; }
|
get { return GuiFrame.Rect.Width / 400.0f; }
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void InitProjSpecific(XElement element)
|
private Point originalMaxSize;
|
||||||
|
private Vector2 originalRelativeSize;
|
||||||
|
|
||||||
|
partial void InitProjSpecific()
|
||||||
{
|
{
|
||||||
if (GuiFrame == null) { return; }
|
if (GuiFrame == null) { return; }
|
||||||
|
originalMaxSize = GuiFrame.RectTransform.MaxSize;
|
||||||
|
originalRelativeSize = GuiFrame.RectTransform.RelativeSize;
|
||||||
|
CheckForLabelOverlap();
|
||||||
new GUICustomComponent(new RectTransform(Vector2.One, GuiFrame.RectTransform), DrawConnections, null)
|
new GUICustomComponent(new RectTransform(Vector2.One, GuiFrame.RectTransform), DrawConnections, null)
|
||||||
{
|
{
|
||||||
UserData = this
|
UserData = this
|
||||||
@@ -40,7 +46,7 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
partial void UpdateProjSpecific(float deltaTime)
|
partial void UpdateProjSpecific(float deltaTime)
|
||||||
{
|
{
|
||||||
foreach (Wire wire in DisconnectedWires)
|
foreach (var _ in DisconnectedWires)
|
||||||
{
|
{
|
||||||
if (Rand.Range(0.0f, 500.0f) < 1.0f)
|
if (Rand.Range(0.0f, 500.0f) < 1.0f)
|
||||||
{
|
{
|
||||||
@@ -112,6 +118,32 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnResolutionChanged()
|
||||||
|
{
|
||||||
|
base.OnResolutionChanged();
|
||||||
|
if (GuiFrame == null) { return; }
|
||||||
|
CheckForLabelOverlap();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CheckForLabelOverlap()
|
||||||
|
{
|
||||||
|
GuiFrame.RectTransform.MaxSize = originalMaxSize;
|
||||||
|
GuiFrame.RectTransform.Resize(originalRelativeSize);
|
||||||
|
if (Connection.CheckConnectionLabelOverlap(this, out Point newRectSize))
|
||||||
|
{
|
||||||
|
int xCenter = (int)(GameMain.GraphicsWidth / 2.0f);
|
||||||
|
int maxNewWidth = 2 * Math.Min(xCenter - HUDLayoutSettings.CrewArea.Right, xCenter - HUDLayoutSettings.ChatBoxArea.Right);
|
||||||
|
int yCenter = (int)(GameMain.GraphicsHeight / 2.0f);
|
||||||
|
int maxNewHeight = 2 * Math.Min(yCenter - HUDLayoutSettings.MessageAreaTop.Bottom, HUDLayoutSettings.InventoryTopY - yCenter);
|
||||||
|
// Make sure we don't expand the panel interface too much
|
||||||
|
newRectSize = new Point(Math.Min(newRectSize.X, maxNewWidth), Math.Min(newRectSize.Y, maxNewHeight));
|
||||||
|
GuiFrame.RectTransform.MaxSize = new Point(
|
||||||
|
Math.Max(GuiFrame.RectTransform.MaxSize.X, newRectSize.X),
|
||||||
|
Math.Max(GuiFrame.RectTransform.MaxSize.Y, newRectSize.Y));
|
||||||
|
GuiFrame.RectTransform.Resize(newRectSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
||||||
{
|
{
|
||||||
if (GameMain.Client.MidRoundSyncing)
|
if (GameMain.Client.MidRoundSyncing)
|
||||||
|
|||||||
@@ -67,17 +67,19 @@ namespace Barotrauma.Items.Components
|
|||||||
item.SendSignal(input, "signal_out");
|
item.SendSignal(input, "signal_out");
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void ShowOnDisplay(string input)
|
partial void ShowOnDisplay(string input, bool addToHistory = true)
|
||||||
{
|
{
|
||||||
messageHistory.Add(input);
|
if (addToHistory)
|
||||||
while (messageHistory.Count > MaxMessages)
|
|
||||||
{
|
{
|
||||||
messageHistory.RemoveAt(0);
|
messageHistory.Add(input);
|
||||||
}
|
while (messageHistory.Count > MaxMessages)
|
||||||
|
{
|
||||||
while (historyBox.Content.CountChildren > MaxMessages)
|
messageHistory.RemoveAt(0);
|
||||||
{
|
}
|
||||||
historyBox.RemoveChild(historyBox.Content.Children.First());
|
while (historyBox.Content.CountChildren > MaxMessages)
|
||||||
|
{
|
||||||
|
historyBox.RemoveChild(historyBox.Content.Children.First());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GUITextBlock newBlock = new GUITextBlock(
|
GUITextBlock newBlock = new GUITextBlock(
|
||||||
|
|||||||
@@ -156,7 +156,8 @@ namespace Barotrauma.Items.Components
|
|||||||
drawOffset = sub.DrawPosition + sub.HiddenSubPosition;
|
drawOffset = sub.DrawPosition + sub.HiddenSubPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
float depth = item.IsSelected ? 0.0f : SubEditorScreen.IsWiringMode() ? 0.02f : wireSprite.Depth + (item.ID % 100) * 0.000001f;// item.GetDrawDepth(wireSprite.Depth, wireSprite);
|
float baseDepth = UseSpriteDepth ? item.SpriteDepth : wireSprite.Depth;
|
||||||
|
float depth = item.IsSelected ? 0.0f : SubEditorScreen.IsWiringMode() ? 0.02f : baseDepth + (item.ID % 100) * 0.000001f;// item.GetDrawDepth(wireSprite.Depth, wireSprite);
|
||||||
|
|
||||||
if (item.IsHighlighted)
|
if (item.IsHighlighted)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -302,7 +302,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
if (!string.IsNullOrEmpty(description)) { toolTip += '\n' + description; }
|
if (!string.IsNullOrEmpty(description)) { toolTip += '\n' + description; }
|
||||||
}
|
}
|
||||||
if (itemsInSlot.Count() > 2)
|
if (itemsInSlot.Count() > 1)
|
||||||
{
|
{
|
||||||
string colorStr = XMLExtensions.ColorToString(GUI.Style.Blue);
|
string colorStr = XMLExtensions.ColorToString(GUI.Style.Blue);
|
||||||
toolTip += $"\n‖color:{colorStr}‖[{GameMain.Config.KeyBindText(InputType.TakeOneFromInventorySlot)}] {TextManager.Get("inputtype.takeonefrominventoryslot")}‖color:end‖";
|
toolTip += $"\n‖color:{colorStr}‖[{GameMain.Config.KeyBindText(InputType.TakeOneFromInventorySlot)}] {TextManager.Get("inputtype.takeonefrominventoryslot")}‖color:end‖";
|
||||||
@@ -569,47 +569,41 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (!DraggingItems.Any())
|
if (!DraggingItems.Any())
|
||||||
{
|
{
|
||||||
if (PlayerInput.PrimaryMouseButtonDown() && slots[slotIndex].Any())
|
var interactableItems = Screen.Selected == GameMain.GameScreen ? slots[slotIndex].Items.Where(it => !it.NonInteractable && !it.NonPlayerTeamInteractable) : slots[slotIndex].Items;
|
||||||
|
if (PlayerInput.PrimaryMouseButtonDown() && interactableItems.Any())
|
||||||
{
|
{
|
||||||
if (PlayerInput.KeyDown(InputType.TakeHalfFromInventorySlot))
|
if (PlayerInput.KeyDown(InputType.TakeHalfFromInventorySlot))
|
||||||
{
|
{
|
||||||
DraggingItems.AddRange(slots[slotIndex].Items.Skip(slots[slotIndex].ItemCount / 2));
|
DraggingItems.AddRange(interactableItems.Skip(interactableItems.Count() / 2));
|
||||||
}
|
}
|
||||||
else if (PlayerInput.KeyDown(InputType.TakeOneFromInventorySlot))
|
else if (PlayerInput.KeyDown(InputType.TakeOneFromInventorySlot))
|
||||||
{
|
{
|
||||||
DraggingItems.Add(slots[slotIndex].First());
|
DraggingItems.Add(interactableItems.First());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DraggingItems.AddRange(slots[slotIndex].Items);
|
DraggingItems.AddRange(interactableItems);
|
||||||
}
|
|
||||||
if (Screen.Selected == GameMain.GameScreen)
|
|
||||||
{
|
|
||||||
DraggingItems.RemoveAll(it => it.NonInteractable || it.NonPlayerTeamInteractable);
|
|
||||||
}
|
}
|
||||||
DraggingSlot = slot;
|
DraggingSlot = slot;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (PlayerInput.PrimaryMouseButtonReleased())
|
else if (PlayerInput.PrimaryMouseButtonReleased())
|
||||||
{
|
{
|
||||||
if (PlayerInput.DoubleClicked() && slots[slotIndex].Any())
|
var interactableItems = Screen.Selected == GameMain.GameScreen ? slots[slotIndex].Items.Where(it => !it.NonInteractable && !it.NonPlayerTeamInteractable) : slots[slotIndex].Items;
|
||||||
|
if (PlayerInput.DoubleClicked() && interactableItems.Any())
|
||||||
{
|
{
|
||||||
doubleClickedItems.Clear();
|
doubleClickedItems.Clear();
|
||||||
if (PlayerInput.KeyDown(InputType.TakeHalfFromInventorySlot))
|
if (PlayerInput.KeyDown(InputType.TakeHalfFromInventorySlot))
|
||||||
{
|
{
|
||||||
doubleClickedItems.AddRange(slots[slotIndex].Items.Skip(slots[slotIndex].ItemCount / 2));
|
doubleClickedItems.AddRange(interactableItems.Skip(interactableItems.Count() / 2));
|
||||||
}
|
}
|
||||||
else if (PlayerInput.KeyDown(InputType.TakeOneFromInventorySlot))
|
else if (PlayerInput.KeyDown(InputType.TakeOneFromInventorySlot))
|
||||||
{
|
{
|
||||||
doubleClickedItems.Add(slots[slotIndex].First());
|
doubleClickedItems.Add(interactableItems.First());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
doubleClickedItems.AddRange(slots[slotIndex].Items);
|
doubleClickedItems.AddRange(interactableItems);
|
||||||
}
|
|
||||||
if (Screen.Selected == GameMain.GameScreen)
|
|
||||||
{
|
|
||||||
doubleClickedItems.RemoveAll(it => it.NonInteractable || it.NonPlayerTeamInteractable);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -618,6 +618,7 @@ namespace Barotrauma
|
|||||||
editingHUD = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.25f), GUI.Canvas, Anchor.CenterRight) { MinSize = new Point(400, 0) }) { UserData = this };
|
editingHUD = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.25f), GUI.Canvas, Anchor.CenterRight) { MinSize = new Point(400, 0) }) { UserData = this };
|
||||||
GUIListBox listBox = new GUIListBox(new RectTransform(new Vector2(0.95f, 0.8f), editingHUD.RectTransform, Anchor.Center), style: null)
|
GUIListBox listBox = new GUIListBox(new RectTransform(new Vector2(0.95f, 0.8f), editingHUD.RectTransform, Anchor.Center), style: null)
|
||||||
{
|
{
|
||||||
|
CanTakeKeyBoardFocus = false,
|
||||||
Spacing = (int)(25 * GUI.Scale)
|
Spacing = (int)(25 * GUI.Scale)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -90,7 +90,10 @@ namespace Barotrauma
|
|||||||
private GUIComponent CreateEditingHUD(bool inGame = false)
|
private GUIComponent CreateEditingHUD(bool inGame = false)
|
||||||
{
|
{
|
||||||
editingHUD = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.25f), GUI.Canvas, Anchor.CenterRight) { MinSize = new Point(400, 0) }) { UserData = this };
|
editingHUD = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.25f), GUI.Canvas, Anchor.CenterRight) { MinSize = new Point(400, 0) }) { UserData = this };
|
||||||
GUIListBox listBox = new GUIListBox(new RectTransform(new Vector2(0.95f, 0.8f), editingHUD.RectTransform, Anchor.Center), style: null);
|
GUIListBox listBox = new GUIListBox(new RectTransform(new Vector2(0.95f, 0.8f), editingHUD.RectTransform, Anchor.Center), style: null)
|
||||||
|
{
|
||||||
|
CanTakeKeyBoardFocus = false
|
||||||
|
};
|
||||||
new SerializableEntityEditor(listBox.Content.RectTransform, this, inGame, showName: true, titleFont: GUI.LargeFont);
|
new SerializableEntityEditor(listBox.Content.RectTransform, this, inGame, showName: true, titleFont: GUI.LargeFont);
|
||||||
|
|
||||||
PositionEditingHUD();
|
PositionEditingHUD();
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ namespace Barotrauma.Lights
|
|||||||
private readonly List<LightSource> lights;
|
private readonly List<LightSource> lights;
|
||||||
|
|
||||||
public bool LosEnabled = true;
|
public bool LosEnabled = true;
|
||||||
|
public float LosAlpha = 1f;
|
||||||
public LosMode LosMode = LosMode.Transparent;
|
public LosMode LosMode = LosMode.Transparent;
|
||||||
|
|
||||||
public bool LightingEnabled = true;
|
public bool LightingEnabled = true;
|
||||||
@@ -495,9 +496,10 @@ namespace Barotrauma.Lights
|
|||||||
if ((!LosEnabled || LosMode == LosMode.None) && !ObstructVision) return;
|
if ((!LosEnabled || LosMode == LosMode.None) && !ObstructVision) return;
|
||||||
if (ViewTarget == null) return;
|
if (ViewTarget == null) return;
|
||||||
|
|
||||||
|
if (Character.Controlled == null) { DebugConsole.NewMessage("aaa", Color.Orange); }
|
||||||
|
|
||||||
graphics.SetRenderTarget(LosTexture);
|
graphics.SetRenderTarget(LosTexture);
|
||||||
|
|
||||||
spriteBatch.Begin(SpriteSortMode.Deferred, transformMatrix: cam.Transform * Matrix.CreateScale(new Vector3(GameMain.Config.LightMapScale, GameMain.Config.LightMapScale, 1.0f)));
|
|
||||||
if (ObstructVision)
|
if (ObstructVision)
|
||||||
{
|
{
|
||||||
graphics.Clear(Color.Black);
|
graphics.Clear(Color.Black);
|
||||||
@@ -507,16 +509,17 @@ namespace Barotrauma.Lights
|
|||||||
float rotation = MathUtils.VectorToAngle(losOffset);
|
float rotation = MathUtils.VectorToAngle(losOffset);
|
||||||
|
|
||||||
Vector2 scale = new Vector2(
|
Vector2 scale = new Vector2(
|
||||||
MathHelper.Clamp(losOffset.Length() / 256.0f, 2.0f, 5.0f), 2.0f);
|
MathHelper.Clamp(losOffset.Length() / 256.0f, 4.0f, 5.0f), 3.0f);
|
||||||
|
|
||||||
|
spriteBatch.Begin(SpriteSortMode.Deferred, transformMatrix: cam.Transform * Matrix.CreateScale(new Vector3(GameMain.Config.LightMapScale, GameMain.Config.LightMapScale, 1.0f)));
|
||||||
spriteBatch.Draw(visionCircle, new Vector2(ViewTarget.WorldPosition.X, -ViewTarget.WorldPosition.Y), null, Color.White, rotation,
|
spriteBatch.Draw(visionCircle, new Vector2(ViewTarget.WorldPosition.X, -ViewTarget.WorldPosition.Y), null, Color.White, rotation,
|
||||||
new Vector2(visionCircle.Width * 0.2f, visionCircle.Height / 2), scale, SpriteEffects.None, 0.0f);
|
new Vector2(visionCircle.Width * 0.2f, visionCircle.Height / 2), scale, SpriteEffects.None, 0.0f);
|
||||||
|
spriteBatch.End();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
graphics.Clear(Color.White);
|
graphics.Clear(Color.White);
|
||||||
}
|
}
|
||||||
spriteBatch.End();
|
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------
|
//--------------------------------------
|
||||||
|
|||||||
@@ -465,7 +465,7 @@ namespace Barotrauma
|
|||||||
Rectangle rect = mapContainer.Rect;
|
Rectangle rect = mapContainer.Rect;
|
||||||
|
|
||||||
Vector2 viewSize = new Vector2(rect.Width / zoom, rect.Height / zoom);
|
Vector2 viewSize = new Vector2(rect.Width / zoom, rect.Height / zoom);
|
||||||
Vector2 edgeBuffer = rect.Size.ToVector2() / 2;
|
Vector2 edgeBuffer = new Vector2(rect.Width * 0.05f);
|
||||||
DrawOffset.X = MathHelper.Clamp(DrawOffset.X, -Width - edgeBuffer.X + viewSize.X / 2.0f, edgeBuffer.X - viewSize.X / 2.0f);
|
DrawOffset.X = MathHelper.Clamp(DrawOffset.X, -Width - edgeBuffer.X + viewSize.X / 2.0f, edgeBuffer.X - viewSize.X / 2.0f);
|
||||||
DrawOffset.Y = MathHelper.Clamp(DrawOffset.Y, -Height - edgeBuffer.Y + viewSize.Y / 2.0f, edgeBuffer.Y - viewSize.Y / 2.0f);
|
DrawOffset.Y = MathHelper.Clamp(DrawOffset.Y, -Height - edgeBuffer.Y + viewSize.Y / 2.0f, edgeBuffer.Y - viewSize.Y / 2.0f);
|
||||||
|
|
||||||
@@ -677,11 +677,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
repLabelText = TextManager.Get("reputation");
|
repLabelText = TextManager.Get("reputation");
|
||||||
repLabelSize = GUI.Font.MeasureString(repLabelText);
|
repLabelSize = GUI.Font.MeasureString(repLabelText);
|
||||||
size.X = Math.Max(size.X, repLabelSize.X);
|
repBarSize = new Vector2(GUI.IntScale(200), repLabelSize.Y);
|
||||||
repBarSize = new Vector2(Math.Max(0.75f * size.X, 100), repLabelSize.Y);
|
|
||||||
size.X = Math.Max(size.X, (4.0f / 3.0f) * repBarSize.X);
|
|
||||||
size.Y += 2 * repLabelSize.Y + GUI.IntScale(5) + repBarSize.Y;
|
size.Y += 2 * repLabelSize.Y + GUI.IntScale(5) + repBarSize.Y;
|
||||||
repValueText = HighlightedLocation.Reputation.GetFormattedReputationText(addColorTags: false);
|
repValueText = HighlightedLocation.Reputation.GetFormattedReputationText(addColorTags: false);
|
||||||
|
size.X = Math.Max(size.X, repBarSize.X + GUI.Font.MeasureString(repValueText).X + GUI.IntScale(10));
|
||||||
}
|
}
|
||||||
GUI.Style.GetComponentStyle("OuterGlow").Sprites[GUIComponent.ComponentState.None][0].Draw(
|
GUI.Style.GetComponentStyle("OuterGlow").Sprites[GUIComponent.ComponentState.None][0].Draw(
|
||||||
spriteBatch, new Rectangle((int)(pos.X - 60 * GUI.Scale), (int)(pos.Y - size.Y), (int)(size.X + 120 * GUI.Scale), (int)(size.Y * 2.2f)), Color.Black * hudVisibility);
|
spriteBatch, new Rectangle((int)(pos.X - 60 * GUI.Scale), (int)(pos.Y - size.Y), (int)(size.X + 120 * GUI.Scale), (int)(size.Y * 2.2f)), Color.Black * hudVisibility);
|
||||||
@@ -696,7 +695,7 @@ namespace Barotrauma
|
|||||||
topLeftPos += new Vector2(0.0f, repLabelSize.Y + GUI.IntScale(10));
|
topLeftPos += new Vector2(0.0f, repLabelSize.Y + GUI.IntScale(10));
|
||||||
Rectangle repBarRect = new Rectangle(new Point((int)topLeftPos.X, (int)topLeftPos.Y), new Point((int)repBarSize.X, (int)repBarSize.Y));
|
Rectangle repBarRect = new Rectangle(new Point((int)topLeftPos.X, (int)topLeftPos.Y), new Point((int)repBarSize.X, (int)repBarSize.Y));
|
||||||
RoundSummary.DrawReputationBar(spriteBatch, repBarRect, HighlightedLocation.Reputation.NormalizedValue);
|
RoundSummary.DrawReputationBar(spriteBatch, repBarRect, HighlightedLocation.Reputation.NormalizedValue);
|
||||||
GUI.DrawString(spriteBatch, new Vector2(repBarRect.Right + 4, repBarRect.Top), repValueText, Reputation.GetReputationColor(HighlightedLocation.Reputation.NormalizedValue));
|
GUI.DrawString(spriteBatch, new Vector2(repBarRect.Right + GUI.IntScale(5), repBarRect.Top), repValueText, Reputation.GetReputationColor(HighlightedLocation.Reputation.NormalizedValue));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -912,7 +911,7 @@ namespace Barotrauma
|
|||||||
Faction unlockFaction = null;
|
Faction unlockFaction = null;
|
||||||
if (!string.IsNullOrEmpty(unlockEvent.UnlockPathFaction))
|
if (!string.IsNullOrEmpty(unlockEvent.UnlockPathFaction))
|
||||||
{
|
{
|
||||||
unlockFaction = GameMain.GameSession.Campaign.Factions.Find(f => f.Prefab.Identifier == unlockEvent.UnlockPathFaction);
|
unlockFaction = GameMain.GameSession.Campaign.Factions.Find(f => f.Prefab.Identifier.Equals(unlockEvent.UnlockPathFaction, StringComparison.OrdinalIgnoreCase));
|
||||||
unlockReputation = unlockFaction?.Reputation;
|
unlockReputation = unlockFaction?.Reputation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,9 +20,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public static Vector2 StartMovingPos => startMovingPos;
|
public static Vector2 StartMovingPos => startMovingPos;
|
||||||
|
|
||||||
// Quick undo/redo for size and movement only. TODO: Remove if we do a more general implementation.
|
|
||||||
private Memento<Rectangle> rectMemento;
|
|
||||||
|
|
||||||
public event Action<Rectangle> Resized;
|
public event Action<Rectangle> Resized;
|
||||||
|
|
||||||
private static bool resizing;
|
private static bool resizing;
|
||||||
@@ -65,8 +62,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//protected bool isSelected;
|
|
||||||
|
|
||||||
private static bool disableSelect;
|
private static bool disableSelect;
|
||||||
public static bool DisableSelect
|
public static bool DisableSelect
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -95,7 +95,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
int heightScaled = (int)(20 * GUI.Scale);
|
int heightScaled = (int)(20 * GUI.Scale);
|
||||||
editingHUD = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.25f), GUI.Canvas, Anchor.CenterRight) { MinSize = new Point(400, 0) }) { UserData = this };
|
editingHUD = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.25f), GUI.Canvas, Anchor.CenterRight) { MinSize = new Point(400, 0) }) { UserData = this };
|
||||||
GUIListBox listBox = new GUIListBox(new RectTransform(new Vector2(0.95f, 0.8f), editingHUD.RectTransform, Anchor.Center), style: null);
|
GUIListBox listBox = new GUIListBox(new RectTransform(new Vector2(0.95f, 0.8f), editingHUD.RectTransform, Anchor.Center), style: null)
|
||||||
|
{
|
||||||
|
CanTakeKeyBoardFocus = false
|
||||||
|
};
|
||||||
var editor = new SerializableEntityEditor(listBox.Content.RectTransform, this, inGame, showName: true, titleFont: GUI.LargeFont) { UserData = this };
|
var editor = new SerializableEntityEditor(listBox.Content.RectTransform, this, inGame, showName: true, titleFont: GUI.LargeFont) { UserData = this };
|
||||||
|
|
||||||
if (Submarine.MainSub?.Info?.Type == SubmarineType.OutpostModule)
|
if (Submarine.MainSub?.Info?.Type == SubmarineType.OutpostModule)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
@@ -32,24 +33,45 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void CreatePreviewWindow(GUIComponent parent)
|
public void CreatePreviewWindow(GUIComponent parent)
|
||||||
{
|
{
|
||||||
var content = new GUIButton(new RectTransform(Vector2.One, parent.RectTransform), style: null)
|
var content = new GUIFrame(new RectTransform(Vector2.One, parent.RectTransform), style: null);
|
||||||
|
|
||||||
|
var previewButton = new GUIButton(new RectTransform(new Vector2(1f, 0.5f), content.RectTransform), style: null)
|
||||||
{
|
{
|
||||||
OnClicked = (btn, obj) => { SubmarinePreview.Create(this); return false; }
|
OnClicked = (btn, obj) => { SubmarinePreview.Create(this); return false; },
|
||||||
};
|
};
|
||||||
|
|
||||||
if (PreviewImage == null)
|
var previewImage = PreviewImage ?? savedSubmarines.Find(s => s.Name.Equals(Name, StringComparison.OrdinalIgnoreCase))?.PreviewImage;
|
||||||
|
if (previewImage == null)
|
||||||
{
|
{
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), content.RectTransform), TextManager.Get(SavedSubmarines.Contains(this) ? "SubPreviewImageNotFound" : "SubNotDownloaded"));
|
new GUITextBlock(new RectTransform(Vector2.One, previewButton.RectTransform), TextManager.Get(SavedSubmarines.Contains(this) ? "SubPreviewImageNotFound" : "SubNotDownloaded"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var submarinePreviewBackground = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.5f), content.RectTransform), style: null) { Color = Color.Black };
|
var submarinePreviewBackground = new GUIFrame(new RectTransform(Vector2.One, previewButton.RectTransform), style: null)
|
||||||
new GUIImage(new RectTransform(new Vector2(0.98f), submarinePreviewBackground.RectTransform, Anchor.Center), PreviewImage, scaleToFit: true);
|
{
|
||||||
new GUIFrame(new RectTransform(Vector2.One, submarinePreviewBackground.RectTransform), "InnerGlow", color: Color.Black);
|
Color = Color.Black,
|
||||||
|
HoverColor = Color.Black,
|
||||||
|
SelectedColor = Color.Black,
|
||||||
|
PressedColor = Color.Black,
|
||||||
|
CanBeFocused = false,
|
||||||
|
};
|
||||||
|
new GUIImage(new RectTransform(new Vector2(0.98f), submarinePreviewBackground.RectTransform, Anchor.Center), previewImage, scaleToFit: true) { CanBeFocused = false };
|
||||||
|
new GUIFrame(new RectTransform(Vector2.One, submarinePreviewBackground.RectTransform), "InnerGlow", color: Color.Black) { CanBeFocused = false };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new GUIFrame(new RectTransform(Vector2.One * 0.12f, previewButton.RectTransform, anchor: Anchor.BottomRight, pivot: Pivot.BottomRight, scaleBasis: ScaleBasis.BothHeight)
|
||||||
|
{
|
||||||
|
AbsoluteOffset = new Point((int)(0.03f * previewButton.Rect.Height))
|
||||||
|
},
|
||||||
|
"ExpandButton", Color.White)
|
||||||
|
{
|
||||||
|
Color = Color.White,
|
||||||
|
HoverColor = Color.White,
|
||||||
|
PressedColor = Color.White
|
||||||
|
};
|
||||||
|
|
||||||
var descriptionBox = new GUIListBox(new RectTransform(new Vector2(1, 0.5f), content.RectTransform, Anchor.BottomCenter))
|
var descriptionBox = new GUIListBox(new RectTransform(new Vector2(1, 0.5f), content.RectTransform, Anchor.BottomCenter))
|
||||||
{
|
{
|
||||||
UserData = "descriptionbox",
|
UserData = "descriptionbox",
|
||||||
@@ -59,36 +81,25 @@ namespace Barotrauma
|
|||||||
|
|
||||||
ScalableFont font = parent.Rect.Width < 350 ? GUI.SmallFont : GUI.Font;
|
ScalableFont font = parent.Rect.Width < 350 ? GUI.SmallFont : GUI.Font;
|
||||||
|
|
||||||
CreateSpecsWindow(descriptionBox, font);
|
CreateSpecsWindow(descriptionBox, font, includesDescription: true);
|
||||||
|
|
||||||
//space
|
|
||||||
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.05f), descriptionBox.Content.RectTransform), style: null);
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(Description))
|
|
||||||
{
|
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1, 0), descriptionBox.Content.RectTransform),
|
|
||||||
TextManager.Get("SaveSubDialogDescription", fallBackTag: "WorkshopItemDescription"), font: GUI.Font, wrap: true)
|
|
||||||
{ CanBeFocused = false, ForceUpperCase = true };
|
|
||||||
}
|
|
||||||
|
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1, 0), descriptionBox.Content.RectTransform), Description, font: font, wrap: true)
|
|
||||||
{
|
|
||||||
CanBeFocused = false
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CreateSpecsWindow(GUIListBox parent, ScalableFont font)
|
public void CreateSpecsWindow(GUIListBox parent, ScalableFont font, bool includeTitle = true, bool includesDescription = false)
|
||||||
{
|
{
|
||||||
float leftPanelWidth = 0.6f;
|
float leftPanelWidth = 0.6f;
|
||||||
float rightPanelWidth = 0.4f / leftPanelWidth;
|
float rightPanelWidth = 0.4f;
|
||||||
string className = !HasTag(SubmarineTag.Shuttle) ? TextManager.Get($"submarineclass.{SubmarineClass}") : TextManager.Get("shuttle");
|
string className = !HasTag(SubmarineTag.Shuttle) ? TextManager.Get($"submarineclass.{SubmarineClass}") : TextManager.Get("shuttle");
|
||||||
|
|
||||||
int nameHeight = (int)GUI.LargeFont.MeasureString(DisplayName, true).Y;
|
|
||||||
int classHeight = (int)GUI.SubHeadingFont.MeasureString(className).Y;
|
int classHeight = (int)GUI.SubHeadingFont.MeasureString(className).Y;
|
||||||
int leftPanelWidthInt = (int)(parent.Rect.Width * leftPanelWidth);
|
int leftPanelWidthInt = (int)(parent.Rect.Width * leftPanelWidth);
|
||||||
|
|
||||||
var submarineNameText = new GUITextBlock(new RectTransform(new Point(leftPanelWidthInt, nameHeight + HUDLayoutSettings.Padding / 2), parent.Content.RectTransform), DisplayName, textAlignment: Alignment.CenterLeft, font: GUI.LargeFont) { CanBeFocused = false };
|
GUITextBlock submarineNameText = null;
|
||||||
submarineNameText.RectTransform.MinSize = new Point(0, (int)submarineNameText.TextSize.Y);
|
if (includeTitle)
|
||||||
|
{
|
||||||
|
int nameHeight = (int)GUI.LargeFont.MeasureString(DisplayName, true).Y;
|
||||||
|
submarineNameText = new GUITextBlock(new RectTransform(new Point(leftPanelWidthInt, nameHeight + HUDLayoutSettings.Padding / 2), parent.Content.RectTransform), DisplayName, textAlignment: Alignment.CenterLeft, font: GUI.LargeFont) { CanBeFocused = false };
|
||||||
|
submarineNameText.RectTransform.MinSize = new Point(0, (int)submarineNameText.TextSize.Y);
|
||||||
|
}
|
||||||
var submarineClassText = new GUITextBlock(new RectTransform(new Point(leftPanelWidthInt, classHeight), parent.Content.RectTransform), className, textAlignment: Alignment.CenterLeft, font: GUI.SubHeadingFont) { CanBeFocused = false };
|
var submarineClassText = new GUITextBlock(new RectTransform(new Point(leftPanelWidthInt, classHeight), parent.Content.RectTransform), className, textAlignment: Alignment.CenterLeft, font: GUI.SubHeadingFont) { CanBeFocused = false };
|
||||||
submarineClassText.RectTransform.MinSize = new Point(0, (int)submarineClassText.TextSize.Y);
|
submarineClassText.RectTransform.MinSize = new Point(0, (int)submarineClassText.TextSize.Y);
|
||||||
|
|
||||||
@@ -152,8 +163,30 @@ namespace Barotrauma
|
|||||||
versionText.RectTransform.MinSize = new Point(0, versionText.Children.First().Rect.Height);
|
versionText.RectTransform.MinSize = new Point(0, versionText.Children.First().Rect.Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
submarineNameText.AutoScaleHorizontal = true;
|
if (submarineNameText != null)
|
||||||
GUITextBlock.AutoScaleAndNormalize(parent.Content.Children.Where(c => c is GUITextBlock && c != submarineNameText).Cast<GUITextBlock>());
|
{
|
||||||
|
submarineNameText.AutoScaleHorizontal = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
GUITextBlock descBlock = null;
|
||||||
|
if (includesDescription)
|
||||||
|
{
|
||||||
|
//space
|
||||||
|
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.05f), parent.Content.RectTransform), style: null);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(Description))
|
||||||
|
{
|
||||||
|
var wsItemDesc = new GUITextBlock(new RectTransform(new Vector2(1, 0), parent.Content.RectTransform),
|
||||||
|
TextManager.Get("SaveSubDialogDescription", fallBackTag: "WorkshopItemDescription"), font: GUI.Font, wrap: true)
|
||||||
|
{ CanBeFocused = false, ForceUpperCase = true };
|
||||||
|
|
||||||
|
descBlock = new GUITextBlock(new RectTransform(new Vector2(1, 0), parent.Content.RectTransform), Description, font: font, wrap: true)
|
||||||
|
{
|
||||||
|
CanBeFocused = false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GUITextBlock.AutoScaleAndNormalize(parent.Content.GetAllChildren<GUITextBlock>().Where(c => c != submarineNameText && c != descBlock));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Barotrauma.IO;
|
using Barotrauma.Extensions;
|
||||||
|
using Barotrauma.IO;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using System;
|
using System;
|
||||||
@@ -83,28 +84,94 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
|
|
||||||
var innerFrame = new GUIFrame(new RectTransform(Vector2.One * 0.9f, previewFrame.RectTransform, Anchor.Center));
|
var innerFrame = new GUIFrame(new RectTransform(Vector2.One * 0.9f, previewFrame.RectTransform, Anchor.Center));
|
||||||
var verticalLayout = new GUILayoutGroup(new RectTransform(Vector2.One * 0.95f, innerFrame.RectTransform, Anchor.Center), isHorizontal: false);
|
int innerPadding = GUI.IntScale(100f);
|
||||||
var topLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.1f), verticalLayout.RectTransform, Anchor.Center), isHorizontal: true, childAnchor: Anchor.CenterLeft);
|
var innerPadded = new GUIFrame(new RectTransform(new Point(innerFrame.Rect.Width - innerPadding, innerFrame.Rect.Height - innerPadding), previewFrame.RectTransform, Anchor.Center), style: null)
|
||||||
|
|
||||||
new GUITextBlock(new RectTransform(new Vector2(0.95f, 1f), topLayout.RectTransform), subInfo.DisplayName, font: GUI.LargeFont);
|
|
||||||
new GUIButton(new RectTransform(new Vector2(0.05f, 1f), topLayout.RectTransform), TextManager.Get("Close"))
|
|
||||||
{
|
{
|
||||||
OnClicked = (btn, obj) => { Dispose(); return false; }
|
OutlineColor = Color.Black,
|
||||||
|
OutlineThickness = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
new GUICustomComponent(new RectTransform(new Vector2(1f, 0.9f), verticalLayout.RectTransform, Anchor.Center),
|
GUITextBlock titleText = null;
|
||||||
(spriteBatch, component) => { camera.UpdateTransform(true); RenderSubmarine(spriteBatch, component.Rect); },
|
GUIListBox specsContainer = null;
|
||||||
|
|
||||||
|
new GUICustomComponent(new RectTransform(Vector2.One, innerPadded.RectTransform, Anchor.Center),
|
||||||
|
(spriteBatch, component) => {
|
||||||
|
camera.UpdateTransform(interpolate: true, updateListener: false);
|
||||||
|
Rectangle drawRect = new Rectangle(component.Rect.X + 1, component.Rect.Y + 1, component.Rect.Width - 2, component.Rect.Height - 2);
|
||||||
|
RenderSubmarine(spriteBatch, drawRect);
|
||||||
|
},
|
||||||
(deltaTime, component) => {
|
(deltaTime, component) => {
|
||||||
camera.MoveCamera(deltaTime, overrideMouseOn: component.Rect);
|
bool isMouseOnComponent = GUI.MouseOn == component;
|
||||||
if (component.Rect.Contains(PlayerInput.MousePosition) &&
|
camera.MoveCamera(deltaTime, allowZoom: isMouseOnComponent);
|
||||||
|
if (isMouseOnComponent &&
|
||||||
(PlayerInput.MidButtonHeld() || PlayerInput.LeftButtonHeld()))
|
(PlayerInput.MidButtonHeld() || PlayerInput.LeftButtonHeld()))
|
||||||
{
|
{
|
||||||
Vector2 moveSpeed = PlayerInput.MouseSpeed * (float)deltaTime * 60.0f / camera.Zoom;
|
Vector2 moveSpeed = PlayerInput.MouseSpeed * (float)deltaTime * 60.0f / camera.Zoom;
|
||||||
moveSpeed.X = -moveSpeed.X;
|
moveSpeed.X = -moveSpeed.X;
|
||||||
camera.Position += moveSpeed;
|
camera.Position += moveSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (titleText != null && specsContainer != null)
|
||||||
|
{
|
||||||
|
specsContainer.Visible = GUI.IsMouseOn(titleText);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var topContainer = new GUIFrame(new RectTransform(new Vector2(1f, 0.07f), innerPadded.RectTransform, Anchor.TopLeft), style: null)
|
||||||
|
{
|
||||||
|
Color = Color.Black * 0.65f
|
||||||
|
};
|
||||||
|
var topLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.97f, 5f / 7f), topContainer.RectTransform, Anchor.Center), isHorizontal: true, childAnchor: Anchor.CenterLeft);
|
||||||
|
|
||||||
|
titleText = new GUITextBlock(new RectTransform(new Vector2(0.95f, 1f), topLayout.RectTransform), subInfo.DisplayName, font: GUI.LargeFont);
|
||||||
|
new GUIButton(new RectTransform(new Vector2(0.05f, 1f), topLayout.RectTransform), TextManager.Get("Close"))
|
||||||
|
{
|
||||||
|
OnClicked = (btn, obj) => { Dispose(); return false; }
|
||||||
|
};
|
||||||
|
|
||||||
|
specsContainer = new GUIListBox(new RectTransform(new Vector2(0.4f, 1f), innerPadded.RectTransform, Anchor.TopLeft) { RelativeOffset = new Vector2(0.015f, 0.07f) })
|
||||||
|
{
|
||||||
|
Color = Color.Black * 0.65f,
|
||||||
|
ScrollBarEnabled = false,
|
||||||
|
ScrollBarVisible = false,
|
||||||
|
Spacing = 5
|
||||||
|
};
|
||||||
|
subInfo.CreateSpecsWindow(specsContainer, GUI.Font, includeTitle: false, includesDescription: true);
|
||||||
|
int width = specsContainer.Rect.Width;
|
||||||
|
void recalculateSpecsContainerHeight()
|
||||||
|
{
|
||||||
|
int totalSize = 0;
|
||||||
|
var children = specsContainer.Content.Children.Where(c => c.Visible);
|
||||||
|
foreach (GUIComponent child in children)
|
||||||
|
{
|
||||||
|
totalSize += child.Rect.Height;
|
||||||
|
}
|
||||||
|
totalSize += specsContainer.Content.CountChildren * specsContainer.Spacing;
|
||||||
|
if (specsContainer.PadBottom)
|
||||||
|
{
|
||||||
|
GUIComponent last = specsContainer.Content.Children.LastOrDefault();
|
||||||
|
if (last != null)
|
||||||
|
{
|
||||||
|
totalSize += specsContainer.Rect.Height - last.Rect.Height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
specsContainer.RectTransform.Resize(new Point(width, totalSize), true);
|
||||||
|
specsContainer.RecalculateChildren();
|
||||||
|
}
|
||||||
|
//hell
|
||||||
|
recalculateSpecsContainerHeight();
|
||||||
|
specsContainer.Content.GetAllChildren<GUITextBlock>().ForEach(c =>
|
||||||
|
{
|
||||||
|
var firstChild = c.Children.FirstOrDefault() as GUITextBlock;
|
||||||
|
if (firstChild != null)
|
||||||
|
{
|
||||||
|
firstChild.CalculateHeightFromText(); firstChild.SetTextPos();
|
||||||
|
c.RectTransform.MinSize = new Point(0, firstChild.Rect.Height);
|
||||||
|
}
|
||||||
|
c.CalculateHeightFromText(); c.SetTextPos();
|
||||||
|
});
|
||||||
|
recalculateSpecsContainerHeight();
|
||||||
|
|
||||||
GeneratePreviewMeshes();
|
GeneratePreviewMeshes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
public static void ClientRead(IReadMessage msg)
|
public static void ClientRead(IReadMessage msg)
|
||||||
{
|
{
|
||||||
UInt16 ID = msg.ReadUInt16();
|
UInt16 id = msg.ReadUInt16();
|
||||||
ChatMessageType type = (ChatMessageType)msg.ReadByte();
|
ChatMessageType type = (ChatMessageType)msg.ReadByte();
|
||||||
PlayerConnectionChangeType changeType = PlayerConnectionChangeType.None;
|
PlayerConnectionChangeType changeType = PlayerConnectionChangeType.None;
|
||||||
string txt = "";
|
string txt = "";
|
||||||
@@ -114,7 +114,7 @@ namespace Barotrauma.Networking
|
|||||||
if (orderIndex < 0 || orderIndex >= Order.PrefabList.Count)
|
if (orderIndex < 0 || orderIndex >= Order.PrefabList.Count)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Invalid order message - order index out of bounds.");
|
DebugConsole.ThrowError("Invalid order message - order index out of bounds.");
|
||||||
if (NetIdUtils.IdMoreRecent(ID, LastID)) { LastID = ID; }
|
if (NetIdUtils.IdMoreRecent(id, LastID)) { LastID = id; }
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -155,11 +155,11 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NetIdUtils.IdMoreRecent(ID, LastID))
|
if (NetIdUtils.IdMoreRecent(id, LastID))
|
||||||
{
|
{
|
||||||
GameMain.Client.AddChatMessage(
|
GameMain.Client.AddChatMessage(
|
||||||
new OrderChatMessage(orderPrefab, orderOption, orderPriority, txt, orderTargetPosition ?? targetEntity as ISpatialEntity, targetCharacter, senderCharacter));
|
new OrderChatMessage(orderPrefab, orderOption, orderPriority, txt, orderTargetPosition ?? targetEntity as ISpatialEntity, targetCharacter, senderCharacter));
|
||||||
LastID = ID;
|
LastID = id;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case ChatMessageType.ServerMessageBox:
|
case ChatMessageType.ServerMessageBox:
|
||||||
@@ -171,7 +171,7 @@ namespace Barotrauma.Networking
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NetIdUtils.IdMoreRecent(ID, LastID))
|
if (NetIdUtils.IdMoreRecent(id, LastID))
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
@@ -200,7 +200,7 @@ namespace Barotrauma.Networking
|
|||||||
GameMain.Client.AddChatMessage(txt, type, senderName, senderCharacter, changeType);
|
GameMain.Client.AddChatMessage(txt, type, senderName, senderCharacter, changeType);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
LastID = ID;
|
LastID = id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -159,6 +159,12 @@ namespace Barotrauma.Networking
|
|||||||
get { return entityEventManager; }
|
get { return entityEventManager; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool? WaitForNextRoundRespawn
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
private readonly object serverEndpoint;
|
private readonly object serverEndpoint;
|
||||||
private readonly int ownerKey;
|
private readonly int ownerKey;
|
||||||
private readonly bool steamP2POwner;
|
private readonly bool steamP2POwner;
|
||||||
@@ -185,10 +191,10 @@ namespace Barotrauma.Networking
|
|||||||
CanBeFocused = false
|
CanBeFocused = false
|
||||||
};
|
};
|
||||||
|
|
||||||
cameraFollowsSub = new GUITickBox(new RectTransform(new Vector2(0.05f, 0.05f), inGameHUD.RectTransform, anchor: Anchor.TopCenter)
|
cameraFollowsSub = new GUITickBox(new RectTransform(new Vector2(0.05f, 0.05f), inGameHUD.RectTransform, anchor: Anchor.TopCenter, pivot: Pivot.CenterLeft)
|
||||||
{
|
{
|
||||||
AbsoluteOffset = new Point(0, 5),
|
AbsoluteOffset = new Point(0, HUDLayoutSettings.ButtonAreaTop.Y + HUDLayoutSettings.ButtonAreaTop.Height / 2),
|
||||||
MaxSize = new Point(25, 25)
|
MaxSize = new Point(GUI.IntScale(25))
|
||||||
}, TextManager.Get("CamFollowSubmarine"))
|
}, TextManager.Get("CamFollowSubmarine"))
|
||||||
{
|
{
|
||||||
Selected = Camera.FollowSub,
|
Selected = Camera.FollowSub,
|
||||||
@@ -1424,6 +1430,8 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
EndVoteTickBox.Selected = false;
|
EndVoteTickBox.Selected = false;
|
||||||
|
|
||||||
|
WaitForNextRoundRespawn = null;
|
||||||
|
|
||||||
roundInitStatus = RoundInitStatus.Starting;
|
roundInitStatus = RoundInitStatus.Starting;
|
||||||
|
|
||||||
int seed = inc.ReadInt32();
|
int seed = inc.ReadInt32();
|
||||||
@@ -1690,13 +1698,15 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
foreach (Submarine sub in Submarine.MainSubs[i].DockedTo)
|
foreach (Submarine sub in Submarine.MainSubs[i].DockedTo)
|
||||||
{
|
{
|
||||||
|
if (sub.Info.Type == SubmarineType.Outpost) { continue; }
|
||||||
sub.TeamID = teamID;
|
sub.TeamID = teamID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (respawnAllowed)
|
if (respawnAllowed)
|
||||||
{
|
{
|
||||||
respawnManager = new RespawnManager(this, GameMain.NetLobbyScreen.UsingShuttle && gameMode != GameModePreset.MultiPlayerCampaign ? GameMain.NetLobbyScreen.SelectedShuttle : null);
|
bool isOutpost = GameMain.GameSession?.GameMode is MultiPlayerCampaign campaign && Level.Loaded?.Type == LevelData.LevelType.Outpost;
|
||||||
|
respawnManager = new RespawnManager(this, GameMain.NetLobbyScreen.UsingShuttle && !isOutpost ? GameMain.NetLobbyScreen.SelectedShuttle : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
gameStarted = true;
|
gameStarted = true;
|
||||||
@@ -1739,6 +1749,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
gameStarted = false;
|
gameStarted = false;
|
||||||
Character.Controlled = null;
|
Character.Controlled = null;
|
||||||
|
WaitForNextRoundRespawn = null;
|
||||||
SpawnAsTraitor = false;
|
SpawnAsTraitor = false;
|
||||||
GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
|
GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
|
||||||
GameMain.LightManager.LosEnabled = false;
|
GameMain.LightManager.LosEnabled = false;
|
||||||
@@ -1965,14 +1976,19 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
foreach (Client client in ConnectedClients)
|
foreach (Client client in ConnectedClients)
|
||||||
{
|
{
|
||||||
if (!previouslyConnectedClients.Any(c => c.ID == client.ID))
|
int index = previouslyConnectedClients.FindIndex(c => c.ID == client.ID);
|
||||||
|
if (index < 0)
|
||||||
{
|
{
|
||||||
while (previouslyConnectedClients.Count > 100)
|
if (previouslyConnectedClients.Count > 100)
|
||||||
{
|
{
|
||||||
previouslyConnectedClients.RemoveAt(0);
|
previouslyConnectedClients.RemoveRange(0, previouslyConnectedClients.Count - 100);
|
||||||
}
|
}
|
||||||
previouslyConnectedClients.Add(client);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
previouslyConnectedClients.RemoveAt(index);
|
||||||
|
}
|
||||||
|
previouslyConnectedClients.Add(client);
|
||||||
}
|
}
|
||||||
if (updateClientListId) { LastClientListUpdateID = listId; }
|
if (updateClientListId) { LastClientListUpdateID = listId; }
|
||||||
|
|
||||||
@@ -2452,6 +2468,15 @@ namespace Barotrauma.Networking
|
|||||||
chatMsgQueue.Add(chatMessage);
|
chatMsgQueue.Add(chatMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SendRespawnPromptResponse(bool waitForNextRoundRespawn)
|
||||||
|
{
|
||||||
|
WaitForNextRoundRespawn = waitForNextRoundRespawn;
|
||||||
|
IWriteMessage msg = new WriteOnlyMessage();
|
||||||
|
msg.Write((byte)ClientPacketHeader.READY_TO_SPAWN);
|
||||||
|
msg.Write((bool)waitForNextRoundRespawn);
|
||||||
|
clientPeer?.Send(msg, DeliveryMethod.Reliable);
|
||||||
|
}
|
||||||
|
|
||||||
public void RequestFile(FileTransferType fileType, string file, string fileHash)
|
public void RequestFile(FileTransferType fileType, string file, string fileHash)
|
||||||
{
|
{
|
||||||
IWriteMessage msg = new WriteOnlyMessage();
|
IWriteMessage msg = new WriteOnlyMessage();
|
||||||
@@ -3143,11 +3168,11 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
cameraFollowsSub.Visible = Character.Controlled == null;
|
cameraFollowsSub.Visible = Character.Controlled == null;
|
||||||
}
|
}
|
||||||
if (Character.Controlled == null || Character.Controlled.IsDead)
|
/*if (Character.Controlled == null || Character.Controlled.IsDead)
|
||||||
{
|
{
|
||||||
GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
|
GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
|
||||||
GameMain.LightManager.LosEnabled = false;
|
GameMain.LightManager.LosEnabled = false;
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
//tab doesn't autoselect the chatbox when debug console is open,
|
//tab doesn't autoselect the chatbox when debug console is open,
|
||||||
@@ -3255,9 +3280,10 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
if (respawnManager != null)
|
if (respawnManager != null)
|
||||||
{
|
{
|
||||||
string respawnText = "";
|
string respawnText = string.Empty;
|
||||||
float textScale = 1.0f;
|
float textScale = 1.0f;
|
||||||
Color textColor = Color.White;
|
Color textColor = Color.White;
|
||||||
|
bool canChooseRespawn = GameMain.GameSession.GameMode is CampaignMode && Character.Controlled == null && Level.Loaded?.Type != LevelData.LevelType.Outpost;
|
||||||
if (respawnManager.CurrentState == RespawnManager.State.Waiting &&
|
if (respawnManager.CurrentState == RespawnManager.State.Waiting &&
|
||||||
respawnManager.RespawnCountdownStarted)
|
respawnManager.RespawnCountdownStarted)
|
||||||
{
|
{
|
||||||
@@ -3275,18 +3301,18 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
//oscillate between 0-1
|
//oscillate between 0-1
|
||||||
float phase = (float)(Math.Sin(timeLeft * MathHelper.Pi) + 1.0f) * 0.5f;
|
float phase = (float)(Math.Sin(timeLeft * MathHelper.Pi) + 1.0f) * 0.5f;
|
||||||
textScale = 1.0f + phase * 0.5f;
|
//textScale = 1.0f + phase * 0.5f;
|
||||||
textColor = Color.Lerp(GUI.Style.Red, Color.White, 1.0f - phase);
|
textColor = Color.Lerp(GUI.Style.Red, Color.White, 1.0f - phase);
|
||||||
}
|
}
|
||||||
|
canChooseRespawn = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(respawnText))
|
GameMain.GameSession?.SetRespawnInfo(
|
||||||
{
|
visible: !string.IsNullOrEmpty(respawnText) || canChooseRespawn, text: respawnText, textColor: textColor,
|
||||||
GUI.SmallFont.DrawString(spriteBatch, respawnText, new Vector2(120.0f, 10), textColor, 0.0f, Vector2.Zero, textScale, Microsoft.Xna.Framework.Graphics.SpriteEffects.None, 0.0f);
|
buttonsVisible: canChooseRespawn, waitForNextRoundRespawn: (WaitForNextRoundRespawn ?? true));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ShowNetStats) return;
|
if (!ShowNetStats) { return; }
|
||||||
|
|
||||||
NetStats.Draw(spriteBatch, new Rectangle(300, 10, 300, 150));
|
NetStats.Draw(spriteBatch, new Rectangle(300, 10, 300, 150));
|
||||||
|
|
||||||
|
|||||||
@@ -473,7 +473,36 @@ namespace Barotrauma
|
|||||||
SelectedColor = MapGenerationParams.Instance.IndicatorColor,
|
SelectedColor = MapGenerationParams.Instance.IndicatorColor,
|
||||||
HoverColor = Color.Lerp(MapGenerationParams.Instance.IndicatorColor, Color.White, 0.5f)
|
HoverColor = Color.Lerp(MapGenerationParams.Instance.IndicatorColor, Color.White, 0.5f)
|
||||||
};
|
};
|
||||||
missionName.Padding = new Vector4(missionName.Padding.X + icon.Rect.Width * 1.5f, missionName.Padding.Y, missionName.Padding.Z, missionName.Padding.W);
|
icon.RectTransform.IsFixedSize = true;
|
||||||
|
|
||||||
|
GUILayoutGroup difficultyIndicatorGroup = null;
|
||||||
|
if (mission.Difficulty.HasValue)
|
||||||
|
{
|
||||||
|
difficultyIndicatorGroup = new GUILayoutGroup(new RectTransform(Vector2.One * 0.9f, missionName.RectTransform, anchor: Anchor.CenterRight, scaleBasis: ScaleBasis.Smallest) { AbsoluteOffset = new Point((int)missionName.Padding.Z, 0) },
|
||||||
|
isHorizontal: true, childAnchor: Anchor.CenterRight)
|
||||||
|
{
|
||||||
|
AbsoluteSpacing = 1,
|
||||||
|
UserData = "difficulty"
|
||||||
|
};
|
||||||
|
var difficultyColor = mission.GetDifficultyColor();
|
||||||
|
for (int i = 0; i < mission.Difficulty; i++)
|
||||||
|
{
|
||||||
|
new GUIImage(new RectTransform(Vector2.One, difficultyIndicatorGroup.RectTransform, scaleBasis: ScaleBasis.Smallest) { IsFixedSize = true }, "DifficultyIndicator", scaleToFit: true)
|
||||||
|
{
|
||||||
|
Color = difficultyColor * 0.5f,
|
||||||
|
SelectedColor = difficultyColor,
|
||||||
|
HoverColor = Color.Lerp(difficultyColor, Color.White, 0.5f)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float extraPadding = 0.5f * icon.Rect.Width;
|
||||||
|
float extraZPadding = difficultyIndicatorGroup != null ? mission.Difficulty.Value * (difficultyIndicatorGroup.Children.First().Rect.Width + difficultyIndicatorGroup.AbsoluteSpacing) : 0;
|
||||||
|
missionName.Padding = new Vector4(missionName.Padding.X + icon.Rect.Width + extraPadding,
|
||||||
|
missionName.Padding.Y,
|
||||||
|
missionName.Padding.Z + extraZPadding + extraPadding,
|
||||||
|
missionName.Padding.W);
|
||||||
|
missionName.CalculateHeightFromText();
|
||||||
}
|
}
|
||||||
|
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform), mission.GetMissionRewardText(), wrap: true, parseRichText: true);
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform), mission.GetMissionRewardText(), wrap: true, parseRichText: true);
|
||||||
@@ -494,6 +523,10 @@ namespace Barotrauma
|
|||||||
missionPanel.OnAddedToGUIUpdateList = (c) =>
|
missionPanel.OnAddedToGUIUpdateList = (c) =>
|
||||||
{
|
{
|
||||||
missionTextContent.Children.ForEach(child => child.State = c.State);
|
missionTextContent.Children.ForEach(child => child.State = c.State);
|
||||||
|
if (missionTextContent.FindChild("difficulty", recursive: true) is GUILayoutGroup group)
|
||||||
|
{
|
||||||
|
group.State = c.State;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (mission != availableMissions.Last())
|
if (mission != availableMissions.Last())
|
||||||
|
|||||||
@@ -171,10 +171,7 @@ namespace Barotrauma
|
|||||||
Character.Controlled.ObstructVision &&
|
Character.Controlled.ObstructVision &&
|
||||||
(Character.Controlled.ViewTarget == Character.Controlled || Character.Controlled.ViewTarget == null);
|
(Character.Controlled.ViewTarget == Character.Controlled || Character.Controlled.ViewTarget == null);
|
||||||
|
|
||||||
if (Character.Controlled != null)
|
GameMain.LightManager.UpdateObstructVision(graphics, spriteBatch, cam, Character.Controlled?.CursorWorldPosition ?? Vector2.Zero);
|
||||||
{
|
|
||||||
GameMain.LightManager.UpdateObstructVision(graphics, spriteBatch, cam, Character.Controlled.CursorWorldPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
graphics.SetRenderTarget(renderTarget);
|
graphics.SetRenderTarget(renderTarget);
|
||||||
@@ -334,12 +331,13 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
spriteBatch.End();
|
spriteBatch.End();
|
||||||
|
|
||||||
if (GameMain.LightManager.LosEnabled && GameMain.LightManager.LosMode != LosMode.None && Character.Controlled != null)
|
if (GameMain.LightManager.LosEnabled && GameMain.LightManager.LosMode != LosMode.None && Lights.LightManager.ViewTarget != null)
|
||||||
{
|
{
|
||||||
GameMain.LightManager.LosEffect.CurrentTechnique = GameMain.LightManager.LosEffect.Techniques["LosShader"];
|
GameMain.LightManager.LosEffect.CurrentTechnique = GameMain.LightManager.LosEffect.Techniques["LosShader"];
|
||||||
|
|
||||||
GameMain.LightManager.LosEffect.Parameters["xTexture"].SetValue(renderTargetBackground);
|
GameMain.LightManager.LosEffect.Parameters["xTexture"].SetValue(renderTargetBackground);
|
||||||
GameMain.LightManager.LosEffect.Parameters["xLosTexture"].SetValue(GameMain.LightManager.LosTexture);
|
GameMain.LightManager.LosEffect.Parameters["xLosTexture"].SetValue(GameMain.LightManager.LosTexture);
|
||||||
|
GameMain.LightManager.LosEffect.Parameters["xLosAlpha"].SetValue(GameMain.LightManager.LosAlpha);
|
||||||
|
|
||||||
Color losColor;
|
Color losColor;
|
||||||
if (GameMain.LightManager.LosMode == LosMode.Transparent)
|
if (GameMain.LightManager.LosMode == LosMode.Transparent)
|
||||||
|
|||||||
@@ -348,6 +348,16 @@ namespace Barotrauma
|
|||||||
CanBeFocused = false
|
CanBeFocused = false
|
||||||
};
|
};
|
||||||
|
|
||||||
|
new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), optionList.RectTransform), TextManager.Get("EditorDisclaimerWikiLink"), textAlignment: Alignment.Left, style: "MainMenuGUIButton")
|
||||||
|
{
|
||||||
|
ForceUpperCase = true,
|
||||||
|
OnClicked = (button, userData) =>
|
||||||
|
{
|
||||||
|
string url = TextManager.Get("EditorDisclaimerWikiUrl", returnNull: true) ?? "https://barotraumagame.com/wiki";
|
||||||
|
GameMain.Instance.ShowOpenUrlInWebBrowserPrompt(url, promptExtensionTag: "wikinotice");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), optionList.RectTransform), TextManager.Get("CreditsButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton")
|
new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), optionList.RectTransform), TextManager.Get("CreditsButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton")
|
||||||
{
|
{
|
||||||
ForceUpperCase = true,
|
ForceUpperCase = true,
|
||||||
|
|||||||
@@ -1305,9 +1305,9 @@ namespace Barotrauma
|
|||||||
StartButton.Visible = GameMain.Client.HasPermission(ClientPermissions.ManageRound) && !GameMain.Client.GameStarted && !CampaignSetupFrame.Visible && !CampaignFrame.Visible;
|
StartButton.Visible = GameMain.Client.HasPermission(ClientPermissions.ManageRound) && !GameMain.Client.GameStarted && !CampaignSetupFrame.Visible && !CampaignFrame.Visible;
|
||||||
ServerName.Readonly = !GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
ServerName.Readonly = !GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
||||||
ServerMessage.Readonly = !GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
ServerMessage.Readonly = !GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
||||||
shuttleTickBox.Enabled = !CampaignFrame.Visible && !CampaignSetupFrame.Visible && GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
shuttleTickBox.Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
||||||
SubList.Enabled = !CampaignFrame.Visible && (GameMain.Client.ServerSettings.Voting.AllowSubVoting || GameMain.Client.HasPermission(ClientPermissions.SelectSub));
|
SubList.Enabled = !CampaignFrame.Visible && (GameMain.Client.ServerSettings.Voting.AllowSubVoting || GameMain.Client.HasPermission(ClientPermissions.SelectSub));
|
||||||
shuttleList.Enabled = shuttleList.ButtonEnabled = shuttleTickBox.Enabled = !CampaignFrame.Visible && !CampaignSetupFrame.Visible && GameMain.Client.HasPermission(ClientPermissions.SelectSub);
|
shuttleList.Enabled = shuttleList.ButtonEnabled = GameMain.Client.HasPermission(ClientPermissions.SelectSub);
|
||||||
ModeList.Enabled = GameMain.Client.ServerSettings.Voting.AllowModeVoting || GameMain.Client.HasPermission(ClientPermissions.SelectMode);
|
ModeList.Enabled = GameMain.Client.ServerSettings.Voting.AllowModeVoting || GameMain.Client.HasPermission(ClientPermissions.SelectMode);
|
||||||
LogButtons.Visible = GameMain.Client.HasPermission(ClientPermissions.ServerLog);
|
LogButtons.Visible = GameMain.Client.HasPermission(ClientPermissions.ServerLog);
|
||||||
GameMain.Client.ShowLogButton.Visible = GameMain.Client.HasPermission(ClientPermissions.ServerLog);
|
GameMain.Client.ShowLogButton.Visible = GameMain.Client.HasPermission(ClientPermissions.ServerLog);
|
||||||
|
|||||||
@@ -533,20 +533,6 @@ namespace Barotrauma
|
|||||||
OnSelected = (GUITickBox obj) =>
|
OnSelected = (GUITickBox obj) =>
|
||||||
{
|
{
|
||||||
lightingEnabled = obj.Selected;
|
lightingEnabled = obj.Selected;
|
||||||
if (lightingEnabled)
|
|
||||||
{
|
|
||||||
//turn off lights that are inside containers
|
|
||||||
foreach (Item item in Item.ItemList)
|
|
||||||
{
|
|
||||||
foreach (LightComponent lightComponent in item.GetComponents<LightComponent>())
|
|
||||||
{
|
|
||||||
lightComponent.Light.Color = item.Container != null || (item.body != null && !item.body.Enabled) ?
|
|
||||||
Color.Transparent :
|
|
||||||
lightComponent.LightColor;
|
|
||||||
lightComponent.Light.LightSpriteEffect = lightComponent.Item.SpriteEffects;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -2704,16 +2690,6 @@ namespace Barotrauma
|
|||||||
cam.Position = Submarine.MainSub.Position + Submarine.MainSub.HiddenSubPosition;
|
cam.Position = Submarine.MainSub.Position + Submarine.MainSub.HiddenSubPosition;
|
||||||
|
|
||||||
loadFrame = null;
|
loadFrame = null;
|
||||||
|
|
||||||
//turn off lights that are inside an inventory (cabinet for example)
|
|
||||||
foreach (Item item in Item.ItemList)
|
|
||||||
{
|
|
||||||
var lightComponent = item.GetComponent<LightComponent>();
|
|
||||||
if (lightComponent != null)
|
|
||||||
{
|
|
||||||
lightComponent.Light.Enabled = item.ParentInventory == null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool LoadSub(GUIButton button, object obj)
|
private bool LoadSub(GUIButton button, object obj)
|
||||||
@@ -2748,16 +2724,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
loadFrame = null;
|
loadFrame = null;
|
||||||
|
|
||||||
//turn off lights that are inside an inventory (cabinet for example)
|
|
||||||
foreach (Item item in Item.ItemList)
|
|
||||||
{
|
|
||||||
var lightComponent = item.GetComponent<LightComponent>();
|
|
||||||
if (lightComponent != null)
|
|
||||||
{
|
|
||||||
lightComponent.Light.Enabled = item.ParentInventory == null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selectedSub.Info.GameVersion < new Version("0.8.9.0"))
|
if (selectedSub.Info.GameVersion < new Version("0.8.9.0"))
|
||||||
{
|
{
|
||||||
var adjustLightsPrompt = new GUIMessageBox(TextManager.Get("Warning"), TextManager.Get("AdjustLightsPrompt"),
|
var adjustLightsPrompt = new GUIMessageBox(TextManager.Get("Warning"), TextManager.Get("AdjustLightsPrompt"),
|
||||||
@@ -2857,8 +2823,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
categorizedEntityList.UpdateScrollBarSize();
|
categorizedEntityList.UpdateScrollBarSize();
|
||||||
categorizedEntityList.BarScroll = 0.0f;
|
categorizedEntityList.BarScroll = 0.0f;
|
||||||
categorizedEntityList.Visible = true;
|
// categorizedEntityList.Visible = true;
|
||||||
allEntityList.Visible = false;
|
// allEntityList.Visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FilterEntities(string filter)
|
private void FilterEntities(string filter)
|
||||||
@@ -3047,6 +3013,37 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public static GUIMessageBox CreatePropertyColorPicker(Color originalColor, SerializableProperty property, ISerializableEntity entity)
|
public static GUIMessageBox CreatePropertyColorPicker(Color originalColor, SerializableProperty property, ISerializableEntity entity)
|
||||||
{
|
{
|
||||||
|
var entities = new List<(ISerializableEntity Entity, Color OriginalColor, SerializableProperty Property)> { (entity, originalColor, property) };
|
||||||
|
|
||||||
|
foreach (ISerializableEntity selectedEntity in MapEntity.SelectedList.Where(selectedEntity => selectedEntity is ISerializableEntity && entity != selectedEntity).Cast<ISerializableEntity>())
|
||||||
|
{
|
||||||
|
switch (entity)
|
||||||
|
{
|
||||||
|
case ItemComponent _ when selectedEntity is Item item:
|
||||||
|
foreach (var component in item.Components)
|
||||||
|
{
|
||||||
|
if (component.GetType() == entity.GetType() && component != entity)
|
||||||
|
{
|
||||||
|
entities.Add((component, (Color) property.GetValue(component), property));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (selectedEntity.GetType() == entity.GetType())
|
||||||
|
{
|
||||||
|
entities.Add((selectedEntity, (Color) property.GetValue(selectedEntity), property));
|
||||||
|
}
|
||||||
|
else if (selectedEntity is { SerializableProperties: { } props} )
|
||||||
|
{
|
||||||
|
if (props.TryGetValue(property.NameToLowerInvariant, out SerializableProperty foundProp))
|
||||||
|
{
|
||||||
|
entities.Add((selectedEntity, (Color) foundProp.GetValue(selectedEntity), foundProp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool setValues = true;
|
bool setValues = true;
|
||||||
object sliderMutex = new object(),
|
object sliderMutex = new object(),
|
||||||
sliderTextMutex = new object(),
|
sliderTextMutex = new object(),
|
||||||
@@ -3142,9 +3139,22 @@ namespace Barotrauma
|
|||||||
colorPicker.DisposeTextures();
|
colorPicker.DisposeTextures();
|
||||||
msgBox.Close();
|
msgBox.Close();
|
||||||
|
|
||||||
if (entity is MapEntity { Removed: true } me) { return true; }
|
|
||||||
Color newColor = SetColor(null);
|
Color newColor = SetColor(null);
|
||||||
StoreCommand(new PropertyCommand(entity, property.Name, newColor, originalColor));
|
|
||||||
|
Dictionary<object, List<ISerializableEntity>> oldProperties = new Dictionary<object, List<ISerializableEntity>>();
|
||||||
|
|
||||||
|
foreach (var (sEntity, color, _) in entities)
|
||||||
|
{
|
||||||
|
if (sEntity is MapEntity { Removed: true }) { continue; }
|
||||||
|
if (!oldProperties.ContainsKey(color))
|
||||||
|
{
|
||||||
|
oldProperties.Add(color, new List<ISerializableEntity>());
|
||||||
|
}
|
||||||
|
oldProperties[color].Add(sEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ISerializableEntity> affected = entities.Select(t => t.Entity).Where(se => se is MapEntity { Removed: false }).ToList();
|
||||||
|
StoreCommand(new PropertyCommand(affected, property.Name, newColor, oldProperties));
|
||||||
|
|
||||||
if (MapEntity.EditingHUD != null && (MapEntity.EditingHUD.UserData == entity || (!(entity is ItemComponent ic) || MapEntity.EditingHUD.UserData == ic.Item)))
|
if (MapEntity.EditingHUD != null && (MapEntity.EditingHUD.UserData == entity || (!(entity is ItemComponent ic) || MapEntity.EditingHUD.UserData == ic.Item)))
|
||||||
{
|
{
|
||||||
@@ -3170,8 +3180,12 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
colorPicker.DisposeTextures();
|
colorPicker.DisposeTextures();
|
||||||
msgBox.Close();
|
msgBox.Close();
|
||||||
if (entity is MapEntity { Removed: true } me) { return true; }
|
|
||||||
property.SetValue(entity, originalColor);
|
foreach (var (e, color, prop) in entities)
|
||||||
|
{
|
||||||
|
if (e is MapEntity { Removed: true }) { continue; }
|
||||||
|
prop.TrySetValue(e, color);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -3218,8 +3232,12 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
Color color = ToolBox.HSVToRGB(colorPicker.SelectedHue, colorPicker.SelectedSaturation, colorPicker.SelectedValue);
|
Color color = ToolBox.HSVToRGB(colorPicker.SelectedHue, colorPicker.SelectedSaturation, colorPicker.SelectedValue);
|
||||||
color.A = originalColor.A;
|
foreach (var (e, origColor, prop) in entities)
|
||||||
property.TrySetValue(entity, color);
|
{
|
||||||
|
if (e is MapEntity { Removed: true }) { continue; }
|
||||||
|
color.A = origColor.A;
|
||||||
|
prop.TrySetValue(e, color);
|
||||||
|
}
|
||||||
return color;
|
return color;
|
||||||
|
|
||||||
void SetSliders(Vector3 hsv)
|
void SetSliders(Vector3 hsv)
|
||||||
@@ -3238,9 +3256,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
void SetColorPicker(Vector3 hsv)
|
void SetColorPicker(Vector3 hsv)
|
||||||
{
|
{
|
||||||
|
bool hueChanged = !MathUtils.NearlyEqual(colorPicker.SelectedHue, hsv.X);
|
||||||
colorPicker.SelectedHue = hsv.X;
|
colorPicker.SelectedHue = hsv.X;
|
||||||
colorPicker.SelectedSaturation = hsv.Y;
|
colorPicker.SelectedSaturation = hsv.Y;
|
||||||
colorPicker.SelectedValue = hsv.Z;
|
colorPicker.SelectedValue = hsv.Z;
|
||||||
|
if (hueChanged) { colorPicker.RefreshHue(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetHex(Vector3 hsv)
|
void SetHex(Vector3 hsv)
|
||||||
@@ -3496,6 +3516,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private bool SelectPrefab(GUIComponent component, object obj)
|
private bool SelectPrefab(GUIComponent component, object obj)
|
||||||
{
|
{
|
||||||
|
allEntityList.Deselect();
|
||||||
|
categorizedEntityList.Deselect();
|
||||||
if (GUI.MouseOn is GUIButton || GUI.MouseOn?.Parent is GUIButton) { return false; }
|
if (GUI.MouseOn is GUIButton || GUI.MouseOn?.Parent is GUIButton) { return false; }
|
||||||
|
|
||||||
AddPreviouslyUsed(obj as MapEntityPrefab);
|
AddPreviouslyUsed(obj as MapEntityPrefab);
|
||||||
@@ -4332,6 +4354,17 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (lightingEnabled)
|
if (lightingEnabled)
|
||||||
{
|
{
|
||||||
|
//turn off lights that are inside containers
|
||||||
|
foreach (Item item in Item.ItemList)
|
||||||
|
{
|
||||||
|
foreach (LightComponent lightComponent in item.GetComponents<LightComponent>())
|
||||||
|
{
|
||||||
|
lightComponent.Light.Color = item.Container != null || (item.body != null && !item.body.Enabled) ?
|
||||||
|
Color.Transparent :
|
||||||
|
lightComponent.LightColor;
|
||||||
|
lightComponent.Light.LightSpriteEffect = lightComponent.Item.SpriteEffects;
|
||||||
|
}
|
||||||
|
}
|
||||||
GameMain.LightManager?.Update((float)deltaTime);
|
GameMain.LightManager?.Update((float)deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1208,7 +1208,7 @@ namespace Barotrauma
|
|||||||
SafeAdd((ISerializableEntity) entity, property);
|
SafeAdd((ISerializableEntity) entity, property);
|
||||||
property.PropertyInfo.SetValue(entity, value);
|
property.PropertyInfo.SetValue(entity, value);
|
||||||
}
|
}
|
||||||
else if (entity is ISerializableEntity sEntity && sEntity.SerializableProperties != null)
|
else if (entity is ISerializableEntity { SerializableProperties: { } } sEntity)
|
||||||
{
|
{
|
||||||
var props = sEntity.SerializableProperties;
|
var props = sEntity.SerializableProperties;
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ namespace Barotrauma.Sounds
|
|||||||
public override int FillStreamBuffer(int samplePos, short[] buffer)
|
public override int FillStreamBuffer(int samplePos, short[] buffer)
|
||||||
{
|
{
|
||||||
if (!Stream) throw new Exception("Called FillStreamBuffer on a non-streamed sound!");
|
if (!Stream) throw new Exception("Called FillStreamBuffer on a non-streamed sound!");
|
||||||
|
if (reader == null) throw new Exception("Called FillStreamBuffer when the reader is null!");
|
||||||
|
|
||||||
if (samplePos >= reader.TotalSamples * reader.Channels * 2) return 0;
|
if (samplePos >= reader.TotalSamples * reader.Channels * 2) return 0;
|
||||||
|
|
||||||
@@ -73,6 +74,8 @@ namespace Barotrauma.Sounds
|
|||||||
{
|
{
|
||||||
if (!Stream)
|
if (!Stream)
|
||||||
{
|
{
|
||||||
|
reader ??= new VorbisReader(Filename);
|
||||||
|
|
||||||
reader.DecodedPosition = 0;
|
reader.DecodedPosition = 0;
|
||||||
|
|
||||||
int bufferSize = (int)reader.TotalSamples * reader.Channels;
|
int bufferSize = (int)reader.TotalSamples * reader.Channels;
|
||||||
@@ -126,7 +129,7 @@ namespace Barotrauma.Sounds
|
|||||||
{
|
{
|
||||||
if (Stream)
|
if (Stream)
|
||||||
{
|
{
|
||||||
reader.Dispose();
|
reader?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
base.Dispose();
|
base.Dispose();
|
||||||
|
|||||||
@@ -14,35 +14,15 @@ namespace Barotrauma.Sounds
|
|||||||
get { return disposed; }
|
get { return disposed; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public SoundManager Owner
|
public readonly SoundManager Owner;
|
||||||
{
|
|
||||||
get;
|
|
||||||
protected set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Filename
|
public readonly string Filename;
|
||||||
{
|
|
||||||
get;
|
|
||||||
protected set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public XElement XElement
|
public readonly XElement XElement;
|
||||||
{
|
|
||||||
get;
|
|
||||||
protected set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Stream
|
public readonly bool Stream;
|
||||||
{
|
|
||||||
get;
|
|
||||||
protected set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool StreamsReliably
|
public readonly bool StreamsReliably;
|
||||||
{
|
|
||||||
get;
|
|
||||||
protected set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual SoundManager.SourcePoolIndex SourcePoolIndex
|
public virtual SoundManager.SourcePoolIndex SourcePoolIndex
|
||||||
{
|
{
|
||||||
@@ -79,10 +59,10 @@ namespace Barotrauma.Sounds
|
|||||||
public float BaseNear;
|
public float BaseNear;
|
||||||
public float BaseFar;
|
public float BaseFar;
|
||||||
|
|
||||||
public Sound(SoundManager owner, string filename, bool stream, bool streamsReliably, XElement xElement=null)
|
public Sound(SoundManager owner, string filename, bool stream, bool streamsReliably, XElement xElement=null, bool getFullPath=true)
|
||||||
{
|
{
|
||||||
Owner = owner;
|
Owner = owner;
|
||||||
Filename = Path.GetFullPath(filename.CleanUpPath()).CleanUpPath();
|
Filename = getFullPath ? Path.GetFullPath(filename.CleanUpPath()).CleanUpPath() : filename;
|
||||||
Stream = stream;
|
Stream = stream;
|
||||||
StreamsReliably = streamsReliably;
|
StreamsReliably = streamsReliably;
|
||||||
XElement = xElement;
|
XElement = xElement;
|
||||||
|
|||||||
@@ -21,12 +21,14 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public readonly string requiredTag;
|
public readonly string requiredTag;
|
||||||
|
|
||||||
public DamageSound(Sound sound, Vector2 damageRange, string damageType, string requiredTag = "")
|
public bool ignoreMuffling;
|
||||||
|
|
||||||
|
public DamageSound(Sound sound, Vector2 damageRange, string damageType, bool ignoreMuffling, string requiredTag = "")
|
||||||
{
|
{
|
||||||
this.sound = sound;
|
this.sound = sound;
|
||||||
this.damageRange = damageRange;
|
this.damageRange = damageRange;
|
||||||
this.damageType = damageType;
|
this.damageType = damageType;
|
||||||
|
this.ignoreMuffling = ignoreMuffling;
|
||||||
this.requiredTag = requiredTag;
|
this.requiredTag = requiredTag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -269,6 +271,7 @@ namespace Barotrauma
|
|||||||
damageSound,
|
damageSound,
|
||||||
soundElement.GetAttributeVector2("damagerange", Vector2.Zero),
|
soundElement.GetAttributeVector2("damagerange", Vector2.Zero),
|
||||||
damageSoundType,
|
damageSoundType,
|
||||||
|
soundElement.GetAttributeBool("ignoremuffling", false),
|
||||||
soundElement.GetAttributeString("requiredtag", "")));
|
soundElement.GetAttributeString("requiredtag", "")));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -531,7 +534,7 @@ namespace Barotrauma
|
|||||||
Vector2 diff = gap.WorldPosition - listenerPos;
|
Vector2 diff = gap.WorldPosition - listenerPos;
|
||||||
if (Math.Abs(diff.X) < FlowSoundRange && Math.Abs(diff.Y) < FlowSoundRange)
|
if (Math.Abs(diff.X) < FlowSoundRange && Math.Abs(diff.Y) < FlowSoundRange)
|
||||||
{
|
{
|
||||||
if (gap.Open < 0.01f) { continue; }
|
if (gap.Open < 0.01f || gap.LerpedFlowForce.LengthSquared() < 100.0f) { continue; }
|
||||||
float gapFlow = Math.Abs(gap.LerpedFlowForce.X) + Math.Abs(gap.LerpedFlowForce.Y) * 2.5f;
|
float gapFlow = Math.Abs(gap.LerpedFlowForce.X) + Math.Abs(gap.LerpedFlowForce.Y) * 2.5f;
|
||||||
if (!gap.IsRoomToRoom) { gapFlow *= 2.0f; }
|
if (!gap.IsRoomToRoom) { gapFlow *= 2.0f; }
|
||||||
if (gapFlow < 10.0f) { continue; }
|
if (gapFlow < 10.0f) { continue; }
|
||||||
@@ -1123,7 +1126,11 @@ namespace Barotrauma
|
|||||||
tempList.Add(s);
|
tempList.Add(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tempList.GetRandom().sound?.Play(1.0f, range, position, muffle: ShouldMuffleSound(Character.Controlled, position, range, null));
|
var damageSound = tempList.GetRandom();
|
||||||
|
if (damageSound.sound != null)
|
||||||
|
{
|
||||||
|
damageSound.sound.Play(1.0f, range, position, muffle: !damageSound.ignoreMuffling && ShouldMuffleSound(Character.Controlled, position, range, null));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void PlayUISound(GUISoundType soundType)
|
public static void PlayUISound(GUISoundType soundType)
|
||||||
|
|||||||
@@ -63,10 +63,8 @@ namespace Barotrauma.Sounds
|
|||||||
get { return soundChannel?.CurrentAmplitude ?? 0.0f; }
|
get { return soundChannel?.CurrentAmplitude ?? 0.0f; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public VoipSound(string name, SoundManager owner, VoipQueue q) : base(owner, "voip", true, true)
|
public VoipSound(string name, SoundManager owner, VoipQueue q) : base(owner, $"VoIP ({name})", true, true, getFullPath: false)
|
||||||
{
|
{
|
||||||
Filename = $"VoIP ({name})";
|
|
||||||
|
|
||||||
VoipConfig.SetupEncoding();
|
VoipConfig.SetupEncoding();
|
||||||
|
|
||||||
ALFormat = Al.FormatMono16;
|
ALFormat = Al.FormatMono16;
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -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.1300.0.2</Version>
|
<Version>0.1300.0.3</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.1300.0.2</Version>
|
<Version>0.1300.0.3</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>
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ sampler TextureSampler : register (s0) = sampler_state { Texture = <xTexture>; }
|
|||||||
Texture2D xLosTexture;
|
Texture2D xLosTexture;
|
||||||
sampler LosSampler = sampler_state { Texture = <xLosTexture>; };
|
sampler LosSampler = sampler_state { Texture = <xLosTexture>; };
|
||||||
|
|
||||||
|
float xLosAlpha;
|
||||||
|
|
||||||
float4 xColor;
|
float4 xColor;
|
||||||
|
|
||||||
float4 mainPS(VertexShaderOutput input) : COLOR0
|
float4 mainPS(VertexShaderOutput input) : COLOR0
|
||||||
@@ -39,7 +41,7 @@ float4 mainPS(VertexShaderOutput input) : COLOR0
|
|||||||
sampleColor.r * xColor.r,
|
sampleColor.r * xColor.r,
|
||||||
sampleColor.g * xColor.g,
|
sampleColor.g * xColor.g,
|
||||||
sampleColor.b * xColor.b,
|
sampleColor.b * xColor.b,
|
||||||
obscureAmount);
|
obscureAmount * xLosAlpha);
|
||||||
|
|
||||||
return outColor;
|
return outColor;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ sampler TextureSampler : register (s0) = sampler_state { Texture = <xTexture>; }
|
|||||||
Texture xLosTexture;
|
Texture xLosTexture;
|
||||||
sampler LosSampler = sampler_state { Texture = <xLosTexture>; };
|
sampler LosSampler = sampler_state { Texture = <xLosTexture>; };
|
||||||
|
|
||||||
|
float xLosAlpha;
|
||||||
|
|
||||||
float4 xColor;
|
float4 xColor;
|
||||||
|
|
||||||
float4 mainPS(VertexShaderOutput input) : COLOR0
|
float4 mainPS(VertexShaderOutput input) : COLOR0
|
||||||
@@ -39,7 +41,7 @@ float4 mainPS(VertexShaderOutput input) : COLOR0
|
|||||||
sampleColor.r * xColor.r,
|
sampleColor.r * xColor.r,
|
||||||
sampleColor.g * xColor.g,
|
sampleColor.g * xColor.g,
|
||||||
sampleColor.b * xColor.b,
|
sampleColor.b * xColor.b,
|
||||||
obscureAmount);
|
obscureAmount * xLosAlpha);
|
||||||
|
|
||||||
return outColor;
|
return outColor;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.1300.0.2</Version>
|
<Version>0.1300.0.3</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.1300.0.2</Version>
|
<Version>0.1300.0.3</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.1300.0.2</Version>
|
<Version>0.1300.0.3</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>
|
||||||
|
|||||||
@@ -25,12 +25,15 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void ShowOnDisplay(string input)
|
partial void ShowOnDisplay(string input, bool addToHistory = true)
|
||||||
{
|
{
|
||||||
messageHistory.Add(input);
|
if (addToHistory)
|
||||||
while (messageHistory.Count > MaxMessages)
|
|
||||||
{
|
{
|
||||||
messageHistory.RemoveAt(0);
|
messageHistory.Add(input);
|
||||||
|
while (messageHistory.Count > MaxMessages)
|
||||||
|
{
|
||||||
|
messageHistory.RemoveAt(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ namespace Barotrauma.Networking
|
|||||||
public NetworkConnection Connection { get; set; }
|
public NetworkConnection Connection { get; set; }
|
||||||
|
|
||||||
public bool SpectateOnly;
|
public bool SpectateOnly;
|
||||||
|
public bool? WaitForNextRoundRespawn;
|
||||||
|
|
||||||
public int KarmaKickCount;
|
public int KarmaKickCount;
|
||||||
|
|
||||||
|
|||||||
@@ -486,6 +486,11 @@ namespace Barotrauma.Networking
|
|||||||
endRoundTimer += deltaTime;
|
endRoundTimer += deltaTime;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
else if (isCrewDead && (GameMain.GameSession?.GameMode is CampaignMode))
|
||||||
|
{
|
||||||
|
endRoundDelay = 1.0f;
|
||||||
|
endRoundTimer += deltaTime;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
endRoundTimer = 0.0f;
|
endRoundTimer = 0.0f;
|
||||||
@@ -505,10 +510,14 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
Log("Ending round (submarine reached the end of the level)", ServerLog.MessageType.ServerMessage);
|
Log("Ending round (submarine reached the end of the level)", ServerLog.MessageType.ServerMessage);
|
||||||
}
|
}
|
||||||
else
|
else if (respawnManager == null)
|
||||||
{
|
{
|
||||||
Log("Ending round (no living players left and respawning is not enabled during this round)", ServerLog.MessageType.ServerMessage);
|
Log("Ending round (no living players left and respawning is not enabled during this round)", ServerLog.MessageType.ServerMessage);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log("Ending round (no living players left)", ServerLog.MessageType.ServerMessage);
|
||||||
|
}
|
||||||
EndGame();
|
EndGame();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -819,6 +828,9 @@ namespace Barotrauma.Networking
|
|||||||
case ClientPacketHeader.READY_CHECK:
|
case ClientPacketHeader.READY_CHECK:
|
||||||
ReadyCheck.ServerRead(inc, connectedClient);
|
ReadyCheck.ServerRead(inc, connectedClient);
|
||||||
break;
|
break;
|
||||||
|
case ClientPacketHeader.READY_TO_SPAWN:
|
||||||
|
ReadReadyToSpawnMessage(inc, connectedClient);
|
||||||
|
break;
|
||||||
case ClientPacketHeader.FILE_REQUEST:
|
case ClientPacketHeader.FILE_REQUEST:
|
||||||
if (serverSettings.AllowFileTransfers)
|
if (serverSettings.AllowFileTransfers)
|
||||||
{
|
{
|
||||||
@@ -1191,6 +1203,15 @@ namespace Barotrauma.Networking
|
|||||||
mpCampaign.ServerReadCrew(inc, sender);
|
mpCampaign.ServerReadCrew(inc, sender);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private void ReadReadyToSpawnMessage(IReadMessage inc, Client sender)
|
||||||
|
{
|
||||||
|
sender.SpectateOnly = inc.ReadBoolean() && (serverSettings.AllowSpectating || sender.Connection == OwnerConnection);
|
||||||
|
sender.WaitForNextRoundRespawn = inc.ReadBoolean();
|
||||||
|
if (!(GameMain.GameSession?.GameMode is CampaignMode))
|
||||||
|
{
|
||||||
|
sender.WaitForNextRoundRespawn = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void ClientReadServerCommand(IReadMessage inc)
|
private void ClientReadServerCommand(IReadMessage inc)
|
||||||
{
|
{
|
||||||
@@ -2145,12 +2166,12 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
|
|
||||||
MissionMode missionMode = GameMain.GameSession.GameMode as MissionMode;
|
MissionMode missionMode = GameMain.GameSession.GameMode as MissionMode;
|
||||||
bool missionAllowRespawn = GameMain.GameSession.Campaign == null && (missionMode == null || !missionMode.Missions.Any(m => !m.AllowRespawn));
|
bool missionAllowRespawn = missionMode == null || !missionMode.Missions.Any(m => !m.AllowRespawn);
|
||||||
bool outpostAllowRespawn = GameMain.GameSession.Campaign != null && Level.Loaded?.Type == LevelData.LevelType.Outpost;
|
bool isOutpost = campaign != null && campaign.NextLevel?.Type == LevelData.LevelType.Outpost;
|
||||||
|
|
||||||
if (serverSettings.AllowRespawn && (missionAllowRespawn || outpostAllowRespawn))
|
if (serverSettings.AllowRespawn && missionAllowRespawn)
|
||||||
{
|
{
|
||||||
respawnManager = new RespawnManager(this, serverSettings.UseRespawnShuttle && !outpostAllowRespawn ? selectedShuttle : null);
|
respawnManager = new RespawnManager(this, serverSettings.UseRespawnShuttle && !isOutpost ? selectedShuttle : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
Level.Loaded?.SpawnNPCs();
|
Level.Loaded?.SpawnNPCs();
|
||||||
@@ -2400,9 +2421,8 @@ namespace Barotrauma.Networking
|
|||||||
msg.Write((byte)ServerPacketHeader.STARTGAME);
|
msg.Write((byte)ServerPacketHeader.STARTGAME);
|
||||||
msg.Write(seed);
|
msg.Write(seed);
|
||||||
msg.Write(gameSession.GameMode.Preset.Identifier);
|
msg.Write(gameSession.GameMode.Preset.Identifier);
|
||||||
bool missionAllowRespawn = campaign == null && (missionMode == null || !missionMode.Missions.Any(m => !m.AllowRespawn));
|
bool missionAllowRespawn = missionMode == null || !missionMode.Missions.Any(m => !m.AllowRespawn);
|
||||||
bool outpostAllowRespawn = campaign != null && campaign.NextLevel?.Type == LevelData.LevelType.Outpost;
|
msg.Write(serverSettings.AllowRespawn && missionAllowRespawn);
|
||||||
msg.Write(serverSettings.AllowRespawn && (missionAllowRespawn || outpostAllowRespawn));
|
|
||||||
msg.Write(serverSettings.AllowDisguises);
|
msg.Write(serverSettings.AllowDisguises);
|
||||||
msg.Write(serverSettings.AllowRewiring);
|
msg.Write(serverSettings.AllowRewiring);
|
||||||
msg.Write(serverSettings.LockAllDefaultWires);
|
msg.Write(serverSettings.LockAllDefaultWires);
|
||||||
@@ -2563,6 +2583,7 @@ namespace Barotrauma.Networking
|
|||||||
client.Character = null;
|
client.Character = null;
|
||||||
client.HasSpawned = false;
|
client.HasSpawned = false;
|
||||||
client.InGame = false;
|
client.InGame = false;
|
||||||
|
client.WaitForNextRoundRespawn = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2798,6 +2819,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
client.Character = null;
|
client.Character = null;
|
||||||
client.HasSpawned = false;
|
client.HasSpawned = false;
|
||||||
|
client.WaitForNextRoundRespawn = null;
|
||||||
client.InGame = false;
|
client.InGame = false;
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(msg)) { msg = $"ServerMessage.ClientLeftServer~[client]={ClientLogName(client)}"; }
|
if (string.IsNullOrWhiteSpace(msg)) { msg = $"ServerMessage.ClientLeftServer~[client]={ClientLogName(client)}"; }
|
||||||
|
|||||||
@@ -21,10 +21,9 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
//don't allow respawning if the client has previously disconnected and their corpse is still present on the server
|
//don't allow respawning if the client has previously disconnected and their corpse is still present on the server
|
||||||
var matchingData = campaign?.GetClientCharacterData(c);
|
var matchingData = campaign?.GetClientCharacterData(c);
|
||||||
if (matchingData != null && matchingData.HasSpawned &&
|
if (matchingData != null && matchingData.HasSpawned)
|
||||||
Character.CharacterList.Any(c => c.Info == matchingData.CharacterInfo && c.CauseOfDeath?.Type == CauseOfDeathType.Disconnected))
|
|
||||||
{
|
{
|
||||||
continue;
|
if (!c.WaitForNextRoundRespawn.HasValue || c.WaitForNextRoundRespawn.Value) { continue; }
|
||||||
}
|
}
|
||||||
|
|
||||||
yield return c;
|
yield return c;
|
||||||
@@ -77,25 +76,24 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
partial void UpdateWaiting(float deltaTime)
|
partial void UpdateWaiting(float deltaTime)
|
||||||
{
|
{
|
||||||
|
if (RespawnShuttle != null)
|
||||||
|
{
|
||||||
|
RespawnShuttle.Velocity = Vector2.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
bool respawnPending = RespawnPending();
|
bool respawnPending = RespawnPending();
|
||||||
if (respawnPending != RespawnCountdownStarted)
|
if (respawnPending != RespawnCountdownStarted)
|
||||||
{
|
{
|
||||||
RespawnCountdownStarted = respawnPending;
|
RespawnCountdownStarted = respawnPending;
|
||||||
RespawnTime = DateTime.Now + new TimeSpan(0,0,0,0, (int)(GameMain.Server.ServerSettings.RespawnInterval * 1000.0f));
|
RespawnTime = DateTime.Now + new TimeSpan(0, 0, 0, 0, (int)(GameMain.Server.ServerSettings.RespawnInterval * 1000.0f));
|
||||||
GameMain.Server.CreateEntityEvent(this);
|
GameMain.Server.CreateEntityEvent(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!RespawnCountdownStarted) { return; }
|
if (RespawnCountdownStarted && DateTime.Now > RespawnTime)
|
||||||
|
|
||||||
if (DateTime.Now > RespawnTime)
|
|
||||||
{
|
{
|
||||||
DispatchShuttle();
|
DispatchShuttle();
|
||||||
RespawnCountdownStarted = false;
|
RespawnCountdownStarted = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RespawnShuttle == null) { return; }
|
|
||||||
|
|
||||||
RespawnShuttle.Velocity = Vector2.Zero;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DispatchShuttle()
|
private void DispatchShuttle()
|
||||||
@@ -183,7 +181,6 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
partial void UpdateTransportingProjSpecific(float deltaTime)
|
partial void UpdateTransportingProjSpecific(float deltaTime)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!ReturnCountdownStarted)
|
if (!ReturnCountdownStarted)
|
||||||
{
|
{
|
||||||
//if there are no living chracters inside, transporting can be stopped immediately
|
//if there are no living chracters inside, transporting can be stopped immediately
|
||||||
@@ -230,6 +227,8 @@ namespace Barotrauma.Networking
|
|||||||
//get rid of the existing character
|
//get rid of the existing character
|
||||||
c.Character?.DespawnNow();
|
c.Character?.DespawnNow();
|
||||||
|
|
||||||
|
c.WaitForNextRoundRespawn = null;
|
||||||
|
|
||||||
var matchingData = campaign?.GetClientCharacterData(c);
|
var matchingData = campaign?.GetClientCharacterData(c);
|
||||||
if (matchingData != null && !matchingData.HasSpawned)
|
if (matchingData != null && !matchingData.HasSpawned)
|
||||||
{
|
{
|
||||||
@@ -332,6 +331,15 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
|
|
||||||
var characterData = campaign?.GetClientCharacterData(clients[i]);
|
var characterData = campaign?.GetClientCharacterData(clients[i]);
|
||||||
|
if (characterData != null && Level.Loaded?.Type != LevelData.LevelType.Outpost)
|
||||||
|
{
|
||||||
|
var respawnPenaltyAffliction = AfflictionPrefab.List.FirstOrDefault(a => a.AfflictionType.Equals("respawnpenalty", StringComparison.OrdinalIgnoreCase));
|
||||||
|
if (respawnPenaltyAffliction != null)
|
||||||
|
{
|
||||||
|
character.CharacterHealth.ApplyAffliction(targetLimb: null, respawnPenaltyAffliction.Instantiate(10.0f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (characterData == null || characterData.HasSpawned)
|
if (characterData == null || characterData.HasSpawned)
|
||||||
{
|
{
|
||||||
//give the character the items they would've gotten if they had spawned in the main sub
|
//give the character the items they would've gotten if they had spawned in the main sub
|
||||||
|
|||||||
@@ -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.1300.0.2</Version>
|
<Version>0.1300.0.3</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>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using NLog.Targets;
|
using NLog.Targets;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
@@ -18,8 +19,11 @@ namespace Barotrauma
|
|||||||
private readonly Alignment? cameraEndPos;
|
private readonly Alignment? cameraEndPos;
|
||||||
private readonly float? startZoom;
|
private readonly float? startZoom;
|
||||||
private readonly float? endZoom;
|
private readonly float? endZoom;
|
||||||
public readonly float Duration;
|
|
||||||
|
public readonly float WaitDuration;
|
||||||
|
public readonly float PanDuration;
|
||||||
public readonly bool FadeOut;
|
public readonly bool FadeOut;
|
||||||
|
public readonly bool LosFadeIn;
|
||||||
|
|
||||||
private readonly CoroutineHandle updateCoroutine;
|
private readonly CoroutineHandle updateCoroutine;
|
||||||
|
|
||||||
@@ -28,10 +32,12 @@ namespace Barotrauma
|
|||||||
public bool AllowInterrupt = false;
|
public bool AllowInterrupt = false;
|
||||||
public bool RemoveControlFromCharacter = true;
|
public bool RemoveControlFromCharacter = true;
|
||||||
|
|
||||||
public CameraTransition(ISpatialEntity targetEntity, Camera cam, Alignment? cameraStartPos, Alignment? cameraEndPos, bool fadeOut = true, float duration = 10.0f, float? startZoom = null, float? endZoom = null)
|
public CameraTransition(ISpatialEntity targetEntity, Camera cam, Alignment? cameraStartPos, Alignment? cameraEndPos, bool fadeOut = true, bool losFadeIn = false, float waitDuration = 0f, float panDuration = 10.0f, float? startZoom = null, float? endZoom = null)
|
||||||
{
|
{
|
||||||
Duration = duration;
|
WaitDuration = waitDuration;
|
||||||
|
PanDuration = panDuration;
|
||||||
FadeOut = fadeOut;
|
FadeOut = fadeOut;
|
||||||
|
LosFadeIn = losFadeIn;
|
||||||
this.cameraStartPos = cameraStartPos;
|
this.cameraStartPos = cameraStartPos;
|
||||||
this.cameraEndPos = cameraEndPos;
|
this.cameraEndPos = cameraEndPos;
|
||||||
this.startZoom = startZoom;
|
this.startZoom = startZoom;
|
||||||
@@ -77,9 +83,12 @@ namespace Barotrauma
|
|||||||
Vector2 initialCameraPos = cam.Position;
|
Vector2 initialCameraPos = cam.Position;
|
||||||
Vector2? initialTargetPos = targetEntity?.WorldPosition;
|
Vector2? initialTargetPos = targetEntity?.WorldPosition;
|
||||||
|
|
||||||
float timer = 0.0f;
|
float timer = -WaitDuration;
|
||||||
while (timer < Duration)
|
|
||||||
|
while (timer < PanDuration)
|
||||||
{
|
{
|
||||||
|
float clampedTimer = Math.Max(timer, 0f);
|
||||||
|
|
||||||
if (Screen.Selected != GameMain.GameScreen)
|
if (Screen.Selected != GameMain.GameScreen)
|
||||||
{
|
{
|
||||||
yield return new WaitForSeconds(0.1f);
|
yield return new WaitForSeconds(0.1f);
|
||||||
@@ -136,14 +145,20 @@ namespace Barotrauma
|
|||||||
MathHelper.Lerp(maxPos.Y, minPos.Y, (cameraEndPos.Value.ToVector2().Y + 1.0f) / 2.0f)) :
|
MathHelper.Lerp(maxPos.Y, minPos.Y, (cameraEndPos.Value.ToVector2().Y + 1.0f) / 2.0f)) :
|
||||||
prevControlled?.WorldPosition ?? targetEntity.WorldPosition;
|
prevControlled?.WorldPosition ?? targetEntity.WorldPosition;
|
||||||
|
|
||||||
Vector2 cameraPos = Vector2.SmoothStep(startPos, endPos, timer / Duration);
|
Vector2 cameraPos = Vector2.SmoothStep(startPos, endPos, clampedTimer / PanDuration);
|
||||||
cam.Translate(cameraPos - cam.Position);
|
cam.Translate(cameraPos - cam.Position);
|
||||||
|
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
cam.Zoom = MathHelper.SmoothStep(startZoom, endZoom, timer / Duration);
|
cam.Zoom = MathHelper.SmoothStep(startZoom, endZoom, clampedTimer / PanDuration);
|
||||||
if (timer / Duration > 0.9f)
|
if (clampedTimer / PanDuration > 0.9f)
|
||||||
{
|
{
|
||||||
if (FadeOut) { GUI.ScreenOverlayColor = Color.Lerp(Color.TransparentBlack, Color.Black, ((timer / Duration) - 0.9f) * 10.0f); }
|
if (FadeOut) { GUI.ScreenOverlayColor = Color.Lerp(Color.TransparentBlack, Color.Black, ((clampedTimer / PanDuration) - 0.9f) * 10.0f); }
|
||||||
|
}
|
||||||
|
if (LosFadeIn && clampedTimer / PanDuration > 0.8f)
|
||||||
|
{
|
||||||
|
GameMain.LightManager.LosAlpha = ((clampedTimer / PanDuration) - 0.8f) * 5.0f;
|
||||||
|
Lights.LightManager.ViewTarget = prevControlled ?? (targetEntity as Entity);
|
||||||
|
GameMain.LightManager.LosEnabled = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
timer += CoroutineManager.UnscaledDeltaTime;
|
timer += CoroutineManager.UnscaledDeltaTime;
|
||||||
@@ -158,6 +173,7 @@ namespace Barotrauma
|
|||||||
#if CLIENT
|
#if CLIENT
|
||||||
GUI.ScreenOverlayColor = Color.TransparentBlack;
|
GUI.ScreenOverlayColor = Color.TransparentBlack;
|
||||||
GameMain.LightManager.LosEnabled = true;
|
GameMain.LightManager.LosEnabled = true;
|
||||||
|
GameMain.LightManager.LosAlpha = 1f;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (prevControlled != null && !prevControlled.Removed)
|
if (prevControlled != null && !prevControlled.Removed)
|
||||||
|
|||||||
@@ -172,6 +172,15 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The monster won't try to damage these submarines
|
||||||
|
/// </summary>
|
||||||
|
public HashSet<Submarine> UnattackableSubmarines
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
private set;
|
||||||
|
} = new HashSet<Submarine>();
|
||||||
|
|
||||||
public bool IsBeingChasedBy(Character c) => c.AIController is EnemyAIController enemyAI && enemyAI.SelectedAiTarget?.Entity is Character && (enemyAI.State == AIState.Aggressive || enemyAI.State == AIState.Attack);
|
public bool IsBeingChasedBy(Character c) => c.AIController is EnemyAIController enemyAI && enemyAI.SelectedAiTarget?.Entity is Character && (enemyAI.State == AIState.Aggressive || enemyAI.State == AIState.Attack);
|
||||||
private bool IsBeingChased => SelectedAiTarget?.Entity is Character targetCharacter && IsBeingChasedBy(targetCharacter);
|
private bool IsBeingChased => SelectedAiTarget?.Entity is Character targetCharacter && IsBeingChasedBy(targetCharacter);
|
||||||
|
|
||||||
@@ -2150,7 +2159,13 @@ namespace Barotrauma
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Ignore all structures, items, and hulls inside wrecks and beacons
|
// Ignore all structures, items, and hulls inside wrecks and beacons
|
||||||
if (aiTarget.Entity.Submarine != null && (aiTarget.Entity.Submarine.Info.IsWreck || aiTarget.Entity.Submarine.Info.IsBeacon)) { continue; }
|
if (aiTarget.Entity.Submarine != null)
|
||||||
|
{
|
||||||
|
if (aiTarget.Entity.Submarine.Info.IsWreck || aiTarget.Entity.Submarine.Info.IsBeacon || UnattackableSubmarines.Contains(aiTarget.Entity.Submarine))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (aiTarget.Entity is Hull hull)
|
if (aiTarget.Entity is Hull hull)
|
||||||
{
|
{
|
||||||
// Ignore the target if it's a room and the character is already inside a sub
|
// Ignore the target if it's a room and the character is already inside a sub
|
||||||
@@ -2439,13 +2454,23 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Don't target characters that are outside of the allowed zone, unless attacking or escaping
|
|
||||||
if (targetParams.State != AIState.Attack && targetParams.State != AIState.Escape && targetParams.State != AIState.Avoid)
|
// Don't target characters that are outside of the allowed zone, unless chasing or escaping.
|
||||||
|
switch (targetParams.State)
|
||||||
{
|
{
|
||||||
if (!IsPositionInsideAllowedZone(aiTarget.WorldPosition, out _))
|
case AIState.Escape:
|
||||||
{
|
case AIState.Avoid:
|
||||||
continue;
|
break;
|
||||||
}
|
default:
|
||||||
|
if (targetParams.State == AIState.Attack)
|
||||||
|
{
|
||||||
|
if (State == targetParams.State && SelectedAiTarget == aiTarget) { break; }
|
||||||
|
}
|
||||||
|
if (!IsPositionInsideAllowedZone(aiTarget.WorldPosition, out _))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
valueModifier *= targetMemory.Priority / (float)Math.Sqrt(dist);
|
valueModifier *= targetMemory.Priority / (float)Math.Sqrt(dist);
|
||||||
|
|||||||
@@ -1012,11 +1012,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool allowOffensive = HasItem(attacker, "handlocker", out _, requireEquipped: true);
|
|
||||||
if (attackResult.Afflictions.Any(a => a is AfflictionHusk))
|
|
||||||
{
|
|
||||||
cumulativeDamage = 100;
|
|
||||||
}
|
|
||||||
// Don't react to minor (accidental) dmg done by characters that are in the same team
|
// Don't react to minor (accidental) dmg done by characters that are in the same team
|
||||||
if (cumulativeDamage < 10)
|
if (cumulativeDamage < 10)
|
||||||
{
|
{
|
||||||
@@ -1027,7 +1022,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AddCombatObjective(DetermineCombatMode(Character, cumulativeDamage, dmgThreshold: 20, allowOffensive: allowOffensive), attacker, GetReactionTime() * 2);
|
AddCombatObjective(DetermineCombatMode(Character, cumulativeDamage, dmgThreshold: 50), attacker, GetReactionTime() * 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1056,7 +1051,7 @@ namespace Barotrauma
|
|||||||
if (!otherHumanAI.IsFriendly(Character)) { continue; }
|
if (!otherHumanAI.IsFriendly(Character)) { continue; }
|
||||||
bool isWitnessing = otherHumanAI.VisibleHulls.Contains(Character.CurrentHull) || otherHumanAI.VisibleHulls.Contains(attacker.CurrentHull);
|
bool isWitnessing = otherHumanAI.VisibleHulls.Contains(Character.CurrentHull) || otherHumanAI.VisibleHulls.Contains(attacker.CurrentHull);
|
||||||
if (!isWitnessing && !CheckReportRange(Character, otherCharacter, ReportRange)) { continue; }
|
if (!isWitnessing && !CheckReportRange(Character, otherCharacter, ReportRange)) { continue; }
|
||||||
var combatMode = DetermineCombatMode(otherCharacter, cumulativeDamage, isWitnessing);
|
var combatMode = DetermineCombatMode(otherCharacter, cumulativeDamage, isWitnessing, dmgThreshold: attacker.TeamID == Character.TeamID ? 50 : 10);
|
||||||
float delay = isWitnessing ? GetReactionTime() : Rand.Range(2.0f, 5.0f, Rand.RandSync.Unsynced);
|
float delay = isWitnessing ? GetReactionTime() : Rand.Range(2.0f, 5.0f, Rand.RandSync.Unsynced);
|
||||||
otherHumanAI.AddCombatObjective(combatMode, attacker, delay);
|
otherHumanAI.AddCombatObjective(combatMode, attacker, delay);
|
||||||
}
|
}
|
||||||
@@ -1099,6 +1094,15 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (c.AIController is HumanAIController humanAI && humanAI.ObjectiveManager.GetActiveObjective<AIObjectiveCombat>()?.Enemy == attacker)
|
||||||
|
{
|
||||||
|
// Already targeting the attacker -> treat as a more serious threat.
|
||||||
|
cumulativeDamage *= 2;
|
||||||
|
}
|
||||||
|
if (attackResult.Afflictions.Any(a => a is AfflictionHusk))
|
||||||
|
{
|
||||||
|
cumulativeDamage = 100;
|
||||||
|
}
|
||||||
if (cumulativeDamage > dmgThreshold)
|
if (cumulativeDamage > dmgThreshold)
|
||||||
{
|
{
|
||||||
if (c.IsSecurity)
|
if (c.IsSecurity)
|
||||||
@@ -1154,7 +1158,7 @@ namespace Barotrauma
|
|||||||
HoldPosition =
|
HoldPosition =
|
||||||
Character.Info?.Job?.Prefab.Identifier == "watchman" ||
|
Character.Info?.Job?.Prefab.Identifier == "watchman" ||
|
||||||
Character.CurrentHull == null ||
|
Character.CurrentHull == null ||
|
||||||
Character.IsOnPlayerTeam && ObjectiveManager.GetActiveObjective<AIObjectiveGoTo>()?.Target is Character followTarget && followTarget.IsPlayer,
|
Character.IsOnPlayerTeam && !target.IsPlayer && ObjectiveManager.GetActiveObjective<AIObjectiveGoTo>()?.Target is Character followTarget && followTarget.IsPlayer,
|
||||||
abortCondition = abortCondition,
|
abortCondition = abortCondition,
|
||||||
allowHoldFire = allowHoldFire,
|
allowHoldFire = allowHoldFire,
|
||||||
};
|
};
|
||||||
@@ -1841,15 +1845,14 @@ namespace Barotrauma
|
|||||||
if (character == null) { continue; }
|
if (character == null) { continue; }
|
||||||
if (c == character) { continue; }
|
if (c == character) { continue; }
|
||||||
if (c.IsDead || c.IsIncapacitated) { continue; }
|
if (c.IsDead || c.IsIncapacitated) { continue; }
|
||||||
if (c.SelectedConstruction != target.Item) { continue; }
|
|
||||||
if (!IsFriendly(character, c, onlySameTeam: true)) { continue; }
|
if (!IsFriendly(character, c, onlySameTeam: true)) { continue; }
|
||||||
operatingCharacter = c;
|
operatingCharacter = c;
|
||||||
// If the other character is player, don't try to operate
|
|
||||||
if (c.IsPlayer) { return true; }
|
|
||||||
if (c.AIController is HumanAIController controllingHumanAi)
|
if (c.AIController is HumanAIController controllingHumanAi)
|
||||||
{
|
{
|
||||||
Item otherTarget = controllingHumanAi.objectiveManager.GetActiveObjective<AIObjectiveOperateItem>()?.Component.Item ?? c.SelectedConstruction;
|
Item otherTarget = controllingHumanAi.objectiveManager.GetActiveObjective<AIObjectiveOperateItem>()?.Component.Item ?? c.SelectedConstruction;
|
||||||
if (otherTarget != target.Item) { continue; }
|
if (otherTarget != target.Item) { continue; }
|
||||||
|
// If the other character is player, don't try to operate
|
||||||
|
if (c.IsPlayer) { return true; }
|
||||||
// If the other character is ordered to operate the item, let him do it
|
// If the other character is ordered to operate the item, let him do it
|
||||||
if (controllingHumanAi.ObjectiveManager.IsCurrentOrder<AIObjectiveOperateItem>())
|
if (controllingHumanAi.ObjectiveManager.IsCurrentOrder<AIObjectiveOperateItem>())
|
||||||
{
|
{
|
||||||
@@ -1874,8 +1877,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Shouldn't go here, unless we allow non-humans to operate items
|
return c.SelectedConstruction == target.Item;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (Timing.TotalTime < GameMain.GameSession.RoundStartTime + 120.0f &&
|
if (Timing.TotalTime < GameMain.GameSession.RoundStartTime + 120.0f &&
|
||||||
speaker?.CurrentHull != null &&
|
speaker?.CurrentHull != null &&
|
||||||
speaker.TeamID == CharacterTeamType.FriendlyNPC &&
|
(speaker.TeamID == CharacterTeamType.FriendlyNPC || speaker.TeamID == CharacterTeamType.None) &&
|
||||||
Character.CharacterList.Any(c => c.TeamID != speaker.TeamID && c.CurrentHull == speaker.CurrentHull))
|
Character.CharacterList.Any(c => c.TeamID != speaker.TeamID && c.CurrentHull == speaker.CurrentHull))
|
||||||
{
|
{
|
||||||
currentFlags.Add("EnterOutpost");
|
currentFlags.Add("EnterOutpost");
|
||||||
@@ -188,6 +188,11 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
currentFlags.Add("Casual");
|
currentFlags.Add("Casual");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (GameMain.GameSession.IsCurrentLocationRadiated())
|
||||||
|
{
|
||||||
|
currentFlags.Add("InRadiation");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (speaker != null)
|
if (speaker != null)
|
||||||
|
|||||||
+13
@@ -50,6 +50,11 @@ namespace Barotrauma
|
|||||||
float reduction = IsPriority ? 1 : isSelected ? 2 : 3;
|
float reduction = IsPriority ? 1 : isSelected ? 2 : 3;
|
||||||
float max = AIObjectiveManager.LowestOrderPriority - reduction;
|
float max = AIObjectiveManager.LowestOrderPriority - reduction;
|
||||||
Priority = MathHelper.Lerp(0, max, MathHelper.Clamp(devotion + (distanceFactor * PriorityModifier), 0, 1));
|
Priority = MathHelper.Lerp(0, max, MathHelper.Clamp(devotion + (distanceFactor * PriorityModifier), 0, 1));
|
||||||
|
if (decontainObjective == null)
|
||||||
|
{
|
||||||
|
// Halve the priority until there's a decontain objective (a valid container was found).
|
||||||
|
Priority /= 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return Priority;
|
return Priority;
|
||||||
}
|
}
|
||||||
@@ -126,5 +131,13 @@ namespace Barotrauma
|
|||||||
itemIndex = 0;
|
itemIndex = 0;
|
||||||
decontainObjective = null;
|
decontainObjective = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void DropTarget()
|
||||||
|
{
|
||||||
|
if (item != null && character.HasItem(item))
|
||||||
|
{
|
||||||
|
item.Drop(character);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+32
-5
@@ -2,6 +2,7 @@
|
|||||||
using Barotrauma.Items.Components;
|
using Barotrauma.Items.Components;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -29,7 +30,21 @@ namespace Barotrauma
|
|||||||
this.prioritizedItems.AddRange(prioritizedItems.Where(i => i != null));
|
this.prioritizedItems.AddRange(prioritizedItems.Where(i => i != null));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override float TargetEvaluation() => Targets.Any() ? (objectiveManager.IsOrder(this) ? objectiveManager.GetOrderPriority(this) : AIObjectiveManager.RunPriority - 1) : 0;
|
protected override float TargetEvaluation()
|
||||||
|
{
|
||||||
|
if (Targets.None()) { return 0; }
|
||||||
|
if (objectiveManager.IsOrder(this))
|
||||||
|
{
|
||||||
|
float prio = objectiveManager.GetOrderPriority(this);
|
||||||
|
if (subObjectives.All(so => so.SubObjectives.None()))
|
||||||
|
{
|
||||||
|
// If none of the subobjectives have subobjectives, no valid container was found. In this case, let's reduce the priority below the run threshold.
|
||||||
|
prio = Math.Min(prio, AIObjectiveManager.RunPriority - 1);
|
||||||
|
}
|
||||||
|
return prio;
|
||||||
|
}
|
||||||
|
return AIObjectiveManager.RunPriority - 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
protected override bool Filter(Item target)
|
protected override bool Filter(Item target)
|
||||||
{
|
{
|
||||||
@@ -65,10 +80,10 @@ namespace Barotrauma
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsValidContainer(Item item, Character character) =>
|
public static bool IsValidContainer(Item item, Character character, bool allowUnloading = true) =>
|
||||||
!item.IgnoreByAI && item.IsInteractable(character) && item.HasTag("allowcleanup") && item.ParentInventory == null && item.OwnInventory != null && item.OwnInventory.AllItems.Any() && IsItemInsideValidSubmarine(item, character);
|
!item.IgnoreByAI && item.IsInteractable(character) && item.HasTag("allowcleanup") && allowUnloading && item.ParentInventory == null && item.OwnInventory != null && item.OwnInventory.AllItems.Any() && IsItemInsideValidSubmarine(item, character);
|
||||||
|
|
||||||
public static bool IsValidTarget(Item item, Character character, bool checkInventory)
|
public static bool IsValidTarget(Item item, Character character, bool checkInventory, bool allowUnloading = true)
|
||||||
{
|
{
|
||||||
if (item == null) { return false; }
|
if (item == null) { return false; }
|
||||||
if (item.IgnoreByAI) { return false; }
|
if (item.IgnoreByAI) { return false; }
|
||||||
@@ -76,7 +91,7 @@ namespace Barotrauma
|
|||||||
if (item.SpawnedInOutpost) { return false; }
|
if (item.SpawnedInOutpost) { return false; }
|
||||||
if (item.ParentInventory != null)
|
if (item.ParentInventory != null)
|
||||||
{
|
{
|
||||||
if (item.Container == null || !IsValidContainer(item.Container, character)) { return false; }
|
if (item.Container == null || !IsValidContainer(item.Container, character, allowUnloading)) { return false; }
|
||||||
}
|
}
|
||||||
if (character != null && !IsItemInsideValidSubmarine(item, character)) { return false; }
|
if (character != null && !IsItemInsideValidSubmarine(item, character)) { return false; }
|
||||||
var pickable = item.GetComponent<Pickable>();
|
var pickable = item.GetComponent<Pickable>();
|
||||||
@@ -127,5 +142,17 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
return canEquip;
|
return canEquip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnDeselected()
|
||||||
|
{
|
||||||
|
base.OnDeselected();
|
||||||
|
foreach (var subObjective in SubObjectives)
|
||||||
|
{
|
||||||
|
if (subObjective is AIObjectiveCleanupItem cleanUpObjective)
|
||||||
|
{
|
||||||
|
cleanUpObjective.DropTarget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-10
@@ -457,7 +457,7 @@ namespace Barotrauma
|
|||||||
priority /= 2;
|
priority /= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Enemy.Stun > 1)
|
if (Enemy.IsKnockedDown)
|
||||||
{
|
{
|
||||||
// Enemy is stunned, reduce the priority of stunner weapons.
|
// Enemy is stunned, reduce the priority of stunner weapons.
|
||||||
Attack attack = GetAttackDefinition(weapon);
|
Attack attack = GetAttackDefinition(weapon);
|
||||||
@@ -730,11 +730,12 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
IgnoreIfTargetDead = true,
|
IgnoreIfTargetDead = true,
|
||||||
DialogueIdentifier = "dialogcannotreachtarget",
|
DialogueIdentifier = "dialogcannotreachtarget",
|
||||||
TargetName = Enemy.DisplayName
|
TargetName = Enemy.DisplayName,
|
||||||
|
AlwaysUseEuclideanDistance = false
|
||||||
},
|
},
|
||||||
onAbandon: () => Abandon = true);
|
onAbandon: () => Abandon = true);
|
||||||
if (followTargetObjective == null) { return; }
|
if (followTargetObjective == null) { return; }
|
||||||
if (Mode == CombatMode.Arrest && Enemy.Stun > 2)
|
if (Mode == CombatMode.Arrest && (Enemy.Stun > 1 || Enemy.IsKnockedDown))
|
||||||
{
|
{
|
||||||
if (HumanAIController.HasItem(character, "handlocker", out _))
|
if (HumanAIController.HasItem(character, "handlocker", out _))
|
||||||
{
|
{
|
||||||
@@ -742,8 +743,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
arrestingRegistered = true;
|
arrestingRegistered = true;
|
||||||
followTargetObjective.Completed += OnArrestTargetReached;
|
followTargetObjective.Completed += OnArrestTargetReached;
|
||||||
|
followTargetObjective.CloseEnough = 100;
|
||||||
}
|
}
|
||||||
followTargetObjective.CloseEnough = 100;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -759,7 +760,7 @@ namespace Barotrauma
|
|||||||
SteeringManager.Reset();
|
SteeringManager.Reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (followTargetObjective != null)
|
if (!arrestingRegistered && followTargetObjective != null)
|
||||||
{
|
{
|
||||||
followTargetObjective.CloseEnough =
|
followTargetObjective.CloseEnough =
|
||||||
WeaponComponent is RangedWeapon ? 1000 :
|
WeaponComponent is RangedWeapon ? 1000 :
|
||||||
@@ -782,7 +783,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void OnArrestTargetReached()
|
private void OnArrestTargetReached()
|
||||||
{
|
{
|
||||||
if (HumanAIController.HasItem(character, "handlocker", out IEnumerable<Item> matchingItems) && Enemy.Stun > 0 && character.CanInteractWith(Enemy))
|
if (HumanAIController.HasItem(character, "handlocker", out IEnumerable<Item> matchingItems) && !Enemy.IsUnconscious && Enemy.IsKnockedDown && character.CanInteractWith(Enemy))
|
||||||
{
|
{
|
||||||
var handCuffs = matchingItems.First();
|
var handCuffs = matchingItems.First();
|
||||||
if (!HumanAIController.TakeItem(handCuffs, Enemy.Inventory, equip: true))
|
if (!HumanAIController.TakeItem(handCuffs, Enemy.Inventory, equip: true))
|
||||||
@@ -802,8 +803,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
character.Speak(TextManager.Get("DialogTargetArrested"), null, 3.0f, "targetarrested", 30.0f);
|
character.Speak(TextManager.Get("DialogTargetArrested"), null, 3.0f, "targetarrested", 30.0f);
|
||||||
IsCompleted = true;
|
|
||||||
}
|
}
|
||||||
|
IsCompleted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -937,7 +938,14 @@ namespace Barotrauma
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (reloadTimer > 0) { return; }
|
if (reloadTimer > 0) { return; }
|
||||||
if (Mode == CombatMode.Arrest && isLethalWeapon && Enemy.Stun > 1) { return; }
|
if (Mode == CombatMode.Arrest)
|
||||||
|
{
|
||||||
|
// If the target is arrested or if it's stunned and we can't lock the target up, consider the objective done.
|
||||||
|
if (Enemy.IsKnockedDown && !HumanAIController.HasItem(character, "handlocker", out _, requireEquipped: false) || HumanAIController.HasItem(Enemy, "handlocker", out _, requireEquipped: true))
|
||||||
|
{
|
||||||
|
IsCompleted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (holdFireCondition != null && holdFireCondition()) { return; }
|
if (holdFireCondition != null && holdFireCondition()) { return; }
|
||||||
float sqrDist = Vector2.DistanceSquared(character.Position, Enemy.Position);
|
float sqrDist = Vector2.DistanceSquared(character.Position, Enemy.Position);
|
||||||
if (WeaponComponent is MeleeWeapon meleeWeapon)
|
if (WeaponComponent is MeleeWeapon meleeWeapon)
|
||||||
@@ -1017,6 +1025,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void UseWeapon(float deltaTime)
|
private void UseWeapon(float deltaTime)
|
||||||
{
|
{
|
||||||
|
// Never allow to attack characters with deadly weapons while trying to arrest.
|
||||||
|
if (Mode == CombatMode.Arrest && isLethalWeapon) { return; }
|
||||||
float reloadTime = 0;
|
float reloadTime = 0;
|
||||||
if (WeaponComponent is RangedWeapon rangedWeapon)
|
if (WeaponComponent is RangedWeapon rangedWeapon)
|
||||||
{
|
{
|
||||||
@@ -1038,10 +1048,16 @@ namespace Barotrauma
|
|||||||
reloadTimer = Math.Max(reloadTime, reloadTime * Rand.Range(1f, 1.25f) / AimSpeed);
|
reloadTimer = Math.Max(reloadTime, reloadTime * Rand.Range(1f, 1.25f) / AimSpeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool ShouldUnequipWeapon =>
|
||||||
|
Weapon != null &&
|
||||||
|
character.Submarine != null &&
|
||||||
|
character.Submarine.TeamID == character.TeamID &&
|
||||||
|
Character.CharacterList.None(c => c.Submarine == character.Submarine && HumanAIController.IsActive(c) && !HumanAIController.IsFriendly(character, c) && HumanAIController.VisibleHulls.Contains(c.CurrentHull));
|
||||||
|
|
||||||
protected override void OnCompleted()
|
protected override void OnCompleted()
|
||||||
{
|
{
|
||||||
base.OnCompleted();
|
base.OnCompleted();
|
||||||
if (Weapon != null)
|
if (ShouldUnequipWeapon)
|
||||||
{
|
{
|
||||||
Unequip();
|
Unequip();
|
||||||
}
|
}
|
||||||
@@ -1051,7 +1067,7 @@ namespace Barotrauma
|
|||||||
protected override void OnAbandon()
|
protected override void OnAbandon()
|
||||||
{
|
{
|
||||||
base.OnAbandon();
|
base.OnAbandon();
|
||||||
if (Weapon != null)
|
if (ShouldUnequipWeapon)
|
||||||
{
|
{
|
||||||
Unequip();
|
Unequip();
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -38,7 +38,7 @@ namespace Barotrauma
|
|||||||
Priority = 0;
|
Priority = 0;
|
||||||
Abandon = true;
|
Abandon = true;
|
||||||
}
|
}
|
||||||
else if (HumanAIController.IsTrueForAnyCrewMember(other => other != HumanAIController && other.ObjectiveManager.GetActiveObjective<AIObjectiveFixLeak>()?.Leak == Leak))
|
else if (HumanAIController.IsTrueForAnyCrewMember(other => other != HumanAIController && other.Character.IsBot && other.ObjectiveManager.GetActiveObjective<AIObjectiveFixLeak>()?.Leak == Leak))
|
||||||
{
|
{
|
||||||
Priority = 0;
|
Priority = 0;
|
||||||
Abandon = true;
|
Abandon = true;
|
||||||
|
|||||||
+44
-18
@@ -10,6 +10,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
public override string DebugTag => "get item";
|
public override string DebugTag => "get item";
|
||||||
|
|
||||||
|
public override bool AbandonWhenCannotCompleteSubjectives => false;
|
||||||
|
|
||||||
private readonly bool equip;
|
private readonly bool equip;
|
||||||
public HashSet<Item> ignoredItems = new HashSet<Item>();
|
public HashSet<Item> ignoredItems = new HashSet<Item>();
|
||||||
|
|
||||||
@@ -225,18 +227,8 @@ namespace Barotrauma
|
|||||||
return new AIObjectiveGoTo(moveToTarget, character, objectiveManager, repeat: false, getDivingGearIfNeeded: AllowToFindDivingGear, closeEnough: DefaultReach)
|
return new AIObjectiveGoTo(moveToTarget, character, objectiveManager, repeat: false, getDivingGearIfNeeded: AllowToFindDivingGear, closeEnough: DefaultReach)
|
||||||
{
|
{
|
||||||
// If the root container changes, the item is no longer where it was (taken by someone -> need to find another item)
|
// If the root container changes, the item is no longer where it was (taken by someone -> need to find another item)
|
||||||
abortCondition = obj =>
|
abortCondition = obj => targetItem == null || targetItem.GetRootInventoryOwner() != moveToTarget,
|
||||||
{
|
SpeakIfFails = false
|
||||||
bool abort = targetItem == null || targetItem.GetRootInventoryOwner() != moveToTarget;
|
|
||||||
if (abort)
|
|
||||||
{
|
|
||||||
// Fail silently if someone takes the suit.
|
|
||||||
obj.speakIfFails = false;
|
|
||||||
}
|
|
||||||
return abort;
|
|
||||||
},
|
|
||||||
DialogueIdentifier = "dialogcannotreachtarget",
|
|
||||||
TargetName = (moveToTarget as MapEntity)?.Name ?? (moveToTarget as Character)?.Name ?? moveToTarget.ToString()
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
onAbandon: () =>
|
onAbandon: () =>
|
||||||
@@ -263,13 +255,18 @@ namespace Barotrauma
|
|||||||
if (targetItem == null)
|
if (targetItem == null)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
DebugConsole.NewMessage($"{character.Name}: Cannot find the item, because neither identifiers nor item was defined.", Color.Red);
|
DebugConsole.NewMessage($"{character.Name}: Cannot find an item, because neither identifiers nor item was defined.", Color.Red);
|
||||||
#endif
|
#endif
|
||||||
Abandon = true;
|
Abandon = true;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 10 && currSearchIndex < Item.ItemList.Count - 1; i++)
|
|
||||||
|
float priority = Math.Clamp(objectiveManager.GetCurrentPriority(), 10, 100);
|
||||||
|
bool checkPath = priority >= AIObjectiveManager.LowestOrderPriority && (objectiveManager.IsCurrentOrder<AIObjectiveFixLeaks>() || objectiveManager.CurrentOrder is AIObjectiveGoTo gotoOrder && gotoOrder.followControlledCharacter);
|
||||||
|
bool hasCalledPathFinder = false;
|
||||||
|
int itemsPerFrame = (int)priority;
|
||||||
|
for (int i = 0; i < itemsPerFrame && currSearchIndex < Item.ItemList.Count - 1; i++)
|
||||||
{
|
{
|
||||||
currSearchIndex++;
|
currSearchIndex++;
|
||||||
var item = Item.ItemList[currSearchIndex];
|
var item = Item.ItemList[currSearchIndex];
|
||||||
@@ -310,8 +307,18 @@ namespace Barotrauma
|
|||||||
float distanceFactor = MathHelper.Lerp(1, 0, MathUtils.InverseLerp(0, 10000, dist));
|
float distanceFactor = MathHelper.Lerp(1, 0, MathUtils.InverseLerp(0, 10000, dist));
|
||||||
itemPriority *= distanceFactor;
|
itemPriority *= distanceFactor;
|
||||||
itemPriority *= item.Condition / item.MaxCondition;
|
itemPriority *= item.Condition / item.MaxCondition;
|
||||||
//ignore if the item has a lower priority than the currently selected one
|
// Ignore if the item has a lower priority than the currently selected one
|
||||||
if (itemPriority < currItemPriority) { continue; }
|
if (itemPriority < currItemPriority) { continue; }
|
||||||
|
if (!hasCalledPathFinder && PathSteering != null && checkPath)
|
||||||
|
{
|
||||||
|
// While following the player, let's ensure that there's a valid path to the target before accepting it.
|
||||||
|
// Otherwise it will take some time for us to find a valid item when there are multiple items that we can't reach and some that we can.
|
||||||
|
// This is relatively expensive, so let's do this only when it significantly improves the behavior.
|
||||||
|
// Only allow one path find call per frame.
|
||||||
|
hasCalledPathFinder = true;
|
||||||
|
var path = PathSteering.PathFinder.FindPath(character.SimPosition, item.SimPosition, errorMsgStr: $"AIObjectiveGetItem {character.DisplayName}", nodeFilter: node => node.Waypoint.CurrentHull != null);
|
||||||
|
if (path.Unreachable) { continue; }
|
||||||
|
}
|
||||||
currItemPriority = itemPriority;
|
currItemPriority = itemPriority;
|
||||||
targetItem = item;
|
targetItem = item;
|
||||||
moveToTarget = rootInventoryOwner ?? item;
|
moveToTarget = rootInventoryOwner ?? item;
|
||||||
@@ -326,7 +333,7 @@ namespace Barotrauma
|
|||||||
if (!(MapEntityPrefab.List.FirstOrDefault(me => me is ItemPrefab ip && identifiersOrTags.Any(id => id == ip.Identifier || ip.Tags.Contains(id))) is ItemPrefab prefab))
|
if (!(MapEntityPrefab.List.FirstOrDefault(me => me is ItemPrefab ip && identifiersOrTags.Any(id => id == ip.Identifier || ip.Tags.Contains(id))) is ItemPrefab prefab))
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
DebugConsole.NewMessage($"{character.Name}: Cannot find the item with the following identifier(s) or tag(s): {string.Join(", ", identifiersOrTags)}, tried to spawn the item but no matching item prefabs were found.", Color.Yellow);
|
DebugConsole.NewMessage($"{character.Name}: Cannot find an item with the following identifier(s) or tag(s): {string.Join(", ", identifiersOrTags)}, tried to spawn the item but no matching item prefabs were found.", Color.Yellow);
|
||||||
#endif
|
#endif
|
||||||
Abandon = true;
|
Abandon = true;
|
||||||
}
|
}
|
||||||
@@ -345,7 +352,7 @@ namespace Barotrauma
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
DebugConsole.NewMessage($"{character.Name}: Cannot find the item with the following identifier(s) or tag(s): {string.Join(", ", identifiersOrTags)}", Color.Yellow);
|
DebugConsole.NewMessage($"{character.Name}: Cannot find an item with the following identifier(s) or tag(s): {string.Join(", ", identifiersOrTags)}", Color.Yellow);
|
||||||
#endif
|
#endif
|
||||||
Abandon = true;
|
Abandon = true;
|
||||||
}
|
}
|
||||||
@@ -393,11 +400,30 @@ namespace Barotrauma
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void ResetInternal()
|
private void ResetInternal()
|
||||||
{
|
{
|
||||||
goToObjective = null;
|
RemoveSubObjective(ref goToObjective);
|
||||||
targetItem = originalTarget;
|
targetItem = originalTarget;
|
||||||
moveToTarget = targetItem?.GetRootInventoryOwner();
|
moveToTarget = targetItem?.GetRootInventoryOwner();
|
||||||
isDoneSeeking = false;
|
isDoneSeeking = false;
|
||||||
currSearchIndex = 0;
|
currSearchIndex = 0;
|
||||||
|
currItemPriority = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnAbandon()
|
||||||
|
{
|
||||||
|
base.OnAbandon();
|
||||||
|
if (moveToTarget == null) { return; }
|
||||||
|
#if DEBUG
|
||||||
|
DebugConsole.NewMessage($"{character.Name}: Get item failed to reach {moveToTarget}", Color.Yellow);
|
||||||
|
#endif
|
||||||
|
if (character.IsOnPlayerTeam && objectiveManager.CurrentOrder != null)
|
||||||
|
{
|
||||||
|
string TargetName = (moveToTarget as MapEntity)?.Name ?? (moveToTarget as Character)?.Name ?? moveToTarget.ToString();
|
||||||
|
string msg = TargetName == null ? TextManager.Get("dialogcannotreachtarget", true) : TextManager.GetWithVariable("dialogcannotreachtarget", "[name]", TargetName, formatCapitals: !(moveToTarget is Character));
|
||||||
|
if (msg != null)
|
||||||
|
{
|
||||||
|
character.Speak(msg, identifier: "dialogcannotreachtarget", minDurationBetweenSimilar: 20.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+34
-22
@@ -30,7 +30,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public bool followControlledCharacter;
|
public bool followControlledCharacter;
|
||||||
public bool mimic;
|
public bool mimic;
|
||||||
public bool speakIfFails = true;
|
public bool SpeakIfFails { get; set; } = true;
|
||||||
|
|
||||||
public float extraDistanceWhileSwimming;
|
public float extraDistanceWhileSwimming;
|
||||||
public float extraDistanceOutsideSub;
|
public float extraDistanceOutsideSub;
|
||||||
@@ -67,6 +67,8 @@ namespace Barotrauma
|
|||||||
public bool IgnoreIfTargetDead { get; set; }
|
public bool IgnoreIfTargetDead { get; set; }
|
||||||
public bool AllowGoingOutside { get; set; }
|
public bool AllowGoingOutside { get; set; }
|
||||||
|
|
||||||
|
public bool AlwaysUseEuclideanDistance { get; set; } = true;
|
||||||
|
|
||||||
public override bool AbandonWhenCannotCompleteSubjectives => !repeat;
|
public override bool AbandonWhenCannotCompleteSubjectives => !repeat;
|
||||||
|
|
||||||
public override bool AllowOutsideSubmarine => AllowGoingOutside;
|
public override bool AllowOutsideSubmarine => AllowGoingOutside;
|
||||||
@@ -88,12 +90,7 @@ namespace Barotrauma
|
|||||||
Abandon = !isOrder;
|
Abandon = !isOrder;
|
||||||
return Priority;
|
return Priority;
|
||||||
}
|
}
|
||||||
if (followControlledCharacter && Character.Controlled == null)
|
if (Target == null || Target is Entity e && e.Removed)
|
||||||
{
|
|
||||||
Priority = 0;
|
|
||||||
Abandon = !isOrder;
|
|
||||||
}
|
|
||||||
if (Target is Entity e && e.Removed)
|
|
||||||
{
|
{
|
||||||
Priority = 0;
|
Priority = 0;
|
||||||
Abandon = !isOrder;
|
Abandon = !isOrder;
|
||||||
@@ -147,11 +144,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void SpeakCannotReach()
|
private void SpeakCannotReach()
|
||||||
{
|
{
|
||||||
if (!character.IsOnPlayerTeam) { return; }
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
DebugConsole.NewMessage($"{character.Name}: Cannot reach the target: {Target}", Color.Yellow);
|
DebugConsole.NewMessage($"{character.Name}: Cannot reach the target: {Target}", Color.Yellow);
|
||||||
#endif
|
#endif
|
||||||
if (objectiveManager.HasOrders() && DialogueIdentifier != null && speakIfFails)
|
if (character.IsOnPlayerTeam && objectiveManager.CurrentOrder != null && DialogueIdentifier != null && SpeakIfFails)
|
||||||
{
|
{
|
||||||
string msg = TargetName == null ? TextManager.Get(DialogueIdentifier, true) : TextManager.GetWithVariable(DialogueIdentifier, "[name]", TargetName, formatCapitals: !(Target is Character));
|
string msg = TargetName == null ? TextManager.Get(DialogueIdentifier, true) : TextManager.GetWithVariable(DialogueIdentifier, "[name]", TargetName, formatCapitals: !(Target is Character));
|
||||||
if (msg != null)
|
if (msg != null)
|
||||||
@@ -165,12 +161,15 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (followControlledCharacter)
|
if (followControlledCharacter)
|
||||||
{
|
{
|
||||||
if (Character.Controlled == null || !HumanAIController.IsFriendly(Character.Controlled))
|
if (Character.Controlled != null && HumanAIController.IsFriendly(Character.Controlled))
|
||||||
|
{
|
||||||
|
Target = Character.Controlled;
|
||||||
|
}
|
||||||
|
if (Target == null)
|
||||||
{
|
{
|
||||||
Abandon = true;
|
Abandon = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Target = Character.Controlled;
|
|
||||||
}
|
}
|
||||||
if (Target == character || character.SelectedBy != null && HumanAIController.IsFriendly(character.SelectedBy))
|
if (Target == character || character.SelectedBy != null && HumanAIController.IsFriendly(character.SelectedBy))
|
||||||
{
|
{
|
||||||
@@ -260,6 +259,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
if (needsEquipment)
|
if (needsEquipment)
|
||||||
{
|
{
|
||||||
|
SteeringManager.Reset();
|
||||||
if (findDivingGear != null && !findDivingGear.CanBeCompleted)
|
if (findDivingGear != null && !findDivingGear.CanBeCompleted)
|
||||||
{
|
{
|
||||||
TryAddSubObjective(ref findDivingGear, () => new AIObjectiveFindDivingGear(character, needsDivingSuit: false, objectiveManager),
|
TryAddSubObjective(ref findDivingGear, () => new AIObjectiveFindDivingGear(character, needsDivingSuit: false, objectiveManager),
|
||||||
@@ -288,9 +288,14 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
float maxGapDistance = 500;
|
||||||
|
Character targetCharacter = Target as Character;
|
||||||
if (character.AnimController.InWater)
|
if (character.AnimController.InWater)
|
||||||
{
|
{
|
||||||
if (character.CurrentHull == null)
|
if (character.CurrentHull == null ||
|
||||||
|
followControlledCharacter &&
|
||||||
|
targetCharacter != null && (targetCharacter.CurrentHull == null) != (character.CurrentHull == null) &&
|
||||||
|
Vector2.DistanceSquared(character.WorldPosition, Target.WorldPosition) < maxGapDistance * maxGapDistance)
|
||||||
{
|
{
|
||||||
if (seekGapsTimer > 0)
|
if (seekGapsTimer > 0)
|
||||||
{
|
{
|
||||||
@@ -298,7 +303,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SeekGaps(maxDistance: 500);
|
SeekGaps(maxGapDistance);
|
||||||
seekGapsTimer = seekGapsInterval * Rand.Range(0.1f, 1.1f);
|
seekGapsTimer = seekGapsInterval * Rand.Range(0.1f, 1.1f);
|
||||||
if (TargetGap != null)
|
if (TargetGap != null)
|
||||||
{
|
{
|
||||||
@@ -327,7 +332,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
if (TargetGap != null)
|
if (TargetGap != null)
|
||||||
{
|
{
|
||||||
if (TargetGap.FlowTargetHull != null && HumanAIController.SteerThroughGap(TargetGap, TargetGap.FlowTargetHull.WorldPosition, deltaTime))
|
if (TargetGap.FlowTargetHull != null && HumanAIController.SteerThroughGap(TargetGap, followControlledCharacter ? Target.WorldPosition : TargetGap.FlowTargetHull.WorldPosition, deltaTime))
|
||||||
{
|
{
|
||||||
SteeringManager.SteeringAvoid(deltaTime, avoidLookAheadDistance, weight: 1);
|
SteeringManager.SteeringAvoid(deltaTime, avoidLookAheadDistance, weight: 1);
|
||||||
return;
|
return;
|
||||||
@@ -347,7 +352,7 @@ namespace Barotrauma
|
|||||||
float closeEnough = 250;
|
float closeEnough = 250;
|
||||||
float squaredDistance = Vector2.DistanceSquared(character.WorldPosition, Target.WorldPosition);
|
float squaredDistance = Vector2.DistanceSquared(character.WorldPosition, Target.WorldPosition);
|
||||||
bool shouldUseScooter = squaredDistance > closeEnough * closeEnough && (!mimic ||
|
bool shouldUseScooter = squaredDistance > closeEnough * closeEnough && (!mimic ||
|
||||||
(Target is Character targetCharacter && targetCharacter.HasEquippedItem(scooterTag, allowBroken: false)) || squaredDistance > Math.Pow(closeEnough * 2, 2));
|
(targetCharacter != null && targetCharacter.HasEquippedItem(scooterTag, allowBroken: false)) || squaredDistance > Math.Pow(closeEnough * 2, 2));
|
||||||
if (HumanAIController.HasItem(character, scooterTag, out IEnumerable<Item> equippedScooters, recursive: false, requireEquipped: true))
|
if (HumanAIController.HasItem(character, scooterTag, out IEnumerable<Item> equippedScooters, recursive: false, requireEquipped: true))
|
||||||
{
|
{
|
||||||
// Currently equipped scooter
|
// Currently equipped scooter
|
||||||
@@ -528,17 +533,24 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Gap selectedGap = null;
|
Gap selectedGap = null;
|
||||||
float selectedDistance = -1;
|
float selectedDistance = -1;
|
||||||
|
Vector2 toTargetNormalized = Vector2.Normalize(Target.WorldPosition - character.WorldPosition);
|
||||||
foreach (Gap gap in Gap.GapList)
|
foreach (Gap gap in Gap.GapList)
|
||||||
{
|
{
|
||||||
if (gap.Open < 1) { continue; }
|
if (gap.Open < 1) { continue; }
|
||||||
if (gap.FlowTargetHull == null) { continue; }
|
if (gap.Submarine == null) { continue; }
|
||||||
if (gap.Submarine != Target.Submarine) { continue; }
|
if (!followControlledCharacter)
|
||||||
float distance = Vector2.DistanceSquared(character.WorldPosition, gap.WorldPosition);
|
{
|
||||||
if (distance > maxDistance * maxDistance) { continue; }
|
if (gap.FlowTargetHull == null) { continue; }
|
||||||
if (selectedGap == null || distance < selectedDistance)
|
if (gap.Submarine != Target.Submarine) { continue; }
|
||||||
|
}
|
||||||
|
Vector2 toGap = gap.WorldPosition - character.WorldPosition;
|
||||||
|
if (Vector2.Dot(Vector2.Normalize(toGap), toTargetNormalized) < 0) { continue; }
|
||||||
|
float squaredDistance = toGap.LengthSquared();
|
||||||
|
if (squaredDistance > maxDistance * maxDistance) { continue; }
|
||||||
|
if (selectedGap == null || squaredDistance < selectedDistance)
|
||||||
{
|
{
|
||||||
selectedGap = gap;
|
selectedGap = gap;
|
||||||
selectedDistance = distance;
|
selectedDistance = squaredDistance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TargetGap = selectedGap;
|
TargetGap = selectedGap;
|
||||||
@@ -555,7 +567,7 @@ namespace Barotrauma
|
|||||||
//otherwise characters can let go of the ladders too soon once they're close enough to the target
|
//otherwise characters can let go of the ladders too soon once they're close enough to the target
|
||||||
if (PathSteering.CurrentPath.NextNode != null) { return false; }
|
if (PathSteering.CurrentPath.NextNode != null) { return false; }
|
||||||
}
|
}
|
||||||
if (!character.AnimController.InWater)
|
if (!AlwaysUseEuclideanDistance && !character.AnimController.InWater)
|
||||||
{
|
{
|
||||||
float yDiff = Math.Abs(Target.WorldPosition.Y - character.WorldPosition.Y);
|
float yDiff = Math.Abs(Target.WorldPosition.Y - character.WorldPosition.Y);
|
||||||
if (yDiff > CloseEnough) { return false; }
|
if (yDiff > CloseEnough) { return false; }
|
||||||
|
|||||||
+13
-1
@@ -495,7 +495,7 @@ namespace Barotrauma
|
|||||||
foreach (Item item in Item.ItemList)
|
foreach (Item item in Item.ItemList)
|
||||||
{
|
{
|
||||||
if (item.CurrentHull != hull) { continue; }
|
if (item.CurrentHull != hull) { continue; }
|
||||||
if (AIObjectiveCleanupItems.IsValidTarget(item, character, checkInventory: true) && !ignoredItems.Contains(item))
|
if (AIObjectiveCleanupItems.IsValidTarget(item, character, checkInventory: true, allowUnloading: false) && !ignoredItems.Contains(item))
|
||||||
{
|
{
|
||||||
itemsToClean.Add(item);
|
itemsToClean.Add(item);
|
||||||
}
|
}
|
||||||
@@ -540,5 +540,17 @@ namespace Barotrauma
|
|||||||
ignoredItems.Clear();
|
ignoredItems.Clear();
|
||||||
autonomousObjectiveRetryTimer = 10;
|
autonomousObjectiveRetryTimer = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnDeselected()
|
||||||
|
{
|
||||||
|
base.OnDeselected();
|
||||||
|
foreach (var subObjective in SubObjectives)
|
||||||
|
{
|
||||||
|
if (subObjective is AIObjectiveCleanupItem cleanUpObjective)
|
||||||
|
{
|
||||||
|
cleanUpObjective.DropTarget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -445,7 +445,7 @@ namespace Barotrauma
|
|||||||
extraDistanceWhileSwimming = 100,
|
extraDistanceWhileSwimming = 100,
|
||||||
AllowGoingOutside = true,
|
AllowGoingOutside = true,
|
||||||
IgnoreIfTargetDead = true,
|
IgnoreIfTargetDead = true,
|
||||||
followControlledCharacter = orderGiver == character,
|
followControlledCharacter = true,
|
||||||
mimic = true,
|
mimic = true,
|
||||||
DialogueIdentifier = "dialogcannotreachplace"
|
DialogueIdentifier = "dialogcannotreachplace"
|
||||||
};
|
};
|
||||||
|
|||||||
+4
-6
@@ -69,10 +69,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (!isOrder)
|
if (!isOrder)
|
||||||
{
|
{
|
||||||
if (reactor.LastUserWasPlayer && character.TeamID != CharacterTeamType.FriendlyNPC ||
|
if (reactor.LastUserWasPlayer && character.TeamID != CharacterTeamType.FriendlyNPC)
|
||||||
HumanAIController.IsTrueForAnyCrewMember(c =>
|
|
||||||
c.ObjectiveManager.CurrentOrder is AIObjectiveOperateItem operateOrder && operateOrder.GetTarget() == target))
|
|
||||||
{
|
{
|
||||||
|
// The reactor was previously operated by a player -> ignore.
|
||||||
Priority = 0;
|
Priority = 0;
|
||||||
return Priority;
|
return Priority;
|
||||||
}
|
}
|
||||||
@@ -89,7 +88,6 @@ namespace Barotrauma
|
|||||||
case "powerup":
|
case "powerup":
|
||||||
// Check that we don't already have another order that is targeting the same item.
|
// Check that we don't already have another order that is targeting the same item.
|
||||||
// Without this the autonomous objective will tell the bot to turn the reactor on again.
|
// Without this the autonomous objective will tell the bot to turn the reactor on again.
|
||||||
|
|
||||||
if (IsAnotherOrderTargetingSameItem(objectiveManager.ForcedOrder) || objectiveManager.CurrentOrders.Any(o => IsAnotherOrderTargetingSameItem(o.Objective)))
|
if (IsAnotherOrderTargetingSameItem(objectiveManager.ForcedOrder) || objectiveManager.CurrentOrders.Any(o => IsAnotherOrderTargetingSameItem(o.Objective)))
|
||||||
{
|
{
|
||||||
Priority = 0;
|
Priority = 0;
|
||||||
@@ -177,9 +175,9 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
if (operateTarget != null)
|
if (operateTarget != null)
|
||||||
{
|
{
|
||||||
if (HumanAIController.IsTrueForAnyCrewMember(other => other != HumanAIController && other.ObjectiveManager.GetActiveObjective() is AIObjectiveOperateItem operateObjective && operateObjective.operateTarget == operateTarget))
|
if (HumanAIController.IsTrueForAnyCrewMember(other => other != HumanAIController && other.Character.IsBot && other.ObjectiveManager.GetActiveObjective() is AIObjectiveOperateItem operateObjective && operateObjective.operateTarget == operateTarget))
|
||||||
{
|
{
|
||||||
// Another crew member is already targeting this entity.
|
// Another crew member is already targeting this entity (leak).
|
||||||
Abandon = true;
|
Abandon = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -471,13 +471,15 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private double pressureProtectionLastSet;
|
||||||
private float pressureProtection;
|
private float pressureProtection;
|
||||||
public float PressureProtection
|
public float PressureProtection
|
||||||
{
|
{
|
||||||
get { return pressureProtection; }
|
get { return pressureProtection; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
pressureProtection = MathHelper.Clamp(value, 0.0f, 100.0f);
|
pressureProtection = Math.Max(value, 0.0f);
|
||||||
|
pressureProtectionLastSet = Timing.TotalTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -528,11 +530,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public float Stun
|
public float Stun
|
||||||
{
|
{
|
||||||
get { return IsRagdolled ? 1.0f : CharacterHealth.StunTimer; }
|
get { return IsRagdolled ? 1.0f : CharacterHealth.Stun; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) return;
|
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; }
|
||||||
|
|
||||||
SetStun(value, true);
|
SetStun(value, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -697,7 +698,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (!canBeDragged) { return false; }
|
if (!canBeDragged) { return false; }
|
||||||
if (Removed || !AnimController.Draggable) { return false; }
|
if (Removed || !AnimController.Draggable) { return false; }
|
||||||
return IsDead || Stun > 0.0f || LockHands || IsIncapacitated || IsPet;
|
return IsKnockedDown || LockHands || IsPet;
|
||||||
}
|
}
|
||||||
set { canBeDragged = value; }
|
set { canBeDragged = value; }
|
||||||
}
|
}
|
||||||
@@ -715,7 +716,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return IsDead || Stun > 0.0f || LockHands || IsIncapacitated;
|
return IsKnockedDown || LockHands;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set { canInventoryBeAccessed = value; }
|
set { canInventoryBeAccessed = value; }
|
||||||
@@ -1016,7 +1017,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
// Get the non husked name and find the ragdoll with it
|
// Get the non husked name and find the ragdoll with it
|
||||||
var matchingAffliction = AfflictionPrefab.List
|
var matchingAffliction = AfflictionPrefab.List
|
||||||
.Where(p => p.AfflictionType == "huskinfection")
|
.Where(p => p is AfflictionPrefabHusk)
|
||||||
.Select(p => p as AfflictionPrefabHusk)
|
.Select(p => p as AfflictionPrefabHusk)
|
||||||
.FirstOrDefault(p => p.TargetSpecies.Any(t => t.Equals(AfflictionHusk.GetNonHuskedSpeciesName(speciesName, p), StringComparison.OrdinalIgnoreCase)));
|
.FirstOrDefault(p => p.TargetSpecies.Any(t => t.Equals(AfflictionHusk.GetNonHuskedSpeciesName(speciesName, p), StringComparison.OrdinalIgnoreCase)));
|
||||||
string nonHuskedSpeciesName = string.Empty;
|
string nonHuskedSpeciesName = string.Empty;
|
||||||
@@ -1052,7 +1053,7 @@ namespace Barotrauma
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
AnimController = new FishAnimController(this, seed, ragdollParams as FishRagdollParams);
|
AnimController = new FishAnimController(this, seed, ragdollParams as FishRagdollParams);
|
||||||
PressureProtection = 100.0f;
|
PressureProtection = int.MaxValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimController.SetPosition(ConvertUnits.ToSimUnits(position));
|
AnimController.SetPosition(ConvertUnits.ToSimUnits(position));
|
||||||
@@ -1271,7 +1272,13 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public float GetSkillLevel(string skillIdentifier)
|
public float GetSkillLevel(string skillIdentifier)
|
||||||
{
|
{
|
||||||
return (Info == null || Info.Job == null) ? 0.0f : Info.Job.GetSkillLevel(skillIdentifier);
|
if (Info?.Job == null) { return 0.0f; }
|
||||||
|
float skillLevel = Info.Job.GetSkillLevel(skillIdentifier);
|
||||||
|
foreach (Affliction affliction in CharacterHealth.GetAllAfflictions())
|
||||||
|
{
|
||||||
|
skillLevel *= affliction.GetSkillMultiplier();
|
||||||
|
}
|
||||||
|
return skillLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: reposition? there's also the overrideTargetMovement variable, but it's not in the same manner
|
// TODO: reposition? there's also the overrideTargetMovement variable, but it's not in the same manner
|
||||||
@@ -2466,11 +2473,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (NeedsAir)
|
if (NeedsAir)
|
||||||
{
|
{
|
||||||
bool protectedFromPressure = PressureProtection > 0.0f;
|
|
||||||
//cannot be protected from pressure when below crush depth
|
|
||||||
protectedFromPressure = protectedFromPressure && WorldPosition.Y > CharacterHealth.CrushDepth;
|
|
||||||
//implode if not protected from pressure, and either outside or in a high-pressure hull
|
//implode if not protected from pressure, and either outside or in a high-pressure hull
|
||||||
if (!protectedFromPressure &&
|
if (!IsProtectedFromPressure() &&
|
||||||
(AnimController.CurrentHull == null || AnimController.CurrentHull.LethalPressure >= 80.0f))
|
(AnimController.CurrentHull == null || AnimController.CurrentHull.LethalPressure >= 80.0f))
|
||||||
{
|
{
|
||||||
if (CharacterHealth.PressureKillDelay <= 0.0f)
|
if (CharacterHealth.PressureKillDelay <= 0.0f)
|
||||||
@@ -2656,7 +2660,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (NeedsAir)
|
if (NeedsAir)
|
||||||
{
|
{
|
||||||
PressureProtection -= deltaTime * 100.0f;
|
if (Timing.TotalTime > pressureProtectionLastSet + 0.1)
|
||||||
|
{
|
||||||
|
PressureProtection = 0.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (NeedsWater)
|
if (NeedsWater)
|
||||||
{
|
{
|
||||||
@@ -3281,7 +3288,7 @@ namespace Barotrauma
|
|||||||
GameMain.Config.RecentlyEncounteredCreatures.Add(other.SpeciesName);
|
GameMain.Config.RecentlyEncounteredCreatures.Add(other.SpeciesName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AttackResult DamageLimb(Vector2 worldPosition, Limb hitLimb, IEnumerable<Affliction> afflictions, float stun, bool playSound, float attackImpulse, Character attacker = null, float damageMultiplier = 1)
|
public AttackResult DamageLimb(Vector2 worldPosition, Limb hitLimb, IEnumerable<Affliction> afflictions, float stun, bool playSound, float attackImpulse, Character attacker = null, float damageMultiplier = 1, bool allowStacking = true)
|
||||||
{
|
{
|
||||||
if (Removed) { return new AttackResult(); }
|
if (Removed) { return new AttackResult(); }
|
||||||
|
|
||||||
@@ -3327,7 +3334,7 @@ namespace Barotrauma
|
|||||||
bool wasDead = IsDead;
|
bool wasDead = IsDead;
|
||||||
Vector2 simPos = hitLimb.SimPosition + ConvertUnits.ToSimUnits(dir);
|
Vector2 simPos = hitLimb.SimPosition + ConvertUnits.ToSimUnits(dir);
|
||||||
AttackResult attackResult = hitLimb.AddDamage(simPos, afflictions, playSound, damageMultiplier: damageMultiplier);
|
AttackResult attackResult = hitLimb.AddDamage(simPos, afflictions, playSound, damageMultiplier: damageMultiplier);
|
||||||
CharacterHealth.ApplyDamage(hitLimb, attackResult);
|
CharacterHealth.ApplyDamage(hitLimb, attackResult, allowStacking);
|
||||||
if (attacker != this)
|
if (attacker != this)
|
||||||
{
|
{
|
||||||
OnAttacked?.Invoke(attacker, attackResult);
|
OnAttacked?.Invoke(attacker, attackResult);
|
||||||
@@ -3382,6 +3389,12 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is the character knocked down regardless whether the technical state is dead, unconcious, paralyzed, or stunned.
|
||||||
|
/// With stunning, the parameter uses a half a second delay before the character is treated as knocked down. The purpose of this is to ignore minor stunning. If you don't want to to ignore any stun, use the Stun property.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsKnockedDown => IsDead || IsIncapacitated || CharacterHealth.StunTimer > 0.5f;
|
||||||
|
|
||||||
public void SetStun(float newStun, bool allowStunDecrease = false, bool isNetworkMessage = false)
|
public void SetStun(float newStun, bool allowStunDecrease = false, bool isNetworkMessage = false)
|
||||||
{
|
{
|
||||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient && !isNetworkMessage) { return; }
|
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient && !isNetworkMessage) { return; }
|
||||||
@@ -3391,7 +3404,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
AnimController.ResetPullJoints();
|
AnimController.ResetPullJoints();
|
||||||
}
|
}
|
||||||
CharacterHealth.StunTimer = newStun;
|
CharacterHealth.Stun = newStun;
|
||||||
if (newStun > 0.0f)
|
if (newStun > 0.0f)
|
||||||
{
|
{
|
||||||
SelectedConstruction = null;
|
SelectedConstruction = null;
|
||||||
@@ -3964,5 +3977,10 @@ namespace Barotrauma
|
|||||||
public bool IsWatchman => HasJob("watchman");
|
public bool IsWatchman => HasJob("watchman");
|
||||||
|
|
||||||
public bool HasJob(string identifier) => Info?.Job?.Prefab.Identifier == identifier;
|
public bool HasJob(string identifier) => Info?.Job?.Prefab.Identifier == identifier;
|
||||||
|
|
||||||
|
public bool IsProtectedFromPressure()
|
||||||
|
{
|
||||||
|
return PressureProtection >= (Level.Loaded?.GetRealWorldDepth(WorldPosition.Y) ?? 0.0f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -961,6 +961,20 @@ namespace Barotrauma
|
|||||||
public void Rename(string newName)
|
public void Rename(string newName)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(newName)) { return; }
|
if (string.IsNullOrEmpty(newName)) { return; }
|
||||||
|
// Replace the name tag of any existing id cards or duffel bags
|
||||||
|
foreach (var item in Item.ItemList)
|
||||||
|
{
|
||||||
|
if (item.Prefab.Identifier != "idcard" && !item.Tags.Contains("despawncontainer")) { continue; }
|
||||||
|
foreach (var tag in item.Tags.Split(','))
|
||||||
|
{
|
||||||
|
var splitTag = tag.Split(":");
|
||||||
|
if (splitTag.Length < 2) { continue; }
|
||||||
|
if (splitTag[0] != "name") { continue; }
|
||||||
|
if (splitTag[1] != Name) { continue; }
|
||||||
|
item.ReplaceTag(tag, $"name:{newName}");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
Name = newName;
|
Name = newName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+60
-15
@@ -14,6 +14,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public Dictionary<string, SerializableProperty> SerializableProperties { get; set; }
|
public Dictionary<string, SerializableProperty> SerializableProperties { get; set; }
|
||||||
|
|
||||||
|
public float PendingAdditionStrenght { get; set; }
|
||||||
|
public float AdditionStrength { get; set; }
|
||||||
|
|
||||||
protected float _strength;
|
protected float _strength;
|
||||||
|
|
||||||
[Serialize(0f, true), Editable]
|
[Serialize(0f, true), Editable]
|
||||||
@@ -26,7 +29,12 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
_nonClampedStrength = value;
|
_nonClampedStrength = value;
|
||||||
}
|
}
|
||||||
_strength = MathHelper.Clamp(value, 0.0f, Prefab.MaxStrength);
|
float newValue = MathHelper.Clamp(value, 0.0f, Prefab.MaxStrength);
|
||||||
|
if (newValue > _strength)
|
||||||
|
{
|
||||||
|
PendingAdditionStrenght = Prefab.GrainBurst;
|
||||||
|
}
|
||||||
|
_strength = newValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,6 +64,7 @@ namespace Barotrauma
|
|||||||
public Affliction(AfflictionPrefab prefab, float strength)
|
public Affliction(AfflictionPrefab prefab, float strength)
|
||||||
{
|
{
|
||||||
Prefab = prefab;
|
Prefab = prefab;
|
||||||
|
PendingAdditionStrenght = Prefab.GrainBurst;
|
||||||
_strength = strength;
|
_strength = strength;
|
||||||
Identifier = prefab?.Identifier;
|
Identifier = prefab?.Identifier;
|
||||||
|
|
||||||
@@ -109,18 +118,25 @@ namespace Barotrauma
|
|||||||
if (currentEffect == null) { return 0.0f; }
|
if (currentEffect == null) { return 0.0f; }
|
||||||
if (MathUtils.NearlyEqual(currentEffect.MaxGrainStrength, 0f)) { return 0.0f; }
|
if (MathUtils.NearlyEqual(currentEffect.MaxGrainStrength, 0f)) { return 0.0f; }
|
||||||
|
|
||||||
return MathHelper.Lerp(
|
float amount = MathHelper.Lerp(
|
||||||
currentEffect.MinGrainStrength,
|
currentEffect.MinGrainStrength,
|
||||||
currentEffect.MaxGrainStrength,
|
currentEffect.MaxGrainStrength,
|
||||||
(Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength));
|
(Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength));
|
||||||
|
|
||||||
|
if (Prefab.GrainBurst > 0 && AdditionStrength > amount)
|
||||||
|
{
|
||||||
|
return AdditionStrength;
|
||||||
|
}
|
||||||
|
|
||||||
|
return amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float GetScreenDistortStrength()
|
public float GetScreenDistortStrength()
|
||||||
{
|
{
|
||||||
if (Strength < Prefab.ActivationThreshold) return 0.0f;
|
if (Strength < Prefab.ActivationThreshold) { return 0.0f; }
|
||||||
AfflictionPrefab.Effect currentEffect = Prefab.GetActiveEffect(Strength);
|
AfflictionPrefab.Effect currentEffect = Prefab.GetActiveEffect(Strength);
|
||||||
if (currentEffect == null) return 0.0f;
|
if (currentEffect == null) { return 0.0f; }
|
||||||
if (currentEffect.MaxScreenDistortStrength - currentEffect.MinScreenDistortStrength <= 0.0f) return 0.0f;
|
if (currentEffect.MaxScreenDistortStrength - currentEffect.MinScreenDistortStrength < 0.0f) { return 0.0f; }
|
||||||
|
|
||||||
return MathHelper.Lerp(
|
return MathHelper.Lerp(
|
||||||
currentEffect.MinScreenDistortStrength,
|
currentEffect.MinScreenDistortStrength,
|
||||||
@@ -130,10 +146,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public float GetRadialDistortStrength()
|
public float GetRadialDistortStrength()
|
||||||
{
|
{
|
||||||
if (Strength < Prefab.ActivationThreshold) return 0.0f;
|
if (Strength < Prefab.ActivationThreshold) { return 0.0f; }
|
||||||
AfflictionPrefab.Effect currentEffect = Prefab.GetActiveEffect(Strength);
|
AfflictionPrefab.Effect currentEffect = Prefab.GetActiveEffect(Strength);
|
||||||
if (currentEffect == null) return 0.0f;
|
if (currentEffect == null) { return 0.0f; }
|
||||||
if (currentEffect.MaxRadialDistortStrength - currentEffect.MinRadialDistortStrength <= 0.0f) return 0.0f;
|
if (currentEffect.MaxRadialDistortStrength - currentEffect.MinRadialDistortStrength < 0.0f) { return 0.0f; }
|
||||||
|
|
||||||
return MathHelper.Lerp(
|
return MathHelper.Lerp(
|
||||||
currentEffect.MinRadialDistortStrength,
|
currentEffect.MinRadialDistortStrength,
|
||||||
@@ -143,10 +159,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public float GetChromaticAberrationStrength()
|
public float GetChromaticAberrationStrength()
|
||||||
{
|
{
|
||||||
if (Strength < Prefab.ActivationThreshold) return 0.0f;
|
if (Strength < Prefab.ActivationThreshold) { return 0.0f; }
|
||||||
AfflictionPrefab.Effect currentEffect = Prefab.GetActiveEffect(Strength);
|
AfflictionPrefab.Effect currentEffect = Prefab.GetActiveEffect(Strength);
|
||||||
if (currentEffect == null) return 0.0f;
|
if (currentEffect == null) { return 0.0f; }
|
||||||
if (currentEffect.MaxChromaticAberrationStrength - currentEffect.MinChromaticAberrationStrength <= 0.0f) return 0.0f;
|
if (currentEffect.MaxChromaticAberrationStrength - currentEffect.MinChromaticAberrationStrength < 0.0f) { return 0.0f; }
|
||||||
|
|
||||||
return MathHelper.Lerp(
|
return MathHelper.Lerp(
|
||||||
currentEffect.MinChromaticAberrationStrength,
|
currentEffect.MinChromaticAberrationStrength,
|
||||||
@@ -156,10 +172,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public float GetScreenBlurStrength()
|
public float GetScreenBlurStrength()
|
||||||
{
|
{
|
||||||
if (Strength < Prefab.ActivationThreshold) return 0.0f;
|
if (Strength < Prefab.ActivationThreshold) { return 0.0f; }
|
||||||
AfflictionPrefab.Effect currentEffect = Prefab.GetActiveEffect(Strength);
|
AfflictionPrefab.Effect currentEffect = Prefab.GetActiveEffect(Strength);
|
||||||
if (currentEffect == null) return 0.0f;
|
if (currentEffect == null) { return 0.0f; }
|
||||||
if (currentEffect.MaxScreenBlurStrength - currentEffect.MinScreenBlurStrength <= 0.0f) return 0.0f;
|
if (currentEffect.MaxScreenBlurStrength - currentEffect.MinScreenBlurStrength < 0.0f) { return 0.0f; }
|
||||||
|
|
||||||
return MathHelper.Lerp(
|
return MathHelper.Lerp(
|
||||||
currentEffect.MinScreenBlurStrength,
|
currentEffect.MinScreenBlurStrength,
|
||||||
@@ -167,6 +183,20 @@ namespace Barotrauma
|
|||||||
(Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength));
|
(Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float GetSkillMultiplier()
|
||||||
|
{
|
||||||
|
if (Strength < Prefab.ActivationThreshold) { return 1.0f; }
|
||||||
|
AfflictionPrefab.Effect currentEffect = Prefab.GetActiveEffect(Strength);
|
||||||
|
if (currentEffect == null) { return 1.0f; }
|
||||||
|
|
||||||
|
float amount = MathHelper.Lerp(
|
||||||
|
currentEffect.MinSkillMultiplier,
|
||||||
|
currentEffect.MaxSkillMultiplier,
|
||||||
|
(Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength));
|
||||||
|
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
public void CalculateDamagePerSecond(float currentVitalityDecrease)
|
public void CalculateDamagePerSecond(float currentVitalityDecrease)
|
||||||
{
|
{
|
||||||
DamagePerSecond = Math.Max(DamagePerSecond, currentVitalityDecrease - PreviousVitalityDecrease);
|
DamagePerSecond = Math.Max(DamagePerSecond, currentVitalityDecrease - PreviousVitalityDecrease);
|
||||||
@@ -245,6 +275,21 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
ApplyStatusEffect(statusEffect, deltaTime, characterHealth, targetLimb);
|
ApplyStatusEffect(statusEffect, deltaTime, characterHealth, targetLimb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float amount = deltaTime;
|
||||||
|
if (Prefab.GrainBurst > 0)
|
||||||
|
{
|
||||||
|
amount /= Prefab.GrainBurst;
|
||||||
|
}
|
||||||
|
if (PendingAdditionStrenght >= 0)
|
||||||
|
{
|
||||||
|
AdditionStrength += amount;
|
||||||
|
PendingAdditionStrenght -= deltaTime;
|
||||||
|
}
|
||||||
|
else if (AdditionStrength > 0)
|
||||||
|
{
|
||||||
|
AdditionStrength -= amount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ApplyStatusEffect(StatusEffect statusEffect, float deltaTime, CharacterHealth characterHealth, Limb targetLimb)
|
public void ApplyStatusEffect(StatusEffect statusEffect, float deltaTime, CharacterHealth characterHealth, Limb targetLimb)
|
||||||
@@ -267,7 +312,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
var targets = new List<ISerializableEntity>();
|
var targets = new List<ISerializableEntity>();
|
||||||
statusEffect.GetNearbyTargets(characterHealth.Character.WorldPosition, targets);
|
statusEffect.GetNearbyTargets(characterHealth.Character.WorldPosition, targets);
|
||||||
statusEffect.Apply(ActionType.OnActive, deltaTime, targetLimb.character, targets);
|
statusEffect.Apply(ActionType.OnActive, deltaTime, characterHealth.Character, targets);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-1
@@ -134,6 +134,8 @@ namespace Barotrauma
|
|||||||
public float MinSpeedMultiplier, MaxSpeedMultiplier;
|
public float MinSpeedMultiplier, MaxSpeedMultiplier;
|
||||||
public float MinBuffMultiplier, MaxBuffMultiplier;
|
public float MinBuffMultiplier, MaxBuffMultiplier;
|
||||||
|
|
||||||
|
public float MinSkillMultiplier, MaxSkillMultiplier;
|
||||||
|
|
||||||
public float MinResistance, MaxResistance;
|
public float MinResistance, MaxResistance;
|
||||||
public string ResistanceFor;
|
public string ResistanceFor;
|
||||||
public string DialogFlag;
|
public string DialogFlag;
|
||||||
@@ -172,6 +174,9 @@ namespace Barotrauma
|
|||||||
MaxScreenBlurStrength = element.GetAttributeFloat("maxscreenblur", 0.0f);
|
MaxScreenBlurStrength = element.GetAttributeFloat("maxscreenblur", 0.0f);
|
||||||
MaxScreenBlurStrength = Math.Max(MinScreenBlurStrength, MaxScreenBlurStrength);
|
MaxScreenBlurStrength = Math.Max(MinScreenBlurStrength, MaxScreenBlurStrength);
|
||||||
|
|
||||||
|
MinSkillMultiplier = element.GetAttributeFloat("minskillmultiplier", 1.0f);
|
||||||
|
MaxSkillMultiplier = element.GetAttributeFloat("maxskillmultiplier", 1.0f);
|
||||||
|
|
||||||
ResistanceFor = element.GetAttributeString("resistancefor", "");
|
ResistanceFor = element.GetAttributeString("resistancefor", "");
|
||||||
MinResistance = element.GetAttributeFloat("minresistance", 0.0f);
|
MinResistance = element.GetAttributeFloat("minresistance", 0.0f);
|
||||||
MaxResistance = element.GetAttributeFloat("maxresistance", 0.0f);
|
MaxResistance = element.GetAttributeFloat("maxresistance", 0.0f);
|
||||||
@@ -292,6 +297,8 @@ namespace Barotrauma
|
|||||||
public readonly float ShowIconToOthersThreshold = 0.05f;
|
public readonly float ShowIconToOthersThreshold = 0.05f;
|
||||||
public readonly float MaxStrength = 100.0f;
|
public readonly float MaxStrength = 100.0f;
|
||||||
|
|
||||||
|
public readonly float GrainBurst;
|
||||||
|
|
||||||
//how high the strength has to be for the affliction icon to be shown with a health scanner
|
//how high the strength has to be for the affliction icon to be shown with a health scanner
|
||||||
public readonly float ShowInHealthScannerThreshold = 0.05f;
|
public readonly float ShowInHealthScannerThreshold = 0.05f;
|
||||||
|
|
||||||
@@ -451,6 +458,7 @@ namespace Barotrauma
|
|||||||
prefab = new AfflictionPrefab(sourceElement, file.Path, typeof(AfflictionBleeding));
|
prefab = new AfflictionPrefab(sourceElement, file.Path, typeof(AfflictionBleeding));
|
||||||
break;
|
break;
|
||||||
case "huskinfection":
|
case "huskinfection":
|
||||||
|
case "alieninfection":
|
||||||
prefab = new AfflictionPrefabHusk(sourceElement, file.Path, typeof(AfflictionHusk));
|
prefab = new AfflictionPrefabHusk(sourceElement, file.Path, typeof(AfflictionHusk));
|
||||||
break;
|
break;
|
||||||
case "cprsettings":
|
case "cprsettings":
|
||||||
@@ -521,7 +529,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (prefab != null)
|
if (prefab != null)
|
||||||
{
|
{
|
||||||
loadedAfflictions.Add((prefab, element));
|
loadedAfflictions.Add((prefab, sourceElement));
|
||||||
Prefabs.Add(prefab, isOverride);
|
Prefabs.Add(prefab, isOverride);
|
||||||
prefab.CalculatePrefabUIntIdentifier(Prefabs);
|
prefab.CalculatePrefabUIntIdentifier(Prefabs);
|
||||||
}
|
}
|
||||||
@@ -582,6 +590,7 @@ namespace Barotrauma
|
|||||||
ShowIconThreshold = element.GetAttributeFloat("showiconthreshold", Math.Max(ActivationThreshold, 0.05f));
|
ShowIconThreshold = element.GetAttributeFloat("showiconthreshold", Math.Max(ActivationThreshold, 0.05f));
|
||||||
ShowIconToOthersThreshold = element.GetAttributeFloat("showicontoothersthreshold", ShowIconThreshold);
|
ShowIconToOthersThreshold = element.GetAttributeFloat("showicontoothersthreshold", ShowIconThreshold);
|
||||||
MaxStrength = element.GetAttributeFloat("maxstrength", 100.0f);
|
MaxStrength = element.GetAttributeFloat("maxstrength", 100.0f);
|
||||||
|
GrainBurst = element.GetAttributeFloat(nameof(GrainBurst).ToLower(), 0.0f);
|
||||||
|
|
||||||
ShowInHealthScannerThreshold = element.GetAttributeFloat("showinhealthscannerthreshold", Math.Max(ActivationThreshold, 0.05f));
|
ShowInHealthScannerThreshold = element.GetAttributeFloat("showinhealthscannerthreshold", Math.Max(ActivationThreshold, 0.05f));
|
||||||
TreatmentThreshold = element.GetAttributeFloat("treatmentthreshold", Math.Max(ActivationThreshold, 5.0f));
|
TreatmentThreshold = element.GetAttributeFloat("treatmentthreshold", Math.Max(ActivationThreshold, 5.0f));
|
||||||
|
|||||||
@@ -190,12 +190,14 @@ namespace Barotrauma
|
|||||||
set { bloodlossAffliction.Strength = MathHelper.Clamp(value, 0.0f, 100.0f); }
|
set { bloodlossAffliction.Strength = MathHelper.Clamp(value, 0.0f, 100.0f); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public float StunTimer
|
public float Stun
|
||||||
{
|
{
|
||||||
get { return stunAffliction.Strength; }
|
get { return stunAffliction.Strength; }
|
||||||
set { stunAffliction.Strength = MathHelper.Clamp(value, 0.0f, stunAffliction.Prefab.MaxStrength); }
|
set { stunAffliction.Strength = MathHelper.Clamp(value, 0.0f, stunAffliction.Prefab.MaxStrength); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float StunTimer { get; private set; }
|
||||||
|
|
||||||
public Affliction PressureAffliction
|
public Affliction PressureAffliction
|
||||||
{
|
{
|
||||||
get { return pressureAffliction; }
|
get { return pressureAffliction; }
|
||||||
@@ -488,7 +490,7 @@ namespace Barotrauma
|
|||||||
CalculateVitality();
|
CalculateVitality();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ApplyDamage(Limb hitLimb, AttackResult attackResult)
|
public void ApplyDamage(Limb hitLimb, AttackResult attackResult, bool allowStacking = true)
|
||||||
{
|
{
|
||||||
if (Unkillable || Character.GodMode) { return; }
|
if (Unkillable || Character.GodMode) { return; }
|
||||||
if (hitLimb.HealthIndex < 0 || hitLimb.HealthIndex >= limbHealths.Count)
|
if (hitLimb.HealthIndex < 0 || hitLimb.HealthIndex >= limbHealths.Count)
|
||||||
@@ -502,11 +504,11 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (newAffliction.Prefab.LimbSpecific)
|
if (newAffliction.Prefab.LimbSpecific)
|
||||||
{
|
{
|
||||||
AddLimbAffliction(hitLimb, newAffliction);
|
AddLimbAffliction(hitLimb, newAffliction, allowStacking);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AddAffliction(newAffliction);
|
AddAffliction(newAffliction, allowStacking);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -573,7 +575,7 @@ namespace Barotrauma
|
|||||||
CalculateVitality();
|
CalculateVitality();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddLimbAffliction(Limb limb, Affliction newAffliction)
|
private void AddLimbAffliction(Limb limb, Affliction newAffliction, bool allowStacking = true)
|
||||||
{
|
{
|
||||||
if (!newAffliction.Prefab.LimbSpecific || limb == null) { return; }
|
if (!newAffliction.Prefab.LimbSpecific || limb == null) { return; }
|
||||||
if (limb.HealthIndex < 0 || limb.HealthIndex >= limbHealths.Count)
|
if (limb.HealthIndex < 0 || limb.HealthIndex >= limbHealths.Count)
|
||||||
@@ -582,10 +584,10 @@ namespace Barotrauma
|
|||||||
"\" only has health configured for" + limbHealths.Count + " limbs but the limb " + limb.type + " is targeting index " + limb.HealthIndex);
|
"\" only has health configured for" + limbHealths.Count + " limbs but the limb " + limb.type + " is targeting index " + limb.HealthIndex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AddLimbAffliction(limbHealths[limb.HealthIndex], newAffliction);
|
AddLimbAffliction(limbHealths[limb.HealthIndex], newAffliction, allowStacking);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddLimbAffliction(LimbHealth limbHealth, Affliction newAffliction)
|
private void AddLimbAffliction(LimbHealth limbHealth, Affliction newAffliction, bool allowStacking = true)
|
||||||
{
|
{
|
||||||
if (!DoesBleed && newAffliction is AfflictionBleeding) { return; }
|
if (!DoesBleed && newAffliction is AfflictionBleeding) { return; }
|
||||||
if (!Character.NeedsOxygen && newAffliction.Prefab == AfflictionPrefab.OxygenLow) { return; }
|
if (!Character.NeedsOxygen && newAffliction.Prefab == AfflictionPrefab.OxygenLow) { return; }
|
||||||
@@ -594,7 +596,15 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (newAffliction.Prefab == affliction.Prefab)
|
if (newAffliction.Prefab == affliction.Prefab)
|
||||||
{
|
{
|
||||||
affliction.Strength = Math.Min(affliction.Prefab.MaxStrength, affliction.Strength + (newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(affliction.Prefab.Identifier))));
|
float newStrength = newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(affliction.Prefab.Identifier));
|
||||||
|
if (allowStacking)
|
||||||
|
{
|
||||||
|
// Add the existing strength
|
||||||
|
newStrength += affliction.Strength;
|
||||||
|
}
|
||||||
|
newStrength = Math.Min(affliction.Prefab.MaxStrength, newStrength);
|
||||||
|
if (affliction == stunAffliction) { Character.SetStun(newStrength, true, true); }
|
||||||
|
affliction.Strength = newStrength;
|
||||||
affliction.Source = newAffliction.Source;
|
affliction.Source = newAffliction.Source;
|
||||||
CalculateVitality();
|
CalculateVitality();
|
||||||
if (Vitality <= MinVitality)
|
if (Vitality <= MinVitality)
|
||||||
@@ -624,13 +634,12 @@ namespace Barotrauma
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddAffliction(Affliction newAffliction)
|
private void AddAffliction(Affliction newAffliction, bool allowStacking = true)
|
||||||
{
|
{
|
||||||
if (!DoesBleed && newAffliction is AfflictionBleeding) { return; }
|
if (!DoesBleed && newAffliction is AfflictionBleeding) { return; }
|
||||||
if (!Character.NeedsOxygen && newAffliction.Prefab == AfflictionPrefab.OxygenLow) { return; }
|
if (!Character.NeedsOxygen && newAffliction.Prefab == AfflictionPrefab.OxygenLow) { return; }
|
||||||
if (newAffliction.Prefab.AfflictionType == "huskinfection")
|
if (newAffliction.Prefab is AfflictionPrefabHusk huskPrefab)
|
||||||
{
|
{
|
||||||
var huskPrefab = newAffliction.Prefab as AfflictionPrefabHusk;
|
|
||||||
if (huskPrefab.TargetSpecies.None(s => s.Equals(Character.SpeciesName, StringComparison.OrdinalIgnoreCase)))
|
if (huskPrefab.TargetSpecies.None(s => s.Equals(Character.SpeciesName, StringComparison.OrdinalIgnoreCase)))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -640,7 +649,13 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (newAffliction.Prefab == affliction.Prefab)
|
if (newAffliction.Prefab == affliction.Prefab)
|
||||||
{
|
{
|
||||||
float newStrength = Math.Min(affliction.Prefab.MaxStrength, affliction.Strength + (newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(affliction.Prefab.Identifier))));
|
float newStrength = newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(affliction.Prefab.Identifier));
|
||||||
|
if (allowStacking)
|
||||||
|
{
|
||||||
|
// Add the existing strength
|
||||||
|
newStrength += affliction.Strength;
|
||||||
|
}
|
||||||
|
newStrength = Math.Min(affliction.Prefab.MaxStrength, newStrength);
|
||||||
if (affliction == stunAffliction) { Character.SetStun(newStrength, true, true); }
|
if (affliction == stunAffliction) { Character.SetStun(newStrength, true, true); }
|
||||||
affliction.Strength = newStrength;
|
affliction.Strength = newStrength;
|
||||||
affliction.Source = newAffliction.Source;
|
affliction.Source = newAffliction.Source;
|
||||||
@@ -676,6 +691,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
UpdateOxygen(deltaTime);
|
UpdateOxygen(deltaTime);
|
||||||
|
|
||||||
|
StunTimer = Stun > 0 ? StunTimer + deltaTime : 0;
|
||||||
|
|
||||||
for (int i = 0; i < limbHealths.Count; i++)
|
for (int i = 0; i < limbHealths.Count; i++)
|
||||||
{
|
{
|
||||||
for (int j = limbHealths[i].Afflictions.Count - 1; j >= 0; j--)
|
for (int j = limbHealths[i].Afflictions.Count - 1; j >= 0; j--)
|
||||||
@@ -795,6 +812,13 @@ namespace Barotrauma
|
|||||||
Vitality -= vitalityDecrease;
|
Vitality -= vitalityDecrease;
|
||||||
affliction.CalculateDamagePerSecond(vitalityDecrease);
|
affliction.CalculateDamagePerSecond(vitalityDecrease);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CLIENT
|
||||||
|
if (IsUnconscious)
|
||||||
|
{
|
||||||
|
HintManager.OnCharacterUnconscious(Character);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Kill()
|
private void Kill()
|
||||||
|
|||||||
@@ -79,6 +79,9 @@ namespace Barotrauma
|
|||||||
[Serialize(0f, true), Editable]
|
[Serialize(0f, true), Editable]
|
||||||
public float SonarDisruption { get; set; }
|
public float SonarDisruption { get; set; }
|
||||||
|
|
||||||
|
[Serialize(0f, true), Editable]
|
||||||
|
public float DistantSonarRange { get; set; }
|
||||||
|
|
||||||
[Serialize(25000f, true, "If the character is farther than this (in pixels) from the sub and the players, it will be disabled. The halved value is used for triggering simple physics where the ragdoll is disabled and only the main collider is updated."), Editable(MinValueFloat = 10000f, MaxValueFloat = 100000f)]
|
[Serialize(25000f, true, "If the character is farther than this (in pixels) from the sub and the players, it will be disabled. The halved value is used for triggering simple physics where the ragdoll is disabled and only the main collider is updated."), Editable(MinValueFloat = 10000f, MaxValueFloat = 100000f)]
|
||||||
public float DisableDistance { get; set; }
|
public float DisableDistance { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -609,7 +609,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
commands.Add(new Command("giveaffliction", "giveaffliction [affliction name] [affliction strength] [character name]: Add an affliction to a character. If the name parameter is omitted, the affliction is added to the controlled character.", (string[] args) =>
|
commands.Add(new Command("giveaffliction", "giveaffliction [affliction name] [affliction strength] [character name]: Add an affliction to a character. If the name parameter is omitted, the affliction is added to the controlled character.", (string[] args) =>
|
||||||
{
|
{
|
||||||
if (args.Length < 2) return;
|
if (args.Length < 2) { return; }
|
||||||
|
|
||||||
AfflictionPrefab afflictionPrefab = AfflictionPrefab.List.FirstOrDefault(a =>
|
AfflictionPrefab afflictionPrefab = AfflictionPrefab.List.FirstOrDefault(a =>
|
||||||
a.Name.Equals(args[0], StringComparison.OrdinalIgnoreCase) ||
|
a.Name.Equals(args[0], StringComparison.OrdinalIgnoreCase) ||
|
||||||
@@ -626,9 +626,19 @@ namespace Barotrauma
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Character targetCharacter = (args.Length <= 2) ? Character.Controlled : FindMatchingCharacter(args.Skip(2).ToArray());
|
bool relativeStrength = false;
|
||||||
|
if (args.Length > 2)
|
||||||
|
{
|
||||||
|
bool.TryParse(args[2], out relativeStrength);
|
||||||
|
}
|
||||||
|
|
||||||
|
Character targetCharacter = (relativeStrength || args.Length <= 2) ? Character.Controlled : FindMatchingCharacter(args.Skip(2).ToArray());
|
||||||
if (targetCharacter != null)
|
if (targetCharacter != null)
|
||||||
{
|
{
|
||||||
|
if (relativeStrength)
|
||||||
|
{
|
||||||
|
afflictionStrength *= targetCharacter.MaxVitality / afflictionPrefab.MaxStrength;
|
||||||
|
}
|
||||||
targetCharacter.CharacterHealth.ApplyAffliction(targetCharacter.AnimController.MainLimb, afflictionPrefab.Instantiate(afflictionStrength));
|
targetCharacter.CharacterHealth.ApplyAffliction(targetCharacter.AnimController.MainLimb, afflictionPrefab.Instantiate(afflictionStrength));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -734,19 +744,19 @@ namespace Barotrauma
|
|||||||
List<EventPrefab> eventPrefabs = EventSet.GetAllEventPrefabs().Where(prefab => !string.IsNullOrWhiteSpace(prefab.Identifier)).ToList();
|
List<EventPrefab> eventPrefabs = EventSet.GetAllEventPrefabs().Where(prefab => !string.IsNullOrWhiteSpace(prefab.Identifier)).ToList();
|
||||||
if (GameMain.GameSession?.EventManager != null && args.Length > 0)
|
if (GameMain.GameSession?.EventManager != null && args.Length > 0)
|
||||||
{
|
{
|
||||||
EventPrefab newEvent = eventPrefabs.Find(prefab => string.Equals(prefab.Identifier, args[0], StringComparison.InvariantCultureIgnoreCase));
|
EventPrefab eventPrefab = eventPrefabs.Find(prefab => string.Equals(prefab.Identifier, args[0], StringComparison.InvariantCultureIgnoreCase));
|
||||||
|
|
||||||
if (newEvent != null)
|
if (eventPrefab != null)
|
||||||
{
|
{
|
||||||
var @event = newEvent.CreateInstance();
|
var newEvent = eventPrefab.CreateInstance();
|
||||||
if (newEvent == null)
|
if (newEvent == null)
|
||||||
{
|
{
|
||||||
NewMessage($"Could not initialize event {args[0]} because level did not meet requirements");
|
NewMessage($"Could not initialize event {args[0]} because level did not meet requirements");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
GameMain.GameSession.EventManager.ActiveEvents.Add(@event);
|
GameMain.GameSession.EventManager.ActiveEvents.Add(newEvent);
|
||||||
@event.Init(true);
|
newEvent.Init(true);
|
||||||
NewMessage($"Initialized event {newEvent.Identifier}", Color.Aqua);
|
NewMessage($"Initialized event {eventPrefab.Identifier}", Color.Aqua);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1002,7 +1012,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThrowError("Could not set location reputation ({args[0]} is not a valid reputation value).");
|
ThrowError($"Could not set location reputation ({args[0]} is not a valid reputation value).");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1011,6 +1021,41 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}, null, true));
|
}, null, true));
|
||||||
|
|
||||||
|
commands.Add(new Command("setreputation", "setreputation [faction] [value]: Set the reputation of a cation to the specified value.", (string[] args) =>
|
||||||
|
{
|
||||||
|
if (args.Length < 2)
|
||||||
|
{
|
||||||
|
ThrowError("Insufficient arguments (expected 2)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GameMain.GameSession?.GameMode is CampaignMode campaign)
|
||||||
|
{
|
||||||
|
if (campaign.Factions.FirstOrDefault(f => f.Prefab.Identifier.Equals(args[0], StringComparison.OrdinalIgnoreCase)) is { } faction)
|
||||||
|
{
|
||||||
|
if (float.TryParse(args[1], NumberStyles.Any, CultureInfo.InvariantCulture, out float reputation))
|
||||||
|
{
|
||||||
|
faction.Reputation.Value = reputation;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ThrowError($"Could not set faction reputation ({args[1]} is not a valid reputation value).");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ThrowError($"Could not set faction reputation (faction {args[0]} not found).");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ThrowError("Could not set faction reputation (no active campaign).");
|
||||||
|
}
|
||||||
|
}, () =>
|
||||||
|
{
|
||||||
|
return new[] { FactionPrefab.Prefabs.Select(f => f.Identifier).ToArray() };
|
||||||
|
}, true));
|
||||||
|
|
||||||
commands.Add(new Command("fixitems", "fixitems: Repairs all items and restores them to full condition.", (string[] args) =>
|
commands.Add(new Command("fixitems", "fixitems: Repairs all items and restores them to full condition.", (string[] args) =>
|
||||||
{
|
{
|
||||||
foreach (Item it in Item.ItemList)
|
foreach (Item it in Item.ItemList)
|
||||||
@@ -1134,6 +1179,56 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
}, true));
|
}, true));
|
||||||
|
|
||||||
|
commands.Add(new Command("maxupgrades", "maxupgrades [category] [prefab]: Maxes out all upgrades or only specific one if given arguments.", args =>
|
||||||
|
{
|
||||||
|
UpgradeManager upgradeManager = GameMain.GameSession?.Campaign?.UpgradeManager;
|
||||||
|
if (upgradeManager == null)
|
||||||
|
{
|
||||||
|
ThrowError("This command can only be used in campaign.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string categoryIdentifier = null;
|
||||||
|
string prefabIdentifier = null;
|
||||||
|
|
||||||
|
switch (args.Length)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
categoryIdentifier = args[0];
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
categoryIdentifier = args[0];
|
||||||
|
prefabIdentifier = args[1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (UpgradeCategory category in UpgradeCategory.Categories)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(categoryIdentifier) && !category.Identifier.Equals(categoryIdentifier, StringComparison.OrdinalIgnoreCase)) { continue; }
|
||||||
|
foreach (UpgradePrefab prefab in UpgradePrefab.Prefabs)
|
||||||
|
{
|
||||||
|
if (!prefab.UpgradeCategories.Contains(category)) { continue; }
|
||||||
|
if (!string.IsNullOrWhiteSpace(prefabIdentifier) && !prefab.Identifier.Equals(prefabIdentifier, StringComparison.OrdinalIgnoreCase)) { continue; }
|
||||||
|
|
||||||
|
int targetLevel = prefab.MaxLevel - upgradeManager.GetRealUpgradeLevel(prefab, category);
|
||||||
|
for (int i = 0; i < targetLevel; i++)
|
||||||
|
{
|
||||||
|
upgradeManager.PurchaseUpgrade(prefab, category, force: true);
|
||||||
|
}
|
||||||
|
NewMessage($"Upgraded {category.Identifier}.{prefab.Identifier} by {targetLevel} levels.", Color.DarkGreen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NewMessage($"Start a new round to apply the upgrades.", Color.Lime);
|
||||||
|
}, () =>
|
||||||
|
{
|
||||||
|
return new[]
|
||||||
|
{
|
||||||
|
UpgradeCategory.Categories.Select(c => c.Identifier).Distinct().ToArray(),
|
||||||
|
UpgradePrefab.Prefabs.Select(c => c.Identifier).Distinct().ToArray()
|
||||||
|
};
|
||||||
|
}, true));
|
||||||
|
|
||||||
commands.Add(new Command("power", "power: Immediately powers up the submarine's nuclear reactor.", (string[] args) =>
|
commands.Add(new Command("power", "power: Immediately powers up the submarine's nuclear reactor.", (string[] args) =>
|
||||||
{
|
{
|
||||||
Item reactorItem = Item.ItemList.Find(i => i.GetComponent<Reactor>() != null);
|
Item reactorItem = Item.ItemList.Find(i => i.GetComponent<Reactor>() != null);
|
||||||
|
|||||||
@@ -253,8 +253,8 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
|
|
||||||
potentialSpawnPoints = potentialSpawnPoints.FindAll(wp => wp.ConnectedDoor == null && wp.Ladders == null && !wp.isObstructed);
|
potentialSpawnPoints = potentialSpawnPoints.FindAll(wp => wp.ConnectedDoor == null && wp.Ladders == null && !wp.isObstructed);
|
||||||
var airlockSpawnPoints = potentialSpawnPoints.Where(wp => wp.CurrentHull?.OutpostModuleTags?.Contains("airlock") ?? false).ToList();
|
|
||||||
|
|
||||||
|
var airlockSpawnPoints = potentialSpawnPoints.Where(wp => wp.CurrentHull?.OutpostModuleTags?.Contains("airlock") ?? false).ToList();
|
||||||
if (moduleFlags != null && moduleFlags.Any())
|
if (moduleFlags != null && moduleFlags.Any())
|
||||||
{
|
{
|
||||||
List<WayPoint> spawnPoints = potentialSpawnPoints.Where(wp => wp.CurrentHull?.OutpostModuleTags?.Any(moduleFlags.Contains) ?? false).ToList();
|
List<WayPoint> spawnPoints = potentialSpawnPoints.Where(wp => wp.CurrentHull?.OutpostModuleTags?.Any(moduleFlags.Contains) ?? false).ToList();
|
||||||
@@ -303,6 +303,12 @@ namespace Barotrauma
|
|||||||
return potentialSpawnPoints.GetRandom();
|
return potentialSpawnPoints.GetRandom();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//avoid using waypoints if there's any actual spawnpoints available
|
||||||
|
if (validSpawnPoints.Any(wp => wp.SpawnType != SpawnType.Path))
|
||||||
|
{
|
||||||
|
validSpawnPoints = validSpawnPoints.Where(wp => wp.SpawnType != SpawnType.Path);
|
||||||
|
}
|
||||||
|
|
||||||
//if not trying to spawn at a tagged spawnpoint, favor spawnpoints without tags
|
//if not trying to spawn at a tagged spawnpoint, favor spawnpoints without tags
|
||||||
if (spawnpointTags == null || !spawnpointTags.Any())
|
if (spawnpointTags == null || !spawnpointTags.Any())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,12 +6,17 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
class TagAction : EventAction
|
class TagAction : EventAction
|
||||||
{
|
{
|
||||||
|
public enum SubType { Any= 0, Player = 1, Outpost = 2, Wreck = 4, BeaconStation = 8 }
|
||||||
|
|
||||||
[Serialize("", true)]
|
[Serialize("", true)]
|
||||||
public string Criteria { get; set; }
|
public string Criteria { get; set; }
|
||||||
|
|
||||||
[Serialize("", true)]
|
[Serialize("", true)]
|
||||||
public string Tag { get; set; }
|
public string Tag { get; set; }
|
||||||
|
|
||||||
|
[Serialize(SubType.Any, true)]
|
||||||
|
public SubType SubmarineType { get; set; }
|
||||||
|
|
||||||
[Serialize(true, true)]
|
[Serialize(true, true)]
|
||||||
public bool IgnoreIncapacitatedCharacters { get; set; }
|
public bool IgnoreIncapacitatedCharacters { get; set; }
|
||||||
|
|
||||||
@@ -63,17 +68,37 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void TagStructuresByIdentifier(string identifier)
|
private void TagStructuresByIdentifier(string identifier)
|
||||||
{
|
{
|
||||||
ParentEvent.AddTargetPredicate(Tag, e => e is Structure s && s.Prefab.Identifier.Equals(identifier, StringComparison.InvariantCultureIgnoreCase));
|
ParentEvent.AddTargetPredicate(Tag, e => e is Structure s && SubmarineTypeMatches(s.Submarine) && s.Prefab.Identifier.Equals(identifier, StringComparison.InvariantCultureIgnoreCase));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TagItemsByIdentifier(string identifier)
|
private void TagItemsByIdentifier(string identifier)
|
||||||
{
|
{
|
||||||
ParentEvent.AddTargetPredicate(Tag, e => e is Item it && it.Prefab.Identifier.Equals(identifier, StringComparison.InvariantCultureIgnoreCase));
|
ParentEvent.AddTargetPredicate(Tag, e => e is Item it && SubmarineTypeMatches(it.Submarine) && it.Prefab.Identifier.Equals(identifier, StringComparison.InvariantCultureIgnoreCase));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TagItemsByTag(string tag)
|
private void TagItemsByTag(string tag)
|
||||||
{
|
{
|
||||||
ParentEvent.AddTargetPredicate(Tag, e => e is Item it && it.HasTag(tag));
|
ParentEvent.AddTargetPredicate(Tag, e => e is Item it && SubmarineTypeMatches(it.Submarine) && it.HasTag(tag));
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool SubmarineTypeMatches(Submarine sub)
|
||||||
|
{
|
||||||
|
if (SubmarineType == SubType.Any) { return true; }
|
||||||
|
if (sub == null) { return false; }
|
||||||
|
switch (sub.Info.Type)
|
||||||
|
{
|
||||||
|
case Barotrauma.SubmarineType.Player:
|
||||||
|
return SubmarineType.HasFlag(SubType.Player);
|
||||||
|
case Barotrauma.SubmarineType.Outpost:
|
||||||
|
case Barotrauma.SubmarineType.OutpostModule:
|
||||||
|
return SubmarineType.HasFlag(SubType.Outpost);
|
||||||
|
case Barotrauma.SubmarineType.Wreck:
|
||||||
|
return SubmarineType.HasFlag(SubType.Wreck);
|
||||||
|
case Barotrauma.SubmarineType.BeaconStation:
|
||||||
|
return SubmarineType.HasFlag(SubType.BeaconStation);
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(float deltaTime)
|
public override void Update(float deltaTime)
|
||||||
@@ -113,7 +138,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public override string ToDebugString()
|
public override string ToDebugString()
|
||||||
{
|
{
|
||||||
return $"{ToolBox.GetDebugSymbol(isFinished)} {nameof(TagAction)} -> (Criteria: {Criteria.ColorizeObject()}, Tag: {Tag.ColorizeObject()})";
|
return $"{ToolBox.GetDebugSymbol(isFinished)} {nameof(TagAction)} -> (Criteria: {Criteria.ColorizeObject()}, Tag: {Tag.ColorizeObject()}, Sub: {SubmarineType.ColorizeObject()})";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -134,7 +134,7 @@ namespace Barotrauma
|
|||||||
if (level?.LevelData?.Type == LevelData.LevelType.Outpost)
|
if (level?.LevelData?.Type == LevelData.LevelType.Outpost)
|
||||||
{
|
{
|
||||||
//if the outpost is connected to a locked connection, create an event to unlock it
|
//if the outpost is connected to a locked connection, create an event to unlock it
|
||||||
if (level.StartLocation?.Connections.Any(c => c.Locked) ?? false)
|
if (level.StartLocation?.Connections.Any(c => c.Locked && level.StartLocation.MapPosition.X < c.OtherLocation(level.StartLocation).MapPosition.X) ?? false)
|
||||||
{
|
{
|
||||||
var unlockPathPrefabs = EventSet.PrefabList.FindAll(e => e.UnlockPathEvent);
|
var unlockPathPrefabs = EventSet.PrefabList.FindAll(e => e.UnlockPathEvent);
|
||||||
var unlockPathPrefabsForBiome = unlockPathPrefabs.FindAll(e =>
|
var unlockPathPrefabsForBiome = unlockPathPrefabs.FindAll(e =>
|
||||||
@@ -166,11 +166,14 @@ namespace Barotrauma
|
|||||||
void AddChildEvents(EventSet eventSet)
|
void AddChildEvents(EventSet eventSet)
|
||||||
{
|
{
|
||||||
if (eventSet == null) { return; }
|
if (eventSet == null) { return; }
|
||||||
foreach (EventPrefab ep in eventSet.EventPrefabs.Select(e => e.First))
|
if (eventSet.OncePerOutpost)
|
||||||
{
|
{
|
||||||
if (!level.LevelData.NonRepeatableEvents.Contains(ep))
|
foreach (EventPrefab ep in eventSet.EventPrefabs.Select(e => e.First))
|
||||||
{
|
{
|
||||||
level.LevelData.NonRepeatableEvents.Add(ep);
|
if (!level.LevelData.NonRepeatableEvents.Contains(ep))
|
||||||
|
{
|
||||||
|
level.LevelData.NonRepeatableEvents.Add(ep);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (EventSet childSet in eventSet.ChildSets)
|
foreach (EventSet childSet in eventSet.ChildSets)
|
||||||
@@ -373,6 +376,8 @@ namespace Barotrauma
|
|||||||
private void CreateEvents(EventSet eventSet, Random rand)
|
private void CreateEvents(EventSet eventSet, Random rand)
|
||||||
{
|
{
|
||||||
if (level == null) { return; }
|
if (level == null) { return; }
|
||||||
|
if (level.LevelData.HasHuntingGrounds && eventSet.DisableInHuntingGrounds) { return; }
|
||||||
|
|
||||||
int applyCount = 1;
|
int applyCount = 1;
|
||||||
List<Func<Level.InterestingPosition, bool>> spawnPosFilter = new List<Func<Level.InterestingPosition, bool>>();
|
List<Func<Level.InterestingPosition, bool>> spawnPosFilter = new List<Func<Level.InterestingPosition, bool>>();
|
||||||
if (eventSet.PerRuin)
|
if (eventSet.PerRuin)
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ namespace Barotrauma
|
|||||||
public readonly bool IgnoreCoolDown;
|
public readonly bool IgnoreCoolDown;
|
||||||
|
|
||||||
public readonly bool PerRuin, PerCave, PerWreck;
|
public readonly bool PerRuin, PerCave, PerWreck;
|
||||||
|
public readonly bool DisableInHuntingGrounds;
|
||||||
|
|
||||||
public readonly bool OncePerOutpost;
|
public readonly bool OncePerOutpost;
|
||||||
|
|
||||||
@@ -142,9 +143,10 @@ namespace Barotrauma
|
|||||||
PerRuin = element.GetAttributeBool("perruin", false);
|
PerRuin = element.GetAttributeBool("perruin", false);
|
||||||
PerCave = element.GetAttributeBool("percave", false);
|
PerCave = element.GetAttributeBool("percave", false);
|
||||||
PerWreck = element.GetAttributeBool("perwreck", false);
|
PerWreck = element.GetAttributeBool("perwreck", false);
|
||||||
|
DisableInHuntingGrounds = element.GetAttributeBool("disableinhuntinggrounds", false);
|
||||||
IgnoreCoolDown = element.GetAttributeBool("ignorecooldown", parentSet?.IgnoreCoolDown ?? (PerRuin || PerCave || PerWreck));
|
IgnoreCoolDown = element.GetAttributeBool("ignorecooldown", parentSet?.IgnoreCoolDown ?? (PerRuin || PerCave || PerWreck));
|
||||||
DelayWhenCrewAway = element.GetAttributeBool("delaywhencrewaway", !PerRuin && !PerCave && !PerWreck);
|
DelayWhenCrewAway = element.GetAttributeBool("delaywhencrewaway", !PerRuin && !PerCave && !PerWreck);
|
||||||
OncePerOutpost = element.GetAttributeBool("perwreck", false);
|
OncePerOutpost = element.GetAttributeBool("onceperoutpost", false);
|
||||||
TriggerEventCooldown = element.GetAttributeBool("triggereventcooldown", true);
|
TriggerEventCooldown = element.GetAttributeBool("triggereventcooldown", true);
|
||||||
|
|
||||||
Commonness[""] = 1.0f;
|
Commonness[""] = 1.0f;
|
||||||
|
|||||||
+13
-4
@@ -54,10 +54,6 @@ namespace Barotrauma
|
|||||||
requireRescue.Clear();
|
requireRescue.Clear();
|
||||||
|
|
||||||
var submarine = Submarine.Loaded.Find(s => s.Info.Type == SubmarineType.Outpost) ?? Submarine.MainSub;
|
var submarine = Submarine.Loaded.Find(s => s.Info.Type == SubmarineType.Outpost) ?? Submarine.MainSub;
|
||||||
if (submarine.Info.Type == SubmarineType.Outpost)
|
|
||||||
{
|
|
||||||
submarine.TeamID = CharacterTeamType.None;
|
|
||||||
}
|
|
||||||
if (!IsClient)
|
if (!IsClient)
|
||||||
{
|
{
|
||||||
InitCharacters(submarine);
|
InitCharacters(submarine);
|
||||||
@@ -148,6 +144,10 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
humanPrefab.InitializeCharacter(spawnedCharacter, spawnPos);
|
humanPrefab.InitializeCharacter(spawnedCharacter, spawnPos);
|
||||||
humanPrefab.GiveItems(spawnedCharacter, Submarine.MainSub, Rand.RandSync.Server, createNetworkEvents: false);
|
humanPrefab.GiveItems(spawnedCharacter, Submarine.MainSub, Rand.RandSync.Server, createNetworkEvents: false);
|
||||||
|
if (spawnPos is WayPoint wp)
|
||||||
|
{
|
||||||
|
spawnedCharacter.GiveIdCardTags(wp);
|
||||||
|
}
|
||||||
if (element.GetAttributeBool("requirekill", false))
|
if (element.GetAttributeBool("requirekill", false))
|
||||||
{
|
{
|
||||||
requireKill.Add(spawnedCharacter);
|
requireKill.Add(spawnedCharacter);
|
||||||
@@ -175,6 +175,15 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
characterItems.Add(spawnedCharacter, spawnedCharacter.Inventory.FindAllItems(recursive: true));
|
characterItems.Add(spawnedCharacter, spawnedCharacter.Inventory.FindAllItems(recursive: true));
|
||||||
}
|
}
|
||||||
|
if (submarine != null && spawnedCharacter.AIController is EnemyAIController enemyAi)
|
||||||
|
{
|
||||||
|
enemyAi.UnattackableSubmarines.Add(submarine);
|
||||||
|
enemyAi.UnattackableSubmarines.Add(Submarine.MainSub);
|
||||||
|
foreach (Submarine sub in Submarine.MainSub.DockedTo)
|
||||||
|
{
|
||||||
|
enemyAi.UnattackableSubmarines.Add(sub);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Barotrauma.Items.Components;
|
using Barotrauma.Extensions;
|
||||||
|
using Barotrauma.Items.Components;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
@@ -99,18 +100,18 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
subs = new Submarine[] { Submarine.MainSubs[0], Submarine.MainSubs[1] };
|
subs = new Submarine[] { Submarine.MainSubs[0], Submarine.MainSubs[1] };
|
||||||
subs[0].TeamID = CharacterTeamType.Team1; subs[1].TeamID = CharacterTeamType.Team2;
|
|
||||||
subs[0].NeutralizeBallast(); subs[1].NeutralizeBallast();
|
subs[0].NeutralizeBallast();
|
||||||
|
subs[0].TeamID = CharacterTeamType.Team1;
|
||||||
|
subs[0].DockedTo.ForEach(s => s.TeamID = CharacterTeamType.Team1);
|
||||||
|
|
||||||
|
subs[1].NeutralizeBallast();
|
||||||
|
subs[1].TeamID = CharacterTeamType.Team2;
|
||||||
|
subs[1].DockedTo.ForEach(s => s.TeamID = CharacterTeamType.Team2);
|
||||||
subs[1].SetPosition(subs[1].FindSpawnPos(Level.Loaded.EndPosition));
|
subs[1].SetPosition(subs[1].FindSpawnPos(Level.Loaded.EndPosition));
|
||||||
subs[1].FlipX();
|
subs[1].FlipX();
|
||||||
|
|
||||||
crews = new List<Character>[] { new List<Character>(), new List<Character>() };
|
crews = new List<Character>[] { new List<Character>(), new List<Character>() };
|
||||||
|
|
||||||
foreach (Submarine submarine in Submarine.Loaded)
|
|
||||||
{
|
|
||||||
//hide all subs from sonar to make sneak attacks possible
|
|
||||||
submarine.ShowSonarMarker = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void End()
|
public override void End()
|
||||||
|
|||||||
@@ -108,6 +108,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public readonly Location[] Locations;
|
public readonly Location[] Locations;
|
||||||
|
|
||||||
|
public int? Difficulty
|
||||||
|
{
|
||||||
|
get { return Prefab.Difficulty; }
|
||||||
|
}
|
||||||
|
|
||||||
public Mission(MissionPrefab prefab, Location[] locations)
|
public Mission(MissionPrefab prefab, Location[] locations)
|
||||||
{
|
{
|
||||||
System.Diagnostics.Debug.Assert(locations.Length == 2);
|
System.Diagnostics.Debug.Assert(locations.Length == 2);
|
||||||
@@ -186,6 +191,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void Start(Level level)
|
public void Start(Level level)
|
||||||
{
|
{
|
||||||
|
#if CLIENT
|
||||||
|
shownMessages.Clear();
|
||||||
|
#endif
|
||||||
foreach (string categoryToShow in Prefab.UnhideEntitySubCategories)
|
foreach (string categoryToShow in Prefab.UnhideEntitySubCategories)
|
||||||
{
|
{
|
||||||
foreach (MapEntity entityToShow in MapEntity.mapEntityList.Where(me => me.prefab?.HasSubCategory(categoryToShow) ?? false))
|
foreach (MapEntity entityToShow in MapEntity.mapEntityList.Where(me => me.prefab?.HasSubCategory(categoryToShow) ?? false))
|
||||||
|
|||||||
@@ -72,6 +72,8 @@ namespace Barotrauma
|
|||||||
public readonly List<Tuple<string, object, SetDataAction.OperationType>> DataRewards = new List<Tuple<string, object, SetDataAction.OperationType>>();
|
public readonly List<Tuple<string, object, SetDataAction.OperationType>> DataRewards = new List<Tuple<string, object, SetDataAction.OperationType>>();
|
||||||
|
|
||||||
public readonly int Commonness;
|
public readonly int Commonness;
|
||||||
|
public readonly int? Difficulty;
|
||||||
|
public const int MinDifficulty = 1, MaxDifficulty = 4;
|
||||||
|
|
||||||
public readonly int Reward;
|
public readonly int Reward;
|
||||||
|
|
||||||
@@ -156,6 +158,11 @@ namespace Barotrauma
|
|||||||
AllowRetry = element.GetAttributeBool("allowretry", false);
|
AllowRetry = element.GetAttributeBool("allowretry", false);
|
||||||
IsSideObjective = element.GetAttributeBool("sideobjective", false);
|
IsSideObjective = element.GetAttributeBool("sideobjective", false);
|
||||||
Commonness = element.GetAttributeInt("commonness", 1);
|
Commonness = element.GetAttributeInt("commonness", 1);
|
||||||
|
if (element.GetAttribute("difficulty") != null)
|
||||||
|
{
|
||||||
|
int difficulty = element.GetAttributeInt("difficulty", MinDifficulty);
|
||||||
|
Difficulty = Math.Clamp(difficulty, MinDifficulty, MaxDifficulty);
|
||||||
|
}
|
||||||
|
|
||||||
SuccessMessage = TextManager.Get("MissionSuccess." + TextIdentifier, true) ?? element.GetAttributeString("successmessage", "Mission completed successfully");
|
SuccessMessage = TextManager.Get("MissionSuccess." + TextIdentifier, true) ?? element.GetAttributeString("successmessage", "Mission completed successfully");
|
||||||
FailureMessage = TextManager.Get("MissionFailure." + TextIdentifier, true) ?? "";
|
FailureMessage = TextManager.Get("MissionFailure." + TextIdentifier, true) ?? "";
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
GiveReward();
|
GiveReward();
|
||||||
completed = true;
|
completed = true;
|
||||||
if (level?.LevelData != null && Prefab.Tags.Any(t => t.Equals("huntinggrounds", StringComparison.OrdinalIgnoreCase)))
|
if (level?.LevelData != null && Prefab.Tags.Any(t => t.Equals("huntinggrounds", StringComparison.OrdinalIgnoreCase) || t.Equals("huntinggroundsnoreward", StringComparison.OrdinalIgnoreCase)))
|
||||||
{
|
{
|
||||||
level.LevelData.HasHuntingGrounds = false;
|
level.LevelData.HasHuntingGrounds = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -310,7 +310,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
foreach (Character npc in Character.CharacterList)
|
foreach (Character npc in Character.CharacterList)
|
||||||
{
|
{
|
||||||
if (npc.TeamID != CharacterTeamType.FriendlyNPC || npc.CurrentHull == null || npc.IsIncapacitated) { continue; }
|
if ((npc.TeamID != CharacterTeamType.FriendlyNPC && npc.TeamID != CharacterTeamType.None) || npc.CurrentHull == null || npc.IsIncapacitated) { continue; }
|
||||||
if (npc.AIController is HumanAIController humanAI && (humanAI.ObjectiveManager.IsCurrentObjective<AIObjectiveFindSafety>() || humanAI.ObjectiveManager.IsCurrentObjective<AIObjectiveCombat>()))
|
if (npc.AIController is HumanAIController humanAI && (humanAI.ObjectiveManager.IsCurrentObjective<AIObjectiveFindSafety>() || humanAI.ObjectiveManager.IsCurrentObjective<AIObjectiveCombat>()))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@@ -327,10 +327,12 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (npc.TeamID == CharacterTeamType.None)
|
if (npc.TeamID == CharacterTeamType.None)
|
||||||
{
|
{
|
||||||
|
dialogFlags.Remove("OutpostNPC");
|
||||||
dialogFlags.Add("Bandit");
|
dialogFlags.Add("Bandit");
|
||||||
}
|
}
|
||||||
else if (npc.TeamID == CharacterTeamType.FriendlyNPC)
|
else if (npc.TeamID == CharacterTeamType.FriendlyNPC)
|
||||||
{
|
{
|
||||||
|
dialogFlags.Remove("OutpostNPC");
|
||||||
dialogFlags.Add("Hostage");
|
dialogFlags.Add("Hostage");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ namespace Barotrauma
|
|||||||
new XAttribute("value", valueStr),
|
new XAttribute("value", valueStr),
|
||||||
new XAttribute("type", value?.GetType())));
|
new XAttribute("type", value?.GetType())));
|
||||||
}
|
}
|
||||||
#if DEBUG || UNSTABLE
|
#if DEBUG
|
||||||
DebugConsole.Log(element.ToString());
|
DebugConsole.Log(element.ToString());
|
||||||
#endif
|
#endif
|
||||||
modeElement.Add(element);
|
modeElement.Add(element);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using Barotrauma.Networking;
|
using Barotrauma.Networking;
|
||||||
|
using Barotrauma.Extensions;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -258,22 +259,32 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (levelData.HasBeaconStation && !levelData.IsBeaconActive)
|
if (levelData.HasBeaconStation && !levelData.IsBeaconActive)
|
||||||
{
|
{
|
||||||
var beaconMissionPrefab = MissionPrefab.List.Find(m => m.Tags.Any(t => t.Equals("beaconnoreward", StringComparison.OrdinalIgnoreCase)));
|
var beaconMissionPrefabs = MissionPrefab.List.FindAll(m => m.Tags.Any(t => t.Equals("beaconnoreward", StringComparison.OrdinalIgnoreCase)));
|
||||||
if (beaconMissionPrefab != null && !Missions.Any(m => m.Prefab.Type == beaconMissionPrefab.Type))
|
if (beaconMissionPrefabs.Any())
|
||||||
{
|
{
|
||||||
extraMissions.Add(beaconMissionPrefab.Instantiate(Map.SelectedConnection.Locations));
|
Random rand = new MTRandom(ToolBox.StringToInt(levelData.Seed));
|
||||||
|
var beaconMissionPrefab = beaconMissionPrefabs.GetRandom(rand);
|
||||||
|
if (!Missions.Any(m => m.Prefab.Type == beaconMissionPrefab.Type))
|
||||||
|
{
|
||||||
|
extraMissions.Add(beaconMissionPrefab.Instantiate(Map.SelectedConnection.Locations));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (levelData.HasHuntingGrounds)
|
if (levelData.HasHuntingGrounds)
|
||||||
{
|
{
|
||||||
var huntingGroundsMissionPrefab = MissionPrefab.List.Find(m => m.Tags.Any(t => t.Equals("huntinggroundsnoreward", StringComparison.OrdinalIgnoreCase)));
|
var huntingGroundsMissionPrefabs = MissionPrefab.List.FindAll(m => m.Tags.Any(t => t.Equals("huntinggroundsnoreward", StringComparison.OrdinalIgnoreCase)));
|
||||||
if (huntingGroundsMissionPrefab == null)
|
if (!huntingGroundsMissionPrefabs.Any())
|
||||||
{
|
{
|
||||||
DebugConsole.AddWarning("Could not find a hunting grounds mission for the level. No mission with the tag \"huntinggroundsnoreward\" found.");
|
DebugConsole.AddWarning("Could not find a hunting grounds mission for the level. No mission with the tag \"huntinggroundsnoreward\" found.");
|
||||||
}
|
}
|
||||||
else if (!Missions.Any(m => m.Prefab.Type == huntingGroundsMissionPrefab.Type))
|
else
|
||||||
{
|
{
|
||||||
extraMissions.Add(huntingGroundsMissionPrefab.Instantiate(Map.SelectedConnection.Locations));
|
Random rand = new MTRandom(ToolBox.StringToInt(levelData.Seed));
|
||||||
|
var huntingGroundsMissionPrefab = huntingGroundsMissionPrefabs.GetRandom(rand);
|
||||||
|
if (!Missions.Any(m => m.Prefab.Type == huntingGroundsMissionPrefab.Type))
|
||||||
|
{
|
||||||
|
extraMissions.Add(huntingGroundsMissionPrefab.Instantiate(Map.SelectedConnection.Locations));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -524,11 +535,13 @@ namespace Barotrauma
|
|||||||
takenItems.Add(item);
|
takenItems.Add(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
map.CurrentLocation.RegisterTakenItems(takenItems);
|
if (map != null && CargoManager != null)
|
||||||
|
{
|
||||||
map.CurrentLocation.AddToStock(CargoManager.SoldItems);
|
map.CurrentLocation.RegisterTakenItems(takenItems);
|
||||||
CargoManager.ClearSoldItemsProjSpecific();
|
map.CurrentLocation.AddToStock(CargoManager.SoldItems);
|
||||||
map.CurrentLocation.RemoveFromStock(CargoManager.PurchasedItems);
|
CargoManager.ClearSoldItemsProjSpecific();
|
||||||
|
map.CurrentLocation.RemoveFromStock(CargoManager.PurchasedItems);
|
||||||
|
}
|
||||||
if (GameMain.NetworkMember == null)
|
if (GameMain.NetworkMember == null)
|
||||||
{
|
{
|
||||||
CargoManager.ClearItemsInBuyCrate();
|
CargoManager.ClearItemsInBuyCrate();
|
||||||
@@ -538,11 +551,11 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (GameMain.NetworkMember.IsServer)
|
if (GameMain.NetworkMember.IsServer)
|
||||||
{
|
{
|
||||||
CargoManager.ClearItemsInBuyCrate();
|
CargoManager?.ClearItemsInBuyCrate();
|
||||||
}
|
}
|
||||||
else if (GameMain.NetworkMember.IsClient)
|
else if (GameMain.NetworkMember.IsClient)
|
||||||
{
|
{
|
||||||
CargoManager.ClearItemsInSellCrate();
|
CargoManager?.ClearItemsInSellCrate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -601,7 +614,11 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
foreach (Location location in Map.Locations)
|
foreach (Location location in Map.Locations)
|
||||||
{
|
{
|
||||||
location.ChangeType(location.OriginalType);
|
if (location.Type != location.OriginalType)
|
||||||
|
{
|
||||||
|
location.ChangeType(location.OriginalType);
|
||||||
|
location.PendingLocationTypeChange = null;
|
||||||
|
}
|
||||||
location.CreateStore(force: true);
|
location.CreateStore(force: true);
|
||||||
location.ClearMissions();
|
location.ClearMissions();
|
||||||
location.Discovered = false;
|
location.Discovered = false;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user