Merge branch 'master' of https://github.com/Regalis11/Barotrauma.git
This commit is contained in:
@@ -11,7 +11,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (Character.IsUnconscious || !Character.Enabled || !Enabled) { return; }
|
if (Character.IsUnconscious || !Character.Enabled || !Enabled) { return; }
|
||||||
|
|
||||||
Vector2 pos = Character.WorldPosition;
|
Vector2 pos = Character.DrawPosition;
|
||||||
pos.Y = -pos.Y;
|
pos.Y = -pos.Y;
|
||||||
|
|
||||||
if (State == AIState.Idle && PreviousState == AIState.Attack)
|
if (State == AIState.Idle && PreviousState == AIState.Attack)
|
||||||
@@ -31,7 +31,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else if (SelectedAiTarget?.Entity != null)
|
else if (SelectedAiTarget?.Entity != null)
|
||||||
{
|
{
|
||||||
Vector2 targetPos = SelectedAiTarget.WorldPosition;
|
Vector2 targetPos = SelectedAiTarget.Entity.DrawPosition;
|
||||||
if (State == AIState.Attack)
|
if (State == AIState.Attack)
|
||||||
{
|
{
|
||||||
targetPos = attackWorldPos;
|
targetPos = attackWorldPos;
|
||||||
@@ -72,7 +72,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 80.0f, State.ToString(), stateColor, Color.Black);
|
GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 80.0f, State.ToString(), stateColor, Color.Black);
|
||||||
|
|
||||||
if (LatchOntoAI != null)
|
if (LatchOntoAI != null && (State == AIState.Idle || LatchOntoAI.IsAttachedToSub))
|
||||||
{
|
{
|
||||||
foreach (Joint attachJoint in LatchOntoAI.AttachJoints)
|
foreach (Joint attachJoint in LatchOntoAI.AttachJoints)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
namespace Barotrauma
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
abstract partial class AIObjective
|
abstract partial class AIObjective
|
||||||
{
|
{
|
||||||
|
public static Color ObjectiveIconColor => Color.LightGray;
|
||||||
|
|
||||||
public static Sprite GetSprite(string identifier, string option, Entity targetEntity)
|
public static Sprite GetSprite(string identifier, string option, Entity targetEntity)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(identifier))
|
if (string.IsNullOrEmpty(identifier))
|
||||||
|
|||||||
@@ -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)
|
public GUIMessage(string rawText, Color color, float delay, string identifier = null, int? value = null, float lifeTime = 3.0f)
|
||||||
{
|
{
|
||||||
RawText = Text = rawText;
|
RawText = Text = rawText;
|
||||||
if (value.HasValue)
|
if (value.HasValue)
|
||||||
@@ -166,7 +166,7 @@ namespace Barotrauma
|
|||||||
Size = GUI.Font.MeasureString(Text);
|
Size = GUI.Font.MeasureString(Text);
|
||||||
Color = color;
|
Color = color;
|
||||||
Identifier = identifier;
|
Identifier = identifier;
|
||||||
Lifetime = 3.0f;
|
Lifetime = lifeTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,11 +312,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cursorPosition = cam.ScreenToWorld(PlayerInput.MousePosition);
|
UpdateLocalCursor(cam);
|
||||||
if (AnimController.CurrentHull?.Submarine != null)
|
|
||||||
{
|
|
||||||
cursorPosition -= AnimController.CurrentHull.Submarine.Position;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 mouseSimPos = ConvertUnits.ToSimUnits(cursorPosition);
|
Vector2 mouseSimPos = ConvertUnits.ToSimUnits(cursorPosition);
|
||||||
if (GUI.PauseMenuOpen)
|
if (GUI.PauseMenuOpen)
|
||||||
@@ -393,6 +389,15 @@ namespace Barotrauma
|
|||||||
DisableControls = false;
|
DisableControls = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UpdateLocalCursor(Camera cam)
|
||||||
|
{
|
||||||
|
cursorPosition = cam.ScreenToWorld(PlayerInput.MousePosition);
|
||||||
|
if (AnimController.CurrentHull?.Submarine != null)
|
||||||
|
{
|
||||||
|
cursorPosition -= AnimController.CurrentHull.Submarine.DrawPosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
partial void UpdateControlled(float deltaTime, Camera cam)
|
partial void UpdateControlled(float deltaTime, Camera cam)
|
||||||
{
|
{
|
||||||
if (controlled != this) return;
|
if (controlled != this) return;
|
||||||
@@ -997,7 +1002,7 @@ namespace Barotrauma
|
|||||||
return nameColor;
|
return nameColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddMessage(string rawText, Color color, bool playSound, string identifier = null, int? value = null)
|
public void AddMessage(string rawText, Color color, bool playSound, string identifier = null, int? value = null, float lifetime = 3.0f)
|
||||||
{
|
{
|
||||||
GUIMessage existingMessage = null;
|
GUIMessage existingMessage = null;
|
||||||
|
|
||||||
@@ -1026,7 +1031,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
if (existingMessage == null || !value.HasValue)
|
if (existingMessage == null || !value.HasValue)
|
||||||
{
|
{
|
||||||
var newMessage = new GUIMessage(rawText, color, delay, identifier, value);
|
var newMessage = new GUIMessage(rawText, color, delay, identifier, value, lifetime);
|
||||||
guiMessages.Insert(0, newMessage);
|
guiMessages.Insert(0, newMessage);
|
||||||
if (playSound)
|
if (playSound)
|
||||||
{
|
{
|
||||||
@@ -1156,9 +1161,9 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void OnTalentGiven(string talentIdentifier)
|
partial void OnTalentGiven(TalentPrefab talentPrefab)
|
||||||
{
|
{
|
||||||
AddMessage(TextManager.Get("talentname." + talentIdentifier.ToString()), GUI.Style.Yellow, playSound: this == Controlled);
|
AddMessage(TextManager.Get("talentname." + talentPrefab.Identifier), GUI.Style.Yellow, playSound: this == Controlled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
return
|
return
|
||||||
character?.Inventory != null &&
|
character?.Inventory != null &&
|
||||||
character.AllowInput &&
|
!character.Removed && !character.IsKnockedDown &&
|
||||||
(controller?.User != character || !controller.HideHUD) &&
|
(controller?.User != character || !controller.HideHUD) &&
|
||||||
!IsCampaignInterfaceOpen &&
|
!IsCampaignInterfaceOpen &&
|
||||||
!ConversationAction.FadeScreenToBlack;
|
!ConversationAction.FadeScreenToBlack;
|
||||||
@@ -406,6 +406,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 = GUI.Style.GetComponentStyle("CampaignInteractionIcon." + npc.CampaignInteractionType);
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
@@ -431,7 +432,7 @@ namespace Barotrauma
|
|||||||
foreach (Item item in Item.ItemList)
|
foreach (Item item in Item.ItemList)
|
||||||
{
|
{
|
||||||
if (item.IconStyle is null || item.Submarine != character.Submarine) { continue; }
|
if (item.IconStyle is null || item.Submarine != character.Submarine) { continue; }
|
||||||
if (Vector2.DistanceSquared(character.Position, item.Position) > 500f*500f) { continue; }
|
if (Vector2.DistanceSquared(character.Position, item.Position) > 500f * 500f) { continue; }
|
||||||
var body = Submarine.CheckVisibility(character.SimPosition, item.SimPosition, ignoreLevel: true);
|
var body = Submarine.CheckVisibility(character.SimPosition, item.SimPosition, ignoreLevel: true);
|
||||||
if (body != null && body.UserData as Item != item) { continue; }
|
if (body != null && body.UserData as Item != item) { continue; }
|
||||||
GUI.DrawIndicator(spriteBatch, item.WorldPosition + new Vector2(0f, item.RectHeight * 0.65f), cam, new Range<float>(-100f, 500.0f), item.IconStyle.GetDefaultSprite(), item.IconStyle.Color, createOffset: false);
|
GUI.DrawIndicator(spriteBatch, item.WorldPosition + new Vector2(0f, item.RectHeight * 0.65f), cam, new Range<float>(-100f, 500.0f), item.IconStyle.GetDefaultSprite(), item.IconStyle.Color, createOffset: false);
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ namespace Barotrauma
|
|||||||
private static Sprite infoAreaPortraitBG;
|
private static Sprite infoAreaPortraitBG;
|
||||||
|
|
||||||
public bool LastControlled;
|
public bool LastControlled;
|
||||||
|
public int CrewListIndex { get; set; } = -1;
|
||||||
|
|
||||||
#warning TODO: Refactor
|
#warning TODO: Refactor
|
||||||
private Sprite disguisedPortrait;
|
private Sprite disguisedPortrait;
|
||||||
@@ -521,6 +522,7 @@ namespace Barotrauma
|
|||||||
ch.SkinColor = skinColor;
|
ch.SkinColor = skinColor;
|
||||||
ch.HairColor = hairColor;
|
ch.HairColor = hairColor;
|
||||||
ch.FacialHairColor = facialHairColor;
|
ch.FacialHairColor = facialHairColor;
|
||||||
|
ch.SetPersonalityTrait();
|
||||||
if (ch.Job != null)
|
if (ch.Job != null)
|
||||||
{
|
{
|
||||||
foreach (KeyValuePair<string, float> skill in skillLevels)
|
foreach (KeyValuePair<string, float> skill in skillLevels)
|
||||||
@@ -830,7 +832,7 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
|
|
||||||
new GUIFrame(
|
new GUIFrame(
|
||||||
new RectTransform(new Vector2(1.25f, 1.25f), HeadSelectionList.RectTransform, Anchor.Center),
|
new RectTransform(new Vector2(1.25f, 1.25f), HeadSelectionList.ContentBackground.RectTransform, Anchor.Center),
|
||||||
style: "OuterGlow", color: Color.Black)
|
style: "OuterGlow", color: Color.Black)
|
||||||
{
|
{
|
||||||
UserData = "outerglow",
|
UserData = "outerglow",
|
||||||
@@ -969,6 +971,11 @@ namespace Barotrauma
|
|||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
ClearSprites();
|
ClearSprites();
|
||||||
|
if (HeadSelectionList != null)
|
||||||
|
{
|
||||||
|
HeadSelectionList.RectTransform.Parent = null;
|
||||||
|
HeadSelectionList = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~AppearanceCustomizationMenu()
|
~AppearanceCustomizationMenu()
|
||||||
|
|||||||
@@ -2,12 +2,20 @@
|
|||||||
{
|
{
|
||||||
partial class AfflictionHusk : Affliction
|
partial class AfflictionHusk : Affliction
|
||||||
{
|
{
|
||||||
|
private InfectionState? prevDisplayedMessage;
|
||||||
partial void UpdateMessages()
|
partial void UpdateMessages()
|
||||||
{
|
{
|
||||||
|
if (character != Character.Controlled) { return; }
|
||||||
if (Prefab is AfflictionPrefabHusk { SendMessages: false }) { return; }
|
if (Prefab is AfflictionPrefabHusk { SendMessages: false }) { return; }
|
||||||
|
if (prevDisplayedMessage.HasValue && prevDisplayedMessage.Value == State) { return; }
|
||||||
|
|
||||||
switch (State)
|
switch (State)
|
||||||
{
|
{
|
||||||
case InfectionState.Dormant:
|
case InfectionState.Dormant:
|
||||||
|
if (Strength < DormantThreshold * 0.5f)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
GUI.AddMessage(TextManager.Get("HuskDormant"), GUI.Style.Red);
|
GUI.AddMessage(TextManager.Get("HuskDormant"), GUI.Style.Red);
|
||||||
break;
|
break;
|
||||||
case InfectionState.Transition:
|
case InfectionState.Transition:
|
||||||
@@ -23,6 +31,7 @@
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
prevDisplayedMessage = State;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ namespace Barotrauma
|
|||||||
Hull fireHull = Hull.hullList.GetRandom(h => h.Submarine == character.Submarine);
|
Hull fireHull = Hull.hullList.GetRandom(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), 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)
|
||||||
{
|
{
|
||||||
CausedByPsychosis = true,
|
CausedByPsychosis = true,
|
||||||
DamagesItems = false,
|
DamagesItems = false,
|
||||||
|
|||||||
@@ -531,6 +531,8 @@ namespace Barotrauma
|
|||||||
bloodParticleTimer -= deltaTime * (affliction.Strength / 10.0f);
|
bloodParticleTimer -= deltaTime * (affliction.Strength / 10.0f);
|
||||||
if (bloodParticleTimer <= 0.0f)
|
if (bloodParticleTimer <= 0.0f)
|
||||||
{
|
{
|
||||||
|
Limb limb = targetLimb ?? Character.AnimController.MainLimb;
|
||||||
|
|
||||||
bool inWater = Character.AnimController.InWater;
|
bool inWater = Character.AnimController.InWater;
|
||||||
var drawTarget = inWater ? Particles.ParticlePrefab.DrawTargetType.Water : Particles.ParticlePrefab.DrawTargetType.Air;
|
var drawTarget = inWater ? Particles.ParticlePrefab.DrawTargetType.Water : Particles.ParticlePrefab.DrawTargetType.Air;
|
||||||
var emitter = Character.BloodEmitters.FirstOrDefault(e => e.Prefab.ParticlePrefab.DrawTarget == drawTarget || e.Prefab.ParticlePrefab.DrawTarget == Particles.ParticlePrefab.DrawTargetType.Both);
|
var emitter = Character.BloodEmitters.FirstOrDefault(e => e.Prefab.ParticlePrefab.DrawTarget == drawTarget || e.Prefab.ParticlePrefab.DrawTarget == Particles.ParticlePrefab.DrawTargetType.Both);
|
||||||
@@ -543,13 +545,13 @@ namespace Barotrauma
|
|||||||
if (!inWater)
|
if (!inWater)
|
||||||
{
|
{
|
||||||
bloodParticleSize *= 2.0f;
|
bloodParticleSize *= 2.0f;
|
||||||
velocity = targetLimb.LinearVelocity * 100.0f;
|
velocity = limb.LinearVelocity * 100.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: use the blood emitter?
|
// TODO: use the blood emitter?
|
||||||
var blood = GameMain.ParticleManager.CreateParticle(
|
var blood = GameMain.ParticleManager.CreateParticle(
|
||||||
inWater ? Character.Params.BleedParticleWater : Character.Params.BleedParticleAir,
|
inWater ? Character.Params.BleedParticleWater : Character.Params.BleedParticleAir,
|
||||||
targetLimb.WorldPosition, velocity, 0.0f, Character.AnimController.CurrentHull);
|
limb.WorldPosition, velocity, 0.0f, Character.AnimController.CurrentHull);
|
||||||
|
|
||||||
if (blood != null && !inWater)
|
if (blood != null && !inWater)
|
||||||
{
|
{
|
||||||
@@ -954,7 +956,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void DrawHUD(SpriteBatch spriteBatch)
|
public void DrawHUD(SpriteBatch spriteBatch)
|
||||||
{
|
{
|
||||||
if (GUI.DisableHUD) { return; }
|
if (GUI.DisableHUD || Character.Removed) { return; }
|
||||||
if (GameMain.GraphicsWidth != screenResolution.X ||
|
if (GameMain.GraphicsWidth != screenResolution.X ||
|
||||||
GameMain.GraphicsHeight != screenResolution.Y ||
|
GameMain.GraphicsHeight != screenResolution.Y ||
|
||||||
Math.Abs(inventoryScale - Inventory.UIScale) > 0.01f ||
|
Math.Abs(inventoryScale - Inventory.UIScale) > 0.01f ||
|
||||||
@@ -996,13 +998,15 @@ namespace Barotrauma
|
|||||||
healthBar.RectTransform.ScreenSpaceOffset = healthBarShadow.RectTransform.ScreenSpaceOffset = Point.Zero;
|
healthBar.RectTransform.ScreenSpaceOffset = healthBarShadow.RectTransform.ScreenSpaceOffset = Point.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If manning a turret the portrait doesn't get rendered so we push the health bar to remove the empty gap
|
if (healthBarHolder != null)
|
||||||
healthBarHolder.RectTransform.ScreenSpaceOffset = Character.ShouldLockHud() ? new Point(0, HUDLayoutSettings.PortraitArea.Height) : Point.Zero;
|
{
|
||||||
|
// If manning a turret the portrait doesn't get rendered so we push the health bar to remove the empty gap
|
||||||
|
healthBarHolder.RectTransform.ScreenSpaceOffset = Character.ShouldLockHud() ? new Point(0, HUDLayoutSettings.PortraitArea.Height) : Point.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
DrawStatusHUD(spriteBatch);
|
DrawStatusHUD(spriteBatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private (Affliction affliction, string text)? highlightedAfflictionIcon;
|
private (Affliction affliction, string text)? highlightedAfflictionIcon;
|
||||||
public void DrawStatusHUD(SpriteBatch spriteBatch)
|
public void DrawStatusHUD(SpriteBatch spriteBatch)
|
||||||
{
|
{
|
||||||
@@ -1122,23 +1126,24 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Color GetAfflictionIconColor(AfflictionPrefab prefab, Affliction affliction)
|
public static Color GetAfflictionIconColor(AfflictionPrefab prefab, Affliction affliction)
|
||||||
|
{
|
||||||
|
return GetAfflictionIconColor(prefab, affliction.Strength);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Color GetAfflictionIconColor(AfflictionPrefab prefab, float afflictionStrength)
|
||||||
{
|
{
|
||||||
// No specific colors, use generic
|
// No specific colors, use generic
|
||||||
if (prefab.IconColors == null)
|
if (prefab.IconColors == null)
|
||||||
{
|
{
|
||||||
if (prefab.IsBuff)
|
if (prefab.IsBuff)
|
||||||
{
|
{
|
||||||
return ToolBox.GradientLerp(affliction.Strength / prefab.MaxStrength, GUI.Style.BuffColorLow, GUI.Style.BuffColorMedium, GUI.Style.BuffColorHigh);
|
return ToolBox.GradientLerp(afflictionStrength / prefab.MaxStrength, GUI.Style.BuffColorLow, GUI.Style.BuffColorMedium, GUI.Style.BuffColorHigh);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return ToolBox.GradientLerp(affliction.Strength / prefab.MaxStrength, GUI.Style.DebuffColorLow, GUI.Style.DebuffColorMedium, GUI.Style.DebuffColorHigh);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ToolBox.GradientLerp(afflictionStrength / prefab.MaxStrength, GUI.Style.DebuffColorLow, GUI.Style.DebuffColorMedium, GUI.Style.DebuffColorHigh);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
return ToolBox.GradientLerp(afflictionStrength / prefab.MaxStrength, prefab.IconColors);
|
||||||
return ToolBox.GradientLerp(affliction.Strength / prefab.MaxStrength, prefab.IconColors);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Color GetAfflictionIconColor(Affliction affliction) => GetAfflictionIconColor(affliction.Prefab, affliction);
|
public static Color GetAfflictionIconColor(Affliction affliction) => GetAfflictionIconColor(affliction.Prefab, affliction);
|
||||||
@@ -1153,7 +1158,7 @@ namespace Barotrauma
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (afflictionsDirty())
|
if (afflictionsDirty() || selectedLimb != currentDisplayedLimb)
|
||||||
{
|
{
|
||||||
var currentAfflictions = afflictions.Where(a => ShouldDisplayAfflictionOnLimb(a, selectedLimb)).Select(a => a.Key);
|
var currentAfflictions = afflictions.Where(a => ShouldDisplayAfflictionOnLimb(a, selectedLimb)).Select(a => a.Key);
|
||||||
CreateAfflictionInfos(currentAfflictions);
|
CreateAfflictionInfos(currentAfflictions);
|
||||||
@@ -2015,6 +2020,27 @@ namespace Barotrauma
|
|||||||
|
|
||||||
limbIndicatorOverlay?.Remove();
|
limbIndicatorOverlay?.Remove();
|
||||||
limbIndicatorOverlay = null;
|
limbIndicatorOverlay = null;
|
||||||
|
|
||||||
|
if (healthWindow != null)
|
||||||
|
{
|
||||||
|
healthWindow.RectTransform.Parent = null;
|
||||||
|
healthWindow = null;
|
||||||
|
}
|
||||||
|
if (healthBarHolder != null)
|
||||||
|
{
|
||||||
|
healthBarHolder.RectTransform.Parent = null;
|
||||||
|
healthBarHolder = null;
|
||||||
|
}
|
||||||
|
if (SuicideButton != null)
|
||||||
|
{
|
||||||
|
SuicideButton.RectTransform.Parent = null;
|
||||||
|
SuicideButton = null;
|
||||||
|
}
|
||||||
|
if (afflictionTooltip != null)
|
||||||
|
{
|
||||||
|
afflictionTooltip.RectTransform.Parent = null;
|
||||||
|
afflictionTooltip = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void Draw(SpriteBatch spriteBatch)
|
public void Draw(SpriteBatch spriteBatch)
|
||||||
{
|
{
|
||||||
// TODO: move this into the character editor
|
|
||||||
//var mouthPos = ragdoll.GetMouthPosition();
|
//var mouthPos = ragdoll.GetMouthPosition();
|
||||||
//if (mouthPos != null)
|
//if (mouthPos != null)
|
||||||
//{
|
//{
|
||||||
@@ -173,6 +172,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public float DefaultSpriteDepth { get; private set; }
|
public float DefaultSpriteDepth { get; private set; }
|
||||||
|
|
||||||
|
public WearableSprite HairWithHatSprite { get; set; }
|
||||||
public WearableSprite HuskSprite { get; private set; }
|
public WearableSprite HuskSprite { get; private set; }
|
||||||
public WearableSprite HerpesSprite { get; private set; }
|
public WearableSprite HerpesSprite { get; private set; }
|
||||||
|
|
||||||
@@ -236,8 +236,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public string HitSoundTag => Params?.Sound?.Tag;
|
public string HitSoundTag => Params?.Sound?.Tag;
|
||||||
|
|
||||||
private List<WearableSprite> wearableTypeHidingSprites = new List<WearableSprite>();
|
private readonly List<WearableSprite> wearableTypeHidingSprites = new List<WearableSprite>();
|
||||||
private List<WearableType> wearableTypesToHide = new List<WearableType>();
|
private readonly HashSet<WearableType> wearableTypesToHide = new HashSet<WearableType>();
|
||||||
private bool enableHuskSprite;
|
private bool enableHuskSprite;
|
||||||
public bool EnableHuskSprite
|
public bool EnableHuskSprite
|
||||||
{
|
{
|
||||||
@@ -895,7 +895,22 @@ namespace Barotrauma
|
|||||||
foreach (WearableSprite wearable in OtherWearables)
|
foreach (WearableSprite wearable in OtherWearables)
|
||||||
{
|
{
|
||||||
if (wearable.Type == WearableType.Husk) { continue; }
|
if (wearable.Type == WearableType.Husk) { continue; }
|
||||||
if (wearableTypesToHide.Contains(wearable.Type)) { continue; }
|
if (wearableTypesToHide.Contains(wearable.Type))
|
||||||
|
{
|
||||||
|
if (wearable.Type == WearableType.Hair)
|
||||||
|
{
|
||||||
|
if (HairWithHatSprite != null)
|
||||||
|
{
|
||||||
|
DrawWearable(HairWithHatSprite, depthStep, spriteBatch, blankColor, alpha: color.A / 255f, spriteEffect);
|
||||||
|
depthStep += step;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
DrawWearable(wearable, depthStep, spriteBatch, blankColor, alpha: color.A / 255f, spriteEffect);
|
DrawWearable(wearable, depthStep, spriteBatch, blankColor, alpha: color.A / 255f, spriteEffect);
|
||||||
//if there are multiple sprites on this limb, make the successive ones be drawn in front
|
//if there are multiple sprites on this limb, make the successive ones be drawn in front
|
||||||
depthStep += step;
|
depthStep += step;
|
||||||
@@ -1195,6 +1210,9 @@ namespace Barotrauma
|
|||||||
HuskSprite?.Sprite.Remove();
|
HuskSprite?.Sprite.Remove();
|
||||||
HuskSprite = null;
|
HuskSprite = null;
|
||||||
|
|
||||||
|
HairWithHatSprite?.Sprite.Remove();
|
||||||
|
HairWithHatSprite = null;
|
||||||
|
|
||||||
HerpesSprite?.Sprite.Remove();
|
HerpesSprite?.Sprite.Remove();
|
||||||
HerpesSprite = null;
|
HerpesSprite = null;
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void ClientExecute(string[] args)
|
public void ClientExecute(string[] args)
|
||||||
{
|
{
|
||||||
if (!CheatsEnabled && IsCheat)
|
bool allowCheats = GameMain.NetworkMember == null && (GameMain.GameSession?.GameMode is TestGameMode || Screen.Selected is EditorScreen);
|
||||||
|
if (!allowCheats && !CheatsEnabled && IsCheat)
|
||||||
{
|
{
|
||||||
NewMessage("You need to enable cheats using the command \"enablecheats\" before you can use the command \"" + names[0] + "\".", Color.Red);
|
NewMessage("You need to enable cheats using the command \"enablecheats\" before you can use the command \"" + names[0] + "\".", Color.Red);
|
||||||
#if USE_STEAM
|
#if USE_STEAM
|
||||||
@@ -743,7 +744,7 @@ namespace Barotrauma
|
|||||||
AssignOnExecute("explosion", (string[] args) =>
|
AssignOnExecute("explosion", (string[] args) =>
|
||||||
{
|
{
|
||||||
Vector2 explosionPos = GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition);
|
Vector2 explosionPos = GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition);
|
||||||
float range = 500, force = 10, damage = 50, structureDamage = 10, itemDamage = 100, empStrength = 0.0f, ballastFloraStrength = 50f;
|
float range = 500, force = 10, damage = 50, structureDamage = 20, itemDamage = 100, empStrength = 0.0f, ballastFloraStrength = 50f;
|
||||||
if (args.Length > 0) float.TryParse(args[0], out range);
|
if (args.Length > 0) float.TryParse(args[0], out range);
|
||||||
if (args.Length > 1) float.TryParse(args[1], out force);
|
if (args.Length > 1) float.TryParse(args[1], out force);
|
||||||
if (args.Length > 2) float.TryParse(args[2], out damage);
|
if (args.Length > 2) float.TryParse(args[2], out damage);
|
||||||
@@ -1120,7 +1121,7 @@ namespace Barotrauma
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Submarine.MainSub.SaveAs(Barotrauma.IO.Path.Combine(SubmarineInfo.SavePath, fileName + ".sub")))
|
if (Submarine.MainSub.TrySaveAs(Barotrauma.IO.Path.Combine(SubmarineInfo.SavePath, fileName + ".sub")))
|
||||||
{
|
{
|
||||||
NewMessage("Sub saved", Color.Green);
|
NewMessage("Sub saved", Color.Green);
|
||||||
}
|
}
|
||||||
@@ -1894,7 +1895,12 @@ namespace Barotrauma
|
|||||||
ThrowError($"\"{args[0]}\" is not a valid Level.PositionType. Available options are: {string.Join(", ", enums)}");
|
ThrowError($"\"{args[0]}\" is not a valid Level.PositionType. Available options are: {string.Join(", ", enums)}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
debugLines = EventSet.GetDebugStatistics(filter: monsterEvent => monsterEvent.SpawnPosType.HasFlag(spawnType));
|
bool fullLog = false;
|
||||||
|
if (args.Length > 1)
|
||||||
|
{
|
||||||
|
bool.TryParse(args[1], out fullLog);
|
||||||
|
}
|
||||||
|
debugLines = EventSet.GetDebugStatistics(filter: monsterEvent => monsterEvent.SpawnPosType.HasFlag(spawnType), fullLog: fullLog);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -2392,8 +2398,9 @@ namespace Barotrauma
|
|||||||
commands.Add(new Command("querylobbies", "Queries all SteamP2P lobbies", (args) =>
|
commands.Add(new Command("querylobbies", "Queries all SteamP2P lobbies", (args) =>
|
||||||
{
|
{
|
||||||
TaskPool.Add("DebugQueryLobbies",
|
TaskPool.Add("DebugQueryLobbies",
|
||||||
SteamManager.LobbyQueryRequest(), (t) => {
|
SteamManager.LobbyQueryRequest(), (t) =>
|
||||||
var lobbies = ((Task<List<Steamworks.Data.Lobby>>)t).Result;
|
{
|
||||||
|
t.TryGetResult(out List<Steamworks.Data.Lobby> lobbies);
|
||||||
foreach (var lobby in lobbies)
|
foreach (var lobby in lobbies)
|
||||||
{
|
{
|
||||||
NewMessage(lobby.GetData("name") + ", " + lobby.GetData("lobbyowner"), Color.Yellow);
|
NewMessage(lobby.GetData("name") + ", " + lobby.GetData("lobbyowner"), Color.Yellow);
|
||||||
@@ -2408,7 +2415,7 @@ namespace Barotrauma
|
|||||||
TextManager.CheckForDuplicates(args[0]);
|
TextManager.CheckForDuplicates(args[0]);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
commands.Add(new Command("writetocsv", "Writes the default language (English) to a .csv file.", (string[] args) =>
|
commands.Add(new Command("writetocsv|xmltocsv", "Writes the default language (English) to a .csv file.", (string[] args) =>
|
||||||
{
|
{
|
||||||
TextManager.WriteToCSV();
|
TextManager.WriteToCSV();
|
||||||
NPCConversation.WriteToCSV();
|
NPCConversation.WriteToCSV();
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Barotrauma.Extensions;
|
||||||
using Barotrauma.Networking;
|
using Barotrauma.Networking;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
@@ -20,6 +21,9 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool DisplayAsCompleted => State > 0 && requireRescue.None();
|
||||||
|
public override bool DisplayAsFailed => State == HostagesKilledState;
|
||||||
|
|
||||||
public override void ClientReadInitial(IReadMessage msg)
|
public override void ClientReadInitial(IReadMessage msg)
|
||||||
{
|
{
|
||||||
base.ClientReadInitial(msg);
|
base.ClientReadInitial(msg);
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
partial class AlienRuinMission : Mission
|
partial class AlienRuinMission : Mission
|
||||||
{
|
{
|
||||||
|
public override bool DisplayAsCompleted => State > 0;
|
||||||
|
public override bool DisplayAsFailed => false;
|
||||||
|
|
||||||
public override void ClientReadInitial(IReadMessage msg)
|
public override void ClientReadInitial(IReadMessage msg)
|
||||||
{
|
{
|
||||||
base.ClientReadInitial(msg);
|
base.ClientReadInitial(msg);
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Barotrauma
|
||||||
|
{
|
||||||
|
partial class BeaconMission : Mission
|
||||||
|
{
|
||||||
|
public override bool DisplayAsCompleted => State > 0;
|
||||||
|
public override bool DisplayAsFailed => false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
partial class CargoMission : Mission
|
partial class CargoMission : Mission
|
||||||
{
|
{
|
||||||
|
public override bool DisplayAsCompleted => false;
|
||||||
|
public override bool DisplayAsFailed => false;
|
||||||
|
|
||||||
public override string GetMissionRewardText(Submarine sub)
|
public override string GetMissionRewardText(Submarine sub)
|
||||||
{
|
{
|
||||||
string rewardText = TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", GetReward(sub)));
|
string rewardText = TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", GetReward(sub)));
|
||||||
|
|||||||
@@ -20,5 +20,8 @@ namespace Barotrauma
|
|||||||
return descriptions[GameMain.Client.Character.TeamID == CharacterTeamType.Team1 ? 1 : 2];
|
return descriptions[GameMain.Client.Character.TeamID == CharacterTeamType.Team1 ? 1 : 2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool DisplayAsCompleted => false;
|
||||||
|
public override bool DisplayAsFailed => false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
partial class EscortMission : Mission
|
partial class EscortMission : Mission
|
||||||
{
|
{
|
||||||
|
public override bool DisplayAsCompleted => false;
|
||||||
|
public override bool DisplayAsFailed => State == 1;
|
||||||
|
|
||||||
public override void ClientReadInitial(IReadMessage msg)
|
public override void ClientReadInitial(IReadMessage msg)
|
||||||
{
|
{
|
||||||
base.ClientReadInitial(msg);
|
base.ClientReadInitial(msg);
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Barotrauma
|
||||||
|
{
|
||||||
|
partial class GoToMission : Mission
|
||||||
|
{
|
||||||
|
public override bool DisplayAsCompleted => false;
|
||||||
|
public override bool DisplayAsFailed => false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,15 +1,14 @@
|
|||||||
using Barotrauma.Extensions;
|
using Barotrauma.Items.Components;
|
||||||
using Barotrauma.Items.Components;
|
|
||||||
using Barotrauma.Networking;
|
using Barotrauma.Networking;
|
||||||
using Microsoft.Xna.Framework;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
partial class MineralMission : Mission
|
partial class MineralMission : Mission
|
||||||
{
|
{
|
||||||
|
public override bool DisplayAsCompleted => false;
|
||||||
|
public override bool DisplayAsFailed => false;
|
||||||
|
|
||||||
public override void ClientReadInitial(IReadMessage msg)
|
public override void ClientReadInitial(IReadMessage msg)
|
||||||
{
|
{
|
||||||
base.ClientReadInitial(msg);
|
base.ClientReadInitial(msg);
|
||||||
|
|||||||
@@ -19,6 +19,15 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public virtual IEnumerable<Entity> HudIconTargets => Enumerable.Empty<Entity>();
|
public virtual IEnumerable<Entity> HudIconTargets => Enumerable.Empty<Entity>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is the mission at a state at which the only thing left to do is to reach the end of the level?
|
||||||
|
/// </summary>
|
||||||
|
public abstract bool DisplayAsCompleted { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Is the mission at a state at which the mission cannot be completed anymore?
|
||||||
|
/// </summary>
|
||||||
|
public abstract bool DisplayAsFailed { get; }
|
||||||
|
|
||||||
public Color GetDifficultyColor()
|
public Color GetDifficultyColor()
|
||||||
{
|
{
|
||||||
int v = Difficulty ?? MissionPrefab.MinDifficulty;
|
int v = Difficulty ?? MissionPrefab.MinDifficulty;
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
partial class MonsterMission : Mission
|
partial class MonsterMission : Mission
|
||||||
{
|
{
|
||||||
|
public override bool DisplayAsCompleted => State > 0;
|
||||||
|
public override bool DisplayAsFailed => false;
|
||||||
|
|
||||||
public override void ClientReadInitial(IReadMessage msg)
|
public override void ClientReadInitial(IReadMessage msg)
|
||||||
{
|
{
|
||||||
base.ClientReadInitial(msg);
|
base.ClientReadInitial(msg);
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
partial class NestMission : Mission
|
partial class NestMission : Mission
|
||||||
{
|
{
|
||||||
|
public override bool DisplayAsCompleted => State > 0 && !requireDelivery;
|
||||||
|
public override bool DisplayAsFailed => false;
|
||||||
|
|
||||||
public override void ClientReadInitial(IReadMessage msg)
|
public override void ClientReadInitial(IReadMessage msg)
|
||||||
{
|
{
|
||||||
base.ClientReadInitial(msg);
|
base.ClientReadInitial(msg);
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
partial class PirateMission : Mission
|
partial class PirateMission : Mission
|
||||||
{
|
{
|
||||||
|
public override bool DisplayAsCompleted => State > 1;
|
||||||
|
public override bool DisplayAsFailed => false;
|
||||||
|
|
||||||
public override void ClientReadInitial(IReadMessage msg)
|
public override void ClientReadInitial(IReadMessage msg)
|
||||||
{
|
{
|
||||||
base.ClientReadInitial(msg);
|
base.ClientReadInitial(msg);
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
partial class SalvageMission : Mission
|
partial class SalvageMission : Mission
|
||||||
{
|
{
|
||||||
|
public override bool DisplayAsCompleted => false;
|
||||||
|
public override bool DisplayAsFailed => false;
|
||||||
|
|
||||||
public override void ClientReadInitial(IReadMessage msg)
|
public override void ClientReadInitial(IReadMessage msg)
|
||||||
{
|
{
|
||||||
base.ClientReadInitial(msg);
|
base.ClientReadInitial(msg);
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Barotrauma.Networking;
|
using Barotrauma.Networking;
|
||||||
using Microsoft.Xna.Framework;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -23,6 +22,9 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool DisplayAsCompleted => false;
|
||||||
|
public override bool DisplayAsFailed => false;
|
||||||
|
|
||||||
public override void ClientReadInitial(IReadMessage msg)
|
public override void ClientReadInitial(IReadMessage msg)
|
||||||
{
|
{
|
||||||
base.ClientReadInitial(msg);
|
base.ClientReadInitial(msg);
|
||||||
@@ -60,7 +62,16 @@ namespace Barotrauma
|
|||||||
ushort id = msg.ReadUInt16();
|
ushort id = msg.ReadUInt16();
|
||||||
bool scanned = msg.ReadBoolean();
|
bool scanned = msg.ReadBoolean();
|
||||||
Entity entity = Entity.FindEntityByID(id);
|
Entity entity = Entity.FindEntityByID(id);
|
||||||
scanTargets.Add(entity as WayPoint, scanned);
|
if (!(entity is WayPoint wayPoint))
|
||||||
|
{
|
||||||
|
string errorMsg = $"Failed to find a waypoint in ScanMission.ClientReadScanTargetStatus. Entity {id} was {(entity?.ToString() ?? null)}";
|
||||||
|
DebugConsole.ThrowError(errorMsg);
|
||||||
|
GameAnalyticsManager.AddErrorEventOnce("ScanMission.ClientReadScanTargetStatus", GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scanTargets.Add(wayPoint, scanned);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
using Microsoft.Xna.Framework;
|
using Barotrauma.Extensions;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using SharpFont;
|
using SharpFont;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
@@ -130,7 +132,7 @@ namespace Barotrauma
|
|||||||
/// <param name="charRanges">Character ranges between each even element with their corresponding odd element. Default is 0x20 to 0xFFFF.</param>
|
/// <param name="charRanges">Character ranges between each even element with their corresponding odd element. Default is 0x20 to 0xFFFF.</param>
|
||||||
/// <param name="texDims">Texture dimensions. Default is 512x512.</param>
|
/// <param name="texDims">Texture dimensions. Default is 512x512.</param>
|
||||||
/// <param name="baseChar">Base character used to shift all other characters downwards when rendering. Defaults to T.</param>
|
/// <param name="baseChar">Base character used to shift all other characters downwards when rendering. Defaults to T.</param>
|
||||||
public void RenderAtlas(GraphicsDevice gd, uint[] charRanges = null, int texDims = 1024, uint baseChar = 0x54)
|
private void RenderAtlas(GraphicsDevice gd, uint[] charRanges = null, int texDims = 1024, uint baseChar = 0x54)
|
||||||
{
|
{
|
||||||
if (DynamicLoading) { return; }
|
if (DynamicLoading) { return; }
|
||||||
|
|
||||||
@@ -253,13 +255,19 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DynamicRenderAtlas(GraphicsDevice gd, uint character, int texDims = 1024, uint baseChar = 0x54)
|
private void DynamicRenderAtlas(GraphicsDevice gd, uint character, int texDims = 1024, uint baseChar = 0x54)
|
||||||
|
=> DynamicRenderAtlas(gd, character.ToEnumerable(), texDims, baseChar);
|
||||||
|
|
||||||
|
private void DynamicRenderAtlas(GraphicsDevice gd, string str, int texDims = 1024, uint baseChar = 0x54)
|
||||||
|
=> DynamicRenderAtlas(gd, str.Distinct().Select(c => (uint)c), texDims, baseChar);
|
||||||
|
|
||||||
|
private void DynamicRenderAtlas(GraphicsDevice gd, IEnumerable<uint> characters, int texDims = 1024, uint baseChar = 0x54)
|
||||||
{
|
{
|
||||||
if (System.Threading.Thread.CurrentThread != GameMain.MainThread)
|
if (System.Threading.Thread.CurrentThread != GameMain.MainThread)
|
||||||
{
|
{
|
||||||
CrossThread.RequestExecutionOnMainThread(() =>
|
CrossThread.RequestExecutionOnMainThread(() =>
|
||||||
{
|
{
|
||||||
DynamicRenderAtlas(gd, character, texDims, baseChar);
|
DynamicRenderAtlas(gd, characters, texDims, baseChar);
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -271,7 +279,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
lock (mutex)
|
lock (mutex)
|
||||||
{
|
{
|
||||||
if (texCoords.ContainsKey(character)) { return; }
|
|
||||||
if (textures.Count == 0)
|
if (textures.Count == 0)
|
||||||
{
|
{
|
||||||
this.texDims = texDims;
|
this.texDims = texDims;
|
||||||
@@ -282,79 +289,90 @@ namespace Barotrauma
|
|||||||
textures.Add(new Texture2D(gd, texDims, texDims, false, SurfaceFormat.Color));
|
textures.Add(new Texture2D(gd, texDims, texDims, false, SurfaceFormat.Color));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint glyphIndex = face.GetCharIndex(character);
|
bool anyChanges = false;
|
||||||
if (glyphIndex == 0) { return; }
|
bool firstChar = true;
|
||||||
|
foreach (var character in characters)
|
||||||
face.SetPixelSizes(0, size);
|
|
||||||
face.LoadGlyph(glyphIndex, LoadFlags.Default, LoadTarget.Normal);
|
|
||||||
if (face.Glyph.Metrics.Width == 0 || face.Glyph.Metrics.Height == 0)
|
|
||||||
{
|
{
|
||||||
if (face.Glyph.Metrics.HorizontalAdvance > 0)
|
if (texCoords.ContainsKey(character)) { continue; }
|
||||||
|
|
||||||
|
uint glyphIndex = face.GetCharIndex(character);
|
||||||
|
if (glyphIndex == 0) { continue; }
|
||||||
|
|
||||||
|
face.SetPixelSizes(0, size);
|
||||||
|
face.LoadGlyph(glyphIndex, LoadFlags.Default, LoadTarget.Normal);
|
||||||
|
if (face.Glyph.Metrics.Width == 0 || face.Glyph.Metrics.Height == 0)
|
||||||
{
|
{
|
||||||
//glyph is empty, but char still applies advance
|
if (face.Glyph.Metrics.HorizontalAdvance > 0)
|
||||||
GlyphData blankData = new GlyphData(
|
{
|
||||||
advance: (float)face.Glyph.Metrics.HorizontalAdvance,
|
//glyph is empty, but char still applies advance
|
||||||
texIndex: -1); //indicates no texture because the glyph is empty
|
GlyphData blankData = new GlyphData(
|
||||||
texCoords.Add(character, blankData);
|
advance: (float)face.Glyph.Metrics.HorizontalAdvance,
|
||||||
|
texIndex: -1); //indicates no texture because the glyph is empty
|
||||||
|
texCoords.Add(character, blankData);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//stacktrace doesn't really work that well when RenderGlyph throws an exception
|
//stacktrace doesn't really work that well when RenderGlyph throws an exception
|
||||||
face.Glyph.RenderGlyph(RenderMode.Normal);
|
face.Glyph.RenderGlyph(RenderMode.Normal);
|
||||||
bitmap = (byte[])face.Glyph.Bitmap.BufferData.Clone();
|
bitmap = (byte[])face.Glyph.Bitmap.BufferData.Clone();
|
||||||
glyphWidth = face.Glyph.Bitmap.Width;
|
glyphWidth = face.Glyph.Bitmap.Width;
|
||||||
glyphHeight = bitmap.Length / glyphWidth;
|
glyphHeight = bitmap.Length / glyphWidth;
|
||||||
horizontalAdvance = face.Glyph.Metrics.HorizontalAdvance;
|
horizontalAdvance = face.Glyph.Metrics.HorizontalAdvance;
|
||||||
drawOffset = new Vector2(face.Glyph.BitmapLeft, baseHeight * 14 / 10 - face.Glyph.BitmapTop);
|
drawOffset = new Vector2(face.Glyph.BitmapLeft, baseHeight * 14 / 10 - face.Glyph.BitmapTop);
|
||||||
|
|
||||||
if (glyphWidth > texDims - 1 || glyphHeight > texDims - 1)
|
if (glyphWidth > texDims - 1 || glyphHeight > texDims - 1)
|
||||||
{
|
|
||||||
throw new Exception(filename + ", " + size.ToString() + ", " + (char)character + "; Glyph dimensions exceed texture atlas dimensions");
|
|
||||||
}
|
|
||||||
|
|
||||||
currentDynamicAtlasNextY = Math.Max(currentDynamicAtlasNextY, glyphHeight + 2);
|
|
||||||
if (currentDynamicAtlasCoords.X + glyphWidth + 2 > texDims - 1)
|
|
||||||
{
|
|
||||||
currentDynamicAtlasCoords.X = 0;
|
|
||||||
currentDynamicAtlasCoords.Y += currentDynamicAtlasNextY;
|
|
||||||
currentDynamicAtlasNextY = 0;
|
|
||||||
}
|
|
||||||
//no more room in current texture atlas, create a new one
|
|
||||||
if (currentDynamicAtlasCoords.Y + glyphHeight + 2 > texDims - 1)
|
|
||||||
{
|
|
||||||
currentDynamicAtlasCoords.X = 0;
|
|
||||||
currentDynamicAtlasCoords.Y = 0;
|
|
||||||
currentDynamicAtlasNextY = 0;
|
|
||||||
textures.Add(new Texture2D(gd, texDims, texDims, false, SurfaceFormat.Color));
|
|
||||||
currentDynamicPixelBuffer = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
GlyphData newData = new GlyphData(
|
|
||||||
advance: (float)horizontalAdvance,
|
|
||||||
texIndex: textures.Count - 1,
|
|
||||||
texCoords: new Rectangle((int)currentDynamicAtlasCoords.X, (int)currentDynamicAtlasCoords.Y, glyphWidth, glyphHeight),
|
|
||||||
drawOffset: drawOffset
|
|
||||||
);
|
|
||||||
texCoords.Add(character, newData);
|
|
||||||
|
|
||||||
if (currentDynamicPixelBuffer == null)
|
|
||||||
{
|
|
||||||
currentDynamicPixelBuffer = new uint[texDims * texDims];
|
|
||||||
textures[newData.TexIndex].GetData<uint>(currentDynamicPixelBuffer, 0, texDims * texDims);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int y = 0; y < glyphHeight; y++)
|
|
||||||
{
|
|
||||||
for (int x = 0; x < glyphWidth; x++)
|
|
||||||
{
|
{
|
||||||
byte byteColor = bitmap[x + y * glyphWidth];
|
throw new Exception(filename + ", " + size.ToString() + ", " + (char)character + "; Glyph dimensions exceed texture atlas dimensions");
|
||||||
currentDynamicPixelBuffer[((int)currentDynamicAtlasCoords.X + x) + ((int)currentDynamicAtlasCoords.Y + y) * texDims] = (uint)(byteColor << 24 | 0x00ffffff);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
textures[newData.TexIndex].SetData<uint>(currentDynamicPixelBuffer);
|
|
||||||
|
|
||||||
currentDynamicAtlasCoords.X += glyphWidth + 2;
|
currentDynamicAtlasNextY = Math.Max(currentDynamicAtlasNextY, glyphHeight + 2);
|
||||||
|
if (currentDynamicAtlasCoords.X + glyphWidth + 2 > texDims - 1)
|
||||||
|
{
|
||||||
|
currentDynamicAtlasCoords.X = 0;
|
||||||
|
currentDynamicAtlasCoords.Y += currentDynamicAtlasNextY;
|
||||||
|
currentDynamicAtlasNextY = 0;
|
||||||
|
}
|
||||||
|
//no more room in current texture atlas, create a new one
|
||||||
|
if (currentDynamicAtlasCoords.Y + glyphHeight + 2 > texDims - 1)
|
||||||
|
{
|
||||||
|
if (!firstChar) { textures[^1].SetData<uint>(currentDynamicPixelBuffer); }
|
||||||
|
currentDynamicAtlasCoords.X = 0;
|
||||||
|
currentDynamicAtlasCoords.Y = 0;
|
||||||
|
currentDynamicAtlasNextY = 0;
|
||||||
|
textures.Add(new Texture2D(gd, texDims, texDims, false, SurfaceFormat.Color));
|
||||||
|
currentDynamicPixelBuffer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
GlyphData newData = new GlyphData(
|
||||||
|
advance: (float)horizontalAdvance,
|
||||||
|
texIndex: textures.Count - 1,
|
||||||
|
texCoords: new Rectangle((int)currentDynamicAtlasCoords.X, (int)currentDynamicAtlasCoords.Y, glyphWidth, glyphHeight),
|
||||||
|
drawOffset: drawOffset
|
||||||
|
);
|
||||||
|
texCoords.Add(character, newData);
|
||||||
|
|
||||||
|
if (currentDynamicPixelBuffer == null)
|
||||||
|
{
|
||||||
|
currentDynamicPixelBuffer = new uint[texDims * texDims];
|
||||||
|
textures[newData.TexIndex].GetData<uint>(currentDynamicPixelBuffer, 0, texDims * texDims);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int y = 0; y < glyphHeight; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < glyphWidth; x++)
|
||||||
|
{
|
||||||
|
byte byteColor = bitmap[x + y * glyphWidth];
|
||||||
|
currentDynamicPixelBuffer[((int)currentDynamicAtlasCoords.X + x) + ((int)currentDynamicAtlasCoords.Y + y) * texDims] = (uint)(byteColor << 24 | 0x00ffffff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
currentDynamicAtlasCoords.X += glyphWidth + 2;
|
||||||
|
firstChar = false;
|
||||||
|
anyChanges = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (anyChanges) { textures[^1].SetData<uint>(currentDynamicPixelBuffer); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,6 +392,10 @@ namespace Barotrauma
|
|||||||
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)
|
||||||
{
|
{
|
||||||
if (textures.Count == 0 && !DynamicLoading) { return; }
|
if (textures.Count == 0 && !DynamicLoading) { return; }
|
||||||
|
if (DynamicLoading)
|
||||||
|
{
|
||||||
|
DynamicRenderAtlas(graphicsDevice, text);
|
||||||
|
}
|
||||||
|
|
||||||
int lineNum = 0;
|
int lineNum = 0;
|
||||||
Vector2 currentPos = position;
|
Vector2 currentPos = position;
|
||||||
@@ -390,10 +412,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint charIndex = text[i];
|
uint charIndex = text[i];
|
||||||
if (DynamicLoading)
|
|
||||||
{
|
|
||||||
DynamicRenderAtlas(graphicsDevice, charIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
GlyphData gd = GetGlyphData(charIndex);
|
GlyphData gd = GetGlyphData(charIndex);
|
||||||
if (gd.TexIndex >= 0)
|
if (gd.TexIndex >= 0)
|
||||||
@@ -417,6 +435,10 @@ namespace Barotrauma
|
|||||||
public void DrawString(SpriteBatch sb, string text, Vector2 position, Color color)
|
public void DrawString(SpriteBatch sb, string text, Vector2 position, Color color)
|
||||||
{
|
{
|
||||||
if (textures.Count == 0 && !DynamicLoading) { return; }
|
if (textures.Count == 0 && !DynamicLoading) { return; }
|
||||||
|
if (DynamicLoading)
|
||||||
|
{
|
||||||
|
DynamicRenderAtlas(graphicsDevice, text);
|
||||||
|
}
|
||||||
|
|
||||||
Vector2 currentPos = position;
|
Vector2 currentPos = position;
|
||||||
for (int i = 0; i < text.Length; i++)
|
for (int i = 0; i < text.Length; i++)
|
||||||
@@ -429,10 +451,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint charIndex = text[i];
|
uint charIndex = text[i];
|
||||||
if (DynamicLoading)
|
|
||||||
{
|
|
||||||
DynamicRenderAtlas(graphicsDevice, charIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
GlyphData gd = GetGlyphData(charIndex);
|
GlyphData gd = GetGlyphData(charIndex);
|
||||||
if (gd.TexIndex >= 0)
|
if (gd.TexIndex >= 0)
|
||||||
@@ -452,6 +470,10 @@ namespace Barotrauma
|
|||||||
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, List<RichTextData> richTextData, int rtdOffset = 0)
|
||||||
{
|
{
|
||||||
if (textures.Count == 0 && !DynamicLoading) { return; }
|
if (textures.Count == 0 && !DynamicLoading) { return; }
|
||||||
|
if (DynamicLoading)
|
||||||
|
{
|
||||||
|
DynamicRenderAtlas(graphicsDevice, text);
|
||||||
|
}
|
||||||
|
|
||||||
int lineNum = 0;
|
int lineNum = 0;
|
||||||
Vector2 currentPos = position;
|
Vector2 currentPos = position;
|
||||||
@@ -472,10 +494,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint charIndex = text[i];
|
uint charIndex = text[i];
|
||||||
if (DynamicLoading && !texCoords.ContainsKey(charIndex))
|
|
||||||
{
|
|
||||||
DynamicRenderAtlas(graphicsDevice, charIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
Color currentTextColor;
|
Color currentTextColor;
|
||||||
|
|
||||||
@@ -626,6 +644,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
retVal.Y = baseHeight;
|
retVal.Y = baseHeight;
|
||||||
}
|
}
|
||||||
|
if (DynamicLoading)
|
||||||
|
{
|
||||||
|
DynamicRenderAtlas(graphicsDevice, text);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < text.Length; i++)
|
for (int i = 0; i < text.Length; i++)
|
||||||
{
|
{
|
||||||
@@ -636,10 +658,6 @@ namespace Barotrauma
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
uint charIndex = text[i];
|
uint charIndex = text[i];
|
||||||
if (DynamicLoading && !texCoords.ContainsKey(charIndex))
|
|
||||||
{
|
|
||||||
DynamicRenderAtlas(graphicsDevice, charIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
GlyphData gd = GetGlyphData(charIndex);
|
GlyphData gd = GetGlyphData(charIndex);
|
||||||
currentLineX += gd.Advance;
|
currentLineX += gd.Advance;
|
||||||
|
|||||||
@@ -389,6 +389,12 @@ namespace Barotrauma
|
|||||||
DrawString(spriteBatch, new Vector2(10, 10),
|
DrawString(spriteBatch, new Vector2(10, 10),
|
||||||
"FPS: " + Math.Round(GameMain.PerformanceCounter.AverageFramesPerSecond),
|
"FPS: " + Math.Round(GameMain.PerformanceCounter.AverageFramesPerSecond),
|
||||||
Color.White, Color.Black * 0.5f, 0, SmallFont);
|
Color.White, Color.Black * 0.5f, 0, SmallFont);
|
||||||
|
if (GameMain.GameSession != null && Timing.TotalTime > GameMain.GameSession.RoundStartTime + 1.0)
|
||||||
|
{
|
||||||
|
DrawString(spriteBatch, new Vector2(10, 25),
|
||||||
|
$"Physics: {GameMain.CurrentUpdateRate}",
|
||||||
|
(GameMain.CurrentUpdateRate < Timing.FixedUpdateRate) ? Color.Red : Color.White, Color.Black * 0.5f, 0, SmallFont);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GameMain.ShowPerf)
|
if (GameMain.ShowPerf)
|
||||||
@@ -397,7 +403,7 @@ namespace Barotrauma
|
|||||||
DrawString(spriteBatch, new Vector2(300, y),
|
DrawString(spriteBatch, new Vector2(300, y),
|
||||||
"Draw - Avg: " + GameMain.PerformanceCounter.DrawTimeGraph.Average().ToString("0.00") + " ms" +
|
"Draw - Avg: " + GameMain.PerformanceCounter.DrawTimeGraph.Average().ToString("0.00") + " ms" +
|
||||||
" Max: " + GameMain.PerformanceCounter.DrawTimeGraph.LargestValue().ToString("0.00") + " ms",
|
" Max: " + GameMain.PerformanceCounter.DrawTimeGraph.LargestValue().ToString("0.00") + " ms",
|
||||||
GUI.Style.Green, Color.Black * 0.8f, font: SmallFont);
|
Style.Green, Color.Black * 0.8f, font: SmallFont);
|
||||||
y += 15;
|
y += 15;
|
||||||
GameMain.PerformanceCounter.DrawTimeGraph.Draw(spriteBatch, new Rectangle(300, y, 170, 50), color: Style.Green);
|
GameMain.PerformanceCounter.DrawTimeGraph.Draw(spriteBatch, new Rectangle(300, y, 170, 50), color: Style.Green);
|
||||||
y += 50;
|
y += 50;
|
||||||
@@ -408,7 +414,6 @@ namespace Barotrauma
|
|||||||
Color.LightBlue, Color.Black * 0.8f, font: SmallFont);
|
Color.LightBlue, Color.Black * 0.8f, font: SmallFont);
|
||||||
y += 15;
|
y += 15;
|
||||||
GameMain.PerformanceCounter.UpdateTimeGraph.Draw(spriteBatch, new Rectangle(300, y, 170, 50), color: Color.LightBlue);
|
GameMain.PerformanceCounter.UpdateTimeGraph.Draw(spriteBatch, new Rectangle(300, y, 170, 50), color: Color.LightBlue);
|
||||||
GameMain.PerformanceCounter.UpdateIterationsGraph.Draw(spriteBatch, new Rectangle(300, y, 170, 50), maxValue: 20, color: Style.Red);
|
|
||||||
y += 50;
|
y += 50;
|
||||||
foreach (string key in GameMain.PerformanceCounter.GetSavedIdentifiers)
|
foreach (string key in GameMain.PerformanceCounter.GetSavedIdentifiers)
|
||||||
{
|
{
|
||||||
@@ -431,7 +436,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GameMain.DebugDraw)
|
if (GameMain.DebugDraw && !Submarine.Unloading && !(Screen.Selected is RoundSummaryScreen))
|
||||||
{
|
{
|
||||||
DrawString(spriteBatch, new Vector2(10, 25),
|
DrawString(spriteBatch, new Vector2(10, 25),
|
||||||
"Physics: " + GameMain.World.UpdateTime,
|
"Physics: " + GameMain.World.UpdateTime,
|
||||||
@@ -1247,7 +1252,10 @@ namespace Barotrauma
|
|||||||
RefreshUpdateList();
|
RefreshUpdateList();
|
||||||
UpdateMouseOn();
|
UpdateMouseOn();
|
||||||
Debug.Assert(updateList.Count == updateListSet.Count);
|
Debug.Assert(updateList.Count == updateListSet.Count);
|
||||||
updateList.ForEach(c => c.UpdateAuto(deltaTime));
|
foreach (var c in updateList)
|
||||||
|
{
|
||||||
|
c.UpdateAuto(deltaTime);
|
||||||
|
}
|
||||||
UpdateMessages(deltaTime);
|
UpdateMessages(deltaTime);
|
||||||
UpdateSavingIndicator(deltaTime);
|
UpdateSavingIndicator(deltaTime);
|
||||||
}
|
}
|
||||||
@@ -1291,7 +1299,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
messages.RemoveAll(m => m.Timer <= 0.0f);
|
messages.RemoveAll(m => m.Timer <= 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void UpdateSavingIndicator(float deltaTime)
|
private static void UpdateSavingIndicator(float deltaTime)
|
||||||
@@ -1349,7 +1356,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
#region Element drawing
|
#region Element drawing
|
||||||
|
|
||||||
private static List<float> usedIndicatorAngles = new List<float>();
|
private static readonly List<float> usedIndicatorAngles = new List<float>();
|
||||||
|
|
||||||
/// <param name="createOffset">Should the indicator move based on the camera position?</param>
|
/// <param name="createOffset">Should the indicator move based on the camera position?</param>
|
||||||
/// <param name="overrideAlpha">Override the distance-based alpha value with the specified alpha value</param>
|
/// <param name="overrideAlpha">Override the distance-based alpha value with the specified alpha value</param>
|
||||||
@@ -1628,7 +1635,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private static void DrawMessages(SpriteBatch spriteBatch, Camera cam)
|
private static void DrawMessages(SpriteBatch spriteBatch, Camera cam)
|
||||||
{
|
{
|
||||||
if (messages.Count == 0) return;
|
if (messages.Count == 0) { return; }
|
||||||
|
|
||||||
bool useScissorRect = messages.Any(m => !m.WorldSpace);
|
bool useScissorRect = messages.Any(m => !m.WorldSpace);
|
||||||
Rectangle prevScissorRect = spriteBatch.GraphicsDevice.ScissorRectangle;
|
Rectangle prevScissorRect = spriteBatch.GraphicsDevice.ScissorRectangle;
|
||||||
@@ -2028,6 +2035,16 @@ namespace Barotrauma
|
|||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void NotifyPrompt(string header, string body)
|
||||||
|
{
|
||||||
|
GUIMessageBox msgBox = new GUIMessageBox(header, body, new[] { TextManager.Get("Ok") }, new Vector2(0.2f, 0.175f), minSize: new Point(300, 175));
|
||||||
|
msgBox.Buttons[0].OnClicked = delegate
|
||||||
|
{
|
||||||
|
msgBox.Close();
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public static GUIMessageBox AskForConfirmation(string header, string body, Action onConfirm, Action onDeny = null)
|
public static GUIMessageBox AskForConfirmation(string header, string body, Action onConfirm, Action onDeny = null)
|
||||||
{
|
{
|
||||||
string[] buttons = { TextManager.Get("Ok"), TextManager.Get("Cancel") };
|
string[] buttons = { TextManager.Get("Ok"), TextManager.Get("Cancel") };
|
||||||
@@ -2051,6 +2068,32 @@ namespace Barotrauma
|
|||||||
return msgBox;
|
return msgBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static GUIMessageBox PromptTextInput(string header, string body, Action<string> onConfirm)
|
||||||
|
{
|
||||||
|
string[] buttons = { TextManager.Get("Ok"), TextManager.Get("Cancel") };
|
||||||
|
GUIMessageBox msgBox = new GUIMessageBox(header, string.Empty, buttons, new Vector2(0.2f, 0.175f), minSize: new Point(300, 175));
|
||||||
|
GUITextBox textBox = new GUITextBox(new RectTransform(Vector2.One, msgBox.Content.RectTransform), text: body)
|
||||||
|
{
|
||||||
|
OverflowClip = true
|
||||||
|
};
|
||||||
|
|
||||||
|
// Cancel button
|
||||||
|
msgBox.Buttons[1].OnClicked = delegate
|
||||||
|
{
|
||||||
|
msgBox.Close();
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Ok button
|
||||||
|
msgBox.Buttons[0].OnClicked = delegate
|
||||||
|
{
|
||||||
|
onConfirm.Invoke(textBox.Text);
|
||||||
|
msgBox.Close();
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
return msgBox;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Element positioning
|
#region Element positioning
|
||||||
@@ -2397,6 +2440,11 @@ namespace Barotrauma
|
|||||||
private static bool TogglePauseMenu(GUIButton button, object obj)
|
private static bool TogglePauseMenu(GUIButton button, object obj)
|
||||||
{
|
{
|
||||||
pauseMenuOpen = !pauseMenuOpen;
|
pauseMenuOpen = !pauseMenuOpen;
|
||||||
|
if (!pauseMenuOpen && PauseMenu != null)
|
||||||
|
{
|
||||||
|
PauseMenu.RectTransform.Parent = null;
|
||||||
|
PauseMenu = null;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2448,7 +2496,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public static void ClearMessages()
|
public static void ClearMessages()
|
||||||
{
|
{
|
||||||
messages.Clear();
|
lock (mutex)
|
||||||
|
{
|
||||||
|
messages.Clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsFourByThree()
|
public static bool IsFourByThree()
|
||||||
|
|||||||
@@ -219,12 +219,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
GUI.Style.ButtonPulse.Draw(spriteBatch, expandRect, ToolBox.GradientLerp(pulseExpand, Color.White, Color.White, Color.Transparent));
|
GUI.Style.ButtonPulse.Draw(spriteBatch, expandRect, ToolBox.GradientLerp(pulseExpand, Color.White, Color.White, Color.Transparent));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UserData is string s && s == "ReadyCheckButton" && ReadyCheck.lastReadyCheck > DateTime.Now)
|
|
||||||
{
|
|
||||||
float progress = (ReadyCheck.lastReadyCheck - DateTime.Now).Seconds / 60.0f;
|
|
||||||
Frame.Color = ToolBox.GradientLerp(progress, Color.White, GUI.Style.Red);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Update(float deltaTime)
|
protected override void Update(float deltaTime)
|
||||||
|
|||||||
@@ -22,13 +22,14 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
GameMain.Instance.ResolutionChanged += RecalculateSize;
|
GameMain.Instance.ResolutionChanged += RecalculateSize;
|
||||||
}
|
}
|
||||||
_instance.ItemComponentHolder = new GUIFrame(new RectTransform(Vector2.One, _instance, Anchor.Center)).RectTransform;
|
_instance.ChildrenChanged += OnChildrenChanged;
|
||||||
}
|
}
|
||||||
return _instance;
|
return _instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public RectTransform ItemComponentHolder;
|
//GUICanvas stores the children as weak references, to allow elements that we no longer need to get garbage collected
|
||||||
|
private readonly List<WeakReference<RectTransform>> childrenWeakRef = new List<WeakReference<RectTransform>>();
|
||||||
|
|
||||||
private static Vector2 size => new Vector2(GameMain.GraphicsWidth / (float)GUI.UIWidth, 1f);
|
private static Vector2 size => new Vector2(GameMain.GraphicsWidth / (float)GUI.UIWidth, 1f);
|
||||||
|
|
||||||
@@ -36,16 +37,41 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private enum ResizeAxis { Both = 0, X = 1, Y = 2 }
|
private enum ResizeAxis { Both = 0, X = 1, Y = 2 }
|
||||||
|
|
||||||
|
private static void OnChildrenChanged(RectTransform _)
|
||||||
|
{
|
||||||
|
//add weak reference if we don't have one yet
|
||||||
|
foreach (var child in _instance.Children)
|
||||||
|
{
|
||||||
|
if (!_instance.childrenWeakRef.Any(c => c.TryGetTarget(out var existingChild) && existingChild == child))
|
||||||
|
{
|
||||||
|
_instance.childrenWeakRef.Add(new WeakReference<RectTransform>(child));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//get rid of strong references
|
||||||
|
_instance.children.Clear();
|
||||||
|
//remove dead children
|
||||||
|
for (int i = _instance.childrenWeakRef.Count - 2; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (!_instance.childrenWeakRef[i].TryGetTarget(out var child) || child.Parent != _instance)
|
||||||
|
{
|
||||||
|
_instance.childrenWeakRef.RemoveAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Turn public, if there is a need to call this manually.
|
// Turn public, if there is a need to call this manually.
|
||||||
private static void RecalculateSize()
|
private static void RecalculateSize()
|
||||||
{
|
{
|
||||||
Vector2 recalculatedSize = size;
|
Vector2 recalculatedSize = size;
|
||||||
|
|
||||||
// Scale children that are supposed to encompass the whole screen so that they are properly scaled on ultrawide as well
|
// Scale children that are supposed to encompass the whole screen so that they are properly scaled on ultrawide as well
|
||||||
for (int i = 0; i < Instance.Children.Count(); i++)
|
for (int i = 0; i < Instance.childrenWeakRef.Count; i++)
|
||||||
{
|
{
|
||||||
RectTransform target = Instance.GetChild(i);
|
if (!_instance.childrenWeakRef[i].TryGetTarget(out RectTransform target) || target == null) { continue; };
|
||||||
if (target == null || target.RelativeSize.X < 1 && target.RelativeSize.Y < 1) continue;
|
|
||||||
|
_instance.children.Add(target);
|
||||||
|
|
||||||
|
if (target.RelativeSize.X < 1 && target.RelativeSize.Y < 1) { continue; }
|
||||||
|
|
||||||
ResizeAxis axis;
|
ResizeAxis axis;
|
||||||
|
|
||||||
@@ -80,6 +106,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
Instance.Resize(size, resizeChildren: true);
|
Instance.Resize(size, resizeChildren: true);
|
||||||
Instance.GetAllChildren().Select(c => c.GUIComponent as GUITextBlock).ForEach(t => t?.SetTextPos());
|
Instance.GetAllChildren().Select(c => c.GUIComponent as GUITextBlock).ForEach(t => t?.SetTextPos());
|
||||||
|
_instance.children.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -317,7 +317,10 @@ namespace Barotrauma
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
selected = value;
|
selected = value;
|
||||||
Children.ForEach(c => c.Selected = value);
|
foreach (var child in Children)
|
||||||
|
{
|
||||||
|
child.Selected = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public virtual ComponentState State
|
public virtual ComponentState State
|
||||||
@@ -537,7 +540,10 @@ namespace Barotrauma
|
|||||||
//would be real nice to un-jank this some day
|
//would be real nice to un-jank this some day
|
||||||
ForceUpdate();
|
ForceUpdate();
|
||||||
ForceUpdate();
|
ForceUpdate();
|
||||||
foreach (var child in Children) { child.ForceLayoutRecalculation(); }
|
foreach (var child in Children)
|
||||||
|
{
|
||||||
|
child.ForceLayoutRecalculation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ForceUpdate() => Update((float)Timing.Step);
|
public void ForceUpdate() => Update((float)Timing.Step);
|
||||||
@@ -547,7 +553,10 @@ namespace Barotrauma
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void UpdateChildren(float deltaTime, bool recursive)
|
public void UpdateChildren(float deltaTime, bool recursive)
|
||||||
{
|
{
|
||||||
RectTransform.Children.ForEach(c => c.GUIComponent.UpdateManually(deltaTime, recursive, recursive));
|
foreach (var child in RectTransform.Children)
|
||||||
|
{
|
||||||
|
child.GUIComponent.UpdateManually(deltaTime, recursive, recursive);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -583,7 +592,10 @@ namespace Barotrauma
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual void DrawChildren(SpriteBatch spriteBatch, bool recursive)
|
public virtual void DrawChildren(SpriteBatch spriteBatch, bool recursive)
|
||||||
{
|
{
|
||||||
RectTransform.Children.ForEach(c => c.GUIComponent.DrawManually(spriteBatch, recursive, recursive));
|
foreach (RectTransform child in RectTransform.Children)
|
||||||
|
{
|
||||||
|
child.GUIComponent.DrawManually(spriteBatch, recursive, recursive);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Color _currentColor;
|
protected Color _currentColor;
|
||||||
@@ -764,8 +776,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
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), richTextData, toolTip, font: GUI.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)(toolTipBlock.Font.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)(toolTipBlock.Font.MeasureString(toolTipBlock.WrappedText).Y + padding.Y + toolTipBlock.Padding.Y + toolTipBlock.Padding.W));
|
||||||
toolTipBlock.userData = toolTip;
|
toolTipBlock.userData = toolTip;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1007,8 +1019,10 @@ namespace Barotrauma
|
|||||||
case "gridtext":
|
case "gridtext":
|
||||||
LoadGridText(element, parent);
|
LoadGridText(element, parent);
|
||||||
return null;
|
return null;
|
||||||
|
case "conditional":
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new NotImplementedException("Loading GUI component \""+element.Name+"\" from XML is not implemented.");
|
throw new NotImplementedException("Loading GUI component \"" + element.Name + "\" from XML is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (component != null)
|
if (component != null)
|
||||||
@@ -1079,6 +1093,29 @@ namespace Barotrauma
|
|||||||
var maxVersion = new Version(attribute.Value);
|
var maxVersion = new Version(attribute.Value);
|
||||||
if (GameMain.Version > maxVersion) { return false; }
|
if (GameMain.Version > maxVersion) { return false; }
|
||||||
break;
|
break;
|
||||||
|
case "buildconfiguration":
|
||||||
|
switch (attribute.Value.ToString().ToLowerInvariant())
|
||||||
|
{
|
||||||
|
case "debug":
|
||||||
|
#if DEBUG
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case "unstable":
|
||||||
|
#if UNSTABLE
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case "release":
|
||||||
|
#if !DEBUG && !UNSTABLE
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -362,6 +362,14 @@ namespace Barotrauma
|
|||||||
RectTransform.ScaleChanged += () => dimensionsNeedsRecalculation = true;
|
RectTransform.ScaleChanged += () => dimensionsNeedsRecalculation = true;
|
||||||
RectTransform.SizeChanged += () => dimensionsNeedsRecalculation = true;
|
RectTransform.SizeChanged += () => dimensionsNeedsRecalculation = true;
|
||||||
UpdateDimensions();
|
UpdateDimensions();
|
||||||
|
|
||||||
|
rectT.ChildrenChanged += CheckForChildren;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CheckForChildren(RectTransform rectT)
|
||||||
|
{
|
||||||
|
if (rectT == ScrollBar.RectTransform || rectT == Content.RectTransform || rectT == ContentBackground.RectTransform) { return; }
|
||||||
|
throw new InvalidOperationException($"Children were added to {nameof(GUIListBox)}, Add them to {nameof(GUIListBox)}.{nameof(Content)} instead.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateDimensions()
|
public void UpdateDimensions()
|
||||||
@@ -431,7 +439,7 @@ namespace Barotrauma
|
|||||||
for (int i = 0; i < Content.CountChildren; i++)
|
for (int i = 0; i < Content.CountChildren; i++)
|
||||||
{
|
{
|
||||||
GUIComponent child = Content.GetChild(i);
|
GUIComponent child = Content.GetChild(i);
|
||||||
if (!child.Visible) { continue; }
|
if (child == null || !child.Visible) { continue; }
|
||||||
if (RectTransform != null)
|
if (RectTransform != null)
|
||||||
{
|
{
|
||||||
callback(i, new Point(x, y));
|
callback(i, new Point(x, y));
|
||||||
@@ -837,7 +845,6 @@ namespace Barotrauma
|
|||||||
UpdateScrollBarSize();
|
UpdateScrollBarSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (FadeElements)
|
if (FadeElements)
|
||||||
{
|
{
|
||||||
foreach (var (component, _) in childVisible)
|
foreach (var (component, _) in childVisible)
|
||||||
|
|||||||
@@ -319,28 +319,29 @@ namespace Barotrauma
|
|||||||
AbsoluteSpacing = absoluteSpacing.Y,
|
AbsoluteSpacing = absoluteSpacing.Y,
|
||||||
};
|
};
|
||||||
|
|
||||||
var bottomContainer = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.3f), verticalLayoutGroup.RectTransform), style: null);
|
var bottomContainer = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.3f), verticalLayoutGroup.RectTransform), style: null)
|
||||||
|
|
||||||
var tickBoxLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.67f, 1.0f), bottomContainer.RectTransform, anchor: Anchor.CenterLeft),
|
|
||||||
isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
|
||||||
{
|
{
|
||||||
Stretch = true,
|
CanBeFocused = true
|
||||||
RelativeSpacing = 0.02f
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var dontShowAgainTickBox = new GUITickBox(new RectTransform(new Vector2(0.5f, 1.0f), tickBoxLayoutGroup.RectTransform),
|
var tickBoxLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.67f, 1.0f), bottomContainer.RectTransform, anchor: Anchor.CenterLeft))
|
||||||
|
{
|
||||||
|
CanBeFocused = true,
|
||||||
|
Stretch = true
|
||||||
|
};
|
||||||
|
Vector2 tickBoxRelativeSize = new Vector2(1.0f, 0.5f);
|
||||||
|
var dontShowAgainTickBox = new GUITickBox(new RectTransform(tickBoxRelativeSize, tickBoxLayoutGroup.RectTransform),
|
||||||
TextManager.Get("hintmessagebox.dontshowagain"))
|
TextManager.Get("hintmessagebox.dontshowagain"))
|
||||||
{
|
{
|
||||||
ToolTip = TextManager.Get("hintmessagebox.dontshowagaintooltip"),
|
ToolTip = TextManager.Get("hintmessagebox.dontshowagaintooltip"),
|
||||||
UserData = "dontshowagain"
|
UserData = "dontshowagain"
|
||||||
};
|
};
|
||||||
|
var disableHintsTickBox = new GUITickBox(new RectTransform(tickBoxRelativeSize, tickBoxLayoutGroup.RectTransform),
|
||||||
//var disableHintsTickBox = new GUITickBox(new RectTransform(new Vector2(0.33f, 1.0f), tickBoxLayoutGroup.RectTransform),
|
TextManager.Get("hintmessagebox.disablehints"))
|
||||||
// TextManager.Get("hintmessagebox.disablehints"))
|
{
|
||||||
//{
|
ToolTip = TextManager.Get("hintmessagebox.disablehintstooltip"),
|
||||||
// ToolTip = TextManager.Get("hintmessagebox.disablehintstooltip"),
|
UserData = "disablehints"
|
||||||
// UserData = "disablehints"
|
};
|
||||||
//};
|
|
||||||
|
|
||||||
Buttons = new List<GUIButton>(1)
|
Buttons = new List<GUIButton>(1)
|
||||||
{
|
{
|
||||||
@@ -379,12 +380,16 @@ namespace Barotrauma
|
|||||||
upperContainerHeight = Math.Max(upperContainerHeight, Icon.Rect.Height);
|
upperContainerHeight = Math.Max(upperContainerHeight, Icon.Rect.Height);
|
||||||
height += upperContainerHeight;
|
height += upperContainerHeight;
|
||||||
height += absoluteSpacing.Y;
|
height += absoluteSpacing.Y;
|
||||||
height += (int)((bottomContainer.RectTransform.RelativeSize.Y / topHorizontalLayoutGroup.RectTransform.RelativeSize.Y) * upperContainerHeight);
|
int bottomContainerHeight = dontShowAgainTickBox.Rect.Height + disableHintsTickBox.Rect.Height;
|
||||||
|
height += bottomContainerHeight;
|
||||||
height += absoluteSpacing.Y;
|
height += absoluteSpacing.Y;
|
||||||
if (minSize.HasValue) { height = Math.Max(height, minSize.Value.Y); }
|
if (minSize.HasValue) { height = Math.Max(height, minSize.Value.Y); }
|
||||||
|
|
||||||
InnerFrame.RectTransform.NonScaledSize = new Point(InnerFrame.Rect.Width, height);
|
InnerFrame.RectTransform.NonScaledSize = new Point(InnerFrame.Rect.Width, height);
|
||||||
verticalLayoutGroup.RectTransform.NonScaledSize = GetVerticalLayoutGroupSize();
|
verticalLayoutGroup.RectTransform.NonScaledSize = GetVerticalLayoutGroupSize();
|
||||||
|
float upperContainerRelativeHeight = (float)upperContainerHeight / (upperContainerHeight + bottomContainerHeight);
|
||||||
|
topHorizontalLayoutGroup.RectTransform.RelativeSize = new Vector2(topHorizontalLayoutGroup.RectTransform.RelativeSize.X, upperContainerRelativeHeight);
|
||||||
|
bottomContainer.RectTransform.RelativeSize = new Vector2(bottomContainer.RectTransform.RelativeSize.X, 1.0f - upperContainerRelativeHeight);
|
||||||
verticalLayoutGroup.Recalculate();
|
verticalLayoutGroup.Recalculate();
|
||||||
topHorizontalLayoutGroup.Recalculate();
|
topHorizontalLayoutGroup.Recalculate();
|
||||||
Content.Recalculate();
|
Content.Recalculate();
|
||||||
@@ -613,6 +618,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public bool Close(GUIButton button, object obj)
|
public bool Close(GUIButton button, object obj)
|
||||||
{
|
{
|
||||||
|
RectTransform.Parent = null;
|
||||||
Close();
|
Close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,12 @@ namespace Barotrauma
|
|||||||
ClampChildMouseRects(Content);
|
ClampChildMouseRects(Content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void DrawChildren(SpriteBatch spriteBatch, bool recursive)
|
||||||
|
{
|
||||||
|
//do nothing (the children have to be drawn in the Draw method after the ScissorRectangle has been set)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
protected override void Draw(SpriteBatch spriteBatch)
|
protected override void Draw(SpriteBatch spriteBatch)
|
||||||
{
|
{
|
||||||
if (!Visible) { return; }
|
if (!Visible) { return; }
|
||||||
|
|||||||
@@ -204,6 +204,12 @@ namespace Barotrauma
|
|||||||
set { textColor = value; }
|
set { textColor = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Color DisabledTextColor
|
||||||
|
{
|
||||||
|
get => disabledTextColor;
|
||||||
|
set => disabledTextColor = value;
|
||||||
|
}
|
||||||
|
|
||||||
private Color? hoverTextColor;
|
private Color? hoverTextColor;
|
||||||
public Color HoverTextColor
|
public Color HoverTextColor
|
||||||
{
|
{
|
||||||
@@ -303,6 +309,10 @@ namespace Barotrauma
|
|||||||
if (parseRichText)
|
if (parseRichText)
|
||||||
{
|
{
|
||||||
RichTextData = Barotrauma.RichTextData.GetRichTextData(text, out text);
|
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,
|
||||||
@@ -457,7 +467,7 @@ namespace Barotrauma
|
|||||||
while (size == Vector2.Zero)
|
while (size == Vector2.Zero)
|
||||||
{
|
{
|
||||||
try { size = Font.MeasureString(string.IsNullOrEmpty(text) ? " " : text); }
|
try { size = Font.MeasureString(string.IsNullOrEmpty(text) ? " " : text); }
|
||||||
catch { text = text.Substring(0, text.Length - 1); }
|
catch { text = text.Length > 0 ? text.Substring(0, text.Length - 1) : ""; }
|
||||||
}
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
|
|||||||
@@ -80,6 +80,8 @@ namespace Barotrauma
|
|||||||
private Vector2 selectionEndPos;
|
private Vector2 selectionEndPos;
|
||||||
private Vector2 selectionRectSize;
|
private Vector2 selectionRectSize;
|
||||||
|
|
||||||
|
private GUICustomComponent caretAndSelectionRenderer;
|
||||||
|
|
||||||
private bool mouseHeldInside;
|
private bool mouseHeldInside;
|
||||||
|
|
||||||
private readonly Memento<string> memento = new Memento<string>();
|
private readonly Memento<string> memento = new Memento<string>();
|
||||||
@@ -188,8 +190,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
base.ToolTip = value;
|
base.ToolTip = textBlock.ToolTip = caretAndSelectionRenderer.ToolTip = value;
|
||||||
textBlock.ToolTip = value;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,7 +279,7 @@ namespace Barotrauma
|
|||||||
CaretEnabled = true;
|
CaretEnabled = true;
|
||||||
caretPosDirty = true;
|
caretPosDirty = true;
|
||||||
|
|
||||||
new GUICustomComponent(new RectTransform(Vector2.One, frame.RectTransform), onDraw: DrawCaretAndSelection);
|
caretAndSelectionRenderer = new GUICustomComponent(new RectTransform(Vector2.One, frame.RectTransform), onDraw: DrawCaretAndSelection);
|
||||||
|
|
||||||
int clearButtonWidth = 0;
|
int clearButtonWidth = 0;
|
||||||
if (createClearButton)
|
if (createClearButton)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -58,7 +58,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly List<RectTransform> children = new List<RectTransform>();
|
protected readonly List<RectTransform> children = new List<RectTransform>();
|
||||||
public IEnumerable<RectTransform> Children => children;
|
public IEnumerable<RectTransform> Children => children;
|
||||||
|
|
||||||
public int CountChildren => children.Count;
|
public int CountChildren => children.Count;
|
||||||
@@ -637,7 +637,15 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public bool IsParentOf(RectTransform rectT, bool recursive = true)
|
public bool IsParentOf(RectTransform rectT, bool recursive = true)
|
||||||
{
|
{
|
||||||
return children.Contains(rectT) || (recursive && children.Any(c => c.IsParentOf(rectT)));
|
if (children.Contains(rectT)) { return true; }
|
||||||
|
if (recursive)
|
||||||
|
{
|
||||||
|
foreach (var child in children)
|
||||||
|
{
|
||||||
|
if (child.IsParentOf(rectT)) { return true; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsChildOf(RectTransform rectT, bool recursive = true)
|
public bool IsChildOf(RectTransform rectT, bool recursive = true)
|
||||||
|
|||||||
@@ -43,36 +43,42 @@ namespace Barotrauma
|
|||||||
private bool needsRefresh, needsBuyingRefresh, needsSellingRefresh, needsItemsToSellRefresh, needsSellingFromSubRefresh, needsItemsToSellFromSubRefresh;
|
private bool needsRefresh, needsBuyingRefresh, needsSellingRefresh, needsItemsToSellRefresh, needsSellingFromSubRefresh, needsItemsToSellFromSubRefresh;
|
||||||
|
|
||||||
private Point resolutionWhenCreated;
|
private Point resolutionWhenCreated;
|
||||||
private bool hadPermissions;
|
|
||||||
|
|
||||||
private Dictionary<ItemPrefab, int> OwnedItems { get; } = new Dictionary<ItemPrefab, int>();
|
private Dictionary<ItemPrefab, int> OwnedItems { get; } = new Dictionary<ItemPrefab, int>();
|
||||||
|
|
||||||
private CargoManager CargoManager => campaignUI.Campaign.CargoManager;
|
private CargoManager CargoManager => campaignUI.Campaign.CargoManager;
|
||||||
private Location CurrentLocation => campaignUI.Campaign.Map?.CurrentLocation;
|
private Location CurrentLocation => campaignUI.Campaign.Map?.CurrentLocation;
|
||||||
private int PlayerMoney => campaignUI.Campaign.Money;
|
private int PlayerMoney => campaignUI.Campaign.Money;
|
||||||
private bool HasPermissions => campaignUI.Campaign.AllowedToManageCampaign();
|
|
||||||
private bool IsBuying => activeTab switch
|
private bool IsBuying => activeTab switch
|
||||||
{
|
{
|
||||||
StoreTab.Buy => true,
|
StoreTab.Buy => true,
|
||||||
StoreTab.Sell => false,
|
StoreTab.Sell => false,
|
||||||
StoreTab.SellFromSub => false,
|
StoreTab.SellSub => false,
|
||||||
_ => throw new NotImplementedException()
|
_ => throw new NotImplementedException()
|
||||||
};
|
};
|
||||||
private GUIListBox ActiveShoppingCrateList => activeTab switch
|
private GUIListBox ActiveShoppingCrateList => activeTab switch
|
||||||
{
|
{
|
||||||
StoreTab.Buy => shoppingCrateBuyList,
|
StoreTab.Buy => shoppingCrateBuyList,
|
||||||
StoreTab.Sell => shoppingCrateSellList,
|
StoreTab.Sell => shoppingCrateSellList,
|
||||||
StoreTab.SellFromSub => shoppingCrateSellFromSubList,
|
StoreTab.SellSub => shoppingCrateSellFromSubList,
|
||||||
_ => throw new NotImplementedException()
|
_ => throw new NotImplementedException()
|
||||||
};
|
};
|
||||||
|
|
||||||
private bool IsTabUnavailable(StoreTab tab) => !tabLists.ContainsKey(tab);
|
|
||||||
|
|
||||||
public enum StoreTab
|
public enum StoreTab
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Buy items from the store
|
||||||
|
/// </summary>
|
||||||
Buy,
|
Buy,
|
||||||
|
/// <summary>
|
||||||
|
/// Sell items from the character inventory
|
||||||
|
/// </summary>
|
||||||
Sell,
|
Sell,
|
||||||
SellFromSub
|
/// <summary>
|
||||||
|
/// Sell items from the sub
|
||||||
|
/// </summary>
|
||||||
|
SellSub
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum SortingMethod
|
private enum SortingMethod
|
||||||
@@ -84,11 +90,117 @@ namespace Barotrauma
|
|||||||
CategoryAsc
|
CategoryAsc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Permissions
|
||||||
|
|
||||||
|
private bool hadPermissions, hadBuyPermissions, hadSellInventoryPermissions, hadSellSubPermissions;
|
||||||
|
|
||||||
|
private bool HasPermissions
|
||||||
|
{
|
||||||
|
get => GetPermissions();
|
||||||
|
set => hadPermissions = value;
|
||||||
|
}
|
||||||
|
private bool HasBuyPermissions
|
||||||
|
{
|
||||||
|
get => HasPermissions || GetPermissions(StoreTab.Buy);
|
||||||
|
set => hadBuyPermissions = value;
|
||||||
|
}
|
||||||
|
private bool HasSellInventoryPermissions
|
||||||
|
{
|
||||||
|
get => HasPermissions || GetPermissions(StoreTab.Sell);
|
||||||
|
set => hadSellInventoryPermissions = value;
|
||||||
|
}
|
||||||
|
private bool HasSellSubPermissions
|
||||||
|
{
|
||||||
|
get => HasPermissions || GetPermissions(StoreTab.SellSub);
|
||||||
|
set => hadSellSubPermissions = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool GetPermissions(StoreTab? tab = null)
|
||||||
|
{
|
||||||
|
if (!tab.HasValue)
|
||||||
|
{
|
||||||
|
return campaignUI.Campaign.AllowedToManageCampaign() || campaignUI.Campaign.AllowedToManageCampaign(Networking.ClientPermissions.CampaignStore);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return tab.Value switch
|
||||||
|
{
|
||||||
|
StoreTab.Buy => campaignUI.Campaign.AllowedToManageCampaign(Networking.ClientPermissions.BuyItems),
|
||||||
|
StoreTab.Sell => campaignUI.Campaign.AllowedToManageCampaign(Networking.ClientPermissions.SellInventoryItems),
|
||||||
|
StoreTab.SellSub => campaignUI.Campaign.AllowedToManageCampaign(Networking.ClientPermissions.SellSubItems),
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdatePermissions(StoreTab? tab = null)
|
||||||
|
{
|
||||||
|
HasPermissions = GetPermissions();
|
||||||
|
if (!tab.HasValue)
|
||||||
|
{
|
||||||
|
HasBuyPermissions = GetPermissions(StoreTab.Buy);
|
||||||
|
HasSellInventoryPermissions = GetPermissions(StoreTab.Sell);
|
||||||
|
HasSellSubPermissions = GetPermissions(StoreTab.SellSub);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (tab.Value)
|
||||||
|
{
|
||||||
|
case StoreTab.Buy:
|
||||||
|
HasBuyPermissions = GetPermissions(tab.Value);
|
||||||
|
break;
|
||||||
|
case StoreTab.Sell:
|
||||||
|
HasSellInventoryPermissions = GetPermissions(tab.Value);
|
||||||
|
break;
|
||||||
|
case StoreTab.SellSub:
|
||||||
|
HasSellSubPermissions = GetPermissions(tab.Value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool HasTabPermissions(StoreTab tab)
|
||||||
|
{
|
||||||
|
return tab switch
|
||||||
|
{
|
||||||
|
StoreTab.Buy => HasBuyPermissions,
|
||||||
|
StoreTab.Sell => HasSellInventoryPermissions,
|
||||||
|
StoreTab.SellSub => HasSellSubPermissions,
|
||||||
|
_ => false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool HasActiveTabPermissions()
|
||||||
|
{
|
||||||
|
return HasTabPermissions(activeTab);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool HavePermissionsChanged(StoreTab? tab = null)
|
||||||
|
{
|
||||||
|
if (!tab.HasValue)
|
||||||
|
{
|
||||||
|
return hadPermissions != HasPermissions;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool hadTabPermissions = tab.Value switch
|
||||||
|
{
|
||||||
|
StoreTab.Buy => hadBuyPermissions,
|
||||||
|
StoreTab.Sell => hadSellInventoryPermissions,
|
||||||
|
StoreTab.SellSub => hadSellSubPermissions,
|
||||||
|
_ => false
|
||||||
|
};
|
||||||
|
return hadTabPermissions != HasTabPermissions(tab.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
public Store(CampaignUI campaignUI, GUIComponent parentComponent)
|
public Store(CampaignUI campaignUI, GUIComponent parentComponent)
|
||||||
{
|
{
|
||||||
this.campaignUI = campaignUI;
|
this.campaignUI = campaignUI;
|
||||||
this.parentComponent = parentComponent;
|
this.parentComponent = parentComponent;
|
||||||
hadPermissions = HasPermissions;
|
UpdatePermissions();
|
||||||
CreateUI();
|
CreateUI();
|
||||||
campaignUI.Campaign.Map.OnLocationChanged += UpdateLocation;
|
campaignUI.Campaign.Map.OnLocationChanged += UpdateLocation;
|
||||||
if (CurrentLocation?.Reputation != null)
|
if (CurrentLocation?.Reputation != null)
|
||||||
@@ -109,7 +221,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void Refresh(bool updateOwned = true)
|
public void Refresh(bool updateOwned = true)
|
||||||
{
|
{
|
||||||
hadPermissions = HasPermissions;
|
UpdatePermissions();
|
||||||
if (updateOwned) { UpdateOwnedItems(); }
|
if (updateOwned) { UpdateOwnedItems(); }
|
||||||
RefreshBuying(updateOwned: false);
|
RefreshBuying(updateOwned: false);
|
||||||
RefreshSelling(updateOwned: false);
|
RefreshSelling(updateOwned: false);
|
||||||
@@ -122,7 +234,7 @@ namespace Barotrauma
|
|||||||
if (updateOwned) { UpdateOwnedItems(); }
|
if (updateOwned) { UpdateOwnedItems(); }
|
||||||
RefreshShoppingCrateBuyList();
|
RefreshShoppingCrateBuyList();
|
||||||
RefreshStoreBuyList();
|
RefreshStoreBuyList();
|
||||||
var hasPermissions = HasPermissions;
|
bool hasPermissions = HasTabPermissions(StoreTab.Buy);
|
||||||
storeBuyList.Enabled = hasPermissions;
|
storeBuyList.Enabled = hasPermissions;
|
||||||
shoppingCrateBuyList.Enabled = hasPermissions;
|
shoppingCrateBuyList.Enabled = hasPermissions;
|
||||||
needsBuyingRefresh = false;
|
needsBuyingRefresh = false;
|
||||||
@@ -133,7 +245,7 @@ namespace Barotrauma
|
|||||||
if (updateOwned) { UpdateOwnedItems(); }
|
if (updateOwned) { UpdateOwnedItems(); }
|
||||||
RefreshShoppingCrateSellList();
|
RefreshShoppingCrateSellList();
|
||||||
RefreshStoreSellList();
|
RefreshStoreSellList();
|
||||||
var hasPermissions = HasPermissions;
|
bool hasPermissions = HasTabPermissions(StoreTab.Sell);
|
||||||
storeSellList.Enabled = hasPermissions;
|
storeSellList.Enabled = hasPermissions;
|
||||||
shoppingCrateSellList.Enabled = hasPermissions;
|
shoppingCrateSellList.Enabled = hasPermissions;
|
||||||
needsSellingRefresh = false;
|
needsSellingRefresh = false;
|
||||||
@@ -141,13 +253,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void RefreshSellingFromSub(bool updateOwned = true, bool updateItemsToSellFromSub = true)
|
private void RefreshSellingFromSub(bool updateOwned = true, bool updateItemsToSellFromSub = true)
|
||||||
{
|
{
|
||||||
if (IsTabUnavailable(StoreTab.SellFromSub)) { return; }
|
|
||||||
if (updateOwned) { UpdateOwnedItems(); }
|
if (updateOwned) { UpdateOwnedItems(); }
|
||||||
if (updateItemsToSellFromSub) RefreshItemsToSellFromSub();
|
if (updateItemsToSellFromSub) RefreshItemsToSellFromSub();
|
||||||
RefreshShoppingCrateSellFromSubList();
|
RefreshShoppingCrateSellFromSubList();
|
||||||
RefreshStoreSellFromSubList();
|
RefreshStoreSellFromSubList();
|
||||||
// TODO: Separate permissions from regular campaign permissions
|
bool hasPermissions = HasTabPermissions(StoreTab.SellSub);
|
||||||
var hasPermissions = HasPermissions;
|
|
||||||
storeSellFromSubList.Enabled = hasPermissions;
|
storeSellFromSubList.Enabled = hasPermissions;
|
||||||
shoppingCrateSellFromSubList.Enabled = hasPermissions;
|
shoppingCrateSellFromSubList.Enabled = hasPermissions;
|
||||||
needsSellingFromSubRefresh = false;
|
needsSellingFromSubRefresh = false;
|
||||||
@@ -261,7 +371,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
StoreTab.Buy => CurrentLocation.StoreCurrentBalance + buyTotal,
|
StoreTab.Buy => CurrentLocation.StoreCurrentBalance + buyTotal,
|
||||||
StoreTab.Sell => CurrentLocation.StoreCurrentBalance - sellTotal,
|
StoreTab.Sell => CurrentLocation.StoreCurrentBalance - sellTotal,
|
||||||
StoreTab.SellFromSub => CurrentLocation.StoreCurrentBalance - sellFromSubTotal,
|
StoreTab.SellSub => CurrentLocation.StoreCurrentBalance - sellFromSubTotal,
|
||||||
_ => throw new NotImplementedException(),
|
_ => throw new NotImplementedException(),
|
||||||
};
|
};
|
||||||
if (balanceAfterTransaction != CurrentLocation.StoreCurrentBalance)
|
if (balanceAfterTransaction != CurrentLocation.StoreCurrentBalance)
|
||||||
@@ -325,10 +435,9 @@ namespace Barotrauma
|
|||||||
tabSortingMethods.Clear();
|
tabSortingMethods.Clear();
|
||||||
foreach (StoreTab tab in tabs)
|
foreach (StoreTab tab in tabs)
|
||||||
{
|
{
|
||||||
if (tab == StoreTab.SellFromSub && GameMain.IsMultiplayer) { continue; }
|
|
||||||
string text = tab switch
|
string text = tab switch
|
||||||
{
|
{
|
||||||
StoreTab.SellFromSub => TextManager.Get("submarine"),
|
StoreTab.SellSub => TextManager.Get("submarine"),
|
||||||
_ => TextManager.Get("campaignstoretab." + tab)
|
_ => TextManager.Get("campaignstoretab." + tab)
|
||||||
};
|
};
|
||||||
var tabButton = new GUIButton(new RectTransform(new Vector2(1.0f / (tabs.Length + 1), 1.0f), modeButtonContainer.RectTransform),
|
var tabButton = new GUIButton(new RectTransform(new Vector2(1.0f / (tabs.Length + 1), 1.0f), modeButtonContainer.RectTransform),
|
||||||
@@ -456,16 +565,13 @@ namespace Barotrauma
|
|||||||
storeRequestedGoodGroup = CreateDealsGroup(storeSellList);
|
storeRequestedGoodGroup = CreateDealsGroup(storeSellList);
|
||||||
tabLists.Add(StoreTab.Sell, storeSellList);
|
tabLists.Add(StoreTab.Sell, storeSellList);
|
||||||
|
|
||||||
if (GameMain.IsSingleplayer)
|
storeSellFromSubList = new GUIListBox(new RectTransform(Vector2.One, storeItemListContainer.RectTransform))
|
||||||
{
|
{
|
||||||
storeSellFromSubList = new GUIListBox(new RectTransform(Vector2.One, storeItemListContainer.RectTransform))
|
AutoHideScrollBar = false,
|
||||||
{
|
Visible = false
|
||||||
AutoHideScrollBar = false,
|
};
|
||||||
Visible = false
|
storeRequestedSubGoodGroup = CreateDealsGroup(storeSellFromSubList);
|
||||||
};
|
tabLists.Add(StoreTab.SellSub, storeSellFromSubList);
|
||||||
storeRequestedSubGoodGroup = CreateDealsGroup(storeSellFromSubList);
|
|
||||||
tabLists.Add(StoreTab.SellFromSub, storeSellFromSubList);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shopping Crate ------------------------------------------------------------------------------------------------------------------------------------------
|
// Shopping Crate ------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -526,10 +632,7 @@ namespace Barotrauma
|
|||||||
var shoppingCrateListContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.8f), shoppingCrateInventoryContainer.RectTransform), style: null);
|
var shoppingCrateListContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.8f), shoppingCrateInventoryContainer.RectTransform), style: null);
|
||||||
shoppingCrateBuyList = new GUIListBox(new RectTransform(Vector2.One, shoppingCrateListContainer.RectTransform)) { Visible = false };
|
shoppingCrateBuyList = new GUIListBox(new RectTransform(Vector2.One, shoppingCrateListContainer.RectTransform)) { Visible = false };
|
||||||
shoppingCrateSellList = new GUIListBox(new RectTransform(Vector2.One, shoppingCrateListContainer.RectTransform)) { Visible = false };
|
shoppingCrateSellList = new GUIListBox(new RectTransform(Vector2.One, shoppingCrateListContainer.RectTransform)) { Visible = false };
|
||||||
if (GameMain.IsSingleplayer)
|
shoppingCrateSellFromSubList = new GUIListBox(new RectTransform(Vector2.One, shoppingCrateListContainer.RectTransform)) { Visible = false };
|
||||||
{
|
|
||||||
shoppingCrateSellFromSubList = new GUIListBox(new RectTransform(Vector2.One, shoppingCrateListContainer.RectTransform)) { Visible = false };
|
|
||||||
}
|
|
||||||
|
|
||||||
var relevantBalanceContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.05f), shoppingCrateInventoryContainer.RectTransform), isHorizontal: true)
|
var relevantBalanceContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.05f), shoppingCrateInventoryContainer.RectTransform), isHorizontal: true)
|
||||||
{
|
{
|
||||||
@@ -569,16 +672,16 @@ namespace Barotrauma
|
|||||||
clearAllButton = new GUIButton(new RectTransform(new Vector2(0.35f, 1.0f), buttonContainer.RectTransform), TextManager.Get("campaignstore.clearall"))
|
clearAllButton = new GUIButton(new RectTransform(new Vector2(0.35f, 1.0f), buttonContainer.RectTransform), TextManager.Get("campaignstore.clearall"))
|
||||||
{
|
{
|
||||||
ClickSound = GUISoundType.DecreaseQuantity,
|
ClickSound = GUISoundType.DecreaseQuantity,
|
||||||
Enabled = HasPermissions,
|
Enabled = HasActiveTabPermissions(),
|
||||||
ForceUpperCase = true,
|
ForceUpperCase = true,
|
||||||
OnClicked = (button, userData) =>
|
OnClicked = (button, userData) =>
|
||||||
{
|
{
|
||||||
if (!HasPermissions) { return false; }
|
if (!HasActiveTabPermissions()) { return false; }
|
||||||
var itemsToRemove = activeTab switch
|
var itemsToRemove = activeTab switch
|
||||||
{
|
{
|
||||||
StoreTab.Buy => new List<PurchasedItem>(CargoManager.ItemsInBuyCrate),
|
StoreTab.Buy => new List<PurchasedItem>(CargoManager.ItemsInBuyCrate),
|
||||||
StoreTab.Sell => new List<PurchasedItem>(CargoManager.ItemsInSellCrate),
|
StoreTab.Sell => new List<PurchasedItem>(CargoManager.ItemsInSellCrate),
|
||||||
StoreTab.SellFromSub => new List<PurchasedItem>(CargoManager.ItemsInSellFromSubCrate),
|
StoreTab.SellSub => new List<PurchasedItem>(CargoManager.ItemsInSellFromSubCrate),
|
||||||
_ => throw new NotImplementedException(),
|
_ => throw new NotImplementedException(),
|
||||||
};
|
};
|
||||||
itemsToRemove.ForEach(i => ClearFromShoppingCrate(i));
|
itemsToRemove.ForEach(i => ClearFromShoppingCrate(i));
|
||||||
@@ -637,7 +740,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void ChangeStoreTab(StoreTab tab)
|
private void ChangeStoreTab(StoreTab tab)
|
||||||
{
|
{
|
||||||
if (IsTabUnavailable(tab)) { return; }
|
|
||||||
activeTab = tab;
|
activeTab = tab;
|
||||||
foreach (GUIButton tabButton in storeTabButtons)
|
foreach (GUIButton tabButton in storeTabButtons)
|
||||||
{
|
{
|
||||||
@@ -680,7 +782,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
shoppingCrateSellList.Visible = true;
|
shoppingCrateSellList.Visible = true;
|
||||||
break;
|
break;
|
||||||
case StoreTab.SellFromSub:
|
case StoreTab.SellSub:
|
||||||
storeBuyList.Visible = false;
|
storeBuyList.Visible = false;
|
||||||
storeSellList.Visible = false;
|
storeSellList.Visible = false;
|
||||||
if (storeSellFromSubList != null)
|
if (storeSellFromSubList != null)
|
||||||
@@ -699,7 +801,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void FilterStoreItems(MapEntityCategory? category, string filter)
|
private void FilterStoreItems(MapEntityCategory? category, string filter)
|
||||||
{
|
{
|
||||||
if (IsTabUnavailable(activeTab)) { return; }
|
|
||||||
selectedItemCategory = category;
|
selectedItemCategory = category;
|
||||||
var list = tabLists[activeTab];
|
var list = tabLists[activeTab];
|
||||||
filter = filter?.ToLower();
|
filter = filter?.ToLower();
|
||||||
@@ -733,7 +834,7 @@ namespace Barotrauma
|
|||||||
float prevBuyListScroll = storeBuyList.BarScroll;
|
float prevBuyListScroll = storeBuyList.BarScroll;
|
||||||
float prevShoppingCrateScroll = shoppingCrateBuyList.BarScroll;
|
float prevShoppingCrateScroll = shoppingCrateBuyList.BarScroll;
|
||||||
|
|
||||||
bool hasPermissions = HasPermissions;
|
bool hasPermissions = HasBuyPermissions;
|
||||||
HashSet<GUIComponent> existingItemFrames = new HashSet<GUIComponent>();
|
HashSet<GUIComponent> existingItemFrames = new HashSet<GUIComponent>();
|
||||||
|
|
||||||
int dailySpecialCount = CurrentLocation?.DailySpecials.Count() ?? 3;
|
int dailySpecialCount = CurrentLocation?.DailySpecials.Count() ?? 3;
|
||||||
@@ -816,7 +917,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
float prevSellListScroll = storeSellList.BarScroll;
|
float prevSellListScroll = storeSellList.BarScroll;
|
||||||
float prevShoppingCrateScroll = shoppingCrateSellList.BarScroll;
|
float prevShoppingCrateScroll = shoppingCrateSellList.BarScroll;
|
||||||
bool hasPermissions = HasPermissions;
|
bool hasPermissions = HasTabPermissions(StoreTab.Sell);
|
||||||
HashSet<GUIComponent> existingItemFrames = new HashSet<GUIComponent>();
|
HashSet<GUIComponent> existingItemFrames = new HashSet<GUIComponent>();
|
||||||
|
|
||||||
if ((storeRequestedGoodGroup != null) != CurrentLocation.RequestedGoods.Any())
|
if ((storeRequestedGoodGroup != null) != CurrentLocation.RequestedGoods.Any())
|
||||||
@@ -894,7 +995,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
float prevSellListScroll = storeSellFromSubList.BarScroll;
|
float prevSellListScroll = storeSellFromSubList.BarScroll;
|
||||||
float prevShoppingCrateScroll = shoppingCrateSellFromSubList.BarScroll;
|
float prevShoppingCrateScroll = shoppingCrateSellFromSubList.BarScroll;
|
||||||
bool hasPermissions = HasPermissions;
|
bool hasPermissions = HasSellSubPermissions;
|
||||||
HashSet<GUIComponent> existingItemFrames = new HashSet<GUIComponent>();
|
HashSet<GUIComponent> existingItemFrames = new HashSet<GUIComponent>();
|
||||||
|
|
||||||
if ((storeRequestedSubGoodGroup != null) != CurrentLocation.RequestedGoods.Any())
|
if ((storeRequestedSubGoodGroup != null) != CurrentLocation.RequestedGoods.Any())
|
||||||
@@ -938,12 +1039,12 @@ namespace Barotrauma
|
|||||||
if (itemFrame == null)
|
if (itemFrame == null)
|
||||||
{
|
{
|
||||||
var parentComponent = isRequestedGood ? storeRequestedSubGoodGroup : storeSellFromSubList as GUIComponent;
|
var parentComponent = isRequestedGood ? storeRequestedSubGoodGroup : storeSellFromSubList as GUIComponent;
|
||||||
itemFrame = CreateItemFrame(new PurchasedItem(itemPrefab, itemQuantity), parentComponent, StoreTab.SellFromSub, forceDisable: !hasPermissions);
|
itemFrame = CreateItemFrame(new PurchasedItem(itemPrefab, itemQuantity), parentComponent, StoreTab.SellSub, forceDisable: !hasPermissions);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
(itemFrame.UserData as PurchasedItem).Quantity = itemQuantity;
|
(itemFrame.UserData as PurchasedItem).Quantity = itemQuantity;
|
||||||
SetQuantityLabelText(StoreTab.SellFromSub, itemFrame);
|
SetQuantityLabelText(StoreTab.SellSub, itemFrame);
|
||||||
SetOwnedLabelText(itemFrame);
|
SetOwnedLabelText(itemFrame);
|
||||||
SetPriceGetters(itemFrame, false);
|
SetPriceGetters(itemFrame, false);
|
||||||
}
|
}
|
||||||
@@ -961,8 +1062,8 @@ namespace Barotrauma
|
|||||||
removedItemFrames.AddRange(storeRequestedSubGoodGroup.Children.Where(c => c.UserData is PurchasedItem).Except(existingItemFrames).ToList());
|
removedItemFrames.AddRange(storeRequestedSubGoodGroup.Children.Where(c => c.UserData is PurchasedItem).Except(existingItemFrames).ToList());
|
||||||
}
|
}
|
||||||
removedItemFrames.ForEach(f => f.RectTransform.Parent = null);
|
removedItemFrames.ForEach(f => f.RectTransform.Parent = null);
|
||||||
if (activeTab == StoreTab.SellFromSub) { FilterStoreItems(); }
|
if (activeTab == StoreTab.SellSub) { FilterStoreItems(); }
|
||||||
SortItems(StoreTab.SellFromSub);
|
SortItems(StoreTab.SellSub);
|
||||||
|
|
||||||
storeSellFromSubList.BarScroll = prevSellListScroll;
|
storeSellFromSubList.BarScroll = prevSellListScroll;
|
||||||
shoppingCrateSellFromSubList.BarScroll = prevShoppingCrateScroll;
|
shoppingCrateSellFromSubList.BarScroll = prevShoppingCrateScroll;
|
||||||
@@ -1062,17 +1163,14 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void RefreshShoppingCrateList(List<PurchasedItem> items, GUIListBox listBox, StoreTab tab)
|
private void RefreshShoppingCrateList(List<PurchasedItem> items, GUIListBox listBox, StoreTab tab)
|
||||||
{
|
{
|
||||||
bool hasPermissions = HasPermissions;
|
bool hasPermissions = HasTabPermissions(tab);
|
||||||
HashSet<GUIComponent> existingItemFrames = new HashSet<GUIComponent>();
|
HashSet<GUIComponent> existingItemFrames = new HashSet<GUIComponent>();
|
||||||
int totalPrice = 0;
|
int totalPrice = 0;
|
||||||
foreach (PurchasedItem item in items)
|
foreach (PurchasedItem item in items)
|
||||||
{
|
{
|
||||||
PriceInfo priceInfo = item.ItemPrefab.GetPriceInfo(CurrentLocation);
|
if (!(item.ItemPrefab.GetPriceInfo(CurrentLocation) is { } priceInfo)) { continue; }
|
||||||
if (priceInfo == null) { continue; }
|
|
||||||
|
|
||||||
var itemFrame = listBox.Content.FindChild(c => c.UserData is PurchasedItem pi && pi.ItemPrefab.Identifier == item.ItemPrefab.Identifier);
|
|
||||||
GUINumberInput numInput = null;
|
GUINumberInput numInput = null;
|
||||||
if (itemFrame == null)
|
if (!(listBox.Content.FindChild(c => c.UserData is PurchasedItem pi && pi.ItemPrefab.Identifier == item.ItemPrefab.Identifier) is { } itemFrame))
|
||||||
{
|
{
|
||||||
itemFrame = CreateItemFrame(item, listBox, tab, forceDisable: !hasPermissions);
|
itemFrame = CreateItemFrame(item, listBox, tab, forceDisable: !hasPermissions);
|
||||||
numInput = itemFrame.FindChild(c => c is GUINumberInput, recursive: true) as GUINumberInput;
|
numInput = itemFrame.FindChild(c => c is GUINumberInput, recursive: true) as GUINumberInput;
|
||||||
@@ -1100,10 +1198,21 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
suppressBuySell = false;
|
suppressBuySell = false;
|
||||||
|
|
||||||
var price = tab == StoreTab.Buy ?
|
try
|
||||||
CurrentLocation.GetAdjustedItemBuyPrice(item.ItemPrefab, priceInfo: priceInfo) :
|
{
|
||||||
CurrentLocation.GetAdjustedItemSellPrice(item.ItemPrefab, priceInfo: priceInfo);
|
int price = tab switch
|
||||||
totalPrice += item.Quantity * price;
|
{
|
||||||
|
StoreTab.Buy => CurrentLocation.GetAdjustedItemBuyPrice(item.ItemPrefab, priceInfo: priceInfo),
|
||||||
|
StoreTab.Sell => CurrentLocation.GetAdjustedItemSellPrice(item.ItemPrefab, priceInfo: priceInfo),
|
||||||
|
StoreTab.SellSub => CurrentLocation.GetAdjustedItemSellPrice(item.ItemPrefab, priceInfo: priceInfo),
|
||||||
|
_ => throw new NotImplementedException()
|
||||||
|
};
|
||||||
|
totalPrice += item.Quantity * price;
|
||||||
|
}
|
||||||
|
catch (NotImplementedException e)
|
||||||
|
{
|
||||||
|
DebugConsole.ShowError($"Error getting item price: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var removedItemFrames = listBox.Content.Children.Except(existingItemFrames).ToList();
|
var removedItemFrames = listBox.Content.Children.Except(existingItemFrames).ToList();
|
||||||
@@ -1119,7 +1228,7 @@ namespace Barotrauma
|
|||||||
case StoreTab.Sell:
|
case StoreTab.Sell:
|
||||||
sellTotal = totalPrice;
|
sellTotal = totalPrice;
|
||||||
break;
|
break;
|
||||||
case StoreTab.SellFromSub:
|
case StoreTab.SellSub:
|
||||||
sellFromSubTotal = totalPrice;
|
sellFromSubTotal = totalPrice;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1135,7 +1244,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void RefreshShoppingCrateSellList() => RefreshShoppingCrateList(CargoManager.ItemsInSellCrate, shoppingCrateSellList, StoreTab.Sell);
|
private void RefreshShoppingCrateSellList() => RefreshShoppingCrateList(CargoManager.ItemsInSellCrate, shoppingCrateSellList, StoreTab.Sell);
|
||||||
|
|
||||||
private void RefreshShoppingCrateSellFromSubList() => RefreshShoppingCrateList(CargoManager.ItemsInSellFromSubCrate, shoppingCrateSellFromSubList, StoreTab.SellFromSub);
|
private void RefreshShoppingCrateSellFromSubList() => RefreshShoppingCrateList(CargoManager.ItemsInSellFromSubCrate, shoppingCrateSellFromSubList, StoreTab.SellSub);
|
||||||
|
|
||||||
private void SortItems(GUIListBox list, SortingMethod sortingMethod)
|
private void SortItems(GUIListBox list, SortingMethod sortingMethod)
|
||||||
{
|
{
|
||||||
@@ -1286,14 +1395,12 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void SortItems(StoreTab tab, SortingMethod sortingMethod)
|
private void SortItems(StoreTab tab, SortingMethod sortingMethod)
|
||||||
{
|
{
|
||||||
if (IsTabUnavailable(tab)) { return; }
|
|
||||||
tabSortingMethods[tab] = sortingMethod;
|
tabSortingMethods[tab] = sortingMethod;
|
||||||
SortItems(tabLists[tab], sortingMethod);
|
SortItems(tabLists[tab], sortingMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SortItems(StoreTab tab)
|
private void SortItems(StoreTab tab)
|
||||||
{
|
{
|
||||||
if (IsTabUnavailable(tab)) { return; }
|
|
||||||
SortItems(tab, tabSortingMethods[tab]);
|
SortItems(tab, tabSortingMethods[tab]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1301,12 +1408,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private GUIComponent CreateItemFrame(PurchasedItem pi, GUIComponent parentComponent, StoreTab containingTab, bool forceDisable = false)
|
private GUIComponent CreateItemFrame(PurchasedItem pi, GUIComponent parentComponent, StoreTab containingTab, bool forceDisable = false)
|
||||||
{
|
{
|
||||||
var tooltip = pi.ItemPrefab.Name;
|
|
||||||
if (!string.IsNullOrWhiteSpace(pi.ItemPrefab.Description))
|
|
||||||
{
|
|
||||||
tooltip += "\n" + pi.ItemPrefab.Description;
|
|
||||||
}
|
|
||||||
|
|
||||||
GUIListBox parentListBox = parentComponent as GUIListBox;
|
GUIListBox parentListBox = parentComponent as GUIListBox;
|
||||||
int width = 0;
|
int width = 0;
|
||||||
RectTransform parent = null;
|
RectTransform parent = null;
|
||||||
@@ -1320,7 +1421,11 @@ namespace Barotrauma
|
|||||||
width = parentComponent.Rect.Width;
|
width = parentComponent.Rect.Width;
|
||||||
parent = parentComponent.RectTransform;
|
parent = parentComponent.RectTransform;
|
||||||
}
|
}
|
||||||
|
string tooltip = pi.ItemPrefab.Name;
|
||||||
|
if (!string.IsNullOrWhiteSpace(pi.ItemPrefab.Description))
|
||||||
|
{
|
||||||
|
tooltip += $"\n{pi.ItemPrefab.Description}";
|
||||||
|
}
|
||||||
GUIFrame frame = new GUIFrame(new RectTransform(new Point(width, (int)(GUI.yScale * 80)), parent: parent), style: "ListBoxElement")
|
GUIFrame frame = new GUIFrame(new RectTransform(new Point(width, (int)(GUI.yScale * 80)), parent: parent), style: "ListBoxElement")
|
||||||
{
|
{
|
||||||
ToolTip = tooltip,
|
ToolTip = tooltip,
|
||||||
@@ -1338,8 +1443,7 @@ namespace Barotrauma
|
|||||||
var iconRelativeWidth = 0.0f;
|
var iconRelativeWidth = 0.0f;
|
||||||
var priceAndButtonRelativeWidth = 1.0f - nameAndIconRelativeWidth;
|
var priceAndButtonRelativeWidth = 1.0f - nameAndIconRelativeWidth;
|
||||||
|
|
||||||
Sprite itemIcon = pi.ItemPrefab.InventoryIcon ?? pi.ItemPrefab.sprite;
|
if ((pi.ItemPrefab.InventoryIcon ?? pi.ItemPrefab.sprite) is { } itemIcon)
|
||||||
if (itemIcon != null)
|
|
||||||
{
|
{
|
||||||
iconRelativeWidth = (0.9f * mainGroup.Rect.Height) / mainGroup.Rect.Width;
|
iconRelativeWidth = (0.9f * mainGroup.Rect.Height) / mainGroup.Rect.Width;
|
||||||
GUIImage img = new GUIImage(new RectTransform(new Vector2(iconRelativeWidth, 0.9f), mainGroup.RectTransform), itemIcon, scaleToFit: true)
|
GUIImage img = new GUIImage(new RectTransform(new Vector2(iconRelativeWidth, 0.9f), mainGroup.RectTransform), itemIcon, scaleToFit: true)
|
||||||
@@ -1425,7 +1529,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (suppressBuySell) { return; }
|
if (suppressBuySell) { return; }
|
||||||
PurchasedItem purchasedItem = numberInput.UserData as PurchasedItem;
|
PurchasedItem purchasedItem = numberInput.UserData as PurchasedItem;
|
||||||
if (!HasPermissions)
|
if (!HasActiveTabPermissions())
|
||||||
{
|
{
|
||||||
numberInput.IntValue = purchasedItem.Quantity;
|
numberInput.IntValue = purchasedItem.Quantity;
|
||||||
return;
|
return;
|
||||||
@@ -1528,11 +1632,16 @@ namespace Barotrauma
|
|||||||
OwnedItems.Clear();
|
OwnedItems.Clear();
|
||||||
|
|
||||||
// Add items on the sub(s)
|
// Add items on the sub(s)
|
||||||
Submarine.MainSub?.GetItems(true)
|
if (Submarine.MainSub?.GetItems(true) is List<Item> subItems)
|
||||||
.Where(i => i.Components.All(c => !(c is Holdable h) || !h.Attachable || !h.Attached) &&
|
{
|
||||||
i.Components.All(c => !(c is Wire w) || w.Connections.All(c => c == null)) &&
|
foreach (var subItem in subItems)
|
||||||
ItemAndAllContainersInteractable(i))
|
{
|
||||||
.ForEach(i => AddToOwnedItems(i.Prefab));
|
if (!subItem.Components.All(c => !(c is Holdable h) || !h.Attachable || !h.Attached)) { continue; }
|
||||||
|
if (!subItem.Components.All(c => !(c is Wire w) || w.Connections.All(c => c == null))) { continue; }
|
||||||
|
if (!ItemAndAllContainersInteractable(subItem)) { continue; }
|
||||||
|
AddToOwnedItems(subItem.Prefab);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add items in character inventories
|
// Add items in character inventories
|
||||||
foreach (var item in Item.ItemList)
|
foreach (var item in Item.ItemList)
|
||||||
@@ -1574,8 +1683,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void SetItemFrameStatus(GUIComponent itemFrame, bool enabled)
|
private void SetItemFrameStatus(GUIComponent itemFrame, bool enabled)
|
||||||
{
|
{
|
||||||
if (itemFrame == null || !(itemFrame.UserData is PurchasedItem pi)) { return; }
|
if (!(itemFrame?.UserData is PurchasedItem pi)) { return; }
|
||||||
|
bool refreshFrameStatus = !pi.IsStoreComponentEnabled.HasValue || pi.IsStoreComponentEnabled.Value != enabled;
|
||||||
|
if (!refreshFrameStatus) { return; }
|
||||||
if (itemFrame.FindChild("icon", recursive: true) is GUIImage icon)
|
if (itemFrame.FindChild("icon", recursive: true) is GUIImage icon)
|
||||||
{
|
{
|
||||||
if (pi.ItemPrefab?.InventoryIcon != null)
|
if (pi.ItemPrefab?.InventoryIcon != null)
|
||||||
@@ -1587,14 +1697,11 @@ namespace Barotrauma
|
|||||||
icon.Color = pi.ItemPrefab.SpriteColor * (enabled ? 1.0f : 0.5f);
|
icon.Color = pi.ItemPrefab.SpriteColor * (enabled ? 1.0f : 0.5f);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var color = Color.White * (enabled ? 1.0f : 0.5f);
|
var color = Color.White * (enabled ? 1.0f : 0.5f);
|
||||||
|
|
||||||
if (itemFrame.FindChild("name", recursive: true) is GUITextBlock name)
|
if (itemFrame.FindChild("name", recursive: true) is GUITextBlock name)
|
||||||
{
|
{
|
||||||
name.TextColor = color;
|
name.TextColor = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (itemFrame.FindChild("quantitylabel", recursive: true) is GUITextBlock qty)
|
if (itemFrame.FindChild("quantitylabel", recursive: true) is GUITextBlock qty)
|
||||||
{
|
{
|
||||||
qty.TextColor = color;
|
qty.TextColor = color;
|
||||||
@@ -1603,25 +1710,21 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
numberInput.Enabled = enabled;
|
numberInput.Enabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (itemFrame.FindChild("owned", recursive: true) is GUITextBlock ownedBlock)
|
if (itemFrame.FindChild("owned", recursive: true) is GUITextBlock ownedBlock)
|
||||||
{
|
{
|
||||||
ownedBlock.TextColor = color;
|
ownedBlock.TextColor = color;
|
||||||
}
|
}
|
||||||
|
bool isDiscounted = false;
|
||||||
var isDiscounted = false;
|
|
||||||
if (itemFrame.FindChild("undiscountedprice", recursive: true) is GUITextBlock undiscountedPriceBlock)
|
if (itemFrame.FindChild("undiscountedprice", recursive: true) is GUITextBlock undiscountedPriceBlock)
|
||||||
{
|
{
|
||||||
undiscountedPriceBlock.TextColor = color;
|
undiscountedPriceBlock.TextColor = color;
|
||||||
undiscountedPriceBlock.Strikethrough.Color = color;
|
undiscountedPriceBlock.Strikethrough.Color = color;
|
||||||
isDiscounted = true;
|
isDiscounted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (itemFrame.FindChild("price", recursive: true) is GUITextBlock priceBlock)
|
if (itemFrame.FindChild("price", recursive: true) is GUITextBlock priceBlock)
|
||||||
{
|
{
|
||||||
priceBlock.TextColor = isDiscounted ? storeSpecialColor * (enabled ? 1.0f : 0.5f) : color;
|
priceBlock.TextColor = isDiscounted ? storeSpecialColor * (enabled ? 1.0f : 0.5f) : color;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (itemFrame.FindChild("addbutton", recursive: true) is GUIButton addButton)
|
if (itemFrame.FindChild("addbutton", recursive: true) is GUIButton addButton)
|
||||||
{
|
{
|
||||||
addButton.Enabled = enabled;
|
addButton.Enabled = enabled;
|
||||||
@@ -1630,6 +1733,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
removeButton.Enabled = enabled;
|
removeButton.Enabled = enabled;
|
||||||
}
|
}
|
||||||
|
pi.IsStoreComponentEnabled = enabled;
|
||||||
|
itemFrame.UserData = pi;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetQuantityLabelText(StoreTab mode, GUIComponent itemFrame)
|
private void SetQuantityLabelText(StoreTab mode, GUIComponent itemFrame)
|
||||||
@@ -1664,14 +1769,22 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private int GetMaxAvailable(ItemPrefab itemPrefab, StoreTab mode)
|
private int GetMaxAvailable(ItemPrefab itemPrefab, StoreTab mode)
|
||||||
{
|
{
|
||||||
var list = mode switch
|
List<PurchasedItem> list = null;
|
||||||
|
try
|
||||||
{
|
{
|
||||||
StoreTab.Buy => CurrentLocation.StoreStock,
|
list = mode switch
|
||||||
StoreTab.Sell => itemsToSell,
|
{
|
||||||
StoreTab.SellFromSub => itemsToSellFromSub,
|
StoreTab.Buy => CurrentLocation?.StoreStock,
|
||||||
_ => throw new NotImplementedException()
|
StoreTab.Sell => itemsToSell,
|
||||||
};
|
StoreTab.SellSub => itemsToSellFromSub,
|
||||||
if (list.Find(i => i.ItemPrefab == itemPrefab) is PurchasedItem item)
|
_ => throw new NotImplementedException()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (NotImplementedException e)
|
||||||
|
{
|
||||||
|
DebugConsole.ShowError($"Error getting item availability: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||||
|
}
|
||||||
|
if (list != null && list.Find(i => i.ItemPrefab == itemPrefab) is PurchasedItem item)
|
||||||
{
|
{
|
||||||
if (mode == StoreTab.Buy)
|
if (mode == StoreTab.Buy)
|
||||||
{
|
{
|
||||||
@@ -1691,8 +1804,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private bool ModifyBuyQuantity(PurchasedItem item, int quantity)
|
private bool ModifyBuyQuantity(PurchasedItem item, int quantity)
|
||||||
{
|
{
|
||||||
if (item == null || item.ItemPrefab == null) { return false; }
|
if (item?.ItemPrefab == null) { return false; }
|
||||||
if (!HasPermissions) { return false; }
|
if (!HasBuyPermissions) { return false; }
|
||||||
if (quantity > 0)
|
if (quantity > 0)
|
||||||
{
|
{
|
||||||
var itemInCrate = CargoManager.ItemsInBuyCrate.Find(i => i.ItemPrefab == item.ItemPrefab);
|
var itemInCrate = CargoManager.ItemsInBuyCrate.Find(i => i.ItemPrefab == item.ItemPrefab);
|
||||||
@@ -1703,13 +1816,13 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
CargoManager.ModifyItemQuantityInBuyCrate(item.ItemPrefab, quantity);
|
CargoManager.ModifyItemQuantityInBuyCrate(item.ItemPrefab, quantity);
|
||||||
GameMain.Client?.SendCampaignState();
|
GameMain.Client?.SendCampaignState();
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ModifySellQuantity(PurchasedItem item, int quantity)
|
private bool ModifySellQuantity(PurchasedItem item, int quantity)
|
||||||
{
|
{
|
||||||
if (item == null || item.ItemPrefab == null) { return false; }
|
if (item?.ItemPrefab == null) { return false; }
|
||||||
if (!HasPermissions) { return false; }
|
if (!HasSellInventoryPermissions) { return false; }
|
||||||
if (quantity > 0)
|
if (quantity > 0)
|
||||||
{
|
{
|
||||||
// Make sure there's enough available to sell
|
// Make sure there's enough available to sell
|
||||||
@@ -1718,45 +1831,68 @@ namespace Barotrauma
|
|||||||
if (totalQuantityToSell > GetMaxAvailable(item.ItemPrefab, StoreTab.Sell)) { return false; }
|
if (totalQuantityToSell > GetMaxAvailable(item.ItemPrefab, StoreTab.Sell)) { return false; }
|
||||||
}
|
}
|
||||||
CargoManager.ModifyItemQuantityInSellCrate(item.ItemPrefab, quantity);
|
CargoManager.ModifyItemQuantityInSellCrate(item.ItemPrefab, quantity);
|
||||||
//GameMain.Client?.SendCampaignState();
|
return true;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ModifySellFromSubQuantity(PurchasedItem item, int quantity)
|
private bool ModifySellFromSubQuantity(PurchasedItem item, int quantity)
|
||||||
{
|
{
|
||||||
if (item == null || item.ItemPrefab == null) { return false; }
|
if (item?.ItemPrefab == null) { return false; }
|
||||||
if (!HasPermissions) { return false; }
|
if (!HasSellSubPermissions) { return false; }
|
||||||
if (quantity > 0)
|
if (quantity > 0)
|
||||||
{
|
{
|
||||||
// Make sure there's enough available to sell
|
// Make sure there's enough available to sell
|
||||||
var itemToSell = CargoManager.ItemsInSellFromSubCrate.Find(i => i.ItemPrefab == item.ItemPrefab);
|
var itemToSell = CargoManager.ItemsInSellFromSubCrate.Find(i => i.ItemPrefab == item.ItemPrefab);
|
||||||
var totalQuantityToSell = itemToSell != null ? itemToSell.Quantity + quantity : quantity;
|
var totalQuantityToSell = itemToSell != null ? itemToSell.Quantity + quantity : quantity;
|
||||||
if (totalQuantityToSell > GetMaxAvailable(item.ItemPrefab, StoreTab.SellFromSub)) { return false; }
|
if (totalQuantityToSell > GetMaxAvailable(item.ItemPrefab, StoreTab.SellSub)) { return false; }
|
||||||
}
|
}
|
||||||
CargoManager.ModifyItemQuantityInSellFromSubCrate(item.ItemPrefab, quantity);
|
CargoManager.ModifyItemQuantityInSellFromSubCrate(item.ItemPrefab, quantity);
|
||||||
// TODO: GameMain.Client?.SendCampaignState();
|
GameMain.Client?.SendCampaignState();
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool AddToShoppingCrate(PurchasedItem item, int quantity = 1) => activeTab switch
|
private bool AddToShoppingCrate(PurchasedItem item, int quantity = 1)
|
||||||
{
|
{
|
||||||
StoreTab.Buy => ModifyBuyQuantity(item, quantity),
|
if (item == null) { return false; }
|
||||||
StoreTab.Sell => ModifySellQuantity(item, quantity),
|
try
|
||||||
StoreTab.SellFromSub => ModifySellFromSubQuantity(item, quantity),
|
{
|
||||||
_ => throw new NotImplementedException(),
|
return activeTab switch
|
||||||
};
|
{
|
||||||
|
StoreTab.Buy => ModifyBuyQuantity(item, quantity),
|
||||||
|
StoreTab.Sell => ModifySellQuantity(item, quantity),
|
||||||
|
StoreTab.SellSub => ModifySellFromSubQuantity(item, quantity),
|
||||||
|
_ => throw new NotImplementedException()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (NotImplementedException e)
|
||||||
|
{
|
||||||
|
DebugConsole.ShowError($"Error adding an item to the shopping crate: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private bool ClearFromShoppingCrate(PurchasedItem item) => activeTab switch
|
private bool ClearFromShoppingCrate(PurchasedItem item)
|
||||||
{
|
{
|
||||||
StoreTab.Buy => ModifyBuyQuantity(item, -item.Quantity),
|
if (item == null) { return false; }
|
||||||
StoreTab.Sell => ModifySellQuantity(item, -item.Quantity),
|
try
|
||||||
StoreTab.SellFromSub => ModifySellFromSubQuantity(item, -item.Quantity),
|
{
|
||||||
_ => throw new NotImplementedException(),
|
return activeTab switch
|
||||||
};
|
{
|
||||||
|
StoreTab.Buy => ModifyBuyQuantity(item, -item.Quantity),
|
||||||
|
StoreTab.Sell => ModifySellQuantity(item, -item.Quantity),
|
||||||
|
StoreTab.SellSub => ModifySellFromSubQuantity(item, -item.Quantity),
|
||||||
|
_ => throw new NotImplementedException(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (NotImplementedException e)
|
||||||
|
{
|
||||||
|
DebugConsole.ShowError($"Error clearing the shopping crate: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private bool BuyItems()
|
private bool BuyItems()
|
||||||
{
|
{
|
||||||
if (!HasPermissions) { return false; }
|
if (!HasBuyPermissions) { return false; }
|
||||||
|
|
||||||
var itemsToPurchase = new List<PurchasedItem>(CargoManager.ItemsInBuyCrate);
|
var itemsToPurchase = new List<PurchasedItem>(CargoManager.ItemsInBuyCrate);
|
||||||
var itemsToRemove = new List<PurchasedItem>();
|
var itemsToRemove = new List<PurchasedItem>();
|
||||||
@@ -1788,15 +1924,24 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private bool SellItems()
|
private bool SellItems()
|
||||||
{
|
{
|
||||||
if (!HasPermissions) { return false; }
|
if (!HasActiveTabPermissions()) { return false; }
|
||||||
var itemsToSell = activeTab switch
|
List<PurchasedItem> itemsToSell;
|
||||||
|
try
|
||||||
{
|
{
|
||||||
StoreTab.Sell => new List<PurchasedItem>(CargoManager.ItemsInSellCrate),
|
itemsToSell = activeTab switch
|
||||||
StoreTab.SellFromSub => new List<PurchasedItem>(CargoManager.ItemsInSellFromSubCrate),
|
{
|
||||||
_ => throw new NotImplementedException()
|
StoreTab.Sell => new List<PurchasedItem>(CargoManager.ItemsInSellCrate),
|
||||||
};
|
StoreTab.SellSub => new List<PurchasedItem>(CargoManager.ItemsInSellFromSubCrate),
|
||||||
|
_ => throw new NotImplementedException()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (NotImplementedException e)
|
||||||
|
{
|
||||||
|
DebugConsole.ShowError($"Error confirming the store transaction: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
var itemsToRemove = new List<PurchasedItem>();
|
var itemsToRemove = new List<PurchasedItem>();
|
||||||
var totalValue = 0;
|
int totalValue = 0;
|
||||||
foreach (PurchasedItem item in itemsToSell)
|
foreach (PurchasedItem item in itemsToSell)
|
||||||
{
|
{
|
||||||
if (item?.ItemPrefab?.GetPriceInfo(CurrentLocation) is PriceInfo priceInfo)
|
if (item?.ItemPrefab?.GetPriceInfo(CurrentLocation) is PriceInfo priceInfo)
|
||||||
@@ -1811,11 +1956,7 @@ namespace Barotrauma
|
|||||||
itemsToRemove.ForEach(i => itemsToSell.Remove(i));
|
itemsToRemove.ForEach(i => itemsToSell.Remove(i));
|
||||||
if (itemsToSell.None() || totalValue > CurrentLocation.StoreCurrentBalance) { return false; }
|
if (itemsToSell.None() || totalValue > CurrentLocation.StoreCurrentBalance) { return false; }
|
||||||
CargoManager.SellItems(itemsToSell, activeTab);
|
CargoManager.SellItems(itemsToSell, activeTab);
|
||||||
if (activeTab == StoreTab.Sell)
|
GameMain.Client?.SendCampaignState();
|
||||||
{
|
|
||||||
// TODO: Implement selling sub items in multiplayer
|
|
||||||
GameMain.Client?.SendCampaignState();
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1831,7 +1972,7 @@ namespace Barotrauma
|
|||||||
int total = activeTab switch
|
int total = activeTab switch
|
||||||
{
|
{
|
||||||
StoreTab.Sell => sellTotal,
|
StoreTab.Sell => sellTotal,
|
||||||
StoreTab.SellFromSub => sellFromSubTotal,
|
StoreTab.SellSub => sellFromSubTotal,
|
||||||
_ => throw new NotImplementedException(),
|
_ => throw new NotImplementedException(),
|
||||||
};
|
};
|
||||||
shoppingCrateTotal.Text = GetCurrencyFormatted(total);
|
shoppingCrateTotal.Text = GetCurrencyFormatted(total);
|
||||||
@@ -1863,21 +2004,29 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetConfirmButtonStatus() => confirmButton.Enabled =
|
private void SetConfirmButtonStatus()
|
||||||
HasPermissions && ActiveShoppingCrateList.Content.RectTransform.Children.Any() &&
|
{
|
||||||
activeTab switch
|
confirmButton.Enabled =
|
||||||
{
|
HasActiveTabPermissions() &&
|
||||||
StoreTab.Buy => buyTotal <= PlayerMoney,
|
ActiveShoppingCrateList.Content.RectTransform.Children.Any() &&
|
||||||
StoreTab.Sell => CurrentLocation != null && sellTotal <= CurrentLocation.StoreCurrentBalance,
|
activeTab switch
|
||||||
StoreTab.SellFromSub => CurrentLocation != null && sellFromSubTotal <= CurrentLocation.StoreCurrentBalance,
|
{
|
||||||
_ => throw new NotImplementedException(),
|
StoreTab.Buy => buyTotal <= PlayerMoney,
|
||||||
};
|
StoreTab.Sell => CurrentLocation != null && sellTotal <= CurrentLocation.StoreCurrentBalance,
|
||||||
|
StoreTab.SellSub => CurrentLocation != null && sellFromSubTotal <= CurrentLocation.StoreCurrentBalance,
|
||||||
|
_ => false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private void SetClearAllButtonStatus() => clearAllButton.Enabled =
|
private void SetClearAllButtonStatus()
|
||||||
HasPermissions && ActiveShoppingCrateList.Content.RectTransform.Children.Any();
|
{
|
||||||
|
clearAllButton.Enabled =
|
||||||
|
HasActiveTabPermissions() &&
|
||||||
|
ActiveShoppingCrateList.Content.RectTransform.Children.Any();
|
||||||
|
}
|
||||||
|
|
||||||
private float ownedItemsUpdateTimer = 0.0f, sellableItemsFromSubUpdateTimer = 0.0f;
|
private float ownedItemsUpdateTimer = 0.0f, sellableItemsFromSubUpdateTimer = 0.0f;
|
||||||
private readonly float timerUpdateInterval = 1.5f;
|
private const float timerUpdateInterval = 1.5f;
|
||||||
|
|
||||||
public void Update(float deltaTime)
|
public void Update(float deltaTime)
|
||||||
{
|
{
|
||||||
@@ -1914,10 +2063,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (needsItemsToSellRefresh) { RefreshItemsToSell(); }
|
if (needsItemsToSellRefresh) { RefreshItemsToSell(); }
|
||||||
if (needsItemsToSellFromSubRefresh) { RefreshItemsToSellFromSub(); }
|
if (needsItemsToSellFromSubRefresh) { RefreshItemsToSellFromSub(); }
|
||||||
if (needsRefresh || hadPermissions != HasPermissions) { Refresh(updateOwned: ownedItemsUpdateTimer > 0.0f); }
|
if (needsRefresh || HavePermissionsChanged()) { Refresh(updateOwned: ownedItemsUpdateTimer > 0.0f); }
|
||||||
if (needsBuyingRefresh) { RefreshBuying(); }
|
if (needsBuyingRefresh || HavePermissionsChanged(StoreTab.Buy)) { RefreshBuying(updateOwned: ownedItemsUpdateTimer > 0.0f); }
|
||||||
if (needsSellingRefresh) { RefreshSelling(); }
|
if (needsSellingRefresh || HavePermissionsChanged(StoreTab.Sell)) { RefreshSelling(updateOwned: ownedItemsUpdateTimer > 0.0f); }
|
||||||
if (needsSellingFromSubRefresh) { RefreshSellingFromSub(updateItemsToSellFromSub: sellableItemsFromSubUpdateTimer > 0.0f); }
|
if (needsSellingFromSubRefresh || HavePermissionsChanged(StoreTab.SellSub)) { RefreshSellingFromSub(updateItemsToSellFromSub: sellableItemsFromSubUpdateTimer > 0.0f); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -414,15 +414,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (GameMain.Client == null)
|
subsToShow.AddRange((GameMain.Client is null ? SubmarineInfo.SavedSubmarines : MultiPlayerCampaign.GetCampaignSubs())
|
||||||
{
|
.Where(s => s.IsCampaignCompatible && !GameMain.GameSession.OwnedSubmarines.Any(os => os.Name == s.Name)));
|
||||||
subsToShow.AddRange(SubmarineInfo.SavedSubmarines.Where(s => s.IsCampaignCompatible && !GameMain.GameSession.OwnedSubmarines.Any(os => os.Name == s.Name)));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
subsToShow.AddRange(GameMain.NetLobbyScreen.CampaignSubmarines.Where(s => !GameMain.GameSession.OwnedSubmarines.Any(os => os.Name == s.Name)));
|
|
||||||
}
|
|
||||||
|
|
||||||
subsToShow.Sort((x, y) => x.SubmarineClass.CompareTo(y.SubmarineClass));
|
subsToShow.Sort((x, y) => x.SubmarineClass.CompareTo(y.SubmarineClass));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -446,20 +439,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (preview == null)
|
if (preview == null)
|
||||||
{
|
{
|
||||||
SubmarineInfo potentialMatch;
|
SubmarineInfo potentialMatch = SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.EqualityCheckVal == info.EqualityCheckVal);
|
||||||
|
|
||||||
if (GameMain.Client == null)
|
|
||||||
{
|
|
||||||
potentialMatch = SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.EqualityCheckVal == info.EqualityCheckVal);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
potentialMatch = GameMain.NetLobbyScreen.CampaignSubmarines.FirstOrDefault(s => s.EqualityCheckVal == info.EqualityCheckVal);
|
|
||||||
}
|
|
||||||
|
|
||||||
preview = potentialMatch?.PreviewImage;
|
preview = potentialMatch?.PreviewImage;
|
||||||
|
|
||||||
// Try from savedsubmarines with name comparison as a backup
|
// Try name comparison as a backup
|
||||||
if (preview == null)
|
if (preview == null)
|
||||||
{
|
{
|
||||||
potentialMatch = SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.Name == info.Name);
|
potentialMatch = SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.Name == info.Name);
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace Barotrauma
|
|||||||
private static Sprite ownerIcon, moderatorIcon;
|
private static Sprite ownerIcon, moderatorIcon;
|
||||||
|
|
||||||
public enum InfoFrameTab { Crew, Mission, Reputation, Traitor, Submarine, Talents };
|
public enum InfoFrameTab { Crew, Mission, Reputation, Traitor, Submarine, Talents };
|
||||||
public static InfoFrameTab selectedTab;
|
public static InfoFrameTab SelectedTab { get; private set; }
|
||||||
private GUIFrame infoFrame, contentFrame;
|
private GUIFrame infoFrame, contentFrame;
|
||||||
|
|
||||||
private readonly List<GUIButton> tabButtons = new List<GUIButton>();
|
private readonly List<GUIButton> tabButtons = new List<GUIButton>();
|
||||||
@@ -129,9 +129,8 @@ namespace Barotrauma
|
|||||||
public TabMenu()
|
public TabMenu()
|
||||||
{
|
{
|
||||||
if (!initialized) { Initialize(); }
|
if (!initialized) { Initialize(); }
|
||||||
|
CreateInfoFrame(SelectedTab);
|
||||||
CreateInfoFrame(selectedTab);
|
SelectInfoFrameTab(SelectedTab);
|
||||||
SelectInfoFrameTab(null, selectedTab);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
@@ -147,8 +146,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedTab != InfoFrameTab.Crew) return;
|
if (SelectedTab != InfoFrameTab.Crew) { return; }
|
||||||
if (linkedGUIList == null) return;
|
if (linkedGUIList == null) { return; }
|
||||||
|
|
||||||
if (GameMain.IsMultiplayer)
|
if (GameMain.IsMultiplayer)
|
||||||
{
|
{
|
||||||
@@ -226,7 +225,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
UserData = tab,
|
UserData = tab,
|
||||||
ToolTip = TextManager.Get(textTag),
|
ToolTip = TextManager.Get(textTag),
|
||||||
OnClicked = SelectInfoFrameTab
|
OnClicked = (btn, userData) => { SelectInfoFrameTab((InfoFrameTab)userData); return true; }
|
||||||
};
|
};
|
||||||
tabButtons.Add(newButton);
|
tabButtons.Add(newButton);
|
||||||
return newButton;
|
return newButton;
|
||||||
@@ -277,16 +276,16 @@ namespace Barotrauma
|
|||||||
talentsButton.Enabled = Character.Controlled?.Info != null;
|
talentsButton.Enabled = Character.Controlled?.Info != null;
|
||||||
if (!talentsButton.Enabled && selectedTab == InfoFrameTab.Talents)
|
if (!talentsButton.Enabled && selectedTab == InfoFrameTab.Talents)
|
||||||
{
|
{
|
||||||
SelectInfoFrameTab(null, InfoFrameTab.Crew);
|
SelectInfoFrameTab(InfoFrameTab.Crew);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
talentPointNotification = GameSession.CreateTalentIconNotification(talentsButton);
|
talentPointNotification = GameSession.CreateTalentIconNotification(talentsButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool SelectInfoFrameTab(GUIButton button, object userData)
|
public void SelectInfoFrameTab(InfoFrameTab selectedTab)
|
||||||
{
|
{
|
||||||
selectedTab = (InfoFrameTab)userData;
|
SelectedTab = selectedTab;
|
||||||
|
|
||||||
CreateInfoFrame(selectedTab);
|
CreateInfoFrame(selectedTab);
|
||||||
tabButtons.ForEach(tb => tb.Selected = (InfoFrameTab)tb.UserData == selectedTab);
|
tabButtons.ForEach(tb => tb.Selected = (InfoFrameTab)tb.UserData == selectedTab);
|
||||||
@@ -300,7 +299,7 @@ namespace Barotrauma
|
|||||||
CreateMissionInfo(infoFrameHolder);
|
CreateMissionInfo(infoFrameHolder);
|
||||||
break;
|
break;
|
||||||
case InfoFrameTab.Reputation:
|
case InfoFrameTab.Reputation:
|
||||||
if (GameMain.GameSession.RoundSummary != null && GameMain.GameSession.GameMode is CampaignMode campaignMode)
|
if (GameMain.GameSession?.RoundSummary != null && GameMain.GameSession?.GameMode is CampaignMode campaignMode)
|
||||||
{
|
{
|
||||||
infoFrameHolder.ClearChildren();
|
infoFrameHolder.ClearChildren();
|
||||||
GUIFrame reputationFrame = new GUIFrame(new RectTransform(Vector2.One, infoFrameHolder.RectTransform, Anchor.TopCenter), style: "GUIFrameListBox");
|
GUIFrame reputationFrame = new GUIFrame(new RectTransform(Vector2.One, infoFrameHolder.RectTransform, Anchor.TopCenter), style: "GUIFrameListBox");
|
||||||
@@ -308,9 +307,9 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case InfoFrameTab.Traitor:
|
case InfoFrameTab.Traitor:
|
||||||
TraitorMissionPrefab traitorMission = GameMain.Client.TraitorMission;
|
TraitorMissionPrefab traitorMission = GameMain.Client?.TraitorMission;
|
||||||
Character traitor = GameMain.Client.Character;
|
Character traitor = GameMain.Client?.Character;
|
||||||
if (traitor == null || traitorMission == null) return false;
|
if (traitor == null || traitorMission == null) { return; }
|
||||||
CreateTraitorInfo(infoFrameHolder, traitorMission, traitor);
|
CreateTraitorInfo(infoFrameHolder, traitorMission, traitor);
|
||||||
break;
|
break;
|
||||||
case InfoFrameTab.Submarine:
|
case InfoFrameTab.Submarine:
|
||||||
@@ -320,8 +319,6 @@ namespace Barotrauma
|
|||||||
CreateTalentInfo(infoFrameHolder);
|
CreateTalentInfo(infoFrameHolder);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private const float jobColumnWidthPercentage = 0.138f;
|
private const float jobColumnWidthPercentage = 0.138f;
|
||||||
@@ -755,7 +752,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (character != null)
|
if (character != null)
|
||||||
{
|
{
|
||||||
if (GameMain.NetworkMember == null)
|
if (GameMain.Client == null)
|
||||||
{
|
{
|
||||||
GUIComponent preview = character.Info.CreateInfoFrame(background, false, null);
|
GUIComponent preview = character.Info.CreateInfoFrame(background, false, null);
|
||||||
}
|
}
|
||||||
@@ -859,7 +856,7 @@ namespace Barotrauma
|
|||||||
string msg = ChatMessage.GetTimeStamp() + message.TextWithSender;
|
string msg = ChatMessage.GetTimeStamp() + message.TextWithSender;
|
||||||
storedMessages.Add(new Pair<string, PlayerConnectionChangeType>(msg, message.ChangeType));
|
storedMessages.Add(new Pair<string, PlayerConnectionChangeType>(msg, message.ChangeType));
|
||||||
|
|
||||||
if (GameSession.IsTabMenuOpen && selectedTab == InfoFrameTab.Crew)
|
if (GameSession.IsTabMenuOpen && SelectedTab == InfoFrameTab.Crew)
|
||||||
{
|
{
|
||||||
TabMenu instance = GameSession.TabMenuInstance;
|
TabMenu instance = GameSession.TabMenuInstance;
|
||||||
instance.AddLineToLog(msg, message.ChangeType);
|
instance.AddLineToLog(msg, message.ChangeType);
|
||||||
@@ -1023,13 +1020,15 @@ namespace Barotrauma
|
|||||||
int iconHeight = Math.Max(missionTextGroup.RectTransform.NonScaledSize.Y, (int)(iconWidth * iconAspectRatio));
|
int iconHeight = Math.Max(missionTextGroup.RectTransform.NonScaledSize.Y, (int)(iconWidth * iconAspectRatio));
|
||||||
Point iconSize = new Point(iconWidth, iconHeight);*/
|
Point iconSize = new Point(iconWidth, iconHeight);*/
|
||||||
|
|
||||||
new GUIImage(new RectTransform(new Point(iconSize), missionDescriptionHolder.RectTransform), mission.Prefab.Icon, null, true)
|
var icon = new GUIImage(new RectTransform(new Point(iconSize), missionDescriptionHolder.RectTransform), mission.Prefab.Icon, null, true)
|
||||||
{
|
{
|
||||||
Color = mission.Prefab.IconColor,
|
Color = mission.Prefab.IconColor,
|
||||||
HoverColor = mission.Prefab.IconColor,
|
HoverColor = mission.Prefab.IconColor,
|
||||||
SelectedColor = mission.Prefab.IconColor,
|
SelectedColor = mission.Prefab.IconColor,
|
||||||
CanBeFocused = false
|
CanBeFocused = false
|
||||||
};
|
};
|
||||||
|
UpdateMissionStateIcon(mission, icon);
|
||||||
|
mission.OnMissionStateChanged += (mission) => UpdateMissionStateIcon(mission, icon);
|
||||||
}
|
}
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionNameRichTextData, missionNameString, font: GUI.LargeFont);
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionNameRichTextData, missionNameString, font: GUI.LargeFont);
|
||||||
GUILayoutGroup difficultyIndicatorGroup = null;
|
GUILayoutGroup difficultyIndicatorGroup = null;
|
||||||
@@ -1066,6 +1065,33 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void UpdateMissionStateIcon(Mission mission, GUIImage missionIcon)
|
||||||
|
{
|
||||||
|
if (mission == null || missionIcon == null) { return; }
|
||||||
|
string style = string.Empty;
|
||||||
|
if (mission.DisplayAsFailed)
|
||||||
|
{
|
||||||
|
style = "MissionFailedIcon";
|
||||||
|
}
|
||||||
|
else if (mission.DisplayAsCompleted)
|
||||||
|
{
|
||||||
|
style = "MissionCompletedIcon";
|
||||||
|
}
|
||||||
|
GUIImage stateIcon = missionIcon.GetChild<GUIImage>();
|
||||||
|
if (string.IsNullOrEmpty(style))
|
||||||
|
{
|
||||||
|
if (stateIcon != null)
|
||||||
|
{
|
||||||
|
stateIcon.Visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stateIcon ??= new GUIImage(new RectTransform(Vector2.One, missionIcon.RectTransform), style, scaleToFit: true);
|
||||||
|
stateIcon.Visible = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void CreateTraitorInfo(GUIFrame infoFrame, TraitorMissionPrefab traitorMission, Character traitor)
|
private void CreateTraitorInfo(GUIFrame infoFrame, TraitorMissionPrefab traitorMission, Character traitor)
|
||||||
{
|
{
|
||||||
GUIFrame missionFrame = new GUIFrame(new RectTransform(Vector2.One, infoFrame.RectTransform, Anchor.TopCenter), style: "GUIFrameListBox");
|
GUIFrame missionFrame = new GUIFrame(new RectTransform(Vector2.One, infoFrame.RectTransform, Anchor.TopCenter), style: "GUIFrameListBox");
|
||||||
@@ -1443,7 +1469,7 @@ namespace Barotrauma
|
|||||||
selectedTalents.Remove(talentIdentifier);
|
selectedTalents.Remove(talentIdentifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateTalentButtons();
|
UpdateTalentInfo();
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -1508,7 +1534,7 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
GUITextBlock.AutoScaleAndNormalize(talentResetButton.TextBlock, talentApplyButton.TextBlock);
|
GUITextBlock.AutoScaleAndNormalize(talentResetButton.TextBlock, talentApplyButton.TextBlock);
|
||||||
|
|
||||||
UpdateTalentButtons();
|
UpdateTalentInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateTalentSkillList(Character character, GUIListBox parent)
|
private void CreateTalentSkillList(Character character, GUIListBox parent)
|
||||||
@@ -1543,30 +1569,14 @@ namespace Barotrauma
|
|||||||
GUITextBlock.AutoScaleAndNormalize(skillNames);
|
GUITextBlock.AutoScaleAndNormalize(skillNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool HasUnlockedAllTalents(Character controlledCharacter)
|
private void UpdateTalentInfo()
|
||||||
{
|
|
||||||
if (TalentTree.JobTalentTrees.TryGetValue(controlledCharacter.Info.Job.Prefab.Identifier, out TalentTree talentTree))
|
|
||||||
{
|
|
||||||
foreach (TalentSubTree talentSubTree in talentTree.TalentSubTrees)
|
|
||||||
{
|
|
||||||
foreach (TalentOption talentOption in talentSubTree.TalentOptionStages)
|
|
||||||
{
|
|
||||||
if (talentOption.Talents.None(t => controlledCharacter.HasTalent(t.Identifier)))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateTalentButtons()
|
|
||||||
{
|
{
|
||||||
Character controlledCharacter = Character.Controlled;
|
Character controlledCharacter = Character.Controlled;
|
||||||
if (controlledCharacter?.Info == null) { return; }
|
if (controlledCharacter?.Info == null) { return; }
|
||||||
|
|
||||||
bool unlockedAllTalents = HasUnlockedAllTalents(controlledCharacter);
|
if (SelectedTab != InfoFrameTab.Talents) { return; }
|
||||||
|
|
||||||
|
bool unlockedAllTalents = controlledCharacter.HasUnlockedAllTalents();
|
||||||
|
|
||||||
if (unlockedAllTalents)
|
if (unlockedAllTalents)
|
||||||
{
|
{
|
||||||
@@ -1646,7 +1656,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
selectedTalents = controlledCharacter.Info.GetUnlockedTalentsInTree().ToList();
|
selectedTalents = controlledCharacter.Info.GetUnlockedTalentsInTree().ToList();
|
||||||
UpdateTalentButtons();
|
UpdateTalentInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ApplyTalentSelection(GUIButton guiButton, object userData)
|
private bool ApplyTalentSelection(GUIButton guiButton, object userData)
|
||||||
@@ -1660,63 +1670,14 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Character controlledCharacter = Character.Controlled;
|
Character controlledCharacter = Character.Controlled;
|
||||||
selectedTalents = controlledCharacter.Info.GetUnlockedTalentsInTree().ToList();
|
selectedTalents = controlledCharacter.Info.GetUnlockedTalentsInTree().ToList();
|
||||||
UpdateTalentButtons();
|
UpdateTalentInfo();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnExperienceChanged(Character character)
|
public void OnExperienceChanged(Character character)
|
||||||
{
|
{
|
||||||
if (character != Character.Controlled) { return; }
|
if (character != Character.Controlled) { return; }
|
||||||
UpdateTalentButtons();
|
UpdateTalentInfo();
|
||||||
}
|
|
||||||
|
|
||||||
private readonly StatTypes[] basicStats = new StatTypes[]
|
|
||||||
{
|
|
||||||
StatTypes.MaximumHealthMultiplier,
|
|
||||||
StatTypes.MovementSpeed,
|
|
||||||
StatTypes.SwimmingSpeed,
|
|
||||||
StatTypes.RepairSpeed,
|
|
||||||
};
|
|
||||||
|
|
||||||
private readonly StatTypes[] combatStats = new StatTypes[]
|
|
||||||
{
|
|
||||||
StatTypes.MeleeAttackMultiplier,
|
|
||||||
StatTypes.MeleeAttackSpeed,
|
|
||||||
StatTypes.RangedAttackSpeed,
|
|
||||||
StatTypes.TurretAttackSpeed,
|
|
||||||
};
|
|
||||||
|
|
||||||
private readonly StatTypes[] miscStats = new StatTypes[]
|
|
||||||
{
|
|
||||||
StatTypes.ReputationGainMultiplier,
|
|
||||||
StatTypes.MissionMoneyGainMultiplier,
|
|
||||||
StatTypes.ExperienceGainMultiplier,
|
|
||||||
StatTypes.MissionExperienceGainMultiplier,
|
|
||||||
};
|
|
||||||
|
|
||||||
private void CreateCharacterSheet(GUILayoutGroup characterInfoColumn)
|
|
||||||
{
|
|
||||||
Character controlledCharacter = Character.Controlled;
|
|
||||||
|
|
||||||
CreateRow(basicStats);
|
|
||||||
CreateRow(combatStats);
|
|
||||||
CreateRow(miscStats);
|
|
||||||
|
|
||||||
void CreateRow(StatTypes[] statTypes)
|
|
||||||
{
|
|
||||||
GUILayoutGroup characterInfoRow = new GUILayoutGroup(new RectTransform(new Vector2(0.33f, 1.0f), characterInfoColumn.RectTransform, anchor: Anchor.TopLeft), childAnchor: Anchor.TopCenter);
|
|
||||||
foreach (StatTypes statType in statTypes)
|
|
||||||
{
|
|
||||||
ShowStat(statType, characterInfoRow);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShowStat(StatTypes statType, GUILayoutGroup characterInfoRow)
|
|
||||||
{
|
|
||||||
GUIFrame textInfoFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.33f), characterInfoRow.RectTransform, Anchor.TopCenter), style: null);
|
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1f, 1f), textInfoFrame.RectTransform, Anchor.TopLeft), statType.ToString(), font: GUI.SmallFont, textAlignment: Alignment.TopLeft);
|
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1f, 1f), textInfoFrame.RectTransform, Anchor.TopLeft), (int)(100f * (1 + controlledCharacter.GetStatValue(statType))) + "%", font: GUI.Font, textAlignment: Alignment.TopRight);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ using Microsoft.Xna.Framework.Input;
|
|||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
|
|
||||||
internal class UpgradeStore
|
internal class UpgradeStore
|
||||||
{
|
{
|
||||||
public readonly struct CategoryData
|
public readonly struct CategoryData
|
||||||
@@ -168,6 +167,7 @@ namespace Barotrauma
|
|||||||
//TODO: move this somewhere else
|
//TODO: move this somewhere else
|
||||||
public static void UpdateCategoryList(GUIListBox categoryList, CampaignMode campaign, Submarine? drawnSubmarine, IEnumerable<UpgradeCategory> applicableCategories)
|
public static void UpdateCategoryList(GUIListBox categoryList, CampaignMode campaign, Submarine? drawnSubmarine, IEnumerable<UpgradeCategory> applicableCategories)
|
||||||
{
|
{
|
||||||
|
var subItems = GetSubItems();
|
||||||
foreach (GUIComponent component in categoryList.Content.Children)
|
foreach (GUIComponent component in categoryList.Content.Children)
|
||||||
{
|
{
|
||||||
if (!(component.UserData is CategoryData data)) { continue; }
|
if (!(component.UserData is CategoryData data)) { continue; }
|
||||||
@@ -179,7 +179,7 @@ namespace Barotrauma
|
|||||||
var customizeButton = component.FindChild("customizebutton", true);
|
var customizeButton = component.FindChild("customizebutton", true);
|
||||||
if (customizeButton != null)
|
if (customizeButton != null)
|
||||||
{
|
{
|
||||||
customizeButton.Visible = HasSwappableItems(data.Category);
|
customizeButton.Visible = HasSwappableItems(data.Category, subItems);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,6 +434,7 @@ namespace Barotrauma
|
|||||||
if (AvailableMoney >= hullRepairCost)
|
if (AvailableMoney >= hullRepairCost)
|
||||||
{
|
{
|
||||||
Campaign.Money -= hullRepairCost;
|
Campaign.Money -= hullRepairCost;
|
||||||
|
GameAnalyticsManager.AddMoneySpentEvent(hullRepairCost, GameAnalyticsManager.MoneySink.Service, "hullrepairs");
|
||||||
Campaign.PurchasedHullRepairs = true;
|
Campaign.PurchasedHullRepairs = true;
|
||||||
button.Enabled = false;
|
button.Enabled = false;
|
||||||
SelectTab(UpgradeTab.Repairs);
|
SelectTab(UpgradeTab.Repairs);
|
||||||
@@ -468,6 +469,7 @@ namespace Barotrauma
|
|||||||
if (AvailableMoney >= itemRepairCost && !Campaign.PurchasedItemRepairs)
|
if (AvailableMoney >= itemRepairCost && !Campaign.PurchasedItemRepairs)
|
||||||
{
|
{
|
||||||
Campaign.Money -= itemRepairCost;
|
Campaign.Money -= itemRepairCost;
|
||||||
|
GameAnalyticsManager.AddMoneySpentEvent(hullRepairCost, GameAnalyticsManager.MoneySink.Service, "devicerepairs");
|
||||||
Campaign.PurchasedItemRepairs = true;
|
Campaign.PurchasedItemRepairs = true;
|
||||||
button.Enabled = false;
|
button.Enabled = false;
|
||||||
SelectTab(UpgradeTab.Repairs);
|
SelectTab(UpgradeTab.Repairs);
|
||||||
@@ -513,6 +515,7 @@ namespace Barotrauma
|
|||||||
if (AvailableMoney >= shuttleRetrieveCost && !Campaign.PurchasedLostShuttles)
|
if (AvailableMoney >= shuttleRetrieveCost && !Campaign.PurchasedLostShuttles)
|
||||||
{
|
{
|
||||||
Campaign.Money -= shuttleRetrieveCost;
|
Campaign.Money -= shuttleRetrieveCost;
|
||||||
|
GameAnalyticsManager.AddMoneySpentEvent(hullRepairCost, GameAnalyticsManager.MoneySink.Service, "retrieveshuttle");
|
||||||
Campaign.PurchasedLostShuttles = true;
|
Campaign.PurchasedLostShuttles = true;
|
||||||
button.Enabled = false;
|
button.Enabled = false;
|
||||||
SelectTab(UpgradeTab.Repairs);
|
SelectTab(UpgradeTab.Repairs);
|
||||||
@@ -717,16 +720,19 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private bool customizeTabOpen;
|
private bool customizeTabOpen;
|
||||||
|
|
||||||
private static bool HasSwappableItems(UpgradeCategory category)
|
private static bool HasSwappableItems(UpgradeCategory category, List<Item>? subItems = null)
|
||||||
{
|
{
|
||||||
if (Submarine.MainSub == null) { return false; }
|
if (Submarine.MainSub == null) { return false; }
|
||||||
return Submarine.MainSub.GetItems(true).Any(i =>
|
subItems ??= GetSubItems();
|
||||||
|
return subItems.Any(i =>
|
||||||
i.Prefab.SwappableItem != null &&
|
i.Prefab.SwappableItem != null &&
|
||||||
!i.HiddenInGame && i.AllowSwapping &&
|
!i.HiddenInGame && i.AllowSwapping &&
|
||||||
(i.Prefab.SwappableItem.CanBeBought || ItemPrefab.Prefabs.Any(ip => ip.SwappableItem?.ReplacementOnUninstall == i.Prefab.Identifier)) &&
|
(i.Prefab.SwappableItem.CanBeBought || ItemPrefab.Prefabs.Any(ip => ip.SwappableItem?.ReplacementOnUninstall == i.Prefab.Identifier)) &&
|
||||||
Submarine.MainSub.IsEntityFoundOnThisSub(i, true) && category.ItemTags.Any(t => i.HasTag(t)));
|
Submarine.MainSub.IsEntityFoundOnThisSub(i, true) && category.ItemTags.Any(t => i.HasTag(t)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static List<Item> GetSubItems() => Submarine.MainSub?.GetItems(true) ?? new List<Item>();
|
||||||
|
|
||||||
private void SelectUpgradeCategory(List<UpgradePrefab> prefabs, UpgradeCategory category, Submarine submarine)
|
private void SelectUpgradeCategory(List<UpgradePrefab> prefabs, UpgradeCategory category, Submarine submarine)
|
||||||
{
|
{
|
||||||
if (selectedUpgradeCategoryLayout == null) { return; }
|
if (selectedUpgradeCategoryLayout == null) { return; }
|
||||||
@@ -1688,7 +1694,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private bool HasPermission => campaignUI.Campaign.AllowedToManageCampaign();
|
private bool HasPermission => campaignUI.Campaign.AllowedToManageCampaign();
|
||||||
|
|
||||||
private static string FormatCurrency(int money, bool format = 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());
|
return TextManager.GetWithVariable("CurrencyFormat", "[credits]", format ? string.Format(CultureInfo.InvariantCulture, "{0:N0}", money) : money.ToString());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ using System.Linq;
|
|||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
public static partial class GameAnalyticsManager
|
static partial class GameAnalyticsManager
|
||||||
{
|
{
|
||||||
static partial void CreateConsentPrompt()
|
static partial void CreateConsentPrompt()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -32,6 +32,13 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public static PerformanceCounter PerformanceCounter;
|
public static PerformanceCounter PerformanceCounter;
|
||||||
|
|
||||||
|
private static Stopwatch performanceCounterTimer;
|
||||||
|
private static int updateCount = 0;
|
||||||
|
public static int CurrentUpdateRate
|
||||||
|
{
|
||||||
|
get; private set;
|
||||||
|
}
|
||||||
|
|
||||||
public static readonly Version Version = Assembly.GetEntryAssembly().GetName().Version;
|
public static readonly Version Version = Assembly.GetEntryAssembly().GetName().Version;
|
||||||
|
|
||||||
public static string[] ConsoleArguments;
|
public static string[] ConsoleArguments;
|
||||||
@@ -124,6 +131,12 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private bool exiting;
|
private bool exiting;
|
||||||
|
|
||||||
|
public static bool IsFirstLaunch
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
private set;
|
||||||
|
}
|
||||||
|
|
||||||
public static GameMain Instance
|
public static GameMain Instance
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
@@ -353,6 +366,8 @@ namespace Barotrauma
|
|||||||
Hyper.ComponentModel.HyperTypeDescriptionProvider.Add(typeof(Item));
|
Hyper.ComponentModel.HyperTypeDescriptionProvider.Add(typeof(Item));
|
||||||
Hyper.ComponentModel.HyperTypeDescriptionProvider.Add(typeof(Items.Components.ItemComponent));
|
Hyper.ComponentModel.HyperTypeDescriptionProvider.Add(typeof(Items.Components.ItemComponent));
|
||||||
Hyper.ComponentModel.HyperTypeDescriptionProvider.Add(typeof(Hull));
|
Hyper.ComponentModel.HyperTypeDescriptionProvider.Add(typeof(Hull));
|
||||||
|
|
||||||
|
performanceCounterTimer = Stopwatch.StartNew();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -441,7 +456,7 @@ namespace Barotrauma
|
|||||||
TaskPool.Add("AutoUpdateWorkshopItemsAsync",
|
TaskPool.Add("AutoUpdateWorkshopItemsAsync",
|
||||||
SteamManager.AutoUpdateWorkshopItemsAsync(), (task) =>
|
SteamManager.AutoUpdateWorkshopItemsAsync(), (task) =>
|
||||||
{
|
{
|
||||||
bool result = ((Task<bool>)task).Result;
|
if (!task.TryGetResult(out bool result)) { return; }
|
||||||
|
|
||||||
Config.WaitingForAutoUpdate = false;
|
Config.WaitingForAutoUpdate = false;
|
||||||
});
|
});
|
||||||
@@ -583,6 +598,18 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Steamworks.SteamFriends.OnGameRichPresenceJoinRequested += OnInvitedToGame;
|
Steamworks.SteamFriends.OnGameRichPresenceJoinRequested += OnInvitedToGame;
|
||||||
Steamworks.SteamFriends.OnGameLobbyJoinRequested += OnLobbyJoinRequested;
|
Steamworks.SteamFriends.OnGameLobbyJoinRequested += OnLobbyJoinRequested;
|
||||||
|
|
||||||
|
if (SteamManager.TryGetUnlockedAchievements(out List<Steamworks.Data.Achievement> achievements))
|
||||||
|
{
|
||||||
|
//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)
|
||||||
|
if (!achievements.Any() && SteamManager.GetStatInt("gamelaunchcount") <= 0)
|
||||||
|
{
|
||||||
|
IsFirstLaunch = true;
|
||||||
|
GameAnalyticsManager.AddDesignEvent("FirstLaunch");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SteamManager.IncrementStat("gamelaunchcount", 1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -700,11 +727,10 @@ namespace Barotrauma
|
|||||||
protected override void Update(GameTime gameTime)
|
protected override void Update(GameTime gameTime)
|
||||||
{
|
{
|
||||||
Timing.Accumulator += gameTime.ElapsedGameTime.TotalSeconds;
|
Timing.Accumulator += gameTime.ElapsedGameTime.TotalSeconds;
|
||||||
int updateIterations = (int)Math.Floor(Timing.Accumulator / Timing.Step);
|
if (Timing.Accumulator > Timing.AccumulatorMax)
|
||||||
if (Timing.Accumulator > Timing.Step * 6.0)
|
|
||||||
{
|
{
|
||||||
//if the game's running too slowly then we have no choice
|
//prevent spiral of death:
|
||||||
//but to skip a bunch of steps
|
//if the game's running too slowly then we have no choice but to skip a bunch of steps
|
||||||
//otherwise it snowballs and becomes unplayable
|
//otherwise it snowballs and becomes unplayable
|
||||||
Timing.Accumulator = Timing.Step;
|
Timing.Accumulator = Timing.Step;
|
||||||
}
|
}
|
||||||
@@ -740,7 +766,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
PlayerInput.Update(Timing.Step);
|
PlayerInput.Update(Timing.Step);
|
||||||
|
|
||||||
|
|
||||||
if (loadingScreenOpen)
|
if (loadingScreenOpen)
|
||||||
{
|
{
|
||||||
//reset accumulator if loading
|
//reset accumulator if loading
|
||||||
@@ -760,7 +785,10 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
CancelQuickStart |= PlayerInput.KeyDown(Keys.LeftShift);
|
if (PlayerInput.KeyHit(Keys.LeftShift))
|
||||||
|
{
|
||||||
|
CancelQuickStart = !CancelQuickStart;
|
||||||
|
}
|
||||||
|
|
||||||
if (TitleScreen.LoadState >= 100.0f && !TitleScreen.PlayingSplashScreen && (Config.AutomaticQuickStartEnabled || Config.AutomaticCampaignLoadEnabled || Config.TestScreenEnabled) && FirstLoad && !CancelQuickStart)
|
if (TitleScreen.LoadState >= 100.0f && !TitleScreen.PlayingSplashScreen && (Config.AutomaticQuickStartEnabled || Config.AutomaticCampaignLoadEnabled || Config.TestScreenEnabled) && FirstLoad && !CancelQuickStart)
|
||||||
{
|
{
|
||||||
@@ -979,13 +1007,21 @@ namespace Barotrauma
|
|||||||
|
|
||||||
Timing.Accumulator -= Timing.Step;
|
Timing.Accumulator -= Timing.Step;
|
||||||
|
|
||||||
|
updateCount++;
|
||||||
|
|
||||||
sw.Stop();
|
sw.Stop();
|
||||||
PerformanceCounter.AddElapsedTicks("Update total", sw.ElapsedTicks);
|
PerformanceCounter.AddElapsedTicks("Update total", sw.ElapsedTicks);
|
||||||
PerformanceCounter.UpdateTimeGraph.Update(sw.ElapsedTicks * 1000.0f / (float)Stopwatch.Frequency);
|
PerformanceCounter.UpdateTimeGraph.Update(sw.ElapsedTicks * 1000.0f / (float)Stopwatch.Frequency);
|
||||||
PerformanceCounter.UpdateIterationsGraph.Update(updateIterations);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Paused) Timing.Alpha = Timing.Accumulator / Timing.Step;
|
if (!Paused) { Timing.Alpha = Timing.Accumulator / Timing.Step; }
|
||||||
|
|
||||||
|
if (performanceCounterTimer.ElapsedMilliseconds > 1000)
|
||||||
|
{
|
||||||
|
CurrentUpdateRate = (int)Math.Round(updateCount / (double)(performanceCounterTimer.ElapsedMilliseconds / 1000.0));
|
||||||
|
performanceCounterTimer.Restart();
|
||||||
|
updateCount = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ResetFrameTime()
|
public static void ResetFrameTime()
|
||||||
@@ -1090,8 +1126,15 @@ 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?.Name ?? "none",
|
GameSession.GameMode?.Preset.Identifier ?? "none",
|
||||||
roundDuration);
|
roundDuration);
|
||||||
|
string eventId = "QuitRound:" + (GameSession.GameMode?.Preset.Identifier ?? "none") + ":";
|
||||||
|
GameAnalyticsManager.AddDesignEvent(eventId + "EventManager:CurrentIntensity", GameSession.EventManager.CurrentIntensity);
|
||||||
|
foreach (var activeEvent in GameSession.EventManager.ActiveEvents)
|
||||||
|
{
|
||||||
|
GameAnalyticsManager.AddDesignEvent(eventId + "EventManager:ActiveEvents:" + activeEvent.ToString());
|
||||||
|
}
|
||||||
|
GameSession.LogEndRoundStats(eventId);
|
||||||
if (Tutorial.Initialized)
|
if (Tutorial.Initialized)
|
||||||
{
|
{
|
||||||
((TutorialMode)GameSession.GameMode).Tutorial?.Stop();
|
((TutorialMode)GameSession.GameMode).Tutorial?.Stop();
|
||||||
@@ -1183,11 +1226,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), linkHolder.RectTransform), TextManager.Get("bugreportgithubform"), style: "MainMenuGUIButton", textAlignment: Alignment.Left)
|
new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), linkHolder.RectTransform), TextManager.Get("bugreportgithubform"), style: "MainMenuGUIButton", textAlignment: Alignment.Left)
|
||||||
{
|
{
|
||||||
#if UNSTABLE
|
|
||||||
UserData = "https://barotraumagame.com/unstable-3rf3w5t4ter/",
|
|
||||||
#else
|
|
||||||
UserData = "https://github.com/Regalis11/Barotrauma/issues/new?template=bug_report.md",
|
UserData = "https://github.com/Regalis11/Barotrauma/issues/new?template=bug_report.md",
|
||||||
#endif
|
|
||||||
OnClicked = (btn, userdata) =>
|
OnClicked = (btn, userdata) =>
|
||||||
{
|
{
|
||||||
ShowOpenUrlInWebBrowserPrompt(userdata as string);
|
ShowOpenUrlInWebBrowserPrompt(userdata as string);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Barotrauma.Extensions;
|
using Barotrauma.Extensions;
|
||||||
using Barotrauma.Items.Components;
|
using Barotrauma.Items.Components;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
@@ -7,37 +8,6 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
partial class CargoManager
|
partial class CargoManager
|
||||||
{
|
{
|
||||||
private class SoldEntity
|
|
||||||
{
|
|
||||||
public enum SellStatus
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Entity sold in SP. Or, entity sold by client and confirmed by server in MP.
|
|
||||||
/// </summary>
|
|
||||||
Confirmed,
|
|
||||||
/// <summary>
|
|
||||||
/// Entity sold by client in MP. Client has received at least one update from server after selling, but this entity wasn't yet confirmed.
|
|
||||||
/// </summary>
|
|
||||||
Unconfirmed,
|
|
||||||
/// <summary>
|
|
||||||
/// Entity sold by client in MP. Client hasn't yet received an update from server after selling.
|
|
||||||
/// </summary>
|
|
||||||
Local
|
|
||||||
}
|
|
||||||
|
|
||||||
public Item Item { get; }
|
|
||||||
public SellStatus Status { get; set; }
|
|
||||||
|
|
||||||
private SoldEntity(Item item, SellStatus status)
|
|
||||||
{
|
|
||||||
Item = item;
|
|
||||||
Status = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SoldEntity CreateInSinglePlayer(Item item) => new SoldEntity(item, SellStatus.Confirmed);
|
|
||||||
public static SoldEntity CreateInMultiPlayer(Item item) => new SoldEntity(item, SellStatus.Local);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<SoldEntity> SoldEntities { get; } = new List<SoldEntity>();
|
private List<SoldEntity> SoldEntities { get; } = new List<SoldEntity>();
|
||||||
|
|
||||||
// The bag slot is intentionally left out since we want to be able to sell items from there
|
// The bag slot is intentionally left out since we want to be able to sell items from there
|
||||||
@@ -67,31 +37,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Item> GetSellableItemsFromSub()
|
|
||||||
{
|
|
||||||
if (Submarine.MainSub == null) { return new List<Item>(); }
|
|
||||||
var confirmedSoldEntities = GetConfirmedSoldEntities();
|
|
||||||
return Submarine.MainSub.GetItems(true).FindAll(item =>
|
|
||||||
{
|
|
||||||
if (!IsItemSellable(item, confirmedSoldEntities)) { return false; }
|
|
||||||
if (item.GetRootInventoryOwner() is Character) { return false; }
|
|
||||||
if (!item.Components.All(c => !(c is Holdable h) || !h.Attachable || !h.Attached)) { return false; }
|
|
||||||
if (!item.Components.All(c => !(c is Wire w) || w.Connections.All(c => c == null))) { return false; }
|
|
||||||
if (!ItemAndAllContainersInteractable(item)) { return false; }
|
|
||||||
return true;
|
|
||||||
}).Distinct();
|
|
||||||
|
|
||||||
static bool ItemAndAllContainersInteractable(Item item)
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (!item.IsPlayerTeamInteractable) { return false; }
|
|
||||||
item = item.Container;
|
|
||||||
} while (item != null);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerable<SoldEntity> GetConfirmedSoldEntities()
|
private IEnumerable<SoldEntity> GetConfirmedSoldEntities()
|
||||||
{
|
{
|
||||||
// Only consider items which have been:
|
// Only consider items which have been:
|
||||||
@@ -100,24 +45,6 @@ namespace Barotrauma
|
|||||||
return SoldEntities.Where(se => se.Status != SoldEntity.SellStatus.Unconfirmed);
|
return SoldEntities.Where(se => se.Status != SoldEntity.SellStatus.Unconfirmed);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsItemSellable(Item item, IEnumerable<SoldEntity> confirmedSoldEntities)
|
|
||||||
{
|
|
||||||
if (!item.Prefab.CanBeSold) { return false; }
|
|
||||||
if (item.SpawnedInCurrentOutpost) { return false; }
|
|
||||||
if (!item.Prefab.AllowSellingWhenBroken && item.ConditionPercentage < 90.0f) { return false; }
|
|
||||||
if (confirmedSoldEntities.Any(it => it.Item == item)) { return false; }
|
|
||||||
if (item.OwnInventory?.Container is ItemContainer itemContainer)
|
|
||||||
{
|
|
||||||
var containedItems = item.ContainedItems;
|
|
||||||
if (containedItems.None()) { return true; }
|
|
||||||
// Allow selling the item if contained items are unsellable and set to be removed on deconstruct
|
|
||||||
if (itemContainer.RemoveContainedItemsOnDeconstruct && containedItems.All(it => !it.Prefab.CanBeSold)) { return true; }
|
|
||||||
// Otherwise there must be no contained items or the contained items must be confirmed as sold
|
|
||||||
if (!containedItems.All(it => confirmedSoldEntities.Any(se => se.Item == it))) { return false; }
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetItemsInBuyCrate(List<PurchasedItem> items)
|
public void SetItemsInBuyCrate(List<PurchasedItem> items)
|
||||||
{
|
{
|
||||||
ItemsInBuyCrate.Clear();
|
ItemsInBuyCrate.Clear();
|
||||||
@@ -125,15 +52,21 @@ namespace Barotrauma
|
|||||||
OnItemsInBuyCrateChanged?.Invoke();
|
OnItemsInBuyCrateChanged?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetItemsInSubSellCrate(List<PurchasedItem> items)
|
||||||
|
{
|
||||||
|
ItemsInSellFromSubCrate.Clear();
|
||||||
|
ItemsInSellFromSubCrate.AddRange(items);
|
||||||
|
OnItemsInSellFromSubCrateChanged?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
public void SetSoldItems(List<SoldItem> items)
|
public void SetSoldItems(List<SoldItem> items)
|
||||||
{
|
{
|
||||||
SoldItems.Clear();
|
SoldItems.Clear();
|
||||||
SoldItems.AddRange(items);
|
SoldItems.AddRange(items);
|
||||||
|
foreach (var se in SoldEntities)
|
||||||
foreach (SoldEntity se in SoldEntities)
|
|
||||||
{
|
{
|
||||||
if (se.Status == SoldEntity.SellStatus.Confirmed) { continue; }
|
if (se.Status == SoldEntity.SellStatus.Confirmed) { continue; }
|
||||||
if (SoldItems.Any(si => si.ID == se.Item.ID && si.ItemPrefab == se.Item.Prefab && (GameMain.Client == null || GameMain.Client.ID == si.SellerID)))
|
if (SoldItems.Any(si => Match(si, se, true)))
|
||||||
{
|
{
|
||||||
se.Status = SoldEntity.SellStatus.Confirmed;
|
se.Status = SoldEntity.SellStatus.Confirmed;
|
||||||
}
|
}
|
||||||
@@ -142,13 +75,28 @@ namespace Barotrauma
|
|||||||
se.Status = SoldEntity.SellStatus.Unconfirmed;
|
se.Status = SoldEntity.SellStatus.Unconfirmed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
foreach (var si in SoldItems)
|
||||||
|
{
|
||||||
|
if (si.Origin != SoldItem.SellOrigin.Submarine) { continue; }
|
||||||
|
if (!(SoldEntities.FirstOrDefault(se => se.Item == null && Match(si, se, false)) is SoldEntity soldEntityMatch)) { continue; }
|
||||||
|
if (!(Entity.FindEntityByID(si.ID) is Item item)) { continue; }
|
||||||
|
soldEntityMatch.SetItem(item);
|
||||||
|
soldEntityMatch.Status = SoldEntity.SellStatus.Confirmed;
|
||||||
|
}
|
||||||
OnSoldItemsChanged?.Invoke();
|
OnSoldItemsChanged?.Invoke();
|
||||||
|
|
||||||
|
static bool Match(SoldItem soldItem, SoldEntity soldEntity, bool matchId)
|
||||||
|
{
|
||||||
|
if (soldItem.ItemPrefab != soldEntity.ItemPrefab) { return false; }
|
||||||
|
if (matchId && (soldEntity.Item == null || soldItem.ID != soldEntity.Item.ID)) { return false; }
|
||||||
|
if (soldItem.Origin == SoldItem.SellOrigin.Character && GameMain.Client != null && soldItem.SellerID != GameMain.Client.ID) { return false; }
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ModifyItemQuantityInSellCrate(ItemPrefab itemPrefab, int changeInQuantity)
|
public void ModifyItemQuantityInSellCrate(ItemPrefab itemPrefab, int changeInQuantity)
|
||||||
{
|
{
|
||||||
PurchasedItem itemToSell = ItemsInSellCrate.Find(i => i.ItemPrefab == itemPrefab);
|
var itemToSell = ItemsInSellCrate.Find(i => i.ItemPrefab == itemPrefab);
|
||||||
if (itemToSell != null)
|
if (itemToSell != null)
|
||||||
{
|
{
|
||||||
itemToSell.Quantity += changeInQuantity;
|
itemToSell.Quantity += changeInQuantity;
|
||||||
@@ -186,72 +134,69 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void SellItems(List<PurchasedItem> itemsToSell, Store.StoreTab sellingMode)
|
public void SellItems(List<PurchasedItem> itemsToSell, Store.StoreTab sellingMode)
|
||||||
{
|
{
|
||||||
var sellableItems = sellingMode switch
|
IEnumerable<Item> sellableItems;
|
||||||
|
try
|
||||||
{
|
{
|
||||||
Store.StoreTab.Sell => GetSellableItems(Character.Controlled),
|
sellableItems = sellingMode switch
|
||||||
Store.StoreTab.SellFromSub => GetSellableItemsFromSub(),
|
{
|
||||||
_ => throw new System.NotImplementedException(),
|
Store.StoreTab.Sell => GetSellableItems(Character.Controlled),
|
||||||
};
|
Store.StoreTab.SellSub => GetSellableItemsFromSub(),
|
||||||
|
_ => throw new NotImplementedException()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (NotImplementedException e)
|
||||||
|
{
|
||||||
|
DebugConsole.ShowError($"Error selling items: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
bool canAddToRemoveQueue = campaign.IsSinglePlayer && Entity.Spawner != null;
|
bool canAddToRemoveQueue = campaign.IsSinglePlayer && Entity.Spawner != null;
|
||||||
var 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
|
||||||
Dictionary<ItemPrefab, int> sellValues = GetSellValuesAtCurrentLocation(itemsToSell.Select(i => i.ItemPrefab));
|
Dictionary<ItemPrefab, int> sellValues = GetSellValuesAtCurrentLocation(itemsToSell.Select(i => i.ItemPrefab));
|
||||||
|
|
||||||
foreach (PurchasedItem item in itemsToSell)
|
foreach (PurchasedItem item in itemsToSell)
|
||||||
{
|
{
|
||||||
var 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 (Location.StoreCurrentBalance < 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);
|
||||||
if (matchingItems.Count() <= item.Quantity)
|
int count = Math.Min(item.Quantity, matchingItems.Count());
|
||||||
|
SoldItem.SellOrigin origin = sellingMode == Store.StoreTab.Sell ? SoldItem.SellOrigin.Character : SoldItem.SellOrigin.Submarine;
|
||||||
|
if (origin == SoldItem.SellOrigin.Character || GameMain.IsSingleplayer)
|
||||||
{
|
{
|
||||||
foreach (Item i in matchingItems)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
SoldItems.Add(new SoldItem(i.Prefab, i.ID, canAddToRemoveQueue, sellerId));
|
var matchingItem = matchingItems.ElementAt(i);
|
||||||
SoldEntities.Add(campaign.IsSinglePlayer ? SoldEntity.CreateInSinglePlayer(i) : SoldEntity.CreateInMultiPlayer(i));
|
SoldItems.Add(new SoldItem(matchingItem.Prefab, matchingItem.ID, canAddToRemoveQueue, sellerId, origin));
|
||||||
if (canAddToRemoveQueue) { Entity.Spawner.AddToRemoveQueue(i); }
|
SoldEntities.Add(new SoldEntity(matchingItem, campaign.IsSinglePlayer ? SoldEntity.SellStatus.Confirmed : SoldEntity.SellStatus.Local));
|
||||||
|
if (canAddToRemoveQueue) { Entity.Spawner.AddToRemoveQueue(matchingItem); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int i = 0; i < item.Quantity; i++)
|
// When selling from the sub in multiplayer, the server will determine the items that are sold
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
var matchingItem = matchingItems.ElementAt(i);
|
SoldItems.Add(new SoldItem(item.ItemPrefab, Entity.NullEntityID, canAddToRemoveQueue, sellerId, origin));
|
||||||
SoldItems.Add(new SoldItem(matchingItem.Prefab, matchingItem.ID, canAddToRemoveQueue, sellerId));
|
SoldEntities.Add(new SoldEntity(item.ItemPrefab, SoldEntity.SellStatus.Local));
|
||||||
SoldEntities.Add(campaign.IsSinglePlayer ? SoldEntity.CreateInSinglePlayer(matchingItem) : SoldEntity.CreateInMultiPlayer(matchingItem));
|
|
||||||
if (canAddToRemoveQueue) { Entity.Spawner.AddToRemoveQueue(matchingItem); }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exchange money
|
// Exchange money
|
||||||
Location.StoreCurrentBalance -= itemValue;
|
Location.StoreCurrentBalance -= itemValue;
|
||||||
campaign.Money += itemValue;
|
campaign.Money += itemValue;
|
||||||
|
GameAnalyticsManager.AddMoneyGainedEvent(itemValue, GameAnalyticsManager.MoneySource.Store, item.ItemPrefab.Identifier);
|
||||||
|
|
||||||
// Remove from the sell crate
|
// Remove from the sell crate
|
||||||
// TODO: Simplify duplicate logic?
|
if ((sellingMode == Store.StoreTab.Sell ? ItemsInSellCrate : ItemsInSellFromSubCrate)?.Find(pi => pi.ItemPrefab == item.ItemPrefab) is { } itemToSell)
|
||||||
if (sellingMode == Store.StoreTab.Sell && ItemsInSellCrate.Find(pi => pi.ItemPrefab == item.ItemPrefab) is { } inventoryItem)
|
|
||||||
{
|
{
|
||||||
inventoryItem.Quantity -= item.Quantity;
|
itemToSell.Quantity -= item.Quantity;
|
||||||
if (inventoryItem.Quantity < 1)
|
if (itemToSell.Quantity < 1)
|
||||||
{
|
{
|
||||||
ItemsInSellCrate.Remove(inventoryItem);
|
(sellingMode == Store.StoreTab.Sell ? ItemsInSellCrate : ItemsInSellFromSubCrate)?.Remove(itemToSell);
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(sellingMode == Store.StoreTab.SellFromSub && ItemsInSellFromSubCrate.Find(pi => pi.ItemPrefab == item.ItemPrefab) is { } subItem)
|
|
||||||
{
|
|
||||||
subItem.Quantity -= item.Quantity;
|
|
||||||
if (subItem.Quantity < 1)
|
|
||||||
{
|
|
||||||
ItemsInSellFromSubCrate.Remove(subItem);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OnSoldItemsChanged?.Invoke();
|
OnSoldItemsChanged?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
partial void InitProjectSpecific()
|
partial void InitProjectSpecific()
|
||||||
{
|
{
|
||||||
guiFrame = new GUIFrame(new RectTransform(Vector2.One, GUICanvas.Instance), null, Color.Transparent)
|
guiFrame = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas), null, Color.Transparent)
|
||||||
{
|
{
|
||||||
CanBeFocused = false
|
CanBeFocused = false
|
||||||
};
|
};
|
||||||
@@ -145,12 +145,14 @@ namespace Barotrauma
|
|||||||
string msgCommand = ChatMessage.GetChatMessageCommand(text, out string msg);
|
string msgCommand = ChatMessage.GetChatMessageCommand(text, out string msg);
|
||||||
// add to local history
|
// add to local history
|
||||||
ChatBox.ChatManager.Store(text);
|
ChatBox.ChatManager.Store(text);
|
||||||
|
WifiComponent headset = null;
|
||||||
|
ChatMessageType messageType =
|
||||||
|
((msgCommand == "r" || msgCommand == "radio") && ChatMessage.CanUseRadio(Character.Controlled, out headset)) ? ChatMessageType.Radio : ChatMessageType.Default;
|
||||||
AddSinglePlayerChatMessage(
|
AddSinglePlayerChatMessage(
|
||||||
Character.Controlled.Info.Name,
|
Character.Controlled.Info.Name,
|
||||||
msg,
|
msg, messageType,
|
||||||
((msgCommand == "r" || msgCommand == "radio") && ChatMessage.CanUseRadio(Character.Controlled)) ? ChatMessageType.Radio : ChatMessageType.Default,
|
|
||||||
Character.Controlled);
|
Character.Controlled);
|
||||||
if (ChatMessage.CanUseRadio(Character.Controlled, out WifiComponent headset))
|
if (messageType == ChatMessageType.Radio && headset != null)
|
||||||
{
|
{
|
||||||
Signal s = new Signal(msg, sender: Character.Controlled, source: headset.Item);
|
Signal s = new Signal(msg, sender: Character.Controlled, source: headset.Item);
|
||||||
headset.TransmitSignal(s, sentFromChat: true);
|
headset.TransmitSignal(s, sentFromChat: true);
|
||||||
@@ -302,7 +304,7 @@ namespace Barotrauma
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="character">The character to remove</param>
|
/// <param name="character">The character to remove</param>
|
||||||
/// <param name="removeInfo">If the character info is also removed, the character will not be visible in the round summary.</param>
|
/// <param name="removeInfo">If the character info is also removed, the character will not be visible in the round summary.</param>
|
||||||
public void RemoveCharacter(Character character, bool removeInfo = false)
|
public void RemoveCharacter(Character character, bool removeInfo = false, bool resetCrewListIndex = true)
|
||||||
{
|
{
|
||||||
if (character == null)
|
if (character == null)
|
||||||
{
|
{
|
||||||
@@ -311,14 +313,15 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
characters.Remove(character);
|
characters.Remove(character);
|
||||||
if (removeInfo) { characterInfos.Remove(character.Info); }
|
if (removeInfo) { characterInfos.Remove(character.Info); }
|
||||||
|
if (resetCrewListIndex) { ResetCrewListIndex(character); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add character to the list without actually adding it to the crew
|
/// Add character to the list without actually adding it to the crew
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void AddCharacterToCrewList(Character character)
|
public GUIComponent AddCharacterToCrewList(Character character)
|
||||||
{
|
{
|
||||||
if (character == null) { return; }
|
if (character == null) { return null; }
|
||||||
|
|
||||||
var background = new GUIFrame(
|
var background = new GUIFrame(
|
||||||
new RectTransform(crewListEntrySize, parent: crewList.Content.RectTransform, anchor: Anchor.TopRight),
|
new RectTransform(crewListEntrySize, parent: crewList.Content.RectTransform, anchor: Anchor.TopRight),
|
||||||
@@ -510,6 +513,8 @@ namespace Barotrauma
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return background;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetCharacterComponentTooltip(GUIComponent characterComponent)
|
private void SetCharacterComponentTooltip(GUIComponent characterComponent)
|
||||||
@@ -549,13 +554,13 @@ namespace Barotrauma
|
|||||||
if (characterInfos.Contains(revivedCharacter.Info)) { AddCharacter(revivedCharacter); }
|
if (characterInfos.Contains(revivedCharacter.Info)) { AddCharacter(revivedCharacter); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public void KillCharacter(Character killedCharacter)
|
public void KillCharacter(Character killedCharacter, bool resetCrewListIndex = true)
|
||||||
{
|
{
|
||||||
if (crewList.Content.GetChildByUserData(killedCharacter) is GUIComponent characterComponent)
|
if (crewList.Content.GetChildByUserData(killedCharacter) is GUIComponent characterComponent)
|
||||||
{
|
{
|
||||||
CoroutineManager.StartCoroutine(KillCharacterAnim(characterComponent));
|
CoroutineManager.StartCoroutine(KillCharacterAnim(characterComponent));
|
||||||
}
|
}
|
||||||
RemoveCharacter(killedCharacter);
|
RemoveCharacter(killedCharacter, resetCrewListIndex: resetCrewListIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<CoroutineStatus> KillCharacterAnim(GUIComponent component)
|
private IEnumerable<CoroutineStatus> KillCharacterAnim(GUIComponent component)
|
||||||
@@ -601,9 +606,53 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (crewList != this.crewList) { return; }
|
if (crewList != this.crewList) { return; }
|
||||||
if (!(draggedElementData is Character)) { return; }
|
if (!(draggedElementData is Character)) { return; }
|
||||||
if (crewList.HasDraggedElementIndexChanged) { return; }
|
|
||||||
if (!IsSinglePlayer) { return; }
|
if (!IsSinglePlayer) { return; }
|
||||||
CharacterClicked(crewList.DraggedElement, draggedElementData);
|
if (crewList.HasDraggedElementIndexChanged)
|
||||||
|
{
|
||||||
|
UpdateCrewListIndices();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CharacterClicked(crewList.DraggedElement, draggedElementData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ResetCrewListIndex(Character c)
|
||||||
|
{
|
||||||
|
if (c?.Info == null) { return; }
|
||||||
|
c.Info.CrewListIndex = -1;
|
||||||
|
UpdateCrewListIndices();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateCrewListIndices()
|
||||||
|
{
|
||||||
|
if (crewList == null) { return; }
|
||||||
|
for (int i = 0; i < crewList.Content.CountChildren; i++)
|
||||||
|
{
|
||||||
|
var characterComponent = crewList.Content.GetChild(i);
|
||||||
|
if (!(characterComponent?.UserData is Character c)) { continue; }
|
||||||
|
if (c.Info == null) { continue; }
|
||||||
|
c.Info.CrewListIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SortCrewList()
|
||||||
|
{
|
||||||
|
if (crewList == null) { return; }
|
||||||
|
crewList.Content.RectTransform.SortChildren((x, y) =>
|
||||||
|
{
|
||||||
|
var infoX = (x.GUIComponent.UserData as Character)?.Info?.CrewListIndex;
|
||||||
|
var infoY = (y.GUIComponent.UserData as Character)?.Info?.CrewListIndex;
|
||||||
|
if (infoX.HasValue)
|
||||||
|
{
|
||||||
|
return infoY.HasValue ? infoX.Value.CompareTo(infoY.Value) : -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return infoY.HasValue ? 1 : 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
UpdateCrewListIndices();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -718,7 +767,7 @@ namespace Barotrauma
|
|||||||
/// Sets the character's current order (if it's close enough to receive messages from orderGiver) and
|
/// Sets the character's current order (if it's close enough to receive messages from orderGiver) and
|
||||||
/// displays the order in the crew UI
|
/// displays the order in the crew UI
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SetCharacterOrder(Character character, Order order, string option, int priority, Character orderGiver, Hull targetHull = null)
|
public void SetCharacterOrder(Character character, Order order, string option, int priority, Character orderGiver, Hull targetHull = null, bool isNewOrder = true)
|
||||||
{
|
{
|
||||||
if (order != null && order.TargetAllCharacters)
|
if (order != null && order.TargetAllCharacters)
|
||||||
{
|
{
|
||||||
@@ -768,11 +817,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (IsSinglePlayer)
|
if (IsSinglePlayer)
|
||||||
{
|
{
|
||||||
orderGiver.Speak(order.GetChatMessage("", hull?.DisplayName, givingOrderToSelf: character == orderGiver), ChatMessageType.Order);
|
orderGiver.Speak(order.GetChatMessage("", hull?.DisplayName, givingOrderToSelf: character == orderGiver, isNewOrder: isNewOrder), ChatMessageType.Order);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OrderChatMessage msg = new OrderChatMessage(order, "", priority, order.IsReport ? hull : order.TargetEntity, null, orderGiver);
|
OrderChatMessage msg = new OrderChatMessage(order, "", priority, order.IsReport ? hull : order.TargetEntity, null, orderGiver, isNewOrder: isNewOrder);
|
||||||
GameMain.Client?.SendChatMessage(msg);
|
GameMain.Client?.SendChatMessage(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -784,12 +833,12 @@ namespace Barotrauma
|
|||||||
if (IsSinglePlayer)
|
if (IsSinglePlayer)
|
||||||
{
|
{
|
||||||
character.SetOrder(order, option, priority, orderGiver, speak: orderGiver != character);
|
character.SetOrder(order, option, priority, orderGiver, speak: orderGiver != character);
|
||||||
string message = order?.GetChatMessage(character.Name, orderGiver?.CurrentHull?.DisplayName, givingOrderToSelf: character == orderGiver, orderOption: option, priority: priority);
|
string message = order?.GetChatMessage(character.Name, orderGiver?.CurrentHull?.DisplayName, givingOrderToSelf: character == orderGiver, orderOption: option, isNewOrder: isNewOrder);
|
||||||
orderGiver?.Speak(message);
|
orderGiver?.Speak(message);
|
||||||
}
|
}
|
||||||
else if (orderGiver != null)
|
else if (orderGiver != null)
|
||||||
{
|
{
|
||||||
OrderChatMessage msg = new OrderChatMessage(order, option, priority, order?.TargetSpatialEntity ?? order?.TargetItemComponent?.Item, character, orderGiver);
|
OrderChatMessage msg = new OrderChatMessage(order, option, priority, order?.TargetSpatialEntity ?? order?.TargetItemComponent?.Item, character, orderGiver, isNewOrder: isNewOrder);
|
||||||
GameMain.Client?.SendChatMessage(msg);
|
GameMain.Client?.SendChatMessage(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1071,13 +1120,19 @@ namespace Barotrauma
|
|||||||
var priority = Math.Max(CharacterInfo.HighestManualOrderPriority - orderList.Content.GetChildIndex(orderComponent), 1);
|
var priority = Math.Max(CharacterInfo.HighestManualOrderPriority - orderList.Content.GetChildIndex(orderComponent), 1);
|
||||||
if (orderInfo.ManualPriority == priority) { return; }
|
if (orderInfo.ManualPriority == priority) { return; }
|
||||||
var character = (Character)orderList.UserData;
|
var character = (Character)orderList.UserData;
|
||||||
SetCharacterOrder(character, orderInfo.Order, orderInfo.OrderOption, priority, Character.Controlled);
|
SetCharacterOrder(character, orderInfo.Order, orderInfo.OrderOption, priority, Character.Controlled, isNewOrder: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string CreateOrderTooltip(Order orderPrefab, string option, Entity targetEntity)
|
private string CreateOrderTooltip(Order orderPrefab, string option, Entity targetEntity)
|
||||||
{
|
{
|
||||||
if (orderPrefab == null) { return ""; }
|
if (orderPrefab == null) { return ""; }
|
||||||
if (!string.IsNullOrEmpty(option))
|
if (orderPrefab.DisplayGiverInTooltip && orderPrefab.OrderGiver != null)
|
||||||
|
{
|
||||||
|
return TextManager.GetWithVariables("crewlistordericontooltip",
|
||||||
|
new string[2] { "[ordername]", "[orderoption]" },
|
||||||
|
new string[2] { orderPrefab.Name, orderPrefab.OrderGiver.DisplayName });
|
||||||
|
}
|
||||||
|
else if (!string.IsNullOrEmpty(option))
|
||||||
{
|
{
|
||||||
return TextManager.GetWithVariables("crewlistordericontooltip",
|
return TextManager.GetWithVariables("crewlistordericontooltip",
|
||||||
new string[2] { "[ordername]", "[orderoption]" },
|
new string[2] { "[ordername]", "[orderoption]" },
|
||||||
@@ -1210,6 +1265,10 @@ namespace Barotrauma
|
|||||||
DisableCommandUI();
|
DisableCommandUI();
|
||||||
Character.Controlled = character;
|
Character.Controlled = character;
|
||||||
HintManager.OnChangeCharacter();
|
HintManager.OnChangeCharacter();
|
||||||
|
if (GameSession.TabMenuInstance != null && TabMenu.SelectedTab == TabMenu.InfoFrameTab.Talents)
|
||||||
|
{
|
||||||
|
GameSession.TabMenuInstance.SelectInfoFrameTab(TabMenu.SelectedTab);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int TryAdjustIndex(int amount)
|
private int TryAdjustIndex(int amount)
|
||||||
@@ -1566,10 +1625,28 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
crewList.Select(character, force: true);
|
crewList.Select(character, force: true);
|
||||||
}
|
}
|
||||||
|
// Icon colors might change based on the target so we check if they need to be updated
|
||||||
|
if (GetCurrentOrderIconList(characterComponent) is GUIListBox currentOrderIconList)
|
||||||
|
{
|
||||||
|
foreach (var orderIcon in currentOrderIconList.Content.Children)
|
||||||
|
{
|
||||||
|
if (!(orderIcon.UserData is OrderInfo orderInfo)) { continue; }
|
||||||
|
if (!(orderInfo.Order is Order order)) { continue; }
|
||||||
|
if (order.ColoredWhenControllingGiver && order.OrderGiver != Character.Controlled)
|
||||||
|
{
|
||||||
|
orderIcon.Color = AIObjective.ObjectiveIconColor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
orderIcon.Color = order.Color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Only update the order highlights and objective icons here in singleplayer
|
||||||
|
// The server will let the clients know when they need to update in multiplayer
|
||||||
if (GameMain.IsSingleplayer && character.IsBot && character.AIController is HumanAIController controller &&
|
if (GameMain.IsSingleplayer && character.IsBot && character.AIController is HumanAIController controller &&
|
||||||
controller.ObjectiveManager is AIObjectiveManager objectiveManager)
|
controller.ObjectiveManager is AIObjectiveManager objectiveManager)
|
||||||
{
|
{
|
||||||
// In multiplayer, these are set through character networking (the server lets the clients now when these are updated)
|
|
||||||
if (objectiveManager.CurrentObjective is AIObjective currentObjective)
|
if (objectiveManager.CurrentObjective is AIObjective currentObjective)
|
||||||
{
|
{
|
||||||
if (objectiveManager.IsOrder(currentObjective))
|
if (objectiveManager.IsOrder(currentObjective))
|
||||||
@@ -1638,8 +1715,8 @@ namespace Barotrauma
|
|||||||
bool foundMatch = false;
|
bool foundMatch = false;
|
||||||
foreach (var orderIcon in currentOrderIconList.Content.Children)
|
foreach (var orderIcon in currentOrderIconList.Content.Children)
|
||||||
{
|
{
|
||||||
var glowComponent = orderIcon.GetChildByUserData("glow");
|
if (!(orderIcon.GetChildByUserData("glow") is GUIComponent glowComponent)) { continue; }
|
||||||
if (glowComponent == null) { continue; }
|
glowComponent.Color = orderIcon.Color;
|
||||||
if (foundMatch)
|
if (foundMatch)
|
||||||
{
|
{
|
||||||
glowComponent.Visible = false;
|
glowComponent.Visible = false;
|
||||||
@@ -1684,11 +1761,11 @@ namespace Barotrauma
|
|||||||
objectiveIconFrame.ClearChildren();
|
objectiveIconFrame.ClearChildren();
|
||||||
if (sprite != null)
|
if (sprite != null)
|
||||||
{
|
{
|
||||||
var objectiveIcon = CreateNodeIcon(Vector2.One, objectiveIconFrame.RectTransform, sprite, Color.LightGray, tooltip: tooltip);
|
var objectiveIcon = CreateNodeIcon(Vector2.One, objectiveIconFrame.RectTransform, sprite, AIObjective.ObjectiveIconColor, tooltip: tooltip);
|
||||||
new GUIFrame(new RectTransform(new Vector2(1.5f), objectiveIcon.RectTransform, anchor: Anchor.Center), style: "OuterGlowCircular")
|
new GUIFrame(new RectTransform(new Vector2(1.5f), objectiveIcon.RectTransform, anchor: Anchor.Center), style: "OuterGlowCircular")
|
||||||
{
|
{
|
||||||
CanBeFocused = false,
|
CanBeFocused = false,
|
||||||
Color = Color.LightGray
|
Color = AIObjective.ObjectiveIconColor
|
||||||
};
|
};
|
||||||
objectiveIconFrame.Visible = true;
|
objectiveIconFrame.Visible = true;
|
||||||
}
|
}
|
||||||
@@ -1909,7 +1986,7 @@ namespace Barotrauma
|
|||||||
ScaleCommandUI();
|
ScaleCommandUI();
|
||||||
|
|
||||||
commandFrame = new GUIFrame(
|
commandFrame = new GUIFrame(
|
||||||
new RectTransform(Vector2.One, GUICanvas.Instance, anchor: Anchor.Center),
|
new RectTransform(Vector2.One, GUI.Canvas, anchor: Anchor.Center),
|
||||||
style: null,
|
style: null,
|
||||||
color: Color.Transparent);
|
color: Color.Transparent);
|
||||||
background = new GUIImage(
|
background = new GUIImage(
|
||||||
@@ -2458,6 +2535,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
shortcutNodes.Add(CreateOrderNode(shortcutNodeSize, null, Point.Zero, dismissedOrderPrefab, -1));
|
shortcutNodes.Add(CreateOrderNode(shortcutNodeSize, null, Point.Zero, dismissedOrderPrefab, -1));
|
||||||
}
|
}
|
||||||
|
shortcutNodes.RemoveAll(n => n.UserData is Order o && !IsOrderAvailable(o));
|
||||||
if (shortcutNodes.Count < 1) { return; }
|
if (shortcutNodes.Count < 1) { return; }
|
||||||
shortcutCenterNode = new GUIFrame(new RectTransform(shortcutCenterNodeSize, parent: commandFrame.RectTransform, anchor: Anchor.Center), style: null)
|
shortcutCenterNode = new GUIFrame(new RectTransform(shortcutCenterNodeSize, parent: commandFrame.RectTransform, anchor: Anchor.Center), style: null)
|
||||||
{
|
{
|
||||||
@@ -2498,7 +2576,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void CreateOrderNodes(OrderCategory orderCategory)
|
private void CreateOrderNodes(OrderCategory orderCategory)
|
||||||
{
|
{
|
||||||
var orders = Order.PrefabList.FindAll(o => o.Category == orderCategory && !o.IsReport);
|
var orders = Order.PrefabList.FindAll(o => o.Category == orderCategory && !o.IsReport && IsOrderAvailable(o));
|
||||||
Order order;
|
Order order;
|
||||||
bool disableNode;
|
bool disableNode;
|
||||||
var offsets = MathUtils.GetPointsOnCircumference(Vector2.Zero, nodeDistance,
|
var offsets = MathUtils.GetPointsOnCircumference(Vector2.Zero, nodeDistance,
|
||||||
@@ -2582,15 +2660,12 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
contextualOrders.Remove(pumpOrderInfo);
|
contextualOrders.Remove(pumpOrderInfo);
|
||||||
}
|
}
|
||||||
if (contextualOrders.None())
|
orderIdentifier = "cleanupitems";
|
||||||
|
if (contextualOrders.None(info => info.Order.Identifier.Equals(orderIdentifier)))
|
||||||
{
|
{
|
||||||
orderIdentifier = "cleanupitems";
|
if (AIObjectiveCleanupItems.IsValidTarget(itemContext, Character.Controlled, checkInventory: false) || AIObjectiveCleanupItems.IsValidContainer(itemContext, Character.Controlled))
|
||||||
if (contextualOrders.None(info => info.Order.Identifier.Equals(orderIdentifier)))
|
|
||||||
{
|
{
|
||||||
if (AIObjectiveCleanupItems.IsValidTarget(itemContext, Character.Controlled, checkInventory: false) || AIObjectiveCleanupItems.IsValidContainer(itemContext, Character.Controlled))
|
contextualOrders.Add(new OrderInfo(new Order(Order.GetPrefab(orderIdentifier), itemContext, targetItem: null, Character.Controlled), null));
|
||||||
{
|
|
||||||
contextualOrders.Add(new OrderInfo(new Order(Order.GetPrefab(orderIdentifier), itemContext, targetItem: null, Character.Controlled), null));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AddIgnoreOrder(itemContext);
|
AddIgnoreOrder(itemContext);
|
||||||
@@ -2653,6 +2728,7 @@ namespace Barotrauma
|
|||||||
contextualOrders.Add(new OrderInfo(Order.GetPrefab(orderIdentifier), null));
|
contextualOrders.Add(new OrderInfo(Order.GetPrefab(orderIdentifier), null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
contextualOrders.RemoveAll(o => !IsOrderAvailable(o.Order));
|
||||||
var offsets = MathUtils.GetPointsOnCircumference(Vector2.Zero, nodeDistance, contextualOrders.Count, MathHelper.ToRadians(90f + 180f / contextualOrders.Count));
|
var offsets = MathUtils.GetPointsOnCircumference(Vector2.Zero, nodeDistance, contextualOrders.Count, MathHelper.ToRadians(90f + 180f / contextualOrders.Count));
|
||||||
bool disableNode = !CanCharacterBeHeard();
|
bool disableNode = !CanCharacterBeHeard();
|
||||||
for (int i = 0; i < contextualOrders.Count; i++)
|
for (int i = 0; i < contextualOrders.Count; i++)
|
||||||
@@ -3411,6 +3487,20 @@ namespace Barotrauma
|
|||||||
return character?.Info?.GetManualOrderPriority(order) ?? CharacterInfo.HighestManualOrderPriority;
|
return character?.Info?.GetManualOrderPriority(order) ?? CharacterInfo.HighestManualOrderPriority;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool IsOrderAvailable(Order order)
|
||||||
|
{
|
||||||
|
if (order == null) { return false; }
|
||||||
|
switch (order.Identifier.ToLowerInvariant())
|
||||||
|
{
|
||||||
|
case "assaultenemy":
|
||||||
|
Character character = characterContext ?? Character.Controlled;
|
||||||
|
if (character?.Submarine == null) { return false; }
|
||||||
|
return character.Submarine.GetConnectedSubs().Any(s => s.TeamID != character.TeamID);
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#region Crew Member Assignment Logic
|
#region Crew Member Assignment Logic
|
||||||
private bool CanOpenManualAssignment(GUIComponent node)
|
private bool CanOpenManualAssignment(GUIComponent node)
|
||||||
{
|
{
|
||||||
@@ -3487,7 +3577,7 @@ namespace Barotrauma
|
|||||||
bool hasLeaks = Character.Controlled.CurrentHull.ConnectedGaps.Any(g => !g.IsRoomToRoom && g.Open > 0.0f);
|
bool hasLeaks = Character.Controlled.CurrentHull.ConnectedGaps.Any(g => !g.IsRoomToRoom && g.Open > 0.0f);
|
||||||
ToggleReportButton("reportbreach", hasLeaks);
|
ToggleReportButton("reportbreach", hasLeaks);
|
||||||
|
|
||||||
bool hasIntruders = Character.CharacterList.Any(c => c.CurrentHull == Character.Controlled.CurrentHull && AIObjectiveFightIntruders.IsValidTarget(c, Character.Controlled));
|
bool hasIntruders = Character.CharacterList.Any(c => c.CurrentHull == Character.Controlled.CurrentHull && AIObjectiveFightIntruders.IsValidTarget(c, Character.Controlled, false));
|
||||||
ToggleReportButton("reportintruders", hasIntruders);
|
ToggleReportButton("reportintruders", hasIntruders);
|
||||||
|
|
||||||
foreach (GUIComponent reportButton in ReportButtonFrame.Children)
|
foreach (GUIComponent reportButton in ReportButtonFrame.Children)
|
||||||
@@ -3523,16 +3613,6 @@ namespace Barotrauma
|
|||||||
InitRound();
|
InitRound();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void EndRound()
|
|
||||||
{
|
|
||||||
//remove characterinfos whose characters have been removed or killed
|
|
||||||
characterInfos.RemoveAll(c => c.Character == null || c.Character.Removed || c.CauseOfDeath != null);
|
|
||||||
|
|
||||||
characters.Clear();
|
|
||||||
crewList.ClearChildren();
|
|
||||||
GUIContextMenu.CurrentContextMenu = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
characters.Clear();
|
characters.Clear();
|
||||||
@@ -3543,12 +3623,14 @@ namespace Barotrauma
|
|||||||
public void Save(XElement parentElement)
|
public void Save(XElement parentElement)
|
||||||
{
|
{
|
||||||
XElement element = new XElement("crew");
|
XElement element = new XElement("crew");
|
||||||
foreach (CharacterInfo ci in characterInfos)
|
for (int i = 0; i < characterInfos.Count; i++)
|
||||||
{
|
{
|
||||||
|
var ci = characterInfos[i];
|
||||||
var infoElement = ci.Save(element);
|
var infoElement = ci.Save(element);
|
||||||
if (ci.InventoryData != null) { infoElement.Add(ci.InventoryData); }
|
if (ci.InventoryData != null) { infoElement.Add(ci.InventoryData); }
|
||||||
if (ci.HealthData != null) { infoElement.Add(ci.HealthData); }
|
if (ci.HealthData != null) { infoElement.Add(ci.HealthData); }
|
||||||
if (ci.OrderData != null) { infoElement.Add(ci.OrderData); }
|
if (ci.OrderData != null) { infoElement.Add(ci.OrderData); }
|
||||||
|
infoElement.Add(new XAttribute("crewlistindex", ci.CrewListIndex));
|
||||||
if (ci.LastControlled) { infoElement.Add(new XAttribute("lastcontrolled", true)); }
|
if (ci.LastControlled) { infoElement.Add(new XAttribute("lastcontrolled", true)); }
|
||||||
}
|
}
|
||||||
SaveActiveOrders(element);
|
SaveActiveOrders(element);
|
||||||
|
|||||||
@@ -97,17 +97,16 @@ 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 AllowedToManageCampaign()
|
public bool AllowedToManageCampaign(ClientPermissions permissions = ClientPermissions.ManageCampaign)
|
||||||
{
|
{
|
||||||
//allow ending 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(ClientPermissions.ManageCampaign) ||
|
GameMain.Client.HasPermission(permissions) ||
|
||||||
GameMain.Client.ConnectedClients.Count == 1 ||
|
GameMain.Client.ConnectedClients.Count == 1 ||
|
||||||
GameMain.Client.IsServerOwner ||
|
GameMain.Client.IsServerOwner ||
|
||||||
GameMain.Client.ConnectedClients.None(c =>
|
GameMain.Client.ConnectedClients.None(c => c.InGame && (c.IsOwner || c.HasPermission(permissions)));
|
||||||
c.InGame && (c.IsOwner || c.HasPermission(ClientPermissions.ManageCampaign)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Draw(SpriteBatch spriteBatch)
|
public override void Draw(SpriteBatch spriteBatch)
|
||||||
@@ -242,6 +241,11 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
ReadyCheckButton.RectTransform.ScreenSpaceOffset = endRoundButton.RectTransform.ScreenSpaceOffset;
|
ReadyCheckButton.RectTransform.ScreenSpaceOffset = endRoundButton.RectTransform.ScreenSpaceOffset;
|
||||||
ReadyCheckButton.DrawManually(spriteBatch);
|
ReadyCheckButton.DrawManually(spriteBatch);
|
||||||
|
if (ReadyCheck.ReadyCheckCooldown > DateTime.Now)
|
||||||
|
{
|
||||||
|
float progress = (ReadyCheck.ReadyCheckCooldown - DateTime.Now).Seconds / 60.0f;
|
||||||
|
ReadyCheckButton.Color = ToolBox.GradientLerp(progress, Color.White, GUI.Style.Red);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,6 +294,9 @@ namespace Barotrauma
|
|||||||
case InteractionType.Crew when GameMain.NetworkMember != null:
|
case InteractionType.Crew when GameMain.NetworkMember != null:
|
||||||
CampaignUI.CrewManagement.SendCrewState(false);
|
CampaignUI.CrewManagement.SendCrewState(false);
|
||||||
goto default;
|
goto default;
|
||||||
|
case InteractionType.MedicalClinic:
|
||||||
|
CampaignUI.MedicalClinic.RequestLatestPending();
|
||||||
|
goto default;
|
||||||
default:
|
default:
|
||||||
ShowCampaignUI = true;
|
ShowCampaignUI = true;
|
||||||
CampaignUI.SelectTab(npc.CampaignInteractionType);
|
CampaignUI.SelectTab(npc.CampaignInteractionType);
|
||||||
@@ -319,6 +326,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
base.Update(deltaTime);
|
base.Update(deltaTime);
|
||||||
|
|
||||||
|
MedicalClinic?.Update(deltaTime);
|
||||||
|
|
||||||
if (PlayerInput.KeyHit(Microsoft.Xna.Framework.Input.Keys.Escape))
|
if (PlayerInput.KeyHit(Microsoft.Xna.Framework.Input.Keys.Escape))
|
||||||
{
|
{
|
||||||
GUIMessageBox.MessageBoxes.RemoveAll(mb => mb.UserData is RoundSummary);
|
GUIMessageBox.MessageBoxes.RemoveAll(mb => mb.UserData is RoundSummary);
|
||||||
|
|||||||
+26
-13
@@ -97,7 +97,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
partial void InitProjSpecific()
|
partial void InitProjSpecific()
|
||||||
{
|
{
|
||||||
var buttonContainer = new GUILayoutGroup(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.ButtonAreaTop, GUICanvas.Instance),
|
var buttonContainer = new GUILayoutGroup(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.ButtonAreaTop, GUI.Canvas),
|
||||||
isHorizontal: true, childAnchor: Anchor.CenterRight)
|
isHorizontal: true, childAnchor: Anchor.CenterRight)
|
||||||
{
|
{
|
||||||
CanBeFocused = false
|
CanBeFocused = false
|
||||||
@@ -108,7 +108,7 @@ namespace Barotrauma
|
|||||||
buttonCenter = buttonHeight / 2,
|
buttonCenter = buttonHeight / 2,
|
||||||
screenMiddle = GameMain.GraphicsWidth / 2;
|
screenMiddle = GameMain.GraphicsWidth / 2;
|
||||||
|
|
||||||
endRoundButton = new GUIButton(HUDLayoutSettings.ToRectTransform(new Rectangle(screenMiddle - buttonWidth / 2, HUDLayoutSettings.ButtonAreaTop.Center.Y - buttonCenter, buttonWidth, buttonHeight), GUICanvas.Instance),
|
endRoundButton = new GUIButton(HUDLayoutSettings.ToRectTransform(new Rectangle(screenMiddle - buttonWidth / 2, HUDLayoutSettings.ButtonAreaTop.Center.Y - buttonCenter, buttonWidth, buttonHeight), GUI.Canvas),
|
||||||
TextManager.Get("EndRound"), textAlignment: Alignment.Center, style: "EndRoundButton")
|
TextManager.Get("EndRound"), textAlignment: Alignment.Center, style: "EndRoundButton")
|
||||||
{
|
{
|
||||||
Pulse = true,
|
Pulse = true,
|
||||||
@@ -145,7 +145,7 @@ namespace Barotrauma
|
|||||||
int readyButtonHeight = buttonHeight;
|
int readyButtonHeight = buttonHeight;
|
||||||
int readyButtonWidth = (int) (GUI.Scale * 50);
|
int readyButtonWidth = (int) (GUI.Scale * 50);
|
||||||
|
|
||||||
ReadyCheckButton = new GUIButton(HUDLayoutSettings.ToRectTransform(new Rectangle(screenMiddle + (buttonWidth / 2) + GUI.IntScale(16), HUDLayoutSettings.ButtonAreaTop.Center.Y - buttonCenter, readyButtonWidth, readyButtonHeight), GUICanvas.Instance),
|
ReadyCheckButton = new GUIButton(HUDLayoutSettings.ToRectTransform(new Rectangle(screenMiddle + (buttonWidth / 2) + GUI.IntScale(16), HUDLayoutSettings.ButtonAreaTop.Center.Y - buttonCenter, readyButtonWidth, readyButtonHeight), GUI.Canvas),
|
||||||
style: "RepairBuyButton")
|
style: "RepairBuyButton")
|
||||||
{
|
{
|
||||||
ToolTip = TextManager.Get("ReadyCheck.Tooltip"),
|
ToolTip = TextManager.Get("ReadyCheck.Tooltip"),
|
||||||
@@ -545,14 +545,21 @@ namespace Barotrauma
|
|||||||
foreach (PurchasedItem pi in CargoManager.ItemsInBuyCrate)
|
foreach (PurchasedItem pi in CargoManager.ItemsInBuyCrate)
|
||||||
{
|
{
|
||||||
msg.Write(pi.ItemPrefab.Identifier);
|
msg.Write(pi.ItemPrefab.Identifier);
|
||||||
msg.WriteRangedInteger(pi.Quantity, 0, 100);
|
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);
|
msg.Write((UInt16)CargoManager.PurchasedItems.Count);
|
||||||
foreach (PurchasedItem pi in CargoManager.PurchasedItems)
|
foreach (PurchasedItem pi in CargoManager.PurchasedItems)
|
||||||
{
|
{
|
||||||
msg.Write(pi.ItemPrefab.Identifier);
|
msg.Write(pi.ItemPrefab.Identifier);
|
||||||
msg.WriteRangedInteger(pi.Quantity, 0, 100);
|
msg.WriteRangedInteger(pi.Quantity, 0, CargoManager.MaxQuantity);
|
||||||
}
|
}
|
||||||
|
|
||||||
msg.Write((UInt16)CargoManager.SoldItems.Count);
|
msg.Write((UInt16)CargoManager.SoldItems.Count);
|
||||||
@@ -562,6 +569,7 @@ namespace Barotrauma
|
|||||||
msg.Write((UInt16)si.ID);
|
msg.Write((UInt16)si.ID);
|
||||||
msg.Write(si.Removed);
|
msg.Write(si.Removed);
|
||||||
msg.Write(si.SellerID);
|
msg.Write(si.SellerID);
|
||||||
|
msg.Write((byte)si.Origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
msg.Write((ushort)UpgradeManager.PurchasedUpgrades.Count);
|
msg.Write((ushort)UpgradeManager.PurchasedUpgrades.Count);
|
||||||
@@ -640,6 +648,15 @@ namespace Barotrauma
|
|||||||
buyCrateItems.Add(new PurchasedItem(ItemPrefab.Prefabs[itemPrefabIdentifier], itemQuantity));
|
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();
|
UInt16 purchasedItemCount = msg.ReadUInt16();
|
||||||
List<PurchasedItem> purchasedItems = new List<PurchasedItem>();
|
List<PurchasedItem> purchasedItems = new List<PurchasedItem>();
|
||||||
for (int i = 0; i < purchasedItemCount; i++)
|
for (int i = 0; i < purchasedItemCount; i++)
|
||||||
@@ -657,7 +674,8 @@ namespace Barotrauma
|
|||||||
UInt16 id = msg.ReadUInt16();
|
UInt16 id = msg.ReadUInt16();
|
||||||
bool removed = msg.ReadBoolean();
|
bool removed = msg.ReadBoolean();
|
||||||
byte sellerId = msg.ReadByte();
|
byte sellerId = msg.ReadByte();
|
||||||
soldItems.Add(new SoldItem(ItemPrefab.Prefabs[itemPrefabIdentifier], id, removed, sellerId));
|
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();
|
||||||
@@ -678,13 +696,9 @@ namespace Barotrauma
|
|||||||
for (int i = 0; i < purchasedItemSwapCount; i++)
|
for (int i = 0; i < purchasedItemSwapCount; i++)
|
||||||
{
|
{
|
||||||
UInt16 itemToRemoveID = msg.ReadUInt16();
|
UInt16 itemToRemoveID = msg.ReadUInt16();
|
||||||
Item itemToRemove = Entity.FindEntityByID(itemToRemoveID) as Item;
|
|
||||||
|
|
||||||
string itemToInstallIdentifier = msg.ReadString();
|
string itemToInstallIdentifier = msg.ReadString();
|
||||||
ItemPrefab itemToInstall = string.IsNullOrEmpty(itemToInstallIdentifier) ? null : ItemPrefab.Find(string.Empty, itemToInstallIdentifier);
|
ItemPrefab itemToInstall = string.IsNullOrEmpty(itemToInstallIdentifier) ? null : ItemPrefab.Find(string.Empty, itemToInstallIdentifier);
|
||||||
|
if (!(Entity.FindEntityByID(itemToRemoveID) is Item itemToRemove)) { continue; }
|
||||||
if (itemToRemove == null) { continue; }
|
|
||||||
|
|
||||||
purchasedItemSwaps.Add(new PurchasedItemSwap(itemToRemove, itemToInstall));
|
purchasedItemSwaps.Add(new PurchasedItemSwap(itemToRemove, itemToInstall));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -728,12 +742,11 @@ namespace Barotrauma
|
|||||||
campaign.Map.SelectMission(selectedMissionIndices);
|
campaign.Map.SelectMission(selectedMissionIndices);
|
||||||
campaign.Map.AllowDebugTeleport = allowDebugTeleport;
|
campaign.Map.AllowDebugTeleport = allowDebugTeleport;
|
||||||
campaign.CargoManager.SetItemsInBuyCrate(buyCrateItems);
|
campaign.CargoManager.SetItemsInBuyCrate(buyCrateItems);
|
||||||
|
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; }
|
if (storeBalance.HasValue) { campaign.Map.CurrentLocation.StoreCurrentBalance = storeBalance.Value; }
|
||||||
campaign.UpgradeManager.SetPendingUpgrades(pendingUpgrades);
|
campaign.UpgradeManager.SetPendingUpgrades(pendingUpgrades);
|
||||||
campaign.UpgradeManager.PurchasedUpgrades.Clear();
|
|
||||||
|
|
||||||
campaign.UpgradeManager.PurchasedUpgrades.Clear();
|
campaign.UpgradeManager.PurchasedUpgrades.Clear();
|
||||||
foreach (var purchasedItemSwap in purchasedItemSwaps)
|
foreach (var purchasedItemSwap in purchasedItemSwaps)
|
||||||
{
|
{
|
||||||
|
|||||||
+9
-1
@@ -108,6 +108,9 @@ namespace Barotrauma
|
|||||||
case "pets":
|
case "pets":
|
||||||
petsElement = subElement;
|
petsElement = subElement;
|
||||||
break;
|
break;
|
||||||
|
case "stats":
|
||||||
|
LoadStats(subElement);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,7 +170,7 @@ namespace Barotrauma
|
|||||||
int buttonHeight = (int)(GUI.Scale * 40);
|
int buttonHeight = (int)(GUI.Scale * 40);
|
||||||
int buttonWidth = GUI.IntScale(450);
|
int buttonWidth = GUI.IntScale(450);
|
||||||
|
|
||||||
endRoundButton = new GUIButton(HUDLayoutSettings.ToRectTransform(new Rectangle((GameMain.GraphicsWidth / 2) - (buttonWidth / 2), HUDLayoutSettings.ButtonAreaTop.Center.Y - (buttonHeight / 2), buttonWidth, buttonHeight), GUICanvas.Instance),
|
endRoundButton = new GUIButton(HUDLayoutSettings.ToRectTransform(new Rectangle((GameMain.GraphicsWidth / 2) - (buttonWidth / 2), HUDLayoutSettings.ButtonAreaTop.Center.Y - (buttonHeight / 2), buttonWidth, buttonHeight), GUI.Canvas),
|
||||||
TextManager.Get("EndRound"), textAlignment: Alignment.Center, style: "EndRoundButton")
|
TextManager.Get("EndRound"), textAlignment: Alignment.Center, style: "EndRoundButton")
|
||||||
{
|
{
|
||||||
Pulse = true,
|
Pulse = true,
|
||||||
@@ -412,6 +415,10 @@ namespace Barotrauma
|
|||||||
break;
|
break;
|
||||||
case TransitionType.ProgressToNextLocation:
|
case TransitionType.ProgressToNextLocation:
|
||||||
Map.MoveToNextLocation();
|
Map.MoveToNextLocation();
|
||||||
|
TotalPassedLevels++;
|
||||||
|
break;
|
||||||
|
case TransitionType.ProgressToNextEmptyLocation:
|
||||||
|
TotalPassedLevels++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -728,6 +735,7 @@ namespace Barotrauma
|
|||||||
new XAttribute("purchaseditemrepairs", PurchasedItemRepairs),
|
new XAttribute("purchaseditemrepairs", PurchasedItemRepairs),
|
||||||
new XAttribute("cheatsenabled", CheatsEnabled));
|
new XAttribute("cheatsenabled", CheatsEnabled));
|
||||||
modeElement.Add(Settings.Save());
|
modeElement.Add(Settings.Save());
|
||||||
|
modeElement.Add(SaveStats());
|
||||||
|
|
||||||
//save and remove all items that are in someone's inventory so they don't get included in the sub file as well
|
//save and remove all items that are in someone's inventory so they don't get included in the sub file as well
|
||||||
foreach (Character c in Character.CharacterList)
|
foreach (Character c in Character.CharacterList)
|
||||||
|
|||||||
+1
-1
@@ -220,12 +220,12 @@ namespace Barotrauma.Tutorials
|
|||||||
SetHighlight(captain_navConsole.Item, true);
|
SetHighlight(captain_navConsole.Item, true);
|
||||||
SetHighlight(captain_sonar.Item, true);
|
SetHighlight(captain_sonar.Item, true);
|
||||||
SetHighlight(captain_statusMonitor, true);
|
SetHighlight(captain_statusMonitor, true);
|
||||||
captain_navConsole.UseAutoDocking = false;
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
//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.DockedTo.Any());
|
} while (Submarine.MainSub.DockedTo.Any());
|
||||||
|
captain_navConsole.UseAutoDocking = false;
|
||||||
RemoveCompletedObjective(segments[4]);
|
RemoveCompletedObjective(segments[4]);
|
||||||
yield return new WaitForSeconds(2f, false);
|
yield return new WaitForSeconds(2f, false);
|
||||||
TriggerTutorialSegment(5); // Navigate to destination
|
TriggerTutorialSegment(5); // Navigate to destination
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
indicator.Visible = Character.Controlled.Info.GetAvailableTalentPoints() > 0;
|
indicator.Visible = Character.Controlled.Info.GetAvailableTalentPoints() > 0 && !Character.Controlled.HasUnlockedAllTalents();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ namespace Barotrauma
|
|||||||
static class HintManager
|
static class HintManager
|
||||||
{
|
{
|
||||||
private const string HintManagerFile = "hintmanager.xml";
|
private const string HintManagerFile = "hintmanager.xml";
|
||||||
|
|
||||||
|
public static bool Enabled => GameMain.Config != null && !GameMain.Config.DisableInGameHints;
|
||||||
private static HashSet<string> HintIdentifiers { get; set; }
|
private static HashSet<string> HintIdentifiers { get; set; }
|
||||||
private static Dictionary<string, HashSet<string>> HintTags { get; } = new Dictionary<string, HashSet<string>>();
|
private static Dictionary<string, HashSet<string>> HintTags { get; } = new Dictionary<string, HashSet<string>>();
|
||||||
private static Dictionary<string, (string identifier, string option)> HintOrders { get; } = new Dictionary<string, (string orderIdentifier, string orderOption)>();
|
private static Dictionary<string, (string identifier, string option)> HintOrders { get; } = new Dictionary<string, (string orderIdentifier, string orderOption)>();
|
||||||
@@ -666,6 +668,8 @@ 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}");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,391 @@
|
|||||||
|
#nullable enable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
using System.Linq;
|
||||||
|
using Barotrauma.Extensions;
|
||||||
|
using Barotrauma.Networking;
|
||||||
|
|
||||||
|
namespace Barotrauma
|
||||||
|
{
|
||||||
|
internal partial class MedicalClinic
|
||||||
|
{
|
||||||
|
public enum RequestResult
|
||||||
|
{
|
||||||
|
Undecided,
|
||||||
|
Success,
|
||||||
|
Error,
|
||||||
|
Timeout
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly struct RequestAction<T>
|
||||||
|
{
|
||||||
|
public readonly Action<T> Callback;
|
||||||
|
public readonly DateTimeOffset Timeout;
|
||||||
|
|
||||||
|
public RequestAction(Action<T> callback, DateTimeOffset timeout)
|
||||||
|
{
|
||||||
|
Callback = callback;
|
||||||
|
Timeout = timeout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly struct AfflictionRequest
|
||||||
|
{
|
||||||
|
public readonly RequestResult Result;
|
||||||
|
public readonly ImmutableArray<NetAffliction> Afflictions;
|
||||||
|
|
||||||
|
public AfflictionRequest(RequestResult result, ImmutableArray<NetAffliction> afflictions)
|
||||||
|
{
|
||||||
|
Result = result;
|
||||||
|
Afflictions = afflictions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly struct PendingRequest
|
||||||
|
{
|
||||||
|
public readonly RequestResult Result;
|
||||||
|
public readonly ImmutableArray<NetCrewMember> CrewMembers;
|
||||||
|
|
||||||
|
public PendingRequest(RequestResult result, ImmutableArray<NetCrewMember> crewMembers)
|
||||||
|
{
|
||||||
|
Result = result;
|
||||||
|
CrewMembers = crewMembers;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly struct CallbackOnlyRequest
|
||||||
|
{
|
||||||
|
public readonly RequestResult Result;
|
||||||
|
|
||||||
|
public CallbackOnlyRequest(RequestResult result)
|
||||||
|
{
|
||||||
|
Result = result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly struct HealRequest
|
||||||
|
{
|
||||||
|
public readonly RequestResult Result;
|
||||||
|
public readonly HealRequestResult HealResult;
|
||||||
|
|
||||||
|
public HealRequest(RequestResult result, HealRequestResult healResult)
|
||||||
|
{
|
||||||
|
Result = result;
|
||||||
|
HealResult = healResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly List<RequestAction<AfflictionRequest>> afflictionRequests = new List<RequestAction<AfflictionRequest>>();
|
||||||
|
private readonly List<RequestAction<PendingRequest>> pendingHealRequests = new List<RequestAction<PendingRequest>>();
|
||||||
|
private readonly List<RequestAction<CallbackOnlyRequest>> clearAllRequests = new List<RequestAction<CallbackOnlyRequest>>();
|
||||||
|
private readonly List<RequestAction<HealRequest>> healAllRequests = new List<RequestAction<HealRequest>>();
|
||||||
|
private readonly List<RequestAction<CallbackOnlyRequest>> addRequests = new List<RequestAction<CallbackOnlyRequest>>();
|
||||||
|
private readonly List<RequestAction<CallbackOnlyRequest>> removeRequests = new List<RequestAction<CallbackOnlyRequest>>();
|
||||||
|
|
||||||
|
public void RequestAfflictions(CharacterInfo info, Action<AfflictionRequest> onReceived)
|
||||||
|
{
|
||||||
|
if (GameMain.IsSingleplayer)
|
||||||
|
{
|
||||||
|
#if DEBUG && LINUX
|
||||||
|
if (Screen.Selected is TestScreen)
|
||||||
|
{
|
||||||
|
onReceived.Invoke(new AfflictionRequest(RequestResult.Success, TestAfflictions.ToImmutableArray()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!(info is { Character: { CharacterHealth: { } health } }))
|
||||||
|
{
|
||||||
|
onReceived.Invoke(new AfflictionRequest(RequestResult.Error, ImmutableArray<NetAffliction>.Empty));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImmutableArray<NetAffliction> pendingAfflictions = GetAllAfflictions(health).ToImmutableArray();
|
||||||
|
onReceived.Invoke(new AfflictionRequest(RequestResult.Success, pendingAfflictions));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
afflictionRequests.Add(new RequestAction<AfflictionRequest>(onReceived, GetTimeout()));
|
||||||
|
SendAfflictionRequest(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RequestLatestPending(Action<PendingRequest> onReceived)
|
||||||
|
{
|
||||||
|
// no need to worry about syncing when there's only one pair of eyes capable of looking at the UI
|
||||||
|
if (GameMain.IsSingleplayer) { return; }
|
||||||
|
|
||||||
|
pendingHealRequests.Add(new RequestAction<PendingRequest>(onReceived, GetTimeout()));
|
||||||
|
SendPendingRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update(float deltaTime)
|
||||||
|
{
|
||||||
|
DateTimeOffset now = DateTimeOffset.Now;
|
||||||
|
UpdateQueue(afflictionRequests, now, onTimeout: callback => { callback(new AfflictionRequest(RequestResult.Timeout, ImmutableArray<NetAffliction>.Empty)); });
|
||||||
|
UpdateQueue(pendingHealRequests, now, onTimeout: callback => { callback(new PendingRequest(RequestResult.Timeout, ImmutableArray<NetCrewMember>.Empty)); });
|
||||||
|
UpdateQueue(healAllRequests, now, onTimeout: callback => { callback(new HealRequest(RequestResult.Timeout, HealRequestResult.Unknown)); });
|
||||||
|
UpdateQueue(clearAllRequests, now, onTimeout: CallbackOnlyTimeout);
|
||||||
|
UpdateQueue(addRequests, now, onTimeout: CallbackOnlyTimeout);
|
||||||
|
UpdateQueue(removeRequests, now, onTimeout: CallbackOnlyTimeout);
|
||||||
|
|
||||||
|
void CallbackOnlyTimeout(Action<CallbackOnlyRequest> callback) { callback(new CallbackOnlyRequest(RequestResult.Timeout)); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsAfflictionPending(NetCrewMember character, NetAffliction affliction)
|
||||||
|
{
|
||||||
|
foreach (NetCrewMember crewMember in PendingHeals)
|
||||||
|
{
|
||||||
|
if (!crewMember.CharacterEquals(character)) { continue; }
|
||||||
|
|
||||||
|
return crewMember.Afflictions.Any(a => a.AfflictionEquals(affliction));
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool TryDequeue<T>(List<RequestAction<T>> requestQueue, out Action<T> result)
|
||||||
|
{
|
||||||
|
RequestAction<T>? first = requestQueue.FirstOrNull();
|
||||||
|
if (!(first is { } action))
|
||||||
|
{
|
||||||
|
result = _ => { };
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
requestQueue.Remove(action);
|
||||||
|
result = action.Callback;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void UpdateQueue<T>(List<RequestAction<T>> requestQueue, DateTimeOffset now, Action<Action<T>> onTimeout)
|
||||||
|
{
|
||||||
|
HashSet<RequestAction<T>>? removals = null;
|
||||||
|
foreach (RequestAction<T> action in requestQueue)
|
||||||
|
{
|
||||||
|
if (action.Timeout < now)
|
||||||
|
{
|
||||||
|
onTimeout.Invoke(action.Callback);
|
||||||
|
|
||||||
|
removals ??= new HashSet<RequestAction<T>>();
|
||||||
|
removals.Add(action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (removals is null) { return; }
|
||||||
|
|
||||||
|
foreach (RequestAction<T> action in removals)
|
||||||
|
{
|
||||||
|
requestQueue.Remove(action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 int GetPing()
|
||||||
|
{
|
||||||
|
if (GameMain.IsSingleplayer || !(GameMain.Client?.Name is { } ownName) || !(GameMain.NetworkMember?.ConnectedClients is { } clients)) { return 0; }
|
||||||
|
|
||||||
|
return (from client in clients where client.Name == ownName select client.Ping).FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void HealAllButtonAction(Action<HealRequest> onReceived)
|
||||||
|
{
|
||||||
|
if (GameMain.IsSingleplayer)
|
||||||
|
{
|
||||||
|
HealRequestResult result = HealAllPending();
|
||||||
|
onReceived(new HealRequest(RequestResult.Success, HealAllPending()));
|
||||||
|
if (result == HealRequestResult.Success)
|
||||||
|
{
|
||||||
|
OnUpdate?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (campaign?.CampaignUI?.MedicalClinic is { } ui)
|
||||||
|
{
|
||||||
|
ui.ClosePopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
healAllRequests.Add(new RequestAction<HealRequest>(onReceived, GetTimeout()));
|
||||||
|
ClientSend(null, NetworkHeader.HEAL_PENDING, DeliveryMethod.Reliable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearAllButtonAction(Action<CallbackOnlyRequest> onReceived)
|
||||||
|
{
|
||||||
|
if (GameMain.IsSingleplayer)
|
||||||
|
{
|
||||||
|
ClearPendingHeals();
|
||||||
|
onReceived(new CallbackOnlyRequest(RequestResult.Success));
|
||||||
|
OnUpdate?.Invoke();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
clearAllRequests.Add(new RequestAction<CallbackOnlyRequest>(onReceived, GetTimeout()));
|
||||||
|
ClientSend(null, NetworkHeader.CLEAR_PENDING, DeliveryMethod.Reliable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClearRequstReceived()
|
||||||
|
{
|
||||||
|
ClearPendingHeals();
|
||||||
|
if (TryDequeue(clearAllRequests, out var callback))
|
||||||
|
{
|
||||||
|
callback(new CallbackOnlyRequest(RequestResult.Success));
|
||||||
|
}
|
||||||
|
OnUpdate?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HealRequestReceived(IReadMessage inc)
|
||||||
|
{
|
||||||
|
NetHealRequest request = INetSerializableStruct.Read<NetHealRequest>(inc);
|
||||||
|
if (request.Result == HealRequestResult.Success)
|
||||||
|
{
|
||||||
|
HealAllPending(force: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TryDequeue(healAllRequests, out var callback))
|
||||||
|
{
|
||||||
|
callback(new HealRequest(RequestResult.Success, request.Result));
|
||||||
|
}
|
||||||
|
|
||||||
|
OnUpdate?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddPendingButtonAction(NetCrewMember crewMember, Action<CallbackOnlyRequest> onReceived)
|
||||||
|
{
|
||||||
|
if (GameMain.IsSingleplayer)
|
||||||
|
{
|
||||||
|
InsertPendingCrewMember(crewMember);
|
||||||
|
onReceived(new CallbackOnlyRequest(RequestResult.Success));
|
||||||
|
OnUpdate?.Invoke();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
addRequests.Add(new RequestAction<CallbackOnlyRequest>(onReceived, GetTimeout()));
|
||||||
|
ClientSend(crewMember, NetworkHeader.ADD_PENDING, DeliveryMethod.Reliable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemovePendingButtonAction(NetCrewMember crewMember, NetAffliction affliction, Action<CallbackOnlyRequest> onReceived)
|
||||||
|
{
|
||||||
|
if (GameMain.IsSingleplayer)
|
||||||
|
{
|
||||||
|
RemovePendingAffliction(crewMember, affliction);
|
||||||
|
onReceived(new CallbackOnlyRequest(RequestResult.Success));
|
||||||
|
OnUpdate?.Invoke();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
INetSerializableStruct removedAffliction = new NetRemovedAffliction
|
||||||
|
{
|
||||||
|
CrewMember = crewMember,
|
||||||
|
Affliction = affliction
|
||||||
|
};
|
||||||
|
|
||||||
|
removeRequests.Add(new RequestAction<CallbackOnlyRequest>(onReceived, GetTimeout()));
|
||||||
|
ClientSend(removedAffliction, NetworkHeader.REMOVE_PENDING, DeliveryMethod.Reliable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NewAdditonReceived(IReadMessage inc, MessageFlag flag)
|
||||||
|
{
|
||||||
|
NetCrewMember crewMember = INetSerializableStruct.Read<NetCrewMember>(inc);
|
||||||
|
InsertPendingCrewMember(crewMember);
|
||||||
|
if (flag == MessageFlag.Response && TryDequeue(addRequests, out var callback))
|
||||||
|
{
|
||||||
|
callback(new CallbackOnlyRequest(RequestResult.Success));
|
||||||
|
}
|
||||||
|
OnUpdate?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NewRemovalReceived(IReadMessage inc, MessageFlag flag)
|
||||||
|
{
|
||||||
|
NetRemovedAffliction removed = INetSerializableStruct.Read<NetRemovedAffliction>(inc);
|
||||||
|
RemovePendingAffliction(removed.CrewMember, removed.Affliction);
|
||||||
|
if (flag == MessageFlag.Response && TryDequeue(removeRequests, out var callback))
|
||||||
|
{
|
||||||
|
callback(new CallbackOnlyRequest(RequestResult.Success));
|
||||||
|
}
|
||||||
|
OnUpdate?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SendAfflictionRequest(CharacterInfo info)
|
||||||
|
{
|
||||||
|
INetSerializableStruct crewMember = new NetCrewMember
|
||||||
|
{
|
||||||
|
CharacterInfo = info,
|
||||||
|
Afflictions = Array.Empty<NetAffliction>()
|
||||||
|
};
|
||||||
|
|
||||||
|
ClientSend(crewMember, NetworkHeader.REQUEST_AFFLICTIONS, DeliveryMethod.Unreliable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SendPendingRequest()
|
||||||
|
{
|
||||||
|
ClientSend(null, NetworkHeader.REQUEST_PENDING, DeliveryMethod.Reliable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AfflictionRequestReceived(IReadMessage inc)
|
||||||
|
{
|
||||||
|
NetCrewMember crewMember = INetSerializableStruct.Read<NetCrewMember>(inc);
|
||||||
|
if (TryDequeue(afflictionRequests, out var callback))
|
||||||
|
{
|
||||||
|
RequestResult result = crewMember.CharacterInfoID == 0 ? RequestResult.Error : RequestResult.Success;
|
||||||
|
callback(new AfflictionRequest(result, crewMember.Afflictions.ToImmutableArray()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PendingRequestReceived(IReadMessage inc)
|
||||||
|
{
|
||||||
|
NetPendingCrew pendingCrew = INetSerializableStruct.Read<NetPendingCrew>(inc);
|
||||||
|
if (TryDequeue(pendingHealRequests, out var callback))
|
||||||
|
{
|
||||||
|
callback(new PendingRequest(RequestResult.Success, pendingCrew.CrewMembers.ToImmutableArray()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IWriteMessage StartSending()
|
||||||
|
{
|
||||||
|
IWriteMessage writeMessage = new WriteOnlyMessage();
|
||||||
|
writeMessage.Write((byte)ClientPacketHeader.MEDICAL);
|
||||||
|
return writeMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ClientSend(INetSerializableStruct? netStruct, NetworkHeader header, DeliveryMethod deliveryMethod)
|
||||||
|
{
|
||||||
|
IWriteMessage msg = StartSending();
|
||||||
|
msg.Write((byte)header);
|
||||||
|
netStruct?.Write(msg);
|
||||||
|
GameMain.Client.ClientPeer?.Send(msg, deliveryMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClientRead(IReadMessage inc)
|
||||||
|
{
|
||||||
|
NetworkHeader header = (NetworkHeader)inc.ReadByte();
|
||||||
|
MessageFlag flag = (MessageFlag)inc.ReadByte();
|
||||||
|
|
||||||
|
switch (header)
|
||||||
|
{
|
||||||
|
case NetworkHeader.REQUEST_AFFLICTIONS:
|
||||||
|
AfflictionRequestReceived(inc);
|
||||||
|
break;
|
||||||
|
case NetworkHeader.REQUEST_PENDING:
|
||||||
|
PendingRequestReceived(inc);
|
||||||
|
break;
|
||||||
|
case NetworkHeader.ADD_PENDING:
|
||||||
|
NewAdditonReceived(inc, flag);
|
||||||
|
break;
|
||||||
|
case NetworkHeader.REMOVE_PENDING:
|
||||||
|
NewRemovalReceived(inc, flag);
|
||||||
|
break;
|
||||||
|
case NetworkHeader.HEAL_PENDING:
|
||||||
|
HealRequestReceived(inc);
|
||||||
|
break;
|
||||||
|
case NetworkHeader.CLEAR_PENDING:
|
||||||
|
ClearRequstReceived();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,7 +31,7 @@ namespace Barotrauma
|
|||||||
private GUIMessageBox? msgBox;
|
private GUIMessageBox? msgBox;
|
||||||
private GUIMessageBox? resultsBox;
|
private GUIMessageBox? resultsBox;
|
||||||
|
|
||||||
public static DateTime lastReadyCheck = DateTime.MinValue;
|
public static DateTime ReadyCheckCooldown = DateTime.MinValue;
|
||||||
|
|
||||||
public static bool IsReadyCheck(GUIComponent? msgBox) => msgBox?.UserData as string == PromptData || msgBox?.UserData as string == ResultData;
|
public static bool IsReadyCheck(GUIComponent? msgBox) => msgBox?.UserData as string == PromptData || msgBox?.UserData as string == ResultData;
|
||||||
|
|
||||||
@@ -273,10 +273,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public static void CreateReadyCheck()
|
public static void CreateReadyCheck()
|
||||||
{
|
{
|
||||||
if (lastReadyCheck < DateTime.Now)
|
if (ReadyCheckCooldown < DateTime.Now)
|
||||||
{
|
{
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
lastReadyCheck = DateTime.Now.AddMinutes(1);
|
ReadyCheckCooldown = DateTime.Now.AddMinutes(1);
|
||||||
#endif
|
#endif
|
||||||
IWriteMessage msg = new WriteOnlyMessage();
|
IWriteMessage msg = new WriteOnlyMessage();
|
||||||
msg.Write((byte) ClientPacketHeader.READY_CHECK);
|
msg.Write((byte) ClientPacketHeader.READY_CHECK);
|
||||||
@@ -285,7 +285,7 @@ namespace Barotrauma
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GUIMessageBox msgBox = new GUIMessageBox(readyCheckHeader, readyCheckPleaseWait((lastReadyCheck - DateTime.Now).Seconds), new[] { closeButton });
|
GUIMessageBox msgBox = new GUIMessageBox(readyCheckHeader, readyCheckPleaseWait((ReadyCheckCooldown - DateTime.Now).Seconds), new[] { closeButton });
|
||||||
msgBox.Buttons[0].OnClicked = delegate
|
msgBox.Buttons[0].OnClicked = delegate
|
||||||
{
|
{
|
||||||
msgBox.Close();
|
msgBox.Close();
|
||||||
|
|||||||
@@ -524,6 +524,7 @@ namespace Barotrauma
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if !OSX
|
||||||
var statisticsTickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.045f), leftPanel.RectTransform), TextManager.Get("statisticsconsenttickbox"))
|
var statisticsTickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.045f), leftPanel.RectTransform), TextManager.Get("statisticsconsenttickbox"))
|
||||||
{
|
{
|
||||||
OnSelected = (GUITickBox tickBox) =>
|
OnSelected = (GUITickBox tickBox) =>
|
||||||
@@ -562,6 +563,15 @@ namespace Barotrauma
|
|||||||
statisticsTickBox.OnSelected = prevHandler;
|
statisticsTickBox.OnSelected = prevHandler;
|
||||||
statisticsTickBox.Enabled = GameAnalyticsManager.UserConsented != GameAnalyticsManager.Consent.Error;
|
statisticsTickBox.Enabled = GameAnalyticsManager.UserConsented != GameAnalyticsManager.Consent.Error;
|
||||||
});
|
});
|
||||||
|
#endif
|
||||||
|
|
||||||
|
foreach (var child in leftPanel.Children)
|
||||||
|
{
|
||||||
|
if (child is GUITextBlock textBlock)
|
||||||
|
{
|
||||||
|
textBlock.RectTransform.MinSize = new Point(textBlock.RectTransform.MinSize.X, (int)Math.Max(textBlock.RectTransform.MinSize.Y, textBlock.TextSize.Y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// right panel --------------------------------------
|
// right panel --------------------------------------
|
||||||
|
|
||||||
@@ -597,6 +607,10 @@ namespace Barotrauma
|
|||||||
OnClicked = (bt, userdata) => { SelectTab((Tab)userdata); return true; }
|
OnClicked = (bt, userdata) => { SelectTab((Tab)userdata); return true; }
|
||||||
};
|
};
|
||||||
tabButtons[(int)tab].Text = ToolBox.LimitString(buttonText, tabButtons[(int)tab].Font, (int)(0.75f * tabWidth * tabButtonHolder.Rect.Width));
|
tabButtons[(int)tab].Text = ToolBox.LimitString(buttonText, tabButtons[(int)tab].Font, (int)(0.75f * tabWidth * tabButtonHolder.Rect.Width));
|
||||||
|
if (tabButtons[(int)tab].Text != buttonText)
|
||||||
|
{
|
||||||
|
tabButtons[(int)tab].ToolTip = buttonText;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Graphics tab --------------------------------------------------------------
|
/// Graphics tab --------------------------------------------------------------
|
||||||
|
|||||||
@@ -153,12 +153,6 @@ namespace Barotrauma
|
|||||||
return container.Inventory;
|
return container.Inventory;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void PutItem(Item item, int i, Character user, bool removeItem = true, bool createNetworkEvent = true)
|
|
||||||
{
|
|
||||||
base.PutItem(item, i, user, removeItem, createNetworkEvent);
|
|
||||||
CreateSlots();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void CreateSlots()
|
public override void CreateSlots()
|
||||||
{
|
{
|
||||||
visualSlots ??= new VisualSlot[capacity];
|
visualSlots ??= new VisualSlot[capacity];
|
||||||
@@ -504,6 +498,13 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
HUDLayoutSettings.InventoryTopY = visualSlots[0].EquipButtonRect.Y - (int)(15 * GUI.Scale);
|
HUDLayoutSettings.InventoryTopY = visualSlots[0].EquipButtonRect.Y - (int)(15 * GUI.Scale);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < capacity; i++)
|
||||||
|
{
|
||||||
|
visualSlots[i].DrawOffset = Vector2.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ControlInput(Camera cam)
|
protected override void ControlInput(Camera cam)
|
||||||
@@ -789,7 +790,7 @@ namespace Barotrauma
|
|||||||
if (quickUseAction != QuickUseAction.Drop)
|
if (quickUseAction != QuickUseAction.Drop)
|
||||||
{
|
{
|
||||||
slot.QuickUseButtonToolTip = quickUseAction == QuickUseAction.None ?
|
slot.QuickUseButtonToolTip = quickUseAction == QuickUseAction.None ?
|
||||||
"" : TextManager.GetWithVariable("QuickUseAction." + quickUseAction.ToString(), "[equippeditem]", item?.Name);
|
"" : TextManager.GetWithVariable("QuickUseAction." + quickUseAction.ToString(), "[equippeditem]", character.HeldItems.FirstOrDefault()?.Name ?? item?.Name);
|
||||||
if (PlayerInput.PrimaryMouseButtonDown()) { slot.EquipButtonState = GUIComponent.ComponentState.Pressed; }
|
if (PlayerInput.PrimaryMouseButtonDown()) { slot.EquipButtonState = GUIComponent.ComponentState.Pressed; }
|
||||||
if (PlayerInput.PrimaryMouseButtonClicked())
|
if (PlayerInput.PrimaryMouseButtonClicked())
|
||||||
{
|
{
|
||||||
@@ -963,7 +964,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
return QuickUseAction.TakeFromCharacter;
|
return QuickUseAction.TakeFromCharacter;
|
||||||
}
|
}
|
||||||
else if (character.HeldItems.Any(i => i.OwnInventory != null && i.OwnInventory.CanBePut(item)) && allowInventorySwap)
|
else if (character.HeldItems.Any(i =>
|
||||||
|
i.OwnInventory != null &&
|
||||||
|
(i.OwnInventory.CanBePut(item) || (i.OwnInventory.Capacity == 1 && i.OwnInventory.AllowSwappingContainedItems && i.OwnInventory.Container.CanBeContained(item)))))
|
||||||
{
|
{
|
||||||
return QuickUseAction.PutToEquippedItem;
|
return QuickUseAction.PutToEquippedItem;
|
||||||
}
|
}
|
||||||
@@ -1128,8 +1131,9 @@ namespace Barotrauma
|
|||||||
case QuickUseAction.PutToEquippedItem:
|
case QuickUseAction.PutToEquippedItem:
|
||||||
foreach (Item heldItem in character.HeldItems)
|
foreach (Item heldItem in character.HeldItems)
|
||||||
{
|
{
|
||||||
if (heldItem.OwnInventory != null &&
|
if (heldItem.OwnInventory == null) { continue; }
|
||||||
heldItem.OwnInventory.TryPutItem(item, Character.Controlled))
|
if (heldItem.OwnInventory.TryPutItem(item, Character.Controlled) ||
|
||||||
|
(heldItem.OwnInventory.Capacity == 1 && heldItem.OwnInventory.TryPutItem(item, 0, allowSwapping: true, allowCombine: false, user: Character.Controlled)))
|
||||||
{
|
{
|
||||||
success = true;
|
success = true;
|
||||||
for (int j = 0; j < capacity; j++)
|
for (int j = 0; j < capacity; j++)
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
case AreaShape.Circle:
|
case AreaShape.Circle:
|
||||||
Vector2 center = item.WorldPosition;
|
Vector2 center = item.WorldPosition;
|
||||||
center.Y = -center.Y;
|
|
||||||
center += SpawnAreaOffset;
|
center += SpawnAreaOffset;
|
||||||
|
center.Y = -center.Y;
|
||||||
spriteBatch.DrawCircle(center, SpawnAreaRadius, 32, GUI.Style.Red, thickness: 4f);
|
spriteBatch.DrawCircle(center, SpawnAreaRadius, 32, GUI.Style.Red, thickness: 4f);
|
||||||
|
|
||||||
if (MaximumAmountRangePadding > 0f)
|
if (MaximumAmountRangePadding > 0f)
|
||||||
@@ -51,8 +51,8 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
case AreaShape.Circle:
|
case AreaShape.Circle:
|
||||||
Vector2 center = item.WorldPosition;
|
Vector2 center = item.WorldPosition;
|
||||||
center.Y = -center.Y;
|
|
||||||
center += CrewAreaOffset;
|
center += CrewAreaOffset;
|
||||||
|
center.Y = -center.Y;
|
||||||
spriteBatch.DrawCircle(center, CrewAreaRadius, 32, GUI.Style.Green);
|
spriteBatch.DrawCircle(center, CrewAreaRadius, 32, GUI.Style.Green);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -256,6 +256,10 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
targetHull.IncreaseSectionColorOrStrength(targetSections[i], color, sizeAdjustedSprayStrength * deltaTime, true, false);
|
targetHull.IncreaseSectionColorOrStrength(targetSections[i], color, sizeAdjustedSprayStrength * deltaTime, true, false);
|
||||||
}
|
}
|
||||||
|
if (GameMain.GameSession != null)
|
||||||
|
{
|
||||||
|
GameMain.GameSession.TimeSpentCleaning += deltaTime;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -263,6 +267,10 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
targetHull.CleanSection(targetSections[i], -sizeAdjustedSprayStrength * deltaTime, true);
|
targetHull.CleanSection(targetSections[i], -sizeAdjustedSprayStrength * deltaTime, true);
|
||||||
}
|
}
|
||||||
|
if (GameMain.GameSession != null)
|
||||||
|
{
|
||||||
|
GameMain.GameSession.TimeSpentPainting += deltaTime;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 particleStartPos = item.WorldPosition + ConvertUnits.ToDisplayUnits(TransformedBarrelPos);
|
Vector2 particleStartPos = item.WorldPosition + ConvertUnits.ToDisplayUnits(TransformedBarrelPos);
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public GUIFrame GuiFrame { get; protected set; }
|
public GUIFrame GuiFrame { get; set; }
|
||||||
|
|
||||||
[Serialize(false, false)]
|
[Serialize(false, false)]
|
||||||
public bool AllowUIOverlap
|
public bool AllowUIOverlap
|
||||||
@@ -390,10 +390,10 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
if (SerializableProperties.TryGetValue(sound.VolumeProperty, out SerializableProperty property))
|
if (SerializableProperties.TryGetValue(sound.VolumeProperty, out SerializableProperty property))
|
||||||
{
|
{
|
||||||
float newVolume = 0.0f;
|
float newVolume;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
newVolume = (float)property.GetValue(this);
|
newVolume = property.GetFloatValue(this);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@@ -554,7 +554,7 @@ namespace Barotrauma.Items.Components
|
|||||||
color = GuiFrameSource.GetAttributeColor("color", Color.White);
|
color = GuiFrameSource.GetAttributeColor("color", Color.White);
|
||||||
}
|
}
|
||||||
string style = GuiFrameSource.Attribute("style") == null ? null : GuiFrameSource.GetAttributeString("style", "");
|
string style = GuiFrameSource.Attribute("style") == null ? null : GuiFrameSource.GetAttributeString("style", "");
|
||||||
GuiFrame = new GUIFrame(RectTransform.Load(GuiFrameSource, GUI.Canvas.ItemComponentHolder, Anchor.Center), style, color);
|
GuiFrame = new GUIFrame(RectTransform.Load(GuiFrameSource, GUI.Canvas, Anchor.Center), style, color);
|
||||||
DefaultLayout = GUILayoutSettings.Load(GuiFrameSource);
|
DefaultLayout = GUILayoutSettings.Load(GuiFrameSource);
|
||||||
if (GuiFrame != null)
|
if (GuiFrame != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -76,6 +76,9 @@ namespace Barotrauma.Items.Components
|
|||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serialize(false, false, description: "If true, the contained state indicator calculates how full the item is based on the total amount of items that can be stacked inside it, as opposed to how many of the inventory slots are occupied.")]
|
||||||
|
public bool ShowTotalStackCapacityInContainedStateIndicator { get; set; }
|
||||||
|
|
||||||
[Serialize(false, false, description: "Should the inventory of this item be kept open when the item is equipped by a character.")]
|
[Serialize(false, false, description: "Should the inventory of this item be kept open when the item is equipped by a character.")]
|
||||||
public bool KeepOpenWhenEquipped { get; set; }
|
public bool KeepOpenWhenEquipped { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void SetLightSourceTransform()
|
partial void SetLightSourceTransformProjSpecific()
|
||||||
{
|
{
|
||||||
if (ParentBody != null)
|
if (ParentBody != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,21 +6,23 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
partial class Controller : ItemComponent
|
partial class Controller : ItemComponent
|
||||||
{
|
{
|
||||||
|
private bool chatBoxOriginalState;
|
||||||
|
private bool isHUDsHidden;
|
||||||
|
|
||||||
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
|
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
|
||||||
{
|
{
|
||||||
if (focusTarget != null && character.ViewTarget == focusTarget)
|
if (focusTarget != null && character.ViewTarget == focusTarget)
|
||||||
{
|
{
|
||||||
foreach (ItemComponent ic in focusTarget.Components)
|
foreach (ItemComponent ic in focusTarget.Components)
|
||||||
{
|
{
|
||||||
ic.DrawHUD(spriteBatch, character);
|
if (ic.ShouldDrawHUD(character))
|
||||||
|
{
|
||||||
|
ic.DrawHUD(spriteBatch, character);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool crewAreaOriginalState;
|
|
||||||
private bool chatBoxOriginalState;
|
|
||||||
private bool isHUDsHidden;
|
|
||||||
|
|
||||||
partial void HideHUDs(bool value)
|
partial void HideHUDs(bool value)
|
||||||
{
|
{
|
||||||
if (isHUDsHidden == value) { return; }
|
if (isHUDsHidden == value) { return; }
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ namespace Barotrauma.Items.Components
|
|||||||
Stretch = true,
|
Stretch = true,
|
||||||
RelativeSpacing = 0.05f
|
RelativeSpacing = 0.05f
|
||||||
};
|
};
|
||||||
var inputLabel = new GUITextBlock(new RectTransform(Vector2.One, inputLabelArea.RectTransform), TextManager.Get("uilabel.input"), font: GUI.SubHeadingFont) { Padding = Vector4.Zero };
|
var inputLabel = new GUITextBlock(new RectTransform(Vector2.One, inputLabelArea.RectTransform), TextManager.Get("deconstructor.input", fallBackTag: "uilabel.input"), font: GUI.SubHeadingFont) { Padding = Vector4.Zero };
|
||||||
inputLabel.RectTransform.Resize(new Point((int) inputLabel.Font.MeasureString(inputLabel.Text).X, inputLabel.RectTransform.Rect.Height));
|
inputLabel.RectTransform.Resize(new Point((int) inputLabel.Font.MeasureString(inputLabel.Text).X, inputLabel.RectTransform.Rect.Height));
|
||||||
new GUIFrame(new RectTransform(Vector2.One, inputLabelArea.RectTransform), style: "HorizontalLine");
|
new GUIFrame(new RectTransform(Vector2.One, inputLabelArea.RectTransform), style: "HorizontalLine");
|
||||||
|
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ namespace Barotrauma.Items.Components
|
|||||||
Stretch = true,
|
Stretch = true,
|
||||||
RelativeSpacing = 0.03f
|
RelativeSpacing = 0.03f
|
||||||
};
|
};
|
||||||
var inputLabel = new GUITextBlock(new RectTransform(Vector2.One, separatorArea.RectTransform), TextManager.Get("uilabel.input"), font: GUI.SubHeadingFont) { Padding = Vector4.Zero };
|
var inputLabel = new GUITextBlock(new RectTransform(Vector2.One, separatorArea.RectTransform), TextManager.Get("fabricator.input", fallBackTag: "uilabel.input"), font: GUI.SubHeadingFont) { Padding = Vector4.Zero };
|
||||||
inputLabel.RectTransform.Resize(new Point((int) inputLabel.Font.MeasureString(inputLabel.Text).X, inputLabel.RectTransform.Rect.Height));
|
inputLabel.RectTransform.Resize(new Point((int) inputLabel.Font.MeasureString(inputLabel.Text).X, inputLabel.RectTransform.Rect.Height));
|
||||||
new GUIFrame(new RectTransform(Vector2.One, separatorArea.RectTransform), style: "HorizontalLine");
|
new GUIFrame(new RectTransform(Vector2.One, separatorArea.RectTransform), style: "HorizontalLine");
|
||||||
|
|
||||||
@@ -302,6 +302,12 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
HideEmptyItemListCategories();
|
HideEmptyItemListCategories();
|
||||||
|
|
||||||
|
if (selectedItem != null)
|
||||||
|
{
|
||||||
|
//reselect to recreate the info based on the new user's skills
|
||||||
|
SelectItem(character, selectedItem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawInputOverLay(SpriteBatch spriteBatch, GUICustomComponent overlayComponent)
|
private void DrawInputOverLay(SpriteBatch spriteBatch, GUICustomComponent overlayComponent)
|
||||||
@@ -343,13 +349,14 @@ namespace Barotrauma.Items.Components
|
|||||||
foreach (Item it in availableItems)
|
foreach (Item it in availableItems)
|
||||||
{
|
{
|
||||||
if (it.ParentInventory == inputContainer.Inventory) { continue; }
|
if (it.ParentInventory == inputContainer.Inventory) { continue; }
|
||||||
var rootContainer = it.GetRootContainer();
|
var rootInventoryOwner = it.GetRootInventoryOwner();
|
||||||
if (rootContainer?.OwnInventory?.visualSlots == null) { continue; }
|
Inventory rootInventory = (rootInventoryOwner as Item)?.OwnInventory as Inventory ?? (rootInventoryOwner as Character)?.Inventory;
|
||||||
int availableSlotIndex = rootContainer.OwnInventory.FindIndex(it.Container == rootContainer ? it : it.Container);
|
if (rootInventory?.visualSlots == null) { continue; }
|
||||||
|
int availableSlotIndex = rootInventory.FindIndex((it.Container != rootInventoryOwner ? it.Container : it) ?? it);
|
||||||
if (availableSlotIndex < 0) { continue; }
|
if (availableSlotIndex < 0) { continue; }
|
||||||
if (rootContainer.OwnInventory.visualSlots[availableSlotIndex].HighlightTimer <= 0.0f)
|
if (rootInventory.visualSlots[availableSlotIndex].HighlightTimer <= 0.0f)
|
||||||
{
|
{
|
||||||
rootContainer.OwnInventory.visualSlots[availableSlotIndex].ShowBorderHighlight(GUI.Style.Green, 0.5f, 0.5f, 0.2f);
|
rootInventory.visualSlots[availableSlotIndex].ShowBorderHighlight(GUI.Style.Green, 0.5f, 0.5f, 0.2f);
|
||||||
if (slotIndex < inputContainer.Capacity)
|
if (slotIndex < inputContainer.Capacity)
|
||||||
{
|
{
|
||||||
inputContainer.Inventory.visualSlots[slotIndex].ShowBorderHighlight(GUI.Style.Green, 0.5f, 0.5f, 0.2f);
|
inputContainer.Inventory.visualSlots[slotIndex].ShowBorderHighlight(GUI.Style.Green, 0.5f, 0.5f, 0.2f);
|
||||||
@@ -406,9 +413,16 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
toolTipText += " " + (int)Math.Round(requiredItem.MinCondition * 100) + "%";
|
toolTipText += " " + (int)Math.Round(requiredItem.MinCondition * 100) + "%";
|
||||||
}
|
}
|
||||||
else if(requiredItem.MaxCondition < 1.0f)
|
else if (requiredItem.MaxCondition < 1.0f)
|
||||||
{
|
{
|
||||||
toolTipText += " 0-" + (int)Math.Round(requiredItem.MaxCondition * 100) + "%";
|
if (requiredItem.MaxCondition <= 0.0f)
|
||||||
|
{
|
||||||
|
toolTipText += " " + (int)Math.Round(requiredItem.MaxCondition * 100) + "%";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
toolTipText += " 0-" + (int)Math.Round(requiredItem.MaxCondition * 100) + "%";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (requiredItem.MaxCondition <= 0.0f)
|
else if (requiredItem.MaxCondition <= 0.0f)
|
||||||
{
|
{
|
||||||
@@ -524,16 +538,6 @@ namespace Barotrauma.Items.Components
|
|||||||
var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.9f), selectedItemFrame.RectTransform, Anchor.Center)) { RelativeSpacing = 0.03f };
|
var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.9f), selectedItemFrame.RectTransform, Anchor.Center)) { RelativeSpacing = 0.03f };
|
||||||
var paddedReqFrame = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.9f), selectedItemReqsFrame.RectTransform, Anchor.Center)) { RelativeSpacing = 0.03f };
|
var paddedReqFrame = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.9f), selectedItemReqsFrame.RectTransform, Anchor.Center)) { RelativeSpacing = 0.03f };
|
||||||
|
|
||||||
/*var itemIcon = selectedItem.TargetItem.InventoryIcon ?? selectedItem.TargetItem.sprite;
|
|
||||||
if (itemIcon != null)
|
|
||||||
{
|
|
||||||
GUIImage img = new GUIImage(new RectTransform(new Point(40, 40), paddedFrame.RectTransform),
|
|
||||||
itemIcon, scaleToFit: true)
|
|
||||||
{
|
|
||||||
Color = selectedItem.TargetItem.InventoryIconColor
|
|
||||||
};
|
|
||||||
}*/
|
|
||||||
|
|
||||||
string itemName = GetRecipeNameAndAmount(selectedItem);
|
string itemName = GetRecipeNameAndAmount(selectedItem);
|
||||||
string name = itemName;
|
string name = itemName;
|
||||||
|
|
||||||
@@ -732,8 +736,6 @@ namespace Barotrauma.Items.Components
|
|||||||
Character user = Entity.FindEntityByID(userID) as Character;
|
Character user = Entity.FindEntityByID(userID) as Character;
|
||||||
|
|
||||||
State = newState;
|
State = newState;
|
||||||
timeUntilReady = newTimeUntilReady;
|
|
||||||
|
|
||||||
if (newState == FabricatorState.Stopped || itemIndex == -1)
|
if (newState == FabricatorState.Stopped || itemIndex == -1)
|
||||||
{
|
{
|
||||||
CancelFabricating();
|
CancelFabricating();
|
||||||
@@ -747,6 +749,7 @@ namespace Barotrauma.Items.Components
|
|||||||
SelectItem(user, fabricationRecipes[itemIndex]);
|
SelectItem(user, fabricationRecipes[itemIndex]);
|
||||||
StartFabricating(fabricationRecipes[itemIndex], user);
|
StartFabricating(fabricationRecipes[itemIndex], user);
|
||||||
}
|
}
|
||||||
|
timeUntilReady = newTimeUntilReady;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -507,7 +507,7 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
Vector2 origin = weaponSprite.Origin;
|
Vector2 origin = weaponSprite.Origin;
|
||||||
float scale = parentWidth / Math.Max(weaponSprite.size.X, weaponSprite.size.Y);
|
float scale = parentWidth / Math.Max(weaponSprite.size.X, weaponSprite.size.Y);
|
||||||
Color color = !hasPower ? NoPowerColor : turret.ActiveUser is null ? GUI.Style.Red : GUI.Style.Green;
|
Color color = !hasPower ? NoPowerColor : turret.ActiveUser is null ? Color.DimGray : GUI.Style.Green;
|
||||||
weaponSprite.Draw(batch, center, color, origin, rotation, scale, it.SpriteEffects);
|
weaponSprite.Draw(batch, center, color, origin, rotation, scale, it.SpriteEffects);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -537,9 +537,9 @@ namespace Barotrauma.Items.Components
|
|||||||
if (item.Submarine == null && displayedSubs.Count > 0 || // item not inside a sub anymore, but display is still showing subs
|
if (item.Submarine == null && displayedSubs.Count > 0 || // item not inside a sub anymore, but display is still showing subs
|
||||||
item.Submarine is { } itemSub &&
|
item.Submarine is { } itemSub &&
|
||||||
(
|
(
|
||||||
!displayedSubs.Contains(itemSub) || // current sub not displayed
|
!displayedSubs.Contains(itemSub) || // current sub not displayed
|
||||||
itemSub.DockedTo.Any(s => !displayedSubs.Contains(s)) || // some of the docked subs not displayed
|
itemSub.DockedTo.Any(s => !displayedSubs.Contains(s) && itemSub.ConnectedDockingPorts[s].IsLocked) || // some of the docked subs not displayed
|
||||||
displayedSubs.Any(s => s != itemSub && !itemSub.DockedTo.Contains(s)) // displaying a sub that shouldn't be displayed
|
displayedSubs.Any(s => s != itemSub && !itemSub.DockedTo.Contains(s)) // displaying a sub that shouldn't be displayed
|
||||||
) ||
|
) ||
|
||||||
prevResolution.X != GameMain.GraphicsWidth || prevResolution.Y != GameMain.GraphicsHeight || // resolution changed
|
prevResolution.X != GameMain.GraphicsWidth || prevResolution.Y != GameMain.GraphicsHeight || // resolution changed
|
||||||
!submarineContainer.Children.Any()) // We lack a GUI
|
!submarineContainer.Children.Any()) // We lack a GUI
|
||||||
@@ -1092,6 +1092,12 @@ namespace Barotrauma.Items.Components
|
|||||||
if (!(entity is Item it)) { continue; }
|
if (!(entity is Item it)) { continue; }
|
||||||
if (!electricalChildren.TryGetValue(miniMapGuiComponent, out GUIComponent component)) { continue; }
|
if (!electricalChildren.TryGetValue(miniMapGuiComponent, out GUIComponent component)) { continue; }
|
||||||
|
|
||||||
|
if (entity.Removed)
|
||||||
|
{
|
||||||
|
component.Visible = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (item.Submarine == null || !hasPower)
|
if (item.Submarine == null || !hasPower)
|
||||||
{
|
{
|
||||||
component.Color = component.OutlineColor = NoPowerElectricalColor;
|
component.Color = component.OutlineColor = NoPowerElectricalColor;
|
||||||
@@ -1117,7 +1123,7 @@ namespace Barotrauma.Items.Components
|
|||||||
int current = (int)-powerTransfer.CurrPowerConsumption, load = (int)powerTransfer.PowerLoad;
|
int current = (int)-powerTransfer.CurrPowerConsumption, load = (int)powerTransfer.PowerLoad;
|
||||||
|
|
||||||
line1 = TextManager.GetWithVariable("statusmonitor.junctionpower.tooltip", "[amount]", current.ToString(), fallBackTag: "statusmonitor.junctioncurrent.tooltip");
|
line1 = TextManager.GetWithVariable("statusmonitor.junctionpower.tooltip", "[amount]", current.ToString(), fallBackTag: "statusmonitor.junctioncurrent.tooltip");
|
||||||
line2 = TextManager.GetWithVariable("statusmonitor.junctionload.tooltip", "[amount]", load.ToString());
|
line2 = TextManager.GetWithVariables("statusmonitor.junctionload.tooltip", new string[] { "[amount]", "[load]" }, new string[] { load.ToString(), load.ToString() });
|
||||||
}
|
}
|
||||||
|
|
||||||
string line3 = TextManager.GetWithVariable("statusmonitor.durability.tooltip", "[amount]", durability.ToString());
|
string line3 = TextManager.GetWithVariable("statusmonitor.durability.tooltip", "[amount]", durability.ToString());
|
||||||
@@ -1329,7 +1335,7 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
RectangleF entityRect = ScaleRectToUI(structure, parent, border);
|
RectangleF entityRect = ScaleRectToUI(structure, parent, border);
|
||||||
Vector2 spriteScale = new Vector2(entityRect.Size.X / sprite.size.X, entityRect.Size.Y / sprite.size.Y);
|
Vector2 spriteScale = new Vector2(entityRect.Size.X / sprite.size.X, entityRect.Size.Y / sprite.size.Y);
|
||||||
sprite.Draw(spriteBatch, new Vector2(entityRect.Location.X + inflate, entityRect.Location.Y + inflate), structure.SpriteColor, Vector2.Zero, 0f, spriteScale, structure.SpriteEffects);
|
sprite.Draw(spriteBatch, new Vector2(entityRect.Location.X + inflate, entityRect.Location.Y + inflate), structure.SpriteColor, Vector2.Zero, 0f, spriteScale, sprite.effects ^ structure.SpriteEffects);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static RectangleF ScaleRectToUI(MapEntity entity, RectangleF parentRect, RectangleF worldBorders)
|
private static RectangleF ScaleRectToUI(MapEntity entity, RectangleF parentRect, RectangleF worldBorders)
|
||||||
@@ -1414,10 +1420,11 @@ namespace Barotrauma.Items.Components
|
|||||||
Vector2 drawPos = new Vector2(frame.Rect.Right - sizeX, frame.Rect.Y - sizeY / 2f);
|
Vector2 drawPos = new Vector2(frame.Rect.Right - sizeX, frame.Rect.Y - sizeY / 2f);
|
||||||
|
|
||||||
UISprite icon = GUI.Style.IconOverflowIndicator;
|
UISprite icon = GUI.Style.IconOverflowIndicator;
|
||||||
|
if (icon != null)
|
||||||
const int iconPadding = 4;
|
{
|
||||||
icon.Draw(spriteBatch, new Rectangle((int) drawPos.X - iconPadding, (int) drawPos.Y - iconPadding, (int) maxWidth + iconPadding * 2, (int) maxWidth + iconPadding * 2), Color.White, SpriteEffects.None);
|
const int iconPadding = 4;
|
||||||
|
icon.Draw(spriteBatch, new Rectangle((int) drawPos.X - iconPadding, (int) drawPos.Y - iconPadding, (int) maxWidth + iconPadding * 2, (int) maxWidth + iconPadding * 2), Color.White, SpriteEffects.None);
|
||||||
|
}
|
||||||
GUI.DrawString(spriteBatch, drawPos, text, GUI.Style.TextColor, font: GUI.SubHeadingFont);
|
GUI.DrawString(spriteBatch, drawPos, text, GUI.Style.TextColor, font: GUI.SubHeadingFont);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1712,5 +1719,20 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
return new MiniMapHullData(scaledPolygon, worldRect, parentRect.Size, snappedRectangles, hullRefs.ToImmutableArray());
|
return new MiniMapHullData(scaledPolygon, worldRect, parentRect.Size, snappedRectangles, hullRefs.ToImmutableArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void RemoveComponentSpecific()
|
||||||
|
{
|
||||||
|
base.RemoveComponentSpecific();
|
||||||
|
if (searchAutoComplete != null)
|
||||||
|
{
|
||||||
|
searchAutoComplete.RectTransform.Parent = null;
|
||||||
|
searchAutoComplete = null;
|
||||||
|
}
|
||||||
|
if (hullInfoFrame != null)
|
||||||
|
{
|
||||||
|
hullInfoFrame.RectTransform.Parent = null;
|
||||||
|
hullInfoFrame = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-1
@@ -14,7 +14,7 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
if (selectionUI == null)
|
if (selectionUI == null)
|
||||||
{
|
{
|
||||||
selectionUI = new SubmarineSelection(true, null, GUICanvas.Instance.ItemComponentHolder);
|
selectionUI = new SubmarineSelection(true, null, GUI.Canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
GuiFrame = selectionUI.GuiFrame;
|
GuiFrame = selectionUI.GuiFrame;
|
||||||
@@ -35,5 +35,15 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
selectionUI?.Update();
|
selectionUI?.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void RemoveComponentSpecific()
|
||||||
|
{
|
||||||
|
base.RemoveComponentSpecific();
|
||||||
|
if (selectionUI != null)
|
||||||
|
{
|
||||||
|
selectionUI.GuiFrame.RectTransform.Parent = null;
|
||||||
|
selectionUI = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -19,15 +19,6 @@ namespace Barotrauma.Items.Components
|
|||||||
private readonly List<(Vector2 position, ParticleEmitter emitter)> pumpOutEmitters = new List<(Vector2 position, ParticleEmitter emitter)>();
|
private readonly List<(Vector2 position, ParticleEmitter emitter)> pumpOutEmitters = new List<(Vector2 position, ParticleEmitter emitter)>();
|
||||||
private readonly List<(Vector2 position, ParticleEmitter emitter)> pumpInEmitters = new List<(Vector2 position, ParticleEmitter emitter)>();
|
private readonly List<(Vector2 position, ParticleEmitter emitter)> pumpInEmitters = new List<(Vector2 position, ParticleEmitter emitter)>();
|
||||||
|
|
||||||
public float CurrentBrokenVolume
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (item.ConditionPercentage > 10.0f || !IsActive) { return 0.0f; }
|
|
||||||
return (1.0f - item.ConditionPercentage / 10.0f) * 100.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
partial void InitProjSpecific(XElement element)
|
partial void InitProjSpecific(XElement element)
|
||||||
{
|
{
|
||||||
foreach (XElement subElement in element.Elements())
|
foreach (XElement subElement in element.Elements())
|
||||||
@@ -193,8 +184,6 @@ namespace Barotrauma.Items.Components
|
|||||||
private readonly float flickerFrequency = 1;
|
private readonly float flickerFrequency = 1;
|
||||||
public override void UpdateHUD(Character character, float deltaTime, Camera cam)
|
public override void UpdateHUD(Character character, float deltaTime, Camera cam)
|
||||||
{
|
{
|
||||||
pumpSpeedLockTimer -= deltaTime;
|
|
||||||
isActiveLockTimer -= deltaTime;
|
|
||||||
autoControlIndicator.Selected = IsAutoControlled;
|
autoControlIndicator.Selected = IsAutoControlled;
|
||||||
PowerButton.Enabled = isActiveLockTimer <= 0.0f;
|
PowerButton.Enabled = isActiveLockTimer <= 0.0f;
|
||||||
if (HasPower)
|
if (HasPower)
|
||||||
|
|||||||
@@ -83,9 +83,7 @@ namespace Barotrauma.Items.Components
|
|||||||
private const float ConnectedSubUpdateInterval = 1.0f;
|
private const float ConnectedSubUpdateInterval = 1.0f;
|
||||||
float connectedSubUpdateTimer;
|
float connectedSubUpdateTimer;
|
||||||
|
|
||||||
//Vector2 = vector from the ping source to the position of the disruption
|
private readonly List<(Vector2 pos, float strength)> disruptedDirections = new List<(Vector2 pos, float strength)>();
|
||||||
//float = strength of the disruption, between 0-1
|
|
||||||
private readonly List<Pair<Vector2, float>> disruptedDirections = new List<Pair<Vector2, float>>();
|
|
||||||
|
|
||||||
private readonly Dictionary<object, CachedDistance> markerDistances = new Dictionary<object, CachedDistance>();
|
private readonly Dictionary<object, CachedDistance> markerDistances = new Dictionary<object, CachedDistance>();
|
||||||
|
|
||||||
@@ -350,6 +348,27 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Vector2 GetTransducerPos()
|
||||||
|
{
|
||||||
|
if (!UseTransducers || connectedTransducers.Count == 0)
|
||||||
|
{
|
||||||
|
//use the position of the sub if the item is static (no body) and inside a sub
|
||||||
|
return item.Submarine != null && item.body == null ? item.Submarine.WorldPosition : item.WorldPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 transducerPosSum = Vector2.Zero;
|
||||||
|
foreach (ConnectedTransducer transducer in connectedTransducers)
|
||||||
|
{
|
||||||
|
if (transducer.Transducer.Item.Submarine != null && !CenterOnTransducers)
|
||||||
|
{
|
||||||
|
return transducer.Transducer.Item.Submarine.WorldPosition;
|
||||||
|
}
|
||||||
|
transducerPosSum += transducer.Transducer.Item.WorldPosition;
|
||||||
|
}
|
||||||
|
return transducerPosSum / connectedTransducers.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void OnItemLoaded()
|
public override void OnItemLoaded()
|
||||||
{
|
{
|
||||||
base.OnItemLoaded();
|
base.OnItemLoaded();
|
||||||
@@ -456,6 +475,19 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector2 transducerCenter = GetTransducerPos();
|
||||||
|
|
||||||
|
if (steering != null && steering.DockingModeEnabled && steering.ActiveDockingSource != null)
|
||||||
|
{
|
||||||
|
Vector2 worldFocusPos = (steering.ActiveDockingSource.Item.WorldPosition + steering.DockingTarget.Item.WorldPosition) / 2.0f;
|
||||||
|
DisplayOffset = Vector2.Lerp(DisplayOffset, worldFocusPos - transducerCenter, 0.1f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DisplayOffset = Vector2.Lerp(DisplayOffset, Vector2.Zero, 0.1f);
|
||||||
|
}
|
||||||
|
transducerCenter += DisplayOffset;
|
||||||
|
|
||||||
float distort = MathHelper.Clamp(1.0f - item.Condition / item.MaxCondition, 0.0f, 1.0f);
|
float distort = MathHelper.Clamp(1.0f - item.Condition / item.MaxCondition, 0.0f, 1.0f);
|
||||||
for (int i = sonarBlips.Count - 1; i >= 0; i--)
|
for (int i = sonarBlips.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
@@ -502,8 +534,6 @@ namespace Barotrauma.Items.Components
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 transducerCenter = GetTransducerPos() + DisplayOffset;
|
|
||||||
|
|
||||||
if (Level.Loaded != null)
|
if (Level.Loaded != null)
|
||||||
{
|
{
|
||||||
nearbyObjectUpdateTimer -= deltaTime;
|
nearbyObjectUpdateTimer -= deltaTime;
|
||||||
@@ -829,8 +859,7 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 transducerCenter = GetTransducerPos();
|
Vector2 transducerCenter = GetTransducerPos();// + DisplayOffset;
|
||||||
|
|
||||||
|
|
||||||
if (sonarBlips.Count > 0)
|
if (sonarBlips.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -840,7 +869,7 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
foreach (SonarBlip sonarBlip in sonarBlips)
|
foreach (SonarBlip sonarBlip in sonarBlips)
|
||||||
{
|
{
|
||||||
DrawBlip(spriteBatch, sonarBlip, transducerCenter, center, sonarBlip.FadeTimer / 2.0f * signalStrength, blipScale);
|
DrawBlip(spriteBatch, sonarBlip, transducerCenter + DisplayOffset, center, sonarBlip.FadeTimer / 2.0f * signalStrength, blipScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
spriteBatch.End();
|
spriteBatch.End();
|
||||||
@@ -849,8 +878,8 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
if (item.Submarine != null && !DetectSubmarineWalls)
|
if (item.Submarine != null && !DetectSubmarineWalls)
|
||||||
{
|
{
|
||||||
DrawDockingPorts(spriteBatch, transducerCenter, signalStrength);
|
|
||||||
transducerCenter += DisplayOffset;
|
transducerCenter += DisplayOffset;
|
||||||
|
DrawDockingPorts(spriteBatch, transducerCenter, signalStrength);
|
||||||
DrawOwnSubmarineBorders(spriteBatch, transducerCenter, signalStrength);
|
DrawOwnSubmarineBorders(spriteBatch, transducerCenter, signalStrength);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1083,14 +1112,11 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
DrawDockingIndicator(spriteBatch, steering, ref transducerCenter);
|
DrawDockingIndicator(spriteBatch, steering, ref transducerCenter);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
DisplayOffset = Vector2.Lerp(DisplayOffset, Vector2.Zero, 0.1f);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (DockingPort dockingPort in DockingPort.List)
|
foreach (DockingPort dockingPort in DockingPort.List)
|
||||||
{
|
{
|
||||||
if (Level.Loaded != null && dockingPort.Item.Submarine.WorldPosition.Y > Level.Loaded.Size.Y) { continue; }
|
if (Level.Loaded != null && dockingPort.Item.Submarine.WorldPosition.Y > Level.Loaded.Size.Y) { continue; }
|
||||||
|
if (dockingPort.Item.HiddenInGame) { continue; }
|
||||||
if (dockingPort.Item.Submarine == null) { continue; }
|
if (dockingPort.Item.Submarine == null) { continue; }
|
||||||
if (dockingPort.Item.Submarine.Info.IsWreck) { continue; }
|
if (dockingPort.Item.Submarine.Info.IsWreck) { continue; }
|
||||||
// docking ports should be shown even if defined as not, if the submarine is the same as the sonar's
|
// docking ports should be shown even if defined as not, if the submarine is the same as the sonar's
|
||||||
@@ -1131,9 +1157,6 @@ namespace Barotrauma.Items.Components
|
|||||||
Vector2 worldFocusPos = (steering.ActiveDockingSource.Item.WorldPosition + steering.DockingTarget.Item.WorldPosition) / 2.0f;
|
Vector2 worldFocusPos = (steering.ActiveDockingSource.Item.WorldPosition + steering.DockingTarget.Item.WorldPosition) / 2.0f;
|
||||||
worldFocusPos.X = steering.DockingTarget.Item.WorldPosition.X;
|
worldFocusPos.X = steering.DockingTarget.Item.WorldPosition.X;
|
||||||
|
|
||||||
DisplayOffset = Vector2.Lerp(DisplayOffset, worldFocusPos - transducerCenter, 0.1f);
|
|
||||||
transducerCenter += DisplayOffset;
|
|
||||||
|
|
||||||
Vector2 sourcePortDiff = (steering.ActiveDockingSource.Item.WorldPosition - transducerCenter) * scale;
|
Vector2 sourcePortDiff = (steering.ActiveDockingSource.Item.WorldPosition - transducerCenter) * scale;
|
||||||
Vector2 sourcePortPos = new Vector2(sourcePortDiff.X, -sourcePortDiff.Y);
|
Vector2 sourcePortPos = new Vector2(sourcePortDiff.X, -sourcePortDiff.Y);
|
||||||
Vector2 targetPortDiff = (steering.DockingTarget.Item.WorldPosition - transducerCenter) * scale;
|
Vector2 targetPortDiff = (steering.DockingTarget.Item.WorldPosition - transducerCenter) * scale;
|
||||||
@@ -1234,7 +1257,7 @@ namespace Barotrauma.Items.Components
|
|||||||
Vector2 disruptionPos = new Vector2(levelObject.Position.X, levelObject.Position.Y);
|
Vector2 disruptionPos = new Vector2(levelObject.Position.X, levelObject.Position.Y);
|
||||||
|
|
||||||
float disruptionDist = Vector2.Distance(pingSource, disruptionPos);
|
float disruptionDist = Vector2.Distance(pingSource, disruptionPos);
|
||||||
disruptedDirections.Add(new Pair<Vector2, float>((disruptionPos - pingSource) / disruptionDist, disruptionStrength));
|
disruptedDirections.Add(((disruptionPos - pingSource) / disruptionDist, disruptionStrength));
|
||||||
|
|
||||||
CreateBlipsForDisruption(disruptionPos, disruptionStrength);
|
CreateBlipsForDisruption(disruptionPos, disruptionStrength);
|
||||||
|
|
||||||
@@ -1246,7 +1269,7 @@ namespace Barotrauma.Items.Components
|
|||||||
float distSqr = Vector2.DistanceSquared(aiTarget.WorldPosition, pingSource);
|
float distSqr = Vector2.DistanceSquared(aiTarget.WorldPosition, pingSource);
|
||||||
if (distSqr > worldPingRadiusSqr) { continue; }
|
if (distSqr > worldPingRadiusSqr) { continue; }
|
||||||
float disruptionDist = (float)Math.Sqrt(distSqr);
|
float disruptionDist = (float)Math.Sqrt(distSqr);
|
||||||
disruptedDirections.Add(new Pair<Vector2, float>((aiTarget.WorldPosition - pingSource) / disruptionDist, aiTarget.SonarDisruption));
|
disruptedDirections.Add(((aiTarget.WorldPosition - pingSource) / disruptionDist, aiTarget.SonarDisruption));
|
||||||
CreateBlipsForDisruption(aiTarget.WorldPosition, disruption);
|
CreateBlipsForDisruption(aiTarget.WorldPosition, disruption);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1461,10 +1484,10 @@ namespace Barotrauma.Items.Components
|
|||||||
float transducerDist = transducerDiff.Length();
|
float transducerDist = transducerDiff.Length();
|
||||||
Vector2 pingDirection = transducerDiff / transducerDist;
|
Vector2 pingDirection = transducerDiff / transducerDist;
|
||||||
bool disrupted = false;
|
bool disrupted = false;
|
||||||
foreach (Pair<Vector2, float> disruptDir in disruptedDirections)
|
foreach ((Vector2 disruptPos, float disruptStrength) in disruptedDirections)
|
||||||
{
|
{
|
||||||
float dot = Vector2.Dot(pingDirection, disruptDir.First);
|
float dot = Vector2.Dot(pingDirection, disruptPos);
|
||||||
if (dot > 1.0f - disruptDir.Second)
|
if (dot > 1.0f - disruptStrength)
|
||||||
{
|
{
|
||||||
disrupted = true;
|
disrupted = true;
|
||||||
break;
|
break;
|
||||||
@@ -1670,13 +1693,12 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iconIdentifier == null || !targetIcons.ContainsKey(iconIdentifier))
|
if (iconIdentifier == null || !targetIcons.TryGetValue(iconIdentifier, out var iconInfo) || iconInfo.Item1 == null)
|
||||||
{
|
{
|
||||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)markerPos.X - 3, (int)markerPos.Y - 3, 6, 6), markerColor, thickness: 2);
|
GUI.DrawRectangle(spriteBatch, new Rectangle((int)markerPos.X - 3, (int)markerPos.Y - 3, 6, 6), markerColor, thickness: 2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var iconInfo = targetIcons[iconIdentifier];
|
|
||||||
iconInfo.Item1.Draw(spriteBatch, markerPos, iconInfo.Item2);
|
iconInfo.Item1.Draw(spriteBatch, markerPos, iconInfo.Item2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1689,7 +1711,10 @@ namespace Barotrauma.Items.Components
|
|||||||
Vector2 textSize = GUI.SmallFont.MeasureString(wrappedLabel);
|
Vector2 textSize = GUI.SmallFont.MeasureString(wrappedLabel);
|
||||||
|
|
||||||
//flip the text to left side when the marker is on the left side or goes outside the right edge of the interface
|
//flip the text to left side when the marker is on the left side or goes outside the right edge of the interface
|
||||||
if ((dir.X < 0.0f || labelPos.X + textSize.X + 10 > GuiFrame.Rect.X) && labelPos.X - textSize.X > 0) labelPos.X -= textSize.X + 10;
|
if (GuiFrame != null && (dir.X < 0.0f || labelPos.X + textSize.X + 10 > GuiFrame.Rect.X) && labelPos.X - textSize.X > 0)
|
||||||
|
{
|
||||||
|
labelPos.X -= textSize.X + 10;
|
||||||
|
}
|
||||||
|
|
||||||
GUI.DrawString(spriteBatch,
|
GUI.DrawString(spriteBatch,
|
||||||
new Vector2(labelPos.X + 10, labelPos.Y),
|
new Vector2(labelPos.X + 10, labelPos.Y),
|
||||||
|
|||||||
@@ -403,7 +403,7 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
if (GameMain.Client == null)
|
if (GameMain.Client == null)
|
||||||
{
|
{
|
||||||
item.SendSignal("1", "toggle_docking");
|
item.SendSignal(new Signal("1", sender: Character.Controlled), "toggle_docking");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -682,7 +682,7 @@ namespace Barotrauma.Items.Components
|
|||||||
enterOutpostPrompt?.Close();
|
enterOutpostPrompt?.Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (DockingSources.Any(d => d.Docked))
|
else if (connectedPorts.Any(d => d.Docked))
|
||||||
{
|
{
|
||||||
dockingButton.Text = undockText;
|
dockingButton.Text = undockText;
|
||||||
dockingContainer.Visible = true;
|
dockingContainer.Visible = true;
|
||||||
@@ -819,7 +819,7 @@ namespace Barotrauma.Items.Components
|
|||||||
Connection dockingConnection = item.Connections?.FirstOrDefault(c => c.Name == "toggle_docking");
|
Connection dockingConnection = item.Connections?.FirstOrDefault(c => c.Name == "toggle_docking");
|
||||||
if (dockingConnection != null)
|
if (dockingConnection != null)
|
||||||
{
|
{
|
||||||
connectedPorts = item.GetConnectedComponentsRecursive<DockingPort>(dockingConnection);
|
connectedPorts = item.GetConnectedComponentsRecursive<DockingPort>(dockingConnection, ignoreInactiveRelays: true);
|
||||||
}
|
}
|
||||||
checkConnectedPortsTimer = CheckConnectedPortsInterval;
|
checkConnectedPortsTimer = CheckConnectedPortsInterval;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,12 @@ namespace Barotrauma.Items.Components
|
|||||||
private GUIProgressBar chargeIndicator;
|
private GUIProgressBar chargeIndicator;
|
||||||
private GUIScrollBar rechargeSpeedSlider;
|
private GUIScrollBar rechargeSpeedSlider;
|
||||||
|
|
||||||
|
[Serialize(0.0f, true)]
|
||||||
|
public float RechargeWarningIndicatorLow { get; set; }
|
||||||
|
|
||||||
|
[Serialize(0.0f, true)]
|
||||||
|
public float RechargeWarningIndicatorHigh { get; set; }
|
||||||
|
|
||||||
public Vector2 DrawSize
|
public Vector2 DrawSize
|
||||||
{
|
{
|
||||||
//use the extents of the item as the draw size
|
//use the extents of the item as the draw size
|
||||||
@@ -28,19 +34,38 @@ namespace Barotrauma.Items.Components
|
|||||||
var upperArea = new GUIFrame(new RectTransform(new Vector2(1, 0.4f), paddedFrame.RectTransform, Anchor.TopCenter), style: null);
|
var upperArea = new GUIFrame(new RectTransform(new Vector2(1, 0.4f), paddedFrame.RectTransform, Anchor.TopCenter), style: null);
|
||||||
var lowerArea = new GUIFrame(new RectTransform(new Vector2(1, 0.6f), paddedFrame.RectTransform, Anchor.BottomCenter), style: null);
|
var lowerArea = new GUIFrame(new RectTransform(new Vector2(1, 0.6f), paddedFrame.RectTransform, Anchor.BottomCenter), style: null);
|
||||||
|
|
||||||
|
var rechargeRateContainer = new GUIFrame(new RectTransform(new Vector2(1, 0.4f), upperArea.RectTransform), style: null);
|
||||||
string rechargeStr = TextManager.Get("PowerContainerRechargeRate");
|
var rechargeLabel = new GUITextBlock(new RectTransform(new Vector2(0.4f, 0.0f), rechargeRateContainer.RectTransform, Anchor.CenterLeft),
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), upperArea.RectTransform, Anchor.TopCenter),
|
TextManager.Get("rechargerate"), textColor: GUI.Style.TextColor, font: GUI.SubHeadingFont, textAlignment: Alignment.CenterLeft);
|
||||||
"RechargeRate", textColor: GUI.Style.TextColor, font: GUI.SubHeadingFont, textAlignment: Alignment.Center)
|
string kW = TextManager.Get("kilowatt");
|
||||||
|
var rechargeText = new GUITextBlock(new RectTransform(new Vector2(0.6f, 1), rechargeRateContainer.RectTransform, Anchor.CenterRight),
|
||||||
|
"", textColor: GUI.Style.TextColor, font: GUI.Font, textAlignment: Alignment.CenterRight)
|
||||||
{
|
{
|
||||||
TextGetter = () =>
|
TextGetter = () => $"{(int)MathF.Round(currPowerConsumption)} {kW} ({(int)MathF.Round(RechargeRatio * 100)} %)"
|
||||||
{
|
|
||||||
return rechargeStr.Replace("[rate]", ((int)((rechargeSpeed / maxRechargeSpeed) * 100.0f)).ToString());
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
if (rechargeText.TextSize.X > rechargeText.Rect.Width) { rechargeText.Font = GUI.SmallFont; }
|
||||||
|
|
||||||
rechargeSpeedSlider = new GUIScrollBar(new RectTransform(new Vector2(0.9f, 0.4f), upperArea.RectTransform, Anchor.BottomCenter),
|
var rechargeSliderContainer = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.4f), upperArea.RectTransform, Anchor.BottomCenter));
|
||||||
barSize: 0.15f, style: "DeviceSlider")
|
|
||||||
|
if (RechargeWarningIndicatorLow > 0.0f || RechargeWarningIndicatorHigh > 0.0f)
|
||||||
|
{
|
||||||
|
var rechargeSliderFill = new GUICustomComponent(new RectTransform(new Vector2(0.95f, 0.9f), rechargeSliderContainer.RectTransform, Anchor.Center), (SpriteBatch sb, GUICustomComponent c) =>
|
||||||
|
{
|
||||||
|
if (RechargeWarningIndicatorLow > 0.0f)
|
||||||
|
{
|
||||||
|
float warningLow = c.Rect.Width * RechargeWarningIndicatorLow;
|
||||||
|
GUI.DrawRectangle(sb, new Vector2(c.Rect.X + warningLow, c.Rect.Y), new Vector2(c.Rect.Width - warningLow, c.Rect.Height), GUI.Style.Orange, isFilled: true);
|
||||||
|
}
|
||||||
|
if (RechargeWarningIndicatorHigh > 0.0f)
|
||||||
|
{
|
||||||
|
float warningHigh = c.Rect.Width * RechargeWarningIndicatorHigh;
|
||||||
|
GUI.DrawRectangle(sb, new Vector2(c.Rect.X + warningHigh, c.Rect.Y), new Vector2(c.Rect.Width - warningHigh, c.Rect.Height), GUI.Style.Red, isFilled: true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
rechargeSpeedSlider = new GUIScrollBar(new RectTransform(Vector2.One, rechargeSliderContainer.RectTransform, Anchor.Center),
|
||||||
|
barSize: 0.15f, style: "DeviceSliderSeeThrough")
|
||||||
{
|
{
|
||||||
Step = 0.1f,
|
Step = 0.1f,
|
||||||
OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
|
OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
|
||||||
@@ -61,17 +86,17 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
// lower area --------------------------
|
// lower area --------------------------
|
||||||
|
|
||||||
var textArea = new GUIFrame(new RectTransform(new Vector2(1, 0.4f), lowerArea.RectTransform), style: null);
|
var chargeTextContainer = new GUIFrame(new RectTransform(new Vector2(1, 0.4f), lowerArea.RectTransform), style: null);
|
||||||
var chargeLabel = new GUITextBlock(new RectTransform(new Vector2(0.4f, 0.0f), textArea.RectTransform, Anchor.CenterLeft),
|
var chargeLabel = new GUITextBlock(new RectTransform(new Vector2(0.4f, 0.0f), chargeTextContainer.RectTransform, Anchor.CenterLeft),
|
||||||
TextManager.Get("charge"), textColor: GUI.Style.TextColor, font: GUI.SubHeadingFont, textAlignment: Alignment.CenterLeft)
|
TextManager.Get("charge"), textColor: GUI.Style.TextColor, font: GUI.SubHeadingFont, textAlignment: Alignment.CenterLeft)
|
||||||
{
|
{
|
||||||
ToolTip = TextManager.Get("PowerTransferTipPower")
|
ToolTip = TextManager.Get("PowerTransferTipPower")
|
||||||
};
|
};
|
||||||
string kWmin = TextManager.Get("kilowattminute");
|
string kWmin = TextManager.Get("kilowattminute");
|
||||||
var chargeText = new GUITextBlock(new RectTransform(new Vector2(0.6f, 1), textArea.RectTransform, Anchor.CenterRight),
|
var chargeText = new GUITextBlock(new RectTransform(new Vector2(0.6f, 1), chargeTextContainer.RectTransform, Anchor.CenterRight),
|
||||||
"", textColor: GUI.Style.TextColor, font: GUI.Font, textAlignment: Alignment.CenterRight)
|
"", textColor: GUI.Style.TextColor, font: GUI.Font, textAlignment: Alignment.CenterRight)
|
||||||
{
|
{
|
||||||
TextGetter = () => $"{(int)Math.Round(charge)}/{(int)capacity} {kWmin} ({(int)Math.Round(MathUtils.Percentage(charge, capacity))} %)"
|
TextGetter = () => $"{(int)MathF.Round(charge)}/{(int)capacity} {kWmin} ({(int)MathF.Round(MathUtils.Percentage(charge, capacity))} %)"
|
||||||
};
|
};
|
||||||
if (chargeText.TextSize.X > chargeText.Rect.Width) { chargeText.Font = GUI.SmallFont; }
|
if (chargeText.TextSize.X > chargeText.Rect.Width) { chargeText.Font = GUI.SmallFont; }
|
||||||
|
|
||||||
|
|||||||
@@ -381,17 +381,17 @@ namespace Barotrauma.Items.Components
|
|||||||
if (deteriorationTimer > 0.0f)
|
if (deteriorationTimer > 0.0f)
|
||||||
{
|
{
|
||||||
GUI.DrawString(spriteBatch,
|
GUI.DrawString(spriteBatch,
|
||||||
new Vector2(item.WorldPosition.X, -item.WorldPosition.Y), "Deterioration delay " + ((int)deteriorationTimer) + (paused ? " [PAUSED]" : ""),
|
new Vector2(item.DrawPosition.X, -item.DrawPosition.Y), "Deterioration delay " + ((int)deteriorationTimer) + (paused ? " [PAUSED]" : ""),
|
||||||
paused ? Color.Cyan : Color.Lime, Color.Black * 0.5f);
|
paused ? Color.Cyan : Color.Lime, Color.Black * 0.5f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GUI.DrawString(spriteBatch,
|
GUI.DrawString(spriteBatch,
|
||||||
new Vector2(item.WorldPosition.X, -item.WorldPosition.Y), "Deteriorating at " + (int)(DeteriorationSpeed * 60.0f) + " units/min" + (paused ? " [PAUSED]" : ""),
|
new Vector2(item.DrawPosition.X, -item.DrawPosition.Y), "Deteriorating at " + (int)(DeteriorationSpeed * 60.0f) + " units/min" + (paused ? " [PAUSED]" : ""),
|
||||||
paused ? Color.Cyan : GUI.Style.Red, Color.Black * 0.5f);
|
paused ? Color.Cyan : GUI.Style.Red, Color.Black * 0.5f);
|
||||||
}
|
}
|
||||||
GUI.DrawString(spriteBatch,
|
GUI.DrawString(spriteBatch,
|
||||||
new Vector2(item.WorldPosition.X, -item.WorldPosition.Y + 20), "Condition: " + (int)item.Condition + "/" + (int)item.MaxCondition,
|
new Vector2(item.DrawPosition.X, -item.DrawPosition.Y + 20), "Condition: " + (int)item.Condition + "/" + (int)item.MaxCondition,
|
||||||
GUI.Style.Orange);
|
GUI.Style.Orange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -434,6 +434,7 @@ namespace Barotrauma.Items.Components
|
|||||||
DeteriorateAlways = msg.ReadBoolean();
|
DeteriorateAlways = msg.ReadBoolean();
|
||||||
tinkeringDuration = msg.ReadSingle();
|
tinkeringDuration = msg.ReadSingle();
|
||||||
tinkeringStrength = msg.ReadSingle();
|
tinkeringStrength = msg.ReadSingle();
|
||||||
|
tinkeringPowersDevices = msg.ReadBoolean();
|
||||||
ushort currentFixerID = msg.ReadUInt16();
|
ushort currentFixerID = msg.ReadUInt16();
|
||||||
currentFixerAction = (FixActions)msg.ReadRangedInteger(0, 2);
|
currentFixerAction = (FixActions)msg.ReadRangedInteger(0, 2);
|
||||||
CurrentFixer = currentFixerID != 0 ? Entity.FindEntityByID(currentFixerID) as Character : null;
|
CurrentFixer = currentFixerID != 0 ? Entity.FindEntityByID(currentFixerID) as Character : null;
|
||||||
|
|||||||
@@ -199,6 +199,26 @@ namespace Barotrauma.Items.Components
|
|||||||
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
||||||
{
|
{
|
||||||
snapped = msg.ReadBoolean();
|
snapped = msg.ReadBoolean();
|
||||||
|
|
||||||
|
if (!snapped)
|
||||||
|
{
|
||||||
|
UInt16 targetId = msg.ReadUInt16();
|
||||||
|
UInt16 sourceId = msg.ReadUInt16();
|
||||||
|
byte limbIndex = msg.ReadByte();
|
||||||
|
|
||||||
|
Item target = Entity.FindEntityByID(targetId) as Item;
|
||||||
|
if (target == null) { return; }
|
||||||
|
var source = Entity.FindEntityByID(sourceId);
|
||||||
|
if (source is Character sourceCharacter && limbIndex >= 0 && limbIndex < sourceCharacter.AnimController.Limbs.Length)
|
||||||
|
{
|
||||||
|
Limb sourceLimb = sourceCharacter.AnimController.Limbs[limbIndex];
|
||||||
|
Attach(sourceLimb, target);
|
||||||
|
}
|
||||||
|
else if (source is ISpatialEntity spatialEntity)
|
||||||
|
{
|
||||||
|
Attach(spatialEntity, target);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void RemoveComponentSpecific()
|
protected override void RemoveComponentSpecific()
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ namespace Barotrauma.Items.Components
|
|||||||
child.Enabled = buttonsEnabled;
|
child.Enabled = buttonsEnabled;
|
||||||
child.Children.ForEach(c => c.Enabled = buttonsEnabled);
|
child.Children.ForEach(c => c.Enabled = buttonsEnabled);
|
||||||
}
|
}
|
||||||
|
if (Container == null) { return; }
|
||||||
bool itemsContained = Container.Inventory.AllItems.Any();
|
bool itemsContained = Container.Inventory.AllItems.Any();
|
||||||
if (itemsContained)
|
if (itemsContained)
|
||||||
{
|
{
|
||||||
@@ -77,7 +78,7 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
if (GameMain.IsSingleplayer)
|
if (GameMain.IsSingleplayer)
|
||||||
{
|
{
|
||||||
SendSignal((int)userData);
|
SendSignal((int)userData, Character.Controlled);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -98,6 +99,7 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
partial void OnItemLoadedProjSpecific()
|
partial void OnItemLoadedProjSpecific()
|
||||||
{
|
{
|
||||||
|
if (Container == null) { return; }
|
||||||
Container.AllowUIOverlap = true;
|
Container.AllowUIOverlap = true;
|
||||||
Container.Inventory.RectTransform = containerHolder.RectTransform;
|
Container.Inventory.RectTransform = containerHolder.RectTransform;
|
||||||
}
|
}
|
||||||
@@ -109,7 +111,7 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
||||||
{
|
{
|
||||||
SendSignal(msg.ReadRangedInteger(0, Signals.Length - 1), isServerMessage: true);
|
SendSignal(msg.ReadRangedInteger(0, Signals.Length - 1), sender: null, isServerMessage: true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -23,7 +23,7 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
public static void DrawConnections(SpriteBatch spriteBatch, ConnectionPanel panel, Character character)
|
public static void DrawConnections(SpriteBatch spriteBatch, ConnectionPanel panel, Character character)
|
||||||
{
|
{
|
||||||
if (DraggingConnected?.Item.Removed ?? false)
|
if (DraggingConnected?.Item?.Removed ?? true)
|
||||||
{
|
{
|
||||||
DraggingConnected = null;
|
DraggingConnected = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void UpdateProjSpecific()
|
public override void UpdateHUD(Character character, float deltaTime, Camera cam)
|
||||||
{
|
{
|
||||||
bool elementVisibilityChanged = false;
|
bool elementVisibilityChanged = false;
|
||||||
int visibleElementCount = 0;
|
int visibleElementCount = 0;
|
||||||
@@ -209,6 +209,7 @@ namespace Barotrauma.Items.Components
|
|||||||
if (uiElement.Visible != visible)
|
if (uiElement.Visible != visible)
|
||||||
{
|
{
|
||||||
uiElement.Visible = visible;
|
uiElement.Visible = visible;
|
||||||
|
uiElement.IgnoreLayoutGroups = !uiElement.Visible;
|
||||||
elementVisibilityChanged = true;
|
elementVisibilityChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -223,6 +224,7 @@ namespace Barotrauma.Items.Components
|
|||||||
uiElement.RectTransform.RelativeSize = new Vector2(1.0f, elementSize);
|
uiElement.RectTransform.RelativeSize = new Vector2(1.0f, elementSize);
|
||||||
}
|
}
|
||||||
GuiFrame.Visible = visibleElementCount > 0;
|
GuiFrame.Visible = visibleElementCount > 0;
|
||||||
|
uiElementContainer.Recalculate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
public void Draw(SpriteBatch spriteBatch, bool editing, float itemDepth = -1)
|
public void Draw(SpriteBatch spriteBatch, bool editing, float itemDepth = -1)
|
||||||
{
|
{
|
||||||
if (!editing || !MapEntity.SelectedList.Contains(item)) return;
|
if (!editing || !MapEntity.SelectedList.Contains(item)) { return; }
|
||||||
|
|
||||||
Vector2 pos = item.WorldPosition + detectOffset;
|
Vector2 pos = item.WorldPosition + TransformedDetectOffset;
|
||||||
pos.Y = -pos.Y;
|
pos.Y = -pos.Y;
|
||||||
GUI.DrawRectangle(spriteBatch, pos - new Vector2(rangeX, rangeY), new Vector2(rangeX, rangeY) * 2.0f, Color.Cyan * 0.5f, isFilled: false, thickness: 2);
|
GUI.DrawRectangle(spriteBatch, pos - new Vector2(rangeX, rangeY), new Vector2(rangeX, rangeY) * 2.0f, Color.Cyan * 0.5f, isFilled: false, thickness: 2);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Microsoft.Xna.Framework;
|
using Barotrauma.Networking;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
namespace Barotrauma.Items.Components
|
namespace Barotrauma.Items.Components
|
||||||
@@ -19,5 +20,10 @@ namespace Barotrauma.Items.Components
|
|||||||
ShapeExtensions.DrawLine(spriteBatch, pos + Vector2.UnitX * range, pos - Vector2.UnitX * range, Color.Cyan * 0.5f, 2);
|
ShapeExtensions.DrawLine(spriteBatch, pos + Vector2.UnitX * range, pos - Vector2.UnitX * range, Color.Cyan * 0.5f, 2);
|
||||||
ShapeExtensions.DrawCircle(spriteBatch, pos, range, 32, Color.Cyan * 0.5f, 3);
|
ShapeExtensions.DrawCircle(spriteBatch, pos, range, 32, Color.Cyan * 0.5f, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
||||||
|
{
|
||||||
|
Channel = msg.ReadRangedInteger(MinChannel, MaxChannel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,7 +135,13 @@ namespace Barotrauma.Items.Components
|
|||||||
wireSprite = overrideSprite ?? defaultWireSprite;
|
wireSprite = overrideSprite ?? defaultWireSprite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void Draw(SpriteBatch spriteBatch, bool editing, float itemDepth = -1)
|
public void Draw(SpriteBatch spriteBatch, bool editing, float itemDepth = -1)
|
||||||
|
{
|
||||||
|
Draw(spriteBatch, editing, Vector2.Zero, itemDepth);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Draw(SpriteBatch spriteBatch, bool editing, Vector2 offset, float itemDepth = -1)
|
||||||
{
|
{
|
||||||
if (sections.Count == 0 && !IsActive || Hidden)
|
if (sections.Count == 0 && !IsActive || Hidden)
|
||||||
{
|
{
|
||||||
@@ -156,6 +162,8 @@ namespace Barotrauma.Items.Components
|
|||||||
drawOffset = sub.DrawPosition + sub.HiddenSubPosition;
|
drawOffset = sub.DrawPosition + sub.HiddenSubPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drawOffset += offset;
|
||||||
|
|
||||||
float baseDepth = UseSpriteDepth ? item.SpriteDepth : wireSprite.Depth;
|
float baseDepth = UseSpriteDepth ? item.SpriteDepth : wireSprite.Depth;
|
||||||
float depth = item.IsSelected ? 0.0f : SubEditorScreen.IsWiringMode() ? 0.02f : baseDepth + (item.ID % 100) * 0.000001f;// item.GetDrawDepth(wireSprite.Depth, wireSprite);
|
float depth = item.IsSelected ? 0.0f : SubEditorScreen.IsWiringMode() ? 0.02f : baseDepth + (item.ID % 100) * 0.000001f;// item.GetDrawDepth(wireSprite.Depth, wireSprite);
|
||||||
|
|
||||||
@@ -286,7 +294,6 @@ namespace Barotrauma.Items.Components
|
|||||||
item.Color, depth, 0.3f);
|
item.Color, depth, 0.3f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void UpdateEditing(List<Wire> wires)
|
public static void UpdateEditing(List<Wire> wires)
|
||||||
{
|
{
|
||||||
var doubleClicked = PlayerInput.DoubleClicked();
|
var doubleClicked = PlayerInput.DoubleClicked();
|
||||||
@@ -509,6 +516,31 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Move(Vector2 amount)
|
||||||
|
{
|
||||||
|
//only used in the sub editor, hence only in the client project
|
||||||
|
if (!item.IsSelected) { return; }
|
||||||
|
|
||||||
|
Vector2 wireNodeOffset = item.Submarine == null ? Vector2.Zero : item.Submarine.HiddenSubPosition + amount;
|
||||||
|
for (int i = 0; i < nodes.Count; i++)
|
||||||
|
{
|
||||||
|
if (i == 0 || i == nodes.Count - 1)
|
||||||
|
{
|
||||||
|
if (connections[0]?.Item != null && !connections[0].Item.IsSelected &&
|
||||||
|
(Submarine.RectContains(connections[0].Item.Rect, nodes[i] + wireNodeOffset) || Submarine.RectContains(connections[0].Item.Rect, nodes[i] + wireNodeOffset - amount)))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (connections[1]?.Item != null && !connections[1].Item.IsSelected &&
|
||||||
|
(Submarine.RectContains(connections[1].Item.Rect, nodes[i] + wireNodeOffset) || Submarine.RectContains(connections[1].Item.Rect, nodes[i] + wireNodeOffset - amount)))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nodes[i] += amount;
|
||||||
|
}
|
||||||
|
UpdateSections();
|
||||||
|
}
|
||||||
public bool IsMouseOn()
|
public bool IsMouseOn()
|
||||||
{
|
{
|
||||||
if (GUI.MouseOn == null)
|
if (GUI.MouseOn == null)
|
||||||
|
|||||||
@@ -301,7 +301,7 @@ namespace Barotrauma.Items.Components
|
|||||||
Dictionary<AfflictionPrefab, float> combinedAfflictionStrengths = new Dictionary<AfflictionPrefab, float>();
|
Dictionary<AfflictionPrefab, float> combinedAfflictionStrengths = new Dictionary<AfflictionPrefab, float>();
|
||||||
foreach (Affliction affliction in allAfflictions)
|
foreach (Affliction affliction in allAfflictions)
|
||||||
{
|
{
|
||||||
if (affliction.Strength < affliction.Prefab.ShowInHealthScannerThreshold || affliction.Strength <= 0.0f) continue;
|
if (affliction.Strength < affliction.Prefab.ShowInHealthScannerThreshold || affliction.Strength <= 0.0f) { continue; }
|
||||||
if (combinedAfflictionStrengths.ContainsKey(affliction.Prefab))
|
if (combinedAfflictionStrengths.ContainsKey(affliction.Prefab))
|
||||||
{
|
{
|
||||||
combinedAfflictionStrengths[affliction.Prefab] += affliction.Strength;
|
combinedAfflictionStrengths[affliction.Prefab] += affliction.Strength;
|
||||||
@@ -314,7 +314,7 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
foreach (AfflictionPrefab affliction in combinedAfflictionStrengths.Keys)
|
foreach (AfflictionPrefab affliction in combinedAfflictionStrengths.Keys)
|
||||||
{
|
{
|
||||||
texts.Add(TextManager.AddPunctuation(':', affliction.Name, Math.Max(((int)combinedAfflictionStrengths[affliction]), 1).ToString() + " %"));
|
texts.Add(TextManager.AddPunctuation(':', affliction.Name, Math.Max((int)combinedAfflictionStrengths[affliction], 1).ToString() + " %"));
|
||||||
textColors.Add(Color.Lerp(GUI.Style.Orange, GUI.Style.Red, combinedAfflictionStrengths[affliction] / affliction.MaxStrength));
|
textColors.Add(Color.Lerp(GUI.Style.Orange, GUI.Style.Red, combinedAfflictionStrengths[affliction] / affliction.MaxStrength));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -580,14 +580,20 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
private void GetAvailablePower(out float availableCharge, out float availableCapacity)
|
private void GetAvailablePower(out float availableCharge, out float availableCapacity)
|
||||||
{
|
{
|
||||||
var batteries = item.GetConnectedComponents<PowerContainer>();
|
|
||||||
|
|
||||||
availableCharge = 0.0f;
|
availableCharge = 0.0f;
|
||||||
availableCapacity = 0.0f;
|
availableCapacity = 0.0f;
|
||||||
foreach (PowerContainer battery in batteries)
|
if (item.Connections == null) { return; }
|
||||||
|
foreach (Connection c in item.Connections)
|
||||||
{
|
{
|
||||||
availableCharge += battery.Charge;
|
var recipients = c.Recipients;
|
||||||
availableCapacity += battery.Capacity;
|
foreach (Connection recipient in recipients)
|
||||||
|
{
|
||||||
|
if (!recipient.IsPower || !recipient.IsOutput) { continue; }
|
||||||
|
var battery = recipient.Item?.GetComponent<PowerContainer>();
|
||||||
|
if (battery == null) { continue; }
|
||||||
|
availableCharge += battery.Charge;
|
||||||
|
availableCapacity += battery.Capacity;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -647,7 +653,9 @@ namespace Barotrauma.Items.Components
|
|||||||
bool readyToFire = reload <= 0.0f && charged && availableAmmo.Any(p => p != null);
|
bool readyToFire = reload <= 0.0f && charged && availableAmmo.Any(p => p != null);
|
||||||
if (ShowChargeIndicator && PowerConsumption > 0.0f)
|
if (ShowChargeIndicator && PowerConsumption > 0.0f)
|
||||||
{
|
{
|
||||||
powerIndicator.Color = charged ? GUI.Style.Green : GUI.Style.Red;
|
powerIndicator.Color = charged ?
|
||||||
|
(HasPowerToShoot() ? GUI.Style.Green : GUI.Style.Orange) :
|
||||||
|
GUI.Style.Red;
|
||||||
if (flashLowPower)
|
if (flashLowPower)
|
||||||
{
|
{
|
||||||
powerIndicator.BarSize = 1;
|
powerIndicator.BarSize = 1;
|
||||||
|
|||||||
@@ -10,7 +10,13 @@ namespace Barotrauma.Items.Components
|
|||||||
int roundedValue = (int)Math.Round((1 - damageModifier.DamageMultiplier * damageModifier.ProbabilityMultiplier) * 100);
|
int roundedValue = (int)Math.Round((1 - damageModifier.DamageMultiplier * damageModifier.ProbabilityMultiplier) * 100);
|
||||||
if (roundedValue == 0) { return; }
|
if (roundedValue == 0) { return; }
|
||||||
string colorStr = XMLExtensions.ColorToString(GUI.Style.Green);
|
string colorStr = XMLExtensions.ColorToString(GUI.Style.Green);
|
||||||
description += $"\n ‖color:{colorStr}‖{roundedValue.ToString("-0;+#")}%‖color:end‖ {AfflictionPrefab.List.FirstOrDefault(ap => ap.Identifier.Equals(afflictionIdentifier, StringComparison.OrdinalIgnoreCase))?.Name ?? afflictionIdentifier}";
|
|
||||||
|
string afflictionName =
|
||||||
|
AfflictionPrefab.List.FirstOrDefault(ap => ap.Identifier.Equals(afflictionIdentifier, StringComparison.OrdinalIgnoreCase))?.Name ??
|
||||||
|
TextManager.Get($"afflictiontype.{afflictionIdentifier}", returnNull: true) ??
|
||||||
|
afflictionIdentifier;
|
||||||
|
|
||||||
|
description += $"\n ‖color:{colorStr}‖{roundedValue.ToString("-0;+#")}%‖color:end‖ {afflictionName}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AddTooltipInfo(ref string name, ref string description)
|
public override void AddTooltipInfo(ref string name, ref string description)
|
||||||
@@ -33,9 +39,9 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
GetDamageModifierText(ref description, damageModifier, afflictionIdentifier);
|
GetDamageModifierText(ref description, damageModifier, afflictionIdentifier);
|
||||||
}
|
}
|
||||||
foreach (string afflictionIdentifier in damageModifier.ParsedAfflictionTypes)
|
foreach (string afflictionType in damageModifier.ParsedAfflictionTypes)
|
||||||
{
|
{
|
||||||
GetDamageModifierText(ref description, damageModifier, afflictionIdentifier);
|
GetDamageModifierText(ref description, damageModifier, afflictionType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1584,6 +1584,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
containedState = item.Condition / item.MaxCondition;
|
containedState = item.Condition / item.MaxCondition;
|
||||||
}
|
}
|
||||||
|
else if (itemContainer.ShowTotalStackCapacityInContainedStateIndicator)
|
||||||
|
{
|
||||||
|
containedState = itemContainer.Inventory.AllItems.Count() / (float)(itemContainer.GetMaxStackSize(0) * itemContainer.Capacity);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var containedItem = itemContainer.Inventory.slots[Math.Max(itemContainer.ContainedStateIndicatorSlot, 0)].FirstOrDefault();
|
var containedItem = itemContainer.Inventory.slots[Math.Max(itemContainer.ContainedStateIndicatorSlot, 0)].FirstOrDefault();
|
||||||
|
|||||||
@@ -105,6 +105,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!SubEditorScreen.IsLayerVisible(this)) { return false;}
|
||||||
|
|
||||||
return parentInventory == null && (body == null || body.Enabled) && ShowItems;
|
return parentInventory == null && (body == null || body.Enabled) && ShowItems;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -255,7 +258,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true)
|
public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true)
|
||||||
{
|
{
|
||||||
if (!Visible || (!editing && HiddenInGame)) { return; }
|
if (!Visible || (!editing && HiddenInGame) || !SubEditorScreen.IsLayerVisible(this)) { return; }
|
||||||
|
|
||||||
if (editing)
|
if (editing)
|
||||||
{
|
{
|
||||||
@@ -582,7 +585,10 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DecorativeSprite.UpdateSpriteStates(Prefab.DecorativeSpriteGroups, spriteAnimState, ID, deltaTime, ConditionalMatches);
|
if (Prefab.DecorativeSpriteGroups.Count > 0)
|
||||||
|
{
|
||||||
|
DecorativeSprite.UpdateSpriteStates(Prefab.DecorativeSpriteGroups, spriteAnimState, ID, deltaTime, ConditionalMatches);
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var upgrade in Upgrades)
|
foreach (var upgrade in Upgrades)
|
||||||
{
|
{
|
||||||
@@ -591,10 +597,13 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
var spriteState = spriteAnimState[decorativeSprite];
|
var spriteState = spriteAnimState[decorativeSprite];
|
||||||
spriteState.IsActive = true;
|
spriteState.IsActive = true;
|
||||||
foreach (var _ in decorativeSprite.IsActiveConditionals.Where(conditional => !ConditionalMatches(conditional)))
|
foreach (var conditional in decorativeSprite.IsActiveConditionals)
|
||||||
{
|
{
|
||||||
spriteState.IsActive = false;
|
if (!ConditionalMatches(conditional))
|
||||||
break;
|
{
|
||||||
|
spriteState.IsActive = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1172,7 +1181,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
texts.Add(new ColoredText(nameText, GUI.Style.TextColor, false, false));
|
texts.Add(new ColoredText(nameText, GUI.Style.TextColor, false, false));
|
||||||
|
|
||||||
if (CampaignInteractionType != CampaignMode.InteractionType.None)
|
if (CampaignMode.BlocksInteraction(CampaignInteractionType))
|
||||||
{
|
{
|
||||||
texts.Add(new ColoredText(TextManager.GetWithVariable($"CampaignInteraction.{CampaignInteractionType}", "[key]", GameMain.Config.KeyBindText(InputType.Use)), Color.Cyan, false, false));
|
texts.Add(new ColoredText(TextManager.GetWithVariable($"CampaignInteraction.{CampaignInteractionType}", "[key]", GameMain.Config.KeyBindText(InputType.Use)), Color.Cyan, false, false));
|
||||||
}
|
}
|
||||||
@@ -1541,6 +1550,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
Vector2 pos = Vector2.Zero;
|
Vector2 pos = Vector2.Zero;
|
||||||
Submarine sub = null;
|
Submarine sub = null;
|
||||||
|
float rotation = 0.0f;
|
||||||
int itemContainerIndex = -1;
|
int itemContainerIndex = -1;
|
||||||
int inventorySlotIndex = -1;
|
int inventorySlotIndex = -1;
|
||||||
|
|
||||||
@@ -1552,7 +1562,7 @@ namespace Barotrauma
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
pos = new Vector2(msg.ReadSingle(), msg.ReadSingle());
|
pos = new Vector2(msg.ReadSingle(), msg.ReadSingle());
|
||||||
|
rotation = msg.ReadRangedSingle(0, MathHelper.TwoPi, 8);
|
||||||
ushort subID = msg.ReadUInt16();
|
ushort subID = msg.ReadUInt16();
|
||||||
if (subID > 0)
|
if (subID > 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -315,7 +315,7 @@ namespace Barotrauma.MapCreatures.Behavior
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RemoveClaim(itemId);
|
RemoveClaim(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -14,7 +13,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return ShowGaps;
|
return ShowGaps && SubEditorScreen.IsLayerVisible(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,11 +24,14 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public override void Draw(SpriteBatch sb, bool editing, bool back = true)
|
public override void Draw(SpriteBatch sb, bool editing, bool back = true)
|
||||||
{
|
{
|
||||||
|
float depth = (ID % 255) * 0.000001f;
|
||||||
|
|
||||||
if (GameMain.DebugDraw && Screen.Selected.Cam.Zoom > 0.1f)
|
if (GameMain.DebugDraw && Screen.Selected.Cam.Zoom > 0.1f)
|
||||||
{
|
{
|
||||||
Vector2 center = new Vector2(WorldRect.X + rect.Width / 2.0f, -(WorldRect.Y - rect.Height / 2.0f));
|
if (FlowTargetHull != null)
|
||||||
GUI.DrawLine(sb, center, center + new Vector2(flowForce.X, -flowForce.Y) / 10.0f, GUI.Style.Red);
|
{
|
||||||
GUI.DrawLine(sb, center + Vector2.One * 5.0f, center + new Vector2(lerpedFlowForce.X, -lerpedFlowForce.Y) / 10.0f + Vector2.One * 5.0f, GUI.Style.Orange);
|
DrawArrow(FlowTargetHull, IsHorizontal ? rect.Height: rect.Width, Math.Abs(lerpedFlowForce.Length()), Color.Red * 0.3f);
|
||||||
|
}
|
||||||
|
|
||||||
if (outsideCollisionBlocker.Enabled && Submarine != null)
|
if (outsideCollisionBlocker.Enabled && Submarine != null)
|
||||||
{
|
{
|
||||||
@@ -42,12 +44,10 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!editing || !ShowGaps) { return; }
|
if (!editing || !ShowGaps || !SubEditorScreen.IsLayerVisible(this)) { return; }
|
||||||
|
|
||||||
Color clr = (open == 0.0f) ? GUI.Style.Red : Color.Cyan;
|
Color clr = (open == 0.0f) ? GUI.Style.Red : Color.Cyan;
|
||||||
if (IsHighlighted) clr = Color.Gold;
|
if (IsHighlighted) { clr = Color.Gold; }
|
||||||
|
|
||||||
float depth = (ID % 255) * 0.000001f;
|
|
||||||
|
|
||||||
GUI.DrawRectangle(
|
GUI.DrawRectangle(
|
||||||
sb, new Rectangle(WorldRect.X, -WorldRect.Y, rect.Width, rect.Height),
|
sb, new Rectangle(WorldRect.X, -WorldRect.Y, rect.Width, rect.Height),
|
||||||
@@ -81,33 +81,38 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < linkedTo.Count; i++)
|
for (int i = 0; i < linkedTo.Count; i++)
|
||||||
{
|
{
|
||||||
Vector2 dir = IsHorizontal ?
|
if (linkedTo[i] is Hull hull)
|
||||||
new Vector2(Math.Sign(linkedTo[i].Rect.Center.X - rect.Center.X), 0.0f)
|
|
||||||
: new Vector2(0.0f, Math.Sign((rect.Y - rect.Height / 2.0f) - (linkedTo[i].Rect.Y - linkedTo[i].Rect.Height / 2.0f)));
|
|
||||||
|
|
||||||
Vector2 arrowPos = new Vector2(WorldRect.Center.X, -(WorldRect.Y - WorldRect.Height / 2));
|
|
||||||
arrowPos += new Vector2(dir.X * (WorldRect.Width / 2), dir.Y * (WorldRect.Height / 2));
|
|
||||||
|
|
||||||
float arrowWidth = 32.0f;
|
|
||||||
float arrowSize = 15.0f;
|
|
||||||
|
|
||||||
bool invalidDir = false;
|
|
||||||
if (dir == Vector2.Zero)
|
|
||||||
{
|
{
|
||||||
invalidDir = true;
|
DrawArrow(hull, 32.0f, 15f, clr);
|
||||||
dir = IsHorizontal ? Vector2.UnitX : Vector2.UnitY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GUI.Arrow.Draw(sb,
|
|
||||||
arrowPos, invalidDir ? Color.Red : clr * 0.8f,
|
|
||||||
GUI.Arrow.Origin, MathUtils.VectorToAngle(dir) + MathHelper.PiOver2,
|
|
||||||
IsHorizontal ?
|
|
||||||
new Vector2(Math.Min(rect.Height, arrowWidth) / GUI.Arrow.size.X, arrowSize / GUI.Arrow.size.Y) :
|
|
||||||
new Vector2(Math.Min(rect.Width, arrowWidth) / GUI.Arrow.size.X, arrowSize / GUI.Arrow.size.Y),
|
|
||||||
SpriteEffects.None, depth);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DrawArrow(Hull targetHull, float arrowWidth, float arrowLength, Color clr)
|
||||||
|
{
|
||||||
|
Vector2 dir = IsHorizontal ?
|
||||||
|
new Vector2(Math.Sign(targetHull.Rect.Center.X - rect.Center.X), 0.0f)
|
||||||
|
: new Vector2(0.0f, Math.Sign((rect.Y - rect.Height / 2.0f) - (targetHull.Rect.Y - targetHull.Rect.Height / 2.0f)));
|
||||||
|
|
||||||
|
Vector2 arrowPos = new Vector2(WorldRect.Center.X, -(WorldRect.Y - WorldRect.Height / 2));
|
||||||
|
arrowPos += new Vector2(dir.X * (WorldRect.Width / 2), dir.Y * (WorldRect.Height / 2));
|
||||||
|
|
||||||
|
bool invalidDir = false;
|
||||||
|
if (dir == Vector2.Zero)
|
||||||
|
{
|
||||||
|
invalidDir = true;
|
||||||
|
dir = IsHorizontal ? Vector2.UnitX : Vector2.UnitY;
|
||||||
|
}
|
||||||
|
|
||||||
|
GUI.Arrow.Draw(sb,
|
||||||
|
arrowPos, invalidDir ? Color.Red : clr * 0.8f,
|
||||||
|
GUI.Arrow.Origin, MathUtils.VectorToAngle(dir) + MathHelper.PiOver2,
|
||||||
|
IsHorizontal ?
|
||||||
|
new Vector2(Math.Min(rect.Height, arrowWidth) / GUI.Arrow.size.X, arrowLength / GUI.Arrow.size.Y) :
|
||||||
|
new Vector2(Math.Min(rect.Width, arrowWidth) / GUI.Arrow.size.X, arrowLength / GUI.Arrow.size.Y),
|
||||||
|
SpriteEffects.None, depth);
|
||||||
|
}
|
||||||
|
|
||||||
if (IsSelected)
|
if (IsSelected)
|
||||||
{
|
{
|
||||||
GUI.DrawRectangle(sb,
|
GUI.DrawRectangle(sb,
|
||||||
@@ -128,8 +133,14 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
//no flow particles between linked hulls (= rooms consisting of multiple hulls)
|
//no flow particles between linked hulls (= rooms consisting of multiple hulls)
|
||||||
if (hull1.linkedTo.Contains(hull2)) { return; }
|
if (hull1.linkedTo.Contains(hull2)) { return; }
|
||||||
if (hull1.linkedTo.Any(h => h.linkedTo.Contains(hull1) && h.linkedTo.Contains(hull2))) { return; }
|
foreach (var linkedEntity in hull1.linkedTo)
|
||||||
if (hull2.linkedTo.Any(h => h.linkedTo.Contains(hull1) && h.linkedTo.Contains(hull2))) { return; }
|
{
|
||||||
|
if (linkedEntity is Hull h && h.linkedTo.Contains(hull1) && h.linkedTo.Contains(hull2)) { return; }
|
||||||
|
}
|
||||||
|
foreach (var linkedEntity in hull2.linkedTo)
|
||||||
|
{
|
||||||
|
if (linkedEntity is Hull h && h.linkedTo.Contains(hull1) && h.linkedTo.Contains(hull2)) { return; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 pos = Position;
|
Vector2 pos = Position;
|
||||||
@@ -202,9 +213,9 @@ namespace Barotrauma
|
|||||||
"watersplash",
|
"watersplash",
|
||||||
(Submarine == null ? pos : pos + Submarine.Position) - Vector2.UnitY * Rand.Range(0.0f, 10.0f),
|
(Submarine == null ? pos : pos + Submarine.Position) - Vector2.UnitY * Rand.Range(0.0f, 10.0f),
|
||||||
velocity, 0, flowTargetHull);
|
velocity, 0, flowTargetHull);
|
||||||
|
|
||||||
if (particle != null)
|
if (particle != null)
|
||||||
{
|
{
|
||||||
|
if (particle.CurrentHull == null) { GameMain.ParticleManager.RemoveParticle(particle); }
|
||||||
particle.Size *= Math.Min(Math.Abs(flowForce.X / 500.0f), 5.0f);
|
particle.Size *= Math.Min(Math.Abs(flowForce.X / 500.0f), 5.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -232,13 +243,13 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (Math.Sign(flowTargetHull.Rect.Y - rect.Y) != Math.Sign(lerpedFlowForce.Y)) return;
|
if (Math.Sign(flowTargetHull.Rect.Y - rect.Y) != Math.Sign(lerpedFlowForce.Y)) { return; }
|
||||||
|
|
||||||
float particlesPerSec = open * rect.Width * 0.3f * particleAmountMultiplier;
|
float particlesPerSec = Math.Max(open * rect.Width * 0.3f * particleAmountMultiplier, 20.0f);
|
||||||
float emitInterval = 1.0f / particlesPerSec;
|
float emitInterval = 1.0f / particlesPerSec;
|
||||||
while (particleTimer > emitInterval)
|
while (particleTimer > emitInterval)
|
||||||
{
|
{
|
||||||
pos.X = Rand.Range(rect.X, rect.X + rect.Width);
|
pos.X = Rand.Range(rect.X, rect.X + rect.Width + 1);
|
||||||
Vector2 velocity = new Vector2(
|
Vector2 velocity = new Vector2(
|
||||||
lerpedFlowForce.X * Rand.Range(0.5f, 0.7f),
|
lerpedFlowForce.X * Rand.Range(0.5f, 0.7f),
|
||||||
MathHelper.Clamp(lerpedFlowForce.Y, -500.0f, 1000.0f) * Rand.Range(0.5f, 0.7f));
|
MathHelper.Clamp(lerpedFlowForce.Y, -500.0f, 1000.0f) * Rand.Range(0.5f, 0.7f));
|
||||||
@@ -246,17 +257,21 @@ namespace Barotrauma
|
|||||||
if (flowTargetHull.WaterVolume < flowTargetHull.Volume * 0.95f)
|
if (flowTargetHull.WaterVolume < flowTargetHull.Volume * 0.95f)
|
||||||
{
|
{
|
||||||
var splash = GameMain.ParticleManager.CreateParticle(
|
var splash = GameMain.ParticleManager.CreateParticle(
|
||||||
"watersplash",
|
"watersplash",
|
||||||
Submarine == null ? pos : pos + Submarine.Position,
|
Submarine == null ? pos : pos + Submarine.Position,
|
||||||
velocity, 0, FlowTargetHull);
|
velocity, 0, FlowTargetHull);
|
||||||
if (splash != null) splash.Size = splash.Size * MathHelper.Clamp(rect.Width / 50.0f, 0.8f, 4.0f);
|
if (splash != null)
|
||||||
|
{
|
||||||
|
if (splash.CurrentHull == null) { GameMain.ParticleManager.RemoveParticle(splash); }
|
||||||
|
splash.Size *= MathHelper.Clamp(rect.Width / 50.0f, 1.5f, 4.0f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (Math.Abs(flowForce.Y) > 190.0f && Rand.Range(0.0f, 1.0f) < 0.3f && flowTargetHull.WaterVolume > flowTargetHull.Volume * 0.1f)
|
if (Math.Abs(flowForce.Y) > 190.0f && Rand.Range(0.0f, 1.0f) < 0.3f && flowTargetHull.WaterVolume > flowTargetHull.Volume * 0.1f)
|
||||||
{
|
{
|
||||||
GameMain.ParticleManager.CreateParticle(
|
GameMain.ParticleManager.CreateParticle(
|
||||||
"bubbles",
|
"bubbles",
|
||||||
Submarine == null ? pos : pos + Submarine.Position,
|
Submarine == null ? pos : pos + Submarine.Position,
|
||||||
flowForce / 2.0f, 0, FlowTargetHull);
|
flowForce / 2.0f, 0, FlowTargetHull);
|
||||||
}
|
}
|
||||||
particleTimer -= emitInterval;
|
particleTimer -= emitInterval;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,11 +37,24 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private double lastAmbientLightEditTime;
|
private double lastAmbientLightEditTime;
|
||||||
|
|
||||||
|
private float drawSurface;
|
||||||
|
|
||||||
|
public float DrawSurface
|
||||||
|
{
|
||||||
|
get { return drawSurface; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (Math.Abs(drawSurface - value) < 0.00001f) { return; }
|
||||||
|
drawSurface = MathHelper.Clamp(value, rect.Y - rect.Height, rect.Y);
|
||||||
|
update = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override bool SelectableInEditor
|
public override bool SelectableInEditor
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return ShowHulls;
|
return ShowHulls && SubEditorScreen.IsLayerVisible(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,86 +151,96 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void UpdateProjSpecific(float deltaTime, Camera cam)
|
partial void UpdateProjSpecific(float deltaTime, Camera _)
|
||||||
{
|
{
|
||||||
serverUpdateDelay -= deltaTime;
|
float waterDepth = WaterVolume / rect.Width;
|
||||||
if (serverUpdateDelay <= 0.0f)
|
//interpolate the position of the rendered surface towards the "target surface"
|
||||||
{
|
drawSurface = Math.Max(MathHelper.Lerp(
|
||||||
ApplyRemoteState();
|
drawSurface,
|
||||||
}
|
rect.Y - rect.Height + waterDepth,
|
||||||
|
deltaTime * 10.0f), rect.Y - rect.Height);
|
||||||
|
|
||||||
if (networkUpdatePending)
|
if (GameMain.Client != null)
|
||||||
{
|
{
|
||||||
networkUpdateTimer += deltaTime;
|
serverUpdateDelay -= deltaTime;
|
||||||
if (networkUpdateTimer > 0.2f)
|
if (serverUpdateDelay <= 0.0f)
|
||||||
{
|
{
|
||||||
if (!pendingSectionUpdates.Any() && !pendingDecalUpdates.Any())
|
ApplyRemoteState();
|
||||||
{
|
|
||||||
GameMain.NetworkMember?.CreateEntityEvent(this);
|
|
||||||
}
|
|
||||||
foreach (Decal decal in pendingDecalUpdates)
|
|
||||||
{
|
|
||||||
GameMain.NetworkMember?.CreateEntityEvent(this, new object[] { decal });
|
|
||||||
}
|
|
||||||
foreach (int pendingSectionUpdate in pendingSectionUpdates)
|
|
||||||
{
|
|
||||||
GameMain.NetworkMember?.CreateEntityEvent(this, new object[] { pendingSectionUpdate });
|
|
||||||
}
|
|
||||||
pendingSectionUpdates.Clear();
|
|
||||||
networkUpdatePending = false;
|
|
||||||
networkUpdateTimer = 0.0f;
|
|
||||||
}
|
}
|
||||||
}
|
if (networkUpdatePending)
|
||||||
|
|
||||||
if (!IdFreed)
|
|
||||||
{
|
|
||||||
if (EditWater)
|
|
||||||
{
|
{
|
||||||
Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);
|
networkUpdateTimer += deltaTime;
|
||||||
if (Submarine.RectContains(WorldRect, position))
|
if (networkUpdateTimer > 0.2f)
|
||||||
{
|
{
|
||||||
if (PlayerInput.PrimaryMouseButtonHeld())
|
if (!pendingSectionUpdates.Any() && !pendingDecalUpdates.Any())
|
||||||
{
|
{
|
||||||
WaterVolume += 1500.0f;
|
GameMain.NetworkMember?.CreateEntityEvent(this);
|
||||||
networkUpdatePending = true;
|
|
||||||
serverUpdateDelay = 0.5f;
|
|
||||||
}
|
}
|
||||||
else if (PlayerInput.SecondaryMouseButtonHeld())
|
foreach (Decal decal in pendingDecalUpdates)
|
||||||
{
|
{
|
||||||
WaterVolume -= 1500.0f;
|
GameMain.NetworkMember?.CreateEntityEvent(this, new object[] { decal });
|
||||||
networkUpdatePending = true;
|
|
||||||
serverUpdateDelay = 0.5f;
|
|
||||||
}
|
}
|
||||||
}
|
foreach (int pendingSectionUpdate in pendingSectionUpdates)
|
||||||
}
|
|
||||||
else if (EditFire)
|
|
||||||
{
|
|
||||||
Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);
|
|
||||||
if (Submarine.RectContains(WorldRect, position))
|
|
||||||
{
|
|
||||||
if (PlayerInput.PrimaryMouseButtonClicked())
|
|
||||||
{
|
{
|
||||||
new FireSource(position, this, isNetworkMessage: true);
|
GameMain.NetworkMember?.CreateEntityEvent(this, new object[] { pendingSectionUpdate });
|
||||||
networkUpdatePending = true;
|
|
||||||
serverUpdateDelay = 0.5f;
|
|
||||||
}
|
}
|
||||||
|
pendingSectionUpdates.Clear();
|
||||||
|
networkUpdatePending = false;
|
||||||
|
networkUpdateTimer = 0.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (waterVolume < 1.0f) { return; }
|
/*if (waterVolume < 1.0f) { return; }
|
||||||
for (int i = 1; i < waveY.Length - 1; i++)
|
for (int i = 1; i < waveY.Length - 1; i++)
|
||||||
{
|
{
|
||||||
float maxDelta = Math.Max(Math.Abs(rightDelta[i]), Math.Abs(leftDelta[i]));
|
float maxDelta = Math.Max(Math.Abs(rightDelta[i]), Math.Abs(leftDelta[i]));
|
||||||
if (maxDelta > 1.0f && maxDelta > Rand.Range(1.0f, 10.0f))
|
if (maxDelta > 0.1f && maxDelta > Rand.Range(0.1f, 10.0f))
|
||||||
{
|
{
|
||||||
var particlePos = new Vector2(rect.X + WaveWidth * i, surface + waveY[i]);
|
var particlePos = new Vector2(rect.X + WaveWidth * i, surface + waveY[i]);
|
||||||
if (Submarine != null) particlePos += Submarine.Position;
|
if (Submarine != null) { particlePos += Submarine.Position; }
|
||||||
|
|
||||||
GameMain.ParticleManager.CreateParticle("mist",
|
GameMain.ParticleManager.CreateParticle("mist",
|
||||||
particlePos,
|
particlePos,
|
||||||
new Vector2(0.0f, -50.0f), 0.0f, this);
|
new Vector2(0.0f, -50.0f), 0.0f, this);
|
||||||
}
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UpdateCheats(float deltaTime, Camera cam)
|
||||||
|
{
|
||||||
|
bool primaryMouseButtonHeld = PlayerInput.PrimaryMouseButtonHeld();
|
||||||
|
bool secondaryMouseButtonHeld = PlayerInput.SecondaryMouseButtonHeld();
|
||||||
|
if (!primaryMouseButtonHeld && !secondaryMouseButtonHeld) { return; }
|
||||||
|
|
||||||
|
Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);
|
||||||
|
Hull hull = FindHull(position);
|
||||||
|
|
||||||
|
if (hull == null || hull.IdFreed) { return; }
|
||||||
|
if (EditWater)
|
||||||
|
{
|
||||||
|
if (primaryMouseButtonHeld)
|
||||||
|
{
|
||||||
|
hull.WaterVolume += 100000.0f * deltaTime;
|
||||||
|
hull.networkUpdatePending = true;
|
||||||
|
hull.serverUpdateDelay = 0.5f;
|
||||||
|
}
|
||||||
|
else if (secondaryMouseButtonHeld)
|
||||||
|
{
|
||||||
|
hull.WaterVolume -= 100000.0f * deltaTime;
|
||||||
|
hull.networkUpdatePending = true;
|
||||||
|
hull.serverUpdateDelay = 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (EditFire)
|
||||||
|
{
|
||||||
|
if (primaryMouseButtonHeld)
|
||||||
|
{
|
||||||
|
new FireSource(position, hull, isNetworkMessage: true);
|
||||||
|
hull.networkUpdatePending = true;
|
||||||
|
hull.serverUpdateDelay = 0.5f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,7 +266,7 @@ namespace Barotrauma
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ShowHulls && !GameMain.DebugDraw) { return; }
|
if ((!ShowHulls || !SubEditorScreen.IsLayerVisible(this)) && !GameMain.DebugDraw) { return; }
|
||||||
|
|
||||||
if (!editing && (!GameMain.DebugDraw || Screen.Selected.Cam.Zoom < 0.1f)) { return; }
|
if (!editing && (!GameMain.DebugDraw || Screen.Selected.Cam.Zoom < 0.1f)) { return; }
|
||||||
|
|
||||||
@@ -385,6 +408,11 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static readonly Vector3[] corners = new Vector3[6];
|
||||||
|
private static readonly Vector2[] uvCoords = new Vector2[4];
|
||||||
|
private static readonly Vector3[] prevCorners = new Vector3[2];
|
||||||
|
private static readonly Vector2[] prevUVs = new Vector2[2];
|
||||||
|
|
||||||
private void UpdateVertices(Camera cam, EntityGrid entityGrid, WaterRenderer renderer)
|
private void UpdateVertices(Camera cam, EntityGrid entityGrid, WaterRenderer renderer)
|
||||||
{
|
{
|
||||||
Vector2 submarinePos = Submarine == null ? Vector2.Zero : Submarine.DrawPosition;
|
Vector2 submarinePos = Submarine == null ? Vector2.Zero : Submarine.DrawPosition;
|
||||||
@@ -397,33 +425,25 @@ namespace Barotrauma
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!renderer.IndoorsVertices.ContainsKey(entityGrid))
|
|
||||||
{
|
|
||||||
renderer.IndoorsVertices[entityGrid] = new VertexPositionColorTexture[WaterRenderer.DefaultIndoorsBufferSize];
|
|
||||||
renderer.PositionInIndoorsBuffer[entityGrid] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//calculate where the surface should be based on the water volume
|
//calculate where the surface should be based on the water volume
|
||||||
float top = rect.Y + submarinePos.Y;
|
float top = rect.Y + submarinePos.Y;
|
||||||
float bottom = top - rect.Height;
|
float bottom = top - rect.Height;
|
||||||
float renderSurface = drawSurface + submarinePos.Y;
|
float renderSurface = drawSurface + submarinePos.Y;
|
||||||
|
|
||||||
if (bottom > cam.WorldView.Y || top < cam.WorldView.Y - cam.WorldView.Height) return;
|
if (bottom > cam.WorldView.Y || top < cam.WorldView.Y - cam.WorldView.Height) { return; }
|
||||||
|
if (rect.X + submarinePos.X > cam.WorldView.Right || rect.Right + submarinePos.X < cam.WorldView.X) { return; }
|
||||||
|
|
||||||
Matrix transform = cam.Transform * Matrix.CreateOrthographic(GameMain.GraphicsWidth, GameMain.GraphicsHeight, -1, 1) * 0.5f;
|
Matrix transform = cam.Transform * Matrix.CreateOrthographic(GameMain.GraphicsWidth, GameMain.GraphicsHeight, -1, 1) * 0.5f;
|
||||||
if (!update)
|
if (!update)
|
||||||
{
|
{
|
||||||
// create the four corners of our triangle.
|
// create the four corners of our triangle.
|
||||||
|
|
||||||
Vector3[] corners = new Vector3[4];
|
|
||||||
|
|
||||||
corners[0] = new Vector3(rect.X, rect.Y, 0.0f);
|
corners[0] = new Vector3(rect.X, rect.Y, 0.0f);
|
||||||
corners[1] = new Vector3(rect.X + rect.Width, rect.Y, 0.0f);
|
corners[1] = new Vector3(rect.X + rect.Width, rect.Y, 0.0f);
|
||||||
|
|
||||||
corners[2] = new Vector3(corners[1].X, rect.Y - rect.Height, 0.0f);
|
corners[2] = new Vector3(corners[1].X, rect.Y - rect.Height, 0.0f);
|
||||||
corners[3] = new Vector3(corners[0].X, corners[2].Y, 0.0f);
|
corners[3] = new Vector3(corners[0].X, corners[2].Y, 0.0f);
|
||||||
|
|
||||||
Vector2[] uvCoords = new Vector2[4];
|
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
corners[i] += new Vector3(submarinePos, 0.0f);
|
corners[i] += new Vector3(submarinePos, 0.0f);
|
||||||
@@ -443,6 +463,15 @@ namespace Barotrauma
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!renderer.IndoorsVertices.ContainsKey(entityGrid))
|
||||||
|
{
|
||||||
|
renderer.IndoorsVertices[entityGrid] = new VertexPositionColorTexture[WaterRenderer.DefaultIndoorsBufferSize];
|
||||||
|
}
|
||||||
|
if (!renderer.PositionInIndoorsBuffer.ContainsKey(entityGrid))
|
||||||
|
{
|
||||||
|
renderer.PositionInIndoorsBuffer[entityGrid] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
float x = rect.X;
|
float x = rect.X;
|
||||||
if (Submarine != null) { x += Submarine.DrawPosition.X; }
|
if (Submarine != null) { x += Submarine.DrawPosition.X; }
|
||||||
|
|
||||||
@@ -454,15 +483,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
x += start * WaveWidth;
|
x += start * WaveWidth;
|
||||||
|
|
||||||
Vector3[] prevCorners = new Vector3[2];
|
|
||||||
Vector2[] prevUVs = new Vector2[2];
|
|
||||||
|
|
||||||
int width = WaveWidth;
|
int width = WaveWidth;
|
||||||
|
|
||||||
for (int i = start; i < end; i++)
|
for (int i = start; i < end; i++)
|
||||||
{
|
{
|
||||||
Vector3[] corners = new Vector3[6];
|
|
||||||
|
|
||||||
//top left
|
//top left
|
||||||
corners[0] = new Vector3(x, top, 0.0f);
|
corners[0] = new Vector3(x, top, 0.0f);
|
||||||
//watersurface left
|
//watersurface left
|
||||||
@@ -714,7 +738,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
remoteBackgroundSections.Clear();
|
remoteBackgroundSections.Clear();
|
||||||
|
|
||||||
if (remoteDecals.Any())
|
if (remoteDecals.Count > 0)
|
||||||
{
|
{
|
||||||
decals.Clear();
|
decals.Clear();
|
||||||
foreach (RemoteDecal remoteDecal in remoteDecals)
|
foreach (RemoteDecal remoteDecal in remoteDecals)
|
||||||
|
|||||||
+1
-1
@@ -95,7 +95,7 @@ namespace Barotrauma
|
|||||||
var prefab = ToolBox.SelectWeightedRandom(availablePrefabs, availablePrefabs.Select(p => p.GetCommonness(level.GenerationParams)).ToList(), Rand.RandSync.ClientOnly);
|
var prefab = ToolBox.SelectWeightedRandom(availablePrefabs, availablePrefabs.Select(p => p.GetCommonness(level.GenerationParams)).ToList(), Rand.RandSync.ClientOnly);
|
||||||
if (prefab == null) { break; }
|
if (prefab == null) { break; }
|
||||||
|
|
||||||
int amount = Rand.Range(prefab.SwarmMin, prefab.SwarmMax, Rand.RandSync.ClientOnly);
|
int amount = Rand.Range(prefab.SwarmMin, prefab.SwarmMax + 1, Rand.RandSync.ClientOnly);
|
||||||
List<BackgroundCreature> swarmMembers = new List<BackgroundCreature>();
|
List<BackgroundCreature> swarmMembers = new List<BackgroundCreature>();
|
||||||
for (int n = 0; n < amount; n++)
|
for (int n = 0; n < amount; n++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ namespace Barotrauma
|
|||||||
public readonly WaterVertexData IndoorsSurfaceBottomColor = new WaterVertexData(0.2f, 0.1f, 0.9f, 1.0f);
|
public readonly WaterVertexData IndoorsSurfaceBottomColor = new WaterVertexData(0.2f, 0.1f, 0.9f, 1.0f);
|
||||||
|
|
||||||
public VertexPositionTexture[] vertices = new VertexPositionTexture[DefaultBufferSize];
|
public VertexPositionTexture[] vertices = new VertexPositionTexture[DefaultBufferSize];
|
||||||
public Dictionary<EntityGrid, VertexPositionColorTexture[]> IndoorsVertices = new Dictionary<EntityGrid, VertexPositionColorTexture[]>();// VertexPositionColorTexture[DefaultBufferSize * 2];
|
public Dictionary<EntityGrid, VertexPositionColorTexture[]> IndoorsVertices = new Dictionary<EntityGrid, VertexPositionColorTexture[]>();
|
||||||
|
|
||||||
public Effect WaterEffect
|
public Effect WaterEffect
|
||||||
{
|
{
|
||||||
@@ -81,13 +81,17 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (basicEffect == null)
|
if (basicEffect == null)
|
||||||
{
|
{
|
||||||
basicEffect = new BasicEffect(GameMain.Instance.GraphicsDevice);
|
basicEffect = new BasicEffect(GameMain.Instance.GraphicsDevice)
|
||||||
basicEffect.VertexColorEnabled = false;
|
{
|
||||||
|
VertexColorEnabled = false,
|
||||||
basicEffect.TextureEnabled = true;
|
TextureEnabled = true
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readonly VertexPositionColorTexture[] tempVertices = new VertexPositionColorTexture[6];
|
||||||
|
private readonly Vector3[] tempCorners = new Vector3[4];
|
||||||
|
|
||||||
public void RenderWater(SpriteBatch spriteBatch, RenderTarget2D texture, Camera cam)
|
public void RenderWater(SpriteBatch spriteBatch, RenderTarget2D texture, Camera cam)
|
||||||
{
|
{
|
||||||
spriteBatch.GraphicsDevice.BlendState = BlendState.NonPremultiplied;
|
spriteBatch.GraphicsDevice.BlendState = BlendState.NonPremultiplied;
|
||||||
@@ -139,29 +143,26 @@ namespace Barotrauma
|
|||||||
|
|
||||||
WaterEffect.CurrentTechnique.Passes[0].Apply();
|
WaterEffect.CurrentTechnique.Passes[0].Apply();
|
||||||
|
|
||||||
VertexPositionColorTexture[] verts = new VertexPositionColorTexture[6];
|
|
||||||
|
|
||||||
Rectangle view = cam != null ? cam.WorldView : spriteBatch.GraphicsDevice.Viewport.Bounds;
|
Rectangle view = cam != null ? cam.WorldView : spriteBatch.GraphicsDevice.Viewport.Bounds;
|
||||||
|
|
||||||
var corners = new Vector3[4];
|
tempCorners[0] = new Vector3(view.X, view.Y, 0.1f);
|
||||||
corners[0] = new Vector3(view.X, view.Y, 0.1f);
|
tempCorners[1] = new Vector3(view.Right, view.Y, 0.1f);
|
||||||
corners[1] = new Vector3(view.Right, view.Y, 0.1f);
|
tempCorners[2] = new Vector3(view.Right, view.Y - view.Height, 0.1f);
|
||||||
corners[2] = new Vector3(view.Right, view.Y - view.Height, 0.1f);
|
tempCorners[3] = new Vector3(view.X, view.Y - view.Height, 0.1f);
|
||||||
corners[3] = new Vector3(view.X, view.Y - view.Height, 0.1f);
|
|
||||||
|
|
||||||
WaterVertexData backGroundColor = new WaterVertexData(0.1f, 0.1f, 0.5f, 1.0f);
|
WaterVertexData backGroundColor = new WaterVertexData(0.1f, 0.1f, 0.5f, 1.0f);
|
||||||
verts[0] = new VertexPositionColorTexture(corners[0], backGroundColor, Vector2.Zero);
|
tempVertices[0] = new VertexPositionColorTexture(tempCorners[0], backGroundColor, Vector2.Zero);
|
||||||
verts[1] = new VertexPositionColorTexture(corners[1], backGroundColor, Vector2.Zero);
|
tempVertices[1] = new VertexPositionColorTexture(tempCorners[1], backGroundColor, Vector2.Zero);
|
||||||
verts[2] = new VertexPositionColorTexture(corners[2], backGroundColor, Vector2.Zero);
|
tempVertices[2] = new VertexPositionColorTexture(tempCorners[2], backGroundColor, Vector2.Zero);
|
||||||
verts[3] = new VertexPositionColorTexture(corners[0], backGroundColor, Vector2.Zero);
|
tempVertices[3] = new VertexPositionColorTexture(tempCorners[0], backGroundColor, Vector2.Zero);
|
||||||
verts[4] = new VertexPositionColorTexture(corners[2], backGroundColor, Vector2.Zero);
|
tempVertices[4] = new VertexPositionColorTexture(tempCorners[2], backGroundColor, Vector2.Zero);
|
||||||
verts[5] = new VertexPositionColorTexture(corners[3], backGroundColor, Vector2.Zero);
|
tempVertices[5] = new VertexPositionColorTexture(tempCorners[3], backGroundColor, Vector2.Zero);
|
||||||
|
|
||||||
spriteBatch.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, verts, 0, 2);
|
spriteBatch.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, tempVertices, 0, 2);
|
||||||
|
|
||||||
foreach (KeyValuePair<EntityGrid, VertexPositionColorTexture[]> subVerts in IndoorsVertices)
|
foreach (KeyValuePair<EntityGrid, VertexPositionColorTexture[]> subVerts in IndoorsVertices)
|
||||||
{
|
{
|
||||||
if (!PositionInIndoorsBuffer.ContainsKey(subVerts.Key) || PositionInIndoorsBuffer[subVerts.Key] == 0) continue;
|
if (!PositionInIndoorsBuffer.ContainsKey(subVerts.Key) || PositionInIndoorsBuffer[subVerts.Key] == 0) { continue; }
|
||||||
|
|
||||||
offset = WavePos;
|
offset = WavePos;
|
||||||
if (subVerts.Key.Submarine != null) { offset -= subVerts.Key.Submarine.WorldPosition; }
|
if (subVerts.Key.Submarine != null) { offset -= subVerts.Key.Submarine.WorldPosition; }
|
||||||
@@ -207,11 +208,23 @@ namespace Barotrauma
|
|||||||
basicEffect.CurrentTechnique.Passes[0].Apply();
|
basicEffect.CurrentTechnique.Passes[0].Apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readonly List<EntityGrid> buffersToRemove = new List<EntityGrid>();
|
||||||
public void ResetBuffers()
|
public void ResetBuffers()
|
||||||
{
|
{
|
||||||
PositionInBuffer = 0;
|
PositionInBuffer = 0;
|
||||||
PositionInIndoorsBuffer.Clear();
|
PositionInIndoorsBuffer.Clear();
|
||||||
IndoorsVertices.Clear();
|
buffersToRemove.Clear();
|
||||||
|
foreach (var buffer in IndoorsVertices.Keys)
|
||||||
|
{
|
||||||
|
if (buffer.Submarine?.Removed ?? false)
|
||||||
|
{
|
||||||
|
buffersToRemove.Add(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (var bufferToRemove in buffersToRemove)
|
||||||
|
{
|
||||||
|
IndoorsVertices.Remove(bufferToRemove);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|||||||
@@ -517,7 +517,7 @@ namespace Barotrauma.Lights
|
|||||||
private void RefreshConvexHullList(ConvexHullList chList, Vector2 lightPos, Submarine sub)
|
private void RefreshConvexHullList(ConvexHullList chList, Vector2 lightPos, Submarine sub)
|
||||||
{
|
{
|
||||||
var fullChList = ConvexHull.HullLists.Find(x => x.Submarine == sub);
|
var fullChList = ConvexHull.HullLists.Find(x => x.Submarine == sub);
|
||||||
if (fullChList == null) return;
|
if (fullChList == null) { return; }
|
||||||
|
|
||||||
chList.List = fullChList.List.FindAll(ch => ch.Enabled && MathUtils.CircleIntersectsRectangle(lightPos, TextureRange, ch.BoundingBox));
|
chList.List = fullChList.List.FindAll(ch => ch.Enabled && MathUtils.CircleIntersectsRectangle(lightPos, TextureRange, ch.BoundingBox));
|
||||||
|
|
||||||
@@ -530,104 +530,120 @@ namespace Barotrauma.Lights
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void CheckHullsInRange()
|
private void CheckHullsInRange()
|
||||||
{
|
{
|
||||||
List<Submarine> subs = new List<Submarine>(Submarine.Loaded);
|
foreach (Submarine sub in Submarine.Loaded)
|
||||||
subs.Add(null);
|
|
||||||
|
|
||||||
foreach (Submarine sub in subs)
|
|
||||||
{
|
{
|
||||||
//find the list of convexhulls that belong to the sub
|
CheckHullsInRange(sub);
|
||||||
var chList = hullsInRange.Find(x => x.Submarine == sub);
|
}
|
||||||
|
//check convex hulls that aren't in any sub
|
||||||
|
CheckHullsInRange(null);
|
||||||
|
}
|
||||||
|
|
||||||
//not found -> create one
|
private void CheckHullsInRange(Submarine sub)
|
||||||
if (chList == null)
|
{
|
||||||
|
//find the list of convexhulls that belong to the sub
|
||||||
|
ConvexHullList chList = null;
|
||||||
|
foreach (var ch in hullsInRange)
|
||||||
|
{
|
||||||
|
if (ch.Submarine == sub)
|
||||||
{
|
{
|
||||||
chList = new ConvexHullList(sub);
|
chList = ch;
|
||||||
hullsInRange.Add(chList);
|
break;
|
||||||
NeedsRecalculation = true;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (chList.List.Any(ch => ch.LastVertexChangeTime > lastRecalculationTime && !chList.IsHidden.Contains(ch)))
|
//not found -> create one
|
||||||
|
if (chList == null)
|
||||||
|
{
|
||||||
|
chList = new ConvexHullList(sub);
|
||||||
|
hullsInRange.Add(chList);
|
||||||
|
NeedsRecalculation = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var ch in chList.List)
|
||||||
|
{
|
||||||
|
if (ch.LastVertexChangeTime > lastRecalculationTime && !chList.IsHidden.Contains(ch))
|
||||||
{
|
{
|
||||||
NeedsRecalculation = true;
|
NeedsRecalculation = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Vector2 lightPos = position;
|
Vector2 lightPos = position;
|
||||||
if (ParentSub == null)
|
if (ParentSub == null)
|
||||||
|
{
|
||||||
|
//light and the convexhulls are both outside
|
||||||
|
if (sub == null)
|
||||||
{
|
{
|
||||||
//light and the convexhulls are both outside
|
if (NeedsHullCheck)
|
||||||
if (sub == null)
|
|
||||||
{
|
{
|
||||||
if (NeedsHullCheck)
|
RefreshConvexHullList(chList, lightPos, null);
|
||||||
{
|
|
||||||
RefreshConvexHullList(chList, lightPos, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//light is outside, convexhulls inside a sub
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lightPos -= sub.Position;
|
|
||||||
|
|
||||||
Rectangle subBorders = sub.Borders;
|
|
||||||
subBorders.Location += sub.HiddenSubPosition.ToPoint() - new Point(0, sub.Borders.Height);
|
|
||||||
|
|
||||||
//only draw if the light overlaps with the sub
|
|
||||||
if (!MathUtils.CircleIntersectsRectangle(lightPos, TextureRange, subBorders))
|
|
||||||
{
|
|
||||||
if (chList.List.Count > 0) NeedsRecalculation = true;
|
|
||||||
chList.List.Clear();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
RefreshConvexHullList(chList, lightPos, sub);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//light is outside, convexhulls inside a sub
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//light is inside, convexhull outside
|
lightPos -= sub.Position;
|
||||||
if (sub == null) continue;
|
|
||||||
|
|
||||||
//light and convexhull are both inside the same sub
|
Rectangle subBorders = sub.Borders;
|
||||||
if (sub == ParentSub)
|
subBorders.Location += sub.HiddenSubPosition.ToPoint() - new Point(0, sub.Borders.Height);
|
||||||
|
|
||||||
|
//only draw if the light overlaps with the sub
|
||||||
|
if (!MathUtils.CircleIntersectsRectangle(lightPos, TextureRange, subBorders))
|
||||||
{
|
{
|
||||||
if (NeedsHullCheck)
|
if (chList.List.Count > 0) { NeedsRecalculation = true; }
|
||||||
{
|
chList.List.Clear();
|
||||||
RefreshConvexHullList(chList, lightPos, sub);
|
return;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
//light and convexhull are inside different subs
|
|
||||||
else
|
RefreshConvexHullList(chList, lightPos, sub);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//light is inside, convexhull outside
|
||||||
|
if (sub == null) { return; }
|
||||||
|
|
||||||
|
//light and convexhull are both inside the same sub
|
||||||
|
if (sub == ParentSub)
|
||||||
|
{
|
||||||
|
if (NeedsHullCheck)
|
||||||
{
|
{
|
||||||
if (sub.DockedTo.Contains(ParentSub) && !NeedsHullCheck) continue;
|
|
||||||
|
|
||||||
lightPos -= (sub.Position - ParentSub.Position);
|
|
||||||
|
|
||||||
Rectangle subBorders = sub.Borders;
|
|
||||||
subBorders.Location += sub.HiddenSubPosition.ToPoint() - new Point(0, sub.Borders.Height);
|
|
||||||
|
|
||||||
//don't draw any shadows if the light doesn't overlap with the borders of the sub
|
|
||||||
if (!MathUtils.CircleIntersectsRectangle(lightPos, TextureRange, subBorders))
|
|
||||||
{
|
|
||||||
if (chList.List.Count > 0) NeedsRecalculation = true;
|
|
||||||
chList.List.Clear();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//recalculate vertices if the subs have moved > 5 px relative to each other
|
|
||||||
Vector2 diff = ParentSub.WorldPosition - sub.WorldPosition;
|
|
||||||
if (!diffToSub.TryGetValue(sub, out Vector2 prevDiff))
|
|
||||||
{
|
|
||||||
diffToSub.Add(sub, diff);
|
|
||||||
NeedsRecalculation = true;
|
|
||||||
}
|
|
||||||
else if (Vector2.DistanceSquared(diff, prevDiff) > 5.0f * 5.0f)
|
|
||||||
{
|
|
||||||
diffToSub[sub] = diff;
|
|
||||||
NeedsRecalculation = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
RefreshConvexHullList(chList, lightPos, sub);
|
RefreshConvexHullList(chList, lightPos, sub);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//light and convexhull are inside different subs
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (sub.DockedTo.Contains(ParentSub) && !NeedsHullCheck) { return; }
|
||||||
|
|
||||||
|
lightPos -= (sub.Position - ParentSub.Position);
|
||||||
|
|
||||||
|
Rectangle subBorders = sub.Borders;
|
||||||
|
subBorders.Location += sub.HiddenSubPosition.ToPoint() - new Point(0, sub.Borders.Height);
|
||||||
|
|
||||||
|
//don't draw any shadows if the light doesn't overlap with the borders of the sub
|
||||||
|
if (!MathUtils.CircleIntersectsRectangle(lightPos, TextureRange, subBorders))
|
||||||
|
{
|
||||||
|
if (chList.List.Count > 0) { NeedsRecalculation = true; }
|
||||||
|
chList.List.Clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//recalculate vertices if the subs have moved > 5 px relative to each other
|
||||||
|
Vector2 diff = ParentSub.WorldPosition - sub.WorldPosition;
|
||||||
|
if (!diffToSub.TryGetValue(sub, out Vector2 prevDiff))
|
||||||
|
{
|
||||||
|
diffToSub.Add(sub, diff);
|
||||||
|
NeedsRecalculation = true;
|
||||||
|
}
|
||||||
|
else if (Vector2.DistanceSquared(diff, prevDiff) > 5.0f * 5.0f)
|
||||||
|
{
|
||||||
|
diffToSub[sub] = diff;
|
||||||
|
NeedsRecalculation = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefreshConvexHullList(chList, lightPos, sub);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -75,10 +75,12 @@ namespace Barotrauma
|
|||||||
if (linkedTo.Contains(entity))
|
if (linkedTo.Contains(entity))
|
||||||
{
|
{
|
||||||
linkedTo.Remove(entity);
|
linkedTo.Remove(entity);
|
||||||
|
entity.linkedTo.Remove(this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
linkedTo.Add(entity);
|
linkedTo.Add(entity);
|
||||||
|
if (!entity.linkedTo.Contains(this)) { entity.linkedTo.Add(this); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,18 +130,31 @@ namespace Barotrauma
|
|||||||
int tilesY = (int)Math.Ceiling(Height / tileSize.Y);
|
int tilesY = (int)Math.Ceiling(Height / tileSize.Y);
|
||||||
mapTiles = new Sprite[tilesX, tilesY];
|
mapTiles = new Sprite[tilesX, tilesY];
|
||||||
tileDiscovered = new bool[tilesX, tilesY];
|
tileDiscovered = new bool[tilesX, tilesY];
|
||||||
|
HashSet<Biome> missingBiomes = new HashSet<Biome>();
|
||||||
for (int x = 0; x < tilesX; x++)
|
for (int x = 0; x < tilesX; x++)
|
||||||
{
|
{
|
||||||
for (int y = 0; y < tilesY; y++)
|
for (int y = 0; y < tilesY; y++)
|
||||||
{
|
{
|
||||||
var biome = GetBiome(x * tileSize.X);
|
var biome = GetBiome(x * tileSize.X);
|
||||||
var tileList = generationParams.MapTiles.ContainsKey(biome.Identifier) ?
|
List<Sprite> tileList = null;
|
||||||
generationParams.MapTiles[biome.Identifier] :
|
if (generationParams.MapTiles.ContainsKey(biome.Identifier))
|
||||||
generationParams.MapTiles.Values.First();
|
{
|
||||||
|
tileList = generationParams.MapTiles[biome.Identifier];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tileList = generationParams.MapTiles.Values.First();
|
||||||
|
missingBiomes.Add(biome);
|
||||||
|
}
|
||||||
mapTiles[x, y] = tileList[x % tileList.Count];
|
mapTiles[x, y] = tileList[x % tileList.Count];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var missingBiome in missingBiomes)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError($"Could not find campaign map sprites for the biome \"{missingBiome.Identifier}\". Using the sprites of the first biome instead...");
|
||||||
|
}
|
||||||
|
|
||||||
RemoveFogOfWar(StartLocation);
|
RemoveFogOfWar(StartLocation);
|
||||||
|
|
||||||
GenerateLocationConnectionVisuals();
|
GenerateLocationConnectionVisuals();
|
||||||
@@ -194,7 +207,11 @@ namespace Barotrauma
|
|||||||
private void RemoveFogOfWar(Location location, bool removeFromAdjacentLocations = true)
|
private void RemoveFogOfWar(Location location, bool removeFromAdjacentLocations = true)
|
||||||
{
|
{
|
||||||
if (location == null) { return; }
|
if (location == null) { return; }
|
||||||
Vector2 mapTileSize = mapTiles[0, 0].size * generationParams.MapTileScale;
|
|
||||||
|
var mapTile = generationParams.MapTiles.Values.FirstOrDefault()?.FirstOrDefault();
|
||||||
|
if (mapTile == null) { return; }
|
||||||
|
|
||||||
|
Vector2 mapTileSize = mapTile.size * generationParams.MapTileScale;
|
||||||
int startX = (int)Math.Max(Math.Floor(location.MapPosition.X / mapTileSize.X - 0.25f), 0);
|
int startX = (int)Math.Max(Math.Floor(location.MapPosition.X / mapTileSize.X - 0.25f), 0);
|
||||||
int startY = (int)Math.Max(Math.Floor(location.MapPosition.Y / mapTileSize.Y - 0.25f), 0);
|
int startY = (int)Math.Max(Math.Floor(location.MapPosition.Y / mapTileSize.Y - 0.25f), 0);
|
||||||
int endX = (int)Math.Min(Math.Floor(location.MapPosition.X / mapTileSize.X + 0.25f), mapTiles.GetLength(0));
|
int endX = (int)Math.Min(Math.Floor(location.MapPosition.X / mapTileSize.X + 0.25f), mapTiles.GetLength(0));
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using Microsoft.Xna.Framework.Graphics;
|
|||||||
using Microsoft.Xna.Framework.Input;
|
using Microsoft.Xna.Framework.Input;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Immutable;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Barotrauma.Lights;
|
using Barotrauma.Lights;
|
||||||
|
|
||||||
@@ -36,9 +37,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private static List<MapEntity> highlightedList = new List<MapEntity>();
|
private static List<MapEntity> highlightedList = new List<MapEntity>();
|
||||||
|
|
||||||
// Test feature. Not yet saved.
|
|
||||||
public static Dictionary<MapEntity, HashSet<MapEntity>> SelectionGroups { get; private set; } = new Dictionary<MapEntity, HashSet<MapEntity>>();
|
|
||||||
|
|
||||||
private static float highlightTimer;
|
private static float highlightTimer;
|
||||||
|
|
||||||
private static GUIListBox highlightedListBox;
|
private static GUIListBox highlightedListBox;
|
||||||
@@ -197,7 +195,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Paste(cam.ScreenToWorld(PlayerInput.MousePosition));
|
Paste(cam.ScreenToWorld(PlayerInput.MousePosition));
|
||||||
}
|
}
|
||||||
else if (PlayerInput.KeyHit(Keys.G))
|
/*else if (PlayerInput.KeyHit(Keys.G))
|
||||||
{
|
{
|
||||||
if (SelectedList.Any())
|
if (SelectedList.Any())
|
||||||
{
|
{
|
||||||
@@ -217,7 +215,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,14 +358,15 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (highLightedEntity != null)
|
if (highLightedEntity != null)
|
||||||
{
|
{
|
||||||
if (SelectionGroups.TryGetValue(highLightedEntity, out HashSet<MapEntity> group))
|
if (SubEditorScreen.IsLayerLinked(highLightedEntity)/*SelectionGroups.TryGetValue(highLightedEntity, out HashSet<MapEntity> group)*/)
|
||||||
{
|
{
|
||||||
foreach (MapEntity entity in group.Where(e => !newSelection.Contains(e)))
|
ImmutableHashSet<MapEntity> entitiesInSameLayer = SubEditorScreen.GetEntitiesInSameLayer(highLightedEntity);
|
||||||
|
foreach (MapEntity entity in entitiesInSameLayer.Where(e => !newSelection.Contains(e)))
|
||||||
{
|
{
|
||||||
newSelection.Add(entity);
|
newSelection.Add(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (MapEntity entity in group)
|
foreach (MapEntity entity in entitiesInSameLayer)
|
||||||
{
|
{
|
||||||
entity.IsIncludedInSelection = true;
|
entity.IsIncludedInSelection = true;
|
||||||
}
|
}
|
||||||
@@ -769,34 +768,40 @@ namespace Barotrauma
|
|||||||
switch (e)
|
switch (e)
|
||||||
{
|
{
|
||||||
case Item item:
|
case Item item:
|
||||||
{
|
{
|
||||||
if (item.FlippedX && item.Prefab.CanSpriteFlipX) spriteEffects ^= SpriteEffects.FlipHorizontally;
|
if (item.FlippedX && item.Prefab.CanSpriteFlipX) { spriteEffects ^= SpriteEffects.FlipHorizontally; }
|
||||||
if (item.flippedY && item.Prefab.CanSpriteFlipY) spriteEffects ^= SpriteEffects.FlipVertically;
|
if (item.flippedY && item.Prefab.CanSpriteFlipY) { spriteEffects ^= SpriteEffects.FlipVertically; }
|
||||||
break;
|
var wire = item.GetComponent<Wire>();
|
||||||
}
|
if (wire != null && wire.Item.body != null && !wire.Item.body.Enabled)
|
||||||
|
{
|
||||||
|
wire.Draw(spriteBatch, editing: false, new Vector2(moveAmount.X, -moveAmount.Y));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case Structure structure:
|
case Structure structure:
|
||||||
{
|
{
|
||||||
if (structure.FlippedX && structure.Prefab.CanSpriteFlipX) spriteEffects ^= SpriteEffects.FlipHorizontally;
|
if (structure.FlippedX && structure.Prefab.CanSpriteFlipX) { spriteEffects ^= SpriteEffects.FlipHorizontally; }
|
||||||
if (structure.flippedY && structure.Prefab.CanSpriteFlipY) spriteEffects ^= SpriteEffects.FlipVertically;
|
if (structure.flippedY && structure.Prefab.CanSpriteFlipY) { spriteEffects ^= SpriteEffects.FlipVertically; }
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WayPoint wayPoint:
|
case WayPoint wayPoint:
|
||||||
{
|
{
|
||||||
Vector2 drawPos = e.WorldPosition;
|
Vector2 drawPos = e.WorldPosition;
|
||||||
drawPos.Y = -drawPos.Y;
|
drawPos.Y = -drawPos.Y;
|
||||||
drawPos += moveAmount;
|
drawPos += moveAmount;
|
||||||
wayPoint.Draw(spriteBatch, drawPos);
|
wayPoint.Draw(spriteBatch, drawPos);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case LinkedSubmarine linkedSub:
|
case LinkedSubmarine linkedSub:
|
||||||
{
|
{
|
||||||
var ma = moveAmount;
|
var ma = moveAmount;
|
||||||
ma.Y = -ma.Y;
|
ma.Y = -ma.Y;
|
||||||
Vector2 lPos = linkedSub.Position;
|
Vector2 lPos = linkedSub.Position;
|
||||||
lPos += ma;
|
lPos += ma;
|
||||||
linkedSub.Draw(spriteBatch, lPos, alpha: 0.5f);
|
linkedSub.Draw(spriteBatch, lPos, alpha: 0.5f);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
e.prefab?.DrawPlacing(spriteBatch,
|
e.prefab?.DrawPlacing(spriteBatch,
|
||||||
new Rectangle(e.WorldRect.Location + new Point((int)moveAmount.X, (int)-moveAmount.Y), e.WorldRect.Size), e.Scale, spriteEffects);
|
new Rectangle(e.WorldRect.Location + new Point((int)moveAmount.X, (int)-moveAmount.Y), e.WorldRect.Size), e.Scale, spriteEffects);
|
||||||
@@ -1197,14 +1202,24 @@ namespace Barotrauma
|
|||||||
|
|
||||||
Rectangle selectionRect = Submarine.AbsRect(pos, size);
|
Rectangle selectionRect = Submarine.AbsRect(pos, size);
|
||||||
|
|
||||||
foreach (MapEntity e in mapEntityList)
|
foreach (MapEntity entity in mapEntityList)
|
||||||
{
|
{
|
||||||
if (!e.SelectableInEditor) continue;
|
if (!entity.SelectableInEditor) { continue; }
|
||||||
|
|
||||||
if (Submarine.RectsOverlap(selectionRect, e.rect))
|
if (Submarine.RectsOverlap(selectionRect, entity.rect))
|
||||||
{
|
{
|
||||||
foundEntities.Add(e);
|
foundEntities.Add(entity);
|
||||||
e.IsIncludedInSelection = true;
|
entity.IsIncludedInSelection = true;
|
||||||
|
|
||||||
|
if (SubEditorScreen.IsLayerLinked(entity))
|
||||||
|
{
|
||||||
|
ImmutableHashSet<MapEntity> entitiesInSameLayer = SubEditorScreen.GetEntitiesInSameLayer(entity);
|
||||||
|
foreach (MapEntity layerEntity in entitiesInSameLayer.Where(e => !foundEntities.Contains(e)))
|
||||||
|
{
|
||||||
|
foundEntities.Add(layerEntity);
|
||||||
|
layerEntity.IsIncludedInSelection = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!SubEditorScreen.IsLayerVisible(this)) { return false; }
|
||||||
|
|
||||||
return HasBody ? ShowWalls : ShowStructures;
|
return HasBody ? ShowWalls : ShowStructures;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -244,8 +247,10 @@ namespace Barotrauma
|
|||||||
public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true)
|
public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true)
|
||||||
{
|
{
|
||||||
if (prefab.sprite == null) { return; }
|
if (prefab.sprite == null) { return; }
|
||||||
|
|
||||||
if (editing)
|
if (editing)
|
||||||
{
|
{
|
||||||
|
if (!SubEditorScreen.IsLayerVisible(this)) { return; }
|
||||||
if (!HasBody && !ShowStructures) { return; }
|
if (!HasBody && !ShowStructures) { return; }
|
||||||
if (HasBody && !ShowWalls) { return; }
|
if (HasBody && !ShowWalls) { return; }
|
||||||
}
|
}
|
||||||
@@ -273,6 +278,7 @@ namespace Barotrauma
|
|||||||
if (prefab.sprite == null) { return; }
|
if (prefab.sprite == null) { return; }
|
||||||
if (editing)
|
if (editing)
|
||||||
{
|
{
|
||||||
|
if (!SubEditorScreen.IsLayerVisible(this)) { return; }
|
||||||
if (!HasBody && !ShowStructures) { return; }
|
if (!HasBody && !ShowStructures) { return; }
|
||||||
if (HasBody && !ShowWalls) { return; }
|
if (HasBody && !ShowWalls) { return; }
|
||||||
}
|
}
|
||||||
@@ -285,13 +291,11 @@ namespace Barotrauma
|
|||||||
//color = Color.Lerp(color, Color.Gold, 0.5f);
|
//color = Color.Lerp(color, Color.Gold, 0.5f);
|
||||||
color = spriteColor;
|
color = spriteColor;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Vector2 rectSize = rect.Size.ToVector2();
|
Vector2 rectSize = rect.Size.ToVector2();
|
||||||
if (BodyWidth > 0.0f) { rectSize.X = BodyWidth; }
|
if (BodyWidth > 0.0f) { rectSize.X = BodyWidth; }
|
||||||
if (BodyHeight > 0.0f) { rectSize.Y = BodyHeight; }
|
if (BodyHeight > 0.0f) { rectSize.Y = BodyHeight; }
|
||||||
|
|
||||||
Vector2 bodyPos = WorldPosition + BodyOffset;
|
Vector2 bodyPos = WorldPosition + BodyOffset * Scale;
|
||||||
|
|
||||||
GUI.DrawRectangle(spriteBatch, new Vector2(bodyPos.X, -bodyPos.Y), rectSize.X, rectSize.Y, BodyRotation, Color.White,
|
GUI.DrawRectangle(spriteBatch, new Vector2(bodyPos.X, -bodyPos.Y), rectSize.X, rectSize.Y, BodyRotation, Color.White,
|
||||||
thickness: Math.Max(1, (int)(2 / Screen.Selected.Cam.Zoom)));
|
thickness: Math.Max(1, (int)(2 / Screen.Selected.Cam.Zoom)));
|
||||||
@@ -465,6 +469,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void UpdateSpriteStates(float deltaTime)
|
public void UpdateSpriteStates(float deltaTime)
|
||||||
{
|
{
|
||||||
|
if (Prefab.DecorativeSpriteGroups.Count == 0) { return; }
|
||||||
DecorativeSprite.UpdateSpriteStates(Prefab.DecorativeSpriteGroups, spriteAnimState, ID, deltaTime, ConditionalMatches);
|
DecorativeSprite.UpdateSpriteStates(Prefab.DecorativeSpriteGroups, spriteAnimState, ID, deltaTime, ConditionalMatches);
|
||||||
foreach (int spriteGroup in Prefab.DecorativeSpriteGroups.Keys)
|
foreach (int spriteGroup in Prefab.DecorativeSpriteGroups.Keys)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,14 +25,11 @@ namespace Barotrauma
|
|||||||
public readonly bool Stream;
|
public readonly bool Stream;
|
||||||
public readonly bool IgnoreMuffling;
|
public readonly bool IgnoreMuffling;
|
||||||
|
|
||||||
|
public readonly string Filename;
|
||||||
public string Filename
|
|
||||||
{
|
|
||||||
get { return Sound?.Filename; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public RoundSound(XElement element, Sound sound)
|
public RoundSound(XElement element, Sound sound)
|
||||||
{
|
{
|
||||||
|
Filename = sound?.Filename;
|
||||||
Sound = sound;
|
Sound = sound;
|
||||||
Stream = sound.Stream;
|
Stream = sound.Stream;
|
||||||
Range = element.GetAttributeFloat("range", 1000.0f);
|
Range = element.GetAttributeFloat("range", 1000.0f);
|
||||||
|
|||||||
@@ -55,9 +55,9 @@ namespace Barotrauma
|
|||||||
if (closestSub != null && subsToMove.Contains(closestSub))
|
if (closestSub != null && subsToMove.Contains(closestSub))
|
||||||
{
|
{
|
||||||
GameMain.GameScreen.Cam.Position += moveAmount;
|
GameMain.GameScreen.Cam.Position += moveAmount;
|
||||||
if (GameMain.GameScreen.Cam.TargetPos != Vector2.Zero) GameMain.GameScreen.Cam.TargetPos += moveAmount;
|
if (GameMain.GameScreen.Cam.TargetPos != Vector2.Zero) { GameMain.GameScreen.Cam.TargetPos += moveAmount; }
|
||||||
|
|
||||||
if (Character.Controlled != null) Character.Controlled.CursorPosition += moveAmount;
|
if (Character.Controlled != null) { Character.Controlled.CursorPosition += moveAmount; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
@@ -91,7 +91,7 @@ namespace Barotrauma
|
|||||||
public void CreateSpecsWindow(GUIListBox parent, ScalableFont font, bool includeTitle = true, bool includeClass = true, bool includeDescription = false)
|
public void CreateSpecsWindow(GUIListBox parent, ScalableFont font, bool includeTitle = true, bool includeClass = true, bool includeDescription = false)
|
||||||
{
|
{
|
||||||
float leftPanelWidth = 0.6f;
|
float leftPanelWidth = 0.6f;
|
||||||
float rightPanelWidth = 0.4f;
|
float rightPanelWidth = 0.4f / leftPanelWidth;
|
||||||
string className = !HasTag(SubmarineTag.Shuttle) ? TextManager.Get($"submarineclass.{SubmarineClass}") : TextManager.Get("shuttle");
|
string className = !HasTag(SubmarineTag.Shuttle) ? TextManager.Get($"submarineclass.{SubmarineClass}") : TextManager.Get("shuttle");
|
||||||
|
|
||||||
int classHeight = (int)GUI.SubHeadingFont.MeasureString(className).Y;
|
int classHeight = (int)GUI.SubHeadingFont.MeasureString(className).Y;
|
||||||
@@ -110,6 +110,17 @@ namespace Barotrauma
|
|||||||
submarineClassText = new GUITextBlock(new RectTransform(new Point(leftPanelWidthInt, classHeight), parent.Content.RectTransform), className, textAlignment: Alignment.CenterLeft, font: GUI.SubHeadingFont) { CanBeFocused = false };
|
submarineClassText = new GUITextBlock(new RectTransform(new Point(leftPanelWidthInt, classHeight), parent.Content.RectTransform), className, textAlignment: Alignment.CenterLeft, font: GUI.SubHeadingFont) { CanBeFocused = false };
|
||||||
submarineClassText.RectTransform.MinSize = new Point(0, (int)submarineClassText.TextSize.Y);
|
submarineClassText.RectTransform.MinSize = new Point(0, (int)submarineClassText.TextSize.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Price > 0)
|
||||||
|
{
|
||||||
|
var priceText = new GUITextBlock(new RectTransform(new Vector2(leftPanelWidth, 0), parent.Content.RectTransform),
|
||||||
|
TextManager.Get("subeditor.price"), textAlignment: Alignment.TopLeft, font: font, wrap: true)
|
||||||
|
{ CanBeFocused = false };
|
||||||
|
new GUITextBlock(new RectTransform(new Vector2(rightPanelWidth, 0.0f), priceText.RectTransform, Anchor.TopRight, Pivot.TopLeft),
|
||||||
|
TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", Price)), textAlignment: Alignment.TopLeft, font: font, wrap: true)
|
||||||
|
{ CanBeFocused = false };
|
||||||
|
}
|
||||||
|
|
||||||
Vector2 realWorldDimensions = Dimensions * Physics.DisplayToRealWorldRatio;
|
Vector2 realWorldDimensions = Dimensions * Physics.DisplayToRealWorldRatio;
|
||||||
if (realWorldDimensions != Vector2.Zero)
|
if (realWorldDimensions != Vector2.Zero)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -316,11 +316,11 @@ namespace Barotrauma
|
|||||||
var srcRect = prefab.sprite.SourceRect;
|
var srcRect = prefab.sprite.SourceRect;
|
||||||
|
|
||||||
SpriteEffects spriteEffects = SpriteEffects.None;
|
SpriteEffects spriteEffects = SpriteEffects.None;
|
||||||
if (flippedX)
|
if (flippedX && ((prefab as ItemPrefab)?.CanSpriteFlipX ?? true))
|
||||||
{
|
{
|
||||||
spriteEffects |= SpriteEffects.FlipHorizontally;
|
spriteEffects |= SpriteEffects.FlipHorizontally;
|
||||||
}
|
}
|
||||||
if (flippedY)
|
if (flippedY && ((prefab as ItemPrefab)?.CanSpriteFlipY ?? true))
|
||||||
{
|
{
|
||||||
spriteEffects |= SpriteEffects.FlipVertically;
|
spriteEffects |= SpriteEffects.FlipVertically;
|
||||||
}
|
}
|
||||||
@@ -651,7 +651,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
previewFrame = null;
|
if (previewFrame != null)
|
||||||
|
{
|
||||||
|
previewFrame.RectTransform.Parent = null;
|
||||||
|
previewFrame = null;
|
||||||
|
}
|
||||||
spriteRecorder?.Dispose();
|
spriteRecorder?.Dispose();
|
||||||
isDisposed = true;
|
isDisposed = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,14 +90,14 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
GUI.DrawLine(spriteBatch,
|
GUI.DrawLine(spriteBatch,
|
||||||
drawPos,
|
drawPos,
|
||||||
new Vector2(ConnectedGap.WorldPosition.X, -ConnectedGap.WorldPosition.Y),
|
new Vector2(ConnectedGap.DrawPosition.X, -ConnectedGap.DrawPosition.Y),
|
||||||
GUI.Style.Green * 0.5f, width: 1);
|
GUI.Style.Green * 0.5f, width: 1);
|
||||||
}
|
}
|
||||||
if (Ladders != null)
|
if (Ladders != null)
|
||||||
{
|
{
|
||||||
GUI.DrawLine(spriteBatch,
|
GUI.DrawLine(spriteBatch,
|
||||||
drawPos,
|
drawPos,
|
||||||
new Vector2(Ladders.Item.WorldPosition.X, -Ladders.Item.WorldPosition.Y),
|
new Vector2(Ladders.Item.DrawPosition.X, -Ladders.Item.DrawPosition.Y),
|
||||||
GUI.Style.Green * 0.5f, width: 1);
|
GUI.Style.Green * 0.5f, width: 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,6 +146,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private bool IsHidden()
|
private bool IsHidden()
|
||||||
{
|
{
|
||||||
|
if (!SubEditorScreen.IsLayerVisible(this)) { return false; }
|
||||||
if (spawnType == SpawnType.Path)
|
if (spawnType == SpawnType.Path)
|
||||||
{
|
{
|
||||||
return (!GameMain.DebugDraw && !ShowWayPoints);
|
return (!GameMain.DebugDraw && !ShowWayPoints);
|
||||||
@@ -318,7 +319,10 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
|
|
||||||
var descText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.2f), paddedFrame.RectTransform),
|
var descText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.2f), paddedFrame.RectTransform),
|
||||||
TextManager.Get("IDCardDescription"), font: GUI.SmallFont);
|
TextManager.Get("IDCardDescription"), font: GUI.SmallFont)
|
||||||
|
{
|
||||||
|
ToolTip = TextManager.Get("IDCardDescriptionTooltip")
|
||||||
|
};
|
||||||
GUITextBox propertyBox = new GUITextBox(new RectTransform(new Vector2(0.5f, 1.0f), descText.RectTransform, Anchor.CenterRight), IdCardDesc)
|
GUITextBox propertyBox = new GUITextBox(new RectTransform(new Vector2(0.5f, 1.0f), descText.RectTransform, Anchor.CenterRight), IdCardDesc)
|
||||||
{
|
{
|
||||||
MaxTextLength = 150,
|
MaxTextLength = 150,
|
||||||
@@ -342,7 +346,10 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
|
|
||||||
var idCardTagsText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.2f), paddedFrame.RectTransform),
|
var idCardTagsText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.2f), paddedFrame.RectTransform),
|
||||||
TextManager.Get("IDCardTags"), font: GUI.SmallFont);
|
TextManager.Get("IDCardTags"), font: GUI.SmallFont)
|
||||||
|
{
|
||||||
|
ToolTip = TextManager.Get("IDCardTagsTooltip")
|
||||||
|
};
|
||||||
propertyBox = new GUITextBox(new RectTransform(new Vector2(0.5f, 1.0f), idCardTagsText.RectTransform, Anchor.CenterRight), string.Join(", ", idCardTags))
|
propertyBox = new GUITextBox(new RectTransform(new Vector2(0.5f, 1.0f), idCardTagsText.RectTransform, Anchor.CenterRight), string.Join(", ", idCardTags))
|
||||||
{
|
{
|
||||||
MaxTextLength = 60,
|
MaxTextLength = 60,
|
||||||
|
|||||||
@@ -46,6 +46,13 @@ namespace Barotrauma.Networking
|
|||||||
senderName = senderCharacter.Name;
|
senderName = senderCharacter.Name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Color? textColor = null;
|
||||||
|
if (msg.ReadBoolean())
|
||||||
|
{
|
||||||
|
textColor = msg.ReadColorR8G8B8A8();
|
||||||
|
}
|
||||||
|
|
||||||
msg.ReadPadBits();
|
msg.ReadPadBits();
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
@@ -78,7 +85,7 @@ namespace Barotrauma.Networking
|
|||||||
txt = orderPrefab.GetChatMessage(orderMessageInfo.TargetCharacter?.Name, targetRoom,
|
txt = orderPrefab.GetChatMessage(orderMessageInfo.TargetCharacter?.Name, targetRoom,
|
||||||
givingOrderToSelf: orderMessageInfo.TargetCharacter == senderCharacter,
|
givingOrderToSelf: orderMessageInfo.TargetCharacter == senderCharacter,
|
||||||
orderOption: orderOption,
|
orderOption: orderOption,
|
||||||
priority: orderMessageInfo.Priority);
|
isNewOrder: orderMessageInfo.IsNewOrder);
|
||||||
|
|
||||||
if (GameMain.Client.GameStarted && Screen.Selected == GameMain.GameScreen)
|
if (GameMain.Client.GameStarted && Screen.Selected == GameMain.GameScreen)
|
||||||
{
|
{
|
||||||
@@ -135,14 +142,18 @@ namespace Barotrauma.Networking
|
|||||||
//only show the message box if the text differs from the text in the currently visible box
|
//only show the message box if the text differs from the text in the currently visible box
|
||||||
if ((GUIMessageBox.VisibleBox as GUIMessageBox)?.Text?.Text != txt)
|
if ((GUIMessageBox.VisibleBox as GUIMessageBox)?.Text?.Text != txt)
|
||||||
{
|
{
|
||||||
new GUIMessageBox("", txt);
|
GUIMessageBox messageBox = new GUIMessageBox("", txt);
|
||||||
|
if (textColor != null) { messageBox.Text.TextColor = textColor.Value; }
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ChatMessageType.ServerMessageBoxInGame:
|
case ChatMessageType.ServerMessageBoxInGame:
|
||||||
new GUIMessageBox("", txt, new string[0], type: GUIMessageBox.Type.InGame, iconStyle: styleSetting);
|
{
|
||||||
|
GUIMessageBox messageBox = new GUIMessageBox("", txt, new string[0], type: GUIMessageBox.Type.InGame, iconStyle: styleSetting);
|
||||||
|
if (textColor != null) { messageBox.Text.TextColor = textColor.Value; }
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ChatMessageType.Console:
|
case ChatMessageType.Console:
|
||||||
DebugConsole.NewMessage(txt, MessageColor[(int)ChatMessageType.Console]);
|
DebugConsole.NewMessage(txt, textColor == null ? MessageColor[(int)ChatMessageType.Console] : textColor.Value);
|
||||||
break;
|
break;
|
||||||
case ChatMessageType.ServerLog:
|
case ChatMessageType.ServerLog:
|
||||||
if (!Enum.TryParse(senderName, out ServerLog.MessageType messageType))
|
if (!Enum.TryParse(senderName, out ServerLog.MessageType messageType))
|
||||||
@@ -152,7 +163,7 @@ namespace Barotrauma.Networking
|
|||||||
GameMain.Client.ServerSettings.ServerLog?.WriteLine(txt, messageType);
|
GameMain.Client.ServerSettings.ServerLog?.WriteLine(txt, messageType);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
GameMain.Client.AddChatMessage(txt, type, senderName, senderClient, senderCharacter, changeType);
|
GameMain.Client.AddChatMessage(txt, type, senderName, senderClient, senderCharacter, changeType, textColor: textColor);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
LastID = id;
|
LastID = id;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Barotrauma.Networking;
|
using Barotrauma.Items.Components;
|
||||||
|
using Barotrauma.Networking;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -15,7 +16,11 @@ namespace Barotrauma
|
|||||||
var entity = FindEntityByID(entityId);
|
var entity = FindEntityByID(entityId);
|
||||||
if (entity != null)
|
if (entity != null)
|
||||||
{
|
{
|
||||||
DebugConsole.Log("Received entity removal message for \"" + entity.ToString() + "\".");
|
DebugConsole.Log($"Received entity removal message for \"{entity}\".");
|
||||||
|
if (entity is Item item && item.Container?.GetComponent<Deconstructor>() != null)
|
||||||
|
{
|
||||||
|
GameAnalyticsManager.AddDesignEvent("ItemDeconstructed:" + (GameMain.GameSession?.GameMode?.Preset.Identifier ?? "none") + ":" + item.prefab.Identifier);
|
||||||
|
}
|
||||||
entity.Remove();
|
entity.Remove();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -28,7 +33,11 @@ namespace Barotrauma
|
|||||||
switch (message.ReadByte())
|
switch (message.ReadByte())
|
||||||
{
|
{
|
||||||
case (byte)SpawnableType.Item:
|
case (byte)SpawnableType.Item:
|
||||||
Item.ReadSpawnData(message, true);
|
var newItem = Item.ReadSpawnData(message, true);
|
||||||
|
if (newItem is Item item && item.Container?.GetComponent<Fabricator>() != null)
|
||||||
|
{
|
||||||
|
GameAnalyticsManager.AddDesignEvent("ItemFabricated:" + (GameMain.GameSession?.GameMode?.Preset.Identifier ?? "none") + ":" + item.prefab.Identifier);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case (byte)SpawnableType.Character:
|
case (byte)SpawnableType.Character:
|
||||||
Character.ReadSpawnData(message);
|
Character.ReadSpawnData(message);
|
||||||
|
|||||||
@@ -859,7 +859,7 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ServerPacketHeader.STARTGAMEFINALIZE:
|
case ServerPacketHeader.STARTGAMEFINALIZE:
|
||||||
DebugConsole.Log("Received STARTGAMEFINALIZE packet.");
|
DebugConsole.NewMessage("Received STARTGAMEFINALIZE packet. Round init status: " + roundInitStatus);
|
||||||
if (roundInitStatus == RoundInitStatus.WaitingForStartGameFinalize)
|
if (roundInitStatus == RoundInitStatus.WaitingForStartGameFinalize)
|
||||||
{
|
{
|
||||||
//waiting for a save file
|
//waiting for a save file
|
||||||
@@ -950,6 +950,9 @@ namespace Barotrauma.Networking
|
|||||||
case ServerPacketHeader.CREW:
|
case ServerPacketHeader.CREW:
|
||||||
campaign?.ClientReadCrew(inc);
|
campaign?.ClientReadCrew(inc);
|
||||||
break;
|
break;
|
||||||
|
case ServerPacketHeader.MEDICAL:
|
||||||
|
campaign?.MedicalClinic?.ClientRead(inc);
|
||||||
|
break;
|
||||||
case ServerPacketHeader.READY_CHECK:
|
case ServerPacketHeader.READY_CHECK:
|
||||||
ReadyCheck.ClientRead(inc);
|
ReadyCheck.ClientRead(inc);
|
||||||
break;
|
break;
|
||||||
@@ -1121,9 +1124,9 @@ namespace Barotrauma.Networking
|
|||||||
disconnectReason != DisconnectReason.InvalidVersion)
|
disconnectReason != DisconnectReason.InvalidVersion)
|
||||||
{
|
{
|
||||||
GameAnalyticsManager.AddErrorEventOnce(
|
GameAnalyticsManager.AddErrorEventOnce(
|
||||||
"GameClient.HandleDisconnectMessage",
|
"GameClient.HandleDisconnectMessage",
|
||||||
GameAnalyticsManager.ErrorSeverity.Debug,
|
GameAnalyticsManager.ErrorSeverity.Debug,
|
||||||
"Client received a disconnect message. Reason: " + disconnectReason.ToString());
|
"Client received a disconnect message. Reason: " + disconnectReason.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (disconnectReason == DisconnectReason.ServerFull)
|
if (disconnectReason == DisconnectReason.ServerFull)
|
||||||
@@ -1276,7 +1279,15 @@ namespace Barotrauma.Networking
|
|||||||
private void ReadAchievement(IReadMessage inc)
|
private void ReadAchievement(IReadMessage inc)
|
||||||
{
|
{
|
||||||
string achievementIdentifier = inc.ReadString();
|
string achievementIdentifier = inc.ReadString();
|
||||||
SteamAchievementManager.UnlockAchievement(achievementIdentifier);
|
int amount = inc.ReadInt32();
|
||||||
|
if (amount == 0)
|
||||||
|
{
|
||||||
|
SteamAchievementManager.UnlockAchievement(achievementIdentifier);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SteamAchievementManager.IncrementStat(achievementIdentifier, amount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReadTraitorMessage(IReadMessage inc)
|
private void ReadTraitorMessage(IReadMessage inc)
|
||||||
@@ -1476,7 +1487,7 @@ namespace Barotrauma.Networking
|
|||||||
serverSettings.LockAllDefaultWires = inc.ReadBoolean();
|
serverSettings.LockAllDefaultWires = inc.ReadBoolean();
|
||||||
serverSettings.AllowRagdollButton = inc.ReadBoolean();
|
serverSettings.AllowRagdollButton = inc.ReadBoolean();
|
||||||
serverSettings.AllowLinkingWifiToChat = inc.ReadBoolean();
|
serverSettings.AllowLinkingWifiToChat = inc.ReadBoolean();
|
||||||
GameMain.NetLobbyScreen.UsingShuttle = inc.ReadBoolean();
|
bool usingShuttle = GameMain.NetLobbyScreen.UsingShuttle = inc.ReadBoolean();
|
||||||
GameMain.LightManager.LosMode = (LosMode)inc.ReadByte();
|
GameMain.LightManager.LosMode = (LosMode)inc.ReadByte();
|
||||||
bool includesFinalize = inc.ReadBoolean(); inc.ReadPadBits();
|
bool includesFinalize = inc.ReadBoolean(); inc.ReadPadBits();
|
||||||
GameMain.LightManager.LightingEnabled = true;
|
GameMain.LightManager.LightingEnabled = true;
|
||||||
@@ -1488,6 +1499,8 @@ namespace Barotrauma.Networking
|
|||||||
Task loadTask = null;
|
Task loadTask = null;
|
||||||
var roundSummary = (GUIMessageBox.MessageBoxes.Find(c => c?.UserData is RoundSummary)?.UserData) as RoundSummary;
|
var roundSummary = (GUIMessageBox.MessageBoxes.Find(c => c?.UserData is RoundSummary)?.UserData) as RoundSummary;
|
||||||
|
|
||||||
|
bool isOutpost = false;
|
||||||
|
|
||||||
if (gameMode != GameModePreset.MultiPlayerCampaign)
|
if (gameMode != GameModePreset.MultiPlayerCampaign)
|
||||||
{
|
{
|
||||||
string levelSeed = inc.ReadString();
|
string levelSeed = inc.ReadString();
|
||||||
@@ -1626,6 +1639,7 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
GameMain.GameSession.StartRound(levelData, mirrorLevel);
|
GameMain.GameSession.StartRound(levelData, mirrorLevel);
|
||||||
}
|
}
|
||||||
|
isOutpost = levelData.Type == LevelData.LevelType.Outpost;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GameMain.Client?.ServerSettings?.Voting != null)
|
if (GameMain.Client?.ServerSettings?.Voting != null)
|
||||||
@@ -1745,8 +1759,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
if (respawnAllowed)
|
if (respawnAllowed)
|
||||||
{
|
{
|
||||||
bool isOutpost = GameMain.GameSession?.GameMode is MultiPlayerCampaign campaign && Level.Loaded?.Type == LevelData.LevelType.Outpost;
|
respawnManager = new RespawnManager(this, usingShuttle && !isOutpost ? GameMain.NetLobbyScreen.SelectedShuttle : null);
|
||||||
respawnManager = new RespawnManager(this, GameMain.NetLobbyScreen.UsingShuttle && !isOutpost ? GameMain.NetLobbyScreen.SelectedShuttle : null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gameStarted = true;
|
gameStarted = true;
|
||||||
@@ -1877,7 +1890,7 @@ namespace Barotrauma.Networking
|
|||||||
if (int.TryParse(ownedIndexes[i], out int index))
|
if (int.TryParse(ownedIndexes[i], out int index))
|
||||||
{
|
{
|
||||||
SubmarineInfo sub = GameMain.Client.ServerSubmarines[index];
|
SubmarineInfo sub = GameMain.Client.ServerSubmarines[index];
|
||||||
if (GameMain.NetLobbyScreen.CheckIfCampaignSubMatches(sub, "owned"))
|
if (GameMain.NetLobbyScreen.CheckIfCampaignSubMatches(sub, NetLobbyScreen.SubmarineDeliveryData.Owned))
|
||||||
{
|
{
|
||||||
GameMain.GameSession.OwnedSubmarines.Add(sub);
|
GameMain.GameSession.OwnedSubmarines.Add(sub);
|
||||||
}
|
}
|
||||||
@@ -1893,7 +1906,7 @@ namespace Barotrauma.Networking
|
|||||||
if (int.TryParse(ownedIndexes[i], out index))
|
if (int.TryParse(ownedIndexes[i], out index))
|
||||||
{
|
{
|
||||||
SubmarineInfo sub = GameMain.Client.ServerSubmarines[index];
|
SubmarineInfo sub = GameMain.Client.ServerSubmarines[index];
|
||||||
if (GameMain.NetLobbyScreen.CheckIfCampaignSubMatches(sub, "owned"))
|
if (GameMain.NetLobbyScreen.CheckIfCampaignSubMatches(sub, NetLobbyScreen.SubmarineDeliveryData.Owned))
|
||||||
{
|
{
|
||||||
GameMain.NetLobbyScreen.ServerOwnedSubmarines.Add(sub);
|
GameMain.NetLobbyScreen.ServerOwnedSubmarines.Add(sub);
|
||||||
}
|
}
|
||||||
@@ -2095,13 +2108,6 @@ namespace Barotrauma.Networking
|
|||||||
string selectShuttleName = inc.ReadString();
|
string selectShuttleName = inc.ReadString();
|
||||||
string selectShuttleHash = inc.ReadString();
|
string selectShuttleHash = inc.ReadString();
|
||||||
|
|
||||||
UInt16 campaignSubmarineIndexCount = inc.ReadUInt16();
|
|
||||||
List<int> campaignSubIndices = new List<int>();
|
|
||||||
for (int i = 0; i< campaignSubmarineIndexCount; i++)
|
|
||||||
{
|
|
||||||
campaignSubIndices.Add(inc.ReadUInt16());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool allowSubVoting = inc.ReadBoolean();
|
bool allowSubVoting = inc.ReadBoolean();
|
||||||
bool allowModeVoting = inc.ReadBoolean();
|
bool allowModeVoting = inc.ReadBoolean();
|
||||||
|
|
||||||
@@ -2162,16 +2168,11 @@ namespace Barotrauma.Networking
|
|||||||
if (GameMain.Client.IsServerOwner) RequestSelectMode(modeIndex);
|
if (GameMain.Client.IsServerOwner) RequestSelectMode(modeIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (campaignSubIndices != null)
|
if (GameMain.NetLobbyScreen.SelectedMode == GameModePreset.MultiPlayerCampaign)
|
||||||
{
|
{
|
||||||
GameMain.NetLobbyScreen.CampaignSubmarines = new List<SubmarineInfo>();
|
foreach (SubmarineInfo sub in ServerSubmarines.Where(s => !ServerSettings.HiddenSubs.Contains(s.Name)))
|
||||||
foreach (UInt16 campaignSubIndex in campaignSubIndices)
|
|
||||||
{
|
{
|
||||||
SubmarineInfo sub = GameMain.Client.ServerSubmarines[campaignSubIndex];
|
GameMain.NetLobbyScreen.CheckIfCampaignSubMatches(sub, NetLobbyScreen.SubmarineDeliveryData.Campaign);
|
||||||
if (GameMain.NetLobbyScreen.CheckIfCampaignSubMatches(sub, "campaign"))
|
|
||||||
{
|
|
||||||
GameMain.NetLobbyScreen.CampaignSubmarines.Add(sub);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2604,7 +2605,6 @@ namespace Barotrauma.Networking
|
|||||||
NetLobbyScreen.FailedSubInfo failedCampaignSub = GameMain.NetLobbyScreen.FailedCampaignSubs.Find(s => s.Name == newSub.Name && s.Hash == newSub.MD5Hash.Hash);
|
NetLobbyScreen.FailedSubInfo failedCampaignSub = GameMain.NetLobbyScreen.FailedCampaignSubs.Find(s => s.Name == newSub.Name && s.Hash == newSub.MD5Hash.Hash);
|
||||||
if (failedCampaignSub != default)
|
if (failedCampaignSub != default)
|
||||||
{
|
{
|
||||||
GameMain.NetLobbyScreen.CampaignSubmarines.Add(newSub);
|
|
||||||
GameMain.NetLobbyScreen.FailedCampaignSubs.Remove(failedCampaignSub);
|
GameMain.NetLobbyScreen.FailedCampaignSubs.Remove(failedCampaignSub);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2881,19 +2881,16 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
public void SendCampaignState()
|
public void SendCampaignState()
|
||||||
{
|
{
|
||||||
MultiPlayerCampaign campaign = GameMain.GameSession.GameMode as MultiPlayerCampaign;
|
if (!(GameMain.GameSession.GameMode is MultiPlayerCampaign campaign))
|
||||||
if (campaign == null)
|
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Failed send campaign state to the server (no campaign active).\n" + Environment.StackTrace.CleanupStackTrace());
|
DebugConsole.ThrowError("Failed send campaign state to the server (no campaign active).\n" + Environment.StackTrace.CleanupStackTrace());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
IWriteMessage msg = new WriteOnlyMessage();
|
IWriteMessage msg = new WriteOnlyMessage();
|
||||||
msg.Write((byte)ClientPacketHeader.SERVER_COMMAND);
|
msg.Write((byte)ClientPacketHeader.SERVER_COMMAND);
|
||||||
msg.Write((UInt16)ClientPermissions.ManageCampaign);
|
msg.Write((UInt16)ClientPermissions.ManageCampaign);
|
||||||
campaign.ClientWrite(msg);
|
campaign.ClientWrite(msg);
|
||||||
msg.Write((byte)ServerNetObject.END_OF_MESSAGE);
|
msg.Write((byte)ServerNetObject.END_OF_MESSAGE);
|
||||||
|
|
||||||
clientPeer.Send(msg, DeliveryMethod.Reliable);
|
clientPeer.Send(msg, DeliveryMethod.Reliable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3571,6 +3568,11 @@ namespace Barotrauma.Networking
|
|||||||
case ClientNetError.MISSING_ENTITY:
|
case ClientNetError.MISSING_ENTITY:
|
||||||
outMsg.Write(eventID);
|
outMsg.Write(eventID);
|
||||||
outMsg.Write(entityID);
|
outMsg.Write(entityID);
|
||||||
|
outMsg.Write((byte)Submarine.Loaded.Count);
|
||||||
|
foreach (Submarine sub in Submarine.Loaded)
|
||||||
|
{
|
||||||
|
outMsg.Write(sub.Info.Name);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
clientPeer.Send(outMsg, DeliveryMethod.Reliable);
|
clientPeer.Send(outMsg, DeliveryMethod.Reliable);
|
||||||
|
|||||||
+13
-7
@@ -100,7 +100,7 @@ namespace Barotrauma.Networking
|
|||||||
if (!isActive) { return; }
|
if (!isActive) { return; }
|
||||||
if (steamId != hostSteamId) { return; }
|
if (steamId != hostSteamId) { return; }
|
||||||
Close($"SteamP2P connection failed: {error}");
|
Close($"SteamP2P connection failed: {error}");
|
||||||
OnDisconnectMessageReceived?.Invoke($"SteamP2P connection failed: {error}");
|
OnDisconnectMessageReceived?.Invoke($"{DisconnectReason.SteamP2PError}/SteamP2P connection failed: {error}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnP2PData(ulong steamId, byte[] data, int dataLength)
|
private void OnP2PData(ulong steamId, byte[] data, int dataLength)
|
||||||
@@ -167,14 +167,14 @@ namespace Barotrauma.Networking
|
|||||||
if (state == null)
|
if (state == null)
|
||||||
{
|
{
|
||||||
Close("SteamP2P connection could not be established");
|
Close("SteamP2P connection could not be established");
|
||||||
OnDisconnectMessageReceived?.Invoke("SteamP2P connection could not be established");
|
OnDisconnectMessageReceived?.Invoke(DisconnectReason.SteamP2PError.ToString());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (state?.P2PSessionError != Steamworks.P2PSessionError.None)
|
if (state?.P2PSessionError != Steamworks.P2PSessionError.None)
|
||||||
{
|
{
|
||||||
Close($"SteamP2P error code: {state?.P2PSessionError}");
|
Close($"SteamP2P error code: {state?.P2PSessionError}");
|
||||||
OnDisconnectMessageReceived?.Invoke($"SteamP2P error code: {state?.P2PSessionError}");
|
OnDisconnectMessageReceived?.Invoke($"{DisconnectReason.SteamP2PError}/SteamP2P error code: {state?.P2PSessionError}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
connectionStatusTimer = 1.0f;
|
connectionStatusTimer = 1.0f;
|
||||||
@@ -210,7 +210,7 @@ namespace Barotrauma.Networking
|
|||||||
if (timeout < 0.0)
|
if (timeout < 0.0)
|
||||||
{
|
{
|
||||||
Close("Timed out");
|
Close("Timed out");
|
||||||
OnDisconnectMessageReceived?.Invoke("");
|
OnDisconnectMessageReceived?.Invoke(DisconnectReason.SteamP2PTimeOut.ToString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,13 +349,19 @@ namespace Barotrauma.Networking
|
|||||||
outMsg.Write((byte)PacketHeader.IsDisconnectMessage);
|
outMsg.Write((byte)PacketHeader.IsDisconnectMessage);
|
||||||
outMsg.Write(msg ?? "Disconnected");
|
outMsg.Write(msg ?? "Disconnected");
|
||||||
|
|
||||||
Steamworks.SteamNetworking.SendP2PPacket(hostSteamId, outMsg.Buffer, outMsg.LengthBytes, 0, Steamworks.P2PSend.Reliable);
|
try
|
||||||
sentBytes += outMsg.LengthBytes;
|
{
|
||||||
|
Steamworks.SteamNetworking.SendP2PPacket(hostSteamId, outMsg.Buffer, outMsg.LengthBytes, 0, Steamworks.P2PSend.Reliable);
|
||||||
|
sentBytes += outMsg.LengthBytes;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Failed to send a disconnect message to the server using SteamP2P.", e);
|
||||||
|
}
|
||||||
|
|
||||||
Thread.Sleep(100);
|
Thread.Sleep(100);
|
||||||
|
|
||||||
Steamworks.SteamNetworking.ResetActions();
|
Steamworks.SteamNetworking.ResetActions();
|
||||||
|
|
||||||
Steamworks.SteamNetworking.CloseP2PSessionWithUser(hostSteamId);
|
Steamworks.SteamNetworking.CloseP2PSessionWithUser(hostSteamId);
|
||||||
|
|
||||||
steamAuthTicket?.Cancel(); steamAuthTicket = null;
|
steamAuthTicket?.Cancel(); steamAuthTicket = null;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user