Merge branch 'dev' of https://github.com/Regalis11/Barotrauma.git into unstable-tests
This commit is contained in:
@@ -13,7 +13,7 @@ namespace Barotrauma
|
|||||||
private float? defaultZoom;
|
private float? defaultZoom;
|
||||||
public float DefaultZoom
|
public float DefaultZoom
|
||||||
{
|
{
|
||||||
get { return defaultZoom ?? (GameMain.Config == null || GameMain.Config.EnableMouseLook ? 1.3f : 1.0f); }
|
get { return defaultZoom ?? (GameSettings.CurrentConfig.EnableMouseLook ? 1.3f : 1.0f); }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
defaultZoom = MathHelper.Clamp(value, 0.5f, 2.0f);
|
defaultZoom = MathHelper.Clamp(value, 0.5f, 2.0f);
|
||||||
@@ -269,10 +269,10 @@ namespace Barotrauma
|
|||||||
if (PlayerInput.KeyDown(Keys.LeftShift)) { moveSpeed *= 2.0f; }
|
if (PlayerInput.KeyDown(Keys.LeftShift)) { moveSpeed *= 2.0f; }
|
||||||
if (PlayerInput.KeyDown(Keys.LeftControl)) { moveSpeed *= 0.5f; }
|
if (PlayerInput.KeyDown(Keys.LeftControl)) { moveSpeed *= 0.5f; }
|
||||||
|
|
||||||
if (GameMain.Config.KeyBind(InputType.Left).IsDown()) { moveInput.X -= 1.0f; }
|
if (GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Left].IsDown()) { moveInput.X -= 1.0f; }
|
||||||
if (GameMain.Config.KeyBind(InputType.Right).IsDown()) { moveInput.X += 1.0f; }
|
if (GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Right].IsDown()) { moveInput.X += 1.0f; }
|
||||||
if (GameMain.Config.KeyBind(InputType.Down).IsDown()) { moveInput.Y -= 1.0f; }
|
if (GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Down].IsDown()) { moveInput.Y -= 1.0f; }
|
||||||
if (GameMain.Config.KeyBind(InputType.Up).IsDown()) { moveInput.Y += 1.0f; }
|
if (GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Up].IsDown()) { moveInput.Y += 1.0f; }
|
||||||
}
|
}
|
||||||
|
|
||||||
velocity = Vector2.Lerp(velocity, moveInput, deltaTime * 10.0f);
|
velocity = Vector2.Lerp(velocity, moveInput, deltaTime * 10.0f);
|
||||||
@@ -346,7 +346,7 @@ namespace Barotrauma
|
|||||||
float scaledZoom = MathHelper.Lerp(DefaultZoom, MinZoom, zoomOutAmount) * globalZoomScale;
|
float scaledZoom = MathHelper.Lerp(DefaultZoom, MinZoom, zoomOutAmount) * globalZoomScale;
|
||||||
//zoom in further if zoomOutAmount is low and resolution is lower than reference
|
//zoom in further if zoomOutAmount is low and resolution is lower than reference
|
||||||
float newZoom = scaledZoom * (MathHelper.Lerp(0.3f * (1f - Math.Min(globalZoomScale, 1f)), 0f,
|
float newZoom = scaledZoom * (MathHelper.Lerp(0.3f * (1f - Math.Min(globalZoomScale, 1f)), 0f,
|
||||||
(GameMain.Config == null || GameMain.Config.EnableMouseLook) ? (float)Math.Sqrt(offsetUnscaledLen) : 0.3f) + 1f);
|
(GameSettings.CurrentConfig.EnableMouseLook) ? (float)Math.Sqrt(offsetUnscaledLen) : 0.3f) + 1f);
|
||||||
|
|
||||||
Zoom += (newZoom - zoom) / ZoomSmoothness;
|
Zoom += (newZoom - zoom) / ZoomSmoothness;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,8 +37,9 @@ namespace Barotrauma
|
|||||||
targetPos = attackWorldPos;
|
targetPos = attackWorldPos;
|
||||||
}
|
}
|
||||||
targetPos.Y = -targetPos.Y;
|
targetPos.Y = -targetPos.Y;
|
||||||
GUI.DrawLine(spriteBatch, pos, targetPos, GUI.Style.Red * 0.5f, 0, 4);
|
|
||||||
if (wallTarget != null)
|
GUI.DrawLine(spriteBatch, pos, targetPos, GUIStyle.Red * 0.5f, 0, 4);
|
||||||
|
if (wallTarget != null && !IsCoolDownRunning)
|
||||||
{
|
{
|
||||||
Vector2 wallTargetPos = wallTarget.Position;
|
Vector2 wallTargetPos = wallTarget.Position;
|
||||||
if (wallTarget.Structure.Submarine != null) { wallTargetPos += wallTarget.Structure.Submarine.Position; }
|
if (wallTarget.Structure.Submarine != null) { wallTargetPos += wallTarget.Structure.Submarine.Position; }
|
||||||
@@ -46,19 +47,19 @@ namespace Barotrauma
|
|||||||
GUI.DrawRectangle(spriteBatch, wallTargetPos - new Vector2(10.0f, 10.0f), new Vector2(20.0f, 20.0f), Color.Orange, false);
|
GUI.DrawRectangle(spriteBatch, wallTargetPos - new Vector2(10.0f, 10.0f), new Vector2(20.0f, 20.0f), Color.Orange, false);
|
||||||
GUI.DrawLine(spriteBatch, pos, wallTargetPos, Color.Orange * 0.5f, 0, 5);
|
GUI.DrawLine(spriteBatch, pos, wallTargetPos, Color.Orange * 0.5f, 0, 5);
|
||||||
}
|
}
|
||||||
GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 60.0f, $"{SelectedAiTarget.Entity} ({GetTargetMemory(SelectedAiTarget, false)?.Priority.FormatZeroDecimal()})", GUI.Style.Red, Color.Black);
|
GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 60.0f, $"{SelectedAiTarget.Entity} ({GetTargetMemory(SelectedAiTarget, false)?.Priority.FormatZeroDecimal()})", GUIStyle.Red, Color.Black);
|
||||||
GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 40.0f, $"({targetValue.FormatZeroDecimal()})", GUI.Style.Red, Color.Black);
|
GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 40.0f, $"({targetValue.FormatZeroDecimal()})", GUIStyle.Red, Color.Black);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*GUI.Font.DrawString(spriteBatch, targetValue.ToString(), pos - Vector2.UnitY * 80.0f, GUI.Style.Red);
|
/*GUIStyle.Font.DrawString(spriteBatch, targetValue.ToString(), pos - Vector2.UnitY * 80.0f, GUIStyle.Red);
|
||||||
GUI.Font.DrawString(spriteBatch, "updatetargets: " + MathUtils.Round(updateTargetsTimer, 0.1f), pos - Vector2.UnitY * 100.0f, GUI.Style.Red);
|
GUIStyle.Font.DrawString(spriteBatch, "updatetargets: " + MathUtils.Round(updateTargetsTimer, 0.1f), pos - Vector2.UnitY * 100.0f, GUIStyle.Red);
|
||||||
GUI.Font.DrawString(spriteBatch, "cooldown: " + MathUtils.Round(coolDownTimer, 0.1f), pos - Vector2.UnitY * 120.0f, GUI.Style.Red);*/
|
GUIStyle.Font.DrawString(spriteBatch, "cooldown: " + MathUtils.Round(coolDownTimer, 0.1f), pos - Vector2.UnitY * 120.0f, GUIStyle.Red);*/
|
||||||
|
|
||||||
Color stateColor = Color.White;
|
Color stateColor = Color.White;
|
||||||
switch (State)
|
switch (State)
|
||||||
{
|
{
|
||||||
case AIState.Attack:
|
case AIState.Attack:
|
||||||
stateColor = IsCoolDownRunning ? Color.Orange : GUI.Style.Red;
|
stateColor = IsCoolDownRunning ? Color.Orange : GUIStyle.Red;
|
||||||
break;
|
break;
|
||||||
case AIState.Escape:
|
case AIState.Escape:
|
||||||
stateColor = Color.LightBlue;
|
stateColor = Color.LightBlue;
|
||||||
@@ -78,13 +79,13 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
GUI.DrawLine(spriteBatch,
|
GUI.DrawLine(spriteBatch,
|
||||||
ConvertUnits.ToDisplayUnits(new Vector2(attachJoint.WorldAnchorA.X, -attachJoint.WorldAnchorA.Y)),
|
ConvertUnits.ToDisplayUnits(new Vector2(attachJoint.WorldAnchorA.X, -attachJoint.WorldAnchorA.Y)),
|
||||||
ConvertUnits.ToDisplayUnits(new Vector2(attachJoint.WorldAnchorB.X, -attachJoint.WorldAnchorB.Y)), GUI.Style.Green, 0, 4);
|
ConvertUnits.ToDisplayUnits(new Vector2(attachJoint.WorldAnchorB.X, -attachJoint.WorldAnchorB.Y)), GUIStyle.Green, 0, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LatchOntoAI.AttachPos.HasValue)
|
if (LatchOntoAI.AttachPos.HasValue)
|
||||||
{
|
{
|
||||||
GUI.DrawLine(spriteBatch, pos,
|
GUI.DrawLine(spriteBatch, pos,
|
||||||
ConvertUnits.ToDisplayUnits(new Vector2(LatchOntoAI.AttachPos.Value.X, -LatchOntoAI.AttachPos.Value.Y)), GUI.Style.Green, 0, 3);
|
ConvertUnits.ToDisplayUnits(new Vector2(LatchOntoAI.AttachPos.Value.X, -LatchOntoAI.AttachPos.Value.Y)), GUIStyle.Green, 0, 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,12 +109,12 @@ namespace Barotrauma
|
|||||||
GUI.DrawLine(spriteBatch,
|
GUI.DrawLine(spriteBatch,
|
||||||
new Vector2(currentNode.DrawPosition.X, -currentNode.DrawPosition.Y),
|
new Vector2(currentNode.DrawPosition.X, -currentNode.DrawPosition.Y),
|
||||||
new Vector2(previousNode.DrawPosition.X, -previousNode.DrawPosition.Y),
|
new Vector2(previousNode.DrawPosition.X, -previousNode.DrawPosition.Y),
|
||||||
GUI.Style.Red * 0.5f, 0, 3);
|
GUIStyle.Red * 0.5f, 0, 3);
|
||||||
|
|
||||||
GUI.SmallFont.DrawString(spriteBatch,
|
GUIStyle.SmallFont.DrawString(spriteBatch,
|
||||||
currentNode.ID.ToString(),
|
currentNode.ID.ToString(),
|
||||||
new Vector2(currentNode.DrawPosition.X - 10, -currentNode.DrawPosition.Y - 30),
|
new Vector2(currentNode.DrawPosition.X - 10, -currentNode.DrawPosition.Y - 30),
|
||||||
GUI.Style.Red);
|
GUIStyle.Red);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -124,7 +125,7 @@ namespace Barotrauma
|
|||||||
Vector2 hitPos = ConvertUnits.ToDisplayUnits(steeringManager.AvoidRayCastHitPosition);
|
Vector2 hitPos = ConvertUnits.ToDisplayUnits(steeringManager.AvoidRayCastHitPosition);
|
||||||
hitPos.Y = -hitPos.Y;
|
hitPos.Y = -hitPos.Y;
|
||||||
|
|
||||||
GUI.DrawLine(spriteBatch, hitPos, hitPos + new Vector2(steeringManager.AvoidDir.X, -steeringManager.AvoidDir.Y) * 100, GUI.Style.Red, width: 5);
|
GUI.DrawLine(spriteBatch, hitPos, hitPos + new Vector2(steeringManager.AvoidDir.X, -steeringManager.AvoidDir.Y) * 100, GUIStyle.Red, width: 5);
|
||||||
//GUI.DrawLine(spriteBatch, pos, ConvertUnits.ToDisplayUnits(steeringManager.AvoidLookAheadPos.X, -steeringManager.AvoidLookAheadPos.Y), Color.Orange, width: 4);
|
//GUI.DrawLine(spriteBatch, pos, ConvertUnits.ToDisplayUnits(steeringManager.AvoidLookAheadPos.X, -steeringManager.AvoidLookAheadPos.Y), Color.Orange, width: 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (SelectedAiTarget?.Entity != null)
|
if (SelectedAiTarget?.Entity != null)
|
||||||
{
|
{
|
||||||
//GUI.DrawLine(spriteBatch, pos, new Vector2(SelectedAiTarget.WorldPosition.X, -SelectedAiTarget.WorldPosition.Y), GUI.Style.Red);
|
//GUI.DrawLine(spriteBatch, pos, new Vector2(SelectedAiTarget.WorldPosition.X, -SelectedAiTarget.WorldPosition.Y), GUIStyle.Red);
|
||||||
//GUI.DrawString(spriteBatch, pos + textOffset, $"AI TARGET: {SelectedAiTarget.Entity.ToString()}", Color.White, Color.Black);
|
//GUI.DrawString(spriteBatch, pos + textOffset, $"AI TARGET: {SelectedAiTarget.Entity.ToString()}", Color.White, Color.Black);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ namespace Barotrauma
|
|||||||
new Vector2(previousNode.DrawPosition.X, -previousNode.DrawPosition.Y),
|
new Vector2(previousNode.DrawPosition.X, -previousNode.DrawPosition.Y),
|
||||||
Color.Blue * 0.5f, 0, 3);
|
Color.Blue * 0.5f, 0, 3);
|
||||||
|
|
||||||
GUI.SmallFont.DrawString(spriteBatch,
|
GUIStyle.SmallFont.DrawString(spriteBatch,
|
||||||
currentNode.ID.ToString(),
|
currentNode.ID.ToString(),
|
||||||
new Vector2(currentNode.DrawPosition.X - 10, -currentNode.DrawPosition.Y - 30),
|
new Vector2(currentNode.DrawPosition.X - 10, -currentNode.DrawPosition.Y - 30),
|
||||||
Color.Blue);
|
Color.Blue);
|
||||||
|
|||||||
@@ -6,16 +6,16 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
public static Color ObjectiveIconColor => Color.LightGray;
|
public static Color ObjectiveIconColor => Color.LightGray;
|
||||||
|
|
||||||
public static Sprite GetSprite(string identifier, string option, Entity targetEntity)
|
public static Sprite GetSprite(Identifier identifier, Identifier option, Entity targetEntity)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(identifier))
|
if (identifier == Identifier.Empty)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
identifier = identifier.RemoveWhitespace();
|
if (OrderPrefab.Prefabs.ContainsKey(identifier))
|
||||||
if (Order.Prefabs.TryGetValue(identifier, out Order orderPrefab))
|
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(option) && orderPrefab.OptionSprites.TryGetValue(option, out var optionSprite))
|
OrderPrefab orderPrefab = OrderPrefab.Prefabs[identifier];
|
||||||
|
if (option != Identifier.Empty && orderPrefab.OptionSprites.TryGetValue(option, out var optionSprite))
|
||||||
{
|
{
|
||||||
return optionSprite;
|
return optionSprite;
|
||||||
}
|
}
|
||||||
@@ -25,7 +25,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
return orderPrefab.SymbolSprite;
|
return orderPrefab.SymbolSprite;
|
||||||
}
|
}
|
||||||
return GUI.Style.GetComponentStyle($"{identifier}objectiveicon")?.GetDefaultSprite();
|
return GUIStyle.GetComponentStyle($"{identifier}objectiveicon")?.GetDefaultSprite();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sprite GetSprite()
|
public Sprite GetSprite()
|
||||||
|
|||||||
@@ -28,13 +28,13 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (item.Prefab.BrokenSprites.None())
|
if (item.Prefab.BrokenSprites.None())
|
||||||
{
|
{
|
||||||
Color c = item.prefab.SpriteColor;
|
Color c = item.Prefab.SpriteColor;
|
||||||
item.SpriteColor = new Color(c.R / 255f * m, c.G / 255f * m, c.B / 255f * m, c.A / 255f);
|
item.SpriteColor = new Color(c.R / 255f * m, c.G / 255f * m, c.B / 255f * m, c.A / 255f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (var structure in thalamusStructures)
|
foreach (var structure in thalamusStructures)
|
||||||
{
|
{
|
||||||
Color c = structure.prefab.SpriteColor;
|
Color c = structure.Prefab.SpriteColor;
|
||||||
structure.SpriteColor = new Color(c.R / 255f * m, c.G / 255f * m, c.B / 255f * m, c.A / 255f);
|
structure.SpriteColor = new Color(c.R / 255f * m, c.G / 255f * m, c.B / 255f * m, c.A / 255f);
|
||||||
}
|
}
|
||||||
yield return CoroutineStatus.Running;
|
yield return CoroutineStatus.Running;
|
||||||
@@ -42,7 +42,7 @@ namespace Barotrauma
|
|||||||
yield return CoroutineStatus.Success;
|
yield return CoroutineStatus.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
public void ClientEventRead(IReadMessage msg, float sendingTime)
|
||||||
{
|
{
|
||||||
IsAlive = msg.ReadBoolean();
|
IsAlive = msg.ReadBoolean();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -469,7 +469,7 @@ namespace Barotrauma
|
|||||||
Color? color = null;
|
Color? color = null;
|
||||||
if (character.ExternalHighlight)
|
if (character.ExternalHighlight)
|
||||||
{
|
{
|
||||||
color = Color.Lerp(Color.White, GUI.Style.Orange, (float)Math.Sin(Timing.TotalTime * 3.5f));
|
color = Color.Lerp(Color.White, GUIStyle.Orange, (float)Math.Sin(Timing.TotalTime * 3.5f));
|
||||||
}
|
}
|
||||||
|
|
||||||
float depthOffset = GetDepthOffset();
|
float depthOffset = GetDepthOffset();
|
||||||
@@ -564,7 +564,7 @@ namespace Barotrauma
|
|||||||
Vector2 pos = ConvertUnits.ToDisplayUnits(limb.PullJointWorldAnchorB);
|
Vector2 pos = ConvertUnits.ToDisplayUnits(limb.PullJointWorldAnchorB);
|
||||||
if (currentHull?.Submarine != null) pos += currentHull.Submarine.DrawPosition;
|
if (currentHull?.Submarine != null) pos += currentHull.Submarine.DrawPosition;
|
||||||
pos.Y = -pos.Y;
|
pos.Y = -pos.Y;
|
||||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X, (int)pos.Y, 5, 5), GUI.Style.Red, true, 0.01f);
|
GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X, (int)pos.Y, 5, 5), GUIStyle.Red, true, 0.01f);
|
||||||
|
|
||||||
pos = ConvertUnits.ToDisplayUnits(limb.PullJointWorldAnchorA);
|
pos = ConvertUnits.ToDisplayUnits(limb.PullJointWorldAnchorA);
|
||||||
if (currentHull?.Submarine != null) pos += currentHull.Submarine.DrawPosition;
|
if (currentHull?.Submarine != null) pos += currentHull.Submarine.DrawPosition;
|
||||||
@@ -575,8 +575,8 @@ namespace Barotrauma
|
|||||||
limb.body.DebugDraw(spriteBatch, inWater ? (currentHull == null ? Color.Blue : Color.Cyan) : Color.White);
|
limb.body.DebugDraw(spriteBatch, inWater ? (currentHull == null ? Color.Blue : Color.Cyan) : Color.White);
|
||||||
}
|
}
|
||||||
|
|
||||||
Collider.DebugDraw(spriteBatch, frozen ? GUI.Style.Red : (inWater ? Color.SkyBlue : Color.Gray));
|
Collider.DebugDraw(spriteBatch, frozen ? GUIStyle.Red : (inWater ? Color.SkyBlue : Color.Gray));
|
||||||
GUI.Font.DrawString(spriteBatch, Collider.LinearVelocity.X.FormatSingleDecimal(), new Vector2(Collider.DrawPosition.X, -Collider.DrawPosition.Y), Color.Orange);
|
GUIStyle.Font.DrawString(spriteBatch, Collider.LinearVelocity.X.FormatSingleDecimal(), new Vector2(Collider.DrawPosition.X, -Collider.DrawPosition.Y), Color.Orange);
|
||||||
|
|
||||||
foreach (var joint in LimbJoints)
|
foreach (var joint in LimbJoints)
|
||||||
{
|
{
|
||||||
@@ -607,10 +607,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Vector2 pos = ConvertUnits.ToDisplayUnits(humanoid.RightHandIKPos);
|
Vector2 pos = ConvertUnits.ToDisplayUnits(humanoid.RightHandIKPos);
|
||||||
if (humanoid.character.Submarine != null) { pos += humanoid.character.Submarine.DrawPosition; }
|
if (humanoid.character.Submarine != null) { pos += humanoid.character.Submarine.DrawPosition; }
|
||||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X, (int)-pos.Y, 4, 4), GUI.Style.Green, true);
|
GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X, (int)-pos.Y, 4, 4), GUIStyle.Green, true);
|
||||||
pos = ConvertUnits.ToDisplayUnits(humanoid.LeftHandIKPos);
|
pos = ConvertUnits.ToDisplayUnits(humanoid.LeftHandIKPos);
|
||||||
if (humanoid.character.Submarine != null) { pos += humanoid.character.Submarine.DrawPosition; }
|
if (humanoid.character.Submarine != null) { pos += humanoid.character.Submarine.DrawPosition; }
|
||||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X, (int)-pos.Y, 4, 4), GUI.Style.Green, true);
|
GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X, (int)-pos.Y, 4, 4), GUIStyle.Green, true);
|
||||||
|
|
||||||
Vector2 aimPos = humanoid.AimSourceWorldPos;
|
Vector2 aimPos = humanoid.AimSourceWorldPos;
|
||||||
aimPos.Y = -aimPos.Y;
|
aimPos.Y = -aimPos.Y;
|
||||||
|
|||||||
@@ -6,22 +6,22 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
partial class Attack
|
partial class Attack
|
||||||
{
|
{
|
||||||
[Serialize("StructureBlunt", true), Editable()]
|
[Serialize("StructureBlunt", IsPropertySaveable.Yes), Editable()]
|
||||||
public string StructureSoundType { get; private set; }
|
public string StructureSoundType { get; private set; }
|
||||||
|
|
||||||
private RoundSound sound;
|
private RoundSound sound;
|
||||||
|
|
||||||
private ParticleEmitter particleEmitter;
|
private ParticleEmitter particleEmitter;
|
||||||
|
|
||||||
partial void InitProjSpecific(XElement element)
|
partial void InitProjSpecific(ContentXElement element)
|
||||||
{
|
{
|
||||||
if (element.Attribute("sound") != null)
|
if (element.GetAttribute("sound") != null)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Error in attack ("+element+") - sounds should be defined as child elements, not as attributes.");
|
DebugConsole.ThrowError("Error in attack ("+element+") - sounds should be defined as child elements, not as attributes.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (XElement subElement in element.Elements())
|
foreach (var subElement in element.Elements())
|
||||||
{
|
{
|
||||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||||
{
|
{
|
||||||
@@ -29,7 +29,7 @@ namespace Barotrauma
|
|||||||
particleEmitter = new ParticleEmitter(subElement);
|
particleEmitter = new ParticleEmitter(subElement);
|
||||||
break;
|
break;
|
||||||
case "sound":
|
case "sound":
|
||||||
sound = Submarine.LoadRoundSound(subElement);
|
sound = RoundSound.Load(subElement);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ namespace Barotrauma
|
|||||||
private class GUIMessage
|
private class GUIMessage
|
||||||
{
|
{
|
||||||
public string RawText;
|
public string RawText;
|
||||||
public string Identifier;
|
public Identifier Identifier;
|
||||||
public string Text;
|
public string Text;
|
||||||
|
|
||||||
private int _value;
|
private int _value;
|
||||||
@@ -142,7 +142,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
_value = value;
|
_value = value;
|
||||||
Text = RawText.Replace("[value]", _value.ToString());
|
Text = RawText.Replace("[value]", _value.ToString());
|
||||||
Size = GUI.Font.MeasureString(Text);
|
Size = GUIStyle.Font.MeasureString(Text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,7 +154,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public bool PlaySound;
|
public bool PlaySound;
|
||||||
|
|
||||||
public GUIMessage(string rawText, Color color, float delay, string identifier = null, int? value = null, float lifeTime = 3.0f)
|
public GUIMessage(string rawText, Color color, float delay, Identifier identifier = default, int? value = null, float lifeTime = 3.0f)
|
||||||
{
|
{
|
||||||
RawText = Text = rawText;
|
RawText = Text = rawText;
|
||||||
if (value.HasValue)
|
if (value.HasValue)
|
||||||
@@ -163,7 +163,7 @@ namespace Barotrauma
|
|||||||
Value = value.Value;
|
Value = value.Value;
|
||||||
}
|
}
|
||||||
Timer = -delay;
|
Timer = -delay;
|
||||||
Size = GUI.Font.MeasureString(Text);
|
Size = GUIStyle.Font.MeasureString(Text);
|
||||||
Color = color;
|
Color = color;
|
||||||
Identifier = identifier;
|
Identifier = identifier;
|
||||||
Lifetime = lifeTime;
|
Lifetime = lifeTime;
|
||||||
@@ -202,14 +202,14 @@ namespace Barotrauma
|
|||||||
get { return activeObjectiveEntities; }
|
get { return activeObjectiveEntities; }
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void InitProjSpecific(XElement mainElement)
|
partial void InitProjSpecific(ContentXElement mainElement)
|
||||||
{
|
{
|
||||||
soundTimer = Rand.Range(0.0f, Params.SoundInterval);
|
soundTimer = Rand.Range(0.0f, Params.SoundInterval);
|
||||||
|
|
||||||
sounds = new List<CharacterSound>();
|
sounds = new List<CharacterSound>();
|
||||||
Params.Sounds.ForEach(s => sounds.Add(new CharacterSound(s)));
|
Params.Sounds.ForEach(s => sounds.Add(new CharacterSound(s)));
|
||||||
|
|
||||||
foreach (XElement subElement in mainElement.Elements())
|
foreach (var subElement in mainElement.Elements())
|
||||||
{
|
{
|
||||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||||
{
|
{
|
||||||
@@ -267,11 +267,11 @@ namespace Barotrauma
|
|||||||
//and the fire key is the same as Select or Use, reset the key to prevent accidentally selecting/using items
|
//and the fire key is the same as Select or Use, reset the key to prevent accidentally selecting/using items
|
||||||
if (wasFiring && !keys[(int)InputType.Shoot].Held)
|
if (wasFiring && !keys[(int)InputType.Shoot].Held)
|
||||||
{
|
{
|
||||||
if (GameMain.Config.KeyBind(InputType.Shoot).Equals(GameMain.Config.KeyBind(InputType.Select)))
|
if (GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Shoot] == GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Select])
|
||||||
{
|
{
|
||||||
keys[(int)InputType.Select].Reset();
|
keys[(int)InputType.Select].Reset();
|
||||||
}
|
}
|
||||||
if (GameMain.Config.KeyBind(InputType.Shoot).Equals(GameMain.Config.KeyBind(InputType.Use)))
|
if (GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Shoot] == GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Use])
|
||||||
{
|
{
|
||||||
keys[(int)InputType.Use].Reset();
|
keys[(int)InputType.Use].Reset();
|
||||||
}
|
}
|
||||||
@@ -331,7 +331,7 @@ namespace Barotrauma
|
|||||||
Position +
|
Position +
|
||||||
PlayerInput.MouseSpeed.ClampLength(10.0f); //apply a little bit of movement to the cursor pos to prevent AFK kicking
|
PlayerInput.MouseSpeed.ClampLength(10.0f); //apply a little bit of movement to the cursor pos to prevent AFK kicking
|
||||||
}
|
}
|
||||||
else if (!GameMain.Config.EnableMouseLook)
|
else if (!GameSettings.CurrentConfig.EnableMouseLook)
|
||||||
{
|
{
|
||||||
cam.OffsetAmount = targetOffsetAmount = 0.0f;
|
cam.OffsetAmount = targetOffsetAmount = 0.0f;
|
||||||
}
|
}
|
||||||
@@ -446,15 +446,15 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (GameMain.NetworkMember != null && controlled == this)
|
if (GameMain.NetworkMember != null && controlled == this)
|
||||||
{
|
{
|
||||||
string chatMessage = CauseOfDeath.Type == CauseOfDeathType.Affliction ?
|
LocalizedString 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(), "Self_CauseOfDeathDescription.Damage");
|
||||||
|
|
||||||
if (GameMain.Client != null) { chatMessage += " " + TextManager.Get("DeathChatNotification"); }
|
if (GameMain.Client != null) { chatMessage += " " + TextManager.Get("DeathChatNotification"); }
|
||||||
|
|
||||||
GameMain.NetworkMember.RespawnManager?.ShowRespawnPromptIfNeeded();
|
GameMain.NetworkMember.RespawnManager?.ShowRespawnPromptIfNeeded();
|
||||||
|
|
||||||
GameMain.NetworkMember.AddChatMessage(chatMessage, ChatMessageType.Dead);
|
GameMain.NetworkMember.AddChatMessage(chatMessage.Value, ChatMessageType.Dead);
|
||||||
GameMain.LightManager.LosEnabled = false;
|
GameMain.LightManager.LosEnabled = false;
|
||||||
controlled = null;
|
controlled = null;
|
||||||
if (!(Screen.Selected?.Cam is null))
|
if (!(Screen.Selected?.Cam is null))
|
||||||
@@ -726,9 +726,9 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void SetOrderProjSpecific(Order order, string orderOption, int priority)
|
partial void SetOrderProjSpecific(Order order)
|
||||||
{
|
{
|
||||||
GameMain.GameSession?.CrewManager?.AddCurrentOrderIcon(this, order, orderOption, priority);
|
GameMain.GameSession?.CrewManager?.AddCurrentOrderIcon(this, order);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AddAllToGUIUpdateList()
|
public static void AddAllToGUIUpdateList()
|
||||||
@@ -812,7 +812,7 @@ namespace Barotrauma
|
|||||||
Controlled != this &&
|
Controlled != this &&
|
||||||
Submarine != null &&
|
Submarine != null &&
|
||||||
Controlled.Submarine == Submarine &&
|
Controlled.Submarine == Submarine &&
|
||||||
GameMain.Config.LosMode != LosMode.None)
|
GameSettings.CurrentConfig.Graphics.LosMode != LosMode.None)
|
||||||
{
|
{
|
||||||
float yPos = Controlled.AnimController.FloorY - 1.5f;
|
float yPos = Controlled.AnimController.FloorY - 1.5f;
|
||||||
|
|
||||||
@@ -854,7 +854,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (speechBubbleTimer > 0.0f)
|
if (speechBubbleTimer > 0.0f)
|
||||||
{
|
{
|
||||||
GUI.SpeechBubbleIcon.Draw(spriteBatch, pos - Vector2.UnitY * 5,
|
GUIStyle.SpeechBubbleIcon.Value.Sprite.Draw(spriteBatch, pos - Vector2.UnitY * 5,
|
||||||
speechBubbleColor * Math.Min(speechBubbleTimer, 1.0f), 0.0f,
|
speechBubbleColor * Math.Min(speechBubbleTimer, 1.0f), 0.0f,
|
||||||
Math.Min(speechBubbleTimer, 1.0f));
|
Math.Min(speechBubbleTimer, 1.0f));
|
||||||
}
|
}
|
||||||
@@ -880,7 +880,7 @@ namespace Barotrauma
|
|||||||
GUI.DrawLine(spriteBatch,
|
GUI.DrawLine(spriteBatch,
|
||||||
cursorPos,
|
cursorPos,
|
||||||
new Vector2(item.DrawPosition.X, -item.DrawPosition.Y),
|
new Vector2(item.DrawPosition.X, -item.DrawPosition.Y),
|
||||||
ToolBox.GradientLerp(dist, GUI.Style.Red, GUI.Style.Orange, GUI.Style.Green), width: 2);
|
ToolBox.GradientLerp(dist, GUIStyle.Red, GUIStyle.Orange, GUIStyle.Green), width: 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -899,10 +899,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (info != null)
|
if (info != null)
|
||||||
{
|
{
|
||||||
string name = Info.DisplayName;
|
LocalizedString name = Info.DisplayName;
|
||||||
if (controlled == null && name != Info.Name) { name += " " + TextManager.Get("Disguised"); }
|
if (controlled == null && name != Info.Name) { name += " " + TextManager.Get("Disguised"); }
|
||||||
|
|
||||||
Vector2 nameSize = GUI.Font.MeasureString(name);
|
Vector2 nameSize = GUIStyle.Font.MeasureString(name);
|
||||||
Vector2 namePos = new Vector2(pos.X, pos.Y - 10.0f - (5.0f / cam.Zoom)) - nameSize * 0.5f / cam.Zoom;
|
Vector2 namePos = new Vector2(pos.X, pos.Y - 10.0f - (5.0f / cam.Zoom)) - nameSize * 0.5f / cam.Zoom;
|
||||||
Color nameColor = GetNameColor();
|
Color nameColor = GetNameColor();
|
||||||
|
|
||||||
@@ -916,7 +916,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (CampaignInteractionType != CampaignMode.InteractionType.None && AllowCustomInteract)
|
if (CampaignInteractionType != CampaignMode.InteractionType.None && AllowCustomInteract)
|
||||||
{
|
{
|
||||||
var iconStyle = GUI.Style.GetComponentStyle("CampaignInteractionBubble." + CampaignInteractionType);
|
var iconStyle = GUIStyle.GetComponentStyle("CampaignInteractionBubble." + CampaignInteractionType);
|
||||||
if (iconStyle != null)
|
if (iconStyle != null)
|
||||||
{
|
{
|
||||||
Vector2 headPos = AnimController.GetLimb(LimbType.Head)?.body?.DrawPosition ?? DrawPosition + Vector2.UnitY * 100.0f;
|
Vector2 headPos = AnimController.GetLimb(LimbType.Head)?.body?.DrawPosition ?? DrawPosition + Vector2.UnitY * 100.0f;
|
||||||
@@ -929,11 +929,11 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GUI.Font.DrawString(spriteBatch, name, namePos + new Vector2(1.0f / cam.Zoom, 1.0f / cam.Zoom), Color.Black, 0.0f, Vector2.Zero, 1.0f / cam.Zoom, SpriteEffects.None, 0.001f);
|
GUIStyle.Font.DrawString(spriteBatch, name, namePos + new Vector2(1.0f / cam.Zoom, 1.0f / cam.Zoom), Color.Black, 0.0f, Vector2.Zero, 1.0f / cam.Zoom, SpriteEffects.None, 0.001f);
|
||||||
GUI.Font.DrawString(spriteBatch, name, namePos, nameColor * hudInfoAlpha, 0.0f, Vector2.Zero, 1.0f / cam.Zoom, SpriteEffects.None, 0.0f);
|
GUIStyle.Font.DrawString(spriteBatch, name, namePos, nameColor * hudInfoAlpha, 0.0f, Vector2.Zero, 1.0f / cam.Zoom, SpriteEffects.None, 0.0f);
|
||||||
if (GameMain.DebugDraw)
|
if (GameMain.DebugDraw)
|
||||||
{
|
{
|
||||||
GUI.Font.DrawString(spriteBatch, ID.ToString(), namePos - new Vector2(0.0f, 20.0f), Color.White);
|
GUIStyle.Font.DrawString(spriteBatch, ID.ToString(), namePos - new Vector2(0.0f, 20.0f), Color.White);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -941,7 +941,7 @@ namespace Barotrauma
|
|||||||
if (petBehavior != null && !IsDead && !IsUnconscious)
|
if (petBehavior != null && !IsDead && !IsUnconscious)
|
||||||
{
|
{
|
||||||
var petStatus = petBehavior.GetCurrentStatusIndicatorType();
|
var petStatus = petBehavior.GetCurrentStatusIndicatorType();
|
||||||
var iconStyle = GUI.Style.GetComponentStyle("PetIcon." + petStatus);
|
var iconStyle = GUIStyle.GetComponentStyle("PetIcon." + petStatus);
|
||||||
if (iconStyle != null)
|
if (iconStyle != null)
|
||||||
{
|
{
|
||||||
Vector2 headPos = AnimController.GetLimb(LimbType.Head)?.body?.DrawPosition ?? DrawPosition + Vector2.UnitY * 100.0f;
|
Vector2 headPos = AnimController.GetLimb(LimbType.Head)?.body?.DrawPosition ?? DrawPosition + Vector2.UnitY * 100.0f;
|
||||||
@@ -963,7 +963,7 @@ namespace Barotrauma
|
|||||||
Vector2 healthBarPos = new Vector2(pos.X - 50, -pos.Y);
|
Vector2 healthBarPos = new Vector2(pos.X - 50, -pos.Y);
|
||||||
GUI.DrawProgressBar(spriteBatch, healthBarPos, new Vector2(100.0f, 15.0f),
|
GUI.DrawProgressBar(spriteBatch, healthBarPos, new Vector2(100.0f, 15.0f),
|
||||||
CharacterHealth.DisplayedVitality / MaxVitality,
|
CharacterHealth.DisplayedVitality / MaxVitality,
|
||||||
Color.Lerp(GUI.Style.Red, GUI.Style.Green, CharacterHealth.DisplayedVitality / MaxVitality) * 0.8f * hudInfoAlpha,
|
Color.Lerp(GUIStyle.Red, GUIStyle.Green, CharacterHealth.DisplayedVitality / MaxVitality) * 0.8f * hudInfoAlpha,
|
||||||
new Color(0.5f, 0.57f, 0.6f, 1.0f) * hudInfoAlpha);
|
new Color(0.5f, 0.57f, 0.6f, 1.0f) * hudInfoAlpha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -987,7 +987,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Color nameColor = GUI.Style.TextColor;
|
Color nameColor = GUIStyle.TextColorNormal;
|
||||||
if (Controlled != null && team != Controlled.TeamID)
|
if (Controlled != null && team != Controlled.TeamID)
|
||||||
{
|
{
|
||||||
if (TeamID == CharacterTeamType.FriendlyNPC)
|
if (TeamID == CharacterTeamType.FriendlyNPC)
|
||||||
@@ -996,13 +996,13 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nameColor = GUI.Style.Red;
|
nameColor = GUIStyle.Red;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nameColor;
|
return nameColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddMessage(string rawText, Color color, bool playSound, string identifier = null, int? value = null, float lifetime = 3.0f)
|
public void AddMessage(string rawText, Color color, bool playSound, Identifier identifier = default, int? value = null, float lifetime = 3.0f)
|
||||||
{
|
{
|
||||||
GUIMessage existingMessage = null;
|
GUIMessage existingMessage = null;
|
||||||
|
|
||||||
@@ -1089,12 +1089,12 @@ namespace Barotrauma
|
|||||||
matchingSounds.Clear();
|
matchingSounds.Clear();
|
||||||
foreach (var s in sounds)
|
foreach (var s in sounds)
|
||||||
{
|
{
|
||||||
if (s.Type == soundType && (s.Gender == Gender.None || (info != null && info.Gender == s.Gender)))
|
if (s.Type == soundType && (s.TagSet.None() || (info != null && s.TagSet.IsSubsetOf(info.Head.Preset.TagSet))))
|
||||||
{
|
{
|
||||||
matchingSounds.Add(s);
|
matchingSounds.Add(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var selectedSound = matchingSounds.GetRandom();
|
var selectedSound = matchingSounds.GetRandomUnsynced();
|
||||||
if (selectedSound?.Sound == null) { return; }
|
if (selectedSound?.Sound == null) { return; }
|
||||||
soundChannel = SoundPlayer.PlaySound(selectedSound.Sound, AnimController.WorldPosition, selectedSound.Volume, selectedSound.Range, hullGuess: CurrentHull, ignoreMuffling: selectedSound.IgnoreMuffling);
|
soundChannel = SoundPlayer.PlaySound(selectedSound.Sound, AnimController.WorldPosition, selectedSound.Volume, selectedSound.Range, hullGuess: CurrentHull, ignoreMuffling: selectedSound.IgnoreMuffling);
|
||||||
soundTimer = Params.SoundInterval;
|
soundTimer = Params.SoundInterval;
|
||||||
@@ -1117,7 +1117,7 @@ namespace Barotrauma
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Note that when a predicate is provided, the random option uses Linq.Where() extension method, which creates a new collection.
|
/// Note that when a predicate is provided, the random option uses Linq.Where() extension method, which creates a new collection.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public CharacterSound GetSound(Func<CharacterSound, bool> predicate = null, bool random = false) => random ? sounds.GetRandom(predicate) : sounds.FirstOrDefault(predicate);
|
public CharacterSound GetSound(Func<CharacterSound, bool> predicate = null, bool random = false) => random ? sounds.GetRandomUnsynced(predicate) : sounds.FirstOrDefault(predicate);
|
||||||
|
|
||||||
partial void ImplodeFX()
|
partial void ImplodeFX()
|
||||||
{
|
{
|
||||||
@@ -1151,19 +1151,11 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void OnMoneyChanged(int prevAmount, int newAmount)
|
partial void OnMoneyChanged(int prevAmount, int newAmount) { }
|
||||||
{
|
|
||||||
if (newAmount > prevAmount)
|
|
||||||
{
|
|
||||||
int increase = newAmount - prevAmount;
|
|
||||||
AddMessage("+" + TextManager.GetWithVariable("currencyformat", "[credits]", "[value]"),
|
|
||||||
GUI.Style.Yellow, playSound: this == Controlled, "money", increase);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
partial void OnTalentGiven(TalentPrefab talentPrefab)
|
partial void OnTalentGiven(TalentPrefab talentPrefab)
|
||||||
{
|
{
|
||||||
AddMessage(TextManager.Get("talentname." + talentPrefab.Identifier), GUI.Style.Yellow, playSound: this == Controlled);
|
AddMessage(TextManager.Get("talentname." + talentPrefab.Identifier).Value, GUIStyle.Yellow, playSound: this == Controlled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,23 +35,23 @@ namespace Barotrauma
|
|||||||
MinSize = new Point(100, 50),
|
MinSize = new Point(100, 50),
|
||||||
RelativeOffset = new Vector2(0.0f, 0.01f)
|
RelativeOffset = new Vector2(0.0f, 0.01f)
|
||||||
}, isHorizontal: false, childAnchor: Anchor.TopCenter);
|
}, isHorizontal: false, childAnchor: Anchor.TopCenter);
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.4f), TopContainer.RectTransform), character.DisplayName, textAlignment: Alignment.Center, textColor: GUI.Style.Red);
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.4f), TopContainer.RectTransform), character.DisplayName, textAlignment: Alignment.Center, textColor: GUIStyle.Red);
|
||||||
TopHealthBar = new GUIProgressBar(new RectTransform(new Vector2(1.0f, 0.6f), TopContainer.RectTransform)
|
TopHealthBar = new GUIProgressBar(new RectTransform(new Vector2(1.0f, 0.6f), TopContainer.RectTransform)
|
||||||
{
|
{
|
||||||
MinSize = new Point(100, HUDLayoutSettings.HealthBarArea.Size.Y)
|
MinSize = new Point(100, HUDLayoutSettings.HealthBarArea.Size.Y)
|
||||||
}, barSize: 0.0f, style: "CharacterHealthBarCentered")
|
}, barSize: 0.0f, style: "CharacterHealthBarCentered")
|
||||||
{
|
{
|
||||||
Color = GUI.Style.Red
|
Color = GUIStyle.Red
|
||||||
};
|
};
|
||||||
|
|
||||||
SideContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.05f), bossHealthContainer.RectTransform)
|
SideContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.05f), bossHealthContainer.RectTransform)
|
||||||
{
|
{
|
||||||
MinSize = new Point(80, 60)
|
MinSize = new Point(80, 60)
|
||||||
}, isHorizontal: false, childAnchor: Anchor.TopRight);
|
}, isHorizontal: false, childAnchor: Anchor.TopRight);
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.3f), SideContainer.RectTransform), character.DisplayName, textAlignment: Alignment.CenterRight, textColor: GUI.Style.Red);
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.3f), SideContainer.RectTransform), character.DisplayName, textAlignment: Alignment.CenterRight, textColor: GUIStyle.Red);
|
||||||
SideHealthBar = new GUIProgressBar(new RectTransform(new Vector2(1.0f, 0.7f), SideContainer.RectTransform), barSize: 0.0f, style: "CharacterHealthBar")
|
SideHealthBar = new GUIProgressBar(new RectTransform(new Vector2(1.0f, 0.7f), SideContainer.RectTransform), barSize: 0.0f, style: "CharacterHealthBar")
|
||||||
{
|
{
|
||||||
Color = GUI.Style.Red
|
Color = GUIStyle.Red
|
||||||
};
|
};
|
||||||
|
|
||||||
TopContainer.Visible = SideContainer.Visible = false;
|
TopContainer.Visible = SideContainer.Visible = false;
|
||||||
@@ -72,7 +72,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private static readonly List<BossHealthBar> bossHealthBars = new List<BossHealthBar>();
|
private static readonly List<BossHealthBar> bossHealthBars = new List<BossHealthBar>();
|
||||||
|
|
||||||
private static readonly Dictionary<string, string> cachedHudTexts = new Dictionary<string, string>();
|
private static readonly Dictionary<Identifier, LocalizedString> cachedHudTexts = new Dictionary<Identifier, LocalizedString>();
|
||||||
|
|
||||||
private static GUILayoutGroup bossHealthContainer;
|
private static GUILayoutGroup bossHealthContainer;
|
||||||
|
|
||||||
@@ -119,14 +119,12 @@ namespace Barotrauma
|
|||||||
!ConversationAction.FadeScreenToBlack;
|
!ConversationAction.FadeScreenToBlack;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetCachedHudText(string textTag, string keyBind)
|
public static LocalizedString GetCachedHudText(string textTag, InputType keyBind)
|
||||||
{
|
{
|
||||||
if (cachedHudTexts.TryGetValue(textTag + keyBind, out string text))
|
Identifier key = (textTag + keyBind).ToIdentifier();
|
||||||
{
|
if (cachedHudTexts.TryGetValue(key, out LocalizedString text)) { return text; }
|
||||||
return text;
|
text = TextManager.GetWithVariable(textTag, "[key]", GameSettings.CurrentConfig.KeyMap.KeyBindText(keyBind)).Value;
|
||||||
}
|
cachedHudTexts.Add(key, text);
|
||||||
text = TextManager.GetWithVariable(textTag, "[key]", keyBind);
|
|
||||||
cachedHudTexts.Add(textTag + keyBind, text);
|
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,24 +254,24 @@ namespace Barotrauma
|
|||||||
if (GameMain.GameSession?.CrewManager != null)
|
if (GameMain.GameSession?.CrewManager != null)
|
||||||
{
|
{
|
||||||
orderIndicatorCount.Clear();
|
orderIndicatorCount.Clear();
|
||||||
foreach (Pair<Order, float?> activeOrder in GameMain.GameSession.CrewManager.ActiveOrders)
|
foreach (CrewManager.ActiveOrder activeOrder in GameMain.GameSession.CrewManager.ActiveOrders)
|
||||||
{
|
{
|
||||||
if (!DrawIcon(activeOrder.First)) { continue; }
|
if (!DrawIcon(activeOrder.Order)) { continue; }
|
||||||
|
|
||||||
if (activeOrder.Second.HasValue)
|
if (activeOrder.FadeOutTime.HasValue)
|
||||||
{
|
{
|
||||||
DrawOrderIndicator(spriteBatch, cam, character, activeOrder.First, iconAlpha: MathHelper.Clamp(activeOrder.Second.Value / 10.0f, 0.2f, 1.0f));
|
DrawOrderIndicator(spriteBatch, cam, character, activeOrder.Order, iconAlpha: MathHelper.Clamp(activeOrder.FadeOutTime.Value / 10.0f, 0.2f, 1.0f));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
float iconAlpha = GetDistanceBasedIconAlpha(activeOrder.First.TargetSpatialEntity, maxDistance: 450.0f);
|
float iconAlpha = GetDistanceBasedIconAlpha(activeOrder.Order.TargetSpatialEntity, maxDistance: 450.0f);
|
||||||
if (iconAlpha <= 0.0f) { continue; }
|
if (iconAlpha <= 0.0f) { continue; }
|
||||||
DrawOrderIndicator(spriteBatch, cam, character, activeOrder.First,
|
DrawOrderIndicator(spriteBatch, cam, character, activeOrder.Order,
|
||||||
iconAlpha: iconAlpha, createOffset: false, scaleMultiplier: 0.5f, overrideAlpha: true);
|
iconAlpha: iconAlpha, createOffset: false, scaleMultiplier: 0.5f, overrideAlpha: true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (character.GetCurrentOrderWithTopPriority()?.Order is Order currentOrder && DrawIcon(currentOrder))
|
if (character.GetCurrentOrderWithTopPriority() is Order currentOrder && DrawIcon(currentOrder))
|
||||||
{
|
{
|
||||||
DrawOrderIndicator(spriteBatch, cam, character, currentOrder, 1.0f);
|
DrawOrderIndicator(spriteBatch, cam, character, currentOrder, 1.0f);
|
||||||
}
|
}
|
||||||
@@ -310,8 +308,8 @@ namespace Barotrauma
|
|||||||
if (!brokenItem.IsInteractable(character)) { continue; }
|
if (!brokenItem.IsInteractable(character)) { continue; }
|
||||||
float alpha = GetDistanceBasedIconAlpha(brokenItem);
|
float alpha = GetDistanceBasedIconAlpha(brokenItem);
|
||||||
if (alpha <= 0.0f) continue;
|
if (alpha <= 0.0f) continue;
|
||||||
GUI.DrawIndicator(spriteBatch, brokenItem.DrawPosition, cam, 100.0f, GUI.BrokenIcon,
|
GUI.DrawIndicator(spriteBatch, brokenItem.DrawPosition, cam, 100.0f, GUIStyle.BrokenIcon.Value.Sprite,
|
||||||
Color.Lerp(GUI.Style.Red, GUI.Style.Orange * 0.5f, brokenItem.Condition / brokenItem.MaxCondition) * alpha);
|
Color.Lerp(GUIStyle.Red, GUIStyle.Orange * 0.5f, brokenItem.Condition / brokenItem.MaxCondition) * alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
float GetDistanceBasedIconAlpha(ISpatialEntity target, float maxDistance = 1000.0f)
|
float GetDistanceBasedIconAlpha(ISpatialEntity target, float maxDistance = 1000.0f)
|
||||||
@@ -344,12 +342,12 @@ namespace Barotrauma
|
|||||||
circleSize = MathHelper.Clamp(circleSize, 45.0f, 100.0f) * Math.Min((focusedItemOverlayTimer - 1.0f) * 5.0f, 1.0f);
|
circleSize = MathHelper.Clamp(circleSize, 45.0f, 100.0f) * Math.Min((focusedItemOverlayTimer - 1.0f) * 5.0f, 1.0f);
|
||||||
if (circleSize > 0.0f)
|
if (circleSize > 0.0f)
|
||||||
{
|
{
|
||||||
Vector2 scale = new Vector2(circleSize / GUI.Style.FocusIndicator.FrameSize.X);
|
Vector2 scale = new Vector2(circleSize / GUIStyle.FocusIndicator.FrameSize.X);
|
||||||
GUI.Style.FocusIndicator.Draw(spriteBatch,
|
GUIStyle.FocusIndicator.Draw(spriteBatch,
|
||||||
(int)((focusedItemOverlayTimer - 1.0f) * GUI.Style.FocusIndicator.FrameCount * 3.0f),
|
(int)((focusedItemOverlayTimer - 1.0f) * GUIStyle.FocusIndicator.FrameCount * 3.0f),
|
||||||
circlePos,
|
circlePos,
|
||||||
Color.LightBlue * 0.3f,
|
Color.LightBlue * 0.3f,
|
||||||
origin: GUI.Style.FocusIndicator.FrameSize.ToVector2() / 2,
|
origin: GUIStyle.FocusIndicator.FrameSize.ToVector2() / 2,
|
||||||
rotate: (float)Timing.TotalTime,
|
rotate: (float)Timing.TotalTime,
|
||||||
scale: scale);
|
scale: scale);
|
||||||
}
|
}
|
||||||
@@ -367,8 +365,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
int dir = Math.Sign(focusedItem.WorldPosition.X - character.WorldPosition.X);
|
int dir = Math.Sign(focusedItem.WorldPosition.X - character.WorldPosition.X);
|
||||||
|
|
||||||
Vector2 textSize = GUI.Font.MeasureString(hudTexts.First().Text);
|
Vector2 textSize = GUIStyle.Font.MeasureString(hudTexts.First().Text);
|
||||||
Vector2 largeTextSize = GUI.SubHeadingFont.MeasureString(hudTexts.First().Text);
|
Vector2 largeTextSize = GUIStyle.SubHeadingFont.MeasureString(hudTexts.First().Text);
|
||||||
|
|
||||||
Vector2 startPos = cam.WorldToScreen(focusedItem.DrawPosition);
|
Vector2 startPos = cam.WorldToScreen(focusedItem.DrawPosition);
|
||||||
startPos.Y -= (hudTexts.Count + 1) * textSize.Y;
|
startPos.Y -= (hudTexts.Count + 1) * textSize.Y;
|
||||||
@@ -383,14 +381,14 @@ namespace Barotrauma
|
|||||||
|
|
||||||
float alpha = MathHelper.Clamp((focusedItemOverlayTimer - ItemOverlayDelay) * 2.0f, 0.0f, 1.0f);
|
float alpha = MathHelper.Clamp((focusedItemOverlayTimer - ItemOverlayDelay) * 2.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
GUI.DrawString(spriteBatch, textPos, hudTexts.First().Text, hudTexts.First().Color * alpha, Color.Black * alpha * 0.7f, 2, font: GUI.SubHeadingFont);
|
GUI.DrawString(spriteBatch, textPos, hudTexts.First().Text, hudTexts.First().Color * alpha, Color.Black * alpha * 0.7f, 2, font: GUIStyle.SubHeadingFont, ForceUpperCase.No);
|
||||||
startPos.X += dir * 10.0f * GUI.Scale;
|
startPos.X += dir * 10.0f * GUI.Scale;
|
||||||
textPos.X += dir * 10.0f * GUI.Scale;
|
textPos.X += dir * 10.0f * GUI.Scale;
|
||||||
textPos.Y += largeTextSize.Y;
|
textPos.Y += largeTextSize.Y;
|
||||||
foreach (ColoredText coloredText in hudTexts.Skip(1))
|
foreach (ColoredText coloredText in hudTexts.Skip(1))
|
||||||
{
|
{
|
||||||
if (dir == -1) textPos.X = (int)(startPos.X - GUI.SmallFont.MeasureString(coloredText.Text).X);
|
if (dir == -1) textPos.X = (int)(startPos.X - GUIStyle.SmallFont.MeasureString(coloredText.Text).X);
|
||||||
GUI.DrawString(spriteBatch, textPos, coloredText.Text, coloredText.Color * alpha, Color.Black * alpha * 0.7f, 2, GUI.SmallFont);
|
GUI.DrawString(spriteBatch, textPos, coloredText.Text, coloredText.Color * alpha, Color.Black * alpha * 0.7f, 2, GUIStyle.SmallFont);
|
||||||
textPos.Y += textSize.Y;
|
textPos.Y += textSize.Y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -405,7 +403,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (npc.CampaignInteractionType == CampaignMode.InteractionType.None || npc.Submarine != character.Submarine || npc.IsDead || npc.IsIncapacitated) { continue; }
|
if (npc.CampaignInteractionType == CampaignMode.InteractionType.None || npc.Submarine != character.Submarine || npc.IsDead || npc.IsIncapacitated) { continue; }
|
||||||
|
|
||||||
var iconStyle = GUI.Style.GetComponentStyle("CampaignInteractionIcon." + npc.CampaignInteractionType);
|
var iconStyle = GUIStyle.GetComponentStyle("CampaignInteractionIcon." + npc.CampaignInteractionType);
|
||||||
if (iconStyle == null) { continue; }
|
if (iconStyle == null) { continue; }
|
||||||
Range<float> visibleRange = new Range<float>(npc.CurrentHull == Character.Controlled.CurrentHull ? 500.0f : 100.0f, float.PositiveInfinity);
|
Range<float> visibleRange = new Range<float>(npc.CurrentHull == Character.Controlled.CurrentHull ? 500.0f : 100.0f, float.PositiveInfinity);
|
||||||
if (npc.CampaignInteractionType == CampaignMode.InteractionType.Examine)
|
if (npc.CampaignInteractionType == CampaignMode.InteractionType.Examine)
|
||||||
@@ -486,12 +484,14 @@ namespace Barotrauma
|
|||||||
(int)(HUDLayoutSettings.BottomRightInfoArea.Y + HUDLayoutSettings.BottomRightInfoArea.Height * 0.1f),
|
(int)(HUDLayoutSettings.BottomRightInfoArea.Y + HUDLayoutSettings.BottomRightInfoArea.Height * 0.1f),
|
||||||
(int)(HUDLayoutSettings.BottomRightInfoArea.Width / 2),
|
(int)(HUDLayoutSettings.BottomRightInfoArea.Width / 2),
|
||||||
(int)(HUDLayoutSettings.BottomRightInfoArea.Height * 0.7f)), character.Info.IsDisguisedAsAnother);
|
(int)(HUDLayoutSettings.BottomRightInfoArea.Height * 0.7f)), character.Info.IsDisguisedAsAnother);
|
||||||
character.Info.DrawPortrait(spriteBatch, HUDLayoutSettings.PortraitArea.Location.ToVector2(), new Vector2(-12 * GUI.Scale, 4 * GUI.Scale), targetWidth: HUDLayoutSettings.PortraitArea.Width, true, character.Info.IsDisguisedAsAnother);
|
float yOffset = (GameMain.GameSession?.Campaign is MultiPlayerCampaign ? -10 : 4) * GUI.Scale;
|
||||||
|
character.Info.DrawPortrait(spriteBatch, HUDLayoutSettings.PortraitArea.Location.ToVector2(), new Vector2(-12 * GUI.Scale, yOffset), targetWidth: HUDLayoutSettings.PortraitArea.Width, true, character.Info.IsDisguisedAsAnother);
|
||||||
|
character.Info.DrawForeground(spriteBatch);
|
||||||
}
|
}
|
||||||
mouseOnPortrait = HUDLayoutSettings.BottomRightInfoArea.Contains(PlayerInput.MousePosition) && !character.ShouldLockHud();
|
mouseOnPortrait = HUDLayoutSettings.BottomRightInfoArea.Contains(PlayerInput.MousePosition) && !character.ShouldLockHud();
|
||||||
if (mouseOnPortrait)
|
if (mouseOnPortrait)
|
||||||
{
|
{
|
||||||
GUI.UIGlow.Draw(spriteBatch, HUDLayoutSettings.BottomRightInfoArea, GUI.Style.Green * 0.5f);
|
GUIStyle.UIGlow.Draw(spriteBatch, HUDLayoutSettings.BottomRightInfoArea, GUIStyle.Green * 0.5f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ShouldDrawInventory(character))
|
if (ShouldDrawInventory(character))
|
||||||
@@ -555,28 +555,28 @@ namespace Barotrauma
|
|||||||
|
|
||||||
string focusName = character.FocusedCharacter.Info == null ? character.FocusedCharacter.DisplayName : character.FocusedCharacter.Info.DisplayName;
|
string focusName = character.FocusedCharacter.Info == null ? character.FocusedCharacter.DisplayName : character.FocusedCharacter.Info.DisplayName;
|
||||||
Vector2 textPos = startPos;
|
Vector2 textPos = startPos;
|
||||||
Vector2 textSize = GUI.Font.MeasureString(focusName);
|
Vector2 textSize = GUIStyle.Font.MeasureString(focusName);
|
||||||
Vector2 largeTextSize = GUI.SubHeadingFont.MeasureString(focusName);
|
Vector2 largeTextSize = GUIStyle.SubHeadingFont.MeasureString(focusName);
|
||||||
|
|
||||||
textPos -= new Vector2(textSize.X / 2, textSize.Y);
|
textPos -= new Vector2(textSize.X / 2, textSize.Y);
|
||||||
|
|
||||||
Color nameColor = character.FocusedCharacter.GetNameColor();
|
Color nameColor = character.FocusedCharacter.GetNameColor();
|
||||||
GUI.DrawString(spriteBatch, textPos, focusName, nameColor, Color.Black * 0.7f, 2, GUI.SubHeadingFont);
|
GUI.DrawString(spriteBatch, textPos, focusName, nameColor, Color.Black * 0.7f, 2, GUIStyle.SubHeadingFont, ForceUpperCase.No);
|
||||||
textPos.X += 10.0f * GUI.Scale;
|
textPos.X += 10.0f * GUI.Scale;
|
||||||
textPos.Y += GUI.SubHeadingFont.MeasureString(focusName).Y;
|
textPos.Y += GUIStyle.SubHeadingFont.MeasureString(focusName).Y;
|
||||||
|
|
||||||
if (!character.FocusedCharacter.IsIncapacitated && character.FocusedCharacter.IsPet)
|
if (!character.FocusedCharacter.IsIncapacitated && character.FocusedCharacter.IsPet)
|
||||||
{
|
{
|
||||||
GUI.DrawString(spriteBatch, textPos, GetCachedHudText("PlayHint", GameMain.Config.KeyBindText(InputType.Use)),
|
GUI.DrawString(spriteBatch, textPos, GetCachedHudText("PlayHint", InputType.Use),
|
||||||
GUI.Style.Green, Color.Black, 2, GUI.SmallFont);
|
GUIStyle.Green, Color.Black, 2, GUIStyle.SmallFont);
|
||||||
textPos.Y += largeTextSize.Y;
|
textPos.Y += largeTextSize.Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (character.FocusedCharacter.CanBeDragged)
|
if (character.FocusedCharacter.CanBeDragged)
|
||||||
{
|
{
|
||||||
string text = character.CanEat ? "EatHint" : "GrabHint";
|
string text = character.CanEat ? "EatHint" : "GrabHint";
|
||||||
GUI.DrawString(spriteBatch, textPos, GetCachedHudText(text, GameMain.Config.KeyBindText(InputType.Grab)),
|
GUI.DrawString(spriteBatch, textPos, GetCachedHudText(text, InputType.Grab),
|
||||||
GUI.Style.Green, Color.Black, 2, GUI.SmallFont);
|
GUIStyle.Green, Color.Black, 2, GUIStyle.SmallFont);
|
||||||
textPos.Y += largeTextSize.Y;
|
textPos.Y += largeTextSize.Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -585,13 +585,13 @@ namespace Barotrauma
|
|||||||
character.FocusedCharacter.CharacterHealth.UseHealthWindow &&
|
character.FocusedCharacter.CharacterHealth.UseHealthWindow &&
|
||||||
character.CanInteractWith(character.FocusedCharacter, 160f, false))
|
character.CanInteractWith(character.FocusedCharacter, 160f, false))
|
||||||
{
|
{
|
||||||
GUI.DrawString(spriteBatch, textPos, GetCachedHudText("HealHint", GameMain.Config.KeyBindText(InputType.Health)),
|
GUI.DrawString(spriteBatch, textPos, GetCachedHudText("HealHint", InputType.Health),
|
||||||
GUI.Style.Green, Color.Black, 2, GUI.SmallFont);
|
GUIStyle.Green, Color.Black, 2, GUIStyle.SmallFont);
|
||||||
textPos.Y += textSize.Y;
|
textPos.Y += textSize.Y;
|
||||||
}
|
}
|
||||||
if (!string.IsNullOrEmpty(character.FocusedCharacter.customInteractHUDText) && character.FocusedCharacter.AllowCustomInteract)
|
if (!character.FocusedCharacter.CustomInteractHUDText.IsNullOrEmpty() && character.FocusedCharacter.AllowCustomInteract)
|
||||||
{
|
{
|
||||||
GUI.DrawString(spriteBatch, textPos, character.FocusedCharacter.customInteractHUDText, GUI.Style.Green, Color.Black, 2, GUI.SmallFont);
|
GUI.DrawString(spriteBatch, textPos, character.FocusedCharacter.CustomInteractHUDText, GUIStyle.Green, Color.Black, 2, GUIStyle.SmallFont);
|
||||||
textPos.Y += textSize.Y;
|
textPos.Y += textSize.Y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using Microsoft.Xna.Framework.Graphics;
|
|||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using Barotrauma.IO;
|
using Barotrauma.IO;
|
||||||
using Barotrauma.Items.Components;
|
using Barotrauma.Items.Components;
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -34,17 +35,17 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public static void Init()
|
public static void Init()
|
||||||
{
|
{
|
||||||
infoAreaPortraitBG = GUI.Style.GetComponentStyle("InfoAreaPortraitBG")?.GetDefaultSprite();
|
infoAreaPortraitBG = GUIStyle.GetComponentStyle("InfoAreaPortraitBG")?.GetDefaultSprite();
|
||||||
new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(833, 298, 142, 98), null, 0);
|
new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(833, 298, 142, 98), null, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void LoadHeadSpriteProjectSpecific(XElement limbElement)
|
partial void LoadHeadSpriteProjectSpecific(ContentXElement limbElement)
|
||||||
{
|
{
|
||||||
XElement maskElement = limbElement.Element("tintmask");
|
ContentXElement maskElement = limbElement.GetChildElement("tintmask");
|
||||||
if (maskElement != null)
|
if (maskElement != null)
|
||||||
{
|
{
|
||||||
string tintMaskPath = maskElement.GetAttributeString("texture", "");
|
ContentPath tintMaskPath = maskElement.GetAttributeContentPath("texture");
|
||||||
if (!string.IsNullOrWhiteSpace(tintMaskPath))
|
if (!tintMaskPath.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
tintMask = new Sprite(maskElement, file: Limb.GetSpritePath(tintMaskPath, this));
|
tintMask = new Sprite(maskElement, file: Limb.GetSpritePath(tintMaskPath, this));
|
||||||
tintHighlightThreshold = maskElement.GetAttributeFloat("highlightthreshold", 0.6f);
|
tintHighlightThreshold = maskElement.GetAttributeFloat("highlightthreshold", 0.6f);
|
||||||
@@ -66,7 +67,7 @@ namespace Barotrauma
|
|||||||
new GUICustomComponent(new RectTransform(new Vector2(0.425f, 1.0f), headerArea.RectTransform),
|
new GUICustomComponent(new RectTransform(new Vector2(0.425f, 1.0f), headerArea.RectTransform),
|
||||||
onDraw: (sb, component) => DrawInfoFrameCharacterIcon(sb, component.Rect));
|
onDraw: (sb, component) => DrawInfoFrameCharacterIcon(sb, component.Rect));
|
||||||
|
|
||||||
ScalableFont font = paddedFrame.Rect.Width < 280 ? GUI.SmallFont : GUI.Font;
|
GUIFont font = paddedFrame.Rect.Width < 280 ? GUIStyle.SmallFont : GUIStyle.Font;
|
||||||
|
|
||||||
var headerTextArea = new GUILayoutGroup(new RectTransform(new Vector2(0.575f, 1.0f), headerArea.RectTransform))
|
var headerTextArea = new GUILayoutGroup(new RectTransform(new Vector2(0.575f, 1.0f), headerArea.RectTransform))
|
||||||
{
|
{
|
||||||
@@ -77,9 +78,9 @@ namespace Barotrauma
|
|||||||
Color? nameColor = null;
|
Color? nameColor = null;
|
||||||
if (Job != null) { nameColor = Job.Prefab.UIColor; }
|
if (Job != null) { nameColor = Job.Prefab.UIColor; }
|
||||||
|
|
||||||
GUITextBlock characterNameBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), headerTextArea.RectTransform), ToolBox.LimitString(Name, GUI.Font, headerTextArea.Rect.Width), textColor: nameColor, font: GUI.Font)
|
GUITextBlock characterNameBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), headerTextArea.RectTransform), ToolBox.LimitString(Name, GUIStyle.Font, headerTextArea.Rect.Width), textColor: nameColor, font: GUIStyle.Font)
|
||||||
{
|
{
|
||||||
ForceUpperCase = true,
|
ForceUpperCase = ForceUpperCase.Yes,
|
||||||
Padding = Vector4.Zero
|
Padding = Vector4.Zero
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -98,9 +99,11 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (personalityTrait != null)
|
if (PersonalityTrait != null)
|
||||||
{
|
{
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), headerTextArea.RectTransform), TextManager.AddPunctuation(':', TextManager.Get("PersonalityTrait"), TextManager.Get("personalitytrait." + personalityTrait.Name.Replace(" ", ""))), font: font)
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), headerTextArea.RectTransform),
|
||||||
|
TextManager.AddPunctuation(':', TextManager.Get("PersonalityTrait"), TextManager.Get("personalitytrait." + PersonalityTrait.Name.Replace(" ".ToIdentifier(), "".ToIdentifier()))),
|
||||||
|
font: font)
|
||||||
{
|
{
|
||||||
Padding = Vector4.Zero
|
Padding = Vector4.Zero
|
||||||
};
|
};
|
||||||
@@ -148,10 +151,10 @@ namespace Barotrauma
|
|||||||
Stretch = true
|
Stretch = true
|
||||||
};
|
};
|
||||||
|
|
||||||
string deadDescription = TextManager.AddPunctuation(':', TextManager.Get("deceased") + "\n" + Character.CauseOfDeath.Affliction?.CauseOfDeathDescription ??
|
LocalizedString deadDescription = TextManager.AddPunctuation(':', TextManager.Get("deceased") + "\n" + Character.CauseOfDeath.Affliction?.CauseOfDeathDescription ??
|
||||||
TextManager.AddPunctuation(':', TextManager.Get("CauseOfDeath"), TextManager.Get("CauseOfDeath." + Character.CauseOfDeath.Type.ToString())));
|
TextManager.AddPunctuation(':', TextManager.Get("CauseOfDeath"), TextManager.Get("CauseOfDeath." + Character.CauseOfDeath.Type.ToString())));
|
||||||
|
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), deadArea.RectTransform), deadDescription, textColor: GUI.Style.Red, font: font, textAlignment: Alignment.TopLeft) { Padding = Vector4.Zero };
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), deadArea.RectTransform), deadDescription, textColor: GUIStyle.Red, font: font, textAlignment: Alignment.TopLeft) { Padding = Vector4.Zero };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (returnParent)
|
if (returnParent)
|
||||||
@@ -182,13 +185,13 @@ namespace Barotrauma
|
|||||||
Color? textColor = null;
|
Color? textColor = null;
|
||||||
if (Job != null) { textColor = Job.Prefab.UIColor; }
|
if (Job != null) { textColor = Job.Prefab.UIColor; }
|
||||||
|
|
||||||
GUITextBlock textBlock = new GUITextBlock(new RectTransform(Vector2.One, frame.RectTransform, Anchor.CenterLeft) { AbsoluteOffset = new Point(40, 0) }, text, textColor: textColor, font: GUI.SmallFont);
|
GUITextBlock textBlock = new GUITextBlock(new RectTransform(Vector2.One, frame.RectTransform, Anchor.CenterLeft) { AbsoluteOffset = new Point(40, 0) }, text, textColor: textColor, font: GUIStyle.SmallFont);
|
||||||
new GUICustomComponent(new RectTransform(new Point(frame.Rect.Height, frame.Rect.Height), frame.RectTransform, Anchor.CenterLeft) { IsFixedSize = false },
|
new GUICustomComponent(new RectTransform(new Point(frame.Rect.Height, frame.Rect.Height), frame.RectTransform, Anchor.CenterLeft) { IsFixedSize = false },
|
||||||
onDraw: (sb, component) => DrawIcon(sb, component.Rect.Center.ToVector2(), targetAreaSize: component.Rect.Size.ToVector2()));
|
onDraw: (sb, component) => DrawIcon(sb, component.Rect.Center.ToVector2(), targetAreaSize: component.Rect.Size.ToVector2()));
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void OnSkillChanged(string skillIdentifier, float prevLevel, float newLevel)
|
partial void OnSkillChanged(Identifier skillIdentifier, float prevLevel, float newLevel)
|
||||||
{
|
{
|
||||||
if (TeamID == CharacterTeamType.FriendlyNPC) { return; }
|
if (TeamID == CharacterTeamType.FriendlyNPC) { return; }
|
||||||
if (Character.Controlled != null && Character.Controlled.TeamID != TeamID) { return; }
|
if (Character.Controlled != null && Character.Controlled.TeamID != TeamID) { return; }
|
||||||
@@ -199,9 +202,10 @@ namespace Barotrauma
|
|||||||
if ((int)newLevel > (int)prevLevel)
|
if ((int)newLevel > (int)prevLevel)
|
||||||
{
|
{
|
||||||
int increase = Math.Max((int)newLevel - (int)prevLevel, 1);
|
int increase = Math.Max((int)newLevel - (int)prevLevel, 1);
|
||||||
|
|
||||||
Character?.AddMessage(
|
Character?.AddMessage(
|
||||||
"+[value] "+ TextManager.Get("SkillName." + skillIdentifier),
|
"+[value] "+ TextManager.Get("SkillName." + skillIdentifier).Value,
|
||||||
specialIncrease ? GUI.Style.Orange : GUI.Style.Green,
|
specialIncrease ? GUIStyle.Orange : GUIStyle.Green,
|
||||||
playSound: Character == Character.Controlled, skillIdentifier, increase);
|
playSound: Character == Character.Controlled, skillIdentifier, increase);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -216,8 +220,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
int increase = newAmount - prevAmount;
|
int increase = newAmount - prevAmount;
|
||||||
Character?.AddMessage(
|
Character?.AddMessage(
|
||||||
"+[value] " + TextManager.Get("experienceshort"),
|
"+[value] " + TextManager.Get("experienceshort").Value,
|
||||||
GUI.Style.Blue, playSound: Character == Character.Controlled, "exp", increase);
|
GUIStyle.Blue, playSound: Character == Character.Controlled, "exp".ToIdentifier(), increase);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,9 +231,13 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (idCard.StoredOwnerAppearance.JobPrefab == null || idCard.StoredOwnerAppearance.Portrait == null)
|
if (idCard.StoredOwnerAppearance.JobPrefab == null || idCard.StoredOwnerAppearance.Portrait == null)
|
||||||
{
|
{
|
||||||
string[] readTags = idCard.Item.Tags.Split(',');
|
var readTags = idCard.Item.Tags.Split(',')
|
||||||
|
.Where(s => s.Contains(':'))
|
||||||
|
.Select(s => s.Split(':'))
|
||||||
|
.Select(s => (s[0].ToIdentifier(),s[1]))
|
||||||
|
.ToImmutableDictionary();
|
||||||
|
|
||||||
if (readTags.Length == 0) { return; }
|
if (readTags.None()) { return; }
|
||||||
|
|
||||||
if (idCard.StoredOwnerAppearance.JobPrefab == null)
|
if (idCard.StoredOwnerAppearance.JobPrefab == null)
|
||||||
{
|
{
|
||||||
@@ -238,7 +246,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (idCard.StoredOwnerAppearance.Portrait == null)
|
if (idCard.StoredOwnerAppearance.Portrait == null)
|
||||||
{
|
{
|
||||||
idCard.StoredOwnerAppearance.ExtractAppearance(this, readTags);
|
idCard.StoredOwnerAppearance.ExtractAppearance(this, idCard);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,17 +275,17 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
LoadHeadAttachments();
|
LoadHeadAttachments();
|
||||||
}
|
}
|
||||||
FaceAttachment?.Elements("sprite").ForEach(s => attachmentSprites.Add(new WearableSprite(s, WearableType.FaceAttachment)));
|
Head.FaceAttachment?.GetChildElements("sprite").ForEach(s => attachmentSprites.Add(new WearableSprite(s, WearableType.FaceAttachment)));
|
||||||
BeardElement?.Elements("sprite").ForEach(s => attachmentSprites.Add(new WearableSprite(s, WearableType.Beard)));
|
Head.BeardElement?.GetChildElements("sprite").ForEach(s => attachmentSprites.Add(new WearableSprite(s, WearableType.Beard)));
|
||||||
MoustacheElement?.Elements("sprite").ForEach(s => attachmentSprites.Add(new WearableSprite(s, WearableType.Moustache)));
|
Head.MoustacheElement?.GetChildElements("sprite").ForEach(s => attachmentSprites.Add(new WearableSprite(s, WearableType.Moustache)));
|
||||||
HairElement?.Elements("sprite").ForEach(s => attachmentSprites.Add(new WearableSprite(s, WearableType.Hair)));
|
Head.HairElement?.GetChildElements("sprite").ForEach(s => attachmentSprites.Add(new WearableSprite(s, WearableType.Hair)));
|
||||||
if (omitJob)
|
if (omitJob)
|
||||||
{
|
{
|
||||||
JobPrefab.NoJobElement?.Element("PortraitClothing")?.Elements("sprite").ForEach(s => attachmentSprites.Add(new WearableSprite(s, WearableType.JobIndicator)));
|
JobPrefab.NoJobElement?.GetChildElement("PortraitClothing")?.GetChildElements("sprite").ForEach(s => attachmentSprites.Add(new WearableSprite(s, WearableType.JobIndicator)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Job?.Prefab.ClothingElement?.Elements("sprite").ForEach(s => attachmentSprites.Add(new WearableSprite(s, WearableType.JobIndicator)));
|
Job?.Prefab.ClothingElement?.GetChildElements("sprite").ForEach(s => attachmentSprites.Add(new WearableSprite(s, WearableType.JobIndicator)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,7 +296,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (sprite == null) { return; }
|
if (sprite == null) { return; }
|
||||||
if (Head.SheetIndex == null) { return; }
|
if (Head.SheetIndex == null) { return; }
|
||||||
Point location = CalculateOffset(sprite, Head.SheetIndex.Value.ToPoint());
|
Point location = CalculateOffset(sprite, Head.SheetIndex.ToPoint());
|
||||||
sprite.SourceRect = new Rectangle(location, sprite.SourceRect.Size);
|
sprite.SourceRect = new Rectangle(location, sprite.SourceRect.Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,6 +309,32 @@ namespace Barotrauma
|
|||||||
HUDLayoutSettings.BottomRightInfoArea.Height / (float)infoAreaPortraitBG.SourceRect.Height));
|
HUDLayoutSettings.BottomRightInfoArea.Height / (float)infoAreaPortraitBG.SourceRect.Height));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void DrawForeground(SpriteBatch spriteBatch)
|
||||||
|
{
|
||||||
|
if (Character is null || GameMain.IsSingleplayer) { return; }
|
||||||
|
const int million = 1000000;
|
||||||
|
int xfraction = (int)(HUDLayoutSettings.BottomRightInfoArea.Width * 0.2f);
|
||||||
|
int yoffset = GUI.IntScale(6);
|
||||||
|
|
||||||
|
int walletAmount = Character.Wallet.Balance;
|
||||||
|
|
||||||
|
LocalizedString str = walletAmount >= million ? TextManager.Get("crewwallet.balance.toomuchtoshow") : TextManager.FormatCurrency(walletAmount);
|
||||||
|
Vector2 size = GUIStyle.Font.MeasureString(str);
|
||||||
|
int barHeight = GUI.IntScale(18);
|
||||||
|
|
||||||
|
Rectangle barRect = new Rectangle((int)(HUDLayoutSettings.BottomRightInfoArea.X + xfraction / 2.5f), HUDLayoutSettings.BottomRightInfoArea.Bottom - barHeight - yoffset, HUDLayoutSettings.BottomRightInfoArea.Width - xfraction, barHeight);
|
||||||
|
float textScale = Math.Max(0.1f, Math.Min(barRect.Width / size.X, barRect.Height / size.Y)) - 0.01f;
|
||||||
|
|
||||||
|
GUIStyle.WalletPortraitBG.Draw(spriteBatch, barRect, Color.White);
|
||||||
|
|
||||||
|
int iconSize = GUI.IntScale(28);
|
||||||
|
int iconXOffset = iconSize / 2;
|
||||||
|
Rectangle iconRect = new Rectangle(barRect.Right - iconXOffset, barRect.Top - iconSize / 4, iconSize, iconSize);
|
||||||
|
GUIStyle.CrewWalletIconSmall.Draw(spriteBatch, iconRect, Color.White);
|
||||||
|
var (scaledTextSizeX, scaledTextSizeY) = size * textScale;
|
||||||
|
GUIStyle.Font.DrawString(spriteBatch, str, new Vector2(barRect.Right - iconXOffset - scaledTextSizeX - GUI.IntScale(4), barRect.Center.Y - scaledTextSizeY / 2), GUIStyle.TextColorNormal, 0f, Vector2.Zero, textScale, SpriteEffects.None, 0f);
|
||||||
|
}
|
||||||
|
|
||||||
public void DrawPortrait(SpriteBatch spriteBatch, Vector2 screenPos, Vector2 offset, float targetWidth, bool flip = false, bool evaluateDisguise = false)
|
public void DrawPortrait(SpriteBatch spriteBatch, Vector2 screenPos, Vector2 offset, float targetWidth, bool flip = false, bool evaluateDisguise = false)
|
||||||
{
|
{
|
||||||
if (evaluateDisguise && IsDisguised) { return; }
|
if (evaluateDisguise && IsDisguised) { return; }
|
||||||
@@ -414,19 +448,16 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
var currEffect = spriteBatch.GetCurrentEffect();
|
var currEffect = spriteBatch.GetCurrentEffect();
|
||||||
float scale = Math.Min(targetAreaSize.X / headSprite.size.X, targetAreaSize.Y / headSprite.size.Y);
|
float scale = Math.Min(targetAreaSize.X / headSprite.size.X, targetAreaSize.Y / headSprite.size.Y);
|
||||||
if (Head.SheetIndex.HasValue)
|
headSprite.SourceRect = new Rectangle(CalculateOffset(headSprite, Head.SheetIndex.ToPoint()), headSprite.SourceRect.Size);
|
||||||
{
|
|
||||||
headSprite.SourceRect = new Rectangle(CalculateOffset(headSprite, Head.SheetIndex.Value.ToPoint()), headSprite.SourceRect.Size);
|
|
||||||
}
|
|
||||||
SetHeadEffect(spriteBatch);
|
SetHeadEffect(spriteBatch);
|
||||||
headSprite.Draw(spriteBatch, screenPos, scale: scale, color: SkinColor);
|
headSprite.Draw(spriteBatch, screenPos, scale: scale, color: Head.SkinColor);
|
||||||
if (AttachmentSprites != null)
|
if (AttachmentSprites != null)
|
||||||
{
|
{
|
||||||
float depthStep = 0.000001f;
|
float depthStep = 0.000001f;
|
||||||
foreach (var attachment in AttachmentSprites)
|
foreach (var attachment in AttachmentSprites)
|
||||||
{
|
{
|
||||||
SetAttachmentEffect(spriteBatch, attachment);
|
SetAttachmentEffect(spriteBatch, attachment);
|
||||||
DrawAttachmentSprite(spriteBatch, attachment, headSprite, Head.SheetIndex, screenPos, scale, depthStep, GetAttachmentColor(attachment, HairColor, FacialHairColor));
|
DrawAttachmentSprite(spriteBatch, attachment, headSprite, Head.SheetIndex, screenPos, scale, depthStep, GetAttachmentColor(attachment, Head.HairColor, Head.FacialHairColor));
|
||||||
depthStep += depthStep;
|
depthStep += depthStep;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -479,14 +510,17 @@ namespace Barotrauma
|
|||||||
attachment.Sprite.Draw(spriteBatch, drawPos, color ?? Color.White, origin, rotate: 0, scale: scale, depth: depth, spriteEffect: spriteEffects);
|
attachment.Sprite.Draw(spriteBatch, drawPos, color ?? Color.White, origin, rotate: 0, scale: scale, depth: depth, spriteEffect: spriteEffects);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CharacterInfo ClientRead(string speciesName, IReadMessage inc)
|
public static CharacterInfo ClientRead(Identifier speciesName, IReadMessage inc)
|
||||||
{
|
{
|
||||||
ushort infoID = inc.ReadUInt16();
|
ushort infoID = inc.ReadUInt16();
|
||||||
string newName = inc.ReadString();
|
string newName = inc.ReadString();
|
||||||
string originalName = inc.ReadString();
|
string originalName = inc.ReadString();
|
||||||
int gender = inc.ReadByte();
|
int tagCount = inc.ReadByte();
|
||||||
int race = inc.ReadByte();
|
HashSet<Identifier> tagSet = new HashSet<Identifier>();
|
||||||
int headSpriteID = inc.ReadByte();
|
for (int i = 0; i < tagCount; i++)
|
||||||
|
{
|
||||||
|
tagSet.Add(inc.ReadIdentifier());
|
||||||
|
}
|
||||||
int hairIndex = inc.ReadByte();
|
int hairIndex = inc.ReadByte();
|
||||||
int beardIndex = inc.ReadByte();
|
int beardIndex = inc.ReadByte();
|
||||||
int moustacheIndex = inc.ReadByte();
|
int moustacheIndex = inc.ReadByte();
|
||||||
@@ -500,14 +534,14 @@ namespace Barotrauma
|
|||||||
int variant = inc.ReadByte();
|
int variant = inc.ReadByte();
|
||||||
|
|
||||||
JobPrefab jobPrefab = null;
|
JobPrefab jobPrefab = null;
|
||||||
Dictionary<string, float> skillLevels = new Dictionary<string, float>();
|
Dictionary<Identifier, float> skillLevels = new Dictionary<Identifier, float>();
|
||||||
if (!string.IsNullOrEmpty(jobIdentifier))
|
if (!string.IsNullOrEmpty(jobIdentifier))
|
||||||
{
|
{
|
||||||
jobPrefab = JobPrefab.Get(jobIdentifier);
|
jobPrefab = JobPrefab.Get(jobIdentifier);
|
||||||
byte skillCount = inc.ReadByte();
|
byte skillCount = inc.ReadByte();
|
||||||
for (int i = 0; i < skillCount; i++)
|
for (int i = 0; i < skillCount; i++)
|
||||||
{
|
{
|
||||||
string skillIdentifier = inc.ReadString();
|
Identifier skillIdentifier = inc.ReadIdentifier();
|
||||||
float skillLevel = inc.ReadSingle();
|
float skillLevel = inc.ReadSingle();
|
||||||
skillLevels.Add(skillIdentifier, skillLevel);
|
skillLevels.Add(skillIdentifier, skillLevel);
|
||||||
}
|
}
|
||||||
@@ -518,14 +552,14 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
ID = infoID,
|
ID = infoID,
|
||||||
};
|
};
|
||||||
ch.RecreateHead(headSpriteID,(Race)race, (Gender)gender, hairIndex, beardIndex, moustacheIndex, faceAttachmentIndex);
|
ch.RecreateHead(tagSet.ToImmutableHashSet(), hairIndex, beardIndex, moustacheIndex, faceAttachmentIndex);
|
||||||
ch.SkinColor = skinColor;
|
ch.Head.SkinColor = skinColor;
|
||||||
ch.HairColor = hairColor;
|
ch.Head.HairColor = hairColor;
|
||||||
ch.FacialHairColor = facialHairColor;
|
ch.Head.FacialHairColor = facialHairColor;
|
||||||
ch.SetPersonalityTrait();
|
ch.SetPersonalityTrait();
|
||||||
if (ch.Job != null)
|
if (ch.Job != null)
|
||||||
{
|
{
|
||||||
foreach (KeyValuePair<string, float> skill in skillLevels)
|
foreach (KeyValuePair<Identifier, float> skill in skillLevels)
|
||||||
{
|
{
|
||||||
Skill matchingSkill = ch.Job.Skills.Find(s => s.Identifier == skill.Key);
|
Skill matchingSkill = ch.Job.Skills.Find(s => s.Identifier == skill.Key);
|
||||||
if (matchingSkill == null)
|
if (matchingSkill == null)
|
||||||
@@ -538,17 +572,8 @@ namespace Barotrauma
|
|||||||
ch.Job.Skills.RemoveAll(s => !skillLevels.ContainsKey(s.Identifier));
|
ch.Job.Skills.RemoveAll(s => !skillLevels.ContainsKey(s.Identifier));
|
||||||
}
|
}
|
||||||
|
|
||||||
byte savedStatValueCount = inc.ReadByte();
|
|
||||||
for (int i = 0; i < savedStatValueCount; i++)
|
|
||||||
{
|
|
||||||
int statType = inc.ReadByte();
|
|
||||||
string statIdentifier = inc.ReadString();
|
|
||||||
float statValue = inc.ReadSingle();
|
|
||||||
bool removeOnDeath = inc.ReadBoolean();
|
|
||||||
ch.ChangeSavedStatValue((StatTypes)statType, statValue, statIdentifier, removeOnDeath);
|
|
||||||
}
|
|
||||||
ch.ExperiencePoints = inc.ReadUInt16();
|
ch.ExperiencePoints = inc.ReadUInt16();
|
||||||
ch.AdditionalTalentPoints = inc.ReadUInt16();
|
ch.AdditionalTalentPoints = inc.ReadRangedInteger(0, MaxAdditionalTalentPoints);
|
||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -605,12 +630,12 @@ namespace Barotrauma
|
|||||||
{ RelativeOffset = new Vector2(-0.01f, 0.0f) });
|
{ RelativeOffset = new Vector2(-0.01f, 0.0f) });
|
||||||
}
|
}
|
||||||
|
|
||||||
RectTransform createItemRectTransform(string labelTag, float width = 0.6f)
|
RectTransform createItemRectTransform(Identifier labelTag, float width = 0.6f)
|
||||||
{
|
{
|
||||||
var layoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.166f), content.RectTransform));
|
var layoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.166f), content.RectTransform));
|
||||||
|
|
||||||
var label = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), layoutGroup.RectTransform),
|
var label = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), layoutGroup.RectTransform),
|
||||||
TextManager.Get(labelTag), font: GUI.SubHeadingFont);
|
TextManager.Get(labelTag), font: GUIStyle.SubHeadingFont);
|
||||||
|
|
||||||
var bottomItem = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.5f), layoutGroup.RectTransform),
|
var bottomItem = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.5f), layoutGroup.RectTransform),
|
||||||
style: null);
|
style: null);
|
||||||
@@ -618,43 +643,40 @@ namespace Barotrauma
|
|||||||
return new RectTransform(new Vector2(width, 1.0f), bottomItem.RectTransform, Anchor.Center);
|
return new RectTransform(new Vector2(width, 1.0f), bottomItem.RectTransform, Anchor.Center);
|
||||||
}
|
}
|
||||||
|
|
||||||
RectTransform genderItemRT = createItemRectTransform("Gender", 1.0f);
|
RectTransform menuCategoryRT = createItemRectTransform(info.Prefab.MenuCategoryVar, 1.0f);
|
||||||
|
|
||||||
GUILayoutGroup genderContainer =
|
GUILayoutGroup menuCategoryContainer =
|
||||||
new GUILayoutGroup(genderItemRT, isHorizontal: true)
|
new GUILayoutGroup(menuCategoryRT, isHorizontal: true)
|
||||||
{
|
{
|
||||||
Stretch = true,
|
Stretch = true,
|
||||||
RelativeSpacing = 0.05f
|
RelativeSpacing = 0.05f
|
||||||
};
|
};
|
||||||
|
|
||||||
void createGenderButton(Gender gender)
|
void createMenuCategoryButton(Identifier tag)
|
||||||
{
|
{
|
||||||
new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), genderContainer.RectTransform),
|
new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), menuCategoryContainer.RectTransform),
|
||||||
TextManager.Get(gender.ToString()), style: "ListBoxElement")
|
TextManager.Get(tag), style: "ListBoxElement")
|
||||||
{
|
{
|
||||||
UserData = gender,
|
UserData = tag,
|
||||||
OnClicked = OpenHeadSelection,
|
OnClicked = OpenHeadSelection,
|
||||||
Selected = info.Gender == gender
|
Selected = info.Head.Preset.TagSet.Contains(tag)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
createGenderButton(Gender.Male);
|
foreach (var tag in info.Prefab.VarTags[info.Prefab.MenuCategoryVar].OrderBy(t => t.Value).Reverse())
|
||||||
createGenderButton(Gender.Female);
|
{
|
||||||
|
createMenuCategoryButton(tag);
|
||||||
int countAttachmentsOfType(WearableType wearableType)
|
}
|
||||||
=> info.FilterByTypeAndHeadID(
|
|
||||||
info.FilterElementsByGenderAndRace(info.Wearables, info.Head.gender, info.Head.race),
|
|
||||||
wearableType, info.HeadSpriteId).Count();
|
|
||||||
|
|
||||||
List<GUIScrollBar> attachmentSliders = new List<GUIScrollBar>();
|
List<GUIScrollBar> attachmentSliders = new List<GUIScrollBar>();
|
||||||
void createAttachmentSlider(int initialValue, WearableType wearableType)
|
void createAttachmentSlider(int initialValue, WearableType wearableType)
|
||||||
{
|
{
|
||||||
int attachmentCount = countAttachmentsOfType(wearableType);
|
int attachmentCount = info.CountValidAttachmentsOfType(wearableType);
|
||||||
if (attachmentCount > 0)
|
if (attachmentCount > 0)
|
||||||
{
|
{
|
||||||
var labelTag = wearableType == WearableType.FaceAttachment
|
var labelTag = wearableType == WearableType.FaceAttachment
|
||||||
? "FaceAttachment.Accessories"
|
? "FaceAttachment.Accessories".ToIdentifier()
|
||||||
: $"FaceAttachment.{wearableType}";
|
: $"FaceAttachment.{wearableType}".ToIdentifier();
|
||||||
var sliderItemRT = createItemRectTransform(labelTag);
|
var sliderItemRT = createItemRectTransform(labelTag);
|
||||||
var slider =
|
var slider =
|
||||||
new GUIScrollBar(sliderItemRT, style: "GUISlider")
|
new GUIScrollBar(sliderItemRT, style: "GUISlider")
|
||||||
@@ -670,12 +692,12 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
createAttachmentSlider(info.HairIndex, WearableType.Hair);
|
createAttachmentSlider(info.Head.HairIndex, WearableType.Hair);
|
||||||
createAttachmentSlider(info.BeardIndex, WearableType.Beard);
|
createAttachmentSlider(info.Head.BeardIndex, WearableType.Beard);
|
||||||
createAttachmentSlider(info.MoustacheIndex, WearableType.Moustache);
|
createAttachmentSlider(info.Head.MoustacheIndex, WearableType.Moustache);
|
||||||
createAttachmentSlider(info.FaceAttachmentIndex, WearableType.FaceAttachment);
|
createAttachmentSlider(info.Head.FaceAttachmentIndex, WearableType.FaceAttachment);
|
||||||
|
|
||||||
void createColorSelector(string labelTag, IEnumerable<(Color Color, float Commonness)> options, Func<Color> getter,
|
void createColorSelector(Identifier labelTag, IEnumerable<(Color Color, float Commonness)> options, Func<Color> getter,
|
||||||
Action<Color> setter)
|
Action<Color> setter)
|
||||||
{
|
{
|
||||||
var selectorItemRT = createItemRectTransform(labelTag, 0.4f);
|
var selectorItemRT = createItemRectTransform(labelTag, 0.4f);
|
||||||
@@ -757,21 +779,21 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (countAttachmentsOfType(WearableType.Hair) > 0)
|
if (info.CountValidAttachmentsOfType(WearableType.Hair) > 0)
|
||||||
{
|
{
|
||||||
createColorSelector($"Customization.{nameof(info.HairColor)}", info.HairColors,
|
createColorSelector($"Customization.{nameof(info.Head.HairColor)}".ToIdentifier(), info.HairColors,
|
||||||
() => info.HairColor, (color) => info.HairColor = color);
|
() => info.Head.HairColor, (color) => info.Head.HairColor = color);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (countAttachmentsOfType(WearableType.Moustache) > 0 ||
|
if (info.CountValidAttachmentsOfType(WearableType.Moustache) > 0 ||
|
||||||
countAttachmentsOfType(WearableType.Beard) > 0)
|
info.CountValidAttachmentsOfType(WearableType.Beard) > 0)
|
||||||
{
|
{
|
||||||
createColorSelector($"Customization.{nameof(info.FacialHairColor)}", info.FacialHairColors,
|
createColorSelector($"Customization.{nameof(info.Head.FacialHairColor)}".ToIdentifier(), info.FacialHairColors,
|
||||||
() => info.FacialHairColor, (color) => info.FacialHairColor = color);
|
() => info.Head.FacialHairColor, (color) => info.Head.FacialHairColor = color);
|
||||||
}
|
}
|
||||||
|
|
||||||
createColorSelector($"Customization.{nameof(info.SkinColor)}", info.SkinColors, () => info.SkinColor,
|
createColorSelector($"Customization.{nameof(info.Head.SkinColor)}".ToIdentifier(), info.SkinColors, () => info.Head.SkinColor,
|
||||||
(color) => info.SkinColor = color);
|
(color) => info.Head.SkinColor = color);
|
||||||
|
|
||||||
RandomizeButton = new GUIButton(new RectTransform(Vector2.One * 0.12f,
|
RandomizeButton = new GUIButton(new RectTransform(Vector2.One * 0.12f,
|
||||||
parentComponent.RectTransform,
|
parentComponent.RectTransform,
|
||||||
@@ -780,9 +802,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
OnClicked = (button, o) =>
|
OnClicked = (button, o) =>
|
||||||
{
|
{
|
||||||
info.Head = new HeadInfo();
|
var headPreset = info.Prefab.Heads.GetRandom(Rand.RandSync.Unsynced);
|
||||||
info.SetGenderAndRace(Rand.RandSync.Unsynced);
|
info.Head = new HeadInfo(info, headPreset);
|
||||||
info.SetColors();
|
info.SetAttachments(Rand.RandSync.Unsynced);
|
||||||
|
info.SetColors(Rand.RandSync.Unsynced);
|
||||||
|
|
||||||
RecreateFrameContents();
|
RecreateFrameContents();
|
||||||
info.RefreshHead();
|
info.RefreshHead();
|
||||||
@@ -801,7 +824,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private bool OpenHeadSelection(GUIButton button, object userData)
|
private bool OpenHeadSelection(GUIButton button, object userData)
|
||||||
{
|
{
|
||||||
Gender selectedGender = (Gender)userData;
|
Identifier selectedCategory = (Identifier)userData;
|
||||||
|
|
||||||
var info = CharacterInfo;
|
var info = CharacterInfo;
|
||||||
|
|
||||||
@@ -842,36 +865,27 @@ namespace Barotrauma
|
|||||||
GUILayoutGroup row = null;
|
GUILayoutGroup row = null;
|
||||||
int itemsInRow = 0;
|
int itemsInRow = 0;
|
||||||
|
|
||||||
XElement headElement = info.Ragdoll.MainElement.Elements().FirstOrDefault(e =>
|
ContentXElement headElement = info.Ragdoll.MainElement.Elements().FirstOrDefault(e =>
|
||||||
e.GetAttributeString("type", "").Equals("head", StringComparison.OrdinalIgnoreCase));
|
e.GetAttributeString("type", "").Equals("head", StringComparison.OrdinalIgnoreCase));
|
||||||
XElement headSpriteElement = headElement.Element("sprite");
|
ContentXElement headSpriteElement = headElement.GetChildElement("sprite");
|
||||||
string spritePathWithTags = headSpriteElement.Attribute("texture").Value;
|
ContentPath spritePathWithTags = headSpriteElement.GetAttributeContentPath("texture");
|
||||||
|
|
||||||
var characterConfigElement = info.CharacterConfigElement;
|
var characterConfigElement = info.CharacterConfigElement;
|
||||||
|
|
||||||
var heads = info.Heads;
|
var heads = info.Prefab.Heads;
|
||||||
if (heads != null)
|
if (heads != null)
|
||||||
{
|
{
|
||||||
row = null;
|
row = null;
|
||||||
itemsInRow = 0;
|
itemsInRow = 0;
|
||||||
foreach (var kvp in heads.Where(kv => kv.Key.Gender == selectedGender))
|
foreach (var head in heads.Where(h => h.TagSet.Contains(selectedCategory)))
|
||||||
{
|
{
|
||||||
var headPreset = kvp.Key;
|
string spritePath = info.Prefab.ReplaceVars(spritePathWithTags.Value, head);
|
||||||
Race race = headPreset.Race;
|
|
||||||
int headIndex = headPreset.ID;
|
|
||||||
|
|
||||||
string spritePath = spritePathWithTags
|
if (!File.Exists(spritePath)) { continue; }
|
||||||
.Replace("[GENDER]", selectedGender.ToString().ToLowerInvariant())
|
|
||||||
.Replace("[RACE]", race.ToString().ToLowerInvariant());
|
|
||||||
|
|
||||||
if (!File.Exists(spritePath))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sprite headSprite = new Sprite(headSpriteElement, "", spritePath);
|
Sprite headSprite = new Sprite(headSpriteElement, "", spritePath);
|
||||||
headSprite.SourceRect =
|
headSprite.SourceRect =
|
||||||
new Rectangle(CalculateOffset(headSprite, kvp.Value.ToPoint()),
|
new Rectangle(CharacterInfo.CalculateOffset(headSprite, head.SheetIndex.ToPoint()),
|
||||||
headSprite.SourceRect.Size);
|
headSprite.SourceRect.Size);
|
||||||
characterSprites.Add(headSprite);
|
characterSprites.Add(headSprite);
|
||||||
|
|
||||||
@@ -881,7 +895,7 @@ namespace Barotrauma
|
|||||||
new RectTransform(new Vector2(1.0f, 0.333f), HeadSelectionList.Content.RectTransform),
|
new RectTransform(new Vector2(1.0f, 0.333f), HeadSelectionList.Content.RectTransform),
|
||||||
true)
|
true)
|
||||||
{
|
{
|
||||||
UserData = selectedGender,
|
UserData = head.MenuCategory,
|
||||||
Visible = true
|
Visible = true
|
||||||
};
|
};
|
||||||
itemsInRow = 0;
|
itemsInRow = 0;
|
||||||
@@ -892,9 +906,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
OutlineColor = Color.White * 0.5f,
|
OutlineColor = Color.White * 0.5f,
|
||||||
PressedColor = Color.White * 0.5f,
|
PressedColor = Color.White * 0.5f,
|
||||||
UserData = new Tuple<Gender, Race, int>(selectedGender, race, headIndex),
|
UserData = head,
|
||||||
OnClicked = SwitchHead,
|
OnClicked = SwitchHead,
|
||||||
Selected = selectedGender == info.Gender && race == info.Race && headIndex == info.HeadSpriteId,
|
Selected = info.Head.Preset == head,
|
||||||
Visible = true
|
Visible = true
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -909,12 +923,18 @@ namespace Barotrauma
|
|||||||
private bool SwitchHead(GUIButton button, object obj)
|
private bool SwitchHead(GUIButton button, object obj)
|
||||||
{
|
{
|
||||||
var info = CharacterInfo;
|
var info = CharacterInfo;
|
||||||
Gender gender = ((Tuple<Gender, Race, int>)obj).Item1;
|
var headPreset = obj as HeadPreset;
|
||||||
Race race = ((Tuple<Gender, Race, int>)obj).Item2;
|
if (info.Head.Preset != headPreset)
|
||||||
int id = ((Tuple<Gender, Race, int>)obj).Item3;
|
{
|
||||||
info.Gender = gender;
|
info.Head = new HeadInfo(info, headPreset)
|
||||||
info.Race = race;
|
{
|
||||||
info.Head.HeadSpriteId = id;
|
SkinColor = info.Head.SkinColor,
|
||||||
|
HairColor = info.Head.HairColor,
|
||||||
|
FacialHairColor = info.Head.FacialHairColor
|
||||||
|
};
|
||||||
|
info.ReloadHeadAttachments();
|
||||||
|
}
|
||||||
|
|
||||||
RecreateFrameContents();
|
RecreateFrameContents();
|
||||||
OnHeadSwitch?.Invoke(this);
|
OnHeadSwitch?.Invoke(this);
|
||||||
return true;
|
return true;
|
||||||
@@ -927,16 +947,16 @@ namespace Barotrauma
|
|||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case WearableType.Beard:
|
case WearableType.Beard:
|
||||||
info.BeardIndex = index;
|
info.Head.BeardIndex = index;
|
||||||
break;
|
break;
|
||||||
case WearableType.FaceAttachment:
|
case WearableType.FaceAttachment:
|
||||||
info.FaceAttachmentIndex = index;
|
info.Head.FaceAttachmentIndex = index;
|
||||||
break;
|
break;
|
||||||
case WearableType.Hair:
|
case WearableType.Hair:
|
||||||
info.HairIndex = index;
|
info.Head.HairIndex = index;
|
||||||
break;
|
break;
|
||||||
case WearableType.Moustache:
|
case WearableType.Moustache:
|
||||||
info.MoustacheIndex = index;
|
info.Head.MoustacheIndex = index;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DebugConsole.ThrowError($"Wearable type not implemented: {type}");
|
DebugConsole.ThrowError($"Wearable type not implemented: {type}");
|
||||||
|
|||||||
@@ -112,395 +112,404 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void ClientWrite(IWriteMessage msg, object[] extraData = null)
|
public void ClientWriteInput(IWriteMessage msg)
|
||||||
{
|
{
|
||||||
if (extraData != null)
|
msg.Write((byte)ClientNetObject.CHARACTER_INPUT);
|
||||||
|
|
||||||
|
if (memInput.Count > 60)
|
||||||
{
|
{
|
||||||
switch ((NetEntityEvent.Type)extraData[0])
|
memInput.RemoveRange(60, memInput.Count - 60);
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.Write(LastNetworkUpdateID);
|
||||||
|
byte inputCount = Math.Min((byte)memInput.Count, (byte)60);
|
||||||
|
msg.Write(inputCount);
|
||||||
|
for (int i = 0; i < inputCount; i++)
|
||||||
|
{
|
||||||
|
msg.WriteRangedInteger((int)memInput[i].states, 0, (int)InputNetFlags.MaxVal);
|
||||||
|
msg.Write(memInput[i].intAim);
|
||||||
|
if (memInput[i].states.HasFlag(InputNetFlags.Select) ||
|
||||||
|
memInput[i].states.HasFlag(InputNetFlags.Deselect) ||
|
||||||
|
memInput[i].states.HasFlag(InputNetFlags.Use) ||
|
||||||
|
memInput[i].states.HasFlag(InputNetFlags.Health) ||
|
||||||
|
memInput[i].states.HasFlag(InputNetFlags.Grab))
|
||||||
{
|
{
|
||||||
case NetEntityEvent.Type.InventoryState:
|
msg.Write(memInput[i].interact);
|
||||||
msg.WriteRangedInteger(0, 0, 4);
|
|
||||||
Inventory.ClientWrite(msg, extraData);
|
|
||||||
break;
|
|
||||||
case NetEntityEvent.Type.Treatment:
|
|
||||||
msg.WriteRangedInteger(1, 0, 4);
|
|
||||||
msg.Write(AnimController.Anim == AnimController.Animation.CPR);
|
|
||||||
break;
|
|
||||||
case NetEntityEvent.Type.Status:
|
|
||||||
msg.WriteRangedInteger(2, 0, 4);
|
|
||||||
break;
|
|
||||||
case NetEntityEvent.Type.UpdateTalents:
|
|
||||||
msg.WriteRangedInteger(3, 0, 4);
|
|
||||||
msg.Write((ushort)characterTalents.Count);
|
|
||||||
foreach (var unlockedTalent in characterTalents)
|
|
||||||
{
|
|
||||||
msg.Write(unlockedTalent.Prefab.UIntIdentifier);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void ClientEventWrite(IWriteMessage msg, NetEntityEvent.IData extraData = null)
|
||||||
|
{
|
||||||
|
if (!(extraData is IEventData eventData)) { throw new Exception($"Malformed character event: expected {nameof(Character)}.{nameof(IEventData)}"); }
|
||||||
|
|
||||||
|
msg.WriteRangedInteger((int)eventData.EventType, (int)EventType.MinValue, (int)EventType.MaxValue);
|
||||||
|
switch (eventData)
|
||||||
|
{
|
||||||
|
case InventoryStateEventData inventoryStateEventData:
|
||||||
|
Inventory.ClientEventWrite(msg, inventoryStateEventData);
|
||||||
|
break;
|
||||||
|
case TreatmentEventData _:
|
||||||
|
msg.Write(AnimController.Anim == AnimController.Animation.CPR);
|
||||||
|
break;
|
||||||
|
case CharacterStatusEventData _:
|
||||||
|
//do nothing
|
||||||
|
break;
|
||||||
|
case UpdateTalentsEventData _:
|
||||||
|
msg.Write((ushort)characterTalents.Count);
|
||||||
|
foreach (var unlockedTalent in characterTalents)
|
||||||
|
{
|
||||||
|
msg.Write(unlockedTalent.Prefab.UintIdentifier);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception($"Malformed character event: did not expect {eventData.GetType().Name}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClientReadPosition(IReadMessage msg, float sendingTime)
|
||||||
|
{
|
||||||
|
bool facingRight = AnimController.Dir > 0.0f;
|
||||||
|
|
||||||
|
lastRecvPositionUpdateTime = (float)Lidgren.Network.NetTime.Now;
|
||||||
|
|
||||||
|
AnimController.Frozen = false;
|
||||||
|
Enabled = true;
|
||||||
|
|
||||||
|
UInt16 networkUpdateID = 0;
|
||||||
|
if (msg.ReadBoolean())
|
||||||
|
{
|
||||||
|
networkUpdateID = msg.ReadUInt16();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
msg.Write((byte)ClientNetObject.CHARACTER_INPUT);
|
bool aimInput = msg.ReadBoolean();
|
||||||
|
keys[(int)InputType.Aim].Held = aimInput;
|
||||||
|
keys[(int)InputType.Aim].SetState(false, aimInput);
|
||||||
|
|
||||||
if (memInput.Count > 60)
|
bool shootInput = msg.ReadBoolean();
|
||||||
|
keys[(int)InputType.Shoot].Held = shootInput;
|
||||||
|
keys[(int)InputType.Shoot].SetState(false, shootInput);
|
||||||
|
|
||||||
|
bool useInput = msg.ReadBoolean();
|
||||||
|
keys[(int)InputType.Use].Held = useInput;
|
||||||
|
keys[(int)InputType.Use].SetState(false, useInput);
|
||||||
|
|
||||||
|
if (AnimController is HumanoidAnimController)
|
||||||
{
|
{
|
||||||
memInput.RemoveRange(60, memInput.Count - 60);
|
bool crouching = msg.ReadBoolean();
|
||||||
|
keys[(int)InputType.Crouch].Held = crouching;
|
||||||
|
keys[(int)InputType.Crouch].SetState(false, crouching);
|
||||||
}
|
}
|
||||||
|
|
||||||
msg.Write(LastNetworkUpdateID);
|
bool attackInput = msg.ReadBoolean();
|
||||||
byte inputCount = Math.Min((byte)memInput.Count, (byte)60);
|
keys[(int)InputType.Attack].Held = attackInput;
|
||||||
msg.Write(inputCount);
|
keys[(int)InputType.Attack].SetState(false, attackInput);
|
||||||
for (int i = 0; i < inputCount; i++)
|
|
||||||
|
double aimAngle = msg.ReadUInt16() / 65535.0 * 2.0 * Math.PI;
|
||||||
|
cursorPosition = AimRefPosition + new Vector2((float)Math.Cos(aimAngle), (float)Math.Sin(aimAngle)) * 500.0f;
|
||||||
|
TransformCursorPos();
|
||||||
|
|
||||||
|
bool ragdollInput = msg.ReadBoolean();
|
||||||
|
keys[(int)InputType.Ragdoll].Held = ragdollInput;
|
||||||
|
keys[(int)InputType.Ragdoll].SetState(false, ragdollInput);
|
||||||
|
|
||||||
|
facingRight = msg.ReadBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool entitySelected = msg.ReadBoolean();
|
||||||
|
Character selectedCharacter = null;
|
||||||
|
Item selectedItem = null;
|
||||||
|
|
||||||
|
AnimController.Animation animation = AnimController.Animation.None;
|
||||||
|
if (entitySelected)
|
||||||
|
{
|
||||||
|
ushort characterID = msg.ReadUInt16();
|
||||||
|
ushort itemID = msg.ReadUInt16();
|
||||||
|
selectedCharacter = FindEntityByID(characterID) as Character;
|
||||||
|
selectedItem = FindEntityByID(itemID) as Item;
|
||||||
|
if (characterID != NullEntityID)
|
||||||
{
|
{
|
||||||
msg.WriteRangedInteger((int)memInput[i].states, 0, (int)InputNetFlags.MaxVal);
|
bool doingCpr = msg.ReadBoolean();
|
||||||
msg.Write(memInput[i].intAim);
|
if (doingCpr && SelectedCharacter != null)
|
||||||
if (memInput[i].states.HasFlag(InputNetFlags.Select) ||
|
|
||||||
memInput[i].states.HasFlag(InputNetFlags.Deselect) ||
|
|
||||||
memInput[i].states.HasFlag(InputNetFlags.Use) ||
|
|
||||||
memInput[i].states.HasFlag(InputNetFlags.Health) ||
|
|
||||||
memInput[i].states.HasFlag(InputNetFlags.Grab))
|
|
||||||
{
|
{
|
||||||
msg.Write(memInput[i].interact);
|
animation = AnimController.Animation.CPR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
msg.WritePadBits();
|
|
||||||
|
Vector2 pos = new Vector2(
|
||||||
|
msg.ReadSingle(),
|
||||||
|
msg.ReadSingle());
|
||||||
|
float MaxVel = NetConfig.MaxPhysicsBodyVelocity;
|
||||||
|
Vector2 linearVelocity = new Vector2(
|
||||||
|
msg.ReadRangedSingle(-MaxVel, MaxVel, 12),
|
||||||
|
msg.ReadRangedSingle(-MaxVel, MaxVel, 12));
|
||||||
|
linearVelocity = NetConfig.Quantize(linearVelocity, -MaxVel, MaxVel, 12);
|
||||||
|
|
||||||
|
bool fixedRotation = msg.ReadBoolean();
|
||||||
|
float? rotation = null;
|
||||||
|
float? angularVelocity = null;
|
||||||
|
if (!fixedRotation)
|
||||||
|
{
|
||||||
|
rotation = msg.ReadSingle();
|
||||||
|
float MaxAngularVel = NetConfig.MaxPhysicsBodyAngularVelocity;
|
||||||
|
angularVelocity = msg.ReadRangedSingle(-MaxAngularVel, MaxAngularVel, 8);
|
||||||
|
angularVelocity = NetConfig.Quantize(angularVelocity.Value, -MaxAngularVel, MaxAngularVel, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool readStatus = msg.ReadBoolean();
|
||||||
|
if (readStatus)
|
||||||
|
{
|
||||||
|
ReadStatus(msg);
|
||||||
|
AIController?.ClientRead(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.ReadPadBits();
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
if (GameMain.Client.Character == this && CanMove)
|
||||||
|
{
|
||||||
|
var posInfo = new CharacterStateInfo(
|
||||||
|
pos, rotation,
|
||||||
|
networkUpdateID,
|
||||||
|
facingRight ? Direction.Right : Direction.Left,
|
||||||
|
selectedCharacter, selectedItem, animation);
|
||||||
|
|
||||||
|
while (index < memState.Count && NetIdUtils.IdMoreRecent(posInfo.ID, memState[index].ID))
|
||||||
|
index++;
|
||||||
|
memState.Insert(index, posInfo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var posInfo = new CharacterStateInfo(
|
||||||
|
pos, rotation,
|
||||||
|
linearVelocity, angularVelocity,
|
||||||
|
sendingTime, facingRight ? Direction.Right : Direction.Left,
|
||||||
|
selectedCharacter, selectedItem, animation);
|
||||||
|
|
||||||
|
while (index < memState.Count && posInfo.Timestamp > memState[index].Timestamp)
|
||||||
|
index++;
|
||||||
|
memState.Insert(index, posInfo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
public virtual void ClientEventRead(IReadMessage msg, float sendingTime)
|
||||||
{
|
{
|
||||||
switch (type)
|
EventType eventType = (EventType)msg.ReadRangedInteger((int)EventType.MinValue, (int)EventType.MaxValue);
|
||||||
|
switch (eventType)
|
||||||
{
|
{
|
||||||
case ServerNetObject.ENTITY_POSITION:
|
case EventType.InventoryState:
|
||||||
bool facingRight = AnimController.Dir > 0.0f;
|
if (Inventory == null)
|
||||||
|
|
||||||
lastRecvPositionUpdateTime = (float)Lidgren.Network.NetTime.Now;
|
|
||||||
|
|
||||||
AnimController.Frozen = false;
|
|
||||||
Enabled = true;
|
|
||||||
|
|
||||||
UInt16 networkUpdateID = 0;
|
|
||||||
if (msg.ReadBoolean())
|
|
||||||
{
|
{
|
||||||
networkUpdateID = msg.ReadUInt16();
|
string errorMsg = "Received an inventory update message for an entity with no inventory ([name], removed: " + Removed + ")";
|
||||||
|
DebugConsole.ThrowError(errorMsg.Replace("[name]", Name));
|
||||||
|
GameAnalyticsManager.AddErrorEventOnce("CharacterNetworking.ClientRead:NoInventory" + ID, GameAnalyticsManager.ErrorSeverity.Error, errorMsg.Replace("[name]", SpeciesName.Value));
|
||||||
|
|
||||||
|
//read anyway to prevent messing up reading the rest of the message
|
||||||
|
_ = msg.ReadUInt16();
|
||||||
|
byte inventoryItemCount = msg.ReadByte();
|
||||||
|
for (int i = 0; i < inventoryItemCount; i++)
|
||||||
|
{
|
||||||
|
msg.ReadUInt16();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool aimInput = msg.ReadBoolean();
|
Inventory.ClientEventRead(msg, sendingTime);
|
||||||
keys[(int)InputType.Aim].Held = aimInput;
|
}
|
||||||
keys[(int)InputType.Aim].SetState(false, aimInput);
|
break;
|
||||||
|
case EventType.Control:
|
||||||
bool shootInput = msg.ReadBoolean();
|
bool myCharacter = msg.ReadBoolean();
|
||||||
keys[(int)InputType.Shoot].Held = shootInput;
|
byte ownerID = msg.ReadByte();
|
||||||
keys[(int)InputType.Shoot].SetState(false, shootInput);
|
ResetNetState();
|
||||||
|
if (myCharacter)
|
||||||
bool useInput = msg.ReadBoolean();
|
{
|
||||||
keys[(int)InputType.Use].Held = useInput;
|
if (controlled != null)
|
||||||
keys[(int)InputType.Use].SetState(false, useInput);
|
|
||||||
|
|
||||||
if (AnimController is HumanoidAnimController)
|
|
||||||
{
|
{
|
||||||
bool crouching = msg.ReadBoolean();
|
LastNetworkUpdateID = controlled.LastNetworkUpdateID;
|
||||||
keys[(int)InputType.Crouch].Held = crouching;
|
|
||||||
keys[(int)InputType.Crouch].SetState(false, crouching);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool attackInput = msg.ReadBoolean();
|
if (!IsDead) { Controlled = this; }
|
||||||
keys[(int)InputType.Attack].Held = attackInput;
|
IsRemotePlayer = false;
|
||||||
keys[(int)InputType.Attack].SetState(false, attackInput);
|
GameMain.Client.HasSpawned = true;
|
||||||
|
GameMain.Client.Character = this;
|
||||||
double aimAngle = msg.ReadUInt16() / 65535.0 * 2.0 * Math.PI;
|
GameMain.LightManager.LosEnabled = true;
|
||||||
cursorPosition = AimRefPosition + new Vector2((float)Math.Cos(aimAngle), (float)Math.Sin(aimAngle)) * 500.0f;
|
GameMain.LightManager.LosAlpha = 1f;
|
||||||
TransformCursorPos();
|
GameMain.Client.WaitForNextRoundRespawn = null;
|
||||||
|
|
||||||
bool ragdollInput = msg.ReadBoolean();
|
|
||||||
keys[(int)InputType.Ragdoll].Held = ragdollInput;
|
|
||||||
keys[(int)InputType.Ragdoll].SetState(false, ragdollInput);
|
|
||||||
|
|
||||||
facingRight = msg.ReadBoolean();
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
bool entitySelected = msg.ReadBoolean();
|
{
|
||||||
Character selectedCharacter = null;
|
if (controlled == this)
|
||||||
Item selectedItem = null;
|
{
|
||||||
|
Controlled = null;
|
||||||
AnimController.Animation animation = AnimController.Animation.None;
|
}
|
||||||
if (entitySelected)
|
if (GameMain.Client?.Character == this)
|
||||||
|
{
|
||||||
|
GameMain.Client.Character = null;
|
||||||
|
}
|
||||||
|
IsRemotePlayer = ownerID > 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EventType.Status:
|
||||||
|
ReadStatus(msg);
|
||||||
|
break;
|
||||||
|
case EventType.UpdateSkills:
|
||||||
|
int skillCount = msg.ReadByte();
|
||||||
|
for (int i = 0; i < skillCount; i++)
|
||||||
|
{
|
||||||
|
Identifier skillIdentifier = msg.ReadIdentifier();
|
||||||
|
float skillLevel = msg.ReadSingle();
|
||||||
|
info?.SetSkillLevel(skillIdentifier, skillLevel);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EventType.SetAttackTarget:
|
||||||
|
case EventType.ExecuteAttack:
|
||||||
|
int attackLimbIndex = msg.ReadByte();
|
||||||
|
UInt16 targetEntityID = msg.ReadUInt16();
|
||||||
|
int targetLimbIndex = msg.ReadByte();
|
||||||
|
float targetX = msg.ReadSingle();
|
||||||
|
float targetY = msg.ReadSingle();
|
||||||
|
Vector2 targetSimPos = new Vector2(targetX, targetY);
|
||||||
|
//255 = entity already removed, no need to do anything
|
||||||
|
if (attackLimbIndex == 255 || Removed) { break; }
|
||||||
|
if (attackLimbIndex >= AnimController.Limbs.Length)
|
||||||
|
{
|
||||||
|
string errorMsg = $"Received invalid {(eventType == EventType.SetAttackTarget ? "SetAttackTarget" : "ExecuteAttack")} message. Limb index out of bounds (character: {Name}, limb index: {attackLimbIndex}, limb count: {AnimController.Limbs.Length})";
|
||||||
|
DebugConsole.ThrowError(errorMsg);
|
||||||
|
GameAnalyticsManager.AddErrorEventOnce("Character.ClientEventRead:AttackLimbOutOfBounds", GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Limb attackLimb = AnimController.Limbs[attackLimbIndex];
|
||||||
|
Limb targetLimb = null;
|
||||||
|
IDamageable targetEntity = FindEntityByID(targetEntityID) as IDamageable;
|
||||||
|
if (targetEntity == null && eventType == EventType.SetAttackTarget)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError($"Received invalid SetAttackTarget message. Target entity not found (ID {targetEntityID})");
|
||||||
|
GameAnalyticsManager.AddErrorEventOnce("Character.ClientEventRead:TargetNotFound", GameAnalyticsManager.ErrorSeverity.Error, "Received invalid SetAttackTarget message. Target entity not found.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (targetEntity is Character targetCharacter && targetLimbIndex != 255)
|
||||||
|
{
|
||||||
|
if (targetLimbIndex >= targetCharacter.AnimController.Limbs.Length)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError($"Received invalid {(eventType == EventType.SetAttackTarget ? "SetAttackTarget" : "ExecuteAttack")} message. Target limb index out of bounds (target character: {targetCharacter.Name}, limb index: {targetLimbIndex}, limb count: {targetCharacter.AnimController.Limbs.Length})");
|
||||||
|
string errorMsgWithoutName = $"Received invalid {(eventType == EventType.SetAttackTarget ? "SetAttackTarget" : "ExecuteAttack")} message. Target limb index out of bounds (target character: {targetCharacter.SpeciesName}, limb index: {targetLimbIndex}, limb count: {targetCharacter.AnimController.Limbs.Length})";
|
||||||
|
GameAnalyticsManager.AddErrorEventOnce("Character.ClientEventRead:TargetLimbOutOfBounds", GameAnalyticsManager.ErrorSeverity.Error, errorMsgWithoutName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
targetLimb = targetCharacter.AnimController.Limbs[targetLimbIndex];
|
||||||
|
}
|
||||||
|
if (attackLimb?.attack != null && Controlled != this)
|
||||||
|
{
|
||||||
|
if (eventType == EventType.SetAttackTarget)
|
||||||
|
{
|
||||||
|
SetAttackTarget(attackLimb, targetEntity, targetSimPos);
|
||||||
|
PlaySound(CharacterSound.SoundType.Attack, maxInterval: 3);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
attackLimb.ExecuteAttack(targetEntity, targetLimb, out _);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EventType.AssignCampaignInteraction:
|
||||||
|
byte campaignInteractionType = msg.ReadByte();
|
||||||
|
bool requireConsciousness = msg.ReadBoolean();
|
||||||
|
(GameMain.GameSession?.GameMode as CampaignMode)?.AssignNPCMenuInteraction(this, (CampaignMode.InteractionType)campaignInteractionType);
|
||||||
|
RequireConsciousnessForCustomInteract = requireConsciousness;
|
||||||
|
break;
|
||||||
|
case EventType.ObjectiveManagerState:
|
||||||
|
// 1 = order, 2 = objective
|
||||||
|
AIObjectiveManager.ObjectiveType msgType
|
||||||
|
= (AIObjectiveManager.ObjectiveType)msg.ReadRangedInteger(
|
||||||
|
(int)AIObjectiveManager.ObjectiveType.MinValue,
|
||||||
|
(int)AIObjectiveManager.ObjectiveType.MaxValue);
|
||||||
|
if (msgType == 0) { break; }
|
||||||
|
bool validData = msg.ReadBoolean();
|
||||||
|
if (!validData) { break; }
|
||||||
|
if (msgType == AIObjectiveManager.ObjectiveType.Order)
|
||||||
|
{
|
||||||
|
UInt32 orderPrefabUintIdentifier = msg.ReadUInt32();
|
||||||
|
var orderPrefab = OrderPrefab.Prefabs.Find(p => p.UintIdentifier == orderPrefabUintIdentifier);
|
||||||
|
Identifier option = Identifier.Empty;
|
||||||
|
if (orderPrefab.HasOptions)
|
||||||
|
{
|
||||||
|
int optionIndex = msg.ReadRangedInteger(-1, orderPrefab.AllOptions.Length);
|
||||||
|
if (optionIndex > -1)
|
||||||
|
{
|
||||||
|
option = orderPrefab.AllOptions[optionIndex];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GameMain.GameSession?.CrewManager?.SetOrderHighlight(this, orderPrefab.Identifier, option);
|
||||||
|
}
|
||||||
|
else if (msgType == AIObjectiveManager.ObjectiveType.Objective)
|
||||||
|
{
|
||||||
|
Identifier identifier = msg.ReadIdentifier();
|
||||||
|
Identifier option = msg.ReadIdentifier();
|
||||||
|
ushort objectiveTargetEntityId = msg.ReadUInt16();
|
||||||
|
var objectiveTargetEntity = FindEntityByID(objectiveTargetEntityId);
|
||||||
|
GameMain.GameSession?.CrewManager?.CreateObjectiveIcon(this, identifier, option, objectiveTargetEntity);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EventType.TeamChange:
|
||||||
|
byte newTeamId = msg.ReadByte();
|
||||||
|
ChangeTeam((CharacterTeamType)newTeamId);
|
||||||
|
break;
|
||||||
|
case EventType.AddToCrew:
|
||||||
|
GameMain.GameSession.CrewManager.AddCharacter(this);
|
||||||
|
CharacterTeamType teamID = (CharacterTeamType)msg.ReadByte();
|
||||||
|
ushort itemCount = msg.ReadUInt16();
|
||||||
|
for (int i = 0; i < itemCount; i++)
|
||||||
{
|
{
|
||||||
ushort characterID = msg.ReadUInt16();
|
|
||||||
ushort itemID = msg.ReadUInt16();
|
ushort itemID = msg.ReadUInt16();
|
||||||
selectedCharacter = FindEntityByID(characterID) as Character;
|
if (!(Entity.FindEntityByID(itemID) is Item item)) { continue; }
|
||||||
selectedItem = FindEntityByID(itemID) as Item;
|
item.AllowStealing = true;
|
||||||
if (characterID != NullEntityID)
|
var wifiComponent = item.GetComponent<WifiComponent>();
|
||||||
|
if (wifiComponent != null)
|
||||||
{
|
{
|
||||||
bool doingCpr = msg.ReadBoolean();
|
wifiComponent.TeamID = teamID;
|
||||||
if (doingCpr && SelectedCharacter != null)
|
}
|
||||||
{
|
var idCard = item.GetComponent<IdCard>();
|
||||||
animation = AnimController.Animation.CPR;
|
if (idCard != null)
|
||||||
}
|
{
|
||||||
|
idCard.TeamID = teamID;
|
||||||
|
idCard.SubmarineSpecificID = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 pos = new Vector2(
|
|
||||||
msg.ReadSingle(),
|
|
||||||
msg.ReadSingle());
|
|
||||||
float MaxVel = NetConfig.MaxPhysicsBodyVelocity;
|
|
||||||
Vector2 linearVelocity = new Vector2(
|
|
||||||
msg.ReadRangedSingle(-MaxVel, MaxVel, 12),
|
|
||||||
msg.ReadRangedSingle(-MaxVel, MaxVel, 12));
|
|
||||||
linearVelocity = NetConfig.Quantize(linearVelocity, -MaxVel, MaxVel, 12);
|
|
||||||
|
|
||||||
bool fixedRotation = msg.ReadBoolean();
|
|
||||||
float? rotation = null;
|
|
||||||
float? angularVelocity = null;
|
|
||||||
if (!fixedRotation)
|
|
||||||
{
|
|
||||||
rotation = msg.ReadSingle();
|
|
||||||
float MaxAngularVel = NetConfig.MaxPhysicsBodyAngularVelocity;
|
|
||||||
angularVelocity = msg.ReadRangedSingle(-MaxAngularVel, MaxAngularVel, 8);
|
|
||||||
angularVelocity = NetConfig.Quantize(angularVelocity.Value, -MaxAngularVel, MaxAngularVel, 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool readStatus = msg.ReadBoolean();
|
|
||||||
if (readStatus)
|
|
||||||
{
|
|
||||||
ReadStatus(msg);
|
|
||||||
AIController?.ClientRead(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
msg.ReadPadBits();
|
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
if (GameMain.Client.Character == this && CanMove)
|
|
||||||
{
|
|
||||||
var posInfo = new CharacterStateInfo(
|
|
||||||
pos, rotation,
|
|
||||||
networkUpdateID,
|
|
||||||
facingRight ? Direction.Right : Direction.Left,
|
|
||||||
selectedCharacter, selectedItem, animation);
|
|
||||||
|
|
||||||
while (index < memState.Count && NetIdUtils.IdMoreRecent(posInfo.ID, memState[index].ID))
|
|
||||||
index++;
|
|
||||||
memState.Insert(index, posInfo);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var posInfo = new CharacterStateInfo(
|
|
||||||
pos, rotation,
|
|
||||||
linearVelocity, angularVelocity,
|
|
||||||
sendingTime, facingRight ? Direction.Right : Direction.Left,
|
|
||||||
selectedCharacter, selectedItem, animation);
|
|
||||||
|
|
||||||
while (index < memState.Count && posInfo.Timestamp > memState[index].Timestamp)
|
|
||||||
index++;
|
|
||||||
memState.Insert(index, posInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case ServerNetObject.ENTITY_EVENT:
|
case EventType.UpdateExperience:
|
||||||
int eventType = msg.ReadRangedInteger(0, 13);
|
int experienceAmount = msg.ReadInt32();
|
||||||
switch (eventType)
|
info?.SetExperience(experienceAmount);
|
||||||
{
|
|
||||||
case 0: //NetEntityEvent.Type.InventoryState
|
|
||||||
if (Inventory == null)
|
|
||||||
{
|
|
||||||
string errorMsg = "Received an inventory update message for an entity with no inventory ([name], removed: " + Removed + ")";
|
|
||||||
DebugConsole.ThrowError(errorMsg.Replace("[name]", Name));
|
|
||||||
GameAnalyticsManager.AddErrorEventOnce("CharacterNetworking.ClientRead:NoInventory" + ID, GameAnalyticsManager.ErrorSeverity.Error, errorMsg.Replace("[name]", SpeciesName));
|
|
||||||
|
|
||||||
//read anyway to prevent messing up reading the rest of the message
|
|
||||||
_ = msg.ReadUInt16();
|
|
||||||
byte inventoryItemCount = msg.ReadByte();
|
|
||||||
for (int i = 0; i < inventoryItemCount; i++)
|
|
||||||
{
|
|
||||||
msg.ReadUInt16();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Inventory.ClientRead(type, msg, sendingTime);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 1: //NetEntityEvent.Type.Control
|
|
||||||
bool myCharacter = msg.ReadBoolean();
|
|
||||||
byte ownerID = msg.ReadByte();
|
|
||||||
ResetNetState();
|
|
||||||
if (myCharacter)
|
|
||||||
{
|
|
||||||
if (controlled != null)
|
|
||||||
{
|
|
||||||
LastNetworkUpdateID = controlled.LastNetworkUpdateID;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!IsDead) { Controlled = this; }
|
|
||||||
IsRemotePlayer = false;
|
|
||||||
GameMain.Client.HasSpawned = true;
|
|
||||||
GameMain.Client.Character = this;
|
|
||||||
GameMain.LightManager.LosEnabled = true;
|
|
||||||
GameMain.LightManager.LosAlpha = 1f;
|
|
||||||
GameMain.Client.WaitForNextRoundRespawn = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (controlled == this)
|
|
||||||
{
|
|
||||||
Controlled = null;
|
|
||||||
IsRemotePlayer = ownerID > 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2: //NetEntityEvent.Type.Status
|
|
||||||
ReadStatus(msg);
|
|
||||||
break;
|
|
||||||
case 3: //NetEntityEvent.Type.UpdateSkills
|
|
||||||
int skillCount = msg.ReadByte();
|
|
||||||
for (int i = 0; i < skillCount; i++)
|
|
||||||
{
|
|
||||||
string skillIdentifier = msg.ReadString();
|
|
||||||
float skillLevel = msg.ReadSingle();
|
|
||||||
info?.SetSkillLevel(skillIdentifier, skillLevel);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 4: // NetEntityEvent.Type.SetAttackTarget
|
|
||||||
case 5: //NetEntityEvent.Type.ExecuteAttack
|
|
||||||
int attackLimbIndex = msg.ReadByte();
|
|
||||||
UInt16 targetEntityID = msg.ReadUInt16();
|
|
||||||
int targetLimbIndex = msg.ReadByte();
|
|
||||||
Vector2 targetSimPos = new Vector2(msg.ReadSingle(), msg.ReadSingle());
|
|
||||||
//255 = entity already removed, no need to do anything
|
|
||||||
if (attackLimbIndex == 255 || Removed) { break; }
|
|
||||||
if (attackLimbIndex >= AnimController.Limbs.Length)
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError($"Received invalid {(eventType == 4 ? "SetAttackTarget" : "ExecuteAttack")} message. Limb index out of bounds (character: {Name}, limb index: {attackLimbIndex}, limb count: {AnimController.Limbs.Length})");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Limb attackLimb = AnimController.Limbs[attackLimbIndex];
|
|
||||||
Limb targetLimb = null;
|
|
||||||
IDamageable targetEntity = FindEntityByID(targetEntityID) as IDamageable;
|
|
||||||
if (targetEntity == null && eventType == 4)
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError($"Received invalid SetAttackTarget message. Target entity not found (ID {targetEntityID})");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (targetEntity is Character targetCharacter)
|
|
||||||
{
|
|
||||||
if (targetLimbIndex >= targetCharacter.AnimController.Limbs.Length)
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError($"Received invalid {(eventType == 4 ? "SetAttackTarget" : "ExecuteAttack")} message. Target limb index out of bounds (target character: {targetCharacter.Name}, limb index: {targetLimbIndex}, limb count: {targetCharacter.AnimController.Limbs.Length})");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
targetLimb = targetCharacter.AnimController.Limbs[targetLimbIndex];
|
|
||||||
}
|
|
||||||
if (attackLimb?.attack != null && Controlled != this)
|
|
||||||
{
|
|
||||||
if (eventType == 4)
|
|
||||||
{
|
|
||||||
SetAttackTarget(attackLimb, targetEntity, targetSimPos);
|
|
||||||
PlaySound(CharacterSound.SoundType.Attack, maxInterval: 3);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
attackLimb.ExecuteAttack(targetEntity, targetLimb, out _);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 6: //NetEntityEvent.Type.AssignCampaignInteraction
|
|
||||||
byte campaignInteractionType = msg.ReadByte();
|
|
||||||
bool requireConsciousness = msg.ReadBoolean();
|
|
||||||
(GameMain.GameSession?.GameMode as CampaignMode)?.AssignNPCMenuInteraction(this, (CampaignMode.InteractionType)campaignInteractionType);
|
|
||||||
RequireConsciousnessForCustomInteract = requireConsciousness;
|
|
||||||
break;
|
|
||||||
case 7: //NetEntityEvent.Type.ObjectiveManagerState
|
|
||||||
// 1 = order, 2 = objective
|
|
||||||
int msgType = msg.ReadRangedInteger(0, 2);
|
|
||||||
if (msgType == 0) { break; }
|
|
||||||
bool validData = msg.ReadBoolean();
|
|
||||||
if (!validData) { break; }
|
|
||||||
if (msgType == 1)
|
|
||||||
{
|
|
||||||
int orderIndex = msg.ReadRangedInteger(0, Order.PrefabList.Count);
|
|
||||||
var orderPrefab = Order.PrefabList[orderIndex];
|
|
||||||
string option = null;
|
|
||||||
if (orderPrefab.HasOptions)
|
|
||||||
{
|
|
||||||
int optionIndex = msg.ReadRangedInteger(-1, orderPrefab.AllOptions.Length);
|
|
||||||
if (optionIndex > -1)
|
|
||||||
{
|
|
||||||
option = orderPrefab.AllOptions[optionIndex];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
GameMain.GameSession?.CrewManager?.SetOrderHighlight(this, orderPrefab.Identifier, option);
|
|
||||||
}
|
|
||||||
else if (msgType == 2)
|
|
||||||
{
|
|
||||||
string identifier = msg.ReadString();
|
|
||||||
string option = msg.ReadString();
|
|
||||||
ushort objectiveTargetEntityId = msg.ReadUInt16();
|
|
||||||
var objectiveTargetEntity = FindEntityByID(objectiveTargetEntityId);
|
|
||||||
GameMain.GameSession?.CrewManager?.CreateObjectiveIcon(this, identifier, option, objectiveTargetEntity);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 8: //NetEntityEvent.Type.TeamChange
|
|
||||||
byte newTeamId = msg.ReadByte();
|
|
||||||
ChangeTeam((CharacterTeamType)newTeamId);
|
|
||||||
break;
|
|
||||||
case 9: //NetEntityEvent.Type.AddToCrew
|
|
||||||
GameMain.GameSession.CrewManager.AddCharacter(this);
|
|
||||||
CharacterTeamType teamID = (CharacterTeamType)msg.ReadByte();
|
|
||||||
ushort itemCount = msg.ReadUInt16();
|
|
||||||
for (int i = 0; i < itemCount; i++)
|
|
||||||
{
|
|
||||||
ushort itemID = msg.ReadUInt16();
|
|
||||||
if (!(Entity.FindEntityByID(itemID) is Item item)) { continue; }
|
|
||||||
item.AllowStealing = true;
|
|
||||||
var wifiComponent = item.GetComponent<WifiComponent>();
|
|
||||||
if (wifiComponent != null)
|
|
||||||
{
|
|
||||||
wifiComponent.TeamID = teamID;
|
|
||||||
}
|
|
||||||
var idCard = item.GetComponent<IdCard>();
|
|
||||||
if (idCard != null)
|
|
||||||
{
|
|
||||||
idCard.TeamID = teamID;
|
|
||||||
idCard.SubmarineSpecificID = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 10: //NetEntityEvent.Type.UpdateExperience
|
|
||||||
int experienceAmount = msg.ReadInt32();
|
|
||||||
info?.SetExperience(experienceAmount);
|
|
||||||
break;
|
|
||||||
case 11: //NetEntityEvent.Type.UpdateTalents:
|
|
||||||
ushort talentCount = msg.ReadUInt16();
|
|
||||||
for (int i = 0; i < talentCount; i++)
|
|
||||||
{
|
|
||||||
bool addedThisRound = msg.ReadBoolean();
|
|
||||||
UInt32 talentIdentifier = msg.ReadUInt32();
|
|
||||||
GiveTalent(talentIdentifier, addedThisRound);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 12: //NetEntityEvent.Type.UpdateMoney:
|
|
||||||
int moneyAmount = msg.ReadInt32();
|
|
||||||
SetMoney(moneyAmount);
|
|
||||||
break;
|
|
||||||
case 13: //NetEntityEvent.Type.UpdatePermanentStats:
|
|
||||||
byte savedStatValueCount = msg.ReadByte();
|
|
||||||
StatTypes statType = (StatTypes)msg.ReadByte();
|
|
||||||
info?.ClearSavedStatValues(statType);
|
|
||||||
for (int i = 0; i < savedStatValueCount; i++)
|
|
||||||
{
|
|
||||||
string statIdentifier = msg.ReadString();
|
|
||||||
float statValue = msg.ReadSingle();
|
|
||||||
bool removeOnDeath = msg.ReadBoolean();
|
|
||||||
info?.ChangeSavedStatValue(statType, statValue, statIdentifier, removeOnDeath, setValue: true);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
msg.ReadPadBits();
|
|
||||||
break;
|
break;
|
||||||
|
case EventType.UpdateTalents:
|
||||||
|
ushort talentCount = msg.ReadUInt16();
|
||||||
|
for (int i = 0; i < talentCount; i++)
|
||||||
|
{
|
||||||
|
bool addedThisRound = msg.ReadBoolean();
|
||||||
|
UInt32 talentIdentifier = msg.ReadUInt32();
|
||||||
|
GiveTalent(talentIdentifier, addedThisRound);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EventType.UpdateMoney:
|
||||||
|
int moneyAmount = msg.ReadInt32();
|
||||||
|
SetMoney(moneyAmount);
|
||||||
|
break;
|
||||||
|
case EventType.UpdatePermanentStats:
|
||||||
|
byte savedStatValueCount = msg.ReadByte();
|
||||||
|
StatTypes statType = (StatTypes)msg.ReadByte();
|
||||||
|
info?.ClearSavedStatValues(statType);
|
||||||
|
for (int i = 0; i < savedStatValueCount; i++)
|
||||||
|
{
|
||||||
|
string statIdentifier = msg.ReadString();
|
||||||
|
float statValue = msg.ReadSingle();
|
||||||
|
bool removeOnDeath = msg.ReadBoolean();
|
||||||
|
info?.ChangeSavedStatValue(statType, statValue, statIdentifier, removeOnDeath, setValue: true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
msg.ReadPadBits();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Character ReadSpawnData(IReadMessage inc)
|
public static Character ReadSpawnData(IReadMessage inc)
|
||||||
@@ -542,9 +551,11 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
bool hasOwner = inc.ReadBoolean();
|
bool hasOwner = inc.ReadBoolean();
|
||||||
int ownerId = hasOwner ? inc.ReadByte() : -1;
|
int ownerId = hasOwner ? inc.ReadByte() : -1;
|
||||||
|
int balance = hasOwner ? inc.ReadInt32() : -1;
|
||||||
|
int rewardDistribution = hasOwner ? inc.ReadRangedInteger(0, 100) : -1;
|
||||||
byte teamID = inc.ReadByte();
|
byte teamID = inc.ReadByte();
|
||||||
bool hasAi = inc.ReadBoolean();
|
bool hasAi = inc.ReadBoolean();
|
||||||
string infoSpeciesName = inc.ReadString();
|
Identifier infoSpeciesName = inc.ReadIdentifier();
|
||||||
|
|
||||||
CharacterInfo info = CharacterInfo.ClientRead(infoSpeciesName, inc);
|
CharacterInfo info = CharacterInfo.ClientRead(infoSpeciesName, inc);
|
||||||
try
|
try
|
||||||
@@ -558,6 +569,12 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
character.TeamID = (CharacterTeamType)teamID;
|
character.TeamID = (CharacterTeamType)teamID;
|
||||||
character.CampaignInteractionType = (CampaignMode.InteractionType)inc.ReadByte();
|
character.CampaignInteractionType = (CampaignMode.InteractionType)inc.ReadByte();
|
||||||
|
if (character.CampaignInteractionType == CampaignMode.InteractionType.Store)
|
||||||
|
{
|
||||||
|
character.MerchantIdentifier = inc.ReadIdentifier();
|
||||||
|
}
|
||||||
|
character.Wallet.Balance = balance;
|
||||||
|
character.Wallet.RewardDistribution = rewardDistribution;
|
||||||
if (character.CampaignInteractionType != CampaignMode.InteractionType.None)
|
if (character.CampaignInteractionType != CampaignMode.InteractionType.None)
|
||||||
{
|
{
|
||||||
(GameMain.GameSession.GameMode as CampaignMode)?.AssignNPCMenuInteraction(character, character.CampaignInteractionType);
|
(GameMain.GameSession.GameMode as CampaignMode)?.AssignNPCMenuInteraction(character, character.CampaignInteractionType);
|
||||||
@@ -567,7 +584,7 @@ namespace Barotrauma
|
|||||||
int orderCount = inc.ReadByte();
|
int orderCount = inc.ReadByte();
|
||||||
for (int i = 0; i < orderCount; i++)
|
for (int i = 0; i < orderCount; i++)
|
||||||
{
|
{
|
||||||
int orderPrefabIndex = inc.ReadByte();
|
UInt32 orderPrefabUintIdentifier = inc.ReadUInt32();
|
||||||
Entity targetEntity = FindEntityByID(inc.ReadUInt16());
|
Entity targetEntity = FindEntityByID(inc.ReadUInt16());
|
||||||
Character orderGiver = inc.ReadBoolean() ? FindEntityByID(inc.ReadUInt16()) as Character : null;
|
Character orderGiver = inc.ReadBoolean() ? FindEntityByID(inc.ReadUInt16()) as Character : null;
|
||||||
int orderOptionIndex = inc.ReadByte();
|
int orderOptionIndex = inc.ReadByte();
|
||||||
@@ -581,18 +598,23 @@ namespace Barotrauma
|
|||||||
targetPosition = new OrderTarget(new Vector2(x, y), hull, creatingFromExistingData: true);
|
targetPosition = new OrderTarget(new Vector2(x, y), hull, creatingFromExistingData: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (orderPrefabIndex >= 0 && orderPrefabIndex < Order.PrefabList.Count)
|
OrderPrefab orderPrefab =
|
||||||
|
OrderPrefab.Prefabs.Find(p => p.UintIdentifier == orderPrefabUintIdentifier);
|
||||||
|
if (orderPrefab != null)
|
||||||
{
|
{
|
||||||
var orderPrefab = Order.PrefabList[orderPrefabIndex];
|
|
||||||
var component = orderPrefab.GetTargetItemComponent(targetEntity as Item);
|
var component = orderPrefab.GetTargetItemComponent(targetEntity as Item);
|
||||||
if (!orderPrefab.MustSetTarget || (targetEntity != null && component != null) || targetPosition != null)
|
if (!orderPrefab.MustSetTarget || (targetEntity != null && component != null) || targetPosition != null)
|
||||||
{
|
{
|
||||||
var order = targetPosition == null ?
|
var order = targetPosition == null ?
|
||||||
new Order(orderPrefab, targetEntity, component, orderGiver: orderGiver) :
|
new Order(orderPrefab, targetEntity, component, orderGiver: orderGiver) :
|
||||||
new Order(orderPrefab, targetPosition, orderGiver: orderGiver);
|
new Order(orderPrefab, targetPosition, orderGiver: orderGiver);
|
||||||
character.SetOrder(order,
|
order = order.WithOption(
|
||||||
orderOptionIndex >= 0 && orderOptionIndex < orderPrefab.Options.Length ? orderPrefab.Options[orderOptionIndex] : null,
|
orderOptionIndex >= 0 && orderOptionIndex < orderPrefab.Options.Length
|
||||||
orderPriority, orderGiver, speak: false, force: true);
|
? orderPrefab.Options[orderOptionIndex]
|
||||||
|
: Identifier.Empty)
|
||||||
|
.WithManualPriority(orderPriority)
|
||||||
|
.WithOrderGiver(orderGiver);
|
||||||
|
character.SetOrder(order, isNewOrder: true, speak: false, force: true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -601,7 +623,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Invalid order prefab index - index (" + orderPrefabIndex + ") out of bounds.");
|
DebugConsole.ThrowError("Invalid order prefab index - index (" + orderPrefabUintIdentifier + ") out of bounds.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Barotrauma.Sounds;
|
using Barotrauma.Sounds;
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -13,20 +14,17 @@ namespace Barotrauma
|
|||||||
public readonly CharacterParams.SoundParams Params;
|
public readonly CharacterParams.SoundParams Params;
|
||||||
|
|
||||||
public SoundType Type => Params.State;
|
public SoundType Type => Params.State;
|
||||||
public Gender Gender => Params.Gender;
|
public ImmutableHashSet<Identifier> TagSet => Params.TagSet;
|
||||||
public float Volume => roundSound == null ? 0.0f : roundSound.Volume;
|
public float Volume => roundSound == null ? 0.0f : roundSound.Volume;
|
||||||
public float Range => roundSound == null ? 0.0f : roundSound.Range;
|
public float Range => roundSound == null ? 0.0f : roundSound.Range;
|
||||||
public Sound Sound => roundSound?.Sound;
|
public Sound Sound => roundSound?.Sound;
|
||||||
|
|
||||||
public bool IgnoreMuffling
|
public bool IgnoreMuffling => roundSound?.IgnoreMuffling ?? false;
|
||||||
{
|
|
||||||
get { return roundSound?.IgnoreMuffling ?? false; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public CharacterSound(CharacterParams.SoundParams soundParams)
|
public CharacterSound(CharacterParams.SoundParams soundParams)
|
||||||
{
|
{
|
||||||
Params = soundParams;
|
Params = soundParams;
|
||||||
roundSound = Submarine.LoadRoundSound(soundParams.Element);
|
roundSound = RoundSound.Load(soundParams.Element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ namespace Barotrauma
|
|||||||
public Vector2 Size;
|
public Vector2 Size;
|
||||||
|
|
||||||
private readonly Submarine parentSub;
|
private readonly Submarine parentSub;
|
||||||
public string Text
|
public LocalizedString Text
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
private set;
|
private set;
|
||||||
@@ -58,7 +58,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
public HUDProgressBar(Vector2 worldPosition, string textTag, Submarine parentSubmarine = null)
|
public HUDProgressBar(Vector2 worldPosition, string textTag, Submarine parentSubmarine = null)
|
||||||
: this(worldPosition, parentSubmarine, GUI.Style.Red, GUI.Style.Green, textTag)
|
: this(worldPosition, parentSubmarine, GUIStyle.Red, GUIStyle.Green, textTag)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ namespace Barotrauma
|
|||||||
if (!string.IsNullOrEmpty(textTag))
|
if (!string.IsNullOrEmpty(textTag))
|
||||||
{
|
{
|
||||||
this.textTag = textTag;
|
this.textTag = textTag;
|
||||||
Text = TextManager.Get(textTag);
|
Text = TextManager.Get(textTag).Fallback(textTag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,12 +101,12 @@ namespace Barotrauma
|
|||||||
color * a,
|
color * a,
|
||||||
Color.White * a * 0.8f);
|
Color.White * a * 0.8f);
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(Text))
|
if (!Text.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
Vector2 textSize = GUI.SmallFont.MeasureString(Text);
|
Vector2 textSize = GUIStyle.SmallFont.MeasureString(Text);
|
||||||
Vector2 textPos = new Vector2(pos.X + (Size.X - textSize.X) / 2, pos.Y - textSize.Y * 1.2f);
|
Vector2 textPos = new Vector2(pos.X + (Size.X - textSize.X) / 2, pos.Y - textSize.Y * 1.2f);
|
||||||
GUI.DrawString(spriteBatch, textPos - Vector2.One, Text, Color.Black * a, font: GUI.SmallFont);
|
GUI.DrawString(spriteBatch, textPos - Vector2.One, Text, Color.Black * a, font: GUIStyle.SmallFont);
|
||||||
GUI.DrawString(spriteBatch, textPos, Text, Color.White * a, font: GUI.SmallFont);
|
GUI.DrawString(spriteBatch, textPos, Text, Color.White * a, font: GUIStyle.SmallFont);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
namespace Barotrauma
|
|
||||||
{
|
|
||||||
partial class AfflictionHusk : Affliction
|
|
||||||
{
|
|
||||||
private InfectionState? prevDisplayedMessage;
|
|
||||||
partial void UpdateMessages()
|
|
||||||
{
|
|
||||||
if (character != Character.Controlled) { return; }
|
|
||||||
if (Prefab is AfflictionPrefabHusk { SendMessages: false }) { return; }
|
|
||||||
if (prevDisplayedMessage.HasValue && prevDisplayedMessage.Value == State) { return; }
|
|
||||||
|
|
||||||
switch (State)
|
|
||||||
{
|
|
||||||
case InfectionState.Dormant:
|
|
||||||
if (Strength < DormantThreshold * 0.5f)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
GUI.AddMessage(TextManager.Get("HuskDormant"), GUI.Style.Red);
|
|
||||||
break;
|
|
||||||
case InfectionState.Transition:
|
|
||||||
GUI.AddMessage(TextManager.Get("HuskCantSpeak"), GUI.Style.Red);
|
|
||||||
break;
|
|
||||||
case InfectionState.Active:
|
|
||||||
if (character.Params.UseHuskAppendage)
|
|
||||||
{
|
|
||||||
GUI.AddMessage(TextManager.GetWithVariable("HuskActivate", "[Attack]", GameMain.Config.KeyBindText(InputType.Attack)), GUI.Style.Red);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case InfectionState.Final:
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
prevDisplayedMessage = State;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -75,7 +75,7 @@ namespace Barotrauma
|
|||||||
case FloodType.Minor:
|
case FloodType.Minor:
|
||||||
currentFloodState += deltaTime;
|
currentFloodState += deltaTime;
|
||||||
//lerp the water surface in all hulls 15 units above the floor within 10 seconds
|
//lerp the water surface in all hulls 15 units above the floor within 10 seconds
|
||||||
foreach (Hull hull in Hull.hullList)
|
foreach (Hull hull in Hull.HullList)
|
||||||
{
|
{
|
||||||
for (int i = hull.FakeFireSources.Count - 1; i >= 0; i--)
|
for (int i = hull.FakeFireSources.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
@@ -87,7 +87,7 @@ namespace Barotrauma
|
|||||||
case FloodType.Major:
|
case FloodType.Major:
|
||||||
currentFloodState += deltaTime;
|
currentFloodState += deltaTime;
|
||||||
//create a full flood in 10 seconds
|
//create a full flood in 10 seconds
|
||||||
foreach (Hull hull in Hull.hullList)
|
foreach (Hull hull in Hull.HullList)
|
||||||
{
|
{
|
||||||
for (int i = hull.FakeFireSources.Count - 1; i >= 0; i--)
|
for (int i = hull.FakeFireSources.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
@@ -98,7 +98,7 @@ namespace Barotrauma
|
|||||||
break;
|
break;
|
||||||
case FloodType.HideFlooding:
|
case FloodType.HideFlooding:
|
||||||
//hide water inside hulls (the player can't see which hulls are flooded)
|
//hide water inside hulls (the player can't see which hulls are flooded)
|
||||||
foreach (Hull hull in Hull.hullList)
|
foreach (Hull hull in Hull.HullList)
|
||||||
{
|
{
|
||||||
hull.DrawSurface = hull.Rect.Y - hull.Rect.Height;
|
hull.DrawSurface = hull.Rect.Y - hull.Rect.Height;
|
||||||
}
|
}
|
||||||
@@ -140,7 +140,7 @@ namespace Barotrauma
|
|||||||
character.Submarine != null &&
|
character.Submarine != null &&
|
||||||
createFireSourceTimer > MathHelper.Lerp(MaxFakeFireSourceInterval, MinFakeFireSourceInterval, Strength / 100.0f))
|
createFireSourceTimer > MathHelper.Lerp(MaxFakeFireSourceInterval, MinFakeFireSourceInterval, Strength / 100.0f))
|
||||||
{
|
{
|
||||||
Hull fireHull = Hull.hullList.GetRandom(h => h.Submarine == character.Submarine);
|
Hull fireHull = Hull.HullList.GetRandomUnsynced(h => h.Submarine == character.Submarine);
|
||||||
if (fireHull != null)
|
if (fireHull != null)
|
||||||
{
|
{
|
||||||
var fakeFire = new DummyFireSource(Vector2.One * 500.0f, new Vector2(Rand.Range(fireHull.WorldRect.X, fireHull.WorldRect.Right), fireHull.WorldPosition.Y + 1), fireHull, isNetworkMessage: true)
|
var fakeFire = new DummyFireSource(Vector2.One * 500.0f, new Vector2(Rand.Range(fireHull.WorldRect.X, fireHull.WorldRect.Right), fireHull.WorldPosition.Y + 1), fireHull, isNetworkMessage: true)
|
||||||
|
|||||||
@@ -14,11 +14,31 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
private static bool toggledThisFrame;
|
private static bool toggledThisFrame;
|
||||||
|
|
||||||
public static Sprite DamageOverlay;
|
public class DamageOverlayPrefab : Prefab
|
||||||
|
{
|
||||||
|
public readonly static PrefabSelector<DamageOverlayPrefab> Prefabs = new PrefabSelector<DamageOverlayPrefab>();
|
||||||
|
|
||||||
public static string DamageOverlayFile;
|
public readonly Sprite DamageOverlay;
|
||||||
|
|
||||||
private static string[] strengthTexts;
|
public DamageOverlayPrefab(ContentXElement element, AfflictionsFile file) : base(file, file.Path.Value.ToIdentifier())
|
||||||
|
{
|
||||||
|
DamageOverlay = new Sprite(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
DamageOverlay.Remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Sprite DamageOverlay => DamageOverlayPrefab.Prefabs.ActivePrefab.DamageOverlay;
|
||||||
|
|
||||||
|
private readonly static LocalizedString[] strengthTexts = new LocalizedString[]
|
||||||
|
{
|
||||||
|
TextManager.Get("AfflictionStrengthLow"),
|
||||||
|
TextManager.Get("AfflictionStrengthMedium"),
|
||||||
|
TextManager.Get("AfflictionStrengthHigh")
|
||||||
|
};
|
||||||
|
|
||||||
private Point screenResolution;
|
private Point screenResolution;
|
||||||
|
|
||||||
@@ -134,7 +154,7 @@ namespace Barotrauma
|
|||||||
Character.Controlled.ResetInteract = true;
|
Character.Controlled.ResetInteract = true;
|
||||||
if (openHealthWindow != null)
|
if (openHealthWindow != null)
|
||||||
{
|
{
|
||||||
if (value.Character.Info == null || value.Character == Character.Controlled || Character.Controlled.HasEquippedItem("healthscanner"))
|
if (value.Character.Info == null || value.Character == Character.Controlled || Character.Controlled.HasEquippedItem("healthscanner".ToIdentifier()))
|
||||||
{
|
{
|
||||||
openHealthWindow.characterName.Text = value.Character.Name;
|
openHealthWindow.characterName.Text = value.Character.Name;
|
||||||
}
|
}
|
||||||
@@ -173,20 +193,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private GUIFrame healthBarHolder;
|
private GUIFrame healthBarHolder;
|
||||||
|
|
||||||
partial void InitProjSpecific(XElement element, Character character)
|
partial void InitProjSpecific(ContentXElement element, Character character)
|
||||||
{
|
{
|
||||||
DisplayedVitality = MaxVitality;
|
DisplayedVitality = MaxVitality;
|
||||||
|
|
||||||
if (strengthTexts == null)
|
|
||||||
{
|
|
||||||
strengthTexts = new string[]
|
|
||||||
{
|
|
||||||
TextManager.Get("AfflictionStrengthLow"),
|
|
||||||
TextManager.Get("AfflictionStrengthMedium"),
|
|
||||||
TextManager.Get("AfflictionStrengthHigh")
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
character.OnAttacked += OnAttacked;
|
character.OnAttacked += OnAttacked;
|
||||||
|
|
||||||
healthWindow = new GUIFrame(new RectTransform(new Vector2(0.35f, 0.6f), GUI.Canvas, anchor: Anchor.Center, scaleBasis: ScaleBasis.Smallest), style: "GUIFrameListBox");
|
healthWindow = new GUIFrame(new RectTransform(new Vector2(0.35f, 0.6f), GUI.Canvas, anchor: Anchor.Center, scaleBasis: ScaleBasis.Smallest), style: "GUIFrameListBox");
|
||||||
@@ -206,7 +216,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
character.Info?.DrawPortrait(spriteBatch, new Vector2(component.Rect.X, component.Rect.Center.Y - component.Rect.Width / 2), Vector2.Zero, component.Rect.Width, false, character != Character.Controlled);
|
character.Info?.DrawPortrait(spriteBatch, new Vector2(component.Rect.X, component.Rect.Center.Y - component.Rect.Width / 2), Vector2.Zero, component.Rect.Width, false, character != Character.Controlled);
|
||||||
});
|
});
|
||||||
characterName = new GUITextBlock(new RectTransform(new Vector2(0.6f, 1.0f), nameContainer.RectTransform), "", textAlignment: Alignment.CenterLeft, font: GUI.SubHeadingFont)
|
characterName = new GUITextBlock(new RectTransform(new Vector2(0.6f, 1.0f), nameContainer.RectTransform), "", textAlignment: Alignment.CenterLeft, font: GUIStyle.SubHeadingFont)
|
||||||
{
|
{
|
||||||
AutoScaleHorizontal = true
|
AutoScaleHorizontal = true
|
||||||
};
|
};
|
||||||
@@ -220,12 +230,12 @@ namespace Barotrauma
|
|||||||
var healthBarContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.07f), healthWindowVerticalLayout.RectTransform), style: null);
|
var healthBarContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.07f), healthWindowVerticalLayout.RectTransform), style: null);
|
||||||
var healthBarIcon = new GUIFrame(new RectTransform(new Vector2(0.095f, 1.0f), healthBarContainer.RectTransform), style: "GUIHealthBarIcon");
|
var healthBarIcon = new GUIFrame(new RectTransform(new Vector2(0.095f, 1.0f), healthBarContainer.RectTransform), style: "GUIHealthBarIcon");
|
||||||
healthWindowHealthBarShadow = new GUIProgressBar(new RectTransform(new Vector2(0.91f, 1.0f), healthBarContainer.RectTransform, Anchor.CenterRight),
|
healthWindowHealthBarShadow = new GUIProgressBar(new RectTransform(new Vector2(0.91f, 1.0f), healthBarContainer.RectTransform, Anchor.CenterRight),
|
||||||
barSize: 1.0f, color: GUI.Style.Green, style: "GUIHealthBar")
|
barSize: 1.0f, color: GUIStyle.Green, style: "GUIHealthBar")
|
||||||
{
|
{
|
||||||
IsHorizontal = true
|
IsHorizontal = true
|
||||||
};
|
};
|
||||||
healthWindowHealthBar = new GUIProgressBar(new RectTransform(new Vector2(0.91f, 1.0f), healthBarContainer.RectTransform, Anchor.CenterRight),
|
healthWindowHealthBar = new GUIProgressBar(new RectTransform(new Vector2(0.91f, 1.0f), healthBarContainer.RectTransform, Anchor.CenterRight),
|
||||||
barSize: 1.0f, color: GUI.Style.Green, style: "GUIHealthBar")
|
barSize: 1.0f, color: GUIStyle.Green, style: "GUIHealthBar")
|
||||||
{
|
{
|
||||||
IsHorizontal = true
|
IsHorizontal = true
|
||||||
};
|
};
|
||||||
@@ -290,7 +300,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (GameMain.Client != null)
|
if (GameMain.Client != null)
|
||||||
{
|
{
|
||||||
GameMain.Client.CreateEntityEvent(Character.Controlled, new object[] { NetEntityEvent.Type.Treatment });
|
GameMain.Client.CreateEntityEvent(Character.Controlled, new Character.TreatmentEventData());
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -311,7 +321,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
deadIndicator = new GUITextBlock(new RectTransform(new Vector2(0.9f, 0.1f), limbSelection.RectTransform, Anchor.Center),
|
deadIndicator = new GUITextBlock(new RectTransform(new Vector2(0.9f, 0.1f), limbSelection.RectTransform, Anchor.Center),
|
||||||
text: TextManager.Get("Deceased"), font: GUI.LargeFont, textAlignment: Alignment.Center, style: "GUIToolTip")
|
text: TextManager.Get("Deceased"), font: GUIStyle.LargeFont, textAlignment: Alignment.Center, style: "GUIToolTip")
|
||||||
{
|
{
|
||||||
Visible = false,
|
Visible = false,
|
||||||
CanBeFocused = false
|
CanBeFocused = false
|
||||||
@@ -328,7 +338,7 @@ namespace Barotrauma
|
|||||||
afflictionIconContainer = new GUIListBox(new RectTransform(new Vector2(0.25f, 1.0f), characterIndicatorArea.RectTransform), style: null);
|
afflictionIconContainer = new GUIListBox(new RectTransform(new Vector2(0.25f, 1.0f), characterIndicatorArea.RectTransform), style: null);
|
||||||
|
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.1f), healthWindowVerticalLayout.RectTransform),
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.1f), healthWindowVerticalLayout.RectTransform),
|
||||||
TextManager.Get("SuitableTreatments"), font: GUI.SubHeadingFont, textAlignment: Alignment.BottomCenter);
|
TextManager.Get("SuitableTreatments"), font: GUIStyle.SubHeadingFont, textAlignment: Alignment.BottomCenter);
|
||||||
|
|
||||||
treatmentLayout = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.15f), healthWindowVerticalLayout.RectTransform), true)
|
treatmentLayout = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.15f), healthWindowVerticalLayout.RectTransform), true)
|
||||||
{
|
{
|
||||||
@@ -366,10 +376,10 @@ namespace Barotrauma
|
|||||||
healthShadowSize = 1.0f;
|
healthShadowSize = 1.0f;
|
||||||
|
|
||||||
healthBar = new GUIProgressBar(new RectTransform(Vector2.One, healthBarHolder.RectTransform, Anchor.BottomRight),
|
healthBar = new GUIProgressBar(new RectTransform(Vector2.One, healthBarHolder.RectTransform, Anchor.BottomRight),
|
||||||
barSize: 1.0f, color: GUI.Style.HealthBarColorHigh, style: "CharacterHealthBar")
|
barSize: 1.0f, color: GUIStyle.HealthBarColorHigh, style: "CharacterHealthBar")
|
||||||
{
|
{
|
||||||
HoverCursor = CursorState.Hand,
|
HoverCursor = CursorState.Hand,
|
||||||
ToolTip = TextManager.GetWithVariable("hudbutton.healthinterface", "[key]", GameMain.Config.KeyBindText(InputType.Health)),
|
ToolTip = TextManager.GetWithVariable("hudbutton.healthinterface", "[key]", GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Health)),
|
||||||
Enabled = true
|
Enabled = true
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -390,7 +400,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (GameMain.Client != null)
|
if (GameMain.Client != null)
|
||||||
{
|
{
|
||||||
GameMain.Client.CreateEntityEvent(Character.Controlled, new object[] { NetEntityEvent.Type.Status });
|
GameMain.Client.CreateEntityEvent(Character.Controlled, new Character.CharacterStatusEventData());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -406,7 +416,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (element != null)
|
if (element != null)
|
||||||
{
|
{
|
||||||
foreach (XElement subElement in element.Elements())
|
foreach (var subElement in element.Elements())
|
||||||
{
|
{
|
||||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||||
{
|
{
|
||||||
@@ -501,7 +511,17 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (prevOxygen > 0.0f && OxygenAmount <= 0.0f && Character.Controlled == Character)
|
if (prevOxygen > 0.0f && OxygenAmount <= 0.0f && Character.Controlled == Character)
|
||||||
{
|
{
|
||||||
SoundPlayer.PlaySound(Character.Info != null && Character.Info.Gender == Gender.Female ? "drownfemale" : "drownmale");
|
string soundName;
|
||||||
|
if (Character.Info != null)
|
||||||
|
{
|
||||||
|
soundName = Character.Info.ReplaceVars($"drown[{Character.Info.Prefab.MenuCategoryVar}]");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var charInfoPrefab = CharacterPrefab.HumanPrefab.CharacterInfoPrefab;
|
||||||
|
soundName = charInfoPrefab.ReplaceVars($"drown[{charInfoPrefab.MenuCategoryVar}]", charInfoPrefab.Heads.First());
|
||||||
|
}
|
||||||
|
SoundPlayer.PlaySound(soundName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Character == Character.Controlled && !IsUnconscious && !Character.IsDead && OxygenAmount < LowOxygenThreshold)
|
if (Character == Character.Controlled && !IsUnconscious && !Character.IsDead && OxygenAmount < LowOxygenThreshold)
|
||||||
@@ -553,10 +573,10 @@ namespace Barotrauma
|
|||||||
inWater ? Character.Params.BleedParticleWater : Character.Params.BleedParticleAir,
|
inWater ? Character.Params.BleedParticleWater : Character.Params.BleedParticleAir,
|
||||||
limb.WorldPosition, velocity, 0.0f, Character.AnimController.CurrentHull);
|
limb.WorldPosition, velocity, 0.0f, Character.AnimController.CurrentHull);
|
||||||
|
|
||||||
if (blood != null && !inWater)
|
if (blood != null)
|
||||||
{
|
{
|
||||||
blood.Size *= bloodParticleSize;
|
blood.Size *= bloodParticleSize;
|
||||||
if (!string.IsNullOrEmpty(Character.BloodDecalName) && Rand.Range(0.0f, 1.0f) < 0.05f)
|
if (!inWater && !string.IsNullOrEmpty(Character.BloodDecalName) && Rand.Range(0.0f, 1.0f) < 0.05f)
|
||||||
{
|
{
|
||||||
blood.OnCollision += (Vector2 pos, Hull hull) =>
|
blood.OnCollision += (Vector2 pos, Hull hull) =>
|
||||||
{
|
{
|
||||||
@@ -715,11 +735,11 @@ namespace Barotrauma
|
|||||||
if (!(afflictionIcon.UserData is Affliction affliction)) { continue; }
|
if (!(afflictionIcon.UserData is Affliction affliction)) { continue; }
|
||||||
if (affliction.AppliedAsFailedTreatmentTime > Timing.TotalTime - 1.0 && afflictionIcon.FlashTimer <= 0.0f)
|
if (affliction.AppliedAsFailedTreatmentTime > Timing.TotalTime - 1.0 && afflictionIcon.FlashTimer <= 0.0f)
|
||||||
{
|
{
|
||||||
afflictionIcon.Flash(GUI.Style.Red);
|
afflictionIcon.Flash(GUIStyle.Red);
|
||||||
}
|
}
|
||||||
else if (affliction.AppliedAsSuccessfulTreatmentTime > Timing.TotalTime - 1.0 && afflictionIcon.FlashTimer <= 0.0f)
|
else if (affliction.AppliedAsSuccessfulTreatmentTime > Timing.TotalTime - 1.0 && afflictionIcon.FlashTimer <= 0.0f)
|
||||||
{
|
{
|
||||||
afflictionIcon.Flash(GUI.Style.Green);
|
afflictionIcon.Flash(GUIStyle.Green);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -754,7 +774,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
var labelContainer = afflictionTooltip.Content.GetChildByUserData("label");
|
var labelContainer = afflictionTooltip.Content.GetChildByUserData("label");
|
||||||
|
|
||||||
labelContainer.RectTransform.Resize(new Point(labelContainer.Rect.Width, (int)(GUI.LargeFont.Size * 1.5f)));
|
labelContainer.RectTransform.Resize(new Point(labelContainer.Rect.Width, (int)(GUIStyle.LargeFont.Size * 1.5f)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -799,7 +819,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
var treatmentButton = component.GetChild<GUIButton>();
|
var treatmentButton = component.GetChild<GUIButton>();
|
||||||
if (!(treatmentButton?.UserData is ItemPrefab itemPrefab)) { continue; }
|
if (!(treatmentButton?.UserData is ItemPrefab itemPrefab)) { continue; }
|
||||||
var matchingItem = Character.Controlled.Inventory.FindItem(it => it.prefab == itemPrefab, recursive: true);
|
var matchingItem = Character.Controlled.Inventory.FindItem(it => it.Prefab == itemPrefab, recursive: true);
|
||||||
treatmentButton.Enabled = matchingItem != null;
|
treatmentButton.Enabled = matchingItem != null;
|
||||||
if (treatmentButton.Enabled && treatmentButton.State == GUIComponent.ComponentState.Hover)
|
if (treatmentButton.Enabled && treatmentButton.State == GUIComponent.ComponentState.Hover)
|
||||||
{
|
{
|
||||||
@@ -809,16 +829,18 @@ namespace Barotrauma
|
|||||||
if (Character.Controlled.Inventory.visualSlots != null && index > -1 && index < Character.Controlled.Inventory.visualSlots.Length &&
|
if (Character.Controlled.Inventory.visualSlots != null && index > -1 && index < Character.Controlled.Inventory.visualSlots.Length &&
|
||||||
Character.Controlled.Inventory.visualSlots[index].HighlightTimer <= 0.0f)
|
Character.Controlled.Inventory.visualSlots[index].HighlightTimer <= 0.0f)
|
||||||
{
|
{
|
||||||
Character.Controlled.Inventory.visualSlots[index].ShowBorderHighlight(GUI.Style.Green, 0.5f, 0.5f);
|
Character.Controlled.Inventory.visualSlots[index].ShowBorderHighlight(GUIStyle.Green, 0.5f, 0.5f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (matchingItem != null && !string.IsNullOrEmpty(treatmentButton.ToolTip)) { continue; }
|
if (matchingItem != null && !treatmentButton.ToolTip.IsNullOrEmpty()) { continue; }
|
||||||
treatmentButton.ToolTip = $"‖color:255,255,255,255‖{itemPrefab.Name}‖color:end‖" + '\n' + itemPrefab.Description;
|
treatmentButton.ToolTip = RichString.Rich($"‖color:255,255,255,255‖{itemPrefab.Name}‖color:end‖" + '\n' + itemPrefab.Description);
|
||||||
if (treatmentButton.Enabled)
|
if (treatmentButton.Enabled)
|
||||||
{
|
{
|
||||||
treatmentButton.ToolTip =
|
treatmentButton.ToolTip =
|
||||||
$"‖color:gui.green‖[{TextManager.Get(PlayerInput.MouseButtonsSwapped() ? "input.rightmouse" : "input.leftmouse")}] {TextManager.Get("quickuseaction.usetreatment")}‖color:end‖" + '\n'
|
RichString.Rich(
|
||||||
+ treatmentButton.RawToolTip;
|
$"‖color:gui.green‖[{TextManager.Get(PlayerInput.MouseButtonsSwapped() ? "input.rightmouse" : "input.leftmouse")}] "
|
||||||
|
+ $"{TextManager.Get("quickuseaction.usetreatment")}‖color:end‖" + '\n'
|
||||||
|
+ treatmentButton.ToolTip.NestedStr);
|
||||||
}
|
}
|
||||||
foreach (GUIComponent child in treatmentButton.Children)
|
foreach (GUIComponent child in treatmentButton.Children)
|
||||||
{
|
{
|
||||||
@@ -834,7 +856,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
healthBar.Color = healthWindowHealthBar.Color = ToolBox.GradientLerp(DisplayedVitality / MaxVitality, GUI.Style.HealthBarColorLow, GUI.Style.HealthBarColorMedium, GUI.Style.HealthBarColorHigh);
|
healthBar.Color = healthWindowHealthBar.Color = ToolBox.GradientLerp(DisplayedVitality / MaxVitality, GUIStyle.HealthBarColorLow, GUIStyle.HealthBarColorMedium, GUIStyle.HealthBarColorHigh);
|
||||||
healthBar.HoverColor = healthWindowHealthBar.HoverColor = healthBar.Color * 2.0f;
|
healthBar.HoverColor = healthWindowHealthBar.HoverColor = healthBar.Color * 2.0f;
|
||||||
healthBar.BarSize = healthWindowHealthBar.BarSize =
|
healthBar.BarSize = healthWindowHealthBar.BarSize =
|
||||||
(DisplayedVitality > 0.0f) ?
|
(DisplayedVitality > 0.0f) ?
|
||||||
@@ -1007,14 +1029,14 @@ namespace Barotrauma
|
|||||||
DrawStatusHUD(spriteBatch);
|
DrawStatusHUD(spriteBatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
private (Affliction affliction, string text)? highlightedAfflictionIcon;
|
private (Affliction Affliction, LocalizedString NameToolTip)? highlightedAfflictionIcon = null;
|
||||||
public void DrawStatusHUD(SpriteBatch spriteBatch)
|
public void DrawStatusHUD(SpriteBatch spriteBatch)
|
||||||
{
|
{
|
||||||
highlightedAfflictionIcon = null;
|
highlightedAfflictionIcon = null;
|
||||||
//Rectangle interactArea = healthBar.Rect;
|
//Rectangle interactArea = healthBar.Rect;
|
||||||
if (Character.Controlled?.SelectedCharacter == null && openHealthWindow == null)
|
if (Character.Controlled?.SelectedCharacter == null && openHealthWindow == null)
|
||||||
{
|
{
|
||||||
List<(Affliction affliction, string text)> statusIcons = new List<(Affliction affliction, string text)>();
|
var statusIcons = new List<(Affliction Affliction, LocalizedString Warning)>();
|
||||||
if (Character.InPressure)
|
if (Character.InPressure)
|
||||||
{
|
{
|
||||||
statusIcons.Add((pressureAffliction, TextManager.Get("PressureHUDWarning")));
|
statusIcons.Add((pressureAffliction, TextManager.Get("PressureHUDWarning")));
|
||||||
@@ -1045,7 +1067,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
foreach (var statusIcon in statusIcons)
|
foreach (var statusIcon in statusIcons)
|
||||||
{
|
{
|
||||||
Affliction affliction = statusIcon.affliction;
|
Affliction affliction = statusIcon.Affliction;
|
||||||
AfflictionPrefab afflictionPrefab = affliction.Prefab;
|
AfflictionPrefab afflictionPrefab = affliction.Prefab;
|
||||||
|
|
||||||
Rectangle afflictionIconRect = new Rectangle(pos, new Point(iconSize));
|
Rectangle afflictionIconRect = new Rectangle(pos, new Point(iconSize));
|
||||||
@@ -1059,10 +1081,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Rectangle glowRect = afflictionIconRect;
|
Rectangle glowRect = afflictionIconRect;
|
||||||
glowRect.Inflate((int)(20 * GUI.Scale), (int)(20 * GUI.Scale));
|
glowRect.Inflate((int)(20 * GUI.Scale), (int)(20 * GUI.Scale));
|
||||||
var glow = GUI.Style.GetComponentStyle("OuterGlowCircular");
|
var glow = GUIStyle.GetComponentStyle("OuterGlowCircular");
|
||||||
glow.Sprites[GUIComponent.ComponentState.None][0].Draw(
|
glow.Sprites[GUIComponent.ComponentState.None][0].Draw(
|
||||||
spriteBatch, glowRect,
|
spriteBatch, glowRect,
|
||||||
GUI.Style.Red * (float)((Math.Sin(affliction.DamagePerSecondTimer * MathHelper.TwoPi - MathHelper.PiOver2) + 1.0f) * 0.5f));
|
GUIStyle.Red * (float)((Math.Sin(affliction.DamagePerSecondTimer * MathHelper.TwoPi - MathHelper.PiOver2) + 1.0f) * 0.5f));
|
||||||
}
|
}
|
||||||
|
|
||||||
float alphaMultiplier = highlightedAfflictionIcon == statusIcon ? 1f : 0.8f;
|
float alphaMultiplier = highlightedAfflictionIcon == statusIcon ? 1f : 0.8f;
|
||||||
@@ -1082,8 +1104,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (highlightedAfflictionIcon != null)
|
if (highlightedAfflictionIcon != null)
|
||||||
{
|
{
|
||||||
string nameTooltip = highlightedAfflictionIcon.Value.text;
|
LocalizedString nameTooltip = highlightedAfflictionIcon.Value.NameToolTip;
|
||||||
Vector2 offset = GUI.Font.MeasureString(nameTooltip);
|
Vector2 offset = GUIStyle.Font.MeasureString(nameTooltip);
|
||||||
|
|
||||||
GUI.DrawString(spriteBatch,
|
GUI.DrawString(spriteBatch,
|
||||||
alignment == Alignment.Left ? highlightedIconPos + offset : highlightedIconPos - offset,
|
alignment == Alignment.Left ? highlightedIconPos + offset : highlightedIconPos - offset,
|
||||||
@@ -1096,7 +1118,7 @@ namespace Barotrauma
|
|||||||
float currHealth = healthBar.BarSize;
|
float currHealth = healthBar.BarSize;
|
||||||
Color prevColor = healthBar.Color;
|
Color prevColor = healthBar.Color;
|
||||||
healthBarShadow.BarSize = healthShadowSize;
|
healthBarShadow.BarSize = healthShadowSize;
|
||||||
healthBarShadow.Color = Color.Lerp(GUI.Style.Red, Color.Black, 0.5f);
|
healthBarShadow.Color = Color.Lerp(GUIStyle.Red, Color.Black, 0.5f);
|
||||||
healthBarShadow.Visible = true;
|
healthBarShadow.Visible = true;
|
||||||
healthBar.BarSize = currHealth;
|
healthBar.BarSize = currHealth;
|
||||||
healthBar.Color = prevColor;
|
healthBar.Color = prevColor;
|
||||||
@@ -1113,7 +1135,7 @@ namespace Barotrauma
|
|||||||
float currHealth = healthWindowHealthBar.BarSize;
|
float currHealth = healthWindowHealthBar.BarSize;
|
||||||
Color prevColor = healthWindowHealthBar.Color;
|
Color prevColor = healthWindowHealthBar.Color;
|
||||||
healthWindowHealthBarShadow.BarSize = healthShadowSize;
|
healthWindowHealthBarShadow.BarSize = healthShadowSize;
|
||||||
healthWindowHealthBarShadow.Color = GUI.Style.Red;
|
healthWindowHealthBarShadow.Color = GUIStyle.Red;
|
||||||
healthWindowHealthBarShadow.Visible = true;
|
healthWindowHealthBarShadow.Visible = true;
|
||||||
healthWindowHealthBar.BarSize = currHealth;
|
healthWindowHealthBar.BarSize = currHealth;
|
||||||
healthWindowHealthBar.Color = prevColor;
|
healthWindowHealthBar.Color = prevColor;
|
||||||
@@ -1137,10 +1159,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (prefab.IsBuff)
|
if (prefab.IsBuff)
|
||||||
{
|
{
|
||||||
return ToolBox.GradientLerp(afflictionStrength / prefab.MaxStrength, GUI.Style.BuffColorLow, GUI.Style.BuffColorMedium, GUI.Style.BuffColorHigh);
|
return ToolBox.GradientLerp(afflictionStrength / prefab.MaxStrength, GUIStyle.BuffColorLow, GUIStyle.BuffColorMedium, GUIStyle.BuffColorHigh);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ToolBox.GradientLerp(afflictionStrength / prefab.MaxStrength, GUI.Style.DebuffColorLow, GUI.Style.DebuffColorMedium, GUI.Style.DebuffColorHigh);
|
return ToolBox.GradientLerp(afflictionStrength / prefab.MaxStrength, GUIStyle.DebuffColorLow, GUIStyle.DebuffColorMedium, GUIStyle.DebuffColorHigh);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ToolBox.GradientLerp(afflictionStrength / prefab.MaxStrength, prefab.IconColors);
|
return ToolBox.GradientLerp(afflictionStrength / prefab.MaxStrength, prefab.IconColors);
|
||||||
@@ -1213,7 +1235,7 @@ namespace Barotrauma
|
|||||||
CanBeFocused = false
|
CanBeFocused = false
|
||||||
};
|
};
|
||||||
|
|
||||||
var progressbarBg = new GUIProgressBar(new RectTransform(new Vector2(1.0f, 0.18f), content.RectTransform), 0.0f, GUI.Style.Green, style: "GUIAfflictionBar")
|
var progressbarBg = new GUIProgressBar(new RectTransform(new Vector2(1.0f, 0.18f), content.RectTransform), 0.0f, GUIStyle.Green, style: "GUIAfflictionBar")
|
||||||
{
|
{
|
||||||
UserData = "afflictionstrengthprediction",
|
UserData = "afflictionstrengthprediction",
|
||||||
CanBeFocused = false
|
CanBeFocused = false
|
||||||
@@ -1242,7 +1264,7 @@ namespace Barotrauma
|
|||||||
afflictionIcon.SelectedColor = Color.Lerp(afflictionIcon.Color, Color.White, 0.5f);
|
afflictionIcon.SelectedColor = Color.Lerp(afflictionIcon.Color, Color.White, 0.5f);
|
||||||
|
|
||||||
var nameText = new GUITextBlock(new RectTransform(new Vector2(1.1f, 0.0f), content.RectTransform),
|
var nameText = new GUITextBlock(new RectTransform(new Vector2(1.1f, 0.0f), content.RectTransform),
|
||||||
affliction.Prefab.Name, font: GUI.SmallFont, textAlignment: Alignment.BottomCenter)
|
affliction.Prefab.Name, font: GUIStyle.SmallFont, textAlignment: Alignment.BottomCenter)
|
||||||
{
|
{
|
||||||
CanBeFocused = false
|
CanBeFocused = false
|
||||||
};
|
};
|
||||||
@@ -1274,13 +1296,13 @@ namespace Barotrauma
|
|||||||
|
|
||||||
//key = item identifier
|
//key = item identifier
|
||||||
//float = suitability
|
//float = suitability
|
||||||
Dictionary<string, float> treatmentSuitability = new Dictionary<string, float>();
|
Dictionary<Identifier, float> treatmentSuitability = new Dictionary<Identifier, float>();
|
||||||
GetSuitableTreatments(treatmentSuitability,
|
GetSuitableTreatments(treatmentSuitability,
|
||||||
normalize: true,
|
normalize: true,
|
||||||
ignoreHiddenAfflictions: true,
|
ignoreHiddenAfflictions: true,
|
||||||
limb: selectedLimbIndex == -1 ? null : Character.AnimController.Limbs.Find(l => l.HealthIndex == selectedLimbIndex));
|
limb: selectedLimbIndex == -1 ? null : Character.AnimController.Limbs.Find(l => l.HealthIndex == selectedLimbIndex));
|
||||||
|
|
||||||
foreach (string treatment in treatmentSuitability.Keys.ToList())
|
foreach (Identifier treatment in treatmentSuitability.Keys.ToList())
|
||||||
{
|
{
|
||||||
//prefer suggestions for items the player has
|
//prefer suggestions for items the player has
|
||||||
if (Character.Controlled.Inventory.FindItemByIdentifier(treatment, recursive: true) != null)
|
if (Character.Controlled.Inventory.FindItemByIdentifier(treatment, recursive: true) != null)
|
||||||
@@ -1304,10 +1326,10 @@ namespace Barotrauma
|
|||||||
recommendedTreatmentContainer.AutoHideScrollBar = true;
|
recommendedTreatmentContainer.AutoHideScrollBar = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<KeyValuePair<string, float>> treatmentSuitabilities = treatmentSuitability.OrderByDescending(t => t.Value).ToList();
|
List<KeyValuePair<Identifier, float>> treatmentSuitabilities = treatmentSuitability.OrderByDescending(t => t.Value).ToList();
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
foreach (KeyValuePair<string, float> treatment in treatmentSuitabilities)
|
foreach (KeyValuePair<Identifier, float> treatment in treatmentSuitabilities)
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
if (count > 5) { break; }
|
if (count > 5) { break; }
|
||||||
@@ -1326,7 +1348,7 @@ namespace Barotrauma
|
|||||||
OnClicked = (btn, userdata) =>
|
OnClicked = (btn, userdata) =>
|
||||||
{
|
{
|
||||||
if (!(userdata is ItemPrefab itemPrefab)) { return false; }
|
if (!(userdata is ItemPrefab itemPrefab)) { return false; }
|
||||||
var item = Character.Controlled.Inventory.FindItem(it => it.prefab == itemPrefab, recursive: true);
|
var item = Character.Controlled.Inventory.FindItem(it => it.Prefab == itemPrefab, recursive: true);
|
||||||
if (item == null) { return false; }
|
if (item == null) { return false; }
|
||||||
Limb targetLimb = Character.AnimController.Limbs.FirstOrDefault(l => l.HealthIndex == selectedLimbIndex);
|
Limb targetLimb = Character.AnimController.Limbs.FirstOrDefault(l => l.HealthIndex == selectedLimbIndex);
|
||||||
item.ApplyTreatment(Character.Controlled, Character, targetLimb);
|
item.ApplyTreatment(Character.Controlled, Character, targetLimb);
|
||||||
@@ -1337,15 +1359,15 @@ namespace Barotrauma
|
|||||||
new GUIImage(new RectTransform(Vector2.One, innerFrame.RectTransform, Anchor.Center), style: "TalentBackgroundGlow")
|
new GUIImage(new RectTransform(Vector2.One, innerFrame.RectTransform, Anchor.Center), style: "TalentBackgroundGlow")
|
||||||
{
|
{
|
||||||
CanBeFocused = false,
|
CanBeFocused = false,
|
||||||
Color = GUI.Style.Green,
|
Color = GUIStyle.Green,
|
||||||
HoverColor = Color.White,
|
HoverColor = Color.White,
|
||||||
PressedColor = Color.DarkGray,
|
PressedColor = Color.DarkGray,
|
||||||
SelectedColor = Color.Transparent,
|
SelectedColor = Color.Transparent,
|
||||||
DisabledColor = Color.Transparent
|
DisabledColor = Color.Transparent
|
||||||
};
|
};
|
||||||
|
|
||||||
Sprite itemSprite = item.InventoryIcon ?? item.sprite;
|
Sprite itemSprite = item.InventoryIcon ?? item.Sprite;
|
||||||
Color itemColor = itemSprite == item.sprite ? item.SpriteColor : item.InventoryIconColor;
|
Color itemColor = itemSprite == item.Sprite ? item.SpriteColor : item.InventoryIconColor;
|
||||||
var itemIcon = new GUIImage(new RectTransform(new Vector2(0.8f, 0.8f), innerFrame.RectTransform, Anchor.Center),
|
var itemIcon = new GUIImage(new RectTransform(new Vector2(0.8f, 0.8f), innerFrame.RectTransform, Anchor.Center),
|
||||||
itemSprite, scaleToFit: true)
|
itemSprite, scaleToFit: true)
|
||||||
{
|
{
|
||||||
@@ -1397,12 +1419,12 @@ namespace Barotrauma
|
|||||||
CanBeFocused = false
|
CanBeFocused = false
|
||||||
};
|
};
|
||||||
|
|
||||||
var afflictionName = new GUITextBlock(new RectTransform(new Vector2(0.65f, 1.0f), labelContainer.RectTransform), affliction.Prefab.Name, textAlignment: Alignment.CenterLeft, font: GUI.LargeFont)
|
var afflictionName = new GUITextBlock(new RectTransform(new Vector2(0.65f, 1.0f), labelContainer.RectTransform), affliction.Prefab.Name, textAlignment: Alignment.CenterLeft, font: GUIStyle.LargeFont)
|
||||||
{
|
{
|
||||||
CanBeFocused = false,
|
CanBeFocused = false,
|
||||||
AutoScaleHorizontal = true
|
AutoScaleHorizontal = true
|
||||||
};
|
};
|
||||||
var afflictionStrength = new GUITextBlock(new RectTransform(new Vector2(0.35f, 0.6f), labelContainer.RectTransform), "", textAlignment: Alignment.TopRight, font: GUI.SubHeadingFont)
|
var afflictionStrength = new GUITextBlock(new RectTransform(new Vector2(0.35f, 0.6f), labelContainer.RectTransform), "", textAlignment: Alignment.TopRight, font: GUIStyle.SubHeadingFont)
|
||||||
{
|
{
|
||||||
UserData = "strength",
|
UserData = "strength",
|
||||||
CanBeFocused = false
|
CanBeFocused = false
|
||||||
@@ -1423,21 +1445,21 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (description.Font.MeasureString(description.WrappedText).Y > description.Rect.Height)
|
if (description.Font.MeasureString(description.WrappedText).Y > description.Rect.Height)
|
||||||
{
|
{
|
||||||
description.Font = GUI.SmallFont;
|
description.Font = GUIStyle.SmallFont;
|
||||||
}
|
}
|
||||||
|
|
||||||
Point nameDims = new Point(afflictionName.Rect.Width, (int)(GUI.LargeFont.Size * 1.5f));
|
Point nameDims = new Point(afflictionName.Rect.Width, (int)(GUIStyle.LargeFont.Size * 1.5f));
|
||||||
|
|
||||||
afflictionStrength.Text = strengthTexts[
|
afflictionStrength.Text = strengthTexts[
|
||||||
MathHelper.Clamp((int)Math.Floor((affliction.Strength / affliction.Prefab.MaxStrength) * strengthTexts.Length), 0, strengthTexts.Length - 1)];
|
MathHelper.Clamp((int)Math.Floor((affliction.Strength / affliction.Prefab.MaxStrength) * strengthTexts.Length), 0, strengthTexts.Length - 1)];
|
||||||
|
|
||||||
Vector2 strengthDims = GUI.SubHeadingFont.MeasureString(afflictionStrength.Text);
|
Vector2 strengthDims = GUIStyle.SubHeadingFont.MeasureString(afflictionStrength.Text);
|
||||||
|
|
||||||
labelContainer.RectTransform.Resize(new Point(labelContainer.Rect.Width, nameDims.Y));
|
labelContainer.RectTransform.Resize(new Point(labelContainer.Rect.Width, nameDims.Y));
|
||||||
afflictionName.RectTransform.Resize(new Point((int)(labelContainer.Rect.Width - strengthDims.X * 0.99f), nameDims.Y));
|
afflictionName.RectTransform.Resize(new Point((int)(labelContainer.Rect.Width - strengthDims.X * 0.99f), nameDims.Y));
|
||||||
afflictionStrength.RectTransform.Resize(new Point(labelContainer.Rect.Width - afflictionName.Rect.Width, nameDims.Y));
|
afflictionStrength.RectTransform.Resize(new Point(labelContainer.Rect.Width - afflictionName.Rect.Width, nameDims.Y));
|
||||||
|
|
||||||
afflictionStrength.TextColor = Color.Lerp(GUI.Style.Orange, GUI.Style.Red,
|
afflictionStrength.TextColor = Color.Lerp(GUIStyle.Orange, GUIStyle.Red,
|
||||||
affliction.Strength / affliction.Prefab.MaxStrength);
|
affliction.Strength / affliction.Prefab.MaxStrength);
|
||||||
|
|
||||||
description.RectTransform.Resize(new Point(description.Rect.Width, (int)(description.TextSize.Y + 10)));
|
description.RectTransform.Resize(new Point(description.Rect.Width, (int)(description.TextSize.Y + 10)));
|
||||||
@@ -1451,8 +1473,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
vitality.Visible = true;
|
vitality.Visible = true;
|
||||||
vitality.Text = TextManager.Get("Vitality") + " -" + vitalityDecrease;
|
vitality.Text = TextManager.Get("Vitality") + " -" + vitalityDecrease;
|
||||||
vitality.TextColor = vitalityDecrease <= 0 ? GUI.Style.Green :
|
vitality.TextColor = vitalityDecrease <= 0 ? GUIStyle.Green :
|
||||||
Color.Lerp(GUI.Style.Orange, GUI.Style.Red, affliction.Strength / affliction.Prefab.MaxStrength);
|
Color.Lerp(GUIStyle.Orange, GUIStyle.Red, affliction.Strength / affliction.Prefab.MaxStrength);
|
||||||
}
|
}
|
||||||
|
|
||||||
vitality.AutoDraw = true;
|
vitality.AutoDraw = true;
|
||||||
@@ -1478,7 +1500,7 @@ namespace Barotrauma
|
|||||||
var potentialTreatment = Inventory.DraggingItems.FirstOrDefault();
|
var potentialTreatment = Inventory.DraggingItems.FirstOrDefault();
|
||||||
if (potentialTreatment == null && GUI.MouseOn?.UserData is ItemPrefab itemPrefab)
|
if (potentialTreatment == null && GUI.MouseOn?.UserData is ItemPrefab itemPrefab)
|
||||||
{
|
{
|
||||||
potentialTreatment = Character.Controlled.Inventory.FindItem(it => it.prefab == itemPrefab, recursive: true);
|
potentialTreatment = Character.Controlled.Inventory.FindItem(it => it.Prefab == itemPrefab, recursive: true);
|
||||||
}
|
}
|
||||||
potentialTreatment ??= Inventory.SelectedSlot?.Item;
|
potentialTreatment ??= Inventory.SelectedSlot?.Item;
|
||||||
|
|
||||||
@@ -1488,11 +1510,11 @@ namespace Barotrauma
|
|||||||
Color afflictionEffectColor = Color.White;
|
Color afflictionEffectColor = Color.White;
|
||||||
if (afflictionVitalityDecrease > 0.0f)
|
if (afflictionVitalityDecrease > 0.0f)
|
||||||
{
|
{
|
||||||
afflictionEffectColor = GUI.Style.Red;
|
afflictionEffectColor = GUIStyle.Red;
|
||||||
}
|
}
|
||||||
else if (afflictionVitalityDecrease < 0.0f)
|
else if (afflictionVitalityDecrease < 0.0f)
|
||||||
{
|
{
|
||||||
afflictionEffectColor = GUI.Style.Green;
|
afflictionEffectColor = GUIStyle.Green;
|
||||||
}
|
}
|
||||||
|
|
||||||
var child = afflictionIconContainer.Content.FindChild(affliction);
|
var child = afflictionIconContainer.Content.FindChild(affliction);
|
||||||
@@ -1510,7 +1532,7 @@ namespace Barotrauma
|
|||||||
if (afflictionStrengthPrediction < affliction.Strength)
|
if (afflictionStrengthPrediction < affliction.Strength)
|
||||||
{
|
{
|
||||||
afflictionStrengthBar.Color = afflictionEffectColor;
|
afflictionStrengthBar.Color = afflictionEffectColor;
|
||||||
afflictionStrengthPredictionBar.Color = GUI.Style.Blue * t;
|
afflictionStrengthPredictionBar.Color = GUIStyle.Blue * t;
|
||||||
afflictionStrengthPredictionBar.BarSize = afflictionStrengthBar.BarSize;
|
afflictionStrengthPredictionBar.BarSize = afflictionStrengthBar.BarSize;
|
||||||
afflictionStrengthBar.BarSize = afflictionStrengthPrediction / affliction.Prefab.MaxStrength;
|
afflictionStrengthBar.BarSize = afflictionStrengthPrediction / affliction.Prefab.MaxStrength;
|
||||||
}
|
}
|
||||||
@@ -1541,8 +1563,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
foreach (var reduceAffliction in effect.ReduceAffliction)
|
foreach (var reduceAffliction in effect.ReduceAffliction)
|
||||||
{
|
{
|
||||||
if (reduceAffliction.affliction != affliction.Identifier && reduceAffliction.affliction != affliction.Prefab.AfflictionType) { continue; }
|
if (reduceAffliction.AfflictionIdentifier != affliction.Identifier && reduceAffliction.AfflictionIdentifier != affliction.Prefab.AfflictionType) { continue; }
|
||||||
strength -= reduceAffliction.amount * (effect.Duration > 0 ? effect.Duration : 1.0f);
|
strength -= reduceAffliction.ReduceAmount * (effect.Duration > 0 ? effect.Duration : 1.0f);
|
||||||
}
|
}
|
||||||
foreach (var addAffliction in effect.Afflictions)
|
foreach (var addAffliction in effect.Afflictions)
|
||||||
{
|
{
|
||||||
@@ -1563,7 +1585,7 @@ namespace Barotrauma
|
|||||||
strengthText.Text = strengthTexts[
|
strengthText.Text = strengthTexts[
|
||||||
MathHelper.Clamp((int)Math.Floor((affliction.Strength / affliction.Prefab.MaxStrength) * strengthTexts.Length), 0, strengthTexts.Length - 1)];
|
MathHelper.Clamp((int)Math.Floor((affliction.Strength / affliction.Prefab.MaxStrength) * strengthTexts.Length), 0, strengthTexts.Length - 1)];
|
||||||
|
|
||||||
strengthText.TextColor = Color.Lerp(GUI.Style.Orange, GUI.Style.Red,
|
strengthText.TextColor = Color.Lerp(GUIStyle.Orange, GUIStyle.Red,
|
||||||
affliction.Strength / affliction.Prefab.MaxStrength);
|
affliction.Strength / affliction.Prefab.MaxStrength);
|
||||||
|
|
||||||
var vitalityText = labelContainer.GetChildByUserData("vitality") as GUITextBlock;
|
var vitalityText = labelContainer.GetChildByUserData("vitality") as GUITextBlock;
|
||||||
@@ -1576,8 +1598,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
vitalityText.Visible = true;
|
vitalityText.Visible = true;
|
||||||
vitalityText.Text = TextManager.Get("Vitality") + " -" + vitalityDecrease;
|
vitalityText.Text = TextManager.Get("Vitality") + " -" + vitalityDecrease;
|
||||||
vitalityText.TextColor = vitalityDecrease <= 0 ? GUI.Style.Green :
|
vitalityText.TextColor = vitalityDecrease <= 0 ? GUIStyle.Green :
|
||||||
Color.Lerp(GUI.Style.Orange, GUI.Style.Red, affliction.Strength / affliction.Prefab.MaxStrength);
|
Color.Lerp(GUIStyle.Orange, GUIStyle.Red, affliction.Strength / affliction.Prefab.MaxStrength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1807,9 +1829,9 @@ namespace Barotrauma
|
|||||||
if (afflictionsDisplayedOnLimb.Count() > 1)
|
if (afflictionsDisplayedOnLimb.Count() > 1)
|
||||||
{
|
{
|
||||||
string additionalAfflictionCount = $"+{afflictionsDisplayedOnLimb.Count() - 1}";
|
string additionalAfflictionCount = $"+{afflictionsDisplayedOnLimb.Count() - 1}";
|
||||||
Vector2 displace = GUI.SubHeadingFont.MeasureString(additionalAfflictionCount);
|
Vector2 displace = GUIStyle.SubHeadingFont.MeasureString(additionalAfflictionCount);
|
||||||
GUI.SubHeadingFont.DrawString(spriteBatch, additionalAfflictionCount, iconPos + new Vector2(displace.X * 1.1f, -displace.Y * 0.45f), Color.Black * 0.75f);
|
GUIStyle.SubHeadingFont.DrawString(spriteBatch, additionalAfflictionCount, iconPos + new Vector2(displace.X * 1.1f, -displace.Y * 0.45f), Color.Black * 0.75f);
|
||||||
GUI.SubHeadingFont.DrawString(spriteBatch, additionalAfflictionCount, iconPos + new Vector2(displace.X, -displace.Y * 0.5f), Color.White);
|
GUIStyle.SubHeadingFont.DrawString(spriteBatch, additionalAfflictionCount, iconPos + new Vector2(displace.X, -displace.Y * 0.5f), Color.White);
|
||||||
}
|
}
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
@@ -1885,7 +1907,7 @@ namespace Barotrauma
|
|||||||
for (int i = 0; i < afflictionCount; i++)
|
for (int i = 0; i < afflictionCount; i++)
|
||||||
{
|
{
|
||||||
uint afflictionID = inc.ReadUInt32();
|
uint afflictionID = inc.ReadUInt32();
|
||||||
AfflictionPrefab afflictionPrefab = AfflictionPrefab.Prefabs.Find(p => p.UIntIdentifier == afflictionID);
|
AfflictionPrefab afflictionPrefab = AfflictionPrefab.Prefabs.Find(p => p.UintIdentifier == afflictionID);
|
||||||
if (afflictionPrefab == null)
|
if (afflictionPrefab == null)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Error while reading character health data: affliction with the uint ID " + afflictionID + " not found.");
|
DebugConsole.ThrowError("Error while reading character health data: affliction with the uint ID " + afflictionID + " not found.");
|
||||||
@@ -1913,7 +1935,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
int limbIndex = inc.ReadRangedInteger(0, limbHealths.Count - 1);
|
int limbIndex = inc.ReadRangedInteger(0, limbHealths.Count - 1);
|
||||||
uint afflictionID = inc.ReadUInt32();
|
uint afflictionID = inc.ReadUInt32();
|
||||||
AfflictionPrefab afflictionPrefab = AfflictionPrefab.Prefabs.Find(p => p.UIntIdentifier == afflictionID);
|
AfflictionPrefab afflictionPrefab = AfflictionPrefab.Prefabs.Find(p => p.UintIdentifier == afflictionID);
|
||||||
if (afflictionPrefab == null)
|
if (afflictionPrefab == null)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Error while reading character health data: affliction with the uint ID " + afflictionID + " not found.");
|
DebugConsole.ThrowError("Error while reading character health data: affliction with the uint ID " + afflictionID + " not found.");
|
||||||
|
|||||||
@@ -2,14 +2,14 @@
|
|||||||
{
|
{
|
||||||
partial class DamageModifier
|
partial class DamageModifier
|
||||||
{
|
{
|
||||||
[Serialize("", false), Editable]
|
[Serialize("", IsPropertySaveable.No), Editable]
|
||||||
public string DamageSound
|
public string DamageSound
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
private set;
|
private set;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serialize("", false), Editable]
|
[Serialize("", IsPropertySaveable.No), Editable]
|
||||||
public string DamageParticle
|
public string DamageParticle
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
partial class JobPrefab : IPrefab, IDisposable
|
partial class JobPrefab : PrefabWithUintIdentifier
|
||||||
{
|
{
|
||||||
public GUIButton CreateInfoFrame(out GUIComponent buttonContainer)
|
public GUIButton CreateInfoFrame(out GUIComponent buttonContainer)
|
||||||
{
|
{
|
||||||
@@ -18,20 +18,20 @@ namespace Barotrauma
|
|||||||
GUIFrame frame = new GUIFrame(new RectTransform(new Point(width, height), frameHolder.RectTransform, Anchor.Center));
|
GUIFrame frame = new GUIFrame(new RectTransform(new Point(width, height), frameHolder.RectTransform, Anchor.Center));
|
||||||
GUIFrame paddedFrame = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.9f), frame.RectTransform, Anchor.Center), style: null);
|
GUIFrame paddedFrame = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.9f), frame.RectTransform, Anchor.Center), style: null);
|
||||||
|
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.1f), paddedFrame.RectTransform), Name, font: GUI.LargeFont);
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.1f), paddedFrame.RectTransform), Name, font: GUIStyle.LargeFont);
|
||||||
|
|
||||||
var descriptionBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedFrame.RectTransform) { RelativeOffset = new Vector2(0.0f, 0.15f) },
|
var descriptionBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedFrame.RectTransform) { RelativeOffset = new Vector2(0.0f, 0.15f) },
|
||||||
Description, font: GUI.SmallFont, wrap: true);
|
Description, font: GUIStyle.SmallFont, wrap: true);
|
||||||
|
|
||||||
var skillContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.45f, 0.5f), paddedFrame.RectTransform)
|
var skillContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.45f, 0.5f), paddedFrame.RectTransform)
|
||||||
{ RelativeOffset = new Vector2(0.0f, 0.2f + descriptionBlock.RectTransform.RelativeSize.Y) });
|
{ RelativeOffset = new Vector2(0.0f, 0.2f + descriptionBlock.RectTransform.RelativeSize.Y) });
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), skillContainer.RectTransform),
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), skillContainer.RectTransform),
|
||||||
TextManager.Get("Skills"), font: GUI.LargeFont);
|
TextManager.Get("Skills"), font: GUIStyle.LargeFont);
|
||||||
foreach (SkillPrefab skill in Skills)
|
foreach (SkillPrefab skill in Skills)
|
||||||
{
|
{
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), skillContainer.RectTransform),
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), skillContainer.RectTransform),
|
||||||
" - " + TextManager.AddPunctuation(':', TextManager.Get("SkillName." + skill.Identifier), (int)skill.LevelRange.Start + " - " + (int)skill.LevelRange.End),
|
" - " + TextManager.AddPunctuation(':', TextManager.Get("SkillName." + skill.Identifier), (int)skill.LevelRange.Start + " - " + (int)skill.LevelRange.End),
|
||||||
font: GUI.SmallFont);
|
font: GUIStyle.SmallFont);
|
||||||
}
|
}
|
||||||
|
|
||||||
buttonContainer = paddedFrame;
|
buttonContainer = paddedFrame;
|
||||||
@@ -43,14 +43,14 @@ namespace Barotrauma
|
|||||||
Stretch = true
|
Stretch = true
|
||||||
};
|
};
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), itemContainer.RectTransform),
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), itemContainer.RectTransform),
|
||||||
TextManager.Get("Items", fallBackTag: "mapentitycategory.equipment"), font: GUI.LargeFont);
|
TextManager.Get("Items", "mapentitycategory.equipment"), font: GUIStyle.LargeFont);
|
||||||
foreach (string identifier in itemIdentifiers.Distinct())
|
foreach (string identifier in itemIdentifiers.Distinct())
|
||||||
{
|
{
|
||||||
if (!(MapEntityPrefab.Find(name: null, identifier: identifier) is ItemPrefab itemPrefab)) { continue; }
|
if (!(MapEntityPrefab.Find(name: null, identifier: identifier) is ItemPrefab itemPrefab)) { continue; }
|
||||||
int count = itemIdentifiers.Count(i => i == identifier);
|
int count = itemIdentifiers.Count(i => i == identifier);
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), itemContainer.RectTransform),
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), itemContainer.RectTransform),
|
||||||
" - " + (count == 1 ? itemPrefab.Name : itemPrefab.Name + " x" + count),
|
" - " + (count == 1 ? itemPrefab.Name : itemPrefab.Name + " x" + count),
|
||||||
font: GUI.SmallFont);
|
font: GUIStyle.SmallFont);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
return frameHolder;
|
return frameHolder;
|
||||||
@@ -76,12 +76,12 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<OutfitPreview> GetJobOutfitSprites(Gender gender, bool useInventoryIcon, out Vector2 maxDimensions)
|
public List<OutfitPreview> GetJobOutfitSprites(CharacterInfoPrefab charInfoPrefab, bool useInventoryIcon, out Vector2 maxDimensions)
|
||||||
{
|
{
|
||||||
List<OutfitPreview> outfitPreviews = new List<OutfitPreview>();
|
List<OutfitPreview> outfitPreviews = new List<OutfitPreview>();
|
||||||
maxDimensions = Vector2.One;
|
maxDimensions = Vector2.One;
|
||||||
|
|
||||||
var equipIdentifiers = Element.GetChildElements("ItemSet").Elements().Where(e => e.GetAttributeBool("outfit", false)).Select(e => e.GetAttributeString("identifier", ""));
|
var equipIdentifiers = Element.GetChildElements("ItemSet").Elements().Where(e => e.GetAttributeBool("outfit", false)).Select(e => e.GetAttributeIdentifier("identifier", ""));
|
||||||
|
|
||||||
List<ItemPrefab> outfitPrefabs = new List<ItemPrefab>();
|
List<ItemPrefab> outfitPrefabs = new List<ItemPrefab>();
|
||||||
foreach (var equipIdentifier in equipIdentifiers)
|
foreach (var equipIdentifier in equipIdentifiers)
|
||||||
@@ -114,8 +114,8 @@ namespace Barotrauma
|
|||||||
var children = previewElement.Elements().ToList();
|
var children = previewElement.Elements().ToList();
|
||||||
for (int n = 0; n < children.Count; n++)
|
for (int n = 0; n < children.Count; n++)
|
||||||
{
|
{
|
||||||
XElement spriteElement = children[n];
|
var spriteElement = children[n];
|
||||||
string spriteTexture = spriteElement.GetAttributeString("texture", "").Replace("[GENDER]", (gender == Gender.Female) ? "female" : "male");
|
string spriteTexture = charInfoPrefab.ReplaceVars(spriteElement.GetAttributeString("texture", ""), charInfoPrefab.Heads.First());
|
||||||
var sprite = new Sprite(spriteElement, file: spriteTexture);
|
var sprite = new Sprite(spriteElement, file: spriteTexture);
|
||||||
sprite.size = new Vector2(sprite.SourceRect.Width, sprite.SourceRect.Height);
|
sprite.size = new Vector2(sprite.SourceRect.Width, sprite.SourceRect.Height);
|
||||||
outfitPreview.AddSprite(sprite, children[n].GetAttributeVector2("offset", Vector2.Zero));
|
outfitPreview.AddSprite(sprite, children[n].GetAttributeVector2("offset", Vector2.Zero));
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ namespace Barotrauma
|
|||||||
//{
|
//{
|
||||||
// var pos = ConvertUnits.ToDisplayUnits(mouthPos.Value);
|
// var pos = ConvertUnits.ToDisplayUnits(mouthPos.Value);
|
||||||
// pos.Y = -pos.Y;
|
// pos.Y = -pos.Y;
|
||||||
// ShapeExtensions.DrawPoint(spriteBatch, pos, GUI.Style.Red, size: 5);
|
// ShapeExtensions.DrawPoint(spriteBatch, pos, GUIStyle.Red, size: 5);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
// A debug visualisation on the bezier curve between limbs.
|
// A debug visualisation on the bezier curve between limbs.
|
||||||
@@ -95,7 +95,7 @@ namespace Barotrauma
|
|||||||
GUI.DrawLine(spriteBatch, start, end, Color.White);
|
GUI.DrawLine(spriteBatch, start, end, Color.White);
|
||||||
GUI.DrawLine(spriteBatch, start, control, Color.Black);
|
GUI.DrawLine(spriteBatch, start, control, Color.Black);
|
||||||
GUI.DrawLine(spriteBatch, control, end, Color.Black);
|
GUI.DrawLine(spriteBatch, control, end, Color.Black);
|
||||||
GUI.DrawBezierWithDots(spriteBatch, start, end, control, 1000, GUI.Style.Red);*/
|
GUI.DrawBezierWithDots(spriteBatch, start, end, control, 1000, GUIStyle.Red);*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,7 +274,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void InitProjSpecific(XElement element)
|
partial void InitProjSpecific(ContentXElement element)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < Params.decorativeSpriteParams.Count; i++)
|
for (int i = 0; i < Params.decorativeSpriteParams.Count; i++)
|
||||||
{
|
{
|
||||||
@@ -290,7 +290,7 @@ namespace Barotrauma
|
|||||||
spriteAnimState.Add(decorativeSprite, new SpriteState());
|
spriteAnimState.Add(decorativeSprite, new SpriteState());
|
||||||
}
|
}
|
||||||
TintMask = null;
|
TintMask = null;
|
||||||
foreach (XElement subElement in element.Elements())
|
foreach (var subElement in element.Elements())
|
||||||
{
|
{
|
||||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||||
{
|
{
|
||||||
@@ -317,7 +317,7 @@ namespace Barotrauma
|
|||||||
NonConditionalDeformations.AddRange(deformations);
|
NonConditionalDeformations.AddRange(deformations);
|
||||||
break;
|
break;
|
||||||
case "randomcolor":
|
case "randomcolor":
|
||||||
randomColor = subElement.GetAttributeColorArray("colors", null)?.GetRandom();
|
randomColor = subElement.GetAttributeColorArray("colors", null)?.GetRandomUnsynced();
|
||||||
if (randomColor.HasValue)
|
if (randomColor.HasValue)
|
||||||
{
|
{
|
||||||
Params.GetSprite().Color = randomColor.Value;
|
Params.GetSprite().Color = randomColor.Value;
|
||||||
@@ -337,8 +337,8 @@ namespace Barotrauma
|
|||||||
InitialLightSpriteAlpha = LightSource.OverrideLightSpriteAlpha;
|
InitialLightSpriteAlpha = LightSource.OverrideLightSpriteAlpha;
|
||||||
break;
|
break;
|
||||||
case "tintmask":
|
case "tintmask":
|
||||||
string tintMaskPath = subElement.GetAttributeString("texture", "");
|
ContentPath tintMaskPath = subElement.GetAttributeContentPath("texture");
|
||||||
if (!string.IsNullOrWhiteSpace(tintMaskPath))
|
if (!tintMaskPath.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
TintMask = new Sprite(subElement, file: GetSpritePath(tintMaskPath));
|
TintMask = new Sprite(subElement, file: GetSpritePath(tintMaskPath));
|
||||||
TintHighlightThreshold = subElement.GetAttributeFloat("highlightthreshold", 0.6f);
|
TintHighlightThreshold = subElement.GetAttributeFloat("highlightthreshold", 0.6f);
|
||||||
@@ -346,8 +346,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "huskmask":
|
case "huskmask":
|
||||||
string huskMaskPath = subElement.GetAttributeString("texture", "");
|
ContentPath huskMaskPath = subElement.GetAttributeContentPath("texture");
|
||||||
if (!string.IsNullOrWhiteSpace(huskMaskPath))
|
if (!huskMaskPath.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
HuskMask = new Sprite(subElement, file: GetSpritePath(huskMaskPath));
|
HuskMask = new Sprite(subElement, file: GetSpritePath(huskMaskPath));
|
||||||
}
|
}
|
||||||
@@ -387,7 +387,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
if (deformation == null)
|
if (deformation == null)
|
||||||
{
|
{
|
||||||
deformation = SpriteDeformation.Load(animationElement, character.SpeciesName);
|
deformation = SpriteDeformation.Load(animationElement, character.SpeciesName.Value);
|
||||||
if (deformation != null)
|
if (deformation != null)
|
||||||
{
|
{
|
||||||
ragdoll.SpriteDeformations.Add(deformation);
|
ragdoll.SpriteDeformations.Add(deformation);
|
||||||
@@ -472,19 +472,23 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
private string _texturePath;
|
private string _texturePath;
|
||||||
private string GetSpritePath(XElement element, SpriteParams spriteParams)
|
private string GetSpritePath(ContentXElement element, SpriteParams spriteParams)
|
||||||
{
|
{
|
||||||
if (_texturePath == null)
|
if (_texturePath == null)
|
||||||
{
|
{
|
||||||
if (spriteParams != null)
|
if (spriteParams != null)
|
||||||
{
|
{
|
||||||
string texturePath = character.Params.VariantFile?.Root?.GetAttributeString("texture", null) ?? spriteParams.GetTexturePath();
|
ContentPath texturePath =
|
||||||
|
character.Params.VariantFile?.Root?.GetAttributeContentPath("texture", character.Prefab.ContentPackage)
|
||||||
|
?? ContentPath.FromRaw(character.Prefab.ContentPackage, spriteParams.GetTexturePath());
|
||||||
_texturePath = GetSpritePath(texturePath);
|
_texturePath = GetSpritePath(texturePath);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string texturePath = element.GetAttributeString("texture", null);
|
ContentPath texturePath = element.GetAttributeContentPath("texture");
|
||||||
texturePath = string.IsNullOrWhiteSpace(texturePath) ? ragdoll.RagdollParams.Texture : texturePath;
|
texturePath = texturePath.IsNullOrWhiteSpace()
|
||||||
|
? ContentPath.FromRaw(character.Prefab.ContentPackage, ragdoll.RagdollParams.Texture)
|
||||||
|
: texturePath;
|
||||||
_texturePath = GetSpritePath(texturePath);
|
_texturePath = GetSpritePath(texturePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -494,20 +498,18 @@ namespace Barotrauma
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the full path of a limb sprite, taking into account tags, gender and head id
|
/// Get the full path of a limb sprite, taking into account tags, gender and head id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string GetSpritePath(string texturePath, CharacterInfo characterInfo)
|
public static string GetSpritePath(ContentPath texturePath, CharacterInfo characterInfo)
|
||||||
{
|
{
|
||||||
string spritePath = texturePath;
|
string spritePath = texturePath.Value;
|
||||||
string spritePathWithTags = spritePath;
|
string spritePathWithTags = spritePath;
|
||||||
if (characterInfo != null)
|
if (characterInfo != null)
|
||||||
{
|
{
|
||||||
spritePath = spritePath.Replace("[GENDER]", (characterInfo.Gender == Gender.Female) ? "female" : "male");
|
spritePath = characterInfo.ReplaceVars(spritePath);
|
||||||
spritePath = spritePath.Replace("[RACE]", characterInfo.Race.ToString().ToLowerInvariant());
|
|
||||||
spritePath = spritePath.Replace("[HEADID]", characterInfo.HeadSpriteId.ToString());
|
|
||||||
|
|
||||||
if (characterInfo.HeadSprite != null && characterInfo.SpriteTags.Any())
|
if (characterInfo.HeadSprite != null && characterInfo.SpriteTags.Any())
|
||||||
{
|
{
|
||||||
string tags = "";
|
string tags = "";
|
||||||
characterInfo.SpriteTags.ForEach(tag => tags += "[" + tag + "]");
|
characterInfo.SpriteTags.ForEach(tag => tags += $"[{tag}]");
|
||||||
|
|
||||||
spritePathWithTags = Path.Combine(
|
spritePathWithTags = Path.Combine(
|
||||||
Path.GetDirectoryName(spritePath),
|
Path.GetDirectoryName(spritePath),
|
||||||
@@ -518,10 +520,10 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private string GetSpritePath(string texturePath)
|
private string GetSpritePath(ContentPath texturePath)
|
||||||
{
|
{
|
||||||
if (!character.IsHumanoid) { return texturePath; }
|
if (!character.IsHumanoid) { return texturePath.Value; }
|
||||||
return GetSpritePath(texturePath, character?.Info);
|
return GetSpritePath(texturePath, character.Info);
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void LoadParamsProjSpecific()
|
partial void LoadParamsProjSpecific()
|
||||||
@@ -696,7 +698,7 @@ namespace Barotrauma
|
|||||||
clr = clr.Multiply(ragdoll.RagdollParams.Color);
|
clr = clr.Multiply(ragdoll.RagdollParams.Color);
|
||||||
if (character.Info != null)
|
if (character.Info != null)
|
||||||
{
|
{
|
||||||
clr = clr.Multiply(character.Info.SkinColor);
|
clr = clr.Multiply(character.Info.Head.SkinColor);
|
||||||
}
|
}
|
||||||
if (character.CharacterHealth.FaceTint.A > 0 && type == LimbType.Head)
|
if (character.CharacterHealth.FaceTint.A > 0 && type == LimbType.Head)
|
||||||
{
|
{
|
||||||
@@ -929,7 +931,7 @@ namespace Barotrauma
|
|||||||
if (pullJoint != null)
|
if (pullJoint != null)
|
||||||
{
|
{
|
||||||
Vector2 pos = ConvertUnits.ToDisplayUnits(pullJoint.WorldAnchorB);
|
Vector2 pos = ConvertUnits.ToDisplayUnits(pullJoint.WorldAnchorB);
|
||||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X, (int)-pos.Y, 5, 5), GUI.Style.Red, true);
|
GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X, (int)-pos.Y, 5, 5), GUIStyle.Red, true);
|
||||||
}
|
}
|
||||||
var bodyDrawPos = body.DrawPosition;
|
var bodyDrawPos = body.DrawPosition;
|
||||||
bodyDrawPos.Y = -bodyDrawPos.Y;
|
bodyDrawPos.Y = -bodyDrawPos.Y;
|
||||||
@@ -943,11 +945,11 @@ namespace Barotrauma
|
|||||||
var front = ConvertUnits.ToDisplayUnits(body.FarseerBody.GetWorldPoint(localFront));
|
var front = ConvertUnits.ToDisplayUnits(body.FarseerBody.GetWorldPoint(localFront));
|
||||||
front.Y = -front.Y;
|
front.Y = -front.Y;
|
||||||
GUI.DrawLine(spriteBatch, bodyDrawPos, front, Color.Yellow, width: 2);
|
GUI.DrawLine(spriteBatch, bodyDrawPos, front, Color.Yellow, width: 2);
|
||||||
GUI.DrawLine(spriteBatch, from, to, GUI.Style.Red, width: 1);
|
GUI.DrawLine(spriteBatch, from, to, GUIStyle.Red, width: 1);
|
||||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)from.X, (int)from.Y, 12, 12), Color.White, true);
|
GUI.DrawRectangle(spriteBatch, new Rectangle((int)from.X, (int)from.Y, 12, 12), Color.White, true);
|
||||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)to.X, (int)to.Y, 12, 12), Color.White, true);
|
GUI.DrawRectangle(spriteBatch, new Rectangle((int)to.X, (int)to.Y, 12, 12), Color.White, true);
|
||||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)from.X, (int)from.Y, 10, 10), Color.Blue, true);
|
GUI.DrawRectangle(spriteBatch, new Rectangle((int)from.X, (int)from.Y, 10, 10), Color.Blue, true);
|
||||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)to.X, (int)to.Y, 10, 10), GUI.Style.Red, true);
|
GUI.DrawRectangle(spriteBatch, new Rectangle((int)to.X, (int)to.Y, 10, 10), GUIStyle.Red, true);
|
||||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)front.X, (int)front.Y, 10, 10), Color.Yellow, true);
|
GUI.DrawRectangle(spriteBatch, new Rectangle((int)front.X, (int)front.Y, 10, 10), Color.Yellow, true);
|
||||||
|
|
||||||
//Vector2 mainLimbFront = ConvertUnits.ToDisplayUnits(ragdoll.MainLimb.body.FarseerBody.GetWorldPoint(ragdoll.MainLimb.body.GetFrontLocal(MathHelper.ToRadians(limbParams.Orientation))));
|
//Vector2 mainLimbFront = ConvertUnits.ToDisplayUnits(ragdoll.MainLimb.body.FarseerBody.GetWorldPoint(ragdoll.MainLimb.body.GetFrontLocal(MathHelper.ToRadians(limbParams.Orientation))));
|
||||||
@@ -1046,8 +1048,8 @@ namespace Barotrauma
|
|||||||
//{
|
//{
|
||||||
// width = (int)Math.Round(width / cam.Zoom);
|
// width = (int)Math.Round(width / cam.Zoom);
|
||||||
//}
|
//}
|
||||||
//GUI.DrawLine(spriteBatch, startPos, startPos + Vector2.Normalize(up) * size, GUI.Style.Red, width: width);
|
//GUI.DrawLine(spriteBatch, startPos, startPos + Vector2.Normalize(up) * size, GUIStyle.Red, width: width);
|
||||||
Color color = modifier.DamageMultiplier > 1 ? GUI.Style.Red : GUI.Style.Green;
|
Color color = modifier.DamageMultiplier > 1 ? GUIStyle.Red : GUIStyle.Green;
|
||||||
float size = ConvertUnits.ToDisplayUnits(body.GetSize().Length() / 2);
|
float size = ConvertUnits.ToDisplayUnits(body.GetSize().Length() / 2);
|
||||||
if (isScreenSpace)
|
if (isScreenSpace)
|
||||||
{
|
{
|
||||||
@@ -1078,9 +1080,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
wearable.Sprite.SourceRect = new Rectangle(CharacterInfo.CalculateOffset(sprite, wearable.SheetIndex.Value), sprite.SourceRect.Size);
|
wearable.Sprite.SourceRect = new Rectangle(CharacterInfo.CalculateOffset(sprite, wearable.SheetIndex.Value), sprite.SourceRect.Size);
|
||||||
}
|
}
|
||||||
else if (type == LimbType.Head && character.Info != null && character.Info.Head.SheetIndex.HasValue)
|
else if (type == LimbType.Head && character.Info != null)
|
||||||
{
|
{
|
||||||
wearable.Sprite.SourceRect = new Rectangle(CharacterInfo.CalculateOffset(sprite, character.Info.Head.SheetIndex.Value.ToPoint()), sprite.SourceRect.Size);
|
wearable.Sprite.SourceRect = new Rectangle(CharacterInfo.CalculateOffset(sprite, character.Info.Head.SheetIndex.ToPoint()), sprite.SourceRect.Size);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1134,11 +1136,11 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (wearable.Type == WearableType.Hair)
|
if (wearable.Type == WearableType.Hair)
|
||||||
{
|
{
|
||||||
wearableColor = character.Info.HairColor;
|
wearableColor = character.Info.Head.HairColor;
|
||||||
}
|
}
|
||||||
else if (wearable.Type == WearableType.Beard || wearable.Type == WearableType.Moustache)
|
else if (wearable.Type == WearableType.Beard || wearable.Type == WearableType.Moustache)
|
||||||
{
|
{
|
||||||
wearableColor = character.Info.FacialHairColor;
|
wearableColor = character.Info.Head.FacialHairColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
float scale = wearable.Scale;
|
float scale = wearable.Scale;
|
||||||
@@ -1164,22 +1166,22 @@ namespace Barotrauma
|
|||||||
wearable.Sprite.Draw(spriteBatch, new Vector2(body.DrawPosition.X, -body.DrawPosition.Y), finalColor, origin, rotation, scale, spriteEffect, depth);
|
wearable.Sprite.Draw(spriteBatch, new Vector2(body.DrawPosition.X, -body.DrawPosition.Y), finalColor, origin, rotation, scale, spriteEffect, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
private WearableSprite GetWearableSprite(WearableType type, bool random = false)
|
private WearableSprite GetWearableSprite(WearableType type)//, bool random = false)
|
||||||
{
|
{
|
||||||
var info = character.Info;
|
var info = character.Info;
|
||||||
if (info == null) { return null; }
|
if (info == null) { return null; }
|
||||||
XElement element;
|
ContentXElement element;
|
||||||
if (random)
|
/*if (random)
|
||||||
{
|
{
|
||||||
element = info.FilterByTypeAndHeadID(info.FilterElementsByGenderAndRace(info.Wearables, info.Gender, info.Race), type, info.Head.HeadSpriteId)?.GetRandom(Rand.RandSync.ClientOnly);
|
element = info.FilterElements(info.Wearables, info.Head.Preset.TagSet)?.GetRandom(Rand.RandSync.ClientOnly);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{*/
|
||||||
element = info.FilterByTypeAndHeadID(info.FilterElementsByGenderAndRace(info.Wearables, info.Gender, info.Race), type, info.Head.HeadSpriteId)?.FirstOrDefault();
|
element = info.FilterElements(info.Wearables, info.Head.Preset.TagSet, type)?.FirstOrDefault();
|
||||||
}
|
//}
|
||||||
if (element != null)
|
if (element != null)
|
||||||
{
|
{
|
||||||
return new WearableSprite(element.Element("sprite"), type);
|
return new WearableSprite(element.GetChildElement("sprite"), type);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
+167
@@ -0,0 +1,167 @@
|
|||||||
|
#nullable enable
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using Barotrauma.IO;
|
||||||
|
|
||||||
|
namespace Barotrauma
|
||||||
|
{
|
||||||
|
public class ModProject
|
||||||
|
{
|
||||||
|
public class File
|
||||||
|
{
|
||||||
|
private File(string path, Type type)
|
||||||
|
{
|
||||||
|
Path = path.CleanUpPathCrossPlatform(correctFilenameCase: false);
|
||||||
|
Type = type switch
|
||||||
|
{
|
||||||
|
_ when !type.IsSubclassOf(typeof(ContentFile)) => throw new ArgumentException($"{type.Name} does not derive from {nameof(ContentFile)}"),
|
||||||
|
{ IsAbstract: true } => throw new ArgumentException($"{type.Name} is abstract"),
|
||||||
|
_ => type
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private File(ContentFile f)
|
||||||
|
{
|
||||||
|
Path = f.Path.RawValue ?? "";
|
||||||
|
Type = f.GetType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static File FromContentFile(ContentFile file)
|
||||||
|
=> new File(file);
|
||||||
|
|
||||||
|
public static File FromPath<T>(string path) where T : ContentFile
|
||||||
|
=> new File(path, typeof(T));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Prefer FromPath<T> when possible, this just exists
|
||||||
|
/// for cases where the type can only be decided at runtime
|
||||||
|
/// </summary>
|
||||||
|
public static File FromPath(string path, Type type)
|
||||||
|
=> new File(path, type);
|
||||||
|
|
||||||
|
public readonly string Path;
|
||||||
|
public readonly Type Type;
|
||||||
|
|
||||||
|
public XElement ToXElement()
|
||||||
|
{
|
||||||
|
if (Type is null) { throw new InvalidOperationException("Type must be set before calling ToXElement"); }
|
||||||
|
if (Path.IsNullOrEmpty()) { throw new InvalidOperationException("Path must be set before calling ToXElement"); }
|
||||||
|
return new XElement(Type.Name.RemoveFromEnd("File"), new XAttribute("file", Path));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModProject() { }
|
||||||
|
|
||||||
|
public ModProject(ContentPackage? contentPackage)
|
||||||
|
{
|
||||||
|
if (contentPackage is null) { return; }
|
||||||
|
Name = contentPackage.Name;
|
||||||
|
AltNames = contentPackage.AltNames.ToList();
|
||||||
|
files = contentPackage.Files.Select(File.FromContentFile).ToList();
|
||||||
|
ModVersion = IncrementModVersion(contentPackage.ModVersion);
|
||||||
|
IsCore = contentPackage is CorePackage;
|
||||||
|
SteamWorkshopId = contentPackage.SteamWorkshopId;
|
||||||
|
ExpectedHash = contentPackage.Hash;
|
||||||
|
InstallTime = contentPackage.InstallTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string name = "";
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get => name;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
var charsToRemove = Path.GetInvalidFileNameChars();
|
||||||
|
name = string.Concat(value.Where(c => !charsToRemove.Contains(c)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly List<string> AltNames = new List<string>();
|
||||||
|
|
||||||
|
private readonly List<File> files = new List<File>();
|
||||||
|
public IReadOnlyList<File> Files => files;
|
||||||
|
|
||||||
|
public string ModVersion = ContentPackage.DefaultModVersion;
|
||||||
|
|
||||||
|
public Md5Hash? ExpectedHash { get; private set; }
|
||||||
|
|
||||||
|
public bool IsCore = false;
|
||||||
|
|
||||||
|
public UInt64 SteamWorkshopId = 0;
|
||||||
|
|
||||||
|
public DateTime? InstallTime = null;
|
||||||
|
|
||||||
|
public bool HasFile(File file)
|
||||||
|
=> Files.Any(f =>
|
||||||
|
string.Equals(f.Path, file.Path, StringComparison.OrdinalIgnoreCase)
|
||||||
|
&& f.Type == file.Type);
|
||||||
|
|
||||||
|
public void AddFile(File file)
|
||||||
|
{
|
||||||
|
if (!HasFile(file))
|
||||||
|
{
|
||||||
|
files.Add(file);
|
||||||
|
DiscardHashAndInstallTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DiscardHashAndInstallTime()
|
||||||
|
{
|
||||||
|
ExpectedHash = null;
|
||||||
|
InstallTime = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string IncrementModVersion(string modVersion)
|
||||||
|
{
|
||||||
|
//look for an integer at the end of the string and increment it
|
||||||
|
int startIndex = modVersion.Length - 1;
|
||||||
|
while (char.IsDigit(modVersion[startIndex])) { startIndex--; }
|
||||||
|
startIndex++;
|
||||||
|
|
||||||
|
if (startIndex >= modVersion.Length
|
||||||
|
|| !char.IsDigit(modVersion[startIndex])
|
||||||
|
|| !int.TryParse(
|
||||||
|
modVersion[startIndex..],
|
||||||
|
NumberStyles.Any,
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
out int theFinalInteger))
|
||||||
|
{
|
||||||
|
return modVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $"{modVersion[..startIndex]}{(theFinalInteger + 1).ToString(CultureInfo.InvariantCulture)}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public XDocument ToXDocument()
|
||||||
|
{
|
||||||
|
XDocument doc = new XDocument();
|
||||||
|
XElement rootElement = new XElement("contentpackage");
|
||||||
|
|
||||||
|
void addRootAttribute<T>(string name, T value) where T : notnull
|
||||||
|
=> rootElement.Add(new XAttribute(name, value.ToString() ?? ""));
|
||||||
|
|
||||||
|
addRootAttribute("name", Name);
|
||||||
|
addRootAttribute("modversion", ModVersion);
|
||||||
|
addRootAttribute("corepackage", IsCore);
|
||||||
|
if (SteamWorkshopId != 0) { addRootAttribute("steamworkshopid", SteamWorkshopId); }
|
||||||
|
addRootAttribute("gameversion", GameMain.Version);
|
||||||
|
if (AltNames.Any()) { addRootAttribute("altnames", string.Join(",", AltNames)); }
|
||||||
|
if (ExpectedHash != null) { addRootAttribute("expectedhash", ExpectedHash.StringRepresentation); }
|
||||||
|
if (InstallTime != null) { addRootAttribute("installtime", ToolBox.Epoch.FromDateTime(InstallTime.Value)); }
|
||||||
|
|
||||||
|
files.ForEach(f => rootElement.Add(f.ToXElement()));
|
||||||
|
|
||||||
|
doc.Add(rootElement);
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Save(string path)
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(Path.GetDirectoryName(path)!);
|
||||||
|
ToXDocument().SaveSafe(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
#nullable enable
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Barotrauma.IO;
|
||||||
|
using Barotrauma.Steam;
|
||||||
|
|
||||||
|
namespace Barotrauma
|
||||||
|
{
|
||||||
|
public static partial class ContentPackageManager
|
||||||
|
{
|
||||||
|
public sealed partial class PackageSource : ICollection<ContentPackage>
|
||||||
|
{
|
||||||
|
public string SaveRegularMod(ModProject modProject)
|
||||||
|
{
|
||||||
|
if (modProject.IsCore) { throw new ArgumentException("ModProject must not be a core package"); }
|
||||||
|
|
||||||
|
string fileListPath = Path.Combine(directory, ToolBox.RemoveInvalidFileNameChars(modProject.Name), ContentPackage.FileListFileName)
|
||||||
|
.CleanUpPathCrossPlatform(correctFilenameCase: false);
|
||||||
|
modProject.Save(fileListPath);
|
||||||
|
Refresh(); EnabledPackages.DisableRemovedMods();
|
||||||
|
|
||||||
|
return fileListPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RegularPackage GetRegularModByPath(string fileListPath)
|
||||||
|
{
|
||||||
|
return Regular.First(p => p.Path == fileListPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RegularPackage SaveAndEnableRegularMod(ModProject modProject)
|
||||||
|
{
|
||||||
|
string fileListPath = SaveRegularMod(modProject);
|
||||||
|
var package = GetRegularModByPath(fileListPath);
|
||||||
|
EnabledPackages.EnableRegular(package);
|
||||||
|
|
||||||
|
return package;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<IEnumerable<Steamworks.Ugc.Item>> EnqueueWorkshopUpdates()
|
||||||
|
{
|
||||||
|
ISet<Steamworks.Ugc.Item> subscribedItems = await SteamManager.Workshop.GetAllSubscribedItems();
|
||||||
|
|
||||||
|
var needInstalling = subscribedItems.Where(item
|
||||||
|
=> !WorkshopPackages.Any(p
|
||||||
|
=> item.Id == p.SteamWorkshopId
|
||||||
|
&& p.InstallTime.HasValue
|
||||||
|
&& item.LatestUpdateTime <= p.InstallTime))
|
||||||
|
.ToArray();
|
||||||
|
if (needInstalling.Any())
|
||||||
|
{
|
||||||
|
await Task.WhenAll(
|
||||||
|
needInstalling.Select(SteamManager.Workshop.DownloadModThenEnqueueInstall));
|
||||||
|
}
|
||||||
|
|
||||||
|
return needInstalling;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+297
@@ -0,0 +1,297 @@
|
|||||||
|
#nullable enable
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using Barotrauma.Extensions;
|
||||||
|
using Barotrauma.Steam;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Directory = Barotrauma.IO.Directory;
|
||||||
|
using File = Barotrauma.IO.File;
|
||||||
|
using Path = Barotrauma.IO.Path;
|
||||||
|
|
||||||
|
namespace Barotrauma.Transition
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Class dedicated to transitioning away from the old, shitty
|
||||||
|
/// Mods + Submarines folders to the new LocalMods folder
|
||||||
|
/// </summary>
|
||||||
|
public static class UgcTransition
|
||||||
|
{
|
||||||
|
private const string readmeName = "LOCALMODS_README.txt";
|
||||||
|
|
||||||
|
public static void Prepare()
|
||||||
|
{
|
||||||
|
TaskPool.Add("UgcTransition.Prepare", DetermineItemsToTransition(), t =>
|
||||||
|
{
|
||||||
|
if (!t.TryGetResult(out (OldSubs, OldItemAssemblies, OldMods) result)) { return; }
|
||||||
|
var (subs, itemAssemblies, mods) = result;
|
||||||
|
if (!subs.FilePaths.Any() && !itemAssemblies.FilePaths.Any() && !mods.Mods.Any()) { return; }
|
||||||
|
|
||||||
|
var msgBox = new GUIMessageBox(TextManager.Get("Ugc.TransferTitle"), "", relativeSize: (0.5f, 0.8f),
|
||||||
|
buttons: new LocalizedString[] { TextManager.Get("Ugc.TransferButton") });
|
||||||
|
|
||||||
|
var desc = new GUITextBlock(new RectTransform((1.0f, 0.24f), msgBox.Content.RectTransform),
|
||||||
|
text: TextManager.Get("Ugc.TransferDesc"), wrap: true, textAlignment: Alignment.CenterLeft);
|
||||||
|
|
||||||
|
var modsList = new GUIListBox(new RectTransform((1.0f, 0.6f), msgBox.Content.RectTransform))
|
||||||
|
{
|
||||||
|
HoverCursor = CursorState.Default
|
||||||
|
};
|
||||||
|
Dictionary<string, GUITickBox> pathTickboxMap = new Dictionary<string, GUITickBox>();
|
||||||
|
|
||||||
|
void addHeader(LocalizedString str)
|
||||||
|
{
|
||||||
|
var itemFrame = new GUITextBlock(new RectTransform((1.0f, 0.08f), modsList.Content.RectTransform),
|
||||||
|
text: str, font: GUIStyle.SubHeadingFont)
|
||||||
|
{
|
||||||
|
CanBeFocused = false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
void addTickbox(string dir, string name, bool ticked)
|
||||||
|
{
|
||||||
|
var itemFrame = new GUIFrame(new RectTransform((1.0f, 0.07f), modsList.Content.RectTransform),
|
||||||
|
style: null)
|
||||||
|
{
|
||||||
|
CanBeFocused = false
|
||||||
|
};
|
||||||
|
var tickbox = new GUITickBox(new RectTransform(Vector2.One, itemFrame.RectTransform), name)
|
||||||
|
{
|
||||||
|
Selected = ticked
|
||||||
|
};
|
||||||
|
pathTickboxMap.Add(dir, tickbox);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool firstHeader = true;
|
||||||
|
|
||||||
|
void addSpacer()
|
||||||
|
{
|
||||||
|
if (firstHeader) { firstHeader = false; return; }
|
||||||
|
addHeader("");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (subs.FilePaths.Any())
|
||||||
|
{
|
||||||
|
addSpacer();
|
||||||
|
addHeader(TextManager.Get("WorkshopLabelSubmarines"));
|
||||||
|
foreach (var sub in subs.FilePaths)
|
||||||
|
{
|
||||||
|
var subName = Path.GetFileNameWithoutExtension(sub);
|
||||||
|
addTickbox(sub, subName, ticked: !ContentPackageManager.LocalPackages.Any(p => p.NameMatches(subName)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemAssemblies.FilePaths.Any())
|
||||||
|
{
|
||||||
|
addSpacer();
|
||||||
|
addHeader(TextManager.Get("ItemAssemblies"));
|
||||||
|
foreach (var itemAssembly in itemAssemblies.FilePaths)
|
||||||
|
{
|
||||||
|
var assemblyName = Path.GetFileNameWithoutExtension(itemAssembly);
|
||||||
|
addTickbox(itemAssembly, assemblyName, ticked: !ContentPackageManager.LocalPackages.Any(p => p.NameMatches(assemblyName)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mods.Mods.Any())
|
||||||
|
{
|
||||||
|
addSpacer();
|
||||||
|
addHeader(TextManager.Get("SubscribedMods"));
|
||||||
|
foreach (var mod in mods.Mods)
|
||||||
|
{
|
||||||
|
addTickbox(mod.Dir, mod.Name, ticked: !ContentPackageManager.LocalPackages.Any(p => p.SteamWorkshopId != 0 && p.SteamWorkshopId == mod.Item?.Id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GUIMessageBox? subMsgBox = null;
|
||||||
|
|
||||||
|
void createSubMsgBox(LocalizedString str, bool closable)
|
||||||
|
{
|
||||||
|
subMsgBox?.Close();
|
||||||
|
subMsgBox = new GUIMessageBox(headerText: "", text: str,
|
||||||
|
buttons: closable ? new[] { TextManager.Get("Close") } : Array.Empty<LocalizedString>());
|
||||||
|
if (closable)
|
||||||
|
{
|
||||||
|
subMsgBox.Buttons[0].OnClicked = subMsgBox.Close;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
msgBox.Buttons[0].OnClicked = (b, o) =>
|
||||||
|
{
|
||||||
|
TaskPool.Add("TransferMods", TransferMods(pathTickboxMap), t2 =>
|
||||||
|
{
|
||||||
|
if (t2.Exception != null)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("There was an error transferring mods", t2.Exception.GetInnermost());
|
||||||
|
}
|
||||||
|
ContentPackageManager.LocalPackages.Refresh();
|
||||||
|
createSubMsgBox(TextManager.Get("Ugc.TransferComplete"), closable: true);
|
||||||
|
});
|
||||||
|
msgBox.Close();
|
||||||
|
createSubMsgBox(TextManager.Get("Ugc.Transferring"), closable: false);
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct OldSubs
|
||||||
|
{
|
||||||
|
public readonly IReadOnlyList<string> FilePaths;
|
||||||
|
|
||||||
|
public OldSubs(IReadOnlyList<string> filePaths)
|
||||||
|
{
|
||||||
|
FilePaths = filePaths;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct OldItemAssemblies
|
||||||
|
{
|
||||||
|
public readonly IReadOnlyList<string> FilePaths;
|
||||||
|
|
||||||
|
public OldItemAssemblies(IReadOnlyList<string> filePaths)
|
||||||
|
{
|
||||||
|
FilePaths = filePaths;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct OldMods
|
||||||
|
{
|
||||||
|
public readonly IReadOnlyList<(string Dir, string Name, Steamworks.Ugc.Item? Item, DateTime InstallTime)> Mods;
|
||||||
|
|
||||||
|
public OldMods(IReadOnlyList<(string Dir, string Name, Steamworks.Ugc.Item? Item, DateTime InstallTime)> mods)
|
||||||
|
{
|
||||||
|
Mods = mods;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private const string oldSubsPath = "Submarines";
|
||||||
|
private const string oldModsPath = "Mods";
|
||||||
|
private const string oldItemAssembliesPath = "ItemAssemblies";
|
||||||
|
|
||||||
|
private static async Task<(OldSubs Subs, OldItemAssemblies ItemAssemblies, OldMods Mods)> DetermineItemsToTransition()
|
||||||
|
{
|
||||||
|
string[] subs = Array.Empty<string>();
|
||||||
|
string[] itemAssemblies = Array.Empty<string>();
|
||||||
|
List<(string Dir, string Name, Steamworks.Ugc.Item? Item, DateTime InstallTime)> mods
|
||||||
|
= new List<(string Dir, string Name, Steamworks.Ugc.Item? Item, DateTime InstallTime)>();
|
||||||
|
if (FolderShouldBeTransitioned(oldModsPath))
|
||||||
|
{
|
||||||
|
string[] getFiles(string path, string pattern)
|
||||||
|
=> Directory.Exists(path)
|
||||||
|
? Directory.GetFiles(path, pattern, SearchOption.TopDirectoryOnly)
|
||||||
|
: Array.Empty<string>();
|
||||||
|
|
||||||
|
subs = getFiles(oldSubsPath, "*.sub");
|
||||||
|
itemAssemblies = getFiles(oldItemAssembliesPath, "*.xml");
|
||||||
|
|
||||||
|
string[] allOldMods = Directory.GetDirectories(oldModsPath, "*", SearchOption.TopDirectoryOnly);
|
||||||
|
|
||||||
|
var publishedItems = await SteamManager.Workshop.GetPublishedItems();
|
||||||
|
foreach (var modDir in allOldMods)
|
||||||
|
{
|
||||||
|
var fileList = XMLExtensions.TryLoadXml(Path.Combine(modDir, ContentPackage.FileListFileName), out _);
|
||||||
|
if (fileList?.Root is null) { continue; }
|
||||||
|
|
||||||
|
var oldId = fileList.Root.GetAttributeUInt64("steamworkshopid", 0);
|
||||||
|
var updateTime = File.GetLastWriteTime(modDir).ToUniversalTime();
|
||||||
|
var oldName = fileList.Root.GetAttributeString("name", "");
|
||||||
|
|
||||||
|
var item = oldId != 0 ? publishedItems.FirstOrNull(it => it.Id == oldId) : null;
|
||||||
|
if (oldId == 0 || item.HasValue)
|
||||||
|
{
|
||||||
|
mods.Add((modDir, oldName, item, updateTime));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!(Screen.Selected is MainMenuScreen)) { await Task.Delay(50); }
|
||||||
|
|
||||||
|
return (new OldSubs(subs), new OldItemAssemblies(itemAssemblies), new OldMods(mods));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool FolderShouldBeTransitioned(string folderName)
|
||||||
|
{
|
||||||
|
return Directory.Exists(folderName)
|
||||||
|
&& !File.Exists(Path.Combine(folderName, readmeName));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task TransferMods(Dictionary<string, GUITickBox> pathTickboxMap)
|
||||||
|
{
|
||||||
|
//WriteReadme(oldSubsPath); //can't do this because the old submarine discovery code is borked
|
||||||
|
WriteReadme(oldModsPath);
|
||||||
|
await Task.WhenAll(pathTickboxMap.Select(TransferMod));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Task TransferMod(KeyValuePair<string, GUITickBox> kvp)
|
||||||
|
=> TransferMod(kvp.Key, kvp.Value);
|
||||||
|
|
||||||
|
private static async Task TransferMod(string path, GUITickBox tickbox)
|
||||||
|
{
|
||||||
|
if (!tickbox.Selected) { return; }
|
||||||
|
string dirName = Path.GetFileNameWithoutExtension(path);
|
||||||
|
string destPath = Path.Combine(ContentPackage.LocalModsDir, dirName);
|
||||||
|
|
||||||
|
//find unique path to save in
|
||||||
|
for (int i = 0;;i++)
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(destPath)) { break; }
|
||||||
|
destPath = Path.Combine(ContentPackage.LocalModsDir, $"{dirName}.{i}");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isSub = path.StartsWith(oldSubsPath, StringComparison.OrdinalIgnoreCase);
|
||||||
|
bool isItemAssembly = path.StartsWith(oldItemAssembliesPath, StringComparison.OrdinalIgnoreCase);
|
||||||
|
if (isSub || isItemAssembly)
|
||||||
|
{
|
||||||
|
//copying a sub or item assembly: manually create filelist.xml
|
||||||
|
ModProject modProject = new ModProject
|
||||||
|
{
|
||||||
|
Name = dirName,
|
||||||
|
ModVersion = ContentPackage.DefaultModVersion
|
||||||
|
};
|
||||||
|
|
||||||
|
Type fileType;
|
||||||
|
if (isSub)
|
||||||
|
{
|
||||||
|
fileType = typeof(SubmarineFile);
|
||||||
|
XDocument? doc = SubmarineInfo.OpenFile(path, out _);
|
||||||
|
if (doc?.Root != null)
|
||||||
|
{
|
||||||
|
SubmarineType subType = doc.Root.GetAttributeEnum("type", SubmarineType.Player);
|
||||||
|
fileType = SubEditorScreen.DetermineSubFileType(subType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fileType = typeof(ItemAssemblyFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
modProject.AddFile(ModProject.File.FromPath(
|
||||||
|
Path.Combine(ContentPath.ModDirStr, $"{dirName}.{(isSub ? "sub" : "xml")}"),
|
||||||
|
fileType));
|
||||||
|
|
||||||
|
Directory.CreateDirectory(destPath);
|
||||||
|
File.Copy(path, Path.Combine(destPath, $"{dirName}.{(isSub ? "sub" : "xml")}"));
|
||||||
|
modProject.Save(Path.Combine(destPath, ContentPackage.FileListFileName));
|
||||||
|
|
||||||
|
await Task.Yield();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//copying a mod: we have a neat method for that!
|
||||||
|
await SteamManager.Workshop.CopyDirectory(path, Path.GetFileName(path), path, destPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WriteReadme(string folderName)
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(folderName)) { return; }
|
||||||
|
File.WriteAllText(path: Path.Combine(folderName, readmeName),
|
||||||
|
contents: "This folder is no longer used by Barotrauma;\n" +
|
||||||
|
"your mods and submarines should have been transferred\n" +
|
||||||
|
"to LocalMods. If they are not being found, delete this\n" +
|
||||||
|
"readme and relaunch the game.", encoding: Encoding.UTF8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
+10
-10
@@ -94,7 +94,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
var (relative, min) = GetSizes(dialogType);
|
var (relative, min) = GetSizes(dialogType);
|
||||||
|
|
||||||
GUIMessageBox messageBox = new GUIMessageBox(string.Empty, string.Empty, new string[0],
|
GUIMessageBox messageBox = new GUIMessageBox(string.Empty, string.Empty, Array.Empty<LocalizedString>(),
|
||||||
relativeSize: relative, minSize: min,
|
relativeSize: relative, minSize: min,
|
||||||
type: GUIMessageBox.Type.InGame, backgroundIcon: EventSet.GetEventSprite(spriteIdentifier))
|
type: GUIMessageBox.Type.InGame, backgroundIcon: EventSet.GetEventSprite(spriteIdentifier))
|
||||||
{
|
{
|
||||||
@@ -105,7 +105,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
messageBox.InnerFrame.ClearChildren();
|
messageBox.InnerFrame.ClearChildren();
|
||||||
messageBox.AutoClose = false;
|
messageBox.AutoClose = false;
|
||||||
GUI.Style.Apply(messageBox.InnerFrame, "DialogBox");
|
GUIStyle.Apply(messageBox.InnerFrame, "DialogBox");
|
||||||
|
|
||||||
if (actionInstance != null)
|
if (actionInstance != null)
|
||||||
{
|
{
|
||||||
@@ -222,11 +222,11 @@ namespace Barotrauma
|
|||||||
closeButton.SlideIn(0.5f, 0.33f, 16, SlideDirection.Down);
|
closeButton.SlideIn(0.5f, 0.33f, 16, SlideDirection.Down);
|
||||||
|
|
||||||
InputType? closeInput = null;
|
InputType? closeInput = null;
|
||||||
if (GameMain.Config.KeyBind(InputType.Use).MouseButton == MouseButton.None)
|
if (GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Use].MouseButton == MouseButton.None)
|
||||||
{
|
{
|
||||||
closeInput = InputType.Use;
|
closeInput = InputType.Use;
|
||||||
}
|
}
|
||||||
else if (GameMain.Config.KeyBind(InputType.Select).MouseButton == MouseButton.None)
|
else if (GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Select].MouseButton == MouseButton.None)
|
||||||
{
|
{
|
||||||
closeInput = InputType.Select;
|
closeInput = InputType.Select;
|
||||||
}
|
}
|
||||||
@@ -239,7 +239,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
GUIButton btn = component as GUIButton;
|
GUIButton btn = component as GUIButton;
|
||||||
btn?.OnClicked(btn, btn.UserData);
|
btn?.OnClicked(btn, btn.UserData);
|
||||||
btn?.Flash(GUI.Style.Green);
|
btn?.Flash(GUIStyle.Green);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -308,7 +308,7 @@ namespace Barotrauma
|
|||||||
AlwaysOverrideCursor = true
|
AlwaysOverrideCursor = true
|
||||||
};
|
};
|
||||||
|
|
||||||
string translatedText = TextManager.Get(text, returnNull: true) ?? text;
|
LocalizedString translatedText = TextManager.Get(text);
|
||||||
|
|
||||||
if (speaker?.Info != null && drawChathead)
|
if (speaker?.Info != null && drawChathead)
|
||||||
{
|
{
|
||||||
@@ -335,9 +335,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
foreach (string option in options)
|
foreach (string option in options)
|
||||||
{
|
{
|
||||||
var btn = new GUIButton(new RectTransform(new Vector2(0.9f, 0.01f), textContent.RectTransform), TextManager.Get(option, returnNull: true) ?? option, style: "ListBoxElement");
|
var btn = new GUIButton(new RectTransform(new Vector2(0.9f, 0.01f), textContent.RectTransform), TextManager.Get(option), style: "ListBoxElement");
|
||||||
btn.TextBlock.TextAlignment = Alignment.CenterLeft;
|
btn.TextBlock.TextAlignment = Alignment.CenterLeft;
|
||||||
btn.TextColor = btn.HoverTextColor = GUI.Style.Green;
|
btn.TextColor = btn.HoverTextColor = GUIStyle.Green;
|
||||||
btn.TextBlock.Wrap = true;
|
btn.TextBlock.Wrap = true;
|
||||||
buttons.Add(btn);
|
buttons.Add(btn);
|
||||||
}
|
}
|
||||||
@@ -384,7 +384,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Too broken, left it here if I ever want to come back to it
|
// Too broken, left it here if I ever want to come back to it
|
||||||
private static List<RichTextData> GetQuoteHighlights(string text, Color color)
|
/*private static List<RichTextData> GetQuoteHighlights(string text, Color color)
|
||||||
{
|
{
|
||||||
char[] quotes = { '“', '”', '\"', '\'', '「', '」'};
|
char[] quotes = { '“', '”', '\"', '\'', '「', '」'};
|
||||||
|
|
||||||
@@ -406,6 +406,6 @@ namespace Barotrauma
|
|||||||
last.EndIndex = text.Length;
|
last.EndIndex = text.Length;
|
||||||
}
|
}
|
||||||
return textColors;
|
return textColors;
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ 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;
|
||||||
|
using System.Collections.Immutable;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
|
||||||
@@ -34,7 +35,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
var textOffset = new Vector2(-150, 0);
|
var textOffset = new Vector2(-150, 0);
|
||||||
spriteBatch.DrawCircle(drawPos, 600, 6, Color.White, thickness: 20);
|
spriteBatch.DrawCircle(drawPos, 600, 6, Color.White, thickness: 20);
|
||||||
GUI.DrawString(spriteBatch, drawPos + textOffset, ev.ToString(), Color.White, Color.Black, 0, GUI.LargeFont);
|
GUI.DrawString(spriteBatch, drawPos + textOffset, ev.ToString(), Color.White, Color.Black, 0, GUIStyle.LargeFont);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,24 +47,23 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
float theoreticalMaxMonsterStrength = 10000;
|
float theoreticalMaxMonsterStrength = 10000;
|
||||||
float relativeMaxMonsterStrength = theoreticalMaxMonsterStrength * GameMain.GameSession.LevelData.Difficulty / 100;
|
float relativeMaxMonsterStrength = theoreticalMaxMonsterStrength * (GameMain.GameSession?.LevelData?.Difficulty ?? 0f) / 100;
|
||||||
float absoluteMonsterStrength = monsterStrength / theoreticalMaxMonsterStrength;
|
float absoluteMonsterStrength = monsterStrength / theoreticalMaxMonsterStrength;
|
||||||
float relativeMonsterStrength = monsterStrength / relativeMaxMonsterStrength;
|
float relativeMonsterStrength = monsterStrength / relativeMaxMonsterStrength;
|
||||||
GUI.DrawString(spriteBatch, new Vector2(10, y), "EventManager", Color.White, Color.Black * 0.6f, 0, GUI.SmallFont);
|
GUI.DrawString(spriteBatch, new Vector2(10, y), "EventManager", Color.White, Color.Black * 0.6f, 0, GUIStyle.SmallFont);
|
||||||
GUI.DrawString(spriteBatch, new Vector2(15, y + 20), "Event cooldown: " + (int)Math.Max(eventCoolDown, 0), Color.White, Color.Black * 0.6f, 0, GUI.SmallFont);
|
GUI.DrawString(spriteBatch, new Vector2(15, y + 20), "Event cooldown: " + (int)Math.Max(eventCoolDown, 0), Color.White, Color.Black * 0.6f, 0, GUIStyle.SmallFont);
|
||||||
GUI.DrawString(spriteBatch, new Vector2(15, y + 35), "Current intensity: " + (int)Math.Round(currentIntensity * 100), Color.Lerp(Color.White, GUI.Style.Red, currentIntensity), Color.Black * 0.6f, 0, GUI.SmallFont);
|
GUI.DrawString(spriteBatch, new Vector2(15, y + 35), "Current intensity: " + (int)Math.Round(currentIntensity * 100), Color.Lerp(Color.White, GUIStyle.Red, currentIntensity), Color.Black * 0.6f, 0, GUIStyle.SmallFont);
|
||||||
GUI.DrawString(spriteBatch, new Vector2(15, y + 50), "Target intensity: " + (int)Math.Round(targetIntensity * 100), Color.Lerp(Color.White, GUI.Style.Red, targetIntensity), Color.Black * 0.6f, 0, GUI.SmallFont);
|
GUI.DrawString(spriteBatch, new Vector2(15, y + 50), "Target intensity: " + (int)Math.Round(targetIntensity * 100), Color.Lerp(Color.White, GUIStyle.Red, targetIntensity), Color.Black * 0.6f, 0, GUIStyle.SmallFont);
|
||||||
|
|
||||||
GUI.DrawString(spriteBatch, new Vector2(15, y + 65), "Crew health: " + (int)Math.Round(avgCrewHealth * 100), Color.Lerp(GUI.Style.Red, GUI.Style.Green, avgCrewHealth), Color.Black * 0.6f, 0, GUI.SmallFont);
|
GUI.DrawString(spriteBatch, new Vector2(15, y + 65), "Crew health: " + (int)Math.Round(avgCrewHealth * 100), Color.Lerp(GUIStyle.Red, GUIStyle.Green, avgCrewHealth), Color.Black * 0.6f, 0, GUIStyle.SmallFont);
|
||||||
GUI.DrawString(spriteBatch, new Vector2(15, y + 80), "Hull integrity: " + (int)Math.Round(avgHullIntegrity * 100), Color.Lerp(GUI.Style.Red, GUI.Style.Green, avgHullIntegrity), Color.Black * 0.6f, 0, GUI.SmallFont);
|
GUI.DrawString(spriteBatch, new Vector2(15, y + 80), "Hull integrity: " + (int)Math.Round(avgHullIntegrity * 100), Color.Lerp(GUIStyle.Red, GUIStyle.Green, avgHullIntegrity), Color.Black * 0.6f, 0, GUIStyle.SmallFont);
|
||||||
GUI.DrawString(spriteBatch, new Vector2(15, y + 95), "Flooding amount: " + (int)Math.Round(floodingAmount * 100), Color.Lerp(GUI.Style.Green, GUI.Style.Red, floodingAmount), Color.Black * 0.6f, 0, GUI.SmallFont);
|
GUI.DrawString(spriteBatch, new Vector2(15, y + 95), "Flooding amount: " + (int)Math.Round(floodingAmount * 100), Color.Lerp(GUIStyle.Green, GUIStyle.Red, floodingAmount), Color.Black * 0.6f, 0, GUIStyle.SmallFont);
|
||||||
GUI.DrawString(spriteBatch, new Vector2(15, y + 110), "Fire amount: " + (int)Math.Round(fireAmount * 100), Color.Lerp(GUI.Style.Green, GUI.Style.Red, fireAmount), Color.Black * 0.6f, 0, GUI.SmallFont);
|
GUI.DrawString(spriteBatch, new Vector2(15, y + 110), "Fire amount: " + (int)Math.Round(fireAmount * 100), Color.Lerp(GUIStyle.Green, GUIStyle.Red, fireAmount), Color.Black * 0.6f, 0, GUIStyle.SmallFont);
|
||||||
GUI.DrawString(spriteBatch, new Vector2(15, y + 125), "Enemy danger: " + (int)Math.Round(enemyDanger * 100), Color.Lerp(GUI.Style.Green, GUI.Style.Red, enemyDanger), Color.Black * 0.6f, 0, GUI.SmallFont);
|
GUI.DrawString(spriteBatch, new Vector2(15, y + 125), "Enemy danger: " + (int)Math.Round(enemyDanger * 100), Color.Lerp(GUIStyle.Green, GUIStyle.Red, enemyDanger), Color.Black * 0.6f, 0, GUIStyle.SmallFont);
|
||||||
GUI.DrawString(spriteBatch, new Vector2(15, y + 140), "Current monster strength (total): " + (int)Math.Round(monsterStrength), Color.Lerp(GUI.Style.Green, GUI.Style.Red, relativeMonsterStrength), Color.Black * 0.6f, 0, GUI.SmallFont);
|
GUI.DrawString(spriteBatch, new Vector2(15, y + 140), "Current monster strength (total): " + (int)Math.Round(monsterStrength), Color.Lerp(GUIStyle.Green, GUIStyle.Red, relativeMonsterStrength), Color.Black * 0.6f, 0, GUIStyle.SmallFont);
|
||||||
GUI.DrawString(spriteBatch, new Vector2(15, y + 155), "Main events: " + (int)Math.Round(CumulativeMonsterStrengthMain), Color.White, Color.Black * 0.6f, 0, GUI.SmallFont);
|
GUI.DrawString(spriteBatch, new Vector2(15, y + 155), "Main events: " + (int)Math.Round(CumulativeMonsterStrengthMain), Color.White, Color.Black * 0.6f, 0, GUIStyle.SmallFont);
|
||||||
GUI.DrawString(spriteBatch, new Vector2(15, y + 170), "Ruin events: " + (int)Math.Round(CumulativeMonsterStrengthRuins), Color.White, Color.Black * 0.6f, 0, GUI.SmallFont);
|
GUI.DrawString(spriteBatch, new Vector2(15, y + 170), "Ruin events: " + (int)Math.Round(CumulativeMonsterStrengthRuins), Color.White, Color.Black * 0.6f, 0, GUIStyle.SmallFont);
|
||||||
GUI.DrawString(spriteBatch, new Vector2(15, y + 185), "Wreck events: " + (int)Math.Round(CumulativeMonsterStrengthWrecks), Color.White, Color.Black * 0.6f, 0, GUI.SmallFont);
|
GUI.DrawString(spriteBatch, new Vector2(15, y + 185), "Wreck events: " + (int)Math.Round(CumulativeMonsterStrengthWrecks), Color.White, Color.Black * 0.6f, 0, GUIStyle.SmallFont);
|
||||||
GUI.DrawString(spriteBatch, new Vector2(15, y + 200), "Cave events: " + (int)Math.Round(CumulativeMonsterStrengthCaves), Color.White, Color.Black * 0.6f, 0, GUI.SmallFont);
|
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (PlayerInput.KeyDown(Microsoft.Xna.Framework.Input.Keys.LeftAlt) &&
|
if (PlayerInput.KeyDown(Microsoft.Xna.Framework.Input.Keys.LeftAlt) &&
|
||||||
@@ -101,7 +101,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
isGraphSelected = false;
|
isGraphSelected = false;
|
||||||
}
|
}
|
||||||
Color intensityColor = Color.Lerp(Color.White, GUI.Style.Red, currentIntensity);
|
Color intensityColor = Color.Lerp(Color.White, GUIStyle.Red, currentIntensity);
|
||||||
if (isGraphHovered || isGraphSelected)
|
if (isGraphHovered || isGraphSelected)
|
||||||
{
|
{
|
||||||
graphRect.Size = new Point(GameMain.GraphicsWidth - 30, (int)(GameMain.GraphicsHeight * 0.35f));
|
graphRect.Size = new Point(GameMain.GraphicsWidth - 30, (int)(GameMain.GraphicsHeight * 0.35f));
|
||||||
@@ -122,7 +122,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
height *= 3;
|
height *= 3;
|
||||||
string text = (order / 6).ToString();
|
string text = (order / 6).ToString();
|
||||||
var font = GUI.SmallFont;
|
var font = GUIStyle.SmallFont;
|
||||||
Vector2 textSize = font.MeasureString(text);
|
Vector2 textSize = font.MeasureString(text);
|
||||||
Vector2 textPos = new Vector2(bottomPoint.X - textSize.X / 2, bottomPoint.Y + height * 1.5f);
|
Vector2 textPos = new Vector2(bottomPoint.X - textSize.X / 2, bottomPoint.Y + height * 1.5f);
|
||||||
GUI.DrawString(sBatch, textPos, text, Color.White, font: font);
|
GUI.DrawString(sBatch, textPos, text, Color.White, font: font);
|
||||||
@@ -175,23 +175,23 @@ namespace Barotrauma
|
|||||||
int x = graphRect.X;
|
int x = graphRect.X;
|
||||||
if (isCrewAway && crewAwayDuration < settings.FreezeDurationWhenCrewAway)
|
if (isCrewAway && crewAwayDuration < settings.FreezeDurationWhenCrewAway)
|
||||||
{
|
{
|
||||||
GUI.DrawString(spriteBatch, new Vector2(x, y), "Events frozen (crew away from sub): " + ToolBox.SecondsToReadableTime(settings.FreezeDurationWhenCrewAway - crewAwayDuration), Color.LightGreen * 0.8f, null, 0, GUI.SmallFont);
|
GUI.DrawString(spriteBatch, new Vector2(x, y), "Events frozen (crew away from sub): " + ToolBox.SecondsToReadableTime(settings.FreezeDurationWhenCrewAway - crewAwayDuration), Color.LightGreen * 0.8f, null, 0, GUIStyle.SmallFont);
|
||||||
y += 15;
|
y += 15;
|
||||||
}
|
}
|
||||||
else if (crewAwayResetTimer > 0.0f)
|
else if (crewAwayResetTimer > 0.0f)
|
||||||
{
|
{
|
||||||
GUI.DrawString(spriteBatch, new Vector2(x, y), "Events frozen (crew just returned to the sub): " + ToolBox.SecondsToReadableTime(crewAwayResetTimer), Color.LightGreen * 0.8f, null, 0, GUI.SmallFont);
|
GUI.DrawString(spriteBatch, new Vector2(x, y), "Events frozen (crew just returned to the sub): " + ToolBox.SecondsToReadableTime(crewAwayResetTimer), Color.LightGreen * 0.8f, null, 0, GUIStyle.SmallFont);
|
||||||
y += 15;
|
y += 15;
|
||||||
}
|
}
|
||||||
else if (eventCoolDown > 0.0f)
|
else if (eventCoolDown > 0.0f)
|
||||||
{
|
{
|
||||||
GUI.DrawString(spriteBatch, new Vector2(x, y), "Event cooldown active: " + ToolBox.SecondsToReadableTime(eventCoolDown), Color.LightGreen * 0.8f, null, 0, GUI.SmallFont);
|
GUI.DrawString(spriteBatch, new Vector2(x, y), "Event cooldown active: " + ToolBox.SecondsToReadableTime(eventCoolDown), Color.LightGreen * 0.8f, null, 0, GUIStyle.SmallFont);
|
||||||
y += 15;
|
y += 15;
|
||||||
}
|
}
|
||||||
else if (currentIntensity > eventThreshold)
|
else if (currentIntensity > eventThreshold)
|
||||||
{
|
{
|
||||||
GUI.DrawString(spriteBatch, new Vector2(x, y),
|
GUI.DrawString(spriteBatch, new Vector2(x, y),
|
||||||
"Intensity too high for new events: " + (int)(currentIntensity * 100) + "%/" + (int)(eventThreshold * 100) + "%", Color.LightGreen * 0.8f, null, 0, GUI.SmallFont);
|
"Intensity too high for new events: " + (int)(currentIntensity * 100) + "%/" + (int)(eventThreshold * 100) + "%", Color.LightGreen * 0.8f, null, 0, GUIStyle.SmallFont);
|
||||||
y += 15;
|
y += 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,29 +199,29 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (Submarine.MainSub == null) { break; }
|
if (Submarine.MainSub == null) { break; }
|
||||||
|
|
||||||
GUI.DrawString(spriteBatch, new Vector2(x, y), "New event (ID " + eventSet.DebugIdentifier + ") after: ", Color.Orange * 0.8f, null, 0, GUI.SmallFont);
|
GUI.DrawString(spriteBatch, new Vector2(x, y), "New event (ID " + eventSet.Identifier + ") after: ", Color.Orange * 0.8f, null, 0, GUIStyle.SmallFont);
|
||||||
y += 12;
|
y += 12;
|
||||||
|
|
||||||
if (eventSet.PerCave)
|
if (eventSet.PerCave)
|
||||||
{
|
{
|
||||||
GUI.DrawString(spriteBatch, new Vector2(x, y), " submarine near cave", Color.Orange * 0.8f, null, 0, GUI.SmallFont);
|
GUI.DrawString(spriteBatch, new Vector2(x, y), " submarine near cave", Color.Orange * 0.8f, null, 0, GUIStyle.SmallFont);
|
||||||
y += 12;
|
y += 12;
|
||||||
}
|
}
|
||||||
if (eventSet.PerWreck)
|
if (eventSet.PerWreck)
|
||||||
{
|
{
|
||||||
GUI.DrawString(spriteBatch, new Vector2(x, y), " submarine near the wreck", Color.Orange * 0.8f, null, 0, GUI.SmallFont);
|
GUI.DrawString(spriteBatch, new Vector2(x, y), " submarine near the wreck", Color.Orange * 0.8f, null, 0, GUIStyle.SmallFont);
|
||||||
y += 12;
|
y += 12;
|
||||||
}
|
}
|
||||||
if (eventSet.PerRuin)
|
if (eventSet.PerRuin)
|
||||||
{
|
{
|
||||||
GUI.DrawString(spriteBatch, new Vector2(x, y), " submarine near the ruins", Color.Orange * 0.8f, null, 0, GUI.SmallFont);
|
GUI.DrawString(spriteBatch, new Vector2(x, y), " submarine near the ruins", Color.Orange * 0.8f, null, 0, GUIStyle.SmallFont);
|
||||||
y += 12;
|
y += 12;
|
||||||
}
|
}
|
||||||
if (roundDuration < eventSet.MinMissionTime)
|
if (roundDuration < eventSet.MinMissionTime)
|
||||||
{
|
{
|
||||||
GUI.DrawString(spriteBatch, new Vector2(x, y),
|
GUI.DrawString(spriteBatch, new Vector2(x, y),
|
||||||
" " + (int) (eventSet.MinDistanceTraveled * 100.0f) + "% travelled (current: " + (int) (distanceTraveled * 100.0f) + " %)",
|
" " + (int) (eventSet.MinDistanceTraveled * 100.0f) + "% travelled (current: " + (int) (distanceTraveled * 100.0f) + " %)",
|
||||||
((Submarine.MainSub == null || distanceTraveled < eventSet.MinDistanceTraveled) ? Color.Lerp(GUI.Style.Yellow, GUI.Style.Red, eventSet.MinDistanceTraveled - distanceTraveled) : GUI.Style.Green) * 0.8f, null, 0, GUI.SmallFont);
|
((Submarine.MainSub == null || distanceTraveled < eventSet.MinDistanceTraveled) ? Color.Lerp(GUIStyle.Yellow, GUIStyle.Red, eventSet.MinDistanceTraveled - distanceTraveled) : GUIStyle.Green) * 0.8f, null, 0, GUIStyle.SmallFont);
|
||||||
y += 12;
|
y += 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,15 +229,15 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
GUI.DrawString(spriteBatch, new Vector2(x, y),
|
GUI.DrawString(spriteBatch, new Vector2(x, y),
|
||||||
" intensity between " + eventSet.MinIntensity.FormatDoubleDecimal() + " and " + eventSet.MaxIntensity.FormatDoubleDecimal(),
|
" intensity between " + eventSet.MinIntensity.FormatDoubleDecimal() + " and " + eventSet.MaxIntensity.FormatDoubleDecimal(),
|
||||||
Color.Orange * 0.8f, null, 0, GUI.SmallFont);
|
Color.Orange * 0.8f, null, 0, GUIStyle.SmallFont);
|
||||||
y += 12;
|
y += 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (roundDuration < eventSet.MinMissionTime)
|
if (roundDuration < eventSet.MinMissionTime)
|
||||||
{
|
{
|
||||||
GUI.DrawString(spriteBatch, new Vector2(x, y),
|
GUI.DrawString(spriteBatch, new Vector2(x, y),
|
||||||
" " + (int) (eventSet.MinMissionTime - roundDuration) + " s",
|
" " + (int) (eventSet.MinMissionTime - roundDuration) + " s",
|
||||||
Color.Lerp(GUI.Style.Yellow, GUI.Style.Red, (eventSet.MinMissionTime - roundDuration)), null, 0, GUI.SmallFont);
|
Color.Lerp(GUIStyle.Yellow, GUIStyle.Red, (eventSet.MinMissionTime - roundDuration)), null, 0, GUIStyle.SmallFont);
|
||||||
}
|
}
|
||||||
|
|
||||||
y += 15;
|
y += 15;
|
||||||
@@ -249,14 +249,14 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GUI.DrawString(spriteBatch, new Vector2(x, y), "Current events: ", Color.White * 0.9f, null, 0, GUI.SmallFont);
|
GUI.DrawString(spriteBatch, new Vector2(x, y), "Current events: ", Color.White * 0.9f, null, 0, GUIStyle.SmallFont);
|
||||||
y += yStep;
|
y += yStep;
|
||||||
|
|
||||||
foreach (Event ev in activeEvents.Where(ev => !ev.IsFinished || PlayerInput.IsShiftDown()))
|
foreach (Event ev in activeEvents.Where(ev => !ev.IsFinished || PlayerInput.IsShiftDown()))
|
||||||
{
|
{
|
||||||
GUI.DrawString(spriteBatch, new Vector2(x + 5, y), ev.ToString(), (!ev.IsFinished ? Color.White : Color.Red) * 0.8f, null, 0, GUI.SmallFont);
|
GUI.DrawString(spriteBatch, new Vector2(x + 5, y), ev.ToString(), (!ev.IsFinished ? Color.White : Color.Red) * 0.8f, null, 0, GUIStyle.SmallFont);
|
||||||
|
|
||||||
Rectangle rect = new Rectangle(new Point(x + 5, y), GUI.SmallFont.MeasureString(ev.ToString()).ToPoint());
|
Rectangle rect = new Rectangle(new Point(x + 5, y), GUIStyle.SmallFont.MeasureString(ev.ToString()).ToPoint());
|
||||||
|
|
||||||
Rectangle outlineRect = new Rectangle(rect.Location, rect.Size);
|
Rectangle outlineRect = new Rectangle(rect.Location, rect.Size);
|
||||||
outlineRect.Inflate(4, 4);
|
outlineRect.Inflate(4, 4);
|
||||||
@@ -331,8 +331,8 @@ namespace Barotrauma
|
|||||||
if (Screen.Selected is GameScreen screen)
|
if (Screen.Selected is GameScreen screen)
|
||||||
{
|
{
|
||||||
Camera cam = screen.Cam;
|
Camera cam = screen.Cam;
|
||||||
Dictionary<Entity, List<string>> tagsDictionary = new Dictionary<Entity, List<string>>();
|
Dictionary<Entity, List<Identifier>> tagsDictionary = new Dictionary<Entity, List<Identifier>>();
|
||||||
foreach ((string key, List<Entity> value) in scriptedEvent.Targets)
|
foreach ((Identifier key, List<Entity> value) in scriptedEvent.Targets)
|
||||||
{
|
{
|
||||||
foreach (Entity entity in value)
|
foreach (Entity entity in value)
|
||||||
{
|
{
|
||||||
@@ -342,24 +342,24 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tagsDictionary.Add(entity, new List<string> { key });
|
tagsDictionary.Add(entity, new List<Identifier> { key });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string identifier = scriptedEvent.Prefab.Identifier;
|
Identifier identifier = scriptedEvent.Prefab.Identifier;
|
||||||
|
|
||||||
foreach ((Entity entity, List<string> tags) in tagsDictionary)
|
foreach ((Entity entity, List<Identifier> tags) in tagsDictionary)
|
||||||
{
|
{
|
||||||
if (entity.Removed) { continue; }
|
if (entity.Removed) { continue; }
|
||||||
|
|
||||||
string text = tags.Aggregate("Tags:\n", (current, tag) => current + $" {tag.ColorizeObject()}\n").TrimEnd('\r', '\n');
|
string text = tags.Aggregate("Tags:\n", (current, tag) => current + $" {tag.ColorizeObject()}\n").TrimEnd('\r', '\n');
|
||||||
if (!string.IsNullOrWhiteSpace(identifier)) { text = $"Event: {identifier.ColorizeObject()}\n{text}"; }
|
if (!identifier.IsEmpty) { text = $"Event: {identifier.ColorizeObject()}\n{text}"; }
|
||||||
|
|
||||||
List<RichTextData> richTextData = RichTextData.GetRichTextData(text, out text);
|
ImmutableArray<RichTextData>? richTextData = RichTextData.GetRichTextData(text, out text);
|
||||||
|
|
||||||
Vector2 entityPos = cam.WorldToScreen(entity.WorldPosition);
|
Vector2 entityPos = cam.WorldToScreen(entity.WorldPosition);
|
||||||
Vector2 infoSize = GUI.SmallFont.MeasureString(text);
|
Vector2 infoSize = GUIStyle.SmallFont.MeasureString(text);
|
||||||
|
|
||||||
Vector2 infoPos = entityPos + new Vector2(128 * cam.Zoom, -(128 * cam.Zoom));
|
Vector2 infoPos = entityPos + new Vector2(128 * cam.Zoom, -(128 * cam.Zoom));
|
||||||
infoPos.Y -= infoSize.Y / 2;
|
infoPos.Y -= infoSize.Y / 2;
|
||||||
@@ -370,7 +370,7 @@ namespace Barotrauma
|
|||||||
GUI.DrawRectangle(spriteBatch, infoRect, Color.Black * 0.8f, isFilled: true);
|
GUI.DrawRectangle(spriteBatch, infoRect, Color.Black * 0.8f, isFilled: true);
|
||||||
GUI.DrawRectangle(spriteBatch, infoRect, Color.White, isFilled: false);
|
GUI.DrawRectangle(spriteBatch, infoRect, Color.White, isFilled: false);
|
||||||
|
|
||||||
GUI.DrawStringWithColors(spriteBatch, infoPos, text, Color.White, richTextData, font: GUI.SmallFont);
|
GUI.DrawStringWithColors(spriteBatch, infoPos, text, Color.White, richTextData, font: GUIStyle.SmallFont);
|
||||||
|
|
||||||
GUI.DrawLine(spriteBatch, entityPos, new Vector2(infoRect.Location.X, infoRect.Location.Y + infoRect.Height / 2), Color.White);
|
GUI.DrawLine(spriteBatch, entityPos, new Vector2(infoRect.Location.X, infoRect.Location.Y + infoRect.Height / 2), Color.White);
|
||||||
}
|
}
|
||||||
@@ -489,15 +489,15 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
text = text.TrimEnd('\r', '\n');
|
text = text.TrimEnd('\r', '\n');
|
||||||
|
|
||||||
string identifier = @event.Prefab.Identifier;
|
Identifier identifier = @event.Prefab.Identifier;
|
||||||
if (!string.IsNullOrWhiteSpace(identifier))
|
if (!identifier.IsEmpty)
|
||||||
{
|
{
|
||||||
text = $"Identifier: {identifier.ColorizeObject()}\n{text}";
|
text = $"Identifier: {identifier.ColorizeObject()}\n{text}";
|
||||||
}
|
}
|
||||||
|
|
||||||
List<RichTextData> richTextData = RichTextData.GetRichTextData(text, out text);
|
ImmutableArray<RichTextData>? richTextData = RichTextData.GetRichTextData(text, out text);
|
||||||
|
|
||||||
Vector2 size = GUI.SmallFont.MeasureString(text);
|
Vector2 size = GUIStyle.SmallFont.MeasureString(text);
|
||||||
Vector2 pos = pinnedPosition;
|
Vector2 pos = pinnedPosition;
|
||||||
Rectangle infoRect;
|
Rectangle infoRect;
|
||||||
Rectangle? infoBarRect = null;
|
Rectangle? infoBarRect = null;
|
||||||
@@ -520,7 +520,7 @@ namespace Barotrauma
|
|||||||
const string titleHeader = "Pinned event";
|
const string titleHeader = "Pinned event";
|
||||||
|
|
||||||
GUI.DrawRectangle(spriteBatch, barRect, Color.DarkGray * 0.8f, isFilled: true);
|
GUI.DrawRectangle(spriteBatch, barRect, Color.DarkGray * 0.8f, isFilled: true);
|
||||||
GUI.DrawString(spriteBatch, barRect.Location.ToVector2() + barRect.Size.ToVector2() / 2 - GUI.SubHeadingFont.MeasureString(titleHeader) / 2, titleHeader, Color.White);
|
GUI.DrawString(spriteBatch, barRect.Location.ToVector2() + barRect.Size.ToVector2() / 2 - GUIStyle.SubHeadingFont.MeasureString(titleHeader) / 2, titleHeader, Color.White);
|
||||||
GUI.DrawRectangle(spriteBatch, barRect, Color.White);
|
GUI.DrawRectangle(spriteBatch, barRect, Color.White);
|
||||||
infoBarRect = barRect;
|
infoBarRect = barRect;
|
||||||
}
|
}
|
||||||
@@ -546,8 +546,14 @@ namespace Barotrauma
|
|||||||
GUI.DrawRectangle(spriteBatch, infoRect, Color.Black * 0.8f, isFilled: true);
|
GUI.DrawRectangle(spriteBatch, infoRect, Color.Black * 0.8f, isFilled: true);
|
||||||
GUI.DrawRectangle(spriteBatch, infoRect, Color.White);
|
GUI.DrawRectangle(spriteBatch, infoRect, Color.White);
|
||||||
|
|
||||||
GUI.DrawStringWithColors(spriteBatch, pos, text, Color.White, richTextData, null, 0, GUI.SmallFont);
|
if (richTextData.HasValue && richTextData.Value.Length > 0)
|
||||||
richTextData.Clear();
|
{
|
||||||
|
GUI.DrawStringWithColors(spriteBatch, pos, text, Color.White, richTextData.Value, null, 0, GUIStyle.SmallFont);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GUI.DrawString(spriteBatch, pos, text, Color.White, null, 0, GUIStyle.SmallFont);
|
||||||
|
}
|
||||||
return infoBarRect ?? infoRect;
|
return infoBarRect ?? infoRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -557,7 +563,7 @@ namespace Barotrauma
|
|||||||
switch (eventType)
|
switch (eventType)
|
||||||
{
|
{
|
||||||
case NetworkEventType.STATUSEFFECT:
|
case NetworkEventType.STATUSEFFECT:
|
||||||
string eventIdentifier = msg.ReadString();
|
Identifier eventIdentifier = msg.ReadIdentifier();
|
||||||
UInt16 actionIndex = msg.ReadUInt16();
|
UInt16 actionIndex = msg.ReadUInt16();
|
||||||
UInt16 targetCount = msg.ReadUInt16();
|
UInt16 targetCount = msg.ReadUInt16();
|
||||||
List<Entity> targets = new List<Entity>();
|
List<Entity> targets = new List<Entity>();
|
||||||
@@ -571,14 +577,14 @@ namespace Barotrauma
|
|||||||
var eventPrefab = EventSet.GetEventPrefab(eventIdentifier);
|
var eventPrefab = EventSet.GetEventPrefab(eventIdentifier);
|
||||||
if (eventPrefab == null) { return; }
|
if (eventPrefab == null) { return; }
|
||||||
int j = 0;
|
int j = 0;
|
||||||
foreach (XElement element in eventPrefab.ConfigElement.Descendants())
|
foreach (var element in eventPrefab.ConfigElement.Descendants())
|
||||||
{
|
{
|
||||||
if (j != actionIndex)
|
if (j != actionIndex)
|
||||||
{
|
{
|
||||||
j++;
|
j++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
foreach (XElement subElement in element.Elements())
|
foreach (var subElement in element.Elements())
|
||||||
{
|
{
|
||||||
if (!subElement.Name.ToString().Equals("statuseffect", StringComparison.OrdinalIgnoreCase)) { continue; }
|
if (!subElement.Name.ToString().Equals("statuseffect", StringComparison.OrdinalIgnoreCase)) { continue; }
|
||||||
StatusEffect effect = StatusEffect.Load(subElement, $"EventManager.ClientRead ({eventIdentifier})");
|
StatusEffect effect = StatusEffect.Load(subElement, $"EventManager.ClientRead ({eventIdentifier})");
|
||||||
@@ -633,13 +639,13 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NetworkEventType.MISSION:
|
case NetworkEventType.MISSION:
|
||||||
string missionIdentifier = msg.ReadString();
|
Identifier missionIdentifier = msg.ReadIdentifier();
|
||||||
|
|
||||||
MissionPrefab? prefab = MissionPrefab.List.Find(mp => mp.Identifier.Equals(missionIdentifier, StringComparison.OrdinalIgnoreCase));
|
MissionPrefab? prefab = MissionPrefab.Prefabs.Find(mp => mp.Identifier == missionIdentifier);
|
||||||
if (prefab != null)
|
if (prefab != null)
|
||||||
{
|
{
|
||||||
new GUIMessageBox(string.Empty, TextManager.GetWithVariable("missionunlocked", "[missionname]", prefab.Name),
|
new GUIMessageBox(string.Empty, TextManager.GetWithVariable("missionunlocked", "[missionname]", prefab.Name),
|
||||||
new string[0], type: GUIMessageBox.Type.InGame, icon: prefab.Icon, relativeSize: new Vector2(0.3f, 0.15f), minSize: new Point(512, 128))
|
Array.Empty<LocalizedString>(), type: GUIMessageBox.Type.InGame, icon: prefab.Icon, relativeSize: new Vector2(0.3f, 0.15f), minSize: new Point(512, 128))
|
||||||
{
|
{
|
||||||
IconColor = prefab.IconColor
|
IconColor = prefab.IconColor
|
||||||
};
|
};
|
||||||
@@ -657,7 +663,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
GameMain.GameSession.Map.Connections[connectionIndex].Locked = false;
|
GameMain.GameSession.Map.Connections[connectionIndex].Locked = false;
|
||||||
new GUIMessageBox(string.Empty, TextManager.Get("pathunlockedgeneric"),
|
new GUIMessageBox(string.Empty, TextManager.Get("pathunlockedgeneric"),
|
||||||
new string[0], type: GUIMessageBox.Type.InGame, iconStyle: "UnlockPathIcon", relativeSize: new Vector2(0.3f, 0.15f), minSize: new Point(512, 128));
|
Array.Empty<LocalizedString>(), type: GUIMessageBox.Type.InGame, iconStyle: "UnlockPathIcon", relativeSize: new Vector2(0.3f, 0.15f), minSize: new Point(512, 128));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace Barotrauma
|
|||||||
if (state != value)
|
if (state != value)
|
||||||
{
|
{
|
||||||
base.State = value;
|
base.State = value;
|
||||||
if (state == HostagesKilledState && !string.IsNullOrEmpty(hostagesKilledMessage))
|
if (state == HostagesKilledState && !hostagesKilledMessage.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
CreateMessageBox(string.Empty, hostagesKilledMessage);
|
CreateMessageBox(string.Empty, hostagesKilledMessage);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,23 +8,29 @@ namespace Barotrauma
|
|||||||
public override bool DisplayAsCompleted => false;
|
public override bool DisplayAsCompleted => false;
|
||||||
public override bool DisplayAsFailed => false;
|
public override bool DisplayAsFailed => false;
|
||||||
|
|
||||||
public override string GetMissionRewardText(Submarine sub)
|
public override RichString GetMissionRewardText(Submarine sub)
|
||||||
{
|
{
|
||||||
string rewardText = TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", GetReward(sub)));
|
LocalizedString rewardText = TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", GetReward(sub)));
|
||||||
|
|
||||||
|
LocalizedString retVal;
|
||||||
if (rewardPerCrate.HasValue)
|
if (rewardPerCrate.HasValue)
|
||||||
{
|
{
|
||||||
string rewardPerCrateText = TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", rewardPerCrate.Value));
|
LocalizedString rewardPerCrateText = TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", rewardPerCrate.Value));
|
||||||
return TextManager.GetWithVariables("missionrewardcargopercrate",
|
retVal = TextManager.GetWithVariables("missionrewardcargopercrate",
|
||||||
new string[] { "[rewardpercrate]", "[itemcount]", "[maxitemcount]", "[totalreward]" },
|
("[rewardpercrate]", rewardPerCrateText),
|
||||||
new string[] { rewardPerCrateText, itemsToSpawn.Count.ToString(), maxItemCount.ToString(), $"‖color:gui.orange‖{rewardText}‖end‖" });
|
("[itemcount]", itemsToSpawn.Count.ToString()),
|
||||||
|
("[maxitemcount]", maxItemCount.ToString()),
|
||||||
|
("[totalreward]", $"‖color:gui.orange‖{rewardText}‖end‖"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return TextManager.GetWithVariables("missionrewardcargo",
|
retVal = TextManager.GetWithVariables("missionrewardcargo",
|
||||||
new string[] { "[totalreward]", "[itemcount]", "[maxitemcount]" },
|
("[totalreward]", $"‖color:gui.orange‖{rewardText}‖end‖"),
|
||||||
new string[] { $"‖color:gui.orange‖{rewardText}‖end‖", itemsToSpawn.Count.ToString(), maxItemCount.ToString() });
|
("[itemcount]", itemsToSpawn.Count.ToString()),
|
||||||
|
("[maxitemcount]", maxItemCount.ToString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return RichString.Rich(retVal);
|
||||||
}
|
}
|
||||||
public override void ClientReadInitial(IReadMessage msg)
|
public override void ClientReadInitial(IReadMessage msg)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
partial class CombatMission : Mission
|
partial class CombatMission : Mission
|
||||||
{
|
{
|
||||||
public override string Description
|
public override LocalizedString Description
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
for(int i = 0; i < resourceClusters.Count; i++)
|
for(int i = 0; i < resourceClusters.Count; i++)
|
||||||
{
|
{
|
||||||
var identifier = msg.ReadString();
|
var identifier = msg.ReadIdentifier();
|
||||||
var count = msg.ReadByte();
|
var count = msg.ReadByte();
|
||||||
var resources = new Item[count];
|
var resources = new Item[count];
|
||||||
for (int j = 0; j < count; j++)
|
for (int j = 0; j < count; j++)
|
||||||
|
|||||||
@@ -9,11 +9,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
abstract partial class Mission
|
abstract partial class Mission
|
||||||
{
|
{
|
||||||
private readonly List<string> shownMessages = new List<string>();
|
private readonly List<LocalizedString> shownMessages = new List<LocalizedString>();
|
||||||
public IEnumerable<string> ShownMessages
|
public IEnumerable<LocalizedString> ShownMessages => shownMessages;
|
||||||
{
|
|
||||||
get { return shownMessages; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool DisplayTargetHudIcons => Prefab.DisplayTargetHudIcons;
|
public bool DisplayTargetHudIcons => Prefab.DisplayTargetHudIcons;
|
||||||
|
|
||||||
@@ -32,29 +29,29 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
int v = Difficulty ?? MissionPrefab.MinDifficulty;
|
int v = Difficulty ?? MissionPrefab.MinDifficulty;
|
||||||
float t = MathUtils.InverseLerp(MissionPrefab.MinDifficulty, MissionPrefab.MaxDifficulty, v);
|
float t = MathUtils.InverseLerp(MissionPrefab.MinDifficulty, MissionPrefab.MaxDifficulty, v);
|
||||||
return ToolBox.GradientLerp(t, GUI.Style.Green, GUI.Style.Orange, GUI.Style.Red);
|
return ToolBox.GradientLerp(t, GUIStyle.Green, GUIStyle.Orange, GUIStyle.Red);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual string GetMissionRewardText(Submarine sub)
|
public virtual RichString GetMissionRewardText(Submarine sub)
|
||||||
{
|
{
|
||||||
string rewardText = TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", GetReward(sub)));
|
LocalizedString rewardText = TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", GetReward(sub)));
|
||||||
return TextManager.GetWithVariable("missionreward", "[reward]", $"‖color:gui.orange‖{rewardText}‖end‖");
|
return RichString.Rich(TextManager.GetWithVariable("missionreward", "[reward]", "‖color:gui.orange‖"+rewardText+"‖end‖"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetReputationRewardText(Location currLocation)
|
public RichString GetReputationRewardText(Location currLocation)
|
||||||
{
|
{
|
||||||
List<string> reputationRewardTexts = new List<string>();
|
List<LocalizedString> reputationRewardTexts = new List<LocalizedString>();
|
||||||
foreach (var reputationReward in ReputationRewards)
|
foreach (var reputationReward in ReputationRewards)
|
||||||
{
|
{
|
||||||
string name = "";
|
LocalizedString name = "";
|
||||||
|
|
||||||
if (reputationReward.Key.Equals("location", StringComparison.OrdinalIgnoreCase))
|
if (reputationReward.Key == "location")
|
||||||
{
|
{
|
||||||
name = $"‖color:gui.orange‖{currLocation.Name}‖end‖";
|
name = $"‖color:gui.orange‖{currLocation.Name}‖end‖";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var faction = FactionPrefab.Prefabs.Find(f => f.Identifier.Equals(reputationReward.Key, StringComparison.OrdinalIgnoreCase));
|
var faction = FactionPrefab.Prefabs.Find(f => f.Identifier == reputationReward.Key);
|
||||||
if (faction != null)
|
if (faction != null)
|
||||||
{
|
{
|
||||||
name = $"‖color:{XMLExtensions.ColorToString(faction.IconColor)}‖{faction.Name}‖end‖";
|
name = $"‖color:{XMLExtensions.ColorToString(faction.IconColor)}‖{faction.Name}‖end‖";
|
||||||
@@ -66,28 +63,28 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
float normalizedValue = MathUtils.InverseLerp(-100.0f, 100.0f, reputationReward.Value);
|
float normalizedValue = MathUtils.InverseLerp(-100.0f, 100.0f, reputationReward.Value);
|
||||||
string formattedValue = ((int)reputationReward.Value).ToString("+#;-#;0"); //force plus sign for positive numbers
|
string formattedValue = ((int)reputationReward.Value).ToString("+#;-#;0"); //force plus sign for positive numbers
|
||||||
string rewardText = TextManager.GetWithVariables(
|
LocalizedString rewardText = TextManager.GetWithVariables(
|
||||||
"reputationformat",
|
"reputationformat",
|
||||||
new string[] { "[reputationname]", "[reputationvalue]" },
|
("[reputationname]", name),
|
||||||
new string[] { name, $"‖color:{XMLExtensions.ColorToString(Reputation.GetReputationColor(normalizedValue))}‖{formattedValue}‖end‖" });
|
("[reputationvalue]", $"‖color:{XMLExtensions.ColorToString(Reputation.GetReputationColor(normalizedValue))}‖{formattedValue}‖end‖" ));
|
||||||
reputationRewardTexts.Add(rewardText);
|
reputationRewardTexts.Add(rewardText.Value);
|
||||||
}
|
}
|
||||||
return TextManager.AddPunctuation(':', TextManager.Get("reputation"), string.Join(", ", reputationRewardTexts));
|
return RichString.Rich(TextManager.AddPunctuation(':', TextManager.Get("reputation"), LocalizedString.Join(", ", reputationRewardTexts)));
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void ShowMessageProjSpecific(int missionState)
|
partial void ShowMessageProjSpecific(int missionState)
|
||||||
{
|
{
|
||||||
int messageIndex = missionState - 1;
|
int messageIndex = missionState - 1;
|
||||||
if (messageIndex >= Headers.Count && messageIndex >= Messages.Count) { return; }
|
if (messageIndex >= Headers.Length && messageIndex >= Messages.Length) { return; }
|
||||||
if (messageIndex < 0) { return; }
|
if (messageIndex < 0) { return; }
|
||||||
|
|
||||||
string header = messageIndex < Headers.Count ? Headers[messageIndex] : "";
|
LocalizedString header = messageIndex < Headers.Length ? Headers[messageIndex] : "";
|
||||||
string message = messageIndex < Messages.Count ? Messages[messageIndex] : "";
|
LocalizedString message = messageIndex < Messages.Length ? Messages[messageIndex] : "";
|
||||||
|
|
||||||
CoroutineManager.StartCoroutine(ShowMessageBoxAfterRoundSummary(header, message));
|
CoroutineManager.StartCoroutine(ShowMessageBoxAfterRoundSummary(header, message));
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<CoroutineStatus> ShowMessageBoxAfterRoundSummary(string header, string message)
|
private IEnumerable<CoroutineStatus> ShowMessageBoxAfterRoundSummary(LocalizedString header, LocalizedString message)
|
||||||
{
|
{
|
||||||
while (GUIMessageBox.VisibleBox?.UserData is RoundSummary)
|
while (GUIMessageBox.VisibleBox?.UserData is RoundSummary)
|
||||||
{
|
{
|
||||||
@@ -97,10 +94,10 @@ namespace Barotrauma
|
|||||||
yield return CoroutineStatus.Success;
|
yield return CoroutineStatus.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void CreateMessageBox(string header, string message)
|
protected void CreateMessageBox(LocalizedString header, LocalizedString message)
|
||||||
{
|
{
|
||||||
shownMessages.Add(message);
|
shownMessages.Add(message);
|
||||||
new GUIMessageBox(header, message, buttons: new string[0], type: GUIMessageBox.Type.InGame, icon: Prefab.Icon, parseRichText: true)
|
new GUIMessageBox(RichString.Rich(header), RichString.Rich(message), buttons: Array.Empty<LocalizedString>(), type: GUIMessageBox.Type.InGame, icon: Prefab.Icon)
|
||||||
{
|
{
|
||||||
IconColor = Prefab.IconColor
|
IconColor = Prefab.IconColor
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
namespace Barotrauma
|
using System;
|
||||||
|
|
||||||
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
abstract partial class MissionMode : GameMode
|
abstract partial class MissionMode : GameMode
|
||||||
{
|
{
|
||||||
@@ -6,7 +8,7 @@
|
|||||||
{
|
{
|
||||||
foreach (Mission mission in missions)
|
foreach (Mission mission in missions)
|
||||||
{
|
{
|
||||||
new GUIMessageBox(mission.Name, mission.Description, new string[0], type: GUIMessageBox.Type.InGame, icon: mission.Prefab.Icon, parseRichText: true)
|
new GUIMessageBox(RichString.Rich(mission.Name), RichString.Rich(mission.Description), Array.Empty<LocalizedString>(), type: GUIMessageBox.Type.InGame, icon: mission.Prefab.Icon)
|
||||||
{
|
{
|
||||||
IconColor = mission.Prefab.IconColor,
|
IconColor = mission.Prefab.IconColor,
|
||||||
UserData = "missionstartmessage"
|
UserData = "missionstartmessage"
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ using System.Xml.Linq;
|
|||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
partial class MissionPrefab
|
partial class MissionPrefab : PrefabWithUintIdentifier
|
||||||
{
|
{
|
||||||
public Sprite Icon
|
public Sprite Icon
|
||||||
{
|
{
|
||||||
@@ -49,11 +49,11 @@ namespace Barotrauma
|
|||||||
private Sprite hudIcon;
|
private Sprite hudIcon;
|
||||||
private Color? hudIconColor;
|
private Color? hudIconColor;
|
||||||
|
|
||||||
partial void InitProjSpecific(XElement element)
|
partial void InitProjSpecific(ContentXElement element)
|
||||||
{
|
{
|
||||||
DisplayTargetHudIcons = element.GetAttributeBool("displaytargethudicons", false);
|
DisplayTargetHudIcons = element.GetAttributeBool("displaytargethudicons", false);
|
||||||
HudIconMaxDistance = element.GetAttributeFloat("hudiconmaxdistance", 1000.0f);
|
HudIconMaxDistance = element.GetAttributeFloat("hudiconmaxdistance", 1000.0f);
|
||||||
foreach (XElement subElement in element.Elements())
|
foreach (var subElement in element.Elements())
|
||||||
{
|
{
|
||||||
string name = subElement.Name.ToString();
|
string name = subElement.Name.ToString();
|
||||||
if (name.Equals("icon", StringComparison.OrdinalIgnoreCase))
|
if (name.Equals("icon", StringComparison.OrdinalIgnoreCase))
|
||||||
@@ -68,5 +68,10 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
partial void DisposeProjectSpecific()
|
||||||
|
{
|
||||||
|
Icon?.Remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using Microsoft.Xna.Framework.Graphics;
|
|||||||
using SharpFont;
|
using SharpFont;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Immutable;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
|
||||||
@@ -19,7 +20,6 @@ namespace Barotrauma
|
|||||||
private Face face;
|
private Face face;
|
||||||
private uint size;
|
private uint size;
|
||||||
private int baseHeight;
|
private int baseHeight;
|
||||||
//private int lineHeight;
|
|
||||||
private Dictionary<uint, GlyphData> texCoords;
|
private Dictionary<uint, GlyphData> texCoords;
|
||||||
private List<Texture2D> textures;
|
private List<Texture2D> textures;
|
||||||
private GraphicsDevice graphicsDevice;
|
private GraphicsDevice graphicsDevice;
|
||||||
@@ -53,6 +53,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool ForceUpperCase = false;
|
||||||
|
|
||||||
public float LineHeight => baseHeight * 1.8f;
|
public float LineHeight => baseHeight * 1.8f;
|
||||||
|
|
||||||
private uint[] charRanges;
|
private uint[] charRanges;
|
||||||
@@ -79,9 +81,9 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScalableFont(XElement element, GraphicsDevice gd = null)
|
public ScalableFont(ContentXElement element, GraphicsDevice gd = null)
|
||||||
: this(
|
: this(
|
||||||
element.GetAttributeString("file", ""),
|
element.GetAttributeContentPath("file")?.Value,
|
||||||
(uint)element.GetAttributeInt("size", 14),
|
(uint)element.GetAttributeInt("size", 14),
|
||||||
gd,
|
gd,
|
||||||
element.GetAttributeBool("dynamicloading", false),
|
element.GetAttributeBool("dynamicloading", false),
|
||||||
@@ -104,10 +106,7 @@ namespace Barotrauma
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.face == null)
|
this.face ??= new Face(Lib, filename);
|
||||||
{
|
|
||||||
this.face = new Face(Lib, filename);
|
|
||||||
}
|
|
||||||
this.size = size;
|
this.size = size;
|
||||||
this.textures = new List<Texture2D>();
|
this.textures = new List<Texture2D>();
|
||||||
this.texCoords = new Dictionary<uint, GlyphData>();
|
this.texCoords = new Dictionary<uint, GlyphData>();
|
||||||
@@ -399,6 +398,52 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: refactor this further
|
||||||
|
private void HandleNewLineAndAlignment(
|
||||||
|
string text,
|
||||||
|
in Vector2 advanceUnit,
|
||||||
|
in Vector2 position,
|
||||||
|
in Vector2 scale,
|
||||||
|
Alignment alignment,
|
||||||
|
int i,
|
||||||
|
ref float lineWidth,
|
||||||
|
ref Vector2 currentLineOffset,
|
||||||
|
ref int lineNum,
|
||||||
|
ref Vector2 currentPos,
|
||||||
|
out uint charIndex,
|
||||||
|
out bool shouldContinue)
|
||||||
|
{
|
||||||
|
if ((alignment.HasFlag(Alignment.CenterX) || alignment.HasFlag(Alignment.Right)) && (lineWidth < 0.0f || text[i] == '\n'))
|
||||||
|
{
|
||||||
|
int startIndex = lineWidth < 0.0f ? i : (i + 1);
|
||||||
|
lineWidth = 0.0f;
|
||||||
|
for (int j = startIndex; j < text.Length; j++)
|
||||||
|
{
|
||||||
|
if (text[j] == '\n') { break; }
|
||||||
|
uint chrIndex = text[j];
|
||||||
|
|
||||||
|
var gd2 = GetGlyphData(chrIndex);
|
||||||
|
lineWidth += gd2.Advance;
|
||||||
|
}
|
||||||
|
currentLineOffset = -lineWidth * advanceUnit * scale.X;
|
||||||
|
if (alignment.HasFlag(Alignment.CenterX)) { currentLineOffset *= 0.5f; }
|
||||||
|
|
||||||
|
currentLineOffset.X = MathF.Round(currentLineOffset.X);
|
||||||
|
currentLineOffset.Y = MathF.Round(currentLineOffset.Y);
|
||||||
|
}
|
||||||
|
if (text[i] == '\n')
|
||||||
|
{
|
||||||
|
lineNum++;
|
||||||
|
currentPos = position;
|
||||||
|
currentPos.X -= LineHeight * lineNum * advanceUnit.Y * scale.Y;
|
||||||
|
currentPos.Y += LineHeight * lineNum * advanceUnit.X * scale.Y;
|
||||||
|
shouldContinue = true; charIndex = 0; return;
|
||||||
|
}
|
||||||
|
|
||||||
|
shouldContinue = false;
|
||||||
|
charIndex = text[i];
|
||||||
|
}
|
||||||
|
|
||||||
private GlyphData GetGlyphData(uint charIndex)
|
private GlyphData GetGlyphData(uint charIndex)
|
||||||
{
|
{
|
||||||
const uint DEFAULT_INDEX = 0x25A1; //U+25A1 = white square
|
const uint DEFAULT_INDEX = 0x25A1; //U+25A1 = white square
|
||||||
@@ -412,29 +457,27 @@ namespace Barotrauma
|
|||||||
return new GlyphData(texIndex: -1);
|
return new GlyphData(texIndex: -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawString(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects se, float layerDepth)
|
public void DrawString(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects se, float layerDepth, Alignment alignment = Alignment.TopLeft, ForceUpperCase forceUpperCase = Barotrauma.ForceUpperCase.Inherit)
|
||||||
{
|
{
|
||||||
if (textures.Count == 0 && !DynamicLoading) { return; }
|
if (textures.Count == 0 && !DynamicLoading) { return; }
|
||||||
|
text = ApplyUpperCase(text, forceUpperCase);
|
||||||
if (DynamicLoading)
|
if (DynamicLoading)
|
||||||
{
|
{
|
||||||
DynamicRenderAtlas(graphicsDevice, text);
|
DynamicRenderAtlas(graphicsDevice, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float lineWidth = -1.0f;
|
||||||
|
Vector2 currentLineOffset = Vector2.Zero;
|
||||||
|
|
||||||
int lineNum = 0;
|
int lineNum = 0;
|
||||||
Vector2 currentPos = position;
|
Vector2 currentPos = position;
|
||||||
Vector2 advanceUnit = rotation == 0.0f ? Vector2.UnitX : new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation));
|
Vector2 advanceUnit = rotation == 0.0f ? Vector2.UnitX : new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation));
|
||||||
for (int i = 0; i < text.Length; i++)
|
for (int i = 0; i < text.Length; i++)
|
||||||
{
|
{
|
||||||
if (text[i] == '\n')
|
HandleNewLineAndAlignment(text, advanceUnit, position, scale, alignment, i,
|
||||||
{
|
ref lineWidth, ref currentLineOffset, ref lineNum, ref currentPos,
|
||||||
lineNum++;
|
out uint charIndex, out bool shouldContinue);
|
||||||
currentPos = position;
|
if (shouldContinue) { continue; }
|
||||||
currentPos.X -= LineHeight * lineNum * advanceUnit.Y * scale.Y;
|
|
||||||
currentPos.Y += LineHeight * lineNum * advanceUnit.X * scale.Y;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint charIndex = text[i];
|
|
||||||
|
|
||||||
GlyphData gd = GetGlyphData(charIndex);
|
GlyphData gd = GetGlyphData(charIndex);
|
||||||
if (gd.TexIndex >= 0)
|
if (gd.TexIndex >= 0)
|
||||||
@@ -444,20 +487,30 @@ namespace Barotrauma
|
|||||||
drawOffset.X = gd.DrawOffset.X * advanceUnit.X * scale.X - gd.DrawOffset.Y * advanceUnit.Y * scale.Y;
|
drawOffset.X = gd.DrawOffset.X * advanceUnit.X * scale.X - gd.DrawOffset.Y * advanceUnit.Y * scale.Y;
|
||||||
drawOffset.Y = gd.DrawOffset.X * advanceUnit.Y * scale.Y + gd.DrawOffset.Y * advanceUnit.X * scale.X;
|
drawOffset.Y = gd.DrawOffset.X * advanceUnit.Y * scale.Y + gd.DrawOffset.Y * advanceUnit.X * scale.X;
|
||||||
|
|
||||||
sb.Draw(tex, currentPos + drawOffset, gd.TexCoords, color, rotation, origin, scale, se, layerDepth);
|
sb.Draw(tex, currentPos + currentLineOffset + drawOffset, gd.TexCoords, color, rotation, origin, scale, se, layerDepth);
|
||||||
}
|
}
|
||||||
currentPos += gd.Advance * advanceUnit * scale.X;
|
currentPos += gd.Advance * advanceUnit * scale.X;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawString(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects se, float layerDepth)
|
public void DrawString(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects se, float layerDepth, Alignment alignment = Alignment.TopLeft, ForceUpperCase forceUpperCase = Barotrauma.ForceUpperCase.Inherit)
|
||||||
{
|
{
|
||||||
DrawString(sb, text, position, color, rotation, origin, new Vector2(scale), se, layerDepth);
|
DrawString(sb, text, position, color, rotation, origin, new Vector2(scale), se, layerDepth, alignment, forceUpperCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawString(SpriteBatch sb, string text, Vector2 position, Color color)
|
private string ApplyUpperCase(string text, ForceUpperCase forceUpperCase)
|
||||||
|
=> forceUpperCase switch
|
||||||
|
{
|
||||||
|
Barotrauma.ForceUpperCase.Inherit => ForceUpperCase ? text.ToUpper() : text,
|
||||||
|
Barotrauma.ForceUpperCase.Yes => text.ToUpper(),
|
||||||
|
Barotrauma.ForceUpperCase.No => text
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly static VertexPositionColorTexture[] quadVertices = new VertexPositionColorTexture[4];
|
||||||
|
public void DrawString(SpriteBatch sb, string text, Vector2 position, Color color, ForceUpperCase forceUpperCase = Barotrauma.ForceUpperCase.Inherit, bool italics = false)
|
||||||
{
|
{
|
||||||
if (textures.Count == 0 && !DynamicLoading) { return; }
|
if (textures.Count == 0 && !DynamicLoading) { return; }
|
||||||
|
text = ApplyUpperCase(text, forceUpperCase);
|
||||||
if (DynamicLoading)
|
if (DynamicLoading)
|
||||||
{
|
{
|
||||||
DynamicRenderAtlas(graphicsDevice, text);
|
DynamicRenderAtlas(graphicsDevice, text);
|
||||||
@@ -478,21 +531,48 @@ namespace Barotrauma
|
|||||||
GlyphData gd = GetGlyphData(charIndex);
|
GlyphData gd = GetGlyphData(charIndex);
|
||||||
if (gd.TexIndex >= 0)
|
if (gd.TexIndex >= 0)
|
||||||
{
|
{
|
||||||
|
float halfCharHeight = gd.TexCoords.Height * 0.5f;
|
||||||
|
float slantStrength = 0.35f;
|
||||||
|
float topItalicOffset = italics ? ((halfCharHeight - gd.DrawOffset.Y) * slantStrength) + baseHeight * 0.18f : 0.0f;
|
||||||
|
float bottomItalicOffset = italics ? ((-halfCharHeight - gd.DrawOffset.Y) * slantStrength) + baseHeight * 0.18f : 0.0f;
|
||||||
|
|
||||||
Texture2D tex = textures[gd.TexIndex];
|
Texture2D tex = textures[gd.TexIndex];
|
||||||
sb.Draw(tex, currentPos + gd.DrawOffset, gd.TexCoords, color);
|
quadVertices[0].Position = new Vector3(currentPos + gd.DrawOffset + (bottomItalicOffset, gd.TexCoords.Height), 0.0f);
|
||||||
|
quadVertices[0].TextureCoordinate = ((float)gd.TexCoords.Left / tex.Width, (float)gd.TexCoords.Bottom / tex.Height);
|
||||||
|
quadVertices[0].Color = color;
|
||||||
|
|
||||||
|
quadVertices[1].Position = new Vector3(currentPos + gd.DrawOffset + (topItalicOffset, 0.0f), 0.0f);
|
||||||
|
quadVertices[1].TextureCoordinate = ((float)gd.TexCoords.Left / tex.Width, (float)gd.TexCoords.Top / tex.Height);
|
||||||
|
quadVertices[1].Color = color;
|
||||||
|
|
||||||
|
quadVertices[2].Position = new Vector3(currentPos + gd.DrawOffset + (gd.TexCoords.Width + bottomItalicOffset, gd.TexCoords.Height), 0.0f);
|
||||||
|
quadVertices[2].TextureCoordinate = ((float)gd.TexCoords.Right / tex.Width, (float)gd.TexCoords.Bottom / tex.Height);
|
||||||
|
quadVertices[2].Color = color;
|
||||||
|
|
||||||
|
quadVertices[3].Position = new Vector3(currentPos + gd.DrawOffset + (gd.TexCoords.Width + topItalicOffset, 0.0f), 0.0f);
|
||||||
|
quadVertices[3].TextureCoordinate = ((float)gd.TexCoords.Right / tex.Width, (float)gd.TexCoords.Top / tex.Height);
|
||||||
|
quadVertices[3].Color = color;
|
||||||
|
|
||||||
|
sb.Draw(tex, quadVertices, 0.0f);
|
||||||
}
|
}
|
||||||
currentPos.X += gd.Advance;
|
currentPos.X += gd.Advance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawStringWithColors(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects se, float layerDepth, List<RichTextData> richTextData, int rtdOffset = 0)
|
public void DrawStringWithColors(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects se, float layerDepth, in ImmutableArray<RichTextData>? richTextData, int rtdOffset = 0, Alignment alignment = Alignment.TopLeft, ForceUpperCase forceUpperCase = Barotrauma.ForceUpperCase.Inherit)
|
||||||
{
|
{
|
||||||
DrawStringWithColors(sb, text, position, color, rotation, origin, new Vector2(scale), se, layerDepth, richTextData, rtdOffset);
|
DrawStringWithColors(sb, text, position, color, rotation, origin, new Vector2(scale), se, layerDepth, richTextData, rtdOffset, alignment, forceUpperCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawStringWithColors(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects se, float layerDepth, List<RichTextData> richTextData, int rtdOffset = 0)
|
public void DrawStringWithColors(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects se, float layerDepth, in ImmutableArray<RichTextData>? richTextData, int rtdOffset = 0, Alignment alignment = Alignment.TopLeft, ForceUpperCase forceUpperCase = Barotrauma.ForceUpperCase.Inherit)
|
||||||
{
|
{
|
||||||
if (textures.Count == 0 && !DynamicLoading) { return; }
|
if (textures.Count == 0 && !DynamicLoading) { return; }
|
||||||
|
if (!richTextData.HasValue || richTextData.Value.Length <= 0) { DrawString(sb, text, position, color, rotation, origin, scale, se, layerDepth, forceUpperCase: forceUpperCase); return; }
|
||||||
|
|
||||||
|
text = ApplyUpperCase(text, forceUpperCase);
|
||||||
|
|
||||||
|
float lineWidth = -1.0f;
|
||||||
|
Vector2 currentLineOffset = Vector2.Zero;
|
||||||
if (DynamicLoading)
|
if (DynamicLoading)
|
||||||
{
|
{
|
||||||
DynamicRenderAtlas(graphicsDevice, text);
|
DynamicRenderAtlas(graphicsDevice, text);
|
||||||
@@ -503,27 +583,21 @@ namespace Barotrauma
|
|||||||
Vector2 advanceUnit = rotation == 0.0f ? Vector2.UnitX : new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation));
|
Vector2 advanceUnit = rotation == 0.0f ? Vector2.UnitX : new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation));
|
||||||
|
|
||||||
int richTextDataIndex = 0;
|
int richTextDataIndex = 0;
|
||||||
RichTextData currentRichTextData = richTextData[richTextDataIndex];
|
RichTextData currentRichTextData = richTextData.Value[richTextDataIndex];
|
||||||
|
|
||||||
for (int i = 0; i < text.Length; i++)
|
for (int i = 0; i < text.Length; i++)
|
||||||
{
|
{
|
||||||
if (text[i] == '\n')
|
HandleNewLineAndAlignment(text, advanceUnit, position, scale, alignment, i,
|
||||||
{
|
ref lineWidth, ref currentLineOffset, ref lineNum, ref currentPos,
|
||||||
lineNum++;
|
out uint charIndex, out bool shouldContinue);
|
||||||
currentPos = position;
|
if (shouldContinue) { continue; }
|
||||||
currentPos.X -= LineHeight * lineNum * advanceUnit.Y * scale.Y;
|
|
||||||
currentPos.Y += LineHeight * lineNum * advanceUnit.X * scale.Y;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint charIndex = text[i];
|
|
||||||
|
|
||||||
Color currentTextColor;
|
Color currentTextColor;
|
||||||
|
|
||||||
while (currentRichTextData != null && i + rtdOffset > currentRichTextData.EndIndex + lineNum)
|
while (currentRichTextData != null && i + rtdOffset > currentRichTextData.EndIndex + lineNum)
|
||||||
{
|
{
|
||||||
richTextDataIndex++;
|
richTextDataIndex++;
|
||||||
currentRichTextData = richTextDataIndex < richTextData.Count ? richTextData[richTextDataIndex] : null;
|
currentRichTextData = richTextDataIndex < richTextData.Value.Length ? richTextData.Value[richTextDataIndex] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentRichTextData != null && currentRichTextData.StartIndex + lineNum <= i + rtdOffset && i + rtdOffset <= currentRichTextData.EndIndex + lineNum)
|
if (currentRichTextData != null && currentRichTextData.StartIndex + lineNum <= i + rtdOffset && i + rtdOffset <= currentRichTextData.EndIndex + lineNum)
|
||||||
@@ -547,7 +621,7 @@ namespace Barotrauma
|
|||||||
drawOffset.X = gd.DrawOffset.X * advanceUnit.X * scale.X - gd.DrawOffset.Y * advanceUnit.Y * scale.Y;
|
drawOffset.X = gd.DrawOffset.X * advanceUnit.X * scale.X - gd.DrawOffset.Y * advanceUnit.Y * scale.Y;
|
||||||
drawOffset.Y = gd.DrawOffset.X * advanceUnit.Y * scale.Y + gd.DrawOffset.Y * advanceUnit.X * scale.X;
|
drawOffset.Y = gd.DrawOffset.X * advanceUnit.Y * scale.Y + gd.DrawOffset.Y * advanceUnit.X * scale.X;
|
||||||
|
|
||||||
sb.Draw(tex, currentPos + drawOffset, gd.TexCoords, currentTextColor, rotation, origin, scale, se, layerDepth);
|
sb.Draw(tex, currentPos + currentLineOffset + drawOffset, gd.TexCoords, currentTextColor, rotation, origin, scale, se, layerDepth);
|
||||||
}
|
}
|
||||||
currentPos += gd.Advance * advanceUnit * scale.X;
|
currentPos += gd.Advance * advanceUnit * scale.X;
|
||||||
}
|
}
|
||||||
@@ -628,6 +702,8 @@ namespace Barotrauma
|
|||||||
//A breaker (whitespace or CJK) was found earlier
|
//A breaker (whitespace or CJK) was found earlier
|
||||||
//in this line, so let's break the line there
|
//in this line, so let's break the line there
|
||||||
i = lastBreakerIndex.Value + 1;
|
i = lastBreakerIndex.Value + 1;
|
||||||
|
gd = GetGlyphData(text[i]);
|
||||||
|
advance = gd.Advance;
|
||||||
}
|
}
|
||||||
|
|
||||||
nextLine();
|
nextLine();
|
||||||
@@ -649,6 +725,11 @@ namespace Barotrauma
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vector2 MeasureString(LocalizedString str, bool removeExtraSpacing = false)
|
||||||
|
{
|
||||||
|
return MeasureString(str.Value, removeExtraSpacing);
|
||||||
|
}
|
||||||
|
|
||||||
public Vector2 MeasureString(string text, bool removeExtraSpacing = false)
|
public Vector2 MeasureString(string text, bool removeExtraSpacing = false)
|
||||||
{
|
{
|
||||||
if (text == null)
|
if (text == null)
|
||||||
|
|||||||
@@ -25,12 +25,14 @@ namespace Barotrauma
|
|||||||
get { return _toggleOpen; }
|
get { return _toggleOpen; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_toggleOpen = GameMain.Config.ChatOpen = value;
|
_toggleOpen = PreferChatBoxOpen = value;
|
||||||
if (value) hideableElements.Visible = true;
|
if (value) { hideableElements.Visible = true; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private float openState;
|
private float openState;
|
||||||
|
|
||||||
|
public static bool PreferChatBoxOpen = true;
|
||||||
|
|
||||||
public bool CloseAfterMessageSent;
|
public bool CloseAfterMessageSent;
|
||||||
|
|
||||||
private float prevUIScale;
|
private float prevUIScale;
|
||||||
@@ -99,6 +101,7 @@ namespace Barotrauma
|
|||||||
var channelSettingsContent = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.9f), channelSettingsFrame.RectTransform, Anchor.Center), isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
var channelSettingsContent = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.9f), channelSettingsFrame.RectTransform, Anchor.Center), isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
||||||
{
|
{
|
||||||
Stretch = true,
|
Stretch = true,
|
||||||
|
CanBeFocused = true,
|
||||||
RelativeSpacing = 0.01f
|
RelativeSpacing = 0.01f
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -119,9 +122,9 @@ namespace Barotrauma
|
|||||||
Color = new Color(51, 59, 46),
|
Color = new Color(51, 59, 46),
|
||||||
SpriteEffects = Microsoft.Xna.Framework.Graphics.SpriteEffects.FlipHorizontally
|
SpriteEffects = Microsoft.Xna.Framework.Graphics.SpriteEffects.FlipHorizontally
|
||||||
};
|
};
|
||||||
arrowIcon.HoverColor = arrowIcon.PressedColor = arrowIcon.PressedColor = arrowIcon.Color;
|
arrowIcon.HoverColor = arrowIcon.PressedColor = arrowIcon.SelectedColor = arrowIcon.Color;
|
||||||
|
|
||||||
channelText = new GUITextBox(new RectTransform(new Vector2(0.25f, 0.8f), channelSettingsContent.RectTransform), style: "DigitalFrameLight", textAlignment: Alignment.Center, font: GUI.DigitalFont)
|
channelText = new GUITextBox(new RectTransform(new Vector2(0.25f, 0.8f), channelSettingsContent.RectTransform), style: "DigitalFrameLight", textAlignment: Alignment.Center, font: GUIStyle.DigitalFont)
|
||||||
{
|
{
|
||||||
textFilterFunction = text =>
|
textFilterFunction = text =>
|
||||||
{
|
{
|
||||||
@@ -173,7 +176,7 @@ namespace Barotrauma
|
|||||||
new GUIButton(new RectTransform(new Vector2(0.1f, 1.0f), channelPickerContent.RectTransform), i.ToString(), style: "GUITextBlock")
|
new GUIButton(new RectTransform(new Vector2(0.1f, 1.0f), channelPickerContent.RectTransform), i.ToString(), style: "GUITextBlock")
|
||||||
{
|
{
|
||||||
TextColor = new Color(51, 59, 46),
|
TextColor = new Color(51, 59, 46),
|
||||||
SelectedTextColor = GUI.Style.Green,
|
SelectedTextColor = GUIStyle.Green,
|
||||||
UserData = i,
|
UserData = i,
|
||||||
OnClicked = (btn, userdata) =>
|
OnClicked = (btn, userdata) =>
|
||||||
{
|
{
|
||||||
@@ -185,13 +188,13 @@ namespace Barotrauma
|
|||||||
int.TryParse(channelText.Text, out int newChannel);
|
int.TryParse(channelText.Text, out int newChannel);
|
||||||
radio.SetChannelMemory(index, newChannel);
|
radio.SetChannelMemory(index, newChannel);
|
||||||
btn.ToolTip = TextManager.GetWithVariables("radiochannelpreset",
|
btn.ToolTip = TextManager.GetWithVariables("radiochannelpreset",
|
||||||
new string[] { "[index]", "[channel]" },
|
("[index]", index.ToString()),
|
||||||
new string[] { index.ToString(), radio.GetChannelMemory(index).ToString() });
|
("[channel]", radio.GetChannelMemory(index).ToString()));
|
||||||
channelMemPending = false;
|
channelMemPending = false;
|
||||||
channelPickerContent.Children.First().CanBeFocused = true;
|
channelPickerContent.Children.First().CanBeFocused = true;
|
||||||
memButton.Enabled = true;
|
memButton.Enabled = true;
|
||||||
channelPickerContent.Flash(GUI.Style.Green);
|
channelPickerContent.Flash(GUIStyle.Green);
|
||||||
channelText.Flash(GUI.Style.Green);
|
channelText.Flash(GUIStyle.Green);
|
||||||
}
|
}
|
||||||
SetChannel(radio.GetChannelMemory(index), setText: true);
|
SetChannel(radio.GetChannelMemory(index), setText: true);
|
||||||
SoundPlayer.PlayUISound(GUISoundType.PopupMenu);
|
SoundPlayer.PlayUISound(GUISoundType.PopupMenu);
|
||||||
@@ -224,7 +227,7 @@ namespace Barotrauma
|
|||||||
style: "ChatTextBox")
|
style: "ChatTextBox")
|
||||||
{
|
{
|
||||||
OverflowClip = true,
|
OverflowClip = true,
|
||||||
Font = GUI.SmallFont,
|
Font = GUIStyle.SmallFont,
|
||||||
MaxTextLength = ChatMessage.MaxLength
|
MaxTextLength = ChatMessage.MaxLength
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -265,7 +268,7 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
|
|
||||||
showNewMessagesButton.Visible = false;
|
showNewMessagesButton.Visible = false;
|
||||||
ToggleOpen = GameMain.Config.ChatOpen;
|
ToggleOpen = PreferChatBoxOpen = GameSettings.CurrentConfig.ChatOpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TypingChatMessage(GUITextBox textBox, string text)
|
public bool TypingChatMessage(GUITextBox textBox, string text)
|
||||||
@@ -337,7 +340,7 @@ namespace Barotrauma
|
|||||||
color: ((chatBox.Content.CountChildren % 2) == 0) ? Color.Transparent : Color.Black * 0.1f);
|
color: ((chatBox.Content.CountChildren % 2) == 0) ? Color.Transparent : Color.Black * 0.1f);
|
||||||
|
|
||||||
GUITextBlock senderNameTimestamp = new GUITextBlock(new RectTransform(new Vector2(0.98f, 0.0f), msgHolder.RectTransform) { AbsoluteOffset = new Point((int)(5 * GUI.Scale), 0) },
|
GUITextBlock senderNameTimestamp = new GUITextBlock(new RectTransform(new Vector2(0.98f, 0.0f), msgHolder.RectTransform) { AbsoluteOffset = new Point((int)(5 * GUI.Scale), 0) },
|
||||||
ChatMessage.GetTimeStamp(), textColor: Color.LightGray, font: GUI.SmallFont, textAlignment: Alignment.TopLeft, style: null)
|
ChatMessage.GetTimeStamp(), textColor: Color.LightGray, font: GUIStyle.SmallFont, textAlignment: Alignment.TopLeft, style: null)
|
||||||
{
|
{
|
||||||
CanBeFocused = true
|
CanBeFocused = true
|
||||||
};
|
};
|
||||||
@@ -350,9 +353,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Padding = Vector4.Zero
|
Padding = Vector4.Zero
|
||||||
},
|
},
|
||||||
Font = GUI.SmallFont,
|
Font = GUIStyle.SmallFont,
|
||||||
CanBeFocused = true,
|
CanBeFocused = true,
|
||||||
ForceUpperCase = false,
|
ForceUpperCase = ForceUpperCase.No,
|
||||||
UserData = message.SenderClient,
|
UserData = message.SenderClient,
|
||||||
OnClicked = (_, o) =>
|
OnClicked = (_, o) =>
|
||||||
{
|
{
|
||||||
@@ -379,8 +382,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
var msgText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), msgHolder.RectTransform)
|
var msgText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), msgHolder.RectTransform)
|
||||||
{ AbsoluteOffset = new Point((int)(10 * GUI.Scale), senderNameTimestamp == null ? 0 : senderNameTimestamp.Rect.Height) },
|
{ AbsoluteOffset = new Point((int)(10 * GUI.Scale), senderNameTimestamp == null ? 0 : senderNameTimestamp.Rect.Height) },
|
||||||
displayedText, textColor: message.Color, font: GUI.SmallFont, textAlignment: Alignment.TopLeft, style: null, wrap: true,
|
RichString.Rich(displayedText), textColor: message.Color, font: GUIStyle.SmallFont, textAlignment: Alignment.TopLeft, style: null, wrap: true,
|
||||||
color: ((chatBox.Content.CountChildren % 2) == 0) ? Color.Transparent : Color.Black * 0.1f, parseRichText: true)
|
color: ((chatBox.Content.CountChildren % 2) == 0) ? Color.Transparent : Color.Black * 0.1f)
|
||||||
{
|
{
|
||||||
UserData = message.SenderName,
|
UserData = message.SenderName,
|
||||||
CanBeFocused = false
|
CanBeFocused = false
|
||||||
@@ -454,7 +457,7 @@ namespace Barotrauma
|
|||||||
if (!string.IsNullOrEmpty(senderName))
|
if (!string.IsNullOrEmpty(senderName))
|
||||||
{
|
{
|
||||||
var senderText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), content.RectTransform),
|
var senderText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), content.RectTransform),
|
||||||
senderName, textColor: senderColor, style: null, font: GUI.SmallFont)
|
senderName, textColor: senderColor, style: null, font: GUIStyle.SmallFont)
|
||||||
{
|
{
|
||||||
CanBeFocused = false
|
CanBeFocused = false
|
||||||
};
|
};
|
||||||
@@ -462,7 +465,7 @@ namespace Barotrauma
|
|||||||
senderText.RectTransform.MinSize = new Point(0, senderText.Rect.Height);
|
senderText.RectTransform.MinSize = new Point(0, senderText.Rect.Height);
|
||||||
}
|
}
|
||||||
var msgPopupText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), content.RectTransform),
|
var msgPopupText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), content.RectTransform),
|
||||||
displayedText, textColor: message.Color, font: GUI.SmallFont, textAlignment: Alignment.BottomLeft, style: null, wrap: true, parseRichText: true)
|
RichString.Rich(displayedText), textColor: message.Color, font: GUIStyle.SmallFont, textAlignment: Alignment.BottomLeft, style: null, wrap: true)
|
||||||
{
|
{
|
||||||
CanBeFocused = false
|
CanBeFocused = false
|
||||||
};
|
};
|
||||||
@@ -553,8 +556,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
int index = (int)presetButton.UserData;
|
int index = (int)presetButton.UserData;
|
||||||
presetButton.ToolTip = TextManager.GetWithVariables("radiochannelpreset",
|
presetButton.ToolTip = TextManager.GetWithVariables("radiochannelpreset",
|
||||||
new string[] { "[index]", "[channel]" },
|
("[index]", index.ToString()),
|
||||||
new string[] { index.ToString(), radio.GetChannelMemory(index).ToString() });
|
("[channel]", radio.GetChannelMemory(index).ToString()));
|
||||||
}
|
}
|
||||||
SetChannel(radio.Channel, setText: true);
|
SetChannel(radio.Channel, setText: true);
|
||||||
prevRadio = radio;
|
prevRadio = radio;
|
||||||
@@ -563,7 +566,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (channelPickerContent.FlashTimer <= 0)
|
if (channelPickerContent.FlashTimer <= 0)
|
||||||
{
|
{
|
||||||
channelPickerContent.Flash(GUI.Style.Green, flashRectInflate: new Vector2(GUI.Scale * 5.0f));
|
channelPickerContent.Flash(GUIStyle.Green, flashRectInflate: new Vector2(GUI.Scale * 5.0f));
|
||||||
}
|
}
|
||||||
if (PlayerInput.PrimaryMouseButtonClicked() && !GUI.IsMouseOn(channelPickerContent))
|
if (PlayerInput.PrimaryMouseButtonClicked() && !GUI.IsMouseOn(channelPickerContent))
|
||||||
{
|
{
|
||||||
@@ -671,7 +674,7 @@ namespace Barotrauma
|
|||||||
if (Character.Controlled != null && ChatMessage.CanUseRadio(Character.Controlled, out WifiComponent radio))
|
if (Character.Controlled != null && ChatMessage.CanUseRadio(Character.Controlled, out WifiComponent radio))
|
||||||
{
|
{
|
||||||
radio.Channel = channel;
|
radio.Channel = channel;
|
||||||
GameMain.Client?.CreateEntityEvent(radio.Item, new object[] { NetEntityEvent.Type.ChangeProperty, radio.SerializableProperties["channel"] });
|
GameMain.Client?.CreateEntityEvent(radio.Item, new Item.ChangePropertyEventData(radio.SerializableProperties["channel".ToIdentifier()]));
|
||||||
|
|
||||||
if (setText)
|
if (setText)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
using Barotrauma.Extensions;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -16,7 +17,7 @@ namespace Barotrauma
|
|||||||
Toggle
|
Toggle
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GUIComponentStyle
|
public class GUIComponentStyle : GUIPrefab
|
||||||
{
|
{
|
||||||
public readonly Vector4 Padding;
|
public readonly Vector4 Padding;
|
||||||
|
|
||||||
@@ -35,31 +36,53 @@ namespace Barotrauma
|
|||||||
public readonly float ColorCrossFadeTime;
|
public readonly float ColorCrossFadeTime;
|
||||||
public readonly TransitionMode TransitionMode;
|
public readonly TransitionMode TransitionMode;
|
||||||
|
|
||||||
public readonly string Font;
|
public readonly Identifier Font;
|
||||||
public readonly bool ForceUpperCase;
|
public readonly bool ForceUpperCase;
|
||||||
|
|
||||||
public readonly Color OutlineColor;
|
public readonly Color OutlineColor;
|
||||||
|
|
||||||
public readonly XElement Element;
|
public readonly ContentXElement Element;
|
||||||
|
|
||||||
public readonly Dictionary<GUIComponent.ComponentState, List<UISprite>> Sprites;
|
public readonly Dictionary<GUIComponent.ComponentState, List<UISprite>> Sprites;
|
||||||
|
|
||||||
public SpriteFallBackState FallBackState;
|
public SpriteFallBackState FallBackState;
|
||||||
|
|
||||||
public Dictionary<string, GUIComponentStyle> ChildStyles;
|
public readonly GUIComponentStyle ParentStyle;
|
||||||
|
public readonly Dictionary<Identifier, GUIComponentStyle> ChildStyles;
|
||||||
|
|
||||||
public readonly GUIStyle Style;
|
public static GUIComponentStyle FromHierarchy(IReadOnlyList<Identifier> hierarchy)
|
||||||
|
{
|
||||||
|
if (hierarchy is null || hierarchy.None()) { return null; }
|
||||||
|
GUIStyle.ComponentStyles.TryGet(hierarchy[0], out GUIComponentStyle style);
|
||||||
|
for (int i = 1; i < hierarchy.Count; i++)
|
||||||
|
{
|
||||||
|
if (style is null) { return null; }
|
||||||
|
style.ChildStyles.TryGetValue(hierarchy[i], out style);
|
||||||
|
}
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Identifier[] ToHierarchy(GUIComponentStyle style)
|
||||||
|
{
|
||||||
|
List<Identifier> ids = new List<Identifier>();
|
||||||
|
while (style != null)
|
||||||
|
{
|
||||||
|
ids.Insert(0, style.Identifier);
|
||||||
|
style = style.ParentStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ids.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
public readonly string Name;
|
public readonly string Name;
|
||||||
|
|
||||||
public int? Width { get; private set; }
|
public int? Width { get; private set; }
|
||||||
public int? Height { get; private set; }
|
public int? Height { get; private set; }
|
||||||
|
|
||||||
public GUIComponentStyle(XElement element, GUIStyle style)
|
public GUIComponentStyle(ContentXElement element, UIStyleFile file, GUIComponentStyle parent = null) : base(element, file)
|
||||||
{
|
{
|
||||||
Name = element.Name.LocalName;
|
Name = element.Name.LocalName;
|
||||||
|
|
||||||
Style = style;
|
|
||||||
Element = element;
|
Element = element;
|
||||||
|
|
||||||
Sprites = new Dictionary<GUIComponent.ComponentState, List<UISprite>>();
|
Sprites = new Dictionary<GUIComponent.ComponentState, List<UISprite>>();
|
||||||
@@ -68,7 +91,8 @@ namespace Barotrauma
|
|||||||
Sprites[state] = new List<UISprite>();
|
Sprites[state] = new List<UISprite>();
|
||||||
}
|
}
|
||||||
|
|
||||||
ChildStyles = new Dictionary<string, GUIComponentStyle>();
|
ParentStyle = parent;
|
||||||
|
ChildStyles = new Dictionary<Identifier, GUIComponentStyle>();
|
||||||
|
|
||||||
Padding = element.GetAttributeVector4("padding", Vector4.Zero);
|
Padding = element.GetAttributeVector4("padding", Vector4.Zero);
|
||||||
|
|
||||||
@@ -95,10 +119,10 @@ namespace Barotrauma
|
|||||||
FallBackState = s;
|
FallBackState = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
Font = element.GetAttributeString("font", "");
|
Font = element.GetAttributeIdentifier("font", "");
|
||||||
ForceUpperCase = element.GetAttributeBool("forceuppercase", false);
|
ForceUpperCase = element.GetAttributeBool("forceuppercase", false);
|
||||||
|
|
||||||
foreach (XElement subElement in element.Elements())
|
foreach (var subElement in element.Elements())
|
||||||
{
|
{
|
||||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||||
{
|
{
|
||||||
@@ -106,7 +130,7 @@ namespace Barotrauma
|
|||||||
UISprite newSprite = new UISprite(subElement);
|
UISprite newSprite = new UISprite(subElement);
|
||||||
|
|
||||||
GUIComponent.ComponentState spriteState = GUIComponent.ComponentState.None;
|
GUIComponent.ComponentState spriteState = GUIComponent.ComponentState.None;
|
||||||
if (subElement.Attribute("state") != null)
|
if (subElement.GetAttribute("state") != null)
|
||||||
{
|
{
|
||||||
string stateStr = subElement.GetAttributeString("state", "None");
|
string stateStr = subElement.GetAttributeString("state", "None");
|
||||||
Enum.TryParse(stateStr, out spriteState);
|
Enum.TryParse(stateStr, out spriteState);
|
||||||
@@ -128,15 +152,15 @@ namespace Barotrauma
|
|||||||
case "size":
|
case "size":
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
string styleName = subElement.Name.ToString().ToLowerInvariant();
|
Identifier styleName = subElement.NameAsIdentifier();
|
||||||
if (ChildStyles.ContainsKey(styleName))
|
if (ChildStyles.ContainsKey(styleName))
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("UI style \"" + element.Name.ToString() + "\" contains multiple child styles with the same name (\"" + styleName + "\")!");
|
DebugConsole.ThrowError("UI style \"" + element.Name.ToString() + "\" contains multiple child styles with the same name (\"" + styleName + "\")!");
|
||||||
ChildStyles[styleName] = new GUIComponentStyle(subElement, style);
|
ChildStyles[styleName] = new GUIComponentStyle(subElement, file, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ChildStyles.Add(styleName, new GUIComponentStyle(subElement, style));
|
ChildStyles.Add(styleName, new GUIComponentStyle(subElement, file, this));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -157,7 +181,7 @@ namespace Barotrauma
|
|||||||
public void GetSize(XElement element)
|
public void GetSize(XElement element)
|
||||||
{
|
{
|
||||||
Point size = new Point(0, 0);
|
Point size = new Point(0, 0);
|
||||||
foreach (XElement subElement in element.Elements())
|
foreach (var subElement in element.Elements())
|
||||||
{
|
{
|
||||||
if (!subElement.Name.ToString().Equals("size", StringComparison.OrdinalIgnoreCase)) { continue; }
|
if (!subElement.Name.ToString().Equals("size", StringComparison.OrdinalIgnoreCase)) { continue; }
|
||||||
Point maxResolution = subElement.GetAttributePoint("maxresolution", new Point(int.MaxValue, int.MaxValue));
|
Point maxResolution = subElement.GetAttributePoint("maxresolution", new Point(int.MaxValue, int.MaxValue));
|
||||||
@@ -172,5 +196,7 @@ namespace Barotrauma
|
|||||||
if (size.X > 0) { Width = size.X; }
|
if (size.X > 0) { Width = size.X; }
|
||||||
if (size.Y > 0) { Height = size.Y; }
|
if (size.Y > 0) { Height = size.Y; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Dispose() { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace Barotrauma
|
|||||||
private GUIButton clearAllButton;
|
private GUIButton clearAllButton;
|
||||||
|
|
||||||
private List<CharacterInfo> PendingHires => campaign.Map?.CurrentLocation?.HireManager?.PendingHires;
|
private List<CharacterInfo> PendingHires => campaign.Map?.CurrentLocation?.HireManager?.PendingHires;
|
||||||
private bool HasPermission => campaignUI.Campaign.AllowedToManageCampaign();
|
private bool HasPermission => campaignUI.Campaign.AllowedToManageCampaign(ClientPermissions.ManageHires);
|
||||||
|
|
||||||
private Point resolutionWhenCreated;
|
private Point resolutionWhenCreated;
|
||||||
|
|
||||||
@@ -108,10 +108,10 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
var imageWidth = (float)headerGroup.Rect.Height / headerGroup.Rect.Width;
|
var imageWidth = (float)headerGroup.Rect.Height / headerGroup.Rect.Width;
|
||||||
new GUIImage(new RectTransform(new Vector2(imageWidth, 1.0f), headerGroup.RectTransform), "CrewManagementHeaderIcon");
|
new GUIImage(new RectTransform(new Vector2(imageWidth, 1.0f), headerGroup.RectTransform), "CrewManagementHeaderIcon");
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f - imageWidth, 1.0f), headerGroup.RectTransform), TextManager.Get("campaigncrew.header"), font: GUI.LargeFont)
|
new GUITextBlock(new RectTransform(new Vector2(1.0f - imageWidth, 1.0f), headerGroup.RectTransform), TextManager.Get("campaigncrew.header"), font: GUIStyle.LargeFont)
|
||||||
{
|
{
|
||||||
CanBeFocused = false,
|
CanBeFocused = false,
|
||||||
ForceUpperCase = true
|
ForceUpperCase = ForceUpperCase.Yes
|
||||||
};
|
};
|
||||||
|
|
||||||
var hireablesGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.95f), anchor: Anchor.Center,
|
var hireablesGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.95f), anchor: Anchor.Center,
|
||||||
@@ -162,17 +162,17 @@ namespace Barotrauma
|
|||||||
RelativeSpacing = 0.005f
|
RelativeSpacing = 0.005f
|
||||||
};
|
};
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), playerBalanceContainer.RectTransform),
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), playerBalanceContainer.RectTransform),
|
||||||
TextManager.Get("campaignstore.balance"), font: GUI.Font, textAlignment: Alignment.BottomRight)
|
TextManager.Get("campaignstore.balance"), font: GUIStyle.Font, textAlignment: Alignment.BottomRight)
|
||||||
{
|
{
|
||||||
AutoScaleVertical = true,
|
AutoScaleVertical = true,
|
||||||
ForceUpperCase = true
|
ForceUpperCase = ForceUpperCase.Yes
|
||||||
};
|
};
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), playerBalanceContainer.RectTransform),
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), playerBalanceContainer.RectTransform),
|
||||||
"", font: GUI.SubHeadingFont, textAlignment: Alignment.TopRight)
|
"", font: GUIStyle.SubHeadingFont, textAlignment: Alignment.TopRight)
|
||||||
{
|
{
|
||||||
AutoScaleVertical = true,
|
AutoScaleVertical = true,
|
||||||
TextScale = 1.1f,
|
TextScale = 1.1f,
|
||||||
TextGetter = () => FormatCurrency(campaign.Money)
|
TextGetter = () => TextManager.FormatCurrency(campaign.Wallet.Balance)
|
||||||
};
|
};
|
||||||
|
|
||||||
var pendingAndCrewGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.95f), anchor: Anchor.Center,
|
var pendingAndCrewGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.95f), anchor: Anchor.Center,
|
||||||
@@ -182,13 +182,13 @@ namespace Barotrauma
|
|||||||
}).RectTransform));
|
}).RectTransform));
|
||||||
|
|
||||||
float height = 0.05f;
|
float height = 0.05f;
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, height), pendingAndCrewGroup.RectTransform), TextManager.Get("campaigncrew.pending"), font: GUI.SubHeadingFont);
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, height), pendingAndCrewGroup.RectTransform), TextManager.Get("campaigncrew.pending"), font: GUIStyle.SubHeadingFont);
|
||||||
pendingList = new GUIListBox(new RectTransform(new Vector2(1.0f, 8 * height), pendingAndCrewGroup.RectTransform))
|
pendingList = new GUIListBox(new RectTransform(new Vector2(1.0f, 8 * height), pendingAndCrewGroup.RectTransform))
|
||||||
{
|
{
|
||||||
Spacing = 1
|
Spacing = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, height), pendingAndCrewGroup.RectTransform), TextManager.Get("campaignmenucrew"), font: GUI.SubHeadingFont);
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, height), pendingAndCrewGroup.RectTransform), TextManager.Get("campaignmenucrew"), font: GUIStyle.SubHeadingFont);
|
||||||
crewList = new GUIListBox(new RectTransform(new Vector2(1.0f, 8 * height), pendingAndCrewGroup.RectTransform))
|
crewList = new GUIListBox(new RectTransform(new Vector2(1.0f, 8 * height), pendingAndCrewGroup.RectTransform))
|
||||||
{
|
{
|
||||||
Spacing = 1
|
Spacing = 1
|
||||||
@@ -196,7 +196,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
var group = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, height), pendingAndCrewGroup.RectTransform), isHorizontal: true);
|
var group = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, height), pendingAndCrewGroup.RectTransform), isHorizontal: true);
|
||||||
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), group.RectTransform), TextManager.Get("campaignstore.total"));
|
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), group.RectTransform), TextManager.Get("campaignstore.total"));
|
||||||
totalBlock = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), group.RectTransform), "", font: GUI.SubHeadingFont, textAlignment: Alignment.Right)
|
totalBlock = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), group.RectTransform), "", font: GUIStyle.SubHeadingFont, textAlignment: Alignment.Right)
|
||||||
{
|
{
|
||||||
TextScale = 1.1f
|
TextScale = 1.1f
|
||||||
};
|
};
|
||||||
@@ -207,12 +207,12 @@ namespace Barotrauma
|
|||||||
validateHiresButton = new GUIButton(new RectTransform(new Vector2(1.0f / 3.0f, 1.0f), group.RectTransform), text: TextManager.Get("campaigncrew.validate"))
|
validateHiresButton = new GUIButton(new RectTransform(new Vector2(1.0f / 3.0f, 1.0f), group.RectTransform), text: TextManager.Get("campaigncrew.validate"))
|
||||||
{
|
{
|
||||||
ClickSound = GUISoundType.HireRepairClick,
|
ClickSound = GUISoundType.HireRepairClick,
|
||||||
ForceUpperCase = true,
|
ForceUpperCase = ForceUpperCase.Yes,
|
||||||
OnClicked = (b, o) => ValidateHires(PendingHires, true)
|
OnClicked = (b, o) => ValidateHires(PendingHires, true)
|
||||||
};
|
};
|
||||||
clearAllButton = new GUIButton(new RectTransform(new Vector2(1.0f / 3.0f, 1.0f), group.RectTransform), text: TextManager.Get("campaignstore.clearall"))
|
clearAllButton = new GUIButton(new RectTransform(new Vector2(1.0f / 3.0f, 1.0f), group.RectTransform), text: TextManager.Get("campaignstore.clearall"))
|
||||||
{
|
{
|
||||||
ForceUpperCase = true,
|
ForceUpperCase = ForceUpperCase.Yes,
|
||||||
Enabled = HasPermission,
|
Enabled = HasPermission,
|
||||||
OnClicked = (b, o) => RemoveAllPendingHires()
|
OnClicked = (b, o) => RemoveAllPendingHires()
|
||||||
};
|
};
|
||||||
@@ -302,30 +302,42 @@ namespace Barotrauma
|
|||||||
if (sortingMethod == SortingMethod.AlphabeticalAsc)
|
if (sortingMethod == SortingMethod.AlphabeticalAsc)
|
||||||
{
|
{
|
||||||
list.Content.RectTransform.SortChildren((x, y) =>
|
list.Content.RectTransform.SortChildren((x, y) =>
|
||||||
(x.GUIComponent.UserData as Tuple<CharacterInfo, float>).Item1.Name.CompareTo((y.GUIComponent.UserData as Tuple<CharacterInfo, float>).Item1.Name));
|
((InfoSkill)x.GUIComponent.UserData).CharacterInfo.Name.CompareTo(((InfoSkill)y.GUIComponent.UserData).CharacterInfo.Name));
|
||||||
}
|
}
|
||||||
else if (sortingMethod == SortingMethod.JobAsc)
|
else if (sortingMethod == SortingMethod.JobAsc)
|
||||||
{
|
{
|
||||||
SortCharacters(list, SortingMethod.AlphabeticalAsc);
|
SortCharacters(list, SortingMethod.AlphabeticalAsc);
|
||||||
list.Content.RectTransform.SortChildren((x, y) =>
|
list.Content.RectTransform.SortChildren((x, y) =>
|
||||||
String.Compare((x.GUIComponent.UserData as Tuple<CharacterInfo, float>)?.Item1.Job.Name, (y.GUIComponent.UserData as Tuple<CharacterInfo, float>).Item1.Job.Name, StringComparison.Ordinal));
|
String.Compare(((InfoSkill)x.GUIComponent.UserData).CharacterInfo.Job.Name.Value, ((InfoSkill)y.GUIComponent.UserData).CharacterInfo.Job.Name.Value, StringComparison.Ordinal));
|
||||||
}
|
}
|
||||||
else if (sortingMethod == SortingMethod.PriceAsc || sortingMethod == SortingMethod.PriceDesc)
|
else if (sortingMethod == SortingMethod.PriceAsc || sortingMethod == SortingMethod.PriceDesc)
|
||||||
{
|
{
|
||||||
SortCharacters(list, SortingMethod.AlphabeticalAsc);
|
SortCharacters(list, SortingMethod.AlphabeticalAsc);
|
||||||
list.Content.RectTransform.SortChildren((x, y) =>
|
list.Content.RectTransform.SortChildren((x, y) =>
|
||||||
(x.GUIComponent.UserData as Tuple<CharacterInfo, float>).Item1.Salary.CompareTo((y.GUIComponent.UserData as Tuple<CharacterInfo, float>).Item1.Salary));
|
((InfoSkill)x.GUIComponent.UserData).CharacterInfo.Salary.CompareTo(((InfoSkill)y.GUIComponent.UserData).CharacterInfo.Salary));
|
||||||
if (sortingMethod == SortingMethod.PriceDesc) { list.Content.RectTransform.ReverseChildren(); }
|
if (sortingMethod == SortingMethod.PriceDesc) { list.Content.RectTransform.ReverseChildren(); }
|
||||||
}
|
}
|
||||||
else if (sortingMethod == SortingMethod.SkillAsc || sortingMethod == SortingMethod.SkillDesc)
|
else if (sortingMethod == SortingMethod.SkillAsc || sortingMethod == SortingMethod.SkillDesc)
|
||||||
{
|
{
|
||||||
SortCharacters(list, SortingMethod.AlphabeticalAsc);
|
SortCharacters(list, SortingMethod.AlphabeticalAsc);
|
||||||
list.Content.RectTransform.SortChildren((x, y) =>
|
list.Content.RectTransform.SortChildren((x, y) =>
|
||||||
(x.GUIComponent.UserData as Tuple<CharacterInfo, float>).Item2.CompareTo((y.GUIComponent.UserData as Tuple<CharacterInfo, float>).Item2));
|
((InfoSkill)x.GUIComponent.UserData).SkillLevel.CompareTo(((InfoSkill)y.GUIComponent.UserData).SkillLevel));
|
||||||
if (sortingMethod == SortingMethod.SkillDesc) { list.Content.RectTransform.ReverseChildren(); }
|
if (sortingMethod == SortingMethod.SkillDesc) { list.Content.RectTransform.ReverseChildren(); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readonly struct InfoSkill
|
||||||
|
{
|
||||||
|
public readonly CharacterInfo CharacterInfo;
|
||||||
|
public readonly float SkillLevel;
|
||||||
|
|
||||||
|
public InfoSkill(CharacterInfo characterInfo, float skillLevel)
|
||||||
|
{
|
||||||
|
CharacterInfo = characterInfo;
|
||||||
|
SkillLevel = skillLevel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void CreateCharacterFrame(CharacterInfo characterInfo, GUIListBox listBox)
|
private void CreateCharacterFrame(CharacterInfo characterInfo, GUIListBox listBox)
|
||||||
{
|
{
|
||||||
Skill skill = null;
|
Skill skill = null;
|
||||||
@@ -338,7 +350,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
GUIFrame frame = new GUIFrame(new RectTransform(new Point(listBox.Content.Rect.Width, (int)(GUI.yScale * 55)), parent: listBox.Content.RectTransform), "ListBoxElement")
|
GUIFrame frame = new GUIFrame(new RectTransform(new Point(listBox.Content.Rect.Width, (int)(GUI.yScale * 55)), parent: listBox.Content.RectTransform), "ListBoxElement")
|
||||||
{
|
{
|
||||||
UserData = new Tuple<CharacterInfo, float>(characterInfo, skill?.Level ?? 0.0f)
|
UserData = new InfoSkill(characterInfo, skill?.Level ?? 0.0f)
|
||||||
};
|
};
|
||||||
GUILayoutGroup mainGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), frame.RectTransform, anchor: Anchor.Center), isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
GUILayoutGroup mainGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), frame.RectTransform, anchor: Anchor.Center), isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
||||||
{
|
{
|
||||||
@@ -363,7 +375,7 @@ namespace Barotrauma
|
|||||||
nameBlock.Text = ToolBox.LimitString(nameBlock.Text, nameBlock.Font, nameBlock.Rect.Width);
|
nameBlock.Text = ToolBox.LimitString(nameBlock.Text, nameBlock.Font, nameBlock.Rect.Width);
|
||||||
|
|
||||||
GUITextBlock jobBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), nameAndJobGroup.RectTransform),
|
GUITextBlock jobBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), nameAndJobGroup.RectTransform),
|
||||||
characterInfo.Job.Name, textColor: Color.White, font: GUI.SmallFont, textAlignment: Alignment.TopLeft)
|
characterInfo.Job.Name, textColor: Color.White, font: GUIStyle.SmallFont, textAlignment: Alignment.TopLeft)
|
||||||
{
|
{
|
||||||
CanBeFocused = false
|
CanBeFocused = false
|
||||||
};
|
};
|
||||||
@@ -374,7 +386,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
GUILayoutGroup skillGroup = new GUILayoutGroup(new RectTransform(new Vector2(width, 0.6f), mainGroup.RectTransform), isHorizontal: true);
|
GUILayoutGroup skillGroup = new GUILayoutGroup(new RectTransform(new Vector2(width, 0.6f), mainGroup.RectTransform), isHorizontal: true);
|
||||||
float iconWidth = (float)skillGroup.Rect.Height / skillGroup.Rect.Width;
|
float iconWidth = (float)skillGroup.Rect.Height / skillGroup.Rect.Width;
|
||||||
GUIImage skillIcon = new GUIImage(new RectTransform(new Vector2(iconWidth, 1.0f), skillGroup.RectTransform), skill.Icon)
|
GUIImage skillIcon = new GUIImage(new RectTransform(Vector2.One, skillGroup.RectTransform, scaleBasis: ScaleBasis.Smallest), skill.Icon, scaleToFit: true)
|
||||||
{
|
{
|
||||||
CanBeFocused = false
|
CanBeFocused = false
|
||||||
};
|
};
|
||||||
@@ -388,7 +400,7 @@ namespace Barotrauma
|
|||||||
if (listBox != crewList)
|
if (listBox != crewList)
|
||||||
{
|
{
|
||||||
new GUITextBlock(new RectTransform(new Vector2(width, 1.0f), mainGroup.RectTransform),
|
new GUITextBlock(new RectTransform(new Vector2(width, 1.0f), mainGroup.RectTransform),
|
||||||
FormatCurrency(characterInfo.Salary),
|
TextManager.FormatCurrency(characterInfo.Salary),
|
||||||
textAlignment: Alignment.Center)
|
textAlignment: Alignment.Center)
|
||||||
{
|
{
|
||||||
CanBeFocused = false
|
CanBeFocused = false
|
||||||
@@ -421,7 +433,7 @@ namespace Barotrauma
|
|||||||
else if (!btn.Enabled)
|
else if (!btn.Enabled)
|
||||||
{
|
{
|
||||||
btn.ToolTip = string.Empty;
|
btn.ToolTip = string.Empty;
|
||||||
btn.Enabled = true;
|
btn.Enabled = HasPermission;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -448,7 +460,7 @@ namespace Barotrauma
|
|||||||
var confirmDialog = new GUIMessageBox(
|
var confirmDialog = new GUIMessageBox(
|
||||||
TextManager.Get("FireWarningHeader"),
|
TextManager.Get("FireWarningHeader"),
|
||||||
TextManager.GetWithVariable("FireWarningText", "[charactername]", ((CharacterInfo)obj).Name),
|
TextManager.GetWithVariable("FireWarningText", "[charactername]", ((CharacterInfo)obj).Name),
|
||||||
new string[] { TextManager.Get("Yes"), TextManager.Get("No") });
|
new LocalizedString[] { TextManager.Get("Yes"), TextManager.Get("No") });
|
||||||
confirmDialog.Buttons[0].UserData = (CharacterInfo)obj;
|
confirmDialog.Buttons[0].UserData = (CharacterInfo)obj;
|
||||||
confirmDialog.Buttons[0].OnClicked = FireCharacter;
|
confirmDialog.Buttons[0].OnClicked = FireCharacter;
|
||||||
confirmDialog.Buttons[0].OnClicked += confirmDialog.Close;
|
confirmDialog.Buttons[0].OnClicked += confirmDialog.Close;
|
||||||
@@ -510,10 +522,11 @@ namespace Barotrauma
|
|||||||
string name = listBox == hireableList ? characterInfo.OriginalName : characterInfo.Name;
|
string name = listBox == hireableList ? characterInfo.OriginalName : characterInfo.Name;
|
||||||
nameBlock.Text = ToolBox.LimitString(name, nameBlock.Font, nameBlock.Rect.Width);
|
nameBlock.Text = ToolBox.LimitString(name, nameBlock.Font, nameBlock.Rect.Width);
|
||||||
|
|
||||||
if (characterInfo.HasGenders)
|
if (characterInfo.HasSpecifierTags)
|
||||||
{
|
{
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, blockHeight), infoLabelGroup.RectTransform), TextManager.Get("gender"));
|
var menuCategoryVar = characterInfo.Prefab.MenuCategoryVar;
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, blockHeight), infoValueGroup.RectTransform), TextManager.Get(characterInfo.Gender.ToString()));
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, blockHeight), infoLabelGroup.RectTransform), TextManager.Get(menuCategoryVar));
|
||||||
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, blockHeight), infoValueGroup.RectTransform), TextManager.Get(characterInfo.ReplaceVars($"[{menuCategoryVar}]")));
|
||||||
}
|
}
|
||||||
if (characterInfo.Job is Job job)
|
if (characterInfo.Job is Job job)
|
||||||
{
|
{
|
||||||
@@ -523,7 +536,7 @@ namespace Barotrauma
|
|||||||
if (characterInfo.PersonalityTrait is NPCPersonalityTrait trait)
|
if (characterInfo.PersonalityTrait is NPCPersonalityTrait trait)
|
||||||
{
|
{
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, blockHeight), infoLabelGroup.RectTransform), TextManager.Get("PersonalityTrait"));
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, blockHeight), infoLabelGroup.RectTransform), TextManager.Get("PersonalityTrait"));
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, blockHeight), infoValueGroup.RectTransform), TextManager.Get("personalitytrait." + trait.Name.Replace(" ", "")));
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, blockHeight), infoValueGroup.RectTransform), TextManager.Get("personalitytrait." + trait.Name.Replace(" ".ToIdentifier(), Identifier.Empty)));
|
||||||
}
|
}
|
||||||
infoLabelGroup.Recalculate();
|
infoLabelGroup.Recalculate();
|
||||||
infoValueGroup.Recalculate();
|
infoValueGroup.Recalculate();
|
||||||
@@ -568,7 +581,7 @@ namespace Barotrauma
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
hireableList.Content.RemoveChild(hireableList.Content.FindChild(c => (c.UserData as Tuple<CharacterInfo, float>).Item1 == characterInfo));
|
hireableList.Content.RemoveChild(hireableList.Content.FindChild(c => ((InfoSkill)c.UserData).CharacterInfo == characterInfo));
|
||||||
hireableList.UpdateScrollBarSize();
|
hireableList.UpdateScrollBarSize();
|
||||||
if (!PendingHires.Contains(characterInfo)) { PendingHires.Add(characterInfo); }
|
if (!PendingHires.Contains(characterInfo)) { PendingHires.Add(characterInfo); }
|
||||||
CreateCharacterFrame(characterInfo, pendingList);
|
CreateCharacterFrame(characterInfo, pendingList);
|
||||||
@@ -582,14 +595,14 @@ namespace Barotrauma
|
|||||||
private bool RemovePendingHire(CharacterInfo characterInfo, bool setTotalHireCost = true, bool createNetworkMessage = true)
|
private bool RemovePendingHire(CharacterInfo characterInfo, bool setTotalHireCost = true, bool createNetworkMessage = true)
|
||||||
{
|
{
|
||||||
if (PendingHires.Contains(characterInfo)) { PendingHires.Remove(characterInfo); }
|
if (PendingHires.Contains(characterInfo)) { PendingHires.Remove(characterInfo); }
|
||||||
pendingList.Content.RemoveChild(pendingList.Content.FindChild(c => (c.UserData as Tuple<CharacterInfo, float>).Item1 == characterInfo));
|
pendingList.Content.RemoveChild(pendingList.Content.FindChild(c => ((InfoSkill)c.UserData).CharacterInfo == characterInfo));
|
||||||
pendingList.UpdateScrollBarSize();
|
pendingList.UpdateScrollBarSize();
|
||||||
|
|
||||||
// Server will reset the names to originals in multiplayer
|
// Server will reset the names to originals in multiplayer
|
||||||
if (!GameMain.IsMultiplayer) { characterInfo?.ResetName(); }
|
if (!GameMain.IsMultiplayer) { characterInfo?.ResetName(); }
|
||||||
|
|
||||||
if (campaign.Map.CurrentLocation.HireManager.AvailableCharacters.Any(info => info.GetIdentifierUsingOriginalName() == characterInfo.GetIdentifierUsingOriginalName()) &&
|
if (campaign.Map.CurrentLocation.HireManager.AvailableCharacters.Any(info => info.GetIdentifierUsingOriginalName() == characterInfo.GetIdentifierUsingOriginalName()) &&
|
||||||
hireableList.Content.Children.None(c => c.UserData is Tuple<CharacterInfo, float> userData && userData.Item1.GetIdentifierUsingOriginalName() == characterInfo.GetIdentifierUsingOriginalName()))
|
hireableList.Content.Children.None(c => c.UserData is InfoSkill userData && userData.CharacterInfo.GetIdentifierUsingOriginalName() == characterInfo.GetIdentifierUsingOriginalName()))
|
||||||
{
|
{
|
||||||
CreateCharacterFrame(characterInfo, hireableList);
|
CreateCharacterFrame(characterInfo, hireableList);
|
||||||
SortCharacters(hireableList, (SortingMethod)sortingDropDown.SelectedItemData);
|
SortCharacters(hireableList, (SortingMethod)sortingDropDown.SelectedItemData);
|
||||||
@@ -603,7 +616,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private bool RemoveAllPendingHires(bool createNetworkMessage = true)
|
private bool RemoveAllPendingHires(bool createNetworkMessage = true)
|
||||||
{
|
{
|
||||||
pendingList.Content.Children.ToList().ForEach(c => RemovePendingHire((c.UserData as Tuple<CharacterInfo, float>).Item1, setTotalHireCost: false, createNetworkMessage));
|
pendingList.Content.Children.ToList().ForEach(c => RemovePendingHire(((InfoSkill)c.UserData).CharacterInfo, setTotalHireCost: false, createNetworkMessage));
|
||||||
SetTotalHireCost();
|
SetTotalHireCost();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -614,12 +627,12 @@ namespace Barotrauma
|
|||||||
int total = 0;
|
int total = 0;
|
||||||
pendingList.Content.Children.ForEach(c =>
|
pendingList.Content.Children.ForEach(c =>
|
||||||
{
|
{
|
||||||
total += (c.UserData as Tuple<CharacterInfo, float>).Item1.Salary;
|
total += ((InfoSkill)c.UserData).CharacterInfo.Salary;
|
||||||
});
|
});
|
||||||
totalBlock.Text = FormatCurrency(total);
|
totalBlock.Text = TextManager.FormatCurrency(total);
|
||||||
bool enoughMoney = campaign != null ? total <= campaign.Money : true;
|
bool enoughMoney = campaign == null || campaign.Wallet.CanAfford(total);
|
||||||
totalBlock.TextColor = enoughMoney ? Color.White : Color.Red;
|
totalBlock.TextColor = enoughMoney ? Color.White : Color.Red;
|
||||||
validateHiresButton.Enabled = enoughMoney && pendingList.Content.RectTransform.Children.Any();
|
validateHiresButton.Enabled = enoughMoney && HasPermission && pendingList.Content.RectTransform.Children.Any();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ValidateHires(List<CharacterInfo> hires, bool createNetworkEvent = false)
|
public bool ValidateHires(List<CharacterInfo> hires, bool createNetworkEvent = false)
|
||||||
@@ -639,7 +652,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
int total = nonDuplicateHires.Aggregate(0, (total, info) => total + info.Salary);
|
int total = nonDuplicateHires.Aggregate(0, (total, info) => total + info.Salary);
|
||||||
|
|
||||||
if (total > campaign.Money) { return false; }
|
if (!campaign.Wallet.CanAfford(total)) { return false; }
|
||||||
|
|
||||||
bool atLeastOneHired = false;
|
bool atLeastOneHired = false;
|
||||||
foreach (CharacterInfo ci in nonDuplicateHires)
|
foreach (CharacterInfo ci in nonDuplicateHires)
|
||||||
@@ -661,7 +674,7 @@ namespace Barotrauma
|
|||||||
var dialog = new GUIMessageBox(
|
var dialog = new GUIMessageBox(
|
||||||
TextManager.Get("newcrewmembers"),
|
TextManager.Get("newcrewmembers"),
|
||||||
TextManager.GetWithVariable("crewhiredmessage", "[location]", campaignUI?.Campaign?.Map?.CurrentLocation?.Name),
|
TextManager.GetWithVariable("crewhiredmessage", "[location]", campaignUI?.Campaign?.Map?.CurrentLocation?.Name),
|
||||||
new string[] { TextManager.Get("Ok") });
|
new LocalizedString[] { TextManager.Get("Ok") });
|
||||||
dialog.Buttons[0].OnClicked += dialog.Close;
|
dialog.Buttons[0].OnClicked += dialog.Close;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -687,7 +700,7 @@ namespace Barotrauma
|
|||||||
RelativeSpacing = 0.02f,
|
RelativeSpacing = 0.02f,
|
||||||
Stretch = true
|
Stretch = true
|
||||||
};
|
};
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), layoutGroup.RectTransform), TextManager.Get("campaigncrew.givenickname"), font: GUI.SubHeadingFont, textAlignment: Alignment.Center, wrap: true);
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), layoutGroup.RectTransform), TextManager.Get("campaigncrew.givenickname"), font: GUIStyle.SubHeadingFont, textAlignment: Alignment.Center, wrap: true);
|
||||||
var groupElementSize = new Vector2(1.0f, 0.25f);
|
var groupElementSize = new Vector2(1.0f, 0.25f);
|
||||||
var nameBox = new GUITextBox(new RectTransform(groupElementSize, layoutGroup.RectTransform))
|
var nameBox = new GUITextBox(new RectTransform(groupElementSize, layoutGroup.RectTransform))
|
||||||
{
|
{
|
||||||
@@ -732,7 +745,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var crewComponent = crewList.Content.FindChild(c => (c.UserData as Tuple<CharacterInfo, float>).Item1 == characterInfo);
|
var crewComponent = crewList.Content.FindChild(c => ((InfoSkill)c.UserData).CharacterInfo == characterInfo);
|
||||||
if (crewComponent != null)
|
if (crewComponent != null)
|
||||||
{
|
{
|
||||||
crewList.Content.RemoveChild(crewComponent);
|
crewList.Content.RemoveChild(crewComponent);
|
||||||
@@ -742,7 +755,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var pendingComponent = pendingList.Content.FindChild(c => (c.UserData as Tuple<CharacterInfo, float>).Item1 == characterInfo);
|
var pendingComponent = pendingList.Content.FindChild(c => ((InfoSkill)c.UserData).CharacterInfo == characterInfo);
|
||||||
if (pendingComponent != null)
|
if (pendingComponent != null)
|
||||||
{
|
{
|
||||||
pendingList.Content.RemoveChild(pendingComponent);
|
pendingList.Content.RemoveChild(pendingComponent);
|
||||||
@@ -821,15 +834,15 @@ namespace Barotrauma
|
|||||||
characterPreviewFrame = null;
|
characterPreviewFrame = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static (GUIComponent, CharacterInfo) FindHighlightedCharacter(GUIComponent c)
|
static (GUIComponent GuiComponent, CharacterInfo CharacterInfo) FindHighlightedCharacter(GUIComponent c)
|
||||||
{
|
{
|
||||||
if (c == null)
|
if (c == null)
|
||||||
{
|
{
|
||||||
return default;
|
return default;
|
||||||
}
|
}
|
||||||
if (c.UserData is Tuple<CharacterInfo, float> highlightedData)
|
if (c.UserData is InfoSkill highlightedData)
|
||||||
{
|
{
|
||||||
return (c, highlightedData.Item1);
|
return (c, highlightedData.CharacterInfo);
|
||||||
}
|
}
|
||||||
if (c.Parent != null)
|
if (c.Parent != null)
|
||||||
{
|
{
|
||||||
@@ -912,7 +925,5 @@ namespace Barotrauma
|
|||||||
GameMain.Client.ClientPeer?.Send(msg, DeliveryMethod.Reliable);
|
GameMain.Client.ClientPeer?.Send(msg, DeliveryMethod.Reliable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string FormatCurrency(int currency) => TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", currency));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
using Microsoft.Xna.Framework;
|
#nullable enable
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Barotrauma.IO;
|
using Barotrauma.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Barotrauma.Extensions;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -18,7 +20,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value && backgroundFrame == null) { Init(); }
|
if (value) { InitIfNecessary(); }
|
||||||
if (!value)
|
if (!value)
|
||||||
{
|
{
|
||||||
fileSystemWatcher?.Dispose();
|
fileSystemWatcher?.Dispose();
|
||||||
@@ -28,26 +30,31 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static GUIFrame backgroundFrame;
|
private static GUIFrame? backgroundFrame;
|
||||||
private static GUIFrame window;
|
private static GUIFrame? window;
|
||||||
private static GUIListBox sidebar;
|
private static GUIListBox? sidebar;
|
||||||
private static GUIListBox fileList;
|
private static GUIListBox? fileList;
|
||||||
private static GUITextBox directoryBox;
|
private static GUITextBox? directoryBox;
|
||||||
private static GUITextBox filterBox;
|
private static GUITextBox? filterBox;
|
||||||
private static GUITextBox fileBox;
|
private static GUITextBox? fileBox;
|
||||||
private static GUIDropDown fileTypeDropdown;
|
private static GUIDropDown? fileTypeDropdown;
|
||||||
private static GUIButton openButton;
|
private static GUIButton? openButton;
|
||||||
|
|
||||||
private static System.IO.FileSystemWatcher fileSystemWatcher;
|
private static System.IO.FileSystemWatcher? fileSystemWatcher;
|
||||||
|
|
||||||
private static string currentFileTypePattern;
|
private enum ItemIsDirectory
|
||||||
|
{
|
||||||
|
Yes, No
|
||||||
|
}
|
||||||
|
|
||||||
private static readonly string[] ignoredDrivePrefixes = new string[]
|
private static string? currentFileTypePattern;
|
||||||
|
|
||||||
|
private static readonly string[] ignoredDrivePrefixes =
|
||||||
{
|
{
|
||||||
"/sys/", "/snap/"
|
"/sys/", "/snap/"
|
||||||
};
|
};
|
||||||
|
|
||||||
private static string currentDirectory;
|
private static string currentDirectory = "";
|
||||||
public static string CurrentDirectory
|
public static string CurrentDirectory
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -91,7 +98,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Action<string> OnFileSelected
|
public static Action<string>? OnFileSelected
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
set;
|
set;
|
||||||
@@ -99,15 +106,16 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private static void OnFileSystemChanges(object sender, System.IO.FileSystemEventArgs e)
|
private static void OnFileSystemChanges(object sender, System.IO.FileSystemEventArgs e)
|
||||||
{
|
{
|
||||||
|
if (fileList is null) { return; }
|
||||||
switch (e.ChangeType)
|
switch (e.ChangeType)
|
||||||
{
|
{
|
||||||
case System.IO.WatcherChangeTypes.Created:
|
case System.IO.WatcherChangeTypes.Created:
|
||||||
{
|
{
|
||||||
var itemFrame = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), fileList.Content.RectTransform), e.Name)
|
var itemFrame = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), fileList.Content.RectTransform), e.Name ?? string.Empty)
|
||||||
{
|
{
|
||||||
UserData = (bool?)Directory.Exists(e.FullPath)
|
UserData = Directory.Exists(e.FullPath) ? ItemIsDirectory.Yes : ItemIsDirectory.No
|
||||||
};
|
};
|
||||||
if ((itemFrame.UserData as bool?) ?? false)
|
if (itemFrame.UserData is ItemIsDirectory.Yes)
|
||||||
{
|
{
|
||||||
itemFrame.Text += "/";
|
itemFrame.Text += "/";
|
||||||
}
|
}
|
||||||
@@ -122,11 +130,13 @@ namespace Barotrauma
|
|||||||
break;
|
break;
|
||||||
case System.IO.WatcherChangeTypes.Renamed:
|
case System.IO.WatcherChangeTypes.Renamed:
|
||||||
{
|
{
|
||||||
System.IO.RenamedEventArgs renameArgs = e as System.IO.RenamedEventArgs;
|
System.IO.RenamedEventArgs renameArgs = e as System.IO.RenamedEventArgs ?? throw new InvalidCastException($"Unable to cast {nameof(System.IO.FileSystemEventArgs)} to {nameof(System.IO.RenamedEventArgs)}.");
|
||||||
var itemFrame = fileList.Content.FindChild(c => (c is GUITextBlock tb) && (tb.Text == renameArgs.OldName || tb.Text == renameArgs.OldName + "/")) as GUITextBlock;
|
var itemFrame =
|
||||||
itemFrame.UserData = (bool?)Directory.Exists(e.FullPath);
|
fileList.Content.FindChild(c => (c is GUITextBlock tb) && (tb.Text == renameArgs.OldName || tb.Text == renameArgs.OldName + "/")) as GUITextBlock
|
||||||
itemFrame.Text = renameArgs.Name;
|
?? throw new Exception($"Could not find file list item with name \"{renameArgs.OldName}\"");
|
||||||
if ((itemFrame.UserData as bool?) ?? false)
|
itemFrame.UserData = Directory.Exists(e.FullPath) ? ItemIsDirectory.Yes : ItemIsDirectory.No;
|
||||||
|
itemFrame.Text = renameArgs.Name ?? string.Empty;
|
||||||
|
if (itemFrame.UserData is ItemIsDirectory.Yes)
|
||||||
{
|
{
|
||||||
itemFrame.Text += "/";
|
itemFrame.Text += "/";
|
||||||
}
|
}
|
||||||
@@ -138,10 +148,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private static int SortFiles(RectTransform r1, RectTransform r2)
|
private static int SortFiles(RectTransform r1, RectTransform r2)
|
||||||
{
|
{
|
||||||
string file1 = (r1.GUIComponent as GUITextBlock)?.Text ?? "";
|
string file1 = (r1.GUIComponent as GUITextBlock)?.Text?.SanitizedValue ?? "";
|
||||||
string file2 = (r2.GUIComponent as GUITextBlock)?.Text ?? "";
|
string file2 = (r2.GUIComponent as GUITextBlock)?.Text?.SanitizedValue ?? "";
|
||||||
bool dir1 = (r1.GUIComponent.UserData as bool?) ?? false;
|
bool dir1 = r1.GUIComponent.UserData is ItemIsDirectory.Yes;
|
||||||
bool dir2 = (r2.GUIComponent.UserData as bool?) ?? false;
|
bool dir2 = r2.GUIComponent.UserData is ItemIsDirectory.Yes;
|
||||||
if (dir1 && !dir2)
|
if (dir1 && !dir2)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
@@ -154,6 +164,11 @@ namespace Barotrauma
|
|||||||
return string.Compare(file1, file2);
|
return string.Compare(file1, file2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void InitIfNecessary()
|
||||||
|
{
|
||||||
|
if (backgroundFrame == null) { Init(); }
|
||||||
|
}
|
||||||
|
|
||||||
public static void Init()
|
public static void Init()
|
||||||
{
|
{
|
||||||
backgroundFrame = new GUIFrame(new RectTransform(GUI.Canvas.RelativeSize, GUI.Canvas), style: null)
|
backgroundFrame = new GUIFrame(new RectTransform(GUI.Canvas.RelativeSize, GUI.Canvas), style: null)
|
||||||
@@ -179,7 +194,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
sidebar.OnSelected = (child, userdata) =>
|
sidebar.OnSelected = (child, userdata) =>
|
||||||
{
|
{
|
||||||
CurrentDirectory = (child as GUITextBlock).Text;
|
CurrentDirectory = (child as GUITextBlock)?.Text.SanitizedValue ?? throw new Exception("Sidebar selection is invalid");
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
@@ -228,13 +243,14 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
OnSelected = (child, userdata) =>
|
OnSelected = (child, userdata) =>
|
||||||
{
|
{
|
||||||
if (userdata == null) { return false; }
|
if (userdata is null) { return false; }
|
||||||
|
if (fileBox is null) { return false; }
|
||||||
|
|
||||||
var fileName = (child as GUITextBlock).Text;
|
var fileName = (child as GUITextBlock)!.Text.SanitizedValue;
|
||||||
fileBox.Text = fileName;
|
fileBox.Text = fileName;
|
||||||
if (PlayerInput.DoubleClicked())
|
if (PlayerInput.DoubleClicked())
|
||||||
{
|
{
|
||||||
bool isDir = (userdata as bool?).Value;
|
bool isDir = userdata is ItemIsDirectory.Yes;
|
||||||
if (isDir)
|
if (isDir)
|
||||||
{
|
{
|
||||||
CurrentDirectory += fileName;
|
CurrentDirectory += fileName;
|
||||||
@@ -263,7 +279,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
OnSelected = (child, userdata) =>
|
OnSelected = (child, userdata) =>
|
||||||
{
|
{
|
||||||
currentFileTypePattern = (child as GUITextBlock).UserData as string;
|
currentFileTypePattern = (child as GUITextBlock)!.UserData as string;
|
||||||
RefreshFileList();
|
RefreshFileList();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -307,30 +323,31 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public static void ClearFileTypeFilters()
|
public static void ClearFileTypeFilters()
|
||||||
{
|
{
|
||||||
if (backgroundFrame == null) { Init(); }
|
InitIfNecessary();
|
||||||
fileTypeDropdown.ClearChildren();
|
fileTypeDropdown!.ClearChildren();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AddFileTypeFilter(string name, string pattern)
|
public static void AddFileTypeFilter(string name, string pattern)
|
||||||
{
|
{
|
||||||
if (backgroundFrame == null) { Init(); }
|
InitIfNecessary();
|
||||||
fileTypeDropdown.AddItem(name + " (" + pattern + ")", pattern);
|
fileTypeDropdown!.AddItem(name + " (" + pattern + ")", pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SelectFileTypeFilter(string pattern)
|
public static void SelectFileTypeFilter(string pattern)
|
||||||
{
|
{
|
||||||
if (backgroundFrame == null) { Init(); }
|
InitIfNecessary();
|
||||||
fileTypeDropdown.SelectItem(pattern);
|
fileTypeDropdown!.SelectItem(pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void RefreshFileList()
|
public static void RefreshFileList()
|
||||||
{
|
{
|
||||||
fileList.Content.ClearChildren();
|
InitIfNecessary();
|
||||||
|
fileList!.Content.ClearChildren();
|
||||||
fileList.BarScroll = 0.0f;
|
fileList.BarScroll = 0.0f;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var directories = Directory.EnumerateDirectories(currentDirectory, "*" + filterBox.Text + "*");
|
var directories = Directory.EnumerateDirectories(currentDirectory, "*" + filterBox!.Text + "*");
|
||||||
foreach (var directory in directories)
|
foreach (var directory in directories)
|
||||||
{
|
{
|
||||||
string txt = directory;
|
string txt = directory;
|
||||||
@@ -338,7 +355,7 @@ namespace Barotrauma
|
|||||||
if (!txt.EndsWith("/")) { txt += "/"; }
|
if (!txt.EndsWith("/")) { txt += "/"; }
|
||||||
var itemFrame = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), fileList.Content.RectTransform), txt)
|
var itemFrame = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), fileList.Content.RectTransform), txt)
|
||||||
{
|
{
|
||||||
UserData = (bool?)true
|
UserData = ItemIsDirectory.Yes
|
||||||
};
|
};
|
||||||
var folderIcon = new GUIImage(new RectTransform(new Point((int)(itemFrame.Rect.Height * 0.8f)), itemFrame.RectTransform, Anchor.CenterLeft)
|
var folderIcon = new GUIImage(new RectTransform(new Point((int)(itemFrame.Rect.Height * 0.8f)), itemFrame.RectTransform, Anchor.CenterLeft)
|
||||||
{
|
{
|
||||||
@@ -347,18 +364,18 @@ namespace Barotrauma
|
|||||||
itemFrame.Padding = new Vector4(folderIcon.Rect.Width * 1.5f, itemFrame.Padding.Y, itemFrame.Padding.Z, itemFrame.Padding.W);
|
itemFrame.Padding = new Vector4(folderIcon.Rect.Width * 1.5f, itemFrame.Padding.Y, itemFrame.Padding.Z, itemFrame.Padding.W);
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerable<string> files = null;
|
IEnumerable<string> files = Enumerable.Empty<string>();
|
||||||
if (currentFileTypePattern == null)
|
if (currentFileTypePattern.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
files = Directory.GetFiles(currentDirectory);
|
files = Directory.GetFiles(currentDirectory);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
foreach (string pattern in currentFileTypePattern.Split(','))
|
foreach (string pattern in currentFileTypePattern!.Split(','))
|
||||||
{
|
{
|
||||||
string patternTrimmed = pattern.Trim();
|
string patternTrimmed = pattern.Trim();
|
||||||
patternTrimmed = "*" + filterBox.Text + "*" + patternTrimmed;
|
patternTrimmed = "*" + filterBox.Text + "*" + patternTrimmed;
|
||||||
if (files == null)
|
if (files.None())
|
||||||
{
|
{
|
||||||
files = Directory.EnumerateFiles(currentDirectory, patternTrimmed);
|
files = Directory.EnumerateFiles(currentDirectory, patternTrimmed);
|
||||||
}
|
}
|
||||||
@@ -375,7 +392,7 @@ namespace Barotrauma
|
|||||||
if (txt.StartsWith(currentDirectory)) { txt = txt.Substring(currentDirectory.Length); }
|
if (txt.StartsWith(currentDirectory)) { txt = txt.Substring(currentDirectory.Length); }
|
||||||
var itemFrame = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), fileList.Content.RectTransform), txt)
|
var itemFrame = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), fileList.Content.RectTransform), txt)
|
||||||
{
|
{
|
||||||
UserData = (bool?)false
|
UserData = ItemIsDirectory.No
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -387,8 +404,8 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
directoryBox.Text = currentDirectory;
|
directoryBox!.Text = currentDirectory;
|
||||||
fileBox.Text = "";
|
fileBox!.Text = "";
|
||||||
fileList.Deselect();
|
fileList.Deselect();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,9 +415,9 @@ namespace Barotrauma
|
|||||||
if (dir.EndsWith("/")) { dir = dir.Substring(0, dir.Length - 1); }
|
if (dir.EndsWith("/")) { dir = dir.Substring(0, dir.Length - 1); }
|
||||||
int index = dir.LastIndexOf("/");
|
int index = dir.LastIndexOf("/");
|
||||||
if (index < 0) { return false; }
|
if (index < 0) { return false; }
|
||||||
CurrentDirectory = CurrentDirectory.Substring(0, index+1);
|
CurrentDirectory = CurrentDirectory.Substring(0, index + 1);
|
||||||
|
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AddToGUIUpdateList()
|
public static void AddToGUIUpdateList()
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -116,32 +116,32 @@ namespace Barotrauma
|
|||||||
get { return Frame.FlashTimer; }
|
get { return Frame.FlashTimer; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ScalableFont Font
|
public override GUIFont Font
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return (textBlock == null) ? GUI.Font : textBlock.Font;
|
return (textBlock == null) ? GUIStyle.Font : textBlock.Font;
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
base.Font = value;
|
base.Font = value;
|
||||||
if (textBlock != null) textBlock.Font = value;
|
if (textBlock != null) { textBlock.Font = value; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Text
|
public LocalizedString Text
|
||||||
{
|
{
|
||||||
get { return textBlock.Text; }
|
get { return textBlock.Text; }
|
||||||
set { textBlock.Text = value; }
|
set { textBlock.Text = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ForceUpperCase
|
public ForceUpperCase ForceUpperCase
|
||||||
{
|
{
|
||||||
get { return textBlock.ForceUpperCase; }
|
get { return textBlock.ForceUpperCase; }
|
||||||
set { textBlock.ForceUpperCase = value; }
|
set { textBlock.ForceUpperCase = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToolTip
|
public override RichString ToolTip
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@@ -161,38 +161,35 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public GUISoundType ClickSound { get; set; } = GUISoundType.Click;
|
public GUISoundType ClickSound { get; set; } = GUISoundType.Click;
|
||||||
|
|
||||||
public GUIButton(RectTransform rectT, string text = "", Alignment textAlignment = Alignment.Center, string style = "", Color? color = null) : base(style, rectT)
|
public GUIButton(RectTransform rectT, Alignment textAlignment = Alignment.Center, string style = "", Color? color = null) : this(rectT, new RawLString(""), textAlignment, style, color) { }
|
||||||
|
|
||||||
|
public GUIButton(RectTransform rectT, LocalizedString text, Alignment textAlignment = Alignment.Center, string style = "", Color? color = null) : base(style, rectT)
|
||||||
{
|
{
|
||||||
CanBeFocused = true;
|
CanBeFocused = true;
|
||||||
HoverCursor = CursorState.Hand;
|
HoverCursor = CursorState.Hand;
|
||||||
|
|
||||||
frame = new GUIFrame(new RectTransform(Vector2.One, rectT), style) { CanBeFocused = false };
|
frame = new GUIFrame(new RectTransform(Vector2.One, rectT), style) { CanBeFocused = false };
|
||||||
if (style != null) { GUI.Style.Apply(frame, style == "" ? "GUIButton" : style); }
|
if (style != null) { GUIStyle.Apply(frame, style == "" ? "GUIButton" : style); }
|
||||||
if (color.HasValue)
|
if (color.HasValue)
|
||||||
{
|
{
|
||||||
this.color = frame.Color = color.Value;
|
this.color = frame.Color = color.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var selfStyle = Style;
|
||||||
textBlock = new GUITextBlock(new RectTransform(Vector2.One, rectT, Anchor.Center), text, textAlignment: textAlignment, style: null)
|
textBlock = new GUITextBlock(new RectTransform(Vector2.One, rectT, Anchor.Center), text, textAlignment: textAlignment, style: null)
|
||||||
{
|
{
|
||||||
TextColor = this.style == null ? Color.Black : this.style.TextColor,
|
TextColor = selfStyle?.TextColor ?? Color.Black,
|
||||||
HoverTextColor = this.style == null ? Color.Black : this.style.HoverTextColor,
|
HoverTextColor = selfStyle?.HoverTextColor ?? Color.Black,
|
||||||
SelectedTextColor = this.style == null ? Color.Black : this.style.SelectedTextColor,
|
SelectedTextColor = selfStyle?.SelectedTextColor ?? Color.Black,
|
||||||
CanBeFocused = false
|
CanBeFocused = false
|
||||||
};
|
};
|
||||||
if (rectT.Rect.Height == 0 && !string.IsNullOrEmpty(text))
|
if (rectT.Rect.Height == 0 && !text.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
RectTransform.Resize(new Point(RectTransform.Rect.Width, (int)Font.MeasureString(textBlock.Text).Y));
|
RectTransform.Resize(new Point(RectTransform.Rect.Width, (int)Font.MeasureString(textBlock.Text).Y));
|
||||||
RectTransform.MinSize = textBlock.RectTransform.MinSize = new Point(0, System.Math.Max(rectT.MinSize.Y, Rect.Height));
|
RectTransform.MinSize = textBlock.RectTransform.MinSize = new Point(0, System.Math.Max(rectT.MinSize.Y, Rect.Height));
|
||||||
TextBlock.SetTextPos();
|
TextBlock.SetTextPos();
|
||||||
}
|
}
|
||||||
GUI.Style.Apply(textBlock, "", this);
|
GUIStyle.Apply(textBlock, "", this);
|
||||||
|
|
||||||
//if the text is in chinese/korean/japanese and we're not using a CJK-compatible font,
|
|
||||||
//use the default CJK font as a fallback
|
|
||||||
if (TextManager.IsCJK(textBlock.Text) && !textBlock.Font.IsCJK)
|
|
||||||
{
|
|
||||||
textBlock.Font = GUI.CJKFont;
|
|
||||||
}
|
|
||||||
|
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
}
|
}
|
||||||
@@ -217,7 +214,7 @@ namespace Barotrauma
|
|||||||
float expand = (pulseExpand * 20.0f) * GUI.Scale;
|
float expand = (pulseExpand * 20.0f) * GUI.Scale;
|
||||||
expandRect.Inflate(expand, expand);
|
expandRect.Inflate(expand, expand);
|
||||||
|
|
||||||
GUI.Style.ButtonPulse.Draw(spriteBatch, expandRect, ToolBox.GradientLerp(pulseExpand, Color.White, Color.White, Color.Transparent));
|
GUIStyle.EndRoundButtonPulse.Draw(spriteBatch, expandRect, ToolBox.GradientLerp(pulseExpand, Color.White, Color.White, Color.Transparent));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ using Microsoft.Xna.Framework;
|
|||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
public class GUIColorPicker : GUIComponent
|
public class GUIColorPicker : GUIComponent, IDisposable
|
||||||
{
|
{
|
||||||
public delegate bool OnColorSelectedHandler(GUIColorPicker component, Color color);
|
public delegate bool OnColorSelectedHandler(GUIColorPicker component, Color color);
|
||||||
public OnColorSelectedHandler? OnColorSelected;
|
public OnColorSelectedHandler? OnColorSelected;
|
||||||
@@ -34,11 +34,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public GUIColorPicker(RectTransform rectT, string? style = null) : base(style, rectT) { }
|
public GUIColorPicker(RectTransform rectT, string? style = null) : base(style, rectT) { }
|
||||||
|
|
||||||
~GUIColorPicker()
|
|
||||||
{
|
|
||||||
DisposeTextures();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Init()
|
private void Init()
|
||||||
{
|
{
|
||||||
int tWidth = Rect.Width;
|
int tWidth = Rect.Width;
|
||||||
@@ -170,10 +165,12 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DisposeTextures()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
mainTexture?.Dispose();
|
mainTexture?.Dispose();
|
||||||
|
mainTexture = null;
|
||||||
hueTexture?.Dispose();
|
hueTexture?.Dispose();
|
||||||
|
hueTexture = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RefreshHue()
|
public void RefreshHue()
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using System.Xml.Linq;
|
|||||||
using Barotrauma.IO;
|
using Barotrauma.IO;
|
||||||
using RestSharp;
|
using RestSharp;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -39,7 +40,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public IEnumerable<T> GetAllChildren<T>() where T : GUIComponent
|
public IEnumerable<T> GetAllChildren<T>() where T : GUIComponent
|
||||||
{
|
{
|
||||||
return GetAllChildren().Where(c => c is T).Select(c => c as T);
|
return GetAllChildren().OfType<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -66,7 +67,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
foreach (GUIComponent child in Children)
|
foreach (GUIComponent child in Children)
|
||||||
{
|
{
|
||||||
if (child.UserData == obj || (child.userData != null && child.userData.Equals(obj))) { return child; }
|
if (Equals(child.UserData, obj)) { return child; }
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -107,7 +108,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
public GUIComponent FindChild(object userData, bool recursive = false)
|
public GUIComponent FindChild(object userData, bool recursive = false)
|
||||||
{
|
{
|
||||||
var matchingChild = Children.FirstOrDefault(c => c.userData == userData);
|
var matchingChild = Children.FirstOrDefault(c => Equals(c.UserData, userData));
|
||||||
if (recursive && matchingChild == null)
|
if (recursive && matchingChild == null)
|
||||||
{
|
{
|
||||||
foreach (GUIComponent child in Children)
|
foreach (GUIComponent child in Children)
|
||||||
@@ -122,7 +123,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public IEnumerable<GUIComponent> FindChildren(object userData)
|
public IEnumerable<GUIComponent> FindChildren(object userData)
|
||||||
{
|
{
|
||||||
return Children.Where(c => c.userData == userData);
|
return Children.Where(c => Equals(c.UserData, userData));
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<GUIComponent> FindChildren(Func<GUIComponent, bool> predicate)
|
public IEnumerable<GUIComponent> FindChildren(Func<GUIComponent, bool> predicate)
|
||||||
@@ -161,9 +162,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
protected Alignment alignment;
|
protected Alignment alignment;
|
||||||
|
|
||||||
protected GUIComponentStyle style;
|
protected Identifier[] styleHierarchy;
|
||||||
|
|
||||||
protected object userData;
|
|
||||||
|
|
||||||
public bool CanBeFocused;
|
public bool CanBeFocused;
|
||||||
|
|
||||||
@@ -206,16 +205,14 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual ScalableFont Font
|
public virtual GUIFont Font
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the rawtooltip when copying displayed tooltips so that any possible color-data related values are translated over as well
|
private RichString toolTip;
|
||||||
public string RawToolTip;
|
public virtual RichString ToolTip
|
||||||
private string toolTip;
|
|
||||||
public virtual string ToolTip
|
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@@ -223,18 +220,12 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
RawToolTip = value;
|
|
||||||
TooltipRichTextData = RichTextData.GetRichTextData(value, out value);
|
|
||||||
toolTip = value;
|
toolTip = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<RichTextData> TooltipRichTextData = null;
|
|
||||||
|
|
||||||
public GUIComponentStyle Style
|
public GUIComponentStyle Style
|
||||||
{
|
=> GUIComponentStyle.FromHierarchy(styleHierarchy);
|
||||||
get { return style; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Visible
|
public bool Visible
|
||||||
{
|
{
|
||||||
@@ -258,8 +249,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
protected Rectangle ClampRect(Rectangle r)
|
protected Rectangle ClampRect(Rectangle r)
|
||||||
{
|
{
|
||||||
if (Parent == null || !ClampMouseRectToParent) { return r; }
|
if (Parent is null) { return r; }
|
||||||
Rectangle parentRect = Parent.ClampRect(Parent.Rect);
|
Rectangle parentRect = !Parent.ClampMouseRectToParent ? Parent.Rect : Parent.ClampRect(Parent.Rect);
|
||||||
if (parentRect.Width <= 0 || parentRect.Height <= 0) { return Rectangle.Empty; }
|
if (parentRect.Width <= 0 || parentRect.Height <= 0) { return Rectangle.Empty; }
|
||||||
if (parentRect.X > r.X)
|
if (parentRect.X > r.X)
|
||||||
{
|
{
|
||||||
@@ -293,11 +284,13 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
public bool ClampMouseRectToParent { get; set; } = false;
|
public bool ClampMouseRectToParent { get; set; } = false;
|
||||||
|
|
||||||
public virtual Rectangle MouseRect
|
public virtual Rectangle MouseRect
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (!CanBeFocused) { return Rectangle.Empty; }
|
if (!CanBeFocused) { return Rectangle.Empty; }
|
||||||
|
|
||||||
return ClampMouseRectToParent ? ClampRect(Rect) : Rect;
|
return ClampMouseRectToParent ? ClampRect(Rect) : Rect;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -310,13 +303,13 @@ namespace Barotrauma
|
|||||||
|
|
||||||
protected ComponentState _state;
|
protected ComponentState _state;
|
||||||
protected ComponentState _previousState;
|
protected ComponentState _previousState;
|
||||||
protected bool selected;
|
protected bool isSelected;
|
||||||
public virtual bool Selected
|
public virtual bool Selected
|
||||||
{
|
{
|
||||||
get { return selected; }
|
get { return isSelected; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
selected = value;
|
isSelected = value;
|
||||||
foreach (var child in Children)
|
foreach (var child in Children)
|
||||||
{
|
{
|
||||||
child.Selected = value;
|
child.Selected = value;
|
||||||
@@ -338,11 +331,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public object UserData
|
#warning TODO: this is cursed, stop using this
|
||||||
{
|
public object UserData;
|
||||||
get { return userData; }
|
|
||||||
set { userData = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public int CountChildren
|
public int CountChildren
|
||||||
{
|
{
|
||||||
@@ -417,20 +407,20 @@ namespace Barotrauma
|
|||||||
|
|
||||||
Visible = true;
|
Visible = true;
|
||||||
OutlineColor = Color.Transparent;
|
OutlineColor = Color.Transparent;
|
||||||
Font = GUI.Font;
|
Font = GUIStyle.Font;
|
||||||
CanBeFocused = true;
|
CanBeFocused = true;
|
||||||
|
|
||||||
if (style != null) { GUI.Style.Apply(this, style); }
|
if (style != null) { GUIStyle.Apply(this, style); }
|
||||||
}
|
}
|
||||||
|
|
||||||
protected GUIComponent(string style)
|
protected GUIComponent(string style)
|
||||||
{
|
{
|
||||||
Visible = true;
|
Visible = true;
|
||||||
OutlineColor = Color.Transparent;
|
OutlineColor = Color.Transparent;
|
||||||
Font = GUI.Font;
|
Font = GUIStyle.Font;
|
||||||
CanBeFocused = true;
|
CanBeFocused = true;
|
||||||
|
|
||||||
if (style != null) { GUI.Style.Apply(this, style); }
|
if (style != null) { GUIStyle.Apply(this, style); }
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Updating
|
#region Updating
|
||||||
@@ -486,7 +476,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (GUI.IsMouseOn(this) && PlayerInput.SecondaryMouseButtonClicked())
|
if (GUI.IsMouseOn(this) && PlayerInput.SecondaryMouseButtonClicked())
|
||||||
{
|
{
|
||||||
OnSecondaryClicked?.Invoke(this, userData);
|
OnSecondaryClicked?.Invoke(this, UserData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -704,7 +694,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (GlowOnSelect && State == ComponentState.Selected)
|
if (GlowOnSelect && State == ComponentState.Selected)
|
||||||
{
|
{
|
||||||
GUI.UIGlow.Draw(spriteBatch, Rect, SelectedColor);
|
GUIStyle.UIGlow.Draw(spriteBatch, Rect, SelectedColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flashTimer > 0.0f)
|
if (flashTimer > 0.0f)
|
||||||
@@ -724,7 +714,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var glow = useCircularFlash ? GUI.UIGlowCircular : GUI.UIGlow;
|
var glow = useCircularFlash ? GUIStyle.UIGlowCircular : GUIStyle.UIGlow;
|
||||||
glow.Draw(spriteBatch,
|
glow.Draw(spriteBatch,
|
||||||
flashRect,
|
flashRect,
|
||||||
flashColor * (float)Math.Sin(flashTimer % flashCycleDuration / flashCycleDuration * MathHelper.Pi * 0.8f));
|
flashColor * (float)Math.Sin(flashTimer % flashCycleDuration / flashCycleDuration * MathHelper.Pi * 0.8f));
|
||||||
@@ -738,24 +728,24 @@ namespace Barotrauma
|
|||||||
public void DrawToolTip(SpriteBatch spriteBatch)
|
public void DrawToolTip(SpriteBatch spriteBatch)
|
||||||
{
|
{
|
||||||
if (!Visible) { return; }
|
if (!Visible) { return; }
|
||||||
DrawToolTip(spriteBatch, ToolTip, GUI.MouseOn.Rect, TooltipRichTextData);
|
DrawToolTip(spriteBatch, ToolTip, GUI.MouseOn.Rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DrawToolTip(SpriteBatch spriteBatch, string toolTip, Vector2 pos, List<RichTextData> richTextData = null)
|
public static void DrawToolTip(SpriteBatch spriteBatch, RichString toolTip, Vector2 pos)
|
||||||
{
|
{
|
||||||
if (Tutorials.Tutorial.ContentRunning) { return; }
|
if (GameMain.GameSession?.GameMode is TutorialMode tutorialMode && tutorialMode.Tutorial.ContentRunning) { return; }
|
||||||
|
|
||||||
int width = (int)(400 * GUI.Scale);
|
int width = (int)(400 * GUI.Scale);
|
||||||
int height = (int)(18 * GUI.Scale);
|
int height = (int)(18 * GUI.Scale);
|
||||||
Point padding = new Point((int)(10 * GUI.Scale));
|
Point padding = new Point((int)(10 * GUI.Scale));
|
||||||
|
|
||||||
if (toolTipBlock == null || (string)toolTipBlock.userData != toolTip)
|
if (toolTipBlock == null || (RichString)toolTipBlock.UserData != toolTip)
|
||||||
{
|
{
|
||||||
toolTipBlock = new GUITextBlock(new RectTransform(new Point(width, height), null), richTextData, toolTip, font: GUI.SmallFont, wrap: true, style: "GUIToolTip");
|
toolTipBlock = new GUITextBlock(new RectTransform(new Point(width, height), null), toolTip, font: GUIStyle.SmallFont, wrap: true, style: "GUIToolTip");
|
||||||
toolTipBlock.RectTransform.NonScaledSize = new Point(
|
toolTipBlock.RectTransform.NonScaledSize = new Point(
|
||||||
(int)(GUI.SmallFont.MeasureString(toolTipBlock.WrappedText).X + padding.X + toolTipBlock.Padding.X + toolTipBlock.Padding.Z),
|
(int)(GUIStyle.SmallFont.MeasureString(toolTipBlock.WrappedText).X + padding.X + toolTipBlock.Padding.X + toolTipBlock.Padding.Z),
|
||||||
(int)(GUI.SmallFont.MeasureString(toolTipBlock.WrappedText).Y + padding.Y + toolTipBlock.Padding.Y + toolTipBlock.Padding.W));
|
(int)(GUIStyle.SmallFont.MeasureString(toolTipBlock.WrappedText).Y + padding.Y + toolTipBlock.Padding.Y + toolTipBlock.Padding.W));
|
||||||
toolTipBlock.userData = toolTip;
|
toolTipBlock.UserData = toolTip;
|
||||||
}
|
}
|
||||||
|
|
||||||
toolTipBlock.RectTransform.AbsoluteOffset = pos.ToPoint();
|
toolTipBlock.RectTransform.AbsoluteOffset = pos.ToPoint();
|
||||||
@@ -764,21 +754,21 @@ namespace Barotrauma
|
|||||||
toolTipBlock.DrawManually(spriteBatch);
|
toolTipBlock.DrawManually(spriteBatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DrawToolTip(SpriteBatch spriteBatch, string toolTip, Rectangle targetElement, List<RichTextData> richTextData = null)
|
public static void DrawToolTip(SpriteBatch spriteBatch, RichString toolTip, Rectangle targetElement)
|
||||||
{
|
{
|
||||||
if (Tutorials.Tutorial.ContentRunning) { return; }
|
if (GameMain.GameSession?.GameMode is TutorialMode tutorialMode && tutorialMode.Tutorial.ContentRunning) { return; }
|
||||||
|
|
||||||
int width = (int)(400 * GUI.Scale);
|
int width = (int)(400 * GUI.Scale);
|
||||||
int height = (int)(18 * GUI.Scale);
|
int height = (int)(18 * GUI.Scale);
|
||||||
Point padding = new Point((int)(10 * GUI.Scale));
|
Point padding = new Point((int)(10 * GUI.Scale));
|
||||||
|
|
||||||
if (toolTipBlock == null || (string)toolTipBlock.userData != toolTip)
|
if (toolTipBlock == null || (RichString)toolTipBlock.UserData != toolTip)
|
||||||
{
|
{
|
||||||
toolTipBlock = new GUITextBlock(new RectTransform(new Point(width, height), null), richTextData, toolTip, font: GUI.SmallFont, wrap: true, style: "GUIToolTip");
|
toolTipBlock = new GUITextBlock(new RectTransform(new Point(width, height), null), toolTip, font: GUIStyle.SmallFont, wrap: true, style: "GUIToolTip");
|
||||||
toolTipBlock.RectTransform.NonScaledSize = new Point(
|
toolTipBlock.RectTransform.NonScaledSize = new Point(
|
||||||
(int)(toolTipBlock.Font.MeasureString(toolTipBlock.WrappedText).X + padding.X + toolTipBlock.Padding.X + toolTipBlock.Padding.Z),
|
(int)(toolTipBlock.Font.MeasureString(toolTipBlock.WrappedText).X + padding.X + toolTipBlock.Padding.X + toolTipBlock.Padding.Z),
|
||||||
(int)(toolTipBlock.Font.MeasureString(toolTipBlock.WrappedText).Y + padding.Y + toolTipBlock.Padding.Y + toolTipBlock.Padding.W));
|
(int)(toolTipBlock.Font.MeasureString(toolTipBlock.WrappedText).Y + padding.Y + toolTipBlock.Padding.Y + toolTipBlock.Padding.W));
|
||||||
toolTipBlock.userData = toolTip;
|
toolTipBlock.UserData = toolTip;
|
||||||
}
|
}
|
||||||
|
|
||||||
toolTipBlock.RectTransform.AbsoluteOffset = new Point(targetElement.Center.X, targetElement.Bottom);
|
toolTipBlock.RectTransform.AbsoluteOffset = new Point(targetElement.Center.X, targetElement.Bottom);
|
||||||
@@ -811,7 +801,7 @@ namespace Barotrauma
|
|||||||
this.useRectangleFlash = useRectangleFlash;
|
this.useRectangleFlash = useRectangleFlash;
|
||||||
this.useCircularFlash = useCircularFlash;
|
this.useCircularFlash = useCircularFlash;
|
||||||
this.flashDuration = flashDuration;
|
this.flashDuration = flashDuration;
|
||||||
flashColor = (color == null) ? GUI.Style.Red : (Color)color;
|
flashColor = (color == null) ? GUIStyle.Red : (Color)color;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FadeOut(float duration, bool removeAfter, float wait = 0.0f)
|
public void FadeOut(float duration, bool removeAfter, float wait = 0.0f)
|
||||||
@@ -952,8 +942,7 @@ namespace Barotrauma
|
|||||||
ApplySizeRestrictions(style);
|
ApplySizeRestrictions(style);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
styleHierarchy = GUIComponentStyle.ToHierarchy(style);
|
||||||
this.style = style;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ApplySizeRestrictions(GUIComponentStyle style)
|
public void ApplySizeRestrictions(GUIComponentStyle style)
|
||||||
@@ -972,11 +961,11 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GUIComponent FromXML(XElement element, RectTransform parent)
|
public static GUIComponent FromXML(ContentXElement element, RectTransform parent)
|
||||||
{
|
{
|
||||||
GUIComponent component = null;
|
GUIComponent component = null;
|
||||||
|
|
||||||
foreach (XElement subElement in element.Elements())
|
foreach (var subElement in element.Elements())
|
||||||
{
|
{
|
||||||
if (subElement.Name.ToString().Equals("conditional", StringComparison.OrdinalIgnoreCase) && !CheckConditional(subElement))
|
if (subElement.Name.ToString().Equals("conditional", StringComparison.OrdinalIgnoreCase) && !CheckConditional(subElement))
|
||||||
{
|
{
|
||||||
@@ -1027,7 +1016,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (component != null)
|
if (component != null)
|
||||||
{
|
{
|
||||||
foreach (XElement subElement in element.Elements())
|
foreach (var subElement in element.Elements())
|
||||||
{
|
{
|
||||||
if (subElement.Name.ToString().Equals("conditional", StringComparison.OrdinalIgnoreCase)) { continue; }
|
if (subElement.Name.ToString().Equals("conditional", StringComparison.OrdinalIgnoreCase)) { continue; }
|
||||||
FromXML(subElement, component is GUIListBox listBox ? listBox.Content.RectTransform : component.RectTransform);
|
FromXML(subElement, component is GUIListBox listBox ? listBox.Content.RectTransform : component.RectTransform);
|
||||||
@@ -1078,8 +1067,9 @@ namespace Barotrauma
|
|||||||
switch (attribute.Name.ToString().ToLowerInvariant())
|
switch (attribute.Name.ToString().ToLowerInvariant())
|
||||||
{
|
{
|
||||||
case "language":
|
case "language":
|
||||||
string[] languages = element.GetAttributeStringArray(attribute.Name.ToString(), new string[0]);
|
var languages = element.GetAttributeIdentifierArray(attribute.Name.ToString(), Array.Empty<Identifier>())
|
||||||
if (!languages.Any(l => GameMain.Config.Language.Equals(l, StringComparison.OrdinalIgnoreCase))) { return false; }
|
.Select(s => new LanguageIdentifier(s));
|
||||||
|
if (!languages.Any(l => GameSettings.CurrentConfig.Language == l)) { return false; }
|
||||||
break;
|
break;
|
||||||
case "gameversion":
|
case "gameversion":
|
||||||
var version = new Version(attribute.Value);
|
var version = new Version(attribute.Value);
|
||||||
@@ -1136,23 +1126,12 @@ namespace Barotrauma
|
|||||||
if (element.Attribute("color") != null) { color = element.GetAttributeColor("color", Color.White); }
|
if (element.Attribute("color") != null) { color = element.GetAttributeColor("color", Color.White); }
|
||||||
float scale = element.GetAttributeFloat("scale", 1.0f);
|
float scale = element.GetAttributeFloat("scale", 1.0f);
|
||||||
bool wrap = element.GetAttributeBool("wrap", true);
|
bool wrap = element.GetAttributeBool("wrap", true);
|
||||||
Alignment alignment = Alignment.Center;
|
Alignment alignment =
|
||||||
Enum.TryParse(element.GetAttributeString("alignment", "Center"), out alignment);
|
element.GetAttributeEnum("alignment", text.Contains('\n') ? Alignment.Left : Alignment.Center);
|
||||||
ScalableFont font = GUI.Font;
|
GUIFont font;
|
||||||
switch (element.GetAttributeString("font", "Font").ToLowerInvariant())
|
if (!GUIStyle.Fonts.TryGetValue(element.GetAttributeIdentifier("font", "Font"), out font))
|
||||||
{
|
{
|
||||||
case "font":
|
font = GUIStyle.Font;
|
||||||
font = GUI.Font;
|
|
||||||
break;
|
|
||||||
case "smallfont":
|
|
||||||
font = GUI.SmallFont;
|
|
||||||
break;
|
|
||||||
case "largefont":
|
|
||||||
font = GUI.LargeFont;
|
|
||||||
break;
|
|
||||||
case "subheading":
|
|
||||||
font = GUI.SubHeadingFont;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var textBlock = new GUITextBlock(RectTransform.Load(element, parent),
|
var textBlock = new GUITextBlock(RectTransform.Load(element, parent),
|
||||||
@@ -1265,7 +1244,7 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static GUIImage LoadGUIImage(XElement element, RectTransform parent)
|
private static GUIImage LoadGUIImage(ContentXElement element, RectTransform parent)
|
||||||
{
|
{
|
||||||
Sprite sprite;
|
Sprite sprite;
|
||||||
string url = element.GetAttributeString("url", "");
|
string url = element.GetAttributeString("url", "");
|
||||||
@@ -1298,11 +1277,11 @@ namespace Barotrauma
|
|||||||
return new GUIImage(RectTransform.Load(element, parent), sprite, scaleToFit: true);
|
return new GUIImage(RectTransform.Load(element, parent), sprite, scaleToFit: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static GUIButton LoadAccordion(XElement element, RectTransform parent)
|
private static GUIButton LoadAccordion(ContentXElement element, RectTransform parent)
|
||||||
{
|
{
|
||||||
var button = LoadGUIButton(element, parent);
|
var button = LoadGUIButton(element, parent);
|
||||||
List<GUIComponent> content = new List<GUIComponent>();
|
List<GUIComponent> content = new List<GUIComponent>();
|
||||||
foreach (XElement subElement in element.Elements())
|
foreach (var subElement in element.Elements())
|
||||||
{
|
{
|
||||||
var contentElement = FromXML(subElement, parent);
|
var contentElement = FromXML(subElement, parent);
|
||||||
if (contentElement != null)
|
if (contentElement != null)
|
||||||
|
|||||||
@@ -9,16 +9,23 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
struct ContextMenuOption
|
struct ContextMenuOption
|
||||||
{
|
{
|
||||||
public string Label;
|
public LocalizedString Label;
|
||||||
public Action OnSelected;
|
public Action OnSelected;
|
||||||
public ContextMenuOption[]? SubOptions;
|
public ContextMenuOption[]? SubOptions;
|
||||||
public bool IsEnabled;
|
public bool IsEnabled;
|
||||||
public string Tooltip;
|
public LocalizedString Tooltip;
|
||||||
|
|
||||||
|
|
||||||
|
public ContextMenuOption(string label, bool isEnabled, Action onSelected)
|
||||||
|
: this(TextManager.Get(label).Fallback(label), isEnabled, onSelected) { }
|
||||||
|
|
||||||
|
public ContextMenuOption(Identifier labelTag, bool isEnabled, Action onSelected)
|
||||||
|
: this(TextManager.Get(labelTag), isEnabled, onSelected) { }
|
||||||
|
|
||||||
// Creates a regular context menu
|
// Creates a regular context menu
|
||||||
public ContextMenuOption(string label, bool isEnabled, Action onSelected)
|
public ContextMenuOption(LocalizedString label, bool isEnabled, Action onSelected)
|
||||||
{
|
{
|
||||||
Label = TextManager.Get(label, returnNull: true) ?? label;
|
Label = label;
|
||||||
OnSelected = onSelected;
|
OnSelected = onSelected;
|
||||||
IsEnabled = isEnabled;
|
IsEnabled = isEnabled;
|
||||||
SubOptions = null;
|
SubOptions = null;
|
||||||
@@ -49,14 +56,14 @@ namespace Barotrauma
|
|||||||
/// <param name="header">Header text</param>
|
/// <param name="header">Header text</param>
|
||||||
/// <param name="style">Background style</param>
|
/// <param name="style">Background style</param>
|
||||||
/// <param name="options">list of context menu options</param>
|
/// <param name="options">list of context menu options</param>
|
||||||
public GUIContextMenu(Vector2? position, string header, string style, params ContextMenuOption[] options) : base(style, new RectTransform(Point.Zero, GUI.Canvas))
|
public GUIContextMenu(Vector2? position, LocalizedString header, string style, params ContextMenuOption[] options) : base(style, new RectTransform(Point.Zero, GUI.Canvas))
|
||||||
{
|
{
|
||||||
Vector2 pos = position ?? PlayerInput.MousePosition;
|
Vector2 pos = position ?? PlayerInput.MousePosition;
|
||||||
ScalableFont headerFont = GUI.SubHeadingFont;
|
GUIFont headerFont = GUIStyle.SubHeadingFont;
|
||||||
ScalableFont font = GUI.SmallFont; // font the context menu options use
|
GUIFont font = GUIStyle.SmallFont; // font the context menu options use
|
||||||
Vector4 padding = new Vector4(4), headerPadding = new Vector4(8);
|
Vector4 padding = new Vector4(4), headerPadding = new Vector4(8);
|
||||||
int horizontalPadding = (int) (padding.X + padding.Z), verticalPadding = (int) (padding.Y + padding.W);
|
int horizontalPadding = (int) (padding.X + padding.Z), verticalPadding = (int) (padding.Y + padding.W);
|
||||||
bool hasHeader = !string.IsNullOrWhiteSpace(header);
|
bool hasHeader = !header.IsNullOrWhiteSpace();
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Estimate the size of the context menu
|
// Estimate the size of the context menu
|
||||||
@@ -88,14 +95,21 @@ namespace Barotrauma
|
|||||||
// Construct the GUI elements
|
// Construct the GUI elements
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
GUILayoutGroup background = new GUILayoutGroup(new RectTransform(Vector2.One, RectTransform, Anchor.Center));
|
GUILayoutGroup background = new GUILayoutGroup(new RectTransform(Vector2.One, RectTransform, Anchor.Center))
|
||||||
|
{
|
||||||
|
Stretch = true
|
||||||
|
};
|
||||||
|
|
||||||
|
Point listSize = estimatedSize;
|
||||||
if (hasHeader)
|
if (hasHeader)
|
||||||
{
|
{
|
||||||
HeaderLabel = new GUITextBlock(new RectTransform(new Vector2(1f, 0.2f), background.RectTransform), header, font: headerFont) { Padding = headerPadding };
|
Point sz = Point.Zero;
|
||||||
|
InflateSize(ref sz, header, headerFont);
|
||||||
|
listSize.Y -= sz.Y;
|
||||||
|
HeaderLabel = new GUITextBlock(new RectTransform(sz, background.RectTransform), header, font: headerFont) { Padding = headerPadding };
|
||||||
}
|
}
|
||||||
|
|
||||||
GUIListBox optionList = new GUIListBox(new RectTransform(new Vector2(1f, hasHeader ? 0.8f : 1f), background.RectTransform), style: null)
|
GUIListBox optionList = new GUIListBox(new RectTransform(listSize, background.RectTransform), style: null)
|
||||||
{
|
{
|
||||||
AutoHideScrollBar = false,
|
AutoHideScrollBar = false,
|
||||||
ScrollBarVisible = false,
|
ScrollBarVisible = false,
|
||||||
@@ -111,7 +125,7 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
Options.Add(option, optionElement);
|
Options.Add(option, optionElement);
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(option.Tooltip) && optionElement.Enabled)
|
if (!option.Tooltip.IsNullOrWhiteSpace() && optionElement.Enabled)
|
||||||
{
|
{
|
||||||
optionElement.ToolTip = option.Tooltip;
|
optionElement.ToolTip = option.Tooltip;
|
||||||
}
|
}
|
||||||
@@ -179,7 +193,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public static GUIContextMenu CreateContextMenu(params ContextMenuOption[] options) => CreateContextMenu(PlayerInput.MousePosition, string.Empty, null, options);
|
public static GUIContextMenu CreateContextMenu(params ContextMenuOption[] options) => CreateContextMenu(PlayerInput.MousePosition, string.Empty, null, options);
|
||||||
|
|
||||||
public static GUIContextMenu CreateContextMenu(Vector2? pos, string header, Color? headerColor, params ContextMenuOption[] options)
|
public static GUIContextMenu CreateContextMenu(Vector2? pos, LocalizedString header, Color? headerColor, params ContextMenuOption[] options)
|
||||||
{
|
{
|
||||||
GUIContextMenu menu = new GUIContextMenu(pos,header, "GUIToolTip", options);
|
GUIContextMenu menu = new GUIContextMenu(pos,header, "GUIToolTip", options);
|
||||||
if (headerColor != null)
|
if (headerColor != null)
|
||||||
@@ -209,7 +223,7 @@ namespace Barotrauma
|
|||||||
/// <param name="label">String whose size to inflate by</param>
|
/// <param name="label">String whose size to inflate by</param>
|
||||||
/// <param name="font">What font to use</param>
|
/// <param name="font">What font to use</param>
|
||||||
/// <returns>The size of the text</returns>
|
/// <returns>The size of the text</returns>
|
||||||
private Vector2 InflateSize(ref Point size, string label, ScalableFont font)
|
private Vector2 InflateSize(ref Point size, LocalizedString label, ScalableFont font)
|
||||||
{
|
{
|
||||||
Vector2 textSize = font.MeasureString(label);
|
Vector2 textSize = font.MeasureString(label);
|
||||||
size.X = Math.Max((int) Math.Ceiling(textSize.X), size.X);
|
size.X = Math.Max((int) Math.Ceiling(textSize.X), size.X);
|
||||||
|
|||||||
@@ -56,8 +56,7 @@ namespace Barotrauma
|
|||||||
get { return listBox.SelectedComponent; }
|
get { return listBox.SelectedComponent; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: fix implicit hiding
|
public override bool Selected
|
||||||
public bool Selected
|
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@@ -97,7 +96,7 @@ namespace Barotrauma
|
|||||||
set { button.TextColor = value; }
|
set { button.TextColor = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ScalableFont Font
|
public override GUIFont Font
|
||||||
{
|
{
|
||||||
get { return button?.Font ?? base.Font; }
|
get { return button?.Font ?? base.Font; }
|
||||||
set
|
set
|
||||||
@@ -142,13 +141,13 @@ namespace Barotrauma
|
|||||||
get { return selectedIndexMultiple; }
|
get { return selectedIndexMultiple; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Text
|
public LocalizedString Text
|
||||||
{
|
{
|
||||||
get { return button.Text; }
|
get { return button.Text; }
|
||||||
set { button.Text = value; }
|
set { button.Text = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToolTip
|
public override RichString ToolTip
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@@ -162,18 +161,21 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public GUIDropDown(RectTransform rectT, string text = "", int elementCount = 4, string style = "", bool selectMultiple = false, bool dropAbove = false) : base(style, rectT)
|
public GUIDropDown(RectTransform rectT, LocalizedString text = null, int elementCount = 4, string style = "", bool selectMultiple = false, bool dropAbove = false, Alignment textAlignment = Alignment.CenterLeft) : base(style, rectT)
|
||||||
{
|
{
|
||||||
|
text ??= new RawLString("");
|
||||||
|
|
||||||
HoverCursor = CursorState.Hand;
|
HoverCursor = CursorState.Hand;
|
||||||
CanBeFocused = true;
|
CanBeFocused = true;
|
||||||
|
|
||||||
this.selectMultiple = selectMultiple;
|
this.selectMultiple = selectMultiple;
|
||||||
|
|
||||||
button = new GUIButton(new RectTransform(Vector2.One, rectT), text, Alignment.CenterLeft, style: "GUIDropDown")
|
button = new GUIButton(new RectTransform(Vector2.One, rectT), text, textAlignment, style: "GUIDropDown")
|
||||||
{
|
{
|
||||||
OnClicked = OnClicked
|
OnClicked = OnClicked,
|
||||||
|
TextBlock = { OverflowClip = true }
|
||||||
};
|
};
|
||||||
GUI.Style.Apply(button, "", this);
|
GUIStyle.Apply(button, "", this);
|
||||||
button.TextBlock.SetTextPos();
|
button.TextBlock.SetTextPos();
|
||||||
|
|
||||||
Anchor listAnchor = dropAbove ? Anchor.TopCenter : Anchor.BottomCenter;
|
Anchor listAnchor = dropAbove ? Anchor.TopCenter : Anchor.BottomCenter;
|
||||||
@@ -184,13 +186,13 @@ namespace Barotrauma
|
|||||||
Enabled = !selectMultiple
|
Enabled = !selectMultiple
|
||||||
};
|
};
|
||||||
if (!selectMultiple) { listBox.OnSelected = SelectItem; }
|
if (!selectMultiple) { listBox.OnSelected = SelectItem; }
|
||||||
GUI.Style.Apply(listBox, "GUIListBox", this);
|
GUIStyle.Apply(listBox, "GUIListBox", this);
|
||||||
GUI.Style.Apply(listBox.ContentBackground, "GUIListBox", this);
|
GUIStyle.Apply(listBox.ContentBackground, "GUIListBox", this);
|
||||||
|
|
||||||
if (button.Style.ChildStyles.ContainsKey("dropdownicon"))
|
if (button.Style.ChildStyles.ContainsKey("dropdownicon".ToIdentifier()))
|
||||||
{
|
{
|
||||||
icon = new GUIImage(new RectTransform(new Vector2(0.6f, 0.6f), button.RectTransform, Anchor.CenterRight, scaleBasis: ScaleBasis.BothHeight) { AbsoluteOffset = new Point(5, 0) }, null, scaleToFit: true);
|
icon = new GUIImage(new RectTransform(new Vector2(0.6f, 0.6f), button.RectTransform, Anchor.CenterRight, scaleBasis: ScaleBasis.BothHeight) { AbsoluteOffset = new Point(5, 0) }, null, scaleToFit: true);
|
||||||
icon.ApplyStyle(button.Style.ChildStyles["dropdownicon"]);
|
icon.ApplyStyle(button.Style.ChildStyles["dropdownicon".ToIdentifier()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
currentHighestParent = FindHighestParent();
|
currentHighestParent = FindHighestParent();
|
||||||
@@ -244,8 +246,9 @@ namespace Barotrauma
|
|||||||
return parentHierarchy.Last();
|
return parentHierarchy.Last();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddItem(string text, object userData = null, string toolTip = "")
|
public void AddItem(LocalizedString text, object userData = null, LocalizedString toolTip = null)
|
||||||
{
|
{
|
||||||
|
toolTip ??= "";
|
||||||
if (selectMultiple)
|
if (selectMultiple)
|
||||||
{
|
{
|
||||||
var frame = new GUIFrame(new RectTransform(new Point(button.Rect.Width, button.Rect.Height), listBox.Content.RectTransform)
|
var frame = new GUIFrame(new RectTransform(new Point(button.Rect.Width, button.Rect.Height), listBox.Content.RectTransform)
|
||||||
@@ -261,7 +264,7 @@ namespace Barotrauma
|
|||||||
ToolTip = toolTip,
|
ToolTip = toolTip,
|
||||||
OnSelected = (GUITickBox tb) =>
|
OnSelected = (GUITickBox tb) =>
|
||||||
{
|
{
|
||||||
List<string> texts = new List<string>();
|
List<LocalizedString> texts = new List<LocalizedString>();
|
||||||
selectedDataMultiple.Clear();
|
selectedDataMultiple.Clear();
|
||||||
selectedIndexMultiple.Clear();
|
selectedIndexMultiple.Clear();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@@ -276,7 +279,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
button.Text = string.Join(", ", texts);
|
button.Text = LocalizedString.Join(", ", texts);
|
||||||
// TODO: The callback is called at least twice, remove this?
|
// TODO: The callback is called at least twice, remove this?
|
||||||
OnSelected?.Invoke(tb.Parent, tb.Parent.UserData);
|
OnSelected?.Invoke(tb.Parent, tb.Parent.UserData);
|
||||||
return true;
|
return true;
|
||||||
@@ -311,13 +314,12 @@ namespace Barotrauma
|
|||||||
foreach (GUIComponent child in ListBox.Content.Children)
|
foreach (GUIComponent child in ListBox.Content.Children)
|
||||||
{
|
{
|
||||||
var tickBox = child.GetChild<GUITickBox>();
|
var tickBox = child.GetChild<GUITickBox>();
|
||||||
if (obj == child.UserData) { tickBox.Selected = true; }
|
if (Equals(obj, child.UserData)) { tickBox.Selected = true; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GUITextBlock textBlock = component as GUITextBlock;
|
if (!(component is GUITextBlock textBlock))
|
||||||
if (textBlock == null)
|
|
||||||
{
|
{
|
||||||
textBlock = component.GetChild<GUITextBlock>();
|
textBlock = component.GetChild<GUITextBlock>();
|
||||||
if (textBlock is null && !AllowNonText) { return false; }
|
if (textBlock is null && !AllowNonText) { return false; }
|
||||||
@@ -368,8 +370,9 @@ namespace Barotrauma
|
|||||||
Dropped = !Dropped;
|
Dropped = !Dropped;
|
||||||
if (Dropped && Enabled)
|
if (Dropped && Enabled)
|
||||||
{
|
{
|
||||||
OnDropped?.Invoke(this, userData);
|
OnDropped?.Invoke(this, UserData);
|
||||||
listBox.UpdateScrollBarSize();
|
listBox.UpdateScrollBarSize();
|
||||||
|
listBox.UpdateDimensions();
|
||||||
|
|
||||||
GUI.KeyboardDispatcher.Subscriber = this;
|
GUI.KeyboardDispatcher.Subscriber = this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -177,6 +177,7 @@ namespace Barotrauma
|
|||||||
spriteBatch.Begin(blendState: BlendState, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
|
spriteBatch.Begin(blendState: BlendState, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var style = Style;
|
||||||
if (style != null)
|
if (style != null)
|
||||||
{
|
{
|
||||||
foreach (UISprite uiSprite in style.Sprites[State])
|
foreach (UISprite uiSprite in style.Sprites[State])
|
||||||
@@ -193,7 +194,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (sprite?.Texture != null)
|
else if (sprite?.Texture is { IsDisposed: false })
|
||||||
{
|
{
|
||||||
spriteBatch.Draw(sprite.Texture, Rect.Center.ToVector2(), sourceRect, currentColor * (currentColor.A / 255.0f), Rotation, origin,
|
spriteBatch.Draw(sprite.Texture, Rect.Center.ToVector2(), sourceRect, currentColor * (currentColor.A / 255.0f), Rotation, origin,
|
||||||
Scale, SpriteEffects, 0.0f);
|
Scale, SpriteEffects, 0.0f);
|
||||||
|
|||||||
@@ -92,29 +92,19 @@ namespace Barotrauma
|
|||||||
foreach (RectTransform child in RectTransform.Children)
|
foreach (RectTransform child in RectTransform.Children)
|
||||||
{
|
{
|
||||||
if (child.GUIComponent.IgnoreLayoutGroups) { continue; }
|
if (child.GUIComponent.IgnoreLayoutGroups) { continue; }
|
||||||
if (child.ScaleBasis == ScaleBasis.BothHeight) { child.MinSize = new Point(child.Rect.Height, child.MinSize.Y); }
|
|
||||||
if (child.ScaleBasis == ScaleBasis.BothWidth) { child.MinSize = new Point(child.MinSize.X, child.Rect.Width); }
|
switch (child.ScaleBasis)
|
||||||
if (child.ScaleBasis == ScaleBasis.Smallest)
|
|
||||||
{
|
{
|
||||||
if (Rect.Width < Rect.Height)
|
case ScaleBasis.BothHeight:
|
||||||
{
|
case ScaleBasis.Smallest when Rect.Height <= Rect.Width:
|
||||||
child.MinSize = new Point(child.MinSize.X, child.Rect.Width);
|
case ScaleBasis.Largest when Rect.Height > Rect.Width:
|
||||||
}
|
child.MinSize = new Point((int)((child.Rect.Height * child.RelativeSize.X) / child.RelativeSize.Y), child.MinSize.Y);
|
||||||
else
|
break;
|
||||||
{
|
case ScaleBasis.BothWidth:
|
||||||
child.MinSize = new Point(child.Rect.Height, child.MinSize.Y);
|
case ScaleBasis.Smallest when Rect.Width <= Rect.Height:
|
||||||
}
|
case ScaleBasis.Largest when Rect.Width > Rect.Height:
|
||||||
}
|
child.MinSize = new Point(child.MinSize.X, (int)((child.Rect.Width * child.RelativeSize.Y) / child.RelativeSize.X));
|
||||||
if (child.ScaleBasis == ScaleBasis.Largest)
|
break;
|
||||||
{
|
|
||||||
if (Rect.Width > Rect.Height)
|
|
||||||
{
|
|
||||||
child.MinSize = new Point(child.MinSize.X, child.Rect.Width);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
child.MinSize = new Point(child.Rect.Height, child.MinSize.Y);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,42 +134,65 @@ namespace Barotrauma
|
|||||||
foreach (var child in RectTransform.Children)
|
foreach (var child in RectTransform.Children)
|
||||||
{
|
{
|
||||||
if (child.GUIComponent.IgnoreLayoutGroups) { continue; }
|
if (child.GUIComponent.IgnoreLayoutGroups) { continue; }
|
||||||
|
|
||||||
|
float currentStretchFactor = child.ScaleBasis == ScaleBasis.Normal ? stretchFactor : 1.0f;
|
||||||
child.SetPosition(childAnchor);
|
child.SetPosition(childAnchor);
|
||||||
|
|
||||||
|
void advancePositionsAndCalculateChildSizes(
|
||||||
|
ref int childNonScaledSize,
|
||||||
|
ref float childRelativeSize,
|
||||||
|
int childMinSize,
|
||||||
|
int childMaxSize,
|
||||||
|
int childRectSize,
|
||||||
|
int selfRectSize)
|
||||||
|
{
|
||||||
|
if (child.IsFixedSize)
|
||||||
|
{
|
||||||
|
absPos += childNonScaledSize + absoluteSpacing;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
absPos += (int)Math.Round(MathHelper.Clamp(childRectSize * currentStretchFactor, childMinSize, childMaxSize) + (absoluteSpacing * currentStretchFactor));
|
||||||
|
if (stretch)
|
||||||
|
{
|
||||||
|
float relativeSize =
|
||||||
|
MathF.Round(childRelativeSize * currentStretchFactor * selfRectSize) / selfRectSize;
|
||||||
|
childRelativeSize = relativeSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Point childNonScaledSize = child.NonScaledSize;
|
||||||
|
Vector2 childRelativeSize = child.RelativeSize;
|
||||||
if (isHorizontal)
|
if (isHorizontal)
|
||||||
{
|
{
|
||||||
child.RelativeOffset = new Vector2(relPos, child.RelativeOffset.Y);
|
child.RelativeOffset = new Vector2(relPos, child.RelativeOffset.Y);
|
||||||
child.AbsoluteOffset = new Point(absPos, child.AbsoluteOffset.Y);
|
child.AbsoluteOffset = new Point(absPos, child.AbsoluteOffset.Y);
|
||||||
if (child.IsFixedSize)
|
advancePositionsAndCalculateChildSizes(
|
||||||
{
|
ref childNonScaledSize.X,
|
||||||
absPos += child.NonScaledSize.X + absoluteSpacing;
|
ref childRelativeSize.X,
|
||||||
}
|
child.MinSize.X,
|
||||||
else
|
child.MaxSize.X,
|
||||||
{
|
child.Rect.Width,
|
||||||
absPos += (int)(MathHelper.Clamp(child.Rect.Width * stretchFactor, child.MinSize.X, child.MaxSize.X) + (absoluteSpacing * stretchFactor));
|
Rect.Width);
|
||||||
if (stretch)
|
|
||||||
{
|
|
||||||
child.RelativeSize = new Vector2(child.RelativeSize.X * stretchFactor, child.RelativeSize.Y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
child.RelativeOffset = new Vector2(child.RelativeOffset.X, relPos);
|
child.RelativeOffset = new Vector2(child.RelativeOffset.X, relPos);
|
||||||
child.AbsoluteOffset = new Point(child.AbsoluteOffset.X, absPos);
|
child.AbsoluteOffset = new Point(child.AbsoluteOffset.X, absPos);
|
||||||
if (child.IsFixedSize)
|
advancePositionsAndCalculateChildSizes(
|
||||||
{
|
ref childNonScaledSize.Y,
|
||||||
absPos += child.NonScaledSize.Y + absoluteSpacing;
|
ref childRelativeSize.Y,
|
||||||
}
|
child.MinSize.Y,
|
||||||
else
|
child.MaxSize.Y,
|
||||||
{
|
child.Rect.Height,
|
||||||
absPos += (int)(MathHelper.Clamp(child.Rect.Height * stretchFactor, child.MinSize.Y, child.MaxSize.Y) + (absoluteSpacing * stretchFactor));
|
Rect.Height);
|
||||||
if (stretch)
|
|
||||||
{
|
|
||||||
child.RelativeSize = new Vector2(child.RelativeSize.X, child.RelativeSize.Y * stretchFactor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
child.NonScaledSize = childNonScaledSize;
|
||||||
|
child.RelativeSize = childRelativeSize;
|
||||||
relPos += relativeSpacing * stretchFactor;
|
relPos += relativeSpacing * stretchFactor;
|
||||||
|
if (isHorizontal) { relPos = MathF.Round(relPos * Rect.Width) / Rect.Width; }
|
||||||
|
else { relPos = MathF.Round(relPos * Rect.Height) / Rect.Height; }
|
||||||
}
|
}
|
||||||
needsToRecalculate = false;
|
needsToRecalculate = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,7 +148,11 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: fix implicit hiding
|
// TODO: fix implicit hiding
|
||||||
public bool Selected { get; set; }
|
public override bool Selected
|
||||||
|
{
|
||||||
|
get { return isSelected; }
|
||||||
|
set { isSelected = value; }
|
||||||
|
}
|
||||||
|
|
||||||
public IReadOnlyList<GUIComponent> AllSelected => selected;
|
public IReadOnlyList<GUIComponent> AllSelected => selected;
|
||||||
|
|
||||||
@@ -328,7 +332,7 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
if (style != null)
|
if (style != null)
|
||||||
{
|
{
|
||||||
GUI.Style.Apply(ContentBackground, "", this);
|
GUIStyle.Apply(ContentBackground, "", this);
|
||||||
}
|
}
|
||||||
if (color.HasValue)
|
if (color.HasValue)
|
||||||
{
|
{
|
||||||
@@ -398,8 +402,7 @@ namespace Barotrauma
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
foreach (GUIComponent child in children)
|
foreach (GUIComponent child in children)
|
||||||
{
|
{
|
||||||
if ((child.UserData != null && child.UserData.Equals(userData)) ||
|
if (Equals(child.UserData, userData))
|
||||||
(child.UserData == null && userData == null))
|
|
||||||
{
|
{
|
||||||
Select(i, force, autoScroll);
|
Select(i, force, autoScroll);
|
||||||
if (!SelectMultiple) { return; }
|
if (!SelectMultiple) { return; }
|
||||||
@@ -509,23 +512,36 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Scrolls the list to the specific element, currently only works when smooth scrolling and PadBottom are enabled.
|
/// Scrolls the list to the specific element.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="component"></param>
|
/// <param name="component"></param>
|
||||||
public void ScrollToElement(GUIComponent component)
|
public void ScrollToElement(GUIComponent component, bool playSound = true)
|
||||||
{
|
{
|
||||||
SoundPlayer.PlayUISound(GUISoundType.Click);
|
if (playSound) { SoundPlayer.PlayUISound(GUISoundType.Click); }
|
||||||
List<GUIComponent> children = Content.Children.ToList();
|
List<GUIComponent> children = Content.Children.ToList();
|
||||||
int index = children.IndexOf(component);
|
int index = children.IndexOf(component);
|
||||||
if (index < 0) { return; }
|
if (index < 0) { return; }
|
||||||
|
|
||||||
|
void performScroll(GUIComponent c)
|
||||||
|
{
|
||||||
|
if (SmoothScroll && PadBottom)
|
||||||
|
{
|
||||||
|
scrollToElement = c;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float diff = isHorizontal ? c.Rect.X - Content.Rect.X : c.Rect.Y - Content.Rect.Y;
|
||||||
|
ScrollBar.BarScroll += diff / TotalSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!Content.Children.Contains(component) || !component.Visible)
|
if (!Content.Children.Contains(component) || !component.Visible)
|
||||||
{
|
{
|
||||||
scrollToElement = null;
|
performScroll(null);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
scrollToElement = component;
|
performScroll(component);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1215,6 +1231,20 @@ namespace Barotrauma
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isDraggingElement && CurrentDragMode == DragMode.DragOutsideBox && HideDraggedElement)
|
||||||
|
{
|
||||||
|
Rectangle drawRect = DraggedElement.Rect;
|
||||||
|
int draggedElementIndex = Content.GetChildIndex(DraggedElement);
|
||||||
|
CalculateChildrenOffsets((index, point) =>
|
||||||
|
{
|
||||||
|
if (draggedElementIndex == index)
|
||||||
|
{
|
||||||
|
drawRect.Location = Content.Rect.Location + point;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
GUI.DrawRectangle(spriteBatch, drawRect, Color.White * 0.5f, thickness: 2f);
|
||||||
|
}
|
||||||
|
|
||||||
if (HideChildrenOutsideFrame)
|
if (HideChildrenOutsideFrame)
|
||||||
{
|
{
|
||||||
spriteBatch.End();
|
spriteBatch.End();
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
public class GUIMessageBox : GUIFrame
|
public class GUIMessageBox : GUIFrame
|
||||||
{
|
{
|
||||||
public static List<GUIComponent> MessageBoxes = new List<GUIComponent>();
|
#warning TODO: change this to List<GUIMessageBox> and fix incorrect uses of this list
|
||||||
|
public readonly static List<GUIComponent> MessageBoxes = new List<GUIComponent>();
|
||||||
private static int DefaultWidth
|
private static int DefaultWidth
|
||||||
{
|
{
|
||||||
get { return Math.Max(400, (int)(400 * (GameMain.GraphicsWidth / GUI.ReferenceResolution.X))); }
|
get { return Math.Max(400, (int)(400 * (GameMain.GraphicsWidth / GUI.ReferenceResolution.X))); }
|
||||||
@@ -70,14 +71,14 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public static GUIComponent VisibleBox => MessageBoxes.LastOrDefault();
|
public static GUIComponent VisibleBox => MessageBoxes.LastOrDefault();
|
||||||
|
|
||||||
public GUIMessageBox(string headerText, string text, Vector2? relativeSize = null, Point? minSize = null)
|
public GUIMessageBox(LocalizedString headerText, LocalizedString text, Vector2? relativeSize = null, Point? minSize = null)
|
||||||
: this(headerText, text, new string[] { "OK" }, relativeSize, minSize)
|
: this(headerText, text, new LocalizedString[] { "OK" }, relativeSize, minSize)
|
||||||
{
|
{
|
||||||
this.Buttons[0].OnClicked = Close;
|
this.Buttons[0].OnClicked = Close;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GUIMessageBox(string headerText, string text, string[] buttons, Vector2? relativeSize = null, Point? minSize = null, Alignment textAlignment = Alignment.TopLeft, Type type = Type.Default, string tag = "", Sprite icon = null, string iconStyle = "", Sprite backgroundIcon = null, bool parseRichText = false)
|
public GUIMessageBox(RichString headerText, RichString text, LocalizedString[] buttons, Vector2? relativeSize = null, Point? minSize = null, Alignment textAlignment = Alignment.TopLeft, Type type = Type.Default, string tag = "", Sprite icon = null, string iconStyle = "", Sprite backgroundIcon = null)
|
||||||
: base(new RectTransform(GUI.Canvas.RelativeSize, GUI.Canvas, Anchor.Center), style: GUI.Style.GetComponentStyle("GUIMessageBox." + type) != null ? "GUIMessageBox." + type : "GUIMessageBox")
|
: base(new RectTransform(GUI.Canvas.RelativeSize, GUI.Canvas, Anchor.Center), style: GUIStyle.GetComponentStyle("GUIMessageBox." + type) != null ? "GUIMessageBox." + type : "GUIMessageBox")
|
||||||
{
|
{
|
||||||
int width = (int)(DefaultWidth * type switch
|
int width = (int)(DefaultWidth * type switch
|
||||||
{
|
{
|
||||||
@@ -125,23 +126,24 @@ namespace Barotrauma
|
|||||||
InnerFrame.RectTransform.ScreenSpaceOffset = new Point(-offset, offset);
|
InnerFrame.RectTransform.ScreenSpaceOffset = new Point(-offset, offset);
|
||||||
CanBeFocused = false;
|
CanBeFocused = false;
|
||||||
}
|
}
|
||||||
GUI.Style.Apply(InnerFrame, "", this);
|
GUIStyle.Apply(InnerFrame, "", this);
|
||||||
this.type = type;
|
this.type = type;
|
||||||
Tag = tag;
|
Tag = tag;
|
||||||
|
|
||||||
|
#warning TODO: These should be broken into separate methods at least
|
||||||
if (type == Type.Default || type == Type.Vote)
|
if (type == Type.Default || type == Type.Vote)
|
||||||
{
|
{
|
||||||
Content = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.85f), InnerFrame.RectTransform, Anchor.Center)) { AbsoluteSpacing = 5 };
|
Content = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.85f), InnerFrame.RectTransform, Anchor.Center)) { AbsoluteSpacing = 5 };
|
||||||
|
|
||||||
Header = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform),
|
Header = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform),
|
||||||
headerText, font: GUI.SubHeadingFont, textAlignment: Alignment.Center, wrap: true, parseRichText: parseRichText);
|
headerText, font: GUIStyle.SubHeadingFont, textAlignment: Alignment.Center, wrap: true);
|
||||||
GUI.Style.Apply(Header, "", this);
|
GUIStyle.Apply(Header, "", this);
|
||||||
Header.RectTransform.MinSize = new Point(0, Header.Rect.Height);
|
Header.RectTransform.MinSize = new Point(0, Header.Rect.Height);
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(text))
|
if (!text.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
Text = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), text, textAlignment: textAlignment, wrap: true, parseRichText: parseRichText);
|
Text = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), text, textAlignment: textAlignment, wrap: true);
|
||||||
GUI.Style.Apply(Text, "", this);
|
GUIStyle.Apply(Text, "", this);
|
||||||
Text.RectTransform.NonScaledSize = Text.RectTransform.MinSize = Text.RectTransform.MaxSize =
|
Text.RectTransform.NonScaledSize = Text.RectTransform.MinSize = Text.RectTransform.MaxSize =
|
||||||
new Point(Text.Rect.Width, Text.Rect.Height);
|
new Point(Text.Rect.Width, Text.Rect.Height);
|
||||||
Text.RectTransform.IsFixedSize = true;
|
Text.RectTransform.IsFixedSize = true;
|
||||||
@@ -154,7 +156,7 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
|
|
||||||
int buttonSize = 35;
|
int buttonSize = 35;
|
||||||
var buttonStyle = GUI.Style.GetComponentStyle("GUIButton");
|
var buttonStyle = GUIStyle.GetComponentStyle("GUIButton");
|
||||||
if (buttonStyle != null && buttonStyle.Height.HasValue)
|
if (buttonStyle != null && buttonStyle.Height.HasValue)
|
||||||
{
|
{
|
||||||
buttonSize = buttonStyle.Height.Value;
|
buttonSize = buttonStyle.Height.Value;
|
||||||
@@ -189,7 +191,7 @@ namespace Barotrauma
|
|||||||
InnerFrame.RectTransform.AbsoluteOffset = new Point(0, GameMain.GraphicsHeight);
|
InnerFrame.RectTransform.AbsoluteOffset = new Point(0, GameMain.GraphicsHeight);
|
||||||
CanBeFocused = false;
|
CanBeFocused = false;
|
||||||
AutoClose = true;
|
AutoClose = true;
|
||||||
GUI.Style.Apply(InnerFrame, "", this);
|
GUIStyle.Apply(InnerFrame, "", this);
|
||||||
|
|
||||||
var horizontalLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.98f, 0.95f), InnerFrame.RectTransform, Anchor.Center),
|
var horizontalLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.98f, 0.95f), InnerFrame.RectTransform, Anchor.Center),
|
||||||
isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
||||||
@@ -219,11 +221,11 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
|
|
||||||
InputType? closeInput = null;
|
InputType? closeInput = null;
|
||||||
if (GameMain.Config.KeyBind(InputType.Use).MouseButton == MouseButton.None)
|
if (GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Use].MouseButton == MouseButton.None)
|
||||||
{
|
{
|
||||||
closeInput = InputType.Use;
|
closeInput = InputType.Use;
|
||||||
}
|
}
|
||||||
else if (GameMain.Config.KeyBind(InputType.Select).MouseButton == MouseButton.None)
|
else if (GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Select].MouseButton == MouseButton.None)
|
||||||
{
|
{
|
||||||
closeInput = InputType.Select;
|
closeInput = InputType.Select;
|
||||||
}
|
}
|
||||||
@@ -236,24 +238,24 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
GUIButton btn = component as GUIButton;
|
GUIButton btn = component as GUIButton;
|
||||||
btn?.OnClicked(btn, btn.UserData);
|
btn?.OnClicked(btn, btn.UserData);
|
||||||
btn?.Flash(GUI.Style.Green);
|
btn?.Flash(GUIStyle.Green);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Header = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), headerText, wrap: true, parseRichText: parseRichText);
|
Header = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), headerText, wrap: true);
|
||||||
GUI.Style.Apply(Header, "", this);
|
GUIStyle.Apply(Header, "", this);
|
||||||
Header.RectTransform.MinSize = new Point(0, Header.Rect.Height);
|
Header.RectTransform.MinSize = new Point(0, Header.Rect.Height);
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(text))
|
if (!text.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
Text = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), text, textAlignment: textAlignment, wrap: true, parseRichText: parseRichText);
|
Text = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), text, textAlignment: textAlignment, wrap: true);
|
||||||
GUI.Style.Apply(Text, "", this);
|
GUIStyle.Apply(Text, "", this);
|
||||||
Content.Recalculate();
|
Content.Recalculate();
|
||||||
Text.RectTransform.NonScaledSize = Text.RectTransform.MinSize = Text.RectTransform.MaxSize =
|
Text.RectTransform.NonScaledSize = Text.RectTransform.MinSize = Text.RectTransform.MaxSize =
|
||||||
new Point(Text.Rect.Width, Text.Rect.Height);
|
new Point(Text.Rect.Width, Text.Rect.Height);
|
||||||
Text.RectTransform.IsFixedSize = true;
|
Text.RectTransform.IsFixedSize = true;
|
||||||
if (string.IsNullOrWhiteSpace(headerText))
|
if (headerText.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
Content.ChildAnchor = Anchor.Center;
|
Content.ChildAnchor = Anchor.Center;
|
||||||
}
|
}
|
||||||
@@ -275,7 +277,7 @@ namespace Barotrauma
|
|||||||
else if (type == Type.Hint)
|
else if (type == Type.Hint)
|
||||||
{
|
{
|
||||||
CanBeFocused = false;
|
CanBeFocused = false;
|
||||||
GUI.Style.Apply(InnerFrame, "", this);
|
GUIStyle.Apply(InnerFrame, "", this);
|
||||||
|
|
||||||
Point absoluteSpacing = GUIStyle.ItemFrameMargin.Multiply(1.0f / 5.0f);
|
Point absoluteSpacing = GUIStyle.ItemFrameMargin.Multiply(1.0f / 5.0f);
|
||||||
var verticalLayoutGroup = new GUILayoutGroup(new RectTransform(GetVerticalLayoutGroupSize(), parent: InnerFrame.RectTransform, anchor: Anchor.Center), childAnchor: Anchor.TopCenter)
|
var verticalLayoutGroup = new GUILayoutGroup(new RectTransform(GetVerticalLayoutGroupSize(), parent: InnerFrame.RectTransform, anchor: Anchor.Center), childAnchor: Anchor.TopCenter)
|
||||||
@@ -353,18 +355,18 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
|
|
||||||
Header = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), headerText, wrap: true);
|
Header = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), headerText, wrap: true);
|
||||||
GUI.Style.Apply(Header, "", this);
|
GUIStyle.Apply(Header, "", this);
|
||||||
Header.RectTransform.MinSize = new Point(0, Header.Rect.Height);
|
Header.RectTransform.MinSize = new Point(0, Header.Rect.Height);
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(text))
|
if (!text.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
Text = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), text, textAlignment: textAlignment, wrap: true);
|
Text = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), text, textAlignment: textAlignment, wrap: true);
|
||||||
GUI.Style.Apply(Text, "", this);
|
GUIStyle.Apply(Text, "", this);
|
||||||
Content.Recalculate();
|
Content.Recalculate();
|
||||||
Text.RectTransform.NonScaledSize = Text.RectTransform.MinSize = Text.RectTransform.MaxSize =
|
Text.RectTransform.NonScaledSize = Text.RectTransform.MinSize = Text.RectTransform.MaxSize =
|
||||||
new Point(Text.Rect.Width, Text.Rect.Height);
|
new Point(Text.Rect.Width, Text.Rect.Height);
|
||||||
Text.RectTransform.IsFixedSize = true;
|
Text.RectTransform.IsFixedSize = true;
|
||||||
if (string.IsNullOrWhiteSpace(headerText))
|
if (headerText.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
Header.RectTransform.Parent = null;
|
Header.RectTransform.Parent = null;
|
||||||
Content.ChildAnchor = Anchor.Center;
|
Content.ChildAnchor = Anchor.Center;
|
||||||
@@ -410,7 +412,7 @@ namespace Barotrauma
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Use to create a message box of Hint type
|
/// Use to create a message box of Hint type
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GUIMessageBox(string hintIdentifier, string text, Sprite icon) : this("", text, new string[0], textAlignment: Alignment.CenterLeft, type: Type.Hint, icon: icon)
|
public GUIMessageBox(Identifier hintIdentifier, LocalizedString text, Sprite icon) : this("", text, Array.Empty<LocalizedString>(), textAlignment: Alignment.CenterLeft, type: Type.Hint, icon: icon)
|
||||||
{
|
{
|
||||||
if (InnerFrame.FindChild("dontshowagain", recursive: true) is GUITickBox dontShowAgainTickBox)
|
if (InnerFrame.FindChild("dontshowagain", recursive: true) is GUITickBox dontShowAgainTickBox)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ namespace Barotrauma
|
|||||||
Int, Float
|
Int, Float
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public delegate void OnValueEnteredHandler(GUINumberInput numberInput);
|
||||||
|
public OnValueEnteredHandler OnValueEntered;
|
||||||
|
|
||||||
public delegate void OnValueChangedHandler(GUINumberInput numberInput);
|
public delegate void OnValueChangedHandler(GUINumberInput numberInput);
|
||||||
public OnValueChangedHandler OnValueChanged;
|
public OnValueChangedHandler OnValueChanged;
|
||||||
|
|
||||||
@@ -162,7 +165,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ScalableFont Font
|
public override GUIFont Font
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@@ -209,6 +212,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
ClampFloatValue();
|
ClampFloatValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OnValueEntered?.Invoke(this);
|
||||||
};
|
};
|
||||||
TextBox.OnEnterPressed += (textBox, text) =>
|
TextBox.OnEnterPressed += (textBox, text) =>
|
||||||
{
|
{
|
||||||
@@ -220,12 +225,14 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
ClampFloatValue();
|
ClampFloatValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OnValueEntered?.Invoke(this);
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
var buttonArea = new GUIFrame(new RectTransform(new Vector2(_relativeButtonAreaWidth, 1.0f), LayoutGroup.RectTransform, Anchor.CenterRight), style: null);
|
var buttonArea = new GUIFrame(new RectTransform(new Vector2(_relativeButtonAreaWidth, 1.0f), LayoutGroup.RectTransform, Anchor.CenterRight), style: null);
|
||||||
PlusButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.5f), buttonArea.RectTransform), style: null);
|
PlusButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.5f), buttonArea.RectTransform), style: null);
|
||||||
GUI.Style.Apply(PlusButton, "PlusButton", this);
|
GUIStyle.Apply(PlusButton, "PlusButton", this);
|
||||||
PlusButton.OnButtonDown += () =>
|
PlusButton.OnButtonDown += () =>
|
||||||
{
|
{
|
||||||
pressedTimer = pressedDelay;
|
pressedTimer = pressedDelay;
|
||||||
@@ -246,7 +253,7 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
|
|
||||||
MinusButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.5f), buttonArea.RectTransform, Anchor.BottomRight), style: null);
|
MinusButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.5f), buttonArea.RectTransform, Anchor.BottomRight), style: null);
|
||||||
GUI.Style.Apply(MinusButton, "MinusButton", this);
|
GUIStyle.Apply(MinusButton, "MinusButton", this);
|
||||||
MinusButton.OnButtonDown += () =>
|
MinusButton.OnButtonDown += () =>
|
||||||
{
|
{
|
||||||
pressedTimer = pressedDelay;
|
pressedTimer = pressedDelay;
|
||||||
|
|||||||
@@ -0,0 +1,395 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Barotrauma
|
||||||
|
{
|
||||||
|
public abstract class GUIPrefab : Prefab
|
||||||
|
{
|
||||||
|
public GUIPrefab(ContentXElement element, UIStyleFile file) : base(file, element) { }
|
||||||
|
|
||||||
|
protected override Identifier DetermineIdentifier(XElement element)
|
||||||
|
{
|
||||||
|
return element.NameAsIdentifier();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class GUISelector<T> where T : GUIPrefab
|
||||||
|
{
|
||||||
|
public readonly PrefabSelector<T> Prefabs = new PrefabSelector<T>();
|
||||||
|
public readonly Identifier Identifier;
|
||||||
|
|
||||||
|
public GUISelector(string identifier)
|
||||||
|
{
|
||||||
|
Identifier = identifier.ToIdentifier();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GUIFontPrefab : GUIPrefab
|
||||||
|
{
|
||||||
|
private readonly ContentXElement element;
|
||||||
|
private ScalableFont font;
|
||||||
|
public ScalableFont Font
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (Language != GameSettings.CurrentConfig.Language) { LoadFont(); }
|
||||||
|
return font;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ScalableFont cjkFont;
|
||||||
|
|
||||||
|
public ScalableFont CjkFont
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (Language != GameSettings.CurrentConfig.Language) { LoadFont(); }
|
||||||
|
if (font.IsCJK) { return font; }
|
||||||
|
return cjkFont;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public LanguageIdentifier Language { get; private set; }
|
||||||
|
|
||||||
|
public GUIFontPrefab(ContentXElement element, UIStyleFile file) : base(element, file)
|
||||||
|
{
|
||||||
|
this.element = element;
|
||||||
|
LoadFont();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LoadFont()
|
||||||
|
{
|
||||||
|
string fontPath = GetFontFilePath(element);
|
||||||
|
uint size = GetFontSize(element);
|
||||||
|
bool dynamicLoading = GetFontDynamicLoading(element);
|
||||||
|
bool isCJK = GetIsCJK(element);
|
||||||
|
font?.Dispose();
|
||||||
|
cjkFont?.Dispose();
|
||||||
|
font = new ScalableFont(fontPath, size, GameMain.Instance.GraphicsDevice, dynamicLoading, isCJK)
|
||||||
|
{
|
||||||
|
ForceUpperCase = element.GetAttributeBool("forceuppercase", false)
|
||||||
|
};
|
||||||
|
if (!isCJK)
|
||||||
|
{
|
||||||
|
cjkFont = ExtractCjkFont(element)
|
||||||
|
?? new ScalableFont("Content/Fonts/NotoSans/NotoSansCJKsc-Bold.otf",
|
||||||
|
font.Size, GameMain.Instance.GraphicsDevice, dynamicLoading: true, isCJK: true);
|
||||||
|
cjkFont.ForceUpperCase = font.ForceUpperCase;
|
||||||
|
}
|
||||||
|
Language = GameSettings.CurrentConfig.Language;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
font?.Dispose(); font = null;
|
||||||
|
cjkFont?.Dispose(); cjkFont = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ScalableFont ExtractCjkFont(ContentXElement element)
|
||||||
|
{
|
||||||
|
foreach (var subElement in element.Elements().Reverse())
|
||||||
|
{
|
||||||
|
if (subElement.NameAsIdentifier() != "override") { continue; }
|
||||||
|
|
||||||
|
if (subElement.GetAttributeBool("iscjk", false))
|
||||||
|
{
|
||||||
|
return new ScalableFont(subElement, GameMain.Instance.GraphicsDevice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetFontFilePath(ContentXElement element)
|
||||||
|
{
|
||||||
|
foreach (var subElement in element.Elements())
|
||||||
|
{
|
||||||
|
if (!subElement.Name.ToString().Equals("override", StringComparison.OrdinalIgnoreCase)) { continue; }
|
||||||
|
if (GameSettings.CurrentConfig.Language == subElement.GetAttributeIdentifier("language", "").ToLanguageIdentifier())
|
||||||
|
{
|
||||||
|
return subElement.GetAttributeContentPath("file")?.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return element.GetAttributeContentPath("file")?.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private uint GetFontSize(XElement element, uint defaultSize = 14)
|
||||||
|
{
|
||||||
|
//check if any of the language override fonts want to override the font size as well
|
||||||
|
foreach (var subElement in element.Elements())
|
||||||
|
{
|
||||||
|
if (!subElement.Name.ToString().Equals("override", StringComparison.OrdinalIgnoreCase)) { continue; }
|
||||||
|
if (GameSettings.CurrentConfig.Language == subElement.GetAttributeIdentifier("language", "").ToLanguageIdentifier())
|
||||||
|
{
|
||||||
|
uint overrideFontSize = GetFontSize(subElement, 0);
|
||||||
|
if (overrideFontSize > 0) { return (uint)Math.Round(overrideFontSize * GameSettings.CurrentConfig.Graphics.TextScale); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var subElement in element.Elements())
|
||||||
|
{
|
||||||
|
if (!subElement.Name.ToString().Equals("size", StringComparison.OrdinalIgnoreCase)) { continue; }
|
||||||
|
Point maxResolution = subElement.GetAttributePoint("maxresolution", new Point(int.MaxValue, int.MaxValue));
|
||||||
|
if (GameMain.GraphicsWidth <= maxResolution.X && GameMain.GraphicsHeight <= maxResolution.Y)
|
||||||
|
{
|
||||||
|
return (uint)Math.Round(subElement.GetAttributeInt("size", 14) * GameSettings.CurrentConfig.Graphics.TextScale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (uint)Math.Round(defaultSize * GameSettings.CurrentConfig.Graphics.TextScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool GetFontDynamicLoading(XElement element)
|
||||||
|
{
|
||||||
|
foreach (var subElement in element.Elements())
|
||||||
|
{
|
||||||
|
if (!subElement.Name.ToString().Equals("override", StringComparison.OrdinalIgnoreCase)) { continue; }
|
||||||
|
if (GameSettings.CurrentConfig.Language == subElement.GetAttributeIdentifier("language", "").ToLanguageIdentifier())
|
||||||
|
{
|
||||||
|
return subElement.GetAttributeBool("dynamicloading", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return element.GetAttributeBool("dynamicloading", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool GetIsCJK(XElement element)
|
||||||
|
{
|
||||||
|
foreach (var subElement in element.Elements())
|
||||||
|
{
|
||||||
|
if (!subElement.Name.ToString().Equals("override", StringComparison.OrdinalIgnoreCase)) { continue; }
|
||||||
|
if (GameSettings.CurrentConfig.Language == subElement.GetAttributeIdentifier("language", "").ToLanguageIdentifier())
|
||||||
|
{
|
||||||
|
return subElement.GetAttributeBool("iscjk", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return element.GetAttributeBool("iscjk", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GUIFont : GUISelector<GUIFontPrefab>
|
||||||
|
{
|
||||||
|
public GUIFont(string identifier) : base(identifier) { }
|
||||||
|
|
||||||
|
public bool HasValue => Prefabs.Any();
|
||||||
|
|
||||||
|
public ScalableFont Value => Prefabs.ActivePrefab.Font;
|
||||||
|
|
||||||
|
public static implicit operator ScalableFont(GUIFont reference) => reference.Value;
|
||||||
|
|
||||||
|
public bool ForceUpperCase => HasValue && Value.ForceUpperCase;
|
||||||
|
|
||||||
|
public uint Size => HasValue ? Value.Size : 0;
|
||||||
|
|
||||||
|
private ScalableFont GetFontForStr(LocalizedString str) => GetFontForStr(str.Value);
|
||||||
|
|
||||||
|
private ScalableFont GetFontForStr(string str) =>
|
||||||
|
TextManager.IsCJK(str) ? Prefabs.ActivePrefab.CjkFont : Prefabs.ActivePrefab.Font;
|
||||||
|
|
||||||
|
public void DrawString(SpriteBatch sb, LocalizedString text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects se, float layerDepth)
|
||||||
|
{
|
||||||
|
DrawString(sb, text.Value, position, color, rotation, origin, scale, se, layerDepth);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DrawString(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects se, float layerDepth)
|
||||||
|
{
|
||||||
|
GetFontForStr(text).DrawString(sb, text, position, color, rotation, origin, scale, se, layerDepth);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DrawString(SpriteBatch sb, LocalizedString text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects se, float layerDepth, Alignment alignment = Alignment.TopLeft)
|
||||||
|
{
|
||||||
|
DrawString(sb, text.Value, position, color, rotation, origin, scale, se, layerDepth, alignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DrawString(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects se, float layerDepth, Alignment alignment = Alignment.TopLeft, ForceUpperCase forceUpperCase = Barotrauma.ForceUpperCase.Inherit)
|
||||||
|
{
|
||||||
|
GetFontForStr(text).DrawString(sb, text, position, color, rotation, origin, scale, se, layerDepth, alignment, forceUpperCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DrawString(SpriteBatch sb, LocalizedString text, Vector2 position, Color color, ForceUpperCase forceUpperCase = Barotrauma.ForceUpperCase.Inherit, bool italics = false)
|
||||||
|
{
|
||||||
|
DrawString(sb, text.Value, position, color, forceUpperCase, italics);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DrawString(SpriteBatch sb, string text, Vector2 position, Color color, ForceUpperCase forceUpperCase = Barotrauma.ForceUpperCase.Inherit, bool italics = false)
|
||||||
|
{
|
||||||
|
GetFontForStr(text).DrawString(sb, text, position, color, forceUpperCase, italics);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DrawStringWithColors(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects se, float layerDepth, in ImmutableArray<RichTextData>? richTextData, int rtdOffset = 0, Alignment alignment = Alignment.TopLeft, ForceUpperCase forceUpperCase = Barotrauma.ForceUpperCase.Inherit)
|
||||||
|
{
|
||||||
|
GetFontForStr(text).DrawStringWithColors(sb, text, position, color, rotation, origin, scale, se, layerDepth, richTextData, rtdOffset, alignment, forceUpperCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2 MeasureString(LocalizedString str, bool removeExtraSpacing = false)
|
||||||
|
{
|
||||||
|
return GetFontForStr(str).MeasureString(str, removeExtraSpacing);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2 MeasureChar(char c)
|
||||||
|
{
|
||||||
|
return GetFontForStr($"{c}").MeasureChar(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string WrapText(string text, float width)
|
||||||
|
=> GetFontForStr(text).WrapText(text, width);
|
||||||
|
|
||||||
|
public string WrapText(string text, float width, int requestCharPos, out Vector2 requestedCharPos)
|
||||||
|
=> GetFontForStr(text).WrapText(text, width, requestCharPos, out requestedCharPos);
|
||||||
|
|
||||||
|
public string WrapText(string text, float width, out Vector2[] allCharPositions)
|
||||||
|
=> GetFontForStr(text).WrapText(text, width, out allCharPositions);
|
||||||
|
|
||||||
|
public float LineHeight => Value.LineHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GUIColorPrefab : GUIPrefab
|
||||||
|
{
|
||||||
|
public readonly Color Color;
|
||||||
|
|
||||||
|
public GUIColorPrefab(ContentXElement element, UIStyleFile file) : base(element, file)
|
||||||
|
{
|
||||||
|
Color = element.GetAttributeColor("color", Color.White);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Dispose() { }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GUIColor : GUISelector<GUIColorPrefab>
|
||||||
|
{
|
||||||
|
public GUIColor(string identifier) : base(identifier) { }
|
||||||
|
|
||||||
|
public Color Value
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Prefabs.ActivePrefab.Color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator Color(GUIColor reference) => reference.Value;
|
||||||
|
|
||||||
|
public static Color operator*(GUIColor value, float scale)
|
||||||
|
{
|
||||||
|
return value.Value * scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GUISpritePrefab : GUIPrefab
|
||||||
|
{
|
||||||
|
public readonly UISprite Sprite;
|
||||||
|
|
||||||
|
public GUISpritePrefab(ContentXElement element, UIStyleFile file) : base(element, file)
|
||||||
|
{
|
||||||
|
Sprite = new UISprite(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
Sprite.Sprite.Remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GUISprite : GUISelector<GUISpritePrefab>
|
||||||
|
{
|
||||||
|
public GUISprite(string identifier) : base(identifier) { }
|
||||||
|
|
||||||
|
public UISprite Value
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Prefabs.ActivePrefab.Sprite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator UISprite(GUISprite reference) => reference.Value;
|
||||||
|
|
||||||
|
public void Draw(SpriteBatch spriteBatch, Rectangle rect, Color color, SpriteEffects spriteEffects = SpriteEffects.None)
|
||||||
|
{
|
||||||
|
Value.Draw(spriteBatch, rect, color, spriteEffects);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GUISpriteSheetPrefab : GUIPrefab
|
||||||
|
{
|
||||||
|
public readonly SpriteSheet SpriteSheet;
|
||||||
|
|
||||||
|
public GUISpriteSheetPrefab(ContentXElement element, UIStyleFile file) : base(element, file)
|
||||||
|
{
|
||||||
|
SpriteSheet = new SpriteSheet(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
SpriteSheet.Remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GUISpriteSheet : GUISelector<GUISpriteSheetPrefab>
|
||||||
|
{
|
||||||
|
public GUISpriteSheet(string identifier) : base(identifier) { }
|
||||||
|
|
||||||
|
public SpriteSheet Value
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Prefabs.ActivePrefab.SpriteSheet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int FrameCount => Value.FrameCount;
|
||||||
|
public Point FrameSize => Value.FrameSize;
|
||||||
|
|
||||||
|
public void Draw(ISpriteBatch spriteBatch, Vector2 pos, float rotate = 0, float scale = 1, SpriteEffects spriteEffects = SpriteEffects.None)
|
||||||
|
{
|
||||||
|
Value.Draw(spriteBatch, pos, rotate, scale, spriteEffects);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Draw(ISpriteBatch spriteBatch, Vector2 pos, Color color, Vector2 origin, float rotate = 0, float scale = 1, SpriteEffects spriteEffects = SpriteEffects.None, float? depth = null)
|
||||||
|
{
|
||||||
|
Value.Draw(spriteBatch, pos, color, origin, rotate, scale, spriteEffects, depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Draw(ISpriteBatch spriteBatch, int spriteIndex, Vector2 pos, Color color, Vector2 origin, float rotate, Vector2 scale, SpriteEffects spriteEffects = SpriteEffects.None, float? depth = null)
|
||||||
|
{
|
||||||
|
Value.Draw(spriteBatch, spriteIndex, pos, color, origin, rotate, scale, spriteEffects, depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator SpriteSheet(GUISpriteSheet reference) => reference.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GUICursorPrefab : GUIPrefab
|
||||||
|
{
|
||||||
|
public readonly Sprite[] Sprites;
|
||||||
|
|
||||||
|
public GUICursorPrefab(ContentXElement element, UIStyleFile file) : base(element, file)
|
||||||
|
{
|
||||||
|
Sprites = new Sprite[Enum.GetValues(typeof(CursorState)).Length];
|
||||||
|
foreach (var subElement in element.Elements())
|
||||||
|
{
|
||||||
|
CursorState state = subElement.GetAttributeEnum("state", CursorState.Default);
|
||||||
|
Sprites[(int)state] = new Sprite(subElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
foreach (var sprite in Sprites)
|
||||||
|
{
|
||||||
|
sprite?.Remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GUICursor : GUISelector<GUICursorPrefab>
|
||||||
|
{
|
||||||
|
public GUICursor(string identifier) : base(identifier) { }
|
||||||
|
|
||||||
|
public Sprite this[CursorState k] => Prefabs.ActivePrefab.Sprites[(int)k];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -47,9 +47,9 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
isHorizontal = (Rect.Width > Rect.Height);
|
isHorizontal = (Rect.Width > Rect.Height);
|
||||||
frame = new GUIFrame(new RectTransform(Vector2.One, rectT));
|
frame = new GUIFrame(new RectTransform(Vector2.One, rectT));
|
||||||
GUI.Style.Apply(frame, "", this);
|
GUIStyle.Apply(frame, "", this);
|
||||||
slider = new GUIFrame(new RectTransform(Vector2.One, rectT));
|
slider = new GUIFrame(new RectTransform(Vector2.One, rectT));
|
||||||
GUI.Style.Apply(slider, "Slider", this);
|
GUIStyle.Apply(slider, "Slider", this);
|
||||||
this.showFrame = showFrame;
|
this.showFrame = showFrame;
|
||||||
this.barSize = barSize;
|
this.barSize = barSize;
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
@@ -62,10 +62,10 @@ namespace Barotrauma
|
|||||||
public Rectangle GetSliderRect(float fillAmount)
|
public Rectangle GetSliderRect(float fillAmount)
|
||||||
{
|
{
|
||||||
Rectangle sliderArea = new Rectangle(
|
Rectangle sliderArea = new Rectangle(
|
||||||
frame.Rect.X + (int)style.Padding.X,
|
frame.Rect.X + (int)Style.Padding.X,
|
||||||
frame.Rect.Y + (int)style.Padding.Y,
|
frame.Rect.Y + (int)Style.Padding.Y,
|
||||||
(int)(frame.Rect.Width - style.Padding.X - style.Padding.Z),
|
(int)(frame.Rect.Width - Style.Padding.X - Style.Padding.Z),
|
||||||
(int)(frame.Rect.Height - style.Padding.Y - style.Padding.W));
|
(int)(frame.Rect.Height - Style.Padding.Y - Style.Padding.W));
|
||||||
|
|
||||||
Vector4 sliceBorderSizes = Vector4.Zero;
|
Vector4 sliceBorderSizes = Vector4.Zero;
|
||||||
if (slider.sprites.ContainsKey(slider.State) && (slider.sprites[slider.State].First()?.Slice ?? false))
|
if (slider.sprites.ContainsKey(slider.State) && (slider.sprites[slider.State].First()?.Slice ?? false))
|
||||||
@@ -116,10 +116,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
var sliderRect = GetSliderRect(barSize);
|
var sliderRect = GetSliderRect(barSize);
|
||||||
|
|
||||||
slider.RectTransform.AbsoluteOffset = new Point((int)style.Padding.X, (int)style.Padding.Y);
|
slider.RectTransform.AbsoluteOffset = new Point((int)Style.Padding.X, (int)Style.Padding.Y);
|
||||||
slider.RectTransform.MaxSize = new Point(
|
slider.RectTransform.MaxSize = new Point(
|
||||||
(int)(Rect.Width - style.Padding.X + style.Padding.Z),
|
(int)(Rect.Width - Style.Padding.X + Style.Padding.Z),
|
||||||
(int)(Rect.Height - style.Padding.Y + style.Padding.W));
|
(int)(Rect.Height - Style.Padding.Y + Style.Padding.W));
|
||||||
frame.Visible = showFrame;
|
frame.Visible = showFrame;
|
||||||
slider.Visible = BarSize > 0.0f;
|
slider.Visible = BarSize > 0.0f;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using Barotrauma.Extensions;
|
using Barotrauma.Extensions;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
@@ -29,7 +28,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public bool IsBooleanSwitch;
|
public bool IsBooleanSwitch;
|
||||||
|
|
||||||
public override string ToolTip
|
public override RichString ToolTip
|
||||||
{
|
{
|
||||||
get { return base.ToolTip; }
|
get { return base.ToolTip; }
|
||||||
set
|
set
|
||||||
@@ -203,7 +202,7 @@ namespace Barotrauma
|
|||||||
CanBeFocused = true;
|
CanBeFocused = true;
|
||||||
this.isHorizontal = isHorizontal ?? (Rect.Width > Rect.Height);
|
this.isHorizontal = isHorizontal ?? (Rect.Width > Rect.Height);
|
||||||
Frame = new GUIFrame(new RectTransform(Vector2.One, rectT));
|
Frame = new GUIFrame(new RectTransform(Vector2.One, rectT));
|
||||||
GUI.Style.Apply(Frame, IsHorizontal ? "GUIFrameHorizontal" : "GUIFrameVertical", this);
|
GUIStyle.Apply(Frame, IsHorizontal ? "GUIFrameHorizontal" : "GUIFrameVertical", this);
|
||||||
this.barSize = barSize;
|
this.barSize = barSize;
|
||||||
|
|
||||||
Bar = new GUIButton(new RectTransform(Vector2.One, rectT, IsHorizontal ? Anchor.CenterLeft : Anchor.TopCenter), color: color, style: null);
|
Bar = new GUIButton(new RectTransform(Vector2.One, rectT, IsHorizontal ? Anchor.CenterLeft : Anchor.TopCenter), color: color, style: null);
|
||||||
@@ -224,7 +223,7 @@ namespace Barotrauma
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
GUI.Style.Apply(Bar, IsHorizontal ? "GUIButtonHorizontal" : "GUIButtonVertical", this);
|
GUIStyle.Apply(Bar, IsHorizontal ? "GUIButtonHorizontal" : "GUIButtonVertical", this);
|
||||||
Bar.OnPressed = SelectBar;
|
Bar.OnPressed = SelectBar;
|
||||||
enabled = true;
|
enabled = true;
|
||||||
UpdateRect();
|
UpdateRect();
|
||||||
@@ -313,6 +312,7 @@ namespace Barotrauma
|
|||||||
MoveButton(new Vector2(
|
MoveButton(new Vector2(
|
||||||
Math.Sign(PlayerInput.MousePosition.X - Bar.Rect.Center.X) * Bar.Rect.Width * barScale,
|
Math.Sign(PlayerInput.MousePosition.X - Bar.Rect.Center.X) * Bar.Rect.Width * barScale,
|
||||||
Math.Sign(PlayerInput.MousePosition.Y - Bar.Rect.Center.Y) * Bar.Rect.Height * barScale));
|
Math.Sign(PlayerInput.MousePosition.Y - Bar.Rect.Center.Y) * Bar.Rect.Height * barScale));
|
||||||
|
OnReleased?.Invoke(this, BarScroll);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,523 +1,202 @@
|
|||||||
using Barotrauma.Extensions;
|
using System;
|
||||||
|
using Barotrauma.Extensions;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using System.Collections.Immutable;
|
||||||
using System;
|
using System.Linq;
|
||||||
using System.Collections.Generic;
|
using System.Reflection;
|
||||||
using System.Xml.Linq;
|
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
public class GUIStyle
|
public static class GUIStyle
|
||||||
{
|
{
|
||||||
private Dictionary<string, GUIComponentStyle> componentStyles;
|
public readonly static ImmutableDictionary<Identifier, GUIFont> Fonts;
|
||||||
|
public readonly static ImmutableDictionary<Identifier, GUISprite> Sprites;
|
||||||
private readonly XElement configElement;
|
public readonly static ImmutableDictionary<Identifier, GUISpriteSheet> SpriteSheets;
|
||||||
|
public readonly static ImmutableDictionary<Identifier, GUIColor> Colors;
|
||||||
private GraphicsDevice graphicsDevice;
|
static GUIStyle()
|
||||||
|
|
||||||
private ScalableFont defaultFont;
|
|
||||||
|
|
||||||
public ScalableFont Font { get; private set; }
|
|
||||||
public ScalableFont GlobalFont { get; private set; }
|
|
||||||
public ScalableFont UnscaledSmallFont { get; private set; }
|
|
||||||
public ScalableFont SmallFont { get; private set; }
|
|
||||||
public ScalableFont LargeFont { get; private set; }
|
|
||||||
public ScalableFont SubHeadingFont { get; private set; }
|
|
||||||
public ScalableFont DigitalFont { get; private set; }
|
|
||||||
public ScalableFont HotkeyFont { get; private set; }
|
|
||||||
public ScalableFont MonospacedFont { get; private set; }
|
|
||||||
|
|
||||||
public Dictionary<ScalableFont, bool> ForceFontUpperCase
|
|
||||||
{
|
{
|
||||||
get;
|
var guiClassProperties = typeof(GUIStyle).GetFields(BindingFlags.Public | BindingFlags.Static);
|
||||||
private set;
|
|
||||||
} = new Dictionary<ScalableFont, bool>();
|
|
||||||
|
|
||||||
public readonly Sprite[] CursorSprite = new Sprite[7];
|
ImmutableDictionary<Identifier, T> getPropertiesOfType<T>() where T : class
|
||||||
|
{
|
||||||
|
return guiClassProperties
|
||||||
|
.Where(p => p.FieldType == typeof(T))
|
||||||
|
.Select(p => (p.Name.ToIdentifier(), p.GetValue(null) as T))
|
||||||
|
.ToImmutableDictionary();
|
||||||
|
}
|
||||||
|
|
||||||
public UISprite RadiationSprite { get; private set; }
|
Fonts = getPropertiesOfType<GUIFont>();
|
||||||
public SpriteSheet RadiationAnimSpriteSheet { get; private set; }
|
Sprites = getPropertiesOfType<GUISprite>();
|
||||||
|
SpriteSheets = getPropertiesOfType<GUISpriteSheet>();
|
||||||
|
Colors = getPropertiesOfType<GUIColor>();
|
||||||
|
}
|
||||||
|
|
||||||
public SpriteSheet SavingIndicator { get; private set; }
|
public readonly static PrefabCollection<GUIComponentStyle> ComponentStyles = new PrefabCollection<GUIComponentStyle>();
|
||||||
|
|
||||||
public UISprite UIGlow { get; private set; }
|
public readonly static GUIFont Font = new GUIFont("Font");
|
||||||
|
public readonly static GUIFont GlobalFont = new GUIFont("GlobalFont");
|
||||||
|
public readonly static GUIFont UnscaledSmallFont = new GUIFont("UnscaledSmallFont");
|
||||||
|
public readonly static GUIFont SmallFont = new GUIFont("SmallFont");
|
||||||
|
public readonly static GUIFont LargeFont = new GUIFont("LargeFont");
|
||||||
|
public readonly static GUIFont SubHeadingFont = new GUIFont("SubHeadingFont");
|
||||||
|
public readonly static GUIFont DigitalFont = new GUIFont("DigitalFont");
|
||||||
|
public readonly static GUIFont HotkeyFont = new GUIFont("HotkeyFont");
|
||||||
|
public readonly static GUIFont MonospacedFont = new GUIFont("MonospacedFont");
|
||||||
|
|
||||||
public UISprite PingCircle { get; private set; }
|
public readonly static GUICursor CursorSprite = new GUICursor("Cursor");
|
||||||
|
|
||||||
public UISprite YouAreHereCircle { get; private set; }
|
public readonly static GUISprite SubmarineLocationIcon = new GUISprite("SubmarineLocationIcon");
|
||||||
|
public readonly static GUISprite Arrow = new GUISprite("Arrow");
|
||||||
|
public readonly static GUISprite SpeechBubbleIcon = new GUISprite("SpeechBubbleIcon");
|
||||||
|
public readonly static GUISprite BrokenIcon = new GUISprite("BrokenIcon");
|
||||||
|
public readonly static GUISprite YouAreHereCircle = new GUISprite("YouAreHereCircle");
|
||||||
|
|
||||||
public UISprite UIGlowCircular { get; private set; }
|
public readonly static GUISprite Radiation = new GUISprite("Radiation");
|
||||||
|
public readonly static GUISpriteSheet RadiationAnimSpriteSheet = new GUISpriteSheet("RadiationAnimSpriteSheet");
|
||||||
|
|
||||||
public UISprite UIGlowSolidCircular { get; private set; }
|
public readonly static GUISpriteSheet SavingIndicator = new GUISpriteSheet("SavingIndicator");
|
||||||
public UISprite UIThermalGlow { get; private set; }
|
public readonly static GUISpriteSheet GenericThrobber = new GUISpriteSheet("GenericThrobber");
|
||||||
|
|
||||||
public UISprite ButtonPulse { get; private set; }
|
public readonly static GUISprite UIGlow = new GUISprite("UIGlow");
|
||||||
|
public readonly static GUISprite TalentGlow = new GUISprite("TalentGlow");
|
||||||
|
public readonly static GUISprite PingCircle = new GUISprite("PingCircle");
|
||||||
|
public readonly static GUISprite UIGlowCircular = new GUISprite("UIGlowCircular");
|
||||||
|
public readonly static GUISprite UIGlowSolidCircular = new GUISprite("UIGlowSolidCircular");
|
||||||
|
public readonly static GUISprite UIThermalGlow = new GUISprite("UIGlowSolidCircular");
|
||||||
|
public readonly static GUISprite ButtonPulse = new GUISprite("ButtonPulse");
|
||||||
|
public readonly static GUISprite WalletPortraitBG = new GUISprite("WalletPortraitBG");
|
||||||
|
public readonly static GUISprite CrewWalletIconSmall = new GUISprite("CrewWalletIconSmall");
|
||||||
|
|
||||||
public SpriteSheet FocusIndicator { get; private set; }
|
public readonly static GUISprite EndRoundButtonPulse = new GUISprite("EndRoundButtonPulse");
|
||||||
|
|
||||||
public UISprite IconOverflowIndicator { get; private set; }
|
public readonly static GUISpriteSheet FocusIndicator = new GUISpriteSheet("FocusIndicator");
|
||||||
|
|
||||||
|
public readonly static GUISprite IconOverflowIndicator = new GUISprite("IconOverflowIndicator");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// General green color used for elements whose colors are set from code
|
/// General green color used for elements whose colors are set from code
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Color Green { get; private set; } = Color.LightGreen;
|
public readonly static GUIColor Green = new GUIColor("Green");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// General red color used for elements whose colors are set from code
|
/// General red color used for elements whose colors are set from code
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Color Orange { get; private set; } = Color.Orange;
|
public readonly static GUIColor Orange = new GUIColor("Orange");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// General red color used for elements whose colors are set from code
|
/// General red color used for elements whose colors are set from code
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Color Red { get; private set; } = Color.Red;
|
public readonly static GUIColor Red = new GUIColor("Red");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// General blue color used for elements whose colors are set from code
|
/// General blue color used for elements whose colors are set from code
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Color Blue { get; private set; } = Color.Blue;
|
public readonly static GUIColor Blue = new GUIColor("Blue");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// General yellow color used for elements whose colors are set from code
|
/// General yellow color used for elements whose colors are set from code
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Color Yellow { get; private set; } = Color.Yellow;
|
public readonly static GUIColor Yellow = new GUIColor("Yellow");
|
||||||
|
|
||||||
public Color ColorInventoryEmpty { get; private set; } = Color.Red;
|
/// <summary>
|
||||||
public Color ColorInventoryHalf { get; private set; } = Color.Orange;
|
/// Color to display the name of modded servers in the server list.
|
||||||
public Color ColorInventoryFull { get; private set; } = Color.LightGreen;
|
/// </summary>
|
||||||
public Color ColorInventoryBackground { get; private set; } = Color.Gray;
|
public readonly static GUIColor ModdedServerColor = new GUIColor("ModdedServerColor");
|
||||||
public Color ColorInventoryEmptyOverlay { get; private set; } = Color.Red;
|
|
||||||
|
|
||||||
public Color TextColor { get; private set; } = Color.White * 0.8f;
|
public readonly static GUIColor ColorInventoryEmpty = new GUIColor("ColorInventoryEmpty");
|
||||||
public Color TextColorBright { get; private set; } = Color.White * 0.9f;
|
public readonly static GUIColor ColorInventoryHalf = new GUIColor("ColorInventoryHalf");
|
||||||
public Color TextColorDark { get; private set; } = Color.Black * 0.9f;
|
public readonly static GUIColor ColorInventoryFull = new GUIColor("ColorInventoryFull");
|
||||||
public Color TextColorDim { get; private set; } = Color.White * 0.6f;
|
public readonly static GUIColor ColorInventoryBackground = new GUIColor("ColorInventoryBackground");
|
||||||
|
public readonly static GUIColor ColorInventoryEmptyOverlay = new GUIColor("ColorInventoryEmptyOverlay");
|
||||||
|
|
||||||
public Color ItemQualityColorPoor { get; private set; } = Color.DarkRed;
|
public readonly static GUIColor TextColorNormal = new GUIColor("TextColorNormal");
|
||||||
public Color ItemQualityColorNormal { get; private set; } = Color.Gray;
|
public readonly static GUIColor TextColorBright = new GUIColor("TextColorBright");
|
||||||
public Color ItemQualityColorGood { get; private set; } = Color.LightGreen;
|
public readonly static GUIColor TextColorDark = new GUIColor("TextColorDark");
|
||||||
public Color ItemQualityColorExcellent { get; private set; } = Color.LightBlue;
|
public readonly static GUIColor TextColorDim = new GUIColor("TextColorDim");
|
||||||
public Color ItemQualityColorMasterwork { get; private set; } = Color.MediumPurple;
|
|
||||||
|
|
||||||
public Color ColorReputationVeryLow { get; private set; } = Color.Red;
|
public readonly static GUIColor ItemQualityColorPoor = new GUIColor("ItemQualityColorPoor");
|
||||||
public Color ColorReputationLow { get; private set; } = Color.Orange;
|
public readonly static GUIColor ItemQualityColorNormal = new GUIColor("ItemQualityColorNormal");
|
||||||
public Color ColorReputationNeutral { get; private set; } = Color.White * 0.8f;
|
public readonly static GUIColor ItemQualityColorGood = new GUIColor("ItemQualityColorGood");
|
||||||
public Color ColorReputationHigh { get; private set; } = Color.LightBlue;
|
public readonly static GUIColor ItemQualityColorExcellent = new GUIColor("ItemQualityColorExcellent");
|
||||||
public Color ColorReputationVeryHigh { get; private set; } = Color.Blue;
|
public readonly static GUIColor ItemQualityColorMasterwork = new GUIColor("ItemQualityColorMasterwork");
|
||||||
|
|
||||||
|
public readonly static GUIColor ColorReputationVeryLow = new GUIColor("ColorReputationVeryLow");
|
||||||
|
public readonly static GUIColor ColorReputationLow = new GUIColor("ColorReputationLow");
|
||||||
|
public readonly static GUIColor ColorReputationNeutral = new GUIColor("ColorReputationNeutral");
|
||||||
|
public readonly static GUIColor ColorReputationHigh = new GUIColor("ColorReputationHigh");
|
||||||
|
public readonly static GUIColor ColorReputationVeryHigh = new GUIColor("ColorReputationVeryHigh");
|
||||||
|
|
||||||
// Inventory
|
// Inventory
|
||||||
public Color EquipmentSlotIconColor { get; private set; } = new Color(99, 70, 64);
|
public readonly static GUIColor EquipmentSlotIconColor = new GUIColor("EquipmentSlotIconColor");
|
||||||
|
|
||||||
// Health HUD
|
// Health HUD
|
||||||
public Color BuffColorLow { get; private set; } = Color.LightGreen;
|
public readonly static GUIColor BuffColorLow = new GUIColor("BuffColorLow");
|
||||||
public Color BuffColorMedium { get; private set; } = Color.Green;
|
public readonly static GUIColor BuffColorMedium = new GUIColor("BuffColorMedium");
|
||||||
public Color BuffColorHigh { get; private set; } = Color.DarkGreen;
|
public readonly static GUIColor BuffColorHigh = new GUIColor("BuffColorHigh");
|
||||||
|
|
||||||
public Color DebuffColorLow { get; private set; } = Color.DarkSalmon;
|
public readonly static GUIColor DebuffColorLow = new GUIColor("DebuffColorLow");
|
||||||
public Color DebuffColorMedium { get; private set; } = Color.Red;
|
public readonly static GUIColor DebuffColorMedium = new GUIColor("DebuffColorMedium");
|
||||||
public Color DebuffColorHigh { get; private set; } = Color.DarkRed;
|
public readonly static GUIColor DebuffColorHigh = new GUIColor("DebuffColorHigh");
|
||||||
|
|
||||||
public Color HealthBarColorLow { get; private set; } = Color.Red;
|
public readonly static GUIColor HealthBarColorLow = new GUIColor("HealthBarColorLow");
|
||||||
public Color HealthBarColorMedium { get; private set; } = Color.Orange;
|
public readonly static GUIColor HealthBarColorMedium = new GUIColor("HealthBarColorMedium");
|
||||||
public Color HealthBarColorHigh { get; private set; } = new Color(78, 114, 88);
|
public readonly static GUIColor HealthBarColorHigh = new GUIColor("HealthBarColorHigh");
|
||||||
|
|
||||||
public Color EquipmentIndicatorNotEquipped { get; private set; } = Color.Gray;
|
public readonly static GUIColor EquipmentIndicatorNotEquipped = new GUIColor("EquipmentIndicatorNotEquipped");
|
||||||
public Color EquipmentIndicatorEquipped { get; private set; } = new Color(105, 202, 125);
|
public readonly static GUIColor EquipmentIndicatorEquipped = new GUIColor("EquipmentIndicatorEquipped");
|
||||||
public Color EquipmentIndicatorRunningOut { get; private set; } = new Color(202, 105, 105);
|
public readonly static GUIColor EquipmentIndicatorRunningOut = new GUIColor("EquipmentIndicatorRunningOut");
|
||||||
|
|
||||||
public static Point ItemFrameMargin => new Point(50, 56).Multiply(GUI.SlicedSpriteScale);
|
public static Point ItemFrameMargin => new Point(50, 56).Multiply(GUI.SlicedSpriteScale);
|
||||||
public static Point ItemFrameOffset => new Point(0, 3).Multiply(GUI.SlicedSpriteScale);
|
public static Point ItemFrameOffset => new Point(0, 3).Multiply(GUI.SlicedSpriteScale);
|
||||||
|
|
||||||
public GUIStyle(XElement element, GraphicsDevice graphicsDevice)
|
public static GUIComponentStyle GetComponentStyle(string name)
|
||||||
|
=> ComponentStyles.ContainsKey(name) ? ComponentStyles[name] : null;
|
||||||
|
|
||||||
|
public static void Apply(GUIComponent targetComponent, string styleName = "", GUIComponent parent = null)
|
||||||
{
|
{
|
||||||
this.graphicsDevice = graphicsDevice;
|
Apply(targetComponent, styleName.ToIdentifier(), parent);
|
||||||
componentStyles = new Dictionary<string, GUIComponentStyle>();
|
|
||||||
configElement = element;
|
|
||||||
foreach (XElement subElement in configElement.Elements())
|
|
||||||
{
|
|
||||||
var name = subElement.Name.ToString().ToLowerInvariant();
|
|
||||||
switch (name)
|
|
||||||
{
|
|
||||||
case "cursor":
|
|
||||||
if (subElement.HasElements)
|
|
||||||
{
|
|
||||||
foreach (var children in subElement.Descendants())
|
|
||||||
{
|
|
||||||
var index = children.GetAttributeInt("state", (int)CursorState.Default);
|
|
||||||
CursorSprite[index] = new Sprite(children);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CursorSprite[(int)CursorState.Default] = new Sprite(subElement);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "green":
|
|
||||||
Green = subElement.GetAttributeColor("color", Green);
|
|
||||||
break;
|
|
||||||
case "orange":
|
|
||||||
Orange = subElement.GetAttributeColor("color", Orange);
|
|
||||||
break;
|
|
||||||
case "red":
|
|
||||||
Red = subElement.GetAttributeColor("color", Red);
|
|
||||||
break;
|
|
||||||
case "blue":
|
|
||||||
Blue = subElement.GetAttributeColor("color", Blue);
|
|
||||||
break;
|
|
||||||
case "yellow":
|
|
||||||
Yellow = subElement.GetAttributeColor("color", Yellow);
|
|
||||||
break;
|
|
||||||
case "colorinventoryempty":
|
|
||||||
ColorInventoryEmpty = subElement.GetAttributeColor("color", ColorInventoryEmpty);
|
|
||||||
break;
|
|
||||||
case "colorinventoryhalf":
|
|
||||||
ColorInventoryHalf = subElement.GetAttributeColor("color", ColorInventoryHalf);
|
|
||||||
break;
|
|
||||||
case "colorinventoryfull":
|
|
||||||
ColorInventoryFull = subElement.GetAttributeColor("color", ColorInventoryFull);
|
|
||||||
break;
|
|
||||||
case "colorinventorybackground":
|
|
||||||
ColorInventoryBackground = subElement.GetAttributeColor("color", ColorInventoryBackground);
|
|
||||||
break;
|
|
||||||
case "colorinventoryemptyoverlay":
|
|
||||||
ColorInventoryEmptyOverlay = subElement.GetAttributeColor("color", ColorInventoryEmptyOverlay);
|
|
||||||
break;
|
|
||||||
case "textcolordark":
|
|
||||||
TextColorDark = subElement.GetAttributeColor("color", TextColorDark);
|
|
||||||
break;
|
|
||||||
case "textcolorbright":
|
|
||||||
TextColorBright = subElement.GetAttributeColor("color", TextColorBright);
|
|
||||||
break;
|
|
||||||
case "textcolordim":
|
|
||||||
TextColorDim = subElement.GetAttributeColor("color", TextColorDim);
|
|
||||||
break;
|
|
||||||
case "textcolornormal":
|
|
||||||
case "textcolor":
|
|
||||||
TextColor = subElement.GetAttributeColor("color", TextColor);
|
|
||||||
break;
|
|
||||||
case "colorreputationverylow":
|
|
||||||
ColorReputationVeryLow = subElement.GetAttributeColor("color", TextColor);
|
|
||||||
break;
|
|
||||||
case "colorreputationlow":
|
|
||||||
ColorReputationLow = subElement.GetAttributeColor("color", TextColor);
|
|
||||||
break;
|
|
||||||
case "colorreputationneutral":
|
|
||||||
ColorReputationNeutral = subElement.GetAttributeColor("color", TextColor);
|
|
||||||
break;
|
|
||||||
case "colorreputationhigh":
|
|
||||||
ColorReputationHigh = subElement.GetAttributeColor("color", TextColor);
|
|
||||||
break;
|
|
||||||
case "colorreputationveryhigh":
|
|
||||||
ColorReputationVeryHigh = subElement.GetAttributeColor("color", TextColor);
|
|
||||||
break;
|
|
||||||
case "equipmentsloticoncolor":
|
|
||||||
EquipmentSlotIconColor = subElement.GetAttributeColor("color", EquipmentSlotIconColor);
|
|
||||||
break;
|
|
||||||
case "buffcolorlow":
|
|
||||||
BuffColorLow = subElement.GetAttributeColor("color", BuffColorLow);
|
|
||||||
break;
|
|
||||||
case "buffcolormedium":
|
|
||||||
BuffColorMedium = subElement.GetAttributeColor("color", BuffColorMedium);
|
|
||||||
break;
|
|
||||||
case "buffcolorhigh":
|
|
||||||
BuffColorHigh = subElement.GetAttributeColor("color", BuffColorHigh);
|
|
||||||
break;
|
|
||||||
case "debuffcolorlow":
|
|
||||||
DebuffColorLow = subElement.GetAttributeColor("color", DebuffColorLow);
|
|
||||||
break;
|
|
||||||
case "debuffcolormedium":
|
|
||||||
DebuffColorMedium = subElement.GetAttributeColor("color", DebuffColorMedium);
|
|
||||||
break;
|
|
||||||
case "debuffcolorhigh":
|
|
||||||
DebuffColorHigh = subElement.GetAttributeColor("color", DebuffColorHigh);
|
|
||||||
break;
|
|
||||||
case "healthbarcolorlow":
|
|
||||||
HealthBarColorLow = subElement.GetAttributeColor("color", HealthBarColorLow);
|
|
||||||
break;
|
|
||||||
case "healthbarcolormedium":
|
|
||||||
HealthBarColorMedium = subElement.GetAttributeColor("color", HealthBarColorMedium);
|
|
||||||
break;
|
|
||||||
case "healthbarcolorhigh":
|
|
||||||
HealthBarColorHigh = subElement.GetAttributeColor("color", HealthBarColorHigh);
|
|
||||||
break;
|
|
||||||
case "equipmentindicatornotequipped":
|
|
||||||
EquipmentIndicatorNotEquipped = subElement.GetAttributeColor("color", EquipmentIndicatorNotEquipped);
|
|
||||||
break;
|
|
||||||
case "equipmentindicatorequipped":
|
|
||||||
EquipmentIndicatorEquipped = subElement.GetAttributeColor("color", EquipmentIndicatorEquipped);
|
|
||||||
break;
|
|
||||||
case "equipmentindicatorrunningout":
|
|
||||||
EquipmentIndicatorRunningOut = subElement.GetAttributeColor("color", EquipmentIndicatorRunningOut);
|
|
||||||
break;
|
|
||||||
case "uiglow":
|
|
||||||
UIGlow = new UISprite(subElement);
|
|
||||||
break;
|
|
||||||
case "pingcircle":
|
|
||||||
PingCircle = new UISprite(subElement);
|
|
||||||
break;
|
|
||||||
case "youareherecircle":
|
|
||||||
YouAreHereCircle = new UISprite(subElement);
|
|
||||||
break;
|
|
||||||
case "radiation":
|
|
||||||
RadiationSprite = new UISprite(subElement);
|
|
||||||
break;
|
|
||||||
case "radiationanimspritesheet":
|
|
||||||
RadiationAnimSpriteSheet = new SpriteSheet(subElement);
|
|
||||||
break;
|
|
||||||
case "uiglowcircular":
|
|
||||||
UIGlowCircular = new UISprite(subElement);
|
|
||||||
break;
|
|
||||||
case "uiglowsolidcircular":
|
|
||||||
UIGlowSolidCircular = new UISprite(subElement);
|
|
||||||
break;
|
|
||||||
case "uithermalglow":
|
|
||||||
UIThermalGlow = new UISprite(subElement);
|
|
||||||
break;
|
|
||||||
case "endroundbuttonpulse":
|
|
||||||
ButtonPulse = new UISprite(subElement);
|
|
||||||
break;
|
|
||||||
case "iconoverflowindicator":
|
|
||||||
IconOverflowIndicator = new UISprite(subElement);
|
|
||||||
break;
|
|
||||||
case "focusindicator":
|
|
||||||
FocusIndicator = new SpriteSheet(subElement);
|
|
||||||
break;
|
|
||||||
case "savingindicator":
|
|
||||||
SavingIndicator = new SpriteSheet(subElement);
|
|
||||||
break;
|
|
||||||
case "font":
|
|
||||||
Font = LoadFont(subElement, graphicsDevice);
|
|
||||||
ForceFontUpperCase[Font] = subElement.GetAttributeBool("forceuppercase", false);
|
|
||||||
break;
|
|
||||||
case "globalfont":
|
|
||||||
GlobalFont = LoadFont(subElement, graphicsDevice);
|
|
||||||
ForceFontUpperCase[GlobalFont] = subElement.GetAttributeBool("forceuppercase", false);
|
|
||||||
break;
|
|
||||||
case "unscaledsmallfont":
|
|
||||||
UnscaledSmallFont = LoadFont(subElement, graphicsDevice);
|
|
||||||
ForceFontUpperCase[UnscaledSmallFont] = subElement.GetAttributeBool("forceuppercase", false);
|
|
||||||
break;
|
|
||||||
case "smallfont":
|
|
||||||
SmallFont = LoadFont(subElement, graphicsDevice);
|
|
||||||
ForceFontUpperCase[SmallFont] = subElement.GetAttributeBool("forceuppercase", false);
|
|
||||||
break;
|
|
||||||
case "largefont":
|
|
||||||
LargeFont = LoadFont(subElement, graphicsDevice);
|
|
||||||
ForceFontUpperCase[LargeFont] = subElement.GetAttributeBool("forceuppercase", false);
|
|
||||||
break;
|
|
||||||
case "digitalfont":
|
|
||||||
DigitalFont = LoadFont(subElement, graphicsDevice);
|
|
||||||
ForceFontUpperCase[DigitalFont] = subElement.GetAttributeBool("forceuppercase", false);
|
|
||||||
break;
|
|
||||||
case "monospacedfont":
|
|
||||||
MonospacedFont = LoadFont(subElement, graphicsDevice);
|
|
||||||
ForceFontUpperCase[MonospacedFont] = subElement.GetAttributeBool("forceuppercase", false);
|
|
||||||
break;
|
|
||||||
case "hotkeyfont":
|
|
||||||
HotkeyFont = LoadFont(subElement, graphicsDevice);
|
|
||||||
ForceFontUpperCase[HotkeyFont] = subElement.GetAttributeBool("forceuppercase", false);
|
|
||||||
break;
|
|
||||||
case "objectivetitle":
|
|
||||||
case "subheading":
|
|
||||||
SubHeadingFont = LoadFont(subElement, graphicsDevice);
|
|
||||||
ForceFontUpperCase[SubHeadingFont] = subElement.GetAttributeBool("forceuppercase", false);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
GUIComponentStyle componentStyle = new GUIComponentStyle(subElement, this);
|
|
||||||
componentStyles.Add(subElement.Name.ToString().ToLowerInvariant(), componentStyle);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GlobalFont == null)
|
|
||||||
{
|
|
||||||
GlobalFont = Font;
|
|
||||||
DebugConsole.NewMessage("Global font not defined in the current UI style file. The global font is used to render western symbols when using Chinese/Japanese/Korean localization. Using default font instead...", Color.Orange);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Needs to unregister if we ever remove GUIStyles.
|
|
||||||
GameMain.Instance.ResolutionChanged += RescaleElements;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public static void Apply(GUIComponent targetComponent, Identifier styleName, GUIComponent parent = null)
|
||||||
/// Returns the default font of the currently selected language
|
|
||||||
/// </summary>
|
|
||||||
public ScalableFont LoadCurrentDefaultFont()
|
|
||||||
{
|
|
||||||
defaultFont?.Dispose();
|
|
||||||
defaultFont = null;
|
|
||||||
foreach (XElement subElement in configElement.Elements())
|
|
||||||
{
|
|
||||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
|
||||||
{
|
|
||||||
case "font":
|
|
||||||
defaultFont = LoadFont(subElement, graphicsDevice);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return defaultFont;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void RescaleElements()
|
|
||||||
{
|
|
||||||
if (configElement == null) { return; }
|
|
||||||
if (configElement.Elements() == null) { return; }
|
|
||||||
foreach (XElement subElement in configElement.Elements())
|
|
||||||
{
|
|
||||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
|
||||||
{
|
|
||||||
case "font":
|
|
||||||
if (Font == null) { continue; }
|
|
||||||
Font.Size = GetFontSize(subElement);
|
|
||||||
break;
|
|
||||||
case "smallfont":
|
|
||||||
if (SmallFont == null) { continue; }
|
|
||||||
SmallFont.Size = GetFontSize(subElement);
|
|
||||||
break;
|
|
||||||
case "largefont":
|
|
||||||
if (LargeFont == null) { continue; }
|
|
||||||
LargeFont.Size = GetFontSize(subElement);
|
|
||||||
break;
|
|
||||||
case "hotkeyfont":
|
|
||||||
if (HotkeyFont == null) { continue; }
|
|
||||||
HotkeyFont.Size = GetFontSize(subElement);
|
|
||||||
break;
|
|
||||||
case "objectivetitle":
|
|
||||||
case "subheading":
|
|
||||||
if (SubHeadingFont == null) { continue; }
|
|
||||||
SubHeadingFont.Size = GetFontSize(subElement);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var componentStyle in componentStyles.Values)
|
|
||||||
{
|
|
||||||
componentStyle.GetSize(componentStyle.Element);
|
|
||||||
foreach (var childStyle in componentStyle.ChildStyles.Values)
|
|
||||||
{
|
|
||||||
childStyle.GetSize(childStyle.Element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ScalableFont LoadFont(XElement element, GraphicsDevice graphicsDevice)
|
|
||||||
{
|
|
||||||
string file = GetFontFilePath(element);
|
|
||||||
uint size = GetFontSize(element);
|
|
||||||
bool dynamicLoading = GetFontDynamicLoading(element);
|
|
||||||
bool isCJK = GetIsCJK(element);
|
|
||||||
return new ScalableFont(file, size, graphicsDevice, dynamicLoading, isCJK);
|
|
||||||
}
|
|
||||||
|
|
||||||
private uint GetFontSize(XElement element, uint defaultSize = 14)
|
|
||||||
{
|
|
||||||
//check if any of the language override fonts want to override the font size as well
|
|
||||||
foreach (XElement subElement in element.Elements())
|
|
||||||
{
|
|
||||||
if (!subElement.Name.ToString().Equals("override", StringComparison.OrdinalIgnoreCase)) { continue; }
|
|
||||||
if (GameMain.Config.Language.Equals(subElement.GetAttributeString("language", ""), StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
uint overrideFontSize = GetFontSize(subElement, 0);
|
|
||||||
if (overrideFontSize > 0) { return (uint)Math.Round(overrideFontSize * GameSettings.TextScale); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (XElement subElement in element.Elements())
|
|
||||||
{
|
|
||||||
if (!subElement.Name.ToString().Equals("size", StringComparison.OrdinalIgnoreCase)) { continue; }
|
|
||||||
Point maxResolution = subElement.GetAttributePoint("maxresolution", new Point(int.MaxValue, int.MaxValue));
|
|
||||||
if (GameMain.GraphicsWidth <= maxResolution.X && GameMain.GraphicsHeight <= maxResolution.Y)
|
|
||||||
{
|
|
||||||
return (uint)Math.Round(subElement.GetAttributeInt("size", 14) * GameSettings.TextScale);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (uint)Math.Round(defaultSize * GameSettings.TextScale);
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetFontFilePath(XElement element)
|
|
||||||
{
|
|
||||||
foreach (XElement subElement in element.Elements())
|
|
||||||
{
|
|
||||||
if (!subElement.Name.ToString().Equals("override", StringComparison.OrdinalIgnoreCase)) { continue; }
|
|
||||||
if (GameMain.Config.Language.Equals(subElement.GetAttributeString("language", ""), StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return subElement.GetAttributeString("file", "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return element.GetAttributeString("file", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool GetFontDynamicLoading(XElement element)
|
|
||||||
{
|
|
||||||
foreach (XElement subElement in element.Elements())
|
|
||||||
{
|
|
||||||
if (!subElement.Name.ToString().Equals("override", StringComparison.OrdinalIgnoreCase)) { continue; }
|
|
||||||
if (GameMain.Config.Language.Equals(subElement.GetAttributeString("language", ""), StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return subElement.GetAttributeBool("dynamicloading", false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return element.GetAttributeBool("dynamicloading", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool GetIsCJK(XElement element)
|
|
||||||
{
|
|
||||||
foreach (XElement subElement in element.Elements())
|
|
||||||
{
|
|
||||||
if (!subElement.Name.ToString().Equals("override", StringComparison.OrdinalIgnoreCase)) { continue; }
|
|
||||||
if (GameMain.Config.Language.Equals(subElement.GetAttributeString("language", ""), StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return subElement.GetAttributeBool("iscjk", false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return element.GetAttributeBool("iscjk", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public GUIComponentStyle GetComponentStyle(string name)
|
|
||||||
{
|
|
||||||
componentStyles.TryGetValue(name.ToLowerInvariant(), out GUIComponentStyle style);
|
|
||||||
return style;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Apply(GUIComponent targetComponent, string styleName = "", GUIComponent parent = null)
|
|
||||||
{
|
{
|
||||||
GUIComponentStyle componentStyle = null;
|
GUIComponentStyle componentStyle = null;
|
||||||
if (parent != null)
|
if (parent != null)
|
||||||
{
|
{
|
||||||
GUIComponentStyle parentStyle = parent.Style;
|
GUIComponentStyle parentStyle = parent.Style;
|
||||||
|
|
||||||
if (parent.Style == null)
|
if (parentStyle == null)
|
||||||
{
|
{
|
||||||
string parentStyleName = parent.GetType().Name.ToLowerInvariant();
|
Identifier parentStyleName = parent.GetType().Name.ToIdentifier();
|
||||||
|
|
||||||
if (!componentStyles.TryGetValue(parentStyleName, out parentStyle))
|
if (!ComponentStyles.ContainsKey(parentStyleName))
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Couldn't find a GUI style \""+ parentStyleName + "\"");
|
DebugConsole.ThrowError($"Couldn't find a GUI style \"{parentStyleName}\"");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
parentStyle = ComponentStyles[parentStyleName];
|
||||||
}
|
}
|
||||||
|
Identifier childStyleName = styleName.IsEmpty ? targetComponent.GetType().Name.ToIdentifier() : styleName;
|
||||||
string childStyleName = string.IsNullOrEmpty(styleName) ? targetComponent.GetType().Name : styleName;
|
parentStyle.ChildStyles.TryGetValue(childStyleName, out componentStyle);
|
||||||
parentStyle.ChildStyles.TryGetValue(childStyleName.ToLowerInvariant(), out componentStyle);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(styleName))
|
Identifier styleIdentifier = styleName.ToIdentifier();
|
||||||
|
if (styleIdentifier == Identifier.Empty)
|
||||||
{
|
{
|
||||||
styleName = targetComponent.GetType().Name;
|
styleIdentifier = targetComponent.GetType().Name.ToIdentifier();
|
||||||
}
|
}
|
||||||
if (!componentStyles.TryGetValue(styleName.ToLowerInvariant(), out componentStyle))
|
if (!ComponentStyles.ContainsKey(styleIdentifier))
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Couldn't find a GUI style \""+ styleName+"\"");
|
DebugConsole.ThrowError($"Couldn't find a GUI style \"{styleIdentifier}\"");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
componentStyle = ComponentStyles[styleIdentifier];
|
||||||
}
|
}
|
||||||
|
|
||||||
targetComponent.ApplyStyle(componentStyle);
|
targetComponent.ApplyStyle(componentStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Color GetQualityColor(int quality)
|
public static GUIColor GetQualityColor(int quality)
|
||||||
{
|
{
|
||||||
switch (quality)
|
switch (quality)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Microsoft.Xna.Framework;
|
using Barotrauma.Extensions;
|
||||||
|
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;
|
||||||
@@ -7,9 +8,16 @@ using System.Linq;
|
|||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
|
public enum ForceUpperCase
|
||||||
|
{
|
||||||
|
Inherit,
|
||||||
|
No,
|
||||||
|
Yes
|
||||||
|
}
|
||||||
|
|
||||||
public class GUITextBlock : GUIComponent
|
public class GUITextBlock : GUIComponent
|
||||||
{
|
{
|
||||||
protected string text;
|
protected RichString text;
|
||||||
|
|
||||||
protected Alignment textAlignment;
|
protected Alignment textAlignment;
|
||||||
|
|
||||||
@@ -20,10 +28,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
protected Color textColor, disabledTextColor, selectedTextColor;
|
protected Color textColor, disabledTextColor, selectedTextColor;
|
||||||
|
|
||||||
private string wrappedText;
|
private LocalizedString wrappedText;
|
||||||
private string censoredText;
|
private string censoredText;
|
||||||
|
|
||||||
public delegate string TextGetterHandler();
|
public delegate LocalizedString TextGetterHandler();
|
||||||
public TextGetterHandler TextGetter;
|
public TextGetterHandler TextGetter;
|
||||||
|
|
||||||
public bool Wrap;
|
public bool Wrap;
|
||||||
@@ -41,8 +49,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private float textDepth;
|
private float textDepth;
|
||||||
|
|
||||||
private ScalableFont originalFont;
|
|
||||||
|
|
||||||
public Vector2 TextOffset { get; set; }
|
public Vector2 TextOffset { get; set; }
|
||||||
|
|
||||||
private Vector4 padding;
|
private Vector4 padding;
|
||||||
@@ -56,7 +62,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ScalableFont Font
|
public override GUIFont Font
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@@ -65,23 +71,25 @@ namespace Barotrauma
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (base.Font == value) { return; }
|
if (base.Font == value) { return; }
|
||||||
base.Font = originalFont = value;
|
base.Font = value;
|
||||||
if (text != null && GUI.Style.ForceFontUpperCase.ContainsKey(Font) && GUI.Style.ForceFontUpperCase[Font])
|
if (text != null) { Text = text; }
|
||||||
{
|
|
||||||
Text = text.ToUpper();
|
|
||||||
}
|
|
||||||
SetTextPos();
|
SetTextPos();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Text
|
public RichString Text
|
||||||
{
|
{
|
||||||
get { return text; }
|
get { return text; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
string newText = forceUpperCase || (GUI.Style.ForceFontUpperCase.ContainsKey(Font) && GUI.Style.ForceFontUpperCase[Font]) || (style != null && style.ForceUpperCase) ?
|
#warning TODO: Remove this eventually. Nobody should want to pass null.
|
||||||
value?.ToUpper() :
|
value ??= "";
|
||||||
value;
|
RichString newText = forceUpperCase switch
|
||||||
|
{
|
||||||
|
ForceUpperCase.Inherit => value.CaseTiedToFontAndStyle(Font, Style),
|
||||||
|
ForceUpperCase.No => value.CaseTiedToFontAndStyle(null, null),
|
||||||
|
ForceUpperCase.Yes => value.ToUpper()
|
||||||
|
};
|
||||||
|
|
||||||
if (Text == newText) { return; }
|
if (Text == newText) { return; }
|
||||||
|
|
||||||
@@ -89,21 +97,12 @@ namespace Barotrauma
|
|||||||
if (autoScaleHorizontal || autoScaleVertical) { textScale = 1.0f; }
|
if (autoScaleHorizontal || autoScaleVertical) { textScale = 1.0f; }
|
||||||
|
|
||||||
text = newText;
|
text = newText;
|
||||||
wrappedText = newText;
|
wrappedText = newText.SanitizedString;
|
||||||
if (TextManager.IsCJK(text))
|
|
||||||
{
|
|
||||||
//switch to fallback CJK font
|
|
||||||
if (!Font.IsCJK) { base.Font = GUI.CJKFont; }
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (Font == GUI.CJKFont) { base.Font = originalFont; }
|
|
||||||
}
|
|
||||||
SetTextPos();
|
SetTextPos();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string WrappedText
|
public LocalizedString WrappedText
|
||||||
{
|
{
|
||||||
get { return wrappedText; }
|
get { return wrappedText; }
|
||||||
}
|
}
|
||||||
@@ -117,7 +116,11 @@ namespace Barotrauma
|
|||||||
public Vector2 TextPos
|
public Vector2 TextPos
|
||||||
{
|
{
|
||||||
get { return textPos; }
|
get { return textPos; }
|
||||||
set { textPos = value; }
|
set
|
||||||
|
{
|
||||||
|
textPos = value;
|
||||||
|
ClearCaretPositions();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float TextScale
|
public float TextScale
|
||||||
@@ -169,8 +172,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool forceUpperCase;
|
private ForceUpperCase forceUpperCase = ForceUpperCase.Inherit;
|
||||||
public bool ForceUpperCase
|
public ForceUpperCase ForceUpperCase
|
||||||
{
|
{
|
||||||
get { return forceUpperCase; }
|
get { return forceUpperCase; }
|
||||||
set
|
set
|
||||||
@@ -178,12 +181,7 @@ namespace Barotrauma
|
|||||||
if (forceUpperCase == value) { return; }
|
if (forceUpperCase == value) { return; }
|
||||||
|
|
||||||
forceUpperCase = value;
|
forceUpperCase = value;
|
||||||
if (forceUpperCase ||
|
if (text != null) { Text = text; }
|
||||||
(style != null && style.ForceUpperCase) ||
|
|
||||||
(GUI.Style.ForceFontUpperCase.ContainsKey(Font) && GUI.Style.ForceFontUpperCase[Font]))
|
|
||||||
{
|
|
||||||
Text = text?.ToUpper();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,7 +245,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public class StrikethroughSettings
|
public class StrikethroughSettings
|
||||||
{
|
{
|
||||||
public Color Color { get; set; } = GUI.Style.Red;
|
public Color Color { get; set; } = GUIStyle.Red;
|
||||||
private int thickness;
|
private int thickness;
|
||||||
private int expand;
|
private int expand;
|
||||||
|
|
||||||
@@ -266,13 +264,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public StrikethroughSettings Strikethrough = null;
|
public StrikethroughSettings Strikethrough = null;
|
||||||
|
|
||||||
public List<RichTextData> RichTextData
|
public ImmutableArray<RichTextData>? RichTextData => text.RichTextData;
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool HasColorHighlight => RichTextData != null;
|
public bool HasColorHighlight => RichTextData.HasValue;
|
||||||
|
|
||||||
public bool OverrideRichTextDataAlpha = true;
|
public bool OverrideRichTextDataAlpha = true;
|
||||||
|
|
||||||
@@ -292,9 +286,9 @@ namespace Barotrauma
|
|||||||
/// This is the new constructor.
|
/// This is the new constructor.
|
||||||
/// If the rectT height is set 0, the height is calculated from the text.
|
/// If the rectT height is set 0, the height is calculated from the text.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GUITextBlock(RectTransform rectT, string text, Color? textColor = null, ScalableFont font = null,
|
public GUITextBlock(RectTransform rectT, RichString text, Color? textColor = null, GUIFont font = null,
|
||||||
Alignment textAlignment = Alignment.Left, bool wrap = false, string style = "", Color? color = null,
|
Alignment textAlignment = Alignment.Left, bool wrap = false, string style = "", Color? color = null,
|
||||||
bool playerInput = false, bool parseRichText = false)
|
bool playerInput = false)
|
||||||
: base(style, rectT)
|
: base(style, rectT)
|
||||||
{
|
{
|
||||||
if (color.HasValue)
|
if (color.HasValue)
|
||||||
@@ -306,28 +300,15 @@ namespace Barotrauma
|
|||||||
OverrideTextColor(textColor.Value);
|
OverrideTextColor(textColor.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parseRichText)
|
|
||||||
{
|
|
||||||
RichTextData = Barotrauma.RichTextData.GetRichTextData(text, out text);
|
|
||||||
if (RichTextData != null && RichTextData.Count == 0)
|
|
||||||
{
|
|
||||||
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,
|
||||||
//use the default CJK font as a fallback
|
//use the default CJK font as a fallback
|
||||||
var selectedFont = originalFont = font ?? GUI.Font;
|
var selectedFont = font ?? GUIStyle.Font;
|
||||||
if (TextManager.IsCJK(text) && !selectedFont.IsCJK)
|
|
||||||
{
|
|
||||||
selectedFont = GUI.CJKFont;
|
|
||||||
}
|
|
||||||
this.Font = selectedFont;
|
this.Font = selectedFont;
|
||||||
this.textAlignment = textAlignment;
|
this.textAlignment = textAlignment;
|
||||||
this.Wrap = wrap;
|
this.Wrap = wrap;
|
||||||
this.Text = text ?? "";
|
this.Text = text ?? "";
|
||||||
this.playerInput = playerInput;
|
this.playerInput = playerInput;
|
||||||
if (rectT.Rect.Height == 0 && !string.IsNullOrEmpty(text))
|
if (rectT.Rect.Height == 0 && !text.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
CalculateHeightFromText();
|
CalculateHeightFromText();
|
||||||
}
|
}
|
||||||
@@ -339,11 +320,6 @@ namespace Barotrauma
|
|||||||
Enabled = true;
|
Enabled = true;
|
||||||
Censor = false;
|
Censor = false;
|
||||||
}
|
}
|
||||||
public GUITextBlock(RectTransform rectT, List<RichTextData> richTextData, string text, Color? textColor = null, ScalableFont font = null, Alignment textAlignment = Alignment.Left, bool wrap = false, string style = "", Color? color = null, bool playerInput = false)
|
|
||||||
: this(rectT, text, textColor, font, textAlignment, wrap, style, color, playerInput)
|
|
||||||
{
|
|
||||||
this.RichTextData = richTextData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CalculateHeightFromText(int padding = 0, bool removeExtraSpacing = false)
|
public void CalculateHeightFromText(int padding = 0, bool removeExtraSpacing = false)
|
||||||
{
|
{
|
||||||
@@ -351,10 +327,9 @@ namespace Barotrauma
|
|||||||
RectTransform.Resize(new Point(RectTransform.Rect.Width, (int)Font.MeasureString(wrappedText, removeExtraSpacing).Y + padding));
|
RectTransform.Resize(new Point(RectTransform.Rect.Width, (int)Font.MeasureString(wrappedText, removeExtraSpacing).Y + padding));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetRichText(string richText)
|
public void SetRichText(LocalizedString richText)
|
||||||
{
|
{
|
||||||
RichTextData = Barotrauma.RichTextData.GetRichTextData(richText, out string sanitizedText);
|
Text = RichString.Rich(richText);
|
||||||
Text = sanitizedText;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ApplyStyle(GUIComponentStyle componentStyle)
|
public override void ApplyStyle(GUIComponentStyle componentStyle)
|
||||||
@@ -368,41 +343,34 @@ namespace Barotrauma
|
|||||||
disabledTextColor = componentStyle.DisabledTextColor;
|
disabledTextColor = componentStyle.DisabledTextColor;
|
||||||
selectedTextColor = componentStyle.SelectedTextColor;
|
selectedTextColor = componentStyle.SelectedTextColor;
|
||||||
|
|
||||||
switch (componentStyle.Font)
|
if (Font == null || !componentStyle.Font.IsEmpty)
|
||||||
{
|
{
|
||||||
case "font":
|
Font = GUIStyle.Fonts[componentStyle.Font.AppendIfMissing("Font")];
|
||||||
Font = componentStyle.Style.Font;
|
|
||||||
break;
|
|
||||||
case "smallfont":
|
|
||||||
Font = componentStyle.Style.SmallFont;
|
|
||||||
break;
|
|
||||||
case "largefont":
|
|
||||||
Font = componentStyle.Style.LargeFont;
|
|
||||||
break;
|
|
||||||
case "objectivetitle":
|
|
||||||
case "subheading":
|
|
||||||
Font = componentStyle.Style.SubHeadingFont;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ClearCaretPositions()
|
||||||
|
{
|
||||||
|
cachedCaretPositions = ImmutableArray<Vector2>.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
public void SetTextPos()
|
public void SetTextPos()
|
||||||
{
|
{
|
||||||
cachedCaretPositions = ImmutableArray<Vector2>.Empty;
|
ClearCaretPositions();
|
||||||
if (text == null) { return; }
|
if (text == null) { return; }
|
||||||
|
|
||||||
censoredText = string.IsNullOrEmpty(text) ? "" : new string('\u2022', text.Length);
|
censoredText = text.IsNullOrEmpty() ? "" : new string('\u2022', text.Length);
|
||||||
|
|
||||||
var rect = Rect;
|
var rect = Rect;
|
||||||
|
|
||||||
overflowClipActive = false;
|
overflowClipActive = false;
|
||||||
wrappedText = text;
|
wrappedText = text.SanitizedString;
|
||||||
|
|
||||||
TextSize = MeasureText(text);
|
TextSize = MeasureText(text.SanitizedString);
|
||||||
|
|
||||||
if (Wrap && rect.Width > 0)
|
if (Wrap && rect.Width > 0)
|
||||||
{
|
{
|
||||||
wrappedText = ToolBox.WrapText(text, rect.Width - padding.X - padding.Z, Font, textScale);
|
wrappedText = ToolBox.WrapText(text.SanitizedString, rect.Width - padding.X - padding.Z, Font, textScale);
|
||||||
TextSize = MeasureText(wrappedText);
|
TextSize = MeasureText(wrappedText);
|
||||||
}
|
}
|
||||||
else if (OverflowClip)
|
else if (OverflowClip)
|
||||||
@@ -426,15 +394,15 @@ namespace Barotrauma
|
|||||||
textPos = new Vector2(padding.X + (rect.Width - padding.Z - padding.X) / 2.0f, padding.Y + (rect.Height - padding.Y - padding.W) / 2.0f);
|
textPos = new Vector2(padding.X + (rect.Width - padding.Z - padding.X) / 2.0f, padding.Y + (rect.Height - padding.Y - padding.W) / 2.0f);
|
||||||
origin = TextSize * 0.5f;
|
origin = TextSize * 0.5f;
|
||||||
|
|
||||||
|
origin.X = 0;
|
||||||
if (textAlignment.HasFlag(Alignment.Left) && !overflowClipActive)
|
if (textAlignment.HasFlag(Alignment.Left) && !overflowClipActive)
|
||||||
{
|
{
|
||||||
textPos.X = padding.X;
|
textPos.X = padding.X;
|
||||||
origin.X = 0;
|
|
||||||
}
|
}
|
||||||
if (textAlignment.HasFlag(Alignment.Right) || overflowClipActive)
|
if (textAlignment.HasFlag(Alignment.Right) || overflowClipActive)
|
||||||
{
|
{
|
||||||
textPos.X = rect.Width - padding.Z;
|
textPos.X = rect.Width - padding.Z;
|
||||||
origin.X = TextSize.X;
|
//origin.X = TextSize.X;
|
||||||
}
|
}
|
||||||
if (textAlignment.HasFlag(Alignment.Top))
|
if (textAlignment.HasFlag(Alignment.Top))
|
||||||
{
|
{
|
||||||
@@ -454,6 +422,11 @@ namespace Barotrauma
|
|||||||
textPos.Y = (int)textPos.Y;
|
textPos.Y = (int)textPos.Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Vector2 MeasureText(LocalizedString text)
|
||||||
|
{
|
||||||
|
return MeasureText(text.Value);
|
||||||
|
}
|
||||||
|
|
||||||
private Vector2 MeasureText(string text)
|
private Vector2 MeasureText(string text)
|
||||||
{
|
{
|
||||||
if (Font == null) return Vector2.Zero;
|
if (Font == null) return Vector2.Zero;
|
||||||
@@ -498,12 +471,20 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
return cachedCaretPositions;
|
return cachedCaretPositions;
|
||||||
}
|
}
|
||||||
string textDrawn = Censor ? CensoredText : Text;
|
string textDrawn = Censor ? CensoredText : Text.SanitizedValue;
|
||||||
float w = Wrap
|
float w = Wrap
|
||||||
? (Rect.Width - Padding.X - Padding.Z) / TextScale
|
? (Rect.Width - Padding.X - Padding.Z) / TextScale
|
||||||
: float.PositiveInfinity;
|
: float.PositiveInfinity;
|
||||||
Font.WrapText(textDrawn, w, out Vector2[] positions);
|
string wrapped = Font.WrapText(textDrawn, w, out Vector2[] positions);
|
||||||
cachedCaretPositions = positions.Select(p => p * TextScale + TextPos - Origin * TextScale).ToImmutableArray();
|
int textWidth = (int)Font.MeasureString(wrapped).X;
|
||||||
|
int alignmentXDiff
|
||||||
|
= textAlignment.HasFlag(Alignment.Right) ? textWidth
|
||||||
|
: textAlignment.HasFlag(Alignment.Center) ? textWidth / 2
|
||||||
|
: 0;
|
||||||
|
cachedCaretPositions = positions
|
||||||
|
.Select(p => p - new Vector2(alignmentXDiff, 0))
|
||||||
|
.Select(p => p * TextScale + TextPos - Origin * TextScale)
|
||||||
|
.ToImmutableArray();
|
||||||
return cachedCaretPositions;
|
return cachedCaretPositions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -584,7 +565,7 @@ namespace Barotrauma
|
|||||||
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
|
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(text))
|
if (!text.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
Vector2 pos = rect.Location.ToVector2() + textPos + TextOffset;
|
Vector2 pos = rect.Location.ToVector2() + textPos + TextOffset;
|
||||||
if (RoundToNearestPixel)
|
if (RoundToNearestPixel)
|
||||||
@@ -605,28 +586,29 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (!HasColorHighlight)
|
if (!HasColorHighlight)
|
||||||
{
|
{
|
||||||
string textToShow = Censor ? censoredText : (Wrap ? wrappedText : text);
|
string textToShow = Censor ? censoredText : (Wrap ? wrappedText.Value : text.SanitizedValue);
|
||||||
Color colorToShow = currentTextColor * (currentTextColor.A / 255.0f);
|
Color colorToShow = currentTextColor * (currentTextColor.A / 255.0f);
|
||||||
|
|
||||||
if (Shadow)
|
if (Shadow)
|
||||||
{
|
{
|
||||||
Vector2 shadowOffset = new Vector2(GUI.IntScale(2));
|
Vector2 shadowOffset = new Vector2(GUI.IntScale(2));
|
||||||
Font.DrawString(spriteBatch, textToShow, pos + shadowOffset, Color.Black, 0.0f, origin, TextScale, SpriteEffects.None, textDepth);
|
Font.DrawString(spriteBatch, textToShow, pos + shadowOffset, Color.Black, 0.0f, origin, TextScale, SpriteEffects.None, textDepth, alignment: textAlignment, forceUpperCase: ForceUpperCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
Font.DrawString(spriteBatch, textToShow, pos, colorToShow, 0.0f, origin, TextScale, SpriteEffects.None, textDepth);
|
Font.DrawString(spriteBatch, textToShow, pos, colorToShow, 0.0f, origin, TextScale, SpriteEffects.None, textDepth, alignment: textAlignment, forceUpperCase: ForceUpperCase);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (OverrideRichTextDataAlpha)
|
if (OverrideRichTextDataAlpha)
|
||||||
{
|
{
|
||||||
RichTextData.ForEach(rt => rt.Alpha = currentTextColor.A / 255.0f);
|
RichTextData.Value.ForEach(rt => rt.Alpha = currentTextColor.A / 255.0f);
|
||||||
}
|
}
|
||||||
Font.DrawStringWithColors(spriteBatch, Censor ? censoredText : (Wrap ? wrappedText : text), pos,
|
Font.DrawStringWithColors(spriteBatch, Censor ? censoredText : (Wrap ? wrappedText : text.SanitizedString).Value, pos,
|
||||||
currentTextColor * (currentTextColor.A / 255.0f), 0.0f, origin, TextScale, SpriteEffects.None, textDepth, RichTextData);
|
currentTextColor * (currentTextColor.A / 255.0f), 0.0f, origin, TextScale, SpriteEffects.None, textDepth, RichTextData.Value, alignment: textAlignment, forceUpperCase: ForceUpperCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
Strikethrough?.Draw(spriteBatch, (int)Math.Ceiling(TextSize.X / 2f), pos.X, ForceUpperCase ? pos.Y : pos.Y + GUI.Scale * 2f);
|
Strikethrough?.Draw(spriteBatch, (int)Math.Ceiling(TextSize.X / 2f), pos.X,
|
||||||
|
/* TODO: ???? */ForceUpperCase == ForceUpperCase.Yes ? pos.Y : pos.Y + GUI.Scale * 2f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (overflowClipActive)
|
if (overflowClipActive)
|
||||||
|
|||||||
@@ -76,9 +76,6 @@ namespace Barotrauma
|
|||||||
private int selectionStartIndex;
|
private int selectionStartIndex;
|
||||||
private int selectionEndIndex;
|
private int selectionEndIndex;
|
||||||
private bool IsLeftToRight => selectionStartIndex <= selectionEndIndex;
|
private bool IsLeftToRight => selectionStartIndex <= selectionEndIndex;
|
||||||
private Vector2 selectionStartPos;
|
|
||||||
private Vector2 selectionEndPos;
|
|
||||||
private Vector2 selectionRectSize;
|
|
||||||
|
|
||||||
private GUICustomComponent caretAndSelectionRenderer;
|
private GUICustomComponent caretAndSelectionRenderer;
|
||||||
|
|
||||||
@@ -151,7 +148,7 @@ namespace Barotrauma
|
|||||||
maxTextLength = value;
|
maxTextLength = value;
|
||||||
if (Text.Length > MaxTextLength)
|
if (Text.Length > MaxTextLength)
|
||||||
{
|
{
|
||||||
SetText(textBlock.Text.Substring(0, (int)maxTextLength));
|
SetText(Text.Substring(0, (int)maxTextLength));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -182,7 +179,7 @@ namespace Barotrauma
|
|||||||
set { textBlock.Censor = value; }
|
set { textBlock.Censor = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToolTip
|
public override RichString ToolTip
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@@ -194,7 +191,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ScalableFont Font
|
public override GUIFont Font
|
||||||
{
|
{
|
||||||
get { return textBlock?.Font ?? base.Font; }
|
get { return textBlock?.Font ?? base.Font; }
|
||||||
set
|
set
|
||||||
@@ -247,7 +244,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return textBlock.Text;
|
return textBlock.Text.SanitizedValue;
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
@@ -259,12 +256,12 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public string WrappedText
|
public string WrappedText
|
||||||
{
|
{
|
||||||
get { return textBlock.WrappedText; }
|
get { return textBlock.WrappedText.Value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Readonly { get; set; }
|
public bool Readonly { get; set; }
|
||||||
|
|
||||||
public GUITextBox(RectTransform rectT, string text = "", Color? textColor = null, ScalableFont font = null,
|
public GUITextBox(RectTransform rectT, string text = "", Color? textColor = null, GUIFont font = null,
|
||||||
Alignment textAlignment = Alignment.Left, bool wrap = false, string style = "", Color? color = null, bool createClearButton = false, bool createPenIcon = true)
|
Alignment textAlignment = Alignment.Left, bool wrap = false, string style = "", Color? color = null, bool createClearButton = false, bool createPenIcon = true)
|
||||||
: base(style, rectT)
|
: base(style, rectT)
|
||||||
{
|
{
|
||||||
@@ -273,9 +270,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
this.color = color ?? Color.White;
|
this.color = color ?? Color.White;
|
||||||
frame = new GUIFrame(new RectTransform(Vector2.One, rectT, Anchor.Center), style, color);
|
frame = new GUIFrame(new RectTransform(Vector2.One, rectT, Anchor.Center), style, color);
|
||||||
GUI.Style.Apply(frame, style == "" ? "GUITextBox" : style);
|
GUIStyle.Apply(frame, style == "" ? "GUITextBox" : style);
|
||||||
textBlock = new GUITextBlock(new RectTransform(Vector2.One, frame.RectTransform, Anchor.CenterLeft), text, textColor, font, textAlignment, wrap, playerInput: true);
|
textBlock = new GUITextBlock(new RectTransform(Vector2.One, frame.RectTransform, Anchor.CenterLeft), text ?? "", textColor, font, textAlignment, wrap, playerInput: true);
|
||||||
GUI.Style.Apply(textBlock, "", this);
|
GUIStyle.Apply(textBlock, "", this);
|
||||||
|
if (font != null) { textBlock.Font = font; }
|
||||||
CaretEnabled = true;
|
CaretEnabled = true;
|
||||||
caretPosDirty = true;
|
caretPosDirty = true;
|
||||||
|
|
||||||
@@ -297,10 +295,11 @@ namespace Barotrauma
|
|||||||
clearButtonWidth = (int)(clearButton.Rect.Width * 1.2f);
|
clearButtonWidth = (int)(clearButton.Rect.Width * 1.2f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.style != null && this.style.ChildStyles.ContainsKey("textboxicon") && createPenIcon)
|
var selfStyle = Style;
|
||||||
|
if (selfStyle != null && selfStyle.ChildStyles.ContainsKey("textboxicon".ToIdentifier()) && createPenIcon)
|
||||||
{
|
{
|
||||||
icon = new GUIImage(new RectTransform(new Vector2(0.6f, 0.6f), frame.RectTransform, Anchor.CenterRight, scaleBasis: ScaleBasis.BothHeight) { AbsoluteOffset = new Point(5 + clearButtonWidth, 0) }, null, scaleToFit: true);
|
icon = new GUIImage(new RectTransform(new Vector2(0.6f, 0.6f), frame.RectTransform, Anchor.CenterRight, scaleBasis: ScaleBasis.BothHeight) { AbsoluteOffset = new Point(5 + clearButtonWidth, 0) }, null, scaleToFit: true);
|
||||||
icon.ApplyStyle(this.style.ChildStyles["textboxicon"]);
|
icon.ApplyStyle(this.Style.ChildStyles["textboxicon".ToIdentifier()]);
|
||||||
textBlock.RectTransform.MaxSize = new Point(frame.Rect.Width - icon.Rect.Height - clearButtonWidth - icon.RectTransform.AbsoluteOffset.X * 2, int.MaxValue);
|
textBlock.RectTransform.MaxSize = new Point(frame.Rect.Width - icon.Rect.Height - clearButtonWidth - icon.RectTransform.AbsoluteOffset.X * 2, int.MaxValue);
|
||||||
}
|
}
|
||||||
Font = textBlock.Font;
|
Font = textBlock.Font;
|
||||||
@@ -325,53 +324,39 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
text = textFilterFunction(text);
|
text = textFilterFunction(text);
|
||||||
}
|
}
|
||||||
if (textBlock.Text == text) { return false; }
|
if (Text == text) { return false; }
|
||||||
textBlock.Text = text;
|
textBlock.Text = text;
|
||||||
if (textBlock.Text == null) textBlock.Text = "";
|
ClearSelection();
|
||||||
if (textBlock.Text != "" && !Wrap)
|
if (Text == null) textBlock.Text = "";
|
||||||
|
if (Text != "" && !Wrap)
|
||||||
{
|
{
|
||||||
if (maxTextLength != null)
|
if (maxTextLength != null)
|
||||||
{
|
{
|
||||||
if (textBlock.Text.Length > maxTextLength)
|
if (textBlock.Text.Length > maxTextLength)
|
||||||
{
|
{
|
||||||
textBlock.Text = textBlock.Text.Substring(0, (int)maxTextLength);
|
textBlock.Text = Text.Substring(0, (int)maxTextLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
while (ClampText && textBlock.Text.Length > 0 && Font.MeasureString(textBlock.Text).X * TextBlock.TextScale > (int)(textBlock.Rect.Width - textBlock.Padding.X - textBlock.Padding.Z))
|
while (ClampText && textBlock.Text.Length > 0 && Font.MeasureString(textBlock.Text).X * TextBlock.TextScale > (int)(textBlock.Rect.Width - textBlock.Padding.X - textBlock.Padding.Z))
|
||||||
{
|
{
|
||||||
textBlock.Text = textBlock.Text.Substring(0, textBlock.Text.Length - 1);
|
textBlock.Text = Text.Substring(0, textBlock.Text.Length - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (store)
|
if (store)
|
||||||
{
|
{
|
||||||
memento.Store(textBlock.Text);
|
memento.Store(Text);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CalculateCaretPos()
|
private void CalculateCaretPos()
|
||||||
{
|
{
|
||||||
if (Censor || !Wrap)
|
CaretIndex = Math.Clamp(CaretIndex, 0, textBlock.Text.Length);
|
||||||
{
|
var caretPositions = textBlock.GetAllCaretPositions();
|
||||||
string textDrawn = textBlock.CensoredText;
|
caretPos = caretPositions[CaretIndex];
|
||||||
CaretIndex = Math.Min(CaretIndex, textDrawn.Length);
|
|
||||||
textDrawn = Censor ? textBlock.CensoredText : textBlock.Text;
|
|
||||||
Vector2 textSize = Font.MeasureString(textDrawn[..CaretIndex]) * TextBlock.TextScale;
|
|
||||||
caretPos = new Vector2(textSize.X, 0) + textBlock.TextPos - textBlock.Origin * TextBlock.TextScale;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CaretIndex = Math.Min(CaretIndex, textBlock.Text.Length);
|
|
||||||
textBlock.Font.WrapText(
|
|
||||||
textBlock.Text,
|
|
||||||
(textBlock.Rect.Width - textBlock.Padding.X - textBlock.Padding.Z) / TextBlock.TextScale,
|
|
||||||
CaretIndex,
|
|
||||||
out Vector2 requestedCharPos);
|
|
||||||
caretPos = requestedCharPos * TextBlock.TextScale + textBlock.TextPos - textBlock.Origin * TextBlock.TextScale;
|
|
||||||
}
|
|
||||||
caretPosDirty = false;
|
caretPosDirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -470,14 +455,19 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (textBlock.OverflowClipActive)
|
if (textBlock.OverflowClipActive)
|
||||||
{
|
{
|
||||||
if (CaretScreenPos.X < textBlock.Rect.X + textBlock.Padding.X)
|
float left = textBlock.Rect.X + textBlock.Padding.X;
|
||||||
|
if (CaretScreenPos.X < left)
|
||||||
{
|
{
|
||||||
textBlock.TextPos = new Vector2(textBlock.TextPos.X + ((textBlock.Rect.X + textBlock.Padding.X) - CaretScreenPos.X), textBlock.TextPos.Y);
|
float diff = left - CaretScreenPos.X;
|
||||||
|
textBlock.TextPos = new Vector2(textBlock.TextPos.X + diff, textBlock.TextPos.Y);
|
||||||
CalculateCaretPos();
|
CalculateCaretPos();
|
||||||
}
|
}
|
||||||
else if (CaretScreenPos.X > textBlock.Rect.Right - textBlock.Padding.Z)
|
|
||||||
|
float right = textBlock.Rect.Right - textBlock.Padding.Z;
|
||||||
|
if (CaretScreenPos.X > right)
|
||||||
{
|
{
|
||||||
textBlock.TextPos = new Vector2(textBlock.TextPos.X - (CaretScreenPos.X - (textBlock.Rect.Right - textBlock.Padding.Z)), textBlock.TextPos.Y);
|
float diff = CaretScreenPos.X - right;
|
||||||
|
textBlock.TextPos = new Vector2(textBlock.TextPos.X - diff, textBlock.TextPos.Y);
|
||||||
CalculateCaretPos();
|
CalculateCaretPos();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -509,74 +499,57 @@ namespace Barotrauma
|
|||||||
private void DrawCaretAndSelection(SpriteBatch spriteBatch, GUICustomComponent customComponent)
|
private void DrawCaretAndSelection(SpriteBatch spriteBatch, GUICustomComponent customComponent)
|
||||||
{
|
{
|
||||||
if (!Visible) { return; }
|
if (!Visible) { return; }
|
||||||
if (Selected)
|
if (!Selected) { return; }
|
||||||
|
|
||||||
|
if (caretVisible)
|
||||||
{
|
{
|
||||||
if (caretVisible )
|
GUI.DrawLine(spriteBatch,
|
||||||
{
|
new Vector2(Rect.X + (int)caretPos.X + 2, Rect.Y + caretPos.Y + 3),
|
||||||
GUI.DrawLine(spriteBatch,
|
new Vector2(Rect.X + (int)caretPos.X + 2, Rect.Y + caretPos.Y + Font.LineHeight * textBlock.TextScale - 3),
|
||||||
new Vector2(Rect.X + (int)caretPos.X + 2, Rect.Y + caretPos.Y + 3),
|
CaretColor ?? textBlock.TextColor * (textBlock.TextColor.A / 255.0f));
|
||||||
new Vector2(Rect.X + (int)caretPos.X + 2, Rect.Y + caretPos.Y + Font.MeasureString("I").Y * textBlock.TextScale - 3),
|
}
|
||||||
CaretColor ?? textBlock.TextColor * (textBlock.TextColor.A / 255.0f));
|
if (selectedCharacters > 0)
|
||||||
}
|
{
|
||||||
if (selectedCharacters > 0)
|
DrawSelectionRect(spriteBatch);
|
||||||
{
|
|
||||||
DrawSelectionRect(spriteBatch);
|
|
||||||
}
|
|
||||||
//GUI.DrawString(spriteBatch, new Vector2(100, 0), selectedCharacters.ToString(), Color.LightBlue, Color.Black);
|
|
||||||
//GUI.DrawString(spriteBatch, new Vector2(100, 20), selectionStartIndex.ToString(), Color.White, Color.Black);
|
|
||||||
//GUI.DrawString(spriteBatch, new Vector2(140, 20), selectionEndIndex.ToString(), Color.White, Color.Black);
|
|
||||||
//GUI.DrawString(spriteBatch, new Vector2(100, 40), selectedText.ToString(), Color.Yellow, Color.Black);
|
|
||||||
//GUI.DrawString(spriteBatch, new Vector2(100, 60), $"caret index: {CaretIndex.ToString()}", GUI.Style.Red, Color.Black);
|
|
||||||
//GUI.DrawString(spriteBatch, new Vector2(100, 80), $"caret pos: {caretPos.ToString()}", GUI.Style.Red, Color.Black);
|
|
||||||
//GUI.DrawString(spriteBatch, new Vector2(100, 100), $"caret screen pos: {CaretScreenPos.ToString()}", GUI.Style.Red, Color.Black);
|
|
||||||
//GUI.DrawString(spriteBatch, new Vector2(100, 120), $"text start pos: {(textBlock.TextPos - textBlock.Origin).ToString()}", Color.White, Color.Black);
|
|
||||||
//GUI.DrawString(spriteBatch, new Vector2(100, 140), $"cursor pos: {PlayerInput.MousePosition.ToString()}", Color.White, Color.Black);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawSelectionRect(SpriteBatch spriteBatch)
|
private void DrawSelectionRect(SpriteBatch spriteBatch)
|
||||||
{
|
{
|
||||||
if (textBlock.WrappedText.Contains("\n"))
|
var characterPositions = textBlock.GetAllCaretPositions();
|
||||||
{
|
(int startIndex, int endIndex) = IsLeftToRight
|
||||||
// Multiline selection
|
? (selectionStartIndex, selectionEndIndex)
|
||||||
var characterPositions = textBlock.GetAllCaretPositions();
|
: (selectionEndIndex, selectionStartIndex);
|
||||||
(int startIndex, int endIndex) = selectionStartIndex < selectionEndIndex
|
endIndex--;
|
||||||
? (selectionStartIndex, selectionEndIndex)
|
|
||||||
: (selectionEndIndex, selectionStartIndex);
|
|
||||||
endIndex--;
|
|
||||||
|
|
||||||
void drawRect(Vector2 topLeft, Vector2 bottomRight)
|
void drawRect(Vector2 topLeft, Vector2 bottomRight)
|
||||||
{
|
|
||||||
int minWidth = GUI.IntScale(5);
|
|
||||||
if (bottomRight.X - topLeft.X < minWidth) { bottomRight.X = topLeft.X + minWidth; }
|
|
||||||
GUI.DrawRectangle(spriteBatch,
|
|
||||||
Rect.Location.ToVector2() + topLeft,
|
|
||||||
bottomRight - topLeft,
|
|
||||||
SelectionColor, isFilled: true);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 topLeft = characterPositions[startIndex];
|
|
||||||
for (int i = startIndex+1; i <= endIndex; i++)
|
|
||||||
{
|
|
||||||
Vector2 currPos = characterPositions[i];
|
|
||||||
if (!MathUtils.NearlyEqual(topLeft.Y, currPos.Y))
|
|
||||||
{
|
|
||||||
Vector2 bottomRight = characterPositions[i - 1];
|
|
||||||
bottomRight += Font.MeasureChar(Text[i - 1]);
|
|
||||||
drawRect(topLeft, bottomRight);
|
|
||||||
topLeft = currPos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vector2 finalBottomRight = characterPositions[endIndex];
|
|
||||||
finalBottomRight += Font.MeasureChar(Text[endIndex]);
|
|
||||||
drawRect(topLeft, finalBottomRight);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// Single line selection
|
int minWidth = GUI.IntScale(5);
|
||||||
Vector2 topLeft = IsLeftToRight ? selectionStartPos : selectionEndPos;
|
if (bottomRight.X - topLeft.X < minWidth) { bottomRight.X = topLeft.X + minWidth; }
|
||||||
GUI.DrawRectangle(spriteBatch, Rect.Location.ToVector2() + topLeft, selectionRectSize, SelectionColor, isFilled: true);
|
GUI.DrawRectangle(spriteBatch,
|
||||||
|
Rect.Location.ToVector2() + topLeft,
|
||||||
|
bottomRight - topLeft,
|
||||||
|
SelectionColor, isFilled: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector2 topLeft = characterPositions[startIndex];
|
||||||
|
for (int i = startIndex+1; i <= endIndex; i++)
|
||||||
|
{
|
||||||
|
Vector2 currPos = characterPositions[i];
|
||||||
|
if (!MathUtils.NearlyEqual(topLeft.Y, currPos.Y))
|
||||||
|
{
|
||||||
|
Vector2 bottomRight = characterPositions[i - 1];
|
||||||
|
bottomRight += Font.MeasureChar(Text[i - 1]) * TextBlock.TextScale;
|
||||||
|
drawRect(topLeft, bottomRight);
|
||||||
|
topLeft = currPos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Vector2 finalBottomRight = characterPositions[endIndex];
|
||||||
|
if (Text.Length > endIndex)
|
||||||
|
{
|
||||||
|
finalBottomRight += Font.MeasureChar(Text[endIndex]) * TextBlock.TextScale;
|
||||||
|
}
|
||||||
|
drawRect(topLeft, finalBottomRight);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReceiveTextInput(char inputChar)
|
public void ReceiveTextInput(char inputChar)
|
||||||
@@ -710,8 +683,8 @@ namespace Barotrauma
|
|||||||
float lineHeight = Font.LineHeight * TextBlock.TextScale;
|
float lineHeight = Font.LineHeight * TextBlock.TextScale;
|
||||||
int newIndex = textBlock.GetCaretIndexFromLocalPos(new Vector2(caretPos.X, caretPos.Y - lineHeight * 0.5f));
|
int newIndex = textBlock.GetCaretIndexFromLocalPos(new Vector2(caretPos.X, caretPos.Y - lineHeight * 0.5f));
|
||||||
textBlock.Font.WrapText(
|
textBlock.Font.WrapText(
|
||||||
textBlock.Text,
|
textBlock.Text.SanitizedValue,
|
||||||
(textBlock.Rect.Width - textBlock.Padding.X - textBlock.Padding.Z) / TextBlock.TextScale,
|
GetWrapWidth(),
|
||||||
newIndex,
|
newIndex,
|
||||||
out Vector2 requestedCharPos);
|
out Vector2 requestedCharPos);
|
||||||
requestedCharPos *= TextBlock.TextScale;
|
requestedCharPos *= TextBlock.TextScale;
|
||||||
@@ -728,8 +701,8 @@ namespace Barotrauma
|
|||||||
lineHeight = Font.LineHeight * TextBlock.TextScale;
|
lineHeight = Font.LineHeight * TextBlock.TextScale;
|
||||||
newIndex = textBlock.GetCaretIndexFromLocalPos(new Vector2(caretPos.X, caretPos.Y + lineHeight * 1.5f));
|
newIndex = textBlock.GetCaretIndexFromLocalPos(new Vector2(caretPos.X, caretPos.Y + lineHeight * 1.5f));
|
||||||
textBlock.Font.WrapText(
|
textBlock.Font.WrapText(
|
||||||
textBlock.Text,
|
textBlock.Text.SanitizedValue,
|
||||||
(textBlock.Rect.Width - textBlock.Padding.X - textBlock.Padding.Z) / TextBlock.TextScale,
|
GetWrapWidth(),
|
||||||
newIndex,
|
newIndex,
|
||||||
out Vector2 requestedCharPos2);
|
out Vector2 requestedCharPos2);
|
||||||
requestedCharPos2 *= TextBlock.TextScale;
|
requestedCharPos2 *= TextBlock.TextScale;
|
||||||
@@ -816,7 +789,6 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
CaretIndex = 0;
|
CaretIndex = 0;
|
||||||
CalculateCaretPos();
|
CalculateCaretPos();
|
||||||
selectionStartPos = caretPos;
|
|
||||||
selectionStartIndex = 0;
|
selectionStartIndex = 0;
|
||||||
CaretIndex = Text.Length;
|
CaretIndex = Text.Length;
|
||||||
CalculateSelection();
|
CalculateSelection();
|
||||||
@@ -847,15 +819,18 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (selectedText.Length == 0) { return; }
|
if (selectedText.Length == 0) { return; }
|
||||||
|
|
||||||
selectionStartIndex = Math.Max(0, Math.Min(selectionEndIndex, Math.Min(selectionStartIndex, Text.Length - 1)));
|
int targetCaretIndex = Math.Max(0, Math.Min(selectionEndIndex, Math.Min(selectionStartIndex, Text.Length - 1)));
|
||||||
int selectionLength = Math.Min(Text.Length - selectionStartIndex, selectedText.Length);
|
int selectionLength = Math.Min(Text.Length - targetCaretIndex, selectedText.Length);
|
||||||
SetText(Text.Remove(selectionStartIndex, selectionLength));
|
SetText(Text.Remove(targetCaretIndex, selectionLength));
|
||||||
CaretIndex = Math.Min(Text.Length, selectionStartIndex);
|
CaretIndex = targetCaretIndex;
|
||||||
|
|
||||||
ClearSelection();
|
ClearSelection();
|
||||||
OnTextChanged?.Invoke(this, Text);
|
OnTextChanged?.Invoke(this, Text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private float GetWrapWidth()
|
||||||
|
=> Wrap ? (textBlock.Rect.Width - textBlock.Padding.X - textBlock.Padding.Z) / TextBlock.TextScale : float.PositiveInfinity;
|
||||||
|
|
||||||
private void InitSelectionStart()
|
private void InitSelectionStart()
|
||||||
{
|
{
|
||||||
if (caretPosDirty)
|
if (caretPosDirty)
|
||||||
@@ -865,29 +840,20 @@ namespace Barotrauma
|
|||||||
if (selectionStartIndex == -1)
|
if (selectionStartIndex == -1)
|
||||||
{
|
{
|
||||||
selectionStartIndex = CaretIndex;
|
selectionStartIndex = CaretIndex;
|
||||||
selectionStartPos = caretPos;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CalculateSelection()
|
private void CalculateSelection()
|
||||||
{
|
{
|
||||||
string textDrawn = Censor ? textBlock.CensoredText : textBlock.WrappedText;
|
string textDrawn = Censor ? textBlock.CensoredText : WrappedText;
|
||||||
InitSelectionStart();
|
InitSelectionStart();
|
||||||
selectionEndIndex = Math.Min(CaretIndex, textDrawn.Length);
|
selectionEndIndex = Math.Min(CaretIndex, textDrawn.Length);
|
||||||
selectionEndPos = caretPos;
|
|
||||||
selectedCharacters = Math.Abs(selectionStartIndex - selectionEndIndex);
|
selectedCharacters = Math.Abs(selectionStartIndex - selectionEndIndex);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (IsLeftToRight)
|
selectedText = Text.Substring(
|
||||||
{
|
IsLeftToRight ? selectionStartIndex : selectionEndIndex,
|
||||||
selectedText = Text.Substring(selectionStartIndex, Math.Min(selectedCharacters, Text.Length));
|
Math.Min(selectedCharacters, Text.Length));
|
||||||
selectionRectSize = Font.MeasureString(textDrawn.Substring(selectionStartIndex, Math.Min(selectedCharacters, textDrawn.Length))) * TextBlock.TextScale;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
selectedText = Text.Substring(selectionEndIndex, Math.Min(selectedCharacters, Text.Length));
|
|
||||||
selectionRectSize = Font.MeasureString(textDrawn.Substring(selectionEndIndex, Math.Min(selectedCharacters, textDrawn.Length))) * TextBlock.TextScale;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (ArgumentOutOfRangeException exception)
|
catch (ArgumentOutOfRangeException exception)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -20,18 +20,18 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public override bool Selected
|
public override bool Selected
|
||||||
{
|
{
|
||||||
get { return selected; }
|
get { return isSelected; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value == selected) { return; }
|
if (value == isSelected) { return; }
|
||||||
if (radioButtonGroup != null && radioButtonGroup.SelectedRadioButton == this)
|
if (radioButtonGroup != null && radioButtonGroup.SelectedRadioButton == this)
|
||||||
{
|
{
|
||||||
selected = true;
|
isSelected = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
selected = value;
|
isSelected = value;
|
||||||
State = selected ? ComponentState.Selected : ComponentState.None;
|
State = isSelected ? ComponentState.Selected : ComponentState.None;
|
||||||
if (value && radioButtonGroup != null)
|
if (value && radioButtonGroup != null)
|
||||||
{
|
{
|
||||||
radioButtonGroup.SelectRadioButton(this);
|
radioButtonGroup.SelectRadioButton(this);
|
||||||
@@ -88,7 +88,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
public override ScalableFont Font
|
public override GUIFont Font
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@@ -112,7 +112,7 @@ namespace Barotrauma
|
|||||||
get { return text; }
|
get { return text; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToolTip
|
public override RichString ToolTip
|
||||||
{
|
{
|
||||||
get { return base.ToolTip; }
|
get { return base.ToolTip; }
|
||||||
set
|
set
|
||||||
@@ -123,13 +123,13 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Text
|
public LocalizedString Text
|
||||||
{
|
{
|
||||||
get { return text.Text; }
|
get { return text.Text; }
|
||||||
set { text.Text = value; }
|
set { text.Text = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public GUITickBox(RectTransform rectT, string label, ScalableFont font = null, string style = "") : base(null, rectT)
|
public GUITickBox(RectTransform rectT, LocalizedString label, GUIFont font = null, string style = "") : base(null, rectT)
|
||||||
{
|
{
|
||||||
CanBeFocused = true;
|
CanBeFocused = true;
|
||||||
HoverCursor = CursorState.Hand;
|
HoverCursor = CursorState.Hand;
|
||||||
@@ -145,7 +145,7 @@ namespace Barotrauma
|
|||||||
SelectedColor = Color.DarkGray,
|
SelectedColor = Color.DarkGray,
|
||||||
CanBeFocused = false
|
CanBeFocused = false
|
||||||
};
|
};
|
||||||
GUI.Style.Apply(box, style == "" ? "GUITickBox" : style);
|
GUIStyle.Apply(box, style == "" ? "GUITickBox" : style);
|
||||||
if (box.RectTransform.MinSize.Y > 0)
|
if (box.RectTransform.MinSize.Y > 0)
|
||||||
{
|
{
|
||||||
RectTransform.MinSize = box.RectTransform.MinSize;
|
RectTransform.MinSize = box.RectTransform.MinSize;
|
||||||
@@ -159,7 +159,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
CanBeFocused = false
|
CanBeFocused = false
|
||||||
};
|
};
|
||||||
GUI.Style.Apply(text, "GUITextBlock", this);
|
GUIStyle.Apply(text, "GUITextBlock", this);
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
|
|
||||||
ResizeBox();
|
ResizeBox();
|
||||||
@@ -205,13 +205,13 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Selected = !Selected;
|
Selected = !Selected;
|
||||||
}
|
}
|
||||||
else if (!selected)
|
else if (!isSelected)
|
||||||
{
|
{
|
||||||
Selected = true;
|
Selected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (selected)
|
else if (isSelected)
|
||||||
{
|
{
|
||||||
State = ComponentState.Selected;
|
State = ComponentState.Selected;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,7 +90,8 @@ namespace Barotrauma
|
|||||||
if (GameMain.Instance != null)
|
if (GameMain.Instance != null)
|
||||||
{
|
{
|
||||||
GameMain.Instance.ResolutionChanged += CreateAreas;
|
GameMain.Instance.ResolutionChanged += CreateAreas;
|
||||||
GameMain.Config.OnHUDScaleChanged += CreateAreas;
|
#warning TODO: reimplement
|
||||||
|
//GameSettings.CurrentConfig.OnHUDScaleChanged += CreateAreas;
|
||||||
CreateAreas();
|
CreateAreas();
|
||||||
CharacterInfo.Init();
|
CharacterInfo.Init();
|
||||||
}
|
}
|
||||||
@@ -163,7 +164,7 @@ namespace Barotrauma
|
|||||||
public static void Draw(SpriteBatch spriteBatch)
|
public static void Draw(SpriteBatch spriteBatch)
|
||||||
{
|
{
|
||||||
GUI.DrawRectangle(spriteBatch, ButtonAreaTop, Color.White * 0.5f);
|
GUI.DrawRectangle(spriteBatch, ButtonAreaTop, Color.White * 0.5f);
|
||||||
GUI.DrawRectangle(spriteBatch, MessageAreaTop, GUI.Style.Orange * 0.5f);
|
GUI.DrawRectangle(spriteBatch, MessageAreaTop, GUIStyle.Orange * 0.5f);
|
||||||
GUI.DrawRectangle(spriteBatch, CrewArea, Color.Blue * 0.5f);
|
GUI.DrawRectangle(spriteBatch, CrewArea, Color.Blue * 0.5f);
|
||||||
GUI.DrawRectangle(spriteBatch, ChatBoxArea, Color.Cyan * 0.5f);
|
GUI.DrawRectangle(spriteBatch, ChatBoxArea, Color.Cyan * 0.5f);
|
||||||
GUI.DrawRectangle(spriteBatch, HealthBarArea, Color.Red * 0.5f);
|
GUI.DrawRectangle(spriteBatch, HealthBarArea, Color.Red * 0.5f);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using System.Xml.Linq;
|
|||||||
using Barotrauma.Media;
|
using Barotrauma.Media;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Barotrauma.Extensions;
|
using Barotrauma.Extensions;
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -69,14 +70,10 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string selectedTip;
|
private RichString selectedTip;
|
||||||
private List<RichTextData> selectedTipRichTextData;
|
private void SetSelectedTip(LocalizedString tip)
|
||||||
private bool selectedTipRichTextUnparsed;
|
|
||||||
private void SetSelectedTip(string tip)
|
|
||||||
{
|
{
|
||||||
selectedTip = tip;
|
selectedTip = RichString.Rich(tip);
|
||||||
selectedTipRichTextData = null;
|
|
||||||
selectedTipRichTextUnparsed = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly object loadMutex = new object();
|
private readonly object loadMutex = new object();
|
||||||
@@ -113,6 +110,8 @@ namespace Barotrauma
|
|||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LanguageIdentifier[] AvailableLanguages = null;
|
||||||
|
|
||||||
public LoadingScreen(GraphicsDevice graphics)
|
public LoadingScreen(GraphicsDevice graphics)
|
||||||
{
|
{
|
||||||
defaultBackgroundTexture = TextureLoader.FromFile("Content/Map/LocationPortraits/AlienRuins.png");
|
defaultBackgroundTexture = TextureLoader.FromFile("Content/Map/LocationPortraits/AlienRuins.png");
|
||||||
@@ -123,12 +122,12 @@ namespace Barotrauma
|
|||||||
overlay = TextureLoader.FromFile("Content/UI/LoadingScreenOverlay.png");
|
overlay = TextureLoader.FromFile("Content/UI/LoadingScreenOverlay.png");
|
||||||
noiseSprite = new Sprite("Content/UI/noise.png", Vector2.Zero);
|
noiseSprite = new Sprite("Content/UI/noise.png", Vector2.Zero);
|
||||||
DrawLoadingText = true;
|
DrawLoadingText = true;
|
||||||
SetSelectedTip(TextManager.Get("LoadingScreenTip", true));
|
SetSelectedTip(TextManager.Get("LoadingScreenTip"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Draw(SpriteBatch spriteBatch, GraphicsDevice graphics, float deltaTime)
|
public void Draw(SpriteBatch spriteBatch, GraphicsDevice graphics, float deltaTime)
|
||||||
{
|
{
|
||||||
if (GameMain.Config.EnableSplashScreen)
|
if (GameSettings.CurrentConfig.EnableSplashScreen)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -138,11 +137,11 @@ namespace Barotrauma
|
|||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Playing splash screen video failed", e);
|
DebugConsole.ThrowError("Playing splash screen video failed", e);
|
||||||
GameMain.Config.EnableSplashScreen = false;
|
DisableSplashScreen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var titleStyle = GUI.Style?.GetComponentStyle("TitleText");
|
var titleStyle = GUIStyle.GetComponentStyle("TitleText");
|
||||||
Sprite titleSprite = null;
|
Sprite titleSprite = null;
|
||||||
if (!WaitForLanguageSelection && titleStyle != null && titleStyle.Sprites.ContainsKey(GUIComponent.ComponentState.None))
|
if (!WaitForLanguageSelection && titleStyle != null && titleStyle.Sprites.ContainsKey(GUIComponent.ComponentState.None))
|
||||||
{
|
{
|
||||||
@@ -187,67 +186,58 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else if (DrawLoadingText)
|
else if (DrawLoadingText)
|
||||||
{
|
{
|
||||||
if (TextManager.Initialized)
|
LocalizedString loadText;
|
||||||
|
if (LoadState == 100.0f)
|
||||||
{
|
{
|
||||||
string loadText;
|
#if DEBUG
|
||||||
if (LoadState == 100.0f)
|
if (GameSettings.CurrentConfig.AutomaticQuickStartEnabled || GameSettings.CurrentConfig.AutomaticCampaignLoadEnabled || (GameSettings.CurrentConfig.TestScreenEnabled && GameMain.FirstLoad))
|
||||||
{
|
{
|
||||||
#if DEBUG
|
loadText = "QUICKSTARTING ...";
|
||||||
if (GameMain.Config.AutomaticQuickStartEnabled || GameMain.Config.AutomaticCampaignLoadEnabled || GameMain.Config.TestScreenEnabled && GameMain.FirstLoad)
|
|
||||||
{
|
|
||||||
loadText = "QUICKSTARTING ...";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
loadText = TextManager.Get("PressAnyKey");
|
|
||||||
#if DEBUG
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
loadText = TextManager.Get("Loading");
|
#endif
|
||||||
if (LoadState != null)
|
loadText = TextManager.Get("PressAnyKey");
|
||||||
{
|
#if DEBUG
|
||||||
loadText += " " + (int)LoadState + " %";
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
loadText = TextManager.Get("Loading");
|
||||||
|
if (LoadState != null)
|
||||||
|
{
|
||||||
|
loadText += " " + (int)LoadState + " %";
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (GameMain.FirstLoad && GameMain.CancelQuickStart)
|
if (GameMain.FirstLoad && GameMain.CancelQuickStart)
|
||||||
{
|
{
|
||||||
loadText += " (Quickstart aborted)";
|
loadText += " (Quickstart aborted)";
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
#endif
|
||||||
if (GUI.LargeFont != null)
|
|
||||||
{
|
|
||||||
GUI.LargeFont.DrawString(spriteBatch, loadText.ToUpper(),
|
|
||||||
new Vector2(GameMain.GraphicsWidth / 2.0f - GUI.LargeFont.MeasureString(loadText.ToUpper()).X / 2.0f, GameMain.GraphicsHeight * 0.75f),
|
|
||||||
Color.White);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (GUIStyle.LargeFont.HasValue)
|
||||||
if (GUI.Font != null && selectedTip != null)
|
|
||||||
{
|
{
|
||||||
if (selectedTipRichTextUnparsed)
|
GUIStyle.LargeFont.DrawString(spriteBatch, loadText.ToUpper(),
|
||||||
{
|
new Vector2(GameMain.GraphicsWidth / 2.0f - GUIStyle.LargeFont.MeasureString(loadText.ToUpper()).X / 2.0f, GameMain.GraphicsHeight * 0.75f),
|
||||||
selectedTipRichTextData = RichTextData.GetRichTextData(selectedTip, out selectedTip);
|
Color.White);
|
||||||
selectedTipRichTextUnparsed = false;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
string wrappedTip = ToolBox.WrapText(selectedTip, GameMain.GraphicsWidth * 0.5f, GUI.Font);
|
if (GUIStyle.Font.HasValue && selectedTip != null)
|
||||||
|
{
|
||||||
|
string wrappedTip = ToolBox.WrapText(selectedTip.SanitizedValue, GameMain.GraphicsWidth * 0.5f, GUIStyle.Font.Value);
|
||||||
string[] lines = wrappedTip.Split('\n');
|
string[] lines = wrappedTip.Split('\n');
|
||||||
float lineHeight = GUI.Font.MeasureString(selectedTip).Y;
|
float lineHeight = GUIStyle.Font.MeasureString(selectedTip).Y;
|
||||||
|
|
||||||
if (selectedTipRichTextData != null)
|
if (selectedTip.RichTextData != null)
|
||||||
{
|
{
|
||||||
int rtdOffset = 0;
|
int rtdOffset = 0;
|
||||||
for (int i = 0; i < lines.Length; i++)
|
for (int i = 0; i < lines.Length; i++)
|
||||||
{
|
{
|
||||||
GUI.Font.DrawStringWithColors(spriteBatch, lines[i],
|
GUIStyle.Font.DrawStringWithColors(spriteBatch, lines[i],
|
||||||
new Vector2((int)(GameMain.GraphicsWidth / 2.0f - GUI.Font.MeasureString(lines[i]).X / 2.0f), (int)(GameMain.GraphicsHeight * 0.8f + i * lineHeight)), Color.White,
|
new Vector2((int)(GameMain.GraphicsWidth / 2.0f - GUIStyle.Font.MeasureString(lines[i]).X / 2.0f), (int)(GameMain.GraphicsHeight * 0.8f + i * lineHeight)), Color.White,
|
||||||
0f, Vector2.Zero, 1f, SpriteEffects.None, 0f, selectedTipRichTextData, rtdOffset);
|
0f, Vector2.Zero, 1f, SpriteEffects.None, 0f, selectedTip.RichTextData.Value, rtdOffset);
|
||||||
rtdOffset += lines[i].Length;
|
rtdOffset += lines[i].Length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -255,8 +245,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < lines.Length; i++)
|
for (int i = 0; i < lines.Length; i++)
|
||||||
{
|
{
|
||||||
GUI.Font.DrawString(spriteBatch, lines[i],
|
GUIStyle.Font.DrawString(spriteBatch, lines[i],
|
||||||
new Vector2((int)(GameMain.GraphicsWidth / 2.0f - GUI.Font.MeasureString(lines[i]).X / 2.0f), (int)(GameMain.GraphicsHeight * 0.8f + i * lineHeight)), Color.White);
|
new Vector2((int)(GameMain.GraphicsWidth / 2.0f - GUIStyle.Font.MeasureString(lines[i]).X / 2.0f), (int)(GameMain.GraphicsHeight * 0.8f + i * lineHeight)), Color.White);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -280,7 +270,7 @@ namespace Barotrauma
|
|||||||
if (noiseVal < 0.2f)
|
if (noiseVal < 0.2f)
|
||||||
{
|
{
|
||||||
//SCP-CB reference
|
//SCP-CB reference
|
||||||
randText = (new string[] { "NIL", "black white gray", "Sometimes we would have had time to scream", "e8m106]af", "NO" }).GetRandom();
|
randText = (new string[] { "NIL", "black white gray", "Sometimes we would have had time to scream", "e8m106]af", "NO" }).GetRandomUnsynced();
|
||||||
}
|
}
|
||||||
else if (noiseVal < 0.3f)
|
else if (noiseVal < 0.3f)
|
||||||
{
|
{
|
||||||
@@ -295,15 +285,20 @@ namespace Barotrauma
|
|||||||
Rand.Int(100).ToString().PadLeft(2, '0');
|
Rand.Int(100).ToString().PadLeft(2, '0');
|
||||||
}
|
}
|
||||||
|
|
||||||
GUI.LargeFont?.DrawString(spriteBatch, randText,
|
if (GUIStyle.LargeFont.HasValue)
|
||||||
new Vector2(GameMain.GraphicsWidth - decorativeMap.FrameSize.X * decorativeScale.X * 0.8f, GameMain.GraphicsHeight * 0.57f),
|
{
|
||||||
Color.White * (1.0f - noiseVal));
|
GUIStyle.LargeFont.DrawString(spriteBatch, randText,
|
||||||
|
new Vector2(GameMain.GraphicsWidth - decorativeMap.FrameSize.X * decorativeScale.X * 0.8f, GameMain.GraphicsHeight * 0.57f),
|
||||||
|
Color.White * (1.0f - noiseVal));
|
||||||
|
}
|
||||||
|
|
||||||
spriteBatch.End();
|
spriteBatch.End();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawLanguageSelectionPrompt(SpriteBatch spriteBatch, GraphicsDevice graphicsDevice)
|
private void DrawLanguageSelectionPrompt(SpriteBatch spriteBatch, GraphicsDevice graphicsDevice)
|
||||||
{
|
{
|
||||||
|
if (AvailableLanguages is null) { return; }
|
||||||
|
|
||||||
if (languageSelectionFont == null)
|
if (languageSelectionFont == null)
|
||||||
{
|
{
|
||||||
languageSelectionFont = new ScalableFont("Content/Fonts/NotoSans/NotoSans-Bold.ttf",
|
languageSelectionFont = new ScalableFont("Content/Fonts/NotoSans/NotoSans-Bold.ttf",
|
||||||
@@ -320,8 +315,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
Vector2 textPos = new Vector2(GameMain.GraphicsWidth / 2, GameMain.GraphicsHeight * 0.3f);
|
Vector2 textPos = new Vector2(GameMain.GraphicsWidth / 2, GameMain.GraphicsHeight * 0.3f);
|
||||||
Vector2 textSpacing = new Vector2(0.0f, (GameMain.GraphicsHeight * 0.5f) / TextManager.AvailableLanguages.Count());
|
Vector2 textSpacing = new Vector2(0.0f, (GameMain.GraphicsHeight * 0.5f) / AvailableLanguages.Length);
|
||||||
foreach (string language in TextManager.AvailableLanguages)
|
foreach (LanguageIdentifier language in AvailableLanguages)
|
||||||
{
|
{
|
||||||
string localizedLanguageName = TextManager.GetTranslatedLanguageName(language);
|
string localizedLanguageName = TextManager.GetTranslatedLanguageName(language);
|
||||||
var font = TextManager.IsCJK(localizedLanguageName) ? languageSelectionFontCJK : languageSelectionFont;
|
var font = TextManager.IsCJK(localizedLanguageName) ? languageSelectionFontCJK : languageSelectionFont;
|
||||||
@@ -335,11 +330,11 @@ namespace Barotrauma
|
|||||||
hover ? Color.White : Color.White * 0.6f);
|
hover ? Color.White : Color.White * 0.6f);
|
||||||
if (hover && PlayerInput.PrimaryMouseButtonClicked())
|
if (hover && PlayerInput.PrimaryMouseButtonClicked())
|
||||||
{
|
{
|
||||||
GameMain.Config.Language = language;
|
var config = GameSettings.CurrentConfig;
|
||||||
|
config.Language = language;
|
||||||
|
GameSettings.SetCurrentConfig(config);
|
||||||
//reload tip in the selected language
|
//reload tip in the selected language
|
||||||
SetSelectedTip(TextManager.Get("LoadingScreenTip", true));
|
SetSelectedTip(TextManager.Get("LoadingScreenTip"));
|
||||||
GameMain.Config.SetDefaultBindings(legacy: false);
|
|
||||||
GameMain.Config.CheckBindings(useDefaults: true);
|
|
||||||
WaitForLanguageSelection = false;
|
WaitForLanguageSelection = false;
|
||||||
languageSelectionFont?.Dispose(); languageSelectionFont = null;
|
languageSelectionFont?.Dispose(); languageSelectionFont = null;
|
||||||
languageSelectionFontCJK?.Dispose(); languageSelectionFontCJK = null;
|
languageSelectionFontCJK?.Dispose(); languageSelectionFontCJK = null;
|
||||||
@@ -368,7 +363,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
GameMain.Config.EnableSplashScreen = false;
|
DisableSplashScreen();
|
||||||
DebugConsole.ThrowError("Playing the splash screen \"" + fileName + "\" failed.", e);
|
DebugConsole.ThrowError("Playing the splash screen \"" + fileName + "\" failed.", e);
|
||||||
PendingSplashScreens.Clear();
|
PendingSplashScreens.Clear();
|
||||||
currSplashScreen = null;
|
currSplashScreen = null;
|
||||||
@@ -425,13 +420,20 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DisableSplashScreen()
|
||||||
|
{
|
||||||
|
var config = GameSettings.CurrentConfig;
|
||||||
|
config.EnableSplashScreen = false;
|
||||||
|
GameSettings.SetCurrentConfig(config);
|
||||||
|
}
|
||||||
|
|
||||||
bool drawn;
|
bool drawn;
|
||||||
public IEnumerable<CoroutineStatus> DoLoading(IEnumerable<CoroutineStatus> loader)
|
public IEnumerable<CoroutineStatus> DoLoading(IEnumerable<CoroutineStatus> loader)
|
||||||
{
|
{
|
||||||
drawn = false;
|
drawn = false;
|
||||||
LoadState = null;
|
LoadState = null;
|
||||||
SetSelectedTip(TextManager.Get("LoadingScreenTip", true));
|
SetSelectedTip(TextManager.Get("LoadingScreenTip"));
|
||||||
currentBackgroundTexture = LocationType.List.GetRandom()?.GetPortrait(Rand.Int(int.MaxValue))?.Texture;
|
currentBackgroundTexture = LocationType.Prefabs.GetRandomUnsynced()?.GetPortrait(Rand.Int(int.MaxValue))?.Texture;
|
||||||
|
|
||||||
while (!drawn)
|
while (!drawn)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ namespace Barotrauma
|
|||||||
Afflictions = new List<PendingAfflictionElement>();
|
Afflictions = new List<PendingAfflictionElement>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PendingAfflictionElement? FindAfflictionElement(MedicalClinic.NetAffliction target) => Afflictions.FirstOrNull(element => element.Target.Identifier.Equals(target.Identifier, StringComparison.OrdinalIgnoreCase));
|
public PendingAfflictionElement? FindAfflictionElement(MedicalClinic.NetAffliction target) => Afflictions.FirstOrNull(element => element.Target.Identifier == target.Identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Represents an affliction on the left side crew entry
|
// Represents an affliction on the left side crew entry
|
||||||
@@ -268,12 +268,12 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
int totalCost = medicalClinic.GetTotalCost();
|
int totalCost = medicalClinic.GetTotalCost();
|
||||||
healList.PriceBlock.Text = UpgradeStore.FormatCurrency(totalCost);
|
healList.PriceBlock.Text = TextManager.FormatCurrency(totalCost);
|
||||||
healList.PriceBlock.TextColor = GUI.Style.Red;
|
healList.PriceBlock.TextColor = GUIStyle.Red;
|
||||||
healList.HealButton.Enabled = false;
|
healList.HealButton.Enabled = false;
|
||||||
if (medicalClinic.GetMoney() > totalCost)
|
if (medicalClinic.GetWallet().CanAfford(totalCost))
|
||||||
{
|
{
|
||||||
healList.PriceBlock.TextColor = GUI.Style.TextColor;
|
healList.PriceBlock.TextColor = GUIStyle.TextColorNormal;
|
||||||
if (medicalClinic.PendingHeals.Any())
|
if (medicalClinic.PendingHeals.Any())
|
||||||
{
|
{
|
||||||
healList.HealButton.Enabled = true;
|
healList.HealButton.Enabled = true;
|
||||||
@@ -288,7 +288,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (element.FindAfflictionElement(affliction) is { } existingAffliction)
|
if (element.FindAfflictionElement(affliction) is { } existingAffliction)
|
||||||
{
|
{
|
||||||
existingAffliction.Price.Text = UpgradeStore.FormatCurrency(affliction.Strength);
|
existingAffliction.Price.Text = TextManager.FormatCurrency(affliction.Strength);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -443,7 +443,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
GUILayoutGroup clinicLabelLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.1f), clinicContent.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft);
|
GUILayoutGroup clinicLabelLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.1f), clinicContent.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft);
|
||||||
GUIImage clinicIcon = new GUIImage(new RectTransform(Vector2.One, clinicLabelLayout.RectTransform, scaleBasis: ScaleBasis.BothHeight), style: "CrewManagementHeaderIcon", scaleToFit: true);
|
GUIImage clinicIcon = new GUIImage(new RectTransform(Vector2.One, clinicLabelLayout.RectTransform, scaleBasis: ScaleBasis.BothHeight), style: "CrewManagementHeaderIcon", scaleToFit: true);
|
||||||
GUITextBlock clinicLabel = new GUITextBlock(new RectTransform(Vector2.One, clinicLabelLayout.RectTransform), TextManager.Get("medicalclinic.medicalclinic"), font: GUI.LargeFont);
|
GUITextBlock clinicLabel = new GUITextBlock(new RectTransform(Vector2.One, clinicLabelLayout.RectTransform), TextManager.Get("medicalclinic.medicalclinic"), font: GUIStyle.LargeFont);
|
||||||
|
|
||||||
GUIFrame clinicBackground = new GUIFrame(new RectTransform(Vector2.One, clinicContent.RectTransform));
|
GUIFrame clinicBackground = new GUIFrame(new RectTransform(Vector2.One, clinicContent.RectTransform));
|
||||||
|
|
||||||
@@ -459,15 +459,15 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
|
|
||||||
GUILayoutGroup balanceLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.1f), crewContent.RectTransform));
|
GUILayoutGroup balanceLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.1f), crewContent.RectTransform));
|
||||||
GUITextBlock balanceLabel = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), balanceLayout.RectTransform), TextManager.Get("campaignstore.balance"), textAlignment: Alignment.BottomRight, font: GUI.Font)
|
GUITextBlock balanceLabel = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), balanceLayout.RectTransform), TextManager.Get("campaignstore.balance"), textAlignment: Alignment.BottomRight, font: GUIStyle.Font)
|
||||||
{
|
{
|
||||||
AutoScaleVertical = true,
|
AutoScaleVertical = true,
|
||||||
ForceUpperCase = true
|
ForceUpperCase = ForceUpperCase.Yes
|
||||||
};
|
};
|
||||||
|
|
||||||
GUITextBlock moneyLabel = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), balanceLayout.RectTransform), string.Empty, textAlignment: Alignment.TopRight, font: GUI.Style.SubHeadingFont)
|
GUITextBlock moneyLabel = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), balanceLayout.RectTransform), string.Empty, textAlignment: Alignment.TopRight, font: GUIStyle.SubHeadingFont)
|
||||||
{
|
{
|
||||||
TextGetter = () => UpgradeStore.FormatCurrency(medicalClinic.GetMoney()),
|
TextGetter = () => TextManager.FormatCurrency(medicalClinic.GetWallet().Balance),
|
||||||
AutoScaleVertical = true,
|
AutoScaleVertical = true,
|
||||||
TextScale = 1.1f
|
TextScale = 1.1f
|
||||||
};
|
};
|
||||||
@@ -519,18 +519,18 @@ namespace Barotrauma
|
|||||||
|
|
||||||
GUILayoutGroup healthLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.1f, 1f), crewLayout.RectTransform), isHorizontal: true, Anchor.Center);
|
GUILayoutGroup healthLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.1f, 1f), crewLayout.RectTransform), isHorizontal: true, Anchor.Center);
|
||||||
|
|
||||||
new GUITextBlock(new RectTransform(Vector2.One, healthLayout.RectTransform), string.Empty, textAlignment: Alignment.Center, font: GUI.SubHeadingFont)
|
new GUITextBlock(new RectTransform(Vector2.One, healthLayout.RectTransform), string.Empty, textAlignment: Alignment.Center, font: GUIStyle.SubHeadingFont)
|
||||||
{
|
{
|
||||||
TextGetter = () => $"{(int)(info.Character?.HealthPercentage ?? 100f)}%",
|
TextGetter = () => TextManager.GetWithVariable("percentageformat", "[value]", $"{(int)(info.Character?.HealthPercentage ?? 100f)}"),
|
||||||
TextColor = GUI.Style.Green
|
TextColor = GUIStyle.Green
|
||||||
};
|
};
|
||||||
|
|
||||||
GUITextBlock overflowIndicator =
|
GUITextBlock overflowIndicator =
|
||||||
new GUITextBlock(new RectTransform(new Vector2(0.25f, 1f), afflictionList.Content.RectTransform, scaleBasis: ScaleBasis.BothHeight), text: "+", textAlignment: Alignment.Center, font: GUI.LargeFont)
|
new GUITextBlock(new RectTransform(new Vector2(0.25f, 1f), afflictionList.Content.RectTransform, scaleBasis: ScaleBasis.BothHeight), text: "+", textAlignment: Alignment.Center, font: GUIStyle.LargeFont)
|
||||||
{
|
{
|
||||||
Visible = false,
|
Visible = false,
|
||||||
CanBeFocused = false,
|
CanBeFocused = false,
|
||||||
TextColor = GUI.Style.Red
|
TextColor = GUIStyle.Red
|
||||||
};
|
};
|
||||||
|
|
||||||
MedicalClinic.NetCrewMember member = new MedicalClinic.NetCrewMember { CharacterInfo = info, Afflictions = Array.Empty<MedicalClinic.NetAffliction>() };
|
MedicalClinic.NetCrewMember member = new MedicalClinic.NetCrewMember { CharacterInfo = info, Afflictions = Array.Empty<MedicalClinic.NetAffliction>() };
|
||||||
@@ -552,13 +552,13 @@ namespace Barotrauma
|
|||||||
Stretch = true
|
Stretch = true
|
||||||
};
|
};
|
||||||
|
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1f, 0.05f), pendingHealContainer.RectTransform), TextManager.Get("medicalclinic.pendingheals"), font: GUI.SubHeadingFont);
|
new GUITextBlock(new RectTransform(new Vector2(1f, 0.05f), pendingHealContainer.RectTransform), TextManager.Get("medicalclinic.pendingheals"), font: GUIStyle.SubHeadingFont);
|
||||||
|
|
||||||
GUIFrame healListContainer = new GUIFrame(new RectTransform(new Vector2(1f, 0.9f), pendingHealContainer.RectTransform), style: null);
|
GUIFrame healListContainer = new GUIFrame(new RectTransform(new Vector2(1f, 0.9f), pendingHealContainer.RectTransform), style: null);
|
||||||
GUITextBlock? errorBlock = null;
|
GUITextBlock? errorBlock = null;
|
||||||
if (!GameMain.IsSingleplayer)
|
if (!GameMain.IsSingleplayer)
|
||||||
{
|
{
|
||||||
errorBlock = new GUITextBlock(new RectTransform(Vector2.One, healListContainer.RectTransform), text: TextManager.Get("pleasewaitupnp"), font: GUI.LargeFont, textAlignment: Alignment.Center);
|
errorBlock = new GUITextBlock(new RectTransform(Vector2.One, healListContainer.RectTransform), text: TextManager.Get("pleasewaitupnp"), font: GUIStyle.LargeFont, textAlignment: Alignment.Center);
|
||||||
}
|
}
|
||||||
|
|
||||||
GUIListBox healList = new GUIListBox(new RectTransform(Vector2.One, healListContainer.RectTransform))
|
GUIListBox healList = new GUIListBox(new RectTransform(Vector2.One, healListContainer.RectTransform))
|
||||||
@@ -571,13 +571,13 @@ namespace Barotrauma
|
|||||||
|
|
||||||
GUILayoutGroup priceLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.5f), footerLayout.RectTransform), isHorizontal: true);
|
GUILayoutGroup priceLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.5f), footerLayout.RectTransform), isHorizontal: true);
|
||||||
GUITextBlock priceLabelBlock = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), priceLayout.RectTransform), TextManager.Get("campaignstore.total"));
|
GUITextBlock priceLabelBlock = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), priceLayout.RectTransform), TextManager.Get("campaignstore.total"));
|
||||||
GUITextBlock priceBlock = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), priceLayout.RectTransform), UpgradeStore.FormatCurrency(medicalClinic.GetTotalCost()), font: GUI.SubHeadingFont,
|
GUITextBlock priceBlock = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), priceLayout.RectTransform), TextManager.FormatCurrency(medicalClinic.GetTotalCost()), font: GUIStyle.SubHeadingFont,
|
||||||
textAlignment: Alignment.Right);
|
textAlignment: Alignment.Right);
|
||||||
|
|
||||||
GUILayoutGroup buttonLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.5f), footerLayout.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterRight);
|
GUILayoutGroup buttonLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.5f), footerLayout.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterRight);
|
||||||
GUIButton healButton = new GUIButton(new RectTransform(new Vector2(0.33f, 1f), buttonLayout.RectTransform), TextManager.Get("medicalclinic.heal"))
|
GUIButton healButton = new GUIButton(new RectTransform(new Vector2(0.33f, 1f), buttonLayout.RectTransform), TextManager.Get("medicalclinic.heal"))
|
||||||
{
|
{
|
||||||
Enabled = medicalClinic.PendingHeals.Any() && medicalClinic.GetTotalCost() < medicalClinic.GetMoney(),
|
Enabled = medicalClinic.PendingHeals.Any() && medicalClinic.GetWallet().CanAfford(medicalClinic.GetTotalCost()),
|
||||||
OnClicked = (button, _) =>
|
OnClicked = (button, _) =>
|
||||||
{
|
{
|
||||||
button.Enabled = false;
|
button.Enabled = false;
|
||||||
@@ -679,12 +679,12 @@ namespace Barotrauma
|
|||||||
|
|
||||||
GUILayoutGroup textLayout = new GUILayoutGroup(new RectTransform(Vector2.One, parentLayout.RectTransform), isHorizontal: true);
|
GUILayoutGroup textLayout = new GUILayoutGroup(new RectTransform(Vector2.One, parentLayout.RectTransform), isHorizontal: true);
|
||||||
|
|
||||||
string name = prefab.Name;
|
LocalizedString name = prefab.Name;
|
||||||
|
|
||||||
GUIFrame textContainer = new GUIFrame(new RectTransform(new Vector2(0.6f, 1f), textLayout.RectTransform), style: null);
|
GUIFrame textContainer = new GUIFrame(new RectTransform(new Vector2(0.6f, 1f), textLayout.RectTransform), style: null);
|
||||||
GUITextBlock afflictionName = new GUITextBlock(new RectTransform(Vector2.One, textContainer.RectTransform), name, font: GUI.SubHeadingFont);
|
GUITextBlock afflictionName = new GUITextBlock(new RectTransform(Vector2.One, textContainer.RectTransform), name, font: GUIStyle.SubHeadingFont);
|
||||||
|
|
||||||
GUITextBlock healCost = new GUITextBlock(new RectTransform(new Vector2(0.2f, 1f), textLayout.RectTransform), UpgradeStore.FormatCurrency(affliction.Price), textAlignment: Alignment.Center, font: GUI.LargeFont)
|
GUITextBlock healCost = new GUITextBlock(new RectTransform(new Vector2(0.2f, 1f), textLayout.RectTransform), TextManager.FormatCurrency(affliction.Price), textAlignment: Alignment.Center, font: GUIStyle.LargeFont)
|
||||||
{
|
{
|
||||||
Padding = Vector4.Zero
|
Padding = Vector4.Zero
|
||||||
};
|
};
|
||||||
@@ -702,7 +702,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
EnsureTextDoesntOverflow(name, afflictionName, textContainer.Rect, ImmutableArray.Create(textLayout, parentLayout));
|
EnsureTextDoesntOverflow(name.Value, afflictionName, textContainer.Rect, ImmutableArray.Create(textLayout, parentLayout));
|
||||||
|
|
||||||
healElement.Afflictions.Add(new PendingAfflictionElement(affliction, backgroundFrame, healCost));
|
healElement.Afflictions.Add(new PendingAfflictionElement(affliction, backgroundFrame, healCost));
|
||||||
|
|
||||||
@@ -720,8 +720,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
GUILayoutGroup textGroup = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.8f), parent.RectTransform));
|
GUILayoutGroup textGroup = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.8f), parent.RectTransform));
|
||||||
|
|
||||||
string? characterName = info.Name,
|
string? characterName = info.Name;
|
||||||
jobName = null;
|
LocalizedString? jobName = null;
|
||||||
|
|
||||||
GUITextBlock? nameBlock = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), textGroup.RectTransform), characterName),
|
GUITextBlock? nameBlock = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), textGroup.RectTransform), characterName),
|
||||||
jobBlock = null;
|
jobBlock = null;
|
||||||
@@ -741,7 +741,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (jobBlock is null) { return; }
|
if (jobBlock is null) { return; }
|
||||||
|
|
||||||
EnsureTextDoesntOverflow(jobName, jobBlock, parent.Rect, layoutGroups);
|
EnsureTextDoesntOverflow(jobName?.Value, jobBlock, parent.Rect, layoutGroups);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -766,14 +766,14 @@ namespace Barotrauma
|
|||||||
mainFrame.RectTransform.ScreenSpaceOffset = new Point((int)location.X, GameMain.GraphicsHeight - mainFrame.Rect.Height);
|
mainFrame.RectTransform.ScreenSpaceOffset = new Point((int)location.X, GameMain.GraphicsHeight - mainFrame.Rect.Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
GUITextBlock feedbackBlock = new GUITextBlock(new RectTransform(Vector2.One, mainFrame.RectTransform), TextManager.Get("pleasewaitupnp"), textAlignment: Alignment.Center, font: GUI.LargeFont, wrap: true)
|
GUITextBlock feedbackBlock = new GUITextBlock(new RectTransform(Vector2.One, mainFrame.RectTransform), TextManager.Get("pleasewaitupnp"), textAlignment: Alignment.Center, font: GUIStyle.LargeFont, wrap: true)
|
||||||
{
|
{
|
||||||
Visible = true
|
Visible = true
|
||||||
};
|
};
|
||||||
|
|
||||||
GUIButton treatAllButton = new GUIButton(new RectTransform(new Vector2(1f, 0.2f), mainLayout.RectTransform), TextManager.Get("medicalclinic.treatall"))
|
GUIButton treatAllButton = new GUIButton(new RectTransform(new Vector2(1f, 0.2f), mainLayout.RectTransform), TextManager.Get("medicalclinic.treatall"))
|
||||||
{
|
{
|
||||||
Font = GUI.SubHeadingFont,
|
Font = GUIStyle.SubHeadingFont,
|
||||||
Visible = false
|
Visible = false
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -793,7 +793,7 @@ namespace Barotrauma
|
|||||||
if (request.Result != MedicalClinic.RequestResult.Success)
|
if (request.Result != MedicalClinic.RequestResult.Success)
|
||||||
{
|
{
|
||||||
feedbackBlock.Text = GetErrorText(request.Result);
|
feedbackBlock.Text = GetErrorText(request.Result);
|
||||||
feedbackBlock.TextColor = GUI.Style.Red;
|
feedbackBlock.TextColor = GUIStyle.Red;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -844,11 +844,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
GUILayoutGroup topTextLayout = new GUILayoutGroup(new RectTransform(Vector2.One, topLayout.RectTransform), isHorizontal: true);
|
GUILayoutGroup topTextLayout = new GUILayoutGroup(new RectTransform(Vector2.One, topLayout.RectTransform), isHorizontal: true);
|
||||||
|
|
||||||
GUITextBlock prefabBlock = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), topTextLayout.RectTransform), prefab.Name, font: GUI.SubHeadingFont);
|
GUITextBlock prefabBlock = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), topTextLayout.RectTransform), prefab.Name, font: GUIStyle.SubHeadingFont);
|
||||||
|
|
||||||
Color textColor = Color.Lerp(GUI.Style.Orange, GUI.Style.Red, (int)affliction.AfflictionSeverity / 2f);
|
Color textColor = Color.Lerp(GUIStyle.Orange, GUIStyle.Red, (int)affliction.AfflictionSeverity / 2f);
|
||||||
|
|
||||||
string vitalityText = TextManager.GetWithVariable("medicalclinic.vitalitydifference", "[amount]", (-affliction.Strength).ToString());
|
LocalizedString vitalityText = TextManager.GetWithVariable("medicalclinic.vitalitydifference", "[amount]", (-affliction.Strength).ToString());
|
||||||
GUITextBlock vitalityBlock = new GUITextBlock(new RectTransform(new Vector2(0.25f, 1f), topTextLayout.RectTransform), vitalityText, textAlignment: Alignment.Center)
|
GUITextBlock vitalityBlock = new GUITextBlock(new RectTransform(new Vector2(0.25f, 1f), topTextLayout.RectTransform), vitalityText, textAlignment: Alignment.Center)
|
||||||
{
|
{
|
||||||
TextColor = textColor,
|
TextColor = textColor,
|
||||||
@@ -857,8 +857,8 @@ namespace Barotrauma
|
|||||||
AutoScaleHorizontal = true
|
AutoScaleHorizontal = true
|
||||||
};
|
};
|
||||||
|
|
||||||
string severityText = TextManager.Get($"AfflictionStrength{affliction.AfflictionSeverity}");
|
LocalizedString severityText = TextManager.Get($"AfflictionStrength{affliction.AfflictionSeverity}");
|
||||||
GUITextBlock severityBlock = new GUITextBlock(new RectTransform(new Vector2(0.25f, 1f), topTextLayout.RectTransform), severityText, textAlignment: Alignment.Center, font: GUI.SubHeadingFont)
|
GUITextBlock severityBlock = new GUITextBlock(new RectTransform(new Vector2(0.25f, 1f), topTextLayout.RectTransform), severityText, textAlignment: Alignment.Center, font: GUIStyle.SubHeadingFont)
|
||||||
{
|
{
|
||||||
TextColor = textColor,
|
TextColor = textColor,
|
||||||
DisabledTextColor = textColor * 0.5f,
|
DisabledTextColor = textColor * 0.5f,
|
||||||
@@ -866,17 +866,17 @@ namespace Barotrauma
|
|||||||
AutoScaleHorizontal = true
|
AutoScaleHorizontal = true
|
||||||
};
|
};
|
||||||
|
|
||||||
EnsureTextDoesntOverflow(prefab.Name, prefabBlock, prefabBlock.Rect, ImmutableArray.Create(mainLayout, topLayout, topTextLayout));
|
EnsureTextDoesntOverflow(prefab.Name.Value, prefabBlock, prefabBlock.Rect, ImmutableArray.Create(mainLayout, topLayout, topTextLayout));
|
||||||
|
|
||||||
GUILayoutGroup bottomLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.66f), mainLayout.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft);
|
GUILayoutGroup bottomLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.66f), mainLayout.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft);
|
||||||
|
|
||||||
GUILayoutGroup bottomTextLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 1f), bottomLayout.RectTransform));
|
GUILayoutGroup bottomTextLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 1f), bottomLayout.RectTransform));
|
||||||
GUITextBlock descriptionBlock = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), bottomTextLayout.RectTransform), ToolBox.LimitString(prefab.Description, GUI.IntScale(64)), wrap: true)
|
GUITextBlock descriptionBlock = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), bottomTextLayout.RectTransform), ToolBox.LimitString(prefab.Description, GUIStyle.Font, GUI.IntScale(64)), wrap: true)
|
||||||
{
|
{
|
||||||
ToolTip = prefab.Description
|
ToolTip = prefab.Description
|
||||||
};
|
};
|
||||||
|
|
||||||
GUITextBlock priceBlock = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), bottomTextLayout.RectTransform), UpgradeStore.FormatCurrency(affliction.Price), font: GUI.LargeFont);
|
GUITextBlock priceBlock = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), bottomTextLayout.RectTransform), TextManager.FormatCurrency(affliction.Price), font: GUIStyle.LargeFont);
|
||||||
|
|
||||||
GUIButton buyButton = new GUIButton(new RectTransform(new Vector2(0.2f, 0.75f), bottomLayout.RectTransform), style: "CrewManagementAddButton");
|
GUIButton buyButton = new GUIButton(new RectTransform(new Vector2(0.2f, 0.75f), bottomLayout.RectTransform), style: "CrewManagementAddButton");
|
||||||
|
|
||||||
@@ -931,7 +931,7 @@ namespace Barotrauma
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void EnsureTextDoesntOverflow(string? text, GUITextBlock textBlock, Rectangle bounds, ImmutableArray<GUILayoutGroup>? layoutGroups = null)
|
public static void EnsureTextDoesntOverflow(string? text, GUITextBlock textBlock, Rectangle bounds, ImmutableArray<GUILayoutGroup>? layoutGroups = null)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(text)) { return; }
|
if (string.IsNullOrWhiteSpace(text)) { return; }
|
||||||
|
|
||||||
@@ -968,7 +968,7 @@ namespace Barotrauma
|
|||||||
if (GameMain.IsSingleplayer || !(pendingHealList is { ErrorBlock: { } errorBlock, HealList: { } healList })) { return; }
|
if (GameMain.IsSingleplayer || !(pendingHealList is { ErrorBlock: { } errorBlock, HealList: { } healList })) { return; }
|
||||||
|
|
||||||
errorBlock.Visible = true;
|
errorBlock.Visible = true;
|
||||||
errorBlock.TextColor = GUI.Style.TextColor;
|
errorBlock.TextColor = GUIStyle.TextColorNormal;
|
||||||
errorBlock.Text = TextManager.Get("pleasewaitupnp");
|
errorBlock.Text = TextManager.Get("pleasewaitupnp");
|
||||||
healList.Visible = false;
|
healList.Visible = false;
|
||||||
|
|
||||||
@@ -983,7 +983,7 @@ namespace Barotrauma
|
|||||||
if (request.Result != MedicalClinic.RequestResult.Success)
|
if (request.Result != MedicalClinic.RequestResult.Success)
|
||||||
{
|
{
|
||||||
errorBlock.Text = GetErrorText(request.Result);
|
errorBlock.Text = GetErrorText(request.Result);
|
||||||
errorBlock.TextColor = GUI.Style.Red;
|
errorBlock.TextColor = GUIStyle.Red;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1011,7 +1011,7 @@ namespace Barotrauma
|
|||||||
selectedCrewAfflictionList = null;
|
selectedCrewAfflictionList = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetErrorText(MedicalClinic.RequestResult result)
|
private static LocalizedString GetErrorText(MedicalClinic.RequestResult result)
|
||||||
{
|
{
|
||||||
return result switch
|
return result switch
|
||||||
{
|
{
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -31,19 +31,12 @@ namespace Barotrauma
|
|||||||
private readonly List<SubmarineInfo> subsToShow;
|
private readonly List<SubmarineInfo> subsToShow;
|
||||||
private readonly SubmarineDisplayContent[] submarineDisplays = new SubmarineDisplayContent[submarinesPerPage];
|
private readonly SubmarineDisplayContent[] submarineDisplays = new SubmarineDisplayContent[submarinesPerPage];
|
||||||
private SubmarineInfo selectedSubmarine = null;
|
private SubmarineInfo selectedSubmarine = null;
|
||||||
private string purchaseAndSwitchText, purchaseOnlyText, deliveryText, currentSubText, deliveryFeeText, priceText, switchText, missingPreviewText, currencyShorthandText, currencyLongText;
|
private LocalizedString purchaseAndSwitchText, purchaseOnlyText, deliveryText, currentSubText, deliveryFeeText, priceText, switchText, missingPreviewText, currencyName;
|
||||||
private readonly RectTransform parent;
|
private readonly RectTransform parent;
|
||||||
private readonly Action closeAction;
|
private readonly Action closeAction;
|
||||||
private Sprite pageIndicator;
|
private Sprite pageIndicator;
|
||||||
|
|
||||||
public static readonly string[] DeliveryTextVariables = new string[] { "[submarinename1]", "[location1]", "[location2]", "[submarinename2]", "[amount]", "[currencyname]" };
|
private readonly LocalizedString[] messageBoxOptions;
|
||||||
public static readonly string[] SwitchTextVariables = new string[] { "[submarinename1]", "[submarinename2]" };
|
|
||||||
public static readonly string[] PurchaseAndSwitchTextVariables = new string[] { "[submarinename1]", "[amount]", "[currencyname]", "[submarinename2]" };
|
|
||||||
public static readonly string[] PurchaseTextVariables = new string[] { "[submarinename]", "[amount]", "[currencyname]" };
|
|
||||||
|
|
||||||
private static readonly string[] notEnoughCreditsDeliveryTextVariables = new string[] { "[currencyname]", "[submarinename]", "[location1]", "[location2]" };
|
|
||||||
private static readonly string[] notEnoughCreditsPurchaseTextVariables = new string[] { "[currencyname]", "[submarinename]" };
|
|
||||||
private readonly string[] messageBoxOptions;
|
|
||||||
|
|
||||||
public const int DeliveryFeePerDistanceTravelled = 1000;
|
public const int DeliveryFeePerDistanceTravelled = 1000;
|
||||||
public static bool ContentRefreshRequired = false;
|
public static bool ContentRefreshRequired = false;
|
||||||
@@ -77,11 +70,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (GameMain.Client == null)
|
if (GameMain.Client == null)
|
||||||
{
|
{
|
||||||
messageBoxOptions = new string[2] { TextManager.Get("Yes"), TextManager.Get("Cancel") };
|
messageBoxOptions = new LocalizedString[2] { TextManager.Get("Yes"), TextManager.Get("Cancel") };
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
messageBoxOptions = new string[2] { TextManager.Get("Yes") + " " + TextManager.Get("initiatevoting"), TextManager.Get("Cancel") };
|
messageBoxOptions = new LocalizedString[2] { TextManager.Get("Yes") + " " + TextManager.Get("initiatevoting"), TextManager.Get("Cancel") };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Submarine.MainSub?.Info == null) { return; }
|
if (Submarine.MainSub?.Info == null) { return; }
|
||||||
@@ -91,23 +84,19 @@ namespace Barotrauma
|
|||||||
private void Initialize()
|
private void Initialize()
|
||||||
{
|
{
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
currentSubText = TextManager.Get("currentsub");
|
||||||
|
deliveryFeeText = TextManager.Get("deliveryfee");
|
||||||
|
deliveryText = TextManager.Get("requestdeliverybutton");
|
||||||
|
switchText = TextManager.Get("switchtosubmarinebutton");
|
||||||
|
purchaseAndSwitchText = TextManager.Get("purchaseandswitch");
|
||||||
|
purchaseOnlyText = TextManager.Get("purchase");
|
||||||
|
priceText = TextManager.Get("price");
|
||||||
if (transferService)
|
if (transferService)
|
||||||
{
|
{
|
||||||
deliveryFee = CalculateDeliveryFee();
|
deliveryFee = CalculateDeliveryFee();
|
||||||
currentSubText = TextManager.Get("currentsub");
|
|
||||||
deliveryFeeText = TextManager.Get("deliveryfee");
|
|
||||||
deliveryText = TextManager.Get("requestdeliverybutton");
|
|
||||||
switchText = TextManager.Get("switchtosubmarinebutton");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
purchaseAndSwitchText = TextManager.Get("purchaseandswitch");
|
|
||||||
purchaseOnlyText = TextManager.Get("purchase");
|
|
||||||
priceText = TextManager.Get("price");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
currencyShorthandText = TextManager.Get("currencyformat");
|
currencyName = TextManager.Get("credit").Value.ToLowerInvariant();
|
||||||
currencyLongText = TextManager.Get("credit").ToLower();
|
|
||||||
|
|
||||||
UpdateSubmarines();
|
UpdateSubmarines();
|
||||||
missingPreviewText = TextManager.Get("SubPreviewImageNotFound");
|
missingPreviewText = TextManager.Get("SubPreviewImageNotFound");
|
||||||
@@ -135,9 +124,9 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
|
|
||||||
content = new GUILayoutGroup(new RectTransform(new Point(background.Rect.Width - HUDLayoutSettings.Padding * 4, background.Rect.Height - HUDLayoutSettings.Padding * 4), background.RectTransform, Anchor.Center)) { AbsoluteSpacing = (int)(HUDLayoutSettings.Padding * 1.5f) };
|
content = new GUILayoutGroup(new RectTransform(new Point(background.Rect.Width - HUDLayoutSettings.Padding * 4, background.Rect.Height - HUDLayoutSettings.Padding * 4), background.RectTransform, Anchor.Center)) { AbsoluteSpacing = (int)(HUDLayoutSettings.Padding * 1.5f) };
|
||||||
GUITextBlock header = new GUITextBlock(new RectTransform(new Vector2(1f, 0.0f), content.RectTransform), transferService ? TextManager.Get("switchsubmarineheader") : TextManager.GetWithVariable("outpostshipyard", "[location]", GameMain.GameSession.Map.CurrentLocation.Name), font: GUI.LargeFont);
|
GUITextBlock header = new GUITextBlock(new RectTransform(new Vector2(1f, 0.0f), content.RectTransform), transferService ? TextManager.Get("switchsubmarineheader") : TextManager.GetWithVariable("outpostshipyard", "[location]", GameMain.GameSession.Map.CurrentLocation.Name), font: GUIStyle.LargeFont);
|
||||||
header.CalculateHeightFromText(0, true);
|
header.CalculateHeightFromText(0, true);
|
||||||
GUITextBlock credits = new GUITextBlock(new RectTransform(Vector2.One, header.RectTransform), "", font: GUI.SubHeadingFont, textAlignment: Alignment.CenterRight)
|
GUITextBlock credits = new GUITextBlock(new RectTransform(Vector2.One, header.RectTransform), "", font: GUIStyle.SubHeadingFont, textAlignment: Alignment.CenterRight)
|
||||||
{
|
{
|
||||||
TextGetter = CampaignUI.GetMoney
|
TextGetter = CampaignUI.GetMoney
|
||||||
};
|
};
|
||||||
@@ -159,7 +148,7 @@ namespace Barotrauma
|
|||||||
specsFrame = new GUIListBox(new RectTransform(new Vector2(0.39f, 1f), infoFrame.RectTransform), style: null) { Spacing = GUI.IntScale(5), Padding = new Vector4(HUDLayoutSettings.Padding / 2f, HUDLayoutSettings.Padding, 0, 0) };
|
specsFrame = new GUIListBox(new RectTransform(new Vector2(0.39f, 1f), infoFrame.RectTransform), style: null) { Spacing = GUI.IntScale(5), Padding = new Vector4(HUDLayoutSettings.Padding / 2f, HUDLayoutSettings.Padding, 0, 0) };
|
||||||
new GUIFrame(new RectTransform(new Vector2(0.02f, 0.8f), infoFrame.RectTransform) { RelativeOffset = new Vector2(0.0f, 0.1f) }, style: "VerticalLine");
|
new GUIFrame(new RectTransform(new Vector2(0.02f, 0.8f), infoFrame.RectTransform) { RelativeOffset = new Vector2(0.0f, 0.1f) }, style: "VerticalLine");
|
||||||
GUIListBox descriptionFrame = new GUIListBox(new RectTransform(new Vector2(0.59f, 1f), infoFrame.RectTransform), style: null) { Padding = new Vector4(HUDLayoutSettings.Padding / 2f, HUDLayoutSettings.Padding * 1.5f, HUDLayoutSettings.Padding * 1.5f, HUDLayoutSettings.Padding / 2f) };
|
GUIListBox descriptionFrame = new GUIListBox(new RectTransform(new Vector2(0.59f, 1f), infoFrame.RectTransform), style: null) { Padding = new Vector4(HUDLayoutSettings.Padding / 2f, HUDLayoutSettings.Padding * 1.5f, HUDLayoutSettings.Padding * 1.5f, HUDLayoutSettings.Padding / 2f) };
|
||||||
descriptionTextBlock = new GUITextBlock(new RectTransform(new Vector2(1, 0), descriptionFrame.Content.RectTransform), string.Empty, font: GUI.Font, wrap: true) { CanBeFocused = false };
|
descriptionTextBlock = new GUITextBlock(new RectTransform(new Vector2(1, 0), descriptionFrame.Content.RectTransform), string.Empty, font: GUIStyle.Font, wrap: true) { CanBeFocused = false };
|
||||||
|
|
||||||
GUILayoutGroup buttonFrame = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.075f), content.RectTransform), childAnchor: Anchor.CenterRight) { IsHorizontal = true, AbsoluteSpacing = HUDLayoutSettings.Padding };
|
GUILayoutGroup buttonFrame = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.075f), content.RectTransform), childAnchor: Anchor.CenterRight) { IsHorizontal = true, AbsoluteSpacing = HUDLayoutSettings.Padding };
|
||||||
|
|
||||||
@@ -180,7 +169,7 @@ namespace Barotrauma
|
|||||||
SetConfirmButtonState(false);
|
SetConfirmButtonState(false);
|
||||||
|
|
||||||
pageIndicatorHolder = new GUIFrame(new RectTransform(new Vector2(1f, 1.5f), submarineControlsGroup.RectTransform), style: null);
|
pageIndicatorHolder = new GUIFrame(new RectTransform(new Vector2(1f, 1.5f), submarineControlsGroup.RectTransform), style: null);
|
||||||
pageIndicator = GUI.Style.GetComponentStyle("GUIPageIndicator").GetDefaultSprite();
|
pageIndicator = GUIStyle.GetComponentStyle("GUIPageIndicator").GetDefaultSprite();
|
||||||
UpdatePaging();
|
UpdatePaging();
|
||||||
|
|
||||||
for (int i = 0; i < submarineDisplays.Length; i++)
|
for (int i = 0; i < submarineDisplays.Length; i++)
|
||||||
@@ -191,9 +180,9 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
submarineDisplayElement.submarineImage = new GUIImage(new RectTransform(new Vector2(0.8f, 1f), submarineDisplayElement.background.RectTransform, Anchor.Center), null, true);
|
submarineDisplayElement.submarineImage = new GUIImage(new RectTransform(new Vector2(0.8f, 1f), submarineDisplayElement.background.RectTransform, Anchor.Center), null, true);
|
||||||
submarineDisplayElement.middleTextBlock = new GUITextBlock(new RectTransform(new Vector2(0.8f, 1f), submarineDisplayElement.background.RectTransform, Anchor.Center), string.Empty, textAlignment: Alignment.Center);
|
submarineDisplayElement.middleTextBlock = new GUITextBlock(new RectTransform(new Vector2(0.8f, 1f), submarineDisplayElement.background.RectTransform, Anchor.Center), string.Empty, textAlignment: Alignment.Center);
|
||||||
submarineDisplayElement.submarineName = new GUITextBlock(new RectTransform(new Vector2(1f, 0.1f), submarineDisplayElement.background.RectTransform, Anchor.TopCenter, Pivot.TopCenter) { AbsoluteOffset = new Point(0, HUDLayoutSettings.Padding) }, string.Empty, textAlignment: Alignment.Center, font: GUI.SubHeadingFont);
|
submarineDisplayElement.submarineName = new GUITextBlock(new RectTransform(new Vector2(1f, 0.1f), submarineDisplayElement.background.RectTransform, Anchor.TopCenter, Pivot.TopCenter) { AbsoluteOffset = new Point(0, HUDLayoutSettings.Padding) }, string.Empty, textAlignment: Alignment.Center, font: GUIStyle.SubHeadingFont);
|
||||||
submarineDisplayElement.submarineClass = new GUITextBlock(new RectTransform(new Vector2(1f, 0.1f), submarineDisplayElement.background.RectTransform, Anchor.TopCenter, Pivot.TopCenter) { AbsoluteOffset = new Point(0, HUDLayoutSettings.Padding + (int)GUI.Font.MeasureString(submarineDisplayElement.submarineName.Text).Y) }, string.Empty, textAlignment: Alignment.Center);
|
submarineDisplayElement.submarineClass = new GUITextBlock(new RectTransform(new Vector2(1f, 0.1f), submarineDisplayElement.background.RectTransform, Anchor.TopCenter, Pivot.TopCenter) { AbsoluteOffset = new Point(0, HUDLayoutSettings.Padding + (int)GUIStyle.Font.MeasureString(submarineDisplayElement.submarineName.Text).Y) }, string.Empty, textAlignment: Alignment.Center);
|
||||||
submarineDisplayElement.submarineFee = new GUITextBlock(new RectTransform(new Vector2(1f, 0.1f), submarineDisplayElement.background.RectTransform, Anchor.BottomCenter, Pivot.BottomCenter) { AbsoluteOffset = new Point(0, HUDLayoutSettings.Padding) }, string.Empty, textAlignment: Alignment.Center, font: GUI.SubHeadingFont);
|
submarineDisplayElement.submarineFee = new GUITextBlock(new RectTransform(new Vector2(1f, 0.1f), submarineDisplayElement.background.RectTransform, Anchor.BottomCenter, Pivot.BottomCenter) { AbsoluteOffset = new Point(0, HUDLayoutSettings.Padding) }, string.Empty, textAlignment: Alignment.Center, font: GUIStyle.SubHeadingFont);
|
||||||
submarineDisplayElement.selectSubmarineButton = new GUIButton(new RectTransform(Vector2.One, submarineDisplayElement.background.RectTransform), style: null);
|
submarineDisplayElement.selectSubmarineButton = new GUIButton(new RectTransform(Vector2.One, submarineDisplayElement.background.RectTransform), style: null);
|
||||||
submarineDisplayElement.previewButton = new GUIButton(new RectTransform(Vector2.One * 0.12f, submarineDisplayElement.background.RectTransform, anchor: Anchor.BottomRight, pivot: Pivot.BottomRight, scaleBasis: ScaleBasis.BothHeight) { AbsoluteOffset = new Point((int)(0.03f * background.Rect.Height)) }, style: "ExpandButton")
|
submarineDisplayElement.previewButton = new GUIButton(new RectTransform(Vector2.One * 0.12f, submarineDisplayElement.background.RectTransform, anchor: Anchor.BottomRight, pivot: Pivot.BottomRight, scaleBasis: ScaleBasis.BothHeight) { AbsoluteOffset = new Point((int)(0.03f * background.Rect.Height)) }, style: "ExpandButton")
|
||||||
{
|
{
|
||||||
@@ -342,7 +331,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (!GameMain.GameSession.IsSubmarineOwned(subToDisplay))
|
if (!GameMain.GameSession.IsSubmarineOwned(subToDisplay))
|
||||||
{
|
{
|
||||||
string amountString = currencyShorthandText.Replace("[credits]", subToDisplay.Price.ToString());
|
LocalizedString amountString = TextManager.FormatCurrency(subToDisplay.Price);
|
||||||
submarineDisplays[i].submarineFee.Text = priceText.Replace("[amount]", amountString).Replace("[currencyname]", string.Empty).TrimEnd();
|
submarineDisplays[i].submarineFee.Text = priceText.Replace("[amount]", amountString).Replace("[currencyname]", string.Empty).TrimEnd();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -351,7 +340,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (deliveryFee > 0)
|
if (deliveryFee > 0)
|
||||||
{
|
{
|
||||||
string amountString = currencyShorthandText.Replace("[credits]", deliveryFee.ToString());
|
LocalizedString amountString = TextManager.FormatCurrency(deliveryFee);
|
||||||
submarineDisplays[i].submarineFee.Text = deliveryFeeText.Replace("[amount]", amountString).Replace("[currencyname]", string.Empty).TrimEnd();
|
submarineDisplays[i].submarineFee.Text = deliveryFeeText.Replace("[amount]", amountString).Replace("[currencyname]", string.Empty).TrimEnd();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -535,7 +524,7 @@ namespace Barotrauma
|
|||||||
listBackground.Sprite = previewImage;
|
listBackground.Sprite = previewImage;
|
||||||
listBackground.SetCrop(true);
|
listBackground.SetCrop(true);
|
||||||
|
|
||||||
ScalableFont font = GUI.Font;
|
GUIFont font = GUIStyle.Font;
|
||||||
info.CreateSpecsWindow(specsFrame, font);
|
info.CreateSpecsWindow(specsFrame, font);
|
||||||
descriptionTextBlock.Text = info.Description;
|
descriptionTextBlock.Text = info.Description;
|
||||||
descriptionTextBlock.CalculateHeightFromText();
|
descriptionTextBlock.CalculateHeightFromText();
|
||||||
@@ -588,10 +577,13 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void ShowTransferPrompt()
|
private void ShowTransferPrompt()
|
||||||
{
|
{
|
||||||
if (GameMain.GameSession.Campaign.Money < deliveryFee && deliveryFee > 0)
|
if (!GameMain.GameSession.Campaign.Wallet.CanAfford(deliveryFee) && deliveryFee > 0)
|
||||||
{
|
{
|
||||||
new GUIMessageBox(TextManager.Get("deliveryrequestheader"), TextManager.GetWithVariables("notenoughmoneyfordeliverytext", notEnoughCreditsDeliveryTextVariables,
|
new GUIMessageBox(TextManager.Get("deliveryrequestheader"), TextManager.GetWithVariables("notenoughmoneyfordeliverytext",
|
||||||
new string[] { currencyLongText, selectedSubmarine.DisplayName, deliveryLocationName, GameMain.GameSession.Map.CurrentLocation.Name }));
|
("[currencyname]", currencyName),
|
||||||
|
("[submarinename]", selectedSubmarine.DisplayName),
|
||||||
|
("[location1]", deliveryLocationName),
|
||||||
|
("[location2]", GameMain.GameSession.Map.CurrentLocation.Name)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -599,13 +591,19 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (deliveryFee > 0)
|
if (deliveryFee > 0)
|
||||||
{
|
{
|
||||||
msgBox = new GUIMessageBox(TextManager.Get("deliveryrequestheader"), TextManager.GetWithVariables("deliveryrequesttext", DeliveryTextVariables,
|
msgBox = new GUIMessageBox(TextManager.Get("deliveryrequestheader"), TextManager.GetWithVariables("deliveryrequesttext",
|
||||||
new string[6] { selectedSubmarine.DisplayName, deliveryLocationName, GameMain.GameSession.Map.CurrentLocation.Name, CurrentOrPendingSubmarine().DisplayName, deliveryFee.ToString(), currencyLongText }), messageBoxOptions);
|
("[submarinename1]", selectedSubmarine.DisplayName),
|
||||||
|
("[location1]", deliveryLocationName),
|
||||||
|
("[location2]", GameMain.GameSession.Map.CurrentLocation.Name),
|
||||||
|
("[submarinename2]", CurrentOrPendingSubmarine().DisplayName),
|
||||||
|
("[amount]", deliveryFee.ToString()),
|
||||||
|
("[currencyname]", currencyName)), messageBoxOptions);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
msgBox = new GUIMessageBox(TextManager.Get("switchsubmarineheader"), TextManager.GetWithVariables("switchsubmarinetext", SwitchTextVariables,
|
msgBox = new GUIMessageBox(TextManager.Get("switchsubmarineheader"), TextManager.GetWithVariables("switchsubmarinetext",
|
||||||
new string[2] { CurrentOrPendingSubmarine().DisplayName, selectedSubmarine.DisplayName }), messageBoxOptions);
|
("[submarinename1]", CurrentOrPendingSubmarine().DisplayName),
|
||||||
|
("[submarinename2]", selectedSubmarine.DisplayName)), messageBoxOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
msgBox.Buttons[0].OnClicked = (applyButton, obj) =>
|
msgBox.Buttons[0].OnClicked = (applyButton, obj) =>
|
||||||
@@ -627,10 +625,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void ShowBuyPrompt(bool purchaseOnly)
|
private void ShowBuyPrompt(bool purchaseOnly)
|
||||||
{
|
{
|
||||||
if (GameMain.GameSession.Campaign.Money < selectedSubmarine.Price)
|
if (!GameMain.GameSession.Campaign.Wallet.CanAfford(selectedSubmarine.Price))
|
||||||
{
|
{
|
||||||
new GUIMessageBox(TextManager.Get("purchasesubmarineheader"), TextManager.GetWithVariables("notenoughmoneyforpurchasetext", notEnoughCreditsPurchaseTextVariables,
|
new GUIMessageBox(TextManager.Get("purchasesubmarineheader"), TextManager.GetWithVariables("notenoughmoneyforpurchasetext",
|
||||||
new string[2] { currencyLongText, selectedSubmarine.DisplayName }));
|
("[currencyname]", currencyName),
|
||||||
|
("[submarinename]", selectedSubmarine.DisplayName)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -638,8 +637,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (!purchaseOnly)
|
if (!purchaseOnly)
|
||||||
{
|
{
|
||||||
msgBox = new GUIMessageBox(TextManager.Get("purchaseandswitchsubmarineheader"), TextManager.GetWithVariables("purchaseandswitchsubmarinetext", PurchaseAndSwitchTextVariables,
|
msgBox = new GUIMessageBox(TextManager.Get("purchaseandswitchsubmarineheader"), TextManager.GetWithVariables("purchaseandswitchsubmarinetext",
|
||||||
new string[4] { selectedSubmarine.DisplayName, selectedSubmarine.Price.ToString(), currencyLongText, CurrentOrPendingSubmarine().DisplayName }), messageBoxOptions);
|
("[submarinename1]", selectedSubmarine.DisplayName),
|
||||||
|
("[amount]", selectedSubmarine.Price.ToString()),
|
||||||
|
("[currencyname]", currencyName),
|
||||||
|
("[submarinename2]", CurrentOrPendingSubmarine().DisplayName)), messageBoxOptions);
|
||||||
|
|
||||||
msgBox.Buttons[0].OnClicked = (applyButton, obj) =>
|
msgBox.Buttons[0].OnClicked = (applyButton, obj) =>
|
||||||
{
|
{
|
||||||
@@ -658,8 +660,10 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
msgBox = new GUIMessageBox(TextManager.Get("purchasesubmarineheader"), TextManager.GetWithVariables("purchasesubmarinetext", PurchaseTextVariables,
|
msgBox = new GUIMessageBox(TextManager.Get("purchasesubmarineheader"), TextManager.GetWithVariables("purchasesubmarinetext",
|
||||||
new string[3] { selectedSubmarine.DisplayName, selectedSubmarine.Price.ToString(), currencyLongText }), messageBoxOptions);
|
("[submarinename]", selectedSubmarine.DisplayName),
|
||||||
|
("[amount]", selectedSubmarine.Price.ToString()),
|
||||||
|
("[currencyname]", currencyName)), messageBoxOptions);
|
||||||
|
|
||||||
msgBox.Buttons[0].OnClicked = (applyButton, obj) =>
|
msgBox.Buttons[0].OnClicked = (applyButton, obj) =>
|
||||||
{
|
{
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -19,11 +19,7 @@ namespace Barotrauma
|
|||||||
private set;
|
private set;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Slice
|
public bool Slice => Slices != null;
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Rectangle[] Slices
|
public Rectangle[] Slices
|
||||||
{
|
{
|
||||||
@@ -54,7 +50,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public TransitionMode TransitionMode { get; private set; }
|
public TransitionMode TransitionMode { get; private set; }
|
||||||
|
|
||||||
public UISprite(XElement element)
|
public UISprite(ContentXElement element)
|
||||||
{
|
{
|
||||||
Sprite = new Sprite(element);
|
Sprite = new Sprite(element);
|
||||||
MaintainAspectRatio = element.GetAttributeBool("maintainaspectratio", false);
|
MaintainAspectRatio = element.GetAttributeBool("maintainaspectratio", false);
|
||||||
@@ -69,6 +65,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
Vector4 sliceVec = element.GetAttributeVector4("slice", Vector4.Zero);
|
Vector4 sliceVec = element.GetAttributeVector4("slice", Vector4.Zero);
|
||||||
|
Slices = null;
|
||||||
if (sliceVec != Vector4.Zero)
|
if (sliceVec != Vector4.Zero)
|
||||||
{
|
{
|
||||||
minBorderScale = element.GetAttributeFloat("minborderscale", 0.1f);
|
minBorderScale = element.GetAttributeFloat("minborderscale", 0.1f);
|
||||||
@@ -76,7 +73,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
Rectangle slice = new Rectangle((int)sliceVec.X, (int)sliceVec.Y, (int)(sliceVec.Z - sliceVec.X), (int)(sliceVec.W - sliceVec.Y));
|
Rectangle slice = new Rectangle((int)sliceVec.X, (int)sliceVec.Y, (int)(sliceVec.Z - sliceVec.X), (int)(sliceVec.W - sliceVec.Y));
|
||||||
|
|
||||||
Slice = true;
|
|
||||||
Slices = new Rectangle[9];
|
Slices = new Rectangle[9];
|
||||||
|
|
||||||
//top-left
|
//top-left
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private readonly CampaignUI campaignUI;
|
private readonly CampaignUI campaignUI;
|
||||||
private CampaignMode? Campaign => campaignUI.Campaign;
|
private CampaignMode? Campaign => campaignUI.Campaign;
|
||||||
private int AvailableMoney => Campaign?.Money ?? 0;
|
private Wallet PlayerWallet => Campaign?.Wallet ?? Wallet.Invalid;
|
||||||
private UpgradeTab selectedUpgradeTab = UpgradeTab.Upgrade;
|
private UpgradeTab selectedUpgradeTab = UpgradeTab.Upgrade;
|
||||||
|
|
||||||
private GUIMessageBox? currectConfirmation;
|
private GUIMessageBox? currectConfirmation;
|
||||||
@@ -61,7 +61,7 @@ namespace Barotrauma
|
|||||||
private Vector2[][] subHullVertices = new Vector2[0][];
|
private Vector2[][] subHullVertices = new Vector2[0][];
|
||||||
private List<Structure> submarineWalls = new List<Structure>();
|
private List<Structure> submarineWalls = new List<Structure>();
|
||||||
|
|
||||||
public MapEntity? HoveredItem;
|
public MapEntity? HoveredEntity;
|
||||||
private bool highlightWalls;
|
private bool highlightWalls;
|
||||||
|
|
||||||
private UpgradeCategory? currentUpgradeCategory;
|
private UpgradeCategory? currentUpgradeCategory;
|
||||||
@@ -73,6 +73,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private Point screenResolution;
|
private Point screenResolution;
|
||||||
|
|
||||||
|
private bool needsRefresh = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// While set to true any call to <see cref="RefreshUpgradeList"/> will cause the buy button to be disabled and to not update the prices.
|
/// While set to true any call to <see cref="RefreshUpgradeList"/> will cause the buy button to be disabled and to not update the prices.
|
||||||
/// This is to prevent us from buying another upgrade before the server has given us the new prices and causing potential syncing issues.
|
/// This is to prevent us from buying another upgrade before the server has given us the new prices and causing potential syncing issues.
|
||||||
@@ -102,12 +104,18 @@ namespace Barotrauma
|
|||||||
CreateUI(upgradeFrame);
|
CreateUI(upgradeFrame);
|
||||||
|
|
||||||
if (Campaign == null) { return; }
|
if (Campaign == null) { return; }
|
||||||
Campaign.UpgradeManager.OnUpgradesChanged += RefreshAll;
|
Campaign.UpgradeManager.OnUpgradesChanged += RequestRefresh;
|
||||||
Campaign.CargoManager.OnPurchasedItemsChanged += RefreshAll;
|
Campaign.CargoManager.OnPurchasedItemsChanged += RequestRefresh;
|
||||||
Campaign.CargoManager.OnSoldItemsChanged += RefreshAll;
|
Campaign.CargoManager.OnSoldItemsChanged += RequestRefresh;
|
||||||
|
Campaign.OnMoneyChanged.RegisterOverwriteExisting(nameof(UpgradeStore).ToIdentifier(), e => { RequestRefresh(); } );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RefreshAll()
|
public void RequestRefresh()
|
||||||
|
{
|
||||||
|
needsRefresh = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RefreshAll()
|
||||||
{
|
{
|
||||||
switch (selectedUpgradeTab)
|
switch (selectedUpgradeTab)
|
||||||
{
|
{
|
||||||
@@ -130,6 +138,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
needsRefresh = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RefreshUpgradeList()
|
private void RefreshUpgradeList()
|
||||||
@@ -184,7 +193,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
// reset the order first
|
// reset the order first
|
||||||
foreach (UpgradeCategory category in UpgradeCategory.Categories)
|
foreach (UpgradeCategory category in UpgradeCategory.Categories.OrderBy(c => c.Name))
|
||||||
{
|
{
|
||||||
GUIComponent component = categoryList.Content.FindChild(c => c.UserData is CategoryData categoryData && categoryData.Category == category);
|
GUIComponent component = categoryList.Content.FindChild(c => c.UserData is CategoryData categoryData && categoryData.Category == category);
|
||||||
component?.SetAsLastChild();
|
component?.SetAsLastChild();
|
||||||
@@ -245,7 +254,7 @@ namespace Barotrauma
|
|||||||
* |----------------------------|
|
* |----------------------------|
|
||||||
*/
|
*/
|
||||||
GUILayoutGroup tooltipLayout = new GUILayoutGroup(rectT(0.95f,0.95f, ItemInfoFrame, Anchor.Center)) { Stretch = true };
|
GUILayoutGroup tooltipLayout = new GUILayoutGroup(rectT(0.95f,0.95f, ItemInfoFrame, Anchor.Center)) { Stretch = true };
|
||||||
new GUITextBlock(rectT(1, 0, tooltipLayout), string.Empty, font: GUI.SubHeadingFont) { UserData = "itemname" };
|
new GUITextBlock(rectT(1, 0, tooltipLayout), string.Empty, font: GUIStyle.SubHeadingFont) { UserData = "itemname" };
|
||||||
new GUITextBlock(rectT(1, 0, tooltipLayout), TextManager.Get("UpgradeUITooltip.UpgradeListHeader"));
|
new GUITextBlock(rectT(1, 0, tooltipLayout), TextManager.Get("UpgradeUITooltip.UpgradeListHeader"));
|
||||||
new GUIListBox(rectT(1, 0.5f, tooltipLayout), style: null) { ScrollBarVisible = false, AutoHideScrollBar = false, SmoothScroll = true, UserData = "upgradelist"};
|
new GUIListBox(rectT(1, 0.5f, tooltipLayout), style: null) { ScrollBarVisible = false, AutoHideScrollBar = false, SmoothScroll = true, UserData = "upgradelist"};
|
||||||
new GUITextBlock(rectT(1, 0, tooltipLayout), string.Empty) { UserData = "moreindicator" };
|
new GUITextBlock(rectT(1, 0, tooltipLayout), string.Empty) { UserData = "moreindicator" };
|
||||||
@@ -268,7 +277,7 @@ namespace Barotrauma
|
|||||||
GUILayoutGroup leftLayout = new GUILayoutGroup(rectT(0.5f, 1, topHeaderLayout)) { RelativeSpacing = 0.05f };
|
GUILayoutGroup leftLayout = new GUILayoutGroup(rectT(0.5f, 1, topHeaderLayout)) { RelativeSpacing = 0.05f };
|
||||||
GUILayoutGroup locationLayout = new GUILayoutGroup(rectT(1, 0.5f, leftLayout), isHorizontal: true);
|
GUILayoutGroup locationLayout = new GUILayoutGroup(rectT(1, 0.5f, leftLayout), isHorizontal: true);
|
||||||
GUIImage submarineIcon = new GUIImage(rectT(new Point(locationLayout.Rect.Height, locationLayout.Rect.Height), locationLayout), style: "SubmarineIcon", scaleToFit: true);
|
GUIImage submarineIcon = new GUIImage(rectT(new Point(locationLayout.Rect.Height, locationLayout.Rect.Height), locationLayout), style: "SubmarineIcon", scaleToFit: true);
|
||||||
new GUITextBlock(rectT(1.0f - submarineIcon.RectTransform.RelativeSize.X, 1, locationLayout), TextManager.Get("UpgradeUI.Title"), font: GUI.LargeFont);
|
new GUITextBlock(rectT(1.0f - submarineIcon.RectTransform.RelativeSize.X, 1, locationLayout), TextManager.Get("UpgradeUI.Title"), font: GUIStyle.LargeFont);
|
||||||
categoryButtonLayout = new GUILayoutGroup(rectT(0.4f, 0.3f, leftLayout), isHorizontal: true) { Stretch = true };
|
categoryButtonLayout = new GUILayoutGroup(rectT(0.4f, 0.3f, leftLayout), isHorizontal: true) { Stretch = true };
|
||||||
GUIButton upgradeButton = new GUIButton(rectT(1, 1f, categoryButtonLayout), TextManager.Get("UICategory.Upgrades"), style: "GUITabButton") { UserData = UpgradeTab.Upgrade, Selected = selectedUpgradeTab == UpgradeTab.Upgrade };
|
GUIButton upgradeButton = new GUIButton(rectT(1, 1f, categoryButtonLayout), TextManager.Get("UICategory.Upgrades"), style: "GUITabButton") { UserData = UpgradeTab.Upgrade, Selected = selectedUpgradeTab == UpgradeTab.Upgrade };
|
||||||
GUIButton repairButton = new GUIButton(rectT(1, 1f, categoryButtonLayout), TextManager.Get("UICategory.Maintenance"), style: "GUITabButton") { UserData = UpgradeTab.Repairs, Selected = selectedUpgradeTab == UpgradeTab.Repairs };
|
GUIButton repairButton = new GUIButton(rectT(1, 1f, categoryButtonLayout), TextManager.Get("UICategory.Maintenance"), style: "GUITabButton") { UserData = UpgradeTab.Repairs, Selected = selectedUpgradeTab == UpgradeTab.Repairs };
|
||||||
@@ -285,9 +294,9 @@ namespace Barotrauma
|
|||||||
*/
|
*/
|
||||||
GUILayoutGroup rightLayout = new GUILayoutGroup(rectT(0.5f, 1, topHeaderLayout), childAnchor: Anchor.TopRight);
|
GUILayoutGroup rightLayout = new GUILayoutGroup(rectT(0.5f, 1, topHeaderLayout), childAnchor: Anchor.TopRight);
|
||||||
GUILayoutGroup priceLayout = new GUILayoutGroup(rectT(1, 0.8f, rightLayout), childAnchor: Anchor.Center) { RelativeSpacing = 0.08f };
|
GUILayoutGroup priceLayout = new GUILayoutGroup(rectT(1, 0.8f, rightLayout), childAnchor: Anchor.Center) { RelativeSpacing = 0.08f };
|
||||||
new GUITextBlock(rectT(1f, 0f, priceLayout), TextManager.Get("CampaignStore.Balance"), font: GUI.SubHeadingFont, textAlignment: Alignment.Right);
|
new GUITextBlock(rectT(1f, 0f, priceLayout), TextManager.Get("CampaignStore.Balance"), font: GUIStyle.SubHeadingFont, textAlignment: Alignment.Right);
|
||||||
new GUITextBlock(rectT(1f, 0f, priceLayout), FormatCurrency(AvailableMoney, format: true), font: GUI.SubHeadingFont, textAlignment: Alignment.Right) { TextGetter = () => FormatCurrency(AvailableMoney, format: true) };
|
new GUITextBlock(rectT(1f, 0f, priceLayout), TextManager.FormatCurrency(PlayerWallet.Balance), font: GUIStyle.SubHeadingFont, textAlignment: Alignment.Right) { TextGetter = () => TextManager.FormatCurrency(PlayerWallet.Balance) };
|
||||||
new GUIFrame(rectT(0.5f, 0.1f, rightLayout, Anchor.BottomRight), style: "HorizontalLine") { IgnoreLayoutGroups = true };
|
new GUIFrame(rectT(0.5f, 0.1f, rightLayout, Anchor.BottomRight), style: "HorizontalLine") { IgnoreLayoutGroups = true };
|
||||||
|
|
||||||
repairButton.OnClicked = upgradeButton.OnClicked = (button, o) =>
|
repairButton.OnClicked = upgradeButton.OnClicked = (button, o) =>
|
||||||
{
|
{
|
||||||
@@ -343,15 +352,15 @@ namespace Barotrauma
|
|||||||
private void DrawItemSwapPreview(SpriteBatch spriteBatch, GUICustomComponent component)
|
private void DrawItemSwapPreview(SpriteBatch spriteBatch, GUICustomComponent component)
|
||||||
{
|
{
|
||||||
var selectedItem = customizeTabOpen ?
|
var selectedItem = customizeTabOpen ?
|
||||||
activeItemSwapSlideDown?.UserData as Item ?? HoveredItem as Item :
|
activeItemSwapSlideDown?.UserData as Item ?? HoveredEntity as Item :
|
||||||
HoveredItem as Item;
|
HoveredEntity as Item;
|
||||||
if (selectedItem?.Prefab.SwappableItem == null) { return; }
|
if (selectedItem?.Prefab.SwappableItem == null) { return; }
|
||||||
|
|
||||||
Sprite schematicsSprite = selectedItem.Prefab.SwappableItem.SchematicSprite;
|
Sprite schematicsSprite = selectedItem.Prefab.SwappableItem.SchematicSprite;
|
||||||
if (schematicsSprite == null) { return; }
|
if (schematicsSprite == null) { return; }
|
||||||
float schematicsScale = Math.Min(component.Rect.Width / 2 / schematicsSprite.size.X, component.Rect.Height / schematicsSprite.size.Y);
|
float schematicsScale = Math.Min(component.Rect.Width / 2 / schematicsSprite.size.X, component.Rect.Height / schematicsSprite.size.Y);
|
||||||
Vector2 center = new Vector2(component.Rect.Center.X, component.Rect.Center.Y);
|
Vector2 center = new Vector2(component.Rect.Center.X, component.Rect.Center.Y);
|
||||||
schematicsSprite.Draw(spriteBatch, new Vector2(component.Rect.X, center.Y), GUI.Style.Green, new Vector2(0, schematicsSprite.size.Y / 2),
|
schematicsSprite.Draw(spriteBatch, new Vector2(component.Rect.X, center.Y), GUIStyle.Green, new Vector2(0, schematicsSprite.size.Y / 2),
|
||||||
scale: schematicsScale);
|
scale: schematicsScale);
|
||||||
|
|
||||||
var swappableItemList = selectedUpgradeCategoryLayout?.FindChild("prefablist", true) as GUIListBox;
|
var swappableItemList = selectedUpgradeCategoryLayout?.FindChild("prefablist", true) as GUIListBox;
|
||||||
@@ -359,10 +368,10 @@ namespace Barotrauma
|
|||||||
ItemPrefab swapTo = highlightedElement?.UserData as ItemPrefab ?? selectedItem.PendingItemSwap;
|
ItemPrefab swapTo = highlightedElement?.UserData as ItemPrefab ?? selectedItem.PendingItemSwap;
|
||||||
if (swapTo?.SwappableItem == null) { return; }
|
if (swapTo?.SwappableItem == null) { return; }
|
||||||
Sprite? schematicsSprite2 = swapTo.SwappableItem?.SchematicSprite;
|
Sprite? schematicsSprite2 = swapTo.SwappableItem?.SchematicSprite;
|
||||||
schematicsSprite2?.Draw(spriteBatch, new Vector2(component.Rect.Right, center.Y), GUI.Style.Orange, new Vector2(schematicsSprite2.size.X, schematicsSprite2.size.Y / 2),
|
schematicsSprite2?.Draw(spriteBatch, new Vector2(component.Rect.Right, center.Y), GUIStyle.Orange, new Vector2(schematicsSprite2.size.X, schematicsSprite2.size.Y / 2),
|
||||||
scale: Math.Min(component.Rect.Width / 2 / schematicsSprite2.size.X, component.Rect.Height / schematicsSprite2.size.Y));
|
scale: Math.Min(component.Rect.Width / 2 / schematicsSprite2.size.X, component.Rect.Height / schematicsSprite2.size.Y));
|
||||||
|
|
||||||
var arrowSprite = GUI.Style?.GetComponentStyle("GUIButtonToggleRight")?.GetDefaultSprite();
|
var arrowSprite = GUIStyle.GetComponentStyle("GUIButtonToggleRight")?.GetDefaultSprite();
|
||||||
if (arrowSprite != null)
|
if (arrowSprite != null)
|
||||||
{
|
{
|
||||||
arrowSprite.Draw(spriteBatch, center, scale: GUI.Scale);
|
arrowSprite.Draw(spriteBatch, center, scale: GUI.Scale);
|
||||||
@@ -426,14 +435,14 @@ namespace Barotrauma
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AvailableMoney >= hullRepairCost)
|
if (PlayerWallet.CanAfford(hullRepairCost))
|
||||||
{
|
{
|
||||||
string body = TextManager.GetWithVariable("WallRepairs.PurchasePromptBody", "[amount]", hullRepairCost.ToString());
|
LocalizedString body = TextManager.GetWithVariable("WallRepairs.PurchasePromptBody", "[amount]", hullRepairCost.ToString());
|
||||||
currectConfirmation = EventEditorScreen.AskForConfirmation(TextManager.Get("Upgrades.PurchasePromptTitle"), body, () =>
|
currectConfirmation = EventEditorScreen.AskForConfirmation(TextManager.Get("Upgrades.PurchasePromptTitle"), body, () =>
|
||||||
{
|
{
|
||||||
if (AvailableMoney >= hullRepairCost)
|
if (PlayerWallet.Balance >= hullRepairCost)
|
||||||
{
|
{
|
||||||
Campaign.Money -= hullRepairCost;
|
PlayerWallet.TryDeduct(hullRepairCost);
|
||||||
GameAnalyticsManager.AddMoneySpentEvent(hullRepairCost, GameAnalyticsManager.MoneySink.Service, "hullrepairs");
|
GameAnalyticsManager.AddMoneySpentEvent(hullRepairCost, GameAnalyticsManager.MoneySink.Service, "hullrepairs");
|
||||||
Campaign.PurchasedHullRepairs = true;
|
Campaign.PurchasedHullRepairs = true;
|
||||||
button.Enabled = false;
|
button.Enabled = false;
|
||||||
@@ -461,14 +470,14 @@ namespace Barotrauma
|
|||||||
|
|
||||||
CreateRepairEntry(currentStoreLayout.Content, TextManager.Get("repairallitems"), "RepairItemsButton", itemRepairCost, (button, o) =>
|
CreateRepairEntry(currentStoreLayout.Content, TextManager.Get("repairallitems"), "RepairItemsButton", itemRepairCost, (button, o) =>
|
||||||
{
|
{
|
||||||
if (AvailableMoney >= itemRepairCost && !Campaign.PurchasedItemRepairs)
|
if (PlayerWallet.Balance >= itemRepairCost && !Campaign.PurchasedItemRepairs)
|
||||||
{
|
{
|
||||||
string body = TextManager.GetWithVariable("ItemRepairs.PurchasePromptBody", "[amount]", itemRepairCost.ToString());
|
LocalizedString body = TextManager.GetWithVariable("ItemRepairs.PurchasePromptBody", "[amount]", itemRepairCost.ToString());
|
||||||
currectConfirmation = EventEditorScreen.AskForConfirmation(TextManager.Get("Upgrades.PurchasePromptTitle"), body, () =>
|
currectConfirmation = EventEditorScreen.AskForConfirmation(TextManager.Get("Upgrades.PurchasePromptTitle"), body, () =>
|
||||||
{
|
{
|
||||||
if (AvailableMoney >= itemRepairCost && !Campaign.PurchasedItemRepairs)
|
if (PlayerWallet.Balance >= itemRepairCost && !Campaign.PurchasedItemRepairs)
|
||||||
{
|
{
|
||||||
Campaign.Money -= itemRepairCost;
|
PlayerWallet.TryDeduct(itemRepairCost);
|
||||||
GameAnalyticsManager.AddMoneySpentEvent(hullRepairCost, GameAnalyticsManager.MoneySink.Service, "devicerepairs");
|
GameAnalyticsManager.AddMoneySpentEvent(hullRepairCost, GameAnalyticsManager.MoneySink.Service, "devicerepairs");
|
||||||
Campaign.PurchasedItemRepairs = true;
|
Campaign.PurchasedItemRepairs = true;
|
||||||
button.Enabled = false;
|
button.Enabled = false;
|
||||||
@@ -493,7 +502,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
foreach (var (item, itemFrame) in itemPreviews)
|
foreach (var (item, itemFrame) in itemPreviews)
|
||||||
{
|
{
|
||||||
itemFrame.OutlineColor = itemFrame.Color = isHovered && item.GetComponent<DockingPort>() == null ? GUI.Style.Orange : previewWhite;
|
itemFrame.OutlineColor = itemFrame.Color = isHovered && item.GetComponent<DockingPort>() == null ? GUIStyle.Orange : previewWhite;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
@@ -507,14 +516,14 @@ namespace Barotrauma
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AvailableMoney >= shuttleRetrieveCost && !Campaign.PurchasedLostShuttles)
|
if (PlayerWallet.CanAfford(shuttleRetrieveCost) && !Campaign.PurchasedLostShuttles)
|
||||||
{
|
{
|
||||||
string body = TextManager.GetWithVariable("ReplaceLostShuttles.PurchasePromptBody", "[amount]", shuttleRetrieveCost.ToString());
|
LocalizedString body = TextManager.GetWithVariable("ReplaceLostShuttles.PurchasePromptBody", "[amount]", shuttleRetrieveCost.ToString());
|
||||||
currectConfirmation = EventEditorScreen.AskForConfirmation(TextManager.Get("Upgrades.PurchasePromptTitle"), body, () =>
|
currectConfirmation = EventEditorScreen.AskForConfirmation(TextManager.Get("Upgrades.PurchasePromptTitle"), body, () =>
|
||||||
{
|
{
|
||||||
if (AvailableMoney >= shuttleRetrieveCost && !Campaign.PurchasedLostShuttles)
|
if (PlayerWallet.Balance >= shuttleRetrieveCost && !Campaign.PurchasedLostShuttles)
|
||||||
{
|
{
|
||||||
Campaign.Money -= shuttleRetrieveCost;
|
PlayerWallet.TryDeduct(shuttleRetrieveCost);
|
||||||
GameAnalyticsManager.AddMoneySpentEvent(hullRepairCost, GameAnalyticsManager.MoneySink.Service, "retrieveshuttle");
|
GameAnalyticsManager.AddMoneySpentEvent(hullRepairCost, GameAnalyticsManager.MoneySink.Service, "retrieveshuttle");
|
||||||
Campaign.PurchasedLostShuttles = true;
|
Campaign.PurchasedLostShuttles = true;
|
||||||
button.Enabled = false;
|
button.Enabled = false;
|
||||||
@@ -540,7 +549,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (subInfo.LeftBehindDockingPortIDs.Contains(item.ID))
|
if (subInfo.LeftBehindDockingPortIDs.Contains(item.ID))
|
||||||
{
|
{
|
||||||
itemFrame.OutlineColor = itemFrame.Color = subInfo.BlockedDockingPortIDs.Contains(item.ID) ? GUI.Style.Red : GUI.Style.Green;
|
itemFrame.OutlineColor = itemFrame.Color = subInfo.BlockedDockingPortIDs.Contains(item.ID) ? GUIStyle.Red : GUIStyle.Green;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -551,7 +560,7 @@ namespace Barotrauma
|
|||||||
}, disableElement: true);
|
}, disableElement: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateRepairEntry(GUIComponent parent, string title, string imageStyle, int price, GUIButton.OnClickedHandler onPressed, bool isDisabled, Func<bool, bool>? onHover = null, bool disableElement = false)
|
private void CreateRepairEntry(GUIComponent parent, LocalizedString title, string imageStyle, int price, GUIButton.OnClickedHandler onPressed, bool isDisabled, Func<bool, bool>? onHover = null, bool disableElement = false)
|
||||||
{
|
{
|
||||||
GUIFrame frameChild = new GUIFrame(rectT(new Point(parent.Rect.Width, (int) (96 * GUI.Scale)), parent), style: "UpgradeUIFrame");
|
GUIFrame frameChild = new GUIFrame(rectT(new Point(parent.Rect.Width, (int) (96 * GUI.Scale)), parent), style: "UpgradeUIFrame");
|
||||||
frameChild.SelectedColor = frameChild.Color;
|
frameChild.SelectedColor = frameChild.Color;
|
||||||
@@ -569,16 +578,16 @@ namespace Barotrauma
|
|||||||
GUILayoutGroup contentLayout = new GUILayoutGroup(rectT(0.9f, 0.85f, frameChild, Anchor.Center), isHorizontal: true);
|
GUILayoutGroup contentLayout = new GUILayoutGroup(rectT(0.9f, 0.85f, frameChild, Anchor.Center), isHorizontal: true);
|
||||||
var repairIcon = new GUIFrame(rectT(new Point(contentLayout.Rect.Height, contentLayout.Rect.Height), contentLayout), style: imageStyle);
|
var repairIcon = new GUIFrame(rectT(new Point(contentLayout.Rect.Height, contentLayout.Rect.Height), contentLayout), style: imageStyle);
|
||||||
GUILayoutGroup textLayout = new GUILayoutGroup(rectT(0.8f - repairIcon.RectTransform.RelativeSize.X, 1, contentLayout)) { Stretch = true };
|
GUILayoutGroup textLayout = new GUILayoutGroup(rectT(0.8f - repairIcon.RectTransform.RelativeSize.X, 1, contentLayout)) { Stretch = true };
|
||||||
new GUITextBlock(rectT(1, 0, textLayout), title, font: GUI.SubHeadingFont) { CanBeFocused = false, AutoScaleHorizontal = true };
|
new GUITextBlock(rectT(1, 0, textLayout), title, font: GUIStyle.SubHeadingFont) { CanBeFocused = false, AutoScaleHorizontal = true };
|
||||||
new GUITextBlock(rectT(1, 0, textLayout), FormatCurrency(price));
|
new GUITextBlock(rectT(1, 0, textLayout), TextManager.FormatCurrency(price));
|
||||||
GUILayoutGroup buyButtonLayout = new GUILayoutGroup(rectT(0.2f, 1, contentLayout), childAnchor: Anchor.Center) { UserData = "buybutton" };
|
GUILayoutGroup buyButtonLayout = new GUILayoutGroup(rectT(0.2f, 1, contentLayout), childAnchor: Anchor.Center) { UserData = "buybutton" };
|
||||||
new GUIButton(rectT(0.7f, 0.5f, buyButtonLayout), string.Empty, style: "RepairBuyButton") { ClickSound = GUISoundType.HireRepairClick, Enabled = AvailableMoney >= price && !isDisabled, OnClicked = onPressed };
|
new GUIButton(rectT(0.7f, 0.5f, buyButtonLayout), string.Empty, style: "RepairBuyButton") { ClickSound = GUISoundType.HireRepairClick, Enabled = PlayerWallet.Balance >= price && !isDisabled, OnClicked = onPressed };
|
||||||
contentLayout.Recalculate();
|
contentLayout.Recalculate();
|
||||||
buyButtonLayout.Recalculate();
|
buyButtonLayout.Recalculate();
|
||||||
|
|
||||||
if (disableElement)
|
if (disableElement)
|
||||||
{
|
{
|
||||||
frameChild.Enabled = AvailableMoney >= price && !isDisabled;
|
frameChild.Enabled = PlayerWallet.Balance >= price && !isDisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!HasPermission)
|
if (!HasPermission)
|
||||||
@@ -610,9 +619,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
Dictionary<UpgradeCategory, List<UpgradePrefab>> upgrades = new Dictionary<UpgradeCategory, List<UpgradePrefab>>();
|
Dictionary<UpgradeCategory, List<UpgradePrefab>> upgrades = new Dictionary<UpgradeCategory, List<UpgradePrefab>>();
|
||||||
|
|
||||||
foreach (UpgradeCategory category in UpgradeCategory.Categories)
|
foreach (UpgradeCategory category in UpgradeCategory.Categories.OrderBy(c => c.Name))
|
||||||
{
|
{
|
||||||
foreach (UpgradePrefab prefab in UpgradePrefab.Prefabs)
|
foreach (UpgradePrefab prefab in UpgradePrefab.Prefabs.OrderBy(p => p.Name))
|
||||||
{
|
{
|
||||||
if (prefab.UpgradeCategories.Contains(category))
|
if (prefab.UpgradeCategories.Contains(category))
|
||||||
{
|
{
|
||||||
@@ -661,7 +670,7 @@ 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: GUIStyle.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)
|
||||||
@@ -742,7 +751,7 @@ namespace Barotrauma
|
|||||||
GUIComponent[] categoryFrames = GetFrames(category);
|
GUIComponent[] categoryFrames = GetFrames(category);
|
||||||
foreach (GUIComponent itemFrame in itemPreviews.Values)
|
foreach (GUIComponent itemFrame in itemPreviews.Values)
|
||||||
{
|
{
|
||||||
itemFrame.OutlineColor = itemFrame.Color = categoryFrames.Contains(itemFrame) ? GUI.Style.Orange : previewWhite;
|
itemFrame.OutlineColor = itemFrame.Color = categoryFrames.Contains(itemFrame) ? GUIStyle.Orange : previewWhite;
|
||||||
itemFrame.Children.ForEach(c => c.Color = itemFrame.Color);
|
itemFrame.Children.ForEach(c => c.Color = itemFrame.Color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -790,7 +799,7 @@ namespace Barotrauma
|
|||||||
GUIComponent[] categoryFrames = GetFrames(category);
|
GUIComponent[] categoryFrames = GetFrames(category);
|
||||||
foreach (GUIComponent itemFrame in itemPreviews.Values)
|
foreach (GUIComponent itemFrame in itemPreviews.Values)
|
||||||
{
|
{
|
||||||
itemFrame.OutlineColor = itemFrame.Color = categoryFrames.Contains(itemFrame) ? GUI.Style.Orange : previewWhite;
|
itemFrame.OutlineColor = itemFrame.Color = categoryFrames.Contains(itemFrame) ? GUIStyle.Orange : previewWhite;
|
||||||
itemFrame.Children.ForEach(c => c.Color = itemFrame.Color);
|
itemFrame.Children.ForEach(c => c.Color = itemFrame.Color);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -851,8 +860,8 @@ namespace Barotrauma
|
|||||||
if (linkedItems.Min(it => it.ID) < item.ID) { return; }
|
if (linkedItems.Min(it => it.ID) < item.ID) { return; }
|
||||||
|
|
||||||
var currentOrPending = item.PendingItemSwap ?? item.Prefab;
|
var currentOrPending = item.PendingItemSwap ?? item.Prefab;
|
||||||
string name = currentOrPending.Name;
|
LocalizedString name = currentOrPending.Name;
|
||||||
string nameWithQuantity = "";
|
LocalizedString nameWithQuantity = "";
|
||||||
if (linkedItems.Count > 1)
|
if (linkedItems.Count > 1)
|
||||||
{
|
{
|
||||||
foreach (ItemPrefab distinctItem in linkedItems.Select(it => it.Prefab).Distinct())
|
foreach (ItemPrefab distinctItem in linkedItems.Select(it => it.Prefab).Distinct())
|
||||||
@@ -881,7 +890,7 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
GUILayoutGroup buttonLayout = new GUILayoutGroup(rectT(1f, 1f, toggleButton.Frame), isHorizontal: true);
|
GUILayoutGroup buttonLayout = new GUILayoutGroup(rectT(1f, 1f, toggleButton.Frame), isHorizontal: true);
|
||||||
|
|
||||||
string slotText = "";
|
LocalizedString slotText = "";
|
||||||
if (linkedItems.Count > 1)
|
if (linkedItems.Count > 1)
|
||||||
{
|
{
|
||||||
slotText = TextManager.GetWithVariable("weaponslot", "[number]", string.Join(", ", linkedItems.Select(it => (swappableEntities.IndexOf(it) + 1).ToString())));
|
slotText = TextManager.GetWithVariable("weaponslot", "[number]", string.Join(", ", linkedItems.Select(it => (swappableEntities.IndexOf(it) + 1).ToString())));
|
||||||
@@ -891,13 +900,13 @@ namespace Barotrauma
|
|||||||
slotText = TextManager.GetWithVariable("weaponslot", "[number]", (swappableEntities.IndexOf(item) + 1).ToString());
|
slotText = TextManager.GetWithVariable("weaponslot", "[number]", (swappableEntities.IndexOf(item) + 1).ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
new GUITextBlock(rectT(0.3f, 1f, buttonLayout), text: slotText, font: GUI.SubHeadingFont);
|
new GUITextBlock(rectT(0.3f, 1f, buttonLayout), text: slotText, font: GUIStyle.SubHeadingFont);
|
||||||
GUILayoutGroup group = new GUILayoutGroup(rectT(0.7f, 1f, buttonLayout), isHorizontal: true) { Stretch = true };
|
GUILayoutGroup group = new GUILayoutGroup(rectT(0.7f, 1f, buttonLayout), isHorizontal: true) { Stretch = true };
|
||||||
|
|
||||||
string title = item.PendingItemSwap != null ? TextManager.GetWithVariable("upgrades.pendingitem", "[itemname]", name) : nameWithQuantity;
|
var title = item.PendingItemSwap != null ? TextManager.GetWithVariable("upgrades.pendingitem", "[itemname]", name) : nameWithQuantity;
|
||||||
GUITextBlock text = new GUITextBlock(rectT(0.7f, 1f, group), text: title, font: GUI.SubHeadingFont, textAlignment: Alignment.Right, parseRichText: true)
|
GUITextBlock text = new GUITextBlock(rectT(0.7f, 1f, group), text: RichString.Rich(title), font: GUIStyle.SubHeadingFont, textAlignment: Alignment.Right)
|
||||||
{
|
{
|
||||||
TextColor = GUI.Style.Orange
|
TextColor = GUIStyle.Orange
|
||||||
};
|
};
|
||||||
GUIImage arrowImage = new GUIImage(rectT(0.5f, 1f, group, scaleBasis: ScaleBasis.BothHeight), style: "SlideDownArrow", scaleToFit: true);
|
GUIImage arrowImage = new GUIImage(rectT(0.5f, 1f, group, scaleBasis: ScaleBasis.BothHeight), style: "SlideDownArrow", scaleToFit: true);
|
||||||
|
|
||||||
@@ -911,7 +920,7 @@ namespace Barotrauma
|
|||||||
List<GUIFrame> frames = new List<GUIFrame>();
|
List<GUIFrame> frames = new List<GUIFrame>();
|
||||||
if (currentOrPending != null)
|
if (currentOrPending != null)
|
||||||
{
|
{
|
||||||
bool canUninstall = item.PendingItemSwap != null || !string.IsNullOrEmpty(currentOrPending.SwappableItem?.ReplacementOnUninstall);
|
bool canUninstall = item.PendingItemSwap != null || !(currentOrPending.SwappableItem?.ReplacementOnUninstall.IsEmpty ?? true);
|
||||||
|
|
||||||
bool isUninstallPending = item.Prefab.SwappableItem != null && item.PendingItemSwap?.Identifier == item.Prefab.SwappableItem.ReplacementOnUninstall;
|
bool isUninstallPending = item.Prefab.SwappableItem != null && item.PendingItemSwap?.Identifier == item.Prefab.SwappableItem.ReplacementOnUninstall;
|
||||||
if (isUninstallPending) { canUninstall = false; }
|
if (isUninstallPending) { canUninstall = false; }
|
||||||
@@ -928,9 +937,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
string textTag = item.PendingItemSwap != null ? "upgrades.cancelitemswappromptbody" : "upgrades.itemuninstallpromptbody";
|
string textTag = item.PendingItemSwap != null ? "upgrades.cancelitemswappromptbody" : "upgrades.itemuninstallpromptbody";
|
||||||
if (isUninstallPending) { textTag = "upgrades.cancelitemuninstallpromptbody"; }
|
if (isUninstallPending) { textTag = "upgrades.cancelitemuninstallpromptbody"; }
|
||||||
string promptBody = TextManager.GetWithVariables(textTag,
|
LocalizedString promptBody = TextManager.GetWithVariable(textTag, "[itemtouninstall]", isUninstallPending ? item.Name : currentOrPending.Name);
|
||||||
new[] { "[itemtouninstall]" },
|
|
||||||
new[] { isUninstallPending ? item.Name : currentOrPending.Name });
|
|
||||||
currectConfirmation = EventEditorScreen.AskForConfirmation(TextManager.Get("upgrades.refundprompttitle"), promptBody, () =>
|
currectConfirmation = EventEditorScreen.AskForConfirmation(TextManager.Get("upgrades.refundprompttitle"), promptBody, () =>
|
||||||
{
|
{
|
||||||
if (GameMain.NetworkMember != null)
|
if (GameMain.NetworkMember != null)
|
||||||
@@ -965,14 +972,14 @@ namespace Barotrauma
|
|||||||
buttonStyle: isPurchased ? "WeaponInstallButton" : "StoreAddToCrateButton"));
|
buttonStyle: isPurchased ? "WeaponInstallButton" : "StoreAddToCrateButton"));
|
||||||
|
|
||||||
if (!(frames.Last().FindChild(c => c is GUIButton, recursive: true) is GUIButton buyButton)) { continue; }
|
if (!(frames.Last().FindChild(c => c is GUIButton, recursive: true) is GUIButton buyButton)) { continue; }
|
||||||
if (Campaign.Money >= price)
|
if (PlayerWallet.CanAfford(price))
|
||||||
{
|
{
|
||||||
buyButton.Enabled = true;
|
buyButton.Enabled = true;
|
||||||
buyButton.OnClicked += (button, o) =>
|
buyButton.OnClicked += (button, o) =>
|
||||||
{
|
{
|
||||||
string promptBody = TextManager.GetWithVariables(isPurchased ? "upgrades.itemswappromptbody" : "upgrades.purchaseitemswappromptbody",
|
LocalizedString promptBody = TextManager.GetWithVariables(isPurchased ? "upgrades.itemswappromptbody" : "upgrades.purchaseitemswappromptbody",
|
||||||
new[] { "[itemtoinstall]", "[amount]" },
|
("[itemtoinstall]", replacement.Name),
|
||||||
new[] { replacement.Name, (replacement.SwappableItem.GetPrice(Campaign?.Map?.CurrentLocation) * linkedItems.Count).ToString() });
|
("[amount]", (replacement.SwappableItem.GetPrice(Campaign?.Map?.CurrentLocation) * linkedItems.Count).ToString()));
|
||||||
currectConfirmation = EventEditorScreen.AskForConfirmation(TextManager.Get("Upgrades.PurchasePromptTitle"), promptBody, () =>
|
currectConfirmation = EventEditorScreen.AskForConfirmation(TextManager.Get("Upgrades.PurchasePromptTitle"), promptBody, () =>
|
||||||
{
|
{
|
||||||
if (GameMain.NetworkMember != null)
|
if (GameMain.NetworkMember != null)
|
||||||
@@ -1019,7 +1026,7 @@ namespace Barotrauma
|
|||||||
var linkedItems = Campaign.UpgradeManager.GetLinkedItemsToSwap(item);
|
var linkedItems = Campaign.UpgradeManager.GetLinkedItemsToSwap(item);
|
||||||
foreach (var itemPreview in itemPreviews)
|
foreach (var itemPreview in itemPreviews)
|
||||||
{
|
{
|
||||||
itemPreview.Value.OutlineColor = itemPreview.Value.Color = linkedItems.Contains(itemPreview.Key) ? GUI.Style.Orange : previewWhite;
|
itemPreview.Value.OutlineColor = itemPreview.Value.Color = linkedItems.Contains(itemPreview.Key) ? GUIStyle.Orange : previewWhite;
|
||||||
}
|
}
|
||||||
foreach (GUIComponent otherComponent in toggleButton.Parent.Children)
|
foreach (GUIComponent otherComponent in toggleButton.Parent.Children)
|
||||||
{
|
{
|
||||||
@@ -1041,7 +1048,7 @@ namespace Barotrauma
|
|||||||
foreach (var itemPreview in itemPreviews)
|
foreach (var itemPreview in itemPreviews)
|
||||||
{
|
{
|
||||||
if (currentStoreLayout?.SelectedData is CategoryData categoryData && !categoryData.Category.ItemTags.Any(t => itemPreview.Key.HasTag(t))) { continue; }
|
if (currentStoreLayout?.SelectedData is CategoryData categoryData && !categoryData.Category.ItemTags.Any(t => itemPreview.Key.HasTag(t))) { continue; }
|
||||||
itemPreview.Value.OutlineColor = itemPreview.Value.Color = GUI.Style.Orange;
|
itemPreview.Value.OutlineColor = itemPreview.Value.Color = GUIStyle.Orange;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
activeItemSwapSlideDown = toggleButton.Selected ? toggleButton : null;
|
activeItemSwapSlideDown = toggleButton.Selected ? toggleButton : null;
|
||||||
@@ -1058,7 +1065,7 @@ namespace Barotrauma
|
|||||||
return CreateUpgradeEntry(rectTransform, prefab.Sprite, prefab.Name, prefab.Description, price, new CategoryData(category, prefab), addBuyButton, upgradePrefab: prefab, currentLevel: campaign.UpgradeManager.GetUpgradeLevel(prefab, category));
|
return CreateUpgradeEntry(rectTransform, prefab.Sprite, prefab.Name, prefab.Description, price, new CategoryData(category, prefab), addBuyButton, upgradePrefab: prefab, currentLevel: campaign.UpgradeManager.GetUpgradeLevel(prefab, category));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GUIFrame CreateUpgradeEntry(RectTransform parent, Sprite sprite, string title, string body, int price, object? userData, bool addBuyButton = true, bool addProgressBar = true, string buttonStyle = "UpgradeBuyButton", UpgradePrefab upgradePrefab = null, int currentLevel = 0)
|
public static GUIFrame CreateUpgradeEntry(RectTransform parent, Sprite sprite, LocalizedString title, LocalizedString body, int price, object? userData, bool addBuyButton = true, bool addProgressBar = true, string buttonStyle = "UpgradeBuyButton", UpgradePrefab? upgradePrefab = null, int currentLevel = 0)
|
||||||
{
|
{
|
||||||
float progressBarHeight = 0.25f;
|
float progressBarHeight = 0.25f;
|
||||||
|
|
||||||
@@ -1080,29 +1087,29 @@ namespace Barotrauma
|
|||||||
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, scaleBasis: ScaleBasis.BothHeight), sprite, scaleToFit: true) { CanBeFocused = false };
|
var icon = new GUIImage(rectT(0.9f, 0.9f, imageLayout, scaleBasis: ScaleBasis.BothHeight), 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));
|
||||||
var name = new GUITextBlock(rectT(1, 0.25f, textLayout), title, font: GUI.SubHeadingFont, parseRichText: true) { AutoScaleHorizontal = true, AutoScaleVertical = true, Padding = Vector4.Zero };
|
var name = new GUITextBlock(rectT(1, 0.25f, textLayout), RichString.Rich(title), font: GUIStyle.SubHeadingFont) { AutoScaleHorizontal = true, AutoScaleVertical = true, Padding = Vector4.Zero };
|
||||||
GUILayoutGroup descriptionLayout = new GUILayoutGroup(rectT(1, 0.75f - progressBarHeight, textLayout));
|
GUILayoutGroup descriptionLayout = new GUILayoutGroup(rectT(1, 0.75f - progressBarHeight, textLayout));
|
||||||
var description = new GUITextBlock(rectT(1, 1, descriptionLayout), body, font: GUI.SmallFont, wrap: true, textAlignment: Alignment.TopLeft) { Padding = Vector4.Zero };
|
var description = new GUITextBlock(rectT(1, 1, descriptionLayout), body, font: GUIStyle.SmallFont, wrap: true, textAlignment: Alignment.TopLeft) { Padding = Vector4.Zero };
|
||||||
GUILayoutGroup? progressLayout = null;
|
GUILayoutGroup? progressLayout = null;
|
||||||
GUILayoutGroup? buyButtonLayout = null;
|
GUILayoutGroup? buyButtonLayout = null;
|
||||||
|
|
||||||
if (addProgressBar)
|
if (addProgressBar)
|
||||||
{
|
{
|
||||||
progressLayout = new GUILayoutGroup(rectT(1, 0.25f, textLayout), isHorizontal: true, childAnchor: Anchor.CenterLeft) { UserData = "progressbar" };
|
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, GUIStyle.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: GUIStyle.SmallFont, textAlignment: Alignment.Center) { Padding = Vector4.Zero };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addBuyButton)
|
if (addBuyButton)
|
||||||
{
|
{
|
||||||
string formattedPrice = FormatCurrency(Math.Abs(price));
|
var formattedPrice = TextManager.FormatCurrency(Math.Abs(price));
|
||||||
//negative price = refund
|
//negative price = refund
|
||||||
if (price < 0) { formattedPrice = "+" + formattedPrice; }
|
if (price < 0) { formattedPrice = "+" + formattedPrice; }
|
||||||
buyButtonLayout = new GUILayoutGroup(rectT(0.2f, 1, prefabLayout), childAnchor: Anchor.TopCenter) { UserData = "buybutton" };
|
buyButtonLayout = new GUILayoutGroup(rectT(0.2f, 1, prefabLayout), childAnchor: Anchor.TopCenter) { UserData = "buybutton" };
|
||||||
var priceText = new GUITextBlock(rectT(1, 0.2f, buyButtonLayout), formattedPrice, textAlignment: Alignment.Center);
|
var priceText = new GUITextBlock(rectT(1, 0.2f, buyButtonLayout), formattedPrice, textAlignment: Alignment.Center);
|
||||||
if (price < 0)
|
if (price < 0)
|
||||||
{
|
{
|
||||||
priceText.TextColor = GUI.Style.Green;
|
priceText.TextColor = GUIStyle.Green;
|
||||||
}
|
}
|
||||||
else if (price == 0)
|
else if (price == 0)
|
||||||
{
|
{
|
||||||
@@ -1120,8 +1127,8 @@ namespace Barotrauma
|
|||||||
// cut the description if it overflows and add a tooltip to it
|
// cut the description if it overflows and add a tooltip to it
|
||||||
for (int i = 100; i > 0 && description.Rect.Height > descriptionLayout.Rect.Height; i--)
|
for (int i = 100; i > 0 && description.Rect.Height > descriptionLayout.Rect.Height; i--)
|
||||||
{
|
{
|
||||||
string[] lines = description.WrappedText.Split('\n');
|
var lines = description.WrappedText.Split('\n');
|
||||||
var newString = string.Join('\n', lines.Take(lines.Length - 1));
|
var newString = string.Join('\n', lines.Take(lines.Count - 1));
|
||||||
if (0 >= newString.Length - 4) { break; }
|
if (0 >= newString.Length - 4) { break; }
|
||||||
|
|
||||||
description.Text = newString.Substring(0, newString.Length - 4) + "...";
|
description.Text = newString.Substring(0, newString.Length - 4) + "...";
|
||||||
@@ -1185,7 +1192,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
buyButton.OnClicked += (button, o) =>
|
buyButton.OnClicked += (button, o) =>
|
||||||
{
|
{
|
||||||
string promptBody = TextManager.GetWithVariables("Upgrades.PurchasePromptBody", new []{ "[upgradename]", "[amount]"}, new []{ prefab.Name, prefab.Price.GetBuyprice(Campaign.UpgradeManager.GetUpgradeLevel(prefab, category), Campaign.Map?.CurrentLocation).ToString() });
|
LocalizedString promptBody = TextManager.GetWithVariables("Upgrades.PurchasePromptBody",
|
||||||
|
("[upgradename]", prefab.Name),
|
||||||
|
("[amount]", prefab.Price.GetBuyprice(Campaign.UpgradeManager.GetUpgradeLevel(prefab, category), Campaign.Map?.CurrentLocation).ToString()));
|
||||||
currectConfirmation = EventEditorScreen.AskForConfirmation(TextManager.Get("Upgrades.PurchasePromptTitle"), promptBody, () =>
|
currectConfirmation = EventEditorScreen.AskForConfirmation(TextManager.Get("Upgrades.PurchasePromptTitle"), promptBody, () =>
|
||||||
{
|
{
|
||||||
if (GameMain.NetworkMember != null)
|
if (GameMain.NetworkMember != null)
|
||||||
@@ -1225,7 +1234,7 @@ namespace Barotrauma
|
|||||||
itemName.Text = entity is Item ? entity.Name : TextManager.Get("upgradecategory.walls");
|
itemName.Text = entity is Item ? entity.Name : TextManager.Get("upgradecategory.walls");
|
||||||
if (slotIndex > -1)
|
if (slotIndex > -1)
|
||||||
{
|
{
|
||||||
itemName.Text = TextManager.GetWithVariables("weaponslotwithname", new string[] { "[number]", "[weaponname]" }, new string[] { slotIndex.ToString(), itemName.Text });
|
itemName.Text = TextManager.GetWithVariables("weaponslotwithname", ("[number]", slotIndex.ToString()), ("[weaponname]", itemName.Text));
|
||||||
}
|
}
|
||||||
upgradeList.Content.ClearChildren();
|
upgradeList.Content.ClearChildren();
|
||||||
for (var i = 0; i < upgrades.Count && i < maxUpgrades; i++)
|
for (var i = 0; i < upgrades.Count && i < maxUpgrades; i++)
|
||||||
@@ -1246,7 +1255,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (textBlock.UserData is Tuple<int, UpgradePrefab> tuple && tuple.Item2 == prefab)
|
if (textBlock.UserData is Tuple<int, UpgradePrefab> tuple && tuple.Item2 == prefab)
|
||||||
{
|
{
|
||||||
string tooltip = CreateListEntry(tuple.Item2.Name, level + tuple.Item1);
|
var tooltip = CreateListEntry(tuple.Item2.Name, level + tuple.Item1);
|
||||||
textBlock.Text = tooltip;
|
textBlock.Text = tooltip;
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
@@ -1275,7 +1284,7 @@ namespace Barotrauma
|
|||||||
moreIndicator.CalculateHeightFromText();
|
moreIndicator.CalculateHeightFromText();
|
||||||
layout.Recalculate();
|
layout.Recalculate();
|
||||||
|
|
||||||
static string CreateListEntry(string name, int level) => TextManager.GetWithVariables("upgradeuitooltip.upgradelistelement", new[] { "[upgradename]", "[level]" }, new[] { name, $"{level}" });
|
static LocalizedString CreateListEntry(LocalizedString name, int level) => TextManager.GetWithVariables("upgradeuitooltip.upgradelistelement", ("[upgradename]", name), ("[level]", $"{level}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<UpgradeCategory> GetApplicableCategories(Submarine drawnSubmarine)
|
public static IEnumerable<UpgradeCategory> GetApplicableCategories(Submarine drawnSubmarine)
|
||||||
@@ -1294,7 +1303,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (Campaign == null) { return; }
|
if (Campaign == null) { return; }
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
GameMain.GameSession?.SubmarineInfo?.CheckSubsLeftBehind();
|
GameMain.GameSession?.SubmarineInfo?.CheckSubsLeftBehind();
|
||||||
drawnSubmarine = Submarine.MainSub;
|
drawnSubmarine = Submarine.MainSub;
|
||||||
@@ -1312,6 +1323,10 @@ namespace Barotrauma
|
|||||||
// we also need this when we first load in so we know which category entries to disable since the CampaignUI is created before the submarine is loaded in.
|
// we also need this when we first load in so we know which category entries to disable since the CampaignUI is created before the submarine is loaded in.
|
||||||
RefreshAll();
|
RefreshAll();
|
||||||
}
|
}
|
||||||
|
if (needsRefresh)
|
||||||
|
{
|
||||||
|
RefreshAll();
|
||||||
|
}
|
||||||
|
|
||||||
// accept an active confirmation popup if any
|
// accept an active confirmation popup if any
|
||||||
if (PlayerInput.KeyHit(Keys.Enter) && GUIMessageBox.MessageBoxes.Any())
|
if (PlayerInput.KeyHit(Keys.Enter) && GUIMessageBox.MessageBoxes.Any())
|
||||||
@@ -1334,16 +1349,16 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (GUI.MouseOn == frame)
|
if (GUI.MouseOn == frame)
|
||||||
{
|
{
|
||||||
if (HoveredItem != item) { CreateItemTooltip(item); }
|
if (HoveredEntity != item) { CreateItemTooltip(item); }
|
||||||
HoveredItem = item;
|
HoveredEntity = item;
|
||||||
if (PlayerInput.PrimaryMouseButtonClicked() && selectedUpgradeTab == UpgradeTab.Upgrade && currentStoreLayout != null)
|
if (PlayerInput.PrimaryMouseButtonClicked() && selectedUpgradeTab == UpgradeTab.Upgrade && currentStoreLayout != null)
|
||||||
{
|
{
|
||||||
if (customizeTabOpen)
|
if (customizeTabOpen)
|
||||||
{
|
{
|
||||||
if (selectedUpgradeCategoryLayout != null)
|
if (selectedUpgradeCategoryLayout != null)
|
||||||
{
|
{
|
||||||
var linkedItems = HoveredItem is Item ? Campaign.UpgradeManager.GetLinkedItemsToSwap((Item)HoveredItem) : new List<Item>();
|
var linkedItems = HoveredEntity is Item hoveredItem ? Campaign.UpgradeManager.GetLinkedItemsToSwap(hoveredItem) : new List<Item>();
|
||||||
if (selectedUpgradeCategoryLayout.FindChild(c => c.UserData as Item == HoveredItem || linkedItems.Contains(c.UserData as Item), recursive: true) is GUIButton itemElement)
|
if (selectedUpgradeCategoryLayout.FindChild(c => c.UserData is Item item && (item == HoveredEntity || linkedItems.Contains(item)), recursive: true) is GUIButton itemElement)
|
||||||
{
|
{
|
||||||
if (!itemElement.Selected) { itemElement.OnClicked(itemElement, itemElement.UserData); }
|
if (!itemElement.Selected) { itemElement.OnClicked(itemElement, itemElement.UserData); }
|
||||||
(itemElement.Parent?.Parent?.Parent as GUIListBox)?.ScrollToElement(itemElement);
|
(itemElement.Parent?.Parent?.Parent as GUIListBox)?.ScrollToElement(itemElement);
|
||||||
@@ -1370,8 +1385,8 @@ namespace Barotrauma
|
|||||||
// use pnpoly algorithm to detect if our mouse is within any of the hull polygons
|
// use pnpoly algorithm to detect if our mouse is within any of the hull polygons
|
||||||
if (subHullVertices.Any(hullVertex => ToolBox.PointIntersectsWithPolygon(PlayerInput.MousePosition, hullVertex)))
|
if (subHullVertices.Any(hullVertex => ToolBox.PointIntersectsWithPolygon(PlayerInput.MousePosition, hullVertex)))
|
||||||
{
|
{
|
||||||
if (HoveredItem != firstStructure && !(firstStructure is null)) { CreateItemTooltip(firstStructure); }
|
if (HoveredEntity != firstStructure && !(firstStructure is null)) { CreateItemTooltip(firstStructure); }
|
||||||
HoveredItem = firstStructure;
|
HoveredEntity = firstStructure;
|
||||||
isMouseOnStructure = true;
|
isMouseOnStructure = true;
|
||||||
GUI.MouseCursor = CursorState.Hand;
|
GUI.MouseCursor = CursorState.Hand;
|
||||||
|
|
||||||
@@ -1382,7 +1397,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isMouseOnStructure) { HoveredItem = null; }
|
if (!isMouseOnStructure) { HoveredEntity = null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// flip the tooltip if it is outside of the screen
|
// flip the tooltip if it is outside of the screen
|
||||||
@@ -1417,9 +1432,9 @@ namespace Barotrauma
|
|||||||
*/
|
*/
|
||||||
submarineInfoFrame = new GUILayoutGroup(rectT(0.25f, 0.2f, mainStoreLayout, Anchor.TopRight)) { IgnoreLayoutGroups = true };
|
submarineInfoFrame = new GUILayoutGroup(rectT(0.25f, 0.2f, mainStoreLayout, Anchor.TopRight)) { IgnoreLayoutGroups = true };
|
||||||
// submarine name
|
// submarine name
|
||||||
new GUITextBlock(rectT(1, 0, submarineInfoFrame), submarine.Info.DisplayName, textAlignment: Alignment.Right, font: GUI.LargeFont);
|
new GUITextBlock(rectT(1, 0, submarineInfoFrame), submarine.Info.DisplayName, textAlignment: Alignment.Right, font: GUIStyle.LargeFont);
|
||||||
// submarine class
|
// submarine class
|
||||||
new GUITextBlock(rectT(1, 0, submarineInfoFrame), $"{TextManager.GetWithVariable("submarineclass.classsuffixformat", "[type]", TextManager.Get($"submarineclass.{submarine.Info.SubmarineClass}"))}", textAlignment: Alignment.Right, font: GUI.Font);
|
new GUITextBlock(rectT(1, 0, submarineInfoFrame), $"{TextManager.GetWithVariable("submarineclass.classsuffixformat", "[type]", TextManager.Get($"submarineclass.{submarine.Info.SubmarineClass}"))}", textAlignment: Alignment.Right, font: GUIStyle.Font);
|
||||||
var description = new GUITextBlock(rectT(1, 0, submarineInfoFrame), submarine.Info.Description, textAlignment: Alignment.Right, wrap: true);
|
var description = new GUITextBlock(rectT(1, 0, submarineInfoFrame), submarine.Info.Description, textAlignment: Alignment.Right, wrap: true);
|
||||||
submarineInfoFrame.RectTransform.ScreenSpaceOffset = new Point(0, (int)(16 * GUI.Scale));
|
submarineInfoFrame.RectTransform.ScreenSpaceOffset = new Point(0, (int)(16 * GUI.Scale));
|
||||||
|
|
||||||
@@ -1448,7 +1463,7 @@ namespace Barotrauma
|
|||||||
Point size = new Point((int) (spriteSize * item.Scale / dockedBorders.Width * hullContainer.Rect.Width));
|
Point size = new Point((int) (spriteSize * item.Scale / dockedBorders.Width * hullContainer.Rect.Width));
|
||||||
itemFrame = new GUIImage(rectT(size, component, Anchor.Center), icon, scaleToFit: true)
|
itemFrame = new GUIImage(rectT(size, component, Anchor.Center), icon, scaleToFit: true)
|
||||||
{
|
{
|
||||||
SelectedColor = GUI.Style.Orange,
|
SelectedColor = GUIStyle.Orange,
|
||||||
Color = previewWhite,
|
Color = previewWhite,
|
||||||
HoverCursor = CursorState.Hand,
|
HoverCursor = CursorState.Hand,
|
||||||
SpriteEffects = item.Rotation > 90.0f && item.Rotation < 270.0f ? SpriteEffects.FlipVertically : SpriteEffects.None
|
SpriteEffects = item.Rotation > 90.0f && item.Rotation < 270.0f ? SpriteEffects.FlipVertically : SpriteEffects.None
|
||||||
@@ -1457,7 +1472,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
new GUIImage(new RectTransform(new Vector2(0.8f), itemFrame.RectTransform, Anchor.TopLeft) { RelativeOffset = new Vector2(-0.2f) }, "WeaponSwitchIcon.DropShadow", scaleToFit: true)
|
new GUIImage(new RectTransform(new Vector2(0.8f), itemFrame.RectTransform, Anchor.TopLeft) { RelativeOffset = new Vector2(-0.2f) }, "WeaponSwitchIcon.DropShadow", scaleToFit: true)
|
||||||
{
|
{
|
||||||
SelectedColor = GUI.Style.Orange,
|
SelectedColor = GUIStyle.Orange,
|
||||||
Color = previewWhite,
|
Color = previewWhite,
|
||||||
CanBeFocused = false
|
CanBeFocused = false
|
||||||
};
|
};
|
||||||
@@ -1468,7 +1483,7 @@ namespace Barotrauma
|
|||||||
Point size = new Point((int) (item.Rect.Width * item.Scale / dockedBorders.Width * hullContainer.Rect.Width), (int) (item.Rect.Height * item.Scale / dockedBorders.Height * hullContainer.Rect.Height));
|
Point size = new Point((int) (item.Rect.Width * item.Scale / dockedBorders.Width * hullContainer.Rect.Width), (int) (item.Rect.Height * item.Scale / dockedBorders.Height * hullContainer.Rect.Height));
|
||||||
itemFrame = new GUIFrame(rectT(size, component, Anchor.Center), style: "ScanLines")
|
itemFrame = new GUIFrame(rectT(size, component, Anchor.Center), style: "ScanLines")
|
||||||
{
|
{
|
||||||
SelectedColor = GUI.Style.Orange,
|
SelectedColor = GUIStyle.Orange,
|
||||||
OutlineColor = previewWhite,
|
OutlineColor = previewWhite,
|
||||||
Color = previewWhite,
|
Color = previewWhite,
|
||||||
OutlineThickness = 2,
|
OutlineThickness = 2,
|
||||||
@@ -1540,7 +1555,7 @@ namespace Barotrauma
|
|||||||
// calculate the center point so we can draw a line from X to Y instead of drawing a rotated rectangle that is filled
|
// calculate the center point so we can draw a line from X to Y instead of drawing a rotated rectangle that is filled
|
||||||
Vector2 point1 = hullVertex[1] + (hullVertex[2] - hullVertex[1]) / 2;
|
Vector2 point1 = hullVertex[1] + (hullVertex[2] - hullVertex[1]) / 2;
|
||||||
Vector2 point2 = hullVertex[0] + (hullVertex[3] - hullVertex[0]) / 2;
|
Vector2 point2 = hullVertex[0] + (hullVertex[3] - hullVertex[0]) / 2;
|
||||||
GUI.DrawLine(spriteBatch, point1, point2, (highlightWalls ? GUI.Style.Orange * 0.6f : Color.DarkCyan * 0.3f), width: 10);
|
GUI.DrawLine(spriteBatch, point1, point2, (highlightWalls ? GUIStyle.Orange * 0.6f : Color.DarkCyan * 0.3f), width: 10);
|
||||||
if (GameMain.DebugDraw)
|
if (GameMain.DebugDraw)
|
||||||
{
|
{
|
||||||
// the "collision box" is a bit bigger than the line we draw so this can be useful data (maybe)
|
// the "collision box" is a bit bigger than the line we draw so this can be useful data (maybe)
|
||||||
@@ -1553,14 +1568,14 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
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() });
|
LocalizedString progressText = TextManager.GetWithVariables("upgrades.progressformat", ("[level]", currentLevel.ToString()), ("[maxlevel]", prefab.MaxLevel.ToString()));
|
||||||
if (prefabFrame.FindChild("progressbar", true) is { } progressParent)
|
if (prefabFrame.FindChild("progressbar", true) is { } progressParent)
|
||||||
{
|
{
|
||||||
GUIProgressBar bar = progressParent.GetChild<GUIProgressBar>();
|
GUIProgressBar bar = progressParent.GetChild<GUIProgressBar>();
|
||||||
if (bar != null)
|
if (bar != null)
|
||||||
{
|
{
|
||||||
bar.BarSize = currentLevel / (float) prefab.MaxLevel;
|
bar.BarSize = currentLevel / (float) prefab.MaxLevel;
|
||||||
bar.Color = currentLevel >= prefab.MaxLevel ? GUI.Style.Green : GUI.Style.Orange;
|
bar.Color = currentLevel >= prefab.MaxLevel ? GUIStyle.Green : GUIStyle.Orange;
|
||||||
}
|
}
|
||||||
|
|
||||||
GUITextBlock block = progressParent.GetChild<GUITextBlock>();
|
GUITextBlock block = progressParent.GetChild<GUITextBlock>();
|
||||||
@@ -1576,7 +1591,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (priceLabel != null && !WaitForServerUpdate)
|
if (priceLabel != null && !WaitForServerUpdate)
|
||||||
{
|
{
|
||||||
priceLabel.Text = FormatCurrency(price);
|
priceLabel.Text = TextManager.FormatCurrency(price);
|
||||||
if (currentLevel >= prefab.MaxLevel)
|
if (currentLevel >= prefab.MaxLevel)
|
||||||
{
|
{
|
||||||
priceLabel.Text = TextManager.Get("Upgrade.MaxedUpgrade");
|
priceLabel.Text = TextManager.Get("Upgrade.MaxedUpgrade");
|
||||||
@@ -1587,7 +1602,7 @@ namespace Barotrauma
|
|||||||
if (button != null)
|
if (button != null)
|
||||||
{
|
{
|
||||||
button.Enabled = currentLevel < prefab.MaxLevel;
|
button.Enabled = currentLevel < prefab.MaxLevel;
|
||||||
if (WaitForServerUpdate || !campaign.AllowedToManageCampaign() || price > campaign.Money)
|
if (WaitForServerUpdate || !campaign.Wallet.CanAfford(price))
|
||||||
{
|
{
|
||||||
button.Enabled = false;
|
button.Enabled = false;
|
||||||
}
|
}
|
||||||
@@ -1620,7 +1635,7 @@ namespace Barotrauma
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
parent.Enabled = false;
|
parent.Enabled = false;
|
||||||
parent.SelectedColor = GUI.Style.Red * 0.5f;
|
parent.SelectedColor = GUIStyle.Red * 0.5f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1632,12 +1647,12 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (component.UserData != prefab) { continue; }
|
if (component.UserData != prefab) { continue; }
|
||||||
|
|
||||||
Dictionary<string, GUIComponentStyle> styles = GUI.Style.GetComponentStyle("upgradeindicator").ChildStyles;
|
Dictionary<Identifier, GUIComponentStyle> styles = GUIStyle.GetComponentStyle("upgradeindicator").ChildStyles;
|
||||||
if (!styles.ContainsKey("upgradeindicatoron") || !styles.ContainsKey("upgradeindicatordim") || !styles.ContainsKey("upgradeindicatoroff")) { continue; }
|
if (!styles.ContainsKey("upgradeindicatoron") || !styles.ContainsKey("upgradeindicatordim") || !styles.ContainsKey("upgradeindicatoroff")) { continue; }
|
||||||
|
|
||||||
GUIComponentStyle onStyle = styles["upgradeindicatoron"];
|
GUIComponentStyle onStyle = styles["upgradeindicatoron".ToIdentifier()];
|
||||||
GUIComponentStyle dimStyle = styles["upgradeindicatordim"];
|
GUIComponentStyle dimStyle = styles["upgradeindicatordim".ToIdentifier()];
|
||||||
GUIComponentStyle offStyle = styles["upgradeindicatoroff"];
|
GUIComponentStyle offStyle = styles["upgradeindicatoroff".ToIdentifier()];
|
||||||
|
|
||||||
if (campaign.UpgradeManager.GetUpgradeLevel(prefab, category) >= prefab.MaxLevel)
|
if (campaign.UpgradeManager.GetUpgradeLevel(prefab, category) >= prefab.MaxLevel)
|
||||||
{
|
{
|
||||||
@@ -1692,12 +1707,7 @@ namespace Barotrauma
|
|||||||
return frames.ToArray();
|
return frames.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool HasPermission => campaignUI.Campaign.AllowedToManageCampaign();
|
private bool HasPermission => true;
|
||||||
|
|
||||||
public static string FormatCurrency(int money, bool format = true)
|
|
||||||
{
|
|
||||||
return TextManager.GetWithVariable("CurrencyFormat", "[credits]", format ? string.Format(CultureInfo.InvariantCulture, "{0:N0}", money) : money.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
// just a shortcut to create new RectTransforms since all the new RectTransform and new Vector2 confuses my IDE (and me)
|
// just a shortcut to create new RectTransforms since all the new RectTransform and new Vector2 confuses my IDE (and me)
|
||||||
private static RectTransform rectT(float x, float y, GUIComponent parentComponent, Anchor anchor = Anchor.TopLeft, ScaleBasis scaleBasis = ScaleBasis.Normal)
|
private static RectTransform rectT(float x, float y, GUIComponent parentComponent, Anchor anchor = Anchor.TopLeft, ScaleBasis scaleBasis = ScaleBasis.Normal)
|
||||||
|
|||||||
@@ -34,23 +34,29 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public class TextSettings
|
public class TextSettings
|
||||||
{
|
{
|
||||||
public string Text;
|
public LocalizedString Text;
|
||||||
public int Width;
|
public int Width;
|
||||||
|
|
||||||
|
public TextSettings(Identifier textTag, int width)
|
||||||
|
{
|
||||||
|
Text = TextManager.GetFormatted(textTag);
|
||||||
|
Width = width;
|
||||||
|
}
|
||||||
|
|
||||||
public TextSettings(XElement element)
|
public TextSettings(XElement element)
|
||||||
{
|
{
|
||||||
Text = TextManager.GetFormatted(element.GetAttributeString("text", string.Empty), true);
|
Text = TextManager.GetFormatted(element.GetAttributeIdentifier("text", Identifier.Empty));
|
||||||
Width = element.GetAttributeInt("width", 450);
|
Width = element.GetAttributeInt("width", 450);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class VideoSettings
|
public class VideoSettings
|
||||||
{
|
{
|
||||||
public string File;
|
public readonly string File;
|
||||||
|
|
||||||
public VideoSettings(XElement element)
|
public VideoSettings(string file)
|
||||||
{
|
{
|
||||||
File = element.GetAttributeString("file", string.Empty);
|
File = file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,13 +81,13 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
videoView = new GUICustomComponent(new RectTransform(Point.Zero, videoFrame.RectTransform, Anchor.Center), (spriteBatch, guiCustomComponent) => { DrawVideo(spriteBatch, guiCustomComponent.Rect); });
|
videoView = new GUICustomComponent(new RectTransform(Point.Zero, videoFrame.RectTransform, Anchor.Center), (spriteBatch, guiCustomComponent) => { DrawVideo(spriteBatch, guiCustomComponent.Rect); });
|
||||||
title = new GUITextBlock(new RectTransform(Point.Zero, textFrame.RectTransform, Anchor.TopLeft, Pivot.TopLeft), string.Empty, font: GUI.LargeFont, textColor: new Color(253, 174, 0), textAlignment: Alignment.Left);
|
title = new GUITextBlock(new RectTransform(Point.Zero, textFrame.RectTransform, Anchor.TopLeft, Pivot.TopLeft), string.Empty, font: GUIStyle.LargeFont, textColor: new Color(253, 174, 0), textAlignment: Alignment.Left);
|
||||||
|
|
||||||
textContent = new GUITextBlock(new RectTransform(Point.Zero, textFrame.RectTransform, Anchor.TopLeft, Pivot.TopLeft), string.Empty, font: GUI.Font, textAlignment: Alignment.TopLeft);
|
textContent = new GUITextBlock(new RectTransform(Point.Zero, textFrame.RectTransform, Anchor.TopLeft, Pivot.TopLeft), string.Empty, font: GUIStyle.Font, textAlignment: Alignment.TopLeft);
|
||||||
|
|
||||||
objectiveTitle = new GUITextBlock(new RectTransform(new Vector2(1f, 0f), textFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter), string.Empty, font: GUI.SubHeadingFont, textAlignment: Alignment.CenterRight, textColor: Color.White);
|
objectiveTitle = new GUITextBlock(new RectTransform(new Vector2(1f, 0f), textFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter), string.Empty, font: GUIStyle.SubHeadingFont, textAlignment: Alignment.CenterRight, textColor: Color.White);
|
||||||
objectiveTitle.Text = TextManager.Get("Tutorial.NewObjective");
|
objectiveTitle.Text = TextManager.Get("Tutorial.NewObjective");
|
||||||
objectiveText = new GUITextBlock(new RectTransform(Point.Zero, textFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter), string.Empty, font: GUI.SubHeadingFont, textColor: new Color(4, 180, 108), textAlignment: Alignment.CenterRight);
|
objectiveText = new GUITextBlock(new RectTransform(Point.Zero, textFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter), string.Empty, font: GUIStyle.SubHeadingFont, textColor: new Color(4, 180, 108), textAlignment: Alignment.CenterRight);
|
||||||
|
|
||||||
objectiveTitle.Visible = objectiveText.Visible = false;
|
objectiveTitle.Visible = objectiveText.Visible = false;
|
||||||
}
|
}
|
||||||
@@ -120,7 +126,12 @@ namespace Barotrauma
|
|||||||
background.AddToGUIUpdateList(ignoreChildren, order);
|
background.AddToGUIUpdateList(ignoreChildren, order);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadContent(string contentPath, VideoSettings videoSettings, TextSettings textSettings, string contentId, bool startPlayback, string objective = "", Action callback = null)
|
public void LoadContent(string contentPath, VideoSettings videoSettings, TextSettings textSettings, Identifier contentId, bool startPlayback)
|
||||||
|
{
|
||||||
|
LoadContent(contentPath, videoSettings, textSettings, contentId, startPlayback, new RawLString(""), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LoadContent(string contentPath, VideoSettings videoSettings, TextSettings textSettings, Identifier contentId, bool startPlayback, LocalizedString objective, Action callback = null)
|
||||||
{
|
{
|
||||||
callbackOnStop = callback;
|
callbackOnStop = callback;
|
||||||
filePath = contentPath + videoSettings.File;
|
filePath = contentPath + videoSettings.File;
|
||||||
@@ -183,10 +194,10 @@ namespace Barotrauma
|
|||||||
title.RectTransform.NonScaledSize = new Point(scaledTextWidth, scaledTitleHeight);
|
title.RectTransform.NonScaledSize = new Point(scaledTextWidth, scaledTitleHeight);
|
||||||
title.RectTransform.AbsoluteOffset = new Point((int)(5 * GUI.Scale), (int)(10 * GUI.Scale));
|
title.RectTransform.AbsoluteOffset = new Point((int)(5 * GUI.Scale), (int)(10 * GUI.Scale));
|
||||||
|
|
||||||
if (textSettings != null && !string.IsNullOrEmpty(textSettings.Text))
|
if (textSettings != null && !textSettings.Text.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
textSettings.Text = ToolBox.WrapText(textSettings.Text, scaledTextWidth, GUI.Font);
|
textSettings.Text = ToolBox.WrapText(textSettings.Text, scaledTextWidth, GUIStyle.Font);
|
||||||
int wrappedHeight = textSettings.Text.Split('\n').Length * scaledTextHeight;
|
int wrappedHeight = textSettings.Text.Value.Split('\n').Length * scaledTextHeight;
|
||||||
|
|
||||||
textFrame.RectTransform.NonScaledSize = new Point(scaledTextWidth + scaledBorderSize, wrappedHeight + scaledBorderSize + scaledButtonSize.Y + scaledTitleHeight);
|
textFrame.RectTransform.NonScaledSize = new Point(scaledTextWidth + scaledBorderSize, wrappedHeight + scaledBorderSize + scaledButtonSize.Y + scaledTitleHeight);
|
||||||
|
|
||||||
@@ -203,7 +214,7 @@ namespace Barotrauma
|
|||||||
textContent.RectTransform.AbsoluteOffset = new Point(0, scaledBorderSize + scaledTitleHeight);
|
textContent.RectTransform.AbsoluteOffset = new Point(0, scaledBorderSize + scaledTitleHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(objectiveText.Text))
|
if (!objectiveText.Text.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
int scaledXOffset = (int)(-10 * GUI.Scale);
|
int scaledXOffset = (int)(-10 * GUI.Scale);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Globalization;
|
||||||
using Barotrauma.Networking;
|
using Barotrauma.Networking;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
@@ -19,32 +19,54 @@ namespace Barotrauma
|
|||||||
private Func<int> getYesVotes, getNoVotes, getMaxVotes;
|
private Func<int> getYesVotes, getNoVotes, getMaxVotes;
|
||||||
private bool votePassed;
|
private bool votePassed;
|
||||||
|
|
||||||
private string votingOnText;
|
private RichString votingOnText;
|
||||||
private List<RichTextData> votingOnTextData;
|
|
||||||
private float votingTime = 100f;
|
private float votingTime = 100f;
|
||||||
private float timer;
|
private float timer;
|
||||||
private VoteType currentVoteType;
|
private VoteType currentVoteType;
|
||||||
private Color submarineColor => GUI.Style.Orange;
|
private Color SubmarineColor => GUIStyle.Orange;
|
||||||
private Point createdForResolution;
|
private Point createdForResolution;
|
||||||
|
|
||||||
public VotingInterface(Client starter, SubmarineInfo info, VoteType type, float votingTime)
|
public static VotingInterface CreateSubmarineVotingInterface(Client starter, SubmarineInfo info, VoteType type, float votingTime)
|
||||||
{
|
{
|
||||||
if (starter == null || info == null) return;
|
if (starter == null || info == null) { return null; }
|
||||||
SetSubmarineVotingText(starter, info, type);
|
|
||||||
this.votingTime = votingTime;
|
|
||||||
getYesVotes = SubmarineYesVotes;
|
|
||||||
getNoVotes = SubmarineNoVotes;
|
|
||||||
getMaxVotes = SubmarineMaxVotes;
|
|
||||||
onVoteEnd = () => SendSubmarineVoteEndMessage(info, type);
|
|
||||||
|
|
||||||
Initialize(starter, type);
|
var subVoting = new VotingInterface()
|
||||||
|
{
|
||||||
|
votingTime = votingTime,
|
||||||
|
getYesVotes = () => GameMain.NetworkMember?.Voting?.GetVoteCountYes(type) ?? 0,
|
||||||
|
getNoVotes = () => GameMain.NetworkMember?.Voting?.GetVoteCountNo(type) ?? 0,
|
||||||
|
getMaxVotes = () => GameMain.NetworkMember?.Voting?.GetVoteCountMax(type) ?? 0,
|
||||||
|
};
|
||||||
|
subVoting.onVoteEnd = () => subVoting.SendSubmarineVoteEndMessage(info, type);
|
||||||
|
subVoting.SetSubmarineVotingText(starter, info, type);
|
||||||
|
subVoting.Initialize(starter, type);
|
||||||
|
return subVoting;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static VotingInterface CreateMoneyTransferVotingInterface(Client starter, Client from, Client to, int amount, float votingTime)
|
||||||
|
{
|
||||||
|
if (starter == null) { return null; }
|
||||||
|
if (from == null && to == null) { return null; }
|
||||||
|
|
||||||
|
var transferVoting = new VotingInterface()
|
||||||
|
{
|
||||||
|
votingTime = votingTime,
|
||||||
|
getYesVotes = () => GameMain.NetworkMember?.Voting?.GetVoteCountYes(VoteType.TransferMoney) ?? 0,
|
||||||
|
getNoVotes = () => GameMain.NetworkMember?.Voting?.GetVoteCountNo(VoteType.TransferMoney) ?? 0,
|
||||||
|
getMaxVotes = () => GameMain.NetworkMember?.Voting?.GetVoteCountMax(VoteType.TransferMoney) ?? 0,
|
||||||
|
};
|
||||||
|
transferVoting.onVoteEnd = () => transferVoting.SendMoneyTransferVoteEndMessage(from, to, amount);
|
||||||
|
transferVoting.SetMoneyTransferVotingText(starter, from, to, amount);
|
||||||
|
transferVoting.Initialize(starter, VoteType.TransferMoney);
|
||||||
|
return transferVoting;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void Initialize(Client starter, VoteType type)
|
private void Initialize(Client starter, VoteType type)
|
||||||
{
|
{
|
||||||
currentVoteType = type;
|
currentVoteType = type;
|
||||||
CreateVotingGUI();
|
CreateVotingGUI();
|
||||||
if (starter.ID == GameMain.Client.ID) SetGUIToVotedState(2);
|
if (starter.ID == GameMain.Client.ID) { SetGUIToVotedState(2); }
|
||||||
VoteRunning = true;
|
VoteRunning = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,7 +74,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
createdForResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
|
createdForResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
|
||||||
|
|
||||||
if (frame != null) frame.Parent.RemoveChild(frame);
|
frame?.Parent.RemoveChild(frame);
|
||||||
frame = new GUIFrame(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.VotingArea, GameMain.Client.InGameHUD.RectTransform), style: "");
|
frame = new GUIFrame(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.VotingArea, GameMain.Client.InGameHUD.RectTransform), style: "");
|
||||||
|
|
||||||
int padding = HUDLayoutSettings.Padding * 2;
|
int padding = HUDLayoutSettings.Padding * 2;
|
||||||
@@ -60,14 +82,14 @@ namespace Barotrauma
|
|||||||
int yOffset = padding;
|
int yOffset = padding;
|
||||||
int paddedWidth = frame.Rect.Width - padding * 2;
|
int paddedWidth = frame.Rect.Width - padding * 2;
|
||||||
|
|
||||||
votingTextBlock = new GUITextBlock(new RectTransform(new Point(paddedWidth, 0), frame.RectTransform), votingOnTextData, votingOnText, wrap: true);
|
votingTextBlock = new GUITextBlock(new RectTransform(new Point(paddedWidth, 0), frame.RectTransform), votingOnText, wrap: true);
|
||||||
votingTextBlock.RectTransform.NonScaledSize = votingTextBlock.RectTransform.MinSize = votingTextBlock.RectTransform.MaxSize = new Point(votingTextBlock.Rect.Width, votingTextBlock.Rect.Height);
|
votingTextBlock.RectTransform.NonScaledSize = votingTextBlock.RectTransform.MinSize = votingTextBlock.RectTransform.MaxSize = new Point(votingTextBlock.Rect.Width, votingTextBlock.Rect.Height);
|
||||||
votingTextBlock.RectTransform.IsFixedSize = true;
|
votingTextBlock.RectTransform.IsFixedSize = true;
|
||||||
votingTextBlock.RectTransform.AbsoluteOffset = new Point(padding, yOffset);
|
votingTextBlock.RectTransform.AbsoluteOffset = new Point(padding, yOffset);
|
||||||
|
|
||||||
yOffset += votingTextBlock.Rect.Height + spacing;
|
yOffset += votingTextBlock.Rect.Height + spacing;
|
||||||
|
|
||||||
voteCounter = new GUITextBlock(new RectTransform(new Point(paddedWidth, 0), frame.RectTransform), "(0/0)", GUI.Style.Green, textAlignment: Alignment.Center);
|
voteCounter = new GUITextBlock(new RectTransform(new Point(paddedWidth, 0), frame.RectTransform), "(0/0)", GUIStyle.Green, textAlignment: Alignment.Center);
|
||||||
voteCounter.RectTransform.NonScaledSize = voteCounter.RectTransform.MinSize = voteCounter.RectTransform.MaxSize = new Point(voteCounter.Rect.Width, voteCounter.Rect.Height);
|
voteCounter.RectTransform.NonScaledSize = voteCounter.RectTransform.MinSize = voteCounter.RectTransform.MaxSize = new Point(voteCounter.Rect.Width, voteCounter.Rect.Height);
|
||||||
voteCounter.RectTransform.IsFixedSize = true;
|
voteCounter.RectTransform.IsFixedSize = true;
|
||||||
voteCounter.RectTransform.AbsoluteOffset = new Point(padding, yOffset);
|
voteCounter.RectTransform.AbsoluteOffset = new Point(padding, yOffset);
|
||||||
@@ -118,8 +140,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void Update(float deltaTime)
|
public void Update(float deltaTime)
|
||||||
{
|
{
|
||||||
if (!VoteRunning) return;
|
if (!VoteRunning) { return; }
|
||||||
if (GameMain.GraphicsWidth != createdForResolution.X || GameMain.GraphicsHeight != createdForResolution.Y) CreateVotingGUI();
|
if (GameMain.GraphicsWidth != createdForResolution.X || GameMain.GraphicsHeight != createdForResolution.Y) { CreateVotingGUI(); }
|
||||||
yesVotes = getYesVotes();
|
yesVotes = getYesVotes();
|
||||||
noVotes = getNoVotes();
|
noVotes = getNoVotes();
|
||||||
maxVotes = getMaxVotes();
|
maxVotes = getMaxVotes();
|
||||||
@@ -128,7 +150,6 @@ namespace Barotrauma
|
|||||||
votingTimer.BarSize = timer / votingTime;
|
votingTimer.BarSize = timer / votingTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void EndVote(bool passed, int yesVoteFinal, int noVoteFinal)
|
public void EndVote(bool passed, int yesVoteFinal, int noVoteFinal)
|
||||||
{
|
{
|
||||||
VoteRunning = false;
|
VoteRunning = false;
|
||||||
@@ -145,75 +166,94 @@ namespace Barotrauma
|
|||||||
JobPrefab prefab = starter?.Character?.Info?.Job?.Prefab;
|
JobPrefab prefab = starter?.Character?.Info?.Job?.Prefab;
|
||||||
Color nameColor = prefab != null ? prefab.UIColor : Color.White;
|
Color nameColor = prefab != null ? prefab.UIColor : Color.White;
|
||||||
string characterRichString = $"‖color:{nameColor.R},{nameColor.G},{nameColor.B}‖{name}‖color:end‖";
|
string characterRichString = $"‖color:{nameColor.R},{nameColor.G},{nameColor.B}‖{name}‖color:end‖";
|
||||||
string submarineRichString = $"‖color:{submarineColor.R},{submarineColor.G},{submarineColor.B}‖{info.DisplayName}‖color:end‖";
|
string submarineRichString = $"‖color:{SubmarineColor.R},{SubmarineColor.G},{SubmarineColor.B}‖{info.DisplayName}‖color:end‖";
|
||||||
|
|
||||||
|
LocalizedString text = string.Empty;
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case VoteType.PurchaseAndSwitchSub:
|
case VoteType.PurchaseAndSwitchSub:
|
||||||
votingOnText = TextManager.GetWithVariables("submarinepurchaseandswitchvote", new string[] { "[playername]", "[submarinename]", "[amount]", "[currencyname]" }, new string[] { characterRichString, submarineRichString, info.Price.ToString(), TextManager.Get("credit").ToLower() });
|
text = TextManager.GetWithVariables("submarinepurchaseandswitchvote",
|
||||||
|
("[playername]", characterRichString),
|
||||||
|
("[submarinename]", submarineRichString),
|
||||||
|
("[amount]", info.Price.ToString()),
|
||||||
|
("[currencyname]", TextManager.Get("credit").ToLower()));
|
||||||
break;
|
break;
|
||||||
case VoteType.PurchaseSub:
|
case VoteType.PurchaseSub:
|
||||||
votingOnText = TextManager.GetWithVariables("submarinepurchasevote", new string[] { "[playername]", "[submarinename]", "[amount]", "[currencyname]" }, new string[] { characterRichString, submarineRichString, info.Price.ToString(), TextManager.Get("credit").ToLower() });
|
text = TextManager.GetWithVariables("submarinepurchasevote",
|
||||||
|
("[playername]", characterRichString),
|
||||||
|
("[submarinename]", submarineRichString),
|
||||||
|
("[amount]", info.Price.ToString()),
|
||||||
|
("[currencyname]", TextManager.Get("credit").ToLower()));
|
||||||
break;
|
break;
|
||||||
case VoteType.SwitchSub:
|
case VoteType.SwitchSub:
|
||||||
int deliveryFee = SubmarineSelection.DeliveryFeePerDistanceTravelled * GameMain.GameSession.Map.DistanceToClosestLocationWithOutpost(GameMain.GameSession.Map.CurrentLocation, out Location endLocation);
|
int deliveryFee = SubmarineSelection.DeliveryFeePerDistanceTravelled * GameMain.GameSession.Map.DistanceToClosestLocationWithOutpost(GameMain.GameSession.Map.CurrentLocation, out Location endLocation);
|
||||||
|
|
||||||
if (deliveryFee > 0)
|
if (deliveryFee > 0)
|
||||||
{
|
{
|
||||||
votingOnText = TextManager.GetWithVariables("submarineswitchfeevote", new string[] { "[playername]", "[submarinename]", "[locationname]", "[amount]", "[currencyname]" }, new string[] { characterRichString, submarineRichString, endLocation.Name, deliveryFee.ToString(), TextManager.Get("credit").ToLower() });
|
text = TextManager.GetWithVariables("submarineswitchfeevote",
|
||||||
|
("[playername]", characterRichString),
|
||||||
|
("[submarinename]", submarineRichString),
|
||||||
|
("[locationname]", endLocation.Name),
|
||||||
|
("[amount]", deliveryFee.ToString()),
|
||||||
|
("[currencyname]", TextManager.Get("credit").ToLower()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
votingOnText = TextManager.GetWithVariables("submarineswitchnofeevote", new string[] { "[playername]", "[submarinename]" }, new string[] { characterRichString, submarineRichString });
|
text = TextManager.GetWithVariables("submarineswitchnofeevote",
|
||||||
|
("[playername]", characterRichString),
|
||||||
|
("[submarinename]", submarineRichString));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
votingOnTextData = RichTextData.GetRichTextData(votingOnText, out votingOnText);
|
votingOnText = RichString.Rich(text);
|
||||||
}
|
|
||||||
|
|
||||||
private int SubmarineYesVotes()
|
|
||||||
{
|
|
||||||
return GameMain.NetworkMember.SubmarineVoteYesCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int SubmarineNoVotes()
|
|
||||||
{
|
|
||||||
return GameMain.NetworkMember.SubmarineVoteNoCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int SubmarineMaxVotes()
|
|
||||||
{
|
|
||||||
return GameMain.NetworkMember.SubmarineVoteMax;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SendSubmarineVoteEndMessage(SubmarineInfo info, VoteType type)
|
private void SendSubmarineVoteEndMessage(SubmarineInfo info, VoteType type)
|
||||||
{
|
{
|
||||||
GameMain.NetworkMember.AddChatMessage(GetSubmarineVoteResultMessage(info, type, yesVotes.ToString(), noVotes.ToString(), votePassed), ChatMessageType.Server);
|
GameMain.NetworkMember.AddChatMessage(GetSubmarineVoteResultMessage(info, type, yesVotes, noVotes, votePassed).Value, ChatMessageType.Server);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetSubmarineVoteResultMessage(SubmarineInfo info, VoteType type, string yesVoteString, string noVoteString, bool votePassed)
|
private LocalizedString GetSubmarineVoteResultMessage(SubmarineInfo info, VoteType type, int yesVoteCount, int noVoteCount, bool votePassed)
|
||||||
{
|
{
|
||||||
string result = string.Empty;
|
LocalizedString result = string.Empty;
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case VoteType.PurchaseAndSwitchSub:
|
case VoteType.PurchaseAndSwitchSub:
|
||||||
result = TextManager.GetWithVariables(votePassed ? "submarinepurchaseandswitchvotepassed" : "submarinepurchaseandswitchvotefailed", new string[] { "[submarinename]", "[amount]", "[currencyname]", "[yesvotecount]", "[novotecount]" }, new string[] { info.DisplayName, info.Price.ToString(), TextManager.Get("credit").ToLower(), yesVoteString, noVoteString });
|
result = TextManager.GetWithVariables(votePassed ? "submarinepurchaseandswitchvotepassed" : "submarinepurchaseandswitchvotefailed",
|
||||||
|
("[submarinename]", info.DisplayName),
|
||||||
|
("[amount]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", info.Price)),
|
||||||
|
("[currencyname]", TextManager.Get("credit").ToLower()),
|
||||||
|
("[yesvotecount]", yesVoteCount.ToString()),
|
||||||
|
("[novotecount]" , noVoteCount.ToString()));
|
||||||
break;
|
break;
|
||||||
case VoteType.PurchaseSub:
|
case VoteType.PurchaseSub:
|
||||||
result = TextManager.GetWithVariables(votePassed ? "submarinepurchasevotepassed" : "submarinepurchasevotefailed", new string[] { "[submarinename]", "[amount]", "[currencyname]", "[yesvotecount]", "[novotecount]" }, new string[] { info.DisplayName, info.Price.ToString(), TextManager.Get("credit").ToLower(), yesVoteString, noVoteString });
|
result = TextManager.GetWithVariables(votePassed ? "submarinepurchasevotepassed" : "submarinepurchasevotefailed",
|
||||||
|
("[submarinename]", info.DisplayName),
|
||||||
|
("[amount]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", info.Price)),
|
||||||
|
("[currencyname]", TextManager.Get("credit").ToLower()),
|
||||||
|
("[yesvotecount]", yesVoteCount.ToString()),
|
||||||
|
("[novotecount]", noVoteCount.ToString()));
|
||||||
break;
|
break;
|
||||||
case VoteType.SwitchSub:
|
case VoteType.SwitchSub:
|
||||||
int deliveryFee = SubmarineSelection.DeliveryFeePerDistanceTravelled * GameMain.GameSession.Map.DistanceToClosestLocationWithOutpost(GameMain.GameSession.Map.CurrentLocation, out Location endLocation);
|
int deliveryFee = SubmarineSelection.DeliveryFeePerDistanceTravelled * GameMain.GameSession.Map.DistanceToClosestLocationWithOutpost(GameMain.GameSession.Map.CurrentLocation, out Location endLocation);
|
||||||
|
|
||||||
if (deliveryFee > 0)
|
if (deliveryFee > 0)
|
||||||
{
|
{
|
||||||
result = TextManager.GetWithVariables(votePassed ? "submarineswitchfeevotepassed" : "submarineswitchfeevotefailed", new string[] { "[submarinename]", "[locationname]", "[amount]", "[currencyname]", "[yesvotecount]", "[novotecount]" }, new string[] { info.DisplayName, endLocation.Name, deliveryFee.ToString(), TextManager.Get("credit").ToLower(), yesVoteString, noVoteString });
|
result = TextManager.GetWithVariables(votePassed ? "submarineswitchfeevotepassed" : "submarineswitchfeevotefailed",
|
||||||
|
("[submarinename]", info.DisplayName),
|
||||||
|
("[locationname]", endLocation.Name),
|
||||||
|
("[amount]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", deliveryFee)),
|
||||||
|
("[currencyname]", TextManager.Get("credit").ToLower()),
|
||||||
|
("[yesvotecount]", yesVoteCount.ToString()),
|
||||||
|
("[novotecount]", noVoteCount.ToString()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = TextManager.GetWithVariables(votePassed ? "submarineswitchnofeevotepassed" : "submarineswitchnofeevotefailed", new string[] { "[submarinename]", "[yesvotecount]", "[novotecount]" }, new string[] { info.DisplayName, yesVoteString, noVoteString });
|
result = TextManager.GetWithVariables(votePassed ? "submarineswitchnofeevotepassed" : "submarineswitchnofeevotefailed",
|
||||||
|
("[submarinename]", info.DisplayName),
|
||||||
|
("[yesvotecount]", yesVoteCount.ToString()),
|
||||||
|
("[novotecount]", noVoteCount.ToString()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -223,6 +263,58 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
private void SetMoneyTransferVotingText(Client starter, Client from, Client to, int amount)
|
||||||
|
{
|
||||||
|
string name = starter.Name;
|
||||||
|
JobPrefab prefab = starter?.Character?.Info?.Job?.Prefab;
|
||||||
|
Color nameColor = prefab != null ? prefab.UIColor : Color.White;
|
||||||
|
string characterRichString = $"‖color:{nameColor.R},{nameColor.G},{nameColor.B}‖{name}‖color:end‖";
|
||||||
|
|
||||||
|
LocalizedString text = string.Empty;
|
||||||
|
if (from == null && to != null)
|
||||||
|
{
|
||||||
|
text = TextManager.GetWithVariables("crewwallet.requestbanktoselfvote",
|
||||||
|
("[requester]", characterRichString),
|
||||||
|
("[amount]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", amount)));
|
||||||
|
}
|
||||||
|
else if (from != null && to == null)
|
||||||
|
{
|
||||||
|
text = TextManager.GetWithVariables("crewwallet.requestselftobankvote",
|
||||||
|
("[requester]", characterRichString),
|
||||||
|
("[amount]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", amount)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//not supported atm: clients can only requests transfers between their own wallet and the bank
|
||||||
|
LocalizedString bankName = TextManager.Get("crewwallet.bank");
|
||||||
|
text = TextManager.GetWithVariables("crewwallet.requesttransfervote",
|
||||||
|
("[requester]", characterRichString),
|
||||||
|
("[player1]", from?.Character == null ? bankName : from.Character.Name),
|
||||||
|
("[player2]", to?.Character == null ? bankName : to.Character.Name),
|
||||||
|
("[amount]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", amount)));
|
||||||
|
}
|
||||||
|
|
||||||
|
votingOnText = RichString.Rich(text);
|
||||||
|
}
|
||||||
|
private void SendMoneyTransferVoteEndMessage(Client from, Client to, int amount)
|
||||||
|
{
|
||||||
|
GameMain.NetworkMember.AddChatMessage(GetMoneyTransferVoteResultMessage(from, to, amount, yesVotes, noVotes, votePassed).Value, ChatMessageType.Server);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LocalizedString GetMoneyTransferVoteResultMessage(Client from, Client to, int transferAmount, int yesVoteCount, int noVoteCount, bool votePassed)
|
||||||
|
{
|
||||||
|
LocalizedString result = string.Empty;
|
||||||
|
if (from == null && to != null)
|
||||||
|
{
|
||||||
|
result = TextManager.GetWithVariables(votePassed ? "crewwallet.banktoplayer.votepassed" : "crewwallet.banktoplayer.votefailed",
|
||||||
|
("[playername]", to.Name),
|
||||||
|
("[amount]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", transferAmount)),
|
||||||
|
("[yesvotecount]", yesVoteCount.ToString()),
|
||||||
|
("[novotecount]", noVoteCount.ToString()));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
public void Remove()
|
public void Remove()
|
||||||
{
|
{
|
||||||
if (frame != null)
|
if (frame != null)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Shape shape;
|
public Shape shape;
|
||||||
public string tooltip;
|
public LocalizedString tooltip;
|
||||||
public bool showTooltip = true;
|
public bool showTooltip = true;
|
||||||
public Rectangle DrawRect => new Rectangle((int)(DrawPos.X - (float)size / 2), (int)(DrawPos.Y - (float)size / 2), size, size);
|
public Rectangle DrawRect => new Rectangle((int)(DrawPos.X - (float)size / 2), (int)(DrawPos.Y - (float)size / 2), size, size);
|
||||||
public Rectangle InputRect
|
public Rectangle InputRect
|
||||||
@@ -42,7 +42,7 @@ namespace Barotrauma
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool isFilled;
|
public bool isFilled;
|
||||||
public int inputAreaMargin;
|
public int inputAreaMargin;
|
||||||
public Color color = GUI.Style.Red;
|
public Color color = GUIStyle.Red;
|
||||||
public Color? secondaryColor;
|
public Color? secondaryColor;
|
||||||
public Color textColor = Color.White;
|
public Color textColor = Color.White;
|
||||||
public Color textBackgroundColor = Color.Black * 0.5f;
|
public Color textBackgroundColor = Color.Black * 0.5f;
|
||||||
@@ -183,7 +183,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
if (IsSelected)
|
if (IsSelected)
|
||||||
{
|
{
|
||||||
if (showTooltip && !string.IsNullOrEmpty(tooltip))
|
if (showTooltip && !tooltip.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
var offset = tooltipOffset ?? new Vector2(size, -size / 2f);
|
var offset = tooltipOffset ?? new Vector2(size, -size / 2f);
|
||||||
GUI.DrawString(spriteBatch, DrawPos + offset, tooltip, textColor, textBackgroundColor);
|
GUI.DrawString(spriteBatch, DrawPos + offset, tooltip, textColor, textBackgroundColor);
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ namespace Barotrauma
|
|||||||
AbsoluteSpacing = GUI.IntScale(15)
|
AbsoluteSpacing = GUI.IntScale(15)
|
||||||
};
|
};
|
||||||
|
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), content.RectTransform), TextManager.Get("statisticsconsentheader"), font: GUI.SubHeadingFont, textColor: Color.White);
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), content.RectTransform), TextManager.Get("statisticsconsentheader"), font: GUIStyle.SubHeadingFont, textColor: Color.White);
|
||||||
var mainText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), content.RectTransform), TextManager.Get("statisticsconsenttext"), wrap: true, parseRichText: true);
|
var mainText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), content.RectTransform), RichString.Rich(TextManager.Get("statisticsconsenttext")), wrap: true);
|
||||||
|
|
||||||
foreach (var data in mainText.RichTextData)
|
foreach (var data in mainText.RichTextData)
|
||||||
{
|
{
|
||||||
@@ -93,7 +93,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (child is GUITextBlock textBlock)
|
if (child is GUITextBlock textBlock)
|
||||||
{
|
{
|
||||||
textBlock.TextScale = MathHelper.Min(1.0f, 1.0f / GameSettings.TextScale);
|
textBlock.TextScale = MathHelper.Min(1.0f, 1.0f / GameSettings.CurrentConfig.Graphics.TextScale);
|
||||||
textBlock.RectTransform.MinSize = new Point(0, (int)textBlock.TextSize.Y);
|
textBlock.RectTransform.MinSize = new Point(0, (int)textBlock.TextSize.Y);
|
||||||
textBlock.RectTransform.MaxSize = new Point(int.MaxValue, (int)textBlock.TextSize.Y);
|
textBlock.RectTransform.MaxSize = new Point(int.MaxValue, (int)textBlock.TextSize.Y);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ using Barotrauma.Tutorials;
|
|||||||
using Barotrauma.Media;
|
using Barotrauma.Media;
|
||||||
using Barotrauma.Extensions;
|
using Barotrauma.Extensions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Barotrauma.Transition;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -47,8 +48,17 @@ namespace Barotrauma
|
|||||||
public static MainMenuScreen MainMenuScreen;
|
public static MainMenuScreen MainMenuScreen;
|
||||||
|
|
||||||
public static NetLobbyScreen NetLobbyScreen;
|
public static NetLobbyScreen NetLobbyScreen;
|
||||||
|
public static ModDownloadScreen ModDownloadScreen;
|
||||||
|
|
||||||
|
public static void ResetNetLobbyScreen()
|
||||||
|
{
|
||||||
|
NetLobbyScreen?.Release();
|
||||||
|
NetLobbyScreen = new NetLobbyScreen();
|
||||||
|
ModDownloadScreen?.Release();
|
||||||
|
ModDownloadScreen = new ModDownloadScreen();
|
||||||
|
}
|
||||||
|
|
||||||
public static ServerListScreen ServerListScreen;
|
public static ServerListScreen ServerListScreen;
|
||||||
public static SteamWorkshopScreen SteamWorkshopScreen;
|
|
||||||
|
|
||||||
public static SubEditorScreen SubEditorScreen;
|
public static SubEditorScreen SubEditorScreen;
|
||||||
public static TestScreen TestScreen;
|
public static TestScreen TestScreen;
|
||||||
@@ -66,19 +76,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public static Thread MainThread { get; private set; }
|
public static Thread MainThread { get; private set; }
|
||||||
|
|
||||||
private static ContentPackage vanillaContent;
|
public static ContentPackage VanillaContent => ContentPackageManager.VanillaCorePackage;
|
||||||
public static ContentPackage VanillaContent
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (vanillaContent == null)
|
|
||||||
{
|
|
||||||
// TODO: Dynamic method for defining and finding the vanilla content package.
|
|
||||||
vanillaContent = ContentPackage.CorePackages.SingleOrDefault(cp => Path.GetFileName(cp.Path).Equals("vanilla 0.9.xml", StringComparison.OrdinalIgnoreCase));
|
|
||||||
}
|
|
||||||
return vanillaContent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static GameSession gameSession;
|
private static GameSession gameSession;
|
||||||
public static GameSession GameSession
|
public static GameSession GameSession
|
||||||
@@ -96,7 +94,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static ParticleManager ParticleManager;
|
public static ParticleManager ParticleManager;
|
||||||
public static DecalManager DecalManager;
|
|
||||||
|
|
||||||
private static World world;
|
private static World world;
|
||||||
public static World World
|
public static World World
|
||||||
@@ -112,10 +109,8 @@ namespace Barotrauma
|
|||||||
public static LoadingScreen TitleScreen;
|
public static LoadingScreen TitleScreen;
|
||||||
private bool loadingScreenOpen;
|
private bool loadingScreenOpen;
|
||||||
|
|
||||||
public static GameSettings Config;
|
|
||||||
|
|
||||||
private CoroutineHandle loadingCoroutine;
|
private CoroutineHandle loadingCoroutine;
|
||||||
private bool hasLoaded;
|
public bool HasLoaded { get; private set; }
|
||||||
|
|
||||||
private readonly GameTime fixedTime;
|
private readonly GameTime fixedTime;
|
||||||
|
|
||||||
@@ -234,11 +229,11 @@ namespace Barotrauma
|
|||||||
throw new Exception("Content folder not found. If you are trying to compile the game from the source code and own a legal copy of the game, you can copy the Content folder from the game's files to BarotraumaShared/Content.");
|
throw new Exception("Content folder not found. If you are trying to compile the game from the source code and own a legal copy of the game, you can copy the Content folder from the game's files to BarotraumaShared/Content.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Config = new GameSettings();
|
|
||||||
|
|
||||||
Lua = new LuaSetup();
|
Lua = new LuaSetup();
|
||||||
|
|
||||||
Md5Hash.LoadCache();
|
GameSettings.Init();
|
||||||
|
|
||||||
|
Md5Hash.Cache.Load();
|
||||||
|
|
||||||
ConsoleArguments = args;
|
ConsoleArguments = args;
|
||||||
|
|
||||||
@@ -294,24 +289,42 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void ApplyGraphicsSettings()
|
public void ApplyGraphicsSettings()
|
||||||
{
|
{
|
||||||
GraphicsWidth = Config.GraphicsWidth;
|
void updateConfig()
|
||||||
GraphicsHeight = Config.GraphicsHeight;
|
{
|
||||||
switch (Config.WindowMode)
|
var config = GameSettings.CurrentConfig;
|
||||||
|
config.Graphics.Width = GraphicsWidth;
|
||||||
|
config.Graphics.Height = GraphicsHeight;
|
||||||
|
GameSettings.SetCurrentConfig(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
GraphicsWidth = GameSettings.CurrentConfig.Graphics.Width;
|
||||||
|
GraphicsHeight = GameSettings.CurrentConfig.Graphics.Height;
|
||||||
|
|
||||||
|
if (GraphicsWidth <= 0 || GraphicsHeight <= 0)
|
||||||
|
{
|
||||||
|
GraphicsWidth = GraphicsDevice.DisplayMode.Width;
|
||||||
|
GraphicsHeight = GraphicsDevice.DisplayMode.Height;
|
||||||
|
updateConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (GameSettings.CurrentConfig.Graphics.DisplayMode)
|
||||||
{
|
{
|
||||||
case WindowMode.BorderlessWindowed:
|
case WindowMode.BorderlessWindowed:
|
||||||
GraphicsWidth = GraphicsDevice.DisplayMode.Width;
|
GraphicsWidth = GraphicsDevice.DisplayMode.Width;
|
||||||
GraphicsHeight = GraphicsDevice.DisplayMode.Height;
|
GraphicsHeight = GraphicsDevice.DisplayMode.Height;
|
||||||
|
updateConfig();
|
||||||
break;
|
break;
|
||||||
case WindowMode.Windowed:
|
case WindowMode.Windowed:
|
||||||
GraphicsWidth = Math.Min(GraphicsDevice.DisplayMode.Width, GraphicsWidth);
|
GraphicsWidth = Math.Min(GraphicsDevice.DisplayMode.Width, GraphicsWidth);
|
||||||
GraphicsHeight = Math.Min(GraphicsDevice.DisplayMode.Height, GraphicsHeight);
|
GraphicsHeight = Math.Min(GraphicsDevice.DisplayMode.Height, GraphicsHeight);
|
||||||
|
updateConfig();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
GraphicsDeviceManager.GraphicsProfile = GfxProfile;
|
GraphicsDeviceManager.GraphicsProfile = GfxProfile;
|
||||||
GraphicsDeviceManager.PreferredBackBufferFormat = SurfaceFormat.Color;
|
GraphicsDeviceManager.PreferredBackBufferFormat = SurfaceFormat.Color;
|
||||||
GraphicsDeviceManager.PreferMultiSampling = false;
|
GraphicsDeviceManager.PreferMultiSampling = false;
|
||||||
GraphicsDeviceManager.SynchronizeWithVerticalRetrace = Config.VSyncEnabled;
|
GraphicsDeviceManager.SynchronizeWithVerticalRetrace = GameSettings.CurrentConfig.Graphics.VSync;
|
||||||
SetWindowMode(Config.WindowMode);
|
SetWindowMode(GameSettings.CurrentConfig.Graphics.DisplayMode);
|
||||||
|
|
||||||
defaultViewport = GraphicsDevice.Viewport;
|
defaultViewport = GraphicsDevice.Viewport;
|
||||||
|
|
||||||
@@ -321,8 +334,8 @@ namespace Barotrauma
|
|||||||
public void SetWindowMode(WindowMode windowMode)
|
public void SetWindowMode(WindowMode windowMode)
|
||||||
{
|
{
|
||||||
WindowMode = windowMode;
|
WindowMode = windowMode;
|
||||||
GraphicsDeviceManager.HardwareModeSwitch = Config.WindowMode != WindowMode.BorderlessWindowed;
|
GraphicsDeviceManager.HardwareModeSwitch = windowMode != WindowMode.BorderlessWindowed;
|
||||||
GraphicsDeviceManager.IsFullScreen = Config.WindowMode == WindowMode.Fullscreen || Config.WindowMode == WindowMode.BorderlessWindowed;
|
GraphicsDeviceManager.IsFullScreen = windowMode == WindowMode.Fullscreen || windowMode == WindowMode.BorderlessWindowed;
|
||||||
Window.IsBorderless = !GraphicsDeviceManager.HardwareModeSwitch;
|
Window.IsBorderless = !GraphicsDeviceManager.HardwareModeSwitch;
|
||||||
|
|
||||||
GraphicsDeviceManager.PreferredBackBufferWidth = GraphicsWidth;
|
GraphicsDeviceManager.PreferredBackBufferWidth = GraphicsWidth;
|
||||||
@@ -394,7 +407,7 @@ namespace Barotrauma
|
|||||||
loadingScreenOpen = true;
|
loadingScreenOpen = true;
|
||||||
TitleScreen = new LoadingScreen(GraphicsDevice)
|
TitleScreen = new LoadingScreen(GraphicsDevice)
|
||||||
{
|
{
|
||||||
WaitForLanguageSelection = Config.ShowLanguageSelectionPrompt
|
WaitForLanguageSelection = GameSettings.CurrentConfig.Language == LanguageIdentifier.None
|
||||||
};
|
};
|
||||||
|
|
||||||
bool canLoadInSeparateThread = true;
|
bool canLoadInSeparateThread = true;
|
||||||
@@ -411,27 +424,31 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private IEnumerable<CoroutineStatus> Load(bool isSeparateThread)
|
private IEnumerable<CoroutineStatus> Load(bool isSeparateThread)
|
||||||
{
|
{
|
||||||
if (GameSettings.VerboseLogging)
|
if (GameSettings.CurrentConfig.VerboseLogging)
|
||||||
{
|
{
|
||||||
DebugConsole.NewMessage("LOADING COROUTINE", Color.Lime);
|
DebugConsole.NewMessage("LOADING COROUTINE", Color.Lime);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (TitleScreen.WaitForLanguageSelection)
|
ContentPackageManager.LoadVanillaFileList();
|
||||||
|
|
||||||
|
if (TitleScreen.WaitForLanguageSelection)
|
||||||
{
|
{
|
||||||
yield return CoroutineStatus.Running;
|
ContentPackageManager.VanillaCorePackage.LoadFilesOfType<TextFile>();
|
||||||
|
TitleScreen.AvailableLanguages = TextManager.AvailableLanguages.ToArray();
|
||||||
|
while (TitleScreen.WaitForLanguageSelection)
|
||||||
|
{
|
||||||
|
yield return CoroutineStatus.Running;
|
||||||
|
}
|
||||||
|
ContentPackageManager.VanillaCorePackage.UnloadFilesOfType<TextFile>();
|
||||||
}
|
}
|
||||||
|
|
||||||
SoundManager = new Sounds.SoundManager();
|
SoundManager = new Sounds.SoundManager();
|
||||||
SoundManager.SetCategoryGainMultiplier("default", Config.SoundVolume, 0);
|
SoundManager.ApplySettings();
|
||||||
SoundManager.SetCategoryGainMultiplier("ui", Config.SoundVolume, 0);
|
|
||||||
SoundManager.SetCategoryGainMultiplier("waterambience", Config.SoundVolume, 0);
|
|
||||||
SoundManager.SetCategoryGainMultiplier("music", Config.MusicVolume, 0);
|
|
||||||
SoundManager.SetCategoryGainMultiplier("voip", Math.Min(Config.VoiceChatVolume, 1.0f), 0);
|
|
||||||
|
|
||||||
if (Config.EnableSplashScreen && !ConsoleArguments.Contains("-skipintro"))
|
if (GameSettings.CurrentConfig.EnableSplashScreen && !ConsoleArguments.Contains("-skipintro"))
|
||||||
{
|
{
|
||||||
var pendingSplashScreens = TitleScreen.PendingSplashScreens;
|
var pendingSplashScreens = TitleScreen.PendingSplashScreens;
|
||||||
float baseVolume = MathHelper.Clamp(Config.SoundVolume * 2.0f, 0.0f, 1.0f);
|
float baseVolume = MathHelper.Clamp(GameSettings.CurrentConfig.Audio.SoundVolume * 2.0f, 0.0f, 1.0f);
|
||||||
pendingSplashScreens?.Enqueue(new LoadingScreen.PendingSplashScreen("Content/SplashScreens/Splash_UTG.webm", baseVolume * 0.5f));
|
pendingSplashScreens?.Enqueue(new LoadingScreen.PendingSplashScreen("Content/SplashScreens/Splash_UTG.webm", baseVolume * 0.5f));
|
||||||
pendingSplashScreens?.Enqueue(new LoadingScreen.PendingSplashScreen("Content/SplashScreens/Splash_FF.webm", baseVolume));
|
pendingSplashScreens?.Enqueue(new LoadingScreen.PendingSplashScreen("Content/SplashScreens/Splash_FF.webm", baseVolume));
|
||||||
pendingSplashScreens?.Enqueue(new LoadingScreen.PendingSplashScreen("Content/SplashScreens/Splash_Daedalic.webm", baseVolume * 0.1f));
|
pendingSplashScreens?.Enqueue(new LoadingScreen.PendingSplashScreen("Content/SplashScreens/Splash_Daedalic.webm", baseVolume * 0.1f));
|
||||||
@@ -447,153 +464,57 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GUI.Init(Window, Config.AllEnabledPackages, GraphicsDevice);
|
GUI.Init();
|
||||||
|
|
||||||
|
yield return CoroutineStatus.Running;
|
||||||
|
|
||||||
|
UgcTransition.Prepare();
|
||||||
|
var contentPackageLoadRoutine = ContentPackageManager.Init();
|
||||||
|
foreach (var progress in contentPackageLoadRoutine)
|
||||||
|
{
|
||||||
|
const float min = 1f, max = 70f;
|
||||||
|
TitleScreen.LoadState = MathHelper.Lerp(min, max, progress.Value);
|
||||||
|
yield return CoroutineStatus.Running;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextManager.VerifyLanguageAvailable();
|
||||||
|
|
||||||
DebugConsole.Init();
|
DebugConsole.Init();
|
||||||
|
|
||||||
if (Config.AutoUpdateWorkshopItems)
|
ContentPackageManager.LogEnabledRegularPackageErrors();
|
||||||
{
|
|
||||||
Config.WaitingForAutoUpdate = true;
|
|
||||||
TaskPool.Add("AutoUpdateWorkshopItemsAsync",
|
|
||||||
SteamManager.AutoUpdateWorkshopItemsAsync(), (task) =>
|
|
||||||
{
|
|
||||||
if (!task.TryGetResult(out bool result)) { return; }
|
|
||||||
|
|
||||||
Config.WaitingForAutoUpdate = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
while (Config.WaitingForAutoUpdate) { yield return CoroutineStatus.Running; }
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
if (Config.ModBreakerMode)
|
|
||||||
{
|
|
||||||
Config.SelectCorePackage(ContentPackage.CorePackages.GetRandom());
|
|
||||||
foreach (var regularPackage in ContentPackage.RegularPackages)
|
|
||||||
{
|
|
||||||
if (Rand.Range(0.0, 1.0) <= 0.5)
|
|
||||||
{
|
|
||||||
Config.EnableRegularPackage(regularPackage);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Config.DisableRegularPackage(regularPackage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ContentPackage.SortContentPackages(p =>
|
|
||||||
{
|
|
||||||
return Rand.Int(int.MaxValue);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (Config.AllEnabledPackages.None())
|
|
||||||
{
|
|
||||||
DebugConsole.Log("No content packages selected");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DebugConsole.Log("Selected content packages: " + string.Join(", ", Config.AllEnabledPackages.Select(cp => cp.Name)));
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !DEBUG && !OSX
|
#if !DEBUG && !OSX
|
||||||
GameAnalyticsManager.InitIfConsented();
|
GameAnalyticsManager.InitIfConsented();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
yield return CoroutineStatus.Running;
|
|
||||||
|
|
||||||
Debug.WriteLine("sounds");
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
foreach (CoroutineStatus status in SoundPlayer.Init())
|
|
||||||
{
|
|
||||||
if (status == CoroutineStatus.Success) break;
|
|
||||||
|
|
||||||
i++;
|
|
||||||
TitleScreen.LoadState = SoundPlayer.SoundCount == 0 ?
|
|
||||||
1.0f :
|
|
||||||
Math.Min(40.0f * i / Math.Max(SoundPlayer.SoundCount, 1), 40.0f);
|
|
||||||
|
|
||||||
yield return CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
TitleScreen.LoadState = 40.0f;
|
|
||||||
yield return CoroutineStatus.Running;
|
|
||||||
|
|
||||||
LightManager = new Lights.LightManager(base.GraphicsDevice, Content);
|
|
||||||
|
|
||||||
TitleScreen.LoadState = 41.0f;
|
|
||||||
yield return CoroutineStatus.Running;
|
|
||||||
|
|
||||||
GUI.LoadContent();
|
|
||||||
TitleScreen.LoadState = 42.0f;
|
|
||||||
|
|
||||||
yield return CoroutineStatus.Running;
|
|
||||||
|
|
||||||
TaskPool.Add("InitRelayNetworkAccess", SteamManager.InitRelayNetworkAccess(), (t) => { });
|
TaskPool.Add("InitRelayNetworkAccess", SteamManager.InitRelayNetworkAccess(), (t) => { });
|
||||||
|
|
||||||
FactionPrefab.LoadFactions();
|
|
||||||
NPCSet.LoadSets();
|
|
||||||
CharacterPrefab.LoadAll();
|
|
||||||
MissionPrefab.Init();
|
|
||||||
TraitorMissionPrefab.Init();
|
|
||||||
MapEntityPrefab.Init();
|
|
||||||
Tutorials.Tutorial.Init();
|
|
||||||
MapGenerationParams.Init();
|
|
||||||
LevelGenerationParams.LoadPresets();
|
|
||||||
CaveGenerationParams.LoadPresets();
|
|
||||||
OutpostGenerationParams.LoadPresets();
|
|
||||||
WreckAIConfig.LoadAll();
|
|
||||||
EventSet.LoadPrefabs();
|
|
||||||
ItemPrefab.LoadAll(GetFilesOfType(ContentType.Item));
|
|
||||||
AfflictionPrefab.LoadAll(GetFilesOfType(ContentType.Afflictions));
|
|
||||||
SkillSettings.Load(GetFilesOfType(ContentType.SkillSettings));
|
|
||||||
TalentPrefab.LoadAll(GetFilesOfType(ContentType.Talents));
|
|
||||||
TalentTree.LoadAll(GetFilesOfType(ContentType.TalentTrees));
|
|
||||||
Order.Init();
|
|
||||||
EventManagerSettings.Init();
|
|
||||||
BallastFloraPrefab.LoadAll(GetFilesOfType(ContentType.MapCreature));
|
|
||||||
HintManager.Init();
|
HintManager.Init();
|
||||||
TitleScreen.LoadState = 50.0f;
|
|
||||||
yield return CoroutineStatus.Running;
|
yield return CoroutineStatus.Running;
|
||||||
|
CoreEntityPrefab.InitCorePrefabs();
|
||||||
StructurePrefab.LoadAll(GetFilesOfType(ContentType.Structure));
|
|
||||||
TitleScreen.LoadState = 55.0f;
|
|
||||||
yield return CoroutineStatus.Running;
|
|
||||||
|
|
||||||
UpgradePrefab.LoadAll(GetFilesOfType(ContentType.UpgradeModules));
|
|
||||||
TitleScreen.LoadState = 56.0f;
|
|
||||||
yield return CoroutineStatus.Running;
|
|
||||||
|
|
||||||
JobPrefab.LoadAll(GetFilesOfType(ContentType.Jobs));
|
|
||||||
CorpsePrefab.LoadAll(GetFilesOfType(ContentType.Corpses));
|
|
||||||
|
|
||||||
NPCConversation.LoadAll(GetFilesOfType(ContentType.NPCConversations));
|
|
||||||
|
|
||||||
ItemAssemblyPrefab.LoadAll();
|
|
||||||
TitleScreen.LoadState = 60.0f;
|
|
||||||
yield return CoroutineStatus.Running;
|
|
||||||
|
|
||||||
GameModePreset.Init();
|
GameModePreset.Init();
|
||||||
|
|
||||||
SaveUtil.DeleteDownloadedSubs();
|
SaveUtil.DeleteDownloadedSubs();
|
||||||
SubmarineInfo.RefreshSavedSubs();
|
SubmarineInfo.RefreshSavedSubs();
|
||||||
|
|
||||||
TitleScreen.LoadState = 65.0f;
|
TitleScreen.LoadState = 75.0f;
|
||||||
yield return CoroutineStatus.Running;
|
yield return CoroutineStatus.Running;
|
||||||
|
|
||||||
GameScreen = new GameScreen(GraphicsDeviceManager.GraphicsDevice, Content);
|
GameScreen = new GameScreen(GraphicsDeviceManager.GraphicsDevice, Content);
|
||||||
|
|
||||||
TitleScreen.LoadState = 68.0f;
|
ParticleManager = new ParticleManager(GameScreen.Cam);
|
||||||
|
LightManager = new Lights.LightManager(base.GraphicsDevice, Content);
|
||||||
|
|
||||||
|
TitleScreen.LoadState = 80.0f;
|
||||||
yield return CoroutineStatus.Running;
|
yield return CoroutineStatus.Running;
|
||||||
|
|
||||||
MainMenuScreen = new MainMenuScreen(this);
|
MainMenuScreen = new MainMenuScreen(this);
|
||||||
ServerListScreen = new ServerListScreen();
|
ServerListScreen = new ServerListScreen();
|
||||||
|
|
||||||
TitleScreen.LoadState = 70.0f;
|
TitleScreen.LoadState = 85.0f;
|
||||||
yield return CoroutineStatus.Running;
|
yield return CoroutineStatus.Running;
|
||||||
|
|
||||||
#if USE_STEAM
|
#if USE_STEAM
|
||||||
SteamWorkshopScreen = new SteamWorkshopScreen();
|
|
||||||
if (SteamManager.IsInitialized)
|
if (SteamManager.IsInitialized)
|
||||||
{
|
{
|
||||||
Steamworks.SteamFriends.OnGameRichPresenceJoinRequested += OnInvitedToGame;
|
Steamworks.SteamFriends.OnGameRichPresenceJoinRequested += OnInvitedToGame;
|
||||||
@@ -603,25 +524,25 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
//check the achievements too, so we don't consider people who've played the game before this "gamelaunchcount" stat was added as being 1st-time-players
|
//check the achievements too, so we don't consider people who've played the game before this "gamelaunchcount" stat was added as being 1st-time-players
|
||||||
//(people who have played previous versions, but not unlocked any achievements, will be incorrectly considered 1st-time-players, but that should be a small enough group to not skew the statistics)
|
//(people who have played previous versions, but not unlocked any achievements, will be incorrectly considered 1st-time-players, but that should be a small enough group to not skew the statistics)
|
||||||
if (!achievements.Any() && SteamManager.GetStatInt("gamelaunchcount") <= 0)
|
if (!achievements.Any() && SteamManager.GetStatInt("gamelaunchcount".ToIdentifier()) <= 0)
|
||||||
{
|
{
|
||||||
IsFirstLaunch = true;
|
IsFirstLaunch = true;
|
||||||
GameAnalyticsManager.AddDesignEvent("FirstLaunch");
|
GameAnalyticsManager.AddDesignEvent("FirstLaunch");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SteamManager.IncrementStat("gamelaunchcount", 1);
|
SteamManager.IncrementStat("gamelaunchcount".ToIdentifier(), 1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SubEditorScreen = new SubEditorScreen();
|
SubEditorScreen = new SubEditorScreen();
|
||||||
TestScreen = new TestScreen();
|
TestScreen = new TestScreen();
|
||||||
|
|
||||||
TitleScreen.LoadState = 75.0f;
|
TitleScreen.LoadState = 90.0f;
|
||||||
yield return CoroutineStatus.Running;
|
yield return CoroutineStatus.Running;
|
||||||
|
|
||||||
ParticleEditorScreen = new ParticleEditorScreen();
|
ParticleEditorScreen = new ParticleEditorScreen();
|
||||||
|
|
||||||
TitleScreen.LoadState = 80.0f;
|
TitleScreen.LoadState = 95.0f;
|
||||||
yield return CoroutineStatus.Running;
|
yield return CoroutineStatus.Running;
|
||||||
|
|
||||||
LevelEditorScreen = new LevelEditorScreen();
|
LevelEditorScreen = new LevelEditorScreen();
|
||||||
@@ -632,31 +553,20 @@ namespace Barotrauma
|
|||||||
|
|
||||||
yield return CoroutineStatus.Running;
|
yield return CoroutineStatus.Running;
|
||||||
|
|
||||||
TitleScreen.LoadState = 85.0f;
|
|
||||||
ParticleManager = new ParticleManager(GameScreen.Cam);
|
|
||||||
ParticleManager.LoadPrefabs();
|
|
||||||
TitleScreen.LoadState = 88.0f;
|
|
||||||
LevelObjectPrefab.LoadAll();
|
|
||||||
|
|
||||||
TitleScreen.LoadState = 90.0f;
|
|
||||||
yield return CoroutineStatus.Running;
|
|
||||||
|
|
||||||
DecalManager = new DecalManager();
|
|
||||||
LocationType.Init();
|
|
||||||
MainMenuScreen.Select();
|
MainMenuScreen.Select();
|
||||||
|
|
||||||
foreach (string steamError in SteamManager.InitializationErrors)
|
foreach (Identifier steamError in SteamManager.InitializationErrors)
|
||||||
{
|
{
|
||||||
new GUIMessageBox(TextManager.Get("Error"), TextManager.Get(steamError));
|
new GUIMessageBox(TextManager.Get("Error"), TextManager.Get(steamError));
|
||||||
}
|
}
|
||||||
|
|
||||||
TitleScreen.LoadState = 100.0f;
|
TitleScreen.LoadState = 100.0f;
|
||||||
hasLoaded = true;
|
HasLoaded = true;
|
||||||
if (GameSettings.VerboseLogging)
|
if (GameSettings.CurrentConfig.VerboseLogging)
|
||||||
{
|
{
|
||||||
DebugConsole.NewMessage("LOADING COROUTINE FINISHED", Color.Lime);
|
DebugConsole.NewMessage("LOADING COROUTINE FINISHED", Color.Lime);
|
||||||
}
|
}
|
||||||
yield return CoroutineStatus.Success;
|
yield return CoroutineStatus.Success;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -674,23 +584,6 @@ namespace Barotrauma
|
|||||||
MainThread = null;
|
MainThread = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the file paths of all files of the given type in the content packages.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="type"></param>
|
|
||||||
/// <param name="searchAllContentPackages">If true, also returns files in content packages that are installed but not currently selected.</param>
|
|
||||||
public IEnumerable<ContentFile> GetFilesOfType(ContentType type, bool searchAllContentPackages = false)
|
|
||||||
{
|
|
||||||
if (searchAllContentPackages)
|
|
||||||
{
|
|
||||||
return ContentPackage.GetFilesOfType(ContentPackage.AllPackages, type);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return ContentPackage.GetFilesOfType(Config.AllEnabledPackages, type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnInvitedToGame(Steamworks.Friend friend, string connectCommand) => OnInvitedToGame(connectCommand);
|
public void OnInvitedToGame(Steamworks.Friend friend, string connectCommand) => OnInvitedToGame(connectCommand);
|
||||||
|
|
||||||
public void OnInvitedToGame(string connectCommand)
|
public void OnInvitedToGame(string connectCommand)
|
||||||
@@ -741,7 +634,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (SoundManager != null)
|
if (SoundManager != null)
|
||||||
{
|
{
|
||||||
if (WindowActive || !Config.MuteOnFocusLost)
|
if (WindowActive || !GameSettings.CurrentConfig.Audio.MuteOnFocusLost)
|
||||||
{
|
{
|
||||||
SoundManager.ListenerGain = SoundManager.CompressionDynamicRangeGain;
|
SoundManager.ListenerGain = SoundManager.CompressionDynamicRangeGain;
|
||||||
}
|
}
|
||||||
@@ -790,29 +683,30 @@ namespace Barotrauma
|
|||||||
CancelQuickStart = !CancelQuickStart;
|
CancelQuickStart = !CancelQuickStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TitleScreen.LoadState >= 100.0f && !TitleScreen.PlayingSplashScreen && (Config.AutomaticQuickStartEnabled || Config.AutomaticCampaignLoadEnabled || Config.TestScreenEnabled) && FirstLoad && !CancelQuickStart)
|
if (TitleScreen.LoadState >= 100.0f && !TitleScreen.PlayingSplashScreen &&
|
||||||
|
(GameSettings.CurrentConfig.AutomaticQuickStartEnabled ||
|
||||||
|
GameSettings.CurrentConfig.AutomaticCampaignLoadEnabled ||
|
||||||
|
GameSettings.CurrentConfig.TestScreenEnabled) && FirstLoad && !CancelQuickStart)
|
||||||
{
|
{
|
||||||
loadingScreenOpen = false;
|
loadingScreenOpen = false;
|
||||||
FirstLoad = false;
|
FirstLoad = false;
|
||||||
|
|
||||||
if (Config.TestScreenEnabled)
|
if (GameSettings.CurrentConfig.TestScreenEnabled)
|
||||||
{
|
{
|
||||||
TestScreen.Select();
|
TestScreen.Select();
|
||||||
}
|
}
|
||||||
else if (Config.AutomaticQuickStartEnabled)
|
else if (GameSettings.CurrentConfig.AutomaticQuickStartEnabled)
|
||||||
{
|
{
|
||||||
MainMenuScreen.QuickStart();
|
MainMenuScreen.QuickStart();
|
||||||
}
|
}
|
||||||
else if (Config.AutomaticCampaignLoadEnabled)
|
else if (GameSettings.CurrentConfig.AutomaticCampaignLoadEnabled)
|
||||||
{
|
{
|
||||||
IEnumerable<string> saveFiles = SaveUtil.GetSaveFiles(SaveUtil.SaveType.Singleplayer);
|
var saveFiles = SaveUtil.GetSaveFiles(SaveUtil.SaveType.Singleplayer);
|
||||||
|
|
||||||
if (saveFiles.Count() > 0)
|
if (saveFiles.Count() > 0)
|
||||||
{
|
{
|
||||||
saveFiles = saveFiles.OrderBy(file => File.GetLastWriteTime(file));
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
SaveUtil.LoadGame(saveFiles.Last());
|
SaveUtil.LoadGame(saveFiles.OrderBy(file => file.SaveTime).Last().FilePath);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@@ -826,12 +720,12 @@ namespace Barotrauma
|
|||||||
|
|
||||||
NetworkMember?.Update((float)Timing.Step);
|
NetworkMember?.Update((float)Timing.Step);
|
||||||
|
|
||||||
if (!hasLoaded && !CoroutineManager.IsCoroutineRunning(loadingCoroutine))
|
if (!HasLoaded && !CoroutineManager.IsCoroutineRunning(loadingCoroutine))
|
||||||
{
|
{
|
||||||
throw new LoadingException(loadingCoroutine.Exception);
|
throw new LoadingException(loadingCoroutine.Exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (hasLoaded)
|
else if (HasLoaded)
|
||||||
{
|
{
|
||||||
if (ConnectLobby != 0)
|
if (ConnectLobby != 0)
|
||||||
{
|
{
|
||||||
@@ -858,7 +752,7 @@ namespace Barotrauma
|
|||||||
GameMain.MainMenuScreen.Select();
|
GameMain.MainMenuScreen.Select();
|
||||||
}
|
}
|
||||||
UInt64 serverSteamId = SteamManager.SteamIDStringToUInt64(ConnectEndpoint);
|
UInt64 serverSteamId = SteamManager.SteamIDStringToUInt64(ConnectEndpoint);
|
||||||
Client = new GameClient(Config.PlayerName,
|
Client = new GameClient(MultiplayerPreferences.Instance.PlayerName.FallbackNullOrEmpty(SteamManager.GetUsername()),
|
||||||
serverSteamId != 0 ? null : ConnectEndpoint,
|
serverSteamId != 0 ? null : ConnectEndpoint,
|
||||||
serverSteamId,
|
serverSteamId,
|
||||||
string.IsNullOrWhiteSpace(ConnectName) ? ConnectEndpoint : ConnectName);
|
string.IsNullOrWhiteSpace(ConnectName) ? ConnectEndpoint : ConnectName);
|
||||||
@@ -892,9 +786,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
GUIMessageBox.MessageBoxes.Remove(GUIMessageBox.VisibleBox);
|
GUIMessageBox.MessageBoxes.Remove(GUIMessageBox.VisibleBox);
|
||||||
}
|
}
|
||||||
else if (Tutorial.Initialized && Tutorial.ContentRunning)
|
else if (GameSession?.GameMode is TutorialMode tutorialMode && tutorialMode.Tutorial.ContentRunning)
|
||||||
{
|
{
|
||||||
(GameSession.GameMode as TutorialMode).Tutorial.CloseActiveContentGUI();
|
tutorialMode.Tutorial.CloseActiveContentGUI();
|
||||||
}
|
}
|
||||||
else if (GameSession.IsTabMenuOpen)
|
else if (GameSession.IsTabMenuOpen)
|
||||||
{
|
{
|
||||||
@@ -939,8 +833,11 @@ namespace Barotrauma
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
GUI.ClearUpdateList();
|
GUI.ClearUpdateList();
|
||||||
Paused = (DebugConsole.IsOpen || GUI.PauseMenuOpen || GUI.SettingsMenuOpen || Tutorial.ContentRunning || DebugConsole.Paused) &&
|
Paused =
|
||||||
(NetworkMember == null || !NetworkMember.GameStarted);
|
(DebugConsole.IsOpen || DebugConsole.Paused ||
|
||||||
|
GUI.PauseMenuOpen || GUI.SettingsMenuOpen ||
|
||||||
|
(GameSession?.GameMode is TutorialMode tutoMode && tutoMode.Tutorial.ContentRunning)) &&
|
||||||
|
(NetworkMember == null || !NetworkMember.GameStarted);
|
||||||
if (GameSession?.GameMode != null && GameSession.GameMode.Paused)
|
if (GameSession?.GameMode != null && GameSession.GameMode.Paused)
|
||||||
{
|
{
|
||||||
Paused = true;
|
Paused = true;
|
||||||
@@ -948,7 +845,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (NetworkMember == null && !WindowActive && !Paused && true && Config.PauseOnFocusLost &&
|
if (NetworkMember == null && !WindowActive && !Paused && true && GameSettings.CurrentConfig.PauseOnFocusLost &&
|
||||||
Screen.Selected != MainMenuScreen && Screen.Selected != ServerListScreen && Screen.Selected != NetLobbyScreen &&
|
Screen.Selected != MainMenuScreen && Screen.Selected != ServerListScreen && Screen.Selected != NetLobbyScreen &&
|
||||||
Screen.Selected != SubEditorScreen && Screen.Selected != LevelEditorScreen)
|
Screen.Selected != SubEditorScreen && Screen.Selected != LevelEditorScreen)
|
||||||
{
|
{
|
||||||
@@ -973,9 +870,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Screen.Selected.Update(Timing.Step);
|
Screen.Selected.Update(Timing.Step);
|
||||||
}
|
}
|
||||||
else if (Tutorial.Initialized && Tutorial.ContentRunning)
|
else if (GameSession?.GameMode is TutorialMode tutorialMode && tutorialMode.Tutorial.ContentRunning)
|
||||||
{
|
{
|
||||||
(GameSession.GameMode as TutorialMode).Update((float)Timing.Step);
|
tutorialMode.Update((float)Timing.Step);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -992,6 +889,27 @@ namespace Barotrauma
|
|||||||
NetworkMember?.Update((float)Timing.Step);
|
NetworkMember?.Update((float)Timing.Step);
|
||||||
|
|
||||||
GUI.Update((float)Timing.Step);
|
GUI.Update((float)Timing.Step);
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
if (DebugDraw && GUI.MouseOn != null && PlayerInput.IsCtrlDown() && PlayerInput.KeyHit(Keys.G))
|
||||||
|
{
|
||||||
|
List<GUIComponent> hierarchy = new List<GUIComponent>();
|
||||||
|
var currComponent = GUI.MouseOn;
|
||||||
|
while (currComponent != null)
|
||||||
|
{
|
||||||
|
hierarchy.Add(currComponent);
|
||||||
|
currComponent = currComponent.Parent;
|
||||||
|
}
|
||||||
|
DebugConsole.NewMessage("*********************");
|
||||||
|
foreach (var component in hierarchy)
|
||||||
|
{
|
||||||
|
if (component is { MouseRect: var mouseRect, Rect: var rect })
|
||||||
|
{
|
||||||
|
DebugConsole.NewMessage($"{component.GetType().Name} {component.Style?.Name ?? "[null]"} {rect.Bottom} {mouseRect.Bottom}", mouseRect!=rect ? Color.Lime : Color.Red);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CoroutineManager.Update((float)Timing.Step, Paused ? 0.0f : (float)Timing.Step);
|
CoroutineManager.Update((float)Timing.Step, Paused ? 0.0f : (float)Timing.Step);
|
||||||
@@ -1042,7 +960,7 @@ namespace Barotrauma
|
|||||||
if (Timing.FrameLimit > 0)
|
if (Timing.FrameLimit > 0)
|
||||||
{
|
{
|
||||||
double step = 1.0 / Timing.FrameLimit;
|
double step = 1.0 / Timing.FrameLimit;
|
||||||
while (!Config.VSyncEnabled && sw.Elapsed.TotalSeconds + deltaTime < step)
|
while (!GameSettings.CurrentConfig.Graphics.VSync && sw.Elapsed.TotalSeconds + deltaTime < step)
|
||||||
{
|
{
|
||||||
Thread.Sleep(1);
|
Thread.Sleep(1);
|
||||||
}
|
}
|
||||||
@@ -1054,7 +972,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
TitleScreen.Draw(spriteBatch, base.GraphicsDevice, (float)deltaTime);
|
TitleScreen.Draw(spriteBatch, base.GraphicsDevice, (float)deltaTime);
|
||||||
}
|
}
|
||||||
else if (hasLoaded)
|
else if (HasLoaded)
|
||||||
{
|
{
|
||||||
Screen.Selected.Draw(deltaTime, base.GraphicsDevice, spriteBatch);
|
Screen.Selected.Draw(deltaTime, base.GraphicsDevice, spriteBatch);
|
||||||
}
|
}
|
||||||
@@ -1062,8 +980,33 @@ namespace Barotrauma
|
|||||||
if (DebugDraw && GUI.MouseOn != null)
|
if (DebugDraw && GUI.MouseOn != null)
|
||||||
{
|
{
|
||||||
spriteBatch.Begin();
|
spriteBatch.Begin();
|
||||||
GUI.DrawRectangle(spriteBatch, GUI.MouseOn.MouseRect, Color.Lime);
|
if (PlayerInput.IsCtrlDown() && PlayerInput.KeyDown(Keys.G))
|
||||||
GUI.DrawRectangle(spriteBatch, GUI.MouseOn.Rect, Color.Cyan);
|
{
|
||||||
|
List<GUIComponent> hierarchy = new List<GUIComponent>();
|
||||||
|
var currComponent = GUI.MouseOn;
|
||||||
|
while (currComponent != null)
|
||||||
|
{
|
||||||
|
hierarchy.Add(currComponent);
|
||||||
|
currComponent = currComponent.Parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
Color[] colors = { Color.Lime, Color.Yellow, Color.Aqua, Color.Red };
|
||||||
|
for (int index = 0; index < hierarchy.Count; index++)
|
||||||
|
{
|
||||||
|
var component = hierarchy[index];
|
||||||
|
if (component is { MouseRect: var mouseRect, Rect: var rect })
|
||||||
|
{
|
||||||
|
if (mouseRect.IsEmpty) { mouseRect = rect; }
|
||||||
|
mouseRect.Location += (index%2,(index%4)/2);
|
||||||
|
GUI.DrawRectangle(spriteBatch, mouseRect, colors[index%4]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GUI.DrawRectangle(spriteBatch, GUI.MouseOn.MouseRect, Color.Lime);
|
||||||
|
GUI.DrawRectangle(spriteBatch, GUI.MouseOn.Rect, Color.Cyan);
|
||||||
|
}
|
||||||
spriteBatch.End();
|
spriteBatch.End();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1078,7 +1021,7 @@ namespace Barotrauma
|
|||||||
if (showVerificationPrompt)
|
if (showVerificationPrompt)
|
||||||
{
|
{
|
||||||
string text = (Screen.Selected is CharacterEditor.CharacterEditorScreen || Screen.Selected is SubEditorScreen) ? "PauseMenuQuitVerificationEditor" : "PauseMenuQuitVerification";
|
string text = (Screen.Selected is CharacterEditor.CharacterEditorScreen || Screen.Selected is SubEditorScreen) ? "PauseMenuQuitVerificationEditor" : "PauseMenuQuitVerification";
|
||||||
var msgBox = new GUIMessageBox("", TextManager.Get(text), new string[] { TextManager.Get("Yes"), TextManager.Get("Cancel") })
|
var msgBox = new GUIMessageBox("", TextManager.Get(text), new LocalizedString[] { TextManager.Get("Yes"), TextManager.Get("Cancel") })
|
||||||
{
|
{
|
||||||
UserData = "verificationprompt"
|
UserData = "verificationprompt"
|
||||||
};
|
};
|
||||||
@@ -1106,9 +1049,9 @@ namespace Barotrauma
|
|||||||
// Update store stock when saving and quitting in an outpost (normally updated when CampaignMode.End() is called)
|
// Update store stock when saving and quitting in an outpost (normally updated when CampaignMode.End() is called)
|
||||||
if (GameSession?.Campaign is SinglePlayerCampaign spCampaign && Level.IsLoadedOutpost && spCampaign.Map?.CurrentLocation != null && spCampaign.CargoManager != null)
|
if (GameSession?.Campaign is SinglePlayerCampaign spCampaign && Level.IsLoadedOutpost && spCampaign.Map?.CurrentLocation != null && spCampaign.CargoManager != null)
|
||||||
{
|
{
|
||||||
spCampaign.Map.CurrentLocation.AddToStock(spCampaign.CargoManager.SoldItems);
|
spCampaign.Map.CurrentLocation.AddStock(spCampaign.CargoManager.SoldItems);
|
||||||
spCampaign.CargoManager.ClearSoldItemsProjSpecific();
|
spCampaign.CargoManager.ClearSoldItemsProjSpecific();
|
||||||
spCampaign.Map.CurrentLocation.RemoveFromStock(spCampaign.CargoManager.PurchasedItems);
|
spCampaign.Map.CurrentLocation.RemoveStock(spCampaign.CargoManager.PurchasedItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
SaveUtil.SaveGame(GameSession.SavePath);
|
SaveUtil.SaveGame(GameSession.SavePath);
|
||||||
@@ -1126,18 +1069,18 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
double roundDuration = Timing.TotalTime - GameSession.RoundStartTime;
|
double roundDuration = Timing.TotalTime - GameSession.RoundStartTime;
|
||||||
GameAnalyticsManager.AddProgressionEvent(GameAnalyticsManager.ProgressionStatus.Fail,
|
GameAnalyticsManager.AddProgressionEvent(GameAnalyticsManager.ProgressionStatus.Fail,
|
||||||
GameSession.GameMode?.Preset.Identifier ?? "none",
|
GameSession.GameMode?.Preset.Identifier.Value ?? "none",
|
||||||
roundDuration);
|
roundDuration);
|
||||||
string eventId = "QuitRound:" + (GameSession.GameMode?.Preset.Identifier ?? "none") + ":";
|
string eventId = "QuitRound:" + (GameSession.GameMode?.Preset.Identifier.Value ?? "none") + ":";
|
||||||
GameAnalyticsManager.AddDesignEvent(eventId + "EventManager:CurrentIntensity", GameSession.EventManager.CurrentIntensity);
|
GameAnalyticsManager.AddDesignEvent(eventId + "EventManager:CurrentIntensity", GameSession.EventManager.CurrentIntensity);
|
||||||
foreach (var activeEvent in GameSession.EventManager.ActiveEvents)
|
foreach (var activeEvent in GameSession.EventManager.ActiveEvents)
|
||||||
{
|
{
|
||||||
GameAnalyticsManager.AddDesignEvent(eventId + "EventManager:ActiveEvents:" + activeEvent.ToString());
|
GameAnalyticsManager.AddDesignEvent(eventId + "EventManager:ActiveEvents:" + activeEvent.ToString());
|
||||||
}
|
}
|
||||||
GameSession.LogEndRoundStats(eventId);
|
GameSession.LogEndRoundStats(eventId);
|
||||||
if (Tutorial.Initialized)
|
if (GameSession.GameMode is TutorialMode tutorialMode)
|
||||||
{
|
{
|
||||||
((TutorialMode)GameSession.GameMode).Tutorial?.Stop();
|
tutorialMode.Tutorial?.Stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GUIMessageBox.CloseAll();
|
GUIMessageBox.CloseAll();
|
||||||
@@ -1150,7 +1093,7 @@ namespace Barotrauma
|
|||||||
public void ShowCampaignDisclaimer(Action onContinue = null)
|
public void ShowCampaignDisclaimer(Action onContinue = null)
|
||||||
{
|
{
|
||||||
var msgBox = new GUIMessageBox(TextManager.Get("CampaignDisclaimerTitle"), TextManager.Get("CampaignDisclaimerText"),
|
var msgBox = new GUIMessageBox(TextManager.Get("CampaignDisclaimerTitle"), TextManager.Get("CampaignDisclaimerText"),
|
||||||
new string[] { TextManager.Get("CampaignRoadMapTitle"), TextManager.Get("OK") });
|
new LocalizedString[] { TextManager.Get("CampaignRoadMapTitle"), TextManager.Get("OK") });
|
||||||
|
|
||||||
msgBox.Buttons[0].OnClicked = (btn, userdata) =>
|
msgBox.Buttons[0].OnClicked = (btn, userdata) =>
|
||||||
{
|
{
|
||||||
@@ -1161,8 +1104,10 @@ namespace Barotrauma
|
|||||||
msgBox.Buttons[1].OnClicked += msgBox.Close;
|
msgBox.Buttons[1].OnClicked += msgBox.Close;
|
||||||
msgBox.Buttons[1].OnClicked += (_, __) => { onContinue?.Invoke(); return true; };
|
msgBox.Buttons[1].OnClicked += (_, __) => { onContinue?.Invoke(); return true; };
|
||||||
|
|
||||||
Config.CampaignDisclaimerShown = true;
|
var config = GameSettings.CurrentConfig;
|
||||||
Config.SaveNewPlayerConfig();
|
config.CampaignDisclaimerShown = true;
|
||||||
|
GameSettings.SetCurrentConfig(config);
|
||||||
|
GameSettings.SaveCurrentConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ShowEditorDisclaimer()
|
public void ShowEditorDisclaimer()
|
||||||
@@ -1170,16 +1115,16 @@ namespace Barotrauma
|
|||||||
var msgBox = new GUIMessageBox(TextManager.Get("EditorDisclaimerTitle"), TextManager.Get("EditorDisclaimerText"));
|
var msgBox = new GUIMessageBox(TextManager.Get("EditorDisclaimerTitle"), TextManager.Get("EditorDisclaimerText"));
|
||||||
var linkHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.25f), msgBox.Content.RectTransform)) { Stretch = true, RelativeSpacing = 0.025f };
|
var linkHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.25f), msgBox.Content.RectTransform)) { Stretch = true, RelativeSpacing = 0.025f };
|
||||||
linkHolder.RectTransform.MaxSize = new Point(int.MaxValue, linkHolder.Rect.Height);
|
linkHolder.RectTransform.MaxSize = new Point(int.MaxValue, linkHolder.Rect.Height);
|
||||||
List<Pair<string, string>> links = new List<Pair<string, string>>()
|
List<(LocalizedString Caption, LocalizedString Url)> links = new List<(LocalizedString, LocalizedString)>()
|
||||||
{
|
{
|
||||||
new Pair<string, string>(TextManager.Get("EditorDisclaimerWikiLink"), TextManager.Get("EditorDisclaimerWikiUrl")),
|
(TextManager.Get("EditorDisclaimerWikiLink"), TextManager.Get("EditorDisclaimerWikiUrl")),
|
||||||
new Pair<string, string>(TextManager.Get("EditorDisclaimerDiscordLink"), TextManager.Get("EditorDisclaimerDiscordUrl")),
|
(TextManager.Get("EditorDisclaimerDiscordLink"), TextManager.Get("EditorDisclaimerDiscordUrl")),
|
||||||
};
|
};
|
||||||
foreach (var link in links)
|
foreach (var link in links)
|
||||||
{
|
{
|
||||||
new GUIButton(new RectTransform(new Vector2(1.0f, 0.2f), linkHolder.RectTransform), link.First, style: "MainMenuGUIButton", textAlignment: Alignment.Left)
|
new GUIButton(new RectTransform(new Vector2(1.0f, 0.2f), linkHolder.RectTransform), link.Caption, style: "MainMenuGUIButton", textAlignment: Alignment.Left)
|
||||||
{
|
{
|
||||||
UserData = link.Second,
|
UserData = link.Url,
|
||||||
OnClicked = (btn, userdata) =>
|
OnClicked = (btn, userdata) =>
|
||||||
{
|
{
|
||||||
ShowOpenUrlInWebBrowserPrompt(userdata as string);
|
ShowOpenUrlInWebBrowserPrompt(userdata as string);
|
||||||
@@ -1190,8 +1135,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
msgBox.InnerFrame.RectTransform.MinSize = new Point(0,
|
msgBox.InnerFrame.RectTransform.MinSize = new Point(0,
|
||||||
msgBox.InnerFrame.Rect.Height + linkHolder.Rect.Height + msgBox.Content.AbsoluteSpacing * 2 + 10);
|
msgBox.InnerFrame.Rect.Height + linkHolder.Rect.Height + msgBox.Content.AbsoluteSpacing * 2 + 10);
|
||||||
Config.EditorDisclaimerShown = true;
|
var config = GameSettings.CurrentConfig;
|
||||||
Config.SaveNewPlayerConfig();
|
config.EditorDisclaimerShown = true;
|
||||||
|
GameSettings.SetCurrentConfig(config);
|
||||||
|
GameSettings.SaveCurrentConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ShowBugReporter()
|
public void ShowBugReporter()
|
||||||
@@ -1265,7 +1212,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (GameAnalyticsManager.SendUserStatistics) { GameAnalyticsManager.ShutDown(); }
|
if (GameAnalyticsManager.SendUserStatistics) { GameAnalyticsManager.ShutDown(); }
|
||||||
if (GameSettings.SaveDebugConsoleLogs || GameSettings.VerboseLogging) { DebugConsole.SaveLogs(); }
|
if (GameSettings.CurrentConfig.SaveDebugConsoleLogs
|
||||||
|
|| GameSettings.CurrentConfig.VerboseLogging) { DebugConsole.SaveLogs(); }
|
||||||
|
|
||||||
base.OnExiting(sender, args);
|
base.OnExiting(sender, args);
|
||||||
}
|
}
|
||||||
@@ -1275,14 +1223,14 @@ namespace Barotrauma
|
|||||||
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; }
|
||||||
|
|
||||||
string text = TextManager.GetWithVariable("openlinkinbrowserprompt", "[link]", url);
|
LocalizedString text = TextManager.GetWithVariable("openlinkinbrowserprompt", "[link]", url);
|
||||||
string extensionText = TextManager.Get(promptExtensionTag, returnNull: true, useEnglishAsFallBack: false);
|
LocalizedString extensionText = TextManager.Get(promptExtensionTag);
|
||||||
if (!string.IsNullOrEmpty(extensionText))
|
if (!extensionText.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
text += $"\n\n{extensionText}";
|
text += $"\n\n{extensionText}";
|
||||||
}
|
}
|
||||||
|
|
||||||
var msgBox = new GUIMessageBox("", text, new string[] { TextManager.Get("Yes"), TextManager.Get("No") })
|
var msgBox = new GUIMessageBox("", text, new LocalizedString[] { TextManager.Get("Yes"), TextManager.Get("No") })
|
||||||
{
|
{
|
||||||
UserData = "verificationprompt"
|
UserData = "verificationprompt"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -45,28 +45,39 @@ namespace Barotrauma
|
|||||||
return SoldEntities.Where(se => se.Status != SoldEntity.SellStatus.Unconfirmed);
|
return SoldEntities.Where(se => se.Status != SoldEntity.SellStatus.Unconfirmed);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetItemsInBuyCrate(List<PurchasedItem> items)
|
public void SetItemsInBuyCrate(Dictionary<Identifier, List<PurchasedItem>> items)
|
||||||
{
|
{
|
||||||
ItemsInBuyCrate.Clear();
|
ItemsInBuyCrate.Clear();
|
||||||
ItemsInBuyCrate.AddRange(items);
|
foreach (var entry in items)
|
||||||
|
{
|
||||||
|
ItemsInBuyCrate.Add(entry.Key, entry.Value);
|
||||||
|
}
|
||||||
OnItemsInBuyCrateChanged?.Invoke();
|
OnItemsInBuyCrateChanged?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetItemsInSubSellCrate(List<PurchasedItem> items)
|
public void SetItemsInSubSellCrate(Dictionary<Identifier, List<PurchasedItem>> items)
|
||||||
{
|
{
|
||||||
ItemsInSellFromSubCrate.Clear();
|
ItemsInSellFromSubCrate.Clear();
|
||||||
ItemsInSellFromSubCrate.AddRange(items);
|
foreach (var entry in items)
|
||||||
|
{
|
||||||
|
ItemsInSellFromSubCrate.Add(entry.Key, entry.Value);
|
||||||
|
}
|
||||||
OnItemsInSellFromSubCrateChanged?.Invoke();
|
OnItemsInSellFromSubCrateChanged?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetSoldItems(List<SoldItem> items)
|
public void SetSoldItems(Dictionary<Identifier, List<SoldItem>> items)
|
||||||
{
|
{
|
||||||
|
if (SoldItems.Count == 0 && items.Count == 0) { return; }
|
||||||
|
|
||||||
SoldItems.Clear();
|
SoldItems.Clear();
|
||||||
SoldItems.AddRange(items);
|
foreach (var entry in items)
|
||||||
|
{
|
||||||
|
SoldItems.Add(entry.Key, entry.Value);
|
||||||
|
}
|
||||||
foreach (var se in SoldEntities)
|
foreach (var se in SoldEntities)
|
||||||
{
|
{
|
||||||
if (se.Status == SoldEntity.SellStatus.Confirmed) { continue; }
|
if (se.Status == SoldEntity.SellStatus.Confirmed) { continue; }
|
||||||
if (SoldItems.Any(si => Match(si, se, true)))
|
if (SoldItems.Any(si => si.Value.Any(si => Match(si, se, true))))
|
||||||
{
|
{
|
||||||
se.Status = SoldEntity.SellStatus.Confirmed;
|
se.Status = SoldEntity.SellStatus.Confirmed;
|
||||||
}
|
}
|
||||||
@@ -75,13 +86,16 @@ namespace Barotrauma
|
|||||||
se.Status = SoldEntity.SellStatus.Unconfirmed;
|
se.Status = SoldEntity.SellStatus.Unconfirmed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (var si in SoldItems)
|
foreach (var soldItems in SoldItems.Values)
|
||||||
{
|
{
|
||||||
if (si.Origin != SoldItem.SellOrigin.Submarine) { continue; }
|
foreach (var si in soldItems)
|
||||||
if (!(SoldEntities.FirstOrDefault(se => se.Item == null && Match(si, se, false)) is SoldEntity soldEntityMatch)) { continue; }
|
{
|
||||||
if (!(Entity.FindEntityByID(si.ID) is Item item)) { continue; }
|
if (si.Origin != SoldItem.SellOrigin.Submarine) { continue; }
|
||||||
soldEntityMatch.SetItem(item);
|
if (!(SoldEntities.FirstOrDefault(se => se.Item == null && Match(si, se, false)) is SoldEntity soldEntityMatch)) { continue; }
|
||||||
soldEntityMatch.Status = SoldEntity.SellStatus.Confirmed;
|
if (!(Entity.FindEntityByID(si.ID) is Item item)) { continue; }
|
||||||
|
soldEntityMatch.SetItem(item);
|
||||||
|
soldEntityMatch.Status = SoldEntity.SellStatus.Confirmed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
OnSoldItemsChanged?.Invoke();
|
OnSoldItemsChanged?.Invoke();
|
||||||
|
|
||||||
@@ -94,45 +108,24 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ModifyItemQuantityInSellCrate(ItemPrefab itemPrefab, int changeInQuantity)
|
public void ModifyItemQuantityInSellCrate(Identifier storeIdentifier, ItemPrefab itemPrefab, int changeInQuantity)
|
||||||
{
|
{
|
||||||
var itemToSell = ItemsInSellCrate.Find(i => i.ItemPrefab == itemPrefab);
|
if (GetSellCrateItem(storeIdentifier, itemPrefab) is { } item)
|
||||||
if (itemToSell != null)
|
|
||||||
{
|
{
|
||||||
itemToSell.Quantity += changeInQuantity;
|
item.Quantity += changeInQuantity;
|
||||||
if (itemToSell.Quantity < 1)
|
if (item.Quantity < 1)
|
||||||
{
|
{
|
||||||
ItemsInSellCrate.Remove(itemToSell);
|
GetSellCrateItems(storeIdentifier)?.Remove(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (changeInQuantity > 0)
|
else if (changeInQuantity > 0)
|
||||||
{
|
{
|
||||||
itemToSell = new PurchasedItem(itemPrefab, changeInQuantity);
|
GetSellCrateItems(storeIdentifier, create: true).Add(new PurchasedItem(itemPrefab, changeInQuantity));
|
||||||
ItemsInSellCrate.Add(itemToSell);
|
|
||||||
}
|
}
|
||||||
OnItemsInSellCrateChanged?.Invoke();
|
OnItemsInSellCrateChanged?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ModifyItemQuantityInSellFromSubCrate(ItemPrefab itemPrefab, int changeInQuantity)
|
public void SellItems(Identifier storeIdentifier, List<PurchasedItem> itemsToSell, Store.StoreTab sellingMode)
|
||||||
{
|
|
||||||
var itemToSell = ItemsInSellFromSubCrate.Find(i => i.ItemPrefab == itemPrefab);
|
|
||||||
if (itemToSell != null)
|
|
||||||
{
|
|
||||||
itemToSell.Quantity += changeInQuantity;
|
|
||||||
if (itemToSell.Quantity < 1)
|
|
||||||
{
|
|
||||||
ItemsInSellFromSubCrate.Remove(itemToSell);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (changeInQuantity > 0)
|
|
||||||
{
|
|
||||||
itemToSell = new PurchasedItem(itemPrefab, changeInQuantity);
|
|
||||||
ItemsInSellFromSubCrate.Add(itemToSell);
|
|
||||||
}
|
|
||||||
OnItemsInSellFromSubCrateChanged?.Invoke();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SellItems(List<PurchasedItem> itemsToSell, Store.StoreTab sellingMode)
|
|
||||||
{
|
{
|
||||||
IEnumerable<Item> sellableItems;
|
IEnumerable<Item> sellableItems;
|
||||||
try
|
try
|
||||||
@@ -146,19 +139,24 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
catch (NotImplementedException e)
|
catch (NotImplementedException e)
|
||||||
{
|
{
|
||||||
DebugConsole.ShowError($"Error selling items: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
DebugConsole.ShowError($"Error selling items: uknown store tab type \"{sellingMode}\".\n{e.StackTrace.CleanupStackTrace()}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bool canAddToRemoveQueue = campaign.IsSinglePlayer && Entity.Spawner != null;
|
bool canAddToRemoveQueue = campaign.IsSinglePlayer && Entity.Spawner != null;
|
||||||
byte sellerId = GameMain.Client?.ID ?? 0;
|
byte sellerId = GameMain.Client?.ID ?? 0;
|
||||||
// Check all the prices before starting the transaction
|
// Check all the prices before starting the transaction to make sure the modifiers stay the same for the whole transaction
|
||||||
// to make sure the modifiers stay the same for the whole transaction
|
var sellValues = GetSellValuesAtCurrentLocation(storeIdentifier, itemsToSell.Select(i => i.ItemPrefab));
|
||||||
Dictionary<ItemPrefab, int> sellValues = GetSellValuesAtCurrentLocation(itemsToSell.Select(i => i.ItemPrefab));
|
if (!(Location.GetStore(storeIdentifier) is { } store))
|
||||||
foreach (PurchasedItem item in itemsToSell)
|
{
|
||||||
|
DebugConsole.ShowError($"Error selling items at {Location}: no store with identifier \"{storeIdentifier}\" exists.\n{Environment.StackTrace.CleanupStackTrace()}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var storeSpecificSoldItems = GetSoldItems(storeIdentifier, create: true);
|
||||||
|
foreach (var item in itemsToSell)
|
||||||
{
|
{
|
||||||
int itemValue = item.Quantity * sellValues[item.ItemPrefab];
|
int itemValue = item.Quantity * sellValues[item.ItemPrefab];
|
||||||
// check if the store can afford the item
|
// check if the store can afford the item
|
||||||
if (Location.StoreCurrentBalance < itemValue) { continue; }
|
if (store.Balance < itemValue) { continue; }
|
||||||
// TODO: Write logic for prioritizing certain items over others (e.g. lone Battery Cell should be preferred over one inside a Stun Baton)
|
// TODO: Write logic for prioritizing certain items over others (e.g. lone Battery Cell should be preferred over one inside a Stun Baton)
|
||||||
var matchingItems = sellableItems.Where(i => i.Prefab == item.ItemPrefab);
|
var matchingItems = sellableItems.Where(i => i.Prefab == item.ItemPrefab);
|
||||||
int count = Math.Min(item.Quantity, matchingItems.Count());
|
int count = Math.Min(item.Quantity, matchingItems.Count());
|
||||||
@@ -168,9 +166,9 @@ namespace Barotrauma
|
|||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
var matchingItem = matchingItems.ElementAt(i);
|
var matchingItem = matchingItems.ElementAt(i);
|
||||||
SoldItems.Add(new SoldItem(matchingItem.Prefab, matchingItem.ID, canAddToRemoveQueue, sellerId, origin));
|
storeSpecificSoldItems.Add(new SoldItem(matchingItem.Prefab, matchingItem.ID, canAddToRemoveQueue, sellerId, origin));
|
||||||
SoldEntities.Add(new SoldEntity(matchingItem, campaign.IsSinglePlayer ? SoldEntity.SellStatus.Confirmed : SoldEntity.SellStatus.Local));
|
SoldEntities.Add(new SoldEntity(matchingItem, campaign.IsSinglePlayer ? SoldEntity.SellStatus.Confirmed : SoldEntity.SellStatus.Local));
|
||||||
if (canAddToRemoveQueue) { Entity.Spawner.AddToRemoveQueue(matchingItem); }
|
if (canAddToRemoveQueue) { Entity.Spawner.AddItemToRemoveQueue(matchingItem); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -178,22 +176,23 @@ namespace Barotrauma
|
|||||||
// When selling from the sub in multiplayer, the server will determine the items that are sold
|
// When selling from the sub in multiplayer, the server will determine the items that are sold
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
SoldItems.Add(new SoldItem(item.ItemPrefab, Entity.NullEntityID, canAddToRemoveQueue, sellerId, origin));
|
storeSpecificSoldItems.Add(new SoldItem(item.ItemPrefab, Entity.NullEntityID, canAddToRemoveQueue, sellerId, origin));
|
||||||
SoldEntities.Add(new SoldEntity(item.ItemPrefab, SoldEntity.SellStatus.Local));
|
SoldEntities.Add(new SoldEntity(item.ItemPrefab, SoldEntity.SellStatus.Local));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Exchange money
|
// Exchange money
|
||||||
Location.StoreCurrentBalance -= itemValue;
|
store.Balance -= itemValue;
|
||||||
campaign.Money += itemValue;
|
campaign.Bank.Give(itemValue);
|
||||||
GameAnalyticsManager.AddMoneyGainedEvent(itemValue, GameAnalyticsManager.MoneySource.Store, item.ItemPrefab.Identifier);
|
GameAnalyticsManager.AddMoneyGainedEvent(itemValue, GameAnalyticsManager.MoneySource.Store, item.ItemPrefab.Identifier.Value);
|
||||||
|
|
||||||
// Remove from the sell crate
|
// Remove from the sell crate
|
||||||
if ((sellingMode == Store.StoreTab.Sell ? ItemsInSellCrate : ItemsInSellFromSubCrate)?.Find(pi => pi.ItemPrefab == item.ItemPrefab) is { } itemToSell)
|
var sellCrate = (sellingMode == Store.StoreTab.Sell ? GetSellCrateItems(storeIdentifier) : GetSubCrateItems(storeIdentifier));
|
||||||
|
if (sellCrate?.Find(pi => pi.ItemPrefab == item.ItemPrefab) is { } itemToSell)
|
||||||
{
|
{
|
||||||
itemToSell.Quantity -= item.Quantity;
|
itemToSell.Quantity -= item.Quantity;
|
||||||
if (itemToSell.Quantity < 1)
|
if (itemToSell.Quantity < 1)
|
||||||
{
|
{
|
||||||
(sellingMode == Store.StoreTab.Sell ? ItemsInSellCrate : ItemsInSellFromSubCrate)?.Remove(itemToSell);
|
sellCrate.Remove(itemToSell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
+13
-14
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Immutable;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
@@ -52,39 +53,39 @@ namespace Barotrauma
|
|||||||
|
|
||||||
text = text.TrimEnd('\n');
|
text = text.TrimEnd('\n');
|
||||||
|
|
||||||
List<RichTextData> richTextDatas = RichTextData.GetRichTextData(text, out text) ?? new List<RichTextData>();
|
ImmutableArray<RichTextData>? richTextDatas = RichTextData.GetRichTextData(text, out text);
|
||||||
|
|
||||||
Vector2 size = GUI.SmallFont.MeasureString(text);
|
Vector2 size = GUIStyle.SmallFont.MeasureString(text);
|
||||||
Vector2 infoPos = new Vector2(GameMain.GraphicsWidth - size.X - 16, pos.Y + 8);
|
Vector2 infoPos = new Vector2(GameMain.GraphicsWidth - size.X - 16, pos.Y + 8);
|
||||||
Rectangle infoRect = new Rectangle(infoPos.ToPoint(), size.ToPoint());
|
Rectangle infoRect = new Rectangle(infoPos.ToPoint(), size.ToPoint());
|
||||||
infoRect.Inflate(8, 8);
|
infoRect.Inflate(8, 8);
|
||||||
GUI.DrawRectangle(spriteBatch, infoRect, Color.Black * 0.8f, isFilled: true);
|
GUI.DrawRectangle(spriteBatch, infoRect, Color.Black * 0.8f, isFilled: true);
|
||||||
GUI.DrawRectangle(spriteBatch, infoRect, Color.White * 0.8f);
|
GUI.DrawRectangle(spriteBatch, infoRect, Color.White * 0.8f);
|
||||||
|
|
||||||
if (richTextDatas.Any())
|
if (richTextDatas != null && richTextDatas.Value.Any())
|
||||||
{
|
{
|
||||||
GUI.DrawStringWithColors(spriteBatch, infoPos, text, Color.White, richTextDatas, font: GUI.SmallFont);
|
GUI.DrawStringWithColors(spriteBatch, infoPos, text, Color.White, richTextDatas.Value, font: GUIStyle.SmallFont);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GUI.DrawString(spriteBatch, infoPos, text, Color.White, font: GUI.SmallFont);
|
GUI.DrawString(spriteBatch, infoPos, text, Color.White, font: GUIStyle.SmallFont);
|
||||||
}
|
}
|
||||||
|
|
||||||
float y = infoRect.Bottom + 16;
|
float y = infoRect.Bottom + 16;
|
||||||
if (Campaign.Factions != null)
|
if (Campaign.Factions != null)
|
||||||
{
|
{
|
||||||
const string factionHeader = "Reputations";
|
const string factionHeader = "Reputations";
|
||||||
Vector2 factionHeaderSize = GUI.SubHeadingFont.MeasureString(factionHeader);
|
Vector2 factionHeaderSize = GUIStyle.SubHeadingFont.MeasureString(factionHeader);
|
||||||
Vector2 factionPos = new Vector2(GameMain.GraphicsWidth - (264 / 2) - factionHeaderSize.X / 2, y);
|
Vector2 factionPos = new Vector2(GameMain.GraphicsWidth - (264 / 2) - factionHeaderSize.X / 2, y);
|
||||||
|
|
||||||
GUI.DrawString(spriteBatch, factionPos, factionHeader, Color.White, font: GUI.SubHeadingFont);
|
GUI.DrawString(spriteBatch, factionPos, factionHeader, Color.White, font: GUIStyle.SubHeadingFont);
|
||||||
y += factionHeaderSize.Y + 8;
|
y += factionHeaderSize.Y + 8;
|
||||||
|
|
||||||
foreach (Faction faction in Campaign.Factions)
|
foreach (Faction faction in Campaign.Factions)
|
||||||
{
|
{
|
||||||
string name = faction.Prefab.Name;
|
LocalizedString name = faction.Prefab.Name;
|
||||||
Vector2 nameSize = GUI.SmallFont.MeasureString(name);
|
Vector2 nameSize = GUIStyle.SmallFont.MeasureString(name);
|
||||||
GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - 264, y), name, Color.White, font: GUI.SmallFont);
|
GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - 264, y), name, Color.White, font: GUIStyle.SmallFont);
|
||||||
y += nameSize.Y + 5;
|
y += nameSize.Y + 5;
|
||||||
|
|
||||||
Color color = ToolBox.GradientLerp(faction.Reputation.NormalizedValue, Color.Red, Color.Yellow, Color.LightGreen);
|
Color color = ToolBox.GradientLerp(faction.Reputation.NormalizedValue, Color.Red, Color.Yellow, Color.LightGreen);
|
||||||
@@ -98,8 +99,8 @@ namespace Barotrauma
|
|||||||
if (location?.Reputation != null)
|
if (location?.Reputation != null)
|
||||||
{
|
{
|
||||||
string name = Campaign.Map?.CurrentLocation.Name;
|
string name = Campaign.Map?.CurrentLocation.Name;
|
||||||
Vector2 nameSize = GUI.SmallFont.MeasureString(name);
|
Vector2 nameSize = GUIStyle.SmallFont.MeasureString(name);
|
||||||
GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - 264, y), name, Color.White, font: GUI.SmallFont);
|
GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - 264, y), name, Color.White, font: GUIStyle.SmallFont);
|
||||||
y += nameSize.Y + 5;
|
y += nameSize.Y + 5;
|
||||||
|
|
||||||
float normalizedReputation = MathUtils.InverseLerp(location.Reputation.MinReputation, location.Reputation.MaxReputation, location.Reputation.Value);
|
float normalizedReputation = MathUtils.InverseLerp(location.Reputation.MinReputation, location.Reputation.MaxReputation, location.Reputation.Value);
|
||||||
@@ -107,8 +108,6 @@ namespace Barotrauma
|
|||||||
GUI.DrawRectangle(spriteBatch, new Rectangle(GameMain.GraphicsWidth - 264, (int) y, (int)(normalizedReputation * 255), 10), color, isFilled: true);
|
GUI.DrawRectangle(spriteBatch, new Rectangle(GameMain.GraphicsWidth - 264, (int) y, (int)(normalizedReputation * 255), 10), color, isFilled: true);
|
||||||
GUI.DrawRectangle(spriteBatch, new Rectangle(GameMain.GraphicsWidth - 264, (int) y, 256, 10), Color.White);
|
GUI.DrawRectangle(spriteBatch, new Rectangle(GameMain.GraphicsWidth - 264, (int) y, 256, 10), Color.White);
|
||||||
}
|
}
|
||||||
|
|
||||||
richTextDatas.Clear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
namespace Barotrauma
|
||||||
|
{
|
||||||
|
internal partial class Wallet
|
||||||
|
{
|
||||||
|
public bool IsOwnWallet =>
|
||||||
|
GameMain.GameSession?.Campaign switch
|
||||||
|
{
|
||||||
|
null => false,
|
||||||
|
SinglePlayerCampaign spCampaign => this == spCampaign.Bank,
|
||||||
|
MultiPlayerCampaign mpCampaign => this == mpCampaign.PersonalWallet,
|
||||||
|
_ => false
|
||||||
|
};
|
||||||
|
|
||||||
|
partial void SettingsChanged(Option<int> balanceChanged, Option<int> rewardChanged)
|
||||||
|
{
|
||||||
|
CampaignMode campaign = GameMain.GameSession?.Campaign;
|
||||||
|
WalletChangedData data = new WalletChangedData
|
||||||
|
{
|
||||||
|
BalanceChanged = balanceChanged,
|
||||||
|
RewardDistributionChanged = rewardChanged,
|
||||||
|
};
|
||||||
|
|
||||||
|
campaign?.OnMoneyChanged.Invoke(new WalletChangedEvent(this, data, CreateWalletInfo()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,7 +14,7 @@ namespace Barotrauma
|
|||||||
protected bool crewDead;
|
protected bool crewDead;
|
||||||
|
|
||||||
protected Color overlayColor;
|
protected Color overlayColor;
|
||||||
protected string overlayText, overlayTextBottom;
|
protected LocalizedString overlayText, overlayTextBottom;
|
||||||
protected Color overlayTextColor;
|
protected Color overlayTextColor;
|
||||||
protected Sprite overlaySprite;
|
protected Sprite overlaySprite;
|
||||||
|
|
||||||
@@ -63,13 +63,19 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current personal wallet
|
||||||
|
/// In singleplayer this is the campaign bank and in multiplayer this is the personal wallet
|
||||||
|
/// </summary>
|
||||||
|
public virtual Wallet Wallet => GetWallet();
|
||||||
|
|
||||||
public override void ShowStartMessage()
|
public override void ShowStartMessage()
|
||||||
{
|
{
|
||||||
foreach (Mission mission in Missions.ToList())
|
foreach (Mission mission in Missions.ToList())
|
||||||
{
|
{
|
||||||
new GUIMessageBox(
|
new GUIMessageBox(
|
||||||
mission.Prefab.IsSideObjective ? TextManager.AddPunctuation(':', TextManager.Get("sideobjective"), mission.Name) : mission.Name,
|
RichString.Rich(mission.Prefab.IsSideObjective ? TextManager.AddPunctuation(':', TextManager.Get("sideobjective"), mission.Name) : mission.Name),
|
||||||
mission.Description, new string[0], type: GUIMessageBox.Type.InGame, icon: mission.Prefab.Icon, parseRichText: true)
|
RichString.Rich(mission.Description), Array.Empty<LocalizedString>(), type: GUIMessageBox.Type.InGame, icon: mission.Prefab.Icon)
|
||||||
{
|
{
|
||||||
IconColor = mission.Prefab.IconColor,
|
IconColor = mission.Prefab.IconColor,
|
||||||
UserData = "missionstartmessage"
|
UserData = "missionstartmessage"
|
||||||
@@ -80,30 +86,14 @@ namespace Barotrauma
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// There is a server-side implementation of the method in <see cref="MultiPlayerCampaign"/>
|
/// There is a server-side implementation of the method in <see cref="MultiPlayerCampaign"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool AllowedToEndRound()
|
public bool AllowedToManageCampaign(ClientPermissions permissions)
|
||||||
{
|
|
||||||
//allow ending the round if the client has permissions, is the owner, the only client in the server
|
|
||||||
//or if no-one has management permissions
|
|
||||||
if (GameMain.Client == null) { return true; }
|
|
||||||
return
|
|
||||||
GameMain.Client.HasPermission(ClientPermissions.ManageRound) ||
|
|
||||||
GameMain.Client.HasPermission(ClientPermissions.ManageCampaign) ||
|
|
||||||
GameMain.Client.ConnectedClients.Count == 1 ||
|
|
||||||
GameMain.Client.IsServerOwner ||
|
|
||||||
GameMain.Client.ConnectedClients.None(c =>
|
|
||||||
c.InGame && (c.IsOwner || c.HasPermission(ClientPermissions.ManageRound) || c.HasPermission(ClientPermissions.ManageCampaign)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// There is a server-side implementation of the method in <see cref="MultiPlayerCampaign"/>
|
|
||||||
/// </summary>
|
|
||||||
public bool AllowedToManageCampaign(ClientPermissions permissions = ClientPermissions.ManageCampaign)
|
|
||||||
{
|
{
|
||||||
//allow managing the round if the client has permissions, is the owner, the only client in the server,
|
//allow managing the round if the client has permissions, is the owner, the only client in the server,
|
||||||
//or if no-one has management permissions
|
//or if no-one has management permissions
|
||||||
if (GameMain.Client == null) { return true; }
|
if (GameMain.Client == null) { return true; }
|
||||||
return
|
return
|
||||||
GameMain.Client.HasPermission(permissions) ||
|
GameMain.Client.HasPermission(permissions) ||
|
||||||
|
GameMain.Client.HasPermission(ClientPermissions.ManageCampaign) ||
|
||||||
GameMain.Client.ConnectedClients.Count == 1 ||
|
GameMain.Client.ConnectedClients.Count == 1 ||
|
||||||
GameMain.Client.IsServerOwner ||
|
GameMain.Client.IsServerOwner ||
|
||||||
GameMain.Client.ConnectedClients.None(c => c.InGame && (c.IsOwner || c.HasPermission(permissions)));
|
GameMain.Client.ConnectedClients.None(c => c.InGame && (c.IsOwner || c.HasPermission(permissions)));
|
||||||
@@ -123,12 +113,12 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
GUI.DrawRectangle(spriteBatch, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), overlayColor, isFilled: true);
|
GUI.DrawRectangle(spriteBatch, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), overlayColor, isFilled: true);
|
||||||
}
|
}
|
||||||
if (!string.IsNullOrEmpty(overlayText) && overlayTextColor.A > 0)
|
if (!overlayText.IsNullOrEmpty() && overlayTextColor.A > 0)
|
||||||
{
|
{
|
||||||
var backgroundSprite = GUI.Style.GetComponentStyle("CommandBackground").GetDefaultSprite();
|
var backgroundSprite = GUIStyle.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);
|
LocalizedString wrappedText = ToolBox.WrapText(overlayText, GameMain.GraphicsWidth / 3, GUIStyle.Font);
|
||||||
Vector2 textSize = GUI.Font.MeasureString(wrappedText);
|
Vector2 textSize = GUIStyle.Font.MeasureString(wrappedText);
|
||||||
Vector2 textPos = centerPos - textSize / 2;
|
Vector2 textPos = centerPos - textSize / 2;
|
||||||
backgroundSprite.Draw(spriteBatch,
|
backgroundSprite.Draw(spriteBatch,
|
||||||
centerPos,
|
centerPos,
|
||||||
@@ -140,11 +130,11 @@ namespace Barotrauma
|
|||||||
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 (!overlayTextBottom.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
Vector2 bottomTextPos = centerPos + new Vector2(0.0f, textSize.Y / 2 + 40 * GUI.Scale) - GUI.Font.MeasureString(overlayTextBottom) / 2;
|
Vector2 bottomTextPos = centerPos + new Vector2(0.0f, textSize.Y / 2 + 40 * GUI.Scale) - GUIStyle.Font.MeasureString(overlayTextBottom) / 2;
|
||||||
GUI.DrawString(spriteBatch, bottomTextPos + Vector2.One, overlayTextBottom, Color.Black * (overlayTextColor.A / 255.0f));
|
GUI.DrawString(spriteBatch, bottomTextPos + Vector2.One, overlayTextBottom.Value, Color.Black * (overlayTextColor.A / 255.0f));
|
||||||
GUI.DrawString(spriteBatch, bottomTextPos, overlayTextBottom, overlayTextColor);
|
GUI.DrawString(spriteBatch, bottomTextPos, overlayTextBottom.Value, overlayTextColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -159,7 +149,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
endRoundButton.Visible = false;
|
endRoundButton.Visible = false;
|
||||||
var availableTransition = GetAvailableTransition(out _, out Submarine leavingSub);
|
var availableTransition = GetAvailableTransition(out _, out Submarine leavingSub);
|
||||||
string buttonText = "";
|
LocalizedString buttonText = "";
|
||||||
switch (availableTransition)
|
switch (availableTransition)
|
||||||
{
|
{
|
||||||
case TransitionType.ProgressToNextLocation:
|
case TransitionType.ProgressToNextLocation:
|
||||||
@@ -188,7 +178,7 @@ namespace Barotrauma
|
|||||||
case TransitionType.None:
|
case TransitionType.None:
|
||||||
default:
|
default:
|
||||||
if (Level.Loaded.Type == LevelData.LevelType.Outpost &&
|
if (Level.Loaded.Type == LevelData.LevelType.Outpost &&
|
||||||
(Character.Controlled?.Submarine?.Info.Type == SubmarineType.Player || (Character.Controlled?.CurrentHull?.OutpostModuleTags.Contains("airlock") ?? false)))
|
(Character.Controlled?.Submarine?.Info.Type == SubmarineType.Player || (Character.Controlled?.CurrentHull?.OutpostModuleTags.Contains("airlock".ToIdentifier()) ?? false)))
|
||||||
{
|
{
|
||||||
buttonText = TextManager.GetWithVariable("LeaveLocation", "[locationname]", Level.Loaded.StartLocation?.Name ?? "[ERROR]");
|
buttonText = TextManager.GetWithVariable("LeaveLocation", "[locationname]", Level.Loaded.StartLocation?.Name ?? "[ERROR]");
|
||||||
endRoundButton.Visible = !ForceMapUI && !ShowCampaignUI;
|
endRoundButton.Visible = !ForceMapUI && !ShowCampaignUI;
|
||||||
@@ -204,7 +194,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (endRoundButton.Visible)
|
if (endRoundButton.Visible)
|
||||||
{
|
{
|
||||||
if (!AllowedToEndRound())
|
if (!AllowedToManageCampaign(ClientPermissions.ManageMap))
|
||||||
{
|
{
|
||||||
buttonText = TextManager.Get("map");
|
buttonText = TextManager.Get("map");
|
||||||
}
|
}
|
||||||
@@ -218,7 +208,7 @@ namespace Barotrauma
|
|||||||
endRoundButton.OnClicked(EndRoundButton, null);
|
endRoundButton.OnClicked(EndRoundButton, null);
|
||||||
prevCampaignUIAutoOpenType = availableTransition;
|
prevCampaignUIAutoOpenType = availableTransition;
|
||||||
}
|
}
|
||||||
endRoundButton.Text = ToolBox.LimitString(buttonText, endRoundButton.Font, endRoundButton.Rect.Width - 5);
|
endRoundButton.Text = ToolBox.LimitString(buttonText.Value, endRoundButton.Font, endRoundButton.Rect.Width - 5);
|
||||||
if (endRoundButton.Text != buttonText)
|
if (endRoundButton.Text != buttonText)
|
||||||
{
|
{
|
||||||
endRoundButton.ToolTip = buttonText;
|
endRoundButton.ToolTip = buttonText;
|
||||||
@@ -244,7 +234,7 @@ namespace Barotrauma
|
|||||||
if (ReadyCheck.ReadyCheckCooldown > DateTime.Now)
|
if (ReadyCheck.ReadyCheckCooldown > DateTime.Now)
|
||||||
{
|
{
|
||||||
float progress = (ReadyCheck.ReadyCheckCooldown - DateTime.Now).Seconds / 60.0f;
|
float progress = (ReadyCheck.ReadyCheckCooldown - DateTime.Now).Seconds / 60.0f;
|
||||||
ReadyCheckButton.Color = ToolBox.GradientLerp(progress, Color.White, GUI.Style.Red);
|
ReadyCheckButton.Color = ToolBox.GradientLerp(progress, Color.White, GUIStyle.Red);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -289,7 +279,7 @@ namespace Barotrauma
|
|||||||
case InteractionType.Examine:
|
case InteractionType.Examine:
|
||||||
return;
|
return;
|
||||||
case InteractionType.Upgrade when !UpgradeManager.CanUpgradeSub():
|
case InteractionType.Upgrade when !UpgradeManager.CanUpgradeSub():
|
||||||
UpgradeManager.CreateUpgradeErrorMessage(TextManager.Get("Dialog.CantUpgrade"), IsSinglePlayer, npc);
|
UpgradeManager.CreateUpgradeErrorMessage(TextManager.Get("Dialog.CantUpgrade").Value, IsSinglePlayer, npc);
|
||||||
return;
|
return;
|
||||||
case InteractionType.Crew when GameMain.NetworkMember != null:
|
case InteractionType.Crew when GameMain.NetworkMember != null:
|
||||||
CampaignUI.CrewManagement.SendCrewState(false);
|
CampaignUI.CrewManagement.SendCrewState(false);
|
||||||
@@ -299,8 +289,8 @@ namespace Barotrauma
|
|||||||
goto default;
|
goto default;
|
||||||
default:
|
default:
|
||||||
ShowCampaignUI = true;
|
ShowCampaignUI = true;
|
||||||
CampaignUI.SelectTab(npc.CampaignInteractionType);
|
CampaignUI.SelectTab(npc.CampaignInteractionType, storeIdentifier: npc.MerchantIdentifier);
|
||||||
CampaignUI.UpgradeStore?.RefreshAll();
|
CampaignUI.UpgradeStore?.RequestRefresh();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -310,7 +300,7 @@ namespace Barotrauma
|
|||||||
if (ShowCampaignUI || ForceMapUI)
|
if (ShowCampaignUI || ForceMapUI)
|
||||||
{
|
{
|
||||||
campaignUIContainer?.AddToGUIUpdateList();
|
campaignUIContainer?.AddToGUIUpdateList();
|
||||||
if (CampaignUI?.UpgradeStore?.HoveredItem != null)
|
if (CampaignUI?.UpgradeStore?.HoveredEntity != null)
|
||||||
{
|
{
|
||||||
if (CampaignUI.SelectedTab != InteractionType.Upgrade) { return; }
|
if (CampaignUI.SelectedTab != InteractionType.Upgrade) { return; }
|
||||||
CampaignUI?.UpgradeStore?.ItemInfoFrame.AddToGUIUpdateList(order: 1);
|
CampaignUI?.UpgradeStore?.ItemInfoFrame.AddToGUIUpdateList(order: 1);
|
||||||
|
|||||||
+116
-100
@@ -34,7 +34,15 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void StartCampaignSetup(IEnumerable<string> saveFiles)
|
public Wallet PersonalWallet => Character.Controlled?.Wallet ?? Wallet.Invalid;
|
||||||
|
public override Wallet Wallet => GetWallet();
|
||||||
|
|
||||||
|
public override Wallet GetWallet(Client client = null)
|
||||||
|
{
|
||||||
|
return PersonalWallet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void StartCampaignSetup(List<SaveInfo> saveFiles)
|
||||||
{
|
{
|
||||||
var parent = GameMain.NetLobbyScreen.CampaignSetupFrame;
|
var parent = GameMain.NetLobbyScreen.CampaignSetupFrame;
|
||||||
parent.ClearChildren();
|
parent.ClearChildren();
|
||||||
@@ -195,6 +203,11 @@ namespace Barotrauma
|
|||||||
yield return CoroutineStatus.Running;
|
yield return CoroutineStatus.Running;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (GameMain.Client == null)
|
||||||
|
{
|
||||||
|
yield return CoroutineStatus.Failure;
|
||||||
|
}
|
||||||
|
|
||||||
if (GameMain.Client.LateCampaignJoin)
|
if (GameMain.Client.LateCampaignJoin)
|
||||||
{
|
{
|
||||||
GameMain.Client.LateCampaignJoin = false;
|
GameMain.Client.LateCampaignJoin = false;
|
||||||
@@ -217,8 +230,7 @@ namespace Barotrauma
|
|||||||
overlaySprite = Map.CurrentLocation.Type.GetPortrait(Map.CurrentLocation.PortraitId);
|
overlaySprite = Map.CurrentLocation.Type.GetPortrait(Map.CurrentLocation.PortraitId);
|
||||||
overlayTextColor = Color.Transparent;
|
overlayTextColor = Color.Transparent;
|
||||||
overlayText = TextManager.GetWithVariables("campaignstart",
|
overlayText = TextManager.GetWithVariables("campaignstart",
|
||||||
new string[] { "xxxx", "yyyy" },
|
("xxxx", Map.CurrentLocation.Name), ("yyyy", TextManager.Get($"submarineclass.{Submarine.MainSub.Info.SubmarineClass}")));
|
||||||
new string[] { Map.CurrentLocation.Name, TextManager.Get("submarineclass." + Submarine.MainSub.Info.SubmarineClass) });
|
|
||||||
float fadeInDuration = 1.0f;
|
float fadeInDuration = 1.0f;
|
||||||
float textDuration = 10.0f;
|
float textDuration = 10.0f;
|
||||||
float timer = 0.0f;
|
float timer = 0.0f;
|
||||||
@@ -317,7 +329,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private IEnumerable<CoroutineStatus> DoLevelTransition()
|
private IEnumerable<CoroutineStatus> DoLevelTransition()
|
||||||
{
|
{
|
||||||
SoundPlayer.OverrideMusicType = CrewManager.GetCharacters().Any(c => !c.IsDead) ? "endround" : "crewdead";
|
SoundPlayer.OverrideMusicType = (CrewManager.GetCharacters().Any(c => !c.IsDead) ? "endround" : "crewdead").ToIdentifier();
|
||||||
SoundPlayer.OverrideMusicDuration = 18.0f;
|
SoundPlayer.OverrideMusicDuration = 18.0f;
|
||||||
|
|
||||||
Level prevLevel = Level.Loaded;
|
Level prevLevel = Level.Loaded;
|
||||||
@@ -541,36 +553,10 @@ namespace Barotrauma
|
|||||||
msg.Write(PurchasedItemRepairs);
|
msg.Write(PurchasedItemRepairs);
|
||||||
msg.Write(PurchasedLostShuttles);
|
msg.Write(PurchasedLostShuttles);
|
||||||
|
|
||||||
msg.Write((UInt16)CargoManager.ItemsInBuyCrate.Count);
|
WriteItems(msg, CargoManager.ItemsInBuyCrate);
|
||||||
foreach (PurchasedItem pi in CargoManager.ItemsInBuyCrate)
|
WriteItems(msg, CargoManager.ItemsInSellFromSubCrate);
|
||||||
{
|
WriteItems(msg, CargoManager.PurchasedItems);
|
||||||
msg.Write(pi.ItemPrefab.Identifier);
|
WriteItems(msg, CargoManager.SoldItems);
|
||||||
msg.WriteRangedInteger(pi.Quantity, 0, CargoManager.MaxQuantity);
|
|
||||||
}
|
|
||||||
|
|
||||||
msg.Write((UInt16)CargoManager.ItemsInSellFromSubCrate.Count);
|
|
||||||
foreach (PurchasedItem pi in CargoManager.ItemsInSellFromSubCrate)
|
|
||||||
{
|
|
||||||
msg.Write(pi.ItemPrefab.Identifier);
|
|
||||||
msg.WriteRangedInteger(pi.Quantity, 0, CargoManager.MaxQuantity);
|
|
||||||
}
|
|
||||||
|
|
||||||
msg.Write((UInt16)CargoManager.PurchasedItems.Count);
|
|
||||||
foreach (PurchasedItem pi in CargoManager.PurchasedItems)
|
|
||||||
{
|
|
||||||
msg.Write(pi.ItemPrefab.Identifier);
|
|
||||||
msg.WriteRangedInteger(pi.Quantity, 0, CargoManager.MaxQuantity);
|
|
||||||
}
|
|
||||||
|
|
||||||
msg.Write((UInt16)CargoManager.SoldItems.Count);
|
|
||||||
foreach (SoldItem si in CargoManager.SoldItems)
|
|
||||||
{
|
|
||||||
msg.Write(si.ItemPrefab.Identifier);
|
|
||||||
msg.Write((UInt16)si.ID);
|
|
||||||
msg.Write(si.Removed);
|
|
||||||
msg.Write(si.SellerID);
|
|
||||||
msg.Write((byte)si.Origin);
|
|
||||||
}
|
|
||||||
|
|
||||||
msg.Write((ushort)UpgradeManager.PurchasedUpgrades.Count);
|
msg.Write((ushort)UpgradeManager.PurchasedUpgrades.Count);
|
||||||
foreach (var (prefab, category, level) in UpgradeManager.PurchasedUpgrades)
|
foreach (var (prefab, category, level) in UpgradeManager.PurchasedUpgrades)
|
||||||
@@ -584,7 +570,7 @@ namespace Barotrauma
|
|||||||
foreach (var itemSwap in UpgradeManager.PurchasedItemSwaps)
|
foreach (var itemSwap in UpgradeManager.PurchasedItemSwaps)
|
||||||
{
|
{
|
||||||
msg.Write(itemSwap.ItemToRemove.ID);
|
msg.Write(itemSwap.ItemToRemove.ID);
|
||||||
msg.Write(itemSwap.ItemToInstall?.Identifier ?? string.Empty);
|
msg.Write(itemSwap.ItemToInstall?.Identifier ?? Identifier.Empty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -606,85 +592,63 @@ namespace Barotrauma
|
|||||||
selectedMissionIndices.Add(msg.ReadByte());
|
selectedMissionIndices.Add(msg.ReadByte());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ushort ownedSubCount = msg.ReadUInt16();
|
||||||
|
List<ushort> ownedSubIndices = new List<ushort>();
|
||||||
|
for (int i = 0; i < ownedSubCount; i++)
|
||||||
|
{
|
||||||
|
ownedSubIndices.Add(msg.ReadUInt16());
|
||||||
|
}
|
||||||
|
|
||||||
bool allowDebugTeleport = msg.ReadBoolean();
|
bool allowDebugTeleport = msg.ReadBoolean();
|
||||||
float? reputation = null;
|
float? reputation = null;
|
||||||
if (msg.ReadBoolean()) { reputation = msg.ReadSingle(); }
|
if (msg.ReadBoolean()) { reputation = msg.ReadSingle(); }
|
||||||
|
|
||||||
Dictionary<string, float> factionReps = new Dictionary<string, float>();
|
Dictionary<Identifier, float> factionReps = new Dictionary<Identifier, float>();
|
||||||
byte factionsCount = msg.ReadByte();
|
byte factionsCount = msg.ReadByte();
|
||||||
for (int i = 0; i < factionsCount; i++)
|
for (int i = 0; i < factionsCount; i++)
|
||||||
{
|
{
|
||||||
factionReps.Add(msg.ReadString(), msg.ReadSingle());
|
factionReps.Add(msg.ReadIdentifier(), msg.ReadSingle());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool forceMapUI = msg.ReadBoolean();
|
bool forceMapUI = msg.ReadBoolean();
|
||||||
|
|
||||||
int money = msg.ReadInt32();
|
|
||||||
bool purchasedHullRepairs = msg.ReadBoolean();
|
bool purchasedHullRepairs = msg.ReadBoolean();
|
||||||
bool purchasedItemRepairs = msg.ReadBoolean();
|
bool purchasedItemRepairs = msg.ReadBoolean();
|
||||||
bool purchasedLostShuttles = msg.ReadBoolean();
|
bool purchasedLostShuttles = msg.ReadBoolean();
|
||||||
|
|
||||||
byte missionCount = msg.ReadByte();
|
byte missionCount = msg.ReadByte();
|
||||||
List<Pair<string, byte>> availableMissions = new List<Pair<string, byte>>();
|
var availableMissions = new List<(Identifier Identifier, byte ConnectionIndex)>();
|
||||||
for (int i = 0; i < missionCount; i++)
|
for (int i = 0; i < missionCount; i++)
|
||||||
{
|
{
|
||||||
string missionIdentifier = msg.ReadString();
|
Identifier missionIdentifier = msg.ReadIdentifier();
|
||||||
byte connectionIndex = msg.ReadByte();
|
byte connectionIndex = msg.ReadByte();
|
||||||
availableMissions.Add(new Pair<string, byte>(missionIdentifier, connectionIndex));
|
availableMissions.Add((missionIdentifier, connectionIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt16? storeBalance = null;
|
var storeBalances = new Dictionary<Identifier, UInt16>();
|
||||||
if (msg.ReadBoolean())
|
if (msg.ReadBoolean())
|
||||||
{
|
{
|
||||||
storeBalance = msg.ReadUInt16();
|
byte storeCount = msg.ReadByte();
|
||||||
|
for (int i = 0; i < storeCount; i++)
|
||||||
|
{
|
||||||
|
Identifier identifier = msg.ReadIdentifier();
|
||||||
|
UInt16 storeBalance = msg.ReadUInt16();
|
||||||
|
storeBalances.Add(identifier, storeBalance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt16 buyCrateItemCount = msg.ReadUInt16();
|
var buyCrateItems = ReadPurchasedItems(msg, sender: null);
|
||||||
List<PurchasedItem> buyCrateItems = new List<PurchasedItem>();
|
var subSellCrateItems = ReadPurchasedItems(msg, sender: null);
|
||||||
for (int i = 0; i < buyCrateItemCount; i++)
|
var purchasedItems = ReadPurchasedItems(msg, sender: null);
|
||||||
{
|
var soldItems = ReadSoldItems(msg);
|
||||||
string itemPrefabIdentifier = msg.ReadString();
|
|
||||||
int itemQuantity = msg.ReadRangedInteger(0, CargoManager.MaxQuantity);
|
|
||||||
buyCrateItems.Add(new PurchasedItem(ItemPrefab.Prefabs[itemPrefabIdentifier], itemQuantity));
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt16 subSellCrateItemCount = msg.ReadUInt16();
|
|
||||||
List<PurchasedItem> subSellCrateItems = new List<PurchasedItem>();
|
|
||||||
for (int i = 0; i < subSellCrateItemCount; i++)
|
|
||||||
{
|
|
||||||
string itemPrefabIdentifier = msg.ReadString();
|
|
||||||
int itemQuantity = msg.ReadRangedInteger(0, CargoManager.MaxQuantity);
|
|
||||||
subSellCrateItems.Add(new PurchasedItem(ItemPrefab.Prefabs[itemPrefabIdentifier], itemQuantity));
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt16 purchasedItemCount = msg.ReadUInt16();
|
|
||||||
List<PurchasedItem> purchasedItems = new List<PurchasedItem>();
|
|
||||||
for (int i = 0; i < purchasedItemCount; i++)
|
|
||||||
{
|
|
||||||
string itemPrefabIdentifier = msg.ReadString();
|
|
||||||
int itemQuantity = msg.ReadRangedInteger(0, CargoManager.MaxQuantity);
|
|
||||||
purchasedItems.Add(new PurchasedItem(ItemPrefab.Prefabs[itemPrefabIdentifier], itemQuantity));
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt16 soldItemCount = msg.ReadUInt16();
|
|
||||||
List<SoldItem> soldItems = new List<SoldItem>();
|
|
||||||
for (int i = 0; i < soldItemCount; i++)
|
|
||||||
{
|
|
||||||
string itemPrefabIdentifier = msg.ReadString();
|
|
||||||
UInt16 id = msg.ReadUInt16();
|
|
||||||
bool removed = msg.ReadBoolean();
|
|
||||||
byte sellerId = msg.ReadByte();
|
|
||||||
byte origin = msg.ReadByte();
|
|
||||||
soldItems.Add(new SoldItem(ItemPrefab.Prefabs[itemPrefabIdentifier], id, removed, sellerId, (SoldItem.SellOrigin)origin));
|
|
||||||
}
|
|
||||||
|
|
||||||
ushort pendingUpgradeCount = msg.ReadUInt16();
|
ushort pendingUpgradeCount = msg.ReadUInt16();
|
||||||
List<PurchasedUpgrade> pendingUpgrades = new List<PurchasedUpgrade>();
|
List<PurchasedUpgrade> pendingUpgrades = new List<PurchasedUpgrade>();
|
||||||
for (int i = 0; i < pendingUpgradeCount; i++)
|
for (int i = 0; i < pendingUpgradeCount; i++)
|
||||||
{
|
{
|
||||||
string upgradeIdentifier = msg.ReadString();
|
Identifier upgradeIdentifier = msg.ReadIdentifier();
|
||||||
UpgradePrefab prefab = UpgradePrefab.Find(upgradeIdentifier);
|
UpgradePrefab prefab = UpgradePrefab.Find(upgradeIdentifier);
|
||||||
string categoryIdentifier = msg.ReadString();
|
Identifier categoryIdentifier = msg.ReadIdentifier();
|
||||||
UpgradeCategory category = UpgradeCategory.Find(categoryIdentifier);
|
UpgradeCategory category = UpgradeCategory.Find(categoryIdentifier);
|
||||||
int upgradeLevel = msg.ReadByte();
|
int upgradeLevel = msg.ReadByte();
|
||||||
if (prefab == null || category == null) { continue; }
|
if (prefab == null || category == null) { continue; }
|
||||||
@@ -696,8 +660,8 @@ namespace Barotrauma
|
|||||||
for (int i = 0; i < purchasedItemSwapCount; i++)
|
for (int i = 0; i < purchasedItemSwapCount; i++)
|
||||||
{
|
{
|
||||||
UInt16 itemToRemoveID = msg.ReadUInt16();
|
UInt16 itemToRemoveID = msg.ReadUInt16();
|
||||||
string itemToInstallIdentifier = msg.ReadString();
|
Identifier itemToInstallIdentifier = msg.ReadIdentifier();
|
||||||
ItemPrefab itemToInstall = string.IsNullOrEmpty(itemToInstallIdentifier) ? null : ItemPrefab.Find(string.Empty, itemToInstallIdentifier);
|
ItemPrefab itemToInstall = itemToInstallIdentifier.IsEmpty ? null : ItemPrefab.Find(string.Empty, itemToInstallIdentifier);
|
||||||
if (!(Entity.FindEntityByID(itemToRemoveID) is Item itemToRemove)) { continue; }
|
if (!(Entity.FindEntityByID(itemToRemoveID) is Item itemToRemove)) { continue; }
|
||||||
purchasedItemSwaps.Add(new PurchasedItemSwap(itemToRemove, itemToInstall));
|
purchasedItemSwaps.Add(new PurchasedItemSwap(itemToRemove, itemToInstall));
|
||||||
}
|
}
|
||||||
@@ -740,12 +704,29 @@ namespace Barotrauma
|
|||||||
campaign.Map.SetLocation(currentLocIndex == UInt16.MaxValue ? -1 : currentLocIndex);
|
campaign.Map.SetLocation(currentLocIndex == UInt16.MaxValue ? -1 : currentLocIndex);
|
||||||
campaign.Map.SelectLocation(selectedLocIndex == UInt16.MaxValue ? -1 : selectedLocIndex);
|
campaign.Map.SelectLocation(selectedLocIndex == UInt16.MaxValue ? -1 : selectedLocIndex);
|
||||||
campaign.Map.SelectMission(selectedMissionIndices);
|
campaign.Map.SelectMission(selectedMissionIndices);
|
||||||
|
|
||||||
|
GameMain.GameSession.OwnedSubmarines.Clear();
|
||||||
|
foreach (int ownedSubIndex in ownedSubIndices)
|
||||||
|
{
|
||||||
|
SubmarineInfo sub = GameMain.Client.ServerSubmarines[ownedSubIndex];
|
||||||
|
if (GameMain.NetLobbyScreen.CheckIfCampaignSubMatches(sub, NetLobbyScreen.SubmarineDeliveryData.Owned))
|
||||||
|
{
|
||||||
|
GameMain.GameSession.OwnedSubmarines.Add(sub);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
campaign.Map.AllowDebugTeleport = allowDebugTeleport;
|
campaign.Map.AllowDebugTeleport = allowDebugTeleport;
|
||||||
campaign.CargoManager.SetItemsInBuyCrate(buyCrateItems);
|
campaign.CargoManager.SetItemsInBuyCrate(buyCrateItems);
|
||||||
campaign.CargoManager.SetItemsInSubSellCrate(subSellCrateItems);
|
campaign.CargoManager.SetItemsInSubSellCrate(subSellCrateItems);
|
||||||
campaign.CargoManager.SetPurchasedItems(purchasedItems);
|
campaign.CargoManager.SetPurchasedItems(purchasedItems);
|
||||||
campaign.CargoManager.SetSoldItems(soldItems);
|
campaign.CargoManager.SetSoldItems(soldItems);
|
||||||
if (storeBalance.HasValue) { campaign.Map.CurrentLocation.StoreCurrentBalance = storeBalance.Value; }
|
foreach (var balance in storeBalances)
|
||||||
|
{
|
||||||
|
if (campaign.Map.CurrentLocation.GetStore(balance.Key) is { } store)
|
||||||
|
{
|
||||||
|
store.Balance = balance.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
campaign.UpgradeManager.SetPendingUpgrades(pendingUpgrades);
|
campaign.UpgradeManager.SetPendingUpgrades(pendingUpgrades);
|
||||||
campaign.UpgradeManager.PurchasedUpgrades.Clear();
|
campaign.UpgradeManager.PurchasedUpgrades.Clear();
|
||||||
foreach (var purchasedItemSwap in purchasedItemSwaps)
|
foreach (var purchasedItemSwap in purchasedItemSwaps)
|
||||||
@@ -769,7 +750,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
foreach (var (identifier, rep) in factionReps)
|
foreach (var (identifier, rep) in factionReps)
|
||||||
{
|
{
|
||||||
Faction faction = campaign.Factions.FirstOrDefault(f => f.Prefab.Identifier.Equals(identifier, StringComparison.OrdinalIgnoreCase));
|
Faction faction = campaign.Factions.FirstOrDefault(f => f.Prefab.Identifier == identifier);
|
||||||
if (faction?.Reputation != null)
|
if (faction?.Reputation != null)
|
||||||
{
|
{
|
||||||
faction.Reputation.SetReputation(rep);
|
faction.Reputation.SetReputation(rep);
|
||||||
@@ -783,29 +764,29 @@ namespace Barotrauma
|
|||||||
if (reputation.HasValue)
|
if (reputation.HasValue)
|
||||||
{
|
{
|
||||||
campaign.Map.CurrentLocation.Reputation.SetReputation(reputation.Value);
|
campaign.Map.CurrentLocation.Reputation.SetReputation(reputation.Value);
|
||||||
campaign?.CampaignUI?.UpgradeStore?.RefreshAll();
|
campaign?.CampaignUI?.UpgradeStore?.RequestRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var availableMission in availableMissions)
|
foreach (var availableMission in availableMissions)
|
||||||
{
|
{
|
||||||
MissionPrefab missionPrefab = MissionPrefab.List.Find(mp => mp.Identifier == availableMission.First);
|
MissionPrefab missionPrefab = MissionPrefab.Prefabs.Find(mp => mp.Identifier == availableMission.Identifier);
|
||||||
if (missionPrefab == null)
|
if (missionPrefab == null)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError($"Error when receiving campaign data from the server: mission prefab \"{availableMission.First}\" not found.");
|
DebugConsole.ThrowError($"Error when receiving campaign data from the server: mission prefab \"{availableMission.Identifier}\" not found.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (availableMission.Second == 255)
|
if (availableMission.ConnectionIndex == 255)
|
||||||
{
|
{
|
||||||
campaign.Map.CurrentLocation.UnlockMission(missionPrefab);
|
campaign.Map.CurrentLocation.UnlockMission(missionPrefab);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (availableMission.Second < 0 || availableMission.Second >= campaign.Map.CurrentLocation.Connections.Count)
|
if (availableMission.ConnectionIndex < 0 || availableMission.ConnectionIndex >= campaign.Map.CurrentLocation.Connections.Count)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError($"Error when receiving campaign data from the server: connection index for mission \"{availableMission.First}\" out of range (index: {availableMission.Second}, current location: {campaign.Map.CurrentLocation.Name}, connections: {campaign.Map.CurrentLocation.Connections.Count}).");
|
DebugConsole.ThrowError($"Error when receiving campaign data from the server: connection index for mission \"{availableMission.Identifier}\" out of range (index: {availableMission.ConnectionIndex}, current location: {campaign.Map.CurrentLocation.Name}, connections: {campaign.Map.CurrentLocation.Connections.Count}).");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
LocationConnection connection = campaign.Map.CurrentLocation.Connections[availableMission.Second];
|
LocationConnection connection = campaign.Map.CurrentLocation.Connections[availableMission.ConnectionIndex];
|
||||||
campaign.Map.CurrentLocation.UnlockMission(missionPrefab, connection);
|
campaign.Map.CurrentLocation.UnlockMission(missionPrefab, connection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -813,19 +794,17 @@ namespace Barotrauma
|
|||||||
GameMain.NetLobbyScreen.ToggleCampaignMode(true);
|
GameMain.NetLobbyScreen.ToggleCampaignMode(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shouldRefresh = campaign.Money != money ||
|
bool shouldRefresh = campaign.PurchasedHullRepairs != purchasedHullRepairs ||
|
||||||
campaign.PurchasedHullRepairs != purchasedHullRepairs ||
|
|
||||||
campaign.PurchasedItemRepairs != purchasedItemRepairs ||
|
campaign.PurchasedItemRepairs != purchasedItemRepairs ||
|
||||||
campaign.PurchasedLostShuttles != purchasedLostShuttles;
|
campaign.PurchasedLostShuttles != purchasedLostShuttles;
|
||||||
|
|
||||||
campaign.Money = money;
|
|
||||||
campaign.PurchasedHullRepairs = purchasedHullRepairs;
|
campaign.PurchasedHullRepairs = purchasedHullRepairs;
|
||||||
campaign.PurchasedItemRepairs = purchasedItemRepairs;
|
campaign.PurchasedItemRepairs = purchasedItemRepairs;
|
||||||
campaign.PurchasedLostShuttles = purchasedLostShuttles;
|
campaign.PurchasedLostShuttles = purchasedLostShuttles;
|
||||||
|
|
||||||
if (shouldRefresh)
|
if (shouldRefresh)
|
||||||
{
|
{
|
||||||
campaign?.CampaignUI?.UpgradeStore?.RefreshAll();
|
campaign?.CampaignUI?.UpgradeStore?.RequestRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (myCharacterInfo != null)
|
if (myCharacterInfo != null)
|
||||||
@@ -849,7 +828,7 @@ namespace Barotrauma
|
|||||||
List<CharacterInfo> availableHires = new List<CharacterInfo>();
|
List<CharacterInfo> availableHires = new List<CharacterInfo>();
|
||||||
for (int i = 0; i < availableHireLength; i++)
|
for (int i = 0; i < availableHireLength; i++)
|
||||||
{
|
{
|
||||||
CharacterInfo hire = CharacterInfo.ClientRead("human", msg);
|
CharacterInfo hire = CharacterInfo.ClientRead(CharacterPrefab.HumanSpeciesName, msg);
|
||||||
hire.Salary = msg.ReadInt32();
|
hire.Salary = msg.ReadInt32();
|
||||||
availableHires.Add(hire);
|
availableHires.Add(hire);
|
||||||
}
|
}
|
||||||
@@ -865,7 +844,7 @@ namespace Barotrauma
|
|||||||
List<CharacterInfo> hiredCharacters = new List<CharacterInfo>();
|
List<CharacterInfo> hiredCharacters = new List<CharacterInfo>();
|
||||||
for (int i = 0; i < hiredLength; i++)
|
for (int i = 0; i < hiredLength; i++)
|
||||||
{
|
{
|
||||||
CharacterInfo hired = CharacterInfo.ClientRead("human", msg);
|
CharacterInfo hired = CharacterInfo.ClientRead(CharacterPrefab.HumanSpeciesName, msg);
|
||||||
hired.Salary = msg.ReadInt32();
|
hired.Salary = msg.ReadInt32();
|
||||||
hiredCharacters.Add(hired);
|
hiredCharacters.Add(hired);
|
||||||
}
|
}
|
||||||
@@ -897,6 +876,43 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ClientReadMoney(IReadMessage inc)
|
||||||
|
{
|
||||||
|
NetWalletUpdate update = INetSerializableStruct.Read<NetWalletUpdate>(inc);
|
||||||
|
foreach (NetWalletTransaction transaction in update.Transactions)
|
||||||
|
{
|
||||||
|
WalletInfo info = transaction.Info;
|
||||||
|
switch (transaction.CharacterID)
|
||||||
|
{
|
||||||
|
case Some<ushort> { Value: var charID }:
|
||||||
|
{
|
||||||
|
Character targetCharacter = Character.CharacterList?.FirstOrDefault(c => c.ID == charID);
|
||||||
|
if (targetCharacter is null) { break; }
|
||||||
|
Wallet wallet = targetCharacter.Wallet;
|
||||||
|
|
||||||
|
wallet.Balance = info.Balance;
|
||||||
|
wallet.RewardDistribution = info.RewardDistribution;
|
||||||
|
TryInvokeEvent(wallet, transaction.ChangedData, info);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case None<ushort> _:
|
||||||
|
{
|
||||||
|
Bank.Balance = info.Balance;
|
||||||
|
TryInvokeEvent(Bank, transaction.ChangedData, info);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TryInvokeEvent(Wallet wallet, WalletChangedData data, WalletInfo info)
|
||||||
|
{
|
||||||
|
if (data.BalanceChanged.IsSome() || data.RewardDistributionChanged.IsSome())
|
||||||
|
{
|
||||||
|
OnMoneyChanged.Invoke(new WalletChangedEvent(wallet, data, info));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void Save(XElement element)
|
public override void Save(XElement element)
|
||||||
{
|
{
|
||||||
//do nothing, the clients get the save files from the server
|
//do nothing, the clients get the save files from the server
|
||||||
|
|||||||
+23
-10
@@ -6,6 +6,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
using Barotrauma.Networking;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -68,7 +69,7 @@ namespace Barotrauma
|
|||||||
for (int i = 0; i < jobPrefab.InitialCount; i++)
|
for (int i = 0; i < jobPrefab.InitialCount; i++)
|
||||||
{
|
{
|
||||||
var variant = Rand.Range(0, jobPrefab.Variants);
|
var variant = Rand.Range(0, jobPrefab.Variants);
|
||||||
CrewManager.AddCharacterInfo(new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: jobPrefab, variant: variant));
|
CrewManager.AddCharacterInfo(new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobOrJobPrefab: jobPrefab, variant: variant));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InitCampaignData();
|
InitCampaignData();
|
||||||
@@ -82,7 +83,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
IsFirstRound = false;
|
IsFirstRound = false;
|
||||||
|
|
||||||
foreach (XElement subElement in element.Elements())
|
foreach (var subElement in element.Elements())
|
||||||
{
|
{
|
||||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||||
{
|
{
|
||||||
@@ -108,6 +109,9 @@ namespace Barotrauma
|
|||||||
case "pets":
|
case "pets":
|
||||||
petsElement = subElement;
|
petsElement = subElement;
|
||||||
break;
|
break;
|
||||||
|
case Wallet.LowerCaseSaveElementName:
|
||||||
|
Bank = new Wallet(Option<Character>.None(), subElement);
|
||||||
|
break;
|
||||||
case "stats":
|
case "stats":
|
||||||
LoadStats(subElement);
|
LoadStats(subElement);
|
||||||
break;
|
break;
|
||||||
@@ -121,7 +125,16 @@ namespace Barotrauma
|
|||||||
|
|
||||||
InitUI();
|
InitUI();
|
||||||
|
|
||||||
Money = element.GetAttributeInt("money", 0);
|
//backwards compatibility for saves made prior to the addition of personal wallets
|
||||||
|
int oldMoney = element.GetAttributeInt("money", 0);
|
||||||
|
if (oldMoney > 0)
|
||||||
|
{
|
||||||
|
Bank = new Wallet(Option<Character>.None())
|
||||||
|
{
|
||||||
|
Balance = oldMoney
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
PurchasedLostShuttles = element.GetAttributeBool("purchasedlostshuttles", false);
|
PurchasedLostShuttles = element.GetAttributeBool("purchasedlostshuttles", false);
|
||||||
PurchasedHullRepairs = element.GetAttributeBool("purchasedhullrepairs", false);
|
PurchasedHullRepairs = element.GetAttributeBool("purchasedhullrepairs", false);
|
||||||
PurchasedItemRepairs = element.GetAttributeBool("purchaseditemrepairs", false);
|
PurchasedItemRepairs = element.GetAttributeBool("purchaseditemrepairs", false);
|
||||||
@@ -283,9 +296,9 @@ namespace Barotrauma
|
|||||||
overlaySprite = Map.CurrentLocation.Type.GetPortrait(Map.CurrentLocation.PortraitId);
|
overlaySprite = Map.CurrentLocation.Type.GetPortrait(Map.CurrentLocation.PortraitId);
|
||||||
overlayTextColor = Color.Transparent;
|
overlayTextColor = Color.Transparent;
|
||||||
overlayText = TextManager.GetWithVariables(showCampaignResetText ? "campaignend4" : "campaignstart",
|
overlayText = TextManager.GetWithVariables(showCampaignResetText ? "campaignend4" : "campaignstart",
|
||||||
new string[] { "xxxx", "yyyy" },
|
("xxxx", Map.CurrentLocation.Name),
|
||||||
new string[] { Map.CurrentLocation.Name, TextManager.Get("submarineclass." + Submarine.MainSub.Info.SubmarineClass) });
|
("yyyy", TextManager.Get("submarineclass." + Submarine.MainSub.Info.SubmarineClass)));
|
||||||
string pressAnyKeyText = TextManager.Get("pressanykey");
|
LocalizedString pressAnyKeyText = TextManager.Get("pressanykey");
|
||||||
float fadeInDuration = 2.0f;
|
float fadeInDuration = 2.0f;
|
||||||
float textDuration = 10.0f;
|
float textDuration = 10.0f;
|
||||||
float timer = 0.0f;
|
float timer = 0.0f;
|
||||||
@@ -385,7 +398,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
NextLevel = newLevel;
|
NextLevel = newLevel;
|
||||||
bool success = CrewManager.GetCharacters().Any(c => !c.IsDead);
|
bool success = CrewManager.GetCharacters().Any(c => !c.IsDead);
|
||||||
SoundPlayer.OverrideMusicType = success ? "endround" : "crewdead";
|
SoundPlayer.OverrideMusicType = (success ? "endround" : "crewdead").ToIdentifier();
|
||||||
SoundPlayer.OverrideMusicDuration = 18.0f;
|
SoundPlayer.OverrideMusicDuration = 18.0f;
|
||||||
GUI.SetSavingIndicatorState(success);
|
GUI.SetSavingIndicatorState(success);
|
||||||
crewDead = false;
|
crewDead = false;
|
||||||
@@ -672,9 +685,9 @@ namespace Barotrauma
|
|||||||
var subsToLeaveBehind = GetSubsToLeaveBehind(leavingSub);
|
var subsToLeaveBehind = GetSubsToLeaveBehind(leavingSub);
|
||||||
if (subsToLeaveBehind.Any())
|
if (subsToLeaveBehind.Any())
|
||||||
{
|
{
|
||||||
string msg = TextManager.Get(subsToLeaveBehind.Count == 1 ? "LeaveSubBehind" : "LeaveSubsBehind");
|
LocalizedString msg = TextManager.Get(subsToLeaveBehind.Count == 1 ? "LeaveSubBehind" : "LeaveSubsBehind");
|
||||||
|
|
||||||
var msgBox = new GUIMessageBox(TextManager.Get("Warning"), msg, new string[] { TextManager.Get("Yes"), TextManager.Get("No") });
|
var msgBox = new GUIMessageBox(TextManager.Get("Warning"), msg, new LocalizedString[] { TextManager.Get("Yes"), TextManager.Get("No") });
|
||||||
msgBox.Buttons[0].OnClicked += (btn, userdata) => { LoadNewLevel(); return true; } ;
|
msgBox.Buttons[0].OnClicked += (btn, userdata) => { LoadNewLevel(); return true; } ;
|
||||||
msgBox.Buttons[0].OnClicked += msgBox.Close;
|
msgBox.Buttons[0].OnClicked += msgBox.Close;
|
||||||
msgBox.Buttons[0].UserData = Submarine.Loaded.FindAll(s => !subsToLeaveBehind.Contains(s));
|
msgBox.Buttons[0].UserData = Submarine.Loaded.FindAll(s => !subsToLeaveBehind.Contains(s));
|
||||||
@@ -729,7 +742,6 @@ namespace Barotrauma
|
|||||||
public override void Save(XElement element)
|
public override void Save(XElement element)
|
||||||
{
|
{
|
||||||
XElement modeElement = new XElement("SinglePlayerCampaign",
|
XElement modeElement = new XElement("SinglePlayerCampaign",
|
||||||
new XAttribute("money", Money),
|
|
||||||
new XAttribute("purchasedlostshuttles", PurchasedLostShuttles),
|
new XAttribute("purchasedlostshuttles", PurchasedLostShuttles),
|
||||||
new XAttribute("purchasedhullrepairs", PurchasedHullRepairs),
|
new XAttribute("purchasedhullrepairs", PurchasedHullRepairs),
|
||||||
new XAttribute("purchaseditemrepairs", PurchasedItemRepairs),
|
new XAttribute("purchaseditemrepairs", PurchasedItemRepairs),
|
||||||
@@ -763,6 +775,7 @@ namespace Barotrauma
|
|||||||
Map.Save(modeElement);
|
Map.Save(modeElement);
|
||||||
CargoManager?.SavePurchasedItems(modeElement);
|
CargoManager?.SavePurchasedItems(modeElement);
|
||||||
UpgradeManager?.Save(modeElement);
|
UpgradeManager?.Save(modeElement);
|
||||||
|
modeElement.Add(Bank.Save());
|
||||||
element.Add(modeElement);
|
element.Add(modeElement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,12 +24,12 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public TestGameMode(GameModePreset preset) : base(preset)
|
public TestGameMode(GameModePreset preset) : base(preset)
|
||||||
{
|
{
|
||||||
foreach (JobPrefab jobPrefab in JobPrefab.Prefabs)
|
foreach (JobPrefab jobPrefab in JobPrefab.Prefabs.OrderBy(p => p.Identifier))
|
||||||
{
|
{
|
||||||
for (int i = 0; i < jobPrefab.InitialCount; i++)
|
for (int i = 0; i < jobPrefab.InitialCount; i++)
|
||||||
{
|
{
|
||||||
var variant = Rand.Range(0, jobPrefab.Variants);
|
var variant = Rand.Range(0, jobPrefab.Variants);
|
||||||
CrewManager.AddCharacterInfo(new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: jobPrefab, variant: variant));
|
CrewManager.AddCharacterInfo(new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobOrJobPrefab: jobPrefab, variant: variant));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -93,7 +93,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void GenerateOutpost(Submarine submarine)
|
private void GenerateOutpost(Submarine submarine)
|
||||||
{
|
{
|
||||||
Submarine outpost = OutpostGenerator.Generate(OutpostParams ?? OutpostGenerationParams.Params.GetRandom(), OutpostType ?? LocationType.List.GetRandom());
|
Submarine outpost = OutpostGenerator.Generate(OutpostParams ?? OutpostGenerationParams.OutpostParams.GetRandomUnsynced(), OutpostType ?? LocationType.Prefabs.GetRandomUnsynced());
|
||||||
outpost.SetPosition(Vector2.Zero);
|
outpost.SetPosition(Vector2.Zero);
|
||||||
|
|
||||||
float closestDistance = 0.0f;
|
float closestDistance = 0.0f;
|
||||||
@@ -131,7 +131,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (Character.Controlled != null)
|
if (Character.Controlled != null)
|
||||||
{
|
{
|
||||||
Character.Controlled.TeleportTo(outpost.GetWaypoints(false).GetRandom(point => point.SpawnType == SpawnType.Human).WorldPosition);
|
Character.Controlled.TeleportTo(outpost.GetWaypoints(false).GetRandomUnsynced(point => point.SpawnType == SpawnType.Human).WorldPosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
-683
@@ -1,683 +0,0 @@
|
|||||||
using Barotrauma.Items.Components;
|
|
||||||
using FarseerPhysics;
|
|
||||||
using Microsoft.Xna.Framework;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Xml.Linq;
|
|
||||||
|
|
||||||
namespace Barotrauma.Tutorials
|
|
||||||
{
|
|
||||||
class BasicTutorial : ScenarioTutorial
|
|
||||||
{
|
|
||||||
public BasicTutorial(XElement element)
|
|
||||||
: base(element)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override IEnumerable<CoroutineStatus> UpdateState()
|
|
||||||
{
|
|
||||||
Character Controlled = Character.Controlled;
|
|
||||||
if (Controlled == null) yield return CoroutineStatus.Success;
|
|
||||||
|
|
||||||
foreach (Item item in Item.ItemList)
|
|
||||||
{
|
|
||||||
var wire = item.GetComponent<Wire>();
|
|
||||||
if (wire != null && wire.Connections.Any(c => c != null))
|
|
||||||
{
|
|
||||||
wire.Locked = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//remove all characters except the controlled one to prevent any unintended monster attacks
|
|
||||||
var existingCharacters = Character.CharacterList.FindAll(c => c != Controlled);
|
|
||||||
foreach (Character c in existingCharacters)
|
|
||||||
{
|
|
||||||
c.Remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
yield return new WaitForSeconds(4.0f);
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "Use WASD to move and the mouse to look around");
|
|
||||||
|
|
||||||
yield return new WaitForSeconds(5.0f);
|
|
||||||
|
|
||||||
//-----------------------------------
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "Open the door at your right side by highlighting the button next to it with your cursor and pressing E");
|
|
||||||
|
|
||||||
Door tutorialDoor = Item.ItemList.Find(i => i.HasTag("tutorialdoor")).GetComponent<Door>();
|
|
||||||
|
|
||||||
while (!tutorialDoor.IsOpen && Controlled.WorldPosition.X < tutorialDoor.Item.WorldPosition.X)
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
yield return new WaitForSeconds(2.0f);
|
|
||||||
|
|
||||||
//-----------------------------------
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "Hold W or S to walk up or down stairs. Use shift to run.", hasButton: true);
|
|
||||||
|
|
||||||
while (infoBox != null)
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "At the moment the submarine has no power, which means that crucial systems such as the oxygen generator or the engine aren't running. Let's fix this: go to the upper left corner of the submarine, where you'll find a nuclear reactor.");
|
|
||||||
|
|
||||||
Reactor reactor = Item.ItemList.Find(i => i.HasTag("tutorialreactor")).GetComponent<Reactor>();
|
|
||||||
//reactor.MeltDownTemp = 20000.0f;
|
|
||||||
|
|
||||||
while (Vector2.Distance(Controlled.Position, reactor.Item.Position) > 200.0f)
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "The reactor requires fuel rods to generate power. You can grab one from the steel cabinet by walking next to it and pressing E.");
|
|
||||||
|
|
||||||
while (Controlled.SelectedConstruction == null || Controlled.SelectedConstruction.Prefab.Identifier != "steelcabinet")
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "Pick up one of the fuel rods either by double-clicking or dragging and dropping it into your inventory.");
|
|
||||||
|
|
||||||
while (!HasItem("fuelrod"))
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "Select the reactor by walking next to it and pressing E.");
|
|
||||||
|
|
||||||
while (Controlled.SelectedConstruction != reactor.Item)
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
yield return new WaitForSeconds(0.5f);
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "Load the fuel rod into the reactor by dropping it into any of the 5 slots.");
|
|
||||||
|
|
||||||
while (reactor.AvailableFuel <= 0.0f)
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "The reactor is now fueled up. Try turning it on by increasing the fission rate.");
|
|
||||||
|
|
||||||
while (reactor.FissionRate <= 0.0f)
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
yield return new WaitForSeconds(0.5f);
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "The reactor core has started generating heat, which in turn generates power for the submarine. The power generation is very low at the moment,"
|
|
||||||
+ " because the reactor is set to shut itself down when the temperature rises above 500 degrees Celsius. You can adjust the temperature limit by changing the \"Shutdown Temperature\" in the control panel.", hasButton: true);
|
|
||||||
|
|
||||||
//TODO: reimplement
|
|
||||||
/*while (infoBox != null)
|
|
||||||
{
|
|
||||||
reactor.ShutDownTemp = Math.Min(reactor.ShutDownTemp, 5000.0f);
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
yield return new WaitForSeconds(0.5f);
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("The amount of power generated by the reactor should be kept close to the amount of power consumed by the devices in the submarine. "
|
|
||||||
+ "If there isn't enough power, devices won't function properly (or at all), and if there's too much power, some devices may be damaged."
|
|
||||||
+ " Try to raise the temperature of the reactor close to 3000 degrees by adjusting the fission and cooling rates.", true);
|
|
||||||
|
|
||||||
while (Math.Abs(reactor.Temperature - 3000.0f) > 100.0f)
|
|
||||||
{
|
|
||||||
reactor.AutoTemp = false;
|
|
||||||
reactor.ShutDownTemp = Math.Min(reactor.ShutDownTemp, 5000.0f);
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
yield return new WaitForSeconds(0.5f);
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("Looks like we're up and running! Now you should turn on the \"Automatic temperature control\", which will make the reactor "
|
|
||||||
+ "automatically adjust the temperature to a suitable level. Even though it's an easy way to keep the reactor up and running most of the time, "
|
|
||||||
+ "you should keep in mind that it changes the temperature very slowly and carefully, which may cause issues if there are sudden changes in grid load.");
|
|
||||||
|
|
||||||
while (!reactor.AutoTemp)
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}*/
|
|
||||||
yield return new WaitForSeconds(0.5f);
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "That's the basics of operating the reactor! Now that there's power available for the engines, it's time to get the submarine moving. "
|
|
||||||
+ "Deselect the reactor by pressing E and head to the command room at the right edge of the vessel.");
|
|
||||||
|
|
||||||
Steering steering = Item.ItemList.Find(i => i.HasTag("tutorialsteering")).GetComponent<Steering>();
|
|
||||||
Sonar sonar = steering.Item.GetComponent<Sonar>();
|
|
||||||
|
|
||||||
while (Vector2.Distance(Controlled.Position, steering.Item.Position) > 150.0f)
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
CoroutineManager.StartCoroutine(KeepReactorRunning(reactor));
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "Select the navigation terminal by walking next to it and pressing E.");
|
|
||||||
|
|
||||||
while (Controlled.SelectedConstruction != steering.Item)
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
yield return new WaitForSeconds(0.5f);
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "There seems to be something wrong with the navigation terminal." +
|
|
||||||
" There's nothing on the monitor, so it's probably out of power. The reactor must still be"
|
|
||||||
+ " running or the lights would've gone out, so it's most likely a problem with the wiring."
|
|
||||||
+ " Deselect the terminal by pressing E to start checking the wiring.");
|
|
||||||
|
|
||||||
while (Controlled.SelectedConstruction == steering.Item)
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
yield return new WaitForSeconds(1.0f);
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "You need a screwdriver to check the wiring of the terminal."
|
|
||||||
+ " Equip a screwdriver by pulling it to either of the slots with a hand symbol, and then use it on the terminal by left clicking.");
|
|
||||||
|
|
||||||
while (Controlled.SelectedConstruction != steering.Item ||
|
|
||||||
Controlled.HeldItems.FirstOrDefault(i => i.Prefab.Identifier == "screwdriver") == null)
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "Here you can see all the wires connected to the terminal. Apparently there's no wire"
|
|
||||||
+ " going into the to the power connection - that's why the monitor isn't working."
|
|
||||||
+ " You should find a piece of wire to connect it. Try searching some of the cabinets scattered around the sub.");
|
|
||||||
|
|
||||||
while (!HasItem("wire"))
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "Head back to the navigation terminal to fix the wiring.");
|
|
||||||
|
|
||||||
PowerTransfer junctionBox = Item.ItemList.Find(i => i != null && i.HasTag("tutorialjunctionbox")).GetComponent<PowerTransfer>();
|
|
||||||
|
|
||||||
while ((Controlled.SelectedConstruction != junctionBox.Item &&
|
|
||||||
Controlled.SelectedConstruction != steering.Item) ||
|
|
||||||
!Controlled.HeldItems.Any(i => i.Prefab.Identifier == "screwdriver"))
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Controlled.HeldItems.Any(i => i.GetComponent<Wire>() != null))
|
|
||||||
{
|
|
||||||
infoBox = CreateInfoFrame("", "Equip the wire by dragging it to one of the slots with a hand symbol.");
|
|
||||||
|
|
||||||
while (!Controlled.HeldItems.Any(i => i.GetComponent<Wire>() != null))
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "You can see the equipped wire at the middle of the connection panel. Drag it to the power connector.");
|
|
||||||
|
|
||||||
var steeringConnection = steering.Item.Connections.Find(c => c.Name.Contains("power"));
|
|
||||||
|
|
||||||
while (steeringConnection.Wires.FirstOrDefault(w => w != null) == null)
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "Now you have to connect the other end of the wire to a power source. "
|
|
||||||
+ "The junction box in the room just below the command room should do.");
|
|
||||||
|
|
||||||
while (Controlled.SelectedConstruction != null)
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
yield return new WaitForSeconds(2.0f);
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "You can now move the other end of the wire around, and attach it on the wall by left clicking or "
|
|
||||||
+ "remove the previous attachment by right clicking. Or if you don't care for neatly laid out wiring, you can just "
|
|
||||||
+ "run it straight to the junction box.");
|
|
||||||
|
|
||||||
while (Controlled.SelectedConstruction == null || Controlled.SelectedConstruction.GetComponent<PowerTransfer>() == null)
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "Connect the wire to the junction box by pulling it to the power connection, the same way you did with the navigation terminal.");
|
|
||||||
|
|
||||||
while (sonar.Voltage < 0.1f)
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "Great! Now we should be able to get moving.");
|
|
||||||
|
|
||||||
|
|
||||||
while (Controlled.SelectedConstruction != steering.Item)
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "You can take a look at the area around the sub by selecting the \"Active Sonar\" checkbox.");
|
|
||||||
|
|
||||||
while (!sonar.IsActive)
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
yield return new WaitForSeconds(0.5f);
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "The blue rectangle in the middle is the submarine, and the flickering shapes outside it are the walls of an underwater cavern. "
|
|
||||||
+ "Try moving the submarine by clicking somewhere on the monitor and dragging the pointer to the direction you want to go to.");
|
|
||||||
|
|
||||||
while (steering.TargetVelocity == Vector2.Zero && steering.TargetVelocity.Length() < 50.0f)
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
yield return new WaitForSeconds(4.0f);
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "The submarine moves up and down by pumping water in and out of the two ballast tanks at the bottom of the submarine. "
|
|
||||||
+ "The engine at the back of the sub moves it forwards and backwards.", hasButton: true);
|
|
||||||
|
|
||||||
while (infoBox != null)
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "Steer the submarine downwards, heading further into the cavern.");
|
|
||||||
|
|
||||||
while (Submarine.MainSub.WorldPosition.Y > 32000.0f)
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
yield return new WaitForSeconds(1.0f);
|
|
||||||
|
|
||||||
var moloch = Character.Create("moloch", steering.Item.WorldPosition + new Vector2(3000.0f, -500.0f), "");
|
|
||||||
|
|
||||||
moloch.PlaySound(CharacterSound.SoundType.Attack);
|
|
||||||
|
|
||||||
yield return new WaitForSeconds(1.0f);
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "Uh-oh... Something enormous just appeared on the sonar.");
|
|
||||||
|
|
||||||
List<Structure> windows = new List<Structure>();
|
|
||||||
foreach (Structure s in Structure.WallList)
|
|
||||||
{
|
|
||||||
if (s.CastShadow || !s.HasBody) continue;
|
|
||||||
|
|
||||||
if (s.Rect.Right > steering.Item.CurrentHull.Rect.Right) windows.Add(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
float slowdownTimer = 1.0f;
|
|
||||||
bool broken = false;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
steering.TargetVelocity = Vector2.Zero;
|
|
||||||
|
|
||||||
slowdownTimer = Math.Max(0.0f, slowdownTimer - CoroutineManager.DeltaTime * 0.3f);
|
|
||||||
Submarine.MainSub.Velocity *= slowdownTimer;
|
|
||||||
|
|
||||||
moloch.AIController.SelectTarget(steering.Item.CurrentHull.AiTarget);
|
|
||||||
Vector2 steeringDir = windows[0].WorldPosition - moloch.WorldPosition;
|
|
||||||
if (steeringDir != Vector2.Zero) steeringDir = Vector2.Normalize(steeringDir);
|
|
||||||
|
|
||||||
moloch.AIController.SteeringManager.SteeringManual(CoroutineManager.DeltaTime, steeringDir * 100.0f);
|
|
||||||
|
|
||||||
foreach (Structure window in windows)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < window.SectionCount; i++)
|
|
||||||
{
|
|
||||||
if (!window.SectionIsLeaking(i)) continue;
|
|
||||||
broken = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (broken) break;
|
|
||||||
}
|
|
||||||
if (broken) break;
|
|
||||||
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
} while (!broken);
|
|
||||||
|
|
||||||
//fix everything except the command windows
|
|
||||||
foreach (Structure w in Structure.WallList)
|
|
||||||
{
|
|
||||||
bool isWindow = windows.Contains(w);
|
|
||||||
|
|
||||||
for (int i = 0; i < w.SectionCount; i++)
|
|
||||||
{
|
|
||||||
if (!w.SectionIsLeaking(i)) continue;
|
|
||||||
|
|
||||||
if (isWindow)
|
|
||||||
{
|
|
||||||
//decrease window damage to slow down the leaking
|
|
||||||
w.AddDamage(i, -w.SectionDamage(i) * 0.48f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
w.AddDamage(i, -100000.0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Submarine.MainSub.GodMode = true;
|
|
||||||
|
|
||||||
var capacitor1 = Item.ItemList.Find(i => i.HasTag("capacitor1")).GetComponent<PowerContainer>();
|
|
||||||
var capacitor2 = Item.ItemList.Find(i => i.HasTag("capacitor1")).GetComponent<PowerContainer>();
|
|
||||||
CoroutineManager.StartCoroutine(KeepEnemyAway(moloch, new PowerContainer[] { capacitor1, capacitor2 }));
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "The hull has been breached! Close all the doors to the command room to stop the water from flooding the entire sub!");
|
|
||||||
|
|
||||||
Door commandDoor1 = Item.ItemList.Find(i => i.HasTag("commanddoor1")).GetComponent<Door>();
|
|
||||||
Door commandDoor2 = Item.ItemList.Find(i => i.HasTag("commanddoor2")).GetComponent<Door>();
|
|
||||||
|
|
||||||
//wait until the player is out of the room and the doors are closed
|
|
||||||
while (Controlled.WorldPosition.X > commandDoor1.Item.WorldPosition.X ||
|
|
||||||
(commandDoor1.IsOpen || commandDoor2.IsOpen))
|
|
||||||
{
|
|
||||||
//prevent the hull from filling up completely and crushing the player
|
|
||||||
steering.Item.CurrentHull.WaterVolume = Math.Min(steering.Item.CurrentHull.WaterVolume, steering.Item.CurrentHull.Volume * 0.9f);
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "You should quickly find yourself a diving mask or a diving suit. " +
|
|
||||||
"There are some in the room next to the airlock.");
|
|
||||||
|
|
||||||
bool divingMaskSelected = false;
|
|
||||||
|
|
||||||
while (!HasItem("divingmask") && !HasItem("divingsuit"))
|
|
||||||
{
|
|
||||||
if (!divingMaskSelected &&
|
|
||||||
Controlled.FocusedItem != null && Controlled.FocusedItem.Prefab.Identifier == "divingsuit")
|
|
||||||
{
|
|
||||||
infoBox = CreateInfoFrame("", "There can only be one item in each inventory slot, so you need to take off "
|
|
||||||
+ "the jumpsuit if you wish to wear a diving suit.");
|
|
||||||
|
|
||||||
divingMaskSelected = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HasItem("divingmask"))
|
|
||||||
{
|
|
||||||
infoBox = CreateInfoFrame("", "The diving mask will let you breathe underwater, but it won't protect from the water pressure outside the sub. " +
|
|
||||||
"It should be fine for the situation at hand, but you still need to find an oxygen tank and drag it into the same slot as the mask." +
|
|
||||||
"You should grab one or two from one of the cabinets.");
|
|
||||||
}
|
|
||||||
else if (HasItem("divingsuit"))
|
|
||||||
{
|
|
||||||
infoBox = CreateInfoFrame("", "In addition to letting you breathe underwater, the suit will protect you from the water pressure outside the sub " +
|
|
||||||
"(unlike the diving mask). However, you still need to drag an oxygen tank into the same slot as the suit to supply oxygen. " +
|
|
||||||
"You should grab one or two from one of the cabinets.");
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!HasItem("oxygentank"))
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
yield return new WaitForSeconds(5.0f);
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "Now you should stop the creature attacking the submarine before it does any more damage. Head to the railgun room at the upper right corner of the sub.");
|
|
||||||
|
|
||||||
var railGun = Item.ItemList.Find(i => i.GetComponent<Turret>() != null);
|
|
||||||
|
|
||||||
while (Vector2.Distance(Controlled.Position, railGun.Position) > 500)
|
|
||||||
{
|
|
||||||
yield return new WaitForSeconds(1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "The railgun requires a large power surge to fire. The reactor can't provide a surge large enough, so we need to use the "
|
|
||||||
+ " supercapacitors in the railgun room. The capacitors need to be charged first; select them and crank up the recharge rate.");
|
|
||||||
|
|
||||||
while (capacitor1.RechargeSpeed < 0.5f && capacitor2.RechargeSpeed < 0.5f)
|
|
||||||
{
|
|
||||||
yield return new WaitForSeconds(1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "The capacitors take some time to recharge, so now is a good " +
|
|
||||||
"time to head to the room below and load some shells for the railgun.");
|
|
||||||
|
|
||||||
|
|
||||||
var loader = Item.ItemList.Find(i => i.Prefab.Identifier == "railgunloader").GetComponent<ItemContainer>();
|
|
||||||
|
|
||||||
while (Math.Abs(Controlled.Position.Y - loader.Item.Position.Y) > 80)
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "Grab one of the shells. You can load it by selecting the railgun loader and dragging the shell to. "
|
|
||||||
+ "one of the free slots. You need two hands to carry a shell, so make sure you don't have anything else in either hand.");
|
|
||||||
|
|
||||||
while (loader.Item.ContainedItems.FirstOrDefault(i => i != null && i.Prefab.Identifier == "railgunshell") == null)
|
|
||||||
{
|
|
||||||
//TODO: reimplement
|
|
||||||
//moloch.Health = 50.0f;
|
|
||||||
|
|
||||||
capacitor1.Charge += 5.0f;
|
|
||||||
capacitor2.Charge += 5.0f;
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "Now we're ready to shoot! Select the railgun controller.");
|
|
||||||
|
|
||||||
while (Controlled.SelectedConstruction == null || Controlled.SelectedConstruction.Prefab.Identifier != "railguncontroller")
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
moloch.AnimController.SetPosition(ConvertUnits.ToSimUnits(Controlled.WorldPosition + Vector2.UnitY * 600.0f));
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "Use the right mouse button to aim and wait for the creature to come closer. When you're ready to shoot, "
|
|
||||||
+ "press the left mouse button.");
|
|
||||||
|
|
||||||
while (!moloch.IsDead)
|
|
||||||
{
|
|
||||||
if (moloch.WorldPosition.Y > Controlled.WorldPosition.Y + 600.0f)
|
|
||||||
{
|
|
||||||
moloch.AIController.SteeringManager.SteeringManual(CoroutineManager.DeltaTime, Controlled.WorldPosition - moloch.WorldPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
moloch.AIController.SelectTarget(Controlled.AiTarget);
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
Submarine.MainSub.GodMode = false;
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "The creature has died. Now you should fix the damages in the control room: " +
|
|
||||||
"Grab a welding tool from the closet in the railgun room.");
|
|
||||||
|
|
||||||
while (!HasItem("weldingtool"))
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "The welding tool requires fuel to work. Grab a welding fuel tank and attach it to the tool " +
|
|
||||||
"by dragging it into the same slot.");
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
var weldingTool = Controlled.Inventory.FindItemByIdentifier("weldingtool");
|
|
||||||
if (weldingTool != null &&
|
|
||||||
weldingTool.ContainedItems.FirstOrDefault(contained => contained != null && contained.Prefab.Identifier == "weldingfueltank") != null) break;
|
|
||||||
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
} while (true);
|
|
||||||
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "You can aim with the tool using the right mouse button and weld using the left button. " +
|
|
||||||
"Head to the command room to fix the leaks there.");
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
broken = false;
|
|
||||||
foreach (Structure window in windows)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < window.SectionCount; i++)
|
|
||||||
{
|
|
||||||
if (!window.SectionIsLeaking(i)) continue;
|
|
||||||
broken = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (broken) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
yield return new WaitForSeconds(1.0f);
|
|
||||||
} while (broken);
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "The hull is fixed now, but there's still quite a bit of water inside the sub. It should be pumped out "
|
|
||||||
+ "using the bilge pump in the room at the bottom of the submarine.");
|
|
||||||
|
|
||||||
Pump pump = Item.ItemList.Find(i => i.HasTag("tutorialpump")).GetComponent<Pump>();
|
|
||||||
|
|
||||||
while (Vector2.Distance(Controlled.Position, pump.Item.Position) > 100.0f)
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "The two pumps inside the ballast tanks "
|
|
||||||
+ "are connected straight to the navigation terminal and can't be manually controlled unless you mess with their wiring, " +
|
|
||||||
"so you should only use the pump in the middle room to pump out the water. Select it, turn it on and adjust the pumping speed " +
|
|
||||||
"to start pumping water out.", hasButton: true);
|
|
||||||
|
|
||||||
while (infoBox != null)
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool brokenMsgShown = false;
|
|
||||||
|
|
||||||
Item brokenBox = null;
|
|
||||||
|
|
||||||
while (pump.FlowPercentage > 0.0f || pump.CurrFlow <= 0.0f || !pump.IsActive)
|
|
||||||
{
|
|
||||||
if (!brokenMsgShown && pump.Voltage < pump.MinVoltage && Controlled.SelectedConstruction == pump.Item)
|
|
||||||
{
|
|
||||||
brokenMsgShown = true;
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "Looks like the pump isn't getting any power. The water must have short-circuited some of the junction "
|
|
||||||
+ "boxes. You can check which boxes are broken by selecting them.");
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
if (Controlled.SelectedConstruction!=null &&
|
|
||||||
Controlled.SelectedConstruction.GetComponent<PowerTransfer>() != null &&
|
|
||||||
Controlled.SelectedConstruction.Condition == 0.0f)
|
|
||||||
{
|
|
||||||
brokenBox = Controlled.SelectedConstruction;
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "Here's our problem: this junction box is broken. Luckily engineers are adept at fixing electrical devices - "
|
|
||||||
+ "you just need to find a spare wire and click the \"Fix\"-button to repair the box.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pump.Voltage > pump.MinVoltage) break;
|
|
||||||
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (brokenBox != null && brokenBox.ConditionPercentage > 50.0f && pump.Voltage < pump.MinVoltage)
|
|
||||||
{
|
|
||||||
yield return new WaitForSeconds(1.0f);
|
|
||||||
|
|
||||||
if (pump.Voltage < pump.MinVoltage)
|
|
||||||
{
|
|
||||||
infoBox = CreateInfoFrame("", "The pump is still not running. Check if there are more broken junction boxes between the pump and the reactor.");
|
|
||||||
}
|
|
||||||
brokenBox = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "The pump is up and running. Wait for the water to be drained out.");
|
|
||||||
|
|
||||||
while (pump.Item.CurrentHull.WaterVolume > 1000.0f)
|
|
||||||
{
|
|
||||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("", "That was all there is to this tutorial! Now you should be able to handle " +
|
|
||||||
"most of the basic tasks on board the submarine.");
|
|
||||||
|
|
||||||
Completed = true;
|
|
||||||
|
|
||||||
yield return new WaitForSeconds(4.0f);
|
|
||||||
|
|
||||||
Controlled = null;
|
|
||||||
GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
|
|
||||||
GameMain.LightManager.LosEnabled = false;
|
|
||||||
|
|
||||||
var cinematic = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam, Alignment.CenterLeft, Alignment.CenterRight, panDuration: 5.0f);
|
|
||||||
|
|
||||||
while (cinematic.Running)
|
|
||||||
{
|
|
||||||
yield return Controlled != null && Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
Submarine.Unload();
|
|
||||||
GameMain.MainMenuScreen.Select();
|
|
||||||
|
|
||||||
yield return CoroutineStatus.Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool HasItem(string itemIdentifier)
|
|
||||||
{
|
|
||||||
if (Character.Controlled == null) return false;
|
|
||||||
|
|
||||||
return Character.Controlled.Inventory.FindItemByIdentifier(itemIdentifier) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected IEnumerable<CoroutineStatus> KeepReactorRunning(Reactor reactor)
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
//TODO: reimplement
|
|
||||||
/*reactor.AutoTemp = true;
|
|
||||||
reactor.ShutDownTemp = 5000.0f;*/
|
|
||||||
|
|
||||||
yield return CoroutineStatus.Running;
|
|
||||||
} while (Item.ItemList.Contains(reactor.Item));
|
|
||||||
|
|
||||||
yield return CoroutineStatus.Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// keeps the enemy away from the sub until the capacitors are loaded
|
|
||||||
/// </summary>
|
|
||||||
private IEnumerable<CoroutineStatus> KeepEnemyAway(Character enemy, PowerContainer[] capacitors)
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (enemy == null || Character.Controlled == null) break;
|
|
||||||
|
|
||||||
//TODO: reimplement
|
|
||||||
//enemy.Health = 50.0f;
|
|
||||||
|
|
||||||
if (enemy.AIController is EnemyAIController enemyAI)
|
|
||||||
{
|
|
||||||
enemyAI.State = AIState.Idle;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 targetPos = Character.Controlled.WorldPosition + new Vector2(0.0f, 3000.0f);
|
|
||||||
|
|
||||||
Vector2 steering = targetPos - enemy.WorldPosition;
|
|
||||||
if (steering != Vector2.Zero) steering = Vector2.Normalize(steering);
|
|
||||||
|
|
||||||
enemy.AIController.Steering = steering;
|
|
||||||
|
|
||||||
yield return CoroutineStatus.Running;
|
|
||||||
} while (capacitors.FirstOrDefault(c => c.Charge > 0.4f) == null);
|
|
||||||
|
|
||||||
yield return CoroutineStatus.Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+77
-28
@@ -41,30 +41,79 @@ namespace Barotrauma.Tutorials
|
|||||||
|
|
||||||
// Variables
|
// Variables
|
||||||
private Character captain;
|
private Character captain;
|
||||||
private string radioSpeakerName;
|
private LocalizedString radioSpeakerName;
|
||||||
private Sprite captain_steerIcon;
|
private Sprite captain_steerIcon;
|
||||||
private Color captain_steerIconColor;
|
private Color captain_steerIconColor;
|
||||||
|
|
||||||
public CaptainTutorial(XElement element) : base(element)
|
public CaptainTutorial() : base("tutorial.captaintraining".ToIdentifier(),
|
||||||
|
new Segment(
|
||||||
|
"Captain.CommandMedic".ToIdentifier(),
|
||||||
|
"Captain.CommandMedicObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.ManualVideo,
|
||||||
|
textContent: new Segment.Text { Tag = "Captain.CommandMedicText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center },
|
||||||
|
videoContent: new Segment.Video { File = "tutorial_command.webm", TextTag = "Captain.CommandMedicText".ToIdentifier(), Width = 450, Height = 80 }),
|
||||||
|
new Segment(
|
||||||
|
"Captain.CommandMechanic".ToIdentifier(),
|
||||||
|
"Captain.CommandMechanicObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.TextOnly,
|
||||||
|
textContent: new Segment.Text { Tag = "Captain.CommandMechanicText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center }),
|
||||||
|
new Segment(
|
||||||
|
"Captain.CommandSecurity".ToIdentifier(),
|
||||||
|
"Captain.CommandSecurityObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.TextOnly,
|
||||||
|
textContent: new Segment.Text { Tag = "Captain.CommandSecurityText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center }),
|
||||||
|
new Segment(
|
||||||
|
"Captain.CommandEngineer".ToIdentifier(),
|
||||||
|
"Captain.CommandEngineerObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.TextOnly,
|
||||||
|
textContent: new Segment.Text { Tag = "Captain.CommandEngineerText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center }),
|
||||||
|
new Segment(
|
||||||
|
"Captain.Undock".ToIdentifier(),
|
||||||
|
"Captain.UndockObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.ManualVideo,
|
||||||
|
textContent: new Segment.Text { Tag = "Captain.UndockText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center },
|
||||||
|
videoContent: new Segment.Video { File = "tutorial_undock.webm", TextTag = "Captain.UndockText".ToIdentifier(), Width = 450, Height = 80 }),
|
||||||
|
new Segment(
|
||||||
|
"Captain.Navigate".ToIdentifier(),
|
||||||
|
"Captain.NavigateObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.ManualVideo,
|
||||||
|
textContent: new Segment.Text { Tag = "Captain.NavigateText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center },
|
||||||
|
videoContent: new Segment.Video { File = "tutorial_navigation.webm", TextTag = "Captain.NavigateText".ToIdentifier(), Width = 450, Height = 80 }),
|
||||||
|
new Segment(
|
||||||
|
"Captain.Dock".ToIdentifier(),
|
||||||
|
"Captain.DockObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.ManualVideo,
|
||||||
|
textContent: new Segment.Text { Tag = "Captain.DockText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center },
|
||||||
|
videoContent: new Segment.Video { File = "tutorial_docking.webm", TextTag = "Captain.DockText".ToIdentifier(), Width = 450, Height = 80 }))
|
||||||
|
{ }
|
||||||
|
|
||||||
|
protected override CharacterInfo GetCharacterInfo()
|
||||||
{
|
{
|
||||||
|
return new CharacterInfo(
|
||||||
|
CharacterPrefab.HumanSpeciesName,
|
||||||
|
jobOrJobPrefab: new Job(
|
||||||
|
JobPrefab.Prefabs["captain"], Rand.RandSync.Unsynced, 0,
|
||||||
|
new Skill("medical".ToIdentifier(), 20),
|
||||||
|
new Skill("weapons".ToIdentifier(), 20),
|
||||||
|
new Skill("mechanical".ToIdentifier(), 20),
|
||||||
|
new Skill("electrical".ToIdentifier(), 20),
|
||||||
|
new Skill("helm".ToIdentifier(), 70)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Start()
|
protected override void Initialize()
|
||||||
{
|
{
|
||||||
base.Start();
|
|
||||||
|
|
||||||
captain = Character.Controlled;
|
captain = Character.Controlled;
|
||||||
radioSpeakerName = TextManager.Get("Tutorial.Radio.Watchman");
|
radioSpeakerName = TextManager.Get("Tutorial.Radio.Watchman");
|
||||||
GameMain.GameSession.CrewManager.AllowCharacterSwitch = false;
|
GameMain.GameSession.CrewManager.AllowCharacterSwitch = false;
|
||||||
|
|
||||||
var revolver = FindOrGiveItem(captain, "revolver");
|
var revolver = FindOrGiveItem(captain, "revolver".ToIdentifier());
|
||||||
revolver.Unequip(captain);
|
revolver.Unequip(captain);
|
||||||
captain.Inventory.RemoveItem(revolver);
|
captain.Inventory.RemoveItem(revolver);
|
||||||
|
|
||||||
var captainscap =
|
var captainscap =
|
||||||
captain.Inventory.FindItemByIdentifier("captainscap1") ??
|
captain.Inventory.FindItemByIdentifier("captainscap1".ToIdentifier()) ??
|
||||||
captain.Inventory.FindItemByIdentifier("captainscap2") ??
|
captain.Inventory.FindItemByIdentifier("captainscap2".ToIdentifier()) ??
|
||||||
captain.Inventory.FindItemByIdentifier("captainscap3");
|
captain.Inventory.FindItemByIdentifier("captainscap3".ToIdentifier());
|
||||||
|
|
||||||
if (captainscap != null)
|
if (captainscap != null)
|
||||||
{
|
{
|
||||||
@@ -73,16 +122,16 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
|
|
||||||
var captainsuniform =
|
var captainsuniform =
|
||||||
captain.Inventory.FindItemByIdentifier("captainsuniform1") ??
|
captain.Inventory.FindItemByIdentifier("captainsuniform1".ToIdentifier()) ??
|
||||||
captain.Inventory.FindItemByIdentifier("captainsuniform2") ??
|
captain.Inventory.FindItemByIdentifier("captainsuniform2".ToIdentifier()) ??
|
||||||
captain.Inventory.FindItemByIdentifier("captainsuniform3");
|
captain.Inventory.FindItemByIdentifier("captainsuniform3".ToIdentifier());
|
||||||
if (captainsuniform != null)
|
if (captainsuniform != null)
|
||||||
{
|
{
|
||||||
captainsuniform.Unequip(captain);
|
captainsuniform.Unequip(captain);
|
||||||
captain.Inventory.RemoveItem(captainsuniform);
|
captain.Inventory.RemoveItem(captainsuniform);
|
||||||
}
|
}
|
||||||
|
|
||||||
var steerOrder = Order.GetPrefab("steer");
|
var steerOrder = OrderPrefab.Prefabs["steer"];
|
||||||
captain_steerIcon = steerOrder.SymbolSprite;
|
captain_steerIcon = steerOrder.SymbolSprite;
|
||||||
captain_steerIconColor = steerOrder.Color;
|
captain_steerIconColor = steerOrder.Color;
|
||||||
|
|
||||||
@@ -99,7 +148,7 @@ namespace Barotrauma.Tutorials
|
|||||||
captain_medicSpawnPos = Item.ItemList.Find(i => i.HasTag("captain_medicspawnpos")).WorldPosition;
|
captain_medicSpawnPos = Item.ItemList.Find(i => i.HasTag("captain_medicspawnpos")).WorldPosition;
|
||||||
tutorial_submarineDoor = Item.ItemList.Find(i => i.HasTag("tutorial_submarinedoor")).GetComponent<Door>();
|
tutorial_submarineDoor = Item.ItemList.Find(i => i.HasTag("tutorial_submarinedoor")).GetComponent<Door>();
|
||||||
tutorial_submarineDoorLight = Item.ItemList.Find(i => i.HasTag("tutorial_submarinedoorlight")).GetComponent<LightComponent>();
|
tutorial_submarineDoorLight = Item.ItemList.Find(i => i.HasTag("tutorial_submarinedoorlight")).GetComponent<LightComponent>();
|
||||||
var medicInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("medicaldoctor"));
|
var medicInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobOrJobPrefab: JobPrefab.Get("medicaldoctor"));
|
||||||
captain_medic = Character.Create(medicInfo, captain_medicSpawnPos, "medicaldoctor");
|
captain_medic = Character.Create(medicInfo, captain_medicSpawnPos, "medicaldoctor");
|
||||||
captain_medic.TeamID = CharacterTeamType.Team1;
|
captain_medic.TeamID = CharacterTeamType.Team1;
|
||||||
captain_medic.GiveJobItems(null);
|
captain_medic.GiveJobItems(null);
|
||||||
@@ -122,17 +171,17 @@ namespace Barotrauma.Tutorials
|
|||||||
SetDoorAccess(tutorial_lockedDoor_1, null, false);
|
SetDoorAccess(tutorial_lockedDoor_1, null, false);
|
||||||
SetDoorAccess(tutorial_lockedDoor_2, null, false);
|
SetDoorAccess(tutorial_lockedDoor_2, null, false);
|
||||||
|
|
||||||
var mechanicInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("mechanic"));
|
var mechanicInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobOrJobPrefab: JobPrefab.Get("mechanic"));
|
||||||
captain_mechanic = Character.Create(mechanicInfo, WayPoint.GetRandom(SpawnType.Human, mechanicInfo.Job?.Prefab, Submarine.MainSub).WorldPosition, "mechanic");
|
captain_mechanic = Character.Create(mechanicInfo, WayPoint.GetRandom(SpawnType.Human, mechanicInfo.Job?.Prefab, Submarine.MainSub).WorldPosition, "mechanic");
|
||||||
captain_mechanic.TeamID = CharacterTeamType.Team1;
|
captain_mechanic.TeamID = CharacterTeamType.Team1;
|
||||||
captain_mechanic.GiveJobItems();
|
captain_mechanic.GiveJobItems();
|
||||||
|
|
||||||
var securityInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("securityofficer"));
|
var securityInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobOrJobPrefab: JobPrefab.Get("securityofficer"));
|
||||||
captain_security = Character.Create(securityInfo, WayPoint.GetRandom(SpawnType.Human, securityInfo.Job?.Prefab, Submarine.MainSub).WorldPosition, "securityofficer");
|
captain_security = Character.Create(securityInfo, WayPoint.GetRandom(SpawnType.Human, securityInfo.Job?.Prefab, Submarine.MainSub).WorldPosition, "securityofficer");
|
||||||
captain_security.TeamID = CharacterTeamType.Team1;
|
captain_security.TeamID = CharacterTeamType.Team1;
|
||||||
captain_security.GiveJobItems();
|
captain_security.GiveJobItems();
|
||||||
|
|
||||||
var engineerInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("engineer"));
|
var engineerInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobOrJobPrefab: JobPrefab.Get("engineer"));
|
||||||
captain_engineer = Character.Create(engineerInfo, WayPoint.GetRandom(SpawnType.Human, engineerInfo.Job?.Prefab, Submarine.MainSub).WorldPosition, "engineer");
|
captain_engineer = Character.Create(engineerInfo, WayPoint.GetRandom(SpawnType.Human, engineerInfo.Job?.Prefab, Submarine.MainSub).WorldPosition, "engineer");
|
||||||
captain_engineer.TeamID = CharacterTeamType.Team1;
|
captain_engineer.TeamID = CharacterTeamType.Team1;
|
||||||
captain_engineer.GiveJobItems();
|
captain_engineer.GiveJobItems();
|
||||||
@@ -163,7 +212,7 @@ namespace Barotrauma.Tutorials
|
|||||||
yield return new WaitForSeconds(2f, false);
|
yield return new WaitForSeconds(2f, false);
|
||||||
GameMain.GameSession.CrewManager.AutoShowCrewList();
|
GameMain.GameSession.CrewManager.AutoShowCrewList();
|
||||||
GameMain.GameSession.CrewManager.AddCharacter(captain_medic);
|
GameMain.GameSession.CrewManager.AddCharacter(captain_medic);
|
||||||
TriggerTutorialSegment(0, GameMain.Config.KeyBindText(InputType.Command));
|
TriggerTutorialSegment(0, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Command));
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
yield return null;
|
yield return null;
|
||||||
@@ -172,13 +221,13 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
while (!HasOrder(captain_medic, "follow"));
|
while (!HasOrder(captain_medic, "follow"));
|
||||||
SetDoorAccess(tutorial_submarineDoor, tutorial_submarineDoorLight, true);
|
SetDoorAccess(tutorial_submarineDoor, tutorial_submarineDoorLight, true);
|
||||||
RemoveCompletedObjective(segments[0]);
|
RemoveCompletedObjective(0);
|
||||||
|
|
||||||
// Submarine
|
// Submarine
|
||||||
do { yield return null; } while (!captain_enteredSubmarineSensor.MotionDetected);
|
do { yield return null; } while (!captain_enteredSubmarineSensor.MotionDetected);
|
||||||
yield return new WaitForSeconds(3f, false);
|
yield return new WaitForSeconds(3f, false);
|
||||||
captain_mechanic.AIController.Enabled = captain_security.AIController.Enabled = captain_engineer.AIController.Enabled = true;
|
captain_mechanic.AIController.Enabled = captain_security.AIController.Enabled = captain_engineer.AIController.Enabled = true;
|
||||||
TriggerTutorialSegment(1, GameMain.Config.KeyBindText(InputType.Command));
|
TriggerTutorialSegment(1, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Command));
|
||||||
GameMain.GameSession.CrewManager.AddCharacter(captain_mechanic);
|
GameMain.GameSession.CrewManager.AddCharacter(captain_mechanic);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@@ -187,9 +236,9 @@ namespace Barotrauma.Tutorials
|
|||||||
// GameMain.GameSession.CrewManager.HighlightOrderButton(captain_mechanic, "repairsystems", highlightColor, new Vector2(5, 5));
|
// GameMain.GameSession.CrewManager.HighlightOrderButton(captain_mechanic, "repairsystems", highlightColor, new Vector2(5, 5));
|
||||||
//HighlightOrderOption("jobspecific");
|
//HighlightOrderOption("jobspecific");
|
||||||
} while (!HasOrder(captain_mechanic, "repairsystems") && !HasOrder(captain_mechanic, "repairmechanical") && !HasOrder(captain_mechanic, "repairelectrical"));
|
} while (!HasOrder(captain_mechanic, "repairsystems") && !HasOrder(captain_mechanic, "repairmechanical") && !HasOrder(captain_mechanic, "repairelectrical"));
|
||||||
RemoveCompletedObjective(segments[1]);
|
RemoveCompletedObjective(1);
|
||||||
yield return new WaitForSeconds(2f, false);
|
yield return new WaitForSeconds(2f, false);
|
||||||
TriggerTutorialSegment(2, GameMain.Config.KeyBindText(InputType.Command));
|
TriggerTutorialSegment(2, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Command));
|
||||||
GameMain.GameSession.CrewManager.AddCharacter(captain_security);
|
GameMain.GameSession.CrewManager.AddCharacter(captain_security);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@@ -199,9 +248,9 @@ namespace Barotrauma.Tutorials
|
|||||||
HighlightOrderOption("fireatwill");
|
HighlightOrderOption("fireatwill");
|
||||||
}
|
}
|
||||||
while (!HasOrder(captain_security, "operateweapons"));
|
while (!HasOrder(captain_security, "operateweapons"));
|
||||||
RemoveCompletedObjective(segments[2]);
|
RemoveCompletedObjective(2);
|
||||||
yield return new WaitForSeconds(4f, false);
|
yield return new WaitForSeconds(4f, false);
|
||||||
TriggerTutorialSegment(3, GameMain.Config.KeyBindText(InputType.Command));
|
TriggerTutorialSegment(3, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Command));
|
||||||
GameMain.GameSession.CrewManager.AddCharacter(captain_engineer);
|
GameMain.GameSession.CrewManager.AddCharacter(captain_engineer);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@@ -211,7 +260,7 @@ namespace Barotrauma.Tutorials
|
|||||||
HighlightOrderOption("powerup");
|
HighlightOrderOption("powerup");
|
||||||
}
|
}
|
||||||
while (!HasOrder(captain_engineer, "operatereactor", "powerup"));
|
while (!HasOrder(captain_engineer, "operatereactor", "powerup"));
|
||||||
RemoveCompletedObjective(segments[3]);
|
RemoveCompletedObjective(3);
|
||||||
tutorial_submarineReactor.CanBeSelected = true;
|
tutorial_submarineReactor.CanBeSelected = true;
|
||||||
do { yield return null; } while (!tutorial_submarineReactor.IsActive); // Wait until reactor on
|
do { yield return null; } while (!tutorial_submarineReactor.IsActive); // Wait until reactor on
|
||||||
TriggerTutorialSegment(4);
|
TriggerTutorialSegment(4);
|
||||||
@@ -226,7 +275,7 @@ namespace Barotrauma.Tutorials
|
|||||||
yield return new WaitForSeconds(1.0f, false);
|
yield return new WaitForSeconds(1.0f, false);
|
||||||
} while (Submarine.MainSub.DockedTo.Any());
|
} while (Submarine.MainSub.DockedTo.Any());
|
||||||
captain_navConsole.UseAutoDocking = false;
|
captain_navConsole.UseAutoDocking = false;
|
||||||
RemoveCompletedObjective(segments[4]);
|
RemoveCompletedObjective(4);
|
||||||
yield return new WaitForSeconds(2f, false);
|
yield return new WaitForSeconds(2f, false);
|
||||||
TriggerTutorialSegment(5); // Navigate to destination
|
TriggerTutorialSegment(5); // Navigate to destination
|
||||||
do
|
do
|
||||||
@@ -241,7 +290,7 @@ namespace Barotrauma.Tutorials
|
|||||||
yield return null;
|
yield return null;
|
||||||
} while (captain_sonar.CurrentMode != Sonar.Mode.Active);
|
} while (captain_sonar.CurrentMode != Sonar.Mode.Active);
|
||||||
do { yield return null; } while (Vector2.Distance(Submarine.MainSub.WorldPosition, Level.Loaded.EndPosition) > 4000f);
|
do { yield return null; } while (Vector2.Distance(Submarine.MainSub.WorldPosition, Level.Loaded.EndPosition) > 4000f);
|
||||||
RemoveCompletedObjective(segments[5]);
|
RemoveCompletedObjective(5);
|
||||||
captain_navConsole.UseAutoDocking = true;
|
captain_navConsole.UseAutoDocking = true;
|
||||||
yield return new WaitForSeconds(4f, false);
|
yield return new WaitForSeconds(4f, false);
|
||||||
TriggerTutorialSegment(6); // Docking
|
TriggerTutorialSegment(6); // Docking
|
||||||
@@ -250,7 +299,7 @@ namespace Barotrauma.Tutorials
|
|||||||
//captain_navConsoleCustomInterface.HighlightElement(0, uiHighlightColor, duration: 1.0f, pulsateAmount: 0.0f);
|
//captain_navConsoleCustomInterface.HighlightElement(0, uiHighlightColor, duration: 1.0f, pulsateAmount: 0.0f);
|
||||||
yield return new WaitForSeconds(1.0f, false);
|
yield return new WaitForSeconds(1.0f, false);
|
||||||
} while (!Submarine.MainSub.AtEndExit || !Submarine.MainSub.DockedTo.Any());
|
} while (!Submarine.MainSub.AtEndExit || !Submarine.MainSub.DockedTo.Any());
|
||||||
RemoveCompletedObjective(segments[6]);
|
RemoveCompletedObjective(6);
|
||||||
yield return new WaitForSeconds(3f, false);
|
yield return new WaitForSeconds(3f, false);
|
||||||
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.GetWithVariable("Captain.Radio.Complete", "[OUTPOSTNAME]", GameMain.GameSession.EndLocation.Name), ChatMessageType.Radio, null);
|
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.GetWithVariable("Captain.Radio.Complete", "[OUTPOSTNAME]", GameMain.GameSession.EndLocation.Name), ChatMessageType.Radio, null);
|
||||||
SetHighlight(captain_navConsole.Item, false);
|
SetHighlight(captain_navConsole.Item, false);
|
||||||
|
|||||||
-520
@@ -1,520 +0,0 @@
|
|||||||
/*using System.Collections.Generic;
|
|
||||||
using System.Xml.Linq;
|
|
||||||
using System;
|
|
||||||
using Microsoft.Xna.Framework;
|
|
||||||
using Barotrauma.Items.Components;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Barotrauma.Tutorials
|
|
||||||
{
|
|
||||||
class ContextualTutorial : Tutorial
|
|
||||||
{
|
|
||||||
public ContextualTutorial(XElement element) : base(element)
|
|
||||||
{
|
|
||||||
//Name = "ContextualTutorial";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool Selected = false;
|
|
||||||
|
|
||||||
private Steering navConsole;
|
|
||||||
private Reactor reactor;
|
|
||||||
private Sonar sonar;
|
|
||||||
private Vector2 subStartingPosition;
|
|
||||||
private List<Character> crew;
|
|
||||||
private Character mechanic;
|
|
||||||
private Character engineer;
|
|
||||||
private Character injuredMember = null;
|
|
||||||
|
|
||||||
private List<Pair<Character, float>> characterTimeOnSonar;
|
|
||||||
private float requiredTimeOnSonar = 5f;
|
|
||||||
|
|
||||||
private float tutorialTimer;
|
|
||||||
|
|
||||||
private bool disableTutorialOnDeficiencyFound = true;
|
|
||||||
|
|
||||||
private float floodTutorialTimer = 0.0f;
|
|
||||||
private const float floodTutorialDelay = 2.0f;
|
|
||||||
private float medicalTutorialTimer = 0.0f;
|
|
||||||
private const float medicalTutorialDelay = 2.0f;
|
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
for (int i = 0; i < segments.Count; i++)
|
|
||||||
{
|
|
||||||
segments[i].IsTriggered = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
characterTimeOnSonar = new List<Pair<Character, float>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void LoadPartiallyComplete(XElement element)
|
|
||||||
{
|
|
||||||
int[] completedSegments = element.GetAttributeIntArray("completedsegments", null);
|
|
||||||
|
|
||||||
if (completedSegments == null || completedSegments.Length == 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (completedSegments.Length == segments.Count) // Completed all segments
|
|
||||||
{
|
|
||||||
Stop();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < completedSegments.Length; i++)
|
|
||||||
{
|
|
||||||
segments[completedSegments[i]].IsTriggered = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SavePartiallyComplete(XElement element)
|
|
||||||
{
|
|
||||||
XElement tutorialElement = new XElement("contextualtutorial");
|
|
||||||
tutorialElement.Add(new XAttribute("completedsegments", GetCompletedSegments()));
|
|
||||||
element.Add(tutorialElement);
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetCompletedSegments()
|
|
||||||
{
|
|
||||||
string completedSegments = string.Empty;
|
|
||||||
|
|
||||||
for (int i = 0; i < segments.Count; i++)
|
|
||||||
{
|
|
||||||
if (segments[i].IsTriggered)
|
|
||||||
{
|
|
||||||
completedSegments += i + ",";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (completedSegments.Length > 0)
|
|
||||||
{
|
|
||||||
completedSegments = completedSegments.TrimEnd(',');
|
|
||||||
}
|
|
||||||
|
|
||||||
return completedSegments;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Start()
|
|
||||||
{
|
|
||||||
if (!Initialized) return;
|
|
||||||
|
|
||||||
base.Start();
|
|
||||||
injuredMember = null;
|
|
||||||
activeContentSegment = null;
|
|
||||||
tutorialTimer = floodTutorialTimer = medicalTutorialTimer = 0.0f;
|
|
||||||
subStartingPosition = Vector2.Zero;
|
|
||||||
characterTimeOnSonar.Clear();
|
|
||||||
|
|
||||||
subStartingPosition = Submarine.MainSub.WorldPosition;
|
|
||||||
navConsole = Item.ItemList.Find(i => i.HasTag("command"))?.GetComponent<Steering>();
|
|
||||||
sonar = navConsole?.Item.GetComponent<Sonar>();
|
|
||||||
reactor = Item.ItemList.Find(i => i.HasTag("reactor"))?.GetComponent<Reactor>();
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
if (reactor == null || navConsole == null || sonar == null)
|
|
||||||
{
|
|
||||||
infoBox = CreateInfoFrame("Error", "Submarine not compatible with the tutorial:"
|
|
||||||
+ "\nReactor - " + (reactor != null ? "OK" : "Tag 'reactor' not found")
|
|
||||||
+ "\nNavigation Console - " + (navConsole != null ? "OK" : "Tag 'command' not found")
|
|
||||||
+ "\nSonar - " + (sonar != null ? "OK" : "Not found under Navigation Console"), hasButton: true);
|
|
||||||
CoroutineManager.StartCoroutine(WaitForErrorClosed());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (disableTutorialOnDeficiencyFound)
|
|
||||||
{
|
|
||||||
if (reactor == null || navConsole == null || sonar == null)
|
|
||||||
{
|
|
||||||
Stop();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (navConsole == null) segments[2].IsTriggered = true; // Disable navigation console usage tutorial
|
|
||||||
if (reactor == null) segments[5].IsTriggered = true; // Disable reactor usage tutorial
|
|
||||||
if (sonar == null) segments[6].IsTriggered = true; // Disable enemy on sonar tutorial
|
|
||||||
}
|
|
||||||
|
|
||||||
crew = GameMain.GameSession.CrewManager.GetCharacters().ToList();
|
|
||||||
mechanic = CrewMemberWithJob("mechanic");
|
|
||||||
engineer = CrewMemberWithJob("engineer");
|
|
||||||
|
|
||||||
Completed = true; // Trigger completed at start to prevent the contextual tutorial from automatically activating on starting new campaigns after this one
|
|
||||||
started = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
private IEnumerable<object> WaitForErrorClosed()
|
|
||||||
{
|
|
||||||
while (infoBox != null) yield return null;
|
|
||||||
Stop();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public override void Stop()
|
|
||||||
{
|
|
||||||
base.Stop();
|
|
||||||
characterTimeOnSonar = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Update(float deltaTime)
|
|
||||||
{
|
|
||||||
base.Update(deltaTime);
|
|
||||||
|
|
||||||
if (!started || ContentRunning) return;
|
|
||||||
|
|
||||||
deltaTime *= 0.5f;
|
|
||||||
|
|
||||||
for (int i = 0; i < segments.Count; i++)
|
|
||||||
{
|
|
||||||
if (segments[i].IsTriggered || HasObjective(segments[i])) continue;
|
|
||||||
if (CheckContextualTutorials(i, deltaTime)) // Found a relevant tutorial, halt finding new ones
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool CheckContextualTutorials(int index, float deltaTime)
|
|
||||||
{
|
|
||||||
switch (index)
|
|
||||||
{
|
|
||||||
case 0: // Welcome: Game Start [Text]
|
|
||||||
if (tutorialTimer < 1.0f)
|
|
||||||
{
|
|
||||||
tutorialTimer += deltaTime;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 1: // Command Reactor: 2 seconds after 'Welcome' dismissed and only if no command given to start reactor [Video]
|
|
||||||
if (!segments[0].IsTriggered) return false;
|
|
||||||
if (tutorialTimer < 3.0f)
|
|
||||||
{
|
|
||||||
tutorialTimer += deltaTime;
|
|
||||||
|
|
||||||
if (HasOrder("operatereactor"))
|
|
||||||
{
|
|
||||||
segments[index].IsTriggered = true;
|
|
||||||
tutorialTimer = 2.5f;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2: // Nav Console: 2 seconds after 'Command Reactor' dismissed or if nav console is activated [Video]
|
|
||||||
if (!IsReactorPoweredUp()) return false; // Do not advance tutorial based on this segment if reactor has not been powered up
|
|
||||||
if (Character.Controlled?.SelectedConstruction != navConsole.Item)
|
|
||||||
{
|
|
||||||
if (tutorialTimer < 4.5f)
|
|
||||||
{
|
|
||||||
tutorialTimer += deltaTime;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tutorialTimer = 4.5f;
|
|
||||||
}
|
|
||||||
|
|
||||||
TriggerTutorialSegment(index, GameMain.GameSession.EndLocation.Name);
|
|
||||||
return true;
|
|
||||||
case 3: // Objective: Travel ~150 meters and while sub is not flooding [Text]
|
|
||||||
if (Vector2.Distance(subStartingPosition, Submarine.MainSub.WorldPosition) < 8000f || IsFlooding())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else // Called earlier than others due to requiring specific args
|
|
||||||
{
|
|
||||||
TriggerTutorialSegment(index, GameMain.GameSession.EndLocation.Name);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case 4: // Flood: Hull is breached and sub is taking on water [Video]
|
|
||||||
if (!IsFlooding())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (floodTutorialTimer < floodTutorialDelay)
|
|
||||||
{
|
|
||||||
floodTutorialTimer += deltaTime;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 5: // Reactor: Player uses reactor for the first time [Video]
|
|
||||||
if (Character.Controlled?.SelectedConstruction != reactor.Item)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 6: // Enemy on Sonar: Player witnesses creature signal on sonar for 5 seconds [Video]
|
|
||||||
if (!HasEnemyOnSonarForDuration(deltaTime))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 7: // Degrading1: Any equipment degrades to 50% health or less and player has not assigned any crew to perform maintenance [Text]
|
|
||||||
if ((mechanic == null || mechanic.IsDead) && (engineer == null || engineer.IsDead)) // Both engineer and mechanic are dead or do not exist -> do not display
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool degradedEquipmentFound = false;
|
|
||||||
|
|
||||||
foreach (Item item in Item.ItemList)
|
|
||||||
{
|
|
||||||
if (!item.Repairables.Any() || item.Condition > 50.0f) continue;
|
|
||||||
degradedEquipmentFound = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (degradedEquipmentFound)
|
|
||||||
{
|
|
||||||
if (HasOrder("repairsystems", "jobspecific"))
|
|
||||||
{
|
|
||||||
segments[index].IsTriggered = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 8: // Medical: Crewmember is injured but not killed [Video]
|
|
||||||
|
|
||||||
if (injuredMember == null)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < crew.Count; i++)
|
|
||||||
{
|
|
||||||
Character member = crew[i];
|
|
||||||
if (member.Vitality < member.MaxVitality && !member.IsDead)
|
|
||||||
{
|
|
||||||
injuredMember = member;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (medicalTutorialTimer < medicalTutorialDelay)
|
|
||||||
{
|
|
||||||
medicalTutorialTimer += deltaTime;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TriggerTutorialSegment(index, new string[] { injuredMember.Info.DisplayName,
|
|
||||||
(injuredMember.Info.Gender == Gender.Male) ? TextManager.Get("PronounPossessiveMale").ToLower() : TextManager.Get("PronounPossessiveFemale").ToLower() });
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case 9: // Approach1: Destination is within ~100m [Video]
|
|
||||||
if (Vector2.Distance(Submarine.MainSub.WorldPosition, Level.Loaded.EndPosition) > 8000f)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TriggerTutorialSegment(index, GameMain.GameSession.EndLocation.Name);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case 10: // Approach2: Sub is docked [Text]
|
|
||||||
if (!Submarine.MainSub.AtEndPosition || Submarine.MainSub.DockedTo.Count == 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
TriggerTutorialSegment(index);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void CheckActiveObjectives(TutorialSegment objective, float deltaTime)
|
|
||||||
{
|
|
||||||
switch(objective.Id)
|
|
||||||
{
|
|
||||||
case "ReactorCommand": // Reactor commanded
|
|
||||||
if (!IsReactorPoweredUp())
|
|
||||||
{
|
|
||||||
if (!HasOrder("operatereactor")) return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "NavConsole": // traveled 50 meters
|
|
||||||
if (Vector2.Distance(subStartingPosition, Submarine.MainSub.WorldPosition) < 4000f)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "Flood": // Hull breaches repaired
|
|
||||||
if (IsFlooding()) return;
|
|
||||||
break;
|
|
||||||
case "Medical":
|
|
||||||
if (injuredMember != null && !injuredMember.IsDead)
|
|
||||||
{
|
|
||||||
if (injuredMember.CharacterHealth.DroppedItem == null) return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "EnemyOnSonar": // Enemy dispatched
|
|
||||||
if (HasEnemyOnSonarForDuration(deltaTime))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "Degrading": // Fixed
|
|
||||||
if (mechanic != null && !mechanic.IsDead)
|
|
||||||
{
|
|
||||||
HumanAIController humanAI = mechanic.AIController as HumanAIController;
|
|
||||||
if (mechanic.CurrentOrder?.AITag != "repairsystems" || humanAI.CurrentOrderOption != "jobspecific")
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (engineer != null && !engineer.IsDead)
|
|
||||||
{
|
|
||||||
HumanAIController humanAI = engineer.AIController as HumanAIController;
|
|
||||||
if (engineer.CurrentOrder?.AITag != "repairsystems" || humanAI.CurrentOrderOption != "jobspecific")
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case "Approach1": // Wait until docked
|
|
||||||
if (!Submarine.MainSub.AtEndPosition || Submarine.MainSub.DockedTo.Count == 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
RemoveCompletedObjective(objective);
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool IsReactorPoweredUp()
|
|
||||||
{
|
|
||||||
float load = 0.0f;
|
|
||||||
List<Connection> connections = reactor.Item.Connections;
|
|
||||||
if (connections != null && connections.Count > 0)
|
|
||||||
{
|
|
||||||
foreach (Connection connection in connections)
|
|
||||||
{
|
|
||||||
if (!connection.IsPower) continue;
|
|
||||||
foreach (Connection recipient in connection.Recipients)
|
|
||||||
{
|
|
||||||
if (!(recipient.Item is Item it)) continue;
|
|
||||||
|
|
||||||
PowerTransfer pt = it.GetComponent<PowerTransfer>();
|
|
||||||
if (pt == null) continue;
|
|
||||||
|
|
||||||
load = Math.Max(load, pt.PowerLoad);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Math.Abs(load + reactor.CurrPowerConsumption) < 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Character CrewMemberWithJob(string job)
|
|
||||||
{
|
|
||||||
job = job.ToLowerInvariant();
|
|
||||||
for (int i = 0; i < crew.Count; i++)
|
|
||||||
{
|
|
||||||
if (crew[i].Info.Job.Prefab.Identifier.ToLowerInvariant() == job) return crew[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool HasOrder(string aiTag, string option = null)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < crew.Count; i++)
|
|
||||||
{
|
|
||||||
if (crew[i].CurrentOrder?.AITag == aiTag)
|
|
||||||
{
|
|
||||||
if (option == null)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HumanAIController humanAI = crew[i].AIController as HumanAIController;
|
|
||||||
return humanAI.CurrentOrderOption == option;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool IsFlooding()
|
|
||||||
{
|
|
||||||
foreach (Gap gap in Gap.GapList)
|
|
||||||
{
|
|
||||||
if (gap.ConnectedWall == null || gap.IsRoomToRoom) continue;
|
|
||||||
if (gap.ConnectedDoor != null || gap.Open <= 0.0f) continue;
|
|
||||||
if (gap.Submarine == null) continue;
|
|
||||||
if (gap.Submarine.IsOutpost) continue;
|
|
||||||
if (gap.Submarine != Submarine.MainSub) continue;
|
|
||||||
if (gap.FlowTargetHull == null || gap.FlowTargetHull.WaterPercentage <= 0.0f) continue;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool HasEnemyOnSonarForDuration(float deltaTime)
|
|
||||||
{
|
|
||||||
foreach (Character c in Character.CharacterList)
|
|
||||||
{
|
|
||||||
if (c.AnimController.CurrentHull != null || !c.Enabled || !(c.AIController is EnemyAIController)) continue;
|
|
||||||
if (sonar.DetectSubmarineWalls && c.AnimController.CurrentHull == null && sonar.Item.CurrentHull != null) continue;
|
|
||||||
if (Vector2.DistanceSquared(c.WorldPosition, sonar.Item.WorldPosition) > sonar.Range * sonar.Range)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < characterTimeOnSonar.Count; i++)
|
|
||||||
{
|
|
||||||
if (characterTimeOnSonar[i].First == c)
|
|
||||||
{
|
|
||||||
characterTimeOnSonar.RemoveAt(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Pair<Character, float> pair = characterTimeOnSonar.Find(ct => ct.First == c);
|
|
||||||
if (pair != null)
|
|
||||||
{
|
|
||||||
pair.Second += deltaTime;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
characterTimeOnSonar.Add(new Pair<Character, float>(c, deltaTime));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return characterTimeOnSonar.Find(ct => ct.Second >= requiredTimeOnSonar && !ct.First.IsDead) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void TriggerTutorialSegment(int index, params object[] args)
|
|
||||||
{
|
|
||||||
base.TriggerTutorialSegment(index, args);
|
|
||||||
|
|
||||||
for (int i = 0; i < segments.Count; i++)
|
|
||||||
{
|
|
||||||
if (!segments[i].IsTriggered) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CoroutineManager.StartCoroutine(WaitToStop()); // Completed
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerable<object> WaitToStop()
|
|
||||||
{
|
|
||||||
while (ContentRunning) yield return null;
|
|
||||||
Stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
+93
-41
@@ -15,7 +15,7 @@ namespace Barotrauma.Tutorials
|
|||||||
private float shakeTimer = 1f;
|
private float shakeTimer = 1f;
|
||||||
private float shakeAmount = 20f;
|
private float shakeAmount = 20f;
|
||||||
|
|
||||||
private string radioSpeakerName;
|
private LocalizedString radioSpeakerName;
|
||||||
private Character doctor;
|
private Character doctor;
|
||||||
|
|
||||||
private ItemContainer doctor_suppliesCabinet;
|
private ItemContainer doctor_suppliesCabinet;
|
||||||
@@ -40,14 +40,66 @@ namespace Barotrauma.Tutorials
|
|||||||
private Sprite doctor_firstAidIcon;
|
private Sprite doctor_firstAidIcon;
|
||||||
private Color doctor_firstAidIconColor;
|
private Color doctor_firstAidIconColor;
|
||||||
|
|
||||||
public DoctorTutorial(XElement element) : base(element)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
public override void Start()
|
|
||||||
{
|
|
||||||
base.Start();
|
|
||||||
|
|
||||||
var firstAidOrder = Order.GetPrefab("requestfirstaid");
|
public DoctorTutorial() : base("tutorial.medicaldoctortraining".ToIdentifier(),
|
||||||
|
new Segment(
|
||||||
|
"Doctor.Supplies".ToIdentifier(),
|
||||||
|
"Doctor.SuppliesObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.TextOnly,
|
||||||
|
textContent: new Segment.Text { Tag = "Doctor.SuppliesText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center }),
|
||||||
|
new Segment(
|
||||||
|
"Doctor.OpenMedicalInterface".ToIdentifier(),
|
||||||
|
"Doctor.OpenMedicalInterfaceObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.ManualVideo,
|
||||||
|
textContent: new Segment.Text { Tag = "Doctor.OpenMedicalInterfaceText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center },
|
||||||
|
videoContent: new Segment.Video { File = "tutorial_medinterface1.webm", TextTag = "Doctor.OpenMedicalInterfaceText".ToIdentifier(), Width = 450, Height = 80 }),
|
||||||
|
new Segment(
|
||||||
|
"Doctor.FirstAidSelf".ToIdentifier(),
|
||||||
|
"Doctor.FirstAidSelfObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.ManualVideo,
|
||||||
|
textContent: new Segment.Text { Tag = "Doctor.FirstAidSelfText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center },
|
||||||
|
videoContent: new Segment.Video { File = "tutorial_medinterface1.webm", TextTag = "Doctor.FirstAidSelfText".ToIdentifier(), Width = 450, Height = 80 }),
|
||||||
|
new Segment(
|
||||||
|
"Doctor.Medbay".ToIdentifier(),
|
||||||
|
"Doctor.MedbayObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.ManualVideo,
|
||||||
|
textContent: new Segment.Text { Tag = "Doctor.MedbayText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center },
|
||||||
|
videoContent: new Segment.Video { File = "tutorial_command.webm", TextTag = "Doctor.MedbayText".ToIdentifier(), Width = 450, Height = 80 }),
|
||||||
|
new Segment(
|
||||||
|
"Doctor.TreatBurns".ToIdentifier(),
|
||||||
|
"Doctor.TreatBurnsObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.ManualVideo,
|
||||||
|
textContent: new Segment.Text { Tag = "Doctor.TreatBurnsText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center },
|
||||||
|
videoContent: new Segment.Video { File = "tutorial_medinterface2.webm", TextTag = "Doctor.TreatBurnsText".ToIdentifier(), Width = 450, Height = 80 }),
|
||||||
|
new Segment(
|
||||||
|
"Doctor.CPR".ToIdentifier(),
|
||||||
|
"Doctor.CPRObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.ManualVideo,
|
||||||
|
textContent: new Segment.Text { Tag = "Doctor.CPRText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center },
|
||||||
|
videoContent: new Segment.Video { File = "tutorial_cpr.webm", TextTag = "Doctor.CPRText".ToIdentifier(), Width = 450, Height = 80 }),
|
||||||
|
new Segment(
|
||||||
|
"Doctor.Submarine".ToIdentifier(),
|
||||||
|
"Doctor.SubmarineObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.TextOnly,
|
||||||
|
textContent: new Segment.Text { Tag = "Doctor.SubmarineText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center }))
|
||||||
|
{ }
|
||||||
|
|
||||||
|
protected override CharacterInfo GetCharacterInfo()
|
||||||
|
{
|
||||||
|
return new CharacterInfo(
|
||||||
|
CharacterPrefab.HumanSpeciesName,
|
||||||
|
jobOrJobPrefab: new Job(
|
||||||
|
JobPrefab.Prefabs["medicaldoctor"], Rand.RandSync.Unsynced, 0,
|
||||||
|
new Skill("medical".ToIdentifier(), 70),
|
||||||
|
new Skill("weapons".ToIdentifier(), 20),
|
||||||
|
new Skill("mechanical".ToIdentifier(), 20),
|
||||||
|
new Skill("electrical".ToIdentifier(), 20),
|
||||||
|
new Skill("helm".ToIdentifier(), 20)));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Initialize()
|
||||||
|
{
|
||||||
|
var firstAidOrder = OrderPrefab.Prefabs["requestfirstaid"];
|
||||||
doctor_firstAidIcon = firstAidOrder.SymbolSprite;
|
doctor_firstAidIcon = firstAidOrder.SymbolSprite;
|
||||||
doctor_firstAidIconColor = firstAidOrder.Color;
|
doctor_firstAidIconColor = firstAidOrder.Color;
|
||||||
|
|
||||||
@@ -55,19 +107,19 @@ namespace Barotrauma.Tutorials
|
|||||||
radioSpeakerName = TextManager.Get("Tutorial.Radio.Speaker");
|
radioSpeakerName = TextManager.Get("Tutorial.Radio.Speaker");
|
||||||
doctor = Character.Controlled;
|
doctor = Character.Controlled;
|
||||||
|
|
||||||
var bandages = FindOrGiveItem(doctor, "antibleeding1");
|
var bandages = FindOrGiveItem(doctor, "antibleeding1".ToIdentifier());
|
||||||
bandages.Unequip(doctor);
|
bandages.Unequip(doctor);
|
||||||
doctor.Inventory.RemoveItem(bandages);
|
doctor.Inventory.RemoveItem(bandages);
|
||||||
|
|
||||||
var syringegun = FindOrGiveItem(doctor, "syringegun");
|
var syringegun = FindOrGiveItem(doctor, "syringegun".ToIdentifier());
|
||||||
syringegun.Unequip(doctor);
|
syringegun.Unequip(doctor);
|
||||||
doctor.Inventory.RemoveItem(syringegun);
|
doctor.Inventory.RemoveItem(syringegun);
|
||||||
|
|
||||||
var antibiotics = FindOrGiveItem(doctor, "antibiotics");
|
var antibiotics = FindOrGiveItem(doctor, "antibiotics".ToIdentifier());
|
||||||
antibiotics.Unequip(doctor);
|
antibiotics.Unequip(doctor);
|
||||||
doctor.Inventory.RemoveItem(antibiotics);
|
doctor.Inventory.RemoveItem(antibiotics);
|
||||||
|
|
||||||
var morphine = FindOrGiveItem(doctor, "antidama1");
|
var morphine = FindOrGiveItem(doctor, "antidama1".ToIdentifier());
|
||||||
morphine.Unequip(doctor);
|
morphine.Unequip(doctor);
|
||||||
doctor.Inventory.RemoveItem(morphine);
|
doctor.Inventory.RemoveItem(morphine);
|
||||||
|
|
||||||
@@ -78,7 +130,7 @@ namespace Barotrauma.Tutorials
|
|||||||
var patientHull2 = WayPoint.WayPointList.Find(wp => wp.IdCardDesc == "airlock").CurrentHull;
|
var patientHull2 = WayPoint.WayPointList.Find(wp => wp.IdCardDesc == "airlock").CurrentHull;
|
||||||
medBay = WayPoint.WayPointList.Find(wp => wp.IdCardDesc == "medbay").CurrentHull;
|
medBay = WayPoint.WayPointList.Find(wp => wp.IdCardDesc == "medbay").CurrentHull;
|
||||||
|
|
||||||
var assistantInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("assistant"));
|
var assistantInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobOrJobPrefab: JobPrefab.Get("assistant"));
|
||||||
patient1 = Character.Create(assistantInfo, patientHull1.WorldPosition, "1");
|
patient1 = Character.Create(assistantInfo, patientHull1.WorldPosition, "1");
|
||||||
patient1.TeamID = CharacterTeamType.Team1;
|
patient1.TeamID = CharacterTeamType.Team1;
|
||||||
patient1.GiveJobItems(null);
|
patient1.GiveJobItems(null);
|
||||||
@@ -86,26 +138,26 @@ namespace Barotrauma.Tutorials
|
|||||||
patient1.AddDamage(patient1.WorldPosition, new List<Affliction>() { new Affliction(AfflictionPrefab.Burn, 15.0f) }, stun: 0, playSound: false);
|
patient1.AddDamage(patient1.WorldPosition, new List<Affliction>() { new Affliction(AfflictionPrefab.Burn, 15.0f) }, stun: 0, playSound: false);
|
||||||
patient1.AIController.Enabled = false;
|
patient1.AIController.Enabled = false;
|
||||||
|
|
||||||
assistantInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("assistant"));
|
assistantInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobOrJobPrefab: JobPrefab.Get("assistant"));
|
||||||
patient2 = Character.Create(assistantInfo, patientHull2.WorldPosition, "2");
|
patient2 = Character.Create(assistantInfo, patientHull2.WorldPosition, "2");
|
||||||
patient2.TeamID = CharacterTeamType.Team1;
|
patient2.TeamID = CharacterTeamType.Team1;
|
||||||
patient2.GiveJobItems(null);
|
patient2.GiveJobItems(null);
|
||||||
patient2.CanSpeak = false;
|
patient2.CanSpeak = false;
|
||||||
patient2.AIController.Enabled = false;
|
patient2.AIController.Enabled = false;
|
||||||
|
|
||||||
var mechanicInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("engineer"));
|
var mechanicInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobOrJobPrefab: JobPrefab.Get("engineer"));
|
||||||
var subPatient1 = Character.Create(mechanicInfo, WayPoint.GetRandom(SpawnType.Human, mechanicInfo.Job?.Prefab, Submarine.MainSub).WorldPosition, "3");
|
var subPatient1 = Character.Create(mechanicInfo, WayPoint.GetRandom(SpawnType.Human, mechanicInfo.Job?.Prefab, Submarine.MainSub).WorldPosition, "3");
|
||||||
subPatient1.TeamID = CharacterTeamType.Team1;
|
subPatient1.TeamID = CharacterTeamType.Team1;
|
||||||
subPatient1.AddDamage(patient1.WorldPosition, new List<Affliction>() { new Affliction(AfflictionPrefab.Burn, 40.0f) }, stun: 0, playSound: false);
|
subPatient1.AddDamage(patient1.WorldPosition, new List<Affliction>() { new Affliction(AfflictionPrefab.Burn, 40.0f) }, stun: 0, playSound: false);
|
||||||
subPatients.Add(subPatient1);
|
subPatients.Add(subPatient1);
|
||||||
|
|
||||||
var securityInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("securityofficer"));
|
var securityInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobOrJobPrefab: JobPrefab.Get("securityofficer"));
|
||||||
var subPatient2 = Character.Create(securityInfo, WayPoint.GetRandom(SpawnType.Human, securityInfo.Job?.Prefab, Submarine.MainSub).WorldPosition, "3");
|
var subPatient2 = Character.Create(securityInfo, WayPoint.GetRandom(SpawnType.Human, securityInfo.Job?.Prefab, Submarine.MainSub).WorldPosition, "3");
|
||||||
subPatient2.TeamID = CharacterTeamType.Team1;
|
subPatient2.TeamID = CharacterTeamType.Team1;
|
||||||
subPatient2.AddDamage(patient1.WorldPosition, new List<Affliction>() { new Affliction(AfflictionPrefab.InternalDamage, 40.0f) }, stun: 0, playSound: false);
|
subPatient2.AddDamage(patient1.WorldPosition, new List<Affliction>() { new Affliction(AfflictionPrefab.InternalDamage, 40.0f) }, stun: 0, playSound: false);
|
||||||
subPatients.Add(subPatient2);
|
subPatients.Add(subPatient2);
|
||||||
|
|
||||||
var engineerInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("engineer"));
|
var engineerInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobOrJobPrefab: JobPrefab.Get("engineer"));
|
||||||
var subPatient3 = Character.Create(securityInfo, WayPoint.GetRandom(SpawnType.Human, engineerInfo.Job?.Prefab, Submarine.MainSub).WorldPosition, "3");
|
var subPatient3 = Character.Create(securityInfo, WayPoint.GetRandom(SpawnType.Human, engineerInfo.Job?.Prefab, Submarine.MainSub).WorldPosition, "3");
|
||||||
subPatient3.TeamID = CharacterTeamType.Team1;
|
subPatient3.TeamID = CharacterTeamType.Team1;
|
||||||
subPatient3.AddDamage(patient1.WorldPosition, new List<Affliction>() { new Affliction(AfflictionPrefab.Burn, 20.0f) }, stun: 0, playSound: false);
|
subPatient3.AddDamage(patient1.WorldPosition, new List<Affliction>() { new Affliction(AfflictionPrefab.Burn, 20.0f) }, stun: 0, playSound: false);
|
||||||
@@ -196,7 +248,7 @@ namespace Barotrauma.Tutorials
|
|||||||
yield return new WaitForSeconds(2.0f);
|
yield return new WaitForSeconds(2.0f);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
TriggerTutorialSegment(0, GameMain.Config.KeyBindText(InputType.Select), GameMain.Config.KeyBindText(InputType.Deselect), GameMain.Config.KeyBindText(InputType.ToggleInventory)); // Medical supplies objective
|
TriggerTutorialSegment(0, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Select), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Deselect), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.ToggleInventory)); // Medical supplies objective
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@@ -215,24 +267,24 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
yield return null;
|
yield return null;
|
||||||
} while (doctor.Inventory.FindItemByIdentifier("antidama1") == null); // Wait until looted
|
} while (doctor.Inventory.FindItemByIdentifier("antidama1".ToIdentifier()) == null); // Wait until looted
|
||||||
yield return new WaitForSeconds(1.0f, false);
|
yield return new WaitForSeconds(1.0f, false);
|
||||||
|
|
||||||
SetHighlight(doctor_suppliesCabinet.Item, false);
|
SetHighlight(doctor_suppliesCabinet.Item, false);
|
||||||
RemoveCompletedObjective(segments[0]);
|
RemoveCompletedObjective(0);
|
||||||
|
|
||||||
yield return new WaitForSeconds(1.0f, false);
|
yield return new WaitForSeconds(1.0f, false);
|
||||||
|
|
||||||
// 2nd tutorial segment, treat self -------------------------------------------------------------------------
|
// 2nd tutorial segment, treat self -------------------------------------------------------------------------
|
||||||
|
|
||||||
TriggerTutorialSegment(1, GameMain.Config.KeyBindText(InputType.Health)); // Open health interface
|
TriggerTutorialSegment(1, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Health)); // Open health interface
|
||||||
while (CharacterHealth.OpenHealthWindow == null)
|
while (CharacterHealth.OpenHealthWindow == null)
|
||||||
{
|
{
|
||||||
doctor.CharacterHealth.HealthBarPulsateTimer = 1.0f;
|
doctor.CharacterHealth.HealthBarPulsateTimer = 1.0f;
|
||||||
yield return null;
|
yield return null;
|
||||||
}
|
}
|
||||||
yield return null;
|
yield return null;
|
||||||
RemoveCompletedObjective(segments[1]);
|
RemoveCompletedObjective(1);
|
||||||
yield return new WaitForSeconds(1.0f, false);
|
yield return new WaitForSeconds(1.0f, false);
|
||||||
TriggerTutorialSegment(2); //Treat self
|
TriggerTutorialSegment(2); //Treat self
|
||||||
while (doctor.CharacterHealth.GetAfflictionStrength("damage") > 0.01f)
|
while (doctor.CharacterHealth.GetAfflictionStrength("damage") > 0.01f)
|
||||||
@@ -243,13 +295,13 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HighlightInventorySlot(doctor.Inventory, "antidama1", highlightColor, .5f, .5f, 0f);
|
HighlightInventorySlot(doctor.Inventory, "antidama1".ToIdentifier(), highlightColor, .5f, .5f, 0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
yield return null;
|
yield return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoveCompletedObjective(segments[2]);
|
RemoveCompletedObjective(2);
|
||||||
SetDoorAccess(doctor_firstDoor, doctor_firstDoorLight, true);
|
SetDoorAccess(doctor_firstDoor, doctor_firstDoorLight, true);
|
||||||
|
|
||||||
while (CharacterHealth.OpenHealthWindow != null)
|
while (CharacterHealth.OpenHealthWindow != null)
|
||||||
@@ -260,10 +312,10 @@ namespace Barotrauma.Tutorials
|
|||||||
// treat patient --------------------------------------------------------------------------------------------
|
// treat patient --------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
//patient 1 requests first aid
|
//patient 1 requests first aid
|
||||||
var newOrder = new Order(Order.GetPrefab("requestfirstaid"), patient1.CurrentHull, null, orderGiver: patient1);
|
var newOrder = new Order(OrderPrefab.Prefabs["requestfirstaid"], patient1.CurrentHull, null, orderGiver: patient1);
|
||||||
doctor.AddActiveObjectiveEntity(patient1, doctor_firstAidIcon, doctor_firstAidIconColor);
|
doctor.AddActiveObjectiveEntity(patient1, doctor_firstAidIcon, doctor_firstAidIconColor);
|
||||||
//GameMain.GameSession.CrewManager.AddOrder(newOrder, newOrder.FadeOutTime);
|
//GameMain.GameSession.CrewManager.AddOrder(newOrder, newOrder.FadeOutTime);
|
||||||
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(patient1.Name, newOrder.GetChatMessage("", patient1.CurrentHull?.DisplayName, givingOrderToSelf: false), ChatMessageType.Order, null);
|
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(patient1.Name, newOrder.GetChatMessage("", patient1.CurrentHull?.DisplayName?.Value, givingOrderToSelf: false), ChatMessageType.Order, null);
|
||||||
|
|
||||||
while (doctor.CurrentHull != patient1.CurrentHull)
|
while (doctor.CurrentHull != patient1.CurrentHull)
|
||||||
{
|
{
|
||||||
@@ -281,9 +333,9 @@ namespace Barotrauma.Tutorials
|
|||||||
yield return new WaitForSeconds(3.0f, false);
|
yield return new WaitForSeconds(3.0f, false);
|
||||||
patient1.AIController.Enabled = true;
|
patient1.AIController.Enabled = true;
|
||||||
doctor.RemoveActiveObjectiveEntity(patient1);
|
doctor.RemoveActiveObjectiveEntity(patient1);
|
||||||
TriggerTutorialSegment(3, GameMain.Config.KeyBindText(InputType.Command)); // Get the patient to medbay
|
TriggerTutorialSegment(3, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Command)); // Get the patient to medbay
|
||||||
|
|
||||||
while (patient1.GetCurrentOrderWithTopPriority()?.Order?.Identifier != "follow")
|
while (patient1.GetCurrentOrderWithTopPriority()?.Identifier != "follow")
|
||||||
{
|
{
|
||||||
// TODO: Rework order highlighting for new command UI
|
// TODO: Rework order highlighting for new command UI
|
||||||
// GameMain.GameSession.CrewManager.HighlightOrderButton(patient1, "follow", highlightColor, new Vector2(5, 5));
|
// GameMain.GameSession.CrewManager.HighlightOrderButton(patient1, "follow", highlightColor, new Vector2(5, 5));
|
||||||
@@ -296,14 +348,14 @@ namespace Barotrauma.Tutorials
|
|||||||
{
|
{
|
||||||
yield return new WaitForSeconds(1.0f, false);
|
yield return new WaitForSeconds(1.0f, false);
|
||||||
}
|
}
|
||||||
RemoveCompletedObjective(segments[3]);
|
RemoveCompletedObjective(3);
|
||||||
SetHighlight(doctor_medBayCabinet.Item, true);
|
SetHighlight(doctor_medBayCabinet.Item, true);
|
||||||
SetDoorAccess(doctor_thirdDoor, doctor_thirdDoorLight, true);
|
SetDoorAccess(doctor_thirdDoor, doctor_thirdDoorLight, true);
|
||||||
patient1.CharacterHealth.UseHealthWindow = true;
|
patient1.CharacterHealth.UseHealthWindow = true;
|
||||||
|
|
||||||
yield return new WaitForSeconds(2.0f, false);
|
yield return new WaitForSeconds(2.0f, false);
|
||||||
|
|
||||||
TriggerTutorialSegment(4, GameMain.Config.KeyBindText(InputType.Health)); // treat burns
|
TriggerTutorialSegment(4, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Health)); // treat burns
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@@ -322,7 +374,7 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
yield return null;
|
yield return null;
|
||||||
} while (doctor.Inventory.FindItemByIdentifier("antibleeding1") == null); // Wait until looted
|
} while (doctor.Inventory.FindItemByIdentifier("antibleeding1".ToIdentifier()) == null); // Wait until looted
|
||||||
SetHighlight(doctor_medBayCabinet.Item, false);
|
SetHighlight(doctor_medBayCabinet.Item, false);
|
||||||
SetHighlight(patient1, true);
|
SetHighlight(patient1, true);
|
||||||
|
|
||||||
@@ -334,12 +386,12 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HighlightInventorySlot(doctor.Inventory, "antibleeding1", highlightColor, .5f, .5f, 0f);
|
HighlightInventorySlot(doctor.Inventory, "antibleeding1".ToIdentifier(), highlightColor, .5f, .5f, 0f);
|
||||||
}
|
}
|
||||||
yield return null;
|
yield return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
RemoveCompletedObjective(segments[4]);
|
RemoveCompletedObjective(4);
|
||||||
SetHighlight(patient1, false);
|
SetHighlight(patient1, false);
|
||||||
yield return new WaitForSeconds(1.0f, false);
|
yield return new WaitForSeconds(1.0f, false);
|
||||||
|
|
||||||
@@ -350,10 +402,10 @@ namespace Barotrauma.Tutorials
|
|||||||
//patient calls for help
|
//patient calls for help
|
||||||
//patient2.CanSpeak = true;
|
//patient2.CanSpeak = true;
|
||||||
yield return new WaitForSeconds(2.0f, false);
|
yield return new WaitForSeconds(2.0f, false);
|
||||||
newOrder = new Order(Order.GetPrefab("requestfirstaid"), patient2.CurrentHull, null, orderGiver: patient2);
|
newOrder = new Order(OrderPrefab.Prefabs["requestfirstaid"], patient2.CurrentHull, null, orderGiver: patient2);
|
||||||
doctor.AddActiveObjectiveEntity(patient2, doctor_firstAidIcon, doctor_firstAidIconColor);
|
doctor.AddActiveObjectiveEntity(patient2, doctor_firstAidIcon, doctor_firstAidIconColor);
|
||||||
//GameMain.GameSession.CrewManager.AddOrder(newOrder, newOrder.FadeOutTime);
|
//GameMain.GameSession.CrewManager.AddOrder(newOrder, newOrder.FadeOutTime);
|
||||||
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(patient2.Name, newOrder.GetChatMessage("", patient1.CurrentHull?.DisplayName, givingOrderToSelf: false), ChatMessageType.Order, null);
|
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(patient2.Name, newOrder.GetChatMessage("", patient1.CurrentHull?.DisplayName?.Value, givingOrderToSelf: false), ChatMessageType.Order, null);
|
||||||
patient2.AIController.Enabled = true;
|
patient2.AIController.Enabled = true;
|
||||||
patient2.Oxygen = -50;
|
patient2.Oxygen = -50;
|
||||||
CoroutineManager.StartCoroutine(KeepPatientAlive(patient2), "KeepPatient2Alive");
|
CoroutineManager.StartCoroutine(KeepPatientAlive(patient2), "KeepPatient2Alive");
|
||||||
@@ -365,7 +417,7 @@ namespace Barotrauma.Tutorials
|
|||||||
do { yield return null; } while (!tutorial_upperFinalDoor.IsOpen);
|
do { yield return null; } while (!tutorial_upperFinalDoor.IsOpen);
|
||||||
yield return new WaitForSeconds(2.0f, false);
|
yield return new WaitForSeconds(2.0f, false);
|
||||||
|
|
||||||
TriggerTutorialSegment(5, GameMain.Config.KeyBindText(InputType.Health)); // perform CPR
|
TriggerTutorialSegment(5, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Health)); // perform CPR
|
||||||
SetHighlight(patient2, true);
|
SetHighlight(patient2, true);
|
||||||
while (patient2.IsUnconscious)
|
while (patient2.IsUnconscious)
|
||||||
{
|
{
|
||||||
@@ -380,7 +432,7 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
yield return null;
|
yield return null;
|
||||||
}
|
}
|
||||||
RemoveCompletedObjective(segments[5]);
|
RemoveCompletedObjective(5);
|
||||||
SetHighlight(patient2, false);
|
SetHighlight(patient2, false);
|
||||||
doctor.RemoveActiveObjectiveEntity(patient2);
|
doctor.RemoveActiveObjectiveEntity(patient2);
|
||||||
CoroutineManager.StopCoroutines("KeepPatient2Alive");
|
CoroutineManager.StopCoroutines("KeepPatient2Alive");
|
||||||
@@ -399,7 +451,7 @@ namespace Barotrauma.Tutorials
|
|||||||
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Doctor.Radio.EnteredSub"), ChatMessageType.Radio, null);
|
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Doctor.Radio.EnteredSub"), ChatMessageType.Radio, null);
|
||||||
|
|
||||||
yield return new WaitForSeconds(3.0f, false);
|
yield return new WaitForSeconds(3.0f, false);
|
||||||
TriggerTutorialSegment(6, GameMain.Config.KeyBindText(InputType.Health)); // give treatment to anyone in need
|
TriggerTutorialSegment(6, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Health)); // give treatment to anyone in need
|
||||||
|
|
||||||
foreach (var patient in subPatients)
|
foreach (var patient in subPatients)
|
||||||
{
|
{
|
||||||
@@ -421,8 +473,8 @@ namespace Barotrauma.Tutorials
|
|||||||
if (!patientCalledHelp[i] && Timing.TotalTime > subEnterTime + 60 * (i + 1))
|
if (!patientCalledHelp[i] && Timing.TotalTime > subEnterTime + 60 * (i + 1))
|
||||||
{
|
{
|
||||||
doctor.AddActiveObjectiveEntity(subPatients[i], doctor_firstAidIcon, doctor_firstAidIconColor);
|
doctor.AddActiveObjectiveEntity(subPatients[i], doctor_firstAidIcon, doctor_firstAidIconColor);
|
||||||
newOrder = new Order(Order.GetPrefab("requestfirstaid"), subPatients[i].CurrentHull, null, orderGiver: subPatients[i]);
|
newOrder = new Order(OrderPrefab.Prefabs["requestfirstaid"], subPatients[i].CurrentHull, null, orderGiver: subPatients[i]);
|
||||||
string message = newOrder.GetChatMessage("", subPatients[i].CurrentHull?.DisplayName, givingOrderToSelf: false);
|
string message = newOrder.GetChatMessage("", subPatients[i].CurrentHull?.DisplayName?.Value, givingOrderToSelf: false);
|
||||||
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(subPatients[i].Name, message, ChatMessageType.Order, null);
|
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(subPatients[i].Name, message, ChatMessageType.Order, null);
|
||||||
patientCalledHelp[i] = true;
|
patientCalledHelp[i] = true;
|
||||||
}
|
}
|
||||||
@@ -435,7 +487,7 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
yield return new WaitForSeconds(1.0f, false);
|
yield return new WaitForSeconds(1.0f, false);
|
||||||
}
|
}
|
||||||
RemoveCompletedObjective(segments[6]);
|
RemoveCompletedObjective(6);
|
||||||
foreach (var patient in subPatients)
|
foreach (var patient in subPatients)
|
||||||
{
|
{
|
||||||
SetHighlight(patient, false);
|
SetHighlight(patient, false);
|
||||||
|
|||||||
-44
@@ -1,44 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Xml.Linq;
|
|
||||||
|
|
||||||
namespace Barotrauma.Tutorials
|
|
||||||
{
|
|
||||||
class EditorTutorial : Tutorial
|
|
||||||
{
|
|
||||||
public EditorTutorial(XElement element)
|
|
||||||
: base (element)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override IEnumerable<CoroutineStatus> UpdateState()
|
|
||||||
{
|
|
||||||
/*infoBox = CreateInfoFrame("Use the mouse wheel to zoom in and out, and WASD to move the camera around.", true);
|
|
||||||
|
|
||||||
while (infoBox != null)
|
|
||||||
{
|
|
||||||
yield return CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("Press \"Structure\" at the left side of the screen to start placing some walls.");
|
|
||||||
|
|
||||||
while (GameMain.SubEditorScreen.SelectedTab != (int)MapEntityCategory.Structure)
|
|
||||||
{
|
|
||||||
yield return CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("Select \"topwall\" from the list.", true);
|
|
||||||
|
|
||||||
while (MapEntityPrefab.Selected == null || MapEntityPrefab.Selected.Name != "topwall")
|
|
||||||
{
|
|
||||||
yield return CoroutineStatus.Running;
|
|
||||||
}
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("You can now create a horizontal wall by clicking and dragging. When you're done, right click to stop creating walls.");*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
yield return CoroutineStatus.Success;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+73
-26
@@ -62,7 +62,7 @@ namespace Barotrauma.Tutorials
|
|||||||
private Reactor engineer_submarineReactor;
|
private Reactor engineer_submarineReactor;
|
||||||
|
|
||||||
// Variables
|
// Variables
|
||||||
private string radioSpeakerName;
|
private LocalizedString radioSpeakerName;
|
||||||
private Character engineer;
|
private Character engineer;
|
||||||
private int[] reactorLoads = new int[5] { 1500, 3000, 2000, 5000, 3500 };
|
private int[] reactorLoads = new int[5] { 1500, 3000, 2000, 5000, 3500 };
|
||||||
private float reactorLoadChangeTime = 2f;
|
private float reactorLoadChangeTime = 2f;
|
||||||
@@ -75,27 +75,74 @@ namespace Barotrauma.Tutorials
|
|||||||
private Color engineer_reactorIconColor;
|
private Color engineer_reactorIconColor;
|
||||||
private bool wiringActive = false;
|
private bool wiringActive = false;
|
||||||
|
|
||||||
public EngineerTutorial(XElement element) : base(element)
|
public EngineerTutorial() : base("tutorial.engineertraining".ToIdentifier(),
|
||||||
{
|
new Segment(
|
||||||
|
"Mechanic.Equipment".ToIdentifier(),
|
||||||
|
"Mechanic.EquipmentObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.TextOnly,
|
||||||
|
textContent: new Segment.Text { Tag = "Mechanic.EquipmentText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center }),
|
||||||
|
new Segment(
|
||||||
|
"Engineer.Reactor".ToIdentifier(),
|
||||||
|
"Engineer.ReactorObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.ManualVideo,
|
||||||
|
textContent: new Segment.Text { Tag = "Engineer.ReactorText".ToIdentifier(), Width = 700, Height = 80, Anchor = Anchor.Center },
|
||||||
|
videoContent: new Segment.Video { File = "tutorial_reactor.webm", TextTag = "Engineer.ReactorText".ToIdentifier(), Width = 700, Height = 80 }),
|
||||||
|
new Segment(
|
||||||
|
"Engineer.OperateReactor".ToIdentifier(),
|
||||||
|
"Engineer.OperateReactorObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.ManualVideo,
|
||||||
|
textContent: new Segment.Text { Tag = "Engineer.OperateReactorText".ToIdentifier(), Width = 700, Height = 80, Anchor = Anchor.Center },
|
||||||
|
videoContent: new Segment.Video { File = "tutorial_reactor.webm", TextTag = "Engineer.ReactorText".ToIdentifier(), Width = 700, Height = 80 }),
|
||||||
|
new Segment(
|
||||||
|
"Engineer.RepairJunctionBox".ToIdentifier(),
|
||||||
|
"Engineer.RepairJunctionBoxObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.TextOnly,
|
||||||
|
textContent: new Segment.Text { Tag = "Engineer.RepairJunctionBoxText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center }),
|
||||||
|
new Segment(
|
||||||
|
"Engineer.WireJunctionBoxes".ToIdentifier(),
|
||||||
|
"Engineer.WireJunctionBoxesObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.ManualVideo,
|
||||||
|
textContent: new Segment.Text { Tag = "Engineer.WireJunctionBoxesText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center },
|
||||||
|
videoContent: new Segment.Video { File = "tutorial_wiring.webm", TextTag = "Engineer.WireJunctionBoxesText".ToIdentifier(), Width = 450, Height = 80 }),
|
||||||
|
new Segment(
|
||||||
|
"Engineer.RepairElectricalRoom".ToIdentifier(),
|
||||||
|
"Engineer.RepairElectricalRoomObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.TextOnly,
|
||||||
|
textContent: new Segment.Text { Tag = "Engineer.RepairElectricalRoomText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center }),
|
||||||
|
new Segment(
|
||||||
|
"Engineer.PowerUpReactor".ToIdentifier(),
|
||||||
|
"Engineer.PowerUpReactorObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.TextOnly,
|
||||||
|
textContent: new Segment.Text { Tag = "Engineer.PowerUpReactorText".ToIdentifier(), Width = 700, Height = 80, Anchor = Anchor.Center }))
|
||||||
|
{ }
|
||||||
|
|
||||||
|
protected override CharacterInfo GetCharacterInfo()
|
||||||
|
{
|
||||||
|
return new CharacterInfo(
|
||||||
|
CharacterPrefab.HumanSpeciesName,
|
||||||
|
jobOrJobPrefab: new Job(
|
||||||
|
JobPrefab.Prefabs["engineer"], Rand.RandSync.Unsynced, 0,
|
||||||
|
new Skill("medical".ToIdentifier(), 0),
|
||||||
|
new Skill("weapons".ToIdentifier(), 0),
|
||||||
|
new Skill("mechanical".ToIdentifier(), 20),
|
||||||
|
new Skill("electrical".ToIdentifier(), 60),
|
||||||
|
new Skill("helm".ToIdentifier(), 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Start()
|
protected override void Initialize()
|
||||||
{
|
{
|
||||||
base.Start();
|
|
||||||
|
|
||||||
radioSpeakerName = TextManager.Get("Tutorial.Radio.Speaker");
|
radioSpeakerName = TextManager.Get("Tutorial.Radio.Speaker");
|
||||||
engineer = Character.Controlled;
|
engineer = Character.Controlled;
|
||||||
|
|
||||||
var toolbelt = FindOrGiveItem(engineer, "toolbelt");
|
var toolbelt = FindOrGiveItem(engineer, "toolbelt".ToIdentifier());
|
||||||
toolbelt.Unequip(engineer);
|
toolbelt.Unequip(engineer);
|
||||||
engineer.Inventory.RemoveItem(toolbelt);
|
engineer.Inventory.RemoveItem(toolbelt);
|
||||||
|
|
||||||
var repairOrder = Order.GetPrefab("repairsystems");
|
var repairOrder = OrderPrefab.Prefabs["repairsystems"];
|
||||||
engineer_repairIcon = repairOrder.SymbolSprite;
|
engineer_repairIcon = repairOrder.SymbolSprite;
|
||||||
engineer_repairIconColor = repairOrder.Color;
|
engineer_repairIconColor = repairOrder.Color;
|
||||||
|
|
||||||
var reactorOrder = Order.GetPrefab("operatereactor");
|
var reactorOrder = OrderPrefab.Prefabs["operatereactor"];
|
||||||
engineer_reactorIcon = reactorOrder.SymbolSprite;
|
engineer_reactorIcon = reactorOrder.SymbolSprite;
|
||||||
engineer_reactorIconColor = reactorOrder.Color;
|
engineer_reactorIconColor = reactorOrder.Color;
|
||||||
|
|
||||||
@@ -235,7 +282,7 @@ namespace Barotrauma.Tutorials
|
|||||||
do { yield return null; } while (!engineer_equipmentObjectiveSensor.MotionDetected);
|
do { yield return null; } while (!engineer_equipmentObjectiveSensor.MotionDetected);
|
||||||
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Engineer.Radio.Equipment"), ChatMessageType.Radio, null);
|
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Engineer.Radio.Equipment"), ChatMessageType.Radio, null);
|
||||||
yield return new WaitForSeconds(0.5f, false);
|
yield return new WaitForSeconds(0.5f, false);
|
||||||
TriggerTutorialSegment(0, GameMain.Config.KeyBindText(InputType.Select), GameMain.Config.KeyBindText(InputType.Deselect), GameMain.Config.KeyBindText(InputType.ToggleInventory)); // Retrieve equipment
|
TriggerTutorialSegment(0, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Select), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Deselect), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.ToggleInventory)); // Retrieve equipment
|
||||||
bool firstSlotRemoved = false;
|
bool firstSlotRemoved = false;
|
||||||
bool secondSlotRemoved = false;
|
bool secondSlotRemoved = false;
|
||||||
bool thirdSlotRemoved = false;
|
bool thirdSlotRemoved = false;
|
||||||
@@ -276,7 +323,7 @@ namespace Barotrauma.Tutorials
|
|||||||
|
|
||||||
yield return null;
|
yield return null;
|
||||||
} while (!engineer_equipmentCabinet.Inventory.IsEmpty()); // Wait until looted
|
} while (!engineer_equipmentCabinet.Inventory.IsEmpty()); // Wait until looted
|
||||||
RemoveCompletedObjective(segments[0]);
|
RemoveCompletedObjective(0);
|
||||||
SetHighlight(engineer_equipmentCabinet.Item, false);
|
SetHighlight(engineer_equipmentCabinet.Item, false);
|
||||||
SetHighlight(engineer_reactor.Item, true);
|
SetHighlight(engineer_reactor.Item, true);
|
||||||
SetDoorAccess(engineer_firstDoor, engineer_firstDoorLight, true);
|
SetDoorAccess(engineer_firstDoor, engineer_firstDoorLight, true);
|
||||||
@@ -302,7 +349,7 @@ namespace Barotrauma.Tutorials
|
|||||||
if (IsSelectedItem(engineer_reactor.Item) && engineer_reactor.Item.OwnInventory.visualSlots != null)
|
if (IsSelectedItem(engineer_reactor.Item) && engineer_reactor.Item.OwnInventory.visualSlots != null)
|
||||||
{
|
{
|
||||||
engineer_reactor.AutoTemp = false;
|
engineer_reactor.AutoTemp = false;
|
||||||
HighlightInventorySlot(engineer.Inventory, "fuelrod", highlightColor, 0.5f, 0.5f, 0f);
|
HighlightInventorySlot(engineer.Inventory, "fuelrod".ToIdentifier(), highlightColor, 0.5f, 0.5f, 0f);
|
||||||
|
|
||||||
for (int i = 0; i < engineer_reactor.Item.OwnInventory.visualSlots.Length; i++)
|
for (int i = 0; i < engineer_reactor.Item.OwnInventory.visualSlots.Length; i++)
|
||||||
{
|
{
|
||||||
@@ -311,7 +358,7 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
yield return null;
|
yield return null;
|
||||||
} while (engineer_reactor.AvailableFuel == 0);
|
} while (engineer_reactor.AvailableFuel == 0);
|
||||||
RemoveCompletedObjective(segments[1]);
|
RemoveCompletedObjective(1);
|
||||||
TriggerTutorialSegment(2);
|
TriggerTutorialSegment(2);
|
||||||
CoroutineManager.StartCoroutine(ReactorOperatedProperly());
|
CoroutineManager.StartCoroutine(ReactorOperatedProperly());
|
||||||
do
|
do
|
||||||
@@ -354,7 +401,7 @@ namespace Barotrauma.Tutorials
|
|||||||
} while (wait > 0.0f);
|
} while (wait > 0.0f);
|
||||||
engineer.SelectedConstruction = null;
|
engineer.SelectedConstruction = null;
|
||||||
engineer_reactor.CanBeSelected = false;
|
engineer_reactor.CanBeSelected = false;
|
||||||
RemoveCompletedObjective(segments[2]);
|
RemoveCompletedObjective(2);
|
||||||
SetHighlight(engineer_reactor.Item, false);
|
SetHighlight(engineer_reactor.Item, false);
|
||||||
SetHighlight(engineer_brokenJunctionBox, true);
|
SetHighlight(engineer_brokenJunctionBox, true);
|
||||||
SetDoorAccess(engineer_secondDoor, engineer_secondDoorLight, true);
|
SetDoorAccess(engineer_secondDoor, engineer_secondDoorLight, true);
|
||||||
@@ -363,12 +410,12 @@ namespace Barotrauma.Tutorials
|
|||||||
do { yield return null; } while (!engineer_secondDoor.IsOpen);
|
do { yield return null; } while (!engineer_secondDoor.IsOpen);
|
||||||
yield return new WaitForSeconds(1f, false);
|
yield return new WaitForSeconds(1f, false);
|
||||||
Repairable repairableJunctionBoxComponent = engineer_brokenJunctionBox.GetComponent<Repairable>();
|
Repairable repairableJunctionBoxComponent = engineer_brokenJunctionBox.GetComponent<Repairable>();
|
||||||
TriggerTutorialSegment(3, GameMain.Config.KeyBindText(InputType.Select)); // Repair the junction box
|
TriggerTutorialSegment(3, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Select)); // Repair the junction box
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (!engineer.HasEquippedItem("screwdriver"))
|
if (!engineer.HasEquippedItem("screwdriver".ToIdentifier()))
|
||||||
{
|
{
|
||||||
HighlightInventorySlot(engineer.Inventory, "screwdriver", highlightColor, .5f, .5f, 0f);
|
HighlightInventorySlot(engineer.Inventory, "screwdriver".ToIdentifier(), highlightColor, .5f, .5f, 0f);
|
||||||
}
|
}
|
||||||
else if (IsSelectedItem(engineer_brokenJunctionBox) && repairableJunctionBoxComponent.CurrentFixer == null)
|
else if (IsSelectedItem(engineer_brokenJunctionBox) && repairableJunctionBoxComponent.CurrentFixer == null)
|
||||||
{
|
{
|
||||||
@@ -380,7 +427,7 @@ namespace Barotrauma.Tutorials
|
|||||||
yield return null;
|
yield return null;
|
||||||
} while (repairableJunctionBoxComponent.IsBelowRepairThreshold); // Wait until repaired
|
} while (repairableJunctionBoxComponent.IsBelowRepairThreshold); // Wait until repaired
|
||||||
SetHighlight(engineer_brokenJunctionBox, false);
|
SetHighlight(engineer_brokenJunctionBox, false);
|
||||||
RemoveCompletedObjective(segments[3]);
|
RemoveCompletedObjective(3);
|
||||||
SetDoorAccess(engineer_thirdDoor, engineer_thirdDoorLight, true);
|
SetDoorAccess(engineer_thirdDoor, engineer_thirdDoorLight, true);
|
||||||
for (int i = 0; i < engineer_disconnectedJunctionBoxes.Length; i++)
|
for (int i = 0; i < engineer_disconnectedJunctionBoxes.Length; i++)
|
||||||
{
|
{
|
||||||
@@ -391,14 +438,14 @@ namespace Barotrauma.Tutorials
|
|||||||
do { yield return null; } while (!engineer_thirdDoor.IsOpen);
|
do { yield return null; } while (!engineer_thirdDoor.IsOpen);
|
||||||
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Engineer.Radio.FaultyWiring"), ChatMessageType.Radio, null);
|
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Engineer.Radio.FaultyWiring"), ChatMessageType.Radio, null);
|
||||||
yield return new WaitForSeconds(2f, false);
|
yield return new WaitForSeconds(2f, false);
|
||||||
TriggerTutorialSegment(4, GameMain.Config.KeyBindText(InputType.Use), GameMain.Config.KeyBindText(InputType.Deselect)); // Connect the junction boxes
|
TriggerTutorialSegment(4, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Use), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Deselect)); // Connect the junction boxes
|
||||||
do { CheckGhostWires(); HandleJunctionBoxWiringHighlights(); yield return null; } while (engineer_workingPump.Voltage < engineer_workingPump.MinVoltage); // Wait until connected all the way to the pump
|
do { CheckGhostWires(); HandleJunctionBoxWiringHighlights(); yield return null; } while (engineer_workingPump.Voltage < engineer_workingPump.MinVoltage); // Wait until connected all the way to the pump
|
||||||
CheckGhostWires();
|
CheckGhostWires();
|
||||||
for (int i = 0; i < engineer_disconnectedJunctionBoxes.Length; i++)
|
for (int i = 0; i < engineer_disconnectedJunctionBoxes.Length; i++)
|
||||||
{
|
{
|
||||||
SetHighlight(engineer_disconnectedJunctionBoxes[i].Item, false);
|
SetHighlight(engineer_disconnectedJunctionBoxes[i].Item, false);
|
||||||
}
|
}
|
||||||
RemoveCompletedObjective(segments[4]);
|
RemoveCompletedObjective(4);
|
||||||
do { yield return null; } while (engineer_workingPump.Item.CurrentHull.WaterPercentage > waterVolumeBeforeOpening); // Wait until drained
|
do { yield return null; } while (engineer_workingPump.Item.CurrentHull.WaterPercentage > waterVolumeBeforeOpening); // Wait until drained
|
||||||
wiringActive = false;
|
wiringActive = false;
|
||||||
SetDoorAccess(engineer_fourthDoor, engineer_fourthDoorLight, true);
|
SetDoorAccess(engineer_fourthDoor, engineer_fourthDoorLight, true);
|
||||||
@@ -424,7 +471,7 @@ namespace Barotrauma.Tutorials
|
|||||||
// Remove highlights when each individual machine is repaired
|
// Remove highlights when each individual machine is repaired
|
||||||
do { CheckJunctionBoxHighlights(repairableJunctionBoxComponent1, repairableJunctionBoxComponent2, repairableJunctionBoxComponent3); yield return null; } while (repairableJunctionBoxComponent1.IsBelowRepairThreshold || repairableJunctionBoxComponent2.IsBelowRepairThreshold || repairableJunctionBoxComponent3.IsBelowRepairThreshold);
|
do { CheckJunctionBoxHighlights(repairableJunctionBoxComponent1, repairableJunctionBoxComponent2, repairableJunctionBoxComponent3); yield return null; } while (repairableJunctionBoxComponent1.IsBelowRepairThreshold || repairableJunctionBoxComponent2.IsBelowRepairThreshold || repairableJunctionBoxComponent3.IsBelowRepairThreshold);
|
||||||
CheckJunctionBoxHighlights(repairableJunctionBoxComponent1, repairableJunctionBoxComponent2, repairableJunctionBoxComponent3);
|
CheckJunctionBoxHighlights(repairableJunctionBoxComponent1, repairableJunctionBoxComponent2, repairableJunctionBoxComponent3);
|
||||||
RemoveCompletedObjective(segments[5]);
|
RemoveCompletedObjective(5);
|
||||||
yield return new WaitForSeconds(2f, false);
|
yield return new WaitForSeconds(2f, false);
|
||||||
|
|
||||||
TriggerTutorialSegment(6); // Powerup reactor
|
TriggerTutorialSegment(6); // Powerup reactor
|
||||||
@@ -433,7 +480,7 @@ namespace Barotrauma.Tutorials
|
|||||||
do { yield return null; } while (!IsReactorPoweredUp(engineer_submarineReactor)); // Wait until ~matches load
|
do { yield return null; } while (!IsReactorPoweredUp(engineer_submarineReactor)); // Wait until ~matches load
|
||||||
engineer.RemoveActiveObjectiveEntity(engineer_submarineReactor.Item);
|
engineer.RemoveActiveObjectiveEntity(engineer_submarineReactor.Item);
|
||||||
SetHighlight(engineer_submarineReactor.Item, false);
|
SetHighlight(engineer_submarineReactor.Item, false);
|
||||||
RemoveCompletedObjective(segments[6]);
|
RemoveCompletedObjective(6);
|
||||||
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Engineer.Radio.Complete"), ChatMessageType.Radio, null);
|
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Engineer.Radio.Complete"), ChatMessageType.Radio, null);
|
||||||
|
|
||||||
yield return new WaitForSeconds(4f, false);
|
yield return new WaitForSeconds(4f, false);
|
||||||
@@ -516,9 +563,9 @@ namespace Barotrauma.Tutorials
|
|||||||
{
|
{
|
||||||
Item selected = engineer.SelectedConstruction;
|
Item selected = engineer.SelectedConstruction;
|
||||||
|
|
||||||
if (!engineer.HasEquippedItem("screwdriver"))
|
if (!engineer.HasEquippedItem("screwdriver".ToIdentifier()))
|
||||||
{
|
{
|
||||||
HighlightInventorySlot(engineer.Inventory, "screwdriver", highlightColor, 0.5f, 0.5f, 0f);
|
HighlightInventorySlot(engineer.Inventory, "screwdriver".ToIdentifier(), highlightColor, 0.5f, 0.5f, 0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
int selectedIndex = -1;
|
int selectedIndex = -1;
|
||||||
@@ -537,9 +584,9 @@ namespace Barotrauma.Tutorials
|
|||||||
|
|
||||||
wiringActive = selectedIndex != -1;
|
wiringActive = selectedIndex != -1;
|
||||||
|
|
||||||
if (!engineer.HasEquippedItem("wire"))
|
if (!engineer.HasEquippedItem("wire".ToIdentifier()))
|
||||||
{
|
{
|
||||||
HighlightInventorySlotWithTag(engineer.Inventory, "wire", highlightColor, 0.5f, 0.5f, 0f);
|
HighlightInventorySlotWithTag(engineer.Inventory, "wire".ToIdentifier(), highlightColor, 0.5f, 0.5f, 0f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
+136
-62
@@ -69,33 +69,106 @@ namespace Barotrauma.Tutorials
|
|||||||
|
|
||||||
// Variables
|
// Variables
|
||||||
private const float waterVolumeBeforeOpening = 15f;
|
private const float waterVolumeBeforeOpening = 15f;
|
||||||
private string radioSpeakerName;
|
private LocalizedString radioSpeakerName;
|
||||||
private Character mechanic;
|
private Character mechanic;
|
||||||
private Sprite mechanic_repairIcon;
|
private Sprite mechanic_repairIcon;
|
||||||
private Color mechanic_repairIconColor;
|
private Color mechanic_repairIconColor;
|
||||||
private Sprite mechanic_weldIcon;
|
private Sprite mechanic_weldIcon;
|
||||||
|
|
||||||
public MechanicTutorial(XElement element) : base(element)
|
public MechanicTutorial() : base("tutorial.mechanictraining".ToIdentifier(),
|
||||||
{
|
new Segment(
|
||||||
|
"Mechanic.OpenDoor".ToIdentifier(),
|
||||||
|
"Mechanic.OpenDoorObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.TextOnly,
|
||||||
|
textContent: new Segment.Text { Tag = "Mechanic.OpenDoorText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center }),
|
||||||
|
new Segment(
|
||||||
|
"Mechanic.Equipment".ToIdentifier(),
|
||||||
|
"Mechanic.EquipmentObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.ManualVideo,
|
||||||
|
textContent: new Segment.Text { Tag = "Mechanic.EquipmentText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center },
|
||||||
|
videoContent: new Segment.Video { File = "tutorial_inventory.webm", TextTag = "Mechanic.EquipmentText".ToIdentifier(), Width = 450, Height = 80 }),
|
||||||
|
new Segment(
|
||||||
|
"Mechanic.Welding".ToIdentifier(),
|
||||||
|
"Mechanic.WeldingObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.ManualVideo,
|
||||||
|
textContent: new Segment.Text { Tag = "Mechanic.WeldingText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center },
|
||||||
|
videoContent: new Segment.Video { File = "tutorial_equip.webm", TextTag = "Mechanic.WeldingText".ToIdentifier(), Width = 450, Height = 80 }),
|
||||||
|
new Segment(
|
||||||
|
"Mechanic.Drain".ToIdentifier(),
|
||||||
|
"Mechanic.DrainObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.TextOnly,
|
||||||
|
textContent: new Segment.Text { Tag = "Mechanic.DrainText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center }),
|
||||||
|
new Segment(
|
||||||
|
"Mechanic.Deconstruct".ToIdentifier(),
|
||||||
|
"Mechanic.DeconstructObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.ManualVideo,
|
||||||
|
textContent: new Segment.Text { Tag = "Mechanic.DeconstructText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center },
|
||||||
|
videoContent: new Segment.Video { File = "tutorial_deconstruct.webm", TextTag = "Mechanic.DeconstructText".ToIdentifier(), Width = 450, Height = 80 }),
|
||||||
|
new Segment(
|
||||||
|
"Mechanic.Fabricate".ToIdentifier(),
|
||||||
|
"Mechanic.FabricateObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.ManualVideo,
|
||||||
|
textContent: new Segment.Text { Tag = "Mechanic.FabricateText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center },
|
||||||
|
videoContent: new Segment.Video { File = "tutorial_fabricate.webm", TextTag = "Mechanic.FabricateText".ToIdentifier(), Width = 450, Height = 80 }),
|
||||||
|
new Segment(
|
||||||
|
"Mechanic.Extinguisher".ToIdentifier(),
|
||||||
|
"Mechanic.ExtinguisherObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.TextOnly,
|
||||||
|
textContent: new Segment.Text { Tag = "Mechanic.ExtinguisherText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center }),
|
||||||
|
new Segment(
|
||||||
|
"Mechanic.DropExtinguisher".ToIdentifier(),
|
||||||
|
"Mechanic.DropExtinguisherObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.TextOnly,
|
||||||
|
textContent: new Segment.Text { Tag = "Mechanic.DropExtinguisherText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center }),
|
||||||
|
new Segment(
|
||||||
|
"Mechanic.Diving".ToIdentifier(),
|
||||||
|
"Mechanic.DivingObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.TextOnly,
|
||||||
|
textContent: new Segment.Text { Tag = "Mechanic.DivingText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center }),
|
||||||
|
new Segment(
|
||||||
|
"Mechanic.RepairPump".ToIdentifier(),
|
||||||
|
"Mechanic.RepairPumpObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.TextOnly,
|
||||||
|
textContent: new Segment.Text { Tag = "Mechanic.RepairPumpText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center }),
|
||||||
|
new Segment(
|
||||||
|
"Mechanic.RepairSubmarine".ToIdentifier(),
|
||||||
|
"Mechanic.RepairSubmarineObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.TextOnly,
|
||||||
|
textContent: new Segment.Text { Tag = "Mechanic.RepairSubmarineText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center }),
|
||||||
|
new Segment(
|
||||||
|
"tutorial.laddertitle".ToIdentifier(),
|
||||||
|
"tutorial.laddertitle".ToIdentifier(),
|
||||||
|
TutorialContentType.TextOnly,
|
||||||
|
textContent: new Segment.Text { Tag = "tutorial.ladderdescription".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center }))
|
||||||
|
{ }
|
||||||
|
|
||||||
|
protected override CharacterInfo GetCharacterInfo()
|
||||||
|
{
|
||||||
|
return new CharacterInfo(
|
||||||
|
CharacterPrefab.HumanSpeciesName,
|
||||||
|
jobOrJobPrefab: new Job(
|
||||||
|
JobPrefab.Prefabs["mechanic"], Rand.RandSync.Unsynced, 0,
|
||||||
|
new Skill("medical".ToIdentifier(), 0),
|
||||||
|
new Skill("weapons".ToIdentifier(), 0),
|
||||||
|
new Skill("mechanical".ToIdentifier(), 50),
|
||||||
|
new Skill("electrical".ToIdentifier(), 20),
|
||||||
|
new Skill("helm".ToIdentifier(), 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Start()
|
protected override void Initialize()
|
||||||
{
|
{
|
||||||
base.Start();
|
|
||||||
|
|
||||||
radioSpeakerName = TextManager.Get("Tutorial.Radio.Speaker");
|
radioSpeakerName = TextManager.Get("Tutorial.Radio.Speaker");
|
||||||
mechanic = Character.Controlled;
|
mechanic = Character.Controlled;
|
||||||
|
|
||||||
var toolbelt = FindOrGiveItem(mechanic, "toolbelt");
|
var toolbelt = FindOrGiveItem(mechanic, "toolbelt".ToIdentifier());
|
||||||
toolbelt.Unequip(mechanic);
|
toolbelt.Unequip(mechanic);
|
||||||
mechanic.Inventory.RemoveItem(toolbelt);
|
mechanic.Inventory.RemoveItem(toolbelt);
|
||||||
|
|
||||||
var crowbar = FindOrGiveItem(mechanic, "crowbar");
|
var crowbar = FindOrGiveItem(mechanic, "crowbar".ToIdentifier());
|
||||||
crowbar.Unequip(mechanic);
|
crowbar.Unequip(mechanic);
|
||||||
mechanic.Inventory.RemoveItem(crowbar);
|
mechanic.Inventory.RemoveItem(crowbar);
|
||||||
|
|
||||||
var repairOrder = Order.GetPrefab("repairsystems");
|
var repairOrder = OrderPrefab.Prefabs["repairsystems"];
|
||||||
mechanic_repairIcon = repairOrder.SymbolSprite;
|
mechanic_repairIcon = repairOrder.SymbolSprite;
|
||||||
mechanic_repairIconColor = repairOrder.Color;
|
mechanic_repairIconColor = repairOrder.Color;
|
||||||
mechanic_weldIcon = new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(1, 256, 127, 127), new Vector2(0.5f, 0.5f));
|
mechanic_weldIcon = new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(1, 256, 127, 127), new Vector2(0.5f, 0.5f));
|
||||||
@@ -239,24 +312,25 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
yield return new WaitForSeconds(2.5f, false);
|
yield return new WaitForSeconds(2.5f, false);
|
||||||
|
|
||||||
mechanic_fabricator.RemoveFabricationRecipes(new List<string>() { "extinguisher", "wrench", "weldingtool", "weldingfuel", "divingmask", "railgunshell", "nuclearshell", "uex", "harpoongun" });
|
mechanic_fabricator.RemoveFabricationRecipes(allowedIdentifiers:
|
||||||
|
new[] { "extinguisher", "wrench", "weldingtool", "weldingfuel", "divingmask", "railgunshell", "nuclearshell", "uex", "harpoongun" }.ToIdentifiers());
|
||||||
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Mechanic.Radio.WakeUp"), ChatMessageType.Radio, null);
|
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Mechanic.Radio.WakeUp"), ChatMessageType.Radio, null);
|
||||||
|
|
||||||
yield return new WaitForSeconds(2.5f, false);
|
yield return new WaitForSeconds(2.5f, false);
|
||||||
TriggerTutorialSegment(0, GameMain.Config.KeyBindText(InputType.Up), GameMain.Config.KeyBindText(InputType.Left), GameMain.Config.KeyBindText(InputType.Down), GameMain.Config.KeyBindText(InputType.Right), GameMain.Config.KeyBindText(InputType.Select), GameMain.Config.KeyBindText(InputType.Select)); // Open door objective
|
TriggerTutorialSegment(0, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Up), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Left), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Down), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Right), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Select), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Select)); // Open door objective
|
||||||
yield return new WaitForSeconds(0.0f, false);
|
yield return new WaitForSeconds(0.0f, false);
|
||||||
SetDoorAccess(mechanic_firstDoor, mechanic_firstDoorLight, true);
|
SetDoorAccess(mechanic_firstDoor, mechanic_firstDoorLight, true);
|
||||||
SetHighlight(mechanic_firstDoor.Item, true);
|
SetHighlight(mechanic_firstDoor.Item, true);
|
||||||
do { yield return null; } while (!mechanic_firstDoor.IsOpen);
|
do { yield return null; } while (!mechanic_firstDoor.IsOpen);
|
||||||
SetHighlight(mechanic_firstDoor.Item, false);
|
SetHighlight(mechanic_firstDoor.Item, false);
|
||||||
yield return new WaitForSeconds(1.5f, false);
|
yield return new WaitForSeconds(1.5f, false);
|
||||||
RemoveCompletedObjective(segments[0]);
|
RemoveCompletedObjective(0);
|
||||||
|
|
||||||
// Room 2
|
// Room 2
|
||||||
yield return new WaitForSeconds(0.0f, false);
|
yield return new WaitForSeconds(0.0f, false);
|
||||||
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Mechanic.Radio.Equipment"), ChatMessageType.Radio, null);
|
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Mechanic.Radio.Equipment"), ChatMessageType.Radio, null);
|
||||||
do { yield return null; } while (!mechanic_equipmentObjectiveSensor.MotionDetected);
|
do { yield return null; } while (!mechanic_equipmentObjectiveSensor.MotionDetected);
|
||||||
TriggerTutorialSegment(1, GameMain.Config.KeyBindText(InputType.Select), GameMain.Config.KeyBindText(InputType.Deselect), GameMain.Config.KeyBindText(InputType.ToggleInventory)); // Equipment & inventory objective
|
TriggerTutorialSegment(1, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Select), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Deselect), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.ToggleInventory)); // Equipment & inventory objective
|
||||||
SetHighlight(mechanic_equipmentCabinet.Item, true);
|
SetHighlight(mechanic_equipmentCabinet.Item, true);
|
||||||
bool firstSlotRemoved = false;
|
bool firstSlotRemoved = false;
|
||||||
bool secondSlotRemoved = false;
|
bool secondSlotRemoved = false;
|
||||||
@@ -290,35 +364,35 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
|
|
||||||
yield return null;
|
yield return null;
|
||||||
} while (mechanic.Inventory.FindItemByIdentifier("divingmask") == null || mechanic.Inventory.FindItemByIdentifier("weldingtool") == null || mechanic.Inventory.FindItemByIdentifier("wrench") == null); // Wait until looted
|
} while (mechanic.Inventory.FindItemByIdentifier("divingmask".ToIdentifier()) == null || mechanic.Inventory.FindItemByIdentifier("weldingtool".ToIdentifier()) == null || mechanic.Inventory.FindItemByIdentifier("wrench".ToIdentifier()) == null); // Wait until looted
|
||||||
SetHighlight(mechanic_equipmentCabinet.Item, false);
|
SetHighlight(mechanic_equipmentCabinet.Item, false);
|
||||||
yield return new WaitForSeconds(1.5f, false);
|
yield return new WaitForSeconds(1.5f, false);
|
||||||
RemoveCompletedObjective(segments[1]);
|
RemoveCompletedObjective(1);
|
||||||
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Mechanic.Radio.Breach"), ChatMessageType.Radio, null);
|
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Mechanic.Radio.Breach"), ChatMessageType.Radio, null);
|
||||||
|
|
||||||
// Room 3
|
// Room 3
|
||||||
do { yield return null; } while (!mechanic_weldingObjectiveSensor.MotionDetected);
|
do { yield return null; } while (!mechanic_weldingObjectiveSensor.MotionDetected);
|
||||||
TriggerTutorialSegment(2, GameMain.Config.KeyBindText(InputType.Aim), GameMain.Config.KeyBindText(InputType.Shoot), GameMain.Config.KeyBindText(InputType.ToggleInventory)); // Welding objective
|
TriggerTutorialSegment(2, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Aim), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Shoot), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.ToggleInventory)); // Welding objective
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (!mechanic.HasEquippedItem("divingmask"))
|
if (!mechanic.HasEquippedItem("divingmask".ToIdentifier()))
|
||||||
{
|
{
|
||||||
HighlightInventorySlot(mechanic.Inventory, "divingmask", highlightColor, .5f, .5f, 0f);
|
HighlightInventorySlot(mechanic.Inventory, "divingmask".ToIdentifier(), highlightColor, .5f, .5f, 0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mechanic.HasEquippedItem("weldingtool"))
|
if (!mechanic.HasEquippedItem("weldingtool".ToIdentifier()))
|
||||||
{
|
{
|
||||||
HighlightInventorySlot(mechanic.Inventory, "weldingtool", highlightColor, .5f, .5f, 0f);
|
HighlightInventorySlot(mechanic.Inventory, "weldingtool".ToIdentifier(), highlightColor, .5f, .5f, 0f);
|
||||||
}
|
}
|
||||||
yield return null;
|
yield return null;
|
||||||
} while (!mechanic.HasEquippedItem("divingmask") || !mechanic.HasEquippedItem("weldingtool")); // Wait until equipped
|
} while (!mechanic.HasEquippedItem("divingmask".ToIdentifier()) || !mechanic.HasEquippedItem("weldingtool".ToIdentifier())); // Wait until equipped
|
||||||
SetDoorAccess(mechanic_secondDoor, mechanic_secondDoorLight, true);
|
SetDoorAccess(mechanic_secondDoor, mechanic_secondDoorLight, true);
|
||||||
mechanic.AddActiveObjectiveEntity(mechanic_brokenWall_1, mechanic_weldIcon, mechanic_repairIconColor);
|
mechanic.AddActiveObjectiveEntity(mechanic_brokenWall_1, mechanic_weldIcon, mechanic_repairIconColor);
|
||||||
do { yield return null; } while (WallHasDamagedSections(mechanic_brokenWall_1)); // Highlight until repaired
|
do { yield return null; } while (WallHasDamagedSections(mechanic_brokenWall_1)); // Highlight until repaired
|
||||||
mechanic.RemoveActiveObjectiveEntity(mechanic_brokenWall_1);
|
mechanic.RemoveActiveObjectiveEntity(mechanic_brokenWall_1);
|
||||||
RemoveCompletedObjective(segments[2]);
|
RemoveCompletedObjective(2);
|
||||||
yield return new WaitForSeconds(1f, false);
|
yield return new WaitForSeconds(1f, false);
|
||||||
TriggerTutorialSegment(3, GameMain.Config.KeyBindText(InputType.Select)); // Pump objective
|
TriggerTutorialSegment(3, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Select)); // Pump objective
|
||||||
SetHighlight(mechanic_workingPump.Item, true);
|
SetHighlight(mechanic_workingPump.Item, true);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@@ -333,9 +407,9 @@ namespace Barotrauma.Tutorials
|
|||||||
} while (mechanic_workingPump.FlowPercentage >= 0 || !mechanic_workingPump.IsActive); // Highlight until draining
|
} while (mechanic_workingPump.FlowPercentage >= 0 || !mechanic_workingPump.IsActive); // Highlight until draining
|
||||||
SetHighlight(mechanic_workingPump.Item, false);
|
SetHighlight(mechanic_workingPump.Item, false);
|
||||||
do { yield return null; } while (mechanic_brokenhull_1.WaterPercentage > waterVolumeBeforeOpening); // Unlock door once drained
|
do { yield return null; } while (mechanic_brokenhull_1.WaterPercentage > waterVolumeBeforeOpening); // Unlock door once drained
|
||||||
RemoveCompletedObjective(segments[3]);
|
RemoveCompletedObjective(3);
|
||||||
SetDoorAccess(mechanic_thirdDoor, mechanic_thirdDoorLight, true);
|
SetDoorAccess(mechanic_thirdDoor, mechanic_thirdDoorLight, true);
|
||||||
//TriggerTutorialSegment(11, GameMain.Config.KeyBind(InputType.Select), GameMain.Config.KeyBind(InputType.Up), GameMain.Config.KeyBind(InputType.Down), GameMain.Config.KeyBind(InputType.Select)); // Ladder objective
|
//TriggerTutorialSegment(11, GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Select], GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Up], GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Down], GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Select]); // Ladder objective
|
||||||
//do { yield return null; } while (!mechanic_ladderSensor.MotionDetected);
|
//do { yield return null; } while (!mechanic_ladderSensor.MotionDetected);
|
||||||
//RemoveCompletedObjective(segments[11]);
|
//RemoveCompletedObjective(segments[11]);
|
||||||
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Mechanic.Radio.News"), ChatMessageType.Radio, null);
|
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Mechanic.Radio.News"), ChatMessageType.Radio, null);
|
||||||
@@ -362,24 +436,24 @@ namespace Barotrauma.Tutorials
|
|||||||
if (mechanic.Inventory.GetItemAt(i) == null) { HighlightInventorySlot(mechanic.Inventory, i, highlightColor, .5f, .5f, 0f); }
|
if (mechanic.Inventory.GetItemAt(i) == null) { HighlightInventorySlot(mechanic.Inventory, i, highlightColor, .5f, .5f, 0f); }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mechanic.Inventory.FindItemByIdentifier("oxygentank") == null && mechanic.Inventory.FindItemByIdentifier("aluminium") == null)
|
if (mechanic.Inventory.FindItemByIdentifier("oxygentank".ToIdentifier()) == null && mechanic.Inventory.FindItemByIdentifier("aluminium".ToIdentifier()) == null)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < mechanic_craftingCabinet.Capacity; i++)
|
for (int i = 0; i < mechanic_craftingCabinet.Capacity; i++)
|
||||||
{
|
{
|
||||||
Item item = mechanic_craftingCabinet.Inventory.GetItemAt(i);
|
Item item = mechanic_craftingCabinet.Inventory.GetItemAt(i);
|
||||||
if (item != null && item.prefab.Identifier == "oxygentank")
|
if (item != null && item.Prefab.Identifier == "oxygentank")
|
||||||
{
|
{
|
||||||
HighlightInventorySlot(mechanic_craftingCabinet.Inventory, i, highlightColor, .5f, .5f, 0f);
|
HighlightInventorySlot(mechanic_craftingCabinet.Inventory, i, highlightColor, .5f, .5f, 0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mechanic.Inventory.FindItemByIdentifier("sodium") == null)
|
if (mechanic.Inventory.FindItemByIdentifier("sodium".ToIdentifier()) == null)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < mechanic_craftingCabinet.Inventory.Capacity; i++)
|
for (int i = 0; i < mechanic_craftingCabinet.Inventory.Capacity; i++)
|
||||||
{
|
{
|
||||||
Item item = mechanic_craftingCabinet.Inventory.GetItemAt(i);
|
Item item = mechanic_craftingCabinet.Inventory.GetItemAt(i);
|
||||||
if (item != null && item.prefab.Identifier == "sodium")
|
if (item != null && item.Prefab.Identifier == "sodium")
|
||||||
{
|
{
|
||||||
HighlightInventorySlot(mechanic_craftingCabinet.Inventory, i, highlightColor, .5f, .5f, 0f);
|
HighlightInventorySlot(mechanic_craftingCabinet.Inventory, i, highlightColor, .5f, .5f, 0f);
|
||||||
}
|
}
|
||||||
@@ -387,12 +461,12 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gotOxygenTank && (mechanic.Inventory.FindItemByIdentifier("oxygentank") != null ||
|
if (!gotOxygenTank && (mechanic.Inventory.FindItemByIdentifier("oxygentank".ToIdentifier()) != null ||
|
||||||
mechanic_deconstructor.InputContainer.Inventory.FindItemByIdentifier("oxygentank") != null))
|
mechanic_deconstructor.InputContainer.Inventory.FindItemByIdentifier("oxygentank".ToIdentifier()) != null))
|
||||||
{
|
{
|
||||||
gotOxygenTank = true;
|
gotOxygenTank = true;
|
||||||
}
|
}
|
||||||
if (!gotSodium && mechanic.Inventory.FindItemByIdentifier("sodium") != null)
|
if (!gotSodium && mechanic.Inventory.FindItemByIdentifier("sodium".ToIdentifier()) != null)
|
||||||
{
|
{
|
||||||
gotSodium = true;
|
gotSodium = true;
|
||||||
}
|
}
|
||||||
@@ -406,9 +480,9 @@ namespace Barotrauma.Tutorials
|
|||||||
{
|
{
|
||||||
if (IsSelectedItem(mechanic_deconstructor.Item))
|
if (IsSelectedItem(mechanic_deconstructor.Item))
|
||||||
{
|
{
|
||||||
if (mechanic_deconstructor.OutputContainer.Inventory.FindItemByIdentifier("aluminium") != null)
|
if (mechanic_deconstructor.OutputContainer.Inventory.FindItemByIdentifier("aluminium".ToIdentifier()) != null)
|
||||||
{
|
{
|
||||||
HighlightInventorySlot(mechanic_deconstructor.OutputContainer.Inventory, "aluminium", highlightColor, .5f, .5f, 0f);
|
HighlightInventorySlot(mechanic_deconstructor.OutputContainer.Inventory, "aluminium".ToIdentifier(), highlightColor, .5f, .5f, 0f);
|
||||||
|
|
||||||
for (int i = 0; i < mechanic.Inventory.Capacity; i++)
|
for (int i = 0; i < mechanic.Inventory.Capacity; i++)
|
||||||
{
|
{
|
||||||
@@ -417,16 +491,16 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (mechanic.Inventory.FindItemByIdentifier("oxygentank") != null && mechanic_deconstructor.InputContainer.Inventory.FindItemByIdentifier("oxygentank") == null)
|
if (mechanic.Inventory.FindItemByIdentifier("oxygentank".ToIdentifier()) != null && mechanic_deconstructor.InputContainer.Inventory.FindItemByIdentifier("oxygentank".ToIdentifier()) == null)
|
||||||
{
|
{
|
||||||
HighlightInventorySlot(mechanic.Inventory, "oxygentank", highlightColor, .5f, .5f, 0f);
|
HighlightInventorySlot(mechanic.Inventory, "oxygentank".ToIdentifier(), highlightColor, .5f, .5f, 0f);
|
||||||
for (int i = 0; i < mechanic_deconstructor.InputContainer.Inventory.Capacity; i++)
|
for (int i = 0; i < mechanic_deconstructor.InputContainer.Inventory.Capacity; i++)
|
||||||
{
|
{
|
||||||
HighlightInventorySlot(mechanic_deconstructor.InputContainer.Inventory, i, highlightColor, .5f, .5f, 0f);
|
HighlightInventorySlot(mechanic_deconstructor.InputContainer.Inventory, i, highlightColor, .5f, .5f, 0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mechanic_deconstructor.InputContainer.Inventory.FindItemByIdentifier("oxygentank") != null && !mechanic_deconstructor.IsActive)
|
if (mechanic_deconstructor.InputContainer.Inventory.FindItemByIdentifier("oxygentank".ToIdentifier()) != null && !mechanic_deconstructor.IsActive)
|
||||||
{
|
{
|
||||||
if (mechanic_deconstructor.ActivateButton.FlashTimer <= 0)
|
if (mechanic_deconstructor.ActivateButton.FlashTimer <= 0)
|
||||||
{
|
{
|
||||||
@@ -437,11 +511,11 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
yield return null;
|
yield return null;
|
||||||
} while (
|
} while (
|
||||||
mechanic.Inventory.FindItemByIdentifier("aluminium") == null &&
|
mechanic.Inventory.FindItemByIdentifier("aluminium".ToIdentifier()) == null &&
|
||||||
mechanic_fabricator.InputContainer.Inventory.FindItemByIdentifier("aluminium") == null); // Wait until aluminium obtained
|
mechanic_fabricator.InputContainer.Inventory.FindItemByIdentifier("aluminium".ToIdentifier()) == null); // Wait until aluminium obtained
|
||||||
|
|
||||||
SetHighlight(mechanic_deconstructor.Item, false);
|
SetHighlight(mechanic_deconstructor.Item, false);
|
||||||
RemoveCompletedObjective(segments[4]);
|
RemoveCompletedObjective(4);
|
||||||
yield return new WaitForSeconds(1f, false);
|
yield return new WaitForSeconds(1f, false);
|
||||||
TriggerTutorialSegment(5); // Fabricate
|
TriggerTutorialSegment(5); // Fabricate
|
||||||
SetHighlight(mechanic_fabricator.Item, true);
|
SetHighlight(mechanic_fabricator.Item, true);
|
||||||
@@ -455,26 +529,26 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (mechanic_fabricator.OutputContainer.Inventory.FindItemByIdentifier("extinguisher") != null)
|
if (mechanic_fabricator.OutputContainer.Inventory.FindItemByIdentifier("extinguisher".ToIdentifier()) != null)
|
||||||
{
|
{
|
||||||
HighlightInventorySlot(mechanic_fabricator.OutputContainer.Inventory, "extinguisher", highlightColor, .5f, .5f, 0f);
|
HighlightInventorySlot(mechanic_fabricator.OutputContainer.Inventory, "extinguisher".ToIdentifier(), highlightColor, .5f, .5f, 0f);
|
||||||
|
|
||||||
/*for (int i = 0; i < mechanic.Inventory.Capacity; i++)
|
/*for (int i = 0; i < mechanic.Inventory.Capacity; i++)
|
||||||
{
|
{
|
||||||
if (mechanic.Inventory.Items[i] == null) HighlightInventorySlot(mechanic.Inventory, i, highlightColor, .5f, .5f, 0f);
|
if (mechanic.Inventory.Items[i] == null) HighlightInventorySlot(mechanic.Inventory, i, highlightColor, .5f, .5f, 0f);
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
else if (mechanic_fabricator.InputContainer.Inventory.FindItemByIdentifier("aluminium") != null && mechanic_fabricator.InputContainer.Inventory.FindItemByIdentifier("sodium") != null && !mechanic_fabricator.IsActive)
|
else if (mechanic_fabricator.InputContainer.Inventory.FindItemByIdentifier("aluminium".ToIdentifier()) != null && mechanic_fabricator.InputContainer.Inventory.FindItemByIdentifier("sodium".ToIdentifier()) != null && !mechanic_fabricator.IsActive)
|
||||||
{
|
{
|
||||||
if (mechanic_fabricator.ActivateButton.FlashTimer <= 0)
|
if (mechanic_fabricator.ActivateButton.FlashTimer <= 0)
|
||||||
{
|
{
|
||||||
mechanic_fabricator.ActivateButton.Flash(highlightColor, 1.5f, false);
|
mechanic_fabricator.ActivateButton.Flash(highlightColor, 1.5f, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mechanic.Inventory.FindItemByIdentifier("aluminium") != null || mechanic.Inventory.FindItemByIdentifier("sodium") != null)
|
else if (mechanic.Inventory.FindItemByIdentifier("aluminium".ToIdentifier()) != null || mechanic.Inventory.FindItemByIdentifier("sodium".ToIdentifier()) != null)
|
||||||
{
|
{
|
||||||
HighlightInventorySlot(mechanic.Inventory, "aluminium", highlightColor, .5f, .5f, 0f);
|
HighlightInventorySlot(mechanic.Inventory, "aluminium".ToIdentifier(), highlightColor, .5f, .5f, 0f);
|
||||||
HighlightInventorySlot(mechanic.Inventory, "sodium", highlightColor, .5f, .5f, 0f);
|
HighlightInventorySlot(mechanic.Inventory, "sodium".ToIdentifier(), highlightColor, .5f, .5f, 0f);
|
||||||
|
|
||||||
if (mechanic_fabricator.InputContainer.Inventory.GetItemAt(0) == null)
|
if (mechanic_fabricator.InputContainer.Inventory.GetItemAt(0) == null)
|
||||||
{
|
{
|
||||||
@@ -489,27 +563,27 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
yield return null;
|
yield return null;
|
||||||
} while (mechanic.Inventory.FindItemByIdentifier("extinguisher") == null); // Wait until extinguisher is created
|
} while (mechanic.Inventory.FindItemByIdentifier("extinguisher".ToIdentifier()) == null); // Wait until extinguisher is created
|
||||||
RemoveCompletedObjective(segments[5]);
|
RemoveCompletedObjective(5);
|
||||||
SetHighlight(mechanic_fabricator.Item, false);
|
SetHighlight(mechanic_fabricator.Item, false);
|
||||||
SetDoorAccess(mechanic_fourthDoor, mechanic_fourthDoorLight, true);
|
SetDoorAccess(mechanic_fourthDoor, mechanic_fourthDoorLight, true);
|
||||||
|
|
||||||
// Room 5
|
// Room 5
|
||||||
do { yield return null; } while (!mechanic_fireSensor.MotionDetected);
|
do { yield return null; } while (!mechanic_fireSensor.MotionDetected);
|
||||||
TriggerTutorialSegment(6, GameMain.Config.KeyBindText(InputType.Aim), GameMain.Config.KeyBindText(InputType.Shoot)); // Using the extinguisher
|
TriggerTutorialSegment(6, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Aim), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Shoot)); // Using the extinguisher
|
||||||
do { yield return null; } while (!mechanic_fire.Removed); // Wait until extinguished
|
do { yield return null; } while (!mechanic_fire.Removed); // Wait until extinguished
|
||||||
yield return new WaitForSeconds(3f, false);
|
yield return new WaitForSeconds(3f, false);
|
||||||
RemoveCompletedObjective(segments[6]);
|
RemoveCompletedObjective(6);
|
||||||
|
|
||||||
if (mechanic.HasEquippedItem("extinguisher")) // do not trigger if dropped already
|
if (mechanic.HasEquippedItem("extinguisher".ToIdentifier())) // do not trigger if dropped already
|
||||||
{
|
{
|
||||||
TriggerTutorialSegment(7);
|
TriggerTutorialSegment(7);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
HighlightInventorySlot(mechanic.Inventory, "extinguisher", highlightColor, 0.5f, 0.5f, 0f);
|
HighlightInventorySlot(mechanic.Inventory, "extinguisher".ToIdentifier(), highlightColor, 0.5f, 0.5f, 0f);
|
||||||
yield return null;
|
yield return null;
|
||||||
} while (mechanic.HasEquippedItem("extinguisher"));
|
} while (mechanic.HasEquippedItem("extinguisher".ToIdentifier()));
|
||||||
RemoveCompletedObjective(segments[7]);
|
RemoveCompletedObjective(7);
|
||||||
}
|
}
|
||||||
SetDoorAccess(mechanic_fifthDoor, mechanic_fifthDoorLight, true);
|
SetDoorAccess(mechanic_fifthDoor, mechanic_fifthDoorLight, true);
|
||||||
|
|
||||||
@@ -531,9 +605,9 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
yield return null;
|
yield return null;
|
||||||
} while (!mechanic.HasEquippedItem("divingsuit", slotType: InvSlotType.OuterClothes));
|
} while (!mechanic.HasEquippedItem("divingsuit".ToIdentifier(), slotType: InvSlotType.OuterClothes));
|
||||||
SetHighlight(mechanic_divingSuitContainer.Item, false);
|
SetHighlight(mechanic_divingSuitContainer.Item, false);
|
||||||
RemoveCompletedObjective(segments[8]);
|
RemoveCompletedObjective(8);
|
||||||
SetDoorAccess(tutorial_mechanicFinalDoor, tutorial_mechanicFinalDoorLight, true);
|
SetDoorAccess(tutorial_mechanicFinalDoor, tutorial_mechanicFinalDoorLight, true);
|
||||||
|
|
||||||
// Room 7
|
// Room 7
|
||||||
@@ -542,7 +616,7 @@ namespace Barotrauma.Tutorials
|
|||||||
mechanic.RemoveActiveObjectiveEntity(mechanic_brokenWall_2);
|
mechanic.RemoveActiveObjectiveEntity(mechanic_brokenWall_2);
|
||||||
yield return new WaitForSeconds(2f, false);
|
yield return new WaitForSeconds(2f, false);
|
||||||
|
|
||||||
TriggerTutorialSegment(9, GameMain.Config.KeyBindText(InputType.Use)); // Repairing machinery (pump)
|
TriggerTutorialSegment(9, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Use)); // Repairing machinery (pump)
|
||||||
SetHighlight(mechanic_brokenPump.Item, true);
|
SetHighlight(mechanic_brokenPump.Item, true);
|
||||||
mechanic_brokenPump.CanBeSelected = true;
|
mechanic_brokenPump.CanBeSelected = true;
|
||||||
Repairable repairablePumpComponent = mechanic_brokenPump.Item.GetComponent<Repairable>();
|
Repairable repairablePumpComponent = mechanic_brokenPump.Item.GetComponent<Repairable>();
|
||||||
@@ -552,9 +626,9 @@ namespace Barotrauma.Tutorials
|
|||||||
yield return null;
|
yield return null;
|
||||||
if (repairablePumpComponent.IsBelowRepairThreshold)
|
if (repairablePumpComponent.IsBelowRepairThreshold)
|
||||||
{
|
{
|
||||||
if (!mechanic.HasEquippedItem("wrench"))
|
if (!mechanic.HasEquippedItem("wrench".ToIdentifier()))
|
||||||
{
|
{
|
||||||
HighlightInventorySlot(mechanic.Inventory, "wrench", highlightColor, 0.5f, 0.5f, 0f);
|
HighlightInventorySlot(mechanic.Inventory, "wrench".ToIdentifier(), highlightColor, 0.5f, 0.5f, 0f);
|
||||||
}
|
}
|
||||||
else if (IsSelectedItem(mechanic_brokenPump.Item) && repairablePumpComponent.CurrentFixer == null)
|
else if (IsSelectedItem(mechanic_brokenPump.Item) && repairablePumpComponent.CurrentFixer == null)
|
||||||
{
|
{
|
||||||
@@ -575,7 +649,7 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (repairablePumpComponent.IsBelowRepairThreshold || mechanic_brokenPump.FlowPercentage >= 0 || !mechanic_brokenPump.IsActive);
|
} while (repairablePumpComponent.IsBelowRepairThreshold || mechanic_brokenPump.FlowPercentage >= 0 || !mechanic_brokenPump.IsActive);
|
||||||
RemoveCompletedObjective(segments[9]);
|
RemoveCompletedObjective(9);
|
||||||
SetHighlight(mechanic_brokenPump.Item, false);
|
SetHighlight(mechanic_brokenPump.Item, false);
|
||||||
do { yield return null; } while (mechanic_brokenhull_2.WaterPercentage > waterVolumeBeforeOpening);
|
do { yield return null; } while (mechanic_brokenhull_2.WaterPercentage > waterVolumeBeforeOpening);
|
||||||
SetDoorAccess(tutorial_submarineDoor, tutorial_submarineDoorLight, true);
|
SetDoorAccess(tutorial_submarineDoor, tutorial_submarineDoorLight, true);
|
||||||
@@ -599,7 +673,7 @@ namespace Barotrauma.Tutorials
|
|||||||
// Remove highlights when each individual machine is repaired
|
// Remove highlights when each individual machine is repaired
|
||||||
do { CheckHighlights(repairablePumpComponent1, repairablePumpComponent2, repairableEngineComponent); yield return null; } while (repairablePumpComponent1.IsBelowRepairThreshold || repairablePumpComponent2.IsBelowRepairThreshold || repairableEngineComponent.IsBelowRepairThreshold);
|
do { CheckHighlights(repairablePumpComponent1, repairablePumpComponent2, repairableEngineComponent); yield return null; } while (repairablePumpComponent1.IsBelowRepairThreshold || repairablePumpComponent2.IsBelowRepairThreshold || repairableEngineComponent.IsBelowRepairThreshold);
|
||||||
CheckHighlights(repairablePumpComponent1, repairablePumpComponent2, repairableEngineComponent);
|
CheckHighlights(repairablePumpComponent1, repairablePumpComponent2, repairableEngineComponent);
|
||||||
RemoveCompletedObjective(segments[10]);
|
RemoveCompletedObjective(10);
|
||||||
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Mechanic.Radio.Complete"), ChatMessageType.Radio, null);
|
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Mechanic.Radio.Complete"), ChatMessageType.Radio, null);
|
||||||
|
|
||||||
// END TUTORIAL
|
// END TUTORIAL
|
||||||
|
|||||||
+93
-41
@@ -72,62 +72,114 @@ namespace Barotrauma.Tutorials
|
|||||||
private PowerContainer officer_subSuperCapacitor_2;
|
private PowerContainer officer_subSuperCapacitor_2;
|
||||||
|
|
||||||
// Variables
|
// Variables
|
||||||
private string radioSpeakerName;
|
private LocalizedString radioSpeakerName;
|
||||||
private Character officer;
|
private Character officer;
|
||||||
private float superCapacitorRechargeRate = 10;
|
private float superCapacitorRechargeRate = 10;
|
||||||
private Sprite officer_gunIcon;
|
private Sprite officer_gunIcon;
|
||||||
private Color officer_gunIconColor;
|
private Color officer_gunIconColor;
|
||||||
|
|
||||||
public OfficerTutorial(XElement element) : base(element)
|
public OfficerTutorial() : base("tutorial.securityofficertraining".ToIdentifier(),
|
||||||
|
new Segment(
|
||||||
|
"Mechanic.Equipment".ToIdentifier(),
|
||||||
|
"Mechanic.EquipmentObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.TextOnly,
|
||||||
|
textContent: new Segment.Text { Tag = "Mechanic.EquipmentText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center }),
|
||||||
|
new Segment(
|
||||||
|
"Officer.MeleeWeapon".ToIdentifier(),
|
||||||
|
"Officer.MeleeWeaponObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.TextOnly,
|
||||||
|
textContent: new Segment.Text { Tag = "Officer.MeleeWeaponText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center }),
|
||||||
|
new Segment(
|
||||||
|
"Officer.Crawler".ToIdentifier(),
|
||||||
|
"Officer.CrawlerObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.TextOnly,
|
||||||
|
textContent: new Segment.Text { Tag = "Officer.CrawlerText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center }),
|
||||||
|
new Segment(
|
||||||
|
"Officer.SomethingBig".ToIdentifier(),
|
||||||
|
"Officer.SomethingBigObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.ManualVideo,
|
||||||
|
textContent: new Segment.Text { Tag = "Officer.SomethingBigText".ToIdentifier(), Width = 700, Height = 80, Anchor = Anchor.Center },
|
||||||
|
videoContent: new Segment.Video { File = "tutorial_loaders.webm", TextTag = "Officer.SomethingBigText".ToIdentifier(), Width = 700, Height = 80 }),
|
||||||
|
new Segment(
|
||||||
|
"Officer.Hammerhead".ToIdentifier(),
|
||||||
|
"Officer.HammerheadObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.TextOnly,
|
||||||
|
textContent: new Segment.Text { Tag = "Officer.HammerheadText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center }),
|
||||||
|
new Segment(
|
||||||
|
"Officer.RangedWeapon".ToIdentifier(),
|
||||||
|
"Officer.RangedWeaponObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.ManualVideo,
|
||||||
|
textContent: new Segment.Text { Tag = "Officer.RangedWeaponText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center },
|
||||||
|
videoContent: new Segment.Video { File = "tutorial_ranged.webm", TextTag = "Officer.RangedWeaponText".ToIdentifier(), Width = 450, Height = 80 }),
|
||||||
|
new Segment(
|
||||||
|
"Officer.Mudraptor".ToIdentifier(),
|
||||||
|
"Officer.MudraptorObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.TextOnly,
|
||||||
|
textContent: new Segment.Text { Tag = "Officer.MudraptorText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center }),
|
||||||
|
new Segment(
|
||||||
|
"Officer.ArmSubmarine".ToIdentifier(),
|
||||||
|
"Officer.ArmSubmarineObjective".ToIdentifier(),
|
||||||
|
TutorialContentType.TextOnly,
|
||||||
|
textContent: new Segment.Text { Tag = "Officer.ArmSubmarineText".ToIdentifier(), Width = 450, Height = 80, Anchor = Anchor.Center }))
|
||||||
|
{ }
|
||||||
|
|
||||||
|
protected override CharacterInfo GetCharacterInfo()
|
||||||
{
|
{
|
||||||
|
return new CharacterInfo(
|
||||||
|
CharacterPrefab.HumanSpeciesName,
|
||||||
|
jobOrJobPrefab: new Job(
|
||||||
|
JobPrefab.Prefabs["securityofficer"], Rand.RandSync.Unsynced, 0,
|
||||||
|
new Skill("medical".ToIdentifier(), 20),
|
||||||
|
new Skill("weapons".ToIdentifier(), 70),
|
||||||
|
new Skill("mechanical".ToIdentifier(), 20),
|
||||||
|
new Skill("electrical".ToIdentifier(), 20),
|
||||||
|
new Skill("helm".ToIdentifier(), 20)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Start()
|
protected override void Initialize()
|
||||||
{
|
{
|
||||||
base.Start();
|
|
||||||
|
|
||||||
radioSpeakerName = TextManager.Get("Tutorial.Radio.Speaker");
|
radioSpeakerName = TextManager.Get("Tutorial.Radio.Speaker");
|
||||||
officer = Character.Controlled;
|
officer = Character.Controlled;
|
||||||
|
|
||||||
var handcuffs = FindOrGiveItem(officer, "handcuffs");
|
var handcuffs = FindOrGiveItem(officer, "handcuffs".ToIdentifier());
|
||||||
handcuffs.Unequip(officer);
|
handcuffs.Unequip(officer);
|
||||||
officer.Inventory.RemoveItem(handcuffs);
|
officer.Inventory.RemoveItem(handcuffs);
|
||||||
|
|
||||||
var stunbaton = FindOrGiveItem(officer, "stunbaton");
|
var stunbaton = FindOrGiveItem(officer, "stunbaton".ToIdentifier());
|
||||||
stunbaton.Unequip(officer);
|
stunbaton.Unequip(officer);
|
||||||
officer.Inventory.RemoveItem(stunbaton);
|
officer.Inventory.RemoveItem(stunbaton);
|
||||||
|
|
||||||
var smg = FindOrGiveItem(officer, "smg");
|
var smg = FindOrGiveItem(officer, "smg".ToIdentifier());
|
||||||
smg.Unequip(officer);
|
smg.Unequip(officer);
|
||||||
officer.Inventory.RemoveItem(smg);
|
officer.Inventory.RemoveItem(smg);
|
||||||
|
|
||||||
var divingknife = FindOrGiveItem(officer, "divingknife");
|
var divingknife = FindOrGiveItem(officer, "divingknife".ToIdentifier());
|
||||||
divingknife.Unequip(officer);
|
divingknife.Unequip(officer);
|
||||||
officer.Inventory.RemoveItem(divingknife);
|
officer.Inventory.RemoveItem(divingknife);
|
||||||
|
|
||||||
var steroids = FindOrGiveItem(officer, "steroids");
|
var steroids = FindOrGiveItem(officer, "steroids".ToIdentifier());
|
||||||
steroids.Unequip(officer);
|
steroids.Unequip(officer);
|
||||||
officer.Inventory.RemoveItem(steroids);
|
officer.Inventory.RemoveItem(steroids);
|
||||||
|
|
||||||
var ballistichelmet =
|
var ballistichelmet =
|
||||||
officer.Inventory.FindItemByIdentifier("ballistichelmet1") ??
|
officer.Inventory.FindItemByIdentifier("ballistichelmet1".ToIdentifier()) ??
|
||||||
officer.Inventory.FindItemByIdentifier("ballistichelmet2") ??
|
officer.Inventory.FindItemByIdentifier("ballistichelmet2".ToIdentifier()) ??
|
||||||
FindOrGiveItem(officer, "ballistichelmet3");
|
FindOrGiveItem(officer, "ballistichelmet3".ToIdentifier());
|
||||||
ballistichelmet.Unequip(officer);
|
ballistichelmet.Unequip(officer);
|
||||||
officer.Inventory.RemoveItem(ballistichelmet);
|
officer.Inventory.RemoveItem(ballistichelmet);
|
||||||
|
|
||||||
var bodyarmor = FindOrGiveItem(officer, "bodyarmor");
|
var bodyarmor = FindOrGiveItem(officer, "bodyarmor".ToIdentifier());
|
||||||
bodyarmor.Unequip(officer);
|
bodyarmor.Unequip(officer);
|
||||||
officer.Inventory.RemoveItem(bodyarmor);
|
officer.Inventory.RemoveItem(bodyarmor);
|
||||||
|
|
||||||
var gunOrder = Order.GetPrefab("operateweapons");
|
var gunOrder = OrderPrefab.Prefabs["operateweapons"];
|
||||||
officer_gunIcon = gunOrder.SymbolSprite;
|
officer_gunIcon = gunOrder.SymbolSprite;
|
||||||
officer_gunIconColor = gunOrder.Color;
|
officer_gunIconColor = gunOrder.Color;
|
||||||
|
|
||||||
var bandage = FindOrGiveItem(officer, "antibleeding1");
|
var bandage = FindOrGiveItem(officer, "antibleeding1".ToIdentifier());
|
||||||
bandage.Unequip(officer);
|
bandage.Unequip(officer);
|
||||||
officer.Inventory.RemoveItem(bandage);
|
officer.Inventory.RemoveItem(bandage);
|
||||||
FindOrGiveItem(officer, "antibleeding1");
|
FindOrGiveItem(officer, "antibleeding1".ToIdentifier());
|
||||||
|
|
||||||
// Other tutorial items
|
// Other tutorial items
|
||||||
tutorial_mechanicFinalDoorLight = Item.ItemList.Find(i => i.HasTag("tutorial_mechanicfinaldoorlight")).GetComponent<LightComponent>();
|
tutorial_mechanicFinalDoorLight = Item.ItemList.Find(i => i.HasTag("tutorial_mechanicfinaldoorlight")).GetComponent<LightComponent>();
|
||||||
@@ -222,7 +274,7 @@ namespace Barotrauma.Tutorials
|
|||||||
do { yield return null; } while (!officer_equipmentObjectiveSensor.MotionDetected);
|
do { yield return null; } while (!officer_equipmentObjectiveSensor.MotionDetected);
|
||||||
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Officer.Radio.Equipment"), ChatMessageType.Radio, null);
|
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Officer.Radio.Equipment"), ChatMessageType.Radio, null);
|
||||||
yield return new WaitForSeconds(3f, false);
|
yield return new WaitForSeconds(3f, false);
|
||||||
//TriggerTutorialSegment(0, GameMain.Config.KeyBind(InputType.Select), GameMain.Config.KeyBind(InputType.Deselect)); // Retrieve equipment
|
//TriggerTutorialSegment(0, GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Select], GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Deselect]); // Retrieve equipment
|
||||||
SetHighlight(officer_equipmentCabinet.Item, true);
|
SetHighlight(officer_equipmentCabinet.Item, true);
|
||||||
bool firstSlotRemoved = false;
|
bool firstSlotRemoved = false;
|
||||||
bool secondSlotRemoved = false;
|
bool secondSlotRemoved = false;
|
||||||
@@ -260,24 +312,24 @@ namespace Barotrauma.Tutorials
|
|||||||
//RemoveCompletedObjective(segments[0]);
|
//RemoveCompletedObjective(segments[0]);
|
||||||
SetHighlight(officer_equipmentCabinet.Item, false);
|
SetHighlight(officer_equipmentCabinet.Item, false);
|
||||||
do { yield return null; } while (IsSelectedItem(officer_equipmentCabinet.Item));
|
do { yield return null; } while (IsSelectedItem(officer_equipmentCabinet.Item));
|
||||||
TriggerTutorialSegment(1, GameMain.Config.KeyBindText(InputType.Aim), GameMain.Config.KeyBindText(InputType.Shoot)); // Equip melee weapon & armor
|
TriggerTutorialSegment(1, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Aim), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Shoot)); // Equip melee weapon & armor
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (!officer.HasEquippedItem("stunbaton"))
|
if (!officer.HasEquippedItem("stunbaton".ToIdentifier()))
|
||||||
{
|
{
|
||||||
HighlightInventorySlot(officer.Inventory, "stunbaton", highlightColor, .5f, .5f, 0f);
|
HighlightInventorySlot(officer.Inventory, "stunbaton".ToIdentifier(), highlightColor, .5f, .5f, 0f);
|
||||||
}
|
}
|
||||||
if (!officer.HasEquippedItem("bodyarmor"))
|
if (!officer.HasEquippedItem("bodyarmor".ToIdentifier()))
|
||||||
{
|
{
|
||||||
HighlightInventorySlot(officer.Inventory, "bodyarmor", highlightColor, .5f, .5f, 0f);
|
HighlightInventorySlot(officer.Inventory, "bodyarmor".ToIdentifier(), highlightColor, .5f, .5f, 0f);
|
||||||
}
|
}
|
||||||
if (!officer.HasEquippedItem("ballistichelmet1"))
|
if (!officer.HasEquippedItem("ballistichelmet1".ToIdentifier()))
|
||||||
{
|
{
|
||||||
HighlightInventorySlot(officer.Inventory, "ballistichelmet1", highlightColor, .5f, .5f, 0f);
|
HighlightInventorySlot(officer.Inventory, "ballistichelmet1".ToIdentifier(), highlightColor, .5f, .5f, 0f);
|
||||||
}
|
}
|
||||||
yield return new WaitForSeconds(1f, false);
|
yield return new WaitForSeconds(1f, false);
|
||||||
} while (!officer.HasEquippedItem("stunbaton") || !officer.HasEquippedItem("bodyarmor") || !officer.HasEquippedItem("ballistichelmet1"));
|
} while (!officer.HasEquippedItem("stunbaton".ToIdentifier()) || !officer.HasEquippedItem("bodyarmor".ToIdentifier()) || !officer.HasEquippedItem("ballistichelmet1".ToIdentifier()));
|
||||||
RemoveCompletedObjective(segments[1]);
|
RemoveCompletedObjective(1);
|
||||||
SetDoorAccess(officer_firstDoor, officer_firstDoorLight, true);
|
SetDoorAccess(officer_firstDoor, officer_firstDoorLight, true);
|
||||||
|
|
||||||
// Room 3
|
// Room 3
|
||||||
@@ -285,7 +337,7 @@ namespace Barotrauma.Tutorials
|
|||||||
TriggerTutorialSegment(2);
|
TriggerTutorialSegment(2);
|
||||||
officer_crawler = SpawnMonster("crawler", officer_crawlerSpawnPos);
|
officer_crawler = SpawnMonster("crawler", officer_crawlerSpawnPos);
|
||||||
do { yield return null; } while (!officer_crawler.IsDead);
|
do { yield return null; } while (!officer_crawler.IsDead);
|
||||||
RemoveCompletedObjective(segments[2]);
|
RemoveCompletedObjective(2);
|
||||||
Heal(officer);
|
Heal(officer);
|
||||||
yield return new WaitForSeconds(1f, false);
|
yield return new WaitForSeconds(1f, false);
|
||||||
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Officer.Radio.CrawlerDead"), ChatMessageType.Radio, null);
|
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Officer.Radio.CrawlerDead"), ChatMessageType.Radio, null);
|
||||||
@@ -305,7 +357,7 @@ namespace Barotrauma.Tutorials
|
|||||||
SetHighlight(officer_ammoShelf_2.Item, officer_coilgunLoader.Item.ExternalHighlight );
|
SetHighlight(officer_ammoShelf_2.Item, officer_coilgunLoader.Item.ExternalHighlight );
|
||||||
if (IsSelectedItem(officer_coilgunLoader.Item))
|
if (IsSelectedItem(officer_coilgunLoader.Item))
|
||||||
{
|
{
|
||||||
HighlightInventorySlot(officer.Inventory, "coilgunammobox", highlightColor, .5f, .5f, 0f);
|
HighlightInventorySlot(officer.Inventory, "coilgunammobox".ToIdentifier(), highlightColor, .5f, .5f, 0f);
|
||||||
}
|
}
|
||||||
yield return null;
|
yield return null;
|
||||||
} while (officer_coilgunLoader.Inventory.GetItemAt(0) == null || officer_superCapacitor.RechargeSpeed < superCapacitorRechargeRate || officer_coilgunLoader.Inventory.GetItemAt(0).Condition == 0);
|
} while (officer_coilgunLoader.Inventory.GetItemAt(0) == null || officer_superCapacitor.RechargeSpeed < superCapacitorRechargeRate || officer_coilgunLoader.Inventory.GetItemAt(0).Condition == 0);
|
||||||
@@ -313,9 +365,9 @@ namespace Barotrauma.Tutorials
|
|||||||
SetHighlight(officer_superCapacitor.Item, false);
|
SetHighlight(officer_superCapacitor.Item, false);
|
||||||
SetHighlight(officer_ammoShelf_1.Item, false);
|
SetHighlight(officer_ammoShelf_1.Item, false);
|
||||||
SetHighlight(officer_ammoShelf_2.Item, false);
|
SetHighlight(officer_ammoShelf_2.Item, false);
|
||||||
RemoveCompletedObjective(segments[3]);
|
RemoveCompletedObjective(3);
|
||||||
yield return new WaitForSeconds(2f, false);
|
yield return new WaitForSeconds(2f, false);
|
||||||
TriggerTutorialSegment(4, GameMain.Config.KeyBindText(InputType.Select), GameMain.Config.KeyBindText(InputType.Shoot), GameMain.Config.KeyBindText(InputType.Deselect)); // Kill hammerhead
|
TriggerTutorialSegment(4, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Select), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Shoot), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Deselect)); // Kill hammerhead
|
||||||
officer_hammerhead = SpawnMonster("hammerhead", officer_hammerheadSpawnPos);
|
officer_hammerhead = SpawnMonster("hammerhead", officer_hammerheadSpawnPos);
|
||||||
officer_hammerhead.Params.AI.AvoidAbyss = false;
|
officer_hammerhead.Params.AI.AvoidAbyss = false;
|
||||||
officer_hammerhead.Params.AI.StayInAbyss = false;
|
officer_hammerhead.Params.AI.StayInAbyss = false;
|
||||||
@@ -348,7 +400,7 @@ namespace Barotrauma.Tutorials
|
|||||||
while(!officer_hammerhead.IsDead);
|
while(!officer_hammerhead.IsDead);
|
||||||
Heal(officer);
|
Heal(officer);
|
||||||
SetHighlight(officer_coilgunPeriscope, false);
|
SetHighlight(officer_coilgunPeriscope, false);
|
||||||
RemoveCompletedObjective(segments[4]);
|
RemoveCompletedObjective(4);
|
||||||
yield return new WaitForSeconds(1f, false);
|
yield return new WaitForSeconds(1f, false);
|
||||||
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Officer.Radio.HammerheadDead"), ChatMessageType.Radio, null);
|
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Officer.Radio.HammerheadDead"), ChatMessageType.Radio, null);
|
||||||
SetDoorAccess(officer_thirdDoor, officer_thirdDoorLight, true);
|
SetDoorAccess(officer_thirdDoor, officer_thirdDoorLight, true);
|
||||||
@@ -357,16 +409,16 @@ namespace Barotrauma.Tutorials
|
|||||||
//do { yield return null; } while (!officer_rangedWeaponSensor.MotionDetected);
|
//do { yield return null; } while (!officer_rangedWeaponSensor.MotionDetected);
|
||||||
do { yield return null; } while (!officer_thirdDoor.IsOpen);
|
do { yield return null; } while (!officer_thirdDoor.IsOpen);
|
||||||
yield return new WaitForSeconds(3f, false);
|
yield return new WaitForSeconds(3f, false);
|
||||||
TriggerTutorialSegment(5, GameMain.Config.KeyBindText(InputType.Aim), GameMain.Config.KeyBindText(InputType.Shoot)); // Ranged weapons
|
TriggerTutorialSegment(5, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Aim), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Shoot)); // Ranged weapons
|
||||||
SetHighlight(officer_rangedWeaponHolder.Item, true);
|
SetHighlight(officer_rangedWeaponHolder.Item, true);
|
||||||
do { yield return null; } while (!officer_rangedWeaponHolder.Inventory.IsEmpty()); // Wait until looted
|
do { yield return null; } while (!officer_rangedWeaponHolder.Inventory.IsEmpty()); // Wait until looted
|
||||||
SetHighlight(officer_rangedWeaponHolder.Item, false);
|
SetHighlight(officer_rangedWeaponHolder.Item, false);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
HighlightInventorySlot(officer.Inventory, "shotgun", highlightColor, 0.5f, 0.5f, 0f);
|
HighlightInventorySlot(officer.Inventory, "shotgun".ToIdentifier(), highlightColor, 0.5f, 0.5f, 0f);
|
||||||
yield return null;
|
yield return null;
|
||||||
} while (!officer.HasEquippedItem("shotgun")); // Wait until equipped
|
} while (!officer.HasEquippedItem("shotgun".ToIdentifier())); // Wait until equipped
|
||||||
ItemContainer shotGunChamber = officer.Inventory.FindItemByIdentifier("shotgun").GetComponent<ItemContainer>();
|
ItemContainer shotGunChamber = officer.Inventory.FindItemByIdentifier("shotgun".ToIdentifier()).GetComponent<ItemContainer>();
|
||||||
SetHighlight(officer_rangedWeaponCabinet.Item, true);
|
SetHighlight(officer_rangedWeaponCabinet.Item, true);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@@ -392,13 +444,13 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (officer.Inventory.FindItemByIdentifier("shotgunshell") != null || (IsSelectedItem(officer_rangedWeaponCabinet.Item) && officer_rangedWeaponCabinet.Inventory.FindItemByIdentifier("shotgunshell") != null))
|
if (officer.Inventory.FindItemByIdentifier("shotgunshell".ToIdentifier()) != null || (IsSelectedItem(officer_rangedWeaponCabinet.Item) && officer_rangedWeaponCabinet.Inventory.FindItemByIdentifier("shotgunshell".ToIdentifier()) != null))
|
||||||
{
|
{
|
||||||
HighlightInventorySlot(officer.Inventory, "shotgun", highlightColor, 0.5f, 0.5f, 0f);
|
HighlightInventorySlot(officer.Inventory, "shotgun".ToIdentifier(), highlightColor, 0.5f, 0.5f, 0f);
|
||||||
}
|
}
|
||||||
yield return null;
|
yield return null;
|
||||||
} while (!shotGunChamber.Inventory.IsFull(takeStacksIntoAccount: true)); // Wait until all six harpoons loaded
|
} while (!shotGunChamber.Inventory.IsFull(takeStacksIntoAccount: true)); // Wait until all six harpoons loaded
|
||||||
RemoveCompletedObjective(segments[5]);
|
RemoveCompletedObjective(5);
|
||||||
SetHighlight(officer_rangedWeaponCabinet.Item, false);
|
SetHighlight(officer_rangedWeaponCabinet.Item, false);
|
||||||
SetDoorAccess(officer_fourthDoor, officer_fourthDoorLight, true);
|
SetDoorAccess(officer_fourthDoor, officer_fourthDoorLight, true);
|
||||||
|
|
||||||
@@ -408,7 +460,7 @@ namespace Barotrauma.Tutorials
|
|||||||
officer_mudraptor = SpawnMonster("mudraptor", officer_mudraptorSpawnPos);
|
officer_mudraptor = SpawnMonster("mudraptor", officer_mudraptorSpawnPos);
|
||||||
do { yield return null; } while (!officer_mudraptor.IsDead);
|
do { yield return null; } while (!officer_mudraptor.IsDead);
|
||||||
Heal(officer);
|
Heal(officer);
|
||||||
RemoveCompletedObjective(segments[6]);
|
RemoveCompletedObjective(6);
|
||||||
SetDoorAccess(tutorial_securityFinalDoor, tutorial_securityFinalDoorLight, true);
|
SetDoorAccess(tutorial_securityFinalDoor, tutorial_securityFinalDoorLight, true);
|
||||||
|
|
||||||
// Submarine
|
// Submarine
|
||||||
@@ -459,7 +511,7 @@ namespace Barotrauma.Tutorials
|
|||||||
officer.RemoveActiveObjectiveEntity(officer_subSuperCapacitor_2.Item);
|
officer.RemoveActiveObjectiveEntity(officer_subSuperCapacitor_2.Item);
|
||||||
officer.RemoveActiveObjectiveEntity(officer_subAmmoBox_1);
|
officer.RemoveActiveObjectiveEntity(officer_subAmmoBox_1);
|
||||||
officer.RemoveActiveObjectiveEntity(officer_subAmmoBox_2);
|
officer.RemoveActiveObjectiveEntity(officer_subAmmoBox_2);
|
||||||
RemoveCompletedObjective(segments[7]);
|
RemoveCompletedObjective(7);
|
||||||
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Officer.Radio.Complete"), ChatMessageType.Radio, null);
|
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Officer.Radio.Complete"), ChatMessageType.Radio, null);
|
||||||
|
|
||||||
yield return new WaitForSeconds(4f, false);
|
yield return new WaitForSeconds(4f, false);
|
||||||
|
|||||||
+40
-53
@@ -8,18 +8,21 @@ using System.Xml.Linq;
|
|||||||
|
|
||||||
namespace Barotrauma.Tutorials
|
namespace Barotrauma.Tutorials
|
||||||
{
|
{
|
||||||
class ScenarioTutorial : Tutorial
|
abstract class ScenarioTutorial : Tutorial
|
||||||
{
|
{
|
||||||
private CoroutineHandle tutorialCoroutine;
|
private CoroutineHandle tutorialCoroutine;
|
||||||
|
|
||||||
private Character character;
|
private Character character;
|
||||||
private string spawnSub;
|
|
||||||
private SpawnType spawnPointType;
|
private const string submarinePath = "Content/Tutorials/Dugong_Tutorial.sub";
|
||||||
private string submarinePath;
|
private const string startOutpostPath = "Content/Tutorials/TutorialOutpost.sub";
|
||||||
private string startOutpostPath;
|
//private const string endOutpostPath = "";
|
||||||
private string endOutpostPath;
|
|
||||||
private string levelSeed;
|
private const string levelSeed = "nLoZLLtza";
|
||||||
private string levelParams;
|
private const string levelParams = "ColdCavernsTutorial";
|
||||||
|
|
||||||
|
//private const string spawnSub = "startoutpost";
|
||||||
|
private const SpawnType spawnPointType = SpawnType.Human;
|
||||||
|
|
||||||
private SubmarineInfo startOutpost = null;
|
private SubmarineInfo startOutpost = null;
|
||||||
private SubmarineInfo endOutpost = null;
|
private SubmarineInfo endOutpost = null;
|
||||||
@@ -31,34 +34,18 @@ namespace Barotrauma.Tutorials
|
|||||||
protected Color highlightColor = Color.OrangeRed;
|
protected Color highlightColor = Color.OrangeRed;
|
||||||
protected Color uiHighlightColor = new Color(150, 50, 0);
|
protected Color uiHighlightColor = new Color(150, 50, 0);
|
||||||
protected Color buttonHighlightColor = new Color(255, 100, 0);
|
protected Color buttonHighlightColor = new Color(255, 100, 0);
|
||||||
protected Color inaccessibleColor = GUI.Style.Red;
|
protected Color inaccessibleColor = GUIStyle.Red;
|
||||||
protected Color accessibleColor = GUI.Style.Green;
|
protected Color accessibleColor = GUIStyle.Green;
|
||||||
|
|
||||||
public ScenarioTutorial(XElement element) : base(element)
|
protected ScenarioTutorial(Identifier identifier, params Segment[] segments) : base(identifier, segments) { }
|
||||||
{
|
|
||||||
submarinePath = element.GetAttributeString("submarinepath", "");
|
|
||||||
startOutpostPath = element.GetAttributeString("startoutpostpath", "");
|
|
||||||
endOutpostPath = element.GetAttributeString("endoutpostpath", "");
|
|
||||||
|
|
||||||
levelSeed = element.GetAttributeString("levelseed", "tuto");
|
protected abstract void Initialize();
|
||||||
levelParams = element.GetAttributeString("levelparams", "");
|
|
||||||
|
|
||||||
spawnSub = element.GetAttributeString("spawnsub", "");
|
protected override IEnumerable<CoroutineStatus> Loading()
|
||||||
Enum.TryParse(element.GetAttributeString("spawnpointtype", "Human"), true, out spawnPointType);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
currentTutorialCompleted = false;
|
|
||||||
GameMain.Instance.ShowLoading(Loading());
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerable<CoroutineStatus> Loading()
|
|
||||||
{
|
{
|
||||||
SubmarineInfo subInfo = new SubmarineInfo(submarinePath);
|
SubmarineInfo subInfo = new SubmarineInfo(submarinePath);
|
||||||
|
|
||||||
LevelGenerationParams generationParams = LevelGenerationParams.LevelParams.Find(p => p.Identifier.Equals(levelParams, StringComparison.OrdinalIgnoreCase));
|
LevelGenerationParams generationParams = LevelGenerationParams.LevelParams.Find(p => p.Identifier == levelParams);
|
||||||
|
|
||||||
yield return CoroutineStatus.Running;
|
yield return CoroutineStatus.Running;
|
||||||
|
|
||||||
@@ -68,18 +55,18 @@ namespace Barotrauma.Tutorials
|
|||||||
if (generationParams != null)
|
if (generationParams != null)
|
||||||
{
|
{
|
||||||
Biome biome =
|
Biome biome =
|
||||||
LevelGenerationParams.GetBiomes().FirstOrDefault(b => generationParams.AllowedBiomes.Contains(b)) ??
|
Biome.Prefabs.FirstOrDefault(b => generationParams.AllowedBiomeIdentifiers.Contains(b.Identifier)) ??
|
||||||
LevelGenerationParams.GetBiomes().First();
|
Biome.Prefabs.First();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(startOutpostPath))
|
if (!string.IsNullOrEmpty(startOutpostPath))
|
||||||
{
|
{
|
||||||
startOutpost = new SubmarineInfo(startOutpostPath);
|
startOutpost = new SubmarineInfo(startOutpostPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(endOutpostPath))
|
/*if (!string.IsNullOrEmpty(endOutpostPath))
|
||||||
{
|
{
|
||||||
endOutpost = new SubmarineInfo(endOutpostPath);
|
endOutpost = new SubmarineInfo(endOutpostPath);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
LevelData tutorialLevel = new LevelData(levelSeed, 0, 0, generationParams, biome);
|
LevelData tutorialLevel = new LevelData(levelSeed, 0, 0, generationParams, biome);
|
||||||
GameMain.GameSession.StartRound(tutorialLevel, startOutpost: startOutpost, endOutpost: endOutpost);
|
GameMain.GameSession.StartRound(tutorialLevel, startOutpost: startOutpost, endOutpost: endOutpost);
|
||||||
@@ -93,12 +80,6 @@ namespace Barotrauma.Tutorials
|
|||||||
GameMain.GameSession.EventManager.Enabled = false;
|
GameMain.GameSession.EventManager.Enabled = false;
|
||||||
GameMain.GameScreen.Select();
|
GameMain.GameScreen.Select();
|
||||||
|
|
||||||
yield return CoroutineStatus.Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Start()
|
|
||||||
{
|
|
||||||
base.Start();
|
|
||||||
|
|
||||||
Submarine.MainSub.GodMode = true;
|
Submarine.MainSub.GodMode = true;
|
||||||
foreach (Structure wall in Structure.WallList)
|
foreach (Structure wall in Structure.WallList)
|
||||||
@@ -109,16 +90,15 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CharacterInfo charInfo = configElement.Element("Character") == null ?
|
CharacterInfo charInfo = GetCharacterInfo();
|
||||||
new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("engineer")) :
|
|
||||||
new CharacterInfo(configElement.Element("Character"));
|
|
||||||
|
|
||||||
WayPoint wayPoint = GetSpawnPoint(charInfo);
|
WayPoint wayPoint = GetSpawnPoint(charInfo);
|
||||||
|
|
||||||
if (wayPoint == null)
|
if (wayPoint == null)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("A waypoint with the spawntype \"" + spawnPointType + "\" is required for the tutorial event");
|
DebugConsole.ThrowError("A waypoint with the spawntype \"" + spawnPointType + "\" is required for the tutorial event");
|
||||||
return;
|
yield return CoroutineStatus.Failure;
|
||||||
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
character = Character.Create(charInfo, wayPoint.WorldPosition, "", isRemotePlayer: false, hasAi: false);
|
character = Character.Create(charInfo, wayPoint.WorldPosition, "", isRemotePlayer: false, hasAi: false);
|
||||||
@@ -126,11 +106,12 @@ namespace Barotrauma.Tutorials
|
|||||||
Character.Controlled = character;
|
Character.Controlled = character;
|
||||||
character.GiveJobItems(null);
|
character.GiveJobItems(null);
|
||||||
|
|
||||||
var idCard = character.Inventory.FindItemByIdentifier("idcard");
|
var idCard = character.Inventory.FindItemByIdentifier("idcard".ToIdentifier());
|
||||||
if (idCard == null)
|
if (idCard == null)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Item prefab \"ID Card\" not found!");
|
DebugConsole.ThrowError("Item prefab \"ID Card\" not found!");
|
||||||
return;
|
yield return CoroutineStatus.Failure;
|
||||||
|
yield break;
|
||||||
}
|
}
|
||||||
idCard.AddTag("com");
|
idCard.AddTag("com");
|
||||||
idCard.AddTag("eng");
|
idCard.AddTag("eng");
|
||||||
@@ -145,8 +126,14 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
|
|
||||||
tutorialCoroutine = CoroutineManager.StartCoroutine(UpdateState());
|
tutorialCoroutine = CoroutineManager.StartCoroutine(UpdateState());
|
||||||
|
|
||||||
|
Initialize();
|
||||||
|
|
||||||
|
yield return CoroutineStatus.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract CharacterInfo GetCharacterInfo();
|
||||||
|
|
||||||
public override void AddToGUIUpdateList()
|
public override void AddToGUIUpdateList()
|
||||||
{
|
{
|
||||||
if (!currentTutorialCompleted)
|
if (!currentTutorialCompleted)
|
||||||
@@ -157,7 +144,7 @@ namespace Barotrauma.Tutorials
|
|||||||
|
|
||||||
private WayPoint GetSpawnPoint(CharacterInfo charInfo)
|
private WayPoint GetSpawnPoint(CharacterInfo charInfo)
|
||||||
{
|
{
|
||||||
Submarine spawnSub = null;
|
/*Submarine spawnSub = null;
|
||||||
|
|
||||||
if (this.spawnSub != string.Empty)
|
if (this.spawnSub != string.Empty)
|
||||||
{
|
{
|
||||||
@@ -175,15 +162,15 @@ namespace Barotrauma.Tutorials
|
|||||||
spawnSub = Submarine.MainSub;
|
spawnSub = Submarine.MainSub;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
Submarine spawnSub = Level.Loaded.StartOutpost;
|
||||||
return WayPoint.GetRandom(spawnPointType, charInfo.Job?.Prefab, spawnSub);
|
return WayPoint.GetRandom(spawnPointType, charInfo.Job?.Prefab, spawnSub);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected bool HasOrder(Character character, string identifier, string option = null)
|
protected bool HasOrder(Character character, string identifier, string option = null)
|
||||||
{
|
{
|
||||||
var currentOrderInfo = character.GetCurrentOrderWithTopPriority();
|
var currentOrderInfo = character.GetCurrentOrderWithTopPriority();
|
||||||
if (currentOrderInfo?.Order?.Identifier == identifier)
|
if (currentOrderInfo?.Identifier == identifier)
|
||||||
{
|
{
|
||||||
if (option == null)
|
if (option == null)
|
||||||
{
|
{
|
||||||
@@ -191,7 +178,7 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return currentOrderInfo?.OrderOption == option;
|
return currentOrderInfo?.Option == option;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,7 +254,7 @@ namespace Barotrauma.Tutorials
|
|||||||
|
|
||||||
yield return new WaitForSeconds(3.0f);
|
yield return new WaitForSeconds(3.0f);
|
||||||
|
|
||||||
var messageBox = new GUIMessageBox(TextManager.Get("Tutorial.TryAgainHeader"), TextManager.Get("Tutorial.TryAgain"), new string[] { TextManager.Get("Yes"), TextManager.Get("No") });
|
var messageBox = new GUIMessageBox(TextManager.Get("Tutorial.TryAgainHeader"), TextManager.Get("Tutorial.TryAgain"), new LocalizedString[] { TextManager.Get("Yes"), TextManager.Get("No") });
|
||||||
|
|
||||||
messageBox.Buttons[0].OnClicked += Restart;
|
messageBox.Buttons[0].OnClicked += Restart;
|
||||||
messageBox.Buttons[0].OnClicked += messageBox.Close;
|
messageBox.Buttons[0].OnClicked += messageBox.Close;
|
||||||
@@ -303,7 +290,7 @@ namespace Barotrauma.Tutorials
|
|||||||
character.SetStun(0.0f, true);
|
character.SetStun(0.0f, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Item FindOrGiveItem(Character character, string identifier)
|
protected Item FindOrGiveItem(Character character, Identifier identifier)
|
||||||
{
|
{
|
||||||
var item = character.Inventory.FindItemByIdentifier(identifier);
|
var item = character.Inventory.FindItemByIdentifier(identifier);
|
||||||
if (item != null && !item.Removed) { return item; }
|
if (item != null && !item.Removed) { return item; }
|
||||||
|
|||||||
+159
-232
@@ -7,189 +7,128 @@ using System.Linq;
|
|||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using Barotrauma.Items.Components;
|
using Barotrauma.Items.Components;
|
||||||
using Barotrauma.Extensions;
|
using Barotrauma.Extensions;
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
|
||||||
namespace Barotrauma.Tutorials
|
namespace Barotrauma.Tutorials
|
||||||
{
|
{
|
||||||
|
enum TutorialContentType { None = 0, Video = 1, ManualVideo = 2, TextOnly = 3 };
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If you're seeing this and are currently working on improving the tutorials, consider
|
||||||
|
/// deleting this class and all that derive from it, and starting from scratch.
|
||||||
|
/// </summary>
|
||||||
abstract class Tutorial
|
abstract class Tutorial
|
||||||
{
|
{
|
||||||
#region Tutorial variables
|
#region Constants
|
||||||
public static bool Initialized = false;
|
public const string PlayableContentPath = "Content/Tutorials/TutorialVideos/";
|
||||||
public static bool ContentRunning = false;
|
#endregion
|
||||||
public static List<Tutorial> Tutorials;
|
|
||||||
|
#region Tutorial variables
|
||||||
|
public static ImmutableHashSet<Type> Types;
|
||||||
|
static Tutorial()
|
||||||
|
{
|
||||||
|
Types = ReflectionUtils.GetDerivedNonAbstract<Tutorial>()
|
||||||
|
.ToImmutableHashSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly Identifier Identifier;
|
||||||
|
|
||||||
|
public LocalizedString DisplayName { get; }
|
||||||
|
|
||||||
|
public bool ContentRunning { get; protected set; }
|
||||||
|
|
||||||
protected bool started = false;
|
|
||||||
protected GUIComponent infoBox;
|
protected GUIComponent infoBox;
|
||||||
private Action infoBoxClosedCallback;
|
private Action infoBoxClosedCallback;
|
||||||
protected XElement configElement;
|
|
||||||
|
|
||||||
protected VideoPlayer videoPlayer;
|
protected VideoPlayer videoPlayer;
|
||||||
protected enum TutorialContentTypes { None = 0, Video = 1, ManualVideo = 2, TextOnly = 3 };
|
|
||||||
protected string playableContentPath;
|
|
||||||
protected Point screenResolution;
|
protected Point screenResolution;
|
||||||
protected WindowMode windowMode;
|
protected WindowMode windowMode;
|
||||||
protected float prevUIScale;
|
protected float prevUIScale;
|
||||||
|
|
||||||
private GUIFrame holderFrame, objectiveFrame;
|
private GUIFrame holderFrame, objectiveFrame;
|
||||||
private List<TutorialSegment> activeObjectives = new List<TutorialSegment>();
|
private readonly List<Index> activeObjectives;
|
||||||
private string objectiveTranslated;
|
private readonly LocalizedString objectiveTranslated;
|
||||||
|
|
||||||
protected TutorialSegment activeContentSegment;
|
protected readonly ImmutableArray<Segment> segments;
|
||||||
protected List<TutorialSegment> segments;
|
protected Index activeContentSegmentIndex;
|
||||||
|
protected Segment activeContentSegment => segments[activeContentSegmentIndex];
|
||||||
|
|
||||||
protected class TutorialSegment
|
protected class Segment
|
||||||
{
|
{
|
||||||
public string Id;
|
public struct Text
|
||||||
public string Objective;
|
{
|
||||||
public TutorialContentTypes ContentType;
|
public Identifier Tag;
|
||||||
public XElement TextContent;
|
public int Width;
|
||||||
public XElement VideoContent;
|
public int Height;
|
||||||
|
public Anchor Anchor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct Video
|
||||||
|
{
|
||||||
|
public string File;
|
||||||
|
public Identifier TextTag;
|
||||||
|
public int Width;
|
||||||
|
public int Height;
|
||||||
|
}
|
||||||
|
|
||||||
public bool IsTriggered;
|
public bool IsTriggered;
|
||||||
public GUIButton ReplayButton;
|
public GUIButton ReplayButton;
|
||||||
public GUITextBlock LinkedTitle, LinkedText;
|
public GUITextBlock LinkedTitle, LinkedText;
|
||||||
public object[] Args;
|
public object[] Args;
|
||||||
|
public LocalizedString Objective;
|
||||||
|
|
||||||
public TutorialSegment(XElement config)
|
public readonly Identifier Id;
|
||||||
|
public readonly Text? TextContent;
|
||||||
|
public readonly Video? VideoContent;
|
||||||
|
public readonly TutorialContentType ContentType;
|
||||||
|
|
||||||
|
public Segment(Identifier id, Identifier objectiveTextTag, TutorialContentType contentType, Text? textContent = null, Video? videoContent = null)
|
||||||
{
|
{
|
||||||
Id = config.GetAttributeString("id", "Missing ID");
|
Id = id;
|
||||||
Objective = TextManager.Get(config.GetAttributeString("objective", string.Empty), true);
|
Objective = TextManager.ParseInputTypes(TextManager.Get(objectiveTextTag));
|
||||||
Enum.TryParse(config.GetAttributeString("contenttype", "None"), true, out ContentType);
|
ContentType = contentType;
|
||||||
IsTriggered = config.GetAttributeBool("istriggered", false);
|
TextContent = textContent;
|
||||||
|
VideoContent = videoContent;
|
||||||
|
|
||||||
switch (ContentType)
|
IsTriggered = false;
|
||||||
{
|
|
||||||
case TutorialContentTypes.None:
|
|
||||||
break;
|
|
||||||
case TutorialContentTypes.Video:
|
|
||||||
case TutorialContentTypes.ManualVideo:
|
|
||||||
VideoContent = config.Element("Video");
|
|
||||||
TextContent = config.Element("Text");
|
|
||||||
break;
|
|
||||||
case TutorialContentTypes.TextOnly:
|
|
||||||
TextContent = config.Element("Text");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Identifier
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
protected set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string DisplayName
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
protected set;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool completed;
|
private bool completed;
|
||||||
public bool Completed
|
public bool Completed
|
||||||
{
|
{
|
||||||
get { return completed; }
|
get { return completed; }
|
||||||
protected set
|
protected set
|
||||||
{
|
{
|
||||||
if (completed == value) return;
|
if (completed == value) { return; }
|
||||||
completed = value;
|
completed = value;
|
||||||
GameMain.Config.SaveNewPlayerConfig();
|
if (value)
|
||||||
|
{
|
||||||
|
CompletedTutorials.Instance.Add(Identifier);
|
||||||
|
}
|
||||||
|
GameSettings.SaveCurrentConfig();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Tutorial Controls
|
#region Tutorial Controls
|
||||||
public static void Init()
|
protected Tutorial(Identifier identifier, params Segment[] segments)
|
||||||
{
|
{
|
||||||
Tutorials = new List<Tutorial>();
|
Identifier = identifier;
|
||||||
foreach (ContentFile file in GameMain.Instance.GetFilesOfType(ContentType.Tutorials))
|
this.segments = segments.ToImmutableArray();
|
||||||
{
|
|
||||||
XDocument doc = XMLExtensions.TryLoadXml(file.Path);
|
|
||||||
if (doc?.Root == null) continue;
|
|
||||||
|
|
||||||
foreach (XElement element in doc.Root.Elements())
|
|
||||||
{
|
|
||||||
Tutorial newTutorial = Load(element);
|
|
||||||
if (newTutorial != null) Tutorials.Add(newTutorial);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Tutorial Load(XElement element)
|
|
||||||
{
|
|
||||||
Type t;
|
|
||||||
string type = element.Name.ToString().ToLowerInvariant();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Get the type of a specified class.
|
|
||||||
t = Type.GetType("Barotrauma.Tutorials." + type + "", false, true);
|
|
||||||
if (t == null)
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError("Could not find tutorial type \"" + type + "\"");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError("Could not find tutorial type \"" + type + "\"", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConstructorInfo constructor;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!t.IsSubclassOf(typeof(Tutorial))) return null;
|
|
||||||
constructor = t.GetConstructor(new Type[] { typeof(XElement) });
|
|
||||||
if (constructor == null)
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError("Could not find the constructor of tutorial type \"" + type + "\"");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError("Could not find the constructor of tutorial type \"" + type + "\"", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
Tutorial tutorial = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
object component = constructor.Invoke(new object[] { element });
|
|
||||||
tutorial = (Tutorial)component;
|
|
||||||
}
|
|
||||||
catch (TargetInvocationException e)
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError("Error while loading tutorial of the type " + t + ".", e.InnerException);
|
|
||||||
}
|
|
||||||
|
|
||||||
return tutorial;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Tutorial(XElement element)
|
|
||||||
{
|
|
||||||
configElement = element;
|
|
||||||
Identifier = element.GetAttributeString("identifier", "unknown");
|
|
||||||
DisplayName = TextManager.Get(Identifier);
|
DisplayName = TextManager.Get(Identifier);
|
||||||
completed = GameMain.Config.CompletedTutorialNames.Contains(Identifier);
|
activeObjectives = new List<Index>();
|
||||||
playableContentPath = element.GetAttributeString("playablecontentpath", "");
|
|
||||||
|
|
||||||
segments = new List<TutorialSegment>();
|
|
||||||
|
|
||||||
foreach (var segment in element.Elements("Segment"))
|
|
||||||
{
|
|
||||||
segments.Add(new TutorialSegment(segment));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void Initialize()
|
|
||||||
{
|
|
||||||
if (Initialized) return;
|
|
||||||
Initialized = true;
|
|
||||||
videoPlayer = new VideoPlayer();
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void Start()
|
|
||||||
{
|
|
||||||
activeObjectives.Clear();
|
|
||||||
objectiveTranslated = TextManager.Get("Tutorial.Objective");
|
objectiveTranslated = TextManager.Get("Tutorial.Objective");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract IEnumerable<CoroutineStatus> Loading();
|
||||||
|
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
videoPlayer = new VideoPlayer();
|
||||||
|
GameMain.Instance.ShowLoading(Loading());
|
||||||
|
|
||||||
|
activeObjectives.Clear();
|
||||||
CreateObjectiveFrame();
|
CreateObjectiveFrame();
|
||||||
|
|
||||||
// Setup doors: Clear all requirements, unless the door is setup as locked.
|
// Setup doors: Clear all requirements, unless the door is setup as locked.
|
||||||
@@ -208,7 +147,7 @@ namespace Barotrauma.Tutorials
|
|||||||
|
|
||||||
public virtual void AddToGUIUpdateList()
|
public virtual void AddToGUIUpdateList()
|
||||||
{
|
{
|
||||||
if (GameMain.GraphicsWidth != screenResolution.X || GameMain.GraphicsHeight != screenResolution.Y || prevUIScale != GUI.Scale || GameMain.Config.WindowMode != windowMode)
|
if (GameMain.GraphicsWidth != screenResolution.X || GameMain.GraphicsHeight != screenResolution.Y || prevUIScale != GUI.Scale || GameSettings.CurrentConfig.Graphics.DisplayMode != windowMode)
|
||||||
{
|
{
|
||||||
CreateObjectiveFrame();
|
CreateObjectiveFrame();
|
||||||
}
|
}
|
||||||
@@ -255,74 +194,69 @@ namespace Barotrauma.Tutorials
|
|||||||
protected bool Restart(GUIButton button, object obj)
|
protected bool Restart(GUIButton button, object obj)
|
||||||
{
|
{
|
||||||
GUI.PreventPauseMenuToggle = false;
|
GUI.PreventPauseMenuToggle = false;
|
||||||
TutorialMode.StartTutorial(this);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void TriggerTutorialSegment(int index, params object[] args)
|
protected virtual void TriggerTutorialSegment(Index index, params object[] args)
|
||||||
{
|
{
|
||||||
Inventory.DraggingItems.Clear();
|
Inventory.DraggingItems.Clear();
|
||||||
ContentRunning = true;
|
ContentRunning = true;
|
||||||
activeContentSegment = segments[index];
|
activeContentSegmentIndex = index;
|
||||||
segments[index].Args = args;
|
segments[index].Args = args;
|
||||||
|
|
||||||
string tutorialText = TextManager.GetFormatted(activeContentSegment.TextContent.GetAttributeString("tag", ""), true, args);
|
LocalizedString tutorialText = TextManager.GetFormatted(segments[index].TextContent.Value.Tag, args);
|
||||||
tutorialText = TextManager.ParseInputTypes(tutorialText);
|
tutorialText = TextManager.ParseInputTypes(tutorialText);
|
||||||
string objectiveText = string.Empty;
|
LocalizedString objectiveText = string.Empty;
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(activeContentSegment.Objective))
|
if (!segments[index].Objective.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
if (args.Length == 0)
|
if (args.Length == 0)
|
||||||
{
|
{
|
||||||
objectiveText = activeContentSegment.Objective;
|
objectiveText = segments[index].Objective;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
objectiveText = string.Format(activeContentSegment.Objective, args);
|
objectiveText = TextManager.GetFormatted(segments[index].Objective, args);
|
||||||
}
|
}
|
||||||
objectiveText = TextManager.ParseInputTypes(objectiveText);
|
objectiveText = TextManager.ParseInputTypes(objectiveText);
|
||||||
activeContentSegment.Objective = objectiveText;
|
segments[index].Objective = objectiveText;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
activeContentSegment.IsTriggered = true; // Complete at this stage only if no related objective
|
segments[index].IsTriggered = true; // Complete at this stage only if no related objective
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
switch (activeContentSegment.ContentType)
|
switch (segments[index].ContentType)
|
||||||
{
|
{
|
||||||
case TutorialContentTypes.None:
|
case TutorialContentType.None:
|
||||||
break;
|
break;
|
||||||
case TutorialContentTypes.Video:
|
case TutorialContentType.Video:
|
||||||
infoBox = CreateInfoFrame(TextManager.Get(activeContentSegment.Id), tutorialText,
|
infoBox = CreateInfoFrame(TextManager.Get(activeContentSegment.Id), tutorialText,
|
||||||
activeContentSegment.TextContent.GetAttributeInt("width", 300),
|
activeContentSegment.TextContent.Value.Width,
|
||||||
activeContentSegment.TextContent.GetAttributeInt("height", 80),
|
activeContentSegment.TextContent.Value.Height,
|
||||||
activeContentSegment.TextContent.GetAttributeString("anchor", "Center"), true, () => LoadVideo(activeContentSegment));
|
activeContentSegment.TextContent.Value.Anchor, true, () => LoadVideo(activeContentSegment));
|
||||||
break;
|
break;
|
||||||
case TutorialContentTypes.ManualVideo:
|
case TutorialContentType.ManualVideo:
|
||||||
infoBox = CreateInfoFrame(TextManager.Get(activeContentSegment.Id), tutorialText,
|
infoBox = CreateInfoFrame(TextManager.Get(activeContentSegment.Id), tutorialText,
|
||||||
activeContentSegment.TextContent.GetAttributeInt("width", 300),
|
activeContentSegment.TextContent.Value.Width,
|
||||||
activeContentSegment.TextContent.GetAttributeInt("height", 80),
|
activeContentSegment.TextContent.Value.Height,
|
||||||
activeContentSegment.TextContent.GetAttributeString("anchor", "Center"), true, StopCurrentContentSegment, () => LoadVideo(activeContentSegment));
|
activeContentSegment.TextContent.Value.Anchor, true, StopCurrentContentSegment, () => LoadVideo(activeContentSegment));
|
||||||
break;
|
break;
|
||||||
case TutorialContentTypes.TextOnly:
|
case TutorialContentType.TextOnly:
|
||||||
infoBox = CreateInfoFrame(TextManager.Get(activeContentSegment.Id), tutorialText,
|
infoBox = CreateInfoFrame(TextManager.Get(activeContentSegment.Id), tutorialText,
|
||||||
activeContentSegment.TextContent.GetAttributeInt("width", 300),
|
activeContentSegment.TextContent.Value.Width,
|
||||||
activeContentSegment.TextContent.GetAttributeInt("height", 80),
|
activeContentSegment.TextContent.Value.Height,
|
||||||
activeContentSegment.TextContent.GetAttributeString("anchor", "Center"), true, StopCurrentContentSegment);
|
activeContentSegment.TextContent.Value.Anchor, true, StopCurrentContentSegment);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Stop()
|
public virtual void Stop()
|
||||||
{
|
{
|
||||||
started = ContentRunning = Initialized = false;
|
ContentRunning = false;
|
||||||
infoBox = null;
|
infoBox = null;
|
||||||
if (videoPlayer != null)
|
videoPlayer.Remove();
|
||||||
{
|
|
||||||
videoPlayer.Remove();
|
|
||||||
videoPlayer = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -334,50 +268,51 @@ namespace Barotrauma.Tutorials
|
|||||||
|
|
||||||
for (int i = 0; i < activeObjectives.Count; i++)
|
for (int i = 0; i < activeObjectives.Count; i++)
|
||||||
{
|
{
|
||||||
CreateObjectiveGUI(activeObjectives[i], i, activeObjectives[i].ContentType);
|
CreateObjectiveGUI(activeObjectives[i], i, segments[activeObjectives[i]].ContentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
screenResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
|
screenResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
|
||||||
windowMode = GameMain.Config.WindowMode;
|
windowMode = GameSettings.CurrentConfig.Graphics.DisplayMode;
|
||||||
prevUIScale = GUI.Scale;
|
prevUIScale = GUI.Scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void StopCurrentContentSegment()
|
protected void StopCurrentContentSegment()
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(activeContentSegment.Objective))
|
if (!activeContentSegment.Objective.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
AddNewObjective(activeContentSegment, activeContentSegment.ContentType);
|
AddNewObjective(activeContentSegmentIndex, activeContentSegment.ContentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
activeContentSegment = null;
|
|
||||||
ContentRunning = false;
|
ContentRunning = false;
|
||||||
|
activeContentSegmentIndex = Index.End;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void CheckActiveObjectives(TutorialSegment objective, float deltaTime)
|
protected virtual void CheckActiveObjectives(Index objective, float deltaTime)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected bool HasObjective(TutorialSegment segment)
|
protected bool HasObjective(Index segment)
|
||||||
{
|
{
|
||||||
return activeObjectives.Contains(segment);
|
return activeObjectives.Contains(segment);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void AddNewObjective(TutorialSegment segment, TutorialContentTypes type)
|
protected void AddNewObjective(Index segment, TutorialContentType type)
|
||||||
{
|
{
|
||||||
activeObjectives.Add(segment);
|
activeObjectives.Add(segment);
|
||||||
CreateObjectiveGUI(segment, activeObjectives.Count - 1, type);
|
CreateObjectiveGUI(segment, activeObjectives.Count - 1, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateObjectiveGUI(TutorialSegment segment, int index, TutorialContentTypes type)
|
private void CreateObjectiveGUI(Index segmentIndex, int index, TutorialContentType type)
|
||||||
{
|
{
|
||||||
string objectiveText = TextManager.ParseInputTypes(segment.Objective);
|
var segment = segments[segmentIndex];
|
||||||
Point replayButtonSize = new Point((int)(GUI.LargeFont.MeasureString(objectiveText).X), (int)(GUI.LargeFont.MeasureString(objectiveText).Y * 1.45f));
|
LocalizedString objectiveText = TextManager.ParseInputTypes(segment.Objective);
|
||||||
|
Point replayButtonSize = new Point((int)(GUIStyle.LargeFont.MeasureString(objectiveText).X), (int)(GUIStyle.LargeFont.MeasureString(objectiveText).Y * 1.45f));
|
||||||
|
|
||||||
segment.ReplayButton = new GUIButton(new RectTransform(replayButtonSize, objectiveFrame.RectTransform, Anchor.TopLeft, Pivot.TopLeft) { AbsoluteOffset = new Point(0, (replayButtonSize.Y + (int)(20f * GUI.Scale)) * index) }, style: null);
|
segment.ReplayButton = new GUIButton(new RectTransform(replayButtonSize, objectiveFrame.RectTransform, Anchor.TopLeft, Pivot.TopLeft) { AbsoluteOffset = new Point(0, (replayButtonSize.Y + (int)(20f * GUI.Scale)) * index) }, style: null);
|
||||||
segment.ReplayButton.OnClicked += (GUIButton btn, object userdata) =>
|
segment.ReplayButton.OnClicked += (GUIButton btn, object userdata) =>
|
||||||
{
|
{
|
||||||
if (type == TutorialContentTypes.Video)
|
if (type == TutorialContentType.Video)
|
||||||
{
|
{
|
||||||
ReplaySegmentVideo(segment);
|
ReplaySegmentVideo(segment);
|
||||||
}
|
}
|
||||||
@@ -388,23 +323,23 @@ namespace Barotrauma.Tutorials
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
string objectiveTitleText = TextManager.ParseInputTypes(objectiveTranslated);
|
LocalizedString objectiveTitleText = TextManager.ParseInputTypes(objectiveTranslated);
|
||||||
int yOffset = (int)((GUI.SubHeadingFont.MeasureString(objectiveTitleText).Y + 5));
|
int yOffset = (int)((GUIStyle.SubHeadingFont.MeasureString(objectiveTitleText).Y + 5));
|
||||||
segment.LinkedTitle = new GUITextBlock(new RectTransform(new Point((int)GUI.SubHeadingFont.MeasureString(objectiveTitleText).X, yOffset), segment.ReplayButton.RectTransform, Anchor.CenterLeft, Pivot.BottomLeft) /*{ AbsoluteOffset = new Point((int)(-10 * GUI.Scale), 0) }*/,
|
segment.LinkedTitle = new GUITextBlock(new RectTransform(new Point((int)GUIStyle.SubHeadingFont.MeasureString(objectiveTitleText).X, yOffset), segment.ReplayButton.RectTransform, Anchor.CenterLeft, Pivot.BottomLeft) /*{ AbsoluteOffset = new Point((int)(-10 * GUI.Scale), 0) }*/,
|
||||||
objectiveTitleText, textColor: Color.White, font: GUI.SubHeadingFont, textAlignment: Alignment.CenterLeft)
|
objectiveTitleText, textColor: Color.White, font: GUIStyle.SubHeadingFont, textAlignment: Alignment.CenterLeft)
|
||||||
{
|
{
|
||||||
ForceUpperCase = true
|
ForceUpperCase = ForceUpperCase.Yes
|
||||||
};
|
};
|
||||||
|
|
||||||
segment.LinkedText = new GUITextBlock(new RectTransform(new Point((int)GUI.LargeFont.MeasureString(objectiveText).X, yOffset), segment.ReplayButton.RectTransform, Anchor.CenterLeft, Pivot.TopLeft) /*{ AbsoluteOffset = new Point((int)(10 * GUI.Scale), 0) }*/,
|
segment.LinkedText = new GUITextBlock(new RectTransform(new Point((int)GUIStyle.LargeFont.MeasureString(objectiveText).X, yOffset), segment.ReplayButton.RectTransform, Anchor.CenterLeft, Pivot.TopLeft) /*{ AbsoluteOffset = new Point((int)(10 * GUI.Scale), 0) }*/,
|
||||||
objectiveText, textColor: new Color(4, 180, 108), font: GUI.LargeFont, textAlignment: Alignment.CenterLeft);
|
objectiveText, textColor: new Color(4, 180, 108), font: GUIStyle.LargeFont, textAlignment: Alignment.CenterLeft);
|
||||||
|
|
||||||
segment.LinkedTitle.Color = segment.LinkedTitle.HoverColor = segment.LinkedTitle.PressedColor = segment.LinkedTitle.SelectedColor = Color.Transparent;
|
segment.LinkedTitle.Color = segment.LinkedTitle.HoverColor = segment.LinkedTitle.PressedColor = segment.LinkedTitle.SelectedColor = Color.Transparent;
|
||||||
segment.LinkedText.Color = segment.LinkedText.HoverColor = segment.LinkedText.PressedColor = segment.LinkedText.SelectedColor = Color.Transparent;
|
segment.LinkedText.Color = segment.LinkedText.HoverColor = segment.LinkedText.PressedColor = segment.LinkedText.SelectedColor = Color.Transparent;
|
||||||
segment.ReplayButton.Color = segment.ReplayButton.HoverColor = segment.ReplayButton.PressedColor = segment.ReplayButton.SelectedColor = Color.Transparent;
|
segment.ReplayButton.Color = segment.ReplayButton.HoverColor = segment.ReplayButton.PressedColor = segment.ReplayButton.SelectedColor = Color.Transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReplaySegmentVideo(TutorialSegment segment)
|
private void ReplaySegmentVideo(Segment segment)
|
||||||
{
|
{
|
||||||
if (ContentRunning) return;
|
if (ContentRunning) return;
|
||||||
Inventory.DraggingItems.Clear();
|
Inventory.DraggingItems.Clear();
|
||||||
@@ -413,30 +348,31 @@ namespace Barotrauma.Tutorials
|
|||||||
//videoPlayer.LoadContent(playableContentPath, new VideoPlayer.VideoSettings(segment.VideoContent), new VideoPlayer.TextSettings(segment.VideoContent), segment.Id, true, callback: () => ContentRunning = false);
|
//videoPlayer.LoadContent(playableContentPath, new VideoPlayer.VideoSettings(segment.VideoContent), new VideoPlayer.TextSettings(segment.VideoContent), segment.Id, true, callback: () => ContentRunning = false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ShowSegmentText(TutorialSegment segment)
|
private void ShowSegmentText(Segment segment)
|
||||||
{
|
{
|
||||||
if (ContentRunning) return;
|
if (ContentRunning) return;
|
||||||
Inventory.DraggingItems.Clear();
|
Inventory.DraggingItems.Clear();
|
||||||
ContentRunning = true;
|
ContentRunning = true;
|
||||||
|
|
||||||
string tutorialText = TextManager.GetFormatted(segment.TextContent.GetAttributeString("tag", ""), true, segment.Args);
|
LocalizedString tutorialText = TextManager.GetFormatted(segment.TextContent.Value.Tag, segment.Args);
|
||||||
|
|
||||||
Action videoAction = null;
|
Action videoAction = null;
|
||||||
|
|
||||||
if (segment.ContentType != TutorialContentTypes.TextOnly)
|
if (segment.ContentType != TutorialContentType.TextOnly)
|
||||||
{
|
{
|
||||||
videoAction = () => LoadVideo(segment);
|
videoAction = () => LoadVideo(segment);
|
||||||
}
|
}
|
||||||
|
|
||||||
infoBox = CreateInfoFrame(TextManager.Get(segment.Id), tutorialText,
|
infoBox = CreateInfoFrame(TextManager.Get(segment.Id), tutorialText,
|
||||||
segment.TextContent.GetAttributeInt("width", 300),
|
segment.TextContent.Value.Width,
|
||||||
segment.TextContent.GetAttributeInt("height", 80),
|
segment.TextContent.Value.Height,
|
||||||
segment.TextContent.GetAttributeString("anchor", "Center"), true, () => ContentRunning = false, videoAction);
|
segment.TextContent.Value.Anchor, true, () => ContentRunning = false, videoAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void RemoveCompletedObjective(TutorialSegment segment)
|
protected void RemoveCompletedObjective(Index segmentIndex)
|
||||||
{
|
{
|
||||||
if (!HasObjective(segment)) return;
|
if (!HasObjective(segmentIndex)) return;
|
||||||
|
var segment = segments[segmentIndex];
|
||||||
segment.IsTriggered = true;
|
segment.IsTriggered = true;
|
||||||
segment.ReplayButton.OnClicked = null;
|
segment.ReplayButton.OnClicked = null;
|
||||||
|
|
||||||
@@ -467,18 +403,20 @@ namespace Barotrauma.Tutorials
|
|||||||
GUIImage stroke = new GUIImage(rectTB, "Stroke");
|
GUIImage stroke = new GUIImage(rectTB, "Stroke");
|
||||||
stroke.Color = stroke.SelectedColor = stroke.HoverColor = stroke.PressedColor = color;
|
stroke.Color = stroke.SelectedColor = stroke.HoverColor = stroke.PressedColor = color;
|
||||||
|
|
||||||
CoroutineManager.StartCoroutine(WaitForObjectiveEnd(segment));
|
CoroutineManager.StartCoroutine(WaitForObjectiveEnd(segmentIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<CoroutineStatus> WaitForObjectiveEnd(TutorialSegment objective)
|
private IEnumerable<CoroutineStatus> WaitForObjectiveEnd(Index objectiveIndex)
|
||||||
{
|
{
|
||||||
|
var objective = segments[objectiveIndex];
|
||||||
yield return new WaitForSeconds(2.0f);
|
yield return new WaitForSeconds(2.0f);
|
||||||
objectiveFrame.RemoveChild(objective.ReplayButton);
|
objectiveFrame.RemoveChild(objective.ReplayButton);
|
||||||
activeObjectives.Remove(objective);
|
activeObjectives.Remove(objectiveIndex);
|
||||||
|
|
||||||
for (int i = 0; i < activeObjectives.Count; i++)
|
for (int i = 0; i < activeObjectives.Count; i++)
|
||||||
{
|
{
|
||||||
activeObjectives[i].ReplayButton.RectTransform.AbsoluteOffset = new Point(0, (activeObjectives[i].ReplayButton.Rect.Height + 20) * i);
|
var activeObjective = segments[activeObjectives[i]];
|
||||||
|
activeObjective.ReplayButton.RectTransform.AbsoluteOffset = new Point(0, (activeObjective.ReplayButton.Rect.Height + 20) * i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -492,32 +430,25 @@ namespace Barotrauma.Tutorials
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected GUIComponent CreateInfoFrame(string title, string text, int width = 300, int height = 80, string anchorStr = "", bool hasButton = false, Action callback = null, Action showVideo = null)
|
protected GUIComponent CreateInfoFrame(LocalizedString title, LocalizedString text, int width = 300, int height = 80, Anchor anchor = Anchor.TopRight, bool hasButton = false, Action callback = null, Action showVideo = null)
|
||||||
{
|
{
|
||||||
if (hasButton) height += 60;
|
if (hasButton) height += 60;
|
||||||
|
|
||||||
Anchor anchor = Anchor.TopRight;
|
|
||||||
|
|
||||||
if (anchorStr != string.Empty)
|
|
||||||
{
|
|
||||||
Enum.TryParse(anchorStr, out anchor);
|
|
||||||
}
|
|
||||||
|
|
||||||
width = (int)(width * GUI.Scale);
|
width = (int)(width * GUI.Scale);
|
||||||
height = (int)(height * GUI.Scale);
|
height = (int)(height * GUI.Scale);
|
||||||
|
|
||||||
string wrappedText = ToolBox.WrapText(text, width, GUI.Font);
|
LocalizedString wrappedText = ToolBox.WrapText(text, width, GUIStyle.Font);
|
||||||
height += (int)GUI.Font.MeasureString(wrappedText).Y;
|
height += (int)GUIStyle.Font.MeasureString(wrappedText).Y;
|
||||||
|
|
||||||
if (title.Length > 0)
|
if (title.Length > 0)
|
||||||
{
|
{
|
||||||
height += (int)GUI.Font.MeasureString(title).Y + (int)(150 * GUI.Scale);
|
height += (int)GUIStyle.Font.MeasureString(title).Y + (int)(150 * GUI.Scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
var background = new GUIFrame(new RectTransform(new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight), GUI.Canvas, Anchor.Center), style: "GUIBackgroundBlocker");
|
var background = new GUIFrame(new RectTransform(new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight), GUI.Canvas, Anchor.Center), style: "GUIBackgroundBlocker");
|
||||||
|
|
||||||
var infoBlock = new GUIFrame(new RectTransform(new Point(width, height), background.RectTransform, anchor));
|
var infoBlock = new GUIFrame(new RectTransform(new Point(width, height), background.RectTransform, anchor));
|
||||||
infoBlock.Flash(GUI.Style.Green);
|
infoBlock.Flash(GUIStyle.Green);
|
||||||
|
|
||||||
var infoContent = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.9f), infoBlock.RectTransform, Anchor.Center))
|
var infoContent = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.9f), infoBlock.RectTransform, Anchor.Center))
|
||||||
{
|
{
|
||||||
@@ -528,20 +459,12 @@ namespace Barotrauma.Tutorials
|
|||||||
if (title.Length > 0)
|
if (title.Length > 0)
|
||||||
{
|
{
|
||||||
var titleBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoContent.RectTransform),
|
var titleBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoContent.RectTransform),
|
||||||
title, font: GUI.LargeFont, textAlignment: Alignment.Center, textColor: new Color(253, 174, 0));
|
title, font: GUIStyle.LargeFont, textAlignment: Alignment.Center, textColor: new Color(253, 174, 0));
|
||||||
titleBlock.RectTransform.IsFixedSize = true;
|
titleBlock.RectTransform.IsFixedSize = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<RichTextData> richTextData = RichTextData.GetRichTextData(" " + text, out text);
|
text = RichString.Rich(text);
|
||||||
GUITextBlock textBlock;
|
GUITextBlock textBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoContent.RectTransform), text, wrap: true);
|
||||||
if (richTextData == null)
|
|
||||||
{
|
|
||||||
textBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoContent.RectTransform), text, wrap: true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
textBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoContent.RectTransform), richTextData, text, wrap: true);
|
|
||||||
}
|
|
||||||
|
|
||||||
textBlock.RectTransform.IsFixedSize = true;
|
textBlock.RectTransform.IsFixedSize = true;
|
||||||
infoBoxClosedCallback = callback;
|
infoBoxClosedCallback = callback;
|
||||||
@@ -589,22 +512,26 @@ namespace Barotrauma.Tutorials
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Video
|
#region Video
|
||||||
protected void LoadVideo(TutorialSegment segment)
|
protected void LoadVideo(Segment segment)
|
||||||
{
|
{
|
||||||
if (videoPlayer == null) videoPlayer = new VideoPlayer();
|
if (videoPlayer == null) videoPlayer = new VideoPlayer();
|
||||||
if (segment.ContentType != TutorialContentTypes.ManualVideo)
|
if (segment.ContentType != TutorialContentType.ManualVideo)
|
||||||
{
|
{
|
||||||
videoPlayer.LoadContent(playableContentPath, new VideoPlayer.VideoSettings(segment.VideoContent), new VideoPlayer.TextSettings(segment.VideoContent), segment.Id, true, segment.Objective, StopCurrentContentSegment);
|
videoPlayer.LoadContent(
|
||||||
|
PlayableContentPath,
|
||||||
|
new VideoPlayer.VideoSettings(segment.VideoContent.Value.File),
|
||||||
|
new VideoPlayer.TextSettings(segment.VideoContent.Value.TextTag, segment.VideoContent.Value.Width),
|
||||||
|
segment.Id, true, segment.Objective, StopCurrentContentSegment);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
videoPlayer.LoadContent(playableContentPath, new VideoPlayer.VideoSettings(segment.VideoContent), null, segment.Id, true, string.Empty, null);
|
videoPlayer.LoadContent(PlayableContentPath, new VideoPlayer.VideoSettings(segment.VideoContent.Value.File), null, segment.Id, true, string.Empty, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Highlights
|
#region Highlights
|
||||||
protected void HighlightInventorySlot(Inventory inventory, string identifier, Color color, float fadeInDuration, float fadeOutDuration, float scaleUpAmount)
|
protected void HighlightInventorySlot(Inventory inventory, Identifier identifier, Color color, float fadeInDuration, float fadeOutDuration, float scaleUpAmount)
|
||||||
{
|
{
|
||||||
if (inventory.visualSlots == null) { return; }
|
if (inventory.visualSlots == null) { return; }
|
||||||
for (int i = 0; i < inventory.Capacity; i++)
|
for (int i = 0; i < inventory.Capacity; i++)
|
||||||
@@ -616,7 +543,7 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void HighlightInventorySlotWithTag(Inventory inventory, string tag, Color color, float fadeInDuration, float fadeOutDuration, float scaleUpAmount)
|
protected void HighlightInventorySlotWithTag(Inventory inventory, Identifier tag, Color color, float fadeInDuration, float fadeOutDuration, float scaleUpAmount)
|
||||||
{
|
{
|
||||||
if (inventory.visualSlots == null) { return; }
|
if (inventory.visualSlots == null) { return; }
|
||||||
for (int i = 0; i < inventory.Capacity; i++)
|
for (int i = 0; i < inventory.Capacity; i++)
|
||||||
|
|||||||
-6
@@ -6,11 +6,6 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
public Tutorial Tutorial;
|
public Tutorial Tutorial;
|
||||||
|
|
||||||
public static void StartTutorial(Tutorial tutorial)
|
|
||||||
{
|
|
||||||
tutorial.Initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
public TutorialMode(GameModePreset preset)
|
public TutorialMode(GameModePreset preset)
|
||||||
: base(preset)
|
: base(preset)
|
||||||
{
|
{
|
||||||
@@ -20,7 +15,6 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
base.Start();
|
base.Start();
|
||||||
GameMain.GameSession.CrewManager = new CrewManager(true);
|
GameMain.GameSession.CrewManager = new CrewManager(true);
|
||||||
Tutorial.Start();
|
|
||||||
foreach (Item item in Item.ItemList)
|
foreach (Item item in Item.ItemList)
|
||||||
{
|
{
|
||||||
//don't consider the items to belong in the outpost to prevent the stealing icon from showing
|
//don't consider the items to belong in the outpost to prevent the stealing icon from showing
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
tabMenu?.OnClose();
|
||||||
tabMenu = null;
|
tabMenu = null;
|
||||||
NetLobbyScreen.JobInfoFrame = null;
|
NetLobbyScreen.JobInfoFrame = null;
|
||||||
}
|
}
|
||||||
@@ -64,12 +65,12 @@ namespace Barotrauma
|
|||||||
GameMain.Instance.ResolutionChanged -= CreateTopLeftButtons;
|
GameMain.Instance.ResolutionChanged -= CreateTopLeftButtons;
|
||||||
};
|
};
|
||||||
int buttonHeight = GUI.IntScale(40);
|
int buttonHeight = GUI.IntScale(40);
|
||||||
Vector2 buttonSpriteSize = GUI.Style.GetComponentStyle("CrewListToggleButton").GetDefaultSprite().size;
|
Vector2 buttonSpriteSize = GUIStyle.GetComponentStyle("CrewListToggleButton").GetDefaultSprite().size;
|
||||||
int buttonWidth = (int)((buttonHeight / buttonSpriteSize.Y) * buttonSpriteSize.X);
|
int buttonWidth = (int)((buttonHeight / buttonSpriteSize.Y) * buttonSpriteSize.X);
|
||||||
Point buttonSize = new Point(buttonWidth, buttonHeight);
|
Point buttonSize = new Point(buttonWidth, buttonHeight);
|
||||||
crewListButton = new GUIButton(new RectTransform(buttonSize, parent: topLeftButtonGroup.RectTransform), style: "CrewListToggleButton")
|
crewListButton = new GUIButton(new RectTransform(buttonSize, parent: topLeftButtonGroup.RectTransform), style: "CrewListToggleButton")
|
||||||
{
|
{
|
||||||
ToolTip = TextManager.GetWithVariable("hudbutton.crewlist", "[key]", GameMain.Config.KeyBindText(InputType.CrewOrders)),
|
ToolTip = TextManager.GetWithVariable("hudbutton.crewlist", "[key]", GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.CrewOrders)),
|
||||||
OnClicked = (GUIButton btn, object userdata) =>
|
OnClicked = (GUIButton btn, object userdata) =>
|
||||||
{
|
{
|
||||||
if (CrewManager == null) { return false; }
|
if (CrewManager == null) { return false; }
|
||||||
@@ -79,7 +80,7 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
commandButton = new GUIButton(new RectTransform(buttonSize, parent: topLeftButtonGroup.RectTransform), style: "CommandButton")
|
commandButton = new GUIButton(new RectTransform(buttonSize, parent: topLeftButtonGroup.RectTransform), style: "CommandButton")
|
||||||
{
|
{
|
||||||
ToolTip = TextManager.GetWithVariable("hudbutton.commandinterface", "[key]", GameMain.Config.KeyBindText(InputType.Command)),
|
ToolTip = TextManager.GetWithVariable("hudbutton.commandinterface", "[key]", GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Command)),
|
||||||
OnClicked = (button, userData) =>
|
OnClicked = (button, userData) =>
|
||||||
{
|
{
|
||||||
if (CrewManager == null) { return false; }
|
if (CrewManager == null) { return false; }
|
||||||
@@ -89,7 +90,7 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
tabMenuButton = new GUIButton(new RectTransform(buttonSize, parent: topLeftButtonGroup.RectTransform), style: "TabMenuButton")
|
tabMenuButton = new GUIButton(new RectTransform(buttonSize, parent: topLeftButtonGroup.RectTransform), style: "TabMenuButton")
|
||||||
{
|
{
|
||||||
ToolTip = TextManager.GetWithVariable("hudbutton.tabmenu", "[key]", GameMain.Config.KeyBindText(InputType.InfoTab)),
|
ToolTip = TextManager.GetWithVariable("hudbutton.tabmenu", "[key]", GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.InfoTab)),
|
||||||
OnClicked = (button, userData) => ToggleTabMenu()
|
OnClicked = (button, userData) => ToggleTabMenu()
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -190,7 +191,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tabMenu.Update();
|
tabMenu.Update(deltaTime);
|
||||||
if ((PlayerInput.KeyHit(InputType.InfoTab) || PlayerInput.KeyHit(Microsoft.Xna.Framework.Input.Keys.Escape)) &&
|
if ((PlayerInput.KeyHit(InputType.InfoTab) || PlayerInput.KeyHit(Microsoft.Xna.Framework.Input.Keys.Escape)) &&
|
||||||
!(GUI.KeyboardDispatcher.Subscriber is GUITextBox))
|
!(GUI.KeyboardDispatcher.Subscriber is GUITextBox))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,14 +13,14 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
private const string HintManagerFile = "hintmanager.xml";
|
private const string HintManagerFile = "hintmanager.xml";
|
||||||
|
|
||||||
public static bool Enabled => GameMain.Config != null && !GameMain.Config.DisableInGameHints;
|
public static bool Enabled => !GameSettings.CurrentConfig.DisableInGameHints;
|
||||||
private static HashSet<string> HintIdentifiers { get; set; }
|
private static HashSet<Identifier> HintIdentifiers { get; set; }
|
||||||
private static Dictionary<string, HashSet<string>> HintTags { get; } = new Dictionary<string, HashSet<string>>();
|
private static Dictionary<Identifier, HashSet<Identifier>> HintTags { get; } = new Dictionary<Identifier, HashSet<Identifier>>();
|
||||||
private static Dictionary<string, (string identifier, string option)> HintOrders { get; } = new Dictionary<string, (string orderIdentifier, string orderOption)>();
|
private static Dictionary<Identifier, (Identifier identifier, Identifier option)> HintOrders { get; } = new Dictionary<Identifier, (Identifier orderIdentifier, Identifier orderOption)>();
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Hints that have already been shown this round and shouldn't be shown shown again until the next round
|
/// Hints that have already been shown this round and shouldn't be shown shown again until the next round
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static HashSet<string> HintsIgnoredThisRound { get; } = new HashSet<string>();
|
private static HashSet<Identifier> HintsIgnoredThisRound { get; } = new HashSet<Identifier>();
|
||||||
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; }
|
||||||
@@ -43,10 +43,10 @@ namespace Barotrauma
|
|||||||
var doc = XMLExtensions.TryLoadXml(HintManagerFile);
|
var doc = XMLExtensions.TryLoadXml(HintManagerFile);
|
||||||
if (doc?.Root != null)
|
if (doc?.Root != null)
|
||||||
{
|
{
|
||||||
HintIdentifiers = new HashSet<string>();
|
HintIdentifiers = new HashSet<Identifier>();
|
||||||
foreach (var element in doc.Root.Elements())
|
foreach (var element in doc.Root.Elements())
|
||||||
{
|
{
|
||||||
GetHintsRecursive(element, element.Name.ToString());
|
GetHintsRecursive(element, element.NameAsIdentifier());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -59,18 +59,18 @@ namespace Barotrauma
|
|||||||
DebugConsole.ThrowError($"File \"{HintManagerFile}\" is missing - cannot initialize the HintManager!");
|
DebugConsole.ThrowError($"File \"{HintManagerFile}\" is missing - cannot initialize the HintManager!");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GetHintsRecursive(XElement element, string identifier)
|
static void GetHintsRecursive(XElement element, Identifier identifier)
|
||||||
{
|
{
|
||||||
if (!element.HasElements)
|
if (!element.HasElements)
|
||||||
{
|
{
|
||||||
HintIdentifiers.Add(identifier);
|
HintIdentifiers.Add(identifier);
|
||||||
if (element.GetAttributeStringArray("tags", null, convertToLowerInvariant: true) is string[] tags)
|
if (element.GetAttributeIdentifierArray("tags", null) is Identifier[] tags)
|
||||||
{
|
{
|
||||||
HintTags.TryAdd(identifier, tags.ToHashSet());
|
HintTags.TryAdd(identifier, tags.ToHashSet());
|
||||||
}
|
}
|
||||||
if (element.GetAttributeString("order", null) is string orderIdentifier && !string.IsNullOrEmpty(orderIdentifier))
|
if (element.GetAttributeIdentifier("order", Identifier.Empty) is Identifier orderIdentifier && orderIdentifier != Identifier.Empty)
|
||||||
{
|
{
|
||||||
string orderOption = element.GetAttributeString("orderoption", "");
|
Identifier orderOption = element.GetAttributeIdentifier("orderoption", Identifier.Empty);
|
||||||
HintOrders.Add(identifier, (orderIdentifier, orderOption));
|
HintOrders.Add(identifier, (orderIdentifier, orderOption));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -82,14 +82,14 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
foreach (var childElement in element.Elements())
|
foreach (var childElement in element.Elements())
|
||||||
{
|
{
|
||||||
GetHintsRecursive(childElement, $"{identifier}.{childElement.Name}");
|
GetHintsRecursive(childElement, $"{identifier}.{childElement.Name}".ToIdentifier());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Update()
|
public static void Update()
|
||||||
{
|
{
|
||||||
if (HintIdentifiers == null || GameMain.Config.DisableInGameHints) { return; }
|
if (HintIdentifiers == null || GameSettings.CurrentConfig.DisableInGameHints) { return; }
|
||||||
if (GameMain.GameSession == null || !GameMain.GameSession.IsRunning) { return; }
|
if (GameMain.GameSession == null || !GameMain.GameSession.IsRunning) { return; }
|
||||||
|
|
||||||
if (ActiveHintMessageBox != null)
|
if (ActiveHintMessageBox != null)
|
||||||
@@ -137,7 +137,7 @@ namespace Barotrauma
|
|||||||
// onstartedinteracting.brokenitem
|
// onstartedinteracting.brokenitem
|
||||||
if (item.Repairables.Any(r => r.IsBelowRepairThreshold))
|
if (item.Repairables.Any(r => r.IsBelowRepairThreshold))
|
||||||
{
|
{
|
||||||
if (DisplayHint($"{hintIdentifierBase}.brokenitem")) { return; }
|
if (DisplayHint($"{hintIdentifierBase}.brokenitem".ToIdentifier())) { return; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't display other item-related hints if the repair interface is displayed
|
// Don't display other item-related hints if the repair interface is displayed
|
||||||
@@ -147,22 +147,25 @@ namespace Barotrauma
|
|||||||
if (item.Submarine?.Info?.Type == SubmarineType.Outpost &&
|
if (item.Submarine?.Info?.Type == SubmarineType.Outpost &&
|
||||||
item.ContainedItems.Any(i => !i.AllowStealing))
|
item.ContainedItems.Any(i => !i.AllowStealing))
|
||||||
{
|
{
|
||||||
if (DisplayHint($"{hintIdentifierBase}.lootingisstealing")) { return; }
|
if (DisplayHint($"{hintIdentifierBase}.lootingisstealing".ToIdentifier())) { 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 (DisplayHint($"{hintIdentifierBase}.turretperiscope",
|
if (DisplayHint($"{hintIdentifierBase}.turretperiscope".ToIdentifier(),
|
||||||
variableTags: new string[] { "[shootkey]", "[deselectkey]", },
|
variables: new[]
|
||||||
variableValues: new string[] { GameMain.Config.KeyBindText(InputType.Shoot), GameMain.Config.KeyBindText(InputType.Deselect) }))
|
{
|
||||||
|
("[shootkey]".ToIdentifier(), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Shoot)),
|
||||||
|
("[deselectkey]".ToIdentifier(), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Deselect))
|
||||||
|
}))
|
||||||
{ return; }
|
{ return; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// onstartedinteracting.item...
|
// onstartedinteracting.item...
|
||||||
hintIdentifierBase += ".item";
|
hintIdentifierBase += ".item";
|
||||||
foreach (string hintIdentifier in HintIdentifiers)
|
foreach (Identifier hintIdentifier in HintIdentifiers)
|
||||||
{
|
{
|
||||||
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; }
|
||||||
@@ -180,7 +183,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 (DisplayHint("onisinteracting.reactorwithextrarods")) { return; }
|
if (DisplayHint("onisinteracting.reactorwithextrarods".ToIdentifier())) { return; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,11 +236,11 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!GameMain.GameSession.GameMode.IsSinglePlayer &&
|
if (!GameMain.GameSession.GameMode.IsSinglePlayer &&
|
||||||
GameMain.Config.VoiceSetting == GameSettings.VoiceMode.Disabled)
|
GameSettings.CurrentConfig.Audio.VoiceSetting == VoiceMode.Disabled)
|
||||||
{
|
{
|
||||||
DisplayHint("onroundstarted.voipdisabled", onUpdate: () =>
|
DisplayHint("onroundstarted.voipdisabled".ToIdentifier(), onUpdate: () =>
|
||||||
{
|
{
|
||||||
if (GameMain.Config.VoiceSetting == GameSettings.VoiceMode.Disabled) { return; }
|
if (GameSettings.CurrentConfig.Audio.VoiceSetting == VoiceMode.Disabled) { return; }
|
||||||
ActiveHintMessageBox.Close();
|
ActiveHintMessageBox.Close();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -271,7 +274,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; }
|
||||||
DisplayHint("onsonarspottedenemy");
|
DisplayHint("onsonarspottedenemy".ToIdentifier());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void OnAfflictionDisplayed(Character character, List<Affliction> displayedAfflictions)
|
public static void OnAfflictionDisplayed(Character character, List<Affliction> displayedAfflictions)
|
||||||
@@ -285,9 +288,8 @@ namespace Barotrauma
|
|||||||
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; }
|
||||||
if (affliction.Strength < affliction.Prefab.ShowIconThreshold) { continue; }
|
if (affliction.Strength < affliction.Prefab.ShowIconThreshold) { continue; }
|
||||||
DisplayHint("onafflictiondisplayed",
|
DisplayHint("onafflictiondisplayed".ToIdentifier(),
|
||||||
variableTags: new string[1] { "[key]" },
|
variables: new[] { ("[key]".ToIdentifier(), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Health)) },
|
||||||
variableValues: new string[1] { GameMain.Config.KeyBindText(InputType.Health) },
|
|
||||||
icon: affliction.Prefab.Icon,
|
icon: affliction.Prefab.Icon,
|
||||||
iconColor: CharacterHealth.GetAfflictionIconColor(affliction),
|
iconColor: CharacterHealth.GetAfflictionIconColor(affliction),
|
||||||
onUpdate: () =>
|
onUpdate: () =>
|
||||||
@@ -308,12 +310,11 @@ namespace Barotrauma
|
|||||||
if (TimeStoppedInteracting + 1 > Timing.TotalTime) { return; }
|
if (TimeStoppedInteracting + 1 > Timing.TotalTime) { return; }
|
||||||
if (GUI.MouseOn != null) { return; }
|
if (GUI.MouseOn != null) { return; }
|
||||||
if (Character.Controlled.Inventory?.visualSlots != null && Character.Controlled.Inventory.visualSlots.Any(s => s.InteractRect.Contains(PlayerInput.MousePosition))) { return; }
|
if (Character.Controlled.Inventory?.visualSlots != null && Character.Controlled.Inventory.visualSlots.Any(s => s.InteractRect.Contains(PlayerInput.MousePosition))) { return; }
|
||||||
string hintIdentifier = "onshootwithoutaiming";
|
Identifier hintIdentifier = "onshootwithoutaiming".ToIdentifier();
|
||||||
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; }
|
||||||
DisplayHint(hintIdentifier,
|
DisplayHint(hintIdentifier,
|
||||||
variableTags: new string[1] { "[key]" },
|
variables: new[] { ("[key]".ToIdentifier(), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Aim)) },
|
||||||
variableValues: new string[1] { GameMain.Config.KeyBindText(InputType.Aim) },
|
|
||||||
onUpdate: () =>
|
onUpdate: () =>
|
||||||
{
|
{
|
||||||
if (character.SelectedConstruction == null && GUI.MouseOn == null && PlayerInput.KeyDown(InputType.Aim))
|
if (character.SelectedConstruction == null && GUI.MouseOn == null && PlayerInput.KeyDown(InputType.Aim))
|
||||||
@@ -328,21 +329,21 @@ 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; }
|
||||||
DisplayHint("onweldingdoor");
|
DisplayHint("onweldingdoor".ToIdentifier());
|
||||||
}
|
}
|
||||||
|
|
||||||
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; }
|
||||||
DisplayHint("ontryopenstuckdoor");
|
DisplayHint("ontryopenstuckdoor".ToIdentifier());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void OnShowCampaignInterface(CampaignMode.InteractionType interactionType)
|
public static void OnShowCampaignInterface(CampaignMode.InteractionType interactionType)
|
||||||
{
|
{
|
||||||
if (!CanDisplayHints()) { return; }
|
if (!CanDisplayHints()) { return; }
|
||||||
if (interactionType == CampaignMode.InteractionType.None) { return; }
|
if (interactionType == CampaignMode.InteractionType.None) { return; }
|
||||||
string hintIdentifier = $"onshowcampaigninterface.{interactionType.ToString().ToLowerInvariant()}";
|
Identifier hintIdentifier = $"onshowcampaigninterface.{interactionType}".ToIdentifier();
|
||||||
DisplayHint(hintIdentifier, onUpdate: () =>
|
DisplayHint(hintIdentifier, onUpdate: () =>
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -359,7 +360,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
IgnoreReminder("commandinterface");
|
IgnoreReminder("commandinterface");
|
||||||
if (!CanDisplayHints()) { return; }
|
if (!CanDisplayHints()) { return; }
|
||||||
DisplayHint("onshowcommandinterface", onUpdate: () =>
|
DisplayHint("onshowcommandinterface".ToIdentifier(), onUpdate: () =>
|
||||||
{
|
{
|
||||||
if (CrewManager.IsCommandInterfaceOpen) { return; }
|
if (CrewManager.IsCommandInterfaceOpen) { return; }
|
||||||
ActiveHintMessageBox.Close();
|
ActiveHintMessageBox.Close();
|
||||||
@@ -370,7 +371,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (!CanDisplayHints()) { return; }
|
if (!CanDisplayHints()) { return; }
|
||||||
if (CharacterHealth.OpenHealthWindow == null) { return; }
|
if (CharacterHealth.OpenHealthWindow == null) { return; }
|
||||||
DisplayHint("onshowhealthinterface", onUpdate: () =>
|
DisplayHint("onshowhealthinterface".ToIdentifier(), onUpdate: () =>
|
||||||
{
|
{
|
||||||
if (CharacterHealth.OpenHealthWindow != null) { return; }
|
if (CharacterHealth.OpenHealthWindow != null) { return; }
|
||||||
ActiveHintMessageBox.Close();
|
ActiveHintMessageBox.Close();
|
||||||
@@ -387,7 +388,7 @@ namespace Barotrauma
|
|||||||
if (!CanDisplayHints()) { return; }
|
if (!CanDisplayHints()) { return; }
|
||||||
if (character != Character.Controlled) { return; }
|
if (character != Character.Controlled) { return; }
|
||||||
if (item == null || item.AllowStealing || !item.StolenDuringRound) { return; }
|
if (item == null || item.AllowStealing || !item.StolenDuringRound) { return; }
|
||||||
DisplayHint("onstoleitem", onUpdate: () =>
|
DisplayHint("onstoleitem".ToIdentifier(), onUpdate: () =>
|
||||||
{
|
{
|
||||||
if (item == null || item.Removed || item.GetRootInventoryOwner() != character)
|
if (item == null || item.Removed || item.GetRootInventoryOwner() != character)
|
||||||
{
|
{
|
||||||
@@ -400,7 +401,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (!CanDisplayHints()) { return; }
|
if (!CanDisplayHints()) { return; }
|
||||||
if (character != Character.Controlled || !character.LockHands) { return; }
|
if (character != Character.Controlled || !character.LockHands) { return; }
|
||||||
DisplayHint("onhandcuffed", onUpdate: () =>
|
DisplayHint("onhandcuffed".ToIdentifier(), onUpdate: () =>
|
||||||
{
|
{
|
||||||
if (character != null && !character.Removed && character.LockHands) { return; }
|
if (character != null && !character.Removed && character.LockHands) { return; }
|
||||||
ActiveHintMessageBox.Close();
|
ActiveHintMessageBox.Close();
|
||||||
@@ -413,7 +414,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; }
|
||||||
DisplayHint("onreactoroutoffuel", onUpdate: () =>
|
DisplayHint("onreactoroutoffuel".ToIdentifier(), 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();
|
||||||
@@ -424,13 +425,13 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (!CanDisplayHints()) { return; }
|
if (!CanDisplayHints()) { return; }
|
||||||
if (transitionType == CampaignMode.TransitionType.None) { return; }
|
if (transitionType == CampaignMode.TransitionType.None) { return; }
|
||||||
DisplayHint($"onavailabletransition.{transitionType.ToString().ToLowerInvariant()}");
|
DisplayHint($"onavailabletransition.{transitionType}".ToIdentifier());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void OnShowSubInventory(Item item)
|
public static void OnShowSubInventory(Item item)
|
||||||
{
|
{
|
||||||
if (item?.Prefab == null) { return; }
|
if (item?.Prefab == null) { return; }
|
||||||
if (item.Prefab.Identifier.Equals("toolbelt", StringComparison.OrdinalIgnoreCase))
|
if (item.Prefab.Identifier == "toolbelt")
|
||||||
{
|
{
|
||||||
IgnoreReminder("toolbelt");
|
IgnoreReminder("toolbelt");
|
||||||
}
|
}
|
||||||
@@ -447,7 +448,7 @@ namespace Barotrauma
|
|||||||
if (character != Character.Controlled) { return; }
|
if (character != Character.Controlled) { return; }
|
||||||
if (character.IsDead) { return; }
|
if (character.IsDead) { return; }
|
||||||
if (character.CharacterHealth != null && character.Vitality < character.CharacterHealth.MinVitality) { return; }
|
if (character.CharacterHealth != null && character.Vitality < character.CharacterHealth.MinVitality) { return; }
|
||||||
DisplayHint("oncharacterunconscious");
|
DisplayHint("oncharacterunconscious".ToIdentifier());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void OnCharacterKilled(Character character)
|
public static void OnCharacterKilled(Character character)
|
||||||
@@ -457,21 +458,21 @@ namespace Barotrauma
|
|||||||
if (GameMain.IsMultiplayer) { return; }
|
if (GameMain.IsMultiplayer) { return; }
|
||||||
if (GameMain.GameSession?.CrewManager == null) { return; }
|
if (GameMain.GameSession?.CrewManager == null) { return; }
|
||||||
if (GameMain.GameSession.CrewManager.GetCharacters().None(c => !c.IsDead)) { return; }
|
if (GameMain.GameSession.CrewManager.GetCharacters().None(c => !c.IsDead)) { return; }
|
||||||
DisplayHint("oncharacterkilled");
|
DisplayHint("oncharacterkilled".ToIdentifier());
|
||||||
}
|
}
|
||||||
|
|
||||||
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}";
|
Identifier hintIdentifier = $"onstartedcontrolling.job.{Character.Controlled.Info.Job.Prefab.Identifier}".ToIdentifier();
|
||||||
DisplayHint(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: () =>
|
||||||
{
|
{
|
||||||
if (!HintOrders.TryGetValue(hintIdentifier, out var orderInfo)) { return; }
|
if (!HintOrders.TryGetValue(hintIdentifier, out var orderInfo)) { return; }
|
||||||
var orderPrefab = Order.GetPrefab(orderInfo.identifier);
|
var orderPrefab = OrderPrefab.Prefabs[orderInfo.identifier];
|
||||||
if (orderPrefab == null) { return; }
|
if (orderPrefab == null) { return; }
|
||||||
Item targetEntity = null;
|
Item targetEntity = null;
|
||||||
ItemComponent targetItem = null;
|
ItemComponent targetItem = null;
|
||||||
@@ -481,8 +482,8 @@ namespace Barotrauma
|
|||||||
if (targetEntity == null) { return; }
|
if (targetEntity == null) { return; }
|
||||||
targetItem = orderPrefab.GetTargetItemComponent(targetEntity);
|
targetItem = orderPrefab.GetTargetItemComponent(targetEntity);
|
||||||
}
|
}
|
||||||
var order = new Order(orderPrefab, targetEntity as Entity, targetItem, orderGiver: Character.Controlled);
|
var order = new Order(orderPrefab, orderInfo.option, targetEntity, targetItem, orderGiver: Character.Controlled).WithManualPriority(CharacterInfo.HighestManualOrderPriority);
|
||||||
GameMain.GameSession?.CrewManager?.SetCharacterOrder(Character.Controlled, order, orderInfo.option, CharacterInfo.HighestManualOrderPriority, Character.Controlled);
|
GameMain.GameSession.CrewManager.SetCharacterOrder(Character.Controlled, order);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -498,7 +499,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; }
|
||||||
DisplayHint("onautopilotreachedoutpost");
|
DisplayHint("onautopilotreachedoutpost".ToIdentifier());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void OnStatusEffectApplied(ItemComponent component, ActionType actionType, Character character)
|
public static void OnStatusEffectApplied(ItemComponent component, ActionType actionType, Character character)
|
||||||
@@ -507,7 +508,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; }
|
||||||
DisplayHint("onrepairfailed");
|
DisplayHint("onrepairfailed".ToIdentifier());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void OnActiveOrderAdded(Order order)
|
public static void OnActiveOrderAdded(Order order)
|
||||||
@@ -519,7 +520,7 @@ namespace Barotrauma
|
|||||||
order.TargetEntity is Hull h &&
|
order.TargetEntity is Hull h &&
|
||||||
h.Submarine?.TeamID == Character.Controlled.TeamID)
|
h.Submarine?.TeamID == Character.Controlled.TeamID)
|
||||||
{
|
{
|
||||||
DisplayHint("onballastflorainfected");
|
DisplayHint("onballastflorainfected".ToIdentifier());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -529,7 +530,7 @@ namespace Barotrauma
|
|||||||
var divingGear = Character.Controlled.GetEquippedItem("diving", InvSlotType.OuterClothes);
|
var divingGear = Character.Controlled.GetEquippedItem("diving", InvSlotType.OuterClothes);
|
||||||
if (divingGear?.OwnInventory == null) { return; }
|
if (divingGear?.OwnInventory == null) { return; }
|
||||||
if (divingGear.GetContainedItemConditionPercentage() > 0.0f) { return; }
|
if (divingGear.GetContainedItemConditionPercentage() > 0.0f) { return; }
|
||||||
DisplayHint("ondivinggearoutofoxygen", onUpdate: () =>
|
DisplayHint("ondivinggearoutofoxygen".ToIdentifier(), 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) ||
|
||||||
@@ -546,7 +547,7 @@ namespace Barotrauma
|
|||||||
if (Character.Controlled.CurrentHull == null) { return; }
|
if (Character.Controlled.CurrentHull == null) { return; }
|
||||||
if (HumanAIController.IsBallastFloraNoticeable(Character.Controlled, Character.Controlled.CurrentHull))
|
if (HumanAIController.IsBallastFloraNoticeable(Character.Controlled, Character.Controlled.CurrentHull))
|
||||||
{
|
{
|
||||||
if (IsOnFriendlySub() && DisplayHint("onballastflorainfected")) { return; }
|
if (IsOnFriendlySub() && DisplayHint("onballastflorainfected".ToIdentifier())) { return; }
|
||||||
}
|
}
|
||||||
foreach (var gap in Character.Controlled.CurrentHull.ConnectedGaps)
|
foreach (var gap in Character.Controlled.CurrentHull.ConnectedGaps)
|
||||||
{
|
{
|
||||||
@@ -556,7 +557,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (!IsWearingDivingSuit()) { continue; }
|
if (!IsWearingDivingSuit()) { continue; }
|
||||||
if (Character.Controlled.IsProtectedFromPressure()) { continue; }
|
if (Character.Controlled.IsProtectedFromPressure()) { continue; }
|
||||||
if (DisplayHint("divingsuitwarning", extendTextTag: false)) { return; }
|
if (DisplayHint("divingsuitwarning".ToIdentifier(), extendTextTag: false)) { return; }
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
foreach (var me in gap.linkedTo)
|
foreach (var me in gap.linkedTo)
|
||||||
@@ -565,8 +566,8 @@ namespace Barotrauma
|
|||||||
if (!(me is Hull adjacentHull)) { continue; }
|
if (!(me is Hull adjacentHull)) { continue; }
|
||||||
if (!IsOnFriendlySub()) { continue; }
|
if (!IsOnFriendlySub()) { continue; }
|
||||||
if (IsWearingDivingSuit()) { continue; }
|
if (IsWearingDivingSuit()) { continue; }
|
||||||
if (adjacentHull.LethalPressure > 5.0f && DisplayHint("onadjacenthull.highpressure")) { return; }
|
if (adjacentHull.LethalPressure > 5.0f && DisplayHint("onadjacenthull.highpressure".ToIdentifier())) { return; }
|
||||||
if (adjacentHull.WaterPercentage > 75 && !BallastHulls.Contains(adjacentHull) && DisplayHint("onadjacenthull.highwaterpercentage")) { return; }
|
if (adjacentHull.WaterPercentage > 75 && !BallastHulls.Contains(adjacentHull) && DisplayHint("onadjacenthull.highwaterpercentage".ToIdentifier())) { return; }
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsWearingDivingSuit() => Character.Controlled.GetEquippedItem("deepdiving", InvSlotType.OuterClothes) is Item;
|
static bool IsWearingDivingSuit() => Character.Controlled.GetEquippedItem("deepdiving", InvSlotType.OuterClothes) is Item;
|
||||||
@@ -586,7 +587,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (GameMain.GameSession.GameMode.IsSinglePlayer)
|
if (GameMain.GameSession.GameMode.IsSinglePlayer)
|
||||||
{
|
{
|
||||||
if (DisplayHint($"{hintIdentifierBase}.characterchange"))
|
if (DisplayHint($"{hintIdentifierBase}.characterchange".ToIdentifier()))
|
||||||
{
|
{
|
||||||
TimeReminderLastDisplayed = GameMain.GameScreen.GameTime;
|
TimeReminderLastDisplayed = GameMain.GameScreen.GameTime;
|
||||||
return;
|
return;
|
||||||
@@ -595,9 +596,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (Level.Loaded.Type != LevelData.LevelType.Outpost)
|
if (Level.Loaded.Type != LevelData.LevelType.Outpost)
|
||||||
{
|
{
|
||||||
if (DisplayHint($"{hintIdentifierBase}.commandinterface",
|
if (DisplayHint($"{hintIdentifierBase}.commandinterface".ToIdentifier(),
|
||||||
variableTags: new string[] { "[commandkey]" },
|
variables: new[] { ("[commandkey]".ToIdentifier(), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Command)) },
|
||||||
variableValues: new string[] { GameMain.Config.KeyBindText(InputType.Command) },
|
|
||||||
onUpdate: () =>
|
onUpdate: () =>
|
||||||
{
|
{
|
||||||
if (!CrewManager.IsCommandInterfaceOpen) { return; }
|
if (!CrewManager.IsCommandInterfaceOpen) { return; }
|
||||||
@@ -609,9 +609,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DisplayHint($"{hintIdentifierBase}.tabmenu",
|
if (DisplayHint($"{hintIdentifierBase}.tabmenu".ToIdentifier(),
|
||||||
variableTags: new string[] { "[infotabkey]" },
|
variables: new[] { ("[infotabkey]".ToIdentifier(), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.InfoTab)) },
|
||||||
variableValues: new string[] { GameMain.Config.KeyBindText(InputType.InfoTab) },
|
|
||||||
onUpdate: () =>
|
onUpdate: () =>
|
||||||
{
|
{
|
||||||
if (!GameSession.IsTabMenuOpen) { return; }
|
if (!GameSession.IsTabMenuOpen) { return; }
|
||||||
@@ -624,7 +623,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (Character.Controlled.Inventory?.GetItemInLimbSlot(InvSlotType.Bag)?.Prefab?.Identifier == "toolbelt")
|
if (Character.Controlled.Inventory?.GetItemInLimbSlot(InvSlotType.Bag)?.Prefab?.Identifier == "toolbelt")
|
||||||
{
|
{
|
||||||
if (DisplayHint($"{hintIdentifierBase}.toolbelt"))
|
if (DisplayHint($"{hintIdentifierBase}.toolbelt".ToIdentifier()))
|
||||||
{
|
{
|
||||||
TimeReminderLastDisplayed = GameMain.GameScreen.GameTime;
|
TimeReminderLastDisplayed = GameMain.GameScreen.GameTime;
|
||||||
return;
|
return;
|
||||||
@@ -632,25 +631,25 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
private static bool DisplayHint(Identifier hintIdentifier, bool extendTextTag = true, (Identifier Tag, LocalizedString Value)[] variables = null, Sprite icon = null, Color? iconColor = null, Action onDisplay = null, Action onUpdate = null)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(hintIdentifier)) { return false; }
|
if (hintIdentifier == Identifier.Empty) { return false; }
|
||||||
if (!HintIdentifiers.Contains(hintIdentifier)) { return false; }
|
if (!HintIdentifiers.Contains(hintIdentifier)) { return false; }
|
||||||
if (GameMain.Config.IgnoredHints.Contains(hintIdentifier)) { return false; }
|
if (IgnoredHints.Instance.Contains(hintIdentifier)) { return false; }
|
||||||
if (HintsIgnoredThisRound.Contains(hintIdentifier)) { return false; }
|
if (HintsIgnoredThisRound.Contains(hintIdentifier)) { return false; }
|
||||||
|
|
||||||
string text;
|
LocalizedString text;
|
||||||
string textTag = extendTextTag ? $"hint.{hintIdentifier}" : hintIdentifier;
|
Identifier textTag = extendTextTag ? $"hint.{hintIdentifier}".ToIdentifier() : hintIdentifier;
|
||||||
if (variableTags != null && variableTags != null && variableTags.Length > 0 && variableTags.Length == variableValues.Length)
|
if (variables != null && variables.Length > 0)
|
||||||
{
|
{
|
||||||
text = TextManager.GetWithVariables(textTag, variableTags, variableValues, returnNull: true);
|
text = TextManager.GetWithVariables(textTag, variables);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
text = TextManager.Get(textTag, returnNull: true);
|
text = TextManager.Get(textTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(text))
|
if (text.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
DebugConsole.ThrowError($"No hint text found for text tag \"{textTag}\"");
|
DebugConsole.ThrowError($"No hint text found for text tag \"{textTag}\"");
|
||||||
@@ -668,20 +667,20 @@ namespace Barotrauma
|
|||||||
ActiveHintMessageBox.InnerFrame.Flash(color: iconColor ?? Color.Orange, flashDuration: 0.75f);
|
ActiveHintMessageBox.InnerFrame.Flash(color: iconColor ?? Color.Orange, flashDuration: 0.75f);
|
||||||
onDisplay?.Invoke();
|
onDisplay?.Invoke();
|
||||||
|
|
||||||
GameAnalyticsManager.AddDesignEvent($"HintManager:{GameMain.GameSession?.GameMode?.Preset?.Identifier ?? "none"}:HintDisplayed:{hintIdentifier}");
|
GameAnalyticsManager.AddDesignEvent($"HintManager:{GameMain.GameSession?.GameMode?.Preset?.Identifier ?? "none".ToIdentifier()}:HintDisplayed:{hintIdentifier}");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool OnDontShowAgain(GUITickBox tickBox)
|
public static bool OnDontShowAgain(GUITickBox tickBox)
|
||||||
{
|
{
|
||||||
IgnoreHint((string)tickBox.UserData, ignore: tickBox.Selected);
|
IgnoreHint((Identifier)tickBox.UserData, ignore: tickBox.Selected);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void IgnoreHint(string hintIdentifier, bool ignore = true)
|
private static void IgnoreHint(Identifier hintIdentifier, bool ignore = true)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(hintIdentifier)) { return; }
|
if (hintIdentifier.IsEmpty) { return; }
|
||||||
if (!HintIdentifiers.Contains(hintIdentifier))
|
if (!HintIdentifiers.Contains(hintIdentifier))
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
@@ -691,29 +690,32 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
if (ignore)
|
if (ignore)
|
||||||
{
|
{
|
||||||
GameMain.Config.IgnoredHints.Add(hintIdentifier);
|
IgnoredHints.Instance.Add(hintIdentifier);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GameMain.Config.IgnoredHints.Remove(hintIdentifier);
|
IgnoredHints.Instance.Remove(hintIdentifier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void IgnoreReminder(string reminderIdentifier)
|
private static void IgnoreReminder(string reminderIdentifier)
|
||||||
{
|
{
|
||||||
HintsIgnoredThisRound.Add($"reminder.{reminderIdentifier}");
|
HintsIgnoredThisRound.Add($"reminder.{reminderIdentifier}".ToIdentifier());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool OnDisableHints(GUITickBox tickBox)
|
public static bool OnDisableHints(GUITickBox tickBox)
|
||||||
{
|
{
|
||||||
GameMain.Config.DisableInGameHints = tickBox.Selected;
|
var config = GameSettings.CurrentConfig;
|
||||||
return GameMain.Config.SaveNewPlayerConfig();
|
config.DisableInGameHints = tickBox.Selected;
|
||||||
|
GameSettings.SetCurrentConfig(config);
|
||||||
|
GameSettings.SaveCurrentConfig();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool CanDisplayHints(bool requireGameScreen = true, bool requireControllingCharacter = true)
|
private static bool CanDisplayHints(bool requireGameScreen = true, bool requireControllingCharacter = true)
|
||||||
{
|
{
|
||||||
if (HintIdentifiers == null) { return false; }
|
if (HintIdentifiers == null) { return false; }
|
||||||
if (GameMain.Config.DisableInGameHints) { return false; }
|
if (GameSettings.CurrentConfig.DisableInGameHints) { return false; }
|
||||||
if (ActiveHintMessageBox != null) { 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;
|
||||||
|
|||||||
@@ -181,6 +181,11 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnMoneyChanged(WalletChangedEvent e)
|
||||||
|
{
|
||||||
|
if (e.Wallet.IsOwnWallet) { OnUpdate?.Invoke(); }
|
||||||
|
}
|
||||||
|
|
||||||
// if you have more than 5000 ping there are probably more important things to worry about but hey just in case
|
// if you have more than 5000 ping there are probably more important things to worry about but hey just in case
|
||||||
private static DateTimeOffset GetTimeout() => DateTimeOffset.Now.AddSeconds(5).AddMilliseconds(GetPing());
|
private static DateTimeOffset GetTimeout() => DateTimeOffset.Now.AddSeconds(5).AddMilliseconds(GetPing());
|
||||||
|
|
||||||
@@ -241,6 +246,7 @@ namespace Barotrauma
|
|||||||
private void HealRequestReceived(IReadMessage inc)
|
private void HealRequestReceived(IReadMessage inc)
|
||||||
{
|
{
|
||||||
NetHealRequest request = INetSerializableStruct.Read<NetHealRequest>(inc);
|
NetHealRequest request = INetSerializableStruct.Read<NetHealRequest>(inc);
|
||||||
|
|
||||||
if (request.Result == HealRequestResult.Success)
|
if (request.Result == HealRequestResult.Success)
|
||||||
{
|
{
|
||||||
HealAllPending(force: true);
|
HealAllPending(force: true);
|
||||||
|
|||||||
@@ -9,16 +9,18 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
internal partial class ReadyCheck
|
internal partial class ReadyCheck
|
||||||
{
|
{
|
||||||
private static string readyCheckBody(string name) => string.IsNullOrWhiteSpace(name) ? TextManager.Get("readycheck.serverbody") : TextManager.GetWithVariable("readycheck.body", "[player]", name);
|
private static LocalizedString readyCheckBody(string name) => string.IsNullOrWhiteSpace(name) ? TextManager.Get("readycheck.serverbody") : TextManager.GetWithVariable("readycheck.body", "[player]", name);
|
||||||
|
|
||||||
private static string readyCheckStatus(int ready, int total) => TextManager.GetWithVariables("readycheck.readycount", new[] { "[ready]", "[total]" }, new[] { ready.ToString(), total.ToString() });
|
private static LocalizedString readyCheckStatus(int ready, int total) => TextManager.GetWithVariables("readycheck.readycount",
|
||||||
private static string readyCheckPleaseWait(int seconds) => TextManager.GetWithVariable("readycheck.pleasewait", "[seconds]", seconds.ToString());
|
("[ready]", ready.ToString()),
|
||||||
|
("[total]", total.ToString()));
|
||||||
|
private static LocalizedString readyCheckPleaseWait(int seconds) => TextManager.GetWithVariable("readycheck.pleasewait", "[seconds]", seconds.ToString());
|
||||||
|
|
||||||
private static readonly string readyCheckHeader = TextManager.Get("ReadyCheck.Title");
|
private static readonly LocalizedString readyCheckHeader = TextManager.Get("ReadyCheck.Title");
|
||||||
|
|
||||||
private static readonly string noButton = TextManager.Get("No"),
|
private static readonly LocalizedString noButton = TextManager.Get("No"),
|
||||||
yesButton = TextManager.Get("Yes"),
|
yesButton = TextManager.Get("Yes"),
|
||||||
closeButton = TextManager.Get("Close");
|
closeButton = TextManager.Get("Close");
|
||||||
|
|
||||||
private const string TimerData = "Timer",
|
private const string TimerData = "Timer",
|
||||||
PromptData = "ReadyCheck",
|
PromptData = "ReadyCheck",
|
||||||
@@ -42,7 +44,7 @@ namespace Barotrauma
|
|||||||
msgBox = new GUIMessageBox(readyCheckHeader, readyCheckBody(author), new[] { yesButton, noButton }, relativeSize, minSize, type: GUIMessageBox.Type.Vote) { UserData = PromptData, Draggable = true };
|
msgBox = new GUIMessageBox(readyCheckHeader, readyCheckBody(author), new[] { yesButton, noButton }, relativeSize, minSize, type: GUIMessageBox.Type.Vote) { UserData = PromptData, Draggable = true };
|
||||||
|
|
||||||
GUILayoutGroup contentLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.125f), msgBox.Content.RectTransform), childAnchor: Anchor.Center);
|
GUILayoutGroup contentLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.125f), msgBox.Content.RectTransform), childAnchor: Anchor.Center);
|
||||||
new GUIProgressBar(new RectTransform(new Vector2(0.8f, 1f), contentLayout.RectTransform), time / endTime, GUI.Style.Orange) { UserData = TimerData };
|
new GUIProgressBar(new RectTransform(new Vector2(0.8f, 1f), contentLayout.RectTransform), time / endTime, GUIStyle.Orange) { UserData = TimerData };
|
||||||
|
|
||||||
// Yes
|
// Yes
|
||||||
msgBox.Buttons[0].OnClicked = delegate
|
msgBox.Buttons[0].OnClicked = delegate
|
||||||
@@ -222,7 +224,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
int readyCount = Clients.Count(pair => pair.Value == ReadyStatus.Yes);
|
int readyCount = Clients.Count(pair => pair.Value == ReadyStatus.Yes);
|
||||||
int totalCount = Clients.Count;
|
int totalCount = Clients.Count;
|
||||||
GameMain.Client.AddChatMessage(ChatMessage.Create(string.Empty, readyCheckStatus(readyCount, totalCount), ChatMessageType.Server, null));
|
GameMain.Client.AddChatMessage(ChatMessage.Create(string.Empty, readyCheckStatus(readyCount, totalCount).Value, ChatMessageType.Server, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateState(byte id, ReadyStatus status)
|
private void UpdateState(byte id, ReadyStatus status)
|
||||||
@@ -256,7 +258,7 @@ namespace Barotrauma
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
image.ApplyStyle(GUI.Style.GetComponentStyle(style));
|
image.ApplyStyle(GUIStyle.GetComponentStyle(style));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Immutable;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
@@ -15,7 +16,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private int jobColumnWidth, characterColumnWidth, statusColumnWidth;
|
private int jobColumnWidth, characterColumnWidth, statusColumnWidth;
|
||||||
|
|
||||||
private readonly SubmarineInfo sub;
|
|
||||||
private readonly List<Mission> selectedMissions;
|
private readonly List<Mission> selectedMissions;
|
||||||
private readonly Location startLocation, endLocation;
|
private readonly Location startLocation, endLocation;
|
||||||
|
|
||||||
@@ -30,11 +30,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public GUIComponent Frame { get; private set; }
|
public GUIComponent Frame { get; private set; }
|
||||||
|
|
||||||
|
public RoundSummary(GameMode gameMode, IEnumerable<Mission> selectedMissions, Location startLocation, Location endLocation)
|
||||||
|
|
||||||
public RoundSummary(SubmarineInfo sub, GameMode gameMode, IEnumerable<Mission> selectedMissions, Location startLocation, Location endLocation)
|
|
||||||
{
|
{
|
||||||
this.sub = sub;
|
|
||||||
this.gameMode = gameMode;
|
this.gameMode = gameMode;
|
||||||
this.selectedMissions = selectedMissions.ToList();
|
this.selectedMissions = selectedMissions.ToList();
|
||||||
this.startLocation = startLocation;
|
this.startLocation = startLocation;
|
||||||
@@ -59,7 +56,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (!singleplayer)
|
if (!singleplayer)
|
||||||
{
|
{
|
||||||
SoundPlayer.OverrideMusicType = gameOver ? "crewdead" : "endround";
|
SoundPlayer.OverrideMusicType = (gameOver ? "crewdead" : "endround").ToIdentifier();
|
||||||
SoundPlayer.OverrideMusicDuration = 18.0f;
|
SoundPlayer.OverrideMusicDuration = 18.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +81,7 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
|
|
||||||
var crewHeader = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), crewContent.RectTransform),
|
var crewHeader = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), crewContent.RectTransform),
|
||||||
TextManager.Get("crew"), textAlignment: Alignment.TopLeft, font: GUI.SubHeadingFont);
|
TextManager.Get("crew"), textAlignment: Alignment.TopLeft, font: GUIStyle.SubHeadingFont);
|
||||||
crewHeader.RectTransform.MinSize = new Point(0, GUI.IntScale(crewHeader.Rect.Height * 2.0f));
|
crewHeader.RectTransform.MinSize = new Point(0, GUI.IntScale(crewHeader.Rect.Height * 2.0f));
|
||||||
|
|
||||||
CreateCrewList(crewContent, gameSession.CrewManager.GetCharacterInfos().Where(c => c.TeamID != CharacterTeamType.Team2));
|
CreateCrewList(crewContent, gameSession.CrewManager.GetCharacterInfos().Where(c => c.TeamID != CharacterTeamType.Team2));
|
||||||
@@ -101,19 +98,19 @@ namespace Barotrauma
|
|||||||
Stretch = true
|
Stretch = true
|
||||||
};
|
};
|
||||||
var crewHeader2 = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), crewContent2.RectTransform),
|
var crewHeader2 = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), crewContent2.RectTransform),
|
||||||
CombatMission.GetTeamName(CharacterTeamType.Team2), textAlignment: Alignment.TopLeft, font: GUI.SubHeadingFont);
|
CombatMission.GetTeamName(CharacterTeamType.Team2), textAlignment: Alignment.TopLeft, font: GUIStyle.SubHeadingFont);
|
||||||
crewHeader2.RectTransform.MinSize = new Point(0, GUI.IntScale(crewHeader2.Rect.Height * 2.0f));
|
crewHeader2.RectTransform.MinSize = new Point(0, GUI.IntScale(crewHeader2.Rect.Height * 2.0f));
|
||||||
CreateCrewList(crewContent2, gameSession.CrewManager.GetCharacterInfos().Where(c => c.TeamID == CharacterTeamType.Team2));
|
CreateCrewList(crewContent2, gameSession.CrewManager.GetCharacterInfos().Where(c => c.TeamID == CharacterTeamType.Team2));
|
||||||
}
|
}
|
||||||
|
|
||||||
//header -------------------------------------------------------------------------------
|
//header -------------------------------------------------------------------------------
|
||||||
|
|
||||||
string headerText = GetHeaderText(gameOver, transitionType);
|
LocalizedString headerText = GetHeaderText(gameOver, transitionType);
|
||||||
GUITextBlock headerTextBlock = null;
|
GUITextBlock headerTextBlock = null;
|
||||||
if (!string.IsNullOrEmpty(headerText))
|
if (!headerText.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
headerTextBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), crewFrame.RectTransform, Anchor.TopLeft, Pivot.BottomLeft),
|
headerTextBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), crewFrame.RectTransform, Anchor.TopLeft, Pivot.BottomLeft),
|
||||||
headerText, textAlignment: Alignment.BottomLeft, font: GUI.LargeFont, wrap: true);
|
headerText, textAlignment: Alignment.BottomLeft, font: GUIStyle.LargeFont, wrap: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//traitor panel -------------------------------------------------------------------------------
|
//traitor panel -------------------------------------------------------------------------------
|
||||||
@@ -130,14 +127,14 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
|
|
||||||
var traitorHeader = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), traitorContent.RectTransform),
|
var traitorHeader = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), traitorContent.RectTransform),
|
||||||
TextManager.Get("traitors"), font: GUI.SubHeadingFont);
|
TextManager.Get("traitors"), font: GUIStyle.SubHeadingFont);
|
||||||
traitorHeader.RectTransform.MinSize = new Point(0, GUI.IntScale(traitorHeader.Rect.Height * 2.0f));
|
traitorHeader.RectTransform.MinSize = new Point(0, GUI.IntScale(traitorHeader.Rect.Height * 2.0f));
|
||||||
|
|
||||||
GUIListBox listBox = CreateCrewList(traitorContent, traitorResults.SelectMany(tr => tr.Characters.Select(c => c.Info)));
|
GUIListBox listBox = CreateCrewList(traitorContent, traitorResults.SelectMany(tr => tr.Characters.Select(c => c.Info)));
|
||||||
|
|
||||||
foreach (var traitorResult in traitorResults)
|
foreach (var traitorResult in traitorResults)
|
||||||
{
|
{
|
||||||
var traitorMission = TraitorMissionPrefab.List.Find(t => t.Identifier == traitorResult.MissionIdentifier);
|
var traitorMission = TraitorMissionPrefab.Prefabs.Find(t => t.Identifier == traitorResult.MissionIdentifier);
|
||||||
if (traitorMission == null) { continue; }
|
if (traitorMission == null) { continue; }
|
||||||
|
|
||||||
//spacing
|
//spacing
|
||||||
@@ -154,8 +151,8 @@ namespace Barotrauma
|
|||||||
Color = traitorMission.IconColor
|
Color = traitorMission.IconColor
|
||||||
};
|
};
|
||||||
|
|
||||||
string traitorMessage = TextManager.GetServerMessage(traitorResult.EndMessage);
|
LocalizedString traitorMessage = TextManager.GetServerMessage(traitorResult.EndMessage);
|
||||||
if (!string.IsNullOrEmpty(traitorMessage))
|
if (!traitorMessage.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
var textContent = new GUILayoutGroup(new RectTransform(Vector2.One, traitorResultHorizontal.RectTransform))
|
var textContent = new GUILayoutGroup(new RectTransform(Vector2.One, traitorResultHorizontal.RectTransform))
|
||||||
{
|
{
|
||||||
@@ -164,10 +161,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
var traitorStatusText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), textContent.RectTransform),
|
var traitorStatusText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), textContent.RectTransform),
|
||||||
TextManager.Get(traitorResult.Success ? "missioncompleted" : "missionfailed"),
|
TextManager.Get(traitorResult.Success ? "missioncompleted" : "missionfailed"),
|
||||||
textColor: traitorResult.Success ? GUI.Style.Green : GUI.Style.Red, font: GUI.SubHeadingFont);
|
textColor: traitorResult.Success ? GUIStyle.Green : GUIStyle.Red, font: GUIStyle.SubHeadingFont);
|
||||||
|
|
||||||
var traitorMissionInfo = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), textContent.RectTransform),
|
var traitorMissionInfo = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), textContent.RectTransform),
|
||||||
traitorMessage, font: GUI.SmallFont, wrap: true);
|
traitorMessage, font: GUIStyle.SmallFont, wrap: true);
|
||||||
|
|
||||||
traitorResultHorizontal.Recalculate();
|
traitorResultHorizontal.Recalculate();
|
||||||
|
|
||||||
@@ -196,7 +193,7 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
|
|
||||||
var reputationHeader = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), reputationContent.RectTransform),
|
var reputationHeader = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), reputationContent.RectTransform),
|
||||||
TextManager.Get("reputation"), textAlignment: Alignment.TopLeft, font: GUI.SubHeadingFont);
|
TextManager.Get("reputation"), textAlignment: Alignment.TopLeft, font: GUIStyle.SubHeadingFont);
|
||||||
reputationHeader.RectTransform.MinSize = new Point(0, GUI.IntScale(reputationHeader.Rect.Height * 2.0f));
|
reputationHeader.RectTransform.MinSize = new Point(0, GUI.IntScale(reputationHeader.Rect.Height * 2.0f));
|
||||||
|
|
||||||
CreateReputationInfoPanel(reputationContent, campaignMode);
|
CreateReputationInfoPanel(reputationContent, campaignMode);
|
||||||
@@ -233,7 +230,7 @@ namespace Barotrauma
|
|||||||
if (missionsToDisplay.Any())
|
if (missionsToDisplay.Any())
|
||||||
{
|
{
|
||||||
var missionHeader = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionContent.RectTransform),
|
var missionHeader = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionContent.RectTransform),
|
||||||
TextManager.Get(missionsToDisplay.Count > 1 ? "Missions" : "Mission"), textAlignment: Alignment.TopLeft, font: GUI.SubHeadingFont);
|
TextManager.Get(missionsToDisplay.Count > 1 ? "Missions" : "Mission"), textAlignment: Alignment.TopLeft, font: GUIStyle.SubHeadingFont);
|
||||||
missionHeader.RectTransform.MinSize = new Point(0, (int)(missionHeader.Rect.Height * 1.2f));
|
missionHeader.RectTransform.MinSize = new Point(0, (int)(missionHeader.Rect.Height * 1.2f));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,7 +268,7 @@ namespace Barotrauma
|
|||||||
Stretch = true
|
Stretch = true
|
||||||
};
|
};
|
||||||
|
|
||||||
string missionMessage =
|
LocalizedString missionMessage =
|
||||||
selectedMissions.Contains(displayedMission) ?
|
selectedMissions.Contains(displayedMission) ?
|
||||||
displayedMission.Completed ? displayedMission.SuccessMessage : displayedMission.FailureMessage :
|
displayedMission.Completed ? displayedMission.SuccessMessage : displayedMission.FailureMessage :
|
||||||
displayedMission.Description;
|
displayedMission.Description;
|
||||||
@@ -293,7 +290,7 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
missionContentHorizontal.Recalculate();
|
missionContentHorizontal.Recalculate();
|
||||||
var missionNameTextBlock = 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: GUIStyle.SubHeadingFont);
|
||||||
if (displayedMission.Difficulty.HasValue)
|
if (displayedMission.Difficulty.HasValue)
|
||||||
{
|
{
|
||||||
var groupSize = missionNameTextBlock.Rect.Size;
|
var groupSize = missionNameTextBlock.Rect.Size;
|
||||||
@@ -314,12 +311,21 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
var missionDescription = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
|
var missionDescription = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
|
||||||
missionMessage, wrap: true, parseRichText: true);
|
RichString.Rich(missionMessage), wrap: true);
|
||||||
int reward = displayedMission.GetReward(Submarine.MainSub);
|
int reward = displayedMission.GetReward(Submarine.MainSub);
|
||||||
if (selectedMissions.Contains(displayedMission) && displayedMission.Completed && reward > 0)
|
if (selectedMissions.Contains(displayedMission) && displayedMission.Completed && reward > 0)
|
||||||
{
|
{
|
||||||
string rewardText = TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", reward));
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform), RichString.Rich(displayedMission.GetMissionRewardText(Submarine.MainSub)));
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform), displayedMission.GetMissionRewardText(Submarine.MainSub), parseRichText: true);
|
if (GameMain.IsMultiplayer && Character.Controlled is { } controlled)
|
||||||
|
{
|
||||||
|
var (share, percentage, _) = Mission.GetRewardShare(controlled.Wallet.RewardDistribution, GameSession.GetSessionCrewCharacters(CharacterType.Player).Where(c => c != controlled), Option<int>.Some(reward));
|
||||||
|
if (share > 0)
|
||||||
|
{
|
||||||
|
string shareFormatted = string.Format(CultureInfo.InvariantCulture, "{0:N0}", share);
|
||||||
|
RichString yourShareString = RichString.Rich(TextManager.GetWithVariables("crewwallet.missionreward.get", ("[money]", $"{shareFormatted}"), ("[share]", $"{percentage}")));
|
||||||
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform), yourShareString);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (displayedMission != missionsToDisplay.Last())
|
if (displayedMission != missionsToDisplay.Last())
|
||||||
@@ -346,7 +352,7 @@ namespace Barotrauma
|
|||||||
GUIImage missionIcon = new GUIImage(new RectTransform(new Point((int)(missionContentHorizontal.Rect.Height * 0.7f)), missionContentHorizontal.RectTransform), style: "NoMissionIcon", scaleToFit: true);
|
GUIImage missionIcon = new GUIImage(new RectTransform(new Point((int)(missionContentHorizontal.Rect.Height * 0.7f)), missionContentHorizontal.RectTransform), style: "NoMissionIcon", scaleToFit: true);
|
||||||
missionIcon.RectTransform.MinSize = new Point((int)(missionContentHorizontal.Rect.Height * 0.7f));
|
missionIcon.RectTransform.MinSize = new Point((int)(missionContentHorizontal.Rect.Height * 0.7f));
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionContentHorizontal.RectTransform),
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionContentHorizontal.RectTransform),
|
||||||
TextManager.Get("nomission"), font: GUI.LargeFont);
|
TextManager.Get("nomission"), font: GUIStyle.LargeFont);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*missionContentHorizontal.Recalculate();
|
/*missionContentHorizontal.Recalculate();
|
||||||
@@ -397,7 +403,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (startLocation.Type.HasOutpost && startLocation.Reputation != null)
|
if (startLocation.Type.HasOutpost && startLocation.Reputation != null)
|
||||||
{
|
{
|
||||||
var iconStyle = GUI.Style.GetComponentStyle("LocationReputationIcon");
|
var iconStyle = GUIStyle.GetComponentStyle("LocationReputationIcon");
|
||||||
var locationFrame = CreateReputationElement(
|
var locationFrame = CreateReputationElement(
|
||||||
reputationList.Content,
|
reputationList.Content,
|
||||||
startLocation.Name,
|
startLocation.Name,
|
||||||
@@ -407,7 +413,7 @@ namespace Barotrauma
|
|||||||
CreatePathUnlockElement(locationFrame, null, startLocation);
|
CreatePathUnlockElement(locationFrame, null, startLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Faction faction in campaignMode.Factions)
|
foreach (Faction faction in campaignMode.Factions.OrderBy(f => f.Prefab.MenuOrder).ThenBy(f => f.Prefab.Name))
|
||||||
{
|
{
|
||||||
float initialReputation = faction.Reputation.Value;
|
float initialReputation = faction.Reputation.Value;
|
||||||
if (initialFactionReputations.ContainsKey(faction))
|
if (initialFactionReputations.ContainsKey(faction))
|
||||||
@@ -452,8 +458,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
var gateLocation = connection.Locations[0].IsGateBetweenBiomes ? connection.Locations[0] : connection.Locations[1];
|
var gateLocation = connection.Locations[0].IsGateBetweenBiomes ? connection.Locations[0] : connection.Locations[1];
|
||||||
var unlockEvent =
|
var unlockEvent =
|
||||||
EventSet.PrefabList.Find(ep => ep.UnlockPathEvent && ep.BiomeIdentifier == gateLocation.LevelData.Biome.Identifier) ??
|
EventPrefab.Prefabs.FirstOrDefault(ep => ep.UnlockPathEvent && ep.BiomeIdentifier == gateLocation.LevelData.Biome.Identifier) ??
|
||||||
EventSet.PrefabList.Find(ep => ep.UnlockPathEvent && string.IsNullOrEmpty(ep.BiomeIdentifier));
|
EventPrefab.Prefabs.FirstOrDefault(ep => ep.UnlockPathEvent && ep.BiomeIdentifier == Identifier.Empty);
|
||||||
|
|
||||||
if (unlockEvent == null) { continue; }
|
if (unlockEvent == null) { continue; }
|
||||||
if (string.IsNullOrEmpty(unlockEvent.UnlockPathFaction) || unlockEvent.UnlockPathFaction.Equals("location", StringComparison.OrdinalIgnoreCase))
|
if (string.IsNullOrEmpty(unlockEvent.UnlockPathFaction) || unlockEvent.UnlockPathFaction.Equals("location", StringComparison.OrdinalIgnoreCase))
|
||||||
@@ -462,7 +468,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (faction == null || !faction.Prefab.Identifier.Equals(unlockEvent.UnlockPathFaction, StringComparison.OrdinalIgnoreCase)) { continue; }
|
if (faction == null || faction.Prefab.Identifier != unlockEvent.UnlockPathFaction) { continue; }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlockEvent != null)
|
if (unlockEvent != null)
|
||||||
@@ -471,20 +477,20 @@ 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.Equals(unlockEvent.UnlockPathFaction, StringComparison.OrdinalIgnoreCase));
|
unlockFaction = GameMain.GameSession.Campaign.Factions.Find(f => f.Prefab.Identifier == unlockEvent.UnlockPathFaction);
|
||||||
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);
|
||||||
string unlockText = TextManager.GetWithVariables(
|
RichString unlockText = RichString.Rich(TextManager.GetWithVariables(
|
||||||
"lockedpathreputationrequirement",
|
"lockedpathreputationrequirement",
|
||||||
new string[] { "[reputation]", "[biomename]" },
|
("[reputation]", Reputation.GetFormattedReputationText(normalizedUnlockReputation, unlockEvent.UnlockPathReputation, addColorTags: true)),
|
||||||
new string[] { Reputation.GetFormattedReputationText(normalizedUnlockReputation, unlockEvent.UnlockPathReputation, addColorTags: true), $"‖color:gui.orange‖{connection.LevelData.Biome.DisplayName}‖end‖" });
|
("[biomename]", $"‖color:gui.orange‖{connection.LevelData.Biome.DisplayName}‖end‖")));
|
||||||
var unlockInfoPanel = new GUITextBlock(new RectTransform(new Vector2(0.8f, 0.0f), reputationFrame.RectTransform, Anchor.BottomCenter) { MinSize = new Point(0, GUI.IntScale(30)), AbsoluteOffset = new Point(0, GUI.IntScale(3)) },
|
var unlockInfoPanel = new GUITextBlock(new RectTransform(new Vector2(0.8f, 0.0f), reputationFrame.RectTransform, Anchor.BottomCenter) { MinSize = new Point(0, GUI.IntScale(30)), AbsoluteOffset = new Point(0, GUI.IntScale(3)) },
|
||||||
unlockText, style: "GUIButtonRound", textAlignment: Alignment.Center, textColor: GUI.Style.TextColor, parseRichText: true);
|
unlockText, style: "GUIButtonRound", textAlignment: Alignment.Center, textColor: GUIStyle.TextColorNormal);
|
||||||
unlockInfoPanel.Color = Color.Lerp(unlockInfoPanel.Color, Color.Black, 0.8f);
|
unlockInfoPanel.Color = Color.Lerp(unlockInfoPanel.Color, Color.Black, 0.8f);
|
||||||
if (unlockInfoPanel.TextSize.X > unlockInfoPanel.Rect.Width * 0.7f)
|
if (unlockInfoPanel.TextSize.X > unlockInfoPanel.Rect.Width * 0.7f)
|
||||||
{
|
{
|
||||||
unlockInfoPanel.Font = GUI.SmallFont;
|
unlockInfoPanel.Font = GUIStyle.SmallFont;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -492,7 +498,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetHeaderText(bool gameOver, CampaignMode.TransitionType transitionType)
|
private LocalizedString GetHeaderText(bool gameOver, CampaignMode.TransitionType transitionType)
|
||||||
{
|
{
|
||||||
string locationName = Submarine.MainSub.AtEndExit ? endLocation?.Name : startLocation?.Name;
|
string locationName = Submarine.MainSub.AtEndExit ? endLocation?.Name : startLocation?.Name;
|
||||||
|
|
||||||
@@ -539,14 +545,14 @@ namespace Barotrauma
|
|||||||
locationName = "[UNKNOWN]";
|
locationName = "[UNKNOWN]";
|
||||||
}
|
}
|
||||||
|
|
||||||
string subName = string.Empty;
|
LocalizedString subName = string.Empty;
|
||||||
SubmarineInfo currentOrPending = SubmarineSelection.CurrentOrPendingSubmarine();
|
SubmarineInfo currentOrPending = SubmarineSelection.CurrentOrPendingSubmarine();
|
||||||
if (currentOrPending != null)
|
if (currentOrPending != null)
|
||||||
{
|
{
|
||||||
subName = currentOrPending.DisplayName;
|
subName = currentOrPending.DisplayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TextManager.GetWithVariables(textTag, new string[2] { "[sub]", "[location]" }, new string[2] { subName, locationName });
|
return TextManager.GetWithVariables(textTag, ("[sub]", subName), ("[location]", locationName));
|
||||||
}
|
}
|
||||||
|
|
||||||
private GUIListBox CreateCrewList(GUIComponent parent, IEnumerable<CharacterInfo> characterInfos)
|
private GUIListBox CreateCrewList(GUIComponent parent, IEnumerable<CharacterInfo> characterInfos)
|
||||||
@@ -566,9 +572,9 @@ namespace Barotrauma
|
|||||||
characterButton.RectTransform.RelativeSize = new Vector2(characterColumnWidthPercentage * sizeMultiplier, 1f);
|
characterButton.RectTransform.RelativeSize = new Vector2(characterColumnWidthPercentage * sizeMultiplier, 1f);
|
||||||
statusButton.RectTransform.RelativeSize = new Vector2(statusColumnWidthPercentage * sizeMultiplier, 1f);
|
statusButton.RectTransform.RelativeSize = new Vector2(statusColumnWidthPercentage * sizeMultiplier, 1f);
|
||||||
|
|
||||||
jobButton.TextBlock.Font = characterButton.TextBlock.Font = statusButton.TextBlock.Font = GUI.HotkeyFont;
|
jobButton.TextBlock.Font = characterButton.TextBlock.Font = statusButton.TextBlock.Font = GUIStyle.HotkeyFont;
|
||||||
jobButton.CanBeFocused = characterButton.CanBeFocused = statusButton.CanBeFocused = false;
|
jobButton.CanBeFocused = characterButton.CanBeFocused = statusButton.CanBeFocused = false;
|
||||||
jobButton.TextBlock.ForceUpperCase = characterButton.TextBlock.ForceUpperCase = statusButton.ForceUpperCase = true;
|
jobButton.TextBlock.ForceUpperCase = characterButton.TextBlock.ForceUpperCase = statusButton.ForceUpperCase = ForceUpperCase.Yes;
|
||||||
|
|
||||||
jobColumnWidth = jobButton.Rect.Width;
|
jobColumnWidth = jobButton.Rect.Width;
|
||||||
characterColumnWidth = characterButton.Rect.Width;
|
characterColumnWidth = characterButton.Rect.Width;
|
||||||
@@ -615,10 +621,10 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
|
|
||||||
GUITextBlock characterNameBlock = new GUITextBlock(new RectTransform(new Point(characterColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform),
|
GUITextBlock characterNameBlock = new GUITextBlock(new RectTransform(new Point(characterColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform),
|
||||||
ToolBox.LimitString(characterInfo.Name, GUI.Font, characterColumnWidth), textAlignment: Alignment.Center, textColor: characterInfo.Job.Prefab.UIColor);
|
ToolBox.LimitString(characterInfo.Name, GUIStyle.Font, characterColumnWidth), textAlignment: Alignment.Center, textColor: characterInfo.Job.Prefab.UIColor);
|
||||||
|
|
||||||
string statusText = TextManager.Get("StatusOK");
|
LocalizedString statusText = TextManager.Get("StatusOK");
|
||||||
Color statusColor = GUI.Style.Green;
|
Color statusColor = GUIStyle.Green;
|
||||||
|
|
||||||
Character character = characterInfo.Character;
|
Character character = characterInfo.Character;
|
||||||
if (character == null || character.IsDead)
|
if (character == null || character.IsDead)
|
||||||
@@ -626,7 +632,7 @@ namespace Barotrauma
|
|||||||
if (character == null && characterInfo.IsNewHire && characterInfo.CauseOfDeath == null)
|
if (character == null && characterInfo.IsNewHire && characterInfo.CauseOfDeath == null)
|
||||||
{
|
{
|
||||||
statusText = TextManager.Get("CampaignCrew.NewHire");
|
statusText = TextManager.Get("CampaignCrew.NewHire");
|
||||||
statusColor = GUI.Style.Blue;
|
statusColor = GUIStyle.Blue;
|
||||||
}
|
}
|
||||||
else if (characterInfo.CauseOfDeath == null)
|
else if (characterInfo.CauseOfDeath == null)
|
||||||
{
|
{
|
||||||
@@ -637,9 +643,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
string errorMsg = "Character \"[name]\" had an invalid cause of death (the type of the cause of death was Affliction, but affliction was not specified).";
|
string errorMsg = "Character \"[name]\" had an invalid cause of death (the type of the cause of death was Affliction, but affliction was not specified).";
|
||||||
DebugConsole.ThrowError(errorMsg.Replace("[name]", characterInfo.Name));
|
DebugConsole.ThrowError(errorMsg.Replace("[name]", characterInfo.Name));
|
||||||
GameAnalyticsManager.AddErrorEventOnce("RoundSummary:InvalidCauseOfDeath", GameAnalyticsManager.ErrorSeverity.Error, errorMsg.Replace("[name]", characterInfo.SpeciesName));
|
GameAnalyticsManager.AddErrorEventOnce("RoundSummary:InvalidCauseOfDeath", GameAnalyticsManager.ErrorSeverity.Error, errorMsg.Replace("[name]", characterInfo.SpeciesName.Value));
|
||||||
statusText = TextManager.Get("CauseOfDeathDescription.Unknown");
|
statusText = TextManager.Get("CauseOfDeathDescription.Unknown");
|
||||||
statusColor = GUI.Style.Red;
|
statusColor = GUIStyle.Red;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -664,12 +670,12 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
GUITextBlock statusBlock = new GUITextBlock(new RectTransform(new Point(statusColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform),
|
GUITextBlock statusBlock = new GUITextBlock(new RectTransform(new Point(statusColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform),
|
||||||
ToolBox.LimitString(statusText, GUI.Font, characterColumnWidth), textAlignment: Alignment.Center, textColor: statusColor);
|
ToolBox.LimitString(statusText.Value, GUIStyle.Font, characterColumnWidth), textAlignment: Alignment.Center, textColor: statusColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private GUIFrame CreateReputationElement(GUIComponent parent,
|
private GUIFrame CreateReputationElement(GUIComponent parent,
|
||||||
string name, float reputation, float normalizedReputation, float initialReputation,
|
LocalizedString name, float reputation, float normalizedReputation, float initialReputation,
|
||||||
string shortDescription, string fullDescription, Sprite icon, Sprite backgroundPortrait, Color iconColor)
|
LocalizedString shortDescription, LocalizedString fullDescription, Sprite icon, Sprite backgroundPortrait, Color iconColor)
|
||||||
{
|
{
|
||||||
var factionFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.1f), parent.RectTransform), style: null);
|
var factionFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.1f), parent.RectTransform), style: null);
|
||||||
|
|
||||||
@@ -704,7 +710,7 @@ namespace Barotrauma
|
|||||||
factionInfoHorizontal.Recalculate();
|
factionInfoHorizontal.Recalculate();
|
||||||
|
|
||||||
var header = new GUITextBlock(new RectTransform(new Point(factionTextContent.Rect.Width, GUI.IntScale(40)), factionTextContent.RectTransform),
|
var header = new GUITextBlock(new RectTransform(new Point(factionTextContent.Rect.Width, GUI.IntScale(40)), factionTextContent.RectTransform),
|
||||||
name, font: GUI.SubHeadingFont)
|
name, font: GUIStyle.SubHeadingFont)
|
||||||
{
|
{
|
||||||
Padding = Vector4.Zero,
|
Padding = Vector4.Zero,
|
||||||
UserData = "header"
|
UserData = "header"
|
||||||
@@ -723,34 +729,34 @@ namespace Barotrauma
|
|||||||
new GUICustomComponent(new RectTransform(new Vector2(0.8f, 1.0f), sliderHolder.RectTransform),
|
new GUICustomComponent(new RectTransform(new Vector2(0.8f, 1.0f), sliderHolder.RectTransform),
|
||||||
onDraw: (sb, customComponent) => DrawReputationBar(sb, customComponent.Rect, normalizedReputation));
|
onDraw: (sb, customComponent) => DrawReputationBar(sb, customComponent.Rect, normalizedReputation));
|
||||||
|
|
||||||
string reputationText = Reputation.GetFormattedReputationText(normalizedReputation, reputation, addColorTags: true);
|
LocalizedString reputationText = Reputation.GetFormattedReputationText(normalizedReputation, reputation, addColorTags: true);
|
||||||
int reputationChange = (int)Math.Round(reputation - initialReputation);
|
int reputationChange = (int)Math.Round(reputation - initialReputation);
|
||||||
if (Math.Abs(reputationChange) > 0)
|
if (Math.Abs(reputationChange) > 0)
|
||||||
{
|
{
|
||||||
string changeText = $"{(reputationChange > 0 ? "+" : "") + reputationChange}";
|
string changeText = $"{(reputationChange > 0 ? "+" : "") + reputationChange}";
|
||||||
string colorStr = XMLExtensions.ColorToString(reputationChange > 0 ? GUI.Style.Green : GUI.Style.Red);
|
string colorStr = XMLExtensions.ToStringHex(reputationChange > 0 ? GUIStyle.Green : GUIStyle.Red);
|
||||||
var rtData = RichTextData.GetRichTextData($"{reputationText} (‖color:{colorStr}‖{changeText}‖color:end‖)", out string sanitizedText);
|
var richText = RichString.Rich($"{reputationText} (‖color:{colorStr}‖{changeText}‖color:end‖)");
|
||||||
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), sliderHolder.RectTransform),
|
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), sliderHolder.RectTransform),
|
||||||
rtData, sanitizedText,
|
richText,
|
||||||
textAlignment: Alignment.CenterLeft, font: GUI.SubHeadingFont);
|
textAlignment: Alignment.CenterLeft, font: GUIStyle.SubHeadingFont);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), sliderHolder.RectTransform),
|
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), sliderHolder.RectTransform),
|
||||||
reputationText,
|
RichString.Rich(reputationText),
|
||||||
textAlignment: Alignment.CenterLeft, font: GUI.SubHeadingFont, parseRichText: true);
|
textAlignment: Alignment.CenterLeft, font: GUIStyle.SubHeadingFont);
|
||||||
}
|
}
|
||||||
|
|
||||||
//spacing
|
//spacing
|
||||||
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.0f), factionTextContent.RectTransform) { MinSize = new Point(0, GUI.IntScale(5)) }, style: null);
|
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.0f), factionTextContent.RectTransform) { MinSize = new Point(0, GUI.IntScale(5)) }, style: null);
|
||||||
|
|
||||||
var factionDescription = new GUITextBlock(new RectTransform(new Vector2(0.8f, 0.6f), factionTextContent.RectTransform),
|
var factionDescription = new GUITextBlock(new RectTransform(new Vector2(0.8f, 0.6f), factionTextContent.RectTransform),
|
||||||
shortDescription, font: GUI.SmallFont, wrap: true)
|
shortDescription, font: GUIStyle.SmallFont, wrap: true)
|
||||||
{
|
{
|
||||||
UserData = "description",
|
UserData = "description",
|
||||||
Padding = Vector4.Zero
|
Padding = Vector4.Zero
|
||||||
};
|
};
|
||||||
if (shortDescription != fullDescription && !string.IsNullOrEmpty(fullDescription))
|
if (shortDescription != fullDescription && !fullDescription.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
factionDescription.ToolTip = fullDescription;
|
factionDescription.ToolTip = fullDescription;
|
||||||
}
|
}
|
||||||
@@ -771,16 +777,16 @@ namespace Barotrauma
|
|||||||
for (int i = 0; i < 5; i++)
|
for (int i = 0; i < 5; i++)
|
||||||
{
|
{
|
||||||
GUI.DrawRectangle(sb, new Rectangle(rect.X + (segmentWidth * i), rect.Y, segmentWidth, rect.Height), Reputation.GetReputationColor(i / 5.0f), isFilled: true);
|
GUI.DrawRectangle(sb, new Rectangle(rect.X + (segmentWidth * i), rect.Y, segmentWidth, rect.Height), Reputation.GetReputationColor(i / 5.0f), isFilled: true);
|
||||||
GUI.DrawRectangle(sb, new Rectangle(rect.X + (segmentWidth * i), rect.Y, segmentWidth, rect.Height), GUI.Style.ColorInventoryBackground, isFilled: false);
|
GUI.DrawRectangle(sb, new Rectangle(rect.X + (segmentWidth * i), rect.Y, segmentWidth, rect.Height), GUIStyle.ColorInventoryBackground, isFilled: false);
|
||||||
}
|
}
|
||||||
GUI.DrawRectangle(sb, rect, GUI.Style.ColorInventoryBackground, isFilled: false);
|
GUI.DrawRectangle(sb, rect, GUIStyle.ColorInventoryBackground, isFilled: false);
|
||||||
|
|
||||||
GUI.Arrow.Draw(sb, new Vector2(rect.X + rect.Width * normalizedReputation, rect.Y), GUI.Style.ColorInventoryBackground, scale: GUI.Scale, spriteEffect: SpriteEffects.FlipVertically);
|
GUI.Arrow.Draw(sb, new Vector2(rect.X + rect.Width * normalizedReputation, rect.Y), GUIStyle.ColorInventoryBackground, scale: GUI.Scale, spriteEffect: SpriteEffects.FlipVertically);
|
||||||
GUI.Arrow.Draw(sb, new Vector2(rect.X + rect.Width * normalizedReputation, rect.Y), GUI.Style.TextColor, scale: GUI.Scale * 0.8f, spriteEffect: SpriteEffects.FlipVertically);
|
GUI.Arrow.Draw(sb, new Vector2(rect.X + rect.Width * normalizedReputation, rect.Y), GUIStyle.TextColorNormal, scale: GUI.Scale * 0.8f, spriteEffect: SpriteEffects.FlipVertically);
|
||||||
|
|
||||||
GUI.DrawString(sb, new Vector2(rect.X, rect.Bottom), "-100", GUI.Style.TextColor, font: GUI.SmallFont);
|
GUI.DrawString(sb, new Vector2(rect.X, rect.Bottom), "-100", GUIStyle.TextColorNormal, font: GUIStyle.SmallFont);
|
||||||
Vector2 textSize = GUI.SmallFont.MeasureString("100");
|
Vector2 textSize = GUIStyle.SmallFont.MeasureString("100");
|
||||||
GUI.DrawString(sb, new Vector2(rect.Right - textSize.X, rect.Bottom), "100", GUI.Style.TextColor, font: GUI.SmallFont);
|
GUI.DrawString(sb, new Vector2(rect.Right - textSize.X, rect.Bottom), "100", GUIStyle.TextColorNormal, font: GUIStyle.SmallFont);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -109,7 +109,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
indicatorGroup = new GUILayoutGroup(new RectTransform(Point.Zero, hideButton.RectTransform)) { IsHorizontal = false };
|
indicatorGroup = new GUILayoutGroup(new RectTransform(Point.Zero, hideButton.RectTransform)) { IsHorizontal = false };
|
||||||
indicatorGroup.ChildAnchor = Anchor.TopCenter;
|
indicatorGroup.ChildAnchor = Anchor.TopCenter;
|
||||||
indicatorSpriteSize = GUI.Style.GetComponentStyle("EquipmentIndicatorDivingSuit").GetDefaultSprite().size;
|
indicatorSpriteSize = GUIStyle.GetComponentStyle("EquipmentIndicatorDivingSuit").GetDefaultSprite().size;
|
||||||
|
|
||||||
indicators[0] = new GUIImage(new RectTransform(Point.Zero, indicatorGroup.RectTransform), "EquipmentIndicatorDivingSuit");
|
indicators[0] = new GUIImage(new RectTransform(Point.Zero, indicatorGroup.RectTransform), "EquipmentIndicatorDivingSuit");
|
||||||
indicators[1] = new GUIImage(new RectTransform(Point.Zero, indicatorGroup.RectTransform), "EquipmentIndicatorID");
|
indicators[1] = new GUIImage(new RectTransform(Point.Zero, indicatorGroup.RectTransform), "EquipmentIndicatorID");
|
||||||
@@ -522,7 +522,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public override void Update(float deltaTime, Camera cam, bool isSubInventory = false)
|
public override void Update(float deltaTime, Camera cam, bool isSubInventory = false)
|
||||||
{
|
{
|
||||||
if (!AccessibleWhenAlive && !character.IsDead)
|
if (!AccessibleWhenAlive && !character.IsDead && !AccessibleByOwner)
|
||||||
{
|
{
|
||||||
syncItemsDelay = Math.Max(syncItemsDelay - deltaTime, 0.0f);
|
syncItemsDelay = Math.Max(syncItemsDelay - deltaTime, 0.0f);
|
||||||
return;
|
return;
|
||||||
@@ -814,21 +814,21 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (conditionPercentage != -1)
|
if (conditionPercentage != -1)
|
||||||
{
|
{
|
||||||
indicators[i].Color = ToolBox.GradientLerp(conditionPercentage, GUI.Style.EquipmentIndicatorRunningOut, GUI.Style.EquipmentIndicatorEquipped);
|
indicators[i].Color = ToolBox.GradientLerp(conditionPercentage, GUIStyle.EquipmentIndicatorRunningOut, GUIStyle.EquipmentIndicatorEquipped);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
indicators[i].Color = GUI.Style.EquipmentIndicatorRunningOut;
|
indicators[i].Color = GUIStyle.EquipmentIndicatorRunningOut;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
indicators[i].Color = GUI.Style.EquipmentIndicatorEquipped;
|
indicators[i].Color = GUIStyle.EquipmentIndicatorEquipped;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
indicators[i].Color = GUI.Style.EquipmentIndicatorNotEquipped;
|
indicators[i].Color = GUIStyle.EquipmentIndicatorNotEquipped;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -966,7 +966,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else if (character.HeldItems.Any(i =>
|
else if (character.HeldItems.Any(i =>
|
||||||
i.OwnInventory != null &&
|
i.OwnInventory != null &&
|
||||||
(i.OwnInventory.CanBePut(item) || (i.OwnInventory.Capacity == 1 && i.OwnInventory.AllowSwappingContainedItems && i.OwnInventory.Container.CanBeContained(item)))))
|
((i.OwnInventory.CanBePut(item) && allowInventorySwap) || (i.OwnInventory.Capacity == 1 && i.OwnInventory.AllowSwappingContainedItems && i.OwnInventory.Container.CanBeContained(item)))))
|
||||||
{
|
{
|
||||||
return QuickUseAction.PutToEquippedItem;
|
return QuickUseAction.PutToEquippedItem;
|
||||||
}
|
}
|
||||||
@@ -1007,7 +1007,7 @@ namespace Barotrauma
|
|||||||
var slot = invSlots[i];
|
var slot = invSlots[i];
|
||||||
if (item.ParentInventory.GetItemAt(i) == item)
|
if (item.ParentInventory.GetItemAt(i) == item)
|
||||||
{
|
{
|
||||||
slot.ShowBorderHighlight(GUI.Style.Red, 0.1f, 0.4f);
|
slot.ShowBorderHighlight(GUIStyle.Red, 0.1f, 0.4f);
|
||||||
SoundPlayer.PlayUISound(GUISoundType.PickItem);
|
SoundPlayer.PlayUISound(GUISoundType.PickItem);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1033,7 +1033,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (GUIMessageBox.MessageBoxes.Any(mb => mb.UserData as string == "equipconfirmation")) { return; }
|
if (GUIMessageBox.MessageBoxes.Any(mb => mb.UserData as string == "equipconfirmation")) { return; }
|
||||||
var equipConfirmation = new GUIMessageBox(string.Empty, TextManager.Get(item.Prefab.EquipConfirmationText),
|
var equipConfirmation = new GUIMessageBox(string.Empty, TextManager.Get(item.Prefab.EquipConfirmationText),
|
||||||
new string[] { TextManager.Get("yes"), TextManager.Get("no") })
|
new LocalizedString[] { TextManager.Get("yes"), TextManager.Get("no") })
|
||||||
{
|
{
|
||||||
UserData = "equipconfirmation"
|
UserData = "equipconfirmation"
|
||||||
};
|
};
|
||||||
@@ -1138,7 +1138,7 @@ namespace Barotrauma
|
|||||||
success = true;
|
success = true;
|
||||||
for (int j = 0; j < capacity; j++)
|
for (int j = 0; j < capacity; j++)
|
||||||
{
|
{
|
||||||
if (slots[j].Contains(heldItem)) { visualSlots[j].ShowBorderHighlight(GUI.Style.Green, 0.1f, 0.4f); }
|
if (slots[j].Contains(heldItem)) { visualSlots[j].ShowBorderHighlight(GUIStyle.Green, 0.1f, 0.4f); }
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1150,7 +1150,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < capacity; i++)
|
for (int i = 0; i < capacity; i++)
|
||||||
{
|
{
|
||||||
if (slots[i].Contains(item)) { visualSlots[i].ShowBorderHighlight(GUI.Style.Green, 0.1f, 0.4f); }
|
if (slots[i].Contains(item)) { visualSlots[i].ShowBorderHighlight(GUIStyle.Green, 0.1f, 0.4f); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1163,7 +1163,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void DrawOwn(SpriteBatch spriteBatch)
|
public void DrawOwn(SpriteBatch spriteBatch)
|
||||||
{
|
{
|
||||||
if (!AccessibleWhenAlive && !character.IsDead) { return; }
|
if (!AccessibleWhenAlive && !character.IsDead && !AccessibleByOwner) { return; }
|
||||||
if (capacity == 0) { return; }
|
if (capacity == 0) { return; }
|
||||||
if (visualSlots == null) { CreateSlots(); }
|
if (visualSlots == null) { CreateSlots(); }
|
||||||
if (GameMain.GraphicsWidth != screenResolution.X ||
|
if (GameMain.GraphicsWidth != screenResolution.X ||
|
||||||
@@ -1182,7 +1182,7 @@ namespace Barotrauma
|
|||||||
CalculateBackgroundFrame();
|
CalculateBackgroundFrame();
|
||||||
GUI.DrawRectangle(spriteBatch, BackgroundFrame, Color.Black * 0.8f, true);
|
GUI.DrawRectangle(spriteBatch, BackgroundFrame, Color.Black * 0.8f, true);
|
||||||
GUI.DrawString(spriteBatch,
|
GUI.DrawString(spriteBatch,
|
||||||
new Vector2((int)(BackgroundFrame.Center.X - GUI.Font.MeasureString(character.Name).X / 2), (int)BackgroundFrame.Y + 5),
|
new Vector2((int)(BackgroundFrame.Center.X - GUIStyle.Font.MeasureString(character.Name).X / 2), (int)BackgroundFrame.Y + 5),
|
||||||
character.Name, Color.White * 0.9f);
|
character.Name, Color.White * 0.9f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1218,7 +1218,7 @@ namespace Barotrauma
|
|||||||
if (LimbSlotIcons.ContainsKey(SlotTypes[i]))
|
if (LimbSlotIcons.ContainsKey(SlotTypes[i]))
|
||||||
{
|
{
|
||||||
var icon = LimbSlotIcons[SlotTypes[i]];
|
var icon = LimbSlotIcons[SlotTypes[i]];
|
||||||
icon.Draw(spriteBatch, visualSlots[i].Rect.Center.ToVector2() + visualSlots[i].DrawOffset, GUI.Style.EquipmentSlotIconColor, origin: icon.size / 2, scale: visualSlots[i].Rect.Width / icon.size.X);
|
icon.Draw(spriteBatch, visualSlots[i].Rect.Center.ToVector2() + visualSlots[i].DrawOffset, GUIStyle.EquipmentSlotIconColor, origin: icon.size / 2, scale: visualSlots[i].Rect.Width / icon.size.X);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1292,14 +1292,14 @@ namespace Barotrauma
|
|||||||
if (Locked)
|
if (Locked)
|
||||||
{
|
{
|
||||||
GUI.DrawRectangle(spriteBatch, inventoryArea, new Color(30,30,30,100), isFilled: true);
|
GUI.DrawRectangle(spriteBatch, inventoryArea, new Color(30,30,30,100), isFilled: true);
|
||||||
var lockIcon = GUI.Style.GetComponentStyle("LockIcon")?.GetDefaultSprite();
|
var lockIcon = GUIStyle.GetComponentStyle("LockIcon")?.GetDefaultSprite();
|
||||||
lockIcon?.Draw(spriteBatch, inventoryArea.Center.ToVector2(), scale: Math.Min(inventoryArea.Height / lockIcon.size.Y * 0.7f, 1.0f));
|
lockIcon?.Draw(spriteBatch, inventoryArea.Center.ToVector2(), scale: Math.Min(inventoryArea.Height / lockIcon.size.Y * 0.7f, 1.0f));
|
||||||
if (inventoryArea.Contains(PlayerInput.MousePosition))
|
if (inventoryArea.Contains(PlayerInput.MousePosition))
|
||||||
{
|
{
|
||||||
GUIComponent.DrawToolTip(spriteBatch, TextManager.Get("handcuffed"), new Rectangle(inventoryArea.Center - new Point(inventoryArea.Height / 2), new Point(inventoryArea.Height)));
|
GUIComponent.DrawToolTip(spriteBatch, TextManager.Get("handcuffed"), new Rectangle(inventoryArea.Center - new Point(inventoryArea.Height / 2), new Point(inventoryArea.Height)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (highlightedQuickUseSlot != null && !string.IsNullOrEmpty(highlightedQuickUseSlot.QuickUseButtonToolTip))
|
else if (highlightedQuickUseSlot != null && !highlightedQuickUseSlot.QuickUseButtonToolTip.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
GUIComponent.DrawToolTip(spriteBatch, highlightedQuickUseSlot.QuickUseButtonToolTip, highlightedQuickUseSlot.EquipButtonRect);
|
GUIComponent.DrawToolTip(spriteBatch, highlightedQuickUseSlot.QuickUseButtonToolTip, highlightedQuickUseSlot.EquipButtonRect);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace Barotrauma.Items.Components
|
|||||||
//openState when the vertices of the convex hull were last calculated
|
//openState when the vertices of the convex hull were last calculated
|
||||||
private float lastConvexHullState;
|
private float lastConvexHullState;
|
||||||
|
|
||||||
[Serialize("1,1", false, description: "The scale of the shadow-casting area of the door (relative to the actual size of the door).")]
|
[Serialize("1,1", IsPropertySaveable.No, description: "The scale of the shadow-casting area of the door (relative to the actual size of the door).")]
|
||||||
public Vector2 ShadowScale
|
public Vector2 ShadowScale
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
@@ -283,9 +283,9 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
public override void ClientEventRead(IReadMessage msg, float sendingTime)
|
||||||
{
|
{
|
||||||
base.ClientRead(type, msg, sendingTime);
|
base.ClientEventRead(msg, sendingTime);
|
||||||
|
|
||||||
bool open = msg.ReadBoolean();
|
bool open = msg.ReadBoolean();
|
||||||
bool broken = msg.ReadBoolean();
|
bool broken = msg.ReadBoolean();
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
public void ClientEventRead(IReadMessage msg, float sendingTime)
|
||||||
{
|
{
|
||||||
CurrPowerConsumption = powerConsumption;
|
CurrPowerConsumption = powerConsumption;
|
||||||
charging = true;
|
charging = true;
|
||||||
|
|||||||
@@ -17,12 +17,12 @@ namespace Barotrauma.Items.Components
|
|||||||
case AreaShape.Rectangle:
|
case AreaShape.Rectangle:
|
||||||
{
|
{
|
||||||
RectangleF rect = GetAreaRectangle(SpawnAreaBounds, SpawnAreaOffset, draw: true);
|
RectangleF rect = GetAreaRectangle(SpawnAreaBounds, SpawnAreaOffset, draw: true);
|
||||||
GUI.DrawRectangle(spriteBatch, rect.Location, rect.Size, GUI.Style.Red, isFilled: false, 0f, 4f);
|
GUI.DrawRectangle(spriteBatch, rect.Location, rect.Size, GUIStyle.Red, isFilled: false, 0f, 4f);
|
||||||
|
|
||||||
if (MaximumAmountRangePadding > 0f)
|
if (MaximumAmountRangePadding > 0f)
|
||||||
{
|
{
|
||||||
rect.Inflate(MaximumAmountRangePadding, MaximumAmountRangePadding);
|
rect.Inflate(MaximumAmountRangePadding, MaximumAmountRangePadding);
|
||||||
GUI.DrawRectangle(spriteBatch, rect.Location, rect.Size, GUI.Style.Red, isFilled: false, 0f, 2f);
|
GUI.DrawRectangle(spriteBatch, rect.Location, rect.Size, GUIStyle.Red, isFilled: false, 0f, 2f);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -30,11 +30,11 @@ namespace Barotrauma.Items.Components
|
|||||||
Vector2 center = item.WorldPosition;
|
Vector2 center = item.WorldPosition;
|
||||||
center += SpawnAreaOffset;
|
center += SpawnAreaOffset;
|
||||||
center.Y = -center.Y;
|
center.Y = -center.Y;
|
||||||
spriteBatch.DrawCircle(center, SpawnAreaRadius, 32, GUI.Style.Red, thickness: 4f);
|
spriteBatch.DrawCircle(center, SpawnAreaRadius, 32, GUIStyle.Red, thickness: 4f);
|
||||||
|
|
||||||
if (MaximumAmountRangePadding > 0f)
|
if (MaximumAmountRangePadding > 0f)
|
||||||
{
|
{
|
||||||
spriteBatch.DrawCircle(center, SpawnAreaRadius + MaximumAmountRangePadding, 32, GUI.Style.Red, thickness: 2f);
|
spriteBatch.DrawCircle(center, SpawnAreaRadius + MaximumAmountRangePadding, 32, GUIStyle.Red, thickness: 2f);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -46,14 +46,14 @@ namespace Barotrauma.Items.Components
|
|||||||
case AreaShape.Rectangle:
|
case AreaShape.Rectangle:
|
||||||
{
|
{
|
||||||
RectangleF rect = GetAreaRectangle(CrewAreaBounds, CrewAreaOffset, draw: true);
|
RectangleF rect = GetAreaRectangle(CrewAreaBounds, CrewAreaOffset, draw: true);
|
||||||
GUI.DrawRectangle(spriteBatch, rect.Location, rect.Size, GUI.Style.Green, isFilled: false, 0f, 4f);
|
GUI.DrawRectangle(spriteBatch, rect.Location, rect.Size, GUIStyle.Green, isFilled: false, 0f, 4f);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AreaShape.Circle:
|
case AreaShape.Circle:
|
||||||
Vector2 center = item.WorldPosition;
|
Vector2 center = item.WorldPosition;
|
||||||
center += CrewAreaOffset;
|
center += CrewAreaOffset;
|
||||||
center.Y = -center.Y;
|
center.Y = -center.Y;
|
||||||
spriteBatch.DrawCircle(center, CrewAreaRadius, 32, GUI.Style.Green);
|
spriteBatch.DrawCircle(center, CrewAreaRadius, 32, GUIStyle.Green);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,17 +6,17 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
partial class GeneticMaterial : ItemComponent
|
partial class GeneticMaterial : ItemComponent
|
||||||
{
|
{
|
||||||
[Serialize(0.0f, false)]
|
[Serialize(0.0f, IsPropertySaveable.No)]
|
||||||
public float TooltipValueMin { get; set; }
|
public float TooltipValueMin { get; set; }
|
||||||
|
|
||||||
[Serialize(0.0f, false)]
|
[Serialize(0.0f, IsPropertySaveable.No)]
|
||||||
public float TooltipValueMax { get; set; }
|
public float TooltipValueMax { get; set; }
|
||||||
|
|
||||||
public override void AddTooltipInfo(ref string name, ref string description)
|
public override void AddTooltipInfo(ref LocalizedString name, ref LocalizedString description)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(materialName) && item.ContainedItems.Count() > 0)
|
if (!materialName.IsNullOrEmpty() && item.ContainedItems.Count() > 0)
|
||||||
{
|
{
|
||||||
string mergedMaterialName = materialName;
|
LocalizedString mergedMaterialName = materialName;
|
||||||
foreach (Item containedItem in item.ContainedItems)
|
foreach (Item containedItem in item.ContainedItems)
|
||||||
{
|
{
|
||||||
var containedMaterial = containedItem.GetComponent<GeneticMaterial>();
|
var containedMaterial = containedItem.GetComponent<GeneticMaterial>();
|
||||||
@@ -31,30 +31,30 @@ namespace Barotrauma.Items.Components
|
|||||||
name = TextManager.GetWithVariable("entityname.taintedgeneticmaterial", "[geneticmaterialname]", name);
|
name = TextManager.GetWithVariable("entityname.taintedgeneticmaterial", "[geneticmaterialname]", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TextManager.ContainsTag("entitydescription." + Item.prefab.Identifier))
|
if (TextManager.ContainsTag("entitydescription." + Item.Prefab.Identifier))
|
||||||
{
|
{
|
||||||
int value = (int)MathHelper.Lerp(TooltipValueMin, TooltipValueMax, item.ConditionPercentage / 100.0f);
|
int value = (int)MathHelper.Lerp(TooltipValueMin, TooltipValueMax, item.ConditionPercentage / 100.0f);
|
||||||
description = TextManager.GetWithVariable("entitydescription." + Item.prefab.Identifier, "[value]", value.ToString());
|
description = TextManager.GetWithVariable("entitydescription." + Item.Prefab.Identifier, "[value]", value.ToString());
|
||||||
}
|
}
|
||||||
foreach (Item containedItem in item.ContainedItems)
|
foreach (Item containedItem in item.ContainedItems)
|
||||||
{
|
{
|
||||||
var containedGeneticMaterial = containedItem.GetComponent<GeneticMaterial>();
|
var containedGeneticMaterial = containedItem.GetComponent<GeneticMaterial>();
|
||||||
if (containedGeneticMaterial == null) { continue; }
|
if (containedGeneticMaterial == null) { continue; }
|
||||||
string _ = string.Empty;
|
LocalizedString _ = string.Empty;
|
||||||
string containedDescription = containedItem.Description;
|
LocalizedString containedDescription = containedItem.Description;
|
||||||
containedGeneticMaterial.AddTooltipInfo(ref _, ref containedDescription);
|
containedGeneticMaterial.AddTooltipInfo(ref _, ref containedDescription);
|
||||||
if (!string.IsNullOrEmpty(containedDescription))
|
if (!containedDescription.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
description += '\n' + containedDescription;
|
description += '\n' + containedDescription;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ModifyDeconstructInfo(Deconstructor deconstructor, ref string buttonText, ref string infoText)
|
public void ModifyDeconstructInfo(Deconstructor deconstructor, ref LocalizedString buttonText, ref LocalizedString infoText)
|
||||||
{
|
{
|
||||||
if (deconstructor.InputContainer.Inventory.AllItems.Count() == 2)
|
if (deconstructor.InputContainer.Inventory.AllItems.Count() == 2)
|
||||||
{
|
{
|
||||||
if (!deconstructor.InputContainer.Inventory.AllItems.All(it => it.prefab == item.prefab))
|
if (!deconstructor.InputContainer.Inventory.AllItems.All(it => it.Prefab == item.Prefab))
|
||||||
{
|
{
|
||||||
buttonText = TextManager.Get("researchstation.combine");
|
buttonText = TextManager.Get("researchstation.combine");
|
||||||
infoText = TextManager.Get("researchstation.combine.infotext");
|
infoText = TextManager.Get("researchstation.combine.infotext");
|
||||||
@@ -68,18 +68,18 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
public void ClientEventRead(IReadMessage msg, float sendingTime)
|
||||||
{
|
{
|
||||||
Tainted = msg.ReadBoolean();
|
Tainted = msg.ReadBoolean();
|
||||||
if (Tainted)
|
if (Tainted)
|
||||||
{
|
{
|
||||||
uint selectedTaintedEffectId = msg.ReadUInt32();
|
uint selectedTaintedEffectId = msg.ReadUInt32();
|
||||||
selectedTaintedEffect = AfflictionPrefab.Prefabs.Find(a => a.UIntIdentifier == selectedTaintedEffectId);
|
selectedTaintedEffect = AfflictionPrefab.Prefabs.Find(a => a.UintIdentifier == selectedTaintedEffectId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint selectedEffectId = msg.ReadUInt32();
|
uint selectedEffectId = msg.ReadUInt32();
|
||||||
selectedEffect = AfflictionPrefab.Prefabs.Find(a => a.UIntIdentifier == selectedEffectId);
|
selectedEffect = AfflictionPrefab.Prefabs.Find(a => a.UintIdentifier == selectedEffectId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using Barotrauma.Networking;
|
using Barotrauma.Networking;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
@@ -10,15 +11,15 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
internal class VineSprite
|
internal class VineSprite
|
||||||
{
|
{
|
||||||
[Serialize("0,0,0,0", false)]
|
[Serialize("0,0,0,0", IsPropertySaveable.No)]
|
||||||
public Rectangle SourceRect { get; private set; }
|
public Rectangle SourceRect { get; private set; }
|
||||||
|
|
||||||
[Serialize("0.5,0.5", false)]
|
[Serialize("0.5,0.5", IsPropertySaveable.No)]
|
||||||
public Vector2 Origin { get; private set; }
|
public Vector2 Origin { get; private set; }
|
||||||
|
|
||||||
public Vector2 AbsoluteOrigin;
|
public Vector2 AbsoluteOrigin;
|
||||||
|
|
||||||
public VineSprite(XElement element)
|
public VineSprite(ContentXElement element)
|
||||||
{
|
{
|
||||||
SerializableProperty.DeserializeProperties(this, element);
|
SerializableProperty.DeserializeProperties(this, element);
|
||||||
AbsoluteOrigin = new Vector2(SourceRect.Width * Origin.X, SourceRect.Height * Origin.Y);
|
AbsoluteOrigin = new Vector2(SourceRect.Width * Origin.X, SourceRect.Height * Origin.Y);
|
||||||
@@ -109,28 +110,27 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void LoadVines(XElement element)
|
partial void LoadVines(ContentXElement element)
|
||||||
{
|
{
|
||||||
string? vineAtlasPath = element.GetAttributeString("vineatlas", null);
|
ContentPath vineAtlasPath = element.GetAttributeContentPath("vineatlas") ?? ContentPath.Empty;
|
||||||
string? decayAtlasPath = element.GetAttributeString("decayatlas", null);
|
ContentPath decayAtlasPath = element.GetAttributeContentPath("decayatlas") ?? ContentPath.Empty;
|
||||||
|
|
||||||
if (vineAtlasPath != null)
|
if (!vineAtlasPath.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
VineAtlas = new Sprite(vineAtlasPath, Rectangle.Empty);
|
VineAtlas = new Sprite(vineAtlasPath.Value, Rectangle.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decayAtlasPath != null)
|
if (!decayAtlasPath.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
DecayAtlas = new Sprite(decayAtlasPath, Rectangle.Empty);
|
DecayAtlas = new Sprite(decayAtlasPath.Value, Rectangle.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (XElement subElement in element.Elements())
|
foreach (var subElement in element.Elements())
|
||||||
{
|
{
|
||||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||||
{
|
{
|
||||||
case "vinesprite":
|
case "vinesprite":
|
||||||
var tileType = subElement.GetAttributeString("type", null);
|
VineTileType type = subElement.GetAttributeEnum("type", VineTileType.Stem);
|
||||||
VineTileType type = Enum.Parse<VineTileType>(tileType);
|
|
||||||
VineSprites.Add(type, new VineSprite(subElement));
|
VineSprites.Add(type, new VineSprite(subElement));
|
||||||
break;
|
break;
|
||||||
case "flowersprite":
|
case "flowersprite":
|
||||||
@@ -145,18 +145,18 @@ namespace Barotrauma.Items.Components
|
|||||||
leafVariants = LeafSprites.Count;
|
leafVariants = LeafSprites.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (VineTileType type in Enum.GetValues(typeof(VineTileType)))
|
foreach (VineTileType type in Enum.GetValues(typeof(VineTileType)).Cast<VineTileType>())
|
||||||
{
|
{
|
||||||
if (!VineSprites.ContainsKey(type))
|
if (!VineSprites.ContainsKey(type))
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError($"Vine sprite missing from {item.prefab.Identifier}: {type}");
|
DebugConsole.ThrowError($"Vine sprite missing from {item.Prefab.Identifier}: {type}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly object mutex = new object();
|
private readonly object mutex = new object();
|
||||||
|
|
||||||
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
public void ClientEventRead(IReadMessage msg, float sendingTime)
|
||||||
{
|
{
|
||||||
Health = msg.ReadRangedSingle(0, MaxHealth, 8);
|
Health = msg.ReadRangedSingle(0, MaxHealth, 8);
|
||||||
int startOffset = msg.ReadRangedInteger(-1, MaximumVines);
|
int startOffset = msg.ReadRangedInteger(-1, MaximumVines);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user